@moltendb-web/core 1.6.0 → 1.8.0

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
@@ -95,7 +95,6 @@ import { MoltenDb } from '@moltendb-web/core';
95
95
  import { MoltenDbClient, WorkerTransport } from '@moltendb-web/query';
96
96
 
97
97
  const db = new MoltenDb('moltendb_demo', {
98
- hotThreshold: 25000, // Keep 25k docs in RAM per collection
99
98
  encryptionKey: 'my-secret', // Enable transparent at-rest encryption
100
99
  writeMode: 'sync' // Ensure every write is flushed to OPFS
101
100
  });
@@ -259,7 +258,6 @@ You can customise the database behavior by passing an options object to the `Mol
259
258
 
260
259
  ```ts
261
260
  const db = new MoltenDb('my-app', {
262
- hotThreshold: 25000, // Page to disk after 25k docs
263
261
  encryptionKey: 'user-secret', // Secure at-rest storage in OPFS
264
262
  writeMode: 'sync' // Ensure durability on every write
265
263
  });
@@ -270,7 +268,6 @@ await db.init();
270
268
 
271
269
  | Property | Type | Default | Description |
272
270
  | :--- | :--- | :--- |:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
273
- | `hotThreshold` | `number` | `50000` | **Hybrid Bitcask Limit:** Maximum documents per collection to keep in RAM. When exceeded, the oldest documents are paged out to OPFS to save memory. |
274
271
  | `encryptionKey` | `string` | `undefined` | **At-Rest Encryption:** If provided, all data written to OPFS is encrypted using XChaCha20-Poly1305. If omitted, data is stored as plain JSON. |
275
272
  | `writeMode` | `'async' \| 'sync'` | `'async'` | **Durability vs Speed:** `'async'` is blazing fast (high throughput), while `'sync'` ensures every write is flushed to disk before returning (safer but slower). **Note:** `async` is recommended for most web apps to avoid blocking during heavy write bursts. |
276
273
  | `workerUrl` | `string \| URL` | `undefined` | Custom path to the Web Worker script. |
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  export interface MoltenDbOptions {
2
2
  /** URL or path to moltendb-worker.js. */
3
3
  workerUrl?: string | URL;
4
- /** Maximum documents per collection to keep in RAM. Default: 50,000. */
5
- hotThreshold?: number;
6
4
  /** Password for at-rest encryption. If not provided, data is stored as plain JSON. */
7
5
  encryptionKey?: string;
8
6
  /** Storage write mode: 'async' (default, high throughput) or 'sync' (durable). */
@@ -59,6 +57,20 @@ export declare class MoltenDb {
59
57
  getAll(collection: string): Promise<unknown[]>;
60
58
  delete(collection: string, key: string): Promise<void>;
61
59
  compact(): Promise<unknown>;
60
+ /**
61
+ * Truncate and close the OPFS file so the directory can be removed.
62
+ *
63
+ * Works from any tab — followers automatically route this through the leader
64
+ * via BroadcastChannel, so the leader worker (which holds the exclusive
65
+ * FileSystemSyncAccessHandle) is the one that actually closes the file.
66
+ *
67
+ * After this resolves, call:
68
+ * `const root = await navigator.storage.getDirectory();`
69
+ * `const root = await navigator.storage.getDirectory();`
70
+ * `await root.removeEntry(dbName, { recursive: true });`
71
+ * then reload the page.
72
+ */
73
+ clearOpfs(): Promise<unknown>;
62
74
  disconnect(): void;
63
75
  terminate(): void;
64
76
  }
package/dist/index.js CHANGED
@@ -120,7 +120,6 @@ export class MoltenDb {
120
120
  await this.sendMessage('init', {
121
121
  dbName: this.dbName,
122
122
  encryptionKey: this.options.encryptionKey,
123
- hotThreshold: this.options.hotThreshold,
124
123
  inMemory: this.options.inMemory,
125
124
  maxBodySize: this.options.maxBodySize,
126
125
  maxKeysPerRequest: this.options.maxKeysPerRequest,
@@ -260,6 +259,22 @@ export class MoltenDb {
260
259
  compact() {
261
260
  return this.sendMessage('compact');
262
261
  }
262
+ /**
263
+ * Truncate and close the OPFS file so the directory can be removed.
264
+ *
265
+ * Works from any tab — followers automatically route this through the leader
266
+ * via BroadcastChannel, so the leader worker (which holds the exclusive
267
+ * FileSystemSyncAccessHandle) is the one that actually closes the file.
268
+ *
269
+ * After this resolves, call:
270
+ * `const root = await navigator.storage.getDirectory();`
271
+ * `const root = await navigator.storage.getDirectory();`
272
+ * `await root.removeEntry(dbName, { recursive: true });`
273
+ * then reload the page.
274
+ */
275
+ clearOpfs() {
276
+ return this.sendMessage('clear_opfs');
277
+ }
263
278
  disconnect() {
264
279
  if (this.bc)
265
280
  this.bc.close();
@@ -9,7 +9,7 @@ self.onmessage = async (e) => {
9
9
  initPromise = (async () => {
10
10
  await init();
11
11
  // Pass all config flags to Rust
12
- const instance = await WorkerDb.create(payload.dbName, payload.hotThreshold, payload.encryptionKey, payload.writeMode, payload.maxBodySize, payload.maxKeysPerRequest, payload.inMemory);
12
+ const instance = await WorkerDb.create(payload.dbName, payload.encryptionKey, payload.writeMode, payload.maxBodySize, payload.maxKeysPerRequest, payload.inMemory);
13
13
  // Listen to Rust and broadcast events
14
14
  instance.subscribe((eventStr) => {
15
15
  try {
@@ -17,28 +17,6 @@ export class WorkerDb {
17
17
  private constructor();
18
18
  free(): void;
19
19
  [Symbol.dispose](): void;
20
- /**
21
- * Execute an analytics query and return the result as a JSON string.
22
- *
23
- * This is the method called by the dashboard's auto-refresh loop:
24
- * `const resultStr = db.analytics(JSON.stringify(query))`
25
- *
26
- * Takes a JSON string (not a JsValue) because the analytics query format
27
- * is complex and easier to pass as a pre-serialized string from JavaScript.
28
- *
29
- * Returns a JSON string (not a JsValue) so JavaScript can parse it with
30
- * `JSON.parse(resultStr)` and access `result` and `metadata`.
31
- *
32
- * Example input:
33
- * `'{"collection":"events","metric":{"type":"COUNT"},"where":{"event_type":"button_click"}}'`
34
- *
35
- * Example output:
36
- * `'{"result":42,"metadata":{"execution_time_ms":0,"rows_scanned":42}}'`
37
- *
38
- * `#[wasm_bindgen(js_name = analytics)]` sets the JavaScript method name to
39
- * "analytics" (matching the call in analytics-worker.js).
40
- */
41
- analytics(query_json: string): string;
42
20
  /**
43
21
  * Initialize the database and open (or create) the OPFS storage file.
44
22
  *
@@ -56,7 +34,6 @@ export class WorkerDb {
56
34
  * # Arguments
57
35
  * * `db_name` — The name of the OPFS file to open (e.g. "click_analytics_db").
58
36
  * Each unique name is a separate database file in the browser's OPFS storage.
59
- * * `hot_threshold` — Optional maximum documents per collection to keep in RAM (default: 50,000).
60
37
  * * `encryption_key` — Optional password for at-rest encryption.
61
38
  * * `write_mode` — Optional write mode: "async" (default) or "sync".
62
39
  * * `max_body_size` — Optional maximum request body size in bytes (default: 10MB).
@@ -65,7 +42,7 @@ export class WorkerDb {
65
42
  * When `true`, all data is lost when the worker is terminated — useful for ephemeral
66
43
  * session caches or testing without touching OPFS storage.
67
44
  */
68
- static create(db_name: string, hot_threshold?: number | null, encryption_key?: string | null, write_mode?: string | null, max_body_size?: number | null, max_keys_per_request?: number | null, in_memory?: boolean | null): Promise<WorkerDb>;
45
+ static create(db_name: string, encryption_key?: string | null, write_mode?: string | null, max_body_size?: number | null, max_keys_per_request?: number | null, in_memory?: boolean | null): Promise<WorkerDb>;
69
46
  /**
70
47
  * Route an incoming message from the JavaScript worker to the correct handler.
71
48
  *
@@ -100,12 +77,11 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
100
77
  export interface InitOutput {
101
78
  readonly memory: WebAssembly.Memory;
102
79
  readonly __wbg_workerdb_free: (a: number, b: number) => void;
103
- readonly workerdb_analytics: (a: number, b: number, c: number, d: number) => void;
104
- readonly workerdb_create: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => number;
80
+ readonly workerdb_create: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => number;
105
81
  readonly workerdb_handle_message: (a: number, b: number, c: number) => void;
106
82
  readonly workerdb_subscribe: (a: number, b: number) => void;
107
- readonly __wasm_bindgen_func_elem_4220: (a: number, b: number, c: number, d: number) => void;
108
- readonly __wasm_bindgen_func_elem_4230: (a: number, b: number, c: number, d: number) => void;
83
+ readonly __wasm_bindgen_func_elem_3769: (a: number, b: number, c: number, d: number) => void;
84
+ readonly __wasm_bindgen_func_elem_3781: (a: number, b: number, c: number, d: number) => void;
109
85
  readonly __wbindgen_export: (a: number, b: number) => number;
110
86
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
111
87
  readonly __wbindgen_export3: (a: number) => void;
@@ -30,47 +30,6 @@ export class WorkerDb {
30
30
  const ptr = this.__destroy_into_raw();
31
31
  wasm.__wbg_workerdb_free(ptr, 0);
32
32
  }
33
- /**
34
- * Execute an analytics query and return the result as a JSON string.
35
- *
36
- * This is the method called by the dashboard's auto-refresh loop:
37
- * `const resultStr = db.analytics(JSON.stringify(query))`
38
- *
39
- * Takes a JSON string (not a JsValue) because the analytics query format
40
- * is complex and easier to pass as a pre-serialized string from JavaScript.
41
- *
42
- * Returns a JSON string (not a JsValue) so JavaScript can parse it with
43
- * `JSON.parse(resultStr)` and access `result` and `metadata`.
44
- *
45
- * Example input:
46
- * `'{"collection":"events","metric":{"type":"COUNT"},"where":{"event_type":"button_click"}}'`
47
- *
48
- * Example output:
49
- * `'{"result":42,"metadata":{"execution_time_ms":0,"rows_scanned":42}}'`
50
- *
51
- * `#[wasm_bindgen(js_name = analytics)]` sets the JavaScript method name to
52
- * "analytics" (matching the call in analytics-worker.js).
53
- * @param {string} query_json
54
- * @returns {string}
55
- */
56
- analytics(query_json) {
57
- let deferred2_0;
58
- let deferred2_1;
59
- try {
60
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
61
- const ptr0 = passStringToWasm0(query_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
62
- const len0 = WASM_VECTOR_LEN;
63
- wasm.workerdb_analytics(retptr, this.__wbg_ptr, ptr0, len0);
64
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
65
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
66
- deferred2_0 = r0;
67
- deferred2_1 = r1;
68
- return getStringFromWasm0(r0, r1);
69
- } finally {
70
- wasm.__wbindgen_add_to_stack_pointer(16);
71
- wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
72
- }
73
- }
74
33
  /**
75
34
  * Initialize the database and open (or create) the OPFS storage file.
76
35
  *
@@ -88,7 +47,6 @@ export class WorkerDb {
88
47
  * # Arguments
89
48
  * * `db_name` — The name of the OPFS file to open (e.g. "click_analytics_db").
90
49
  * Each unique name is a separate database file in the browser's OPFS storage.
91
- * * `hot_threshold` — Optional maximum documents per collection to keep in RAM (default: 50,000).
92
50
  * * `encryption_key` — Optional password for at-rest encryption.
93
51
  * * `write_mode` — Optional write mode: "async" (default) or "sync".
94
52
  * * `max_body_size` — Optional maximum request body size in bytes (default: 10MB).
@@ -97,7 +55,6 @@ export class WorkerDb {
97
55
  * When `true`, all data is lost when the worker is terminated — useful for ephemeral
98
56
  * session caches or testing without touching OPFS storage.
99
57
  * @param {string} db_name
100
- * @param {number | null} [hot_threshold]
101
58
  * @param {string | null} [encryption_key]
102
59
  * @param {string | null} [write_mode]
103
60
  * @param {number | null} [max_body_size]
@@ -105,14 +62,14 @@ export class WorkerDb {
105
62
  * @param {boolean | null} [in_memory]
106
63
  * @returns {Promise<WorkerDb>}
107
64
  */
108
- static create(db_name, hot_threshold, encryption_key, write_mode, max_body_size, max_keys_per_request, in_memory) {
65
+ static create(db_name, encryption_key, write_mode, max_body_size, max_keys_per_request, in_memory) {
109
66
  const ptr0 = passStringToWasm0(db_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
110
67
  const len0 = WASM_VECTOR_LEN;
111
68
  var ptr1 = isLikeNone(encryption_key) ? 0 : passStringToWasm0(encryption_key, wasm.__wbindgen_export, wasm.__wbindgen_export2);
112
69
  var len1 = WASM_VECTOR_LEN;
113
70
  var ptr2 = isLikeNone(write_mode) ? 0 : passStringToWasm0(write_mode, wasm.__wbindgen_export, wasm.__wbindgen_export2);
114
71
  var len2 = WASM_VECTOR_LEN;
115
- const ret = wasm.workerdb_create(ptr0, len0, isLikeNone(hot_threshold) ? 0x100000001 : (hot_threshold) >>> 0, ptr1, len1, ptr2, len2, isLikeNone(max_body_size) ? 0x100000001 : (max_body_size) >>> 0, isLikeNone(max_keys_per_request) ? 0x100000001 : (max_keys_per_request) >>> 0, isLikeNone(in_memory) ? 0xFFFFFF : in_memory ? 1 : 0);
72
+ const ret = wasm.workerdb_create(ptr0, len0, ptr1, len1, ptr2, len2, isLikeNone(max_body_size) ? 0x100000001 : (max_body_size) >>> 0, isLikeNone(max_keys_per_request) ? 0x100000001 : (max_keys_per_request) >>> 0, isLikeNone(in_memory) ? 0xFFFFFF : in_memory ? 1 : 0);
116
73
  return takeObject(ret);
117
74
  }
118
75
  /**
@@ -420,7 +377,7 @@ function __wbg_get_imports() {
420
377
  const a = state0.a;
421
378
  state0.a = 0;
422
379
  try {
423
- return __wasm_bindgen_func_elem_4230(a, state0.b, arg0, arg1);
380
+ return __wasm_bindgen_func_elem_3781(a, state0.b, arg0, arg1);
424
381
  } finally {
425
382
  state0.a = a;
426
383
  }
@@ -455,14 +412,6 @@ function __wbg_get_imports() {
455
412
  const ret = Date.now();
456
413
  return ret;
457
414
  },
458
- __wbg_now_e7c6795a7f81e10f: function(arg0) {
459
- const ret = getObject(arg0).now();
460
- return ret;
461
- },
462
- __wbg_performance_3fcf6e32a7e1ed0a: function(arg0) {
463
- const ret = getObject(arg0).performance;
464
- return addHeapObject(ret);
465
- },
466
415
  __wbg_process_44c7a14e11e9f69e: function(arg0) {
467
416
  const ret = getObject(arg0).process;
468
417
  return addHeapObject(ret);
@@ -567,8 +516,8 @@ function __wbg_get_imports() {
567
516
  return ret;
568
517
  }, arguments); },
569
518
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
570
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 774, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
571
- const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_4220);
519
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 724, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
520
+ const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_3769);
572
521
  return addHeapObject(ret);
573
522
  },
574
523
  __wbindgen_cast_0000000000000002: function(arg0) {
@@ -610,10 +559,10 @@ function __wbg_get_imports() {
610
559
  };
611
560
  }
612
561
 
613
- function __wasm_bindgen_func_elem_4220(arg0, arg1, arg2) {
562
+ function __wasm_bindgen_func_elem_3769(arg0, arg1, arg2) {
614
563
  try {
615
564
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
616
- wasm.__wasm_bindgen_func_elem_4220(retptr, arg0, arg1, addHeapObject(arg2));
565
+ wasm.__wasm_bindgen_func_elem_3769(retptr, arg0, arg1, addHeapObject(arg2));
617
566
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
618
567
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
619
568
  if (r1) {
@@ -624,8 +573,8 @@ function __wasm_bindgen_func_elem_4220(arg0, arg1, arg2) {
624
573
  }
625
574
  }
626
575
 
627
- function __wasm_bindgen_func_elem_4230(arg0, arg1, arg2, arg3) {
628
- wasm.__wasm_bindgen_func_elem_4230(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
576
+ function __wasm_bindgen_func_elem_3781(arg0, arg1, arg2, arg3) {
577
+ wasm.__wasm_bindgen_func_elem_3781(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
629
578
  }
630
579
 
631
580
  const WorkerDbFinalization = (typeof FinalizationRegistry === 'undefined')
Binary file
@@ -2,12 +2,11 @@
2
2
  /* eslint-disable */
3
3
  export const memory: WebAssembly.Memory;
4
4
  export const __wbg_workerdb_free: (a: number, b: number) => void;
5
- export const workerdb_analytics: (a: number, b: number, c: number, d: number) => void;
6
- export const workerdb_create: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => number;
5
+ export const workerdb_create: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => number;
7
6
  export const workerdb_handle_message: (a: number, b: number, c: number) => void;
8
7
  export const workerdb_subscribe: (a: number, b: number) => void;
9
- export const __wasm_bindgen_func_elem_4220: (a: number, b: number, c: number, d: number) => void;
10
- export const __wasm_bindgen_func_elem_4230: (a: number, b: number, c: number, d: number) => void;
8
+ export const __wasm_bindgen_func_elem_3769: (a: number, b: number, c: number, d: number) => void;
9
+ export const __wasm_bindgen_func_elem_3781: (a: number, b: number, c: number, d: number) => void;
11
10
  export const __wbindgen_export: (a: number, b: number) => number;
12
11
  export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
13
12
  export const __wbindgen_export3: (a: number) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltendb-web/core",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "MoltenDb WASM runtime — the database engine, Web Worker, and main-thread client in one package.",
5
5
  "type": "module",
6
6
  "author": "Maximilian Both <maximilian.both27@outlook.com>",