@loradb/lora-node 0.3.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 +76 -14
- package/dist/index.d.ts +92 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +319 -30
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/ts/native.d.ts +18 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# lora-node
|
|
2
2
|
|
|
3
|
-
Node.js / TypeScript bindings for the [Lora](../../README.md)
|
|
4
|
-
|
|
3
|
+
Node.js / TypeScript bindings for the [Lora](../../README.md) graph
|
|
4
|
+
engine. The package exposes a first-class typed API: query results are
|
|
5
5
|
modelled as discriminated unions, temporal values carry `kind` tags, and the
|
|
6
6
|
`Database` class is strongly typed in both directions (params and rows).
|
|
7
7
|
|
|
@@ -29,13 +29,13 @@ to `package.json`.
|
|
|
29
29
|
## Usage
|
|
30
30
|
|
|
31
31
|
`lora-node` is **async-only** — the sole initialization pattern is
|
|
32
|
-
`createDatabase()`. There is no synchronous constructor and no
|
|
32
|
+
`createDatabase(...)`. There is no synchronous constructor and no
|
|
33
33
|
`Database.create()` static; `Database` is a type-only export.
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
import { createDatabase, isNode, type LoraNode } from "lora-node";
|
|
37
37
|
|
|
38
|
-
const db = await createDatabase();
|
|
38
|
+
const db = await createDatabase(); // in-memory by default
|
|
39
39
|
await db.execute("CREATE (:Person {name: $n, age: $a})", { n: "Alice", a: 30 });
|
|
40
40
|
|
|
41
41
|
const res = await db.execute<{ n: LoraNode }>("MATCH (n:Person) RETURN n");
|
|
@@ -46,9 +46,66 @@ for (const row of res.rows) {
|
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
The
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
The initialization rule is:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { createDatabase } from "lora-node";
|
|
53
|
+
|
|
54
|
+
const inMemory = await createDatabase(); // in-memory only
|
|
55
|
+
const persistent = await createDatabase("./app"); // persistent: pass a directory string
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If you want persistence, pass a **directory string** to `createDatabase(...)`.
|
|
59
|
+
|
|
60
|
+
Node also has a WAL-backed convenience overload:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { createDatabase } from "lora-node";
|
|
64
|
+
|
|
65
|
+
const db = await createDatabase("./.lora-wal"); // persistent: directory string
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The string is treated as the WAL directory path verbatim. Relative
|
|
69
|
+
paths resolve from the current working directory. This is a Node-only
|
|
70
|
+
initialization convenience; the query surface, shared types, and async
|
|
71
|
+
method signatures still match `lora-wasm`.
|
|
72
|
+
|
|
73
|
+
Call `db.dispose()` when you need to release the native handle eagerly,
|
|
74
|
+
especially before reopening the same WAL directory in the same process.
|
|
75
|
+
|
|
76
|
+
## Snapshots
|
|
77
|
+
|
|
78
|
+
`saveSnapshot(path)` writes the current graph to a local file. It also accepts
|
|
79
|
+
typed formats: `"binary"` returns a Node `Buffer`, `"base64"` returns base64
|
|
80
|
+
text, and `{ format: "path", path }` accepts either a path string or `file:`
|
|
81
|
+
URL.
|
|
82
|
+
|
|
83
|
+
`loadSnapshot` accepts a `NodeSnapshotSource`: a filesystem path, `file:` URL,
|
|
84
|
+
HTTP(S) or `data:` URL, `Buffer`, `Uint8Array`, `ArrayBuffer`, Node
|
|
85
|
+
`Readable`, web `ReadableStream`, or async iterable of byte chunks.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { readFile } from "node:fs/promises";
|
|
89
|
+
import { createReadStream } from "node:fs";
|
|
90
|
+
import { pathToFileURL } from "node:url";
|
|
91
|
+
import { createDatabase } from "lora-node";
|
|
92
|
+
|
|
93
|
+
const db = await createDatabase();
|
|
94
|
+
await db.execute("CREATE (:Person {name: 'Alice'})");
|
|
95
|
+
await db.saveSnapshot("./graph.lorasnap");
|
|
96
|
+
const bytes = await db.saveSnapshot("binary");
|
|
97
|
+
const base64 = await db.saveSnapshot({ format: "base64" });
|
|
98
|
+
|
|
99
|
+
await db.loadSnapshot("./graph.lorasnap");
|
|
100
|
+
await db.loadSnapshot(pathToFileURL("./graph.lorasnap"));
|
|
101
|
+
await db.loadSnapshot(await readFile("./graph.lorasnap"));
|
|
102
|
+
await db.loadSnapshot(createReadStream("./graph.lorasnap"));
|
|
103
|
+
await db.loadSnapshot(bytes);
|
|
104
|
+
await db.loadSnapshot(new URL("https://example.com/graph.lorasnap"));
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use `loadSnapshotFromBytes(bytes)` when you already have in-memory bytes and
|
|
108
|
+
want to make that intent explicit.
|
|
52
109
|
|
|
53
110
|
## Typed value model
|
|
54
111
|
|
|
@@ -116,15 +173,20 @@ identical to `lora-wasm`.
|
|
|
116
173
|
|
|
117
174
|
## Known limitations
|
|
118
175
|
|
|
119
|
-
- **Concurrent writes.** Each `execute()` hops through the threadpool
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
batched query for heavy write workloads.
|
|
176
|
+
- **Concurrent writes.** Each `execute()` hops through the threadpool; read
|
|
177
|
+
queries can share the store read lock, while writes serialize on the store
|
|
178
|
+
write lock. Firing many concurrent write queries against the same
|
|
179
|
+
`Database` (e.g. 2 000 parallel `CREATE`s via `Promise.all`) works but
|
|
180
|
+
queues behind that write lock. Prefer `await`-in-a-loop or a single batched
|
|
181
|
+
query for heavy write workloads.
|
|
126
182
|
- **I64 precision.** Integer values above `Number.MAX_SAFE_INTEGER`
|
|
127
183
|
(2^53) are returned as JS `number` and lose precision. A `bigint`-aware
|
|
128
184
|
path would require extending the value serializer.
|
|
129
185
|
- **Cancellation.** The napi `Task` abstraction does not support
|
|
130
186
|
cancellation once dispatched; a runaway query runs to completion.
|
|
187
|
+
- **WAL surface.** This first Node persistence slice only exposes
|
|
188
|
+
WAL-backed initialization via `createDatabase(walDir)`. Checkpoint,
|
|
189
|
+
truncate, status, and sync-mode controls are not exposed yet.
|
|
190
|
+
- **WAL directory ownership.** A WAL directory can only be open by one
|
|
191
|
+
live handle at a time. Dispose the first handle before reopening the
|
|
192
|
+
same directory.
|
package/dist/index.d.ts
CHANGED
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
* native surface into the strongly-typed `QueryResult<T>` / `LoraParams`
|
|
8
8
|
* shapes defined in the shared TS contract (`crates/shared-ts/types.ts`).
|
|
9
9
|
*
|
|
10
|
-
* **Initialization is async-only.** The
|
|
11
|
-
* `createDatabase()
|
|
10
|
+
* **Initialization is async-only.** The canonical entry point is
|
|
11
|
+
* `createDatabase(...)`, optionally with a WAL directory path. There is no
|
|
12
|
+
* synchronous constructor. See the docs at
|
|
12
13
|
* https://loradb.com/docs/getting-started/node for the full rationale.
|
|
13
14
|
*/
|
|
15
|
+
import { Buffer } from "node:buffer";
|
|
16
|
+
import { Readable } from "node:stream";
|
|
14
17
|
import type { LoraParams, LoraValue, QueryResult } from "./types.js";
|
|
15
18
|
declare const NativeDatabase: typeof import("./native.js").Database;
|
|
16
19
|
export * from "./types.js";
|
|
@@ -26,17 +29,40 @@ export interface SnapshotMeta {
|
|
|
26
29
|
relationshipCount: number;
|
|
27
30
|
walLsn: number | null;
|
|
28
31
|
}
|
|
32
|
+
export type NodeSnapshotChunk = string | Uint8Array | ArrayBuffer | Buffer;
|
|
33
|
+
export type NodeSnapshotSource = string | URL | Uint8Array | ArrayBuffer | Buffer | Readable | ReadableStream<NodeSnapshotChunk> | AsyncIterable<NodeSnapshotChunk>;
|
|
34
|
+
export type NodeSnapshotSaveFormat = "binary" | "base64";
|
|
35
|
+
export type NodeSnapshotSaveOptions = {
|
|
36
|
+
format: "path";
|
|
37
|
+
path: string | URL;
|
|
38
|
+
} | {
|
|
39
|
+
format: NodeSnapshotSaveFormat;
|
|
40
|
+
};
|
|
41
|
+
export type NodeSnapshotSaveTarget = string | URL | NodeSnapshotSaveFormat | NodeSnapshotSaveOptions;
|
|
42
|
+
export interface CreateDatabaseOptions {
|
|
43
|
+
databaseDir?: string;
|
|
44
|
+
}
|
|
45
|
+
export type TransactionMode = "read_write" | "read_only" | "readwrite" | "readonly" | "rw" | "ro";
|
|
46
|
+
export interface TransactionStatement {
|
|
47
|
+
query: string;
|
|
48
|
+
params?: LoraParams | null;
|
|
49
|
+
}
|
|
50
|
+
export interface RowStream<T extends Record<string, LoraValue> = Record<string, LoraValue>> extends AsyncIterableIterator<T> {
|
|
51
|
+
columns(): string[];
|
|
52
|
+
toArray(): Promise<T[]>;
|
|
53
|
+
close(): void;
|
|
54
|
+
}
|
|
29
55
|
/**
|
|
30
|
-
*
|
|
56
|
+
* Lora graph database instance.
|
|
31
57
|
*
|
|
32
|
-
* Obtained exclusively via `createDatabase()`. There is no public
|
|
33
|
-
* and no synchronous factory
|
|
34
|
-
*
|
|
35
|
-
*
|
|
58
|
+
* Obtained exclusively via `createDatabase()`. There is no public
|
|
59
|
+
* constructor and no synchronous factory. With no args the instance is
|
|
60
|
+
* purely in-memory; with a WAL directory path it replays committed WAL
|
|
61
|
+
* state from disk before serving queries.
|
|
36
62
|
*
|
|
37
63
|
* Instances are independent — each owns its own in-memory graph. Multiple
|
|
38
|
-
* concurrent `execute()` calls against one instance
|
|
39
|
-
*
|
|
64
|
+
* concurrent read-only `execute()` calls against one instance can share
|
|
65
|
+
* the store read lock; writes serialize without blocking the event loop.
|
|
40
66
|
*/
|
|
41
67
|
declare class DatabaseImpl {
|
|
42
68
|
#private;
|
|
@@ -47,6 +73,24 @@ declare class DatabaseImpl {
|
|
|
47
73
|
* with a narrowed `code` (`LORA_ERROR` / `INVALID_PARAMS`).
|
|
48
74
|
*/
|
|
49
75
|
execute<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): Promise<QueryResult<T>>;
|
|
76
|
+
/**
|
|
77
|
+
* Return an async row iterator for a query.
|
|
78
|
+
*
|
|
79
|
+
* The binding exposes the same `for await` shape as the Rust stream API.
|
|
80
|
+
* Rows are materialized by the native `execute()` promise today, then
|
|
81
|
+
* yielded one at a time to JS consumers.
|
|
82
|
+
*/
|
|
83
|
+
stream<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): RowStream<T>;
|
|
84
|
+
/** Alias for `stream()`, useful when naming the row-level API explicitly. */
|
|
85
|
+
rows<T extends Record<string, LoraValue> = Record<string, LoraValue>>(query: string, params?: LoraParams): RowStream<T>;
|
|
86
|
+
/**
|
|
87
|
+
* Execute a statement batch inside one native transaction.
|
|
88
|
+
*
|
|
89
|
+
* Results are returned in statement order. If any statement fails, the
|
|
90
|
+
* native transaction is dropped before commit and all prior writes in the
|
|
91
|
+
* batch are rolled back.
|
|
92
|
+
*/
|
|
93
|
+
transaction<T extends Record<string, LoraValue> = Record<string, LoraValue>>(statements: TransactionStatement[], mode?: TransactionMode): Promise<Array<QueryResult<T>>>;
|
|
50
94
|
/** Drop every node and relationship. Constant-time under the hood. */
|
|
51
95
|
clear(): Promise<void>;
|
|
52
96
|
/** Number of nodes currently in the graph. */
|
|
@@ -54,21 +98,33 @@ declare class DatabaseImpl {
|
|
|
54
98
|
/** Number of relationships currently in the graph. */
|
|
55
99
|
relationshipCount(): Promise<number>;
|
|
56
100
|
/**
|
|
57
|
-
*
|
|
58
|
-
* rename dance — the target path is only replaced once the full payload
|
|
59
|
-
* has been written and fsync'd.
|
|
101
|
+
* Release the native database handle. Idempotent.
|
|
60
102
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* Promise resolves immediately once the save returns.
|
|
103
|
+
* Call this when a WAL-backed database needs to be reopened in the same
|
|
104
|
+
* process. New operations after disposal reject with `database is closed`.
|
|
64
105
|
*/
|
|
65
|
-
|
|
106
|
+
dispose(): void;
|
|
107
|
+
saveSnapshot(format: "binary"): Promise<Buffer>;
|
|
108
|
+
saveSnapshot(format: "base64"): Promise<string>;
|
|
109
|
+
saveSnapshot(path: string | URL): Promise<SnapshotMeta>;
|
|
110
|
+
saveSnapshot(options: {
|
|
111
|
+
format: "binary";
|
|
112
|
+
}): Promise<Buffer>;
|
|
113
|
+
saveSnapshot(options: {
|
|
114
|
+
format: "base64";
|
|
115
|
+
}): Promise<string>;
|
|
116
|
+
saveSnapshot(options: {
|
|
117
|
+
format: "path";
|
|
118
|
+
path: string | URL;
|
|
119
|
+
}): Promise<SnapshotMeta>;
|
|
120
|
+
saveSnapshotToBytes(): Promise<Buffer>;
|
|
66
121
|
/**
|
|
67
122
|
* Replace the current graph state with a snapshot loaded from `path`.
|
|
68
|
-
* Concurrent `execute()` calls block on the store
|
|
69
|
-
* completes.
|
|
123
|
+
* Concurrent `execute()` calls block on the store write lock until the
|
|
124
|
+
* load completes.
|
|
70
125
|
*/
|
|
71
|
-
loadSnapshot(
|
|
126
|
+
loadSnapshot(source: NodeSnapshotSource): Promise<SnapshotMeta>;
|
|
127
|
+
loadSnapshotFromBytes(bytes: Uint8Array | ArrayBuffer | Buffer): Promise<SnapshotMeta>;
|
|
72
128
|
}
|
|
73
129
|
/**
|
|
74
130
|
* Public type for a LoraDB instance.
|
|
@@ -84,24 +140,36 @@ declare class DatabaseImpl {
|
|
|
84
140
|
*/
|
|
85
141
|
export type Database = DatabaseImpl;
|
|
86
142
|
/**
|
|
87
|
-
* Create and initialize a new
|
|
143
|
+
* Create and initialize a new LoraDB instance.
|
|
88
144
|
*
|
|
89
145
|
* **This is the only supported initialization pattern** for `lora-node`.
|
|
90
146
|
* Synchronous construction is not available — the async factory guarantees
|
|
91
|
-
* the native layer is ready before the first query dispatches
|
|
92
|
-
* the Node and WASM surfaces symmetric.
|
|
147
|
+
* the native layer is ready before the first query dispatches.
|
|
93
148
|
*
|
|
94
149
|
* ```ts
|
|
95
150
|
* import { createDatabase } from "lora-node";
|
|
96
151
|
*
|
|
97
|
-
* const db = await createDatabase();
|
|
152
|
+
* const db = await createDatabase(); // in-memory by default
|
|
98
153
|
* const res = await db.execute(
|
|
99
154
|
* "CREATE (n:Person {name: $name}) RETURN n",
|
|
100
155
|
* { name: "Alice" },
|
|
101
156
|
* );
|
|
102
157
|
* ```
|
|
103
158
|
*
|
|
159
|
+
* Optional Node-only persistence convenience:
|
|
160
|
+
*
|
|
161
|
+
* ```ts
|
|
162
|
+
* import { createDatabase } from "lora-node";
|
|
163
|
+
*
|
|
164
|
+
* const inMemory = await createDatabase(); // in-memory
|
|
165
|
+
* const persistent = await createDatabase("./app"); // persistent: pass a directory string
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* If you want persistence, pass a directory string. The string is treated
|
|
169
|
+
* as a WAL directory path verbatim. Relative paths resolve from the
|
|
170
|
+
* current working directory.
|
|
171
|
+
*
|
|
104
172
|
* Each call returns an independent graph — no shared state between instances.
|
|
105
173
|
*/
|
|
106
|
-
export declare function createDatabase(): Promise<Database>;
|
|
174
|
+
export declare function createDatabase(databaseName?: string, options?: CreateDatabaseOptions): Promise<Database>;
|
|
107
175
|
//# 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
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* native surface into the strongly-typed `QueryResult<T>` / `LoraParams`
|
|
9
9
|
* shapes defined in the shared TS contract (`crates/shared-ts/types.ts`).
|
|
10
10
|
*
|
|
11
|
-
* **Initialization is async-only.** The
|
|
12
|
-
* `createDatabase()
|
|
11
|
+
* **Initialization is async-only.** The canonical entry point is
|
|
12
|
+
* `createDatabase(...)`, optionally with a WAL directory path. There is no
|
|
13
|
+
* synchronous constructor. See the docs at
|
|
13
14
|
* https://loradb.com/docs/getting-started/node for the full rationale.
|
|
14
15
|
*/
|
|
15
16
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -31,23 +32,189 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
32
|
};
|
|
32
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
34
|
exports.createDatabase = createDatabase;
|
|
35
|
+
const node_buffer_1 = require("node:buffer");
|
|
36
|
+
const node_stream_1 = require("node:stream");
|
|
37
|
+
const node_url_1 = require("node:url");
|
|
34
38
|
const types_js_1 = require("./types.js");
|
|
35
39
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
36
40
|
// @ts-ignore - resolved at runtime via native.js loader
|
|
37
41
|
const native_js_1 = __importDefault(require("./native.js"));
|
|
38
42
|
const NativeDatabase = native_js_1.default.Database;
|
|
39
43
|
__exportStar(require("./types.js"), exports);
|
|
44
|
+
class NativeRowStream {
|
|
45
|
+
#inner;
|
|
46
|
+
#streamId;
|
|
47
|
+
#closed = false;
|
|
48
|
+
constructor(inner, streamId) {
|
|
49
|
+
this.#inner = inner;
|
|
50
|
+
this.#streamId = streamId;
|
|
51
|
+
}
|
|
52
|
+
[Symbol.asyncIterator]() {
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
columns() {
|
|
56
|
+
try {
|
|
57
|
+
return this.#inner.streamColumns(this.#streamId);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
throw (0, types_js_1.wrapError)(err);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async next() {
|
|
64
|
+
if (this.#closed) {
|
|
65
|
+
return { done: true, value: undefined };
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const row = this.#inner.streamNext(this.#streamId);
|
|
69
|
+
if (row === null) {
|
|
70
|
+
this.#closed = true;
|
|
71
|
+
return { done: true, value: undefined };
|
|
72
|
+
}
|
|
73
|
+
return { done: false, value: row };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
this.#closed = true;
|
|
77
|
+
throw (0, types_js_1.wrapError)(err);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async return() {
|
|
81
|
+
this.close();
|
|
82
|
+
return { done: true, value: undefined };
|
|
83
|
+
}
|
|
84
|
+
async toArray() {
|
|
85
|
+
const rows = [];
|
|
86
|
+
for (;;) {
|
|
87
|
+
const next = await this.next();
|
|
88
|
+
if (next.done) {
|
|
89
|
+
return rows;
|
|
90
|
+
}
|
|
91
|
+
rows.push(next.value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
close() {
|
|
95
|
+
if (this.#closed)
|
|
96
|
+
return;
|
|
97
|
+
this.#closed = true;
|
|
98
|
+
try {
|
|
99
|
+
this.#inner.streamClose(this.#streamId);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
throw (0, types_js_1.wrapError)(err);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function isFetchUrl(url) {
|
|
107
|
+
return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "data:";
|
|
108
|
+
}
|
|
109
|
+
function stringToUrl(value) {
|
|
110
|
+
try {
|
|
111
|
+
return new URL(value);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function bytesToUint8Array(bytes) {
|
|
118
|
+
if (bytes instanceof Uint8Array) {
|
|
119
|
+
return bytes;
|
|
120
|
+
}
|
|
121
|
+
return new Uint8Array(bytes);
|
|
122
|
+
}
|
|
123
|
+
function snapshotChunkToBuffer(chunk) {
|
|
124
|
+
return typeof chunk === "string"
|
|
125
|
+
? node_buffer_1.Buffer.from(chunk)
|
|
126
|
+
: node_buffer_1.Buffer.from(bytesToUint8Array(chunk));
|
|
127
|
+
}
|
|
128
|
+
function resolveNodeSnapshotPath(path) {
|
|
129
|
+
if (path instanceof URL) {
|
|
130
|
+
if (path.protocol !== "file:") {
|
|
131
|
+
throw new Error(`LORA_ERROR: unsupported snapshot save URL protocol '${path.protocol}'`);
|
|
132
|
+
}
|
|
133
|
+
return (0, node_url_1.fileURLToPath)(path);
|
|
134
|
+
}
|
|
135
|
+
return path;
|
|
136
|
+
}
|
|
137
|
+
async function fetchSnapshotBytes(url) {
|
|
138
|
+
const res = await fetch(url);
|
|
139
|
+
if (!res.ok) {
|
|
140
|
+
throw new Error(`LORA_ERROR: snapshot fetch failed (${res.status} ${res.statusText})`);
|
|
141
|
+
}
|
|
142
|
+
return node_buffer_1.Buffer.from(await res.arrayBuffer());
|
|
143
|
+
}
|
|
144
|
+
function isReadableStream(source) {
|
|
145
|
+
return typeof source.getReader === "function";
|
|
146
|
+
}
|
|
147
|
+
function isAsyncIterable(source) {
|
|
148
|
+
return typeof source[Symbol.asyncIterator] === "function";
|
|
149
|
+
}
|
|
150
|
+
async function readableStreamToBuffer(stream) {
|
|
151
|
+
const reader = stream.getReader();
|
|
152
|
+
const chunks = [];
|
|
153
|
+
try {
|
|
154
|
+
for (;;) {
|
|
155
|
+
const { done, value } = await reader.read();
|
|
156
|
+
if (done) {
|
|
157
|
+
return node_buffer_1.Buffer.concat(chunks);
|
|
158
|
+
}
|
|
159
|
+
chunks.push(snapshotChunkToBuffer(value));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
reader.releaseLock();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function asyncIterableToBuffer(stream) {
|
|
167
|
+
const chunks = [];
|
|
168
|
+
for await (const chunk of stream) {
|
|
169
|
+
chunks.push(snapshotChunkToBuffer(chunk));
|
|
170
|
+
}
|
|
171
|
+
return node_buffer_1.Buffer.concat(chunks);
|
|
172
|
+
}
|
|
173
|
+
async function resolveNodeSnapshotSource(source) {
|
|
174
|
+
if (source instanceof URL) {
|
|
175
|
+
if (source.protocol === "file:") {
|
|
176
|
+
return (0, node_url_1.fileURLToPath)(source);
|
|
177
|
+
}
|
|
178
|
+
if (isFetchUrl(source)) {
|
|
179
|
+
return fetchSnapshotBytes(source);
|
|
180
|
+
}
|
|
181
|
+
throw new Error(`LORA_ERROR: unsupported snapshot URL protocol '${source.protocol}'`);
|
|
182
|
+
}
|
|
183
|
+
if (typeof source === "string") {
|
|
184
|
+
const url = stringToUrl(source);
|
|
185
|
+
if (!url) {
|
|
186
|
+
return source;
|
|
187
|
+
}
|
|
188
|
+
if (url.protocol === "file:") {
|
|
189
|
+
return (0, node_url_1.fileURLToPath)(url);
|
|
190
|
+
}
|
|
191
|
+
if (isFetchUrl(url)) {
|
|
192
|
+
return fetchSnapshotBytes(url);
|
|
193
|
+
}
|
|
194
|
+
return source;
|
|
195
|
+
}
|
|
196
|
+
if (isReadableStream(source)) {
|
|
197
|
+
return readableStreamToBuffer(source);
|
|
198
|
+
}
|
|
199
|
+
if (source instanceof node_stream_1.Readable) {
|
|
200
|
+
return asyncIterableToBuffer(source);
|
|
201
|
+
}
|
|
202
|
+
if (isAsyncIterable(source)) {
|
|
203
|
+
return asyncIterableToBuffer(source);
|
|
204
|
+
}
|
|
205
|
+
return node_buffer_1.Buffer.from(bytesToUint8Array(source));
|
|
206
|
+
}
|
|
40
207
|
/**
|
|
41
|
-
*
|
|
208
|
+
* Lora graph database instance.
|
|
42
209
|
*
|
|
43
|
-
* Obtained exclusively via `createDatabase()`. There is no public
|
|
44
|
-
* and no synchronous factory
|
|
45
|
-
*
|
|
46
|
-
*
|
|
210
|
+
* Obtained exclusively via `createDatabase()`. There is no public
|
|
211
|
+
* constructor and no synchronous factory. With no args the instance is
|
|
212
|
+
* purely in-memory; with a WAL directory path it replays committed WAL
|
|
213
|
+
* state from disk before serving queries.
|
|
47
214
|
*
|
|
48
215
|
* Instances are independent — each owns its own in-memory graph. Multiple
|
|
49
|
-
* concurrent `execute()` calls against one instance
|
|
50
|
-
*
|
|
216
|
+
* concurrent read-only `execute()` calls against one instance can share
|
|
217
|
+
* the store read lock; writes serialize without blocking the event loop.
|
|
51
218
|
*/
|
|
52
219
|
class DatabaseImpl {
|
|
53
220
|
#inner;
|
|
@@ -68,30 +235,121 @@ class DatabaseImpl {
|
|
|
68
235
|
throw (0, types_js_1.wrapError)(err);
|
|
69
236
|
}
|
|
70
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Return an async row iterator for a query.
|
|
240
|
+
*
|
|
241
|
+
* The binding exposes the same `for await` shape as the Rust stream API.
|
|
242
|
+
* Rows are materialized by the native `execute()` promise today, then
|
|
243
|
+
* yielded one at a time to JS consumers.
|
|
244
|
+
*/
|
|
245
|
+
stream(query, params) {
|
|
246
|
+
try {
|
|
247
|
+
const streamId = this.#inner.openStream(query, params ?? null);
|
|
248
|
+
return new NativeRowStream(this.#inner, streamId);
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
throw (0, types_js_1.wrapError)(err);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/** Alias for `stream()`, useful when naming the row-level API explicitly. */
|
|
255
|
+
rows(query, params) {
|
|
256
|
+
return this.stream(query, params);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Execute a statement batch inside one native transaction.
|
|
260
|
+
*
|
|
261
|
+
* Results are returned in statement order. If any statement fails, the
|
|
262
|
+
* native transaction is dropped before commit and all prior writes in the
|
|
263
|
+
* batch are rolled back.
|
|
264
|
+
*/
|
|
265
|
+
async transaction(statements, mode = "read_write") {
|
|
266
|
+
try {
|
|
267
|
+
return (await this.#inner.transaction(statements, mode));
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
throw (0, types_js_1.wrapError)(err);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
71
273
|
/** Drop every node and relationship. Constant-time under the hood. */
|
|
72
274
|
async clear() {
|
|
73
|
-
|
|
275
|
+
try {
|
|
276
|
+
this.#inner.clear();
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
throw (0, types_js_1.wrapError)(err);
|
|
280
|
+
}
|
|
74
281
|
}
|
|
75
282
|
/** Number of nodes currently in the graph. */
|
|
76
283
|
async nodeCount() {
|
|
77
|
-
|
|
284
|
+
try {
|
|
285
|
+
return this.#inner.nodeCount();
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
throw (0, types_js_1.wrapError)(err);
|
|
289
|
+
}
|
|
78
290
|
}
|
|
79
291
|
/** Number of relationships currently in the graph. */
|
|
80
292
|
async relationshipCount() {
|
|
81
|
-
|
|
293
|
+
try {
|
|
294
|
+
return this.#inner.relationshipCount();
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
throw (0, types_js_1.wrapError)(err);
|
|
298
|
+
}
|
|
82
299
|
}
|
|
83
300
|
/**
|
|
84
|
-
*
|
|
85
|
-
* rename dance — the target path is only replaced once the full payload
|
|
86
|
-
* has been written and fsync'd.
|
|
301
|
+
* Release the native database handle. Idempotent.
|
|
87
302
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* Promise resolves immediately once the save returns.
|
|
303
|
+
* Call this when a WAL-backed database needs to be reopened in the same
|
|
304
|
+
* process. New operations after disposal reject with `database is closed`.
|
|
91
305
|
*/
|
|
92
|
-
|
|
306
|
+
dispose() {
|
|
93
307
|
try {
|
|
94
|
-
|
|
308
|
+
this.#inner.dispose();
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
throw (0, types_js_1.wrapError)(err);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Save the graph as a snapshot.
|
|
316
|
+
*
|
|
317
|
+
* - `saveSnapshot(path)` and `saveSnapshot({ format: "path", path })`
|
|
318
|
+
* write atomically to a local file and return `SnapshotMeta`.
|
|
319
|
+
* - `saveSnapshot("binary")` / `{ format: "binary" }` return a `Buffer`.
|
|
320
|
+
* - `saveSnapshot("base64")` / `{ format: "base64" }` return base64 text.
|
|
321
|
+
*/
|
|
322
|
+
async saveSnapshot(target) {
|
|
323
|
+
try {
|
|
324
|
+
if (target === "binary" || (typeof target === "object"
|
|
325
|
+
&& !(target instanceof URL)
|
|
326
|
+
&& target.format === "binary")) {
|
|
327
|
+
return this.saveSnapshotToBytes();
|
|
328
|
+
}
|
|
329
|
+
if (target === "base64" || (typeof target === "object"
|
|
330
|
+
&& !(target instanceof URL)
|
|
331
|
+
&& target.format === "base64")) {
|
|
332
|
+
return (await this.saveSnapshotToBytes()).toString("base64");
|
|
333
|
+
}
|
|
334
|
+
let path;
|
|
335
|
+
if (typeof target === "object" && !(target instanceof URL)) {
|
|
336
|
+
if (target.format !== "path") {
|
|
337
|
+
throw new Error(`LORA_ERROR: unsupported snapshot save format '${target.format}'`);
|
|
338
|
+
}
|
|
339
|
+
path = target.path;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
path = target;
|
|
343
|
+
}
|
|
344
|
+
return this.#inner.saveSnapshot(resolveNodeSnapshotPath(path));
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
throw (0, types_js_1.wrapError)(err);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async saveSnapshotToBytes() {
|
|
351
|
+
try {
|
|
352
|
+
return this.#inner.saveSnapshotToBytes();
|
|
95
353
|
}
|
|
96
354
|
catch (err) {
|
|
97
355
|
throw (0, types_js_1.wrapError)(err);
|
|
@@ -99,12 +357,24 @@ class DatabaseImpl {
|
|
|
99
357
|
}
|
|
100
358
|
/**
|
|
101
359
|
* Replace the current graph state with a snapshot loaded from `path`.
|
|
102
|
-
* Concurrent `execute()` calls block on the store
|
|
103
|
-
* completes.
|
|
360
|
+
* Concurrent `execute()` calls block on the store write lock until the
|
|
361
|
+
* load completes.
|
|
104
362
|
*/
|
|
105
|
-
async loadSnapshot(
|
|
363
|
+
async loadSnapshot(source) {
|
|
106
364
|
try {
|
|
107
|
-
|
|
365
|
+
const resolved = await resolveNodeSnapshotSource(source);
|
|
366
|
+
if (typeof resolved === "string") {
|
|
367
|
+
return this.#inner.loadSnapshot(resolved);
|
|
368
|
+
}
|
|
369
|
+
return this.#inner.loadSnapshotFromBytes(resolved);
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
throw (0, types_js_1.wrapError)(err);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
async loadSnapshotFromBytes(bytes) {
|
|
376
|
+
try {
|
|
377
|
+
return this.#inner.loadSnapshotFromBytes(node_buffer_1.Buffer.from(bytesToUint8Array(bytes)));
|
|
108
378
|
}
|
|
109
379
|
catch (err) {
|
|
110
380
|
throw (0, types_js_1.wrapError)(err);
|
|
@@ -112,26 +382,45 @@ class DatabaseImpl {
|
|
|
112
382
|
}
|
|
113
383
|
}
|
|
114
384
|
/**
|
|
115
|
-
* Create and initialize a new
|
|
385
|
+
* Create and initialize a new LoraDB instance.
|
|
116
386
|
*
|
|
117
387
|
* **This is the only supported initialization pattern** for `lora-node`.
|
|
118
388
|
* Synchronous construction is not available — the async factory guarantees
|
|
119
|
-
* the native layer is ready before the first query dispatches
|
|
120
|
-
* the Node and WASM surfaces symmetric.
|
|
389
|
+
* the native layer is ready before the first query dispatches.
|
|
121
390
|
*
|
|
122
391
|
* ```ts
|
|
123
392
|
* import { createDatabase } from "lora-node";
|
|
124
393
|
*
|
|
125
|
-
* const db = await createDatabase();
|
|
394
|
+
* const db = await createDatabase(); // in-memory by default
|
|
126
395
|
* const res = await db.execute(
|
|
127
396
|
* "CREATE (n:Person {name: $name}) RETURN n",
|
|
128
397
|
* { name: "Alice" },
|
|
129
398
|
* );
|
|
130
399
|
* ```
|
|
131
400
|
*
|
|
401
|
+
* Optional Node-only persistence convenience:
|
|
402
|
+
*
|
|
403
|
+
* ```ts
|
|
404
|
+
* import { createDatabase } from "lora-node";
|
|
405
|
+
*
|
|
406
|
+
* const inMemory = await createDatabase(); // in-memory
|
|
407
|
+
* const persistent = await createDatabase("./app"); // persistent: pass a directory string
|
|
408
|
+
* ```
|
|
409
|
+
*
|
|
410
|
+
* If you want persistence, pass a directory string. The string is treated
|
|
411
|
+
* as a WAL directory path verbatim. Relative paths resolve from the
|
|
412
|
+
* current working directory.
|
|
413
|
+
*
|
|
132
414
|
* Each call returns an independent graph — no shared state between instances.
|
|
133
415
|
*/
|
|
134
|
-
async function createDatabase() {
|
|
135
|
-
|
|
416
|
+
async function createDatabase(databaseName, options = {}) {
|
|
417
|
+
try {
|
|
418
|
+
return new DatabaseImpl(databaseName === undefined
|
|
419
|
+
? new NativeDatabase()
|
|
420
|
+
: new NativeDatabase(databaseName, options.databaseDir ?? null));
|
|
421
|
+
}
|
|
422
|
+
catch (err) {
|
|
423
|
+
throw (0, types_js_1.wrapError)(err);
|
|
424
|
+
}
|
|
136
425
|
}
|
|
137
426
|
//# 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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loradb/lora-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Node.js / TypeScript bindings for the Lora in-memory graph database",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "LoraDB, Inc.",
|
|
@@ -89,10 +89,10 @@
|
|
|
89
89
|
"vitest": "^2.1.1"
|
|
90
90
|
},
|
|
91
91
|
"optionalDependencies": {
|
|
92
|
-
"@loradb/lora-node-linux-x64-gnu": "0.
|
|
93
|
-
"@loradb/lora-node-linux-arm64-gnu": "0.
|
|
94
|
-
"@loradb/lora-node-darwin-x64": "0.
|
|
95
|
-
"@loradb/lora-node-darwin-arm64": "0.
|
|
96
|
-
"@loradb/lora-node-win32-x64-msvc": "0.
|
|
92
|
+
"@loradb/lora-node-linux-x64-gnu": "0.5.0",
|
|
93
|
+
"@loradb/lora-node-linux-arm64-gnu": "0.5.0",
|
|
94
|
+
"@loradb/lora-node-darwin-x64": "0.5.0",
|
|
95
|
+
"@loradb/lora-node-darwin-arm64": "0.5.0",
|
|
96
|
+
"@loradb/lora-node-win32-x64-msvc": "0.5.0"
|
|
97
97
|
}
|
|
98
98
|
}
|
package/ts/native.d.ts
CHANGED
|
@@ -19,17 +19,33 @@ export interface NativeSnapshotMeta {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export declare class Database {
|
|
22
|
-
constructor();
|
|
22
|
+
constructor(databaseName?: string | null, databaseDir?: string | null);
|
|
23
23
|
/** Non-blocking: runs on the libuv threadpool, returns a Promise. */
|
|
24
24
|
execute(
|
|
25
25
|
query: string,
|
|
26
26
|
params?: Record<string, unknown> | null,
|
|
27
27
|
): Promise<NativeQueryResult>;
|
|
28
|
+
openStream(
|
|
29
|
+
query: string,
|
|
30
|
+
params?: Record<string, unknown> | null,
|
|
31
|
+
): number;
|
|
32
|
+
streamColumns(streamId: number): string[];
|
|
33
|
+
streamNext(streamId: number): Record<string, unknown> | null;
|
|
34
|
+
streamClose(streamId: number): void;
|
|
35
|
+
transaction(
|
|
36
|
+
statements: Array<{ query: string; params?: Record<string, unknown> | null }>,
|
|
37
|
+
mode?: "read_write" | "read_only" | "readwrite" | "readonly" | "rw" | "ro" | null,
|
|
38
|
+
): Promise<NativeQueryResult[]>;
|
|
28
39
|
clear(): void;
|
|
29
40
|
nodeCount(): number;
|
|
30
41
|
relationshipCount(): number;
|
|
31
|
-
|
|
42
|
+
dispose(): void;
|
|
43
|
+
/** Atomic save. Synchronous under the store read lock. */
|
|
32
44
|
saveSnapshot(path: string): NativeSnapshotMeta;
|
|
45
|
+
/** Serialize the current graph into snapshot bytes. */
|
|
46
|
+
saveSnapshotToBytes(): Buffer;
|
|
33
47
|
/** Replace the current graph with the snapshot at `path`. */
|
|
34
48
|
loadSnapshot(path: string): NativeSnapshotMeta;
|
|
49
|
+
/** Replace the current graph with snapshot bytes. */
|
|
50
|
+
loadSnapshotFromBytes(bytes: Uint8Array | Buffer): NativeSnapshotMeta;
|
|
35
51
|
}
|