@powerhousedao/connect 6.2.0-dev.4 → 6.2.0-dev.40

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 (79) hide show
  1. package/dist/{AddDriveModal-kzL41qdg.js → AddDriveModal-D-nbV40j.js} +5 -8
  2. package/dist/{AddDriveModal-kzL41qdg.js.map → AddDriveModal-D-nbV40j.js.map} +1 -1
  3. package/dist/{ClearStorageModal-BSNg-Ymg.js → ClearStorageModal-Cl9fxCul.js} +4 -4
  4. package/dist/{ClearStorageModal-BSNg-Ymg.js.map → ClearStorageModal-Cl9fxCul.js.map} +1 -1
  5. package/dist/{CookiesPolicyModal-1nOh6oN3.js → CookiesPolicyModal-CkcUKPLb.js} +3 -3
  6. package/dist/{CookiesPolicyModal-1nOh6oN3.js.map → CookiesPolicyModal-CkcUKPLb.js.map} +1 -1
  7. package/dist/{CreateDocumentModal-nQbLVDq3.js → CreateDocumentModal-CvsTh0HM.js} +3 -3
  8. package/dist/{CreateDocumentModal-nQbLVDq3.js.map → CreateDocumentModal-CvsTh0HM.js.map} +1 -1
  9. package/dist/{DebugSettingsModal-D4Mk5SmY.js → DebugSettingsModal-iBk2t1kf.js} +10 -10
  10. package/dist/DebugSettingsModal-iBk2t1kf.js.map +1 -0
  11. package/dist/{DeleteDriveModal-6P0T1QgD.js → DeleteDriveModal-DSTK8FYk.js} +4 -4
  12. package/dist/{DeleteDriveModal-6P0T1QgD.js.map → DeleteDriveModal-DSTK8FYk.js.map} +1 -1
  13. package/dist/{DeleteItemModal-BmV1aQyZ.js → DeleteItemModal-B2nJmjsP.js} +4 -4
  14. package/dist/{DeleteItemModal-BmV1aQyZ.js.map → DeleteItemModal-B2nJmjsP.js.map} +1 -1
  15. package/dist/{DisclaimerModal-CVTFfN0_.js → DisclaimerModal-D5FO34u9.js} +3 -3
  16. package/dist/{DisclaimerModal-CVTFfN0_.js.map → DisclaimerModal-D5FO34u9.js.map} +1 -1
  17. package/dist/{DownloadDocumentWithErrorsModal-CXeFUtaz.js → DownloadDocumentWithErrorsModal-tEr3bbtN.js} +3 -3
  18. package/dist/{DownloadDocumentWithErrorsModal-CXeFUtaz.js.map → DownloadDocumentWithErrorsModal-tEr3bbtN.js.map} +1 -1
  19. package/dist/DriveAuthRequiredModal-B5-ZfKsb.js +36 -0
  20. package/dist/DriveAuthRequiredModal-B5-ZfKsb.js.map +1 -0
  21. package/dist/{DriveSettingsModal-L5sM-rIh.js → DriveSettingsModal-kR3hQnh4.js} +5 -5
  22. package/dist/DriveSettingsModal-kR3hQnh4.js.map +1 -0
  23. package/dist/{InspectorModal-DyrVQ4fu.js → InspectorModal-D5OMGJBP.js} +84 -35
  24. package/dist/InspectorModal-D5OMGJBP.js.map +1 -0
  25. package/dist/{MissingPackageModal-D_N96M6a.js → MissingPackageModal-BQcCQbOn.js} +4 -4
  26. package/dist/{MissingPackageModal-D_N96M6a.js.map → MissingPackageModal-BQcCQbOn.js.map} +1 -1
  27. package/dist/{SettingsModal-NqDM9cwJ.js → SettingsModal-D58SPZbC.js} +36 -43
  28. package/dist/SettingsModal-D58SPZbC.js.map +1 -0
  29. package/dist/{UpgradeDriveModal-CyAUDCU7.js → UpgradeDriveModal-BZGSE9_r.js} +3 -3
  30. package/dist/{UpgradeDriveModal-CyAUDCU7.js.map → UpgradeDriveModal-BZGSE9_r.js.map} +1 -1
  31. package/dist/{app-loader-DxoMZXTL.js → app-loader-6NP0KBww.js} +241 -286
  32. package/dist/app-loader-6NP0KBww.js.map +1 -0
  33. package/dist/app-loader-CH_NJYxf.js +4 -0
  34. package/dist/{build-info-CL8h_tYH.js → build-info-CdzDJjSq.js} +8 -5
  35. package/dist/{build-info-CL8h_tYH.js.map → build-info-CdzDJjSq.js.map} +1 -1
  36. package/dist/components-DZ8ahFEH.js +5 -0
  37. package/dist/{connect.config-aPx3rHZQ.js → connect.config-BG681xG9.js} +9 -5
  38. package/dist/connect.config-BG681xG9.js.map +1 -0
  39. package/dist/connection-state-Cig644T0.js +126 -0
  40. package/dist/connection-state-Cig644T0.js.map +1 -0
  41. package/dist/{load-BLx_riHu.js → load-EfgIfQ14.js} +11 -11
  42. package/dist/{load-BLx_riHu.js.map → load-EfgIfQ14.js.map} +1 -1
  43. package/dist/main.js +1 -1
  44. package/dist/{package-Bcan1Erm.js → package-A7bYtenR.js} +7 -5
  45. package/dist/package-A7bYtenR.js.map +1 -0
  46. package/dist/{pglite-runtime-toc1-TWa.js → pglite-major-B39aOEiE.js} +8 -51
  47. package/dist/pglite-major-B39aOEiE.js.map +1 -0
  48. package/dist/pglite-migrate-core-Boxqqx-c.js +143 -0
  49. package/dist/pglite-migrate-core-Boxqqx-c.js.map +1 -0
  50. package/dist/{pglite-seed-D8oSKkep.js → pglite-seed-9rjhdCs5.js} +4 -4
  51. package/dist/{pglite-seed-D8oSKkep.js.map → pglite-seed-9rjhdCs5.js.map} +1 -1
  52. package/dist/{reactor-RZaraEfU.js → reactor-DPkyKOCH.js} +239 -36
  53. package/dist/reactor-DPkyKOCH.js.map +1 -0
  54. package/dist/reactor.worker.d.ts +1 -0
  55. package/dist/reactor.worker.js +316 -0
  56. package/dist/reactor.worker.js.map +1 -0
  57. package/dist/{registerServiceWorker-B7uKpkci.js → registerServiceWorker-2tRbkdJj.js} +4 -4
  58. package/dist/{registerServiceWorker-B7uKpkci.js.map → registerServiceWorker-2tRbkdJj.js.map} +1 -1
  59. package/dist/{reload-connect-toast-CwvSc6F-.js → reload-connect-toast-qibmlgQm.js} +3 -3
  60. package/dist/{reload-connect-toast-CwvSc6F-.js.map → reload-connect-toast-qibmlgQm.js.map} +1 -1
  61. package/dist/start-connect.js +1 -1
  62. package/dist/style.css +851 -2392
  63. package/dist/{toast-BEy42aYx.js → toast-4t-VimvD.js} +3 -3
  64. package/dist/{toast-BEy42aYx.js.map → toast-4t-VimvD.js.map} +1 -1
  65. package/dist/{useRegistryPackages-Bh0luCvV.js → useRegistryPackages-BaYtekjQ.js} +44 -8
  66. package/dist/useRegistryPackages-BaYtekjQ.js.map +1 -0
  67. package/package.json +13 -11
  68. package/dist/DebugSettingsModal-D4Mk5SmY.js.map +0 -1
  69. package/dist/DriveSettingsModal-L5sM-rIh.js.map +0 -1
  70. package/dist/InspectorModal-DyrVQ4fu.js.map +0 -1
  71. package/dist/SettingsModal-NqDM9cwJ.js.map +0 -1
  72. package/dist/app-loader-B0Va8NxF.js +0 -4
  73. package/dist/app-loader-DxoMZXTL.js.map +0 -1
  74. package/dist/components-Dd4Xq0Cj.js +0 -5
  75. package/dist/connect.config-aPx3rHZQ.js.map +0 -1
  76. package/dist/package-Bcan1Erm.js.map +0 -1
  77. package/dist/pglite-runtime-toc1-TWa.js.map +0 -1
  78. package/dist/reactor-RZaraEfU.js.map +0 -1
  79. package/dist/useRegistryPackages-Bh0luCvV.js.map +0 -1
@@ -1,18 +1,19 @@
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]="e428717e-ea15-57ae-b56b-d3f820f6d77c")}catch(e){}}();
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]="3ad5ed01-1906-5e34-87e1-a4d5b03fb8d0")}catch(e){}}();
3
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";
4
+ import { c as idbError } from "./pglite-major-B39aOEiE.js";
5
+ import { n as cloneFileData, r as migrateIdb } from "./pglite-migrate-core-Boxqqx-c.js";
6
+ import { n as i18n } from "./reload-connect-toast-qibmlgQm.js";
7
+ import { a as defaultPHDocumentEditorConfig, i as defaultPHAppConfig, r as connectConfig } from "./connect.config-BG681xG9.js";
8
+ import { f as PRIMARY_IDB_NAMES, r as subscribeWorkerConnection, s as getCachedMigrationMajor, t as getWorkerConnectionStatus, u as subscribeMigrationMajor } from "./connection-state-Cig644T0.js";
9
+ import { t as serviceWorkerManager } from "./registerServiceWorker-2tRbkdJj.js";
10
+ import { n as toast, t as ToastContainer } from "./toast-4t-VimvD.js";
9
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
- import { PGlite } from "@electric-sql/pglite";
11
12
  import { Trans, useTranslation } from "react-i18next";
12
13
  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 { DriveCollectionId, getRevisionFromDate, initTheme, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useConnectionStates, 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
15
  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 { ConnectSidebar, ConnectTooltipProvider, CookieBanner, DefaultEditorLoader, DriveAuthGate, DropZoneWrapper, HomeScreen, HomeScreenAddDriveItem, HomeScreenItem, LogoAnimation, PackageInstallModal, RevisionHistory, SidebarAddDriveItem, SidebarItem, useEns } from "@powerhousedao/design-system/connect";
16
17
  import { z } from "zod";
17
18
  import { Outlet, RouterProvider, createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
18
19
  import { useHotkeys } from "react-hotkeys-hook";
@@ -76,18 +77,18 @@ var DocumentEditorDebugTools = class {
76
77
  //#endregion
77
78
  //#region src/components/migration-status.ts
78
79
  let current = null;
79
- const listeners$3 = /* @__PURE__ */ new Set();
80
+ const listeners$2 = /* @__PURE__ */ new Set();
80
81
  function setMigrationStatus(status) {
81
82
  current = status;
82
- for (const l of listeners$3) l();
83
+ for (const l of listeners$2) l();
83
84
  }
84
85
  function getMigrationStatus() {
85
86
  return current;
86
87
  }
87
88
  function subscribeMigrationStatus(cb) {
88
- listeners$3.add(cb);
89
+ listeners$2.add(cb);
89
90
  return () => {
90
- listeners$3.delete(cb);
91
+ listeners$2.delete(cb);
91
92
  };
92
93
  }
93
94
  //#endregion
@@ -95,18 +96,6 @@ function subscribeMigrationStatus(cb) {
95
96
  const BACKUP_PREFIX = "ph-pglite-backup::";
96
97
  const BACKUP_INDEX_KEY = "ph:pglite-backups";
97
98
  const BACKUP_RETENTION_MS = 720 * 60 * 60 * 1e3;
98
- const LEGACY_DUMPERS = { 16: async () => {
99
- const [{ PGlite: LegacyPGlite }, { pgDump }] = await Promise.all([import("pglite-legacy-02"), import("pglite-tools-legacy-02/pg_dump")]);
100
- return async (idbName) => {
101
- const pg = new LegacyPGlite(`idb://${idbName.replace(/^\/pglite\//, "")}`);
102
- try {
103
- await pg.waitReady;
104
- return await (await pgDump({ pg })).text();
105
- } finally {
106
- await pg.close();
107
- }
108
- };
109
- } };
110
99
  function deleteIdb(name, timeoutMs = 15e3) {
111
100
  return new Promise((resolve, reject) => {
112
101
  const req = indexedDB.deleteDatabase(name);
@@ -127,56 +116,6 @@ function deleteIdb(name, timeoutMs = 15e3) {
127
116
  });
128
117
  });
129
118
  }
130
- async function clearFileData(name) {
131
- const db = await openIdb(name, 21, createFileDataStore);
132
- try {
133
- await new Promise((resolve, reject) => {
134
- const tx = db.transaction(IDB_STORE_NAME, "readwrite");
135
- tx.oncomplete = () => resolve();
136
- tx.onerror = () => reject(idbError(tx, `FILE_DATA clear failed for ${name}`));
137
- tx.onabort = () => reject(idbError(tx, `FILE_DATA clear aborted for ${name}`));
138
- tx.objectStore(IDB_STORE_NAME).clear();
139
- });
140
- } finally {
141
- db.close();
142
- }
143
- }
144
- async function cloneFileData(sourceName, destName) {
145
- const source = await openIdb(sourceName, 21, createFileDataStore);
146
- try {
147
- const dest = await openIdb(destName, 21, createFileDataStore);
148
- try {
149
- const readStore = source.transaction(IDB_STORE_NAME, "readonly").objectStore(IDB_STORE_NAME);
150
- const entries = await new Promise((resolve, reject) => {
151
- const out = [];
152
- const req = readStore.openCursor();
153
- req.onerror = () => reject(idbError(req, `FILE_DATA read cursor failed for ${sourceName}`));
154
- req.onsuccess = () => {
155
- const cursor = req.result;
156
- if (!cursor) return resolve(out);
157
- out.push({
158
- key: cursor.key,
159
- value: cursor.value
160
- });
161
- cursor.continue();
162
- };
163
- });
164
- await new Promise((resolve, reject) => {
165
- const writeTx = dest.transaction(IDB_STORE_NAME, "readwrite");
166
- writeTx.oncomplete = () => resolve();
167
- writeTx.onerror = () => reject(idbError(writeTx, `FILE_DATA write failed for ${destName}`));
168
- writeTx.onabort = () => reject(idbError(writeTx, `FILE_DATA write aborted for ${destName}`));
169
- const writeStore = writeTx.objectStore(IDB_STORE_NAME);
170
- writeStore.clear();
171
- for (const { key, value } of entries) writeStore.put(value, key);
172
- });
173
- } finally {
174
- dest.close();
175
- }
176
- } finally {
177
- source.close();
178
- }
179
- }
180
119
  function readBackupIndex() {
181
120
  try {
182
121
  const raw = localStorage.getItem(BACKUP_INDEX_KEY);
@@ -215,101 +154,47 @@ async function janitor() {
215
154
  }
216
155
  writeBackupIndex(keep);
217
156
  }
218
- function publishPhase(idbName, phase) {
219
- setMigrationStatus({
220
- idbName,
221
- phase
222
- });
223
- }
224
- async function migrateIdbIfNeeded(idbName) {
225
- const major = await readPgVersionFile(idbName);
226
- if (major === null || major === 17) return;
227
- const loader = LEGACY_DUMPERS[major];
228
- if (!loader) throw new Error(`Unsupported legacy PGlite data dir: PG_VERSION=${major} for ${idbName}`);
229
- const backupName = `${BACKUP_PREFIX}${idbName}::${(/* @__PURE__ */ new Date()).toISOString()}`;
230
- const backupRec = {
231
- name: backupName,
232
- idbName,
233
- createdAt: Date.now()
234
- };
235
- publishPhase(idbName, "clone");
236
- await cloneFileData(idbName, backupName);
237
- registerBackup(backupRec);
238
- let sql;
239
- try {
240
- publishPhase(idbName, "dump");
241
- sql = await (await loader())(idbName);
242
- } catch (err) {
243
- await deleteIdb(backupName).catch(() => {});
244
- forgetBackup(backupName);
245
- throw err;
246
- }
247
- try {
248
- await clearFileData(idbName);
249
- publishPhase(idbName, "restore");
250
- const pg = new PGlite(`idb://${idbName.replace(/^\/pglite\//, "")}`, { relaxedDurability: false });
251
- try {
252
- await pg.waitReady;
253
- console.info(`[pglite-migration] Dump preamble (first 500 chars):\n${sql.slice(0, 500)}`);
254
- try {
255
- await pg.exec("SET standard_conforming_strings = off;");
256
- } catch (gucErr) {
257
- console.warn("[pglite-migration] Could not force standard_conforming_strings=off", gucErr);
258
- }
157
+ function createPersistentBackup() {
158
+ return {
159
+ snapshot: async (idbName) => {
160
+ const backupName = `${BACKUP_PREFIX}${idbName}::${(/* @__PURE__ */ new Date()).toISOString()}`;
161
+ await cloneFileData(idbName, backupName);
162
+ registerBackup({
163
+ name: backupName,
164
+ idbName,
165
+ createdAt: Date.now()
166
+ });
167
+ return backupName;
168
+ },
169
+ rollback: async (handle, idbName, cause) => {
170
+ const backupName = handle;
259
171
  try {
260
- await pg.exec(sql);
261
- } catch (execErr) {
262
- logRestoreFailure(idbName, sql, execErr);
263
- throw execErr;
172
+ await cloneFileData(backupName, idbName);
173
+ } catch (rollbackErr) {
174
+ console.error(`PGlite migration rollback failed for ${idbName}; backup ${backupName} retained. Primary migration error:`, cause, "Rollback error:", rollbackErr);
175
+ return;
264
176
  }
265
- } finally {
266
- await pg.close();
267
- }
268
- } catch (err) {
269
- await rollbackFromBackup(idbName, backupName, err);
270
- throw err;
271
- }
177
+ await deleteIdb(backupName).catch(() => void 0);
178
+ forgetBackup(backupName);
179
+ },
180
+ discard: async (handle) => {
181
+ const backupName = handle;
182
+ await deleteIdb(backupName).catch(() => void 0);
183
+ forgetBackup(backupName);
184
+ },
185
+ commit: () => Promise.resolve()
186
+ };
272
187
  }
273
- function logRestoreFailure(idbName, sql, err) {
274
- const errObj = err;
275
- const position = typeof errObj.position === "string" ? parseInt(errObj.position, 10) : typeof errObj.position === "number" ? errObj.position : NaN;
276
- console.error(`[pglite-migration] Restore failed for ${idbName}`, {
277
- message: errObj.message,
278
- code: errObj.code,
279
- severity: errObj.severity,
280
- detail: errObj.detail,
281
- where: errObj.where,
282
- position: errObj.position,
283
- sqlLength: sql.length
284
- });
285
- if (Number.isFinite(position) && position > 0) {
286
- const zeroBased = position - 1;
287
- const start = Math.max(0, zeroBased - 200);
288
- const end = Math.min(sql.length, zeroBased + 200);
289
- const before = sql.slice(start, zeroBased);
290
- const at = sql.slice(zeroBased, zeroBased + 1);
291
- const after = sql.slice(zeroBased + 1, end);
292
- console.error(`[pglite-migration] SQL context around position ${position}:\n${before}»${at}«${after}`);
293
- const lineStart = sql.lastIndexOf("\n", zeroBased) + 1;
294
- const lineEnd = sql.indexOf("\n", zeroBased);
295
- const line = sql.slice(lineStart, lineEnd === -1 ? sql.length : lineEnd);
296
- console.error(`[pglite-migration] Failing line (truncated to 500 chars):\n${line.slice(0, 500)}`);
297
- } else console.error(`[pglite-migration] No position info. First 2000 chars of dump:\n${sql.slice(0, 2e3)}`);
298
- }
299
- async function rollbackFromBackup(idbName, backupName, originalError) {
188
+ async function migrateAllLocked() {
189
+ const backup = createPersistentBackup();
300
190
  try {
301
- await clearFileData(idbName).catch(() => {});
302
- await cloneFileData(backupName, idbName);
303
- } catch (rollbackErr) {
304
- console.error(`PGlite migration failed AND rollback failed for ${idbName}. Primary error:`, originalError, "Rollback error:", rollbackErr);
305
- return;
191
+ for (const idbName of PRIMARY_IDB_NAMES) await migrateIdb(idbName, (phase) => setMigrationStatus({
192
+ idbName,
193
+ phase
194
+ }), backup);
195
+ } finally {
196
+ setMigrationStatus(null);
306
197
  }
307
- await deleteIdb(backupName).catch(() => {});
308
- forgetBackup(backupName);
309
- }
310
- async function migrateAllLocked() {
311
- for (const idbName of PRIMARY_IDB_NAMES) await migrateIdbIfNeeded(idbName);
312
- setMigrationStatus(null);
313
198
  }
314
199
  async function migrateAllIfNeeded() {
315
200
  janitor().catch((err) => console.warn("PGlite backup janitor failed", err));
@@ -324,7 +209,7 @@ async function migrateAllIfNeeded() {
324
209
  //#endregion
325
210
  //#region src/hooks/useAcceptedCookies.ts
326
211
  const ACCEPTED_COOKIES_KEY_STORAGE = `${connectConfig.routerBasename}:acceptedCookies`;
327
- const listeners$2 = /* @__PURE__ */ new Set();
212
+ const listeners$1 = /* @__PURE__ */ new Set();
328
213
  let cookies = getInitial$1();
329
214
  function getInitial$1() {
330
215
  try {
@@ -348,11 +233,11 @@ function getCookies() {
348
233
  function setCookies(setter) {
349
234
  cookies = setter(cookies);
350
235
  localStorage.setItem(ACCEPTED_COOKIES_KEY_STORAGE, JSON.stringify(cookies));
351
- listeners$2.forEach((fn) => fn());
236
+ listeners$1.forEach((fn) => fn());
352
237
  }
353
238
  function subscribe$1(fn) {
354
- listeners$2.add(fn);
355
- return () => listeners$2.delete(fn);
239
+ listeners$1.add(fn);
240
+ return () => listeners$1.delete(fn);
356
241
  }
357
242
  const useAcceptedCookies = () => {
358
243
  return [useSyncExternalStore(subscribe$1, getCookies, getCookies), setCookies];
@@ -602,7 +487,7 @@ function useIsEmbedded() {
602
487
  return getIsEmbedded();
603
488
  }
604
489
  const COOKIE_BANNER_KEY_STORAGE = `${connectConfig.routerBasename}:display-cookie-banner`;
605
- const listeners$1 = /* @__PURE__ */ new Set();
490
+ const listeners = /* @__PURE__ */ new Set();
606
491
  let bannerShown = getInitial();
607
492
  function getInitial() {
608
493
  if (getIsEmbedded()) return false;
@@ -621,8 +506,8 @@ function setCookieBannerState(state) {
621
506
  localStorage.setItem(COOKIE_BANNER_KEY_STORAGE, JSON.stringify(state));
622
507
  }
623
508
  function subscribe(fn) {
624
- listeners$1.add(fn);
625
- return () => listeners$1.delete(fn);
509
+ listeners.add(fn);
510
+ return () => listeners.delete(fn);
626
511
  }
627
512
  const useCookieBanner = () => {
628
513
  return [useSyncExternalStore(subscribe, getCookieBannerState, getCookieBannerState), setCookieBannerState];
@@ -743,12 +628,12 @@ const MigrationOverlay = () => {
743
628
  return /* @__PURE__ */ jsx("div", {
744
629
  className: "absolute inset-0 z-20 flex items-center justify-center",
745
630
  children: /* @__PURE__ */ jsxs("div", {
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",
631
+ className: "rounded-lg bg-card/90 px-6 py-4 text-sm text-foreground shadow-lg",
747
632
  children: [/* @__PURE__ */ jsx("div", {
748
633
  className: "font-medium",
749
634
  children: "Upgrading local database…"
750
635
  }), /* @__PURE__ */ jsx("div", {
751
- className: "text-gray-700 dark:text-slate-200",
636
+ className: "text-foreground",
752
637
  children: PHASE_LABEL[status.phase]
753
638
  })]
754
639
  })
@@ -780,7 +665,7 @@ const AppSkeleton = (props) => {
780
665
  const isSSR = typeof window === "undefined";
781
666
  const isHomeScreen = !isSSR && window.location.pathname === getBasePath();
782
667
  return /* @__PURE__ */ jsxs("div", {
783
- className: "flex h-screen overflow-hidden bg-gray-50 dark:bg-slate-700",
668
+ className: "flex h-screen overflow-hidden bg-background",
784
669
  children: [
785
670
  !(!isSSR && getIsEmbedded()) && /* @__PURE__ */ jsx(ConnectSidebar, {
786
671
  className: "animate-pulse",
@@ -790,7 +675,7 @@ const AppSkeleton = (props) => {
790
675
  address: void 0
791
676
  }),
792
677
  /* @__PURE__ */ jsx(HomeScreen, {
793
- containerClassName: isSSR || !isHomeScreen ? "hidden home-screen" : void 0,
678
+ containerClassName: isSSR || !isHomeScreen ? "home-screen hidden" : void 0,
794
679
  children: props.children ?? null
795
680
  }),
796
681
  isSSR ? /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: `
@@ -835,7 +720,7 @@ function DetailedFallback({ error, resetErrorBoundary }) {
835
720
  return /* @__PURE__ */ jsx("div", {
836
721
  className: "z-10 mx-auto flex max-w-[80%] flex-1 items-center justify-center p-6",
837
722
  children: /* @__PURE__ */ jsxs("div", {
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",
723
+ className: "w-full max-w-lg rounded-lg border border-border bg-background p-6 shadow-sm",
839
724
  children: [
840
725
  /* @__PURE__ */ jsxs("div", {
841
726
  className: "mb-3 flex items-center gap-2",
@@ -848,16 +733,16 @@ function DetailedFallback({ error, resetErrorBoundary }) {
848
733
  })]
849
734
  }),
850
735
  /* @__PURE__ */ jsx("p", {
851
- className: "mb-4 text-sm text-gray-700 dark:text-slate-200",
736
+ className: "mb-4 text-sm text-foreground",
852
737
  children: errorMessage
853
738
  }),
854
739
  errorDetails !== "{}" && /* @__PURE__ */ jsxs("details", {
855
740
  className: "group",
856
741
  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",
742
+ className: "cursor-pointer text-sm font-medium text-foreground underline select-none hover:hover-effect",
858
743
  children: "Show details"
859
744
  }), /* @__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",
745
+ className: "mt-2 max-h-48 overflow-auto rounded-sm bg-muted p-3 text-xs",
861
746
  children: errorDetails
862
747
  })]
863
748
  }),
@@ -1071,7 +956,8 @@ function buildIdentifyPayload(user) {
1071
956
  function OpenPanel() {
1072
957
  const [{ analytics }] = useAcceptedCookies();
1073
958
  const user = useUser();
1074
- const reactorClientModule = useReactorClientModule();
959
+ const module = useReactorClientModule();
960
+ const reactorClientModule = module?.kind === "browser" ? module : void 0;
1075
961
  const [client, setClient] = useState();
1076
962
  /**
1077
963
  * Tracks the previous `user` value so we can detect the two transitions:
@@ -1219,11 +1105,11 @@ function MissingModelBanner() {
1219
1105
  const [open, setOpen] = useState(false);
1220
1106
  if (failed.length === 0) return null;
1221
1107
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
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",
1108
+ className: "flex items-center justify-between gap-3 bg-warning/10 px-4 py-2 text-sm text-warning",
1223
1109
  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", {
1224
1110
  type: "button",
1225
1111
  onClick: () => setOpen(true),
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",
1112
+ className: "rounded-md border border-warning bg-background px-3 py-1 text-warning hover:hover-effect",
1227
1113
  children: "View"
1228
1114
  })]
1229
1115
  }), /* @__PURE__ */ jsx(MissingModelDetailsModal, {
@@ -1256,18 +1142,18 @@ function MissingModelDetailsModal(props) {
1256
1142
  },
1257
1143
  contentProps: { className: "rounded-3xl" },
1258
1144
  children: /* @__PURE__ */ jsxs("div", {
1259
- className: "w-[520px] max-w-[90vw] bg-gray-50 p-6 dark:bg-slate-800",
1145
+ className: "w-[520px] max-w-[90vw] bg-background p-6",
1260
1146
  children: [
1261
1147
  /* @__PURE__ */ jsx("div", {
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",
1148
+ className: "border-b border-border pb-2 text-2xl font-bold text-foreground",
1263
1149
  children: "Missing document models"
1264
1150
  }),
1265
1151
  /* @__PURE__ */ jsx("div", {
1266
- className: "my-4 text-sm text-gray-700 dark:text-slate-200",
1152
+ className: "my-4 text-sm text-foreground",
1267
1153
  children: "The following document types couldn't be loaded. Documents using them won't display until the underlying package is installed."
1268
1154
  }),
1269
1155
  failed.length === 0 ? /* @__PURE__ */ jsx("div", {
1270
- className: "rounded-xl bg-gray-50 p-4 text-sm text-gray-700 dark:bg-slate-800 dark:text-slate-200",
1156
+ className: "rounded-xl bg-background p-4 text-sm text-foreground",
1271
1157
  children: "No outstanding failures."
1272
1158
  }) : /* @__PURE__ */ jsx("div", {
1273
1159
  className: "flex max-h-[60vh] flex-col gap-3 overflow-y-auto",
@@ -1275,18 +1161,18 @@ function MissingModelDetailsModal(props) {
1275
1161
  const isRetrying = retrying.has(entry.documentType);
1276
1162
  const retryDisabled = !canRetry(entry.reason) || isRetrying;
1277
1163
  return /* @__PURE__ */ jsxs("div", {
1278
- className: "rounded-xl bg-gray-50 p-4 dark:bg-slate-800",
1164
+ className: "rounded-xl bg-background p-4",
1279
1165
  children: [
1280
1166
  /* @__PURE__ */ jsx("div", {
1281
- className: "mb-1 font-mono text-sm font-semibold text-gray-900 dark:text-slate-100",
1167
+ className: "mb-1 font-mono text-sm font-semibold text-foreground",
1282
1168
  children: entry.documentType
1283
1169
  }),
1284
1170
  /* @__PURE__ */ jsx("div", {
1285
- className: "mb-2 text-xs text-gray-700 dark:text-slate-200",
1171
+ className: "mb-2 text-xs text-foreground",
1286
1172
  children: reasonLabels[entry.reason]
1287
1173
  }),
1288
1174
  entry.packageNames.length > 0 ? /* @__PURE__ */ jsxs("div", {
1289
- className: "mb-2 text-xs text-gray-500 dark:text-slate-400",
1175
+ className: "mb-2 text-xs text-muted-foreground",
1290
1176
  children: [
1291
1177
  "Package",
1292
1178
  entry.packageNames.length > 1 ? "s" : "",
@@ -1296,7 +1182,7 @@ function MissingModelDetailsModal(props) {
1296
1182
  ]
1297
1183
  }) : null,
1298
1184
  entry.error ? /* @__PURE__ */ jsx("div", {
1299
- className: "mb-2 font-mono text-xs wrap-break-word text-red-700 dark:text-red-100",
1185
+ className: "mb-2 font-mono text-xs wrap-break-word text-destructive",
1300
1186
  children: entry.error.message
1301
1187
  }) : null,
1302
1188
  /* @__PURE__ */ jsx("div", {
@@ -1306,7 +1192,7 @@ function MissingModelDetailsModal(props) {
1306
1192
  onClick: () => void handleRetry(entry.documentType),
1307
1193
  disabled: retryDisabled,
1308
1194
  title: canRetry(entry.reason) ? void 0 : "No registry is configured; nothing to retry against.",
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"),
1195
+ className: twMerge("min-h-[32px] rounded-xl px-3 py-1 text-sm font-semibold text-foreground transition-all hover:hover-effect", retryDisabled ? "cursor-not-allowed bg-secondary hover:hover-effect" : "bg-primary text-primary-foreground active:active-effect"),
1310
1196
  children: isRetrying ? "Retrying..." : "Try install again"
1311
1197
  })
1312
1198
  })
@@ -1319,7 +1205,7 @@ function MissingModelDetailsModal(props) {
1319
1205
  children: /* @__PURE__ */ jsx("button", {
1320
1206
  type: "button",
1321
1207
  onClick: onClose,
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",
1208
+ className: "min-h-[36px] rounded-xl border border-border bg-background px-4 py-2 text-sm font-semibold text-foreground hover:hover-effect",
1323
1209
  children: "Close"
1324
1210
  })
1325
1211
  })
@@ -1410,8 +1296,8 @@ const CookieBanner$1 = () => {
1410
1296
  if (!showBanner) return null;
1411
1297
  return /* @__PURE__ */ jsxs("div", {
1412
1298
  className: "absolute inset-0 z-10000 backdrop-blur-sm",
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",
1299
+ children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-primary opacity-15" }), /* @__PURE__ */ jsx("div", {
1300
+ className: "absolute inset-x-0 bottom-0 flex justify-center bg-background px-10 pt-10 pb-16 shadow-lg",
1415
1301
  children: /* @__PURE__ */ jsx(CookieBanner, {
1416
1302
  className: "max-w-[1024px]",
1417
1303
  cookies: cookiesInput,
@@ -1420,12 +1306,12 @@ const CookieBanner$1 = () => {
1420
1306
  submitLabel: t("cookieBanner.accept"),
1421
1307
  rejectLabel: t("cookieBanner.reject"),
1422
1308
  children: /* @__PURE__ */ jsx("p", {
1423
- className: "font-semibold text-gray-500 dark:text-slate-400",
1309
+ className: "font-semibold text-muted-foreground",
1424
1310
  children: /* @__PURE__ */ jsx(Trans, {
1425
1311
  i18nKey: "cookieBanner.message",
1426
1312
  components: { a: /* @__PURE__ */ jsx("a", {
1427
1313
  onClick: () => showPHModal({ type: "cookiesPolicy" }),
1428
- className: "cursor-pointer text-gray-900 hover:underline dark:text-slate-50"
1314
+ className: "cursor-pointer text-foreground hover:underline"
1429
1315
  }, "cookieBanner.message-link") }
1430
1316
  }, "cookieBanner.message")
1431
1317
  })
@@ -1439,7 +1325,7 @@ function DriveIcon({ drive }) {
1439
1325
  const remotes = useSyncList();
1440
1326
  const isRemoteDrive = useMemo(() => {
1441
1327
  if (!drive) return false;
1442
- return remotes.some((remote) => remote.collectionId === driveCollectionId("main", drive.header.id));
1328
+ return remotes.some((remote) => remote.meta.collectionId.equals(DriveCollectionId.forDrive(drive.header.id)));
1443
1329
  }, [remotes, drive]);
1444
1330
  const driveIconSrc = drive?.state.global.icon;
1445
1331
  if (driveIconSrc) return /* @__PURE__ */ jsx("img", {
@@ -1604,7 +1490,7 @@ const DocumentEditor = (props) => {
1604
1490
  //#region src/components/root.tsx
1605
1491
  function Root() {
1606
1492
  return /* @__PURE__ */ jsx("div", {
1607
- className: "h-screen bg-gray-50 dark:bg-slate-800",
1493
+ className: "h-screen bg-background",
1608
1494
  children: /* @__PURE__ */ jsx("div", {
1609
1495
  className: `flex h-screen items-stretch overflow-auto`,
1610
1496
  role: "presentation",
@@ -1620,8 +1506,24 @@ function Root() {
1620
1506
  });
1621
1507
  }
1622
1508
  //#endregion
1509
+ //#region src/components/use-drive-auth-gate.ts
1510
+ /** Gate an anonymous user only when a remote failed with an auth rejection
1511
+ * (`requiresAuth`) — the switchboard refusing the caller for lack of login. */
1512
+ function computeNeedsLogin(isAuthenticated, connectionStates) {
1513
+ if (isAuthenticated) return false;
1514
+ for (const snap of connectionStates.values()) if (snap.state === "error" && snap.requiresAuth) return true;
1515
+ return false;
1516
+ }
1517
+ /** Live wrapper over {@link computeNeedsLogin}. */
1518
+ function useDriveAuthGate() {
1519
+ const user = useUser();
1520
+ const connectionStates = useConnectionStates();
1521
+ return { needsLogin: computeNeedsLogin(Boolean(user), connectionStates) };
1522
+ }
1523
+ //#endregion
1623
1524
  //#region src/pages/content.tsx
1624
1525
  function Content() {
1526
+ const { needsLogin } = useDriveAuthGate();
1625
1527
  const [selectedDrive] = useSelectedDriveSafe();
1626
1528
  const selectedFolder = useSelectedFolder();
1627
1529
  const selectedDocumentId = useSelectedDocumentId();
@@ -1631,7 +1533,10 @@ function Content() {
1631
1533
  useEffect(() => {
1632
1534
  if (!selectedDrive) setPHAppConfig(defaultPHAppConfig);
1633
1535
  }, [selectedDrive]);
1634
- return /* @__PURE__ */ jsx(ContentContainer, { children: !selectedDocumentId && !selectedDrive && !selectedFolder ? /* @__PURE__ */ jsx(HomeScreenContainer, {}) : /* @__PURE__ */ jsx(AppContainer, {}) });
1536
+ return /* @__PURE__ */ jsx(ContentContainer, { children: needsLogin ? /* @__PURE__ */ jsx("div", {
1537
+ className: "flex h-full items-center justify-center p-4",
1538
+ children: /* @__PURE__ */ jsx(DriveAuthGate, { onLogin: openRenown })
1539
+ }) : !selectedDocumentId && !selectedDrive && !selectedFolder ? /* @__PURE__ */ jsx(HomeScreenContainer, {}) : /* @__PURE__ */ jsx(AppContainer, {}) });
1635
1540
  }
1636
1541
  function ContentContainer({ children }) {
1637
1542
  return /* @__PURE__ */ jsx("div", {
@@ -1738,28 +1643,99 @@ function Sidebar() {
1738
1643
  }) });
1739
1644
  }
1740
1645
  //#endregion
1646
+ //#region src/components/connection-banner.tsx
1647
+ const CONNECTED = "connected";
1648
+ const ConnectionBanner = () => {
1649
+ if (useSyncExternalStore(subscribeWorkerConnection, getWorkerConnectionStatus, () => CONNECTED) !== "lost") return null;
1650
+ return /* @__PURE__ */ jsx("div", {
1651
+ className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1652
+ children: /* @__PURE__ */ jsxs("div", {
1653
+ className: "flex max-w-3xl items-center gap-3 rounded-lg border border-destructive bg-warning px-4 py-3 text-sm text-warning-foreground shadow-lg",
1654
+ children: [/* @__PURE__ */ jsxs("div", {
1655
+ className: "flex-1",
1656
+ children: [/* @__PURE__ */ jsx("div", {
1657
+ className: "font-semibold",
1658
+ children: "Lost connection to the reactor"
1659
+ }), /* @__PURE__ */ jsx("div", {
1660
+ className: "text-foreground",
1661
+ children: "The background worker stopped responding. Reload to reconnect."
1662
+ })]
1663
+ }), /* @__PURE__ */ jsx("button", {
1664
+ type: "button",
1665
+ onClick: () => window.location.reload(),
1666
+ className: "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect",
1667
+ children: "Reload"
1668
+ })]
1669
+ })
1670
+ });
1671
+ };
1672
+ //#endregion
1741
1673
  //#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();
1674
+ function BannerShell({ title, body, error, children }) {
1675
+ return /* @__PURE__ */ jsx("div", {
1676
+ className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1677
+ children: /* @__PURE__ */ jsxs("div", {
1678
+ className: "flex max-w-3xl items-center gap-3 rounded-lg border border-warning bg-warning px-4 py-3 text-sm text-warning-foreground shadow-lg",
1679
+ children: [/* @__PURE__ */ jsxs("div", {
1680
+ className: "flex-1",
1681
+ children: [
1682
+ /* @__PURE__ */ jsx("div", {
1683
+ className: "font-semibold",
1684
+ children: title
1685
+ }),
1686
+ /* @__PURE__ */ jsx("div", {
1687
+ className: "text-foreground",
1688
+ children: body
1689
+ }),
1690
+ error && /* @__PURE__ */ jsxs("div", {
1691
+ className: "mt-2 font-medium text-destructive",
1692
+ children: ["Migration failed: ", error]
1693
+ })
1694
+ ]
1695
+ }), children]
1696
+ })
1697
+ });
1750
1698
  }
1751
- function subscribeDismissed(cb) {
1752
- listeners.add(cb);
1753
- return () => {
1754
- listeners.delete(cb);
1699
+ const actionButton = "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect disabled:disabled-effect";
1700
+ const dismissButton = "rounded-sm border border-foreground bg-transparent px-3 py-1 text-sm font-medium text-foreground hover:hover-effect disabled:disabled-effect";
1701
+ let browserDismissed = false;
1702
+ const browserListeners = /* @__PURE__ */ new Set();
1703
+ function WorkerMigrationBanner({ adminClient }) {
1704
+ const state = useSyncExternalStore((cb) => adminClient.subscribeMigration(cb), () => adminClient.getMigrationState());
1705
+ const [dismissed, setDismissed] = useState(false);
1706
+ const [error, setError] = useState(null);
1707
+ if (state.status === "idle") return null;
1708
+ if (state.status === "needed" && dismissed) return null;
1709
+ const migrating = state.status === "migrating";
1710
+ const handleMigrate = () => {
1711
+ setError(null);
1712
+ adminClient.migrate().catch((err) => {
1713
+ setError(err instanceof Error ? err.message : String(err));
1714
+ });
1755
1715
  };
1716
+ return /* @__PURE__ */ jsxs(BannerShell, {
1717
+ title: migrating ? `Migrating to Postgres 17…` : `Your local database uses Postgres ${state.legacyMajor ?? "?"}.`,
1718
+ body: migrating ? `Working (${state.phase ?? "starting"}). Your data is backed up first.` : `Migrate to Postgres 17 to pick up the latest features. Your data will be backed up first.`,
1719
+ error: error ?? (state.status === "failed" ? state.error : null),
1720
+ children: [!migrating && /* @__PURE__ */ jsx("button", {
1721
+ type: "button",
1722
+ onClick: handleMigrate,
1723
+ className: actionButton,
1724
+ children: state.status === "failed" ? "Retry" : "Migrate now"
1725
+ }), state.status === "needed" && /* @__PURE__ */ jsx("button", {
1726
+ type: "button",
1727
+ onClick: () => setDismissed(true),
1728
+ className: dismissButton,
1729
+ children: "Dismiss"
1730
+ })]
1731
+ });
1756
1732
  }
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);
1733
+ function BrowserMigrationBanner() {
1734
+ const isDismissed = useSyncExternalStore((cb) => {
1735
+ browserListeners.add(cb);
1736
+ return () => browserListeners.delete(cb);
1737
+ }, () => browserDismissed, () => false);
1738
+ const major = useSyncExternalStore(subscribeMigrationMajor, getCachedMigrationMajor, () => void 0);
1763
1739
  const [migrating, setMigrating] = useState(false);
1764
1740
  const [error, setError] = useState(null);
1765
1741
  if (major === void 0 || major === null || major === 17) return null;
@@ -1767,75 +1743,52 @@ const MigrationBanner = () => {
1767
1743
  const handleMigrate = () => {
1768
1744
  setError(null);
1769
1745
  setMigrating(true);
1770
- migrateAllIfNeeded().then(() => {
1771
- window.location.reload();
1772
- }).catch((err) => {
1746
+ migrateAllIfNeeded().then(() => window.location.reload()).catch((err) => {
1773
1747
  setError(err instanceof Error ? err.message : String(err));
1774
1748
  setMigrating(false);
1775
1749
  });
1776
1750
  };
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
- })
1751
+ return /* @__PURE__ */ jsxs(BannerShell, {
1752
+ title: `Your local database uses Postgres ${major}.`,
1753
+ body: `Migrate to Postgres 17 to pick up the latest features. Your data will be backed up first.`,
1754
+ error,
1755
+ children: [/* @__PURE__ */ jsx("button", {
1756
+ type: "button",
1757
+ disabled: migrating,
1758
+ onClick: handleMigrate,
1759
+ className: actionButton,
1760
+ children: migrating ? "Migrating…" : "Migrate now"
1761
+ }), /* @__PURE__ */ jsx("button", {
1762
+ type: "button",
1763
+ disabled: migrating,
1764
+ onClick: () => {
1765
+ browserDismissed = true;
1766
+ for (const l of browserListeners) l();
1767
+ },
1768
+ className: dismissButton,
1769
+ children: "Dismiss"
1770
+ })]
1823
1771
  });
1772
+ }
1773
+ const MigrationBanner = () => {
1774
+ const module = useReactorClientModule();
1775
+ if (module?.kind === "worker") return /* @__PURE__ */ jsx(WorkerMigrationBanner, { adminClient: module.adminClient });
1776
+ return /* @__PURE__ */ jsx(BrowserMigrationBanner, {});
1824
1777
  };
1825
1778
  //#endregion
1826
1779
  //#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-BSNg-Ymg.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-D4Mk5SmY.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-NqDM9cwJ.js").then((m) => ({ default: m.SettingsModal })));
1838
- const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-CyAUDCU7.js").then((m) => ({ default: m.UpgradeDriveModal })));
1780
+ const AddDriveModal$1 = lazy(() => import("./AddDriveModal-D-nbV40j.js").then((m) => ({ default: m.AddDriveModal })));
1781
+ const ClearStorageModal = lazy(() => import("./ClearStorageModal-Cl9fxCul.js").then((m) => ({ default: m.ClearStorageModal })));
1782
+ const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-CkcUKPLb.js").then((m) => ({ default: m.CookiesPolicyModal })));
1783
+ const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-CvsTh0HM.js").then((m) => ({ default: m.CreateDocumentModal })));
1784
+ const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-iBk2t1kf.js").then((m) => ({ default: m.DebugSettingsModal })));
1785
+ const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-DSTK8FYk.js").then((m) => ({ default: m.DeleteDriveModal })));
1786
+ const DeleteItemModal = lazy(() => import("./DeleteItemModal-B2nJmjsP.js").then((m) => ({ default: m.DeleteItemModal })));
1787
+ const DisclaimerModal = lazy(() => import("./DisclaimerModal-D5FO34u9.js").then((m) => ({ default: m.DisclaimerModal })));
1788
+ const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-kR3hQnh4.js").then((m) => ({ default: m.DriveSettingsModal })));
1789
+ const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-tEr3bbtN.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1790
+ const SettingsModal$1 = lazy(() => import("./SettingsModal-D58SPZbC.js").then((m) => ({ default: m.SettingsModal })));
1791
+ const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BZGSE9_r.js").then((m) => ({ default: m.UpgradeDriveModal })));
1839
1792
  const modalComponents = {
1840
1793
  addDrive: AddDriveModal$1,
1841
1794
  clearStorage: ClearStorageModal,
@@ -1847,10 +1800,11 @@ const modalComponents = {
1847
1800
  disclaimer: DisclaimerModal,
1848
1801
  driveSettings: DriveSettingsModal$1,
1849
1802
  downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
1850
- inspector: lazy(() => import("./InspectorModal-DyrVQ4fu.js").then((m) => ({ default: m.InspectorModal }))),
1803
+ inspector: lazy(() => import("./InspectorModal-D5OMGJBP.js").then((m) => ({ default: m.InspectorModal }))),
1851
1804
  settings: SettingsModal$1,
1852
1805
  upgradeDrive: UpgradeDriveModal,
1853
- missingPackage: lazy(() => import("./MissingPackageModal-D_N96M6a.js").then((m) => ({ default: m.ConnectMissingPackageModal })))
1806
+ missingPackage: lazy(() => import("./MissingPackageModal-BQcCQbOn.js").then((m) => ({ default: m.ConnectMissingPackageModal }))),
1807
+ driveAuthRequired: lazy(() => import("./DriveAuthRequiredModal-B5-ZfKsb.js").then((m) => ({ default: m.DriveAuthRequiredModal })))
1854
1808
  };
1855
1809
  const ModalsContainer = lazy(() => {
1856
1810
  return Promise.resolve({ default: () => {
@@ -1870,7 +1824,7 @@ const ModalsContainer = lazy(() => {
1870
1824
  //#endregion
1871
1825
  //#region src/components/app-loader.tsx
1872
1826
  const AppLoader = (props) => {
1873
- const Load = lazy(() => import("./load-BLx_riHu.js").then((m) => m.loadComponent(props.localPackage)));
1827
+ const Load = lazy(() => import("./load-EfgIfQ14.js").then((m) => m.loadComponent(props.localPackage)));
1874
1828
  return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
1875
1829
  fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
1876
1830
  resetKeys: [props.localPackage],
@@ -1892,12 +1846,13 @@ const AppLoader = (props) => {
1892
1846
  name: "ModalsContainer",
1893
1847
  children: /* @__PURE__ */ jsx(ModalsContainer, {})
1894
1848
  }),
1895
- /* @__PURE__ */ jsx(MigrationBanner, {})
1849
+ /* @__PURE__ */ jsx(MigrationBanner, {}),
1850
+ /* @__PURE__ */ jsx(ConnectionBanner, {})
1896
1851
  ]
1897
1852
  }) });
1898
1853
  };
1899
1854
  //#endregion
1900
1855
  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 };
1901
1856
 
1902
- //# sourceMappingURL=app-loader-DxoMZXTL.js.map
1903
- //# debugId=e428717e-ea15-57ae-b56b-d3f820f6d77c
1857
+ //# sourceMappingURL=app-loader-6NP0KBww.js.map
1858
+ //# debugId=3ad5ed01-1906-5e34-87e1-a4d5b03fb8d0