dexie-cloud-addon 4.1.0-alpha.10 → 4.1.0-alpha.12
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/define-ydoc-trigger.d.ts +2 -0
- package/dist/modern/dexie-cloud-addon.d.ts +1 -0
- package/dist/modern/dexie-cloud-addon.js +295 -113
- 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 +139 -109
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/umd/define-ydoc-trigger.d.ts +2 -0
- package/dist/umd/dexie-cloud-addon.d.ts +1 -0
- package/dist/umd/dexie-cloud-addon.js +294 -111
- 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 +139 -109
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/package.json +2 -2
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.1.0-alpha.
|
|
11
|
+
* Version 4.1.0-alpha.12, Wed Oct 16 2024
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -4755,6 +4755,7 @@
|
|
|
4755
4755
|
}
|
|
4756
4756
|
|
|
4757
4757
|
function applyYServerMessages(yMessages, db) {
|
|
4758
|
+
var _a;
|
|
4758
4759
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4759
4760
|
const result = {};
|
|
4760
4761
|
for (const m of yMessages) {
|
|
@@ -4786,7 +4787,24 @@
|
|
|
4786
4787
|
// See my question in https://discuss.yjs.dev/t/generate-an-inverse-update/2765
|
|
4787
4788
|
console.debug(`Y update rejected. Deleting it.`);
|
|
4788
4789
|
const utbl = getUpdatesTable(db, m.table, m.prop);
|
|
4789
|
-
|
|
4790
|
+
// Delete the rejected update and all local updates since (avoid holes in the CRDT)
|
|
4791
|
+
// and destroy it's open document if there is one.
|
|
4792
|
+
const primaryKey = (_a = (yield utbl.get(m.i))) === null || _a === void 0 ? void 0 : _a.k;
|
|
4793
|
+
if (primaryKey != null) {
|
|
4794
|
+
yield db.transaction('rw', utbl, tx => {
|
|
4795
|
+
// @ts-ignore
|
|
4796
|
+
tx.idbtrans._rejecting_y_ypdate = true; // Inform ydoc triggers that we delete because of a rejection and not GC
|
|
4797
|
+
return utbl
|
|
4798
|
+
.where('i')
|
|
4799
|
+
.aboveOrEqual(m.i)
|
|
4800
|
+
.filter(u => Dexie.cmp(u.k, primaryKey) === 0 && ((u.f || 0) & 1) === 1)
|
|
4801
|
+
.delete();
|
|
4802
|
+
});
|
|
4803
|
+
// Destroy active doc
|
|
4804
|
+
const activeDoc = Dexie.DexieYProvider.getDocCache(db.dx).find(m.table, primaryKey, m.prop);
|
|
4805
|
+
if (activeDoc)
|
|
4806
|
+
activeDoc.destroy(); // Destroy the document so that editors don't continue to work on it
|
|
4807
|
+
}
|
|
4790
4808
|
break;
|
|
4791
4809
|
}
|
|
4792
4810
|
case 'in-sync': {
|
|
@@ -7807,125 +7825,137 @@
|
|
|
7807
7825
|
function createYHandler(db) {
|
|
7808
7826
|
return (provider) => {
|
|
7809
7827
|
var _a;
|
|
7810
|
-
const awap = getAwarenessLibrary(db);
|
|
7811
7828
|
const doc = provider.doc;
|
|
7812
|
-
const { parentTable
|
|
7829
|
+
const { parentTable } = doc.meta || {};
|
|
7813
7830
|
if (!((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[parentTable].markedForSync)) {
|
|
7814
7831
|
return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.
|
|
7815
7832
|
}
|
|
7816
|
-
let awareness
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7833
|
+
let awareness;
|
|
7834
|
+
Object.defineProperty(provider, "awareness", {
|
|
7835
|
+
get() {
|
|
7836
|
+
if (awareness)
|
|
7837
|
+
return awareness;
|
|
7838
|
+
awarenessWeakMap.set(doc, awareness);
|
|
7839
|
+
awareness = createAwareness(db, doc, provider);
|
|
7840
|
+
return awareness;
|
|
7841
|
+
}
|
|
7842
|
+
});
|
|
7843
|
+
};
|
|
7844
|
+
}
|
|
7845
|
+
function createAwareness(db, doc, provider) {
|
|
7846
|
+
const { parentTable, parentId, parentProp, updatesTable } = doc.meta;
|
|
7847
|
+
const awap = getAwarenessLibrary(db);
|
|
7848
|
+
const awareness = new awap.Awareness(doc);
|
|
7849
|
+
awareness.on('update', ({ added, updated, removed }, origin) => {
|
|
7850
|
+
// Send the update
|
|
7851
|
+
const changedClients = added.concat(updated).concat(removed);
|
|
7852
|
+
const user = db.cloud.currentUser.value;
|
|
7853
|
+
if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7854
|
+
const update = awap.encodeAwarenessUpdate(awareness, changedClients);
|
|
7855
|
+
db.messageProducer.next({
|
|
7856
|
+
type: 'aware',
|
|
7857
|
+
table: parentTable,
|
|
7858
|
+
prop: parentProp,
|
|
7859
|
+
k: doc.meta.parentId,
|
|
7860
|
+
u: update,
|
|
7861
|
+
});
|
|
7862
|
+
if (provider.destroyed) {
|
|
7863
|
+
// We're called from awareness.on('destroy') that did
|
|
7864
|
+
// removeAwarenessStates.
|
|
7865
|
+
// It's time to also send the doc-close message that dexie-cloud understands
|
|
7866
|
+
// and uses to stop subscribing for updates and awareness updates and brings
|
|
7867
|
+
// down the cached information in memory on the WS connection for this.
|
|
7825
7868
|
db.messageProducer.next({
|
|
7826
|
-
type: '
|
|
7869
|
+
type: 'doc-close',
|
|
7827
7870
|
table: parentTable,
|
|
7828
7871
|
prop: parentProp,
|
|
7829
|
-
k: doc.meta.parentId
|
|
7830
|
-
u: update,
|
|
7872
|
+
k: doc.meta.parentId
|
|
7831
7873
|
});
|
|
7832
|
-
if (provider.destroyed) {
|
|
7833
|
-
// We're called from awareness.on('destroy') that did
|
|
7834
|
-
// removeAwarenessStates.
|
|
7835
|
-
// It's time to also send the doc-close message that dexie-cloud understands
|
|
7836
|
-
// and uses to stop subscribing for updates and awareness updates and brings
|
|
7837
|
-
// down the cached information in memory on the WS connection for this.
|
|
7838
|
-
db.messageProducer.next({
|
|
7839
|
-
type: 'doc-close',
|
|
7840
|
-
table: parentTable,
|
|
7841
|
-
prop: parentProp,
|
|
7842
|
-
k: doc.meta.parentId
|
|
7843
|
-
});
|
|
7844
|
-
}
|
|
7845
7874
|
}
|
|
7846
|
-
}
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7875
|
+
}
|
|
7876
|
+
});
|
|
7877
|
+
awareness.on('destroy', () => {
|
|
7878
|
+
// Signal to server that this provider is destroyed (the update event will be triggered, which
|
|
7879
|
+
// in turn will trigger db.messageProducer that will send the message to the server if WS is connected)
|
|
7880
|
+
awap.removeAwarenessStates(awareness, [doc.clientID], 'provider destroyed');
|
|
7881
|
+
});
|
|
7882
|
+
// Open the document on the server
|
|
7883
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
7884
|
+
if (provider.destroyed)
|
|
7885
|
+
return;
|
|
7886
|
+
let connected = false;
|
|
7887
|
+
let currentFlowId = 1;
|
|
7888
|
+
const subscription = db.cloud.webSocketStatus.subscribe((wsStatus) => {
|
|
7854
7889
|
if (provider.destroyed)
|
|
7855
7890
|
return;
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7891
|
+
// Keep "connected" state in a variable so we can check it after async operations
|
|
7892
|
+
connected = wsStatus === 'connected';
|
|
7893
|
+
// We are or got connected. Open the document on the server.
|
|
7894
|
+
const user = db.cloud.currentUser.value;
|
|
7895
|
+
if (wsStatus === "connected" && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7896
|
+
++currentFlowId;
|
|
7897
|
+
openDocumentOnServer().catch(error => {
|
|
7898
|
+
console.warn(`Error catched in createYHandler.ts: ${error}`);
|
|
7899
|
+
});
|
|
7900
|
+
}
|
|
7901
|
+
});
|
|
7902
|
+
// Wait until WebSocket is connected
|
|
7903
|
+
provider.addCleanupHandler(subscription);
|
|
7904
|
+
/** Sends an 'doc-open' message to server whenever websocket becomes
|
|
7905
|
+
* connected, or if it is already connected.
|
|
7906
|
+
* The flow is aborted in case websocket is disconnected while querying
|
|
7907
|
+
* information required to compute the state vector. Flow is also
|
|
7908
|
+
* aborted in case document or provider has been destroyed during
|
|
7909
|
+
* the async parts of the task.
|
|
7910
|
+
*
|
|
7911
|
+
* The state vector is only computed from the updates that have occured
|
|
7912
|
+
* after the last full sync - which could very often be zero - in which
|
|
7913
|
+
* case no state vector is sent (then the server already knows us by
|
|
7914
|
+
* revision)
|
|
7915
|
+
*
|
|
7916
|
+
* When server gets the doc-open message, it will authorized us for
|
|
7917
|
+
* whether we are allowed to read / write to this document, and then
|
|
7918
|
+
* keep the cached information in memory on the WS connection for this
|
|
7919
|
+
* particular document, as well as subscribe to updates and awareness updates
|
|
7920
|
+
* from other clients on the document.
|
|
7921
|
+
*/
|
|
7922
|
+
function openDocumentOnServer(wsStatus) {
|
|
7923
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7924
|
+
const myFlow = currentFlowId; // So we can abort when a new flow is started
|
|
7925
|
+
const yTbl = db.table(updatesTable);
|
|
7926
|
+
const syncState = yield yTbl.get(DEXIE_CLOUD_SYNCER_ID);
|
|
7927
|
+
// After every await, check if we still should be working on this task.
|
|
7928
|
+
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7860
7929
|
return;
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7930
|
+
const receivedUntil = (syncState === null || syncState === void 0 ? void 0 : syncState.receivedUntil) || 0;
|
|
7931
|
+
const docOpenMsg = {
|
|
7932
|
+
type: 'doc-open',
|
|
7933
|
+
table: parentTable,
|
|
7934
|
+
prop: parentProp,
|
|
7935
|
+
k: parentId,
|
|
7936
|
+
serverRev: syncState === null || syncState === void 0 ? void 0 : syncState.serverRev,
|
|
7937
|
+
};
|
|
7938
|
+
const serverUpdatesSinceLastSync = yield yTbl
|
|
7939
|
+
.where('i')
|
|
7940
|
+
.between(receivedUntil, Infinity, false)
|
|
7941
|
+
.filter((update) => Dexie.cmp(update.k, parentId) === 0 && // Only updates for this document
|
|
7942
|
+
((update.f || 0) & 1) === 0 // Don't include local changes
|
|
7943
|
+
)
|
|
7944
|
+
.toArray();
|
|
7945
|
+
// After every await, check if we still should be working on this task.
|
|
7946
|
+
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7947
|
+
return;
|
|
7948
|
+
if (serverUpdatesSinceLastSync.length > 0) {
|
|
7949
|
+
const Y = $Y(db); // Get the Yjs library from Dexie constructor options
|
|
7950
|
+
const mergedUpdate = Y.mergeUpdatesV2(serverUpdatesSinceLastSync.map((update) => update.u));
|
|
7951
|
+
const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);
|
|
7952
|
+
docOpenMsg.sv = stateVector;
|
|
7870
7953
|
}
|
|
7954
|
+
db.messageProducer.next(docOpenMsg);
|
|
7871
7955
|
});
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
* connected, or if it is already connected.
|
|
7876
|
-
* The flow is aborted in case websocket is disconnected while querying
|
|
7877
|
-
* information required to compute the state vector. Flow is also
|
|
7878
|
-
* aborted in case document or provider has been destroyed during
|
|
7879
|
-
* the async parts of the task.
|
|
7880
|
-
*
|
|
7881
|
-
* The state vector is only computed from the updates that have occured
|
|
7882
|
-
* after the last full sync - which could very often be zero - in which
|
|
7883
|
-
* case no state vector is sent (then the server already knows us by
|
|
7884
|
-
* revision)
|
|
7885
|
-
*
|
|
7886
|
-
* When server gets the doc-open message, it will authorized us for
|
|
7887
|
-
* whether we are allowed to read / write to this document, and then
|
|
7888
|
-
* keep the cached information in memory on the WS connection for this
|
|
7889
|
-
* particular document, as well as subscribe to updates and awareness updates
|
|
7890
|
-
* from other clients on the document.
|
|
7891
|
-
*/
|
|
7892
|
-
function openDocumentOnServer(wsStatus) {
|
|
7893
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7894
|
-
const myFlow = currentFlowId; // So we can abort when a new flow is started
|
|
7895
|
-
const yTbl = db.table(updatesTable);
|
|
7896
|
-
const syncState = yield yTbl.get(DEXIE_CLOUD_SYNCER_ID);
|
|
7897
|
-
// After every await, check if we still should be working on this task.
|
|
7898
|
-
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7899
|
-
return;
|
|
7900
|
-
const receivedUntil = (syncState === null || syncState === void 0 ? void 0 : syncState.receivedUntil) || 0;
|
|
7901
|
-
const docOpenMsg = {
|
|
7902
|
-
type: 'doc-open',
|
|
7903
|
-
table: parentTable,
|
|
7904
|
-
prop: parentProp,
|
|
7905
|
-
k: parentId,
|
|
7906
|
-
serverRev: syncState === null || syncState === void 0 ? void 0 : syncState.serverRev,
|
|
7907
|
-
};
|
|
7908
|
-
const serverUpdatesSinceLastSync = yield yTbl
|
|
7909
|
-
.where('i')
|
|
7910
|
-
.between(receivedUntil, Infinity, false)
|
|
7911
|
-
.filter((update) => Dexie.cmp(update.k, parentId) === 0 && // Only updates for this document
|
|
7912
|
-
((update.f || 0) & 1) === 0 // Don't include local changes
|
|
7913
|
-
)
|
|
7914
|
-
.toArray();
|
|
7915
|
-
// After every await, check if we still should be working on this task.
|
|
7916
|
-
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7917
|
-
return;
|
|
7918
|
-
if (serverUpdatesSinceLastSync.length > 0) {
|
|
7919
|
-
const Y = $Y(db); // Get the Yjs library from Dexie constructor options
|
|
7920
|
-
const mergedUpdate = Y.mergeUpdatesV2(serverUpdatesSinceLastSync.map((update) => update.u));
|
|
7921
|
-
const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);
|
|
7922
|
-
docOpenMsg.sv = stateVector;
|
|
7923
|
-
}
|
|
7924
|
-
db.messageProducer.next(docOpenMsg);
|
|
7925
|
-
});
|
|
7926
|
-
}
|
|
7927
|
-
}));
|
|
7928
|
-
};
|
|
7956
|
+
}
|
|
7957
|
+
}))();
|
|
7958
|
+
return awareness;
|
|
7929
7959
|
}
|
|
7930
7960
|
|
|
7931
7961
|
const DEFAULT_OPTIONS = {
|
|
@@ -7968,7 +7998,7 @@
|
|
|
7968
7998
|
const syncComplete = new rxjs.Subject();
|
|
7969
7999
|
dexie.cloud = {
|
|
7970
8000
|
// @ts-ignore
|
|
7971
|
-
version: "4.1.0-alpha.
|
|
8001
|
+
version: "4.1.0-alpha.12",
|
|
7972
8002
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
7973
8003
|
schema: null,
|
|
7974
8004
|
get currentUserId() {
|
|
@@ -8270,7 +8300,7 @@
|
|
|
8270
8300
|
}
|
|
8271
8301
|
}
|
|
8272
8302
|
// @ts-ignore
|
|
8273
|
-
dexieCloud.version = "4.1.0-alpha.
|
|
8303
|
+
dexieCloud.version = "4.1.0-alpha.12";
|
|
8274
8304
|
Dexie.Cloud = dexieCloud;
|
|
8275
8305
|
|
|
8276
8306
|
// In case the SW lives for a while, let it reuse already opened connections:
|