starddb 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +22 -1
  2. package/package.json +1 -1
  3. package/stardb.js +38 -1
package/README.md CHANGED
@@ -48,7 +48,7 @@ await db.close();
48
48
  - `maxQueueSize` — Maximum queued operations (default: 10000)
49
49
 
50
50
  **Methods:**
51
- - `update(method, value)` — Queue an operation. Methods: `set`, `add`, `sub`, `mult`, `div`
51
+ - `update(method, value)` — Queue an operation. Methods: `set`, `add`, `sub`, `mult`, `div`, `push`
52
52
  - `flush()` — Returns a promise that resolves when all queued operations are processed
53
53
 
54
54
  ### StarDDB(database, saveTime, databaseHook, options)
@@ -62,3 +62,24 @@ await db.close();
62
62
  - `db()` — Get the database hook (object of StarDDBField instances)
63
63
  - `flush()` — Wait for all field operations to complete
64
64
  - `close()` — Flush, save, and stop the background save interval
65
+ - `addField(keyPath, value)` — Add a new field to a nested dict at runtime. `keyPath` is a dot-separated string (`"players.newGuy"`) or array of keys. Plain object values are automatically crawled into `StarDDBField` instances. Throws if the path doesn't exist or the key already exists.
66
+
67
+ **`push` operation:**
68
+ ```javascript
69
+ // Append a value to an array field
70
+ hook.scores.update("push", 30);
71
+ ```
72
+
73
+ **`addField` examples:**
74
+ ```javascript
75
+ // Add a primitive or array field
76
+ db.addField("players.newGuy", 0);
77
+ db.addField("players.newGuy.inventory", []);
78
+
79
+ // Add a nested object (crawled automatically)
80
+ db.addField("players.newGuy", { coins: 0, level: 1 });
81
+ hook.players.newGuy.coins.update("add", 5);
82
+
83
+ // Use an array of keys to avoid dot ambiguity
84
+ db.addField(["some.weird.key", "nested"], 42);
85
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starddb",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A lightweight JSON document database with field-level operation queuing and concurrency support",
5
5
  "main": "stardb.js",
6
6
  "files": [
package/stardb.js CHANGED
@@ -2,7 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const lockfile = require('proper-lockfile');
4
4
 
5
- const VALID_METHODS = new Set(['set', 'add', 'sub', 'mult', 'div']);
5
+ const VALID_METHODS = new Set(['set', 'add', 'sub', 'mult', 'div', 'push']);
6
6
  const MAX_QUEUE_SIZE = 10000;
7
7
  const MAX_RECURSION_DEPTH = 100;
8
8
 
@@ -61,6 +61,13 @@ class StarDDBField {
61
61
  }
62
62
  this.value /= item.value;
63
63
  break;
64
+ case 'push':
65
+ if (!Array.isArray(this.value)) {
66
+ console.error('[StarDDB] push called on non-array field');
67
+ break;
68
+ }
69
+ this.value.push(item.value);
70
+ break;
64
71
  default:
65
72
  console.error(`[StarDDB] Unknown method "${item.method}" dropped`);
66
73
  }
@@ -202,6 +209,36 @@ class StarDDB {
202
209
  }
203
210
  }
204
211
 
212
+ /**
213
+ * Add a new field to a nested dict at runtime.
214
+ * keyPath can be a dot-separated string ("players.newPlayer") or an array of keys.
215
+ * value can be a primitive, array, or plain object (which will be crawled into StarDDBFields).
216
+ */
217
+ addField(keyPath, value) {
218
+ const keys = Array.isArray(keyPath) ? keyPath : keyPath.split('.');
219
+ if (keys.length === 0) throw new Error('keyPath must not be empty');
220
+
221
+ let node = this.databaseHook;
222
+ for (let i = 0; i < keys.length - 1; i++) {
223
+ const k = keys[i];
224
+ if (!(k in node) || node[k] instanceof StarDDBField) {
225
+ throw new Error(`Path "${keys.slice(0, i + 1).join('.')}" does not exist or is a leaf field, not a nested object`);
226
+ }
227
+ node = node[k];
228
+ }
229
+
230
+ const lastKey = keys[keys.length - 1];
231
+ if (lastKey in node) {
232
+ throw new Error(`Field "${keys.join('.')}" already exists. Use .update() to modify existing fields.`);
233
+ }
234
+
235
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
236
+ node[lastKey] = _crawlDb(Object.assign({}, value));
237
+ } else {
238
+ node[lastKey] = new StarDDBField(value);
239
+ }
240
+ }
241
+
205
242
  async close() {
206
243
  clearInterval(this._saveInterval);
207
244
  await this.flush();