dexie-cloud-addon 4.2.0 → 4.2.2
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/dexie-cloud-import.json +6 -0
- package/dist/modern/dexie-cloud-addon.js +193 -68
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/service-worker.js +193 -68
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.js +194 -69
- package/dist/umd/dexie-cloud-addon.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.min.js +1 -1
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/service-worker.js +194 -69
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/package.json +4 -4
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.2.
|
|
11
|
+
* Version 4.2.2, Sat Oct 04 2025
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -2472,17 +2472,14 @@
|
|
|
2472
2472
|
: mutationTable;
|
|
2473
2473
|
if (limit < Infinity)
|
|
2474
2474
|
query = query.limit(limit);
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
mut.values = await objTable.bulkGet(mut.keys);
|
|
2480
|
-
}
|
|
2481
|
-
}*/
|
|
2482
|
-
return muts.map((mut) => ({
|
|
2475
|
+
let muts = yield query.toArray();
|
|
2476
|
+
muts = canonicalizeToUpdateOps(muts);
|
|
2477
|
+
muts = removeRedundantUpdateOps(muts);
|
|
2478
|
+
const rv = muts.map((mut) => ({
|
|
2483
2479
|
table: tableName,
|
|
2484
2480
|
mut,
|
|
2485
2481
|
}));
|
|
2482
|
+
return rv;
|
|
2486
2483
|
})));
|
|
2487
2484
|
// Sort by time to get a true order of the operations (between tables)
|
|
2488
2485
|
const sorted = flatten(allMutsOnTables).sort((a, b) => a.mut.txid === b.mut.txid
|
|
@@ -2511,6 +2508,69 @@
|
|
|
2511
2508
|
return result;
|
|
2512
2509
|
});
|
|
2513
2510
|
}
|
|
2511
|
+
function removeRedundantUpdateOps(muts) {
|
|
2512
|
+
const updateCoverage = new Map();
|
|
2513
|
+
for (const mut of muts) {
|
|
2514
|
+
if (mut.type === 'update') {
|
|
2515
|
+
if (mut.keys.length !== 1 || mut.changeSpecs.length !== 1) {
|
|
2516
|
+
continue; // Don't optimize multi-key updates
|
|
2517
|
+
}
|
|
2518
|
+
const strKey = '' + mut.keys[0];
|
|
2519
|
+
const changeSpecs = mut.changeSpecs[0];
|
|
2520
|
+
if (Object.values(changeSpecs).some(v => typeof v === "object" && v && "@@propmod" in v)) {
|
|
2521
|
+
continue; // Cannot optimize if any PropModification is present
|
|
2522
|
+
}
|
|
2523
|
+
let keyCoverage = updateCoverage.get(strKey);
|
|
2524
|
+
if (keyCoverage) {
|
|
2525
|
+
keyCoverage.push({ txid: mut.txid, updateSpec: changeSpecs });
|
|
2526
|
+
}
|
|
2527
|
+
else {
|
|
2528
|
+
updateCoverage.set(strKey, [{ txid: mut.txid, updateSpec: changeSpecs }]);
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
muts = muts.filter(mut => {
|
|
2533
|
+
// Only apply optimization to update mutations that are single-key
|
|
2534
|
+
if (mut.type !== 'update')
|
|
2535
|
+
return true;
|
|
2536
|
+
if (mut.keys.length !== 1 || mut.changeSpecs.length !== 1)
|
|
2537
|
+
return true;
|
|
2538
|
+
// Keep track of properties that aren't overlapped by later transactions
|
|
2539
|
+
const unoverlappedProps = new Set(Object.keys(mut.changeSpecs[0]));
|
|
2540
|
+
const strKey = '' + mut.keys[0];
|
|
2541
|
+
const keyCoverage = updateCoverage.get(strKey);
|
|
2542
|
+
for (let i = keyCoverage.length - 1; i >= 0; --i) {
|
|
2543
|
+
const { txid, updateSpec } = keyCoverage[i];
|
|
2544
|
+
if (txid === mut.txid)
|
|
2545
|
+
break; // Stop when reaching own txid
|
|
2546
|
+
// If all changes in updateSpec are covered by all props on all mut.changeSpecs then
|
|
2547
|
+
// txid is redundant and can be removed.
|
|
2548
|
+
for (const keyPath of Object.keys(updateSpec)) {
|
|
2549
|
+
unoverlappedProps.delete(keyPath);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
if (unoverlappedProps.size === 0) {
|
|
2553
|
+
// This operation is completely overlapped by later operations. It can be removed.
|
|
2554
|
+
return false;
|
|
2555
|
+
}
|
|
2556
|
+
return true;
|
|
2557
|
+
});
|
|
2558
|
+
return muts;
|
|
2559
|
+
}
|
|
2560
|
+
function canonicalizeToUpdateOps(muts) {
|
|
2561
|
+
muts = muts.map(mut => {
|
|
2562
|
+
if (mut.type === 'modify' && mut.criteria.index === null) {
|
|
2563
|
+
// The criteria is on primary key. Convert to an update operation instead.
|
|
2564
|
+
// It is simpler for the server to handle and also more efficient.
|
|
2565
|
+
const updateMut = Object.assign(Object.assign({}, mut), { criteria: undefined, changeSpec: undefined, type: 'update', keys: mut.keys, changeSpecs: [mut.changeSpec] });
|
|
2566
|
+
delete updateMut.criteria;
|
|
2567
|
+
delete updateMut.changeSpec;
|
|
2568
|
+
return updateMut;
|
|
2569
|
+
}
|
|
2570
|
+
return mut;
|
|
2571
|
+
});
|
|
2572
|
+
return muts;
|
|
2573
|
+
}
|
|
2514
2574
|
|
|
2515
2575
|
function randomString(bytes) {
|
|
2516
2576
|
const buf = new Uint8Array(bytes);
|
|
@@ -14193,7 +14253,7 @@
|
|
|
14193
14253
|
*
|
|
14194
14254
|
* ==========================================================================
|
|
14195
14255
|
*
|
|
14196
|
-
* Version 4.2.
|
|
14256
|
+
* Version 4.2.1, Sat Oct 04 2025
|
|
14197
14257
|
*
|
|
14198
14258
|
* https://dexie.org
|
|
14199
14259
|
*
|
|
@@ -16005,6 +16065,7 @@
|
|
|
16005
16065
|
let values = 'values' in req ? req.values : [];
|
|
16006
16066
|
let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;
|
|
16007
16067
|
let updates = 'updates' in req ? req.updates : undefined;
|
|
16068
|
+
let upsert = updates && 'upsert' in req ? req.upsert : false;
|
|
16008
16069
|
if (hasFailures) {
|
|
16009
16070
|
keys = keys.filter((_, idx) => !failures[idx]);
|
|
16010
16071
|
values = values.filter((_, idx) => !failures[idx]);
|
|
@@ -16036,29 +16097,32 @@
|
|
|
16036
16097
|
};
|
|
16037
16098
|
const validKeys = new Dexie.RangeSet();
|
|
16038
16099
|
let anyChangeSpecBecameEmpty = false;
|
|
16039
|
-
|
|
16040
|
-
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
16044
|
-
|
|
16045
|
-
|
|
16046
|
-
|
|
16100
|
+
if (!upsert) {
|
|
16101
|
+
for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {
|
|
16102
|
+
if (Object.keys(strippedChangeSpecs[i]).length > 0) {
|
|
16103
|
+
newUpdates.keys.push(updates.keys[i]);
|
|
16104
|
+
newUpdates.changeSpecs.push(strippedChangeSpecs[i]);
|
|
16105
|
+
validKeys.addKey(updates.keys[i]);
|
|
16106
|
+
}
|
|
16107
|
+
else {
|
|
16108
|
+
anyChangeSpecBecameEmpty = true;
|
|
16109
|
+
}
|
|
16047
16110
|
}
|
|
16048
|
-
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
|
|
16053
|
-
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16111
|
+
updates = newUpdates;
|
|
16112
|
+
if (anyChangeSpecBecameEmpty) {
|
|
16113
|
+
// Some keys were stripped. We must also strip them from keys and values
|
|
16114
|
+
// unless this is an upsert operation in which case we want to send them all.
|
|
16115
|
+
let newKeys = [];
|
|
16116
|
+
let newValues = [];
|
|
16117
|
+
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
16118
|
+
if (validKeys.hasKey(keys[i])) {
|
|
16119
|
+
newKeys.push(keys[i]);
|
|
16120
|
+
newValues.push(values[i]);
|
|
16121
|
+
}
|
|
16058
16122
|
}
|
|
16123
|
+
keys = newKeys;
|
|
16124
|
+
values = newValues;
|
|
16059
16125
|
}
|
|
16060
|
-
keys = newKeys;
|
|
16061
|
-
values = newValues;
|
|
16062
16126
|
}
|
|
16063
16127
|
}
|
|
16064
16128
|
}
|
|
@@ -16100,49 +16164,59 @@
|
|
|
16100
16164
|
userId,
|
|
16101
16165
|
values,
|
|
16102
16166
|
}
|
|
16103
|
-
:
|
|
16104
|
-
|
|
16105
|
-
|
|
16106
|
-
|
|
16107
|
-
|
|
16108
|
-
|
|
16109
|
-
|
|
16110
|
-
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
}
|
|
16115
|
-
: changeSpec
|
|
16167
|
+
: upsert ? {
|
|
16168
|
+
type: 'upsert',
|
|
16169
|
+
ts,
|
|
16170
|
+
opNo,
|
|
16171
|
+
keys,
|
|
16172
|
+
values,
|
|
16173
|
+
changeSpecs: updates.changeSpecs.filter((_, idx) => !failures[idx]),
|
|
16174
|
+
txid,
|
|
16175
|
+
userId,
|
|
16176
|
+
}
|
|
16177
|
+
: criteria && changeSpec
|
|
16116
16178
|
? {
|
|
16117
|
-
//
|
|
16118
|
-
type: '
|
|
16179
|
+
// Common changeSpec for all keys
|
|
16180
|
+
type: 'modify',
|
|
16119
16181
|
ts,
|
|
16120
16182
|
opNo,
|
|
16121
16183
|
keys,
|
|
16122
|
-
|
|
16184
|
+
criteria,
|
|
16185
|
+
changeSpec,
|
|
16123
16186
|
txid,
|
|
16124
16187
|
userId,
|
|
16125
16188
|
}
|
|
16126
|
-
:
|
|
16189
|
+
: changeSpec
|
|
16127
16190
|
? {
|
|
16128
|
-
//
|
|
16191
|
+
// In case criteria involved an unsynced property, we go for keys instead.
|
|
16129
16192
|
type: 'update',
|
|
16130
16193
|
ts,
|
|
16131
16194
|
opNo,
|
|
16132
|
-
keys: updates.keys,
|
|
16133
|
-
changeSpecs: updates.changeSpecs,
|
|
16134
|
-
txid,
|
|
16135
|
-
userId,
|
|
16136
|
-
}
|
|
16137
|
-
: {
|
|
16138
|
-
type: 'upsert',
|
|
16139
|
-
ts,
|
|
16140
|
-
opNo,
|
|
16141
16195
|
keys,
|
|
16142
|
-
|
|
16196
|
+
changeSpecs: keys.map(() => changeSpec),
|
|
16143
16197
|
txid,
|
|
16144
16198
|
userId,
|
|
16145
|
-
}
|
|
16199
|
+
}
|
|
16200
|
+
: updates
|
|
16201
|
+
? {
|
|
16202
|
+
// One changeSpec per key
|
|
16203
|
+
type: 'update',
|
|
16204
|
+
ts,
|
|
16205
|
+
opNo,
|
|
16206
|
+
keys: updates.keys,
|
|
16207
|
+
changeSpecs: updates.changeSpecs,
|
|
16208
|
+
txid,
|
|
16209
|
+
userId,
|
|
16210
|
+
}
|
|
16211
|
+
: {
|
|
16212
|
+
type: 'upsert',
|
|
16213
|
+
ts,
|
|
16214
|
+
opNo,
|
|
16215
|
+
keys,
|
|
16216
|
+
values,
|
|
16217
|
+
txid,
|
|
16218
|
+
userId,
|
|
16219
|
+
};
|
|
16146
16220
|
if ('isAdditionalChunk' in req && req.isAdditionalChunk) {
|
|
16147
16221
|
mut.isAdditionalChunk = true;
|
|
16148
16222
|
}
|
|
@@ -17299,34 +17373,85 @@
|
|
|
17299
17373
|
alignItems: "center",
|
|
17300
17374
|
display: "flex",
|
|
17301
17375
|
justifyContent: "center",
|
|
17376
|
+
padding: "16px",
|
|
17377
|
+
boxSizing: "border-box"
|
|
17302
17378
|
},
|
|
17303
17379
|
DialogInner: {
|
|
17304
17380
|
position: "relative",
|
|
17305
17381
|
color: "#222",
|
|
17306
17382
|
backgroundColor: "#fff",
|
|
17307
|
-
padding: "
|
|
17383
|
+
padding: "24px",
|
|
17308
17384
|
marginBottom: "2em",
|
|
17309
|
-
maxWidth: "
|
|
17385
|
+
maxWidth: "400px",
|
|
17386
|
+
width: "100%",
|
|
17310
17387
|
maxHeight: "90%",
|
|
17311
17388
|
overflowY: "auto",
|
|
17312
17389
|
border: "3px solid #3d3d5d",
|
|
17313
17390
|
borderRadius: "8px",
|
|
17314
17391
|
boxShadow: "0 0 80px 10px #666",
|
|
17315
|
-
width: "auto",
|
|
17316
17392
|
fontFamily: "sans-serif",
|
|
17393
|
+
boxSizing: "border-box"
|
|
17317
17394
|
},
|
|
17318
17395
|
Input: {
|
|
17319
17396
|
height: "35px",
|
|
17320
|
-
width: "
|
|
17397
|
+
width: "100%",
|
|
17398
|
+
maxWidth: "100%",
|
|
17321
17399
|
borderColor: "#ccf4",
|
|
17322
17400
|
outline: "none",
|
|
17323
|
-
fontSize: "
|
|
17324
|
-
padding: "8px"
|
|
17401
|
+
fontSize: "16px",
|
|
17402
|
+
padding: "8px",
|
|
17403
|
+
boxSizing: "border-box"
|
|
17404
|
+
},
|
|
17405
|
+
Button: {
|
|
17406
|
+
padding: "10px 20px",
|
|
17407
|
+
margin: "0 4px",
|
|
17408
|
+
border: "1px solid #d1d5db",
|
|
17409
|
+
borderRadius: "6px",
|
|
17410
|
+
backgroundColor: "#ffffff",
|
|
17411
|
+
cursor: "pointer",
|
|
17412
|
+
fontSize: "14px",
|
|
17413
|
+
fontWeight: "500",
|
|
17414
|
+
color: "#374151",
|
|
17415
|
+
transition: "all 0.2s ease"
|
|
17416
|
+
},
|
|
17417
|
+
PrimaryButton: {
|
|
17418
|
+
padding: "10px 20px",
|
|
17419
|
+
margin: "0 4px",
|
|
17420
|
+
border: "1px solid #3b82f6",
|
|
17421
|
+
borderRadius: "6px",
|
|
17422
|
+
backgroundColor: "#3b82f6",
|
|
17423
|
+
color: "white",
|
|
17424
|
+
cursor: "pointer",
|
|
17425
|
+
fontSize: "14px",
|
|
17426
|
+
fontWeight: "500",
|
|
17427
|
+
transition: "all 0.2s ease"
|
|
17428
|
+
},
|
|
17429
|
+
ButtonsDiv: {
|
|
17430
|
+
display: "flex",
|
|
17431
|
+
justifyContent: "flex-end",
|
|
17432
|
+
gap: "12px",
|
|
17433
|
+
marginTop: "24px",
|
|
17434
|
+
paddingTop: "20px"
|
|
17435
|
+
},
|
|
17436
|
+
Label: {
|
|
17437
|
+
display: "block",
|
|
17438
|
+
marginBottom: "12px",
|
|
17439
|
+
fontSize: "14px",
|
|
17440
|
+
fontWeight: "500",
|
|
17441
|
+
color: "#333"
|
|
17442
|
+
},
|
|
17443
|
+
WindowHeader: {
|
|
17444
|
+
margin: "0 0 20px 0",
|
|
17445
|
+
fontSize: "18px",
|
|
17446
|
+
fontWeight: "600",
|
|
17447
|
+
color: "#333",
|
|
17448
|
+
borderBottom: "1px solid #eee",
|
|
17449
|
+
paddingBottom: "10px"
|
|
17325
17450
|
}
|
|
17326
17451
|
};
|
|
17327
17452
|
|
|
17328
17453
|
function Dialog({ children, className }) {
|
|
17329
|
-
return (h("div", { className: className },
|
|
17454
|
+
return (h("div", { className: `dexie-dialog ${className || ''}` },
|
|
17330
17455
|
h("div", { style: Styles.Darken }),
|
|
17331
17456
|
h("div", { style: Styles.DialogOuter },
|
|
17332
17457
|
h("div", { style: Styles.DialogInner }, children))));
|
|
@@ -17378,7 +17503,7 @@
|
|
|
17378
17503
|
} })))))),
|
|
17379
17504
|
h("div", { style: Styles.ButtonsDiv },
|
|
17380
17505
|
h(p$1, null,
|
|
17381
|
-
h("button", { type: "submit", style: Styles.
|
|
17506
|
+
h("button", { type: "submit", style: Styles.PrimaryButton, onClick: () => onSubmit(params) }, submitLabel),
|
|
17382
17507
|
cancelLabel && (h("button", { style: Styles.Button, onClick: onCancel }, cancelLabel))))));
|
|
17383
17508
|
}
|
|
17384
17509
|
function valueTransformer(type, value) {
|
|
@@ -18180,7 +18305,7 @@
|
|
|
18180
18305
|
const syncComplete = new rxjs.Subject();
|
|
18181
18306
|
dexie.cloud = {
|
|
18182
18307
|
// @ts-ignore
|
|
18183
|
-
version: "4.2.
|
|
18308
|
+
version: "4.2.2",
|
|
18184
18309
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
18185
18310
|
schema: null,
|
|
18186
18311
|
get currentUserId() {
|
|
@@ -18497,7 +18622,7 @@
|
|
|
18497
18622
|
}
|
|
18498
18623
|
}
|
|
18499
18624
|
// @ts-ignore
|
|
18500
|
-
dexieCloud.version = "4.2.
|
|
18625
|
+
dexieCloud.version = "4.2.2";
|
|
18501
18626
|
Dexie.Cloud = dexieCloud;
|
|
18502
18627
|
|
|
18503
18628
|
exports.default = dexieCloud;
|