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