@ai-matrx/messaging 0.11.8 → 0.12.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/react.js CHANGED
@@ -1449,6 +1449,145 @@ function createReadCache(options) {
1449
1449
  };
1450
1450
  }
1451
1451
 
1452
+ // src/core/session-identity.ts
1453
+ var RESOLVING = Object.freeze({
1454
+ state: "resolving",
1455
+ userId: null
1456
+ });
1457
+ var SERVER_SESSION_IDENTITY = RESOLVING;
1458
+ function authOf(client) {
1459
+ const candidate = client.auth;
1460
+ if (candidate === null || typeof candidate !== "object") return null;
1461
+ const auth = candidate;
1462
+ if (typeof auth.getSession !== "function") return null;
1463
+ if (typeof auth.onAuthStateChange !== "function") return null;
1464
+ return auth;
1465
+ }
1466
+ function userIdOf(session) {
1467
+ const id = session?.user?.id;
1468
+ return typeof id === "string" && id.length > 0 ? asUserId(id) : null;
1469
+ }
1470
+ var NO_AUTH_SOURCE = {
1471
+ message: "Messaging cannot tell who is signed in: the Supabase client it was given has no auth session source.",
1472
+ remedy: "Pass your app's browser Supabase client \u2014 the same client it signs in with \u2014 to <MessagingProvider client={...}> or createMessagingRepository({ client }). Messaging reads the acting user from that client's session; there is no prop or option for a user id, on purpose (DD-241)."
1473
+ };
1474
+ function createSessionIdentity(options) {
1475
+ const { client, onDiagnostic } = options;
1476
+ const listeners = /* @__PURE__ */ new Set();
1477
+ let current = RESOLVING;
1478
+ let disposed = false;
1479
+ const publish = (state, userId) => {
1480
+ if (disposed) return;
1481
+ if (current.state === state && current.userId === userId) return;
1482
+ current = Object.freeze({ state, userId });
1483
+ for (const listener of [...listeners]) listener();
1484
+ };
1485
+ const subscribeOnly = (hasAuthSource) => ({
1486
+ hasAuthSource,
1487
+ snapshot: () => current,
1488
+ subscribe: (listener) => {
1489
+ listeners.add(listener);
1490
+ return () => {
1491
+ listeners.delete(listener);
1492
+ };
1493
+ },
1494
+ dispose: () => {
1495
+ disposed = true;
1496
+ listeners.clear();
1497
+ }
1498
+ });
1499
+ const auth = authOf(client);
1500
+ if (auth === null) {
1501
+ onDiagnostic?.({ level: "error", ...NO_AUTH_SOURCE });
1502
+ current = Object.freeze({ state: "resolved", userId: null });
1503
+ return subscribeOnly(false);
1504
+ }
1505
+ void (async () => {
1506
+ try {
1507
+ const result = await auth.getSession();
1508
+ publish("resolved", userIdOf(result?.data?.session));
1509
+ } catch (error) {
1510
+ onDiagnostic?.({
1511
+ level: "warn",
1512
+ message: `Messaging could not read the signed-in session: ${String(
1513
+ error?.message ?? error
1514
+ )}`,
1515
+ remedy: "Messages stay unavailable on this device until the session can be read. Reload the page; if it persists, sign in again."
1516
+ });
1517
+ publish("resolved", null);
1518
+ }
1519
+ })();
1520
+ const subscription = auth.onAuthStateChange((_event, session) => {
1521
+ publish("resolved", userIdOf(session));
1522
+ });
1523
+ const base = subscribeOnly(true);
1524
+ return {
1525
+ hasAuthSource: true,
1526
+ snapshot: base.snapshot,
1527
+ subscribe: base.subscribe,
1528
+ dispose: () => {
1529
+ base.dispose();
1530
+ try {
1531
+ subscription.data.subscription.unsubscribe();
1532
+ } catch {
1533
+ }
1534
+ }
1535
+ };
1536
+ }
1537
+ function actingUserIdOf(identity) {
1538
+ return new Promise((resolve, reject) => {
1539
+ const settle = () => {
1540
+ const snapshot = identity.snapshot();
1541
+ if (snapshot.state !== "resolved") return false;
1542
+ if (snapshot.userId === null) {
1543
+ reject(identity.hasAuthSource ? noSignedInUserError() : noAuthSourceError());
1544
+ return true;
1545
+ }
1546
+ resolve(snapshot.userId);
1547
+ return true;
1548
+ };
1549
+ if (settle()) return;
1550
+ const unsubscribe = identity.subscribe(() => {
1551
+ if (settle()) unsubscribe();
1552
+ });
1553
+ });
1554
+ }
1555
+ function noSignedInUserError() {
1556
+ return new MessagingError(
1557
+ "session-unavailable",
1558
+ "Messaging has no signed-in user: the Supabase client's session names nobody.",
1559
+ "Sign in, then try again. Messaging takes the acting user from the session of the client it was given \u2014 never from an id handed in by the caller (DD-241), because a handed-in id goes stale the moment the auth cookie rotates and lands on the wire as sender_id and created_by."
1560
+ );
1561
+ }
1562
+ function noAuthSourceError() {
1563
+ return new MessagingError(
1564
+ "misconfigured",
1565
+ NO_AUTH_SOURCE.message,
1566
+ NO_AUTH_SOURCE.remedy
1567
+ );
1568
+ }
1569
+ async function readActingUserId(client) {
1570
+ const auth = authOf(client);
1571
+ if (auth === null) throw noAuthSourceError();
1572
+ let session;
1573
+ try {
1574
+ const result = await auth.getSession();
1575
+ session = result?.data?.session;
1576
+ } catch (error) {
1577
+ throw new MessagingError(
1578
+ "session-unavailable",
1579
+ `Messaging could not read the signed-in session: ${String(
1580
+ error?.message ?? error
1581
+ )}`,
1582
+ "Reload the page and try again; if it persists, sign in again.",
1583
+ error
1584
+ );
1585
+ }
1586
+ const userId = userIdOf(session);
1587
+ if (userId === null) throw noSignedInUserError();
1588
+ return userId;
1589
+ }
1590
+
1452
1591
  // src/core/repository.ts
1453
1592
  var MESSAGING_SCHEMA = "communication";
1454
1593
  var MESSAGING_RPC_SCHEMA = "public";
@@ -1485,8 +1624,15 @@ function sleep(ms) {
1485
1624
  return new Promise((resolve) => setTimeout(resolve, jittered));
1486
1625
  }
1487
1626
  function createMessagingRepository(options) {
1488
- const { identity } = options;
1489
- const org = requireOrg(identity.organizationId, "createMessagingRepository");
1627
+ const org = requireOrg(options.organizationId, "createMessagingRepository");
1628
+ const handedIn = options.identity;
1629
+ if (handedIn !== void 0 && handedIn !== null && handedIn.userId !== void 0) {
1630
+ options.onDiagnostic?.(
1631
+ "createMessagingRepository({ identity: { userId } }) is ignored: since 0.12.0 messaging reads the acting user from the session of the client it was given (DD-241). Remove the option and pass { client, organizationId } \u2014 a handed-in id goes stale the moment the auth cookie rotates, and it lands on the wire as sender_id and created_by."
1632
+ );
1633
+ }
1634
+ const sessionIdentity = options.sessionIdentity;
1635
+ const actingUserId = () => sessionIdentity !== void 0 ? actingUserIdOf(sessionIdentity) : readActingUserId(options.client);
1490
1636
  const userCache = createReadCache({
1491
1637
  ttlMs: options.userTtlMs ?? 5 * 6e4,
1492
1638
  ...options.now !== void 0 ? { now: options.now } : {}
@@ -1523,6 +1669,9 @@ function createMessagingRepository(options) {
1523
1669
  }
1524
1670
  }
1525
1671
  }
1672
+ function actingUser(operation) {
1673
+ return withSessionRetry(operation, () => actingUserId());
1674
+ }
1526
1675
  async function rpc(fn, args, operation) {
1527
1676
  const { data, error } = await rpcDb().rpc(fn, args);
1528
1677
  if (error !== null) throw normalizeMessagingError(error, operation);
@@ -1546,17 +1695,19 @@ function createMessagingRepository(options) {
1546
1695
  return found;
1547
1696
  }
1548
1697
  const repository = {
1549
- identity,
1698
+ organizationId: org,
1699
+ actingUserId,
1550
1700
  async listConversations(args = {}) {
1551
1701
  const limit = args.limit ?? 30;
1552
1702
  const archived = args.archived ?? DEFAULT_MESSAGING_ARCHIVE_FILTER;
1553
1703
  const operation = "listConversations";
1704
+ const me = await actingUser(operation);
1554
1705
  const rows = await withSessionRetry(
1555
1706
  operation,
1556
1707
  () => rpc(
1557
1708
  RPCS.conversationsWithDetails,
1558
1709
  {
1559
- p_user_id: identity.userId,
1710
+ p_user_id: me,
1560
1711
  p_limit: limit + 1,
1561
1712
  p_before_sort_at: args.cursor?.beforeSortAt ?? null,
1562
1713
  p_before_conversation_id: args.cursor?.beforeConversationId ?? null,
@@ -1573,7 +1724,7 @@ function createMessagingRepository(options) {
1573
1724
  throw invalidResponse(operation, `${RPCS.conversationsWithDetails} did not return rows`);
1574
1725
  }
1575
1726
  const projected = (rows ?? []).map(
1576
- (row) => projectConversationSummary(row, identity.userId, org)
1727
+ (row) => projectConversationSummary(row, me, org)
1577
1728
  );
1578
1729
  const hasMore = projected.length > limit;
1579
1730
  const items = hasMore ? projected.slice(0, limit) : projected;
@@ -1587,12 +1738,13 @@ function createMessagingRepository(options) {
1587
1738
  async countArchivedConversations(args = {}) {
1588
1739
  const limit = args.limit ?? 100;
1589
1740
  const operation = "countArchivedConversations";
1741
+ const me = await actingUser(operation);
1590
1742
  const rows = await withSessionRetry(
1591
1743
  operation,
1592
1744
  () => rpc(
1593
1745
  RPCS.conversationsWithDetails,
1594
1746
  {
1595
- p_user_id: identity.userId,
1747
+ p_user_id: me,
1596
1748
  p_limit: limit + 1,
1597
1749
  p_before_sort_at: null,
1598
1750
  p_before_conversation_id: null,
@@ -1609,6 +1761,7 @@ function createMessagingRepository(options) {
1609
1761
  },
1610
1762
  async getConversation(id) {
1611
1763
  const operation = "getConversation";
1764
+ const me = await actingUser(operation);
1612
1765
  const { data, error } = await withSessionRetry(
1613
1766
  operation,
1614
1767
  async () => db().from(TABLES.conversations).select(CONVERSATION_COLUMNS).eq("id", id).single()
@@ -1629,7 +1782,7 @@ function createMessagingRepository(options) {
1629
1782
  participants: [],
1630
1783
  unread_count: 0
1631
1784
  },
1632
- identity.userId,
1785
+ me,
1633
1786
  org
1634
1787
  );
1635
1788
  return summary.conversation;
@@ -1673,6 +1826,7 @@ function createMessagingRepository(options) {
1673
1826
  },
1674
1827
  async getOrCreateDirectConversation(otherUserId) {
1675
1828
  const operation = "getOrCreateDirectConversation";
1829
+ const me = await actingUser(operation);
1676
1830
  const id = await withSessionRetry(
1677
1831
  operation,
1678
1832
  () => rpc(
@@ -1681,7 +1835,7 @@ function createMessagingRepository(options) {
1681
1835
  // The RPC's own guard requires an `authenticated` caller to pass
1682
1836
  // THEMSELVES as user1; passing them in the other slot is a denial,
1683
1837
  // not a preference.
1684
- p_user1_id: identity.userId,
1838
+ p_user1_id: me,
1685
1839
  p_user2_id: otherUserId,
1686
1840
  p_organization_id: org
1687
1841
  },
@@ -1695,13 +1849,14 @@ function createMessagingRepository(options) {
1695
1849
  },
1696
1850
  async createGroupConversation({ name, memberIds }) {
1697
1851
  const operation = "createGroupConversation";
1852
+ const me = await actingUser(operation);
1698
1853
  const { data, error } = await withSessionRetry(
1699
1854
  operation,
1700
1855
  async () => db().from(TABLES.conversations).insert({
1701
1856
  type: "group",
1702
1857
  group_name: name,
1703
1858
  organization_id: org,
1704
- created_by: identity.userId
1859
+ created_by: me
1705
1860
  }).select("id").single()
1706
1861
  );
1707
1862
  if (error !== null) throw normalizeMessagingError(error, operation);
@@ -1709,14 +1864,14 @@ function createMessagingRepository(options) {
1709
1864
  if (typeof conversationId !== "string") {
1710
1865
  throw invalidResponse(operation, "insert returned no conversation id");
1711
1866
  }
1712
- const members = [.../* @__PURE__ */ new Set([identity.userId, ...memberIds])];
1867
+ const members = [.../* @__PURE__ */ new Set([me, ...memberIds])];
1713
1868
  const { error: memberError } = await db().from(TABLES.participants).insert(
1714
1869
  members.map((userId) => ({
1715
1870
  conversation_id: conversationId,
1716
1871
  user_id: userId,
1717
- role: userId === identity.userId ? "owner" : "member",
1872
+ role: userId === me ? "owner" : "member",
1718
1873
  organization_id: org,
1719
- created_by: identity.userId
1874
+ created_by: me
1720
1875
  }))
1721
1876
  );
1722
1877
  if (memberError !== null) throw normalizeMessagingError(memberError, operation);
@@ -1724,11 +1879,12 @@ function createMessagingRepository(options) {
1724
1879
  },
1725
1880
  async insertMessage(draft, clientMessageId) {
1726
1881
  const operation = "insertMessage";
1882
+ const me = await actingUser(operation);
1727
1883
  const { data, error } = await db().from(TABLES.messages).insert({
1728
1884
  conversation_id: draft.conversationId,
1729
- sender_id: identity.userId,
1885
+ sender_id: me,
1730
1886
  organization_id: org,
1731
- created_by: identity.userId,
1887
+ created_by: me,
1732
1888
  content: draft.content,
1733
1889
  message_type: draft.kind ?? "text",
1734
1890
  status: "sent",
@@ -1750,10 +1906,11 @@ function createMessagingRepository(options) {
1750
1906
  },
1751
1907
  async editMessage(id, content) {
1752
1908
  const operation = "editMessage";
1909
+ const me = await actingUser(operation);
1753
1910
  const { data, error } = await db().from(TABLES.messages).update({
1754
1911
  content,
1755
1912
  edited_at: (/* @__PURE__ */ new Date()).toISOString(),
1756
- updated_by: identity.userId
1913
+ updated_by: me
1757
1914
  }).eq("id", id).select(MESSAGE_COLUMNS).single();
1758
1915
  if (error !== null) throw normalizeMessagingError(error, operation);
1759
1916
  if (data === null) throw invalidResponse(operation, "update returned no row");
@@ -1761,47 +1918,53 @@ function createMessagingRepository(options) {
1761
1918
  },
1762
1919
  async deleteMessage(id, forEveryone) {
1763
1920
  const operation = "deleteMessage";
1921
+ const me = await actingUser(operation);
1764
1922
  const { error } = await db().from(TABLES.messages).update({
1765
1923
  deleted_at: (/* @__PURE__ */ new Date()).toISOString(),
1766
1924
  deleted_for_everyone: forEveryone,
1767
- updated_by: identity.userId
1925
+ updated_by: me
1768
1926
  }).eq("id", id);
1769
1927
  if (error !== null) throw normalizeMessagingError(error, operation);
1770
1928
  },
1771
1929
  async markRead(conversationId, at) {
1772
1930
  const operation = "markRead";
1773
- const { error } = await db().from(TABLES.participants).update({ last_read_at: at ?? (/* @__PURE__ */ new Date()).toISOString(), updated_by: identity.userId }).eq("conversation_id", conversationId).eq("user_id", identity.userId);
1931
+ const me = await actingUser(operation);
1932
+ const { error } = await db().from(TABLES.participants).update({ last_read_at: at ?? (/* @__PURE__ */ new Date()).toISOString(), updated_by: me }).eq("conversation_id", conversationId).eq("user_id", me);
1774
1933
  if (error !== null) throw normalizeMessagingError(error, operation);
1775
1934
  },
1776
1935
  async setConversationFlags(conversationId, flags) {
1777
1936
  const operation = "setConversationFlags";
1778
- const patch = { updated_by: identity.userId };
1937
+ const me = await actingUser(operation);
1938
+ const patch = { updated_by: me };
1779
1939
  if (flags.isMuted !== void 0) patch["is_muted"] = flags.isMuted;
1780
1940
  if (flags.isArchived !== void 0) patch["is_archived"] = flags.isArchived;
1781
- const { error } = await db().from(TABLES.participants).update(patch).eq("conversation_id", conversationId).eq("user_id", identity.userId);
1941
+ const { error } = await db().from(TABLES.participants).update(patch).eq("conversation_id", conversationId).eq("user_id", me);
1782
1942
  if (error !== null) throw normalizeMessagingError(error, operation);
1783
1943
  },
1784
1944
  async addMembers(conversationId, memberIds) {
1785
1945
  const operation = "addMembers";
1946
+ const me = await actingUser(operation);
1786
1947
  const { error } = await db().from(TABLES.participants).insert(
1787
1948
  memberIds.map((userId) => ({
1788
1949
  conversation_id: conversationId,
1789
1950
  user_id: userId,
1790
1951
  role: "member",
1791
1952
  organization_id: org,
1792
- created_by: identity.userId
1953
+ created_by: me
1793
1954
  }))
1794
1955
  );
1795
1956
  if (error !== null) throw normalizeMessagingError(error, operation);
1796
1957
  },
1797
1958
  async removeMember(conversationId, memberId) {
1798
1959
  const operation = "removeMember";
1799
- const { error } = await db().from(TABLES.participants).update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString(), updated_by: identity.userId }).eq("conversation_id", conversationId).eq("user_id", memberId);
1960
+ const me = await actingUser(operation);
1961
+ const { error } = await db().from(TABLES.participants).update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString(), updated_by: me }).eq("conversation_id", conversationId).eq("user_id", memberId);
1800
1962
  if (error !== null) throw normalizeMessagingError(error, operation);
1801
1963
  },
1802
1964
  async setMemberRole(conversationId, memberId, role) {
1803
1965
  const operation = "setMemberRole";
1804
- const { error } = await db().from(TABLES.participants).update({ role, updated_by: identity.userId }).eq("conversation_id", conversationId).eq("user_id", memberId);
1966
+ const me = await actingUser(operation);
1967
+ const { error } = await db().from(TABLES.participants).update({ role, updated_by: me }).eq("conversation_id", conversationId).eq("user_id", memberId);
1805
1968
  if (error !== null) throw normalizeMessagingError(error, operation);
1806
1969
  },
1807
1970
  getUser(userId) {
@@ -1856,22 +2019,69 @@ function defaultDiagnostics(event) {
1856
2019
  else if (event.level === "warn") console.warn(line);
1857
2020
  else console.info(line);
1858
2021
  }
2022
+ function useSessionUserId(client, onDiagnostic) {
2023
+ const diagnosticRef = useRef(onDiagnostic);
2024
+ diagnosticRef.current = onDiagnostic;
2025
+ const identity = useMemo(() => {
2026
+ if (client == null) return null;
2027
+ return createSessionIdentity({
2028
+ client,
2029
+ onDiagnostic: (event) => {
2030
+ (diagnosticRef.current ?? defaultDiagnostics)(event);
2031
+ }
2032
+ });
2033
+ }, [client]);
2034
+ useEffect(() => {
2035
+ if (identity === null) return void 0;
2036
+ return () => {
2037
+ identity.dispose();
2038
+ };
2039
+ }, [identity]);
2040
+ const snapshot = useSyncExternalStore(
2041
+ (listener) => identity === null ? () => void 0 : identity.subscribe(listener),
2042
+ () => identity?.snapshot() ?? SERVER_SESSION_IDENTITY,
2043
+ () => SERVER_SESSION_IDENTITY
2044
+ );
2045
+ return { identity, snapshot };
2046
+ }
1859
2047
  function MessagingProvider(props) {
1860
- const { client, userId, organizationId } = props;
1861
- const ready = client != null && typeof userId === "string" && userId.length > 0 && typeof organizationId === "string" && organizationId.length > 0;
2048
+ const { client, organizationId } = props;
2049
+ const strayUserId = props.userId;
2050
+ const reportedStray = useRef(false);
2051
+ useEffect(() => {
2052
+ if (typeof strayUserId !== "string" || strayUserId.length === 0) return;
2053
+ if (reportedStray.current) return;
2054
+ reportedStray.current = true;
2055
+ (props.onDiagnostic ?? defaultDiagnostics)({
2056
+ level: "error",
2057
+ message: "<MessagingProvider userId> is ignored: since 0.12.0 messaging reads the acting user from the Supabase client's own session (DD-241).",
2058
+ remedy: "Delete the userId prop. A copy of a user id goes stale the moment the auth cookie rotates, and in messaging it lands on the wire as sender_id and created_by \u2014 so it writes rows attributed to somebody the tab cannot prove it is."
2059
+ });
2060
+ }, [strayUserId]);
2061
+ const session = useSessionUserId(client, props.onDiagnostic);
2062
+ const userId = session.snapshot.userId;
2063
+ const ready = client != null && userId !== null && typeof organizationId === "string" && organizationId.length > 0;
1862
2064
  const hostProvidesRealtime = useIsRealtimeProviderMounted();
1863
- if (hostProvidesRealtime) return /* @__PURE__ */ jsx(MessagingRuntime, { ...props });
2065
+ const runtime = /* @__PURE__ */ jsx(
2066
+ MessagingRuntime,
2067
+ {
2068
+ ...props,
2069
+ sessionUserId: userId,
2070
+ sessionIdentity: session.identity
2071
+ }
2072
+ );
2073
+ if (hostProvidesRealtime) return runtime;
1864
2074
  return /* @__PURE__ */ jsx(
1865
2075
  RealtimeProvider,
1866
2076
  {
1867
2077
  client: ready ? client : null,
1868
2078
  actorId: userId ?? void 0,
1869
- children: /* @__PURE__ */ jsx(MessagingRuntime, { ...props })
2079
+ children: runtime
1870
2080
  }
1871
2081
  );
1872
2082
  }
1873
2083
  function MessagingRuntime(props) {
1874
- const { client, userId, organizationId, children } = props;
2084
+ const { client, sessionUserId: userId, sessionIdentity, organizationId, children } = props;
1875
2085
  const manager = useRealtimeManager();
1876
2086
  const diagnosticRef = useRef(props.onDiagnostic);
1877
2087
  diagnosticRef.current = props.onDiagnostic;
@@ -1886,9 +2096,9 @@ function MessagingRuntime(props) {
1886
2096
  actionRegistry.register(handler);
1887
2097
  });
1888
2098
  }, [actionRegistry, handlers]);
1889
- const ready = client != null && manager !== null && typeof userId === "string" && userId.length > 0 && typeof organizationId === "string" && organizationId.length > 0;
2099
+ const ready = client != null && manager !== null && sessionIdentity !== null && userId !== null && typeof organizationId === "string" && organizationId.length > 0;
1890
2100
  const engine = useMemo(() => {
1891
- if (!ready || manager === null) return null;
2101
+ if (!ready || manager === null || sessionIdentity === null || userId === null) return null;
1892
2102
  const identity = {
1893
2103
  userId,
1894
2104
  organizationId
@@ -1902,7 +2112,10 @@ function MessagingRuntime(props) {
1902
2112
  // supabase-shape.ts); everything below this line works against the rich
1903
2113
  // contract, which `supabase-shape.test.ts` proves a real client honors.
1904
2114
  client,
1905
- identity,
2115
+ organizationId,
2116
+ // THE SAME READER the render loop above uses. Two readers would be two
2117
+ // answers during the tick an account switch takes.
2118
+ sessionIdentity,
1906
2119
  // An automatic heal ANNOUNCES itself: a lock collision the package
1907
2120
  // re-ran is a warning in the host's diagnostics, never a banner on the
1908
2121
  // inbox and never silence.
@@ -1932,7 +2145,7 @@ function MessagingRuntime(props) {
1932
2145
  }
1933
2146
  });
1934
2147
  return built;
1935
- }, [ready, manager, userId, organizationId]);
2148
+ }, [ready, manager, sessionIdentity, userId, organizationId]);
1936
2149
  useEffect(() => {
1937
2150
  if (engine === null) return void 0;
1938
2151
  void engine.start().catch((error) => {
@@ -3333,6 +3546,7 @@ export {
3333
3546
  RPCS,
3334
3547
  ReferenceCard,
3335
3548
  ReplyIcon,
3549
+ SERVER_SESSION_IDENTITY,
3336
3550
  SearchIcon,
3337
3551
  SendIcon,
3338
3552
  SparklesIcon,
@@ -3354,6 +3568,7 @@ export {
3354
3568
  createMessagingStore,
3355
3569
  createOutbox,
3356
3570
  createReadCache,
3571
+ createSessionIdentity,
3357
3572
  createWebOutboxStorage,
3358
3573
  effectiveActorKey,
3359
3574
  extractReferences,