dexie-cloud-addon 1.0.0-beta.10 → 1.0.0-beta.11
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/modern/dexie-cloud-addon.js +189 -158
- 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 +1208 -1176
- 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/module-es5/dexie-cloud-addon.js +259 -207
- package/dist/module-es5/dexie-cloud-addon.js.map +1 -1
- package/dist/module-es5/dexie-cloud-addon.min.js +1 -1
- package/dist/module-es5/dexie-cloud-addon.min.js.map +1 -1
- package/dist/types/WSObservable.d.ts +11 -6
- package/dist/types/WebSocketStatus.d.ts +1 -0
- package/dist/types/helpers/BroadcastedLocalEvent.d.ts +8 -0
- package/dist/types/helpers/visibleState.d.ts +1 -0
- package/dist/types/sync/syncServerToClientOnly.d.ts +3 -0
- package/dist/types/types/CloudConnectionStatus.d.ts +0 -0
- package/dist/types/types/ConnectionStatus.d.ts +0 -0
- package/dist/types/types/LoginState.d.ts +41 -0
- package/dist/types/types/SyncConnectionStatus.d.ts +1 -0
- package/dist/types/types/SyncFlowStatus.d.ts +6 -0
- package/dist/types/types/SyncStatus.d.ts +6 -0
- package/dist/umd/dexie-cloud-addon.js +259 -207
- 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 +1208 -1176
- 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/dist/umd-modern/dexie-cloud-addon.js +188 -157
- package/dist/umd-modern/dexie-cloud-addon.js.map +1 -1
- package/package.json +2 -2
|
@@ -97,7 +97,7 @@ function __spreadArray(to, from) {
|
|
|
97
97
|
*
|
|
98
98
|
* ==========================================================================
|
|
99
99
|
*
|
|
100
|
-
* Version 1.0.0-beta.10, Wed
|
|
100
|
+
* Version 1.0.0-beta.10, Wed Oct 06 2021
|
|
101
101
|
*
|
|
102
102
|
* https://dexie.org
|
|
103
103
|
*
|
|
@@ -3135,6 +3135,151 @@ var BroadcastedAndLocalEvent = /** @class */ (function (_super_1) {
|
|
|
3135
3135
|
};
|
|
3136
3136
|
return BroadcastedAndLocalEvent;
|
|
3137
3137
|
}(Observable$1));
|
|
3138
|
+
function computeRealmSetHash(_g) {
|
|
3139
|
+
var realms = _g.realms, inviteRealms = _g.inviteRealms;
|
|
3140
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3141
|
+
var data, byteArray, digestBytes, base64;
|
|
3142
|
+
return __generator(this, function (_h) {
|
|
3143
|
+
switch (_h.label) {
|
|
3144
|
+
case 0:
|
|
3145
|
+
data = JSON.stringify(__spreadArray(__spreadArray([], realms.map(function (realmId) { return ({ realmId: realmId, accepted: true }); })), inviteRealms.map(function (realmId) { return ({ realmId: realmId, accepted: false }); })).sort(function (a, b) { return a.realmId < b.realmId ? -1 : a.realmId > b.realmId ? 1 : 0; }));
|
|
3146
|
+
byteArray = new TextEncoder().encode(data);
|
|
3147
|
+
return [4 /*yield*/, crypto.subtle.digest('SHA-1', byteArray)];
|
|
3148
|
+
case 1:
|
|
3149
|
+
digestBytes = _h.sent();
|
|
3150
|
+
base64 = b64encode(digestBytes);
|
|
3151
|
+
return [2 /*return*/, base64];
|
|
3152
|
+
}
|
|
3153
|
+
});
|
|
3154
|
+
});
|
|
3155
|
+
}
|
|
3156
|
+
function getSyncableTables(db) {
|
|
3157
|
+
return Object.entries(db.cloud.schema || {})
|
|
3158
|
+
.filter(function (_g) {
|
|
3159
|
+
var markedForSync = _g[1].markedForSync;
|
|
3160
|
+
return markedForSync;
|
|
3161
|
+
})
|
|
3162
|
+
.map(function (_g) {
|
|
3163
|
+
var tbl = _g[0];
|
|
3164
|
+
return db.table(tbl);
|
|
3165
|
+
});
|
|
3166
|
+
}
|
|
3167
|
+
function getMutationTable(tableName) {
|
|
3168
|
+
return "$" + tableName + "_mutations";
|
|
3169
|
+
}
|
|
3170
|
+
function getTableFromMutationTable(mutationTable) {
|
|
3171
|
+
var _a;
|
|
3172
|
+
var tableName = (_a = /^\$(.*)_mutations$/.exec(mutationTable)) === null || _a === void 0 ? void 0 : _a[1];
|
|
3173
|
+
if (!tableName)
|
|
3174
|
+
throw new Error("Given mutationTable " + mutationTable + " is not correct");
|
|
3175
|
+
return tableName;
|
|
3176
|
+
}
|
|
3177
|
+
function listClientChanges(mutationTables, db, _g) {
|
|
3178
|
+
var _h = _g === void 0 ? {} : _g, _j = _h.since, since = _j === void 0 ? {} : _j, _k = _h.limit, limit = _k === void 0 ? Infinity : _k;
|
|
3179
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3180
|
+
var allMutsOnTables;
|
|
3181
|
+
var _this_1 = this;
|
|
3182
|
+
return __generator(this, function (_l) {
|
|
3183
|
+
switch (_l.label) {
|
|
3184
|
+
case 0: return [4 /*yield*/, Promise.all(mutationTables.map(function (mutationTable) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3185
|
+
var tableName, lastRevision, query, muts;
|
|
3186
|
+
return __generator(this, function (_g) {
|
|
3187
|
+
switch (_g.label) {
|
|
3188
|
+
case 0:
|
|
3189
|
+
tableName = getTableFromMutationTable(mutationTable.name);
|
|
3190
|
+
lastRevision = since[tableName];
|
|
3191
|
+
query = lastRevision
|
|
3192
|
+
? mutationTable.where("rev").above(lastRevision)
|
|
3193
|
+
: mutationTable;
|
|
3194
|
+
if (limit < Infinity)
|
|
3195
|
+
query = query.limit(limit);
|
|
3196
|
+
return [4 /*yield*/, query.toArray()];
|
|
3197
|
+
case 1:
|
|
3198
|
+
muts = _g.sent();
|
|
3199
|
+
//const objTable = db.table(tableName);
|
|
3200
|
+
/*for (const mut of muts) {
|
|
3201
|
+
if (mut.type === "insert" || mut.type === "upsert") {
|
|
3202
|
+
mut.values = await objTable.bulkGet(mut.keys);
|
|
3203
|
+
}
|
|
3204
|
+
}*/
|
|
3205
|
+
return [2 /*return*/, {
|
|
3206
|
+
table: tableName,
|
|
3207
|
+
muts: muts,
|
|
3208
|
+
}];
|
|
3209
|
+
}
|
|
3210
|
+
});
|
|
3211
|
+
}); }))];
|
|
3212
|
+
case 1:
|
|
3213
|
+
allMutsOnTables = _l.sent();
|
|
3214
|
+
// Filter out those tables that doesn't have any mutations:
|
|
3215
|
+
return [2 /*return*/, allMutsOnTables.filter(function (_g) {
|
|
3216
|
+
var muts = _g.muts;
|
|
3217
|
+
return muts.length > 0;
|
|
3218
|
+
})];
|
|
3219
|
+
}
|
|
3220
|
+
});
|
|
3221
|
+
});
|
|
3222
|
+
}
|
|
3223
|
+
function listSyncifiedChanges(tablesToSyncify, currentUser, schema, alreadySyncedRealms) {
|
|
3224
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3225
|
+
var ignoredRealms_1, inserts;
|
|
3226
|
+
var _this_1 = this;
|
|
3227
|
+
return __generator(this, function (_g) {
|
|
3228
|
+
switch (_g.label) {
|
|
3229
|
+
case 0:
|
|
3230
|
+
if (!currentUser.isLoggedIn) return [3 /*break*/, 2];
|
|
3231
|
+
if (!(tablesToSyncify.length > 0)) return [3 /*break*/, 2];
|
|
3232
|
+
ignoredRealms_1 = new Set(alreadySyncedRealms || []);
|
|
3233
|
+
return [4 /*yield*/, Promise.all(tablesToSyncify.map(function (table) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3234
|
+
var extractKey, dexieCloudTableSchema, query, unsyncedObjects, mut;
|
|
3235
|
+
return __generator(this, function (_g) {
|
|
3236
|
+
switch (_g.label) {
|
|
3237
|
+
case 0:
|
|
3238
|
+
extractKey = table.core.schema.primaryKey.extractKey;
|
|
3239
|
+
if (!extractKey)
|
|
3240
|
+
return [2 /*return*/, { table: table.name, muts: [] }]; // Outbound tables are not synced.
|
|
3241
|
+
dexieCloudTableSchema = schema[table.name];
|
|
3242
|
+
query = (dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.generatedGlobalId)
|
|
3243
|
+
? table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidSyncableID(extractKey(item)); })
|
|
3244
|
+
: table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidAtID(extractKey(item), dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.idPrefix); });
|
|
3245
|
+
return [4 /*yield*/, query.toArray()];
|
|
3246
|
+
case 1:
|
|
3247
|
+
unsyncedObjects = _g.sent();
|
|
3248
|
+
if (unsyncedObjects.length > 0) {
|
|
3249
|
+
mut = {
|
|
3250
|
+
type: "insert",
|
|
3251
|
+
values: unsyncedObjects,
|
|
3252
|
+
keys: unsyncedObjects.map(extractKey),
|
|
3253
|
+
userId: currentUser.userId,
|
|
3254
|
+
};
|
|
3255
|
+
return [2 /*return*/, {
|
|
3256
|
+
table: table.name,
|
|
3257
|
+
muts: [mut],
|
|
3258
|
+
}];
|
|
3259
|
+
}
|
|
3260
|
+
else {
|
|
3261
|
+
return [2 /*return*/, {
|
|
3262
|
+
table: table.name,
|
|
3263
|
+
muts: []
|
|
3264
|
+
}];
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
});
|
|
3268
|
+
}); }))];
|
|
3269
|
+
case 1:
|
|
3270
|
+
inserts = _g.sent();
|
|
3271
|
+
return [2 /*return*/, inserts.filter(function (op) { return op.muts.length > 0; })];
|
|
3272
|
+
case 2: return [2 /*return*/, []];
|
|
3273
|
+
}
|
|
3274
|
+
});
|
|
3275
|
+
});
|
|
3276
|
+
}
|
|
3277
|
+
function getTablesToSyncify(db, syncState) {
|
|
3278
|
+
var syncedTables = (syncState === null || syncState === void 0 ? void 0 : syncState.syncedTables) || [];
|
|
3279
|
+
var syncableTables = getSyncableTables(db);
|
|
3280
|
+
var tablesToSyncify = syncableTables.filter(function (tbl) { return !syncedTables.includes(tbl.name); });
|
|
3281
|
+
return tablesToSyncify;
|
|
3282
|
+
}
|
|
3138
3283
|
var toStr = {}.toString;
|
|
3139
3284
|
function getToStringTag(val) {
|
|
3140
3285
|
return toStr.call(val).slice(8, -1);
|
|
@@ -3654,22 +3799,6 @@ var undefinedDef = {
|
|
|
3654
3799
|
// else
|
|
3655
3800
|
// serverRev.rev = new FakeBigInt(server.rev)
|
|
3656
3801
|
var hasBigIntSupport = typeof BigInt(0) === 'bigint';
|
|
3657
|
-
function getValueOfBigInt(x) {
|
|
3658
|
-
if (typeof x === 'bigint') {
|
|
3659
|
-
return x;
|
|
3660
|
-
}
|
|
3661
|
-
if (hasBigIntSupport) {
|
|
3662
|
-
return typeof x === 'string' ? BigInt(x) : BigInt(x.v);
|
|
3663
|
-
}
|
|
3664
|
-
else {
|
|
3665
|
-
return typeof x === 'string' ? Number(x) : Number(x.v);
|
|
3666
|
-
}
|
|
3667
|
-
}
|
|
3668
|
-
function compareBigInts(a, b) {
|
|
3669
|
-
var valA = getValueOfBigInt(a);
|
|
3670
|
-
var valB = getValueOfBigInt(b);
|
|
3671
|
-
return valA < valB ? -1 : valA > valB ? 1 : 0;
|
|
3672
|
-
}
|
|
3673
3802
|
var FakeBigInt = /** @class */ (function () {
|
|
3674
3803
|
function FakeBigInt(value) {
|
|
3675
3804
|
this.v = value;
|
|
@@ -3695,151 +3824,6 @@ var defs = __assign(__assign({}, undefinedDef), (hasBigIntSupport
|
|
|
3695
3824
|
}));
|
|
3696
3825
|
var TSON = TypesonSimplified(builtin, defs);
|
|
3697
3826
|
var BISON = Bison(defs);
|
|
3698
|
-
function computeRealmSetHash(_g) {
|
|
3699
|
-
var realms = _g.realms, inviteRealms = _g.inviteRealms;
|
|
3700
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3701
|
-
var data, byteArray, digestBytes, base64;
|
|
3702
|
-
return __generator(this, function (_h) {
|
|
3703
|
-
switch (_h.label) {
|
|
3704
|
-
case 0:
|
|
3705
|
-
data = JSON.stringify(__spreadArray(__spreadArray([], realms.map(function (realmId) { return ({ realmId: realmId, accepted: true }); })), inviteRealms.map(function (realmId) { return ({ realmId: realmId, accepted: false }); })).sort(function (a, b) { return a.realmId < b.realmId ? -1 : a.realmId > b.realmId ? 1 : 0; }));
|
|
3706
|
-
byteArray = new TextEncoder().encode(data);
|
|
3707
|
-
return [4 /*yield*/, crypto.subtle.digest('SHA-1', byteArray)];
|
|
3708
|
-
case 1:
|
|
3709
|
-
digestBytes = _h.sent();
|
|
3710
|
-
base64 = b64encode(digestBytes);
|
|
3711
|
-
return [2 /*return*/, base64];
|
|
3712
|
-
}
|
|
3713
|
-
});
|
|
3714
|
-
});
|
|
3715
|
-
}
|
|
3716
|
-
function getSyncableTables(db) {
|
|
3717
|
-
return Object.entries(db.cloud.schema || {})
|
|
3718
|
-
.filter(function (_g) {
|
|
3719
|
-
var markedForSync = _g[1].markedForSync;
|
|
3720
|
-
return markedForSync;
|
|
3721
|
-
})
|
|
3722
|
-
.map(function (_g) {
|
|
3723
|
-
var tbl = _g[0];
|
|
3724
|
-
return db.table(tbl);
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
function getMutationTable(tableName) {
|
|
3728
|
-
return "$" + tableName + "_mutations";
|
|
3729
|
-
}
|
|
3730
|
-
function getTableFromMutationTable(mutationTable) {
|
|
3731
|
-
var _a;
|
|
3732
|
-
var tableName = (_a = /^\$(.*)_mutations$/.exec(mutationTable)) === null || _a === void 0 ? void 0 : _a[1];
|
|
3733
|
-
if (!tableName)
|
|
3734
|
-
throw new Error("Given mutationTable " + mutationTable + " is not correct");
|
|
3735
|
-
return tableName;
|
|
3736
|
-
}
|
|
3737
|
-
function listClientChanges(mutationTables, db, _g) {
|
|
3738
|
-
var _h = _g === void 0 ? {} : _g, _j = _h.since, since = _j === void 0 ? {} : _j, _k = _h.limit, limit = _k === void 0 ? Infinity : _k;
|
|
3739
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3740
|
-
var allMutsOnTables;
|
|
3741
|
-
var _this_1 = this;
|
|
3742
|
-
return __generator(this, function (_l) {
|
|
3743
|
-
switch (_l.label) {
|
|
3744
|
-
case 0: return [4 /*yield*/, Promise.all(mutationTables.map(function (mutationTable) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3745
|
-
var tableName, lastRevision, query, muts;
|
|
3746
|
-
return __generator(this, function (_g) {
|
|
3747
|
-
switch (_g.label) {
|
|
3748
|
-
case 0:
|
|
3749
|
-
tableName = getTableFromMutationTable(mutationTable.name);
|
|
3750
|
-
lastRevision = since[tableName];
|
|
3751
|
-
query = lastRevision
|
|
3752
|
-
? mutationTable.where("rev").above(lastRevision)
|
|
3753
|
-
: mutationTable;
|
|
3754
|
-
if (limit < Infinity)
|
|
3755
|
-
query = query.limit(limit);
|
|
3756
|
-
return [4 /*yield*/, query.toArray()];
|
|
3757
|
-
case 1:
|
|
3758
|
-
muts = _g.sent();
|
|
3759
|
-
//const objTable = db.table(tableName);
|
|
3760
|
-
/*for (const mut of muts) {
|
|
3761
|
-
if (mut.type === "insert" || mut.type === "upsert") {
|
|
3762
|
-
mut.values = await objTable.bulkGet(mut.keys);
|
|
3763
|
-
}
|
|
3764
|
-
}*/
|
|
3765
|
-
return [2 /*return*/, {
|
|
3766
|
-
table: tableName,
|
|
3767
|
-
muts: muts,
|
|
3768
|
-
}];
|
|
3769
|
-
}
|
|
3770
|
-
});
|
|
3771
|
-
}); }))];
|
|
3772
|
-
case 1:
|
|
3773
|
-
allMutsOnTables = _l.sent();
|
|
3774
|
-
// Filter out those tables that doesn't have any mutations:
|
|
3775
|
-
return [2 /*return*/, allMutsOnTables.filter(function (_g) {
|
|
3776
|
-
var muts = _g.muts;
|
|
3777
|
-
return muts.length > 0;
|
|
3778
|
-
})];
|
|
3779
|
-
}
|
|
3780
|
-
});
|
|
3781
|
-
});
|
|
3782
|
-
}
|
|
3783
|
-
function listSyncifiedChanges(tablesToSyncify, currentUser, schema, alreadySyncedRealms) {
|
|
3784
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3785
|
-
var ignoredRealms_1, inserts;
|
|
3786
|
-
var _this_1 = this;
|
|
3787
|
-
return __generator(this, function (_g) {
|
|
3788
|
-
switch (_g.label) {
|
|
3789
|
-
case 0:
|
|
3790
|
-
if (!currentUser.isLoggedIn) return [3 /*break*/, 2];
|
|
3791
|
-
if (!(tablesToSyncify.length > 0)) return [3 /*break*/, 2];
|
|
3792
|
-
ignoredRealms_1 = new Set(alreadySyncedRealms || []);
|
|
3793
|
-
return [4 /*yield*/, Promise.all(tablesToSyncify.map(function (table) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3794
|
-
var extractKey, dexieCloudTableSchema, query, unsyncedObjects, mut;
|
|
3795
|
-
return __generator(this, function (_g) {
|
|
3796
|
-
switch (_g.label) {
|
|
3797
|
-
case 0:
|
|
3798
|
-
extractKey = table.core.schema.primaryKey.extractKey;
|
|
3799
|
-
if (!extractKey)
|
|
3800
|
-
return [2 /*return*/, { table: table.name, muts: [] }]; // Outbound tables are not synced.
|
|
3801
|
-
dexieCloudTableSchema = schema[table.name];
|
|
3802
|
-
query = (dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.generatedGlobalId)
|
|
3803
|
-
? table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidSyncableID(extractKey(item)); })
|
|
3804
|
-
: table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidAtID(extractKey(item), dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.idPrefix); });
|
|
3805
|
-
return [4 /*yield*/, query.toArray()];
|
|
3806
|
-
case 1:
|
|
3807
|
-
unsyncedObjects = _g.sent();
|
|
3808
|
-
if (unsyncedObjects.length > 0) {
|
|
3809
|
-
mut = {
|
|
3810
|
-
type: "insert",
|
|
3811
|
-
values: unsyncedObjects,
|
|
3812
|
-
keys: unsyncedObjects.map(extractKey),
|
|
3813
|
-
userId: currentUser.userId,
|
|
3814
|
-
};
|
|
3815
|
-
return [2 /*return*/, {
|
|
3816
|
-
table: table.name,
|
|
3817
|
-
muts: [mut],
|
|
3818
|
-
}];
|
|
3819
|
-
}
|
|
3820
|
-
else {
|
|
3821
|
-
return [2 /*return*/, {
|
|
3822
|
-
table: table.name,
|
|
3823
|
-
muts: []
|
|
3824
|
-
}];
|
|
3825
|
-
}
|
|
3826
|
-
}
|
|
3827
|
-
});
|
|
3828
|
-
}); }))];
|
|
3829
|
-
case 1:
|
|
3830
|
-
inserts = _g.sent();
|
|
3831
|
-
return [2 /*return*/, inserts.filter(function (op) { return op.muts.length > 0; })];
|
|
3832
|
-
case 2: return [2 /*return*/, []];
|
|
3833
|
-
}
|
|
3834
|
-
});
|
|
3835
|
-
});
|
|
3836
|
-
}
|
|
3837
|
-
function getTablesToSyncify(db, syncState) {
|
|
3838
|
-
var syncedTables = (syncState === null || syncState === void 0 ? void 0 : syncState.syncedTables) || [];
|
|
3839
|
-
var syncableTables = getSyncableTables(db);
|
|
3840
|
-
var tablesToSyncify = syncableTables.filter(function (tbl) { return !syncedTables.includes(tbl.name); });
|
|
3841
|
-
return tablesToSyncify;
|
|
3842
|
-
}
|
|
3843
3827
|
//import {BisonWebStreamReader} from "dreambase-library/dist/typeson-simplified/BisonWebStreamReader";
|
|
3844
3828
|
function syncWithServer(changes, syncState, baseRevs, db, databaseUrl, schema, clientIdentity) {
|
|
3845
3829
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -3858,6 +3842,7 @@ function syncWithServer(changes, syncState, baseRevs, db, databaseUrl, schema, c
|
|
|
3858
3842
|
headers.Authorization = "Bearer " + accessToken;
|
|
3859
3843
|
}
|
|
3860
3844
|
syncRequest = {
|
|
3845
|
+
v: 2,
|
|
3861
3846
|
dbID: syncState === null || syncState === void 0 ? void 0 : syncState.remoteDbId,
|
|
3862
3847
|
clientIdentity: clientIdentity,
|
|
3863
3848
|
schema: schema || {},
|
|
@@ -4039,8 +4024,8 @@ function getLatestRevisionsPerTable(clientChangeSet, lastRevisions) {
|
|
|
4039
4024
|
if (lastRevisions === void 0) { lastRevisions = {}; }
|
|
4040
4025
|
for (var _g = 0, clientChangeSet_1 = clientChangeSet; _g < clientChangeSet_1.length; _g++) {
|
|
4041
4026
|
var _h = clientChangeSet_1[_g], table = _h.table, muts = _h.muts;
|
|
4042
|
-
var lastRev = muts.length > 0 ? muts[muts.length - 1].rev
|
|
4043
|
-
lastRevisions[table] = lastRev;
|
|
4027
|
+
var lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;
|
|
4028
|
+
lastRevisions[table] = lastRev || lastRevisions[table] || 0;
|
|
4044
4029
|
}
|
|
4045
4030
|
return lastRevisions;
|
|
4046
4031
|
}
|
|
@@ -4545,27 +4530,49 @@ function MessagesFromServerConsumer(db) {
|
|
|
4545
4530
|
var readyToServe = new BehaviorSubject(true);
|
|
4546
4531
|
var event = new BehaviorSubject(null);
|
|
4547
4532
|
var isWorking = false;
|
|
4533
|
+
var loopWarning = 0;
|
|
4534
|
+
var loopDetection = [0, 0, 0, 0, 0, 0, 0, 0, 0, Date.now()];
|
|
4548
4535
|
event.subscribe(function () { return __awaiter(_this_1, void 0, void 0, function () {
|
|
4549
4536
|
return __generator(this, function (_g) {
|
|
4550
4537
|
switch (_g.label) {
|
|
4551
4538
|
case 0:
|
|
4552
4539
|
if (isWorking)
|
|
4553
4540
|
return [2 /*return*/];
|
|
4554
|
-
if (!(queue.length > 0)) return [3 /*break*/,
|
|
4541
|
+
if (!(queue.length > 0)) return [3 /*break*/, 8];
|
|
4555
4542
|
isWorking = true;
|
|
4543
|
+
loopDetection.shift();
|
|
4544
|
+
loopDetection.push(Date.now());
|
|
4556
4545
|
readyToServe.next(false);
|
|
4557
4546
|
_g.label = 1;
|
|
4558
4547
|
case 1:
|
|
4559
|
-
_g.trys.push([1, , 3,
|
|
4548
|
+
_g.trys.push([1, , 3, 8]);
|
|
4560
4549
|
return [4 /*yield*/, consumeQueue()];
|
|
4561
4550
|
case 2:
|
|
4562
4551
|
_g.sent();
|
|
4563
|
-
return [3 /*break*/,
|
|
4552
|
+
return [3 /*break*/, 8];
|
|
4564
4553
|
case 3:
|
|
4554
|
+
if (!(loopDetection[loopDetection.length - 1] - loopDetection[0] < 10000)) return [3 /*break*/, 7];
|
|
4555
|
+
if (!(Date.now() - loopWarning < 5000)) return [3 /*break*/, 5];
|
|
4556
|
+
// Last time we did this, we ended up here too. Wait for a minute.
|
|
4557
|
+
console.warn("Slowing down websocket loop for one minute");
|
|
4558
|
+
loopWarning = Date.now() + 60000;
|
|
4559
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 60000); })];
|
|
4560
|
+
case 4:
|
|
4561
|
+
_g.sent();
|
|
4562
|
+
return [3 /*break*/, 7];
|
|
4563
|
+
case 5:
|
|
4564
|
+
// This is a one-time event. Just pause 10 seconds.
|
|
4565
|
+
console.warn("Slowing down websocket loop for 10 seconds");
|
|
4566
|
+
loopWarning = Date.now() + 10000;
|
|
4567
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 10000); })];
|
|
4568
|
+
case 6:
|
|
4569
|
+
_g.sent();
|
|
4570
|
+
_g.label = 7;
|
|
4571
|
+
case 7:
|
|
4565
4572
|
isWorking = false;
|
|
4566
4573
|
readyToServe.next(true);
|
|
4567
4574
|
return [7 /*endfinally*/];
|
|
4568
|
-
case
|
|
4575
|
+
case 8: return [2 /*return*/];
|
|
4569
4576
|
}
|
|
4570
4577
|
});
|
|
4571
4578
|
}); });
|
|
@@ -4590,6 +4597,9 @@ function MessagesFromServerConsumer(db) {
|
|
|
4590
4597
|
case 1:
|
|
4591
4598
|
_j.trys.push([1, 12, , 13]);
|
|
4592
4599
|
console.debug('processing msg', msg);
|
|
4600
|
+
// If the sync worker or service worker is syncing, wait 'til thei're done.
|
|
4601
|
+
// It's no need to have two channels at the same time - even though it wouldnt
|
|
4602
|
+
// be a problem - this is an optimization.
|
|
4593
4603
|
return [4 /*yield*/, db.cloud.syncState
|
|
4594
4604
|
.pipe(filter(function (_g) {
|
|
4595
4605
|
var phase = _g.phase;
|
|
@@ -4597,6 +4607,9 @@ function MessagesFromServerConsumer(db) {
|
|
|
4597
4607
|
}), take(1))
|
|
4598
4608
|
.toPromise()];
|
|
4599
4609
|
case 2:
|
|
4610
|
+
// If the sync worker or service worker is syncing, wait 'til thei're done.
|
|
4611
|
+
// It's no need to have two channels at the same time - even though it wouldnt
|
|
4612
|
+
// be a problem - this is an optimization.
|
|
4600
4613
|
_j.sent();
|
|
4601
4614
|
console.debug('processing msg', msg);
|
|
4602
4615
|
persistedSyncState = db.cloud.persistedSyncState.value;
|
|
@@ -4606,9 +4619,9 @@ function MessagesFromServerConsumer(db) {
|
|
|
4606
4619
|
_h = msg.type;
|
|
4607
4620
|
switch (_h) {
|
|
4608
4621
|
case 'token-expired': return [3 /*break*/, 3];
|
|
4609
|
-
case '
|
|
4610
|
-
case 'realm-
|
|
4611
|
-
case '
|
|
4622
|
+
case 'realm-added': return [3 /*break*/, 6];
|
|
4623
|
+
case 'realm-removed': return [3 /*break*/, 7];
|
|
4624
|
+
case 'realms-changed': return [3 /*break*/, 8];
|
|
4612
4625
|
case 'changes': return [3 /*break*/, 9];
|
|
4613
4626
|
}
|
|
4614
4627
|
return [3 /*break*/, 11];
|
|
@@ -4631,25 +4644,22 @@ function MessagesFromServerConsumer(db) {
|
|
|
4631
4644
|
// new token. So we don't need to do anything more here.
|
|
4632
4645
|
return [3 /*break*/, 11];
|
|
4633
4646
|
case 6:
|
|
4634
|
-
if (!(persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.
|
|
4635
|
-
|
|
4636
|
-
triggerSync(db, "pull");
|
|
4647
|
+
if (!((_a = persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms) === null || _a === void 0 ? void 0 : _a.includes(msg.realm))) {
|
|
4648
|
+
triggerSync(db, 'pull');
|
|
4637
4649
|
}
|
|
4638
4650
|
return [3 /*break*/, 11];
|
|
4639
4651
|
case 7:
|
|
4640
|
-
if (
|
|
4641
|
-
triggerSync(db,
|
|
4652
|
+
if ((_b = persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms) === null || _b === void 0 ? void 0 : _b.includes(msg.realm)) {
|
|
4653
|
+
triggerSync(db, 'pull');
|
|
4642
4654
|
}
|
|
4643
4655
|
return [3 /*break*/, 11];
|
|
4644
4656
|
case 8:
|
|
4645
|
-
|
|
4646
|
-
triggerSync(db, "pull");
|
|
4647
|
-
}
|
|
4657
|
+
triggerSync(db, 'pull');
|
|
4648
4658
|
return [3 /*break*/, 11];
|
|
4649
4659
|
case 9:
|
|
4650
4660
|
console.debug('changes');
|
|
4651
4661
|
if (((_c = db.cloud.syncState.value) === null || _c === void 0 ? void 0 : _c.phase) === 'error') {
|
|
4652
|
-
triggerSync(db,
|
|
4662
|
+
triggerSync(db, 'pull');
|
|
4653
4663
|
return [3 /*break*/, 11];
|
|
4654
4664
|
}
|
|
4655
4665
|
return [4 /*yield*/, db.transaction('rw', db.dx.tables, function (tx) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
@@ -4678,17 +4688,35 @@ function MessagesFromServerConsumer(db) {
|
|
|
4678
4688
|
return [2 /*return*/]; // Initial sync must have taken place - otherwise, ignore this.
|
|
4679
4689
|
}
|
|
4680
4690
|
// Verify again in ACID tx that we're on same server revision.
|
|
4681
|
-
if (
|
|
4691
|
+
if (msg.baseRev !== syncState.serverRevision) {
|
|
4682
4692
|
console.debug("baseRev (" + msg.baseRev + ") differs from our serverRevision in syncState (" + syncState.serverRevision + ")");
|
|
4693
|
+
// Should we trigger a sync now? No. This is a normal case
|
|
4694
|
+
// when another local peer (such as the SW or a websocket channel on other tab) has
|
|
4695
|
+
// updated syncState from new server information but we are not aware yet. It would
|
|
4696
|
+
// be unnescessary to do a sync in that case. Instead, the caller of this consumeQueue()
|
|
4697
|
+
// function will do readyToServe.next(true) right after this return, which will lead
|
|
4698
|
+
// to a "ready" message being sent to server with the new accurate serverRev we have,
|
|
4699
|
+
// so that the next message indeed will be correct.
|
|
4700
|
+
if (typeof msg.baseRev === 'string' && // v2 format
|
|
4701
|
+
(typeof syncState.serverRevision === 'bigint' || // v1 format
|
|
4702
|
+
typeof syncState.serverRevision === 'object') // v1 format old browser
|
|
4703
|
+
) {
|
|
4704
|
+
// The reason for the diff seems to be that server has migrated the revision format.
|
|
4705
|
+
// Do a full sync to update revision format.
|
|
4706
|
+
// If we don't do a sync request now, we could stuck in an endless loop.
|
|
4707
|
+
triggerSync(db, 'pull');
|
|
4708
|
+
}
|
|
4683
4709
|
return [2 /*return*/]; // Ignore message
|
|
4684
4710
|
}
|
|
4685
|
-
return [4 /*yield*/, Dexie.waitFor(
|
|
4711
|
+
return [4 /*yield*/, Dexie.waitFor(
|
|
4712
|
+
// Keep TX in non-IDB work
|
|
4713
|
+
computeRealmSetHash(syncState))];
|
|
4686
4714
|
case 2:
|
|
4687
4715
|
ourRealmSetHash = _h.sent();
|
|
4688
4716
|
console.debug('ourRealmSetHash', ourRealmSetHash);
|
|
4689
4717
|
if (ourRealmSetHash !== msg.realmSetHash) {
|
|
4690
4718
|
console.debug('not same realmSetHash', msg.realmSetHash);
|
|
4691
|
-
triggerSync(db,
|
|
4719
|
+
triggerSync(db, 'pull');
|
|
4692
4720
|
// The message isn't based on the same realms.
|
|
4693
4721
|
// Trigger a sync instead to resolve all things up.
|
|
4694
4722
|
return [2 /*return*/];
|
|
@@ -4702,6 +4730,7 @@ function MessagesFromServerConsumer(db) {
|
|
|
4702
4730
|
console.debug('msg queue: client changes', clientChanges);
|
|
4703
4731
|
_h.label = 4;
|
|
4704
4732
|
case 4:
|
|
4733
|
+
if (!(msg.changes.length > 0)) return [3 /*break*/, 6];
|
|
4705
4734
|
filteredChanges = filterServerChangesThroughAddedClientChanges(msg.changes, clientChanges);
|
|
4706
4735
|
//
|
|
4707
4736
|
// apply server changes
|
|
@@ -4710,6 +4739,8 @@ function MessagesFromServerConsumer(db) {
|
|
|
4710
4739
|
return [4 /*yield*/, applyServerChanges(filteredChanges, db)];
|
|
4711
4740
|
case 5:
|
|
4712
4741
|
_h.sent();
|
|
4742
|
+
_h.label = 6;
|
|
4743
|
+
case 6:
|
|
4713
4744
|
// Update latest revisions per table in case there are unsynced changes
|
|
4714
4745
|
// This can be a real case in future when we allow non-eagery sync.
|
|
4715
4746
|
// And it can actually be realistic now also, but very rare.
|
|
@@ -4718,14 +4749,14 @@ function MessagesFromServerConsumer(db) {
|
|
|
4718
4749
|
// Update base revs
|
|
4719
4750
|
console.debug('Updating baseRefs', syncState.latestRevisions);
|
|
4720
4751
|
return [4 /*yield*/, updateBaseRevs(db, schema, syncState.latestRevisions, msg.newRev)];
|
|
4721
|
-
case
|
|
4752
|
+
case 7:
|
|
4722
4753
|
_h.sent();
|
|
4723
4754
|
//
|
|
4724
4755
|
// Update syncState
|
|
4725
4756
|
//
|
|
4726
4757
|
console.debug('Updating syncState', syncState);
|
|
4727
4758
|
return [4 /*yield*/, db.$syncState.put(syncState, 'syncState')];
|
|
4728
|
-
case
|
|
4759
|
+
case 8:
|
|
4729
4760
|
_h.sent();
|
|
4730
4761
|
return [2 /*return*/];
|
|
4731
4762
|
}
|
|
@@ -5612,20 +5643,21 @@ var CLIENT_PING_INTERVAL = 30000;
|
|
|
5612
5643
|
var FAIL_RETRY_WAIT_TIME = 60000;
|
|
5613
5644
|
var WSObservable = /** @class */ (function (_super_1) {
|
|
5614
5645
|
__extends$1(WSObservable, _super_1);
|
|
5615
|
-
function WSObservable(databaseUrl, rev, clientIdentity, messageProducer, webSocketStatus, token, tokenExpiration) {
|
|
5616
|
-
return _super_1.call(this, function (subscriber) { return new WSConnection(databaseUrl, rev, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus); }) || this;
|
|
5646
|
+
function WSObservable(databaseUrl, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus, token, tokenExpiration) {
|
|
5647
|
+
return _super_1.call(this, function (subscriber) { return new WSConnection(databaseUrl, rev, realmSetHash, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus); }) || this;
|
|
5617
5648
|
}
|
|
5618
5649
|
return WSObservable;
|
|
5619
5650
|
}(Observable$1));
|
|
5620
5651
|
var counter = 0;
|
|
5621
5652
|
var WSConnection = /** @class */ (function (_super_1) {
|
|
5622
5653
|
__extends$1(WSConnection, _super_1);
|
|
5623
|
-
function WSConnection(databaseUrl, rev, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus) {
|
|
5654
|
+
function WSConnection(databaseUrl, rev, realmSetHash, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus) {
|
|
5624
5655
|
var _this_1 = _super_1.call(this, function () { return _this_1.teardown(); }) || this;
|
|
5625
5656
|
_this_1.id = ++counter;
|
|
5626
5657
|
console.debug('New WebSocket Connection', _this_1.id, token ? 'authorized' : 'unauthorized');
|
|
5627
5658
|
_this_1.databaseUrl = databaseUrl;
|
|
5628
5659
|
_this_1.rev = rev;
|
|
5660
|
+
_this_1.realmSetHash = realmSetHash;
|
|
5629
5661
|
_this_1.clientIdentity = clientIdentity;
|
|
5630
5662
|
_this_1.token = token;
|
|
5631
5663
|
_this_1.tokenExpiration = tokenExpiration;
|
|
@@ -5740,7 +5772,9 @@ var WSConnection = /** @class */ (function (_super_1) {
|
|
|
5740
5772
|
searchParams = new URLSearchParams();
|
|
5741
5773
|
if (this.subscriber.closed)
|
|
5742
5774
|
return [2 /*return*/];
|
|
5775
|
+
searchParams.set('v', "2");
|
|
5743
5776
|
searchParams.set('rev', this.rev);
|
|
5777
|
+
searchParams.set('realmsHash', this.realmSetHash);
|
|
5744
5778
|
searchParams.set('clientId', this.clientIdentity);
|
|
5745
5779
|
if (this.token) {
|
|
5746
5780
|
searchParams.set('token', this.token);
|
|
@@ -5857,12 +5891,26 @@ function connectWebSocket(db) {
|
|
|
5857
5891
|
var _this_1 = this;
|
|
5858
5892
|
return db.cloud.persistedSyncState.pipe(filter(function (syncState) { return syncState === null || syncState === void 0 ? void 0 : syncState.serverRevision; }), // Don't connect before there's no initial sync performed.
|
|
5859
5893
|
take(1), // Don't continue waking up whenever syncState change
|
|
5860
|
-
switchMap(function () { return db.cloud.currentUser
|
|
5894
|
+
switchMap(function (syncState) { return db.cloud.currentUser.pipe(map(function (userLogin) { return [userLogin, syncState]; })); }), switchMap(function (_g) {
|
|
5895
|
+
var userLogin = _g[0], syncState = _g[1];
|
|
5896
|
+
return userIsReallyActive.pipe(map(function (isActive) { return [isActive ? userLogin : null, syncState]; }));
|
|
5897
|
+
}), switchMap(function (_g) {
|
|
5898
|
+
var userLogin = _g[0], syncState = _g[1];
|
|
5899
|
+
return __awaiter(_this_1, void 0, void 0, function () { var _h; return __generator(this, function (_j) {
|
|
5900
|
+
switch (_j.label) {
|
|
5901
|
+
case 0:
|
|
5902
|
+
_h = [userLogin];
|
|
5903
|
+
return [4 /*yield*/, computeRealmSetHash(syncState)];
|
|
5904
|
+
case 1: return [2 /*return*/, _h.concat([_j.sent()])];
|
|
5905
|
+
}
|
|
5906
|
+
}); });
|
|
5907
|
+
}), switchMap(function (_g) {
|
|
5908
|
+
var userLogin = _g[0], realmSetHash = _g[1];
|
|
5861
5909
|
// Let server end query changes from last entry of same client-ID and forward.
|
|
5862
5910
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
5863
5911
|
// and the baseRev of the last from same client-ID.
|
|
5864
5912
|
return userLogin
|
|
5865
|
-
? new WSObservable(db.cloud.options.databaseUrl, db.cloud.persistedSyncState.value.serverRevision, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin.accessToken, userLogin.accessTokenExpiration)
|
|
5913
|
+
? new WSObservable(db.cloud.options.databaseUrl, db.cloud.persistedSyncState.value.serverRevision, realmSetHash, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin.accessToken, userLogin.accessTokenExpiration)
|
|
5866
5914
|
: from$1([]);
|
|
5867
5915
|
}), catchError(function (error) {
|
|
5868
5916
|
if ((error === null || error === void 0 ? void 0 : error.name) === 'TokenExpiredError') {
|
|
@@ -6018,22 +6066,26 @@ function LocalSyncWorker(db, cloudOptions, cloudSchema) {
|
|
|
6018
6066
|
var cancelToken = { cancelled: false };
|
|
6019
6067
|
function syncAndRetry(purpose, retryNum) {
|
|
6020
6068
|
if (retryNum === void 0) { retryNum = 1; }
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6069
|
+
// Use setTimeout() to get onto a clean stack and
|
|
6070
|
+
// break free from possible active transaction:
|
|
6071
|
+
setTimeout(function () {
|
|
6072
|
+
syncIfPossible(db, cloudOptions, cloudSchema, {
|
|
6073
|
+
cancelToken: cancelToken,
|
|
6074
|
+
retryImmediatelyOnFetchError: true,
|
|
6075
|
+
purpose: purpose,
|
|
6076
|
+
}).catch(function (e) {
|
|
6077
|
+
console.error('error in syncIfPossible()', e);
|
|
6078
|
+
if (cancelToken.cancelled) {
|
|
6079
|
+
stop();
|
|
6080
|
+
}
|
|
6081
|
+
else if (retryNum < 3) {
|
|
6082
|
+
// Mimic service worker sync event: retry 3 times
|
|
6083
|
+
// * first retry after 5 minutes
|
|
6084
|
+
// * second retry 15 minutes later
|
|
6085
|
+
setTimeout(function () { return syncAndRetry(purpose, retryNum + 1); }, [0, 5, 15][retryNum] * MINUTES);
|
|
6086
|
+
}
|
|
6087
|
+
});
|
|
6088
|
+
}, 0);
|
|
6037
6089
|
}
|
|
6038
6090
|
var start = function () {
|
|
6039
6091
|
// Sync eagerly whenever a change has happened (+ initially when there's no syncState yet)
|
|
@@ -6042,7 +6094,7 @@ function LocalSyncWorker(db, cloudOptions, cloudSchema) {
|
|
|
6042
6094
|
localSyncEventSubscription = db.localSyncEvent.subscribe(function (_g) {
|
|
6043
6095
|
var purpose = _g.purpose;
|
|
6044
6096
|
try {
|
|
6045
|
-
syncAndRetry(purpose ||
|
|
6097
|
+
syncAndRetry(purpose || 'pull');
|
|
6046
6098
|
}
|
|
6047
6099
|
catch (err) {
|
|
6048
6100
|
console.error('What-the....', err);
|