@liveblocks/core 2.16.0 → 2.16.1-ai

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.16.0";
9
+ var PKG_VERSION = "2.16.1-ai";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -166,14 +166,6 @@ 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
-
177
169
  // src/lib/utils.ts
178
170
  function raise(msg) {
179
171
  throw new Error(msg);
@@ -259,48 +251,13 @@ function memoizeOnSuccess(factoryFn) {
259
251
  }
260
252
 
261
253
  // src/lib/autoRetry.ts
262
- var HttpError = class _HttpError extends Error {
263
- response;
264
- details;
265
- constructor(message, response, details) {
254
+ var HttpError = class extends Error {
255
+ constructor(message, status, details) {
266
256
  super(message);
267
- this.name = "HttpError";
268
- this.response = response;
257
+ this.message = message;
258
+ this.status = status;
269
259
  this.details = details;
270
260
  }
271
- static async fromResponse(response) {
272
- let bodyAsText;
273
- try {
274
- bodyAsText = await response.text();
275
- } catch {
276
- }
277
- const bodyAsJson = bodyAsText ? tryParseJson(bodyAsText) : void 0;
278
- let bodyAsJsonObject;
279
- if (isPlainObject(bodyAsJson)) {
280
- bodyAsJsonObject = bodyAsJson;
281
- }
282
- let message = "";
283
- message ||= typeof bodyAsJsonObject?.message === "string" ? bodyAsJsonObject.message : "";
284
- message ||= typeof bodyAsJsonObject?.error === "string" ? bodyAsJsonObject.error : "";
285
- if (bodyAsJson === void 0) {
286
- message ||= bodyAsText || "";
287
- }
288
- message ||= response.statusText;
289
- let path;
290
- try {
291
- path = new URL(response.url).pathname;
292
- } catch {
293
- }
294
- message += path !== void 0 ? ` (got status ${response.status} from ${path})` : ` (got status ${response.status})`;
295
- const details = bodyAsJsonObject;
296
- return new _HttpError(message, response, details);
297
- }
298
- /**
299
- * Convenience accessor for response.status.
300
- */
301
- get status() {
302
- return this.response.status;
303
- }
304
261
  };
305
262
  var DONT_RETRY_4XX = (x) => x instanceof HttpError && x.status >= 400 && x.status < 500;
306
263
  async function autoRetry(promiseFn, maxTries, backoff, shouldStopRetrying = DONT_RETRY_4XX) {
@@ -366,12 +323,7 @@ function makeEventSource() {
366
323
  }).finally(() => unsub?.());
367
324
  }
368
325
  function notify(event) {
369
- let called = false;
370
- for (const callback of _observers) {
371
- callback(event);
372
- called = true;
373
- }
374
- return called;
326
+ _observers.forEach((callback) => callback(event));
375
327
  }
376
328
  function count() {
377
329
  return _observers.size;
@@ -412,9 +364,8 @@ function makeBufferableEventSource() {
412
364
  function notifyOrBuffer(event) {
413
365
  if (_buffer !== null) {
414
366
  _buffer.push(event);
415
- return false;
416
367
  } else {
417
- return eventSource2.notify(event);
368
+ eventSource2.notify(event);
418
369
  }
419
370
  }
420
371
  return {
@@ -719,15 +670,32 @@ var MutableSignal = class extends AbstractSignal {
719
670
  };
720
671
 
721
672
  // src/lib/stringify.ts
673
+ var EXPLICIT_UNDEFINED_PLACEHOLDER = "_explicit_undefined";
722
674
  function replacer(_key, value) {
723
675
  return value !== null && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).sort().reduce((sorted, key) => {
724
676
  sorted[key] = value[key];
725
677
  return sorted;
726
- }, {}) : value;
678
+ }, {}) : value === void 0 ? EXPLICIT_UNDEFINED_PLACEHOLDER : value;
679
+ }
680
+ function reviver(key, value) {
681
+ if (!key && value === EXPLICIT_UNDEFINED_PLACEHOLDER) {
682
+ return void 0;
683
+ }
684
+ if (value && typeof value === "object") {
685
+ for (const k in value) {
686
+ if (value[k] === EXPLICIT_UNDEFINED_PLACEHOLDER) {
687
+ Object.defineProperty(value, k, { value: void 0 });
688
+ }
689
+ }
690
+ }
691
+ return value;
727
692
  }
728
693
  function stringify(value) {
729
694
  return JSON.stringify(value, replacer);
730
695
  }
696
+ function unstringify(value) {
697
+ return JSON.parse(value, reviver);
698
+ }
731
699
 
732
700
  // src/lib/batch.ts
733
701
  var DEFAULT_SIZE = 50;
@@ -943,6 +911,14 @@ var DefaultMap = class extends Map {
943
911
  }
944
912
  };
945
913
 
914
+ // src/lib/guards.ts
915
+ function isPlainObject(blob) {
916
+ return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
917
+ }
918
+ function isStartsWithOperator(blob) {
919
+ return isPlainObject(blob) && typeof blob.startsWith === "string";
920
+ }
921
+
946
922
  // src/lib/objectToQuery.ts
947
923
  var identifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
948
924
  function objectToQuery(obj) {
@@ -992,7 +968,9 @@ function objectToQuery(obj) {
992
968
  ...getFiltersFromKeyValuePairsWithOperator(nKeyValuePairsWithOperator)
993
969
  ];
994
970
  });
995
- return filterList.map(({ key, operator, value }) => `${key}${operator}${quote(value)}`).join(" ");
971
+ return filterList.map(
972
+ ({ key, operator, value }) => formatFilter(key, operator, formatFilterValue(value))
973
+ ).join(" AND ");
996
974
  }
997
975
  var getFiltersFromKeyValuePairs = (keyValuePairs) => {
998
976
  const filters = [];
@@ -1019,27 +997,29 @@ var getFiltersFromKeyValuePairsWithOperator = (keyValuePairsWithOperator) => {
1019
997
  return filters;
1020
998
  };
1021
999
  var isSimpleValue = (value) => {
1022
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
1000
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1001
+ };
1002
+ var formatFilter = (key, operator, value) => {
1003
+ return `${key}${operator}${value}`;
1023
1004
  };
1024
1005
  var formatFilterKey = (key, nestedKey) => {
1025
1006
  if (nestedKey) {
1026
- return `${key}[${quote(nestedKey)}]`;
1007
+ return `${key}[${JSON.stringify(nestedKey)}]`;
1027
1008
  }
1028
1009
  return key;
1029
1010
  };
1011
+ var formatFilterValue = (value) => {
1012
+ if (typeof value === "string") {
1013
+ if (isStringEmpty(value)) {
1014
+ throw new Error("Value cannot be empty");
1015
+ }
1016
+ return JSON.stringify(value);
1017
+ }
1018
+ return value.toString();
1019
+ };
1030
1020
  var isStringEmpty = (value) => {
1031
1021
  return !value || value.toString().trim() === "";
1032
1022
  };
1033
- function quote(input) {
1034
- const result = JSON.stringify(input);
1035
- if (typeof input !== "string") {
1036
- return result;
1037
- }
1038
- if (result.includes("'")) {
1039
- return result;
1040
- }
1041
- return `'${result.slice(1, -1).replace(/\\"/g, '"')}'`;
1042
- }
1043
1023
 
1044
1024
  // src/lib/url.ts
1045
1025
  function toURLSearchParams(params) {
@@ -1556,6 +1536,25 @@ function createApiClient({
1556
1536
  }
1557
1537
  );
1558
1538
  }
1539
+ async function executeContextualPrompt(options) {
1540
+ const result = await httpClient.post(
1541
+ url`/v2/c/rooms/${options.roomId}/ai/contextual-prompt`,
1542
+ await authManager.getAuthValue({
1543
+ requestedScope: "room:read",
1544
+ roomId: options.roomId
1545
+ }),
1546
+ {
1547
+ prompt: options.prompt,
1548
+ selectionText: options.selectionText,
1549
+ context: options.context
1550
+ },
1551
+ { signal: options.signal }
1552
+ );
1553
+ if (!result || result.content.length === 0) {
1554
+ throw new Error("No content returned from server");
1555
+ }
1556
+ return result.content[0].text;
1557
+ }
1559
1558
  async function listTextVersions(options) {
1560
1559
  const result = await httpClient.get(
1561
1560
  url`/v2/c/rooms/${options.roomId}/versions`,
@@ -1796,7 +1795,9 @@ function createApiClient({
1796
1795
  deleteInboxNotification,
1797
1796
  // User threads
1798
1797
  getUserThreads_experimental,
1799
- getUserThreadsSince_experimental
1798
+ getUserThreadsSince_experimental,
1799
+ // ai
1800
+ executeContextualPrompt
1800
1801
  };
1801
1802
  }
1802
1803
  function getBearerTokenFromAuthValue(authValue) {
@@ -1864,7 +1865,14 @@ var HttpClient = class {
1864
1865
  async #fetch(endpoint, authValue, options, params) {
1865
1866
  const response = await this.#rawFetch(endpoint, authValue, options, params);
1866
1867
  if (!response.ok) {
1867
- throw await HttpError.fromResponse(response);
1868
+ let error3;
1869
+ try {
1870
+ const errorBody = await response.json();
1871
+ error3 = new HttpError(errorBody.message, response.status, errorBody);
1872
+ } catch {
1873
+ error3 = new HttpError(response.statusText, response.status);
1874
+ }
1875
+ throw error3;
1868
1876
  }
1869
1877
  let body;
1870
1878
  try {
@@ -2508,6 +2516,13 @@ var StopRetrying = class extends Error {
2508
2516
  super(reason);
2509
2517
  }
2510
2518
  };
2519
+ var LiveblocksError = class extends Error {
2520
+ /** @internal */
2521
+ constructor(message, code) {
2522
+ super(message);
2523
+ this.code = code;
2524
+ }
2525
+ };
2511
2526
  function nextBackoffDelay(currentDelay, delays) {
2512
2527
  return delays.find((delay) => delay > currentDelay) ?? delays[delays.length - 1];
2513
2528
  }
@@ -2617,10 +2632,11 @@ var assign = (patch) => (ctx) => ctx.patch(patch);
2617
2632
  function createConnectionStateMachine(delegates, options) {
2618
2633
  const onMessage = makeBufferableEventSource();
2619
2634
  onMessage.pause();
2620
- const onConnectionError = makeEventSource();
2621
- function fireErrorEvent(message, code) {
2635
+ const onLiveblocksError = makeEventSource();
2636
+ function fireErrorEvent(errmsg, errcode) {
2622
2637
  return () => {
2623
- onConnectionError.notify({ message, code });
2638
+ const err = new LiveblocksError(errmsg, errcode);
2639
+ onLiveblocksError.notify(err);
2624
2640
  };
2625
2641
  }
2626
2642
  const initialContext = {
@@ -2978,7 +2994,7 @@ function createConnectionStateMachine(delegates, options) {
2978
2994
  didConnect,
2979
2995
  didDisconnect,
2980
2996
  onMessage: onMessage.observable,
2981
- onConnectionError: onConnectionError.observable
2997
+ onLiveblocksError: onLiveblocksError.observable
2982
2998
  }
2983
2999
  };
2984
3000
  }
@@ -6242,83 +6258,6 @@ var ManagedOthers = class {
6242
6258
  }
6243
6259
  };
6244
6260
 
6245
- // src/types/LiveblocksError.ts
6246
- var LiveblocksError = class _LiveblocksError extends Error {
6247
- context;
6248
- constructor(message, context, cause) {
6249
- super(message, { cause });
6250
- this.context = context;
6251
- this.name = "LiveblocksError";
6252
- }
6253
- /** Convenience accessor for error.context.roomId (if available) */
6254
- get roomId() {
6255
- return this.context.roomId;
6256
- }
6257
- /** @deprecated Prefer using `context.code` instead, to enable type narrowing */
6258
- get code() {
6259
- return this.context.code;
6260
- }
6261
- /**
6262
- * Creates a LiveblocksError from a generic error, by attaching Liveblocks
6263
- * contextual information like room ID, thread ID, etc.
6264
- */
6265
- static from(context, cause) {
6266
- return new _LiveblocksError(
6267
- defaultMessageFromContext(context),
6268
- context,
6269
- cause
6270
- );
6271
- }
6272
- };
6273
- function defaultMessageFromContext(context) {
6274
- switch (context.type) {
6275
- case "ROOM_CONNECTION_ERROR": {
6276
- switch (context.code) {
6277
- case 4001:
6278
- return "Not allowed to connect to the room";
6279
- case 4005:
6280
- return "Room is already full";
6281
- case 4006:
6282
- return "Kicked out of the room, because the room ID changed";
6283
- default:
6284
- return "Could not connect to the room";
6285
- }
6286
- }
6287
- case "CREATE_THREAD_ERROR":
6288
- return "Could not create new thread";
6289
- case "DELETE_THREAD_ERROR":
6290
- return "Could not delete thread";
6291
- case "EDIT_THREAD_METADATA_ERROR":
6292
- return "Could not edit thread metadata";
6293
- case "MARK_THREAD_AS_RESOLVED_ERROR":
6294
- return "Could not mark thread as resolved";
6295
- case "MARK_THREAD_AS_UNRESOLVED_ERROR":
6296
- return "Could not mark thread as unresolved";
6297
- case "CREATE_COMMENT_ERROR":
6298
- return "Could not create new comment";
6299
- case "EDIT_COMMENT_ERROR":
6300
- return "Could not edit comment";
6301
- case "DELETE_COMMENT_ERROR":
6302
- return "Could not delete comment";
6303
- case "ADD_REACTION_ERROR":
6304
- return "Could not add reaction";
6305
- case "REMOVE_REACTION_ERROR":
6306
- return "Could not remove reaction";
6307
- case "MARK_INBOX_NOTIFICATION_AS_READ_ERROR":
6308
- return "Could not mark inbox notification as read";
6309
- case "DELETE_INBOX_NOTIFICATION_ERROR":
6310
- return "Could not delete inbox notification";
6311
- case "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR":
6312
- return "Could not mark all inbox notifications as read";
6313
- case "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR":
6314
- return "Could not delete all inbox notifications";
6315
- case "UPDATE_NOTIFICATION_SETTINGS_ERROR":
6316
- return "Could not update notification settings";
6317
- default:
6318
- return assertNever(context, "Unhandled case");
6319
- }
6320
- }
6321
-
6322
6261
  // src/room.ts
6323
6262
  var MAX_SOCKET_MESSAGE_SIZE = 1024 * 1024 - 1024;
6324
6263
  function makeIdFactory(connectionId) {
@@ -6483,17 +6422,13 @@ function createRoom(options, config) {
6483
6422
  managedSocket.events.statusDidChange.subscribe(handleConnectionLossEvent);
6484
6423
  managedSocket.events.didConnect.subscribe(onDidConnect);
6485
6424
  managedSocket.events.didDisconnect.subscribe(onDidDisconnect);
6486
- managedSocket.events.onConnectionError.subscribe(({ message, code }) => {
6487
- const type = "ROOM_CONNECTION_ERROR";
6488
- const err = new LiveblocksError(message, { type, code, roomId });
6489
- const didNotify = config.errorEventSource.notify(err);
6490
- if (!didNotify) {
6491
- if (process.env.NODE_ENV !== "production") {
6492
- error2(
6493
- `Connection to websocket server closed. Reason: ${message} (code: ${code}).`
6494
- );
6495
- }
6425
+ managedSocket.events.onLiveblocksError.subscribe((err) => {
6426
+ if (process.env.NODE_ENV !== "production") {
6427
+ error2(
6428
+ `Connection to websocket server closed. Reason: ${err.message} (code: ${err.code}).`
6429
+ );
6496
6430
  }
6431
+ eventHub.error.notify(err);
6497
6432
  });
6498
6433
  const pool = {
6499
6434
  roomId: config.roomId,
@@ -6556,6 +6491,7 @@ function createRoom(options, config) {
6556
6491
  self: makeEventSource(),
6557
6492
  myPresence: makeEventSource(),
6558
6493
  others: makeEventSource(),
6494
+ error: makeEventSource(),
6559
6495
  storageBatch: makeEventSource(),
6560
6496
  history: makeEventSource(),
6561
6497
  storageDidLoad: makeEventSource(),
@@ -6589,6 +6525,12 @@ function createRoom(options, config) {
6589
6525
  async function createTextVersion() {
6590
6526
  return httpClient.createTextVersion({ roomId });
6591
6527
  }
6528
+ async function executeContextualPrompt(options2) {
6529
+ return httpClient.executeContextualPrompt({
6530
+ roomId,
6531
+ ...options2
6532
+ });
6533
+ }
6592
6534
  function sendMessages(messages) {
6593
6535
  const serializedPayload = JSON.stringify(messages);
6594
6536
  const nonce = context.dynamicSessionInfoSig.get()?.nonce;
@@ -7395,6 +7337,7 @@ ${Array.from(traces).join("\n\n")}`
7395
7337
  others: eventHub.others.observable,
7396
7338
  self: eventHub.self.observable,
7397
7339
  myPresence: eventHub.myPresence.observable,
7340
+ error: eventHub.error.observable,
7398
7341
  /** @deprecated */
7399
7342
  storage: eventHub.storageBatch.observable,
7400
7343
  storageBatch: eventHub.storageBatch.observable,
@@ -7573,6 +7516,8 @@ ${Array.from(traces).join("\n\n")}`
7573
7516
  getTextVersion,
7574
7517
  // create a version
7575
7518
  createTextVersion,
7519
+ // execute contextual prompt
7520
+ executeContextualPrompt,
7576
7521
  // Support for the Liveblocks browser extension
7577
7522
  getSelf_forDevTools: () => selfAsTreeNode.get(),
7578
7523
  getOthers_forDevTools: () => others_forDevTools.get(),
@@ -7585,11 +7530,7 @@ ${Array.from(traces).join("\n\n")}`
7585
7530
  attachmentUrlsStore: httpClient.getOrCreateAttachmentUrlsStore(roomId)
7586
7531
  },
7587
7532
  id: config.roomId,
7588
- subscribe: makeClassicSubscribeFn(
7589
- config.roomId,
7590
- events,
7591
- config.errorEventSource
7592
- ),
7533
+ subscribe: makeClassicSubscribeFn(events),
7593
7534
  connect: () => managedSocket.connect(),
7594
7535
  reconnect: () => managedSocket.reconnect(),
7595
7536
  disconnect: () => managedSocket.disconnect(),
@@ -7658,7 +7599,7 @@ ${Array.from(traces).join("\n\n")}`
7658
7599
  { enumerable: false }
7659
7600
  );
7660
7601
  }
7661
- function makeClassicSubscribeFn(roomId, events, errorEvents) {
7602
+ function makeClassicSubscribeFn(events) {
7662
7603
  function subscribeToLiveStructureDeeply(node, callback) {
7663
7604
  return events.storageBatch.subscribe((updates) => {
7664
7605
  const relatedUpdates = updates.filter(
@@ -7698,13 +7639,8 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
7698
7639
  return cb(others, internalEvent);
7699
7640
  });
7700
7641
  }
7701
- case "error": {
7702
- return errorEvents.subscribe((err) => {
7703
- if (err.roomId === roomId) {
7704
- return callback(err);
7705
- }
7706
- });
7707
- }
7642
+ case "error":
7643
+ return events.error.subscribe(callback);
7708
7644
  case "status":
7709
7645
  return events.status.subscribe(callback);
7710
7646
  case "lost-connection":
@@ -7876,7 +7812,6 @@ function createClient(options) {
7876
7812
  },
7877
7813
  enableDebugLogging: clientOptions.enableDebugLogging,
7878
7814
  baseUrl,
7879
- errorEventSource: liveblocksErrorSource,
7880
7815
  unstable_fallbackToHTTP: !!clientOptions.unstable_fallbackToHTTP,
7881
7816
  unstable_streamData: !!clientOptions.unstable_streamData,
7882
7817
  roomHttpClient: httpClient,
@@ -7959,7 +7894,6 @@ function createClient(options) {
7959
7894
  }
7960
7895
  const syncStatusSources = [];
7961
7896
  const syncStatusSignal = new Signal("synchronized");
7962
- const liveblocksErrorSource = makeEventSource();
7963
7897
  function getSyncStatus() {
7964
7898
  const status = syncStatusSignal.get();
7965
7899
  return status === "synchronizing" ? status : "synchronized";
@@ -8019,7 +7953,6 @@ function createClient(options) {
8019
7953
  },
8020
7954
  getSyncStatus,
8021
7955
  events: {
8022
- error: liveblocksErrorSource,
8023
7956
  syncStatus: syncStatusSignal
8024
7957
  },
8025
7958
  // Internal
@@ -8035,14 +7968,7 @@ function createClient(options) {
8035
7968
  httpClient,
8036
7969
  // Type-level helper only, it's effectively only an identity-function at runtime
8037
7970
  as: () => client,
8038
- createSyncSource,
8039
- emitError: (context, cause) => {
8040
- const error3 = LiveblocksError.from(context, cause);
8041
- const didNotify = liveblocksErrorSource.notify(error3);
8042
- if (!didNotify) {
8043
- error2(error3.message);
8044
- }
8045
- }
7971
+ createSyncSource
8046
7972
  }
8047
7973
  },
8048
7974
  kInternal,
@@ -8878,7 +8804,6 @@ function makePoller(callback, intervalMs, options) {
8878
8804
  }
8879
8805
  doc?.addEventListener("visibilitychange", onVisibilityChange);
8880
8806
  win?.addEventListener("online", onVisibilityChange);
8881
- win?.addEventListener("focus", pollNowIfStale);
8882
8807
  fsm.start();
8883
8808
  return {
8884
8809
  inc,
@@ -9021,7 +8946,6 @@ export {
9021
8946
  LiveList,
9022
8947
  LiveMap,
9023
8948
  LiveObject,
9024
- LiveblocksError,
9025
8949
  MutableSignal,
9026
8950
  NotificationsApiError,
9027
8951
  OpCode,
@@ -9093,6 +9017,7 @@ export {
9093
9017
  toAbsoluteUrl,
9094
9018
  toPlainLson,
9095
9019
  tryParseJson,
9020
+ unstringify,
9096
9021
  url,
9097
9022
  urljoin,
9098
9023
  wait,