@liveblocks/react 3.8.0 → 3.9.0

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/_private.cjs CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
 
27
27
 
28
- var _chunkIQBSX6NScjs = require('./chunk-IQBSX6NS.cjs');
28
+ var _chunkNGMOQDHXcjs = require('./chunk-NGMOQDHX.cjs');
29
29
 
30
30
  // src/lib/use-layout-effect.ts
31
31
  var _react = require('react');
@@ -50,7 +50,7 @@ function selectorFor_useGroup(state) {
50
50
  };
51
51
  }
52
52
  function useGroup(groupId) {
53
- const client = _chunkIQBSX6NScjs.useClient.call(void 0, );
53
+ const client = _chunkNGMOQDHXcjs.useClient.call(void 0, );
54
54
  const store = client[_core.kInternal].httpClient.groupsStore;
55
55
  const getGroupState = _react.useCallback.call(void 0,
56
56
  () => store.getItemState(groupId),
@@ -59,7 +59,7 @@ function useGroup(groupId) {
59
59
  _react.useEffect.call(void 0, () => {
60
60
  void store.enqueue(groupId);
61
61
  }, [store, groupId]);
62
- return _chunkIQBSX6NScjs.useSyncExternalStoreWithSelector.call(void 0,
62
+ return _chunkNGMOQDHXcjs.useSyncExternalStoreWithSelector.call(void 0,
63
63
  store.subscribe,
64
64
  getGroupState,
65
65
  getGroupState,
@@ -80,8 +80,8 @@ function normalizeMentionSuggestions(suggestions) {
80
80
  function useMentionSuggestions(roomId, search) {
81
81
  const [mentionSuggestions, setMentionSuggestions] = _react.useState.call(void 0, );
82
82
  const lastInvokedAt = _react.useRef.call(void 0, );
83
- const resolveMentionSuggestions = _chunkIQBSX6NScjs.useResolveMentionSuggestions.call(void 0, );
84
- const mentionSuggestionsCache = _chunkIQBSX6NScjs.useMentionSuggestionsCache.call(void 0, );
83
+ const resolveMentionSuggestions = _chunkNGMOQDHXcjs.useResolveMentionSuggestions.call(void 0, );
84
+ const mentionSuggestionsCache = _chunkNGMOQDHXcjs.useMentionSuggestionsCache.call(void 0, );
85
85
  _react.useEffect.call(void 0, () => {
86
86
  if (search === void 0 || !resolveMentionSuggestions) {
87
87
  return;
@@ -136,7 +136,7 @@ function useMentionSuggestions(roomId, search) {
136
136
 
137
137
 
138
138
  function useSyncSource() {
139
- const client = _chunkIQBSX6NScjs.useClient.call(void 0, );
139
+ const client = _chunkNGMOQDHXcjs.useClient.call(void 0, );
140
140
  const createSyncSource = client[_core.kInternal].createSyncSource;
141
141
  const [syncSource, setSyncSource] = _react.useState.call(void 0, );
142
142
  _react.useEffect.call(void 0, () => {
@@ -176,5 +176,5 @@ function useSyncSource() {
176
176
 
177
177
 
178
178
 
179
- exports.getUmbrellaStoreForClient = _chunkIQBSX6NScjs.getUmbrellaStoreForClient; exports.useAddRoomCommentReaction = _chunkIQBSX6NScjs.useAddRoomCommentReaction; exports.useClientOrNull = _chunkIQBSX6NScjs.useClientOrNull; exports.useCreateRoomComment = _chunkIQBSX6NScjs.useCreateRoomComment; exports.useCreateRoomThread = _chunkIQBSX6NScjs.useCreateRoomThread; exports.useCreateTextMention = _chunkIQBSX6NScjs.useCreateTextMention; exports.useDeleteRoomComment = _chunkIQBSX6NScjs.useDeleteRoomComment; exports.useDeleteRoomThread = _chunkIQBSX6NScjs.useDeleteRoomThread; exports.useDeleteTextMention = _chunkIQBSX6NScjs.useDeleteTextMention; exports.useEditRoomComment = _chunkIQBSX6NScjs.useEditRoomComment; exports.useEditRoomThreadMetadata = _chunkIQBSX6NScjs.useEditRoomThreadMetadata; exports.useGroup = useGroup; exports.useLatest = _chunkIQBSX6NScjs.useLatest; exports.useLayoutEffect = useLayoutEffect; exports.useMarkRoomThreadAsRead = _chunkIQBSX6NScjs.useMarkRoomThreadAsRead; exports.useMarkRoomThreadAsResolved = _chunkIQBSX6NScjs.useMarkRoomThreadAsResolved; exports.useMarkRoomThreadAsUnresolved = _chunkIQBSX6NScjs.useMarkRoomThreadAsUnresolved; exports.useMentionSuggestions = useMentionSuggestions; exports.useMentionSuggestionsCache = _chunkIQBSX6NScjs.useMentionSuggestionsCache; exports.useRemoveRoomCommentReaction = _chunkIQBSX6NScjs.useRemoveRoomCommentReaction; exports.useReportTextEditor = _chunkIQBSX6NScjs.useReportTextEditor; exports.useResolveMentionSuggestions = _chunkIQBSX6NScjs.useResolveMentionSuggestions; exports.useRoomAttachmentUrl = _chunkIQBSX6NScjs.useRoomAttachmentUrl; exports.useRoomPermissions = _chunkIQBSX6NScjs.useRoomPermissions; exports.useRoomThreadSubscription = _chunkIQBSX6NScjs.useRoomThreadSubscription; exports.useSignal = _chunkIQBSX6NScjs.useSignal; exports.useSyncExternalStoreWithSelector = _chunkIQBSX6NScjs.useSyncExternalStoreWithSelector; exports.useSyncSource = useSyncSource; exports.useYjsProvider = _chunkIQBSX6NScjs.useYjsProvider;
179
+ exports.getUmbrellaStoreForClient = _chunkNGMOQDHXcjs.getUmbrellaStoreForClient; exports.useAddRoomCommentReaction = _chunkNGMOQDHXcjs.useAddRoomCommentReaction; exports.useClientOrNull = _chunkNGMOQDHXcjs.useClientOrNull; exports.useCreateRoomComment = _chunkNGMOQDHXcjs.useCreateRoomComment; exports.useCreateRoomThread = _chunkNGMOQDHXcjs.useCreateRoomThread; exports.useCreateTextMention = _chunkNGMOQDHXcjs.useCreateTextMention; exports.useDeleteRoomComment = _chunkNGMOQDHXcjs.useDeleteRoomComment; exports.useDeleteRoomThread = _chunkNGMOQDHXcjs.useDeleteRoomThread; exports.useDeleteTextMention = _chunkNGMOQDHXcjs.useDeleteTextMention; exports.useEditRoomComment = _chunkNGMOQDHXcjs.useEditRoomComment; exports.useEditRoomThreadMetadata = _chunkNGMOQDHXcjs.useEditRoomThreadMetadata; exports.useGroup = useGroup; exports.useLatest = _chunkNGMOQDHXcjs.useLatest; exports.useLayoutEffect = useLayoutEffect; exports.useMarkRoomThreadAsRead = _chunkNGMOQDHXcjs.useMarkRoomThreadAsRead; exports.useMarkRoomThreadAsResolved = _chunkNGMOQDHXcjs.useMarkRoomThreadAsResolved; exports.useMarkRoomThreadAsUnresolved = _chunkNGMOQDHXcjs.useMarkRoomThreadAsUnresolved; exports.useMentionSuggestions = useMentionSuggestions; exports.useMentionSuggestionsCache = _chunkNGMOQDHXcjs.useMentionSuggestionsCache; exports.useRemoveRoomCommentReaction = _chunkNGMOQDHXcjs.useRemoveRoomCommentReaction; exports.useReportTextEditor = _chunkNGMOQDHXcjs.useReportTextEditor; exports.useResolveMentionSuggestions = _chunkNGMOQDHXcjs.useResolveMentionSuggestions; exports.useRoomAttachmentUrl = _chunkNGMOQDHXcjs.useRoomAttachmentUrl; exports.useRoomPermissions = _chunkNGMOQDHXcjs.useRoomPermissions; exports.useRoomThreadSubscription = _chunkNGMOQDHXcjs.useRoomThreadSubscription; exports.useSignal = _chunkNGMOQDHXcjs.useSignal; exports.useSyncExternalStoreWithSelector = _chunkNGMOQDHXcjs.useSyncExternalStoreWithSelector; exports.useSyncSource = useSyncSource; exports.useYjsProvider = _chunkNGMOQDHXcjs.useYjsProvider;
180
180
  //# sourceMappingURL=_private.cjs.map
@@ -1,5 +1,5 @@
1
- import { G as GroupAsyncResult } from './room-C97RX2dB.cjs';
2
- export { g as getUmbrellaStoreForClient, a as useAddRoomCommentReaction, u as useClientOrNull, b as useCreateRoomComment, c as useCreateRoomThread, d as useCreateTextMention, e as useDeleteRoomComment, f as useDeleteRoomThread, h as useDeleteTextMention, i as useEditRoomComment, j as useEditRoomThreadMetadata, k as useMarkRoomThreadAsRead, l as useMarkRoomThreadAsResolved, m as useMarkRoomThreadAsUnresolved, n as useMentionSuggestionsCache, o as useRemoveRoomCommentReaction, p as useReportTextEditor, q as useResolveMentionSuggestions, r as useRoomAttachmentUrl, s as useRoomPermissions, t as useRoomThreadSubscription, v as useYjsProvider } from './room-C97RX2dB.cjs';
1
+ import { G as GroupAsyncResult } from './room-BZvk8RRP.cjs';
2
+ export { g as getUmbrellaStoreForClient, a as useAddRoomCommentReaction, u as useClientOrNull, b as useCreateRoomComment, c as useCreateRoomThread, d as useCreateTextMention, e as useDeleteRoomComment, f as useDeleteRoomThread, h as useDeleteTextMention, i as useEditRoomComment, j as useEditRoomThreadMetadata, k as useMarkRoomThreadAsRead, l as useMarkRoomThreadAsResolved, m as useMarkRoomThreadAsUnresolved, n as useMentionSuggestionsCache, o as useRemoveRoomCommentReaction, p as useReportTextEditor, q as useResolveMentionSuggestions, r as useRoomAttachmentUrl, s as useRoomPermissions, t as useRoomThreadSubscription, v as useYjsProvider } from './room-BZvk8RRP.cjs';
3
3
  import { MutableRefObject, useEffect } from 'react';
4
4
  import { MentionData, ISignal, SyncSource } from '@liveblocks/core';
5
5
  import '@liveblocks/client';
@@ -1,5 +1,5 @@
1
- import { G as GroupAsyncResult } from './room-C97RX2dB.js';
2
- export { g as getUmbrellaStoreForClient, a as useAddRoomCommentReaction, u as useClientOrNull, b as useCreateRoomComment, c as useCreateRoomThread, d as useCreateTextMention, e as useDeleteRoomComment, f as useDeleteRoomThread, h as useDeleteTextMention, i as useEditRoomComment, j as useEditRoomThreadMetadata, k as useMarkRoomThreadAsRead, l as useMarkRoomThreadAsResolved, m as useMarkRoomThreadAsUnresolved, n as useMentionSuggestionsCache, o as useRemoveRoomCommentReaction, p as useReportTextEditor, q as useResolveMentionSuggestions, r as useRoomAttachmentUrl, s as useRoomPermissions, t as useRoomThreadSubscription, v as useYjsProvider } from './room-C97RX2dB.js';
1
+ import { G as GroupAsyncResult } from './room-BZvk8RRP.js';
2
+ export { g as getUmbrellaStoreForClient, a as useAddRoomCommentReaction, u as useClientOrNull, b as useCreateRoomComment, c as useCreateRoomThread, d as useCreateTextMention, e as useDeleteRoomComment, f as useDeleteRoomThread, h as useDeleteTextMention, i as useEditRoomComment, j as useEditRoomThreadMetadata, k as useMarkRoomThreadAsRead, l as useMarkRoomThreadAsResolved, m as useMarkRoomThreadAsUnresolved, n as useMentionSuggestionsCache, o as useRemoveRoomCommentReaction, p as useReportTextEditor, q as useResolveMentionSuggestions, r as useRoomAttachmentUrl, s as useRoomPermissions, t as useRoomThreadSubscription, v as useYjsProvider } from './room-BZvk8RRP.js';
3
3
  import { MutableRefObject, useEffect } from 'react';
4
4
  import { MentionData, ISignal, SyncSource } from '@liveblocks/core';
5
5
  import '@liveblocks/client';
package/dist/_private.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  useSignal,
26
26
  useSyncExternalStoreWithSelector,
27
27
  useYjsProvider
28
- } from "./chunk-2R44HQCN.js";
28
+ } from "./chunk-J2LMX3A6.js";
29
29
 
30
30
  // src/lib/use-layout-effect.ts
31
31
  import { useEffect, useLayoutEffect as useOriginalLayoutEffect } from "react";
@@ -39,23 +39,28 @@ function useRandom() {
39
39
  var RegisterAiKnowledge = memo(function RegisterAiKnowledge2(props) {
40
40
  const layerId = useId();
41
41
  const ai = useAi();
42
- const { description, value } = props;
42
+ const { description, value, chatId } = props;
43
43
  const [layerKey, setLayerKey] = useState();
44
44
  useEffect2(() => {
45
- const layerKey2 = ai.registerKnowledgeLayer(layerId);
45
+ const { layerKey: layerKey2, deregister } = ai.registerKnowledgeLayer(layerId, chatId);
46
46
  setLayerKey(layerKey2);
47
47
  return () => {
48
- ai.deregisterKnowledgeLayer(layerKey2);
48
+ deregister();
49
49
  setLayerKey(void 0);
50
50
  };
51
- }, [ai, layerId]);
51
+ }, [ai, layerId, chatId]);
52
52
  const randomKey = useRandom();
53
53
  const knowledgeKey = props.id ?? randomKey;
54
54
  useEffect2(() => {
55
55
  if (layerKey !== void 0) {
56
- ai.updateKnowledge(layerKey, { description, value }, knowledgeKey);
56
+ ai.updateKnowledge(
57
+ layerKey,
58
+ { description, value },
59
+ knowledgeKey,
60
+ chatId
61
+ );
57
62
  }
58
- }, [ai, layerKey, knowledgeKey, description, value]);
63
+ }, [ai, layerKey, knowledgeKey, description, value, chatId]);
59
64
  return null;
60
65
  });
61
66
  var RegisterAiTool = memo(function RegisterAiTool2({
@@ -281,7 +286,7 @@ import {
281
286
  createNotificationSettings,
282
287
  DefaultMap,
283
288
  DerivedSignal,
284
- getSubscriptionKey,
289
+ getSubscriptionKey as getSubscriptionKey2,
285
290
  kInternal as kInternal2,
286
291
  MutableSignal as MutableSignal3,
287
292
  nanoid as nanoid2,
@@ -319,12 +324,20 @@ function find(it, predicate) {
319
324
  }
320
325
 
321
326
  // src/lib/querying.ts
322
- import { isNumberOperator, isStartsWithOperator } from "@liveblocks/core";
323
- function makeThreadsFilter(query) {
324
- return (thread) => matchesThreadsQuery(thread, query) && matchesMetadata(thread, query);
327
+ import {
328
+ getSubscriptionKey,
329
+ isNumberOperator,
330
+ isStartsWithOperator
331
+ } from "@liveblocks/core";
332
+ function makeThreadsFilter(query, subscriptions) {
333
+ return (thread) => matchesThreadsQuery(thread, query, subscriptions) && matchesMetadata(thread, query);
325
334
  }
326
- function matchesThreadsQuery(thread, q) {
327
- return q.resolved === void 0 || thread.resolved === q.resolved;
335
+ function matchesThreadsQuery(thread, q, subscriptions) {
336
+ let subscription = void 0;
337
+ if (subscriptions) {
338
+ subscription = subscriptions?.[getSubscriptionKey("thread", thread.id)];
339
+ }
340
+ return (q.resolved === void 0 || thread.resolved === q.resolved) && (q.subscribed === void 0 || q.subscribed === true && subscription !== void 0 || q.subscribed === false && subscription === void 0);
328
341
  }
329
342
  function matchesMetadata(thread, q) {
330
343
  const metadata = thread.metadata;
@@ -470,15 +483,17 @@ var ThreadDB = class _ThreadDB {
470
483
  * 'desc' means by updatedAt DESC
471
484
  *
472
485
  * Will never return deleted threads in the result.
486
+ *
487
+ * Subscriptions are needed to filter threads based on the user's subscriptions.
473
488
  */
474
- findMany(roomId, query, direction) {
489
+ findMany(roomId, query, direction, subscriptions) {
475
490
  const index = direction === "desc" ? this.#desc : this.#asc;
476
491
  const crit = [];
477
492
  if (roomId !== void 0) {
478
493
  crit.push((t) => t.roomId === roomId);
479
494
  }
480
495
  if (query !== void 0) {
481
- crit.push(makeThreadsFilter(query));
496
+ crit.push(makeThreadsFilter(query, subscriptions));
482
497
  }
483
498
  return Array.from(index.filter((t) => crit.every((pred) => pred(t))));
484
499
  }
@@ -609,10 +624,12 @@ var SinglePageResource = class {
609
624
  #signal;
610
625
  signal;
611
626
  #fetchPage;
612
- constructor(fetchPage) {
627
+ #autoRetry = true;
628
+ constructor(fetchPage, autoRetry2 = true) {
613
629
  this.#signal = new Signal(ASYNC_LOADING);
614
630
  this.signal = this.#signal.asReadonly();
615
631
  this.#fetchPage = fetchPage;
632
+ this.#autoRetry = autoRetry2;
616
633
  autobind(this);
617
634
  }
618
635
  get() {
@@ -623,11 +640,7 @@ var SinglePageResource = class {
623
640
  if (this.#cachedPromise) {
624
641
  return this.#cachedPromise;
625
642
  }
626
- const initialFetcher$ = autoRetry(
627
- () => this.#fetchPage(),
628
- 5,
629
- [5e3, 5e3, 1e4, 15e3]
630
- );
643
+ const initialFetcher$ = this.#autoRetry ? autoRetry(() => this.#fetchPage(), 5, [5e3, 5e3, 1e4, 15e3]) : this.#fetchPage();
631
644
  const promise = usify(initialFetcher$);
632
645
  promise.then(
633
646
  () => {
@@ -635,10 +648,12 @@ var SinglePageResource = class {
635
648
  },
636
649
  (err) => {
637
650
  this.#signal.set(ASYNC_ERR(err));
638
- setTimeout(() => {
639
- this.#cachedPromise = null;
640
- this.#signal.set(ASYNC_LOADING);
641
- }, 5e3);
651
+ if (this.#autoRetry) {
652
+ setTimeout(() => {
653
+ this.#cachedPromise = null;
654
+ this.#signal.set(ASYNC_LOADING);
655
+ }, 5e3);
656
+ }
642
657
  }
643
658
  );
644
659
  this.#cachedPromise = promise;
@@ -742,11 +757,11 @@ function createStore_forSubscriptions(updates, threads) {
742
757
  baseSignal.mutate((lut) => {
743
758
  let mutated = false;
744
759
  for (const s of newSubscriptions) {
745
- lut.set(getSubscriptionKey(s), s);
760
+ lut.set(getSubscriptionKey2(s), s);
746
761
  mutated = true;
747
762
  }
748
763
  for (const s of deletedSubscriptions) {
749
- lut.delete(getSubscriptionKey(s));
764
+ lut.delete(getSubscriptionKey2(s));
750
765
  mutated = true;
751
766
  }
752
767
  return mutated;
@@ -754,7 +769,7 @@ function createStore_forSubscriptions(updates, threads) {
754
769
  }
755
770
  function create(subscription) {
756
771
  baseSignal.mutate((lut) => {
757
- lut.set(getSubscriptionKey(subscription), subscription);
772
+ lut.set(getSubscriptionKey2(subscription), subscription);
758
773
  });
759
774
  }
760
775
  function deleteOne(subscriptionKey) {
@@ -817,6 +832,19 @@ function createStore_forHistoryVersions() {
817
832
  update
818
833
  };
819
834
  }
835
+ function createStore_forUrlsMetadata() {
836
+ const baseSignal = new MutableSignal3(/* @__PURE__ */ new Map());
837
+ function update(url, metadata) {
838
+ baseSignal.mutate((lut) => {
839
+ lut.set(url, metadata);
840
+ });
841
+ }
842
+ return {
843
+ signal: DerivedSignal.from(baseSignal, (m) => Object.fromEntries(m)),
844
+ // Mutations
845
+ update
846
+ };
847
+ }
820
848
  function createStore_forPermissionHints() {
821
849
  const permissionsByRoomId = new DefaultMap(
822
850
  () => new Signal(/* @__PURE__ */ new Set())
@@ -926,6 +954,7 @@ var UmbrellaStore = class {
926
954
  // prettier-ignore
927
955
  historyVersions;
928
956
  unreadNotificationsCount;
957
+ urlsMetadata;
929
958
  permissionHints;
930
959
  notificationSettings;
931
960
  optimisticUpdates;
@@ -974,6 +1003,7 @@ var UmbrellaStore = class {
974
1003
  );
975
1004
  this.historyVersions = createStore_forHistoryVersions();
976
1005
  this.unreadNotificationsCount = createStore_forUnreadNotificationsCount();
1006
+ this.urlsMetadata = createStore_forUrlsMetadata();
977
1007
  const threadifications = DerivedSignal.from(
978
1008
  this.threads.signal,
979
1009
  this.notifications.signal,
@@ -1021,11 +1051,13 @@ var UmbrellaStore = class {
1021
1051
  if (result.isLoading || result.error) {
1022
1052
  return result;
1023
1053
  }
1054
+ const subscriptions = threadSubscriptions.get().subscriptions;
1024
1055
  const threads2 = this.outputs.threads.get().findMany(
1025
1056
  void 0,
1026
1057
  // Do _not_ filter by roomId
1027
1058
  query ?? {},
1028
- "desc"
1059
+ "desc",
1060
+ subscriptions
1029
1061
  );
1030
1062
  const page = result.data;
1031
1063
  return {
@@ -1069,7 +1101,8 @@ var UmbrellaStore = class {
1069
1101
  if (result.isLoading || result.error) {
1070
1102
  return result;
1071
1103
  }
1072
- const threads2 = this.outputs.threads.get().findMany(roomId, query ?? {}, "asc");
1104
+ const subscriptions = threadSubscriptions.get().subscriptions;
1105
+ const threads2 = this.outputs.threads.get().findMany(roomId, query ?? {}, "asc", subscriptions);
1073
1106
  const page = result.data;
1074
1107
  return {
1075
1108
  isLoading: false,
@@ -1300,6 +1333,22 @@ var UmbrellaStore = class {
1300
1333
  }, shallow);
1301
1334
  return { signal, waitUntilLoaded: resource.waitUntilLoaded };
1302
1335
  });
1336
+ const urlMetadataByUrl = new DefaultMap(
1337
+ (url) => {
1338
+ const resource = new SinglePageResource(async () => {
1339
+ const metadata = await this.#client[kInternal2].httpClient.getUrlMetadata(url);
1340
+ this.urlsMetadata.update(url, metadata);
1341
+ }, false);
1342
+ const signal = DerivedSignal.from(() => {
1343
+ const result = resource.get();
1344
+ if (result.isLoading || result.error) {
1345
+ return result;
1346
+ }
1347
+ return ASYNC_OK("metadata", nn(this.urlsMetadata.signal.get()[url]));
1348
+ }, shallow);
1349
+ return { signal, waitUntilLoaded: resource.waitUntilLoaded };
1350
+ }
1351
+ );
1303
1352
  this.outputs = {
1304
1353
  threadifications,
1305
1354
  threads,
@@ -1314,7 +1363,8 @@ var UmbrellaStore = class {
1314
1363
  threadSubscriptions,
1315
1364
  aiChats,
1316
1365
  messagesByChatId,
1317
- aiChatById
1366
+ aiChatById,
1367
+ urlMetadataByUrl
1318
1368
  };
1319
1369
  autobind(this);
1320
1370
  }
@@ -1795,9 +1845,14 @@ function applyOptimisticUpdates_forSubscriptions(subscriptionsLUT, threads, opti
1795
1845
  if (!update.settings.threads) {
1796
1846
  continue;
1797
1847
  }
1798
- const roomThreads = threads.findMany(update.roomId, void 0, "desc");
1848
+ const roomThreads = threads.findMany(
1849
+ update.roomId,
1850
+ void 0,
1851
+ "desc",
1852
+ void 0
1853
+ );
1799
1854
  for (const thread of roomThreads) {
1800
- const subscriptionKey = getSubscriptionKey("thread", thread.id);
1855
+ const subscriptionKey = getSubscriptionKey2("thread", thread.id);
1801
1856
  switch (update.settings.threads) {
1802
1857
  // Create subscriptions for all existing threads in the room
1803
1858
  case "all": {
@@ -2220,6 +2275,7 @@ function makeLiveblocksContextBundle(client) {
2220
2275
  useCreateAiChat,
2221
2276
  useDeleteAiChat,
2222
2277
  useSendAiMessage,
2278
+ useUrlMetadata,
2223
2279
  ...shared.classic,
2224
2280
  suspense: {
2225
2281
  LiveblocksProvider: LiveblocksProvider2,
@@ -2240,6 +2296,7 @@ function makeLiveblocksContextBundle(client) {
2240
2296
  useCreateAiChat,
2241
2297
  useDeleteAiChat,
2242
2298
  useSendAiMessage,
2299
+ useUrlMetadata: useUrlMetadataSuspense,
2243
2300
  ...shared.suspense
2244
2301
  }
2245
2302
  };
@@ -2817,6 +2874,32 @@ function useAiChatSuspense(chatId) {
2817
2874
  assert(!result.isLoading, "Did not expect loading");
2818
2875
  return result;
2819
2876
  }
2877
+ function useUrlMetadata(url) {
2878
+ const client = useClient();
2879
+ const store = getUmbrellaStoreForClient(client);
2880
+ useEffect4(
2881
+ () => void store.outputs.urlMetadataByUrl.getOrCreate(url).waitUntilLoaded()
2882
+ // NOTE: Deliberately *not* using a dependency array here!
2883
+ //
2884
+ // It is important to call waitUntil on *every* render.
2885
+ // This is harmless though, on most renders, except:
2886
+ // 1. The very first render, in which case we'll want to trigger the initial page fetch.
2887
+ // 2. All other subsequent renders now "just" return the same promise (a quick operation).
2888
+ // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2889
+ // *next* render after that, a *new* fetch/promise will get created.
2890
+ );
2891
+ return useSignal(store.outputs.urlMetadataByUrl.getOrCreate(url).signal);
2892
+ }
2893
+ function useUrlMetadataSuspense(url) {
2894
+ ensureNotServerSide();
2895
+ const client = useClient();
2896
+ const store = getUmbrellaStoreForClient(client);
2897
+ use(store.outputs.urlMetadataByUrl.getOrCreate(url).waitUntilLoaded());
2898
+ const result = useUrlMetadata(url);
2899
+ assert(!result.error, "Did not expect error");
2900
+ assert(!result.isLoading, "Did not expect loading");
2901
+ return result;
2902
+ }
2820
2903
  function useCreateAiChat() {
2821
2904
  const client = useClient();
2822
2905
  return useCallback2(
@@ -2849,6 +2932,7 @@ function useDeleteAiChat() {
2849
2932
  [client]
2850
2933
  );
2851
2934
  }
2935
+ var DISCONNECTED = Object.freeze({ status: "disconnected" });
2852
2936
  var LOADING = Object.freeze({ status: "loading" });
2853
2937
  var IDLE = Object.freeze({ status: "idle" });
2854
2938
  function useAiChatStatus(chatId, branchId) {
@@ -2858,7 +2942,14 @@ function useAiChatStatus(chatId, branchId) {
2858
2942
  useEffect4(
2859
2943
  () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branchId ?? null).waitUntilLoaded()
2860
2944
  );
2861
- return useSignal(
2945
+ const isAvailable = useSignal(
2946
+ // Subscribe to connection status signal
2947
+ client[kInternal3].ai.signals.status\u03A3,
2948
+ // "Disconnected" means the AI service is not available
2949
+ // as it represents a final error status.
2950
+ (status) => status !== "disconnected"
2951
+ );
2952
+ const chatStatus = useSignal(
2862
2953
  // Signal
2863
2954
  store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branchId ?? null).signal,
2864
2955
  // Selector
@@ -2879,12 +2970,19 @@ function useAiChatStatus(chatId, branchId) {
2879
2970
  toolName: lastPart.name
2880
2971
  };
2881
2972
  } else {
2882
- return { status: "generating", partType: lastPart?.type };
2973
+ return {
2974
+ status: "generating",
2975
+ partType: lastPart?.type
2976
+ };
2883
2977
  }
2884
2978
  },
2885
2979
  // Consider { status: "generating", partType: "text" } and { status: "generating", partType: "text" } equal
2886
2980
  shallow3
2887
2981
  );
2982
+ if (!isAvailable) {
2983
+ return DISCONNECTED;
2984
+ }
2985
+ return chatStatus;
2888
2986
  }
2889
2987
  function useSendAiMessage(chatId, options) {
2890
2988
  const client = useClient();
@@ -2937,20 +3035,12 @@ To ensure the correct copilot ID is used, specify it either through the hook as
2937
3035
  {
2938
3036
  stream: messageOptions.stream ?? options?.stream,
2939
3037
  copilotId: resolvedCopilotId,
2940
- timeout: messageOptions.timeout ?? options?.timeout,
2941
- knowledge: messageOptions.knowledge ?? options?.knowledge
3038
+ timeout: messageOptions.timeout ?? options?.timeout
2942
3039
  }
2943
3040
  );
2944
3041
  return newMessage;
2945
3042
  },
2946
- [
2947
- client,
2948
- chatId,
2949
- options?.copilotId,
2950
- options?.stream,
2951
- options?.timeout,
2952
- options?.knowledge
2953
- ]
3043
+ [client, chatId, options?.copilotId, options?.stream, options?.timeout]
2954
3044
  );
2955
3045
  }
2956
3046
  function createSharedContext(client) {
@@ -3148,6 +3238,8 @@ var _useAiChat = useAiChat;
3148
3238
  var _useAiChatSuspense = useAiChatSuspense;
3149
3239
  var _useAiChatMessages = useAiChatMessages;
3150
3240
  var _useAiChatMessagesSuspense = useAiChatMessagesSuspense;
3241
+ var _useUrlMetadata = useUrlMetadata;
3242
+ var _useUrlMetadataSuspense = useUrlMetadataSuspense;
3151
3243
  function useSyncStatus_withClient(client, options) {
3152
3244
  const smooth = useInitial(options?.smooth ?? false);
3153
3245
  if (smooth) {
@@ -3206,7 +3298,7 @@ import {
3206
3298
  createThreadId,
3207
3299
  DefaultMap as DefaultMap3,
3208
3300
  errorIf,
3209
- getSubscriptionKey as getSubscriptionKey2,
3301
+ getSubscriptionKey as getSubscriptionKey3,
3210
3302
  HttpError as HttpError2,
3211
3303
  kInternal as kInternal4,
3212
3304
  makePoller as makePoller2,
@@ -4453,7 +4545,7 @@ function useUnsubscribeFromRoomThread(roomId) {
4453
4545
  client[kInternal4].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4454
4546
  () => {
4455
4547
  store.deleteSubscription(
4456
- getSubscriptionKey2("thread", threadId),
4548
+ getSubscriptionKey3("thread", threadId),
4457
4549
  optimisticId
4458
4550
  );
4459
4551
  },
@@ -4474,7 +4566,7 @@ function useRoomThreadSubscription(roomId, threadId) {
4474
4566
  const client = useClient();
4475
4567
  const { store } = getRoomExtrasForClient(client);
4476
4568
  const subscriptionKey = useMemo4(
4477
- () => getSubscriptionKey2("thread", threadId),
4569
+ () => getSubscriptionKey3("thread", threadId),
4478
4570
  [threadId]
4479
4571
  );
4480
4572
  const subscribeToThread = useSubscribeToRoomThread(roomId);
@@ -4862,6 +4954,8 @@ export {
4862
4954
  _useAiChatSuspense,
4863
4955
  _useAiChatMessages,
4864
4956
  _useAiChatMessagesSuspense,
4957
+ _useUrlMetadata,
4958
+ _useUrlMetadataSuspense,
4865
4959
  useSyncStatus,
4866
4960
  useErrorListener,
4867
4961
  useStatus,
@@ -4939,4 +5033,4 @@ export {
4939
5033
  _useStorageRoot,
4940
5034
  _useUpdateMyPresence
4941
5035
  };
4942
- //# sourceMappingURL=chunk-2R44HQCN.js.map
5036
+ //# sourceMappingURL=chunk-J2LMX3A6.js.map