@anfenn/dync 1.0.3 → 1.0.5

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.
Files changed (47) hide show
  1. package/README.md +32 -14
  2. package/dist/{chunk-66PSQW4D.js → chunk-YAAFAS64.js} +42 -42
  3. package/dist/chunk-YAAFAS64.js.map +1 -0
  4. package/dist/{dexie-Bv-fV10P.d.cts → dexie-1_xyU5MV.d.cts} +41 -38
  5. package/dist/{dexie-DJFApKsM.d.ts → dexie-ChZ0o0Sz.d.ts} +41 -38
  6. package/dist/dexie.cjs +40 -40
  7. package/dist/dexie.cjs.map +1 -1
  8. package/dist/dexie.d.cts +1 -1
  9. package/dist/dexie.d.ts +1 -1
  10. package/dist/dexie.js +40 -40
  11. package/dist/dexie.js.map +1 -1
  12. package/dist/index.cjs +41 -41
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +2 -2
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.js +1 -1
  17. package/dist/{index.shared-CkYsQYyn.d.ts → index.shared-3gbnIINY.d.ts} +4 -4
  18. package/dist/{index.shared-BGwvMH8f.d.cts → index.shared-XsB8HrvX.d.cts} +4 -4
  19. package/dist/react/index.cjs +26 -26
  20. package/dist/react/index.cjs.map +1 -1
  21. package/dist/react/index.d.cts +2 -2
  22. package/dist/react/index.d.ts +2 -2
  23. package/dist/react/index.js +1 -1
  24. package/dist/wa-sqlite.cjs +2 -2
  25. package/dist/wa-sqlite.cjs.map +1 -1
  26. package/dist/wa-sqlite.d.cts +2 -2
  27. package/dist/wa-sqlite.d.ts +2 -2
  28. package/dist/wa-sqlite.js +2 -2
  29. package/dist/wa-sqlite.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/core/StateManager.ts +4 -4
  32. package/src/core/pullOperations.ts +3 -3
  33. package/src/core/pushOperations.ts +13 -13
  34. package/src/core/tableEnhancers.ts +20 -20
  35. package/src/helpers.ts +1 -1
  36. package/src/storage/dexie/DexieAdapter.ts +2 -2
  37. package/src/storage/dexie/{DexieStorageCollection.ts → DexieCollection.ts} +12 -12
  38. package/src/storage/dexie/DexieTable.ts +123 -0
  39. package/src/storage/dexie/{DexieStorageWhereClause.ts → DexieWhereClause.ts} +21 -21
  40. package/src/storage/dexie/index.ts +3 -3
  41. package/src/storage/memory/MemoryTable.ts +40 -40
  42. package/src/storage/sqlite/SQLiteTable.ts +34 -36
  43. package/src/storage/sqlite/drivers/WaSqliteDriver.ts +6 -6
  44. package/src/storage/types.ts +22 -19
  45. package/src/types.ts +4 -4
  46. package/dist/chunk-66PSQW4D.js.map +0 -1
  47. package/src/storage/dexie/DexieStorageTable.ts +0 -123
@@ -1,4 +1,4 @@
1
- import type { StorageTable, StorageWhereClause, StorageCollection } from '../types';
1
+ import type { AddItem, StorageTable, StorageWhereClause, StorageCollection } from '../types';
2
2
  import { LOCAL_PK } from '../../types';
3
3
  import type { SQLiteTableSchemaMetadata, SQLiteIterateEntriesOptions, SQLiteOrderByOptions, SQLiteCollectionState, TableEntry } from './types';
4
4
  import { SQLiteAdapter } from './SQLiteAdapter';
@@ -11,15 +11,15 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
11
11
  readonly schema: SQLiteTableSchemaMetadata;
12
12
  readonly hook: unknown = Object.freeze({});
13
13
  readonly raw: {
14
- add: (item: T) => Promise<unknown>;
15
- put: (item: T) => Promise<unknown>;
16
- update: (key: unknown, changes: Partial<T>) => Promise<number>;
17
- delete: (key: unknown) => Promise<void>;
18
- get: (key: unknown) => Promise<T | undefined>;
19
- bulkAdd: (items: T[]) => Promise<unknown>;
20
- bulkPut: (items: T[]) => Promise<unknown>;
21
- bulkUpdate: (keysAndChanges: Array<{ key: unknown; changes: Partial<T> }>) => Promise<number>;
22
- bulkDelete: (keys: Array<unknown>) => Promise<void>;
14
+ add: (item: T) => Promise<string>;
15
+ put: (item: T) => Promise<string>;
16
+ update: (key: string, changes: Partial<T>) => Promise<number>;
17
+ delete: (key: string) => Promise<void>;
18
+ get: (key: string) => Promise<T | undefined>;
19
+ bulkAdd: (items: T[]) => Promise<string[]>;
20
+ bulkPut: (items: T[]) => Promise<string[]>;
21
+ bulkUpdate: (keysAndChanges: Array<{ key: string; changes: Partial<T> }>) => Promise<number>;
22
+ bulkDelete: (keys: string[]) => Promise<void>;
23
23
  clear: () => Promise<void>;
24
24
  };
25
25
 
@@ -54,19 +54,19 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
54
54
  });
55
55
  }
56
56
 
57
- async add(item: T): Promise<unknown> {
58
- return this.baseAdd(item);
57
+ async add(item: AddItem<T>): Promise<string> {
58
+ return this.baseAdd(item as T);
59
59
  }
60
60
 
61
- async put(item: T): Promise<unknown> {
61
+ async put(item: T): Promise<string> {
62
62
  return this.basePut(item);
63
63
  }
64
64
 
65
- async update(key: unknown, changes: Partial<T>): Promise<number> {
65
+ async update(key: string, changes: Partial<T>): Promise<number> {
66
66
  return this.baseUpdate(key, changes);
67
67
  }
68
68
 
69
- async delete(key: unknown): Promise<void> {
69
+ async delete(key: string): Promise<void> {
70
70
  await this.baseDelete(key);
71
71
  }
72
72
 
@@ -78,7 +78,7 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
78
78
  await this.adapter.execute(`DELETE FROM ${quoteIdentifier(this.name)}`);
79
79
  }
80
80
 
81
- async get(key: unknown): Promise<T | undefined> {
81
+ async get(key: string): Promise<T | undefined> {
82
82
  if (!key || typeof key !== 'string') {
83
83
  return undefined;
84
84
  }
@@ -96,12 +96,12 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
96
96
  return Number(rows[0]?.count ?? 0);
97
97
  }
98
98
 
99
- async bulkAdd(items: T[]): Promise<unknown> {
100
- return this.baseBulkAdd(items);
99
+ async bulkAdd(items: AddItem<T>[]): Promise<string[]> {
100
+ return this.baseBulkAdd(items as T[]);
101
101
  }
102
102
 
103
- private async baseBulkAdd(items: T[]): Promise<unknown> {
104
- if (!items.length) return undefined;
103
+ private async baseBulkAdd(items: T[]): Promise<string[]> {
104
+ if (!items.length) return [];
105
105
 
106
106
  const columns = this.columnNames;
107
107
  const columnCount = columns.length;
@@ -109,7 +109,7 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
109
109
  const maxParamsPerBatch = 500;
110
110
  const batchSize = Math.max(1, Math.floor(maxParamsPerBatch / columnCount));
111
111
 
112
- let lastKey: unknown = undefined;
112
+ const allKeys: string[] = [];
113
113
 
114
114
  for (let i = 0; i < items.length; i += batchSize) {
115
115
  const batch = items.slice(i, i + batchSize);
@@ -121,32 +121,31 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
121
121
 
122
122
  for (const record of records) {
123
123
  values.push(...this.extractColumnValues(record));
124
+ allKeys.push((record as any)[LOCAL_PK]);
124
125
  }
125
126
 
126
127
  await this.adapter.run(
127
128
  `INSERT INTO ${quoteIdentifier(this.name)} (${columns.map((c) => quoteIdentifier(c)).join(', ')}) VALUES ${placeholders}`,
128
129
  values,
129
130
  );
130
-
131
- lastKey = (records[records.length - 1] as any)[LOCAL_PK];
132
131
  }
133
132
 
134
- return lastKey;
133
+ return allKeys;
135
134
  }
136
135
 
137
- async bulkPut(items: T[]): Promise<unknown> {
136
+ async bulkPut(items: T[]): Promise<string[]> {
138
137
  return this.baseBulkPut(items);
139
138
  }
140
139
 
141
- private async baseBulkPut(items: T[]): Promise<unknown> {
142
- if (!items.length) return undefined;
140
+ private async baseBulkPut(items: T[]): Promise<string[]> {
141
+ if (!items.length) return [];
143
142
 
144
143
  const columns = this.columnNames;
145
144
  const columnCount = columns.length;
146
145
  const maxParamsPerBatch = 500;
147
146
  const batchSize = Math.max(1, Math.floor(maxParamsPerBatch / columnCount));
148
147
 
149
- let lastKey: unknown = undefined;
148
+ const allKeys: string[] = [];
150
149
 
151
150
  for (let i = 0; i < items.length; i += batchSize) {
152
151
  const batch = items.slice(i, i + batchSize);
@@ -158,20 +157,19 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
158
157
 
159
158
  for (const record of records) {
160
159
  values.push(...this.extractColumnValues(record));
160
+ allKeys.push((record as any)[LOCAL_PK]);
161
161
  }
162
162
 
163
163
  await this.adapter.run(
164
164
  `INSERT OR REPLACE INTO ${quoteIdentifier(this.name)} (${columns.map((c) => quoteIdentifier(c)).join(', ')}) VALUES ${placeholders}`,
165
165
  values,
166
166
  );
167
-
168
- lastKey = (records[records.length - 1] as any)[LOCAL_PK];
169
167
  }
170
168
 
171
- return lastKey;
169
+ return allKeys;
172
170
  }
173
171
 
174
- async bulkGet(keys: Array<unknown>): Promise<Array<T | undefined>> {
172
+ async bulkGet(keys: string[]): Promise<Array<T | undefined>> {
175
173
  if (!keys.length) return [];
176
174
 
177
175
  // Use IN clause for bulk lookup
@@ -197,11 +195,11 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
197
195
  return keys.map((key) => (key && typeof key === 'string' ? recordMap.get(key) : undefined));
198
196
  }
199
197
 
200
- async bulkUpdate(keysAndChanges: Array<{ key: unknown; changes: Partial<T> }>): Promise<number> {
198
+ async bulkUpdate(keysAndChanges: Array<{ key: string; changes: Partial<T> }>): Promise<number> {
201
199
  return this.baseBulkUpdate(keysAndChanges);
202
200
  }
203
201
 
204
- private async baseBulkUpdate(keysAndChanges: Array<{ key: unknown; changes: Partial<T> }>): Promise<number> {
202
+ private async baseBulkUpdate(keysAndChanges: Array<{ key: string; changes: Partial<T> }>): Promise<number> {
205
203
  if (!keysAndChanges.length) return 0;
206
204
 
207
205
  let updatedCount = 0;
@@ -212,11 +210,11 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
212
210
  return updatedCount;
213
211
  }
214
212
 
215
- async bulkDelete(keys: Array<unknown>): Promise<void> {
213
+ async bulkDelete(keys: string[]): Promise<void> {
216
214
  await this.baseBulkDelete(keys);
217
215
  }
218
216
 
219
- private async baseBulkDelete(keys: Array<unknown>): Promise<void> {
217
+ private async baseBulkDelete(keys: string[]): Promise<void> {
220
218
  if (!keys.length) return;
221
219
 
222
220
  const validKeys = keys.filter((k) => k && typeof k === 'string');
@@ -476,9 +476,9 @@ export class WaSqliteDriver implements SQLiteDatabaseDriver {
476
476
 
477
477
  /**
478
478
  * Delete the database.
479
- * This will close the database if open and remove all persisted data.
479
+ * This will close the database if open and delete all persisted data.
480
480
  * For IndexedDB-based VFS, this deletes the IndexedDB database.
481
- * For OPFS-based VFS, this removes the files from OPFS.
481
+ * For OPFS-based VFS, this deletes the files from OPFS.
482
482
  */
483
483
  async delete(): Promise<void> {
484
484
  // Close if open
@@ -499,12 +499,12 @@ export class WaSqliteDriver implements SQLiteDatabaseDriver {
499
499
  };
500
500
  });
501
501
  } else {
502
- // For OPFS-based VFS, remove the directory
502
+ // For OPFS-based VFS, delete the directory
503
503
  const dbPath = this.buildDatabasePath();
504
504
  const root = await navigator.storage.getDirectory();
505
505
 
506
506
  try {
507
- // Try to remove the file/directory
507
+ // Try to delete the file/directory
508
508
  const pathParts = dbPath.split('/').filter(Boolean);
509
509
  let current = root;
510
510
 
@@ -513,11 +513,11 @@ export class WaSqliteDriver implements SQLiteDatabaseDriver {
513
513
  current = await current.getDirectoryHandle(pathParts[i]!);
514
514
  }
515
515
 
516
- // Remove the database file
516
+ // Delete the database file
517
517
  const filename = pathParts[pathParts.length - 1]!;
518
518
  await current.removeEntry(filename, { recursive: true });
519
519
 
520
- // Also try to remove associated journal/wal files
520
+ // Also try to delete associated journal/wal files
521
521
  const associatedFiles = [`${filename}-journal`, `${filename}-wal`, `${filename}-shm`];
522
522
  for (const file of associatedFiles) {
523
523
  try {
@@ -71,23 +71,26 @@ export interface StorageWhereClause<T = any> {
71
71
  notEqual(value: any): StorageCollection<T>;
72
72
  }
73
73
 
74
+ // Item type for add operations - _localId is optional since Dync auto-generates it
75
+ export type AddItem<T> = Omit<T, '_localId'> & { _localId?: string };
76
+
74
77
  export interface StorageTable<T = any> {
75
78
  readonly name: string;
76
79
  readonly schema: unknown;
77
80
  readonly hook: unknown;
78
- add(item: T): Promise<unknown>;
79
- put(item: T): Promise<unknown>;
80
- update(key: unknown, changes: Partial<T>): Promise<number>;
81
- delete(key: unknown): Promise<void>;
81
+ add(item: AddItem<T>): Promise<string>;
82
+ put(item: T): Promise<string>;
83
+ update(key: string, changes: Partial<T>): Promise<number>;
84
+ delete(key: string): Promise<void>;
82
85
  clear(): Promise<void>;
83
- get(key: unknown): Promise<T | undefined>;
86
+ get(key: string): Promise<T | undefined>;
84
87
  toArray(): Promise<T[]>;
85
88
  count(): Promise<number>;
86
- bulkAdd(items: T[]): Promise<unknown>;
87
- bulkPut(items: T[]): Promise<unknown>;
88
- bulkGet(keys: Array<unknown>): Promise<Array<T | undefined>>;
89
- bulkUpdate(keysAndChanges: Array<{ key: unknown; changes: Partial<T> }>): Promise<number>;
90
- bulkDelete(keys: Array<unknown>): Promise<void>;
89
+ bulkAdd(items: AddItem<T>[]): Promise<string[]>;
90
+ bulkPut(items: T[]): Promise<string[]>;
91
+ bulkGet(keys: string[]): Promise<Array<T | undefined>>;
92
+ bulkUpdate(keysAndChanges: Array<{ key: string; changes: Partial<T> }>): Promise<number>;
93
+ bulkDelete(keys: string[]): Promise<void>;
91
94
  where(index: string | string[]): StorageWhereClause<T>;
92
95
  orderBy(index: string | string[]): StorageCollection<T>;
93
96
  reverse(): StorageCollection<T>;
@@ -98,15 +101,15 @@ export interface StorageTable<T = any> {
98
101
  jsFilter(predicate: (item: T) => boolean): StorageCollection<T>;
99
102
  // The "raw" property exposes the underlying storage operations without Dync sync logic.
100
103
  readonly raw: {
101
- add(item: T): Promise<unknown>;
102
- put(item: T): Promise<unknown>;
103
- update(key: unknown, changes: Partial<T>): Promise<number>;
104
- delete(key: unknown): Promise<void>;
105
- get(key: unknown): Promise<T | undefined>;
106
- bulkAdd(items: T[]): Promise<unknown>;
107
- bulkPut(items: T[]): Promise<unknown>;
108
- bulkUpdate(keysAndChanges: Array<{ key: unknown; changes: Partial<T> }>): Promise<number>;
109
- bulkDelete(keys: Array<unknown>): Promise<void>;
104
+ add(item: T): Promise<string>;
105
+ put(item: T): Promise<string>;
106
+ update(key: string, changes: Partial<T>): Promise<number>;
107
+ delete(key: string): Promise<void>;
108
+ get(key: string): Promise<T | undefined>;
109
+ bulkAdd(items: T[]): Promise<string[]>;
110
+ bulkPut(items: T[]): Promise<string[]>;
111
+ bulkUpdate(keysAndChanges: Array<{ key: string; changes: Partial<T> }>): Promise<number>;
112
+ bulkDelete(keys: string[]): Promise<void>;
110
113
  clear(): Promise<void>;
111
114
  };
112
115
  }
package/src/types.ts CHANGED
@@ -15,7 +15,7 @@ export interface SyncedRecord {
15
15
  export interface ApiFunctions {
16
16
  add: (item: any) => Promise<any | undefined>;
17
17
  update: (id: any, changes: any, item: any) => Promise<boolean>;
18
- remove: (id: any) => Promise<void>;
18
+ delete: (id: any) => Promise<void>;
19
19
  list: (lastUpdatedAt: Date) => Promise<any[]>;
20
20
  firstLoad?: (lastId: any) => Promise<any[]>;
21
21
  }
@@ -29,9 +29,9 @@ export interface ApiFunctions {
29
29
  */
30
30
  export interface BatchPushPayload {
31
31
  table: string;
32
- action: 'add' | 'update' | 'remove';
32
+ action: 'add' | 'update' | 'delete';
33
33
  localId: string;
34
- // Server-assigned ID (for update/remove)
34
+ // Server-assigned ID (for update/delete)
35
35
  id?: any;
36
36
  // The data to sync (for add/update)
37
37
  data?: any;
@@ -152,7 +152,7 @@ export interface SyncState extends PersistedSyncState {
152
152
  export enum SyncAction {
153
153
  Create = 'create',
154
154
  Update = 'update',
155
- Remove = 'remove', // Remote removes are a noop if no record found
155
+ Delete = 'delete', // Remote deletes are a noop if no record found
156
156
  }
157
157
 
158
158
  export interface PendingChange {