Skip to content

Commit e027e9a

Browse files
authored
QuickDB | Optimize (#381)
1 parent 9bad193 commit e027e9a

1 file changed

Lines changed: 145 additions & 90 deletions

File tree

scripts/quick-db/index.js

Lines changed: 145 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,157 @@
11
// Script example for ScriptAPI
22
// Author: Nperma <https://github.com/nperma>
33
// Project: https://github.com/JaylyDev/ScriptAPI
4-
import { world, World } from "@minecraft/server";
54

6-
const DATABASE_PREFIX = "\u0235\u0235";
5+
import { world, World } from '@minecraft/server';
6+
7+
const DATABASE_PREFIX = '\u0235\u0235';
78

89
const {
9-
getDynamicProperty: GET,
10-
setDynamicProperty: SET,
11-
getDynamicPropertyIds: IDS
10+
getDynamicProperty: GET,
11+
setDynamicProperty: SET,
12+
getDynamicPropertyIds: IDS
1213
} = World.prototype;
1314

14-
//adapt code to JalyDev/scriptAPI
1515
class QuickDB {
16-
#identifier;
17-
constructor(id) {
18-
this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`;
19-
}
20-
21-
get size() {
22-
return IDS.call(world).filter((id) => id.startsWith(this.#identifier))
23-
.length;
24-
}
25-
26-
has(key) {
27-
return !!(
28-
GET.call(world, `${this.#identifier}${key}`) &&
29-
GET.call(world, `${this.#identifier}${key}`) !== undefined
30-
);
31-
}
32-
33-
get(key) {
34-
return this.has(key)
35-
? JSON.parse(GET.call(world, `${this.#identifier}${key}`))
36-
: undefined;
37-
}
38-
39-
set(key, value) {
40-
if (typeof key !== "string") return false;
41-
SET.call(world, `${this.#identifier}${key}`, JSON.stringify(value));
42-
return true;
43-
}
44-
45-
delete(key) {
46-
if (!this.has(key)) return false;
47-
SET.call(world, `${this.#identifier}${key}`, undefined);
48-
return true;
49-
}
50-
51-
keys() {
52-
return Array.from(this.#UIDX("keys"));
53-
}
54-
55-
values() {
56-
return Array.from(this.#UIDX("values"));
57-
}
58-
59-
entries() {
60-
return Array.from(this.#UIDX("entries"));
61-
}
62-
63-
#UIDX(type) {
64-
const ids = this.getIds();
65-
let u_idx = 0;
66-
const len = ids.length;
67-
68-
return function* () {
69-
while (u_idx < len) {
70-
const id = ids[u_idx];
71-
const key = id.split(this.#identifier)[1];
72-
const value = this.get(key);
73-
switch (type) {
74-
case "key":
75-
yield key;
76-
break;
77-
case "value":
78-
yield this.has(key) ? JSON.parse(value) : undefined;
79-
break;
80-
case "entries":
81-
yield [key, JSON.parse(value)];
82-
break;
83-
}
84-
u_idx++;
85-
}
86-
}.bind(this)();
87-
}
88-
89-
getIds() {
90-
return world
91-
.getDynamicPropertyIds()
92-
.filter((id) => id.startsWith(this.#identifier));
93-
}
94-
95-
clear() {
96-
for (const id of this.getIds()) {
97-
this.delete(id.replace(this.#identifier,""));
98-
}
99-
}
16+
#identifier;
17+
__cache = {};
18+
19+
/**
20+
* @param {string} id - Unique database identifier.
21+
*/
22+
constructor(id) {
23+
if (typeof id !== 'string' || !id.trim()) {
24+
throw new Error('Invalid database ID');
25+
}
26+
this.#identifier = `${DATABASE_PREFIX}${id}${DATABASE_PREFIX}`;
27+
28+
for (const keyFull of this.getIds()) {
29+
const key = keyFull.replace(this.#identifier, '');
30+
const rawValue = GET.call(world, keyFull);
31+
this.__cache[key] = this.#parseValue(rawValue);
32+
}
33+
}
34+
35+
/**
36+
* Parses stored string values into their appropriate types.
37+
* @param {any} value
38+
* @returns {any}
39+
*/
40+
#parseValue(value) {
41+
if (typeof value === 'string') {
42+
if (value.startsWith('obj')) return JSON.parse(value.slice(3));
43+
if (value === 'null') return null;
44+
if (value === 'true' || value === 'false') return value === 'true';
45+
const num = Number(value);
46+
if (!isNaN(num)) return num;
47+
}
48+
return value;
49+
}
50+
51+
/**
52+
* Converts values into a storable format.
53+
* @param {any} value
54+
* @returns {string}
55+
*/
56+
#stringifyValue(value) {
57+
if (typeof value === 'object' && value !== null) return 'obj' + JSON.stringify(value);
58+
if (typeof value === 'boolean' || value === null) return String(value);
59+
return String(value);
60+
}
61+
62+
/** @returns {number} */
63+
get size() {
64+
return this.keys().length;
65+
}
66+
67+
/** @returns {string[]} */
68+
keys() {
69+
return Object.keys(this.__cache);
70+
}
71+
72+
/** @returns {any[]} */
73+
values() {
74+
return Object.values(this.__cache);
75+
}
76+
77+
/** @returns {[string, any][]} */
78+
entries() {
79+
return Object.entries(this.__cache);
80+
}
81+
82+
/**
83+
* Stores a key-value pair.
84+
* @param {string} key
85+
* @param {any} value
86+
* @returns {boolean}
87+
*/
88+
set(key, value) {
89+
if (typeof key !== 'string' || !key.trim()) throw new Error('Key must be a non-empty string');
90+
const finalValue = this.#stringifyValue(value);
91+
SET.call(world, this.#identifier + key, finalValue);
92+
this.__cache[key] = value;
93+
return true;
94+
}
95+
96+
/**
97+
* Deletes a key.
98+
* @param {string} key
99+
* @returns {boolean}
100+
*/
101+
delete(key) {
102+
if (!this.has(key)) return false;
103+
SET.call(world, this.#identifier + key, undefined);
104+
delete this.__cache[key];
105+
return true;
106+
}
107+
108+
/**
109+
* Retrieves a value.
110+
* @param {string} key
111+
* @returns {any}
112+
*/
113+
get(key) {
114+
if (typeof key !== 'string' || !key.trim()) throw new Error('Key must be a non-empty string');
115+
return this.__cache[key];
116+
}
117+
118+
/**
119+
* Checks if a key exists.
120+
* @param {string} key
121+
* @returns {boolean}
122+
*/
123+
has(key) {
124+
return key in this.__cache;
125+
}
126+
127+
/** @returns {string[]} */
128+
static get ids() {
129+
return [...new Set(
130+
IDS.call(world)
131+
.filter((id) => id.startsWith(DATABASE_PREFIX))
132+
.map((k) => k.slice(DATABASE_PREFIX.length).split(DATABASE_PREFIX)[0])
133+
)];
134+
}
135+
136+
/** @returns {string[]} */
137+
getIds() {
138+
return IDS.call(world).filter((id) => id.startsWith(this.#identifier));
139+
}
140+
141+
/** Clears the database. */
142+
clear() {
143+
for (const key of this.keys()) {
144+
this.delete(key);
145+
}
146+
this.__cache = {};
147+
}
148+
149+
/** Clears all databases globally. */
150+
static clearAll() {
151+
for (const real_id of IDS.call(world).filter((id) => id.startsWith(DATABASE_PREFIX))) {
152+
SET.call(world, real_id, undefined);
153+
}
154+
}
100155
}
101156

102157
export default QuickDB;

0 commit comments

Comments
 (0)