dexie-cloud-addon 4.2.0-alpha.4 → 4.2.0-alpha.6
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 +4 -12
- 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 +4 -12
- 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/awareness.d.ts +3 -4
- package/dist/umd/dexie-cloud-addon.js +457 -21
- 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 +457 -21
- 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/awareness.d.ts +3 -4
- package/package.json +2 -2
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.2.0-alpha.
|
|
11
|
+
* Version 4.2.0-alpha.6, Fri Aug 01 2025
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -930,7 +930,7 @@
|
|
|
930
930
|
* @param {Encoder} encoder
|
|
931
931
|
* @return {number}
|
|
932
932
|
*/
|
|
933
|
-
const length$
|
|
933
|
+
const length$2 = encoder => {
|
|
934
934
|
let len = encoder.cpos;
|
|
935
935
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
936
936
|
len += encoder.bufs[i].length;
|
|
@@ -946,7 +946,7 @@
|
|
|
946
946
|
* @return {Uint8Array} The created ArrayBuffer.
|
|
947
947
|
*/
|
|
948
948
|
const toUint8Array$1 = encoder => {
|
|
949
|
-
const uint8arr = new Uint8Array(length$
|
|
949
|
+
const uint8arr = new Uint8Array(length$2(encoder));
|
|
950
950
|
let curPos = 0;
|
|
951
951
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
952
952
|
const d = encoder.bufs[i];
|
|
@@ -3443,6 +3443,78 @@
|
|
|
3443
3443
|
this._observers = create$5();
|
|
3444
3444
|
}
|
|
3445
3445
|
}
|
|
3446
|
+
|
|
3447
|
+
/* c8 ignore start */
|
|
3448
|
+
/**
|
|
3449
|
+
* Handles named events.
|
|
3450
|
+
*
|
|
3451
|
+
* @deprecated
|
|
3452
|
+
* @template N
|
|
3453
|
+
*/
|
|
3454
|
+
class Observable {
|
|
3455
|
+
constructor () {
|
|
3456
|
+
/**
|
|
3457
|
+
* Some desc.
|
|
3458
|
+
* @type {Map<N, any>}
|
|
3459
|
+
*/
|
|
3460
|
+
this._observers = create$5();
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
/**
|
|
3464
|
+
* @param {N} name
|
|
3465
|
+
* @param {function} f
|
|
3466
|
+
*/
|
|
3467
|
+
on (name, f) {
|
|
3468
|
+
setIfUndefined(this._observers, name, create$4).add(f);
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3471
|
+
/**
|
|
3472
|
+
* @param {N} name
|
|
3473
|
+
* @param {function} f
|
|
3474
|
+
*/
|
|
3475
|
+
once (name, f) {
|
|
3476
|
+
/**
|
|
3477
|
+
* @param {...any} args
|
|
3478
|
+
*/
|
|
3479
|
+
const _f = (...args) => {
|
|
3480
|
+
this.off(name, _f);
|
|
3481
|
+
f(...args);
|
|
3482
|
+
};
|
|
3483
|
+
this.on(name, _f);
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
/**
|
|
3487
|
+
* @param {N} name
|
|
3488
|
+
* @param {function} f
|
|
3489
|
+
*/
|
|
3490
|
+
off (name, f) {
|
|
3491
|
+
const observers = this._observers.get(name);
|
|
3492
|
+
if (observers !== undefined) {
|
|
3493
|
+
observers.delete(f);
|
|
3494
|
+
if (observers.size === 0) {
|
|
3495
|
+
this._observers.delete(name);
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
/**
|
|
3501
|
+
* Emit a named event. All registered event listeners that listen to the
|
|
3502
|
+
* specified name will receive the event.
|
|
3503
|
+
*
|
|
3504
|
+
* @todo This should catch exceptions
|
|
3505
|
+
*
|
|
3506
|
+
* @param {N} name The event name.
|
|
3507
|
+
* @param {Array<any>} args The arguments that are applied to the event listener.
|
|
3508
|
+
*/
|
|
3509
|
+
emit (name, args) {
|
|
3510
|
+
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
3511
|
+
return from((this._observers.get(name) || create$5()).values()).forEach(f => f(...args))
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
destroy () {
|
|
3515
|
+
this._observers = create$5();
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3446
3518
|
/* c8 ignore end */
|
|
3447
3519
|
|
|
3448
3520
|
/**
|
|
@@ -3639,7 +3711,7 @@
|
|
|
3639
3711
|
* @param {Encoder} encoder
|
|
3640
3712
|
* @return {number}
|
|
3641
3713
|
*/
|
|
3642
|
-
const length = encoder => {
|
|
3714
|
+
const length$1 = encoder => {
|
|
3643
3715
|
let len = encoder.cpos;
|
|
3644
3716
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
3645
3717
|
len += encoder.bufs[i].length;
|
|
@@ -3655,7 +3727,7 @@
|
|
|
3655
3727
|
* @return {Uint8Array} The created ArrayBuffer.
|
|
3656
3728
|
*/
|
|
3657
3729
|
const toUint8Array = encoder => {
|
|
3658
|
-
const uint8arr = new Uint8Array(length(encoder));
|
|
3730
|
+
const uint8arr = new Uint8Array(length$1(encoder));
|
|
3659
3731
|
let curPos = 0;
|
|
3660
3732
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
3661
3733
|
const d = encoder.bufs[i];
|
|
@@ -4713,6 +4785,20 @@
|
|
|
4713
4785
|
(c ^ uint32() & 15 >> c / 4).toString(16)
|
|
4714
4786
|
);
|
|
4715
4787
|
|
|
4788
|
+
/**
|
|
4789
|
+
* Utility module to work with time.
|
|
4790
|
+
*
|
|
4791
|
+
* @module time
|
|
4792
|
+
*/
|
|
4793
|
+
|
|
4794
|
+
|
|
4795
|
+
/**
|
|
4796
|
+
* Return current unix time.
|
|
4797
|
+
*
|
|
4798
|
+
* @return {number}
|
|
4799
|
+
*/
|
|
4800
|
+
const getUnixTime = Date.now;
|
|
4801
|
+
|
|
4716
4802
|
/**
|
|
4717
4803
|
* Utility helpers to work with promises.
|
|
4718
4804
|
*
|
|
@@ -4839,6 +4925,13 @@
|
|
|
4839
4925
|
}
|
|
4840
4926
|
};
|
|
4841
4927
|
|
|
4928
|
+
/**
|
|
4929
|
+
* @deprecated use object.size instead
|
|
4930
|
+
* @param {Object<string,any>} obj
|
|
4931
|
+
* @return {number}
|
|
4932
|
+
*/
|
|
4933
|
+
const length = obj => keys(obj).length;
|
|
4934
|
+
|
|
4842
4935
|
/**
|
|
4843
4936
|
* @param {Object<string,any>} obj
|
|
4844
4937
|
* @return {number}
|
|
@@ -4935,6 +5028,96 @@
|
|
|
4935
5028
|
}
|
|
4936
5029
|
};
|
|
4937
5030
|
|
|
5031
|
+
/**
|
|
5032
|
+
* @template T
|
|
5033
|
+
*
|
|
5034
|
+
* @param {T} a
|
|
5035
|
+
* @param {T} b
|
|
5036
|
+
* @return {boolean}
|
|
5037
|
+
*/
|
|
5038
|
+
const equalityStrict = (a, b) => a === b;
|
|
5039
|
+
|
|
5040
|
+
/* c8 ignore start */
|
|
5041
|
+
|
|
5042
|
+
/**
|
|
5043
|
+
* @param {any} a
|
|
5044
|
+
* @param {any} b
|
|
5045
|
+
* @return {boolean}
|
|
5046
|
+
*/
|
|
5047
|
+
const equalityDeep = (a, b) => {
|
|
5048
|
+
if (a == null || b == null) {
|
|
5049
|
+
return equalityStrict(a, b)
|
|
5050
|
+
}
|
|
5051
|
+
if (a.constructor !== b.constructor) {
|
|
5052
|
+
return false
|
|
5053
|
+
}
|
|
5054
|
+
if (a === b) {
|
|
5055
|
+
return true
|
|
5056
|
+
}
|
|
5057
|
+
switch (a.constructor) {
|
|
5058
|
+
case ArrayBuffer:
|
|
5059
|
+
a = new Uint8Array(a);
|
|
5060
|
+
b = new Uint8Array(b);
|
|
5061
|
+
// eslint-disable-next-line no-fallthrough
|
|
5062
|
+
case Uint8Array: {
|
|
5063
|
+
if (a.byteLength !== b.byteLength) {
|
|
5064
|
+
return false
|
|
5065
|
+
}
|
|
5066
|
+
for (let i = 0; i < a.length; i++) {
|
|
5067
|
+
if (a[i] !== b[i]) {
|
|
5068
|
+
return false
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
5071
|
+
break
|
|
5072
|
+
}
|
|
5073
|
+
case Set: {
|
|
5074
|
+
if (a.size !== b.size) {
|
|
5075
|
+
return false
|
|
5076
|
+
}
|
|
5077
|
+
for (const value of a) {
|
|
5078
|
+
if (!b.has(value)) {
|
|
5079
|
+
return false
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
break
|
|
5083
|
+
}
|
|
5084
|
+
case Map: {
|
|
5085
|
+
if (a.size !== b.size) {
|
|
5086
|
+
return false
|
|
5087
|
+
}
|
|
5088
|
+
for (const key of a.keys()) {
|
|
5089
|
+
if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) {
|
|
5090
|
+
return false
|
|
5091
|
+
}
|
|
5092
|
+
}
|
|
5093
|
+
break
|
|
5094
|
+
}
|
|
5095
|
+
case Object:
|
|
5096
|
+
if (length(a) !== length(b)) {
|
|
5097
|
+
return false
|
|
5098
|
+
}
|
|
5099
|
+
for (const key in a) {
|
|
5100
|
+
if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) {
|
|
5101
|
+
return false
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5104
|
+
break
|
|
5105
|
+
case Array:
|
|
5106
|
+
if (a.length !== b.length) {
|
|
5107
|
+
return false
|
|
5108
|
+
}
|
|
5109
|
+
for (let i = 0; i < a.length; i++) {
|
|
5110
|
+
if (!equalityDeep(a[i], b[i])) {
|
|
5111
|
+
return false
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
break
|
|
5115
|
+
default:
|
|
5116
|
+
return false
|
|
5117
|
+
}
|
|
5118
|
+
return true
|
|
5119
|
+
};
|
|
5120
|
+
|
|
4938
5121
|
/**
|
|
4939
5122
|
* @template V
|
|
4940
5123
|
* @template {V} OPTS
|
|
@@ -13706,7 +13889,7 @@
|
|
|
13706
13889
|
*
|
|
13707
13890
|
* ==========================================================================
|
|
13708
13891
|
*
|
|
13709
|
-
* Version 4.2.0-alpha.
|
|
13892
|
+
* Version 4.2.0-alpha.6, Fri Aug 01 2025
|
|
13710
13893
|
*
|
|
13711
13894
|
* https://dexie.org
|
|
13712
13895
|
*
|
|
@@ -16189,16 +16372,271 @@
|
|
|
16189
16372
|
rxjs.mergeMap((messages) => messages));
|
|
16190
16373
|
}
|
|
16191
16374
|
|
|
16192
|
-
function getAwarenessLibrary(db) {
|
|
16193
|
-
var _a, _b;
|
|
16194
|
-
if (!((_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.awarenessProtocol)) {
|
|
16195
|
-
throw new Dexie.MissingAPIError('awarenessProtocol was not provided to db.cloud.configure(). Please import * as awarenessProtocol from "y-protocols/awareness".');
|
|
16196
|
-
}
|
|
16197
|
-
return (_b = db.cloud.options) === null || _b === void 0 ? void 0 : _b.awarenessProtocol;
|
|
16198
|
-
}
|
|
16199
16375
|
const awarenessWeakMap = new WeakMap();
|
|
16200
16376
|
const getDocAwareness = (doc) => awarenessWeakMap.get(doc);
|
|
16201
16377
|
|
|
16378
|
+
/**
|
|
16379
|
+
* @module awareness-protocol
|
|
16380
|
+
*/
|
|
16381
|
+
|
|
16382
|
+
|
|
16383
|
+
const outdatedTimeout = 30000;
|
|
16384
|
+
|
|
16385
|
+
/**
|
|
16386
|
+
* @typedef {Object} MetaClientState
|
|
16387
|
+
* @property {number} MetaClientState.clock
|
|
16388
|
+
* @property {number} MetaClientState.lastUpdated unix timestamp
|
|
16389
|
+
*/
|
|
16390
|
+
|
|
16391
|
+
/**
|
|
16392
|
+
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
|
|
16393
|
+
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
|
|
16394
|
+
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
|
|
16395
|
+
*
|
|
16396
|
+
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
|
|
16397
|
+
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
|
|
16398
|
+
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
|
|
16399
|
+
* a remote client is offline, it may propagate a message with
|
|
16400
|
+
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
|
|
16401
|
+
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
|
|
16402
|
+
*
|
|
16403
|
+
* Before a client disconnects, it should propagate a `null` state with an updated clock.
|
|
16404
|
+
*
|
|
16405
|
+
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
|
|
16406
|
+
*
|
|
16407
|
+
* @extends {Observable<string>}
|
|
16408
|
+
*/
|
|
16409
|
+
class Awareness extends Observable {
|
|
16410
|
+
/**
|
|
16411
|
+
* @param {Y.Doc} doc
|
|
16412
|
+
*/
|
|
16413
|
+
constructor (doc) {
|
|
16414
|
+
super();
|
|
16415
|
+
this.doc = doc;
|
|
16416
|
+
/**
|
|
16417
|
+
* @type {number}
|
|
16418
|
+
*/
|
|
16419
|
+
this.clientID = doc.clientID;
|
|
16420
|
+
/**
|
|
16421
|
+
* Maps from client id to client state
|
|
16422
|
+
* @type {Map<number, Object<string, any>>}
|
|
16423
|
+
*/
|
|
16424
|
+
this.states = new Map();
|
|
16425
|
+
/**
|
|
16426
|
+
* @type {Map<number, MetaClientState>}
|
|
16427
|
+
*/
|
|
16428
|
+
this.meta = new Map();
|
|
16429
|
+
this._checkInterval = /** @type {any} */ (setInterval(() => {
|
|
16430
|
+
const now = getUnixTime();
|
|
16431
|
+
if (this.getLocalState() !== null && (outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ (this.meta.get(this.clientID)).lastUpdated)) {
|
|
16432
|
+
// renew local clock
|
|
16433
|
+
this.setLocalState(this.getLocalState());
|
|
16434
|
+
}
|
|
16435
|
+
/**
|
|
16436
|
+
* @type {Array<number>}
|
|
16437
|
+
*/
|
|
16438
|
+
const remove = [];
|
|
16439
|
+
this.meta.forEach((meta, clientid) => {
|
|
16440
|
+
if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) {
|
|
16441
|
+
remove.push(clientid);
|
|
16442
|
+
}
|
|
16443
|
+
});
|
|
16444
|
+
if (remove.length > 0) {
|
|
16445
|
+
removeAwarenessStates(this, remove, 'timeout');
|
|
16446
|
+
}
|
|
16447
|
+
}, floor(outdatedTimeout / 10)));
|
|
16448
|
+
doc.on('destroy', () => {
|
|
16449
|
+
this.destroy();
|
|
16450
|
+
});
|
|
16451
|
+
this.setLocalState({});
|
|
16452
|
+
}
|
|
16453
|
+
|
|
16454
|
+
destroy () {
|
|
16455
|
+
this.emit('destroy', [this]);
|
|
16456
|
+
this.setLocalState(null);
|
|
16457
|
+
super.destroy();
|
|
16458
|
+
clearInterval(this._checkInterval);
|
|
16459
|
+
}
|
|
16460
|
+
|
|
16461
|
+
/**
|
|
16462
|
+
* @return {Object<string,any>|null}
|
|
16463
|
+
*/
|
|
16464
|
+
getLocalState () {
|
|
16465
|
+
return this.states.get(this.clientID) || null
|
|
16466
|
+
}
|
|
16467
|
+
|
|
16468
|
+
/**
|
|
16469
|
+
* @param {Object<string,any>|null} state
|
|
16470
|
+
*/
|
|
16471
|
+
setLocalState (state) {
|
|
16472
|
+
const clientID = this.clientID;
|
|
16473
|
+
const currLocalMeta = this.meta.get(clientID);
|
|
16474
|
+
const clock = currLocalMeta === undefined ? 0 : currLocalMeta.clock + 1;
|
|
16475
|
+
const prevState = this.states.get(clientID);
|
|
16476
|
+
if (state === null) {
|
|
16477
|
+
this.states.delete(clientID);
|
|
16478
|
+
} else {
|
|
16479
|
+
this.states.set(clientID, state);
|
|
16480
|
+
}
|
|
16481
|
+
this.meta.set(clientID, {
|
|
16482
|
+
clock,
|
|
16483
|
+
lastUpdated: getUnixTime()
|
|
16484
|
+
});
|
|
16485
|
+
const added = [];
|
|
16486
|
+
const updated = [];
|
|
16487
|
+
const filteredUpdated = [];
|
|
16488
|
+
const removed = [];
|
|
16489
|
+
if (state === null) {
|
|
16490
|
+
removed.push(clientID);
|
|
16491
|
+
} else if (prevState == null) {
|
|
16492
|
+
if (state != null) {
|
|
16493
|
+
added.push(clientID);
|
|
16494
|
+
}
|
|
16495
|
+
} else {
|
|
16496
|
+
updated.push(clientID);
|
|
16497
|
+
if (!equalityDeep(prevState, state)) {
|
|
16498
|
+
filteredUpdated.push(clientID);
|
|
16499
|
+
}
|
|
16500
|
+
}
|
|
16501
|
+
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
|
|
16502
|
+
this.emit('change', [{ added, updated: filteredUpdated, removed }, 'local']);
|
|
16503
|
+
}
|
|
16504
|
+
this.emit('update', [{ added, updated, removed }, 'local']);
|
|
16505
|
+
}
|
|
16506
|
+
|
|
16507
|
+
/**
|
|
16508
|
+
* @param {string} field
|
|
16509
|
+
* @param {any} value
|
|
16510
|
+
*/
|
|
16511
|
+
setLocalStateField (field, value) {
|
|
16512
|
+
const state = this.getLocalState();
|
|
16513
|
+
if (state !== null) {
|
|
16514
|
+
this.setLocalState({
|
|
16515
|
+
...state,
|
|
16516
|
+
[field]: value
|
|
16517
|
+
});
|
|
16518
|
+
}
|
|
16519
|
+
}
|
|
16520
|
+
|
|
16521
|
+
/**
|
|
16522
|
+
* @return {Map<number,Object<string,any>>}
|
|
16523
|
+
*/
|
|
16524
|
+
getStates () {
|
|
16525
|
+
return this.states
|
|
16526
|
+
}
|
|
16527
|
+
}
|
|
16528
|
+
|
|
16529
|
+
/**
|
|
16530
|
+
* Mark (remote) clients as inactive and remove them from the list of active peers.
|
|
16531
|
+
* This change will be propagated to remote clients.
|
|
16532
|
+
*
|
|
16533
|
+
* @param {Awareness} awareness
|
|
16534
|
+
* @param {Array<number>} clients
|
|
16535
|
+
* @param {any} origin
|
|
16536
|
+
*/
|
|
16537
|
+
const removeAwarenessStates = (awareness, clients, origin) => {
|
|
16538
|
+
const removed = [];
|
|
16539
|
+
for (let i = 0; i < clients.length; i++) {
|
|
16540
|
+
const clientID = clients[i];
|
|
16541
|
+
if (awareness.states.has(clientID)) {
|
|
16542
|
+
awareness.states.delete(clientID);
|
|
16543
|
+
if (clientID === awareness.clientID) {
|
|
16544
|
+
const curMeta = /** @type {MetaClientState} */ (awareness.meta.get(clientID));
|
|
16545
|
+
awareness.meta.set(clientID, {
|
|
16546
|
+
clock: curMeta.clock + 1,
|
|
16547
|
+
lastUpdated: getUnixTime()
|
|
16548
|
+
});
|
|
16549
|
+
}
|
|
16550
|
+
removed.push(clientID);
|
|
16551
|
+
}
|
|
16552
|
+
}
|
|
16553
|
+
if (removed.length > 0) {
|
|
16554
|
+
awareness.emit('change', [{ added: [], updated: [], removed }, origin]);
|
|
16555
|
+
awareness.emit('update', [{ added: [], updated: [], removed }, origin]);
|
|
16556
|
+
}
|
|
16557
|
+
};
|
|
16558
|
+
|
|
16559
|
+
/**
|
|
16560
|
+
* @param {Awareness} awareness
|
|
16561
|
+
* @param {Array<number>} clients
|
|
16562
|
+
* @return {Uint8Array}
|
|
16563
|
+
*/
|
|
16564
|
+
const encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => {
|
|
16565
|
+
const len = clients.length;
|
|
16566
|
+
const encoder = createEncoder();
|
|
16567
|
+
writeVarUint(encoder, len);
|
|
16568
|
+
for (let i = 0; i < len; i++) {
|
|
16569
|
+
const clientID = clients[i];
|
|
16570
|
+
const state = states.get(clientID) || null;
|
|
16571
|
+
const clock = /** @type {MetaClientState} */ (awareness.meta.get(clientID)).clock;
|
|
16572
|
+
writeVarUint(encoder, clientID);
|
|
16573
|
+
writeVarUint(encoder, clock);
|
|
16574
|
+
writeVarString(encoder, JSON.stringify(state));
|
|
16575
|
+
}
|
|
16576
|
+
return toUint8Array(encoder)
|
|
16577
|
+
};
|
|
16578
|
+
|
|
16579
|
+
/**
|
|
16580
|
+
* @param {Awareness} awareness
|
|
16581
|
+
* @param {Uint8Array} update
|
|
16582
|
+
* @param {any} origin This will be added to the emitted change event
|
|
16583
|
+
*/
|
|
16584
|
+
const applyAwarenessUpdate = (awareness, update, origin) => {
|
|
16585
|
+
const decoder = createDecoder(update);
|
|
16586
|
+
const timestamp = getUnixTime();
|
|
16587
|
+
const added = [];
|
|
16588
|
+
const updated = [];
|
|
16589
|
+
const filteredUpdated = [];
|
|
16590
|
+
const removed = [];
|
|
16591
|
+
const len = readVarUint(decoder);
|
|
16592
|
+
for (let i = 0; i < len; i++) {
|
|
16593
|
+
const clientID = readVarUint(decoder);
|
|
16594
|
+
let clock = readVarUint(decoder);
|
|
16595
|
+
const state = JSON.parse(readVarString(decoder));
|
|
16596
|
+
const clientMeta = awareness.meta.get(clientID);
|
|
16597
|
+
const prevState = awareness.states.get(clientID);
|
|
16598
|
+
const currClock = clientMeta === undefined ? 0 : clientMeta.clock;
|
|
16599
|
+
if (currClock < clock || (currClock === clock && state === null && awareness.states.has(clientID))) {
|
|
16600
|
+
if (state === null) {
|
|
16601
|
+
// never let a remote client remove this local state
|
|
16602
|
+
if (clientID === awareness.clientID && awareness.getLocalState() != null) {
|
|
16603
|
+
// remote client removed the local state. Do not remote state. Broadcast a message indicating
|
|
16604
|
+
// that this client still exists by increasing the clock
|
|
16605
|
+
clock++;
|
|
16606
|
+
} else {
|
|
16607
|
+
awareness.states.delete(clientID);
|
|
16608
|
+
}
|
|
16609
|
+
} else {
|
|
16610
|
+
awareness.states.set(clientID, state);
|
|
16611
|
+
}
|
|
16612
|
+
awareness.meta.set(clientID, {
|
|
16613
|
+
clock,
|
|
16614
|
+
lastUpdated: timestamp
|
|
16615
|
+
});
|
|
16616
|
+
if (clientMeta === undefined && state !== null) {
|
|
16617
|
+
added.push(clientID);
|
|
16618
|
+
} else if (clientMeta !== undefined && state === null) {
|
|
16619
|
+
removed.push(clientID);
|
|
16620
|
+
} else if (state !== null) {
|
|
16621
|
+
if (!equalityDeep(state, prevState)) {
|
|
16622
|
+
filteredUpdated.push(clientID);
|
|
16623
|
+
}
|
|
16624
|
+
updated.push(clientID);
|
|
16625
|
+
}
|
|
16626
|
+
}
|
|
16627
|
+
}
|
|
16628
|
+
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
|
|
16629
|
+
awareness.emit('change', [{
|
|
16630
|
+
added, updated: filteredUpdated, removed
|
|
16631
|
+
}, origin]);
|
|
16632
|
+
}
|
|
16633
|
+
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
|
|
16634
|
+
awareness.emit('update', [{
|
|
16635
|
+
added, updated, removed
|
|
16636
|
+
}, origin]);
|
|
16637
|
+
}
|
|
16638
|
+
};
|
|
16639
|
+
|
|
16202
16640
|
const wm = new WeakMap();
|
|
16203
16641
|
/** A property (package-private) on Y.Doc that is used
|
|
16204
16642
|
* to signal that the server wants us to send a 'doc-open' message
|
|
@@ -16394,8 +16832,7 @@
|
|
|
16394
16832
|
if (doc) {
|
|
16395
16833
|
const awareness = getDocAwareness(doc);
|
|
16396
16834
|
if (awareness) {
|
|
16397
|
-
|
|
16398
|
-
awap.applyAwarenessUpdate(awareness, msg.u, 'server');
|
|
16835
|
+
applyAwarenessUpdate(awareness, msg.u, 'server');
|
|
16399
16836
|
}
|
|
16400
16837
|
}
|
|
16401
16838
|
}
|
|
@@ -17406,15 +17843,14 @@
|
|
|
17406
17843
|
}
|
|
17407
17844
|
function createAwareness(db, doc, provider) {
|
|
17408
17845
|
const { parentTable, parentId, parentProp, updatesTable } = doc.meta;
|
|
17409
|
-
const
|
|
17410
|
-
const awareness = new awap.Awareness(doc);
|
|
17846
|
+
const awareness = new Awareness(doc);
|
|
17411
17847
|
const reopenDocSignal = getOpenDocSignal(doc);
|
|
17412
17848
|
awareness.on('update', ({ added, updated, removed }, origin) => {
|
|
17413
17849
|
// Send the update
|
|
17414
17850
|
const changedClients = added.concat(updated).concat(removed);
|
|
17415
17851
|
const user = db.cloud.currentUser.value;
|
|
17416
17852
|
if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {
|
|
17417
|
-
const update =
|
|
17853
|
+
const update = encodeAwarenessUpdate(awareness, changedClients);
|
|
17418
17854
|
db.messageProducer.next({
|
|
17419
17855
|
type: 'aware',
|
|
17420
17856
|
table: parentTable,
|
|
@@ -17440,7 +17876,7 @@
|
|
|
17440
17876
|
awareness.on('destroy', () => {
|
|
17441
17877
|
// Signal to server that this provider is destroyed (the update event will be triggered, which
|
|
17442
17878
|
// in turn will trigger db.messageProducer that will send the message to the server if WS is connected)
|
|
17443
|
-
|
|
17879
|
+
removeAwarenessStates(awareness, [doc.clientID], 'provider destroyed');
|
|
17444
17880
|
});
|
|
17445
17881
|
// Open the document on the server
|
|
17446
17882
|
(() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -17573,7 +18009,7 @@
|
|
|
17573
18009
|
const syncComplete = new rxjs.Subject();
|
|
17574
18010
|
dexie.cloud = {
|
|
17575
18011
|
// @ts-ignore
|
|
17576
|
-
version: "4.2.0-alpha.
|
|
18012
|
+
version: "4.2.0-alpha.6",
|
|
17577
18013
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
17578
18014
|
schema: null,
|
|
17579
18015
|
get currentUserId() {
|
|
@@ -17890,7 +18326,7 @@
|
|
|
17890
18326
|
}
|
|
17891
18327
|
}
|
|
17892
18328
|
// @ts-ignore
|
|
17893
|
-
dexieCloud.version = "4.2.0-alpha.
|
|
18329
|
+
dexieCloud.version = "4.2.0-alpha.6";
|
|
17894
18330
|
Dexie.Cloud = dexieCloud;
|
|
17895
18331
|
|
|
17896
18332
|
// In case the SW lives for a while, let it reuse already opened connections:
|