@arbidocs/react 0.5.30 → 0.5.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifacts/index.cjs +5 -5
- package/dist/artifacts/index.js +2 -2
- package/dist/calls/livekit/index.cjs +41 -41
- package/dist/calls/livekit/index.js +2 -2
- package/dist/{chunk-NV5G5RR5.cjs → chunk-CWJAULV2.cjs} +420 -5
- package/dist/chunk-CWJAULV2.cjs.map +1 -0
- package/dist/{chunk-YMAZYYD5.cjs → chunk-FSPLYO52.cjs} +2264 -2264
- package/dist/chunk-FSPLYO52.cjs.map +1 -0
- package/dist/{chunk-2ERRXEOB.cjs → chunk-GAW2PLSL.cjs} +59 -4
- package/dist/chunk-GAW2PLSL.cjs.map +1 -0
- package/dist/{chunk-3ZLRZTKP.cjs → chunk-KHRCABUX.cjs} +5 -5
- package/dist/{chunk-3ZLRZTKP.cjs.map → chunk-KHRCABUX.cjs.map} +1 -1
- package/dist/{chunk-I4JYI6GY.js → chunk-KUGZXI7V.js} +2266 -2266
- package/dist/chunk-KUGZXI7V.js.map +1 -0
- package/dist/{chunk-VHGJG32Q.js → chunk-MJWUUDYT.js} +57 -5
- package/dist/chunk-MJWUUDYT.js.map +1 -0
- package/dist/{chunk-5X4RZ36M.js → chunk-R4YLLLCT.js} +3 -3
- package/dist/{chunk-5X4RZ36M.js.map → chunk-R4YLLLCT.js.map} +1 -1
- package/dist/{chunk-CIWI5UFT.js → chunk-VTNFF7P6.js} +406 -7
- package/dist/chunk-VTNFF7P6.js.map +1 -0
- package/dist/index.cjs +1337 -820
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +517 -98
- package/dist/index.d.ts +517 -98
- package/dist/index.js +616 -187
- package/dist/index.js.map +1 -1
- package/dist/ui/index.cjs +147 -147
- package/dist/ui/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-2ERRXEOB.cjs.map +0 -1
- package/dist/chunk-CIWI5UFT.js.map +0 -1
- package/dist/chunk-I4JYI6GY.js.map +0 -1
- package/dist/chunk-NV5G5RR5.cjs.map +0 -1
- package/dist/chunk-VHGJG32Q.js.map +0 -1
- package/dist/chunk-YMAZYYD5.cjs.map +0 -1
|
@@ -3,10 +3,280 @@ import { OWN_SESSION_SLOT } from './chunk-DPYBZDJB.js';
|
|
|
3
3
|
import { parseVersionRef } from './chunk-NNWMHMEC.js';
|
|
4
4
|
import { useArbiHost, useArbi } from './chunk-MB34NKBZ.js';
|
|
5
5
|
import { getUserEncryptionKeypair, sealedBoxDecrypt, sealedBoxEncrypt } from '@arbidocs/client';
|
|
6
|
-
import { useSyncExternalStore, useMemo, useRef, useEffect } from 'react';
|
|
6
|
+
import { useSyncExternalStore, useCallback, useMemo, useRef, useEffect } from 'react';
|
|
7
7
|
import { useQuery, useMutation, useQueryClient, useInfiniteQuery, useQueries } from '@tanstack/react-query';
|
|
8
8
|
import { ArbiApiError } from '@arbidocs/sdk/browser';
|
|
9
9
|
|
|
10
|
+
// src/session/layout.ts
|
|
11
|
+
var PANEL_MODES = ["main", "docked", "overlay", "popout"];
|
|
12
|
+
var defaultPinned = () => typeof window === "undefined" || window.innerWidth >= 640;
|
|
13
|
+
function defaultLayoutState() {
|
|
14
|
+
return {
|
|
15
|
+
shell: {
|
|
16
|
+
page: "home",
|
|
17
|
+
sidebar: { pinned: defaultPinned(), hovering: false, drawerOpen: false },
|
|
18
|
+
panels: { main: null, docked: null, overlay: null, popout: null, modes: {}, sizes: {} },
|
|
19
|
+
focusedArea: "main"
|
|
20
|
+
},
|
|
21
|
+
tabs: { dm: [], activeDm: null, dmMessageId: null, projects: [], activeProject: null },
|
|
22
|
+
views: { tabs: {}, filters: {}, values: {}, transient: {} },
|
|
23
|
+
grid: { states: {}, rowHeights: {}, labelWidths: {}, savedViews: {} }
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27
|
+
var recordOf = (value, keep) => isRecord(value) ? Object.fromEntries(Object.entries(value).filter(([, v]) => keep(v))) : {};
|
|
28
|
+
var isString = (v) => typeof v === "string";
|
|
29
|
+
var isNumber = (v) => typeof v === "number" && Number.isFinite(v);
|
|
30
|
+
var isAny = (v) => v !== void 0;
|
|
31
|
+
var isMode = (v) => PANEL_MODES.includes(v);
|
|
32
|
+
var isSize = (v) => isRecord(v) && isNumber(v.width) && isNumber(v.height);
|
|
33
|
+
var isList = (v) => Array.isArray(v);
|
|
34
|
+
var stringOrNull = (v) => isString(v) ? v : null;
|
|
35
|
+
function parseSavedLayout(saved) {
|
|
36
|
+
if (!isRecord(saved) || saved.version !== 1) return null;
|
|
37
|
+
const shell = isRecord(saved.shell) ? saved.shell : {};
|
|
38
|
+
const panels = isRecord(shell.panels) ? shell.panels : {};
|
|
39
|
+
const views = isRecord(saved.views) ? saved.views : {};
|
|
40
|
+
const grid = isRecord(saved.grid) ? saved.grid : {};
|
|
41
|
+
const defaults = defaultLayoutState();
|
|
42
|
+
return {
|
|
43
|
+
version: 1,
|
|
44
|
+
migrated: isList(saved.migrated) ? saved.migrated.filter(isString) : [],
|
|
45
|
+
shell: {
|
|
46
|
+
page: isString(shell.page) ? shell.page : defaults.shell.page,
|
|
47
|
+
sidebarPinned: typeof shell.sidebarPinned === "boolean" ? shell.sidebarPinned : defaults.shell.sidebar.pinned,
|
|
48
|
+
panels: {
|
|
49
|
+
main: stringOrNull(panels.main),
|
|
50
|
+
docked: stringOrNull(panels.docked),
|
|
51
|
+
modes: recordOf(panels.modes, isMode),
|
|
52
|
+
sizes: recordOf(panels.sizes, isSize)
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
views: {
|
|
56
|
+
tabs: recordOf(views.tabs, isString),
|
|
57
|
+
filters: recordOf(views.filters, isAny),
|
|
58
|
+
values: recordOf(views.values, isAny)
|
|
59
|
+
},
|
|
60
|
+
grid: {
|
|
61
|
+
states: recordOf(grid.states, isRecord),
|
|
62
|
+
rowHeights: recordOf(grid.rowHeights, isNumber),
|
|
63
|
+
labelWidths: recordOf(grid.labelWidths, isNumber),
|
|
64
|
+
savedViews: recordOf(grid.savedViews, isList)
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function savedLayoutOf(layout, migrated) {
|
|
69
|
+
const { shell, views, grid } = layout;
|
|
70
|
+
return {
|
|
71
|
+
version: 1,
|
|
72
|
+
migrated,
|
|
73
|
+
shell: {
|
|
74
|
+
page: shell.page,
|
|
75
|
+
sidebarPinned: shell.sidebar.pinned,
|
|
76
|
+
// A panel over the page or in its own window does not come back after a reload.
|
|
77
|
+
panels: {
|
|
78
|
+
main: shell.panels.main,
|
|
79
|
+
docked: shell.panels.docked,
|
|
80
|
+
modes: shell.panels.modes,
|
|
81
|
+
sizes: shell.panels.sizes
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
views: { tabs: views.tabs, filters: views.filters, values: views.values },
|
|
85
|
+
grid
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function restoreLayout(current, saved) {
|
|
89
|
+
return {
|
|
90
|
+
...current,
|
|
91
|
+
shell: {
|
|
92
|
+
...current.shell,
|
|
93
|
+
page: saved.shell.page,
|
|
94
|
+
sidebar: { ...current.shell.sidebar, pinned: saved.shell.sidebarPinned },
|
|
95
|
+
panels: { ...current.shell.panels, ...saved.shell.panels }
|
|
96
|
+
},
|
|
97
|
+
views: { ...saved.views, transient: current.views.transient },
|
|
98
|
+
grid: saved.grid
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function openPanelIn(panels, panelId, mode) {
|
|
102
|
+
const leave = (slot) => slot === panelId ? null : slot;
|
|
103
|
+
const next = {
|
|
104
|
+
...panels,
|
|
105
|
+
main: leave(panels.main),
|
|
106
|
+
docked: leave(panels.docked),
|
|
107
|
+
overlay: leave(panels.overlay),
|
|
108
|
+
popout: leave(panels.popout),
|
|
109
|
+
modes: { ...panels.modes, [panelId]: mode }
|
|
110
|
+
};
|
|
111
|
+
if (mode === "docked") return { ...next, docked: panelId, overlay: null };
|
|
112
|
+
if (mode === "overlay") return { ...next, overlay: panelId, docked: null };
|
|
113
|
+
return { ...next, [mode]: panelId };
|
|
114
|
+
}
|
|
115
|
+
function closePanelIn(panels, panelId) {
|
|
116
|
+
const leave = (slot) => slot === panelId ? null : slot;
|
|
117
|
+
return {
|
|
118
|
+
...panels,
|
|
119
|
+
main: leave(panels.main),
|
|
120
|
+
docked: leave(panels.docked),
|
|
121
|
+
overlay: leave(panels.overlay),
|
|
122
|
+
popout: leave(panels.popout)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function panelPlace(panels, panelId) {
|
|
126
|
+
return PANEL_MODES.find((mode) => panels[mode] === panelId) ?? null;
|
|
127
|
+
}
|
|
128
|
+
var isPanelOpen = (state, panelId) => panelPlace(state.shell.panels, panelId) !== null;
|
|
129
|
+
var dmTabId = (tab) => tab.recipientId ?? "new";
|
|
130
|
+
function createArbiLayoutStore({ persist } = {}) {
|
|
131
|
+
let layout = defaultLayoutState();
|
|
132
|
+
let migrated = [];
|
|
133
|
+
let isHydrated = !persist;
|
|
134
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
135
|
+
const save = () => {
|
|
136
|
+
if (persist && isHydrated) persist.save(savedLayoutOf(layout, migrated));
|
|
137
|
+
};
|
|
138
|
+
const update = (next) => {
|
|
139
|
+
if (next === layout) return;
|
|
140
|
+
const persisted = next.views.tabs !== layout.views.tabs || next.views.filters !== layout.views.filters || next.views.values !== layout.views.values || next.grid !== layout.grid || next.shell.page !== layout.shell.page || next.shell.sidebar.pinned !== layout.shell.sidebar.pinned || next.shell.panels !== layout.shell.panels;
|
|
141
|
+
layout = next;
|
|
142
|
+
listeners.forEach((listener) => listener());
|
|
143
|
+
if (persisted) save();
|
|
144
|
+
};
|
|
145
|
+
const shell = (change) => update({ ...layout, shell: { ...layout.shell, ...change } });
|
|
146
|
+
const tabs = (change) => update({ ...layout, tabs: { ...layout.tabs, ...change } });
|
|
147
|
+
const views = (change) => update({ ...layout, views: { ...layout.views, ...change } });
|
|
148
|
+
const grid = (change) => update({ ...layout, grid: { ...layout.grid, ...change } });
|
|
149
|
+
const hydration = persist ? persist.load().then(
|
|
150
|
+
(saved) => {
|
|
151
|
+
const parsed = parseSavedLayout(saved);
|
|
152
|
+
if (parsed) {
|
|
153
|
+
migrated = parsed.migrated;
|
|
154
|
+
layout = restoreLayout(layout, parsed);
|
|
155
|
+
}
|
|
156
|
+
isHydrated = true;
|
|
157
|
+
listeners.forEach((listener) => listener());
|
|
158
|
+
},
|
|
159
|
+
() => {
|
|
160
|
+
isHydrated = true;
|
|
161
|
+
listeners.forEach((listener) => listener());
|
|
162
|
+
}
|
|
163
|
+
) : Promise.resolve();
|
|
164
|
+
return {
|
|
165
|
+
getLayout: () => layout,
|
|
166
|
+
reset: () => update(defaultLayoutState()),
|
|
167
|
+
subscribe: (listener) => {
|
|
168
|
+
listeners.add(listener);
|
|
169
|
+
return () => listeners.delete(listener);
|
|
170
|
+
},
|
|
171
|
+
hydrated: () => hydration,
|
|
172
|
+
isHydrated: () => isHydrated,
|
|
173
|
+
setPage: (page) => {
|
|
174
|
+
if (layout.shell.page !== page || layout.shell.focusedArea !== "main")
|
|
175
|
+
shell({ page, focusedArea: "main" });
|
|
176
|
+
},
|
|
177
|
+
setSidebar: (change) => {
|
|
178
|
+
const sidebar = { ...layout.shell.sidebar, ...change };
|
|
179
|
+
const current = layout.shell.sidebar;
|
|
180
|
+
if (sidebar.pinned !== current.pinned || sidebar.hovering !== current.hovering || sidebar.drawerOpen !== current.drawerOpen)
|
|
181
|
+
shell({ sidebar });
|
|
182
|
+
},
|
|
183
|
+
openPanel: (panelId, mode) => shell({ panels: openPanelIn(layout.shell.panels, panelId, mode), focusedArea: panelId }),
|
|
184
|
+
closePanel: (panelId) => shell({ panels: closePanelIn(layout.shell.panels, panelId), focusedArea: "main" }),
|
|
185
|
+
setPanelMode: (panelId, mode) => {
|
|
186
|
+
const panels = layout.shell.panels;
|
|
187
|
+
if (panelPlace(panels, panelId) !== null)
|
|
188
|
+
shell({ panels: openPanelIn(panels, panelId, mode), focusedArea: panelId });
|
|
189
|
+
else if (panels.modes[panelId] !== mode)
|
|
190
|
+
shell({ panels: { ...panels, modes: { ...panels.modes, [panelId]: mode } } });
|
|
191
|
+
},
|
|
192
|
+
setPanelSize: (panelId, size) => {
|
|
193
|
+
const panels = layout.shell.panels;
|
|
194
|
+
shell({ panels: { ...panels, sizes: { ...panels.sizes, [panelId]: size } } });
|
|
195
|
+
},
|
|
196
|
+
setFocusedArea: (focusedArea) => {
|
|
197
|
+
if (layout.shell.focusedArea !== focusedArea) shell({ focusedArea });
|
|
198
|
+
},
|
|
199
|
+
openDmTab: (recipientId, messageId) => {
|
|
200
|
+
const id = recipientId ?? "new";
|
|
201
|
+
const dm = layout.tabs.dm.some((tab) => dmTabId(tab) === id) ? layout.tabs.dm : [...layout.tabs.dm, { recipientId }];
|
|
202
|
+
tabs({ dm, activeDm: id, ...messageId ? { dmMessageId: messageId } : {} });
|
|
203
|
+
},
|
|
204
|
+
closeDmTab: (tabId) => {
|
|
205
|
+
const dm = layout.tabs.dm.filter((tab) => dmTabId(tab) !== tabId);
|
|
206
|
+
if (dm.length === layout.tabs.dm.length) return;
|
|
207
|
+
if (dm.length === 0) return tabs({ dm, activeDm: null });
|
|
208
|
+
if (layout.tabs.activeDm !== tabId) return tabs({ dm });
|
|
209
|
+
const index = layout.tabs.dm.findIndex((tab) => dmTabId(tab) === tabId);
|
|
210
|
+
tabs({ dm, activeDm: dmTabId(dm[Math.min(index, dm.length - 1)]) });
|
|
211
|
+
},
|
|
212
|
+
selectDmTab: (activeDm) => {
|
|
213
|
+
if (layout.tabs.activeDm !== activeDm) tabs({ activeDm });
|
|
214
|
+
},
|
|
215
|
+
clearDmTabs: () => tabs({ dm: [], activeDm: null }),
|
|
216
|
+
setDmMessageId: (dmMessageId) => {
|
|
217
|
+
if (layout.tabs.dmMessageId !== dmMessageId) tabs({ dmMessageId });
|
|
218
|
+
},
|
|
219
|
+
openProjectTab: (projectId) => tabs({
|
|
220
|
+
projects: layout.tabs.projects.includes(projectId) ? layout.tabs.projects : [...layout.tabs.projects, projectId],
|
|
221
|
+
activeProject: projectId
|
|
222
|
+
}),
|
|
223
|
+
closeProjectTab: (projectId) => {
|
|
224
|
+
const projects = layout.tabs.projects.filter((id) => id !== projectId);
|
|
225
|
+
if (projects.length === layout.tabs.projects.length) return;
|
|
226
|
+
if (layout.tabs.activeProject !== projectId) return tabs({ projects });
|
|
227
|
+
const index = layout.tabs.projects.indexOf(projectId);
|
|
228
|
+
tabs({
|
|
229
|
+
projects,
|
|
230
|
+
activeProject: projects.length ? projects[Math.min(index, projects.length - 1)] : null
|
|
231
|
+
});
|
|
232
|
+
},
|
|
233
|
+
selectProjectTab: (activeProject) => {
|
|
234
|
+
if (layout.tabs.activeProject !== activeProject) tabs({ activeProject });
|
|
235
|
+
},
|
|
236
|
+
setPageTab: (page, tab) => {
|
|
237
|
+
if (layout.views.tabs[page] !== tab) views({ tabs: { ...layout.views.tabs, [page]: tab } });
|
|
238
|
+
},
|
|
239
|
+
setViewFilter: (key, value) => views({ filters: { ...layout.views.filters, [key]: value } }),
|
|
240
|
+
setViewValue: (key, value) => {
|
|
241
|
+
if (layout.views.values[key] !== value)
|
|
242
|
+
views({ values: { ...layout.views.values, [key]: value } });
|
|
243
|
+
},
|
|
244
|
+
setTransientView: (key, value) => {
|
|
245
|
+
if (layout.views.transient[key] === value) return;
|
|
246
|
+
const transient = { ...layout.views.transient };
|
|
247
|
+
if (value === void 0) delete transient[key];
|
|
248
|
+
else transient[key] = value;
|
|
249
|
+
views({ transient });
|
|
250
|
+
},
|
|
251
|
+
setGridState: (gridId, state) => grid({ states: { ...layout.grid.states, [gridId]: state } }),
|
|
252
|
+
clearGridState: (gridId) => {
|
|
253
|
+
if (!(gridId in layout.grid.states)) return;
|
|
254
|
+
const states = { ...layout.grid.states };
|
|
255
|
+
delete states[gridId];
|
|
256
|
+
grid({ states });
|
|
257
|
+
},
|
|
258
|
+
setGridRowHeight: (gridId, height) => grid({ rowHeights: { ...layout.grid.rowHeights, [gridId]: height } }),
|
|
259
|
+
setGridLabelWidth: (gridId, width) => grid({ labelWidths: { ...layout.grid.labelWidths, [gridId]: width } }),
|
|
260
|
+
setGridSavedViews: (gridId, saved) => grid({ savedViews: { ...layout.grid.savedViews, [gridId]: saved } }),
|
|
261
|
+
resetLayout: (variant) => {
|
|
262
|
+
const fresh = defaultLayoutState();
|
|
263
|
+
update({
|
|
264
|
+
shell: {
|
|
265
|
+
...fresh.shell,
|
|
266
|
+
panels: {
|
|
267
|
+
...fresh.shell.panels,
|
|
268
|
+
modes: layout.shell.panels.modes,
|
|
269
|
+
sizes: layout.shell.panels.sizes
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
tabs: fresh.tabs,
|
|
273
|
+
views: { ...layout.views, tabs: {}, transient: {} },
|
|
274
|
+
grid: variant === "logout" ? { ...layout.grid, states: {} } : layout.grid
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
10
280
|
// src/chat/run-state.ts
|
|
11
281
|
var MIN_QUEUED_MESSAGE_VISIBILITY_MS = 800;
|
|
12
282
|
var mapQueues = (queues, update) => Object.fromEntries(Object.entries(queues).map(([id, messages]) => [id, update(messages)]));
|
|
@@ -137,7 +407,8 @@ var EMPTY_SESSION_STATE = {
|
|
|
137
407
|
agentChatOwners: {},
|
|
138
408
|
newAgentChat: null,
|
|
139
409
|
newChatDocumentId: null,
|
|
140
|
-
messageTimers: {}
|
|
410
|
+
messageTimers: {},
|
|
411
|
+
...defaultLayoutState()
|
|
141
412
|
};
|
|
142
413
|
var selectViewingDocumentId = (state) => state.viewingDocument ? parseVersionRef(state.viewingDocument.id).docId : null;
|
|
143
414
|
var conversationKey = (state) => state.conversationId ?? "new";
|
|
@@ -152,17 +423,28 @@ function nextViewingDocument(current, input) {
|
|
|
152
423
|
passageId: input.passageId !== void 0 ? input.passageId : current?.passageId ?? null
|
|
153
424
|
};
|
|
154
425
|
}
|
|
426
|
+
function layoutActionsOf(layout) {
|
|
427
|
+
const actions = { ...layout };
|
|
428
|
+
delete actions.getLayout;
|
|
429
|
+
delete actions.subscribe;
|
|
430
|
+
delete actions.hydrated;
|
|
431
|
+
delete actions.isHydrated;
|
|
432
|
+
delete actions.reset;
|
|
433
|
+
return actions;
|
|
434
|
+
}
|
|
155
435
|
function withoutNew(record) {
|
|
156
436
|
const { new: _new, ...saved } = record;
|
|
157
437
|
return saved;
|
|
158
438
|
}
|
|
159
|
-
function createArbiSessionStore(initial = {}, { draftStorage } = {}) {
|
|
160
|
-
|
|
439
|
+
function createArbiSessionStore(initial = {}, { draftStorage, persist } = {}) {
|
|
440
|
+
const layout = createArbiLayoutStore({ persist });
|
|
441
|
+
let state = { ...EMPTY_SESSION_STATE, ...layout.getLayout(), ...initial };
|
|
161
442
|
const listeners = /* @__PURE__ */ new Set();
|
|
162
443
|
const update = (patch) => {
|
|
163
444
|
state = { ...state, ...patch };
|
|
164
445
|
listeners.forEach((listener) => listener());
|
|
165
446
|
};
|
|
447
|
+
layout.subscribe(() => update(layout.getLayout()));
|
|
166
448
|
let preEdit = { draft: "", cursor: null };
|
|
167
449
|
let draftsRestored = !draftStorage;
|
|
168
450
|
let draftsOwner = draftStorage?.owner() ?? null;
|
|
@@ -206,6 +488,9 @@ function createArbiSessionStore(initial = {}, { draftStorage } = {}) {
|
|
|
206
488
|
setDrafts(drafts);
|
|
207
489
|
};
|
|
208
490
|
return {
|
|
491
|
+
...layoutActionsOf(layout),
|
|
492
|
+
layoutHydrated: () => layout.hydrated(),
|
|
493
|
+
isLayoutHydrated: () => layout.isHydrated(),
|
|
209
494
|
getState: () => state,
|
|
210
495
|
subscribe: (listener) => {
|
|
211
496
|
listeners.add(listener);
|
|
@@ -597,6 +882,18 @@ function useArbiSessionState(selector) {
|
|
|
597
882
|
const select = () => selector(store.getState());
|
|
598
883
|
return useSyncExternalStore(store.subscribe, select, select);
|
|
599
884
|
}
|
|
885
|
+
function useSessionView(key, fallback) {
|
|
886
|
+
const store = useArbiSessionStore();
|
|
887
|
+
const value = useArbiSessionState((state) => state.views.values[key]);
|
|
888
|
+
const set = useCallback((next) => store.setViewValue(key, next), [store, key]);
|
|
889
|
+
return [value === void 0 ? fallback : value, set];
|
|
890
|
+
}
|
|
891
|
+
function useTransientView(key, fallback) {
|
|
892
|
+
const store = useArbiSessionStore();
|
|
893
|
+
const value = useArbiSessionState((state) => state.views.transient[key]);
|
|
894
|
+
const set = useCallback((next) => store.setTransientView(key, next), [store, key]);
|
|
895
|
+
return [value === void 0 ? fallback : value, set];
|
|
896
|
+
}
|
|
600
897
|
var SIGNED_OUT = {
|
|
601
898
|
status: "signed-out",
|
|
602
899
|
user: null,
|
|
@@ -627,6 +924,108 @@ function useSignedInSession(session) {
|
|
|
627
924
|
);
|
|
628
925
|
}
|
|
629
926
|
|
|
927
|
+
// src/session/persist.ts
|
|
928
|
+
function createDebouncedWriter({
|
|
929
|
+
write,
|
|
930
|
+
delayMs,
|
|
931
|
+
maxWaitMs,
|
|
932
|
+
onError
|
|
933
|
+
}) {
|
|
934
|
+
const queue = /* @__PURE__ */ new Map();
|
|
935
|
+
const run = (key, value) => {
|
|
936
|
+
try {
|
|
937
|
+
void Promise.resolve(write(key, value)).catch((error) => onError?.(key, error));
|
|
938
|
+
} catch (error) {
|
|
939
|
+
onError?.(key, error);
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
const flush = (key) => {
|
|
943
|
+
const entry = queue.get(key);
|
|
944
|
+
if (!entry) return;
|
|
945
|
+
clearTimeout(entry.timer);
|
|
946
|
+
queue.delete(key);
|
|
947
|
+
run(key, entry.value);
|
|
948
|
+
};
|
|
949
|
+
return {
|
|
950
|
+
schedule(key, value) {
|
|
951
|
+
const now = Date.now();
|
|
952
|
+
const existing = queue.get(key);
|
|
953
|
+
if (existing) clearTimeout(existing.timer);
|
|
954
|
+
const firstQueuedAt = existing?.firstQueuedAt ?? now;
|
|
955
|
+
const wait = Math.max(0, Math.min(delayMs, firstQueuedAt + maxWaitMs - now));
|
|
956
|
+
queue.set(key, { value, firstQueuedAt, timer: setTimeout(() => flush(key), wait) });
|
|
957
|
+
},
|
|
958
|
+
pending: (key) => queue.get(key)?.value,
|
|
959
|
+
cancel(key) {
|
|
960
|
+
const entry = queue.get(key);
|
|
961
|
+
if (!entry) return;
|
|
962
|
+
clearTimeout(entry.timer);
|
|
963
|
+
queue.delete(key);
|
|
964
|
+
},
|
|
965
|
+
flushAll() {
|
|
966
|
+
for (const key of Array.from(queue.keys())) flush(key);
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function flushOnPageExit(writer) {
|
|
971
|
+
if (typeof window === "undefined" || typeof document === "undefined") return () => {
|
|
972
|
+
};
|
|
973
|
+
const flush = () => writer.flushAll();
|
|
974
|
+
const onVisibility = () => {
|
|
975
|
+
if (document.visibilityState === "hidden") writer.flushAll();
|
|
976
|
+
};
|
|
977
|
+
window.addEventListener("beforeunload", flush);
|
|
978
|
+
window.addEventListener("pagehide", flush);
|
|
979
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
980
|
+
return () => {
|
|
981
|
+
window.removeEventListener("beforeunload", flush);
|
|
982
|
+
window.removeEventListener("pagehide", flush);
|
|
983
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function createStoragePersist({
|
|
987
|
+
storage,
|
|
988
|
+
key,
|
|
989
|
+
parse = (saved) => saved,
|
|
990
|
+
migrate,
|
|
991
|
+
delayMs = 250,
|
|
992
|
+
maxWaitMs = 1e3
|
|
993
|
+
}) {
|
|
994
|
+
const writer = createDebouncedWriter({
|
|
995
|
+
write: (k, value) => storage.set(k, value),
|
|
996
|
+
delayMs,
|
|
997
|
+
maxWaitMs,
|
|
998
|
+
onError: (k, error) => console.error(`[session] Failed to save ${k}:`, error)
|
|
999
|
+
});
|
|
1000
|
+
flushOnPageExit(writer);
|
|
1001
|
+
const read = async () => {
|
|
1002
|
+
const pending = writer.pending(key);
|
|
1003
|
+
const raw = pending ?? await storage.get(key);
|
|
1004
|
+
if (raw === null || raw === void 0) return null;
|
|
1005
|
+
return parse(JSON.parse(raw));
|
|
1006
|
+
};
|
|
1007
|
+
return {
|
|
1008
|
+
async load() {
|
|
1009
|
+
try {
|
|
1010
|
+
const saved = await read();
|
|
1011
|
+
if (!migrate) return saved;
|
|
1012
|
+
const migrated = await migrate(saved);
|
|
1013
|
+
if (migrated !== null && migrated !== saved)
|
|
1014
|
+
await storage.set(key, JSON.stringify(migrated));
|
|
1015
|
+
return migrated;
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
console.warn("[session] The saved layout could not be read; starting from defaults", error);
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
save: (value) => writer.schedule(key, JSON.stringify(value)),
|
|
1022
|
+
async clear() {
|
|
1023
|
+
writer.cancel(key);
|
|
1024
|
+
await storage.remove(key);
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
|
|
630
1029
|
// src/usage-metered.ts
|
|
631
1030
|
function isUsageMetered(usage, subscription) {
|
|
632
1031
|
const empty = usage.total_spend === 0 && usage.total_tokens === 0 && usage.total_requests === 0;
|
|
@@ -1000,6 +1399,6 @@ function useUserUsageToday(options) {
|
|
|
1000
1399
|
});
|
|
1001
1400
|
}
|
|
1002
1401
|
|
|
1003
|
-
export { DEFAULT_DOCUMENT_VIEWER_STATE, EMPTY_SESSION_STATE, MAX_THREAD_TABS, MIN_QUEUED_MESSAGE_VISIBILITY_MS, PROJECT_CREATION_DENIED_REASON, agentControl, clearSealedDrafts, conversationKey, createArbiSessionStore, createSealedDraftStorage, isUsageMetered, nextViewingDocument, queuedMessages, selectDraft, selectIsGenerating, selectViewingDocumentId, threadTabId, useActivity, useAgents, useArbiSession, useArbiSessionState, useArbiSessionStore, useAssistantQuery, useAvailableModels, useBoxRole, useBuiltinCommands, useCanCreateProjects, useConfig, useConfigs, useConversationThreads, useConversations, useCurrentUser, useDeleteAgents, useDocumentVersionList, useFirmPool, useHealth, useMessageDetails, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSignedInSession, useTags, useThumbnails, useTopUpFirmPool, useUserUsageToday, useWorkspaceActivity, useWorkspaces };
|
|
1004
|
-
//# sourceMappingURL=chunk-
|
|
1005
|
-
//# sourceMappingURL=chunk-
|
|
1402
|
+
export { DEFAULT_DOCUMENT_VIEWER_STATE, EMPTY_SESSION_STATE, MAX_THREAD_TABS, MIN_QUEUED_MESSAGE_VISIBILITY_MS, PROJECT_CREATION_DENIED_REASON, agentControl, clearSealedDrafts, closePanelIn, conversationKey, createArbiLayoutStore, createArbiSessionStore, createDebouncedWriter, createSealedDraftStorage, createStoragePersist, defaultLayoutState, dmTabId, flushOnPageExit, isPanelOpen, isUsageMetered, layoutActionsOf, nextViewingDocument, openPanelIn, panelPlace, parseSavedLayout, queuedMessages, restoreLayout, savedLayoutOf, selectDraft, selectIsGenerating, selectViewingDocumentId, threadTabId, useActivity, useAgents, useArbiSession, useArbiSessionState, useArbiSessionStore, useAssistantQuery, useAvailableModels, useBoxRole, useBuiltinCommands, useCanCreateProjects, useConfig, useConfigs, useConversationThreads, useConversations, useCurrentUser, useDeleteAgents, useDocumentVersionList, useFirmPool, useHealth, useMessageDetails, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSessionView, useSignedInSession, useTags, useThumbnails, useTopUpFirmPool, useTransientView, useUserUsageToday, useWorkspaceActivity, useWorkspaces };
|
|
1403
|
+
//# sourceMappingURL=chunk-VTNFF7P6.js.map
|
|
1404
|
+
//# sourceMappingURL=chunk-VTNFF7P6.js.map
|