@loradb/lora-wasm 0.1.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.
Files changed (49) hide show
  1. package/LICENSE +87 -0
  2. package/README.md +197 -0
  3. package/dist/index.d.ts +66 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +87 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/loader-node.d.ts +12 -0
  8. package/dist/loader-node.d.ts.map +1 -0
  9. package/dist/loader-node.js +12 -0
  10. package/dist/loader-node.js.map +1 -0
  11. package/dist/types.d.ts +193 -0
  12. package/dist/types.d.ts.map +1 -0
  13. package/dist/types.js +111 -0
  14. package/dist/types.js.map +1 -0
  15. package/dist/worker-client.d.ts +41 -0
  16. package/dist/worker-client.d.ts.map +1 -0
  17. package/dist/worker-client.js +69 -0
  18. package/dist/worker-client.js.map +1 -0
  19. package/dist/worker-protocol.d.ts +40 -0
  20. package/dist/worker-protocol.d.ts.map +1 -0
  21. package/dist/worker-protocol.js +9 -0
  22. package/dist/worker-protocol.js.map +1 -0
  23. package/dist/worker.d.ts +12 -0
  24. package/dist/worker.d.ts.map +1 -0
  25. package/dist/worker.js +75 -0
  26. package/dist/worker.js.map +1 -0
  27. package/package.json +98 -0
  28. package/pkg-bundler/LICENSE +87 -0
  29. package/pkg-bundler/README.md +197 -0
  30. package/pkg-bundler/lora_wasm.d.ts +25 -0
  31. package/pkg-bundler/lora_wasm.js +5 -0
  32. package/pkg-bundler/lora_wasm_bg.js +559 -0
  33. package/pkg-bundler/lora_wasm_bg.wasm +0 -0
  34. package/pkg-bundler/lora_wasm_bg.wasm.d.ts +18 -0
  35. package/pkg-bundler/package.json +22 -0
  36. package/pkg-node/LICENSE +87 -0
  37. package/pkg-node/README.md +197 -0
  38. package/pkg-node/lora_wasm.d.ts +25 -0
  39. package/pkg-node/lora_wasm.js +566 -0
  40. package/pkg-node/lora_wasm_bg.wasm +0 -0
  41. package/pkg-node/lora_wasm_bg.wasm.d.ts +18 -0
  42. package/pkg-node/package.json +16 -0
  43. package/pkg-web/LICENSE +87 -0
  44. package/pkg-web/README.md +197 -0
  45. package/pkg-web/lora_wasm.d.ts +67 -0
  46. package/pkg-web/lora_wasm.js +607 -0
  47. package/pkg-web/lora_wasm_bg.wasm +0 -0
  48. package/pkg-web/lora_wasm_bg.wasm.d.ts +18 -0
  49. package/pkg-web/package.json +20 -0
package/LICENSE ADDED
@@ -0,0 +1,87 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: LoraDB, Inc.
6
+ Licensed Work: LoraDB
7
+ Change Date: 2029-04-19
8
+ Change License: Apache License, Version 2.0
9
+
10
+ Additional Use Grant: You may use, copy, modify, create derivative works of,
11
+ distribute, and make production use of the Licensed Work
12
+ for internal business purposes and non-production
13
+ purposes, provided that you do not use the Licensed Work
14
+ to offer, operate, or make available a database-as-a-
15
+ service, hosted API, managed database platform, or any
16
+ substantially similar hosted service for third parties.
17
+
18
+ The Additional Use Grant does not permit using the
19
+ Licensed Work to provide a commercial or non-commercial
20
+ hosted service that allows third parties to access LoraDB
21
+ functionality, including as part of a competing managed
22
+ database platform, backend-as-a-service, application
23
+ platform, developer platform, or resale offering.
24
+
25
+ Business Source License
26
+
27
+ Terms
28
+
29
+ The Licensor hereby grants you the right to copy, modify, create derivative
30
+ works, redistribute, and make non-production use of the Licensed Work. The
31
+ Licensor may make an Additional Use Grant, above, permitting limited production
32
+ use.
33
+
34
+ Effective on the Change Date, or the fourth anniversary of the first publicly
35
+ available distribution of a specific version of the Licensed Work under this
36
+ License, whichever comes first, the Licensor hereby grants you rights under
37
+ the terms of the Change License, and the rights granted in the paragraph
38
+ above terminate.
39
+
40
+ If your use of the Licensed Work does not comply with the requirements
41
+ currently in effect as described in this License, you must purchase a
42
+ commercial license from the Licensor, its affiliated entities, or authorized
43
+ resellers, or you must refrain from using the Licensed Work.
44
+
45
+ All copies of the original and modified Licensed Work, and derivative works
46
+ of the Licensed Work, are subject to this License. This License applies
47
+ separately for each version of the Licensed Work and the Change Date may vary
48
+ for each version of the Licensed Work released by Licensor.
49
+
50
+ You must conspicuously display this License on each original or modified copy
51
+ of the Licensed Work. If you receive the Licensed Work in original or modified
52
+ form from a third party, the terms and conditions set forth in this License
53
+ apply to your use of that work.
54
+
55
+ Any use of the Licensed Work in violation of this License will automatically
56
+ terminate your rights under this License for the current and all other
57
+ versions of the Licensed Work.
58
+
59
+ This License does not grant you any right in any trademark or logo of Licensor
60
+ or its affiliates.
61
+
62
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
63
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
64
+ EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY,
65
+ FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
66
+
67
+ MariaDB hereby grants you permission to use this License's text to license
68
+ your works, and to refer to it using the trademark "Business Source License",
69
+ as long as you comply with the Covenants of Licensor below.
70
+
71
+ Covenants of Licensor
72
+
73
+ In consideration of the right to use this License's text and the "Business
74
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
75
+ other recipients of the licensed work to be provided by Licensor:
76
+
77
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
78
+ or a license that is compatible with GPL Version 2.0 or a later version,
79
+ where "compatible" means that software provided under the Change License can
80
+ be included in a program with software provided under GPL Version 2.0 or a
81
+ later version. Licensor may specify additional Change Licenses without
82
+ limitation.
83
+ 2. To either: (a) specify an additional grant of rights to use that does not
84
+ impose any additional restriction on the right granted in this License, as
85
+ the Additional Use Grant; or (b) insert the text "None".
86
+ 3. To specify a Change Date.
87
+ 4. Not to modify this License in any other way.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # lora-wasm
2
+
3
+ WebAssembly bindings for the [Lora](../../README.md) in-memory graph
4
+ database. The package is designed for browsers and Node.js and exposes a
5
+ **strongly typed, async-facing API** that keeps the main thread responsive:
6
+ heavy query work can run inside a Web Worker while your UI code simply awaits
7
+ the result.
8
+
9
+ > **Status:** prototype / feasibility check. Not published to npm.
10
+
11
+ ## Build
12
+
13
+ ```bash
14
+ cd crates/lora-wasm
15
+ npm install
16
+ npm run build # wasm-pack (node + bundler) + tsc
17
+ npm test # vitest
18
+ ```
19
+
20
+ Build artefacts:
21
+
22
+ | Directory | Target | Purpose |
23
+ |-------------------|---------------------|-----------------------------------------------------------------|
24
+ | `pkg-node/` | `--target nodejs` | In-process usage from Node (vitest, CLI, loader-node.ts) |
25
+ | `pkg-bundler/` | `--target bundler` | Consumption via Vite/webpack/esbuild |
26
+ | `pkg-web/` | `--target web` | Browser Worker entry — self-fetches the `.wasm` binary |
27
+ | `dist/` | TypeScript (`tsc`) | Compiled wrapper (`Database`, worker, worker-client, types) |
28
+
29
+ To run the full validation suite (typecheck, vitest, Playwright browser
30
+ test, npm pack dry-run), add:
31
+
32
+ ```bash
33
+ npm run typecheck
34
+ npm test
35
+ npm run test:browser:install # one-time chromium download
36
+ npm run test:browser
37
+ npm run pack:dry
38
+ ```
39
+
40
+ ## Two execution modes
41
+
42
+ ### 1. In-process (Node / scripts)
43
+
44
+ `lora-wasm` is **async-only** — the sole initialization pattern is
45
+ `createDatabase()`, which bootstraps the WASM module on first call.
46
+ There is no synchronous constructor and no `Database.create()`
47
+ static; `Database` is a type-only export.
48
+
49
+ ```ts
50
+ import { createDatabase, isNode } from "lora-wasm";
51
+
52
+ const db = await createDatabase();
53
+ await db.execute("CREATE (:Person {name: $n})", { n: "Alice" });
54
+
55
+ const r = await db.execute("MATCH (n:Person) RETURN n");
56
+ for (const row of r.rows) {
57
+ if (isNode(row.n)) console.log(row.n.properties.name);
58
+ }
59
+ ```
60
+
61
+ ### 2. Non-blocking Web Worker (browser)
62
+
63
+ ```ts
64
+ import { createWorkerDatabase } from "lora-wasm/worker-client";
65
+
66
+ const worker = new Worker(new URL("./worker.js", import.meta.url), {
67
+ type: "module",
68
+ });
69
+ const db = createWorkerDatabase(worker);
70
+
71
+ await db.execute("CREATE (:N {n: 1})"); // runs off-main-thread
72
+ const { rows } = await db.execute("MATCH (n) RETURN n.n AS n");
73
+ ```
74
+
75
+ The worker entry (`ts/worker.ts`) hosts the WASM module. The main thread only
76
+ posts messages, so long-running queries never block the event loop / UI.
77
+
78
+ ### 3. In-process but typed like the worker (advanced)
79
+
80
+ The same `createWorkerDatabase` signature accepts any `WorkerLike` object —
81
+ useful for tests and for swapping execution backends behind the same API.
82
+
83
+ ## Typed value model
84
+
85
+ | TS type | Runtime shape |
86
+ |--------------------------------------|-----------------------------------------------------------------------------|
87
+ | `null`/`boolean`/`number`/`string` | pass-through |
88
+ | `LoraValue[]` / nested record | arrays / objects |
89
+ | `LoraNode` | `{ kind: "node", id, labels, properties }` |
90
+ | `LoraRelationship` | `{ kind: "relationship", id, startId, endId, type, properties }` |
91
+ | `LoraPath` | `{ kind: "path", nodes: number[], rels: number[] }` |
92
+ | `LoraDate`…`LoraDuration` | `{ kind: "date", iso: "YYYY-MM-DD" }` etc. |
93
+ | `LoraPoint` | Discriminated union on `srid` — see below |
94
+
95
+ `LoraPoint` is a union of four CRS-specific shapes:
96
+
97
+ | Shape | Meaning |
98
+ |---------------------------------------------------------------------------------------------------------|---------------|
99
+ | `{ kind: "point", srid: 7203, crs: "cartesian", x, y }` | Cartesian 2D |
100
+ | `{ kind: "point", srid: 9157, crs: "cartesian-3D", x, y, z }` | Cartesian 3D |
101
+ | `{ kind: "point", srid: 4326, crs: "WGS-84-2D", x, y, longitude, latitude }` | WGS-84 2D |
102
+ | `{ kind: "point", srid: 4979, crs: "WGS-84-3D", x, y, z, longitude, latitude, height }` | WGS-84 3D |
103
+
104
+ Helper constructors: `date`, `time`, `datetime`, `localtime`, `localdatetime`,
105
+ `duration`, `cartesian`, `cartesian3d`, `wgs84`, `wgs84_3d`. Guards:
106
+ `isNode`, `isRelationship`, `isPath`, `isPoint`, `isTemporal`.
107
+
108
+ > `distance()` on WGS-84-3D points ignores `height`. See
109
+ > [functions reference](../../apps/loradb.com/docs/functions/overview.md) for the spatial
110
+ > reference and out-of-scope operations.
111
+
112
+ ## Errors
113
+
114
+ `db.execute(...)` and the worker client throw `LoraError` with a narrowed
115
+ `code`:
116
+
117
+ - `LORA_ERROR` — parse / analyze / execute failure
118
+ - `INVALID_PARAMS` — a param value could not be mapped to a Lora value
119
+ - `WORKER_ERROR` — worker transport / lifecycle failure (worker client only)
120
+
121
+ ## Shared type contract
122
+
123
+ The public TypeScript value model (`LoraValue`, `LoraNode`, …,
124
+ `QueryResult`, `LoraError`) lives in a single canonical file at
125
+ `crates/shared-ts/types.ts` and is copied into each consumer package by
126
+ its `sync:types` npm script. CI runs `verify:types` to fail on drift.
127
+ That keeps `lora-node` and `lora-wasm` locked to one identical
128
+ public surface — consumers can swap backends without rewriting types.
129
+
130
+ ## Known limitations
131
+
132
+ - The wasm module is single-threaded. Parallel queries inside one worker
133
+ serialise; spawn more workers for true parallelism.
134
+ - I64 values are delivered as JS `number` and lose precision above 2^53.
135
+ Applications that need bigint precision should use the native
136
+ `lora-node` binding instead.
137
+ - Wall-clock reads (`date()`, `datetime()`, `time()`, `localdatetime()`,
138
+ `localtime()`) are routed through `js_sys::Date::now()` on wasm32 via
139
+ the shim in `lora-store::temporal::unix_now`. The browser clock is
140
+ millisecond-granular, so the nanosecond field on returned values is
141
+ zero below the millisecond boundary.
142
+ - Engine errors cross the worker boundary as `LoraError` with a
143
+ narrowed `code`; the engine does not currently stream query progress
144
+ or offer cancellation.
145
+
146
+ ## Feasibility assessment
147
+
148
+ **What works today**
149
+
150
+ - `cargo check --target wasm32-unknown-unknown` passes for the whole
151
+ database pipeline (`lora-ast`, `lora-parser`, `lora-analyzer`,
152
+ `lora-compiler`, `lora-executor`, `lora-store`,
153
+ `lora-database`, `lora-wasm`).
154
+ - `wasm-pack build` succeeds for three targets (`nodejs`, `bundler`,
155
+ `web`) with a ~2.2 MB optimised `.wasm` each.
156
+ - The non-blocking worker-backed path is end-to-end verified: a real
157
+ Chromium instance spawns a module Worker, loads the `pkg-web` bundle,
158
+ and runs a CREATE + MATCH round-trip — asserted by a Playwright test
159
+ behind `npm run test:browser`.
160
+ - `vitest` runs 18 in-process tests against the `nodejs` bundle,
161
+ covering scalars, nested maps/lists, nodes, relationships, paths,
162
+ points, all temporal kinds including `date()`/`datetime()` no-arg
163
+ forms, parameter validation errors, and concurrent queries across the
164
+ worker message protocol.
165
+ - The TypeScript public contract is shared verbatim with `lora-node`
166
+ via `crates/shared-ts/types.ts`, enforced by `verify:types` in CI.
167
+ - `npm pack --dry-run` produces a 45-file, 6.6 MB tarball containing
168
+ all three wasm bundles plus the compiled TS wrapper. No `file:` deps,
169
+ no postinstall scripts.
170
+
171
+ **What still blocks a real npm publish**
172
+
173
+ - Package is marked `private: true` and the workspace is pre-1.0.
174
+ Publishing needs a final scope decision (e.g. `@lora/wasm`),
175
+ a LICENSE file, and a repository URL in `Cargo.toml`/`package.json`.
176
+ - The three wasm bundles are each ~2.2 MB. A production publish should
177
+ either ship conditional exports that load only the bundle the
178
+ consumer imports, or switch to compressed `.wasm` + `fetch` with
179
+ `Content-Encoding: br`.
180
+ - I64 precision is capped at `Number.MAX_SAFE_INTEGER`. For larger
181
+ integer properties we need a `bigint`-aware serializer on the wasm
182
+ boundary.
183
+ - The engine is synchronous inside wasm — a single Worker serialises
184
+ queries. Multi-tenant workloads need either multiple Workers (already
185
+ possible), or an engine-level cooperative scheduler.
186
+ - No query cancellation or progress streaming crosses the Worker
187
+ boundary; a slow query blocks that Worker until completion.
188
+
189
+ **Bottom line**
190
+
191
+ Yes — this database can be used from JavaScript and TypeScript in
192
+ practice, in the browser and in Node, without native bindings. The
193
+ worker-backed path keeps heavy query work off the main thread by
194
+ default, and the strongly-typed wrapper makes query results ergonomic
195
+ for TS consumers. The remaining gaps are packaging polish and two
196
+ well-known wasm constraints (i64 precision, no cancellation); neither
197
+ blocks feasibility.
@@ -0,0 +1,66 @@
1
+ /**
2
+ * lora-wasm — typed WebAssembly bindings for the Lora graph engine.
3
+ *
4
+ * This entry targets Node.js (ESM) and any bundler host whose resolver maps
5
+ * `node:module` through. Browser consumers should prefer the Worker-backed
6
+ * API exposed in `worker-client.ts` to keep the main thread responsive.
7
+ *
8
+ * **Initialization is async-only.** The one canonical entry point is
9
+ * `createDatabase()`; the WASM module is bootstrapped inside it before the
10
+ * first query runs. There is no synchronous constructor.
11
+ *
12
+ * import { createDatabase } from "lora-wasm";
13
+ *
14
+ * const db = await createDatabase();
15
+ * const res = await db.execute("CREATE (:N {n: $v}) RETURN 1 AS one", { v: 1 });
16
+ */
17
+ import type { LoraParams, LoraValue, QueryResult } from "./types.js";
18
+ import { WasmDatabase } from "./loader-node.js";
19
+ export * from "./types.js";
20
+ export { createWorkerDatabase, type WorkerDatabase } from "./worker-client.js";
21
+ /**
22
+ * In-memory Lora graph database running on the WASM engine.
23
+ *
24
+ * Obtained exclusively via `createDatabase()`. Queries still execute
25
+ * synchronously inside WASM, so for heavy queries in the browser prefer
26
+ * `createWorkerDatabase()`; every method returns a Promise for API symmetry
27
+ * with `lora-node` and the Worker variant.
28
+ */
29
+ declare class DatabaseImpl {
30
+ #private;
31
+ constructor(inner: InstanceType<typeof WasmDatabase>);
32
+ execute<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): Promise<QueryResult<T>>;
33
+ clear(): Promise<void>;
34
+ nodeCount(): Promise<number>;
35
+ relationshipCount(): Promise<number>;
36
+ /** Release the underlying wasm handle. Subsequent calls will throw. */
37
+ dispose(): void;
38
+ }
39
+ /**
40
+ * Public type for a LoraDB instance backed by WASM.
41
+ *
42
+ * Exported as a type only — there is no runtime `Database` value. To obtain
43
+ * an instance, always use `createDatabase()`.
44
+ */
45
+ export type Database = DatabaseImpl;
46
+ /**
47
+ * Create and initialize a new in-memory LoraDB instance on the WASM engine.
48
+ *
49
+ * **This is the only supported initialization pattern** for `lora-wasm`.
50
+ * Synchronous construction is not available — the async factory bootstraps
51
+ * the WASM module on first call and guarantees the engine is ready before
52
+ * the first query.
53
+ *
54
+ * ```ts
55
+ * import { createDatabase } from "lora-wasm";
56
+ *
57
+ * const db = await createDatabase();
58
+ * const res = await db.execute("MATCH (n) RETURN count(n) AS n");
59
+ * ```
60
+ *
61
+ * For heavy browser workloads, use `createWorkerDatabase()` from
62
+ * `lora-wasm/worker-client` instead — it keeps the main thread responsive
63
+ * by running the engine in a Web Worker.
64
+ */
65
+ export declare function createDatabase(): Promise<Database>;
66
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAoB,MAAM,kBAAkB,CAAC;AAElE,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAS/E;;;;;;;GAOG;AACH,cAAM,YAAY;;gBAGJ,KAAK,EAAE,YAAY,CAAC,OAAO,YAAY,CAAC;IAI9C,OAAO,CACX,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/D,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IASxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI1C,uEAAuE;IACvE,OAAO,IAAI,IAAI;CAGhB;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAGxD"}
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * lora-wasm — typed WebAssembly bindings for the Lora graph engine.
3
+ *
4
+ * This entry targets Node.js (ESM) and any bundler host whose resolver maps
5
+ * `node:module` through. Browser consumers should prefer the Worker-backed
6
+ * API exposed in `worker-client.ts` to keep the main thread responsive.
7
+ *
8
+ * **Initialization is async-only.** The one canonical entry point is
9
+ * `createDatabase()`; the WASM module is bootstrapped inside it before the
10
+ * first query runs. There is no synchronous constructor.
11
+ *
12
+ * import { createDatabase } from "lora-wasm";
13
+ *
14
+ * const db = await createDatabase();
15
+ * const res = await db.execute("CREATE (:N {n: $v}) RETURN 1 AS one", { v: 1 });
16
+ */
17
+ import { wrapError } from "./types.js";
18
+ import { WasmDatabase, init as wasmInit } from "./loader-node.js";
19
+ export * from "./types.js";
20
+ export { createWorkerDatabase } from "./worker-client.js";
21
+ let bootstrapped = false;
22
+ function ensureBootstrapped() {
23
+ if (bootstrapped)
24
+ return;
25
+ wasmInit();
26
+ bootstrapped = true;
27
+ }
28
+ /**
29
+ * In-memory Lora graph database running on the WASM engine.
30
+ *
31
+ * Obtained exclusively via `createDatabase()`. Queries still execute
32
+ * synchronously inside WASM, so for heavy queries in the browser prefer
33
+ * `createWorkerDatabase()`; every method returns a Promise for API symmetry
34
+ * with `lora-node` and the Worker variant.
35
+ */
36
+ class DatabaseImpl {
37
+ #inner;
38
+ constructor(inner) {
39
+ this.#inner = inner;
40
+ }
41
+ async execute(query, params) {
42
+ try {
43
+ const raw = this.#inner.execute(query, (params ?? null));
44
+ return raw;
45
+ }
46
+ catch (err) {
47
+ throw wrapError(err);
48
+ }
49
+ }
50
+ async clear() {
51
+ this.#inner.clear();
52
+ }
53
+ async nodeCount() {
54
+ return this.#inner.nodeCount();
55
+ }
56
+ async relationshipCount() {
57
+ return this.#inner.relationshipCount();
58
+ }
59
+ /** Release the underlying wasm handle. Subsequent calls will throw. */
60
+ dispose() {
61
+ this.#inner.free();
62
+ }
63
+ }
64
+ /**
65
+ * Create and initialize a new in-memory LoraDB instance on the WASM engine.
66
+ *
67
+ * **This is the only supported initialization pattern** for `lora-wasm`.
68
+ * Synchronous construction is not available — the async factory bootstraps
69
+ * the WASM module on first call and guarantees the engine is ready before
70
+ * the first query.
71
+ *
72
+ * ```ts
73
+ * import { createDatabase } from "lora-wasm";
74
+ *
75
+ * const db = await createDatabase();
76
+ * const res = await db.execute("MATCH (n) RETURN count(n) AS n");
77
+ * ```
78
+ *
79
+ * For heavy browser workloads, use `createWorkerDatabase()` from
80
+ * `lora-wasm/worker-client` instead — it keeps the main thread responsive
81
+ * by running the engine in a Web Worker.
82
+ */
83
+ export async function createDatabase() {
84
+ ensureBootstrapped();
85
+ return new DatabaseImpl(new WasmDatabase());
86
+ }
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAElE,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAuB,MAAM,oBAAoB,CAAC;AAE/E,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,SAAS,kBAAkB;IACzB,IAAI,YAAY;QAAE,OAAO;IACzB,QAAQ,EAAE,CAAC;IACX,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,YAAY;IACP,MAAM,CAAoC;IAEnD,YAAY,KAAwC;QAClD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAEX,KAAa,EAAE,MAAmB;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,IAAI,IAAI,CAAY,CAAC,CAAC;YACpE,OAAO,GAAqB,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,iBAAiB;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACzC,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;CACF;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,kBAAkB,EAAE,CAAC;IACrB,OAAO,IAAI,YAAY,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Node-specific loader. The wasm-pack `--target nodejs` output is CommonJS,
3
+ * so we wrap it with `createRequire` to stay ESM-compatible.
4
+ */
5
+ import type { WasmDatabase as NativeWasmDatabase } from "../pkg-node/lora_wasm.js";
6
+ export interface NativeModule {
7
+ WasmDatabase: new () => NativeWasmDatabase;
8
+ init: () => void;
9
+ }
10
+ export declare const WasmDatabase: new () => NativeWasmDatabase;
11
+ export declare const init: () => void;
12
+ //# sourceMappingURL=loader-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-node.d.ts","sourceRoot":"","sources":["../ts/loader-node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnF,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,UAAU,kBAAkB,CAAC;IAC3C,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAOD,eAAO,MAAM,YAAY,YATC,kBASkB,CAAC;AAC7C,eAAO,MAAM,IAAI,QATH,IASc,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Node-specific loader. The wasm-pack `--target nodejs` output is CommonJS,
3
+ * so we wrap it with `createRequire` to stay ESM-compatible.
4
+ */
5
+ import { createRequire } from "node:module";
6
+ const require = createRequire(import.meta.url);
7
+ // The pkg-node path is stable because `wasm-pack build --out-dir pkg-node`
8
+ // writes it next to this file's parent.
9
+ const mod = require("../pkg-node/lora_wasm.js");
10
+ export const WasmDatabase = mod.WasmDatabase;
11
+ export const init = mod.init;
12
+ //# sourceMappingURL=loader-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-node.js","sourceRoot":"","sources":["../ts/loader-node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,2EAA2E;AAC3E,wCAAwC;AACxC,MAAM,GAAG,GAAG,OAAO,CAAC,0BAA0B,CAAiB,CAAC;AAEhE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;AAC7C,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Canonical typed value model for the JS-facing Lora packages
3
+ * (`lora-node` and `lora-wasm`).
4
+ *
5
+ * Every structural value carries a `kind` discriminator. Temporal and
6
+ * spatial values are tagged so TypeScript can narrow safely after a
7
+ * query runs.
8
+ *
9
+ * Canonical source: `crates/shared-ts/types.ts`. Each JS-facing package
10
+ * (`lora-node`, `lora-wasm`) copies this file into its own `ts/` dir
11
+ * via its `sync:types` npm script. The `verify:types` script fails CI if
12
+ * the copies drift — do not edit the per-package copies directly.
13
+ */
14
+ /**
15
+ * Values accepted as Lora query parameters. Mirrors `LoraValue` but
16
+ * also allows plain JS scalars / arrays / objects. Temporal and spatial
17
+ * values must be passed as tagged objects so the bridge can parse them
18
+ * without ambiguity.
19
+ */
20
+ export type LoraParam = null | boolean | number | string | LoraParam[] | {
21
+ [key: string]: LoraParam;
22
+ } | LoraDate | LoraTime | LoraLocalTime | LoraDateTime | LoraLocalDateTime | LoraDuration | LoraPoint;
23
+ export type LoraParams = Record<string, LoraParam>;
24
+ export interface LoraNode {
25
+ kind: "node";
26
+ id: number;
27
+ labels: string[];
28
+ properties: Record<string, LoraValue>;
29
+ }
30
+ export interface LoraRelationship {
31
+ kind: "relationship";
32
+ id: number;
33
+ startId: number;
34
+ endId: number;
35
+ type: string;
36
+ properties: Record<string, LoraValue>;
37
+ }
38
+ export interface LoraPath {
39
+ kind: "path";
40
+ nodes: number[];
41
+ rels: number[];
42
+ }
43
+ export interface LoraDate {
44
+ kind: "date";
45
+ /** `YYYY-MM-DD` */
46
+ iso: string;
47
+ }
48
+ export interface LoraTime {
49
+ kind: "time";
50
+ /** `HH:MM:SS[.nnn][Z|±HH:MM]` */
51
+ iso: string;
52
+ }
53
+ export interface LoraLocalTime {
54
+ kind: "localtime";
55
+ /** `HH:MM:SS[.nnn]` */
56
+ iso: string;
57
+ }
58
+ export interface LoraDateTime {
59
+ kind: "datetime";
60
+ /** `YYYY-MM-DDTHH:MM:SS[.nnn][Z|±HH:MM]` */
61
+ iso: string;
62
+ }
63
+ export interface LoraLocalDateTime {
64
+ kind: "localdatetime";
65
+ /** `YYYY-MM-DDTHH:MM:SS[.nnn]` */
66
+ iso: string;
67
+ }
68
+ export interface LoraDuration {
69
+ kind: "duration";
70
+ /** ISO-8601 duration, e.g. `P1Y2M3DT4H5M6S` */
71
+ iso: string;
72
+ }
73
+ export type TemporalKind = "date" | "time" | "localtime" | "datetime" | "localdatetime" | "duration";
74
+ export type LoraTemporal = LoraDate | LoraTime | LoraLocalTime | LoraDateTime | LoraLocalDateTime | LoraDuration;
75
+ /**
76
+ * Supported spatial-reference identifiers.
77
+ *
78
+ * - `7203` — Cartesian 2D
79
+ * - `9157` — Cartesian 3D
80
+ * - `4326` — WGS-84 Geographic 2D
81
+ * - `4979` — WGS-84 Geographic 3D
82
+ */
83
+ export type LoraPointSrid = 7203 | 9157 | 4326 | 4979;
84
+ /**
85
+ * Canonical CRS name string. Mirrors `srid` 1:1 on the output side; on
86
+ * the input side, `point({…, crs: "…"})` accepts these plus the alias
87
+ * `"WGS-84"` (equivalent to `"WGS-84-2D"`) — see the engine README.
88
+ */
89
+ export type LoraPointCrs = "cartesian" | "cartesian-3D" | "WGS-84-2D" | "WGS-84-3D";
90
+ /** Cartesian 2D point. */
91
+ export interface LoraCartesianPoint {
92
+ kind: "point";
93
+ srid: 7203;
94
+ crs: "cartesian";
95
+ x: number;
96
+ y: number;
97
+ }
98
+ /** Cartesian 3D point. */
99
+ export interface LoraCartesianPoint3D {
100
+ kind: "point";
101
+ srid: 9157;
102
+ crs: "cartesian-3D";
103
+ x: number;
104
+ y: number;
105
+ z: number;
106
+ }
107
+ /**
108
+ * WGS-84 geographic 2D point.
109
+ *
110
+ * `x === longitude` and `y === latitude`. Both naming conventions are
111
+ * exposed so consumers can pick whichever is clearer at the call site.
112
+ */
113
+ export interface LoraWgs84Point {
114
+ kind: "point";
115
+ srid: 4326;
116
+ crs: "WGS-84-2D";
117
+ x: number;
118
+ y: number;
119
+ longitude: number;
120
+ latitude: number;
121
+ }
122
+ /**
123
+ * WGS-84 geographic 3D point.
124
+ *
125
+ * `x === longitude`, `y === latitude`, `z === height` (metres).
126
+ *
127
+ * **Caveat:** `distance()` on WGS-84-3D points currently ignores
128
+ * `height` and computes the great-circle surface distance only. A full
129
+ * 3D geodesic distance is not implemented.
130
+ */
131
+ export interface LoraWgs84Point3D {
132
+ kind: "point";
133
+ srid: 4979;
134
+ crs: "WGS-84-3D";
135
+ x: number;
136
+ y: number;
137
+ z: number;
138
+ longitude: number;
139
+ latitude: number;
140
+ height: number;
141
+ }
142
+ /**
143
+ * Any point value returned by the engine. Narrow via the `srid` or
144
+ * `crs` discriminator (or the `isPoint` guard plus `point.srid`).
145
+ */
146
+ export type LoraPoint = LoraCartesianPoint | LoraCartesianPoint3D | LoraWgs84Point | LoraWgs84Point3D;
147
+ export type LoraValue = null | boolean | number | string | LoraValue[] | {
148
+ [key: string]: LoraValue;
149
+ } | LoraNode | LoraRelationship | LoraPath | LoraDate | LoraTime | LoraLocalTime | LoraDateTime | LoraLocalDateTime | LoraDuration | LoraPoint;
150
+ export type QueryRow<T extends Record<string, LoraValue> = Record<string, LoraValue>> = T;
151
+ export interface QueryResult<T extends Record<string, LoraValue> = Record<string, LoraValue>> {
152
+ columns: string[];
153
+ rows: QueryRow<T>[];
154
+ }
155
+ export declare function isNode(v: LoraValue): v is LoraNode;
156
+ export declare function isRelationship(v: LoraValue): v is LoraRelationship;
157
+ export declare function isPath(v: LoraValue): v is LoraPath;
158
+ export declare function isPoint(v: LoraValue): v is LoraPoint;
159
+ export declare function isTemporal(v: LoraValue): v is LoraTemporal;
160
+ export declare const date: (iso: string) => LoraDate;
161
+ export declare const time: (iso: string) => LoraTime;
162
+ export declare const localtime: (iso: string) => LoraLocalTime;
163
+ export declare const datetime: (iso: string) => LoraDateTime;
164
+ export declare const localdatetime: (iso: string) => LoraLocalDateTime;
165
+ export declare const duration: (iso: string) => LoraDuration;
166
+ export declare const cartesian: (x: number, y: number) => LoraCartesianPoint;
167
+ export declare const cartesian3d: (x: number, y: number, z: number) => LoraCartesianPoint3D;
168
+ export declare const wgs84: (longitude: number, latitude: number) => LoraWgs84Point;
169
+ export declare const wgs84_3d: (longitude: number, latitude: number, height: number) => LoraWgs84Point3D;
170
+ /**
171
+ * Error codes emitted by the engine bridges.
172
+ *
173
+ * - `LORA_ERROR` — parse / analyze / execute failure
174
+ * - `INVALID_PARAMS` — a param value could not be mapped to a Lora value
175
+ * - `WORKER_ERROR` — worker transport / lifecycle failure (wasm worker only)
176
+ * - `UNKNOWN` — fall-through for unrecognised error shapes
177
+ */
178
+ export type LoraErrorCode = "LORA_ERROR" | "INVALID_PARAMS" | "WORKER_ERROR" | "UNKNOWN";
179
+ /**
180
+ * Error thrown by `Database.execute` when Lora parsing, analysis, or
181
+ * execution fails.
182
+ */
183
+ export declare class LoraError extends Error {
184
+ readonly code: LoraErrorCode;
185
+ constructor(message: string, code?: LoraErrorCode);
186
+ }
187
+ /**
188
+ * Normalise a thrown value into a `LoraError` with a narrowed `code`
189
+ * when the message carries a recognised prefix; otherwise returns the
190
+ * original `Error` unchanged.
191
+ */
192
+ export declare function wrapError(err: unknown): Error;
193
+ //# sourceMappingURL=types.d.ts.map