@korajs/store 1.0.0-beta.11 → 1.0.0-beta.13
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 +29 -37
- package/dist/adapters/better-sqlite3.cjs +90 -4
- package/dist/adapters/better-sqlite3.cjs.map +1 -1
- package/dist/adapters/better-sqlite3.d.cts +21 -12
- package/dist/adapters/better-sqlite3.d.ts +21 -12
- package/dist/adapters/better-sqlite3.js +69 -5
- package/dist/adapters/better-sqlite3.js.map +1 -1
- package/dist/adapters/indexeddb.cjs +1316 -610
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.d.cts +29 -3
- package/dist/adapters/indexeddb.d.ts +29 -3
- package/dist/adapters/indexeddb.js +247 -221
- package/dist/adapters/indexeddb.js.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.cjs +803 -62
- package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.js +480 -62
- package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
- package/dist/adapters/sqlite-wasm.cjs +1032 -344
- package/dist/adapters/sqlite-wasm.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm.d.cts +239 -18
- package/dist/adapters/sqlite-wasm.d.ts +239 -18
- package/dist/adapters/sqlite-wasm.js +111 -5
- package/dist/adapters/sqlite-wasm.js.map +1 -1
- package/dist/backup-4NUPDEMB.js +25 -0
- package/dist/chunk-32EDKWMI.js +876 -0
- package/dist/chunk-32EDKWMI.js.map +1 -0
- package/dist/{chunk-CYO3YKFL.js → chunk-5ZRRF6R2.js} +2 -2
- package/dist/chunk-A6GFH5IG.js +36 -0
- package/dist/chunk-A6GFH5IG.js.map +1 -0
- package/dist/chunk-DUKTWVZW.js +175 -0
- package/dist/chunk-DUKTWVZW.js.map +1 -0
- package/dist/chunk-HZTDBLDB.js +607 -0
- package/dist/chunk-HZTDBLDB.js.map +1 -0
- package/dist/{chunk-GSJ7EEUC.js → chunk-J5AGXF3D.js} +58 -9
- package/dist/chunk-J5AGXF3D.js.map +1 -0
- package/dist/chunk-MCQKEHOD.js +112 -0
- package/dist/chunk-MCQKEHOD.js.map +1 -0
- package/dist/chunk-P4V375FY.js +810 -0
- package/dist/chunk-P4V375FY.js.map +1 -0
- package/dist/chunk-QDUSJMFV.js +1095 -0
- package/dist/chunk-QDUSJMFV.js.map +1 -0
- package/dist/chunk-SJP2HTYZ.js +1003 -0
- package/dist/chunk-SJP2HTYZ.js.map +1 -0
- package/dist/chunk-W5F2LWG6.js +591 -0
- package/dist/chunk-W5F2LWG6.js.map +1 -0
- package/dist/chunk-Y5LRH7KI.js +5341 -0
- package/dist/chunk-Y5LRH7KI.js.map +1 -0
- package/dist/{export-audit-ODGQTQIK.js → export-audit-J2QXRHD2.js} +3 -3
- package/dist/index.cjs +9354 -4157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1064 -108
- package/dist/index.d.ts +1064 -108
- package/dist/index.js +249 -3092
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +580 -264
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +15 -85
- package/dist/internal.d.ts +15 -85
- package/dist/internal.js +10 -8
- package/dist/restore-FR7XIKT2.js +299 -0
- package/dist/restore-FR7XIKT2.js.map +1 -0
- package/dist/sql-builder-C4u55jKW.d.cts +608 -0
- package/dist/sql-builder-CGckdBDL.d.ts +608 -0
- package/dist/sqlite-wasm-channel-DVX93Uiq.d.cts +141 -0
- package/dist/sqlite-wasm-channel-DVX93Uiq.d.ts +141 -0
- package/dist/sqlite-wasm-channel-MLHLKEED.js +12 -0
- package/dist/store-IMWKZLWB.js +16 -0
- package/dist/store-IMWKZLWB.js.map +1 -0
- package/dist/{types-BslDOTk0.d.ts → types-Dh-xyUjP.d.cts} +99 -26
- package/dist/{types-BslDOTk0.d.cts → types-Dh-xyUjP.d.ts} +99 -26
- package/package.json +3 -2
- package/dist/backup-5S7K2Z35.js +0 -14
- package/dist/chunk-GSJ7EEUC.js.map +0 -1
- package/dist/chunk-HS6DBMST.js +0 -383
- package/dist/chunk-HS6DBMST.js.map +0 -1
- package/dist/chunk-RJIEKEN4.js +0 -751
- package/dist/chunk-RJIEKEN4.js.map +0 -1
- package/dist/chunk-TUR7RGEP.js +0 -84
- package/dist/chunk-TUR7RGEP.js.map +0 -1
- package/dist/chunk-VDBJQ75K.js +0 -78
- package/dist/chunk-VDBJQ75K.js.map +0 -1
- package/dist/chunk-YT7MRFCP.js +0 -687
- package/dist/chunk-YT7MRFCP.js.map +0 -1
- package/dist/sqlite-wasm-channel-GGHA2BXU.js +0 -12
- package/dist/sqlite-wasm-channel-L6o3bWQK.d.cts +0 -92
- package/dist/sqlite-wasm-channel-L6o3bWQK.d.ts +0 -92
- package/dist/types-BOO9EPt1.d.ts +0 -170
- package/dist/types-C_GDavG-.d.cts +0 -170
- /package/dist/{backup-5S7K2Z35.js.map → backup-4NUPDEMB.js.map} +0 -0
- /package/dist/{chunk-CYO3YKFL.js.map → chunk-5ZRRF6R2.js.map} +0 -0
- /package/dist/{export-audit-ODGQTQIK.js.map → export-audit-J2QXRHD2.js.map} +0 -0
- /package/dist/{sqlite-wasm-channel-GGHA2BXU.js.map → sqlite-wasm-channel-MLHLKEED.js.map} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/** Fields every request carries besides its type. */
|
|
2
|
+
interface RequestMeta {
|
|
3
|
+
/** Correlates a worker response with its request on one postMessage channel. */
|
|
4
|
+
id: number;
|
|
5
|
+
/**
|
|
6
|
+
* Stable id for de-duplication. A follower retrying a request (after a
|
|
7
|
+
* `LeaderUnresponsiveError`, say) sends the same id and the leader worker
|
|
8
|
+
* answers from its response cache instead of applying it twice.
|
|
9
|
+
*/
|
|
10
|
+
requestId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Request message sent from the main thread (or a follower tab) to the SQLite
|
|
14
|
+
* WASM worker.
|
|
15
|
+
*/
|
|
16
|
+
type WorkerRequest = (RequestMeta & {
|
|
17
|
+
type: 'open';
|
|
18
|
+
ddlStatements: string[];
|
|
19
|
+
dbName?: string;
|
|
20
|
+
/**
|
|
21
|
+
* `memory` opens an in-memory database without touching OPFS (the
|
|
22
|
+
* IndexedDB adapter persists snapshots itself). Defaults to `opfs`.
|
|
23
|
+
*/
|
|
24
|
+
storage?: 'opfs' | 'memory';
|
|
25
|
+
/** Fail with `NOT_FOUND` instead of creating the database file. */
|
|
26
|
+
mustExist?: boolean;
|
|
27
|
+
}) | (RequestMeta & {
|
|
28
|
+
type: 'close';
|
|
29
|
+
}) | (RequestMeta & {
|
|
30
|
+
type: 'destroy';
|
|
31
|
+
}) | (RequestMeta & {
|
|
32
|
+
type: 'execute';
|
|
33
|
+
sql: string;
|
|
34
|
+
params?: unknown[];
|
|
35
|
+
}) | (RequestMeta & {
|
|
36
|
+
type: 'query';
|
|
37
|
+
sql: string;
|
|
38
|
+
params?: unknown[];
|
|
39
|
+
}) | (RequestMeta & {
|
|
40
|
+
type: 'begin';
|
|
41
|
+
}) | (RequestMeta & {
|
|
42
|
+
type: 'commit';
|
|
43
|
+
}) | (RequestMeta & {
|
|
44
|
+
type: 'rollback';
|
|
45
|
+
}) | (RequestMeta & {
|
|
46
|
+
type: 'migrate';
|
|
47
|
+
from: number;
|
|
48
|
+
to: number;
|
|
49
|
+
statements: string[];
|
|
50
|
+
}) | (RequestMeta & {
|
|
51
|
+
type: 'export';
|
|
52
|
+
}) | (RequestMeta & {
|
|
53
|
+
type: 'import';
|
|
54
|
+
data: Uint8Array;
|
|
55
|
+
}) | (RequestMeta & {
|
|
56
|
+
/**
|
|
57
|
+
* Leader worker only: answer follower RPC, pings and heartbeats on this
|
|
58
|
+
* BroadcastChannel directly, so a hung leader main thread never blocks
|
|
59
|
+
* other tabs (NEW-STORE-9).
|
|
60
|
+
*/
|
|
61
|
+
type: 'serve';
|
|
62
|
+
channelName: string;
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Response message sent from the worker back to the main thread.
|
|
66
|
+
* Matches the request `id` for correlation.
|
|
67
|
+
*/
|
|
68
|
+
type WorkerResponse = {
|
|
69
|
+
id: number;
|
|
70
|
+
type: 'success';
|
|
71
|
+
data?: unknown;
|
|
72
|
+
} | {
|
|
73
|
+
id: number;
|
|
74
|
+
type: 'error';
|
|
75
|
+
message: string;
|
|
76
|
+
code: string;
|
|
77
|
+
context?: Record<string, unknown>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Unsolicited status the worker reports while it works on a request, such as
|
|
81
|
+
* waiting for another holder of the OPFS pool (a blocking state the app shows).
|
|
82
|
+
*/
|
|
83
|
+
type WorkerStatusEvent = {
|
|
84
|
+
kind: 'storage-blocked';
|
|
85
|
+
resource: 'pool' | 'legacy-pool';
|
|
86
|
+
poolName: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'storage-unblocked';
|
|
89
|
+
resource: 'pool' | 'legacy-pool';
|
|
90
|
+
poolName: string;
|
|
91
|
+
waitedMs: number;
|
|
92
|
+
};
|
|
93
|
+
/** Per-request options accepted by bridges. */
|
|
94
|
+
interface WorkerSendOptions {
|
|
95
|
+
/** Cancels the wait for the response (the worker may still apply the request). */
|
|
96
|
+
signal?: AbortSignal;
|
|
97
|
+
/** Overrides the bridge timeout for this request; `Infinity` disables it. */
|
|
98
|
+
timeoutMs?: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Abstraction over the communication channel with the SQLite WASM worker.
|
|
102
|
+
* In browsers, this is backed by a real Web Worker via MessagePort.
|
|
103
|
+
* In Node.js tests, this is backed by better-sqlite3 via MockWorkerBridge.
|
|
104
|
+
*/
|
|
105
|
+
interface WorkerBridge {
|
|
106
|
+
/** Send a request to the worker and wait for a response. */
|
|
107
|
+
send(request: WorkerRequest, clientId?: string, options?: WorkerSendOptions): Promise<WorkerResponse>;
|
|
108
|
+
/** Terminate the worker. Safe to call multiple times. */
|
|
109
|
+
terminate(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Options for {@link WebWorkerBridge}. */
|
|
113
|
+
interface WebWorkerBridgeOptions {
|
|
114
|
+
/** Receives status events (blocking state) the worker reports. */
|
|
115
|
+
onEvent?: (event: WorkerStatusEvent) => void;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* WorkerBridge implementation for browser environments.
|
|
119
|
+
* Communicates with an actual Web Worker running SQLite WASM.
|
|
120
|
+
*/
|
|
121
|
+
declare class WebWorkerBridge implements WorkerBridge {
|
|
122
|
+
private worker;
|
|
123
|
+
private pending;
|
|
124
|
+
private nextId;
|
|
125
|
+
private terminated;
|
|
126
|
+
private timeoutMs;
|
|
127
|
+
/**
|
|
128
|
+
* @param workerUrl - URL to the sqlite-wasm-worker script
|
|
129
|
+
* @param timeoutMs - Timeout for worker responses in milliseconds (default: 30000)
|
|
130
|
+
* @param options - Status event listener
|
|
131
|
+
*/
|
|
132
|
+
constructor(workerUrl: string | URL, timeoutMs?: number, options?: WebWorkerBridgeOptions);
|
|
133
|
+
/** True once {@link terminate} ran. */
|
|
134
|
+
isTerminated(): boolean;
|
|
135
|
+
/** Post a request without awaiting a response (fire-and-forget control messages). */
|
|
136
|
+
post(request: WorkerRequest, clientId?: string): void;
|
|
137
|
+
send(request: WorkerRequest, clientId?: string, options?: WorkerSendOptions): Promise<WorkerResponse>;
|
|
138
|
+
terminate(): void;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { type WorkerBridge as W, WebWorkerBridge as a, type WorkerRequest as b, type WorkerResponse as c, type WorkerSendOptions as d, type WorkerStatusEvent as e };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/** Fields every request carries besides its type. */
|
|
2
|
+
interface RequestMeta {
|
|
3
|
+
/** Correlates a worker response with its request on one postMessage channel. */
|
|
4
|
+
id: number;
|
|
5
|
+
/**
|
|
6
|
+
* Stable id for de-duplication. A follower retrying a request (after a
|
|
7
|
+
* `LeaderUnresponsiveError`, say) sends the same id and the leader worker
|
|
8
|
+
* answers from its response cache instead of applying it twice.
|
|
9
|
+
*/
|
|
10
|
+
requestId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Request message sent from the main thread (or a follower tab) to the SQLite
|
|
14
|
+
* WASM worker.
|
|
15
|
+
*/
|
|
16
|
+
type WorkerRequest = (RequestMeta & {
|
|
17
|
+
type: 'open';
|
|
18
|
+
ddlStatements: string[];
|
|
19
|
+
dbName?: string;
|
|
20
|
+
/**
|
|
21
|
+
* `memory` opens an in-memory database without touching OPFS (the
|
|
22
|
+
* IndexedDB adapter persists snapshots itself). Defaults to `opfs`.
|
|
23
|
+
*/
|
|
24
|
+
storage?: 'opfs' | 'memory';
|
|
25
|
+
/** Fail with `NOT_FOUND` instead of creating the database file. */
|
|
26
|
+
mustExist?: boolean;
|
|
27
|
+
}) | (RequestMeta & {
|
|
28
|
+
type: 'close';
|
|
29
|
+
}) | (RequestMeta & {
|
|
30
|
+
type: 'destroy';
|
|
31
|
+
}) | (RequestMeta & {
|
|
32
|
+
type: 'execute';
|
|
33
|
+
sql: string;
|
|
34
|
+
params?: unknown[];
|
|
35
|
+
}) | (RequestMeta & {
|
|
36
|
+
type: 'query';
|
|
37
|
+
sql: string;
|
|
38
|
+
params?: unknown[];
|
|
39
|
+
}) | (RequestMeta & {
|
|
40
|
+
type: 'begin';
|
|
41
|
+
}) | (RequestMeta & {
|
|
42
|
+
type: 'commit';
|
|
43
|
+
}) | (RequestMeta & {
|
|
44
|
+
type: 'rollback';
|
|
45
|
+
}) | (RequestMeta & {
|
|
46
|
+
type: 'migrate';
|
|
47
|
+
from: number;
|
|
48
|
+
to: number;
|
|
49
|
+
statements: string[];
|
|
50
|
+
}) | (RequestMeta & {
|
|
51
|
+
type: 'export';
|
|
52
|
+
}) | (RequestMeta & {
|
|
53
|
+
type: 'import';
|
|
54
|
+
data: Uint8Array;
|
|
55
|
+
}) | (RequestMeta & {
|
|
56
|
+
/**
|
|
57
|
+
* Leader worker only: answer follower RPC, pings and heartbeats on this
|
|
58
|
+
* BroadcastChannel directly, so a hung leader main thread never blocks
|
|
59
|
+
* other tabs (NEW-STORE-9).
|
|
60
|
+
*/
|
|
61
|
+
type: 'serve';
|
|
62
|
+
channelName: string;
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Response message sent from the worker back to the main thread.
|
|
66
|
+
* Matches the request `id` for correlation.
|
|
67
|
+
*/
|
|
68
|
+
type WorkerResponse = {
|
|
69
|
+
id: number;
|
|
70
|
+
type: 'success';
|
|
71
|
+
data?: unknown;
|
|
72
|
+
} | {
|
|
73
|
+
id: number;
|
|
74
|
+
type: 'error';
|
|
75
|
+
message: string;
|
|
76
|
+
code: string;
|
|
77
|
+
context?: Record<string, unknown>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Unsolicited status the worker reports while it works on a request, such as
|
|
81
|
+
* waiting for another holder of the OPFS pool (a blocking state the app shows).
|
|
82
|
+
*/
|
|
83
|
+
type WorkerStatusEvent = {
|
|
84
|
+
kind: 'storage-blocked';
|
|
85
|
+
resource: 'pool' | 'legacy-pool';
|
|
86
|
+
poolName: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'storage-unblocked';
|
|
89
|
+
resource: 'pool' | 'legacy-pool';
|
|
90
|
+
poolName: string;
|
|
91
|
+
waitedMs: number;
|
|
92
|
+
};
|
|
93
|
+
/** Per-request options accepted by bridges. */
|
|
94
|
+
interface WorkerSendOptions {
|
|
95
|
+
/** Cancels the wait for the response (the worker may still apply the request). */
|
|
96
|
+
signal?: AbortSignal;
|
|
97
|
+
/** Overrides the bridge timeout for this request; `Infinity` disables it. */
|
|
98
|
+
timeoutMs?: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Abstraction over the communication channel with the SQLite WASM worker.
|
|
102
|
+
* In browsers, this is backed by a real Web Worker via MessagePort.
|
|
103
|
+
* In Node.js tests, this is backed by better-sqlite3 via MockWorkerBridge.
|
|
104
|
+
*/
|
|
105
|
+
interface WorkerBridge {
|
|
106
|
+
/** Send a request to the worker and wait for a response. */
|
|
107
|
+
send(request: WorkerRequest, clientId?: string, options?: WorkerSendOptions): Promise<WorkerResponse>;
|
|
108
|
+
/** Terminate the worker. Safe to call multiple times. */
|
|
109
|
+
terminate(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Options for {@link WebWorkerBridge}. */
|
|
113
|
+
interface WebWorkerBridgeOptions {
|
|
114
|
+
/** Receives status events (blocking state) the worker reports. */
|
|
115
|
+
onEvent?: (event: WorkerStatusEvent) => void;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* WorkerBridge implementation for browser environments.
|
|
119
|
+
* Communicates with an actual Web Worker running SQLite WASM.
|
|
120
|
+
*/
|
|
121
|
+
declare class WebWorkerBridge implements WorkerBridge {
|
|
122
|
+
private worker;
|
|
123
|
+
private pending;
|
|
124
|
+
private nextId;
|
|
125
|
+
private terminated;
|
|
126
|
+
private timeoutMs;
|
|
127
|
+
/**
|
|
128
|
+
* @param workerUrl - URL to the sqlite-wasm-worker script
|
|
129
|
+
* @param timeoutMs - Timeout for worker responses in milliseconds (default: 30000)
|
|
130
|
+
* @param options - Status event listener
|
|
131
|
+
*/
|
|
132
|
+
constructor(workerUrl: string | URL, timeoutMs?: number, options?: WebWorkerBridgeOptions);
|
|
133
|
+
/** True once {@link terminate} ran. */
|
|
134
|
+
isTerminated(): boolean;
|
|
135
|
+
/** Post a request without awaiting a response (fire-and-forget control messages). */
|
|
136
|
+
post(request: WorkerRequest, clientId?: string): void;
|
|
137
|
+
send(request: WorkerRequest, clientId?: string, options?: WorkerSendOptions): Promise<WorkerResponse>;
|
|
138
|
+
terminate(): void;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { type WorkerBridge as W, WebWorkerBridge as a, type WorkerRequest as b, type WorkerResponse as c, type WorkerSendOptions as d, type WorkerStatusEvent as e };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReservedNodeIdError,
|
|
3
|
+
Store
|
|
4
|
+
} from "./chunk-Y5LRH7KI.js";
|
|
5
|
+
import "./chunk-HZTDBLDB.js";
|
|
6
|
+
import "./chunk-A6GFH5IG.js";
|
|
7
|
+
import "./chunk-P4V375FY.js";
|
|
8
|
+
import "./chunk-32EDKWMI.js";
|
|
9
|
+
import "./chunk-SJP2HTYZ.js";
|
|
10
|
+
import "./chunk-J5AGXF3D.js";
|
|
11
|
+
import "./chunk-DUKTWVZW.js";
|
|
12
|
+
export {
|
|
13
|
+
ReservedNodeIdError,
|
|
14
|
+
Store
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=store-IMWKZLWB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _korajs_core from '@korajs/core';
|
|
2
|
+
import { HLCTimestamp, SchemaDefinition, Operation, KoraEventEmitter, SecretKeyProvider, OperationTransform } from '@korajs/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Transaction interface for executing multiple operations atomically.
|
|
@@ -22,6 +23,14 @@ interface StorageOpenState {
|
|
|
22
23
|
mode: 'opfs' | 'indexeddb' | 'memory' | 'native' | 'unknown';
|
|
23
24
|
/** Present when a primary storage mode degraded during open. */
|
|
24
25
|
fallbackReason?: StorageFallbackReason;
|
|
26
|
+
/** OPFS pool that owns the database file (one pool per database), when known. */
|
|
27
|
+
poolName?: string;
|
|
28
|
+
/**
|
|
29
|
+
* SQLite journal mode the database actually runs with, when known (NEW-STORE-11).
|
|
30
|
+
* OPFS (opfs-sahpool): `delete`, the rollback journal; WAL is not available on
|
|
31
|
+
* that VFS. In-memory fallback: `memory`. Native better-sqlite3: `wal`.
|
|
32
|
+
*/
|
|
33
|
+
journalMode?: string;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
36
|
* Storage adapter interface. All storage backends must implement this.
|
|
@@ -46,39 +55,32 @@ interface StorageAdapter {
|
|
|
46
55
|
* fallback before app code starts reading or writing user data.
|
|
47
56
|
*/
|
|
48
57
|
getStorageOpenState?(): StorageOpenState | null;
|
|
58
|
+
/**
|
|
59
|
+
* Optional durability barrier (RT-35): resolve once every write committed before the
|
|
60
|
+
* call is durable, reject when it cannot be made durable. Adapters whose commits are
|
|
61
|
+
* durable when they resolve (SQLite on a file or OPFS) omit it; an adapter that
|
|
62
|
+
* persists asynchronously (the IndexedDB snapshot fallback) must implement it.
|
|
63
|
+
*/
|
|
64
|
+
ensureDurable?(): Promise<void>;
|
|
49
65
|
}
|
|
50
66
|
/**
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
sql: string;
|
|
57
|
-
params: unknown[];
|
|
58
|
-
}>;
|
|
59
|
-
collection: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Batch passed to {@link LocalMutationHandler.commitTransaction} on commit.
|
|
67
|
+
* Routes local mutations through a unified apply pipeline (korajs ApplyPipeline).
|
|
68
|
+
*
|
|
69
|
+
* Every local write — including each entry of an `app.transaction` commit — is
|
|
70
|
+
* built and persisted by the store's single local write path; the handler adds
|
|
71
|
+
* pipeline behaviour around it.
|
|
63
72
|
*/
|
|
64
|
-
interface TransactionCommitBatch {
|
|
65
|
-
entries: TransactionBufferedEntry[];
|
|
66
|
-
transactionId: string;
|
|
67
|
-
mutationName?: string;
|
|
68
|
-
}
|
|
69
|
-
interface TransactionCommitResult {
|
|
70
|
-
operations: Operation[];
|
|
71
|
-
affectedCollections: Set<string>;
|
|
72
|
-
}
|
|
73
73
|
interface LocalMutationHandler {
|
|
74
74
|
insert(collection: string, data: Record<string, unknown>): Promise<CollectionRecord>;
|
|
75
75
|
update(collection: string, id: string, data: Record<string, unknown>): Promise<CollectionRecord>;
|
|
76
76
|
delete(collection: string, id: string): Promise<void>;
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
78
|
+
* Called inside the write transaction for every local delete (single-record,
|
|
79
|
+
* transactional and cascaded), after the delete operation is built and before
|
|
80
|
+
* referential side effects run. Reads must go through `tx`. Throwing aborts
|
|
81
|
+
* the whole write.
|
|
80
82
|
*/
|
|
81
|
-
|
|
83
|
+
beforeLocalDelete?(operation: Operation, tx: Transaction): Promise<void>;
|
|
82
84
|
}
|
|
83
85
|
type StoreIsolation = 'shared' | 'per-tab';
|
|
84
86
|
interface StoreConfig {
|
|
@@ -104,6 +106,30 @@ interface StoreConfig {
|
|
|
104
106
|
* Required only when the schema declares encrypted secret fields.
|
|
105
107
|
*/
|
|
106
108
|
secretKeyProvider?: SecretKeyProvider;
|
|
109
|
+
/**
|
|
110
|
+
* How rows are materialized. `'fold'` (default, W7): every write merges into the
|
|
111
|
+
* record's per-field CRDT fold state, which re-materializes the row. `'legacy'`:
|
|
112
|
+
* the beta.12 per-field LWW write paths (used by `experimental.legacyMerge` for
|
|
113
|
+
* one beta, to compare). Switching modes on an existing database re-materializes
|
|
114
|
+
* it on open.
|
|
115
|
+
*/
|
|
116
|
+
materialization?: 'fold' | 'legacy';
|
|
117
|
+
/**
|
|
118
|
+
* Schema transforms applied at fold time (RT-84): an operation authored under an
|
|
119
|
+
* older schema version is stored exactly as written and folded as
|
|
120
|
+
* `operationSchemaView(op, schema.version, transforms)` reads it. Pass the same list
|
|
121
|
+
* as the sync engine's `operationTransforms` (`createApp` does). Transforms must be
|
|
122
|
+
* pure and deterministic; they are part of the fold plan fingerprint, so changing
|
|
123
|
+
* them re-folds once.
|
|
124
|
+
*/
|
|
125
|
+
operationTransforms?: readonly OperationTransform[];
|
|
126
|
+
/**
|
|
127
|
+
* Largest serialized operation a local write may produce, in bytes (RT-86). Set it to
|
|
128
|
+
* the sync server's `maxOperationBytes`. A write over it is refused with
|
|
129
|
+
* `OperationTooLargeError` and nothing is written. Default 256 KiB, the server's
|
|
130
|
+
* default.
|
|
131
|
+
*/
|
|
132
|
+
maxOperationBytes?: number;
|
|
107
133
|
}
|
|
108
134
|
/**
|
|
109
135
|
* Operators for where clause conditions.
|
|
@@ -150,6 +176,38 @@ interface QueryDescriptor {
|
|
|
150
176
|
* Callback for reactive subscriptions. Receives the current result set.
|
|
151
177
|
*/
|
|
152
178
|
type SubscriptionCallback<T> = (results: T[]) => void;
|
|
179
|
+
/**
|
|
180
|
+
* Where a subscription failure happened.
|
|
181
|
+
* - `initial`: the first run of the query, before any result was delivered.
|
|
182
|
+
* - `refresh`: a re-run after a write to a collection the query reads.
|
|
183
|
+
* - `callback`: the query succeeded but the subscriber's own callback threw.
|
|
184
|
+
*/
|
|
185
|
+
type QueryErrorPhase = 'initial' | 'refresh' | 'callback';
|
|
186
|
+
/**
|
|
187
|
+
* A failure delivered to a subscriber's `onError` (STORE-12). The previous result
|
|
188
|
+
* set stays current; the subscription stays registered and is re-run on the next
|
|
189
|
+
* write, and a later success is delivered even if it equals the last results.
|
|
190
|
+
*/
|
|
191
|
+
interface QuerySubscriptionError {
|
|
192
|
+
/** The error thrown by the query or the callback. */
|
|
193
|
+
error: Error;
|
|
194
|
+
phase: QueryErrorPhase;
|
|
195
|
+
/** The collection the query reads. */
|
|
196
|
+
collection: string;
|
|
197
|
+
/** Subscription id, the same `queryId` carried by the `query:error` event. */
|
|
198
|
+
queryId: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Options for `QueryBuilder.subscribe()`.
|
|
202
|
+
*/
|
|
203
|
+
interface SubscribeOptions {
|
|
204
|
+
/**
|
|
205
|
+
* Called when the query fails (or the callback throws) instead of the failure
|
|
206
|
+
* becoming an unhandled rejection. Every failure is also emitted as a
|
|
207
|
+
* `query:error` event; without `onError` it is additionally logged.
|
|
208
|
+
*/
|
|
209
|
+
onError?: (failure: QuerySubscriptionError) => void;
|
|
210
|
+
}
|
|
153
211
|
/**
|
|
154
212
|
* Serialized row in the operations log table.
|
|
155
213
|
*/
|
|
@@ -198,12 +256,27 @@ interface Subscription<T = CollectionRecord> {
|
|
|
198
256
|
callback: SubscriptionCallback<T>;
|
|
199
257
|
executeFn: () => Promise<T[]>;
|
|
200
258
|
lastResults: T[];
|
|
259
|
+
/** Result-set comparator (structural, per field kind). */
|
|
260
|
+
resultsEqual?: (prev: readonly T[], next: readonly T[]) => boolean;
|
|
261
|
+
onError?: (failure: QuerySubscriptionError) => void;
|
|
262
|
+
/** Monotonic run counter: a slower, older run never overwrites a newer result. */
|
|
263
|
+
runsStarted?: number;
|
|
264
|
+
lastAppliedRun?: number;
|
|
265
|
+
/** True after a failure until the next successful delivery. */
|
|
266
|
+
errored?: boolean;
|
|
267
|
+
/** True once a result set has been delivered to the callback. */
|
|
268
|
+
delivered?: boolean;
|
|
201
269
|
}
|
|
202
270
|
|
|
203
271
|
/**
|
|
204
272
|
* Options for applying a remote operation to materialized storage.
|
|
205
273
|
*/
|
|
206
274
|
interface ApplyRemoteOptions {
|
|
275
|
+
/**
|
|
276
|
+
* W7: receives the merge traces of the operation (conflicting field decisions),
|
|
277
|
+
* after commit. The store also emits them as `merge:*` events.
|
|
278
|
+
*/
|
|
279
|
+
onMergeTraces?: (traces: _korajs_core.MergeTrace[]) => void;
|
|
207
280
|
/** When true, a winning remote update clears soft-delete on the row. */
|
|
208
281
|
reactivateIfDeleted?: boolean;
|
|
209
282
|
/**
|
|
@@ -280,4 +353,4 @@ interface VersionVectorRow {
|
|
|
280
353
|
sequence_number: number;
|
|
281
354
|
}
|
|
282
355
|
|
|
283
|
-
export type { ApplyRemoteOptions as A, CollectionRecord as C, LocalMutationHandler as L, MigrationPlan as M, OperationRow as O, QueryDescriptor as Q, RawCollectionRow as R, StorageAdapter as S, Transaction as T, VersionVectorRow as V, WhereClause as W, StorageOpenState as a, MetaRow as b, Subscription as c,
|
|
356
|
+
export type { ApplyRemoteOptions as A, CollectionRecord as C, LocalMutationHandler as L, MigrationPlan as M, OperationRow as O, QueryDescriptor as Q, RawCollectionRow as R, StorageAdapter as S, Transaction as T, VersionVectorRow as V, WhereClause as W, StorageOpenState as a, MetaRow as b, Subscription as c, QuerySubscriptionError as d, SubscriptionCallback as e, SubscribeOptions as f, OrderByDirection as g, StoreConfig as h, MaterializedRowSnapshot as i, RowVersionState as j, OrderByClause as k, QueryErrorPhase as l, StorageFallbackReason as m, StoreIsolation as n, WhereOperators as o };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _korajs_core from '@korajs/core';
|
|
2
|
+
import { HLCTimestamp, SchemaDefinition, Operation, KoraEventEmitter, SecretKeyProvider, OperationTransform } from '@korajs/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Transaction interface for executing multiple operations atomically.
|
|
@@ -22,6 +23,14 @@ interface StorageOpenState {
|
|
|
22
23
|
mode: 'opfs' | 'indexeddb' | 'memory' | 'native' | 'unknown';
|
|
23
24
|
/** Present when a primary storage mode degraded during open. */
|
|
24
25
|
fallbackReason?: StorageFallbackReason;
|
|
26
|
+
/** OPFS pool that owns the database file (one pool per database), when known. */
|
|
27
|
+
poolName?: string;
|
|
28
|
+
/**
|
|
29
|
+
* SQLite journal mode the database actually runs with, when known (NEW-STORE-11).
|
|
30
|
+
* OPFS (opfs-sahpool): `delete`, the rollback journal; WAL is not available on
|
|
31
|
+
* that VFS. In-memory fallback: `memory`. Native better-sqlite3: `wal`.
|
|
32
|
+
*/
|
|
33
|
+
journalMode?: string;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
36
|
* Storage adapter interface. All storage backends must implement this.
|
|
@@ -46,39 +55,32 @@ interface StorageAdapter {
|
|
|
46
55
|
* fallback before app code starts reading or writing user data.
|
|
47
56
|
*/
|
|
48
57
|
getStorageOpenState?(): StorageOpenState | null;
|
|
58
|
+
/**
|
|
59
|
+
* Optional durability barrier (RT-35): resolve once every write committed before the
|
|
60
|
+
* call is durable, reject when it cannot be made durable. Adapters whose commits are
|
|
61
|
+
* durable when they resolve (SQLite on a file or OPFS) omit it; an adapter that
|
|
62
|
+
* persists asynchronously (the IndexedDB snapshot fallback) must implement it.
|
|
63
|
+
*/
|
|
64
|
+
ensureDurable?(): Promise<void>;
|
|
49
65
|
}
|
|
50
66
|
/**
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
sql: string;
|
|
57
|
-
params: unknown[];
|
|
58
|
-
}>;
|
|
59
|
-
collection: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Batch passed to {@link LocalMutationHandler.commitTransaction} on commit.
|
|
67
|
+
* Routes local mutations through a unified apply pipeline (korajs ApplyPipeline).
|
|
68
|
+
*
|
|
69
|
+
* Every local write — including each entry of an `app.transaction` commit — is
|
|
70
|
+
* built and persisted by the store's single local write path; the handler adds
|
|
71
|
+
* pipeline behaviour around it.
|
|
63
72
|
*/
|
|
64
|
-
interface TransactionCommitBatch {
|
|
65
|
-
entries: TransactionBufferedEntry[];
|
|
66
|
-
transactionId: string;
|
|
67
|
-
mutationName?: string;
|
|
68
|
-
}
|
|
69
|
-
interface TransactionCommitResult {
|
|
70
|
-
operations: Operation[];
|
|
71
|
-
affectedCollections: Set<string>;
|
|
72
|
-
}
|
|
73
73
|
interface LocalMutationHandler {
|
|
74
74
|
insert(collection: string, data: Record<string, unknown>): Promise<CollectionRecord>;
|
|
75
75
|
update(collection: string, id: string, data: Record<string, unknown>): Promise<CollectionRecord>;
|
|
76
76
|
delete(collection: string, id: string): Promise<void>;
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
78
|
+
* Called inside the write transaction for every local delete (single-record,
|
|
79
|
+
* transactional and cascaded), after the delete operation is built and before
|
|
80
|
+
* referential side effects run. Reads must go through `tx`. Throwing aborts
|
|
81
|
+
* the whole write.
|
|
80
82
|
*/
|
|
81
|
-
|
|
83
|
+
beforeLocalDelete?(operation: Operation, tx: Transaction): Promise<void>;
|
|
82
84
|
}
|
|
83
85
|
type StoreIsolation = 'shared' | 'per-tab';
|
|
84
86
|
interface StoreConfig {
|
|
@@ -104,6 +106,30 @@ interface StoreConfig {
|
|
|
104
106
|
* Required only when the schema declares encrypted secret fields.
|
|
105
107
|
*/
|
|
106
108
|
secretKeyProvider?: SecretKeyProvider;
|
|
109
|
+
/**
|
|
110
|
+
* How rows are materialized. `'fold'` (default, W7): every write merges into the
|
|
111
|
+
* record's per-field CRDT fold state, which re-materializes the row. `'legacy'`:
|
|
112
|
+
* the beta.12 per-field LWW write paths (used by `experimental.legacyMerge` for
|
|
113
|
+
* one beta, to compare). Switching modes on an existing database re-materializes
|
|
114
|
+
* it on open.
|
|
115
|
+
*/
|
|
116
|
+
materialization?: 'fold' | 'legacy';
|
|
117
|
+
/**
|
|
118
|
+
* Schema transforms applied at fold time (RT-84): an operation authored under an
|
|
119
|
+
* older schema version is stored exactly as written and folded as
|
|
120
|
+
* `operationSchemaView(op, schema.version, transforms)` reads it. Pass the same list
|
|
121
|
+
* as the sync engine's `operationTransforms` (`createApp` does). Transforms must be
|
|
122
|
+
* pure and deterministic; they are part of the fold plan fingerprint, so changing
|
|
123
|
+
* them re-folds once.
|
|
124
|
+
*/
|
|
125
|
+
operationTransforms?: readonly OperationTransform[];
|
|
126
|
+
/**
|
|
127
|
+
* Largest serialized operation a local write may produce, in bytes (RT-86). Set it to
|
|
128
|
+
* the sync server's `maxOperationBytes`. A write over it is refused with
|
|
129
|
+
* `OperationTooLargeError` and nothing is written. Default 256 KiB, the server's
|
|
130
|
+
* default.
|
|
131
|
+
*/
|
|
132
|
+
maxOperationBytes?: number;
|
|
107
133
|
}
|
|
108
134
|
/**
|
|
109
135
|
* Operators for where clause conditions.
|
|
@@ -150,6 +176,38 @@ interface QueryDescriptor {
|
|
|
150
176
|
* Callback for reactive subscriptions. Receives the current result set.
|
|
151
177
|
*/
|
|
152
178
|
type SubscriptionCallback<T> = (results: T[]) => void;
|
|
179
|
+
/**
|
|
180
|
+
* Where a subscription failure happened.
|
|
181
|
+
* - `initial`: the first run of the query, before any result was delivered.
|
|
182
|
+
* - `refresh`: a re-run after a write to a collection the query reads.
|
|
183
|
+
* - `callback`: the query succeeded but the subscriber's own callback threw.
|
|
184
|
+
*/
|
|
185
|
+
type QueryErrorPhase = 'initial' | 'refresh' | 'callback';
|
|
186
|
+
/**
|
|
187
|
+
* A failure delivered to a subscriber's `onError` (STORE-12). The previous result
|
|
188
|
+
* set stays current; the subscription stays registered and is re-run on the next
|
|
189
|
+
* write, and a later success is delivered even if it equals the last results.
|
|
190
|
+
*/
|
|
191
|
+
interface QuerySubscriptionError {
|
|
192
|
+
/** The error thrown by the query or the callback. */
|
|
193
|
+
error: Error;
|
|
194
|
+
phase: QueryErrorPhase;
|
|
195
|
+
/** The collection the query reads. */
|
|
196
|
+
collection: string;
|
|
197
|
+
/** Subscription id, the same `queryId` carried by the `query:error` event. */
|
|
198
|
+
queryId: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Options for `QueryBuilder.subscribe()`.
|
|
202
|
+
*/
|
|
203
|
+
interface SubscribeOptions {
|
|
204
|
+
/**
|
|
205
|
+
* Called when the query fails (or the callback throws) instead of the failure
|
|
206
|
+
* becoming an unhandled rejection. Every failure is also emitted as a
|
|
207
|
+
* `query:error` event; without `onError` it is additionally logged.
|
|
208
|
+
*/
|
|
209
|
+
onError?: (failure: QuerySubscriptionError) => void;
|
|
210
|
+
}
|
|
153
211
|
/**
|
|
154
212
|
* Serialized row in the operations log table.
|
|
155
213
|
*/
|
|
@@ -198,12 +256,27 @@ interface Subscription<T = CollectionRecord> {
|
|
|
198
256
|
callback: SubscriptionCallback<T>;
|
|
199
257
|
executeFn: () => Promise<T[]>;
|
|
200
258
|
lastResults: T[];
|
|
259
|
+
/** Result-set comparator (structural, per field kind). */
|
|
260
|
+
resultsEqual?: (prev: readonly T[], next: readonly T[]) => boolean;
|
|
261
|
+
onError?: (failure: QuerySubscriptionError) => void;
|
|
262
|
+
/** Monotonic run counter: a slower, older run never overwrites a newer result. */
|
|
263
|
+
runsStarted?: number;
|
|
264
|
+
lastAppliedRun?: number;
|
|
265
|
+
/** True after a failure until the next successful delivery. */
|
|
266
|
+
errored?: boolean;
|
|
267
|
+
/** True once a result set has been delivered to the callback. */
|
|
268
|
+
delivered?: boolean;
|
|
201
269
|
}
|
|
202
270
|
|
|
203
271
|
/**
|
|
204
272
|
* Options for applying a remote operation to materialized storage.
|
|
205
273
|
*/
|
|
206
274
|
interface ApplyRemoteOptions {
|
|
275
|
+
/**
|
|
276
|
+
* W7: receives the merge traces of the operation (conflicting field decisions),
|
|
277
|
+
* after commit. The store also emits them as `merge:*` events.
|
|
278
|
+
*/
|
|
279
|
+
onMergeTraces?: (traces: _korajs_core.MergeTrace[]) => void;
|
|
207
280
|
/** When true, a winning remote update clears soft-delete on the row. */
|
|
208
281
|
reactivateIfDeleted?: boolean;
|
|
209
282
|
/**
|
|
@@ -280,4 +353,4 @@ interface VersionVectorRow {
|
|
|
280
353
|
sequence_number: number;
|
|
281
354
|
}
|
|
282
355
|
|
|
283
|
-
export type { ApplyRemoteOptions as A, CollectionRecord as C, LocalMutationHandler as L, MigrationPlan as M, OperationRow as O, QueryDescriptor as Q, RawCollectionRow as R, StorageAdapter as S, Transaction as T, VersionVectorRow as V, WhereClause as W, StorageOpenState as a, MetaRow as b, Subscription as c,
|
|
356
|
+
export type { ApplyRemoteOptions as A, CollectionRecord as C, LocalMutationHandler as L, MigrationPlan as M, OperationRow as O, QueryDescriptor as Q, RawCollectionRow as R, StorageAdapter as S, Transaction as T, VersionVectorRow as V, WhereClause as W, StorageOpenState as a, MetaRow as b, Subscription as c, QuerySubscriptionError as d, SubscriptionCallback as e, SubscribeOptions as f, OrderByDirection as g, StoreConfig as h, MaterializedRowSnapshot as i, RowVersionState as j, OrderByClause as k, QueryErrorPhase as l, StorageFallbackReason as m, StoreIsolation as n, WhereOperators as o };
|