dexie-cloud-addon 4.1.0-alpha.10 → 4.1.0-alpha.13
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/DexieCloudOptions.d.ts +3 -0
- 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 +406 -133
- 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 +251 -130
- 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/DexieCloudOptions.d.ts +3 -0
- 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 +405 -131
- 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 +250 -129
- 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.13, Thu Oct 17 2024
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import Dexie, { PropModification, cmp, DexieYProvider, liveQuery } from 'dexie';
|
|
19
|
+
import Dexie, { PropModification, cmp, DexieYProvider, RangeSet, liveQuery } from 'dexie';
|
|
20
20
|
import { Observable as Observable$1, BehaviorSubject, firstValueFrom, Subject, from as from$1, filter as filter$1, fromEvent, of, merge, switchMap as switchMap$1, tap as tap$1, mergeMap as mergeMap$1, Subscription as Subscription$1, throwError, combineLatest, map as map$1, share, timer as timer$1 } from 'rxjs';
|
|
21
21
|
|
|
22
22
|
/******************************************************************************
|
|
@@ -4752,6 +4752,7 @@ function getUpdatesTable(db, table, ydocProp) {
|
|
|
4752
4752
|
}
|
|
4753
4753
|
|
|
4754
4754
|
function applyYServerMessages(yMessages, db) {
|
|
4755
|
+
var _a;
|
|
4755
4756
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4756
4757
|
const result = {};
|
|
4757
4758
|
for (const m of yMessages) {
|
|
@@ -4783,7 +4784,24 @@ function applyYServerMessages(yMessages, db) {
|
|
|
4783
4784
|
// See my question in https://discuss.yjs.dev/t/generate-an-inverse-update/2765
|
|
4784
4785
|
console.debug(`Y update rejected. Deleting it.`);
|
|
4785
4786
|
const utbl = getUpdatesTable(db, m.table, m.prop);
|
|
4786
|
-
|
|
4787
|
+
// Delete the rejected update and all local updates since (avoid holes in the CRDT)
|
|
4788
|
+
// and destroy it's open document if there is one.
|
|
4789
|
+
const primaryKey = (_a = (yield utbl.get(m.i))) === null || _a === void 0 ? void 0 : _a.k;
|
|
4790
|
+
if (primaryKey != null) {
|
|
4791
|
+
yield db.transaction('rw', utbl, tx => {
|
|
4792
|
+
// @ts-ignore
|
|
4793
|
+
tx.idbtrans._rejecting_y_ypdate = true; // Inform ydoc triggers that we delete because of a rejection and not GC
|
|
4794
|
+
return utbl
|
|
4795
|
+
.where('i')
|
|
4796
|
+
.aboveOrEqual(m.i)
|
|
4797
|
+
.filter(u => cmp(u.k, primaryKey) === 0 && ((u.f || 0) & 1) === 1)
|
|
4798
|
+
.delete();
|
|
4799
|
+
});
|
|
4800
|
+
// Destroy active doc
|
|
4801
|
+
const activeDoc = DexieYProvider.getDocCache(db.dx).find(m.table, primaryKey, m.prop);
|
|
4802
|
+
if (activeDoc)
|
|
4803
|
+
activeDoc.destroy(); // Destroy the document so that editors don't continue to work on it
|
|
4804
|
+
}
|
|
4787
4805
|
break;
|
|
4788
4806
|
}
|
|
4789
4807
|
case 'in-sync': {
|
|
@@ -6303,8 +6321,7 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
|
|
|
6303
6321
|
outstandingTransactions.next(outstandingTransactions.value);
|
|
6304
6322
|
};
|
|
6305
6323
|
const txComplete = () => {
|
|
6306
|
-
if (tx.mutationsAdded &&
|
|
6307
|
-
!isEagerSyncDisabled(db)) {
|
|
6324
|
+
if (tx.mutationsAdded && !isEagerSyncDisabled(db)) {
|
|
6308
6325
|
triggerSync(db, 'push');
|
|
6309
6326
|
}
|
|
6310
6327
|
removeTransaction();
|
|
@@ -6386,26 +6403,107 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
|
|
|
6386
6403
|
: mutateAndLog(req);
|
|
6387
6404
|
} }));
|
|
6388
6405
|
function mutateAndLog(req) {
|
|
6406
|
+
var _a, _b;
|
|
6389
6407
|
const trans = req.trans;
|
|
6390
|
-
|
|
6408
|
+
const unsyncedProps = (_b = (_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.unsyncedProperties) === null || _b === void 0 ? void 0 : _b[tableName];
|
|
6391
6409
|
const { txid, currentUser: { userId }, } = trans;
|
|
6392
6410
|
const { type } = req;
|
|
6393
6411
|
const opNo = ++trans.opCount;
|
|
6412
|
+
function stripChangeSpec(changeSpec) {
|
|
6413
|
+
if (!unsyncedProps)
|
|
6414
|
+
return changeSpec;
|
|
6415
|
+
let rv = changeSpec;
|
|
6416
|
+
for (const keyPath of Object.keys(changeSpec)) {
|
|
6417
|
+
if (unsyncedProps.some((p) => keyPath === p || keyPath.startsWith(p + '.'))) {
|
|
6418
|
+
if (rv === changeSpec)
|
|
6419
|
+
rv = Object.assign({}, changeSpec); // clone on demand
|
|
6420
|
+
delete rv[keyPath];
|
|
6421
|
+
}
|
|
6422
|
+
}
|
|
6423
|
+
return rv;
|
|
6424
|
+
}
|
|
6394
6425
|
return table.mutate(req).then((res) => {
|
|
6426
|
+
var _a;
|
|
6395
6427
|
const { numFailures: hasFailures, failures } = res;
|
|
6396
6428
|
let keys = type === 'delete' ? req.keys : res.results;
|
|
6397
6429
|
let values = 'values' in req ? req.values : [];
|
|
6398
|
-
let
|
|
6430
|
+
let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;
|
|
6431
|
+
let updates = 'updates' in req ? req.updates : undefined;
|
|
6399
6432
|
if (hasFailures) {
|
|
6400
6433
|
keys = keys.filter((_, idx) => !failures[idx]);
|
|
6401
6434
|
values = values.filter((_, idx) => !failures[idx]);
|
|
6402
6435
|
}
|
|
6436
|
+
if (unsyncedProps) {
|
|
6437
|
+
// Filter out unsynced properties
|
|
6438
|
+
values = values.map((value) => {
|
|
6439
|
+
const newValue = Object.assign({}, value);
|
|
6440
|
+
for (const prop of unsyncedProps) {
|
|
6441
|
+
delete newValue[prop];
|
|
6442
|
+
}
|
|
6443
|
+
return newValue;
|
|
6444
|
+
});
|
|
6445
|
+
if (changeSpec) {
|
|
6446
|
+
// modify operation with criteria and changeSpec.
|
|
6447
|
+
// We must strip out unsynced properties from changeSpec.
|
|
6448
|
+
// We deal with criteria later.
|
|
6449
|
+
changeSpec = stripChangeSpec(changeSpec);
|
|
6450
|
+
if (Object.keys(changeSpec).length === 0) {
|
|
6451
|
+
// Nothing to change on server
|
|
6452
|
+
return res;
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6455
|
+
if (updates) {
|
|
6456
|
+
let strippedChangeSpecs = updates.changeSpecs.map(stripChangeSpec);
|
|
6457
|
+
let newUpdates = {
|
|
6458
|
+
keys: [],
|
|
6459
|
+
changeSpecs: [],
|
|
6460
|
+
};
|
|
6461
|
+
const validKeys = new RangeSet();
|
|
6462
|
+
let anyChangeSpecBecameEmpty = false;
|
|
6463
|
+
for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {
|
|
6464
|
+
if (Object.keys(strippedChangeSpecs[i]).length > 0) {
|
|
6465
|
+
newUpdates.keys.push(updates.keys[i]);
|
|
6466
|
+
newUpdates.changeSpecs.push(strippedChangeSpecs[i]);
|
|
6467
|
+
validKeys.addKey(updates.keys[i]);
|
|
6468
|
+
}
|
|
6469
|
+
else {
|
|
6470
|
+
anyChangeSpecBecameEmpty = true;
|
|
6471
|
+
}
|
|
6472
|
+
}
|
|
6473
|
+
updates = newUpdates;
|
|
6474
|
+
if (anyChangeSpecBecameEmpty) {
|
|
6475
|
+
// Some keys were stripped. We must also strip them from keys and values
|
|
6476
|
+
let newKeys = [];
|
|
6477
|
+
let newValues = [];
|
|
6478
|
+
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
6479
|
+
if (validKeys.hasKey(keys[i])) {
|
|
6480
|
+
newKeys.push(keys[i]);
|
|
6481
|
+
newValues.push(values[i]);
|
|
6482
|
+
}
|
|
6483
|
+
}
|
|
6484
|
+
keys = newKeys;
|
|
6485
|
+
values = newValues;
|
|
6486
|
+
}
|
|
6487
|
+
}
|
|
6488
|
+
}
|
|
6403
6489
|
const ts = Date.now();
|
|
6404
6490
|
// Canonicalize req.criteria.index to null if it's on the primary key.
|
|
6405
|
-
|
|
6491
|
+
let criteria = 'criteria' in req && req.criteria
|
|
6406
6492
|
? Object.assign(Object.assign({}, req.criteria), { index: req.criteria.index === schema.primaryKey.keyPath // Use null to inform server that criteria is on primary key
|
|
6407
6493
|
? null // This will disable the server from trying to log consistent operations where it shouldnt.
|
|
6408
6494
|
: req.criteria.index }) : undefined;
|
|
6495
|
+
if (unsyncedProps && (criteria === null || criteria === void 0 ? void 0 : criteria.index)) {
|
|
6496
|
+
const keyPaths = (_a = schema.indexes.find((idx) => idx.name === criteria.index)) === null || _a === void 0 ? void 0 : _a.keyPath;
|
|
6497
|
+
const involvedProps = keyPaths
|
|
6498
|
+
? typeof keyPaths === 'string'
|
|
6499
|
+
? [keyPaths]
|
|
6500
|
+
: keyPaths
|
|
6501
|
+
: [];
|
|
6502
|
+
if (involvedProps.some((p) => unsyncedProps === null || unsyncedProps === void 0 ? void 0 : unsyncedProps.includes(p))) {
|
|
6503
|
+
// Don't log criteria on unsynced properties as the server could not test them.
|
|
6504
|
+
criteria = undefined;
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6409
6507
|
const mut = req.type === 'delete'
|
|
6410
6508
|
? {
|
|
6411
6509
|
type: 'delete',
|
|
@@ -6426,7 +6524,7 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
|
|
|
6426
6524
|
userId,
|
|
6427
6525
|
values,
|
|
6428
6526
|
}
|
|
6429
|
-
: criteria &&
|
|
6527
|
+
: criteria && changeSpec
|
|
6430
6528
|
? {
|
|
6431
6529
|
// Common changeSpec for all keys
|
|
6432
6530
|
type: 'modify',
|
|
@@ -6434,30 +6532,41 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
|
|
|
6434
6532
|
opNo,
|
|
6435
6533
|
keys,
|
|
6436
6534
|
criteria,
|
|
6437
|
-
changeSpec
|
|
6535
|
+
changeSpec,
|
|
6438
6536
|
txid,
|
|
6439
6537
|
userId,
|
|
6440
6538
|
}
|
|
6441
|
-
:
|
|
6539
|
+
: changeSpec
|
|
6442
6540
|
? {
|
|
6443
|
-
//
|
|
6541
|
+
// In case criteria involved an unsynced property, we go for keys instead.
|
|
6444
6542
|
type: 'update',
|
|
6445
6543
|
ts,
|
|
6446
6544
|
opNo,
|
|
6447
|
-
keys: updates.keys,
|
|
6448
|
-
changeSpecs: updates.changeSpecs,
|
|
6449
|
-
txid,
|
|
6450
|
-
userId,
|
|
6451
|
-
}
|
|
6452
|
-
: {
|
|
6453
|
-
type: 'upsert',
|
|
6454
|
-
ts,
|
|
6455
|
-
opNo,
|
|
6456
6545
|
keys,
|
|
6457
|
-
|
|
6546
|
+
changeSpecs: keys.map(() => changeSpec),
|
|
6458
6547
|
txid,
|
|
6459
6548
|
userId,
|
|
6460
|
-
}
|
|
6549
|
+
}
|
|
6550
|
+
: updates
|
|
6551
|
+
? {
|
|
6552
|
+
// One changeSpec per key
|
|
6553
|
+
type: 'update',
|
|
6554
|
+
ts,
|
|
6555
|
+
opNo,
|
|
6556
|
+
keys: updates.keys,
|
|
6557
|
+
changeSpecs: updates.changeSpecs,
|
|
6558
|
+
txid,
|
|
6559
|
+
userId,
|
|
6560
|
+
}
|
|
6561
|
+
: {
|
|
6562
|
+
type: 'upsert',
|
|
6563
|
+
ts,
|
|
6564
|
+
opNo,
|
|
6565
|
+
keys,
|
|
6566
|
+
values,
|
|
6567
|
+
txid,
|
|
6568
|
+
userId,
|
|
6569
|
+
};
|
|
6461
6570
|
if ('isAdditionalChunk' in req && req.isAdditionalChunk) {
|
|
6462
6571
|
mut.isAdditionalChunk = true;
|
|
6463
6572
|
}
|
|
@@ -7804,125 +7913,137 @@ const getInvitesObservable = associate((db) => {
|
|
|
7804
7913
|
function createYHandler(db) {
|
|
7805
7914
|
return (provider) => {
|
|
7806
7915
|
var _a;
|
|
7807
|
-
const awap = getAwarenessLibrary(db);
|
|
7808
7916
|
const doc = provider.doc;
|
|
7809
|
-
const { parentTable
|
|
7917
|
+
const { parentTable } = doc.meta || {};
|
|
7810
7918
|
if (!((_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[parentTable].markedForSync)) {
|
|
7811
7919
|
return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.
|
|
7812
7920
|
}
|
|
7813
|
-
let awareness
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7921
|
+
let awareness;
|
|
7922
|
+
Object.defineProperty(provider, "awareness", {
|
|
7923
|
+
get() {
|
|
7924
|
+
if (awareness)
|
|
7925
|
+
return awareness;
|
|
7926
|
+
awarenessWeakMap.set(doc, awareness);
|
|
7927
|
+
awareness = createAwareness(db, doc, provider);
|
|
7928
|
+
return awareness;
|
|
7929
|
+
}
|
|
7930
|
+
});
|
|
7931
|
+
};
|
|
7932
|
+
}
|
|
7933
|
+
function createAwareness(db, doc, provider) {
|
|
7934
|
+
const { parentTable, parentId, parentProp, updatesTable } = doc.meta;
|
|
7935
|
+
const awap = getAwarenessLibrary(db);
|
|
7936
|
+
const awareness = new awap.Awareness(doc);
|
|
7937
|
+
awareness.on('update', ({ added, updated, removed }, origin) => {
|
|
7938
|
+
// Send the update
|
|
7939
|
+
const changedClients = added.concat(updated).concat(removed);
|
|
7940
|
+
const user = db.cloud.currentUser.value;
|
|
7941
|
+
if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7942
|
+
const update = awap.encodeAwarenessUpdate(awareness, changedClients);
|
|
7943
|
+
db.messageProducer.next({
|
|
7944
|
+
type: 'aware',
|
|
7945
|
+
table: parentTable,
|
|
7946
|
+
prop: parentProp,
|
|
7947
|
+
k: doc.meta.parentId,
|
|
7948
|
+
u: update,
|
|
7949
|
+
});
|
|
7950
|
+
if (provider.destroyed) {
|
|
7951
|
+
// We're called from awareness.on('destroy') that did
|
|
7952
|
+
// removeAwarenessStates.
|
|
7953
|
+
// It's time to also send the doc-close message that dexie-cloud understands
|
|
7954
|
+
// and uses to stop subscribing for updates and awareness updates and brings
|
|
7955
|
+
// down the cached information in memory on the WS connection for this.
|
|
7822
7956
|
db.messageProducer.next({
|
|
7823
|
-
type: '
|
|
7957
|
+
type: 'doc-close',
|
|
7824
7958
|
table: parentTable,
|
|
7825
7959
|
prop: parentProp,
|
|
7826
|
-
k: doc.meta.parentId
|
|
7827
|
-
u: update,
|
|
7960
|
+
k: doc.meta.parentId
|
|
7828
7961
|
});
|
|
7829
|
-
if (provider.destroyed) {
|
|
7830
|
-
// We're called from awareness.on('destroy') that did
|
|
7831
|
-
// removeAwarenessStates.
|
|
7832
|
-
// It's time to also send the doc-close message that dexie-cloud understands
|
|
7833
|
-
// and uses to stop subscribing for updates and awareness updates and brings
|
|
7834
|
-
// down the cached information in memory on the WS connection for this.
|
|
7835
|
-
db.messageProducer.next({
|
|
7836
|
-
type: 'doc-close',
|
|
7837
|
-
table: parentTable,
|
|
7838
|
-
prop: parentProp,
|
|
7839
|
-
k: doc.meta.parentId
|
|
7840
|
-
});
|
|
7841
|
-
}
|
|
7842
7962
|
}
|
|
7843
|
-
}
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7963
|
+
}
|
|
7964
|
+
});
|
|
7965
|
+
awareness.on('destroy', () => {
|
|
7966
|
+
// Signal to server that this provider is destroyed (the update event will be triggered, which
|
|
7967
|
+
// in turn will trigger db.messageProducer that will send the message to the server if WS is connected)
|
|
7968
|
+
awap.removeAwarenessStates(awareness, [doc.clientID], 'provider destroyed');
|
|
7969
|
+
});
|
|
7970
|
+
// Open the document on the server
|
|
7971
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
7972
|
+
if (provider.destroyed)
|
|
7973
|
+
return;
|
|
7974
|
+
let connected = false;
|
|
7975
|
+
let currentFlowId = 1;
|
|
7976
|
+
const subscription = db.cloud.webSocketStatus.subscribe((wsStatus) => {
|
|
7851
7977
|
if (provider.destroyed)
|
|
7852
7978
|
return;
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7979
|
+
// Keep "connected" state in a variable so we can check it after async operations
|
|
7980
|
+
connected = wsStatus === 'connected';
|
|
7981
|
+
// We are or got connected. Open the document on the server.
|
|
7982
|
+
const user = db.cloud.currentUser.value;
|
|
7983
|
+
if (wsStatus === "connected" && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
7984
|
+
++currentFlowId;
|
|
7985
|
+
openDocumentOnServer().catch(error => {
|
|
7986
|
+
console.warn(`Error catched in createYHandler.ts: ${error}`);
|
|
7987
|
+
});
|
|
7988
|
+
}
|
|
7989
|
+
});
|
|
7990
|
+
// Wait until WebSocket is connected
|
|
7991
|
+
provider.addCleanupHandler(subscription);
|
|
7992
|
+
/** Sends an 'doc-open' message to server whenever websocket becomes
|
|
7993
|
+
* connected, or if it is already connected.
|
|
7994
|
+
* The flow is aborted in case websocket is disconnected while querying
|
|
7995
|
+
* information required to compute the state vector. Flow is also
|
|
7996
|
+
* aborted in case document or provider has been destroyed during
|
|
7997
|
+
* the async parts of the task.
|
|
7998
|
+
*
|
|
7999
|
+
* The state vector is only computed from the updates that have occured
|
|
8000
|
+
* after the last full sync - which could very often be zero - in which
|
|
8001
|
+
* case no state vector is sent (then the server already knows us by
|
|
8002
|
+
* revision)
|
|
8003
|
+
*
|
|
8004
|
+
* When server gets the doc-open message, it will authorized us for
|
|
8005
|
+
* whether we are allowed to read / write to this document, and then
|
|
8006
|
+
* keep the cached information in memory on the WS connection for this
|
|
8007
|
+
* particular document, as well as subscribe to updates and awareness updates
|
|
8008
|
+
* from other clients on the document.
|
|
8009
|
+
*/
|
|
8010
|
+
function openDocumentOnServer(wsStatus) {
|
|
8011
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8012
|
+
const myFlow = currentFlowId; // So we can abort when a new flow is started
|
|
8013
|
+
const yTbl = db.table(updatesTable);
|
|
8014
|
+
const syncState = yield yTbl.get(DEXIE_CLOUD_SYNCER_ID);
|
|
8015
|
+
// After every await, check if we still should be working on this task.
|
|
8016
|
+
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7857
8017
|
return;
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
8018
|
+
const receivedUntil = (syncState === null || syncState === void 0 ? void 0 : syncState.receivedUntil) || 0;
|
|
8019
|
+
const docOpenMsg = {
|
|
8020
|
+
type: 'doc-open',
|
|
8021
|
+
table: parentTable,
|
|
8022
|
+
prop: parentProp,
|
|
8023
|
+
k: parentId,
|
|
8024
|
+
serverRev: syncState === null || syncState === void 0 ? void 0 : syncState.serverRev,
|
|
8025
|
+
};
|
|
8026
|
+
const serverUpdatesSinceLastSync = yield yTbl
|
|
8027
|
+
.where('i')
|
|
8028
|
+
.between(receivedUntil, Infinity, false)
|
|
8029
|
+
.filter((update) => cmp(update.k, parentId) === 0 && // Only updates for this document
|
|
8030
|
+
((update.f || 0) & 1) === 0 // Don't include local changes
|
|
8031
|
+
)
|
|
8032
|
+
.toArray();
|
|
8033
|
+
// After every await, check if we still should be working on this task.
|
|
8034
|
+
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
8035
|
+
return;
|
|
8036
|
+
if (serverUpdatesSinceLastSync.length > 0) {
|
|
8037
|
+
const Y = $Y(db); // Get the Yjs library from Dexie constructor options
|
|
8038
|
+
const mergedUpdate = Y.mergeUpdatesV2(serverUpdatesSinceLastSync.map((update) => update.u));
|
|
8039
|
+
const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);
|
|
8040
|
+
docOpenMsg.sv = stateVector;
|
|
7867
8041
|
}
|
|
8042
|
+
db.messageProducer.next(docOpenMsg);
|
|
7868
8043
|
});
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
* connected, or if it is already connected.
|
|
7873
|
-
* The flow is aborted in case websocket is disconnected while querying
|
|
7874
|
-
* information required to compute the state vector. Flow is also
|
|
7875
|
-
* aborted in case document or provider has been destroyed during
|
|
7876
|
-
* the async parts of the task.
|
|
7877
|
-
*
|
|
7878
|
-
* The state vector is only computed from the updates that have occured
|
|
7879
|
-
* after the last full sync - which could very often be zero - in which
|
|
7880
|
-
* case no state vector is sent (then the server already knows us by
|
|
7881
|
-
* revision)
|
|
7882
|
-
*
|
|
7883
|
-
* When server gets the doc-open message, it will authorized us for
|
|
7884
|
-
* whether we are allowed to read / write to this document, and then
|
|
7885
|
-
* keep the cached information in memory on the WS connection for this
|
|
7886
|
-
* particular document, as well as subscribe to updates and awareness updates
|
|
7887
|
-
* from other clients on the document.
|
|
7888
|
-
*/
|
|
7889
|
-
function openDocumentOnServer(wsStatus) {
|
|
7890
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7891
|
-
const myFlow = currentFlowId; // So we can abort when a new flow is started
|
|
7892
|
-
const yTbl = db.table(updatesTable);
|
|
7893
|
-
const syncState = yield yTbl.get(DEXIE_CLOUD_SYNCER_ID);
|
|
7894
|
-
// After every await, check if we still should be working on this task.
|
|
7895
|
-
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7896
|
-
return;
|
|
7897
|
-
const receivedUntil = (syncState === null || syncState === void 0 ? void 0 : syncState.receivedUntil) || 0;
|
|
7898
|
-
const docOpenMsg = {
|
|
7899
|
-
type: 'doc-open',
|
|
7900
|
-
table: parentTable,
|
|
7901
|
-
prop: parentProp,
|
|
7902
|
-
k: parentId,
|
|
7903
|
-
serverRev: syncState === null || syncState === void 0 ? void 0 : syncState.serverRev,
|
|
7904
|
-
};
|
|
7905
|
-
const serverUpdatesSinceLastSync = yield yTbl
|
|
7906
|
-
.where('i')
|
|
7907
|
-
.between(receivedUntil, Infinity, false)
|
|
7908
|
-
.filter((update) => cmp(update.k, parentId) === 0 && // Only updates for this document
|
|
7909
|
-
((update.f || 0) & 1) === 0 // Don't include local changes
|
|
7910
|
-
)
|
|
7911
|
-
.toArray();
|
|
7912
|
-
// After every await, check if we still should be working on this task.
|
|
7913
|
-
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
7914
|
-
return;
|
|
7915
|
-
if (serverUpdatesSinceLastSync.length > 0) {
|
|
7916
|
-
const Y = $Y(db); // Get the Yjs library from Dexie constructor options
|
|
7917
|
-
const mergedUpdate = Y.mergeUpdatesV2(serverUpdatesSinceLastSync.map((update) => update.u));
|
|
7918
|
-
const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);
|
|
7919
|
-
docOpenMsg.sv = stateVector;
|
|
7920
|
-
}
|
|
7921
|
-
db.messageProducer.next(docOpenMsg);
|
|
7922
|
-
});
|
|
7923
|
-
}
|
|
7924
|
-
}));
|
|
7925
|
-
};
|
|
8044
|
+
}
|
|
8045
|
+
}))();
|
|
8046
|
+
return awareness;
|
|
7926
8047
|
}
|
|
7927
8048
|
|
|
7928
8049
|
const DEFAULT_OPTIONS = {
|
|
@@ -7965,7 +8086,7 @@ function dexieCloud(dexie) {
|
|
|
7965
8086
|
const syncComplete = new Subject();
|
|
7966
8087
|
dexie.cloud = {
|
|
7967
8088
|
// @ts-ignore
|
|
7968
|
-
version: "4.1.0-alpha.
|
|
8089
|
+
version: "4.1.0-alpha.13",
|
|
7969
8090
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
7970
8091
|
schema: null,
|
|
7971
8092
|
get currentUserId() {
|
|
@@ -8267,7 +8388,7 @@ function dexieCloud(dexie) {
|
|
|
8267
8388
|
}
|
|
8268
8389
|
}
|
|
8269
8390
|
// @ts-ignore
|
|
8270
|
-
dexieCloud.version = "4.1.0-alpha.
|
|
8391
|
+
dexieCloud.version = "4.1.0-alpha.13";
|
|
8271
8392
|
Dexie.Cloud = dexieCloud;
|
|
8272
8393
|
|
|
8273
8394
|
// In case the SW lives for a while, let it reuse already opened connections:
|