@tanstack/db-sqlite-persistence-core 0.1.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 +95 -0
- package/dist/cjs/errors.cjs +72 -0
- package/dist/cjs/errors.cjs.map +1 -0
- package/dist/cjs/errors.d.cts +25 -0
- package/dist/cjs/index.cjs +22 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +3 -0
- package/dist/cjs/persisted.cjs +1705 -0
- package/dist/cjs/persisted.cjs.map +1 -0
- package/dist/cjs/persisted.d.cts +293 -0
- package/dist/cjs/sqlite-core-adapter.cjs +1588 -0
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -0
- package/dist/cjs/sqlite-core-adapter.d.cts +67 -0
- package/dist/esm/errors.d.ts +25 -0
- package/dist/esm/errors.js +72 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/persisted.d.ts +293 -0
- package/dist/esm/persisted.js +1705 -0
- package/dist/esm/persisted.js.map +1 -0
- package/dist/esm/sqlite-core-adapter.d.ts +67 -0
- package/dist/esm/sqlite-core-adapter.js +1588 -0
- package/dist/esm/sqlite-core-adapter.js.map +1 -0
- package/package.json +57 -0
- package/src/errors.ts +73 -0
- package/src/index.ts +3 -0
- package/src/persisted.ts +2820 -0
- package/src/sqlite-core-adapter.ts +2129 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import { CollectionConfig, LoadSubsetOptions, PendingMutation, SyncConfig, UtilsRecord } from '@tanstack/db';
|
|
3
|
+
export type PersistedMutationEnvelope = {
|
|
4
|
+
mutationId: string;
|
|
5
|
+
type: `insert`;
|
|
6
|
+
key: string | number;
|
|
7
|
+
value: Record<string, unknown>;
|
|
8
|
+
} | {
|
|
9
|
+
mutationId: string;
|
|
10
|
+
type: `update`;
|
|
11
|
+
key: string | number;
|
|
12
|
+
value: Record<string, unknown>;
|
|
13
|
+
} | {
|
|
14
|
+
mutationId: string;
|
|
15
|
+
type: `delete`;
|
|
16
|
+
key: string | number;
|
|
17
|
+
value: Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
export type ProtocolEnvelope<TPayload> = {
|
|
20
|
+
v: 1;
|
|
21
|
+
dbName: string;
|
|
22
|
+
collectionId: string;
|
|
23
|
+
senderId: string;
|
|
24
|
+
ts: number;
|
|
25
|
+
payload: TPayload;
|
|
26
|
+
};
|
|
27
|
+
export type LeaderHeartbeat = {
|
|
28
|
+
type: `leader:heartbeat`;
|
|
29
|
+
term: number;
|
|
30
|
+
leaderId: string;
|
|
31
|
+
latestSeq: number;
|
|
32
|
+
latestRowVersion: number;
|
|
33
|
+
};
|
|
34
|
+
export type TxCommitted = {
|
|
35
|
+
type: `tx:committed`;
|
|
36
|
+
term: number;
|
|
37
|
+
seq: number;
|
|
38
|
+
txId: string;
|
|
39
|
+
latestRowVersion: number;
|
|
40
|
+
} & ({
|
|
41
|
+
requiresFullReload: true;
|
|
42
|
+
} | {
|
|
43
|
+
requiresFullReload: false;
|
|
44
|
+
changedRows: Array<{
|
|
45
|
+
key: string | number;
|
|
46
|
+
value: Record<string, unknown>;
|
|
47
|
+
}>;
|
|
48
|
+
deletedKeys: Array<string | number>;
|
|
49
|
+
rowMetadataMutations?: Array<PersistedRowMetadataMutation<string | number>>;
|
|
50
|
+
collectionMetadataMutations?: Array<PersistedCollectionMetadataMutation>;
|
|
51
|
+
});
|
|
52
|
+
export type EnsureRemoteSubsetRequest = {
|
|
53
|
+
type: `rpc:ensureRemoteSubset:req`;
|
|
54
|
+
rpcId: string;
|
|
55
|
+
options: LoadSubsetOptions;
|
|
56
|
+
};
|
|
57
|
+
export type EnsureRemoteSubsetResponse = {
|
|
58
|
+
type: `rpc:ensureRemoteSubset:res`;
|
|
59
|
+
rpcId: string;
|
|
60
|
+
ok: true;
|
|
61
|
+
} | {
|
|
62
|
+
type: `rpc:ensureRemoteSubset:res`;
|
|
63
|
+
rpcId: string;
|
|
64
|
+
ok: false;
|
|
65
|
+
error: string;
|
|
66
|
+
};
|
|
67
|
+
export type ApplyLocalMutationsRequest = {
|
|
68
|
+
type: `rpc:applyLocalMutations:req`;
|
|
69
|
+
rpcId: string;
|
|
70
|
+
envelopeId: string;
|
|
71
|
+
mutations: Array<PersistedMutationEnvelope>;
|
|
72
|
+
};
|
|
73
|
+
export type ApplyLocalMutationsResponse = {
|
|
74
|
+
type: `rpc:applyLocalMutations:res`;
|
|
75
|
+
rpcId: string;
|
|
76
|
+
ok: true;
|
|
77
|
+
term: number;
|
|
78
|
+
seq: number;
|
|
79
|
+
latestRowVersion: number;
|
|
80
|
+
acceptedMutationIds: Array<string>;
|
|
81
|
+
} | {
|
|
82
|
+
type: `rpc:applyLocalMutations:res`;
|
|
83
|
+
rpcId: string;
|
|
84
|
+
ok: false;
|
|
85
|
+
code: `NOT_LEADER` | `VALIDATION_ERROR` | `CONFLICT` | `TIMEOUT`;
|
|
86
|
+
error: string;
|
|
87
|
+
};
|
|
88
|
+
export type PullSinceRequest = {
|
|
89
|
+
type: `rpc:pullSince:req`;
|
|
90
|
+
rpcId: string;
|
|
91
|
+
fromRowVersion: number;
|
|
92
|
+
};
|
|
93
|
+
export type PullSinceResponse = {
|
|
94
|
+
type: `rpc:pullSince:res`;
|
|
95
|
+
rpcId: string;
|
|
96
|
+
ok: true;
|
|
97
|
+
latestTerm: number;
|
|
98
|
+
latestSeq: number;
|
|
99
|
+
latestRowVersion: number;
|
|
100
|
+
requiresFullReload: true;
|
|
101
|
+
} | {
|
|
102
|
+
type: `rpc:pullSince:res`;
|
|
103
|
+
rpcId: string;
|
|
104
|
+
ok: true;
|
|
105
|
+
latestTerm: number;
|
|
106
|
+
latestSeq: number;
|
|
107
|
+
latestRowVersion: number;
|
|
108
|
+
requiresFullReload: false;
|
|
109
|
+
changedKeys: Array<string | number>;
|
|
110
|
+
deletedKeys: Array<string | number>;
|
|
111
|
+
deltas?: Array<ReplayableTxDelta<Record<string, unknown>, string | number>>;
|
|
112
|
+
} | {
|
|
113
|
+
type: `rpc:pullSince:res`;
|
|
114
|
+
rpcId: string;
|
|
115
|
+
ok: false;
|
|
116
|
+
error: string;
|
|
117
|
+
};
|
|
118
|
+
export type CollectionReset = {
|
|
119
|
+
type: `collection:reset`;
|
|
120
|
+
schemaVersion: number;
|
|
121
|
+
resetEpoch: number;
|
|
122
|
+
};
|
|
123
|
+
export interface PersistedIndexSpec {
|
|
124
|
+
readonly expressionSql: ReadonlyArray<string>;
|
|
125
|
+
readonly whereSql?: string;
|
|
126
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
127
|
+
}
|
|
128
|
+
export type PersistedRowMetadataMutation<TKey extends string | number = string | number> = {
|
|
129
|
+
type: `set`;
|
|
130
|
+
key: TKey;
|
|
131
|
+
value: unknown;
|
|
132
|
+
} | {
|
|
133
|
+
type: `delete`;
|
|
134
|
+
key: TKey;
|
|
135
|
+
};
|
|
136
|
+
export type PersistedCollectionMetadataMutation = {
|
|
137
|
+
type: `set`;
|
|
138
|
+
key: string;
|
|
139
|
+
value: unknown;
|
|
140
|
+
} | {
|
|
141
|
+
type: `delete`;
|
|
142
|
+
key: string;
|
|
143
|
+
};
|
|
144
|
+
export type ReplayableTxDelta<T extends Record<string, unknown> = Record<string, unknown>, TKey extends string | number = string | number> = {
|
|
145
|
+
txId: string;
|
|
146
|
+
latestRowVersion: number;
|
|
147
|
+
changedRows: Array<{
|
|
148
|
+
key: TKey;
|
|
149
|
+
value: T;
|
|
150
|
+
}>;
|
|
151
|
+
deletedKeys: Array<TKey>;
|
|
152
|
+
rowMetadataMutations: Array<PersistedRowMetadataMutation<TKey>>;
|
|
153
|
+
collectionMetadataMutations: Array<PersistedCollectionMetadataMutation>;
|
|
154
|
+
};
|
|
155
|
+
export type PersistedScannedRow<T extends object, TKey extends string | number = string | number> = {
|
|
156
|
+
key: TKey;
|
|
157
|
+
value: T;
|
|
158
|
+
metadata?: unknown;
|
|
159
|
+
};
|
|
160
|
+
export type PersistedRowScanOptions = {
|
|
161
|
+
metadataOnly?: boolean;
|
|
162
|
+
};
|
|
163
|
+
export type PersistedTx<T extends object, TKey extends string | number = string | number> = {
|
|
164
|
+
txId: string;
|
|
165
|
+
term: number;
|
|
166
|
+
seq: number;
|
|
167
|
+
rowVersion: number;
|
|
168
|
+
truncate?: boolean;
|
|
169
|
+
mutations: Array<{
|
|
170
|
+
type: `insert`;
|
|
171
|
+
key: TKey;
|
|
172
|
+
value: T;
|
|
173
|
+
metadata?: unknown;
|
|
174
|
+
metadataChanged?: boolean;
|
|
175
|
+
} | {
|
|
176
|
+
type: `update`;
|
|
177
|
+
key: TKey;
|
|
178
|
+
value: T;
|
|
179
|
+
metadata?: unknown;
|
|
180
|
+
metadataChanged?: boolean;
|
|
181
|
+
} | {
|
|
182
|
+
type: `delete`;
|
|
183
|
+
key: TKey;
|
|
184
|
+
value: T;
|
|
185
|
+
}>;
|
|
186
|
+
rowMetadataMutations?: Array<PersistedRowMetadataMutation<TKey>>;
|
|
187
|
+
collectionMetadataMutations?: Array<PersistedCollectionMetadataMutation>;
|
|
188
|
+
};
|
|
189
|
+
export interface PersistenceAdapter<T extends object, TKey extends string | number = string | number> {
|
|
190
|
+
loadSubset: (collectionId: string, options: LoadSubsetOptions, ctx?: {
|
|
191
|
+
requiredIndexSignatures?: ReadonlyArray<string>;
|
|
192
|
+
}) => Promise<Array<{
|
|
193
|
+
key: TKey;
|
|
194
|
+
value: T;
|
|
195
|
+
metadata?: unknown;
|
|
196
|
+
}>>;
|
|
197
|
+
applyCommittedTx: (collectionId: string, tx: PersistedTx<T, TKey>) => Promise<void>;
|
|
198
|
+
loadCollectionMetadata?: (collectionId: string) => Promise<Array<{
|
|
199
|
+
key: string;
|
|
200
|
+
value: unknown;
|
|
201
|
+
}>>;
|
|
202
|
+
scanRows?: (collectionId: string, options?: PersistedRowScanOptions) => Promise<Array<PersistedScannedRow<T, TKey>>>;
|
|
203
|
+
ensureIndex: (collectionId: string, signature: string, spec: PersistedIndexSpec) => Promise<void>;
|
|
204
|
+
markIndexRemoved?: (collectionId: string, signature: string) => Promise<void>;
|
|
205
|
+
getStreamPosition?: (collectionId: string) => Promise<{
|
|
206
|
+
latestTerm: number;
|
|
207
|
+
latestSeq: number;
|
|
208
|
+
latestRowVersion: number;
|
|
209
|
+
}>;
|
|
210
|
+
}
|
|
211
|
+
export interface SQLiteDriver {
|
|
212
|
+
exec: (sql: string) => Promise<void>;
|
|
213
|
+
query: <T>(sql: string, params?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<T>>;
|
|
214
|
+
run: (sql: string, params?: ReadonlyArray<unknown>) => Promise<void>;
|
|
215
|
+
transaction: <T>(fn: (transactionDriver: SQLiteDriver) => Promise<T>) => Promise<T>;
|
|
216
|
+
transactionWithDriver?: <T>(fn: (transactionDriver: SQLiteDriver) => Promise<T>) => Promise<T>;
|
|
217
|
+
}
|
|
218
|
+
export interface PersistedCollectionCoordinator {
|
|
219
|
+
getNodeId: () => string;
|
|
220
|
+
subscribe: (collectionId: string, onMessage: (message: ProtocolEnvelope<unknown>) => void) => () => void;
|
|
221
|
+
publish: (collectionId: string, message: ProtocolEnvelope<unknown>) => void;
|
|
222
|
+
isLeader: (collectionId: string) => boolean;
|
|
223
|
+
ensureLeadership: (collectionId: string) => Promise<void>;
|
|
224
|
+
requestEnsureRemoteSubset?: (collectionId: string, options: LoadSubsetOptions) => Promise<void>;
|
|
225
|
+
requestEnsurePersistedIndex: (collectionId: string, signature: string, spec: PersistedIndexSpec) => Promise<void>;
|
|
226
|
+
requestApplyLocalMutations?: (collectionId: string, mutations: Array<PersistedMutationEnvelope>) => Promise<ApplyLocalMutationsResponse>;
|
|
227
|
+
pullSince?: (collectionId: string, fromRowVersion: number) => Promise<PullSinceResponse>;
|
|
228
|
+
}
|
|
229
|
+
export interface PersistedCollectionPersistence<T extends object, TKey extends string | number = string | number> {
|
|
230
|
+
adapter: PersistenceAdapter<T, TKey>;
|
|
231
|
+
coordinator?: PersistedCollectionCoordinator;
|
|
232
|
+
resolvePersistenceForCollection?: (options: {
|
|
233
|
+
collectionId: string;
|
|
234
|
+
mode: PersistedCollectionMode;
|
|
235
|
+
schemaVersion?: number;
|
|
236
|
+
}) => PersistedCollectionPersistence<T, TKey>;
|
|
237
|
+
resolvePersistenceForMode?: (mode: PersistedCollectionMode) => PersistedCollectionPersistence<T, TKey>;
|
|
238
|
+
}
|
|
239
|
+
type PersistedResolvedPersistence<T extends object, TKey extends string | number> = PersistedCollectionPersistence<T, TKey> & {
|
|
240
|
+
coordinator: PersistedCollectionCoordinator;
|
|
241
|
+
};
|
|
242
|
+
export type PersistedCollectionLeadershipState = {
|
|
243
|
+
nodeId: string;
|
|
244
|
+
isLeader: boolean;
|
|
245
|
+
};
|
|
246
|
+
export interface PersistedCollectionUtils extends UtilsRecord {
|
|
247
|
+
acceptMutations: (transaction: {
|
|
248
|
+
mutations: Array<PendingMutation<Record<string, unknown>>>;
|
|
249
|
+
}) => Promise<void> | void;
|
|
250
|
+
getLeadershipState?: () => PersistedCollectionLeadershipState;
|
|
251
|
+
forceReloadSubset?: (options: LoadSubsetOptions) => Promise<void> | void;
|
|
252
|
+
}
|
|
253
|
+
export type PersistedSyncWrappedOptions<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord> = CollectionConfig<T, TKey, TSchema, TUtils> & {
|
|
254
|
+
sync: SyncConfig<T, TKey>;
|
|
255
|
+
persistence: PersistedCollectionPersistence<T, TKey>;
|
|
256
|
+
schemaVersion?: number;
|
|
257
|
+
};
|
|
258
|
+
export type PersistedLocalOnlyOptions<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord> = Omit<CollectionConfig<T, TKey, TSchema, TUtils>, `sync`> & {
|
|
259
|
+
persistence: PersistedCollectionPersistence<T, TKey>;
|
|
260
|
+
schemaVersion?: number;
|
|
261
|
+
};
|
|
262
|
+
type PersistedSyncOptionsResult<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1, TUtils extends UtilsRecord> = CollectionConfig<T, TKey, TSchema, TUtils> & {
|
|
263
|
+
persistence: PersistedResolvedPersistence<T, TKey>;
|
|
264
|
+
};
|
|
265
|
+
type PersistedLocalOnlyOptionsResult<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1, TUtils extends UtilsRecord> = CollectionConfig<T, TKey, TSchema, TUtils & PersistedCollectionUtils> & {
|
|
266
|
+
id: string;
|
|
267
|
+
persistence: PersistedResolvedPersistence<T, TKey>;
|
|
268
|
+
utils: TUtils & PersistedCollectionUtils;
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Phase-0 coordinator implementation for single-process runtimes.
|
|
272
|
+
* It satisfies the coordinator contract without cross-process transport.
|
|
273
|
+
*/
|
|
274
|
+
export declare class SingleProcessCoordinator implements PersistedCollectionCoordinator {
|
|
275
|
+
private readonly nodeId;
|
|
276
|
+
constructor(nodeId?: string);
|
|
277
|
+
getNodeId(): string;
|
|
278
|
+
subscribe(): () => void;
|
|
279
|
+
publish(): void;
|
|
280
|
+
isLeader(): boolean;
|
|
281
|
+
ensureLeadership(): Promise<void>;
|
|
282
|
+
requestEnsureRemoteSubset(): Promise<void>;
|
|
283
|
+
requestEnsurePersistedIndex(): Promise<void>;
|
|
284
|
+
pullSince(): Promise<PullSinceResponse>;
|
|
285
|
+
}
|
|
286
|
+
export declare function validatePersistedCollectionCoordinator(coordinator: PersistedCollectionCoordinator): void;
|
|
287
|
+
export type PersistedCollectionMode = `sync-present` | `sync-absent`;
|
|
288
|
+
export declare function persistedCollectionOptions<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord>(options: PersistedSyncWrappedOptions<T, TKey, TSchema, TUtils>): PersistedSyncOptionsResult<T, TKey, TSchema, TUtils>;
|
|
289
|
+
export declare function persistedCollectionOptions<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord>(options: PersistedLocalOnlyOptions<T, TKey, TSchema, TUtils>): PersistedLocalOnlyOptionsResult<T, TKey, TSchema, TUtils>;
|
|
290
|
+
export declare function encodePersistedStorageKey(key: string | number): string;
|
|
291
|
+
export declare function decodePersistedStorageKey(encoded: string): string | number;
|
|
292
|
+
export declare function createPersistedTableName(collectionId: string, prefix?: `c` | `t`): string;
|
|
293
|
+
export {};
|