@liveblocks/core 3.20.0-perm1 → 3.20.0-perm2
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/index.cjs +450 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -9
- package/dist/index.d.ts +61 -9
- package/dist/index.js +351 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "3.20.0-
|
|
9
|
+
var PKG_VERSION = "3.20.0-perm2";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -701,6 +701,20 @@ var SortedList = class _SortedList {
|
|
|
701
701
|
get length() {
|
|
702
702
|
return this.#data.length;
|
|
703
703
|
}
|
|
704
|
+
/**
|
|
705
|
+
* Whether the given value is present, by identity. O(log n) plus the length
|
|
706
|
+
* of any run of items that share its sort key (normally 1). Bisects on the
|
|
707
|
+
* value's own key, so it only finds values sitting at their sorted position,
|
|
708
|
+
* which is true for any item currently in the list.
|
|
709
|
+
*/
|
|
710
|
+
includes(value) {
|
|
711
|
+
for (let i = bisectRight(this.#data, value, this.#lt) - 1; i >= 0 && !this.#lt(this.#data[i], value); i--) {
|
|
712
|
+
if (this.#data[i] === value) {
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
704
718
|
*filter(predicate) {
|
|
705
719
|
for (const item of this.#data) {
|
|
706
720
|
if (predicate(item)) {
|
|
@@ -5723,6 +5737,9 @@ var OpCode = Object.freeze({
|
|
|
5723
5737
|
function isIgnoredOp(op) {
|
|
5724
5738
|
return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
|
|
5725
5739
|
}
|
|
5740
|
+
function isCreateOp(op) {
|
|
5741
|
+
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
|
|
5742
|
+
}
|
|
5726
5743
|
|
|
5727
5744
|
// src/protocol/StorageNode.ts
|
|
5728
5745
|
var CrdtType = Object.freeze({
|
|
@@ -5980,12 +5997,112 @@ function asPos(str) {
|
|
|
5980
5997
|
return isPos(str) ? str : convertToPos(str);
|
|
5981
5998
|
}
|
|
5982
5999
|
|
|
6000
|
+
// src/crdts/UnacknowledgedOps.ts
|
|
6001
|
+
var UnacknowledgedOps = class {
|
|
6002
|
+
// opId -> op
|
|
6003
|
+
#byOpId = /* @__PURE__ */ new Map();
|
|
6004
|
+
// position -> (opId -> Create op)
|
|
6005
|
+
#createOpsByPosition = /* @__PURE__ */ new Map();
|
|
6006
|
+
// parentId -> (opId -> Create op)
|
|
6007
|
+
#createOpsByParent = /* @__PURE__ */ new Map();
|
|
6008
|
+
// opIds of pending ops that were in flight when a connection died, so the
|
|
6009
|
+
// server may already have processed them. See isPossiblyStored().
|
|
6010
|
+
#possiblyStoredOpIds = /* @__PURE__ */ new Set();
|
|
6011
|
+
#posKey(parentId, parentKey) {
|
|
6012
|
+
return `${parentId}
|
|
6013
|
+
${parentKey}`;
|
|
6014
|
+
}
|
|
6015
|
+
get size() {
|
|
6016
|
+
return this.#byOpId.size;
|
|
6017
|
+
}
|
|
6018
|
+
/**
|
|
6019
|
+
* Mark the given Op as still unacknowledged.
|
|
6020
|
+
*/
|
|
6021
|
+
add(op) {
|
|
6022
|
+
this.#byOpId.set(op.opId, op);
|
|
6023
|
+
if (isCreateOp(op)) {
|
|
6024
|
+
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
6025
|
+
let atPosition = this.#createOpsByPosition.get(posKey);
|
|
6026
|
+
if (atPosition === void 0) {
|
|
6027
|
+
atPosition = /* @__PURE__ */ new Map();
|
|
6028
|
+
this.#createOpsByPosition.set(posKey, atPosition);
|
|
6029
|
+
}
|
|
6030
|
+
atPosition.set(op.opId, op);
|
|
6031
|
+
let inParent = this.#createOpsByParent.get(op.parentId);
|
|
6032
|
+
if (inParent === void 0) {
|
|
6033
|
+
inParent = /* @__PURE__ */ new Map();
|
|
6034
|
+
this.#createOpsByParent.set(op.parentId, inParent);
|
|
6035
|
+
}
|
|
6036
|
+
inParent.set(op.opId, op);
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
/**
|
|
6040
|
+
* Drop the op with the given opId from the set, because the server has
|
|
6041
|
+
* acknowledged it (confirmed our own op, or signalled it was seen but
|
|
6042
|
+
* ignored).
|
|
6043
|
+
*/
|
|
6044
|
+
delete(opId) {
|
|
6045
|
+
const op = this.#byOpId.get(opId);
|
|
6046
|
+
if (op === void 0) {
|
|
6047
|
+
return;
|
|
6048
|
+
}
|
|
6049
|
+
this.#byOpId.delete(opId);
|
|
6050
|
+
this.#possiblyStoredOpIds.delete(opId);
|
|
6051
|
+
if (isCreateOp(op)) {
|
|
6052
|
+
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
6053
|
+
const atPosition = this.#createOpsByPosition.get(posKey);
|
|
6054
|
+
_optionalChain([atPosition, 'optionalAccess', _111 => _111.delete, 'call', _112 => _112(opId)]);
|
|
6055
|
+
if (atPosition !== void 0 && atPosition.size === 0) {
|
|
6056
|
+
this.#createOpsByPosition.delete(posKey);
|
|
6057
|
+
}
|
|
6058
|
+
const inParent = this.#createOpsByParent.get(op.parentId);
|
|
6059
|
+
_optionalChain([inParent, 'optionalAccess', _113 => _113.delete, 'call', _114 => _114(opId)]);
|
|
6060
|
+
if (inParent !== void 0 && inParent.size === 0) {
|
|
6061
|
+
this.#createOpsByParent.delete(op.parentId);
|
|
6062
|
+
}
|
|
6063
|
+
}
|
|
6064
|
+
}
|
|
6065
|
+
/**
|
|
6066
|
+
* The still-unacknowledged Create ops with the given `parentId` and
|
|
6067
|
+
* `parentKey` (targeting one exact position), in dispatch order. O(1) lookup.
|
|
6068
|
+
* Empty if none.
|
|
6069
|
+
*/
|
|
6070
|
+
getByParentIdAndKey(parentId, parentKey) {
|
|
6071
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _115 => _115.#createOpsByPosition, 'access', _116 => _116.get, 'call', _117 => _117(this.#posKey(parentId, parentKey)), 'optionalAccess', _118 => _118.values, 'call', _119 => _119()]), () => ( []));
|
|
6072
|
+
}
|
|
6073
|
+
/**
|
|
6074
|
+
* The still-unacknowledged Create ops with the given `parentId` (across all
|
|
6075
|
+
* positions), in dispatch order. O(1) lookup. Empty if none.
|
|
6076
|
+
*/
|
|
6077
|
+
getByParentId(parentId) {
|
|
6078
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _120 => _120.#createOpsByParent, 'access', _121 => _121.get, 'call', _122 => _122(parentId), 'optionalAccess', _123 => _123.values, 'call', _124 => _124()]), () => ( []));
|
|
6079
|
+
}
|
|
6080
|
+
/** All still-unacknowledged ops, in dispatch order. */
|
|
6081
|
+
values() {
|
|
6082
|
+
return this.#byOpId.values();
|
|
6083
|
+
}
|
|
6084
|
+
isPossiblyStored(opId) {
|
|
6085
|
+
return this.#possiblyStoredOpIds.has(opId);
|
|
6086
|
+
}
|
|
6087
|
+
/**
|
|
6088
|
+
* Mark every currently pending op as possibly stored on the server. Called
|
|
6089
|
+
* when the connection dies: all of these ops were in flight, and their
|
|
6090
|
+
* (possibly lost) acks would have been the only way to know their fate.
|
|
6091
|
+
*/
|
|
6092
|
+
markAllAsPossiblyStored() {
|
|
6093
|
+
for (const opId of this.#byOpId.keys()) {
|
|
6094
|
+
this.#possiblyStoredOpIds.add(opId);
|
|
6095
|
+
}
|
|
6096
|
+
}
|
|
6097
|
+
};
|
|
6098
|
+
|
|
5983
6099
|
// src/crdts/AbstractCrdt.ts
|
|
5984
6100
|
function createManagedPool(roomId, options) {
|
|
5985
6101
|
const {
|
|
5986
6102
|
getCurrentConnectionId,
|
|
5987
6103
|
onDispatch,
|
|
5988
|
-
isStorageWritable = () => true
|
|
6104
|
+
isStorageWritable = () => true,
|
|
6105
|
+
unacknowledgedOps = new UnacknowledgedOps()
|
|
5989
6106
|
} = options;
|
|
5990
6107
|
let clock = 0;
|
|
5991
6108
|
let opClock = 0;
|
|
@@ -5999,7 +6116,7 @@ function createManagedPool(roomId, options) {
|
|
|
5999
6116
|
generateId: () => `${getCurrentConnectionId()}:${clock++}`,
|
|
6000
6117
|
generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
|
|
6001
6118
|
dispatch(ops, reverse, storageUpdates) {
|
|
6002
|
-
_optionalChain([onDispatch, 'optionalCall',
|
|
6119
|
+
_optionalChain([onDispatch, 'optionalCall', _125 => _125(ops, reverse, storageUpdates)]);
|
|
6003
6120
|
},
|
|
6004
6121
|
assertStorageIsWritable: () => {
|
|
6005
6122
|
if (!isStorageWritable()) {
|
|
@@ -6007,7 +6124,8 @@ function createManagedPool(roomId, options) {
|
|
|
6007
6124
|
"Cannot write to storage with a read only user, please ensure the user has write permissions"
|
|
6008
6125
|
);
|
|
6009
6126
|
}
|
|
6010
|
-
}
|
|
6127
|
+
},
|
|
6128
|
+
unacknowledgedOps
|
|
6011
6129
|
};
|
|
6012
6130
|
}
|
|
6013
6131
|
function crdtAsLiveNode(value) {
|
|
@@ -6289,11 +6407,9 @@ function childNodeLt(a, b) {
|
|
|
6289
6407
|
var LiveList = class _LiveList extends AbstractCrdt {
|
|
6290
6408
|
#items;
|
|
6291
6409
|
#implicitlyDeletedItems;
|
|
6292
|
-
#unacknowledgedSets;
|
|
6293
6410
|
constructor(items) {
|
|
6294
6411
|
super();
|
|
6295
6412
|
this.#implicitlyDeletedItems = /* @__PURE__ */ new WeakSet();
|
|
6296
|
-
this.#unacknowledgedSets = /* @__PURE__ */ new Map();
|
|
6297
6413
|
const nodes = [];
|
|
6298
6414
|
let lastPos;
|
|
6299
6415
|
for (const item of items) {
|
|
@@ -6323,12 +6439,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6323
6439
|
}
|
|
6324
6440
|
/**
|
|
6325
6441
|
* @internal
|
|
6326
|
-
*
|
|
6327
|
-
*
|
|
6328
|
-
*
|
|
6442
|
+
* Serializes this list (and its children) into Create ops. Each child's
|
|
6443
|
+
* create is tagged with the "set" intent (in the loop below) so that a list
|
|
6444
|
+
* created and immediately mutated doesn't transiently re-show its initial
|
|
6445
|
+
* items (flicker, https://github.com/liveblocks/liveblocks/pull/1177).
|
|
6329
6446
|
*
|
|
6330
|
-
* This is quite unintuitive and should disappear as soon as
|
|
6331
|
-
*
|
|
6447
|
+
* This is quite unintuitive and should disappear as soon as we introduce an
|
|
6448
|
+
* explicit LiveList.Set operation.
|
|
6332
6449
|
*/
|
|
6333
6450
|
_toOps(parentId, parentKey) {
|
|
6334
6451
|
if (this._id === void 0) {
|
|
@@ -6344,9 +6461,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6344
6461
|
ops.push(op);
|
|
6345
6462
|
for (const item of this.#items) {
|
|
6346
6463
|
const parentKey2 = item._getParentKeyOrThrow();
|
|
6347
|
-
const childOps =
|
|
6464
|
+
const childOps = addIntentToRootOp(
|
|
6348
6465
|
item._toOps(this._id, parentKey2),
|
|
6349
|
-
|
|
6466
|
+
"set"
|
|
6350
6467
|
);
|
|
6351
6468
|
for (const childOp of childOps) {
|
|
6352
6469
|
ops.push(childOp);
|
|
@@ -6388,6 +6505,28 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6388
6505
|
(item) => item._getParentKeyOrThrow() === position
|
|
6389
6506
|
);
|
|
6390
6507
|
}
|
|
6508
|
+
/**
|
|
6509
|
+
* The opId of this list's still-unacknowledged "set" op at the given position,
|
|
6510
|
+
* or undefined if none. Derived from the room's unacknowledgedOps (the single
|
|
6511
|
+
* source of truth) rather than tracked in a per-instance map. The pool's
|
|
6512
|
+
* position index already scopes to this list's (parentId, position); the last
|
|
6513
|
+
* match wins, matching the original last-write-wins map semantics.
|
|
6514
|
+
*/
|
|
6515
|
+
#unacknowledgedSetOpIdAt(position) {
|
|
6516
|
+
if (this._pool === void 0 || this._id === void 0) {
|
|
6517
|
+
return void 0;
|
|
6518
|
+
}
|
|
6519
|
+
let opId;
|
|
6520
|
+
for (const op of this._pool.unacknowledgedOps.getByParentIdAndKey(
|
|
6521
|
+
this._id,
|
|
6522
|
+
position
|
|
6523
|
+
)) {
|
|
6524
|
+
if (op.intent === "set") {
|
|
6525
|
+
opId = op.opId;
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6528
|
+
return opId;
|
|
6529
|
+
}
|
|
6391
6530
|
/** @internal */
|
|
6392
6531
|
_attach(id, pool) {
|
|
6393
6532
|
super._attach(id, pool);
|
|
@@ -6468,13 +6607,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6468
6607
|
if (deletedDelta) {
|
|
6469
6608
|
delta.push(deletedDelta);
|
|
6470
6609
|
}
|
|
6471
|
-
const unacknowledgedOpId = this.#
|
|
6472
|
-
if (unacknowledgedOpId !== void 0) {
|
|
6473
|
-
|
|
6474
|
-
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
|
|
6475
|
-
} else {
|
|
6476
|
-
this.#unacknowledgedSets.delete(op.parentKey);
|
|
6477
|
-
}
|
|
6610
|
+
const unacknowledgedOpId = this.#unacknowledgedSetOpIdAt(op.parentKey);
|
|
6611
|
+
if (unacknowledgedOpId !== void 0 && unacknowledgedOpId !== op.opId) {
|
|
6612
|
+
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
|
|
6478
6613
|
}
|
|
6479
6614
|
const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey);
|
|
6480
6615
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
@@ -6565,11 +6700,92 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6565
6700
|
this.#shiftItemPosition(existingItemIndex, key);
|
|
6566
6701
|
}
|
|
6567
6702
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
6703
|
+
const bumpDeltas = this.#bumpUnackedPushesAbove(key);
|
|
6568
6704
|
return {
|
|
6569
|
-
modified: makeUpdate(this, [
|
|
6705
|
+
modified: makeUpdate(this, [
|
|
6706
|
+
insertDelta(newIndex, newItem),
|
|
6707
|
+
...bumpDeltas
|
|
6708
|
+
]),
|
|
6570
6709
|
reverse: []
|
|
6571
6710
|
};
|
|
6572
6711
|
}
|
|
6712
|
+
/**
|
|
6713
|
+
* This list's own still-unacknowledged pushed items (their `intent: "push"`
|
|
6714
|
+
* Create op is still pending in the room's unacknowledgedOps). Derived from
|
|
6715
|
+
* the single source of truth, so an item drops out the instant its op is
|
|
6716
|
+
* acked, with no per-instance membership to leak. Yielded in push order.
|
|
6717
|
+
*
|
|
6718
|
+
* Excludes ops that may already be stored on the server (they were in
|
|
6719
|
+
* flight when a connection died, so their fate is unknown): the bump
|
|
6720
|
+
* prediction assumes the server has not processed the op yet, which is only
|
|
6721
|
+
* guaranteed for ops sent on the current connection. For these excluded
|
|
6722
|
+
* ops, the server's (re-)ack states the authoritative position; predicting
|
|
6723
|
+
* locally could produce a wrong position that no ack would correct.
|
|
6724
|
+
*
|
|
6725
|
+
* Restricted to items currently in `#items`: a pushed node whose op is still
|
|
6726
|
+
* pending may have been pulled out of the list (e.g. implicitly deleted by a
|
|
6727
|
+
* remote set, or removed by an undo) while still living in the pool, and such
|
|
6728
|
+
* a node must not be repositioned.
|
|
6729
|
+
*/
|
|
6730
|
+
*#unackedPushNodes() {
|
|
6731
|
+
if (this._pool === void 0 || this._id === void 0) {
|
|
6732
|
+
return;
|
|
6733
|
+
}
|
|
6734
|
+
for (const op of this._pool.unacknowledgedOps.getByParentId(this._id)) {
|
|
6735
|
+
if (op.intent !== "push") {
|
|
6736
|
+
continue;
|
|
6737
|
+
}
|
|
6738
|
+
if (this._pool.unacknowledgedOps.isPossiblyStored(op.opId)) {
|
|
6739
|
+
continue;
|
|
6740
|
+
}
|
|
6741
|
+
const node = this._pool.getNode(op.id);
|
|
6742
|
+
if (node !== void 0 && this.#items.includes(node)) {
|
|
6743
|
+
yield node;
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
}
|
|
6747
|
+
/**
|
|
6748
|
+
* Optimistic no-flip for pushed items. When a remote op lands at or below my
|
|
6749
|
+
* still-unacked pushed items, those items must end up *after* it: FIFO plus
|
|
6750
|
+
* the room's serial processing guarantee the remote was processed first, so
|
|
6751
|
+
* my unacked pushes belong behind it. Re-chain the whole unacked-push block,
|
|
6752
|
+
* in push order, to sit after the highest confirmed sibling, so it keeps
|
|
6753
|
+
* rendering as a contiguous tail instead of getting interleaved. Local-only;
|
|
6754
|
+
* the real acks overwrite these keys with the (identical) server keys.
|
|
6755
|
+
*/
|
|
6756
|
+
#bumpUnackedPushesAbove(remoteKey) {
|
|
6757
|
+
const pending = new Set(this.#unackedPushNodes());
|
|
6758
|
+
if (pending.size === 0) {
|
|
6759
|
+
return [];
|
|
6760
|
+
}
|
|
6761
|
+
let minPending;
|
|
6762
|
+
for (const node of pending) {
|
|
6763
|
+
const pos = node._parentPos;
|
|
6764
|
+
if (minPending === void 0 || pos < minPending) {
|
|
6765
|
+
minPending = pos;
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
if (remoteKey < nn(minPending)) {
|
|
6769
|
+
return [];
|
|
6770
|
+
}
|
|
6771
|
+
let base;
|
|
6772
|
+
for (const item of this.#items) {
|
|
6773
|
+
if (!pending.has(item)) {
|
|
6774
|
+
base = item._parentPos;
|
|
6775
|
+
}
|
|
6776
|
+
}
|
|
6777
|
+
const deltas = [];
|
|
6778
|
+
for (const node of pending) {
|
|
6779
|
+
const previousIndex = this.#items.findIndex((item) => item === node);
|
|
6780
|
+
base = makePosition(base);
|
|
6781
|
+
this.#updateItemPosition(node, base);
|
|
6782
|
+
const index = this.#items.findIndex((item) => item === node);
|
|
6783
|
+
if (index !== previousIndex) {
|
|
6784
|
+
deltas.push(moveDelta(previousIndex, index, node));
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
return deltas;
|
|
6788
|
+
}
|
|
6573
6789
|
#applyInsertAck(op) {
|
|
6574
6790
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
6575
6791
|
const key = asPos(op.parentKey);
|
|
@@ -6624,7 +6840,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6624
6840
|
#applyInsertUndoRedo(op) {
|
|
6625
6841
|
const { id, parentKey: key } = op;
|
|
6626
6842
|
const child = creationOpToLiveNode(op);
|
|
6627
|
-
if (_optionalChain([this, 'access',
|
|
6843
|
+
if (_optionalChain([this, 'access', _126 => _126._pool, 'optionalAccess', _127 => _127.getNode, 'call', _128 => _128(id)]) !== void 0) {
|
|
6628
6844
|
return { modified: false };
|
|
6629
6845
|
}
|
|
6630
6846
|
child._attach(id, nn(this._pool));
|
|
@@ -6632,8 +6848,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6632
6848
|
const existingItemIndex = this._indexOfPosition(key);
|
|
6633
6849
|
let newKey = key;
|
|
6634
6850
|
if (existingItemIndex !== -1) {
|
|
6635
|
-
const before2 = _optionalChain([this, 'access',
|
|
6636
|
-
const after2 = _optionalChain([this, 'access',
|
|
6851
|
+
const before2 = _optionalChain([this, 'access', _129 => _129.#items, 'access', _130 => _130.at, 'call', _131 => _131(existingItemIndex), 'optionalAccess', _132 => _132._parentPos]);
|
|
6852
|
+
const after2 = _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134.at, 'call', _135 => _135(existingItemIndex + 1), 'optionalAccess', _136 => _136._parentPos]);
|
|
6637
6853
|
newKey = makePosition(before2, after2);
|
|
6638
6854
|
child._setParentLink(this, newKey);
|
|
6639
6855
|
}
|
|
@@ -6647,10 +6863,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6647
6863
|
#applySetUndoRedo(op) {
|
|
6648
6864
|
const { id, parentKey: key } = op;
|
|
6649
6865
|
const child = creationOpToLiveNode(op);
|
|
6650
|
-
if (_optionalChain([this, 'access',
|
|
6866
|
+
if (_optionalChain([this, 'access', _137 => _137._pool, 'optionalAccess', _138 => _138.getNode, 'call', _139 => _139(id)]) !== void 0) {
|
|
6651
6867
|
return { modified: false };
|
|
6652
6868
|
}
|
|
6653
|
-
this.#unacknowledgedSets.set(key, nn(op.opId));
|
|
6654
6869
|
const indexOfItemWithSameKey = this._indexOfPosition(key);
|
|
6655
6870
|
child._attach(id, nn(this._pool));
|
|
6656
6871
|
child._setParentLink(this, key);
|
|
@@ -6660,8 +6875,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6660
6875
|
existingItem._detach();
|
|
6661
6876
|
this.#items.remove(existingItem);
|
|
6662
6877
|
this.#items.add(child);
|
|
6663
|
-
const reverse =
|
|
6878
|
+
const reverse = addIntentToRootOp(
|
|
6664
6879
|
existingItem._toOps(nn(this._id), key),
|
|
6880
|
+
"set",
|
|
6665
6881
|
op.id
|
|
6666
6882
|
);
|
|
6667
6883
|
const delta = [setDelta(indexOfItemWithSameKey, child)];
|
|
@@ -6768,7 +6984,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6768
6984
|
} else {
|
|
6769
6985
|
this.#updateItemPositionAt(
|
|
6770
6986
|
existingItemIndex,
|
|
6771
|
-
makePosition(newKey, _optionalChain([this, 'access',
|
|
6987
|
+
makePosition(newKey, _optionalChain([this, 'access', _140 => _140.#items, 'access', _141 => _141.at, 'call', _142 => _142(existingItemIndex + 1), 'optionalAccess', _143 => _143._parentPos]))
|
|
6772
6988
|
);
|
|
6773
6989
|
const previousIndex = this.#items.findIndex((item) => item === child);
|
|
6774
6990
|
this.#updateItemPosition(child, newKey);
|
|
@@ -6795,7 +7011,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6795
7011
|
this,
|
|
6796
7012
|
makePosition(
|
|
6797
7013
|
newKey,
|
|
6798
|
-
_optionalChain([this, 'access',
|
|
7014
|
+
_optionalChain([this, 'access', _144 => _144.#items, 'access', _145 => _145.at, 'call', _146 => _146(existingItemIndex + 1), 'optionalAccess', _147 => _147._parentPos])
|
|
6799
7015
|
)
|
|
6800
7016
|
);
|
|
6801
7017
|
this.#items.reposition(existingItem);
|
|
@@ -6819,7 +7035,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6819
7035
|
existingItemIndex,
|
|
6820
7036
|
makePosition(
|
|
6821
7037
|
newKey,
|
|
6822
|
-
_optionalChain([this, 'access',
|
|
7038
|
+
_optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(existingItemIndex + 1), 'optionalAccess', _151 => _151._parentPos])
|
|
6823
7039
|
)
|
|
6824
7040
|
);
|
|
6825
7041
|
}
|
|
@@ -6847,7 +7063,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6847
7063
|
if (existingItemIndex !== -1) {
|
|
6848
7064
|
actualNewKey = makePosition(
|
|
6849
7065
|
newKey,
|
|
6850
|
-
_optionalChain([this, 'access',
|
|
7066
|
+
_optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(existingItemIndex + 1), 'optionalAccess', _155 => _155._parentPos])
|
|
6851
7067
|
);
|
|
6852
7068
|
}
|
|
6853
7069
|
this.#updateItemPosition(child, actualNewKey);
|
|
@@ -6904,8 +7120,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6904
7120
|
* @param element The element to add to the end of the LiveList.
|
|
6905
7121
|
*/
|
|
6906
7122
|
push(element) {
|
|
6907
|
-
|
|
6908
|
-
return this.insert(element, this.length);
|
|
7123
|
+
return this.#injectAt(element, this.length, "push");
|
|
6909
7124
|
}
|
|
6910
7125
|
/**
|
|
6911
7126
|
* Inserts one element at a specified index.
|
|
@@ -6913,14 +7128,23 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6913
7128
|
* @param index The index at which you want to insert the element.
|
|
6914
7129
|
*/
|
|
6915
7130
|
insert(element, index) {
|
|
6916
|
-
|
|
7131
|
+
return this.#injectAt(element, index, "insert");
|
|
7132
|
+
}
|
|
7133
|
+
/**
|
|
7134
|
+
* Shared implementation of `insert` and `push`. A `"push"` intent leaves the
|
|
7135
|
+
* client-computed position untouched (so optimistic rendering is unchanged),
|
|
7136
|
+
* but tags the Op so the server appends it to the true end of the list
|
|
7137
|
+
* instead of resolving its position against the client's stale view.
|
|
7138
|
+
*/
|
|
7139
|
+
#injectAt(element, index, intent) {
|
|
7140
|
+
_optionalChain([this, 'access', _156 => _156._pool, 'optionalAccess', _157 => _157.assertStorageIsWritable, 'call', _158 => _158()]);
|
|
6917
7141
|
if (index < 0 || index > this.#items.length) {
|
|
6918
7142
|
throw new Error(
|
|
6919
7143
|
`Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
|
|
6920
7144
|
);
|
|
6921
7145
|
}
|
|
6922
|
-
const before2 = _optionalChain([this, 'access',
|
|
6923
|
-
const after2 = _optionalChain([this, 'access',
|
|
7146
|
+
const before2 = _optionalChain([this, 'access', _159 => _159.#items, 'access', _160 => _160.at, 'call', _161 => _161(index - 1), 'optionalAccess', _162 => _162._parentPos]);
|
|
7147
|
+
const after2 = _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(index), 'optionalAccess', _166 => _166._parentPos]);
|
|
6924
7148
|
const position = makePosition(before2, after2);
|
|
6925
7149
|
const value = lsonToLiveNode(element);
|
|
6926
7150
|
value._setParentLink(this, position);
|
|
@@ -6928,8 +7152,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6928
7152
|
if (this._pool && this._id) {
|
|
6929
7153
|
const id = this._pool.generateId();
|
|
6930
7154
|
value._attach(id, this._pool);
|
|
7155
|
+
const ops = value._toOpsWithOpId(this._id, position, this._pool);
|
|
6931
7156
|
this._pool.dispatch(
|
|
6932
|
-
|
|
7157
|
+
intent === "push" ? addIntentToRootOp(ops, "push") : ops,
|
|
6933
7158
|
[{ type: OpCode.DELETE_CRDT, id }],
|
|
6934
7159
|
/* @__PURE__ */ new Map([
|
|
6935
7160
|
[this._id, makeUpdate(this, [insertDelta(index, value)])]
|
|
@@ -6943,7 +7168,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6943
7168
|
* @param targetIndex The index where the element should be after moving.
|
|
6944
7169
|
*/
|
|
6945
7170
|
move(index, targetIndex) {
|
|
6946
|
-
_optionalChain([this, 'access',
|
|
7171
|
+
_optionalChain([this, 'access', _167 => _167._pool, 'optionalAccess', _168 => _168.assertStorageIsWritable, 'call', _169 => _169()]);
|
|
6947
7172
|
if (targetIndex < 0) {
|
|
6948
7173
|
throw new Error("targetIndex cannot be less than 0");
|
|
6949
7174
|
}
|
|
@@ -6961,11 +7186,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6961
7186
|
let beforePosition = null;
|
|
6962
7187
|
let afterPosition = null;
|
|
6963
7188
|
if (index < targetIndex) {
|
|
6964
|
-
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access',
|
|
7189
|
+
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _170 => _170.#items, 'access', _171 => _171.at, 'call', _172 => _172(targetIndex + 1), 'optionalAccess', _173 => _173._parentPos]);
|
|
6965
7190
|
beforePosition = this.#items.at(targetIndex)._parentPos;
|
|
6966
7191
|
} else {
|
|
6967
7192
|
afterPosition = this.#items.at(targetIndex)._parentPos;
|
|
6968
|
-
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access',
|
|
7193
|
+
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _174 => _174.#items, 'access', _175 => _175.at, 'call', _176 => _176(targetIndex - 1), 'optionalAccess', _177 => _177._parentPos]);
|
|
6969
7194
|
}
|
|
6970
7195
|
const position = makePosition(beforePosition, afterPosition);
|
|
6971
7196
|
const item = this.#items.at(index);
|
|
@@ -7000,7 +7225,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7000
7225
|
* @param index The index of the element to delete
|
|
7001
7226
|
*/
|
|
7002
7227
|
delete(index) {
|
|
7003
|
-
_optionalChain([this, 'access',
|
|
7228
|
+
_optionalChain([this, 'access', _178 => _178._pool, 'optionalAccess', _179 => _179.assertStorageIsWritable, 'call', _180 => _180()]);
|
|
7004
7229
|
if (index < 0 || index >= this.#items.length) {
|
|
7005
7230
|
throw new Error(
|
|
7006
7231
|
`Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -7033,7 +7258,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7033
7258
|
}
|
|
7034
7259
|
}
|
|
7035
7260
|
clear() {
|
|
7036
|
-
_optionalChain([this, 'access',
|
|
7261
|
+
_optionalChain([this, 'access', _181 => _181._pool, 'optionalAccess', _182 => _182.assertStorageIsWritable, 'call', _183 => _183()]);
|
|
7037
7262
|
if (this._pool) {
|
|
7038
7263
|
const ops = [];
|
|
7039
7264
|
const reverseOps = [];
|
|
@@ -7067,7 +7292,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7067
7292
|
}
|
|
7068
7293
|
}
|
|
7069
7294
|
set(index, item) {
|
|
7070
|
-
_optionalChain([this, 'access',
|
|
7295
|
+
_optionalChain([this, 'access', _184 => _184._pool, 'optionalAccess', _185 => _185.assertStorageIsWritable, 'call', _186 => _186()]);
|
|
7071
7296
|
if (index < 0 || index >= this.#items.length) {
|
|
7072
7297
|
throw new Error(
|
|
7073
7298
|
`Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -7087,13 +7312,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7087
7312
|
value._attach(id, this._pool);
|
|
7088
7313
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
7089
7314
|
storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
|
|
7090
|
-
const ops =
|
|
7315
|
+
const ops = addIntentToRootOp(
|
|
7091
7316
|
value._toOpsWithOpId(this._id, position, this._pool),
|
|
7317
|
+
"set",
|
|
7092
7318
|
existingId
|
|
7093
7319
|
);
|
|
7094
|
-
|
|
7095
|
-
const reverseOps = HACK_addIntentAndDeletedIdToOperation(
|
|
7320
|
+
const reverseOps = addIntentToRootOp(
|
|
7096
7321
|
existingItem._toOps(this._id, position),
|
|
7322
|
+
"set",
|
|
7097
7323
|
id
|
|
7098
7324
|
);
|
|
7099
7325
|
this._pool.dispatch(ops, reverseOps, storageUpdates);
|
|
@@ -7225,7 +7451,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7225
7451
|
#shiftItemPosition(index, key) {
|
|
7226
7452
|
const shiftedPosition = makePosition(
|
|
7227
7453
|
key,
|
|
7228
|
-
this.#items.length > index + 1 ? _optionalChain([this, 'access',
|
|
7454
|
+
this.#items.length > index + 1 ? _optionalChain([this, 'access', _187 => _187.#items, 'access', _188 => _188.at, 'call', _189 => _189(index + 1), 'optionalAccess', _190 => _190._parentPos]) : void 0
|
|
7229
7455
|
);
|
|
7230
7456
|
this.#updateItemPositionAt(index, shiftedPosition);
|
|
7231
7457
|
}
|
|
@@ -7294,15 +7520,11 @@ function moveDelta(previousIndex, index, item) {
|
|
|
7294
7520
|
previousIndex
|
|
7295
7521
|
};
|
|
7296
7522
|
}
|
|
7297
|
-
function
|
|
7523
|
+
function addIntentToRootOp(ops, intent, deletedId) {
|
|
7298
7524
|
return ops.map((op, index) => {
|
|
7299
7525
|
if (index === 0) {
|
|
7300
7526
|
const firstOp = op;
|
|
7301
|
-
return {
|
|
7302
|
-
...firstOp,
|
|
7303
|
-
intent: "set",
|
|
7304
|
-
deletedId
|
|
7305
|
-
};
|
|
7527
|
+
return { ...firstOp, intent, deletedId };
|
|
7306
7528
|
} else {
|
|
7307
7529
|
return op;
|
|
7308
7530
|
}
|
|
@@ -7478,7 +7700,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7478
7700
|
* @param value The value of the element to add. Should be serializable to JSON.
|
|
7479
7701
|
*/
|
|
7480
7702
|
set(key, value) {
|
|
7481
|
-
_optionalChain([this, 'access',
|
|
7703
|
+
_optionalChain([this, 'access', _191 => _191._pool, 'optionalAccess', _192 => _192.assertStorageIsWritable, 'call', _193 => _193()]);
|
|
7482
7704
|
const oldValue = this.#map.get(key);
|
|
7483
7705
|
if (oldValue) {
|
|
7484
7706
|
oldValue._detach();
|
|
@@ -7524,7 +7746,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7524
7746
|
* @returns true if an element existed and has been removed, or false if the element does not exist.
|
|
7525
7747
|
*/
|
|
7526
7748
|
delete(key) {
|
|
7527
|
-
_optionalChain([this, 'access',
|
|
7749
|
+
_optionalChain([this, 'access', _194 => _194._pool, 'optionalAccess', _195 => _195.assertStorageIsWritable, 'call', _196 => _196()]);
|
|
7528
7750
|
const item = this.#map.get(key);
|
|
7529
7751
|
if (item === void 0) {
|
|
7530
7752
|
return false;
|
|
@@ -7954,6 +8176,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7954
8176
|
const id = nn(this._id);
|
|
7955
8177
|
const parentKey = nn(child._parentKey);
|
|
7956
8178
|
const reverse = child._toOps(id, parentKey);
|
|
8179
|
+
const deletedItem = liveNodeToLson(child);
|
|
7957
8180
|
for (const [key, value] of this.#synced) {
|
|
7958
8181
|
if (value === child) {
|
|
7959
8182
|
this.#synced.delete(key);
|
|
@@ -7965,7 +8188,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
7965
8188
|
node: this,
|
|
7966
8189
|
type: "LiveObject",
|
|
7967
8190
|
updates: {
|
|
7968
|
-
[parentKey]: { type: "delete" }
|
|
8191
|
+
[parentKey]: { type: "delete", deletedItem }
|
|
7969
8192
|
}
|
|
7970
8193
|
};
|
|
7971
8194
|
return { modified: storageUpdate, reverse };
|
|
@@ -8135,20 +8358,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8135
8358
|
* Caveat: this method will not add changes to the undo/redo stack.
|
|
8136
8359
|
*/
|
|
8137
8360
|
setLocal(key, value) {
|
|
8138
|
-
_optionalChain([this, 'access',
|
|
8361
|
+
_optionalChain([this, 'access', _197 => _197._pool, 'optionalAccess', _198 => _198.assertStorageIsWritable, 'call', _199 => _199()]);
|
|
8139
8362
|
const deleteResult = this.#prepareDelete(key);
|
|
8140
8363
|
this.#local.set(key, value);
|
|
8141
8364
|
this.invalidate();
|
|
8142
8365
|
if (this._pool !== void 0 && this._id !== void 0) {
|
|
8143
|
-
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8144
|
-
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8145
|
-
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8366
|
+
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _200 => _200[0]]), () => ( []));
|
|
8367
|
+
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _201 => _201[1]]), () => ( []));
|
|
8368
|
+
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _202 => _202[2]]), () => ( /* @__PURE__ */ new Map()));
|
|
8146
8369
|
const existing = storageUpdates.get(this._id);
|
|
8147
8370
|
storageUpdates.set(this._id, {
|
|
8148
8371
|
node: this,
|
|
8149
8372
|
type: "LiveObject",
|
|
8150
8373
|
updates: {
|
|
8151
|
-
..._optionalChain([existing, 'optionalAccess',
|
|
8374
|
+
..._optionalChain([existing, 'optionalAccess', _203 => _203.updates]),
|
|
8152
8375
|
[key]: { type: "update" }
|
|
8153
8376
|
}
|
|
8154
8377
|
});
|
|
@@ -8168,7 +8391,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8168
8391
|
* #synced or pool/id are unavailable. Does NOT dispatch.
|
|
8169
8392
|
*/
|
|
8170
8393
|
#prepareDelete(key) {
|
|
8171
|
-
_optionalChain([this, 'access',
|
|
8394
|
+
_optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
|
|
8172
8395
|
const k = key;
|
|
8173
8396
|
if (this.#local.has(k) && !this.#synced.has(k)) {
|
|
8174
8397
|
const oldValue2 = this.#local.get(k);
|
|
@@ -8244,7 +8467,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8244
8467
|
const result = this.#prepareDelete(key);
|
|
8245
8468
|
if (result) {
|
|
8246
8469
|
const [ops, reverse, storageUpdates] = result;
|
|
8247
|
-
_optionalChain([this, 'access',
|
|
8470
|
+
_optionalChain([this, 'access', _207 => _207._pool, 'optionalAccess', _208 => _208.dispatch, 'call', _209 => _209(ops, reverse, storageUpdates)]);
|
|
8248
8471
|
}
|
|
8249
8472
|
}
|
|
8250
8473
|
/**
|
|
@@ -8252,7 +8475,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8252
8475
|
* @param patch The object used to overrides properties
|
|
8253
8476
|
*/
|
|
8254
8477
|
update(patch) {
|
|
8255
|
-
_optionalChain([this, 'access',
|
|
8478
|
+
_optionalChain([this, 'access', _210 => _210._pool, 'optionalAccess', _211 => _211.assertStorageIsWritable, 'call', _212 => _212()]);
|
|
8256
8479
|
if (_LiveObject.detectLargeObjects) {
|
|
8257
8480
|
const data = {};
|
|
8258
8481
|
for (const [key, value] of this.#synced) {
|
|
@@ -8542,6 +8765,60 @@ function lsonToLiveNode(value) {
|
|
|
8542
8765
|
return new LiveRegister(value);
|
|
8543
8766
|
}
|
|
8544
8767
|
}
|
|
8768
|
+
function dumpPool(pool) {
|
|
8769
|
+
const rows = Array.from(pool.nodes.values(), (node) => {
|
|
8770
|
+
const parent = node.parent;
|
|
8771
|
+
const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
|
|
8772
|
+
let value;
|
|
8773
|
+
if (node instanceof LiveRegister) {
|
|
8774
|
+
value = stringifyOrLog(node.data);
|
|
8775
|
+
} else if (node instanceof LiveList) {
|
|
8776
|
+
value = "<LiveList>";
|
|
8777
|
+
} else if (node instanceof LiveMap) {
|
|
8778
|
+
value = "<LiveMap>";
|
|
8779
|
+
} else {
|
|
8780
|
+
value = "<LiveObject>";
|
|
8781
|
+
}
|
|
8782
|
+
return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
|
|
8783
|
+
});
|
|
8784
|
+
rows.sort((a, b) => {
|
|
8785
|
+
if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
|
|
8786
|
+
if (a.key !== b.key) return a.key < b.key ? -1 : 1;
|
|
8787
|
+
return 0;
|
|
8788
|
+
});
|
|
8789
|
+
return rows.map(
|
|
8790
|
+
(r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
|
|
8791
|
+
).join("\n");
|
|
8792
|
+
}
|
|
8793
|
+
function isJsonEq(a, b) {
|
|
8794
|
+
if (a === b) {
|
|
8795
|
+
return true;
|
|
8796
|
+
}
|
|
8797
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
8798
|
+
return false;
|
|
8799
|
+
}
|
|
8800
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
8801
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
8802
|
+
return false;
|
|
8803
|
+
}
|
|
8804
|
+
for (let i = 0; i < a.length; i++) {
|
|
8805
|
+
if (!isJsonEq(a[i], b[i])) {
|
|
8806
|
+
return false;
|
|
8807
|
+
}
|
|
8808
|
+
}
|
|
8809
|
+
return true;
|
|
8810
|
+
}
|
|
8811
|
+
const aKeys = Object.keys(a);
|
|
8812
|
+
if (aKeys.length !== Object.keys(b).length) {
|
|
8813
|
+
return false;
|
|
8814
|
+
}
|
|
8815
|
+
for (const key of aKeys) {
|
|
8816
|
+
if (!isJsonEq(a[key], b[key])) {
|
|
8817
|
+
return false;
|
|
8818
|
+
}
|
|
8819
|
+
}
|
|
8820
|
+
return true;
|
|
8821
|
+
}
|
|
8545
8822
|
function getTreesDiffOperations(currentItems, newItems) {
|
|
8546
8823
|
const ops = [];
|
|
8547
8824
|
currentItems.forEach((_, id) => {
|
|
@@ -8553,12 +8830,28 @@ function getTreesDiffOperations(currentItems, newItems) {
|
|
|
8553
8830
|
const currentCrdt = currentItems.get(id);
|
|
8554
8831
|
if (currentCrdt) {
|
|
8555
8832
|
if (crdt.type === CrdtType.OBJECT) {
|
|
8556
|
-
if (currentCrdt.type !== CrdtType.OBJECT
|
|
8557
|
-
ops.push({
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8833
|
+
if (currentCrdt.type !== CrdtType.OBJECT) {
|
|
8834
|
+
ops.push({ type: OpCode.UPDATE_OBJECT, id, data: crdt.data });
|
|
8835
|
+
} else {
|
|
8836
|
+
const changed = /* @__PURE__ */ new Map();
|
|
8837
|
+
for (const key of Object.keys(crdt.data)) {
|
|
8838
|
+
const value = crdt.data[key];
|
|
8839
|
+
if (value !== void 0 && !isJsonEq(value, currentCrdt.data[key])) {
|
|
8840
|
+
changed.set(key, value);
|
|
8841
|
+
}
|
|
8842
|
+
}
|
|
8843
|
+
if (changed.size > 0) {
|
|
8844
|
+
ops.push({
|
|
8845
|
+
type: OpCode.UPDATE_OBJECT,
|
|
8846
|
+
id,
|
|
8847
|
+
data: Object.fromEntries(changed)
|
|
8848
|
+
});
|
|
8849
|
+
}
|
|
8850
|
+
for (const key of Object.keys(currentCrdt.data)) {
|
|
8851
|
+
if (!(key in crdt.data)) {
|
|
8852
|
+
ops.push({ type: OpCode.DELETE_OBJECT_KEY, id, key });
|
|
8853
|
+
}
|
|
8854
|
+
}
|
|
8562
8855
|
}
|
|
8563
8856
|
}
|
|
8564
8857
|
if (crdt.parentKey !== currentCrdt.parentKey) {
|
|
@@ -8669,7 +8962,7 @@ function sendToPanel(message, options) {
|
|
|
8669
8962
|
...message,
|
|
8670
8963
|
source: "liveblocks-devtools-client"
|
|
8671
8964
|
};
|
|
8672
|
-
if (!(_optionalChain([options, 'optionalAccess',
|
|
8965
|
+
if (!(_optionalChain([options, 'optionalAccess', _213 => _213.force]) || _bridgeActive)) {
|
|
8673
8966
|
return;
|
|
8674
8967
|
}
|
|
8675
8968
|
window.postMessage(fullMsg, "*");
|
|
@@ -8677,7 +8970,7 @@ function sendToPanel(message, options) {
|
|
|
8677
8970
|
var eventSource = makeEventSource();
|
|
8678
8971
|
if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
|
|
8679
8972
|
window.addEventListener("message", (event) => {
|
|
8680
|
-
if (event.source === window && _optionalChain([event, 'access',
|
|
8973
|
+
if (event.source === window && _optionalChain([event, 'access', _214 => _214.data, 'optionalAccess', _215 => _215.source]) === "liveblocks-devtools-panel") {
|
|
8681
8974
|
eventSource.notify(event.data);
|
|
8682
8975
|
} else {
|
|
8683
8976
|
}
|
|
@@ -8819,7 +9112,7 @@ function fullSync(room) {
|
|
|
8819
9112
|
msg: "room::sync::full",
|
|
8820
9113
|
roomId: room.id,
|
|
8821
9114
|
status: room.getStatus(),
|
|
8822
|
-
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess',
|
|
9115
|
+
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _216 => _216.toTreeNode, 'call', _217 => _217("root"), 'access', _218 => _218.payload]), () => ( null)),
|
|
8823
9116
|
me,
|
|
8824
9117
|
others
|
|
8825
9118
|
});
|
|
@@ -9498,15 +9791,15 @@ function installBackgroundTabSpy() {
|
|
|
9498
9791
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
9499
9792
|
const inBackgroundSince = { current: null };
|
|
9500
9793
|
function onVisibilityChange() {
|
|
9501
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
9794
|
+
if (_optionalChain([doc, 'optionalAccess', _219 => _219.visibilityState]) === "hidden") {
|
|
9502
9795
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
9503
9796
|
} else {
|
|
9504
9797
|
inBackgroundSince.current = null;
|
|
9505
9798
|
}
|
|
9506
9799
|
}
|
|
9507
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9800
|
+
_optionalChain([doc, 'optionalAccess', _220 => _220.addEventListener, 'call', _221 => _221("visibilitychange", onVisibilityChange)]);
|
|
9508
9801
|
const unsub = () => {
|
|
9509
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9802
|
+
_optionalChain([doc, 'optionalAccess', _222 => _222.removeEventListener, 'call', _223 => _223("visibilitychange", onVisibilityChange)]);
|
|
9510
9803
|
};
|
|
9511
9804
|
return [inBackgroundSince, unsub];
|
|
9512
9805
|
}
|
|
@@ -9551,6 +9844,7 @@ function createRoom(options, config) {
|
|
|
9551
9844
|
delegates,
|
|
9552
9845
|
config.enableDebugLogging
|
|
9553
9846
|
);
|
|
9847
|
+
const unacknowledgedOps = new UnacknowledgedOps();
|
|
9554
9848
|
const context = {
|
|
9555
9849
|
buffer: {
|
|
9556
9850
|
flushTimerID: void 0,
|
|
@@ -9578,14 +9872,15 @@ function createRoom(options, config) {
|
|
|
9578
9872
|
pool: createManagedPool(roomId, {
|
|
9579
9873
|
getCurrentConnectionId,
|
|
9580
9874
|
onDispatch,
|
|
9581
|
-
isStorageWritable
|
|
9875
|
+
isStorageWritable,
|
|
9876
|
+
unacknowledgedOps
|
|
9582
9877
|
}),
|
|
9583
9878
|
root: void 0,
|
|
9584
9879
|
undoStack: [],
|
|
9585
9880
|
redoStack: [],
|
|
9586
9881
|
pausedHistory: null,
|
|
9587
9882
|
activeBatch: null,
|
|
9588
|
-
unacknowledgedOps
|
|
9883
|
+
unacknowledgedOps
|
|
9589
9884
|
};
|
|
9590
9885
|
const nodeMapBuffer = makeNodeMapBuffer();
|
|
9591
9886
|
const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
|
|
@@ -9652,6 +9947,7 @@ function createRoom(options, config) {
|
|
|
9652
9947
|
}
|
|
9653
9948
|
function onDidDisconnect() {
|
|
9654
9949
|
clearTimeout(context.buffer.flushTimerID);
|
|
9950
|
+
context.unacknowledgedOps.markAllAsPossiblyStored();
|
|
9655
9951
|
}
|
|
9656
9952
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
9657
9953
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -9697,7 +9993,7 @@ function createRoom(options, config) {
|
|
|
9697
9993
|
}
|
|
9698
9994
|
}
|
|
9699
9995
|
function isStorageWritable() {
|
|
9700
|
-
const scopes = _optionalChain([context, 'access',
|
|
9996
|
+
const scopes = _optionalChain([context, 'access', _224 => _224.dynamicSessionInfoSig, 'access', _225 => _225.get, 'call', _226 => _226(), 'optionalAccess', _227 => _227.scopes]);
|
|
9701
9997
|
return scopes !== void 0 ? hasPermissionCapability(scopes, "storage", "write") : true;
|
|
9702
9998
|
}
|
|
9703
9999
|
const eventHub = {
|
|
@@ -9809,7 +10105,7 @@ function createRoom(options, config) {
|
|
|
9809
10105
|
context.pool
|
|
9810
10106
|
);
|
|
9811
10107
|
}
|
|
9812
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
10108
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _228 => _228.get, 'call', _229 => _229(), 'optionalAccess', _230 => _230.canWrite]), () => ( true));
|
|
9813
10109
|
const root = context.root;
|
|
9814
10110
|
disableHistory(() => {
|
|
9815
10111
|
for (const key in context.initialStorage) {
|
|
@@ -10014,7 +10310,7 @@ function createRoom(options, config) {
|
|
|
10014
10310
|
}
|
|
10015
10311
|
context.myPresence.patch(patch);
|
|
10016
10312
|
if (context.activeBatch) {
|
|
10017
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10313
|
+
if (_optionalChain([options2, 'optionalAccess', _231 => _231.addToHistory])) {
|
|
10018
10314
|
context.activeBatch.reverseOps.pushLeft({
|
|
10019
10315
|
type: "presence",
|
|
10020
10316
|
data: oldValues
|
|
@@ -10023,7 +10319,7 @@ function createRoom(options, config) {
|
|
|
10023
10319
|
context.activeBatch.updates.presence = true;
|
|
10024
10320
|
} else {
|
|
10025
10321
|
flushNowOrSoon();
|
|
10026
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10322
|
+
if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
|
|
10027
10323
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
10028
10324
|
}
|
|
10029
10325
|
notify({ presence: true });
|
|
@@ -10132,12 +10428,11 @@ function createRoom(options, config) {
|
|
|
10132
10428
|
}
|
|
10133
10429
|
}
|
|
10134
10430
|
function applyAndSendOfflineOps(unackedOps) {
|
|
10135
|
-
if (unackedOps.
|
|
10431
|
+
if (unackedOps.length === 0) {
|
|
10136
10432
|
return;
|
|
10137
10433
|
}
|
|
10138
10434
|
const messages = [];
|
|
10139
|
-
const
|
|
10140
|
-
const result = applyLocalOps(inOps);
|
|
10435
|
+
const result = applyLocalOps(unackedOps);
|
|
10141
10436
|
messages.push({
|
|
10142
10437
|
type: ClientMsgCode.UPDATE_STORAGE,
|
|
10143
10438
|
ops: result.opsToEmit
|
|
@@ -10201,11 +10496,11 @@ function createRoom(options, config) {
|
|
|
10201
10496
|
break;
|
|
10202
10497
|
}
|
|
10203
10498
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
10204
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10499
|
+
_optionalChain([stopwatch, 'optionalAccess', _233 => _233.lap, 'call', _234 => _234()]);
|
|
10205
10500
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
10206
10501
|
break;
|
|
10207
10502
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
10208
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
10503
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _235 => _235.stop, 'call', _236 => _236()]);
|
|
10209
10504
|
if (timing) {
|
|
10210
10505
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
10211
10506
|
const rest = timing.laps.slice(1);
|
|
@@ -10340,11 +10635,11 @@ function createRoom(options, config) {
|
|
|
10340
10635
|
} else if (pendingFeedsRequests.has(requestId)) {
|
|
10341
10636
|
const pending = pendingFeedsRequests.get(requestId);
|
|
10342
10637
|
pendingFeedsRequests.delete(requestId);
|
|
10343
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10638
|
+
_optionalChain([pending, 'optionalAccess', _237 => _237.reject, 'call', _238 => _238(err)]);
|
|
10344
10639
|
} else if (pendingFeedMessagesRequests.has(requestId)) {
|
|
10345
10640
|
const pending = pendingFeedMessagesRequests.get(requestId);
|
|
10346
10641
|
pendingFeedMessagesRequests.delete(requestId);
|
|
10347
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10642
|
+
_optionalChain([pending, 'optionalAccess', _239 => _239.reject, 'call', _240 => _240(err)]);
|
|
10348
10643
|
}
|
|
10349
10644
|
eventHub.feeds.notify(message);
|
|
10350
10645
|
break;
|
|
@@ -10361,7 +10656,7 @@ function createRoom(options, config) {
|
|
|
10361
10656
|
const storageOps = context.buffer.storageOperations;
|
|
10362
10657
|
if (storageOps.length > 0) {
|
|
10363
10658
|
for (const op of storageOps) {
|
|
10364
|
-
context.unacknowledgedOps.
|
|
10659
|
+
context.unacknowledgedOps.add(op);
|
|
10365
10660
|
}
|
|
10366
10661
|
notifyStorageStatus();
|
|
10367
10662
|
}
|
|
@@ -10498,10 +10793,10 @@ function createRoom(options, config) {
|
|
|
10498
10793
|
timeoutId,
|
|
10499
10794
|
kind,
|
|
10500
10795
|
feedId,
|
|
10501
|
-
messageId: _optionalChain([options2, 'optionalAccess',
|
|
10502
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
10796
|
+
messageId: _optionalChain([options2, 'optionalAccess', _241 => _241.messageId]),
|
|
10797
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _242 => _242.expectedClientMessageId])
|
|
10503
10798
|
});
|
|
10504
|
-
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess',
|
|
10799
|
+
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _243 => _243.expectedClientMessageId]) === void 0) {
|
|
10505
10800
|
const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
|
|
10506
10801
|
q.push(requestId);
|
|
10507
10802
|
pendingAddMessageFifoByFeed.set(feedId, q);
|
|
@@ -10552,10 +10847,10 @@ function createRoom(options, config) {
|
|
|
10552
10847
|
}
|
|
10553
10848
|
if (!matched) {
|
|
10554
10849
|
const q = pendingAddMessageFifoByFeed.get(message.feedId);
|
|
10555
|
-
const headId = _optionalChain([q, 'optionalAccess',
|
|
10850
|
+
const headId = _optionalChain([q, 'optionalAccess', _244 => _244[0]]);
|
|
10556
10851
|
if (headId !== void 0) {
|
|
10557
10852
|
const pending = pendingFeedMutations.get(headId);
|
|
10558
|
-
if (_optionalChain([pending, 'optionalAccess',
|
|
10853
|
+
if (_optionalChain([pending, 'optionalAccess', _245 => _245.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
|
|
10559
10854
|
settleFeedMutation(headId, "ok");
|
|
10560
10855
|
}
|
|
10561
10856
|
}
|
|
@@ -10588,10 +10883,10 @@ function createRoom(options, config) {
|
|
|
10588
10883
|
}
|
|
10589
10884
|
}
|
|
10590
10885
|
function processInitialStorage(nodes) {
|
|
10591
|
-
const
|
|
10886
|
+
const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
|
|
10592
10887
|
createOrUpdateRootFromMessage(nodes);
|
|
10593
|
-
applyAndSendOfflineOps(
|
|
10594
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
10888
|
+
applyAndSendOfflineOps(unacknowledgedOps2);
|
|
10889
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _246 => _246()]);
|
|
10595
10890
|
notifyStorageStatus();
|
|
10596
10891
|
eventHub.storageDidLoad.notify();
|
|
10597
10892
|
}
|
|
@@ -10609,7 +10904,7 @@ function createRoom(options, config) {
|
|
|
10609
10904
|
} else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
10610
10905
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
10611
10906
|
nodeMapBuffer.take();
|
|
10612
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10907
|
+
_optionalChain([stopwatch, 'optionalAccess', _247 => _247.start, 'call', _248 => _248()]);
|
|
10613
10908
|
}
|
|
10614
10909
|
if (options2.flush) {
|
|
10615
10910
|
flushNowOrSoon();
|
|
@@ -10665,10 +10960,10 @@ function createRoom(options, config) {
|
|
|
10665
10960
|
const message = {
|
|
10666
10961
|
type: ClientMsgCode.FETCH_FEEDS,
|
|
10667
10962
|
requestId,
|
|
10668
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
10669
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
10670
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
10671
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
10963
|
+
cursor: _optionalChain([options2, 'optionalAccess', _249 => _249.cursor]),
|
|
10964
|
+
since: _optionalChain([options2, 'optionalAccess', _250 => _250.since]),
|
|
10965
|
+
limit: _optionalChain([options2, 'optionalAccess', _251 => _251.limit]),
|
|
10966
|
+
metadata: _optionalChain([options2, 'optionalAccess', _252 => _252.metadata])
|
|
10672
10967
|
};
|
|
10673
10968
|
context.buffer.messages.push(message);
|
|
10674
10969
|
flushNowOrSoon();
|
|
@@ -10688,9 +10983,9 @@ function createRoom(options, config) {
|
|
|
10688
10983
|
type: ClientMsgCode.FETCH_FEED_MESSAGES,
|
|
10689
10984
|
requestId,
|
|
10690
10985
|
feedId,
|
|
10691
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
10692
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
10693
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
10986
|
+
cursor: _optionalChain([options2, 'optionalAccess', _253 => _253.cursor]),
|
|
10987
|
+
since: _optionalChain([options2, 'optionalAccess', _254 => _254.since]),
|
|
10988
|
+
limit: _optionalChain([options2, 'optionalAccess', _255 => _255.limit])
|
|
10694
10989
|
};
|
|
10695
10990
|
context.buffer.messages.push(message);
|
|
10696
10991
|
flushNowOrSoon();
|
|
@@ -10709,8 +11004,8 @@ function createRoom(options, config) {
|
|
|
10709
11004
|
type: ClientMsgCode.ADD_FEED,
|
|
10710
11005
|
requestId,
|
|
10711
11006
|
feedId,
|
|
10712
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
10713
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11007
|
+
metadata: _optionalChain([options2, 'optionalAccess', _256 => _256.metadata]),
|
|
11008
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _257 => _257.createdAt])
|
|
10714
11009
|
};
|
|
10715
11010
|
context.buffer.messages.push(message);
|
|
10716
11011
|
flushNowOrSoon();
|
|
@@ -10744,15 +11039,15 @@ function createRoom(options, config) {
|
|
|
10744
11039
|
function addFeedMessage(feedId, data, options2) {
|
|
10745
11040
|
const requestId = nanoid();
|
|
10746
11041
|
const promise = registerFeedMutation(requestId, "add-message", feedId, {
|
|
10747
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11042
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _258 => _258.id])
|
|
10748
11043
|
});
|
|
10749
11044
|
const message = {
|
|
10750
11045
|
type: ClientMsgCode.ADD_FEED_MESSAGE,
|
|
10751
11046
|
requestId,
|
|
10752
11047
|
feedId,
|
|
10753
11048
|
data,
|
|
10754
|
-
id: _optionalChain([options2, 'optionalAccess',
|
|
10755
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11049
|
+
id: _optionalChain([options2, 'optionalAccess', _259 => _259.id]),
|
|
11050
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _260 => _260.createdAt])
|
|
10756
11051
|
};
|
|
10757
11052
|
context.buffer.messages.push(message);
|
|
10758
11053
|
flushNowOrSoon();
|
|
@@ -10769,7 +11064,7 @@ function createRoom(options, config) {
|
|
|
10769
11064
|
feedId,
|
|
10770
11065
|
messageId,
|
|
10771
11066
|
data,
|
|
10772
|
-
updatedAt: _optionalChain([options2, 'optionalAccess',
|
|
11067
|
+
updatedAt: _optionalChain([options2, 'optionalAccess', _261 => _261.updatedAt])
|
|
10773
11068
|
};
|
|
10774
11069
|
context.buffer.messages.push(message);
|
|
10775
11070
|
flushNowOrSoon();
|
|
@@ -10976,8 +11271,8 @@ function createRoom(options, config) {
|
|
|
10976
11271
|
async function getThreads(options2) {
|
|
10977
11272
|
return httpClient.getThreads({
|
|
10978
11273
|
roomId,
|
|
10979
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
10980
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
11274
|
+
query: _optionalChain([options2, 'optionalAccess', _262 => _262.query]),
|
|
11275
|
+
cursor: _optionalChain([options2, 'optionalAccess', _263 => _263.cursor])
|
|
10981
11276
|
});
|
|
10982
11277
|
}
|
|
10983
11278
|
async function getThread(threadId) {
|
|
@@ -11099,7 +11394,7 @@ function createRoom(options, config) {
|
|
|
11099
11394
|
function getSubscriptionSettings(options2) {
|
|
11100
11395
|
return httpClient.getSubscriptionSettings({
|
|
11101
11396
|
roomId,
|
|
11102
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
11397
|
+
signal: _optionalChain([options2, 'optionalAccess', _264 => _264.signal])
|
|
11103
11398
|
});
|
|
11104
11399
|
}
|
|
11105
11400
|
function updateSubscriptionSettings(settings) {
|
|
@@ -11121,7 +11416,7 @@ function createRoom(options, config) {
|
|
|
11121
11416
|
{
|
|
11122
11417
|
[kInternal]: {
|
|
11123
11418
|
get presenceBuffer() {
|
|
11124
|
-
return deepClone(_nullishCoalesce(_optionalChain([context, 'access',
|
|
11419
|
+
return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _265 => _265.buffer, 'access', _266 => _266.presenceUpdates, 'optionalAccess', _267 => _267.data]), () => ( null)));
|
|
11125
11420
|
},
|
|
11126
11421
|
// prettier-ignore
|
|
11127
11422
|
get undoStack() {
|
|
@@ -11136,9 +11431,9 @@ function createRoom(options, config) {
|
|
|
11136
11431
|
return context.yjsProvider;
|
|
11137
11432
|
},
|
|
11138
11433
|
setYjsProvider(newProvider) {
|
|
11139
|
-
_optionalChain([context, 'access',
|
|
11434
|
+
_optionalChain([context, 'access', _268 => _268.yjsProvider, 'optionalAccess', _269 => _269.off, 'call', _270 => _270("status", yjsStatusDidChange)]);
|
|
11140
11435
|
context.yjsProvider = newProvider;
|
|
11141
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
11436
|
+
_optionalChain([newProvider, 'optionalAccess', _271 => _271.on, 'call', _272 => _272("status", yjsStatusDidChange)]);
|
|
11142
11437
|
context.yjsProviderDidChange.notify();
|
|
11143
11438
|
},
|
|
11144
11439
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
@@ -11179,6 +11474,11 @@ function createRoom(options, config) {
|
|
|
11179
11474
|
connect: () => managedSocket.connect(),
|
|
11180
11475
|
reconnect: () => managedSocket.reconnect(),
|
|
11181
11476
|
disconnect: () => managedSocket.disconnect(),
|
|
11477
|
+
_dump: () => {
|
|
11478
|
+
const n = context.pool.nodes.size;
|
|
11479
|
+
return `Room "${roomId}" (${n} node${n === 1 ? "" : "s"}):
|
|
11480
|
+
${dumpPool(context.pool)}`;
|
|
11481
|
+
},
|
|
11182
11482
|
destroy: () => {
|
|
11183
11483
|
pendingFeedsRequests.forEach(
|
|
11184
11484
|
(request) => request.reject(new Error("Room destroyed"))
|
|
@@ -11191,7 +11491,7 @@ function createRoom(options, config) {
|
|
|
11191
11491
|
source.dispose();
|
|
11192
11492
|
}
|
|
11193
11493
|
eventHub.roomWillDestroy.notify();
|
|
11194
|
-
_optionalChain([context, 'access',
|
|
11494
|
+
_optionalChain([context, 'access', _273 => _273.yjsProvider, 'optionalAccess', _274 => _274.off, 'call', _275 => _275("status", yjsStatusDidChange)]);
|
|
11195
11495
|
syncSourceForStorage.destroy();
|
|
11196
11496
|
syncSourceForYjs.destroy();
|
|
11197
11497
|
uninstallBgTabSpy();
|
|
@@ -11351,7 +11651,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
11351
11651
|
}
|
|
11352
11652
|
if (isLiveNode(first)) {
|
|
11353
11653
|
const node = first;
|
|
11354
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
11654
|
+
if (_optionalChain([options, 'optionalAccess', _276 => _276.isDeep])) {
|
|
11355
11655
|
const storageCallback = second;
|
|
11356
11656
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
11357
11657
|
} else {
|
|
@@ -11441,8 +11741,8 @@ function createClient(options) {
|
|
|
11441
11741
|
const authManager = createAuthManager(options, (token) => {
|
|
11442
11742
|
currentUserId.set(() => token.uid);
|
|
11443
11743
|
});
|
|
11444
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
11445
|
-
_optionalChain([globalThis, 'access',
|
|
11744
|
+
const fetchPolyfill = _optionalChain([clientOptions, 'access', _277 => _277.polyfills, 'optionalAccess', _278 => _278.fetch]) || /* istanbul ignore next */
|
|
11745
|
+
_optionalChain([globalThis, 'access', _279 => _279.fetch, 'optionalAccess', _280 => _280.bind, 'call', _281 => _281(globalThis)]);
|
|
11446
11746
|
const httpClient = createApiClient({
|
|
11447
11747
|
baseUrl,
|
|
11448
11748
|
fetchPolyfill,
|
|
@@ -11460,7 +11760,7 @@ function createClient(options) {
|
|
|
11460
11760
|
delegates: {
|
|
11461
11761
|
createSocket: makeCreateSocketDelegateForAi(
|
|
11462
11762
|
baseUrl,
|
|
11463
|
-
_optionalChain([clientOptions, 'access',
|
|
11763
|
+
_optionalChain([clientOptions, 'access', _282 => _282.polyfills, 'optionalAccess', _283 => _283.WebSocket])
|
|
11464
11764
|
),
|
|
11465
11765
|
authenticate: async () => {
|
|
11466
11766
|
const resp = await authManager.getAuthValue({
|
|
@@ -11532,7 +11832,7 @@ function createClient(options) {
|
|
|
11532
11832
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
11533
11833
|
roomId,
|
|
11534
11834
|
baseUrl,
|
|
11535
|
-
_optionalChain([clientOptions, 'access',
|
|
11835
|
+
_optionalChain([clientOptions, 'access', _284 => _284.polyfills, 'optionalAccess', _285 => _285.WebSocket])
|
|
11536
11836
|
),
|
|
11537
11837
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
11538
11838
|
})),
|
|
@@ -11555,7 +11855,7 @@ function createClient(options) {
|
|
|
11555
11855
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
11556
11856
|
if (shouldConnect) {
|
|
11557
11857
|
if (typeof atob === "undefined") {
|
|
11558
|
-
if (_optionalChain([clientOptions, 'access',
|
|
11858
|
+
if (_optionalChain([clientOptions, 'access', _286 => _286.polyfills, 'optionalAccess', _287 => _287.atob]) === void 0) {
|
|
11559
11859
|
throw new Error(
|
|
11560
11860
|
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
11561
11861
|
);
|
|
@@ -11567,7 +11867,7 @@ function createClient(options) {
|
|
|
11567
11867
|
return leaseRoom(newRoomDetails);
|
|
11568
11868
|
}
|
|
11569
11869
|
function getRoom(roomId) {
|
|
11570
|
-
const room = _optionalChain([roomsById, 'access',
|
|
11870
|
+
const room = _optionalChain([roomsById, 'access', _288 => _288.get, 'call', _289 => _289(roomId), 'optionalAccess', _290 => _290.room]);
|
|
11571
11871
|
return room ? room : null;
|
|
11572
11872
|
}
|
|
11573
11873
|
function logout() {
|
|
@@ -11583,7 +11883,7 @@ function createClient(options) {
|
|
|
11583
11883
|
const batchedResolveUsers = new Batch(
|
|
11584
11884
|
async (batchedUserIds) => {
|
|
11585
11885
|
const userIds = batchedUserIds.flat();
|
|
11586
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
11886
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _291 => _291({ userIds })]);
|
|
11587
11887
|
warnOnceIf(
|
|
11588
11888
|
!resolveUsers,
|
|
11589
11889
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -11600,7 +11900,7 @@ function createClient(options) {
|
|
|
11600
11900
|
const batchedResolveRoomsInfo = new Batch(
|
|
11601
11901
|
async (batchedRoomIds) => {
|
|
11602
11902
|
const roomIds = batchedRoomIds.flat();
|
|
11603
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
11903
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _292 => _292({ roomIds })]);
|
|
11604
11904
|
warnOnceIf(
|
|
11605
11905
|
!resolveRoomsInfo,
|
|
11606
11906
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -11617,7 +11917,7 @@ function createClient(options) {
|
|
|
11617
11917
|
const batchedResolveGroupsInfo = new Batch(
|
|
11618
11918
|
async (batchedGroupIds) => {
|
|
11619
11919
|
const groupIds = batchedGroupIds.flat();
|
|
11620
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
11920
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _293 => _293({ groupIds })]);
|
|
11621
11921
|
warnOnceIf(
|
|
11622
11922
|
!resolveGroupsInfo,
|
|
11623
11923
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -11676,7 +11976,7 @@ function createClient(options) {
|
|
|
11676
11976
|
}
|
|
11677
11977
|
};
|
|
11678
11978
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
11679
|
-
_optionalChain([win, 'optionalAccess',
|
|
11979
|
+
_optionalChain([win, 'optionalAccess', _294 => _294.addEventListener, 'call', _295 => _295("beforeunload", maybePreventClose)]);
|
|
11680
11980
|
}
|
|
11681
11981
|
async function getNotificationSettings(options2) {
|
|
11682
11982
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -11692,6 +11992,7 @@ function createClient(options) {
|
|
|
11692
11992
|
{
|
|
11693
11993
|
enterRoom,
|
|
11694
11994
|
getRoom,
|
|
11995
|
+
_dump: () => Array.from(roomsById.values(), ({ room }) => room._dump()).join("\n\n"),
|
|
11695
11996
|
logout,
|
|
11696
11997
|
// Public inbox notifications API
|
|
11697
11998
|
getInboxNotifications: httpClient.getInboxNotifications,
|
|
@@ -11803,7 +12104,7 @@ var commentBodyElementsTypes = {
|
|
|
11803
12104
|
mention: "inline"
|
|
11804
12105
|
};
|
|
11805
12106
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
11806
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
12107
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _296 => _296.content])) {
|
|
11807
12108
|
return;
|
|
11808
12109
|
}
|
|
11809
12110
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -11813,13 +12114,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
11813
12114
|
for (const block of body.content) {
|
|
11814
12115
|
if (type === "all" || type === "block") {
|
|
11815
12116
|
if (guard(block)) {
|
|
11816
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12117
|
+
_optionalChain([visitor, 'optionalCall', _297 => _297(block)]);
|
|
11817
12118
|
}
|
|
11818
12119
|
}
|
|
11819
12120
|
if (type === "all" || type === "inline") {
|
|
11820
12121
|
for (const inline of block.children) {
|
|
11821
12122
|
if (guard(inline)) {
|
|
11822
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12123
|
+
_optionalChain([visitor, 'optionalCall', _298 => _298(inline)]);
|
|
11823
12124
|
}
|
|
11824
12125
|
}
|
|
11825
12126
|
}
|
|
@@ -11989,7 +12290,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
11989
12290
|
text: ({ element }) => element.text,
|
|
11990
12291
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
11991
12292
|
mention: ({ element, user, group }) => {
|
|
11992
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12293
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _299 => _299.name]), () => ( _optionalChain([group, 'optionalAccess', _300 => _300.name]))), () => ( element.id))}`;
|
|
11993
12294
|
}
|
|
11994
12295
|
};
|
|
11995
12296
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -12019,7 +12320,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
12019
12320
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
12020
12321
|
},
|
|
12021
12322
|
mention: ({ element, user, group }) => {
|
|
12022
|
-
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess',
|
|
12323
|
+
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _301 => _301.name]) ? html`${_optionalChain([user, 'optionalAccess', _302 => _302.name])}` : _optionalChain([group, 'optionalAccess', _303 => _303.name]) ? html`${_optionalChain([group, 'optionalAccess', _304 => _304.name])}` : element.id}</span>`;
|
|
12023
12324
|
}
|
|
12024
12325
|
};
|
|
12025
12326
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -12049,20 +12350,20 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
12049
12350
|
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
12050
12351
|
},
|
|
12051
12352
|
mention: ({ element, user, group }) => {
|
|
12052
|
-
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12353
|
+
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _305 => _305.name]), () => ( _optionalChain([group, 'optionalAccess', _306 => _306.name]))), () => ( element.id))}`;
|
|
12053
12354
|
}
|
|
12054
12355
|
};
|
|
12055
12356
|
async function stringifyCommentBody(body, options) {
|
|
12056
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12057
|
-
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12357
|
+
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _307 => _307.format]), () => ( "plain"));
|
|
12358
|
+
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _308 => _308.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
12058
12359
|
const elements = {
|
|
12059
12360
|
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
12060
|
-
..._optionalChain([options, 'optionalAccess',
|
|
12361
|
+
..._optionalChain([options, 'optionalAccess', _309 => _309.elements])
|
|
12061
12362
|
};
|
|
12062
12363
|
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
12063
12364
|
body,
|
|
12064
|
-
_optionalChain([options, 'optionalAccess',
|
|
12065
|
-
_optionalChain([options, 'optionalAccess',
|
|
12365
|
+
_optionalChain([options, 'optionalAccess', _310 => _310.resolveUsers]),
|
|
12366
|
+
_optionalChain([options, 'optionalAccess', _311 => _311.resolveGroupsInfo])
|
|
12066
12367
|
);
|
|
12067
12368
|
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
12068
12369
|
switch (block.type) {
|
|
@@ -12197,9 +12498,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
12197
12498
|
const startTime = performance.now();
|
|
12198
12499
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
12199
12500
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
12200
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12501
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _312 => _312.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
12201
12502
|
const context = {
|
|
12202
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
12503
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _313 => _313.visibilityState]) !== "hidden",
|
|
12203
12504
|
lastSuccessfulPollAt: startTime,
|
|
12204
12505
|
count: 0,
|
|
12205
12506
|
backoff: 0
|
|
@@ -12280,11 +12581,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
12280
12581
|
pollNowIfStale();
|
|
12281
12582
|
}
|
|
12282
12583
|
function onVisibilityChange() {
|
|
12283
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
12584
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _314 => _314.visibilityState]) !== "hidden");
|
|
12284
12585
|
}
|
|
12285
|
-
_optionalChain([doc, 'optionalAccess',
|
|
12286
|
-
_optionalChain([win, 'optionalAccess',
|
|
12287
|
-
_optionalChain([win, 'optionalAccess',
|
|
12586
|
+
_optionalChain([doc, 'optionalAccess', _315 => _315.addEventListener, 'call', _316 => _316("visibilitychange", onVisibilityChange)]);
|
|
12587
|
+
_optionalChain([win, 'optionalAccess', _317 => _317.addEventListener, 'call', _318 => _318("online", onVisibilityChange)]);
|
|
12588
|
+
_optionalChain([win, 'optionalAccess', _319 => _319.addEventListener, 'call', _320 => _320("focus", pollNowIfStale)]);
|
|
12288
12589
|
fsm.start();
|
|
12289
12590
|
return {
|
|
12290
12591
|
inc,
|
|
@@ -12428,5 +12729,6 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
12428
12729
|
|
|
12429
12730
|
|
|
12430
12731
|
|
|
12431
|
-
|
|
12732
|
+
|
|
12733
|
+
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getRoomPermissionConflicts = getRoomPermissionConflicts; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionCapability = hasPermissionCapability; exports.hasPermissionCapabilityAccess = hasPermissionCapabilityAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccessesInput = normalizeRoomAccessesInput; exports.normalizeRoomAccessesUpdateInput = normalizeRoomAccessesUpdateInput; exports.normalizeRoomPermissionInput = normalizeRoomPermissionInput; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionCapabilitiesFromScopes = permissionCapabilitiesFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
12432
12734
|
//# sourceMappingURL=index.cjs.map
|