@firtoz/drizzle-utils 1.2.0 → 1.3.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 +23 -0
- package/README.md +8 -1
- package/dist/chunk-7RBDVFVG.js +408 -0
- package/dist/chunk-7RBDVFVG.js.map +1 -0
- package/dist/chunk-J7DNZ25N.js +3 -0
- package/dist/chunk-J7DNZ25N.js.map +1 -0
- package/dist/chunk-JM254VLB.js +92 -0
- package/dist/chunk-JM254VLB.js.map +1 -0
- package/dist/chunk-LIICLRMB.js +45 -0
- package/dist/chunk-LIICLRMB.js.map +1 -0
- package/dist/chunk-TOYHUPFU.js +91 -0
- package/dist/chunk-TOYHUPFU.js.map +1 -0
- package/dist/collection-utils.d.ts +106 -0
- package/dist/collection-utils.js +3 -0
- package/dist/collection-utils.js.map +1 -0
- package/dist/drizzle-sqlite-table-collection.d.ts +19 -0
- package/dist/drizzle-sqlite-table-collection.js +3 -0
- package/dist/drizzle-sqlite-table-collection.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/sqlite-table-sync/convert-ir.d.ts +10 -0
- package/dist/sqlite-table-sync/convert-ir.js +3 -0
- package/dist/sqlite-table-sync/convert-ir.js.map +1 -0
- package/dist/sqlite-table-sync/index.d.ts +11 -0
- package/dist/sqlite-table-sync/index.js +5 -0
- package/dist/sqlite-table-sync/index.js.map +1 -0
- package/dist/sqlite-table-sync/sqlite-table-sync-backend.d.ts +28 -0
- package/dist/sqlite-table-sync/sqlite-table-sync-backend.js +4 -0
- package/dist/sqlite-table-sync/sqlite-table-sync-backend.js.map +1 -0
- package/dist/sqlite-table-sync/types.d.ts +59 -0
- package/dist/sqlite-table-sync/types.js +3 -0
- package/dist/sqlite-table-sync/types.js.map +1 -0
- package/dist/syncableTable.d.ts +49 -0
- package/dist/syncableTable.js +3 -0
- package/dist/syncableTable.js.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +25 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @firtoz/drizzle-utils
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`c3a3cc7`](https://github.com/firtoz/fullstack-toolkit/commit/c3a3cc778ba9ce4b5efe1bcdd8d541f46dec3bfd) Thanks [@firtoz](https://github.com/firtoz)! - Publish compiled ESM and TypeScript declarations from `dist/` for each package (`tsup`, `prepack` build). `exports`, `main`, and `types` resolve to `dist/`; CLI bins point at built JS with a Node shebang where applicable. Shared `scripts/tsup-lib.ts` discovers `src` entries and externals; workspace test apps map `@firtoz/*` to package sources in `tsconfig` for accurate generics during typecheck. `@firtoz/socka` is published under the scoped name with the same `dist/` layout.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [`f78c988`](https://github.com/firtoz/fullstack-toolkit/commit/f78c988d37a9cc48490ee3372dccc14a42810bfe) Thanks [@firtoz](https://github.com/firtoz)! - Improve READMEs: npm shields, contextual stack badges, clearer taglines, and new docs for `@firtoz/idb-collections` and `@firtoz/collection-sync`. Align `@firtoz/db-helpers` copy with published `dist/` builds.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`c3a3cc7`](https://github.com/firtoz/fullstack-toolkit/commit/c3a3cc778ba9ce4b5efe1bcdd8d541f46dec3bfd), [`f78c988`](https://github.com/firtoz/fullstack-toolkit/commit/f78c988d37a9cc48490ee3372dccc14a42810bfe)]:
|
|
14
|
+
- @firtoz/db-helpers@2.2.0
|
|
15
|
+
- @firtoz/maybe-error@1.6.0
|
|
16
|
+
|
|
17
|
+
## 1.2.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#70](https://github.com/firtoz/fullstack-toolkit/pull/70) [`138c394`](https://github.com/firtoz/fullstack-toolkit/commit/138c3944b491ebf2e76b7f2c00d651fd5d788bac) Thanks [@firtoz](https://github.com/firtoz)! - Raise TanStack DB peer range to `>=0.6.3` where applicable. `createGenericCollectionConfig` now sets `defaultIndexType: BasicIndex` and `autoIndex: "eager"` so Drizzle-backed collections match pre-0.6 indexing defaults for `orderBy`/`limit` live queries. Re-enable `DeduplicatedLoadSubset` (`USE_DEDUPE`) with `@tanstack/db` 0.6.4.
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [[`138c394`](https://github.com/firtoz/fullstack-toolkit/commit/138c3944b491ebf2e76b7f2c00d651fd5d788bac)]:
|
|
24
|
+
- @firtoz/db-helpers@2.1.1
|
|
25
|
+
|
|
3
26
|
## 1.2.0
|
|
4
27
|
|
|
5
28
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# @firtoz/drizzle-utils
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@firtoz/drizzle-utils)
|
|
4
|
+
[](https://www.npmjs.com/package/@firtoz/drizzle-utils)
|
|
5
|
+
[](https://github.com/firtoz/fullstack-toolkit/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://orm.drizzle.team/)
|
|
9
|
+
|
|
10
|
+
**Shared utilities for Drizzle-based stacks** — syncable table builders, branded IDs, migration helpers, and collection-sync primitives shared across `@firtoz/drizzle-*` packages.
|
|
4
11
|
|
|
5
12
|
> **⚠️ Early WIP Notice:** This package is in very early development and is **not production-ready**. It is TypeScript-only and may have breaking changes. While I (the maintainer) have limited time, I'm open to PRs for features, bug fixes, or additional support (like JS builds). Please feel free to try it out and contribute! See [CONTRIBUTING.md](../../CONTRIBUTING.md) for details.
|
|
6
13
|
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { convertBasicExpressionToDrizzle, convertOrderByToDrizzle } from './chunk-JM254VLB.js';
|
|
2
|
+
import { exhaustiveGuard } from '@firtoz/maybe-error';
|
|
3
|
+
import { and, eq, getTableColumns, sql } from 'drizzle-orm';
|
|
4
|
+
|
|
5
|
+
function sqliteExcludedUpsertSet(table) {
|
|
6
|
+
const cols = getTableColumns(table);
|
|
7
|
+
const set = {};
|
|
8
|
+
for (const [jsName, col] of Object.entries(cols)) {
|
|
9
|
+
if (jsName === "id") continue;
|
|
10
|
+
set[jsName] = sql.raw(`excluded."${col.name}"`);
|
|
11
|
+
}
|
|
12
|
+
return set;
|
|
13
|
+
}
|
|
14
|
+
function createSqliteTableSyncBackend(config) {
|
|
15
|
+
const table = config.table;
|
|
16
|
+
const driverMode = config.driverMode;
|
|
17
|
+
let transactionQueue = Promise.resolve();
|
|
18
|
+
const queueTransaction = (_label, fn) => {
|
|
19
|
+
const run = () => fn();
|
|
20
|
+
const result = transactionQueue.then(run, run);
|
|
21
|
+
transactionQueue = result.then(
|
|
22
|
+
() => {
|
|
23
|
+
},
|
|
24
|
+
() => {
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
const backend = {
|
|
30
|
+
initialLoad: async () => {
|
|
31
|
+
const items = await config.drizzle.select().from(table);
|
|
32
|
+
if (config.interceptor?.onOperation) {
|
|
33
|
+
config.interceptor.onOperation({
|
|
34
|
+
type: "select-all",
|
|
35
|
+
tableName: config.tableName,
|
|
36
|
+
itemsReturned: items,
|
|
37
|
+
itemCount: items.length,
|
|
38
|
+
context: "Initial load (eager mode)",
|
|
39
|
+
timestamp: Date.now()
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (config.interceptor?.onOperation) {
|
|
43
|
+
config.interceptor.onOperation({
|
|
44
|
+
type: "write",
|
|
45
|
+
tableName: config.tableName,
|
|
46
|
+
itemsWritten: items,
|
|
47
|
+
writeCount: items.length,
|
|
48
|
+
context: "Initial load (eager mode)",
|
|
49
|
+
timestamp: Date.now()
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return items;
|
|
53
|
+
},
|
|
54
|
+
loadSubset: async (options) => {
|
|
55
|
+
let query = config.drizzle.select().from(table).$dynamic();
|
|
56
|
+
let hasWhere = false;
|
|
57
|
+
if (options.where || options.cursor?.whereFrom) {
|
|
58
|
+
let drizzleWhere;
|
|
59
|
+
if (options.where && options.cursor?.whereFrom) {
|
|
60
|
+
const mainWhere = convertBasicExpressionToDrizzle(
|
|
61
|
+
options.where,
|
|
62
|
+
table
|
|
63
|
+
);
|
|
64
|
+
const cursorWhere = convertBasicExpressionToDrizzle(
|
|
65
|
+
options.cursor.whereFrom,
|
|
66
|
+
table
|
|
67
|
+
);
|
|
68
|
+
drizzleWhere = and(mainWhere, cursorWhere);
|
|
69
|
+
} else if (options.where) {
|
|
70
|
+
drizzleWhere = convertBasicExpressionToDrizzle(options.where, table);
|
|
71
|
+
} else if (options.cursor?.whereFrom) {
|
|
72
|
+
drizzleWhere = convertBasicExpressionToDrizzle(
|
|
73
|
+
options.cursor.whereFrom,
|
|
74
|
+
table
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (drizzleWhere) {
|
|
78
|
+
query = query.where(drizzleWhere);
|
|
79
|
+
hasWhere = true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (options.orderBy) {
|
|
83
|
+
const drizzleOrderBy = convertOrderByToDrizzle(options.orderBy, table);
|
|
84
|
+
query = query.orderBy(...drizzleOrderBy);
|
|
85
|
+
}
|
|
86
|
+
if (options.limit !== void 0) {
|
|
87
|
+
query = query.limit(options.limit);
|
|
88
|
+
}
|
|
89
|
+
if (options.offset !== void 0 && options.offset > 0) {
|
|
90
|
+
query = query.offset(options.offset);
|
|
91
|
+
}
|
|
92
|
+
const items = await query;
|
|
93
|
+
if (config.interceptor?.onOperation) {
|
|
94
|
+
const contextParts = ["On-demand load"];
|
|
95
|
+
if (options.orderBy) contextParts.push("with sorting");
|
|
96
|
+
if (options.limit !== void 0)
|
|
97
|
+
contextParts.push(`limit ${options.limit}`);
|
|
98
|
+
if (options.offset !== void 0 && options.offset > 0)
|
|
99
|
+
contextParts.push(`offset ${options.offset}`);
|
|
100
|
+
if (options.cursor) contextParts.push("with cursor pagination");
|
|
101
|
+
if (hasWhere) {
|
|
102
|
+
config.interceptor.onOperation({
|
|
103
|
+
type: "select-where",
|
|
104
|
+
tableName: config.tableName,
|
|
105
|
+
whereClause: "WHERE clause applied",
|
|
106
|
+
itemsReturned: items,
|
|
107
|
+
itemCount: items.length,
|
|
108
|
+
context: contextParts.join(", "),
|
|
109
|
+
timestamp: Date.now()
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
config.interceptor.onOperation({
|
|
113
|
+
type: "select-all",
|
|
114
|
+
tableName: config.tableName,
|
|
115
|
+
itemsReturned: items,
|
|
116
|
+
itemCount: items.length,
|
|
117
|
+
context: contextParts.join(", "),
|
|
118
|
+
timestamp: Date.now()
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (config.interceptor?.onOperation) {
|
|
123
|
+
const contextParts = ["On-demand load"];
|
|
124
|
+
if (hasWhere) contextParts.push("with WHERE clause");
|
|
125
|
+
if (options.orderBy) contextParts.push("with sorting");
|
|
126
|
+
if (options.limit !== void 0)
|
|
127
|
+
contextParts.push(`limit ${options.limit}`);
|
|
128
|
+
if (options.offset !== void 0 && options.offset > 0)
|
|
129
|
+
contextParts.push(`offset ${options.offset}`);
|
|
130
|
+
config.interceptor.onOperation({
|
|
131
|
+
type: "write",
|
|
132
|
+
tableName: config.tableName,
|
|
133
|
+
itemsWritten: items,
|
|
134
|
+
writeCount: items.length,
|
|
135
|
+
context: contextParts.join(", "),
|
|
136
|
+
timestamp: Date.now()
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return items;
|
|
140
|
+
},
|
|
141
|
+
handleInsert: async (items) => {
|
|
142
|
+
const results = [];
|
|
143
|
+
await queueTransaction("handleInsert", async () => {
|
|
144
|
+
if (driverMode === "sync") {
|
|
145
|
+
config.drizzle.transaction((tx) => {
|
|
146
|
+
for (const itemToInsert of items) {
|
|
147
|
+
if (config.debug) {
|
|
148
|
+
console.log(
|
|
149
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] insertListener inserting`,
|
|
150
|
+
itemToInsert
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const result = tx.insert(table).values(
|
|
154
|
+
itemToInsert
|
|
155
|
+
).onConflictDoUpdate({
|
|
156
|
+
target: table.id,
|
|
157
|
+
set: sqliteExcludedUpsertSet(table)
|
|
158
|
+
}).returning().all();
|
|
159
|
+
if (config.debug) {
|
|
160
|
+
console.log(
|
|
161
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] insertListener result`,
|
|
162
|
+
result
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (result.length > 0) {
|
|
166
|
+
results.push(result[0]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
await config.drizzle.transaction(
|
|
172
|
+
async (tx) => {
|
|
173
|
+
for (const itemToInsert of items) {
|
|
174
|
+
if (config.debug) {
|
|
175
|
+
console.log(
|
|
176
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] insertListener inserting`,
|
|
177
|
+
itemToInsert
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
const result = await tx.insert(table).values(
|
|
181
|
+
itemToInsert
|
|
182
|
+
).onConflictDoUpdate({
|
|
183
|
+
target: table.id,
|
|
184
|
+
set: sqliteExcludedUpsertSet(table)
|
|
185
|
+
}).returning();
|
|
186
|
+
if (config.debug) {
|
|
187
|
+
console.log(
|
|
188
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] insertListener result`,
|
|
189
|
+
result
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
if (result.length > 0) {
|
|
193
|
+
results.push(result[0]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
if (config.checkpoint) {
|
|
200
|
+
await config.checkpoint();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
return results;
|
|
204
|
+
},
|
|
205
|
+
handleUpdate: async (mutations) => {
|
|
206
|
+
const results = [];
|
|
207
|
+
await queueTransaction("handleUpdate", async () => {
|
|
208
|
+
if (driverMode === "sync") {
|
|
209
|
+
config.drizzle.transaction((tx) => {
|
|
210
|
+
for (const mutation of mutations) {
|
|
211
|
+
if (config.debug) {
|
|
212
|
+
console.log(
|
|
213
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] updateListener updating`,
|
|
214
|
+
mutation
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
const updateTime = /* @__PURE__ */ new Date();
|
|
218
|
+
const result = tx.update(table).set({
|
|
219
|
+
...mutation.changes,
|
|
220
|
+
updatedAt: updateTime
|
|
221
|
+
}).where(eq(table.id, mutation.key)).returning().all();
|
|
222
|
+
if (config.debug) {
|
|
223
|
+
console.log(
|
|
224
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] updateListener result`,
|
|
225
|
+
result
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
results.push(...result);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
} else {
|
|
232
|
+
await config.drizzle.transaction(
|
|
233
|
+
async (tx) => {
|
|
234
|
+
for (const mutation of mutations) {
|
|
235
|
+
if (config.debug) {
|
|
236
|
+
console.log(
|
|
237
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] updateListener updating`,
|
|
238
|
+
mutation
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const updateTime = /* @__PURE__ */ new Date();
|
|
242
|
+
const result = await tx.update(table).set({
|
|
243
|
+
...mutation.changes,
|
|
244
|
+
updatedAt: updateTime
|
|
245
|
+
}).where(eq(table.id, mutation.key)).returning();
|
|
246
|
+
if (config.debug) {
|
|
247
|
+
console.log(
|
|
248
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] updateListener result`,
|
|
249
|
+
result
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
results.push(...result);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
if (config.checkpoint) {
|
|
258
|
+
await config.checkpoint();
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
return results;
|
|
262
|
+
},
|
|
263
|
+
handleDelete: async (mutations) => {
|
|
264
|
+
await queueTransaction("handleDelete", async () => {
|
|
265
|
+
if (driverMode === "sync") {
|
|
266
|
+
config.drizzle.transaction((tx) => {
|
|
267
|
+
for (const mutation of mutations) {
|
|
268
|
+
tx.delete(table).where(eq(table.id, mutation.key)).run();
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
} else {
|
|
272
|
+
await config.drizzle.transaction(
|
|
273
|
+
async (tx) => {
|
|
274
|
+
for (const mutation of mutations) {
|
|
275
|
+
await tx.delete(table).where(eq(table.id, mutation.key));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
if (config.checkpoint) {
|
|
281
|
+
await config.checkpoint();
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
},
|
|
285
|
+
handleTruncate: async () => {
|
|
286
|
+
await queueTransaction("handleTruncate", async () => {
|
|
287
|
+
if (driverMode === "sync") {
|
|
288
|
+
config.drizzle.transaction((tx) => {
|
|
289
|
+
tx.delete(table).run();
|
|
290
|
+
});
|
|
291
|
+
} else {
|
|
292
|
+
await config.drizzle.transaction(
|
|
293
|
+
async (tx) => {
|
|
294
|
+
await tx.delete(table);
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
if (config.checkpoint) {
|
|
299
|
+
await config.checkpoint();
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
applyReceiveSyncDurableWrites: async (ops) => {
|
|
304
|
+
if (ops.length === 0) return;
|
|
305
|
+
await queueTransaction("applyReceiveSyncDurableWrites", async () => {
|
|
306
|
+
if (driverMode === "sync") {
|
|
307
|
+
config.drizzle.transaction((tx) => {
|
|
308
|
+
for (const op of ops) {
|
|
309
|
+
switch (op.type) {
|
|
310
|
+
case "insert": {
|
|
311
|
+
if (config.debug) {
|
|
312
|
+
console.log(
|
|
313
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] receiveSync batch insert`,
|
|
314
|
+
op.value
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
tx.insert(table).values(
|
|
318
|
+
op.value
|
|
319
|
+
).onConflictDoUpdate({
|
|
320
|
+
target: table.id,
|
|
321
|
+
set: sqliteExcludedUpsertSet(table)
|
|
322
|
+
}).run();
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
case "update": {
|
|
326
|
+
if (config.debug) {
|
|
327
|
+
console.log(
|
|
328
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] receiveSync batch update`,
|
|
329
|
+
op
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
const updateTime = /* @__PURE__ */ new Date();
|
|
333
|
+
tx.update(table).set({
|
|
334
|
+
...op.changes,
|
|
335
|
+
updatedAt: updateTime
|
|
336
|
+
}).where(eq(table.id, op.key)).run();
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
case "delete":
|
|
340
|
+
tx.delete(table).where(eq(table.id, op.key)).run();
|
|
341
|
+
break;
|
|
342
|
+
case "truncate":
|
|
343
|
+
tx.delete(table).run();
|
|
344
|
+
break;
|
|
345
|
+
default:
|
|
346
|
+
exhaustiveGuard(op);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
} else {
|
|
351
|
+
await config.drizzle.transaction(
|
|
352
|
+
async (tx) => {
|
|
353
|
+
for (const op of ops) {
|
|
354
|
+
switch (op.type) {
|
|
355
|
+
case "insert": {
|
|
356
|
+
if (config.debug) {
|
|
357
|
+
console.log(
|
|
358
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] receiveSync batch insert`,
|
|
359
|
+
op.value
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
await tx.insert(table).values(
|
|
363
|
+
op.value
|
|
364
|
+
).onConflictDoUpdate({
|
|
365
|
+
target: table.id,
|
|
366
|
+
set: sqliteExcludedUpsertSet(table)
|
|
367
|
+
});
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case "update": {
|
|
371
|
+
if (config.debug) {
|
|
372
|
+
console.log(
|
|
373
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] receiveSync batch update`,
|
|
374
|
+
op
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
const updateTime = /* @__PURE__ */ new Date();
|
|
378
|
+
await tx.update(table).set({
|
|
379
|
+
...op.changes,
|
|
380
|
+
updatedAt: updateTime
|
|
381
|
+
}).where(eq(table.id, op.key));
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
case "delete":
|
|
385
|
+
await tx.delete(table).where(eq(table.id, op.key));
|
|
386
|
+
break;
|
|
387
|
+
case "truncate":
|
|
388
|
+
await tx.delete(table);
|
|
389
|
+
break;
|
|
390
|
+
default:
|
|
391
|
+
exhaustiveGuard(op);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
if (config.checkpoint) {
|
|
398
|
+
await config.checkpoint();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
return backend;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export { createSqliteTableSyncBackend };
|
|
407
|
+
//# sourceMappingURL=chunk-7RBDVFVG.js.map
|
|
408
|
+
//# sourceMappingURL=chunk-7RBDVFVG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sqlite-table-sync/sqlite-table-sync-backend.ts"],"names":[],"mappings":"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","file":"chunk-7RBDVFVG.js","sourcesContent":["import type { ReceiveSyncDurableOp } from \"@firtoz/db-helpers\";\nimport { exhaustiveGuard } from \"@firtoz/maybe-error\";\nimport type { InferSchemaOutput } from \"@tanstack/db\";\nimport { and, eq, getTableColumns, sql, type SQL } from \"drizzle-orm\";\nimport type {\n\tSQLiteInsertValue,\n\tSQLiteUpdateSetSource,\n} from \"drizzle-orm/sqlite-core\";\nimport type { SelectSchema, SyncBackend } from \"../collection-utils\";\nimport type { TableWithRequiredFields } from \"../syncableTable\";\nimport {\n\tconvertBasicExpressionToDrizzle,\n\tconvertOrderByToDrizzle,\n} from \"./convert-ir\";\nimport type { SQLInterceptor } from \"./types\";\n\nexport type SqliteDriverMode = \"async\" | \"sync\";\n\n/**\n * `ON CONFLICT DO UPDATE` set map using SQLite `excluded.*` so inserts are idempotent\n * (matches IndexedDB `put` / replayed partial-sync rows already present from `initialLoad`).\n */\nfunction sqliteExcludedUpsertSet<TTable extends TableWithRequiredFields>(\n\ttable: TTable,\n): SQLiteUpdateSetSource<TTable> {\n\tconst cols = getTableColumns(table);\n\tconst set: Record<string, SQL> = {};\n\tfor (const [jsName, col] of Object.entries(cols)) {\n\t\tif (jsName === \"id\") continue;\n\t\tset[jsName] = sql.raw(`excluded.\"${col.name}\"`);\n\t}\n\treturn set as SQLiteUpdateSetSource<TTable>;\n}\n\nexport interface SqliteTableSyncBackendConfig<\n\tTTable extends TableWithRequiredFields,\n> {\n\t/** drizzle-orm SQLite database (async WASM/libsql or sync Durable Object) */\n\t// biome-ignore lint/suspicious/noExplicitAny: generic over sync/async Drizzle DB shapes\n\tdrizzle: any;\n\ttable: TTable;\n\ttableName: string;\n\tdebug?: boolean;\n\tcheckpoint?: () => Promise<void>;\n\tinterceptor?: SQLInterceptor;\n\t/**\n\t * `async`: libsql/WASM — use `await db.transaction(async (tx) => …)`.\n\t * `sync`: Cloudflare DO SQLite — `transactionSync` requires a **synchronous** callback; use `.all()` / `.run()` on builders inside `tx`.\n\t */\n\tdriverMode: SqliteDriverMode;\n}\n\nexport function createSqliteTableSyncBackend<\n\tTTable extends TableWithRequiredFields,\n>(config: SqliteTableSyncBackendConfig<TTable>): SyncBackend<TTable> {\n\ttype TItem = InferSchemaOutput<SelectSchema<TTable>>;\n\tconst table = config.table;\n\tconst driverMode = config.driverMode;\n\n\tlet transactionQueue = Promise.resolve();\n\tconst queueTransaction = <T>(\n\t\t_label: string,\n\t\tfn: () => Promise<T>,\n\t): Promise<T> => {\n\t\tconst run = (): Promise<T> => fn();\n\t\tconst result = transactionQueue.then(run, run);\n\t\ttransactionQueue = result.then(\n\t\t\t() => {},\n\t\t\t() => {},\n\t\t);\n\t\treturn result;\n\t};\n\n\tconst backend: SyncBackend<TTable> = {\n\t\tinitialLoad: async () => {\n\t\t\tconst items = (await config.drizzle\n\t\t\t\t.select()\n\t\t\t\t.from(table)) as unknown as InferSchemaOutput<SelectSchema<TTable>>[];\n\n\t\t\tif (config.interceptor?.onOperation) {\n\t\t\t\tconfig.interceptor.onOperation({\n\t\t\t\t\ttype: \"select-all\",\n\t\t\t\t\ttableName: config.tableName,\n\t\t\t\t\titemsReturned: items,\n\t\t\t\t\titemCount: items.length,\n\t\t\t\t\tcontext: \"Initial load (eager mode)\",\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (config.interceptor?.onOperation) {\n\t\t\t\tconfig.interceptor.onOperation({\n\t\t\t\t\ttype: \"write\",\n\t\t\t\t\ttableName: config.tableName,\n\t\t\t\t\titemsWritten: items,\n\t\t\t\t\twriteCount: items.length,\n\t\t\t\t\tcontext: \"Initial load (eager mode)\",\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn items as unknown as InferSchemaOutput<SelectSchema<TTable>>[];\n\t\t},\n\n\t\tloadSubset: async (options) => {\n\t\t\tlet query = config.drizzle.select().from(table).$dynamic();\n\n\t\t\tlet hasWhere = false;\n\t\t\tif (options.where || options.cursor?.whereFrom) {\n\t\t\t\tlet drizzleWhere: SQL | undefined;\n\n\t\t\t\tif (options.where && options.cursor?.whereFrom) {\n\t\t\t\t\tconst mainWhere = convertBasicExpressionToDrizzle(\n\t\t\t\t\t\toptions.where,\n\t\t\t\t\t\ttable,\n\t\t\t\t\t);\n\t\t\t\t\tconst cursorWhere = convertBasicExpressionToDrizzle(\n\t\t\t\t\t\toptions.cursor.whereFrom,\n\t\t\t\t\t\ttable,\n\t\t\t\t\t);\n\t\t\t\t\tdrizzleWhere = and(mainWhere, cursorWhere);\n\t\t\t\t} else if (options.where) {\n\t\t\t\t\tdrizzleWhere = convertBasicExpressionToDrizzle(options.where, table);\n\t\t\t\t} else if (options.cursor?.whereFrom) {\n\t\t\t\t\tdrizzleWhere = convertBasicExpressionToDrizzle(\n\t\t\t\t\t\toptions.cursor.whereFrom,\n\t\t\t\t\t\ttable,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (drizzleWhere) {\n\t\t\t\t\tquery = query.where(drizzleWhere);\n\t\t\t\t\thasWhere = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (options.orderBy) {\n\t\t\t\tconst drizzleOrderBy = convertOrderByToDrizzle(options.orderBy, table);\n\t\t\t\tquery = query.orderBy(...drizzleOrderBy);\n\t\t\t}\n\n\t\t\tif (options.limit !== undefined) {\n\t\t\t\tquery = query.limit(options.limit);\n\t\t\t}\n\n\t\t\tif (options.offset !== undefined && options.offset > 0) {\n\t\t\t\tquery = query.offset(options.offset);\n\t\t\t}\n\n\t\t\tconst items = (await query) as unknown as InferSchemaOutput<\n\t\t\t\tSelectSchema<TTable>\n\t\t\t>[];\n\n\t\t\tif (config.interceptor?.onOperation) {\n\t\t\t\tconst contextParts: string[] = [\"On-demand load\"];\n\t\t\t\tif (options.orderBy) contextParts.push(\"with sorting\");\n\t\t\t\tif (options.limit !== undefined)\n\t\t\t\t\tcontextParts.push(`limit ${options.limit}`);\n\t\t\t\tif (options.offset !== undefined && options.offset > 0)\n\t\t\t\t\tcontextParts.push(`offset ${options.offset}`);\n\t\t\t\tif (options.cursor) contextParts.push(\"with cursor pagination\");\n\n\t\t\t\tif (hasWhere) {\n\t\t\t\t\tconfig.interceptor.onOperation({\n\t\t\t\t\t\ttype: \"select-where\",\n\t\t\t\t\t\ttableName: config.tableName,\n\t\t\t\t\t\twhereClause: \"WHERE clause applied\",\n\t\t\t\t\t\titemsReturned: items,\n\t\t\t\t\t\titemCount: items.length,\n\t\t\t\t\t\tcontext: contextParts.join(\", \"),\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconfig.interceptor.onOperation({\n\t\t\t\t\t\ttype: \"select-all\",\n\t\t\t\t\t\ttableName: config.tableName,\n\t\t\t\t\t\titemsReturned: items,\n\t\t\t\t\t\titemCount: items.length,\n\t\t\t\t\t\tcontext: contextParts.join(\", \"),\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (config.interceptor?.onOperation) {\n\t\t\t\tconst contextParts: string[] = [\"On-demand load\"];\n\t\t\t\tif (hasWhere) contextParts.push(\"with WHERE clause\");\n\t\t\t\tif (options.orderBy) contextParts.push(\"with sorting\");\n\t\t\t\tif (options.limit !== undefined)\n\t\t\t\t\tcontextParts.push(`limit ${options.limit}`);\n\t\t\t\tif (options.offset !== undefined && options.offset > 0)\n\t\t\t\t\tcontextParts.push(`offset ${options.offset}`);\n\n\t\t\t\tconfig.interceptor.onOperation({\n\t\t\t\t\ttype: \"write\",\n\t\t\t\t\ttableName: config.tableName,\n\t\t\t\t\titemsWritten: items,\n\t\t\t\t\twriteCount: items.length,\n\t\t\t\t\tcontext: contextParts.join(\", \"),\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn items as unknown as InferSchemaOutput<SelectSchema<TTable>>[];\n\t\t},\n\n\t\thandleInsert: async (items) => {\n\t\t\tconst results: Array<InferSchemaOutput<SelectSchema<TTable>>> = [];\n\n\t\t\tawait queueTransaction(\"handleInsert\", async () => {\n\t\t\t\tif (driverMode === \"sync\") {\n\t\t\t\t\tconfig.drizzle.transaction((tx: typeof config.drizzle) => {\n\t\t\t\t\t\tfor (const itemToInsert of items) {\n\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] insertListener inserting`,\n\t\t\t\t\t\t\t\t\titemToInsert,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst result = tx\n\t\t\t\t\t\t\t\t.insert(table)\n\t\t\t\t\t\t\t\t.values(\n\t\t\t\t\t\t\t\t\titemToInsert as unknown as SQLiteInsertValue<typeof table>,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\t\t\t\t\ttarget: table.id,\n\t\t\t\t\t\t\t\t\tset: sqliteExcludedUpsertSet(table),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.returning()\n\t\t\t\t\t\t\t\t.all() as Array<InferSchemaOutput<SelectSchema<TTable>>>;\n\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] insertListener result`,\n\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (result.length > 0) {\n\t\t\t\t\t\t\t\tresults.push(result[0]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait config.drizzle.transaction(\n\t\t\t\t\t\tasync (tx: typeof config.drizzle) => {\n\t\t\t\t\t\t\tfor (const itemToInsert of items) {\n\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] insertListener inserting`,\n\t\t\t\t\t\t\t\t\t\titemToInsert,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst result = (await tx\n\t\t\t\t\t\t\t\t\t.insert(table)\n\t\t\t\t\t\t\t\t\t.values(\n\t\t\t\t\t\t\t\t\t\titemToInsert as unknown as SQLiteInsertValue<typeof table>,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\t\t\t\t\t\ttarget: table.id,\n\t\t\t\t\t\t\t\t\t\tset: sqliteExcludedUpsertSet(table),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.returning()) as Array<\n\t\t\t\t\t\t\t\t\tInferSchemaOutput<SelectSchema<TTable>>\n\t\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] insertListener result`,\n\t\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (result.length > 0) {\n\t\t\t\t\t\t\t\t\tresults.push(result[0]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config.checkpoint) {\n\t\t\t\t\tawait config.checkpoint();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn results;\n\t\t},\n\n\t\thandleUpdate: async (mutations) => {\n\t\t\tconst results: Array<InferSchemaOutput<SelectSchema<TTable>>> = [];\n\n\t\t\tawait queueTransaction(\"handleUpdate\", async () => {\n\t\t\t\tif (driverMode === \"sync\") {\n\t\t\t\t\tconfig.drizzle.transaction((tx: typeof config.drizzle) => {\n\t\t\t\t\t\tfor (const mutation of mutations) {\n\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] updateListener updating`,\n\t\t\t\t\t\t\t\t\tmutation,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst updateTime = new Date();\n\t\t\t\t\t\t\tconst result = tx\n\t\t\t\t\t\t\t\t.update(table)\n\t\t\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\t\t\t...mutation.changes,\n\t\t\t\t\t\t\t\t\tupdatedAt: updateTime,\n\t\t\t\t\t\t\t\t} as SQLiteUpdateSetSource<typeof table>)\n\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t.where(eq(table.id, mutation.key as any))\n\t\t\t\t\t\t\t\t.returning()\n\t\t\t\t\t\t\t\t.all() as Array<InferSchemaOutput<SelectSchema<TTable>>>;\n\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] updateListener result`,\n\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresults.push(...result);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait config.drizzle.transaction(\n\t\t\t\t\t\tasync (tx: typeof config.drizzle) => {\n\t\t\t\t\t\t\tfor (const mutation of mutations) {\n\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] updateListener updating`,\n\t\t\t\t\t\t\t\t\t\tmutation,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst updateTime = new Date();\n\t\t\t\t\t\t\t\tconst result = (await tx\n\t\t\t\t\t\t\t\t\t.update(table)\n\t\t\t\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\t\t\t\t...mutation.changes,\n\t\t\t\t\t\t\t\t\t\tupdatedAt: updateTime,\n\t\t\t\t\t\t\t\t\t} as SQLiteUpdateSetSource<typeof table>)\n\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t.where(eq(table.id, mutation.key as any))\n\t\t\t\t\t\t\t\t\t.returning()) as Array<\n\t\t\t\t\t\t\t\t\tInferSchemaOutput<SelectSchema<TTable>>\n\t\t\t\t\t\t\t\t>;\n\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] updateListener result`,\n\t\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tresults.push(...result);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config.checkpoint) {\n\t\t\t\t\tawait config.checkpoint();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn results;\n\t\t},\n\n\t\thandleDelete: async (mutations) => {\n\t\t\tawait queueTransaction(\"handleDelete\", async () => {\n\t\t\t\tif (driverMode === \"sync\") {\n\t\t\t\t\tconfig.drizzle.transaction((tx: typeof config.drizzle) => {\n\t\t\t\t\t\tfor (const mutation of mutations) {\n\t\t\t\t\t\t\ttx.delete(table)\n\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t.where(eq(table.id, mutation.key as any))\n\t\t\t\t\t\t\t\t.run();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait config.drizzle.transaction(\n\t\t\t\t\t\tasync (tx: typeof config.drizzle) => {\n\t\t\t\t\t\t\tfor (const mutation of mutations) {\n\t\t\t\t\t\t\t\tawait tx\n\t\t\t\t\t\t\t\t\t.delete(table)\n\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t.where(eq(table.id, mutation.key as any));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config.checkpoint) {\n\t\t\t\t\tawait config.checkpoint();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\thandleTruncate: async () => {\n\t\t\tawait queueTransaction(\"handleTruncate\", async () => {\n\t\t\t\tif (driverMode === \"sync\") {\n\t\t\t\t\tconfig.drizzle.transaction((tx: typeof config.drizzle) => {\n\t\t\t\t\t\ttx.delete(table).run();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait config.drizzle.transaction(\n\t\t\t\t\t\tasync (tx: typeof config.drizzle) => {\n\t\t\t\t\t\t\tawait tx.delete(table);\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config.checkpoint) {\n\t\t\t\t\tawait config.checkpoint();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tapplyReceiveSyncDurableWrites: async (\n\t\t\tops: ReceiveSyncDurableOp<TItem>[],\n\t\t) => {\n\t\t\tif (ops.length === 0) return;\n\n\t\t\tawait queueTransaction(\"applyReceiveSyncDurableWrites\", async () => {\n\t\t\t\tif (driverMode === \"sync\") {\n\t\t\t\t\tconfig.drizzle.transaction((tx: typeof config.drizzle) => {\n\t\t\t\t\t\tfor (const op of ops) {\n\t\t\t\t\t\t\tswitch (op.type) {\n\t\t\t\t\t\t\t\tcase \"insert\": {\n\t\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] receiveSync batch insert`,\n\t\t\t\t\t\t\t\t\t\t\top.value,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttx.insert(table)\n\t\t\t\t\t\t\t\t\t\t.values(\n\t\t\t\t\t\t\t\t\t\t\top.value as unknown as SQLiteInsertValue<typeof table>,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\t\t\t\t\t\t\ttarget: table.id,\n\t\t\t\t\t\t\t\t\t\t\tset: sqliteExcludedUpsertSet(table),\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t.run();\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] receiveSync batch update`,\n\t\t\t\t\t\t\t\t\t\t\top,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst updateTime = new Date();\n\t\t\t\t\t\t\t\t\ttx.update(table)\n\t\t\t\t\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\t\t\t\t\t...op.changes,\n\t\t\t\t\t\t\t\t\t\t\tupdatedAt: updateTime,\n\t\t\t\t\t\t\t\t\t\t} as SQLiteUpdateSetSource<typeof table>)\n\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t\t.where(eq(table.id, op.key as any))\n\t\t\t\t\t\t\t\t\t\t.run();\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase \"delete\":\n\t\t\t\t\t\t\t\t\ttx.delete(table)\n\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t\t.where(eq(table.id, op.key as any))\n\t\t\t\t\t\t\t\t\t\t.run();\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase \"truncate\":\n\t\t\t\t\t\t\t\t\ttx.delete(table).run();\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\texhaustiveGuard(op);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait config.drizzle.transaction(\n\t\t\t\t\t\tasync (tx: typeof config.drizzle) => {\n\t\t\t\t\t\t\tfor (const op of ops) {\n\t\t\t\t\t\t\t\tswitch (op.type) {\n\t\t\t\t\t\t\t\t\tcase \"insert\": {\n\t\t\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] receiveSync batch insert`,\n\t\t\t\t\t\t\t\t\t\t\t\top.value,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tawait tx\n\t\t\t\t\t\t\t\t\t\t\t.insert(table)\n\t\t\t\t\t\t\t\t\t\t\t.values(\n\t\t\t\t\t\t\t\t\t\t\t\top.value as unknown as SQLiteInsertValue<typeof table>,\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\t\t\t\t\t\t\t\ttarget: table.id,\n\t\t\t\t\t\t\t\t\t\t\t\tset: sqliteExcludedUpsertSet(table),\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcase \"update\": {\n\t\t\t\t\t\t\t\t\t\tif (config.debug) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\t`[${new Date().toISOString()}] receiveSync batch update`,\n\t\t\t\t\t\t\t\t\t\t\t\top,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tconst updateTime = new Date();\n\t\t\t\t\t\t\t\t\t\tawait tx\n\t\t\t\t\t\t\t\t\t\t\t.update(table)\n\t\t\t\t\t\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\t\t\t\t\t\t...op.changes,\n\t\t\t\t\t\t\t\t\t\t\t\tupdatedAt: updateTime,\n\t\t\t\t\t\t\t\t\t\t\t} as SQLiteUpdateSetSource<typeof table>)\n\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t\t\t.where(eq(table.id, op.key as any));\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcase \"delete\":\n\t\t\t\t\t\t\t\t\t\tawait tx\n\t\t\t\t\t\t\t\t\t\t\t.delete(table)\n\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: branded id key\n\t\t\t\t\t\t\t\t\t\t\t.where(eq(table.id, op.key as any));\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase \"truncate\":\n\t\t\t\t\t\t\t\t\t\tawait tx.delete(table);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\texhaustiveGuard(op);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config.checkpoint) {\n\t\t\t\t\tawait config.checkpoint();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t};\n\n\treturn backend;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-J7DNZ25N.js"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { isNull, inArray, like, isNotNull, not, or, and, lte, lt, gte, gt, ne, eq, sql, asc, desc } from 'drizzle-orm';
|
|
2
|
+
import { SQLiteColumn } from 'drizzle-orm/sqlite-core';
|
|
3
|
+
import { exhaustiveGuard } from '@firtoz/maybe-error';
|
|
4
|
+
|
|
5
|
+
// src/sqlite-table-sync/convert-ir.ts
|
|
6
|
+
function convertBasicExpressionToDrizzle(expression, table) {
|
|
7
|
+
switch (expression.type) {
|
|
8
|
+
case "ref": {
|
|
9
|
+
const propRef = expression;
|
|
10
|
+
const columnName = propRef.path[propRef.path.length - 1];
|
|
11
|
+
const column = table[columnName];
|
|
12
|
+
if (!column || !(column instanceof SQLiteColumn)) {
|
|
13
|
+
console.error("[SQLite sync backend] Column lookup failed:", {
|
|
14
|
+
columnName,
|
|
15
|
+
column,
|
|
16
|
+
tableKeys: Object.keys(table),
|
|
17
|
+
hasColumn: columnName in table
|
|
18
|
+
});
|
|
19
|
+
throw new Error(`Column ${String(columnName)} not found in table`);
|
|
20
|
+
}
|
|
21
|
+
return column;
|
|
22
|
+
}
|
|
23
|
+
case "val": {
|
|
24
|
+
const value = expression;
|
|
25
|
+
return sql`${value.value}`;
|
|
26
|
+
}
|
|
27
|
+
case "func": {
|
|
28
|
+
const func = expression;
|
|
29
|
+
const args = func.args.map(
|
|
30
|
+
(arg) => convertBasicExpressionToDrizzle(arg, table)
|
|
31
|
+
);
|
|
32
|
+
switch (func.name) {
|
|
33
|
+
case "eq":
|
|
34
|
+
return eq(args[0], args[1]);
|
|
35
|
+
case "ne":
|
|
36
|
+
return ne(args[0], args[1]);
|
|
37
|
+
case "gt":
|
|
38
|
+
return gt(args[0], args[1]);
|
|
39
|
+
case "gte":
|
|
40
|
+
return gte(args[0], args[1]);
|
|
41
|
+
case "lt":
|
|
42
|
+
return lt(args[0], args[1]);
|
|
43
|
+
case "lte":
|
|
44
|
+
return lte(args[0], args[1]);
|
|
45
|
+
case "and": {
|
|
46
|
+
const result = and(...args);
|
|
47
|
+
if (!result) {
|
|
48
|
+
throw new Error("Invalid 'and' expression - no arguments provided");
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
case "or": {
|
|
53
|
+
const result = or(...args);
|
|
54
|
+
if (!result) {
|
|
55
|
+
throw new Error("Invalid 'or' expression - no arguments provided");
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
case "not":
|
|
60
|
+
return not(args[0]);
|
|
61
|
+
case "isNull":
|
|
62
|
+
return isNull(args[0]);
|
|
63
|
+
case "isNotNull":
|
|
64
|
+
return isNotNull(args[0]);
|
|
65
|
+
case "like":
|
|
66
|
+
return like(args[0], args[1]);
|
|
67
|
+
case "in":
|
|
68
|
+
return inArray(args[0], args[1]);
|
|
69
|
+
case "isUndefined":
|
|
70
|
+
return isNull(args[0]);
|
|
71
|
+
default:
|
|
72
|
+
throw new Error(`Unsupported function: ${func.name}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
exhaustiveGuard(expression);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function convertOrderByToDrizzle(orderBy, table) {
|
|
80
|
+
return orderBy.map((clause) => {
|
|
81
|
+
const expression = convertBasicExpressionToDrizzle(
|
|
82
|
+
clause.expression,
|
|
83
|
+
table
|
|
84
|
+
);
|
|
85
|
+
const direction = clause.compareOptions.direction || "asc";
|
|
86
|
+
return direction === "asc" ? asc(expression) : desc(expression);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { convertBasicExpressionToDrizzle, convertOrderByToDrizzle };
|
|
91
|
+
//# sourceMappingURL=chunk-JM254VLB.js.map
|
|
92
|
+
//# sourceMappingURL=chunk-JM254VLB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sqlite-table-sync/convert-ir.ts"],"names":[],"mappings":"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","file":"chunk-JM254VLB.js","sourcesContent":["import type { IR } from \"@tanstack/db\";\nimport {\n\teq,\n\tsql,\n\ttype Table,\n\tgt,\n\tgte,\n\tlt,\n\tlte,\n\tne,\n\tand,\n\tor,\n\tnot,\n\tisNull,\n\tisNotNull,\n\tlike,\n\tinArray,\n\tasc,\n\tdesc,\n\ttype SQL,\n} from \"drizzle-orm\";\nimport { SQLiteColumn } from \"drizzle-orm/sqlite-core\";\nimport { exhaustiveGuard } from \"@firtoz/maybe-error\";\n\n/**\n * Converts TanStack DB IR BasicExpression to Drizzle SQL expression.\n */\nexport function convertBasicExpressionToDrizzle<TTable extends Table>(\n\texpression: IR.BasicExpression,\n\ttable: TTable,\n): SQL {\n\tswitch (expression.type) {\n\t\tcase \"ref\": {\n\t\t\tconst propRef = expression;\n\t\t\tconst columnName = propRef.path[propRef.path.length - 1];\n\t\t\tconst column = table[columnName as keyof typeof table];\n\n\t\t\tif (!column || !(column instanceof SQLiteColumn)) {\n\t\t\t\tconsole.error(\"[SQLite sync backend] Column lookup failed:\", {\n\t\t\t\t\tcolumnName,\n\t\t\t\t\tcolumn,\n\t\t\t\t\ttableKeys: Object.keys(table),\n\t\t\t\t\thasColumn: columnName in table,\n\t\t\t\t});\n\t\t\t\tthrow new Error(`Column ${String(columnName)} not found in table`);\n\t\t\t}\n\n\t\t\treturn column as unknown as SQL;\n\t\t}\n\t\tcase \"val\": {\n\t\t\tconst value = expression;\n\t\t\treturn sql`${value.value}`;\n\t\t}\n\t\tcase \"func\": {\n\t\t\tconst func = expression;\n\t\t\tconst args = func.args.map((arg) =>\n\t\t\t\tconvertBasicExpressionToDrizzle(arg, table),\n\t\t\t);\n\n\t\t\tswitch (func.name) {\n\t\t\t\tcase \"eq\":\n\t\t\t\t\treturn eq(args[0], args[1]);\n\t\t\t\tcase \"ne\":\n\t\t\t\t\treturn ne(args[0], args[1]);\n\t\t\t\tcase \"gt\":\n\t\t\t\t\treturn gt(args[0], args[1]);\n\t\t\t\tcase \"gte\":\n\t\t\t\t\treturn gte(args[0], args[1]);\n\t\t\t\tcase \"lt\":\n\t\t\t\t\treturn lt(args[0], args[1]);\n\t\t\t\tcase \"lte\":\n\t\t\t\t\treturn lte(args[0], args[1]);\n\t\t\t\tcase \"and\": {\n\t\t\t\t\tconst result = and(...args);\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\tthrow new Error(\"Invalid 'and' expression - no arguments provided\");\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tcase \"or\": {\n\t\t\t\t\tconst result = or(...args);\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\tthrow new Error(\"Invalid 'or' expression - no arguments provided\");\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tcase \"not\":\n\t\t\t\t\treturn not(args[0]);\n\t\t\t\tcase \"isNull\":\n\t\t\t\t\treturn isNull(args[0]);\n\t\t\t\tcase \"isNotNull\":\n\t\t\t\t\treturn isNotNull(args[0]);\n\t\t\t\tcase \"like\":\n\t\t\t\t\treturn like(args[0], args[1]);\n\t\t\t\tcase \"in\":\n\t\t\t\t\treturn inArray(args[0], args[1]);\n\t\t\t\tcase \"isUndefined\":\n\t\t\t\t\treturn isNull(args[0]);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unsupported function: ${func.name}`);\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\texhaustiveGuard(expression);\n\t}\n}\n\nexport function convertOrderByToDrizzle<TTable extends Table>(\n\torderBy: IR.OrderBy,\n\ttable: TTable,\n): SQL[] {\n\treturn orderBy.map((clause) => {\n\t\tconst expression = convertBasicExpressionToDrizzle(\n\t\t\tclause.expression,\n\t\t\ttable,\n\t\t);\n\t\tconst direction = clause.compareOptions.direction || \"asc\";\n\n\t\treturn direction === \"asc\" ? asc(expression) : desc(expression);\n\t});\n}\n"]}
|