@loradb/lora-wasm 0.4.0 → 0.5.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 +71 -7
- package/dist/index.d.ts +71 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -12
- package/dist/index.js.map +1 -1
- package/dist/snapshot.d.ts +22 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +107 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/worker-client.d.ts +28 -0
- package/dist/worker-client.d.ts.map +1 -1
- package/dist/worker-client.js +100 -0
- package/dist/worker-client.js.map +1 -1
- package/dist/worker-protocol.d.ts +24 -1
- package/dist/worker-protocol.d.ts.map +1 -1
- package/dist/worker.js +52 -0
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/pkg-bundler/README.md +71 -7
- package/pkg-bundler/lora_wasm.d.ts +17 -0
- package/pkg-bundler/lora_wasm_bg.js +82 -0
- package/pkg-bundler/lora_wasm_bg.wasm +0 -0
- package/pkg-bundler/lora_wasm_bg.wasm.d.ts +6 -0
- package/pkg-bundler/package.json +1 -1
- package/pkg-node/README.md +71 -7
- package/pkg-node/lora_wasm.d.ts +17 -0
- package/pkg-node/lora_wasm.js +83 -0
- package/pkg-node/lora_wasm_bg.wasm +0 -0
- package/pkg-node/lora_wasm_bg.wasm.d.ts +6 -0
- package/pkg-node/package.json +1 -1
- package/pkg-web/README.md +71 -7
- package/pkg-web/lora_wasm.d.ts +23 -0
- package/pkg-web/lora_wasm.js +82 -0
- package/pkg-web/lora_wasm_bg.wasm +0 -0
- package/pkg-web/lora_wasm_bg.wasm.d.ts +6 -0
- package/pkg-web/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,19 +37,24 @@ npm run test:browser
|
|
|
37
37
|
npm run pack:dry
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
##
|
|
40
|
+
## Execution modes
|
|
41
41
|
|
|
42
|
-
### 1.
|
|
42
|
+
### 1. Default: Worker first, main-thread fallback
|
|
43
43
|
|
|
44
44
|
`lora-wasm` is **async-only** — the sole initialization pattern is
|
|
45
45
|
`createDatabase()`, which bootstraps the WASM module on first call.
|
|
46
46
|
There is no synchronous constructor and no `Database.create()`
|
|
47
47
|
static; `Database` is a type-only export.
|
|
48
48
|
|
|
49
|
+
In browser-like hosts, `createDatabase()` tries to spawn the packaged module
|
|
50
|
+
Worker first and pings it before returning. If the Worker cannot be created or
|
|
51
|
+
fails during startup, the package emits one `console.warn` and falls back to
|
|
52
|
+
the in-process WASM engine so the app can still run.
|
|
53
|
+
|
|
49
54
|
```ts
|
|
50
55
|
import { createDatabase, isNode } from "lora-wasm";
|
|
51
56
|
|
|
52
|
-
const db = await createDatabase();
|
|
57
|
+
const db = await createDatabase(); // Worker-backed in browsers when possible
|
|
53
58
|
await db.execute("CREATE (:Person {name: $n})", { n: "Alice" });
|
|
54
59
|
|
|
55
60
|
const r = await db.execute("MATCH (n:Person) RETURN n");
|
|
@@ -58,7 +63,36 @@ for (const row of r.rows) {
|
|
|
58
63
|
}
|
|
59
64
|
```
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
To force the in-process engine:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const db = await createDatabase({ runtime: "main-thread" });
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To require Worker startup instead of falling back:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const db = await createDatabase({ runtime: "worker" });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
To disable the fallback warning:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
const db = await createDatabase({ warnOnFallback: false });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2. Explicit main-thread WASM
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { createMainThreadDatabase } from "lora-wasm";
|
|
88
|
+
|
|
89
|
+
const db = await createMainThreadDatabase();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. Custom Web Worker
|
|
93
|
+
|
|
94
|
+
Use this when you need to control the Worker URL, lifecycle, bundler entry, or
|
|
95
|
+
pooling strategy.
|
|
62
96
|
|
|
63
97
|
```ts
|
|
64
98
|
import { createWorkerDatabase } from "lora-wasm/worker-client";
|
|
@@ -75,11 +109,42 @@ const { rows } = await db.execute("MATCH (n) RETURN n.n AS n");
|
|
|
75
109
|
The worker entry (`ts/worker.ts`) hosts the WASM module. The main thread only
|
|
76
110
|
posts messages, so long-running queries never block the event loop / UI.
|
|
77
111
|
|
|
78
|
-
###
|
|
112
|
+
### 4. In-process but typed like the worker (advanced)
|
|
79
113
|
|
|
80
114
|
The same `createWorkerDatabase` signature accepts any `WorkerLike` object —
|
|
81
115
|
useful for tests and for swapping execution backends behind the same API.
|
|
82
116
|
|
|
117
|
+
## Snapshots
|
|
118
|
+
|
|
119
|
+
WASM has no filesystem access, so `saveSnapshot()` defaults to a `Uint8Array`.
|
|
120
|
+
It also accepts typed formats: `"base64"` returns base64 text, `"blob"` returns
|
|
121
|
+
a `Blob`, and `"download"` triggers a browser download from the main thread.
|
|
122
|
+
|
|
123
|
+
`loadSnapshot` accepts a `WasmSnapshotSource`: `Uint8Array`, `ArrayBuffer`,
|
|
124
|
+
`Blob`/`File`, `Response`, web `ReadableStream`, string URL, or `URL`. It does
|
|
125
|
+
not include Node `Buffer`; use `Uint8Array` bytes when running the WASM package
|
|
126
|
+
from Node.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { createDatabase } from "lora-wasm";
|
|
130
|
+
|
|
131
|
+
const db = await createDatabase();
|
|
132
|
+
await db.execute("CREATE (:Person {name: 'Alice'})");
|
|
133
|
+
|
|
134
|
+
const bytes = await db.saveSnapshotToBytes();
|
|
135
|
+
const sameBytes = await db.saveSnapshot("binary");
|
|
136
|
+
const blob = await db.saveSnapshot({ format: "blob" });
|
|
137
|
+
await db.saveSnapshot({ format: "download", filename: "graph.lorasnap" });
|
|
138
|
+
|
|
139
|
+
await db.loadSnapshot(bytes);
|
|
140
|
+
await db.loadSnapshot(blob);
|
|
141
|
+
await db.loadSnapshot(new Response(bytes).body!);
|
|
142
|
+
await db.loadSnapshot(new URL("/graph.lorasnap", location.href));
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`loadSnapshotFromBytes(bytes)` remains available for the narrow
|
|
146
|
+
`Uint8Array`-only path.
|
|
147
|
+
|
|
83
148
|
## Typed value model
|
|
84
149
|
|
|
85
150
|
| TS type | Runtime shape |
|
|
@@ -140,8 +205,7 @@ public surface — consumers can swap backends without rewriting types.
|
|
|
140
205
|
millisecond-granular, so the nanosecond field on returned values is
|
|
141
206
|
zero below the millisecond boundary.
|
|
142
207
|
- Engine errors cross the worker boundary as `LoraError` with a
|
|
143
|
-
narrowed `code`; the engine does not currently
|
|
144
|
-
or offer cancellation.
|
|
208
|
+
narrowed `code`; the engine does not currently offer query cancellation.
|
|
145
209
|
|
|
146
210
|
## Feasibility assessment
|
|
147
211
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* lora-wasm — typed WebAssembly bindings for the Lora graph engine.
|
|
3
3
|
*
|
|
4
|
-
* This entry targets Node.js (ESM) and
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
4
|
+
* This entry targets Node.js (ESM) and browser bundlers. In browser-like
|
|
5
|
+
* hosts, `createDatabase()` tries to start the packaged Web Worker first so
|
|
6
|
+
* query work stays off the main thread. If that fails, it warns once and
|
|
7
|
+
* falls back to the in-process WASM engine.
|
|
7
8
|
*
|
|
8
9
|
* **Initialization is async-only.** The one canonical entry point is
|
|
9
10
|
* `createDatabase()`; the WASM module is bootstrapped inside it before the
|
|
@@ -16,8 +17,11 @@
|
|
|
16
17
|
*/
|
|
17
18
|
import type { LoraParams, LoraValue, QueryResult } from "./types.js";
|
|
18
19
|
import { WasmDatabase } from "./loader-node.js";
|
|
20
|
+
import type { WorkerDatabase } from "./worker-client.js";
|
|
21
|
+
import type { WasmSnapshotSource } from "./snapshot.js";
|
|
19
22
|
export * from "./types.js";
|
|
20
|
-
export { createWorkerDatabase, type WorkerDatabase } from "./worker-client.js";
|
|
23
|
+
export { createWorkerDatabase, type WorkerDatabase, type WorkerLike, } from "./worker-client.js";
|
|
24
|
+
export type { WasmSnapshotSaveFormat, WasmSnapshotSaveOptions, WasmSnapshotSource, } from "./snapshot.js";
|
|
21
25
|
/**
|
|
22
26
|
* Metadata returned by `saveSnapshotToBytes` / `loadSnapshotFromBytes`.
|
|
23
27
|
* Mirrors the Rust `SnapshotMeta` struct and matches the shape used by
|
|
@@ -30,6 +34,34 @@ export interface SnapshotMeta {
|
|
|
30
34
|
relationshipCount: number;
|
|
31
35
|
walLsn: number | null;
|
|
32
36
|
}
|
|
37
|
+
export interface CreateDatabaseOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Select where the WASM engine runs.
|
|
40
|
+
*
|
|
41
|
+
* - `"auto"` tries a Web Worker first when available, then falls back to
|
|
42
|
+
* the main thread.
|
|
43
|
+
* - `"worker"` requires a Web Worker and rejects if startup fails.
|
|
44
|
+
* - `"main-thread"` skips Worker startup and runs the engine in-process.
|
|
45
|
+
*
|
|
46
|
+
* Defaults to `"auto"`.
|
|
47
|
+
*/
|
|
48
|
+
runtime?: "auto" | "worker" | "main-thread";
|
|
49
|
+
/**
|
|
50
|
+
* Emit `console.warn` if worker startup fails and the factory falls back to
|
|
51
|
+
* the main-thread WASM engine in `"auto"` mode. Defaults to `true`.
|
|
52
|
+
*/
|
|
53
|
+
warnOnFallback?: boolean;
|
|
54
|
+
}
|
|
55
|
+
export type TransactionMode = "read_write" | "read_only" | "readwrite" | "readonly" | "rw" | "ro";
|
|
56
|
+
export interface TransactionStatement {
|
|
57
|
+
query: string;
|
|
58
|
+
params?: LoraParams | null;
|
|
59
|
+
}
|
|
60
|
+
export interface RowStream<T extends Record<string, LoraValue> = Record<string, LoraValue>> extends AsyncIterableIterator<T> {
|
|
61
|
+
columns(): string[] | Promise<string[]>;
|
|
62
|
+
toArray(): Promise<T[]>;
|
|
63
|
+
close(): void;
|
|
64
|
+
}
|
|
33
65
|
/**
|
|
34
66
|
* In-memory Lora graph database running on the WASM engine.
|
|
35
67
|
*
|
|
@@ -42,6 +74,9 @@ declare class DatabaseImpl {
|
|
|
42
74
|
#private;
|
|
43
75
|
constructor(inner: InstanceType<typeof WasmDatabase>);
|
|
44
76
|
execute<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): Promise<QueryResult<T>>;
|
|
77
|
+
stream<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): RowStream<T>;
|
|
78
|
+
rows<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): RowStream<T>;
|
|
79
|
+
transaction<T extends Record<string, LoraValue> = Record<string, LoraValue>>(statements: TransactionStatement[], mode?: TransactionMode): Promise<Array<QueryResult<T>>>;
|
|
45
80
|
clear(): Promise<void>;
|
|
46
81
|
nodeCount(): Promise<number>;
|
|
47
82
|
relationshipCount(): Promise<number>;
|
|
@@ -52,11 +87,32 @@ declare class DatabaseImpl {
|
|
|
52
87
|
* them back to `loadSnapshotFromBytes` on a future database instance.
|
|
53
88
|
*/
|
|
54
89
|
saveSnapshotToBytes(): Promise<Uint8Array>;
|
|
90
|
+
saveSnapshot(): Promise<Uint8Array>;
|
|
91
|
+
saveSnapshot(format: "binary"): Promise<Uint8Array>;
|
|
92
|
+
saveSnapshot(format: "base64"): Promise<string>;
|
|
93
|
+
saveSnapshot(format: "blob"): Promise<Blob>;
|
|
94
|
+
saveSnapshot(format: "download"): Promise<void>;
|
|
95
|
+
saveSnapshot(options: {
|
|
96
|
+
format: "binary";
|
|
97
|
+
}): Promise<Uint8Array>;
|
|
98
|
+
saveSnapshot(options: {
|
|
99
|
+
format: "base64";
|
|
100
|
+
}): Promise<string>;
|
|
101
|
+
saveSnapshot(options: {
|
|
102
|
+
format: "blob";
|
|
103
|
+
mimeType?: string;
|
|
104
|
+
}): Promise<Blob>;
|
|
105
|
+
saveSnapshot(options: {
|
|
106
|
+
format: "download";
|
|
107
|
+
filename?: string;
|
|
108
|
+
mimeType?: string;
|
|
109
|
+
}): Promise<void>;
|
|
55
110
|
/**
|
|
56
111
|
* Replace the current graph state with a snapshot decoded from `bytes`.
|
|
57
112
|
* Returns metadata describing the restored snapshot.
|
|
58
113
|
*/
|
|
59
114
|
loadSnapshotFromBytes(bytes: Uint8Array): Promise<SnapshotMeta>;
|
|
115
|
+
loadSnapshot(source: WasmSnapshotSource): Promise<SnapshotMeta>;
|
|
60
116
|
/** Release the underlying wasm handle. Subsequent calls will throw. */
|
|
61
117
|
dispose(): void;
|
|
62
118
|
}
|
|
@@ -66,14 +122,15 @@ declare class DatabaseImpl {
|
|
|
66
122
|
* Exported as a type only — there is no runtime `Database` value. To obtain
|
|
67
123
|
* an instance, always use `createDatabase()`.
|
|
68
124
|
*/
|
|
69
|
-
export type Database = DatabaseImpl;
|
|
125
|
+
export type Database = DatabaseImpl | WorkerDatabase;
|
|
70
126
|
/**
|
|
71
127
|
* Create and initialize a new in-memory LoraDB instance on the WASM engine.
|
|
72
128
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* the
|
|
129
|
+
* In browser-like hosts this factory tries the packaged Web Worker first,
|
|
130
|
+
* pings it, and returns the worker-backed database when startup succeeds.
|
|
131
|
+
* If worker construction or bootstrap fails it warns once and falls back to
|
|
132
|
+
* the main-thread WASM engine. Pass `{ runtime: "main-thread" }` to force the
|
|
133
|
+
* in-process engine, or `{ runtime: "worker" }` to require a Worker.
|
|
77
134
|
*
|
|
78
135
|
* ```ts
|
|
79
136
|
* import { createDatabase } from "lora-wasm";
|
|
@@ -82,9 +139,10 @@ export type Database = DatabaseImpl;
|
|
|
82
139
|
* const res = await db.execute("MATCH (n) RETURN count(n) AS n");
|
|
83
140
|
* ```
|
|
84
141
|
*
|
|
85
|
-
*
|
|
86
|
-
* `
|
|
87
|
-
*
|
|
142
|
+
* Use `createMainThreadDatabase()` when you explicitly want the in-process
|
|
143
|
+
* WASM engine, or `createWorkerDatabase(worker)` when you need to supply a
|
|
144
|
+
* custom Worker instance.
|
|
88
145
|
*/
|
|
89
|
-
export declare function
|
|
146
|
+
export declare function createMainThreadDatabase(): Promise<DatabaseImpl>;
|
|
147
|
+
export declare function createDatabase(options?: CreateDatabaseOptions): Promise<Database>;
|
|
90
148
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* lora-wasm — typed WebAssembly bindings for the Lora graph engine.
|
|
3
3
|
*
|
|
4
|
-
* This entry targets Node.js (ESM) and
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
4
|
+
* This entry targets Node.js (ESM) and browser bundlers. In browser-like
|
|
5
|
+
* hosts, `createDatabase()` tries to start the packaged Web Worker first so
|
|
6
|
+
* query work stays off the main thread. If that fails, it warns once and
|
|
7
|
+
* falls back to the in-process WASM engine.
|
|
7
8
|
*
|
|
8
9
|
* **Initialization is async-only.** The one canonical entry point is
|
|
9
10
|
* `createDatabase()`; the WASM module is bootstrapped inside it before the
|
|
@@ -16,8 +17,70 @@
|
|
|
16
17
|
*/
|
|
17
18
|
import { wrapError } from "./types.js";
|
|
18
19
|
import { WasmDatabase, init as wasmInit } from "./loader-node.js";
|
|
20
|
+
import { createWorkerDatabase } from "./worker-client.js";
|
|
21
|
+
import { downloadSnapshotBytes, resolveSnapshotSaveFormat, snapshotBytesToBase64, snapshotBytesToBlob, snapshotSourceToBytes, } from "./snapshot.js";
|
|
19
22
|
export * from "./types.js";
|
|
20
|
-
export { createWorkerDatabase } from "./worker-client.js";
|
|
23
|
+
export { createWorkerDatabase, } from "./worker-client.js";
|
|
24
|
+
class NativeRowStream {
|
|
25
|
+
#inner;
|
|
26
|
+
#closed = false;
|
|
27
|
+
constructor(inner) {
|
|
28
|
+
this.#inner = inner;
|
|
29
|
+
}
|
|
30
|
+
[Symbol.asyncIterator]() {
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
columns() {
|
|
34
|
+
try {
|
|
35
|
+
return this.#inner.columns();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
throw wrapError(err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async next() {
|
|
42
|
+
if (this.#closed) {
|
|
43
|
+
return { done: true, value: undefined };
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const row = this.#inner.next();
|
|
47
|
+
if (row === null) {
|
|
48
|
+
this.#closed = true;
|
|
49
|
+
return { done: true, value: undefined };
|
|
50
|
+
}
|
|
51
|
+
return { done: false, value: row };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
this.#closed = true;
|
|
55
|
+
throw wrapError(err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async return() {
|
|
59
|
+
this.close();
|
|
60
|
+
return { done: true, value: undefined };
|
|
61
|
+
}
|
|
62
|
+
async toArray() {
|
|
63
|
+
const rows = [];
|
|
64
|
+
for (;;) {
|
|
65
|
+
const next = await this.next();
|
|
66
|
+
if (next.done) {
|
|
67
|
+
return rows;
|
|
68
|
+
}
|
|
69
|
+
rows.push(next.value);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
close() {
|
|
73
|
+
if (this.#closed)
|
|
74
|
+
return;
|
|
75
|
+
this.#closed = true;
|
|
76
|
+
try {
|
|
77
|
+
this.#inner.close();
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
throw wrapError(err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
21
84
|
let bootstrapped = false;
|
|
22
85
|
function ensureBootstrapped() {
|
|
23
86
|
if (bootstrapped)
|
|
@@ -47,6 +110,27 @@ class DatabaseImpl {
|
|
|
47
110
|
throw wrapError(err);
|
|
48
111
|
}
|
|
49
112
|
}
|
|
113
|
+
stream(query, params) {
|
|
114
|
+
try {
|
|
115
|
+
const native = this.#inner;
|
|
116
|
+
return new NativeRowStream(native.openStream(query, params ?? null));
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
throw wrapError(err);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
rows(query, params) {
|
|
123
|
+
return this.stream(query, params);
|
|
124
|
+
}
|
|
125
|
+
async transaction(statements, mode = "read_write") {
|
|
126
|
+
try {
|
|
127
|
+
const native = this.#inner;
|
|
128
|
+
return native.transaction(statements, mode);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
throw wrapError(err);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
50
134
|
async clear() {
|
|
51
135
|
this.#inner.clear();
|
|
52
136
|
}
|
|
@@ -70,6 +154,20 @@ class DatabaseImpl {
|
|
|
70
154
|
throw wrapError(err);
|
|
71
155
|
}
|
|
72
156
|
}
|
|
157
|
+
async saveSnapshot(target) {
|
|
158
|
+
const options = resolveSnapshotSaveFormat(target);
|
|
159
|
+
const bytes = await this.saveSnapshotToBytes();
|
|
160
|
+
switch (options.format) {
|
|
161
|
+
case "binary":
|
|
162
|
+
return bytes;
|
|
163
|
+
case "base64":
|
|
164
|
+
return snapshotBytesToBase64(bytes);
|
|
165
|
+
case "blob":
|
|
166
|
+
return snapshotBytesToBlob(bytes, options.mimeType);
|
|
167
|
+
case "download":
|
|
168
|
+
return downloadSnapshotBytes(bytes, options.filename, options.mimeType);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
73
171
|
/**
|
|
74
172
|
* Replace the current graph state with a snapshot decoded from `bytes`.
|
|
75
173
|
* Returns metadata describing the restored snapshot.
|
|
@@ -82,18 +180,50 @@ class DatabaseImpl {
|
|
|
82
180
|
throw wrapError(err);
|
|
83
181
|
}
|
|
84
182
|
}
|
|
183
|
+
async loadSnapshot(source) {
|
|
184
|
+
try {
|
|
185
|
+
return this.#inner.loadSnapshotFromBytes(await snapshotSourceToBytes(source));
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
throw wrapError(err);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
85
191
|
/** Release the underlying wasm handle. Subsequent calls will throw. */
|
|
86
192
|
dispose() {
|
|
87
193
|
this.#inner.free();
|
|
88
194
|
}
|
|
89
195
|
}
|
|
196
|
+
let warnedWorkerFallback = false;
|
|
197
|
+
function requestedRuntime(options) {
|
|
198
|
+
return options?.runtime ?? "auto";
|
|
199
|
+
}
|
|
200
|
+
function shouldTryDefaultWorker(options) {
|
|
201
|
+
const runtime = requestedRuntime(options);
|
|
202
|
+
return runtime !== "main-thread" && typeof Worker !== "undefined";
|
|
203
|
+
}
|
|
204
|
+
function shouldFallbackToMainThread(options) {
|
|
205
|
+
return requestedRuntime(options) === "auto";
|
|
206
|
+
}
|
|
207
|
+
function warnWorkerFallback(err, options) {
|
|
208
|
+
if (options?.warnOnFallback === false || warnedWorkerFallback)
|
|
209
|
+
return;
|
|
210
|
+
warnedWorkerFallback = true;
|
|
211
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
212
|
+
console.warn(`[lora-wasm] Web Worker startup failed; falling back to main-thread WASM. ${detail}`);
|
|
213
|
+
}
|
|
214
|
+
function createDefaultWorker() {
|
|
215
|
+
return new Worker(new URL("./worker.js", import.meta.url), {
|
|
216
|
+
type: "module",
|
|
217
|
+
});
|
|
218
|
+
}
|
|
90
219
|
/**
|
|
91
220
|
* Create and initialize a new in-memory LoraDB instance on the WASM engine.
|
|
92
221
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* the
|
|
222
|
+
* In browser-like hosts this factory tries the packaged Web Worker first,
|
|
223
|
+
* pings it, and returns the worker-backed database when startup succeeds.
|
|
224
|
+
* If worker construction or bootstrap fails it warns once and falls back to
|
|
225
|
+
* the main-thread WASM engine. Pass `{ runtime: "main-thread" }` to force the
|
|
226
|
+
* in-process engine, or `{ runtime: "worker" }` to require a Worker.
|
|
97
227
|
*
|
|
98
228
|
* ```ts
|
|
99
229
|
* import { createDatabase } from "lora-wasm";
|
|
@@ -102,12 +232,39 @@ class DatabaseImpl {
|
|
|
102
232
|
* const res = await db.execute("MATCH (n) RETURN count(n) AS n");
|
|
103
233
|
* ```
|
|
104
234
|
*
|
|
105
|
-
*
|
|
106
|
-
* `
|
|
107
|
-
*
|
|
235
|
+
* Use `createMainThreadDatabase()` when you explicitly want the in-process
|
|
236
|
+
* WASM engine, or `createWorkerDatabase(worker)` when you need to supply a
|
|
237
|
+
* custom Worker instance.
|
|
108
238
|
*/
|
|
109
|
-
export async function
|
|
239
|
+
export async function createMainThreadDatabase() {
|
|
110
240
|
ensureBootstrapped();
|
|
111
241
|
return new DatabaseImpl(new WasmDatabase());
|
|
112
242
|
}
|
|
243
|
+
export async function createDatabase(options = {}) {
|
|
244
|
+
if (shouldTryDefaultWorker(options)) {
|
|
245
|
+
let worker = null;
|
|
246
|
+
try {
|
|
247
|
+
worker = createDefaultWorker();
|
|
248
|
+
const db = createWorkerDatabase(worker);
|
|
249
|
+
await db.nodeCount();
|
|
250
|
+
return db;
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
try {
|
|
254
|
+
worker?.terminate();
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// best-effort cleanup after a failed worker startup
|
|
258
|
+
}
|
|
259
|
+
if (!shouldFallbackToMainThread(options)) {
|
|
260
|
+
throw wrapError(err);
|
|
261
|
+
}
|
|
262
|
+
warnWorkerFallback(err, options);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (requestedRuntime(options) === "worker") {
|
|
266
|
+
throw wrapError(new Error("WORKER_ERROR: Web Worker is not available"));
|
|
267
|
+
}
|
|
268
|
+
return createMainThreadDatabase();
|
|
269
|
+
}
|
|
113
270
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type WasmSnapshotSource = string | URL | Uint8Array | ArrayBuffer | Blob | Response | ReadableStream<Uint8Array | ArrayBuffer>;
|
|
2
|
+
export type WasmSnapshotSaveFormat = "binary" | "base64" | "blob" | "download";
|
|
3
|
+
export type WasmSnapshotSaveOptions = {
|
|
4
|
+
format: "binary";
|
|
5
|
+
} | {
|
|
6
|
+
format: "base64";
|
|
7
|
+
} | {
|
|
8
|
+
format: "blob";
|
|
9
|
+
mimeType?: string;
|
|
10
|
+
} | {
|
|
11
|
+
format: "download";
|
|
12
|
+
filename?: string;
|
|
13
|
+
mimeType?: string;
|
|
14
|
+
};
|
|
15
|
+
export type WasmSnapshotSaveTarget = WasmSnapshotSaveFormat | WasmSnapshotSaveOptions | undefined;
|
|
16
|
+
export declare function bytesToUint8Array(bytes: Uint8Array | ArrayBuffer): Uint8Array;
|
|
17
|
+
export declare function snapshotBytesToBase64(bytes: Uint8Array): string;
|
|
18
|
+
export declare function snapshotBytesToBlob(bytes: Uint8Array, mimeType?: string): Blob;
|
|
19
|
+
export declare function downloadSnapshotBytes(bytes: Uint8Array, filename?: string, mimeType?: string): void;
|
|
20
|
+
export declare function resolveSnapshotSaveFormat(target: WasmSnapshotSaveTarget): WasmSnapshotSaveOptions;
|
|
21
|
+
export declare function snapshotSourceToBytes(source: WasmSnapshotSource): Promise<Uint8Array>;
|
|
22
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../ts/snapshot.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,GAAG,GACH,UAAU,GACV,WAAW,GACX,IAAI,GACJ,QAAQ,GACR,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;AAC7C,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAC/E,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACjE,MAAM,MAAM,sBAAsB,GAC9B,sBAAsB,GACtB,uBAAuB,GACvB,SAAS,CAAC;AAKd,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,CAK7E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAe/D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,QAAQ,SAA6B,GACpC,IAAI,CAIN;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EACjB,QAAQ,SAA4B,EACpC,QAAQ,SAA6B,GACpC,IAAI,CAsCN;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,sBAAsB,GAC7B,uBAAuB,CAQzB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,UAAU,CAAC,CAkBrB"}
|
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const DEFAULT_SNAPSHOT_MIME_TYPE = "application/octet-stream";
|
|
2
|
+
const DEFAULT_SNAPSHOT_FILENAME = "lora-snapshot.bin";
|
|
3
|
+
export function bytesToUint8Array(bytes) {
|
|
4
|
+
if (bytes instanceof Uint8Array) {
|
|
5
|
+
return bytes;
|
|
6
|
+
}
|
|
7
|
+
return new Uint8Array(bytes);
|
|
8
|
+
}
|
|
9
|
+
export function snapshotBytesToBase64(bytes) {
|
|
10
|
+
const buffer = globalThis.Buffer;
|
|
11
|
+
if (buffer) {
|
|
12
|
+
return buffer.from(bytes).toString("base64");
|
|
13
|
+
}
|
|
14
|
+
const chunkSize = 0x8000;
|
|
15
|
+
let binary = "";
|
|
16
|
+
for (let offset = 0; offset < bytes.byteLength; offset += chunkSize) {
|
|
17
|
+
const chunk = bytes.subarray(offset, offset + chunkSize);
|
|
18
|
+
binary += String.fromCharCode(...chunk);
|
|
19
|
+
}
|
|
20
|
+
return btoa(binary);
|
|
21
|
+
}
|
|
22
|
+
export function snapshotBytesToBlob(bytes, mimeType = DEFAULT_SNAPSHOT_MIME_TYPE) {
|
|
23
|
+
const copy = new Uint8Array(bytes.byteLength);
|
|
24
|
+
copy.set(bytes);
|
|
25
|
+
return new Blob([copy.buffer], { type: mimeType });
|
|
26
|
+
}
|
|
27
|
+
export function downloadSnapshotBytes(bytes, filename = DEFAULT_SNAPSHOT_FILENAME, mimeType = DEFAULT_SNAPSHOT_MIME_TYPE) {
|
|
28
|
+
const doc = globalThis.document;
|
|
29
|
+
const urlApi = globalThis.URL;
|
|
30
|
+
if (!doc || !urlApi?.createObjectURL) {
|
|
31
|
+
throw new Error("LORA_ERROR: snapshot download requires a browser document");
|
|
32
|
+
}
|
|
33
|
+
const url = urlApi.createObjectURL(snapshotBytesToBlob(bytes, mimeType));
|
|
34
|
+
const anchor = doc.createElement("a");
|
|
35
|
+
anchor.href = url;
|
|
36
|
+
anchor.download = filename;
|
|
37
|
+
if (anchor.style) {
|
|
38
|
+
anchor.style.display = "none";
|
|
39
|
+
}
|
|
40
|
+
doc.body?.appendChild(anchor);
|
|
41
|
+
try {
|
|
42
|
+
anchor.click();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
anchor.remove?.();
|
|
46
|
+
setTimeout(() => urlApi.revokeObjectURL(url), 0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function resolveSnapshotSaveFormat(target) {
|
|
50
|
+
if (target === undefined) {
|
|
51
|
+
return { format: "binary" };
|
|
52
|
+
}
|
|
53
|
+
if (typeof target === "string") {
|
|
54
|
+
return { format: target };
|
|
55
|
+
}
|
|
56
|
+
return target;
|
|
57
|
+
}
|
|
58
|
+
export async function snapshotSourceToBytes(source) {
|
|
59
|
+
if (source instanceof Uint8Array || source instanceof ArrayBuffer) {
|
|
60
|
+
return bytesToUint8Array(source);
|
|
61
|
+
}
|
|
62
|
+
if (typeof Blob !== "undefined" && source instanceof Blob) {
|
|
63
|
+
return new Uint8Array(await source.arrayBuffer());
|
|
64
|
+
}
|
|
65
|
+
if (typeof Response !== "undefined" && source instanceof Response) {
|
|
66
|
+
return responseToBytes(source);
|
|
67
|
+
}
|
|
68
|
+
if (isReadableStream(source)) {
|
|
69
|
+
return readableStreamToBytes(source);
|
|
70
|
+
}
|
|
71
|
+
return responseToBytes(await fetch(source));
|
|
72
|
+
}
|
|
73
|
+
function isReadableStream(source) {
|
|
74
|
+
return typeof source.getReader === "function";
|
|
75
|
+
}
|
|
76
|
+
async function readableStreamToBytes(stream) {
|
|
77
|
+
const reader = stream.getReader();
|
|
78
|
+
const chunks = [];
|
|
79
|
+
let total = 0;
|
|
80
|
+
try {
|
|
81
|
+
for (;;) {
|
|
82
|
+
const { done, value } = await reader.read();
|
|
83
|
+
if (done) {
|
|
84
|
+
const merged = new Uint8Array(total);
|
|
85
|
+
let offset = 0;
|
|
86
|
+
for (const chunk of chunks) {
|
|
87
|
+
merged.set(chunk, offset);
|
|
88
|
+
offset += chunk.byteLength;
|
|
89
|
+
}
|
|
90
|
+
return merged;
|
|
91
|
+
}
|
|
92
|
+
const chunk = bytesToUint8Array(value);
|
|
93
|
+
chunks.push(chunk);
|
|
94
|
+
total += chunk.byteLength;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
reader.releaseLock();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async function responseToBytes(response) {
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`LORA_ERROR: snapshot fetch failed (${response.status} ${response.statusText})`);
|
|
104
|
+
}
|
|
105
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../ts/snapshot.ts"],"names":[],"mappings":"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"}
|