@liveblocks/react 3.8.0-tiptap1 → 3.8.1

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/version.ts
2
2
  var PKG_NAME = "@liveblocks/react";
3
- var PKG_VERSION = "3.8.0-tiptap1";
3
+ var PKG_VERSION = "3.8.1";
4
4
  var PKG_FORMAT = "cjs";
5
5
 
6
6
  // src/ClientSideSuspense.tsx
@@ -20,4 +20,4 @@ function ClientSideSuspense(props) {
20
20
 
21
21
 
22
22
  exports.PKG_NAME = PKG_NAME; exports.PKG_VERSION = PKG_VERSION; exports.PKG_FORMAT = PKG_FORMAT; exports.ClientSideSuspense = ClientSideSuspense;
23
- //# sourceMappingURL=chunk-ZU7C6DJE.cjs.map
23
+ //# sourceMappingURL=chunk-BXCA7DCZ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/liveblocks/liveblocks/packages/liveblocks-react/dist/chunk-ZU7C6DJE.cjs","../src/version.ts","../src/ClientSideSuspense.tsx"],"names":[],"mappings":"AAAA;ACGO,IAAM,SAAA,EAAW,mBAAA;AACjB,IAAM,YAAA,EAAiD,eAAA;AACvD,IAAM,WAAA,EAAgD,KAAA;ADD7D;AACA;AEJA,8BAA8C;AAkC1C,+CAAA;AAVG,SAAS,kBAAA,CAAmB,KAAA,EAAc;AAC/C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,EAAA,EAAI,6BAAA,KAAc,CAAA;AAE5C,EAAA,8BAAA,CAAU,EAAA,GAAM;AAGd,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA,EAAG,CAAC,CAAC,CAAA;AAEL,EAAA,uBACE,6BAAA,eAAC,EAAA,EAAS,QAAA,EAAU,KAAA,CAAM,QAAA,EACvB,QAAA,EAAA,QAAA,EACG,OAAO,KAAA,CAAM,SAAA,IAAa,WAAA,EACxB,KAAA,CAAM,QAAA,CAAS,EAAA,EACf,KAAA,CAAM,SAAA,EACR,KAAA,CAAM,SAAA,CACZ,CAAA;AAEJ;AF5BA;AACA;AACE;AACA;AACA;AACA;AACF,iJAAC","file":"/home/runner/work/liveblocks/liveblocks/packages/liveblocks-react/dist/chunk-ZU7C6DJE.cjs","sourcesContent":[null,"declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n","import type { ReactNode } from \"react\";\nimport { Suspense, useEffect, useState } from \"react\";\n\ntype Props = {\n fallback: ReactNode;\n children: (() => ReactNode | undefined) | ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <Suspense fallback={props.fallback}>\n {mounted\n ? typeof props.children === \"function\"\n ? props.children()\n : props.children\n : props.fallback}\n </Suspense>\n );\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/liveblocks/liveblocks/packages/liveblocks-react/dist/chunk-BXCA7DCZ.cjs","../src/version.ts","../src/ClientSideSuspense.tsx"],"names":[],"mappings":"AAAA;ACGO,IAAM,SAAA,EAAW,mBAAA;AACjB,IAAM,YAAA,EAAiD,OAAA;AACvD,IAAM,WAAA,EAAgD,KAAA;ADD7D;AACA;AEJA,8BAA8C;AAkC1C,+CAAA;AAVG,SAAS,kBAAA,CAAmB,KAAA,EAAc;AAC/C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,EAAA,EAAI,6BAAA,KAAc,CAAA;AAE5C,EAAA,8BAAA,CAAU,EAAA,GAAM;AAGd,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA,EAAG,CAAC,CAAC,CAAA;AAEL,EAAA,uBACE,6BAAA,eAAC,EAAA,EAAS,QAAA,EAAU,KAAA,CAAM,QAAA,EACvB,QAAA,EAAA,QAAA,EACG,OAAO,KAAA,CAAM,SAAA,IAAa,WAAA,EACxB,KAAA,CAAM,QAAA,CAAS,EAAA,EACf,KAAA,CAAM,SAAA,EACR,KAAA,CAAM,SAAA,CACZ,CAAA;AAEJ;AF5BA;AACA;AACE;AACA;AACA;AACA;AACF,iJAAC","file":"/home/runner/work/liveblocks/liveblocks/packages/liveblocks-react/dist/chunk-BXCA7DCZ.cjs","sourcesContent":[null,"declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n","import type { ReactNode } from \"react\";\nimport { Suspense, useEffect, useState } from \"react\";\n\ntype Props = {\n fallback: ReactNode;\n children: (() => ReactNode | undefined) | ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <Suspense fallback={props.fallback}>\n {mounted\n ? typeof props.children === \"function\"\n ? props.children()\n : props.children\n : props.fallback}\n </Suspense>\n );\n}\n"]}
@@ -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({
@@ -172,6 +177,7 @@ import {
172
177
  assert,
173
178
  console as console2,
174
179
  createClient,
180
+ DefaultMap as DefaultMap2,
175
181
  HttpError,
176
182
  kInternal as kInternal3,
177
183
  makePoller,
@@ -216,21 +222,6 @@ function ASYNC_OK(fieldOrData, data) {
216
222
  }
217
223
  }
218
224
 
219
- // src/lib/itertools.ts
220
- function find(it, predicate) {
221
- for (const item of it) {
222
- if (predicate(item)) return item;
223
- }
224
- return void 0;
225
- }
226
- function count(it, predicate) {
227
- let total = 0;
228
- for (const item of it) {
229
- if (predicate(item)) total++;
230
- }
231
- return total;
232
- }
233
-
234
225
  // src/lib/ssr.ts
235
226
  function ensureNotServerSide() {
236
227
  if (typeof window === "undefined") {
@@ -324,8 +315,16 @@ function autobind(self) {
324
315
  } while ((obj = Reflect.getPrototypeOf(obj)) && obj !== Object.prototype);
325
316
  }
326
317
 
318
+ // src/lib/itertools.ts
319
+ function find(it, predicate) {
320
+ for (const item of it) {
321
+ if (predicate(item)) return item;
322
+ }
323
+ return void 0;
324
+ }
325
+
327
326
  // src/lib/querying.ts
328
- import { isStartsWithOperator } from "@liveblocks/core";
327
+ import { isNumberOperator, isStartsWithOperator } from "@liveblocks/core";
329
328
  function makeThreadsFilter(query) {
330
329
  return (thread) => matchesThreadsQuery(thread, query) && matchesMetadata(thread, query);
331
330
  }
@@ -347,10 +346,15 @@ function matchesOperator(value, op) {
347
346
  return value === void 0;
348
347
  } else if (isStartsWithOperator(op)) {
349
348
  return typeof value === "string" && value.startsWith(op.startsWith);
349
+ } else if (isNumberOperator(op)) {
350
+ return typeof value === "number" && matchesNumberOperator(value, op);
350
351
  } else {
351
352
  return value === op;
352
353
  }
353
354
  }
355
+ function matchesNumberOperator(value, op) {
356
+ return (op.lt === void 0 || value < op.lt) && (op.gt === void 0 || value > op.gt) && (op.lte === void 0 || value <= op.lte) && (op.gte === void 0 || value >= op.gte);
357
+ }
354
358
  function makeInboxNotificationsFilter(query) {
355
359
  return (inboxNotification) => matchesInboxNotificationsQuery(inboxNotification, query);
356
360
  }
@@ -722,6 +726,21 @@ function createStore_forNotifications() {
722
726
  upsert
723
727
  };
724
728
  }
729
+ function createStore_forUnreadNotificationsCount() {
730
+ const baseSignal = new MutableSignal3(
731
+ /* @__PURE__ */ new Map()
732
+ );
733
+ function update(queryKey, count) {
734
+ baseSignal.mutate((lut) => {
735
+ lut.set(queryKey, count);
736
+ });
737
+ }
738
+ return {
739
+ signal: DerivedSignal.from(baseSignal, (c) => Object.fromEntries(c)),
740
+ // Mutations
741
+ update
742
+ };
743
+ }
725
744
  function createStore_forSubscriptions(updates, threads) {
726
745
  const baseSignal = new MutableSignal3(/* @__PURE__ */ new Map());
727
746
  function applyDelta(newSubscriptions, deletedSubscriptions) {
@@ -911,6 +930,7 @@ var UmbrellaStore = class {
911
930
  roomSubscriptionSettings;
912
931
  // prettier-ignore
913
932
  historyVersions;
933
+ unreadNotificationsCount;
914
934
  permissionHints;
915
935
  notificationSettings;
916
936
  optimisticUpdates;
@@ -958,6 +978,7 @@ var UmbrellaStore = class {
958
978
  this.optimisticUpdates.signal
959
979
  );
960
980
  this.historyVersions = createStore_forHistoryVersions();
981
+ this.unreadNotificationsCount = createStore_forUnreadNotificationsCount();
961
982
  const threadifications = DerivedSignal.from(
962
983
  this.threads.signal,
963
984
  this.notifications.signal,
@@ -1114,6 +1135,35 @@ var UmbrellaStore = class {
1114
1135
  };
1115
1136
  }
1116
1137
  );
1138
+ const unreadNotificationsCount = new DefaultMap(
1139
+ (queryKey) => {
1140
+ const query = JSON.parse(queryKey);
1141
+ const resource = new SinglePageResource(async () => {
1142
+ const result = await this.#client.getUnreadInboxNotificationsCount({
1143
+ query
1144
+ });
1145
+ this.unreadNotificationsCount.update(queryKey, result);
1146
+ });
1147
+ const signal = DerivedSignal.from(
1148
+ () => {
1149
+ const result = resource.get();
1150
+ if (result.isLoading || result.error) {
1151
+ return result;
1152
+ } else {
1153
+ return ASYNC_OK(
1154
+ "count",
1155
+ nn(this.unreadNotificationsCount.signal.get()[queryKey])
1156
+ );
1157
+ }
1158
+ },
1159
+ shallow
1160
+ );
1161
+ return {
1162
+ signal,
1163
+ waitUntilLoaded: resource.waitUntilLoaded
1164
+ };
1165
+ }
1166
+ );
1117
1167
  const roomSubscriptionSettingsByRoomId = new DefaultMap(
1118
1168
  (roomId) => {
1119
1169
  const resource = new SinglePageResource(async () => {
@@ -1262,6 +1312,7 @@ var UmbrellaStore = class {
1262
1312
  loadingUserThreads,
1263
1313
  notifications,
1264
1314
  loadingNotifications,
1315
+ unreadNotificationsCount,
1265
1316
  roomSubscriptionSettingsByRoomId,
1266
1317
  versionsByRoomId,
1267
1318
  notificationSettings,
@@ -1469,6 +1520,14 @@ var UmbrellaStore = class {
1469
1520
  result.subscriptions.deleted
1470
1521
  );
1471
1522
  }
1523
+ async fetchUnreadNotificationsCount(queryKey, signal) {
1524
+ const query = JSON.parse(queryKey);
1525
+ const result = await this.#client.getUnreadInboxNotificationsCount({
1526
+ query,
1527
+ signal
1528
+ });
1529
+ this.unreadNotificationsCount.update(queryKey, result);
1530
+ }
1472
1531
  async fetchRoomThreadsDeltaUpdate(roomId, signal) {
1473
1532
  const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
1474
1533
  if (lastRequestedAt === void 0) {
@@ -1983,16 +2042,10 @@ var _umbrellaStores = /* @__PURE__ */ new WeakMap();
1983
2042
  var _extras = /* @__PURE__ */ new WeakMap();
1984
2043
  var _bundles = /* @__PURE__ */ new WeakMap();
1985
2044
  function selectorFor_useUnreadInboxNotificationsCount(result) {
1986
- if (!result.inboxNotifications) {
2045
+ if (!("count" in result) || result.count === void 0) {
1987
2046
  return result;
1988
2047
  }
1989
- return ASYNC_OK(
1990
- "count",
1991
- count(
1992
- result.inboxNotifications,
1993
- (n) => n.readAt === null || n.readAt < n.notifiedAt
1994
- )
1995
- );
2048
+ return ASYNC_OK("count", result.count);
1996
2049
  }
1997
2050
  function selectorFor_useUser(state, userId) {
1998
2051
  if (state === void 0 || state?.isLoading) {
@@ -2091,6 +2144,22 @@ function makeLiveblocksExtrasForClient(client) {
2091
2144
  config.NOTIFICATIONS_POLL_INTERVAL,
2092
2145
  { maxStaleTimeMs: config.NOTIFICATIONS_MAX_STALE_TIME }
2093
2146
  );
2147
+ const unreadNotificationsCountPollersByQueryKey = new DefaultMap2(
2148
+ (queryKey) => makePoller(
2149
+ async (signal) => {
2150
+ try {
2151
+ return await store.fetchUnreadNotificationsCount(queryKey, signal);
2152
+ } catch (err) {
2153
+ console2.warn(
2154
+ `Polling unread inbox notifications countfailed: ${String(err)}`
2155
+ );
2156
+ throw err;
2157
+ }
2158
+ },
2159
+ config.NOTIFICATIONS_POLL_INTERVAL,
2160
+ { maxStaleTimeMs: config.NOTIFICATIONS_MAX_STALE_TIME }
2161
+ )
2162
+ );
2094
2163
  const userThreadsPoller = makePoller(
2095
2164
  async (signal) => {
2096
2165
  try {
@@ -2121,7 +2190,8 @@ function makeLiveblocksExtrasForClient(client) {
2121
2190
  store,
2122
2191
  notificationsPoller,
2123
2192
  userThreadsPoller,
2124
- notificationSettingsPoller
2193
+ notificationSettingsPoller,
2194
+ unreadNotificationsCountPollersByQueryKey
2125
2195
  };
2126
2196
  }
2127
2197
  function makeLiveblocksContextBundle(client) {
@@ -2151,6 +2221,7 @@ function makeLiveblocksContextBundle(client) {
2151
2221
  useAiChats,
2152
2222
  useAiChat,
2153
2223
  useAiChatMessages,
2224
+ useAiChatStatus,
2154
2225
  useCreateAiChat,
2155
2226
  useDeleteAiChat,
2156
2227
  useSendAiMessage,
@@ -2170,6 +2241,7 @@ function makeLiveblocksContextBundle(client) {
2170
2241
  useAiChats: useAiChatsSuspense,
2171
2242
  useAiChat: useAiChatSuspense,
2172
2243
  useAiChatMessages: useAiChatMessagesSuspense,
2244
+ useAiChatStatus,
2173
2245
  useCreateAiChat,
2174
2246
  useDeleteAiChat,
2175
2247
  useSendAiMessage,
@@ -2223,11 +2295,31 @@ function useInboxNotificationsSuspense_withClient(client, options) {
2223
2295
  return result;
2224
2296
  }
2225
2297
  function useUnreadInboxNotificationsCount_withClient(client, options) {
2226
- return useInboxNotifications_withClient(
2227
- client,
2298
+ const { store, unreadNotificationsCountPollersByQueryKey: pollers } = getLiveblocksExtrasForClient(client);
2299
+ const queryKey = makeInboxNotificationsQueryKey(options?.query);
2300
+ const poller = pollers.getOrCreate(queryKey);
2301
+ useEffect4(
2302
+ () => void store.outputs.unreadNotificationsCount.getOrCreate(queryKey).waitUntilLoaded()
2303
+ // NOTE: Deliberately *not* using a dependency array here!
2304
+ //
2305
+ // It is important to call waitUntil on *every* render.
2306
+ // This is harmless though, on most renders, except:
2307
+ // 1. The very first render, in which case we'll want to trigger the initial page fetch.
2308
+ // 2. All other subsequent renders now "just" return the same promise (a quick operation).
2309
+ // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2310
+ // *next* render after that, a *new* fetch/promise will get created.
2311
+ );
2312
+ useEffect4(() => {
2313
+ poller.inc();
2314
+ poller.pollNowIfStale();
2315
+ return () => {
2316
+ poller.dec();
2317
+ };
2318
+ }, [poller]);
2319
+ return useSignal(
2320
+ store.outputs.unreadNotificationsCount.getOrCreate(queryKey).signal,
2228
2321
  selectorFor_useUnreadInboxNotificationsCount,
2229
- shallow3,
2230
- options
2322
+ shallow3
2231
2323
  );
2232
2324
  }
2233
2325
  function useUnreadInboxNotificationsCountSuspense_withClient(client, options) {
@@ -2235,7 +2327,7 @@ function useUnreadInboxNotificationsCountSuspense_withClient(client, options) {
2235
2327
  const store = getLiveblocksExtrasForClient(client).store;
2236
2328
  const queryKey = makeInboxNotificationsQueryKey(options?.query);
2237
2329
  use(
2238
- store.outputs.loadingNotifications.getOrCreate(queryKey).waitUntilLoaded()
2330
+ store.outputs.unreadNotificationsCount.getOrCreate(queryKey).waitUntilLoaded()
2239
2331
  );
2240
2332
  const result = useUnreadInboxNotificationsCount_withClient(client, options);
2241
2333
  assert(!result.isLoading, "Did not expect loading");
@@ -2245,7 +2337,7 @@ function useUnreadInboxNotificationsCountSuspense_withClient(client, options) {
2245
2337
  function useMarkInboxNotificationAsRead_withClient(client) {
2246
2338
  return useCallback2(
2247
2339
  (inboxNotificationId) => {
2248
- const { store } = getLiveblocksExtrasForClient(client);
2340
+ const { store, unreadNotificationsCountPollersByQueryKey } = getLiveblocksExtrasForClient(client);
2249
2341
  const readAt = /* @__PURE__ */ new Date();
2250
2342
  const optimisticId = store.optimisticUpdates.add({
2251
2343
  type: "mark-inbox-notification-as-read",
@@ -2259,6 +2351,10 @@ function useMarkInboxNotificationAsRead_withClient(client) {
2259
2351
  readAt,
2260
2352
  optimisticId
2261
2353
  );
2354
+ for (const poller of unreadNotificationsCountPollersByQueryKey.values()) {
2355
+ poller.markAsStale();
2356
+ poller.pollNowIfStale();
2357
+ }
2262
2358
  },
2263
2359
  (err) => {
2264
2360
  store.optimisticUpdates.remove(optimisticId);
@@ -2277,7 +2373,7 @@ function useMarkInboxNotificationAsRead_withClient(client) {
2277
2373
  }
2278
2374
  function useMarkAllInboxNotificationsAsRead_withClient(client) {
2279
2375
  return useCallback2(() => {
2280
- const { store } = getLiveblocksExtrasForClient(client);
2376
+ const { store, unreadNotificationsCountPollersByQueryKey } = getLiveblocksExtrasForClient(client);
2281
2377
  const readAt = /* @__PURE__ */ new Date();
2282
2378
  const optimisticId = store.optimisticUpdates.add({
2283
2379
  type: "mark-all-inbox-notifications-as-read",
@@ -2286,6 +2382,10 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
2286
2382
  client.markAllInboxNotificationsAsRead().then(
2287
2383
  () => {
2288
2384
  store.markAllInboxNotificationsRead(optimisticId, readAt);
2385
+ for (const poller of unreadNotificationsCountPollersByQueryKey.values()) {
2386
+ poller.markAsStale();
2387
+ poller.pollNowIfStale();
2388
+ }
2289
2389
  },
2290
2390
  (err) => {
2291
2391
  store.optimisticUpdates.remove(optimisticId);
@@ -2301,7 +2401,7 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
2301
2401
  function useDeleteInboxNotification_withClient(client) {
2302
2402
  return useCallback2(
2303
2403
  (inboxNotificationId) => {
2304
- const { store } = getLiveblocksExtrasForClient(client);
2404
+ const { store, unreadNotificationsCountPollersByQueryKey } = getLiveblocksExtrasForClient(client);
2305
2405
  const deletedAt = /* @__PURE__ */ new Date();
2306
2406
  const optimisticId = store.optimisticUpdates.add({
2307
2407
  type: "delete-inbox-notification",
@@ -2311,6 +2411,10 @@ function useDeleteInboxNotification_withClient(client) {
2311
2411
  client.deleteInboxNotification(inboxNotificationId).then(
2312
2412
  () => {
2313
2413
  store.deleteInboxNotification(inboxNotificationId, optimisticId);
2414
+ for (const poller of unreadNotificationsCountPollersByQueryKey.values()) {
2415
+ poller.markAsStale();
2416
+ poller.pollNowIfStale();
2417
+ }
2314
2418
  },
2315
2419
  (err) => {
2316
2420
  store.optimisticUpdates.remove(optimisticId);
@@ -2326,7 +2430,7 @@ function useDeleteInboxNotification_withClient(client) {
2326
2430
  }
2327
2431
  function useDeleteAllInboxNotifications_withClient(client) {
2328
2432
  return useCallback2(() => {
2329
- const { store } = getLiveblocksExtrasForClient(client);
2433
+ const { store, unreadNotificationsCountPollersByQueryKey } = getLiveblocksExtrasForClient(client);
2330
2434
  const deletedAt = /* @__PURE__ */ new Date();
2331
2435
  const optimisticId = store.optimisticUpdates.add({
2332
2436
  type: "delete-all-inbox-notifications",
@@ -2335,6 +2439,10 @@ function useDeleteAllInboxNotifications_withClient(client) {
2335
2439
  client.deleteAllInboxNotifications().then(
2336
2440
  () => {
2337
2441
  store.deleteAllInboxNotifications(optimisticId);
2442
+ for (const poller of unreadNotificationsCountPollersByQueryKey.values()) {
2443
+ poller.markAsStale();
2444
+ poller.pollNowIfStale();
2445
+ }
2338
2446
  },
2339
2447
  (err) => {
2340
2448
  store.optimisticUpdates.remove(optimisticId);
@@ -2746,6 +2854,43 @@ function useDeleteAiChat() {
2746
2854
  [client]
2747
2855
  );
2748
2856
  }
2857
+ var LOADING = Object.freeze({ status: "loading" });
2858
+ var IDLE = Object.freeze({ status: "idle" });
2859
+ function useAiChatStatus(chatId, branchId) {
2860
+ const client = useClient();
2861
+ const store = getUmbrellaStoreForClient(client);
2862
+ useEnsureAiConnection(client);
2863
+ useEffect4(
2864
+ () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branchId ?? null).waitUntilLoaded()
2865
+ );
2866
+ return useSignal(
2867
+ // Signal
2868
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branchId ?? null).signal,
2869
+ // Selector
2870
+ (result) => {
2871
+ if (result.isLoading) return LOADING;
2872
+ if (result.error) return IDLE;
2873
+ const messages = result.messages;
2874
+ const lastMessage = messages[messages.length - 1];
2875
+ if (lastMessage?.role !== "assistant") return IDLE;
2876
+ if (lastMessage.status !== "generating" && lastMessage.status !== "awaiting-tool")
2877
+ return IDLE;
2878
+ const contentSoFar = lastMessage.contentSoFar;
2879
+ const lastPart = contentSoFar[contentSoFar.length - 1];
2880
+ if (lastPart?.type === "tool-invocation") {
2881
+ return {
2882
+ status: "generating",
2883
+ partType: "tool-invocation",
2884
+ toolName: lastPart.name
2885
+ };
2886
+ } else {
2887
+ return { status: "generating", partType: lastPart?.type };
2888
+ }
2889
+ },
2890
+ // Consider { status: "generating", partType: "text" } and { status: "generating", partType: "text" } equal
2891
+ shallow3
2892
+ );
2893
+ }
2749
2894
  function useSendAiMessage(chatId, options) {
2750
2895
  const client = useClient();
2751
2896
  return useCallback2(
@@ -2797,20 +2942,12 @@ To ensure the correct copilot ID is used, specify it either through the hook as
2797
2942
  {
2798
2943
  stream: messageOptions.stream ?? options?.stream,
2799
2944
  copilotId: resolvedCopilotId,
2800
- timeout: messageOptions.timeout ?? options?.timeout,
2801
- knowledge: messageOptions.knowledge ?? options?.knowledge
2945
+ timeout: messageOptions.timeout ?? options?.timeout
2802
2946
  }
2803
2947
  );
2804
2948
  return newMessage;
2805
2949
  },
2806
- [
2807
- client,
2808
- chatId,
2809
- options?.copilotId,
2810
- options?.stream,
2811
- options?.timeout,
2812
- options?.knowledge
2813
- ]
2950
+ [client, chatId, options?.copilotId, options?.stream, options?.timeout]
2814
2951
  );
2815
2952
  }
2816
2953
  function createSharedContext(client) {
@@ -3064,7 +3201,7 @@ import {
3064
3201
  console as console3,
3065
3202
  createCommentId,
3066
3203
  createThreadId,
3067
- DefaultMap as DefaultMap2,
3204
+ DefaultMap as DefaultMap3,
3068
3205
  errorIf,
3069
3206
  getSubscriptionKey as getSubscriptionKey2,
3070
3207
  HttpError as HttpError2,
@@ -3198,7 +3335,7 @@ function makeRoomExtrasForClient(client) {
3198
3335
  throw innerError;
3199
3336
  }
3200
3337
  }
3201
- const threadsPollersByRoomId = new DefaultMap2(
3338
+ const threadsPollersByRoomId = new DefaultMap3(
3202
3339
  (roomId) => makePoller2(
3203
3340
  async (signal) => {
3204
3341
  try {
@@ -3212,7 +3349,7 @@ function makeRoomExtrasForClient(client) {
3212
3349
  { maxStaleTimeMs: config.ROOM_THREADS_MAX_STALE_TIME }
3213
3350
  )
3214
3351
  );
3215
- const versionsPollersByRoomId = new DefaultMap2(
3352
+ const versionsPollersByRoomId = new DefaultMap3(
3216
3353
  (roomId) => makePoller2(
3217
3354
  async (signal) => {
3218
3355
  try {
@@ -3226,7 +3363,7 @@ function makeRoomExtrasForClient(client) {
3226
3363
  { maxStaleTimeMs: config.HISTORY_VERSIONS_MAX_STALE_TIME }
3227
3364
  )
3228
3365
  );
3229
- const roomSubscriptionSettingsPollersByRoomId = new DefaultMap2(
3366
+ const roomSubscriptionSettingsPollersByRoomId = new DefaultMap3(
3230
3367
  (roomId) => makePoller2(
3231
3368
  async (signal) => {
3232
3369
  try {
@@ -4692,6 +4829,7 @@ export {
4692
4829
  getUmbrellaStoreForClient,
4693
4830
  useCreateAiChat,
4694
4831
  useDeleteAiChat,
4832
+ useAiChatStatus,
4695
4833
  useSendAiMessage,
4696
4834
  LiveblocksProvider,
4697
4835
  createLiveblocksContext,
@@ -4798,4 +4936,4 @@ export {
4798
4936
  _useStorageRoot,
4799
4937
  _useUpdateMyPresence
4800
4938
  };
4801
- //# sourceMappingURL=chunk-OKYUUXNY.js.map
4939
+ //# sourceMappingURL=chunk-QY4EJ7GZ.js.map