@liveblocks/core 2.5.1 → 2.7.0-beta1

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.js 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.5.1";
9
+ var PKG_VERSION = "2.7.0-beta1";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -1859,8 +1859,7 @@ var Batch = class {
1859
1859
  this.clearDelayTimeout();
1860
1860
  }
1861
1861
  };
1862
- function createBatchStore(callback, options) {
1863
- const batch = new Batch(callback, options);
1862
+ function createBatchStore(batch) {
1864
1863
  const cache = /* @__PURE__ */ new Map();
1865
1864
  const eventSource2 = makeEventSource();
1866
1865
  function getCacheKey(args) {
@@ -4749,9 +4748,19 @@ function findNonSerializableValue(value, path = "") {
4749
4748
  return false;
4750
4749
  }
4751
4750
 
4751
+ // src/lib/chunk.ts
4752
+ function chunk(array, size) {
4753
+ const chunks = [];
4754
+ for (let i = 0, j = array.length; i < j; i += size) {
4755
+ chunks.push(array.slice(i, i + size));
4756
+ }
4757
+ return chunks;
4758
+ }
4759
+
4752
4760
  // src/lib/createIds.ts
4753
4761
  var THREAD_ID_PREFIX = "th";
4754
4762
  var COMMENT_ID_PREFIX = "cm";
4763
+ var COMMENT_ATTACHMENT_ID_PREFIX = "at";
4755
4764
  var INBOX_NOTIFICATION_ID_PREFIX = "in";
4756
4765
  function createOptimisticId(prefix) {
4757
4766
  return `${prefix}_${nanoid()}`;
@@ -4762,6 +4771,9 @@ function createThreadId() {
4762
4771
  function createCommentId() {
4763
4772
  return createOptimisticId(COMMENT_ID_PREFIX);
4764
4773
  }
4774
+ function createCommentAttachmentId() {
4775
+ return createOptimisticId(COMMENT_ATTACHMENT_ID_PREFIX);
4776
+ }
4765
4777
  function createInboxNotificationId() {
4766
4778
  return createOptimisticId(INBOX_NOTIFICATION_ID_PREFIX);
4767
4779
  }
@@ -5164,6 +5176,22 @@ function installBackgroundTabSpy() {
5164
5176
  };
5165
5177
  return [inBackgroundSince, unsub];
5166
5178
  }
5179
+ var GET_ATTACHMENT_URLS_BATCH_DELAY = 50;
5180
+ var ATTACHMENT_PART_SIZE = 5 * 1024 * 1024;
5181
+ var ATTACHMENT_PART_BATCH_SIZE = 5;
5182
+ function splitFileIntoParts(file) {
5183
+ const parts = [];
5184
+ let start = 0;
5185
+ while (start < file.size) {
5186
+ const end = Math.min(start + ATTACHMENT_PART_SIZE, file.size);
5187
+ parts.push({
5188
+ partNumber: parts.length + 1,
5189
+ part: file.slice(start, end)
5190
+ });
5191
+ start = end;
5192
+ }
5193
+ return parts;
5194
+ }
5167
5195
  var CommentsApiError = class extends Error {
5168
5196
  constructor(message, status, details) {
5169
5197
  super(message);
@@ -5172,297 +5200,6 @@ var CommentsApiError = class extends Error {
5172
5200
  this.details = details;
5173
5201
  }
5174
5202
  };
5175
- function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
5176
- async function fetchCommentsApi(endpoint, params, options) {
5177
- const authValue = await getAuthValue();
5178
- return fetchClientApi(roomId, endpoint, authValue, options, params);
5179
- }
5180
- async function fetchJson(endpoint, options, params) {
5181
- const response = await fetchCommentsApi(endpoint, params, options);
5182
- if (!response.ok) {
5183
- if (response.status >= 400 && response.status < 600) {
5184
- let error3;
5185
- try {
5186
- const errorBody = await response.json();
5187
- error3 = new CommentsApiError(
5188
- errorBody.message,
5189
- response.status,
5190
- errorBody
5191
- );
5192
- } catch (e5) {
5193
- error3 = new CommentsApiError(response.statusText, response.status);
5194
- }
5195
- throw error3;
5196
- }
5197
- }
5198
- let body;
5199
- try {
5200
- body = await response.json();
5201
- } catch (e6) {
5202
- body = {};
5203
- }
5204
- return body;
5205
- }
5206
- async function getThreadsSince(options) {
5207
- const response = await fetchCommentsApi(
5208
- "/threads",
5209
- {
5210
- since: _optionalChain([options, 'optionalAccess', _119 => _119.since, 'optionalAccess', _120 => _120.toISOString, 'call', _121 => _121()])
5211
- },
5212
- {
5213
- headers: {
5214
- "Content-Type": "application/json"
5215
- }
5216
- }
5217
- );
5218
- if (response.ok) {
5219
- const json = await response.json();
5220
- return {
5221
- threads: {
5222
- updated: json.data.map(convertToThreadData),
5223
- deleted: json.deletedThreads.map(convertToThreadDeleteInfo)
5224
- },
5225
- inboxNotifications: {
5226
- updated: json.inboxNotifications.map(convertToInboxNotificationData),
5227
- deleted: json.deletedInboxNotifications.map(
5228
- convertToInboxNotificationDeleteInfo
5229
- )
5230
- },
5231
- requestedAt: new Date(json.meta.requestedAt)
5232
- };
5233
- } else if (response.status === 404) {
5234
- return {
5235
- threads: {
5236
- updated: [],
5237
- deleted: []
5238
- },
5239
- inboxNotifications: {
5240
- updated: [],
5241
- deleted: []
5242
- },
5243
- requestedAt: /* @__PURE__ */ new Date()
5244
- };
5245
- } else {
5246
- throw new Error("There was an error while getting threads.");
5247
- }
5248
- }
5249
- async function getThreads(options) {
5250
- let query;
5251
- if (_optionalChain([options, 'optionalAccess', _122 => _122.query])) {
5252
- query = objectToQuery(options.query);
5253
- }
5254
- const response = await fetchCommentsApi(
5255
- "/threads",
5256
- {
5257
- query
5258
- },
5259
- {
5260
- headers: {
5261
- "Content-Type": "application/json"
5262
- }
5263
- }
5264
- );
5265
- if (response.ok) {
5266
- const json = await response.json();
5267
- return {
5268
- threads: json.data.map(convertToThreadData),
5269
- inboxNotifications: json.inboxNotifications.map(
5270
- convertToInboxNotificationData
5271
- ),
5272
- requestedAt: new Date(json.meta.requestedAt)
5273
- };
5274
- } else if (response.status === 404) {
5275
- return {
5276
- threads: [],
5277
- inboxNotifications: [],
5278
- deletedThreads: [],
5279
- deletedInboxNotifications: [],
5280
- requestedAt: /* @__PURE__ */ new Date()
5281
- };
5282
- } else {
5283
- throw new Error("There was an error while getting threads.");
5284
- }
5285
- }
5286
- async function getThread(threadId) {
5287
- const response = await fetchCommentsApi(
5288
- `/thread-with-notification/${threadId}`
5289
- );
5290
- if (response.ok) {
5291
- const json = await response.json();
5292
- return {
5293
- thread: convertToThreadData(json.thread),
5294
- inboxNotification: json.inboxNotification ? convertToInboxNotificationData(json.inboxNotification) : void 0
5295
- };
5296
- } else if (response.status === 404) {
5297
- return {
5298
- thread: void 0,
5299
- inboxNotification: void 0
5300
- };
5301
- } else {
5302
- throw new Error(`There was an error while getting thread ${threadId}.`);
5303
- }
5304
- }
5305
- async function createThread({
5306
- metadata,
5307
- body,
5308
- commentId = createCommentId(),
5309
- threadId = createThreadId()
5310
- }) {
5311
- const thread = await fetchJson("/threads", {
5312
- method: "POST",
5313
- headers: {
5314
- "Content-Type": "application/json"
5315
- },
5316
- body: JSON.stringify({
5317
- id: threadId,
5318
- comment: {
5319
- id: commentId,
5320
- body
5321
- },
5322
- metadata
5323
- })
5324
- });
5325
- return convertToThreadData(thread);
5326
- }
5327
- async function deleteThread(threadId) {
5328
- await fetchJson(`/threads/${encodeURIComponent(threadId)}`, {
5329
- method: "DELETE"
5330
- });
5331
- }
5332
- async function editThreadMetadata({
5333
- metadata,
5334
- threadId
5335
- }) {
5336
- return await fetchJson(
5337
- `/threads/${encodeURIComponent(threadId)}/metadata`,
5338
- {
5339
- method: "POST",
5340
- headers: {
5341
- "Content-Type": "application/json"
5342
- },
5343
- body: JSON.stringify(metadata)
5344
- }
5345
- );
5346
- }
5347
- async function markThreadAsResolved(threadId) {
5348
- await fetchJson(
5349
- `/threads/${encodeURIComponent(threadId)}/mark-as-resolved`,
5350
- {
5351
- method: "POST"
5352
- }
5353
- );
5354
- }
5355
- async function markThreadAsUnresolved(threadId) {
5356
- await fetchJson(
5357
- `/threads/${encodeURIComponent(threadId)}/mark-as-unresolved`,
5358
- {
5359
- method: "POST"
5360
- }
5361
- );
5362
- }
5363
- async function createComment({
5364
- threadId,
5365
- commentId = createCommentId(),
5366
- body
5367
- }) {
5368
- const comment = await fetchJson(
5369
- `/threads/${encodeURIComponent(threadId)}/comments`,
5370
- {
5371
- method: "POST",
5372
- headers: {
5373
- "Content-Type": "application/json"
5374
- },
5375
- body: JSON.stringify({
5376
- id: commentId,
5377
- body
5378
- })
5379
- }
5380
- );
5381
- return convertToCommentData(comment);
5382
- }
5383
- async function editComment({
5384
- threadId,
5385
- commentId,
5386
- body
5387
- }) {
5388
- const comment = await fetchJson(
5389
- `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
5390
- commentId
5391
- )}`,
5392
- {
5393
- method: "POST",
5394
- headers: {
5395
- "Content-Type": "application/json"
5396
- },
5397
- body: JSON.stringify({
5398
- body
5399
- })
5400
- }
5401
- );
5402
- return convertToCommentData(comment);
5403
- }
5404
- async function deleteComment2({
5405
- threadId,
5406
- commentId
5407
- }) {
5408
- await fetchJson(
5409
- `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
5410
- commentId
5411
- )}`,
5412
- {
5413
- method: "DELETE"
5414
- }
5415
- );
5416
- }
5417
- async function addReaction2({
5418
- threadId,
5419
- commentId,
5420
- emoji
5421
- }) {
5422
- const reaction = await fetchJson(
5423
- `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
5424
- commentId
5425
- )}/reactions`,
5426
- {
5427
- method: "POST",
5428
- headers: {
5429
- "Content-Type": "application/json"
5430
- },
5431
- body: JSON.stringify({ emoji })
5432
- }
5433
- );
5434
- return convertToCommentUserReaction(reaction);
5435
- }
5436
- async function removeReaction2({
5437
- threadId,
5438
- commentId,
5439
- emoji
5440
- }) {
5441
- await fetchJson(
5442
- `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
5443
- commentId
5444
- )}/reactions/${encodeURIComponent(emoji)}`,
5445
- {
5446
- method: "DELETE"
5447
- }
5448
- );
5449
- }
5450
- return {
5451
- getThreads,
5452
- getThreadsSince,
5453
- getThread,
5454
- createThread,
5455
- deleteThread,
5456
- editThreadMetadata,
5457
- markThreadAsResolved,
5458
- markThreadAsUnresolved,
5459
- createComment,
5460
- editComment,
5461
- deleteComment: deleteComment2,
5462
- addReaction: addReaction2,
5463
- removeReaction: removeReaction2
5464
- };
5465
- }
5466
5203
  var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 = 50;
5467
5204
  function createRoom(options, config) {
5468
5205
  const initialPresence = options.initialPresence;
@@ -5654,7 +5391,7 @@ function createRoom(options, config) {
5654
5391
  }
5655
5392
  },
5656
5393
  assertStorageIsWritable: () => {
5657
- const scopes = _optionalChain([context, 'access', _123 => _123.dynamicSessionInfo, 'access', _124 => _124.current, 'optionalAccess', _125 => _125.scopes]);
5394
+ const scopes = _optionalChain([context, 'access', _119 => _119.dynamicSessionInfo, 'access', _120 => _120.current, 'optionalAccess', _121 => _121.scopes]);
5658
5395
  if (scopes === void 0) {
5659
5396
  return;
5660
5397
  }
@@ -5688,12 +5425,12 @@ function createRoom(options, config) {
5688
5425
  `/v2/c/rooms/${encodeURIComponent(roomId)}${endpoint}`,
5689
5426
  params
5690
5427
  );
5691
- const fetcher = _optionalChain([config, 'access', _126 => _126.polyfills, 'optionalAccess', _127 => _127.fetch]) || /* istanbul ignore next */
5428
+ const fetcher = _optionalChain([config, 'access', _122 => _122.polyfills, 'optionalAccess', _123 => _123.fetch]) || /* istanbul ignore next */
5692
5429
  fetch;
5693
5430
  return await fetcher(url, {
5694
5431
  ...options2,
5695
5432
  headers: {
5696
- ..._optionalChain([options2, 'optionalAccess', _128 => _128.headers]),
5433
+ ..._optionalChain([options2, 'optionalAccess', _124 => _124.headers]),
5697
5434
  Authorization: `Bearer ${getAuthBearerHeaderFromAuthValue(authValue)}`
5698
5435
  }
5699
5436
  });
@@ -5766,7 +5503,7 @@ function createRoom(options, config) {
5766
5503
  }
5767
5504
  function sendMessages(messages) {
5768
5505
  const serializedPayload = JSON.stringify(messages);
5769
- const nonce = _optionalChain([context, 'access', _129 => _129.dynamicSessionInfo, 'access', _130 => _130.current, 'optionalAccess', _131 => _131.nonce]);
5506
+ const nonce = _optionalChain([context, 'access', _125 => _125.dynamicSessionInfo, 'access', _126 => _126.current, 'optionalAccess', _127 => _127.nonce]);
5770
5507
  if (config.unstable_fallbackToHTTP && nonce) {
5771
5508
  const size = new TextEncoder().encode(serializedPayload).length;
5772
5509
  if (size > MAX_SOCKET_MESSAGE_SIZE) {
@@ -5828,7 +5565,7 @@ function createRoom(options, config) {
5828
5565
  } else {
5829
5566
  context.root = LiveObject._fromItems(message.items, pool);
5830
5567
  }
5831
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _132 => _132.current, 'optionalAccess', _133 => _133.canWrite]), () => ( true));
5568
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _128 => _128.current, 'optionalAccess', _129 => _129.canWrite]), () => ( true));
5832
5569
  const stackSizeBefore = context.undoStack.length;
5833
5570
  for (const key in context.initialStorage) {
5834
5571
  if (context.root.get(key) === void 0) {
@@ -6033,7 +5770,7 @@ function createRoom(options, config) {
6033
5770
  }
6034
5771
  context.myPresence.patch(patch);
6035
5772
  if (context.activeBatch) {
6036
- if (_optionalChain([options2, 'optionalAccess', _134 => _134.addToHistory])) {
5773
+ if (_optionalChain([options2, 'optionalAccess', _130 => _130.addToHistory])) {
6037
5774
  context.activeBatch.reverseOps.unshift({
6038
5775
  type: "presence",
6039
5776
  data: oldValues
@@ -6043,7 +5780,7 @@ function createRoom(options, config) {
6043
5780
  } else {
6044
5781
  flushNowOrSoon();
6045
5782
  batchUpdates(() => {
6046
- if (_optionalChain([options2, 'optionalAccess', _135 => _135.addToHistory])) {
5783
+ if (_optionalChain([options2, 'optionalAccess', _131 => _131.addToHistory])) {
6047
5784
  addToUndoStack(
6048
5785
  [{ type: "presence", data: oldValues }],
6049
5786
  doNotBatchUpdates
@@ -6241,7 +5978,7 @@ function createRoom(options, config) {
6241
5978
  if (process.env.NODE_ENV !== "production") {
6242
5979
  const traces = /* @__PURE__ */ new Set();
6243
5980
  for (const opId of message.opIds) {
6244
- const trace = _optionalChain([context, 'access', _136 => _136.opStackTraces, 'optionalAccess', _137 => _137.get, 'call', _138 => _138(opId)]);
5981
+ const trace = _optionalChain([context, 'access', _132 => _132.opStackTraces, 'optionalAccess', _133 => _133.get, 'call', _134 => _134(opId)]);
6245
5982
  if (trace) {
6246
5983
  traces.add(trace);
6247
5984
  }
@@ -6375,7 +6112,7 @@ ${Array.from(traces).join("\n\n")}`
6375
6112
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
6376
6113
  createOrUpdateRootFromMessage(message, doNotBatchUpdates);
6377
6114
  applyAndSendOps(unacknowledgedOps, doNotBatchUpdates);
6378
- _optionalChain([_resolveStoragePromise, 'optionalCall', _139 => _139()]);
6115
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _135 => _135()]);
6379
6116
  notifyStorageStatus();
6380
6117
  eventHub.storageDidLoad.notify();
6381
6118
  }
@@ -6477,126 +6214,521 @@ ${Array.from(traces).join("\n\n")}`
6477
6214
  context.undoStack.push(result.reverse);
6478
6215
  onHistoryChange(doNotBatchUpdates);
6479
6216
  });
6480
- for (const op of result.ops) {
6481
- if (op.type !== "presence") {
6482
- context.buffer.storageOperations.push(op);
6483
- }
6484
- }
6485
- flushNowOrSoon();
6217
+ for (const op of result.ops) {
6218
+ if (op.type !== "presence") {
6219
+ context.buffer.storageOperations.push(op);
6220
+ }
6221
+ }
6222
+ flushNowOrSoon();
6223
+ }
6224
+ function clear() {
6225
+ context.undoStack.length = 0;
6226
+ context.redoStack.length = 0;
6227
+ }
6228
+ function batch(callback) {
6229
+ if (context.activeBatch) {
6230
+ return callback();
6231
+ }
6232
+ let returnValue = void 0;
6233
+ batchUpdates(() => {
6234
+ context.activeBatch = {
6235
+ ops: [],
6236
+ updates: {
6237
+ storageUpdates: /* @__PURE__ */ new Map(),
6238
+ presence: false,
6239
+ others: []
6240
+ },
6241
+ reverseOps: []
6242
+ };
6243
+ try {
6244
+ returnValue = callback();
6245
+ } finally {
6246
+ const currentBatch = context.activeBatch;
6247
+ context.activeBatch = null;
6248
+ if (currentBatch.reverseOps.length > 0) {
6249
+ addToUndoStack(currentBatch.reverseOps, doNotBatchUpdates);
6250
+ }
6251
+ if (currentBatch.ops.length > 0) {
6252
+ context.redoStack.length = 0;
6253
+ }
6254
+ if (currentBatch.ops.length > 0) {
6255
+ dispatchOps(currentBatch.ops);
6256
+ }
6257
+ notify(currentBatch.updates, doNotBatchUpdates);
6258
+ flushNowOrSoon();
6259
+ }
6260
+ });
6261
+ return returnValue;
6262
+ }
6263
+ function pauseHistory() {
6264
+ if (context.pausedHistory === null) {
6265
+ context.pausedHistory = [];
6266
+ }
6267
+ }
6268
+ function resumeHistory() {
6269
+ const historyOps = context.pausedHistory;
6270
+ context.pausedHistory = null;
6271
+ if (historyOps !== null && historyOps.length > 0) {
6272
+ _addToRealUndoStack(historyOps, batchUpdates);
6273
+ }
6274
+ }
6275
+ function getStorageStatus() {
6276
+ if (context.root === void 0) {
6277
+ return _getStorage$ === null ? "not-loaded" : "loading";
6278
+ } else {
6279
+ return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
6280
+ }
6281
+ }
6282
+ let _lastStorageStatus = getStorageStatus();
6283
+ function notifyStorageStatus() {
6284
+ const storageStatus = getStorageStatus();
6285
+ if (_lastStorageStatus !== storageStatus) {
6286
+ _lastStorageStatus = storageStatus;
6287
+ eventHub.storageStatus.notify(storageStatus);
6288
+ }
6289
+ }
6290
+ function isPresenceReady() {
6291
+ return self.current !== null;
6292
+ }
6293
+ async function waitUntilPresenceReady() {
6294
+ while (!isPresenceReady()) {
6295
+ const { promise, resolve } = Promise_withResolvers();
6296
+ const unsub1 = events.self.subscribeOnce(resolve);
6297
+ const unsub2 = events.status.subscribeOnce(resolve);
6298
+ await promise;
6299
+ unsub1();
6300
+ unsub2();
6301
+ }
6302
+ }
6303
+ function isStorageReady() {
6304
+ return getStorageSnapshot() !== null;
6305
+ }
6306
+ async function waitUntilStorageReady() {
6307
+ while (!isStorageReady()) {
6308
+ await getStorage();
6309
+ }
6310
+ }
6311
+ const others_forDevTools = new DerivedRef(
6312
+ context.others,
6313
+ (others) => others.map((other, index) => userToTreeNode(`Other ${index}`, other))
6314
+ );
6315
+ const events = {
6316
+ status: eventHub.status.observable,
6317
+ lostConnection: eventHub.lostConnection.observable,
6318
+ customEvent: eventHub.customEvent.observable,
6319
+ others: eventHub.others.observable,
6320
+ self: eventHub.self.observable,
6321
+ myPresence: eventHub.myPresence.observable,
6322
+ error: eventHub.error.observable,
6323
+ /** @deprecated */
6324
+ storage: eventHub.storageBatch.observable,
6325
+ storageBatch: eventHub.storageBatch.observable,
6326
+ history: eventHub.history.observable,
6327
+ storageDidLoad: eventHub.storageDidLoad.observable,
6328
+ storageStatus: eventHub.storageStatus.observable,
6329
+ ydoc: eventHub.ydoc.observable,
6330
+ comments: eventHub.comments.observable
6331
+ };
6332
+ async function fetchCommentsApi(endpoint, params, options2) {
6333
+ const authValue = await delegates.authenticate();
6334
+ return fetchClientApi(config.roomId, endpoint, authValue, options2, params);
6335
+ }
6336
+ async function fetchCommentsJson(endpoint, options2, params) {
6337
+ const response = await fetchCommentsApi(endpoint, params, options2);
6338
+ if (!response.ok) {
6339
+ if (response.status >= 400 && response.status < 600) {
6340
+ let error3;
6341
+ try {
6342
+ const errorBody = await response.json();
6343
+ error3 = new CommentsApiError(
6344
+ errorBody.message,
6345
+ response.status,
6346
+ errorBody
6347
+ );
6348
+ } catch (e5) {
6349
+ error3 = new CommentsApiError(response.statusText, response.status);
6350
+ }
6351
+ throw error3;
6352
+ }
6353
+ }
6354
+ let body;
6355
+ try {
6356
+ body = await response.json();
6357
+ } catch (e6) {
6358
+ body = {};
6359
+ }
6360
+ return body;
6361
+ }
6362
+ async function getThreadsSince(options2) {
6363
+ const response = await fetchCommentsApi(
6364
+ "/threads",
6365
+ {
6366
+ since: _optionalChain([options2, 'optionalAccess', _136 => _136.since, 'optionalAccess', _137 => _137.toISOString, 'call', _138 => _138()])
6367
+ },
6368
+ {
6369
+ headers: {
6370
+ "Content-Type": "application/json"
6371
+ }
6372
+ }
6373
+ );
6374
+ if (response.ok) {
6375
+ const json = await response.json();
6376
+ return {
6377
+ threads: {
6378
+ updated: json.data.map(convertToThreadData),
6379
+ deleted: json.deletedThreads.map(convertToThreadDeleteInfo)
6380
+ },
6381
+ inboxNotifications: {
6382
+ updated: json.inboxNotifications.map(convertToInboxNotificationData),
6383
+ deleted: json.deletedInboxNotifications.map(
6384
+ convertToInboxNotificationDeleteInfo
6385
+ )
6386
+ },
6387
+ requestedAt: new Date(json.meta.requestedAt)
6388
+ };
6389
+ } else if (response.status === 404) {
6390
+ return {
6391
+ threads: {
6392
+ updated: [],
6393
+ deleted: []
6394
+ },
6395
+ inboxNotifications: {
6396
+ updated: [],
6397
+ deleted: []
6398
+ },
6399
+ requestedAt: /* @__PURE__ */ new Date()
6400
+ };
6401
+ } else {
6402
+ throw new Error("There was an error while getting threads.");
6403
+ }
6404
+ }
6405
+ async function getThreads(options2) {
6406
+ let query;
6407
+ if (_optionalChain([options2, 'optionalAccess', _139 => _139.query])) {
6408
+ query = objectToQuery(options2.query);
6409
+ }
6410
+ const response = await fetchCommentsApi(
6411
+ "/threads",
6412
+ {
6413
+ query
6414
+ },
6415
+ {
6416
+ headers: {
6417
+ "Content-Type": "application/json"
6418
+ }
6419
+ }
6420
+ );
6421
+ if (response.ok) {
6422
+ const json = await response.json();
6423
+ return {
6424
+ threads: json.data.map(convertToThreadData),
6425
+ inboxNotifications: json.inboxNotifications.map(
6426
+ convertToInboxNotificationData
6427
+ ),
6428
+ requestedAt: new Date(json.meta.requestedAt)
6429
+ };
6430
+ } else if (response.status === 404) {
6431
+ return {
6432
+ threads: [],
6433
+ inboxNotifications: [],
6434
+ deletedThreads: [],
6435
+ deletedInboxNotifications: [],
6436
+ requestedAt: /* @__PURE__ */ new Date()
6437
+ };
6438
+ } else {
6439
+ throw new Error("There was an error while getting threads.");
6440
+ }
6441
+ }
6442
+ async function getThread(threadId) {
6443
+ const response = await fetchCommentsApi(
6444
+ `/thread-with-notification/${threadId}`
6445
+ );
6446
+ if (response.ok) {
6447
+ const json = await response.json();
6448
+ return {
6449
+ thread: convertToThreadData(json.thread),
6450
+ inboxNotification: json.inboxNotification ? convertToInboxNotificationData(json.inboxNotification) : void 0
6451
+ };
6452
+ } else if (response.status === 404) {
6453
+ return {
6454
+ thread: void 0,
6455
+ inboxNotification: void 0
6456
+ };
6457
+ } else {
6458
+ throw new Error(`There was an error while getting thread ${threadId}.`);
6459
+ }
6460
+ }
6461
+ async function createThread({
6462
+ metadata,
6463
+ body,
6464
+ commentId = createCommentId(),
6465
+ threadId = createThreadId(),
6466
+ attachmentIds
6467
+ }) {
6468
+ const thread = await fetchCommentsJson("/threads", {
6469
+ method: "POST",
6470
+ headers: {
6471
+ "Content-Type": "application/json"
6472
+ },
6473
+ body: JSON.stringify({
6474
+ id: threadId,
6475
+ comment: {
6476
+ id: commentId,
6477
+ body,
6478
+ attachmentIds
6479
+ },
6480
+ metadata
6481
+ })
6482
+ });
6483
+ return convertToThreadData(thread);
6486
6484
  }
6487
- function clear() {
6488
- context.undoStack.length = 0;
6489
- context.redoStack.length = 0;
6485
+ async function deleteThread(threadId) {
6486
+ await fetchCommentsJson(`/threads/${encodeURIComponent(threadId)}`, {
6487
+ method: "DELETE"
6488
+ });
6490
6489
  }
6491
- function batch(callback) {
6492
- if (context.activeBatch) {
6493
- return callback();
6494
- }
6495
- let returnValue = void 0;
6496
- batchUpdates(() => {
6497
- context.activeBatch = {
6498
- ops: [],
6499
- updates: {
6500
- storageUpdates: /* @__PURE__ */ new Map(),
6501
- presence: false,
6502
- others: []
6490
+ async function editThreadMetadata({
6491
+ metadata,
6492
+ threadId
6493
+ }) {
6494
+ return await fetchCommentsJson(
6495
+ `/threads/${encodeURIComponent(threadId)}/metadata`,
6496
+ {
6497
+ method: "POST",
6498
+ headers: {
6499
+ "Content-Type": "application/json"
6503
6500
  },
6504
- reverseOps: []
6505
- };
6506
- try {
6507
- returnValue = callback();
6508
- } finally {
6509
- const currentBatch = context.activeBatch;
6510
- context.activeBatch = null;
6511
- if (currentBatch.reverseOps.length > 0) {
6512
- addToUndoStack(currentBatch.reverseOps, doNotBatchUpdates);
6513
- }
6514
- if (currentBatch.ops.length > 0) {
6515
- context.redoStack.length = 0;
6516
- }
6517
- if (currentBatch.ops.length > 0) {
6518
- dispatchOps(currentBatch.ops);
6519
- }
6520
- notify(currentBatch.updates, doNotBatchUpdates);
6521
- flushNowOrSoon();
6501
+ body: JSON.stringify(metadata)
6522
6502
  }
6523
- });
6524
- return returnValue;
6503
+ );
6525
6504
  }
6526
- function pauseHistory() {
6527
- if (context.pausedHistory === null) {
6528
- context.pausedHistory = [];
6529
- }
6505
+ async function markThreadAsResolved(threadId) {
6506
+ await fetchCommentsJson(
6507
+ `/threads/${encodeURIComponent(threadId)}/mark-as-resolved`,
6508
+ {
6509
+ method: "POST"
6510
+ }
6511
+ );
6530
6512
  }
6531
- function resumeHistory() {
6532
- const historyOps = context.pausedHistory;
6533
- context.pausedHistory = null;
6534
- if (historyOps !== null && historyOps.length > 0) {
6535
- _addToRealUndoStack(historyOps, batchUpdates);
6536
- }
6513
+ async function markThreadAsUnresolved(threadId) {
6514
+ await fetchCommentsJson(
6515
+ `/threads/${encodeURIComponent(threadId)}/mark-as-unresolved`,
6516
+ {
6517
+ method: "POST"
6518
+ }
6519
+ );
6537
6520
  }
6538
- function getStorageStatus() {
6539
- if (context.root === void 0) {
6540
- return _getStorage$ === null ? "not-loaded" : "loading";
6541
- } else {
6542
- return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
6543
- }
6521
+ async function createComment({
6522
+ threadId,
6523
+ commentId = createCommentId(),
6524
+ body,
6525
+ attachmentIds
6526
+ }) {
6527
+ const comment = await fetchCommentsJson(
6528
+ `/threads/${encodeURIComponent(threadId)}/comments`,
6529
+ {
6530
+ method: "POST",
6531
+ headers: {
6532
+ "Content-Type": "application/json"
6533
+ },
6534
+ body: JSON.stringify({
6535
+ id: commentId,
6536
+ body,
6537
+ attachmentIds
6538
+ })
6539
+ }
6540
+ );
6541
+ return convertToCommentData(comment);
6544
6542
  }
6545
- let _lastStorageStatus = getStorageStatus();
6546
- function notifyStorageStatus() {
6547
- const storageStatus = getStorageStatus();
6548
- if (_lastStorageStatus !== storageStatus) {
6549
- _lastStorageStatus = storageStatus;
6550
- eventHub.storageStatus.notify(storageStatus);
6551
- }
6543
+ async function editComment({
6544
+ threadId,
6545
+ commentId,
6546
+ body,
6547
+ attachmentIds
6548
+ }) {
6549
+ const comment = await fetchCommentsJson(
6550
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
6551
+ commentId
6552
+ )}`,
6553
+ {
6554
+ method: "POST",
6555
+ headers: {
6556
+ "Content-Type": "application/json"
6557
+ },
6558
+ body: JSON.stringify({
6559
+ body,
6560
+ attachmentIds
6561
+ })
6562
+ }
6563
+ );
6564
+ return convertToCommentData(comment);
6552
6565
  }
6553
- function isPresenceReady() {
6554
- return self.current !== null;
6566
+ async function deleteComment2({
6567
+ threadId,
6568
+ commentId
6569
+ }) {
6570
+ await fetchCommentsJson(
6571
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
6572
+ commentId
6573
+ )}`,
6574
+ {
6575
+ method: "DELETE"
6576
+ }
6577
+ );
6555
6578
  }
6556
- async function waitUntilPresenceReady() {
6557
- while (!isPresenceReady()) {
6558
- const { promise, resolve } = Promise_withResolvers();
6559
- const unsub1 = events.self.subscribeOnce(resolve);
6560
- const unsub2 = events.status.subscribeOnce(resolve);
6561
- await promise;
6562
- unsub1();
6563
- unsub2();
6564
- }
6579
+ async function addReaction2({
6580
+ threadId,
6581
+ commentId,
6582
+ emoji
6583
+ }) {
6584
+ const reaction = await fetchCommentsJson(
6585
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
6586
+ commentId
6587
+ )}/reactions`,
6588
+ {
6589
+ method: "POST",
6590
+ headers: {
6591
+ "Content-Type": "application/json"
6592
+ },
6593
+ body: JSON.stringify({ emoji })
6594
+ }
6595
+ );
6596
+ return convertToCommentUserReaction(reaction);
6565
6597
  }
6566
- function isStorageReady() {
6567
- return getStorageSnapshot() !== null;
6598
+ async function removeReaction2({
6599
+ threadId,
6600
+ commentId,
6601
+ emoji
6602
+ }) {
6603
+ await fetchCommentsJson(
6604
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
6605
+ commentId
6606
+ )}/reactions/${encodeURIComponent(emoji)}`,
6607
+ {
6608
+ method: "DELETE"
6609
+ }
6610
+ );
6568
6611
  }
6569
- async function waitUntilStorageReady() {
6570
- while (!isStorageReady()) {
6571
- await getStorage();
6612
+ function prepareAttachment(file) {
6613
+ return {
6614
+ type: "localAttachment",
6615
+ status: "idle",
6616
+ id: createCommentAttachmentId(),
6617
+ name: file.name,
6618
+ size: file.size,
6619
+ mimeType: file.type,
6620
+ file
6621
+ };
6622
+ }
6623
+ async function uploadAttachment(attachment, options2 = {}) {
6624
+ const abortSignal = options2.signal;
6625
+ const abortError = abortSignal ? new DOMException(
6626
+ `Upload of attachment ${attachment.id} was aborted.`,
6627
+ "AbortError"
6628
+ ) : void 0;
6629
+ if (_optionalChain([abortSignal, 'optionalAccess', _140 => _140.aborted])) {
6630
+ throw abortError;
6631
+ }
6632
+ if (attachment.size <= ATTACHMENT_PART_SIZE) {
6633
+ return fetchCommentsJson(
6634
+ `/attachments/${encodeURIComponent(attachment.id)}/upload/${encodeURIComponent(attachment.name)}`,
6635
+ {
6636
+ method: "PUT",
6637
+ body: attachment.file,
6638
+ signal: abortSignal
6639
+ }
6640
+ );
6641
+ } else {
6642
+ let uploadId;
6643
+ const uploadedParts = [];
6644
+ try {
6645
+ const createMultiPartUpload = await fetchCommentsJson(
6646
+ `/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(attachment.name)}`,
6647
+ {
6648
+ method: "POST",
6649
+ signal: abortSignal
6650
+ }
6651
+ );
6652
+ uploadId = createMultiPartUpload.uploadId;
6653
+ const parts = splitFileIntoParts(attachment.file);
6654
+ if (_optionalChain([abortSignal, 'optionalAccess', _141 => _141.aborted])) {
6655
+ throw abortError;
6656
+ }
6657
+ const batches = chunk(parts, ATTACHMENT_PART_BATCH_SIZE);
6658
+ for (const parts2 of batches) {
6659
+ const uploadedPartsPromises = [];
6660
+ for (const { part, partNumber } of parts2) {
6661
+ uploadedPartsPromises.push(
6662
+ fetchCommentsJson(
6663
+ `/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/${encodeURIComponent(partNumber)}`,
6664
+ {
6665
+ method: "PUT",
6666
+ body: part,
6667
+ signal: abortSignal
6668
+ }
6669
+ )
6670
+ );
6671
+ }
6672
+ uploadedParts.push(...await Promise.all(uploadedPartsPromises));
6673
+ }
6674
+ if (_optionalChain([abortSignal, 'optionalAccess', _142 => _142.aborted])) {
6675
+ throw abortError;
6676
+ }
6677
+ const sortedUploadedParts = uploadedParts.sort(
6678
+ (a, b) => a.partNumber - b.partNumber
6679
+ );
6680
+ return fetchCommentsJson(
6681
+ `/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/complete`,
6682
+ {
6683
+ method: "POST",
6684
+ headers: {
6685
+ "Content-Type": "application/json"
6686
+ },
6687
+ body: JSON.stringify({ parts: sortedUploadedParts }),
6688
+ signal: abortSignal
6689
+ }
6690
+ );
6691
+ } catch (error3) {
6692
+ if (uploadId && _optionalChain([error3, 'optionalAccess', _143 => _143.name]) && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
6693
+ await fetchCommentsApi(
6694
+ `/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}`,
6695
+ void 0,
6696
+ {
6697
+ method: "DELETE"
6698
+ }
6699
+ );
6700
+ }
6701
+ throw error3;
6702
+ }
6572
6703
  }
6573
6704
  }
6574
- const others_forDevTools = new DerivedRef(
6575
- context.others,
6576
- (others) => others.map((other, index) => userToTreeNode(`Other ${index}`, other))
6577
- );
6578
- const events = {
6579
- status: eventHub.status.observable,
6580
- lostConnection: eventHub.lostConnection.observable,
6581
- customEvent: eventHub.customEvent.observable,
6582
- others: eventHub.others.observable,
6583
- self: eventHub.self.observable,
6584
- myPresence: eventHub.myPresence.observable,
6585
- error: eventHub.error.observable,
6586
- /** @deprecated */
6587
- storage: eventHub.storageBatch.observable,
6588
- storageBatch: eventHub.storageBatch.observable,
6589
- history: eventHub.history.observable,
6590
- storageDidLoad: eventHub.storageDidLoad.observable,
6591
- storageStatus: eventHub.storageStatus.observable,
6592
- ydoc: eventHub.ydoc.observable,
6593
- comments: eventHub.comments.observable
6594
- };
6595
- const commentsApi = createCommentsApi(
6596
- config.roomId,
6597
- delegates.authenticate,
6598
- fetchClientApi
6705
+ async function getAttachmentUrls(attachmentIds) {
6706
+ const { urls } = await fetchCommentsJson(
6707
+ "/attachments/presigned-urls",
6708
+ {
6709
+ method: "POST",
6710
+ headers: {
6711
+ "Content-Type": "application/json"
6712
+ },
6713
+ body: JSON.stringify({ attachmentIds })
6714
+ }
6715
+ );
6716
+ return urls;
6717
+ }
6718
+ const batchedGetAttachmentUrls = new Batch(
6719
+ async (batchedAttachmentIds) => {
6720
+ const attachmentIds = batchedAttachmentIds.flat();
6721
+ const attachmentUrls = await getAttachmentUrls(attachmentIds);
6722
+ return attachmentUrls.map(
6723
+ (url) => _nullishCoalesce(url, () => ( new Error("There was an error while getting this attachment's URL")))
6724
+ );
6725
+ },
6726
+ { delay: GET_ATTACHMENT_URLS_BATCH_DELAY }
6599
6727
  );
6728
+ const attachmentUrlsStore = createBatchStore(batchedGetAttachmentUrls);
6729
+ function getAttachmentUrl(attachmentId) {
6730
+ return batchedGetAttachmentUrls.get(attachmentId);
6731
+ }
6600
6732
  async function fetchNotificationsJson(endpoint, options2) {
6601
6733
  const authValue = await delegates.authenticate();
6602
6734
  const response = await fetchClientApi(
@@ -6673,7 +6805,7 @@ ${Array.from(traces).join("\n\n")}`
6673
6805
  {
6674
6806
  [kInternal]: {
6675
6807
  get presenceBuffer() {
6676
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _140 => _140.buffer, 'access', _141 => _141.presenceUpdates, 'optionalAccess', _142 => _142.data]), () => ( null)));
6808
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _144 => _144.buffer, 'access', _145 => _145.presenceUpdates, 'optionalAccess', _146 => _146.data]), () => ( null)));
6677
6809
  },
6678
6810
  // prettier-ignore
6679
6811
  get undoStack() {
@@ -6706,7 +6838,8 @@ ${Array.from(traces).join("\n\n")}`
6706
6838
  // These exist only for our E2E testing app
6707
6839
  explicitClose: (event) => managedSocket._privateSendMachineEvent({ type: "EXPLICIT_SOCKET_CLOSE", event }),
6708
6840
  rawSend: (data) => managedSocket.send(data)
6709
- }
6841
+ },
6842
+ attachmentUrlsStore
6710
6843
  },
6711
6844
  id: config.roomId,
6712
6845
  subscribe: makeClassicSubscribeFn(events),
@@ -6747,10 +6880,27 @@ ${Array.from(traces).join("\n\n")}`
6747
6880
  // Presence
6748
6881
  getPresence: () => context.myPresence.current,
6749
6882
  getOthers: () => context.others.current,
6883
+ // Comments
6884
+ getThreads,
6885
+ getThreadsSince,
6886
+ getThread,
6887
+ createThread,
6888
+ deleteThread,
6889
+ editThreadMetadata,
6890
+ markThreadAsResolved,
6891
+ markThreadAsUnresolved,
6892
+ createComment,
6893
+ editComment,
6894
+ deleteComment: deleteComment2,
6895
+ addReaction: addReaction2,
6896
+ removeReaction: removeReaction2,
6897
+ prepareAttachment,
6898
+ uploadAttachment,
6899
+ getAttachmentUrl,
6900
+ // Notifications
6750
6901
  getNotificationSettings,
6751
6902
  updateNotificationSettings,
6752
- markInboxNotificationAsRead,
6753
- ...commentsApi
6903
+ markInboxNotificationAsRead
6754
6904
  },
6755
6905
  // Explictly make the internal field non-enumerable, to avoid aggressive
6756
6906
  // freezing when used with Immer
@@ -6833,7 +6983,7 @@ function makeClassicSubscribeFn(events) {
6833
6983
  }
6834
6984
  if (isLiveNode(first)) {
6835
6985
  const node = first;
6836
- if (_optionalChain([options, 'optionalAccess', _143 => _143.isDeep])) {
6986
+ if (_optionalChain([options, 'optionalAccess', _147 => _147.isDeep])) {
6837
6987
  const storageCallback = second;
6838
6988
  return subscribeToLiveStructureDeeply(node, storageCallback);
6839
6989
  } else {
@@ -7243,7 +7393,7 @@ function upsertComment(thread, comment) {
7243
7393
  );
7244
7394
  if (existingComment === void 0) {
7245
7395
  const updatedAt = new Date(
7246
- Math.max(_optionalChain([thread, 'access', _144 => _144.updatedAt, 'optionalAccess', _145 => _145.getTime, 'call', _146 => _146()]) || 0, comment.createdAt.getTime())
7396
+ Math.max(_optionalChain([thread, 'access', _148 => _148.updatedAt, 'optionalAccess', _149 => _149.getTime, 'call', _150 => _150()]) || 0, comment.createdAt.getTime())
7247
7397
  );
7248
7398
  const updatedThread = {
7249
7399
  ...thread,
@@ -7263,8 +7413,8 @@ function upsertComment(thread, comment) {
7263
7413
  ...thread,
7264
7414
  updatedAt: new Date(
7265
7415
  Math.max(
7266
- _optionalChain([thread, 'access', _147 => _147.updatedAt, 'optionalAccess', _148 => _148.getTime, 'call', _149 => _149()]) || 0,
7267
- _optionalChain([comment, 'access', _150 => _150.editedAt, 'optionalAccess', _151 => _151.getTime, 'call', _152 => _152()]) || comment.createdAt.getTime()
7416
+ _optionalChain([thread, 'access', _151 => _151.updatedAt, 'optionalAccess', _152 => _152.getTime, 'call', _153 => _153()]) || 0,
7417
+ _optionalChain([comment, 'access', _154 => _154.editedAt, 'optionalAccess', _155 => _155.getTime, 'call', _156 => _156()]) || comment.createdAt.getTime()
7268
7418
  )
7269
7419
  ),
7270
7420
  comments: updatedComments
@@ -7329,7 +7479,7 @@ function addReaction(thread, commentId, reaction) {
7329
7479
  return {
7330
7480
  ...thread,
7331
7481
  updatedAt: new Date(
7332
- Math.max(reaction.createdAt.getTime(), _optionalChain([thread, 'access', _153 => _153.updatedAt, 'optionalAccess', _154 => _154.getTime, 'call', _155 => _155()]) || 0)
7482
+ Math.max(reaction.createdAt.getTime(), _optionalChain([thread, 'access', _157 => _157.updatedAt, 'optionalAccess', _158 => _158.getTime, 'call', _159 => _159()]) || 0)
7333
7483
  ),
7334
7484
  comments: updatedComments
7335
7485
  };
@@ -7362,7 +7512,7 @@ function removeReaction(thread, commentId, emoji, userId, removedAt) {
7362
7512
  return {
7363
7513
  ...thread,
7364
7514
  updatedAt: new Date(
7365
- Math.max(removedAt.getTime(), _optionalChain([thread, 'access', _156 => _156.updatedAt, 'optionalAccess', _157 => _157.getTime, 'call', _158 => _158()]) || 0)
7515
+ Math.max(removedAt.getTime(), _optionalChain([thread, 'access', _160 => _160.updatedAt, 'optionalAccess', _161 => _161.getTime, 'call', _162 => _162()]) || 0)
7366
7516
  ),
7367
7517
  comments: updatedComments
7368
7518
  };
@@ -7473,12 +7623,12 @@ function createClient(options) {
7473
7623
  createSocket: makeCreateSocketDelegateForRoom(
7474
7624
  roomId,
7475
7625
  baseUrl,
7476
- _optionalChain([clientOptions, 'access', _159 => _159.polyfills, 'optionalAccess', _160 => _160.WebSocket])
7626
+ _optionalChain([clientOptions, 'access', _163 => _163.polyfills, 'optionalAccess', _164 => _164.WebSocket])
7477
7627
  ),
7478
7628
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
7479
7629
  })),
7480
7630
  enableDebugLogging: clientOptions.enableDebugLogging,
7481
- unstable_batchedUpdates: _optionalChain([options2, 'optionalAccess', _161 => _161.unstable_batchedUpdates]),
7631
+ unstable_batchedUpdates: _optionalChain([options2, 'optionalAccess', _165 => _165.unstable_batchedUpdates]),
7482
7632
  baseUrl,
7483
7633
  unstable_fallbackToHTTP: !!clientOptions.unstable_fallbackToHTTP,
7484
7634
  unstable_streamData: !!clientOptions.unstable_streamData
@@ -7494,7 +7644,7 @@ function createClient(options) {
7494
7644
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
7495
7645
  if (shouldConnect) {
7496
7646
  if (typeof atob === "undefined") {
7497
- if (_optionalChain([clientOptions, 'access', _162 => _162.polyfills, 'optionalAccess', _163 => _163.atob]) === void 0) {
7647
+ if (_optionalChain([clientOptions, 'access', _166 => _166.polyfills, 'optionalAccess', _167 => _167.atob]) === void 0) {
7498
7648
  throw new Error(
7499
7649
  "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"
7500
7650
  );
@@ -7506,7 +7656,7 @@ function createClient(options) {
7506
7656
  return leaseRoom(newRoomDetails);
7507
7657
  }
7508
7658
  function getRoom(roomId) {
7509
- const room = _optionalChain([roomsById, 'access', _164 => _164.get, 'call', _165 => _165(roomId), 'optionalAccess', _166 => _166.room]);
7659
+ const room = _optionalChain([roomsById, 'access', _168 => _168.get, 'call', _169 => _169(roomId), 'optionalAccess', _170 => _170.room]);
7510
7660
  return room ? room : null;
7511
7661
  }
7512
7662
  function logout() {
@@ -7530,7 +7680,7 @@ function createClient(options) {
7530
7680
  getThreadsSince
7531
7681
  } = createNotificationsApi({
7532
7682
  baseUrl,
7533
- fetcher: _optionalChain([clientOptions, 'access', _167 => _167.polyfills, 'optionalAccess', _168 => _168.fetch]) || /* istanbul ignore next */
7683
+ fetcher: _optionalChain([clientOptions, 'access', _171 => _171.polyfills, 'optionalAccess', _172 => _172.fetch]) || /* istanbul ignore next */
7534
7684
  fetch,
7535
7685
  authManager,
7536
7686
  currentUserIdStore
@@ -7541,29 +7691,31 @@ function createClient(options) {
7541
7691
  () => !resolveUsers,
7542
7692
  "Set the resolveUsers option in createClient to specify user info."
7543
7693
  );
7544
- const usersStore = createBatchStore(
7694
+ const batchedResolveUsers = new Batch(
7545
7695
  async (batchedUserIds) => {
7546
7696
  const userIds = batchedUserIds.flat();
7547
- const users = await _optionalChain([resolveUsers, 'optionalCall', _169 => _169({ userIds })]);
7697
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _173 => _173({ userIds })]);
7548
7698
  warnIfNoResolveUsers();
7549
7699
  return _nullishCoalesce(users, () => ( userIds.map(() => void 0)));
7550
7700
  },
7551
7701
  { delay: RESOLVE_USERS_BATCH_DELAY }
7552
7702
  );
7703
+ const usersStore = createBatchStore(batchedResolveUsers);
7553
7704
  const resolveRoomsInfo = clientOptions.resolveRoomsInfo;
7554
7705
  const warnIfNoResolveRoomsInfo = createDevelopmentWarning(
7555
7706
  () => !resolveRoomsInfo,
7556
7707
  "Set the resolveRoomsInfo option in createClient to specify room info."
7557
7708
  );
7558
- const roomsInfoStore = createBatchStore(
7709
+ const batchedResolveRoomsInfo = new Batch(
7559
7710
  async (batchedRoomIds) => {
7560
7711
  const roomIds = batchedRoomIds.flat();
7561
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _170 => _170({ roomIds })]);
7712
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _174 => _174({ roomIds })]);
7562
7713
  warnIfNoResolveRoomsInfo();
7563
7714
  return _nullishCoalesce(roomsInfo, () => ( roomIds.map(() => void 0)));
7564
7715
  },
7565
7716
  { delay: RESOLVE_ROOMS_INFO_BATCH_DELAY }
7566
7717
  );
7718
+ const roomsInfoStore = createBatchStore(batchedResolveRoomsInfo);
7567
7719
  return Object.defineProperty(
7568
7720
  {
7569
7721
  enterRoom,
@@ -7674,7 +7826,7 @@ var commentBodyElementsTypes = {
7674
7826
  mention: "inline"
7675
7827
  };
7676
7828
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
7677
- if (!body || !_optionalChain([body, 'optionalAccess', _171 => _171.content])) {
7829
+ if (!body || !_optionalChain([body, 'optionalAccess', _175 => _175.content])) {
7678
7830
  return;
7679
7831
  }
7680
7832
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -7684,13 +7836,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
7684
7836
  for (const block of body.content) {
7685
7837
  if (type === "all" || type === "block") {
7686
7838
  if (guard(block)) {
7687
- _optionalChain([visitor, 'optionalCall', _172 => _172(block)]);
7839
+ _optionalChain([visitor, 'optionalCall', _176 => _176(block)]);
7688
7840
  }
7689
7841
  }
7690
7842
  if (type === "all" || type === "inline") {
7691
7843
  for (const inline of block.children) {
7692
7844
  if (guard(inline)) {
7693
- _optionalChain([visitor, 'optionalCall', _173 => _173(inline)]);
7845
+ _optionalChain([visitor, 'optionalCall', _177 => _177(inline)]);
7694
7846
  }
7695
7847
  }
7696
7848
  }
@@ -7715,7 +7867,7 @@ async function resolveUsersInCommentBody(body, resolveUsers) {
7715
7867
  userIds
7716
7868
  });
7717
7869
  for (const [index, userId] of userIds.entries()) {
7718
- const user = _optionalChain([users, 'optionalAccess', _174 => _174[index]]);
7870
+ const user = _optionalChain([users, 'optionalAccess', _178 => _178[index]]);
7719
7871
  if (user) {
7720
7872
  resolvedUsers.set(userId, user);
7721
7873
  }
@@ -7838,7 +7990,7 @@ var stringifyCommentBodyPlainElements = {
7838
7990
  text: ({ element }) => element.text,
7839
7991
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
7840
7992
  mention: ({ element, user }) => {
7841
- return `@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _175 => _175.name]), () => ( element.id))}`;
7993
+ return `@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _179 => _179.name]), () => ( element.id))}`;
7842
7994
  }
7843
7995
  };
7844
7996
  var stringifyCommentBodyHtmlElements = {
@@ -7868,7 +8020,7 @@ var stringifyCommentBodyHtmlElements = {
7868
8020
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${_nullishCoalesce(element.text, () => ( element.url))}</a>`;
7869
8021
  },
7870
8022
  mention: ({ element, user }) => {
7871
- return html`<span data-mention>@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _176 => _176.name]), () => ( element.id))}</span>`;
8023
+ return html`<span data-mention>@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _180 => _180.name]), () => ( element.id))}</span>`;
7872
8024
  }
7873
8025
  };
7874
8026
  var stringifyCommentBodyMarkdownElements = {
@@ -7898,19 +8050,19 @@ var stringifyCommentBodyMarkdownElements = {
7898
8050
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
7899
8051
  },
7900
8052
  mention: ({ element, user }) => {
7901
- return markdown`@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _177 => _177.name]), () => ( element.id))}`;
8053
+ return markdown`@${_nullishCoalesce(_optionalChain([user, 'optionalAccess', _181 => _181.name]), () => ( element.id))}`;
7902
8054
  }
7903
8055
  };
7904
8056
  async function stringifyCommentBody(body, options) {
7905
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _178 => _178.format]), () => ( "plain"));
7906
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _179 => _179.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
8057
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _182 => _182.format]), () => ( "plain"));
8058
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _183 => _183.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
7907
8059
  const elements = {
7908
8060
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
7909
- ..._optionalChain([options, 'optionalAccess', _180 => _180.elements])
8061
+ ..._optionalChain([options, 'optionalAccess', _184 => _184.elements])
7910
8062
  };
7911
8063
  const resolvedUsers = await resolveUsersInCommentBody(
7912
8064
  body,
7913
- _optionalChain([options, 'optionalAccess', _181 => _181.resolveUsers])
8065
+ _optionalChain([options, 'optionalAccess', _185 => _185.resolveUsers])
7914
8066
  );
7915
8067
  const blocks = body.content.flatMap((block, blockIndex) => {
7916
8068
  switch (block.type) {
@@ -8185,12 +8337,12 @@ function legacy_patchImmutableNode(state, path, update) {
8185
8337
  }
8186
8338
  const newState = Object.assign({}, state);
8187
8339
  for (const key in update.updates) {
8188
- if (_optionalChain([update, 'access', _182 => _182.updates, 'access', _183 => _183[key], 'optionalAccess', _184 => _184.type]) === "update") {
8340
+ if (_optionalChain([update, 'access', _186 => _186.updates, 'access', _187 => _187[key], 'optionalAccess', _188 => _188.type]) === "update") {
8189
8341
  const val = update.node.get(key);
8190
8342
  if (val !== void 0) {
8191
8343
  newState[key] = lsonToJson(val);
8192
8344
  }
8193
- } else if (_optionalChain([update, 'access', _185 => _185.updates, 'access', _186 => _186[key], 'optionalAccess', _187 => _187.type]) === "delete") {
8345
+ } else if (_optionalChain([update, 'access', _189 => _189.updates, 'access', _190 => _190[key], 'optionalAccess', _191 => _191.type]) === "delete") {
8194
8346
  delete newState[key];
8195
8347
  }
8196
8348
  }
@@ -8251,12 +8403,12 @@ function legacy_patchImmutableNode(state, path, update) {
8251
8403
  }
8252
8404
  const newState = Object.assign({}, state);
8253
8405
  for (const key in update.updates) {
8254
- if (_optionalChain([update, 'access', _188 => _188.updates, 'access', _189 => _189[key], 'optionalAccess', _190 => _190.type]) === "update") {
8406
+ if (_optionalChain([update, 'access', _192 => _192.updates, 'access', _193 => _193[key], 'optionalAccess', _194 => _194.type]) === "update") {
8255
8407
  const value = update.node.get(key);
8256
8408
  if (value !== void 0) {
8257
8409
  newState[key] = lsonToJson(value);
8258
8410
  }
8259
- } else if (_optionalChain([update, 'access', _191 => _191.updates, 'access', _192 => _192[key], 'optionalAccess', _193 => _193.type]) === "delete") {
8411
+ } else if (_optionalChain([update, 'access', _195 => _195.updates, 'access', _196 => _196[key], 'optionalAccess', _197 => _197.type]) === "delete") {
8260
8412
  delete newState[key];
8261
8413
  }
8262
8414
  }
@@ -8515,5 +8667,6 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
8515
8667
 
8516
8668
 
8517
8669
 
8518
- exports.ClientMsgCode = ClientMsgCode; exports.CommentsApiError = CommentsApiError; exports.CrdtType = CrdtType; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.NotificationsApiError = NotificationsApiError; exports.OpCode = OpCode; exports.ServerMsgCode = ServerMsgCode; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.ackOp = ackOp; exports.addReaction = addReaction; exports.applyOptimisticUpdates = applyOptimisticUpdates; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.b64decode = b64decode; exports.cloneLson = cloneLson; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToThreadData = convertToThreadData; exports.createClient = createClient; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createThreadId = createThreadId; exports.deleteComment = deleteComment; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.errorIf = errorIf; exports.freeze = freeze; exports.getMentionedIdsFromCommentBody = getMentionedIdsFromCommentBody; exports.isChildCrdt = isChildCrdt; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isLiveNode = isLiveNode; exports.isPlainObject = isPlainObject; exports.isRootCrdt = isRootCrdt; exports.kInternal = kInternal; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.objectToQuery = objectToQuery; exports.patchLiveObjectKey = patchLiveObjectKey; exports.raise = raise; exports.removeReaction = removeReaction; exports.shallow = shallow; exports.stringify = stringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.upsertComment = upsertComment; exports.wait = wait; exports.withTimeout = withTimeout;
8670
+
8671
+ exports.ClientMsgCode = ClientMsgCode; exports.CommentsApiError = CommentsApiError; exports.CrdtType = CrdtType; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.NotificationsApiError = NotificationsApiError; exports.OpCode = OpCode; exports.ServerMsgCode = ServerMsgCode; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.ackOp = ackOp; exports.addReaction = addReaction; exports.applyOptimisticUpdates = applyOptimisticUpdates; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.b64decode = b64decode; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToThreadData = convertToThreadData; exports.createClient = createClient; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createThreadId = createThreadId; exports.deleteComment = deleteComment; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.errorIf = errorIf; exports.freeze = freeze; exports.getMentionedIdsFromCommentBody = getMentionedIdsFromCommentBody; exports.isChildCrdt = isChildCrdt; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isLiveNode = isLiveNode; exports.isPlainObject = isPlainObject; exports.isRootCrdt = isRootCrdt; exports.kInternal = kInternal; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.objectToQuery = objectToQuery; exports.patchLiveObjectKey = patchLiveObjectKey; exports.raise = raise; exports.removeReaction = removeReaction; exports.shallow = shallow; exports.stringify = stringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.upsertComment = upsertComment; exports.wait = wait; exports.withTimeout = withTimeout;
8519
8672
  //# sourceMappingURL=index.js.map