@liveblocks/core 3.19.4-test1 → 3.19.5-rc1

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 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.19.4-test1";
9
+ var PKG_VERSION = "3.19.5-rc1";
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)) {
@@ -2715,6 +2729,7 @@ var HttpClient = class {
2715
2729
  };
2716
2730
 
2717
2731
  // src/lib/fsm.ts
2732
+ var IGNORE = /* @__PURE__ */ Symbol("fsm.ignore");
2718
2733
  function distance(state1, state2) {
2719
2734
  if (state1 === state2) {
2720
2735
  return [0, 0];
@@ -2887,7 +2902,7 @@ var FSM = class {
2887
2902
  this.#eventHub = {
2888
2903
  didReceiveEvent: makeEventSource(),
2889
2904
  willTransition: makeEventSource(),
2890
- didIgnoreEvent: makeEventSource(),
2905
+ didIgnoreUnexpectedEvent: makeEventSource(),
2891
2906
  willExitState: makeEventSource(),
2892
2907
  didEnterState: makeEventSource(),
2893
2908
  didExitState: makeEventSource()
@@ -2895,7 +2910,7 @@ var FSM = class {
2895
2910
  this.events = {
2896
2911
  didReceiveEvent: this.#eventHub.didReceiveEvent.observable,
2897
2912
  willTransition: this.#eventHub.willTransition.observable,
2898
- didIgnoreEvent: this.#eventHub.didIgnoreEvent.observable,
2913
+ didIgnoreUnexpectedEvent: this.#eventHub.didIgnoreUnexpectedEvent.observable,
2899
2914
  willExitState: this.#eventHub.willExitState.observable,
2900
2915
  didEnterState: this.#eventHub.didEnterState.observable,
2901
2916
  didExitState: this.#eventHub.didExitState.observable
@@ -3018,9 +3033,14 @@ var FSM = class {
3018
3033
  * `context` params to conditionally decide which next state to transition
3019
3034
  * to.
3020
3035
  *
3021
- * If you set it to `null`, then the transition will be explicitly forbidden
3022
- * and throw an error. If you don't define a target for a transition, then
3023
- * such events will get ignored.
3036
+ * If you don't define a target for a transition, the event is treated
3037
+ * as unhandled in this state: `didIgnoreUnexpectedEvent` fires and the
3038
+ * state does not change.
3039
+ *
3040
+ * To declare an event as an intentional silent no-op in this state, use
3041
+ * the {@link IGNORE} sentinel — either statically (`{ EVENT: IGNORE }`)
3042
+ * or as a return value from a target function. IGNORE'd events do not
3043
+ * fire `didIgnoreUnexpectedEvent`.
3024
3044
  */
3025
3045
  addTransitions(nameOrPattern, mapping) {
3026
3046
  if (this.#runningState !== 0 /* NOT_STARTED_YET */) {
@@ -3040,7 +3060,12 @@ var FSM = class {
3040
3060
  }
3041
3061
  const target = target_;
3042
3062
  this.#knownEventTypes.add(type);
3043
- if (target !== void 0) {
3063
+ if (target === void 0) {
3064
+ continue;
3065
+ }
3066
+ if (target === IGNORE) {
3067
+ map.set(type, IGNORE);
3068
+ } else {
3044
3069
  const targetFn = typeof target === "function" ? target : () => target;
3045
3070
  map.set(type, targetFn);
3046
3071
  }
@@ -3139,12 +3164,14 @@ var FSM = class {
3139
3164
  if (this.#runningState === 2 /* STOPPED */) {
3140
3165
  return;
3141
3166
  }
3142
- const targetFn = this.#getTargetFn(event.type);
3143
- if (targetFn !== void 0) {
3144
- return this.#transition(event, targetFn);
3145
- } else {
3146
- this.#eventHub.didIgnoreEvent.notify(event);
3167
+ const entry = this.#getTargetFn(event.type);
3168
+ if (entry === IGNORE) {
3169
+ return;
3170
+ }
3171
+ if (entry !== void 0) {
3172
+ return this.#transition(event, entry);
3147
3173
  }
3174
+ this.#eventHub.didIgnoreUnexpectedEvent.notify(event);
3148
3175
  }
3149
3176
  #transition(event, target) {
3150
3177
  this.#eventHub.didReceiveEvent.notify(event);
@@ -3153,8 +3180,7 @@ var FSM = class {
3153
3180
  const nextTarget = targetFn(event, this.#currentContext.current);
3154
3181
  let nextState;
3155
3182
  let effects = void 0;
3156
- if (nextTarget === null) {
3157
- this.#eventHub.didIgnoreEvent.notify(event);
3183
+ if (nextTarget === IGNORE) {
3158
3184
  return;
3159
3185
  }
3160
3186
  if (typeof nextTarget === "string") {
@@ -3373,8 +3399,8 @@ function enableTracing(machine) {
3373
3399
  machine.events.didExitState.subscribe(
3374
3400
  ({ state, durationMs }) => log2(`Exited ${state} after ${durationMs.toFixed(0)}ms`)
3375
3401
  ),
3376
- machine.events.didIgnoreEvent.subscribe(
3377
- (e) => log2("Ignored event", e.type, e, "(current state won't handle it)")
3402
+ machine.events.didIgnoreUnexpectedEvent.subscribe(
3403
+ (e) => log2("Ignored unexpected event", e.type, e, "(no transition declared)")
3378
3404
  )
3379
3405
  ];
3380
3406
  return () => {
@@ -3486,7 +3512,12 @@ function createConnectionStateMachine(delegates, options) {
3486
3512
  );
3487
3513
  const onSocketError = (event) => machine.send({ type: "EXPLICIT_SOCKET_ERROR", event });
3488
3514
  const onSocketClose = (event) => machine.send({ type: "EXPLICIT_SOCKET_CLOSE", event });
3489
- const onSocketMessage = (event) => event.data === "pong" ? machine.send({ type: "PONG" }) : onMessage.notify(event);
3515
+ const onSocketMessage = (event) => {
3516
+ machine.send({ type: "ALIVE" });
3517
+ if (event.data !== "pong") {
3518
+ onMessage.notify(event);
3519
+ }
3520
+ };
3490
3521
  function teardownSocket(socket) {
3491
3522
  if (socket) {
3492
3523
  socket.removeEventListener("error", onSocketError);
@@ -3656,7 +3687,13 @@ function createConnectionStateMachine(delegates, options) {
3656
3687
  effect: [increaseBackoffDelay, logPrematureErrorOrCloseEvent(err)]
3657
3688
  };
3658
3689
  }
3659
- );
3690
+ ).addTransitions("@connecting.busy", {
3691
+ // The socket message listener is attached during @connecting.busy (see
3692
+ // onEnterAsync above), so server frames (most notably the actor-id
3693
+ // handshake) can fire onSocketMessage and emit a ALIVE before we
3694
+ // reach @ok.*. That's fine. Heartbeat only matters in @ok.*.
3695
+ ALIVE: IGNORE
3696
+ });
3660
3697
  const sendHeartbeat = {
3661
3698
  target: "@ok.awaiting-pong",
3662
3699
  effect: (ctx) => {
@@ -3671,7 +3708,8 @@ function createConnectionStateMachine(delegates, options) {
3671
3708
  machine.addTimedTransition("@ok.connected", HEARTBEAT_INTERVAL, maybeHeartbeat).addTransitions("@ok.connected", {
3672
3709
  NAVIGATOR_OFFLINE: maybeHeartbeat,
3673
3710
  // Don't take the browser's word for it when it says it's offline. Do a ping/pong to make sure.
3674
- WINDOW_GOT_FOCUS: sendHeartbeat
3711
+ WINDOW_GOT_FOCUS: sendHeartbeat,
3712
+ ALIVE: IGNORE
3675
3713
  });
3676
3714
  machine.addTransitions("@idle.zombie", {
3677
3715
  WINDOW_GOT_FOCUS: "@connecting.backoff"
@@ -3692,7 +3730,7 @@ function createConnectionStateMachine(delegates, options) {
3692
3730
  clearTimeout(timerID);
3693
3731
  onMessage.pause();
3694
3732
  };
3695
- }).addTransitions("@ok.awaiting-pong", { PONG: "@ok.connected" }).addTimedTransition("@ok.awaiting-pong", PONG_TIMEOUT, {
3733
+ }).addTransitions("@ok.awaiting-pong", { ALIVE: "@ok.connected" }).addTimedTransition("@ok.awaiting-pong", PONG_TIMEOUT, {
3696
3734
  target: "@connecting.busy",
3697
3735
  // Log implicit connection loss and drop the current open socket
3698
3736
  effect: log(
@@ -3705,7 +3743,7 @@ function createConnectionStateMachine(delegates, options) {
3705
3743
  // not. When still OPEN, don't transition.
3706
3744
  EXPLICIT_SOCKET_ERROR: (_, context) => {
3707
3745
  if (_optionalChain([context, 'access', _48 => _48.socket, 'optionalAccess', _49 => _49.readyState]) === 1) {
3708
- return null;
3746
+ return IGNORE;
3709
3747
  }
3710
3748
  return {
3711
3749
  target: "@connecting.backoff",
@@ -5473,21 +5511,21 @@ var OpCode = Object.freeze({
5473
5511
  DELETE_CRDT: 5,
5474
5512
  DELETE_OBJECT_KEY: 6,
5475
5513
  CREATE_MAP: 7,
5476
- CREATE_REGISTER: 8,
5477
- CREATE_TEXT: 9,
5478
- UPDATE_TEXT: 10
5514
+ CREATE_REGISTER: 8
5479
5515
  });
5480
5516
  function isIgnoredOp(op) {
5481
5517
  return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
5482
5518
  }
5519
+ function isCreateOp(op) {
5520
+ return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
5521
+ }
5483
5522
 
5484
5523
  // src/protocol/StorageNode.ts
5485
5524
  var CrdtType = Object.freeze({
5486
5525
  OBJECT: 0,
5487
5526
  LIST: 1,
5488
5527
  MAP: 2,
5489
- REGISTER: 3,
5490
- TEXT: 4
5528
+ REGISTER: 3
5491
5529
  });
5492
5530
  function isRootStorageNode(node) {
5493
5531
  return node[0] === "root";
@@ -5504,9 +5542,6 @@ function isMapStorageNode(node) {
5504
5542
  function isRegisterStorageNode(node) {
5505
5543
  return node[1].type === CrdtType.REGISTER;
5506
5544
  }
5507
- function isTextStorageNode(node) {
5508
- return node[1].type === CrdtType.TEXT;
5509
- }
5510
5545
  function isCompactRootNode(node) {
5511
5546
  return node[0] === "root";
5512
5547
  }
@@ -5529,9 +5564,6 @@ function* compactNodesToNodeStream(compactNodes) {
5529
5564
  case CrdtType.REGISTER:
5530
5565
  yield [cnode[0], { type: CrdtType.REGISTER, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
5531
5566
  break;
5532
- case CrdtType.TEXT:
5533
- yield [cnode[0], { type: CrdtType.TEXT, parentId: cnode[2], parentKey: cnode[3], data: cnode[4], version: cnode[5] }];
5534
- break;
5535
5567
  default:
5536
5568
  }
5537
5569
  }
@@ -5560,17 +5592,6 @@ function* nodeStreamToCompactNodes(nodes) {
5560
5592
  const id = node[0];
5561
5593
  const crdt = node[1];
5562
5594
  yield [id, CrdtType.REGISTER, crdt.parentId, crdt.parentKey, crdt.data];
5563
- } else if (isTextStorageNode(node)) {
5564
- const id = node[0];
5565
- const crdt = node[1];
5566
- yield [
5567
- id,
5568
- CrdtType.TEXT,
5569
- crdt.parentId,
5570
- crdt.parentKey,
5571
- crdt.data,
5572
- crdt.version
5573
- ];
5574
5595
  } else {
5575
5596
  }
5576
5597
  }
@@ -5755,12 +5776,95 @@ function asPos(str) {
5755
5776
  return isPos(str) ? str : convertToPos(str);
5756
5777
  }
5757
5778
 
5779
+ // src/crdts/UnacknowledgedOps.ts
5780
+ var UnacknowledgedOps = class {
5781
+ // opId -> op
5782
+ #byOpId = /* @__PURE__ */ new Map();
5783
+ // position -> (opId -> Create op)
5784
+ #createOpsByPosition = /* @__PURE__ */ new Map();
5785
+ // parentId -> (opId -> Create op)
5786
+ #createOpsByParent = /* @__PURE__ */ new Map();
5787
+ #posKey(parentId, parentKey) {
5788
+ return `${parentId}
5789
+ ${parentKey}`;
5790
+ }
5791
+ get size() {
5792
+ return this.#byOpId.size;
5793
+ }
5794
+ /**
5795
+ * Mark the given Op as still unacknowledged.
5796
+ */
5797
+ add(op) {
5798
+ this.#byOpId.set(op.opId, op);
5799
+ if (isCreateOp(op)) {
5800
+ const posKey = this.#posKey(op.parentId, op.parentKey);
5801
+ let atPosition = this.#createOpsByPosition.get(posKey);
5802
+ if (atPosition === void 0) {
5803
+ atPosition = /* @__PURE__ */ new Map();
5804
+ this.#createOpsByPosition.set(posKey, atPosition);
5805
+ }
5806
+ atPosition.set(op.opId, op);
5807
+ let inParent = this.#createOpsByParent.get(op.parentId);
5808
+ if (inParent === void 0) {
5809
+ inParent = /* @__PURE__ */ new Map();
5810
+ this.#createOpsByParent.set(op.parentId, inParent);
5811
+ }
5812
+ inParent.set(op.opId, op);
5813
+ }
5814
+ }
5815
+ /**
5816
+ * Drop the op with the given opId from the set, because the server has
5817
+ * acknowledged it (confirmed our own op, or signalled it was seen but
5818
+ * ignored).
5819
+ */
5820
+ delete(opId) {
5821
+ const op = this.#byOpId.get(opId);
5822
+ if (op === void 0) {
5823
+ return;
5824
+ }
5825
+ this.#byOpId.delete(opId);
5826
+ if (isCreateOp(op)) {
5827
+ const posKey = this.#posKey(op.parentId, op.parentKey);
5828
+ const atPosition = this.#createOpsByPosition.get(posKey);
5829
+ _optionalChain([atPosition, 'optionalAccess', _111 => _111.delete, 'call', _112 => _112(opId)]);
5830
+ if (atPosition !== void 0 && atPosition.size === 0) {
5831
+ this.#createOpsByPosition.delete(posKey);
5832
+ }
5833
+ const inParent = this.#createOpsByParent.get(op.parentId);
5834
+ _optionalChain([inParent, 'optionalAccess', _113 => _113.delete, 'call', _114 => _114(opId)]);
5835
+ if (inParent !== void 0 && inParent.size === 0) {
5836
+ this.#createOpsByParent.delete(op.parentId);
5837
+ }
5838
+ }
5839
+ }
5840
+ /**
5841
+ * The still-unacknowledged Create ops with the given `parentId` and
5842
+ * `parentKey` (targeting one exact position), in dispatch order. O(1) lookup.
5843
+ * Empty if none.
5844
+ */
5845
+ getByParentIdAndKey(parentId, parentKey) {
5846
+ 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()]), () => ( []));
5847
+ }
5848
+ /**
5849
+ * The still-unacknowledged Create ops with the given `parentId` (across all
5850
+ * positions), in dispatch order. O(1) lookup. Empty if none.
5851
+ */
5852
+ getByParentId(parentId) {
5853
+ return _nullishCoalesce(_optionalChain([this, 'access', _120 => _120.#createOpsByParent, 'access', _121 => _121.get, 'call', _122 => _122(parentId), 'optionalAccess', _123 => _123.values, 'call', _124 => _124()]), () => ( []));
5854
+ }
5855
+ /** All still-unacknowledged ops, in dispatch order. */
5856
+ values() {
5857
+ return this.#byOpId.values();
5858
+ }
5859
+ };
5860
+
5758
5861
  // src/crdts/AbstractCrdt.ts
5759
5862
  function createManagedPool(roomId, options) {
5760
5863
  const {
5761
5864
  getCurrentConnectionId,
5762
5865
  onDispatch,
5763
- isStorageWritable = () => true
5866
+ isStorageWritable = () => true,
5867
+ unacknowledgedOps = new UnacknowledgedOps()
5764
5868
  } = options;
5765
5869
  let clock = 0;
5766
5870
  let opClock = 0;
@@ -5774,7 +5878,7 @@ function createManagedPool(roomId, options) {
5774
5878
  generateId: () => `${getCurrentConnectionId()}:${clock++}`,
5775
5879
  generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
5776
5880
  dispatch(ops, reverse, storageUpdates) {
5777
- _optionalChain([onDispatch, 'optionalCall', _111 => _111(ops, reverse, storageUpdates)]);
5881
+ _optionalChain([onDispatch, 'optionalCall', _125 => _125(ops, reverse, storageUpdates)]);
5778
5882
  },
5779
5883
  assertStorageIsWritable: () => {
5780
5884
  if (!isStorageWritable()) {
@@ -5782,7 +5886,8 @@ function createManagedPool(roomId, options) {
5782
5886
  "Cannot write to storage with a read only user, please ensure the user has write permissions"
5783
5887
  );
5784
5888
  }
5785
- }
5889
+ },
5890
+ unacknowledgedOps
5786
5891
  };
5787
5892
  }
5788
5893
  function crdtAsLiveNode(value) {
@@ -6064,11 +6169,9 @@ function childNodeLt(a, b) {
6064
6169
  var LiveList = class _LiveList extends AbstractCrdt {
6065
6170
  #items;
6066
6171
  #implicitlyDeletedItems;
6067
- #unacknowledgedSets;
6068
6172
  constructor(items) {
6069
6173
  super();
6070
6174
  this.#implicitlyDeletedItems = /* @__PURE__ */ new WeakSet();
6071
- this.#unacknowledgedSets = /* @__PURE__ */ new Map();
6072
6175
  const nodes = [];
6073
6176
  let lastPos;
6074
6177
  for (const item of items) {
@@ -6098,12 +6201,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
6098
6201
  }
6099
6202
  /**
6100
6203
  * @internal
6101
- * This function assumes that the resulting ops will be sent to the server if they have an 'opId'
6102
- * so we mutate _unacknowledgedSets to avoid potential flickering
6103
- * https://github.com/liveblocks/liveblocks/pull/1177
6204
+ * Serializes this list (and its children) into Create ops. Each child's
6205
+ * create is tagged with the "set" intent (in the loop below) so that a list
6206
+ * created and immediately mutated doesn't transiently re-show its initial
6207
+ * items (flicker, https://github.com/liveblocks/liveblocks/pull/1177).
6104
6208
  *
6105
- * This is quite unintuitive and should disappear as soon as
6106
- * we introduce an explicit LiveList.Set operation
6209
+ * This is quite unintuitive and should disappear as soon as we introduce an
6210
+ * explicit LiveList.Set operation.
6107
6211
  */
6108
6212
  _toOps(parentId, parentKey) {
6109
6213
  if (this._id === void 0) {
@@ -6119,9 +6223,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6119
6223
  ops.push(op);
6120
6224
  for (const item of this.#items) {
6121
6225
  const parentKey2 = item._getParentKeyOrThrow();
6122
- const childOps = HACK_addIntentAndDeletedIdToOperation(
6226
+ const childOps = addIntentToRootOp(
6123
6227
  item._toOps(this._id, parentKey2),
6124
- void 0
6228
+ "set"
6125
6229
  );
6126
6230
  for (const childOp of childOps) {
6127
6231
  ops.push(childOp);
@@ -6163,6 +6267,28 @@ var LiveList = class _LiveList extends AbstractCrdt {
6163
6267
  (item) => item._getParentKeyOrThrow() === position
6164
6268
  );
6165
6269
  }
6270
+ /**
6271
+ * The opId of this list's still-unacknowledged "set" op at the given position,
6272
+ * or undefined if none. Derived from the room's unacknowledgedOps (the single
6273
+ * source of truth) rather than tracked in a per-instance map. The pool's
6274
+ * position index already scopes to this list's (parentId, position); the last
6275
+ * match wins, matching the original last-write-wins map semantics.
6276
+ */
6277
+ #unacknowledgedSetOpIdAt(position) {
6278
+ if (this._pool === void 0 || this._id === void 0) {
6279
+ return void 0;
6280
+ }
6281
+ let opId;
6282
+ for (const op of this._pool.unacknowledgedOps.getByParentIdAndKey(
6283
+ this._id,
6284
+ position
6285
+ )) {
6286
+ if (op.intent === "set") {
6287
+ opId = op.opId;
6288
+ }
6289
+ }
6290
+ return opId;
6291
+ }
6166
6292
  /** @internal */
6167
6293
  _attach(id, pool) {
6168
6294
  super._attach(id, pool);
@@ -6243,13 +6369,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6243
6369
  if (deletedDelta) {
6244
6370
  delta.push(deletedDelta);
6245
6371
  }
6246
- const unacknowledgedOpId = this.#unacknowledgedSets.get(op.parentKey);
6247
- if (unacknowledgedOpId !== void 0) {
6248
- if (unacknowledgedOpId !== op.opId) {
6249
- return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
6250
- } else {
6251
- this.#unacknowledgedSets.delete(op.parentKey);
6252
- }
6372
+ const unacknowledgedOpId = this.#unacknowledgedSetOpIdAt(op.parentKey);
6373
+ if (unacknowledgedOpId !== void 0 && unacknowledgedOpId !== op.opId) {
6374
+ return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
6253
6375
  }
6254
6376
  const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey);
6255
6377
  const existingItem = this.#items.find((item) => item._id === op.id);
@@ -6330,7 +6452,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6330
6452
  }
6331
6453
  return result.modified.updates[0];
6332
6454
  }
6333
- #applyRemoteInsert(op) {
6455
+ #applyRemoteInsert(op, fromSnapshot) {
6334
6456
  if (this._pool === void 0) {
6335
6457
  throw new Error("Can't attach child if managed pool is not present");
6336
6458
  }
@@ -6340,11 +6462,82 @@ var LiveList = class _LiveList extends AbstractCrdt {
6340
6462
  this.#shiftItemPosition(existingItemIndex, key);
6341
6463
  }
6342
6464
  const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
6465
+ const bumpDeltas = fromSnapshot ? [] : this.#bumpUnackedPushesAbove(key);
6343
6466
  return {
6344
- modified: makeUpdate(this, [insertDelta(newIndex, newItem)]),
6467
+ modified: makeUpdate(this, [
6468
+ insertDelta(newIndex, newItem),
6469
+ ...bumpDeltas
6470
+ ]),
6345
6471
  reverse: []
6346
6472
  };
6347
6473
  }
6474
+ /**
6475
+ * This list's own still-unacknowledged pushed items (their `intent: "push"`
6476
+ * Create op is still pending in the room's unacknowledgedOps). Derived from
6477
+ * the single source of truth, so an item drops out the instant its op is
6478
+ * acked, with no per-instance membership to leak. Yielded in push order.
6479
+ *
6480
+ * Restricted to items currently in `#items`: a pushed node whose op is still
6481
+ * pending may have been pulled out of the list (e.g. implicitly deleted by a
6482
+ * remote set, or removed by an undo) while still living in the pool, and such
6483
+ * a node must not be repositioned.
6484
+ */
6485
+ *#unackedPushNodes() {
6486
+ if (this._pool === void 0 || this._id === void 0) {
6487
+ return;
6488
+ }
6489
+ for (const op of this._pool.unacknowledgedOps.getByParentId(this._id)) {
6490
+ if (op.intent !== "push") {
6491
+ continue;
6492
+ }
6493
+ const node = this._pool.getNode(op.id);
6494
+ if (node !== void 0 && this.#items.includes(node)) {
6495
+ yield node;
6496
+ }
6497
+ }
6498
+ }
6499
+ /**
6500
+ * Optimistic no-flip for pushed items. When a remote op lands at or below my
6501
+ * still-unacked pushed items, those items must end up *after* it: FIFO plus
6502
+ * the room's serial processing guarantee the remote was processed first, so
6503
+ * my unacked pushes belong behind it. Re-chain the whole unacked-push block,
6504
+ * in push order, to sit after the highest confirmed sibling, so it keeps
6505
+ * rendering as a contiguous tail instead of getting interleaved. Local-only;
6506
+ * the real acks overwrite these keys with the (identical) server keys.
6507
+ */
6508
+ #bumpUnackedPushesAbove(remoteKey) {
6509
+ const pending = new Set(this.#unackedPushNodes());
6510
+ if (pending.size === 0) {
6511
+ return [];
6512
+ }
6513
+ let minPending;
6514
+ for (const node of pending) {
6515
+ const pos = node._parentPos;
6516
+ if (minPending === void 0 || pos < minPending) {
6517
+ minPending = pos;
6518
+ }
6519
+ }
6520
+ if (remoteKey < nn(minPending)) {
6521
+ return [];
6522
+ }
6523
+ let base;
6524
+ for (const item of this.#items) {
6525
+ if (!pending.has(item)) {
6526
+ base = item._parentPos;
6527
+ }
6528
+ }
6529
+ const deltas = [];
6530
+ for (const node of pending) {
6531
+ const previousIndex = this.#items.findIndex((item) => item === node);
6532
+ base = makePosition(base);
6533
+ this.#updateItemPosition(node, base);
6534
+ const index = this.#items.findIndex((item) => item === node);
6535
+ if (index !== previousIndex) {
6536
+ deltas.push(moveDelta(previousIndex, index, node));
6537
+ }
6538
+ }
6539
+ return deltas;
6540
+ }
6348
6541
  #applyInsertAck(op) {
6349
6542
  const existingItem = this.#items.find((item) => item._id === op.id);
6350
6543
  const key = asPos(op.parentKey);
@@ -6399,7 +6592,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6399
6592
  #applyInsertUndoRedo(op) {
6400
6593
  const { id, parentKey: key } = op;
6401
6594
  const child = creationOpToLiveNode(op);
6402
- if (_optionalChain([this, 'access', _112 => _112._pool, 'optionalAccess', _113 => _113.getNode, 'call', _114 => _114(id)]) !== void 0) {
6595
+ if (_optionalChain([this, 'access', _126 => _126._pool, 'optionalAccess', _127 => _127.getNode, 'call', _128 => _128(id)]) !== void 0) {
6403
6596
  return { modified: false };
6404
6597
  }
6405
6598
  child._attach(id, nn(this._pool));
@@ -6407,8 +6600,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
6407
6600
  const existingItemIndex = this._indexOfPosition(key);
6408
6601
  let newKey = key;
6409
6602
  if (existingItemIndex !== -1) {
6410
- const before2 = _optionalChain([this, 'access', _115 => _115.#items, 'access', _116 => _116.at, 'call', _117 => _117(existingItemIndex), 'optionalAccess', _118 => _118._parentPos]);
6411
- const after2 = _optionalChain([this, 'access', _119 => _119.#items, 'access', _120 => _120.at, 'call', _121 => _121(existingItemIndex + 1), 'optionalAccess', _122 => _122._parentPos]);
6603
+ const before2 = _optionalChain([this, 'access', _129 => _129.#items, 'access', _130 => _130.at, 'call', _131 => _131(existingItemIndex), 'optionalAccess', _132 => _132._parentPos]);
6604
+ const after2 = _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134.at, 'call', _135 => _135(existingItemIndex + 1), 'optionalAccess', _136 => _136._parentPos]);
6412
6605
  newKey = makePosition(before2, after2);
6413
6606
  child._setParentLink(this, newKey);
6414
6607
  }
@@ -6422,10 +6615,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6422
6615
  #applySetUndoRedo(op) {
6423
6616
  const { id, parentKey: key } = op;
6424
6617
  const child = creationOpToLiveNode(op);
6425
- if (_optionalChain([this, 'access', _123 => _123._pool, 'optionalAccess', _124 => _124.getNode, 'call', _125 => _125(id)]) !== void 0) {
6618
+ if (_optionalChain([this, 'access', _137 => _137._pool, 'optionalAccess', _138 => _138.getNode, 'call', _139 => _139(id)]) !== void 0) {
6426
6619
  return { modified: false };
6427
6620
  }
6428
- this.#unacknowledgedSets.set(key, nn(op.opId));
6429
6621
  const indexOfItemWithSameKey = this._indexOfPosition(key);
6430
6622
  child._attach(id, nn(this._pool));
6431
6623
  child._setParentLink(this, key);
@@ -6435,8 +6627,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6435
6627
  existingItem._detach();
6436
6628
  this.#items.remove(existingItem);
6437
6629
  this.#items.add(child);
6438
- const reverse = HACK_addIntentAndDeletedIdToOperation(
6630
+ const reverse = addIntentToRootOp(
6439
6631
  existingItem._toOps(nn(this._id), key),
6632
+ "set",
6440
6633
  op.id
6441
6634
  );
6442
6635
  const delta = [setDelta(indexOfItemWithSameKey, child)];
@@ -6461,7 +6654,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6461
6654
  }
6462
6655
  }
6463
6656
  /** @internal */
6464
- _attachChild(op, source) {
6657
+ _attachChild(op, source, fromSnapshot = false) {
6465
6658
  if (this._pool === void 0) {
6466
6659
  throw new Error("Can't attach child if managed pool is not present");
6467
6660
  }
@@ -6476,7 +6669,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6476
6669
  }
6477
6670
  } else {
6478
6671
  if (source === 1 /* THEIRS */) {
6479
- result = this.#applyRemoteInsert(op);
6672
+ result = this.#applyRemoteInsert(op, fromSnapshot);
6480
6673
  } else if (source === 2 /* OURS */) {
6481
6674
  result = this.#applyInsertAck(op);
6482
6675
  } else {
@@ -6543,7 +6736,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6543
6736
  } else {
6544
6737
  this.#updateItemPositionAt(
6545
6738
  existingItemIndex,
6546
- makePosition(newKey, _optionalChain([this, 'access', _126 => _126.#items, 'access', _127 => _127.at, 'call', _128 => _128(existingItemIndex + 1), 'optionalAccess', _129 => _129._parentPos]))
6739
+ makePosition(newKey, _optionalChain([this, 'access', _140 => _140.#items, 'access', _141 => _141.at, 'call', _142 => _142(existingItemIndex + 1), 'optionalAccess', _143 => _143._parentPos]))
6547
6740
  );
6548
6741
  const previousIndex = this.#items.findIndex((item) => item === child);
6549
6742
  this.#updateItemPosition(child, newKey);
@@ -6570,7 +6763,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6570
6763
  this,
6571
6764
  makePosition(
6572
6765
  newKey,
6573
- _optionalChain([this, 'access', _130 => _130.#items, 'access', _131 => _131.at, 'call', _132 => _132(existingItemIndex + 1), 'optionalAccess', _133 => _133._parentPos])
6766
+ _optionalChain([this, 'access', _144 => _144.#items, 'access', _145 => _145.at, 'call', _146 => _146(existingItemIndex + 1), 'optionalAccess', _147 => _147._parentPos])
6574
6767
  )
6575
6768
  );
6576
6769
  this.#items.reposition(existingItem);
@@ -6594,7 +6787,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6594
6787
  existingItemIndex,
6595
6788
  makePosition(
6596
6789
  newKey,
6597
- _optionalChain([this, 'access', _134 => _134.#items, 'access', _135 => _135.at, 'call', _136 => _136(existingItemIndex + 1), 'optionalAccess', _137 => _137._parentPos])
6790
+ _optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(existingItemIndex + 1), 'optionalAccess', _151 => _151._parentPos])
6598
6791
  )
6599
6792
  );
6600
6793
  }
@@ -6622,7 +6815,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6622
6815
  if (existingItemIndex !== -1) {
6623
6816
  actualNewKey = makePosition(
6624
6817
  newKey,
6625
- _optionalChain([this, 'access', _138 => _138.#items, 'access', _139 => _139.at, 'call', _140 => _140(existingItemIndex + 1), 'optionalAccess', _141 => _141._parentPos])
6818
+ _optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(existingItemIndex + 1), 'optionalAccess', _155 => _155._parentPos])
6626
6819
  );
6627
6820
  }
6628
6821
  this.#updateItemPosition(child, actualNewKey);
@@ -6679,8 +6872,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6679
6872
  * @param element The element to add to the end of the LiveList.
6680
6873
  */
6681
6874
  push(element) {
6682
- _optionalChain([this, 'access', _142 => _142._pool, 'optionalAccess', _143 => _143.assertStorageIsWritable, 'call', _144 => _144()]);
6683
- return this.insert(element, this.length);
6875
+ return this.#injectAt(element, this.length, "push");
6684
6876
  }
6685
6877
  /**
6686
6878
  * Inserts one element at a specified index.
@@ -6688,14 +6880,23 @@ var LiveList = class _LiveList extends AbstractCrdt {
6688
6880
  * @param index The index at which you want to insert the element.
6689
6881
  */
6690
6882
  insert(element, index) {
6691
- _optionalChain([this, 'access', _145 => _145._pool, 'optionalAccess', _146 => _146.assertStorageIsWritable, 'call', _147 => _147()]);
6883
+ return this.#injectAt(element, index, "insert");
6884
+ }
6885
+ /**
6886
+ * Shared implementation of `insert` and `push`. A `"push"` intent leaves the
6887
+ * client-computed position untouched (so optimistic rendering is unchanged),
6888
+ * but tags the Op so the server appends it to the true end of the list
6889
+ * instead of resolving its position against the client's stale view.
6890
+ */
6891
+ #injectAt(element, index, intent) {
6892
+ _optionalChain([this, 'access', _156 => _156._pool, 'optionalAccess', _157 => _157.assertStorageIsWritable, 'call', _158 => _158()]);
6692
6893
  if (index < 0 || index > this.#items.length) {
6693
6894
  throw new Error(
6694
6895
  `Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
6695
6896
  );
6696
6897
  }
6697
- const before2 = _optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(index - 1), 'optionalAccess', _151 => _151._parentPos]);
6698
- const after2 = _optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(index), 'optionalAccess', _155 => _155._parentPos]);
6898
+ const before2 = _optionalChain([this, 'access', _159 => _159.#items, 'access', _160 => _160.at, 'call', _161 => _161(index - 1), 'optionalAccess', _162 => _162._parentPos]);
6899
+ const after2 = _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(index), 'optionalAccess', _166 => _166._parentPos]);
6699
6900
  const position = makePosition(before2, after2);
6700
6901
  const value = lsonToLiveNode(element);
6701
6902
  value._setParentLink(this, position);
@@ -6703,8 +6904,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6703
6904
  if (this._pool && this._id) {
6704
6905
  const id = this._pool.generateId();
6705
6906
  value._attach(id, this._pool);
6907
+ const ops = value._toOpsWithOpId(this._id, position, this._pool);
6706
6908
  this._pool.dispatch(
6707
- value._toOpsWithOpId(this._id, position, this._pool),
6909
+ intent === "push" ? addIntentToRootOp(ops, "push") : ops,
6708
6910
  [{ type: OpCode.DELETE_CRDT, id }],
6709
6911
  /* @__PURE__ */ new Map([
6710
6912
  [this._id, makeUpdate(this, [insertDelta(index, value)])]
@@ -6718,7 +6920,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6718
6920
  * @param targetIndex The index where the element should be after moving.
6719
6921
  */
6720
6922
  move(index, targetIndex) {
6721
- _optionalChain([this, 'access', _156 => _156._pool, 'optionalAccess', _157 => _157.assertStorageIsWritable, 'call', _158 => _158()]);
6923
+ _optionalChain([this, 'access', _167 => _167._pool, 'optionalAccess', _168 => _168.assertStorageIsWritable, 'call', _169 => _169()]);
6722
6924
  if (targetIndex < 0) {
6723
6925
  throw new Error("targetIndex cannot be less than 0");
6724
6926
  }
@@ -6736,11 +6938,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
6736
6938
  let beforePosition = null;
6737
6939
  let afterPosition = null;
6738
6940
  if (index < targetIndex) {
6739
- afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _159 => _159.#items, 'access', _160 => _160.at, 'call', _161 => _161(targetIndex + 1), 'optionalAccess', _162 => _162._parentPos]);
6941
+ 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]);
6740
6942
  beforePosition = this.#items.at(targetIndex)._parentPos;
6741
6943
  } else {
6742
6944
  afterPosition = this.#items.at(targetIndex)._parentPos;
6743
- beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(targetIndex - 1), 'optionalAccess', _166 => _166._parentPos]);
6945
+ beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _174 => _174.#items, 'access', _175 => _175.at, 'call', _176 => _176(targetIndex - 1), 'optionalAccess', _177 => _177._parentPos]);
6744
6946
  }
6745
6947
  const position = makePosition(beforePosition, afterPosition);
6746
6948
  const item = this.#items.at(index);
@@ -6775,7 +6977,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6775
6977
  * @param index The index of the element to delete
6776
6978
  */
6777
6979
  delete(index) {
6778
- _optionalChain([this, 'access', _167 => _167._pool, 'optionalAccess', _168 => _168.assertStorageIsWritable, 'call', _169 => _169()]);
6980
+ _optionalChain([this, 'access', _178 => _178._pool, 'optionalAccess', _179 => _179.assertStorageIsWritable, 'call', _180 => _180()]);
6779
6981
  if (index < 0 || index >= this.#items.length) {
6780
6982
  throw new Error(
6781
6983
  `Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -6808,7 +7010,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6808
7010
  }
6809
7011
  }
6810
7012
  clear() {
6811
- _optionalChain([this, 'access', _170 => _170._pool, 'optionalAccess', _171 => _171.assertStorageIsWritable, 'call', _172 => _172()]);
7013
+ _optionalChain([this, 'access', _181 => _181._pool, 'optionalAccess', _182 => _182.assertStorageIsWritable, 'call', _183 => _183()]);
6812
7014
  if (this._pool) {
6813
7015
  const ops = [];
6814
7016
  const reverseOps = [];
@@ -6842,7 +7044,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6842
7044
  }
6843
7045
  }
6844
7046
  set(index, item) {
6845
- _optionalChain([this, 'access', _173 => _173._pool, 'optionalAccess', _174 => _174.assertStorageIsWritable, 'call', _175 => _175()]);
7047
+ _optionalChain([this, 'access', _184 => _184._pool, 'optionalAccess', _185 => _185.assertStorageIsWritable, 'call', _186 => _186()]);
6846
7048
  if (index < 0 || index >= this.#items.length) {
6847
7049
  throw new Error(
6848
7050
  `Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -6862,13 +7064,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
6862
7064
  value._attach(id, this._pool);
6863
7065
  const storageUpdates = /* @__PURE__ */ new Map();
6864
7066
  storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
6865
- const ops = HACK_addIntentAndDeletedIdToOperation(
7067
+ const ops = addIntentToRootOp(
6866
7068
  value._toOpsWithOpId(this._id, position, this._pool),
7069
+ "set",
6867
7070
  existingId
6868
7071
  );
6869
- this.#unacknowledgedSets.set(position, nn(ops[0].opId));
6870
- const reverseOps = HACK_addIntentAndDeletedIdToOperation(
7072
+ const reverseOps = addIntentToRootOp(
6871
7073
  existingItem._toOps(this._id, position),
7074
+ "set",
6872
7075
  id
6873
7076
  );
6874
7077
  this._pool.dispatch(ops, reverseOps, storageUpdates);
@@ -7000,7 +7203,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7000
7203
  #shiftItemPosition(index, key) {
7001
7204
  const shiftedPosition = makePosition(
7002
7205
  key,
7003
- this.#items.length > index + 1 ? _optionalChain([this, 'access', _176 => _176.#items, 'access', _177 => _177.at, 'call', _178 => _178(index + 1), 'optionalAccess', _179 => _179._parentPos]) : void 0
7206
+ 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
7004
7207
  );
7005
7208
  this.#updateItemPositionAt(index, shiftedPosition);
7006
7209
  }
@@ -7069,15 +7272,11 @@ function moveDelta(previousIndex, index, item) {
7069
7272
  previousIndex
7070
7273
  };
7071
7274
  }
7072
- function HACK_addIntentAndDeletedIdToOperation(ops, deletedId) {
7275
+ function addIntentToRootOp(ops, intent, deletedId) {
7073
7276
  return ops.map((op, index) => {
7074
7277
  if (index === 0) {
7075
7278
  const firstOp = op;
7076
- return {
7077
- ...firstOp,
7078
- intent: "set",
7079
- deletedId
7080
- };
7279
+ return { ...firstOp, intent, deletedId };
7081
7280
  } else {
7082
7281
  return op;
7083
7282
  }
@@ -7253,7 +7452,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7253
7452
  * @param value The value of the element to add. Should be serializable to JSON.
7254
7453
  */
7255
7454
  set(key, value) {
7256
- _optionalChain([this, 'access', _180 => _180._pool, 'optionalAccess', _181 => _181.assertStorageIsWritable, 'call', _182 => _182()]);
7455
+ _optionalChain([this, 'access', _191 => _191._pool, 'optionalAccess', _192 => _192.assertStorageIsWritable, 'call', _193 => _193()]);
7257
7456
  const oldValue = this.#map.get(key);
7258
7457
  if (oldValue) {
7259
7458
  oldValue._detach();
@@ -7299,7 +7498,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7299
7498
  * @returns true if an element existed and has been removed, or false if the element does not exist.
7300
7499
  */
7301
7500
  delete(key) {
7302
- _optionalChain([this, 'access', _183 => _183._pool, 'optionalAccess', _184 => _184.assertStorageIsWritable, 'call', _185 => _185()]);
7501
+ _optionalChain([this, 'access', _194 => _194._pool, 'optionalAccess', _195 => _195.assertStorageIsWritable, 'call', _196 => _196()]);
7303
7502
  const item = this.#map.get(key);
7304
7503
  if (item === void 0) {
7305
7504
  return false;
@@ -7910,20 +8109,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7910
8109
  * Caveat: this method will not add changes to the undo/redo stack.
7911
8110
  */
7912
8111
  setLocal(key, value) {
7913
- _optionalChain([this, 'access', _186 => _186._pool, 'optionalAccess', _187 => _187.assertStorageIsWritable, 'call', _188 => _188()]);
8112
+ _optionalChain([this, 'access', _197 => _197._pool, 'optionalAccess', _198 => _198.assertStorageIsWritable, 'call', _199 => _199()]);
7914
8113
  const deleteResult = this.#prepareDelete(key);
7915
8114
  this.#local.set(key, value);
7916
8115
  this.invalidate();
7917
8116
  if (this._pool !== void 0 && this._id !== void 0) {
7918
- const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _189 => _189[0]]), () => ( []));
7919
- const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _190 => _190[1]]), () => ( []));
7920
- const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _191 => _191[2]]), () => ( /* @__PURE__ */ new Map()));
8117
+ const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _200 => _200[0]]), () => ( []));
8118
+ const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _201 => _201[1]]), () => ( []));
8119
+ const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _202 => _202[2]]), () => ( /* @__PURE__ */ new Map()));
7921
8120
  const existing = storageUpdates.get(this._id);
7922
8121
  storageUpdates.set(this._id, {
7923
8122
  node: this,
7924
8123
  type: "LiveObject",
7925
8124
  updates: {
7926
- ..._optionalChain([existing, 'optionalAccess', _192 => _192.updates]),
8125
+ ..._optionalChain([existing, 'optionalAccess', _203 => _203.updates]),
7927
8126
  [key]: { type: "update" }
7928
8127
  }
7929
8128
  });
@@ -7943,7 +8142,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7943
8142
  * #synced or pool/id are unavailable. Does NOT dispatch.
7944
8143
  */
7945
8144
  #prepareDelete(key) {
7946
- _optionalChain([this, 'access', _193 => _193._pool, 'optionalAccess', _194 => _194.assertStorageIsWritable, 'call', _195 => _195()]);
8145
+ _optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
7947
8146
  const k = key;
7948
8147
  if (this.#local.has(k) && !this.#synced.has(k)) {
7949
8148
  const oldValue2 = this.#local.get(k);
@@ -8019,7 +8218,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8019
8218
  const result = this.#prepareDelete(key);
8020
8219
  if (result) {
8021
8220
  const [ops, reverse, storageUpdates] = result;
8022
- _optionalChain([this, 'access', _196 => _196._pool, 'optionalAccess', _197 => _197.dispatch, 'call', _198 => _198(ops, reverse, storageUpdates)]);
8221
+ _optionalChain([this, 'access', _207 => _207._pool, 'optionalAccess', _208 => _208.dispatch, 'call', _209 => _209(ops, reverse, storageUpdates)]);
8023
8222
  }
8024
8223
  }
8025
8224
  /**
@@ -8027,7 +8226,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8027
8226
  * @param patch The object used to overrides properties
8028
8227
  */
8029
8228
  update(patch) {
8030
- _optionalChain([this, 'access', _199 => _199._pool, 'optionalAccess', _200 => _200.assertStorageIsWritable, 'call', _201 => _201()]);
8229
+ _optionalChain([this, 'access', _210 => _210._pool, 'optionalAccess', _211 => _211.assertStorageIsWritable, 'call', _212 => _212()]);
8031
8230
  if (_LiveObject.detectLargeObjects) {
8032
8231
  const data = {};
8033
8232
  for (const [key, value] of this.#synced) {
@@ -8227,581 +8426,6 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8227
8426
  }
8228
8427
  }, _class2.__initStatic(), _class2);
8229
8428
 
8230
- // src/crdts/liveTextOps.ts
8231
- function attributesEqual(left, right) {
8232
- if (left === right) {
8233
- return true;
8234
- }
8235
- if (left === void 0 || right === void 0) {
8236
- return false;
8237
- }
8238
- const leftKeys = Object.keys(left);
8239
- const rightKeys = Object.keys(right);
8240
- if (leftKeys.length !== rightKeys.length) {
8241
- return false;
8242
- }
8243
- for (const key of leftKeys) {
8244
- if (left[key] !== right[key]) {
8245
- return false;
8246
- }
8247
- }
8248
- return true;
8249
- }
8250
- function cloneAttributes(attributes) {
8251
- return attributes === void 0 ? void 0 : freeze({ ...attributes });
8252
- }
8253
- function normalizeSegments(segments) {
8254
- const normalized = [];
8255
- for (const segment of segments) {
8256
- if (segment.text.length === 0) {
8257
- continue;
8258
- }
8259
- const last = normalized.at(-1);
8260
- const attributes = cloneAttributes(segment.attributes);
8261
- if (last !== void 0 && attributesEqual(last.attributes, attributes)) {
8262
- last.text += segment.text;
8263
- } else {
8264
- normalized.push({ text: segment.text, attributes });
8265
- }
8266
- }
8267
- return normalized;
8268
- }
8269
- function deltaToSegments(delta) {
8270
- return normalizeSegments(
8271
- delta.map((item) => ({
8272
- text: item.text,
8273
- attributes: item.attributes
8274
- }))
8275
- );
8276
- }
8277
- function segmentsToDelta(segments) {
8278
- return segments.map(
8279
- (segment) => segment.attributes === void 0 ? { text: segment.text } : { text: segment.text, attributes: { ...segment.attributes } }
8280
- );
8281
- }
8282
- function textLength(segments) {
8283
- return segments.reduce((sum, segment) => sum + segment.text.length, 0);
8284
- }
8285
- function splitSegmentsAt(segments, index) {
8286
- const result = [];
8287
- let offset = 0;
8288
- for (const segment of segments) {
8289
- const end = offset + segment.text.length;
8290
- if (index > offset && index < end) {
8291
- const before2 = segment.text.slice(0, index - offset);
8292
- const after2 = segment.text.slice(index - offset);
8293
- result.push({ text: before2, attributes: segment.attributes });
8294
- result.push({ text: after2, attributes: segment.attributes });
8295
- } else {
8296
- result.push({ text: segment.text, attributes: segment.attributes });
8297
- }
8298
- offset = end;
8299
- }
8300
- return result;
8301
- }
8302
- function clipRange(index, length, contentLength) {
8303
- const clippedIndex = Math.max(0, Math.min(index, contentLength));
8304
- const clippedEnd = Math.max(
8305
- clippedIndex,
8306
- Math.min(index + length, contentLength)
8307
- );
8308
- return { index: clippedIndex, length: clippedEnd - clippedIndex };
8309
- }
8310
- function applyInsert(segments, index, text, attributes) {
8311
- if (text.length === 0) {
8312
- return normalizeSegments(segments);
8313
- }
8314
- const split = splitSegmentsAt(segments, index);
8315
- const result = [];
8316
- let offset = 0;
8317
- let inserted = false;
8318
- for (const segment of split) {
8319
- if (!inserted && offset === index) {
8320
- result.push({ text, attributes });
8321
- inserted = true;
8322
- }
8323
- result.push(segment);
8324
- offset += segment.text.length;
8325
- }
8326
- if (!inserted) {
8327
- result.push({ text, attributes });
8328
- }
8329
- return normalizeSegments(result);
8330
- }
8331
- function extractDeletedSegments(segments, index, length) {
8332
- const split = splitSegmentsAt(
8333
- splitSegmentsAt(segments, index),
8334
- index + length
8335
- );
8336
- const deleted = [];
8337
- let offset = 0;
8338
- for (const segment of split) {
8339
- const end = offset + segment.text.length;
8340
- if (offset >= index && end <= index + length) {
8341
- deleted.push({
8342
- text: segment.text,
8343
- attributes: segment.attributes
8344
- });
8345
- }
8346
- offset = end;
8347
- }
8348
- return normalizeSegments(deleted);
8349
- }
8350
- function applyDelete(segments, index, length) {
8351
- const deletedSegments = extractDeletedSegments(segments, index, length);
8352
- const split = splitSegmentsAt(
8353
- splitSegmentsAt(segments, index),
8354
- index + length
8355
- );
8356
- const result = [];
8357
- let offset = 0;
8358
- let deletedText = "";
8359
- for (const segment of split) {
8360
- const end = offset + segment.text.length;
8361
- if (offset >= index && end <= index + length) {
8362
- deletedText += segment.text;
8363
- } else {
8364
- result.push(segment);
8365
- }
8366
- offset = end;
8367
- }
8368
- return {
8369
- segments: normalizeSegments(result),
8370
- deletedText,
8371
- deletedSegments
8372
- };
8373
- }
8374
- function applyFormat(segments, index, length, attributes) {
8375
- const split = splitSegmentsAt(
8376
- splitSegmentsAt(segments, index),
8377
- index + length
8378
- );
8379
- const result = [];
8380
- let offset = 0;
8381
- for (const segment of split) {
8382
- const end = offset + segment.text.length;
8383
- if (offset >= index && end <= index + length) {
8384
- const nextAttributes = {
8385
- ..._nullishCoalesce(segment.attributes, () => ( {}))
8386
- };
8387
- for (const [key, value] of Object.entries(attributes)) {
8388
- if (value === null) {
8389
- delete nextAttributes[key];
8390
- } else {
8391
- nextAttributes[key] = value;
8392
- }
8393
- }
8394
- result.push({
8395
- text: segment.text,
8396
- attributes: Object.keys(nextAttributes).length === 0 ? void 0 : freeze(nextAttributes)
8397
- });
8398
- } else {
8399
- result.push(segment);
8400
- }
8401
- offset = end;
8402
- }
8403
- return normalizeSegments(result);
8404
- }
8405
- function formatReverseOperations(segments, index, length, patch) {
8406
- const split = splitSegmentsAt(
8407
- splitSegmentsAt(segments, index),
8408
- index + length
8409
- );
8410
- const result = [];
8411
- let offset = 0;
8412
- for (const segment of split) {
8413
- const end = offset + segment.text.length;
8414
- if (offset >= index && end <= index + length) {
8415
- const attributes = {};
8416
- for (const key of Object.keys(patch)) {
8417
- attributes[key] = _nullishCoalesce(_optionalChain([segment, 'access', _202 => _202.attributes, 'optionalAccess', _203 => _203[key]]), () => ( null));
8418
- }
8419
- result.push({
8420
- type: "format",
8421
- index: offset,
8422
- length: segment.text.length,
8423
- attributes
8424
- });
8425
- }
8426
- offset = end;
8427
- }
8428
- return result;
8429
- }
8430
- function mapIndexThroughOperation(index, op) {
8431
- if (op.type === "insert") {
8432
- return op.index <= index ? index + op.text.length : index;
8433
- } else if (op.type === "delete") {
8434
- if (op.index >= index) {
8435
- return index;
8436
- }
8437
- return Math.max(op.index, index - op.length);
8438
- } else {
8439
- return index;
8440
- }
8441
- }
8442
- function mapTextIndexThroughOperations(index, ops) {
8443
- let mapped = index;
8444
- for (const op of ops) {
8445
- mapped = mapIndexThroughOperation(mapped, op);
8446
- }
8447
- return mapped;
8448
- }
8449
- function rebaseTextOperations(ops, acceptedOps) {
8450
- return ops.map((op) => {
8451
- if (op.type === "insert") {
8452
- return {
8453
- ...op,
8454
- index: mapTextIndexThroughOperations(op.index, acceptedOps)
8455
- };
8456
- } else if (op.type === "delete" || op.type === "format") {
8457
- const start = mapTextIndexThroughOperations(op.index, acceptedOps);
8458
- const end = mapTextIndexThroughOperations(
8459
- op.index + op.length,
8460
- acceptedOps
8461
- );
8462
- return { ...op, index: start, length: Math.max(0, end - start) };
8463
- } else {
8464
- return op;
8465
- }
8466
- });
8467
- }
8468
- function applyTextOperationsToSegments(segments, ops) {
8469
- let next = [...segments];
8470
- for (const op of ops) {
8471
- if (op.type === "insert") {
8472
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8473
- next = applyInsert(next, index, op.text, op.attributes);
8474
- } else if (op.type === "delete") {
8475
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8476
- const clipped = clipRange(index, op.length, textLength(next));
8477
- next = applyDelete(next, clipped.index, clipped.length).segments;
8478
- } else {
8479
- const index = Math.max(0, Math.min(op.index, textLength(next)));
8480
- const clipped = clipRange(index, op.length, textLength(next));
8481
- next = applyFormat(next, clipped.index, clipped.length, op.attributes);
8482
- }
8483
- }
8484
- return next;
8485
- }
8486
- function applyLiveTextOperations(delta, ops) {
8487
- return segmentsToDelta(applyTextOperationsToSegments(deltaToSegments(delta), ops));
8488
- }
8489
- function invertTextOperations(segments, ops) {
8490
- let shadow = [...segments];
8491
- const reverse = [];
8492
- for (const op of ops) {
8493
- if (op.type === "insert") {
8494
- shadow = applyInsert(shadow, op.index, op.text, op.attributes);
8495
- reverse.unshift({
8496
- type: "delete",
8497
- index: op.index,
8498
- length: op.text.length
8499
- });
8500
- } else if (op.type === "delete") {
8501
- const deletedSegments = extractDeletedSegments(
8502
- shadow,
8503
- op.index,
8504
- op.length
8505
- );
8506
- shadow = applyDelete(shadow, op.index, op.length).segments;
8507
- const inserts = [];
8508
- let insertIndex = op.index;
8509
- for (const segment of deletedSegments) {
8510
- inserts.push({
8511
- type: "insert",
8512
- index: insertIndex,
8513
- text: segment.text,
8514
- attributes: segment.attributes
8515
- });
8516
- insertIndex += segment.text.length;
8517
- }
8518
- for (let index = inserts.length - 1; index >= 0; index--) {
8519
- reverse.unshift(inserts[index]);
8520
- }
8521
- } else {
8522
- const inverse = formatReverseOperations(
8523
- shadow,
8524
- op.index,
8525
- op.length,
8526
- op.attributes
8527
- );
8528
- shadow = applyFormat(shadow, op.index, op.length, op.attributes);
8529
- reverse.unshift(...inverse.reverse());
8530
- }
8531
- }
8532
- return reverse;
8533
- }
8534
-
8535
- // src/crdts/LiveText.ts
8536
- var LiveText = class _LiveText extends AbstractCrdt {
8537
- #segments;
8538
- #version;
8539
- #pendingOps;
8540
- constructor(textOrDelta = "", version = 0) {
8541
- super();
8542
- this.#segments = typeof textOrDelta === "string" ? textOrDelta.length === 0 ? [] : [{ text: textOrDelta }] : deltaToSegments(textOrDelta);
8543
- this.#version = version;
8544
- this.#pendingOps = /* @__PURE__ */ new Map();
8545
- }
8546
- get version() {
8547
- return this.#version;
8548
- }
8549
- get length() {
8550
- return this.toString().length;
8551
- }
8552
- /** @internal */
8553
- static _deserialize([id, item], _parentToChildren, pool) {
8554
- const text = new _LiveText(item.data, item.version);
8555
- text._attach(id, pool);
8556
- return text;
8557
- }
8558
- /** @internal */
8559
- _toOps(parentId, parentKey) {
8560
- if (this._id === void 0) {
8561
- throw new Error("Cannot serialize LiveText if it is not attached");
8562
- }
8563
- return [
8564
- {
8565
- type: OpCode.CREATE_TEXT,
8566
- id: this._id,
8567
- parentId,
8568
- parentKey,
8569
- data: this.toDelta(),
8570
- version: this.#version
8571
- }
8572
- ];
8573
- }
8574
- /** @internal */
8575
- _serialize() {
8576
- if (this.parent.type !== "HasParent") {
8577
- throw new Error("Cannot serialize LiveText if parent is missing");
8578
- }
8579
- return {
8580
- type: CrdtType.TEXT,
8581
- parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
8582
- parentKey: this.parent.key,
8583
- data: this.toDelta(),
8584
- version: this.#version
8585
- };
8586
- }
8587
- /** @internal */
8588
- _attachChild(_op) {
8589
- throw new Error("LiveText cannot contain child nodes");
8590
- }
8591
- /** @internal */
8592
- _detachChild(_crdt) {
8593
- throw new Error("LiveText cannot contain child nodes");
8594
- }
8595
- /** @internal */
8596
- _apply(op, isLocal) {
8597
- if (op.type !== OpCode.UPDATE_TEXT) {
8598
- return super._apply(op, isLocal);
8599
- }
8600
- if (isLocal) {
8601
- this.#pendingOps.set(nn(op.opId), op.ops);
8602
- return this.#applyOperations(op.ops, _nullishCoalesce(op.version, () => ( this.#version)));
8603
- }
8604
- if (op.opId !== void 0) {
8605
- const pending2 = this.#pendingOps.get(op.opId);
8606
- this.#pendingOps.delete(op.opId);
8607
- const otherPending = Array.from(this.#pendingOps.values()).flat();
8608
- if (pending2 !== void 0 && otherPending.length > 0) {
8609
- this.#segments = applyTextOperationsToSegments(
8610
- this.#segments,
8611
- invertTextOperations(this.#segments, pending2)
8612
- );
8613
- const ops2 = rebaseTextOperations(op.ops, otherPending);
8614
- return this.#applyOperations(
8615
- ops2,
8616
- _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)))
8617
- );
8618
- }
8619
- this.#version = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
8620
- return { modified: false };
8621
- }
8622
- const pending = Array.from(this.#pendingOps.values()).flat();
8623
- const ops = pending.length > 0 ? rebaseTextOperations(op.ops, pending) : op.ops;
8624
- return this.#applyOperations(ops, _nullishCoalesce(op.version, () => ( this.#version + 1)));
8625
- }
8626
- insert(index, text, attributes) {
8627
- const clippedIndex = Math.max(0, Math.min(index, this.length));
8628
- this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
8629
- }
8630
- delete(index, length) {
8631
- const clipped = clipRange(index, length, this.length);
8632
- if (clipped.length === 0) {
8633
- return;
8634
- }
8635
- this.#dispatch([
8636
- { type: "delete", index: clipped.index, length: clipped.length }
8637
- ]);
8638
- }
8639
- replace(index, length, text, attributes) {
8640
- const clipped = clipRange(index, length, this.length);
8641
- const ops = [];
8642
- if (clipped.length > 0) {
8643
- ops.push({
8644
- type: "delete",
8645
- index: clipped.index,
8646
- length: clipped.length
8647
- });
8648
- }
8649
- if (text.length > 0) {
8650
- ops.push({ type: "insert", index: clipped.index, text, attributes });
8651
- }
8652
- this.#dispatch(ops);
8653
- }
8654
- format(index, length, attributes) {
8655
- const clipped = clipRange(index, length, this.length);
8656
- if (clipped.length === 0) {
8657
- return;
8658
- }
8659
- this.#dispatch([
8660
- {
8661
- type: "format",
8662
- index: clipped.index,
8663
- length: clipped.length,
8664
- attributes
8665
- }
8666
- ]);
8667
- }
8668
- #dispatch(ops) {
8669
- if (ops.length === 0) {
8670
- return;
8671
- }
8672
- _optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
8673
- const baseVersion = this.#version;
8674
- const reverse = this._pool !== void 0 && this._id !== void 0 ? this.#invertOperations(ops) : [];
8675
- const changes = this.#applyOperationsLocally(ops);
8676
- if (this._pool !== void 0 && this._id !== void 0) {
8677
- const opId = this._pool.generateOpId();
8678
- this.#pendingOps.set(opId, ops);
8679
- this._pool.dispatch(
8680
- [
8681
- {
8682
- type: OpCode.UPDATE_TEXT,
8683
- id: this._id,
8684
- opId,
8685
- baseVersion,
8686
- ops: [...ops]
8687
- }
8688
- ],
8689
- reverse,
8690
- /* @__PURE__ */ new Map([
8691
- [
8692
- this._id,
8693
- {
8694
- type: "LiveText",
8695
- node: this,
8696
- version: this.#version,
8697
- updates: changes
8698
- }
8699
- ]
8700
- ])
8701
- );
8702
- }
8703
- }
8704
- #applyOperations(ops, version) {
8705
- const reverse = this.#invertOperations(ops);
8706
- const changes = this.#applyOperationsLocally(ops);
8707
- this.#version = Math.max(this.#version, version);
8708
- return {
8709
- reverse,
8710
- modified: {
8711
- type: "LiveText",
8712
- node: this,
8713
- version: this.#version,
8714
- updates: changes
8715
- }
8716
- };
8717
- }
8718
- #applyOperationsLocally(ops) {
8719
- const changes = [];
8720
- for (const op of ops) {
8721
- if (op.type === "insert") {
8722
- this.#segments = applyInsert(
8723
- this.#segments,
8724
- op.index,
8725
- op.text,
8726
- op.attributes
8727
- );
8728
- changes.push({
8729
- type: "insert",
8730
- index: op.index,
8731
- text: op.text,
8732
- attributes: op.attributes
8733
- });
8734
- } else if (op.type === "delete") {
8735
- const result = applyDelete(this.#segments, op.index, op.length);
8736
- this.#segments = result.segments;
8737
- changes.push({
8738
- type: "delete",
8739
- index: op.index,
8740
- length: op.length,
8741
- deletedText: result.deletedText
8742
- });
8743
- } else {
8744
- this.#segments = applyFormat(
8745
- this.#segments,
8746
- op.index,
8747
- op.length,
8748
- op.attributes
8749
- );
8750
- changes.push({
8751
- type: "format",
8752
- index: op.index,
8753
- length: op.length,
8754
- attributes: op.attributes
8755
- });
8756
- }
8757
- }
8758
- this.invalidate();
8759
- return changes;
8760
- }
8761
- #invertOperations(ops) {
8762
- return [
8763
- {
8764
- type: OpCode.UPDATE_TEXT,
8765
- id: nn(this._id),
8766
- baseVersion: this.#version,
8767
- ops: invertTextOperations(this.#segments, ops)
8768
- }
8769
- ];
8770
- }
8771
- toString() {
8772
- return this.#segments.map((segment) => segment.text).join("");
8773
- }
8774
- toDelta() {
8775
- return segmentsToDelta(this.#segments);
8776
- }
8777
- toJSON() {
8778
- return super.toJSON();
8779
- }
8780
- /** @internal */
8781
- _toJSON() {
8782
- return this.toDelta();
8783
- }
8784
- /** @internal */
8785
- _toTreeNode(key) {
8786
- return {
8787
- type: "LiveText",
8788
- id: _nullishCoalesce(this._id, () => ( nanoid())),
8789
- key,
8790
- payload: [
8791
- {
8792
- type: "Json",
8793
- id: `${_nullishCoalesce(this._id, () => ( nanoid()))}:text`,
8794
- key: "text",
8795
- payload: this.toString()
8796
- }
8797
- ]
8798
- };
8799
- }
8800
- clone() {
8801
- return new _LiveText(this.toDelta(), this.#version);
8802
- }
8803
- };
8804
-
8805
8429
  // src/crdts/liveblocks-helpers.ts
8806
8430
  function creationOpToLiveNode(op) {
8807
8431
  return lsonToLiveNode(creationOpToLson(op));
@@ -8816,8 +8440,6 @@ function creationOpToLson(op) {
8816
8440
  return new LiveMap();
8817
8441
  case OpCode.CREATE_LIST:
8818
8442
  return new LiveList([]);
8819
- case OpCode.CREATE_TEXT:
8820
- return new LiveText(op.data, op.version);
8821
8443
  default:
8822
8444
  return assertNever(op, "Unknown creation Op");
8823
8445
  }
@@ -8840,8 +8462,6 @@ function deserialize(node, parentToChildren, pool) {
8840
8462
  return LiveMap._deserialize(node, parentToChildren, pool);
8841
8463
  } else if (isRegisterStorageNode(node)) {
8842
8464
  return LiveRegister._deserialize(node, parentToChildren, pool);
8843
- } else if (isTextStorageNode(node)) {
8844
- return LiveText._deserialize(node, parentToChildren, pool);
8845
8465
  } else {
8846
8466
  throw new Error("Unexpected CRDT type");
8847
8467
  }
@@ -8855,14 +8475,12 @@ function deserializeToLson(node, parentToChildren, pool) {
8855
8475
  return LiveMap._deserialize(node, parentToChildren, pool);
8856
8476
  } else if (isRegisterStorageNode(node)) {
8857
8477
  return node[1].data;
8858
- } else if (isTextStorageNode(node)) {
8859
- return LiveText._deserialize(node, parentToChildren, pool);
8860
8478
  } else {
8861
8479
  throw new Error("Unexpected CRDT type");
8862
8480
  }
8863
8481
  }
8864
8482
  function isLiveStructure(value) {
8865
- return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveText(value);
8483
+ return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
8866
8484
  }
8867
8485
  function isLiveNode(value) {
8868
8486
  return isLiveStructure(value) || isLiveRegister(value);
@@ -8876,9 +8494,6 @@ function isLiveMap(value) {
8876
8494
  function isLiveObject(value) {
8877
8495
  return value instanceof LiveObject;
8878
8496
  }
8879
- function isLiveText(value) {
8880
- return value instanceof LiveText;
8881
- }
8882
8497
  function isLiveRegister(value) {
8883
8498
  return value instanceof LiveRegister;
8884
8499
  }
@@ -8888,19 +8503,44 @@ function cloneLson(value) {
8888
8503
  function liveNodeToLson(obj) {
8889
8504
  if (obj instanceof LiveRegister) {
8890
8505
  return obj.data;
8891
- } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveText) {
8506
+ } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
8892
8507
  return obj;
8893
8508
  } else {
8894
8509
  return assertNever(obj, "Unknown AbstractCrdt");
8895
8510
  }
8896
8511
  }
8897
8512
  function lsonToLiveNode(value) {
8898
- if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveText) {
8513
+ if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
8899
8514
  return value;
8900
8515
  } else {
8901
8516
  return new LiveRegister(value);
8902
8517
  }
8903
8518
  }
8519
+ function dumpPool(pool) {
8520
+ const rows = Array.from(pool.nodes.values(), (node) => {
8521
+ const parent = node.parent;
8522
+ const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
8523
+ let value;
8524
+ if (node instanceof LiveRegister) {
8525
+ value = stringifyOrLog(node.data);
8526
+ } else if (node instanceof LiveList) {
8527
+ value = "<LiveList>";
8528
+ } else if (node instanceof LiveMap) {
8529
+ value = "<LiveMap>";
8530
+ } else {
8531
+ value = "<LiveObject>";
8532
+ }
8533
+ return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
8534
+ });
8535
+ rows.sort((a, b) => {
8536
+ if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
8537
+ if (a.key !== b.key) return a.key < b.key ? -1 : 1;
8538
+ return 0;
8539
+ });
8540
+ return rows.map(
8541
+ (r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
8542
+ ).join("\n");
8543
+ }
8904
8544
  function getTreesDiffOperations(currentItems, newItems) {
8905
8545
  const ops = [];
8906
8546
  currentItems.forEach((_, id) => {
@@ -8920,38 +8560,6 @@ function getTreesDiffOperations(currentItems, newItems) {
8920
8560
  });
8921
8561
  }
8922
8562
  }
8923
- if (crdt.type === CrdtType.TEXT) {
8924
- if (currentCrdt.type !== CrdtType.TEXT || stringifyOrLog(crdt.data) !== stringifyOrLog(currentCrdt.data) || crdt.version !== currentCrdt.version) {
8925
- ops.push({
8926
- type: OpCode.UPDATE_TEXT,
8927
- id,
8928
- baseVersion: currentCrdt.type === CrdtType.TEXT ? currentCrdt.version : 0,
8929
- version: crdt.version,
8930
- ops: [
8931
- {
8932
- type: "delete",
8933
- index: 0,
8934
- length: currentCrdt.type === CrdtType.TEXT ? currentCrdt.data.reduce(
8935
- (sum, item) => sum + item.text.length,
8936
- 0
8937
- ) : 0
8938
- },
8939
- ...crdt.data.map(
8940
- (item, index, items) => item.attributes === void 0 ? {
8941
- type: "insert",
8942
- index: items.slice(0, index).reduce((sum, item2) => sum + item2.text.length, 0),
8943
- text: item.text
8944
- } : {
8945
- type: "insert",
8946
- index: items.slice(0, index).reduce((sum, item2) => sum + item2.text.length, 0),
8947
- text: item.text,
8948
- attributes: item.attributes
8949
- }
8950
- )
8951
- ]
8952
- });
8953
- }
8954
- }
8955
8563
  if (crdt.parentKey !== currentCrdt.parentKey) {
8956
8564
  ops.push({
8957
8565
  type: OpCode.SET_PARENT_KEY,
@@ -9000,16 +8608,6 @@ function getTreesDiffOperations(currentItems, newItems) {
9000
8608
  parentKey: crdt.parentKey
9001
8609
  });
9002
8610
  break;
9003
- case CrdtType.TEXT:
9004
- ops.push({
9005
- type: OpCode.CREATE_TEXT,
9006
- id,
9007
- parentId: crdt.parentId,
9008
- parentKey: crdt.parentKey,
9009
- data: crdt.data,
9010
- version: crdt.version
9011
- });
9012
- break;
9013
8611
  }
9014
8612
  }
9015
8613
  });
@@ -9042,12 +8640,6 @@ function mergeListStorageUpdates(first, second) {
9042
8640
  updates: updates.concat(second.updates)
9043
8641
  };
9044
8642
  }
9045
- function mergeTextStorageUpdates(first, second) {
9046
- return {
9047
- ...second,
9048
- updates: first.updates.concat(second.updates)
9049
- };
9050
- }
9051
8643
  function mergeStorageUpdates(first, second) {
9052
8644
  if (first === void 0) {
9053
8645
  return second;
@@ -9058,8 +8650,6 @@ function mergeStorageUpdates(first, second) {
9058
8650
  return mergeMapStorageUpdates(first, second);
9059
8651
  } else if (first.type === "LiveList" && second.type === "LiveList") {
9060
8652
  return mergeListStorageUpdates(first, second);
9061
- } else if (first.type === "LiveText" && second.type === "LiveText") {
9062
- return mergeTextStorageUpdates(first, second);
9063
8653
  } else {
9064
8654
  }
9065
8655
  return second;
@@ -9078,7 +8668,7 @@ function sendToPanel(message, options) {
9078
8668
  ...message,
9079
8669
  source: "liveblocks-devtools-client"
9080
8670
  };
9081
- if (!(_optionalChain([options, 'optionalAccess', _207 => _207.force]) || _bridgeActive)) {
8671
+ if (!(_optionalChain([options, 'optionalAccess', _213 => _213.force]) || _bridgeActive)) {
9082
8672
  return;
9083
8673
  }
9084
8674
  window.postMessage(fullMsg, "*");
@@ -9086,7 +8676,7 @@ function sendToPanel(message, options) {
9086
8676
  var eventSource = makeEventSource();
9087
8677
  if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
9088
8678
  window.addEventListener("message", (event) => {
9089
- if (event.source === window && _optionalChain([event, 'access', _208 => _208.data, 'optionalAccess', _209 => _209.source]) === "liveblocks-devtools-panel") {
8679
+ if (event.source === window && _optionalChain([event, 'access', _214 => _214.data, 'optionalAccess', _215 => _215.source]) === "liveblocks-devtools-panel") {
9090
8680
  eventSource.notify(event.data);
9091
8681
  } else {
9092
8682
  }
@@ -9228,7 +8818,7 @@ function fullSync(room) {
9228
8818
  msg: "room::sync::full",
9229
8819
  roomId: room.id,
9230
8820
  status: room.getStatus(),
9231
- storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _210 => _210.toTreeNode, 'call', _211 => _211("root"), 'access', _212 => _212.payload]), () => ( null)),
8821
+ storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _216 => _216.toTreeNode, 'call', _217 => _217("root"), 'access', _218 => _218.payload]), () => ( null)),
9232
8822
  me,
9233
8823
  others
9234
8824
  });
@@ -9907,15 +9497,15 @@ function installBackgroundTabSpy() {
9907
9497
  const doc = typeof document !== "undefined" ? document : void 0;
9908
9498
  const inBackgroundSince = { current: null };
9909
9499
  function onVisibilityChange() {
9910
- if (_optionalChain([doc, 'optionalAccess', _213 => _213.visibilityState]) === "hidden") {
9500
+ if (_optionalChain([doc, 'optionalAccess', _219 => _219.visibilityState]) === "hidden") {
9911
9501
  inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
9912
9502
  } else {
9913
9503
  inBackgroundSince.current = null;
9914
9504
  }
9915
9505
  }
9916
- _optionalChain([doc, 'optionalAccess', _214 => _214.addEventListener, 'call', _215 => _215("visibilitychange", onVisibilityChange)]);
9506
+ _optionalChain([doc, 'optionalAccess', _220 => _220.addEventListener, 'call', _221 => _221("visibilitychange", onVisibilityChange)]);
9917
9507
  const unsub = () => {
9918
- _optionalChain([doc, 'optionalAccess', _216 => _216.removeEventListener, 'call', _217 => _217("visibilitychange", onVisibilityChange)]);
9508
+ _optionalChain([doc, 'optionalAccess', _222 => _222.removeEventListener, 'call', _223 => _223("visibilitychange", onVisibilityChange)]);
9919
9509
  };
9920
9510
  return [inBackgroundSince, unsub];
9921
9511
  }
@@ -9960,6 +9550,7 @@ function createRoom(options, config) {
9960
9550
  delegates,
9961
9551
  config.enableDebugLogging
9962
9552
  );
9553
+ const unacknowledgedOps = new UnacknowledgedOps();
9963
9554
  const context = {
9964
9555
  buffer: {
9965
9556
  flushTimerID: void 0,
@@ -9987,14 +9578,15 @@ function createRoom(options, config) {
9987
9578
  pool: createManagedPool(roomId, {
9988
9579
  getCurrentConnectionId,
9989
9580
  onDispatch,
9990
- isStorageWritable
9581
+ isStorageWritable,
9582
+ unacknowledgedOps
9991
9583
  }),
9992
9584
  root: void 0,
9993
9585
  undoStack: [],
9994
9586
  redoStack: [],
9995
9587
  pausedHistory: null,
9996
9588
  activeBatch: null,
9997
- unacknowledgedOps: /* @__PURE__ */ new Map()
9589
+ unacknowledgedOps
9998
9590
  };
9999
9591
  const nodeMapBuffer = makeNodeMapBuffer();
10000
9592
  const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
@@ -10106,7 +9698,7 @@ function createRoom(options, config) {
10106
9698
  }
10107
9699
  }
10108
9700
  function isStorageWritable() {
10109
- const scopes = _optionalChain([context, 'access', _218 => _218.dynamicSessionInfoSig, 'access', _219 => _219.get, 'call', _220 => _220(), 'optionalAccess', _221 => _221.scopes]);
9701
+ const scopes = _optionalChain([context, 'access', _224 => _224.dynamicSessionInfoSig, 'access', _225 => _225.get, 'call', _226 => _226(), 'optionalAccess', _227 => _227.scopes]);
10110
9702
  return scopes !== void 0 ? canWriteStorage(scopes) : true;
10111
9703
  }
10112
9704
  const eventHub = {
@@ -10202,7 +9794,11 @@ function createRoom(options, config) {
10202
9794
  currentItems.set(id, crdt._serialize());
10203
9795
  }
10204
9796
  const ops = getTreesDiffOperations(currentItems, nodes);
10205
- const result = applyRemoteOps(ops);
9797
+ const result = applyRemoteOps(
9798
+ ops,
9799
+ /* fromSnapshot */
9800
+ true
9801
+ );
10206
9802
  notify(result.updates);
10207
9803
  } else {
10208
9804
  context.root = LiveObject._fromItems(
@@ -10210,7 +9806,7 @@ function createRoom(options, config) {
10210
9806
  context.pool
10211
9807
  );
10212
9808
  }
10213
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _222 => _222.get, 'call', _223 => _223(), 'optionalAccess', _224 => _224.canWrite]), () => ( true));
9809
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _228 => _228.get, 'call', _229 => _229(), 'optionalAccess', _230 => _230.canWrite]), () => ( true));
10214
9810
  const root = context.root;
10215
9811
  disableHistory(() => {
10216
9812
  for (const key in context.initialStorage) {
@@ -10284,15 +9880,16 @@ function createRoom(options, config) {
10284
9880
  );
10285
9881
  return { opsToEmit: opsWithOpIds, reverse, updates };
10286
9882
  }
10287
- function applyRemoteOps(ops) {
9883
+ function applyRemoteOps(ops, fromSnapshot = false) {
10288
9884
  return applyOps(
10289
9885
  [],
10290
9886
  ops,
10291
9887
  /* isLocal */
10292
- false
9888
+ false,
9889
+ fromSnapshot
10293
9890
  );
10294
9891
  }
10295
- function applyOps(pframes, ops, isLocal) {
9892
+ function applyOps(pframes, ops, isLocal, fromSnapshot = false) {
10296
9893
  const output = {
10297
9894
  reverse: new Deque(),
10298
9895
  storageUpdates: /* @__PURE__ */ new Map(),
@@ -10328,7 +9925,7 @@ function createRoom(options, config) {
10328
9925
  } else {
10329
9926
  source = 1 /* THEIRS */;
10330
9927
  }
10331
- const applyOpResult = applyOp(op, source);
9928
+ const applyOpResult = applyOp(op, source, fromSnapshot);
10332
9929
  if (applyOpResult.modified) {
10333
9930
  const nodeId = applyOpResult.modified.node._id;
10334
9931
  if (!(nodeId && createdNodeIds.has(nodeId))) {
@@ -10341,7 +9938,7 @@ function createRoom(options, config) {
10341
9938
  );
10342
9939
  output.reverse.pushLeft(applyOpResult.reverse);
10343
9940
  }
10344
- if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_TEXT) {
9941
+ if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
10345
9942
  createdNodeIds.add(op.id);
10346
9943
  }
10347
9944
  }
@@ -10354,14 +9951,13 @@ function createRoom(options, config) {
10354
9951
  }
10355
9952
  };
10356
9953
  }
10357
- function applyOp(op, source) {
9954
+ function applyOp(op, source, fromSnapshot = false) {
10358
9955
  if (isIgnoredOp(op)) {
10359
9956
  return { modified: false };
10360
9957
  }
10361
9958
  switch (op.type) {
10362
9959
  case OpCode.DELETE_OBJECT_KEY:
10363
9960
  case OpCode.UPDATE_OBJECT:
10364
- case OpCode.UPDATE_TEXT:
10365
9961
  case OpCode.DELETE_CRDT: {
10366
9962
  const node = context.pool.nodes.get(op.id);
10367
9963
  if (node === void 0) {
@@ -10386,7 +9982,6 @@ function createRoom(options, config) {
10386
9982
  case OpCode.CREATE_OBJECT:
10387
9983
  case OpCode.CREATE_LIST:
10388
9984
  case OpCode.CREATE_MAP:
10389
- case OpCode.CREATE_TEXT:
10390
9985
  case OpCode.CREATE_REGISTER: {
10391
9986
  if (op.parentId === void 0) {
10392
9987
  return { modified: false };
@@ -10395,7 +9990,7 @@ function createRoom(options, config) {
10395
9990
  if (parentNode === void 0) {
10396
9991
  return { modified: false };
10397
9992
  }
10398
- return parentNode._attachChild(op, source);
9993
+ return parentNode._attachChild(op, source, fromSnapshot);
10399
9994
  }
10400
9995
  }
10401
9996
  }
@@ -10417,7 +10012,7 @@ function createRoom(options, config) {
10417
10012
  }
10418
10013
  context.myPresence.patch(patch);
10419
10014
  if (context.activeBatch) {
10420
- if (_optionalChain([options2, 'optionalAccess', _225 => _225.addToHistory])) {
10015
+ if (_optionalChain([options2, 'optionalAccess', _231 => _231.addToHistory])) {
10421
10016
  context.activeBatch.reverseOps.pushLeft({
10422
10017
  type: "presence",
10423
10018
  data: oldValues
@@ -10426,7 +10021,7 @@ function createRoom(options, config) {
10426
10021
  context.activeBatch.updates.presence = true;
10427
10022
  } else {
10428
10023
  flushNowOrSoon();
10429
- if (_optionalChain([options2, 'optionalAccess', _226 => _226.addToHistory])) {
10024
+ if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
10430
10025
  addToUndoStack([{ type: "presence", data: oldValues }]);
10431
10026
  }
10432
10027
  notify({ presence: true });
@@ -10535,12 +10130,11 @@ function createRoom(options, config) {
10535
10130
  }
10536
10131
  }
10537
10132
  function applyAndSendOfflineOps(unackedOps) {
10538
- if (unackedOps.size === 0) {
10133
+ if (unackedOps.length === 0) {
10539
10134
  return;
10540
10135
  }
10541
10136
  const messages = [];
10542
- const inOps = Array.from(unackedOps.values());
10543
- const result = applyLocalOps(inOps);
10137
+ const result = applyLocalOps(unackedOps);
10544
10138
  messages.push({
10545
10139
  type: ClientMsgCode.UPDATE_STORAGE,
10546
10140
  ops: result.opsToEmit
@@ -10604,11 +10198,11 @@ function createRoom(options, config) {
10604
10198
  break;
10605
10199
  }
10606
10200
  case ServerMsgCode.STORAGE_CHUNK:
10607
- _optionalChain([stopwatch, 'optionalAccess', _227 => _227.lap, 'call', _228 => _228()]);
10201
+ _optionalChain([stopwatch, 'optionalAccess', _233 => _233.lap, 'call', _234 => _234()]);
10608
10202
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
10609
10203
  break;
10610
10204
  case ServerMsgCode.STORAGE_STREAM_END: {
10611
- const timing = _optionalChain([stopwatch, 'optionalAccess', _229 => _229.stop, 'call', _230 => _230()]);
10205
+ const timing = _optionalChain([stopwatch, 'optionalAccess', _235 => _235.stop, 'call', _236 => _236()]);
10612
10206
  if (timing) {
10613
10207
  const ms = (v) => `${v.toFixed(1)}ms`;
10614
10208
  const rest = timing.laps.slice(1);
@@ -10743,11 +10337,11 @@ function createRoom(options, config) {
10743
10337
  } else if (pendingFeedsRequests.has(requestId)) {
10744
10338
  const pending = pendingFeedsRequests.get(requestId);
10745
10339
  pendingFeedsRequests.delete(requestId);
10746
- _optionalChain([pending, 'optionalAccess', _231 => _231.reject, 'call', _232 => _232(err)]);
10340
+ _optionalChain([pending, 'optionalAccess', _237 => _237.reject, 'call', _238 => _238(err)]);
10747
10341
  } else if (pendingFeedMessagesRequests.has(requestId)) {
10748
10342
  const pending = pendingFeedMessagesRequests.get(requestId);
10749
10343
  pendingFeedMessagesRequests.delete(requestId);
10750
- _optionalChain([pending, 'optionalAccess', _233 => _233.reject, 'call', _234 => _234(err)]);
10344
+ _optionalChain([pending, 'optionalAccess', _239 => _239.reject, 'call', _240 => _240(err)]);
10751
10345
  }
10752
10346
  eventHub.feeds.notify(message);
10753
10347
  break;
@@ -10764,7 +10358,7 @@ function createRoom(options, config) {
10764
10358
  const storageOps = context.buffer.storageOperations;
10765
10359
  if (storageOps.length > 0) {
10766
10360
  for (const op of storageOps) {
10767
- context.unacknowledgedOps.set(op.opId, op);
10361
+ context.unacknowledgedOps.add(op);
10768
10362
  }
10769
10363
  notifyStorageStatus();
10770
10364
  }
@@ -10901,10 +10495,10 @@ function createRoom(options, config) {
10901
10495
  timeoutId,
10902
10496
  kind,
10903
10497
  feedId,
10904
- messageId: _optionalChain([options2, 'optionalAccess', _235 => _235.messageId]),
10905
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _236 => _236.expectedClientMessageId])
10498
+ messageId: _optionalChain([options2, 'optionalAccess', _241 => _241.messageId]),
10499
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _242 => _242.expectedClientMessageId])
10906
10500
  });
10907
- if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _237 => _237.expectedClientMessageId]) === void 0) {
10501
+ if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _243 => _243.expectedClientMessageId]) === void 0) {
10908
10502
  const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
10909
10503
  q.push(requestId);
10910
10504
  pendingAddMessageFifoByFeed.set(feedId, q);
@@ -10955,10 +10549,10 @@ function createRoom(options, config) {
10955
10549
  }
10956
10550
  if (!matched) {
10957
10551
  const q = pendingAddMessageFifoByFeed.get(message.feedId);
10958
- const headId = _optionalChain([q, 'optionalAccess', _238 => _238[0]]);
10552
+ const headId = _optionalChain([q, 'optionalAccess', _244 => _244[0]]);
10959
10553
  if (headId !== void 0) {
10960
10554
  const pending = pendingFeedMutations.get(headId);
10961
- if (_optionalChain([pending, 'optionalAccess', _239 => _239.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10555
+ if (_optionalChain([pending, 'optionalAccess', _245 => _245.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10962
10556
  settleFeedMutation(headId, "ok");
10963
10557
  }
10964
10558
  }
@@ -10991,10 +10585,10 @@ function createRoom(options, config) {
10991
10585
  }
10992
10586
  }
10993
10587
  function processInitialStorage(nodes) {
10994
- const unacknowledgedOps = new Map(context.unacknowledgedOps);
10588
+ const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
10995
10589
  createOrUpdateRootFromMessage(nodes);
10996
- applyAndSendOfflineOps(unacknowledgedOps);
10997
- _optionalChain([_resolveStoragePromise, 'optionalCall', _240 => _240()]);
10590
+ applyAndSendOfflineOps(unacknowledgedOps2);
10591
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _246 => _246()]);
10998
10592
  notifyStorageStatus();
10999
10593
  eventHub.storageDidLoad.notify();
11000
10594
  }
@@ -11012,7 +10606,7 @@ function createRoom(options, config) {
11012
10606
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
11013
10607
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
11014
10608
  nodeMapBuffer.take();
11015
- _optionalChain([stopwatch, 'optionalAccess', _241 => _241.start, 'call', _242 => _242()]);
10609
+ _optionalChain([stopwatch, 'optionalAccess', _247 => _247.start, 'call', _248 => _248()]);
11016
10610
  }
11017
10611
  if (options2.flush) {
11018
10612
  flushNowOrSoon();
@@ -11068,10 +10662,10 @@ function createRoom(options, config) {
11068
10662
  const message = {
11069
10663
  type: ClientMsgCode.FETCH_FEEDS,
11070
10664
  requestId,
11071
- cursor: _optionalChain([options2, 'optionalAccess', _243 => _243.cursor]),
11072
- since: _optionalChain([options2, 'optionalAccess', _244 => _244.since]),
11073
- limit: _optionalChain([options2, 'optionalAccess', _245 => _245.limit]),
11074
- metadata: _optionalChain([options2, 'optionalAccess', _246 => _246.metadata])
10665
+ cursor: _optionalChain([options2, 'optionalAccess', _249 => _249.cursor]),
10666
+ since: _optionalChain([options2, 'optionalAccess', _250 => _250.since]),
10667
+ limit: _optionalChain([options2, 'optionalAccess', _251 => _251.limit]),
10668
+ metadata: _optionalChain([options2, 'optionalAccess', _252 => _252.metadata])
11075
10669
  };
11076
10670
  context.buffer.messages.push(message);
11077
10671
  flushNowOrSoon();
@@ -11091,9 +10685,9 @@ function createRoom(options, config) {
11091
10685
  type: ClientMsgCode.FETCH_FEED_MESSAGES,
11092
10686
  requestId,
11093
10687
  feedId,
11094
- cursor: _optionalChain([options2, 'optionalAccess', _247 => _247.cursor]),
11095
- since: _optionalChain([options2, 'optionalAccess', _248 => _248.since]),
11096
- limit: _optionalChain([options2, 'optionalAccess', _249 => _249.limit])
10688
+ cursor: _optionalChain([options2, 'optionalAccess', _253 => _253.cursor]),
10689
+ since: _optionalChain([options2, 'optionalAccess', _254 => _254.since]),
10690
+ limit: _optionalChain([options2, 'optionalAccess', _255 => _255.limit])
11097
10691
  };
11098
10692
  context.buffer.messages.push(message);
11099
10693
  flushNowOrSoon();
@@ -11112,8 +10706,8 @@ function createRoom(options, config) {
11112
10706
  type: ClientMsgCode.ADD_FEED,
11113
10707
  requestId,
11114
10708
  feedId,
11115
- metadata: _optionalChain([options2, 'optionalAccess', _250 => _250.metadata]),
11116
- createdAt: _optionalChain([options2, 'optionalAccess', _251 => _251.createdAt])
10709
+ metadata: _optionalChain([options2, 'optionalAccess', _256 => _256.metadata]),
10710
+ createdAt: _optionalChain([options2, 'optionalAccess', _257 => _257.createdAt])
11117
10711
  };
11118
10712
  context.buffer.messages.push(message);
11119
10713
  flushNowOrSoon();
@@ -11147,15 +10741,15 @@ function createRoom(options, config) {
11147
10741
  function addFeedMessage(feedId, data, options2) {
11148
10742
  const requestId = nanoid();
11149
10743
  const promise = registerFeedMutation(requestId, "add-message", feedId, {
11150
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _252 => _252.id])
10744
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _258 => _258.id])
11151
10745
  });
11152
10746
  const message = {
11153
10747
  type: ClientMsgCode.ADD_FEED_MESSAGE,
11154
10748
  requestId,
11155
10749
  feedId,
11156
10750
  data,
11157
- id: _optionalChain([options2, 'optionalAccess', _253 => _253.id]),
11158
- createdAt: _optionalChain([options2, 'optionalAccess', _254 => _254.createdAt])
10751
+ id: _optionalChain([options2, 'optionalAccess', _259 => _259.id]),
10752
+ createdAt: _optionalChain([options2, 'optionalAccess', _260 => _260.createdAt])
11159
10753
  };
11160
10754
  context.buffer.messages.push(message);
11161
10755
  flushNowOrSoon();
@@ -11172,7 +10766,7 @@ function createRoom(options, config) {
11172
10766
  feedId,
11173
10767
  messageId,
11174
10768
  data,
11175
- updatedAt: _optionalChain([options2, 'optionalAccess', _255 => _255.updatedAt])
10769
+ updatedAt: _optionalChain([options2, 'optionalAccess', _261 => _261.updatedAt])
11176
10770
  };
11177
10771
  context.buffer.messages.push(message);
11178
10772
  flushNowOrSoon();
@@ -11379,8 +10973,8 @@ function createRoom(options, config) {
11379
10973
  async function getThreads(options2) {
11380
10974
  return httpClient.getThreads({
11381
10975
  roomId,
11382
- query: _optionalChain([options2, 'optionalAccess', _256 => _256.query]),
11383
- cursor: _optionalChain([options2, 'optionalAccess', _257 => _257.cursor])
10976
+ query: _optionalChain([options2, 'optionalAccess', _262 => _262.query]),
10977
+ cursor: _optionalChain([options2, 'optionalAccess', _263 => _263.cursor])
11384
10978
  });
11385
10979
  }
11386
10980
  async function getThread(threadId) {
@@ -11502,7 +11096,7 @@ function createRoom(options, config) {
11502
11096
  function getSubscriptionSettings(options2) {
11503
11097
  return httpClient.getSubscriptionSettings({
11504
11098
  roomId,
11505
- signal: _optionalChain([options2, 'optionalAccess', _258 => _258.signal])
11099
+ signal: _optionalChain([options2, 'optionalAccess', _264 => _264.signal])
11506
11100
  });
11507
11101
  }
11508
11102
  function updateSubscriptionSettings(settings) {
@@ -11524,7 +11118,7 @@ function createRoom(options, config) {
11524
11118
  {
11525
11119
  [kInternal]: {
11526
11120
  get presenceBuffer() {
11527
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _259 => _259.buffer, 'access', _260 => _260.presenceUpdates, 'optionalAccess', _261 => _261.data]), () => ( null)));
11121
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _265 => _265.buffer, 'access', _266 => _266.presenceUpdates, 'optionalAccess', _267 => _267.data]), () => ( null)));
11528
11122
  },
11529
11123
  // prettier-ignore
11530
11124
  get undoStack() {
@@ -11539,9 +11133,9 @@ function createRoom(options, config) {
11539
11133
  return context.yjsProvider;
11540
11134
  },
11541
11135
  setYjsProvider(newProvider) {
11542
- _optionalChain([context, 'access', _262 => _262.yjsProvider, 'optionalAccess', _263 => _263.off, 'call', _264 => _264("status", yjsStatusDidChange)]);
11136
+ _optionalChain([context, 'access', _268 => _268.yjsProvider, 'optionalAccess', _269 => _269.off, 'call', _270 => _270("status", yjsStatusDidChange)]);
11543
11137
  context.yjsProvider = newProvider;
11544
- _optionalChain([newProvider, 'optionalAccess', _265 => _265.on, 'call', _266 => _266("status", yjsStatusDidChange)]);
11138
+ _optionalChain([newProvider, 'optionalAccess', _271 => _271.on, 'call', _272 => _272("status", yjsStatusDidChange)]);
11545
11139
  context.yjsProviderDidChange.notify();
11546
11140
  },
11547
11141
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -11582,6 +11176,11 @@ function createRoom(options, config) {
11582
11176
  connect: () => managedSocket.connect(),
11583
11177
  reconnect: () => managedSocket.reconnect(),
11584
11178
  disconnect: () => managedSocket.disconnect(),
11179
+ _dump: () => {
11180
+ const n = context.pool.nodes.size;
11181
+ return `Room "${roomId}" (${n} node${n === 1 ? "" : "s"}):
11182
+ ${dumpPool(context.pool)}`;
11183
+ },
11585
11184
  destroy: () => {
11586
11185
  pendingFeedsRequests.forEach(
11587
11186
  (request) => request.reject(new Error("Room destroyed"))
@@ -11594,7 +11193,7 @@ function createRoom(options, config) {
11594
11193
  source.dispose();
11595
11194
  }
11596
11195
  eventHub.roomWillDestroy.notify();
11597
- _optionalChain([context, 'access', _267 => _267.yjsProvider, 'optionalAccess', _268 => _268.off, 'call', _269 => _269("status", yjsStatusDidChange)]);
11196
+ _optionalChain([context, 'access', _273 => _273.yjsProvider, 'optionalAccess', _274 => _274.off, 'call', _275 => _275("status", yjsStatusDidChange)]);
11598
11197
  syncSourceForStorage.destroy();
11599
11198
  syncSourceForYjs.destroy();
11600
11199
  uninstallBgTabSpy();
@@ -11754,7 +11353,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
11754
11353
  }
11755
11354
  if (isLiveNode(first)) {
11756
11355
  const node = first;
11757
- if (_optionalChain([options, 'optionalAccess', _270 => _270.isDeep])) {
11356
+ if (_optionalChain([options, 'optionalAccess', _276 => _276.isDeep])) {
11758
11357
  const storageCallback = second;
11759
11358
  return subscribeToLiveStructureDeeply(node, storageCallback);
11760
11359
  } else {
@@ -11840,8 +11439,8 @@ function createClient(options) {
11840
11439
  const authManager = createAuthManager(options, (token) => {
11841
11440
  currentUserId.set(() => token.uid);
11842
11441
  });
11843
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _271 => _271.polyfills, 'optionalAccess', _272 => _272.fetch]) || /* istanbul ignore next */
11844
- _optionalChain([globalThis, 'access', _273 => _273.fetch, 'optionalAccess', _274 => _274.bind, 'call', _275 => _275(globalThis)]);
11442
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _277 => _277.polyfills, 'optionalAccess', _278 => _278.fetch]) || /* istanbul ignore next */
11443
+ _optionalChain([globalThis, 'access', _279 => _279.fetch, 'optionalAccess', _280 => _280.bind, 'call', _281 => _281(globalThis)]);
11845
11444
  const httpClient = createApiClient({
11846
11445
  baseUrl,
11847
11446
  fetchPolyfill,
@@ -11859,7 +11458,7 @@ function createClient(options) {
11859
11458
  delegates: {
11860
11459
  createSocket: makeCreateSocketDelegateForAi(
11861
11460
  baseUrl,
11862
- _optionalChain([clientOptions, 'access', _276 => _276.polyfills, 'optionalAccess', _277 => _277.WebSocket])
11461
+ _optionalChain([clientOptions, 'access', _282 => _282.polyfills, 'optionalAccess', _283 => _283.WebSocket])
11863
11462
  ),
11864
11463
  authenticate: async () => {
11865
11464
  const resp = await authManager.getAuthValue({
@@ -11929,7 +11528,7 @@ function createClient(options) {
11929
11528
  createSocket: makeCreateSocketDelegateForRoom(
11930
11529
  roomId,
11931
11530
  baseUrl,
11932
- _optionalChain([clientOptions, 'access', _278 => _278.polyfills, 'optionalAccess', _279 => _279.WebSocket])
11531
+ _optionalChain([clientOptions, 'access', _284 => _284.polyfills, 'optionalAccess', _285 => _285.WebSocket])
11933
11532
  ),
11934
11533
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
11935
11534
  })),
@@ -11952,7 +11551,7 @@ function createClient(options) {
11952
11551
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
11953
11552
  if (shouldConnect) {
11954
11553
  if (typeof atob === "undefined") {
11955
- if (_optionalChain([clientOptions, 'access', _280 => _280.polyfills, 'optionalAccess', _281 => _281.atob]) === void 0) {
11554
+ if (_optionalChain([clientOptions, 'access', _286 => _286.polyfills, 'optionalAccess', _287 => _287.atob]) === void 0) {
11956
11555
  throw new Error(
11957
11556
  "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"
11958
11557
  );
@@ -11964,7 +11563,7 @@ function createClient(options) {
11964
11563
  return leaseRoom(newRoomDetails);
11965
11564
  }
11966
11565
  function getRoom(roomId) {
11967
- const room = _optionalChain([roomsById, 'access', _282 => _282.get, 'call', _283 => _283(roomId), 'optionalAccess', _284 => _284.room]);
11566
+ const room = _optionalChain([roomsById, 'access', _288 => _288.get, 'call', _289 => _289(roomId), 'optionalAccess', _290 => _290.room]);
11968
11567
  return room ? room : null;
11969
11568
  }
11970
11569
  function logout() {
@@ -11980,7 +11579,7 @@ function createClient(options) {
11980
11579
  const batchedResolveUsers = new Batch(
11981
11580
  async (batchedUserIds) => {
11982
11581
  const userIds = batchedUserIds.flat();
11983
- const users = await _optionalChain([resolveUsers, 'optionalCall', _285 => _285({ userIds })]);
11582
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _291 => _291({ userIds })]);
11984
11583
  warnOnceIf(
11985
11584
  !resolveUsers,
11986
11585
  "Set the resolveUsers option in createClient to specify user info."
@@ -11997,7 +11596,7 @@ function createClient(options) {
11997
11596
  const batchedResolveRoomsInfo = new Batch(
11998
11597
  async (batchedRoomIds) => {
11999
11598
  const roomIds = batchedRoomIds.flat();
12000
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _286 => _286({ roomIds })]);
11599
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _292 => _292({ roomIds })]);
12001
11600
  warnOnceIf(
12002
11601
  !resolveRoomsInfo,
12003
11602
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -12014,7 +11613,7 @@ function createClient(options) {
12014
11613
  const batchedResolveGroupsInfo = new Batch(
12015
11614
  async (batchedGroupIds) => {
12016
11615
  const groupIds = batchedGroupIds.flat();
12017
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _287 => _287({ groupIds })]);
11616
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _293 => _293({ groupIds })]);
12018
11617
  warnOnceIf(
12019
11618
  !resolveGroupsInfo,
12020
11619
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -12073,7 +11672,7 @@ function createClient(options) {
12073
11672
  }
12074
11673
  };
12075
11674
  const win = typeof window !== "undefined" ? window : void 0;
12076
- _optionalChain([win, 'optionalAccess', _288 => _288.addEventListener, 'call', _289 => _289("beforeunload", maybePreventClose)]);
11675
+ _optionalChain([win, 'optionalAccess', _294 => _294.addEventListener, 'call', _295 => _295("beforeunload", maybePreventClose)]);
12077
11676
  }
12078
11677
  async function getNotificationSettings(options2) {
12079
11678
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -12089,6 +11688,7 @@ function createClient(options) {
12089
11688
  {
12090
11689
  enterRoom,
12091
11690
  getRoom,
11691
+ _dump: () => Array.from(roomsById.values(), ({ room }) => room._dump()).join("\n\n"),
12092
11692
  logout,
12093
11693
  // Public inbox notifications API
12094
11694
  getInboxNotifications: httpClient.getInboxNotifications,
@@ -12200,7 +11800,7 @@ var commentBodyElementsTypes = {
12200
11800
  mention: "inline"
12201
11801
  };
12202
11802
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
12203
- if (!body || !_optionalChain([body, 'optionalAccess', _290 => _290.content])) {
11803
+ if (!body || !_optionalChain([body, 'optionalAccess', _296 => _296.content])) {
12204
11804
  return;
12205
11805
  }
12206
11806
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -12210,13 +11810,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
12210
11810
  for (const block of body.content) {
12211
11811
  if (type === "all" || type === "block") {
12212
11812
  if (guard(block)) {
12213
- _optionalChain([visitor, 'optionalCall', _291 => _291(block)]);
11813
+ _optionalChain([visitor, 'optionalCall', _297 => _297(block)]);
12214
11814
  }
12215
11815
  }
12216
11816
  if (type === "all" || type === "inline") {
12217
11817
  for (const inline of block.children) {
12218
11818
  if (guard(inline)) {
12219
- _optionalChain([visitor, 'optionalCall', _292 => _292(inline)]);
11819
+ _optionalChain([visitor, 'optionalCall', _298 => _298(inline)]);
12220
11820
  }
12221
11821
  }
12222
11822
  }
@@ -12386,7 +11986,7 @@ var stringifyCommentBodyPlainElements = {
12386
11986
  text: ({ element }) => element.text,
12387
11987
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
12388
11988
  mention: ({ element, user, group }) => {
12389
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _293 => _293.name]), () => ( _optionalChain([group, 'optionalAccess', _294 => _294.name]))), () => ( element.id))}`;
11989
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _299 => _299.name]), () => ( _optionalChain([group, 'optionalAccess', _300 => _300.name]))), () => ( element.id))}`;
12390
11990
  }
12391
11991
  };
12392
11992
  var stringifyCommentBodyHtmlElements = {
@@ -12416,7 +12016,7 @@ var stringifyCommentBodyHtmlElements = {
12416
12016
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
12417
12017
  },
12418
12018
  mention: ({ element, user, group }) => {
12419
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _295 => _295.name]) ? html`${_optionalChain([user, 'optionalAccess', _296 => _296.name])}` : _optionalChain([group, 'optionalAccess', _297 => _297.name]) ? html`${_optionalChain([group, 'optionalAccess', _298 => _298.name])}` : element.id}</span>`;
12019
+ 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>`;
12420
12020
  }
12421
12021
  };
12422
12022
  var stringifyCommentBodyMarkdownElements = {
@@ -12446,20 +12046,20 @@ var stringifyCommentBodyMarkdownElements = {
12446
12046
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
12447
12047
  },
12448
12048
  mention: ({ element, user, group }) => {
12449
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _299 => _299.name]), () => ( _optionalChain([group, 'optionalAccess', _300 => _300.name]))), () => ( element.id))}`;
12049
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _305 => _305.name]), () => ( _optionalChain([group, 'optionalAccess', _306 => _306.name]))), () => ( element.id))}`;
12450
12050
  }
12451
12051
  };
12452
12052
  async function stringifyCommentBody(body, options) {
12453
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _301 => _301.format]), () => ( "plain"));
12454
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _302 => _302.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
12053
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _307 => _307.format]), () => ( "plain"));
12054
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _308 => _308.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
12455
12055
  const elements = {
12456
12056
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
12457
- ..._optionalChain([options, 'optionalAccess', _303 => _303.elements])
12057
+ ..._optionalChain([options, 'optionalAccess', _309 => _309.elements])
12458
12058
  };
12459
12059
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
12460
12060
  body,
12461
- _optionalChain([options, 'optionalAccess', _304 => _304.resolveUsers]),
12462
- _optionalChain([options, 'optionalAccess', _305 => _305.resolveGroupsInfo])
12061
+ _optionalChain([options, 'optionalAccess', _310 => _310.resolveUsers]),
12062
+ _optionalChain([options, 'optionalAccess', _311 => _311.resolveGroupsInfo])
12463
12063
  );
12464
12064
  const blocks = body.content.flatMap((block, blockIndex) => {
12465
12065
  switch (block.type) {
@@ -12541,12 +12141,6 @@ function toPlainLson(lson) {
12541
12141
  liveblocksType: "LiveList",
12542
12142
  data: [...lson].map((item) => toPlainLson(item))
12543
12143
  };
12544
- } else if (lson instanceof LiveText) {
12545
- return {
12546
- liveblocksType: "LiveText",
12547
- data: lson.toDelta(),
12548
- version: lson.version
12549
- };
12550
12144
  } else {
12551
12145
  return lson;
12552
12146
  }
@@ -12600,9 +12194,9 @@ function makePoller(callback, intervalMs, options) {
12600
12194
  const startTime = performance.now();
12601
12195
  const doc = typeof document !== "undefined" ? document : void 0;
12602
12196
  const win = typeof window !== "undefined" ? window : void 0;
12603
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _306 => _306.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
12197
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _312 => _312.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
12604
12198
  const context = {
12605
- inForeground: _optionalChain([doc, 'optionalAccess', _307 => _307.visibilityState]) !== "hidden",
12199
+ inForeground: _optionalChain([doc, 'optionalAccess', _313 => _313.visibilityState]) !== "hidden",
12606
12200
  lastSuccessfulPollAt: startTime,
12607
12201
  count: 0,
12608
12202
  backoff: 0
@@ -12683,11 +12277,11 @@ function makePoller(callback, intervalMs, options) {
12683
12277
  pollNowIfStale();
12684
12278
  }
12685
12279
  function onVisibilityChange() {
12686
- setInForeground(_optionalChain([doc, 'optionalAccess', _308 => _308.visibilityState]) !== "hidden");
12280
+ setInForeground(_optionalChain([doc, 'optionalAccess', _314 => _314.visibilityState]) !== "hidden");
12687
12281
  }
12688
- _optionalChain([doc, 'optionalAccess', _309 => _309.addEventListener, 'call', _310 => _310("visibilitychange", onVisibilityChange)]);
12689
- _optionalChain([win, 'optionalAccess', _311 => _311.addEventListener, 'call', _312 => _312("online", onVisibilityChange)]);
12690
- _optionalChain([win, 'optionalAccess', _313 => _313.addEventListener, 'call', _314 => _314("focus", pollNowIfStale)]);
12282
+ _optionalChain([doc, 'optionalAccess', _315 => _315.addEventListener, 'call', _316 => _316("visibilitychange", onVisibilityChange)]);
12283
+ _optionalChain([win, 'optionalAccess', _317 => _317.addEventListener, 'call', _318 => _318("online", onVisibilityChange)]);
12284
+ _optionalChain([win, 'optionalAccess', _319 => _319.addEventListener, 'call', _320 => _320("focus", pollNowIfStale)]);
12691
12285
  fsm.start();
12692
12286
  return {
12693
12287
  inc,
@@ -12824,8 +12418,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
12824
12418
 
12825
12419
 
12826
12420
 
12827
-
12828
-
12829
-
12830
- 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.LiveText = LiveText; 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.applyLiveTextOperations = applyLiveTextOperations; 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.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.getSubscriptionKey = getSubscriptionKey; 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.isTextStorageNode = isTextStorageNode; 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.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; 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;
12421
+ 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.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.getSubscriptionKey = getSubscriptionKey; 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.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; 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;
12831
12422
  //# sourceMappingURL=index.cjs.map