@timbal-ai/timbal-react 0.2.1 → 0.2.2

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.cjs CHANGED
@@ -70,6 +70,8 @@ __export(index_exports, {
70
70
  getAccessToken: () => getAccessToken,
71
71
  getRefreshToken: () => getRefreshToken,
72
72
  refreshAccessToken: () => refreshAccessToken,
73
+ setAccessToken: () => setAccessToken,
74
+ setRefreshToken: () => setRefreshToken,
73
75
  useComposerRuntime: () => import_react13.useComposerRuntime,
74
76
  useMessageRuntime: () => import_react13.useMessageRuntime,
75
77
  useSession: () => useSession,
@@ -87,7 +89,9 @@ var import_timbal_sdk = require("@timbal-ai/timbal-sdk");
87
89
  var ACCESS_TOKEN_KEY = "timbal_project_access_token";
88
90
  var REFRESH_TOKEN_KEY = "timbal_project_refresh_token";
89
91
  var getAccessToken = () => localStorage.getItem(ACCESS_TOKEN_KEY);
92
+ var setAccessToken = (token) => localStorage.setItem(ACCESS_TOKEN_KEY, token);
90
93
  var getRefreshToken = () => localStorage.getItem(REFRESH_TOKEN_KEY);
94
+ var setRefreshToken = (token) => localStorage.setItem(REFRESH_TOKEN_KEY, token);
91
95
  var clearTokens = () => {
92
96
  localStorage.removeItem(ACCESS_TOKEN_KEY);
93
97
  localStorage.removeItem(REFRESH_TOKEN_KEY);
@@ -1555,6 +1559,13 @@ var import_react13 = require("@assistant-ui/react");
1555
1559
  // src/auth/provider.tsx
1556
1560
  var import_react12 = require("react");
1557
1561
  var import_jsx_runtime14 = require("react/jsx-runtime");
1562
+ function isInsideIframe() {
1563
+ try {
1564
+ return typeof window !== "undefined" && window.self !== window.top;
1565
+ } catch {
1566
+ return true;
1567
+ }
1568
+ }
1558
1569
  var SessionContext = (0, import_react12.createContext)(void 0);
1559
1570
  var useSession = () => {
1560
1571
  const context = (0, import_react12.useContext)(SessionContext);
@@ -1569,6 +1580,7 @@ var SessionProvider = ({
1569
1580
  }) => {
1570
1581
  const [user, setUser] = (0, import_react12.useState)(null);
1571
1582
  const [loading, setLoading] = (0, import_react12.useState)(enabled);
1583
+ const [embedded] = (0, import_react12.useState)(isInsideIframe);
1572
1584
  (0, import_react12.useEffect)(() => {
1573
1585
  if (!enabled) {
1574
1586
  setLoading(false);
@@ -1601,13 +1613,35 @@ var SessionProvider = ({
1601
1613
  if (ignore) return;
1602
1614
  clearTokens();
1603
1615
  }
1604
- setLoading(false);
1616
+ if (!ignore && !embedded) {
1617
+ setLoading(false);
1618
+ }
1605
1619
  };
1606
1620
  restoreSession();
1621
+ let messageCleanup;
1622
+ if (embedded) {
1623
+ const handleMessage = async (event) => {
1624
+ if (ignore) return;
1625
+ if (event.data?.type !== "timbal:auth" || !event.data.token) return;
1626
+ setAccessToken(event.data.token);
1627
+ if (event.data.refreshToken) {
1628
+ setRefreshToken(event.data.refreshToken);
1629
+ }
1630
+ const u = await fetchCurrentUser();
1631
+ if (!ignore) {
1632
+ setUser(u);
1633
+ setLoading(false);
1634
+ }
1635
+ };
1636
+ window.addEventListener("message", handleMessage);
1637
+ window.parent.postMessage({ type: "timbal:request-session" }, "*");
1638
+ messageCleanup = () => window.removeEventListener("message", handleMessage);
1639
+ }
1607
1640
  return () => {
1608
1641
  ignore = true;
1642
+ messageCleanup?.();
1609
1643
  };
1610
- }, [enabled]);
1644
+ }, [enabled, embedded]);
1611
1645
  const logout = (0, import_react12.useCallback)(() => {
1612
1646
  clearTokens();
1613
1647
  setUser(null);
@@ -1625,6 +1659,7 @@ var SessionProvider = ({
1625
1659
  user,
1626
1660
  loading,
1627
1661
  isAuthenticated: !!user,
1662
+ isEmbedded: embedded,
1628
1663
  logout
1629
1664
  },
1630
1665
  children
@@ -1640,14 +1675,14 @@ var AuthGuard = ({
1640
1675
  requireAuth = false,
1641
1676
  enabled = true
1642
1677
  }) => {
1643
- const { isAuthenticated, loading } = useSession();
1678
+ const { isAuthenticated, loading, isEmbedded } = useSession();
1644
1679
  if (!enabled) {
1645
1680
  return children;
1646
1681
  }
1647
1682
  if (loading) {
1648
1683
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.Loader2, { className: "w-8 h-8 animate-spin" }) });
1649
1684
  }
1650
- if (requireAuth && !isAuthenticated) {
1685
+ if (requireAuth && !isAuthenticated && !isEmbedded) {
1651
1686
  const returnTo = encodeURIComponent(
1652
1687
  window.location.pathname + window.location.search
1653
1688
  );
@@ -1698,6 +1733,8 @@ var AuthGuard = ({
1698
1733
  getAccessToken,
1699
1734
  getRefreshToken,
1700
1735
  refreshAccessToken,
1736
+ setAccessToken,
1737
+ setRefreshToken,
1701
1738
  useComposerRuntime,
1702
1739
  useMessageRuntime,
1703
1740
  useSession,
package/dist/index.d.cts CHANGED
@@ -102,6 +102,7 @@ interface SessionContextType {
102
102
  user: Session | null;
103
103
  loading: boolean;
104
104
  isAuthenticated: boolean;
105
+ isEmbedded: boolean;
105
106
  logout: () => void;
106
107
  }
107
108
  declare const useSession: () => SessionContextType;
@@ -121,7 +122,9 @@ interface AuthGuardProps {
121
122
  declare const AuthGuard: React__default.FC<AuthGuardProps>;
122
123
 
123
124
  declare const getAccessToken: () => string | null;
125
+ declare const setAccessToken: (token: string) => void;
124
126
  declare const getRefreshToken: () => string | null;
127
+ declare const setRefreshToken: (token: string) => void;
125
128
  declare const clearTokens: () => void;
126
129
  declare const refreshAccessToken: () => Promise<boolean>;
127
130
  declare const authFetch: (url: string, options?: RequestInit) => Promise<Response>;
@@ -159,4 +162,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
159
162
 
160
163
  declare function cn(...inputs: ClassValue[]): string;
161
164
 
162
- export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
165
+ export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, setAccessToken, setRefreshToken, useSession };
package/dist/index.d.ts CHANGED
@@ -102,6 +102,7 @@ interface SessionContextType {
102
102
  user: Session | null;
103
103
  loading: boolean;
104
104
  isAuthenticated: boolean;
105
+ isEmbedded: boolean;
105
106
  logout: () => void;
106
107
  }
107
108
  declare const useSession: () => SessionContextType;
@@ -121,7 +122,9 @@ interface AuthGuardProps {
121
122
  declare const AuthGuard: React__default.FC<AuthGuardProps>;
122
123
 
123
124
  declare const getAccessToken: () => string | null;
125
+ declare const setAccessToken: (token: string) => void;
124
126
  declare const getRefreshToken: () => string | null;
127
+ declare const setRefreshToken: (token: string) => void;
125
128
  declare const clearTokens: () => void;
126
129
  declare const refreshAccessToken: () => Promise<boolean>;
127
130
  declare const authFetch: (url: string, options?: RequestInit) => Promise<Response>;
@@ -159,4 +162,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
159
162
 
160
163
  declare function cn(...inputs: ClassValue[]): string;
161
164
 
162
- export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
165
+ export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, setAccessToken, setRefreshToken, useSession };
package/dist/index.esm.js CHANGED
@@ -10,7 +10,9 @@ import { parseSSELine } from "@timbal-ai/timbal-sdk";
10
10
  var ACCESS_TOKEN_KEY = "timbal_project_access_token";
11
11
  var REFRESH_TOKEN_KEY = "timbal_project_refresh_token";
12
12
  var getAccessToken = () => localStorage.getItem(ACCESS_TOKEN_KEY);
13
+ var setAccessToken = (token) => localStorage.setItem(ACCESS_TOKEN_KEY, token);
13
14
  var getRefreshToken = () => localStorage.getItem(REFRESH_TOKEN_KEY);
15
+ var setRefreshToken = (token) => localStorage.setItem(REFRESH_TOKEN_KEY, token);
14
16
  var clearTokens = () => {
15
17
  localStorage.removeItem(ACCESS_TOKEN_KEY);
16
18
  localStorage.removeItem(REFRESH_TOKEN_KEY);
@@ -1525,6 +1527,13 @@ import {
1525
1527
  useState as useState5
1526
1528
  } from "react";
1527
1529
  import { jsx as jsx14 } from "react/jsx-runtime";
1530
+ function isInsideIframe() {
1531
+ try {
1532
+ return typeof window !== "undefined" && window.self !== window.top;
1533
+ } catch {
1534
+ return true;
1535
+ }
1536
+ }
1528
1537
  var SessionContext = createContext(void 0);
1529
1538
  var useSession = () => {
1530
1539
  const context = useContext(SessionContext);
@@ -1539,6 +1548,7 @@ var SessionProvider = ({
1539
1548
  }) => {
1540
1549
  const [user, setUser] = useState5(null);
1541
1550
  const [loading, setLoading] = useState5(enabled);
1551
+ const [embedded] = useState5(isInsideIframe);
1542
1552
  useEffect4(() => {
1543
1553
  if (!enabled) {
1544
1554
  setLoading(false);
@@ -1571,13 +1581,35 @@ var SessionProvider = ({
1571
1581
  if (ignore) return;
1572
1582
  clearTokens();
1573
1583
  }
1574
- setLoading(false);
1584
+ if (!ignore && !embedded) {
1585
+ setLoading(false);
1586
+ }
1575
1587
  };
1576
1588
  restoreSession();
1589
+ let messageCleanup;
1590
+ if (embedded) {
1591
+ const handleMessage = async (event) => {
1592
+ if (ignore) return;
1593
+ if (event.data?.type !== "timbal:auth" || !event.data.token) return;
1594
+ setAccessToken(event.data.token);
1595
+ if (event.data.refreshToken) {
1596
+ setRefreshToken(event.data.refreshToken);
1597
+ }
1598
+ const u = await fetchCurrentUser();
1599
+ if (!ignore) {
1600
+ setUser(u);
1601
+ setLoading(false);
1602
+ }
1603
+ };
1604
+ window.addEventListener("message", handleMessage);
1605
+ window.parent.postMessage({ type: "timbal:request-session" }, "*");
1606
+ messageCleanup = () => window.removeEventListener("message", handleMessage);
1607
+ }
1577
1608
  return () => {
1578
1609
  ignore = true;
1610
+ messageCleanup?.();
1579
1611
  };
1580
- }, [enabled]);
1612
+ }, [enabled, embedded]);
1581
1613
  const logout = useCallback2(() => {
1582
1614
  clearTokens();
1583
1615
  setUser(null);
@@ -1595,6 +1627,7 @@ var SessionProvider = ({
1595
1627
  user,
1596
1628
  loading,
1597
1629
  isAuthenticated: !!user,
1630
+ isEmbedded: embedded,
1598
1631
  logout
1599
1632
  },
1600
1633
  children
@@ -1610,14 +1643,14 @@ var AuthGuard = ({
1610
1643
  requireAuth = false,
1611
1644
  enabled = true
1612
1645
  }) => {
1613
- const { isAuthenticated, loading } = useSession();
1646
+ const { isAuthenticated, loading, isEmbedded } = useSession();
1614
1647
  if (!enabled) {
1615
1648
  return children;
1616
1649
  }
1617
1650
  if (loading) {
1618
1651
  return /* @__PURE__ */ jsx15("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ jsx15(Loader2, { className: "w-8 h-8 animate-spin" }) });
1619
1652
  }
1620
- if (requireAuth && !isAuthenticated) {
1653
+ if (requireAuth && !isAuthenticated && !isEmbedded) {
1621
1654
  const returnTo = encodeURIComponent(
1622
1655
  window.location.pathname + window.location.search
1623
1656
  );
@@ -1667,6 +1700,8 @@ export {
1667
1700
  getAccessToken,
1668
1701
  getRefreshToken,
1669
1702
  refreshAccessToken,
1703
+ setAccessToken,
1704
+ setRefreshToken,
1670
1705
  useComposerRuntime,
1671
1706
  useMessageRuntime,
1672
1707
  useSession,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timbal-ai/timbal-react",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "React components and runtime for building Timbal chat UIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",