@powerhousedao/connect 6.2.3-dev.4 → 6.2.3-dev.41

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 (119) hide show
  1. package/dist/{AddDriveModal-xAw48kdl.js → AddDriveModal-DhNfP94R.js} +5 -5
  2. package/dist/{AddDriveModal-xAw48kdl.js.map → AddDriveModal-DhNfP94R.js.map} +1 -1
  3. package/dist/{ClearStorageModal-DLchAUxQ.js → ClearStorageModal-DaNmZ8f2.js} +5 -5
  4. package/dist/{ClearStorageModal-DLchAUxQ.js.map → ClearStorageModal-DaNmZ8f2.js.map} +1 -1
  5. package/dist/{ConfirmDocumentUpgradeModal-FUOhZsk7.js → ConfirmDocumentUpgradeModal-DcOZy20m.js} +8 -7
  6. package/dist/{ConfirmDocumentUpgradeModal-FUOhZsk7.js.map → ConfirmDocumentUpgradeModal-DcOZy20m.js.map} +1 -1
  7. package/dist/{CookiesPolicyModal-BpyPPyxS.js → CookiesPolicyModal-BLw4pnhn.js} +4 -4
  8. package/dist/{CookiesPolicyModal-BpyPPyxS.js.map → CookiesPolicyModal-BLw4pnhn.js.map} +1 -1
  9. package/dist/{CreateDocumentModal-C45W8J0V.js → CreateDocumentModal-Bmv0V-kY.js} +6 -5
  10. package/dist/{CreateDocumentModal-C45W8J0V.js.map → CreateDocumentModal-Bmv0V-kY.js.map} +1 -1
  11. package/dist/{DebugSettingsModal-Bg0wn3oX.js → DebugSettingsModal-EYgccEiI.js} +7 -7
  12. package/dist/{DebugSettingsModal-Bg0wn3oX.js.map → DebugSettingsModal-EYgccEiI.js.map} +1 -1
  13. package/dist/{DeleteDriveModal-Dug84t1j.js → DeleteDriveModal-CjGnG0ht.js} +5 -5
  14. package/dist/{DeleteDriveModal-Dug84t1j.js.map → DeleteDriveModal-CjGnG0ht.js.map} +1 -1
  15. package/dist/{DeleteItemModal-mMzy3V8o.js → DeleteItemModal-BbY_4_xT.js} +5 -5
  16. package/dist/{DeleteItemModal-mMzy3V8o.js.map → DeleteItemModal-BbY_4_xT.js.map} +1 -1
  17. package/dist/{DisclaimerModal-DvpD5dPM.js → DisclaimerModal-DuglmEwL.js} +4 -4
  18. package/dist/{DisclaimerModal-DvpD5dPM.js.map → DisclaimerModal-DuglmEwL.js.map} +1 -1
  19. package/dist/{DocumentVersionUnsupportedModal-C3Q0V75l.js → DocumentVersionUnsupportedModal-C4fy7fZ6.js} +4 -4
  20. package/dist/{DocumentVersionUnsupportedModal-C3Q0V75l.js.map → DocumentVersionUnsupportedModal-C4fy7fZ6.js.map} +1 -1
  21. package/dist/{DownloadDocumentWithErrorsModal-IKl0ljQb.js → DownloadDocumentWithErrorsModal-BsPQ5qgy.js} +6 -5
  22. package/dist/{DownloadDocumentWithErrorsModal-IKl0ljQb.js.map → DownloadDocumentWithErrorsModal-BsPQ5qgy.js.map} +1 -1
  23. package/dist/{DriveAuthRequiredModal-DVK7ZQzO.js → DriveAuthRequiredModal-CtsB0kwH.js} +5 -5
  24. package/dist/{DriveAuthRequiredModal-DVK7ZQzO.js.map → DriveAuthRequiredModal-CtsB0kwH.js.map} +1 -1
  25. package/dist/{DriveSettingsModal-C6-mRQiv.js → DriveSettingsModal-d1L0eYof.js} +4 -4
  26. package/dist/{DriveSettingsModal-C6-mRQiv.js.map → DriveSettingsModal-d1L0eYof.js.map} +1 -1
  27. package/dist/{InspectorModal-DoEQVQYq.js → InspectorModal-Bkry1jv9.js} +61 -21
  28. package/dist/InspectorModal-Bkry1jv9.js.map +1 -0
  29. package/dist/{LoginModal-CybbOm3N.js → LoginModal-CI0ogC2-.js} +5 -5
  30. package/dist/{LoginModal-CybbOm3N.js.map → LoginModal-CI0ogC2-.js.map} +1 -1
  31. package/dist/{MissingPackageModal-nBnExqO0.js → MissingPackageModal-CjkK_4A7.js} +5 -5
  32. package/dist/{MissingPackageModal-nBnExqO0.js.map → MissingPackageModal-CjkK_4A7.js.map} +1 -1
  33. package/dist/{OpenFileDocumentsModal-D50ZOp6U.js → OpenFileDocumentsModal-CEFijapC.js} +8 -7
  34. package/dist/{OpenFileDocumentsModal-D50ZOp6U.js.map → OpenFileDocumentsModal-CEFijapC.js.map} +1 -1
  35. package/dist/{SettingsModal-Dj6IQcRU.js → SettingsModal-iBBWf4UN.js} +17 -15
  36. package/dist/{SettingsModal-Dj6IQcRU.js.map → SettingsModal-iBBWf4UN.js.map} +1 -1
  37. package/dist/{UpgradeDriveModal-_8t9slxQ.js → UpgradeDriveModal-CXX6D5Au.js} +4 -4
  38. package/dist/{UpgradeDriveModal-_8t9slxQ.js.map → UpgradeDriveModal-CXX6D5Au.js.map} +1 -1
  39. package/dist/{app-loader-CKTEeFBT.js → app-loader-BXd5hsez.js} +1160 -1121
  40. package/dist/app-loader-BXd5hsez.js.map +1 -0
  41. package/dist/app-loader-D_p85Yp8.js +4 -0
  42. package/dist/app-skeleton--Me5zlSz.js +112 -0
  43. package/dist/app-skeleton--Me5zlSz.js.map +1 -0
  44. package/dist/app-skeleton-CBN4tenZ.js +4 -0
  45. package/dist/boot-DPNEOI2A.js +210 -0
  46. package/dist/boot-DPNEOI2A.js.map +1 -0
  47. package/dist/buffer-DNTcuap_.js +66 -0
  48. package/dist/buffer-DNTcuap_.js.map +1 -0
  49. package/dist/{build-info-N9NcY_pl.js → build-info-C7dDerrM.js} +5 -5
  50. package/dist/{build-info-N9NcY_pl.js.map → build-info-C7dDerrM.js.map} +1 -1
  51. package/dist/components-CRXekmxS.js +5 -0
  52. package/dist/{connect.config-DaHDEUrw.js → connect.config-CaXMoB42.js} +24 -12
  53. package/dist/connect.config-CaXMoB42.js.map +1 -0
  54. package/dist/{connection-state-3w4liC1X.js → connection-state-Eqc2izmt.js} +6 -6
  55. package/dist/{connection-state-3w4liC1X.js.map → connection-state-Eqc2izmt.js.map} +1 -1
  56. package/dist/{cookie-banner-BH6bIq24.js → cookie-banner-BxXvPdIY.js} +6 -6
  57. package/dist/{cookie-banner-BH6bIq24.js.map → cookie-banner-BxXvPdIY.js.map} +1 -1
  58. package/dist/{i18n-CWO0vYVd.js → i18n-CTgT1HG-.js} +3 -3
  59. package/dist/{i18n-CWO0vYVd.js.map → i18n-CTgT1HG-.js.map} +1 -1
  60. package/dist/{load-BcbPl8PK.js → load--VQTmlAi.js} +13 -11
  61. package/dist/{load-BcbPl8PK.js.map → load--VQTmlAi.js.map} +1 -1
  62. package/dist/main.d.ts +2 -1
  63. package/dist/main.js +8 -8
  64. package/dist/main.js.map +1 -1
  65. package/dist/package-manager-BbzIV9aN.js +485 -0
  66. package/dist/package-manager-BbzIV9aN.js.map +1 -0
  67. package/dist/{pglite-major-B39aOEiE.js → pglite-major-p4_YefAE.js} +23 -5
  68. package/dist/pglite-major-p4_YefAE.js.map +1 -0
  69. package/dist/{pglite-migrate-core-Boxqqx-c.js → pglite-migrate-core-BcXcImng.js} +8 -6
  70. package/dist/{pglite-migrate-core-Boxqqx-c.js.map → pglite-migrate-core-BcXcImng.js.map} +1 -1
  71. package/dist/{pglite-seed-BqAUvNFw.js → pglite-seed-Cl2d-iyl.js} +4 -4
  72. package/dist/{pglite-seed-BqAUvNFw.js.map → pglite-seed-Cl2d-iyl.js.map} +1 -1
  73. package/dist/pglite.worker.d.ts +2 -1
  74. package/dist/pglite.worker.js +4 -3
  75. package/dist/pglite.worker.js.map +1 -1
  76. package/dist/pglite.worker.legacy.d.ts +2 -1
  77. package/dist/pglite.worker.legacy.js +4 -3
  78. package/dist/pglite.worker.legacy.js.map +1 -1
  79. package/dist/{preferences-store-_5Cw4_YV.js → preferences-store-DZUIAkHE.js} +6 -25
  80. package/dist/preferences-store-DZUIAkHE.js.map +1 -0
  81. package/dist/{pwa-manifest-link-DIgOSo2Q.js → pwa-manifest-link-DQRJpF0r.js} +3 -3
  82. package/dist/{pwa-manifest-link-DIgOSo2Q.js.map → pwa-manifest-link-DQRJpF0r.js.map} +1 -1
  83. package/dist/{reactor-C8xEzPA1.js → reactor-DnUFDbsP.js} +93 -451
  84. package/dist/reactor-DnUFDbsP.js.map +1 -0
  85. package/dist/reactor.worker.d.ts +2 -1
  86. package/dist/reactor.worker.js +76 -21
  87. package/dist/reactor.worker.js.map +1 -1
  88. package/dist/{registerServiceWorker-BSzbNfvz.js → registerServiceWorker-smkROQhm.js} +5 -5
  89. package/dist/{registerServiceWorker-BSzbNfvz.js.map → registerServiceWorker-smkROQhm.js.map} +1 -1
  90. package/dist/renown-trust-DRgHpxlZ.js +34 -0
  91. package/dist/renown-trust-DRgHpxlZ.js.map +1 -0
  92. package/dist/{runtime-config-DL3QjcfM.js → runtime-config-DtJIUgYw.js} +3 -3
  93. package/dist/{runtime-config-DL3QjcfM.js.map → runtime-config-DtJIUgYw.js.map} +1 -1
  94. package/dist/{sentry-QXKgQmr2.js → sentry-jfDyrxdX.js} +3 -3
  95. package/dist/{sentry-QXKgQmr2.js.map → sentry-jfDyrxdX.js.map} +1 -1
  96. package/dist/start-connect.d.ts +4 -5
  97. package/dist/start-connect.d.ts.map +1 -1
  98. package/dist/start-connect.js +6 -8
  99. package/dist/start-connect.js.map +1 -1
  100. package/dist/style.css +2907 -1
  101. package/dist/{toast-BXIGd4Eb.js → toast-C6WW-_O-.js} +3 -3
  102. package/dist/{toast-BXIGd4Eb.js.map → toast-C6WW-_O-.js.map} +1 -1
  103. package/dist/{use-renown-login-Cf3va6u_.js → use-renown-login-BzOSQETV.js} +3 -3
  104. package/dist/{use-renown-login-Cf3va6u_.js.map → use-renown-login-BzOSQETV.js.map} +1 -1
  105. package/dist/useIsEmbedded-BWJ0qb7w.js +26 -0
  106. package/dist/useIsEmbedded-BWJ0qb7w.js.map +1 -0
  107. package/dist/{useRegistryPackages-BnUcL_nZ.js → useRegistryPackages-Bruz_77X.js} +75 -13
  108. package/dist/useRegistryPackages-Bruz_77X.js.map +1 -0
  109. package/package.json +19 -19
  110. package/style.css +7 -5
  111. package/dist/InspectorModal-DoEQVQYq.js.map +0 -1
  112. package/dist/app-loader-B2GI39lp.js +0 -4
  113. package/dist/app-loader-CKTEeFBT.js.map +0 -1
  114. package/dist/components-CkldoWSk.js +0 -4
  115. package/dist/connect.config-DaHDEUrw.js.map +0 -1
  116. package/dist/pglite-major-B39aOEiE.js.map +0 -1
  117. package/dist/preferences-store-_5Cw4_YV.js.map +0 -1
  118. package/dist/reactor-C8xEzPA1.js.map +0 -1
  119. package/dist/useRegistryPackages-BnUcL_nZ.js.map +0 -1
@@ -1,12 +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]="015b58c8-52fc-5eb6-9dd7-125ad20b267b")}catch(e){}}();
3
- import { r as loadRuntimeConfig, t as applyConnectBranding } from "./runtime-config-DL3QjcfM.js";
4
- import { t as getBuildHash } from "./build-info-N9NcY_pl.js";
5
- import { r as connectConfig } from "./connect.config-DaHDEUrw.js";
6
- import { n as createReactor } from "./reactor-C8xEzPA1.js";
7
- import { a as detectReactorPgMajor, i as detectMigrationMajor } from "./connection-state-3w4liC1X.js";
8
- import { n as seedPendingPgVersion } from "./pglite-seed-BqAUvNFw.js";
9
- import { n as setUser } from "./sentry-QXKgQmr2.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]="facbb6be-069b-59d0-9454-e6681f1ac443")}catch(e){}}();
3
+ import { r as loadRuntimeConfig, t as applyConnectBranding } from "./runtime-config-DtJIUgYw.js";
4
+ import "./i18n-CTgT1HG-.js";
5
+ import { r as connectConfig } from "./connect.config-CaXMoB42.js";
6
+ import { n as setUser } from "./sentry-jfDyrxdX.js";
7
+ import { t as getBuildHash } from "./build-info-C7dDerrM.js";
8
+ import { a as detectReactorPgMajor, i as detectMigrationMajor } from "./connection-state-Eqc2izmt.js";
9
+ import { n as seedPendingPgVersion } from "./pglite-seed-Cl2d-iyl.js";
10
+ import { n as createReactor } from "./reactor-DnUFDbsP.js";
10
11
  import { useEffect } from "react";
11
12
  import { initTheme, useUser } from "@powerhousedao/reactor-browser";
12
13
  import { logger } from "document-model";
@@ -115,7 +116,8 @@ function useSetSentryUser() {
115
116
  async function loadComponent(localPackage) {
116
117
  await seedPendingPgVersion();
117
118
  await Promise.all([detectReactorPgMajor(), detectMigrationMajor()]);
118
- applyConnectBranding(await loadRuntimeConfig());
119
+ const runtimeConfig = await loadRuntimeConfig();
120
+ applyConnectBranding(runtimeConfig);
119
121
  await createReactor(localPackage);
120
122
  return { default: ({ children }) => {
121
123
  initTheme();
@@ -127,5 +129,5 @@ async function loadComponent(localPackage) {
127
129
  //#endregion
128
130
  export { loadComponent };
129
131
 
130
- //# sourceMappingURL=load-BcbPl8PK.js.map
131
- //# debugId=015b58c8-52fc-5eb6-9dd7-125ad20b267b
132
+ //# sourceMappingURL=load--VQTmlAi.js.map
133
+ //# debugId=facbb6be-069b-59d0-9454-e6681f1ac443
@@ -1 +1 @@
1
- {"version":3,"file":"load-BcbPl8PK.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;AAC/C,KAAI;AACF,MAAI,EAAE,YAAY,QAAS;EAC3B,MAAM,OAAO,MAAM,OAAO,OAAO,MAAM;AACvC,QAAM,QAAQ,IACZ,KACG,QAAQ,QAAQ,IAAI,SAAS,WAAW,IAAI,IAAI,SAAS,WAAW,CAAC,CACrE,KAAK,QAAQ,OAAO,OAAO,OAAO,IAAI,CAAC,CAC3C;UACM,OAAO;AACd,SAAO,KACL,4DACA,MACD;;;;;;;;;;;;AAaL,MAAa,8BAA8B;AACzC,iBAAgB;AACd,MACE,OAAO,KAAK,IAAI,SAAS,iBACzB,cAAc,cACd,CAAC,cAAc,gBAEf;EAGF,MAAM,iBAAiB,YAAY;GACjC,MAAM,SAAS,MAAM,oBAAoB;AACzC,OAAI,CAAC,UAAU,OAAO,UAAW;AAGjC,OADoB,OAAO,eAAe,QAAQ,iBAAiB,KAC/C,OAAO,aAAc;AACzC,UAAO,eAAe,QAAQ,kBAAkB,OAAO,aAAa;AAEpE,UAAO,KACL,4EACA,OAAO,aACP,OAAO,aACR;AACD,SAAM,kBAAkB;AACxB,UAAO,SAAS,QAAQ;;AAGrB,kBAAgB;EACrB,MAAM,2BAA2B;AAC/B,OAAI,SAAS,oBAAoB,UAAgB,iBAAgB;;AAEnE,WAAS,iBAAiB,oBAAoB,mBAAmB;AACjE,eAAa;AACX,YAAS,oBAAoB,oBAAoB,mBAAmB;;IAErE,EAAE,CAAC;;AC7Ea,OAAO,UAAU,WAAW,SAAS,MAAM;;;;;;;;;;;;;;;;AA0BhE,MAAa,qBAAqB,YAA6C;CAC7E,MAAM,cAAc,cAAc;AAClC,KAAI,CAAC,eAAe,gBAAgB,UAAW,QAAO;AACtD,KAAI;EACF,MAAM,SAAS,MAAM,MAAM,GAAG,OAAO,KAAK,IAAI,SAAS,kBAAkB,EACvE,OAAO,YACR,CAAC;AACF,MAAI,CAAC,OAAO,GAAI,QAAO;EACvB,MAAM,OAAQ,MAAM,OAAO,MAAM;AACjC,MAAI,OAAO,KAAK,SAAS,YAAY,CAAC,KAAK,KAAM,QAAO;AACxD,SAAO;GACL;GACA,cAAc,KAAK;GACnB,WAAW,KAAK,SAAS;GAC1B;SACK;AACN,SAAO;;;;;ACvCX,SAAgB,mBAAmB;CACjC,MAAM,OAAO,SAAS;AACtB,iBAAgB;EACd,IAAI,aAAgC;AACpC,MAAI,MAAM;GAER,MAAM,EAAE,YAAY,aAAa,GAAG,SAAS;AAC7C,gBAAa;IAAE,IAAI,KAAK;IAAK,UAAU,KAAK,KAAK;IAAM,GAAG;IAAM;;AAElE,UAAc,WAAW;IACxB,CAAC,KAAK,CAAC;;;;ACFZ,eAAsB,cAAc,cAAiC;AACnE,OAAM,sBAAsB;AAC5B,OAAM,QAAQ,IAAI,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,CAAC;AAEnE,sBADsB,MAAM,mBAAmB,CACZ;AACnC,OAAM,cAAc,aAAa;AACjC,QAAO,EACL,UAAU,EAAE,eAAyC;AACnD,aAAW;AAEX,oBAAkB;AAElB,yBAAuB;AACvB,SAAO;IAEV","debug_id":"015b58c8-52fc-5eb6-9dd7-125ad20b267b"}
1
+ {"version":3,"file":"load--VQTmlAi.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":"facbb6be-069b-59d0-9454-e6681f1ac443"}
package/dist/main.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { };
1
+ export {}
2
+ export {};
package/dist/main.js CHANGED
@@ -1,14 +1,14 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3c7b261e-f73c-509e-b758-8cb48bb6f3fd")}catch(e){}}();
3
- import { r as loadRuntimeConfig } from "./runtime-config-DL3QjcfM.js";
4
- import { createRoot } from "react-dom/client";
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]="1f52a123-ef3c-5452-bdfa-b05d09bb17c0")}catch(e){}}();
3
+ import { t as bootConnect } from "./boot-DPNEOI2A.js";
5
4
  import { jsx } from "react/jsx-runtime";
6
5
  //#region main.tsx
7
- if (!window.ph) window.ph = {};
8
- await loadRuntimeConfig();
9
- const { AppLoader } = await import("./app-loader-B2GI39lp.js");
10
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ jsx(AppLoader, {}));
6
+ const root = await bootConnect();
7
+ if (root) {
8
+ const { AppLoader } = await import("./app-loader-D_p85Yp8.js");
9
+ root.render(/* @__PURE__ */ jsx(AppLoader, {}));
10
+ }
11
11
  //#endregion
12
12
 
13
13
  //# sourceMappingURL=main.js.map
14
- //# debugId=3c7b261e-f73c-509e-b758-8cb48bb6f3fd
14
+ //# debugId=1f52a123-ef3c-5452-bdfa-b05d09bb17c0
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../main.tsx"],"sourcesContent":["import { createRoot } from \"react-dom/client\";\nimport { loadRuntimeConfig } from \"./src/runtime-config.js\";\n\nif (!window.ph) {\n window.ph = {};\n}\n\n// Bootstrap the runtime config BEFORE AppLoader's transitive imports\nawait loadRuntimeConfig();\nconst { AppLoader } = await import(\"./src/components/app-loader.js\");\n\ncreateRoot(document.getElementById(\"root\")!).render(<AppLoader />);\n"],"names":[],"mappings":";;;;;;AAGA,IAAI,CAAC,OAAO,GACV,QAAO,KAAK,EAAE;AAIhB,MAAM,mBAAmB;AACzB,MAAM,EAAE,cAAc,MAAM,OAAO;AAEnC,WAAW,SAAS,eAAe,OAAO,CAAE,CAAC,OAAO,oBAAC,WAAD,EAAa,CAAA,CAAC","debug_id":"3c7b261e-f73c-509e-b758-8cb48bb6f3fd"}
1
+ {"version":3,"file":"main.js","sources":["../main.tsx"],"sourcesContent":["import { bootConnect } from \"./src/boot.js\";\n\n// Paint the config-independent skeleton, start the runtime config fetch\n// alongside it, and wait for the config. See src/boot.tsx for why the two\n// overlap and what a failure renders.\nconst root = await bootConnect();\n\n// `null` means startup failed and the error state is already painted. The app\n// graph must not be imported then: its modules read the runtime config at\n// module-evaluation and would throw.\nif (root) {\n const { AppLoader } = await import(\"./src/components/app-loader.js\");\n root.render(<AppLoader />);\n}\n"],"names":[],"mappings":";;;;;AAKA,MAAM,OAAO,MAAM,YAAY;AAK/B,IAAI,MAAM;CACR,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,KAAK,OAAO,oBAAC,WAAD,CAAY,CAAA,CAAC;AAC3B","debug_id":"1f52a123-ef3c-5452-bdfa-b05d09bb17c0"}
@@ -0,0 +1,485 @@
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]="9177dffe-876f-5372-b971-22d253b5334e")}catch(e){}}();
3
+ import { t as refreshPwaManifestLink } from "./pwa-manifest-link-DQRJpF0r.js";
4
+ import { DYNAMIC_BASE_PLACEHOLDER, PWA_IDB_KEY, PWA_IDB_NAME, PWA_IDB_STORE, PWA_IDB_VERSION, checkSharedDeps, formatSharedDepWarnings, mergePwaConfig, withInferredCategory } from "@powerhousedao/shared/connect";
5
+ import { BrowserLocalStorage } from "@powerhousedao/reactor-browser";
6
+ import { toCdnUrl } from "@powerhousedao/shared/registry/urls";
7
+ import * as common from "@powerhousedao/powerhouse-vetra-packages";
8
+ import commonPkg from "@powerhousedao/powerhouse-vetra-packages/package.json" with { type: "json" };
9
+ import { PwaConfigSchema } from "@powerhousedao/shared/document-model";
10
+ import vetraPkg from "@powerhousedao/vetra/package.json" with { type: "json" };
11
+ import workflowPkg from "@powerhousedao/workflow/package.json" with { type: "json" };
12
+ //#region src/shared-deps.ts
13
+ /**
14
+ * Resolve the vendor's import-map values to absolute URLs: the
15
+ * dynamic-base placeholder (present in dynamic-base builds) is replaced
16
+ * with the runtime base — which `import.meta.env.BASE_URL` already is,
17
+ * since the dynamic-base plugin rewrites it to the resolved base — and
18
+ * the result is made absolute against the page origin. Absolute URLs are
19
+ * what the worker needs: its imports have no document context, so
20
+ * relative or placeholder-based values would not resolve there.
21
+ */
22
+ function normalizeVendorImports(rawImports, runtimeBase) {
23
+ const origin = globalThis.location?.origin ?? "http://localhost";
24
+ return Object.fromEntries(Object.entries(rawImports).map(([spec, value]) => [spec, new URL(value.replace(DYNAMIC_BASE_PLACEHOLDER, runtimeBase), origin).href]));
25
+ }
26
+ let cached = null;
27
+ /**
28
+ * The production vendor's shared-deps table: import-map entries for the
29
+ * shared dependency set plus the resolved version of every shared package
30
+ * in this build. Fails soft (`null`) when the vendor is not present (dev,
31
+ * or a `PH_CONNECT_VENDOR=0` build) — callers treat that as "no sharing".
32
+ * The promise is cached: the vendor table is immutable per build.
33
+ */
34
+ function getSharedDeps() {
35
+ cached ??= (async () => {
36
+ try {
37
+ const mod = await import(
38
+ /* @vite-ignore */
39
+ `${import.meta.env.BASE_URL}__vendor__/shared-deps.js`
40
+ );
41
+ return {
42
+ imports: normalizeVendorImports(mod.imports, import.meta.env.BASE_URL),
43
+ versions: mod.versions
44
+ };
45
+ } catch {
46
+ return null;
47
+ }
48
+ })();
49
+ return cached;
50
+ }
51
+ //#endregion
52
+ //#region src/utils/pwa-idb.ts
53
+ function openPwaIdb() {
54
+ return new Promise((resolve, reject) => {
55
+ const req = indexedDB.open(PWA_IDB_NAME, PWA_IDB_VERSION);
56
+ req.onupgradeneeded = () => {
57
+ if (!req.result.objectStoreNames.contains(PWA_IDB_STORE)) req.result.createObjectStore(PWA_IDB_STORE);
58
+ };
59
+ req.onerror = () => reject(req.error ?? /* @__PURE__ */ new Error("ph-pwa open failed"));
60
+ req.onblocked = () => reject(/* @__PURE__ */ new Error("ph-pwa open blocked"));
61
+ req.onsuccess = () => resolve(req.result);
62
+ });
63
+ }
64
+ /** Write (replace) the single merged fragment record. Best-effort: a failure to
65
+ * mirror the manifest must never break package installation, so callers ignore
66
+ * rejections. No-op when IndexedDB is unavailable (SSR/tests). */
67
+ async function writeMergedPwaFragment(fragment) {
68
+ if (typeof indexedDB === "undefined") return;
69
+ const db = await openPwaIdb();
70
+ try {
71
+ await new Promise((resolve, reject) => {
72
+ const tx = db.transaction(PWA_IDB_STORE, "readwrite");
73
+ tx.oncomplete = () => resolve();
74
+ tx.onerror = () => reject(tx.error ?? /* @__PURE__ */ new Error("PWA fragment write failed"));
75
+ tx.objectStore(PWA_IDB_STORE).put({
76
+ version: 1,
77
+ fragment,
78
+ updatedAt: Date.now()
79
+ }, PWA_IDB_KEY);
80
+ });
81
+ } finally {
82
+ db.close();
83
+ }
84
+ }
85
+ /** Resolve `src` against the package `baseUrl`, absolute srcs passing through.
86
+ * `baseUrl` may itself be relative (e.g. a same-origin-proxied registry, or the
87
+ * dev `/node_modules/…` path), so it is first made absolute against the app
88
+ * origin — `new URL(src, relativeBase)` would otherwise throw and silently
89
+ * leave the src unresolved. A malformed src is left untouched. */
90
+ function toAbsoluteAssetUrl(src, baseUrl) {
91
+ try {
92
+ const origin = typeof location !== "undefined" ? location.href : "http://localhost/";
93
+ return new URL(src, new URL(baseUrl, origin)).toString();
94
+ } catch {
95
+ return src;
96
+ }
97
+ }
98
+ function resolveIconSrc(icon, baseUrl) {
99
+ return {
100
+ ...icon,
101
+ src: toAbsoluteAssetUrl(icon.src, baseUrl)
102
+ };
103
+ }
104
+ /**
105
+ * Rewrite a package fragment's relative asset srcs (manifest icons and
106
+ * file-handler icons) to absolute URLs against the package's base — a runtime
107
+ * package's assets live on the registry CDN, not the app origin, so the served
108
+ * manifest must point there. `baseUrl` null (a local/bundled package whose
109
+ * assets are app-origin-relative) leaves srcs untouched.
110
+ */
111
+ function resolveFragmentAssetUrls(config, baseUrl) {
112
+ if (!baseUrl || !config.manifest) return config;
113
+ const m = config.manifest;
114
+ const resolveIcons = (icons) => icons?.map((icon) => resolveIconSrc(icon, baseUrl));
115
+ return {
116
+ ...config,
117
+ manifest: {
118
+ ...m,
119
+ icons: resolveIcons(m.icons),
120
+ file_handlers: m.file_handlers?.map((handler) => ({
121
+ ...handler,
122
+ icons: resolveIcons(handler.icons)
123
+ }))
124
+ }
125
+ };
126
+ }
127
+ //#endregion
128
+ //#region src/package-manager.ts
129
+ /**
130
+ * Strip any `@tag` / `@version` suffix from a package spec, returning the bare
131
+ * package name. Mirrors `parsePackageSpec` on the UI side.
132
+ */
133
+ function parseBareName(spec) {
134
+ const trimmed = spec.trim();
135
+ const at = trimmed.startsWith("@") ? trimmed.lastIndexOf("@") : trimmed.indexOf("@");
136
+ return at > 0 ? trimmed.slice(0, at) : trimmed;
137
+ }
138
+ async function fetchPackageJson(baseUrl) {
139
+ try {
140
+ const res = await fetch(baseUrl);
141
+ if (!res.ok) return null;
142
+ const pkg = await res.json();
143
+ return {
144
+ version: typeof pkg.version === "string" ? pkg.version : void 0,
145
+ dependencies: pkg.dependencies,
146
+ peerDependencies: pkg.peerDependencies
147
+ };
148
+ } catch {
149
+ return null;
150
+ }
151
+ }
152
+ async function fetchPackageJsonVersion(baseUrl) {
153
+ return (await fetchPackageJson(baseUrl))?.version;
154
+ }
155
+ /**
156
+ * Human-readable warnings for shared-dep mismatches between a package's npm
157
+ * `package.json` (as served by the CDN) and the host's shared-deps version
158
+ * table. Empty when either side is unavailable — a dev / vendor-off host has
159
+ * no table to compare against, and a missing package.json means the check
160
+ * can't run. Used by both the install flow and the package-manager UI.
161
+ */
162
+ function sharedDepMismatchWarnings(pkgJson, hostVersions) {
163
+ if (!pkgJson || !hostVersions) return [];
164
+ return formatSharedDepWarnings(checkSharedDeps(pkgJson, hostVersions));
165
+ }
166
+ const LOCAL_PACKAGE_NAME = "Local";
167
+ const LAYER_ORDER = "@layer theme, base, components, external-packages, utilities;";
168
+ const LAYER_ORDER_ATTR = "data-ph-layer-order";
169
+ function declareExternalPackagesLayer() {
170
+ if (document.head.querySelector(`style[${LAYER_ORDER_ATTR}]`)) return;
171
+ const order = document.createElement("style");
172
+ order.setAttribute(LAYER_ORDER_ATTR, "");
173
+ order.textContent = LAYER_ORDER;
174
+ document.head.prepend(order);
175
+ }
176
+ var BrowserPackageManager = class {
177
+ registryUrl;
178
+ #storage;
179
+ #packages = /* @__PURE__ */ new Map();
180
+ #subscribers = /* @__PURE__ */ new Set();
181
+ #packagesMemo = [];
182
+ #stylesheets = /* @__PURE__ */ new Map();
183
+ #localPackage;
184
+ #cdnUrl;
185
+ #localPackageVersion;
186
+ #localPackageNames = /* @__PURE__ */ new Set([LOCAL_PACKAGE_NAME]);
187
+ #pwaSyncTimer;
188
+ /** Serialized last-mirrored PWA fragment; lets a sync skip the IndexedDB
189
+ * write + manifest re-attach when nothing PWA-relevant changed. */
190
+ #lastSyncedFragmentJson;
191
+ constructor(namespace, registryUrl) {
192
+ this.#storage = new BrowserLocalStorage(namespace + ":PH_PACKAGES");
193
+ this.registryUrl = registryUrl;
194
+ this.#cdnUrl = registryUrl !== null ? toCdnUrl(registryUrl) : null;
195
+ }
196
+ async init(localPackage, localPackageVersion, studioMode, workflowsEnabled) {
197
+ this.addLocalPackage(common.manifest.name, common, commonPkg.version);
198
+ if (studioMode) {
199
+ const vetra = await import("@powerhousedao/vetra");
200
+ this.addLocalPackage(vetra.manifest.name, vetra, vetraPkg.version);
201
+ }
202
+ if (workflowsEnabled) {
203
+ const workflow = await import("@powerhousedao/workflow");
204
+ this.addLocalPackage(workflow.manifest.name, workflow, workflowPkg.version);
205
+ }
206
+ if (localPackage) this.updateLocalPackage(localPackage, localPackageVersion);
207
+ for (const packageName of this.#storage.keys()) {
208
+ const specForReload = this.#storage.get(packageName)?.spec ?? packageName;
209
+ console.debug(`[Connect][PackageManager] Rehydrating "${packageName}" via spec "${specForReload}"`);
210
+ if ((await this.addPackage(specForReload)).type === "error") this.#storage.delete(packageName);
211
+ }
212
+ }
213
+ addLocalPackage(name, loadedPackage, version) {
214
+ this.#localPackageNames.add(name);
215
+ this.#registerPackage({
216
+ name,
217
+ importUrl: null,
218
+ stylesheetUrl: null,
219
+ loadedPackage,
220
+ version
221
+ });
222
+ }
223
+ updateLocalPackage(pkg, version) {
224
+ console.debug("Updating local package:", pkg);
225
+ this.#localPackage = pkg;
226
+ this.#registerPackage({
227
+ name: LOCAL_PACKAGE_NAME,
228
+ stylesheetUrl: null,
229
+ importUrl: null,
230
+ loadedPackage: pkg
231
+ });
232
+ if (version) {
233
+ this.#localPackageVersion = version;
234
+ this.#notifyPackagesChanged();
235
+ return;
236
+ }
237
+ fetchPackageJsonVersion("/package.json").then((fetchedVersion) => {
238
+ this.#localPackageVersion = fetchedVersion;
239
+ if (fetchedVersion) this.#notifyPackagesChanged();
240
+ }).catch(() => {});
241
+ }
242
+ get packages() {
243
+ return this.#packagesMemo;
244
+ }
245
+ get cdnUrl() {
246
+ return this.#cdnUrl;
247
+ }
248
+ getPackageSource(packageName) {
249
+ if (this.#localPackageNames.has(packageName)) return "common";
250
+ if (packageName === this.#localPackage?.manifest.name) return "project";
251
+ const packageMeta = this.#storage.get(packageName);
252
+ if (!packageMeta) return null;
253
+ if (packageMeta.importUrl === `/node_modules/${packageName}`) return "local-install";
254
+ return "registry-install";
255
+ }
256
+ /**
257
+ * Return the registry-installed packages keyed by their storage name (which
258
+ * is the registry spec, e.g. "@powerhousedao/clint-common"), with the
259
+ * installed version when known. Excludes bundled (common) packages, the
260
+ * local project package, and packages resolved out of `/node_modules/`.
261
+ */
262
+ getRegistryPackages() {
263
+ const out = [];
264
+ for (const [name, meta] of this.#storage) {
265
+ if (this.#localPackageNames.has(name)) continue;
266
+ if (name === LOCAL_PACKAGE_NAME) continue;
267
+ if (meta.importUrl === `/node_modules/${name}`) continue;
268
+ out.push({
269
+ name,
270
+ version: meta.version
271
+ });
272
+ }
273
+ return out;
274
+ }
275
+ getPackageVersion(packageName) {
276
+ if (packageName === this.#localPackage?.manifest.name) return this.#localPackageVersion;
277
+ return this.#storage.get(packageName)?.version;
278
+ }
279
+ /**
280
+ * The spec the user requested when this package was installed (e.g.
281
+ * `name@dev` or `name@6.2.1`). Undefined for bare-name installs, legacy
282
+ * entries, and local packages — the Package Manager treats that as the
283
+ * `latest` stream when picking update targets.
284
+ */
285
+ getPackageSpec(packageName) {
286
+ return this.#storage.get(packageName)?.spec;
287
+ }
288
+ async addPackage(packageSpec) {
289
+ const bareName = parseBareName(packageSpec);
290
+ const hasTagOrVersion = bareName !== packageSpec;
291
+ console.debug(`[Connect][PackageManager] addPackage spec="${packageSpec}" bareName="${bareName}"`);
292
+ const existingPackage = this.#packages.get(bareName);
293
+ if (existingPackage) {
294
+ const requestedVersion = hasTagOrVersion ? packageSpec.slice(bareName.length + 1) : void 0;
295
+ const currentVersion = this.#storage.get(bareName)?.version;
296
+ if (this.#localPackageNames.has(bareName) || !requestedVersion || !currentVersion || requestedVersion === currentVersion) {
297
+ console.debug(`[Connect][PackageManager] "${bareName}" already loaded; skipping re-fetch`);
298
+ return {
299
+ type: "success",
300
+ package: existingPackage
301
+ };
302
+ }
303
+ console.debug(`[Connect][PackageManager] "${bareName}" version bump ${currentVersion} → ${requestedVersion}; refetching`);
304
+ }
305
+ try {
306
+ const packageWithMeta = await this.#loadPackage(packageSpec);
307
+ packageWithMeta.name = bareName;
308
+ if (hasTagOrVersion) packageWithMeta.spec = packageSpec;
309
+ if (existingPackage) this.#unmountStylesheet(bareName);
310
+ this.#registerPackage(packageWithMeta);
311
+ return {
312
+ type: "success",
313
+ package: packageWithMeta.loadedPackage
314
+ };
315
+ } catch (error) {
316
+ const normalized = error instanceof Error ? error : new Error(String(error));
317
+ console.error(`[Connect][PackageManager] Failed to install package "${packageSpec}": ${normalized.message}`, normalized);
318
+ return {
319
+ type: "error",
320
+ error: normalized
321
+ };
322
+ }
323
+ }
324
+ async addPackages(packageNames) {
325
+ const results = [];
326
+ for (const packageName of packageNames) {
327
+ const result = await this.addPackage(packageName);
328
+ results.push(result);
329
+ }
330
+ return results;
331
+ }
332
+ removePackage(name) {
333
+ this.#packages.delete(name);
334
+ this.#storage.delete(name);
335
+ this.#unmountStylesheet(name);
336
+ this.#notifyPackagesChanged();
337
+ }
338
+ subscribe(handler) {
339
+ this.#subscribers.add(handler);
340
+ return () => {
341
+ this.#subscribers.delete(handler);
342
+ };
343
+ }
344
+ load(documentType) {
345
+ const documentModelModule = Array.from(this.#packages.values().flatMap((p) => p.documentModels)).find((m) => m.documentModel.global.id === documentType);
346
+ if (documentModelModule) return Promise.resolve(documentModelModule);
347
+ return Promise.reject(/* @__PURE__ */ new Error("Model not available"));
348
+ }
349
+ async #loadPackageFromNodeModules(name) {
350
+ const importUrl = `/node_modules/${name}/browser/index.js`;
351
+ const stylesheetUrl = `/node_modules/${name}/style.css`;
352
+ const packageWithMeta = await this.#importPackage({
353
+ name,
354
+ importUrl,
355
+ stylesheetUrl
356
+ });
357
+ packageWithMeta.version = await fetchPackageJsonVersion(`/node_modules/${name}/package.json`);
358
+ return packageWithMeta;
359
+ }
360
+ async #loadPackageFromRegistry(name) {
361
+ const importUrl = `${this.#cdnUrl}/${name}/browser/index.js`;
362
+ const stylesheetUrl = `${this.#cdnUrl}/${name}/style.css`;
363
+ const packageWithMeta = await this.#importPackage({
364
+ name,
365
+ importUrl,
366
+ stylesheetUrl
367
+ });
368
+ const pkgJson = await fetchPackageJson(`${this.#cdnUrl}/${name}/package.json`);
369
+ packageWithMeta.version = pkgJson?.version;
370
+ const warnings = sharedDepMismatchWarnings(pkgJson, (await getSharedDeps())?.versions);
371
+ if (warnings.length > 0) console.error(`[package-manager] shared-deps mismatch for ${name}:\n` + warnings.join("\n"));
372
+ return packageWithMeta;
373
+ }
374
+ async #importPackage(packageMeta) {
375
+ const { name, importUrl, stylesheetUrl } = packageMeta;
376
+ if (!importUrl) throw new Error(`Import url not defined for package "${name}".`);
377
+ return {
378
+ name,
379
+ loadedPackage: await import(
380
+ /* @vite-ignore */
381
+ importUrl
382
+ ),
383
+ importUrl,
384
+ stylesheetUrl
385
+ };
386
+ }
387
+ async #loadPackage(packageName) {
388
+ if (this.#localPackageNames.has(packageName)) throw new Error(`Package "${packageName}" is a local package and cannot be loaded dynamically.`);
389
+ if (!import.meta.env.PROD) try {
390
+ return await this.#loadPackageFromNodeModules(packageName);
391
+ } catch (error) {
392
+ console.warn(`Failed to load package "${packageName}" from node_modules:`, error);
393
+ }
394
+ if (!this.registryUrl) throw new Error("Registry url not defined.");
395
+ return await this.#loadPackageFromRegistry(packageName);
396
+ }
397
+ #registerPackage(packageWithMeta) {
398
+ const { name, loadedPackage, importUrl, stylesheetUrl, version, spec } = packageWithMeta;
399
+ if (stylesheetUrl !== null) this.#mountStylesheet(name, stylesheetUrl);
400
+ this.#packages.set(name, loadedPackage);
401
+ this.#storage.set(name, {
402
+ name,
403
+ importUrl,
404
+ stylesheetUrl,
405
+ version,
406
+ ...spec ? { spec } : {}
407
+ });
408
+ console.debug(`[Connect][PackageManager] Registered "${name}" (version=${version ?? "?"}, spec=${spec ?? "—"})`);
409
+ this.#notifyPackagesChanged();
410
+ }
411
+ #mountStylesheet(name, href) {
412
+ const existing = this.#stylesheets.get(name);
413
+ if (existing) return existing;
414
+ declareExternalPackagesLayer();
415
+ const style = document.createElement("style");
416
+ style.textContent = `@import url("${href}") layer(external-packages);`;
417
+ document.head.appendChild(style);
418
+ this.#stylesheets.set(name, style);
419
+ }
420
+ #unmountStylesheet(name) {
421
+ const style = this.#stylesheets.get(name);
422
+ if (!style) return;
423
+ style.remove();
424
+ this.#stylesheets.delete(name);
425
+ }
426
+ #notifyPackagesChanged() {
427
+ this.#packagesMemo = Array.from(this.#packages.values());
428
+ const packages = this.packages;
429
+ this.#subscribers.forEach((handler) => {
430
+ handler({ packages });
431
+ });
432
+ this.#schedulePwaSync();
433
+ }
434
+ /**
435
+ * Debounced mirror of every loaded package's PWA fragment into IndexedDB, so
436
+ * the service worker can serve a web-app manifest that reflects packages
437
+ * installed AT RUNTIME (a SW can't read localStorage, where the package list
438
+ * lives). Debounced because `init()` rehydrates many packages in a burst;
439
+ * coalescing collapses that into a single write.
440
+ */
441
+ #schedulePwaSync() {
442
+ if (typeof indexedDB === "undefined") return;
443
+ clearTimeout(this.#pwaSyncTimer);
444
+ this.#pwaSyncTimer = setTimeout(() => {
445
+ this.#syncPwaFragments();
446
+ }, 50);
447
+ }
448
+ async #syncPwaFragments() {
449
+ const contributions = [];
450
+ for (const [name, loadedPackage] of this.#packages) {
451
+ const manifest = loadedPackage.manifest;
452
+ let config = {};
453
+ if (manifest.pwa) {
454
+ const parsed = PwaConfigSchema.safeParse(manifest.pwa);
455
+ if (parsed.success) {
456
+ const importUrl = this.#storage.get(name)?.importUrl ?? null;
457
+ const baseUrl = importUrl ? importUrl.replace(/browser\/index\.js$/, "") : null;
458
+ config = resolveFragmentAssetUrls(parsed.data, baseUrl);
459
+ } else console.warn(`[Connect][PWA] "${name}" ships an invalid pwa fragment; skipped.`, parsed.error);
460
+ }
461
+ config = withInferredCategory(config, manifest.category);
462
+ if (Object.keys(config).length === 0) continue;
463
+ contributions.push({
464
+ source: name,
465
+ config
466
+ });
467
+ }
468
+ const merged = mergePwaConfig(contributions);
469
+ const mergedJson = JSON.stringify(merged);
470
+ if (mergedJson === this.#lastSyncedFragmentJson) return;
471
+ try {
472
+ await writeMergedPwaFragment(merged);
473
+ } catch (error) {
474
+ console.debug("[Connect][PWA] fragment mirror to IndexedDB failed:", error);
475
+ return;
476
+ }
477
+ this.#lastSyncedFragmentJson = mergedJson;
478
+ refreshPwaManifestLink();
479
+ }
480
+ };
481
+ //#endregion
482
+ export { sharedDepMismatchWarnings as n, getSharedDeps as r, BrowserPackageManager as t };
483
+
484
+ //# sourceMappingURL=package-manager-BbzIV9aN.js.map
485
+ //# debugId=9177dffe-876f-5372-b971-22d253b5334e