dexie-cloud-addon 4.1.0-alpha.2 → 4.1.0-alpha.5
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/WSObservable.d.ts +4 -4
- package/dist/modern/dexie-cloud-addon.js +73 -46
- 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 +73 -46
- 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/modern/yjs/listYClientMessagesAndStateVector.d.ts +3 -1
- package/dist/umd/WSObservable.d.ts +4 -4
- package/dist/umd/dexie-cloud-addon.js +73 -46
- 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 +73 -46
- 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/yjs/listYClientMessagesAndStateVector.d.ts +3 -1
- package/package.json +2 -2
- package/dist/modern/yjs/listYClientMessages.d.ts +0 -3
- package/dist/umd/yjs/listYClientMessages.d.ts +0 -3
- /package/dist/modern/yjs/{y.d.ts → Y.d.ts} +0 -0
- /package/dist/umd/yjs/{y.d.ts → Y.d.ts} +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.1.0-alpha.
|
|
11
|
+
* Version 4.1.0-alpha.5, Mon Oct 14 2024
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -4661,13 +4661,12 @@ function $Y(db) {
|
|
|
4661
4661
|
* @param db
|
|
4662
4662
|
* @returns
|
|
4663
4663
|
*/
|
|
4664
|
-
function listYClientMessagesAndStateVector(db) {
|
|
4665
|
-
var _a;
|
|
4664
|
+
function listYClientMessagesAndStateVector(db, tablesToSync) {
|
|
4666
4665
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4667
4666
|
const result = [];
|
|
4668
4667
|
const lastUpdateIds = {};
|
|
4669
|
-
for (const table of
|
|
4670
|
-
if (table.schema.yProps
|
|
4668
|
+
for (const table of tablesToSync) {
|
|
4669
|
+
if (table.schema.yProps) {
|
|
4671
4670
|
for (const yProp of table.schema.yProps) {
|
|
4672
4671
|
const Y = $Y(db); // This is how we retrieve the user-provided Y library
|
|
4673
4672
|
const yTable = db.table(yProp.updatesTable); // the updates-table for this combo of table+propName
|
|
@@ -4801,7 +4800,7 @@ function applyYServerMessages(yMessages, db) {
|
|
|
4801
4800
|
}
|
|
4802
4801
|
|
|
4803
4802
|
function updateYSyncStates(lastUpdateIdsBeforeSync, receivedUntilsAfterSync, db, serverRevision) {
|
|
4804
|
-
var _a, _b;
|
|
4803
|
+
var _a, _b, _c, _d, _e;
|
|
4805
4804
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4806
4805
|
// We want to update unsentFrom for each yTable to the value specified in first argument
|
|
4807
4806
|
// because we got those values before we synced with server and here we are back from server
|
|
@@ -4809,7 +4808,7 @@ function updateYSyncStates(lastUpdateIdsBeforeSync, receivedUntilsAfterSync, db,
|
|
|
4809
4808
|
// we can safely store unsentFrom to a value of the last update + 1 here.
|
|
4810
4809
|
// We also want to update receivedUntil for each yTable to the value specified in the second argument,
|
|
4811
4810
|
// because that contains the highest resulted id of each update from server after storing it.
|
|
4812
|
-
// We could do these two tasks separately, but that would require two update calls on the same YSyncState, so
|
|
4811
|
+
// We could do these two tasks separately, but that would require two update calls on the same YSyncState, so
|
|
4813
4812
|
// to optimize the dexie calls, we merge these two maps into a single one so we can do a single update request
|
|
4814
4813
|
// per yTable.
|
|
4815
4814
|
const mergedSpec = {};
|
|
@@ -4821,28 +4820,42 @@ function updateYSyncStates(lastUpdateIdsBeforeSync, receivedUntilsAfterSync, db,
|
|
|
4821
4820
|
(_b = mergedSpec[yTable]) !== null && _b !== void 0 ? _b : (mergedSpec[yTable] = {});
|
|
4822
4821
|
mergedSpec[yTable].receivedUntil = lastUpdateId;
|
|
4823
4822
|
}
|
|
4824
|
-
// Now go through
|
|
4825
|
-
|
|
4823
|
+
// Now go through all yTables and update their YSyncStates:
|
|
4824
|
+
const allYTables = Object.values(db.dx._dbSchema)
|
|
4825
|
+
.filter((tblSchema) => tblSchema.yProps)
|
|
4826
|
+
.map((tblSchema) => tblSchema.yProps.map((yProp) => yProp.updatesTable))
|
|
4827
|
+
.flat();
|
|
4828
|
+
for (const yTable of allYTables) {
|
|
4829
|
+
const mergedEntry = mergedSpec[yTable];
|
|
4830
|
+
const unsentFrom = (_c = mergedEntry === null || mergedEntry === void 0 ? void 0 : mergedEntry.unsentFrom) !== null && _c !== void 0 ? _c : 1;
|
|
4831
|
+
const receivedUntil = (_e = (_d = mergedEntry === null || mergedEntry === void 0 ? void 0 : mergedEntry.receivedUntil) !== null && _d !== void 0 ? _d :
|
|
4832
|
+
// from local because we are in the same parent transaction (in sync.ts) that
|
|
4833
|
+
// applied all updates from the server
|
|
4834
|
+
(yield db
|
|
4835
|
+
.table(yTable)
|
|
4836
|
+
.where('i')
|
|
4837
|
+
.between(1, Infinity) // Because i might be string DEXIE_CLOUD_SYNCER_ID if not a number.
|
|
4838
|
+
.reverse()
|
|
4839
|
+
.limit(1)
|
|
4840
|
+
.primaryKeys())[0]) !== null && _e !== void 0 ? _e : 0;
|
|
4826
4841
|
// We're already in a transaction, but for the sake of
|
|
4827
4842
|
// code readability and correctness, let's launch an atomic sub transaction:
|
|
4828
4843
|
yield db.transaction('rw', yTable, () => __awaiter(this, void 0, void 0, function* () {
|
|
4829
|
-
const state = yield db
|
|
4844
|
+
const state = yield db
|
|
4845
|
+
.table(yTable)
|
|
4846
|
+
.get(DEXIE_CLOUD_SYNCER_ID);
|
|
4830
4847
|
if (!state) {
|
|
4831
4848
|
yield db.table(yTable).add({
|
|
4832
4849
|
i: DEXIE_CLOUD_SYNCER_ID,
|
|
4833
|
-
unsentFrom
|
|
4834
|
-
receivedUntil
|
|
4850
|
+
unsentFrom,
|
|
4851
|
+
receivedUntil,
|
|
4835
4852
|
serverRev: serverRevision,
|
|
4836
4853
|
});
|
|
4837
4854
|
}
|
|
4838
4855
|
else {
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
if (receivedUntil) {
|
|
4843
|
-
state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);
|
|
4844
|
-
state.serverRev = serverRevision;
|
|
4845
|
-
}
|
|
4856
|
+
state.unsentFrom = Math.max(unsentFrom, state.unsentFrom || 1);
|
|
4857
|
+
state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);
|
|
4858
|
+
state.serverRev = serverRevision;
|
|
4846
4859
|
yield db.table(yTable).put(state);
|
|
4847
4860
|
}
|
|
4848
4861
|
}));
|
|
@@ -4855,7 +4868,9 @@ const BINSTREAM_TYPE_TABLE_AND_PROP = 2;
|
|
|
4855
4868
|
const BINSTREAM_TYPE_DOCUMENT = 3;
|
|
4856
4869
|
function downloadYDocsFromServer(db, databaseUrl, { yDownloadedRealms, realms }) {
|
|
4857
4870
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4858
|
-
if (yDownloadedRealms &&
|
|
4871
|
+
if (yDownloadedRealms &&
|
|
4872
|
+
realms &&
|
|
4873
|
+
realms.every((realmId) => yDownloadedRealms[realmId] === '*')) {
|
|
4859
4874
|
return; // Already done!
|
|
4860
4875
|
}
|
|
4861
4876
|
console.debug('Downloading Y.Docs from added realms');
|
|
@@ -4895,16 +4910,19 @@ function downloadYDocsFromServer(db, databaseUrl, { yDownloadedRealms, realms })
|
|
|
4895
4910
|
yield yTable.bulkAdd(docsToInsert);
|
|
4896
4911
|
docsToInsert = [];
|
|
4897
4912
|
}
|
|
4898
|
-
if (currentRealmId &&
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4913
|
+
if (currentRealmId &&
|
|
4914
|
+
((currentTable && currentProp && lastDoc) || completedRealm)) {
|
|
4915
|
+
yield db.$syncState.update('syncState', (syncState) => {
|
|
4916
|
+
const yDownloadedRealms = syncState.yDownloadedRealms || {};
|
|
4917
|
+
yDownloadedRealms[currentRealmId] = completedRealm
|
|
4918
|
+
? '*'
|
|
4919
|
+
: {
|
|
4903
4920
|
tbl: currentTable,
|
|
4904
4921
|
prop: currentProp,
|
|
4905
4922
|
key: lastDoc.k,
|
|
4906
|
-
}
|
|
4907
|
-
|
|
4923
|
+
};
|
|
4924
|
+
syncState.yDownloadedRealms = yDownloadedRealms;
|
|
4925
|
+
});
|
|
4908
4926
|
}
|
|
4909
4927
|
});
|
|
4910
4928
|
}
|
|
@@ -5054,7 +5072,7 @@ function _sync(db, options, schema, { isInitialSync, cancelToken, justCheckIfNee
|
|
|
5054
5072
|
const syncState = yield db.getPersistedSyncState();
|
|
5055
5073
|
const baseRevs = yield db.$baseRevs.toArray();
|
|
5056
5074
|
let clientChanges = yield listClientChanges(mutationTables);
|
|
5057
|
-
const yResults = yield listYClientMessagesAndStateVector(db);
|
|
5075
|
+
const yResults = yield listYClientMessagesAndStateVector(db, tablesToSync);
|
|
5058
5076
|
throwIfCancelled(cancelToken);
|
|
5059
5077
|
if (doSyncify) {
|
|
5060
5078
|
const alreadySyncedRealms = [
|
|
@@ -6613,7 +6631,7 @@ class TokenExpiredError extends Error {
|
|
|
6613
6631
|
|
|
6614
6632
|
function createYClientUpdateObservable(db) {
|
|
6615
6633
|
const yTableRecords = flatten(db.tables
|
|
6616
|
-
.filter((table) => { var _a; return ((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[table.name].markedForSync) && table.schema.yProps; })
|
|
6634
|
+
.filter((table) => { var _a, _b; return ((_b = (_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[table.name]) === null || _b === void 0 ? void 0 : _b.markedForSync) && table.schema.yProps; })
|
|
6617
6635
|
.map((table) => table.schema.yProps.map((p) => ({
|
|
6618
6636
|
table: table.name,
|
|
6619
6637
|
ydocProp: p.prop,
|
|
@@ -6644,7 +6662,12 @@ function createYClientUpdateObservable(db) {
|
|
|
6644
6662
|
};
|
|
6645
6663
|
});
|
|
6646
6664
|
}));
|
|
6647
|
-
})).pipe(
|
|
6665
|
+
})).pipe(
|
|
6666
|
+
// Flatten the array of messages.
|
|
6667
|
+
// If messageProducer emits empty array, nothing is emitted
|
|
6668
|
+
// but if messageProducer emits array of messages, they are
|
|
6669
|
+
// emitted one by one.
|
|
6670
|
+
mergeMap$1((messages) => messages));
|
|
6648
6671
|
}
|
|
6649
6672
|
|
|
6650
6673
|
function getAwarenessLibrary(db) {
|
|
@@ -6661,25 +6684,24 @@ const SERVER_PING_TIMEOUT = 20000;
|
|
|
6661
6684
|
const CLIENT_PING_INTERVAL = 30000;
|
|
6662
6685
|
const FAIL_RETRY_WAIT_TIME = 60000;
|
|
6663
6686
|
class WSObservable extends Observable$1 {
|
|
6664
|
-
constructor(db, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus,
|
|
6665
|
-
super((subscriber) => new WSConnection(db, rev, realmSetHash, clientIdentity,
|
|
6687
|
+
constructor(db, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus, user) {
|
|
6688
|
+
super((subscriber) => new WSConnection(db, rev, realmSetHash, clientIdentity, user, subscriber, messageProducer, webSocketStatus));
|
|
6666
6689
|
}
|
|
6667
6690
|
}
|
|
6668
6691
|
let counter = 0;
|
|
6669
6692
|
class WSConnection extends Subscription$1 {
|
|
6670
|
-
constructor(db, rev, realmSetHash, clientIdentity,
|
|
6693
|
+
constructor(db, rev, realmSetHash, clientIdentity, user, subscriber, messageProducer, webSocketStatus) {
|
|
6671
6694
|
super(() => this.teardown());
|
|
6672
6695
|
this.id = ++counter;
|
|
6673
6696
|
this.subscriptions = new Set();
|
|
6674
6697
|
this.reconnecting = false;
|
|
6675
|
-
console.debug('New WebSocket Connection', this.id,
|
|
6698
|
+
console.debug('New WebSocket Connection', this.id, user.accessToken ? 'authorized' : 'unauthorized');
|
|
6676
6699
|
this.db = db;
|
|
6677
6700
|
this.databaseUrl = db.cloud.options.databaseUrl;
|
|
6678
6701
|
this.rev = rev;
|
|
6679
6702
|
this.realmSetHash = realmSetHash;
|
|
6680
6703
|
this.clientIdentity = clientIdentity;
|
|
6681
|
-
this.
|
|
6682
|
-
this.tokenExpiration = tokenExpiration;
|
|
6704
|
+
this.user = user;
|
|
6683
6705
|
this.subscriber = subscriber;
|
|
6684
6706
|
this.lastUserActivity = new Date();
|
|
6685
6707
|
this.messageProducer = messageProducer;
|
|
@@ -6739,7 +6761,8 @@ class WSConnection extends Subscription$1 {
|
|
|
6739
6761
|
//console.debug('SyncStatus: DUBB: Ooops it was closed!');
|
|
6740
6762
|
return;
|
|
6741
6763
|
}
|
|
6742
|
-
|
|
6764
|
+
const tokenExpiration = this.user.accessTokenExpiration;
|
|
6765
|
+
if (tokenExpiration && tokenExpiration < new Date()) {
|
|
6743
6766
|
this.subscriber.error(new TokenExpiredError()); // Will be handled in connectWebSocket.ts.
|
|
6744
6767
|
return;
|
|
6745
6768
|
}
|
|
@@ -6794,8 +6817,8 @@ class WSConnection extends Subscription$1 {
|
|
|
6794
6817
|
searchParams.set('rev', this.rev);
|
|
6795
6818
|
searchParams.set('realmsHash', this.realmSetHash);
|
|
6796
6819
|
searchParams.set('clientId', this.clientIdentity);
|
|
6797
|
-
if (this.
|
|
6798
|
-
searchParams.set('token', this.
|
|
6820
|
+
if (this.user.accessToken) {
|
|
6821
|
+
searchParams.set('token', this.user.accessToken);
|
|
6799
6822
|
}
|
|
6800
6823
|
// Connect the WebSocket to given url:
|
|
6801
6824
|
console.debug('dexie-cloud WebSocket create');
|
|
@@ -6881,7 +6904,9 @@ class WSConnection extends Subscription$1 {
|
|
|
6881
6904
|
}
|
|
6882
6905
|
}
|
|
6883
6906
|
}));
|
|
6884
|
-
|
|
6907
|
+
if (this.user.isLoggedIn && !isEagerSyncDisabled(this.db)) {
|
|
6908
|
+
this.subscriptions.add(createYClientUpdateObservable(this.db).subscribe(this.db.messageProducer));
|
|
6909
|
+
}
|
|
6885
6910
|
}
|
|
6886
6911
|
catch (error) {
|
|
6887
6912
|
this.pauseUntil = new Date(Date.now() + FAIL_RETRY_WAIT_TIME);
|
|
@@ -6961,7 +6986,7 @@ function connectWebSocket(db) {
|
|
|
6961
6986
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
6962
6987
|
// and the baseRev of the last from same client-ID.
|
|
6963
6988
|
if (userLogin) {
|
|
6964
|
-
return new WSObservable(db, db.cloud.persistedSyncState.value.serverRevision, realmSetHash, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin
|
|
6989
|
+
return new WSObservable(db, db.cloud.persistedSyncState.value.serverRevision, realmSetHash, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin);
|
|
6965
6990
|
}
|
|
6966
6991
|
else {
|
|
6967
6992
|
return from$1([]);
|
|
@@ -7768,9 +7793,9 @@ const getInvitesObservable = associate((db) => {
|
|
|
7768
7793
|
});
|
|
7769
7794
|
|
|
7770
7795
|
function createYHandler(db) {
|
|
7771
|
-
const awap = getAwarenessLibrary(db);
|
|
7772
7796
|
return (provider) => {
|
|
7773
7797
|
var _a;
|
|
7798
|
+
const awap = getAwarenessLibrary(db);
|
|
7774
7799
|
const doc = provider.doc;
|
|
7775
7800
|
const { parentTable, parentId, parentProp, updatesTable } = doc.meta;
|
|
7776
7801
|
if (!((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[parentTable].markedForSync)) {
|
|
@@ -7782,7 +7807,8 @@ function createYHandler(db) {
|
|
|
7782
7807
|
awareness.on('update', ({ added, updated, removed }, origin) => {
|
|
7783
7808
|
// Send the update
|
|
7784
7809
|
const changedClients = added.concat(updated).concat(removed);
|
|
7785
|
-
|
|
7810
|
+
const user = db.cloud.currentUser.value;
|
|
7811
|
+
if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7786
7812
|
const update = awap.encodeAwarenessUpdate(awareness, changedClients);
|
|
7787
7813
|
db.messageProducer.next({
|
|
7788
7814
|
type: 'aware',
|
|
@@ -7823,7 +7849,8 @@ function createYHandler(db) {
|
|
|
7823
7849
|
// Keep "connected" state in a variable so we can check it after async operations
|
|
7824
7850
|
connected = wsStatus === 'connected';
|
|
7825
7851
|
// We are or got connected. Open the document on the server.
|
|
7826
|
-
|
|
7852
|
+
const user = db.cloud.currentUser.value;
|
|
7853
|
+
if (wsStatus === "connected" && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7827
7854
|
++currentFlowId;
|
|
7828
7855
|
openDocumentOnServer().catch(error => {
|
|
7829
7856
|
console.warn(`Error catched in createYHandler.ts: ${error}`);
|
|
@@ -7929,7 +7956,7 @@ function dexieCloud(dexie) {
|
|
|
7929
7956
|
const syncComplete = new Subject();
|
|
7930
7957
|
dexie.cloud = {
|
|
7931
7958
|
// @ts-ignore
|
|
7932
|
-
version: "4.1.0-alpha.
|
|
7959
|
+
version: "4.1.0-alpha.5",
|
|
7933
7960
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
7934
7961
|
schema: null,
|
|
7935
7962
|
get currentUserId() {
|
|
@@ -8231,7 +8258,7 @@ function dexieCloud(dexie) {
|
|
|
8231
8258
|
}
|
|
8232
8259
|
}
|
|
8233
8260
|
// @ts-ignore
|
|
8234
|
-
dexieCloud.version = "4.1.0-alpha.
|
|
8261
|
+
dexieCloud.version = "4.1.0-alpha.5";
|
|
8235
8262
|
Dexie.Cloud = dexieCloud;
|
|
8236
8263
|
|
|
8237
8264
|
// In case the SW lives for a while, let it reuse already opened connections:
|