@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.
- package/README.md +32 -14
- package/dist/{chunk-66PSQW4D.js → chunk-YAAFAS64.js} +42 -42
- package/dist/chunk-YAAFAS64.js.map +1 -0
- package/dist/{dexie-Bv-fV10P.d.cts → dexie-1_xyU5MV.d.cts} +41 -38
- package/dist/{dexie-DJFApKsM.d.ts → dexie-ChZ0o0Sz.d.ts} +41 -38
- package/dist/dexie.cjs +40 -40
- package/dist/dexie.cjs.map +1 -1
- package/dist/dexie.d.cts +1 -1
- package/dist/dexie.d.ts +1 -1
- package/dist/dexie.js +40 -40
- package/dist/dexie.js.map +1 -1
- package/dist/index.cjs +41 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{index.shared-CkYsQYyn.d.ts → index.shared-3gbnIINY.d.ts} +4 -4
- package/dist/{index.shared-BGwvMH8f.d.cts → index.shared-XsB8HrvX.d.cts} +4 -4
- package/dist/react/index.cjs +26 -26
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/wa-sqlite.cjs +2 -2
- package/dist/wa-sqlite.cjs.map +1 -1
- package/dist/wa-sqlite.d.cts +2 -2
- package/dist/wa-sqlite.d.ts +2 -2
- package/dist/wa-sqlite.js +2 -2
- package/dist/wa-sqlite.js.map +1 -1
- package/package.json +1 -1
- package/src/core/StateManager.ts +4 -4
- package/src/core/pullOperations.ts +3 -3
- package/src/core/pushOperations.ts +13 -13
- package/src/core/tableEnhancers.ts +20 -20
- package/src/helpers.ts +1 -1
- package/src/storage/dexie/DexieAdapter.ts +2 -2
- package/src/storage/dexie/{DexieStorageCollection.ts → DexieCollection.ts} +12 -12
- package/src/storage/dexie/DexieTable.ts +123 -0
- package/src/storage/dexie/{DexieStorageWhereClause.ts → DexieWhereClause.ts} +21 -21
- package/src/storage/dexie/index.ts +3 -3
- package/src/storage/memory/MemoryTable.ts +40 -40
- package/src/storage/sqlite/SQLiteTable.ts +34 -36
- package/src/storage/sqlite/drivers/WaSqliteDriver.ts +6 -6
- package/src/storage/types.ts +22 -19
- package/src/types.ts +4 -4
- package/dist/chunk-66PSQW4D.js.map +0 -1
- 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<
|
|
15
|
-
put: (item: T) => Promise<
|
|
16
|
-
update: (key:
|
|
17
|
-
delete: (key:
|
|
18
|
-
get: (key:
|
|
19
|
-
bulkAdd: (items: T[]) => Promise<
|
|
20
|
-
bulkPut: (items: T[]) => Promise<
|
|
21
|
-
bulkUpdate: (keysAndChanges: Array<{ key:
|
|
22
|
-
bulkDelete: (keys:
|
|
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<
|
|
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<
|
|
61
|
+
async put(item: T): Promise<string> {
|
|
62
62
|
return this.basePut(item);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
async update(key:
|
|
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:
|
|
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:
|
|
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<
|
|
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<
|
|
104
|
-
if (!items.length) return
|
|
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
|
-
|
|
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
|
|
133
|
+
return allKeys;
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
async bulkPut(items: T[]): Promise<
|
|
136
|
+
async bulkPut(items: T[]): Promise<string[]> {
|
|
138
137
|
return this.baseBulkPut(items);
|
|
139
138
|
}
|
|
140
139
|
|
|
141
|
-
private async baseBulkPut(items: T[]): Promise<
|
|
142
|
-
if (!items.length) return
|
|
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
|
-
|
|
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
|
|
169
|
+
return allKeys;
|
|
172
170
|
}
|
|
173
171
|
|
|
174
|
-
async bulkGet(keys:
|
|
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:
|
|
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:
|
|
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:
|
|
213
|
+
async bulkDelete(keys: string[]): Promise<void> {
|
|
216
214
|
await this.baseBulkDelete(keys);
|
|
217
215
|
}
|
|
218
216
|
|
|
219
|
-
private async baseBulkDelete(keys:
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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 {
|
package/src/storage/types.ts
CHANGED
|
@@ -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<
|
|
79
|
-
put(item: T): Promise<
|
|
80
|
-
update(key:
|
|
81
|
-
delete(key:
|
|
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:
|
|
86
|
+
get(key: string): Promise<T | undefined>;
|
|
84
87
|
toArray(): Promise<T[]>;
|
|
85
88
|
count(): Promise<number>;
|
|
86
|
-
bulkAdd(items: T[]): Promise<
|
|
87
|
-
bulkPut(items: T[]): Promise<
|
|
88
|
-
bulkGet(keys:
|
|
89
|
-
bulkUpdate(keysAndChanges: Array<{ key:
|
|
90
|
-
bulkDelete(keys:
|
|
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<
|
|
102
|
-
put(item: T): Promise<
|
|
103
|
-
update(key:
|
|
104
|
-
delete(key:
|
|
105
|
-
get(key:
|
|
106
|
-
bulkAdd(items: T[]): Promise<
|
|
107
|
-
bulkPut(items: T[]): Promise<
|
|
108
|
-
bulkUpdate(keysAndChanges: Array<{ key:
|
|
109
|
-
bulkDelete(keys:
|
|
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
|
-
|
|
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' | '
|
|
32
|
+
action: 'add' | 'update' | 'delete';
|
|
33
33
|
localId: string;
|
|
34
|
-
// Server-assigned ID (for update/
|
|
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
|
-
|
|
155
|
+
Delete = 'delete', // Remote deletes are a noop if no record found
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
export interface PendingChange {
|