cry-synced-db-client 0.1.164 → 0.1.166
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/dist/index.js +48 -8
- package/dist/src/db/SyncedDb.d.ts +17 -0
- package/dist/src/types/I_SyncedDb.d.ts +8 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -507,6 +507,11 @@ function setSegment(current, part, value) {
|
|
|
507
507
|
const idStr = part.slice(1, -1);
|
|
508
508
|
if (!Array.isArray(current)) return false;
|
|
509
509
|
const idx = current.findIndex((item) => item && String(item._id) === idStr);
|
|
510
|
+
if (Array.isArray(value) && value.length === 1 && value[0] && typeof value[0] === "object" && String(value[0]._id) === idStr) {
|
|
511
|
+
if (idx >= 0) current[idx] = value[0];
|
|
512
|
+
else current.push(value[0]);
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
510
515
|
if (idx < 0) return false;
|
|
511
516
|
current[idx] = value;
|
|
512
517
|
return true;
|
|
@@ -562,6 +567,14 @@ function isTerminalBracketKey(path) {
|
|
|
562
567
|
const last = tokens[tokens.length - 1];
|
|
563
568
|
return !!(last && last.length >= 2 && last.charCodeAt(0) === 91 && last.charCodeAt(last.length - 1) === 93);
|
|
564
569
|
}
|
|
570
|
+
function canExpandArrayToBrackets(value) {
|
|
571
|
+
if (!Array.isArray(value) || value.length === 0) return false;
|
|
572
|
+
for (const el of value) {
|
|
573
|
+
if (el === null || typeof el !== "object") return false;
|
|
574
|
+
if (el._id == null) return false;
|
|
575
|
+
}
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
565
578
|
function mergeDirtyPath(accumulated, newPath, newValue) {
|
|
566
579
|
for (const existingKey of Object.keys(accumulated)) {
|
|
567
580
|
if (existingKey === newPath) continue;
|
|
@@ -575,7 +588,16 @@ function mergeDirtyPath(accumulated, newPath, newValue) {
|
|
|
575
588
|
if (existingIsTerminal && Array.isArray(existingValue) && existingValue.length === 1) {
|
|
576
589
|
mutationTarget = existingValue[0];
|
|
577
590
|
}
|
|
578
|
-
|
|
591
|
+
if (!existingIsTerminal && newPath[existingKey.length] === "[" && canExpandArrayToBrackets(existingValue)) {
|
|
592
|
+
delete accumulated[existingKey];
|
|
593
|
+
for (const el of existingValue) {
|
|
594
|
+
accumulated[`${existingKey}[${String(el._id)}]`] = [el];
|
|
595
|
+
}
|
|
596
|
+
mergeDirtyPath(accumulated, newPath, newValue);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
const sepChar = newPath[existingKey.length];
|
|
600
|
+
const relativePath = sepChar === "[" ? newPath.substring(existingKey.length) : newPath.substring(existingKey.length + 1);
|
|
579
601
|
const ok = setByPath(mutationTarget, relativePath, newValue);
|
|
580
602
|
if (ok) return;
|
|
581
603
|
break;
|
|
@@ -4951,6 +4973,9 @@ var _SyncedDb = class _SyncedDb {
|
|
|
4951
4973
|
}
|
|
4952
4974
|
async upsert(collection, query, update) {
|
|
4953
4975
|
this.assertCollection(collection);
|
|
4976
|
+
if ((query == null ? void 0 : query._id) != null && update._id == null) {
|
|
4977
|
+
update._id = query._id;
|
|
4978
|
+
}
|
|
4954
4979
|
this.ensureId(update, "upsert", collection);
|
|
4955
4980
|
query = _SyncedDb.stringifyObjectIds(query);
|
|
4956
4981
|
update = _SyncedDb.stringifyObjectIds(update);
|
|
@@ -5204,16 +5229,31 @@ var _SyncedDb = class _SyncedDb {
|
|
|
5204
5229
|
isSyncing() {
|
|
5205
5230
|
return this.syncing;
|
|
5206
5231
|
}
|
|
5207
|
-
// ==================== Batch Operations
|
|
5232
|
+
// ==================== Batch Operations ====================
|
|
5233
|
+
/**
|
|
5234
|
+
* Run each batch entry through the standard `upsert()` pipeline so every
|
|
5235
|
+
* write — single or batched — goes through `computeDiff` →
|
|
5236
|
+
* `applyDiffLocally` → in-mem write + Dexie schedule + dirty change.
|
|
5237
|
+
*
|
|
5238
|
+
* Server upload remains batched: dirty entries accumulated by the per-item
|
|
5239
|
+
* calls coalesce into one `updateCollections` request at the next sync
|
|
5240
|
+
* flush. We never bypass the diff pipeline (no separate server-only
|
|
5241
|
+
* `restInterface.upsertBatch` route), so bracket-by-_id sub-field path
|
|
5242
|
+
* generation and conflict resolution behave identically to a sequence of
|
|
5243
|
+
* `upsert()` calls.
|
|
5244
|
+
*
|
|
5245
|
+
* Works offline — items queue as dirty and upload on reconnect.
|
|
5246
|
+
*
|
|
5247
|
+
* Per-entry `opts` (`UpsertOptions` / `FindOneAndUpdateOptions`) is
|
|
5248
|
+
* ignored; the diff pipeline has no mongo-`findOneAndUpdate` knob.
|
|
5249
|
+
*/
|
|
5208
5250
|
async upsertBatch(collection, batch) {
|
|
5209
5251
|
this.assertCollection(collection);
|
|
5210
|
-
|
|
5211
|
-
|
|
5252
|
+
const results = [];
|
|
5253
|
+
for (const entry of batch) {
|
|
5254
|
+
results.push(await this.upsert(collection, entry.query, entry.update));
|
|
5212
5255
|
}
|
|
5213
|
-
return
|
|
5214
|
-
this.restInterface.upsertBatch(collection, batch),
|
|
5215
|
-
"upsertBatch"
|
|
5216
|
-
);
|
|
5256
|
+
return results;
|
|
5217
5257
|
}
|
|
5218
5258
|
// ==================== In-Memory Access ====================
|
|
5219
5259
|
getMemoryCollection(collection) {
|
|
@@ -156,6 +156,23 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
156
156
|
sync(calledFrom?: string): Promise<void>;
|
|
157
157
|
private processQueuedWsUpdates;
|
|
158
158
|
isSyncing(): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Run each batch entry through the standard `upsert()` pipeline so every
|
|
161
|
+
* write — single or batched — goes through `computeDiff` →
|
|
162
|
+
* `applyDiffLocally` → in-mem write + Dexie schedule + dirty change.
|
|
163
|
+
*
|
|
164
|
+
* Server upload remains batched: dirty entries accumulated by the per-item
|
|
165
|
+
* calls coalesce into one `updateCollections` request at the next sync
|
|
166
|
+
* flush. We never bypass the diff pipeline (no separate server-only
|
|
167
|
+
* `restInterface.upsertBatch` route), so bracket-by-_id sub-field path
|
|
168
|
+
* generation and conflict resolution behave identically to a sequence of
|
|
169
|
+
* `upsert()` calls.
|
|
170
|
+
*
|
|
171
|
+
* Works offline — items queue as dirty and upload on reconnect.
|
|
172
|
+
*
|
|
173
|
+
* Per-entry `opts` (`UpsertOptions` / `FindOneAndUpdateOptions`) is
|
|
174
|
+
* ignored; the diff pipeline has no mongo-`findOneAndUpdate` knob.
|
|
175
|
+
*/
|
|
159
176
|
upsertBatch<T extends DbEntity>(collection: string, batch: BatchSpec<T>): Promise<T[]>;
|
|
160
177
|
getMemoryCollection<T extends DbEntity>(collection: string): T[];
|
|
161
178
|
getDebounceDexieWritesMs(): number;
|
|
@@ -866,27 +866,15 @@ export interface I_SyncedDb {
|
|
|
866
866
|
*/
|
|
867
867
|
getSyncOnlyTheseCollections(): ReadonlySet<string> | null;
|
|
868
868
|
/**
|
|
869
|
-
*
|
|
869
|
+
* Batch wrapper around `upsert()` — applies each entry via the standard
|
|
870
|
+
* write pipeline (`computeDiff` → `applyDiffLocally` → in-mem + Dexie +
|
|
871
|
+
* dirty change). Dirty entries from all entries coalesce into a single
|
|
872
|
+
* `updateCollections` request at the next sync flush, so the server side
|
|
873
|
+
* still sees one batched upload.
|
|
870
874
|
*
|
|
871
|
-
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
* If you need local state to reflect the changes after calling upsertBatch(),
|
|
876
|
-
* call sync() afterward to fetch the updated data from the server.
|
|
877
|
-
*
|
|
878
|
-
* Note: Server notifications (via serverUpdateNotifier) for upsertBatch changes
|
|
879
|
-
* may trigger handleServerUpdate(), which will update local state. However, this
|
|
880
|
-
* happens asynchronously and may overwrite concurrent local changes if any exist.
|
|
881
|
-
*
|
|
882
|
-
* - Deluje samo online, offline vrže napako
|
|
883
|
-
* - Ne posodablja dexie ali in-mem baze
|
|
884
|
-
* - Uporabljeno za operacije, ki ne potrebujejo lokalne sinhronizacije
|
|
885
|
-
*
|
|
886
|
-
* @example
|
|
887
|
-
* // If you need local state updated after batch operation:
|
|
888
|
-
* await syncedDb.upsertBatch('items', batchSpec);
|
|
889
|
-
* await syncedDb.sync(); // Fetch changes to local state
|
|
875
|
+
* Works offline; entries queue as dirty and upload on reconnect.
|
|
876
|
+
* Per-entry `opts` is ignored (no mongo-`findOneAndUpdate` knob in the
|
|
877
|
+
* diff pipeline).
|
|
890
878
|
*/
|
|
891
879
|
upsertBatch<T extends DbEntity>(collection: string, batch: BatchSpec<T>): Promise<T[]>;
|
|
892
880
|
/** Vrne vse objekte iz in-mem baze za dano kolekcijo */
|