@useatlas/react 0.0.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.
- package/README.md +95 -0
- package/dist/chunk-2WFDP7G5.js +231 -0
- package/dist/chunk-2WFDP7G5.js.map +1 -0
- package/dist/chunk-44HBZYKP.js +224 -0
- package/dist/chunk-44HBZYKP.js.map +1 -0
- package/dist/chunk-5SEVKHS5.cjs +229 -0
- package/dist/chunk-5SEVKHS5.cjs.map +1 -0
- package/dist/chunk-UIRB6L36.cjs +249 -0
- package/dist/chunk-UIRB6L36.cjs.map +1 -0
- package/dist/hooks.cjs +251 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.cts +132 -0
- package/dist/hooks.d.ts +132 -0
- package/dist/hooks.js +237 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.cjs +2976 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +2926 -0
- package/dist/index.js.map +1 -0
- package/dist/result-chart-NFAJ4IQ5.js +398 -0
- package/dist/result-chart-NFAJ4IQ5.js.map +1 -0
- package/dist/result-chart-YLCKBNV4.cjs +400 -0
- package/dist/result-chart-YLCKBNV4.cjs.map +1 -0
- package/dist/styles.css +59 -0
- package/dist/use-dark-mode-rFxawUv1.d.cts +123 -0
- package/dist/use-dark-mode-rFxawUv1.d.ts +123 -0
- package/dist/widget.css +2 -0
- package/dist/widget.js +445 -0
- package/package.json +113 -0
- package/src/components/__tests__/tool-renderers.test.tsx +239 -0
- package/src/components/actions/action-approval-card.tsx +296 -0
- package/src/components/actions/action-status-badge.tsx +50 -0
- package/src/components/admin/change-password-dialog.tsx +128 -0
- package/src/components/atlas-chat.tsx +656 -0
- package/src/components/chart/chart-detection.ts +318 -0
- package/src/components/chart/result-chart.tsx +590 -0
- package/src/components/chat/api-key-bar.tsx +66 -0
- package/src/components/chat/copy-button.tsx +25 -0
- package/src/components/chat/data-table.tsx +104 -0
- package/src/components/chat/error-banner.tsx +32 -0
- package/src/components/chat/explore-card.tsx +41 -0
- package/src/components/chat/follow-up-chips.tsx +29 -0
- package/src/components/chat/loading-card.tsx +10 -0
- package/src/components/chat/managed-auth-card.tsx +116 -0
- package/src/components/chat/markdown.tsx +146 -0
- package/src/components/chat/python-result-card.tsx +245 -0
- package/src/components/chat/sql-block.tsx +54 -0
- package/src/components/chat/sql-result-card.tsx +163 -0
- package/src/components/chat/starter-prompts.ts +6 -0
- package/src/components/chat/tool-part.tsx +106 -0
- package/src/components/chat/typing-indicator.tsx +22 -0
- package/src/components/conversations/conversation-item.tsx +135 -0
- package/src/components/conversations/conversation-list.tsx +69 -0
- package/src/components/conversations/conversation-sidebar.tsx +113 -0
- package/src/components/conversations/delete-confirmation.tsx +27 -0
- package/src/components/schema-explorer/schema-explorer.tsx +517 -0
- package/src/components/ui/alert-dialog.tsx +196 -0
- package/src/components/ui/badge.tsx +48 -0
- package/src/components/ui/button.tsx +64 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/dialog.tsx +158 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/scroll-area.tsx +62 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +143 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/context.tsx +85 -0
- package/src/env.d.ts +9 -0
- package/src/hooks/__tests__/provider.test.tsx +83 -0
- package/src/hooks/__tests__/use-atlas-auth.test.tsx +283 -0
- package/src/hooks/__tests__/use-atlas-chat.test.tsx +157 -0
- package/src/hooks/__tests__/use-atlas-conversations.test.tsx +159 -0
- package/src/hooks/__tests__/use-atlas-theme.test.tsx +56 -0
- package/src/hooks/index.ts +47 -0
- package/src/hooks/provider.tsx +77 -0
- package/src/hooks/theme-init-script.ts +17 -0
- package/src/hooks/use-atlas-auth.ts +131 -0
- package/src/hooks/use-atlas-chat.ts +102 -0
- package/src/hooks/use-atlas-conversations.ts +61 -0
- package/src/hooks/use-atlas-theme.ts +34 -0
- package/src/hooks/use-conversations.ts +189 -0
- package/src/hooks/use-dark-mode.ts +150 -0
- package/src/index.ts +36 -0
- package/src/lib/action-types.ts +11 -0
- package/src/lib/helpers.ts +198 -0
- package/src/lib/tool-renderer-types.ts +76 -0
- package/src/lib/types.ts +29 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles.css +59 -0
- package/src/test-setup.ts +55 -0
- package/src/widget-entry.ts +20 -0
- package/src/widget.css +12 -0
package/dist/hooks.cjs
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkUIRB6L36_cjs = require('./chunk-UIRB6L36.cjs');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var react$1 = require('@ai-sdk/react');
|
|
7
|
+
var ai = require('ai');
|
|
8
|
+
|
|
9
|
+
var noopAuthClient = {
|
|
10
|
+
signIn: {
|
|
11
|
+
email: async () => {
|
|
12
|
+
console.warn("[Atlas] signIn called but no authClient was provided to AtlasProvider");
|
|
13
|
+
return { error: { message: "Auth client not configured" } };
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
signUp: {
|
|
17
|
+
email: async () => {
|
|
18
|
+
console.warn("[Atlas] signUp called but no authClient was provided to AtlasProvider");
|
|
19
|
+
return { error: { message: "Auth client not configured" } };
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
signOut: async () => {
|
|
23
|
+
console.warn("[Atlas] signOut called but no authClient was provided to AtlasProvider");
|
|
24
|
+
},
|
|
25
|
+
useSession: () => ({ data: null, isPending: false })
|
|
26
|
+
};
|
|
27
|
+
var AtlasContext = react.createContext(null);
|
|
28
|
+
function useAtlasContext() {
|
|
29
|
+
const ctx = react.useContext(AtlasContext);
|
|
30
|
+
if (!ctx) throw new Error("useAtlasContext must be used within <AtlasProvider>");
|
|
31
|
+
return ctx;
|
|
32
|
+
}
|
|
33
|
+
function AtlasProvider({
|
|
34
|
+
apiUrl,
|
|
35
|
+
apiKey,
|
|
36
|
+
authClient = noopAuthClient,
|
|
37
|
+
children
|
|
38
|
+
}) {
|
|
39
|
+
const isCrossOrigin = typeof window !== "undefined" && apiUrl !== "" && !apiUrl.startsWith(window.location.origin);
|
|
40
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AtlasContext.Provider, { value: { apiUrl, apiKey, authClient, isCrossOrigin }, children });
|
|
41
|
+
}
|
|
42
|
+
function useAtlasChat(options = {}) {
|
|
43
|
+
const { apiUrl, apiKey, isCrossOrigin } = useAtlasContext();
|
|
44
|
+
const [conversationId, setConversationId] = react.useState(
|
|
45
|
+
options.initialConversationId ?? null
|
|
46
|
+
);
|
|
47
|
+
const conversationIdRef = react.useRef(conversationId);
|
|
48
|
+
conversationIdRef.current = conversationId;
|
|
49
|
+
const onChangeRef = react.useRef(options.onConversationIdChange);
|
|
50
|
+
onChangeRef.current = options.onConversationIdChange;
|
|
51
|
+
const transport = react.useMemo(() => {
|
|
52
|
+
const headers = {};
|
|
53
|
+
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
54
|
+
return new ai.DefaultChatTransport({
|
|
55
|
+
api: `${apiUrl}/api/chat`,
|
|
56
|
+
headers,
|
|
57
|
+
credentials: isCrossOrigin ? "include" : void 0,
|
|
58
|
+
body: () => conversationIdRef.current ? { conversationId: conversationIdRef.current } : {},
|
|
59
|
+
fetch: (async (input2, init) => {
|
|
60
|
+
const response = await globalThis.fetch(input2, init);
|
|
61
|
+
const convId = response.headers.get("x-conversation-id");
|
|
62
|
+
if (convId && convId !== conversationIdRef.current) {
|
|
63
|
+
setConversationId(convId);
|
|
64
|
+
onChangeRef.current?.(convId);
|
|
65
|
+
}
|
|
66
|
+
return response;
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
}, [apiKey, apiUrl, isCrossOrigin]);
|
|
70
|
+
const { messages, setMessages, sendMessage: rawSend, status, error } = react$1.useChat({ transport });
|
|
71
|
+
const [input, setInput] = react.useState("");
|
|
72
|
+
const sendMessage = async (text) => {
|
|
73
|
+
const previousInput = input;
|
|
74
|
+
setInput("");
|
|
75
|
+
try {
|
|
76
|
+
await rawSend({ text });
|
|
77
|
+
} catch (err) {
|
|
78
|
+
setInput(previousInput);
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
messages,
|
|
84
|
+
setMessages,
|
|
85
|
+
sendMessage,
|
|
86
|
+
input,
|
|
87
|
+
setInput,
|
|
88
|
+
status,
|
|
89
|
+
isLoading: status === "streaming" || status === "submitted",
|
|
90
|
+
error: error ?? null,
|
|
91
|
+
conversationId,
|
|
92
|
+
setConversationId
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function useAtlasAuth() {
|
|
96
|
+
const { apiUrl, apiKey, authClient, isCrossOrigin } = useAtlasContext();
|
|
97
|
+
const [authMode, setAuthMode] = react.useState(null);
|
|
98
|
+
const [error, setError] = react.useState(null);
|
|
99
|
+
const managedSession = authClient.useSession();
|
|
100
|
+
react.useEffect(() => {
|
|
101
|
+
let cancelled = false;
|
|
102
|
+
async function fetchHealth(attempt) {
|
|
103
|
+
try {
|
|
104
|
+
const res = await fetch(`${apiUrl}/api/health`, {
|
|
105
|
+
credentials: isCrossOrigin ? "include" : "same-origin"
|
|
106
|
+
});
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
console.warn(`[Atlas] Health check returned HTTP ${res.status} (attempt ${attempt})`);
|
|
109
|
+
if (attempt < 2 && !cancelled) {
|
|
110
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
111
|
+
return fetchHealth(attempt + 1);
|
|
112
|
+
}
|
|
113
|
+
if (!cancelled) {
|
|
114
|
+
setError(new Error(`Health check failed with HTTP ${res.status}`));
|
|
115
|
+
setAuthMode("none");
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const data = await res.json();
|
|
120
|
+
const mode = data?.checks?.auth?.mode;
|
|
121
|
+
if (!cancelled) {
|
|
122
|
+
if (typeof mode === "string" && chunkUIRB6L36_cjs.AUTH_MODES.includes(mode)) {
|
|
123
|
+
setAuthMode(mode);
|
|
124
|
+
} else {
|
|
125
|
+
console.warn("[Atlas] Health check returned no valid auth mode:", data);
|
|
126
|
+
setAuthMode("none");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
131
|
+
console.warn(`[Atlas] Health check failed (attempt ${attempt}):`, message);
|
|
132
|
+
if (attempt < 2 && !cancelled) {
|
|
133
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
134
|
+
return fetchHealth(attempt + 1);
|
|
135
|
+
}
|
|
136
|
+
if (!cancelled) {
|
|
137
|
+
setError(err instanceof Error ? err : new Error(message));
|
|
138
|
+
setAuthMode("none");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
fetchHealth(1);
|
|
143
|
+
return () => {
|
|
144
|
+
cancelled = true;
|
|
145
|
+
};
|
|
146
|
+
}, [apiUrl, isCrossOrigin]);
|
|
147
|
+
const isAuthenticated = (() => {
|
|
148
|
+
if (authMode === null) return false;
|
|
149
|
+
if (authMode === "none") return true;
|
|
150
|
+
if (authMode === "simple-key" || authMode === "byot") return !!apiKey;
|
|
151
|
+
if (authMode === "managed") return !!managedSession.data?.user;
|
|
152
|
+
return false;
|
|
153
|
+
})();
|
|
154
|
+
const login = async (email, password) => {
|
|
155
|
+
try {
|
|
156
|
+
const result = await authClient.signIn.email({ email, password });
|
|
157
|
+
return { error: result.error?.message };
|
|
158
|
+
} catch (err) {
|
|
159
|
+
const message = err instanceof Error ? err.message : "Login failed";
|
|
160
|
+
console.warn("[Atlas] login error:", message);
|
|
161
|
+
return { error: message };
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const signup = async (email, password, name) => {
|
|
165
|
+
try {
|
|
166
|
+
const result = await authClient.signUp.email({ email, password, name });
|
|
167
|
+
return { error: result.error?.message };
|
|
168
|
+
} catch (err) {
|
|
169
|
+
const message = err instanceof Error ? err.message : "Signup failed";
|
|
170
|
+
console.warn("[Atlas] signup error:", message);
|
|
171
|
+
return { error: message };
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const logout = async () => {
|
|
175
|
+
try {
|
|
176
|
+
await authClient.signOut();
|
|
177
|
+
return {};
|
|
178
|
+
} catch (err) {
|
|
179
|
+
const message = err instanceof Error ? err.message : "Logout failed";
|
|
180
|
+
console.warn("[Atlas] logout error:", message);
|
|
181
|
+
return { error: message };
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return {
|
|
185
|
+
authMode,
|
|
186
|
+
isAuthenticated,
|
|
187
|
+
session: managedSession.data ?? null,
|
|
188
|
+
isLoading: authMode === null || authMode === "managed" && !!managedSession.isPending,
|
|
189
|
+
error,
|
|
190
|
+
login,
|
|
191
|
+
signup,
|
|
192
|
+
logout
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/hooks/use-atlas-theme.ts
|
|
197
|
+
function useAtlasTheme() {
|
|
198
|
+
const theme = chunkUIRB6L36_cjs.useThemeMode();
|
|
199
|
+
const isDark = chunkUIRB6L36_cjs.useDarkMode();
|
|
200
|
+
return {
|
|
201
|
+
theme,
|
|
202
|
+
isDark,
|
|
203
|
+
setTheme: chunkUIRB6L36_cjs.setTheme,
|
|
204
|
+
applyBrandColor: chunkUIRB6L36_cjs.applyBrandColor
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/hooks/use-atlas-conversations.ts
|
|
209
|
+
function useAtlasConversations(options = {}) {
|
|
210
|
+
const { apiUrl, apiKey, isCrossOrigin } = useAtlasContext();
|
|
211
|
+
const { enabled = true } = options;
|
|
212
|
+
const inner = chunkUIRB6L36_cjs.useConversations({
|
|
213
|
+
apiUrl,
|
|
214
|
+
enabled,
|
|
215
|
+
getHeaders: () => {
|
|
216
|
+
const headers = {};
|
|
217
|
+
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
218
|
+
return headers;
|
|
219
|
+
},
|
|
220
|
+
getCredentials: () => isCrossOrigin ? "include" : "same-origin"
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
conversations: inner.conversations,
|
|
224
|
+
total: inner.total,
|
|
225
|
+
isLoading: inner.loading,
|
|
226
|
+
available: inner.available,
|
|
227
|
+
selectedId: inner.selectedId,
|
|
228
|
+
setSelectedId: inner.setSelectedId,
|
|
229
|
+
refresh: inner.refresh,
|
|
230
|
+
loadConversation: inner.loadConversation,
|
|
231
|
+
deleteConversation: inner.deleteConversation,
|
|
232
|
+
starConversation: inner.starConversation
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
Object.defineProperty(exports, "AUTH_MODES", {
|
|
237
|
+
enumerable: true,
|
|
238
|
+
get: function () { return chunkUIRB6L36_cjs.AUTH_MODES; }
|
|
239
|
+
});
|
|
240
|
+
Object.defineProperty(exports, "parseChatError", {
|
|
241
|
+
enumerable: true,
|
|
242
|
+
get: function () { return chunkUIRB6L36_cjs.parseChatError; }
|
|
243
|
+
});
|
|
244
|
+
exports.AtlasProvider = AtlasProvider;
|
|
245
|
+
exports.useAtlasAuth = useAtlasAuth;
|
|
246
|
+
exports.useAtlasChat = useAtlasChat;
|
|
247
|
+
exports.useAtlasContext = useAtlasContext;
|
|
248
|
+
exports.useAtlasConversations = useAtlasConversations;
|
|
249
|
+
exports.useAtlasTheme = useAtlasTheme;
|
|
250
|
+
//# sourceMappingURL=hooks.cjs.map
|
|
251
|
+
//# sourceMappingURL=hooks.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/provider.tsx","../src/hooks/use-atlas-chat.ts","../src/hooks/use-atlas-auth.ts","../src/hooks/use-atlas-theme.ts","../src/hooks/use-atlas-conversations.ts"],"names":["createContext","useContext","jsx","useState","useRef","useMemo","DefaultChatTransport","input","useChat","useEffect","AUTH_MODES","useThemeMode","useDarkMode","setTheme","applyBrandColor","useConversations"],"mappings":"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","file":"hooks.cjs","sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { AtlasAuthClient } from \"../context\";\n\nexport type { AtlasAuthClient };\n\nexport interface AtlasProviderProps {\n /** Atlas API server URL (e.g. \"https://api.example.com\" or \"\" for same-origin). */\n apiUrl: string;\n /** API key for simple-key auth mode. Sent as Bearer token. Accessible in context by all hooks. */\n apiKey?: string;\n /** Custom auth client for managed auth mode (better-auth compatible). */\n authClient?: AtlasAuthClient;\n children: ReactNode;\n}\n\nexport interface AtlasContextValue {\n apiUrl: string;\n apiKey: string | undefined;\n authClient: AtlasAuthClient;\n isCrossOrigin: boolean;\n}\n\n/** No-op auth client for non-managed auth modes. Warns when auth operations are attempted. */\nconst noopAuthClient: AtlasAuthClient = {\n signIn: {\n email: async () => {\n console.warn(\"[Atlas] signIn called but no authClient was provided to AtlasProvider\");\n return { error: { message: \"Auth client not configured\" } };\n },\n },\n signUp: {\n email: async () => {\n console.warn(\"[Atlas] signUp called but no authClient was provided to AtlasProvider\");\n return { error: { message: \"Auth client not configured\" } };\n },\n },\n signOut: async () => {\n console.warn(\"[Atlas] signOut called but no authClient was provided to AtlasProvider\");\n },\n useSession: () => ({ data: null, isPending: false }),\n};\n\nconst AtlasContext = createContext<AtlasContextValue | null>(null);\n\n/** Access the AtlasProvider context. Throws if used outside <AtlasProvider>. */\nexport function useAtlasContext(): AtlasContextValue {\n const ctx = useContext(AtlasContext);\n if (!ctx) throw new Error(\"useAtlasContext must be used within <AtlasProvider>\");\n return ctx;\n}\n\n/**\n * Lightweight provider for headless Atlas hooks.\n *\n * Wraps your app and supplies API URL, auth credentials, and an optional\n * better-auth client to all Atlas hooks. Derives isCrossOrigin from apiUrl\n * to configure credential handling for cross-origin requests.\n */\nexport function AtlasProvider({\n apiUrl,\n apiKey,\n authClient = noopAuthClient,\n children,\n}: AtlasProviderProps) {\n const isCrossOrigin =\n typeof window !== \"undefined\" &&\n apiUrl !== \"\" &&\n !apiUrl.startsWith(window.location.origin);\n\n return (\n <AtlasContext.Provider value={{ apiUrl, apiKey, authClient, isCrossOrigin }}>\n {children}\n </AtlasContext.Provider>\n );\n}\n","\"use client\";\n\nimport { useState, useRef, useMemo } from \"react\";\nimport { useChat, type UIMessage } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { useAtlasContext } from \"./provider\";\n\nexport type AtlasChatStatus = \"submitted\" | \"streaming\" | \"ready\" | \"error\";\n\nexport interface UseAtlasChatOptions {\n /** Conversation ID to associate with this chat session. The server will append messages to this conversation. To load prior messages, use loadConversation() from useAtlasConversations and pass them via setMessages. */\n initialConversationId?: string;\n /** Called when the server assigns or changes the conversation ID. */\n onConversationIdChange?: (id: string) => void;\n}\n\nexport interface UseAtlasChatReturn {\n messages: UIMessage[];\n /** Replace all messages, or update via callback `(prev) => next`. */\n setMessages: (messages: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])) => void;\n /** Send a text message. Rejects on failure (also surfaces via `error`). */\n sendMessage: (text: string) => Promise<void>;\n /** Current input value (managed by the hook). */\n input: string;\n /** Update the input value. */\n setInput: (input: string) => void;\n /** Chat status from the AI SDK. */\n status: AtlasChatStatus;\n /** Whether the chat is currently loading (streaming or submitted). */\n isLoading: boolean;\n /** Last error, if any. */\n error: Error | null;\n /** Current conversation ID. Initially set from options, updated when the server returns an x-conversation-id header. */\n conversationId: string | null;\n /** Manually set the conversation ID. */\n setConversationId: (id: string | null) => void;\n}\n\nexport function useAtlasChat(options: UseAtlasChatOptions = {}): UseAtlasChatReturn {\n const { apiUrl, apiKey, isCrossOrigin } = useAtlasContext();\n const [conversationId, setConversationId] = useState<string | null>(\n options.initialConversationId ?? null,\n );\n const conversationIdRef = useRef(conversationId);\n conversationIdRef.current = conversationId;\n\n const onChangeRef = useRef(options.onConversationIdChange);\n onChangeRef.current = options.onConversationIdChange;\n\n const transport = useMemo(() => {\n const headers: Record<string, string> = {};\n if (apiKey) headers[\"Authorization\"] = `Bearer ${apiKey}`;\n\n return new DefaultChatTransport({\n api: `${apiUrl}/api/chat`,\n headers,\n credentials: isCrossOrigin ? \"include\" : undefined,\n body: () =>\n conversationIdRef.current\n ? { conversationId: conversationIdRef.current }\n : {},\n fetch: (async (input: RequestInfo | URL, init?: RequestInit) => {\n const response = await globalThis.fetch(input, init);\n const convId = response.headers.get(\"x-conversation-id\");\n if (convId && convId !== conversationIdRef.current) {\n setConversationId(convId);\n onChangeRef.current?.(convId);\n }\n return response;\n }) as typeof fetch,\n });\n }, [apiKey, apiUrl, isCrossOrigin]);\n\n const { messages, setMessages, sendMessage: rawSend, status, error } =\n useChat({ transport });\n\n const [input, setInput] = useState(\"\");\n\n const sendMessage = async (text: string) => {\n const previousInput = input;\n setInput(\"\");\n try {\n await rawSend({ text });\n } catch (err) {\n setInput(previousInput);\n throw err;\n }\n };\n\n return {\n messages,\n setMessages,\n sendMessage,\n input,\n setInput,\n status: status as AtlasChatStatus,\n isLoading: status === \"streaming\" || status === \"submitted\",\n error: error ?? null,\n conversationId,\n setConversationId,\n };\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useAtlasContext } from \"./provider\";\nimport { AUTH_MODES, type AuthMode } from \"../lib/types\";\n\nexport interface UseAtlasAuthReturn {\n /** Auth mode detected from the server's /api/health endpoint. `null` while the initial health check is in flight. */\n authMode: AuthMode | null;\n /** Whether the user is authenticated (based on auth mode, API key, or session). */\n isAuthenticated: boolean;\n /** Session data for managed auth mode. */\n session: { user?: { email?: string } } | null;\n /** Whether auth state is still being resolved (health check or managed session loading). */\n isLoading: boolean;\n /** Error from health check or auth operations. `null` when healthy. */\n error: Error | null;\n /** Sign in with email/password (managed auth). */\n login: (email: string, password: string) => Promise<{ error?: string }>;\n /** Sign up with email/password/name (managed auth). */\n signup: (email: string, password: string, name: string) => Promise<{ error?: string }>;\n /** Sign out (managed auth). */\n logout: () => Promise<{ error?: string }>;\n}\n\nexport function useAtlasAuth(): UseAtlasAuthReturn {\n const { apiUrl, apiKey, authClient, isCrossOrigin } = useAtlasContext();\n const [authMode, setAuthMode] = useState<AuthMode | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const managedSession = authClient.useSession();\n\n useEffect(() => {\n let cancelled = false;\n\n async function fetchHealth(attempt: number): Promise<void> {\n try {\n const res = await fetch(`${apiUrl}/api/health`, {\n credentials: isCrossOrigin ? \"include\" : \"same-origin\",\n });\n if (!res.ok) {\n console.warn(`[Atlas] Health check returned HTTP ${res.status} (attempt ${attempt})`);\n if (attempt < 2 && !cancelled) {\n await new Promise((r) => setTimeout(r, 2000));\n return fetchHealth(attempt + 1);\n }\n if (!cancelled) {\n setError(new Error(`Health check failed with HTTP ${res.status}`));\n setAuthMode(\"none\");\n }\n return;\n }\n const data = await res.json();\n const mode = data?.checks?.auth?.mode;\n if (!cancelled) {\n if (typeof mode === \"string\" && AUTH_MODES.includes(mode as AuthMode)) {\n setAuthMode(mode as AuthMode);\n } else {\n console.warn(\"[Atlas] Health check returned no valid auth mode:\", data);\n setAuthMode(\"none\");\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.warn(`[Atlas] Health check failed (attempt ${attempt}):`, message);\n if (attempt < 2 && !cancelled) {\n await new Promise((r) => setTimeout(r, 2000));\n return fetchHealth(attempt + 1);\n }\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(message));\n setAuthMode(\"none\");\n }\n }\n }\n\n fetchHealth(1);\n return () => { cancelled = true; };\n }, [apiUrl, isCrossOrigin]);\n\n const isAuthenticated = (() => {\n if (authMode === null) return false;\n if (authMode === \"none\") return true;\n if (authMode === \"simple-key\" || authMode === \"byot\") return !!apiKey;\n if (authMode === \"managed\") return !!managedSession.data?.user;\n return false;\n })();\n\n const login = async (email: string, password: string) => {\n try {\n const result = await authClient.signIn.email({ email, password });\n return { error: result.error?.message };\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Login failed\";\n console.warn(\"[Atlas] login error:\", message);\n return { error: message };\n }\n };\n\n const signup = async (email: string, password: string, name: string) => {\n try {\n const result = await authClient.signUp.email({ email, password, name });\n return { error: result.error?.message };\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Signup failed\";\n console.warn(\"[Atlas] signup error:\", message);\n return { error: message };\n }\n };\n\n const logout = async () => {\n try {\n await authClient.signOut();\n return {};\n } catch (err) {\n const message = err instanceof Error ? err.message : \"Logout failed\";\n console.warn(\"[Atlas] logout error:\", message);\n return { error: message };\n }\n };\n\n return {\n authMode,\n isAuthenticated,\n session: managedSession.data ?? null,\n isLoading: authMode === null || (authMode === \"managed\" && !!managedSession.isPending),\n error,\n login,\n signup,\n logout,\n };\n}\n","\"use client\";\n\nimport {\n useDarkMode,\n useThemeMode,\n setTheme,\n applyBrandColor,\n type ThemeMode,\n} from \"./use-dark-mode\";\n\nexport type { ThemeMode };\n\nexport interface UseAtlasThemeReturn {\n /** Current theme setting: \"light\", \"dark\", or \"system\". */\n theme: ThemeMode;\n /** Whether the effective (resolved) theme is dark. */\n isDark: boolean;\n /** Set the theme mode. Persists to localStorage. */\n setTheme: (mode: ThemeMode) => void;\n /** Apply a brand color (oklch format, e.g. \"oklch(0.759 0.148 167.71)\") via CSS custom property --atlas-brand. */\n applyBrandColor: (color: string) => void;\n}\n\nexport function useAtlasTheme(): UseAtlasThemeReturn {\n const theme = useThemeMode();\n const isDark = useDarkMode();\n\n return {\n theme,\n isDark,\n setTheme,\n applyBrandColor,\n };\n}\n","\"use client\";\n\nimport type { UIMessage } from \"@ai-sdk/react\";\nimport { useAtlasContext } from \"./provider\";\nimport { useConversations } from \"./use-conversations\";\nimport type { Conversation } from \"../lib/types\";\n\nexport interface UseAtlasConversationsOptions {\n /** When false, refresh() becomes a no-op. Defaults to true. */\n enabled?: boolean;\n}\n\nexport interface UseAtlasConversationsReturn {\n conversations: Conversation[];\n total: number;\n isLoading: boolean;\n available: boolean;\n selectedId: string | null;\n setSelectedId: (id: string | null) => void;\n refresh: () => Promise<void>;\n loadConversation: (id: string) => Promise<UIMessage[] | null>;\n deleteConversation: (id: string) => Promise<boolean>;\n starConversation: (id: string, starred: boolean) => Promise<boolean>;\n}\n\n/**\n * Manage conversation history with auth automatically wired from AtlasProvider.\n *\n * Wraps the lower-level `useConversations` hook with context-derived\n * API URL and credentials.\n */\nexport function useAtlasConversations(\n options: UseAtlasConversationsOptions = {},\n): UseAtlasConversationsReturn {\n const { apiUrl, apiKey, isCrossOrigin } = useAtlasContext();\n const { enabled = true } = options;\n\n const inner = useConversations({\n apiUrl,\n enabled,\n getHeaders: () => {\n const headers: Record<string, string> = {};\n if (apiKey) headers[\"Authorization\"] = `Bearer ${apiKey}`;\n return headers;\n },\n getCredentials: () => (isCrossOrigin ? \"include\" : \"same-origin\"),\n });\n\n return {\n conversations: inner.conversations,\n total: inner.total,\n isLoading: inner.loading,\n available: inner.available,\n selectedId: inner.selectedId,\n setSelectedId: inner.setSelectedId,\n refresh: inner.refresh,\n loadConversation: inner.loadConversation,\n deleteConversation: inner.deleteConversation,\n starConversation: inner.starConversation,\n };\n}\n"]}
|
package/dist/hooks.d.cts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { A as AtlasAuthClient, T as ThemeMode } from './use-dark-mode-rFxawUv1.cjs';
|
|
4
|
+
export { E as ExploreToolResult, P as PythonToolResult, S as SQLToolResult, d as ToolRendererProps, a as ToolRenderers } from './use-dark-mode-rFxawUv1.cjs';
|
|
5
|
+
import { UIMessage } from '@ai-sdk/react';
|
|
6
|
+
import { AuthMode, Conversation } from '@useatlas/types';
|
|
7
|
+
export { AUTH_MODES, AuthMode, ChatErrorCode, ChatErrorInfo, Conversation, ConversationWithMessages, Message } from '@useatlas/types';
|
|
8
|
+
export { parseChatError } from '@useatlas/types/errors';
|
|
9
|
+
|
|
10
|
+
interface AtlasProviderProps {
|
|
11
|
+
/** Atlas API server URL (e.g. "https://api.example.com" or "" for same-origin). */
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
/** API key for simple-key auth mode. Sent as Bearer token. Accessible in context by all hooks. */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Custom auth client for managed auth mode (better-auth compatible). */
|
|
16
|
+
authClient?: AtlasAuthClient;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
interface AtlasContextValue {
|
|
20
|
+
apiUrl: string;
|
|
21
|
+
apiKey: string | undefined;
|
|
22
|
+
authClient: AtlasAuthClient;
|
|
23
|
+
isCrossOrigin: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Access the AtlasProvider context. Throws if used outside <AtlasProvider>. */
|
|
26
|
+
declare function useAtlasContext(): AtlasContextValue;
|
|
27
|
+
/**
|
|
28
|
+
* Lightweight provider for headless Atlas hooks.
|
|
29
|
+
*
|
|
30
|
+
* Wraps your app and supplies API URL, auth credentials, and an optional
|
|
31
|
+
* better-auth client to all Atlas hooks. Derives isCrossOrigin from apiUrl
|
|
32
|
+
* to configure credential handling for cross-origin requests.
|
|
33
|
+
*/
|
|
34
|
+
declare function AtlasProvider({ apiUrl, apiKey, authClient, children, }: AtlasProviderProps): react_jsx_runtime.JSX.Element;
|
|
35
|
+
|
|
36
|
+
type AtlasChatStatus = "submitted" | "streaming" | "ready" | "error";
|
|
37
|
+
interface UseAtlasChatOptions {
|
|
38
|
+
/** Conversation ID to associate with this chat session. The server will append messages to this conversation. To load prior messages, use loadConversation() from useAtlasConversations and pass them via setMessages. */
|
|
39
|
+
initialConversationId?: string;
|
|
40
|
+
/** Called when the server assigns or changes the conversation ID. */
|
|
41
|
+
onConversationIdChange?: (id: string) => void;
|
|
42
|
+
}
|
|
43
|
+
interface UseAtlasChatReturn {
|
|
44
|
+
messages: UIMessage[];
|
|
45
|
+
/** Replace all messages, or update via callback `(prev) => next`. */
|
|
46
|
+
setMessages: (messages: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])) => void;
|
|
47
|
+
/** Send a text message. Rejects on failure (also surfaces via `error`). */
|
|
48
|
+
sendMessage: (text: string) => Promise<void>;
|
|
49
|
+
/** Current input value (managed by the hook). */
|
|
50
|
+
input: string;
|
|
51
|
+
/** Update the input value. */
|
|
52
|
+
setInput: (input: string) => void;
|
|
53
|
+
/** Chat status from the AI SDK. */
|
|
54
|
+
status: AtlasChatStatus;
|
|
55
|
+
/** Whether the chat is currently loading (streaming or submitted). */
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
/** Last error, if any. */
|
|
58
|
+
error: Error | null;
|
|
59
|
+
/** Current conversation ID. Initially set from options, updated when the server returns an x-conversation-id header. */
|
|
60
|
+
conversationId: string | null;
|
|
61
|
+
/** Manually set the conversation ID. */
|
|
62
|
+
setConversationId: (id: string | null) => void;
|
|
63
|
+
}
|
|
64
|
+
declare function useAtlasChat(options?: UseAtlasChatOptions): UseAtlasChatReturn;
|
|
65
|
+
|
|
66
|
+
interface UseAtlasAuthReturn {
|
|
67
|
+
/** Auth mode detected from the server's /api/health endpoint. `null` while the initial health check is in flight. */
|
|
68
|
+
authMode: AuthMode | null;
|
|
69
|
+
/** Whether the user is authenticated (based on auth mode, API key, or session). */
|
|
70
|
+
isAuthenticated: boolean;
|
|
71
|
+
/** Session data for managed auth mode. */
|
|
72
|
+
session: {
|
|
73
|
+
user?: {
|
|
74
|
+
email?: string;
|
|
75
|
+
};
|
|
76
|
+
} | null;
|
|
77
|
+
/** Whether auth state is still being resolved (health check or managed session loading). */
|
|
78
|
+
isLoading: boolean;
|
|
79
|
+
/** Error from health check or auth operations. `null` when healthy. */
|
|
80
|
+
error: Error | null;
|
|
81
|
+
/** Sign in with email/password (managed auth). */
|
|
82
|
+
login: (email: string, password: string) => Promise<{
|
|
83
|
+
error?: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** Sign up with email/password/name (managed auth). */
|
|
86
|
+
signup: (email: string, password: string, name: string) => Promise<{
|
|
87
|
+
error?: string;
|
|
88
|
+
}>;
|
|
89
|
+
/** Sign out (managed auth). */
|
|
90
|
+
logout: () => Promise<{
|
|
91
|
+
error?: string;
|
|
92
|
+
}>;
|
|
93
|
+
}
|
|
94
|
+
declare function useAtlasAuth(): UseAtlasAuthReturn;
|
|
95
|
+
|
|
96
|
+
interface UseAtlasThemeReturn {
|
|
97
|
+
/** Current theme setting: "light", "dark", or "system". */
|
|
98
|
+
theme: ThemeMode;
|
|
99
|
+
/** Whether the effective (resolved) theme is dark. */
|
|
100
|
+
isDark: boolean;
|
|
101
|
+
/** Set the theme mode. Persists to localStorage. */
|
|
102
|
+
setTheme: (mode: ThemeMode) => void;
|
|
103
|
+
/** Apply a brand color (oklch format, e.g. "oklch(0.759 0.148 167.71)") via CSS custom property --atlas-brand. */
|
|
104
|
+
applyBrandColor: (color: string) => void;
|
|
105
|
+
}
|
|
106
|
+
declare function useAtlasTheme(): UseAtlasThemeReturn;
|
|
107
|
+
|
|
108
|
+
interface UseAtlasConversationsOptions {
|
|
109
|
+
/** When false, refresh() becomes a no-op. Defaults to true. */
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
}
|
|
112
|
+
interface UseAtlasConversationsReturn {
|
|
113
|
+
conversations: Conversation[];
|
|
114
|
+
total: number;
|
|
115
|
+
isLoading: boolean;
|
|
116
|
+
available: boolean;
|
|
117
|
+
selectedId: string | null;
|
|
118
|
+
setSelectedId: (id: string | null) => void;
|
|
119
|
+
refresh: () => Promise<void>;
|
|
120
|
+
loadConversation: (id: string) => Promise<UIMessage[] | null>;
|
|
121
|
+
deleteConversation: (id: string) => Promise<boolean>;
|
|
122
|
+
starConversation: (id: string, starred: boolean) => Promise<boolean>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Manage conversation history with auth automatically wired from AtlasProvider.
|
|
126
|
+
*
|
|
127
|
+
* Wraps the lower-level `useConversations` hook with context-derived
|
|
128
|
+
* API URL and credentials.
|
|
129
|
+
*/
|
|
130
|
+
declare function useAtlasConversations(options?: UseAtlasConversationsOptions): UseAtlasConversationsReturn;
|
|
131
|
+
|
|
132
|
+
export { AtlasAuthClient, type AtlasChatStatus, type AtlasContextValue, AtlasProvider, type AtlasProviderProps, ThemeMode, type UseAtlasAuthReturn, type UseAtlasChatOptions, type UseAtlasChatReturn, type UseAtlasConversationsOptions, type UseAtlasConversationsReturn, type UseAtlasThemeReturn, useAtlasAuth, useAtlasChat, useAtlasContext, useAtlasConversations, useAtlasTheme };
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { A as AtlasAuthClient, T as ThemeMode } from './use-dark-mode-rFxawUv1.js';
|
|
4
|
+
export { E as ExploreToolResult, P as PythonToolResult, S as SQLToolResult, d as ToolRendererProps, a as ToolRenderers } from './use-dark-mode-rFxawUv1.js';
|
|
5
|
+
import { UIMessage } from '@ai-sdk/react';
|
|
6
|
+
import { AuthMode, Conversation } from '@useatlas/types';
|
|
7
|
+
export { AUTH_MODES, AuthMode, ChatErrorCode, ChatErrorInfo, Conversation, ConversationWithMessages, Message } from '@useatlas/types';
|
|
8
|
+
export { parseChatError } from '@useatlas/types/errors';
|
|
9
|
+
|
|
10
|
+
interface AtlasProviderProps {
|
|
11
|
+
/** Atlas API server URL (e.g. "https://api.example.com" or "" for same-origin). */
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
/** API key for simple-key auth mode. Sent as Bearer token. Accessible in context by all hooks. */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Custom auth client for managed auth mode (better-auth compatible). */
|
|
16
|
+
authClient?: AtlasAuthClient;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
interface AtlasContextValue {
|
|
20
|
+
apiUrl: string;
|
|
21
|
+
apiKey: string | undefined;
|
|
22
|
+
authClient: AtlasAuthClient;
|
|
23
|
+
isCrossOrigin: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Access the AtlasProvider context. Throws if used outside <AtlasProvider>. */
|
|
26
|
+
declare function useAtlasContext(): AtlasContextValue;
|
|
27
|
+
/**
|
|
28
|
+
* Lightweight provider for headless Atlas hooks.
|
|
29
|
+
*
|
|
30
|
+
* Wraps your app and supplies API URL, auth credentials, and an optional
|
|
31
|
+
* better-auth client to all Atlas hooks. Derives isCrossOrigin from apiUrl
|
|
32
|
+
* to configure credential handling for cross-origin requests.
|
|
33
|
+
*/
|
|
34
|
+
declare function AtlasProvider({ apiUrl, apiKey, authClient, children, }: AtlasProviderProps): react_jsx_runtime.JSX.Element;
|
|
35
|
+
|
|
36
|
+
type AtlasChatStatus = "submitted" | "streaming" | "ready" | "error";
|
|
37
|
+
interface UseAtlasChatOptions {
|
|
38
|
+
/** Conversation ID to associate with this chat session. The server will append messages to this conversation. To load prior messages, use loadConversation() from useAtlasConversations and pass them via setMessages. */
|
|
39
|
+
initialConversationId?: string;
|
|
40
|
+
/** Called when the server assigns or changes the conversation ID. */
|
|
41
|
+
onConversationIdChange?: (id: string) => void;
|
|
42
|
+
}
|
|
43
|
+
interface UseAtlasChatReturn {
|
|
44
|
+
messages: UIMessage[];
|
|
45
|
+
/** Replace all messages, or update via callback `(prev) => next`. */
|
|
46
|
+
setMessages: (messages: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])) => void;
|
|
47
|
+
/** Send a text message. Rejects on failure (also surfaces via `error`). */
|
|
48
|
+
sendMessage: (text: string) => Promise<void>;
|
|
49
|
+
/** Current input value (managed by the hook). */
|
|
50
|
+
input: string;
|
|
51
|
+
/** Update the input value. */
|
|
52
|
+
setInput: (input: string) => void;
|
|
53
|
+
/** Chat status from the AI SDK. */
|
|
54
|
+
status: AtlasChatStatus;
|
|
55
|
+
/** Whether the chat is currently loading (streaming or submitted). */
|
|
56
|
+
isLoading: boolean;
|
|
57
|
+
/** Last error, if any. */
|
|
58
|
+
error: Error | null;
|
|
59
|
+
/** Current conversation ID. Initially set from options, updated when the server returns an x-conversation-id header. */
|
|
60
|
+
conversationId: string | null;
|
|
61
|
+
/** Manually set the conversation ID. */
|
|
62
|
+
setConversationId: (id: string | null) => void;
|
|
63
|
+
}
|
|
64
|
+
declare function useAtlasChat(options?: UseAtlasChatOptions): UseAtlasChatReturn;
|
|
65
|
+
|
|
66
|
+
interface UseAtlasAuthReturn {
|
|
67
|
+
/** Auth mode detected from the server's /api/health endpoint. `null` while the initial health check is in flight. */
|
|
68
|
+
authMode: AuthMode | null;
|
|
69
|
+
/** Whether the user is authenticated (based on auth mode, API key, or session). */
|
|
70
|
+
isAuthenticated: boolean;
|
|
71
|
+
/** Session data for managed auth mode. */
|
|
72
|
+
session: {
|
|
73
|
+
user?: {
|
|
74
|
+
email?: string;
|
|
75
|
+
};
|
|
76
|
+
} | null;
|
|
77
|
+
/** Whether auth state is still being resolved (health check or managed session loading). */
|
|
78
|
+
isLoading: boolean;
|
|
79
|
+
/** Error from health check or auth operations. `null` when healthy. */
|
|
80
|
+
error: Error | null;
|
|
81
|
+
/** Sign in with email/password (managed auth). */
|
|
82
|
+
login: (email: string, password: string) => Promise<{
|
|
83
|
+
error?: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** Sign up with email/password/name (managed auth). */
|
|
86
|
+
signup: (email: string, password: string, name: string) => Promise<{
|
|
87
|
+
error?: string;
|
|
88
|
+
}>;
|
|
89
|
+
/** Sign out (managed auth). */
|
|
90
|
+
logout: () => Promise<{
|
|
91
|
+
error?: string;
|
|
92
|
+
}>;
|
|
93
|
+
}
|
|
94
|
+
declare function useAtlasAuth(): UseAtlasAuthReturn;
|
|
95
|
+
|
|
96
|
+
interface UseAtlasThemeReturn {
|
|
97
|
+
/** Current theme setting: "light", "dark", or "system". */
|
|
98
|
+
theme: ThemeMode;
|
|
99
|
+
/** Whether the effective (resolved) theme is dark. */
|
|
100
|
+
isDark: boolean;
|
|
101
|
+
/** Set the theme mode. Persists to localStorage. */
|
|
102
|
+
setTheme: (mode: ThemeMode) => void;
|
|
103
|
+
/** Apply a brand color (oklch format, e.g. "oklch(0.759 0.148 167.71)") via CSS custom property --atlas-brand. */
|
|
104
|
+
applyBrandColor: (color: string) => void;
|
|
105
|
+
}
|
|
106
|
+
declare function useAtlasTheme(): UseAtlasThemeReturn;
|
|
107
|
+
|
|
108
|
+
interface UseAtlasConversationsOptions {
|
|
109
|
+
/** When false, refresh() becomes a no-op. Defaults to true. */
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
}
|
|
112
|
+
interface UseAtlasConversationsReturn {
|
|
113
|
+
conversations: Conversation[];
|
|
114
|
+
total: number;
|
|
115
|
+
isLoading: boolean;
|
|
116
|
+
available: boolean;
|
|
117
|
+
selectedId: string | null;
|
|
118
|
+
setSelectedId: (id: string | null) => void;
|
|
119
|
+
refresh: () => Promise<void>;
|
|
120
|
+
loadConversation: (id: string) => Promise<UIMessage[] | null>;
|
|
121
|
+
deleteConversation: (id: string) => Promise<boolean>;
|
|
122
|
+
starConversation: (id: string, starred: boolean) => Promise<boolean>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Manage conversation history with auth automatically wired from AtlasProvider.
|
|
126
|
+
*
|
|
127
|
+
* Wraps the lower-level `useConversations` hook with context-derived
|
|
128
|
+
* API URL and credentials.
|
|
129
|
+
*/
|
|
130
|
+
declare function useAtlasConversations(options?: UseAtlasConversationsOptions): UseAtlasConversationsReturn;
|
|
131
|
+
|
|
132
|
+
export { AtlasAuthClient, type AtlasChatStatus, type AtlasContextValue, AtlasProvider, type AtlasProviderProps, ThemeMode, type UseAtlasAuthReturn, type UseAtlasChatOptions, type UseAtlasChatReturn, type UseAtlasConversationsOptions, type UseAtlasConversationsReturn, type UseAtlasThemeReturn, useAtlasAuth, useAtlasChat, useAtlasContext, useAtlasConversations, useAtlasTheme };
|