@lix-js/sdk 0.8.4 → 0.10.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 +105 -22
- package/dist/binding-types.d.ts +21 -2
- package/dist/binding.browser.d.ts +2 -2
- package/dist/binding.browser.js +3 -3
- package/dist/binding.node.d.ts +2 -2
- package/dist/binding.node.js +18 -4
- package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
- package/dist/bundled-plugins/plugin_markdown.lixplugin +0 -0
- package/dist/bundled-plugins.js +2 -2
- package/dist/client-state.d.ts +53 -0
- package/dist/client-state.js +318 -0
- package/dist/index.d.ts +2 -1
- package/dist/lix.d.ts +47 -0
- package/dist/lix.js +378 -0
- package/dist/local-storage-adapter.d.ts +26 -0
- package/dist/local-storage-adapter.js +117 -0
- package/dist/open-lix.d.ts +3 -34
- package/dist/open-lix.js +99 -170
- package/dist/remote/client.d.ts +9 -0
- package/dist/remote/client.js +1150 -0
- package/dist/remote/protocol.d.ts +178 -0
- package/dist/remote/protocol.js +367 -0
- package/dist/remote/sse.d.ts +12 -0
- package/dist/remote/sse.js +87 -0
- package/dist/snapshot-persistence.d.ts +7 -0
- package/dist/snapshot-persistence.js +26 -0
- package/dist/types.d.ts +68 -1
- package/dist/wasm/lix_js_sdk.d.ts +22 -4
- package/dist/wasm/lix_js_sdk.js +96 -17
- package/dist/wasm/lix_js_sdk_bg.wasm +0 -0
- package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +11 -2
- package/dist/worker/client.d.ts +23 -4
- package/dist/worker/client.js +329 -11
- package/dist/worker/factory.browser.d.ts +2 -0
- package/dist/worker/factory.browser.js +2 -0
- package/dist/worker/factory.node.d.ts +2 -0
- package/dist/worker/factory.node.js +5 -0
- package/dist/worker/host.js +36 -2
- package/dist/worker/protocol.d.ts +32 -2
- package/dist/workerd.js +1 -3
- package/package.json +19 -16
- package/dist/bundled-plugins/plugin_md_v2.lixplugin +0 -0
- package/dist/jco/js-component-bindgen-component.core.wasm +0 -0
- package/dist/jco/js-component-bindgen-component.core2.wasm +0 -0
- package/dist/jco/js-component-bindgen-component.js +0 -13662
- package/dist/jco-transpile.browser.d.ts +0 -14
- package/dist/jco-transpile.browser.js +0 -22
- package/dist/plugin-runtime.d.ts +0 -45
- package/dist/plugin-runtime.js +0 -124
package/dist/open-lix.js
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import { localFilesystemAlreadyOpen, localFilesystemNotOpen,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
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
|
-
});
|
|
1
|
+
import { localFilesystemAlreadyOpen, localFilesystemNotOpen, } from "./errors.js";
|
|
2
|
+
import { ACTIVE_ACCOUNT_CLIENT_STATE_KEY, ACTIVE_BRANCH_CLIENT_STATE_KEY, openClientState, openStoredClientState, } from "./client-state.js";
|
|
3
|
+
import { Lix } from "./lix.js";
|
|
4
|
+
export { Lix, LixTransaction, ObserveEvents } from "./lix.js";
|
|
14
5
|
export class SQLite {
|
|
15
6
|
path;
|
|
16
7
|
constructor(options) {
|
|
@@ -53,16 +44,13 @@ export class LocalFilesystem {
|
|
|
53
44
|
throw new TypeError("importPaths() paths must contain non-empty strings");
|
|
54
45
|
}
|
|
55
46
|
if (path.endsWith("/")) {
|
|
56
|
-
throw new TypeError("importPaths() paths must
|
|
47
|
+
throw new TypeError("importPaths() paths must not end with a trailing slash");
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
await this.client("importPaths").
|
|
60
|
-
kind: "importFilesystemPaths",
|
|
61
|
-
paths: [...paths],
|
|
62
|
-
});
|
|
50
|
+
await this.client("importPaths").importFilesystemPaths([...paths]);
|
|
63
51
|
}
|
|
64
52
|
async syncDiskToLix() {
|
|
65
|
-
return this.client("syncDiskToLix").
|
|
53
|
+
return this.client("syncDiskToLix").syncDiskToLix();
|
|
66
54
|
}
|
|
67
55
|
client(operation) {
|
|
68
56
|
const client = openLocalFilesystems.get(this);
|
|
@@ -79,11 +67,63 @@ export async function openLix(options = {}) {
|
|
|
79
67
|
if ("backend" in options) {
|
|
80
68
|
throw new TypeError("openLix() option 'backend' was removed; use 'storage' instead");
|
|
81
69
|
}
|
|
70
|
+
if (options.telemetry !== undefined &&
|
|
71
|
+
(typeof options.telemetry !== "object" ||
|
|
72
|
+
typeof options.telemetry.onSpan !== "function")) {
|
|
73
|
+
throw new TypeError("openLix() telemetry requires an onSpan callback");
|
|
74
|
+
}
|
|
75
|
+
if (options.server !== undefined) {
|
|
76
|
+
const { openRemoteLixBinding } = await import("./remote/client.js");
|
|
77
|
+
if (options.storage === undefined) {
|
|
78
|
+
return new Lix(await openRemoteLixBinding(options.server));
|
|
79
|
+
}
|
|
80
|
+
assertSnapshotStorage(options.storage);
|
|
81
|
+
const clientState = await openStoredClientState({
|
|
82
|
+
storage: options.storage,
|
|
83
|
+
namespace: remoteClientStateNamespace(options.server.url),
|
|
84
|
+
});
|
|
85
|
+
const restoredBranchId = clientState.get(ACTIVE_BRANCH_CLIENT_STATE_KEY);
|
|
86
|
+
const restoredAccountId = clientState.get(ACTIVE_ACCOUNT_CLIENT_STATE_KEY);
|
|
87
|
+
let remoteBinding;
|
|
88
|
+
try {
|
|
89
|
+
try {
|
|
90
|
+
remoteBinding = await openRemoteLixBinding(options.server, {
|
|
91
|
+
initialActiveBranchId: restoredBranchId,
|
|
92
|
+
initialActiveAccountId: restoredAccountId,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (!restoredBranchId || !isBranchNotFoundError(error))
|
|
97
|
+
throw error;
|
|
98
|
+
remoteBinding = await openRemoteLixBinding(options.server, {
|
|
99
|
+
initialActiveAccountId: restoredAccountId,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const activeBranchId = await remoteBinding.activeBranchId();
|
|
103
|
+
const activeAccountId = await remoteBinding.activeAccountId();
|
|
104
|
+
if (activeBranchId !== restoredBranchId) {
|
|
105
|
+
await clientState.set(ACTIVE_BRANCH_CLIENT_STATE_KEY, activeBranchId);
|
|
106
|
+
}
|
|
107
|
+
if (activeAccountId !== restoredAccountId) {
|
|
108
|
+
await clientState.set(ACTIVE_ACCOUNT_CLIENT_STATE_KEY, activeAccountId);
|
|
109
|
+
}
|
|
110
|
+
return new Lix(remoteBinding, clientState);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
await remoteBinding?.close().catch(() => undefined);
|
|
114
|
+
await clientState.close().catch(() => undefined);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const { openLixWorkerBinding } = await import("./worker/client.js");
|
|
82
119
|
if (options.storage === undefined) {
|
|
83
|
-
return new Lix(await
|
|
120
|
+
return new Lix(await openLixWorkerBinding({ kind: "memory" }, undefined, options.telemetry));
|
|
84
121
|
}
|
|
85
122
|
if (options.storage instanceof SQLite) {
|
|
86
|
-
return new Lix(await
|
|
123
|
+
return new Lix(await openLixWorkerBinding({
|
|
124
|
+
kind: "sqlite",
|
|
125
|
+
path: options.storage.path,
|
|
126
|
+
}, undefined, options.telemetry));
|
|
87
127
|
}
|
|
88
128
|
if (options.storage instanceof LocalFilesystem) {
|
|
89
129
|
const storage = options.storage;
|
|
@@ -92,175 +132,64 @@ export async function openLix(options = {}) {
|
|
|
92
132
|
}
|
|
93
133
|
openLocalFilesystems.set(storage, null);
|
|
94
134
|
try {
|
|
95
|
-
const
|
|
135
|
+
const binding = await openLixWorkerBinding({
|
|
96
136
|
kind: "localFilesystem",
|
|
97
137
|
path: storage.path,
|
|
98
138
|
lixDir: storage.lixDir,
|
|
99
139
|
syncAllFiles: storage.syncAllFiles,
|
|
100
|
-
}, () => openLocalFilesystems.delete(storage));
|
|
101
|
-
openLocalFilesystems.set(storage,
|
|
102
|
-
return new Lix(
|
|
140
|
+
}, () => openLocalFilesystems.delete(storage), options.telemetry);
|
|
141
|
+
openLocalFilesystems.set(storage, binding);
|
|
142
|
+
return new Lix(binding);
|
|
103
143
|
}
|
|
104
144
|
catch (error) {
|
|
105
145
|
openLocalFilesystems.delete(storage);
|
|
106
146
|
throw error;
|
|
107
147
|
}
|
|
108
148
|
}
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
this.client = client;
|
|
116
|
-
}
|
|
117
|
-
async execute(sql, params = [], options) {
|
|
118
|
-
assertExecuteArgs("lix", sql, params, options);
|
|
119
|
-
return wrapExecuteResult(await this.client.request({
|
|
120
|
-
kind: "execute",
|
|
121
|
-
sql,
|
|
122
|
-
params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
|
|
123
|
-
options,
|
|
124
|
-
}));
|
|
125
|
-
}
|
|
126
|
-
observe(sql, params = []) {
|
|
127
|
-
assertSqlArgs("observe", "lix", sql, params);
|
|
128
|
-
return new ObserveEvents(this.client, this.client.request({
|
|
129
|
-
kind: "observe",
|
|
130
|
-
sql,
|
|
131
|
-
params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
|
|
132
|
-
}));
|
|
133
|
-
}
|
|
134
|
-
async beginTransaction() {
|
|
135
|
-
const transactionId = await this.client.request({
|
|
136
|
-
kind: "beginTransaction",
|
|
149
|
+
if (isSnapshotStorage(options.storage)) {
|
|
150
|
+
const { openPersistentLixWorkerBinding } = await import("./worker/client.js");
|
|
151
|
+
const binding = await openPersistentLixWorkerBinding({
|
|
152
|
+
storage: options.storage,
|
|
153
|
+
namespace: "local",
|
|
154
|
+
telemetry: options.telemetry,
|
|
137
155
|
});
|
|
138
|
-
return new LixTransaction(this.client, transactionId);
|
|
139
|
-
}
|
|
140
|
-
async activeBranchId() {
|
|
141
|
-
return this.client.request({ kind: "activeBranchId" });
|
|
142
|
-
}
|
|
143
|
-
async createBranch(options) {
|
|
144
|
-
return this.client.request({ kind: "createBranch", options });
|
|
145
|
-
}
|
|
146
|
-
async switchBranch(options) {
|
|
147
|
-
return this.client.request({ kind: "switchBranch", options });
|
|
148
|
-
}
|
|
149
|
-
async mergeBranchPreview(options) {
|
|
150
|
-
return normalizeOptionals(await this.client.request({ kind: "mergeBranchPreview", options }));
|
|
151
|
-
}
|
|
152
|
-
async mergeBranch(options) {
|
|
153
|
-
const receipt = normalizeOptionals(await this.client.request({ kind: "mergeBranch", options }));
|
|
154
|
-
receipt.createdMergeCommitId ??= null;
|
|
155
|
-
return receipt;
|
|
156
|
-
}
|
|
157
|
-
async close() {
|
|
158
|
-
this.closePromise ??= (async () => {
|
|
159
|
-
await this.client.request({ kind: "close" });
|
|
160
|
-
await this.client.terminate();
|
|
161
|
-
})();
|
|
162
156
|
try {
|
|
163
|
-
await
|
|
157
|
+
const clientState = await openClientState({ binding });
|
|
158
|
+
return new Lix(binding, clientState);
|
|
164
159
|
}
|
|
165
160
|
catch (error) {
|
|
166
|
-
|
|
161
|
+
await binding.close().catch(() => undefined);
|
|
167
162
|
throw error;
|
|
168
163
|
}
|
|
169
164
|
}
|
|
165
|
+
throw new TypeError("openLix() requires storage to be SQLite, LocalFilesystem, or a Lix snapshot storage adapter");
|
|
170
166
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
constructor(client, observeId) {
|
|
177
|
-
this.client = client;
|
|
178
|
-
const setup = this.setup;
|
|
179
|
-
this.observeId = observeId.catch((error) => {
|
|
180
|
-
setup.error = error;
|
|
181
|
-
return undefined;
|
|
182
|
-
});
|
|
183
|
-
observeFinalizer.register(this, { client, observeId: this.observeId }, this);
|
|
184
|
-
}
|
|
185
|
-
async next() {
|
|
186
|
-
if (this.closed)
|
|
187
|
-
return undefined;
|
|
188
|
-
const observeId = await this.observeId;
|
|
189
|
-
if (observeId === undefined) {
|
|
190
|
-
throw this.setup.error;
|
|
191
|
-
}
|
|
192
|
-
const event = await this.client.request({
|
|
193
|
-
kind: "observe.next",
|
|
194
|
-
observeId,
|
|
195
|
-
});
|
|
196
|
-
if (event == null) {
|
|
197
|
-
return undefined;
|
|
198
|
-
}
|
|
199
|
-
return {
|
|
200
|
-
sequence: event.sequence,
|
|
201
|
-
mutationSequence: event.mutationSequence,
|
|
202
|
-
result: wrapExecuteResult(event.rows),
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
close() {
|
|
206
|
-
if (this.closed)
|
|
207
|
-
return;
|
|
208
|
-
this.closed = true;
|
|
209
|
-
observeFinalizer.unregister(this);
|
|
210
|
-
void this.observeId.then((observeId) => {
|
|
211
|
-
if (observeId !== undefined) {
|
|
212
|
-
this.client.notify({ kind: "observe.close", observeId });
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
167
|
+
function isSnapshotStorage(value) {
|
|
168
|
+
return (typeof value === "object" &&
|
|
169
|
+
value !== null &&
|
|
170
|
+
typeof value.load === "function" &&
|
|
171
|
+
typeof value.save === "function");
|
|
216
172
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
constructor(client, transactionId) {
|
|
221
|
-
this.client = client;
|
|
222
|
-
this.transactionId = transactionId;
|
|
223
|
-
transactionFinalizer.register(this, { client, transactionId }, this);
|
|
224
|
-
}
|
|
225
|
-
async execute(sql, params = [], options) {
|
|
226
|
-
assertExecuteArgs("lixTransaction", sql, params, options);
|
|
227
|
-
return wrapExecuteResult(await this.client.request({
|
|
228
|
-
kind: "transaction.execute",
|
|
229
|
-
transactionId: this.transactionId,
|
|
230
|
-
sql,
|
|
231
|
-
params: params.map((param, index) => toNativeValue(normalizeParam(param, index))),
|
|
232
|
-
options,
|
|
233
|
-
}));
|
|
234
|
-
}
|
|
235
|
-
async commit() {
|
|
236
|
-
return this.finish("transaction.commit");
|
|
237
|
-
}
|
|
238
|
-
async rollback() {
|
|
239
|
-
return this.finish("transaction.rollback");
|
|
240
|
-
}
|
|
241
|
-
async finish(kind) {
|
|
242
|
-
transactionFinalizer.unregister(this);
|
|
243
|
-
return this.client.request({ kind, transactionId: this.transactionId });
|
|
173
|
+
function assertSnapshotStorage(value) {
|
|
174
|
+
if (!isSnapshotStorage(value)) {
|
|
175
|
+
throw new TypeError("openLix() remote storage must implement load() and save()");
|
|
244
176
|
}
|
|
245
177
|
}
|
|
246
|
-
function
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
throw
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
178
|
+
function remoteClientStateNamespace(value) {
|
|
179
|
+
let url;
|
|
180
|
+
try {
|
|
181
|
+
url = new URL(value);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
throw new TypeError("openLix() remote server url must be an absolute URL");
|
|
185
|
+
}
|
|
186
|
+
url.pathname = url.pathname.replace(/\/$/, "");
|
|
187
|
+
url.search = "";
|
|
188
|
+
url.hash = "";
|
|
189
|
+
return `remote:${url.href}`;
|
|
258
190
|
}
|
|
259
|
-
function
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (!Array.isArray(params)) {
|
|
264
|
-
throw invalidArgument(operation, "params", "array", typeof params, receiver);
|
|
265
|
-
}
|
|
191
|
+
function isBranchNotFoundError(error) {
|
|
192
|
+
return (error instanceof Error &&
|
|
193
|
+
"code" in error &&
|
|
194
|
+
error.code === "LIX_BRANCH_NOT_FOUND");
|
|
266
195
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LixBinding } from "../binding-types.js";
|
|
2
|
+
import type { RemoteLixServerOptions } from "../types.js";
|
|
3
|
+
import { type RemoteHandshakeRequest } from "./protocol.js";
|
|
4
|
+
type RemoteLixClientOptions = {
|
|
5
|
+
initialActiveBranchId?: RemoteHandshakeRequest["activeBranchId"];
|
|
6
|
+
initialActiveAccountId?: RemoteHandshakeRequest["activeAccountId"];
|
|
7
|
+
};
|
|
8
|
+
export declare function openRemoteLixBinding(options: RemoteLixServerOptions, clientOptions?: RemoteLixClientOptions): Promise<LixBinding>;
|
|
9
|
+
export {};
|