@firtoz/db-helpers 2.1.0 → 2.2.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.
@@ -0,0 +1,7 @@
1
+ export { CollectionUtils, ExternalSyncEvent, ExternalSyncHandler, ReceiveSyncDurableOp, SyncMessage } from './sync-types.js';
2
+ export { MemoryCollection, createMemoryCollection, memoryCollectionOptions } from './memoryCollection.js';
3
+ export { evaluateExpression, getExpressionValue } from './ir-evaluator.js';
4
+ export { GenericBaseSyncConfig, GenericSyncBackend, GenericSyncFunctionResult, USE_DEDUPE, createGenericCollectionConfig, createGenericSyncFunction } from './generic-sync.js';
5
+ export { DeferredDeleteMutation, DeferredUpdateMutation, DeferredWriteQueue } from './deferred-write-queue.js';
6
+ import '@standard-schema/spec';
7
+ import '@tanstack/db';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { USE_DEDUPE, createGenericCollectionConfig, createGenericSyncFunction } from './chunk-72YXZ3BK.js';
2
+ export { DeferredWriteQueue } from './chunk-E6ZONR5D.js';
3
+ export { evaluateExpression, getExpressionValue } from './chunk-Y64WBRON.js';
4
+ export { createMemoryCollection, memoryCollectionOptions } from './chunk-EIDXVFD3.js';
5
+ import './chunk-HMLY7DHA.js';
6
+ //# sourceMappingURL=index.js.map
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,14 @@
1
+ import { IR } from '@tanstack/db';
2
+
3
+ /**
4
+ * Evaluates a TanStack DB IR expression against a plain object item.
5
+ * @internal Exported for testing and reuse by collection backends
6
+ */
7
+ declare function evaluateExpression(expression: IR.BasicExpression, item: Record<string, unknown>): boolean;
8
+ /**
9
+ * Gets the value from an IR expression by resolving refs and vals.
10
+ * @internal Exported for testing and reuse by collection backends
11
+ */
12
+ declare function getExpressionValue(expression: IR.BasicExpression, item: Record<string, unknown>): any;
13
+
14
+ export { evaluateExpression, getExpressionValue };
@@ -0,0 +1,4 @@
1
+ export { evaluateExpression, getExpressionValue } from './chunk-Y64WBRON.js';
2
+ import './chunk-HMLY7DHA.js';
3
+ //# sourceMappingURL=ir-evaluator.js.map
4
+ //# sourceMappingURL=ir-evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"ir-evaluator.js"}
@@ -0,0 +1,26 @@
1
+ import { SyncMessage } from './sync-types.js';
2
+ import { StandardSchemaV1 } from '@standard-schema/spec';
3
+ import { CollectionConfig, InferSchemaOutput, Collection, InferSchemaInput } from '@tanstack/db';
4
+
5
+ type MemoryCollectionConfig<TSchema extends StandardSchemaV1> = Omit<CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema>, "onInsert" | "onUpdate" | "onDelete" | "sync" | "schema"> & {
6
+ schema: TSchema;
7
+ /** Called when a local mutation is written to the sync layer; use to broadcast to other peers. */
8
+ onBroadcast?: (changes: SyncMessage<InferSchemaOutput<TSchema>, string | number>[]) => void;
9
+ };
10
+ type MemoryUtils<TItem = unknown, TKey extends string | number = string | number> = {
11
+ truncate: () => Promise<void>;
12
+ /**
13
+ * Apply incoming sync messages without triggering onInsert/onUpdate/onDelete.
14
+ * Uses the sync layer (begin/write/commit) so state updates and subscribeChanges fire,
15
+ * but no rebroadcast occurs.
16
+ */
17
+ receiveSync: (messages: SyncMessage<TItem, TKey>[]) => Promise<void>;
18
+ };
19
+ declare function memoryCollectionOptions<TSchema extends StandardSchemaV1>(config: MemoryCollectionConfig<TSchema>): CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema> & {
20
+ utils: MemoryUtils<InferSchemaOutput<TSchema>, string | number>;
21
+ schema: TSchema;
22
+ };
23
+ type MemoryCollection<TSchema extends StandardSchemaV1> = Collection<InferSchemaOutput<TSchema>, string | number, MemoryUtils<InferSchemaOutput<TSchema>, string | number>, TSchema, InferSchemaInput<TSchema>>;
24
+ declare function createMemoryCollection<TSchema extends StandardSchemaV1>(config: MemoryCollectionConfig<TSchema>): MemoryCollection<TSchema>;
25
+
26
+ export { type MemoryCollection, createMemoryCollection, memoryCollectionOptions };
@@ -0,0 +1,4 @@
1
+ export { createMemoryCollection, memoryCollectionOptions } from './chunk-EIDXVFD3.js';
2
+ import './chunk-HMLY7DHA.js';
3
+ //# sourceMappingURL=memoryCollection.js.map
4
+ //# sourceMappingURL=memoryCollection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"memoryCollection.js"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Generic collection sync types. Used by memory, IndexedDB, SQLite, and other
3
+ * collection backends for a unified sync protocol.
4
+ */
5
+ /**
6
+ * Canonical per-mutation sync message. Use for broadcast and receive across all collection types.
7
+ */
8
+ type SyncMessage<T = unknown, TKey extends string | number = string | number> = {
9
+ type: "insert";
10
+ value: T;
11
+ } | {
12
+ type: "update";
13
+ value: T;
14
+ previousValue: T;
15
+ } | {
16
+ type: "delete";
17
+ key: TKey;
18
+ } | {
19
+ type: "truncate";
20
+ };
21
+ /**
22
+ * Normalized durable ops for a {@link SyncMessage} batch. SQLite-style backends can implement
23
+ * `GenericSyncBackend.applyReceiveSyncDurableWrites` to persist the whole batch in one store
24
+ * transaction instead of one transaction per message.
25
+ */
26
+ type ReceiveSyncDurableOp<TItem extends object> = {
27
+ type: "insert";
28
+ value: TItem;
29
+ } | {
30
+ type: "update";
31
+ key: string;
32
+ changes: Partial<TItem>;
33
+ original: TItem;
34
+ } | {
35
+ type: "delete";
36
+ key: string;
37
+ } | {
38
+ type: "truncate";
39
+ };
40
+ /**
41
+ * External sync event (batched). Used internally by the sync layer.
42
+ */
43
+ type ExternalSyncEvent<T> = {
44
+ type: "insert";
45
+ items: T[];
46
+ } | {
47
+ type: "update";
48
+ items: T[];
49
+ } | {
50
+ type: "delete";
51
+ items: T[];
52
+ } | {
53
+ type: "truncate";
54
+ };
55
+ /**
56
+ * Handler for external sync events (internal use).
57
+ */
58
+ type ExternalSyncHandler<T> = (event: ExternalSyncEvent<T>) => void;
59
+ /**
60
+ * Collection utils: truncate and receiveSync (canonical sync protocol).
61
+ */
62
+ interface CollectionUtils<T = unknown> {
63
+ /**
64
+ * Clear all data from the store (truncate).
65
+ * This clears the backend store and updates the local reactive store.
66
+ */
67
+ truncate: () => Promise<void>;
68
+ /**
69
+ * Apply incoming sync messages without triggering mutation handlers.
70
+ * Use the same SyncMessage[] shape for memory and backend collections.
71
+ */
72
+ receiveSync: (messages: SyncMessage<T>[]) => Promise<void>;
73
+ }
74
+
75
+ export type { CollectionUtils, ExternalSyncEvent, ExternalSyncHandler, ReceiveSyncDurableOp, SyncMessage };
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=sync-types.js.map
3
+ //# sourceMappingURL=sync-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"sync-types.js"}
package/package.json CHANGED
@@ -1,23 +1,28 @@
1
1
  {
2
2
  "name": "@firtoz/db-helpers",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "TanStack DB helpers and utilities",
5
- "main": "./src/index.ts",
6
- "module": "./src/index.ts",
7
- "types": "./src/index.ts",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "types": "./src/index.ts",
11
- "import": "./src/index.ts",
12
- "require": "./src/index.ts"
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
13
  }
14
14
  },
15
15
  "files": [
16
+ "dist/**/*.js",
17
+ "dist/**/*.js.map",
18
+ "dist/**/*.d.ts",
16
19
  "src/**/*.ts",
17
20
  "!src/**/*.test.ts",
18
21
  "README.md"
19
22
  ],
20
23
  "scripts": {
24
+ "build": "tsup",
25
+ "prepack": "bun run build",
21
26
  "typecheck": "tsgo --noEmit -p ./tsconfig.json",
22
27
  "test": "bun test",
23
28
  "lint": "biome check --write src",
@@ -49,15 +54,15 @@
49
54
  },
50
55
  "peerDependencies": {
51
56
  "@standard-schema/spec": ">=1.1.0",
52
- "@tanstack/db": ">=0.6.1"
57
+ "@tanstack/db": ">=0.6.3"
53
58
  },
54
59
  "devDependencies": {
55
60
  "@standard-schema/spec": "^1.1.0",
56
- "@tanstack/db": "^0.6.1",
61
+ "@tanstack/db": "^0.6.4",
57
62
  "bun-types": "^1.3.11",
58
63
  "zod": "^4.3.6"
59
64
  },
60
65
  "dependencies": {
61
- "@firtoz/maybe-error": "^1.5.2"
66
+ "@firtoz/maybe-error": "^1.6.0"
62
67
  }
63
68
  }
@@ -14,13 +14,12 @@ import type {
14
14
  SyncMode,
15
15
  LoadSubsetOptions,
16
16
  } from "@tanstack/db";
17
- import { DeduplicatedLoadSubset } from "@tanstack/db";
17
+ import { BasicIndex, DeduplicatedLoadSubset } from "@tanstack/db";
18
18
 
19
- // WORKAROUND: DeduplicatedLoadSubset has a bug where toggling queries (e.g., isNull/isNotNull)
20
- // creates invalid expressions like not(or(isNull(...), not(isNull(...))))
21
- // See: https://github.com/TanStack/db/issues/828
22
- // TODO: Re-enable once the bug is fixed
23
- export const USE_DEDUPE = false as boolean;
19
+ // DeduplicatedLoadSubset dedupes overlapping loadSubset calls. Previously disabled for TanStack/db#828
20
+ // (invalid OR expressions when toggling isNull/isNotNull). Re-enabled with @tanstack/db 0.6.4; if
21
+ // regressions appear, set back to false and add a regression test.
22
+ export const USE_DEDUPE = true as boolean;
24
23
 
25
24
  /**
26
25
  * Base configuration for sync lifecycle management (generic, no Drizzle dependency).
@@ -646,6 +645,10 @@ export function createGenericCollectionConfig<
646
645
  onUpdate: config.onUpdate ?? config.syncResult.onUpdate,
647
646
  onDelete: config.onDelete ?? config.syncResult.onDelete,
648
647
  syncMode: config.syncMode,
648
+ // TanStack DB 0.6+: indexing is opt-in; eager BasicIndex restores pre-0.6 behavior for
649
+ // orderBy/limit live queries (playground pagination, usePredicateFilteredRows, etc.).
650
+ defaultIndexType: BasicIndex,
651
+ autoIndex: "eager",
649
652
  utils: config.syncResult.utils as CollectionUtils<
650
653
  InferSchemaOutput<TSchema>
651
654
  >,