@firtoz/drizzle-utils 0.3.2 → 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 CHANGED
@@ -1,5 +1,26 @@
1
1
  # @firtoz/drizzle-utils
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)! - **Unified collection sync**
8
+
9
+ `CollectionUtils` now exposes `receiveSync(messages: SyncMessage<T>[])` instead of `pushExternalSync`. Canonical sync message type is `SyncMessage<T, TKey>` (`insert` | `update` | `delete` | `truncate`). `ExternalSyncEvent` / `ExternalSyncHandler` are internal only.
10
+
11
+ **Upgrade:** Replace `utils.pushExternalSync(events)` with `utils.receiveSync(messages)`. Import `SyncMessage` from `@firtoz/drizzle-utils` (or from `@firtoz/db-helpers`) and send per-mutation messages: `{ type: "insert", value }`, `{ type: "update", value, previousValue }`, `{ type: "delete", key }`, or `{ type: "truncate" }`. Stop using `ExternalSyncEvent` / `ExternalSyncHandler` in your code; they are no longer part of the public API. Generic sync types (`SyncMessage`, `CollectionUtils`) are now defined in `@firtoz/db-helpers` and re-exported here for backward compatibility.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [[`3c7ce1d`](https://github.com/firtoz/fullstack-toolkit/commit/3c7ce1dbca5c5396386db9927ae7f5e19a562cf6)]:
16
+ - @firtoz/db-helpers@1.0.0
17
+
18
+ ## 0.3.3
19
+
20
+ ### Patch Changes
21
+
22
+ - [`ec365af`](https://github.com/firtoz/fullstack-toolkit/commit/ec365af8c17bcd7efc2b0cf9b3bed5225b853e72) Thanks [@firtoz](https://github.com/firtoz)! - Update dependencies
23
+
3
24
  ## 0.3.2
4
25
 
5
26
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firtoz/drizzle-utils",
3
- "version": "0.3.2",
3
+ "version": "1.0.0",
4
4
  "description": "Shared utilities and types for Drizzle-based packages",
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -53,15 +53,19 @@
53
53
  "access": "public"
54
54
  },
55
55
  "peerDependencies": {
56
- "@tanstack/db": ">=0.5.23",
56
+ "@tanstack/db": ">=0.5.26",
57
57
  "drizzle-orm": ">=0.45.1",
58
58
  "drizzle-valibot": ">=0.4.0",
59
59
  "valibot": ">=1.0.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@tanstack/db": "^0.5.23",
62
+ "@tanstack/db": "^0.5.26",
63
63
  "drizzle-orm": "^0.45.1",
64
64
  "drizzle-valibot": "^0.4.2",
65
65
  "valibot": "^1.2.0"
66
+ },
67
+ "dependencies": {
68
+ "@firtoz/db-helpers": "^1.0.0",
69
+ "@firtoz/maybe-error": "^1.5.2"
66
70
  }
67
71
  }
@@ -1,3 +1,5 @@
1
+ import type { CollectionUtils, SyncMessage } from "@firtoz/db-helpers";
2
+ import { exhaustiveGuard } from "@firtoz/maybe-error";
1
3
  import { type Table, SQL, getTableColumns } from "drizzle-orm";
2
4
  import type { BuildSchema } from "drizzle-valibot";
3
5
  import { createInsertSchema } from "drizzle-valibot";
@@ -162,36 +164,6 @@ export interface SyncBackend<TTable extends Table> {
162
164
  handleTruncate?: () => Promise<void>;
163
165
  }
164
166
 
165
- /**
166
- * External sync event for pushing changes from outside (e.g., from a proxy server)
167
- */
168
- export type ExternalSyncEvent<T> =
169
- | { type: "insert"; items: T[] }
170
- | { type: "update"; items: T[] }
171
- | { type: "delete"; items: T[] }
172
- | { type: "truncate" };
173
-
174
- /**
175
- * Handler for external sync events
176
- */
177
- export type ExternalSyncHandler<T> = (event: ExternalSyncEvent<T>) => void;
178
-
179
- /**
180
- * Collection utils that include truncate and external sync functionality
181
- */
182
- export interface CollectionUtils<T = unknown> {
183
- /**
184
- * Clear all data from the store (truncate).
185
- * This clears the backend store and updates the local reactive store.
186
- */
187
- truncate: () => Promise<void>;
188
- /**
189
- * Push external sync events to the collection.
190
- * Use this when receiving sync messages from a proxy server or other external source.
191
- */
192
- pushExternalSync: ExternalSyncHandler<T>;
193
- }
194
-
195
167
  /**
196
168
  * Return type for createSyncFunction that includes both sync config and listeners
197
169
  */
@@ -364,49 +336,44 @@ export function createSyncFunction<TTable extends Table>(
364
336
  } satisfies SyncConfigRes;
365
337
  };
366
338
 
367
- // External sync handler - allows pushing sync events from outside (e.g., proxy server)
368
- const pushExternalSync: ExternalSyncHandler<ItemType> = (event) => {
339
+ // Apply SyncMessage[] to the sync layer (canonical receive API)
340
+ const receiveSync = async (messages: SyncMessage<ItemType>[]) => {
341
+ if (messages.length === 0) return;
369
342
  if (!syncBegin || !syncWrite || !syncCommit || !syncTruncate) {
370
343
  if (config.debug) {
371
344
  console.warn(
372
- "[pushExternalSync] Sync functions not initialized yet - event will be dropped",
373
- event,
345
+ "[receiveSync] Sync functions not initialized yet - messages will be dropped",
346
+ messages.length,
374
347
  );
375
348
  }
376
349
  return;
377
350
  }
378
-
379
- switch (event.type) {
380
- case "insert":
381
- syncBegin();
382
- for (const item of event.items) {
383
- syncWrite({ type: "insert", value: item });
384
- }
385
- syncCommit();
386
- break;
387
- case "update":
388
- syncBegin();
389
- for (const item of event.items) {
390
- syncWrite({ type: "update", value: item });
391
- }
392
- syncCommit();
393
- break;
394
- case "delete":
395
- syncBegin();
396
- for (const item of event.items) {
397
- syncWrite({ type: "delete", value: item });
398
- }
399
- syncCommit();
400
- break;
401
- case "truncate":
402
- syncBegin();
403
- syncTruncate();
404
- syncCommit();
405
- break;
351
+ syncBegin();
352
+ for (const msg of messages) {
353
+ switch (msg.type) {
354
+ case "insert":
355
+ syncWrite({ type: "insert", value: msg.value });
356
+ break;
357
+ case "update":
358
+ syncWrite({ type: "update", value: msg.value });
359
+ break;
360
+ case "delete":
361
+ syncWrite({
362
+ type: "delete",
363
+ value: { id: msg.key } as ItemType,
364
+ });
365
+ break;
366
+ case "truncate":
367
+ syncTruncate();
368
+ break;
369
+ default:
370
+ exhaustiveGuard(msg);
371
+ }
406
372
  }
373
+ syncCommit();
407
374
  };
408
375
 
409
- // Create utils with truncate and external sync
376
+ // Create utils with truncate and receiveSync
410
377
  const utils: CollectionUtils<ItemType> = {
411
378
  truncate: async () => {
412
379
  if (!backend.handleTruncate) {
@@ -424,7 +391,7 @@ export function createSyncFunction<TTable extends Table>(
424
391
  syncTruncate();
425
392
  syncCommit();
426
393
  },
427
- pushExternalSync,
394
+ receiveSync,
428
395
  };
429
396
 
430
397
  return {
@@ -614,7 +581,7 @@ export function createCollectionConfig<
614
581
  onUpdate: config.onUpdate ?? config.syncResult.onUpdate,
615
582
  onDelete: config.onDelete ?? config.syncResult.onDelete,
616
583
  syncMode: config.syncMode,
617
- // Include utils with truncate and pushExternalSync
584
+ // Include utils with truncate and receiveSync
618
585
  utils: config.syncResult.utils,
619
586
  };
620
587
  }
package/src/index.ts CHANGED
@@ -27,9 +27,6 @@ export type {
27
27
  BaseSyncConfig,
28
28
  SyncBackend,
29
29
  SyncFunctionResult,
30
- ExternalSyncEvent,
31
- ExternalSyncHandler,
32
- CollectionUtils,
33
30
  } from "./collection-utils";
34
31
 
35
32
  export {