@lix-js/sdk 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +90 -22
  2. package/dist/binding-types.d.ts +52 -0
  3. package/dist/binding-types.js +1 -0
  4. package/dist/binding.browser.d.ts +2 -0
  5. package/dist/binding.browser.js +14 -0
  6. package/dist/binding.node.d.ts +2 -0
  7. package/dist/{native.js → binding.node.js} +15 -11
  8. package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
  9. package/dist/bundled-plugins/plugin_md_v2.lixplugin +0 -0
  10. package/dist/bundled-plugins.js +10 -2
  11. package/dist/errors.d.ts +2 -0
  12. package/dist/errors.js +13 -0
  13. package/dist/index.d.ts +1 -1
  14. package/dist/jco/js-component-bindgen-component.core.wasm +0 -0
  15. package/dist/jco/js-component-bindgen-component.core2.wasm +0 -0
  16. package/dist/jco/js-component-bindgen-component.js +13662 -0
  17. package/dist/jco-transpile.browser.d.ts +14 -0
  18. package/dist/jco-transpile.browser.js +22 -0
  19. package/dist/open-lix.d.ts +21 -39
  20. package/dist/open-lix.js +172 -34
  21. package/dist/plugin-runtime.d.ts +45 -0
  22. package/dist/plugin-runtime.js +124 -0
  23. package/dist/types.d.ts +5 -0
  24. package/dist/wasm/lix_js_sdk.d.ts +95 -0
  25. package/dist/wasm/lix_js_sdk.js +951 -0
  26. package/dist/wasm/lix_js_sdk_bg.wasm +0 -0
  27. package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +31 -0
  28. package/dist/worker/client.d.ts +17 -0
  29. package/dist/worker/client.js +104 -0
  30. package/dist/worker/entry.browser.d.ts +1 -0
  31. package/dist/worker/entry.browser.js +11 -0
  32. package/dist/worker/entry.node.d.ts +1 -0
  33. package/dist/worker/entry.node.js +13 -0
  34. package/dist/worker/factory.browser.d.ts +2 -0
  35. package/dist/worker/factory.browser.js +23 -0
  36. package/dist/worker/factory.node.d.ts +2 -0
  37. package/dist/worker/factory.node.js +35 -0
  38. package/dist/worker/host.d.ts +2 -0
  39. package/dist/worker/host.js +145 -0
  40. package/dist/worker/protocol.d.ts +96 -0
  41. package/dist/worker/protocol.js +23 -0
  42. package/dist/workerd.d.ts +15 -0
  43. package/dist/workerd.js +32 -0
  44. package/package.json +38 -8
  45. package/dist/native.d.ts +0 -1
@@ -0,0 +1,14 @@
1
+ type TranspileOptions = {
2
+ name?: string;
3
+ emitTypescriptDeclarations?: boolean;
4
+ instantiation?: "async" | "sync";
5
+ nodejsCompat?: boolean;
6
+ base64Cutoff?: number;
7
+ };
8
+ type TranspileResult = {
9
+ files: Record<string, Uint8Array>;
10
+ imports: string[];
11
+ exports: [string, "function" | "instance"][];
12
+ };
13
+ export declare function transpileBytes(component: Uint8Array, options?: TranspileOptions): Promise<TranspileResult>;
14
+ export {};
@@ -0,0 +1,22 @@
1
+ // This module is copied from the pinned JCO package by build:jco-browser. Using
2
+ // its browser-native generator avoids pulling JCO's CLI-only Node imports and
3
+ // optional minifier into application bundles.
4
+ // @ts-expect-error The generated module is copied into dist after tsc runs.
5
+ import { $init, generate } from "./jco/js-component-bindgen-component.js";
6
+ export async function transpileBytes(component, options = {}) {
7
+ await $init;
8
+ const generated = generate(component, {
9
+ name: options.name ?? "component",
10
+ noTypescript: options.emitTypescriptDeclarations === false,
11
+ instantiation: options.instantiation
12
+ ? { tag: options.instantiation }
13
+ : undefined,
14
+ noNodejsCompat: options.nodejsCompat === false,
15
+ base64Cutoff: options.base64Cutoff ?? 5000,
16
+ });
17
+ return {
18
+ files: Object.fromEntries(generated.files),
19
+ imports: generated.imports,
20
+ exports: generated.exports,
21
+ };
22
+ }
@@ -1,46 +1,24 @@
1
- import { wrapExecuteResult } from "./result.js";
2
- import { toNativeValue } from "./value.js";
3
- import type { CreateBranchOptions, CreateBranchReceipt, ExecuteResult, FsBackendOptions, MergeBranchOptions, MergeBranchPreview, MergeBranchReceipt, ObserveEvent, OpenLixOptions, SqlParam, SqliteBackendOptions, SwitchBranchOptions, SwitchBranchReceipt } from "./types.js";
4
- type NativeExecuteResult = Parameters<typeof wrapExecuteResult>[0];
5
- type NativeObserveEvent = {
6
- sequence: number;
7
- mutationSequence: number;
8
- rows: NativeExecuteResult;
9
- };
10
- type NativeParam = ReturnType<typeof toNativeValue>;
11
- type NativeLix = {
12
- execute(sql: string, params: NativeParam[]): NativeExecuteResult;
13
- observe(sql: string, params: NativeParam[]): NativeObserveEvents;
14
- beginTransaction(): NativeLixTransaction;
15
- activeBranchId(): string;
16
- createBranch(options: CreateBranchOptions): CreateBranchReceipt;
17
- switchBranch(options: SwitchBranchOptions): SwitchBranchReceipt;
18
- mergeBranchPreview(options: MergeBranchOptions): MergeBranchPreview;
19
- mergeBranch(options: MergeBranchOptions): MergeBranchReceipt;
20
- close(): void;
21
- };
22
- type NativeLixTransaction = {
23
- execute(sql: string, params: NativeParam[]): NativeExecuteResult;
24
- commit(): void;
25
- rollback(): void;
26
- };
27
- type NativeObserveEvents = {
28
- next(): Promise<NativeObserveEvent | null | undefined>;
29
- close(): void;
30
- };
1
+ import { LixWorkerClient } from "./worker/client.js";
2
+ import type { CreateBranchOptions, CreateBranchReceipt, ExecuteOptions, ExecuteResult, FsBackendOptions, MergeBranchOptions, MergeBranchPreview, MergeBranchReceipt, ObserveEvent, OpenLixOptions, SqlParam, SqliteBackendOptions, SwitchBranchOptions, SwitchBranchReceipt } from "./types.js";
31
3
  export declare class SqliteBackend {
32
4
  readonly path: string;
33
5
  constructor(options: SqliteBackendOptions);
34
6
  }
35
7
  export declare class FsBackend {
36
8
  readonly path: string;
9
+ readonly lixDir: string | undefined;
10
+ readonly syncAllFiles: boolean;
37
11
  constructor(options: FsBackendOptions);
12
+ importPaths(paths: readonly string[]): Promise<void>;
13
+ syncDiskToLix(): Promise<void>;
14
+ private client;
38
15
  }
39
16
  export declare function openLix(options?: OpenLixOptions): Promise<Lix>;
40
17
  export declare class Lix {
41
- private readonly native;
42
- constructor(native: NativeLix);
43
- execute(sql: string, params?: SqlParam[]): Promise<ExecuteResult>;
18
+ private readonly client;
19
+ private closePromise;
20
+ constructor(client: LixWorkerClient);
21
+ execute(sql: string, params?: SqlParam[], options?: ExecuteOptions): Promise<ExecuteResult>;
44
22
  observe(sql: string, params?: SqlParam[]): ObserveEvents;
45
23
  beginTransaction(): Promise<LixTransaction>;
46
24
  activeBranchId(): Promise<string>;
@@ -51,16 +29,20 @@ export declare class Lix {
51
29
  close(): Promise<void>;
52
30
  }
53
31
  export declare class ObserveEvents {
54
- private readonly native;
55
- constructor(native: NativeObserveEvents);
32
+ private readonly client;
33
+ private readonly setup;
34
+ private closed;
35
+ private readonly observeId;
36
+ constructor(client: LixWorkerClient, observeId: Promise<number>);
56
37
  next(): Promise<ObserveEvent | undefined>;
57
38
  close(): void;
58
39
  }
59
40
  export declare class LixTransaction {
60
- private readonly native;
61
- constructor(native: NativeLixTransaction);
62
- execute(sql: string, params?: SqlParam[]): Promise<ExecuteResult>;
41
+ private readonly client;
42
+ private readonly transactionId;
43
+ constructor(client: LixWorkerClient, transactionId: number);
44
+ execute(sql: string, params?: SqlParam[], options?: ExecuteOptions): Promise<ExecuteResult>;
63
45
  commit(): Promise<void>;
64
46
  rollback(): Promise<void>;
47
+ private finish;
65
48
  }
66
- export {};
package/dist/open-lix.js CHANGED
@@ -1,7 +1,16 @@
1
- import { invalidArgument } from "./errors.js";
2
- import { addon } from "./native.js";
1
+ import { fsBackendAlreadyOpen, fsBackendNotOpen, invalidArgument, } from "./errors.js";
3
2
  import { normalizeOptionals, wrapExecuteResult } from "./result.js";
4
3
  import { normalizeParam, toNativeValue } from "./value.js";
4
+ import { openLixWorker } from "./worker/client.js";
5
+ const transactionFinalizer = new FinalizationRegistry(({ client, transactionId }) => {
6
+ client.notify({ kind: "transaction.abandon", transactionId });
7
+ });
8
+ const observeFinalizer = new FinalizationRegistry(({ client, observeId }) => {
9
+ void observeId.then((id) => {
10
+ if (id !== undefined)
11
+ client.notify({ kind: "observe.close", observeId: id });
12
+ });
13
+ });
5
14
  export class SqliteBackend {
6
15
  path;
7
16
  constructor(options) {
@@ -13,15 +22,54 @@ export class SqliteBackend {
13
22
  this.path = options.path;
14
23
  }
15
24
  }
25
+ const openFsBackends = new WeakMap();
16
26
  export class FsBackend {
17
27
  path;
28
+ lixDir;
29
+ syncAllFiles;
18
30
  constructor(options) {
19
31
  if (!options ||
20
32
  typeof options.path !== "string" ||
21
33
  options.path.length === 0) {
22
34
  throw new TypeError("FsBackend requires a non-empty path");
23
35
  }
36
+ if (options.lixDir !== undefined &&
37
+ (typeof options.lixDir !== "string" || options.lixDir.length === 0)) {
38
+ throw new TypeError("FsBackend lixDir must be a non-empty string");
39
+ }
40
+ if (typeof options.syncAllFiles !== "boolean") {
41
+ throw new TypeError("FsBackend syncAllFiles must be a boolean");
42
+ }
24
43
  this.path = options.path;
44
+ this.lixDir = options.lixDir;
45
+ this.syncAllFiles = options.syncAllFiles;
46
+ }
47
+ async importPaths(paths) {
48
+ if (!Array.isArray(paths)) {
49
+ throw new TypeError("importPaths() paths must be an array");
50
+ }
51
+ for (const path of paths) {
52
+ if (typeof path !== "string" || path.length === 0) {
53
+ throw new TypeError("importPaths() paths must contain non-empty strings");
54
+ }
55
+ if (path.endsWith("/")) {
56
+ throw new TypeError("importPaths() paths must contain file paths, not directory paths");
57
+ }
58
+ }
59
+ await this.client("importPaths").request({
60
+ kind: "importFilesystemPaths",
61
+ paths: [...paths],
62
+ });
63
+ }
64
+ async syncDiskToLix() {
65
+ return this.client("syncDiskToLix").request({ kind: "syncDiskToLix" });
66
+ }
67
+ client(operation) {
68
+ const client = openFsBackends.get(this);
69
+ if (!client) {
70
+ throw fsBackendNotOpen(operation);
71
+ }
72
+ return client;
25
73
  }
26
74
  }
27
75
  export async function openLix(options = {}) {
@@ -29,60 +77,119 @@ export async function openLix(options = {}) {
29
77
  throw new TypeError("openLix() options must be an object");
30
78
  }
31
79
  if (options.backend === undefined) {
32
- return new Lix(addon.Lix.openMemory());
80
+ return new Lix(await openLixWorker({ kind: "memory" }));
33
81
  }
34
82
  if (options.backend instanceof SqliteBackend) {
35
- return new Lix(addon.Lix.openSqlite(options.backend.path));
83
+ return new Lix(await openLixWorker({ kind: "sqlite", path: options.backend.path }));
36
84
  }
37
85
  if (options.backend instanceof FsBackend) {
38
- return new Lix(addon.Lix.openFs(options.backend.path));
86
+ const backend = options.backend;
87
+ if (openFsBackends.has(backend)) {
88
+ throw fsBackendAlreadyOpen();
89
+ }
90
+ openFsBackends.set(backend, null);
91
+ try {
92
+ const client = await openLixWorker({
93
+ kind: "fs",
94
+ path: backend.path,
95
+ lixDir: backend.lixDir,
96
+ syncAllFiles: backend.syncAllFiles,
97
+ }, () => openFsBackends.delete(backend));
98
+ openFsBackends.set(backend, client);
99
+ return new Lix(client);
100
+ }
101
+ catch (error) {
102
+ openFsBackends.delete(backend);
103
+ throw error;
104
+ }
39
105
  }
40
- throw new TypeError("openLix() requires { backend: new SqliteBackend({ path }) } or { backend: new FsBackend({ path }) }");
106
+ throw new TypeError("openLix() requires backend to be SqliteBackend or FsBackend");
41
107
  }
42
108
  export class Lix {
43
- native;
44
- constructor(native) {
45
- this.native = native;
109
+ client;
110
+ closePromise;
111
+ constructor(client) {
112
+ this.client = client;
46
113
  }
47
- async execute(sql, params = []) {
48
- assertExecuteArgs("lix", sql, params);
49
- return wrapExecuteResult(this.native.execute(sql, params.map((param, index) => toNativeValue(normalizeParam(param, index)))));
114
+ async execute(sql, params = [], options) {
115
+ assertExecuteArgs("lix", sql, params, options);
116
+ return wrapExecuteResult(await this.client.request({
117
+ kind: "execute",
118
+ sql,
119
+ params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
120
+ options,
121
+ }));
50
122
  }
51
123
  observe(sql, params = []) {
52
124
  assertSqlArgs("observe", "lix", sql, params);
53
- return new ObserveEvents(this.native.observe(sql, params.map((param, index) => toNativeValue(normalizeParam(param, index)))));
125
+ return new ObserveEvents(this.client, this.client.request({
126
+ kind: "observe",
127
+ sql,
128
+ params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
129
+ }));
54
130
  }
55
131
  async beginTransaction() {
56
- return new LixTransaction(this.native.beginTransaction());
132
+ const transactionId = await this.client.request({
133
+ kind: "beginTransaction",
134
+ });
135
+ return new LixTransaction(this.client, transactionId);
57
136
  }
58
137
  async activeBranchId() {
59
- return this.native.activeBranchId();
138
+ return this.client.request({ kind: "activeBranchId" });
60
139
  }
61
140
  async createBranch(options) {
62
- return this.native.createBranch(options);
141
+ return this.client.request({ kind: "createBranch", options });
63
142
  }
64
143
  async switchBranch(options) {
65
- return this.native.switchBranch(options);
144
+ return this.client.request({ kind: "switchBranch", options });
66
145
  }
67
146
  async mergeBranchPreview(options) {
68
- return normalizeOptionals(this.native.mergeBranchPreview(options));
147
+ return normalizeOptionals(await this.client.request({ kind: "mergeBranchPreview", options }));
69
148
  }
70
149
  async mergeBranch(options) {
71
- const receipt = normalizeOptionals(this.native.mergeBranch(options));
150
+ const receipt = normalizeOptionals(await this.client.request({ kind: "mergeBranch", options }));
72
151
  receipt.createdMergeCommitId ??= null;
73
152
  return receipt;
74
153
  }
75
154
  async close() {
76
- return this.native.close();
155
+ this.closePromise ??= (async () => {
156
+ await this.client.request({ kind: "close" });
157
+ await this.client.terminate();
158
+ })();
159
+ try {
160
+ await this.closePromise;
161
+ }
162
+ catch (error) {
163
+ this.closePromise = undefined;
164
+ throw error;
165
+ }
77
166
  }
78
167
  }
79
168
  export class ObserveEvents {
80
- native;
81
- constructor(native) {
82
- this.native = native;
169
+ client;
170
+ setup = {};
171
+ closed = false;
172
+ observeId;
173
+ constructor(client, observeId) {
174
+ this.client = client;
175
+ const setup = this.setup;
176
+ this.observeId = observeId.catch((error) => {
177
+ setup.error = error;
178
+ return undefined;
179
+ });
180
+ observeFinalizer.register(this, { client, observeId: this.observeId }, this);
83
181
  }
84
182
  async next() {
85
- const event = await this.native.next();
183
+ if (this.closed)
184
+ return undefined;
185
+ const observeId = await this.observeId;
186
+ if (observeId === undefined) {
187
+ throw this.setup.error;
188
+ }
189
+ const event = await this.client.request({
190
+ kind: "observe.next",
191
+ observeId,
192
+ });
86
193
  if (event == null) {
87
194
  return undefined;
88
195
  }
@@ -93,27 +200,58 @@ export class ObserveEvents {
93
200
  };
94
201
  }
95
202
  close() {
96
- this.native.close();
203
+ if (this.closed)
204
+ return;
205
+ this.closed = true;
206
+ observeFinalizer.unregister(this);
207
+ void this.observeId.then((observeId) => {
208
+ if (observeId !== undefined) {
209
+ this.client.notify({ kind: "observe.close", observeId });
210
+ }
211
+ });
97
212
  }
98
213
  }
99
214
  export class LixTransaction {
100
- native;
101
- constructor(native) {
102
- this.native = native;
215
+ client;
216
+ transactionId;
217
+ constructor(client, transactionId) {
218
+ this.client = client;
219
+ this.transactionId = transactionId;
220
+ transactionFinalizer.register(this, { client, transactionId }, this);
103
221
  }
104
- async execute(sql, params = []) {
105
- assertExecuteArgs("lixTransaction", sql, params);
106
- return wrapExecuteResult(this.native.execute(sql, params.map((param, index) => toNativeValue(normalizeParam(param, index)))));
222
+ async execute(sql, params = [], options) {
223
+ assertExecuteArgs("lixTransaction", sql, params, options);
224
+ return wrapExecuteResult(await this.client.request({
225
+ kind: "transaction.execute",
226
+ transactionId: this.transactionId,
227
+ sql,
228
+ params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
229
+ options,
230
+ }));
107
231
  }
108
232
  async commit() {
109
- return this.native.commit();
233
+ return this.finish("transaction.commit");
110
234
  }
111
235
  async rollback() {
112
- return this.native.rollback();
236
+ return this.finish("transaction.rollback");
237
+ }
238
+ async finish(kind) {
239
+ transactionFinalizer.unregister(this);
240
+ return this.client.request({ kind, transactionId: this.transactionId });
113
241
  }
114
242
  }
115
- function assertExecuteArgs(receiver, sql, params) {
243
+ function assertExecuteArgs(receiver, sql, params, options) {
116
244
  assertSqlArgs("execute", receiver, sql, params);
245
+ if (options === undefined) {
246
+ return;
247
+ }
248
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
249
+ throw invalidArgument("execute", "options", "object", typeof options, receiver);
250
+ }
251
+ if (options.originKey !== undefined &&
252
+ typeof options.originKey !== "string") {
253
+ throw invalidArgument("execute", "options.originKey", "string", typeof options.originKey, receiver);
254
+ }
117
255
  }
118
256
  function assertSqlArgs(operation, receiver, sql, params) {
119
257
  if (typeof sql !== "string") {
@@ -0,0 +1,45 @@
1
+ type PluginRuntimeOperation = "initComponent" | "detectChanges" | "render" | "closeComponent";
2
+ export type PluginRuntimeRequest = {
3
+ operation: PluginRuntimeOperation;
4
+ componentId?: number;
5
+ componentBytes?: Uint8Array;
6
+ maxMemoryBytes?: string;
7
+ maxFuel?: string;
8
+ timeoutMs?: string;
9
+ state?: PluginEntityState[];
10
+ file?: PluginFile;
11
+ };
12
+ export type PluginRuntimeResponse = {
13
+ componentId?: number;
14
+ changes?: PluginDetectedChange[];
15
+ bytes?: Uint8Array;
16
+ errorMessage?: string;
17
+ };
18
+ type PluginFile = {
19
+ filename?: string;
20
+ data: Uint8Array;
21
+ };
22
+ type PluginEntityState = {
23
+ entityPk: string[];
24
+ schemaKey: string;
25
+ snapshotContent: string;
26
+ metadata?: string;
27
+ };
28
+ type PluginDetectedChange = {
29
+ entityPk: string[];
30
+ schemaKey: string;
31
+ snapshotContent?: string;
32
+ metadata?: string;
33
+ };
34
+ declare class WasmPluginRuntime {
35
+ private nextComponentId;
36
+ private readonly components;
37
+ readonly dispatch: (request: PluginRuntimeRequest) => Promise<PluginRuntimeResponse>;
38
+ private initComponent;
39
+ private detectChanges;
40
+ private render;
41
+ private closeComponent;
42
+ private requiredComponent;
43
+ }
44
+ export declare function createPluginRuntimeDispatch(): WasmPluginRuntime["dispatch"];
45
+ export {};
@@ -0,0 +1,124 @@
1
+ import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation";
2
+ import { transpileBytes } from "#jco-transpile";
3
+ const webAssembly = globalThis.WebAssembly;
4
+ class WasmPluginRuntime {
5
+ nextComponentId = 1;
6
+ components = new Map();
7
+ dispatch = async (request) => {
8
+ try {
9
+ switch (request.operation) {
10
+ case "initComponent":
11
+ return await this.initComponent(request);
12
+ case "detectChanges":
13
+ return this.detectChanges(request);
14
+ case "render":
15
+ return this.render(request);
16
+ case "closeComponent":
17
+ return this.closeComponent(request);
18
+ }
19
+ }
20
+ catch (cause) {
21
+ return {
22
+ errorMessage: `Lix plugin runtime ${request.operation} failed: ${errorMessage(cause)}`,
23
+ };
24
+ }
25
+ };
26
+ async initComponent(request) {
27
+ if (!request.componentBytes) {
28
+ throw new TypeError("initComponent requires componentBytes");
29
+ }
30
+ const componentId = this.nextComponentId;
31
+ this.nextComponentId += 1;
32
+ const name = "lix_plugin";
33
+ const transpiled = await transpileBytes(request.componentBytes, {
34
+ name,
35
+ emitTypescriptDeclarations: false,
36
+ instantiation: "async",
37
+ nodejsCompat: false,
38
+ });
39
+ const files = new Map(Object.entries(transpiled.files));
40
+ const moduleSource = requiredFile(files, `${name}.js`);
41
+ const moduleUrl = `data:text/javascript;base64,${bytesToBase64(moduleSource)}`;
42
+ const generatedModule = (await import(
43
+ /* @vite-ignore */ moduleUrl));
44
+ const wasi = new WASIShim({
45
+ sandbox: {
46
+ preopens: {},
47
+ env: {},
48
+ args: ["lix-plugin"],
49
+ enableNetwork: false,
50
+ },
51
+ });
52
+ const instance = await generatedModule.instantiate(async (path) => await webAssembly.compile(copyArrayBuffer(requiredFile(files, path))), wasi.getImportObject());
53
+ if (!instance.api) {
54
+ throw new Error("component does not export lix:plugin/api");
55
+ }
56
+ this.components.set(componentId, instance.api);
57
+ return { componentId };
58
+ }
59
+ detectChanges(request) {
60
+ const component = this.requiredComponent(request.componentId);
61
+ if (!request.file) {
62
+ throw new TypeError("detectChanges requires file");
63
+ }
64
+ return {
65
+ changes: component.detectChanges(request.state ?? [], request.file),
66
+ };
67
+ }
68
+ render(request) {
69
+ const component = this.requiredComponent(request.componentId);
70
+ return { bytes: component.render(request.state ?? []) };
71
+ }
72
+ closeComponent(request) {
73
+ if (request.componentId !== undefined) {
74
+ this.components.delete(request.componentId);
75
+ }
76
+ return {};
77
+ }
78
+ requiredComponent(componentId) {
79
+ if (componentId === undefined) {
80
+ throw new TypeError("plugin runtime operation requires componentId");
81
+ }
82
+ const component = this.components.get(componentId);
83
+ if (!component) {
84
+ throw new Error(`unknown plugin component ${componentId}`);
85
+ }
86
+ return component;
87
+ }
88
+ }
89
+ export function createPluginRuntimeDispatch() {
90
+ return new WasmPluginRuntime().dispatch;
91
+ }
92
+ function bytesToBase64(bytes) {
93
+ let binary = "";
94
+ const chunkSize = 0x8000;
95
+ for (let index = 0; index < bytes.length; index += chunkSize) {
96
+ binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
97
+ }
98
+ return btoa(binary);
99
+ }
100
+ function requiredFile(files, path) {
101
+ const file = files.get(path);
102
+ if (!file) {
103
+ throw new Error(`JCO output is missing ${path}`);
104
+ }
105
+ return file;
106
+ }
107
+ function copyArrayBuffer(bytes) {
108
+ const copy = new Uint8Array(bytes.byteLength);
109
+ copy.set(bytes);
110
+ return copy.buffer;
111
+ }
112
+ function errorMessage(cause) {
113
+ if (cause instanceof Error) {
114
+ return cause.message;
115
+ }
116
+ if (cause && typeof cause === "object") {
117
+ const tag = "tag" in cause ? String(cause.tag) : undefined;
118
+ const value = "val" in cause ? String(cause.val) : undefined;
119
+ if (tag || value) {
120
+ return [tag, value].filter(Boolean).join(": ");
121
+ }
122
+ }
123
+ return String(cause);
124
+ }
package/dist/types.d.ts CHANGED
@@ -3,6 +3,8 @@ export type SqliteBackendOptions = {
3
3
  };
4
4
  export type FsBackendOptions = {
5
5
  path: string;
6
+ lixDir?: string;
7
+ syncAllFiles: boolean;
6
8
  };
7
9
  export type OpenLixOptions = {
8
10
  backend?: import("./open-lix.js").SqliteBackend | import("./open-lix.js").FsBackend;
@@ -33,6 +35,9 @@ export type JsonValue = null | boolean | number | string | readonly JsonValue[]
33
35
  readonly [key: string]: JsonValue;
34
36
  };
35
37
  export type SqlParam = JsonValue | Uint8Array | import("./value.js").Value;
38
+ export type ExecuteOptions = {
39
+ originKey?: string;
40
+ };
36
41
  export type ExecuteResult = {
37
42
  columns: string[];
38
43
  rows: RowLike[];