@anfenn/dync 1.0.3 → 1.0.4
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 +31 -13
- package/dist/{chunk-66PSQW4D.js → chunk-PCA4XM2N.js} +17 -17
- package/dist/chunk-PCA4XM2N.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 +16 -16
- 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-Byhq6TyU.d.ts} +1 -1
- package/dist/{index.shared-BGwvMH8f.d.cts → index.shared-DsDBNWlz.d.cts} +1 -1
- package/dist/react/index.cjs +2 -2
- 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/package.json +1 -1
- package/src/core/tableEnhancers.ts +17 -17
- 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/types.ts +22 -19
- package/dist/chunk-66PSQW4D.js.map +0 -1
- package/src/storage/dexie/DexieStorageTable.ts +0 -123
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ And see how Dync compares to the alternatives [below](#hasnt-this-already-been-d
|
|
|
52
52
|
...,
|
|
53
53
|
{
|
|
54
54
|
// Only add an entry here for tables that should be synced
|
|
55
|
+
// Pseudocode here, see examples for working code
|
|
55
56
|
items: {
|
|
56
57
|
add: (item) => fetch('/api/items'),
|
|
57
58
|
update: (id, changes) => fetch(`/api/items/${id}`),
|
|
@@ -69,8 +70,21 @@ And see how Dync compares to the alternatives [below](#hasnt-this-already-been-d
|
|
|
69
70
|
...,
|
|
70
71
|
{
|
|
71
72
|
syncTables: ['items'], // Only add tables to this array that should be synced
|
|
72
|
-
push: (changes) =>
|
|
73
|
-
|
|
73
|
+
push: async (changes) => {
|
|
74
|
+
const res = await fetch('/api/sync/push', {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: { 'Content-Type': 'application/json' },
|
|
77
|
+
body: JSON.stringify(changes),
|
|
78
|
+
});
|
|
79
|
+
return res.json();
|
|
80
|
+
},
|
|
81
|
+
pull: async (since) => {
|
|
82
|
+
const params = new URLSearchParams(
|
|
83
|
+
Object.entries(since).map(([table, date]) => [table, date.toISOString()])
|
|
84
|
+
);
|
|
85
|
+
const res = await fetch(`/api/sync/pull?${params}`);
|
|
86
|
+
return res.json();
|
|
87
|
+
},
|
|
74
88
|
},
|
|
75
89
|
);
|
|
76
90
|
```
|
|
@@ -81,8 +95,8 @@ And see how Dync compares to the alternatives [below](#hasnt-this-already-been-d
|
|
|
81
95
|
|
|
82
96
|
```ts
|
|
83
97
|
const { syncState, db } = useDync();
|
|
84
|
-
syncState.conflicts; // Record<
|
|
85
|
-
db.sync.resolveConflict(
|
|
98
|
+
syncState.conflicts; // Record<localId, Conflict>
|
|
99
|
+
db.sync.resolveConflict(localId, true);
|
|
86
100
|
```
|
|
87
101
|
|
|
88
102
|
- Optional first load data download before periodic sync is enabled
|
|
@@ -90,10 +104,14 @@ And see how Dync compares to the alternatives [below](#hasnt-this-already-been-d
|
|
|
90
104
|
- Reactive updates when data changes via `useLiveQuery()` React hook:
|
|
91
105
|
|
|
92
106
|
```ts
|
|
93
|
-
useLiveQuery(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
useLiveQuery(
|
|
108
|
+
async (db) => {
|
|
109
|
+
const items = await db.items.toArray(); // toArray() executes the query
|
|
110
|
+
setTodos(items);
|
|
111
|
+
},
|
|
112
|
+
[], // Re-run when variables change
|
|
113
|
+
['items'], // Re-run when tables change
|
|
114
|
+
);
|
|
97
115
|
```
|
|
98
116
|
|
|
99
117
|
- Sqlite schema migration
|
|
@@ -159,11 +177,11 @@ Your server records **must** have these fields. If it does but they're named dif
|
|
|
159
177
|
|
|
160
178
|
Dync auto-injects these fields into your local table schema:
|
|
161
179
|
|
|
162
|
-
| Field | Description
|
|
163
|
-
| ------------ |
|
|
164
|
-
| `_localId` | Stable local identifier, never sent to the server. Ideal for React keys.
|
|
165
|
-
| `id` | Unique identifier (any datatype). Can be assigned by client or server.
|
|
166
|
-
| `updated_at` | Assigned from the server's `updated_at` after sync. You may set it optimistically, but it's always overwritten on sync.
|
|
180
|
+
| Field | Description |
|
|
181
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
182
|
+
| `_localId` | Stable local identifier, never sent to the server. Ideal for React keys. Auto-generated UUID, but can be set manually with any unique value. |
|
|
183
|
+
| `id` | Unique identifier (any datatype). Can be assigned by client or server. |
|
|
184
|
+
| `updated_at` | Assigned from the server's `updated_at` after sync. You may set it optimistically, but it's always overwritten on sync. |
|
|
167
185
|
|
|
168
186
|
Note: `deleted` doesn't exist on the client, as it's removed during sync.
|
|
169
187
|
|
|
@@ -481,7 +481,7 @@ function enhanceSyncTable({ table, tableName, withTransaction, state, enhancedTa
|
|
|
481
481
|
}
|
|
482
482
|
};
|
|
483
483
|
const wrappedBulkAdd = async (items) => {
|
|
484
|
-
if (items.length === 0) return;
|
|
484
|
+
if (items.length === 0) return [];
|
|
485
485
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
486
486
|
const syncedItems = items.map((item) => {
|
|
487
487
|
const localId = item._localId || createLocalId();
|
|
@@ -509,7 +509,7 @@ function enhanceSyncTable({ table, tableName, withTransaction, state, enhancedTa
|
|
|
509
509
|
return result;
|
|
510
510
|
};
|
|
511
511
|
const wrappedBulkPut = async (items) => {
|
|
512
|
-
if (items.length === 0) return;
|
|
512
|
+
if (items.length === 0) return [];
|
|
513
513
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
514
514
|
const syncedItems = items.map((item) => {
|
|
515
515
|
const localId = item._localId || createLocalId();
|
|
@@ -2015,23 +2015,23 @@ var MemoryTable = class {
|
|
|
2015
2015
|
return this.baseBulkAdd(items);
|
|
2016
2016
|
}
|
|
2017
2017
|
baseBulkAdd(items) {
|
|
2018
|
-
|
|
2018
|
+
const keys = [];
|
|
2019
2019
|
for (let index = 0; index < items.length; index += 1) {
|
|
2020
2020
|
const item = items[index];
|
|
2021
|
-
|
|
2021
|
+
keys.push(this.baseAdd(item));
|
|
2022
2022
|
}
|
|
2023
|
-
return
|
|
2023
|
+
return keys;
|
|
2024
2024
|
}
|
|
2025
2025
|
async bulkPut(items) {
|
|
2026
2026
|
return this.baseBulkPut(items);
|
|
2027
2027
|
}
|
|
2028
2028
|
baseBulkPut(items) {
|
|
2029
|
-
|
|
2029
|
+
const keys = [];
|
|
2030
2030
|
for (let index = 0; index < items.length; index += 1) {
|
|
2031
2031
|
const item = items[index];
|
|
2032
|
-
|
|
2032
|
+
keys.push(this.basePut(item));
|
|
2033
2033
|
}
|
|
2034
|
-
return
|
|
2034
|
+
return keys;
|
|
2035
2035
|
}
|
|
2036
2036
|
async bulkGet(keys) {
|
|
2037
2037
|
return Promise.all(keys.map((key) => this.get(key)));
|
|
@@ -3251,12 +3251,12 @@ var SQLiteTable = class {
|
|
|
3251
3251
|
return this.baseBulkAdd(items);
|
|
3252
3252
|
}
|
|
3253
3253
|
async baseBulkAdd(items) {
|
|
3254
|
-
if (!items.length) return
|
|
3254
|
+
if (!items.length) return [];
|
|
3255
3255
|
const columns = this.columnNames;
|
|
3256
3256
|
const columnCount = columns.length;
|
|
3257
3257
|
const maxParamsPerBatch = 500;
|
|
3258
3258
|
const batchSize = Math.max(1, Math.floor(maxParamsPerBatch / columnCount));
|
|
3259
|
-
|
|
3259
|
+
const allKeys = [];
|
|
3260
3260
|
for (let i = 0; i < items.length; i += batchSize) {
|
|
3261
3261
|
const batch = items.slice(i, i + batchSize);
|
|
3262
3262
|
const records = batch.map((item) => this.prepareRecordForWrite(item));
|
|
@@ -3265,25 +3265,25 @@ var SQLiteTable = class {
|
|
|
3265
3265
|
const values = [];
|
|
3266
3266
|
for (const record of records) {
|
|
3267
3267
|
values.push(...this.extractColumnValues(record));
|
|
3268
|
+
allKeys.push(record[LOCAL_PK]);
|
|
3268
3269
|
}
|
|
3269
3270
|
await this.adapter.run(
|
|
3270
3271
|
`INSERT INTO ${quoteIdentifier(this.name)} (${columns.map((c) => quoteIdentifier(c)).join(", ")}) VALUES ${placeholders}`,
|
|
3271
3272
|
values
|
|
3272
3273
|
);
|
|
3273
|
-
lastKey = records[records.length - 1][LOCAL_PK];
|
|
3274
3274
|
}
|
|
3275
|
-
return
|
|
3275
|
+
return allKeys;
|
|
3276
3276
|
}
|
|
3277
3277
|
async bulkPut(items) {
|
|
3278
3278
|
return this.baseBulkPut(items);
|
|
3279
3279
|
}
|
|
3280
3280
|
async baseBulkPut(items) {
|
|
3281
|
-
if (!items.length) return
|
|
3281
|
+
if (!items.length) return [];
|
|
3282
3282
|
const columns = this.columnNames;
|
|
3283
3283
|
const columnCount = columns.length;
|
|
3284
3284
|
const maxParamsPerBatch = 500;
|
|
3285
3285
|
const batchSize = Math.max(1, Math.floor(maxParamsPerBatch / columnCount));
|
|
3286
|
-
|
|
3286
|
+
const allKeys = [];
|
|
3287
3287
|
for (let i = 0; i < items.length; i += batchSize) {
|
|
3288
3288
|
const batch = items.slice(i, i + batchSize);
|
|
3289
3289
|
const records = batch.map((item) => this.prepareRecordForWrite(item));
|
|
@@ -3292,14 +3292,14 @@ var SQLiteTable = class {
|
|
|
3292
3292
|
const values = [];
|
|
3293
3293
|
for (const record of records) {
|
|
3294
3294
|
values.push(...this.extractColumnValues(record));
|
|
3295
|
+
allKeys.push(record[LOCAL_PK]);
|
|
3295
3296
|
}
|
|
3296
3297
|
await this.adapter.run(
|
|
3297
3298
|
`INSERT OR REPLACE INTO ${quoteIdentifier(this.name)} (${columns.map((c) => quoteIdentifier(c)).join(", ")}) VALUES ${placeholders}`,
|
|
3298
3299
|
values
|
|
3299
3300
|
);
|
|
3300
|
-
lastKey = records[records.length - 1][LOCAL_PK];
|
|
3301
3301
|
}
|
|
3302
|
-
return
|
|
3302
|
+
return allKeys;
|
|
3303
3303
|
}
|
|
3304
3304
|
async bulkGet(keys) {
|
|
3305
3305
|
if (!keys.length) return [];
|
|
@@ -3881,4 +3881,4 @@ export {
|
|
|
3881
3881
|
SqliteQueryContext,
|
|
3882
3882
|
SQLiteAdapter2 as SQLiteAdapter
|
|
3883
3883
|
};
|
|
3884
|
-
//# sourceMappingURL=chunk-
|
|
3884
|
+
//# sourceMappingURL=chunk-PCA4XM2N.js.map
|