Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indexed db extension #1340

Closed
wants to merge 13 commits into from
1 change: 1 addition & 0 deletions extensions/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"fetch",
"text",
"local-storage",
"ffghdfh/indexedDB",
"true-fantom/base",
"bitwise",
"Skyhigh173/bigint",
Expand Down
222 changes: 222 additions & 0 deletions extensions/ffghdfh/indexedDB.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Name: Indexed Database
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Credit yourself here! You made the extension! :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done! i added my discord username!

// ID: ffghdfhIndexedDB
// Description: Lets you use an IndexedDB database, allowing for you to store more than 5MB of data locally. Made by chair_senpai :)
// License: LGPL-3.0
(function (Scratch) {
"use strict";
if (!Scratch.extensions.unsandboxed) {
throw new Error("Indexed Database must be run unsandboxed");
}

class IndexedDBExtension {
constructor() {
this.dbName = "MyScratchDB"; // Default database name
this.db = null;
}

// Set the database name
_setDBName(name) {
this.dbName = name;
}

// Initialize the IndexedDB
_initDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, 1);

request.onerror = (event) => {
console.error("Database error:", event.target.error);
resolve();
};

request.onsuccess = (event) => {
this.db = event.target.result;
resolve(this.db);
};

request.onupgradeneeded = (event) => {
const db = event.target.result;
db.createObjectStore("data", { keyPath: "key" });
};
});
}

// Set value in the IndexedDB
_setValue(key, value) {
return this._initDB().then((db) => {
const transaction = db.transaction(["data"], "readwrite");
const store = transaction.objectStore("data");
const request = store.put({ key, value });

return new Promise((resolve, reject) => {
request.onsuccess = () => resolve();
request.onerror = () => resolve();
});
});
}

// Get value from the IndexedDB
_getValue(key) {
return this._initDB().then((db) => {
const transaction = db.transaction(["data"], "readonly");
const store = transaction.objectStore("data");
const request = store.get(key);

return new Promise((resolve, reject) => {
request.onsuccess = () =>
resolve(request.result ? request.result.value : null);
request.onerror = () => resolve("undefined");
});
});
}

// Delete all keys in the IndexedDB
_deleteAllKeys() {
return this._initDB().then((db) => {
const transaction = db.transaction(["data"], "readwrite");
const store = transaction.objectStore("data");
const request = store.clear();

return new Promise((resolve, reject) => {
request.onsuccess = () => resolve();
request.onerror = () => resolve();
});
});
}

// Delete a specific key in the IndexedDB
_deleteKey(key) {
return this._initDB().then((db) => {
const transaction = db.transaction(["data"], "readwrite");
const store = transaction.objectStore("data");
const request = store.delete(key);

return new Promise((resolve, reject) => {
request.onsuccess = () => resolve();
request.onerror = () => resolve();
});
});
}

// Check if a key exists in the IndexedDB
_keyExists(key) {
return this._initDB().then((db) => {
const transaction = db.transaction(["data"], "readonly");
const store = transaction.objectStore("data");
const request = store.get(key);

return new Promise((resolve) => {
request.onsuccess = () => resolve(request.result !== undefined);
});
});
}

// Scratch blocks implementation
getInfo() {
return {
id: "ffghdfhIndexedDB",
name: "IndexedDB",
color1: "#fd7f54", // Main block color
color2: "#c26140",
color3: "#b35b3d", // Slightly darker outline color
blocks: [
{
opcode: "setDBName",
blockType: Scratch.BlockType.COMMAND,
text: "set database name [NAME]",
arguments: {
NAME: {
type: Scratch.ArgumentType.STRING,
defaultValue: "MyScratchDB",
},
},
},
{
opcode: "setValue",
blockType: Scratch.BlockType.COMMAND,
text: "set key [KEY] to [VALUE]",
arguments: {
KEY: {
type: Scratch.ArgumentType.STRING,
defaultValue: "myKey",
},
VALUE: {
type: Scratch.ArgumentType.STRING,
defaultValue: "myValue",
},
},
},
{
opcode: "getValue",
blockType: Scratch.BlockType.REPORTER,
text: "get value for key [KEY]",
arguments: {
KEY: {
type: Scratch.ArgumentType.STRING,
defaultValue: "myKey",
},
},
},
{
opcode: "deleteAllKeys",
blockType: Scratch.BlockType.COMMAND,
text: "delete all keys",
},
{
opcode: "deleteKey",
blockType: Scratch.BlockType.COMMAND,
text: "delete key [KEY]",
arguments: {
KEY: {
type: Scratch.ArgumentType.STRING,
defaultValue: "myKey",
},
},
},
{
opcode: "keyExists",
blockType: Scratch.BlockType.BOOLEAN,
text: "key [KEY] exists?",
arguments: {
KEY: {
type: Scratch.ArgumentType.STRING,
defaultValue: "myKey",
},
},
},
],
};
}

setDBName(args) {
const { NAME } = args;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do this in the function argument as opposed to setting it retroactively, if you wanted to

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uhh i'm sorry, but i'm not quite sure what you mean by that 😅

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh i got it, one sec imma modify it

this._setDBName(NAME);
}

setValue(args) {
const { KEY, VALUE } = args;
return this._setValue(KEY, VALUE);
}

getValue(args) {
const { KEY } = args;
return this._getValue(KEY);
}

deleteAllKeys() {
return this._deleteAllKeys();
}

deleteKey(args) {
const { KEY } = args;
return this._deleteKey(KEY);
}

keyExists(args) {
const { KEY } = args;
return this._keyExists(KEY);
}
}

Scratch.extensions.register(new IndexedDBExtension());
})(Scratch);
4 changes: 4 additions & 0 deletions images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ All images in this folder are licensed under the [GNU General Public License ver
- File icons based on https://icon-icons.com/icon/file-pdf/153412 under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
- Background based on https://bgjar.com/contour-line under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).

## ffghdfh/indexedDB.svg
- Created by [ffghdfh](https://github.com/ffghdfh)
- Database icon by [@fontawesome](https://fontawesome.com), [CC BY 4.0](https://creativecommons.org/licenses/by/4.0), via Wikimedia Commons

## battery.svg
- Created by [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1586143227
- Based on image created by [@Martinelplayz](https://scratch.mit.edu/users/MARTINELPLAYZ/) in https://github.com/TurboWarp/extensions/pull/504#issuecomment-1574243161
Expand Down
141 changes: 141 additions & 0 deletions images/ffghdfh/indexedDB.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading