From ca67071a00f3d2fe3fab748d2c8ae947469698ef Mon Sep 17 00:00:00 2001 From: Nperma <129764133+nperma@users.noreply.github.com> Date: Sun, 2 Mar 2025 02:57:48 +0700 Subject: [PATCH 1/3] QuickDB | Optimize --- scripts/quick-db/index.js | 169 ++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 87 deletions(-) diff --git a/scripts/quick-db/index.js b/scripts/quick-db/index.js index ad10da80..83b22427 100644 --- a/scripts/quick-db/index.js +++ b/scripts/quick-db/index.js @@ -6,97 +6,92 @@ import { world, World } from "@minecraft/server"; const DATABASE_PREFIX = "\u0235\u0235"; const { - getDynamicProperty: GET, - setDynamicProperty: SET, - getDynamicPropertyIds: IDS + getDynamicProperty: GET, + setDynamicProperty: SET, + getDynamicPropertyIds: IDS } = World.prototype; -//adapt code to JalyDev/scriptAPI class QuickDB { - #identifier; - constructor(id) { - this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`; - } - - get size() { - return IDS.call(world).filter((id) => id.startsWith(this.#identifier)) - .length; - } - - has(key) { - return !!( - GET.call(world, `${this.#identifier}${key}`) && - GET.call(world, `${this.#identifier}${key}`) !== undefined - ); - } - - get(key) { - return this.has(key) - ? JSON.parse(GET.call(world, `${this.#identifier}${key}`)) - : undefined; - } - - set(key, value) { - if (typeof key !== "string") return false; - SET.call(world, `${this.#identifier}${key}`, JSON.stringify(value)); - return true; - } - - delete(key) { - if (!this.has(key)) return false; - SET.call(world, `${this.#identifier}${key}`, undefined); - return true; - } - - keys() { - return Array.from(this.#UIDX("keys")); - } - - values() { - return Array.from(this.#UIDX("values")); - } - - entries() { - return Array.from(this.#UIDX("entries")); - } - - #UIDX(type) { - const ids = this.getIds(); - let u_idx = 0; - const len = ids.length; - - return function* () { - while (u_idx < len) { - const id = ids[u_idx]; - const key = id.split(this.#identifier)[1]; - const value = this.get(key); - switch (type) { - case "key": - yield key; - break; - case "value": - yield this.has(key) ? JSON.parse(value) : undefined; - break; - case "entries": - yield [key, JSON.parse(value)]; - break; - } - u_idx++; - } - }.bind(this)(); - } - - getIds() { - return world - .getDynamicPropertyIds() - .filter((id) => id.startsWith(this.#identifier)); - } - - clear() { - for (const id of this.getIds()) { - this.delete(id.replace(this.#identifier,"")); - } + #identifier; + constructor(id) { + this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`; + + const IDDS = this.getIds(); + let length_ = IDDS.length; + this.__cache = {}; + while (length_--) { + const key = IDDS[length_].replace(this.#identifier, ""); + let value = GET.call(world, this.#identifier + key); + if (typeof value == "string" && value.startsWith("obj")) + this.__cache[key] = JSON.parse(value.slice(3)); + this.__cache[key] = value; } + } + + get size() { + return this.keys().length; + } + + keys() { + return Object.keys(this.__cache); + } + + values() { + return Object.values(this.__cache); + } + + entries() { + return Object.entries(this.__cache); + } + + set(key, value) { + if (!key) throw new Error("pls type the key!!"); + if (value.length > 0 || value !== undefined || value !== undefined) + SET.call(world, this.#identifier + String(key), JSON.stringify(value)); + else SET.call(world, this.#identifier + String(key)); + return true; + } + + delete(key) { + if (!this.has(key)) return false; + SET.call(world, `${this.#identifier}${String(key)}`); + return true; + } + + get(key) { + if (!key) throw new Error("pls type the key!!"); + return this.__cache?.[key]; + } + + has(key) { + return !!this.get(key); + } + + static get ids() { + return [ + ...new Set( + IDS.call(world) + .filter((id) => id.startsWith(DATABASE_PREFIX)) + .map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0]) + ) + ]; + } + getIds() { + return IDS.call(world).filter((id) => id.startsWith(this.#identifier)); + } + + clear() { + let length_ = this.size; + while (length_--) this.delete(this.keys()[length_]); + this.__cache = {}; + } + + static clearAll() { + for (const real_id of IDS.call(world).filter((id) => + id.startsWith(DATABASE_PREFIX) + )) + SET.call(world, real_id); + } } export default QuickDB; From c3a5f7a9e0875ba94dcfdd00690df3d425cd0e23 Mon Sep 17 00:00:00 2001 From: Nperma <129764133+nperma@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:33:15 +0700 Subject: [PATCH 2/3] QuickDB | FIXED - fixed .delete() --- scripts/quick-db/index.js | 188 +++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 85 deletions(-) diff --git a/scripts/quick-db/index.js b/scripts/quick-db/index.js index 83b22427..f15a9124 100644 --- a/scripts/quick-db/index.js +++ b/scripts/quick-db/index.js @@ -1,97 +1,115 @@ // Script example for ScriptAPI // Author: Nperma // Project: https://github.com/JaylyDev/ScriptAPI -import { world, World } from "@minecraft/server"; +import { world, World } from '@minecraft/server'; -const DATABASE_PREFIX = "\u0235\u0235"; +const DATABASE_PREFIX = '\u0235\u0235'; const { - getDynamicProperty: GET, - setDynamicProperty: SET, - getDynamicPropertyIds: IDS + getDynamicProperty: GET, + setDynamicProperty: SET, + getDynamicPropertyIds: IDS } = World.prototype; class QuickDB { - #identifier; - constructor(id) { - this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`; - - const IDDS = this.getIds(); - let length_ = IDDS.length; - this.__cache = {}; - while (length_--) { - const key = IDDS[length_].replace(this.#identifier, ""); - let value = GET.call(world, this.#identifier + key); - if (typeof value == "string" && value.startsWith("obj")) - this.__cache[key] = JSON.parse(value.slice(3)); - this.__cache[key] = value; - } - } - - get size() { - return this.keys().length; - } - - keys() { - return Object.keys(this.__cache); - } - - values() { - return Object.values(this.__cache); - } - - entries() { - return Object.entries(this.__cache); - } - - set(key, value) { - if (!key) throw new Error("pls type the key!!"); - if (value.length > 0 || value !== undefined || value !== undefined) - SET.call(world, this.#identifier + String(key), JSON.stringify(value)); - else SET.call(world, this.#identifier + String(key)); - return true; - } - - delete(key) { - if (!this.has(key)) return false; - SET.call(world, `${this.#identifier}${String(key)}`); - return true; - } - - get(key) { - if (!key) throw new Error("pls type the key!!"); - return this.__cache?.[key]; - } - - has(key) { - return !!this.get(key); - } - - static get ids() { - return [ - ...new Set( - IDS.call(world) - .filter((id) => id.startsWith(DATABASE_PREFIX)) - .map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0]) - ) - ]; - } - getIds() { - return IDS.call(world).filter((id) => id.startsWith(this.#identifier)); - } - - clear() { - let length_ = this.size; - while (length_--) this.delete(this.keys()[length_]); - this.__cache = {}; - } - - static clearAll() { - for (const real_id of IDS.call(world).filter((id) => - id.startsWith(DATABASE_PREFIX) - )) - SET.call(world, real_id); - } + #identifier; + constructor(id) { + this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`; + + const IDDS = this.getIds(); + this.__cache = {}; + + for (const keyFull of IDDS) { + const key = keyFull.replace(this.#identifier, ''); + const rawValue = GET.call(world, keyFull); + + this.__cache[key] = this.#parseValue(rawValue); + } + } + + #parseValue(value) { + if (typeof value === 'string') { + if (value.startsWith('obj')) return JSON.parse(value.slice(3)); + if (value === 'null') return null; + if (value === 'true') return true; + if (value === 'false') return false; + if (!isNaN(value)) return Number(value); + } + return value; + } + + #stringifyValue(value) { + if (typeof value === 'object' && value !== null) return 'obj' + JSON.stringify(value); + if (typeof value === 'boolean' || value === null) return String(value); + return value; + } + + get size() { + return this.keys().length; + } + + keys() { + return Object.keys(this.__cache); + } + + values() { + return Object.values(this.__cache); + } + + entries() { + return Object.entries(this.__cache); + } + + set(key, value) { + if (!key) throw new Error('pls type the key!!'); + const finalValue = this.#stringifyValue(value); + SET.call(world, this.#identifier + String(key), finalValue); + this.__cache[key] = value; + return true; + } + + delete(key) { + if (!this.has(key)) return false; + SET.call(world, this.#identifier + String(key)); + delete this.__cache[key]; + return true; + } + + get(key) { + if (!key) throw new Error('pls type the key!!'); + return this.__cache?.[key]; + } + + has(key) { + return key in this.__cache; + } + + static get ids() { + return [ + ...new Set( + IDS.call(world) + .filter((id) => id.startsWith(DATABASE_PREFIX)) + .map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0]) + ) + ]; + } + + getIds() { + return IDS.call(world).filter((id) => id.startsWith(this.#identifier)); + } + + clear() { + for (const key of this.keys()) { + this.delete(key); + } + this.__cache = {}; + } + + static clearAll() { + for (const real_id of IDS.call(world).filter((id) => id.startsWith(DATABASE_PREFIX))) { + SET.call(world, real_id); + } + } } export default QuickDB; From 6b65978cad79e2768e2c636e3bc84cf04a453a09 Mon Sep 17 00:00:00 2001 From: Nperma <129764133+nperma@users.noreply.github.com> Date: Sun, 9 Mar 2025 06:49:54 +0700 Subject: [PATCH 3/3] QuickDB | Optimize adding JsDocs --- scripts/quick-db/index.js | 86 +++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/scripts/quick-db/index.js b/scripts/quick-db/index.js index f15a9124..35a3d2b8 100644 --- a/scripts/quick-db/index.js +++ b/scripts/quick-db/index.js @@ -1,6 +1,7 @@ // Script example for ScriptAPI // Author: Nperma // Project: https://github.com/JaylyDev/ScriptAPI + import { world, World } from '@minecraft/server'; const DATABASE_PREFIX = '\u0235\u0235'; @@ -13,91 +14,131 @@ const { class QuickDB { #identifier; + __cache = {}; + + /** + * @param {string} id - Unique database identifier. + */ constructor(id) { + if (typeof id !== 'string' || !id.trim()) { + throw new Error('Invalid database ID'); + } this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`; - const IDDS = this.getIds(); - this.__cache = {}; - - for (const keyFull of IDDS) { + for (const keyFull of this.getIds()) { const key = keyFull.replace(this.#identifier, ''); const rawValue = GET.call(world, keyFull); - this.__cache[key] = this.#parseValue(rawValue); } } + /** + * Parses stored string values into their appropriate types. + * @param {any} value + * @returns {any} + */ #parseValue(value) { if (typeof value === 'string') { if (value.startsWith('obj')) return JSON.parse(value.slice(3)); if (value === 'null') return null; - if (value === 'true') return true; - if (value === 'false') return false; - if (!isNaN(value)) return Number(value); + if (value === 'true' || value === 'false') return value === 'true'; + const num = Number(value); + if (!isNaN(num)) return num; } return value; } + /** + * Converts values into a storable format. + * @param {any} value + * @returns {string} + */ #stringifyValue(value) { if (typeof value === 'object' && value !== null) return 'obj' + JSON.stringify(value); if (typeof value === 'boolean' || value === null) return String(value); - return value; + return String(value); } + /** @returns {number} */ get size() { return this.keys().length; } + /** @returns {string[]} */ keys() { return Object.keys(this.__cache); } + /** @returns {any[]} */ values() { return Object.values(this.__cache); } + /** @returns {[string, any][]} */ entries() { return Object.entries(this.__cache); } + /** + * Stores a key-value pair. + * @param {string} key + * @param {any} value + * @returns {boolean} + */ set(key, value) { - if (!key) throw new Error('pls type the key!!'); + if (typeof key !== 'string' || !key.trim()) throw new Error('Key must be a non-empty string'); const finalValue = this.#stringifyValue(value); - SET.call(world, this.#identifier + String(key), finalValue); + SET.call(world, this.#identifier + key, finalValue); this.__cache[key] = value; return true; } + /** + * Deletes a key. + * @param {string} key + * @returns {boolean} + */ delete(key) { if (!this.has(key)) return false; - SET.call(world, this.#identifier + String(key)); + SET.call(world, this.#identifier + key, undefined); delete this.__cache[key]; return true; } + /** + * Retrieves a value. + * @param {string} key + * @returns {any} + */ get(key) { - if (!key) throw new Error('pls type the key!!'); - return this.__cache?.[key]; + if (typeof key !== 'string' || !key.trim()) throw new Error('Key must be a non-empty string'); + return this.__cache[key]; } + /** + * Checks if a key exists. + * @param {string} key + * @returns {boolean} + */ has(key) { return key in this.__cache; } + /** @returns {string[]} */ static get ids() { - return [ - ...new Set( - IDS.call(world) - .filter((id) => id.startsWith(DATABASE_PREFIX)) - .map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0]) - ) - ]; + return [...new Set( + IDS.call(world) + .filter((id) => id.startsWith(DATABASE_PREFIX)) + .map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0]) + )]; } + /** @returns {string[]} */ getIds() { return IDS.call(world).filter((id) => id.startsWith(this.#identifier)); } + /** Clears the database. */ clear() { for (const key of this.keys()) { this.delete(key); @@ -105,9 +146,10 @@ class QuickDB { this.__cache = {}; } + /** Clears all databases globally. */ static clearAll() { for (const real_id of IDS.call(world).filter((id) => id.startsWith(DATABASE_PREFIX))) { - SET.call(world, real_id); + SET.call(world, real_id, undefined); } } }