@lix-js/sdk 0.12.2 → 0.14.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 +40 -10
- package/dist/binding-types.d.ts +37 -9
- package/dist/binding.browser.d.ts +2 -2
- package/dist/binding.browser.js +25 -10
- package/dist/binding.node-wasm.d.ts +2 -2
- package/dist/binding.node-wasm.js +8 -4
- package/dist/binding.node.d.ts +3 -3
- package/dist/binding.node.js +70 -13
- package/dist/browser-wasm-init.d.ts +14 -0
- package/dist/browser-wasm-init.js +16 -0
- package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
- package/dist/bundled-plugins/plugin_markdown.lixplugin +0 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/lix.d.ts +27 -5
- package/dist/lix.js +135 -12
- package/dist/open-lix.d.ts +4 -5
- package/dist/open-lix.js +173 -33
- package/dist/remote/client.d.ts +1 -2
- package/dist/remote/client.js +58 -1151
- package/dist/remote/server-protocol.d.ts +5 -6
- package/dist/remote/server-protocol.js +40 -9
- package/dist/result.d.ts +6 -13
- package/dist/result.js +9 -35
- package/dist/snapshot-restore.d.ts +6 -0
- package/dist/snapshot-restore.js +101 -0
- package/dist/storage-adapter.d.ts +175 -19
- package/dist/storage-adapter.js +21 -0
- package/dist/types.d.ts +101 -31
- package/dist/value.d.ts +1 -0
- package/dist/value.js +8 -0
- package/dist/wasm/lix_js_sdk.d.ts +119 -24
- package/dist/wasm/lix_js_sdk.js +599 -78
- package/dist/wasm/lix_js_sdk_bg.wasm +0 -0
- package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +47 -6
- package/dist/worker/client.d.ts +27 -5
- package/dist/worker/client.js +458 -45
- package/dist/worker/factory.browser.d.ts +2 -2
- package/dist/worker/factory.node.d.ts +3 -2
- package/dist/worker/factory.node.js +18 -12
- package/dist/worker/host.d.ts +2 -1
- package/dist/worker/host.js +283 -37
- package/dist/worker/protocol.d.ts +80 -3
- package/package.json +6 -10
- package/dist/indexeddb-backend.d.ts +0 -19
- package/dist/indexeddb-backend.js +0 -121
- package/dist/remote/sse.d.ts +0 -12
- package/dist/remote/sse.js +0 -87
- package/dist/workerd.d.ts +0 -25
- package/dist/workerd.js +0 -35
package/README.md
CHANGED
|
@@ -18,10 +18,36 @@ import { openLix } from "@lix-js/sdk";
|
|
|
18
18
|
|
|
19
19
|
const lix = await openLix();
|
|
20
20
|
const result = await lix.execute("SELECT $1 AS message", ["hello"]);
|
|
21
|
-
console.log(result.rows[0]?.
|
|
21
|
+
console.log(result.rows[0]?.message);
|
|
22
22
|
await lix.close();
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
## Synchronized local repositories
|
|
26
|
+
|
|
27
|
+
Use sync mode when reads and writes should execute locally while Lix exchanges
|
|
28
|
+
commits with a hosted repository in the background:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { openLix } from "@lix-js/sdk";
|
|
32
|
+
import { OpfsStorage } from "@lix-js/storage-opfs";
|
|
33
|
+
|
|
34
|
+
const lix = await openLix({
|
|
35
|
+
storage: new OpfsStorage({ name: "acme" }),
|
|
36
|
+
server: {
|
|
37
|
+
mode: "sync",
|
|
38
|
+
url: "https://example.com/lix/01936f4e-7b6c-7c3d-8f9a-123456789abc",
|
|
39
|
+
headers: async () => ({
|
|
40
|
+
Authorization: `Bearer ${await accessToken()}`,
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`await lix.execute(...)` means that the local transaction committed. It does
|
|
47
|
+
not mean that the server has received the commit. Current data and new commits
|
|
48
|
+
synchronize automatically; older history and binary content load when needed.
|
|
49
|
+
See [Collaboration and Sync](https://lix.dev/docs/collaboration-and-sync).
|
|
50
|
+
|
|
25
51
|
## Remote repositories
|
|
26
52
|
|
|
27
53
|
Use the same Lix client as a thin client against a hosted repository:
|
|
@@ -30,7 +56,7 @@ Use the same Lix client as a thin client against a hosted repository:
|
|
|
30
56
|
const lix = await openLix({
|
|
31
57
|
server: {
|
|
32
58
|
mode: "remote",
|
|
33
|
-
url: "https://example.com/
|
|
59
|
+
url: "https://example.com/lix/01936f4e-7b6c-7c3d-8f9a-123456789abc",
|
|
34
60
|
headers: async () => ({
|
|
35
61
|
Authorization: `Bearer ${await accessToken()}`,
|
|
36
62
|
}),
|
|
@@ -78,7 +104,7 @@ const result = await lix.execute(
|
|
|
78
104
|
"SELECT content FROM lix_file WHERE path = $1",
|
|
79
105
|
["/hello.txt"],
|
|
80
106
|
);
|
|
81
|
-
const bytes = result.rows[0]?.
|
|
107
|
+
const bytes = result.rows[0]?.content as Uint8Array | undefined;
|
|
82
108
|
|
|
83
109
|
console.log(bytes && new TextDecoder().decode(bytes));
|
|
84
110
|
|
|
@@ -143,12 +169,16 @@ try {
|
|
|
143
169
|
## Notes
|
|
144
170
|
|
|
145
171
|
- `openLix()` opens a fresh in-memory Lix. Install `@lix-js/storage-filesystem` and pass `new FilesystemStorage({ path })` for a filesystem repository directory backed by `<path>/.lix/.internal/rocksdb`.
|
|
146
|
-
- In browsers,
|
|
147
|
-
|
|
172
|
+
- In browsers, install a storage provider such as `@lix-js/storage-opfs` and pass its
|
|
173
|
+
storage registration to `openLix()`.
|
|
174
|
+
- JavaScript storage packages register a worker-loadable module URL. That module exports
|
|
175
|
+
`createLixStorageProvider(options)` and returns the SDK's Rust-shaped `LixStorageProvider`:
|
|
176
|
+
`beginRead`, `beginWrite`, read/scan handles, write mutation methods, `commit`, and `rollback`.
|
|
177
|
+
The provider module is loaded beside the Lix Wasm engine in its dedicated worker; it does not
|
|
178
|
+
bundle or select a Lix engine version.
|
|
148
179
|
- Pass `syncAllFiles: false` to start filesystem sync with no regular repository files, then call `storage.importPaths(["notes/today.md"])` on the `FilesystemStorage` instance to sync selected files. Imported paths are exact repository-relative file paths, not directories or globs.
|
|
149
|
-
-
|
|
150
|
-
|
|
151
|
-
state.
|
|
180
|
+
- Browser-local storage loads the Rust engine as WebAssembly. Remote mode does
|
|
181
|
+
not open a local storage provider.
|
|
152
182
|
- `FilesystemStorage` is Node.js-only. Constructing it is safe in
|
|
153
183
|
shared code, but passing one to `openLix()` in a browser throws an error.
|
|
154
184
|
- The package is ESM-only.
|
|
@@ -161,8 +191,8 @@ try {
|
|
|
161
191
|
- Every browser `openLix()` owns one dedicated worker, so database work does
|
|
162
192
|
not block the page's main thread. Node.js uses the native binding's actor.
|
|
163
193
|
- Node.js executes installed Component API v1 plugins with the Rust SDK's
|
|
164
|
-
Wasmtime runtime. The browser
|
|
165
|
-
|
|
194
|
+
Wasmtime runtime. The browser binding currently opens without a component
|
|
195
|
+
runtime: it can use ordinary Lix storage and SQL, but does not
|
|
166
196
|
execute installed plugins. A browser Component host is a separate follow-up.
|
|
167
197
|
- A page Content Security Policy only needs to permit the package's same-origin
|
|
168
198
|
worker. WebAssembly compilation happens inside that worker, so the required
|
package/dist/binding-types.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import type { CreateBranchOptions, CreateBranchReceipt,
|
|
1
|
+
import type { CreateBranchOptions, CreateBranchReceipt, UndoReceipt, RedoReceipt, ExecuteOptions, LixBatchOptions, MergeBranchOptions, MergeBranchPreview, MergeBranchReceipt, SwitchBranchOptions, SwitchBranchReceipt, LixTelemetrySpan, LixTelemetryParentContext, LixOpenProgress, LixOpenReport, OpenAnotherSessionOptions, ResultColumn } from "./types.js";
|
|
2
2
|
import type { NativeLixValue } from "./value.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { LixStorageProvider } from "./storage-adapter.js";
|
|
4
|
+
export type SyncServerBindingOptions = {
|
|
5
|
+
url: string;
|
|
6
|
+
headers: [string, string][];
|
|
7
|
+
headerProvider?: () => Promise<[string, string][]>;
|
|
8
|
+
fetch?: typeof fetch;
|
|
9
|
+
};
|
|
4
10
|
export type BindingExecuteResult = {
|
|
5
11
|
statementIndex?: number;
|
|
6
12
|
label?: string;
|
|
7
|
-
columns:
|
|
13
|
+
columns: ResultColumn[];
|
|
8
14
|
rows: NativeLixValue[][];
|
|
9
15
|
rowsAffected: number;
|
|
10
16
|
notices: Array<{
|
|
@@ -19,12 +25,25 @@ export type BindingObserveEvent = {
|
|
|
19
25
|
rows: BindingExecuteResult;
|
|
20
26
|
};
|
|
21
27
|
export type BindingParam = NativeLixValue;
|
|
28
|
+
export type SnapshotExportBinding = {
|
|
29
|
+
next(): Promise<Uint8Array | null | undefined>;
|
|
30
|
+
cancel(): void | Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
export type SnapshotRestoreBinding<T> = {
|
|
33
|
+
write(chunk: Uint8Array): Promise<void>;
|
|
34
|
+
isComplete(): boolean;
|
|
35
|
+
finish(): Promise<T>;
|
|
36
|
+
cancel(): void | Promise<void>;
|
|
37
|
+
};
|
|
22
38
|
export type BindingBatchStatement = {
|
|
23
39
|
sql: string;
|
|
24
40
|
params: BindingParam[];
|
|
25
41
|
label?: string;
|
|
26
42
|
};
|
|
27
43
|
export type LixBinding = {
|
|
44
|
+
openReport?(): LixOpenReport | undefined;
|
|
45
|
+
setTelemetryParent(parent?: TelemetryParentContext): void;
|
|
46
|
+
openAnotherSession(options: OpenAnotherSessionOptions): Promise<LixBinding>;
|
|
28
47
|
execute(sql: string, params: BindingParam[], options?: ExecuteOptions): Promise<BindingExecuteResult>;
|
|
29
48
|
executeBatch(statements: BindingBatchStatement[], options?: LixBatchOptions): Promise<BindingExecuteResult[]>;
|
|
30
49
|
observe(sql: string, params: BindingParam[]): Promise<ObserveEventsBinding>;
|
|
@@ -32,7 +51,6 @@ export type LixBinding = {
|
|
|
32
51
|
activeBranchId(): Promise<string>;
|
|
33
52
|
activeAccountId(): Promise<string>;
|
|
34
53
|
createBranch(options: CreateBranchOptions): Promise<CreateBranchReceipt>;
|
|
35
|
-
createCheckpoint(): Promise<CreateCheckpointReceipt>;
|
|
36
54
|
undo(): Promise<UndoReceipt>;
|
|
37
55
|
redo(): Promise<RedoReceipt>;
|
|
38
56
|
switchBranch(options: SwitchBranchOptions): Promise<SwitchBranchReceipt>;
|
|
@@ -40,8 +58,7 @@ export type LixBinding = {
|
|
|
40
58
|
mergeBranchPreview(options: MergeBranchOptions): Promise<MergeBranchPreview>;
|
|
41
59
|
mergeBranch(options: MergeBranchOptions): Promise<MergeBranchReceipt>;
|
|
42
60
|
syncDiskToLix(): Promise<void>;
|
|
43
|
-
|
|
44
|
-
exportSnapshot?(): Promise<Uint8Array>;
|
|
61
|
+
exportSnapshot?(): SnapshotExportBinding;
|
|
45
62
|
close(): Promise<void>;
|
|
46
63
|
};
|
|
47
64
|
export type LixTransactionBinding = {
|
|
@@ -50,13 +67,24 @@ export type LixTransactionBinding = {
|
|
|
50
67
|
rollback(): Promise<void>;
|
|
51
68
|
};
|
|
52
69
|
export type ObserveEventsBinding = {
|
|
70
|
+
setTelemetryParent(parent?: TelemetryParentContext): void;
|
|
53
71
|
next(): Promise<BindingObserveEvent | null | undefined>;
|
|
54
72
|
close(): void;
|
|
55
73
|
};
|
|
56
74
|
export type TelemetryDispatch = (span: LixTelemetrySpan) => void;
|
|
75
|
+
export type OpenProgressDispatch = (progress: LixOpenProgress) => void;
|
|
76
|
+
export type TelemetryParentContext = LixTelemetryParentContext;
|
|
77
|
+
export type LixStorageProviderModule = {
|
|
78
|
+
createLixStorageProvider(options: unknown): Promise<LixStorageProvider>;
|
|
79
|
+
};
|
|
57
80
|
export type LixStorageConfig = {
|
|
58
81
|
kind: "memory";
|
|
59
82
|
} | {
|
|
60
|
-
kind: "
|
|
61
|
-
|
|
62
|
-
|
|
83
|
+
kind: "jsStorage";
|
|
84
|
+
moduleUrl: string;
|
|
85
|
+
options: unknown;
|
|
86
|
+
} | {
|
|
87
|
+
kind: "filesystem";
|
|
88
|
+
path: string;
|
|
89
|
+
syncAllFiles: boolean;
|
|
90
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { LixStorageConfig, LixBinding, TelemetryDispatch } from "./binding-types.js";
|
|
2
|
-
export declare function openLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch): Promise<LixBinding>;
|
|
1
|
+
import type { LixStorageConfig, LixBinding, SyncServerBindingOptions, TelemetryDispatch, TelemetryParentContext, OpenProgressDispatch } from "./binding-types.js";
|
|
2
|
+
export declare function openLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch, telemetryParent?: TelemetryParentContext, server?: SyncServerBindingOptions, openProgress?: OpenProgressDispatch, snapshot?: ReadableStream<Uint8Array>): Promise<LixBinding>;
|
package/dist/binding.browser.js
CHANGED
|
@@ -1,23 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { initializeBrowserWasm } from "./browser-wasm-init.js";
|
|
2
|
+
import { restoreSnapshot } from "./snapshot-restore.js";
|
|
2
3
|
// Generated before TypeScript compilation and emitted beside this module.
|
|
3
|
-
// @ts-
|
|
4
|
-
import initWasm, {
|
|
4
|
+
// @ts-ignore Generated by build:wasm and absent in source-only checks.
|
|
5
|
+
import initWasm, { openJsStorage, openJsStorageFromSnapshot, openMemory, openMemoryFromSnapshot, } from "./wasm/lix_js_sdk.js";
|
|
5
6
|
let wasmInitialized;
|
|
6
7
|
function initializeWasm() {
|
|
7
|
-
|
|
8
|
+
if (wasmInitialized !== undefined)
|
|
9
|
+
return wasmInitialized;
|
|
10
|
+
const initialization = initializeBrowserWasm(initWasm, new URL("./wasm/lix_js_sdk_bg.wasm", import.meta.url));
|
|
11
|
+
wasmInitialized = initialization;
|
|
12
|
+
return wasmInitialized;
|
|
8
13
|
}
|
|
9
|
-
export async function openLixBinding(storage, telemetry) {
|
|
14
|
+
export async function openLixBinding(storage, telemetry, telemetryParent, server, openProgress, snapshot) {
|
|
10
15
|
await initializeWasm();
|
|
11
16
|
switch (storage.kind) {
|
|
12
17
|
case "memory":
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
return (snapshot
|
|
19
|
+
? restoreSnapshot(snapshot, openMemoryFromSnapshot(telemetry, telemetryParent, openProgress))
|
|
20
|
+
: openMemory(telemetry, telemetryParent, server, openProgress));
|
|
21
|
+
case "jsStorage": {
|
|
22
|
+
const module = (await import(
|
|
23
|
+
/* @vite-ignore */ storage.moduleUrl));
|
|
24
|
+
if (typeof module.createLixStorageProvider !== "function") {
|
|
25
|
+
throw new TypeError(`Storage provider module '${storage.moduleUrl}' does not export createLixStorageProvider()`);
|
|
26
|
+
}
|
|
27
|
+
const provider = await module.createLixStorageProvider(storage.options);
|
|
16
28
|
try {
|
|
17
|
-
|
|
29
|
+
const binding = (await (snapshot
|
|
30
|
+
? restoreSnapshot(snapshot, openJsStorageFromSnapshot(provider, telemetry, telemetryParent, openProgress))
|
|
31
|
+
: openJsStorage(provider, telemetry, telemetryParent, server, openProgress)));
|
|
32
|
+
return binding;
|
|
18
33
|
}
|
|
19
34
|
catch (error) {
|
|
20
|
-
await
|
|
35
|
+
await provider.close().catch(() => undefined);
|
|
21
36
|
throw error;
|
|
22
37
|
}
|
|
23
38
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { LixBinding, TelemetryDispatch } from "./binding-types.js";
|
|
2
|
-
export declare function openMemoryWasmBinding(telemetry?: TelemetryDispatch): Promise<LixBinding>;
|
|
1
|
+
import type { LixBinding, TelemetryDispatch, TelemetryParentContext, OpenProgressDispatch } from "./binding-types.js";
|
|
2
|
+
export declare function openMemoryWasmBinding(telemetry?: TelemetryDispatch, telemetryParent?: TelemetryParentContext, openProgress?: OpenProgressDispatch, snapshot?: ReadableStream<Uint8Array>): Promise<LixBinding>;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { restoreSnapshot } from "./snapshot-restore.js";
|
|
2
3
|
// Generated before TypeScript compilation and emitted beside this module.
|
|
3
|
-
// @ts-
|
|
4
|
-
import initWasm, { openMemory } from "./wasm/lix_js_sdk.js";
|
|
4
|
+
// @ts-ignore Generated by build:wasm and absent in source-only checks.
|
|
5
|
+
import initWasm, { openMemory, openMemoryFromSnapshot } from "./wasm/lix_js_sdk.js";
|
|
5
6
|
let wasmInitialized;
|
|
6
7
|
function initializeWasm() {
|
|
7
8
|
return (wasmInitialized ??= initWasm({
|
|
8
9
|
module_or_path: readFile(new URL("./wasm/lix_js_sdk_bg.wasm", import.meta.url)),
|
|
9
10
|
}));
|
|
10
11
|
}
|
|
11
|
-
export async function openMemoryWasmBinding(telemetry) {
|
|
12
|
+
export async function openMemoryWasmBinding(telemetry, telemetryParent, openProgress, snapshot) {
|
|
12
13
|
await initializeWasm();
|
|
13
|
-
|
|
14
|
+
if (snapshot) {
|
|
15
|
+
return restoreSnapshot(snapshot, openMemoryFromSnapshot(telemetry, telemetryParent, openProgress));
|
|
16
|
+
}
|
|
17
|
+
return openMemory(telemetry, telemetryParent, undefined, openProgress);
|
|
14
18
|
}
|
package/dist/binding.node.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { LixStorageConfig, LixBinding, TelemetryDispatch } from "./binding-types.js";
|
|
2
|
-
export declare function openLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch): Promise<LixBinding>;
|
|
3
|
-
export declare function openNativeLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch): Promise<LixBinding>;
|
|
1
|
+
import type { LixStorageConfig, LixBinding, SyncServerBindingOptions, TelemetryDispatch, TelemetryParentContext, OpenProgressDispatch } from "./binding-types.js";
|
|
2
|
+
export declare function openLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch, telemetryParent?: TelemetryParentContext, server?: SyncServerBindingOptions, openProgress?: OpenProgressDispatch, snapshot?: ReadableStream<Uint8Array>): Promise<LixBinding>;
|
|
3
|
+
export declare function openNativeLixBinding(storage: LixStorageConfig, telemetry?: TelemetryDispatch, telemetryParent?: TelemetryParentContext, server?: SyncServerBindingOptions, openProgress?: OpenProgressDispatch, snapshot?: ReadableStream<Uint8Array>): Promise<LixBinding>;
|
package/dist/binding.node.js
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { restoreSnapshot } from "./snapshot-restore.js";
|
|
5
|
+
function normalizeNativeObserveEvents(events) {
|
|
6
|
+
return new Proxy(events, {
|
|
7
|
+
get(target, property, receiver) {
|
|
8
|
+
if (property === "setTelemetryParent") {
|
|
9
|
+
return (parent) => target.setTelemetryParent(parent === undefined ? undefined : JSON.stringify(parent));
|
|
10
|
+
}
|
|
11
|
+
const value = Reflect.get(target, property, receiver);
|
|
12
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function normalizeNativeBinding(binding) {
|
|
17
|
+
return new Proxy(binding, {
|
|
18
|
+
get(target, property, receiver) {
|
|
19
|
+
if (property === "setTelemetryParent") {
|
|
20
|
+
return (parent) => target.setTelemetryParent(parent === undefined ? undefined : JSON.stringify(parent));
|
|
21
|
+
}
|
|
22
|
+
if (property === "observe") {
|
|
23
|
+
return async (sql, params) => normalizeNativeObserveEvents(await target.observe(sql, params));
|
|
24
|
+
}
|
|
25
|
+
const value = Reflect.get(target, property, receiver);
|
|
26
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
4
30
|
const require = createRequire(import.meta.url);
|
|
5
31
|
const localNativePath = fileURLToPath(new URL("../lix_js_sdk.node", import.meta.url));
|
|
6
32
|
const nativePackages = {
|
|
@@ -30,6 +56,12 @@ function resolveNativePath() {
|
|
|
30
56
|
}
|
|
31
57
|
let addon;
|
|
32
58
|
let addonLoadError;
|
|
59
|
+
class NativeAddonUnavailableError extends Error {
|
|
60
|
+
constructor(message, options) {
|
|
61
|
+
super(message, options);
|
|
62
|
+
this.name = "NativeAddonUnavailableError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
33
65
|
function loadNativeAddon() {
|
|
34
66
|
if (addon)
|
|
35
67
|
return addon;
|
|
@@ -40,51 +72,76 @@ function loadNativeAddon() {
|
|
|
40
72
|
return addon;
|
|
41
73
|
}
|
|
42
74
|
catch (cause) {
|
|
43
|
-
const error = new
|
|
75
|
+
const error = new NativeAddonUnavailableError(`Failed to load @lix-js/sdk native addon for ${process.platform}-${process.arch}. ` +
|
|
44
76
|
"This package requires the matching optional native binary package. " +
|
|
45
77
|
"Run `npm run build` from packages/js-sdk for local development, or install a release that includes your platform binary.", { cause });
|
|
46
78
|
addonLoadError = error;
|
|
47
79
|
throw error;
|
|
48
80
|
}
|
|
49
81
|
}
|
|
50
|
-
export async function openLixBinding(storage, telemetry) {
|
|
82
|
+
export async function openLixBinding(storage, telemetry, telemetryParent, server, openProgress, snapshot) {
|
|
51
83
|
try {
|
|
52
|
-
return await openNativeLixBinding(storage, telemetry);
|
|
84
|
+
return await openNativeLixBinding(storage, telemetry, telemetryParent, server, openProgress, snapshot);
|
|
53
85
|
}
|
|
54
86
|
catch (nativeError) {
|
|
55
|
-
if (
|
|
87
|
+
if (!(nativeError instanceof NativeAddonUnavailableError) ||
|
|
88
|
+
storage.kind !== "memory" ||
|
|
89
|
+
server !== undefined) {
|
|
56
90
|
throw nativeError;
|
|
91
|
+
}
|
|
57
92
|
try {
|
|
58
93
|
const { openMemoryWasmBinding } = await import("./binding.node-wasm.js");
|
|
59
|
-
return await openMemoryWasmBinding(telemetry);
|
|
94
|
+
return await openMemoryWasmBinding(telemetry, telemetryParent, openProgress, snapshot);
|
|
60
95
|
}
|
|
61
96
|
catch (wasmError) {
|
|
62
97
|
throw new AggregateError([nativeError, wasmError], "Failed to open in-memory Lix with either the native or WebAssembly binding.");
|
|
63
98
|
}
|
|
64
99
|
}
|
|
65
100
|
}
|
|
66
|
-
export async function openNativeLixBinding(storage, telemetry) {
|
|
101
|
+
export async function openNativeLixBinding(storage, telemetry, telemetryParent, server, openProgress, snapshot) {
|
|
102
|
+
if (server?.fetch) {
|
|
103
|
+
throw new TypeError("Custom sync fetch is only supported by the browser worker");
|
|
104
|
+
}
|
|
105
|
+
const nativeOpenProgress = openProgress
|
|
106
|
+
? (progressJson) => {
|
|
107
|
+
try {
|
|
108
|
+
openProgress(JSON.parse(progressJson));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Open progress is observational and cannot fail repository opening.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
: undefined;
|
|
67
115
|
switch (storage.kind) {
|
|
68
116
|
case "memory": {
|
|
69
117
|
const nativeAddon = loadNativeAddon();
|
|
70
118
|
const nativeTelemetry = telemetry
|
|
71
119
|
? (spanJson) => telemetry(JSON.parse(spanJson))
|
|
72
120
|
: undefined;
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
121
|
+
if (snapshot) {
|
|
122
|
+
const restore = nativeAddon.Lix.openMemoryFromSnapshot(nativeTelemetry, telemetryParent ? JSON.stringify(telemetryParent) : undefined, nativeOpenProgress);
|
|
123
|
+
return normalizeNativeBinding(await restoreSnapshot(snapshot, restore));
|
|
124
|
+
}
|
|
125
|
+
if (nativeTelemetry) {
|
|
126
|
+
return normalizeNativeBinding(await nativeAddon.Lix.openMemory(nativeTelemetry, telemetryParent ? JSON.stringify(telemetryParent) : undefined, server?.url, server?.headers, nativeOpenProgress));
|
|
127
|
+
}
|
|
128
|
+
return normalizeNativeBinding(await nativeAddon.Lix.openMemory(undefined, undefined, server?.url, server?.headers, nativeOpenProgress));
|
|
76
129
|
}
|
|
77
|
-
case "
|
|
78
|
-
throw new Error("
|
|
130
|
+
case "jsStorage":
|
|
131
|
+
throw new Error("JavaScript storage providers are only available in browsers");
|
|
79
132
|
case "filesystem": {
|
|
80
133
|
const nativeAddon = loadNativeAddon();
|
|
81
134
|
const nativeTelemetry = telemetry
|
|
82
135
|
? (spanJson) => telemetry(JSON.parse(spanJson))
|
|
83
136
|
: undefined;
|
|
137
|
+
if (snapshot) {
|
|
138
|
+
const restore = nativeAddon.Lix.openFilesystemStorageFromSnapshot(storage.path, storage.syncAllFiles, nativeTelemetry, telemetryParent ? JSON.stringify(telemetryParent) : undefined, nativeOpenProgress);
|
|
139
|
+
return normalizeNativeBinding(await restoreSnapshot(snapshot, restore));
|
|
140
|
+
}
|
|
84
141
|
if (nativeTelemetry) {
|
|
85
|
-
return nativeAddon.Lix.openFilesystemStorage(storage.path, storage.syncAllFiles, nativeTelemetry);
|
|
142
|
+
return normalizeNativeBinding(await nativeAddon.Lix.openFilesystemStorage(storage.path, storage.syncAllFiles, nativeTelemetry, telemetryParent ? JSON.stringify(telemetryParent) : undefined, server?.url, server?.headers, nativeOpenProgress));
|
|
86
143
|
}
|
|
87
|
-
return nativeAddon.Lix.openFilesystemStorage(storage.path, storage.syncAllFiles);
|
|
144
|
+
return normalizeNativeBinding(await nativeAddon.Lix.openFilesystemStorage(storage.path, storage.syncAllFiles, undefined, undefined, server?.url, server?.headers, nativeOpenProgress));
|
|
88
145
|
}
|
|
89
146
|
}
|
|
90
147
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type WasmInitializer = (options: {
|
|
2
|
+
module_or_path: URL;
|
|
3
|
+
}) => Promise<unknown>;
|
|
4
|
+
/**
|
|
5
|
+
* Initializes one fingerprinted Wasm asset without racing the browser's shared
|
|
6
|
+
* HTTP cache across tabs.
|
|
7
|
+
*
|
|
8
|
+
* Chromium can abort one consumer when separate workers cold-load the same
|
|
9
|
+
* large response concurrently. The lock lasts only for the initial streaming
|
|
10
|
+
* compilation. Once it releases, later workers consume the completed immutable
|
|
11
|
+
* cache entry and compile independently.
|
|
12
|
+
*/
|
|
13
|
+
export declare function initializeBrowserWasm(initialize: WasmInitializer, moduleUrl: URL): Promise<unknown>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initializes one fingerprinted Wasm asset without racing the browser's shared
|
|
3
|
+
* HTTP cache across tabs.
|
|
4
|
+
*
|
|
5
|
+
* Chromium can abort one consumer when separate workers cold-load the same
|
|
6
|
+
* large response concurrently. The lock lasts only for the initial streaming
|
|
7
|
+
* compilation. Once it releases, later workers consume the completed immutable
|
|
8
|
+
* cache entry and compile independently.
|
|
9
|
+
*/
|
|
10
|
+
export function initializeBrowserWasm(initialize, moduleUrl) {
|
|
11
|
+
const lockManager = globalThis.navigator.locks;
|
|
12
|
+
const run = () => initialize({ module_or_path: moduleUrl });
|
|
13
|
+
if (!lockManager)
|
|
14
|
+
return run();
|
|
15
|
+
return lockManager.request(`lix:browser-wasm:${moduleUrl.href}`, { mode: "exclusive" }, run);
|
|
16
|
+
}
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { LixStorage,
|
|
1
|
+
export { Lix, LixTransaction, ObserveEvents, openLix } from "./open-lix.js";
|
|
2
|
+
export type { LixStorage, LixStorageBound, LixStorageChangeWatch, LixStorageCommitResult, LixStorageErrorCode, LixStorageGetManyRequest, LixStorageKeyRange, LixStoragePrecondition, LixStorageProjectedValue, LixStorageProvider, LixStorageProviderRegistration, LixStoragePutEntry, LixStorageRead, LixStorageReadEntry, LixStorageReadOptions, LixStorageScanOrder, LixStorageScanSource, LixStorageSpace, LixStorageWrite, LixStorageWriteOptions, LixStorageWriteStats, } from "./storage-adapter.js";
|
|
3
|
+
export { LixStorageError } from "./storage-adapter.js";
|
|
3
4
|
export { bundledPluginArchives, type BundledPluginArchive, } from "./bundled-plugins.js";
|
|
4
|
-
export { Row } from "./result.js";
|
|
5
5
|
export { Value } from "./value.js";
|
|
6
|
-
export type { CreateBranchOptions, CreateBranchReceipt,
|
|
6
|
+
export type { CreateBranchOptions, CreateBranchReceipt, RedoReceipt, ExecuteOptions, ExecuteResult, ExecuteBatchResult, LixBatchOptions, LixBatchStatement, JsonValue, LixValue, ResultArrayRow, ResultColumn, ResultColumnType, ResultObjectRow, ResultRow, MergeBranchOptions, MergeBranchOutcome, MergeBranchPreview, MergeBranchReceipt, MergeChangeStats, MergeConflict, MergeConflictSide, ObserveEvent, OpenLixOptions, OpenAnotherSessionOptions, LixTelemetryOptions, LixTelemetryParentContext, LixTelemetrySpan, LixTelemetrySpanLink, LixOpenMigrationReport, LixOpenPhase, LixOpenProgress, LixOpenProgressOptions, LixOpenReport, RemoteLixFetch, RemoteLixServerOptions, SyncLixServerOptions, UndoReceipt, SqlParam, SwitchBranchOptions, SwitchBranchReceipt, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Lix, LixTransaction, ObserveEvents, openLix } from "./open-lix.js";
|
|
2
|
+
export { LixStorageError } from "./storage-adapter.js";
|
|
2
3
|
export { bundledPluginArchives, } from "./bundled-plugins.js";
|
|
3
|
-
export { Row } from "./result.js";
|
|
4
4
|
export { Value } from "./value.js";
|
package/dist/lix.d.ts
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import type { LixBinding, LixTransactionBinding, ObserveEventsBinding } from "./binding-types.js";
|
|
2
|
-
import type { CreateBranchOptions, CreateBranchReceipt,
|
|
2
|
+
import type { CreateBranchOptions, CreateBranchReceipt, RedoReceipt, ExecuteOptions, ExecuteResult, ExecuteBatchResult, LixBatchOptions, LixBatchStatement, MergeBranchOptions, MergeBranchPreview, MergeBranchReceipt, ObserveEvent, OpenAnotherSessionOptions, LixOpenReport, SqlParam, ResultArrayRow, ResultObjectRow, ResultRow, SwitchBranchOptions, SwitchBranchReceipt, UndoReceipt } from "./types.js";
|
|
3
3
|
export declare class Lix {
|
|
4
4
|
#private;
|
|
5
5
|
private readonly binding;
|
|
6
|
+
readonly openReport: LixOpenReport | undefined;
|
|
6
7
|
private closePromise;
|
|
7
8
|
constructor(binding: LixBinding);
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/** Opens an independent session over the same repository storage. */
|
|
10
|
+
openAnotherSession(options?: OpenAnotherSessionOptions): Promise<Lix>;
|
|
11
|
+
execute(sql: string, params: SqlParam[] | undefined, options: ExecuteOptions & {
|
|
12
|
+
rowMode: "array";
|
|
13
|
+
}): Promise<ExecuteResult<ResultArrayRow>>;
|
|
14
|
+
execute<TRow extends object = ResultObjectRow>(sql: string, params?: SqlParam[], options?: ExecuteOptions & {
|
|
15
|
+
rowMode?: "object";
|
|
16
|
+
}): Promise<ExecuteResult<TRow>>;
|
|
17
|
+
execute(sql: string, params: SqlParam[] | undefined, options?: ExecuteOptions): Promise<ExecuteResult<ResultRow>>;
|
|
18
|
+
executeBatch(statements: readonly LixBatchStatement[], options: LixBatchOptions & {
|
|
19
|
+
rowMode: "array";
|
|
20
|
+
}): Promise<readonly ExecuteBatchResult<ResultArrayRow>[]>;
|
|
21
|
+
executeBatch(statements: readonly LixBatchStatement[], options?: LixBatchOptions & {
|
|
22
|
+
rowMode?: "object";
|
|
23
|
+
}): Promise<readonly ExecuteBatchResult<ResultObjectRow>[]>;
|
|
24
|
+
executeBatch(statements: readonly LixBatchStatement[], options?: LixBatchOptions): Promise<readonly ExecuteBatchResult<ResultRow>[]>;
|
|
10
25
|
observe(sql: string, params?: SqlParam[]): ObserveEvents;
|
|
11
26
|
beginTransaction(): Promise<LixTransaction>;
|
|
12
27
|
activeBranchId(): Promise<string>;
|
|
@@ -14,7 +29,8 @@ export declare class Lix {
|
|
|
14
29
|
/** Subscribes to successful branch switches made through this Lix handle. */
|
|
15
30
|
subscribeActiveBranch(listener: () => void): () => void;
|
|
16
31
|
createBranch(options: CreateBranchOptions): Promise<CreateBranchReceipt>;
|
|
17
|
-
|
|
32
|
+
/** Streams a deterministic snapshot of the complete Lix. */
|
|
33
|
+
exportSnapshot(): ReadableStream<Uint8Array>;
|
|
18
34
|
undo(): Promise<UndoReceipt>;
|
|
19
35
|
redo(): Promise<RedoReceipt>;
|
|
20
36
|
switchBranch(options: SwitchBranchOptions): Promise<SwitchBranchReceipt>;
|
|
@@ -37,7 +53,13 @@ export declare class LixTransaction {
|
|
|
37
53
|
private finishPromise;
|
|
38
54
|
private finished;
|
|
39
55
|
constructor(binding: LixTransactionBinding, onFinish?: () => void);
|
|
40
|
-
execute(sql: string, params
|
|
56
|
+
execute(sql: string, params: SqlParam[] | undefined, options: ExecuteOptions & {
|
|
57
|
+
rowMode: "array";
|
|
58
|
+
}): Promise<ExecuteResult<ResultArrayRow>>;
|
|
59
|
+
execute<TRow extends object = ResultObjectRow>(sql: string, params?: SqlParam[], options?: ExecuteOptions & {
|
|
60
|
+
rowMode?: "object";
|
|
61
|
+
}): Promise<ExecuteResult<TRow>>;
|
|
62
|
+
execute(sql: string, params: SqlParam[] | undefined, options?: ExecuteOptions): Promise<ExecuteResult<ResultRow>>;
|
|
41
63
|
commit(): Promise<void>;
|
|
42
64
|
rollback(): Promise<void>;
|
|
43
65
|
private finish;
|