@liveblocks/core 1.3.5 → 1.4.0-test1

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 = "1.3.5";
9
+ var PKG_VERSION = "1.4.0-test1";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -1542,9 +1542,18 @@ function startSyncStream(room) {
1542
1542
  room.events.storage.subscribe(() => partialSyncStorage(room)),
1543
1543
  // Any time "me" or "others" updates, send the new values accordingly
1544
1544
  room.events.self.subscribe(() => partialSyncMe(room)),
1545
- room.events.others.subscribe(() => partialSyncOthers(room))
1545
+ room.events.others.subscribe(() => partialSyncOthers(room)),
1546
+ // Any time ydoc is updated, forward the update
1547
+ room.events.ydoc.subscribe((update) => syncYdocUpdate(room, update))
1546
1548
  ]);
1547
1549
  }
1550
+ function syncYdocUpdate(room, update) {
1551
+ sendToPanel({
1552
+ msg: "room::sync::ydoc",
1553
+ roomId: room.id,
1554
+ update
1555
+ });
1556
+ }
1548
1557
  function partialSyncConnection(room) {
1549
1558
  sendToPanel({
1550
1559
  msg: "room::sync::partial",
@@ -1586,6 +1595,7 @@ function fullSync(room) {
1586
1595
  const root = room.getStorageSnapshot();
1587
1596
  const me = room.__internal.getSelf_forDevTools();
1588
1597
  const others = room.__internal.getOthers_forDevTools();
1598
+ room.fetchYDoc("");
1589
1599
  sendToPanel({
1590
1600
  msg: "room::sync::full",
1591
1601
  roomId: room.id,
@@ -1821,13 +1831,47 @@ function createCommentsApi(roomId, getAuthValue, { serverEndpoint }) {
1821
1831
  }
1822
1832
  );
1823
1833
  }
1834
+ function addReaction({
1835
+ threadId,
1836
+ commentId,
1837
+ emoji
1838
+ }) {
1839
+ return fetchJson(
1840
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
1841
+ commentId
1842
+ )}/reactions`,
1843
+ {
1844
+ method: "POST",
1845
+ headers: {
1846
+ "Content-Type": "application/json"
1847
+ },
1848
+ body: JSON.stringify({ emoji })
1849
+ }
1850
+ );
1851
+ }
1852
+ function removeReaction({
1853
+ threadId,
1854
+ commentId,
1855
+ emoji
1856
+ }) {
1857
+ return fetchJson(
1858
+ `/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
1859
+ commentId
1860
+ )}/reactions/${encodeURIComponent(emoji)}`,
1861
+ {
1862
+ method: "DELETE"
1863
+ }
1864
+ );
1865
+ }
1824
1866
  return {
1825
1867
  getThreads,
1826
1868
  createThread,
1827
1869
  editThreadMetadata,
1828
1870
  createComment,
1829
1871
  editComment,
1830
- deleteComment
1872
+ deleteComment,
1873
+ addReaction,
1874
+ removeReaction
1831
1875
  };
1832
1876
  }
1833
1877
 
@@ -4596,7 +4640,7 @@ var DerivedRef = class extends ImmutableRef {
4596
4640
  };
4597
4641
 
4598
4642
  // src/room.ts
4599
- var MAX_MESSAGE_SIZE = 1024 * 1024 - 128;
4643
+ var MAX_SOCKET_MESSAGE_SIZE = 1024 * 1024 - 1024;
4600
4644
  function makeIdFactory(connectionId) {
4601
4645
  let count = 0;
4602
4646
  return () => `${connectionId}:${count++}`;
@@ -4811,17 +4855,35 @@ function createRoom(options, config) {
4811
4855
  ydoc: makeEventSource(),
4812
4856
  comments: makeEventSource()
4813
4857
  };
4814
- function sendMessages(messageOrMessages) {
4815
- const message = JSON.stringify(messageOrMessages);
4816
- if (config.unstable_fallbackToHTTP) {
4817
- const size = new TextEncoder().encode(message).length;
4818
- if (size > MAX_MESSAGE_SIZE && // TODO: support public api key auth in REST API
4819
- _optionalChain([managedSocket, 'access', _115 => _115.authValue, 'optionalAccess', _116 => _116.type]) === "secret" && config.httpSendEndpoint) {
4858
+ async function httpSend(authTokenOrPublicApiKey, roomId, nonce, messages) {
4859
+ const baseUrl = new URL(config.liveblocksServer);
4860
+ baseUrl.protocol = "https";
4861
+ const url = new URL(
4862
+ `/v2/c/rooms/${encodeURIComponent(roomId)}/send-message`,
4863
+ baseUrl
4864
+ );
4865
+ const fetcher = _optionalChain([config, 'access', _115 => _115.polyfills, 'optionalAccess', _116 => _116.fetch]) || /* istanbul ignore next */
4866
+ fetch;
4867
+ return fetcher(url.toString(), {
4868
+ method: "POST",
4869
+ headers: {
4870
+ "Content-Type": "application/json",
4871
+ Authorization: `Bearer ${authTokenOrPublicApiKey}`
4872
+ },
4873
+ body: JSON.stringify({ nonce, messages })
4874
+ });
4875
+ }
4876
+ function sendMessages(messages) {
4877
+ const serializedPayload = JSON.stringify(messages);
4878
+ const nonce = _optionalChain([context, 'access', _117 => _117.dynamicSessionInfo, 'access', _118 => _118.current, 'optionalAccess', _119 => _119.nonce]);
4879
+ if (config.unstable_fallbackToHTTP && managedSocket.authValue && nonce) {
4880
+ const size = new TextEncoder().encode(serializedPayload).length;
4881
+ if (size > MAX_SOCKET_MESSAGE_SIZE) {
4820
4882
  void httpSend(
4821
- message,
4822
- managedSocket.authValue.token.raw,
4823
- config.httpSendEndpoint,
4824
- _optionalChain([config, 'access', _117 => _117.polyfills, 'optionalAccess', _118 => _118.fetch])
4883
+ managedSocket.authValue.type === "public" ? managedSocket.authValue.publicApiKey : managedSocket.authValue.token.raw,
4884
+ config.roomId,
4885
+ nonce,
4886
+ messages
4825
4887
  ).then((resp) => {
4826
4888
  if (!resp.ok && resp.status === 403) {
4827
4889
  managedSocket.reconnect();
@@ -4833,7 +4895,7 @@ function createRoom(options, config) {
4833
4895
  return;
4834
4896
  }
4835
4897
  }
4836
- managedSocket.send(message);
4898
+ managedSocket.send(serializedPayload);
4837
4899
  }
4838
4900
  const self = new DerivedRef(
4839
4901
  context.staticSessionInfo,
@@ -5080,7 +5142,7 @@ function createRoom(options, config) {
5080
5142
  }
5081
5143
  context.myPresence.patch(patch);
5082
5144
  if (context.activeBatch) {
5083
- if (_optionalChain([options2, 'optionalAccess', _119 => _119.addToHistory])) {
5145
+ if (_optionalChain([options2, 'optionalAccess', _120 => _120.addToHistory])) {
5084
5146
  context.activeBatch.reverseOps.unshift({
5085
5147
  type: "presence",
5086
5148
  data: oldValues
@@ -5090,7 +5152,7 @@ function createRoom(options, config) {
5090
5152
  } else {
5091
5153
  flushNowOrSoon();
5092
5154
  batchUpdates(() => {
5093
- if (_optionalChain([options2, 'optionalAccess', _120 => _120.addToHistory])) {
5155
+ if (_optionalChain([options2, 'optionalAccess', _121 => _121.addToHistory])) {
5094
5156
  addToUndoStack(
5095
5157
  [{ type: "presence", data: oldValues }],
5096
5158
  doNotBatchUpdates
@@ -5133,6 +5195,7 @@ function createRoom(options, config) {
5133
5195
  function onRoomStateMessage(message, batchedUpdatesWrapper) {
5134
5196
  context.dynamicSessionInfo.set({
5135
5197
  actor: message.actor,
5198
+ nonce: message.nonce,
5136
5199
  scopes: message.scopes
5137
5200
  });
5138
5201
  context.idFactory = makeIdFactory(message.actor);
@@ -5242,8 +5305,10 @@ function createRoom(options, config) {
5242
5305
  break;
5243
5306
  }
5244
5307
  case 103 /* BROADCASTED_EVENT */: {
5308
+ const others = context.others.current;
5245
5309
  eventHub.customEvent.notify({
5246
5310
  connectionId: message.actor,
5311
+ user: message.actor < 0 ? null : _nullishCoalesce(others.find((u) => u.connectionId === message.actor), () => ( null)),
5247
5312
  event: message.event
5248
5313
  });
5249
5314
  break;
@@ -5267,7 +5332,7 @@ function createRoom(options, config) {
5267
5332
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
5268
5333
  createOrUpdateRootFromMessage(message, doNotBatchUpdates);
5269
5334
  applyAndSendOps(unacknowledgedOps, doNotBatchUpdates);
5270
- _optionalChain([_resolveStoragePromise, 'optionalCall', _121 => _121()]);
5335
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _122 => _122()]);
5271
5336
  notifyStorageStatus();
5272
5337
  eventHub.storageDidLoad.notify();
5273
5338
  break;
@@ -5290,7 +5355,7 @@ function createRoom(options, config) {
5290
5355
  if (process.env.NODE_ENV !== "production") {
5291
5356
  const traces = /* @__PURE__ */ new Set();
5292
5357
  for (const opId of message.opIds) {
5293
- const trace = _optionalChain([context, 'access', _122 => _122.opStackTraces, 'optionalAccess', _123 => _123.get, 'call', _124 => _124(opId)]);
5358
+ const trace = _optionalChain([context, 'access', _123 => _123.opStackTraces, 'optionalAccess', _124 => _124.get, 'call', _125 => _125(opId)]);
5294
5359
  if (trace) {
5295
5360
  traces.add(trace);
5296
5361
  }
@@ -5386,10 +5451,12 @@ ${Array.from(traces).join("\n\n")}`
5386
5451
  return messages;
5387
5452
  }
5388
5453
  function updateYDoc(update) {
5389
- context.buffer.messages.push({
5454
+ const clientMsg = {
5390
5455
  type: 301 /* UPDATE_YDOC */,
5391
5456
  update
5392
- });
5457
+ };
5458
+ context.buffer.messages.push(clientMsg);
5459
+ eventHub.ydoc.notify(clientMsg);
5393
5460
  flushNowOrSoon();
5394
5461
  }
5395
5462
  function broadcastEvent(event, options2 = {
@@ -5598,7 +5665,7 @@ ${Array.from(traces).join("\n\n")}`
5598
5665
  /* NOTE: Exposing __internal here only to allow testing implementation details in unit tests */
5599
5666
  __internal: {
5600
5667
  get presenceBuffer() {
5601
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _125 => _125.buffer, 'access', _126 => _126.presenceUpdates, 'optionalAccess', _127 => _127.data]), () => ( null)));
5668
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _126 => _126.buffer, 'access', _127 => _127.presenceUpdates, 'optionalAccess', _128 => _128.data]), () => ( null)));
5602
5669
  },
5603
5670
  // prettier-ignore
5604
5671
  get undoStack() {
@@ -5734,7 +5801,7 @@ function makeClassicSubscribeFn(events) {
5734
5801
  }
5735
5802
  if (isLiveNode(first)) {
5736
5803
  const node = first;
5737
- if (_optionalChain([options, 'optionalAccess', _128 => _128.isDeep])) {
5804
+ if (_optionalChain([options, 'optionalAccess', _129 => _129.isDeep])) {
5738
5805
  const storageCallback = second;
5739
5806
  return subscribeToLiveStructureDeeply(node, storageCallback);
5740
5807
  } else {
@@ -5777,18 +5844,6 @@ function makeCreateSocketDelegateForRoom(roomId, liveblocksServer, WebSocketPoly
5777
5844
  return new ws(url.toString());
5778
5845
  };
5779
5846
  }
5780
- async function httpSend(message, token, endpoint, fetchPolyfill) {
5781
- const fetcher = fetchPolyfill || /* istanbul ignore next */
5782
- fetch;
5783
- return fetcher(endpoint, {
5784
- method: "POST",
5785
- headers: {
5786
- "Content-Type": "application/json",
5787
- Authorization: `Bearer ${token}`
5788
- },
5789
- body: message
5790
- });
5791
- }
5792
5847
 
5793
5848
  // src/client.ts
5794
5849
  var MIN_THROTTLE = 16;
@@ -5837,17 +5892,13 @@ function createClient(options) {
5837
5892
  createSocket: makeCreateSocketDelegateForRoom(
5838
5893
  roomId,
5839
5894
  getServerFromClientOptions(clientOptions),
5840
- _optionalChain([clientOptions, 'access', _129 => _129.polyfills, 'optionalAccess', _130 => _130.WebSocket])
5895
+ _optionalChain([clientOptions, 'access', _130 => _130.polyfills, 'optionalAccess', _131 => _131.WebSocket])
5841
5896
  ),
5842
5897
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
5843
5898
  })),
5844
5899
  enableDebugLogging: clientOptions.enableDebugLogging,
5845
- unstable_batchedUpdates: _optionalChain([options2, 'optionalAccess', _131 => _131.unstable_batchedUpdates]),
5900
+ unstable_batchedUpdates: _optionalChain([options2, 'optionalAccess', _132 => _132.unstable_batchedUpdates]),
5846
5901
  liveblocksServer: getServerFromClientOptions(clientOptions),
5847
- httpSendEndpoint: buildLiveblocksHttpSendEndpoint(
5848
- clientOptions,
5849
- roomId
5850
- ),
5851
5902
  unstable_fallbackToHTTP: !!clientOptions.unstable_fallbackToHTTP
5852
5903
  }
5853
5904
  );
@@ -5857,7 +5908,7 @@ function createClient(options) {
5857
5908
  const shouldConnect = _nullishCoalesce(options2.shouldInitiallyConnect, () => ( true));
5858
5909
  if (shouldConnect) {
5859
5910
  if (typeof atob === "undefined") {
5860
- if (_optionalChain([clientOptions, 'access', _132 => _132.polyfills, 'optionalAccess', _133 => _133.atob]) === void 0) {
5911
+ if (_optionalChain([clientOptions, 'access', _133 => _133.polyfills, 'optionalAccess', _134 => _134.atob]) === void 0) {
5861
5912
  throw new Error(
5862
5913
  "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"
5863
5914
  );
@@ -5902,14 +5953,6 @@ function getLostConnectionTimeout(value) {
5902
5953
  RECOMMENDED_MIN_LOST_CONNECTION_TIMEOUT
5903
5954
  );
5904
5955
  }
5905
- function buildLiveblocksHttpSendEndpoint(options, roomId) {
5906
- if (options.httpSendEndpoint) {
5907
- return options.httpSendEndpoint.replace("{roomId}", roomId);
5908
- }
5909
- return `https://api.liveblocks.io/v2/rooms/${encodeURIComponent(
5910
- roomId
5911
- )}/send-message`;
5912
- }
5913
5956
 
5914
5957
  // src/crdts/utils.ts
5915
5958
  function toPlainLson(lson) {
@@ -6140,12 +6183,12 @@ function legacy_patchImmutableNode(state, path, update) {
6140
6183
  }
6141
6184
  const newState = Object.assign({}, state);
6142
6185
  for (const key in update.updates) {
6143
- if (_optionalChain([update, 'access', _134 => _134.updates, 'access', _135 => _135[key], 'optionalAccess', _136 => _136.type]) === "update") {
6186
+ if (_optionalChain([update, 'access', _135 => _135.updates, 'access', _136 => _136[key], 'optionalAccess', _137 => _137.type]) === "update") {
6144
6187
  const val = update.node.get(key);
6145
6188
  if (val !== void 0) {
6146
6189
  newState[key] = lsonToJson(val);
6147
6190
  }
6148
- } else if (_optionalChain([update, 'access', _137 => _137.updates, 'access', _138 => _138[key], 'optionalAccess', _139 => _139.type]) === "delete") {
6191
+ } else if (_optionalChain([update, 'access', _138 => _138.updates, 'access', _139 => _139[key], 'optionalAccess', _140 => _140.type]) === "delete") {
6149
6192
  delete newState[key];
6150
6193
  }
6151
6194
  }
@@ -6206,12 +6249,12 @@ function legacy_patchImmutableNode(state, path, update) {
6206
6249
  }
6207
6250
  const newState = Object.assign({}, state);
6208
6251
  for (const key in update.updates) {
6209
- if (_optionalChain([update, 'access', _140 => _140.updates, 'access', _141 => _141[key], 'optionalAccess', _142 => _142.type]) === "update") {
6252
+ if (_optionalChain([update, 'access', _141 => _141.updates, 'access', _142 => _142[key], 'optionalAccess', _143 => _143.type]) === "update") {
6210
6253
  const value = update.node.get(key);
6211
6254
  if (value !== void 0) {
6212
6255
  newState[key] = lsonToJson(value);
6213
6256
  }
6214
- } else if (_optionalChain([update, 'access', _143 => _143.updates, 'access', _144 => _144[key], 'optionalAccess', _145 => _145.type]) === "delete") {
6257
+ } else if (_optionalChain([update, 'access', _144 => _144.updates, 'access', _145 => _145[key], 'optionalAccess', _146 => _146.type]) === "delete") {
6215
6258
  delete newState[key];
6216
6259
  }
6217
6260
  }
@@ -6301,7 +6344,7 @@ function createCacheItem(key, defaultAsyncFunction, options) {
6301
6344
  let previousState = { isLoading: false };
6302
6345
  const eventSource2 = makeEventSource();
6303
6346
  function notify() {
6304
- const isEqual = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _146 => _146.isStateEqual]), () => ( isShallowEqual));
6347
+ const isEqual = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _147 => _147.isStateEqual]), () => ( isShallowEqual));
6305
6348
  if (!isEqual(previousState, state)) {
6306
6349
  previousState = state;
6307
6350
  eventSource2.notify(state);
@@ -6380,7 +6423,7 @@ function createAsyncCache(asyncFunction, options) {
6380
6423
  return create(key).get();
6381
6424
  }
6382
6425
  function getState(key) {
6383
- return _optionalChain([cache, 'access', _147 => _147.get, 'call', _148 => _148(key), 'optionalAccess', _149 => _149.getState, 'call', _150 => _150()]);
6426
+ return _optionalChain([cache, 'access', _148 => _148.get, 'call', _149 => _149(key), 'optionalAccess', _150 => _150.getState, 'call', _151 => _151()]);
6384
6427
  }
6385
6428
  function revalidate(key) {
6386
6429
  return create(key).revalidate();