@liveblocks/core 2.17.0-channels1 → 2.17.0-usrnotsettings1

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.mjs 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 = "2.17.0-channels1";
9
+ var PKG_VERSION = "2.17.0-usrnotsettings1";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -166,6 +166,14 @@ function wrapWithTitle(method) {
166
166
  var warnWithTitle = wrapWithTitle("warn");
167
167
  var errorWithTitle = wrapWithTitle("error");
168
168
 
169
+ // src/lib/guards.ts
170
+ function isPlainObject(blob) {
171
+ return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
172
+ }
173
+ function isStartsWithOperator(blob) {
174
+ return isPlainObject(blob) && typeof blob.startsWith === "string";
175
+ }
176
+
169
177
  // src/lib/utils.ts
170
178
  function raise(msg) {
171
179
  throw new Error(msg);
@@ -257,13 +265,48 @@ function memoizeOnSuccess(factoryFn) {
257
265
  }
258
266
 
259
267
  // src/lib/autoRetry.ts
260
- var HttpError = class extends Error {
261
- constructor(message, status, details) {
268
+ var HttpError = class _HttpError extends Error {
269
+ response;
270
+ details;
271
+ constructor(message, response, details) {
262
272
  super(message);
263
- this.message = message;
264
- this.status = status;
273
+ this.name = "HttpError";
274
+ this.response = response;
265
275
  this.details = details;
266
276
  }
277
+ static async fromResponse(response) {
278
+ let bodyAsText;
279
+ try {
280
+ bodyAsText = await response.text();
281
+ } catch {
282
+ }
283
+ const bodyAsJson = bodyAsText ? tryParseJson(bodyAsText) : void 0;
284
+ let bodyAsJsonObject;
285
+ if (isPlainObject(bodyAsJson)) {
286
+ bodyAsJsonObject = bodyAsJson;
287
+ }
288
+ let message = "";
289
+ message ||= typeof bodyAsJsonObject?.message === "string" ? bodyAsJsonObject.message : "";
290
+ message ||= typeof bodyAsJsonObject?.error === "string" ? bodyAsJsonObject.error : "";
291
+ if (bodyAsJson === void 0) {
292
+ message ||= bodyAsText || "";
293
+ }
294
+ message ||= response.statusText;
295
+ let path;
296
+ try {
297
+ path = new URL(response.url).pathname;
298
+ } catch {
299
+ }
300
+ message += path !== void 0 ? ` (got status ${response.status} from ${path})` : ` (got status ${response.status})`;
301
+ const details = bodyAsJsonObject;
302
+ return new _HttpError(message, response, details);
303
+ }
304
+ /**
305
+ * Convenience accessor for response.status.
306
+ */
307
+ get status() {
308
+ return this.response.status;
309
+ }
267
310
  };
268
311
  var DONT_RETRY_4XX = (x) => x instanceof HttpError && x.status >= 400 && x.status < 500;
269
312
  async function autoRetry(promiseFn, maxTries, backoff, shouldStopRetrying = DONT_RETRY_4XX) {
@@ -329,7 +372,12 @@ function makeEventSource() {
329
372
  }).finally(() => unsub?.());
330
373
  }
331
374
  function notify(event) {
332
- _observers.forEach((callback) => callback(event));
375
+ let called = false;
376
+ for (const callback of _observers) {
377
+ callback(event);
378
+ called = true;
379
+ }
380
+ return called;
333
381
  }
334
382
  function count() {
335
383
  return _observers.size;
@@ -370,8 +418,9 @@ function makeBufferableEventSource() {
370
418
  function notifyOrBuffer(event) {
371
419
  if (_buffer !== null) {
372
420
  _buffer.push(event);
421
+ return false;
373
422
  } else {
374
- eventSource2.notify(event);
423
+ return eventSource2.notify(event);
375
424
  }
376
425
  }
377
426
  return {
@@ -676,32 +725,15 @@ var MutableSignal = class extends AbstractSignal {
676
725
  };
677
726
 
678
727
  // src/lib/stringify.ts
679
- var EXPLICIT_UNDEFINED_PLACEHOLDER = "_explicit_undefined";
680
728
  function replacer(_key, value) {
681
729
  return value !== null && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).sort().reduce((sorted, key) => {
682
730
  sorted[key] = value[key];
683
731
  return sorted;
684
- }, {}) : value === void 0 ? EXPLICIT_UNDEFINED_PLACEHOLDER : value;
685
- }
686
- function reviver(key, value) {
687
- if (!key && value === EXPLICIT_UNDEFINED_PLACEHOLDER) {
688
- return void 0;
689
- }
690
- if (value && typeof value === "object") {
691
- for (const k in value) {
692
- if (value[k] === EXPLICIT_UNDEFINED_PLACEHOLDER) {
693
- Object.defineProperty(value, k, { value: void 0 });
694
- }
695
- }
696
- }
697
- return value;
732
+ }, {}) : value;
698
733
  }
699
734
  function stringify(value) {
700
735
  return JSON.stringify(value, replacer);
701
736
  }
702
- function unstringify(value) {
703
- return JSON.parse(value, reviver);
704
- }
705
737
 
706
738
  // src/lib/batch.ts
707
739
  var DEFAULT_SIZE = 50;
@@ -917,14 +949,6 @@ var DefaultMap = class extends Map {
917
949
  }
918
950
  };
919
951
 
920
- // src/lib/guards.ts
921
- function isPlainObject(blob) {
922
- return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
923
- }
924
- function isStartsWithOperator(blob) {
925
- return isPlainObject(blob) && typeof blob.startsWith === "string";
926
- }
927
-
928
952
  // src/lib/objectToQuery.ts
929
953
  var identifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
930
954
  function objectToQuery(obj) {
@@ -974,9 +998,7 @@ function objectToQuery(obj) {
974
998
  ...getFiltersFromKeyValuePairsWithOperator(nKeyValuePairsWithOperator)
975
999
  ];
976
1000
  });
977
- return filterList.map(
978
- ({ key, operator, value }) => formatFilter(key, operator, formatFilterValue(value))
979
- ).join(" AND ");
1001
+ return filterList.map(({ key, operator, value }) => `${key}${operator}${quote(value)}`).join(" ");
980
1002
  }
981
1003
  var getFiltersFromKeyValuePairs = (keyValuePairs) => {
982
1004
  const filters = [];
@@ -1003,29 +1025,27 @@ var getFiltersFromKeyValuePairsWithOperator = (keyValuePairsWithOperator) => {
1003
1025
  return filters;
1004
1026
  };
1005
1027
  var isSimpleValue = (value) => {
1006
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1007
- };
1008
- var formatFilter = (key, operator, value) => {
1009
- return `${key}${operator}${value}`;
1028
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
1010
1029
  };
1011
1030
  var formatFilterKey = (key, nestedKey) => {
1012
1031
  if (nestedKey) {
1013
- return `${key}[${JSON.stringify(nestedKey)}]`;
1032
+ return `${key}[${quote(nestedKey)}]`;
1014
1033
  }
1015
1034
  return key;
1016
1035
  };
1017
- var formatFilterValue = (value) => {
1018
- if (typeof value === "string") {
1019
- if (isStringEmpty(value)) {
1020
- throw new Error("Value cannot be empty");
1021
- }
1022
- return JSON.stringify(value);
1023
- }
1024
- return value.toString();
1025
- };
1026
1036
  var isStringEmpty = (value) => {
1027
1037
  return !value || value.toString().trim() === "";
1028
1038
  };
1039
+ function quote(input) {
1040
+ const result = JSON.stringify(input);
1041
+ if (typeof input !== "string") {
1042
+ return result;
1043
+ }
1044
+ if (result.includes("'")) {
1045
+ return result;
1046
+ }
1047
+ return `'${result.slice(1, -1).replace(/\\"/g, '"')}'`;
1048
+ }
1029
1049
 
1030
1050
  // src/lib/url.ts
1031
1051
  function toURLSearchParams(params) {
@@ -1691,17 +1711,17 @@ function createApiClient({
1691
1711
  await authManager.getAuthValue({ requestedScope: "comments:read" })
1692
1712
  );
1693
1713
  }
1694
- async function getChannelsNotificationSettings(options) {
1714
+ async function getUserNotificationSettings(options) {
1695
1715
  return httpClient.get(
1696
- url`/v2/c/channels-notification-settings`,
1716
+ url`/v2/c/notification-settings`,
1697
1717
  await authManager.getAuthValue({ requestedScope: "comments:read" }),
1698
1718
  void 0,
1699
1719
  { signal: options?.signal }
1700
1720
  );
1701
1721
  }
1702
- async function updateChannelsNotificationSettings(settings) {
1722
+ async function updateUserNotificationSettings(settings) {
1703
1723
  return httpClient.post(
1704
- url`/v2/c/channels-notification-settings`,
1724
+ url`/v2/c/notification-settings`,
1705
1725
  await authManager.getAuthValue({ requestedScope: "comments:read" }),
1706
1726
  settings
1707
1727
  );
@@ -1768,12 +1788,10 @@ function createApiClient({
1768
1788
  removeReaction,
1769
1789
  markThreadAsResolved,
1770
1790
  markThreadAsUnresolved,
1771
- // Room notifications
1772
1791
  markRoomInboxNotificationAsRead,
1773
- updateNotificationSettings,
1774
- // Channel notification settings
1792
+ // Room notifications
1775
1793
  getNotificationSettings,
1776
- updateChannelsNotificationSettings,
1794
+ updateNotificationSettings,
1777
1795
  // Room text editor
1778
1796
  createTextMention,
1779
1797
  deleteTextMention,
@@ -1797,7 +1815,8 @@ function createApiClient({
1797
1815
  markInboxNotificationAsRead,
1798
1816
  deleteAllInboxNotifications,
1799
1817
  deleteInboxNotification,
1800
- getChannelsNotificationSettings,
1818
+ getUserNotificationSettings,
1819
+ updateUserNotificationSettings,
1801
1820
  // User threads
1802
1821
  getUserThreads_experimental,
1803
1822
  getUserThreadsSince_experimental
@@ -1868,14 +1887,7 @@ var HttpClient = class {
1868
1887
  async #fetch(endpoint, authValue, options, params) {
1869
1888
  const response = await this.#rawFetch(endpoint, authValue, options, params);
1870
1889
  if (!response.ok) {
1871
- let error3;
1872
- try {
1873
- const errorBody = await response.json();
1874
- error3 = new HttpError(errorBody.message, response.status, errorBody);
1875
- } catch {
1876
- error3 = new HttpError(response.statusText, response.status);
1877
- }
1878
- throw error3;
1890
+ throw await HttpError.fromResponse(response);
1879
1891
  }
1880
1892
  let body;
1881
1893
  try {
@@ -2519,13 +2531,6 @@ var StopRetrying = class extends Error {
2519
2531
  super(reason);
2520
2532
  }
2521
2533
  };
2522
- var LiveblocksError = class extends Error {
2523
- /** @internal */
2524
- constructor(message, code) {
2525
- super(message);
2526
- this.code = code;
2527
- }
2528
- };
2529
2534
  function nextBackoffDelay(currentDelay, delays) {
2530
2535
  return delays.find((delay) => delay > currentDelay) ?? delays[delays.length - 1];
2531
2536
  }
@@ -2635,11 +2640,10 @@ var assign = (patch) => (ctx) => ctx.patch(patch);
2635
2640
  function createConnectionStateMachine(delegates, options) {
2636
2641
  const onMessage = makeBufferableEventSource();
2637
2642
  onMessage.pause();
2638
- const onLiveblocksError = makeEventSource();
2639
- function fireErrorEvent(errmsg, errcode) {
2643
+ const onConnectionError = makeEventSource();
2644
+ function fireErrorEvent(message, code) {
2640
2645
  return () => {
2641
- const err = new LiveblocksError(errmsg, errcode);
2642
- onLiveblocksError.notify(err);
2646
+ onConnectionError.notify({ message, code });
2643
2647
  };
2644
2648
  }
2645
2649
  const initialContext = {
@@ -2997,7 +3001,7 @@ function createConnectionStateMachine(delegates, options) {
2997
3001
  didConnect,
2998
3002
  didDisconnect,
2999
3003
  onMessage: onMessage.observable,
3000
- onLiveblocksError: onLiveblocksError.observable
3004
+ onConnectionError: onConnectionError.observable
3001
3005
  }
3002
3006
  };
3003
3007
  }
@@ -6261,6 +6265,83 @@ var ManagedOthers = class {
6261
6265
  }
6262
6266
  };
6263
6267
 
6268
+ // src/types/LiveblocksError.ts
6269
+ var LiveblocksError = class _LiveblocksError extends Error {
6270
+ context;
6271
+ constructor(message, context, cause) {
6272
+ super(message, { cause });
6273
+ this.context = context;
6274
+ this.name = "LiveblocksError";
6275
+ }
6276
+ /** Convenience accessor for error.context.roomId (if available) */
6277
+ get roomId() {
6278
+ return this.context.roomId;
6279
+ }
6280
+ /** @deprecated Prefer using `context.code` instead, to enable type narrowing */
6281
+ get code() {
6282
+ return this.context.code;
6283
+ }
6284
+ /**
6285
+ * Creates a LiveblocksError from a generic error, by attaching Liveblocks
6286
+ * contextual information like room ID, thread ID, etc.
6287
+ */
6288
+ static from(context, cause) {
6289
+ return new _LiveblocksError(
6290
+ defaultMessageFromContext(context),
6291
+ context,
6292
+ cause
6293
+ );
6294
+ }
6295
+ };
6296
+ function defaultMessageFromContext(context) {
6297
+ switch (context.type) {
6298
+ case "ROOM_CONNECTION_ERROR": {
6299
+ switch (context.code) {
6300
+ case 4001:
6301
+ return "Not allowed to connect to the room";
6302
+ case 4005:
6303
+ return "Room is already full";
6304
+ case 4006:
6305
+ return "Kicked out of the room, because the room ID changed";
6306
+ default:
6307
+ return "Could not connect to the room";
6308
+ }
6309
+ }
6310
+ case "CREATE_THREAD_ERROR":
6311
+ return "Could not create new thread";
6312
+ case "DELETE_THREAD_ERROR":
6313
+ return "Could not delete thread";
6314
+ case "EDIT_THREAD_METADATA_ERROR":
6315
+ return "Could not edit thread metadata";
6316
+ case "MARK_THREAD_AS_RESOLVED_ERROR":
6317
+ return "Could not mark thread as resolved";
6318
+ case "MARK_THREAD_AS_UNRESOLVED_ERROR":
6319
+ return "Could not mark thread as unresolved";
6320
+ case "CREATE_COMMENT_ERROR":
6321
+ return "Could not create new comment";
6322
+ case "EDIT_COMMENT_ERROR":
6323
+ return "Could not edit comment";
6324
+ case "DELETE_COMMENT_ERROR":
6325
+ return "Could not delete comment";
6326
+ case "ADD_REACTION_ERROR":
6327
+ return "Could not add reaction";
6328
+ case "REMOVE_REACTION_ERROR":
6329
+ return "Could not remove reaction";
6330
+ case "MARK_INBOX_NOTIFICATION_AS_READ_ERROR":
6331
+ return "Could not mark inbox notification as read";
6332
+ case "DELETE_INBOX_NOTIFICATION_ERROR":
6333
+ return "Could not delete inbox notification";
6334
+ case "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR":
6335
+ return "Could not mark all inbox notifications as read";
6336
+ case "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR":
6337
+ return "Could not delete all inbox notifications";
6338
+ case "UPDATE_NOTIFICATION_SETTINGS_ERROR":
6339
+ return "Could not update notification settings";
6340
+ default:
6341
+ return assertNever(context, "Unhandled case");
6342
+ }
6343
+ }
6344
+
6264
6345
  // src/room.ts
6265
6346
  var MAX_SOCKET_MESSAGE_SIZE = 1024 * 1024 - 1024;
6266
6347
  function makeIdFactory(connectionId) {
@@ -6425,13 +6506,17 @@ function createRoom(options, config) {
6425
6506
  managedSocket.events.statusDidChange.subscribe(handleConnectionLossEvent);
6426
6507
  managedSocket.events.didConnect.subscribe(onDidConnect);
6427
6508
  managedSocket.events.didDisconnect.subscribe(onDidDisconnect);
6428
- managedSocket.events.onLiveblocksError.subscribe((err) => {
6429
- if (process.env.NODE_ENV !== "production") {
6430
- error2(
6431
- `Connection to websocket server closed. Reason: ${err.message} (code: ${err.code}).`
6432
- );
6509
+ managedSocket.events.onConnectionError.subscribe(({ message, code }) => {
6510
+ const type = "ROOM_CONNECTION_ERROR";
6511
+ const err = new LiveblocksError(message, { type, code, roomId });
6512
+ const didNotify = config.errorEventSource.notify(err);
6513
+ if (!didNotify) {
6514
+ if (process.env.NODE_ENV !== "production") {
6515
+ error2(
6516
+ `Connection to websocket server closed. Reason: ${message} (code: ${code}).`
6517
+ );
6518
+ }
6433
6519
  }
6434
- eventHub.error.notify(err);
6435
6520
  });
6436
6521
  const pool = {
6437
6522
  roomId: config.roomId,
@@ -6494,7 +6579,6 @@ function createRoom(options, config) {
6494
6579
  self: makeEventSource(),
6495
6580
  myPresence: makeEventSource(),
6496
6581
  others: makeEventSource(),
6497
- error: makeEventSource(),
6498
6582
  storageBatch: makeEventSource(),
6499
6583
  history: makeEventSource(),
6500
6584
  storageDidLoad: makeEventSource(),
@@ -7334,7 +7418,6 @@ ${Array.from(traces).join("\n\n")}`
7334
7418
  others: eventHub.others.observable,
7335
7419
  self: eventHub.self.observable,
7336
7420
  myPresence: eventHub.myPresence.observable,
7337
- error: eventHub.error.observable,
7338
7421
  /** @deprecated */
7339
7422
  storage: eventHub.storageBatch.observable,
7340
7423
  storageBatch: eventHub.storageBatch.observable,
@@ -7525,7 +7608,11 @@ ${Array.from(traces).join("\n\n")}`
7525
7608
  attachmentUrlsStore: httpClient.getOrCreateAttachmentUrlsStore(roomId)
7526
7609
  },
7527
7610
  id: config.roomId,
7528
- subscribe: makeClassicSubscribeFn(events),
7611
+ subscribe: makeClassicSubscribeFn(
7612
+ config.roomId,
7613
+ events,
7614
+ config.errorEventSource
7615
+ ),
7529
7616
  connect: () => managedSocket.connect(),
7530
7617
  reconnect: () => managedSocket.reconnect(),
7531
7618
  disconnect: () => managedSocket.disconnect(),
@@ -7594,7 +7681,7 @@ ${Array.from(traces).join("\n\n")}`
7594
7681
  { enumerable: false }
7595
7682
  );
7596
7683
  }
7597
- function makeClassicSubscribeFn(events) {
7684
+ function makeClassicSubscribeFn(roomId, events, errorEvents) {
7598
7685
  function subscribeToLiveStructureDeeply(node, callback) {
7599
7686
  return events.storageBatch.subscribe((updates) => {
7600
7687
  const relatedUpdates = updates.filter(
@@ -7634,8 +7721,13 @@ function makeClassicSubscribeFn(events) {
7634
7721
  return cb(others, internalEvent);
7635
7722
  });
7636
7723
  }
7637
- case "error":
7638
- return events.error.subscribe(callback);
7724
+ case "error": {
7725
+ return errorEvents.subscribe((err) => {
7726
+ if (err.roomId === roomId) {
7727
+ return callback(err);
7728
+ }
7729
+ });
7730
+ }
7639
7731
  case "status":
7640
7732
  return events.status.subscribe(callback);
7641
7733
  case "lost-connection":
@@ -7807,6 +7899,7 @@ function createClient(options) {
7807
7899
  },
7808
7900
  enableDebugLogging: clientOptions.enableDebugLogging,
7809
7901
  baseUrl,
7902
+ errorEventSource: liveblocksErrorSource,
7810
7903
  unstable_fallbackToHTTP: !!clientOptions.unstable_fallbackToHTTP,
7811
7904
  unstable_streamData: !!clientOptions.unstable_streamData,
7812
7905
  roomHttpClient: httpClient,
@@ -7889,6 +7982,7 @@ function createClient(options) {
7889
7982
  }
7890
7983
  const syncStatusSources = [];
7891
7984
  const syncStatusSignal = new Signal("synchronized");
7985
+ const liveblocksErrorSource = makeEventSource();
7892
7986
  function getSyncStatus() {
7893
7987
  const status = syncStatusSignal.get();
7894
7988
  return status === "synchronizing" ? status : "synchronized";
@@ -7941,8 +8035,8 @@ function createClient(options) {
7941
8035
  deleteAllInboxNotifications: httpClient.deleteAllInboxNotifications,
7942
8036
  deleteInboxNotification: httpClient.deleteInboxNotification,
7943
8037
  // Public channel notification settings API
7944
- getChannelsNotificationSettings: httpClient.getChannelsNotificationSettings,
7945
- updateChannelsNotificationSettings: httpClient.updateChannelsNotificationSettings,
8038
+ getNotificationSettings: httpClient.getUserNotificationSettings,
8039
+ updateNotificationSettings: httpClient.updateUserNotificationSettings,
7946
8040
  // Advanced resolvers APIs
7947
8041
  resolvers: {
7948
8042
  invalidateUsers: invalidateResolvedUsers,
@@ -7951,6 +8045,7 @@ function createClient(options) {
7951
8045
  },
7952
8046
  getSyncStatus,
7953
8047
  events: {
8048
+ error: liveblocksErrorSource,
7954
8049
  syncStatus: syncStatusSignal
7955
8050
  },
7956
8051
  // Internal
@@ -7966,7 +8061,14 @@ function createClient(options) {
7966
8061
  httpClient,
7967
8062
  // Type-level helper only, it's effectively only an identity-function at runtime
7968
8063
  as: () => client,
7969
- createSyncSource
8064
+ createSyncSource,
8065
+ emitError: (context, cause) => {
8066
+ const error3 = LiveblocksError.from(context, cause);
8067
+ const didNotify = liveblocksErrorSource.notify(error3);
8068
+ if (!didNotify) {
8069
+ error2(error3.message);
8070
+ }
8071
+ }
7970
8072
  }
7971
8073
  },
7972
8074
  kInternal,
@@ -8802,6 +8904,7 @@ function makePoller(callback, intervalMs, options) {
8802
8904
  }
8803
8905
  doc?.addEventListener("visibilitychange", onVisibilityChange);
8804
8906
  win?.addEventListener("online", onVisibilityChange);
8907
+ win?.addEventListener("focus", pollNowIfStale);
8805
8908
  fsm.start();
8806
8909
  return {
8807
8910
  inc,
@@ -8923,9 +9026,9 @@ var SortedList = class _SortedList {
8923
9026
  }
8924
9027
  };
8925
9028
 
8926
- // src/protocol/ChannelsNotificationSettings.ts
8927
- function isChannelNotificationSettingEnabled(setting) {
8928
- return values(setting).every((enabled) => enabled === true);
9029
+ // src/protocol/UserNotificationSettings.ts
9030
+ function isNotificationChannelEnabled(settings) {
9031
+ return values(settings).every((enabled) => enabled === true);
8929
9032
  }
8930
9033
 
8931
9034
  // src/types/Others.ts
@@ -8949,6 +9052,7 @@ export {
8949
9052
  LiveList,
8950
9053
  LiveMap,
8951
9054
  LiveObject,
9055
+ LiveblocksError,
8952
9056
  MutableSignal,
8953
9057
  NotificationsApiError,
8954
9058
  OpCode,
@@ -8989,7 +9093,6 @@ export {
8989
9093
  getMentionedIdsFromCommentBody,
8990
9094
  html,
8991
9095
  htmlSafe,
8992
- isChannelNotificationSettingEnabled,
8993
9096
  isChildCrdt,
8994
9097
  isCommentBodyLink,
8995
9098
  isCommentBodyMention,
@@ -8998,6 +9101,7 @@ export {
8998
9101
  isJsonObject,
8999
9102
  isJsonScalar,
9000
9103
  isLiveNode,
9104
+ isNotificationChannelEnabled,
9001
9105
  isPlainObject,
9002
9106
  isRootCrdt,
9003
9107
  isStartsWithOperator,
@@ -9023,7 +9127,6 @@ export {
9023
9127
  toAbsoluteUrl,
9024
9128
  toPlainLson,
9025
9129
  tryParseJson,
9026
- unstringify,
9027
9130
  url,
9028
9131
  urljoin,
9029
9132
  wait,