@firtoz/drizzle-indexeddb 3.0.0 → 4.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-indexeddb
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#64](https://github.com/firtoz/fullstack-toolkit/pull/64) [`556555a`](https://github.com/firtoz/fullstack-toolkit/commit/556555a2e09030a8658be8c07b5881e72be64b2f) Thanks [@firtoz](https://github.com/firtoz)! - **`@firtoz/drizzle-utils`:** Export `DrizzleSqliteTableCollection`; extend `BaseSyncConfig` / `createCollectionConfig` for typed `getSyncPersistKey` and `getKey` as `IdOf<TTable>`; avoid executing `syncableTable` default functions during table definition for Worker/DO globals; export collection helper types for Drizzle-backed TanStack collections.
8
+
9
+ **`@firtoz/drizzle-indexeddb` (major):** `deferLocalPersistence`, `handleBatchPut`, and related collection options; `receiveSync` persistence aligned with generic sync and partial-sync traffic; remove debug ingest usage. **Breaking** alongside the `@firtoz/drizzle-utils` sync/collection typing changes above (including `DrizzleSqliteTableCollection` and `BaseSyncConfig` expectations).
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [[`556555a`](https://github.com/firtoz/fullstack-toolkit/commit/556555a2e09030a8658be8c07b5881e72be64b2f), [`556555a`](https://github.com/firtoz/fullstack-toolkit/commit/556555a2e09030a8658be8c07b5881e72be64b2f), [`556555a`](https://github.com/firtoz/fullstack-toolkit/commit/556555a2e09030a8658be8c07b5881e72be64b2f), [`f90479f`](https://github.com/firtoz/fullstack-toolkit/commit/f90479f263e932b39269aecce4f54dbbb7cdce3e)]:
14
+ - @firtoz/db-helpers@2.1.0
15
+ - @firtoz/drizzle-utils@1.2.0
16
+ - @firtoz/idb-collections@0.2.2
17
+
18
+ ## 3.0.1
19
+
20
+ ### Patch Changes
21
+
22
+ - [`8b839f2`](https://github.com/firtoz/fullstack-toolkit/commit/8b839f2227f50409af649aab87178e039aad55dc) Thanks [@firtoz](https://github.com/firtoz)! - Export collection helper types for Drizzle-backed TanStack DB collections so users can declare collection variables with preserved select and insert inference from table schemas.
23
+
3
24
  ## 3.0.0
4
25
 
5
26
  ### Patch Changes
package/README.md CHANGED
@@ -100,16 +100,23 @@ Create reactive collections backed by IndexedDB:
100
100
 
101
101
  ```typescript
102
102
  import { createCollection } from "@tanstack/db";
103
- import { indexedDBCollectionOptions } from "@firtoz/drizzle-indexeddb";
103
+ import {
104
+ drizzleIndexedDBCollectionOptions,
105
+ type DrizzleIndexedDBCollection,
106
+ } from "@firtoz/drizzle-indexeddb";
107
+ import * as schema from "./schema";
104
108
 
105
109
  const todosCollection = createCollection(
106
- indexedDBCollectionOptions({
107
- db,
108
- tableName: "todos",
110
+ drizzleIndexedDBCollectionOptions({
111
+ indexedDBRef: { current: db },
112
+ table: schema.todoTable,
113
+ storeName: "todos",
109
114
  syncMode: "on-demand", // or "realtime"
110
115
  })
111
116
  );
112
117
 
118
+ type TodosCollection = DrizzleIndexedDBCollection<typeof schema.todoTable>;
119
+
113
120
  // Subscribe to changes
114
121
  const unsubscribe = todosCollection.subscribe((todos) => {
115
122
  console.log("Todos updated:", todos);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firtoz/drizzle-indexeddb",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "IndexedDB migrations powered by Drizzle ORM",
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -39,7 +39,7 @@
39
39
  "CHANGELOG.md"
40
40
  ],
41
41
  "scripts": {
42
- "typecheck": "tsc --noEmit -p ./tsconfig.json",
42
+ "typecheck": "tsgo --noEmit -p ./tsconfig.json",
43
43
  "lint": "biome check --write src",
44
44
  "lint:ci": "biome ci src",
45
45
  "format": "biome format src --write"
@@ -68,25 +68,25 @@
68
68
  "access": "public"
69
69
  },
70
70
  "peerDependencies": {
71
- "@firtoz/drizzle-utils": ">=1.1.0",
72
- "@tanstack/db": ">=0.5.33",
73
- "drizzle-orm": ">=0.45.1",
71
+ "@firtoz/drizzle-utils": ">=1.2.0",
72
+ "@tanstack/db": ">=0.6.1",
73
+ "drizzle-orm": ">=0.45.2",
74
74
  "drizzle-valibot": ">=0.4.0",
75
75
  "react": ">=19.2.4",
76
76
  "valibot": ">=1.3.1"
77
77
  },
78
78
  "devDependencies": {
79
- "@firtoz/drizzle-utils": "^1.1.0",
80
- "@tanstack/db": "^0.5.33",
79
+ "@firtoz/drizzle-utils": "^1.2.0",
80
+ "@tanstack/db": "^0.6.1",
81
81
  "@types/react": "^19.2.14",
82
- "drizzle-orm": "^0.45.1",
82
+ "drizzle-orm": "^0.45.2",
83
83
  "drizzle-valibot": "^0.4.2",
84
84
  "react": "^19.2.4",
85
85
  "valibot": "^1.3.1"
86
86
  },
87
87
  "dependencies": {
88
- "@firtoz/db-helpers": "^2.0.0",
89
- "@firtoz/idb-collections": "^0.2.1",
88
+ "@firtoz/db-helpers": "^2.1.0",
89
+ "@firtoz/idb-collections": "^0.2.2",
90
90
  "@firtoz/maybe-error": "^1.5.2",
91
91
  "citty": "^0.2.1"
92
92
  }
@@ -1,4 +1,10 @@
1
- import type { InferSchemaOutput, SyncMode } from "@tanstack/db";
1
+ import type {
2
+ Collection,
3
+ CollectionConfig,
4
+ InferSchemaInput,
5
+ InferSchemaOutput,
6
+ SyncMode,
7
+ } from "@tanstack/db";
2
8
  import type { IR } from "@tanstack/db";
3
9
  import { parseOrderByExpression } from "@tanstack/db";
4
10
  import type { Table } from "drizzle-orm";
@@ -6,6 +12,8 @@ import type { Table } from "drizzle-orm";
6
12
  import {
7
13
  type IdOf,
8
14
  type SelectSchema,
15
+ type InsertToSelectSchema,
16
+ type TableWithRequiredFields,
9
17
  type BaseSyncConfig,
10
18
  type SyncBackend,
11
19
  createSyncFunction,
@@ -13,7 +21,7 @@ import {
13
21
  createGetKeyFunction,
14
22
  createCollectionConfig,
15
23
  } from "@firtoz/drizzle-utils";
16
- import { evaluateExpression } from "@firtoz/db-helpers";
24
+ import { evaluateExpression, type CollectionUtils } from "@firtoz/db-helpers";
17
25
  import { tryExtractIndexedQuery } from "@firtoz/idb-collections";
18
26
 
19
27
  import type { IDBDatabaseLike } from "../idb-types";
@@ -57,8 +65,35 @@ export interface DrizzleIndexedDBCollectionConfig<TTable extends Table> {
57
65
  * Enable debug logging for index discovery and query optimization
58
66
  */
59
67
  debug?: boolean;
68
+ /**
69
+ * When set, local mutations confirm TanStack sync immediately and persist to IndexedDB on a
70
+ * coalesced timer (`createGenericSyncFunction` in `@firtoz/db-helpers`).
71
+ */
72
+ deferLocalPersistence?: boolean | { flushIntervalMs?: number };
60
73
  }
61
74
 
75
+ export type DrizzleIndexedDBCollectionConfigResult<TTable extends Table> = Omit<
76
+ CollectionConfig<
77
+ InferSchemaOutput<SelectSchema<TTable>>,
78
+ IdOf<TTable>,
79
+ InsertToSelectSchema<TTable>,
80
+ CollectionUtils<InferSchemaOutput<SelectSchema<TTable>>>
81
+ >,
82
+ "utils"
83
+ > & {
84
+ schema: InsertToSelectSchema<TTable>;
85
+ utils: CollectionUtils<InferSchemaOutput<SelectSchema<TTable>>>;
86
+ };
87
+
88
+ export type DrizzleIndexedDBCollection<TTable extends TableWithRequiredFields> =
89
+ Collection<
90
+ InferSchemaOutput<SelectSchema<TTable>>,
91
+ IdOf<TTable>,
92
+ CollectionUtils<InferSchemaOutput<SelectSchema<TTable>>>,
93
+ InsertToSelectSchema<TTable>,
94
+ InferSchemaInput<InsertToSelectSchema<TTable>>
95
+ >;
96
+
62
97
  /**
63
98
  * Auto-discovers indexes from the IndexedDB store.
64
99
  * Returns a map of field names to index names for single-column indexes.
@@ -84,7 +119,7 @@ function discoverIndexes(
84
119
  */
85
120
  export function drizzleIndexedDBCollectionOptions<const TTable extends Table>(
86
121
  config: DrizzleIndexedDBCollectionConfig<TTable>,
87
- ) {
122
+ ): DrizzleIndexedDBCollectionConfigResult<TTable> {
88
123
  let discoveredIndexes: Record<string, string> = {};
89
124
  let indexesDiscovered = false;
90
125
 
@@ -254,6 +289,21 @@ export function drizzleIndexedDBCollectionOptions<const TTable extends Table>(
254
289
  return results;
255
290
  },
256
291
 
292
+ handleBatchPut: async (itemsToPut) => {
293
+ const db = config.indexedDBRef.current;
294
+ if (!db) {
295
+ throw new Error("Database not ready");
296
+ }
297
+ const now = new Date();
298
+ const rows = (itemsToPut as unknown as DrizzleIndexedDBSyncItem[]).map(
299
+ (row) => ({
300
+ ...row,
301
+ updatedAt: now,
302
+ }),
303
+ );
304
+ await db.put(config.storeName, rows);
305
+ },
306
+
257
307
  handleDelete: async (mutations) => {
258
308
  const db = config.indexedDBRef.current;
259
309
 
@@ -290,11 +340,18 @@ export function drizzleIndexedDBCollectionOptions<const TTable extends Table>(
290
340
  },
291
341
  };
292
342
 
343
+ type TItem = InferSchemaOutput<SelectSchema<TTable>>;
344
+ const getKey = createGetKeyFunction<TTable>();
345
+
293
346
  const baseSyncConfig: BaseSyncConfig<TTable> = {
294
347
  table,
295
348
  readyPromise: config.readyPromise,
296
349
  syncMode: config.syncMode,
297
350
  debug: config.debug,
351
+ getSyncPersistKey: (item: TItem) => String(getKey(item)),
352
+ ...(config.deferLocalPersistence !== undefined
353
+ ? { deferLocalPersistence: config.deferLocalPersistence }
354
+ : {}),
298
355
  };
299
356
 
300
357
  const syncResult = createSyncFunction(baseSyncConfig, wrappedBackend);
@@ -303,7 +360,7 @@ export function drizzleIndexedDBCollectionOptions<const TTable extends Table>(
303
360
 
304
361
  return createCollectionConfig({
305
362
  schema,
306
- getKey: createGetKeyFunction<TTable>(),
363
+ getKey,
307
364
  syncResult,
308
365
  syncMode: config.syncMode,
309
366
  });
package/src/index.ts CHANGED
@@ -35,6 +35,8 @@ export { createInstrumentedDbCreator } from "./instrumented-idb-database";
35
35
  export {
36
36
  drizzleIndexedDBCollectionOptions,
37
37
  type DrizzleIndexedDBCollectionConfig,
38
+ type DrizzleIndexedDBCollectionConfigResult,
39
+ type DrizzleIndexedDBCollection,
38
40
  type DrizzleIndexedDBSyncItem,
39
41
  } from "./collections/drizzle-indexeddb-collection";
40
42