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
|
*
|
|
@@ -4664,13 +4664,12 @@
|
|
|
4664
4664
|
* @param db
|
|
4665
4665
|
* @returns
|
|
4666
4666
|
*/
|
|
4667
|
-
function listYClientMessagesAndStateVector(db) {
|
|
4668
|
-
var _a;
|
|
4667
|
+
function listYClientMessagesAndStateVector(db, tablesToSync) {
|
|
4669
4668
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4670
4669
|
const result = [];
|
|
4671
4670
|
const lastUpdateIds = {};
|
|
4672
|
-
for (const table of
|
|
4673
|
-
if (table.schema.yProps
|
|
4671
|
+
for (const table of tablesToSync) {
|
|
4672
|
+
if (table.schema.yProps) {
|
|
4674
4673
|
for (const yProp of table.schema.yProps) {
|
|
4675
4674
|
const Y = $Y(db); // This is how we retrieve the user-provided Y library
|
|
4676
4675
|
const yTable = db.table(yProp.updatesTable); // the updates-table for this combo of table+propName
|
|
@@ -4804,7 +4803,7 @@
|
|
|
4804
4803
|
}
|
|
4805
4804
|
|
|
4806
4805
|
function updateYSyncStates(lastUpdateIdsBeforeSync, receivedUntilsAfterSync, db, serverRevision) {
|
|
4807
|
-
var _a, _b;
|
|
4806
|
+
var _a, _b, _c, _d, _e;
|
|
4808
4807
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4809
4808
|
// We want to update unsentFrom for each yTable to the value specified in first argument
|
|
4810
4809
|
// because we got those values before we synced with server and here we are back from server
|
|
@@ -4812,7 +4811,7 @@
|
|
|
4812
4811
|
// we can safely store unsentFrom to a value of the last update + 1 here.
|
|
4813
4812
|
// We also want to update receivedUntil for each yTable to the value specified in the second argument,
|
|
4814
4813
|
// because that contains the highest resulted id of each update from server after storing it.
|
|
4815
|
-
// We could do these two tasks separately, but that would require two update calls on the same YSyncState, so
|
|
4814
|
+
// We could do these two tasks separately, but that would require two update calls on the same YSyncState, so
|
|
4816
4815
|
// to optimize the dexie calls, we merge these two maps into a single one so we can do a single update request
|
|
4817
4816
|
// per yTable.
|
|
4818
4817
|
const mergedSpec = {};
|
|
@@ -4824,28 +4823,42 @@
|
|
|
4824
4823
|
(_b = mergedSpec[yTable]) !== null && _b !== void 0 ? _b : (mergedSpec[yTable] = {});
|
|
4825
4824
|
mergedSpec[yTable].receivedUntil = lastUpdateId;
|
|
4826
4825
|
}
|
|
4827
|
-
// Now go through
|
|
4828
|
-
|
|
4826
|
+
// Now go through all yTables and update their YSyncStates:
|
|
4827
|
+
const allYTables = Object.values(db.dx._dbSchema)
|
|
4828
|
+
.filter((tblSchema) => tblSchema.yProps)
|
|
4829
|
+
.map((tblSchema) => tblSchema.yProps.map((yProp) => yProp.updatesTable))
|
|
4830
|
+
.flat();
|
|
4831
|
+
for (const yTable of allYTables) {
|
|
4832
|
+
const mergedEntry = mergedSpec[yTable];
|
|
4833
|
+
const unsentFrom = (_c = mergedEntry === null || mergedEntry === void 0 ? void 0 : mergedEntry.unsentFrom) !== null && _c !== void 0 ? _c : 1;
|
|
4834
|
+
const receivedUntil = (_e = (_d = mergedEntry === null || mergedEntry === void 0 ? void 0 : mergedEntry.receivedUntil) !== null && _d !== void 0 ? _d :
|
|
4835
|
+
// from local because we are in the same parent transaction (in sync.ts) that
|
|
4836
|
+
// applied all updates from the server
|
|
4837
|
+
(yield db
|
|
4838
|
+
.table(yTable)
|
|
4839
|
+
.where('i')
|
|
4840
|
+
.between(1, Infinity) // Because i might be string DEXIE_CLOUD_SYNCER_ID if not a number.
|
|
4841
|
+
.reverse()
|
|
4842
|
+
.limit(1)
|
|
4843
|
+
.primaryKeys())[0]) !== null && _e !== void 0 ? _e : 0;
|
|
4829
4844
|
// We're already in a transaction, but for the sake of
|
|
4830
4845
|
// code readability and correctness, let's launch an atomic sub transaction:
|
|
4831
4846
|
yield db.transaction('rw', yTable, () => __awaiter(this, void 0, void 0, function* () {
|
|
4832
|
-
const state = yield db
|
|
4847
|
+
const state = yield db
|
|
4848
|
+
.table(yTable)
|
|
4849
|
+
.get(DEXIE_CLOUD_SYNCER_ID);
|
|
4833
4850
|
if (!state) {
|
|
4834
4851
|
yield db.table(yTable).add({
|
|
4835
4852
|
i: DEXIE_CLOUD_SYNCER_ID,
|
|
4836
|
-
unsentFrom
|
|
4837
|
-
receivedUntil
|
|
4853
|
+
unsentFrom,
|
|
4854
|
+
receivedUntil,
|
|
4838
4855
|
serverRev: serverRevision,
|
|
4839
4856
|
});
|
|
4840
4857
|
}
|
|
4841
4858
|
else {
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
if (receivedUntil) {
|
|
4846
|
-
state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);
|
|
4847
|
-
state.serverRev = serverRevision;
|
|
4848
|
-
}
|
|
4859
|
+
state.unsentFrom = Math.max(unsentFrom, state.unsentFrom || 1);
|
|
4860
|
+
state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);
|
|
4861
|
+
state.serverRev = serverRevision;
|
|
4849
4862
|
yield db.table(yTable).put(state);
|
|
4850
4863
|
}
|
|
4851
4864
|
}));
|
|
@@ -4858,7 +4871,9 @@
|
|
|
4858
4871
|
const BINSTREAM_TYPE_DOCUMENT = 3;
|
|
4859
4872
|
function downloadYDocsFromServer(db, databaseUrl, { yDownloadedRealms, realms }) {
|
|
4860
4873
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4861
|
-
if (yDownloadedRealms &&
|
|
4874
|
+
if (yDownloadedRealms &&
|
|
4875
|
+
realms &&
|
|
4876
|
+
realms.every((realmId) => yDownloadedRealms[realmId] === '*')) {
|
|
4862
4877
|
return; // Already done!
|
|
4863
4878
|
}
|
|
4864
4879
|
console.debug('Downloading Y.Docs from added realms');
|
|
@@ -4898,16 +4913,19 @@
|
|
|
4898
4913
|
yield yTable.bulkAdd(docsToInsert);
|
|
4899
4914
|
docsToInsert = [];
|
|
4900
4915
|
}
|
|
4901
|
-
if (currentRealmId &&
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4916
|
+
if (currentRealmId &&
|
|
4917
|
+
((currentTable && currentProp && lastDoc) || completedRealm)) {
|
|
4918
|
+
yield db.$syncState.update('syncState', (syncState) => {
|
|
4919
|
+
const yDownloadedRealms = syncState.yDownloadedRealms || {};
|
|
4920
|
+
yDownloadedRealms[currentRealmId] = completedRealm
|
|
4921
|
+
? '*'
|
|
4922
|
+
: {
|
|
4906
4923
|
tbl: currentTable,
|
|
4907
4924
|
prop: currentProp,
|
|
4908
4925
|
key: lastDoc.k,
|
|
4909
|
-
}
|
|
4910
|
-
|
|
4926
|
+
};
|
|
4927
|
+
syncState.yDownloadedRealms = yDownloadedRealms;
|
|
4928
|
+
});
|
|
4911
4929
|
}
|
|
4912
4930
|
});
|
|
4913
4931
|
}
|
|
@@ -5057,7 +5075,7 @@
|
|
|
5057
5075
|
const syncState = yield db.getPersistedSyncState();
|
|
5058
5076
|
const baseRevs = yield db.$baseRevs.toArray();
|
|
5059
5077
|
let clientChanges = yield listClientChanges(mutationTables);
|
|
5060
|
-
const yResults = yield listYClientMessagesAndStateVector(db);
|
|
5078
|
+
const yResults = yield listYClientMessagesAndStateVector(db, tablesToSync);
|
|
5061
5079
|
throwIfCancelled(cancelToken);
|
|
5062
5080
|
if (doSyncify) {
|
|
5063
5081
|
const alreadySyncedRealms = [
|
|
@@ -6616,7 +6634,7 @@
|
|
|
6616
6634
|
|
|
6617
6635
|
function createYClientUpdateObservable(db) {
|
|
6618
6636
|
const yTableRecords = flatten(db.tables
|
|
6619
|
-
.filter((table) => { var _a; return ((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[table.name].markedForSync) && table.schema.yProps; })
|
|
6637
|
+
.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; })
|
|
6620
6638
|
.map((table) => table.schema.yProps.map((p) => ({
|
|
6621
6639
|
table: table.name,
|
|
6622
6640
|
ydocProp: p.prop,
|
|
@@ -6647,7 +6665,12 @@
|
|
|
6647
6665
|
};
|
|
6648
6666
|
});
|
|
6649
6667
|
}));
|
|
6650
|
-
})).pipe(
|
|
6668
|
+
})).pipe(
|
|
6669
|
+
// Flatten the array of messages.
|
|
6670
|
+
// If messageProducer emits empty array, nothing is emitted
|
|
6671
|
+
// but if messageProducer emits array of messages, they are
|
|
6672
|
+
// emitted one by one.
|
|
6673
|
+
rxjs.mergeMap((messages) => messages));
|
|
6651
6674
|
}
|
|
6652
6675
|
|
|
6653
6676
|
function getAwarenessLibrary(db) {
|
|
@@ -6664,25 +6687,24 @@
|
|
|
6664
6687
|
const CLIENT_PING_INTERVAL = 30000;
|
|
6665
6688
|
const FAIL_RETRY_WAIT_TIME = 60000;
|
|
6666
6689
|
class WSObservable extends rxjs.Observable {
|
|
6667
|
-
constructor(db, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus,
|
|
6668
|
-
super((subscriber) => new WSConnection(db, rev, realmSetHash, clientIdentity,
|
|
6690
|
+
constructor(db, rev, realmSetHash, clientIdentity, messageProducer, webSocketStatus, user) {
|
|
6691
|
+
super((subscriber) => new WSConnection(db, rev, realmSetHash, clientIdentity, user, subscriber, messageProducer, webSocketStatus));
|
|
6669
6692
|
}
|
|
6670
6693
|
}
|
|
6671
6694
|
let counter = 0;
|
|
6672
6695
|
class WSConnection extends rxjs.Subscription {
|
|
6673
|
-
constructor(db, rev, realmSetHash, clientIdentity,
|
|
6696
|
+
constructor(db, rev, realmSetHash, clientIdentity, user, subscriber, messageProducer, webSocketStatus) {
|
|
6674
6697
|
super(() => this.teardown());
|
|
6675
6698
|
this.id = ++counter;
|
|
6676
6699
|
this.subscriptions = new Set();
|
|
6677
6700
|
this.reconnecting = false;
|
|
6678
|
-
console.debug('New WebSocket Connection', this.id,
|
|
6701
|
+
console.debug('New WebSocket Connection', this.id, user.accessToken ? 'authorized' : 'unauthorized');
|
|
6679
6702
|
this.db = db;
|
|
6680
6703
|
this.databaseUrl = db.cloud.options.databaseUrl;
|
|
6681
6704
|
this.rev = rev;
|
|
6682
6705
|
this.realmSetHash = realmSetHash;
|
|
6683
6706
|
this.clientIdentity = clientIdentity;
|
|
6684
|
-
this.
|
|
6685
|
-
this.tokenExpiration = tokenExpiration;
|
|
6707
|
+
this.user = user;
|
|
6686
6708
|
this.subscriber = subscriber;
|
|
6687
6709
|
this.lastUserActivity = new Date();
|
|
6688
6710
|
this.messageProducer = messageProducer;
|
|
@@ -6742,7 +6764,8 @@
|
|
|
6742
6764
|
//console.debug('SyncStatus: DUBB: Ooops it was closed!');
|
|
6743
6765
|
return;
|
|
6744
6766
|
}
|
|
6745
|
-
|
|
6767
|
+
const tokenExpiration = this.user.accessTokenExpiration;
|
|
6768
|
+
if (tokenExpiration && tokenExpiration < new Date()) {
|
|
6746
6769
|
this.subscriber.error(new TokenExpiredError()); // Will be handled in connectWebSocket.ts.
|
|
6747
6770
|
return;
|
|
6748
6771
|
}
|
|
@@ -6797,8 +6820,8 @@
|
|
|
6797
6820
|
searchParams.set('rev', this.rev);
|
|
6798
6821
|
searchParams.set('realmsHash', this.realmSetHash);
|
|
6799
6822
|
searchParams.set('clientId', this.clientIdentity);
|
|
6800
|
-
if (this.
|
|
6801
|
-
searchParams.set('token', this.
|
|
6823
|
+
if (this.user.accessToken) {
|
|
6824
|
+
searchParams.set('token', this.user.accessToken);
|
|
6802
6825
|
}
|
|
6803
6826
|
// Connect the WebSocket to given url:
|
|
6804
6827
|
console.debug('dexie-cloud WebSocket create');
|
|
@@ -6884,7 +6907,9 @@
|
|
|
6884
6907
|
}
|
|
6885
6908
|
}
|
|
6886
6909
|
}));
|
|
6887
|
-
|
|
6910
|
+
if (this.user.isLoggedIn && !isEagerSyncDisabled(this.db)) {
|
|
6911
|
+
this.subscriptions.add(createYClientUpdateObservable(this.db).subscribe(this.db.messageProducer));
|
|
6912
|
+
}
|
|
6888
6913
|
}
|
|
6889
6914
|
catch (error) {
|
|
6890
6915
|
this.pauseUntil = new Date(Date.now() + FAIL_RETRY_WAIT_TIME);
|
|
@@ -6964,7 +6989,7 @@
|
|
|
6964
6989
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
6965
6990
|
// and the baseRev of the last from same client-ID.
|
|
6966
6991
|
if (userLogin) {
|
|
6967
|
-
return new WSObservable(db, db.cloud.persistedSyncState.value.serverRevision, realmSetHash, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin
|
|
6992
|
+
return new WSObservable(db, db.cloud.persistedSyncState.value.serverRevision, realmSetHash, db.cloud.persistedSyncState.value.clientIdentity, messageProducer, db.cloud.webSocketStatus, userLogin);
|
|
6968
6993
|
}
|
|
6969
6994
|
else {
|
|
6970
6995
|
return rxjs.from([]);
|
|
@@ -7771,9 +7796,9 @@
|
|
|
7771
7796
|
});
|
|
7772
7797
|
|
|
7773
7798
|
function createYHandler(db) {
|
|
7774
|
-
const awap = getAwarenessLibrary(db);
|
|
7775
7799
|
return (provider) => {
|
|
7776
7800
|
var _a;
|
|
7801
|
+
const awap = getAwarenessLibrary(db);
|
|
7777
7802
|
const doc = provider.doc;
|
|
7778
7803
|
const { parentTable, parentId, parentProp, updatesTable } = doc.meta;
|
|
7779
7804
|
if (!((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[parentTable].markedForSync)) {
|
|
@@ -7785,7 +7810,8 @@
|
|
|
7785
7810
|
awareness.on('update', ({ added, updated, removed }, origin) => {
|
|
7786
7811
|
// Send the update
|
|
7787
7812
|
const changedClients = added.concat(updated).concat(removed);
|
|
7788
|
-
|
|
7813
|
+
const user = db.cloud.currentUser.value;
|
|
7814
|
+
if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7789
7815
|
const update = awap.encodeAwarenessUpdate(awareness, changedClients);
|
|
7790
7816
|
db.messageProducer.next({
|
|
7791
7817
|
type: 'aware',
|
|
@@ -7826,7 +7852,8 @@
|
|
|
7826
7852
|
// Keep "connected" state in a variable so we can check it after async operations
|
|
7827
7853
|
connected = wsStatus === 'connected';
|
|
7828
7854
|
// We are or got connected. Open the document on the server.
|
|
7829
|
-
|
|
7855
|
+
const user = db.cloud.currentUser.value;
|
|
7856
|
+
if (wsStatus === "connected" && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7830
7857
|
++currentFlowId;
|
|
7831
7858
|
openDocumentOnServer().catch(error => {
|
|
7832
7859
|
console.warn(`Error catched in createYHandler.ts: ${error}`);
|
|
@@ -7932,7 +7959,7 @@
|
|
|
7932
7959
|
const syncComplete = new rxjs.Subject();
|
|
7933
7960
|
dexie.cloud = {
|
|
7934
7961
|
// @ts-ignore
|
|
7935
|
-
version: "4.1.0-alpha.
|
|
7962
|
+
version: "4.1.0-alpha.5",
|
|
7936
7963
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
7937
7964
|
schema: null,
|
|
7938
7965
|
get currentUserId() {
|
|
@@ -8234,7 +8261,7 @@
|
|
|
8234
8261
|
}
|
|
8235
8262
|
}
|
|
8236
8263
|
// @ts-ignore
|
|
8237
|
-
dexieCloud.version = "4.1.0-alpha.
|
|
8264
|
+
dexieCloud.version = "4.1.0-alpha.5";
|
|
8238
8265
|
Dexie.Cloud = dexieCloud;
|
|
8239
8266
|
|
|
8240
8267
|
// In case the SW lives for a while, let it reuse already opened connections:
|