@powerhousedao/connect 6.2.1 → 6.2.2-dev.1

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 (77) hide show
  1. package/dist/{AddDriveModal-vA-eqqPS.js → AddDriveModal-MMHlkJBJ.js} +10 -14
  2. package/dist/AddDriveModal-MMHlkJBJ.js.map +1 -0
  3. package/dist/{ClearStorageModal-Dm00WyUu.js → ClearStorageModal-BigtCV_M.js} +4 -4
  4. package/dist/{ClearStorageModal-Dm00WyUu.js.map → ClearStorageModal-BigtCV_M.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-CWZkbU7v.js → DebugSettingsModal-Bti38_qt.js} +6 -6
  10. package/dist/{DebugSettingsModal-CWZkbU7v.js.map → DebugSettingsModal-Bti38_qt.js.map} +1 -1
  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-DDlfeXD_.js → DriveAuthRequiredModal-BA2vS3oF.js} +3 -3
  20. package/dist/{DriveAuthRequiredModal-DDlfeXD_.js.map → DriveAuthRequiredModal-BA2vS3oF.js.map} +1 -1
  21. package/dist/{DriveSettingsModal-CsNFEJ9E.js → DriveSettingsModal-kR3hQnh4.js} +4 -4
  22. package/dist/DriveSettingsModal-kR3hQnh4.js.map +1 -0
  23. package/dist/{InspectorModal-wChBJ6R5.js → InspectorModal-B2Zbsa4l.js} +84 -35
  24. package/dist/InspectorModal-B2Zbsa4l.js.map +1 -0
  25. package/dist/{MissingPackageModal-Bn036mWQ.js → MissingPackageModal-BQcCQbOn.js} +4 -4
  26. package/dist/{MissingPackageModal-Bn036mWQ.js.map → MissingPackageModal-BQcCQbOn.js.map} +1 -1
  27. package/dist/{SettingsModal-1i3Dr5eT.js → SettingsModal-BnHg4yeC.js} +9 -9
  28. package/dist/SettingsModal-BnHg4yeC.js.map +1 -0
  29. package/dist/{UpgradeDriveModal-C7lV4rAX.js → UpgradeDriveModal-BZGSE9_r.js} +3 -3
  30. package/dist/{UpgradeDriveModal-C7lV4rAX.js.map → UpgradeDriveModal-BZGSE9_r.js.map} +1 -1
  31. package/dist/app-loader-B_HyriND.js +4 -0
  32. package/dist/{app-loader-C5IWlQ7x.js → app-loader-CuYQDicM.js} +199 -264
  33. package/dist/app-loader-CuYQDicM.js.map +1 -0
  34. package/dist/{build-info-zGvEjLMy.js → build-info-D0TYDOtW.js} +8 -5
  35. package/dist/{build-info-zGvEjLMy.js.map → build-info-D0TYDOtW.js.map} +1 -1
  36. package/dist/components-xBFneZuJ.js +5 -0
  37. package/dist/{connect.config-BDYNejx3.js → connect.config-vgUeFoNp.js} +16 -6
  38. package/dist/connect.config-vgUeFoNp.js.map +1 -0
  39. package/dist/connection-state-DO_2lAEJ.js +126 -0
  40. package/dist/connection-state-DO_2lAEJ.js.map +1 -0
  41. package/dist/{load-Bt4B0U-v.js → load-DajsG0zi.js} +11 -11
  42. package/dist/{load-Bt4B0U-v.js.map → load-DajsG0zi.js.map} +1 -1
  43. package/dist/main.js +1 -1
  44. package/dist/{package-CNJ1Q-58.js → package-CX2sgCBs.js} +5 -4
  45. package/dist/package-CX2sgCBs.js.map +1 -0
  46. package/dist/{pglite-runtime-CHa5UyCw.js → pglite-major-B39aOEiE.js} +8 -47
  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-CvnZdEbx.js → pglite-seed-z3B1JA38.js} +4 -4
  51. package/dist/{pglite-seed-CvnZdEbx.js.map → pglite-seed-z3B1JA38.js.map} +1 -1
  52. package/dist/{reactor-DWY9_ifj.js → reactor-Bo6Lut7c.js} +271 -37
  53. package/dist/reactor-Bo6Lut7c.js.map +1 -0
  54. package/dist/reactor.worker.d.ts +1 -0
  55. package/dist/reactor.worker.js +323 -0
  56. package/dist/reactor.worker.js.map +1 -0
  57. package/dist/{registerServiceWorker-Dc4QY0Sd.js → registerServiceWorker-nJIc0yEY.js} +4 -4
  58. package/dist/{registerServiceWorker-Dc4QY0Sd.js.map → registerServiceWorker-nJIc0yEY.js.map} +1 -1
  59. package/dist/{reload-connect-toast-DIFQ9FCX.js → reload-connect-toast-D1Iqw9E_.js} +3 -3
  60. package/dist/{reload-connect-toast-DIFQ9FCX.js.map → reload-connect-toast-D1Iqw9E_.js.map} +1 -1
  61. package/dist/start-connect.js +1 -1
  62. package/dist/{toast-BEy42aYx.js → toast-4t-VimvD.js} +3 -3
  63. package/dist/{toast-BEy42aYx.js.map → toast-4t-VimvD.js.map} +1 -1
  64. package/dist/{useRegistryPackages-B-gFECmd.js → useRegistryPackages-BaYtekjQ.js} +3 -3
  65. package/dist/{useRegistryPackages-B-gFECmd.js.map → useRegistryPackages-BaYtekjQ.js.map} +1 -1
  66. package/package.json +11 -10
  67. package/dist/AddDriveModal-vA-eqqPS.js.map +0 -1
  68. package/dist/DriveSettingsModal-CsNFEJ9E.js.map +0 -1
  69. package/dist/InspectorModal-wChBJ6R5.js.map +0 -1
  70. package/dist/SettingsModal-1i3Dr5eT.js.map +0 -1
  71. package/dist/app-loader-C5IWlQ7x.js.map +0 -1
  72. package/dist/app-loader-DYpRh5ax.js +0 -4
  73. package/dist/components-CiPNtuf_.js +0 -5
  74. package/dist/connect.config-BDYNejx3.js.map +0 -1
  75. package/dist/package-CNJ1Q-58.js.map +0 -1
  76. package/dist/pglite-runtime-CHa5UyCw.js.map +0 -1
  77. package/dist/reactor-DWY9_ifj.js.map +0 -1
@@ -1,13 +1,14 @@
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]="e953dc08-9a65-58dd-8382-5a31beb3ed26")}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]="5643cee8-d3b6-5800-a974-4c21fa405450")}catch(e){}}();
3
3
  import { n as getRuntimeConfig } from "./runtime-config-DL3QjcfM.js";
4
- import { i as i18n, n as setSentryModule } from "./reload-connect-toast-DIFQ9FCX.js";
5
- import { a as defaultPHDocumentEditorConfig, i as defaultPHAppConfig, r as connectConfig } from "./connect.config-BDYNejx3.js";
6
- import { c as IDB_STORE_NAME, d as idbError, f as openIdb, l as PRIMARY_IDB_NAMES, n as getCachedReactorPgMajor, p as readPgVersionFile, s as subscribeReactorPgMajor, u as createFileDataStore } from "./pglite-runtime-CHa5UyCw.js";
7
- import { n as serviceWorkerManager, r as subscribeServiceWorkerUpdate, t as getServiceWorkerUpdateAvailable } from "./registerServiceWorker-Dc4QY0Sd.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 { i as i18n, n as setSentryModule } from "./reload-connect-toast-D1Iqw9E_.js";
7
+ import { a as defaultPHDocumentEditorConfig, i as defaultPHAppConfig, r as connectConfig } from "./connect.config-vgUeFoNp.js";
8
+ import { f as PRIMARY_IDB_NAMES, r as subscribeWorkerConnection, s as getCachedMigrationMajor, t as getWorkerConnectionStatus, u as subscribeMigrationMajor } from "./connection-state-DO_2lAEJ.js";
9
+ import { n as serviceWorkerManager, r as subscribeServiceWorkerUpdate, t as getServiceWorkerUpdateAvailable } from "./registerServiceWorker-nJIc0yEY.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
14
  import { DriveCollectionId, getRevisionFromDate, initTheme, logout, openRenown, setPHAppConfig, setPHDocumentEditorConfig, setRevisionHistoryVisible, setSelectedDrive, setSelectedNode, showPHModal, useAppModuleById, useConnectionStates, useDefaultAppModule, useDocumentById, useDocumentModelModuleById, useDocumentOperations, useDrives, useEditorModuleById, useEditorPreloader, useFallbackEditorModule, useIsAddDriveEnabled, useNodeParentFolderById, usePHModal, usePackageDiscoveryService, useReactorClientModule, useRevisionHistoryVisible, useSelectedDocument, useSelectedDocumentId, useSelectedDriveSafe, useSelectedFolder, useSelectedTimelineItem, useSyncList, useTheme, useUser, useVetraPackageManager, useVetraPackages } from "@powerhousedao/reactor-browser";
@@ -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];
@@ -823,7 +708,7 @@ function SilentFallback() {
823
708
  */
824
709
  function TextFallback({ message = "Something went wrong" }) {
825
710
  return /* @__PURE__ */ jsx("div", {
826
- className: "text-center",
711
+ className: "text-center text-foreground",
827
712
  children: message
828
713
  });
829
714
  }
@@ -838,15 +723,15 @@ function DetailedFallback({ error, resetErrorBoundary }) {
838
723
  return /* @__PURE__ */ jsx("div", {
839
724
  className: "z-10 mx-auto flex max-w-[80%] flex-1 items-center justify-center p-6",
840
725
  children: /* @__PURE__ */ jsxs("div", {
841
- className: "w-full max-w-lg rounded-lg border border-border bg-background p-6 shadow-sm",
726
+ className: "w-full max-w-lg rounded-lg border border-border bg-card p-6 text-foreground shadow-sm",
842
727
  children: [
843
728
  /* @__PURE__ */ jsxs("div", {
844
729
  className: "mb-3 flex items-center gap-2",
845
730
  children: [/* @__PURE__ */ jsx(Icon, {
846
731
  name: "Error",
847
- className: "size-5 shrink-0"
732
+ className: "size-5 shrink-0 text-destructive"
848
733
  }), /* @__PURE__ */ jsx("h1", {
849
- className: "text-lg font-semibold",
734
+ className: "text-lg font-semibold text-foreground",
850
735
  children: "Something went wrong"
851
736
  })]
852
737
  }),
@@ -860,7 +745,7 @@ function DetailedFallback({ error, resetErrorBoundary }) {
860
745
  className: "cursor-pointer text-sm font-medium text-foreground underline select-none hover:hover-effect",
861
746
  children: "Show details"
862
747
  }), /* @__PURE__ */ jsx("pre", {
863
- className: "mt-2 max-h-48 overflow-auto rounded-sm bg-muted p-3 text-xs",
748
+ className: "mt-2 max-h-48 overflow-auto rounded-sm bg-muted p-3 text-xs text-foreground",
864
749
  children: errorDetails
865
750
  })]
866
751
  }),
@@ -883,7 +768,7 @@ function CenteredErrorMessage({ error }) {
883
768
  return /* @__PURE__ */ jsx("div", {
884
769
  className: "flex size-full items-center justify-center",
885
770
  children: /* @__PURE__ */ jsx("h3", {
886
- className: "text-lg font-semibold",
771
+ className: "text-lg font-semibold text-foreground",
887
772
  children: error instanceof Error ? error.message : String(error)
888
773
  })
889
774
  });
@@ -1074,7 +959,8 @@ function buildIdentifyPayload(user) {
1074
959
  function OpenPanel() {
1075
960
  const [{ analytics }] = useAcceptedCookies();
1076
961
  const user = useUser();
1077
- const reactorClientModule = useReactorClientModule();
962
+ const module = useReactorClientModule();
963
+ const reactorClientModule = module?.kind === "browser" ? module : void 0;
1078
964
  const [client, setClient] = useState();
1079
965
  /**
1080
966
  * Tracks the previous `user` value so we can detect the two transitions:
@@ -1445,7 +1331,7 @@ function DriveIcon({ drive }) {
1445
1331
  const remotes = useSyncList();
1446
1332
  const isRemoteDrive = useMemo(() => {
1447
1333
  if (!drive) return false;
1448
- return remotes.some((remote) => remote.collectionId.equals(DriveCollectionId.forDrive(drive.header.id)));
1334
+ return remotes.some((remote) => remote.meta.collectionId.equals(DriveCollectionId.forDrive(drive.header.id)));
1449
1335
  }, [remotes, drive]);
1450
1336
  const driveIconSrc = drive?.state.global.icon;
1451
1337
  if (driveIconSrc) return /* @__PURE__ */ jsx("img", {
@@ -1769,28 +1655,99 @@ function Sidebar() {
1769
1655
  }) });
1770
1656
  }
1771
1657
  //#endregion
1658
+ //#region src/components/connection-banner.tsx
1659
+ const CONNECTED = "connected";
1660
+ const ConnectionBanner = () => {
1661
+ if (useSyncExternalStore(subscribeWorkerConnection, getWorkerConnectionStatus, () => CONNECTED) !== "lost") return null;
1662
+ return /* @__PURE__ */ jsx("div", {
1663
+ className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1664
+ children: /* @__PURE__ */ jsxs("div", {
1665
+ 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",
1666
+ children: [/* @__PURE__ */ jsxs("div", {
1667
+ className: "flex-1",
1668
+ children: [/* @__PURE__ */ jsx("div", {
1669
+ className: "font-semibold",
1670
+ children: "Lost connection to the reactor"
1671
+ }), /* @__PURE__ */ jsx("div", {
1672
+ className: "text-foreground",
1673
+ children: "The background worker stopped responding. Reload to reconnect."
1674
+ })]
1675
+ }), /* @__PURE__ */ jsx("button", {
1676
+ type: "button",
1677
+ onClick: () => window.location.reload(),
1678
+ className: "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect",
1679
+ children: "Reload"
1680
+ })]
1681
+ })
1682
+ });
1683
+ };
1684
+ //#endregion
1772
1685
  //#region src/components/migration-banner.tsx
1773
- let dismissed = false;
1774
- const listeners = /* @__PURE__ */ new Set();
1775
- function notify() {
1776
- for (const l of listeners) l();
1777
- }
1778
- function dismiss() {
1779
- dismissed = true;
1780
- notify();
1686
+ function BannerShell({ title, body, error, children }) {
1687
+ return /* @__PURE__ */ jsx("div", {
1688
+ className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1689
+ children: /* @__PURE__ */ jsxs("div", {
1690
+ 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",
1691
+ children: [/* @__PURE__ */ jsxs("div", {
1692
+ className: "flex-1",
1693
+ children: [
1694
+ /* @__PURE__ */ jsx("div", {
1695
+ className: "font-semibold",
1696
+ children: title
1697
+ }),
1698
+ /* @__PURE__ */ jsx("div", {
1699
+ className: "text-foreground",
1700
+ children: body
1701
+ }),
1702
+ error && /* @__PURE__ */ jsxs("div", {
1703
+ className: "mt-2 font-medium text-destructive",
1704
+ children: ["Migration failed: ", error]
1705
+ })
1706
+ ]
1707
+ }), children]
1708
+ })
1709
+ });
1781
1710
  }
1782
- function subscribeDismissed(cb) {
1783
- listeners.add(cb);
1784
- return () => {
1785
- listeners.delete(cb);
1711
+ const actionButton = "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect disabled:disabled-effect";
1712
+ 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";
1713
+ let browserDismissed = false;
1714
+ const browserListeners = /* @__PURE__ */ new Set();
1715
+ function WorkerMigrationBanner({ adminClient }) {
1716
+ const state = useSyncExternalStore((cb) => adminClient.subscribeMigration(cb), () => adminClient.getMigrationState());
1717
+ const [dismissed, setDismissed] = useState(false);
1718
+ const [error, setError] = useState(null);
1719
+ if (state.status === "idle") return null;
1720
+ if (state.status === "needed" && dismissed) return null;
1721
+ const migrating = state.status === "migrating";
1722
+ const handleMigrate = () => {
1723
+ setError(null);
1724
+ adminClient.migrate().catch((err) => {
1725
+ setError(err instanceof Error ? err.message : String(err));
1726
+ });
1786
1727
  };
1728
+ return /* @__PURE__ */ jsxs(BannerShell, {
1729
+ title: migrating ? `Migrating to Postgres 17…` : `Your local database uses Postgres ${state.legacyMajor ?? "?"}.`,
1730
+ 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.`,
1731
+ error: error ?? (state.status === "failed" ? state.error : null),
1732
+ children: [!migrating && /* @__PURE__ */ jsx("button", {
1733
+ type: "button",
1734
+ onClick: handleMigrate,
1735
+ className: actionButton,
1736
+ children: state.status === "failed" ? "Retry" : "Migrate now"
1737
+ }), state.status === "needed" && /* @__PURE__ */ jsx("button", {
1738
+ type: "button",
1739
+ onClick: () => setDismissed(true),
1740
+ className: dismissButton,
1741
+ children: "Dismiss"
1742
+ })]
1743
+ });
1787
1744
  }
1788
- function getDismissed() {
1789
- return dismissed;
1790
- }
1791
- const MigrationBanner = () => {
1792
- const isDismissed = useSyncExternalStore(subscribeDismissed, getDismissed, () => false);
1793
- const major = useSyncExternalStore(subscribeReactorPgMajor, getCachedReactorPgMajor, () => void 0);
1745
+ function BrowserMigrationBanner() {
1746
+ const isDismissed = useSyncExternalStore((cb) => {
1747
+ browserListeners.add(cb);
1748
+ return () => browserListeners.delete(cb);
1749
+ }, () => browserDismissed, () => false);
1750
+ const major = useSyncExternalStore(subscribeMigrationMajor, getCachedMigrationMajor, () => void 0);
1794
1751
  const [migrating, setMigrating] = useState(false);
1795
1752
  const [error, setError] = useState(null);
1796
1753
  if (major === void 0 || major === null || major === 17) return null;
@@ -1798,75 +1755,52 @@ const MigrationBanner = () => {
1798
1755
  const handleMigrate = () => {
1799
1756
  setError(null);
1800
1757
  setMigrating(true);
1801
- migrateAllIfNeeded().then(() => {
1802
- window.location.reload();
1803
- }).catch((err) => {
1758
+ migrateAllIfNeeded().then(() => window.location.reload()).catch((err) => {
1804
1759
  setError(err instanceof Error ? err.message : String(err));
1805
1760
  setMigrating(false);
1806
1761
  });
1807
1762
  };
1808
- return /* @__PURE__ */ jsx("div", {
1809
- className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1810
- children: /* @__PURE__ */ jsxs("div", {
1811
- 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",
1812
- children: [
1813
- /* @__PURE__ */ jsxs("div", {
1814
- className: "flex-1",
1815
- children: [
1816
- /* @__PURE__ */ jsxs("div", {
1817
- className: "font-semibold",
1818
- children: [
1819
- "Your local database uses Postgres ",
1820
- major,
1821
- "."
1822
- ]
1823
- }),
1824
- /* @__PURE__ */ jsxs("div", {
1825
- className: "text-foreground",
1826
- children: [
1827
- "Migrate to Postgres ",
1828
- 17,
1829
- " to pick up the latest features. Your data will be backed up first."
1830
- ]
1831
- }),
1832
- error && /* @__PURE__ */ jsxs("div", {
1833
- className: "mt-2 font-medium text-destructive",
1834
- children: ["Migration failed: ", error]
1835
- })
1836
- ]
1837
- }),
1838
- /* @__PURE__ */ jsx("button", {
1839
- type: "button",
1840
- disabled: migrating,
1841
- onClick: handleMigrate,
1842
- className: "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect disabled:disabled-effect",
1843
- children: migrating ? "Migrating…" : "Migrate now"
1844
- }),
1845
- /* @__PURE__ */ jsx("button", {
1846
- type: "button",
1847
- disabled: migrating,
1848
- onClick: dismiss,
1849
- className: "rounded-sm border border-foreground bg-transparent px-3 py-1 text-sm font-medium text-foreground hover:hover-effect disabled:disabled-effect",
1850
- children: "Dismiss"
1851
- })
1852
- ]
1853
- })
1763
+ return /* @__PURE__ */ jsxs(BannerShell, {
1764
+ title: `Your local database uses Postgres ${major}.`,
1765
+ body: `Migrate to Postgres 17 to pick up the latest features. Your data will be backed up first.`,
1766
+ error,
1767
+ children: [/* @__PURE__ */ jsx("button", {
1768
+ type: "button",
1769
+ disabled: migrating,
1770
+ onClick: handleMigrate,
1771
+ className: actionButton,
1772
+ children: migrating ? "Migrating…" : "Migrate now"
1773
+ }), /* @__PURE__ */ jsx("button", {
1774
+ type: "button",
1775
+ disabled: migrating,
1776
+ onClick: () => {
1777
+ browserDismissed = true;
1778
+ for (const l of browserListeners) l();
1779
+ },
1780
+ className: dismissButton,
1781
+ children: "Dismiss"
1782
+ })]
1854
1783
  });
1784
+ }
1785
+ const MigrationBanner = () => {
1786
+ const module = useReactorClientModule();
1787
+ if (module?.kind === "worker") return /* @__PURE__ */ jsx(WorkerMigrationBanner, { adminClient: module.adminClient });
1788
+ return /* @__PURE__ */ jsx(BrowserMigrationBanner, {});
1855
1789
  };
1856
1790
  //#endregion
1857
1791
  //#region src/components/modal/modals-container.tsx
1858
- const AddDriveModal$1 = lazy(() => import("./AddDriveModal-vA-eqqPS.js").then((m) => ({ default: m.AddDriveModal })));
1859
- const ClearStorageModal = lazy(() => import("./ClearStorageModal-Dm00WyUu.js").then((m) => ({ default: m.ClearStorageModal })));
1860
- const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-1nOh6oN3.js").then((m) => ({ default: m.CookiesPolicyModal })));
1861
- const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-nQbLVDq3.js").then((m) => ({ default: m.CreateDocumentModal })));
1862
- const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-CWZkbU7v.js").then((m) => ({ default: m.DebugSettingsModal })));
1863
- const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-6P0T1QgD.js").then((m) => ({ default: m.DeleteDriveModal })));
1864
- const DeleteItemModal = lazy(() => import("./DeleteItemModal-BmV1aQyZ.js").then((m) => ({ default: m.DeleteItemModal })));
1865
- const DisclaimerModal = lazy(() => import("./DisclaimerModal-CVTFfN0_.js").then((m) => ({ default: m.DisclaimerModal })));
1866
- const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-CsNFEJ9E.js").then((m) => ({ default: m.DriveSettingsModal })));
1867
- const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-CXeFUtaz.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1868
- const SettingsModal$1 = lazy(() => import("./SettingsModal-1i3Dr5eT.js").then((m) => ({ default: m.SettingsModal })));
1869
- const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-C7lV4rAX.js").then((m) => ({ default: m.UpgradeDriveModal })));
1792
+ const AddDriveModal$1 = lazy(() => import("./AddDriveModal-MMHlkJBJ.js").then((m) => ({ default: m.AddDriveModal })));
1793
+ const ClearStorageModal = lazy(() => import("./ClearStorageModal-BigtCV_M.js").then((m) => ({ default: m.ClearStorageModal })));
1794
+ const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-CkcUKPLb.js").then((m) => ({ default: m.CookiesPolicyModal })));
1795
+ const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-CvsTh0HM.js").then((m) => ({ default: m.CreateDocumentModal })));
1796
+ const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-Bti38_qt.js").then((m) => ({ default: m.DebugSettingsModal })));
1797
+ const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-DSTK8FYk.js").then((m) => ({ default: m.DeleteDriveModal })));
1798
+ const DeleteItemModal = lazy(() => import("./DeleteItemModal-B2nJmjsP.js").then((m) => ({ default: m.DeleteItemModal })));
1799
+ const DisclaimerModal = lazy(() => import("./DisclaimerModal-D5FO34u9.js").then((m) => ({ default: m.DisclaimerModal })));
1800
+ const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-kR3hQnh4.js").then((m) => ({ default: m.DriveSettingsModal })));
1801
+ const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-tEr3bbtN.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1802
+ const SettingsModal$1 = lazy(() => import("./SettingsModal-BnHg4yeC.js").then((m) => ({ default: m.SettingsModal })));
1803
+ const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BZGSE9_r.js").then((m) => ({ default: m.UpgradeDriveModal })));
1870
1804
  const modalComponents = {
1871
1805
  addDrive: AddDriveModal$1,
1872
1806
  clearStorage: ClearStorageModal,
@@ -1878,11 +1812,11 @@ const modalComponents = {
1878
1812
  disclaimer: DisclaimerModal,
1879
1813
  driveSettings: DriveSettingsModal$1,
1880
1814
  downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
1881
- inspector: lazy(() => import("./InspectorModal-wChBJ6R5.js").then((m) => ({ default: m.InspectorModal }))),
1815
+ inspector: lazy(() => import("./InspectorModal-B2Zbsa4l.js").then((m) => ({ default: m.InspectorModal }))),
1882
1816
  settings: SettingsModal$1,
1883
1817
  upgradeDrive: UpgradeDriveModal,
1884
- missingPackage: lazy(() => import("./MissingPackageModal-Bn036mWQ.js").then((m) => ({ default: m.ConnectMissingPackageModal }))),
1885
- driveAuthRequired: lazy(() => import("./DriveAuthRequiredModal-DDlfeXD_.js").then((m) => ({ default: m.DriveAuthRequiredModal })))
1818
+ missingPackage: lazy(() => import("./MissingPackageModal-BQcCQbOn.js").then((m) => ({ default: m.ConnectMissingPackageModal }))),
1819
+ driveAuthRequired: lazy(() => import("./DriveAuthRequiredModal-BA2vS3oF.js").then((m) => ({ default: m.DriveAuthRequiredModal })))
1886
1820
  };
1887
1821
  const ModalsContainer = lazy(() => {
1888
1822
  return Promise.resolve({ default: () => {
@@ -1922,7 +1856,7 @@ const ServiceWorkerUpdatePrompt = () => {
1922
1856
  //#endregion
1923
1857
  //#region src/components/app-loader.tsx
1924
1858
  const AppLoader = (props) => {
1925
- const Load = lazy(() => import("./load-Bt4B0U-v.js").then((m) => m.loadComponent(props.localPackage)));
1859
+ const Load = lazy(() => import("./load-DajsG0zi.js").then((m) => m.loadComponent(props.localPackage)));
1926
1860
  return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
1927
1861
  fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
1928
1862
  resetKeys: [props.localPackage],
@@ -1945,12 +1879,13 @@ const AppLoader = (props) => {
1945
1879
  children: /* @__PURE__ */ jsx(ModalsContainer, {})
1946
1880
  }),
1947
1881
  /* @__PURE__ */ jsx(MigrationBanner, {}),
1948
- /* @__PURE__ */ jsx(ServiceWorkerUpdatePrompt, {})
1882
+ /* @__PURE__ */ jsx(ServiceWorkerUpdatePrompt, {}),
1883
+ /* @__PURE__ */ jsx(ConnectionBanner, {})
1949
1884
  ]
1950
1885
  }) });
1951
1886
  };
1952
1887
  //#endregion
1953
1888
  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 };
1954
1889
 
1955
- //# sourceMappingURL=app-loader-C5IWlQ7x.js.map
1956
- //# debugId=e953dc08-9a65-58dd-8382-5a31beb3ed26
1890
+ //# sourceMappingURL=app-loader-CuYQDicM.js.map
1891
+ //# debugId=5643cee8-d3b6-5800-a974-4c21fa405450