@loradb/lora-wasm 0.5.6 → 0.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 +76 -34
- package/dist/decode.d.ts +29 -0
- package/dist/decode.d.ts.map +1 -0
- package/dist/decode.js +338 -0
- package/dist/decode.js.map +1 -0
- package/dist/index.d.ts +21 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -37
- package/dist/index.js.map +1 -1
- package/dist/loader-node.d.ts +1 -1
- package/dist/snapshot.d.ts +49 -16
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +36 -54
- package/dist/snapshot.js.map +1 -1
- package/dist/types.d.ts +81 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -2
- package/dist/types.js.map +1 -1
- package/dist/worker-client.d.ts +20 -20
- package/dist/worker-client.d.ts.map +1 -1
- package/dist/worker-client.js +32 -22
- package/dist/worker-client.js.map +1 -1
- package/dist/worker-protocol.d.ts +5 -2
- package/dist/worker-protocol.d.ts.map +1 -1
- package/dist/worker.js +18 -10
- package/dist/worker.js.map +1 -1
- package/package.json +5 -5
- package/pkg-bundler/README.md +76 -34
- package/pkg-bundler/lora_wasm.d.ts +37 -10
- package/pkg-bundler/lora_wasm_bg.js +173 -26
- package/pkg-bundler/lora_wasm_bg.wasm +0 -0
- package/pkg-bundler/lora_wasm_bg.wasm.d.ts +5 -2
- package/pkg-bundler/package.json +1 -1
- package/pkg-node/README.md +76 -34
- package/pkg-node/lora_wasm.d.ts +37 -10
- package/pkg-node/lora_wasm.js +173 -26
- package/pkg-node/lora_wasm_bg.wasm +0 -0
- package/pkg-node/lora_wasm_bg.wasm.d.ts +5 -2
- package/pkg-node/package.json +1 -1
- package/pkg-web/README.md +76 -34
- package/pkg-web/lora_wasm.d.ts +42 -12
- package/pkg-web/lora_wasm.js +156 -26
- package/pkg-web/lora_wasm_bg.wasm +0 -0
- package/pkg-web/lora_wasm_bg.wasm.d.ts +5 -2
- package/pkg-web/package.json +1 -1
package/pkg-node/lora_wasm.js
CHANGED
|
@@ -177,17 +177,17 @@ function takeFromExternrefTable0(idx) {
|
|
|
177
177
|
return value;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
function getArrayU8FromWasm0(ptr, len) {
|
|
181
|
-
ptr = ptr >>> 0;
|
|
182
|
-
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
180
|
function passArray8ToWasm0(arg, malloc) {
|
|
186
181
|
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
187
182
|
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
188
183
|
WASM_VECTOR_LEN = arg.length;
|
|
189
184
|
return ptr;
|
|
190
185
|
}
|
|
186
|
+
|
|
187
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
188
|
+
ptr = ptr >>> 0;
|
|
189
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
190
|
+
}
|
|
191
191
|
/**
|
|
192
192
|
* Call once at module start to install a panic hook that routes Rust
|
|
193
193
|
* panics to `console.error`. No-op if compiled without the default feature.
|
|
@@ -255,23 +255,37 @@ class WasmDatabase {
|
|
|
255
255
|
return takeFromExternrefTable0(ret[0]);
|
|
256
256
|
}
|
|
257
257
|
/**
|
|
258
|
-
*
|
|
258
|
+
* Replace the graph state with a database snapshot decoded from `bytes`.
|
|
259
|
+
* Legacy store snapshot bytes are accepted for compatibility.
|
|
260
|
+
*
|
|
261
|
+
* Returns a plain object matching the shape of `SnapshotMeta`:
|
|
262
|
+
* `{ formatVersion, nodeCount, relationshipCount, walLsn }`.
|
|
263
|
+
* @param {Uint8Array} bytes
|
|
264
|
+
* @param {any} options
|
|
265
|
+
* @returns {any}
|
|
259
266
|
*/
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
267
|
+
loadSnapshot(bytes, options) {
|
|
268
|
+
const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
|
|
269
|
+
const len0 = WASM_VECTOR_LEN;
|
|
270
|
+
const ret = wasm.wasmdatabase_loadSnapshot(this.__wbg_ptr, ptr0, len0, options);
|
|
271
|
+
if (ret[2]) {
|
|
272
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
273
|
+
}
|
|
274
|
+
return takeFromExternrefTable0(ret[0]);
|
|
263
275
|
}
|
|
264
276
|
/**
|
|
265
|
-
* Serialize the graph into
|
|
266
|
-
* writing
|
|
267
|
-
*
|
|
268
|
-
* passed to `
|
|
277
|
+
* Serialize the graph into database snapshot bytes. The caller is
|
|
278
|
+
* responsible for writing them to IndexedDB, localStorage, a server, or
|
|
279
|
+
* another host-provided store — WASM has no direct filesystem access.
|
|
280
|
+
* The returned bytes can later be passed to `loadSnapshot` on any
|
|
281
|
+
* `WasmDatabase` instance.
|
|
269
282
|
*
|
|
270
283
|
* Returns the serialized bytes as a `Uint8Array`.
|
|
284
|
+
* @param {any} options
|
|
271
285
|
* @returns {Uint8Array}
|
|
272
286
|
*/
|
|
273
|
-
|
|
274
|
-
const ret = wasm.
|
|
287
|
+
saveSnapshot(options) {
|
|
288
|
+
const ret = wasm.wasmdatabase_saveSnapshot(this.__wbg_ptr, options);
|
|
275
289
|
if (ret[3]) {
|
|
276
290
|
throw takeFromExternrefTable0(ret[2]);
|
|
277
291
|
}
|
|
@@ -280,21 +294,34 @@ class WasmDatabase {
|
|
|
280
294
|
return v1;
|
|
281
295
|
}
|
|
282
296
|
/**
|
|
283
|
-
*
|
|
297
|
+
* Execute a Lora query and return the result as a binary buffer.
|
|
284
298
|
*
|
|
285
|
-
*
|
|
286
|
-
* `{
|
|
287
|
-
*
|
|
288
|
-
*
|
|
299
|
+
* Wire format is the shared `lora_binding_buffer` layout. The TS
|
|
300
|
+
* wrapper decodes it once into the same `{ columns, rows }` shape
|
|
301
|
+
* `execute()` returns, but in a tight V8 loop instead of going
|
|
302
|
+
* through `serde_wasm_bindgen` value-by-value. Materially faster
|
|
303
|
+
* on bulk reads.
|
|
304
|
+
* @param {string} query
|
|
305
|
+
* @param {any} params
|
|
306
|
+
* @returns {Uint8Array}
|
|
289
307
|
*/
|
|
290
|
-
|
|
291
|
-
const ptr0 =
|
|
308
|
+
executeBuffer(query, params) {
|
|
309
|
+
const ptr0 = passStringToWasm0(query, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
292
310
|
const len0 = WASM_VECTOR_LEN;
|
|
293
|
-
const ret = wasm.
|
|
294
|
-
if (ret[
|
|
295
|
-
throw takeFromExternrefTable0(ret[
|
|
311
|
+
const ret = wasm.wasmdatabase_executeBuffer(this.__wbg_ptr, ptr0, len0, params);
|
|
312
|
+
if (ret[3]) {
|
|
313
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
296
314
|
}
|
|
297
|
-
|
|
315
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
316
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
317
|
+
return v2;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* @returns {number}
|
|
321
|
+
*/
|
|
322
|
+
relationshipCount() {
|
|
323
|
+
const ret = wasm.wasmdatabase_relationshipCount(this.__wbg_ptr);
|
|
324
|
+
return ret >>> 0;
|
|
298
325
|
}
|
|
299
326
|
constructor() {
|
|
300
327
|
const ret = wasm.wasmdatabase_new();
|
|
@@ -324,6 +351,43 @@ class WasmDatabase {
|
|
|
324
351
|
}
|
|
325
352
|
return takeFromExternrefTable0(ret[0]);
|
|
326
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Compile a query and return its plan without executing it.
|
|
356
|
+
*
|
|
357
|
+
* Mutating queries (CREATE / MERGE / SET / DELETE / REMOVE) leave
|
|
358
|
+
* the graph untouched — this method never runs the executor.
|
|
359
|
+
* @param {string} query
|
|
360
|
+
* @param {any} params
|
|
361
|
+
* @returns {any}
|
|
362
|
+
*/
|
|
363
|
+
explain(query, params) {
|
|
364
|
+
const ptr0 = passStringToWasm0(query, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
365
|
+
const len0 = WASM_VECTOR_LEN;
|
|
366
|
+
const ret = wasm.wasmdatabase_explain(this.__wbg_ptr, ptr0, len0, params);
|
|
367
|
+
if (ret[2]) {
|
|
368
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
369
|
+
}
|
|
370
|
+
return takeFromExternrefTable0(ret[0]);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Execute a query and return the plan plus runtime metrics.
|
|
374
|
+
*
|
|
375
|
+
* **PROFILE executes the query for real.** Mutating queries are
|
|
376
|
+
* persisted exactly as in `execute()`. Use `explain()` to inspect
|
|
377
|
+
* a mutating plan without running it.
|
|
378
|
+
* @param {string} query
|
|
379
|
+
* @param {any} params
|
|
380
|
+
* @returns {any}
|
|
381
|
+
*/
|
|
382
|
+
profile(query, params) {
|
|
383
|
+
const ptr0 = passStringToWasm0(query, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
384
|
+
const len0 = WASM_VECTOR_LEN;
|
|
385
|
+
const ret = wasm.wasmdatabase_profile(this.__wbg_ptr, ptr0, len0, params);
|
|
386
|
+
if (ret[2]) {
|
|
387
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
388
|
+
}
|
|
389
|
+
return takeFromExternrefTable0(ret[0]);
|
|
390
|
+
}
|
|
327
391
|
}
|
|
328
392
|
module.exports.WasmDatabase = WasmDatabase;
|
|
329
393
|
|
|
@@ -396,6 +460,16 @@ module.exports.__wbg_call_672a4d21634d4a24 = function() { return handleError(fun
|
|
|
396
460
|
return ret;
|
|
397
461
|
}, arguments) };
|
|
398
462
|
|
|
463
|
+
module.exports.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
464
|
+
const ret = arg0.call(arg1, arg2);
|
|
465
|
+
return ret;
|
|
466
|
+
}, arguments) };
|
|
467
|
+
|
|
468
|
+
module.exports.__wbg_crypto_86f2631e91b51511 = function(arg0) {
|
|
469
|
+
const ret = arg0.crypto;
|
|
470
|
+
return ret;
|
|
471
|
+
};
|
|
472
|
+
|
|
399
473
|
module.exports.__wbg_done_769e5ede4b31c67b = function(arg0) {
|
|
400
474
|
const ret = arg0.done;
|
|
401
475
|
return ret;
|
|
@@ -418,6 +492,10 @@ module.exports.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
|
|
|
418
492
|
}
|
|
419
493
|
};
|
|
420
494
|
|
|
495
|
+
module.exports.__wbg_getRandomValues_b3f15fcbfabb0f8b = function() { return handleError(function (arg0, arg1) {
|
|
496
|
+
arg0.getRandomValues(arg1);
|
|
497
|
+
}, arguments) };
|
|
498
|
+
|
|
421
499
|
module.exports.__wbg_get_67b2ba62fc30de12 = function() { return handleError(function (arg0, arg1) {
|
|
422
500
|
const ret = Reflect.get(arg0, arg1);
|
|
423
501
|
return ret;
|
|
@@ -486,6 +564,11 @@ module.exports.__wbg_length_e2d2a49132c1b256 = function(arg0) {
|
|
|
486
564
|
return ret;
|
|
487
565
|
};
|
|
488
566
|
|
|
567
|
+
module.exports.__wbg_msCrypto_d562bbe83e0d4b91 = function(arg0) {
|
|
568
|
+
const ret = arg0.msCrypto;
|
|
569
|
+
return ret;
|
|
570
|
+
};
|
|
571
|
+
|
|
489
572
|
module.exports.__wbg_new_405e22f390576ce2 = function() {
|
|
490
573
|
const ret = new Object();
|
|
491
574
|
return ret;
|
|
@@ -511,6 +594,21 @@ module.exports.__wbg_new_a12002a7f91c75be = function(arg0) {
|
|
|
511
594
|
return ret;
|
|
512
595
|
};
|
|
513
596
|
|
|
597
|
+
module.exports.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) {
|
|
598
|
+
const ret = new Function(getStringFromWasm0(arg0, arg1));
|
|
599
|
+
return ret;
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
module.exports.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) {
|
|
603
|
+
const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0);
|
|
604
|
+
return ret;
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
module.exports.__wbg_newwithlength_a381634e90c276d4 = function(arg0) {
|
|
608
|
+
const ret = new Uint8Array(arg0 >>> 0);
|
|
609
|
+
return ret;
|
|
610
|
+
};
|
|
611
|
+
|
|
514
612
|
module.exports.__wbg_next_25feadfc0913fea9 = function(arg0) {
|
|
515
613
|
const ret = arg0.next;
|
|
516
614
|
return ret;
|
|
@@ -521,11 +619,30 @@ module.exports.__wbg_next_6574e1a8a62d1055 = function() { return handleError(fun
|
|
|
521
619
|
return ret;
|
|
522
620
|
}, arguments) };
|
|
523
621
|
|
|
622
|
+
module.exports.__wbg_node_e1f24f89a7336c2e = function(arg0) {
|
|
623
|
+
const ret = arg0.node;
|
|
624
|
+
return ret;
|
|
625
|
+
};
|
|
626
|
+
|
|
524
627
|
module.exports.__wbg_now_807e54c39636c349 = function() {
|
|
525
628
|
const ret = Date.now();
|
|
526
629
|
return ret;
|
|
527
630
|
};
|
|
528
631
|
|
|
632
|
+
module.exports.__wbg_process_3975fd6c72f520aa = function(arg0) {
|
|
633
|
+
const ret = arg0.process;
|
|
634
|
+
return ret;
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
module.exports.__wbg_randomFillSync_f8c153b79f285817 = function() { return handleError(function (arg0, arg1) {
|
|
638
|
+
arg0.randomFillSync(arg1);
|
|
639
|
+
}, arguments) };
|
|
640
|
+
|
|
641
|
+
module.exports.__wbg_require_b74f47fc2d022fd6 = function() { return handleError(function () {
|
|
642
|
+
const ret = module.require;
|
|
643
|
+
return ret;
|
|
644
|
+
}, arguments) };
|
|
645
|
+
|
|
529
646
|
module.exports.__wbg_set_37837023f3d740e8 = function(arg0, arg1, arg2) {
|
|
530
647
|
arg0[arg1 >>> 0] = arg2;
|
|
531
648
|
};
|
|
@@ -551,11 +668,41 @@ module.exports.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
|
|
|
551
668
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
552
669
|
};
|
|
553
670
|
|
|
671
|
+
module.exports.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() {
|
|
672
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
673
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
module.exports.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() {
|
|
677
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
678
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
module.exports.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() {
|
|
682
|
+
const ret = typeof self === 'undefined' ? null : self;
|
|
683
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
module.exports.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() {
|
|
687
|
+
const ret = typeof window === 'undefined' ? null : window;
|
|
688
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
module.exports.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) {
|
|
692
|
+
const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
|
|
693
|
+
return ret;
|
|
694
|
+
};
|
|
695
|
+
|
|
554
696
|
module.exports.__wbg_value_cd1ffa7b1ab794f1 = function(arg0) {
|
|
555
697
|
const ret = arg0.value;
|
|
556
698
|
return ret;
|
|
557
699
|
};
|
|
558
700
|
|
|
701
|
+
module.exports.__wbg_versions_4e31226f5e8dc909 = function(arg0) {
|
|
702
|
+
const ret = arg0.versions;
|
|
703
|
+
return ret;
|
|
704
|
+
};
|
|
705
|
+
|
|
559
706
|
module.exports.__wbindgen_bigint_from_i64 = function(arg0) {
|
|
560
707
|
const ret = arg0;
|
|
561
708
|
return ret;
|
|
Binary file
|
|
@@ -5,12 +5,15 @@ export const __wbg_wasmdatabase_free: (a: number, b: number) => void;
|
|
|
5
5
|
export const __wbg_wasmquerystream_free: (a: number, b: number) => void;
|
|
6
6
|
export const wasmdatabase_clear: (a: number) => void;
|
|
7
7
|
export const wasmdatabase_execute: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
8
|
-
export const
|
|
8
|
+
export const wasmdatabase_executeBuffer: (a: number, b: number, c: number, d: any) => [number, number, number, number];
|
|
9
|
+
export const wasmdatabase_explain: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
10
|
+
export const wasmdatabase_loadSnapshot: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
9
11
|
export const wasmdatabase_new: () => number;
|
|
10
12
|
export const wasmdatabase_nodeCount: (a: number) => number;
|
|
11
13
|
export const wasmdatabase_openStream: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
14
|
+
export const wasmdatabase_profile: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
12
15
|
export const wasmdatabase_relationshipCount: (a: number) => number;
|
|
13
|
-
export const
|
|
16
|
+
export const wasmdatabase_saveSnapshot: (a: number, b: any) => [number, number, number, number];
|
|
14
17
|
export const wasmdatabase_transaction: (a: number, b: any, c: number, d: number) => [number, number, number];
|
|
15
18
|
export const wasmquerystream_close: (a: number) => void;
|
|
16
19
|
export const wasmquerystream_columns: (a: number) => [number, number, number];
|
package/pkg-node/package.json
CHANGED
package/pkg-web/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# lora-wasm
|
|
2
2
|
|
|
3
|
-
WebAssembly bindings for the [Lora](
|
|
3
|
+
WebAssembly bindings for the [Lora](../../../README.md) in-memory graph
|
|
4
4
|
database. The package is designed for browsers and Node.js and exposes a
|
|
5
5
|
**strongly typed, async-facing API** that keeps the main thread responsive:
|
|
6
6
|
heavy query work can run inside a Web Worker while your UI code simply awaits
|
|
7
7
|
the result.
|
|
8
8
|
|
|
9
|
-
> **
|
|
9
|
+
> **Package:** `@loradb/lora-wasm`.
|
|
10
10
|
|
|
11
11
|
## Build
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
cd crates/lora-wasm
|
|
14
|
+
cd crates/bindings/lora-wasm
|
|
15
15
|
npm install
|
|
16
16
|
npm run build # wasm-pack (node + bundler) + tsc
|
|
17
17
|
npm test # vitest
|
|
@@ -52,7 +52,7 @@ fails during startup, the package emits one `console.warn` and falls back to
|
|
|
52
52
|
the in-process WASM engine so the app can still run.
|
|
53
53
|
|
|
54
54
|
```ts
|
|
55
|
-
import { createDatabase, isNode } from "lora-wasm";
|
|
55
|
+
import { createDatabase, isNode } from "@loradb/lora-wasm";
|
|
56
56
|
|
|
57
57
|
const db = await createDatabase(); // Worker-backed in browsers when possible
|
|
58
58
|
await db.execute("CREATE (:Person {name: $n})", { n: "Alice" });
|
|
@@ -63,6 +63,37 @@ for (const row of r.rows) {
|
|
|
63
63
|
}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
### Explain & Profile
|
|
67
|
+
|
|
68
|
+
`db.explain()` and `db.profile()` are first-class methods alongside
|
|
69
|
+
`db.execute()`. They are intentionally *separate calls*, not a flag
|
|
70
|
+
on `execute()`, so plan inspection and runtime metrics must be
|
|
71
|
+
requested explicitly.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
const plan = await db.explain(
|
|
75
|
+
"MATCH (p:Person) WHERE p.name = $name RETURN p",
|
|
76
|
+
{ name: "Alice" },
|
|
77
|
+
);
|
|
78
|
+
console.log(plan.shape); // "readOnly"
|
|
79
|
+
console.log(plan.tree.operator);
|
|
80
|
+
|
|
81
|
+
const profile = await db.profile(
|
|
82
|
+
"MATCH (p:Person) WHERE p.name = $name RETURN p",
|
|
83
|
+
{ name: "Alice" },
|
|
84
|
+
);
|
|
85
|
+
console.log(profile.metrics.totalElapsedNs);
|
|
86
|
+
console.log(profile.metrics.perOperator); // per-step inclusive timing
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`explain()` never invokes the executor — calling it on a mutating
|
|
90
|
+
query (`CREATE`, `MERGE`, `SET`, `DELETE`, `REMOVE`) leaves the graph
|
|
91
|
+
untouched.
|
|
92
|
+
|
|
93
|
+
> **`profile()` executes the query for real.** Mutating queries
|
|
94
|
+
> produce the same side effects as `execute()`. Use `explain()` to
|
|
95
|
+
> inspect a mutating plan without running it.
|
|
96
|
+
|
|
66
97
|
To force the in-process engine:
|
|
67
98
|
|
|
68
99
|
```ts
|
|
@@ -84,7 +115,7 @@ const db = await createDatabase({ warnOnFallback: false });
|
|
|
84
115
|
### 2. Explicit main-thread WASM
|
|
85
116
|
|
|
86
117
|
```ts
|
|
87
|
-
import { createMainThreadDatabase } from "lora-wasm";
|
|
118
|
+
import { createMainThreadDatabase } from "@loradb/lora-wasm";
|
|
88
119
|
|
|
89
120
|
const db = await createMainThreadDatabase();
|
|
90
121
|
```
|
|
@@ -116,35 +147,36 @@ useful for tests and for swapping execution backends behind the same API.
|
|
|
116
147
|
|
|
117
148
|
## Snapshots
|
|
118
149
|
|
|
119
|
-
WASM has no filesystem access, so
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
`
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
150
|
+
WASM has no filesystem access, so snapshots never accept string paths.
|
|
151
|
+
`saveSnapshot()` defaults to `Uint8Array`, and can also return `ArrayBuffer`,
|
|
152
|
+
`Blob`, `Response`, `ReadableStream`, or an object `URL`. `loadSnapshot`
|
|
153
|
+
accepts `URL`, `Uint8Array`, `ArrayBuffer`, `Blob`, `Response`, and web
|
|
154
|
+
`ReadableStream<Uint8Array | ArrayBuffer>`. The bytes use the database
|
|
155
|
+
snapshot codec (`LORACOL1`) and can be loaded by native LoraDB. Older store
|
|
156
|
+
snapshots use the current `LORACOL1` columnar format.
|
|
157
|
+
Snapshot bytes are uncompressed by default; pass `{ compression: "gzip" }` or
|
|
158
|
+
`{ compression: { format: "gzip", level: 1 } }` to save smaller
|
|
159
|
+
WASM-portable snapshots. Gzip levels `0..9` are supported; level `1` is the
|
|
160
|
+
fast default.
|
|
127
161
|
|
|
128
162
|
```ts
|
|
129
|
-
import { createDatabase } from "lora-wasm";
|
|
163
|
+
import { createDatabase } from "@loradb/lora-wasm";
|
|
130
164
|
|
|
131
165
|
const db = await createDatabase();
|
|
132
166
|
await db.execute("CREATE (:Person {name: 'Alice'})");
|
|
133
167
|
|
|
134
|
-
const bytes = await db.
|
|
135
|
-
const
|
|
136
|
-
const blob = await db.saveSnapshot({ format: "blob" });
|
|
137
|
-
await db.saveSnapshot({ format: "
|
|
168
|
+
const bytes = await db.saveSnapshot();
|
|
169
|
+
const compressed = await db.saveSnapshot({ compression: "gzip" });
|
|
170
|
+
const blob = await db.saveSnapshot({ format: "blob", compression: "gzip" });
|
|
171
|
+
const response = await db.saveSnapshot({ format: "response" });
|
|
138
172
|
|
|
139
173
|
await db.loadSnapshot(bytes);
|
|
174
|
+
await db.loadSnapshot(compressed);
|
|
140
175
|
await db.loadSnapshot(blob);
|
|
141
|
-
await db.loadSnapshot(
|
|
176
|
+
await db.loadSnapshot(response);
|
|
142
177
|
await db.loadSnapshot(new URL("/graph.lorasnap", location.href));
|
|
143
178
|
```
|
|
144
179
|
|
|
145
|
-
`loadSnapshotFromBytes(bytes)` remains available for the narrow
|
|
146
|
-
`Uint8Array`-only path.
|
|
147
|
-
|
|
148
180
|
## Typed value model
|
|
149
181
|
|
|
150
182
|
| TS type | Runtime shape |
|
|
@@ -171,31 +203,42 @@ Helper constructors: `date`, `time`, `datetime`, `localtime`, `localdatetime`,
|
|
|
171
203
|
`isNode`, `isRelationship`, `isPath`, `isPoint`, `isTemporal`.
|
|
172
204
|
|
|
173
205
|
> `distance()` on WGS-84-3D points ignores `height`. See
|
|
174
|
-
> [functions reference](
|
|
206
|
+
> [functions reference](../../../apps/loradb.com/docs/functions/overview.md) for the spatial
|
|
175
207
|
> reference and out-of-scope operations.
|
|
176
208
|
|
|
177
209
|
## Errors
|
|
178
210
|
|
|
179
|
-
`db.execute(...)` and the worker client throw `LoraError` with a
|
|
180
|
-
`code
|
|
211
|
+
`db.execute(...)` and the worker client throw `LoraError` with a
|
|
212
|
+
narrowed `code` from the `LoraErrorCode` union — these mirror
|
|
213
|
+
`lora_database::LoraErrorCode` 1:1, plus `WORKER_ERROR` and `UNKNOWN`.
|
|
181
214
|
|
|
182
|
-
|
|
183
|
-
|
|
215
|
+
Common ones:
|
|
216
|
+
|
|
217
|
+
- `LORA_PARSE` — Cypher syntax could not be parsed
|
|
218
|
+
- `LORA_SEMANTIC` — analysis failure (unknown variable, label, type mismatch, …)
|
|
219
|
+
- `LORA_INVALID_PARAMS` — a parameter value could not be coerced to a `LoraValue`
|
|
220
|
+
- `LORA_INVALID_VECTOR` — vector value failed dimension / coordinate-type validation
|
|
221
|
+
- `LORA_TIMEOUT` — query exceeded its cooperative deadline
|
|
222
|
+
- `LORA_IO`, `LORA_SNAPSHOT_CODEC`, `LORA_SNAPSHOT_CRYPTO` — storage / snapshot failures
|
|
223
|
+
- `LORA_INTERNAL` — last-resort fallback when the engine cannot classify the failure
|
|
184
224
|
- `WORKER_ERROR` — worker transport / lifecycle failure (worker client only)
|
|
185
225
|
|
|
226
|
+
See `ts/types.ts` (`LoraErrorCode`) for the full list.
|
|
227
|
+
|
|
186
228
|
## Shared type contract
|
|
187
229
|
|
|
188
230
|
The public TypeScript value model (`LoraValue`, `LoraNode`, …,
|
|
189
231
|
`QueryResult`, `LoraError`) lives in a single canonical file at
|
|
190
|
-
`crates/shared-ts/types.ts` and is copied into each consumer package by
|
|
232
|
+
`crates/bindings/shared-ts/types.ts` and is copied into each consumer package by
|
|
191
233
|
its `sync:types` npm script. CI runs `verify:types` to fail on drift.
|
|
192
234
|
That keeps `lora-node` and `lora-wasm` locked to one identical
|
|
193
235
|
public surface — consumers can swap backends without rewriting types.
|
|
194
236
|
|
|
195
237
|
## Known limitations
|
|
196
238
|
|
|
197
|
-
- The wasm module
|
|
198
|
-
|
|
239
|
+
- The wasm module runs inside one JavaScript runtime. Auto-commit reads can
|
|
240
|
+
overlap on engine snapshots; write commits serialize. Use more Workers for
|
|
241
|
+
separate graphs or stronger UI isolation.
|
|
199
242
|
- I64 values are delivered as JS `number` and lose precision above 2^53.
|
|
200
243
|
Applications that need bigint precision should use the native
|
|
201
244
|
`lora-node` binding instead.
|
|
@@ -227,7 +270,7 @@ public surface — consumers can swap backends without rewriting types.
|
|
|
227
270
|
forms, parameter validation errors, and concurrent queries across the
|
|
228
271
|
worker message protocol.
|
|
229
272
|
- The TypeScript public contract is shared verbatim with `lora-node`
|
|
230
|
-
via `crates/shared-ts/types.ts`, enforced by `verify:types` in CI.
|
|
273
|
+
via `crates/bindings/shared-ts/types.ts`, enforced by `verify:types` in CI.
|
|
231
274
|
- `npm pack --dry-run` produces a 45-file, 6.6 MB tarball containing
|
|
232
275
|
all three wasm bundles plus the compiled TS wrapper. No `file:` deps,
|
|
233
276
|
no postinstall scripts.
|
|
@@ -244,9 +287,8 @@ public surface — consumers can swap backends without rewriting types.
|
|
|
244
287
|
- I64 precision is capped at `Number.MAX_SAFE_INTEGER`. For larger
|
|
245
288
|
integer properties we need a `bigint`-aware serializer on the wasm
|
|
246
289
|
boundary.
|
|
247
|
-
- The engine is synchronous inside wasm
|
|
248
|
-
|
|
249
|
-
possible), or an engine-level cooperative scheduler.
|
|
290
|
+
- The engine is synchronous inside wasm once a call enters the module. A slow
|
|
291
|
+
query blocks that Worker until completion.
|
|
250
292
|
- No query cancellation or progress streaming crosses the Worker
|
|
251
293
|
boundary; a slow query blocks that Worker until completion.
|
|
252
294
|
|
package/pkg-web/lora_wasm.d.ts
CHANGED
|
@@ -21,23 +21,35 @@ export class WasmDatabase {
|
|
|
21
21
|
* transaction. Returns an array of query results in statement order.
|
|
22
22
|
*/
|
|
23
23
|
transaction(statements: any, mode?: string | null): any;
|
|
24
|
-
relationshipCount(): number;
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
25
|
+
* Replace the graph state with a database snapshot decoded from `bytes`.
|
|
26
|
+
* Legacy store snapshot bytes are accepted for compatibility.
|
|
27
|
+
*
|
|
28
|
+
* Returns a plain object matching the shape of `SnapshotMeta`:
|
|
29
|
+
* `{ formatVersion, nodeCount, relationshipCount, walLsn }`.
|
|
30
|
+
*/
|
|
31
|
+
loadSnapshot(bytes: Uint8Array, options: any): any;
|
|
32
|
+
/**
|
|
33
|
+
* Serialize the graph into database snapshot bytes. The caller is
|
|
34
|
+
* responsible for writing them to IndexedDB, localStorage, a server, or
|
|
35
|
+
* another host-provided store — WASM has no direct filesystem access.
|
|
36
|
+
* The returned bytes can later be passed to `loadSnapshot` on any
|
|
37
|
+
* `WasmDatabase` instance.
|
|
30
38
|
*
|
|
31
39
|
* Returns the serialized bytes as a `Uint8Array`.
|
|
32
40
|
*/
|
|
33
|
-
|
|
41
|
+
saveSnapshot(options: any): Uint8Array;
|
|
34
42
|
/**
|
|
35
|
-
*
|
|
43
|
+
* Execute a Lora query and return the result as a binary buffer.
|
|
36
44
|
*
|
|
37
|
-
*
|
|
38
|
-
* `{
|
|
45
|
+
* Wire format is the shared `lora_binding_buffer` layout. The TS
|
|
46
|
+
* wrapper decodes it once into the same `{ columns, rows }` shape
|
|
47
|
+
* `execute()` returns, but in a tight V8 loop instead of going
|
|
48
|
+
* through `serde_wasm_bindgen` value-by-value. Materially faster
|
|
49
|
+
* on bulk reads.
|
|
39
50
|
*/
|
|
40
|
-
|
|
51
|
+
executeBuffer(query: string, params: any): Uint8Array;
|
|
52
|
+
relationshipCount(): number;
|
|
41
53
|
constructor();
|
|
42
54
|
clear(): void;
|
|
43
55
|
/**
|
|
@@ -48,6 +60,21 @@ export class WasmDatabase {
|
|
|
48
60
|
* as a plain JS object (structured-clonable).
|
|
49
61
|
*/
|
|
50
62
|
execute(query: string, params: any): any;
|
|
63
|
+
/**
|
|
64
|
+
* Compile a query and return its plan without executing it.
|
|
65
|
+
*
|
|
66
|
+
* Mutating queries (CREATE / MERGE / SET / DELETE / REMOVE) leave
|
|
67
|
+
* the graph untouched — this method never runs the executor.
|
|
68
|
+
*/
|
|
69
|
+
explain(query: string, params: any): any;
|
|
70
|
+
/**
|
|
71
|
+
* Execute a query and return the plan plus runtime metrics.
|
|
72
|
+
*
|
|
73
|
+
* **PROFILE executes the query for real.** Mutating queries are
|
|
74
|
+
* persisted exactly as in `execute()`. Use `explain()` to inspect
|
|
75
|
+
* a mutating plan without running it.
|
|
76
|
+
*/
|
|
77
|
+
profile(query: string, params: any): any;
|
|
51
78
|
}
|
|
52
79
|
export class WasmQueryStream {
|
|
53
80
|
private constructor();
|
|
@@ -65,12 +92,15 @@ export interface InitOutput {
|
|
|
65
92
|
readonly __wbg_wasmquerystream_free: (a: number, b: number) => void;
|
|
66
93
|
readonly wasmdatabase_clear: (a: number) => void;
|
|
67
94
|
readonly wasmdatabase_execute: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
68
|
-
readonly
|
|
95
|
+
readonly wasmdatabase_executeBuffer: (a: number, b: number, c: number, d: any) => [number, number, number, number];
|
|
96
|
+
readonly wasmdatabase_explain: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
97
|
+
readonly wasmdatabase_loadSnapshot: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
69
98
|
readonly wasmdatabase_new: () => number;
|
|
70
99
|
readonly wasmdatabase_nodeCount: (a: number) => number;
|
|
71
100
|
readonly wasmdatabase_openStream: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
101
|
+
readonly wasmdatabase_profile: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
72
102
|
readonly wasmdatabase_relationshipCount: (a: number) => number;
|
|
73
|
-
readonly
|
|
103
|
+
readonly wasmdatabase_saveSnapshot: (a: number, b: any) => [number, number, number, number];
|
|
74
104
|
readonly wasmdatabase_transaction: (a: number, b: any, c: number, d: number) => [number, number, number];
|
|
75
105
|
readonly wasmquerystream_close: (a: number) => void;
|
|
76
106
|
readonly wasmquerystream_columns: (a: number) => [number, number, number];
|