@liveblocks/core 3.16.0-feeds1 → 3.16.0-flow2

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.16.0-feeds1";
9
+ var PKG_VERSION = "3.16.0-flow2";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -3219,26 +3219,10 @@ var ServerMsgCode = Object.freeze({
3219
3219
  COMMENT_REACTION_ADDED: 405,
3220
3220
  COMMENT_REACTION_REMOVED: 406,
3221
3221
  COMMENT_METADATA_UPDATED: 409,
3222
- // For Feeds
3223
- FEEDS_LIST: 500,
3224
- FEEDS_ADDED: 501,
3225
- FEEDS_UPDATED: 502,
3226
- FEED_DELETED: 503,
3227
- FEED_MESSAGES_LIST: 504,
3228
- FEED_MESSAGES_ADDED: 505,
3229
- FEED_MESSAGES_UPDATED: 506,
3230
- FEED_MESSAGES_DELETED: 507,
3231
- FEED_REQUEST_FAILED: 508,
3232
3222
  // Error codes
3233
3223
  REJECT_STORAGE_OP: 299
3234
3224
  // Sent if a mutation was not allowed on the server (i.e. due to permissions, limit exceeded, etc)
3235
3225
  });
3236
- var FeedRequestErrorCode = {
3237
- INTERNAL: "INTERNAL",
3238
- FEED_ALREADY_EXISTS: "FEED_ALREADY_EXISTS",
3239
- FEED_NOT_FOUND: "FEED_NOT_FOUND",
3240
- FEED_MESSAGE_NOT_FOUND: "FEED_MESSAGE_NOT_FOUND"
3241
- };
3242
3226
 
3243
3227
  // src/types/IWebSocket.ts
3244
3228
  var WebsocketCloseCodes = /* @__PURE__ */ ((WebsocketCloseCodes2) => {
@@ -5202,7 +5186,6 @@ var Permission = /* @__PURE__ */ ((Permission2) => {
5202
5186
  Permission2["PresenceWrite"] = "room:presence:write";
5203
5187
  Permission2["CommentsWrite"] = "comments:write";
5204
5188
  Permission2["CommentsRead"] = "comments:read";
5205
- Permission2["FeedsWrite"] = "feeds:write";
5206
5189
  return Permission2;
5207
5190
  })(Permission || {});
5208
5191
  function canWriteStorage(scopes) {
@@ -6319,7 +6302,6 @@ var AbstractCrdt = class {
6319
6302
  }
6320
6303
  /**
6321
6304
  * @internal
6322
- *
6323
6305
  * Return an snapshot of this Live tree for use in DevTools.
6324
6306
  */
6325
6307
  toTreeNode(key) {
@@ -6329,6 +6311,14 @@ var AbstractCrdt = class {
6329
6311
  }
6330
6312
  return this.#cachedTreeNode;
6331
6313
  }
6314
+ /**
6315
+ * @private
6316
+ * Returns true if the cached immutable snapshot exists and is
6317
+ * reference-equal to the given value. Does not trigger a recompute.
6318
+ */
6319
+ immutableIs(value) {
6320
+ return this.#cachedImmutable !== void 0 && this.#cachedImmutable === value;
6321
+ }
6332
6322
  /**
6333
6323
  * Return an immutable snapshot of this Live node and its children.
6334
6324
  */
@@ -7876,159 +7866,562 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7876
7866
  }
7877
7867
  };
7878
7868
 
7879
- // src/crdts/LiveObject.ts
7880
- var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
7881
- var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7882
- #map;
7883
- /**
7884
- * Tracks unacknowledged local changes per property to preserve optimistic
7885
- * updates. Maps property keys to their pending operation IDs.
7886
- *
7887
- * INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
7888
- * are only compared against (to detect ACKs), never stored.
7889
- *
7890
- * When a local change is made, the opId is stored here. When a remote op
7891
- * arrives for the same key:
7892
- * - If no entry exists → apply remote op
7893
- * - If opId matches → it's an ACK, clear the entry
7894
- * - If opId differs → ignore remote op to preserve optimistic update
7895
- */
7896
- #unackedOpsByKey;
7897
- /**
7898
- * Enable or disable detection of too large LiveObjects.
7899
- * When enabled, throws an error if LiveObject static data exceeds 128KB, which
7900
- * is the maximum value the server will be able to accept.
7901
- * By default, this behavior is disabled to avoid the runtime performance
7902
- * overhead on every LiveObject.set() or LiveObject.update() call.
7903
- *
7904
- * @experimental
7905
- */
7906
- static __initStatic() {this.detectLargeObjects = false}
7907
- static #buildRootAndParentToChildren(nodes) {
7908
- const parentToChildren = /* @__PURE__ */ new Map();
7909
- let root = null;
7910
- for (const node of nodes) {
7911
- if (isRootStorageNode(node)) {
7912
- root = node[1];
7869
+ // src/lib/Json.ts
7870
+ function isJsonScalar(data) {
7871
+ return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
7872
+ }
7873
+ function isJsonArray(data) {
7874
+ return Array.isArray(data);
7875
+ }
7876
+ function isJsonObject(data) {
7877
+ return !isJsonScalar(data) && !isJsonArray(data);
7878
+ }
7879
+
7880
+ // src/immutable.ts
7881
+ function lsonObjectToJson(obj) {
7882
+ const result = {};
7883
+ for (const key in obj) {
7884
+ const val = obj[key];
7885
+ if (val !== void 0) {
7886
+ result[key] = lsonToJson(val);
7887
+ }
7888
+ }
7889
+ return result;
7890
+ }
7891
+ function liveObjectToJson(liveObject) {
7892
+ return lsonObjectToJson(liveObject.toObject());
7893
+ }
7894
+ function liveMapToJson(map) {
7895
+ const result = {};
7896
+ for (const [key, value] of map.entries()) {
7897
+ result[key] = lsonToJson(value);
7898
+ }
7899
+ return result;
7900
+ }
7901
+ function lsonListToJson(value) {
7902
+ return value.map(lsonToJson);
7903
+ }
7904
+ function liveListToJson(value) {
7905
+ return lsonListToJson(value.toArray());
7906
+ }
7907
+ function lsonToJson(value) {
7908
+ if (value instanceof LiveObject) {
7909
+ return liveObjectToJson(value);
7910
+ } else if (value instanceof LiveList) {
7911
+ return liveListToJson(value);
7912
+ } else if (value instanceof LiveMap) {
7913
+ return liveMapToJson(value);
7914
+ } else if (value instanceof LiveRegister) {
7915
+ return value.data;
7916
+ }
7917
+ if (Array.isArray(value)) {
7918
+ return lsonListToJson(value);
7919
+ } else if (isPlainObject(value)) {
7920
+ return lsonObjectToJson(value);
7921
+ }
7922
+ return value;
7923
+ }
7924
+ function deepLiveify(value, config) {
7925
+ if (Array.isArray(value)) {
7926
+ return new LiveList(value.map((v) => deepLiveify(v, config)));
7927
+ } else if (isPlainObject(value)) {
7928
+ const init = {};
7929
+ const locals = {};
7930
+ for (const key in value) {
7931
+ const val = value[key];
7932
+ if (val === void 0) {
7933
+ continue;
7934
+ }
7935
+ const subConfig = isPlainObject(config) ? config[key] : config;
7936
+ if (subConfig === false) {
7937
+ locals[key] = val;
7938
+ } else if (subConfig === "atomic") {
7939
+ init[key] = val;
7913
7940
  } else {
7914
- const crdt = node[1];
7915
- const children = parentToChildren.get(crdt.parentId);
7916
- if (children !== void 0) {
7917
- children.push(node);
7918
- } else {
7919
- parentToChildren.set(crdt.parentId, [node]);
7920
- }
7941
+ init[key] = deepLiveify(val, subConfig);
7921
7942
  }
7922
7943
  }
7923
- if (root === null) {
7924
- throw new Error("Root can't be null");
7944
+ const lo = new LiveObject(init);
7945
+ for (const key in locals) {
7946
+ lo.setLocal(key, locals[key]);
7925
7947
  }
7926
- return [root, parentToChildren];
7948
+ return lo;
7949
+ } else {
7950
+ return value;
7927
7951
  }
7928
- /** @private Do not use this API directly */
7929
- static _fromItems(nodes, pool) {
7930
- const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(nodes);
7931
- return _LiveObject._deserialize(
7932
- ["root", root],
7933
- parentToChildren,
7934
- pool
7935
- );
7952
+ }
7953
+ function deepLiveifyObject(obj, config) {
7954
+ return deepLiveify(obj, config);
7955
+ }
7956
+ function reconcile(live, json, config) {
7957
+ if (isLiveObject(live) && isPlainObject(json)) {
7958
+ return reconcileLiveObject(live, json, config);
7959
+ } else if (isLiveList(live) && Array.isArray(json)) {
7960
+ return reconcileLiveList(live, json, config);
7961
+ } else if (isLiveMap(live) && isPlainObject(json)) {
7962
+ return reconcileLiveMap(live, config);
7963
+ } else {
7964
+ return deepLiveify(json, config);
7936
7965
  }
7937
- constructor(obj = {}) {
7938
- super();
7939
- this.#unackedOpsByKey = /* @__PURE__ */ new Map();
7940
- const o = compactObject(obj);
7941
- for (const key of Object.keys(o)) {
7942
- const value = o[key];
7943
- if (isLiveNode(value)) {
7944
- value._setParentLink(this, key);
7966
+ }
7967
+ function reconcileLiveMap(_liveMap, _config) {
7968
+ throw new Error("Reconciling a LiveMap is not supported yet");
7969
+ }
7970
+ function reconcileLiveObject(liveObj, jsonObj, config) {
7971
+ const currentKeys = liveObj.keys();
7972
+ for (const key in jsonObj) {
7973
+ currentKeys.delete(key);
7974
+ const newVal = jsonObj[key];
7975
+ if (newVal === void 0) {
7976
+ liveObj.delete(key);
7977
+ continue;
7978
+ }
7979
+ const subConfig = isPlainObject(config) ? config[key] : config;
7980
+ if (subConfig === false) {
7981
+ liveObj.setLocal(key, newVal);
7982
+ } else if (subConfig === "atomic") {
7983
+ const curVal = liveObj.get(key);
7984
+ if (curVal !== newVal) {
7985
+ liveObj.set(key, newVal);
7986
+ }
7987
+ } else {
7988
+ const curVal = liveObj.get(key);
7989
+ if (curVal === void 0) {
7990
+ liveObj.set(key, deepLiveify(newVal, subConfig));
7991
+ } else if (isLiveStructure(curVal)) {
7992
+ const next = reconcile(curVal, newVal, subConfig);
7993
+ if (next !== curVal) {
7994
+ liveObj.set(key, next);
7995
+ }
7996
+ } else if (curVal !== newVal) {
7997
+ liveObj.set(key, deepLiveify(newVal, subConfig));
7945
7998
  }
7946
7999
  }
7947
- this.#map = new Map(Object.entries(o));
7948
8000
  }
7949
- /** @internal */
7950
- _toOps(parentId, parentKey) {
7951
- if (this._id === void 0) {
7952
- throw new Error("Cannot serialize item is not attached");
7953
- }
7954
- const ops = [];
7955
- const op = {
7956
- type: OpCode.CREATE_OBJECT,
7957
- id: this._id,
7958
- parentId,
7959
- parentKey,
7960
- data: {}
7961
- };
7962
- ops.push(op);
7963
- for (const [key, value] of this.#map) {
7964
- if (isLiveNode(value)) {
7965
- for (const childOp of value._toOps(this._id, key)) {
7966
- ops.push(childOp);
7967
- }
7968
- } else {
7969
- op.data[key] = value;
8001
+ for (const key of currentKeys) {
8002
+ liveObj.delete(key);
8003
+ }
8004
+ return liveObj;
8005
+ }
8006
+ function reconcileLiveList(liveList, jsonArr, config) {
8007
+ const curLen = liveList.length;
8008
+ const newLen = jsonArr.length;
8009
+ for (let i = 0; i < Math.min(curLen, newLen); i++) {
8010
+ const curVal = liveList.get(i);
8011
+ const newVal = jsonArr[i];
8012
+ if (isLiveStructure(curVal)) {
8013
+ const next = reconcile(curVal, newVal, config);
8014
+ if (next !== curVal) {
8015
+ liveList.set(i, next);
7970
8016
  }
8017
+ } else if (curVal !== newVal) {
8018
+ liveList.set(i, deepLiveify(newVal, config));
7971
8019
  }
7972
- return ops;
7973
8020
  }
7974
- /** @internal */
7975
- static _deserialize([id, item], parentToChildren, pool) {
7976
- const liveObj = new _LiveObject(item.data);
7977
- liveObj._attach(id, pool);
7978
- return this._deserializeChildren(liveObj, parentToChildren, pool);
8021
+ for (let i = curLen; i < newLen; i++) {
8022
+ liveList.push(deepLiveify(jsonArr[i], config));
7979
8023
  }
7980
- /** @internal */
7981
- static _deserializeChildren(liveObj, parentToChildren, pool) {
7982
- const children = parentToChildren.get(nn(liveObj._id));
7983
- if (children === void 0) {
7984
- return liveObj;
8024
+ for (let i = curLen - 1; i >= newLen; i--) {
8025
+ liveList.delete(i);
8026
+ }
8027
+ return liveList;
8028
+ }
8029
+ function legacy_patchLiveList(liveList, prev, next) {
8030
+ let i = 0;
8031
+ let prevEnd = prev.length - 1;
8032
+ let nextEnd = next.length - 1;
8033
+ let prevNode = prev[0];
8034
+ let nextNode = next[0];
8035
+ outer: {
8036
+ while (prevNode === nextNode) {
8037
+ ++i;
8038
+ if (i > prevEnd || i > nextEnd) {
8039
+ break outer;
8040
+ }
8041
+ prevNode = prev[i];
8042
+ nextNode = next[i];
7985
8043
  }
7986
- for (const node of children) {
7987
- const child = deserializeToLson(node, parentToChildren, pool);
7988
- const crdt = node[1];
7989
- if (isLiveStructure(child)) {
7990
- child._setParentLink(liveObj, crdt.parentKey);
8044
+ prevNode = prev[prevEnd];
8045
+ nextNode = next[nextEnd];
8046
+ while (prevNode === nextNode) {
8047
+ prevEnd--;
8048
+ nextEnd--;
8049
+ if (i > prevEnd || i > nextEnd) {
8050
+ break outer;
7991
8051
  }
7992
- liveObj.#map.set(crdt.parentKey, child);
7993
- liveObj.invalidate();
8052
+ prevNode = prev[prevEnd];
8053
+ nextNode = next[nextEnd];
7994
8054
  }
7995
- return liveObj;
7996
8055
  }
7997
- /** @internal */
7998
- _attach(id, pool) {
7999
- super._attach(id, pool);
8000
- for (const [_key, value] of this.#map) {
8001
- if (isLiveNode(value)) {
8002
- value._attach(pool.generateId(), pool);
8056
+ if (i > prevEnd) {
8057
+ if (i <= nextEnd) {
8058
+ while (i <= nextEnd) {
8059
+ liveList.insert(deepLiveify(next[i]), i);
8060
+ i++;
8003
8061
  }
8004
8062
  }
8005
- }
8006
- /** @internal */
8007
- _attachChild(op, source) {
8008
- if (this._pool === void 0) {
8009
- throw new Error("Can't attach child if managed pool is not present");
8063
+ } else if (i > nextEnd) {
8064
+ let localI = i;
8065
+ while (localI <= prevEnd) {
8066
+ liveList.delete(i);
8067
+ localI++;
8010
8068
  }
8011
- const { id, opId, parentKey: key } = op;
8012
- const child = creationOpToLson(op);
8013
- if (this._pool.getNode(id) !== void 0) {
8014
- if (this.#unackedOpsByKey.get(key) === opId) {
8015
- this.#unackedOpsByKey.delete(key);
8069
+ } else {
8070
+ while (i <= prevEnd && i <= nextEnd) {
8071
+ prevNode = prev[i];
8072
+ nextNode = next[i];
8073
+ const liveListNode = liveList.get(i);
8074
+ if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
8075
+ legacy_patchLiveObject(liveListNode, prevNode, nextNode);
8076
+ } else {
8077
+ liveList.set(i, deepLiveify(nextNode));
8016
8078
  }
8017
- return { modified: false };
8079
+ i++;
8018
8080
  }
8019
- if (source === 0 /* LOCAL */) {
8020
- this.#unackedOpsByKey.set(key, nn(opId));
8021
- } else if (this.#unackedOpsByKey.get(key) === void 0) {
8022
- } else if (this.#unackedOpsByKey.get(key) === opId) {
8023
- this.#unackedOpsByKey.delete(key);
8024
- return { modified: false };
8025
- } else {
8026
- return { modified: false };
8081
+ while (i <= nextEnd) {
8082
+ liveList.insert(deepLiveify(next[i]), i);
8083
+ i++;
8027
8084
  }
8028
- const thisId = nn(this._id);
8029
- const previousValue = this.#map.get(key);
8030
- let reverse;
8031
- if (isLiveNode(previousValue)) {
8085
+ let localI = i;
8086
+ while (localI <= prevEnd) {
8087
+ liveList.delete(i);
8088
+ localI++;
8089
+ }
8090
+ }
8091
+ }
8092
+ function legacy_patchLiveObjectKey(liveObject, key, prev, next) {
8093
+ if (process.env.NODE_ENV !== "production") {
8094
+ const nonSerializableValue = findNonSerializableValue(next);
8095
+ if (nonSerializableValue) {
8096
+ error2(
8097
+ `New state path: '${nonSerializableValue.path}' value: '${String(
8098
+ nonSerializableValue.value
8099
+ )}' is not serializable.
8100
+ Only serializable value can be synced with Liveblocks.`
8101
+ );
8102
+ return;
8103
+ }
8104
+ }
8105
+ const value = liveObject.get(key);
8106
+ if (next === void 0) {
8107
+ liveObject.delete(key);
8108
+ } else if (value === void 0) {
8109
+ liveObject.set(key, deepLiveify(next));
8110
+ } else if (prev === next) {
8111
+ return;
8112
+ } else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
8113
+ legacy_patchLiveList(value, prev, next);
8114
+ } else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
8115
+ legacy_patchLiveObject(value, prev, next);
8116
+ } else {
8117
+ liveObject.set(key, deepLiveify(next));
8118
+ }
8119
+ }
8120
+ function legacy_patchLiveObject(root, prev, next) {
8121
+ const updates = {};
8122
+ for (const key in next) {
8123
+ legacy_patchLiveObjectKey(root, key, prev[key], next[key]);
8124
+ }
8125
+ for (const key in prev) {
8126
+ if (next[key] === void 0) {
8127
+ root.delete(key);
8128
+ }
8129
+ }
8130
+ if (Object.keys(updates).length > 0) {
8131
+ root.update(updates);
8132
+ }
8133
+ }
8134
+ function getParentsPath(node) {
8135
+ const path = [];
8136
+ while (node.parent.type === "HasParent") {
8137
+ if (isLiveList(node.parent.node)) {
8138
+ path.push(node.parent.node._indexOfPosition(node.parent.key));
8139
+ } else {
8140
+ path.push(node.parent.key);
8141
+ }
8142
+ node = node.parent.node;
8143
+ }
8144
+ return path;
8145
+ }
8146
+ function legacy_patchImmutableObject(state, updates) {
8147
+ return updates.reduce(
8148
+ (state2, update) => legacy_patchImmutableObjectWithUpdate(state2, update),
8149
+ state
8150
+ );
8151
+ }
8152
+ function legacy_patchImmutableObjectWithUpdate(state, update) {
8153
+ const path = getParentsPath(update.node);
8154
+ return legacy_patchImmutableNode(state, path, update);
8155
+ }
8156
+ function legacy_patchImmutableNode(state, path, update) {
8157
+ const pathItem = path.pop();
8158
+ if (pathItem === void 0) {
8159
+ switch (update.type) {
8160
+ case "LiveObject": {
8161
+ if (!isJsonObject(state)) {
8162
+ throw new Error(
8163
+ "Internal: received update on LiveObject but state was not an object"
8164
+ );
8165
+ }
8166
+ const newState = Object.assign({}, state);
8167
+ for (const key in update.updates) {
8168
+ if (_optionalChain([update, 'access', _192 => _192.updates, 'access', _193 => _193[key], 'optionalAccess', _194 => _194.type]) === "update") {
8169
+ const val = update.node.get(key);
8170
+ if (val !== void 0) {
8171
+ newState[key] = lsonToJson(val);
8172
+ }
8173
+ } else if (_optionalChain([update, 'access', _195 => _195.updates, 'access', _196 => _196[key], 'optionalAccess', _197 => _197.type]) === "delete") {
8174
+ delete newState[key];
8175
+ }
8176
+ }
8177
+ return newState;
8178
+ }
8179
+ case "LiveList": {
8180
+ if (!Array.isArray(state)) {
8181
+ throw new Error(
8182
+ "Internal: received update on LiveList but state was not an array"
8183
+ );
8184
+ }
8185
+ let newState = state.map((x) => x);
8186
+ for (const listUpdate of update.updates) {
8187
+ if (listUpdate.type === "set") {
8188
+ newState = newState.map(
8189
+ (item, index) => index === listUpdate.index ? lsonToJson(listUpdate.item) : item
8190
+ );
8191
+ } else if (listUpdate.type === "insert") {
8192
+ if (listUpdate.index === newState.length) {
8193
+ newState.push(lsonToJson(listUpdate.item));
8194
+ } else {
8195
+ newState = [
8196
+ ...newState.slice(0, listUpdate.index),
8197
+ lsonToJson(listUpdate.item),
8198
+ ...newState.slice(listUpdate.index)
8199
+ ];
8200
+ }
8201
+ } else if (listUpdate.type === "delete") {
8202
+ newState.splice(listUpdate.index, 1);
8203
+ } else if (listUpdate.type === "move") {
8204
+ if (listUpdate.previousIndex > listUpdate.index) {
8205
+ newState = [
8206
+ ...newState.slice(0, listUpdate.index),
8207
+ lsonToJson(listUpdate.item),
8208
+ ...newState.slice(listUpdate.index, listUpdate.previousIndex),
8209
+ ...newState.slice(listUpdate.previousIndex + 1)
8210
+ ];
8211
+ } else {
8212
+ newState = [
8213
+ ...newState.slice(0, listUpdate.previousIndex),
8214
+ ...newState.slice(
8215
+ listUpdate.previousIndex + 1,
8216
+ listUpdate.index + 1
8217
+ ),
8218
+ lsonToJson(listUpdate.item),
8219
+ ...newState.slice(listUpdate.index + 1)
8220
+ ];
8221
+ }
8222
+ }
8223
+ }
8224
+ return newState;
8225
+ }
8226
+ case "LiveMap": {
8227
+ if (!isJsonObject(state)) {
8228
+ throw new Error(
8229
+ "Internal: received update on LiveMap but state was not an object"
8230
+ );
8231
+ }
8232
+ const newState = Object.assign({}, state);
8233
+ for (const key in update.updates) {
8234
+ if (_optionalChain([update, 'access', _198 => _198.updates, 'access', _199 => _199[key], 'optionalAccess', _200 => _200.type]) === "update") {
8235
+ const value = update.node.get(key);
8236
+ if (value !== void 0) {
8237
+ newState[key] = lsonToJson(value);
8238
+ }
8239
+ } else if (_optionalChain([update, 'access', _201 => _201.updates, 'access', _202 => _202[key], 'optionalAccess', _203 => _203.type]) === "delete") {
8240
+ delete newState[key];
8241
+ }
8242
+ }
8243
+ return newState;
8244
+ }
8245
+ }
8246
+ }
8247
+ if (Array.isArray(state)) {
8248
+ const newArray = [...state];
8249
+ newArray[pathItem] = legacy_patchImmutableNode(
8250
+ state[pathItem],
8251
+ path,
8252
+ update
8253
+ );
8254
+ return newArray;
8255
+ } else if (isJsonObject(state)) {
8256
+ const node = state[pathItem];
8257
+ if (node === void 0) {
8258
+ return state;
8259
+ } else {
8260
+ const stateAsObj = state;
8261
+ return {
8262
+ ...stateAsObj,
8263
+ [pathItem]: legacy_patchImmutableNode(node, path, update)
8264
+ };
8265
+ }
8266
+ } else {
8267
+ return state;
8268
+ }
8269
+ }
8270
+
8271
+ // src/crdts/LiveObject.ts
8272
+ var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
8273
+ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8274
+ #synced;
8275
+ #local = /* @__PURE__ */ new Map();
8276
+ /**
8277
+ * Tracks unacknowledged local changes per property to preserve optimistic
8278
+ * updates. Maps property keys to their pending operation IDs.
8279
+ *
8280
+ * INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
8281
+ * are only compared against (to detect ACKs), never stored.
8282
+ *
8283
+ * When a local change is made, the opId is stored here. When a remote op
8284
+ * arrives for the same key:
8285
+ * - If no entry exists → apply remote op
8286
+ * - If opId matches → it's an ACK, clear the entry
8287
+ * - If opId differs → ignore remote op to preserve optimistic update
8288
+ */
8289
+ #unackedOpsByKey;
8290
+ /**
8291
+ * Enable or disable detection of too large LiveObjects.
8292
+ * When enabled, throws an error if LiveObject static data exceeds 128KB, which
8293
+ * is the maximum value the server will be able to accept.
8294
+ * By default, this behavior is disabled to avoid the runtime performance
8295
+ * overhead on every LiveObject.set() or LiveObject.update() call.
8296
+ *
8297
+ * @experimental
8298
+ */
8299
+ static __initStatic() {this.detectLargeObjects = false}
8300
+ static #buildRootAndParentToChildren(nodes) {
8301
+ const parentToChildren = /* @__PURE__ */ new Map();
8302
+ let root = null;
8303
+ for (const node of nodes) {
8304
+ if (isRootStorageNode(node)) {
8305
+ root = node[1];
8306
+ } else {
8307
+ const crdt = node[1];
8308
+ const children = parentToChildren.get(crdt.parentId);
8309
+ if (children !== void 0) {
8310
+ children.push(node);
8311
+ } else {
8312
+ parentToChildren.set(crdt.parentId, [node]);
8313
+ }
8314
+ }
8315
+ }
8316
+ if (root === null) {
8317
+ throw new Error("Root can't be null");
8318
+ }
8319
+ return [root, parentToChildren];
8320
+ }
8321
+ /** @private Do not use this API directly */
8322
+ static _fromItems(nodes, pool) {
8323
+ const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(nodes);
8324
+ return _LiveObject._deserialize(
8325
+ ["root", root],
8326
+ parentToChildren,
8327
+ pool
8328
+ );
8329
+ }
8330
+ constructor(obj = {}) {
8331
+ super();
8332
+ this.#unackedOpsByKey = /* @__PURE__ */ new Map();
8333
+ const o = compactObject(obj);
8334
+ for (const key of Object.keys(o)) {
8335
+ const value = o[key];
8336
+ if (isLiveNode(value)) {
8337
+ value._setParentLink(this, key);
8338
+ }
8339
+ }
8340
+ this.#synced = new Map(Object.entries(o));
8341
+ }
8342
+ /** @internal */
8343
+ _toOps(parentId, parentKey) {
8344
+ if (this._id === void 0) {
8345
+ throw new Error("Cannot serialize item is not attached");
8346
+ }
8347
+ const ops = [];
8348
+ const op = {
8349
+ type: OpCode.CREATE_OBJECT,
8350
+ id: this._id,
8351
+ parentId,
8352
+ parentKey,
8353
+ data: {}
8354
+ };
8355
+ ops.push(op);
8356
+ for (const [key, value] of this.#synced) {
8357
+ if (isLiveNode(value)) {
8358
+ for (const childOp of value._toOps(this._id, key)) {
8359
+ ops.push(childOp);
8360
+ }
8361
+ } else {
8362
+ op.data[key] = value;
8363
+ }
8364
+ }
8365
+ return ops;
8366
+ }
8367
+ /** @internal */
8368
+ static _deserialize([id, item], parentToChildren, pool) {
8369
+ const liveObj = new _LiveObject(item.data);
8370
+ liveObj._attach(id, pool);
8371
+ return this._deserializeChildren(liveObj, parentToChildren, pool);
8372
+ }
8373
+ /** @internal */
8374
+ static _deserializeChildren(liveObj, parentToChildren, pool) {
8375
+ const children = parentToChildren.get(nn(liveObj._id));
8376
+ if (children === void 0) {
8377
+ return liveObj;
8378
+ }
8379
+ for (const node of children) {
8380
+ const child = deserializeToLson(node, parentToChildren, pool);
8381
+ const crdt = node[1];
8382
+ if (isLiveStructure(child)) {
8383
+ child._setParentLink(liveObj, crdt.parentKey);
8384
+ }
8385
+ liveObj.#synced.set(crdt.parentKey, child);
8386
+ liveObj.invalidate();
8387
+ }
8388
+ return liveObj;
8389
+ }
8390
+ /** @internal */
8391
+ _attach(id, pool) {
8392
+ super._attach(id, pool);
8393
+ for (const [_key, value] of this.#synced) {
8394
+ if (isLiveNode(value)) {
8395
+ value._attach(pool.generateId(), pool);
8396
+ }
8397
+ }
8398
+ }
8399
+ /** @internal */
8400
+ _attachChild(op, source) {
8401
+ if (this._pool === void 0) {
8402
+ throw new Error("Can't attach child if managed pool is not present");
8403
+ }
8404
+ const { id, opId, parentKey: key } = op;
8405
+ const child = creationOpToLson(op);
8406
+ if (this._pool.getNode(id) !== void 0) {
8407
+ if (this.#unackedOpsByKey.get(key) === opId) {
8408
+ this.#unackedOpsByKey.delete(key);
8409
+ }
8410
+ return { modified: false };
8411
+ }
8412
+ if (source === 0 /* LOCAL */) {
8413
+ this.#unackedOpsByKey.set(key, nn(opId));
8414
+ } else if (this.#unackedOpsByKey.get(key) === void 0) {
8415
+ } else if (this.#unackedOpsByKey.get(key) === opId) {
8416
+ this.#unackedOpsByKey.delete(key);
8417
+ return { modified: false };
8418
+ } else {
8419
+ return { modified: false };
8420
+ }
8421
+ const thisId = nn(this._id);
8422
+ const previousValue = this.#synced.get(key);
8423
+ let reverse;
8424
+ if (isLiveNode(previousValue)) {
8032
8425
  reverse = previousValue._toOps(thisId, key);
8033
8426
  previousValue._detach();
8034
8427
  } else if (previousValue === void 0) {
@@ -8042,7 +8435,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8042
8435
  }
8043
8436
  ];
8044
8437
  }
8045
- this.#map.set(key, child);
8438
+ this.#local.delete(key);
8439
+ this.#synced.set(key, child);
8046
8440
  this.invalidate();
8047
8441
  if (isLiveStructure(child)) {
8048
8442
  child._setParentLink(this, key);
@@ -8063,9 +8457,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8063
8457
  const id = nn(this._id);
8064
8458
  const parentKey = nn(child._parentKey);
8065
8459
  const reverse = child._toOps(id, parentKey);
8066
- for (const [key, value] of this.#map) {
8460
+ for (const [key, value] of this.#synced) {
8067
8461
  if (value === child) {
8068
- this.#map.delete(key);
8462
+ this.#synced.delete(key);
8069
8463
  this.invalidate();
8070
8464
  }
8071
8465
  }
@@ -8084,7 +8478,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8084
8478
  /** @internal */
8085
8479
  _detach() {
8086
8480
  super._detach();
8087
- for (const value of this.#map.values()) {
8481
+ for (const value of this.#synced.values()) {
8088
8482
  if (isLiveNode(value)) {
8089
8483
  value._detach();
8090
8484
  }
@@ -8102,7 +8496,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8102
8496
  /** @internal */
8103
8497
  _serialize() {
8104
8498
  const data = {};
8105
- for (const [key, value] of this.#map) {
8499
+ for (const [key, value] of this.#synced) {
8106
8500
  if (!isLiveNode(value)) {
8107
8501
  data[key] = value;
8108
8502
  }
@@ -8131,7 +8525,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8131
8525
  data: {}
8132
8526
  };
8133
8527
  for (const key in op.data) {
8134
- const oldValue = this.#map.get(key);
8528
+ const oldValue = this.#synced.get(key);
8135
8529
  if (isLiveNode(oldValue)) {
8136
8530
  for (const childOp of oldValue._toOps(id, key)) {
8137
8531
  reverse.push(childOp);
@@ -8159,13 +8553,14 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8159
8553
  } else {
8160
8554
  continue;
8161
8555
  }
8162
- const oldValue = this.#map.get(key);
8556
+ const oldValue = this.#synced.get(key);
8163
8557
  if (isLiveNode(oldValue)) {
8164
8558
  oldValue._detach();
8165
8559
  }
8166
8560
  isModified = true;
8167
8561
  updateDelta[key] = { type: "update" };
8168
- this.#map.set(key, value);
8562
+ this.#local.delete(key);
8563
+ this.#synced.set(key, value);
8169
8564
  this.invalidate();
8170
8565
  }
8171
8566
  if (Object.keys(reverseUpdate.data).length !== 0) {
@@ -8182,7 +8577,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8182
8577
  }
8183
8578
  #applyDeleteObjectKey(op, isLocal) {
8184
8579
  const key = op.key;
8185
- const oldValue = this.#map.get(key);
8580
+ const oldValue = this.#synced.get(key);
8186
8581
  if (oldValue === void 0) {
8187
8582
  return { modified: false };
8188
8583
  }
@@ -8203,7 +8598,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8203
8598
  }
8204
8599
  ];
8205
8600
  }
8206
- this.#map.delete(key);
8601
+ this.#local.delete(key);
8602
+ this.#synced.delete(key);
8207
8603
  this.invalidate();
8208
8604
  return {
8209
8605
  modified: {
@@ -8216,11 +8612,23 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8216
8612
  reverse
8217
8613
  };
8218
8614
  }
8615
+ /** @private */
8616
+ keys() {
8617
+ const result = new Set(this.#synced.keys());
8618
+ for (const key of this.#local.keys()) {
8619
+ result.add(key);
8620
+ }
8621
+ return result;
8622
+ }
8219
8623
  /**
8220
8624
  * Transform the LiveObject into a javascript object
8221
8625
  */
8222
8626
  toObject() {
8223
- return Object.fromEntries(this.#map);
8627
+ const result = Object.fromEntries(this.#synced);
8628
+ for (const [key, value] of this.#local) {
8629
+ result[key] = value;
8630
+ }
8631
+ return result;
8224
8632
  }
8225
8633
  /**
8226
8634
  * Adds or updates a property with a specified key and a value.
@@ -8228,49 +8636,109 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8228
8636
  * @param value The value of the property to add
8229
8637
  */
8230
8638
  set(key, value) {
8231
- _optionalChain([this, 'access', _192 => _192._pool, 'optionalAccess', _193 => _193.assertStorageIsWritable, 'call', _194 => _194()]);
8232
8639
  this.update({ [key]: value });
8233
8640
  }
8641
+ /**
8642
+ * @experimental
8643
+ *
8644
+ * Sets a local-only property that is not synchronized over the wire.
8645
+ * The value will be visible via get(), toObject(), and toImmutable() on
8646
+ * this client only. Other clients and the server will see `undefined`
8647
+ * for this key.
8648
+ *
8649
+ * Caveat: this method will not add changes to the undo/redo stack.
8650
+ */
8651
+ setLocal(key, value) {
8652
+ _optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
8653
+ const deleteResult = this.#prepareDelete(key);
8654
+ this.#local.set(key, value);
8655
+ this.invalidate();
8656
+ if (this._pool !== void 0 && this._id !== void 0) {
8657
+ const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _207 => _207[0]]), () => ( []));
8658
+ const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _208 => _208[1]]), () => ( []));
8659
+ const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _209 => _209[2]]), () => ( /* @__PURE__ */ new Map()));
8660
+ const existing = storageUpdates.get(this._id);
8661
+ storageUpdates.set(this._id, {
8662
+ node: this,
8663
+ type: "LiveObject",
8664
+ updates: {
8665
+ ..._optionalChain([existing, 'optionalAccess', _210 => _210.updates]),
8666
+ [key]: { type: "update" }
8667
+ }
8668
+ });
8669
+ this._pool.dispatch(ops, reverse, storageUpdates);
8670
+ }
8671
+ }
8234
8672
  /**
8235
8673
  * Returns a specified property from the LiveObject.
8236
8674
  * @param key The key of the property to get
8237
8675
  */
8238
8676
  get(key) {
8239
- return this.#map.get(key);
8677
+ return this.#local.has(key) ? this.#local.get(key) : this.#synced.get(key);
8240
8678
  }
8241
8679
  /**
8242
- * Deletes a key from the LiveObject
8243
- * @param key The key of the property to delete
8680
+ * Removes a synced key, returning the ops, reverse ops, and storage updates
8681
+ * needed to notify the pool. Returns null if the key doesn't exist in
8682
+ * #synced or pool/id are unavailable. Does NOT dispatch.
8244
8683
  */
8245
- delete(key) {
8246
- _optionalChain([this, 'access', _195 => _195._pool, 'optionalAccess', _196 => _196.assertStorageIsWritable, 'call', _197 => _197()]);
8247
- const keyAsString = key;
8248
- const oldValue = this.#map.get(keyAsString);
8684
+ #prepareDelete(key) {
8685
+ _optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.assertStorageIsWritable, 'call', _213 => _213()]);
8686
+ const k = key;
8687
+ if (this.#local.has(k) && !this.#synced.has(k)) {
8688
+ const oldValue2 = this.#local.get(k);
8689
+ this.#local.delete(k);
8690
+ this.invalidate();
8691
+ if (this._pool !== void 0 && this._id !== void 0) {
8692
+ const storageUpdates2 = /* @__PURE__ */ new Map();
8693
+ storageUpdates2.set(this._id, {
8694
+ node: this,
8695
+ type: "LiveObject",
8696
+ updates: {
8697
+ [k]: {
8698
+ type: "delete",
8699
+ deletedItem: oldValue2
8700
+ }
8701
+ }
8702
+ });
8703
+ return [[], [], storageUpdates2];
8704
+ }
8705
+ return null;
8706
+ }
8707
+ this.#local.delete(k);
8708
+ const oldValue = this.#synced.get(k);
8249
8709
  if (oldValue === void 0) {
8250
- return;
8710
+ return null;
8251
8711
  }
8252
8712
  if (this._pool === void 0 || this._id === void 0) {
8253
8713
  if (isLiveNode(oldValue)) {
8254
8714
  oldValue._detach();
8255
8715
  }
8256
- this.#map.delete(keyAsString);
8716
+ this.#synced.delete(k);
8257
8717
  this.invalidate();
8258
- return;
8718
+ return null;
8259
8719
  }
8720
+ const ops = [
8721
+ {
8722
+ type: OpCode.DELETE_OBJECT_KEY,
8723
+ key: k,
8724
+ id: this._id,
8725
+ opId: this._pool.generateOpId()
8726
+ }
8727
+ ];
8260
8728
  let reverse;
8261
8729
  if (isLiveNode(oldValue)) {
8262
8730
  oldValue._detach();
8263
- reverse = oldValue._toOps(this._id, keyAsString);
8731
+ reverse = oldValue._toOps(this._id, k);
8264
8732
  } else {
8265
8733
  reverse = [
8266
8734
  {
8267
8735
  type: OpCode.UPDATE_OBJECT,
8268
- data: { [keyAsString]: oldValue },
8736
+ data: { [k]: oldValue },
8269
8737
  id: this._id
8270
8738
  }
8271
8739
  ];
8272
8740
  }
8273
- this.#map.delete(keyAsString);
8741
+ this.#synced.delete(k);
8274
8742
  this.invalidate();
8275
8743
  const storageUpdates = /* @__PURE__ */ new Map();
8276
8744
  storageUpdates.set(this._id, {
@@ -8280,28 +8748,28 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8280
8748
  [key]: { type: "delete", deletedItem: oldValue }
8281
8749
  }
8282
8750
  });
8283
- this._pool.dispatch(
8284
- [
8285
- {
8286
- type: OpCode.DELETE_OBJECT_KEY,
8287
- key: keyAsString,
8288
- id: this._id,
8289
- opId: this._pool.generateOpId()
8290
- }
8291
- ],
8292
- reverse,
8293
- storageUpdates
8294
- );
8751
+ return [ops, reverse, storageUpdates];
8752
+ }
8753
+ /**
8754
+ * Deletes a key from the LiveObject
8755
+ * @param key The key of the property to delete
8756
+ */
8757
+ delete(key) {
8758
+ const result = this.#prepareDelete(key);
8759
+ if (result) {
8760
+ const [ops, reverse, storageUpdates] = result;
8761
+ _optionalChain([this, 'access', _214 => _214._pool, 'optionalAccess', _215 => _215.dispatch, 'call', _216 => _216(ops, reverse, storageUpdates)]);
8762
+ }
8295
8763
  }
8296
8764
  /**
8297
8765
  * Adds or updates multiple properties at once with an object.
8298
8766
  * @param patch The object used to overrides properties
8299
8767
  */
8300
8768
  update(patch) {
8301
- _optionalChain([this, 'access', _198 => _198._pool, 'optionalAccess', _199 => _199.assertStorageIsWritable, 'call', _200 => _200()]);
8769
+ _optionalChain([this, 'access', _217 => _217._pool, 'optionalAccess', _218 => _218.assertStorageIsWritable, 'call', _219 => _219()]);
8302
8770
  if (_LiveObject.detectLargeObjects) {
8303
8771
  const data = {};
8304
- for (const [key, value] of this.#map) {
8772
+ for (const [key, value] of this.#synced) {
8305
8773
  if (!isLiveNode(value)) {
8306
8774
  data[key] = value;
8307
8775
  }
@@ -8330,14 +8798,15 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8330
8798
  if (newValue === void 0) {
8331
8799
  continue;
8332
8800
  }
8333
- const oldValue = this.#map.get(key);
8801
+ const oldValue = this.#synced.get(key);
8334
8802
  if (isLiveNode(oldValue)) {
8335
8803
  oldValue._detach();
8336
8804
  }
8337
8805
  if (isLiveNode(newValue)) {
8338
8806
  newValue._setParentLink(this, key);
8339
8807
  }
8340
- this.#map.set(key, newValue);
8808
+ this.#local.delete(key);
8809
+ this.#synced.set(key, newValue);
8341
8810
  this.invalidate();
8342
8811
  }
8343
8812
  return;
@@ -8357,7 +8826,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8357
8826
  if (newValue === void 0) {
8358
8827
  continue;
8359
8828
  }
8360
- const oldValue = this.#map.get(key);
8829
+ const oldValue = this.#synced.get(key);
8361
8830
  if (isLiveNode(oldValue)) {
8362
8831
  for (const childOp of oldValue._toOps(this._id, key)) {
8363
8832
  reverseOps.push(childOp);
@@ -8389,7 +8858,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8389
8858
  updatedProps[key] = newValue;
8390
8859
  this.#unackedOpsByKey.set(key, opId);
8391
8860
  }
8392
- this.#map.set(key, newValue);
8861
+ this.#local.delete(key);
8862
+ this.#synced.set(key, newValue);
8393
8863
  this.invalidate();
8394
8864
  updateDelta[key] = { type: "update" };
8395
8865
  }
@@ -8412,6 +8882,19 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8412
8882
  });
8413
8883
  this._pool.dispatch(ops, reverseOps, storageUpdates);
8414
8884
  }
8885
+ /**
8886
+ * Reconciles a LiveObject tree to match the given JSON object and sync
8887
+ * config. Only mutates keys that actually changed. Recursively reconciles
8888
+ * the entire Live tree below it.
8889
+ */
8890
+ reconcile(jsonObj, config) {
8891
+ if (this.immutableIs(jsonObj)) return;
8892
+ if (!isPlainObject(jsonObj))
8893
+ throw new Error(
8894
+ "Reconciling the document root expects a plain object value"
8895
+ );
8896
+ reconcileLiveObject(this, jsonObj, config);
8897
+ }
8415
8898
  toImmutable() {
8416
8899
  return super.toImmutable();
8417
8900
  }
@@ -8426,7 +8909,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8426
8909
  type: "LiveObject",
8427
8910
  id: nodeId,
8428
8911
  key,
8429
- payload: Array.from(this.#map.entries()).map(
8912
+ payload: Array.from(this.#synced.entries()).map(
8430
8913
  ([key2, value]) => isLiveNode(value) ? value.toTreeNode(key2) : { type: "Json", id: `${nodeId}:${key2}`, key: key2, payload: value }
8431
8914
  )
8432
8915
  };
@@ -8434,20 +8917,27 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8434
8917
  /** @internal */
8435
8918
  _toImmutable() {
8436
8919
  const result = {};
8437
- for (const [key, val] of this.#map) {
8920
+ for (const [key, val] of this.#synced) {
8438
8921
  result[key] = isLiveStructure(val) ? val.toImmutable() : val;
8439
8922
  }
8923
+ for (const [key, val] of this.#local) {
8924
+ result[key] = val;
8925
+ }
8440
8926
  return process.env.NODE_ENV === "production" ? result : Object.freeze(result);
8441
8927
  }
8442
8928
  clone() {
8443
- return new _LiveObject(
8929
+ const cloned = new _LiveObject(
8444
8930
  Object.fromEntries(
8445
- Array.from(this.#map).map(([key, value]) => [
8931
+ Array.from(this.#synced).map(([key, value]) => [
8446
8932
  key,
8447
8933
  isLiveStructure(value) ? value.clone() : deepClone(value)
8448
8934
  ])
8449
8935
  )
8450
8936
  );
8937
+ for (const [key, value] of this.#local) {
8938
+ cloned.#local.set(key, deepClone(value));
8939
+ }
8940
+ return cloned;
8451
8941
  }
8452
8942
  }, _class2.__initStatic(), _class2);
8453
8943
 
@@ -8747,17 +9237,6 @@ var Deque = class {
8747
9237
  }
8748
9238
  };
8749
9239
 
8750
- // src/lib/Json.ts
8751
- function isJsonScalar(data) {
8752
- return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
8753
- }
8754
- function isJsonArray(data) {
8755
- return Array.isArray(data);
8756
- }
8757
- function isJsonObject(data) {
8758
- return !isJsonScalar(data) && !isJsonArray(data);
8759
- }
8760
-
8761
9240
  // src/lib/stopwatch.ts
8762
9241
  function makeStopWatch() {
8763
9242
  let startTime = 0;
@@ -8791,16 +9270,7 @@ var ClientMsgCode = Object.freeze({
8791
9270
  UPDATE_STORAGE: 201,
8792
9271
  // For Yjs support
8793
9272
  FETCH_YDOC: 300,
8794
- UPDATE_YDOC: 301,
8795
- // For Feeds
8796
- FETCH_FEEDS: 510,
8797
- FETCH_FEED_MESSAGES: 511,
8798
- ADD_FEED: 512,
8799
- UPDATE_FEED: 513,
8800
- DELETE_FEED: 514,
8801
- ADD_FEED_MESSAGE: 515,
8802
- UPDATE_FEED_MESSAGE: 516,
8803
- DELETE_FEED_MESSAGE: 517
9273
+ UPDATE_YDOC: 301
8804
9274
  });
8805
9275
 
8806
9276
  // src/refs/ManagedOthers.ts
@@ -9036,15 +9506,12 @@ function defaultMessageFromContext(context) {
9036
9506
  return "Could not update notification settings";
9037
9507
  case "LARGE_MESSAGE_ERROR":
9038
9508
  return "Could not send large message";
9039
- case "FEED_REQUEST_ERROR":
9040
- return _nullishCoalesce(context.reason, () => ( "Feed request failed"));
9041
9509
  default:
9042
9510
  return assertNever(context, "Unhandled case");
9043
9511
  }
9044
9512
  }
9045
9513
 
9046
9514
  // src/room.ts
9047
- var FEEDS_TIMEOUT = 5e3;
9048
9515
  function makeIdFactory(connectionId) {
9049
9516
  let count = 0;
9050
9517
  return () => `${connectionId}:${count++}`;
@@ -9067,15 +9534,15 @@ function installBackgroundTabSpy() {
9067
9534
  const doc = typeof document !== "undefined" ? document : void 0;
9068
9535
  const inBackgroundSince = { current: null };
9069
9536
  function onVisibilityChange() {
9070
- if (_optionalChain([doc, 'optionalAccess', _201 => _201.visibilityState]) === "hidden") {
9537
+ if (_optionalChain([doc, 'optionalAccess', _220 => _220.visibilityState]) === "hidden") {
9071
9538
  inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
9072
9539
  } else {
9073
9540
  inBackgroundSince.current = null;
9074
9541
  }
9075
9542
  }
9076
- _optionalChain([doc, 'optionalAccess', _202 => _202.addEventListener, 'call', _203 => _203("visibilitychange", onVisibilityChange)]);
9543
+ _optionalChain([doc, 'optionalAccess', _221 => _221.addEventListener, 'call', _222 => _222("visibilitychange", onVisibilityChange)]);
9077
9544
  const unsub = () => {
9078
- _optionalChain([doc, 'optionalAccess', _204 => _204.removeEventListener, 'call', _205 => _205("visibilitychange", onVisibilityChange)]);
9545
+ _optionalChain([doc, 'optionalAccess', _223 => _223.removeEventListener, 'call', _224 => _224("visibilitychange", onVisibilityChange)]);
9079
9546
  };
9080
9547
  return [inBackgroundSince, unsub];
9081
9548
  }
@@ -9255,14 +9722,18 @@ function createRoom(options, config) {
9255
9722
  }
9256
9723
  context.activeBatch.reverseOps.pushLeft(reverse);
9257
9724
  } else {
9258
- addToUndoStack(reverse);
9259
- context.redoStack.length = 0;
9260
- dispatchOps(ops);
9725
+ if (reverse.length > 0) {
9726
+ addToUndoStack(reverse);
9727
+ }
9728
+ if (ops.length > 0) {
9729
+ context.redoStack.length = 0;
9730
+ dispatchOps(ops);
9731
+ }
9261
9732
  notify({ storageUpdates });
9262
9733
  }
9263
9734
  }
9264
9735
  function isStorageWritable() {
9265
- const scopes = _optionalChain([context, 'access', _206 => _206.dynamicSessionInfoSig, 'access', _207 => _207.get, 'call', _208 => _208(), 'optionalAccess', _209 => _209.scopes]);
9736
+ const scopes = _optionalChain([context, 'access', _225 => _225.dynamicSessionInfoSig, 'access', _226 => _226.get, 'call', _227 => _227(), 'optionalAccess', _228 => _228.scopes]);
9266
9737
  return scopes !== void 0 ? canWriteStorage(scopes) : true;
9267
9738
  }
9268
9739
  const eventHub = {
@@ -9279,7 +9750,6 @@ function createRoom(options, config) {
9279
9750
  storageStatus: makeEventSource(),
9280
9751
  ydoc: makeEventSource(),
9281
9752
  comments: makeEventSource(),
9282
- feeds: makeEventSource(),
9283
9753
  roomWillDestroy: makeEventSource()
9284
9754
  };
9285
9755
  async function createTextMention(mentionId, mention) {
@@ -9366,20 +9836,21 @@ function createRoom(options, config) {
9366
9836
  context.pool
9367
9837
  );
9368
9838
  }
9369
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _210 => _210.get, 'call', _211 => _211(), 'optionalAccess', _212 => _212.canWrite]), () => ( true));
9370
- const stackSizeBefore = context.undoStack.length;
9371
- for (const key in context.initialStorage) {
9372
- if (context.root.get(key) === void 0) {
9373
- if (canWrite) {
9374
- context.root.set(key, cloneLson(context.initialStorage[key]));
9375
- } else {
9376
- warn(
9377
- `Attempted to populate missing storage key '${key}', but current user has no write access`
9378
- );
9839
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _229 => _229.get, 'call', _230 => _230(), 'optionalAccess', _231 => _231.canWrite]), () => ( true));
9840
+ const root = context.root;
9841
+ withoutHistory(() => {
9842
+ for (const key in context.initialStorage) {
9843
+ if (root.get(key) === void 0) {
9844
+ if (canWrite) {
9845
+ root.set(key, cloneLson(context.initialStorage[key]));
9846
+ } else {
9847
+ warn(
9848
+ `Attempted to populate missing storage key '${key}', but current user has no write access`
9849
+ );
9850
+ }
9379
9851
  }
9380
9852
  }
9381
- }
9382
- context.undoStack.length = stackSizeBefore;
9853
+ });
9383
9854
  }
9384
9855
  function _addToRealUndoStack(frames) {
9385
9856
  if (context.undoStack.length >= 50) {
@@ -9570,7 +10041,7 @@ function createRoom(options, config) {
9570
10041
  }
9571
10042
  context.myPresence.patch(patch);
9572
10043
  if (context.activeBatch) {
9573
- if (_optionalChain([options2, 'optionalAccess', _213 => _213.addToHistory])) {
10044
+ if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
9574
10045
  context.activeBatch.reverseOps.pushLeft({
9575
10046
  type: "presence",
9576
10047
  data: oldValues
@@ -9579,7 +10050,7 @@ function createRoom(options, config) {
9579
10050
  context.activeBatch.updates.presence = true;
9580
10051
  } else {
9581
10052
  flushNowOrSoon();
9582
- if (_optionalChain([options2, 'optionalAccess', _214 => _214.addToHistory])) {
10053
+ if (_optionalChain([options2, 'optionalAccess', _233 => _233.addToHistory])) {
9583
10054
  addToUndoStack([{ type: "presence", data: oldValues }]);
9584
10055
  }
9585
10056
  notify({ presence: true });
@@ -9700,9 +10171,6 @@ function createRoom(options, config) {
9700
10171
  notify(result.updates);
9701
10172
  sendMessages(messages);
9702
10173
  }
9703
- function isFeedRequestFailedMsg(msg) {
9704
- return msg.type === ServerMsgCode.FEED_REQUEST_FAILED;
9705
- }
9706
10174
  function handleServerMessage(event) {
9707
10175
  if (typeof event.data !== "string") {
9708
10176
  return;
@@ -9756,11 +10224,11 @@ function createRoom(options, config) {
9756
10224
  break;
9757
10225
  }
9758
10226
  case ServerMsgCode.STORAGE_CHUNK:
9759
- _optionalChain([stopwatch, 'optionalAccess', _215 => _215.lap, 'call', _216 => _216()]);
10227
+ _optionalChain([stopwatch, 'optionalAccess', _234 => _234.lap, 'call', _235 => _235()]);
9760
10228
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
9761
10229
  break;
9762
10230
  case ServerMsgCode.STORAGE_STREAM_END: {
9763
- const timing = _optionalChain([stopwatch, 'optionalAccess', _217 => _217.stop, 'call', _218 => _218()]);
10231
+ const timing = _optionalChain([stopwatch, 'optionalAccess', _236 => _236.stop, 'call', _237 => _237()]);
9764
10232
  if (timing) {
9765
10233
  const ms = (v) => `${v.toFixed(1)}ms`;
9766
10234
  const rest = timing.laps.slice(1);
@@ -9816,94 +10284,6 @@ function createRoom(options, config) {
9816
10284
  eventHub.comments.notify(message);
9817
10285
  break;
9818
10286
  }
9819
- case ServerMsgCode.FEEDS_LIST: {
9820
- const feedsListMsg = message;
9821
- const pending = pendingFeedsRequests.get(feedsListMsg.requestId);
9822
- if (pending) {
9823
- pending.resolve({
9824
- feeds: feedsListMsg.feeds,
9825
- nextCursor: feedsListMsg.nextCursor
9826
- });
9827
- pendingFeedsRequests.delete(feedsListMsg.requestId);
9828
- }
9829
- eventHub.feeds.notify(feedsListMsg);
9830
- break;
9831
- }
9832
- case ServerMsgCode.FEEDS_ADDED: {
9833
- const feedsAddedMsg = message;
9834
- eventHub.feeds.notify(feedsAddedMsg);
9835
- tryResolvePendingFeedMutationsFromFeedsEvent(feedsAddedMsg);
9836
- break;
9837
- }
9838
- case ServerMsgCode.FEEDS_UPDATED: {
9839
- const feedsUpdatedMsg = message;
9840
- eventHub.feeds.notify(feedsUpdatedMsg);
9841
- tryResolvePendingFeedMutationsFromFeedsEvent(feedsUpdatedMsg);
9842
- break;
9843
- }
9844
- case ServerMsgCode.FEED_DELETED: {
9845
- eventHub.feeds.notify(message);
9846
- tryResolvePendingFeedMutationsFromFeedsEvent(message);
9847
- break;
9848
- }
9849
- case ServerMsgCode.FEED_MESSAGES_LIST: {
9850
- const feedMsgsListMsg = message;
9851
- const pending = pendingFeedMessagesRequests.get(
9852
- feedMsgsListMsg.requestId
9853
- );
9854
- if (pending) {
9855
- pending.resolve({
9856
- messages: feedMsgsListMsg.messages,
9857
- nextCursor: feedMsgsListMsg.nextCursor
9858
- });
9859
- pendingFeedMessagesRequests.delete(feedMsgsListMsg.requestId);
9860
- }
9861
- eventHub.feeds.notify(feedMsgsListMsg);
9862
- break;
9863
- }
9864
- case ServerMsgCode.FEED_MESSAGES_ADDED: {
9865
- const feedMsgsAddedMsg = message;
9866
- eventHub.feeds.notify(feedMsgsAddedMsg);
9867
- tryResolvePendingFeedMutationsFromFeedsEvent(feedMsgsAddedMsg);
9868
- break;
9869
- }
9870
- case ServerMsgCode.FEED_MESSAGES_UPDATED: {
9871
- const feedMsgsUpdatedMsg = message;
9872
- eventHub.feeds.notify(feedMsgsUpdatedMsg);
9873
- tryResolvePendingFeedMutationsFromFeedsEvent(feedMsgsUpdatedMsg);
9874
- break;
9875
- }
9876
- case ServerMsgCode.FEED_MESSAGES_DELETED: {
9877
- eventHub.feeds.notify(message);
9878
- tryResolvePendingFeedMutationsFromFeedsEvent(message);
9879
- break;
9880
- }
9881
- case ServerMsgCode.FEED_REQUEST_FAILED: {
9882
- if (!isFeedRequestFailedMsg(message)) {
9883
- break;
9884
- }
9885
- const { requestId, code, reason } = message;
9886
- const err = new LiveblocksError(_nullishCoalesce(reason, () => ( "Feed request failed")), {
9887
- type: "FEED_REQUEST_ERROR",
9888
- roomId,
9889
- requestId,
9890
- code,
9891
- reason
9892
- });
9893
- if (pendingFeedMutations.has(requestId)) {
9894
- settleFeedMutation(requestId, "error", err);
9895
- } else if (pendingFeedsRequests.has(requestId)) {
9896
- const pending = pendingFeedsRequests.get(requestId);
9897
- pendingFeedsRequests.delete(requestId);
9898
- _optionalChain([pending, 'optionalAccess', _219 => _219.reject, 'call', _220 => _220(err)]);
9899
- } else if (pendingFeedMessagesRequests.has(requestId)) {
9900
- const pending = pendingFeedMessagesRequests.get(requestId);
9901
- pendingFeedMessagesRequests.delete(requestId);
9902
- _optionalChain([pending, 'optionalAccess', _221 => _221.reject, 'call', _222 => _222(err)]);
9903
- }
9904
- eventHub.feeds.notify(message);
9905
- break;
9906
- }
9907
10287
  case ServerMsgCode.STORAGE_STATE_V7:
9908
10288
  // No longer used in V8
9909
10289
  default:
@@ -10007,146 +10387,11 @@ function createRoom(options, config) {
10007
10387
  }
10008
10388
  let _getStorage$ = null;
10009
10389
  let _resolveStoragePromise = null;
10010
- const pendingFeedsRequests = /* @__PURE__ */ new Map();
10011
- const pendingFeedMessagesRequests = /* @__PURE__ */ new Map();
10012
- const pendingFeedMutations = /* @__PURE__ */ new Map();
10013
- const pendingAddMessageFifoByFeed = /* @__PURE__ */ new Map();
10014
- function settleFeedMutation(requestId, outcome, error3) {
10015
- const pending = pendingFeedMutations.get(requestId);
10016
- if (pending === void 0) {
10017
- return;
10018
- }
10019
- clearTimeout(pending.timeoutId);
10020
- pendingFeedMutations.delete(requestId);
10021
- if (pending.kind === "add-message" && !pending.expectedClientMessageId) {
10022
- const q = pendingAddMessageFifoByFeed.get(pending.feedId);
10023
- if (q !== void 0) {
10024
- const idx = q.indexOf(requestId);
10025
- if (idx >= 0) {
10026
- q.splice(idx, 1);
10027
- }
10028
- if (q.length === 0) {
10029
- pendingAddMessageFifoByFeed.delete(pending.feedId);
10030
- }
10031
- }
10032
- }
10033
- if (outcome === "ok") {
10034
- pending.resolve();
10035
- } else {
10036
- pending.reject(_nullishCoalesce(error3, () => ( new Error("Feed mutation failed"))));
10037
- }
10038
- }
10039
- function registerFeedMutation(requestId, kind, feedId, options2) {
10040
- const { promise, resolve, reject } = Promise_withResolvers();
10041
- const timeoutId = setTimeout(() => {
10042
- if (pendingFeedMutations.has(requestId)) {
10043
- settleFeedMutation(
10044
- requestId,
10045
- "error",
10046
- new Error("Feed mutation timeout")
10047
- );
10048
- }
10049
- }, FEEDS_TIMEOUT);
10050
- pendingFeedMutations.set(requestId, {
10051
- resolve,
10052
- reject,
10053
- timeoutId,
10054
- kind,
10055
- feedId,
10056
- messageId: _optionalChain([options2, 'optionalAccess', _223 => _223.messageId]),
10057
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _224 => _224.expectedClientMessageId])
10058
- });
10059
- if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _225 => _225.expectedClientMessageId]) === void 0) {
10060
- const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
10061
- q.push(requestId);
10062
- pendingAddMessageFifoByFeed.set(feedId, q);
10063
- }
10064
- return promise;
10065
- }
10066
- function tryResolvePendingFeedMutationsFromFeedsEvent(message) {
10067
- switch (message.type) {
10068
- case ServerMsgCode.FEEDS_ADDED: {
10069
- for (const feed of message.feeds) {
10070
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10071
- if (pending.kind === "add-feed" && pending.feedId === feed.feedId) {
10072
- settleFeedMutation(requestId, "ok");
10073
- break;
10074
- }
10075
- }
10076
- }
10077
- break;
10078
- }
10079
- case ServerMsgCode.FEEDS_UPDATED: {
10080
- for (const feed of message.feeds) {
10081
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10082
- if (pending.kind === "update-feed" && pending.feedId === feed.feedId) {
10083
- settleFeedMutation(requestId, "ok");
10084
- }
10085
- }
10086
- }
10087
- break;
10088
- }
10089
- case ServerMsgCode.FEED_DELETED: {
10090
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10091
- if (pending.kind === "delete-feed" && pending.feedId === message.feedId) {
10092
- settleFeedMutation(requestId, "ok");
10093
- break;
10094
- }
10095
- }
10096
- break;
10097
- }
10098
- case ServerMsgCode.FEED_MESSAGES_ADDED: {
10099
- for (const m of message.messages) {
10100
- let matched = false;
10101
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10102
- if (pending.kind === "add-message" && pending.feedId === message.feedId && pending.expectedClientMessageId === m.id) {
10103
- settleFeedMutation(requestId, "ok");
10104
- matched = true;
10105
- break;
10106
- }
10107
- }
10108
- if (!matched) {
10109
- const q = pendingAddMessageFifoByFeed.get(message.feedId);
10110
- const headId = _optionalChain([q, 'optionalAccess', _226 => _226[0]]);
10111
- if (headId !== void 0) {
10112
- const pending = pendingFeedMutations.get(headId);
10113
- if (_optionalChain([pending, 'optionalAccess', _227 => _227.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10114
- settleFeedMutation(headId, "ok");
10115
- }
10116
- }
10117
- }
10118
- }
10119
- break;
10120
- }
10121
- case ServerMsgCode.FEED_MESSAGES_UPDATED: {
10122
- for (const m of message.messages) {
10123
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10124
- if (pending.kind === "update-message" && pending.feedId === message.feedId && pending.messageId === m.id) {
10125
- settleFeedMutation(requestId, "ok");
10126
- }
10127
- }
10128
- }
10129
- break;
10130
- }
10131
- case ServerMsgCode.FEED_MESSAGES_DELETED: {
10132
- for (const mid of message.messageIds) {
10133
- for (const [requestId, pending] of [...pendingFeedMutations]) {
10134
- if (pending.kind === "delete-message" && pending.feedId === message.feedId && pending.messageId === mid) {
10135
- settleFeedMutation(requestId, "ok");
10136
- }
10137
- }
10138
- }
10139
- break;
10140
- }
10141
- default:
10142
- break;
10143
- }
10144
- }
10145
10390
  function processInitialStorage(nodes) {
10146
10391
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
10147
10392
  createOrUpdateRootFromMessage(nodes);
10148
10393
  applyAndSendOfflineOps(unacknowledgedOps);
10149
- _optionalChain([_resolveStoragePromise, 'optionalCall', _228 => _228()]);
10394
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _238 => _238()]);
10150
10395
  notifyStorageStatus();
10151
10396
  eventHub.storageDidLoad.notify();
10152
10397
  }
@@ -10164,7 +10409,7 @@ function createRoom(options, config) {
10164
10409
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
10165
10410
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
10166
10411
  nodeMapBuffer.take();
10167
- _optionalChain([stopwatch, 'optionalAccess', _229 => _229.start, 'call', _230 => _230()]);
10412
+ _optionalChain([stopwatch, 'optionalAccess', _239 => _239.start, 'call', _240 => _240()]);
10168
10413
  }
10169
10414
  if (options2.flush) {
10170
10415
  flushNowOrSoon();
@@ -10189,161 +10434,29 @@ function createRoom(options, config) {
10189
10434
  return null;
10190
10435
  }
10191
10436
  }
10192
- async function getStorage() {
10193
- if (context.root !== void 0) {
10194
- return Promise.resolve({
10195
- root: context.root
10196
- });
10197
- }
10198
- await startLoadingStorage();
10199
- return {
10200
- root: nn(context.root)
10201
- };
10202
- }
10203
- function fetchYDoc(vector, guid, isV2) {
10204
- if (!context.buffer.messages.find((m) => {
10205
- return m.type === ClientMsgCode.FETCH_YDOC && m.vector === vector && m.guid === guid && m.v2 === isV2;
10206
- })) {
10207
- context.buffer.messages.push({
10208
- type: ClientMsgCode.FETCH_YDOC,
10209
- vector,
10210
- guid,
10211
- v2: isV2
10212
- });
10213
- }
10214
- flushNowOrSoon();
10215
- }
10216
- async function fetchFeeds(options2) {
10217
- const requestId = nanoid();
10218
- const { promise, resolve, reject } = Promise_withResolvers();
10219
- pendingFeedsRequests.set(requestId, { resolve, reject });
10220
- const message = {
10221
- type: ClientMsgCode.FETCH_FEEDS,
10222
- requestId,
10223
- cursor: _optionalChain([options2, 'optionalAccess', _231 => _231.cursor]),
10224
- since: _optionalChain([options2, 'optionalAccess', _232 => _232.since]),
10225
- limit: _optionalChain([options2, 'optionalAccess', _233 => _233.limit]),
10226
- metadata: _optionalChain([options2, 'optionalAccess', _234 => _234.metadata])
10227
- };
10228
- context.buffer.messages.push(message);
10229
- flushNowOrSoon();
10230
- setTimeout(() => {
10231
- if (pendingFeedsRequests.has(requestId)) {
10232
- pendingFeedsRequests.delete(requestId);
10233
- reject(new Error("Feeds fetch timeout"));
10234
- }
10235
- }, FEEDS_TIMEOUT);
10236
- return promise;
10237
- }
10238
- async function fetchFeedMessages(feedId, options2) {
10239
- const requestId = nanoid();
10240
- const { promise, resolve, reject } = Promise_withResolvers();
10241
- pendingFeedMessagesRequests.set(requestId, { resolve, reject });
10242
- const message = {
10243
- type: ClientMsgCode.FETCH_FEED_MESSAGES,
10244
- requestId,
10245
- feedId,
10246
- cursor: _optionalChain([options2, 'optionalAccess', _235 => _235.cursor]),
10247
- since: _optionalChain([options2, 'optionalAccess', _236 => _236.since]),
10248
- limit: _optionalChain([options2, 'optionalAccess', _237 => _237.limit])
10249
- };
10250
- context.buffer.messages.push(message);
10251
- flushNowOrSoon();
10252
- setTimeout(() => {
10253
- if (pendingFeedMessagesRequests.has(requestId)) {
10254
- pendingFeedMessagesRequests.delete(requestId);
10255
- reject(new Error("Feed messages fetch timeout"));
10256
- }
10257
- }, FEEDS_TIMEOUT);
10258
- return promise;
10259
- }
10260
- function addFeed(feedId, options2) {
10261
- const requestId = nanoid();
10262
- const promise = registerFeedMutation(requestId, "add-feed", feedId);
10263
- const message = {
10264
- type: ClientMsgCode.ADD_FEED,
10265
- requestId,
10266
- feedId,
10267
- metadata: _optionalChain([options2, 'optionalAccess', _238 => _238.metadata]),
10268
- createdAt: _optionalChain([options2, 'optionalAccess', _239 => _239.createdAt])
10269
- };
10270
- context.buffer.messages.push(message);
10271
- flushNowOrSoon();
10272
- return promise;
10273
- }
10274
- function updateFeed(feedId, metadata) {
10275
- const requestId = nanoid();
10276
- const promise = registerFeedMutation(requestId, "update-feed", feedId);
10277
- const message = {
10278
- type: ClientMsgCode.UPDATE_FEED,
10279
- requestId,
10280
- feedId,
10281
- metadata
10282
- };
10283
- context.buffer.messages.push(message);
10284
- flushNowOrSoon();
10285
- return promise;
10286
- }
10287
- function deleteFeed(feedId) {
10288
- const requestId = nanoid();
10289
- const promise = registerFeedMutation(requestId, "delete-feed", feedId);
10290
- const message = {
10291
- type: ClientMsgCode.DELETE_FEED,
10292
- requestId,
10293
- feedId
10294
- };
10295
- context.buffer.messages.push(message);
10296
- flushNowOrSoon();
10297
- return promise;
10298
- }
10299
- function addFeedMessage(feedId, data, options2) {
10300
- const requestId = nanoid();
10301
- const promise = registerFeedMutation(requestId, "add-message", feedId, {
10302
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _240 => _240.id])
10303
- });
10304
- const message = {
10305
- type: ClientMsgCode.ADD_FEED_MESSAGE,
10306
- requestId,
10307
- feedId,
10308
- data,
10309
- id: _optionalChain([options2, 'optionalAccess', _241 => _241.id]),
10310
- createdAt: _optionalChain([options2, 'optionalAccess', _242 => _242.createdAt])
10311
- };
10312
- context.buffer.messages.push(message);
10313
- flushNowOrSoon();
10314
- return promise;
10315
- }
10316
- function updateFeedMessage(feedId, messageId, data, options2) {
10317
- const requestId = nanoid();
10318
- const promise = registerFeedMutation(requestId, "update-message", feedId, {
10319
- messageId
10320
- });
10321
- const message = {
10322
- type: ClientMsgCode.UPDATE_FEED_MESSAGE,
10323
- requestId,
10324
- feedId,
10325
- messageId,
10326
- data,
10327
- updatedAt: _optionalChain([options2, 'optionalAccess', _243 => _243.updatedAt])
10437
+ async function getStorage() {
10438
+ if (context.root !== void 0) {
10439
+ return Promise.resolve({
10440
+ root: context.root
10441
+ });
10442
+ }
10443
+ await startLoadingStorage();
10444
+ return {
10445
+ root: nn(context.root)
10328
10446
  };
10329
- context.buffer.messages.push(message);
10330
- flushNowOrSoon();
10331
- return promise;
10332
10447
  }
10333
- function deleteFeedMessage(feedId, messageId) {
10334
- const requestId = nanoid();
10335
- const promise = registerFeedMutation(requestId, "delete-message", feedId, {
10336
- messageId
10337
- });
10338
- const message = {
10339
- type: ClientMsgCode.DELETE_FEED_MESSAGE,
10340
- requestId,
10341
- feedId,
10342
- messageId
10343
- };
10344
- context.buffer.messages.push(message);
10448
+ function fetchYDoc(vector, guid, isV2) {
10449
+ if (!context.buffer.messages.find((m) => {
10450
+ return m.type === ClientMsgCode.FETCH_YDOC && m.vector === vector && m.guid === guid && m.v2 === isV2;
10451
+ })) {
10452
+ context.buffer.messages.push({
10453
+ type: ClientMsgCode.FETCH_YDOC,
10454
+ vector,
10455
+ guid,
10456
+ v2: isV2
10457
+ });
10458
+ }
10345
10459
  flushNowOrSoon();
10346
- return promise;
10347
10460
  }
10348
10461
  function undo() {
10349
10462
  if (context.activeBatch) {
@@ -10430,6 +10543,16 @@ function createRoom(options, config) {
10430
10543
  _addToRealUndoStack(Array.from(frames));
10431
10544
  }
10432
10545
  }
10546
+ function withoutHistory(fn) {
10547
+ const undoBefore = context.undoStack.length;
10548
+ const redoBefore = context.redoStack.length;
10549
+ try {
10550
+ return fn();
10551
+ } finally {
10552
+ context.undoStack.length = undoBefore;
10553
+ context.redoStack.length = redoBefore;
10554
+ }
10555
+ }
10433
10556
  const syncSourceForStorage = config.createSyncSource();
10434
10557
  function getStorageStatus() {
10435
10558
  if (context.root === void 0) {
@@ -10487,7 +10610,6 @@ function createRoom(options, config) {
10487
10610
  storageStatus: eventHub.storageStatus.observable,
10488
10611
  ydoc: eventHub.ydoc.observable,
10489
10612
  comments: eventHub.comments.observable,
10490
- feeds: eventHub.feeds.observable,
10491
10613
  roomWillDestroy: eventHub.roomWillDestroy.observable
10492
10614
  };
10493
10615
  async function getThreadsSince(options2) {
@@ -10500,8 +10622,8 @@ function createRoom(options, config) {
10500
10622
  async function getThreads(options2) {
10501
10623
  return httpClient.getThreads({
10502
10624
  roomId,
10503
- query: _optionalChain([options2, 'optionalAccess', _244 => _244.query]),
10504
- cursor: _optionalChain([options2, 'optionalAccess', _245 => _245.cursor])
10625
+ query: _optionalChain([options2, 'optionalAccess', _241 => _241.query]),
10626
+ cursor: _optionalChain([options2, 'optionalAccess', _242 => _242.cursor])
10505
10627
  });
10506
10628
  }
10507
10629
  async function getThread(threadId) {
@@ -10623,7 +10745,7 @@ function createRoom(options, config) {
10623
10745
  function getSubscriptionSettings(options2) {
10624
10746
  return httpClient.getSubscriptionSettings({
10625
10747
  roomId,
10626
- signal: _optionalChain([options2, 'optionalAccess', _246 => _246.signal])
10748
+ signal: _optionalChain([options2, 'optionalAccess', _243 => _243.signal])
10627
10749
  });
10628
10750
  }
10629
10751
  function updateSubscriptionSettings(settings) {
@@ -10645,7 +10767,7 @@ function createRoom(options, config) {
10645
10767
  {
10646
10768
  [kInternal]: {
10647
10769
  get presenceBuffer() {
10648
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _247 => _247.buffer, 'access', _248 => _248.presenceUpdates, 'optionalAccess', _249 => _249.data]), () => ( null)));
10770
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _244 => _244.buffer, 'access', _245 => _245.presenceUpdates, 'optionalAccess', _246 => _246.data]), () => ( null)));
10649
10771
  },
10650
10772
  // prettier-ignore
10651
10773
  get undoStack() {
@@ -10660,9 +10782,9 @@ function createRoom(options, config) {
10660
10782
  return context.yjsProvider;
10661
10783
  },
10662
10784
  setYjsProvider(newProvider) {
10663
- _optionalChain([context, 'access', _250 => _250.yjsProvider, 'optionalAccess', _251 => _251.off, 'call', _252 => _252("status", yjsStatusDidChange)]);
10785
+ _optionalChain([context, 'access', _247 => _247.yjsProvider, 'optionalAccess', _248 => _248.off, 'call', _249 => _249("status", yjsStatusDidChange)]);
10664
10786
  context.yjsProvider = newProvider;
10665
- _optionalChain([newProvider, 'optionalAccess', _253 => _253.on, 'call', _254 => _254("status", yjsStatusDidChange)]);
10787
+ _optionalChain([newProvider, 'optionalAccess', _250 => _250.on, 'call', _251 => _251("status", yjsStatusDidChange)]);
10666
10788
  context.yjsProviderDidChange.notify();
10667
10789
  },
10668
10790
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -10697,25 +10819,19 @@ function createRoom(options, config) {
10697
10819
  id: roomId,
10698
10820
  subscribe: makeClassicSubscribeFn(
10699
10821
  roomId,
10700
- eventHub,
10822
+ events,
10701
10823
  config.errorEventSource
10702
10824
  ),
10703
10825
  connect: () => managedSocket.connect(),
10704
10826
  reconnect: () => managedSocket.reconnect(),
10705
10827
  disconnect: () => managedSocket.disconnect(),
10706
10828
  destroy: () => {
10707
- pendingFeedsRequests.forEach(
10708
- (request) => request.reject(new Error("Room destroyed"))
10709
- );
10710
- pendingFeedMessagesRequests.forEach(
10711
- (request) => request.reject(new Error("Room destroyed"))
10712
- );
10713
10829
  const { roomWillDestroy, ...eventsExceptDestroy } = eventHub;
10714
10830
  for (const source of Object.values(eventsExceptDestroy)) {
10715
10831
  source.dispose();
10716
10832
  }
10717
10833
  eventHub.roomWillDestroy.notify();
10718
- _optionalChain([context, 'access', _255 => _255.yjsProvider, 'optionalAccess', _256 => _256.off, 'call', _257 => _257("status", yjsStatusDidChange)]);
10834
+ _optionalChain([context, 'access', _252 => _252.yjsProvider, 'optionalAccess', _253 => _253.off, 'call', _254 => _254("status", yjsStatusDidChange)]);
10719
10835
  syncSourceForStorage.destroy();
10720
10836
  syncSourceForYjs.destroy();
10721
10837
  uninstallBgTabSpy();
@@ -10735,17 +10851,12 @@ function createRoom(options, config) {
10735
10851
  canRedo,
10736
10852
  clear,
10737
10853
  pause: pauseHistory,
10738
- resume: resumeHistory
10854
+ resume: resumeHistory,
10855
+ [kInternal]: {
10856
+ withoutHistory
10857
+ }
10739
10858
  },
10740
10859
  fetchYDoc,
10741
- fetchFeeds,
10742
- fetchFeedMessages,
10743
- addFeed,
10744
- updateFeed,
10745
- deleteFeed,
10746
- addFeedMessage,
10747
- updateFeedMessage,
10748
- deleteFeedMessage,
10749
10860
  getStorage,
10750
10861
  getStorageSnapshot,
10751
10862
  getStorageStatus,
@@ -10874,7 +10985,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
10874
10985
  }
10875
10986
  if (isLiveNode(first)) {
10876
10987
  const node = first;
10877
- if (_optionalChain([options, 'optionalAccess', _258 => _258.isDeep])) {
10988
+ if (_optionalChain([options, 'optionalAccess', _255 => _255.isDeep])) {
10878
10989
  const storageCallback = second;
10879
10990
  return subscribeToLiveStructureDeeply(node, storageCallback);
10880
10991
  } else {
@@ -10960,8 +11071,8 @@ function createClient(options) {
10960
11071
  const authManager = createAuthManager(options, (token) => {
10961
11072
  currentUserId.set(() => token.uid);
10962
11073
  });
10963
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _259 => _259.polyfills, 'optionalAccess', _260 => _260.fetch]) || /* istanbul ignore next */
10964
- _optionalChain([globalThis, 'access', _261 => _261.fetch, 'optionalAccess', _262 => _262.bind, 'call', _263 => _263(globalThis)]);
11074
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _256 => _256.polyfills, 'optionalAccess', _257 => _257.fetch]) || /* istanbul ignore next */
11075
+ _optionalChain([globalThis, 'access', _258 => _258.fetch, 'optionalAccess', _259 => _259.bind, 'call', _260 => _260(globalThis)]);
10965
11076
  const httpClient = createApiClient({
10966
11077
  baseUrl,
10967
11078
  fetchPolyfill,
@@ -10979,7 +11090,7 @@ function createClient(options) {
10979
11090
  delegates: {
10980
11091
  createSocket: makeCreateSocketDelegateForAi(
10981
11092
  baseUrl,
10982
- _optionalChain([clientOptions, 'access', _264 => _264.polyfills, 'optionalAccess', _265 => _265.WebSocket])
11093
+ _optionalChain([clientOptions, 'access', _261 => _261.polyfills, 'optionalAccess', _262 => _262.WebSocket])
10983
11094
  ),
10984
11095
  authenticate: async () => {
10985
11096
  const resp = await authManager.getAuthValue({
@@ -11039,7 +11150,7 @@ function createClient(options) {
11039
11150
  createSocket: makeCreateSocketDelegateForRoom(
11040
11151
  roomId,
11041
11152
  baseUrl,
11042
- _optionalChain([clientOptions, 'access', _266 => _266.polyfills, 'optionalAccess', _267 => _267.WebSocket])
11153
+ _optionalChain([clientOptions, 'access', _263 => _263.polyfills, 'optionalAccess', _264 => _264.WebSocket])
11043
11154
  ),
11044
11155
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
11045
11156
  })),
@@ -11062,7 +11173,7 @@ function createClient(options) {
11062
11173
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
11063
11174
  if (shouldConnect) {
11064
11175
  if (typeof atob === "undefined") {
11065
- if (_optionalChain([clientOptions, 'access', _268 => _268.polyfills, 'optionalAccess', _269 => _269.atob]) === void 0) {
11176
+ if (_optionalChain([clientOptions, 'access', _265 => _265.polyfills, 'optionalAccess', _266 => _266.atob]) === void 0) {
11066
11177
  throw new Error(
11067
11178
  "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"
11068
11179
  );
@@ -11074,7 +11185,7 @@ function createClient(options) {
11074
11185
  return leaseRoom(newRoomDetails);
11075
11186
  }
11076
11187
  function getRoom(roomId) {
11077
- const room = _optionalChain([roomsById, 'access', _270 => _270.get, 'call', _271 => _271(roomId), 'optionalAccess', _272 => _272.room]);
11188
+ const room = _optionalChain([roomsById, 'access', _267 => _267.get, 'call', _268 => _268(roomId), 'optionalAccess', _269 => _269.room]);
11078
11189
  return room ? room : null;
11079
11190
  }
11080
11191
  function logout() {
@@ -11090,7 +11201,7 @@ function createClient(options) {
11090
11201
  const batchedResolveUsers = new Batch(
11091
11202
  async (batchedUserIds) => {
11092
11203
  const userIds = batchedUserIds.flat();
11093
- const users = await _optionalChain([resolveUsers, 'optionalCall', _273 => _273({ userIds })]);
11204
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _270 => _270({ userIds })]);
11094
11205
  warnOnceIf(
11095
11206
  !resolveUsers,
11096
11207
  "Set the resolveUsers option in createClient to specify user info."
@@ -11107,7 +11218,7 @@ function createClient(options) {
11107
11218
  const batchedResolveRoomsInfo = new Batch(
11108
11219
  async (batchedRoomIds) => {
11109
11220
  const roomIds = batchedRoomIds.flat();
11110
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _274 => _274({ roomIds })]);
11221
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _271 => _271({ roomIds })]);
11111
11222
  warnOnceIf(
11112
11223
  !resolveRoomsInfo,
11113
11224
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -11124,7 +11235,7 @@ function createClient(options) {
11124
11235
  const batchedResolveGroupsInfo = new Batch(
11125
11236
  async (batchedGroupIds) => {
11126
11237
  const groupIds = batchedGroupIds.flat();
11127
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _275 => _275({ groupIds })]);
11238
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _272 => _272({ groupIds })]);
11128
11239
  warnOnceIf(
11129
11240
  !resolveGroupsInfo,
11130
11241
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -11180,7 +11291,7 @@ function createClient(options) {
11180
11291
  }
11181
11292
  };
11182
11293
  const win = typeof window !== "undefined" ? window : void 0;
11183
- _optionalChain([win, 'optionalAccess', _276 => _276.addEventListener, 'call', _277 => _277("beforeunload", maybePreventClose)]);
11294
+ _optionalChain([win, 'optionalAccess', _273 => _273.addEventListener, 'call', _274 => _274("beforeunload", maybePreventClose)]);
11184
11295
  }
11185
11296
  async function getNotificationSettings(options2) {
11186
11297
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -11307,7 +11418,7 @@ var commentBodyElementsTypes = {
11307
11418
  mention: "inline"
11308
11419
  };
11309
11420
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
11310
- if (!body || !_optionalChain([body, 'optionalAccess', _278 => _278.content])) {
11421
+ if (!body || !_optionalChain([body, 'optionalAccess', _275 => _275.content])) {
11311
11422
  return;
11312
11423
  }
11313
11424
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -11317,13 +11428,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
11317
11428
  for (const block of body.content) {
11318
11429
  if (type === "all" || type === "block") {
11319
11430
  if (guard(block)) {
11320
- _optionalChain([visitor, 'optionalCall', _279 => _279(block)]);
11431
+ _optionalChain([visitor, 'optionalCall', _276 => _276(block)]);
11321
11432
  }
11322
11433
  }
11323
11434
  if (type === "all" || type === "inline") {
11324
11435
  for (const inline of block.children) {
11325
11436
  if (guard(inline)) {
11326
- _optionalChain([visitor, 'optionalCall', _280 => _280(inline)]);
11437
+ _optionalChain([visitor, 'optionalCall', _277 => _277(inline)]);
11327
11438
  }
11328
11439
  }
11329
11440
  }
@@ -11493,7 +11604,7 @@ var stringifyCommentBodyPlainElements = {
11493
11604
  text: ({ element }) => element.text,
11494
11605
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
11495
11606
  mention: ({ element, user, group }) => {
11496
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _281 => _281.name]), () => ( _optionalChain([group, 'optionalAccess', _282 => _282.name]))), () => ( element.id))}`;
11607
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _278 => _278.name]), () => ( _optionalChain([group, 'optionalAccess', _279 => _279.name]))), () => ( element.id))}`;
11497
11608
  }
11498
11609
  };
11499
11610
  var stringifyCommentBodyHtmlElements = {
@@ -11523,7 +11634,7 @@ var stringifyCommentBodyHtmlElements = {
11523
11634
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
11524
11635
  },
11525
11636
  mention: ({ element, user, group }) => {
11526
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _283 => _283.name]) ? html`${_optionalChain([user, 'optionalAccess', _284 => _284.name])}` : _optionalChain([group, 'optionalAccess', _285 => _285.name]) ? html`${_optionalChain([group, 'optionalAccess', _286 => _286.name])}` : element.id}</span>`;
11637
+ return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _280 => _280.name]) ? html`${_optionalChain([user, 'optionalAccess', _281 => _281.name])}` : _optionalChain([group, 'optionalAccess', _282 => _282.name]) ? html`${_optionalChain([group, 'optionalAccess', _283 => _283.name])}` : element.id}</span>`;
11527
11638
  }
11528
11639
  };
11529
11640
  var stringifyCommentBodyMarkdownElements = {
@@ -11533,426 +11644,123 @@ var stringifyCommentBodyMarkdownElements = {
11533
11644
  text: ({ element }) => {
11534
11645
  let children = element.text;
11535
11646
  if (!children) {
11536
- return children;
11537
- }
11538
- if (element.bold) {
11539
- children = markdown`**${children}**`;
11540
- }
11541
- if (element.italic) {
11542
- children = markdown`_${children}_`;
11543
- }
11544
- if (element.strikethrough) {
11545
- children = markdown`~~${children}~~`;
11546
- }
11547
- if (element.code) {
11548
- children = markdown`\`${children}\``;
11549
- }
11550
- return children;
11551
- },
11552
- link: ({ element, href }) => {
11553
- return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
11554
- },
11555
- mention: ({ element, user, group }) => {
11556
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _287 => _287.name]), () => ( _optionalChain([group, 'optionalAccess', _288 => _288.name]))), () => ( element.id))}`;
11557
- }
11558
- };
11559
- async function stringifyCommentBody(body, options) {
11560
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _289 => _289.format]), () => ( "plain"));
11561
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _290 => _290.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
11562
- const elements = {
11563
- ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
11564
- ..._optionalChain([options, 'optionalAccess', _291 => _291.elements])
11565
- };
11566
- const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
11567
- body,
11568
- _optionalChain([options, 'optionalAccess', _292 => _292.resolveUsers]),
11569
- _optionalChain([options, 'optionalAccess', _293 => _293.resolveGroupsInfo])
11570
- );
11571
- const blocks = body.content.flatMap((block, blockIndex) => {
11572
- switch (block.type) {
11573
- case "paragraph": {
11574
- const inlines = block.children.flatMap((inline, inlineIndex) => {
11575
- if (isCommentBodyMention(inline)) {
11576
- return inline.id ? [
11577
- elements.mention(
11578
- {
11579
- element: inline,
11580
- user: inline.kind === "user" ? resolvedUsers.get(inline.id) : void 0,
11581
- group: inline.kind === "group" ? resolvedGroupsInfo.get(inline.id) : void 0
11582
- },
11583
- inlineIndex
11584
- )
11585
- ] : [];
11586
- }
11587
- if (isCommentBodyLink(inline)) {
11588
- const href = sanitizeUrl(inline.url);
11589
- if (href === null) {
11590
- return [
11591
- elements.text(
11592
- {
11593
- element: { text: _nullishCoalesce(inline.text, () => ( inline.url)) }
11594
- },
11595
- inlineIndex
11596
- )
11597
- ];
11598
- }
11599
- return [
11600
- elements.link(
11601
- {
11602
- element: inline,
11603
- href
11604
- },
11605
- inlineIndex
11606
- )
11607
- ];
11608
- }
11609
- if (isCommentBodyText(inline)) {
11610
- return [elements.text({ element: inline }, inlineIndex)];
11611
- }
11612
- return [];
11613
- });
11614
- return [
11615
- elements.paragraph(
11616
- { element: block, children: inlines.join("") },
11617
- blockIndex
11618
- )
11619
- ];
11620
- }
11621
- default:
11622
- return [];
11623
- }
11624
- });
11625
- return blocks.join(separator);
11626
- }
11627
-
11628
- // src/crdts/utils.ts
11629
- function toPlainLson(lson) {
11630
- if (lson instanceof LiveObject) {
11631
- return {
11632
- liveblocksType: "LiveObject",
11633
- data: Object.fromEntries(
11634
- Object.entries(lson.toObject()).flatMap(
11635
- ([key, value]) => value !== void 0 ? [[key, toPlainLson(value)]] : []
11636
- )
11637
- )
11638
- };
11639
- } else if (lson instanceof LiveMap) {
11640
- return {
11641
- liveblocksType: "LiveMap",
11642
- data: Object.fromEntries(
11643
- [...lson].map(([key, value]) => [key, toPlainLson(value)])
11644
- )
11645
- };
11646
- } else if (lson instanceof LiveList) {
11647
- return {
11648
- liveblocksType: "LiveList",
11649
- data: [...lson].map((item) => toPlainLson(item))
11650
- };
11651
- } else {
11652
- return lson;
11653
- }
11654
- }
11655
-
11656
- // src/immutable.ts
11657
- function lsonObjectToJson(obj) {
11658
- const result = {};
11659
- for (const key in obj) {
11660
- const val = obj[key];
11661
- if (val !== void 0) {
11662
- result[key] = lsonToJson(val);
11663
- }
11664
- }
11665
- return result;
11666
- }
11667
- function liveObjectToJson(liveObject) {
11668
- return lsonObjectToJson(liveObject.toObject());
11669
- }
11670
- function liveMapToJson(map) {
11671
- const result = {};
11672
- for (const [key, value] of map.entries()) {
11673
- result[key] = lsonToJson(value);
11674
- }
11675
- return result;
11676
- }
11677
- function lsonListToJson(value) {
11678
- return value.map(lsonToJson);
11679
- }
11680
- function liveListToJson(value) {
11681
- return lsonListToJson(value.toArray());
11682
- }
11683
- function lsonToJson(value) {
11684
- if (value instanceof LiveObject) {
11685
- return liveObjectToJson(value);
11686
- } else if (value instanceof LiveList) {
11687
- return liveListToJson(value);
11688
- } else if (value instanceof LiveMap) {
11689
- return liveMapToJson(value);
11690
- } else if (value instanceof LiveRegister) {
11691
- return value.data;
11692
- }
11693
- if (Array.isArray(value)) {
11694
- return lsonListToJson(value);
11695
- } else if (isPlainObject(value)) {
11696
- return lsonObjectToJson(value);
11697
- }
11698
- return value;
11699
- }
11700
- function deepLiveify(value) {
11701
- if (Array.isArray(value)) {
11702
- return new LiveList(value.map(deepLiveify));
11703
- } else if (isPlainObject(value)) {
11704
- const init = {};
11705
- for (const key in value) {
11706
- const val = value[key];
11707
- if (val === void 0) {
11708
- continue;
11709
- }
11710
- init[key] = deepLiveify(val);
11711
- }
11712
- return new LiveObject(init);
11713
- } else {
11714
- return value;
11715
- }
11716
- }
11717
- function patchLiveList(liveList, prev, next) {
11718
- let i = 0;
11719
- let prevEnd = prev.length - 1;
11720
- let nextEnd = next.length - 1;
11721
- let prevNode = prev[0];
11722
- let nextNode = next[0];
11723
- outer: {
11724
- while (prevNode === nextNode) {
11725
- ++i;
11726
- if (i > prevEnd || i > nextEnd) {
11727
- break outer;
11728
- }
11729
- prevNode = prev[i];
11730
- nextNode = next[i];
11731
- }
11732
- prevNode = prev[prevEnd];
11733
- nextNode = next[nextEnd];
11734
- while (prevNode === nextNode) {
11735
- prevEnd--;
11736
- nextEnd--;
11737
- if (i > prevEnd || i > nextEnd) {
11738
- break outer;
11739
- }
11740
- prevNode = prev[prevEnd];
11741
- nextNode = next[nextEnd];
11742
- }
11743
- }
11744
- if (i > prevEnd) {
11745
- if (i <= nextEnd) {
11746
- while (i <= nextEnd) {
11747
- liveList.insert(deepLiveify(next[i]), i);
11748
- i++;
11749
- }
11750
- }
11751
- } else if (i > nextEnd) {
11752
- let localI = i;
11753
- while (localI <= prevEnd) {
11754
- liveList.delete(i);
11755
- localI++;
11756
- }
11757
- } else {
11758
- while (i <= prevEnd && i <= nextEnd) {
11759
- prevNode = prev[i];
11760
- nextNode = next[i];
11761
- const liveListNode = liveList.get(i);
11762
- if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
11763
- patchLiveObject(liveListNode, prevNode, nextNode);
11764
- } else {
11765
- liveList.set(i, deepLiveify(nextNode));
11766
- }
11767
- i++;
11768
- }
11769
- while (i <= nextEnd) {
11770
- liveList.insert(deepLiveify(next[i]), i);
11771
- i++;
11647
+ return children;
11772
11648
  }
11773
- let localI = i;
11774
- while (localI <= prevEnd) {
11775
- liveList.delete(i);
11776
- localI++;
11649
+ if (element.bold) {
11650
+ children = markdown`**${children}**`;
11777
11651
  }
11778
- }
11779
- }
11780
- function patchLiveObjectKey(liveObject, key, prev, next) {
11781
- if (process.env.NODE_ENV !== "production") {
11782
- const nonSerializableValue = findNonSerializableValue(next);
11783
- if (nonSerializableValue) {
11784
- error2(
11785
- `New state path: '${nonSerializableValue.path}' value: '${String(
11786
- nonSerializableValue.value
11787
- )}' is not serializable.
11788
- Only serializable value can be synced with Liveblocks.`
11789
- );
11790
- return;
11652
+ if (element.italic) {
11653
+ children = markdown`_${children}_`;
11791
11654
  }
11792
- }
11793
- const value = liveObject.get(key);
11794
- if (next === void 0) {
11795
- liveObject.delete(key);
11796
- } else if (value === void 0) {
11797
- liveObject.set(key, deepLiveify(next));
11798
- } else if (prev === next) {
11799
- return;
11800
- } else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
11801
- patchLiveList(value, prev, next);
11802
- } else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
11803
- patchLiveObject(value, prev, next);
11804
- } else {
11805
- liveObject.set(key, deepLiveify(next));
11806
- }
11807
- }
11808
- function patchLiveObject(root, prev, next) {
11809
- const updates = {};
11810
- for (const key in next) {
11811
- patchLiveObjectKey(root, key, prev[key], next[key]);
11812
- }
11813
- for (const key in prev) {
11814
- if (next[key] === void 0) {
11815
- root.delete(key);
11655
+ if (element.strikethrough) {
11656
+ children = markdown`~~${children}~~`;
11816
11657
  }
11817
- }
11818
- if (Object.keys(updates).length > 0) {
11819
- root.update(updates);
11820
- }
11821
- }
11822
- function getParentsPath(node) {
11823
- const path = [];
11824
- while (node.parent.type === "HasParent") {
11825
- if (isLiveList(node.parent.node)) {
11826
- path.push(node.parent.node._indexOfPosition(node.parent.key));
11827
- } else {
11828
- path.push(node.parent.key);
11658
+ if (element.code) {
11659
+ children = markdown`\`${children}\``;
11829
11660
  }
11830
- node = node.parent.node;
11661
+ return children;
11662
+ },
11663
+ link: ({ element, href }) => {
11664
+ return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
11665
+ },
11666
+ mention: ({ element, user, group }) => {
11667
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _284 => _284.name]), () => ( _optionalChain([group, 'optionalAccess', _285 => _285.name]))), () => ( element.id))}`;
11831
11668
  }
11832
- return path;
11833
- }
11834
- function legacy_patchImmutableObject(state, updates) {
11835
- return updates.reduce(
11836
- (state2, update) => legacy_patchImmutableObjectWithUpdate(state2, update),
11837
- state
11669
+ };
11670
+ async function stringifyCommentBody(body, options) {
11671
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _286 => _286.format]), () => ( "plain"));
11672
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _287 => _287.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
11673
+ const elements = {
11674
+ ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
11675
+ ..._optionalChain([options, 'optionalAccess', _288 => _288.elements])
11676
+ };
11677
+ const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
11678
+ body,
11679
+ _optionalChain([options, 'optionalAccess', _289 => _289.resolveUsers]),
11680
+ _optionalChain([options, 'optionalAccess', _290 => _290.resolveGroupsInfo])
11838
11681
  );
11839
- }
11840
- function legacy_patchImmutableObjectWithUpdate(state, update) {
11841
- const path = getParentsPath(update.node);
11842
- return legacy_patchImmutableNode(state, path, update);
11843
- }
11844
- function legacy_patchImmutableNode(state, path, update) {
11845
- const pathItem = path.pop();
11846
- if (pathItem === void 0) {
11847
- switch (update.type) {
11848
- case "LiveObject": {
11849
- if (!isJsonObject(state)) {
11850
- throw new Error(
11851
- "Internal: received update on LiveObject but state was not an object"
11852
- );
11853
- }
11854
- const newState = Object.assign({}, state);
11855
- for (const key in update.updates) {
11856
- if (_optionalChain([update, 'access', _294 => _294.updates, 'access', _295 => _295[key], 'optionalAccess', _296 => _296.type]) === "update") {
11857
- const val = update.node.get(key);
11858
- if (val !== void 0) {
11859
- newState[key] = lsonToJson(val);
11860
- }
11861
- } else if (_optionalChain([update, 'access', _297 => _297.updates, 'access', _298 => _298[key], 'optionalAccess', _299 => _299.type]) === "delete") {
11862
- delete newState[key];
11682
+ const blocks = body.content.flatMap((block, blockIndex) => {
11683
+ switch (block.type) {
11684
+ case "paragraph": {
11685
+ const inlines = block.children.flatMap((inline, inlineIndex) => {
11686
+ if (isCommentBodyMention(inline)) {
11687
+ return inline.id ? [
11688
+ elements.mention(
11689
+ {
11690
+ element: inline,
11691
+ user: inline.kind === "user" ? resolvedUsers.get(inline.id) : void 0,
11692
+ group: inline.kind === "group" ? resolvedGroupsInfo.get(inline.id) : void 0
11693
+ },
11694
+ inlineIndex
11695
+ )
11696
+ ] : [];
11863
11697
  }
11864
- }
11865
- return newState;
11866
- }
11867
- case "LiveList": {
11868
- if (!Array.isArray(state)) {
11869
- throw new Error(
11870
- "Internal: received update on LiveList but state was not an array"
11871
- );
11872
- }
11873
- let newState = state.map((x) => x);
11874
- for (const listUpdate of update.updates) {
11875
- if (listUpdate.type === "set") {
11876
- newState = newState.map(
11877
- (item, index) => index === listUpdate.index ? lsonToJson(listUpdate.item) : item
11878
- );
11879
- } else if (listUpdate.type === "insert") {
11880
- if (listUpdate.index === newState.length) {
11881
- newState.push(lsonToJson(listUpdate.item));
11882
- } else {
11883
- newState = [
11884
- ...newState.slice(0, listUpdate.index),
11885
- lsonToJson(listUpdate.item),
11886
- ...newState.slice(listUpdate.index)
11887
- ];
11888
- }
11889
- } else if (listUpdate.type === "delete") {
11890
- newState.splice(listUpdate.index, 1);
11891
- } else if (listUpdate.type === "move") {
11892
- if (listUpdate.previousIndex > listUpdate.index) {
11893
- newState = [
11894
- ...newState.slice(0, listUpdate.index),
11895
- lsonToJson(listUpdate.item),
11896
- ...newState.slice(listUpdate.index, listUpdate.previousIndex),
11897
- ...newState.slice(listUpdate.previousIndex + 1)
11898
- ];
11899
- } else {
11900
- newState = [
11901
- ...newState.slice(0, listUpdate.previousIndex),
11902
- ...newState.slice(
11903
- listUpdate.previousIndex + 1,
11904
- listUpdate.index + 1
11905
- ),
11906
- lsonToJson(listUpdate.item),
11907
- ...newState.slice(listUpdate.index + 1)
11698
+ if (isCommentBodyLink(inline)) {
11699
+ const href = sanitizeUrl(inline.url);
11700
+ if (href === null) {
11701
+ return [
11702
+ elements.text(
11703
+ {
11704
+ element: { text: _nullishCoalesce(inline.text, () => ( inline.url)) }
11705
+ },
11706
+ inlineIndex
11707
+ )
11908
11708
  ];
11909
11709
  }
11710
+ return [
11711
+ elements.link(
11712
+ {
11713
+ element: inline,
11714
+ href
11715
+ },
11716
+ inlineIndex
11717
+ )
11718
+ ];
11910
11719
  }
11911
- }
11912
- return newState;
11913
- }
11914
- case "LiveMap": {
11915
- if (!isJsonObject(state)) {
11916
- throw new Error(
11917
- "Internal: received update on LiveMap but state was not an object"
11918
- );
11919
- }
11920
- const newState = Object.assign({}, state);
11921
- for (const key in update.updates) {
11922
- if (_optionalChain([update, 'access', _300 => _300.updates, 'access', _301 => _301[key], 'optionalAccess', _302 => _302.type]) === "update") {
11923
- const value = update.node.get(key);
11924
- if (value !== void 0) {
11925
- newState[key] = lsonToJson(value);
11926
- }
11927
- } else if (_optionalChain([update, 'access', _303 => _303.updates, 'access', _304 => _304[key], 'optionalAccess', _305 => _305.type]) === "delete") {
11928
- delete newState[key];
11720
+ if (isCommentBodyText(inline)) {
11721
+ return [elements.text({ element: inline }, inlineIndex)];
11929
11722
  }
11930
- }
11931
- return newState;
11723
+ return [];
11724
+ });
11725
+ return [
11726
+ elements.paragraph(
11727
+ { element: block, children: inlines.join("") },
11728
+ blockIndex
11729
+ )
11730
+ ];
11932
11731
  }
11732
+ default:
11733
+ return [];
11933
11734
  }
11934
- }
11935
- if (Array.isArray(state)) {
11936
- const newArray = [...state];
11937
- newArray[pathItem] = legacy_patchImmutableNode(
11938
- state[pathItem],
11939
- path,
11940
- update
11941
- );
11942
- return newArray;
11943
- } else if (isJsonObject(state)) {
11944
- const node = state[pathItem];
11945
- if (node === void 0) {
11946
- return state;
11947
- } else {
11948
- const stateAsObj = state;
11949
- return {
11950
- ...stateAsObj,
11951
- [pathItem]: legacy_patchImmutableNode(node, path, update)
11952
- };
11953
- }
11735
+ });
11736
+ return blocks.join(separator);
11737
+ }
11738
+
11739
+ // src/crdts/utils.ts
11740
+ function toPlainLson(lson) {
11741
+ if (lson instanceof LiveObject) {
11742
+ return {
11743
+ liveblocksType: "LiveObject",
11744
+ data: Object.fromEntries(
11745
+ Object.entries(lson.toObject()).flatMap(
11746
+ ([key, value]) => value !== void 0 ? [[key, toPlainLson(value)]] : []
11747
+ )
11748
+ )
11749
+ };
11750
+ } else if (lson instanceof LiveMap) {
11751
+ return {
11752
+ liveblocksType: "LiveMap",
11753
+ data: Object.fromEntries(
11754
+ [...lson].map(([key, value]) => [key, toPlainLson(value)])
11755
+ )
11756
+ };
11757
+ } else if (lson instanceof LiveList) {
11758
+ return {
11759
+ liveblocksType: "LiveList",
11760
+ data: [...lson].map((item) => toPlainLson(item))
11761
+ };
11954
11762
  } else {
11955
- return state;
11763
+ return lson;
11956
11764
  }
11957
11765
  }
11958
11766
 
@@ -12004,9 +11812,9 @@ function makePoller(callback, intervalMs, options) {
12004
11812
  const startTime = performance.now();
12005
11813
  const doc = typeof document !== "undefined" ? document : void 0;
12006
11814
  const win = typeof window !== "undefined" ? window : void 0;
12007
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _306 => _306.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11815
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _291 => _291.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
12008
11816
  const context = {
12009
- inForeground: _optionalChain([doc, 'optionalAccess', _307 => _307.visibilityState]) !== "hidden",
11817
+ inForeground: _optionalChain([doc, 'optionalAccess', _292 => _292.visibilityState]) !== "hidden",
12010
11818
  lastSuccessfulPollAt: startTime,
12011
11819
  count: 0,
12012
11820
  backoff: 0
@@ -12087,11 +11895,11 @@ function makePoller(callback, intervalMs, options) {
12087
11895
  pollNowIfStale();
12088
11896
  }
12089
11897
  function onVisibilityChange() {
12090
- setInForeground(_optionalChain([doc, 'optionalAccess', _308 => _308.visibilityState]) !== "hidden");
11898
+ setInForeground(_optionalChain([doc, 'optionalAccess', _293 => _293.visibilityState]) !== "hidden");
12091
11899
  }
12092
- _optionalChain([doc, 'optionalAccess', _309 => _309.addEventListener, 'call', _310 => _310("visibilitychange", onVisibilityChange)]);
12093
- _optionalChain([win, 'optionalAccess', _311 => _311.addEventListener, 'call', _312 => _312("online", onVisibilityChange)]);
12094
- _optionalChain([win, 'optionalAccess', _313 => _313.addEventListener, 'call', _314 => _314("focus", pollNowIfStale)]);
11900
+ _optionalChain([doc, 'optionalAccess', _294 => _294.addEventListener, 'call', _295 => _295("visibilitychange", onVisibilityChange)]);
11901
+ _optionalChain([win, 'optionalAccess', _296 => _296.addEventListener, 'call', _297 => _297("online", onVisibilityChange)]);
11902
+ _optionalChain([win, 'optionalAccess', _298 => _298.addEventListener, 'call', _299 => _299("focus", pollNowIfStale)]);
12095
11903
  fsm.start();
12096
11904
  return {
12097
11905
  inc,
@@ -12231,5 +12039,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
12231
12039
 
12232
12040
 
12233
12041
 
12234
- 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.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; 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.patchLiveObjectKey = patchLiveObjectKey; 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;
12042
+ exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; 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.deepLiveifyObject = deepLiveifyObject; 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.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.legacy_patchLiveObjectKey = legacy_patchLiveObjectKey; exports.lsonToJson = lsonToJson; 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;
12235
12043
  //# sourceMappingURL=index.cjs.map