@powerhousedao/connect 6.2.0-dev.38 → 6.2.0-dev.39

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 (75) hide show
  1. package/dist/{AddDriveModal-BoKLJyUY.js → AddDriveModal-D-nbV40j.js} +4 -4
  2. package/dist/{AddDriveModal-BoKLJyUY.js.map → AddDriveModal-D-nbV40j.js.map} +1 -1
  3. package/dist/{ClearStorageModal-kAd_wAOs.js → ClearStorageModal-Y34xFYii.js} +4 -4
  4. package/dist/{ClearStorageModal-kAd_wAOs.js.map → ClearStorageModal-Y34xFYii.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-COZ8ehrF.js → DebugSettingsModal-CwLH5KC9.js} +6 -6
  10. package/dist/{DebugSettingsModal-COZ8ehrF.js.map → DebugSettingsModal-CwLH5KC9.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-B3VdLwSH.js → DriveAuthRequiredModal-B5-ZfKsb.js} +3 -3
  20. package/dist/{DriveAuthRequiredModal-B3VdLwSH.js.map → DriveAuthRequiredModal-B5-ZfKsb.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-so7krTny.js → InspectorModal-C1MvTLQV.js} +84 -35
  24. package/dist/InspectorModal-C1MvTLQV.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-CZ4zSICk.js → SettingsModal-C0gXNY6D.js} +9 -9
  28. package/dist/SettingsModal-C0gXNY6D.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-BVgVR-WX.js +4 -0
  32. package/dist/{app-loader-BcXcehGe.js → app-loader-BeaPtqWb.js} +193 -258
  33. package/dist/app-loader-BeaPtqWb.js.map +1 -0
  34. package/dist/{build-info-BCK6n_XY.js → build-info-BNG5pRW5.js} +8 -5
  35. package/dist/{build-info-BCK6n_XY.js.map → build-info-BNG5pRW5.js.map} +1 -1
  36. package/dist/components-DGNTgcZV.js +5 -0
  37. package/dist/{connect.config-Bt4pvvWV.js → connect.config-BG681xG9.js} +3 -3
  38. package/dist/{connect.config-Bt4pvvWV.js.map → connect.config-BG681xG9.js.map} +1 -1
  39. package/dist/connection-state-Cig644T0.js +126 -0
  40. package/dist/connection-state-Cig644T0.js.map +1 -0
  41. package/dist/{load-BRBI6pnT.js → load-C-XbtAd4.js} +11 -11
  42. package/dist/{load-BRBI6pnT.js.map → load-C-XbtAd4.js.map} +1 -1
  43. package/dist/main.js +1 -1
  44. package/dist/{package-B-TZdzz9.js → package-DUieCgZv.js} +5 -4
  45. package/dist/package-DUieCgZv.js.map +1 -0
  46. package/dist/{pglite-runtime-Ch2YeUAA.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-BWk7yOwr.js → pglite-seed-9rjhdCs5.js} +4 -4
  51. package/dist/{pglite-seed-BWk7yOwr.js.map → pglite-seed-9rjhdCs5.js.map} +1 -1
  52. package/dist/{reactor-BkaNhcsJ.js → reactor-DCmBjI53.js} +229 -17
  53. package/dist/reactor-DCmBjI53.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-D9l1kja7.js → registerServiceWorker-2tRbkdJj.js} +4 -4
  58. package/dist/{registerServiceWorker-D9l1kja7.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/{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/DriveSettingsModal-CsNFEJ9E.js.map +0 -1
  68. package/dist/InspectorModal-so7krTny.js.map +0 -1
  69. package/dist/SettingsModal-CZ4zSICk.js.map +0 -1
  70. package/dist/app-loader-BcXcehGe.js.map +0 -1
  71. package/dist/app-loader-gIHublFd.js +0 -4
  72. package/dist/components-Chon07yw.js +0 -5
  73. package/dist/package-B-TZdzz9.js.map +0 -1
  74. package/dist/pglite-runtime-Ch2YeUAA.js.map +0 -1
  75. package/dist/reactor-BkaNhcsJ.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]="aee78ba0-6668-5e8c-b501-328f31e9493f")}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]="fb81ff15-5efd-5d52-ac99-14da36a5814d")}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-Bt4pvvWV.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-Ch2YeUAA.js";
7
- import { t as serviceWorkerManager } from "./registerServiceWorker-D9l1kja7.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
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";
@@ -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];
@@ -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:
@@ -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.equals(DriveCollectionId.forDrive(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", {
@@ -1757,28 +1643,99 @@ function Sidebar() {
1757
1643
  }) });
1758
1644
  }
1759
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
1760
1673
  //#region src/components/migration-banner.tsx
1761
- let dismissed = false;
1762
- const listeners = /* @__PURE__ */ new Set();
1763
- function notify() {
1764
- for (const l of listeners) l();
1765
- }
1766
- function dismiss() {
1767
- dismissed = true;
1768
- 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
+ });
1769
1698
  }
1770
- function subscribeDismissed(cb) {
1771
- listeners.add(cb);
1772
- return () => {
1773
- 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
+ });
1774
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
+ });
1775
1732
  }
1776
- function getDismissed() {
1777
- return dismissed;
1778
- }
1779
- const MigrationBanner = () => {
1780
- const isDismissed = useSyncExternalStore(subscribeDismissed, getDismissed, () => false);
1781
- 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);
1782
1739
  const [migrating, setMigrating] = useState(false);
1783
1740
  const [error, setError] = useState(null);
1784
1741
  if (major === void 0 || major === null || major === 17) return null;
@@ -1786,75 +1743,52 @@ const MigrationBanner = () => {
1786
1743
  const handleMigrate = () => {
1787
1744
  setError(null);
1788
1745
  setMigrating(true);
1789
- migrateAllIfNeeded().then(() => {
1790
- window.location.reload();
1791
- }).catch((err) => {
1746
+ migrateAllIfNeeded().then(() => window.location.reload()).catch((err) => {
1792
1747
  setError(err instanceof Error ? err.message : String(err));
1793
1748
  setMigrating(false);
1794
1749
  });
1795
1750
  };
1796
- return /* @__PURE__ */ jsx("div", {
1797
- className: "absolute inset-x-0 top-0 z-30 flex justify-center p-3",
1798
- children: /* @__PURE__ */ jsxs("div", {
1799
- 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",
1800
- children: [
1801
- /* @__PURE__ */ jsxs("div", {
1802
- className: "flex-1",
1803
- children: [
1804
- /* @__PURE__ */ jsxs("div", {
1805
- className: "font-semibold",
1806
- children: [
1807
- "Your local database uses Postgres ",
1808
- major,
1809
- "."
1810
- ]
1811
- }),
1812
- /* @__PURE__ */ jsxs("div", {
1813
- className: "text-foreground",
1814
- children: [
1815
- "Migrate to Postgres ",
1816
- 17,
1817
- " to pick up the latest features. Your data will be backed up first."
1818
- ]
1819
- }),
1820
- error && /* @__PURE__ */ jsxs("div", {
1821
- className: "mt-2 font-medium text-destructive",
1822
- children: ["Migration failed: ", error]
1823
- })
1824
- ]
1825
- }),
1826
- /* @__PURE__ */ jsx("button", {
1827
- type: "button",
1828
- disabled: migrating,
1829
- onClick: handleMigrate,
1830
- className: "rounded-sm bg-primary px-3 py-1 text-sm font-medium text-primary-foreground hover:hover-effect disabled:disabled-effect",
1831
- children: migrating ? "Migrating…" : "Migrate now"
1832
- }),
1833
- /* @__PURE__ */ jsx("button", {
1834
- type: "button",
1835
- disabled: migrating,
1836
- onClick: dismiss,
1837
- className: "rounded-sm border border-foreground bg-transparent px-3 py-1 text-sm font-medium text-foreground hover:hover-effect disabled:disabled-effect",
1838
- children: "Dismiss"
1839
- })
1840
- ]
1841
- })
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
+ })]
1842
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, {});
1843
1777
  };
1844
1778
  //#endregion
1845
1779
  //#region src/components/modal/modals-container.tsx
1846
- const AddDriveModal$1 = lazy(() => import("./AddDriveModal-BoKLJyUY.js").then((m) => ({ default: m.AddDriveModal })));
1847
- const ClearStorageModal = lazy(() => import("./ClearStorageModal-kAd_wAOs.js").then((m) => ({ default: m.ClearStorageModal })));
1848
- const CookiesPolicyModal = lazy(() => import("./CookiesPolicyModal-1nOh6oN3.js").then((m) => ({ default: m.CookiesPolicyModal })));
1849
- const CreateDocumentModal$1 = lazy(() => import("./CreateDocumentModal-nQbLVDq3.js").then((m) => ({ default: m.CreateDocumentModal })));
1850
- const DebugSettingsModal = lazy(() => import("./DebugSettingsModal-COZ8ehrF.js").then((m) => ({ default: m.DebugSettingsModal })));
1851
- const DeleteDriveModal = lazy(() => import("./DeleteDriveModal-6P0T1QgD.js").then((m) => ({ default: m.DeleteDriveModal })));
1852
- const DeleteItemModal = lazy(() => import("./DeleteItemModal-BmV1aQyZ.js").then((m) => ({ default: m.DeleteItemModal })));
1853
- const DisclaimerModal = lazy(() => import("./DisclaimerModal-CVTFfN0_.js").then((m) => ({ default: m.DisclaimerModal })));
1854
- const DriveSettingsModal$1 = lazy(() => import("./DriveSettingsModal-CsNFEJ9E.js").then((m) => ({ default: m.DriveSettingsModal })));
1855
- const DownloadDocumentWithErrorsModal = lazy(() => import("./DownloadDocumentWithErrorsModal-CXeFUtaz.js").then((m) => ({ default: m.DownloadDocumentWithErrorsModal })));
1856
- const SettingsModal$1 = lazy(() => import("./SettingsModal-CZ4zSICk.js").then((m) => ({ default: m.SettingsModal })));
1857
- const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-C7lV4rAX.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-Y34xFYii.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-CwLH5KC9.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-C0gXNY6D.js").then((m) => ({ default: m.SettingsModal })));
1791
+ const UpgradeDriveModal = lazy(() => import("./UpgradeDriveModal-BZGSE9_r.js").then((m) => ({ default: m.UpgradeDriveModal })));
1858
1792
  const modalComponents = {
1859
1793
  addDrive: AddDriveModal$1,
1860
1794
  clearStorage: ClearStorageModal,
@@ -1866,11 +1800,11 @@ const modalComponents = {
1866
1800
  disclaimer: DisclaimerModal,
1867
1801
  driveSettings: DriveSettingsModal$1,
1868
1802
  downloadDocumentWithErrors: DownloadDocumentWithErrorsModal,
1869
- inspector: lazy(() => import("./InspectorModal-so7krTny.js").then((m) => ({ default: m.InspectorModal }))),
1803
+ inspector: lazy(() => import("./InspectorModal-C1MvTLQV.js").then((m) => ({ default: m.InspectorModal }))),
1870
1804
  settings: SettingsModal$1,
1871
1805
  upgradeDrive: UpgradeDriveModal,
1872
- missingPackage: lazy(() => import("./MissingPackageModal-Bn036mWQ.js").then((m) => ({ default: m.ConnectMissingPackageModal }))),
1873
- driveAuthRequired: lazy(() => import("./DriveAuthRequiredModal-B3VdLwSH.js").then((m) => ({ default: m.DriveAuthRequiredModal })))
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 })))
1874
1808
  };
1875
1809
  const ModalsContainer = lazy(() => {
1876
1810
  return Promise.resolve({ default: () => {
@@ -1890,7 +1824,7 @@ const ModalsContainer = lazy(() => {
1890
1824
  //#endregion
1891
1825
  //#region src/components/app-loader.tsx
1892
1826
  const AppLoader = (props) => {
1893
- const Load = lazy(() => import("./load-BRBI6pnT.js").then((m) => m.loadComponent(props.localPackage)));
1827
+ const Load = lazy(() => import("./load-C-XbtAd4.js").then((m) => m.loadComponent(props.localPackage)));
1894
1828
  return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsxs(ErrorBoundary$1, {
1895
1829
  fallbackRender: (props) => /* @__PURE__ */ jsx(AppSkeleton, { children: /* @__PURE__ */ jsx(DetailedFallback, { ...props }) }),
1896
1830
  resetKeys: [props.localPackage],
@@ -1912,12 +1846,13 @@ const AppLoader = (props) => {
1912
1846
  name: "ModalsContainer",
1913
1847
  children: /* @__PURE__ */ jsx(ModalsContainer, {})
1914
1848
  }),
1915
- /* @__PURE__ */ jsx(MigrationBanner, {})
1849
+ /* @__PURE__ */ jsx(MigrationBanner, {}),
1850
+ /* @__PURE__ */ jsx(ConnectionBanner, {})
1916
1851
  ]
1917
1852
  }) });
1918
1853
  };
1919
1854
  //#endregion
1920
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 };
1921
1856
 
1922
- //# sourceMappingURL=app-loader-BcXcehGe.js.map
1923
- //# debugId=aee78ba0-6668-5e8c-b501-328f31e9493f
1857
+ //# sourceMappingURL=app-loader-BeaPtqWb.js.map
1858
+ //# debugId=fb81ff15-5efd-5d52-ac99-14da36a5814d