@firtoz/drizzle-indexeddb 0.6.1 → 1.0.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/CHANGELOG.md +27 -0
- package/package.json +11 -9
- package/src/collections/indexeddb-collection.ts +113 -102
- package/src/context/DrizzleIndexedDBProvider.tsx +2 -87
- package/src/function-migrator.ts +3 -0
- package/src/index.ts +0 -27
- package/src/native-idb-database.ts +3 -0
- package/src/standalone-collection.ts +3 -7
- package/src/proxy/idb-proxy-client.ts +0 -341
- package/src/proxy/idb-proxy-server.ts +0 -313
- package/src/proxy/idb-proxy-transport.ts +0 -174
- package/src/proxy/idb-proxy-types.ts +0 -77
- package/src/proxy/idb-sync-adapter.ts +0 -95
- package/src/proxy/index.ts +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @firtoz/drizzle-indexeddb
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`3c7ce1d`](https://github.com/firtoz/fullstack-toolkit/commit/3c7ce1dbca5c5396386db9927ae7f5e19a562cf6) Thanks [@firtoz](https://github.com/firtoz)! - **IndexedDB proxy removed**
|
|
8
|
+
|
|
9
|
+
The IDB proxy layer (proxy client/server, transport, sync adapter) has been removed. Provider no longer exposes proxy sync; use native IndexedDB only.
|
|
10
|
+
|
|
11
|
+
**Upgrade:** If you were using the IDB proxy (e.g. `idb-proxy-client`, `idb-proxy-server`, `handleProxySync`, `onSyncReady`): remove that code. There is no replacement API; you implement the transport and call `receiveSync` with `SyncMessage[]` from `@firtoz/drizzle-utils` on each side.
|
|
12
|
+
|
|
13
|
+
**Remote / multi-context setup:** Use a **memory collection** (`@firtoz/db-helpers`) in the context that cannot access IndexedDB and keep the **IDB collection** where IndexedDB is available (source of truth). Implement your own channel (e.g. BroadcastChannel, `postMessage`, or WebSocket): when a context receives sync messages, call `utils.receiveSync(messages)` on its collection. Use `SyncMessage` from `@firtoz/db-helpers` (or `@firtoz/drizzle-utils`). The side that holds IDB can push initial state and updates as `SyncMessage[]` so the other side’s memory collection stays in sync.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`3c7ce1d`](https://github.com/firtoz/fullstack-toolkit/commit/3c7ce1dbca5c5396386db9927ae7f5e19a562cf6), [`3c7ce1d`](https://github.com/firtoz/fullstack-toolkit/commit/3c7ce1dbca5c5396386db9927ae7f5e19a562cf6)]:
|
|
18
|
+
- @firtoz/db-helpers@1.0.0
|
|
19
|
+
- @firtoz/drizzle-utils@1.0.0
|
|
20
|
+
|
|
21
|
+
## 0.6.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- [`ec365af`](https://github.com/firtoz/fullstack-toolkit/commit/ec365af8c17bcd7efc2b0cf9b3bed5225b853e72) Thanks [@firtoz](https://github.com/firtoz)! - Update dependencies
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`ec365af`](https://github.com/firtoz/fullstack-toolkit/commit/ec365af8c17bcd7efc2b0cf9b3bed5225b853e72)]:
|
|
28
|
+
- @firtoz/drizzle-utils@0.3.3
|
|
29
|
+
|
|
3
30
|
## 0.6.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firtoz/drizzle-indexeddb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "IndexedDB migrations powered by Drizzle ORM",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -68,23 +68,25 @@
|
|
|
68
68
|
"access": "public"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@firtoz/drizzle-utils": ">=0.
|
|
72
|
-
"@tanstack/db": ">=0.5.
|
|
71
|
+
"@firtoz/drizzle-utils": ">=1.0.0",
|
|
72
|
+
"@tanstack/db": ">=0.5.26",
|
|
73
73
|
"drizzle-orm": ">=0.45.1",
|
|
74
74
|
"drizzle-valibot": ">=0.4.0",
|
|
75
|
-
"react": ">=19.2.
|
|
75
|
+
"react": ">=19.2.4",
|
|
76
76
|
"valibot": ">=1.0.0"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@firtoz/drizzle-utils": "^0.
|
|
80
|
-
"@tanstack/db": "^0.5.
|
|
81
|
-
"@types/react": "^19.2.
|
|
79
|
+
"@firtoz/drizzle-utils": "^1.0.0",
|
|
80
|
+
"@tanstack/db": "^0.5.26",
|
|
81
|
+
"@types/react": "^19.2.14",
|
|
82
82
|
"drizzle-orm": "^0.45.1",
|
|
83
83
|
"drizzle-valibot": "^0.4.2",
|
|
84
|
-
"react": "^19.2.
|
|
84
|
+
"react": "^19.2.4",
|
|
85
85
|
"valibot": "^1.2.0"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"
|
|
88
|
+
"@firtoz/db-helpers": "^1.0.0",
|
|
89
|
+
"@firtoz/maybe-error": "^1.5.2",
|
|
90
|
+
"citty": "^0.2.1"
|
|
89
91
|
}
|
|
90
92
|
}
|
|
@@ -65,100 +65,103 @@ export function evaluateExpression(
|
|
|
65
65
|
expression: IR.BasicExpression,
|
|
66
66
|
item: Record<string, unknown>,
|
|
67
67
|
): boolean {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
68
|
+
switch (expression.type) {
|
|
69
|
+
case "ref": {
|
|
70
|
+
const propRef = expression;
|
|
71
|
+
const columnName = propRef.path[propRef.path.length - 1];
|
|
72
|
+
return item[columnName as string] !== undefined;
|
|
73
|
+
}
|
|
74
|
+
case "val": {
|
|
75
|
+
const value = expression;
|
|
76
|
+
return !!value.value;
|
|
77
|
+
}
|
|
78
|
+
case "func": {
|
|
79
|
+
const func = expression;
|
|
80
|
+
|
|
81
|
+
switch (func.name) {
|
|
82
|
+
case "eq": {
|
|
83
|
+
const left = getExpressionValue(func.args[0], item);
|
|
84
|
+
const right = getExpressionValue(func.args[1], item);
|
|
85
|
+
return left === right;
|
|
86
|
+
}
|
|
87
|
+
case "ne": {
|
|
88
|
+
const left = getExpressionValue(func.args[0], item);
|
|
89
|
+
const right = getExpressionValue(func.args[1], item);
|
|
90
|
+
return left !== right;
|
|
91
|
+
}
|
|
92
|
+
case "gt": {
|
|
93
|
+
const left = getExpressionValue(func.args[0], item);
|
|
94
|
+
const right = getExpressionValue(func.args[1], item);
|
|
95
|
+
return left > right;
|
|
96
|
+
}
|
|
97
|
+
case "gte": {
|
|
98
|
+
const left = getExpressionValue(func.args[0], item);
|
|
99
|
+
const right = getExpressionValue(func.args[1], item);
|
|
100
|
+
return left >= right;
|
|
101
|
+
}
|
|
102
|
+
case "lt": {
|
|
103
|
+
const left = getExpressionValue(func.args[0], item);
|
|
104
|
+
const right = getExpressionValue(func.args[1], item);
|
|
105
|
+
return left < right;
|
|
106
|
+
}
|
|
107
|
+
case "lte": {
|
|
108
|
+
const left = getExpressionValue(func.args[0], item);
|
|
109
|
+
const right = getExpressionValue(func.args[1], item);
|
|
110
|
+
return left <= right;
|
|
111
|
+
}
|
|
112
|
+
case "and": {
|
|
113
|
+
return func.args.every((arg) => evaluateExpression(arg, item));
|
|
114
|
+
}
|
|
115
|
+
case "or": {
|
|
116
|
+
return func.args.some((arg) => evaluateExpression(arg, item));
|
|
117
|
+
}
|
|
118
|
+
case "not": {
|
|
119
|
+
return !evaluateExpression(func.args[0], item);
|
|
120
|
+
}
|
|
121
|
+
case "isNull": {
|
|
122
|
+
const value = getExpressionValue(func.args[0], item);
|
|
123
|
+
return value === null || value === undefined;
|
|
124
|
+
}
|
|
125
|
+
case "isNotNull": {
|
|
126
|
+
const value = getExpressionValue(func.args[0], item);
|
|
127
|
+
return value !== null && value !== undefined;
|
|
128
|
+
}
|
|
129
|
+
case "like": {
|
|
130
|
+
const left = String(getExpressionValue(func.args[0], item));
|
|
131
|
+
const right = String(getExpressionValue(func.args[1], item));
|
|
132
|
+
// Convert SQL LIKE pattern to regex (case-sensitive)
|
|
133
|
+
const pattern = right.replace(/%/g, ".*").replace(/_/g, ".");
|
|
134
|
+
return new RegExp(`^${pattern}$`).test(left);
|
|
135
|
+
}
|
|
136
|
+
case "ilike": {
|
|
137
|
+
const left = String(getExpressionValue(func.args[0], item));
|
|
138
|
+
const right = String(getExpressionValue(func.args[1], item));
|
|
139
|
+
// Convert SQL ILIKE pattern to regex (case-insensitive)
|
|
140
|
+
const pattern = right.replace(/%/g, ".*").replace(/_/g, ".");
|
|
141
|
+
return new RegExp(`^${pattern}$`, "i").test(left);
|
|
142
|
+
}
|
|
143
|
+
case "in": {
|
|
144
|
+
const left = getExpressionValue(func.args[0], item);
|
|
145
|
+
const right = getExpressionValue(func.args[1], item);
|
|
146
|
+
// Check if left value is in the right array
|
|
147
|
+
return Array.isArray(right) && right.includes(left);
|
|
148
|
+
}
|
|
149
|
+
case "isUndefined": {
|
|
150
|
+
const value = getExpressionValue(func.args[0], item);
|
|
151
|
+
return value === null || value === undefined;
|
|
152
|
+
}
|
|
153
|
+
default:
|
|
154
|
+
throw new Error(`Unsupported function: ${func.name}`);
|
|
153
155
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
}
|
|
157
|
+
default: {
|
|
158
|
+
const _ex: never = expression;
|
|
159
|
+
void _ex;
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Unsupported expression type: ${(expression as { type: string }).type}`,
|
|
162
|
+
);
|
|
156
163
|
}
|
|
157
164
|
}
|
|
158
|
-
|
|
159
|
-
throw new Error(
|
|
160
|
-
`Unsupported expression type: ${(expression as { type: string }).type}`,
|
|
161
|
-
);
|
|
162
165
|
}
|
|
163
166
|
|
|
164
167
|
/**
|
|
@@ -170,18 +173,26 @@ export function getExpressionValue(
|
|
|
170
173
|
item: Record<string, unknown>,
|
|
171
174
|
// biome-ignore lint/suspicious/noExplicitAny: We need any here for dynamic values
|
|
172
175
|
): any {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
switch (expression.type) {
|
|
177
|
+
case "ref": {
|
|
178
|
+
const propRef = expression;
|
|
179
|
+
const columnName = propRef.path[propRef.path.length - 1];
|
|
180
|
+
return item[columnName as string];
|
|
181
|
+
}
|
|
182
|
+
case "val": {
|
|
183
|
+
const value = expression;
|
|
184
|
+
return value.value;
|
|
185
|
+
}
|
|
186
|
+
case "func":
|
|
187
|
+
throw new Error("Cannot get value from func expression");
|
|
188
|
+
default: {
|
|
189
|
+
const _ex: never = expression;
|
|
190
|
+
void _ex;
|
|
191
|
+
throw new Error(
|
|
192
|
+
`Cannot get value from expression type: ${(expression as { type: string }).type}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
182
195
|
}
|
|
183
|
-
|
|
184
|
-
throw new Error(`Cannot get value from expression type: ${expression.type}`);
|
|
185
196
|
}
|
|
186
197
|
|
|
187
198
|
/**
|
|
@@ -19,13 +19,13 @@ import {
|
|
|
19
19
|
indexedDBCollectionOptions,
|
|
20
20
|
type IndexedDBCollectionConfig,
|
|
21
21
|
} from "@firtoz/drizzle-indexeddb";
|
|
22
|
+
import type { CollectionUtils } from "@firtoz/db-helpers";
|
|
22
23
|
import type {
|
|
23
24
|
IdOf,
|
|
24
25
|
InsertSchema,
|
|
25
26
|
SelectSchema,
|
|
26
27
|
GetTableFromSchema,
|
|
27
28
|
InferCollectionFromTable,
|
|
28
|
-
CollectionUtils,
|
|
29
29
|
} from "@firtoz/drizzle-utils";
|
|
30
30
|
import {
|
|
31
31
|
type Migration,
|
|
@@ -33,7 +33,6 @@ import {
|
|
|
33
33
|
} from "../function-migrator";
|
|
34
34
|
import type { IDBCreator, IDBDatabaseLike } from "../idb-types";
|
|
35
35
|
import { openIndexedDb } from "../idb-operations";
|
|
36
|
-
import type { IDBProxySyncMessage } from "../proxy/idb-proxy-types";
|
|
37
36
|
|
|
38
37
|
interface CollectionCacheEntry {
|
|
39
38
|
// biome-ignore lint/suspicious/noExplicitAny: Cache needs to store collections of various types
|
|
@@ -65,11 +64,6 @@ export type DrizzleIndexedDBContextValue<
|
|
|
65
64
|
) => IndexedDbCollection<TSchema, TTableName>;
|
|
66
65
|
incrementRefCount: (tableName: string) => void;
|
|
67
66
|
decrementRefCount: (tableName: string) => void;
|
|
68
|
-
/**
|
|
69
|
-
* Handle a sync message from a proxy server.
|
|
70
|
-
* Routes the message to the appropriate collection's external sync handler.
|
|
71
|
-
*/
|
|
72
|
-
handleProxySync: (message: IDBProxySyncMessage) => void;
|
|
73
67
|
};
|
|
74
68
|
|
|
75
69
|
export const DrizzleIndexedDBContext =
|
|
@@ -94,18 +88,6 @@ type DrizzleIndexedDBProviderProps<TSchema extends Record<string, unknown>> =
|
|
|
94
88
|
* Use createInstrumentedDbCreator() to track IndexedDB operations.
|
|
95
89
|
*/
|
|
96
90
|
dbCreator?: IDBCreator;
|
|
97
|
-
/**
|
|
98
|
-
* Called when the sync handler is ready.
|
|
99
|
-
* Use this to connect proxy sync messages to the provider.
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* const proxyClient = ...;
|
|
103
|
-
* <DrizzleIndexedDBProvider
|
|
104
|
-
* onSyncReady={(handleSync) => proxyClient.onSync(handleSync)}
|
|
105
|
-
* ...
|
|
106
|
-
* />
|
|
107
|
-
*/
|
|
108
|
-
onSyncReady?: (handleSync: (message: IDBProxySyncMessage) => void) => void;
|
|
109
91
|
}>;
|
|
110
92
|
|
|
111
93
|
export function DrizzleIndexedDBProvider<
|
|
@@ -119,7 +101,6 @@ export function DrizzleIndexedDBProvider<
|
|
|
119
101
|
debug = false,
|
|
120
102
|
syncMode = "eager",
|
|
121
103
|
dbCreator,
|
|
122
|
-
onSyncReady,
|
|
123
104
|
}: DrizzleIndexedDBProviderProps<TSchema>) {
|
|
124
105
|
const [indexedDB, setIndexedDB] = useState<IDBDatabaseLike | null>(null);
|
|
125
106
|
const indexedDBRef = useRef<IDBDatabaseLike | null>(null);
|
|
@@ -248,80 +229,14 @@ export function DrizzleIndexedDBProvider<
|
|
|
248
229
|
[collections],
|
|
249
230
|
);
|
|
250
231
|
|
|
251
|
-
// Handle proxy sync messages by routing to the appropriate collection
|
|
252
|
-
const handleProxySync: DrizzleIndexedDBContextValue<TSchema>["handleProxySync"] =
|
|
253
|
-
useCallback(
|
|
254
|
-
(message: IDBProxySyncMessage) => {
|
|
255
|
-
// Find the collection for this store by checking the schema
|
|
256
|
-
for (const [tableName, table] of Object.entries(schema)) {
|
|
257
|
-
const actualStoreName = getTableName(table as Table);
|
|
258
|
-
if (actualStoreName === message.storeName) {
|
|
259
|
-
const entry = collections.get(tableName);
|
|
260
|
-
if (entry) {
|
|
261
|
-
const { pushExternalSync } = entry.collection.utils;
|
|
262
|
-
// Route sync message to collection
|
|
263
|
-
switch (message.type) {
|
|
264
|
-
case "sync:add":
|
|
265
|
-
pushExternalSync({
|
|
266
|
-
type: "insert",
|
|
267
|
-
items: message.items,
|
|
268
|
-
});
|
|
269
|
-
break;
|
|
270
|
-
case "sync:put":
|
|
271
|
-
pushExternalSync({
|
|
272
|
-
type: "update",
|
|
273
|
-
items: message.items,
|
|
274
|
-
});
|
|
275
|
-
break;
|
|
276
|
-
case "sync:delete":
|
|
277
|
-
// For delete, construct items with id
|
|
278
|
-
pushExternalSync({
|
|
279
|
-
type: "delete",
|
|
280
|
-
items: message.keys.map((key) => ({ id: key })),
|
|
281
|
-
});
|
|
282
|
-
break;
|
|
283
|
-
case "sync:truncate":
|
|
284
|
-
pushExternalSync({
|
|
285
|
-
type: "truncate",
|
|
286
|
-
});
|
|
287
|
-
break;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (debug) {
|
|
295
|
-
console.warn(
|
|
296
|
-
`[DrizzleIndexedDBProvider] No collection found for store: ${message.storeName}`,
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
},
|
|
300
|
-
[collections, schema, debug],
|
|
301
|
-
);
|
|
302
|
-
|
|
303
|
-
// Call onSyncReady when handleProxySync is available
|
|
304
|
-
useEffect(() => {
|
|
305
|
-
if (onSyncReady) {
|
|
306
|
-
onSyncReady(handleProxySync);
|
|
307
|
-
}
|
|
308
|
-
}, [onSyncReady, handleProxySync]);
|
|
309
|
-
|
|
310
232
|
const contextValue: DrizzleIndexedDBContextValue<TSchema> = useMemo(
|
|
311
233
|
() => ({
|
|
312
234
|
indexedDB,
|
|
313
235
|
getCollection,
|
|
314
236
|
incrementRefCount,
|
|
315
237
|
decrementRefCount,
|
|
316
|
-
handleProxySync,
|
|
317
238
|
}),
|
|
318
|
-
[
|
|
319
|
-
indexedDB,
|
|
320
|
-
getCollection,
|
|
321
|
-
incrementRefCount,
|
|
322
|
-
decrementRefCount,
|
|
323
|
-
handleProxySync,
|
|
324
|
-
],
|
|
239
|
+
[indexedDB, getCollection, incrementRefCount, decrementRefCount],
|
|
325
240
|
);
|
|
326
241
|
|
|
327
242
|
return (
|
package/src/function-migrator.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// IndexedDB migrator with declarative migration format
|
|
2
2
|
|
|
3
|
+
import { exhaustiveGuard } from "@firtoz/maybe-error";
|
|
3
4
|
import type { IDBCreator, IDBDatabaseLike } from "./idb-types";
|
|
4
5
|
import { openIndexedDb } from "./idb-operations";
|
|
5
6
|
|
|
@@ -107,6 +108,8 @@ function executeMigrationOperation(
|
|
|
107
108
|
}
|
|
108
109
|
break;
|
|
109
110
|
}
|
|
111
|
+
default:
|
|
112
|
+
exhaustiveGuard(op);
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
|
package/src/index.ts
CHANGED
|
@@ -59,30 +59,3 @@ export {
|
|
|
59
59
|
useDrizzleIndexedDB,
|
|
60
60
|
type UseDrizzleIndexedDBContextReturn,
|
|
61
61
|
} from "./context/useDrizzleIndexedDB";
|
|
62
|
-
|
|
63
|
-
// IDB Proxy (for Chrome extension, messaging-based IDB access)
|
|
64
|
-
export {
|
|
65
|
-
// Types
|
|
66
|
-
type IDBProxyRequest,
|
|
67
|
-
type IDBProxyRequestBody,
|
|
68
|
-
type IDBProxyResponse,
|
|
69
|
-
type IDBProxySyncMessage,
|
|
70
|
-
generateRequestId,
|
|
71
|
-
generateClientId,
|
|
72
|
-
// Transport
|
|
73
|
-
type IDBProxyClientTransport,
|
|
74
|
-
type IDBProxyServerTransport,
|
|
75
|
-
createInMemoryTransport,
|
|
76
|
-
createMultiClientTransport,
|
|
77
|
-
// Client
|
|
78
|
-
IDBProxyClient,
|
|
79
|
-
createProxyIDbCreator,
|
|
80
|
-
type SyncHandler,
|
|
81
|
-
// Server
|
|
82
|
-
IDBProxyServer,
|
|
83
|
-
createProxyServer,
|
|
84
|
-
type IDBProxyServerOptions,
|
|
85
|
-
// Sync adapter (connects proxy sync to collection)
|
|
86
|
-
createCollectionSyncHandler,
|
|
87
|
-
combineSyncHandlers,
|
|
88
|
-
} from "./proxy";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { exhaustiveGuard } from "@firtoz/maybe-error";
|
|
1
2
|
import type {
|
|
2
3
|
IDBDatabaseLike,
|
|
3
4
|
IDBCreator,
|
|
@@ -26,6 +27,8 @@ function createKeyRange(spec: KeyRangeSpec): IDBKeyRange {
|
|
|
26
27
|
spec.lowerOpen,
|
|
27
28
|
spec.upperOpen,
|
|
28
29
|
);
|
|
30
|
+
default:
|
|
31
|
+
exhaustiveGuard(spec.type);
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -8,12 +8,8 @@ import {
|
|
|
8
8
|
type WritableDeep,
|
|
9
9
|
} from "@tanstack/db";
|
|
10
10
|
import type { Table } from "drizzle-orm";
|
|
11
|
-
import type {
|
|
12
|
-
|
|
13
|
-
InsertSchema,
|
|
14
|
-
SelectSchema,
|
|
15
|
-
CollectionUtils,
|
|
16
|
-
} from "@firtoz/drizzle-utils";
|
|
11
|
+
import type { CollectionUtils } from "@firtoz/db-helpers";
|
|
12
|
+
import type { IdOf, InsertSchema, SelectSchema } from "@firtoz/drizzle-utils";
|
|
17
13
|
import {
|
|
18
14
|
indexedDBCollectionOptions,
|
|
19
15
|
type IndexedDBCollectionConfig,
|
|
@@ -151,7 +147,7 @@ export interface StandaloneCollection<TTable extends Table> {
|
|
|
151
147
|
truncate(): Promise<void>;
|
|
152
148
|
|
|
153
149
|
/**
|
|
154
|
-
* Access to collection utils (truncate,
|
|
150
|
+
* Access to collection utils (truncate, receiveSync)
|
|
155
151
|
*/
|
|
156
152
|
utils: CollectionUtils<ItemType<TTable>>;
|
|
157
153
|
|