@lix-js/sdk 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +82 -16
  2. package/dist/binding-types.d.ts +18 -2
  3. package/dist/binding.browser.d.ts +2 -2
  4. package/dist/binding.browser.js +3 -3
  5. package/dist/binding.node.d.ts +2 -2
  6. package/dist/binding.node.js +10 -4
  7. package/dist/bundled-plugins/plugin_csv_v2.lixplugin +0 -0
  8. package/dist/bundled-plugins/plugin_markdown_incremental_v2.lixplugin +0 -0
  9. package/dist/bundled-plugins.js +4 -4
  10. package/dist/client-state.d.ts +40 -0
  11. package/dist/client-state.js +178 -0
  12. package/dist/index.d.ts +2 -1
  13. package/dist/lix.d.ts +44 -0
  14. package/dist/lix.js +369 -0
  15. package/dist/local-storage-adapter.d.ts +26 -0
  16. package/dist/local-storage-adapter.js +117 -0
  17. package/dist/open-lix.d.ts +3 -34
  18. package/dist/open-lix.js +103 -170
  19. package/dist/remote/client.d.ts +8 -0
  20. package/dist/remote/client.js +1036 -0
  21. package/dist/remote/protocol.d.ts +166 -0
  22. package/dist/remote/protocol.js +362 -0
  23. package/dist/remote/sse.d.ts +12 -0
  24. package/dist/remote/sse.js +87 -0
  25. package/dist/snapshot-persistence.d.ts +7 -0
  26. package/dist/snapshot-persistence.js +26 -0
  27. package/dist/types.d.ts +58 -1
  28. package/dist/wasm/lix_js_sdk.d.ts +19 -4
  29. package/dist/wasm/lix_js_sdk.js +98 -17
  30. package/dist/wasm/lix_js_sdk_bg.wasm +0 -0
  31. package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +9 -2
  32. package/dist/worker/client.d.ts +23 -4
  33. package/dist/worker/client.js +287 -10
  34. package/dist/worker/host.js +30 -2
  35. package/dist/worker/protocol.d.ts +26 -2
  36. package/dist/workerd.d.ts +10 -0
  37. package/dist/workerd.js +7 -4
  38. package/package.json +19 -16
  39. package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
  40. package/dist/bundled-plugins/plugin_md_v2.lixplugin +0 -0
  41. package/dist/jco/js-component-bindgen-component.core.wasm +0 -0
  42. package/dist/jco/js-component-bindgen-component.core2.wasm +0 -0
  43. package/dist/jco/js-component-bindgen-component.js +0 -13662
  44. package/dist/jco-transpile.browser.d.ts +0 -14
  45. package/dist/jco-transpile.browser.js +0 -22
  46. package/dist/plugin-runtime.d.ts +0 -45
  47. package/dist/plugin-runtime.js +0 -124
@@ -1,9 +1,22 @@
1
1
  import { createWorkerConnection } from "#worker-factory";
2
+ import { snapshotPersistenceAfterCommitError } from "../snapshot-persistence.js";
2
3
  import { deserializeWorkerError, } from "./protocol.js";
3
- export async function openLixWorker(storage, onDisposed) {
4
- const client = new LixWorkerClient(onDisposed);
4
+ const MAX_IDLE_WORKERS = 1;
5
+ // The common serial reopen path retains one worker so its prepared plugin cache
6
+ // survives close(). Concurrent opens still receive isolated workers.
7
+ const idleWorkers = [];
8
+ export async function openLixWorker(storage, onDisposed, telemetry) {
9
+ let client = idleWorkers.pop();
10
+ while (client?.isDisposed)
11
+ client = idleWorkers.pop();
12
+ client ??= new LixWorkerClient();
13
+ client.beginLease(onDisposed, telemetry);
5
14
  try {
6
- await client.request({ kind: "open", storage });
15
+ await client.request({
16
+ kind: "open",
17
+ storage,
18
+ telemetryEnabled: telemetry !== undefined,
19
+ });
7
20
  return client;
8
21
  }
9
22
  catch (error) {
@@ -11,21 +24,276 @@ export async function openLixWorker(storage, onDisposed) {
11
24
  throw error;
12
25
  }
13
26
  }
27
+ /** Opens the local worker transport behind the semantic Lix binding. */
28
+ export async function openLixWorkerBinding(storage, onDisposed, telemetry) {
29
+ const client = await openLixWorker(storage, onDisposed, telemetry);
30
+ return workerBinding(client);
31
+ }
32
+ /**
33
+ * Opens a browser memory binding from an opaque snapshot and persists a fresh
34
+ * snapshot after every successful mutation. This is an internal composition
35
+ * seam for public storage adapters; it does not route workspace operations.
36
+ */
37
+ export async function openPersistentLixWorkerBinding(options) {
38
+ if (!options || typeof options !== "object") {
39
+ throw new TypeError("openPersistentLixWorkerBinding() options must be an object");
40
+ }
41
+ if (!options.storage ||
42
+ typeof options.storage.load !== "function" ||
43
+ typeof options.storage.save !== "function") {
44
+ throw new TypeError("openPersistentLixWorkerBinding() storage must implement load() and save()");
45
+ }
46
+ if (typeof options.namespace !== "string" || options.namespace.length === 0) {
47
+ throw new TypeError("openPersistentLixWorkerBinding() namespace must be a non-empty string");
48
+ }
49
+ const snapshot = await options.storage.load(options.namespace);
50
+ if (snapshot !== undefined && !(snapshot instanceof Uint8Array)) {
51
+ throw new TypeError("Snapshot storage load() must return a Uint8Array");
52
+ }
53
+ const binding = await openLixWorkerBinding({
54
+ kind: "memory",
55
+ ...(snapshot === undefined ? {} : { snapshot }),
56
+ }, undefined, options.telemetry);
57
+ const persistent = persistentSnapshotBinding(binding, options.storage, options.namespace);
58
+ if (snapshot === undefined) {
59
+ try {
60
+ await persistent.persist();
61
+ }
62
+ catch (error) {
63
+ await binding.close().catch(() => undefined);
64
+ throw error;
65
+ }
66
+ }
67
+ return persistent.binding;
68
+ }
69
+ function workerBinding(client) {
70
+ let closed = false;
71
+ const request = (operation) => {
72
+ if (closed)
73
+ return Promise.reject(workerClosedError());
74
+ return client.request(operation);
75
+ };
76
+ const notify = (notification) => {
77
+ if (!closed)
78
+ client.notify(notification);
79
+ };
80
+ return {
81
+ execute: (sql, params, options) => request({ kind: "execute", sql, params, options }),
82
+ executeBatch: (statements, options) => request({ kind: "executeBatch", statements, options }),
83
+ observe: async (sql, params) => {
84
+ const observeId = await request({
85
+ kind: "observe",
86
+ sql,
87
+ params,
88
+ });
89
+ return workerObserveBinding(request, notify, observeId);
90
+ },
91
+ beginTransaction: async () => {
92
+ const transactionId = await request({
93
+ kind: "beginTransaction",
94
+ });
95
+ return workerTransactionBinding(request, transactionId);
96
+ },
97
+ activeBranchId: () => request({ kind: "activeBranchId" }),
98
+ clientStateEntries: () => request({ kind: "clientState.entries" }),
99
+ clientStateGet: (key) => request({ kind: "clientState.get", key }),
100
+ clientStateSet: (key, value) => request({ kind: "clientState.set", key, value }),
101
+ clientStateDelete: (key) => request({ kind: "clientState.delete", key }),
102
+ createBranch: (options) => request({ kind: "createBranch", options }),
103
+ createCheckpoint: () => request({ kind: "createCheckpoint" }),
104
+ switchBranch: (options) => request({ kind: "switchBranch", options }),
105
+ importFilesystemPaths: (paths) => request({ kind: "importFilesystemPaths", paths }),
106
+ mergeBranchPreview: (options) => request({ kind: "mergeBranchPreview", options }),
107
+ mergeBranch: (options) => request({ kind: "mergeBranch", options }),
108
+ syncDiskToLix: () => request({ kind: "syncDiskToLix" }),
109
+ exportSnapshot: () => request({ kind: "exportSnapshot" }),
110
+ close: async () => {
111
+ if (closed)
112
+ return;
113
+ await request({ kind: "close" });
114
+ closed = true;
115
+ await releaseWorker(client);
116
+ },
117
+ };
118
+ }
119
+ function persistentSnapshotBinding(binding, storage, namespace) {
120
+ let persistenceTail = Promise.resolve();
121
+ let closePromise;
122
+ let bindingClosed = false;
123
+ const persist = () => {
124
+ const operation = persistenceTail.then(async () => {
125
+ const exportSnapshot = binding.exportSnapshot;
126
+ if (!exportSnapshot) {
127
+ throw new Error("The open Lix binding does not support snapshot export");
128
+ }
129
+ const snapshot = await exportSnapshot.call(binding);
130
+ await storage.save(namespace, snapshot);
131
+ });
132
+ persistenceTail = operation.catch(() => undefined);
133
+ return operation;
134
+ };
135
+ const afterMutation = async (operation) => {
136
+ const result = await operation;
137
+ try {
138
+ await persist();
139
+ }
140
+ catch (error) {
141
+ // The Rust transaction is already committed. Preserve that fact so
142
+ // synchronous facades can reflect the live session value while still
143
+ // reporting that durability failed.
144
+ throw snapshotPersistenceAfterCommitError(error);
145
+ }
146
+ return result;
147
+ };
148
+ const persistentBinding = {
149
+ execute: (sql, params, executeOptions) => afterMutation(binding.execute(sql, params, executeOptions)),
150
+ executeBatch: (statements, batchOptions) => afterMutation(binding.executeBatch(statements, batchOptions)),
151
+ observe: (sql, params) => binding.observe(sql, params),
152
+ beginTransaction: async () => {
153
+ const transaction = await binding.beginTransaction();
154
+ return {
155
+ execute: (sql, params, executeOptions) => transaction.execute(sql, params, executeOptions),
156
+ commit: () => afterMutation(transaction.commit()),
157
+ rollback: () => transaction.rollback(),
158
+ };
159
+ },
160
+ activeBranchId: () => binding.activeBranchId(),
161
+ clientStateEntries: () => {
162
+ const method = binding.clientStateEntries;
163
+ if (!method)
164
+ return Promise.reject(clientStateUnsupportedError());
165
+ return method.call(binding);
166
+ },
167
+ clientStateGet: (key) => {
168
+ const method = binding.clientStateGet;
169
+ if (!method)
170
+ return Promise.reject(clientStateUnsupportedError());
171
+ return method.call(binding, key);
172
+ },
173
+ clientStateSet: (key, value) => {
174
+ const method = binding.clientStateSet;
175
+ if (!method)
176
+ return Promise.reject(clientStateUnsupportedError());
177
+ return afterMutation(method.call(binding, key, value));
178
+ },
179
+ clientStateDelete: (key) => {
180
+ const method = binding.clientStateDelete;
181
+ if (!method)
182
+ return Promise.reject(clientStateUnsupportedError());
183
+ return afterMutation(method.call(binding, key));
184
+ },
185
+ createBranch: (branchOptions) => afterMutation(binding.createBranch(branchOptions)),
186
+ createCheckpoint: () => afterMutation(binding.createCheckpoint()),
187
+ switchBranch: (branchOptions) => afterMutation(binding.switchBranch(branchOptions)),
188
+ importFilesystemPaths: (paths) => afterMutation(binding.importFilesystemPaths(paths)),
189
+ mergeBranchPreview: (branchOptions) => binding.mergeBranchPreview(branchOptions),
190
+ mergeBranch: (branchOptions) => afterMutation(binding.mergeBranch(branchOptions)),
191
+ syncDiskToLix: () => afterMutation(binding.syncDiskToLix()),
192
+ exportSnapshot: () => {
193
+ const exportSnapshot = binding.exportSnapshot;
194
+ if (!exportSnapshot) {
195
+ return Promise.reject(new Error("The open Lix binding does not support snapshot export"));
196
+ }
197
+ return exportSnapshot.call(binding);
198
+ },
199
+ close: () => {
200
+ if (closePromise)
201
+ return closePromise;
202
+ closePromise = (async () => {
203
+ let persistenceError;
204
+ try {
205
+ await persist();
206
+ }
207
+ catch (error) {
208
+ persistenceError = error;
209
+ }
210
+ await binding.close();
211
+ bindingClosed = true;
212
+ if (persistenceError !== undefined)
213
+ throw persistenceError;
214
+ })();
215
+ void closePromise.catch((error) => {
216
+ if (!bindingClosed && isActiveTransactionCloseError(error)) {
217
+ closePromise = undefined;
218
+ }
219
+ });
220
+ return closePromise;
221
+ },
222
+ };
223
+ return { binding: persistentBinding, persist };
224
+ }
225
+ function isActiveTransactionCloseError(error) {
226
+ return (typeof error === "object" &&
227
+ error !== null &&
228
+ "code" in error &&
229
+ error.code === "LIX_INVALID_TRANSACTION_STATE");
230
+ }
231
+ function clientStateUnsupportedError() {
232
+ return new Error("The open Lix binding does not support typed client state");
233
+ }
234
+ function workerTransactionBinding(request, transactionId) {
235
+ return {
236
+ execute: (sql, params, options) => request({
237
+ kind: "transaction.execute",
238
+ transactionId,
239
+ sql,
240
+ params,
241
+ options,
242
+ }),
243
+ commit: () => request({ kind: "transaction.commit", transactionId }),
244
+ rollback: () => request({ kind: "transaction.rollback", transactionId }),
245
+ };
246
+ }
247
+ function workerObserveBinding(request, notify, observeId) {
248
+ return {
249
+ next: () => request({ kind: "observe.next", observeId }),
250
+ close: () => notify({ kind: "observe.close", observeId }),
251
+ };
252
+ }
253
+ async function releaseWorker(client) {
254
+ client.endLease();
255
+ if (!client.isDisposed && idleWorkers.length < MAX_IDLE_WORKERS) {
256
+ idleWorkers.push(client);
257
+ return;
258
+ }
259
+ await client.terminate();
260
+ }
14
261
  export class LixWorkerClient {
15
- onDisposed;
16
262
  connection;
17
263
  nextRequestId = 1;
18
264
  pending = new Map();
19
265
  disposed = false;
20
- constructor(onDisposed, connection = createWorkerConnection()) {
21
- this.onDisposed = onDisposed;
266
+ leased = false;
267
+ onDisposed;
268
+ telemetry;
269
+ constructor(connection = createWorkerConnection()) {
22
270
  this.connection = connection;
23
271
  connection.onMessage((message) => this.handleMessage(message));
24
272
  connection.onFatal((error) => this.handleFatal(error));
25
273
  }
274
+ get isDisposed() {
275
+ return this.disposed;
276
+ }
277
+ beginLease(onDisposed, telemetry) {
278
+ if (this.disposed || this.leased)
279
+ throw workerClosedError();
280
+ this.leased = true;
281
+ this.onDisposed = onDisposed;
282
+ this.telemetry = telemetry;
283
+ }
284
+ endLease() {
285
+ if (!this.leased)
286
+ return;
287
+ this.leased = false;
288
+ const onDisposed = this.onDisposed;
289
+ this.onDisposed = undefined;
290
+ this.telemetry = undefined;
291
+ onDisposed?.();
292
+ }
26
293
  request(operation) {
27
- if (this.disposed)
294
+ if (this.disposed || !this.leased) {
28
295
  return Promise.reject(workerClosedError());
296
+ }
29
297
  const id = this.nextRequestId++;
30
298
  if (this.pending.size === 0)
31
299
  this.connection.ref();
@@ -46,7 +314,7 @@ export class LixWorkerClient {
46
314
  });
47
315
  }
48
316
  notify(notification) {
49
- if (this.disposed)
317
+ if (this.disposed || !this.leased)
50
318
  return;
51
319
  try {
52
320
  this.connection.postMessage(notification);
@@ -64,10 +332,19 @@ export class LixWorkerClient {
64
332
  await this.connection.terminate();
65
333
  }
66
334
  finally {
67
- this.onDisposed?.();
335
+ this.endLease();
68
336
  }
69
337
  }
70
338
  handleMessage(message) {
339
+ if ("kind" in message) {
340
+ try {
341
+ this.telemetry?.onSpan(message.span);
342
+ }
343
+ catch {
344
+ // Telemetry callbacks are isolated from Lix operation results.
345
+ }
346
+ return;
347
+ }
71
348
  const pending = this.pending.get(message.id);
72
349
  if (!pending)
73
350
  return;
@@ -87,7 +364,7 @@ export class LixWorkerClient {
87
364
  fatal.name = "LixError";
88
365
  fatal.code ??= "LIX_WORKER_TERMINATED";
89
366
  this.rejectPending(fatal);
90
- this.onDisposed?.();
367
+ this.endLease();
91
368
  }
92
369
  rejectPending(error) {
93
370
  for (const pending of this.pending.values())
@@ -1,5 +1,4 @@
1
1
  import { openLixBinding } from "#binding";
2
- import { createPluginRuntimeDispatch } from "../plugin-runtime.js";
3
2
  import { serializeWorkerError, } from "./protocol.js";
4
3
  export function startWorkerHost(endpoint) {
5
4
  let lix;
@@ -58,10 +57,14 @@ export function startWorkerHost(endpoint) {
58
57
  case "open":
59
58
  if (lix)
60
59
  throw workerStateError("Lix worker is already open");
61
- lix = await openLixBinding(operation.storage, createPluginRuntimeDispatch());
60
+ lix = await openLixBinding(operation.storage, operation.telemetryEnabled
61
+ ? (span) => endpoint.postMessage({ kind: "telemetry", span })
62
+ : undefined);
62
63
  return undefined;
63
64
  case "execute":
64
65
  return requiredLix().execute(operation.sql, operation.params, operation.options);
66
+ case "executeBatch":
67
+ return requiredLix().executeBatch(operation.statements, operation.options);
65
68
  case "beginTransaction": {
66
69
  const transaction = await requiredLix().beginTransaction();
67
70
  const transactionId = nextTransactionId++;
@@ -84,8 +87,18 @@ export function startWorkerHost(endpoint) {
84
87
  }
85
88
  case "activeBranchId":
86
89
  return requiredLix().activeBranchId();
90
+ case "clientState.entries":
91
+ return requiredClientStateMethod("clientStateEntries")();
92
+ case "clientState.get":
93
+ return requiredClientStateMethod("clientStateGet")(operation.key);
94
+ case "clientState.set":
95
+ return requiredClientStateMethod("clientStateSet")(operation.key, operation.value);
96
+ case "clientState.delete":
97
+ return requiredClientStateMethod("clientStateDelete")(operation.key);
87
98
  case "createBranch":
88
99
  return requiredLix().createBranch(operation.options);
100
+ case "createCheckpoint":
101
+ return requiredLix().createCheckpoint();
89
102
  case "switchBranch":
90
103
  return requiredLix().switchBranch(operation.options);
91
104
  case "mergeBranchPreview":
@@ -96,6 +109,14 @@ export function startWorkerHost(endpoint) {
96
109
  return requiredLix().importFilesystemPaths(operation.paths);
97
110
  case "syncDiskToLix":
98
111
  return requiredLix().syncDiskToLix();
112
+ case "exportSnapshot": {
113
+ const lix = requiredLix();
114
+ const exportSnapshot = lix.exportSnapshot;
115
+ if (!exportSnapshot) {
116
+ throw workerStateError("The open Lix storage does not support snapshot export");
117
+ }
118
+ return exportSnapshot.call(lix);
119
+ }
99
120
  case "observe": {
100
121
  const events = await requiredLix().observe(operation.sql, operation.params);
101
122
  const observeId = nextObserveId++;
@@ -127,6 +148,13 @@ export function startWorkerHost(endpoint) {
127
148
  throw workerStateError("Lix worker is closed");
128
149
  return lix;
129
150
  }
151
+ function requiredClientStateMethod(key) {
152
+ const method = requiredLix()[key];
153
+ if (!method) {
154
+ throw workerStateError("The open Lix binding does not support typed client state");
155
+ }
156
+ return method.bind(requiredLix());
157
+ }
130
158
  function requiredTransaction(transactionId) {
131
159
  const transaction = transactions.get(transactionId);
132
160
  if (!transaction) {
@@ -1,5 +1,5 @@
1
- import type { BindingParam, LixStorageConfig } from "../binding-types.js";
2
- import type { CreateBranchOptions, ExecuteOptions, MergeBranchOptions, SwitchBranchOptions } from "../types.js";
1
+ import type { BindingBatchStatement, BindingParam, LixStorageConfig } from "../binding-types.js";
2
+ import type { CreateBranchOptions, ExecuteOptions, JsonValue, LixBatchOptions, MergeBranchOptions, SwitchBranchOptions, LixTelemetrySpan } from "../types.js";
3
3
  export type WorkerRequest = {
4
4
  id: number;
5
5
  operation: WorkerOperation;
@@ -7,11 +7,16 @@ export type WorkerRequest = {
7
7
  export type WorkerOperation = {
8
8
  kind: "open";
9
9
  storage: LixStorageConfig;
10
+ telemetryEnabled: boolean;
10
11
  } | {
11
12
  kind: "execute";
12
13
  sql: string;
13
14
  params: BindingParam[];
14
15
  options?: ExecuteOptions;
16
+ } | {
17
+ kind: "executeBatch";
18
+ statements: BindingBatchStatement[];
19
+ options?: LixBatchOptions;
15
20
  } | {
16
21
  kind: "beginTransaction";
17
22
  } | {
@@ -28,9 +33,23 @@ export type WorkerOperation = {
28
33
  transactionId: number;
29
34
  } | {
30
35
  kind: "activeBranchId";
36
+ } | {
37
+ kind: "clientState.entries";
38
+ } | {
39
+ kind: "clientState.get";
40
+ key: string;
41
+ } | {
42
+ kind: "clientState.set";
43
+ key: string;
44
+ value: JsonValue;
45
+ } | {
46
+ kind: "clientState.delete";
47
+ key: string;
31
48
  } | {
32
49
  kind: "createBranch";
33
50
  options: CreateBranchOptions;
51
+ } | {
52
+ kind: "createCheckpoint";
34
53
  } | {
35
54
  kind: "switchBranch";
36
55
  options: SwitchBranchOptions;
@@ -45,6 +64,8 @@ export type WorkerOperation = {
45
64
  paths: string[];
46
65
  } | {
47
66
  kind: "syncDiskToLix";
67
+ } | {
68
+ kind: "exportSnapshot";
48
69
  } | {
49
70
  kind: "observe";
50
71
  sql: string;
@@ -91,6 +112,9 @@ export type WorkerResponse = {
91
112
  id: number;
92
113
  ok: false;
93
114
  error: SerializedWorkerError;
115
+ } | {
116
+ kind: "telemetry";
117
+ span: LixTelemetrySpan;
94
118
  };
95
119
  export declare function serializeWorkerError(error: unknown): SerializedWorkerError;
96
120
  export declare function deserializeWorkerError(error: SerializedWorkerError): Error;
package/dist/workerd.d.ts CHANGED
@@ -1,10 +1,20 @@
1
1
  import type { LixBinding } from "./binding-types.js";
2
+ export type SqlScriptPlan = {
3
+ statements: SqlScriptStatement[];
4
+ };
5
+ export type SqlScriptStatement = {
6
+ sql: string;
7
+ paramStart: number;
8
+ paramEnd: number;
9
+ };
2
10
  export interface OpenMemoryLixOptions {
3
11
  snapshot?: Uint8Array;
4
12
  }
5
13
  export interface WorkerdLixBinding extends LixBinding {
6
14
  exportSnapshot(): Promise<Uint8Array>;
7
15
  }
16
+ /** Parses SQL using the same DataFusion dialect and transaction policy as Lix. */
17
+ export declare function parseSqlScript(sql: string, providedParamCount: number): SqlScriptPlan;
8
18
  /**
9
19
  * Opens an in-memory Lix binding directly in a Cloudflare Worker isolate.
10
20
  *
package/dist/workerd.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // @ts-expect-error Generated by build:wasm.
3
3
  import wasmModule from "./wasm/lix_js_sdk_bg.wasm";
4
4
  // @ts-expect-error Generated by build:wasm.
5
- import { initSync, openMemoryFromSnapshot } from "./wasm/lix_js_sdk.js";
5
+ import { initSync, openMemoryFromSnapshot, parseSqlScript as parseSqlScriptBinding } from "./wasm/lix_js_sdk.js";
6
6
  let initialized = false;
7
7
  function initializeWasm() {
8
8
  if (initialized)
@@ -10,6 +10,11 @@ function initializeWasm() {
10
10
  initSync({ module: wasmModule });
11
11
  initialized = true;
12
12
  }
13
+ /** Parses SQL using the same DataFusion dialect and transaction policy as Lix. */
14
+ export function parseSqlScript(sql, providedParamCount) {
15
+ initializeWasm();
16
+ return parseSqlScriptBinding(sql, providedParamCount);
17
+ }
13
18
  /**
14
19
  * Opens an in-memory Lix binding directly in a Cloudflare Worker isolate.
15
20
  *
@@ -26,7 +31,5 @@ export async function openMemoryLix(options = {}) {
26
31
  throw new TypeError("openMemoryLix() snapshot must be a Uint8Array");
27
32
  }
28
33
  initializeWasm();
29
- return openMemoryFromSnapshot(async () => {
30
- throw new Error("Lix plugin execution is unavailable in Workerd");
31
- }, options.snapshot);
34
+ return openMemoryFromSnapshot(undefined, options.snapshot);
32
35
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lix-js/sdk",
3
3
  "type": "module",
4
- "version": "0.8.3",
4
+ "version": "0.9.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,6 +16,14 @@
16
16
  "types": "./dist/workerd.d.ts",
17
17
  "workerd": "./dist/workerd.js",
18
18
  "default": "./dist/workerd.js"
19
+ },
20
+ "./remote-protocol": {
21
+ "types": "./dist/remote/protocol.d.ts",
22
+ "default": "./dist/remote/protocol.js"
23
+ },
24
+ "./local-storage-adapter": {
25
+ "types": "./dist/local-storage-adapter.d.ts",
26
+ "default": "./dist/local-storage-adapter.js"
19
27
  }
20
28
  },
21
29
  "imports": {
@@ -23,10 +31,6 @@
23
31
  "node": "./dist/binding.node.js",
24
32
  "default": "./dist/binding.browser.js"
25
33
  },
26
- "#jco-transpile": {
27
- "node": "@bytecodealliance/jco-transpile",
28
- "default": "./dist/jco-transpile.browser.js"
29
- },
30
34
  "#worker-factory": {
31
35
  "node": "./dist/worker/factory.node.js",
32
36
  "default": "./dist/worker/factory.browser.js"
@@ -36,13 +40,13 @@
36
40
  "dist"
37
41
  ],
38
42
  "scripts": {
39
- "build": "npm run clean && npm run build:native && npm run build:wasm && npm run build:ts && npm run build:jco-browser && npm run build:plugins",
40
- "build:browser": "npm run clean && npm run build:wasm && npm run build:ts && npm run build:jco-browser && npm run build:plugins",
41
- "build:jco-browser": "node ./scripts/build-jco-browser.js",
43
+ "build": "npm run clean && npm run build:native && npm run build:wasm && npm run build:ts && npm run build:plugins",
44
+ "build:browser": "npm run clean && npm run build:wasm && npm run build:ts && npm run build:plugins",
42
45
  "build:native": "node ./scripts/build-native.js",
43
46
  "build:wasm": "node ./scripts/build-wasm.js",
44
47
  "build:wasm:dev": "LIX_WASM_PROFILE=dev node ./scripts/build-wasm.js",
45
48
  "build:plugins": "node ./scripts/build-bundled-plugins.js",
49
+ "benchmark:plugin-reopen": "node ./scripts/benchmark-plugin-reopen.mjs",
46
50
  "clean": "node ./scripts/clean.js",
47
51
  "prepare:native-package": "node ./scripts/prepare-native-package.js",
48
52
  "build:ts": "tsc -p tsconfig.json",
@@ -53,21 +57,20 @@
53
57
  "typecheck": "tsc -p tsconfig.test.json --noEmit"
54
58
  },
55
59
  "optionalDependencies": {
56
- "@lix-js/sdk-darwin-arm64": "0.8.3",
57
- "@lix-js/sdk-linux-arm64": "0.8.3",
58
- "@lix-js/sdk-linux-x64": "0.8.3",
59
- "@lix-js/sdk-win32-x64": "0.8.3"
60
+ "@lix-js/sdk-darwin-arm64": "0.9.0",
61
+ "@lix-js/sdk-linux-arm64": "0.9.0",
62
+ "@lix-js/sdk-linux-x64": "0.9.0",
63
+ "@lix-js/sdk-win32-x64": "0.9.0"
60
64
  },
61
65
  "devDependencies": {
62
- "@vitest/browser-playwright": "4.0.18",
66
+ "@vitest/browser-playwright": "4.1.10",
63
67
  "@types/node": "^24.10.2",
64
68
  "playwright": "1.57.0",
65
69
  "typescript": "^5.5.4",
66
- "vitest": "^4.0.18"
70
+ "vite": "8.1.4",
71
+ "vitest": "4.1.10"
67
72
  },
68
73
  "dependencies": {
69
- "@bytecodealliance/jco-transpile": "0.4.2",
70
- "@bytecodealliance/preview2-shim": "0.19.0",
71
74
  "fflate": "^0.8.3"
72
75
  }
73
76
  }