@lix-js/sdk 0.6.0-preview.0 → 0.6.0-preview.2
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 +9 -0
- package/SKILL.md +468 -0
- package/dist/engine-wasm/index.d.ts +15 -11
- package/dist/engine-wasm/index.js +105 -38
- package/dist/engine-wasm/wasm/lix_engine.d.ts +14 -2
- package/dist/engine-wasm/wasm/lix_engine.js +18 -17
- package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
- package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +2 -1
- package/dist/generated/builtin-schemas.d.ts +31 -41
- package/dist/generated/builtin-schemas.js +52 -56
- package/dist/open-lix.d.ts +141 -24
- package/dist/open-lix.js +199 -35
- package/dist/sqlite/index.js +99 -22
- package/dist-engine-src/README.md +18 -0
- package/dist-engine-src/src/backend/kv.rs +358 -0
- package/dist-engine-src/src/backend/mod.rs +12 -0
- package/dist-engine-src/src/backend/testing.rs +658 -0
- package/dist-engine-src/src/backend/types.rs +96 -0
- package/dist-engine-src/src/binary_cas/chunking.rs +31 -0
- package/dist-engine-src/src/binary_cas/codec.rs +346 -0
- package/dist-engine-src/src/binary_cas/context.rs +139 -0
- package/dist-engine-src/src/binary_cas/kv.rs +1063 -0
- package/dist-engine-src/src/binary_cas/mod.rs +11 -0
- package/dist-engine-src/src/binary_cas/types.rs +127 -0
- package/dist-engine-src/src/cel/context.rs +86 -0
- package/dist-engine-src/src/cel/error.rs +19 -0
- package/dist-engine-src/src/cel/mod.rs +8 -0
- package/dist-engine-src/src/cel/provider.rs +9 -0
- package/dist-engine-src/src/cel/runtime.rs +167 -0
- package/dist-engine-src/src/cel/value.rs +50 -0
- package/dist-engine-src/src/changelog/codec.rs +321 -0
- package/dist-engine-src/src/changelog/context.rs +92 -0
- package/dist-engine-src/src/changelog/materialization.rs +121 -0
- package/dist-engine-src/src/changelog/mod.rs +13 -0
- package/dist-engine-src/src/changelog/reader.rs +20 -0
- package/dist-engine-src/src/changelog/storage.rs +220 -0
- package/dist-engine-src/src/changelog/types.rs +38 -0
- package/dist-engine-src/src/commit_graph/context.rs +1588 -0
- package/dist-engine-src/src/commit_graph/mod.rs +12 -0
- package/dist-engine-src/src/commit_graph/types.rs +145 -0
- package/dist-engine-src/src/commit_graph/walker.rs +780 -0
- package/dist-engine-src/src/common/error.rs +313 -0
- package/dist-engine-src/src/common/fingerprint.rs +3 -0
- package/dist-engine-src/src/common/fs_path.rs +1336 -0
- package/dist-engine-src/src/common/identity.rs +135 -0
- package/dist-engine-src/src/common/metadata.rs +35 -0
- package/dist-engine-src/src/common/mod.rs +23 -0
- package/dist-engine-src/src/common/types.rs +105 -0
- package/dist-engine-src/src/common/wire.rs +222 -0
- package/dist-engine-src/src/engine.rs +239 -0
- package/dist-engine-src/src/entity_identity.rs +285 -0
- package/dist-engine-src/src/functions/context.rs +327 -0
- package/dist-engine-src/src/functions/deterministic.rs +113 -0
- package/dist-engine-src/src/functions/mod.rs +18 -0
- package/dist-engine-src/src/functions/provider.rs +130 -0
- package/dist-engine-src/src/functions/state.rs +363 -0
- package/dist-engine-src/src/functions/types.rs +37 -0
- package/dist-engine-src/src/init.rs +505 -0
- package/dist-engine-src/src/json_store/compression.rs +77 -0
- package/dist-engine-src/src/json_store/context.rs +129 -0
- package/dist-engine-src/src/json_store/encoded.rs +15 -0
- package/dist-engine-src/src/json_store/mod.rs +9 -0
- package/dist-engine-src/src/json_store/store.rs +236 -0
- package/dist-engine-src/src/json_store/types.rs +52 -0
- package/dist-engine-src/src/lib.rs +61 -0
- package/dist-engine-src/src/live_state/context.rs +2241 -0
- package/dist-engine-src/src/live_state/mod.rs +15 -0
- package/dist-engine-src/src/live_state/overlay.rs +75 -0
- package/dist-engine-src/src/live_state/reader.rs +23 -0
- package/dist-engine-src/src/live_state/types.rs +239 -0
- package/dist-engine-src/src/live_state/visibility.rs +218 -0
- package/dist-engine-src/src/plugin/archive.rs +441 -0
- package/dist-engine-src/src/plugin/component.rs +183 -0
- package/dist-engine-src/src/plugin/install.rs +637 -0
- package/dist-engine-src/src/plugin/manifest.rs +516 -0
- package/dist-engine-src/src/plugin/materializer.rs +477 -0
- package/dist-engine-src/src/plugin/mod.rs +33 -0
- package/dist-engine-src/src/plugin/plugin_manifest.json +119 -0
- package/dist-engine-src/src/plugin/storage.rs +74 -0
- package/dist-engine-src/src/schema/annotations/defaults.rs +280 -0
- package/dist-engine-src/src/schema/annotations/mod.rs +1 -0
- package/dist-engine-src/src/schema/builtin/lix_account.json +22 -0
- package/dist-engine-src/src/schema/builtin/lix_active_account.json +30 -0
- package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +30 -0
- package/dist-engine-src/src/schema/builtin/lix_change.json +62 -0
- package/dist-engine-src/src/schema/builtin/lix_change_author.json +46 -0
- package/dist-engine-src/src/schema/builtin/lix_change_set.json +18 -0
- package/dist-engine-src/src/schema/builtin/lix_change_set_element.json +75 -0
- package/dist-engine-src/src/schema/builtin/lix_commit.json +62 -0
- package/dist-engine-src/src/schema/builtin/lix_commit_edge.json +46 -0
- package/dist-engine-src/src/schema/builtin/lix_directory_descriptor.json +53 -0
- package/dist-engine-src/src/schema/builtin/lix_entity_label.json +63 -0
- package/dist-engine-src/src/schema/builtin/lix_file_descriptor.json +53 -0
- package/dist-engine-src/src/schema/builtin/lix_key_value.json +41 -0
- package/dist-engine-src/src/schema/builtin/lix_label.json +22 -0
- package/dist-engine-src/src/schema/builtin/lix_registered_schema.json +31 -0
- package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +35 -0
- package/dist-engine-src/src/schema/builtin/lix_version_ref.json +49 -0
- package/dist-engine-src/src/schema/builtin/mod.rs +271 -0
- package/dist-engine-src/src/schema/definition.json +157 -0
- package/dist-engine-src/src/schema/definition.rs +636 -0
- package/dist-engine-src/src/schema/key.rs +206 -0
- package/dist-engine-src/src/schema/mod.rs +20 -0
- package/dist-engine-src/src/schema/seed.rs +14 -0
- package/dist-engine-src/src/schema/tests.rs +739 -0
- package/dist-engine-src/src/schema_registry.rs +294 -0
- package/dist-engine-src/src/session/context.rs +366 -0
- package/dist-engine-src/src/session/create_version.rs +80 -0
- package/dist-engine-src/src/session/execute.rs +447 -0
- package/dist-engine-src/src/session/merge/analysis.rs +102 -0
- package/dist-engine-src/src/session/merge/apply.rs +23 -0
- package/dist-engine-src/src/session/merge/conflicts.rs +62 -0
- package/dist-engine-src/src/session/merge/mod.rs +11 -0
- package/dist-engine-src/src/session/merge/stats.rs +65 -0
- package/dist-engine-src/src/session/merge/version.rs +437 -0
- package/dist-engine-src/src/session/mod.rs +25 -0
- package/dist-engine-src/src/session/switch_version.rs +121 -0
- package/dist-engine-src/src/sql2/change_provider.rs +337 -0
- package/dist-engine-src/src/sql2/classify.rs +147 -0
- package/dist-engine-src/src/sql2/commit_derived_provider.rs +591 -0
- package/dist-engine-src/src/sql2/context.rs +307 -0
- package/dist-engine-src/src/sql2/directory_history_provider.rs +623 -0
- package/dist-engine-src/src/sql2/directory_provider.rs +2405 -0
- package/dist-engine-src/src/sql2/dml.rs +148 -0
- package/dist-engine-src/src/sql2/entity_history_provider.rs +444 -0
- package/dist-engine-src/src/sql2/entity_provider.rs +2700 -0
- package/dist-engine-src/src/sql2/error.rs +196 -0
- package/dist-engine-src/src/sql2/execute.rs +3379 -0
- package/dist-engine-src/src/sql2/file_history_provider.rs +902 -0
- package/dist-engine-src/src/sql2/file_provider.rs +3254 -0
- package/dist-engine-src/src/sql2/filesystem_planner.rs +1526 -0
- package/dist-engine-src/src/sql2/filesystem_predicates.rs +159 -0
- package/dist-engine-src/src/sql2/filesystem_visibility.rs +369 -0
- package/dist-engine-src/src/sql2/history_projection.rs +80 -0
- package/dist-engine-src/src/sql2/history_provider.rs +418 -0
- package/dist-engine-src/src/sql2/history_route.rs +643 -0
- package/dist-engine-src/src/sql2/lix_state_provider.rs +2430 -0
- package/dist-engine-src/src/sql2/mod.rs +43 -0
- package/dist-engine-src/src/sql2/read_only.rs +65 -0
- package/dist-engine-src/src/sql2/record_batch.rs +17 -0
- package/dist-engine-src/src/sql2/result_metadata.rs +29 -0
- package/dist-engine-src/src/sql2/runtime.rs +60 -0
- package/dist-engine-src/src/sql2/session.rs +135 -0
- package/dist-engine-src/src/sql2/udfs/common.rs +295 -0
- package/dist-engine-src/src/sql2/udfs/lix_active_version_commit_id.rs +53 -0
- package/dist-engine-src/src/sql2/udfs/lix_empty_blob.rs +47 -0
- package/dist-engine-src/src/sql2/udfs/lix_json.rs +100 -0
- package/dist-engine-src/src/sql2/udfs/lix_json_get.rs +99 -0
- package/dist-engine-src/src/sql2/udfs/lix_json_get_text.rs +99 -0
- package/dist-engine-src/src/sql2/udfs/lix_text_decode.rs +82 -0
- package/dist-engine-src/src/sql2/udfs/lix_text_encode.rs +85 -0
- package/dist-engine-src/src/sql2/udfs/lix_uuid_v7.rs +76 -0
- package/dist-engine-src/src/sql2/udfs/mod.rs +82 -0
- package/dist-engine-src/src/sql2/version_provider.rs +1187 -0
- package/dist-engine-src/src/sql2/version_scope.rs +394 -0
- package/dist-engine-src/src/sql2/write_normalization.rs +345 -0
- package/dist-engine-src/src/storage/context.rs +356 -0
- package/dist-engine-src/src/storage/mod.rs +14 -0
- package/dist-engine-src/src/storage/read_scope.rs +88 -0
- package/dist-engine-src/src/storage/types.rs +501 -0
- package/dist-engine-src/src/storage_bench.rs +3406 -0
- package/dist-engine-src/src/test_support.rs +81 -0
- package/dist-engine-src/src/tracked_state/by_file_index.rs +102 -0
- package/dist-engine-src/src/tracked_state/codec.rs +747 -0
- package/dist-engine-src/src/tracked_state/context.rs +983 -0
- package/dist-engine-src/src/tracked_state/diff.rs +494 -0
- package/dist-engine-src/src/tracked_state/materialization.rs +141 -0
- package/dist-engine-src/src/tracked_state/merge.rs +474 -0
- package/dist-engine-src/src/tracked_state/mod.rs +31 -0
- package/dist-engine-src/src/tracked_state/rebuild.rs +771 -0
- package/dist-engine-src/src/tracked_state/storage.rs +243 -0
- package/dist-engine-src/src/tracked_state/tree.rs +2744 -0
- package/dist-engine-src/src/tracked_state/tree_types.rs +176 -0
- package/dist-engine-src/src/tracked_state/types.rs +61 -0
- package/dist-engine-src/src/transaction/commit.rs +1224 -0
- package/dist-engine-src/src/transaction/context.rs +1307 -0
- package/dist-engine-src/src/transaction/live_state_overlay.rs +34 -0
- package/dist-engine-src/src/transaction/mod.rs +11 -0
- package/dist-engine-src/src/transaction/normalization.rs +1026 -0
- package/dist-engine-src/src/transaction/schema_resolver.rs +127 -0
- package/dist-engine-src/src/transaction/staging.rs +1436 -0
- package/dist-engine-src/src/transaction/types.rs +351 -0
- package/dist-engine-src/src/transaction/validation.rs +4811 -0
- package/dist-engine-src/src/untracked_state/codec.rs +363 -0
- package/dist-engine-src/src/untracked_state/context.rs +82 -0
- package/dist-engine-src/src/untracked_state/materialization.rs +157 -0
- package/dist-engine-src/src/untracked_state/mod.rs +17 -0
- package/dist-engine-src/src/untracked_state/storage.rs +348 -0
- package/dist-engine-src/src/untracked_state/types.rs +96 -0
- package/dist-engine-src/src/version/context.rs +52 -0
- package/dist-engine-src/src/version/mod.rs +12 -0
- package/dist-engine-src/src/version/refs.rs +421 -0
- package/dist-engine-src/src/version/stage_rows.rs +71 -0
- package/dist-engine-src/src/version/types.rs +21 -0
- package/dist-engine-src/src/wasm/mod.rs +60 -0
- package/package.json +68 -63
package/dist/open-lix.js
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
import init, { resolveEngineWasmModuleOrPath, Value, } from "./engine-wasm/index.js";
|
|
2
2
|
import * as wasmModule from "./engine-wasm/index.js";
|
|
3
|
+
export class Row {
|
|
4
|
+
columns;
|
|
5
|
+
valuesByIndex;
|
|
6
|
+
constructor(columns, values) {
|
|
7
|
+
this.columns = columns;
|
|
8
|
+
this.valuesByIndex = values;
|
|
9
|
+
}
|
|
10
|
+
get(columnName) {
|
|
11
|
+
return valueToNative(this.value(columnName));
|
|
12
|
+
}
|
|
13
|
+
tryGet(columnName) {
|
|
14
|
+
const value = this.tryValue(columnName);
|
|
15
|
+
return value === undefined ? undefined : valueToNative(value);
|
|
16
|
+
}
|
|
17
|
+
value(columnName) {
|
|
18
|
+
const index = this.columns.indexOf(columnName);
|
|
19
|
+
if (index === -1) {
|
|
20
|
+
throw createLixError("LIX_COLUMN_NOT_FOUND", `Column "${columnName}" does not exist. Available columns: ${this.availableColumns()}`);
|
|
21
|
+
}
|
|
22
|
+
const value = this.valuesByIndex[index];
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
throw createLixError("LIX_COLUMN_NOT_FOUND", `Column "${columnName}" is outside row width ${this.valuesByIndex.length}.`);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
tryValue(columnName) {
|
|
29
|
+
const index = this.columns.indexOf(columnName);
|
|
30
|
+
return index === -1 ? undefined : this.valuesByIndex[index];
|
|
31
|
+
}
|
|
32
|
+
getAt(index) {
|
|
33
|
+
return valueToNative(this.valueAt(index));
|
|
34
|
+
}
|
|
35
|
+
valueAt(index) {
|
|
36
|
+
const value = this.valuesByIndex[index];
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
throw createLixError("LIX_COLUMN_NOT_FOUND", `Column index ${index} is outside row width ${this.valuesByIndex.length}.`);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
values() {
|
|
43
|
+
return [...this.valuesByIndex];
|
|
44
|
+
}
|
|
45
|
+
toObject() {
|
|
46
|
+
return Object.fromEntries(this.columns.map((column, index) => [
|
|
47
|
+
column,
|
|
48
|
+
valueToNative(this.valueAt(index)),
|
|
49
|
+
]));
|
|
50
|
+
}
|
|
51
|
+
toValueMap() {
|
|
52
|
+
return Object.fromEntries(this.columns.map((column, index) => [column, this.valueAt(index)]));
|
|
53
|
+
}
|
|
54
|
+
availableColumns() {
|
|
55
|
+
return this.columns.length === 0 ? "<none>" : this.columns.join(", ");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function valueToNative(value) {
|
|
59
|
+
switch (value.kind) {
|
|
60
|
+
case "null":
|
|
61
|
+
return null;
|
|
62
|
+
case "boolean":
|
|
63
|
+
case "integer":
|
|
64
|
+
case "real":
|
|
65
|
+
case "text":
|
|
66
|
+
case "json":
|
|
67
|
+
return value.value;
|
|
68
|
+
case "blob":
|
|
69
|
+
return value.asBlob() ?? new Uint8Array();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
3
72
|
let wasmReady = null;
|
|
4
73
|
async function ensureWasmReady() {
|
|
5
74
|
if (!wasmReady) {
|
|
@@ -13,7 +82,7 @@ export async function openLix(options = {}) {
|
|
|
13
82
|
await ensureWasmReady();
|
|
14
83
|
try {
|
|
15
84
|
const wasmLix = (await wasmModule.openLix(options));
|
|
16
|
-
return createLixHandle(wasmLix
|
|
85
|
+
return createLixHandle(wasmLix);
|
|
17
86
|
}
|
|
18
87
|
catch (error) {
|
|
19
88
|
try {
|
|
@@ -22,17 +91,11 @@ export async function openLix(options = {}) {
|
|
|
22
91
|
catch {
|
|
23
92
|
// Preserve the original open failure.
|
|
24
93
|
}
|
|
25
|
-
throw error;
|
|
94
|
+
throw normalizeThrownError(error);
|
|
26
95
|
}
|
|
27
96
|
}
|
|
28
|
-
function createLixHandle(wasmLix
|
|
29
|
-
let closed = false;
|
|
97
|
+
function createLixHandle(wasmLix) {
|
|
30
98
|
let operationQueue = Promise.resolve();
|
|
31
|
-
const ensureOpen = (methodName) => {
|
|
32
|
-
if (closed) {
|
|
33
|
-
throw new Error(`lix is closed; ${methodName}() is unavailable`);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
99
|
const acquireOperationSlot = async () => {
|
|
37
100
|
const previous = operationQueue;
|
|
38
101
|
let releaseCurrent;
|
|
@@ -48,57 +111,158 @@ function createLixHandle(wasmLix, backend) {
|
|
|
48
111
|
try {
|
|
49
112
|
return await operation();
|
|
50
113
|
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw normalizeThrownError(error);
|
|
116
|
+
}
|
|
51
117
|
finally {
|
|
52
118
|
release();
|
|
53
119
|
}
|
|
54
120
|
};
|
|
55
121
|
return {
|
|
56
122
|
async execute(sql, params = []) {
|
|
57
|
-
|
|
58
|
-
const
|
|
123
|
+
validateExecuteArguments(sql, params);
|
|
124
|
+
const values = params.map((param, index) => valueFromExecuteParam(param, index));
|
|
125
|
+
const result = await runQueued(() => wasmLix.execute(sql, values));
|
|
59
126
|
return normalizeExecuteResult(result);
|
|
60
127
|
},
|
|
61
128
|
async activeVersionId() {
|
|
62
|
-
ensureOpen("activeVersionId");
|
|
63
129
|
return await runQueued(() => wasmLix.activeVersionId());
|
|
64
130
|
},
|
|
65
131
|
async createVersion(options) {
|
|
66
|
-
ensureOpen("createVersion");
|
|
67
132
|
return await runQueued(() => wasmLix.createVersion(options));
|
|
68
133
|
},
|
|
69
134
|
async switchVersion(options) {
|
|
70
|
-
ensureOpen("switchVersion");
|
|
71
135
|
return await runQueued(() => wasmLix.switchVersion(options));
|
|
72
136
|
},
|
|
137
|
+
async mergeVersionPreview(options) {
|
|
138
|
+
return await runQueued(() => wasmLix.mergeVersionPreview(options));
|
|
139
|
+
},
|
|
73
140
|
async mergeVersion(options) {
|
|
74
|
-
ensureOpen("mergeVersion");
|
|
75
141
|
return await runQueued(() => wasmLix.mergeVersion(options));
|
|
76
142
|
},
|
|
77
143
|
async close() {
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
try {
|
|
81
|
-
await runQueued(() => wasmLix.close());
|
|
82
|
-
}
|
|
83
|
-
finally {
|
|
84
|
-
backend?.close?.();
|
|
85
|
-
closed = true;
|
|
86
|
-
}
|
|
144
|
+
await runQueued(() => wasmLix.close());
|
|
87
145
|
},
|
|
88
146
|
};
|
|
89
147
|
}
|
|
90
|
-
function
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
148
|
+
function validateExecuteArguments(sql, params) {
|
|
149
|
+
if (typeof sql !== "string") {
|
|
150
|
+
throw invalidArgumentError("execute", "sql", "string", sql);
|
|
151
|
+
}
|
|
152
|
+
if (!Array.isArray(params)) {
|
|
153
|
+
throw invalidArgumentError("execute", "params", "array", params);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function invalidArgumentError(operation, argument, expected, actualValue) {
|
|
157
|
+
return createLixError("LIX_INVALID_ARGUMENT", `lix.${operation}() expected ${argument} to be ${expectedArticle(expected)} ${expected}`, {
|
|
158
|
+
details: {
|
|
159
|
+
operation,
|
|
160
|
+
argument,
|
|
161
|
+
expected,
|
|
162
|
+
actual: runtimeTypeName(actualValue),
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function valueFromExecuteParam(param, index) {
|
|
167
|
+
try {
|
|
168
|
+
return Value.from(param);
|
|
99
169
|
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw invalidParamError(index, param, error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function invalidParamError(index, actualValue, cause) {
|
|
175
|
+
const message = cause instanceof Error && cause.message
|
|
176
|
+
? cause.message
|
|
177
|
+
: "parameter is not a valid Lix SQL value";
|
|
178
|
+
return createLixError("LIX_INVALID_PARAM", `lix.execute() invalid parameter $${index + 1}: ${message}`, {
|
|
179
|
+
details: {
|
|
180
|
+
operation: "execute",
|
|
181
|
+
parameter_index: index + 1,
|
|
182
|
+
argument: `params[${index}]`,
|
|
183
|
+
actual: runtimeTypeName(actualValue),
|
|
184
|
+
},
|
|
185
|
+
cause,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function expectedArticle(expected) {
|
|
189
|
+
return /^[aeiou]/i.test(expected) ? "an" : "a";
|
|
190
|
+
}
|
|
191
|
+
function runtimeTypeName(value) {
|
|
192
|
+
if (value === null)
|
|
193
|
+
return "null";
|
|
194
|
+
if (Array.isArray(value))
|
|
195
|
+
return "array";
|
|
196
|
+
if (value instanceof Date)
|
|
197
|
+
return "Date";
|
|
198
|
+
if (value instanceof ArrayBuffer)
|
|
199
|
+
return "ArrayBuffer";
|
|
200
|
+
if (ArrayBuffer.isView(value))
|
|
201
|
+
return value.constructor.name;
|
|
202
|
+
return typeof value;
|
|
203
|
+
}
|
|
204
|
+
function normalizeExecuteResult(result) {
|
|
205
|
+
const columns = [...result.columns];
|
|
100
206
|
return {
|
|
101
|
-
|
|
102
|
-
|
|
207
|
+
columns,
|
|
208
|
+
rows: result.rows.map((row) => new Row(columns, row.map((value) => Value.from(value)))),
|
|
209
|
+
rowsAffected: result.rowsAffected,
|
|
210
|
+
notices: result.notices ?? [],
|
|
103
211
|
};
|
|
104
212
|
}
|
|
213
|
+
function createLixError(code, message, options = {}) {
|
|
214
|
+
const error = new Error(message);
|
|
215
|
+
error.name = "LixError";
|
|
216
|
+
error.code = code;
|
|
217
|
+
if (options.hint !== undefined) {
|
|
218
|
+
error.hint = options.hint;
|
|
219
|
+
}
|
|
220
|
+
if (options.details !== undefined) {
|
|
221
|
+
error.details = options.details;
|
|
222
|
+
}
|
|
223
|
+
if (options.cause !== undefined) {
|
|
224
|
+
error.cause = options.cause;
|
|
225
|
+
}
|
|
226
|
+
return error;
|
|
227
|
+
}
|
|
228
|
+
function normalizeThrownError(error) {
|
|
229
|
+
if (isLixErrorLike(error)) {
|
|
230
|
+
const hint = typeof error.hint === "string"
|
|
231
|
+
? error.hint
|
|
232
|
+
: extractHintFromMessage(error.message);
|
|
233
|
+
const details = "details" in error ? error.details : undefined;
|
|
234
|
+
if (error instanceof Error) {
|
|
235
|
+
if (hint !== undefined && error.hint === undefined) {
|
|
236
|
+
error.hint = hint;
|
|
237
|
+
}
|
|
238
|
+
if (details !== undefined && error.details === undefined) {
|
|
239
|
+
error.details = details;
|
|
240
|
+
}
|
|
241
|
+
return error;
|
|
242
|
+
}
|
|
243
|
+
const message = typeof error.message === "string" ? error.message : error.code;
|
|
244
|
+
return createLixError(error.code, message, { hint, details });
|
|
245
|
+
}
|
|
246
|
+
if (error instanceof WebAssembly.RuntimeError) {
|
|
247
|
+
return createLixError("LIX_WASM_RUNTIME_ERROR", error.message, {
|
|
248
|
+
hint: "The Lix engine encountered a WebAssembly runtime trap. Please report this as an engine bug with the SQL statement or API call that triggered it.",
|
|
249
|
+
cause: error,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (error instanceof Error) {
|
|
253
|
+
return createLixError("LIX_ERROR_UNKNOWN", error.message, { cause: error });
|
|
254
|
+
}
|
|
255
|
+
return createLixError("LIX_ERROR_UNKNOWN", String(error));
|
|
256
|
+
}
|
|
257
|
+
function extractHintFromMessage(message) {
|
|
258
|
+
if (typeof message !== "string")
|
|
259
|
+
return undefined;
|
|
260
|
+
const match = message.match(/(?:^|\n)hint:\s*(.+)$/s);
|
|
261
|
+
return match?.[1]?.trim();
|
|
262
|
+
}
|
|
263
|
+
function isLixErrorLike(error) {
|
|
264
|
+
return (typeof error === "object" &&
|
|
265
|
+
error !== null &&
|
|
266
|
+
typeof error.code === "string" &&
|
|
267
|
+
error.code.startsWith("LIX_"));
|
|
268
|
+
}
|
package/dist/sqlite/index.js
CHANGED
|
@@ -51,21 +51,21 @@ class BetterSqlite3Backend {
|
|
|
51
51
|
this.#db = db;
|
|
52
52
|
this.#registryKey = registryKey;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
beginReadTransaction() {
|
|
55
55
|
this.#ensureOpen();
|
|
56
56
|
if (this.#db.inTransaction) {
|
|
57
57
|
throw new Error("cannot open nested Lix backend transaction");
|
|
58
58
|
}
|
|
59
|
-
this.#db.exec(
|
|
59
|
+
this.#db.exec("BEGIN DEFERRED");
|
|
60
60
|
return new BetterSqlite3Transaction(this.#db);
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
beginWriteTransaction() {
|
|
63
63
|
this.#ensureOpen();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.#
|
|
68
|
-
return
|
|
64
|
+
if (this.#db.inTransaction) {
|
|
65
|
+
throw new Error("cannot open nested Lix backend transaction");
|
|
66
|
+
}
|
|
67
|
+
this.#db.exec("BEGIN IMMEDIATE");
|
|
68
|
+
return new BetterSqlite3Transaction(this.#db);
|
|
69
69
|
}
|
|
70
70
|
close() {
|
|
71
71
|
if (this.#closed)
|
|
@@ -92,27 +92,59 @@ class BetterSqlite3Transaction {
|
|
|
92
92
|
constructor(db) {
|
|
93
93
|
this.#db = db;
|
|
94
94
|
}
|
|
95
|
-
|
|
95
|
+
getValues(request) {
|
|
96
|
+
this.#ensureOpen();
|
|
97
|
+
return getValues(this.#db, request);
|
|
98
|
+
}
|
|
99
|
+
existsMany(request) {
|
|
96
100
|
this.#ensureOpen();
|
|
97
|
-
return
|
|
101
|
+
return existsMany(this.#db, request);
|
|
98
102
|
}
|
|
99
|
-
|
|
103
|
+
scanKeys(request) {
|
|
100
104
|
this.#ensureOpen();
|
|
101
|
-
|
|
105
|
+
const { pairs, resumeAfter } = scanPage(this.#db, request);
|
|
106
|
+
return {
|
|
107
|
+
keys: pairs.map(({ key }) => key),
|
|
108
|
+
resumeAfter,
|
|
109
|
+
};
|
|
102
110
|
}
|
|
103
|
-
|
|
111
|
+
scanValues(request) {
|
|
104
112
|
this.#ensureOpen();
|
|
105
|
-
this.#db
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
const { pairs, resumeAfter } = scanPage(this.#db, request);
|
|
114
|
+
return {
|
|
115
|
+
values: pairs.map(({ value }) => value),
|
|
116
|
+
resumeAfter,
|
|
117
|
+
};
|
|
110
118
|
}
|
|
111
|
-
|
|
119
|
+
scanEntries(request) {
|
|
112
120
|
this.#ensureOpen();
|
|
113
|
-
this.#db
|
|
114
|
-
|
|
115
|
-
.
|
|
121
|
+
const { pairs, resumeAfter } = scanPage(this.#db, request);
|
|
122
|
+
return {
|
|
123
|
+
keys: pairs.map(({ key }) => key),
|
|
124
|
+
values: pairs.map(({ value }) => value),
|
|
125
|
+
resumeAfter,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
writeKvBatch(batch) {
|
|
129
|
+
this.#ensureOpen();
|
|
130
|
+
const stats = {
|
|
131
|
+
puts: 0,
|
|
132
|
+
deletes: 0,
|
|
133
|
+
bytesWritten: 0,
|
|
134
|
+
};
|
|
135
|
+
for (const group of batch.groups) {
|
|
136
|
+
for (const put of group.puts) {
|
|
137
|
+
stats.puts += 1;
|
|
138
|
+
stats.bytesWritten += put.key.length + put.value.length;
|
|
139
|
+
kvPut(this.#db, group.namespace, put.key, put.value);
|
|
140
|
+
}
|
|
141
|
+
for (const key of group.deletes) {
|
|
142
|
+
stats.deletes += 1;
|
|
143
|
+
stats.bytesWritten += key.length;
|
|
144
|
+
kvDelete(this.#db, group.namespace, key);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return stats;
|
|
116
148
|
}
|
|
117
149
|
commit() {
|
|
118
150
|
this.#ensureOpen();
|
|
@@ -130,6 +162,34 @@ class BetterSqlite3Transaction {
|
|
|
130
162
|
}
|
|
131
163
|
}
|
|
132
164
|
}
|
|
165
|
+
function getValues(db, request) {
|
|
166
|
+
return {
|
|
167
|
+
groups: request.groups.map((group) => ({
|
|
168
|
+
namespace: group.namespace,
|
|
169
|
+
values: group.keys.map((key) => kvGet(db, group.namespace, key)),
|
|
170
|
+
})),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function existsMany(db, request) {
|
|
174
|
+
return {
|
|
175
|
+
groups: request.groups.map((group) => ({
|
|
176
|
+
namespace: group.namespace,
|
|
177
|
+
exists: group.keys.map((key) => kvGet(db, group.namespace, key) !== null),
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function scanPage(db, request) {
|
|
182
|
+
const scanLimit = request.limit + 1 + (request.after ? 1 : 0);
|
|
183
|
+
const pairs = kvScan(db, request.namespace, request.range, scanLimit).filter((pair) => !request.after || compareBytes(pair.key, request.after) > 0);
|
|
184
|
+
const hasMore = pairs.length > request.limit;
|
|
185
|
+
const pagePairs = pairs.slice(0, request.limit);
|
|
186
|
+
return {
|
|
187
|
+
pairs: pagePairs,
|
|
188
|
+
resumeAfter: hasMore
|
|
189
|
+
? (pagePairs.at(-1)?.key ?? null)
|
|
190
|
+
: null,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
133
193
|
function kvGet(db, namespace, key) {
|
|
134
194
|
const row = db
|
|
135
195
|
.prepare("SELECT value FROM lix_kv WHERE namespace = ? AND key = ?")
|
|
@@ -139,6 +199,14 @@ function kvGet(db, namespace, key) {
|
|
|
139
199
|
}
|
|
140
200
|
return bytesFromUnknown(row.value, "lix_kv.value");
|
|
141
201
|
}
|
|
202
|
+
function kvPut(db, namespace, key, value) {
|
|
203
|
+
db.prepare(`INSERT INTO lix_kv (namespace, key, value)
|
|
204
|
+
VALUES (?, ?, ?)
|
|
205
|
+
ON CONFLICT(namespace, key) DO UPDATE SET value = excluded.value`).run(namespace, sqliteBytes(key), sqliteBytes(value));
|
|
206
|
+
}
|
|
207
|
+
function kvDelete(db, namespace, key) {
|
|
208
|
+
db.prepare("DELETE FROM lix_kv WHERE namespace = ? AND key = ?").run(namespace, sqliteBytes(key));
|
|
209
|
+
}
|
|
142
210
|
function kvScan(db, namespace, range, limit) {
|
|
143
211
|
const { sql, params } = scanQuery(namespace, range, limit);
|
|
144
212
|
return db.prepare(sql).all(...params).map((row) => {
|
|
@@ -174,6 +242,15 @@ function scanQuery(namespace, range, limit) {
|
|
|
174
242
|
}
|
|
175
243
|
return { sql, params };
|
|
176
244
|
}
|
|
245
|
+
function compareBytes(left, right) {
|
|
246
|
+
const length = Math.min(left.length, right.length);
|
|
247
|
+
for (let index = 0; index < length; index++) {
|
|
248
|
+
const delta = left[index] - right[index];
|
|
249
|
+
if (delta !== 0)
|
|
250
|
+
return delta;
|
|
251
|
+
}
|
|
252
|
+
return left.length - right.length;
|
|
253
|
+
}
|
|
177
254
|
function prefixUpperBound(prefix) {
|
|
178
255
|
const end = new Uint8Array(prefix);
|
|
179
256
|
for (let index = end.length - 1; index >= 0; index--) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Bundled Lix Engine Source
|
|
2
|
+
|
|
3
|
+
This directory is a generated snapshot of the Rust engine source that backs this @lix-js/sdk release.
|
|
4
|
+
|
|
5
|
+
Source in the Lix monorepo: `packages/engine/src`
|
|
6
|
+
|
|
7
|
+
Agents should inspect these files when SDK behavior is unclear instead of relying only on SKILL.md prose.
|
|
8
|
+
|
|
9
|
+
Useful entry points:
|
|
10
|
+
|
|
11
|
+
- `src/sql2/entity_provider.rs` - registered schema SQL surfaces
|
|
12
|
+
- `src/sql2/change_provider.rs` - `lix_change` projection
|
|
13
|
+
- `src/sql2/version_provider.rs` - writable `lix_version` surface
|
|
14
|
+
- `src/transaction/validation.rs` - primary-key, unique, foreign-key, and shape validation
|
|
15
|
+
- `src/schema/definition.json` - Lix schema-definition meta-schema
|
|
16
|
+
- `src/schema/builtin/` - built-in schema definitions
|
|
17
|
+
|
|
18
|
+
Regenerate with `pnpm --filter @lix-js/sdk sync:engine-src` from the repo root.
|