@moltendb-web/query 1.0.0-rc.1 → 1.0.0-rc.4

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.
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # @moltendb-web/query
2
2
 
3
- Type-safe, chainable query builder for [MoltenDB](https://github.com/maximilian27/MoltenDB).
3
+ Type-safe, chainable query builder for [MoltenDb](https://github.com/maximilian27/MoltenDb).
4
4
 
5
5
  Works in vanilla JavaScript and TypeScript. Compiles as an npm module (CJS + ESM + `.d.ts`).
6
6
 
7
7
  ### 🌋 Explore the Full Functionality
8
8
 
9
- The best way to experience the MoltenDB query builder is through our **[Interactive Demo on StackBlitz](https://stackblitz.com/~/github.com/maximilian27/moltendb-wasm-demo?file=package.json)**. It contains a complete, live environment where you can test query builder expressions, perform mutations, and see real-time events without any local setup.
9
+ The best way to experience the MoltenDb query builder is through our **[Interactive Demo on StackBlitz](https://stackblitz.com/~/github.com/maximilian27/moltendb-wasm-demo?file=package.json)**. It contains a complete, live environment where you can test query builder expressions, perform mutations, and see real-time events without any local setup.
10
10
 
11
11
  ---
12
12
 
@@ -21,15 +21,15 @@ npm install @moltendb-web/query
21
21
  ## Quick start
22
22
 
23
23
  ```ts
24
- import { MoltenDB } from '@moltendb-web/core';
25
- import { MoltenDBClient, WorkerTransport } from '@moltendb-web/query';
24
+ import { MoltenDb } from '@moltendb-web/core';
25
+ import { MoltenDbClient, WorkerTransport } from '@moltendb-web/query';
26
26
 
27
27
  // 1. Initialize the Core Engine (boots WASM worker)
28
- const db = new MoltenDB('moltendb_demo');
28
+ const db = new MoltenDb('moltendb_demo');
29
29
  await db.init();
30
30
 
31
31
  // 2. Connect the Query Builder to the worker
32
- const client = new MoltenDBClient(db);
32
+ const client = new MoltenDbClient(db);
33
33
 
34
34
  // SET — insert / upsert
35
35
  await client.collection('laptops')
@@ -196,7 +196,7 @@ await client.collection('laptops')
196
196
  Implement `MoltenTransport` to connect to any backend:
197
197
 
198
198
  ```ts
199
- import { MoltenTransport, MoltenDBClient, Document, JsonValue } from '@moltendb-web/query';
199
+ import { MoltenTransport, MoltenDbClient, Document, JsonValue } from '@moltendb-web/query';
200
200
 
201
201
  class FetchTransport implements MoltenTransport {
202
202
  constructor(private baseUrl: string, private token: string) {}
@@ -214,7 +214,7 @@ class FetchTransport implements MoltenTransport {
214
214
  }
215
215
  }
216
216
 
217
- const db = new MoltenDBClient(new FetchTransport('[https://api.mydomain.com](https://api.mydomain.com)', myToken));
217
+ const db = new MoltenDbClient(new FetchTransport('[https://api.mydomain.com](https://api.mydomain.com)', myToken));
218
218
  ```
219
219
 
220
220
  ---
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  export type JsonValue = string | number | boolean | null | JsonValue[] | {
3
3
  [key: string]: JsonValue;
4
4
  };
5
- /** A document stored in MoltenDB — any object with string keys. */
5
+ /** A document stored in MoltenDb — any object with string keys. */
6
6
  export type Document = {
7
7
  [key: string]: JsonValue;
8
8
  };
@@ -54,7 +54,7 @@ export type ExtendsMap = {
54
54
  [alias: string]: string;
55
55
  };
56
56
  /**
57
- * The transport layer used by MoltenDBClient to send messages.
57
+ * The transport layer used by MoltenDbClient to send messages.
58
58
  * Implement this interface to connect the query builder to any backend:
59
59
  * - A Web Worker (WASM in-browser)
60
60
  * - A fetch-based HTTP client
@@ -269,7 +269,7 @@ export declare class DeleteQuery {
269
269
  }
270
270
  /**
271
271
  * A handle to a specific collection.
272
- * Returned by `MoltenDBClient.collection(name)`.
272
+ * Returned by `MoltenDbClient.collection(name)`.
273
273
  * Use it to start any of the four operation builders.
274
274
  */
275
275
  export declare class CollectionHandle {
@@ -313,17 +313,17 @@ export declare class CollectionHandle {
313
313
  delete(): DeleteQuery;
314
314
  }
315
315
  /**
316
- * The main entry point for the MoltenDB query builder.
316
+ * The main entry point for the MoltenDb query builder.
317
317
  *
318
318
  * Accepts any {@link MoltenTransport} implementation — use {@link WorkerTransport}
319
- * to connect to a MoltenDB WASM Web Worker, or provide your own transport
319
+ * to connect to a MoltenDb WASM Web Worker, or provide your own transport
320
320
  * for HTTP, WebSocket, or testing.
321
321
  *
322
322
  * @example
323
323
  * // Browser + WASM Web Worker
324
324
  * const worker = new Worker('./moltendb-worker.js', { type: 'module' });
325
325
  * const transport = new WorkerTransport(worker);
326
- * const db = new MoltenDBClient(transport);
326
+ * const db = new MoltenDbClient(transport);
327
327
  *
328
328
  * const results = await db.collection('laptops')
329
329
  * .get()
@@ -332,7 +332,7 @@ export declare class CollectionHandle {
332
332
  * .count(5)
333
333
  * .exec();
334
334
  */
335
- export declare class MoltenDBClient {
335
+ export declare class MoltenDbClient {
336
336
  private transport;
337
337
  constructor(transport: MoltenTransport);
338
338
  /**
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
- // ─── MoltenDB Query Builder ───────────────────────────────────────────────────
2
- // Chainable, type-safe query builder for MoltenDB.
1
+ // ─── MoltenDb Query Builder ───────────────────────────────────────────────────
2
+ // Chainable, type-safe query builder for MoltenDb.
3
3
  //
4
4
  // Each operation has its own builder class that only exposes the methods
5
5
  // that are valid for that operation — matching the server's allowed-property
@@ -13,7 +13,7 @@
13
13
  //
14
14
  // Usage (vanilla JS or TypeScript):
15
15
  //
16
- // const db = new MoltenDBClient(worker);
16
+ // const db = new MoltenDbClient(worker);
17
17
  //
18
18
  // // GET — chainable query
19
19
  // const results = await db.collection('laptops')
@@ -326,7 +326,7 @@ export { DeleteQuery as DeleteQuery };
326
326
  // ─── CollectionHandle ─────────────────────────────────────────────────────────
327
327
  /**
328
328
  * A handle to a specific collection.
329
- * Returned by `MoltenDBClient.collection(name)`.
329
+ * Returned by `MoltenDbClient.collection(name)`.
330
330
  * Use it to start any of the four operation builders.
331
331
  */
332
332
  class CollectionHandle {
@@ -379,19 +379,19 @@ class CollectionHandle {
379
379
  }
380
380
  }
381
381
  export { CollectionHandle as CollectionHandle };
382
- // ─── MoltenDBClient ───────────────────────────────────────────────────────────
382
+ // ─── MoltenDbClient ───────────────────────────────────────────────────────────
383
383
  /**
384
- * The main entry point for the MoltenDB query builder.
384
+ * The main entry point for the MoltenDb query builder.
385
385
  *
386
386
  * Accepts any {@link MoltenTransport} implementation — use {@link WorkerTransport}
387
- * to connect to a MoltenDB WASM Web Worker, or provide your own transport
387
+ * to connect to a MoltenDb WASM Web Worker, or provide your own transport
388
388
  * for HTTP, WebSocket, or testing.
389
389
  *
390
390
  * @example
391
391
  * // Browser + WASM Web Worker
392
392
  * const worker = new Worker('./moltendb-worker.js', { type: 'module' });
393
393
  * const transport = new WorkerTransport(worker);
394
- * const db = new MoltenDBClient(transport);
394
+ * const db = new MoltenDbClient(transport);
395
395
  *
396
396
  * const results = await db.collection('laptops')
397
397
  * .get()
@@ -400,7 +400,7 @@ export { CollectionHandle as CollectionHandle };
400
400
  * .count(5)
401
401
  * .exec();
402
402
  */
403
- class MoltenDBClient {
403
+ class MoltenDbClient {
404
404
  constructor(transport) {
405
405
  this.transport = transport;
406
406
  }
@@ -414,5 +414,5 @@ class MoltenDBClient {
414
414
  return new CollectionHandle(this.transport, name);
415
415
  }
416
416
  }
417
- export { MoltenDBClient as MoltenDBClient };
417
+ export { MoltenDbClient as MoltenDbClient };
418
418
  //# sourceMappingURL=index.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- // ─── MoltenDB Query Builder ───────────────────────────────────────────────────
3
- // Chainable, type-safe query builder for MoltenDB.
2
+ // ─── MoltenDb Query Builder ───────────────────────────────────────────────────
3
+ // Chainable, type-safe query builder for MoltenDb.
4
4
  //
5
5
  // Each operation has its own builder class that only exposes the methods
6
6
  // that are valid for that operation — matching the server's allowed-property
@@ -14,7 +14,7 @@
14
14
  //
15
15
  // Usage (vanilla JS or TypeScript):
16
16
  //
17
- // const db = new MoltenDBClient(worker);
17
+ // const db = new MoltenDbClient(worker);
18
18
  //
19
19
  // // GET — chainable query
20
20
  // const results = await db.collection('laptops')
@@ -41,7 +41,7 @@
41
41
  // await db.collection('laptops').delete().drop().exec();
42
42
  // ─────────────────────────────────────────────────────────────────────────────
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.MoltenDBClient = exports.CollectionHandle = exports.DeleteQuery = exports.UpdateQuery = exports.SetQuery = exports.GetQuery = void 0;
44
+ exports.MoltenDbClient = exports.CollectionHandle = exports.DeleteQuery = exports.UpdateQuery = exports.SetQuery = exports.GetQuery = void 0;
45
45
  // ─── GetQuery ─────────────────────────────────────────────────────────────────
46
46
  /**
47
47
  * Builder for GET (read/query) operations.
@@ -328,7 +328,7 @@ exports.DeleteQuery = DeleteQuery;
328
328
  // ─── CollectionHandle ─────────────────────────────────────────────────────────
329
329
  /**
330
330
  * A handle to a specific collection.
331
- * Returned by `MoltenDBClient.collection(name)`.
331
+ * Returned by `MoltenDbClient.collection(name)`.
332
332
  * Use it to start any of the four operation builders.
333
333
  */
334
334
  class CollectionHandle {
@@ -381,19 +381,19 @@ class CollectionHandle {
381
381
  }
382
382
  }
383
383
  exports.CollectionHandle = CollectionHandle;
384
- // ─── MoltenDBClient ───────────────────────────────────────────────────────────
384
+ // ─── MoltenDbClient ───────────────────────────────────────────────────────────
385
385
  /**
386
- * The main entry point for the MoltenDB query builder.
386
+ * The main entry point for the MoltenDb query builder.
387
387
  *
388
388
  * Accepts any {@link MoltenTransport} implementation — use {@link WorkerTransport}
389
- * to connect to a MoltenDB WASM Web Worker, or provide your own transport
389
+ * to connect to a MoltenDb WASM Web Worker, or provide your own transport
390
390
  * for HTTP, WebSocket, or testing.
391
391
  *
392
392
  * @example
393
393
  * // Browser + WASM Web Worker
394
394
  * const worker = new Worker('./moltendb-worker.js', { type: 'module' });
395
395
  * const transport = new WorkerTransport(worker);
396
- * const db = new MoltenDBClient(transport);
396
+ * const db = new MoltenDbClient(transport);
397
397
  *
398
398
  * const results = await db.collection('laptops')
399
399
  * .get()
@@ -402,7 +402,7 @@ exports.CollectionHandle = CollectionHandle;
402
402
  * .count(5)
403
403
  * .exec();
404
404
  */
405
- class MoltenDBClient {
405
+ class MoltenDbClient {
406
406
  constructor(transport) {
407
407
  this.transport = transport;
408
408
  }
@@ -416,5 +416,5 @@ class MoltenDBClient {
416
416
  return new CollectionHandle(this.transport, name);
417
417
  }
418
418
  }
419
- exports.MoltenDBClient = MoltenDBClient;
419
+ exports.MoltenDbClient = MoltenDbClient;
420
420
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@moltendb-web/query",
3
- "version": "1.0.0-rc.1",
4
- "description": "Type-safe query builder for MoltenDB — chainable API for get, set, update and delete operations.",
3
+ "version": "1.0.0-rc.4",
4
+ "description": "Type-safe query builder for MoltenDb — chainable API for get, set, update and delete operations.",
5
+ "author": "Maximilian Both <maximilian.both27@outlook.com>",
5
6
  "main": "./dist/index.js",
6
7
  "module": "./dist/index.esm.js",
7
8
  "types": "./dist/index.d.ts",
@@ -23,7 +24,8 @@
23
24
  "scripts": {
24
25
  "build": "tsc --project tsconfig.build.json && node scripts/build-esm.js",
25
26
  "typecheck": "tsc --noEmit",
26
- "test": "node --experimental-vm-modules node_modules/.bin/jest"
27
+ "test": "node --experimental-vm-modules node_modules/.bin/jest",
28
+ "prepublishOnly": "npm run build"
27
29
  },
28
30
  "keywords": ["moltendb", "database", "query-builder", "nosql", "wasm"],
29
31
  "license": "MIT",
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- // ─── MoltenDB Query Builder ───────────────────────────────────────────────────
2
- // Chainable, type-safe query builder for MoltenDB.
1
+ // ─── MoltenDb Query Builder ───────────────────────────────────────────────────
2
+ // Chainable, type-safe query builder for MoltenDb.
3
3
  //
4
4
  // Each operation has its own builder class that only exposes the methods
5
5
  // that are valid for that operation — matching the server's allowed-property
@@ -13,7 +13,7 @@
13
13
  //
14
14
  // Usage (vanilla JS or TypeScript):
15
15
  //
16
- // const db = new MoltenDBClient(worker);
16
+ // const db = new MoltenDbClient(worker);
17
17
  //
18
18
  // // GET — chainable query
19
19
  // const results = await db.collection('laptops')
@@ -51,7 +51,7 @@ export type JsonValue =
51
51
  | JsonValue[]
52
52
  | { [key: string]: JsonValue };
53
53
 
54
- /** A document stored in MoltenDB — any object with string keys. */
54
+ /** A document stored in MoltenDb — any object with string keys. */
55
55
  export type Document = { [key: string]: JsonValue };
56
56
 
57
57
  /** A map of document key → document body used in set/update payloads. */
@@ -114,7 +114,7 @@ export type ExtendsMap = { [alias: string]: string };
114
114
  // ── Transport interface ───────────────────────────────────────────────────────
115
115
 
116
116
  /**
117
- * The transport layer used by MoltenDBClient to send messages.
117
+ * The transport layer used by MoltenDbClient to send messages.
118
118
  * Implement this interface to connect the query builder to any backend:
119
119
  * - A Web Worker (WASM in-browser)
120
120
  * - A fetch-based HTTP client
@@ -447,7 +447,7 @@ export class DeleteQuery {
447
447
 
448
448
  /**
449
449
  * A handle to a specific collection.
450
- * Returned by `MoltenDBClient.collection(name)`.
450
+ * Returned by `MoltenDbClient.collection(name)`.
451
451
  * Use it to start any of the four operation builders.
452
452
  */
453
453
  export class CollectionHandle {
@@ -507,20 +507,20 @@ export class CollectionHandle {
507
507
  }
508
508
  }
509
509
 
510
- // ─── MoltenDBClient ───────────────────────────────────────────────────────────
510
+ // ─── MoltenDbClient ───────────────────────────────────────────────────────────
511
511
 
512
512
  /**
513
- * The main entry point for the MoltenDB query builder.
513
+ * The main entry point for the MoltenDb query builder.
514
514
  *
515
515
  * Accepts any {@link MoltenTransport} implementation — use {@link WorkerTransport}
516
- * to connect to a MoltenDB WASM Web Worker, or provide your own transport
516
+ * to connect to a MoltenDb WASM Web Worker, or provide your own transport
517
517
  * for HTTP, WebSocket, or testing.
518
518
  *
519
519
  * @example
520
520
  * // Browser + WASM Web Worker
521
521
  * const worker = new Worker('./moltendb-worker.js', { type: 'module' });
522
522
  * const transport = new WorkerTransport(worker);
523
- * const db = new MoltenDBClient(transport);
523
+ * const db = new MoltenDbClient(transport);
524
524
  *
525
525
  * const results = await db.collection('laptops')
526
526
  * .get()
@@ -529,7 +529,7 @@ export class CollectionHandle {
529
529
  * .count(5)
530
530
  * .exec();
531
531
  */
532
- export class MoltenDBClient {
532
+ export class MoltenDbClient {
533
533
  private transport: MoltenTransport;
534
534
 
535
535
  constructor(transport: MoltenTransport) {
package/dist/esm/index.js DELETED
@@ -1,443 +0,0 @@
1
- // ─── MoltenDB Query Builder ───────────────────────────────────────────────────
2
- // Chainable, type-safe query builder for MoltenDB.
3
- //
4
- // Each operation has its own builder class that only exposes the methods
5
- // that are valid for that operation — matching the server's allowed-property
6
- // lists exactly:
7
- //
8
- // GET_ALLOWED: collection, keys, where, fields, excludedFields,
9
- // joins, sort, count, offset
10
- // SET_ALLOWED: collection, data, extends
11
- // UPDATE_ALLOWED: collection, data
12
- // DELETE_ALLOWED: collection, keys, drop
13
- //
14
- // Usage (vanilla JS or TypeScript):
15
- //
16
- // const db = new MoltenDBClient(worker);
17
- //
18
- // // GET — chainable query
19
- // const results = await db.collection('laptops')
20
- // .get()
21
- // .where({ brand: 'Apple' })
22
- // .fields(['brand', 'model', 'price'])
23
- // .sort([{ field: 'price', order: 'asc' }])
24
- // .count(10)
25
- // .exec();
26
- //
27
- // // SET — insert/upsert
28
- // await db.collection('laptops')
29
- // .set({ lp1: { brand: 'Lenovo', price: 1499 } })
30
- // .exec();
31
- //
32
- // // UPDATE — partial patch
33
- // await db.collection('laptops')
34
- // .update({ lp4: { price: 1749, in_stock: true } })
35
- // .exec();
36
- //
37
- // // DELETE — single key, batch, or drop
38
- // await db.collection('laptops').delete().keys('lp6').exec();
39
- // await db.collection('laptops').delete().keys(['lp4', 'lp5']).exec();
40
- // await db.collection('laptops').delete().drop().exec();
41
- // ─────────────────────────────────────────────────────────────────────────────
42
- // ─── WorkerTransport ──────────────────────────────────────────────────────────
43
- /**
44
- * Default transport that communicates with a MoltenDB Web Worker.
45
- *
46
- * The worker must follow the moltendb-worker.js message protocol:
47
- * postMessage({ id, action, ...payload })
48
- * onmessage → { id, result } | { id, error }
49
- */
50
- export class WorkerTransport {
51
- constructor(worker, startId = 0) {
52
- this.pending = new Map();
53
- this.messageId = startId;
54
- this.worker = worker;
55
- this.worker.addEventListener('message', (event) => {
56
- const { id, result, error } = event.data;
57
- const p = this.pending.get(id);
58
- if (!p)
59
- return;
60
- this.pending.delete(id);
61
- if (error)
62
- p.reject(new Error(error));
63
- else
64
- p.resolve(result ?? null);
65
- });
66
- }
67
- send(action, payload) {
68
- return new Promise((resolve, reject) => {
69
- const id = this.messageId++;
70
- this.pending.set(id, { resolve, reject });
71
- this.worker.postMessage({ id, action, ...payload });
72
- });
73
- }
74
- }
75
- // ─── GetQuery ─────────────────────────────────────────────────────────────────
76
- /**
77
- * Builder for GET (read/query) operations.
78
- *
79
- * Allowed fields: collection, keys, where, fields, excludedFields,
80
- * joins, sort, count, offset
81
- *
82
- * @example
83
- * const rows = await db.collection('laptops')
84
- * .get()
85
- * .where({ brand: 'Apple' })
86
- * .fields(['brand', 'model', 'price'])
87
- * .sort([{ field: 'price', order: 'asc' }])
88
- * .count(5)
89
- * .exec();
90
- */
91
- export class GetQuery {
92
- /** @internal */
93
- constructor(transport, collection) {
94
- this.transport = transport;
95
- this.payload = { collection };
96
- }
97
- /**
98
- * Fetch a single document by key, or a batch of documents by key array.
99
- *
100
- * @param keys - A single key string or an array of key strings.
101
- *
102
- * @example
103
- * // Single key
104
- * .keys('lp2')
105
- * // Batch
106
- * .keys(['lp1', 'lp3', 'lp5'])
107
- */
108
- keys(keys) {
109
- this.payload['keys'] = keys;
110
- return this;
111
- }
112
- /**
113
- * Filter documents using a WHERE clause.
114
- * Multiple conditions are combined with implicit AND.
115
- *
116
- * Supported operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $contains
117
- * Dot-notation is supported for nested fields.
118
- *
119
- * @example
120
- * .where({ brand: 'Apple' })
121
- * .where({ price: { $gt: 1000, $lt: 3000 } })
122
- * .where({ 'specs.cpu.brand': 'Intel', in_stock: true })
123
- */
124
- where(clause) {
125
- this.payload['where'] = clause;
126
- return this;
127
- }
128
- /**
129
- * Project the response to only the specified fields (dot-notation supported).
130
- * Cannot be combined with {@link excludedFields}.
131
- *
132
- * @example
133
- * .fields(['brand', 'model', 'specs.cpu.ghz'])
134
- */
135
- fields(fields) {
136
- this.payload['fields'] = fields;
137
- return this;
138
- }
139
- /**
140
- * Return all fields except the specified ones.
141
- * Cannot be combined with {@link fields}.
142
- *
143
- * @example
144
- * .excludedFields(['price', 'memory_id', 'display_id'])
145
- */
146
- excludedFields(fields) {
147
- this.payload['excludedFields'] = fields;
148
- return this;
149
- }
150
- /**
151
- * Join related documents from other collections.
152
- * Each join embeds the related document under the given alias.
153
- *
154
- * @example
155
- * .joins([
156
- * { alias: 'ram', from: 'memory', on: 'memory_id', fields: ['capacity_gb', 'type'] },
157
- * { alias: 'screen', from: 'display', on: 'display_id', fields: ['refresh_hz', 'panel'] },
158
- * ])
159
- */
160
- joins(specs) {
161
- this.payload['joins'] = specs.map(({ alias, from, on, fields }) => ({
162
- [alias]: fields ? { from, on, fields } : { from, on },
163
- }));
164
- return this;
165
- }
166
- /**
167
- * Sort the results.
168
- * Multiple specs are applied in priority order (first = primary sort key).
169
- *
170
- * @example
171
- * .sort([{ field: 'price', order: 'asc' }])
172
- * .sort([{ field: 'brand', order: 'asc' }, { field: 'price', order: 'desc' }])
173
- */
174
- sort(specs) {
175
- this.payload['sort'] = specs;
176
- return this;
177
- }
178
- /**
179
- * Limit the number of results returned (applied after filtering and sorting).
180
- *
181
- * @example
182
- * .count(10)
183
- */
184
- count(n) {
185
- this.payload['count'] = n;
186
- return this;
187
- }
188
- /**
189
- * Skip the first N results (for pagination, applied after sorting).
190
- *
191
- * @example
192
- * .offset(20).count(10) // page 3 of 10
193
- */
194
- offset(n) {
195
- this.payload['offset'] = n;
196
- return this;
197
- }
198
- /**
199
- * Build and return the raw JSON payload without sending it.
200
- * Useful for debugging or passing to a custom transport.
201
- */
202
- build() {
203
- return { ...this.payload };
204
- }
205
- /**
206
- * Execute the query and return the result.
207
- * Returns a single document for single-key lookups, or an array for all others.
208
- */
209
- exec() {
210
- return this.transport.send('get', this.payload);
211
- }
212
- }
213
- // ─── SetQuery ─────────────────────────────────────────────────────────────────
214
- /**
215
- * Builder for SET (insert / upsert) operations.
216
- *
217
- * Allowed fields: collection, data, extends
218
- *
219
- * @example
220
- * await db.collection('laptops')
221
- * .set({
222
- * lp1: { brand: 'Lenovo', model: 'ThinkPad X1', price: 1499 },
223
- * lp2: { brand: 'Apple', model: 'MacBook Pro', price: 3499 },
224
- * })
225
- * .exec();
226
- */
227
- export class SetQuery {
228
- /** @internal */
229
- constructor(transport, collection, data) {
230
- this.transport = transport;
231
- this.payload = { collection, data: data };
232
- }
233
- /**
234
- * Embed data from other collections into each document at insert time.
235
- * The referenced document is fetched once and stored as a snapshot.
236
- *
237
- * Format: `{ alias: "collection.key" }`
238
- *
239
- * @example
240
- * .extends({ ram: 'memory.mem4', screen: 'display.dsp3' })
241
- */
242
- extends(map) {
243
- // The extends map is applied to every document in data.
244
- // We store it at the top level; the server resolves it per-document.
245
- const data = this.payload['data'];
246
- if (Array.isArray(data)) {
247
- // Array format — inject extends into each item
248
- this.payload['data'] = data.map((doc) => ({
249
- ...doc,
250
- extends: map,
251
- }));
252
- }
253
- else if (data && typeof data === 'object') {
254
- // Object format — inject extends into each document value
255
- const updated = {};
256
- for (const [key, doc] of Object.entries(data)) {
257
- updated[key] = { ...doc, extends: map };
258
- }
259
- this.payload['data'] = updated;
260
- }
261
- return this;
262
- }
263
- /** Build and return the raw JSON payload without sending it. */
264
- build() {
265
- return { ...this.payload };
266
- }
267
- /** Execute the insert/upsert and return `{ count, status }`. */
268
- exec() {
269
- return this.transport.send('set', this.payload);
270
- }
271
- }
272
- // ─── UpdateQuery ──────────────────────────────────────────────────────────────
273
- /**
274
- * Builder for UPDATE (partial patch / merge) operations.
275
- *
276
- * Allowed fields: collection, data
277
- *
278
- * Only the fields present in each patch object are updated —
279
- * all other fields on the existing document are left unchanged.
280
- *
281
- * @example
282
- * await db.collection('laptops')
283
- * .update({ lp4: { price: 1749, in_stock: true } })
284
- * .exec();
285
- */
286
- export class UpdateQuery {
287
- /** @internal */
288
- constructor(transport, collection, data) {
289
- this.transport = transport;
290
- this.payload = { collection, data: data };
291
- }
292
- /** Build and return the raw JSON payload without sending it. */
293
- build() {
294
- return { ...this.payload };
295
- }
296
- /** Execute the patch and return `{ count, status }`. */
297
- exec() {
298
- return this.transport.send('update', this.payload);
299
- }
300
- }
301
- // ─── DeleteQuery ──────────────────────────────────────────────────────────────
302
- /**
303
- * Builder for DELETE operations.
304
- *
305
- * Allowed fields: collection, keys, drop
306
- *
307
- * @example
308
- * // Delete a single document
309
- * await db.collection('laptops').delete().keys('lp6').exec();
310
- *
311
- * // Delete multiple documents
312
- * await db.collection('laptops').delete().keys(['lp4', 'lp5']).exec();
313
- *
314
- * // Drop the entire collection
315
- * await db.collection('laptops').delete().drop().exec();
316
- */
317
- export class DeleteQuery {
318
- /** @internal */
319
- constructor(transport, collection) {
320
- this.transport = transport;
321
- this.payload = { collection };
322
- }
323
- /**
324
- * Delete a single document by key, or multiple documents by key array.
325
- *
326
- * @example
327
- * .keys('lp6')
328
- * .keys(['lp4', 'lp5'])
329
- */
330
- keys(keys) {
331
- this.payload['keys'] = keys;
332
- return this;
333
- }
334
- /**
335
- * Drop the entire collection (deletes all documents).
336
- * Cannot be combined with {@link keys}.
337
- *
338
- * @example
339
- * .drop()
340
- */
341
- drop() {
342
- this.payload['drop'] = true;
343
- return this;
344
- }
345
- /** Build and return the raw JSON payload without sending it. */
346
- build() {
347
- return { ...this.payload };
348
- }
349
- /** Execute the delete and return `{ count, status }`. */
350
- exec() {
351
- return this.transport.send('delete', this.payload);
352
- }
353
- }
354
- // ─── CollectionHandle ─────────────────────────────────────────────────────────
355
- /**
356
- * A handle to a specific collection.
357
- * Returned by `MoltenDBClient.collection(name)`.
358
- * Use it to start any of the four operation builders.
359
- */
360
- export class CollectionHandle {
361
- /** @internal */
362
- constructor(transport, collectionName) {
363
- this.transport = transport;
364
- this.collectionName = collectionName;
365
- }
366
- /**
367
- * Start a GET (read/query) builder for this collection.
368
- *
369
- * @example
370
- * db.collection('laptops').get().where({ brand: 'Apple' }).exec()
371
- */
372
- get() {
373
- return new GetQuery(this.transport, this.collectionName);
374
- }
375
- /**
376
- * Start a SET (insert/upsert) builder for this collection.
377
- *
378
- * @param data - A map of `{ key: document }` pairs, or an array of documents
379
- * (keys are auto-generated as UUIDv7 when using array format).
380
- *
381
- * @example
382
- * db.collection('laptops').set({ lp1: { brand: 'Lenovo', price: 1499 } }).exec()
383
- */
384
- set(data) {
385
- return new SetQuery(this.transport, this.collectionName, data);
386
- }
387
- /**
388
- * Start an UPDATE (partial patch) builder for this collection.
389
- *
390
- * @param data - A map of `{ key: patch }` pairs. Only the provided fields are updated.
391
- *
392
- * @example
393
- * db.collection('laptops').update({ lp4: { price: 1749 } }).exec()
394
- */
395
- update(data) {
396
- return new UpdateQuery(this.transport, this.collectionName, data);
397
- }
398
- /**
399
- * Start a DELETE builder for this collection.
400
- * Chain `.keys(...)` or `.drop()` to specify what to delete.
401
- *
402
- * @example
403
- * db.collection('laptops').delete().keys('lp6').exec()
404
- */
405
- delete() {
406
- return new DeleteQuery(this.transport, this.collectionName);
407
- }
408
- }
409
- // ─── MoltenDBClient ───────────────────────────────────────────────────────────
410
- /**
411
- * The main entry point for the MoltenDB query builder.
412
- *
413
- * Accepts any {@link MoltenTransport} implementation — use {@link WorkerTransport}
414
- * to connect to a MoltenDB WASM Web Worker, or provide your own transport
415
- * for HTTP, WebSocket, or testing.
416
- *
417
- * @example
418
- * // Browser + WASM Web Worker
419
- * const worker = new Worker('./moltendb-worker.js', { type: 'module' });
420
- * const transport = new WorkerTransport(worker);
421
- * const db = new MoltenDBClient(transport);
422
- *
423
- * const results = await db.collection('laptops')
424
- * .get()
425
- * .where({ in_stock: true })
426
- * .sort([{ field: 'price', order: 'asc' }])
427
- * .count(5)
428
- * .exec();
429
- */
430
- export class MoltenDBClient {
431
- constructor(transport) {
432
- this.transport = transport;
433
- }
434
- /**
435
- * Select a collection to operate on.
436
- * Returns a {@link CollectionHandle} from which you can start any query builder.
437
- *
438
- * @param name - The collection name (e.g. `'laptops'`).
439
- */
440
- collection(name) {
441
- return new CollectionHandle(this.transport, name);
442
- }
443
- }