@powerhousedao/connect 6.2.3-dev.32 → 6.2.3-dev.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{ClearStorageModal-D_qIH8xO.js → ClearStorageModal-CyQfpQgd.js} +4 -4
  2. package/dist/{ClearStorageModal-D_qIH8xO.js.map → ClearStorageModal-CyQfpQgd.js.map} +1 -1
  3. package/dist/{DebugSettingsModal-CqTKcFT6.js → DebugSettingsModal-ftX1TEN_.js} +4 -4
  4. package/dist/{DebugSettingsModal-CqTKcFT6.js.map → DebugSettingsModal-ftX1TEN_.js.map} +1 -1
  5. package/dist/{InspectorModal-tGsfYXkd.js → InspectorModal-CGdyIReA.js} +56 -18
  6. package/dist/InspectorModal-CGdyIReA.js.map +1 -0
  7. package/dist/{OpenFileDocumentsModal-DuMkAI98.js → OpenFileDocumentsModal-BtbrRLj_.js} +4 -4
  8. package/dist/{OpenFileDocumentsModal-DuMkAI98.js.map → OpenFileDocumentsModal-BtbrRLj_.js.map} +1 -1
  9. package/dist/{SettingsModal-B7cyFF6I.js → SettingsModal-CCK6biQm.js} +5 -5
  10. package/dist/{SettingsModal-B7cyFF6I.js.map → SettingsModal-CCK6biQm.js.map} +1 -1
  11. package/dist/app-loader-HZ41uC1O.js +4 -0
  12. package/dist/{app-loader-DMtilkt3.js → app-loader-eIErMqM8.js} +49 -13
  13. package/dist/app-loader-eIErMqM8.js.map +1 -0
  14. package/dist/{build-info-CQAER_nk.js → build-info-CNHv6iwN.js} +5 -5
  15. package/dist/{build-info-CQAER_nk.js.map → build-info-CNHv6iwN.js.map} +1 -1
  16. package/dist/{components-DOnhm8ra.js → components-DoZMPd0b.js} +3 -3
  17. package/dist/{connection-state-DJX_vUhI.js → connection-state-Eqc2izmt.js} +4 -4
  18. package/dist/{connection-state-DJX_vUhI.js.map → connection-state-Eqc2izmt.js.map} +1 -1
  19. package/dist/{load-uNwKzH6m.js → load-DV4AXFcM.js} +7 -7
  20. package/dist/{load-uNwKzH6m.js.map → load-DV4AXFcM.js.map} +1 -1
  21. package/dist/main.js +1 -1
  22. package/dist/{pglite-major-BbmMK26m.js → pglite-major-p4_YefAE.js} +23 -5
  23. package/dist/pglite-major-p4_YefAE.js.map +1 -0
  24. package/dist/{pglite-migrate-core-o88cWesm.js → pglite-migrate-core-BcXcImng.js} +4 -4
  25. package/dist/{pglite-migrate-core-o88cWesm.js.map → pglite-migrate-core-BcXcImng.js.map} +1 -1
  26. package/dist/{pglite-seed-AR1MKM1R.js → pglite-seed-Cl2d-iyl.js} +4 -4
  27. package/dist/{pglite-seed-AR1MKM1R.js.map → pglite-seed-Cl2d-iyl.js.map} +1 -1
  28. package/dist/{reactor-CHFsGnJ2.js → reactor--yIPUbFV.js} +20 -10
  29. package/dist/reactor--yIPUbFV.js.map +1 -0
  30. package/dist/reactor.worker.js +33 -6
  31. package/dist/reactor.worker.js.map +1 -1
  32. package/dist/start-connect.js +1 -1
  33. package/package.json +13 -13
  34. package/dist/InspectorModal-tGsfYXkd.js.map +0 -1
  35. package/dist/app-loader-DMtilkt3.js.map +0 -1
  36. package/dist/app-loader-DSuZw3NZ.js +0 -4
  37. package/dist/pglite-major-BbmMK26m.js.map +0 -1
  38. package/dist/reactor-CHFsGnJ2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"load-uNwKzH6m.js","sources":["../src/hooks/useCheckLatestVersion.ts","../src/hooks/utils.ts","../src/store/user.ts","../src/components/load.tsx"],"sourcesContent":["import { connectConfig } from \"@powerhousedao/connect/config\";\nimport { getBuildHashStatus } from \"@powerhousedao/connect/hooks\";\nimport { logger } from \"document-model\";\nimport { useEffect } from \"react\";\n\n// Session-scoped guard: records the deployed hash this tab already reloaded\n// for, so a broken or rolling deploy (server hash keeps changing under us)\n// cannot turn the tab into a reload loop. Cleared implicitly with the tab.\nconst RELOADED_FOR_KEY = \"ph-reloaded-for-build-hash\";\n\n/**\n * Drop the service worker's stale caches (precache + the NetworkFirst shell\n * cache) before reloading onto a new deploy, so the post-reload navigation\n * is answered from the network / fresh build instead of leftovers of the\n * build we are leaving. Best-effort: if the Caches API is unavailable or a\n * delete fails, the reload still picks up the new shell (the navigation\n * route is NetworkFirst).\n */\nasync function clearStaleCaches(): Promise<void> {\n try {\n if (!(\"caches\" in window)) return;\n const keys = await window.caches.keys();\n await Promise.all(\n keys\n .filter((key) => key.includes(\"precache\") || key.includes(\"ph-shell\"))\n .map((key) => window.caches.delete(key)),\n );\n } catch (error) {\n logger.warn(\n \"Failed to clear stale caches before update reload @error\",\n error,\n );\n }\n}\n\n/**\n * Detects that the server is serving a different build than the one this\n * page was loaded from (a new deploy) and reloads onto it — once per session\n * per deployed hash. Checked on mount and whenever the tab returns to the\n * foreground, so a deploy that lands while the tab sits open is picked up on\n * the next focus without a manual reload. The in-tab \"new version available\"\n * service-worker prompt (ServiceWorkerUpdatePrompt) remains the opt-in path\n * for workers that are waiting but not yet controlling.\n */\nexport const useCheckLatestVersion = () => {\n useEffect(() => {\n if (\n import.meta.env.MODE === \"development\" ||\n connectConfig.studioMode ||\n !connectConfig.warnOutdatedApp\n ) {\n return;\n }\n\n const checkBuildHash = async () => {\n const status = await getBuildHashStatus();\n if (!status || status.isCurrent) return;\n\n const reloadedFor = window.sessionStorage.getItem(RELOADED_FOR_KEY);\n if (reloadedFor === status.deployedHash) return;\n window.sessionStorage.setItem(RELOADED_FOR_KEY, status.deployedHash);\n\n logger.info(\n \"New deploy detected — reloading from build @currentHash to @deployedHash\",\n status.currentHash,\n status.deployedHash,\n );\n await clearStaleCaches();\n window.location.reload();\n };\n\n void checkBuildHash();\n const onVisibilityChange = () => {\n if (document.visibilityState === \"visible\") void checkBuildHash();\n };\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n return () => {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n };\n }, []);\n};\n","import { getBuildHash } from \"../utils/build-info.js\";\n\nexport const isMac = window.navigator.appVersion.includes(\"Mac\");\n\nexport interface BuildHashStatus {\n /** Hash baked into the running build. */\n currentHash: string;\n /** Hash the server is currently serving. */\n deployedHash: string;\n /** true when the running build matches what the server serves. */\n isCurrent: boolean;\n}\n\n/**\n * Same-origin build-identity probe. The build bakes a hash of the inputs that\n * determine the deployed content into the bundle (define\n * `PH_CONNECT_BUILD_HASH`, see builder-tools' connectBuildHashPlugin) and\n * emits `build-hash.json` next to the app (served no-cache). Comparing the\n * two tells us whether the server is serving a different build than the one\n * this page was loaded from — the reliable \"a new deploy went out\" signal.\n * Unlike the old GitHub-raw version check it works on localhost (it compares\n * against what the origin actually serves, not a remote branch head) and\n * needs no network beyond the app's own origin.\n *\n * Returns null when there is nothing to compare: dev/studio builds (no hash\n * baked), a server predating `build-hash.json`, an offline fetch, or a\n * malformed body.\n */\nexport const getBuildHashStatus = async (): Promise<BuildHashStatus | null> => {\n const currentHash = getBuildHash();\n if (!currentHash || currentHash === \"unknown\") return null;\n try {\n const result = await fetch(`${import.meta.env.BASE_URL}build-hash.json`, {\n cache: \"no-cache\",\n });\n if (!result.ok) return null;\n const data = (await result.json()) as { hash?: unknown };\n if (typeof data.hash !== \"string\" || !data.hash) return null;\n return {\n currentHash,\n deployedHash: data.hash,\n isCurrent: data.hash === currentHash,\n };\n } catch {\n return null;\n }\n};\n","import { useUser } from \"@powerhousedao/reactor-browser\";\nimport type { User as SentryUser } from \"@sentry/react\";\nimport { useEffect } from \"react\";\nimport { setUser as setSentryUser } from \"../services/sentry.js\";\n\nexport function useSetSentryUser() {\n const user = useUser();\n useEffect(() => {\n let sentryUser: SentryUser | null = null;\n if (user) {\n // saves the user info except the credential\n const { credential: _credential, ...rest } = user;\n sentryUser = { id: rest.did, username: rest.ens?.name, ...rest };\n }\n setSentryUser(sentryUser);\n }, [user]);\n}\n","import { useCheckLatestVersion } from \"@powerhousedao/connect/hooks\";\nimport \"@powerhousedao/connect/i18n\";\nimport { createReactor, useSetSentryUser } from \"@powerhousedao/connect/store\";\nimport {\n detectMigrationMajor,\n detectReactorPgMajor,\n seedPendingPgVersion,\n} from \"@powerhousedao/connect/utils\";\nimport { initTheme } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentModelLib } from \"document-model\";\nimport { type ReactNode } from \"react\";\nimport { applyConnectBranding, loadRuntimeConfig } from \"../runtime-config.js\";\n\nexport async function loadComponent(localPackage?: DocumentModelLib) {\n await seedPendingPgVersion();\n await Promise.all([detectReactorPgMajor(), detectMigrationMajor()]);\n const runtimeConfig = await loadRuntimeConfig();\n applyConnectBranding(runtimeConfig);\n await createReactor(localPackage);\n return {\n default: ({ children }: { children?: ReactNode }) => {\n initTheme();\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useSetSentryUser();\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useCheckLatestVersion();\n return children;\n },\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAQA,MAAM,mBAAmB;;;;;;;;;AAUzB,eAAe,mBAAkC;CAC/C,IAAI;EACF,IAAI,EAAE,YAAY,SAAS;EAC3B,MAAM,OAAO,MAAM,OAAO,OAAO,KAAK;EACtC,MAAM,QAAQ,IACZ,KACG,QAAQ,QAAQ,IAAI,SAAS,UAAU,KAAK,IAAI,SAAS,UAAU,CAAC,CAAC,CACrE,KAAK,QAAQ,OAAO,OAAO,OAAO,GAAG,CAAC,CAC3C;CACF,SAAS,OAAO;EACd,OAAO,KACL,4DACA,KACF;CACF;AACF;;;;;;;;;;AAWA,MAAa,8BAA8B;CACzC,gBAAgB;EACd,IACE,YAAY,IAAI,SAAS,iBACzB,cAAc,cACd,CAAC,cAAc,iBAEf;EAGF,MAAM,iBAAiB,YAAY;GACjC,MAAM,SAAS,MAAM,mBAAmB;GACxC,IAAI,CAAC,UAAU,OAAO,WAAW;GAGjC,IADoB,OAAO,eAAe,QAAQ,gBACpC,MAAM,OAAO,cAAc;GACzC,OAAO,eAAe,QAAQ,kBAAkB,OAAO,YAAY;GAEnE,OAAO,KACL,4EACA,OAAO,aACP,OAAO,YACT;GACA,MAAM,iBAAiB;GACvB,OAAO,SAAS,OAAO;EACzB;EAEA,eAAoB;EACpB,MAAM,2BAA2B;GAC/B,IAAI,SAAS,oBAAoB,WAAW,eAAoB;EAClE;EACA,SAAS,iBAAiB,oBAAoB,kBAAkB;EAChE,aAAa;GACX,SAAS,oBAAoB,oBAAoB,kBAAkB;EACrE;CACF,GAAG,CAAC,CAAC;AACP;AC9EqB,OAAO,UAAU,WAAW,SAAS,KAAK;;;;;;;;;;;;;;;;AA0B/D,MAAa,qBAAqB,YAA6C;CAC7E,MAAM,cAAc,aAAa;CACjC,IAAI,CAAC,eAAe,gBAAgB,WAAW,OAAO;CACtD,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,GAAG,YAAY,IAAI,SAAS,kBAAkB,EACvE,OAAO,WACT,CAAC;EACD,IAAI,CAAC,OAAO,IAAI,OAAO;EACvB,MAAM,OAAQ,MAAM,OAAO,KAAK;EAChC,IAAI,OAAO,KAAK,SAAS,YAAY,CAAC,KAAK,MAAM,OAAO;EACxD,OAAO;GACL;GACA,cAAc,KAAK;GACnB,WAAW,KAAK,SAAS;EAC3B;CACF,QAAQ;EACN,OAAO;CACT;AACF;;;ACzCA,SAAgB,mBAAmB;CACjC,MAAM,OAAO,QAAQ;CACrB,gBAAgB;EACd,IAAI,aAAgC;EACpC,IAAI,MAAM;GAER,MAAM,EAAE,YAAY,aAAa,GAAG,SAAS;GAC7C,aAAa;IAAE,IAAI,KAAK;IAAK,UAAU,KAAK,KAAK;IAAM,GAAG;GAAK;EACjE;EACA,QAAc,UAAU;CAC1B,GAAG,CAAC,IAAI,CAAC;AACX;;;ACHA,eAAsB,cAAc,cAAiC;CACnE,MAAM,qBAAqB;CAC3B,MAAM,QAAQ,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC,CAAC;CAClE,MAAM,gBAAgB,MAAM,kBAAkB;CAC9C,qBAAqB,aAAa;CAClC,MAAM,cAAc,YAAY;CAChC,OAAO,EACL,UAAU,EAAE,eAAyC;EACnD,UAAU;EAEV,iBAAiB;EAEjB,sBAAsB;EACtB,OAAO;CACT,EACF;AACF","debug_id":"7021b8a4-a0a9-5ab1-a097-e577561a1a17"}
1
+ {"version":3,"file":"load-DV4AXFcM.js","sources":["../src/hooks/useCheckLatestVersion.ts","../src/hooks/utils.ts","../src/store/user.ts","../src/components/load.tsx"],"sourcesContent":["import { connectConfig } from \"@powerhousedao/connect/config\";\nimport { getBuildHashStatus } from \"@powerhousedao/connect/hooks\";\nimport { logger } from \"document-model\";\nimport { useEffect } from \"react\";\n\n// Session-scoped guard: records the deployed hash this tab already reloaded\n// for, so a broken or rolling deploy (server hash keeps changing under us)\n// cannot turn the tab into a reload loop. Cleared implicitly with the tab.\nconst RELOADED_FOR_KEY = \"ph-reloaded-for-build-hash\";\n\n/**\n * Drop the service worker's stale caches (precache + the NetworkFirst shell\n * cache) before reloading onto a new deploy, so the post-reload navigation\n * is answered from the network / fresh build instead of leftovers of the\n * build we are leaving. Best-effort: if the Caches API is unavailable or a\n * delete fails, the reload still picks up the new shell (the navigation\n * route is NetworkFirst).\n */\nasync function clearStaleCaches(): Promise<void> {\n try {\n if (!(\"caches\" in window)) return;\n const keys = await window.caches.keys();\n await Promise.all(\n keys\n .filter((key) => key.includes(\"precache\") || key.includes(\"ph-shell\"))\n .map((key) => window.caches.delete(key)),\n );\n } catch (error) {\n logger.warn(\n \"Failed to clear stale caches before update reload @error\",\n error,\n );\n }\n}\n\n/**\n * Detects that the server is serving a different build than the one this\n * page was loaded from (a new deploy) and reloads onto it — once per session\n * per deployed hash. Checked on mount and whenever the tab returns to the\n * foreground, so a deploy that lands while the tab sits open is picked up on\n * the next focus without a manual reload. The in-tab \"new version available\"\n * service-worker prompt (ServiceWorkerUpdatePrompt) remains the opt-in path\n * for workers that are waiting but not yet controlling.\n */\nexport const useCheckLatestVersion = () => {\n useEffect(() => {\n if (\n import.meta.env.MODE === \"development\" ||\n connectConfig.studioMode ||\n !connectConfig.warnOutdatedApp\n ) {\n return;\n }\n\n const checkBuildHash = async () => {\n const status = await getBuildHashStatus();\n if (!status || status.isCurrent) return;\n\n const reloadedFor = window.sessionStorage.getItem(RELOADED_FOR_KEY);\n if (reloadedFor === status.deployedHash) return;\n window.sessionStorage.setItem(RELOADED_FOR_KEY, status.deployedHash);\n\n logger.info(\n \"New deploy detected — reloading from build @currentHash to @deployedHash\",\n status.currentHash,\n status.deployedHash,\n );\n await clearStaleCaches();\n window.location.reload();\n };\n\n void checkBuildHash();\n const onVisibilityChange = () => {\n if (document.visibilityState === \"visible\") void checkBuildHash();\n };\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n return () => {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n };\n }, []);\n};\n","import { getBuildHash } from \"../utils/build-info.js\";\n\nexport const isMac = window.navigator.appVersion.includes(\"Mac\");\n\nexport interface BuildHashStatus {\n /** Hash baked into the running build. */\n currentHash: string;\n /** Hash the server is currently serving. */\n deployedHash: string;\n /** true when the running build matches what the server serves. */\n isCurrent: boolean;\n}\n\n/**\n * Same-origin build-identity probe. The build bakes a hash of the inputs that\n * determine the deployed content into the bundle (define\n * `PH_CONNECT_BUILD_HASH`, see builder-tools' connectBuildHashPlugin) and\n * emits `build-hash.json` next to the app (served no-cache). Comparing the\n * two tells us whether the server is serving a different build than the one\n * this page was loaded from — the reliable \"a new deploy went out\" signal.\n * Unlike the old GitHub-raw version check it works on localhost (it compares\n * against what the origin actually serves, not a remote branch head) and\n * needs no network beyond the app's own origin.\n *\n * Returns null when there is nothing to compare: dev/studio builds (no hash\n * baked), a server predating `build-hash.json`, an offline fetch, or a\n * malformed body.\n */\nexport const getBuildHashStatus = async (): Promise<BuildHashStatus | null> => {\n const currentHash = getBuildHash();\n if (!currentHash || currentHash === \"unknown\") return null;\n try {\n const result = await fetch(`${import.meta.env.BASE_URL}build-hash.json`, {\n cache: \"no-cache\",\n });\n if (!result.ok) return null;\n const data = (await result.json()) as { hash?: unknown };\n if (typeof data.hash !== \"string\" || !data.hash) return null;\n return {\n currentHash,\n deployedHash: data.hash,\n isCurrent: data.hash === currentHash,\n };\n } catch {\n return null;\n }\n};\n","import { useUser } from \"@powerhousedao/reactor-browser\";\nimport type { User as SentryUser } from \"@sentry/react\";\nimport { useEffect } from \"react\";\nimport { setUser as setSentryUser } from \"../services/sentry.js\";\n\nexport function useSetSentryUser() {\n const user = useUser();\n useEffect(() => {\n let sentryUser: SentryUser | null = null;\n if (user) {\n // saves the user info except the credential\n const { credential: _credential, ...rest } = user;\n sentryUser = { id: rest.did, username: rest.ens?.name, ...rest };\n }\n setSentryUser(sentryUser);\n }, [user]);\n}\n","import { useCheckLatestVersion } from \"@powerhousedao/connect/hooks\";\nimport \"@powerhousedao/connect/i18n\";\nimport { createReactor, useSetSentryUser } from \"@powerhousedao/connect/store\";\nimport {\n detectMigrationMajor,\n detectReactorPgMajor,\n seedPendingPgVersion,\n} from \"@powerhousedao/connect/utils\";\nimport { initTheme } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentModelLib } from \"document-model\";\nimport { type ReactNode } from \"react\";\nimport { applyConnectBranding, loadRuntimeConfig } from \"../runtime-config.js\";\n\nexport async function loadComponent(localPackage?: DocumentModelLib) {\n await seedPendingPgVersion();\n await Promise.all([detectReactorPgMajor(), detectMigrationMajor()]);\n const runtimeConfig = await loadRuntimeConfig();\n applyConnectBranding(runtimeConfig);\n await createReactor(localPackage);\n return {\n default: ({ children }: { children?: ReactNode }) => {\n initTheme();\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useSetSentryUser();\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useCheckLatestVersion();\n return children;\n },\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAQA,MAAM,mBAAmB;;;;;;;;;AAUzB,eAAe,mBAAkC;CAC/C,IAAI;EACF,IAAI,EAAE,YAAY,SAAS;EAC3B,MAAM,OAAO,MAAM,OAAO,OAAO,KAAK;EACtC,MAAM,QAAQ,IACZ,KACG,QAAQ,QAAQ,IAAI,SAAS,UAAU,KAAK,IAAI,SAAS,UAAU,CAAC,CAAC,CACrE,KAAK,QAAQ,OAAO,OAAO,OAAO,GAAG,CAAC,CAC3C;CACF,SAAS,OAAO;EACd,OAAO,KACL,4DACA,KACF;CACF;AACF;;;;;;;;;;AAWA,MAAa,8BAA8B;CACzC,gBAAgB;EACd,IACE,YAAY,IAAI,SAAS,iBACzB,cAAc,cACd,CAAC,cAAc,iBAEf;EAGF,MAAM,iBAAiB,YAAY;GACjC,MAAM,SAAS,MAAM,mBAAmB;GACxC,IAAI,CAAC,UAAU,OAAO,WAAW;GAGjC,IADoB,OAAO,eAAe,QAAQ,gBACpC,MAAM,OAAO,cAAc;GACzC,OAAO,eAAe,QAAQ,kBAAkB,OAAO,YAAY;GAEnE,OAAO,KACL,4EACA,OAAO,aACP,OAAO,YACT;GACA,MAAM,iBAAiB;GACvB,OAAO,SAAS,OAAO;EACzB;EAEA,eAAoB;EACpB,MAAM,2BAA2B;GAC/B,IAAI,SAAS,oBAAoB,WAAW,eAAoB;EAClE;EACA,SAAS,iBAAiB,oBAAoB,kBAAkB;EAChE,aAAa;GACX,SAAS,oBAAoB,oBAAoB,kBAAkB;EACrE;CACF,GAAG,CAAC,CAAC;AACP;AC9EqB,OAAO,UAAU,WAAW,SAAS,KAAK;;;;;;;;;;;;;;;;AA0B/D,MAAa,qBAAqB,YAA6C;CAC7E,MAAM,cAAc,aAAa;CACjC,IAAI,CAAC,eAAe,gBAAgB,WAAW,OAAO;CACtD,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,GAAG,YAAY,IAAI,SAAS,kBAAkB,EACvE,OAAO,WACT,CAAC;EACD,IAAI,CAAC,OAAO,IAAI,OAAO;EACvB,MAAM,OAAQ,MAAM,OAAO,KAAK;EAChC,IAAI,OAAO,KAAK,SAAS,YAAY,CAAC,KAAK,MAAM,OAAO;EACxD,OAAO;GACL;GACA,cAAc,KAAK;GACnB,WAAW,KAAK,SAAS;EAC3B;CACF,QAAQ;EACN,OAAO;CACT;AACF;;;ACzCA,SAAgB,mBAAmB;CACjC,MAAM,OAAO,QAAQ;CACrB,gBAAgB;EACd,IAAI,aAAgC;EACpC,IAAI,MAAM;GAER,MAAM,EAAE,YAAY,aAAa,GAAG,SAAS;GAC7C,aAAa;IAAE,IAAI,KAAK;IAAK,UAAU,KAAK,KAAK;IAAM,GAAG;GAAK;EACjE;EACA,QAAc,UAAU;CAC1B,GAAG,CAAC,IAAI,CAAC;AACX;;;ACHA,eAAsB,cAAc,cAAiC;CACnE,MAAM,qBAAqB;CAC3B,MAAM,QAAQ,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC,CAAC;CAClE,MAAM,gBAAgB,MAAM,kBAAkB;CAC9C,qBAAqB,aAAa;CAClC,MAAM,cAAc,YAAY;CAChC,OAAO,EACL,UAAU,EAAE,eAAyC;EACnD,UAAU;EAEV,iBAAiB;EAEjB,sBAAsB;EACtB,OAAO;CACT,EACF;AACF","debug_id":"4889212b-d5de-5871-95aa-6f3b7506b335"}
package/dist/main.js CHANGED
@@ -5,7 +5,7 @@ import { jsx } from "react/jsx-runtime";
5
5
  //#region main.tsx
6
6
  const root = await bootConnect();
7
7
  if (root) {
8
- const { AppLoader } = await import("./app-loader-DSuZw3NZ.js");
8
+ const { AppLoader } = await import("./app-loader-HZ41uC1O.js");
9
9
  root.render(/* @__PURE__ */ jsx(AppLoader, {}));
10
10
  }
11
11
  //#endregion
@@ -1,6 +1,24 @@
1
- //#region src/utils/pglite-idb.ts
2
1
 
3
- !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]="ae106f6d-a19b-578a-a8b6-6a2e690d0eea")}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]="bf83be21-3f86-55bd-ae14-c4aa466d5a81")}catch(e){}}();
3
+ import { UnsupportedStoredProtocolError } from "@powerhousedao/reactor";
4
+ //#region src/utils/stored-documents-refused.ts
5
+ const STORED_DOCUMENTS_REFUSED = "StoredDocumentsRefusedError";
6
+ var StoredDocumentsRefusedError = class extends Error {
7
+ constructor(cause) {
8
+ const named = cause.versions.map(({ protocol, version }) => `${protocol} ${version}`).join(", ");
9
+ super(`This browser holds ${cause.documents} document(s) that require ${named}, which this version of Connect does not run. Open them with a Connect build that runs ${named}, or set connect.reactor.unsupportedStoredDocuments to "read-only" in powerhouse.config.json to open them read-only.`, { cause });
10
+ this.name = STORED_DOCUMENTS_REFUSED;
11
+ }
12
+ };
13
+ /** Rewrites the reactor's refusal for the boot screen. */
14
+ function toStoredDocumentsRefused(error) {
15
+ return UnsupportedStoredProtocolError.isError(error) ? new StoredDocumentsRefusedError(error) : error;
16
+ }
17
+ function isStoredDocumentsRefused(error) {
18
+ return error instanceof Error && error.name === "StoredDocumentsRefusedError";
19
+ }
20
+ //#endregion
21
+ //#region src/utils/pglite-idb.ts
4
22
  const IDB_STORE_NAME = "FILE_DATA";
5
23
  function idbError(req, context) {
6
24
  const cause = req.error ?? /* @__PURE__ */ new Error("unknown IDB error");
@@ -92,7 +110,7 @@ async function loadPgDump(major) {
92
110
  throw new Error(`Unsupported PGlite major: ${String(major)}`);
93
111
  }
94
112
  //#endregion
95
- export { resolvePgMajorForRuntime as a, idbError as c, loadPgDump as i, openIdb as l, isMigratableMajor as n, IDB_STORE_NAME as o, loadPGliteModule as r, createFileDataStore as s, coerceMajor as t, readPgVersionFile as u };
113
+ export { resolvePgMajorForRuntime as a, idbError as c, isStoredDocumentsRefused as d, toStoredDocumentsRefused as f, loadPgDump as i, openIdb as l, isMigratableMajor as n, IDB_STORE_NAME as o, loadPGliteModule as r, createFileDataStore as s, coerceMajor as t, readPgVersionFile as u };
96
114
 
97
- //# sourceMappingURL=pglite-major-BbmMK26m.js.map
98
- //# debugId=ae106f6d-a19b-578a-a8b6-6a2e690d0eea
115
+ //# sourceMappingURL=pglite-major-p4_YefAE.js.map
116
+ //# debugId=bf83be21-3f86-55bd-ae14-c4aa466d5a81
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pglite-major-p4_YefAE.js","sources":["../src/utils/stored-documents-refused.ts","../src/utils/pglite-idb.ts","../src/utils/pglite-major.ts"],"sourcesContent":["import { UnsupportedStoredProtocolError } from \"@powerhousedao/reactor\";\n\nexport const STORED_DOCUMENTS_REFUSED = \"StoredDocumentsRefusedError\";\n\n// Only name and message cross the worker boundary, so the message says it all.\nexport class StoredDocumentsRefusedError extends Error {\n constructor(cause: UnsupportedStoredProtocolError) {\n const named = cause.versions\n .map(({ protocol, version }) => `${protocol} ${version}`)\n .join(\", \");\n super(\n `This browser holds ${cause.documents} document(s) that require ${named}, which this version of Connect does not run. ` +\n `Open them with a Connect build that runs ${named}, or set connect.reactor.unsupportedStoredDocuments to \"read-only\" in powerhouse.config.json to open them read-only.`,\n { cause },\n );\n this.name = STORED_DOCUMENTS_REFUSED;\n }\n}\n\n/** Rewrites the reactor's refusal for the boot screen. */\nexport function toStoredDocumentsRefused(error: unknown): unknown {\n return UnsupportedStoredProtocolError.isError(error)\n ? new StoredDocumentsRefusedError(error)\n : error;\n}\n\nexport function isStoredDocumentsRefused(error: unknown): error is Error {\n return error instanceof Error && error.name === STORED_DOCUMENTS_REFUSED;\n}\n","export const IDB_STORE_NAME = \"FILE_DATA\";\nexport const IDB_DB_VERSION = 21;\n\ntype FileDataValue = {\n contents: Uint8Array | number[];\n mode: number;\n timestamp: Date | number;\n};\n\nexport function idbError(\n req: IDBRequest | IDBTransaction,\n context: string,\n): Error {\n const cause = req.error ?? new Error(\"unknown IDB error\");\n return new Error(`${context}: ${cause.message}`, { cause });\n}\n\nexport function indexedDbExists(name: string): Promise<boolean> {\n if (typeof indexedDB.databases === \"function\") {\n return indexedDB\n .databases()\n .then((dbs) => dbs.some((d) => d.name === name))\n .catch(() => true);\n }\n return Promise.resolve(true);\n}\n\nexport function openIdb(\n name: string,\n version: number,\n upgrade?: (db: IDBDatabase) => void,\n): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(name, version);\n req.onerror = () => reject(idbError(req, `IDB open failed for ${name}`));\n req.onblocked = () => reject(new Error(`IDB open blocked for ${name}`));\n req.onupgradeneeded = () => upgrade?.(req.result);\n req.onsuccess = () => resolve(req.result);\n });\n}\n\nexport function createFileDataStore(db: IDBDatabase): void {\n if (!db.objectStoreNames.contains(IDB_STORE_NAME)) {\n const store = db.createObjectStore(IDB_STORE_NAME);\n store.createIndex(\"timestamp\", \"timestamp\", { unique: false });\n }\n}\n\nexport async function readPgVersionFile(\n idbName: string,\n): Promise<number | null> {\n if (!(await indexedDbExists(idbName))) return null;\n let db: IDBDatabase;\n try {\n db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n } catch {\n return null;\n }\n try {\n if (!db.objectStoreNames.contains(IDB_STORE_NAME)) return null;\n const tx = db.transaction(IDB_STORE_NAME, \"readonly\");\n const store = tx.objectStore(IDB_STORE_NAME);\n const value = await new Promise<FileDataValue | null>((resolve, reject) => {\n const req = store.openCursor();\n req.onerror = () =>\n reject(idbError(req, `FILE_DATA cursor failed for ${idbName}`));\n req.onsuccess = () => {\n const cursor = req.result;\n if (!cursor) return resolve(null);\n const key = typeof cursor.key === \"string\" ? cursor.key : \"\";\n if (key.endsWith(\"/PG_VERSION\")) {\n resolve(cursor.value as FileDataValue);\n } else {\n cursor.continue();\n }\n };\n });\n if (!value) return null;\n const bytes =\n value.contents instanceof Uint8Array\n ? value.contents\n : new Uint8Array(value.contents);\n const text = new TextDecoder().decode(bytes).trim();\n const major = parseInt(text, 10);\n return Number.isFinite(major) ? major : null;\n } finally {\n db.close();\n }\n}\n","import type * as CurrentPGliteModuleNs from \"@electric-sql/pglite\";\n\nexport const CURRENT_PG_MAJOR = 17;\nexport const SUPPORTED_PG_MAJORS = [16, 17] as const;\nexport type SupportedPgMajor = (typeof SUPPORTED_PG_MAJORS)[number];\nexport type DetectedMajor = SupportedPgMajor | null;\n\ntype CurrentPGliteModule = typeof CurrentPGliteModuleNs;\n\nexport function coerceMajor(value: number | null): DetectedMajor {\n if (value === null) return null;\n return (SUPPORTED_PG_MAJORS as readonly number[]).includes(value)\n ? (value as SupportedPgMajor)\n : null;\n}\n\nexport function isMigratableMajor(\n value: number | null,\n): value is SupportedPgMajor {\n const major = coerceMajor(value);\n return major !== null && major !== CURRENT_PG_MAJOR;\n}\n\n/**\n * Pick the PGlite major to use for *new* reactor clients: fall back to the\n * current version when there is no existing data dir.\n */\nexport function resolvePgMajorForRuntime(\n detected: DetectedMajor,\n): SupportedPgMajor {\n return detected ?? CURRENT_PG_MAJOR;\n}\n\n/**\n * Loads the PGlite module that matches an on-disk data dir major version.\n *\n * The 0.2.x and 0.3.x modules expose the same runtime interface (PGlite class,\n * `idb://` data-dir support, waitReady, exec/query/transaction, close). The\n * return type is pinned to the current package's module so callers can use it\n * against `kysely-pglite-dialect` which peer-depends on both majors.\n */\nexport async function loadPGliteModule(\n major: SupportedPgMajor,\n): Promise<CurrentPGliteModule> {\n if (major === 16) {\n return (await import(\"pglite-legacy-02\")) as unknown as CurrentPGliteModule;\n }\n if (major === 17) return import(\"@electric-sql/pglite\");\n throw new Error(`Unsupported PGlite major: ${String(major)}`);\n}\n\ntype PgDumpFn = (options: {\n pg: unknown;\n}) => Promise<{ text(): Promise<string> }>;\n\n/**\n * Loads the pg_dump tool for the given PGlite major. pg_dump's VFS layout is\n * version-specific, so using the wrong major against a live PGlite instance\n * fails with Emscripten ENOENT (errno 44).\n */\nexport async function loadPgDump(major: SupportedPgMajor): Promise<PgDumpFn> {\n if (major === 16) {\n const mod = (await import(\"pglite-tools-legacy-02/pg_dump\")) as {\n pgDump: PgDumpFn;\n };\n return mod.pgDump;\n }\n if (major === 17) {\n const mod = (await import(\"@electric-sql/pglite-tools/pg_dump\")) as {\n pgDump: PgDumpFn;\n };\n return mod.pgDump;\n }\n throw new Error(`Unsupported PGlite major: ${String(major)}`);\n}\n"],"names":[],"mappings":"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","debug_id":"bf83be21-3f86-55bd-ae14-c4aa466d5a81"}
@@ -1,6 +1,6 @@
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]="542cf4dc-7da9-516e-b1a0-2fcc0a0c16af")}catch(e){}}();
3
- import { c as idbError, l as openIdb, n as isMigratableMajor, o as IDB_STORE_NAME, s as createFileDataStore, u as readPgVersionFile } from "./pglite-major-BbmMK26m.js";
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]="b8f54f63-862e-5017-822c-cf08ac6f7ca2")}catch(e){}}();
3
+ import { c as idbError, l as openIdb, n as isMigratableMajor, o as IDB_STORE_NAME, s as createFileDataStore, u as readPgVersionFile } from "./pglite-major-p4_YefAE.js";
4
4
  import { PGlite } from "@electric-sql/pglite";
5
5
  //#region src/utils/pglite-migrate-core.ts
6
6
  const LEGACY_DUMPERS = { 16: async () => {
@@ -141,5 +141,5 @@ async function migrateIdb(idbName, publishPhase, backup) {
141
141
  //#endregion
142
142
  export { writeFileData as a, readFileData as i, cloneFileData as n, migrateIdb as r, clearFileData as t };
143
143
 
144
- //# sourceMappingURL=pglite-migrate-core-o88cWesm.js.map
145
- //# debugId=542cf4dc-7da9-516e-b1a0-2fcc0a0c16af
144
+ //# sourceMappingURL=pglite-migrate-core-BcXcImng.js.map
145
+ //# debugId=b8f54f63-862e-5017-822c-cf08ac6f7ca2
@@ -1 +1 @@
1
- {"version":3,"file":"pglite-migrate-core-o88cWesm.js","sources":["../src/utils/pglite-migrate-core.ts"],"sourcesContent":["import { PGlite } from \"@electric-sql/pglite\";\nimport {\n createFileDataStore,\n IDB_DB_VERSION,\n IDB_STORE_NAME,\n idbError,\n openIdb,\n readPgVersionFile,\n} from \"./pglite-idb.js\";\nimport { CURRENT_PG_MAJOR, isMigratableMajor } from \"./pglite-major.js\";\n\nexport type MigrationPhase = \"clone\" | \"dump\" | \"restore\";\n\nexport type FileDataValue = {\n contents: Uint8Array | number[];\n mode: number;\n timestamp: Date | number;\n};\n\nexport type FileDataEntry = { key: IDBValidKey; value: FileDataValue };\n\n// Snapshots a data dir before migration and restores/discards it after. The\n// flag-off path persists to an IDB backup (with retention); the worker keeps\n// the snapshot in memory for same-run rollback only.\nexport interface BackupStrategy {\n snapshot(idbName: string): Promise<unknown>;\n rollback(handle: unknown, idbName: string, cause: unknown): Promise<void>;\n discard(handle: unknown): Promise<void>;\n commit(handle: unknown): Promise<void>;\n}\n\ntype LegacyDumper = (idbName: string) => Promise<string>;\n\nconst LEGACY_DUMPERS: Partial<Record<number, () => Promise<LegacyDumper>>> = {\n 16: async () => {\n const [{ PGlite: LegacyPGlite }, { pgDump }] = await Promise.all([\n import(\"pglite-legacy-02\"),\n import(\"pglite-tools-legacy-02/pg_dump\"),\n ]);\n return async (idbName: string) => {\n const stripped = idbName.replace(/^\\/pglite\\//, \"\");\n const pg = new LegacyPGlite(`idb://${stripped}`);\n try {\n await pg.waitReady;\n const file = await pgDump({ pg });\n return await file.text();\n } finally {\n await pg.close();\n }\n };\n },\n};\n\nexport async function clearFileData(idbName: string): Promise<void> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE_NAME, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(idbError(tx, `FILE_DATA clear failed for ${idbName}`));\n tx.onabort = () =>\n reject(idbError(tx, `FILE_DATA clear aborted for ${idbName}`));\n tx.objectStore(IDB_STORE_NAME).clear();\n });\n } finally {\n db.close();\n }\n}\n\nexport async function readFileData(idbName: string): Promise<FileDataEntry[]> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n return await new Promise<FileDataEntry[]>((resolve, reject) => {\n const out: FileDataEntry[] = [];\n const req = db\n .transaction(IDB_STORE_NAME, \"readonly\")\n .objectStore(IDB_STORE_NAME)\n .openCursor();\n req.onerror = () =>\n reject(idbError(req, `FILE_DATA read cursor failed for ${idbName}`));\n req.onsuccess = () => {\n const cursor = req.result;\n if (!cursor) return resolve(out);\n out.push({ key: cursor.key, value: cursor.value as FileDataValue });\n cursor.continue();\n };\n });\n } finally {\n db.close();\n }\n}\n\nexport async function writeFileData(\n idbName: string,\n entries: FileDataEntry[],\n): Promise<void> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE_NAME, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(idbError(tx, `FILE_DATA write failed for ${idbName}`));\n tx.onabort = () =>\n reject(idbError(tx, `FILE_DATA write aborted for ${idbName}`));\n const store = tx.objectStore(IDB_STORE_NAME);\n store.clear();\n for (const { key, value } of entries) {\n store.put(value, key);\n }\n });\n } finally {\n db.close();\n }\n}\n\nexport async function cloneFileData(\n sourceName: string,\n destName: string,\n): Promise<void> {\n await writeFileData(destName, await readFileData(sourceName));\n}\n\nfunction logRestoreFailure(idbName: string, sql: string, err: unknown): void {\n const errObj = err as {\n message?: string;\n position?: string | number;\n severity?: string;\n code?: string;\n detail?: string;\n where?: string;\n };\n const position =\n typeof errObj.position === \"string\"\n ? parseInt(errObj.position, 10)\n : typeof errObj.position === \"number\"\n ? errObj.position\n : NaN;\n\n console.error(`[pglite-migration] Restore failed for ${idbName}`, {\n message: errObj.message,\n code: errObj.code,\n severity: errObj.severity,\n detail: errObj.detail,\n where: errObj.where,\n position: errObj.position,\n sqlLength: sql.length,\n });\n\n if (Number.isFinite(position) && position > 0) {\n const zeroBased = position - 1;\n const start = Math.max(0, zeroBased - 200);\n const end = Math.min(sql.length, zeroBased + 200);\n console.error(\n `[pglite-migration] SQL context around position ${position}:\\n${sql.slice(start, zeroBased)}»${sql.slice(zeroBased, zeroBased + 1)}«${sql.slice(zeroBased + 1, end)}`,\n );\n } else {\n console.error(\n `[pglite-migration] No position info. First 2000 chars of dump:\\n${sql.slice(0, 2000)}`,\n );\n }\n}\n\nasync function restoreDumpIntoIdb(idbName: string, sql: string): Promise<void> {\n const stripped = idbName.replace(/^\\/pglite\\//, \"\");\n const pg = new PGlite(`idb://${stripped}`, { relaxedDurability: false });\n try {\n await pg.waitReady;\n // PG16 pg_dump emits doubled backslashes (escape-string form) without the\n // matching SET; PG17 defaults standard_conforming_strings on, breaking JSONB.\n try {\n await pg.exec(\"SET standard_conforming_strings = off;\");\n } catch (gucErr) {\n console.warn(\n \"[pglite-migration] Could not force standard_conforming_strings=off\",\n gucErr,\n );\n }\n try {\n await pg.exec(sql);\n } catch (execErr) {\n logRestoreFailure(idbName, sql, execErr);\n throw execErr;\n }\n } finally {\n await pg.close();\n }\n}\n\nexport async function migrateIdb(\n idbName: string,\n publishPhase: (phase: MigrationPhase) => void,\n backup: BackupStrategy,\n): Promise<void> {\n const major = await readPgVersionFile(idbName);\n if (major === null || major === CURRENT_PG_MAJOR) return;\n\n if (!isMigratableMajor(major)) {\n console.warn(\n `[pglite-migration] Skipping ${idbName}: unsupported PG_VERSION=${major}; no migration path.`,\n );\n return;\n }\n\n const loader = LEGACY_DUMPERS[major];\n if (!loader) {\n throw new Error(\n `No legacy dumper for supported PG_VERSION=${major} (${idbName}); ` +\n `SUPPORTED_PG_MAJORS and LEGACY_DUMPERS are out of sync.`,\n );\n }\n\n publishPhase(\"clone\");\n const handle = await backup.snapshot(idbName);\n\n let sql: string;\n try {\n publishPhase(\"dump\");\n const dump = await loader();\n sql = await dump(idbName);\n } catch (err) {\n await backup.discard(handle);\n throw err;\n }\n\n try {\n await clearFileData(idbName);\n publishPhase(\"restore\");\n await restoreDumpIntoIdb(idbName, sql);\n } catch (err) {\n await backup.rollback(handle, idbName, err);\n throw err;\n }\n await backup.commit(handle);\n}\n"],"names":[],"mappings":"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","debug_id":"542cf4dc-7da9-516e-b1a0-2fcc0a0c16af"}
1
+ {"version":3,"file":"pglite-migrate-core-BcXcImng.js","sources":["../src/utils/pglite-migrate-core.ts"],"sourcesContent":["import { PGlite } from \"@electric-sql/pglite\";\nimport {\n createFileDataStore,\n IDB_DB_VERSION,\n IDB_STORE_NAME,\n idbError,\n openIdb,\n readPgVersionFile,\n} from \"./pglite-idb.js\";\nimport { CURRENT_PG_MAJOR, isMigratableMajor } from \"./pglite-major.js\";\n\nexport type MigrationPhase = \"clone\" | \"dump\" | \"restore\";\n\nexport type FileDataValue = {\n contents: Uint8Array | number[];\n mode: number;\n timestamp: Date | number;\n};\n\nexport type FileDataEntry = { key: IDBValidKey; value: FileDataValue };\n\n// Snapshots a data dir before migration and restores/discards it after. The\n// flag-off path persists to an IDB backup (with retention); the worker keeps\n// the snapshot in memory for same-run rollback only.\nexport interface BackupStrategy {\n snapshot(idbName: string): Promise<unknown>;\n rollback(handle: unknown, idbName: string, cause: unknown): Promise<void>;\n discard(handle: unknown): Promise<void>;\n commit(handle: unknown): Promise<void>;\n}\n\ntype LegacyDumper = (idbName: string) => Promise<string>;\n\nconst LEGACY_DUMPERS: Partial<Record<number, () => Promise<LegacyDumper>>> = {\n 16: async () => {\n const [{ PGlite: LegacyPGlite }, { pgDump }] = await Promise.all([\n import(\"pglite-legacy-02\"),\n import(\"pglite-tools-legacy-02/pg_dump\"),\n ]);\n return async (idbName: string) => {\n const stripped = idbName.replace(/^\\/pglite\\//, \"\");\n const pg = new LegacyPGlite(`idb://${stripped}`);\n try {\n await pg.waitReady;\n const file = await pgDump({ pg });\n return await file.text();\n } finally {\n await pg.close();\n }\n };\n },\n};\n\nexport async function clearFileData(idbName: string): Promise<void> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE_NAME, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(idbError(tx, `FILE_DATA clear failed for ${idbName}`));\n tx.onabort = () =>\n reject(idbError(tx, `FILE_DATA clear aborted for ${idbName}`));\n tx.objectStore(IDB_STORE_NAME).clear();\n });\n } finally {\n db.close();\n }\n}\n\nexport async function readFileData(idbName: string): Promise<FileDataEntry[]> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n return await new Promise<FileDataEntry[]>((resolve, reject) => {\n const out: FileDataEntry[] = [];\n const req = db\n .transaction(IDB_STORE_NAME, \"readonly\")\n .objectStore(IDB_STORE_NAME)\n .openCursor();\n req.onerror = () =>\n reject(idbError(req, `FILE_DATA read cursor failed for ${idbName}`));\n req.onsuccess = () => {\n const cursor = req.result;\n if (!cursor) return resolve(out);\n out.push({ key: cursor.key, value: cursor.value as FileDataValue });\n cursor.continue();\n };\n });\n } finally {\n db.close();\n }\n}\n\nexport async function writeFileData(\n idbName: string,\n entries: FileDataEntry[],\n): Promise<void> {\n const db = await openIdb(idbName, IDB_DB_VERSION, createFileDataStore);\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE_NAME, \"readwrite\");\n tx.oncomplete = () => resolve();\n tx.onerror = () =>\n reject(idbError(tx, `FILE_DATA write failed for ${idbName}`));\n tx.onabort = () =>\n reject(idbError(tx, `FILE_DATA write aborted for ${idbName}`));\n const store = tx.objectStore(IDB_STORE_NAME);\n store.clear();\n for (const { key, value } of entries) {\n store.put(value, key);\n }\n });\n } finally {\n db.close();\n }\n}\n\nexport async function cloneFileData(\n sourceName: string,\n destName: string,\n): Promise<void> {\n await writeFileData(destName, await readFileData(sourceName));\n}\n\nfunction logRestoreFailure(idbName: string, sql: string, err: unknown): void {\n const errObj = err as {\n message?: string;\n position?: string | number;\n severity?: string;\n code?: string;\n detail?: string;\n where?: string;\n };\n const position =\n typeof errObj.position === \"string\"\n ? parseInt(errObj.position, 10)\n : typeof errObj.position === \"number\"\n ? errObj.position\n : NaN;\n\n console.error(`[pglite-migration] Restore failed for ${idbName}`, {\n message: errObj.message,\n code: errObj.code,\n severity: errObj.severity,\n detail: errObj.detail,\n where: errObj.where,\n position: errObj.position,\n sqlLength: sql.length,\n });\n\n if (Number.isFinite(position) && position > 0) {\n const zeroBased = position - 1;\n const start = Math.max(0, zeroBased - 200);\n const end = Math.min(sql.length, zeroBased + 200);\n console.error(\n `[pglite-migration] SQL context around position ${position}:\\n${sql.slice(start, zeroBased)}»${sql.slice(zeroBased, zeroBased + 1)}«${sql.slice(zeroBased + 1, end)}`,\n );\n } else {\n console.error(\n `[pglite-migration] No position info. First 2000 chars of dump:\\n${sql.slice(0, 2000)}`,\n );\n }\n}\n\nasync function restoreDumpIntoIdb(idbName: string, sql: string): Promise<void> {\n const stripped = idbName.replace(/^\\/pglite\\//, \"\");\n const pg = new PGlite(`idb://${stripped}`, { relaxedDurability: false });\n try {\n await pg.waitReady;\n // PG16 pg_dump emits doubled backslashes (escape-string form) without the\n // matching SET; PG17 defaults standard_conforming_strings on, breaking JSONB.\n try {\n await pg.exec(\"SET standard_conforming_strings = off;\");\n } catch (gucErr) {\n console.warn(\n \"[pglite-migration] Could not force standard_conforming_strings=off\",\n gucErr,\n );\n }\n try {\n await pg.exec(sql);\n } catch (execErr) {\n logRestoreFailure(idbName, sql, execErr);\n throw execErr;\n }\n } finally {\n await pg.close();\n }\n}\n\nexport async function migrateIdb(\n idbName: string,\n publishPhase: (phase: MigrationPhase) => void,\n backup: BackupStrategy,\n): Promise<void> {\n const major = await readPgVersionFile(idbName);\n if (major === null || major === CURRENT_PG_MAJOR) return;\n\n if (!isMigratableMajor(major)) {\n console.warn(\n `[pglite-migration] Skipping ${idbName}: unsupported PG_VERSION=${major}; no migration path.`,\n );\n return;\n }\n\n const loader = LEGACY_DUMPERS[major];\n if (!loader) {\n throw new Error(\n `No legacy dumper for supported PG_VERSION=${major} (${idbName}); ` +\n `SUPPORTED_PG_MAJORS and LEGACY_DUMPERS are out of sync.`,\n );\n }\n\n publishPhase(\"clone\");\n const handle = await backup.snapshot(idbName);\n\n let sql: string;\n try {\n publishPhase(\"dump\");\n const dump = await loader();\n sql = await dump(idbName);\n } catch (err) {\n await backup.discard(handle);\n throw err;\n }\n\n try {\n await clearFileData(idbName);\n publishPhase(\"restore\");\n await restoreDumpIntoIdb(idbName, sql);\n } catch (err) {\n await backup.rollback(handle, idbName, err);\n throw err;\n }\n await backup.commit(handle);\n}\n"],"names":[],"mappings":"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","debug_id":"b8f54f63-862e-5017-822c-cf08ac6f7ca2"}
@@ -1,6 +1,6 @@
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]="472fb35a-9dae-509b-802f-ea816048f7ad")}catch(e){}}();
3
- import { l as invalidateReactorPgMajorCache, m as REACTOR_PGLITE_NAME } from "./connection-state-DJX_vUhI.js";
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]="d59c69fe-5f4d-5aa8-accd-b4fbae2bd47a")}catch(e){}}();
3
+ import { l as invalidateReactorPgMajorCache, m as REACTOR_PGLITE_NAME } from "./connection-state-Eqc2izmt.js";
4
4
  //#region src/utils/pglite-seed.ts
5
5
  const PENDING_PG_SEED_KEY = "ph:pending-pg-seed";
6
6
  /**
@@ -45,5 +45,5 @@ async function seedPendingPgVersion() {
45
45
  //#endregion
46
46
  export { seedPendingPgVersion as n, PENDING_PG_SEED_KEY as t };
47
47
 
48
- //# sourceMappingURL=pglite-seed-AR1MKM1R.js.map
49
- //# debugId=472fb35a-9dae-509b-802f-ea816048f7ad
48
+ //# sourceMappingURL=pglite-seed-Cl2d-iyl.js.map
49
+ //# debugId=d59c69fe-5f4d-5aa8-accd-b4fbae2bd47a
@@ -1 +1 @@
1
- {"version":3,"file":"pglite-seed-AR1MKM1R.js","sources":["../src/utils/pglite-seed.ts"],"sourcesContent":["import { invalidateReactorPgMajorCache } from \"./pglite-runtime.js\";\nimport { REACTOR_PGLITE_NAME } from \"./storage-namespace.js\";\n\nexport const PENDING_PG_SEED_KEY = \"ph:pending-pg-seed\";\n\n/**\n * If the Debug Inspector requested a forced PG version reset, this runs\n * before the reactor is created on the subsequent page load: opens a fresh\n * PGlite of the requested major against the reactor data dir, lets `initdb`\n * populate `PG_VERSION`, then closes. The next step of app boot then\n * detects this fresh data dir and picks the matching runtime.\n */\nexport async function seedPendingPgVersion(): Promise<void> {\n const raw = localStorage.getItem(PENDING_PG_SEED_KEY);\n if (!raw) return;\n\n const major = parseInt(raw, 10);\n console.info(`[pglite-seed] Seeding fresh PG${major} data dir...`);\n\n try {\n if (major === 16) {\n const { PGlite } = await import(\"pglite-legacy-02\");\n const pg = new PGlite(`idb://${REACTOR_PGLITE_NAME}`);\n try {\n await pg.waitReady;\n } finally {\n await pg.close();\n }\n } else if (major === 17) {\n const { PGlite } = await import(\"@electric-sql/pglite\");\n const pg = new PGlite(`idb://${REACTOR_PGLITE_NAME}`);\n try {\n await pg.waitReady;\n } finally {\n await pg.close();\n }\n } else {\n console.warn(`[pglite-seed] Unsupported version ${raw}, skipping`);\n return;\n }\n console.info(`[pglite-seed] Seeded PG${major} data dir.`);\n } finally {\n localStorage.removeItem(PENDING_PG_SEED_KEY);\n invalidateReactorPgMajorCache();\n }\n}\n"],"names":[],"mappings":";;;;AAGA,MAAa,sBAAsB;;;;;;;;AASnC,eAAsB,uBAAsC;CAC1D,MAAM,MAAM,aAAa,QAAQ,mBAAmB;CACpD,IAAI,CAAC,KAAK;CAEV,MAAM,QAAQ,SAAS,KAAK,EAAE;CAC9B,QAAQ,KAAK,iCAAiC,MAAM,aAAa;CAEjE,IAAI;EACF,IAAI,UAAU,IAAI;GAChB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,qBAAqB;GACpD,IAAI;IACF,MAAM,GAAG;GACX,UAAU;IACR,MAAM,GAAG,MAAM;GACjB;EACF,OAAO,IAAI,UAAU,IAAI;GACvB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,qBAAqB;GACpD,IAAI;IACF,MAAM,GAAG;GACX,UAAU;IACR,MAAM,GAAG,MAAM;GACjB;EACF,OAAO;GACL,QAAQ,KAAK,qCAAqC,IAAI,WAAW;GACjE;EACF;EACA,QAAQ,KAAK,0BAA0B,MAAM,WAAW;CAC1D,UAAU;EACR,aAAa,WAAW,mBAAmB;EAC3C,8BAA8B;CAChC;AACF","debug_id":"472fb35a-9dae-509b-802f-ea816048f7ad"}
1
+ {"version":3,"file":"pglite-seed-Cl2d-iyl.js","sources":["../src/utils/pglite-seed.ts"],"sourcesContent":["import { invalidateReactorPgMajorCache } from \"./pglite-runtime.js\";\nimport { REACTOR_PGLITE_NAME } from \"./storage-namespace.js\";\n\nexport const PENDING_PG_SEED_KEY = \"ph:pending-pg-seed\";\n\n/**\n * If the Debug Inspector requested a forced PG version reset, this runs\n * before the reactor is created on the subsequent page load: opens a fresh\n * PGlite of the requested major against the reactor data dir, lets `initdb`\n * populate `PG_VERSION`, then closes. The next step of app boot then\n * detects this fresh data dir and picks the matching runtime.\n */\nexport async function seedPendingPgVersion(): Promise<void> {\n const raw = localStorage.getItem(PENDING_PG_SEED_KEY);\n if (!raw) return;\n\n const major = parseInt(raw, 10);\n console.info(`[pglite-seed] Seeding fresh PG${major} data dir...`);\n\n try {\n if (major === 16) {\n const { PGlite } = await import(\"pglite-legacy-02\");\n const pg = new PGlite(`idb://${REACTOR_PGLITE_NAME}`);\n try {\n await pg.waitReady;\n } finally {\n await pg.close();\n }\n } else if (major === 17) {\n const { PGlite } = await import(\"@electric-sql/pglite\");\n const pg = new PGlite(`idb://${REACTOR_PGLITE_NAME}`);\n try {\n await pg.waitReady;\n } finally {\n await pg.close();\n }\n } else {\n console.warn(`[pglite-seed] Unsupported version ${raw}, skipping`);\n return;\n }\n console.info(`[pglite-seed] Seeded PG${major} data dir.`);\n } finally {\n localStorage.removeItem(PENDING_PG_SEED_KEY);\n invalidateReactorPgMajorCache();\n }\n}\n"],"names":[],"mappings":";;;;AAGA,MAAa,sBAAsB;;;;;;;;AASnC,eAAsB,uBAAsC;CAC1D,MAAM,MAAM,aAAa,QAAQ,mBAAmB;CACpD,IAAI,CAAC,KAAK;CAEV,MAAM,QAAQ,SAAS,KAAK,EAAE;CAC9B,QAAQ,KAAK,iCAAiC,MAAM,aAAa;CAEjE,IAAI;EACF,IAAI,UAAU,IAAI;GAChB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,qBAAqB;GACpD,IAAI;IACF,MAAM,GAAG;GACX,UAAU;IACR,MAAM,GAAG,MAAM;GACjB;EACF,OAAO,IAAI,UAAU,IAAI;GACvB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,qBAAqB;GACpD,IAAI;IACF,MAAM,GAAG;GACX,UAAU;IACR,MAAM,GAAG,MAAM;GACjB;EACF,OAAO;GACL,QAAQ,KAAK,qCAAqC,IAAI,WAAW;GACjE;EACF;EACA,QAAQ,KAAK,0BAA0B,MAAM,WAAW;CAC1D,UAAU;EACR,aAAa,WAAW,mBAAmB;EAC3C,8BAA8B;CAChC;AACF","debug_id":"d59c69fe-5f4d-5aa8-accd-b4fbae2bd47a"}
@@ -1,13 +1,13 @@
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]="a3855d12-7091-5a48-861e-5fdd3eb884fa")}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]="022038d0-e4f5-5d38-af03-f3a04e7f9e24")}catch(e){}}();
3
3
  import { n as getRuntimeConfig } from "./runtime-config-DtJIUgYw.js";
4
4
  import { t as createConnectSignerConfig } from "./renown-trust-DRgHpxlZ.js";
5
- import { a as resolvePgMajorForRuntime, r as loadPGliteModule } from "./pglite-major-BbmMK26m.js";
5
+ import { a as resolvePgMajorForRuntime, f as toStoredDocumentsRefused, r as loadPGliteModule } from "./pglite-major-p4_YefAE.js";
6
6
  import { n as buildPHGlobalConfig, o as phGlobalConfig, r as connectConfig } from "./connect.config-CaXMoB42.js";
7
7
  import { r as toast } from "./toast-C6WW-_O-.js";
8
8
  import { r as getSharedDeps, t as BrowserPackageManager } from "./package-manager-BbzIV9aN.js";
9
- import { i as getVersion, n as getGitSha } from "./build-info-CQAER_nk.js";
10
- import { a as detectReactorPgMajor, h as RELATIONAL_PGLITE_NAME, m as REACTOR_PGLITE_NAME, n as setWorkerConnectionStatus, o as detectRelationalPgMajor, p as REACTOR_INSTANCE_NAMESPACE } from "./connection-state-DJX_vUhI.js";
9
+ import { i as getVersion, n as getGitSha } from "./build-info-CNHv6iwN.js";
10
+ import { a as detectReactorPgMajor, h as RELATIONAL_PGLITE_NAME, m as REACTOR_PGLITE_NAME, n as setWorkerConnectionStatus, o as detectRelationalPgMajor, p as REACTOR_INSTANCE_NAMESPACE } from "./connection-state-Eqc2izmt.js";
11
11
  import { createRelationalDb } from "@powerhousedao/shared/processors";
12
12
  import { DocumentModelRegistry, DocumentModelResolver, ReactorEventTypes, createReactorHostModuleBase } from "@powerhousedao/reactor";
13
13
  import { MessageRouter, RPC_PROTOCOL_VERSION, SyncManagerProxy, connectReactorClient, createInspectorProxy, createPortTransport, createReactorEventBusProxy, createRelationalPgliteProxy, createWorkerAdminClient, postReactorIdentity } from "@powerhousedao/reactor-browser/rpc";
@@ -72,7 +72,7 @@ async function getDb() {
72
72
  * Creates a Reactor that plugs into legacy storage but syncs through the new
73
73
  * Reactor GQL API.
74
74
  */
75
- async function createBrowserReactor(documentModelModules, upgradeManifests, renown, featureFlags, documentModelLoader, createSignaturePolicy, renownEndpoints = {}) {
75
+ async function createBrowserReactor(documentModelModules, upgradeManifests, renown, featureFlags, documentModelLoader, createSignaturePolicy, renownEndpoints = {}, unsupportedStoredDocuments) {
76
76
  const signerConfig = await createConnectSignerConfig(renown.signer, featureFlags, renownEndpoints);
77
77
  const jwtHandler = async (_url) => {
78
78
  if (!renown.user) return;
@@ -80,10 +80,17 @@ async function createBrowserReactor(documentModelModules, upgradeManifests, reno
80
80
  };
81
81
  const pg = await getReactorPGlite();
82
82
  const logger = new ConsoleLogger(["reactor-client"]);
83
- const builder = new ReactorClientBuilder$1().withLogger(logger).withSigner(signerConfig).withReactorBuilder(new ReactorBuilder$1().withDocumentModelSources(documentModelModules).withUpgradeManifests(upgradeManifests).withChannelScheme(ChannelScheme$1.CONNECT).withExecutorConfig({ featureFlags }).withJwtHandler(jwtHandler).withKysely(new Kysely({ dialect: new PGliteDialect(pg) })));
83
+ const reactorBuilder = new ReactorBuilder$1().withDocumentModelSources(documentModelModules).withUpgradeManifests(upgradeManifests).withChannelScheme(ChannelScheme$1.CONNECT).withExecutorConfig({ featureFlags }).withJwtHandler(jwtHandler).withKysely(new Kysely({ dialect: new PGliteDialect(pg) }));
84
+ const builder = new ReactorClientBuilder$1().withLogger(logger).withSigner(signerConfig).withReactorBuilder(reactorBuilder);
84
85
  if (documentModelLoader) builder.withDocumentModelLoader(documentModelLoader);
85
86
  if (createSignaturePolicy) builder.withCreateSignaturePolicy(createSignaturePolicy);
86
- const module = await builder.buildModule();
87
+ if (unsupportedStoredDocuments) reactorBuilder.withUnsupportedStoredDocuments(unsupportedStoredDocuments);
88
+ let module;
89
+ try {
90
+ module = await builder.buildModule();
91
+ } catch (error) {
92
+ throw toStoredDocumentsRefused(error);
93
+ }
87
94
  return {
88
95
  ...module,
89
96
  kind: "browser",
@@ -676,6 +683,7 @@ function createWorkerReactorClientModule(args) {
676
683
  renownChainId: args.renownChainId,
677
684
  featureFlags: args.featureFlags,
678
685
  createSignaturePolicy: args.createSignaturePolicy,
686
+ unsupportedStoredDocuments: args.unsupportedStoredDocuments,
679
687
  renownEndpoints: args.renownEndpoints
680
688
  },
681
689
  packages: args.packageSpecs
@@ -931,6 +939,7 @@ async function createReactor(localPackage) {
931
939
  const enabledReactorFlags = Object.entries(reactorFeatureFlags).filter(([, enabled]) => enabled).map(([name]) => name);
932
940
  if (enabledReactorFlags.length > 0) logger.info(`Reactor feature flags: ${enabledReactorFlags.join(", ")}`);
933
941
  const createSignaturePolicy = runtimeConfig.connect?.reactor?.createSignaturePolicy;
942
+ const unsupportedStoredDocuments = runtimeConfig.connect?.reactor?.unsupportedStoredDocuments;
934
943
  const renownEndpoints = {
935
944
  renownUrl: phGlobalConfig.renownUrl,
936
945
  switchboardUrl: phGlobalConfig.switchboardUrl
@@ -961,6 +970,7 @@ async function createReactor(localPackage) {
961
970
  renownChainId,
962
971
  featureFlags: reactorFeatureFlags,
963
972
  createSignaturePolicy,
973
+ unsupportedStoredDocuments,
964
974
  renownEndpoints,
965
975
  documentModelModules,
966
976
  upgradeManifests,
@@ -980,7 +990,7 @@ async function createReactor(localPackage) {
980
990
  logger.error("Reactor worker failed to start: @error", error);
981
991
  throw error;
982
992
  }
983
- } else reactorClientModule = await createBrowserReactor(documentModelModules, upgradeManifests, renown, reactorFeatureFlags, discoveryService, createSignaturePolicy, renownEndpoints);
993
+ } else reactorClientModule = await createBrowserReactor(documentModelModules, upgradeManifests, renown, reactorFeatureFlags, discoveryService, createSignaturePolicy, renownEndpoints, unsupportedStoredDocuments);
984
994
  const drives = await getDrives(reactorClientModule.client);
985
995
  const didFromUrl = getDidFromUrl();
986
996
  await login(didFromUrl, renown);
@@ -1081,5 +1091,5 @@ function getDriveUrl() {
1081
1091
  //#endregion
1082
1092
  export { createReactor as n, clearReactorStorage as t };
1083
1093
 
1084
- //# sourceMappingURL=reactor-CHFsGnJ2.js.map
1085
- //# debugId=a3855d12-7091-5a48-861e-5fdd3eb884fa
1094
+ //# sourceMappingURL=reactor--yIPUbFV.js.map
1095
+ //# debugId=022038d0-e4f5-5d38-af03-f3a04e7f9e24
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactor--yIPUbFV.js","sources":["../src/pglite.db.ts","../src/utils/reactor.ts","../src/feature-flags.ts","../src/no-registry-discovery.ts","../src/package-discovery.ts","../src/reactor-worker-name.ts","../src/reactor-worker-client.ts","../src/utils/reactor-worker-flag.ts","../src/store/processor-host-module.ts","../src/store/reactor.ts"],"sourcesContent":["import type { PGlite } from \"@electric-sql/pglite\";\nimport { createRelationalDb } from \"@powerhousedao/shared/processors\";\nimport { Kysely } from \"kysely\";\nimport { PGliteDialect } from \"kysely-pglite-dialect\";\nimport {\n detectReactorPgMajor,\n detectRelationalPgMajor,\n loadPGliteModule,\n resolvePgMajorForRuntime,\n type DetectedMajor,\n type SupportedPgMajor,\n} from \"./utils/pglite-runtime.js\";\nimport {\n REACTOR_PGLITE_NAME,\n RELATIONAL_PGLITE_NAME,\n} from \"./utils/storage-namespace.js\";\n\n// Separate reactor/relational instances so their transactions can't interleave\n// on one session; the wasm download is still shared — PGlite memoizes the\n// compiled module per JS realm.\n\n// Off by default: workers hide `Module.FS` (the Inspector needs it) and each\n// worker realm re-downloads the wasm.\nexport const PGLITE_USE_WORKER: boolean = false;\n\nasync function createMainThreadPGlite(\n major: SupportedPgMajor,\n dbName: string,\n): Promise<PGlite> {\n const { PGlite } = await loadPGliteModule(major);\n const { live } =\n major === 16\n ? await import(\"pglite-legacy-02/live\")\n : await import(\"@electric-sql/pglite/live\");\n return new PGlite(`idb://${dbName}`, {\n relaxedDurability: true,\n extensions: { live },\n }) as unknown as PGlite;\n}\n\nasync function createWorkerPGlite(\n major: SupportedPgMajor,\n dbName: string,\n): Promise<PGlite> {\n // dbName is owned here so the namespace matches the other origin-scoped stores.\n const meta = { dbName };\n if (major === 16) {\n const [legacyWorker, legacyLive] = await Promise.all([\n import(\"pglite-legacy-02/worker\"),\n import(\"pglite-legacy-02/live\"),\n ]);\n const worker = new Worker(\n new URL(\"./pglite.worker.legacy.js\", import.meta.url),\n { type: \"module\" },\n );\n return legacyWorker.PGliteWorker.create(worker, {\n meta,\n extensions: { live: legacyLive.live },\n }) as unknown as PGlite;\n }\n const [{ PGliteWorker }, { live }] = await Promise.all([\n import(\"@electric-sql/pglite/worker\"),\n import(\"@electric-sql/pglite/live\"),\n ]);\n const worker = new Worker(new URL(\"./pglite.worker.js\", import.meta.url), {\n type: \"module\",\n });\n return PGliteWorker.create(worker, {\n meta,\n extensions: { live },\n }) as unknown as PGlite;\n}\n\n// Overlapping cold boots race on PGlite's un-cloned wasm fetch Response and\n// re-fetch the fs bundle; chaining avoids both.\nlet bootChain: Promise<unknown> = Promise.resolve();\n\nfunction chainedCreate(create: () => Promise<PGlite>): Promise<PGlite> {\n const pending = bootChain.then(create, create);\n bootChain = pending.catch(() => undefined);\n return pending;\n}\n\nfunction pgliteSingleton(opts: {\n dbName: string;\n detectMajor: () => Promise<DetectedMajor>;\n label: string;\n}): () => Promise<PGlite> {\n let cached: Promise<PGlite> | undefined;\n return function getPGlite(): Promise<PGlite> {\n if (cached) return cached;\n const pending = chainedCreate(async () => {\n const major = resolvePgMajorForRuntime(await opts.detectMajor());\n if (major !== 17) {\n console.warn(\n `[${opts.label}] Opening legacy Postgres ${major} data dir. Migrate to PG17 from the banner or the Inspector → Debug tab.`,\n );\n }\n return PGLITE_USE_WORKER\n ? createWorkerPGlite(major, opts.dbName)\n : createMainThreadPGlite(major, opts.dbName);\n });\n // Don't cache a rejection: let a later call retry a transient IDB/wasm failure.\n cached = pending;\n pending.catch(() => {\n if (cached === pending) cached = undefined;\n });\n return pending;\n };\n}\n\nexport const getReactorPGlite = pgliteSingleton({\n dbName: REACTOR_PGLITE_NAME,\n detectMajor: detectReactorPgMajor,\n label: \"reactor\",\n});\n\nconst getRelationalPGlite = pgliteSingleton({\n dbName: RELATIONAL_PGLITE_NAME,\n detectMajor: detectRelationalPgMajor,\n label: \"relational\",\n});\n\nexport async function getDb() {\n const pgLite = await getRelationalPGlite();\n const relationalDb = createRelationalDb(\n new Kysely({\n dialect: new PGliteDialect(pgLite),\n }),\n );\n return { pgLite, relationalDb };\n}\n","import {\n addDrive,\n addRemoteDrive,\n ChannelScheme,\n isDriveAuthError,\n ReactorBuilder,\n ReactorClientBuilder,\n setDriveMetadata,\n waitForDocumentReady,\n type BrowserReactorClientModule,\n type Database,\n type IDocumentModelLoader,\n type JwtHandler,\n type ReactorFeatureFlags,\n} from \"@powerhousedao/reactor-browser\";\nimport type { UnsupportedStoredDocuments } from \"@powerhousedao/reactor\";\nimport type {\n PHConnectDefaultDrive,\n PHConnectDefaultDriveLocal,\n PHConnectDefaultDriveRemote,\n} from \"@powerhousedao/shared/clis\";\nimport type { RuntimePowerhouseConfig } from \"@powerhousedao/shared/connect\";\nimport type {\n DocumentModelModule,\n SignaturePolicy,\n UpgradeManifest,\n} from \"@powerhousedao/shared/document-model\";\nimport type { IRenown } from \"@renown/sdk\";\nimport { ConsoleLogger } from \"document-model\";\nimport { Kysely } from \"kysely\";\nimport { PGliteDialect } from \"kysely-pglite-dialect\";\nimport { getReactorPGlite } from \"../pglite.db.js\";\nimport { toStoredDocumentsRefused } from \"./stored-documents-refused.js\";\nimport {\n createConnectSignerConfig,\n type RenownTrustEndpoints,\n} from \"./renown-trust.js\";\n\n/**\n * Creates a Reactor that plugs into legacy storage but syncs through the new\n * Reactor GQL API.\n */\nexport async function createBrowserReactor(\n documentModelModules: DocumentModelModule[],\n upgradeManifests: UpgradeManifest<readonly number[]>[],\n renown: IRenown,\n featureFlags: Partial<ReactorFeatureFlags>,\n documentModelLoader?: IDocumentModelLoader,\n createSignaturePolicy?: SignaturePolicy,\n renownEndpoints: RenownTrustEndpoints = {},\n unsupportedStoredDocuments?: UnsupportedStoredDocuments,\n): Promise<BrowserReactorClientModule> {\n const signerConfig = await createConnectSignerConfig(\n renown.signer,\n featureFlags,\n renownEndpoints,\n );\n\n const jwtHandler: JwtHandler = async (_url: string) => {\n if (!renown.user) {\n return undefined;\n }\n // aud omitted: server verifies without an audience, so aud-bearing tokens\n // are rejected. Re-enable once both sides support audience restriction.\n return renown.getBearerToken({ expiresIn: 10 });\n };\n\n const pg = await getReactorPGlite();\n const logger = new ConsoleLogger([\"reactor-client\"]);\n const reactorBuilder = new ReactorBuilder()\n .withDocumentModelSources(documentModelModules)\n .withUpgradeManifests(upgradeManifests)\n .withChannelScheme(ChannelScheme.CONNECT)\n .withExecutorConfig({ featureFlags })\n .withJwtHandler(jwtHandler)\n .withKysely(\n new Kysely<Database>({\n dialect: new PGliteDialect(pg),\n }),\n );\n const builder = new ReactorClientBuilder()\n .withLogger(logger)\n .withSigner(signerConfig)\n .withReactorBuilder(reactorBuilder);\n\n if (documentModelLoader) {\n builder.withDocumentModelLoader(documentModelLoader);\n }\n if (createSignaturePolicy) {\n builder.withCreateSignaturePolicy(createSignaturePolicy);\n }\n if (unsupportedStoredDocuments) {\n reactorBuilder.withUnsupportedStoredDocuments(unsupportedStoredDocuments);\n }\n\n let module: Awaited<ReturnType<typeof builder.buildModule>>;\n try {\n module = await builder.buildModule();\n } catch (error) {\n throw toStoredDocumentsRefused(error);\n }\n return {\n ...module,\n kind: \"browser\",\n reactorModule: module.reactorModule\n ? { ...module.reactorModule, pg }\n : undefined,\n };\n}\n\nexport function getDefaultDrives(\n runtimeConfig: RuntimePowerhouseConfig,\n): PHConnectDefaultDrive[] {\n return runtimeConfig.connect.drives?.defaultDrives ?? [];\n}\n\n/**\n * Add default drives for the new reactor via sync manager.\n *\n * Drives register concurrently so a slow or unreachable drive can't delay the\n * others — in particular the one the URL slug resolves to. Remote drives\n * retry with linear backoff to handle the common race where Connect's dev\n * server is ready before the switchboard has finished binding its port.\n *\n * Each entry is either a remote drive (a URL registered with the sync\n * manager, waited on for initial backfill) or a local drive (created once in\n * this browser's local reactor; its fixed id makes later boots skip it).\n *\n * @param drives - Array of default-drive entries\n */\nexport async function addDefaultDrivesForNewReactor(\n drives: PHConnectDefaultDrive[],\n): Promise<void> {\n await Promise.all(\n drives.map((drive) =>\n \"url\" in drive\n ? addRemoteDefaultDrive(drive)\n : addLocalDefaultDrive(drive),\n ),\n );\n}\n\nasync function addRemoteDefaultDrive(\n drive: PHConnectDefaultDriveRemote,\n): Promise<void> {\n const MAX_ATTEMPTS = 3;\n const BACKOFF_MS = 2000;\n\n let driveId: string | undefined;\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n driveId = await addRemoteDrive(drive.url);\n break;\n } catch (error) {\n if (isDriveAuthError(error)) {\n // addRemoteDrive already surfaces the login modal; auth failures\n // don't self-heal, so don't burn the remaining retries.\n break;\n }\n if (attempt === MAX_ATTEMPTS) {\n console.error(\n `Failed to add default drive ${drive.url} after ${MAX_ATTEMPTS} attempts:`,\n error,\n );\n } else {\n const delay = BACKOFF_MS * attempt;\n console.warn(\n `Default drive ${drive.url} not reachable (attempt ${attempt}/${MAX_ATTEMPTS}), retrying in ${delay}ms...`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n if (driveId && (drive.name || drive.icon)) {\n try {\n // setDriveMetadata dispatches against the local drive document, which\n // only exists once initial backfill delivers it — wait for it first\n // so the name/icon override isn't lost to a sync race.\n // waitForDocumentReady needs the full reactor client\n const reactorClient = window.ph?.reactorClientModule?.client;\n if (reactorClient) {\n await waitForDocumentReady(reactorClient, driveId, {\n timeoutMs: 15_000,\n });\n }\n await setDriveMetadata(driveId, {\n name: drive.name,\n icon: drive.icon,\n });\n } catch (error) {\n console.warn(\n `Default drive ${drive.url} was added but metadata update failed:`,\n error,\n );\n }\n }\n}\n\n/**\n * Create a configured local default drive in this browser's local reactor.\n * The drive is only created when the configured id is not already taken, so\n * repeated boots are idempotent and a drive the user deleted stays deleted.\n * Name and icon are written straight into the created document's global state\n * (no setDriveMetadata round-trip), and `app` maps to the drive's preferred\n * editor.\n */\nasync function addLocalDefaultDrive(\n drive: PHConnectDefaultDriveLocal,\n): Promise<void> {\n // The union is discriminated on `url`, so a hand-edited config entry with\n // neither `url` nor `id` lands here. Without an id addDrive would mint a\n // random one, creating another drive on every boot.\n if (!drive.id) {\n console.error(\n \"Ignoring local default drive with no id:\",\n JSON.stringify(drive),\n );\n return;\n }\n\n try {\n // isDocumentIdTaken() lives on the full reactor client, not the browser\n // client the interactive addDrive action uses. It asks what the create\n // path asks — is the id reserved, deleted or not — where find() reports\n // only live documents, so a deleted drive would look absent and be\n // re-created (and rejected) on every boot.\n const reactorClient = window.ph?.reactorClientModule?.client;\n if (reactorClient) {\n const taken = await reactorClient.isDocumentIdTaken(drive.id);\n if (taken) {\n return; // created on an earlier boot, or deleted since\n }\n }\n await addDrive(\n {\n id: drive.id,\n global: {\n name: drive.name ?? \"\",\n icon: drive.icon ?? null,\n },\n },\n drive.app,\n );\n } catch (error) {\n console.error(`Failed to create local default drive ${drive.id}:`, error);\n }\n}\n","import {\n OpenFeature,\n type ErrorCode,\n type JsonValue,\n type Provider,\n type ResolutionDetails,\n} from \"@openfeature/web-sdk\";\nimport { logger, setLogLevel, type ILogger } from \"document-model\";\n\n/**\n * QueryParamProvider reads feature flags from URL query parameters.\n *\n * Usage:\n * const params = new URLSearchParams(window.location.search);\n * const provider = new QueryParamProvider(params);\n * await OpenFeature.setProviderAndWait(provider);\n *\n * Query parameter format:\n * ?FEATURE_DUAL_ACTION_CREATE_ENABLED=true&FEATURE_FOO=false\n */\nexport class QueryParamProvider implements Provider {\n public readonly runsOn = \"client\" as const;\n\n readonly metadata = {\n name: \"QueryParamProvider\",\n } as const;\n\n private flags: Map<string, string>;\n\n constructor(searchParams: URLSearchParams) {\n this.flags = new Map();\n\n // Extract all query parameters that look like feature flags\n for (const [key, value] of searchParams.entries()) {\n this.flags.set(key, value);\n }\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n ): ResolutionDetails<boolean> {\n const value = this.flags.get(flagKey);\n\n if (value === undefined) {\n return {\n value: defaultValue,\n reason: \"DEFAULT\",\n };\n }\n\n // Parse boolean from string\n const boolValue = value.toLowerCase() === \"true\" || value === \"1\";\n\n return {\n value: boolValue,\n reason: \"STATIC\",\n variant: value,\n };\n }\n\n resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n ): ResolutionDetails<string> {\n const value = this.flags.get(flagKey);\n\n if (value === undefined) {\n return {\n value: defaultValue,\n reason: \"DEFAULT\",\n };\n }\n\n return {\n value,\n reason: \"STATIC\",\n variant: value,\n };\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n ): ResolutionDetails<number> {\n const value = this.flags.get(flagKey);\n\n if (value === undefined) {\n return {\n value: defaultValue,\n reason: \"DEFAULT\",\n };\n }\n\n const numValue = Number(value);\n\n if (isNaN(numValue)) {\n return {\n value: defaultValue,\n reason: \"ERROR\",\n errorCode: \"PARSE_ERROR\" as ErrorCode,\n errorMessage: `Failed to parse \"${value}\" as a number`,\n };\n }\n\n return {\n value: numValue,\n reason: \"STATIC\",\n variant: value,\n };\n }\n\n resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n ): ResolutionDetails<T> {\n const value = this.flags.get(flagKey);\n\n if (value === undefined) {\n return {\n value: defaultValue,\n reason: \"DEFAULT\",\n };\n }\n\n try {\n const objValue = JSON.parse(value) as T;\n return {\n value: objValue,\n reason: \"STATIC\",\n variant: value,\n };\n } catch (error) {\n return {\n value: defaultValue,\n reason: \"ERROR\",\n errorCode: \"PARSE_ERROR\" as ErrorCode,\n errorMessage: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n}\n\n/**\n * Initialize OpenFeature with the QueryParamProvider.\n * Reads feature flags from query parameters.\n */\nexport async function initFeatureFlags(\n searchParams?: URLSearchParams,\n): Promise<Map<string, boolean>> {\n const params =\n searchParams ??\n (typeof window !== \"undefined\"\n ? new URLSearchParams(window.location.search)\n : new URLSearchParams());\n const provider = new QueryParamProvider(params);\n await OpenFeature.setProviderAndWait(provider);\n\n const features = new Map<string, boolean>();\n\n // Handle LOG_LEVEL query param override\n const logLevelParam = params.get(\"LOG_LEVEL\");\n if (logLevelParam) {\n const validLogLevels = [\"verbose\", \"debug\", \"info\", \"warn\", \"error\"];\n if (validLogLevels.includes(logLevelParam.toLowerCase())) {\n setLogLevel(logLevelParam.toLowerCase() as ILogger[\"level\"]);\n logger.info(\n \"Log level set to @level via query param\",\n logLevelParam.toLowerCase(),\n );\n } else {\n logger.warn(\n \"Invalid LOG_LEVEL query param: @param. Valid values: @validLevels\",\n logLevelParam,\n validLogLevels.join(\", \"),\n );\n }\n }\n\n return features;\n}\n","import {\n type IDocumentModelLoader,\n type IPackageDiscoveryService,\n type DiscoveryEvent,\n type DiscoveryEventListener,\n type FailedInstallation,\n type PendingInstallation,\n} from \"@powerhousedao/reactor-browser\";\nimport type { DocumentModelModule } from \"@powerhousedao/shared/document-model\";\nimport type { BrowserPackageManager } from \"./package-manager.js\";\n\n/**\n * Discovery service used when no package registry is configured. Every load\n * for an unknown document type is recorded as a failure with reason\n * \"no-registry\" so the UI can surface the issue; the modal install flow is a\n * no-op because there is no registry to query.\n */\nexport class NoRegistryDiscoveryService\n implements IDocumentModelLoader, IPackageDiscoveryService\n{\n #packageManager: BrowserPackageManager;\n #failed = new Map<string, FailedInstallation>();\n #failedMemo: FailedInstallation[] = [];\n #failedSubscribers = new Set<() => void>();\n #eventSubscribers = new Set<DiscoveryEventListener>();\n\n constructor(packageManager: BrowserPackageManager) {\n this.#packageManager = packageManager;\n }\n\n load(documentType: string): Promise<DocumentModelModule<any>> {\n const existing = this.#findModuleInLoadedPackages(documentType);\n if (existing) {\n this.#clearFailed(documentType);\n return Promise.resolve(existing);\n }\n\n this.#recordFailure(documentType);\n return Promise.reject(\n new Error(\n `No package registry configured; cannot resolve \"${documentType}\"`,\n ),\n );\n }\n\n promptInstallation(): void {\n // no registry to query — nothing to prompt\n }\n\n approveInstallation(): Promise<void> {\n return Promise.resolve();\n }\n\n dismissInstallation(): void {\n // nothing to dismiss\n }\n\n getPendingInstallations(): PendingInstallation[] {\n return [];\n }\n\n subscribePending(): () => void {\n return () => {};\n }\n\n getFailedInstallations(): FailedInstallation[] {\n return this.#failedMemo;\n }\n\n subscribeFailed(listener: () => void): () => void {\n this.#failedSubscribers.add(listener);\n return () => {\n this.#failedSubscribers.delete(listener);\n };\n }\n\n subscribeEvents(listener: DiscoveryEventListener): () => void {\n this.#eventSubscribers.add(listener);\n return () => {\n this.#eventSubscribers.delete(listener);\n };\n }\n\n retryInstallation(documentType: string): Promise<void> {\n // Retry is a no-op without a registry, but re-emitting the failure lets\n // a UI that cleared the row know the underlying condition still holds.\n this.#recordFailure(documentType);\n return Promise.resolve();\n }\n\n #findModuleInLoadedPackages(\n documentType: string,\n ): DocumentModelModule<any> | undefined {\n return this.#packageManager.packages\n .flatMap((p) => p.documentModels)\n .find((m) => m.documentModel.global.id === documentType);\n }\n\n #recordFailure(documentType: string): void {\n this.#failed.set(documentType, {\n documentType,\n reason: \"no-registry\",\n packageNames: [],\n error: null,\n });\n this.#emitEvent({\n type: \"load-failed\",\n documentType,\n reason: \"no-registry\",\n });\n this.#notifyFailedChanged();\n }\n\n #clearFailed(documentType: string): void {\n if (this.#failed.delete(documentType)) {\n this.#notifyFailedChanged();\n }\n }\n\n #notifyFailedChanged(): void {\n this.#failedMemo = Array.from(this.#failed.values());\n for (const listener of this.#failedSubscribers) {\n listener();\n }\n }\n\n #emitEvent(event: DiscoveryEvent): void {\n for (const listener of this.#eventSubscribers) {\n listener(event);\n }\n }\n}\n","import {\n BrowserLocalStorage,\n type IDocumentModelLoader,\n type IPackageDiscoveryService,\n type DiscoveryEvent,\n type DiscoveryEventListener,\n type FailedInstallation,\n type FailedInstallationReason,\n type PendingInstallation,\n} from \"@powerhousedao/reactor-browser\";\nimport type { RegistryClient } from \"@powerhousedao/reactor-browser\";\nimport type { DocumentModelModule } from \"@powerhousedao/shared/document-model\";\nimport type { BrowserPackageManager } from \"./package-manager.js\";\n\nexport type DiscoveryMode = \"immediate\" | \"manual\";\n\ntype DeferredEntry = {\n packageNames: string[];\n resolve: (module: DocumentModelModule<any>) => void;\n reject: (reason: unknown) => void;\n promise: Promise<DocumentModelModule<any>>;\n};\n\nexport class PackageDiscoveryService\n implements IDocumentModelLoader, IPackageDiscoveryService\n{\n #packageManager: BrowserPackageManager;\n #registryClient: RegistryClient;\n #mode: DiscoveryMode;\n\n #deferred = new Map<string, DeferredEntry>();\n #pending = new Map<string, PendingInstallation>();\n #pendingMemo: PendingInstallation[] = [];\n #pendingSubscribers = new Set<() => void>();\n #failed = new Map<string, FailedInstallation>();\n #failedMemo: FailedInstallation[] = [];\n #failedSubscribers = new Set<() => void>();\n #eventSubscribers = new Set<DiscoveryEventListener>();\n #dismissedStorage: BrowserLocalStorage<boolean>;\n #discoveredTypes = new Map<string, string[]>();\n\n constructor(\n packageManager: BrowserPackageManager,\n registryClient: RegistryClient,\n options: { mode: DiscoveryMode; storageKey: string },\n ) {\n this.#packageManager = packageManager;\n this.#registryClient = registryClient;\n this.#mode = options.mode;\n this.#dismissedStorage = new BrowserLocalStorage<boolean>(\n options.storageKey + \":PH_DISMISSED_TYPES\",\n );\n }\n\n load(documentType: string): Promise<DocumentModelModule<any>> {\n const existing = this.#findModuleInLoadedPackages(documentType);\n if (existing) {\n this.#clearFailed(documentType);\n return Promise.resolve(existing);\n }\n\n if (this.#dismissedStorage.has(documentType)) {\n this.#recordFailure(documentType, \"dismissed\", [], null);\n return Promise.reject(\n new Error(`Document type \"${documentType}\" was dismissed`),\n );\n }\n\n const tracked = this.#deferred.get(documentType);\n if (tracked) {\n return tracked.promise;\n }\n\n return this.#discover(documentType);\n }\n\n promptInstallation(documentType: string): void {\n const packageNames = this.#discoveredTypes.get(documentType);\n if (!packageNames) return;\n if (this.#pending.has(documentType)) return;\n\n this.#discoveredTypes.delete(documentType);\n this.#addToPending(documentType, packageNames);\n }\n\n async approveInstallation(packageName: string): Promise<void> {\n const affectedTypes = this.#findTypesByPackage(packageName);\n if (affectedTypes.length === 0) return;\n\n const result = await this.#packageManager.addPackage(packageName);\n if (result.type === \"error\") {\n this.#emitEvent({\n type: \"installation-failed\",\n packageName,\n error: result.error,\n });\n for (const documentType of affectedTypes) {\n const entry = this.#deferred.get(documentType);\n if (entry) {\n entry.reject(result.error);\n this.#deferred.delete(documentType);\n this.#pending.delete(documentType);\n }\n this.#recordFailure(\n documentType,\n \"install-failed\",\n [packageName],\n result.error,\n );\n }\n this.#notifyPendingChanged();\n return;\n }\n\n this.#emitEvent({\n type: \"installation-approved\",\n packageName,\n documentTypes: affectedTypes,\n });\n\n for (const documentType of affectedTypes) {\n const entry = this.#deferred.get(documentType);\n if (!entry) continue;\n\n const module = this.#findModuleInLoadedPackages(documentType);\n if (module) {\n entry.resolve(module);\n this.#clearFailed(documentType);\n } else {\n const error = new Error(\n `Package \"${packageName}\" installed but module for \"${documentType}\" not found`,\n );\n entry.reject(error);\n this.#recordFailure(\n documentType,\n \"install-failed\",\n [packageName],\n error,\n );\n }\n this.#deferred.delete(documentType);\n this.#pending.delete(documentType);\n }\n this.#notifyPendingChanged();\n }\n\n dismissInstallation(packageName: string): void {\n const affectedTypes = this.#findTypesByPackage(packageName);\n if (affectedTypes.length === 0) return;\n\n for (const documentType of affectedTypes) {\n this.#dismissedStorage.set(documentType, true);\n const entry = this.#deferred.get(documentType);\n if (entry) {\n entry.reject(\n new Error(`Document type \"${documentType}\" was dismissed`),\n );\n }\n this.#deferred.delete(documentType);\n this.#pending.delete(documentType);\n this.#discoveredTypes.delete(documentType);\n this.#recordFailure(documentType, \"dismissed\", [packageName], null);\n }\n\n this.#emitEvent({\n type: \"installation-dismissed\",\n packageName,\n documentTypes: affectedTypes,\n });\n this.#notifyPendingChanged();\n }\n\n getPendingInstallations(): PendingInstallation[] {\n return this.#pendingMemo;\n }\n\n subscribePending(listener: () => void): () => void {\n this.#pendingSubscribers.add(listener);\n return () => {\n this.#pendingSubscribers.delete(listener);\n };\n }\n\n getFailedInstallations(): FailedInstallation[] {\n return this.#failedMemo;\n }\n\n subscribeFailed(listener: () => void): () => void {\n this.#failedSubscribers.add(listener);\n return () => {\n this.#failedSubscribers.delete(listener);\n };\n }\n\n subscribeEvents(listener: DiscoveryEventListener): () => void {\n this.#eventSubscribers.add(listener);\n return () => {\n this.#eventSubscribers.delete(listener);\n };\n }\n\n async retryInstallation(documentType: string): Promise<void> {\n this.#dismissedStorage.delete(documentType);\n this.#clearFailed(documentType);\n try {\n await this.#discover(documentType);\n } catch {\n // failure has been recorded via #recordFailure; swallow so the\n // caller (UI button) doesn't have to handle the rejection\n }\n }\n\n async #discover(documentType: string): Promise<DocumentModelModule<any>> {\n // Offline: skip the doomed registry lookup and record an \"offline\" failure\n // so the banner shows an accurate, retryable message (not a generic registry\n // error). Only never-installed types reach here; cached editors rehydrate\n // from the SW.\n if (typeof navigator !== \"undefined\" && navigator.onLine === false) {\n this.#recordFailure(documentType, \"offline\", [], null);\n return Promise.reject(\n new Error(`Offline: cannot discover document type \"${documentType}\"`),\n );\n }\n\n let packageNames: string[];\n try {\n packageNames =\n await this.#registryClient.getPackagesByDocumentType(documentType);\n } catch (error) {\n const normalized =\n error instanceof Error ? error : new Error(String(error));\n this.#emitEvent({\n type: \"registry-query-failed\",\n documentType,\n error: normalized,\n });\n this.#recordFailure(documentType, \"registry-error\", [], normalized);\n return Promise.reject(normalized);\n }\n\n if (packageNames.length === 0) {\n this.#recordFailure(documentType, \"not-in-registry\", [], null);\n return Promise.reject(\n new Error(`No packages found for document type \"${documentType}\"`),\n );\n }\n\n const entry = this.#createDeferredEntry(documentType, packageNames);\n\n this.#emitEvent({\n type: \"type-discovered\",\n documentType,\n packageNames,\n });\n\n if (this.#mode === \"immediate\") {\n this.#addToPending(documentType, packageNames);\n } else {\n this.#discoveredTypes.set(documentType, packageNames);\n }\n\n return entry.promise;\n }\n\n #createDeferredEntry(\n documentType: string,\n packageNames: string[],\n ): DeferredEntry {\n let resolve!: (module: DocumentModelModule<any>) => void;\n let reject!: (reason: unknown) => void;\n const promise = new Promise<DocumentModelModule<any>>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n const entry: DeferredEntry = { packageNames, resolve, reject, promise };\n this.#deferred.set(documentType, entry);\n return entry;\n }\n\n #addToPending(documentType: string, packageNames: string[]): void {\n const installation: PendingInstallation = { documentType, packageNames };\n this.#pending.set(documentType, installation);\n this.#emitEvent({\n type: \"installation-prompted\",\n documentType,\n packageNames,\n });\n this.#notifyPendingChanged();\n }\n\n #findModuleInLoadedPackages(\n documentType: string,\n ): DocumentModelModule<any> | undefined {\n return this.#packageManager.packages\n .flatMap((p) => p.documentModels)\n .find((m) => m.documentModel.global.id === documentType);\n }\n\n #findTypesByPackage(packageName: string): string[] {\n const types: string[] = [];\n for (const [documentType, entry] of this.#deferred) {\n if (entry.packageNames.includes(packageName)) {\n types.push(documentType);\n }\n }\n return types;\n }\n\n #notifyPendingChanged(): void {\n this.#pendingMemo = Array.from(this.#pending.values());\n for (const listener of this.#pendingSubscribers) {\n listener();\n }\n }\n\n #notifyFailedChanged(): void {\n this.#failedMemo = Array.from(this.#failed.values());\n for (const listener of this.#failedSubscribers) {\n listener();\n }\n }\n\n #recordFailure(\n documentType: string,\n reason: FailedInstallationReason,\n packageNames: string[],\n error: Error | null,\n ): void {\n this.#failed.set(documentType, {\n documentType,\n reason,\n packageNames,\n error,\n });\n this.#emitEvent({ type: \"load-failed\", documentType, reason });\n this.#notifyFailedChanged();\n }\n\n #clearFailed(documentType: string): void {\n if (this.#failed.delete(documentType)) {\n this.#notifyFailedChanged();\n }\n }\n\n #emitEvent(event: DiscoveryEvent): void {\n for (const listener of this.#eventSubscribers) {\n listener(event);\n }\n }\n}\n","const GEN_KEY_PREFIX = \"ph-reactor-gen:\";\n\n// A persisted generation token, bumped on restart, is folded into the\n// SharedWorker name so a restart spawns a fresh worker instance while the\n// IndexedDB namespace (and its data) stays put.\nexport function reactorWorkerName(namespace: string): string {\n const gen = readWorkerGen(namespace);\n return gen ? `ph-reactor:${namespace}#${gen}` : `ph-reactor:${namespace}`;\n}\n\nexport function readWorkerGen(namespace: string): string | null {\n try {\n return localStorage.getItem(GEN_KEY_PREFIX + namespace);\n } catch {\n return null;\n }\n}\n\nexport function bumpWorkerGen(namespace: string, gen: string): void {\n try {\n localStorage.setItem(GEN_KEY_PREFIX + namespace, gen);\n } catch {\n // localStorage unavailable; the reload falls back to reusing the worker.\n }\n}\n","import {\n DocumentModelRegistry,\n DocumentModelResolver,\n ReactorEventTypes,\n type IDocumentModelLoader,\n type ModelLoadedEvent,\n type ReactorFeatureFlags,\n type UnsupportedStoredDocuments,\n} from \"@powerhousedao/reactor\";\nimport {\n setPGliteDB,\n type WorkerReactorClientModule,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n connectReactorClient,\n createInspectorProxy,\n createPortTransport,\n createReactorEventBusProxy,\n createRelationalPgliteProxy,\n createWorkerAdminClient,\n MessageRouter,\n postReactorIdentity,\n RPC_PROTOCOL_VERSION,\n SyncManagerProxy,\n type ReactorIdentity,\n} from \"@powerhousedao/reactor-browser/rpc\";\nimport type {\n DocumentModelModule,\n SignaturePolicy,\n UpgradeManifest,\n} from \"@powerhousedao/shared/document-model\";\nimport type { IRenown, User } from \"@renown/sdk\";\nimport { setWorkerConnectionStatus } from \"./connection-state.js\";\nimport { reactorWorkerName } from \"./reactor-worker-name.js\";\nimport { getGitSha, getVersion } from \"./utils/build-info.js\";\nimport type { RenownTrustEndpoints } from \"./utils/renown-trust.js\";\n\nconst PING_INTERVAL_MS = 2000;\nconst PING_DEADLINE_MS = 3000;\nconst MAX_MISSED_PINGS = 2;\n\nexport type WorkerReactorClientArgs = {\n namespace: string;\n relationalNamespace: string;\n cdnUrl: string;\n packageSpecs: string[];\n /** Absolute-URL shared-deps import map (from the production vendor); the\n * worker rewrites package sources to these URLs and blob-imports them. */\n sharedImports?: Record<string, string>;\n studioMode?: boolean;\n /** Loads the workflow package's document models. Independent of studioMode. */\n workflowsEnabled?: boolean;\n /** Chain the worker's bearer tokens are scoped to; matches the main thread's Renown instance. */\n renownChainId?: number;\n /** Enforcement flags for the worker's reactor; it has no runtime config to read them from. */\n featureFlags: Partial<ReactorFeatureFlags>;\n /** What the worker's client creates new documents as. */\n createSignaturePolicy?: SignaturePolicy;\n /** Whether the worker boots over stored documents this build does not run. */\n unsupportedStoredDocuments?: UnsupportedStoredDocuments;\n /** Where the worker's trust policy verifies signers under authEnforcement. */\n renownEndpoints?: RenownTrustEndpoints;\n documentModelModules: DocumentModelModule[];\n upgradeManifests: UpgradeManifest<readonly number[]>[];\n documentModelLoader: IDocumentModelLoader;\n renown: IRenown;\n onReload: (reason: string, workerGen?: string) => void;\n};\n\nexport type WorkerReactorClient = {\n reactorClientModule: WorkerReactorClientModule;\n syncManagerProxy: SyncManagerProxy;\n dispose: () => void;\n};\n\n/** Sorted so the same set always produces the same fingerprint. */\nfunction enabledFlagList(flags: Partial<ReactorFeatureFlags>): string {\n return Object.entries(flags)\n .filter(([, enabled]) => enabled)\n .map(([name]) => name)\n .sort()\n .join(\",\");\n}\n\nfunction toReactorIdentity(user: User | undefined): ReactorIdentity | null {\n if (!user) {\n return null;\n }\n return {\n address: user.address,\n chainId: user.chainId,\n networkId: user.networkId,\n };\n}\n\nexport function createWorkerReactorClientModule(\n args: WorkerReactorClientArgs,\n): WorkerReactorClient {\n const workerUrl = new URL(\"./reactor.worker.js\", import.meta.url);\n console.info(\n `[reactor-worker] constructing SharedWorker ${reactorWorkerName(\n args.namespace,\n )} from ${workerUrl.href}`,\n );\n const worker = new SharedWorker(workerUrl, {\n name: reactorWorkerName(args.namespace),\n type: \"module\",\n });\n worker.addEventListener(\"error\", (event) => {\n console.error(\n `[reactor-worker] SharedWorker failed to load from ${workerUrl.href}`,\n event.message || event,\n );\n });\n worker.port.onmessageerror = (event) => {\n console.error(\n \"[reactor-worker] port message could not be deserialized\",\n event,\n );\n };\n const transport = createPortTransport(worker.port);\n const router = new MessageRouter();\n router.attach(transport);\n\n const documentModelRegistry = new DocumentModelRegistry();\n documentModelRegistry.registerModules(...args.documentModelModules);\n documentModelRegistry.registerUpgradeManifests(...args.upgradeManifests);\n\n const gitSha = getGitSha();\n const clientProxy = connectReactorClient(\n router,\n {\n version: {\n appBuildId: gitSha !== \"unknown\" ? gitSha : getVersion(),\n rpcProtocolVersion: RPC_PROTOCOL_VERSION,\n models: args.documentModelModules.map((m) => ({\n id: m.documentModel.global.id,\n version: m.version ?? 1,\n })),\n featureFlags: enabledFlagList(args.featureFlags),\n },\n construct: {\n namespace: args.namespace,\n relationalNamespace: args.relationalNamespace,\n cdnUrl: args.cdnUrl,\n packageSpecs: args.packageSpecs,\n sharedImports: args.sharedImports,\n studioMode: args.studioMode,\n workflowsEnabled: args.workflowsEnabled,\n renownChainId: args.renownChainId,\n featureFlags: args.featureFlags,\n createSignaturePolicy: args.createSignaturePolicy,\n unsupportedStoredDocuments: args.unsupportedStoredDocuments,\n renownEndpoints: args.renownEndpoints,\n },\n packages: args.packageSpecs,\n },\n args.onReload,\n documentModelRegistry,\n );\n\n const busProxy = createReactorEventBusProxy(router);\n const syncManagerProxy = new SyncManagerProxy(router, busProxy);\n\n // Keep the tab registry synced with the worker's on-demand loads.\n const modelResolver = new DocumentModelResolver(\n documentModelRegistry,\n args.documentModelLoader,\n );\n busProxy.subscribe(ReactorEventTypes.MODEL_LOADED, (_type, event) => {\n const { documentType } = event as ModelLoadedEvent;\n void modelResolver.ensureModelLoaded(documentType).catch((error) => {\n console.error(\n `Failed to load model \"${documentType}\" into tab registry`,\n error,\n );\n });\n });\n\n // Seed the relational read surface the relational hooks read (SELECT + live, no raw PGlite).\n setPGliteDB({\n db: createRelationalPgliteProxy(router),\n isLoading: false,\n error: null,\n });\n\n postReactorIdentity(router, toReactorIdentity(args.renown.user));\n args.renown.on(\"user\", (user) =>\n postReactorIdentity(router, toReactorIdentity(user)),\n );\n\n const reactorClientModule: WorkerReactorClientModule = {\n kind: \"worker\",\n client: clientProxy,\n adminClient: createWorkerAdminClient(router),\n inspector: createInspectorProxy(router),\n reactorModule: {\n documentModelRegistry,\n syncModule: { syncManager: syncManagerProxy },\n eventBus: busProxy,\n },\n };\n\n let pingCounter = 0;\n let missedPings = 0;\n const pingDeadlines = new Map<string, ReturnType<typeof setTimeout>>();\n\n router.on(\"pong\", (msg) => {\n const timer = pingDeadlines.get(msg.id);\n if (timer === undefined) {\n return;\n }\n clearTimeout(timer);\n pingDeadlines.delete(msg.id);\n missedPings = 0;\n setWorkerConnectionStatus(\"connected\");\n });\n\n const pingInterval = setInterval(() => {\n const id = `ping${++pingCounter}`;\n const timer = setTimeout(() => {\n pingDeadlines.delete(id);\n missedPings += 1;\n if (missedPings >= MAX_MISSED_PINGS) {\n setWorkerConnectionStatus(\"lost\");\n }\n }, PING_DEADLINE_MS);\n pingDeadlines.set(id, timer);\n router.post({ k: \"ping\", id });\n }, PING_INTERVAL_MS);\n\n const dispose = () => {\n clearInterval(pingInterval);\n for (const timer of pingDeadlines.values()) {\n clearTimeout(timer);\n }\n pingDeadlines.clear();\n };\n\n return { reactorClientModule, syncManagerProxy, dispose };\n}\n","import { getRuntimeConfig } from \"../runtime-config.js\";\n\nexport const REACTOR_WORKER_QUERY_KEY = \"reactorWorker\";\nexport const REACTOR_WORKER_STORAGE_KEY = \"ph:reactorWorker\";\n\nexport type ReactorWorkerFlagInput = {\n configFlag: boolean;\n queryParam?: string | null;\n storedValue?: string | null;\n};\n\nexport function resolveReactorWorkerEnabled(\n input: ReactorWorkerFlagInput,\n): boolean {\n const fromQuery = parseFlag(input.queryParam);\n if (fromQuery !== undefined) {\n return fromQuery;\n }\n const fromStore = parseFlag(input.storedValue);\n if (fromStore !== undefined) {\n return fromStore;\n }\n return input.configFlag;\n}\n\n// Effective flag from config + dev override; a query-param override is persisted\n// to localStorage so it survives a refresh.\nexport function isReactorWorkerEnabled(): boolean {\n const configFlag =\n getRuntimeConfig().connect.instance?.reactorWorker ?? false;\n if (typeof window === \"undefined\") {\n return configFlag;\n }\n const queryParam = new URLSearchParams(window.location.search).get(\n REACTOR_WORKER_QUERY_KEY,\n );\n const storedValue = window.localStorage.getItem(REACTOR_WORKER_STORAGE_KEY);\n const enabled = resolveReactorWorkerEnabled({\n configFlag,\n queryParam,\n storedValue,\n });\n // Persist only an explicit override, not an unrecognized value.\n if (parseFlag(queryParam) !== undefined) {\n window.localStorage.setItem(\n REACTOR_WORKER_STORAGE_KEY,\n enabled ? \"true\" : \"false\",\n );\n }\n return enabled;\n}\n\nfunction parseFlag(value: string | null | undefined): boolean | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === \"true\" || normalized === \"1\") {\n return true;\n }\n if (normalized === \"false\" || normalized === \"0\") {\n return false;\n }\n // Unrecognized value (e.g. a typo): no override, fall through to store/config.\n return undefined;\n}\n","import {\n createReactorHostModuleBase,\n type IReadModel,\n} from \"@powerhousedao/reactor\";\nimport {\n createAttachmentClient,\n type AttachmentDownloadTarget,\n type AttachmentHeader,\n type AttachmentResponse,\n type IAttachmentService,\n} from \"@powerhousedao/reactor-attachments/client\";\nimport {\n createAnalyticsStore,\n type IProcessorHostModule,\n type IReactorClient,\n} from \"@powerhousedao/reactor-browser\";\nimport { getDb } from \"../pglite.db.js\";\n\n/** @deprecated Use IReactorClient from @powerhousedao/reactor-browser */\nexport type IReactorDispatch = IReactorClient;\n\nclass NullAttachmentService implements IAttachmentService {\n reserve(): Promise<never> {\n return Promise.reject(\n new Error(\"NullAttachmentService: no attachment service configured\"),\n );\n }\n stat(): Promise<AttachmentHeader> {\n return Promise.reject(\n new Error(\"NullAttachmentService: no attachment service configured\"),\n );\n }\n get(): Promise<AttachmentResponse> {\n return Promise.reject(\n new Error(\"NullAttachmentService: no attachment service configured\"),\n );\n }\n getDownloadTarget(): Promise<AttachmentDownloadTarget> {\n return Promise.reject(\n new Error(\"NullAttachmentService: no attachment service configured\"),\n );\n }\n}\n\nexport async function createProcessorHostModule(\n reactorClient: IReactorClient,\n readModels: ReadonlyArray<Pick<IReadModel, \"name\">>,\n attachmentService?: IAttachmentService,\n): Promise<IProcessorHostModule | undefined> {\n try {\n const { pgLite, relationalDb } = await getDb();\n const { store: analyticsStore } = await createAnalyticsStore({\n pgLite,\n });\n return {\n ...createReactorHostModuleBase({\n client: reactorClient,\n readModels,\n relationalDb,\n analyticsStore,\n processorApp: \"connect\",\n }),\n attachments: createAttachmentClient(\n attachmentService ?? new NullAttachmentService(),\n ),\n };\n } catch (error) {\n console.error(`Failed to initialize processor host module:`);\n console.error(error);\n }\n}\n","import {\n buildPHGlobalConfig,\n connectConfig,\n phGlobalConfig,\n} from \"@powerhousedao/connect/config\";\nimport { toast } from \"@powerhousedao/connect/services\";\nimport {\n addDefaultDrivesForNewReactor,\n createBrowserReactor,\n getDefaultDrives,\n} from \"@powerhousedao/connect/utils\";\nimport {\n createRemoteAttachmentService,\n createXhrUploadTransport,\n} from \"@powerhousedao/reactor-attachments/client\";\nimport {\n addPHEventHandlers,\n addRemoteDrive,\n DocumentCache,\n DocumentChangeType,\n DRIVE_DOCUMENT_TYPES,\n extractDriveSlugFromPath,\n extractNodeSlugFromPath,\n getDrives,\n login,\n refreshReactorDataClient,\n RegistryClient,\n setAttachmentService,\n setDefaultPHGlobalConfig,\n setDocumentCache,\n setDrives,\n setFeatures,\n setPackageDiscoveryService,\n setPHToast,\n setReactorClient,\n setReactorClientModule,\n setRenown,\n setSelectedDrive,\n setSelectedNode,\n setVetraPackageManager,\n type BrowserReactorClientModule,\n type IDocumentModelLoader,\n type IPackageManager,\n type PHToastFn,\n type ReactorFeatureFlags,\n type WorkerReactorClientModule,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n BrowserKeyStorage,\n RenownBuilder,\n RenownCryptoBuilder,\n} from \"@renown/sdk\";\nimport {\n logger,\n type DocumentModelLib,\n type UpgradeManifest,\n} from \"document-model\";\nimport { initFeatureFlags } from \"../feature-flags.js\";\nimport { NoRegistryDiscoveryService } from \"../no-registry-discovery.js\";\nimport { PackageDiscoveryService } from \"../package-discovery.js\";\nimport { BrowserPackageManager } from \"../package-manager.js\";\nimport { createWorkerReactorClientModule } from \"../reactor-worker-client.js\";\nimport { bumpWorkerGen } from \"../reactor-worker-name.js\";\nimport { getRuntimeConfig } from \"../runtime-config.js\";\nimport { getSharedDeps } from \"../shared-deps.js\";\nimport { isReactorWorkerEnabled } from \"../utils/reactor-worker-flag.js\";\nimport {\n REACTOR_INSTANCE_NAMESPACE,\n RELATIONAL_PGLITE_NAME,\n} from \"../utils/storage-namespace.js\";\nimport { createProcessorHostModule } from \"./processor-host-module.js\";\n\n/**\n * Subscribe to ph-clint's `/__packages` SSE channel; each `packages-changed`\n * event sends the full live list, which we diff to add/remove packages.\n * Best-effort: no-ops when the endpoint is absent (e.g. vite dev).\n */\nfunction subscribeToPackagesChannel(packageManager: IPackageManager): void {\n if (typeof window === \"undefined\" || typeof EventSource === \"undefined\") {\n return;\n }\n let source: EventSource;\n try {\n source = new EventSource(\"/__packages\");\n } catch (err) {\n console.debug(\"[Connect] /__packages subscribe failed:\", err);\n return;\n }\n let firstEvent = true;\n source.addEventListener(\"packages-changed\", (event) => {\n try {\n const payload = JSON.parse((event as MessageEvent<string>).data) as {\n packages?: unknown;\n };\n if (!Array.isArray(payload.packages)) return;\n const next = payload.packages.filter(\n (p): p is string => typeof p === \"string\",\n );\n // Split a spec into (bareName, version). For scoped specs the leading\n // `@` is the scope, so the version `@` only counts when past index 0.\n const parseBare = (\n spec: string,\n ): { bareName: string; version?: string } => {\n const at = spec.startsWith(\"@\")\n ? spec.lastIndexOf(\"@\")\n : spec.indexOf(\"@\");\n if (at > 0) {\n return { bareName: spec.slice(0, at), version: spec.slice(at + 1) };\n }\n return { bareName: spec };\n };\n\n // Diff against registry packages only; bundled/local packages aren't in\n // the server list and removing them would break the drive editors.\n const currentByName = new Map(\n packageManager\n .getRegistryPackages()\n .map(({ name, version }) => [name, version]),\n );\n const nextByName = new Map<string, string | undefined>();\n for (const spec of next) {\n const { bareName, version } = parseBare(spec);\n nextByName.set(bareName, version);\n }\n\n const isFirst = firstEvent;\n firstEvent = false;\n\n for (const name of currentByName.keys()) {\n if (!nextByName.has(name)) {\n packageManager.removePackage(name);\n if (!isFirst) {\n toast(`Removed package ${name}`, { type: \"connect-deleted\" });\n }\n }\n }\n for (const spec of next) {\n const { bareName, version } = parseBare(spec);\n const currentVersion = currentByName.get(bareName);\n const isKnown = currentByName.has(bareName);\n if (\n isKnown &&\n (!version || !currentVersion || version === currentVersion)\n ) {\n continue;\n }\n const isUpdate = isKnown;\n Promise.resolve(packageManager.addPackage(spec)).then(\n (result) => {\n if (result.type === \"error\") {\n console.error(\n `[Connect] /__packages addPackage(${spec}) failed:`,\n result.error,\n );\n return;\n }\n if (isFirst) return;\n const name = result.package.manifest.name;\n toast(\n isUpdate\n ? `Updated package ${name}`\n : `Installed package ${name}`,\n { type: \"connect-success\" },\n );\n },\n (err: unknown) => {\n console.error(\n `[Connect] /__packages addPackage(${spec}) threw:`,\n err,\n );\n },\n );\n }\n } catch (err) {\n console.error(\"[Connect] /__packages event parse failed:\", err);\n }\n });\n source.addEventListener(\"error\", () => {\n // EventSource auto-reconnects.\n });\n}\n\nexport async function clearReactorStorage() {\n const module = window.ph?.reactorClientModule;\n if (module?.kind === \"worker\") {\n // The worker holds the PGlite handles open, so it must close + clear them.\n await module.adminClient.clearStorage();\n return;\n }\n if (module?.kind === \"browser\") {\n await module.reactorModule?.pg?.close();\n }\n\n // Dropping tables in PGlite with relaxedDurability can lose pending IDB\n // writes on reload; delete the whole DB so startup re-migrates from scratch.\n const dbs = await indexedDB.databases();\n const targets = dbs\n .map((d) => d.name)\n .filter(\n (n): n is string =>\n !!n && !n.startsWith(\"ph-pglite-backup::\") && /pglite|reactor/i.test(n),\n );\n\n await Promise.all(\n targets.map(\n (name) =>\n new Promise<void>((resolve) => {\n const req = indexedDB.deleteDatabase(name);\n req.onsuccess = req.onerror = req.onblocked = () => resolve();\n }),\n ),\n );\n}\n\nexport async function createReactor(localPackage?: DocumentModelLib) {\n if (!window.ph) {\n window.ph = {};\n }\n if (window.ph.loading) return;\n\n window.ph.loading = true;\n\n addPHEventHandlers();\n\n setPHToast(toast as PHToastFn);\n\n const features = await initFeatureFlags();\n\n logger.info(\n \"Features: @features\",\n JSON.stringify(Object.fromEntries(features), null, 2),\n );\n\n // Credentials and the bearer token must be scoped to the same chain, and the\n // worker mints its own tokens, so this value is passed to it too (see below).\n const renownChainId = getRuntimeConfig().connect.renown?.chainId;\n\n const keyPairStorage = await BrowserKeyStorage.create();\n const cryptoBuilder = new RenownCryptoBuilder().withKeyPairStorage(\n keyPairStorage,\n );\n if (renownChainId !== undefined) {\n cryptoBuilder.withChainId(renownChainId);\n }\n const renownCrypto = await cryptoBuilder.build();\n\n // Renown namespace is a boot-time constant, so read it from runtime config\n // rather than the PHGlobalConfig machinery; baseUrl stays in phGlobalConfig.\n const renown = await new RenownBuilder(\"connect\", {\n basename:\n getRuntimeConfig().connect.renown?.namespace ??\n phGlobalConfig.routerBasename,\n baseUrl: phGlobalConfig.renownUrl,\n switchboardUrl: phGlobalConfig.switchboardUrl,\n chainId: renownChainId,\n })\n .withCrypto(renownCrypto)\n .build();\n\n // Sync getter is safe: loadComponent() warmed the cache before createReactor,\n // and it throws loudly if a future caller violates that boot ordering.\n const runtimeConfig = getRuntimeConfig();\n\n const packageManager = new BrowserPackageManager(\n phGlobalConfig.routerBasename ?? \"\",\n runtimeConfig.packageRegistryUrl ?? null,\n );\n setVetraPackageManager(packageManager);\n await packageManager.init(\n localPackage,\n runtimeConfig.localPackage?.version,\n phGlobalConfig.studioMode,\n connectConfig.workflowsEnabled,\n );\n // Register provider:\"local\" packages the vite plugin bundled in. The virtual\n // module only exists under phBundledPackagesPlugin (ph-cli), so a resolution\n // failure under plain vite dev is expected; the indirection + @vite-ignore\n // also stops Vite's dep scanner from pre-bundling the specifier.\n try {\n const bundledPackagesModule = \"ph-bundled-packages-virtual\";\n const { default: registerBundledPackages } = (await import(\n /* @vite-ignore */ bundledPackagesModule\n )) as { default: (pm: IPackageManager) => void };\n registerBundledPackages(packageManager);\n } catch {\n // no bundled packages in this build\n }\n const remotePackages = runtimeConfig.packages\n .filter((p) => p.provider !== \"local\")\n .map((p) => (p.version ? `${p.packageName}@${p.version}` : p.packageName));\n const packagesResult = await packageManager.addPackages(remotePackages);\n packagesResult.map((r) => {\n if (r.type === \"error\") console.error(r.error);\n });\n\n // Opt-in (connect.packages.liveReload): pick up live publishes without a\n // page reload via the static-mode `/__packages` SSE channel.\n if (runtimeConfig.connect?.packages?.liveReload) {\n subscribeToPackagesChannel(packageManager);\n }\n\n const documentModelModules = packageManager.packages\n .flatMap((pkg) => pkg.documentModels)\n .filter(\n (module, index, modules) =>\n // dedupe by documentType and version\n modules.findIndex(\n (m) =>\n m.documentModel.global.id === module.documentModel.global.id &&\n m.version === module.version,\n ) === index,\n );\n\n const upgradeManifests = packageManager.packages\n .flatMap((pkg) => pkg.upgradeManifests)\n .filter(\n (manifest, index, manifests) =>\n // dedupe by documentType\n manifest !== undefined &&\n manifests.findIndex(\n (m) => m && m.documentType === manifest.documentType,\n ) === index,\n ) as UpgradeManifest<readonly number[]>[];\n\n // auto-installs packages for unknown document types\n const discoveryService =\n packageManager.cdnUrl !== null\n ? new PackageDiscoveryService(\n packageManager,\n new RegistryClient(packageManager.cdnUrl),\n {\n mode: \"immediate\",\n storageKey: phGlobalConfig.routerBasename ?? \"\",\n },\n )\n : new NoRegistryDiscoveryService(packageManager);\n\n setPackageDiscoveryService(discoveryService);\n\n // Config alone, no per-tab override: these must match the fleet Connect syncs\n // with. The worker gets them in its construct message.\n const reactorFeatureFlags: Partial<ReactorFeatureFlags> =\n runtimeConfig.connect?.reactor?.featureFlags ?? {};\n const enabledReactorFlags = Object.entries(reactorFeatureFlags)\n .filter(([, enabled]) => enabled)\n .map(([name]) => name);\n if (enabledReactorFlags.length > 0) {\n logger.info(`Reactor feature flags: ${enabledReactorFlags.join(\", \")}`);\n }\n const createSignaturePolicy =\n runtimeConfig.connect?.reactor?.createSignaturePolicy;\n const unsupportedStoredDocuments =\n runtimeConfig.connect?.reactor?.unsupportedStoredDocuments;\n // Both hosts verify signers against the endpoints the tab's Renown uses.\n const renownEndpoints = {\n renownUrl: phGlobalConfig.renownUrl,\n switchboardUrl: phGlobalConfig.switchboardUrl,\n };\n\n // create reactor v2 with all versions and upgrade manifests\n let reactorClientModule:\n | BrowserReactorClientModule\n | WorkerReactorClientModule;\n if (isReactorWorkerEnabled()) {\n const packageSpecs = packageManager\n .getRegistryPackages()\n .map((p) => (p.version ? `${p.name}@${p.version}` : p.name));\n // Silent tab loader (no install prompt; the worker already loaded the model).\n const registryClient = new RegistryClient(packageManager.cdnUrl ?? \"\");\n const documentModelLoader: IDocumentModelLoader = {\n async load(documentType) {\n const names = packageManager.cdnUrl\n ? await registryClient.getPackagesByDocumentType(documentType)\n : [];\n for (const name of names) {\n const result = await packageManager.addPackage(name);\n if (result.type === \"error\") {\n throw new Error(\n `Failed to install package \"${name}\" for document model: ${documentType}`,\n { cause: result.error },\n );\n }\n }\n const module = packageManager.packages\n .flatMap((p) => p.documentModels)\n .find((m) => m.documentModel.global.id === documentType);\n if (!module) {\n throw new Error(\n names.length > 0\n ? `Installed [${names.join(\", \")}] but document model not available: ${documentType}`\n : `No package found for document model: ${documentType} (cdnUrl: ${packageManager.cdnUrl ?? \"none\"})`,\n );\n }\n return module;\n },\n };\n // The production vendor's shared-deps table (null in dev / vendor-off\n // builds): the worker rewrites shared imports in package sources to\n // these absolute URLs and blob-imports the result.\n const sharedImports = (await getSharedDeps())?.imports;\n const workerClient = createWorkerReactorClientModule({\n namespace: REACTOR_INSTANCE_NAMESPACE,\n relationalNamespace: RELATIONAL_PGLITE_NAME,\n cdnUrl: packageManager.cdnUrl ?? \"\",\n packageSpecs,\n sharedImports,\n studioMode: phGlobalConfig.studioMode,\n workflowsEnabled: connectConfig.workflowsEnabled,\n renownChainId,\n featureFlags: reactorFeatureFlags,\n createSignaturePolicy,\n unsupportedStoredDocuments,\n renownEndpoints,\n documentModelModules,\n upgradeManifests,\n documentModelLoader,\n renown,\n onReload: (reason, workerGen) => {\n logger.warn(\"Reactor worker requested reload: @reason\", reason);\n if (workerGen) {\n bumpWorkerGen(REACTOR_INSTANCE_NAMESPACE, workerGen);\n }\n window.location.reload();\n },\n });\n reactorClientModule = workerClient.reactorClientModule;\n // Block boot until the sync manager seeds remotes from the worker, so\n // list()/connection state are warm before consumers first read them.\n try {\n await workerClient.syncManagerProxy.startup();\n } catch (error) {\n window.ph.loading = false;\n logger.error(\"Reactor worker failed to start: @error\", error);\n throw error;\n }\n } else {\n reactorClientModule = await createBrowserReactor(\n documentModelModules,\n upgradeManifests,\n renown,\n reactorFeatureFlags,\n discoveryService,\n createSignaturePolicy,\n renownEndpoints,\n unsupportedStoredDocuments,\n );\n }\n\n const drives = await getDrives(reactorClientModule.client);\n\n const didFromUrl = getDidFromUrl();\n await login(didFromUrl, renown);\n\n const documentCache = new DocumentCache(reactorClientModule.client);\n\n const basePath = phGlobalConfig.basePath ?? \"/\";\n const routerBasename = phGlobalConfig.routerBasename ?? \"/\";\n const mergedGlobalConfig = buildPHGlobalConfig(\n basePath,\n routerBasename,\n runtimeConfig.connect ?? {},\n );\n setDefaultPHGlobalConfig(mergedGlobalConfig);\n\n // Slug extraction needs window.ph.basePath, published by\n // setDefaultPHGlobalConfig above.\n const path = window.location.pathname;\n const driveSlug = extractDriveSlugFromPath(path);\n const nodeSlug = extractNodeSlugFromPath(path);\n setReactorClientModule(reactorClientModule);\n setReactorClient(reactorClientModule.client);\n\n const _defaultDrivesUrl = phGlobalConfig.defaultDrivesUrl;\n if (_defaultDrivesUrl) {\n let switchboardOrigin: string | undefined;\n try {\n switchboardOrigin = new URL(_defaultDrivesUrl).origin;\n } catch {\n // malformed URL — skip attachment service construction\n }\n if (switchboardOrigin) {\n const attachmentJwtHandler = async (_url: string) => {\n if (!renown.user) return undefined;\n // aud omitted: server rejects aud-bearing tokens. Re-enable once both sides support it.\n return renown.getBearerToken({ expiresIn: 10 });\n };\n const attachmentService = createRemoteAttachmentService({\n remoteUrl: switchboardOrigin,\n jwtHandler: attachmentJwtHandler,\n // XMLHttpRequest is the only browser API that reports upload byte\n // progress; everything else about the request is unchanged.\n uploadTransport: createXhrUploadTransport(),\n });\n setAttachmentService(attachmentService);\n }\n }\n\n setDocumentCache(documentCache);\n setRenown(renown);\n setDrives(drives);\n setFeatures(features);\n\n // Add default/remote drives in the background so the app renders immediately;\n // setSelectedDrive defers selection until the URL-matched drive syncs in.\n const defaultDrivesConfig = getDefaultDrives(runtimeConfig);\n if (defaultDrivesConfig.length > 0) {\n void addDefaultDrivesForNewReactor(defaultDrivesConfig).catch((error) =>\n console.error(\"Failed to add default drives:\", error),\n );\n }\n\n const remoteUrl = getDriveUrl();\n if (remoteUrl) {\n void addRemoteDrive(remoteUrl, undefined).catch((error) =>\n console.error(`Failed to add remote drive from ${remoteUrl}:`, error),\n );\n }\n\n setSelectedDrive(driveSlug);\n setSelectedNode(nodeSlug);\n\n // Refresh the drive list on any drive-type change so async-added\n // default/remote drives surface on first load without a manual reload.\n const reactorClient = reactorClientModule.client;\n for (const driveType of DRIVE_DOCUMENT_TYPES) {\n reactorClient.subscribe({ type: driveType }, (event) => {\n logger.verbose(\"ReactorClient subscription event: @event\", event);\n refreshReactorDataClient(reactorClientModule.client).catch((e) =>\n logger.error(\"@error\", e),\n );\n });\n }\n\n // Redirect when a currently-viewed document or drive is deleted remotely\n reactorClient.subscribe({}, (event) => {\n if (event.type !== DocumentChangeType.Deleted) return;\n const deletedId = event.context?.childId;\n if (!deletedId) return;\n\n const selectedDriveId = window.ph?.selectedDriveId;\n const selectedNodeId = window.ph?.selectedNodeId;\n\n if (selectedDriveId && deletedId === selectedDriveId) {\n setSelectedDrive(undefined);\n toast(\"The drive you were viewing has been deleted\");\n return;\n }\n\n if (selectedNodeId && deletedId === selectedNodeId) {\n setSelectedNode(undefined);\n toast(\"The document you were editing has been deleted\");\n }\n });\n\n await refreshReactorDataClient(reactorClientModule.client);\n\n const packagesWithProcessorFactories = packageManager.packages.filter(\n (pkg) => pkg.processorFactory !== undefined,\n );\n\n // processorManager lives in the worker on the cutover path and is not yet\n // bridged, so surface the gap loudly rather than dropping factories silently.\n const reactorModule =\n reactorClientModule.kind === \"browser\"\n ? reactorClientModule.reactorModule\n : undefined;\n if (packagesWithProcessorFactories.length > 0 && !reactorModule) {\n for (const pkg of packagesWithProcessorFactories) {\n logger.warn(\n \"Skipping processor factory @name: processors are not supported on the worker reactor path yet\",\n pkg.manifest.name,\n );\n }\n } else if (packagesWithProcessorFactories.length > 0 && reactorModule) {\n const readModels = reactorModule.readModelCoordinator.readModels;\n const processorHostModule = await createProcessorHostModule(\n reactorClientModule.client,\n readModels,\n window.ph?.attachmentService,\n );\n if (processorHostModule !== undefined) {\n await Promise.all(\n packagesWithProcessorFactories.map(async (pkg) => {\n const { manifest, processorFactory } = pkg;\n const name = manifest.name;\n const id = manifest.name;\n const version = packageManager.getPackageVersion(name);\n const label = version ? `${name}@${version}` : name;\n logger.info(\"Loading processor factory: @label\", label);\n try {\n const factory = await processorFactory?.(processorHostModule);\n if (!factory) return;\n await reactorModule.processorManager.registerFactory(id, factory);\n } catch (error) {\n logger.error(`Error registering processor: @label`, label);\n logger.error(\"@error\", error);\n }\n }),\n );\n }\n }\n\n window.ph.loading = false;\n}\n\nfunction getDidFromUrl() {\n const searchParams = new URLSearchParams(window.location.search);\n const didComponent = searchParams.get(\"user\");\n const did = didComponent ? decodeURIComponent(didComponent) : undefined;\n return did;\n}\n\nfunction getDriveUrl() {\n const searchParams = new URLSearchParams(window.location.search);\n const driveUrl = searchParams.get(\"driveUrl\");\n const url = driveUrl ? decodeURIComponent(driveUrl) : undefined;\n return url;\n}\n"],"names":["ReactorBuilder","ChannelScheme","ReactorClientBuilder"],"mappings":"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","debug_id":"022038d0-e4f5-5d38-af03-f3a04e7f9e24"}