@lix-js/sdk 0.10.0 → 0.12.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 +49 -78
- package/dist/binding-types.d.ts +9 -18
- package/dist/binding.browser.js +18 -5
- package/dist/binding.node.js +5 -11
- package/dist/bundled-plugins/plugin_csv.lixplugin +0 -0
- package/dist/bundled-plugins/plugin_markdown.lixplugin +0 -0
- package/dist/errors.d.ts +0 -2
- package/dist/errors.js +0 -13
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/indexeddb-backend.d.ts +19 -0
- package/dist/indexeddb-backend.js +121 -0
- package/dist/lix.d.ts +3 -6
- package/dist/lix.js +28 -54
- package/dist/open-lix.d.ts +4 -13
- package/dist/open-lix.js +45 -152
- package/dist/remote/client.d.ts +2 -3
- package/dist/remote/client.js +50 -23
- package/dist/remote/{protocol.d.ts → server-protocol.d.ts} +40 -32
- package/dist/remote/{protocol.js → server-protocol.js} +36 -17
- package/dist/result.d.ts +2 -1
- package/dist/result.js +12 -0
- package/dist/storage-adapter.d.ts +30 -0
- package/dist/storage-adapter.js +12 -0
- package/dist/types.d.ts +25 -27
- package/dist/value.d.ts +2 -1
- package/dist/value.js +23 -10
- package/dist/wasm/lix_js_sdk.d.ts +5 -10
- package/dist/wasm/lix_js_sdk.js +33 -45
- package/dist/wasm/lix_js_sdk_bg.wasm +0 -0
- package/dist/wasm/lix_js_sdk_bg.wasm.d.ts +3 -6
- package/dist/worker/client.d.ts +1 -12
- package/dist/worker/client.js +0 -161
- package/dist/worker/host.js +0 -23
- package/dist/worker/protocol.d.ts +1 -15
- package/package.json +8 -12
- package/dist/client-state.d.ts +0 -53
- package/dist/client-state.js +0 -318
- package/dist/local-storage-adapter.d.ts +0 -26
- package/dist/local-storage-adapter.js +0 -117
- package/dist/snapshot-persistence.d.ts +0 -7
- package/dist/snapshot-persistence.js +0 -26
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BindingExecuteResult, BindingObserveEvent } from "../binding-types.js";
|
|
2
2
|
import type { NativeLixValue } from "../value.js";
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
3
|
+
export declare const SERVER_PROTOCOL_VERSION = 2;
|
|
4
|
+
export declare const SERVER_PROTOCOL_PATH = "/lix/v1/";
|
|
5
5
|
export type WireValue = {
|
|
6
6
|
kind: "null";
|
|
7
7
|
value: null;
|
|
@@ -18,8 +18,11 @@ export type WireValue = {
|
|
|
18
18
|
kind: "text";
|
|
19
19
|
value: string;
|
|
20
20
|
} | {
|
|
21
|
-
kind: "
|
|
21
|
+
kind: "jsonb";
|
|
22
22
|
value: unknown;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "timestamptz";
|
|
25
|
+
value: string;
|
|
23
26
|
} | {
|
|
24
27
|
kind: "blob";
|
|
25
28
|
base64: string;
|
|
@@ -33,17 +36,16 @@ export type WireRequestBlobSplice = {
|
|
|
33
36
|
insertBase64: string;
|
|
34
37
|
};
|
|
35
38
|
export type WireRequestValue = WireValue | WireRequestBlobSplice;
|
|
36
|
-
export type
|
|
39
|
+
export type ServerProtocolHandshake = {
|
|
37
40
|
protocolVersion: number;
|
|
38
41
|
activeBranchId: string;
|
|
39
42
|
activeAccountId: string;
|
|
40
43
|
sessionId: string;
|
|
41
44
|
};
|
|
42
|
-
export type
|
|
45
|
+
export type ServerProtocolHandshakeRequest = {
|
|
43
46
|
activeBranchId?: string;
|
|
44
|
-
activeAccountId?: string;
|
|
45
47
|
};
|
|
46
|
-
export type
|
|
48
|
+
export type ServerProtocolExecuteRequest = {
|
|
47
49
|
sql: string;
|
|
48
50
|
params: WireRequestValue[];
|
|
49
51
|
options?: {
|
|
@@ -51,17 +53,18 @@ export type RemoteExecuteRequest = {
|
|
|
51
53
|
};
|
|
52
54
|
cacheBlobs?: true;
|
|
53
55
|
};
|
|
54
|
-
export type
|
|
56
|
+
export type ServerProtocolExecuteBatchRequest = {
|
|
55
57
|
statements: Array<{
|
|
56
58
|
sql: string;
|
|
57
59
|
params: WireRequestValue[];
|
|
60
|
+
label?: string;
|
|
58
61
|
}>;
|
|
59
62
|
options?: {
|
|
60
63
|
originKey?: string;
|
|
61
64
|
};
|
|
62
65
|
cacheBlobs?: true;
|
|
63
66
|
};
|
|
64
|
-
export type
|
|
67
|
+
export type ServerProtocolExecuteResponse = {
|
|
65
68
|
columns: string[];
|
|
66
69
|
rows: WireValue[][];
|
|
67
70
|
rowsAffected: number;
|
|
@@ -71,76 +74,80 @@ export type RemoteExecuteResponse = {
|
|
|
71
74
|
hint?: string;
|
|
72
75
|
}>;
|
|
73
76
|
};
|
|
74
|
-
export type
|
|
77
|
+
export type ServerProtocolExecuteBatchResponse = ServerProtocolExecuteResponse & {
|
|
78
|
+
statementIndex: number;
|
|
79
|
+
label?: string;
|
|
80
|
+
};
|
|
81
|
+
export type ServerProtocolObserveRequest = {
|
|
75
82
|
sql: string;
|
|
76
83
|
params: WireValue[];
|
|
77
84
|
};
|
|
78
|
-
export type
|
|
85
|
+
export type ServerProtocolObserveSubscription = ServerProtocolObserveRequest & {
|
|
79
86
|
id: string;
|
|
80
87
|
};
|
|
81
|
-
export type
|
|
82
|
-
subscriptions:
|
|
88
|
+
export type ServerProtocolMultiplexObserveRequest = {
|
|
89
|
+
subscriptions: ServerProtocolObserveSubscription[];
|
|
83
90
|
};
|
|
84
|
-
type
|
|
91
|
+
type ServerProtocolObserveEventBase = {
|
|
85
92
|
sequence: number;
|
|
86
93
|
mutationSequence: number;
|
|
87
94
|
};
|
|
88
|
-
export type
|
|
95
|
+
export type ServerProtocolObserveBlobDelta = {
|
|
89
96
|
kind: "single-blob-splice";
|
|
90
97
|
baseSequence: number;
|
|
91
98
|
prefixBytes: number;
|
|
92
99
|
suffixBytes: number;
|
|
93
100
|
insertBase64: string;
|
|
94
101
|
};
|
|
95
|
-
type
|
|
102
|
+
type ServerProtocolObserveRowSplice = {
|
|
96
103
|
kind: "row-splice";
|
|
97
104
|
baseSequence: number;
|
|
98
105
|
prefixRows: number;
|
|
99
106
|
deleteRows: number;
|
|
100
107
|
insertRows: WireValue[][];
|
|
101
108
|
};
|
|
102
|
-
type
|
|
103
|
-
export type
|
|
104
|
-
result:
|
|
109
|
+
type ServerProtocolObserveDelta = ServerProtocolObserveBlobDelta | ServerProtocolObserveRowSplice;
|
|
110
|
+
export type ServerProtocolObserveEvent = ServerProtocolObserveEventBase & ({
|
|
111
|
+
result: ServerProtocolExecuteResponse;
|
|
105
112
|
delta?: never;
|
|
106
113
|
} | {
|
|
107
114
|
result?: never;
|
|
108
|
-
delta:
|
|
115
|
+
delta: ServerProtocolObserveDelta;
|
|
109
116
|
});
|
|
110
|
-
export type
|
|
117
|
+
export type ServerProtocolMultiplexObserveEvent = ServerProtocolObserveEvent & {
|
|
111
118
|
subscriptionId: string;
|
|
112
119
|
};
|
|
113
|
-
export type
|
|
120
|
+
export type ServerProtocolCreateBranchRequest = {
|
|
114
121
|
id?: string;
|
|
115
122
|
name: string;
|
|
116
123
|
fromCommitId?: string;
|
|
117
124
|
};
|
|
118
|
-
export type
|
|
125
|
+
export type ServerProtocolCreateBranchResponse = {
|
|
119
126
|
id: string;
|
|
120
127
|
name: string;
|
|
121
128
|
hidden: boolean;
|
|
122
129
|
commitId: string;
|
|
123
130
|
};
|
|
124
|
-
export type
|
|
131
|
+
export type ServerProtocolCreateCheckpointResponse = {
|
|
125
132
|
commitId: string;
|
|
126
133
|
};
|
|
127
|
-
export type
|
|
134
|
+
export type ServerProtocolUndoResponse = {
|
|
128
135
|
branchId: string;
|
|
129
136
|
targetCommitId: string;
|
|
130
137
|
inverseCommitId: string;
|
|
131
138
|
};
|
|
132
|
-
export type
|
|
139
|
+
export type ServerProtocolRedoResponse = {
|
|
133
140
|
branchId: string;
|
|
134
141
|
targetCommitId: string;
|
|
135
142
|
replayCommitId: string;
|
|
136
143
|
};
|
|
137
|
-
export type
|
|
144
|
+
export type ServerProtocolSwitchBranchRequest = {
|
|
138
145
|
branchId: string;
|
|
139
146
|
};
|
|
140
|
-
export type
|
|
147
|
+
export type ServerProtocolSwitchBranchResponse = {
|
|
141
148
|
branchId: string;
|
|
142
149
|
};
|
|
143
|
-
export type
|
|
150
|
+
export type ServerProtocolErrorBody = {
|
|
144
151
|
error: {
|
|
145
152
|
code?: string;
|
|
146
153
|
message?: string;
|
|
@@ -148,15 +155,16 @@ export type RemoteErrorBody = {
|
|
|
148
155
|
details?: unknown;
|
|
149
156
|
};
|
|
150
157
|
};
|
|
151
|
-
export type
|
|
158
|
+
export type ServerProtocolObserveErrorEvent = ServerProtocolErrorBody & {
|
|
152
159
|
retryable?: boolean;
|
|
153
160
|
};
|
|
154
|
-
export type
|
|
161
|
+
export type ServerProtocolMultiplexObserveErrorEvent = ServerProtocolObserveErrorEvent & {
|
|
155
162
|
subscriptionId?: string;
|
|
156
163
|
};
|
|
157
164
|
export declare function encodeWireValue(value: NativeLixValue): WireValue;
|
|
158
165
|
export declare function decodeExecuteResult(value: unknown): BindingExecuteResult;
|
|
159
|
-
export declare function
|
|
166
|
+
export declare function decodeExecuteBatchResult(value: unknown): BindingExecuteResult;
|
|
167
|
+
export declare function decodeHandshake(value: unknown): ServerProtocolHandshake;
|
|
160
168
|
export declare function decodeObserveEvent(value: unknown, base?: BindingObserveEvent): BindingObserveEvent;
|
|
161
169
|
export declare function remoteError(code: string, message: string, options?: {
|
|
162
170
|
hint?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const SERVER_PROTOCOL_VERSION = 2;
|
|
2
|
+
export const SERVER_PROTOCOL_PATH = "/lix/v1/";
|
|
3
3
|
export function encodeWireValue(value) {
|
|
4
4
|
switch (value.kind) {
|
|
5
5
|
case "null":
|
|
@@ -12,8 +12,10 @@ export function encodeWireValue(value) {
|
|
|
12
12
|
return { kind: "float", value: value.value };
|
|
13
13
|
case "text":
|
|
14
14
|
return { kind: "text", value: value.value };
|
|
15
|
-
case "
|
|
16
|
-
return { kind: "
|
|
15
|
+
case "jsonb":
|
|
16
|
+
return { kind: "jsonb", value: value.value };
|
|
17
|
+
case "timestamptz":
|
|
18
|
+
return { kind: "timestamptz", value: value.value };
|
|
17
19
|
case "blob":
|
|
18
20
|
return { kind: "blob", base64: bytesToBase64(value.blob) };
|
|
19
21
|
}
|
|
@@ -57,25 +59,37 @@ export function decodeExecuteResult(value) {
|
|
|
57
59
|
});
|
|
58
60
|
return { columns, rows, rowsAffected: result.rowsAffected, notices };
|
|
59
61
|
}
|
|
62
|
+
export function decodeExecuteBatchResult(value) {
|
|
63
|
+
const result = record(value, "execute batch result");
|
|
64
|
+
const statementIndex = nonNegativeSafeInteger(result.statementIndex, "execute batch result statementIndex");
|
|
65
|
+
if (result.label !== undefined && typeof result.label !== "string") {
|
|
66
|
+
throw protocolError("execute batch result label must be a string when present");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
...decodeExecuteResult(value),
|
|
70
|
+
statementIndex,
|
|
71
|
+
...(result.label === undefined ? {} : { label: result.label }),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
60
74
|
export function decodeHandshake(value) {
|
|
61
|
-
const handshake = record(value, "
|
|
62
|
-
if (handshake.protocolVersion !==
|
|
63
|
-
throw protocolError(`unsupported
|
|
75
|
+
const handshake = record(value, "Lix Server Protocol handshake");
|
|
76
|
+
if (handshake.protocolVersion !== SERVER_PROTOCOL_VERSION) {
|
|
77
|
+
throw protocolError(`unsupported Lix Server Protocol version: ${String(handshake.protocolVersion)}`);
|
|
64
78
|
}
|
|
65
79
|
if (typeof handshake.activeBranchId !== "string" ||
|
|
66
80
|
handshake.activeBranchId.length === 0) {
|
|
67
|
-
throw protocolError("
|
|
81
|
+
throw protocolError("Lix Server Protocol handshake requires activeBranchId");
|
|
68
82
|
}
|
|
69
83
|
if (typeof handshake.activeAccountId !== "string" ||
|
|
70
84
|
handshake.activeAccountId.length === 0) {
|
|
71
|
-
throw protocolError("
|
|
85
|
+
throw protocolError("Lix Server Protocol handshake requires activeAccountId");
|
|
72
86
|
}
|
|
73
87
|
if (typeof handshake.sessionId !== "string" ||
|
|
74
88
|
!/^[\x21-\x7e]{1,256}$/.test(handshake.sessionId)) {
|
|
75
|
-
throw protocolError("
|
|
89
|
+
throw protocolError("Lix Server Protocol handshake requires a valid sessionId");
|
|
76
90
|
}
|
|
77
91
|
return {
|
|
78
|
-
protocolVersion:
|
|
92
|
+
protocolVersion: SERVER_PROTOCOL_VERSION,
|
|
79
93
|
activeBranchId: handshake.activeBranchId,
|
|
80
94
|
activeAccountId: handshake.activeAccountId,
|
|
81
95
|
sessionId: handshake.sessionId,
|
|
@@ -228,11 +242,11 @@ export function remoteError(code, message, options = {}) {
|
|
|
228
242
|
return error;
|
|
229
243
|
}
|
|
230
244
|
export function protocolError(message) {
|
|
231
|
-
return remoteError("
|
|
245
|
+
return remoteError("LIX_SERVER_PROTOCOL_ERROR", message);
|
|
232
246
|
}
|
|
233
247
|
export function errorFromResponseBody(value, status) {
|
|
234
|
-
const body = record(value, "
|
|
235
|
-
const rawError = record(body.error, "
|
|
248
|
+
const body = record(value, "Lix Server Protocol error response");
|
|
249
|
+
const rawError = record(body.error, "Lix Server Protocol error response error");
|
|
236
250
|
return remoteError(typeof rawError.code === "string"
|
|
237
251
|
? rawError.code
|
|
238
252
|
: "LIX_REMOTE_REQUEST_FAILED", typeof rawError.message === "string"
|
|
@@ -281,9 +295,14 @@ function decodeWireValue(value) {
|
|
|
281
295
|
throw protocolError("text wire value is invalid");
|
|
282
296
|
}
|
|
283
297
|
return { kind: "text", value: wire.value };
|
|
284
|
-
case "
|
|
285
|
-
assertJsonValue(wire.value, "
|
|
286
|
-
return { kind: "
|
|
298
|
+
case "jsonb":
|
|
299
|
+
assertJsonValue(wire.value, "jsonb wire value");
|
|
300
|
+
return { kind: "jsonb", value: wire.value };
|
|
301
|
+
case "timestamptz":
|
|
302
|
+
if (typeof wire.value !== "string") {
|
|
303
|
+
throw protocolError("timestamptz wire value is invalid");
|
|
304
|
+
}
|
|
305
|
+
return { kind: "timestamptz", value: wire.value };
|
|
287
306
|
case "blob":
|
|
288
307
|
if (typeof wire.base64 !== "string") {
|
|
289
308
|
throw protocolError("blob wire value is invalid");
|
package/dist/result.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type NativeLixValue, Value } from "./value.js";
|
|
2
|
-
import type { ExecuteResult, LixValue } from "./types.js";
|
|
2
|
+
import type { ExecuteBatchResult, ExecuteResult, LixValue } from "./types.js";
|
|
3
3
|
export declare class Row {
|
|
4
4
|
private readonly columns;
|
|
5
5
|
private readonly values;
|
|
@@ -14,5 +14,6 @@ type NativeExecuteResult = Omit<ExecuteResult, "rows"> & {
|
|
|
14
14
|
rows: NativeLixValue[][];
|
|
15
15
|
};
|
|
16
16
|
export declare function wrapExecuteResult(result: NativeExecuteResult): ExecuteResult;
|
|
17
|
+
export declare function wrapExecuteBatchResult(result: NativeExecuteResult): ExecuteBatchResult;
|
|
17
18
|
export declare function normalizeOptionals<T>(value: T): T;
|
|
18
19
|
export {};
|
package/dist/result.js
CHANGED
|
@@ -36,6 +36,18 @@ export function wrapExecuteResult(result) {
|
|
|
36
36
|
rows: result.rows.map((row) => Row.fromRaw(result.columns, row.map(fromNativeValue))),
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
export function wrapExecuteBatchResult(result) {
|
|
40
|
+
const statementIndex = result.statementIndex;
|
|
41
|
+
if (typeof statementIndex !== "number" ||
|
|
42
|
+
!Number.isSafeInteger(statementIndex) ||
|
|
43
|
+
statementIndex < 0) {
|
|
44
|
+
throw new Error("executeBatch result is missing a valid statementIndex");
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
...wrapExecuteResult(result),
|
|
48
|
+
statementIndex,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
39
51
|
export function normalizeOptionals(value) {
|
|
40
52
|
if (Array.isArray(value))
|
|
41
53
|
return value.map(normalizeOptionals);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operations exposed to a storage adapter while its Lix is open.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally narrower than the engine binding. Storage packages
|
|
5
|
+
* receive only the controls required to manage their own persistence layer.
|
|
6
|
+
*/
|
|
7
|
+
export type LixStorageConnection = {
|
|
8
|
+
importFilesystemPaths(paths: string[]): Promise<void>;
|
|
9
|
+
syncDiskToLix(): Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
/** Engine configuration currently supported by external JavaScript storage packages. */
|
|
12
|
+
export type LixStorageAdapterConfig = {
|
|
13
|
+
kind: "filesystem";
|
|
14
|
+
path: string;
|
|
15
|
+
syncAllFiles: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Protocol implemented by JavaScript storage packages accepted by `openLix()`.
|
|
19
|
+
*
|
|
20
|
+
* Applications normally use a concrete package such as
|
|
21
|
+
* `@lix-js/storage-filesystem` rather than implementing this directly.
|
|
22
|
+
*/
|
|
23
|
+
export type LixStorage = {
|
|
24
|
+
readonly lixStorage: {
|
|
25
|
+
readonly version: 1;
|
|
26
|
+
readonly config: LixStorageAdapterConfig;
|
|
27
|
+
connect(connection: LixStorageConnection | undefined): void;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function isLixStorage(value: unknown): value is LixStorage;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function isLixStorage(value) {
|
|
2
|
+
if (!value || typeof value !== "object" || !("lixStorage" in value)) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
const adapter = value.lixStorage;
|
|
6
|
+
return Boolean(adapter &&
|
|
7
|
+
typeof adapter === "object" &&
|
|
8
|
+
adapter.version === 1 &&
|
|
9
|
+
typeof adapter.connect === "function" &&
|
|
10
|
+
adapter.config?.kind ===
|
|
11
|
+
"filesystem");
|
|
12
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
syncAllFiles: boolean;
|
|
1
|
+
export type IndexedDbStorageOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Identifies one persistent Lix database within the current origin.
|
|
4
|
+
* A database name can be opened by only one Lix handle at a time.
|
|
5
|
+
*/
|
|
6
|
+
name: string;
|
|
8
7
|
};
|
|
9
8
|
export type RemoteLixFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
10
9
|
export type RemoteLixServerOptions = {
|
|
@@ -24,27 +23,12 @@ export type LixTelemetrySpan = {
|
|
|
24
23
|
export type LixTelemetryOptions = {
|
|
25
24
|
onSpan(span: LixTelemetrySpan): void;
|
|
26
25
|
};
|
|
27
|
-
/**
|
|
28
|
-
* Persists opaque Lix snapshots under SDK-provided namespaces.
|
|
29
|
-
*
|
|
30
|
-
* Implementations must treat snapshots as bytes owned by Lix. The namespace
|
|
31
|
-
* selects one logical Lix and allows a single adapter to persist more than one
|
|
32
|
-
* instance without collisions.
|
|
33
|
-
*/
|
|
34
|
-
export interface LixSnapshotStorage {
|
|
35
|
-
load(namespace: string): Promise<Uint8Array | undefined>;
|
|
36
|
-
save(namespace: string, snapshot: Uint8Array): Promise<void>;
|
|
37
|
-
}
|
|
38
26
|
export type OpenLixOptions = {
|
|
39
|
-
storage?: import("./
|
|
27
|
+
storage?: import("./storage-adapter.js").LixStorage | import("./open-lix.js").IndexedDbStorage;
|
|
40
28
|
server?: never;
|
|
41
29
|
telemetry?: LixTelemetryOptions;
|
|
42
30
|
} | {
|
|
43
|
-
|
|
44
|
-
* Optional client-local storage. In remote mode workspace SQL remains on
|
|
45
|
-
* the server; only `lix.clientState` is stored here.
|
|
46
|
-
*/
|
|
47
|
-
storage?: LixSnapshotStorage;
|
|
31
|
+
storage?: never;
|
|
48
32
|
server: RemoteLixServerOptions;
|
|
49
33
|
telemetry?: never;
|
|
50
34
|
};
|
|
@@ -64,8 +48,11 @@ export type LixValue = {
|
|
|
64
48
|
kind: "text";
|
|
65
49
|
value: string;
|
|
66
50
|
} | {
|
|
67
|
-
kind: "
|
|
51
|
+
kind: "jsonb";
|
|
68
52
|
value: JsonValue;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "timestamptz";
|
|
55
|
+
value: string;
|
|
69
56
|
} | {
|
|
70
57
|
kind: "blob";
|
|
71
58
|
value: Uint8Array;
|
|
@@ -86,6 +73,7 @@ export type ExecuteOptions = {
|
|
|
86
73
|
export type LixBatchStatement = {
|
|
87
74
|
sql: string;
|
|
88
75
|
params?: readonly SqlParam[];
|
|
76
|
+
label?: string;
|
|
89
77
|
};
|
|
90
78
|
export type LixBatchOptions = {
|
|
91
79
|
originKey?: string;
|
|
@@ -93,6 +81,8 @@ export type LixBatchOptions = {
|
|
|
93
81
|
idempotencyKey?: string;
|
|
94
82
|
};
|
|
95
83
|
export type ExecuteResult = {
|
|
84
|
+
statementIndex?: number;
|
|
85
|
+
label?: string;
|
|
96
86
|
columns: string[];
|
|
97
87
|
rows: RowLike[];
|
|
98
88
|
rowsAffected: number;
|
|
@@ -102,9 +92,17 @@ export type ExecuteResult = {
|
|
|
102
92
|
hint?: string;
|
|
103
93
|
}>;
|
|
104
94
|
};
|
|
95
|
+
export type ExecuteBatchResult = ExecuteResult & {
|
|
96
|
+
statementIndex: number;
|
|
97
|
+
};
|
|
105
98
|
export type ObserveEvent = {
|
|
106
99
|
sequence: number;
|
|
107
100
|
mutationSequence: number;
|
|
101
|
+
/**
|
|
102
|
+
* The current result of the observed query. Remote observations reconcile
|
|
103
|
+
* the first frame of every stream through execute before publishing it, so
|
|
104
|
+
* reconnects cannot expose a stale server snapshot to consumers.
|
|
105
|
+
*/
|
|
108
106
|
result: ExecuteResult;
|
|
109
107
|
};
|
|
110
108
|
export type RowLike = {
|
|
@@ -180,9 +178,9 @@ export type MergeChangeStats = {
|
|
|
180
178
|
removed: number;
|
|
181
179
|
};
|
|
182
180
|
export type MergeConflict = {
|
|
183
|
-
kind: "
|
|
181
|
+
kind: "sameRowChanged";
|
|
184
182
|
schemaKey: string;
|
|
185
|
-
|
|
183
|
+
rowPk: unknown;
|
|
186
184
|
fileId: string | null;
|
|
187
185
|
target: MergeConflictSide;
|
|
188
186
|
source: MergeConflictSide;
|
package/dist/value.d.ts
CHANGED
|
@@ -8,7 +8,8 @@ export declare class Value {
|
|
|
8
8
|
static integer(value: number): Value;
|
|
9
9
|
static real(value: number): Value;
|
|
10
10
|
static text(value: string): Value;
|
|
11
|
-
static
|
|
11
|
+
static jsonb(value: JsonValue): Value;
|
|
12
|
+
static timestamptz(value: string): Value;
|
|
12
13
|
static blob(value: Uint8Array): Value;
|
|
13
14
|
static from(value: SqlParam): Value;
|
|
14
15
|
static _fromNative(value: LixValue): Value;
|
package/dist/value.js
CHANGED
|
@@ -2,9 +2,9 @@ import { invalidParam } from "./errors.js";
|
|
|
2
2
|
export class Value {
|
|
3
3
|
kind;
|
|
4
4
|
#raw;
|
|
5
|
-
constructor(raw) {
|
|
5
|
+
constructor(raw, clone = true) {
|
|
6
6
|
validateExplicitValue(raw);
|
|
7
|
-
this.#raw = cloneValue(raw);
|
|
7
|
+
this.#raw = clone ? cloneValue(raw) : raw;
|
|
8
8
|
this.kind = this.#raw.kind;
|
|
9
9
|
}
|
|
10
10
|
static null() {
|
|
@@ -22,8 +22,11 @@ export class Value {
|
|
|
22
22
|
static text(value) {
|
|
23
23
|
return new Value({ kind: "text", value });
|
|
24
24
|
}
|
|
25
|
-
static
|
|
26
|
-
return new Value({ kind: "
|
|
25
|
+
static jsonb(value) {
|
|
26
|
+
return new Value({ kind: "jsonb", value });
|
|
27
|
+
}
|
|
28
|
+
static timestamptz(value) {
|
|
29
|
+
return new Value({ kind: "timestamptz", value });
|
|
27
30
|
}
|
|
28
31
|
static blob(value) {
|
|
29
32
|
return new Value({ kind: "blob", value });
|
|
@@ -32,7 +35,11 @@ export class Value {
|
|
|
32
35
|
return new Value(normalizeParam(value));
|
|
33
36
|
}
|
|
34
37
|
static _fromNative(value) {
|
|
35
|
-
|
|
38
|
+
// Native execute results are newly materialized for this result set. Keep
|
|
39
|
+
// the native value as-is and defer the defensive copy until toJS(). This
|
|
40
|
+
// avoids cloning every structured result once during row wrapping and
|
|
41
|
+
// again when callers read it.
|
|
42
|
+
return new Value(value, false);
|
|
36
43
|
}
|
|
37
44
|
_toNative() {
|
|
38
45
|
return toNativeValue(this.#raw);
|
|
@@ -101,7 +108,7 @@ export function normalizeParam(value, index = 0, seen = new WeakSet()) {
|
|
|
101
108
|
throw invalidParam(index, "typed array SQL parameters must be Uint8Array", value.constructor.name);
|
|
102
109
|
}
|
|
103
110
|
assertJsonSerializable(value, seen, index);
|
|
104
|
-
return { kind: "
|
|
111
|
+
return { kind: "jsonb", value };
|
|
105
112
|
}
|
|
106
113
|
throw invalidParam(index, `${typeof value} is not a valid SQL parameter`, typeof value);
|
|
107
114
|
}
|
|
@@ -113,7 +120,8 @@ function unwrapValue(value) {
|
|
|
113
120
|
case "integer":
|
|
114
121
|
case "real":
|
|
115
122
|
case "text":
|
|
116
|
-
case "
|
|
123
|
+
case "timestamptz":
|
|
124
|
+
case "jsonb":
|
|
117
125
|
return cloneJsonValue(value.value);
|
|
118
126
|
case "blob":
|
|
119
127
|
return new Uint8Array(value.value);
|
|
@@ -193,9 +201,14 @@ function validateExplicitValue(value) {
|
|
|
193
201
|
throw invalidParam(0, "string SQL parameters must be well-formed UTF-16", "string");
|
|
194
202
|
}
|
|
195
203
|
return;
|
|
196
|
-
case "
|
|
204
|
+
case "jsonb":
|
|
197
205
|
assertJsonSerializable(value.value, new WeakSet(), 0);
|
|
198
206
|
return;
|
|
207
|
+
case "timestamptz":
|
|
208
|
+
if (typeof value.value === "string" && !Number.isNaN(Date.parse(value.value))) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
199
212
|
case "blob":
|
|
200
213
|
if (value.value instanceof Uint8Array)
|
|
201
214
|
return;
|
|
@@ -209,8 +222,8 @@ function cloneValue(value) {
|
|
|
209
222
|
if (value.kind === "blob") {
|
|
210
223
|
return { kind: "blob", value: new Uint8Array(value.value) };
|
|
211
224
|
}
|
|
212
|
-
if (value.kind === "
|
|
213
|
-
return { kind: "
|
|
225
|
+
if (value.kind === "jsonb") {
|
|
226
|
+
return { kind: "jsonb", value: cloneJsonValue(value.value) };
|
|
214
227
|
}
|
|
215
228
|
return value;
|
|
216
229
|
}
|
|
@@ -8,10 +8,6 @@ export class WasmLix {
|
|
|
8
8
|
activeAccountId(): Promise<string>;
|
|
9
9
|
activeBranchId(): Promise<string>;
|
|
10
10
|
beginTransaction(): Promise<WasmLixTransaction>;
|
|
11
|
-
clientStateDelete(key: string): Promise<void>;
|
|
12
|
-
clientStateEntries(): Promise<any>;
|
|
13
|
-
clientStateGet(key: string): Promise<any>;
|
|
14
|
-
clientStateSet(key: string, value: any): Promise<void>;
|
|
15
11
|
close(): Promise<void>;
|
|
16
12
|
createBranch(options: any): Promise<any>;
|
|
17
13
|
createCheckpoint(): Promise<any>;
|
|
@@ -43,6 +39,8 @@ export class WasmObserveEvents {
|
|
|
43
39
|
next(): Promise<any>;
|
|
44
40
|
}
|
|
45
41
|
|
|
42
|
+
export function openIndexedDb(backend: any, telemetry_dispatch?: Function | null): Promise<WasmLix>;
|
|
43
|
+
|
|
46
44
|
export function openMemory(telemetry_dispatch?: Function | null): Promise<WasmLix>;
|
|
47
45
|
|
|
48
46
|
export function openMemoryFromSnapshot(telemetry_dispatch?: Function | null, snapshot?: Uint8Array | null): Promise<WasmLix>;
|
|
@@ -56,16 +54,13 @@ export interface InitOutput {
|
|
|
56
54
|
readonly __wbg_wasmlix_free: (a: number, b: number) => void;
|
|
57
55
|
readonly __wbg_wasmlixtransaction_free: (a: number, b: number) => void;
|
|
58
56
|
readonly __wbg_wasmobserveevents_free: (a: number, b: number) => void;
|
|
57
|
+
readonly openIndexedDb: (a: number, b: number) => number;
|
|
59
58
|
readonly openMemory: (a: number) => number;
|
|
60
59
|
readonly openMemoryFromSnapshot: (a: number, b: number, c: number) => number;
|
|
61
60
|
readonly parseSqlScript: (a: number, b: number, c: number, d: number) => void;
|
|
62
61
|
readonly wasmlix_activeAccountId: (a: number) => number;
|
|
63
62
|
readonly wasmlix_activeBranchId: (a: number) => number;
|
|
64
63
|
readonly wasmlix_beginTransaction: (a: number) => number;
|
|
65
|
-
readonly wasmlix_clientStateDelete: (a: number, b: number, c: number) => number;
|
|
66
|
-
readonly wasmlix_clientStateEntries: (a: number) => number;
|
|
67
|
-
readonly wasmlix_clientStateGet: (a: number, b: number, c: number) => number;
|
|
68
|
-
readonly wasmlix_clientStateSet: (a: number, b: number, c: number, d: number) => number;
|
|
69
64
|
readonly wasmlix_close: (a: number) => number;
|
|
70
65
|
readonly wasmlix_createBranch: (a: number, b: number) => number;
|
|
71
66
|
readonly wasmlix_createCheckpoint: (a: number) => number;
|
|
@@ -83,8 +78,8 @@ export interface InitOutput {
|
|
|
83
78
|
readonly wasmlixtransaction_rollback: (a: number) => number;
|
|
84
79
|
readonly wasmobserveevents_close: (a: number) => void;
|
|
85
80
|
readonly wasmobserveevents_next: (a: number) => number;
|
|
86
|
-
readonly
|
|
87
|
-
readonly
|
|
81
|
+
readonly __wasm_bindgen_func_elem_119239: (a: number, b: number, c: number, d: number) => void;
|
|
82
|
+
readonly __wasm_bindgen_func_elem_119241: (a: number, b: number, c: number, d: number) => void;
|
|
88
83
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
89
84
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
90
85
|
readonly __wbindgen_export3: (a: number) => void;
|