@powerhousedao/connect 6.1.0-staging.0 → 6.2.0-dev.0

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.
Files changed (90) hide show
  1. package/.env +11 -49
  2. package/README.md +4 -0
  3. package/dist/{AddDriveModal-ZK9-BWMB.js → AddDriveModal-kzL41qdg.js} +23 -9
  4. package/dist/AddDriveModal-kzL41qdg.js.map +1 -0
  5. package/dist/{ClearStorageModal-BLr3sRfl.js → ClearStorageModal-DIKwqiia.js} +8 -9
  6. package/dist/ClearStorageModal-DIKwqiia.js.map +1 -0
  7. package/dist/{CookiesPolicyModal-DiXQV82b.js → CookiesPolicyModal-1nOh6oN3.js} +6 -6
  8. package/dist/{CookiesPolicyModal-DiXQV82b.js.map → CookiesPolicyModal-1nOh6oN3.js.map} +1 -1
  9. package/dist/{CreateDocumentModal-BhJh4nWt.js → CreateDocumentModal-nQbLVDq3.js} +7 -5
  10. package/dist/{CreateDocumentModal-BhJh4nWt.js.map → CreateDocumentModal-nQbLVDq3.js.map} +1 -1
  11. package/dist/{DebugSettingsModal-DHORxOiI.js → DebugSettingsModal-DoY0auxt.js} +12 -12
  12. package/dist/DebugSettingsModal-DoY0auxt.js.map +1 -0
  13. package/dist/{DeleteDriveModal-CbuIdjKY.js → DeleteDriveModal-6P0T1QgD.js} +9 -7
  14. package/dist/{DeleteDriveModal-CbuIdjKY.js.map → DeleteDriveModal-6P0T1QgD.js.map} +1 -1
  15. package/dist/{DeleteItemModal-9ErYlauT.js → DeleteItemModal-BmV1aQyZ.js} +10 -8
  16. package/dist/{DeleteItemModal-9ErYlauT.js.map → DeleteItemModal-BmV1aQyZ.js.map} +1 -1
  17. package/dist/{DisclaimerModal-CfDeiBz8.js → DisclaimerModal-CVTFfN0_.js} +6 -6
  18. package/dist/{DisclaimerModal-CfDeiBz8.js.map → DisclaimerModal-CVTFfN0_.js.map} +1 -1
  19. package/dist/{DownloadDocumentWithErrorsModal-KZGWQ4J7.js → DownloadDocumentWithErrorsModal-CXeFUtaz.js} +15 -14
  20. package/dist/DownloadDocumentWithErrorsModal-CXeFUtaz.js.map +1 -0
  21. package/dist/{DriveSettingsModal-DEk05PS7.js → DriveSettingsModal-L5sM-rIh.js} +14 -8
  22. package/dist/{DriveSettingsModal-DEk05PS7.js.map → DriveSettingsModal-L5sM-rIh.js.map} +1 -1
  23. package/dist/{InspectorModal-DrBnrYZl.js → InspectorModal-C7pIf6OO.js} +19 -18
  24. package/dist/InspectorModal-C7pIf6OO.js.map +1 -0
  25. package/dist/{MissingPackageModal-CUdcDjSO.js → MissingPackageModal-D_N96M6a.js} +5 -5
  26. package/dist/{MissingPackageModal-CUdcDjSO.js.map → MissingPackageModal-D_N96M6a.js.map} +1 -1
  27. package/dist/{SettingsModal-CwIcZXAy.js → SettingsModal-B4BiV0hg.js} +31 -32
  28. package/dist/SettingsModal-B4BiV0hg.js.map +1 -0
  29. package/dist/{UpgradeDriveModal-BwI5E5k3.js → UpgradeDriveModal-CyAUDCU7.js} +6 -6
  30. package/dist/{UpgradeDriveModal-BwI5E5k3.js.map → UpgradeDriveModal-CyAUDCU7.js.map} +1 -1
  31. package/dist/{sidebar-BLHOoVIg.js → app-loader-DCYDK6hq.js} +1016 -591
  32. package/dist/app-loader-DCYDK6hq.js.map +1 -0
  33. package/dist/app-loader-UqO12emj.js +4 -0
  34. package/dist/{build-info-Megqmixp.js → build-info-sckG5_D4.js} +4 -4
  35. package/dist/{build-info-Megqmixp.js.map → build-info-sckG5_D4.js.map} +1 -1
  36. package/dist/components-B9mRhivD.js +5 -0
  37. package/dist/connect.config-aPx3rHZQ.js +161 -0
  38. package/dist/connect.config-aPx3rHZQ.js.map +1 -0
  39. package/dist/{load-DOIDDXvY.js → load-Cs4KcEw0.js} +16 -27
  40. package/dist/load-Cs4KcEw0.js.map +1 -0
  41. package/dist/main.js +5 -3
  42. package/dist/main.js.map +1 -1
  43. package/dist/{package-B4r0SFiy.js → package-BFW159r-.js} +19 -11
  44. package/dist/package-BFW159r-.js.map +1 -0
  45. package/dist/{pglite-runtime-Btp8ZXVH.js → pglite-runtime-toc1-TWa.js} +12 -6
  46. package/dist/pglite-runtime-toc1-TWa.js.map +1 -0
  47. package/dist/{pglite-seed-b1mJUaip.js → pglite-seed-D8oSKkep.js} +7 -7
  48. package/dist/pglite-seed-D8oSKkep.js.map +1 -0
  49. package/dist/pglite.worker.js +8 -7
  50. package/dist/pglite.worker.js.map +1 -1
  51. package/dist/pglite.worker.legacy.js +7 -6
  52. package/dist/pglite.worker.legacy.js.map +1 -1
  53. package/dist/{reactor-CppbYt7w.js → reactor-BlxTyHZ5.js} +113 -57
  54. package/dist/reactor-BlxTyHZ5.js.map +1 -0
  55. package/dist/{registerServiceWorker-CMRF2LWE.js → registerServiceWorker-B7uKpkci.js} +13 -11
  56. package/dist/{registerServiceWorker-CMRF2LWE.js.map → registerServiceWorker-B7uKpkci.js.map} +1 -1
  57. package/dist/{i18n-4rfcgnb9.js → reload-connect-toast-CwvSc6F-.js} +20 -6
  58. package/dist/reload-connect-toast-CwvSc6F-.js.map +1 -0
  59. package/dist/runtime-config-DL3QjcfM.js +24 -0
  60. package/dist/runtime-config-DL3QjcfM.js.map +1 -0
  61. package/dist/start-connect.d.ts.map +1 -1
  62. package/dist/start-connect.js +5 -3
  63. package/dist/start-connect.js.map +1 -1
  64. package/dist/style.css +4904 -12773
  65. package/dist/{toast-DnODOv28.js → toast-BEy42aYx.js} +3 -3
  66. package/dist/{toast-DnODOv28.js.map → toast-BEy42aYx.js.map} +1 -1
  67. package/dist/{useRegistryPackages-PUiMxd73.js → useRegistryPackages-Bh0luCvV.js} +6 -6
  68. package/dist/useRegistryPackages-Bh0luCvV.js.map +1 -0
  69. package/package.json +22 -14
  70. package/public/powerhouse.config.json +33 -0
  71. package/style.css +28 -0
  72. package/dist/AddDriveModal-ZK9-BWMB.js.map +0 -1
  73. package/dist/ClearStorageModal-BLr3sRfl.js.map +0 -1
  74. package/dist/DebugSettingsModal-DHORxOiI.js.map +0 -1
  75. package/dist/DownloadDocumentWithErrorsModal-KZGWQ4J7.js.map +0 -1
  76. package/dist/InspectorModal-DrBnrYZl.js.map +0 -1
  77. package/dist/SettingsModal-CwIcZXAy.js.map +0 -1
  78. package/dist/connect.config-Cuh0hj_Q.js +0 -142
  79. package/dist/connect.config-Cuh0hj_Q.js.map +0 -1
  80. package/dist/i18n-4rfcgnb9.js.map +0 -1
  81. package/dist/load-DOIDDXvY.js.map +0 -1
  82. package/dist/package-B4r0SFiy.js.map +0 -1
  83. package/dist/packages.config-CiH8KJVN.js +0 -32
  84. package/dist/packages.config-CiH8KJVN.js.map +0 -1
  85. package/dist/pglite-runtime-Btp8ZXVH.js.map +0 -1
  86. package/dist/pglite-seed-b1mJUaip.js.map +0 -1
  87. package/dist/reactor-CppbYt7w.js.map +0 -1
  88. package/dist/sidebar-BLHOoVIg.js.map +0 -1
  89. package/dist/useRegistryPackages-PUiMxd73.js.map +0 -1
  90. package/public/ph-packages.json +0 -4
@@ -1,410 +1,26 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ebf04d37-dff0-53fa-872d-097855e3824e")}catch(e){}}();
3
- import { n as defaultPHAppConfig, r as defaultPHDocumentEditorConfig, t as connectConfig } from "./connect.config-Cuh0hj_Q.js";
4
- import { n as toast, t as ToastContainer } from "./toast-DnODOv28.js";
5
- import { t as i18n } from "./i18n-4rfcgnb9.js";
6
- import { c as subscribeReactorPgMajor, d as createFileDataStore, f as idbError, l as IDB_STORE_NAME, m as readPgVersionFile, p as openIdb, r as getCachedReactorPgMajor, u as PRIMARY_IDB_NAMES } from "./pglite-runtime-Btp8ZXVH.js";
7
- import { t as serviceWorkerManager } from "./registerServiceWorker-CMRF2LWE.js";
8
- import { driveCollectionId, getRevisionFromDate, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDrive, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
9
- import { childLogger } from "document-model";
10
- import React, { StrictMode, Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
11
- import { Trans, useTranslation } from "react-i18next";
12
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
- import { Outlet, RouterProvider, createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
14
- import { useHotkeys } from "react-hotkeys-hook";
15
- import { AnimatedLoader, ConnectSidebar, ConnectTooltipProvider, CookieBanner, DefaultEditorLoader, DropZoneWrapper, HomeScreen, HomeScreenAddDriveItem, HomeScreenItem, PackageInstallModal, RevisionHistory, SidebarAddDriveItem, SidebarItem, useEns } from "@powerhousedao/design-system/connect";
16
- import { GenericDriveExplorer } from "@powerhousedao/powerhouse-vetra-packages/editors";
17
- import { Icon, Modal, PowerhouseButton } from "@powerhousedao/design-system";
18
- import { ErrorBoundary } from "react-error-boundary";
19
- import { PGlite } from "@electric-sql/pglite";
20
- import { twMerge } from "tailwind-merge";
21
- import { redo, undo } from "@powerhousedao/shared/document-model";
22
- //#region src/hooks/useAcceptedCookies.ts
23
- const ACCEPTED_COOKIES_KEY_STORAGE = `${connectConfig.routerBasename}:acceptedCookies`;
24
- const listeners$3 = /* @__PURE__ */ new Set();
25
- let cookies = getInitial$1();
26
- function getInitial$1() {
27
- try {
28
- const value = localStorage.getItem(ACCEPTED_COOKIES_KEY_STORAGE);
29
- return value ? JSON.parse(value) : {
30
- analytics: false,
31
- marketing: false,
32
- functional: false
33
- };
34
- } catch {
35
- return {
36
- analytics: false,
37
- marketing: false,
38
- functional: false
39
- };
40
- }
41
- }
42
- function getCookies() {
43
- return cookies;
44
- }
45
- function setCookies(setter) {
46
- cookies = setter(cookies);
47
- localStorage.setItem(ACCEPTED_COOKIES_KEY_STORAGE, JSON.stringify(cookies));
48
- listeners$3.forEach((fn) => fn());
49
- }
50
- function subscribe$1(fn) {
51
- listeners$3.add(fn);
52
- return () => listeners$3.delete(fn);
53
- }
54
- const useAcceptedCookies = () => {
55
- return [useSyncExternalStore(subscribe$1, getCookies, getCookies), setCookies];
56
- };
57
- const COOKIE_BANNER_KEY_STORAGE = `${connectConfig.routerBasename}:display-cookie-banner`;
58
- const listeners$2 = /* @__PURE__ */ new Set();
59
- let bannerShown = getInitial();
60
- function getInitial() {
61
- try {
62
- return localStorage.getItem(COOKIE_BANNER_KEY_STORAGE) !== "false";
63
- } catch (error) {
64
- console.error(error);
65
- return true;
66
- }
67
- }
68
- function getCookieBannerState() {
69
- return bannerShown;
70
- }
71
- function setCookieBannerState(state) {
72
- bannerShown = state;
73
- localStorage.setItem(COOKIE_BANNER_KEY_STORAGE, JSON.stringify(state));
74
- }
75
- function subscribe(fn) {
76
- listeners$2.add(fn);
77
- return () => listeners$2.delete(fn);
78
- }
79
- const useCookieBanner = () => {
80
- return [useSyncExternalStore(subscribe, getCookieBannerState, getCookieBannerState), setCookieBannerState];
81
- };
82
- //#endregion
83
- //#region src/hooks/useFailedInstallations.ts
84
- const emptyArray$1 = [];
85
- function useFailedInstallations() {
86
- const discoveryService = usePackageDiscoveryService();
87
- return useSyncExternalStore((cb) => discoveryService?.subscribeFailed(cb) ?? (() => {}), () => discoveryService?.getFailedInstallations() ?? emptyArray$1);
88
- }
89
- //#endregion
90
- //#region src/hooks/useInitSentry.ts
91
- const logger$2 = childLogger(["sentry"]);
92
- let clientStarted = false;
93
- async function getSentry() {
94
- return await import("@sentry/react");
95
- }
96
- async function initSentry() {
97
- connectConfig.sentry;
98
- const Sentry = await getSentry();
99
- const integrations = [
100
- Sentry.httpClientIntegration(),
101
- Sentry.extraErrorDataIntegration({ depth: 5 }),
102
- Sentry.replayIntegration(),
103
- Sentry.captureConsoleIntegration({ levels: ["error"] })
104
- ];
105
- if (connectConfig.sentry.tracing) integrations.push(Sentry.reactRouterV6BrowserTracingIntegration({
106
- useEffect: React.useEffect,
107
- useLocation,
108
- useNavigationType,
109
- createRoutesFromChildren,
110
- matchRoutes
111
- }));
112
- Sentry.init({
113
- release: connectConfig.sentry.release,
114
- dsn: connectConfig.sentry.dsn,
115
- environment: connectConfig.sentry.env,
116
- integrations,
117
- ignoreErrors: [
118
- "User is not allowed to create files",
119
- "User is not allowed to move documents",
120
- "The user aborted a request."
121
- ],
122
- sendDefaultPii: true,
123
- tracesSampleRate: 1,
124
- replaysSessionSampleRate: .1,
125
- replaysOnErrorSampleRate: 1,
126
- beforeSend(event, hint) {
127
- const error = hint.originalException;
128
- if (error instanceof TypeError && error.message.includes("Failed to fetch") && !navigator.onLine) return null;
129
- return event;
130
- }
131
- });
132
- clientStarted = true;
133
- }
134
- async function closeClient() {
135
- if (!clientStarted) return;
136
- return (await getSentry()).getClient()?.close();
137
- }
138
- function useInitSentry() {
139
- const [acceptedCookies] = useAcceptedCookies();
140
- const { analytics } = acceptedCookies;
141
- useEffect(() => {
142
- if (!analytics) {
143
- closeClient().catch((error) => logger$2.error("@error", error));
144
- return;
145
- }
146
- if (clientStarted || !connectConfig.sentry.dsn || connectConfig.sentry.dsn === "") return;
147
- initSentry().catch((error) => logger$2.error("@error", error));
148
- }, [analytics]);
149
- }
150
- //#endregion
151
- //#region src/hooks/usePendingInstallations.ts
152
- const emptyArray = [];
153
- function usePendingInstallations() {
154
- const discoveryService = usePackageDiscoveryService();
155
- const cacheRef = useRef(emptyArray);
156
- return useSyncExternalStore((cb) => discoveryService?.subscribePending(cb) ?? (() => {}), useCallback(() => {
157
- if (!discoveryService) return emptyArray;
158
- const next = discoveryService.getPendingInstallations() ?? emptyArray;
159
- const prev = cacheRef.current;
160
- if (next === prev || next.length === prev.length && next.every((p, i) => p === prev[i])) return prev;
161
- cacheRef.current = next;
162
- return next;
163
- }, [discoveryService]));
164
- }
165
- //#endregion
166
- //#region src/hooks/useUndoRedoShortcuts.ts
167
- const useUndoRedoShortcuts = (props) => {
168
- const { undo, redo, canRedo, canUndo } = props;
169
- const isMac = window.navigator.userAgent.includes("Mac");
170
- let undoShortcut = "ctrl+z";
171
- let redoShortcut = "ctrl+y";
172
- if (isMac) {
173
- undoShortcut = "mod+z";
174
- redoShortcut = "mod+shift+z";
175
- }
176
- useHotkeys(undoShortcut, (event) => {
177
- event.preventDefault();
178
- if (canUndo) undo();
179
- }, {}, [canUndo, undo]);
180
- useHotkeys(redoShortcut, (event) => {
181
- event.preventDefault();
182
- if (canRedo) redo();
183
- }, {}, [canRedo, redo]);
184
- };
185
- //#endregion
186
- //#region src/components/analytics.tsx
187
- function gtag(...args) {
188
- window.dataLayer?.push(...args);
189
- }
190
- const Analytics = () => {
191
- const gaTrackingId = connectConfig.gaTrackingId;
192
- const [{ analytics }] = useAcceptedCookies();
193
- const useAnalytics = gaTrackingId && analytics;
194
- useEffect(() => {
195
- if (useAnalytics) {
196
- const script = document.createElement("script");
197
- script.src = `https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`;
198
- script.async = true;
199
- document.head.appendChild(script);
200
- window.dataLayer = window.dataLayer || [];
201
- gtag("js", /* @__PURE__ */ new Date());
202
- gtag("config", gaTrackingId);
203
- return () => {
204
- document.head.removeChild(script);
205
- };
206
- }
207
- }, [useAnalytics, gaTrackingId]);
208
- return null;
209
- };
210
- //#endregion
211
- //#region src/components/document-editor-container.tsx
212
- function DocumentEditorContainer() {
213
- const [selectedDocument] = useSelectedDocument();
214
- const parentFolder = useNodeParentFolderById(selectedDocument.header.id);
215
- useMemo(() => {
216
- return async () => {};
217
- }, []);
218
- useCallback(() => {
219
- setSelectedNode(parentFolder);
220
- }, [parentFolder, setSelectedNode]);
221
- return /* @__PURE__ */ jsx("div", {
222
- id: "document-editor-container",
223
- className: "flex-1",
224
- "data-document-type": selectedDocument.header.documentType,
225
- children: /* @__PURE__ */ jsx(DocumentEditor, { document: selectedDocument })
226
- });
227
- }
228
- //#endregion
229
- //#region src/components/editor-loader.tsx
230
- function EditorLoader(props) {
231
- const [showLoading, setShowLoading] = useState(false);
232
- useEffect(() => {
233
- setTimeout(() => {
234
- setShowLoading(true);
235
- }, props.loadingTimeout ?? 200);
236
- }, [props]);
237
- if (!showLoading) return null;
238
- const { customEditorLoader, ...defaultProps } = props;
239
- if (customEditorLoader) return /* @__PURE__ */ jsx(Fragment, { children: customEditorLoader });
240
- return /* @__PURE__ */ jsx(DefaultEditorLoader, { ...defaultProps });
241
- }
242
- //#endregion
243
- //#region src/components/error-boundary.tsx
244
- const logger$1 = childLogger(["Connect"]);
245
- function hasCustomFallback(props) {
246
- return "fallbackRender" in props;
247
- }
248
- function SilentFallback() {
249
- return null;
250
- }
251
- /**
252
- * Simple text-based fallback component.
253
- * Displays a centered message when an error occurs.
254
- */
255
- function TextFallback({ message = "Something went wrong" }) {
256
- return /* @__PURE__ */ jsx("div", {
257
- className: "text-center",
258
- children: message
259
- });
260
- }
261
- /**
262
- * Detailed fallback component showing full error information.
263
- * Displays error message with a collapsible details section.
264
- * Useful for development and debugging purposes.
265
- */
266
- function DetailedFallback({ error, resetErrorBoundary }) {
267
- const errorMessage = error instanceof Error ? error.message : String(error);
268
- const errorDetails = error instanceof Error ? error.stack ?? String(error.cause) : JSON.stringify(error, null, 2);
269
- return /* @__PURE__ */ jsx("div", {
270
- className: "z-10 mx-auto flex max-w-[80%] flex-1 items-center justify-center p-6",
271
- children: /* @__PURE__ */ jsxs("div", {
272
- className: "w-full max-w-lg rounded-lg border border-gray-500 bg-white p-6 shadow-sm",
273
- children: [
274
- /* @__PURE__ */ jsxs("div", {
275
- className: "mb-3 flex items-center gap-2",
276
- children: [/* @__PURE__ */ jsx(Icon, {
277
- name: "Error",
278
- className: "size-5 shrink-0"
279
- }), /* @__PURE__ */ jsx("h1", {
280
- className: "text-lg font-semibold",
281
- children: "Something went wrong"
282
- })]
283
- }),
284
- /* @__PURE__ */ jsx("p", {
285
- className: "mb-4 text-sm text-gray-700",
286
- children: errorMessage
287
- }),
288
- errorDetails !== "{}" && /* @__PURE__ */ jsxs("details", {
289
- className: "group",
290
- children: [/* @__PURE__ */ jsx("summary", {
291
- className: "cursor-pointer text-sm font-medium text-gray-700 underline select-none hover:text-gray-700",
292
- children: "Show details"
293
- }), /* @__PURE__ */ jsx("pre", {
294
- className: "mt-2 max-h-48 overflow-auto rounded-sm bg-gray-100 p-3 text-xs",
295
- children: errorDetails
296
- })]
297
- }),
298
- /* @__PURE__ */ jsx(PowerhouseButton, {
299
- type: "button",
300
- onClick: resetErrorBoundary,
301
- className: "mt-4 px-3 py-1.5 text-base font-medium",
302
- children: "Try again"
303
- })
304
- ]
305
- })
306
- });
307
- }
308
- /**
309
- * Centered error message fallback component.
310
- * Displays the error message in a centered, full-size container.
311
- * Suitable for use as a custom fallbackRender when you need simple error display.
312
- */
313
- function CenteredErrorMessage({ error }) {
314
- return /* @__PURE__ */ jsx("div", {
315
- className: "flex size-full items-center justify-center",
316
- children: /* @__PURE__ */ jsx("h3", {
317
- className: "text-lg font-semibold",
318
- children: error instanceof Error ? error.message : String(error)
319
- })
320
- });
321
- }
322
- function getFallbackComponent(variant, fallbackMessage) {
323
- switch (variant) {
324
- case "silent": return SilentFallback;
325
- case "text": return () => /* @__PURE__ */ jsx(TextFallback, { message: fallbackMessage });
326
- case "detailed": return DetailedFallback;
327
- default: return CenteredErrorMessage;
328
- }
329
- }
330
- /**
331
- * Unified error boundary component for catching and handling React errors.
332
- *
333
- * Built on top of `react-error-boundary`, this component provides:
334
- * - Automatic error logging with configurable context
335
- * - Multiple fallback UI variants (silent, text, detailed)
336
- * - Support for custom fallback render functions
337
- * - Reset capability via `resetKeys`
338
- *
339
- * @example
340
- * // Using a predefined variant
341
- * <ErrorBoundary variant="detailed" loggerContext={["Connect", "Editor"]}>
342
- * <EditorComponent />
343
- * </ErrorBoundary>
344
- *
345
- * @example
346
- * // Using a custom message with the text variant
347
- * <ErrorBoundary variant="text" fallbackMessage="Failed to load drives">
348
- * <DrivesList />
349
- * </ErrorBoundary>
350
- *
351
- * @example
352
- * // Using a custom fallback render
353
- * <ErrorBoundary
354
- * fallbackRender={CenteredErrorMessage}
355
- * onError={(error) => trackError(error)}
356
- * >
357
- * <MyComponent />
358
- * </ErrorBoundary>
359
- *
360
- * @example
361
- * // Silent mode for modals (renders null on error)
362
- * <ErrorBoundary variant="silent" loggerContext={["Connect", "Modals"]}>
363
- * <ModalContent />
364
- * </ErrorBoundary>
365
- */
366
- function ErrorBoundary$1(props) {
367
- const { children, onError, resetKeys, loggerContext } = props;
368
- const handleError = (error, info) => {
369
- if (error.message.includes("Failed to fetch dynamically imported module") && error.message.includes("node_modules/.vite")) {
370
- console.error(error);
371
- console.log("Outdated chunk detected, reloading page...");
372
- window.location.reload();
373
- return;
374
- }
375
- (loggerContext ? childLogger(loggerContext) : logger$1).error("@error @info", error, info);
376
- onError?.(error, info);
377
- };
378
- return /* @__PURE__ */ jsx(ErrorBoundary, {
379
- fallbackRender: hasCustomFallback(props) ? props.fallbackRender : getFallbackComponent(props.variant, props.fallbackMessage),
380
- onError: handleError,
381
- resetKeys,
382
- children
383
- });
384
- }
385
- //#endregion
386
- //#region src/components/app-container.tsx
387
- function AppContainer() {
388
- const [selectedDrive] = useSelectedDrive();
389
- const selectedDocumentId = useSelectedDocumentId();
390
- const app = useAppModuleById(selectedDrive.header.meta?.preferredEditor);
391
- const defaultApp = useDefaultAppModule();
392
- const AppComponent = app?.Component ?? defaultApp?.Component ?? GenericDriveExplorer.Component;
393
- if (!AppComponent) throw new Error("No app component found");
394
- return /* @__PURE__ */ jsx(ErrorBoundary$1, {
395
- variant: "detailed",
396
- resetKeys: [selectedDrive.header.id],
397
- loggerContext: ["Connect", "App"],
398
- children: /* @__PURE__ */ jsx(Suspense, {
399
- fallback: /* @__PURE__ */ jsx(EditorLoader, {}),
400
- children: /* @__PURE__ */ jsx(DropZoneWrapper, {
401
- className: "flex h-full flex-col overflow-auto",
402
- children: /* @__PURE__ */ jsx(AppComponent, { children: selectedDocumentId ? /* @__PURE__ */ jsx(DocumentEditorContainer, {}) : null })
403
- })
404
- })
405
- });
406
- }
407
- //#endregion
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ecb0fae1-8b49-5b4b-b37b-86f2feb9a9b6")}catch(e){}}();
3
+ import { n as getRuntimeConfig } from "./runtime-config-DL3QjcfM.js";
4
+ import { n as i18n } from "./reload-connect-toast-CwvSc6F-.js";
5
+ import { a as defaultPHDocumentEditorConfig, i as defaultPHAppConfig, r as connectConfig } from "./connect.config-aPx3rHZQ.js";
6
+ import { c as subscribeReactorPgMajor, d as createFileDataStore, f as idbError, l as IDB_STORE_NAME, m as readPgVersionFile, p as openIdb, r as getCachedReactorPgMajor, u as PRIMARY_IDB_NAMES } from "./pglite-runtime-toc1-TWa.js";
7
+ import { t as serviceWorkerManager } from "./registerServiceWorker-B7uKpkci.js";
8
+ import { n as toast, t as ToastContainer } from "./toast-BEy42aYx.js";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { PGlite } from "@electric-sql/pglite";
11
+ import { Trans, useTranslation } from "react-i18next";
12
+ import React, { StrictMode, Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
13
+ import { driveCollectionId, getRevisionFromDate, initTheme, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useFallbackEditorModule, useIsAddDriveEnabled, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useReactorClientModule, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useTheme, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
14
+ import { childLogger } from "document-model";
15
+ import { ConnectSidebar, ConnectTooltipProvider, CookieBanner, DefaultEditorLoader, DropZoneWrapper, HomeScreen, HomeScreenAddDriveItem, HomeScreenItem, LogoAnimation, PackageInstallModal, RevisionHistory, SidebarAddDriveItem, SidebarItem, useEns } from "@powerhousedao/design-system/connect";
16
+ import { z } from "zod";
17
+ import { Outlet, RouterProvider, createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
18
+ import { useHotkeys } from "react-hotkeys-hook";
19
+ import { Icon, Modal, PowerhouseButton } from "@powerhousedao/design-system";
20
+ import { ErrorBoundary } from "react-error-boundary";
21
+ import { GenericDriveExplorer } from "@powerhousedao/powerhouse-vetra-packages/editors";
22
+ import { twMerge } from "tailwind-merge";
23
+ import { redo, undo } from "@powerhousedao/shared/document-model";
408
24
  //#region src/utils/browser.ts
409
25
  function getBasePath() {
410
26
  if (typeof document === "undefined") return "/";
@@ -460,18 +76,18 @@ var DocumentEditorDebugTools = class {
460
76
  //#endregion
461
77
  //#region src/components/migration-status.ts
462
78
  let current = null;
463
- const listeners$1 = /* @__PURE__ */ new Set();
79
+ const listeners$3 = /* @__PURE__ */ new Set();
464
80
  function setMigrationStatus(status) {
465
81
  current = status;
466
- for (const l of listeners$1) l();
82
+ for (const l of listeners$3) l();
467
83
  }
468
84
  function getMigrationStatus() {
469
85
  return current;
470
86
  }
471
87
  function subscribeMigrationStatus(cb) {
472
- listeners$1.add(cb);
88
+ listeners$3.add(cb);
473
89
  return () => {
474
- listeners$1.delete(cb);
90
+ listeners$3.delete(cb);
475
91
  };
476
92
  }
477
93
  //#endregion
@@ -701,10 +317,418 @@ async function migrateAllIfNeeded() {
701
317
  await migrateAllLocked();
702
318
  return;
703
319
  }
704
- await navigator.locks.request("ph-pglite-migration", { mode: "exclusive" }, async () => {
705
- await migrateAllLocked();
706
- });
707
- }
320
+ await navigator.locks.request("ph-pglite-migration", { mode: "exclusive" }, async () => {
321
+ await migrateAllLocked();
322
+ });
323
+ }
324
+ //#endregion
325
+ //#region src/hooks/useAcceptedCookies.ts
326
+ const ACCEPTED_COOKIES_KEY_STORAGE = `${connectConfig.routerBasename}:acceptedCookies`;
327
+ const listeners$2 = /* @__PURE__ */ new Set();
328
+ let cookies = getInitial$1();
329
+ function getInitial$1() {
330
+ try {
331
+ const value = localStorage.getItem(ACCEPTED_COOKIES_KEY_STORAGE);
332
+ return value ? JSON.parse(value) : {
333
+ analytics: false,
334
+ marketing: false,
335
+ functional: false
336
+ };
337
+ } catch {
338
+ return {
339
+ analytics: false,
340
+ marketing: false,
341
+ functional: false
342
+ };
343
+ }
344
+ }
345
+ function getCookies() {
346
+ return cookies;
347
+ }
348
+ function setCookies(setter) {
349
+ cookies = setter(cookies);
350
+ localStorage.setItem(ACCEPTED_COOKIES_KEY_STORAGE, JSON.stringify(cookies));
351
+ listeners$2.forEach((fn) => fn());
352
+ }
353
+ function subscribe$1(fn) {
354
+ listeners$2.add(fn);
355
+ return () => listeners$2.delete(fn);
356
+ }
357
+ const useAcceptedCookies = () => {
358
+ return [useSyncExternalStore(subscribe$1, getCookies, getCookies), setCookies];
359
+ };
360
+ //#endregion
361
+ //#region src/services/openpanel/buffer.ts
362
+ const buffer = [];
363
+ let errorHandler;
364
+ function defaultOnError(err) {
365
+ console.warn("[useOpenPanelAnalytics] track failed:", err);
366
+ }
367
+ /**
368
+ * Forward a single event to the active client, swallowing any throw.
369
+ *
370
+ * The outer try/catch handles synchronous throws from `client.track`; the
371
+ * inner `.catch()` handles rejected promises. Both are needed because
372
+ * `Promise.resolve(x).catch()` cannot catch a throw from evaluating `x`.
373
+ */
374
+ function forward(client, name, props) {
375
+ try {
376
+ Promise.resolve(client.track(name, props)).catch((err) => (errorHandler ?? defaultOnError)(err));
377
+ } catch (err) {
378
+ (errorHandler ?? defaultOnError)(err);
379
+ }
380
+ }
381
+ /**
382
+ * Drain the pre-init buffer in FIFO order through `client.track`, then forward
383
+ * subsequent events directly. Called once from `getOpenPanelClient()`.
384
+ */
385
+ function drainOpenPanelBuffer(client, onError) {
386
+ errorHandler = onError;
387
+ const pending = buffer.splice(0, buffer.length);
388
+ for (const [name, props] of pending) forward(client, name, props);
389
+ }
390
+ /**
391
+ * Clear the buffer and reset the active client. Buffered pre-consent events
392
+ * are discarded so they are not replayed if the user later re-accepts.
393
+ */
394
+ function clearOpenPanelBuffer() {
395
+ buffer.length = 0;
396
+ errorHandler = void 0;
397
+ }
398
+ //#endregion
399
+ //#region src/services/openpanel/client.ts
400
+ let client;
401
+ /**
402
+ * Returns the cached `OpenPanel` singleton, building it on first call.
403
+ *
404
+ * When `config.clientId` is empty it returns `undefined` without importing
405
+ * `@openpanel/web`, so the bundler can tree-shake the SDK out of production.
406
+ */
407
+ async function getOpenPanelClient(config) {
408
+ if (!config.clientId) return;
409
+ if (client) return client;
410
+ const { OpenPanel: OpenPanelClass } = await import("@openpanel/web");
411
+ client = new OpenPanelClass({
412
+ clientId: config.clientId,
413
+ ...config.apiUrl ? { apiUrl: config.apiUrl } : {},
414
+ trackScreenViews: true,
415
+ trackOutgoingLinks: true
416
+ });
417
+ client.setGlobalProperties({ app: "connect" });
418
+ drainOpenPanelBuffer(client);
419
+ return client;
420
+ }
421
+ /**
422
+ * Clears the cached singleton and the pre-init buffer. Call on consent
423
+ * revocation or during tests; buffered events are discarded, not replayed.
424
+ */
425
+ function resetOpenPanelClient() {
426
+ client = void 0;
427
+ clearOpenPanelBuffer();
428
+ }
429
+ //#endregion
430
+ //#region src/services/openpanel/events.json
431
+ var events_default = [
432
+ {
433
+ "documentType": "powerhouse/document-drive",
434
+ "actionTypes": [
435
+ "ADD_FOLDER",
436
+ "DELETE_NODE",
437
+ "ADD_FILE",
438
+ "UPDATE_FILE",
439
+ "COPY_NODE",
440
+ "MOVE_NODE",
441
+ "SET_DRIVE_NAME",
442
+ "SET_DRIVE_ICON"
443
+ ]
444
+ },
445
+ {
446
+ "documentType": "powerhouse/document-model",
447
+ "actionTypes": [
448
+ "SET_MODEL_NAME",
449
+ "SET_MODEL_ID",
450
+ "ADD_MODULE",
451
+ "DELETE_MODULE",
452
+ "ADD_OPERATION",
453
+ "DELETE_OPERATION"
454
+ ]
455
+ },
456
+ {
457
+ "documentType": "powerhouse/reactor-drive",
458
+ "actionTypes": [
459
+ "ADD_FOLDER",
460
+ "REMOVE_FOLDER",
461
+ "UPDATE_FOLDER"
462
+ ]
463
+ }
464
+ ];
465
+ //#endregion
466
+ //#region src/services/openpanel/events.ts
467
+ const EventMappingSchema = z.object({
468
+ documentType: z.string().min(1),
469
+ actionTypes: z.array(z.string().min(1)).min(1),
470
+ alias: z.string().optional()
471
+ }).strict();
472
+ const EventMappingsSchema = z.array(EventMappingSchema).readonly();
473
+ /**
474
+ * Parses and validates the event mapping table, returning the validated array
475
+ * and an O(1) lookup map. Accepts a `raw` override for tests. Throws on zod
476
+ * failures and on duplicate `(documentType, actionType)` pairs.
477
+ */
478
+ function loadEvents(raw = events_default) {
479
+ const result = EventMappingsSchema.safeParse(raw);
480
+ if (!result.success) throw new Error(`Invalid OpenPanel events.json: ${result.error.message}`);
481
+ const mappings = result.data;
482
+ const lookupMap = /* @__PURE__ */ new Map();
483
+ for (const mapping of mappings) {
484
+ let inner = lookupMap.get(mapping.documentType);
485
+ if (!inner) {
486
+ inner = /* @__PURE__ */ new Map();
487
+ lookupMap.set(mapping.documentType, inner);
488
+ }
489
+ for (const actionType of mapping.actionTypes) {
490
+ if (inner.has(actionType)) throw new Error(`Duplicate OpenPanel event mapping for ${mapping.documentType}/${actionType}`);
491
+ inner.set(actionType, mapping);
492
+ }
493
+ }
494
+ return {
495
+ mappings,
496
+ lookupMap
497
+ };
498
+ }
499
+ const { mappings: defaultMappings, lookupMap: defaultLookupMap } = loadEvents();
500
+ /** Validated mapping array from the bundled events.json. */
501
+ const eventMappings = defaultMappings;
502
+ /** O(1) lookup map: documentType → actionType → mapping. */
503
+ const eventLookupMap = defaultLookupMap;
504
+ /**
505
+ * Normalizes a document type into a safe event-name segment: lowercased, `/`
506
+ * replaced with `.`, and any character outside `[a-z0-9._-]` stripped.
507
+ * e.g. `powerhouse/document-drive` → `powerhouse.document-drive`.
508
+ */
509
+ function normalize(documentType) {
510
+ return documentType.toLowerCase().replace(/\//g, ".").replace(/[^a-z0-9._-]/g, "");
511
+ }
512
+ /**
513
+ * Derives the OpenPanel event name: `mapping.alias` when present, otherwise
514
+ * `${normalize(documentType)}.${actionType.toLowerCase()}`.
515
+ */
516
+ function deriveEventName(mapping, op) {
517
+ if (mapping.alias) return mapping.alias;
518
+ return `${normalize(op.context.documentType)}.${op.operation.action.type.toLowerCase()}`;
519
+ }
520
+ /**
521
+ * Builds the default properties attached to every OpenPanel event. The `app`
522
+ * property is stamped globally by the client, not here.
523
+ */
524
+ function buildDefaultProperties(op) {
525
+ return {
526
+ documentType: op.context.documentType,
527
+ actionType: op.operation.action.type,
528
+ documentId: op.context.documentId,
529
+ scope: op.context.scope,
530
+ branch: op.context.branch
531
+ };
532
+ }
533
+ //#endregion
534
+ //#region src/services/openpanel/processor.ts
535
+ /**
536
+ * Read-only reactor `IProcessor` that translates matching document operations
537
+ * into OpenPanel analytics events. Operations whose `(documentType, actionType)`
538
+ * pair is absent from the lookup map are skipped; per-operation errors are
539
+ * routed to `onError` and never thrown back to the manager.
540
+ */
541
+ var OpenPanelProcessor = class {
542
+ constructor(client, lookupMap, onError = (err) => console.warn("[OpenPanelProcessor] Error tracking event:", err)) {
543
+ this.client = client;
544
+ this.lookupMap = lookupMap;
545
+ this.onError = onError;
546
+ }
547
+ async onOperations(operations) {
548
+ for (const op of operations) {
549
+ const inner = this.lookupMap.get(op.context.documentType);
550
+ if (!inner) continue;
551
+ const mapping = inner.get(op.operation.action.type);
552
+ if (!mapping) continue;
553
+ const name = deriveEventName(mapping, op);
554
+ const payload = buildDefaultProperties(op);
555
+ try {
556
+ await this.client.track(name, payload);
557
+ } catch (err) {
558
+ this.onError(err, op);
559
+ }
560
+ }
561
+ }
562
+ onDisconnect() {
563
+ this.client.flush?.();
564
+ return Promise.resolve();
565
+ }
566
+ };
567
+ //#endregion
568
+ //#region src/services/openpanel/factory.ts
569
+ /**
570
+ * Returns a `ProcessorFactory` that, for each drive, creates a single
571
+ * `OpenPanelProcessor` record whose `filter.documentType` is the union of all
572
+ * document types present in the event mapping table.
573
+ */
574
+ function createOpenPanelProcessorFactory(config) {
575
+ return function openPanelProcessorFactory(_driveHeader) {
576
+ const documentType = Array.from(config.events.lookupMap.keys());
577
+ return [{
578
+ processor: new OpenPanelProcessor(config.client, config.events.lookupMap, config.onError),
579
+ filter: { documentType },
580
+ startFrom: config.startFrom ?? "current"
581
+ }];
582
+ };
583
+ }
584
+ //#endregion
585
+ //#region src/hooks/useIsEmbedded.ts
586
+ /**
587
+ * Detects whether Connect is being rendered inside another app (e.g. inside
588
+ * an iframe in the vetra-cli drive editor). When `?embed=1` is present in the
589
+ * URL, chrome that doesn't make sense in the embedded context — the cookie
590
+ * banner, the outer sidebar — is suppressed.
591
+ */
592
+ function getIsEmbedded() {
593
+ if (typeof window === "undefined") return false;
594
+ try {
595
+ const value = new URLSearchParams(window.location.search).get("embed");
596
+ return value !== null && value !== "0" && value !== "false";
597
+ } catch {
598
+ return false;
599
+ }
600
+ }
601
+ function useIsEmbedded() {
602
+ return getIsEmbedded();
603
+ }
604
+ const COOKIE_BANNER_KEY_STORAGE = `${connectConfig.routerBasename}:display-cookie-banner`;
605
+ const listeners$1 = /* @__PURE__ */ new Set();
606
+ let bannerShown = getInitial();
607
+ function getInitial() {
608
+ if (getIsEmbedded()) return false;
609
+ try {
610
+ return localStorage.getItem(COOKIE_BANNER_KEY_STORAGE) !== "false";
611
+ } catch (error) {
612
+ console.error(error);
613
+ return true;
614
+ }
615
+ }
616
+ function getCookieBannerState() {
617
+ return bannerShown;
618
+ }
619
+ function setCookieBannerState(state) {
620
+ bannerShown = state;
621
+ localStorage.setItem(COOKIE_BANNER_KEY_STORAGE, JSON.stringify(state));
622
+ }
623
+ function subscribe(fn) {
624
+ listeners$1.add(fn);
625
+ return () => listeners$1.delete(fn);
626
+ }
627
+ const useCookieBanner = () => {
628
+ return [useSyncExternalStore(subscribe, getCookieBannerState, getCookieBannerState), setCookieBannerState];
629
+ };
630
+ //#endregion
631
+ //#region src/hooks/useFailedInstallations.ts
632
+ const emptyArray$1 = [];
633
+ function useFailedInstallations() {
634
+ const discoveryService = usePackageDiscoveryService();
635
+ return useSyncExternalStore((cb) => discoveryService?.subscribeFailed(cb) ?? (() => {}), () => discoveryService?.getFailedInstallations() ?? emptyArray$1);
636
+ }
637
+ //#endregion
638
+ //#region src/hooks/useInitSentry.ts
639
+ const logger$2 = childLogger(["sentry"]);
640
+ let clientStarted = false;
641
+ async function getSentry() {
642
+ return await import("@sentry/react");
643
+ }
644
+ async function initSentry() {
645
+ const Sentry = await getSentry();
646
+ const integrations = [
647
+ Sentry.httpClientIntegration(),
648
+ Sentry.extraErrorDataIntegration({ depth: 5 }),
649
+ Sentry.replayIntegration(),
650
+ Sentry.captureConsoleIntegration({ levels: ["error"] })
651
+ ];
652
+ if (connectConfig.sentry.tracing) integrations.push(Sentry.reactRouterV6BrowserTracingIntegration({
653
+ useEffect: React.useEffect,
654
+ useLocation,
655
+ useNavigationType,
656
+ createRoutesFromChildren,
657
+ matchRoutes
658
+ }));
659
+ Sentry.init({
660
+ release: connectConfig.sentry.release,
661
+ dsn: connectConfig.sentry.dsn ?? void 0,
662
+ environment: connectConfig.sentry.env,
663
+ integrations,
664
+ ignoreErrors: [
665
+ "User is not allowed to create files",
666
+ "User is not allowed to move documents",
667
+ "The user aborted a request."
668
+ ],
669
+ sendDefaultPii: true,
670
+ tracesSampleRate: 1,
671
+ replaysSessionSampleRate: .1,
672
+ replaysOnErrorSampleRate: 1,
673
+ beforeSend(event, hint) {
674
+ const error = hint.originalException;
675
+ if (error instanceof TypeError && error.message.includes("Failed to fetch") && !navigator.onLine) return null;
676
+ return event;
677
+ }
678
+ });
679
+ clientStarted = true;
680
+ }
681
+ async function closeClient() {
682
+ if (!clientStarted) return;
683
+ return (await getSentry()).getClient()?.close();
684
+ }
685
+ function useInitSentry() {
686
+ const [acceptedCookies] = useAcceptedCookies();
687
+ const { analytics } = acceptedCookies;
688
+ useEffect(() => {
689
+ if (!analytics) {
690
+ closeClient().catch((error) => logger$2.error("@error", error));
691
+ return;
692
+ }
693
+ if (clientStarted || connectConfig.sentry.dsn === null || connectConfig.sentry.dsn === void 0 || connectConfig.sentry.dsn === "") return;
694
+ initSentry().catch((error) => logger$2.error("@error", error));
695
+ }, [analytics]);
696
+ }
697
+ //#endregion
698
+ //#region src/hooks/usePendingInstallations.ts
699
+ const emptyArray = [];
700
+ function usePendingInstallations() {
701
+ const discoveryService = usePackageDiscoveryService();
702
+ const cacheRef = useRef(emptyArray);
703
+ return useSyncExternalStore((cb) => discoveryService?.subscribePending(cb) ?? (() => {}), useCallback(() => {
704
+ if (!discoveryService) return emptyArray;
705
+ const next = discoveryService.getPendingInstallations() ?? emptyArray;
706
+ const prev = cacheRef.current;
707
+ if (next === prev || next.length === prev.length && next.every((p, i) => p === prev[i])) return prev;
708
+ cacheRef.current = next;
709
+ return next;
710
+ }, [discoveryService]));
711
+ }
712
+ //#endregion
713
+ //#region src/hooks/useUndoRedoShortcuts.ts
714
+ const useUndoRedoShortcuts = (props) => {
715
+ const { undo, redo, canRedo, canUndo } = props;
716
+ const isMac = window.navigator.userAgent.includes("Mac");
717
+ let undoShortcut = "ctrl+z";
718
+ let redoShortcut = "ctrl+y";
719
+ if (isMac) {
720
+ undoShortcut = "mod+z";
721
+ redoShortcut = "mod+shift+z";
722
+ }
723
+ useHotkeys(undoShortcut, (event) => {
724
+ event.preventDefault();
725
+ if (canUndo) undo();
726
+ }, {}, [canUndo, undo]);
727
+ useHotkeys(redoShortcut, (event) => {
728
+ event.preventDefault();
729
+ if (canRedo) redo();
730
+ }, {}, [canRedo, redo]);
731
+ };
708
732
  //#endregion
709
733
  //#region src/components/app-skeleton.tsx
710
734
  const LOADER_DELAY = 250;
@@ -719,12 +743,12 @@ const MigrationOverlay = () => {
719
743
  return /* @__PURE__ */ jsx("div", {
720
744
  className: "absolute inset-0 z-20 flex items-center justify-center",
721
745
  children: /* @__PURE__ */ jsxs("div", {
722
- className: "rounded-lg bg-white/90 px-6 py-4 text-sm text-gray-900 shadow-lg",
746
+ className: "rounded-lg bg-white/90 px-6 py-4 text-sm text-gray-900 shadow-lg dark:bg-slate-900/90 dark:text-slate-50",
723
747
  children: [/* @__PURE__ */ jsx("div", {
724
748
  className: "font-medium",
725
749
  children: "Upgrading local database…"
726
750
  }), /* @__PURE__ */ jsx("div", {
727
- className: "text-gray-600",
751
+ className: "text-gray-700 dark:text-slate-200",
728
752
  children: PHASE_LABEL[status.phase]
729
753
  })]
730
754
  })
@@ -733,6 +757,7 @@ const MigrationOverlay = () => {
733
757
  const Loader = ({ delay = LOADER_DELAY }) => {
734
758
  const isSSR = typeof window === "undefined";
735
759
  const showInitialLoader = typeof document !== "undefined" && document.body.getAttribute("data-show-loader") === "true";
760
+ if (!isSSR) initTheme();
736
761
  const [showLoading, setShowLoading] = useState(!delay || showInitialLoader);
737
762
  useEffect(() => {
738
763
  const id = setTimeout(() => {
@@ -744,7 +769,7 @@ const Loader = ({ delay = LOADER_DELAY }) => {
744
769
  className: `skeleton-loader absolute inset-0 z-10 flex items-center justify-center ${showLoading ? "" : "hidden"}`,
745
770
  children: [/* @__PURE__ */ jsx("div", {
746
771
  className: "animate-pulse overflow-hidden rounded-full shadow-lg",
747
- children: /* @__PURE__ */ jsx(AnimatedLoader, {})
772
+ children: /* @__PURE__ */ jsx(LogoAnimation, {})
748
773
  }), isSSR ? /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: `setTimeout(() => {
749
774
  document.querySelector('.skeleton-loader')?.classList.remove('hidden');
750
775
  document.body.setAttribute('data-show-loader', 'true');
@@ -755,9 +780,9 @@ const AppSkeleton = (props) => {
755
780
  const isSSR = typeof window === "undefined";
756
781
  const isHomeScreen = !isSSR && window.location.pathname === getBasePath();
757
782
  return /* @__PURE__ */ jsxs("div", {
758
- className: "flex h-screen overflow-hidden",
783
+ className: "flex h-screen overflow-hidden bg-gray-50 dark:bg-slate-700",
759
784
  children: [
760
- /* @__PURE__ */ jsx(ConnectSidebar, {
785
+ !(!isSSR && getIsEmbedded()) && /* @__PURE__ */ jsx(ConnectSidebar, {
761
786
  className: "animate-pulse",
762
787
  onLogin: void 0,
763
788
  onDisconnect: void 0,
@@ -781,164 +806,396 @@ const AppSkeleton = (props) => {
781
806
  });
782
807
  };
783
808
  //#endregion
784
- //#region src/components/migration-banner.tsx
785
- let dismissed = false;
786
- const listeners = /* @__PURE__ */ new Set();
787
- function notify() {
788
- for (const l of listeners) l();
789
- }
790
- function dismiss() {
791
- dismissed = true;
792
- notify();
809
+ //#region src/components/error-boundary.tsx
810
+ const logger$1 = childLogger(["Connect"]);
811
+ function hasCustomFallback(props) {
812
+ return "fallbackRender" in props;
793
813
  }
794
- function subscribeDismissed(cb) {
795
- listeners.add(cb);
796
- return () => {
797
- listeners.delete(cb);
798
- };
814
+ function SilentFallback() {
815
+ return null;
799
816
  }
800
- function getDismissed() {
801
- return dismissed;
817
+ /**
818
+ * Simple text-based fallback component.
819
+ * Displays a centered message when an error occurs.
820
+ */
821
+ function TextFallback({ message = "Something went wrong" }) {
822
+ return /* @__PURE__ */ jsx("div", {
823
+ className: "text-center",
824
+ children: message
825
+ });
802
826
  }
803
- const MigrationBanner = () => {
804
- const isDismissed = useSyncExternalStore(subscribeDismissed, getDismissed, () => false);
805
- const major = useSyncExternalStore(subscribeReactorPgMajor, getCachedReactorPgMajor, () => void 0);
806
- const [migrating, setMigrating] = useState(false);
807
- const [error, setError] = useState(null);
808
- if (major === void 0 || major === null || major === 17) return null;
809
- if (isDismissed) return null;
810
- const handleMigrate = () => {
811
- setError(null);
812
- setMigrating(true);
813
- migrateAllIfNeeded().then(() => {
814
- window.location.reload();
815
- }).catch((err) => {
816
- setError(err instanceof Error ? err.message : String(err));
817
- setMigrating(false);
818
- });
819
- };
827
+ /**
828
+ * Detailed fallback component showing full error information.
829
+ * Displays error message with a collapsible details section.
830
+ * Useful for development and debugging purposes.
831
+ */
832
+ function DetailedFallback({ error, resetErrorBoundary }) {
833
+ const errorMessage = error instanceof Error ? error.message : String(error);
834
+ const errorDetails = error instanceof Error ? error.stack ?? String(error.cause) : JSON.stringify(error, null, 2);
820
835
  return /* @__PURE__ */ jsx("div", {
821
- className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
836
+ className: "z-10 mx-auto flex max-w-[80%] flex-1 items-center justify-center p-6",
822
837
  children: /* @__PURE__ */ jsxs("div", {
823
- className: "flex max-w-3xl items-center gap-3 rounded-lg border border-yellow-500 bg-yellow-400 px-4 py-3 text-sm text-gray-900 shadow-lg",
838
+ className: "w-full max-w-lg rounded-lg border border-gray-500 bg-gray-50 p-6 shadow-sm dark:border-slate-400 dark:bg-slate-800",
824
839
  children: [
825
840
  /* @__PURE__ */ jsxs("div", {
826
- className: "flex-1",
827
- children: [
828
- /* @__PURE__ */ jsxs("div", {
829
- className: "font-semibold",
830
- children: [
831
- "Your local database uses Postgres ",
832
- major,
833
- "."
834
- ]
835
- }),
836
- /* @__PURE__ */ jsxs("div", {
837
- className: "text-gray-800",
838
- children: [
839
- "Migrate to Postgres ",
840
- 17,
841
- " to pick up the latest features. Your data will be backed up first."
842
- ]
843
- }),
844
- error && /* @__PURE__ */ jsxs("div", {
845
- className: "mt-2 font-medium text-red-900",
846
- children: ["Migration failed: ", error]
847
- })
848
- ]
841
+ className: "mb-3 flex items-center gap-2",
842
+ children: [/* @__PURE__ */ jsx(Icon, {
843
+ name: "Error",
844
+ className: "size-5 shrink-0"
845
+ }), /* @__PURE__ */ jsx("h1", {
846
+ className: "text-lg font-semibold",
847
+ children: "Something went wrong"
848
+ })]
849
849
  }),
850
- /* @__PURE__ */ jsx("button", {
851
- type: "button",
852
- disabled: migrating,
853
- onClick: handleMigrate,
854
- className: "rounded-sm bg-gray-900 px-3 py-1 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50",
855
- children: migrating ? "Migrating…" : "Migrate now"
850
+ /* @__PURE__ */ jsx("p", {
851
+ className: "mb-4 text-sm text-gray-700 dark:text-slate-200",
852
+ children: errorMessage
856
853
  }),
857
- /* @__PURE__ */ jsx("button", {
854
+ errorDetails !== "{}" && /* @__PURE__ */ jsxs("details", {
855
+ className: "group",
856
+ children: [/* @__PURE__ */ jsx("summary", {
857
+ className: "cursor-pointer text-sm font-medium text-gray-700 underline select-none hover:text-gray-700 dark:text-slate-200 dark:hover:text-slate-200",
858
+ children: "Show details"
859
+ }), /* @__PURE__ */ jsx("pre", {
860
+ className: "mt-2 max-h-48 overflow-auto rounded-sm bg-gray-100 p-3 text-xs dark:bg-slate-700",
861
+ children: errorDetails
862
+ })]
863
+ }),
864
+ /* @__PURE__ */ jsx(PowerhouseButton, {
858
865
  type: "button",
859
- disabled: migrating,
860
- onClick: dismiss,
861
- className: "rounded-sm border border-gray-900 bg-transparent px-3 py-1 text-sm font-medium text-gray-900 hover:bg-gray-900/10 disabled:opacity-50",
862
- children: "Dismiss"
866
+ onClick: resetErrorBoundary,
867
+ className: "mt-4 px-3 py-1.5 text-base font-medium",
868
+ children: "Try again"
863
869
  })
864
870
  ]
865
871
  })
866
872
  });
867
- };
873
+ }
874
+ /**
875
+ * Centered error message fallback component.
876
+ * Displays the error message in a centered, full-size container.
877
+ * Suitable for use as a custom fallbackRender when you need simple error display.
878
+ */
879
+ function CenteredErrorMessage({ error }) {
880
+ return /* @__PURE__ */ jsx("div", {
881
+ className: "flex size-full items-center justify-center",
882
+ children: /* @__PURE__ */ jsx("h3", {
883
+ className: "text-lg font-semibold",
884
+ children: error instanceof Error ? error.message : String(error)
885
+ })
886
+ });
887
+ }
888
+ function getFallbackComponent(variant, fallbackMessage) {
889
+ switch (variant) {
890
+ case "silent": return SilentFallback;
891
+ case "text": return () => /* @__PURE__ */ jsx(TextFallback, { message: fallbackMessage });
892
+ case "detailed": return DetailedFallback;
893
+ default: return CenteredErrorMessage;
894
+ }
895
+ }
896
+ /**
897
+ * Unified error boundary component for catching and handling React errors.
898
+ *
899
+ * Built on top of `react-error-boundary`, this component provides:
900
+ * - Automatic error logging with configurable context
901
+ * - Multiple fallback UI variants (silent, text, detailed)
902
+ * - Support for custom fallback render functions
903
+ * - Reset capability via `resetKeys`
904
+ *
905
+ * @example
906
+ * // Using a predefined variant
907
+ * <ErrorBoundary variant="detailed" loggerContext={["Connect", "Editor"]}>
908
+ * <EditorComponent />
909
+ * </ErrorBoundary>
910
+ *
911
+ * @example
912
+ * // Using a custom message with the text variant
913
+ * <ErrorBoundary variant="text" fallbackMessage="Failed to load drives">
914
+ * <DrivesList />
915
+ * </ErrorBoundary>
916
+ *
917
+ * @example
918
+ * // Using a custom fallback render
919
+ * <ErrorBoundary
920
+ * fallbackRender={CenteredErrorMessage}
921
+ * onError={(error) => trackError(error)}
922
+ * >
923
+ * <MyComponent />
924
+ * </ErrorBoundary>
925
+ *
926
+ * @example
927
+ * // Silent mode for modals (renders null on error)
928
+ * <ErrorBoundary variant="silent" loggerContext={["Connect", "Modals"]}>
929
+ * <ModalContent />
930
+ * </ErrorBoundary>
931
+ */
932
+ function ErrorBoundary$1(props) {
933
+ const { children, onError, resetKeys, loggerContext } = props;
934
+ const handleError = (error, info) => {
935
+ if (error.message.includes("Failed to fetch dynamically imported module") && error.message.includes("node_modules/.vite")) {
936
+ console.error(error);
937
+ console.log("Outdated chunk detected, reloading page...");
938
+ window.location.reload();
939
+ return;
940
+ }
941
+ (loggerContext ? childLogger(loggerContext) : logger$1).error("@error @info", error, info);
942
+ onError?.(error, info);
943
+ };
944
+ return /* @__PURE__ */ jsx(ErrorBoundary, {
945
+ fallbackRender: hasCustomFallback(props) ? props.fallbackRender : getFallbackComponent(props.variant, props.fallbackMessage),
946
+ onError: handleError,
947
+ resetKeys,
948
+ children
949
+ });
950
+ }
951
+ //#endregion
952
+ //#region src/components/analytics.tsx
953
+ function gtag(...args) {
954
+ window.dataLayer?.push(...args);
955
+ }
956
+ const Analytics = () => {
957
+ const gaTrackingId = connectConfig.gaTrackingId;
958
+ const [{ analytics }] = useAcceptedCookies();
959
+ const useAnalytics = gaTrackingId && analytics;
960
+ useEffect(() => {
961
+ if (useAnalytics) {
962
+ const script = document.createElement("script");
963
+ script.src = `https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`;
964
+ script.async = true;
965
+ document.head.appendChild(script);
966
+ window.dataLayer = window.dataLayer || [];
967
+ gtag("js", /* @__PURE__ */ new Date());
968
+ gtag("config", gaTrackingId);
969
+ return () => {
970
+ document.head.removeChild(script);
971
+ };
972
+ }
973
+ }, [useAnalytics, gaTrackingId]);
974
+ return null;
975
+ };
976
+ //#endregion
977
+ //#region src/components/openpanel-traits.ts
978
+ /**
979
+ * Builds the OpenPanel identity traits from a renown User.
980
+ *
981
+ * Canonical trait schema (shared with Renown and Vetra — each app sends every
982
+ * field it has data for, under these names):
983
+ * - `address`, `did`, `networkId`, `chainId`, `caip2` — wallet/chain facts.
984
+ * - `ensName`, `ensAvatar` — raw ENS facts.
985
+ * - `username`, `userImage`, `profileDocumentId`, `profileCreatedAt` — raw
986
+ * Renown profile facts.
987
+ * - `accountType` — wallet-adapter concept; only Renown has it.
988
+ *
989
+ * Rules:
990
+ * - `credential` (contains a JWT) is **never** forwarded.
991
+ * - Traits carry raw facts only; resolved presentation values (avatar,
992
+ * display name) go in OpenPanel's native identify fields — see
993
+ * {@link buildIdentifyPayload}.
994
+ * - Optional fields (`ens`, `profile`) are only included when their value is
995
+ * non-nullish (guards against `null` from `RenownProfile` fields as well
996
+ * as plain `undefined`).
997
+ *
998
+ * Mirror the Sentry pattern in `store/user.ts`: destructure off `credential`
999
+ * first, then assemble the trait payload from the remainder.
1000
+ */
1001
+ function buildTraits(user) {
1002
+ const { credential: _credential, ...rest } = user;
1003
+ const traits = {
1004
+ address: rest.address,
1005
+ did: rest.did,
1006
+ networkId: rest.networkId,
1007
+ chainId: rest.chainId,
1008
+ caip2: `${rest.networkId}:${rest.chainId}`
1009
+ };
1010
+ if (rest.ens?.name != null) traits.ensName = rest.ens.name;
1011
+ if (rest.ens?.avatarUrl != null) traits.ensAvatar = rest.ens.avatarUrl;
1012
+ if (rest.profile?.username != null) traits.username = rest.profile.username;
1013
+ if (rest.profile?.userImage != null) traits.userImage = rest.profile.userImage;
1014
+ if (rest.profile?.documentId != null) traits.profileDocumentId = rest.profile.documentId;
1015
+ if (rest.profile?.createdAt != null) traits.profileCreatedAt = rest.profile.createdAt;
1016
+ return traits;
1017
+ }
1018
+ /**
1019
+ * Builds the full `identify()` payload:
1020
+ * - `profileId` is the wallet address — the cross-app profile key shared with
1021
+ * Renown and Vetra.
1022
+ * - `avatar` / `firstName` are OpenPanel's native profile fields (they drive
1023
+ * the picture and name in the dashboard UI), resolved as
1024
+ * `userImage ?? ensAvatar` and `ensName ?? username`.
1025
+ * - `properties` are the raw traits from {@link buildTraits}.
1026
+ */
1027
+ function buildIdentifyPayload(user) {
1028
+ const avatar = user.profile?.userImage ?? user.ens?.avatarUrl;
1029
+ const firstName = user.ens?.name ?? user.profile?.username;
1030
+ return {
1031
+ profileId: user.address,
1032
+ ...avatar != null ? { avatar } : {},
1033
+ ...firstName != null ? { firstName } : {},
1034
+ properties: buildTraits(user)
1035
+ };
1036
+ }
1037
+ //#endregion
1038
+ //#region src/components/openpanel.tsx
1039
+ /**
1040
+ * `OpenPanel` is a `null`-rendering component that manages the full lifecycle
1041
+ * of the OpenPanel analytics subsystem.
1042
+ *
1043
+ * Gates:
1044
+ * - `useAcceptedCookies().analytics === true` — the existing analytics cookie.
1045
+ * - `connectConfig.openPanel.clientId` non-empty — no client ID → no-op.
1046
+ *
1047
+ * Behaviour when both gates pass:
1048
+ * 1. Lazy-imports `@openpanel/web` and builds the singleton via
1049
+ * `getOpenPanelClient(connectConfig.openPanel)`.
1050
+ * 2. Exposes the client on `window.openPanel` for the card-6
1051
+ * `useOpenPanelAnalytics()` hook to consume.
1052
+ * 3. If `connectConfig.openPanel.trackOperations`, registers the processor
1053
+ * factory against `processorManager` so document operations are forwarded.
1054
+ * 4. Calls `client.identify()` when the renown user transitions from
1055
+ * `undefined` → defined (login). The profile ID is the wallet address —
1056
+ * the cross-app key shared with Renown and Vetra.
1057
+ * 5. Calls `client.clear()` when the user transitions from defined →
1058
+ * `undefined` (logout).
1059
+ *
1060
+ * Teardown (unmount **or** consent revocation):
1061
+ * - `unregisterFactory("openpanel")` to remove the processor.
1062
+ * - `resetOpenPanelClient()` to clear the singleton.
1063
+ * - `window.openPanel` is cleared.
1064
+ *
1065
+ * Mirrors the Sentry pattern in `store/user.ts` for login/logout detection.
1066
+ * Analytics failures are caught and forwarded to `console.warn` — they must
1067
+ * never throw into the application.
1068
+ *
1069
+ * Mounted next to `<Analytics />` in `app.tsx`.
1070
+ */
1071
+ function OpenPanel() {
1072
+ const [{ analytics }] = useAcceptedCookies();
1073
+ const user = useUser();
1074
+ const reactorClientModule = useReactorClientModule();
1075
+ const [client, setClient] = useState();
1076
+ /**
1077
+ * Tracks the previous `user` value so we can detect the two transitions:
1078
+ * undefined → defined (login)
1079
+ * defined → undefined (logout)
1080
+ */
1081
+ const prevUserRef = useRef(void 0);
1082
+ const enabled = analytics && !!connectConfig.openPanel.clientId;
1083
+ const processorManager = reactorClientModule?.reactorModule?.processorManager;
1084
+ useEffect(() => {
1085
+ if (!enabled) return;
1086
+ let cancelled = false;
1087
+ const isCancelled = () => cancelled;
1088
+ const setup = async () => {
1089
+ let builtClient;
1090
+ try {
1091
+ builtClient = await getOpenPanelClient(connectConfig.openPanel);
1092
+ } catch (err) {
1093
+ console.warn("[OpenPanel] Failed to build client:", err);
1094
+ return;
1095
+ }
1096
+ if (isCancelled() || !builtClient) return;
1097
+ setClient(builtClient);
1098
+ window.openPanel = builtClient;
1099
+ if (connectConfig.openPanel.trackOperations && processorManager) try {
1100
+ await processorManager.registerFactory("openpanel", createOpenPanelProcessorFactory({
1101
+ client: builtClient,
1102
+ events: {
1103
+ mappings: eventMappings,
1104
+ lookupMap: eventLookupMap
1105
+ },
1106
+ startFrom: "current"
1107
+ }));
1108
+ if (isCancelled()) await processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister factory after cancellation:", err));
1109
+ } catch (err) {
1110
+ console.warn("[OpenPanel] Failed to register processor factory:", err);
1111
+ }
1112
+ };
1113
+ setup();
1114
+ return () => {
1115
+ cancelled = true;
1116
+ prevUserRef.current = void 0;
1117
+ if (connectConfig.openPanel.trackOperations && processorManager) processorManager.unregisterFactory("openpanel").catch((err) => console.warn("[OpenPanel] Failed to unregister processor factory:", err));
1118
+ resetOpenPanelClient();
1119
+ window.openPanel = void 0;
1120
+ setClient(void 0);
1121
+ };
1122
+ }, [enabled, processorManager]);
1123
+ useEffect(() => {
1124
+ if (!enabled || !client) return;
1125
+ const prev = prevUserRef.current;
1126
+ prevUserRef.current = user;
1127
+ if (!prev && user) try {
1128
+ client.identify(buildIdentifyPayload(user));
1129
+ } catch (err) {
1130
+ console.warn("[OpenPanel] Failed to identify user:", err);
1131
+ }
1132
+ else if (prev && !user) try {
1133
+ client.clear();
1134
+ } catch (err) {
1135
+ console.warn("[OpenPanel] Failed to clear user:", err);
1136
+ }
1137
+ }, [
1138
+ client,
1139
+ user,
1140
+ enabled
1141
+ ]);
1142
+ return null;
1143
+ }
1144
+ //#endregion
1145
+ //#region src/components/document-editor-container.tsx
1146
+ function DocumentEditorContainer() {
1147
+ const [selectedDocument] = useSelectedDocument();
1148
+ const parentFolder = useNodeParentFolderById(selectedDocument.header.id);
1149
+ useMemo(() => {
1150
+ return async () => {};
1151
+ }, []);
1152
+ useCallback(() => {
1153
+ setSelectedNode(parentFolder);
1154
+ }, [parentFolder]);
1155
+ return /* @__PURE__ */ jsx("div", {
1156
+ id: "document-editor-container",
1157
+ className: "flex-1",
1158
+ "data-document-type": selectedDocument.header.documentType,
1159
+ children: /* @__PURE__ */ jsx(DocumentEditor, { document: selectedDocument })
1160
+ });
1161
+ }
868
1162
  //#endregion
869
- //#region src/components/modal/modals-container.tsx
870
- const AddDriveModal$1 = lazy(() => import("./AddDriveModal-ZK9-BWMB.js").then((m) => ({ default: m.AddDriveModal })));
871
- const ClearStorageModal = lazy(() => import("./ClearStorageModal-BLr3sRfl.js").then((m) => ({ default: m.ClearStorageModal })));
872
- const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-DiXQV82b.js").then((m) => ({ default: m.CookiesPolicyModal })));
873
- const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-BhJh4nWt.js").then((m) => ({ default: m.CreateDocumentModal })));
874
- const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-DHORxOiI.js").then((m) => ({ default: m.DebugSettingsModal })));
875
- const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-CbuIdjKY.js").then((m) => ({ default: m.DeleteDriveModal })));
876
- const DeleteItemModal = lazy(() => import("./DeleteItemModal-9ErYlauT.js").then((m) => ({ default: m.DeleteItemModal })));
877
- const DisclaimerModal = lazy(() => import("./DisclaimerModal-CfDeiBz8.js").then((m) => ({ default: m.DisclaimerModal })));
878
- const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-DEk05PS7.js").then((m) => ({ default: m.DriveSettingsModal })));
879
- const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-KZGWQ4J7.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
880
- const SettingsModal$1 = lazy(() => import("./SettingsModal-CwIcZXAy.js").then((m) => ({ default: m.SettingsModal })));
881
- const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BwI5E5k3.js").then((m) => ({ default: m.UpgradeDriveModal })));
882
- const modalComponents = {
883
- addDrive: AddDriveModal$1,
884
- clearStorage: ClearStorageModal,
885
- cookiesPolicy: CookiesPolicyModal,
886
- createDocument: CreateDocumentModal$1,
887
- debugSettings: DebugSettingsModal,
888
- deleteDrive: DeleteDriveModal,
889
- deleteItem: DeleteItemModal,
890
- disclaimer: DisclaimerModal,
891
- driveSettings: DriveSettingsModal$1,
892
- downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
893
- inspector: lazy(() => import("./InspectorModal-DrBnrYZl.js").then((m) => ({ default: m.InspectorModal }))),
894
- settings: SettingsModal$1,
895
- upgradeDrive: UpgradeDriveModal,
896
- missingPackage: lazy(() => import("./MissingPackageModal-CUdcDjSO.js").then((m) => ({ default: m.ConnectMissingPackageModal })))
897
- };
898
- const ModalsContainer = lazy(async () => {
899
- return { default: () => {
900
- const phModal = usePHModal();
901
- if (!phModal?.type) return null;
902
- const ModalComponent = modalComponents[phModal.type];
903
- return ModalComponent ? /* @__PURE__ */ jsx(ErrorBoundary$1, {
904
- variant: "silent",
905
- loggerContext: ["Connect", "Modals"],
906
- children: /* @__PURE__ */ jsx(Suspense, {
907
- fallback: null,
908
- children: /* @__PURE__ */ jsx(ModalComponent, {})
909
- })
910
- }) : null;
911
- } };
912
- });
1163
+ //#region src/components/editor-loader.tsx
1164
+ function EditorLoader(props) {
1165
+ const [showLoading, setShowLoading] = useState(false);
1166
+ useEffect(() => {
1167
+ setTimeout(() => {
1168
+ setShowLoading(true);
1169
+ }, props.loadingTimeout ?? 200);
1170
+ }, [props]);
1171
+ if (!showLoading) return null;
1172
+ const { customEditorLoader, ...defaultProps } = props;
1173
+ if (customEditorLoader) return /* @__PURE__ */ jsx(Fragment, { children: customEditorLoader });
1174
+ return /* @__PURE__ */ jsx(DefaultEditorLoader, { ...defaultProps });
1175
+ }
913
1176
  //#endregion
914
- //#region src/components/app-loader.tsx
915
- const AppLoader = (props) => {
916
- const Load = lazy(() => import("./load-DOIDDXvY.js").then((m) => m.loadComponent(props.localPackage)));
917
- return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
918
- fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
919
- resetKeys: [props.localPackage],
920
- loggerContext: ["Connect"],
921
- children: [
922
- /* @__PURE__ */ jsx(Suspense, {
923
- fallback: /* @__PURE__ */ jsx(AppSkeleton, {}),
924
- name: "AppLoader",
925
- children: /* @__PURE__ */ jsx(Load, {
926
- ...props,
927
- children: /* @__PURE__ */ jsx(App, {})
928
- })
929
- }),
930
- /* @__PURE__ */ jsx(Suspense, {
931
- name: "CookieBanner",
932
- children: /* @__PURE__ */ jsx(CookieBanner$1, {})
933
- }),
934
- /* @__PURE__ */ jsx(Suspense, {
935
- name: "ModalsContainer",
936
- children: /* @__PURE__ */ jsx(ModalsContainer, {})
937
- }),
938
- /* @__PURE__ */ jsx(MigrationBanner, {})
939
- ]
940
- }) });
941
- };
1177
+ //#region src/components/app-container.tsx
1178
+ function AppContainer() {
1179
+ const [selectedDrive] = useSelectedDriveSafe();
1180
+ const selectedDocumentId = useSelectedDocumentId();
1181
+ const app = useAppModuleById(selectedDrive?.header.meta?.preferredEditor);
1182
+ const defaultApp = useDefaultAppModule();
1183
+ if (!selectedDrive) return /* @__PURE__ */ jsx(EditorLoader, {});
1184
+ const AppComponent = app?.Component ?? defaultApp?.Component ?? GenericDriveExplorer.Component;
1185
+ if (!AppComponent) throw new Error("No app component found");
1186
+ return /* @__PURE__ */ jsx(ErrorBoundary$1, {
1187
+ variant: "detailed",
1188
+ resetKeys: [selectedDrive.header.id],
1189
+ loggerContext: ["Connect", "App"],
1190
+ children: /* @__PURE__ */ jsx(Suspense, {
1191
+ fallback: /* @__PURE__ */ jsx(EditorLoader, {}),
1192
+ children: /* @__PURE__ */ jsx(DropZoneWrapper, {
1193
+ className: "flex h-full flex-col overflow-auto",
1194
+ children: /* @__PURE__ */ jsx(AppComponent, { children: selectedDocumentId ? /* @__PURE__ */ jsx(DocumentEditorContainer, {}) : null })
1195
+ })
1196
+ })
1197
+ });
1198
+ }
942
1199
  //#endregion
943
1200
  //#region src/context/sentry-provider.tsx
944
1201
  const SentryProvider = ({ children }) => {
@@ -962,11 +1219,11 @@ function MissingModelBanner() {
962
1219
  const [open, setOpen] = useState(false);
963
1220
  if (failed.length === 0) return null;
964
1221
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
965
- className: "flex items-center justify-between gap-3 bg-amber-100 px-4 py-2 text-sm text-amber-900",
1222
+ className: "flex items-center justify-between gap-3 bg-amber-100 px-4 py-2 text-sm text-amber-900 dark:bg-amber-800 dark:text-amber-100",
966
1223
  children: [/* @__PURE__ */ jsx("span", { children: failed.length === 1 ? "1 document type couldn't load (missing model)." : `${failed.length} document types couldn't load (missing models).` }), /* @__PURE__ */ jsx("button", {
967
1224
  type: "button",
968
1225
  onClick: () => setOpen(true),
969
- className: "rounded-md border border-amber-300 bg-white px-3 py-1 text-amber-900 hover:bg-amber-50",
1226
+ className: "rounded-md border border-amber-300 bg-gray-50 px-3 py-1 text-amber-900 hover:bg-amber-50 dark:border-amber-600 dark:bg-slate-800 dark:text-amber-100 dark:hover:bg-amber-900",
970
1227
  children: "View"
971
1228
  })]
972
1229
  }), /* @__PURE__ */ jsx(MissingModelDetailsModal, {
@@ -999,18 +1256,18 @@ function MissingModelDetailsModal(props) {
999
1256
  },
1000
1257
  contentProps: { className: "rounded-3xl" },
1001
1258
  children: /* @__PURE__ */ jsxs("div", {
1002
- className: "w-[520px] max-w-[90vw] bg-white p-6",
1259
+ className: "w-[520px] max-w-[90vw] bg-gray-50 p-6 dark:bg-slate-800",
1003
1260
  children: [
1004
1261
  /* @__PURE__ */ jsx("div", {
1005
- className: "border-b border-slate-100 pb-2 text-2xl font-bold text-gray-800",
1262
+ className: "border-b border-gray-100 pb-2 text-2xl font-bold text-gray-900 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100",
1006
1263
  children: "Missing document models"
1007
1264
  }),
1008
1265
  /* @__PURE__ */ jsx("div", {
1009
- className: "my-4 text-sm text-gray-600",
1266
+ className: "my-4 text-sm text-gray-700 dark:text-slate-200",
1010
1267
  children: "The following document types couldn't be loaded. Documents using them won't display until the underlying package is installed."
1011
1268
  }),
1012
1269
  failed.length === 0 ? /* @__PURE__ */ jsx("div", {
1013
- className: "rounded-xl bg-slate-50 p-4 text-sm text-gray-600",
1270
+ className: "rounded-xl bg-gray-50 p-4 text-sm text-gray-700 dark:bg-slate-800 dark:text-slate-200",
1014
1271
  children: "No outstanding failures."
1015
1272
  }) : /* @__PURE__ */ jsx("div", {
1016
1273
  className: "flex max-h-[60vh] flex-col gap-3 overflow-y-auto",
@@ -1018,18 +1275,18 @@ function MissingModelDetailsModal(props) {
1018
1275
  const isRetrying = retrying.has(entry.documentType);
1019
1276
  const retryDisabled = !canRetry(entry.reason) || isRetrying;
1020
1277
  return /* @__PURE__ */ jsxs("div", {
1021
- className: "rounded-xl bg-slate-50 p-4",
1278
+ className: "rounded-xl bg-gray-50 p-4 dark:bg-slate-800",
1022
1279
  children: [
1023
1280
  /* @__PURE__ */ jsx("div", {
1024
- className: "mb-1 font-mono text-sm font-semibold text-gray-800",
1281
+ className: "mb-1 font-mono text-sm font-semibold text-gray-900 dark:text-slate-100",
1025
1282
  children: entry.documentType
1026
1283
  }),
1027
1284
  /* @__PURE__ */ jsx("div", {
1028
- className: "mb-2 text-xs text-gray-600",
1285
+ className: "mb-2 text-xs text-gray-700 dark:text-slate-200",
1029
1286
  children: reasonLabels[entry.reason]
1030
1287
  }),
1031
1288
  entry.packageNames.length > 0 ? /* @__PURE__ */ jsxs("div", {
1032
- className: "mb-2 text-xs text-gray-500",
1289
+ className: "mb-2 text-xs text-gray-500 dark:text-slate-400",
1033
1290
  children: [
1034
1291
  "Package",
1035
1292
  entry.packageNames.length > 1 ? "s" : "",
@@ -1039,7 +1296,7 @@ function MissingModelDetailsModal(props) {
1039
1296
  ]
1040
1297
  }) : null,
1041
1298
  entry.error ? /* @__PURE__ */ jsx("div", {
1042
- className: "mb-2 font-mono text-xs wrap-break-word text-red-700",
1299
+ className: "mb-2 font-mono text-xs wrap-break-word text-red-700 dark:text-red-100",
1043
1300
  children: entry.error.message
1044
1301
  }) : null,
1045
1302
  /* @__PURE__ */ jsx("div", {
@@ -1049,7 +1306,7 @@ function MissingModelDetailsModal(props) {
1049
1306
  onClick: () => void handleRetry(entry.documentType),
1050
1307
  disabled: retryDisabled,
1051
1308
  title: canRetry(entry.reason) ? void 0 : "No registry is configured; nothing to retry against.",
1052
- className: twMerge("min-h-[32px] rounded-xl px-3 py-1 text-sm font-semibold text-white transition-all hover:scale-105", retryDisabled ? "cursor-not-allowed bg-gray-300 hover:scale-100" : "bg-gray-800 active:opacity-75"),
1309
+ className: twMerge("min-h-[32px] rounded-xl px-3 py-1 text-sm font-semibold text-white transition-all hover:scale-105 dark:text-slate-900", retryDisabled ? "cursor-not-allowed bg-gray-300 hover:scale-100 dark:bg-slate-600 dark:text-slate-100" : "bg-gray-800 active:opacity-75 dark:bg-slate-100"),
1053
1310
  children: isRetrying ? "Retrying..." : "Try install again"
1054
1311
  })
1055
1312
  })
@@ -1062,7 +1319,7 @@ function MissingModelDetailsModal(props) {
1062
1319
  children: /* @__PURE__ */ jsx("button", {
1063
1320
  type: "button",
1064
1321
  onClick: onClose,
1065
- className: "min-h-[36px] rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm font-semibold text-slate-800 hover:bg-slate-50",
1322
+ className: "min-h-[36px] rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 dark:border-slate-500 dark:bg-slate-600 dark:text-slate-100 dark:hover:bg-slate-800",
1066
1323
  children: "Close"
1067
1324
  })
1068
1325
  })
@@ -1088,10 +1345,11 @@ function PackageInstallPrompt() {
1088
1345
  //#endregion
1089
1346
  //#region src/components/app.tsx
1090
1347
  const App = () => {
1348
+ useTheme();
1091
1349
  useEffect(() => {
1092
1350
  const handlePreloadError = (event) => {
1093
1351
  const payload = event.payload;
1094
- const failedUrl = (payload instanceof Error ? payload.message : String(payload ?? "")).match(/https?:\/\/[^\s"']+/)?.[0];
1352
+ const failedUrl = (payload instanceof Error ? payload.message : typeof payload === "string" ? payload : "").match(/https?:\/\/[^\s"']+/)?.[0];
1095
1353
  if (failedUrl && !failedUrl.startsWith(window.location.origin)) {
1096
1354
  console.debug(`[Connect] Skipping reload — vite:preloadError for off-origin URL: ${failedUrl}`);
1097
1355
  return;
@@ -1113,7 +1371,8 @@ const App = () => {
1113
1371
  /* @__PURE__ */ jsx(MissingModelBanner, {}),
1114
1372
  /* @__PURE__ */ jsx(Router, {}),
1115
1373
  /* @__PURE__ */ jsx(PackageInstallPrompt, {}),
1116
- /* @__PURE__ */ jsx(Analytics, {})
1374
+ /* @__PURE__ */ jsx(Analytics, {}),
1375
+ /* @__PURE__ */ jsx(OpenPanel, {})
1117
1376
  ] });
1118
1377
  };
1119
1378
  //#endregion
@@ -1151,8 +1410,8 @@ const CookieBanner$1 = () => {
1151
1410
  if (!showBanner) return null;
1152
1411
  return /* @__PURE__ */ jsxs("div", {
1153
1412
  className: "absolute inset-0 z-10000 backdrop-blur-sm",
1154
- children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black opacity-15" }), /* @__PURE__ */ jsx("div", {
1155
- className: "absolute inset-x-0 bottom-0 flex justify-center bg-white px-10 pt-10 pb-16 shadow-lg",
1413
+ children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gray-900 opacity-15 dark:bg-slate-50" }), /* @__PURE__ */ jsx("div", {
1414
+ className: "absolute inset-x-0 bottom-0 flex justify-center bg-gray-50 px-10 pt-10 pb-16 shadow-lg dark:bg-slate-800",
1156
1415
  children: /* @__PURE__ */ jsx(CookieBanner, {
1157
1416
  className: "max-w-[1024px]",
1158
1417
  cookies: cookiesInput,
@@ -1161,12 +1420,12 @@ const CookieBanner$1 = () => {
1161
1420
  submitLabel: t("cookieBanner.accept"),
1162
1421
  rejectLabel: t("cookieBanner.reject"),
1163
1422
  children: /* @__PURE__ */ jsx("p", {
1164
- className: "font-semibold text-gray-500",
1423
+ className: "font-semibold text-gray-500 dark:text-slate-400",
1165
1424
  children: /* @__PURE__ */ jsx(Trans, {
1166
1425
  i18nKey: "cookieBanner.message",
1167
1426
  components: { a: /* @__PURE__ */ jsx("a", {
1168
1427
  onClick: () => showPHModal({ type: "cookiesPolicy" }),
1169
- className: "cursor-pointer text-gray-900 hover:underline"
1428
+ className: "cursor-pointer text-gray-900 hover:underline dark:text-slate-50"
1170
1429
  }, "cookieBanner.message-link") }
1171
1430
  }, "cookieBanner.message")
1172
1431
  })
@@ -1345,14 +1604,14 @@ const DocumentEditor = (props) => {
1345
1604
  //#region src/components/root.tsx
1346
1605
  function Root() {
1347
1606
  return /* @__PURE__ */ jsx("div", {
1348
- className: "h-screen",
1607
+ className: "h-screen bg-gray-50 dark:bg-slate-800",
1349
1608
  children: /* @__PURE__ */ jsx("div", {
1350
1609
  className: `flex h-screen items-stretch overflow-auto`,
1351
1610
  role: "presentation",
1352
1611
  tabIndex: 0,
1353
1612
  children: /* @__PURE__ */ jsxs(Suspense, {
1354
1613
  name: "Root",
1355
- children: [/* @__PURE__ */ jsx(Sidebar, {}), /* @__PURE__ */ jsx("div", {
1614
+ children: [!useIsEmbedded() && /* @__PURE__ */ jsx(Sidebar, {}), /* @__PURE__ */ jsx("div", {
1356
1615
  className: "relative flex-1 overflow-auto",
1357
1616
  children: /* @__PURE__ */ jsx(Outlet, {})
1358
1617
  })]
@@ -1392,10 +1651,14 @@ function DriveItem({ drive }) {
1392
1651
  }
1393
1652
  function HomeScreenContainer() {
1394
1653
  const drives = useDrives();
1395
- const config = connectConfig;
1396
- return /* @__PURE__ */ jsxs(HomeScreen, { children: [drives?.map((drive) => {
1397
- return /* @__PURE__ */ jsx(DriveItem, { drive }, drive.header.id);
1398
- }), config.drives.addDriveEnabled && /* @__PURE__ */ jsx(HomeScreenAddDriveItem, {})] });
1654
+ const isAddDriveEnabled = useIsAddDriveEnabled();
1655
+ const homeBackground = getRuntimeConfig().connect?.branding?.homeBackground;
1656
+ return /* @__PURE__ */ jsxs(HomeScreen, {
1657
+ homeBackground,
1658
+ children: [drives?.map((drive) => {
1659
+ return /* @__PURE__ */ jsx(DriveItem, { drive }, drive.header.id);
1660
+ }), isAddDriveEnabled && /* @__PURE__ */ jsx(HomeScreenAddDriveItem, {})]
1661
+ });
1399
1662
  }
1400
1663
  //#endregion
1401
1664
  //#region src/components/router.tsx
@@ -1434,6 +1697,7 @@ const Router = () => {
1434
1697
  function Sidebar() {
1435
1698
  const user = useUser();
1436
1699
  const drives = useDrives();
1700
+ const isAddDriveEnabled = useIsAddDriveEnabled();
1437
1701
  const [selectedDrive] = useSelectedDriveSafe();
1438
1702
  const connectDebug = localStorage.getItem("CONNECT_DEBUG") === "true";
1439
1703
  const ensName = user?.ens?.name || user?.profile?.username || void 0;
@@ -1452,7 +1716,9 @@ function Sidebar() {
1452
1716
  onClickSettings,
1453
1717
  address: user?.address,
1454
1718
  onLogin: openRenown,
1455
- onDisconnect: logout,
1719
+ onDisconnect: () => {
1720
+ logout();
1721
+ },
1456
1722
  ensName: ensName || ensInfo.data?.ens,
1457
1723
  avatarUrl: avatarUrl || ensInfo.data?.avatar_small || ensInfo.data?.avatar_url || void 0,
1458
1724
  etherscanUrl,
@@ -1467,12 +1733,171 @@ function Sidebar() {
1467
1733
  onClick: () => setSelectedDrive(drive),
1468
1734
  active: selectedDrive?.header.id === drive.header.id,
1469
1735
  icon: /* @__PURE__ */ jsx(DriveIcon, { drive })
1470
- }, index)), connectConfig.drives.addDriveEnabled && /* @__PURE__ */ jsx(SidebarAddDriveItem, { onClick: onAddDriveClick })]
1736
+ }, index)), isAddDriveEnabled && /* @__PURE__ */ jsx(SidebarAddDriveItem, { onClick: onAddDriveClick })]
1471
1737
  })
1472
1738
  }) });
1473
1739
  }
1474
1740
  //#endregion
1475
- export { AppLoader as t };
1741
+ //#region src/components/migration-banner.tsx
1742
+ let dismissed = false;
1743
+ const listeners = /* @__PURE__ */ new Set();
1744
+ function notify() {
1745
+ for (const l of listeners) l();
1746
+ }
1747
+ function dismiss() {
1748
+ dismissed = true;
1749
+ notify();
1750
+ }
1751
+ function subscribeDismissed(cb) {
1752
+ listeners.add(cb);
1753
+ return () => {
1754
+ listeners.delete(cb);
1755
+ };
1756
+ }
1757
+ function getDismissed() {
1758
+ return dismissed;
1759
+ }
1760
+ const MigrationBanner = () => {
1761
+ const isDismissed = useSyncExternalStore(subscribeDismissed, getDismissed, () => false);
1762
+ const major = useSyncExternalStore(subscribeReactorPgMajor, getCachedReactorPgMajor, () => void 0);
1763
+ const [migrating, setMigrating] = useState(false);
1764
+ const [error, setError] = useState(null);
1765
+ if (major === void 0 || major === null || major === 17) return null;
1766
+ if (isDismissed) return null;
1767
+ const handleMigrate = () => {
1768
+ setError(null);
1769
+ setMigrating(true);
1770
+ migrateAllIfNeeded().then(() => {
1771
+ window.location.reload();
1772
+ }).catch((err) => {
1773
+ setError(err instanceof Error ? err.message : String(err));
1774
+ setMigrating(false);
1775
+ });
1776
+ };
1777
+ return /* @__PURE__ */ jsx("div", {
1778
+ className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1779
+ children: /* @__PURE__ */ jsxs("div", {
1780
+ className: "flex max-w-3xl items-center gap-3 rounded-lg border border-yellow-500 bg-yellow-400 px-4 py-3 text-sm text-gray-900 shadow-lg dark:border-yellow-400 dark:bg-yellow-500 dark:text-slate-50",
1781
+ children: [
1782
+ /* @__PURE__ */ jsxs("div", {
1783
+ className: "flex-1",
1784
+ children: [
1785
+ /* @__PURE__ */ jsxs("div", {
1786
+ className: "font-semibold",
1787
+ children: [
1788
+ "Your local database uses Postgres ",
1789
+ major,
1790
+ "."
1791
+ ]
1792
+ }),
1793
+ /* @__PURE__ */ jsxs("div", {
1794
+ className: "text-gray-900 dark:text-slate-100",
1795
+ children: [
1796
+ "Migrate to Postgres ",
1797
+ 17,
1798
+ " to pick up the latest features. Your data will be backed up first."
1799
+ ]
1800
+ }),
1801
+ error && /* @__PURE__ */ jsxs("div", {
1802
+ className: "mt-2 font-medium text-red-900 dark:text-red-400",
1803
+ children: ["Migration failed: ", error]
1804
+ })
1805
+ ]
1806
+ }),
1807
+ /* @__PURE__ */ jsx("button", {
1808
+ type: "button",
1809
+ disabled: migrating,
1810
+ onClick: handleMigrate,
1811
+ className: "rounded-sm bg-gray-900 px-3 py-1 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-100",
1812
+ children: migrating ? "Migrating…" : "Migrate now"
1813
+ }),
1814
+ /* @__PURE__ */ jsx("button", {
1815
+ type: "button",
1816
+ disabled: migrating,
1817
+ onClick: dismiss,
1818
+ className: "rounded-sm border border-gray-900 bg-transparent px-3 py-1 text-sm font-medium text-gray-900 hover:bg-gray-900/10 disabled:opacity-50 dark:border-slate-50 dark:text-slate-50",
1819
+ children: "Dismiss"
1820
+ })
1821
+ ]
1822
+ })
1823
+ });
1824
+ };
1825
+ //#endregion
1826
+ //#region src/components/modal/modals-container.tsx
1827
+ const AddDriveModal$1 = lazy(() => import("./AddDriveModal-kzL41qdg.js").then((m) => ({ default: m.AddDriveModal })));
1828
+ const ClearStorageModal = lazy(() => import("./ClearStorageModal-DIKwqiia.js").then((m) => ({ default: m.ClearStorageModal })));
1829
+ const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-1nOh6oN3.js").then((m) => ({ default: m.CookiesPolicyModal })));
1830
+ const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-nQbLVDq3.js").then((m) => ({ default: m.CreateDocumentModal })));
1831
+ const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-DoY0auxt.js").then((m) => ({ default: m.DebugSettingsModal })));
1832
+ const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-6P0T1QgD.js").then((m) => ({ default: m.DeleteDriveModal })));
1833
+ const DeleteItemModal = lazy(() => import("./DeleteItemModal-BmV1aQyZ.js").then((m) => ({ default: m.DeleteItemModal })));
1834
+ const DisclaimerModal = lazy(() => import("./DisclaimerModal-CVTFfN0_.js").then((m) => ({ default: m.DisclaimerModal })));
1835
+ const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-L5sM-rIh.js").then((m) => ({ default: m.DriveSettingsModal })));
1836
+ const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-CXeFUtaz.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1837
+ const SettingsModal$1 = lazy(() => import("./SettingsModal-B4BiV0hg.js").then((m) => ({ default: m.SettingsModal })));
1838
+ const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-CyAUDCU7.js").then((m) => ({ default: m.UpgradeDriveModal })));
1839
+ const modalComponents = {
1840
+ addDrive: AddDriveModal$1,
1841
+ clearStorage: ClearStorageModal,
1842
+ cookiesPolicy: CookiesPolicyModal,
1843
+ createDocument: CreateDocumentModal$1,
1844
+ debugSettings: DebugSettingsModal,
1845
+ deleteDrive: DeleteDriveModal,
1846
+ deleteItem: DeleteItemModal,
1847
+ disclaimer: DisclaimerModal,
1848
+ driveSettings: DriveSettingsModal$1,
1849
+ downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
1850
+ inspector: lazy(() => import("./InspectorModal-C7pIf6OO.js").then((m) => ({ default: m.InspectorModal }))),
1851
+ settings: SettingsModal$1,
1852
+ upgradeDrive: UpgradeDriveModal,
1853
+ missingPackage: lazy(() => import("./MissingPackageModal-D_N96M6a.js").then((m) => ({ default: m.ConnectMissingPackageModal })))
1854
+ };
1855
+ const ModalsContainer = lazy(() => {
1856
+ return Promise.resolve({ default: () => {
1857
+ const phModal = usePHModal();
1858
+ if (!phModal?.type) return null;
1859
+ const ModalComponent = modalComponents[phModal.type];
1860
+ return ModalComponent ? /* @__PURE__ */ jsx(ErrorBoundary$1, {
1861
+ variant: "silent",
1862
+ loggerContext: ["Connect", "Modals"],
1863
+ children: /* @__PURE__ */ jsx(Suspense, {
1864
+ fallback: null,
1865
+ children: /* @__PURE__ */ jsx(ModalComponent, {})
1866
+ })
1867
+ }) : null;
1868
+ } });
1869
+ });
1870
+ //#endregion
1871
+ //#region src/components/app-loader.tsx
1872
+ const AppLoader = (props) => {
1873
+ const Load = lazy(() => import("./load-Cs4KcEw0.js").then((m) => m.loadComponent(props.localPackage)));
1874
+ return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
1875
+ fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
1876
+ resetKeys: [props.localPackage],
1877
+ loggerContext: ["Connect"],
1878
+ children: [
1879
+ /* @__PURE__ */ jsx(Suspense, {
1880
+ fallback: /* @__PURE__ */ jsx(AppSkeleton, {}),
1881
+ name: "AppLoader",
1882
+ children: /* @__PURE__ */ jsx(Load, {
1883
+ ...props,
1884
+ children: /* @__PURE__ */ jsx(App, {})
1885
+ })
1886
+ }),
1887
+ /* @__PURE__ */ jsx(Suspense, {
1888
+ name: "CookieBanner",
1889
+ children: /* @__PURE__ */ jsx(CookieBanner$1, {})
1890
+ }),
1891
+ /* @__PURE__ */ jsx(Suspense, {
1892
+ name: "ModalsContainer",
1893
+ children: /* @__PURE__ */ jsx(ModalsContainer, {})
1894
+ }),
1895
+ /* @__PURE__ */ jsx(MigrationBanner, {})
1896
+ ]
1897
+ }) });
1898
+ };
1899
+ //#endregion
1900
+ export { DocumentEditor as a, App as c, DocumentEditorContainer as d, OpenPanel as f, Root as i, AppContainer as l, AppSkeleton as m, Sidebar as n, DriveIcon as o, Analytics as p, Router as r, CookieBanner$1 as s, AppLoader as t, EditorLoader as u };
1476
1901
 
1477
- //# sourceMappingURL=sidebar-BLHOoVIg.js.map
1478
- //# debugId=ebf04d37-dff0-53fa-872d-097855e3824e
1902
+ //# sourceMappingURL=app-loader-DCYDK6hq.js.map
1903
+ //# debugId=ecb0fae1-8b49-5b4b-b37b-86f2feb9a9b6