@lix-js/sdk 0.16.1 → 0.17.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 +162 -44
- package/dist/binding-types.d.ts +15 -5
- package/dist/binding.browser.d.ts +2 -0
- package/dist/binding.browser.js +14 -4
- package/dist/binding.node-wasm.d.ts +1 -1
- package/dist/binding.node-wasm.js +5 -3
- package/dist/binding.node.d.ts +2 -0
- package/dist/binding.node.js +34 -8
- package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
- package/dist/bundled-plugins/plugin_markdown.lixplugin +0 -0
- package/dist/compatibility.d.ts +6 -0
- package/dist/compatibility.js +6 -0
- package/dist/component-host/dispatch.d.ts +12 -0
- package/dist/component-host/dispatch.js +364 -0
- package/dist/component-host/index.d.ts +15 -0
- package/dist/component-host/index.js +84 -0
- package/dist/component-host/instrument.d.ts +6 -0
- package/dist/component-host/instrument.js +260 -0
- package/dist/conversion-provider.d.ts +4 -0
- package/dist/conversion-provider.js +20 -0
- package/dist/hosted-lix.js +1 -1
- package/dist/http-transport.d.ts +25 -0
- package/dist/http-transport.js +162 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/lix.d.ts +14 -9
- package/dist/lix.js +44 -9
- package/dist/migration-binding.browser.d.ts +33 -0
- package/dist/migration-binding.browser.js +46 -0
- package/dist/migration-binding.node.d.ts +6 -0
- package/dist/migration-binding.node.js +5 -0
- package/dist/migration-wasm/lix_js_sdk.d.ts +271 -0
- package/dist/migration-wasm/lix_js_sdk.js +1852 -0
- package/dist/migration-wasm/lix_js_sdk_bg.wasm +4 -0
- package/dist/migration-wasm/lix_js_sdk_bg.wasm.d.ts +101 -0
- package/dist/migration.d.ts +23 -0
- package/dist/migration.js +55 -0
- package/dist/open-lix.js +29 -18
- package/dist/open-progress.d.ts +10 -0
- package/dist/open-progress.js +59 -0
- package/dist/remote/client.d.ts +2 -1
- package/dist/remote/client.js +11 -1
- package/dist/result.d.ts +4 -3
- package/dist/result.js +3 -4
- package/dist/storage-adapter.d.ts +7 -1
- package/dist/storage-ownership.d.ts +5 -0
- package/dist/storage-ownership.js +4 -0
- package/dist/types.d.ts +65 -31
- package/dist/wasm/lix_js_sdk.d.ts +45 -16
- package/dist/wasm/lix_js_sdk.js +214 -60
- package/dist/wasm/lix_js_sdk_bg.wasm +2 -2
- package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +17 -9
- package/dist/worker/client.d.ts +12 -3
- package/dist/worker/client.js +95 -81
- package/dist/worker/durable-local-admission.d.ts +20 -0
- package/dist/worker/durable-local-admission.js +87 -0
- package/dist/worker/entry.shared.browser.d.ts +1 -0
- package/dist/worker/entry.shared.browser.js +211 -0
- package/dist/worker/factory.browser.d.ts +2 -0
- package/dist/worker/factory.browser.js +65 -1
- package/dist/worker/factory.node.d.ts +1 -0
- package/dist/worker/factory.node.js +3 -0
- package/dist/worker/host.d.ts +4 -2
- package/dist/worker/host.js +86 -32
- package/dist/worker/protocol.d.ts +25 -8
- package/dist/worker/protocol.js +25 -7
- package/dist/worker/shared-admission.d.ts +26 -0
- package/dist/worker/shared-admission.js +116 -0
- package/dist/worker/shared-engine.d.ts +34 -0
- package/dist/worker/shared-engine.js +194 -0
- package/package.json +21 -9
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const __wbg_browsercomponenthost_free: (a: number, b: number) => void;
|
|
5
|
+
export const __wbg_wasmlix_free: (a: number, b: number) => void;
|
|
6
|
+
export const __wbg_wasmlixtransaction_free: (a: number, b: number) => void;
|
|
7
|
+
export const __wbg_wasmobserveevents_free: (a: number, b: number) => void;
|
|
8
|
+
export const __wbg_wasmremotelix_free: (a: number, b: number) => void;
|
|
9
|
+
export const __wbg_wasmremotelixtransaction_free: (a: number, b: number) => void;
|
|
10
|
+
export const __wbg_wasmremoteobserveevents_free: (a: number, b: number) => void;
|
|
11
|
+
export const __wbg_wasmsnapshotexport_free: (a: number, b: number) => void;
|
|
12
|
+
export const __wbg_wasmsnapshotrestore_free: (a: number, b: number) => void;
|
|
13
|
+
export const browsercomponenthost_call: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
14
|
+
export const convertJsStorageReplicaToPartial: (a: number, b: number, c: number, d: number) => number;
|
|
15
|
+
export const createHosted: (a: number) => number;
|
|
16
|
+
export const deleteHosted: (a: number) => number;
|
|
17
|
+
export const inspectJsStorageRepository: (a: number) => number;
|
|
18
|
+
export const migrateJsStorageRepository: (a: number, b: number) => number;
|
|
19
|
+
export const openJsStorage: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => number;
|
|
20
|
+
export const openJsStorageFromSnapshot: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
|
|
21
|
+
export const openMemory: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
|
|
22
|
+
export const openMemoryFromSnapshot: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
23
|
+
export const openRemote: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
24
|
+
export const parseSqlScript: (a: number, b: number, c: number, d: number) => void;
|
|
25
|
+
export const retryJsStorageReplicaMigrationCleanup: (a: number, b: number) => number;
|
|
26
|
+
export const wasmlix_activeAccountId: (a: number) => number;
|
|
27
|
+
export const wasmlix_activeBranchId: (a: number) => number;
|
|
28
|
+
export const wasmlix_beginTransaction: (a: number) => number;
|
|
29
|
+
export const wasmlix_close: (a: number) => number;
|
|
30
|
+
export const wasmlix_createBranch: (a: number, b: number) => number;
|
|
31
|
+
export const wasmlix_createHosted: (a: number, b: number) => number;
|
|
32
|
+
export const wasmlix_execute: (a: number, b: number, c: number, d: number, e: number) => number;
|
|
33
|
+
export const wasmlix_executeBatch: (a: number, b: number, c: number) => number;
|
|
34
|
+
export const wasmlix_exportReplicaRecovery: (a: number, b: number, c: number) => number;
|
|
35
|
+
export const wasmlix_exportSnapshot: (a: number) => number;
|
|
36
|
+
export const wasmlix_importFilesystemPaths: (a: number, b: number) => number;
|
|
37
|
+
export const wasmlix_mergeBranch: (a: number, b: number) => number;
|
|
38
|
+
export const wasmlix_mergeBranchPreview: (a: number, b: number) => number;
|
|
39
|
+
export const wasmlix_observe: (a: number, b: number, c: number, d: number) => number;
|
|
40
|
+
export const wasmlix_openAnotherSession: (a: number, b: number, c: number) => number;
|
|
41
|
+
export const wasmlix_openReport: (a: number, b: number) => void;
|
|
42
|
+
export const wasmlix_recoverReplica: (a: number, b: number, c: number) => number;
|
|
43
|
+
export const wasmlix_recoverReplicaWithServer: (a: number, b: number, c: number, d: number) => number;
|
|
44
|
+
export const wasmlix_redo: (a: number) => number;
|
|
45
|
+
export const wasmlix_replicaRecoverySources: (a: number) => number;
|
|
46
|
+
export const wasmlix_setTelemetryParent: (a: number, b: number, c: number) => void;
|
|
47
|
+
export const wasmlix_switchBranch: (a: number, b: number) => number;
|
|
48
|
+
export const wasmlix_syncDiskToLix: (a: number) => number;
|
|
49
|
+
export const wasmlix_syncHealth: (a: number) => number;
|
|
50
|
+
export const wasmlix_undo: (a: number) => number;
|
|
51
|
+
export const wasmlixtransaction_commit: (a: number) => number;
|
|
52
|
+
export const wasmlixtransaction_execute: (a: number, b: number, c: number, d: number, e: number) => number;
|
|
53
|
+
export const wasmlixtransaction_rollback: (a: number) => number;
|
|
54
|
+
export const wasmobserveevents_close: (a: number) => void;
|
|
55
|
+
export const wasmobserveevents_next: (a: number) => number;
|
|
56
|
+
export const wasmobserveevents_setTelemetryParent: (a: number, b: number, c: number) => void;
|
|
57
|
+
export const wasmremotelix_activeAccountId: (a: number) => number;
|
|
58
|
+
export const wasmremotelix_activeBranchId: (a: number) => number;
|
|
59
|
+
export const wasmremotelix_beginTransaction: (a: number) => number;
|
|
60
|
+
export const wasmremotelix_close: (a: number) => number;
|
|
61
|
+
export const wasmremotelix_createBranch: (a: number, b: number) => number;
|
|
62
|
+
export const wasmremotelix_execute: (a: number, b: number, c: number, d: number, e: number) => number;
|
|
63
|
+
export const wasmremotelix_executeBatch: (a: number, b: number, c: number) => number;
|
|
64
|
+
export const wasmremotelix_exportReplicaRecovery: (a: number, b: number, c: number) => number;
|
|
65
|
+
export const wasmremotelix_exportSnapshot: (a: number) => number;
|
|
66
|
+
export const wasmremotelix_importFilesystemPaths: (a: number, b: number) => number;
|
|
67
|
+
export const wasmremotelix_mergeBranch: (a: number, b: number) => number;
|
|
68
|
+
export const wasmremotelix_mergeBranchPreview: (a: number, b: number) => number;
|
|
69
|
+
export const wasmremotelix_observe: (a: number, b: number, c: number, d: number) => number;
|
|
70
|
+
export const wasmremotelix_openAnotherSession: (a: number, b: number) => number;
|
|
71
|
+
export const wasmremotelix_recoverReplica: (a: number, b: number, c: number) => number;
|
|
72
|
+
export const wasmremotelix_recoverReplicaWithServer: (a: number, b: number, c: number, d: number) => number;
|
|
73
|
+
export const wasmremotelix_redo: (a: number) => number;
|
|
74
|
+
export const wasmremotelix_replicaRecoverySources: (a: number) => number;
|
|
75
|
+
export const wasmremotelix_setTelemetryParent: (a: number, b: number) => void;
|
|
76
|
+
export const wasmremotelix_switchBranch: (a: number, b: number) => number;
|
|
77
|
+
export const wasmremotelix_syncDiskToLix: (a: number) => number;
|
|
78
|
+
export const wasmremotelix_syncHealth: (a: number) => number;
|
|
79
|
+
export const wasmremotelix_undo: (a: number) => number;
|
|
80
|
+
export const wasmremotelixtransaction_commit: (a: number) => number;
|
|
81
|
+
export const wasmremotelixtransaction_execute: (a: number, b: number, c: number, d: number, e: number) => number;
|
|
82
|
+
export const wasmremotelixtransaction_rollback: (a: number) => number;
|
|
83
|
+
export const wasmremoteobserveevents_close: (a: number) => void;
|
|
84
|
+
export const wasmremoteobserveevents_next: (a: number) => number;
|
|
85
|
+
export const wasmremoteobserveevents_setTelemetryParent: (a: number, b: number) => void;
|
|
86
|
+
export const wasmsnapshotexport_cancel: (a: number) => number;
|
|
87
|
+
export const wasmsnapshotexport_next: (a: number) => number;
|
|
88
|
+
export const wasmsnapshotrestore_cancel: (a: number) => number;
|
|
89
|
+
export const wasmsnapshotrestore_finish: (a: number) => number;
|
|
90
|
+
export const wasmsnapshotrestore_isComplete: (a: number) => number;
|
|
91
|
+
export const wasmsnapshotrestore_write: (a: number, b: number, c: number) => number;
|
|
92
|
+
export const __wasm_bindgen_func_elem_105798: (a: number, b: number, c: number, d: number) => void;
|
|
93
|
+
export const __wasm_bindgen_func_elem_105800: (a: number, b: number, c: number, d: number) => void;
|
|
94
|
+
export const __wasm_bindgen_func_elem_26031: (a: number, b: number, c: number) => number;
|
|
95
|
+
export const __wasm_bindgen_func_elem_26030: (a: number, b: number) => void;
|
|
96
|
+
export const __wbindgen_export: (a: number, b: number) => number;
|
|
97
|
+
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
98
|
+
export const __wbindgen_export3: (a: number) => void;
|
|
99
|
+
export const __wbindgen_export4: (a: number, b: number, c: number) => void;
|
|
100
|
+
export const __wbindgen_export5: (a: number, b: number) => void;
|
|
101
|
+
export const __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Detached migration entry. Normal SDK opening never imports this module. */
|
|
2
|
+
import { type LixStorage } from "./storage-adapter.js";
|
|
3
|
+
import type { LixServerOptions } from "./types.js";
|
|
4
|
+
export type ConvertReplicaToPartialOptions = {
|
|
5
|
+
storage: LixStorage;
|
|
6
|
+
server: LixServerOptions;
|
|
7
|
+
branchId?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Explicit conversion of closed full-replica storage; pending edits are preserved. */
|
|
10
|
+
export declare function convertReplicaToPartial(options: ConvertReplicaToPartialOptions): Promise<void>;
|
|
11
|
+
export type RetryReplicaMigrationCleanupOptions = {
|
|
12
|
+
storage: LixStorage;
|
|
13
|
+
server: LixServerOptions;
|
|
14
|
+
};
|
|
15
|
+
/** Retry durable migration cleanup on closed storage. Returns newly completed cleanups. */
|
|
16
|
+
export declare function retryReplicaMigrationCleanup(options: RetryReplicaMigrationCleanupOptions): Promise<number>;
|
|
17
|
+
export type { RepositoryInspection, RepositoryMigrationReport, MigrationLimits } from "./migration-binding.browser.js";
|
|
18
|
+
type MigrationBinding = typeof import("./migration-binding.browser.js");
|
|
19
|
+
export declare function initializeMigration(): Promise<unknown>;
|
|
20
|
+
export declare function inspectStorageProvider(...args: Parameters<MigrationBinding["inspectStorageProvider"]>): Promise<import("./migration-binding.browser.js").RepositoryInspection>;
|
|
21
|
+
export declare function migrateStorageProvider(...args: Parameters<MigrationBinding["migrateStorageProvider"]>): Promise<import("./migration-binding.browser.js").RepositoryMigrationReport>;
|
|
22
|
+
export declare function convertStorageProviderToPartial(...args: Parameters<MigrationBinding["convertStorageProviderToPartial"]>): Promise<void>;
|
|
23
|
+
export { fetchTransport } from "./http-transport.js";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Detached migration entry. Normal SDK opening never imports this module. */
|
|
2
|
+
import { isJsProviderLixStorage, isLixStorage } from "./storage-adapter.js";
|
|
3
|
+
import { openStorages, storageAlreadyOpen } from "./storage-ownership.js";
|
|
4
|
+
/** Explicit conversion of closed full-replica storage; pending edits are preserved. */
|
|
5
|
+
export async function convertReplicaToPartial(options) {
|
|
6
|
+
if (!options || (!isLixStorage(options.storage) && !isJsProviderLixStorage(options.storage)) || !options.server)
|
|
7
|
+
throw new TypeError("Conversion requires storage and server");
|
|
8
|
+
if (options.branchId !== undefined && (typeof options.branchId !== "string" || !options.branchId))
|
|
9
|
+
throw new TypeError("branchId must be a nonempty string");
|
|
10
|
+
const storage = options.storage;
|
|
11
|
+
if (openStorages.has(storage))
|
|
12
|
+
throw storageAlreadyOpen();
|
|
13
|
+
openStorages.add(storage);
|
|
14
|
+
try {
|
|
15
|
+
const registration = storage.lixStorage;
|
|
16
|
+
const config = isJsProviderLixStorage(storage) ? { kind: "jsStorage", moduleUrl: storage.lixStorage.moduleUrl, options: storage.lixStorage.options } :
|
|
17
|
+
registration.config;
|
|
18
|
+
const { convertReplicaWorkerOperation } = await import("./worker/client.js");
|
|
19
|
+
await convertReplicaWorkerOperation(config, options.server, options.branchId);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
openStorages.delete(storage);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Retry durable migration cleanup on closed storage. Returns newly completed cleanups. */
|
|
26
|
+
export async function retryReplicaMigrationCleanup(options) {
|
|
27
|
+
if (!options || (!isLixStorage(options.storage) && !isJsProviderLixStorage(options.storage)) || !options.server)
|
|
28
|
+
throw new TypeError("Migration cleanup requires storage and server");
|
|
29
|
+
const storage = options.storage;
|
|
30
|
+
if (openStorages.has(storage))
|
|
31
|
+
throw storageAlreadyOpen();
|
|
32
|
+
openStorages.add(storage);
|
|
33
|
+
try {
|
|
34
|
+
const config = isJsProviderLixStorage(storage) ? { kind: "jsStorage", moduleUrl: storage.lixStorage.moduleUrl, options: storage.lixStorage.options } :
|
|
35
|
+
storage.lixStorage.config;
|
|
36
|
+
const { retryReplicaMigrationCleanupWorkerOperation } = await import("./worker/client.js");
|
|
37
|
+
return await retryReplicaMigrationCleanupWorkerOperation(config, options.server);
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
openStorages.delete(storage);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function initializeMigration() {
|
|
44
|
+
return (await import("./migration-binding.browser.js")).initializeMigration();
|
|
45
|
+
}
|
|
46
|
+
export async function inspectStorageProvider(...args) {
|
|
47
|
+
return (await import("./migration-binding.browser.js")).inspectStorageProvider(...args);
|
|
48
|
+
}
|
|
49
|
+
export async function migrateStorageProvider(...args) {
|
|
50
|
+
return (await import("./migration-binding.browser.js")).migrateStorageProvider(...args);
|
|
51
|
+
}
|
|
52
|
+
export async function convertStorageProviderToPartial(...args) {
|
|
53
|
+
return (await import("./migration-binding.browser.js")).convertStorageProviderToPartial(...args);
|
|
54
|
+
}
|
|
55
|
+
export { fetchTransport } from "./http-transport.js";
|
package/dist/open-lix.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Lix } from "./lix.js";
|
|
2
2
|
import { isJsProviderLixStorage, isLixStorage, } from "./storage-adapter.js";
|
|
3
3
|
export { Lix, LixTransaction, ObserveEvents } from "./lix.js";
|
|
4
|
-
|
|
4
|
+
import { openStorages, storageAlreadyOpen } from "./storage-ownership.js";
|
|
5
5
|
export function openLix(options = {}) {
|
|
6
6
|
return openLixInternal(options);
|
|
7
7
|
}
|
|
@@ -9,6 +9,11 @@ async function openLixInternal(options, snapshot) {
|
|
|
9
9
|
if (!options || typeof options !== "object") {
|
|
10
10
|
throw new TypeError("openLix() options must be an object");
|
|
11
11
|
}
|
|
12
|
+
if (options.durability !== undefined &&
|
|
13
|
+
options.durability !== "durable" &&
|
|
14
|
+
options.durability !== "buffered") {
|
|
15
|
+
throw new TypeError('openLix() durability must be "durable" or "buffered"');
|
|
16
|
+
}
|
|
12
17
|
if ("backend" in options) {
|
|
13
18
|
throw new TypeError("openLix() option 'backend' was removed; use 'storage' instead");
|
|
14
19
|
}
|
|
@@ -26,19 +31,30 @@ async function openLixInternal(options, snapshot) {
|
|
|
26
31
|
throw new TypeError("openLix() onProgress must be a function");
|
|
27
32
|
}
|
|
28
33
|
if (options.server !== undefined) {
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
const mode = options.server.mode ?? "remote";
|
|
35
|
+
if (mode !== "remote" && mode !== "partial_replica") {
|
|
36
|
+
throw new TypeError('server.mode must be "remote" or "partial_replica"');
|
|
37
|
+
}
|
|
31
38
|
if (snapshot) {
|
|
32
39
|
throw new TypeError("openLix.fromSnapshot() does not accept server mode");
|
|
33
40
|
}
|
|
34
|
-
if (
|
|
35
|
-
if (options.
|
|
36
|
-
throw new TypeError("remote
|
|
41
|
+
if (mode === "remote") {
|
|
42
|
+
if (options.durability !== undefined) {
|
|
43
|
+
throw new TypeError("remote persistence is configured by the authority; durability requires local storage");
|
|
44
|
+
}
|
|
45
|
+
if (options.storage !== undefined) {
|
|
46
|
+
throw new TypeError('remote mode does not accept storage; set server.mode to "partial_replica" for on-demand sync');
|
|
47
|
+
}
|
|
48
|
+
if (options.telemetry !== undefined)
|
|
49
|
+
throw new TypeError("remote execution does not accept local telemetry");
|
|
37
50
|
const { openRemoteLixBinding } = await import("./remote/client.js");
|
|
38
|
-
return new Lix(await openRemoteLixBinding(options.server));
|
|
51
|
+
return new Lix(await openRemoteLixBinding(options.server, { onProgress: options.onProgress }));
|
|
52
|
+
}
|
|
53
|
+
if (options.storage === undefined) {
|
|
54
|
+
throw new TypeError('server.mode "partial_replica" requires storage');
|
|
39
55
|
}
|
|
40
56
|
}
|
|
41
|
-
const syncServer = options.server
|
|
57
|
+
const syncServer = options.server?.mode === "partial_replica"
|
|
42
58
|
? {
|
|
43
59
|
url: new URL(options.server.url).toString(),
|
|
44
60
|
headers: options.server.headers,
|
|
@@ -56,11 +72,11 @@ async function openLixInternal(options, snapshot) {
|
|
|
56
72
|
}
|
|
57
73
|
const { openLixWorkerBinding } = await import("./worker/client.js");
|
|
58
74
|
if (options.storage === undefined) {
|
|
59
|
-
const binding = await openLixWorkerBinding({ kind: "memory" }, undefined, options.telemetry, syncServer, options.onProgress, snapshot);
|
|
75
|
+
const binding = await openLixWorkerBinding({ kind: "memory", durability: options.durability ?? "durable" }, undefined, options.telemetry, syncServer, options.onProgress, snapshot);
|
|
60
76
|
return new Lix(binding);
|
|
61
77
|
}
|
|
62
78
|
if (isJsProviderLixStorage(options.storage)) {
|
|
63
|
-
return openJsProviderStorage(options.storage, options.telemetry, syncServer, options.onProgress, snapshot);
|
|
79
|
+
return openJsProviderStorage(options.storage, options.durability ?? "durable", options.telemetry, syncServer, options.onProgress, snapshot);
|
|
64
80
|
}
|
|
65
81
|
if (isLixStorage(options.storage)) {
|
|
66
82
|
const storage = options.storage;
|
|
@@ -74,7 +90,7 @@ async function openLixInternal(options, snapshot) {
|
|
|
74
90
|
openStorages.delete(storage);
|
|
75
91
|
};
|
|
76
92
|
try {
|
|
77
|
-
binding = await openLixWorkerBinding(storage.lixStorage.config, disconnect, options.telemetry, syncServer, options.onProgress, snapshot);
|
|
93
|
+
binding = await openLixWorkerBinding({ ...storage.lixStorage.config, durability: options.durability ?? "durable" }, disconnect, options.telemetry, syncServer, options.onProgress, snapshot);
|
|
78
94
|
const routed = routeStorageBinding(binding);
|
|
79
95
|
storage.lixStorage.connect({
|
|
80
96
|
importFilesystemPaths: (paths) => routed.current().importFilesystemPaths(paths),
|
|
@@ -122,7 +138,7 @@ function routeStorageBinding(root) {
|
|
|
122
138
|
},
|
|
123
139
|
};
|
|
124
140
|
}
|
|
125
|
-
async function openJsProviderStorage(storage, telemetry, syncServer, onProgress, snapshot) {
|
|
141
|
+
async function openJsProviderStorage(storage, durability, telemetry, syncServer, onProgress, snapshot) {
|
|
126
142
|
const { openLixWorkerBinding } = await import("./worker/client.js");
|
|
127
143
|
if (openStorages.has(storage))
|
|
128
144
|
throw storageAlreadyOpen();
|
|
@@ -131,6 +147,7 @@ async function openJsProviderStorage(storage, telemetry, syncServer, onProgress,
|
|
|
131
147
|
try {
|
|
132
148
|
const opened = await openLixWorkerBinding({
|
|
133
149
|
kind: "jsStorage",
|
|
150
|
+
durability,
|
|
134
151
|
moduleUrl: storage.lixStorage.moduleUrl,
|
|
135
152
|
options: storage.lixStorage.options,
|
|
136
153
|
}, () => openStorages.delete(storage), telemetry, syncServer, onProgress, snapshot);
|
|
@@ -218,9 +235,3 @@ function prepareSnapshotSource(source) {
|
|
|
218
235
|
}, { highWaterMark: 0 });
|
|
219
236
|
return { stream, cancel };
|
|
220
237
|
}
|
|
221
|
-
function storageAlreadyOpen() {
|
|
222
|
-
const error = new Error("openLix() storage is already open; close the existing Lix or create a new storage adapter");
|
|
223
|
-
error.name = "LixError";
|
|
224
|
-
error.code = "LIX_STORAGE_IN_USE";
|
|
225
|
-
return error;
|
|
226
|
-
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type HttpTransport } from "./http-transport.js";
|
|
2
|
+
import type { LixOpenProgress } from "./types.js";
|
|
3
|
+
/** Notifications cannot change an opening operation's result. */
|
|
4
|
+
export declare function emitOpenProgress(callback: ((progress: LixOpenProgress) => void) | undefined, progress: LixOpenProgress): void;
|
|
5
|
+
/** Observe bounded admission responses without taking ownership of retries. */
|
|
6
|
+
export declare function observeOpenProgress(callback?: (progress: LixOpenProgress) => void): {
|
|
7
|
+
transport(transport: HttpTransport): HttpTransport;
|
|
8
|
+
complete(): void;
|
|
9
|
+
stop(): void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { boundedResponseBody } from "./http-transport.js";
|
|
2
|
+
import { ADMISSION_STORAGE_EPOCH } from "./worker/shared-admission.js";
|
|
3
|
+
/** Notifications cannot change an opening operation's result. */
|
|
4
|
+
export function emitOpenProgress(callback, progress) {
|
|
5
|
+
try {
|
|
6
|
+
callback?.(progress);
|
|
7
|
+
}
|
|
8
|
+
catch { /* Observational only. */ }
|
|
9
|
+
}
|
|
10
|
+
/** Observe bounded admission responses without taking ownership of retries. */
|
|
11
|
+
export function observeOpenProgress(callback) {
|
|
12
|
+
let active = callback !== undefined;
|
|
13
|
+
let migrating = false;
|
|
14
|
+
let observed = false;
|
|
15
|
+
let fromFormat;
|
|
16
|
+
const emit = (phase) => active && emitOpenProgress(callback, { phase, scope: "authority", ...(fromFormat === undefined ? {} : { fromFormat }), toFormat: ADMISSION_STORAGE_EPOCH });
|
|
17
|
+
return {
|
|
18
|
+
transport(transport) {
|
|
19
|
+
if (!callback)
|
|
20
|
+
return transport;
|
|
21
|
+
return async (request) => {
|
|
22
|
+
const response = await transport(request);
|
|
23
|
+
if (!active || request.response.mode !== "buffered" ||
|
|
24
|
+
(request.init.method ?? "GET").toUpperCase() !== "GET" ||
|
|
25
|
+
!/\/lix\/v1\/[^/]+(?:\/admission)?\/?$/.test(new URL(request.url).pathname))
|
|
26
|
+
return response;
|
|
27
|
+
if (response.status === 503) {
|
|
28
|
+
// The ABI already supplies a byte budget. Consume once and return the
|
|
29
|
+
// same bounded bytes; do not tee or clone a potentially live body.
|
|
30
|
+
const bytes = await boundedResponseBody(response, request.response.maxBytes);
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
body = JSON.parse(new TextDecoder().decode(bytes));
|
|
34
|
+
}
|
|
35
|
+
catch { /* Preserve malformed errors. */ }
|
|
36
|
+
if (body?.error?.code === "LIX_REPOSITORY_MIGRATING" || body?.error?.code === "LIX_ERROR_MIGRATING") {
|
|
37
|
+
const from = body.error.details?.fromVersion ?? body.error.details?.fromFormat;
|
|
38
|
+
if (Number.isSafeInteger(from) && from >= 0 && from <= 0xffff_ffff)
|
|
39
|
+
fromFormat = from;
|
|
40
|
+
observed = true;
|
|
41
|
+
if (!migrating) {
|
|
42
|
+
migrating = true;
|
|
43
|
+
emit("migrating");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return new Response(bytes, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
47
|
+
}
|
|
48
|
+
if (response.ok && migrating) {
|
|
49
|
+
migrating = false;
|
|
50
|
+
emit("opening");
|
|
51
|
+
}
|
|
52
|
+
return response;
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
complete() { if (active && observed)
|
|
56
|
+
emit("complete"); active = false; },
|
|
57
|
+
stop() { active = false; },
|
|
58
|
+
};
|
|
59
|
+
}
|
package/dist/remote/client.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { LixBinding } from "../binding-types.js";
|
|
2
|
-
import type { LixServerOptions } from "../types.js";
|
|
2
|
+
import type { LixOpenProgress, LixServerOptions } from "../types.js";
|
|
3
3
|
type RemoteLixClientOptions = {
|
|
4
4
|
initialActiveBranchId?: string;
|
|
5
|
+
onProgress?: (progress: LixOpenProgress) => void;
|
|
5
6
|
};
|
|
6
7
|
export declare function openRemoteLixBinding(options: LixServerOptions, clientOptions?: RemoteLixClientOptions): Promise<LixBinding>;
|
|
7
8
|
export {};
|
package/dist/remote/client.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { observeOpenProgress } from "../open-progress.js";
|
|
2
|
+
import { fetchTransport } from "../http-transport.js";
|
|
1
3
|
import { initializeWasm } from "../wasm-init.js";
|
|
2
4
|
// Generated before TypeScript compilation and emitted beside the JS SDK.
|
|
3
5
|
// @ts-ignore Generated by build:wasm and absent in source-only checks.
|
|
@@ -22,7 +24,15 @@ export async function openRemoteLixBinding(options, clientOptions = {}) {
|
|
|
22
24
|
const locator = connectionUrl(options.url);
|
|
23
25
|
const protocolLocator = locator.toString();
|
|
24
26
|
await initializeWasm();
|
|
25
|
-
|
|
27
|
+
const progress = observeOpenProgress(clientOptions.onProgress);
|
|
28
|
+
try {
|
|
29
|
+
const binding = await openRemote(protocolLocator, progress.transport(fetchTransport(options.fetch)), options.headers, clientOptions.initialActiveBranchId);
|
|
30
|
+
progress.complete();
|
|
31
|
+
return binding;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
progress.stop();
|
|
35
|
+
}
|
|
26
36
|
}
|
|
27
37
|
function connectionUrl(value) {
|
|
28
38
|
let locator;
|
package/dist/result.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { type NativeLixValue } from "./value.js";
|
|
2
|
-
import type {
|
|
3
|
-
type NativeExecuteResult = Omit<ExecuteResult, "rows"> & {
|
|
2
|
+
import type { ExecuteBatchStatementResult, CommitSpan, ExecuteResult, ResultArrayRow, ResultObjectRow, ResultRow } from "./types.js";
|
|
3
|
+
type NativeExecuteResult = Omit<ExecuteResult, "rows" | "commit"> & {
|
|
4
|
+
commit?: CommitSpan | null;
|
|
4
5
|
rows: NativeLixValue[][];
|
|
5
6
|
};
|
|
6
7
|
export declare function wrapExecuteResult(result: NativeExecuteResult): ExecuteResult;
|
|
7
8
|
export declare function wrapExecuteResult(result: NativeExecuteResult, rowMode: "object"): ExecuteResult<ResultObjectRow>;
|
|
8
9
|
export declare function wrapExecuteResult(result: NativeExecuteResult, rowMode: "array"): ExecuteResult<ResultArrayRow>;
|
|
9
10
|
export declare function wrapExecuteResult(result: NativeExecuteResult, rowMode: "object" | "array"): ExecuteResult<ResultRow>;
|
|
10
|
-
export declare function wrapExecuteBatchResult(result: NativeExecuteResult, rowMode?: "object" | "array"):
|
|
11
|
+
export declare function wrapExecuteBatchResult(result: NativeExecuteResult, rowMode?: "object" | "array"): ExecuteBatchStatementResult<ResultRow>;
|
|
11
12
|
export declare function normalizeOptionals<T>(value: T): T;
|
|
12
13
|
export {};
|
package/dist/result.js
CHANGED
|
@@ -2,6 +2,7 @@ import { fromNativeValue, Value } from "./value.js";
|
|
|
2
2
|
export function wrapExecuteResult(result, rowMode = "object") {
|
|
3
3
|
return {
|
|
4
4
|
...result,
|
|
5
|
+
commit: result.commit ?? null,
|
|
5
6
|
rows: result.rows.map((row) => {
|
|
6
7
|
const values = row.map((value) => Value._fromNative(fromNativeValue(value)).toJS());
|
|
7
8
|
if (rowMode === "array")
|
|
@@ -17,10 +18,8 @@ export function wrapExecuteBatchResult(result, rowMode = "object") {
|
|
|
17
18
|
statementIndex < 0) {
|
|
18
19
|
throw new Error("executeBatch result is missing a valid statementIndex");
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
statementIndex,
|
|
23
|
-
};
|
|
21
|
+
const { commit: _commit, ...statement } = wrapExecuteResult(result, rowMode);
|
|
22
|
+
return { ...statement, statementIndex };
|
|
24
23
|
}
|
|
25
24
|
export function normalizeOptionals(value) {
|
|
26
25
|
if (Array.isArray(value))
|
|
@@ -135,6 +135,12 @@ export type LixStorageCommitResult = {
|
|
|
135
135
|
export interface LixStorageProvider {
|
|
136
136
|
/** Joins the active generation and returns its canonical unsigned 64-bit base-10 token. */
|
|
137
137
|
acquireSession(): Promise<string>;
|
|
138
|
+
/** Optional exclusive physical-store owner for partial replicas. The handle
|
|
139
|
+
* exists before asynchronous acquisition so close cancels even a granted lock. */
|
|
140
|
+
acquirePartialReplicaOwner?(sessionToken: string): {
|
|
141
|
+
readonly ready: Promise<void>;
|
|
142
|
+
close(): void;
|
|
143
|
+
};
|
|
138
144
|
beginRead(options: LixStorageReadOptions): Promise<LixStorageRead>;
|
|
139
145
|
beginWrite(options: LixStorageWriteOptions): Promise<LixStorageWrite>;
|
|
140
146
|
watchForChanges(): Promise<LixStorageChangeWatch>;
|
|
@@ -172,7 +178,7 @@ export interface LixStorageWrite {
|
|
|
172
178
|
commit(): Promise<LixStorageCommitResult>;
|
|
173
179
|
rollback(): Promise<void>;
|
|
174
180
|
}
|
|
175
|
-
export type LixStorageErrorCode = "LIX_STORAGE_UNSUPPORTED" | "LIX_STORAGE_INVALID_KEY" | "LIX_STORAGE_INVALID_CURSOR" | "LIX_STORAGE_READ_EXPIRED" | "LIX_STORAGE_WRITE_CONFLICT" | "LIX_STORAGE_PRECONDITION_FAILED" | "LIX_STORAGE_DURABILITY" | "LIX_STORAGE_FENCED" | "LIX_STORAGE_CLOSED" | "LIX_STORAGE_COMMIT_OUTCOME_UNKNOWN" | "LIX_STORAGE_CORRUPTION" | "LIX_STORAGE_IO";
|
|
181
|
+
export type LixStorageErrorCode = "LIX_STORAGE_UNSUPPORTED" | "LIX_STORAGE_INVALID_KEY" | "LIX_STORAGE_INVALID_CURSOR" | "LIX_STORAGE_READ_EXPIRED" | "LIX_STORAGE_WRITE_CONFLICT" | "LIX_STORAGE_PRECONDITION_FAILED" | "LIX_STORAGE_DURABILITY" | "LIX_STORAGE_IN_USE" | "LIX_STORAGE_FENCED" | "LIX_STORAGE_CLOSED" | "LIX_STORAGE_COMMIT_OUTCOME_UNKNOWN" | "LIX_STORAGE_CORRUPTION" | "LIX_STORAGE_IO";
|
|
176
182
|
/** Error representation decoded back into `lix::storage::StorageError`. */
|
|
177
183
|
export declare class LixStorageError extends Error {
|
|
178
184
|
readonly code: LixStorageErrorCode;
|