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
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
*
|
|
105
105
|
* ==========================================================================
|
|
106
106
|
*
|
|
107
|
-
* Version 1.0.0-beta.10, Wed
|
|
107
|
+
* Version 1.0.0-beta.10, Wed Oct 06 2021
|
|
108
108
|
*
|
|
109
109
|
* https://dexie.org
|
|
110
110
|
*
|
|
@@ -3142,6 +3142,151 @@
|
|
|
3142
3142
|
};
|
|
3143
3143
|
return BroadcastedAndLocalEvent;
|
|
3144
3144
|
}(rxjs.Observable));
|
|
3145
|
+
function computeRealmSetHash(_g) {
|
|
3146
|
+
var realms = _g.realms, inviteRealms = _g.inviteRealms;
|
|
3147
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3148
|
+
var data, byteArray, digestBytes, base64;
|
|
3149
|
+
return __generator(this, function (_h) {
|
|
3150
|
+
switch (_h.label) {
|
|
3151
|
+
case 0:
|
|
3152
|
+
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; }));
|
|
3153
|
+
byteArray = new TextEncoder().encode(data);
|
|
3154
|
+
return [4 /*yield*/, crypto.subtle.digest('SHA-1', byteArray)];
|
|
3155
|
+
case 1:
|
|
3156
|
+
digestBytes = _h.sent();
|
|
3157
|
+
base64 = b64encode(digestBytes);
|
|
3158
|
+
return [2 /*return*/, base64];
|
|
3159
|
+
}
|
|
3160
|
+
});
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
function getSyncableTables(db) {
|
|
3164
|
+
return Object.entries(db.cloud.schema || {})
|
|
3165
|
+
.filter(function (_g) {
|
|
3166
|
+
var markedForSync = _g[1].markedForSync;
|
|
3167
|
+
return markedForSync;
|
|
3168
|
+
})
|
|
3169
|
+
.map(function (_g) {
|
|
3170
|
+
var tbl = _g[0];
|
|
3171
|
+
return db.table(tbl);
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3174
|
+
function getMutationTable(tableName) {
|
|
3175
|
+
return "$" + tableName + "_mutations";
|
|
3176
|
+
}
|
|
3177
|
+
function getTableFromMutationTable(mutationTable) {
|
|
3178
|
+
var _a;
|
|
3179
|
+
var tableName = (_a = /^\$(.*)_mutations$/.exec(mutationTable)) === null || _a === void 0 ? void 0 : _a[1];
|
|
3180
|
+
if (!tableName)
|
|
3181
|
+
throw new Error("Given mutationTable " + mutationTable + " is not correct");
|
|
3182
|
+
return tableName;
|
|
3183
|
+
}
|
|
3184
|
+
function listClientChanges(mutationTables, db, _g) {
|
|
3185
|
+
var _h = _g === void 0 ? {} : _g, _j = _h.since, since = _j === void 0 ? {} : _j, _k = _h.limit, limit = _k === void 0 ? Infinity : _k;
|
|
3186
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3187
|
+
var allMutsOnTables;
|
|
3188
|
+
var _this_1 = this;
|
|
3189
|
+
return __generator(this, function (_l) {
|
|
3190
|
+
switch (_l.label) {
|
|
3191
|
+
case 0: return [4 /*yield*/, Promise.all(mutationTables.map(function (mutationTable) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3192
|
+
var tableName, lastRevision, query, muts;
|
|
3193
|
+
return __generator(this, function (_g) {
|
|
3194
|
+
switch (_g.label) {
|
|
3195
|
+
case 0:
|
|
3196
|
+
tableName = getTableFromMutationTable(mutationTable.name);
|
|
3197
|
+
lastRevision = since[tableName];
|
|
3198
|
+
query = lastRevision
|
|
3199
|
+
? mutationTable.where("rev").above(lastRevision)
|
|
3200
|
+
: mutationTable;
|
|
3201
|
+
if (limit < Infinity)
|
|
3202
|
+
query = query.limit(limit);
|
|
3203
|
+
return [4 /*yield*/, query.toArray()];
|
|
3204
|
+
case 1:
|
|
3205
|
+
muts = _g.sent();
|
|
3206
|
+
//const objTable = db.table(tableName);
|
|
3207
|
+
/*for (const mut of muts) {
|
|
3208
|
+
if (mut.type === "insert" || mut.type === "upsert") {
|
|
3209
|
+
mut.values = await objTable.bulkGet(mut.keys);
|
|
3210
|
+
}
|
|
3211
|
+
}*/
|
|
3212
|
+
return [2 /*return*/, {
|
|
3213
|
+
table: tableName,
|
|
3214
|
+
muts: muts,
|
|
3215
|
+
}];
|
|
3216
|
+
}
|
|
3217
|
+
});
|
|
3218
|
+
}); }))];
|
|
3219
|
+
case 1:
|
|
3220
|
+
allMutsOnTables = _l.sent();
|
|
3221
|
+
// Filter out those tables that doesn't have any mutations:
|
|
3222
|
+
return [2 /*return*/, allMutsOnTables.filter(function (_g) {
|
|
3223
|
+
var muts = _g.muts;
|
|
3224
|
+
return muts.length > 0;
|
|
3225
|
+
})];
|
|
3226
|
+
}
|
|
3227
|
+
});
|
|
3228
|
+
});
|
|
3229
|
+
}
|
|
3230
|
+
function listSyncifiedChanges(tablesToSyncify, currentUser, schema, alreadySyncedRealms) {
|
|
3231
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3232
|
+
var ignoredRealms_1, inserts;
|
|
3233
|
+
var _this_1 = this;
|
|
3234
|
+
return __generator(this, function (_g) {
|
|
3235
|
+
switch (_g.label) {
|
|
3236
|
+
case 0:
|
|
3237
|
+
if (!currentUser.isLoggedIn) return [3 /*break*/, 2];
|
|
3238
|
+
if (!(tablesToSyncify.length > 0)) return [3 /*break*/, 2];
|
|
3239
|
+
ignoredRealms_1 = new Set(alreadySyncedRealms || []);
|
|
3240
|
+
return [4 /*yield*/, Promise.all(tablesToSyncify.map(function (table) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3241
|
+
var extractKey, dexieCloudTableSchema, query, unsyncedObjects, mut;
|
|
3242
|
+
return __generator(this, function (_g) {
|
|
3243
|
+
switch (_g.label) {
|
|
3244
|
+
case 0:
|
|
3245
|
+
extractKey = table.core.schema.primaryKey.extractKey;
|
|
3246
|
+
if (!extractKey)
|
|
3247
|
+
return [2 /*return*/, { table: table.name, muts: [] }]; // Outbound tables are not synced.
|
|
3248
|
+
dexieCloudTableSchema = schema[table.name];
|
|
3249
|
+
query = (dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.generatedGlobalId)
|
|
3250
|
+
? table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidSyncableID(extractKey(item)); })
|
|
3251
|
+
: table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidAtID(extractKey(item), dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.idPrefix); });
|
|
3252
|
+
return [4 /*yield*/, query.toArray()];
|
|
3253
|
+
case 1:
|
|
3254
|
+
unsyncedObjects = _g.sent();
|
|
3255
|
+
if (unsyncedObjects.length > 0) {
|
|
3256
|
+
mut = {
|
|
3257
|
+
type: "insert",
|
|
3258
|
+
values: unsyncedObjects,
|
|
3259
|
+
keys: unsyncedObjects.map(extractKey),
|
|
3260
|
+
userId: currentUser.userId,
|
|
3261
|
+
};
|
|
3262
|
+
return [2 /*return*/, {
|
|
3263
|
+
table: table.name,
|
|
3264
|
+
muts: [mut],
|
|
3265
|
+
}];
|
|
3266
|
+
}
|
|
3267
|
+
else {
|
|
3268
|
+
return [2 /*return*/, {
|
|
3269
|
+
table: table.name,
|
|
3270
|
+
muts: []
|
|
3271
|
+
}];
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
});
|
|
3275
|
+
}); }))];
|
|
3276
|
+
case 1:
|
|
3277
|
+
inserts = _g.sent();
|
|
3278
|
+
return [2 /*return*/, inserts.filter(function (op) { return op.muts.length > 0; })];
|
|
3279
|
+
case 2: return [2 /*return*/, []];
|
|
3280
|
+
}
|
|
3281
|
+
});
|
|
3282
|
+
});
|
|
3283
|
+
}
|
|
3284
|
+
function getTablesToSyncify(db, syncState) {
|
|
3285
|
+
var syncedTables = (syncState === null || syncState === void 0 ? void 0 : syncState.syncedTables) || [];
|
|
3286
|
+
var syncableTables = getSyncableTables(db);
|
|
3287
|
+
var tablesToSyncify = syncableTables.filter(function (tbl) { return !syncedTables.includes(tbl.name); });
|
|
3288
|
+
return tablesToSyncify;
|
|
3289
|
+
}
|
|
3145
3290
|
var toStr = {}.toString;
|
|
3146
3291
|
function getToStringTag(val) {
|
|
3147
3292
|
return toStr.call(val).slice(8, -1);
|
|
@@ -3661,22 +3806,6 @@
|
|
|
3661
3806
|
// else
|
|
3662
3807
|
// serverRev.rev = new FakeBigInt(server.rev)
|
|
3663
3808
|
var hasBigIntSupport = typeof BigInt(0) === 'bigint';
|
|
3664
|
-
function getValueOfBigInt(x) {
|
|
3665
|
-
if (typeof x === 'bigint') {
|
|
3666
|
-
return x;
|
|
3667
|
-
}
|
|
3668
|
-
if (hasBigIntSupport) {
|
|
3669
|
-
return typeof x === 'string' ? BigInt(x) : BigInt(x.v);
|
|
3670
|
-
}
|
|
3671
|
-
else {
|
|
3672
|
-
return typeof x === 'string' ? Number(x) : Number(x.v);
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3675
|
-
function compareBigInts(a, b) {
|
|
3676
|
-
var valA = getValueOfBigInt(a);
|
|
3677
|
-
var valB = getValueOfBigInt(b);
|
|
3678
|
-
return valA < valB ? -1 : valA > valB ? 1 : 0;
|
|
3679
|
-
}
|
|
3680
3809
|
var FakeBigInt = /** @class */ (function () {
|
|
3681
3810
|
function FakeBigInt(value) {
|
|
3682
3811
|
this.v = value;
|
|
@@ -3702,151 +3831,6 @@
|
|
|
3702
3831
|
}));
|
|
3703
3832
|
var TSON = TypesonSimplified(builtin, defs);
|
|
3704
3833
|
var BISON = Bison(defs);
|
|
3705
|
-
function computeRealmSetHash(_g) {
|
|
3706
|
-
var realms = _g.realms, inviteRealms = _g.inviteRealms;
|
|
3707
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3708
|
-
var data, byteArray, digestBytes, base64;
|
|
3709
|
-
return __generator(this, function (_h) {
|
|
3710
|
-
switch (_h.label) {
|
|
3711
|
-
case 0:
|
|
3712
|
-
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; }));
|
|
3713
|
-
byteArray = new TextEncoder().encode(data);
|
|
3714
|
-
return [4 /*yield*/, crypto.subtle.digest('SHA-1', byteArray)];
|
|
3715
|
-
case 1:
|
|
3716
|
-
digestBytes = _h.sent();
|
|
3717
|
-
base64 = b64encode(digestBytes);
|
|
3718
|
-
return [2 /*return*/, base64];
|
|
3719
|
-
}
|
|
3720
|
-
});
|
|
3721
|
-
});
|
|
3722
|
-
}
|
|
3723
|
-
function getSyncableTables(db) {
|
|
3724
|
-
return Object.entries(db.cloud.schema || {})
|
|
3725
|
-
.filter(function (_g) {
|
|
3726
|
-
var markedForSync = _g[1].markedForSync;
|
|
3727
|
-
return markedForSync;
|
|
3728
|
-
})
|
|
3729
|
-
.map(function (_g) {
|
|
3730
|
-
var tbl = _g[0];
|
|
3731
|
-
return db.table(tbl);
|
|
3732
|
-
});
|
|
3733
|
-
}
|
|
3734
|
-
function getMutationTable(tableName) {
|
|
3735
|
-
return "$" + tableName + "_mutations";
|
|
3736
|
-
}
|
|
3737
|
-
function getTableFromMutationTable(mutationTable) {
|
|
3738
|
-
var _a;
|
|
3739
|
-
var tableName = (_a = /^\$(.*)_mutations$/.exec(mutationTable)) === null || _a === void 0 ? void 0 : _a[1];
|
|
3740
|
-
if (!tableName)
|
|
3741
|
-
throw new Error("Given mutationTable " + mutationTable + " is not correct");
|
|
3742
|
-
return tableName;
|
|
3743
|
-
}
|
|
3744
|
-
function listClientChanges(mutationTables, db, _g) {
|
|
3745
|
-
var _h = _g === void 0 ? {} : _g, _j = _h.since, since = _j === void 0 ? {} : _j, _k = _h.limit, limit = _k === void 0 ? Infinity : _k;
|
|
3746
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3747
|
-
var allMutsOnTables;
|
|
3748
|
-
var _this_1 = this;
|
|
3749
|
-
return __generator(this, function (_l) {
|
|
3750
|
-
switch (_l.label) {
|
|
3751
|
-
case 0: return [4 /*yield*/, Promise.all(mutationTables.map(function (mutationTable) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3752
|
-
var tableName, lastRevision, query, muts;
|
|
3753
|
-
return __generator(this, function (_g) {
|
|
3754
|
-
switch (_g.label) {
|
|
3755
|
-
case 0:
|
|
3756
|
-
tableName = getTableFromMutationTable(mutationTable.name);
|
|
3757
|
-
lastRevision = since[tableName];
|
|
3758
|
-
query = lastRevision
|
|
3759
|
-
? mutationTable.where("rev").above(lastRevision)
|
|
3760
|
-
: mutationTable;
|
|
3761
|
-
if (limit < Infinity)
|
|
3762
|
-
query = query.limit(limit);
|
|
3763
|
-
return [4 /*yield*/, query.toArray()];
|
|
3764
|
-
case 1:
|
|
3765
|
-
muts = _g.sent();
|
|
3766
|
-
//const objTable = db.table(tableName);
|
|
3767
|
-
/*for (const mut of muts) {
|
|
3768
|
-
if (mut.type === "insert" || mut.type === "upsert") {
|
|
3769
|
-
mut.values = await objTable.bulkGet(mut.keys);
|
|
3770
|
-
}
|
|
3771
|
-
}*/
|
|
3772
|
-
return [2 /*return*/, {
|
|
3773
|
-
table: tableName,
|
|
3774
|
-
muts: muts,
|
|
3775
|
-
}];
|
|
3776
|
-
}
|
|
3777
|
-
});
|
|
3778
|
-
}); }))];
|
|
3779
|
-
case 1:
|
|
3780
|
-
allMutsOnTables = _l.sent();
|
|
3781
|
-
// Filter out those tables that doesn't have any mutations:
|
|
3782
|
-
return [2 /*return*/, allMutsOnTables.filter(function (_g) {
|
|
3783
|
-
var muts = _g.muts;
|
|
3784
|
-
return muts.length > 0;
|
|
3785
|
-
})];
|
|
3786
|
-
}
|
|
3787
|
-
});
|
|
3788
|
-
});
|
|
3789
|
-
}
|
|
3790
|
-
function listSyncifiedChanges(tablesToSyncify, currentUser, schema, alreadySyncedRealms) {
|
|
3791
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3792
|
-
var ignoredRealms_1, inserts;
|
|
3793
|
-
var _this_1 = this;
|
|
3794
|
-
return __generator(this, function (_g) {
|
|
3795
|
-
switch (_g.label) {
|
|
3796
|
-
case 0:
|
|
3797
|
-
if (!currentUser.isLoggedIn) return [3 /*break*/, 2];
|
|
3798
|
-
if (!(tablesToSyncify.length > 0)) return [3 /*break*/, 2];
|
|
3799
|
-
ignoredRealms_1 = new Set(alreadySyncedRealms || []);
|
|
3800
|
-
return [4 /*yield*/, Promise.all(tablesToSyncify.map(function (table) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
3801
|
-
var extractKey, dexieCloudTableSchema, query, unsyncedObjects, mut;
|
|
3802
|
-
return __generator(this, function (_g) {
|
|
3803
|
-
switch (_g.label) {
|
|
3804
|
-
case 0:
|
|
3805
|
-
extractKey = table.core.schema.primaryKey.extractKey;
|
|
3806
|
-
if (!extractKey)
|
|
3807
|
-
return [2 /*return*/, { table: table.name, muts: [] }]; // Outbound tables are not synced.
|
|
3808
|
-
dexieCloudTableSchema = schema[table.name];
|
|
3809
|
-
query = (dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.generatedGlobalId)
|
|
3810
|
-
? table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidSyncableID(extractKey(item)); })
|
|
3811
|
-
: table.filter(function (item) { return !ignoredRealms_1.has(item.realmId || "") && isValidAtID(extractKey(item), dexieCloudTableSchema === null || dexieCloudTableSchema === void 0 ? void 0 : dexieCloudTableSchema.idPrefix); });
|
|
3812
|
-
return [4 /*yield*/, query.toArray()];
|
|
3813
|
-
case 1:
|
|
3814
|
-
unsyncedObjects = _g.sent();
|
|
3815
|
-
if (unsyncedObjects.length > 0) {
|
|
3816
|
-
mut = {
|
|
3817
|
-
type: "insert",
|
|
3818
|
-
values: unsyncedObjects,
|
|
3819
|
-
keys: unsyncedObjects.map(extractKey),
|
|
3820
|
-
userId: currentUser.userId,
|
|
3821
|
-
};
|
|
3822
|
-
return [2 /*return*/, {
|
|
3823
|
-
table: table.name,
|
|
3824
|
-
muts: [mut],
|
|
3825
|
-
}];
|
|
3826
|
-
}
|
|
3827
|
-
else {
|
|
3828
|
-
return [2 /*return*/, {
|
|
3829
|
-
table: table.name,
|
|
3830
|
-
muts: []
|
|
3831
|
-
}];
|
|
3832
|
-
}
|
|
3833
|
-
}
|
|
3834
|
-
});
|
|
3835
|
-
}); }))];
|
|
3836
|
-
case 1:
|
|
3837
|
-
inserts = _g.sent();
|
|
3838
|
-
return [2 /*return*/, inserts.filter(function (op) { return op.muts.length > 0; })];
|
|
3839
|
-
case 2: return [2 /*return*/, []];
|
|
3840
|
-
}
|
|
3841
|
-
});
|
|
3842
|
-
});
|
|
3843
|
-
}
|
|
3844
|
-
function getTablesToSyncify(db, syncState) {
|
|
3845
|
-
var syncedTables = (syncState === null || syncState === void 0 ? void 0 : syncState.syncedTables) || [];
|
|
3846
|
-
var syncableTables = getSyncableTables(db);
|
|
3847
|
-
var tablesToSyncify = syncableTables.filter(function (tbl) { return !syncedTables.includes(tbl.name); });
|
|
3848
|
-
return tablesToSyncify;
|
|
3849
|
-
}
|
|
3850
3834
|
//import {BisonWebStreamReader} from "dreambase-library/dist/typeson-simplified/BisonWebStreamReader";
|
|
3851
3835
|
function syncWithServer(changes, syncState, baseRevs, db, databaseUrl, schema, clientIdentity) {
|
|
3852
3836
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -3865,6 +3849,7 @@
|
|
|
3865
3849
|
headers.Authorization = "Bearer " + accessToken;
|
|
3866
3850
|
}
|
|
3867
3851
|
syncRequest = {
|
|
3852
|
+
v: 2,
|
|
3868
3853
|
dbID: syncState === null || syncState === void 0 ? void 0 : syncState.remoteDbId,
|
|
3869
3854
|
clientIdentity: clientIdentity,
|
|
3870
3855
|
schema: schema || {},
|
|
@@ -4046,8 +4031,8 @@
|
|
|
4046
4031
|
if (lastRevisions === void 0) { lastRevisions = {}; }
|
|
4047
4032
|
for (var _g = 0, clientChangeSet_1 = clientChangeSet; _g < clientChangeSet_1.length; _g++) {
|
|
4048
4033
|
var _h = clientChangeSet_1[_g], table = _h.table, muts = _h.muts;
|
|
4049
|
-
var lastRev = muts.length > 0 ? muts[muts.length - 1].rev
|
|
4050
|
-
lastRevisions[table] = lastRev;
|
|
4034
|
+
var lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;
|
|
4035
|
+
lastRevisions[table] = lastRev || lastRevisions[table] || 0;
|
|
4051
4036
|
}
|
|
4052
4037
|
return lastRevisions;
|
|
4053
4038
|
}
|
|
@@ -4552,27 +4537,49 @@
|
|
|
4552
4537
|
var readyToServe = new rxjs.BehaviorSubject(true);
|
|
4553
4538
|
var event = new rxjs.BehaviorSubject(null);
|
|
4554
4539
|
var isWorking = false;
|
|
4540
|
+
var loopWarning = 0;
|
|
4541
|
+
var loopDetection = [0, 0, 0, 0, 0, 0, 0, 0, 0, Date.now()];
|
|
4555
4542
|
event.subscribe(function () { return __awaiter(_this_1, void 0, void 0, function () {
|
|
4556
4543
|
return __generator(this, function (_g) {
|
|
4557
4544
|
switch (_g.label) {
|
|
4558
4545
|
case 0:
|
|
4559
4546
|
if (isWorking)
|
|
4560
4547
|
return [2 /*return*/];
|
|
4561
|
-
if (!(queue.length > 0)) return [3 /*break*/,
|
|
4548
|
+
if (!(queue.length > 0)) return [3 /*break*/, 8];
|
|
4562
4549
|
isWorking = true;
|
|
4550
|
+
loopDetection.shift();
|
|
4551
|
+
loopDetection.push(Date.now());
|
|
4563
4552
|
readyToServe.next(false);
|
|
4564
4553
|
_g.label = 1;
|
|
4565
4554
|
case 1:
|
|
4566
|
-
_g.trys.push([1, , 3,
|
|
4555
|
+
_g.trys.push([1, , 3, 8]);
|
|
4567
4556
|
return [4 /*yield*/, consumeQueue()];
|
|
4568
4557
|
case 2:
|
|
4569
4558
|
_g.sent();
|
|
4570
|
-
return [3 /*break*/,
|
|
4559
|
+
return [3 /*break*/, 8];
|
|
4571
4560
|
case 3:
|
|
4561
|
+
if (!(loopDetection[loopDetection.length - 1] - loopDetection[0] < 10000)) return [3 /*break*/, 7];
|
|
4562
|
+
if (!(Date.now() - loopWarning < 5000)) return [3 /*break*/, 5];
|
|
4563
|
+
// Last time we did this, we ended up here too. Wait for a minute.
|
|
4564
|
+
console.warn("Slowing down websocket loop for one minute");
|
|
4565
|
+
loopWarning = Date.now() + 60000;
|
|
4566
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 60000); })];
|
|
4567
|
+
case 4:
|
|
4568
|
+
_g.sent();
|
|
4569
|
+
return [3 /*break*/, 7];
|
|
4570
|
+
case 5:
|
|
4571
|
+
// This is a one-time event. Just pause 10 seconds.
|
|
4572
|
+
console.warn("Slowing down websocket loop for 10 seconds");
|
|
4573
|
+
loopWarning = Date.now() + 10000;
|
|
4574
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 10000); })];
|
|
4575
|
+
case 6:
|
|
4576
|
+
_g.sent();
|
|
4577
|
+
_g.label = 7;
|
|
4578
|
+
case 7:
|
|
4572
4579
|
isWorking = false;
|
|
4573
4580
|
readyToServe.next(true);
|
|
4574
4581
|
return [7 /*endfinally*/];
|
|
4575
|
-
case
|
|
4582
|
+
case 8: return [2 /*return*/];
|
|
4576
4583
|
}
|
|
4577
4584
|
});
|
|
4578
4585
|
}); });
|
|
@@ -4597,6 +4604,9 @@
|
|
|
4597
4604
|
case 1:
|
|
4598
4605
|
_j.trys.push([1, 12, , 13]);
|
|
4599
4606
|
console.debug('processing msg', msg);
|
|
4607
|
+
// If the sync worker or service worker is syncing, wait 'til thei're done.
|
|
4608
|
+
// It's no need to have two channels at the same time - even though it wouldnt
|
|
4609
|
+
// be a problem - this is an optimization.
|
|
4600
4610
|
return [4 /*yield*/, db.cloud.syncState
|
|
4601
4611
|
.pipe(filter(function (_g) {
|
|
4602
4612
|
var phase = _g.phase;
|
|
@@ -4604,6 +4614,9 @@
|
|
|
4604
4614
|
}), take(1))
|
|
4605
4615
|
.toPromise()];
|
|
4606
4616
|
case 2:
|
|
4617
|
+
// If the sync worker or service worker is syncing, wait 'til thei're done.
|
|
4618
|
+
// It's no need to have two channels at the same time - even though it wouldnt
|
|
4619
|
+
// be a problem - this is an optimization.
|
|
4607
4620
|
_j.sent();
|
|
4608
4621
|
console.debug('processing msg', msg);
|
|
4609
4622
|
persistedSyncState = db.cloud.persistedSyncState.value;
|
|
@@ -4613,9 +4626,9 @@
|
|
|
4613
4626
|
_h = msg.type;
|
|
4614
4627
|
switch (_h) {
|
|
4615
4628
|
case 'token-expired': return [3 /*break*/, 3];
|
|
4616
|
-
case '
|
|
4617
|
-
case 'realm-
|
|
4618
|
-
case '
|
|
4629
|
+
case 'realm-added': return [3 /*break*/, 6];
|
|
4630
|
+
case 'realm-removed': return [3 /*break*/, 7];
|
|
4631
|
+
case 'realms-changed': return [3 /*break*/, 8];
|
|
4619
4632
|
case 'changes': return [3 /*break*/, 9];
|
|
4620
4633
|
}
|
|
4621
4634
|
return [3 /*break*/, 11];
|
|
@@ -4638,25 +4651,22 @@
|
|
|
4638
4651
|
// new token. So we don't need to do anything more here.
|
|
4639
4652
|
return [3 /*break*/, 11];
|
|
4640
4653
|
case 6:
|
|
4641
|
-
if (!(persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.
|
|
4642
|
-
|
|
4643
|
-
triggerSync(db, "pull");
|
|
4654
|
+
if (!((_a = persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms) === null || _a === void 0 ? void 0 : _a.includes(msg.realm))) {
|
|
4655
|
+
triggerSync(db, 'pull');
|
|
4644
4656
|
}
|
|
4645
4657
|
return [3 /*break*/, 11];
|
|
4646
4658
|
case 7:
|
|
4647
|
-
if (
|
|
4648
|
-
triggerSync(db,
|
|
4659
|
+
if ((_b = persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms) === null || _b === void 0 ? void 0 : _b.includes(msg.realm)) {
|
|
4660
|
+
triggerSync(db, 'pull');
|
|
4649
4661
|
}
|
|
4650
4662
|
return [3 /*break*/, 11];
|
|
4651
4663
|
case 8:
|
|
4652
|
-
|
|
4653
|
-
triggerSync(db, "pull");
|
|
4654
|
-
}
|
|
4664
|
+
triggerSync(db, 'pull');
|
|
4655
4665
|
return [3 /*break*/, 11];
|
|
4656
4666
|
case 9:
|
|
4657
4667
|
console.debug('changes');
|
|
4658
4668
|
if (((_c = db.cloud.syncState.value) === null || _c === void 0 ? void 0 : _c.phase) === 'error') {
|
|
4659
|
-
triggerSync(db,
|
|
4669
|
+
triggerSync(db, 'pull');
|
|
4660
4670
|
return [3 /*break*/, 11];
|
|
4661
4671
|
}
|
|
4662
4672
|
return [4 /*yield*/, db.transaction('rw', db.dx.tables, function (tx) { return __awaiter(_this_1, void 0, void 0, function () {
|
|
@@ -4685,17 +4695,35 @@
|
|
|
4685
4695
|
return [2 /*return*/]; // Initial sync must have taken place - otherwise, ignore this.
|
|
4686
4696
|
}
|
|
4687
4697
|
// Verify again in ACID tx that we're on same server revision.
|
|
4688
|
-
if (
|
|
4698
|
+
if (msg.baseRev !== syncState.serverRevision) {
|
|
4689
4699
|
console.debug("baseRev (" + msg.baseRev + ") differs from our serverRevision in syncState (" + syncState.serverRevision + ")");
|
|
4700
|
+
// Should we trigger a sync now? No. This is a normal case
|
|
4701
|
+
// when another local peer (such as the SW or a websocket channel on other tab) has
|
|
4702
|
+
// updated syncState from new server information but we are not aware yet. It would
|
|
4703
|
+
// be unnescessary to do a sync in that case. Instead, the caller of this consumeQueue()
|
|
4704
|
+
// function will do readyToServe.next(true) right after this return, which will lead
|
|
4705
|
+
// to a "ready" message being sent to server with the new accurate serverRev we have,
|
|
4706
|
+
// so that the next message indeed will be correct.
|
|
4707
|
+
if (typeof msg.baseRev === 'string' && // v2 format
|
|
4708
|
+
(typeof syncState.serverRevision === 'bigint' || // v1 format
|
|
4709
|
+
typeof syncState.serverRevision === 'object') // v1 format old browser
|
|
4710
|
+
) {
|
|
4711
|
+
// The reason for the diff seems to be that server has migrated the revision format.
|
|
4712
|
+
// Do a full sync to update revision format.
|
|
4713
|
+
// If we don't do a sync request now, we could stuck in an endless loop.
|
|
4714
|
+
triggerSync(db, 'pull');
|
|
4715
|
+
}
|
|
4690
4716
|
return [2 /*return*/]; // Ignore message
|
|
4691
4717
|
}
|
|
4692
|
-
return [4 /*yield*/, Dexie__default['default'].waitFor(
|
|
4718
|
+
return [4 /*yield*/, Dexie__default['default'].waitFor(
|
|
4719
|
+
// Keep TX in non-IDB work
|
|
4720
|
+
computeRealmSetHash(syncState))];
|
|
4693
4721
|
case 2:
|
|
4694
4722
|
ourRealmSetHash = _h.sent();
|
|
4695
4723
|
console.debug('ourRealmSetHash', ourRealmSetHash);
|
|
4696
4724
|
if (ourRealmSetHash !== msg.realmSetHash) {
|
|
4697
4725
|
console.debug('not same realmSetHash', msg.realmSetHash);
|
|
4698
|
-
triggerSync(db,
|
|
4726
|
+
triggerSync(db, 'pull');
|
|
4699
4727
|
// The message isn't based on the same realms.
|
|
4700
4728
|
// Trigger a sync instead to resolve all things up.
|
|
4701
4729
|
return [2 /*return*/];
|
|
@@ -4709,6 +4737,7 @@
|
|
|
4709
4737
|
console.debug('msg queue: client changes', clientChanges);
|
|
4710
4738
|
_h.label = 4;
|
|
4711
4739
|
case 4:
|
|
4740
|
+
if (!(msg.changes.length > 0)) return [3 /*break*/, 6];
|
|
4712
4741
|
filteredChanges = filterServerChangesThroughAddedClientChanges(msg.changes, clientChanges);
|
|
4713
4742
|
//
|
|
4714
4743
|
// apply server changes
|
|
@@ -4717,6 +4746,8 @@
|
|
|
4717
4746
|
return [4 /*yield*/, applyServerChanges(filteredChanges, db)];
|
|
4718
4747
|
case 5:
|
|
4719
4748
|
_h.sent();
|
|
4749
|
+
_h.label = 6;
|
|
4750
|
+
case 6:
|
|
4720
4751
|
// Update latest revisions per table in case there are unsynced changes
|
|
4721
4752
|
// This can be a real case in future when we allow non-eagery sync.
|
|
4722
4753
|
// And it can actually be realistic now also, but very rare.
|
|
@@ -4725,14 +4756,14 @@
|
|
|
4725
4756
|
// Update base revs
|
|
4726
4757
|
console.debug('Updating baseRefs', syncState.latestRevisions);
|
|
4727
4758
|
return [4 /*yield*/, updateBaseRevs(db, schema, syncState.latestRevisions, msg.newRev)];
|
|
4728
|
-
case
|
|
4759
|
+
case 7:
|
|
4729
4760
|
_h.sent();
|
|
4730
4761
|
//
|
|
4731
4762
|
// Update syncState
|
|
4732
4763
|
//
|
|
4733
4764
|
console.debug('Updating syncState', syncState);
|
|
4734
4765
|
return [4 /*yield*/, db.$syncState.put(syncState, 'syncState')];
|
|
4735
|
-
case
|
|
4766
|
+
case 8:
|
|
4736
4767
|
_h.sent();
|
|
4737
4768
|
return [2 /*return*/];
|
|
4738
4769
|
}
|
|
@@ -5619,20 +5650,21 @@
|
|
|
5619
5650
|
var FAIL_RETRY_WAIT_TIME = 60000;
|
|
5620
5651
|
var WSObservable = /** @class */ (function (_super_1) {
|
|
5621
5652
|
__extends$1(WSObservable, _super_1);
|
|
5622
|
-
function WSObservable(databaseUrl, rev, clientIdentity, messageProducer, webSocketStatus, token, tokenExpiration) {
|
|
5623
|
-
return _super_1.call(this, function (subscriber) { return new WSConnection(databaseUrl, rev, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus); }) || this;
|
|
5653
|
+
function WSObservable(databaseUrl, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus, token, tokenExpiration) {
|
|
5654
|
+
return _super_1.call(this, function (subscriber) { return new WSConnection(databaseUrl, rev, realmSetHash, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus); }) || this;
|
|
5624
5655
|
}
|
|
5625
5656
|
return WSObservable;
|
|
5626
5657
|
}(rxjs.Observable));
|
|
5627
5658
|
var counter = 0;
|
|
5628
5659
|
var WSConnection = /** @class */ (function (_super_1) {
|
|
5629
5660
|
__extends$1(WSConnection, _super_1);
|
|
5630
|
-
function WSConnection(databaseUrl, rev, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus) {
|
|
5661
|
+
function WSConnection(databaseUrl, rev, realmSetHash, clientIdentity, token, tokenExpiration, subscriber, messageProducer, webSocketStatus) {
|
|
5631
5662
|
var _this_1 = _super_1.call(this, function () { return _this_1.teardown(); }) || this;
|
|
5632
5663
|
_this_1.id = ++counter;
|
|
5633
5664
|
console.debug('New WebSocket Connection', _this_1.id, token ? 'authorized' : 'unauthorized');
|
|
5634
5665
|
_this_1.databaseUrl = databaseUrl;
|
|
5635
5666
|
_this_1.rev = rev;
|
|
5667
|
+
_this_1.realmSetHash = realmSetHash;
|
|
5636
5668
|
_this_1.clientIdentity = clientIdentity;
|
|
5637
5669
|
_this_1.token = token;
|
|
5638
5670
|
_this_1.tokenExpiration = tokenExpiration;
|
|
@@ -5747,7 +5779,9 @@
|
|
|
5747
5779
|
searchParams = new URLSearchParams();
|
|
5748
5780
|
if (this.subscriber.closed)
|
|
5749
5781
|
return [2 /*return*/];
|
|
5782
|
+
searchParams.set('v', "2");
|
|
5750
5783
|
searchParams.set('rev', this.rev);
|
|
5784
|
+
searchParams.set('realmsHash', this.realmSetHash);
|
|
5751
5785
|
searchParams.set('clientId', this.clientIdentity);
|
|
5752
5786
|
if (this.token) {
|
|
5753
5787
|
searchParams.set('token', this.token);
|
|
@@ -5864,12 +5898,26 @@
|
|
|
5864
5898
|
var _this_1 = this;
|
|
5865
5899
|
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.
|
|
5866
5900
|
take(1), // Don't continue waking up whenever syncState change
|
|
5867
|
-
switchMap(function () { return db.cloud.currentUser
|
|
5901
|
+
switchMap(function (syncState) { return db.cloud.currentUser.pipe(map(function (userLogin) { return [userLogin, syncState]; })); }), switchMap(function (_g) {
|
|
5902
|
+
var userLogin = _g[0], syncState = _g[1];
|
|
5903
|
+
return userIsReallyActive.pipe(map(function (isActive) { return [isActive ? userLogin : null, syncState]; }));
|
|
5904
|
+
}), switchMap(function (_g) {
|
|
5905
|
+
var userLogin = _g[0], syncState = _g[1];
|
|
5906
|
+
return __awaiter(_this_1, void 0, void 0, function () { var _h; return __generator(this, function (_j) {
|
|
5907
|
+
switch (_j.label) {
|
|
5908
|
+
case 0:
|
|
5909
|
+
_h = [userLogin];
|
|
5910
|
+
return [4 /*yield*/, computeRealmSetHash(syncState)];
|
|
5911
|
+
case 1: return [2 /*return*/, _h.concat([_j.sent()])];
|
|
5912
|
+
}
|
|
5913
|
+
}); });
|
|
5914
|
+
}), switchMap(function (_g) {
|
|
5915
|
+
var userLogin = _g[0], realmSetHash = _g[1];
|
|
5868
5916
|
// Let server end query changes from last entry of same client-ID and forward.
|
|
5869
5917
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
5870
5918
|
// and the baseRev of the last from same client-ID.
|
|
5871
5919
|
return userLogin
|
|
5872
|
-
? new WSObservable(db.cloud.options.databaseUrl, db.cloud.persistedSyncState.value.serverRevision, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin.accessToken, userLogin.accessTokenExpiration)
|
|
5920
|
+
? 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)
|
|
5873
5921
|
: rxjs.from([]);
|
|
5874
5922
|
}), catchError(function (error) {
|
|
5875
5923
|
if ((error === null || error === void 0 ? void 0 : error.name) === 'TokenExpiredError') {
|
|
@@ -6025,22 +6073,26 @@
|
|
|
6025
6073
|
var cancelToken = { cancelled: false };
|
|
6026
6074
|
function syncAndRetry(purpose, retryNum) {
|
|
6027
6075
|
if (retryNum === void 0) { retryNum = 1; }
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6076
|
+
// Use setTimeout() to get onto a clean stack and
|
|
6077
|
+
// break free from possible active transaction:
|
|
6078
|
+
setTimeout(function () {
|
|
6079
|
+
syncIfPossible(db, cloudOptions, cloudSchema, {
|
|
6080
|
+
cancelToken: cancelToken,
|
|
6081
|
+
retryImmediatelyOnFetchError: true,
|
|
6082
|
+
purpose: purpose,
|
|
6083
|
+
}).catch(function (e) {
|
|
6084
|
+
console.error('error in syncIfPossible()', e);
|
|
6085
|
+
if (cancelToken.cancelled) {
|
|
6086
|
+
stop();
|
|
6087
|
+
}
|
|
6088
|
+
else if (retryNum < 3) {
|
|
6089
|
+
// Mimic service worker sync event: retry 3 times
|
|
6090
|
+
// * first retry after 5 minutes
|
|
6091
|
+
// * second retry 15 minutes later
|
|
6092
|
+
setTimeout(function () { return syncAndRetry(purpose, retryNum + 1); }, [0, 5, 15][retryNum] * MINUTES);
|
|
6093
|
+
}
|
|
6094
|
+
});
|
|
6095
|
+
}, 0);
|
|
6044
6096
|
}
|
|
6045
6097
|
var start = function () {
|
|
6046
6098
|
// Sync eagerly whenever a change has happened (+ initially when there's no syncState yet)
|
|
@@ -6049,7 +6101,7 @@
|
|
|
6049
6101
|
localSyncEventSubscription = db.localSyncEvent.subscribe(function (_g) {
|
|
6050
6102
|
var purpose = _g.purpose;
|
|
6051
6103
|
try {
|
|
6052
|
-
syncAndRetry(purpose ||
|
|
6104
|
+
syncAndRetry(purpose || 'pull');
|
|
6053
6105
|
}
|
|
6054
6106
|
catch (err) {
|
|
6055
6107
|
console.error('What-the....', err);
|