@arbidocs/react 0.4.4 → 0.4.6
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 +23 -0
- package/dist/artifacts/index.cjs +458 -0
- package/dist/artifacts/index.cjs.map +1 -0
- package/dist/artifacts/index.d.cts +276 -0
- package/dist/artifacts/index.d.ts +276 -0
- package/dist/artifacts/index.js +434 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/redline-core.cjs +20 -0
- package/dist/artifacts/redline-core.cjs.map +1 -0
- package/dist/artifacts/redline-core.d.cts +36 -0
- package/dist/artifacts/redline-core.d.ts +36 -0
- package/dist/artifacts/redline-core.js +3 -0
- package/dist/artifacts/redline-core.js.map +1 -0
- package/dist/{chunk-MIJRORQL.js → chunk-2ACHNDO6.js} +10 -304
- package/dist/chunk-2ACHNDO6.js.map +1 -0
- package/dist/chunk-CBJ3WOGD.cjs +317 -0
- package/dist/chunk-CBJ3WOGD.cjs.map +1 -0
- package/dist/{chunk-EJ2BMHYK.js → chunk-FSMIN5VX.js} +4 -3
- package/dist/chunk-FSMIN5VX.js.map +1 -0
- package/dist/{chunk-JKO3NR5L.js → chunk-HDCRPPBW.js} +5 -23
- package/dist/chunk-HDCRPPBW.js.map +1 -0
- package/dist/chunk-J4MX2W4H.js +26 -0
- package/dist/chunk-J4MX2W4H.js.map +1 -0
- package/dist/chunk-KWCHIAQ5.js +290 -0
- package/dist/chunk-KWCHIAQ5.js.map +1 -0
- package/dist/{chunk-6ALMBER7.js → chunk-N5SVBDLC.js} +4 -9
- package/dist/chunk-N5SVBDLC.js.map +1 -0
- package/dist/{chunk-RZQACYNQ.cjs → chunk-OBNTJEEO.cjs} +14 -20
- package/dist/chunk-OBNTJEEO.cjs.map +1 -0
- package/dist/chunk-OI55JRKT.cjs +334 -0
- package/dist/chunk-OI55JRKT.cjs.map +1 -0
- package/dist/{chunk-BXP6S34V.cjs → chunk-PGLV23SB.cjs} +13 -12
- package/dist/chunk-PGLV23SB.cjs.map +1 -0
- package/dist/chunk-RIHMIEXM.js +320 -0
- package/dist/chunk-RIHMIEXM.js.map +1 -0
- package/dist/chunk-RKWNX32A.js +299 -0
- package/dist/chunk-RKWNX32A.js.map +1 -0
- package/dist/chunk-S6A6FSG7.cjs +13 -0
- package/dist/chunk-S6A6FSG7.cjs.map +1 -0
- package/dist/chunk-SN5YV6FF.js +11 -0
- package/dist/chunk-SN5YV6FF.js.map +1 -0
- package/dist/{chunk-7IOCMCC5.cjs → chunk-TMPDW7J5.cjs} +3 -23
- package/dist/chunk-TMPDW7J5.cjs.map +1 -0
- package/dist/chunk-VJWAP2HJ.cjs +303 -0
- package/dist/chunk-VJWAP2HJ.cjs.map +1 -0
- package/dist/{chunk-ORKGCXG3.cjs → chunk-Z5YCRJY3.cjs} +125 -429
- package/dist/chunk-Z5YCRJY3.cjs.map +1 -0
- package/dist/chunk-ZMTLGO3K.cjs +29 -0
- package/dist/chunk-ZMTLGO3K.cjs.map +1 -0
- package/dist/index-CC6CvXEs.d.cts +1366 -0
- package/dist/index-CC6CvXEs.d.ts +1366 -0
- package/dist/index.cjs +1159 -722
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +588 -28
- package/dist/index.d.ts +588 -28
- package/dist/index.js +645 -310
- package/dist/index.js.map +1 -1
- package/dist/shell/index.cjs +8 -7
- package/dist/shell/index.js +3 -2
- package/dist/ui/index.cjs +158 -152
- package/dist/ui/index.d.cts +24 -1324
- package/dist/ui/index.d.ts +24 -1324
- package/dist/ui/index.js +4 -2
- package/dist/viewers/index.cjs +9 -8
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.js +3 -2
- package/dist/viewers/index.js.map +1 -1
- package/package.json +19 -3
- package/dist/chunk-6ALMBER7.js.map +0 -1
- package/dist/chunk-7IOCMCC5.cjs.map +0 -1
- package/dist/chunk-BXP6S34V.cjs.map +0 -1
- package/dist/chunk-EJ2BMHYK.js.map +0 -1
- package/dist/chunk-JKO3NR5L.js.map +0 -1
- package/dist/chunk-MIJRORQL.js.map +0 -1
- package/dist/chunk-ORKGCXG3.cjs.map +0 -1
- package/dist/chunk-RZQACYNQ.cjs.map +0 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkZMTLGO3K_cjs = require('./chunk-ZMTLGO3K.cjs');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var reactQuery = require('@tanstack/react-query');
|
|
6
|
+
|
|
7
|
+
// src/credits.ts
|
|
8
|
+
var DEFAULT_USD_PER_CREDIT = 0.01;
|
|
9
|
+
function formatCredits(credits, options = {}) {
|
|
10
|
+
const { unit = true, locale = "en-US" } = options;
|
|
11
|
+
const whole = Math.round(Number.isFinite(credits) ? credits : 0);
|
|
12
|
+
const digits = whole.toLocaleString(locale);
|
|
13
|
+
return unit ? `${digits} ${whole === 1 ? "credit" : "credits"}` : digits;
|
|
14
|
+
}
|
|
15
|
+
function creditsToUsd(credits, usdPerCredit = DEFAULT_USD_PER_CREDIT) {
|
|
16
|
+
return credits * usdPerCredit;
|
|
17
|
+
}
|
|
18
|
+
function isUsageMetered(usage, subscription) {
|
|
19
|
+
const empty = usage.total_spend === 0 && usage.total_tokens === 0 && usage.total_requests === 0;
|
|
20
|
+
return !(empty && subscription === "dev");
|
|
21
|
+
}
|
|
22
|
+
var arbiQueryKeys = {
|
|
23
|
+
workspaces: () => ["arbi", "workspaces"],
|
|
24
|
+
documents: (workspaceId) => ["arbi", "documents", workspaceId],
|
|
25
|
+
conversations: (workspaceId) => ["arbi", "conversations", workspaceId],
|
|
26
|
+
conversationThreads: (workspaceId, conversationId) => ["arbi", "conversations", workspaceId, "threads", conversationId],
|
|
27
|
+
tags: (workspaceId) => ["arbi", "tags", workspaceId],
|
|
28
|
+
thumbnails: (docIds) => ["arbi", "thumbnails", [...docIds].sort().join(",")],
|
|
29
|
+
parsedDoc: (docId, stage) => ["arbi", "parsedDoc", docId, stage],
|
|
30
|
+
agents: () => ["arbi", "agents"],
|
|
31
|
+
sessions: () => ["arbi", "sessions"],
|
|
32
|
+
health: () => ["arbi", "health"],
|
|
33
|
+
tasks: () => ["arbi", "tasks"],
|
|
34
|
+
facts: (workspaceId) => ["arbi", "facts", workspaceId],
|
|
35
|
+
configs: () => ["arbi", "configs"],
|
|
36
|
+
activity: () => ["arbi", "activity"],
|
|
37
|
+
projects: () => ["arbi", "projects"],
|
|
38
|
+
projectUsage: (projectExtId, monthsBack) => ["arbi", "projectUsage", projectExtId, monthsBack],
|
|
39
|
+
projectInvoices: (projectExtId) => ["arbi", "projectInvoices", projectExtId],
|
|
40
|
+
userUsageToday: () => ["arbi", "userUsageToday"],
|
|
41
|
+
contacts: () => ["arbi", "contacts"],
|
|
42
|
+
skills: () => ["arbi", "skills"],
|
|
43
|
+
taskRuns: (taskId) => ["arbi", "taskRuns", taskId],
|
|
44
|
+
/** An agent's pinned config; `undefined` = the library default config. */
|
|
45
|
+
agentConfig: (agentExtId) => ["arbi", "agentConfig", agentExtId ?? "default"],
|
|
46
|
+
agentWorkspaces: (agentExtId) => ["arbi", "agentWorkspaces", agentExtId],
|
|
47
|
+
models: () => ["arbi", "models"],
|
|
48
|
+
/** The signed-in user's own profile (name, picture, email). */
|
|
49
|
+
profile: () => ["arbi", "profile"],
|
|
50
|
+
/** The signed-in user's settings record (notification preferences, flags). */
|
|
51
|
+
userSettings: () => ["arbi", "userSettings"]
|
|
52
|
+
};
|
|
53
|
+
function useWorkspaces(options) {
|
|
54
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
55
|
+
return reactQuery.useQuery({
|
|
56
|
+
queryKey: arbiQueryKeys.workspaces(),
|
|
57
|
+
queryFn: () => arbi.workspaces.list(),
|
|
58
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function useDocuments(workspaceId, options) {
|
|
62
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
63
|
+
return reactQuery.useQuery({
|
|
64
|
+
queryKey: arbiQueryKeys.documents(workspaceId ?? ""),
|
|
65
|
+
queryFn: () => arbi.documents.list(),
|
|
66
|
+
enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function useConversations(workspaceId, options) {
|
|
70
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
71
|
+
return reactQuery.useQuery({
|
|
72
|
+
queryKey: arbiQueryKeys.conversations(workspaceId ?? ""),
|
|
73
|
+
queryFn: () => arbi.conversations.list(),
|
|
74
|
+
enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function useConversationThreads(workspaceId, conversationId, options) {
|
|
78
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
79
|
+
return reactQuery.useQuery({
|
|
80
|
+
queryKey: arbiQueryKeys.conversationThreads(workspaceId ?? "", conversationId ?? ""),
|
|
81
|
+
queryFn: () => arbi.conversations.getThreads(conversationId),
|
|
82
|
+
enabled: (options?.enabled ?? true) && !!workspaceId && !!conversationId && arbi.hasWorkspace,
|
|
83
|
+
gcTime: 0
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function useTags(workspaceId, options) {
|
|
87
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
88
|
+
return reactQuery.useQuery({
|
|
89
|
+
queryKey: arbiQueryKeys.tags(workspaceId ?? ""),
|
|
90
|
+
queryFn: () => arbi.tags.list(),
|
|
91
|
+
enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function useThumbnails(docIds, options) {
|
|
95
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
96
|
+
return reactQuery.useQuery({
|
|
97
|
+
queryKey: arbiQueryKeys.thumbnails(docIds),
|
|
98
|
+
queryFn: () => arbi.documents.getThumbnails(docIds),
|
|
99
|
+
enabled: (options?.enabled ?? true) && docIds.length > 0 && arbi.hasWorkspace,
|
|
100
|
+
staleTime: 5 * 6e4
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function useParsedDocument(docId, stage = "final", options) {
|
|
104
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
105
|
+
return reactQuery.useQuery({
|
|
106
|
+
queryKey: arbiQueryKeys.parsedDoc(docId ?? "", stage),
|
|
107
|
+
queryFn: () => arbi.documents.getParsedContent(docId, stage),
|
|
108
|
+
enabled: (options?.enabled ?? true) && !!docId && arbi.hasWorkspace
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function useAssistantQuery() {
|
|
112
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
113
|
+
return reactQuery.useMutation({
|
|
114
|
+
mutationFn: ({ question, ...options }) => arbi.assistant.query(question, options)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function useAgents(options) {
|
|
118
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
119
|
+
return reactQuery.useQuery({
|
|
120
|
+
queryKey: arbiQueryKeys.agents(),
|
|
121
|
+
queryFn: () => arbi.agents.list(),
|
|
122
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function useDeleteAgents() {
|
|
126
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
127
|
+
return reactQuery.useMutation({
|
|
128
|
+
mutationFn: ({ agentExtIds }) => arbi.agents.delete(agentExtIds)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function useSessions(options) {
|
|
132
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
133
|
+
return reactQuery.useQuery({
|
|
134
|
+
queryKey: arbiQueryKeys.sessions(),
|
|
135
|
+
queryFn: () => arbi.sessions.list(),
|
|
136
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function useHealth(options) {
|
|
140
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
141
|
+
return reactQuery.useQuery({
|
|
142
|
+
queryKey: arbiQueryKeys.health(),
|
|
143
|
+
queryFn: () => arbi.health.check(),
|
|
144
|
+
enabled: options?.enabled
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function useTasks(options) {
|
|
148
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
149
|
+
return reactQuery.useQuery({
|
|
150
|
+
queryKey: arbiQueryKeys.tasks(),
|
|
151
|
+
queryFn: () => arbi.tasks.list(),
|
|
152
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function useFacts(workspaceId, options) {
|
|
156
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
157
|
+
return reactQuery.useQuery({
|
|
158
|
+
queryKey: arbiQueryKeys.facts(workspaceId ?? ""),
|
|
159
|
+
queryFn: () => arbi.facts.list({ pinnedOnly: options?.pinnedOnly }),
|
|
160
|
+
enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function useConfigs(options) {
|
|
164
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
165
|
+
return reactQuery.useQuery({
|
|
166
|
+
queryKey: arbiQueryKeys.configs(),
|
|
167
|
+
queryFn: () => arbi.agentConfig.list(),
|
|
168
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function useActivity(options) {
|
|
172
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
173
|
+
return reactQuery.useQuery({
|
|
174
|
+
queryKey: arbiQueryKeys.activity(),
|
|
175
|
+
queryFn: () => arbi.dm.listActivity({ limit: options?.limit, offset: options?.offset }),
|
|
176
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function useProjects(options) {
|
|
180
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
181
|
+
return reactQuery.useQuery({
|
|
182
|
+
queryKey: arbiQueryKeys.projects(),
|
|
183
|
+
queryFn: () => arbi.projects.list(),
|
|
184
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function useProjectUsage(projectExtId, monthsBack = 0, options) {
|
|
188
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
189
|
+
const usage = reactQuery.useQuery({
|
|
190
|
+
queryKey: arbiQueryKeys.projectUsage(projectExtId ?? "", monthsBack),
|
|
191
|
+
queryFn: () => arbi.projects.usage(projectExtId, monthsBack),
|
|
192
|
+
enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn
|
|
193
|
+
});
|
|
194
|
+
const projects = useProjects({ enabled: !!projectExtId && (options?.enabled ?? true) });
|
|
195
|
+
const subscription = projects.data?.find((p) => p.external_id === projectExtId)?.subscription;
|
|
196
|
+
const metered = usage.data ? isUsageMetered(usage.data, subscription) : void 0;
|
|
197
|
+
return { ...usage, metered };
|
|
198
|
+
}
|
|
199
|
+
function useProjectsUsage(projectExtIds, monthsBack = 0, options) {
|
|
200
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
201
|
+
const enabled = (options?.enabled ?? true) && arbi.isLoggedIn;
|
|
202
|
+
const projects = useProjects({ enabled: enabled && projectExtIds.length > 0 });
|
|
203
|
+
const results = reactQuery.useQueries({
|
|
204
|
+
queries: projectExtIds.map((id) => ({
|
|
205
|
+
queryKey: arbiQueryKeys.projectUsage(id, monthsBack),
|
|
206
|
+
queryFn: () => arbi.projects.usage(id, monthsBack),
|
|
207
|
+
enabled: enabled && !!id
|
|
208
|
+
}))
|
|
209
|
+
});
|
|
210
|
+
const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join("|") + `#${projects.dataUpdatedAt}`;
|
|
211
|
+
return react.useMemo(() => {
|
|
212
|
+
const dailyMap = /* @__PURE__ */ new Map();
|
|
213
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
214
|
+
let totalCredits = 0;
|
|
215
|
+
let anyData = false;
|
|
216
|
+
let anyMetered = false;
|
|
217
|
+
let totalTokens = 0;
|
|
218
|
+
let totalRequests = 0;
|
|
219
|
+
results.forEach((r, i) => {
|
|
220
|
+
const d = r.data;
|
|
221
|
+
if (!d) return;
|
|
222
|
+
anyData = true;
|
|
223
|
+
const subscription = projects.data?.find(
|
|
224
|
+
(p) => p.external_id === projectExtIds[i]
|
|
225
|
+
)?.subscription;
|
|
226
|
+
if (isUsageMetered(d, subscription)) anyMetered = true;
|
|
227
|
+
totalCredits += d.total_spend ?? 0;
|
|
228
|
+
totalTokens += d.total_tokens ?? 0;
|
|
229
|
+
totalRequests += d.total_requests ?? 0;
|
|
230
|
+
for (const day of d.daily ?? []) {
|
|
231
|
+
const cur = dailyMap.get(day.date) ?? {
|
|
232
|
+
date: day.date,
|
|
233
|
+
credits: 0,
|
|
234
|
+
totalTokens: 0,
|
|
235
|
+
apiRequests: 0
|
|
236
|
+
};
|
|
237
|
+
cur.credits += day.spend ?? 0;
|
|
238
|
+
cur.totalTokens += day.total_tokens ?? 0;
|
|
239
|
+
cur.apiRequests += day.api_requests ?? 0;
|
|
240
|
+
dailyMap.set(day.date, cur);
|
|
241
|
+
}
|
|
242
|
+
for (const [model, mg] of Object.entries(d.model_groups ?? {})) {
|
|
243
|
+
const cur = modelMap.get(model) ?? {
|
|
244
|
+
model,
|
|
245
|
+
credits: 0,
|
|
246
|
+
totalTokens: 0,
|
|
247
|
+
promptTokens: 0,
|
|
248
|
+
completionTokens: 0,
|
|
249
|
+
successfulRequests: 0
|
|
250
|
+
};
|
|
251
|
+
cur.credits += mg.spend ?? 0;
|
|
252
|
+
cur.totalTokens += mg.total_tokens ?? 0;
|
|
253
|
+
cur.promptTokens += mg.prompt_tokens ?? 0;
|
|
254
|
+
cur.completionTokens += mg.completion_tokens ?? 0;
|
|
255
|
+
cur.successfulRequests += mg.successful_requests ?? 0;
|
|
256
|
+
modelMap.set(model, cur);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
totalCredits,
|
|
261
|
+
totalTokens,
|
|
262
|
+
totalRequests,
|
|
263
|
+
daily: [...dailyMap.values()].sort((a, b) => a.date.localeCompare(b.date)),
|
|
264
|
+
modelGroups: [...modelMap.values()].sort(
|
|
265
|
+
(a, b) => b.credits - a.credits || b.totalTokens - a.totalTokens
|
|
266
|
+
),
|
|
267
|
+
metered: !anyData || anyMetered,
|
|
268
|
+
isLoading: results.some((r) => r.isLoading),
|
|
269
|
+
isError: results.some((r) => r.isError)
|
|
270
|
+
};
|
|
271
|
+
}, [signature]);
|
|
272
|
+
}
|
|
273
|
+
function useProjectInvoices(projectExtId, options) {
|
|
274
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
275
|
+
return reactQuery.useQuery({
|
|
276
|
+
queryKey: arbiQueryKeys.projectInvoices(projectExtId ?? ""),
|
|
277
|
+
queryFn: () => arbi.projects.invoices(projectExtId),
|
|
278
|
+
enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function useUserUsageToday(options) {
|
|
282
|
+
const arbi = chunkZMTLGO3K_cjs.useArbi();
|
|
283
|
+
return reactQuery.useQuery({
|
|
284
|
+
queryKey: arbiQueryKeys.userUsageToday(),
|
|
285
|
+
queryFn: () => arbi.user.usageToday(),
|
|
286
|
+
enabled: options?.enabled ?? arbi.isLoggedIn
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
exports.DEFAULT_USD_PER_CREDIT = DEFAULT_USD_PER_CREDIT;
|
|
291
|
+
exports.arbiQueryKeys = arbiQueryKeys;
|
|
292
|
+
exports.creditsToUsd = creditsToUsd;
|
|
293
|
+
exports.formatCredits = formatCredits;
|
|
294
|
+
exports.isUsageMetered = isUsageMetered;
|
|
295
|
+
exports.useActivity = useActivity;
|
|
296
|
+
exports.useAgents = useAgents;
|
|
297
|
+
exports.useAssistantQuery = useAssistantQuery;
|
|
298
|
+
exports.useConfigs = useConfigs;
|
|
299
|
+
exports.useConversationThreads = useConversationThreads;
|
|
300
|
+
exports.useConversations = useConversations;
|
|
301
|
+
exports.useDeleteAgents = useDeleteAgents;
|
|
302
|
+
exports.useDocuments = useDocuments;
|
|
303
|
+
exports.useFacts = useFacts;
|
|
304
|
+
exports.useHealth = useHealth;
|
|
305
|
+
exports.useParsedDocument = useParsedDocument;
|
|
306
|
+
exports.useProjectInvoices = useProjectInvoices;
|
|
307
|
+
exports.useProjectUsage = useProjectUsage;
|
|
308
|
+
exports.useProjects = useProjects;
|
|
309
|
+
exports.useProjectsUsage = useProjectsUsage;
|
|
310
|
+
exports.useSessions = useSessions;
|
|
311
|
+
exports.useTags = useTags;
|
|
312
|
+
exports.useTasks = useTasks;
|
|
313
|
+
exports.useThumbnails = useThumbnails;
|
|
314
|
+
exports.useUserUsageToday = useUserUsageToday;
|
|
315
|
+
exports.useWorkspaces = useWorkspaces;
|
|
316
|
+
//# sourceMappingURL=chunk-CBJ3WOGD.cjs.map
|
|
317
|
+
//# sourceMappingURL=chunk-CBJ3WOGD.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/credits.ts","../src/hooks.ts"],"names":["useArbi","useQuery","useMutation","useQueries","useMemo"],"mappings":"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","file":"chunk-CBJ3WOGD.cjs","sourcesContent":["/**\n * Credits: the unit the ARBI backend reports AI usage in.\n *\n * The usage endpoints (`/v1/user/projects/{id}/usage`, `/me/usage/today`) convert the metered USD\n * spend into whole credits at the API boundary: 1 credit = `CREDITS_TO_AI_USD`, which is $0.01 on\n * a default deployment. The fields are still named `spend` / `total_spend` in the schema, but they\n * hold CREDITS, never dollars. Label them as credits; use {@link creditsToUsd} only when a\n * dollar figure is genuinely wanted, with the deployment's own rate.\n */\n\n/** Dollars per credit on a default deployment (`CREDITS_TO_AI_USD`). */\nexport const DEFAULT_USD_PER_CREDIT = 0.01\n\nexport interface FormatCreditsOptions {\n /** Append the unit (\"12 credits\"). Default true; pass false inside a column headed \"Credits\". */\n unit?: boolean\n /** BCP 47 locale for the digit grouping. Default `en-US`. */\n locale?: string\n}\n\n/** \"1,234 credits\" / \"1 credit\". The backend reports whole credits; this rounds away float dust. */\nexport function formatCredits(credits: number, options: FormatCreditsOptions = {}): string {\n const { unit = true, locale = 'en-US' } = options\n const whole = Math.round(Number.isFinite(credits) ? credits : 0)\n const digits = whole.toLocaleString(locale)\n return unit ? `${digits} ${whole === 1 ? 'credit' : 'credits'}` : digits\n}\n\n/** The dollar value of an amount of credits. `usdPerCredit` defaults to {@link DEFAULT_USD_PER_CREDIT}. */\nexport function creditsToUsd(\n credits: number,\n usdPerCredit: number = DEFAULT_USD_PER_CREDIT\n): number {\n return credits * usdPerCredit\n}\n\n/** The slice of a usage response that tells whether anything was recorded. */\nexport interface UsageTotals {\n total_spend: number\n total_tokens: number\n total_requests: number\n}\n\n/**\n * Was this usage actually metered? A project on the `dev` plan belongs to a deployment with\n * billing switched off: the backend only records AI usage per project when billing is enabled, so\n * an all-zero response there means \"not metered\", not \"nothing happened\". Show a note instead of\n * silent zeros.\n */\nexport function isUsageMetered(\n usage: UsageTotals,\n subscription: string | null | undefined\n): boolean {\n const empty = usage.total_spend === 0 && usage.total_tokens === 0 && usage.total_requests === 0\n return !(empty && subscription === 'dev')\n}\n","/**\n * React Query hooks that use the Arbi instance from context.\n */\n\nimport { useMemo } from 'react'\nimport { useQuery, useQueries, useMutation } from '@tanstack/react-query'\nimport type {\n SSEStreamResult,\n SSEStreamStartData,\n ResponseOutputItemDoneEvent,\n ArtifactEvent,\n UserMessageEvent,\n MessageMetadataPayload,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport type { ParsedDocument } from './documents/parsed-types'\nimport { isUsageMetered } from './credits'\n\n// ── Query keys ──────────────────────────────────────────────────────────────\n\nexport const arbiQueryKeys = {\n workspaces: () => ['arbi', 'workspaces'] as const,\n documents: (workspaceId: string) => ['arbi', 'documents', workspaceId] as const,\n conversations: (workspaceId: string) => ['arbi', 'conversations', workspaceId] as const,\n conversationThreads: (workspaceId: string, conversationId: string) =>\n ['arbi', 'conversations', workspaceId, 'threads', conversationId] as const,\n tags: (workspaceId: string) => ['arbi', 'tags', workspaceId] as const,\n thumbnails: (docIds: string[]) => ['arbi', 'thumbnails', [...docIds].sort().join(',')] as const,\n parsedDoc: (docId: string, stage: string) => ['arbi', 'parsedDoc', docId, stage] as const,\n agents: () => ['arbi', 'agents'] as const,\n sessions: () => ['arbi', 'sessions'] as const,\n health: () => ['arbi', 'health'] as const,\n tasks: () => ['arbi', 'tasks'] as const,\n facts: (workspaceId: string) => ['arbi', 'facts', workspaceId] as const,\n configs: () => ['arbi', 'configs'] as const,\n activity: () => ['arbi', 'activity'] as const,\n projects: () => ['arbi', 'projects'] as const,\n projectUsage: (projectExtId: string, monthsBack: number) =>\n ['arbi', 'projectUsage', projectExtId, monthsBack] as const,\n projectInvoices: (projectExtId: string) => ['arbi', 'projectInvoices', projectExtId] as const,\n userUsageToday: () => ['arbi', 'userUsageToday'] as const,\n contacts: () => ['arbi', 'contacts'] as const,\n skills: () => ['arbi', 'skills'] as const,\n taskRuns: (taskId: string) => ['arbi', 'taskRuns', taskId] as const,\n /** An agent's pinned config; `undefined` = the library default config. */\n agentConfig: (agentExtId?: string) => ['arbi', 'agentConfig', agentExtId ?? 'default'] as const,\n agentWorkspaces: (agentExtId: string) => ['arbi', 'agentWorkspaces', agentExtId] as const,\n models: () => ['arbi', 'models'] as const,\n /** The signed-in user's own profile (name, picture, email). */\n profile: () => ['arbi', 'profile'] as const,\n /** The signed-in user's settings record (notification preferences, flags). */\n userSettings: () => ['arbi', 'userSettings'] as const,\n}\n\n// ── Hooks ───────────────────────────────────────────────────────────────────\n\n/** List the logged-in user's workspaces. */\nexport function useWorkspaces(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.workspaces(),\n queryFn: () => arbi.workspaces.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** List documents in a workspace. */\nexport function useDocuments(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.documents(workspaceId ?? ''),\n queryFn: () => arbi.documents.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/** List conversations in a workspace. */\nexport function useConversations(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.conversations(workspaceId ?? ''),\n queryFn: () => arbi.conversations.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/**\n * A conversation's stored threads (each with its message history, citations data included).\n * Always refetched on mount: a conversation that was open before may have new turns.\n */\nexport function useConversationThreads(\n workspaceId: string | undefined,\n conversationId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.conversationThreads(workspaceId ?? '', conversationId ?? ''),\n queryFn: () => arbi.conversations.getThreads(conversationId as string),\n enabled: (options?.enabled ?? true) && !!workspaceId && !!conversationId && arbi.hasWorkspace,\n gcTime: 0,\n })\n}\n\n/** List tags in a workspace. */\nexport function useTags(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tags(workspaceId ?? ''),\n queryFn: () => arbi.tags.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/**\n * Batch-fetch first-page thumbnails for a set of documents. Returns a map of\n * doc external id → `data:image/webp` URI (or `null` when no thumbnail exists).\n * Cached for a few minutes since thumbnails are effectively immutable per doc.\n */\nexport function useThumbnails(docIds: string[], options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.thumbnails(docIds),\n queryFn: () => arbi.documents.getThumbnails(docIds),\n enabled: (options?.enabled ?? true) && docIds.length > 0 && arbi.hasWorkspace,\n staleTime: 5 * 60_000,\n })\n}\n\n/**\n * Fetch a document's parsed content (chunks grouped by page) for the review\n * viewer. `stage` defaults to `final` (fully processed); `marker`/`subchunk`\n * expose earlier pipeline stages.\n */\nexport function useParsedDocument(\n docId: string | undefined,\n stage: string = 'final',\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.parsedDoc(docId ?? '', stage),\n queryFn: () =>\n arbi.documents.getParsedContent(docId as string, stage) as unknown as Promise<ParsedDocument>,\n enabled: (options?.enabled ?? true) && !!docId && arbi.hasWorkspace,\n })\n}\n\n/** Send a streaming query to the RAG assistant. Returns a mutation. */\nexport function useAssistantQuery() {\n const arbi = useArbi()\n\n return useMutation<\n SSEStreamResult,\n Error,\n {\n question: string\n docIds: string[]\n previousResponseId?: string | null\n model?: string\n onToken?: (content: string) => void\n /** Aborts the request and the stream; the mutation then rejects with an `AbortError`. */\n signal?: AbortSignal\n onStreamStart?: (data: SSEStreamStartData) => void\n onUserMessage?: (data: UserMessageEvent) => void\n onMetadata?: (data: MessageMetadataPayload) => void\n onOutputItemDone?: (data: ResponseOutputItemDoneEvent) => void\n onArtifact?: (data: ArtifactEvent) => void\n onError?: (message: string) => void\n onComplete?: () => void\n }\n >({\n mutationFn: ({ question, ...options }) => arbi.assistant.query(question, options),\n })\n}\n\n/** List agents owned by the current user. */\nexport function useAgents(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agents(),\n queryFn: () => arbi.agents.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Delete agents. Returns a mutation. */\nexport function useDeleteAgents() {\n const arbi = useArbi()\n return useMutation<unknown, Error, { agentExtIds: string[] }>({\n mutationFn: ({ agentExtIds }) => arbi.agents.delete(agentExtIds),\n })\n}\n\n/** List active sessions. */\nexport function useSessions(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.sessions(),\n queryFn: () => arbi.sessions.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Authorize a delegated session (generates claim code). Returns a mutation. */\n\n/** Check backend health. */\nexport function useHealth(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.health(),\n queryFn: () => arbi.health.check(),\n enabled: options?.enabled,\n })\n}\n\n// ── Scheduled tasks ──────────────────────────────────────────────────────────\n\n/** List the caller's scheduled agent tasks. */\nexport function useTasks(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tasks(),\n queryFn: () => arbi.tasks.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Workspace notes ──────────────────────────────────────────────────────────\n\n/** List the open workspace's facts. */\nexport function useFacts(\n workspaceId: string | undefined,\n options?: { enabled?: boolean; pinnedOnly?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.facts(workspaceId ?? ''),\n queryFn: () => arbi.facts.list({ pinnedOnly: options?.pinnedOnly }),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n// ── Behaviour-template configs ───────────────────────────────────────────────\n\n/** List the caller's saved agent configurations (behaviour templates). */\nexport function useConfigs(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.configs(),\n queryFn: () => arbi.agentConfig.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Activity feed ─────────────────────────────────────────────────────────────\n\n/**\n * List the caller's durable activity feed, newest first.\n *\n * Activity entries are backend-originated, to-self log lines that are always\n * read — they are deliberately kept out of the normal notifications/DM feed and\n * never affect the unread badge, so this is a separate, opt-in query.\n */\nexport function useActivity(options?: { enabled?: boolean; limit?: number; offset?: number }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.activity(),\n queryFn: () => arbi.dm.listActivity({ limit: options?.limit, offset: options?.offset }),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Projects, usage & spend ───────────────────────────────────────────────────\n\n/** List the logged-in user's projects (billing accounts). */\nexport function useProjects(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projects(),\n queryFn: () => arbi.projects.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/**\n * AI usage breakdown for a project's billing period. `monthsBack` selects the period (0 =\n * current, 1 = previous month, …).\n *\n * The response's `total_spend` / `spend` fields are CREDITS, not dollars (see `formatCredits`).\n * `metered` is `false` when the deployment does not record usage (a `dev`-plan project with all\n * zeros): show \"usage is not metered here\" instead of zeros. It is `undefined` until the usage\n * has loaded.\n */\nexport function useProjectUsage(\n projectExtId: string | undefined,\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n const usage = useQuery({\n queryKey: arbiQueryKeys.projectUsage(projectExtId ?? '', monthsBack),\n queryFn: () => arbi.projects.usage(projectExtId as string, monthsBack),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n const projects = useProjects({ enabled: !!projectExtId && (options?.enabled ?? true) })\n const subscription = projects.data?.find((p) => p.external_id === projectExtId)?.subscription\n const metered = usage.data ? isUsageMetered(usage.data, subscription) : undefined\n return { ...usage, metered }\n}\n\n/** One day of aggregated usage across projects (for a spend/token trend). */\nexport interface AggregatedDailyUsage {\n date: string\n /** Credits used that day (not dollars). */\n credits: number\n totalTokens: number\n apiRequests: number\n}\n\n/** One model group's aggregated usage across projects (for a breakdown). */\nexport interface AggregatedModelGroupUsage {\n model: string\n /** Credits used by this model group (not dollars). */\n credits: number\n totalTokens: number\n promptTokens: number\n completionTokens: number\n successfulRequests: number\n}\n\n/** Aggregated AI usage + spend across several projects. */\nexport interface ProjectsUsageAggregate {\n /** Summed usage across the projects, in CREDITS (1 credit = $0.01 by default), not dollars. */\n totalCredits: number\n /** Summed token count across the projects. */\n totalTokens: number\n /** Summed API request count across the projects. */\n totalRequests: number\n /** Per-day totals merged across every project, oldest first. */\n daily: AggregatedDailyUsage[]\n /** Per-model-group totals merged across every project, most credits first. */\n modelGroups: AggregatedModelGroupUsage[]\n /**\n * False when none of the loaded projects records usage (billing is off on this deployment), so\n * zeros mean \"not metered\". True while anything real was recorded, or before data arrived.\n */\n metered: boolean\n /** True while any per-project query is still loading. */\n isLoading: boolean\n /** True if any per-project query errored. */\n isError: boolean\n}\n\n/**\n * Firm-wide AI usage + spend: aggregates {@link useProjectUsage} across several\n * projects (e.g. all of a firm's matters) in parallel and merges the real totals,\n * the daily trend, and the per-model breakdown. Shares the per-project query\n * cache, so it costs nothing extra where a project's usage is already loaded.\n * Numbers are genuine — zero projects (or zero billed work) yields zero totals;\n * callers render that honestly.\n */\nexport function useProjectsUsage(\n projectExtIds: string[],\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n): ProjectsUsageAggregate {\n const arbi = useArbi()\n const enabled = (options?.enabled ?? true) && arbi.isLoggedIn\n const projects = useProjects({ enabled: enabled && projectExtIds.length > 0 })\n const results = useQueries({\n queries: projectExtIds.map((id) => ({\n queryKey: arbiQueryKeys.projectUsage(id, monthsBack),\n queryFn: () => arbi.projects.usage(id, monthsBack),\n enabled: enabled && !!id,\n })),\n })\n\n // Recompute only when a query's data actually changes (not on every parent\n // render — the dashboard re-renders often while a digest streams).\n const signature =\n results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join('|') +\n `#${projects.dataUpdatedAt}`\n\n return useMemo(() => {\n const dailyMap = new Map<string, AggregatedDailyUsage>()\n const modelMap = new Map<string, AggregatedModelGroupUsage>()\n let totalCredits = 0\n let anyData = false\n let anyMetered = false\n let totalTokens = 0\n let totalRequests = 0\n\n results.forEach((r, i) => {\n const d = r.data\n if (!d) return\n anyData = true\n const subscription = projects.data?.find(\n (p) => p.external_id === projectExtIds[i]\n )?.subscription\n if (isUsageMetered(d, subscription)) anyMetered = true\n totalCredits += d.total_spend ?? 0\n totalTokens += d.total_tokens ?? 0\n totalRequests += d.total_requests ?? 0\n\n for (const day of d.daily ?? []) {\n const cur = dailyMap.get(day.date) ?? {\n date: day.date,\n credits: 0,\n totalTokens: 0,\n apiRequests: 0,\n }\n cur.credits += day.spend ?? 0\n cur.totalTokens += day.total_tokens ?? 0\n cur.apiRequests += day.api_requests ?? 0\n dailyMap.set(day.date, cur)\n }\n\n for (const [model, mg] of Object.entries(d.model_groups ?? {})) {\n const cur = modelMap.get(model) ?? {\n model,\n credits: 0,\n totalTokens: 0,\n promptTokens: 0,\n completionTokens: 0,\n successfulRequests: 0,\n }\n cur.credits += mg.spend ?? 0\n cur.totalTokens += mg.total_tokens ?? 0\n cur.promptTokens += mg.prompt_tokens ?? 0\n cur.completionTokens += mg.completion_tokens ?? 0\n cur.successfulRequests += mg.successful_requests ?? 0\n modelMap.set(model, cur)\n }\n })\n\n return {\n totalCredits,\n totalTokens,\n totalRequests,\n daily: [...dailyMap.values()].sort((a, b) => a.date.localeCompare(b.date)),\n modelGroups: [...modelMap.values()].sort(\n (a, b) => b.credits - a.credits || b.totalTokens - a.totalTokens\n ),\n metered: !anyData || anyMetered,\n isLoading: results.some((r) => r.isLoading),\n isError: results.some((r) => r.isError),\n }\n }, [signature])\n}\n\n/** List the Stripe invoices for a project's subscription. */\nexport function useProjectInvoices(\n projectExtId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projectInvoices(projectExtId ?? ''),\n queryFn: () => arbi.projects.invoices(projectExtId as string),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n}\n\n/** Today's deployment-wide credit use for the current user (`credits_used`, in credits). */\nexport function useUserUsageToday(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.userUsageToday(),\n queryFn: () => arbi.user.usageToday(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent,
|
|
1
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea } from './chunk-N5SVBDLC.js';
|
|
2
|
+
import { cn } from './chunk-SN5YV6FF.js';
|
|
2
3
|
import { Toaster as Toaster$1, toast } from 'sonner';
|
|
3
4
|
export { toast } from 'sonner';
|
|
4
5
|
import { create } from 'zustand';
|
|
@@ -268,5 +269,5 @@ function Toaster({ toastOptions, ...props }) {
|
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
export { DEFAULT_NOTIFY_TONE, NotificationBell, Toaster, formatRelativeTime, notify, seedNotifications, selectUnread, useNotify };
|
|
271
|
-
//# sourceMappingURL=chunk-
|
|
272
|
-
//# sourceMappingURL=chunk-
|
|
272
|
+
//# sourceMappingURL=chunk-FSMIN5VX.js.map
|
|
273
|
+
//# sourceMappingURL=chunk-FSMIN5VX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/notifications/notify-store.ts","../src/lib/format-relative-time.ts","../src/notifications/NotificationBell.tsx","../src/notifications/Toaster.tsx"],"names":["jsx","Sonner"],"mappings":"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","file":"chunk-FSMIN5VX.js","sourcesContent":["/**\n * App notification store — the one shared toast + notification-centre. A single\n * `notify.*` call pops a transient toast (rendered by <Toaster/>, on sonner) and,\n * unless `{ record: false }`, records a persistent entry for the topbar bell.\n *\n * notify.success('Saved') // toast + centre entry\n * notify.error('Upload failed', { record: false }) // toast only\n *\n * sonner owns the transient toast lifecycle (stacking, timing, dismissal); this\n * store owns only the persistent centre history (what the <NotificationBell/>\n * shows). Brand-neutral: no seed data (inject via `seedNotifications`), no app\n * imports. For full sonner power (custom content, `toast.dismiss`, …) the raw\n * `toast` is re-exported.\n */\nimport { type ReactNode } from 'react'\n// This module IS the sanctioned toast engine home — the app-level rule that\n// steers callers to sendNotification()/notify() doesn't apply here.\n// eslint-disable-next-line no-restricted-imports\nimport { toast } from 'sonner'\nimport { create } from 'zustand'\n\nexport { toast }\n\nexport type NotifyVariant = 'success' | 'error' | 'info' | 'warning'\n\nexport interface AppNotification {\n id: string\n title: string\n description?: string\n variant: NotifyVariant\n /** Epoch ms the entry was recorded. */\n ts: number\n read: boolean\n /** Optional in-app link the entry deep-links to (passed to the bell's onNavigate). */\n href?: string\n /** Optional click action — wins over `href` when both are present. Session\n * history only; entries are never serialized, so a closure is safe here. */\n onSelect?: () => void\n /** Routine session activity (\"Opening workspace…\", \"Saved\") — kept for the\n * log but not something that demands attention: excluded from the unread\n * badge and from the bell's default list (shown under \"All activity\"). */\n ambient?: boolean\n /** Where the entry comes from. Session entries (`record`) have none; a\n * backend bridge stamps its own (e.g. 'server') so {@link syncSource} can\n * replace exactly its slice on every refetch without touching the rest. */\n source?: string\n}\n\nexport interface NotifyOptions {\n description?: string\n /** Also record a persistent notification-centre entry (default true). */\n record?: boolean\n href?: string\n duration?: number\n /** A toast action button (sonner). */\n action?: { label: ReactNode; onClick: () => void }\n /** Override the toast glyph (sonner). */\n icon?: ReactNode\n /** Record as routine session activity (see {@link AppNotification.ambient}). */\n ambient?: boolean\n}\n\ninterface NotifyState {\n notifications: AppNotification[]\n markRead: (id: string) => void\n markAllRead: () => void\n removeNotification: (id: string) => void\n clearNotifications: () => void\n /** Replace the centre's history (e.g. seed a demo/initial set). */\n seed: (items: AppNotification[]) => void\n /** Record a centre entry (used by `notify.*`; sonner renders the toast). */\n record: (note: AppNotification) => void\n /** Reconcile one source's slice with fresh truth (e.g. a backend list on\n * every refetch): entries stamped with `source` are replaced wholesale —\n * including their read state, which the source owns — while entries from\n * other sources (session activity) stay untouched. Newest first. */\n syncSource: (source: string, items: AppNotification[]) => void\n}\n\nlet seq = 0\nconst uid = () => `n${Date.now().toString(36)}${(seq++).toString(36)}`\n\nexport const useNotify = create<NotifyState>((set) => ({\n notifications: [],\n markRead: (id) =>\n set((s) => ({\n notifications: s.notifications.map((n) => (n.id === id ? { ...n, read: true } : n)),\n })),\n markAllRead: () =>\n set((s) => ({ notifications: s.notifications.map((n) => ({ ...n, read: true })) })),\n removeNotification: (id) =>\n set((s) => ({ notifications: s.notifications.filter((n) => n.id !== id) })),\n clearNotifications: () => set({ notifications: [] }),\n seed: (items) => set({ notifications: items }),\n record: (note) => set((s) => ({ notifications: [note, ...s.notifications].slice(0, 50) })),\n syncSource: (source, items) =>\n set((s) => ({\n notifications: [\n ...items.map((n) => ({ ...n, source })),\n ...s.notifications.filter((n) => n.source !== source),\n ]\n .sort((a, b) => b.ts - a.ts)\n .slice(0, 100),\n })),\n}))\n\n/** Ergonomic helper — `notify.success('Saved')` — toast (sonner) + optional centre entry. */\nfunction make(variant: NotifyVariant) {\n return (title: string, opts: NotifyOptions = {}): string => {\n toast[variant](title, {\n description: opts.description,\n duration: opts.duration,\n action: opts.action,\n icon: opts.icon,\n })\n const id = uid()\n if (opts.record !== false) {\n useNotify.getState().record({\n id,\n title,\n description: opts.description,\n variant,\n ts: Date.now(),\n read: false,\n href: opts.href,\n ambient: opts.ambient,\n })\n }\n return id\n }\n}\nexport const notify = {\n success: make('success'),\n error: make('error'),\n info: make('info'),\n warning: make('warning'),\n}\n\n/** Replace the notification centre's history — inject a seed/initial set. */\nexport function seedNotifications(items: AppNotification[]): void {\n useNotify.getState().seed(items)\n}\n\n/** Unread count selector for the topbar bell — ambient session activity never\n * demands attention, so it never counts. */\nexport const selectUnread = (s: NotifyState): number =>\n s.notifications.filter((n) => !n.read && !n.ambient).length\n\n/** Default glyph colour per variant (raw palette, override via `toneClassNames`). */\nexport const DEFAULT_NOTIFY_TONE: Record<NotifyVariant, string> = {\n success: 'text-green-600',\n error: 'text-destructive',\n warning: 'text-amber-500',\n info: 'text-blue-500',\n}\n","/** Relative-time formatting shared by the notification bell and the DM kit (no type imports, so the\n * SDK-free `/shell` entry can use it). */\n\nconst RELATIVE = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' })\nconst DIVISIONS: Array<{ amount: number; unit: Intl.RelativeTimeFormatUnit }> = [\n { amount: 60, unit: 'seconds' },\n { amount: 60, unit: 'minutes' },\n { amount: 24, unit: 'hours' },\n { amount: 7, unit: 'days' },\n { amount: 4.34524, unit: 'weeks' },\n { amount: 12, unit: 'months' },\n { amount: Number.POSITIVE_INFINITY, unit: 'years' },\n]\n\n/** Compact relative time, e.g. \"2 hours ago\", \"just now\". */\nexport function formatRelativeTime(iso: string): string {\n const then = Date.parse(iso)\n if (Number.isNaN(then)) return ''\n let duration = (then - Date.now()) / 1000\n if (Math.abs(duration) < 45) return 'just now'\n for (const division of DIVISIONS) {\n if (Math.abs(duration) < division.amount) {\n return RELATIVE.format(Math.round(duration), division.unit)\n }\n duration /= division.amount\n }\n return ''\n}\n","/**\n * NotificationBell — the topbar notification centre: a bell with an unread badge\n * that opens a dropdown of recorded entries (newest first) with an unread dot,\n * relative time and optional deep-link. \"Mark all read\" clears the badge. Backed\n * by the shared {@link useNotify} store (the same one the <Toaster/> renders).\n *\n * Firm-agnostic: navigation is a callback (`onNavigate`), styling tracks semantic\n * tokens, and per-variant glyph colours are overridable via `toneClassNames`.\n */\nimport type { ReactElement } from 'react'\nimport {\n Bell,\n BellOff,\n CheckCheck,\n CheckCircle2,\n AlertTriangle,\n XCircle,\n Info,\n X,\n} from 'lucide-react'\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from '../ui/dropdown-menu'\nimport { ScrollArea } from '../ui/scroll-area'\nimport { cn } from '../lib/utils'\nimport { formatRelativeTime } from '../lib/format-relative-time'\nimport { useNotify, selectUnread, DEFAULT_NOTIFY_TONE, type NotifyVariant } from './notify-store'\n\nconst GLYPH: Record<NotifyVariant, typeof Info> = {\n success: CheckCircle2,\n error: XCircle,\n warning: AlertTriangle,\n info: Info,\n}\n\n/** What a custom bell trigger needs to render itself. */\nexport interface NotificationBellTriggerState {\n /** Unread count (0 when none). */\n unread: number\n /** Accessible name, including the count: \"Notifications, 2 unread\". */\n ariaLabel: string\n testId: string\n}\n\nexport interface NotificationBellProps {\n /**\n * Replaces the default icon button with the host's own trigger (for example a labelled sidebar\n * row). It must forward its ref and rest props: it is mounted as the dropdown trigger.\n */\n renderTrigger?: (state: NotificationBellTriggerState) => ReactElement\n /** Called with an entry's `href` when it's clicked (e.g. router navigate). */\n onNavigate?: (href: string) => void\n /** Called after an entry is locally marked read — the hook for a backend\n * bridge to propagate read state upstream (filter by the ids it owns). */\n onMarkRead?: (id: string) => void\n /** Called after \"Mark all read\" — same upstream-propagation hook. */\n onMarkAllRead?: () => void\n /** Toast muting — the bell is where notification behaviour is controlled, so\n * the mute switch lives in its header. Omit `onToggleMute` to hide it. */\n muted?: boolean\n onToggleMute?: () => void\n /** Override per-variant glyph colours (e.g. brand emerald for success). */\n toneClassNames?: Partial<Record<NotifyVariant, string>>\n emptyText?: string\n /** Footer link to the app's full notification surface. Omit to hide. */\n onViewAll?: () => void\n viewAllLabel?: string\n testId?: string\n /** Where the panel opens relative to the bell (a sidebar-footer bell opens upward). */\n side?: 'top' | 'right' | 'bottom' | 'left'\n align?: 'start' | 'center' | 'end'\n}\n\nexport function NotificationBell({\n renderTrigger,\n onNavigate,\n onMarkRead,\n onMarkAllRead,\n muted = false,\n onToggleMute,\n toneClassNames,\n emptyText = \"You're all caught up.\",\n onViewAll,\n viewAllLabel = 'View all',\n testId = 'notifications',\n side = 'bottom',\n align = 'end',\n}: NotificationBellProps) {\n const notifications = useNotify((s) => s.notifications)\n const unread = useNotify(selectUnread)\n const markAllRead = useNotify((s) => s.markAllRead)\n const markRead = useNotify((s) => s.markRead)\n const tone = (v: NotifyVariant) => toneClassNames?.[v] ?? DEFAULT_NOTIFY_TONE[v]\n\n // Ambient entries (routine session activity — \"Opening workspace…\") are kept\n // for the log but never surfaced in the bell panel: they never badge and are\n // always filtered out here.\n const visible = notifications.filter((n) => !n.ambient)\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n {renderTrigger ? (\n renderTrigger({\n unread,\n ariaLabel: `Notifications${unread ? `, ${unread} unread` : ''}`,\n testId,\n })\n ) : (\n <button\n className=\"relative flex size-9 pointer-coarse:size-11 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\"\n data-testid={testId}\n aria-label={`Notifications${unread ? `, ${unread} unread` : ''}`}\n title=\"Notifications\"\n >\n <Bell className=\"size-5\" />\n {unread > 0 && (\n <span\n className=\"absolute -right-0.5 -top-0.5 flex min-w-4 items-center justify-center rounded-full bg-primary px-1 text-xs font-semibold leading-4 text-primary-foreground\"\n data-testid={`${testId}-badge`}\n >\n {unread > 9 ? '9+' : unread}\n </span>\n )}\n </button>\n )}\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align={align}\n side={side}\n sideOffset={8}\n collisionPadding={12}\n className=\"w-[360px] rounded-lg border-border/60 p-0 shadow-lg\"\n data-testid={`${testId}-panel`}\n data-topbar-popover=\"\"\n >\n <div className=\"flex items-center justify-between gap-3 border-b border-border px-3.5 py-2.5 pointer-coarse:py-0\">\n <p className=\"text-sm font-semibold text-foreground\">Notifications</p>\n <div className=\"flex items-center gap-3 pointer-coarse:gap-1\">\n {unread > 0 && (\n <button\n onClick={() => {\n markAllRead()\n onMarkAllRead?.()\n }}\n className=\"flex items-center gap-1 text-xs font-medium text-primary transition-colors hover:opacity-80 pointer-coarse:min-h-11 pointer-coarse:px-2\"\n data-testid={`${testId}-mark-all`}\n >\n <CheckCheck className=\"size-3.5\" /> Mark all read\n </button>\n )}\n {onToggleMute && (\n <button\n onClick={onToggleMute}\n aria-pressed={muted}\n title={muted ? 'Unmute notifications' : 'Mute notifications'}\n aria-label={muted ? 'Unmute notifications' : 'Mute notifications'}\n className={cn(\n 'flex size-6 items-center justify-center rounded-md transition-colors hover:bg-accent pointer-coarse:size-11',\n muted ? 'text-foreground' : 'text-muted-foreground hover:text-foreground'\n )}\n data-testid={`${testId}-mute`}\n >\n <BellOff className=\"size-3.5\" />\n </button>\n )}\n {/* Explicit close — the dropdown otherwise only dismisses via\n tap-outside/Escape, which isn't discoverable on touch and (at\n mobile width, see blocks.css) the panel covers most\n of the screen so there's nothing to tap outside of. Radix\n closes a DropdownMenu on any item select by default, so a\n plain item with no other effect doubles as a close button. */}\n <DropdownMenuItem\n className=\"flex size-6 items-center justify-center rounded-md p-0 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:bg-accent pointer-coarse:size-11\"\n aria-label=\"Close notifications\"\n data-testid={`${testId}-close`}\n >\n <X className=\"size-3.5\" />\n </DropdownMenuItem>\n </div>\n </div>\n {muted && (\n <p\n className=\"border-b border-border/60 bg-amber-500/10 px-3.5 py-1.5 text-xs text-muted-foreground\"\n data-testid={`${testId}-muted-note`}\n >\n Toasts are muted — everything still lands here.\n </p>\n )}\n\n {visible.length === 0 ? (\n <div className=\"px-3.5 py-10 text-center text-sm text-muted-foreground\">{emptyText}</div>\n ) : (\n <ScrollArea className=\"max-h-[380px]\">\n <ul data-testid={`${testId}-list`}>\n {visible.map((n) => {\n const Glyph = GLYPH[n.variant]\n return (\n <li key={n.id}>\n <button\n onClick={() => {\n markRead(n.id)\n if (!n.read) onMarkRead?.(n.id)\n // The specific action wins over the generic deep link.\n if (n.onSelect) n.onSelect()\n else if (n.href) onNavigate?.(n.href)\n }}\n className={cn(\n 'flex w-full items-start gap-3 border-b border-border/60 px-3.5 py-3 text-left transition-colors hover:bg-accent',\n !n.read && 'bg-accent/40'\n )}\n data-testid={`${testId}-item`}\n >\n <Glyph className={cn('mt-0.5 size-4 shrink-0', tone(n.variant))} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium leading-snug text-foreground\">\n {n.title}\n </p>\n {n.description && (\n <p className=\"mt-0.5 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {n.description}\n </p>\n )}\n <p className=\"mt-1 text-xs text-muted-foreground/80\">\n {formatRelativeTime(new Date(n.ts).toISOString())}\n </p>\n </div>\n {!n.read && (\n <span className=\"mt-1.5 size-2 shrink-0 rounded-full bg-primary\" />\n )}\n </button>\n </li>\n )\n })}\n </ul>\n </ScrollArea>\n )}\n {onViewAll && (\n // A real menu item, not a bare button: selecting it must CLOSE the\n // dropdown on its way to the full surface.\n <DropdownMenuItem\n onClick={onViewAll}\n className=\"justify-center rounded-none border-t border-border px-3.5 py-2.5 text-xs font-medium text-primary focus:text-primary pointer-coarse:min-h-11\"\n data-testid={`${testId}-view-all`}\n >\n {viewAllLabel}\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n","/**\n * Toaster — the one shared toast surface, built on sonner (the mature engine:\n * stacking, swipe-to-dismiss, a11y, timing). Mount once near the app root; any\n * code then calls `notify.*(...)` (or the re-exported `toast`) from anywhere.\n *\n * Firm-agnostic: every sonner `ToasterProps` passes through, so a consumer sets\n * its own `position` / `theme` / `toastOptions`. The defaults give a neutral\n * shadcn-token card that both apps can override.\n */\nimport { Toaster as Sonner, type ToasterProps } from 'sonner'\n\nexport type { ToasterProps }\n\nconst DEFAULT_TOAST_OPTIONS: ToasterProps['toastOptions'] = {\n classNames: {\n toast:\n 'group toast group-[.toaster]:bg-card group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:border-border group-[.toaster]:shadow-lg group-[.toaster]:rounded-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n },\n}\n\nexport function Toaster({ toastOptions, ...props }: ToasterProps) {\n return (\n <Sonner\n className=\"toaster group\"\n toastOptions={toastOptions ?? DEFAULT_TOAST_OPTIONS}\n {...props}\n />\n )\n}\n"]}
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Arbi } from '@arbidocs/sdk/browser';
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
3
2
|
import { jsx } from 'react/jsx-runtime';
|
|
4
3
|
|
|
5
|
-
// src/
|
|
6
|
-
var ArbiContext = createContext(null);
|
|
7
|
-
function ArbiProvider({ children, ...options }) {
|
|
8
|
-
const arbi = useMemo(
|
|
9
|
-
() => new Arbi(options),
|
|
10
|
-
// Stable on url + deploymentDomain — re-creating the instance on every render would be wrong
|
|
11
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
-
[options.url, options.deploymentDomain, options.credentials]
|
|
13
|
-
);
|
|
14
|
-
return /* @__PURE__ */ jsx(ArbiContext.Provider, { value: arbi, children });
|
|
15
|
-
}
|
|
16
|
-
function useArbi() {
|
|
17
|
-
const arbi = useContext(ArbiContext);
|
|
18
|
-
if (!arbi) {
|
|
19
|
-
throw new Error("useArbi() must be used within an <ArbiProvider>");
|
|
20
|
-
}
|
|
21
|
-
return arbi;
|
|
22
|
-
}
|
|
4
|
+
// src/viewers/AudioViewer.tsx
|
|
23
5
|
function AudioViewer({ blob, title }) {
|
|
24
6
|
const [objectUrl, setObjectUrl] = useState("");
|
|
25
7
|
useEffect(() => {
|
|
@@ -88,6 +70,6 @@ function VideoViewer({ blob, title }) {
|
|
|
88
70
|
);
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
export {
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
73
|
+
export { AudioViewer, ImageViewer, VideoViewer };
|
|
74
|
+
//# sourceMappingURL=chunk-HDCRPPBW.js.map
|
|
75
|
+
//# sourceMappingURL=chunk-HDCRPPBW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/viewers/AudioViewer.tsx","../src/viewers/ImageViewer.tsx","../src/viewers/VideoViewer.tsx"],"names":["useState","useEffect","jsx"],"mappings":";;;;AAQO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,KAAA,EAAM,EAAqB;AAC7D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAiB,EAAE,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,IAAA,YAAA,CAAa,GAAG,CAAA;AAChB,IAAA,OAAO,MAAM,GAAA,CAAI,eAAA,CAAgB,GAAG,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,gEAAA;AAAA,MACV,aAAA,EAAY,cAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA,CAAC,WAAM,GAAA,EAAK,SAAA,EAAW,UAAQ,IAAA,EAAC,KAAA,EAAc,WAAU,iBAAA,EAAkB;AAAA;AAAA,GAC5E;AAEJ;ACnBO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,GAAA,EAAI,EAAqB;AAC3D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAiB,EAAE,CAAA;AAErD,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,IAAA,YAAA,CAAa,GAAG,CAAA;AAChB,IAAA,OAAO,MAAM,GAAA,CAAI,eAAA,CAAgB,GAAG,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,uBACEC,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,8EAAA;AAAA,MACV,aAAA,EAAY,cAAA;AAAA,MAEZ,QAAA,kBAAAA,GAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,GAAA;AAAA,UACA,SAAA,EAAU,wDAAA;AAAA,UACV,aAAA,EAAY;AAAA;AAAA;AACd;AAAA,GACF;AAEJ;ACxBO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,KAAA,EAAM,EAAqB;AAC7D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIF,SAAiB,EAAE,CAAA;AAErD,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,IAAA,YAAA,CAAa,GAAG,CAAA;AAChB,IAAA,OAAO,MAAM,GAAA,CAAI,eAAA,CAAgB,GAAG,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,uBACEC,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,8EAAA;AAAA,MACV,aAAA,EAAY,cAAA;AAAA,MAEZ,QAAA,kBAAAA,GAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,SAAA;AAAA,UACL,QAAA,EAAQ,IAAA;AAAA,UACR,KAAA;AAAA,UACA,SAAA,EAAU;AAAA;AAAA;AACZ;AAAA,GACF;AAEJ","file":"chunk-HDCRPPBW.js","sourcesContent":["import { useEffect, useState } from 'react'\n\nexport interface AudioViewerProps {\n blob: Blob\n title: string\n}\n\n/** Renders an audio blob with the browser's native transport controls. */\nexport function AudioViewer({ blob, title }: AudioViewerProps) {\n const [objectUrl, setObjectUrl] = useState<string>('')\n\n useEffect(() => {\n const url = URL.createObjectURL(blob)\n setObjectUrl(url)\n return () => URL.revokeObjectURL(url)\n }, [blob])\n\n if (!objectUrl) return null\n\n return (\n <div\n className=\"h-full w-full flex items-center justify-center p-4 bg-muted/30\"\n data-testid=\"audio-viewer\"\n >\n <audio src={objectUrl} controls title={title} className=\"w-full max-w-lg\" />\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport interface ImageViewerProps {\n blob: Blob\n alt: string\n}\n\n/** Renders an image blob, scaled to fit its container. */\nexport function ImageViewer({ blob, alt }: ImageViewerProps) {\n const [objectUrl, setObjectUrl] = useState<string>('')\n\n useEffect(() => {\n const url = URL.createObjectURL(blob)\n setObjectUrl(url)\n return () => URL.revokeObjectURL(url)\n }, [blob])\n\n if (!objectUrl) return null\n\n return (\n <div\n className=\"h-full w-full overflow-auto flex items-center justify-center p-4 bg-muted/30\"\n data-testid=\"image-viewer\"\n >\n <img\n src={objectUrl}\n alt={alt}\n className=\"max-w-full max-h-full object-contain rounded shadow-sm\"\n data-testid=\"image-viewer-img\"\n />\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport interface VideoViewerProps {\n blob: Blob\n title: string\n}\n\n/** Renders a video blob with the browser's native transport controls. */\nexport function VideoViewer({ blob, title }: VideoViewerProps) {\n const [objectUrl, setObjectUrl] = useState<string>('')\n\n useEffect(() => {\n const url = URL.createObjectURL(blob)\n setObjectUrl(url)\n return () => URL.revokeObjectURL(url)\n }, [blob])\n\n if (!objectUrl) return null\n\n return (\n <div\n className=\"h-full w-full overflow-auto flex items-center justify-center p-4 bg-muted/30\"\n data-testid=\"video-viewer\"\n >\n <video\n src={objectUrl}\n controls\n title={title}\n className=\"max-w-full max-h-full rounded shadow-sm\"\n />\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createContext, useMemo, useContext } from 'react';
|
|
2
|
+
import { Arbi } from '@arbidocs/sdk/browser';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/ArbiProvider.tsx
|
|
6
|
+
var ArbiContext = createContext(null);
|
|
7
|
+
function ArbiProvider({ children, ...options }) {
|
|
8
|
+
const arbi = useMemo(
|
|
9
|
+
() => new Arbi(options),
|
|
10
|
+
// Stable on url + deploymentDomain — re-creating the instance on every render would be wrong
|
|
11
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
+
[options.url, options.deploymentDomain, options.credentials]
|
|
13
|
+
);
|
|
14
|
+
return /* @__PURE__ */ jsx(ArbiContext.Provider, { value: arbi, children });
|
|
15
|
+
}
|
|
16
|
+
function useArbi() {
|
|
17
|
+
const arbi = useContext(ArbiContext);
|
|
18
|
+
if (!arbi) {
|
|
19
|
+
throw new Error("useArbi() must be used within an <ArbiProvider>");
|
|
20
|
+
}
|
|
21
|
+
return arbi;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { ArbiProvider, useArbi };
|
|
25
|
+
//# sourceMappingURL=chunk-J4MX2W4H.js.map
|
|
26
|
+
//# sourceMappingURL=chunk-J4MX2W4H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ArbiProvider.tsx","../src/useArbi.ts"],"names":[],"mappings":";;;;;AAYO,IAAM,WAAA,GAAc,cAA2B,IAAI,CAAA;AAMnD,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,GAAG,SAAQ,EAAsB;AACxE,EAAA,MAAM,IAAA,GAAO,OAAA;AAAA,IACX,MAAM,IAAI,IAAA,CAAK,OAAO,CAAA;AAAA;AAAA;AAAA,IAGtB,CAAC,OAAA,CAAQ,GAAA,EAAK,OAAA,CAAQ,gBAAA,EAAkB,QAAQ,WAAW;AAAA,GAC7D;AAEA,EAAA,2BAAQ,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,MAAO,QAAA,EAAS,CAAA;AACtD;ACnBO,SAAS,OAAA,GAAgB;AAC9B,EAAA,MAAM,IAAA,GAAO,WAAW,WAAW,CAAA;AACnC,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAM,IAAI,MAAM,iDAAiD,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,IAAA;AACT","file":"chunk-J4MX2W4H.js","sourcesContent":["/**\n * ArbiProvider — React context that holds an Arbi instance.\n *\n * Usage:\n * <ArbiProvider url=\"https://arbi.mycompany.com\">\n * <App />\n * </ArbiProvider>\n */\n\nimport { createContext, useMemo, type ReactNode } from 'react'\nimport { Arbi, type ArbiOptions } from '@arbidocs/sdk/browser'\n\nexport const ArbiContext = createContext<Arbi | null>(null)\n\nexport interface ArbiProviderProps extends ArbiOptions {\n children: ReactNode\n}\n\nexport function ArbiProvider({ children, ...options }: ArbiProviderProps) {\n const arbi = useMemo(\n () => new Arbi(options),\n // Stable on url + deploymentDomain — re-creating the instance on every render would be wrong\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [options.url, options.deploymentDomain, options.credentials]\n )\n\n return <ArbiContext.Provider value={arbi}>{children}</ArbiContext.Provider>\n}\n","/**\n * Hook to access the Arbi instance from the nearest ArbiProvider.\n */\n\nimport { useContext } from 'react'\nimport type { Arbi } from '@arbidocs/sdk/browser'\nimport { ArbiContext } from './ArbiProvider'\n\nexport function useArbi(): Arbi {\n const arbi = useContext(ArbiContext)\n if (!arbi) {\n throw new Error('useArbi() must be used within an <ArbiProvider>')\n }\n return arbi\n}\n"]}
|