@powerhousedao/connect 6.2.2-dev.9 → 6.2.2
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.
- package/assets/document-icon-192x192.png +0 -0
- package/assets/document-icon-512x512.png +0 -0
- package/assets/pwa-192x192.png +0 -0
- package/assets/pwa-512x512-maskable.png +0 -0
- package/assets/pwa-512x512.png +0 -0
- package/dist/{AddDriveModal-MMHlkJBJ.js → AddDriveModal-Q-Ffh5XA.js} +5 -5
- package/dist/AddDriveModal-Q-Ffh5XA.js.map +1 -0
- package/dist/{ClearStorageModal-BrqS8I-J.js → ClearStorageModal-Fmh5kOVI.js} +4 -4
- package/dist/{ClearStorageModal-BrqS8I-J.js.map → ClearStorageModal-Fmh5kOVI.js.map} +1 -1
- package/dist/ConfirmDocumentUpgradeModal-FUOhZsk7.js +114 -0
- package/dist/ConfirmDocumentUpgradeModal-FUOhZsk7.js.map +1 -0
- package/dist/{CookiesPolicyModal-CkcUKPLb.js → CookiesPolicyModal-BpyPPyxS.js} +3 -3
- package/dist/{CookiesPolicyModal-CkcUKPLb.js.map → CookiesPolicyModal-BpyPPyxS.js.map} +1 -1
- package/dist/{CreateDocumentModal-CvsTh0HM.js → CreateDocumentModal-C45W8J0V.js} +7 -5
- package/dist/CreateDocumentModal-C45W8J0V.js.map +1 -0
- package/dist/{DebugSettingsModal-CCZi5Gmx.js → DebugSettingsModal-CpGjPPjw.js} +6 -6
- package/dist/{DebugSettingsModal-CCZi5Gmx.js.map → DebugSettingsModal-CpGjPPjw.js.map} +1 -1
- package/dist/{DeleteDriveModal-DSTK8FYk.js → DeleteDriveModal-Dug84t1j.js} +4 -4
- package/dist/{DeleteDriveModal-DSTK8FYk.js.map → DeleteDriveModal-Dug84t1j.js.map} +1 -1
- package/dist/{DeleteItemModal-B2nJmjsP.js → DeleteItemModal-mMzy3V8o.js} +4 -4
- package/dist/{DeleteItemModal-B2nJmjsP.js.map → DeleteItemModal-mMzy3V8o.js.map} +1 -1
- package/dist/{DisclaimerModal-D5FO34u9.js → DisclaimerModal-DvpD5dPM.js} +3 -3
- package/dist/{DisclaimerModal-D5FO34u9.js.map → DisclaimerModal-DvpD5dPM.js.map} +1 -1
- package/dist/DocumentVersionUnsupportedModal-C3Q0V75l.js +32 -0
- package/dist/DocumentVersionUnsupportedModal-C3Q0V75l.js.map +1 -0
- package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js → DownloadDocumentWithErrorsModal-IKl0ljQb.js} +3 -3
- package/dist/{DownloadDocumentWithErrorsModal-tEr3bbtN.js.map → DownloadDocumentWithErrorsModal-IKl0ljQb.js.map} +1 -1
- package/dist/DriveAuthRequiredModal-Cw9eCAQ_.js +36 -0
- package/dist/DriveAuthRequiredModal-Cw9eCAQ_.js.map +1 -0
- package/dist/{DriveSettingsModal-kR3hQnh4.js → DriveSettingsModal-C6-mRQiv.js} +3 -3
- package/dist/{DriveSettingsModal-kR3hQnh4.js.map → DriveSettingsModal-C6-mRQiv.js.map} +1 -1
- package/dist/{InspectorModal-BfwRytsl.js → InspectorModal-CiFokzb8.js} +6 -6
- package/dist/{InspectorModal-BfwRytsl.js.map → InspectorModal-CiFokzb8.js.map} +1 -1
- package/dist/LoginModal-CybbOm3N.js +75 -0
- package/dist/LoginModal-CybbOm3N.js.map +1 -0
- package/dist/{MissingPackageModal-BQcCQbOn.js → MissingPackageModal-C7usWVHQ.js} +18 -6
- package/dist/MissingPackageModal-C7usWVHQ.js.map +1 -0
- package/dist/OpenFileDocumentsModal-TskJgkzl.js +311 -0
- package/dist/OpenFileDocumentsModal-TskJgkzl.js.map +1 -0
- package/dist/SettingsModal-Chptr_NH.js +568 -0
- package/dist/SettingsModal-Chptr_NH.js.map +1 -0
- package/dist/{UpgradeDriveModal-BZGSE9_r.js → UpgradeDriveModal-_8t9slxQ.js} +3 -3
- package/dist/{UpgradeDriveModal-BZGSE9_r.js.map → UpgradeDriveModal-_8t9slxQ.js.map} +1 -1
- package/dist/{app-loader-BqH5S4gP.js → app-loader-CoxjGoau.js} +839 -560
- package/dist/app-loader-CoxjGoau.js.map +1 -0
- package/dist/app-loader-D7RV-yqv.js +4 -0
- package/dist/build-info-D8VekPcJ.js +28 -0
- package/dist/build-info-D8VekPcJ.js.map +1 -0
- package/dist/components-qFeURFYe.js +4 -0
- package/dist/{connect.config-vgUeFoNp.js → connect.config-DaHDEUrw.js} +13 -7
- package/dist/connect.config-DaHDEUrw.js.map +1 -0
- package/dist/{connection-state-DO_2lAEJ.js → connection-state-3w4liC1X.js} +4 -4
- package/dist/{connection-state-DO_2lAEJ.js.map → connection-state-3w4liC1X.js.map} +1 -1
- package/dist/cookie-banner-BH6bIq24.js +70 -0
- package/dist/cookie-banner-BH6bIq24.js.map +1 -0
- package/dist/{reload-connect-toast-D1Iqw9E_.js → i18n-CWO0vYVd.js} +23 -30
- package/dist/i18n-CWO0vYVd.js.map +1 -0
- package/dist/load-D_BC1JxM.js +131 -0
- package/dist/load-D_BC1JxM.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/{pglite-seed-z3B1JA38.js → pglite-seed-BqAUvNFw.js} +4 -4
- package/dist/{pglite-seed-z3B1JA38.js.map → pglite-seed-BqAUvNFw.js.map} +1 -1
- package/dist/preferences-store-_5Cw4_YV.js +104 -0
- package/dist/preferences-store-_5Cw4_YV.js.map +1 -0
- package/dist/pwa-manifest-link-DIgOSo2Q.js +34 -0
- package/dist/pwa-manifest-link-DIgOSo2Q.js.map +1 -0
- package/dist/{reactor-ynguOpe7.js → reactor-DBCWJdBA.js} +240 -67
- package/dist/reactor-DBCWJdBA.js.map +1 -0
- package/dist/reactor.worker.js +11 -6
- package/dist/reactor.worker.js.map +1 -1
- package/dist/{registerServiceWorker-nJIc0yEY.js → registerServiceWorker-BSzbNfvz.js} +6 -4
- package/dist/registerServiceWorker-BSzbNfvz.js.map +1 -0
- package/dist/sentry-QXKgQmr2.js +15 -0
- package/dist/sentry-QXKgQmr2.js.map +1 -0
- package/dist/start-connect.js +1 -1
- package/dist/style.css +243 -7
- package/dist/{toast-4t-VimvD.js → toast-BXIGd4Eb.js} +8 -5
- package/dist/toast-BXIGd4Eb.js.map +1 -0
- package/dist/use-renown-login-Cf3va6u_.js +52 -0
- package/dist/use-renown-login-Cf3va6u_.js.map +1 -0
- package/dist/useRegistryPackages-DMhCvTWq.js +314 -0
- package/dist/useRegistryPackages-DMhCvTWq.js.map +1 -0
- package/package.json +19 -13
- package/public/powerhouse.config.json +3 -0
- package/style.css +1 -0
- package/dist/AddDriveModal-MMHlkJBJ.js.map +0 -1
- package/dist/CreateDocumentModal-CvsTh0HM.js.map +0 -1
- package/dist/DriveAuthRequiredModal-BA2vS3oF.js +0 -40
- package/dist/DriveAuthRequiredModal-BA2vS3oF.js.map +0 -1
- package/dist/MissingPackageModal-BQcCQbOn.js.map +0 -1
- package/dist/SettingsModal-CdoFxyJJ.js +0 -289
- package/dist/SettingsModal-CdoFxyJJ.js.map +0 -1
- package/dist/app-loader-BqH5S4gP.js.map +0 -1
- package/dist/app-loader-J8Z4QAD5.js +0 -4
- package/dist/build-info-AUWI7jOw.js +0 -18
- package/dist/build-info-AUWI7jOw.js.map +0 -1
- package/dist/components-B6-PFL8z.js +0 -5
- package/dist/connect.config-vgUeFoNp.js.map +0 -1
- package/dist/load-BucYuvxH.js +0 -100
- package/dist/load-BucYuvxH.js.map +0 -1
- package/dist/package-BcKQ9BGX.js +0 -127
- package/dist/package-BcKQ9BGX.js.map +0 -1
- package/dist/reactor-ynguOpe7.js.map +0 -1
- package/dist/registerServiceWorker-nJIc0yEY.js.map +0 -1
- package/dist/reload-connect-toast-D1Iqw9E_.js.map +0 -1
- package/dist/toast-4t-VimvD.js.map +0 -1
- package/dist/useRegistryPackages-BaYtekjQ.js +0 -179
- package/dist/useRegistryPackages-BaYtekjQ.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-state-
|
|
1
|
+
{"version":3,"file":"connection-state-3w4liC1X.js","sources":["../src/utils/reactor-namespace.ts","../src/utils/storage-namespace.ts","../src/utils/pglite-runtime.ts","../src/connection-state.ts"],"sourcesContent":["import { getStorageNamespace } from \"@powerhousedao/shared/connect\";\nimport { hashNamespace } from \"@powerhousedao/shared/processors\";\n\nexport type ReactorNamespaceInput = {\n basePath: string;\n explicit?: string;\n endpoint?: string;\n};\n\nexport function resolveReactorNamespace(input: ReactorNamespaceInput): string {\n const explicit = input.explicit?.trim();\n if (explicit) {\n return explicit;\n }\n const base = getStorageNamespace(input.basePath);\n const endpoint = input.endpoint?.trim();\n if (endpoint) {\n return `${base}--${hashNamespace(endpoint, 8)}`;\n }\n return base;\n}\n","import { DEFAULT_RELATIONAL_PROCESSOR_DB_NAME } from \"@powerhousedao/shared/processors\";\nimport { ROOT_STORAGE_NAMESPACE } from \"@powerhousedao/shared/connect\";\nimport { PH_CONNECT_BASE_PATH } from \"../connect.config.js\";\nimport { getRuntimeConfig } from \"../runtime-config.js\";\nimport { resolveReactorNamespace } from \"./reactor-namespace.js\";\n\nexport const REACTOR_INSTANCE_NAMESPACE = resolveReactorNamespace({\n basePath: PH_CONNECT_BASE_PATH,\n explicit: getRuntimeConfig().connect.instance?.namespace ?? undefined,\n});\n\nexport const REACTOR_PGLITE_NAME = REACTOR_INSTANCE_NAMESPACE;\n\nexport const RELATIONAL_PGLITE_NAME =\n REACTOR_INSTANCE_NAMESPACE === ROOT_STORAGE_NAMESPACE\n ? DEFAULT_RELATIONAL_PROCESSOR_DB_NAME\n : `${REACTOR_INSTANCE_NAMESPACE}-${DEFAULT_RELATIONAL_PROCESSOR_DB_NAME}`;\n\n// Here, not pglite-idb.ts, so those IDB helpers stay free of runtime-config\n// and remain importable by the reactor SharedWorker.\nexport const REACTOR_IDB_NAME = `/pglite/${REACTOR_PGLITE_NAME}`;\nexport const RELATIONAL_IDB_NAME = `/pglite/${RELATIONAL_PGLITE_NAME}`;\nexport const PRIMARY_IDB_NAMES = [\n REACTOR_IDB_NAME,\n RELATIONAL_IDB_NAME,\n] as const;\n","import { readPgVersionFile } from \"./pglite-idb.js\";\nimport {\n coerceMajor,\n isMigratableMajor,\n type DetectedMajor,\n} from \"./pglite-major.js\";\nimport { REACTOR_IDB_NAME, RELATIONAL_IDB_NAME } from \"./storage-namespace.js\";\n\nexport {\n CURRENT_PG_MAJOR,\n SUPPORTED_PG_MAJORS,\n coerceMajor,\n resolvePgMajorForRuntime,\n loadPGliteModule,\n loadPgDump,\n type SupportedPgMajor,\n type DetectedMajor,\n} from \"./pglite-major.js\";\n\nlet cachedReactorMajor: DetectedMajor | undefined;\nlet inflight: Promise<DetectedMajor> | undefined;\nconst majorListeners = new Set<() => void>();\n\nlet cachedMigrationMajor: DetectedMajor | undefined;\nlet migrationInflight: Promise<DetectedMajor> | undefined;\nconst migrationListeners = new Set<() => void>();\n\nfunction notifyMajorChanged() {\n for (const l of majorListeners) l();\n}\n\nfunction notifyMigrationChanged() {\n for (const l of migrationListeners) l();\n}\n\nexport function subscribeReactorPgMajor(cb: () => void): () => void {\n majorListeners.add(cb);\n return () => {\n majorListeners.delete(cb);\n };\n}\n\nexport async function detectReactorPgMajor(): Promise<DetectedMajor> {\n if (cachedReactorMajor !== undefined) return cachedReactorMajor;\n if (inflight) return inflight;\n\n inflight = (async () => {\n const major = coerceMajor(await readPgVersionFile(REACTOR_IDB_NAME));\n cachedReactorMajor = major;\n notifyMajorChanged();\n return major;\n })();\n try {\n return await inflight;\n } finally {\n inflight = undefined;\n }\n}\n\nexport function getCachedReactorPgMajor(): DetectedMajor | undefined {\n return cachedReactorMajor;\n}\n\nexport function invalidateReactorPgMajorCache(): void {\n cachedReactorMajor = undefined;\n cachedMigrationMajor = undefined;\n notifyMajorChanged();\n notifyMigrationChanged();\n}\n\nexport async function detectRelationalPgMajor(): Promise<DetectedMajor> {\n return coerceMajor(await readPgVersionFile(RELATIONAL_IDB_NAME));\n}\n\nexport function subscribeMigrationMajor(cb: () => void): () => void {\n migrationListeners.add(cb);\n return () => {\n migrationListeners.delete(cb);\n };\n}\n\nexport function getCachedMigrationMajor(): DetectedMajor | undefined {\n return cachedMigrationMajor;\n}\n\n/**\n * Legacy major the migration banner should prompt for: the first primary store\n * (reactor or relational) on a supported, non-current major. Spans both stores\n * to match migrateAllIfNeeded.\n */\nexport async function detectMigrationMajor(): Promise<DetectedMajor> {\n if (cachedMigrationMajor !== undefined) return cachedMigrationMajor;\n if (migrationInflight) return migrationInflight;\n\n migrationInflight = (async () => {\n const majors = await Promise.all([\n readPgVersionFile(REACTOR_IDB_NAME),\n readPgVersionFile(RELATIONAL_IDB_NAME),\n ]);\n const legacy = majors.find(isMigratableMajor) ?? null;\n cachedMigrationMajor = legacy;\n notifyMigrationChanged();\n return legacy;\n })();\n try {\n return await migrationInflight;\n } finally {\n migrationInflight = undefined;\n }\n}\n","export type WorkerConnectionStatus = \"connected\" | \"lost\";\n\nlet status: WorkerConnectionStatus = \"connected\";\nconst listeners = new Set<() => void>();\n\nexport function getWorkerConnectionStatus(): WorkerConnectionStatus {\n return status;\n}\n\nexport function setWorkerConnectionStatus(next: WorkerConnectionStatus): void {\n if (status === next) {\n return;\n }\n status = next;\n for (const listener of [...listeners]) {\n listener();\n }\n}\n\nexport function subscribeWorkerConnection(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n"],"names":[],"mappings":";;;;;;;;AASA,SAAgB,wBAAwB,OAAsC;CAC5E,MAAM,WAAW,MAAM,UAAU,MAAM;AACvC,KAAI,SACF,QAAO;CAET,MAAM,OAAO,oBAAoB,MAAM,SAAS;CAChD,MAAM,WAAW,MAAM,UAAU,MAAM;AACvC,KAAI,SACF,QAAO,GAAG,KAAK,IAAI,cAAc,UAAU,EAAE;AAE/C,QAAO;;;;ACbT,MAAa,6BAA6B,wBAAwB;CAChE,UAAU;CACV,UAAU,kBAAkB,CAAC,QAAQ,UAAU,aAAa,KAAA;CAC7D,CAAC;AAEF,MAAa,sBAAsB;AAEnC,MAAa,yBACX,+BAA+B,yBAC3B,uCACA,GAAG,2BAA2B,GAAG;AAIvC,MAAa,mBAAmB,WAAW;AAC3C,MAAa,sBAAsB,WAAW;AAC9C,MAAa,oBAAoB,CAC/B,kBACA,oBACD;;;ACND,IAAI;AACJ,IAAI;AACJ,MAAM,iCAAiB,IAAI,KAAiB;AAE5C,IAAI;AACJ,IAAI;AACJ,MAAM,qCAAqB,IAAI,KAAiB;AAEhD,SAAS,qBAAqB;AAC5B,MAAK,MAAM,KAAK,eAAgB,IAAG;;AAGrC,SAAS,yBAAyB;AAChC,MAAK,MAAM,KAAK,mBAAoB,IAAG;;AAGzC,SAAgB,wBAAwB,IAA4B;AAClE,gBAAe,IAAI,GAAG;AACtB,cAAa;AACX,iBAAe,OAAO,GAAG;;;AAI7B,eAAsB,uBAA+C;AACnE,KAAI,uBAAuB,KAAA,EAAW,QAAO;AAC7C,KAAI,SAAU,QAAO;AAErB,aAAY,YAAY;EACtB,MAAM,QAAQ,YAAY,MAAM,kBAAkB,iBAAiB,CAAC;AACpE,uBAAqB;AACrB,sBAAoB;AACpB,SAAO;KACL;AACJ,KAAI;AACF,SAAO,MAAM;WACL;AACR,aAAW,KAAA;;;AAIf,SAAgB,0BAAqD;AACnE,QAAO;;AAGT,SAAgB,gCAAsC;AACpD,sBAAqB,KAAA;AACrB,wBAAuB,KAAA;AACvB,qBAAoB;AACpB,yBAAwB;;AAG1B,eAAsB,0BAAkD;AACtE,QAAO,YAAY,MAAM,kBAAkB,oBAAoB,CAAC;;AAGlE,SAAgB,wBAAwB,IAA4B;AAClE,oBAAmB,IAAI,GAAG;AAC1B,cAAa;AACX,qBAAmB,OAAO,GAAG;;;AAIjC,SAAgB,0BAAqD;AACnE,QAAO;;;;;;;AAQT,eAAsB,uBAA+C;AACnE,KAAI,yBAAyB,KAAA,EAAW,QAAO;AAC/C,KAAI,kBAAmB,QAAO;AAE9B,sBAAqB,YAAY;EAK/B,MAAM,UAJS,MAAM,QAAQ,IAAI,CAC/B,kBAAkB,iBAAiB,EACnC,kBAAkB,oBAAoB,CACvC,CAAC,EACoB,KAAK,kBAAkB,IAAI;AACjD,yBAAuB;AACvB,0BAAwB;AACxB,SAAO;KACL;AACJ,KAAI;AACF,SAAO,MAAM;WACL;AACR,sBAAoB,KAAA;;;;;ACzGxB,IAAI,SAAiC;AACrC,MAAM,4BAAY,IAAI,KAAiB;AAEvC,SAAgB,4BAAoD;AAClE,QAAO;;AAGT,SAAgB,0BAA0B,MAAoC;AAC5E,KAAI,WAAW,KACb;AAEF,UAAS;AACT,MAAK,MAAM,YAAY,CAAC,GAAG,UAAU,CACnC,WAAU;;AAId,SAAgB,0BAA0B,UAAkC;AAC1E,WAAU,IAAI,SAAS;AACvB,cAAa;AACX,YAAU,OAAO,SAAS","debug_id":"f678f465-b7fd-5e27-bf6c-9ccdf05e9a69"}
|
|
@@ -0,0 +1,70 @@
|
|
|
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]="5dc522b0-5423-5c74-8f11-6044a6947ba3")}catch(e){}}();
|
|
3
|
+
import { t as i18n } from "./i18n-CWO0vYVd.js";
|
|
4
|
+
import { n as useCookieBanner, t as useAcceptedCookies } from "./preferences-store-_5Cw4_YV.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Trans, useTranslation } from "react-i18next";
|
|
7
|
+
import { showPHModal } from "@powerhousedao/reactor-browser";
|
|
8
|
+
import { CookieBanner as CookieBanner$1 } from "@powerhousedao/design-system/connect";
|
|
9
|
+
//#region src/components/cookie-banner.tsx
|
|
10
|
+
const isCookieAccepted = (cookies, id) => {
|
|
11
|
+
return cookies.some((cookie) => cookie.id === id && cookie.value);
|
|
12
|
+
};
|
|
13
|
+
const CookieBanner = () => {
|
|
14
|
+
const { t } = useTranslation(void 0, {
|
|
15
|
+
useSuspense: true,
|
|
16
|
+
i18n
|
|
17
|
+
});
|
|
18
|
+
const [showBanner, setShowBanner] = useCookieBanner();
|
|
19
|
+
const [, setAcceptedCookies] = useAcceptedCookies();
|
|
20
|
+
const cookiesInput = [{
|
|
21
|
+
id: "analytics-cookie",
|
|
22
|
+
label: t("cookieBanner.cookies.analytics"),
|
|
23
|
+
value: true
|
|
24
|
+
}];
|
|
25
|
+
const handleAccept = (cookies) => {
|
|
26
|
+
setShowBanner(false);
|
|
27
|
+
if (isCookieAccepted(cookies, "analytics-cookie")) setAcceptedCookies((acceptedCookies) => ({
|
|
28
|
+
...acceptedCookies,
|
|
29
|
+
analytics: true
|
|
30
|
+
}));
|
|
31
|
+
};
|
|
32
|
+
const handleReject = () => {
|
|
33
|
+
setShowBanner(false);
|
|
34
|
+
setAcceptedCookies(() => ({
|
|
35
|
+
analytics: false,
|
|
36
|
+
functional: false,
|
|
37
|
+
marketing: false
|
|
38
|
+
}));
|
|
39
|
+
};
|
|
40
|
+
if (!showBanner) return null;
|
|
41
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
42
|
+
className: "absolute inset-0 z-10000 backdrop-blur-sm",
|
|
43
|
+
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-primary opacity-15" }), /* @__PURE__ */ jsx("div", {
|
|
44
|
+
className: "absolute inset-x-0 bottom-0 flex justify-center bg-background px-10 pt-10 pb-16 shadow-lg",
|
|
45
|
+
children: /* @__PURE__ */ jsx(CookieBanner$1, {
|
|
46
|
+
className: "max-w-[1024px]",
|
|
47
|
+
cookies: cookiesInput,
|
|
48
|
+
onSubmit: handleAccept,
|
|
49
|
+
onReject: handleReject,
|
|
50
|
+
submitLabel: t("cookieBanner.accept"),
|
|
51
|
+
rejectLabel: t("cookieBanner.reject"),
|
|
52
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
53
|
+
className: "font-semibold text-muted-foreground",
|
|
54
|
+
children: /* @__PURE__ */ jsx(Trans, {
|
|
55
|
+
i18nKey: "cookieBanner.message",
|
|
56
|
+
components: { a: /* @__PURE__ */ jsx("a", {
|
|
57
|
+
onClick: () => showPHModal({ type: "cookiesPolicy" }),
|
|
58
|
+
className: "cursor-pointer text-foreground hover:underline"
|
|
59
|
+
}, "cookieBanner.message-link") }
|
|
60
|
+
}, "cookieBanner.message")
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
})]
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
export { CookieBanner };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=cookie-banner-BH6bIq24.js.map
|
|
70
|
+
//# debugId=5dc522b0-5423-5c74-8f11-6044a6947ba3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie-banner-BH6bIq24.js","sources":["../src/components/cookie-banner.tsx"],"sourcesContent":["import {\n useAcceptedCookies,\n useCookieBanner,\n} from \"../hooks/preferences-store.js\";\nimport type { CookieInput } from \"@powerhousedao/design-system/connect\";\nimport { CookieBanner as PHCookieBanner } from \"@powerhousedao/design-system/connect\";\nimport { showPHModal } from \"@powerhousedao/reactor-browser\";\nimport { Trans, useTranslation } from \"react-i18next\";\nimport { i18n } from \"@powerhousedao/connect/i18n\";\n\nconst isCookieAccepted = (cookies: CookieInput[], id: string) => {\n return cookies.some((cookie) => cookie.id === id && cookie.value);\n};\n\nexport const CookieBanner = () => {\n const { t } = useTranslation(undefined, {\n useSuspense: true,\n i18n,\n });\n const [showBanner, setShowBanner] = useCookieBanner();\n const [, setAcceptedCookies] = useAcceptedCookies();\n\n const cookiesInput: CookieInput[] = [\n {\n id: \"analytics-cookie\",\n label: t(\"cookieBanner.cookies.analytics\"),\n value: true,\n },\n ];\n\n const handleAccept = (cookies: CookieInput[]) => {\n setShowBanner(false);\n\n if (isCookieAccepted(cookies, \"analytics-cookie\")) {\n setAcceptedCookies((acceptedCookies) => ({\n ...acceptedCookies,\n analytics: true,\n }));\n }\n };\n\n const handleReject = () => {\n setShowBanner(false);\n setAcceptedCookies(() => ({\n analytics: false,\n functional: false,\n marketing: false,\n }));\n };\n\n if (!showBanner) {\n return null;\n }\n\n return (\n <div className=\"absolute inset-0 z-10000 backdrop-blur-sm\">\n <div className=\"absolute inset-0 bg-primary opacity-15\" />\n <div className=\"absolute inset-x-0 bottom-0 flex justify-center bg-background px-10 pt-10 pb-16 shadow-lg\">\n <PHCookieBanner\n className=\"max-w-[1024px]\"\n cookies={cookiesInput}\n onSubmit={handleAccept}\n onReject={handleReject}\n submitLabel={t(\"cookieBanner.accept\")}\n rejectLabel={t(\"cookieBanner.reject\")}\n >\n <p className=\"font-semibold text-muted-foreground\">\n <Trans\n key={\"cookieBanner.message\"}\n i18nKey=\"cookieBanner.message\"\n components={{\n a: (\n <a\n onClick={() => showPHModal({ type: \"cookiesPolicy\" })}\n key={\"cookieBanner.message-link\"}\n className=\"cursor-pointer text-foreground hover:underline\"\n />\n ),\n }}\n />\n </p>\n </PHCookieBanner>\n </div>\n </div>\n );\n};\n"],"names":["PHCookieBanner"],"mappings":";;;;;;;;;AAUA,MAAM,oBAAoB,SAAwB,OAAe;AAC/D,QAAO,QAAQ,MAAM,WAAW,OAAO,OAAO,MAAM,OAAO,MAAM;;AAGnE,MAAa,qBAAqB;CAChC,MAAM,EAAE,MAAM,eAAe,KAAA,GAAW;EACtC,aAAa;EACb;EACD,CAAC;CACF,MAAM,CAAC,YAAY,iBAAiB,iBAAiB;CACrD,MAAM,GAAG,sBAAsB,oBAAoB;CAEnD,MAAM,eAA8B,CAClC;EACE,IAAI;EACJ,OAAO,EAAE,iCAAiC;EAC1C,OAAO;EACR,CACF;CAED,MAAM,gBAAgB,YAA2B;AAC/C,gBAAc,MAAM;AAEpB,MAAI,iBAAiB,SAAS,mBAAmB,CAC/C,qBAAoB,qBAAqB;GACvC,GAAG;GACH,WAAW;GACZ,EAAE;;CAIP,MAAM,qBAAqB;AACzB,gBAAc,MAAM;AACpB,4BAA0B;GACxB,WAAW;GACX,YAAY;GACZ,WAAW;GACZ,EAAE;;AAGL,KAAI,CAAC,WACH,QAAO;AAGT,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,OAAD,EAAK,WAAU,0CAA2C,CAAA,EAC1D,oBAAC,OAAD;GAAK,WAAU;aACb,oBAACA,gBAAD;IACE,WAAU;IACV,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa,EAAE,sBAAsB;IACrC,aAAa,EAAE,sBAAsB;cAErC,oBAAC,KAAD;KAAG,WAAU;eACX,oBAAC,OAAD;MAEE,SAAQ;MACR,YAAY,EACV,GACE,oBAAC,KAAD;OACE,eAAe,YAAY,EAAE,MAAM,iBAAiB,CAAC;OAErD,WAAU;OACV,EAFK,4BAEL,EAEL;MACD,EAXK,uBAWL;KACA,CAAA;IACW,CAAA;GACb,CAAA,CACF","debug_id":"5dc522b0-5423-5c74-8f11-6044a6947ba3"}
|
|
@@ -1,8 +1,7 @@
|
|
|
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]="
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
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]="4b6a75b5-90d3-57d5-8307-cac89ca822fa")}catch(e){}}();
|
|
4
3
|
import i18n from "i18next";
|
|
5
|
-
import { initReactI18next
|
|
4
|
+
import { initReactI18next } from "react-i18next";
|
|
6
5
|
i18n.use(initReactI18next).init({
|
|
7
6
|
resources: { en: {
|
|
8
7
|
code: "en",
|
|
@@ -17,7 +16,7 @@ i18n.use(initReactI18next).init({
|
|
|
17
16
|
"save": "Save",
|
|
18
17
|
"download": "Download",
|
|
19
18
|
"reload": "Reload",
|
|
20
|
-
"
|
|
19
|
+
"updateDocument": "Update document"
|
|
21
20
|
},
|
|
22
21
|
searchbar: {
|
|
23
22
|
"placeholder": "Search Powerhouse",
|
|
@@ -80,6 +79,22 @@ i18n.use(initReactI18next).init({
|
|
|
80
79
|
"title": "Your document contains errors",
|
|
81
80
|
"body": "Your document contains structure errors. Do you want to export it anyway?"
|
|
82
81
|
},
|
|
82
|
+
"openFileDocuments": {
|
|
83
|
+
"title_one": "Open document",
|
|
84
|
+
"title_other": "Open documents",
|
|
85
|
+
"body": "Choose the drive to import into:",
|
|
86
|
+
"noDrives": "No drives available yet — remote drives may still be loading. Create a drive to import into, or try again in a moment.",
|
|
87
|
+
"notAllowed": "Your account is not allowed to create documents in this reactor.",
|
|
88
|
+
"createDrive": "Create drive",
|
|
89
|
+
"import": "Import",
|
|
90
|
+
"renameAndImport": "Rename and import",
|
|
91
|
+
"checking": "Checking…",
|
|
92
|
+
"invalidFile": "File is not a valid Powerhouse document",
|
|
93
|
+
"unsupportedType": "Document type is not supported",
|
|
94
|
+
"duplicateHint": "Already in this drive — will be imported as \"{{name}}\"",
|
|
95
|
+
"duplicateCopyHint": "Already in this drive — a copy will be created",
|
|
96
|
+
"renamedHint": "Renamed to \"{{name}}\" to avoid a name clash"
|
|
97
|
+
},
|
|
83
98
|
"disclaimer": {
|
|
84
99
|
"title": "Disclaimer",
|
|
85
100
|
"body": "All content provided herein our website, hyperlinked sites, associated applications, forums, blogs, social media accounts and other platforms (“Site”) is for your general information only, procured from third party sources. We make no warranties of any kind in relation to our content, including but not limited to accuracy and updatedness. No part of the content that we provide constitutes financial advice, legal advice or any other form of advice meant for your specific reliance for any purpose. Any use or reliance on our content is solely at your own risk and discretion. You should conduct your own research, review, analyse and verify our content before relying on them. Trading is a highly risky activity that can lead to major losses, please therefore consult your financial advisor before making any decision. No content on our Site is meant to be a solicitation or offer."
|
|
@@ -97,7 +112,7 @@ i18n.use(initReactI18next).init({
|
|
|
97
112
|
"driveSyncSuccess": "Drive synced successfully",
|
|
98
113
|
"driveSyncError": "Error synchronizing drive {{drive}}",
|
|
99
114
|
"driveSyncConflict": "Conflict error detected in {{drive}}",
|
|
100
|
-
"
|
|
115
|
+
"documentUpgradeAvailable": "A newer version of this document type is installed."
|
|
101
116
|
},
|
|
102
117
|
footer: {
|
|
103
118
|
"cookiePolicy": "Cookie Policy",
|
|
@@ -123,29 +138,7 @@ i18n.use(initReactI18next).init({
|
|
|
123
138
|
console.error(e);
|
|
124
139
|
});
|
|
125
140
|
//#endregion
|
|
126
|
-
|
|
127
|
-
let sentry;
|
|
128
|
-
function setSentryModule(mod) {
|
|
129
|
-
sentry = mod;
|
|
130
|
-
}
|
|
131
|
-
function setUser(...args) {
|
|
132
|
-
sentry?.setUser(...args);
|
|
133
|
-
}
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region src/components/reload-connect-toast.tsx
|
|
136
|
-
const ReloadConnectToast = () => {
|
|
137
|
-
const { t } = useTranslation();
|
|
138
|
-
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
|
|
139
|
-
className: "font-medium",
|
|
140
|
-
children: t("notifications.reloadApp")
|
|
141
|
-
}), /* @__PURE__ */ jsxs("button", {
|
|
142
|
-
onClick: () => location.reload(),
|
|
143
|
-
className: "underline decoration-solid underline-offset-2",
|
|
144
|
-
children: [t("common.reloadConnect"), " 🔄"]
|
|
145
|
-
})] });
|
|
146
|
-
};
|
|
147
|
-
//#endregion
|
|
148
|
-
export { i18n as i, setSentryModule as n, setUser as r, ReloadConnectToast as t };
|
|
141
|
+
export { i18n as t };
|
|
149
142
|
|
|
150
|
-
//# sourceMappingURL=
|
|
151
|
-
//# debugId=
|
|
143
|
+
//# sourceMappingURL=i18n-CWO0vYVd.js.map
|
|
144
|
+
//# debugId=4b6a75b5-90d3-57d5-8307-cac89ca822fa
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-CWO0vYVd.js","sources":["../src/i18n/locales/en.json","../src/i18n/index.ts"],"sourcesContent":["","import type { Resource } from \"i18next\";\nimport i18n from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\n\nimport translationEN from \"./locales/en.json\" with { type: \"json\" };\n\nconst resources: Resource = {\n en: {\n code: \"en\",\n name: \"English\",\n translation: translationEN,\n },\n};\n\ni18n\n .use(initReactI18next)\n .init({\n resources,\n fallbackLng: \"en\",\n debug: false,\n interpolation: {\n escapeValue: false,\n },\n })\n .catch((e: unknown) => {\n console.error(e);\n });\n\nexport { i18n };\nexport default i18n;\n"],"names":["translationEN"],"mappings":";;;;ACcA,KACG,IAAI,iBAAiB,CACrB,KAAK;CACJ,WAXwB,EAC1B,IAAI;EACF,MAAM;EACN,MAAM;EACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACD,EACF;CAMG,aAAa;CACb,OAAO;CACP,eAAe,EACb,aAAa,OACd;CACF,CAAC,CACD,OAAO,MAAe;AACrB,SAAQ,MAAM,EAAE;EAChB","debug_id":"4b6a75b5-90d3-57d5-8307-cac89ca822fa"}
|
|
@@ -0,0 +1,131 @@
|
|
|
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]="a7516642-2718-511e-9358-709d819df64a")}catch(e){}}();
|
|
3
|
+
import { r as loadRuntimeConfig, t as applyConnectBranding } from "./runtime-config-DL3QjcfM.js";
|
|
4
|
+
import { t as getBuildHash } from "./build-info-D8VekPcJ.js";
|
|
5
|
+
import { r as connectConfig } from "./connect.config-DaHDEUrw.js";
|
|
6
|
+
import { n as createReactor } from "./reactor-DBCWJdBA.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";
|
|
10
|
+
import { useEffect } from "react";
|
|
11
|
+
import { initTheme, useUser } from "@powerhousedao/reactor-browser";
|
|
12
|
+
import { logger } from "document-model";
|
|
13
|
+
//#region src/hooks/useCheckLatestVersion.ts
|
|
14
|
+
const RELOADED_FOR_KEY = "ph-reloaded-for-build-hash";
|
|
15
|
+
/**
|
|
16
|
+
* Drop the service worker's stale caches (precache + the NetworkFirst shell
|
|
17
|
+
* cache) before reloading onto a new deploy, so the post-reload navigation
|
|
18
|
+
* is answered from the network / fresh build instead of leftovers of the
|
|
19
|
+
* build we are leaving. Best-effort: if the Caches API is unavailable or a
|
|
20
|
+
* delete fails, the reload still picks up the new shell (the navigation
|
|
21
|
+
* route is NetworkFirst).
|
|
22
|
+
*/
|
|
23
|
+
async function clearStaleCaches() {
|
|
24
|
+
try {
|
|
25
|
+
if (!("caches" in window)) return;
|
|
26
|
+
const keys = await window.caches.keys();
|
|
27
|
+
await Promise.all(keys.filter((key) => key.includes("precache") || key.includes("ph-shell")).map((key) => window.caches.delete(key)));
|
|
28
|
+
} catch (error) {
|
|
29
|
+
logger.warn("Failed to clear stale caches before update reload @error", error);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Detects that the server is serving a different build than the one this
|
|
34
|
+
* page was loaded from (a new deploy) and reloads onto it — once per session
|
|
35
|
+
* per deployed hash. Checked on mount and whenever the tab returns to the
|
|
36
|
+
* foreground, so a deploy that lands while the tab sits open is picked up on
|
|
37
|
+
* the next focus without a manual reload. The in-tab "new version available"
|
|
38
|
+
* service-worker prompt (ServiceWorkerUpdatePrompt) remains the opt-in path
|
|
39
|
+
* for workers that are waiting but not yet controlling.
|
|
40
|
+
*/
|
|
41
|
+
const useCheckLatestVersion = () => {
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (import.meta.env.MODE === "development" || connectConfig.studioMode || !connectConfig.warnOutdatedApp) return;
|
|
44
|
+
const checkBuildHash = async () => {
|
|
45
|
+
const status = await getBuildHashStatus();
|
|
46
|
+
if (!status || status.isCurrent) return;
|
|
47
|
+
if (window.sessionStorage.getItem(RELOADED_FOR_KEY) === status.deployedHash) return;
|
|
48
|
+
window.sessionStorage.setItem(RELOADED_FOR_KEY, status.deployedHash);
|
|
49
|
+
logger.info("New deploy detected — reloading from build @currentHash to @deployedHash", status.currentHash, status.deployedHash);
|
|
50
|
+
await clearStaleCaches();
|
|
51
|
+
window.location.reload();
|
|
52
|
+
};
|
|
53
|
+
checkBuildHash();
|
|
54
|
+
const onVisibilityChange = () => {
|
|
55
|
+
if (document.visibilityState === "visible") checkBuildHash();
|
|
56
|
+
};
|
|
57
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
58
|
+
return () => {
|
|
59
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
60
|
+
};
|
|
61
|
+
}, []);
|
|
62
|
+
};
|
|
63
|
+
window.navigator.appVersion.includes("Mac");
|
|
64
|
+
/**
|
|
65
|
+
* Same-origin build-identity probe. The build bakes a hash of the inputs that
|
|
66
|
+
* determine the deployed content into the bundle (define
|
|
67
|
+
* `PH_CONNECT_BUILD_HASH`, see builder-tools' connectBuildHashPlugin) and
|
|
68
|
+
* emits `build-hash.json` next to the app (served no-cache). Comparing the
|
|
69
|
+
* two tells us whether the server is serving a different build than the one
|
|
70
|
+
* this page was loaded from — the reliable "a new deploy went out" signal.
|
|
71
|
+
* Unlike the old GitHub-raw version check it works on localhost (it compares
|
|
72
|
+
* against what the origin actually serves, not a remote branch head) and
|
|
73
|
+
* needs no network beyond the app's own origin.
|
|
74
|
+
*
|
|
75
|
+
* Returns null when there is nothing to compare: dev/studio builds (no hash
|
|
76
|
+
* baked), a server predating `build-hash.json`, an offline fetch, or a
|
|
77
|
+
* malformed body.
|
|
78
|
+
*/
|
|
79
|
+
const getBuildHashStatus = async () => {
|
|
80
|
+
const currentHash = getBuildHash();
|
|
81
|
+
if (!currentHash || currentHash === "unknown") return null;
|
|
82
|
+
try {
|
|
83
|
+
const result = await fetch(`${import.meta.env.BASE_URL}build-hash.json`, { cache: "no-cache" });
|
|
84
|
+
if (!result.ok) return null;
|
|
85
|
+
const data = await result.json();
|
|
86
|
+
if (typeof data.hash !== "string" || !data.hash) return null;
|
|
87
|
+
return {
|
|
88
|
+
currentHash,
|
|
89
|
+
deployedHash: data.hash,
|
|
90
|
+
isCurrent: data.hash === currentHash
|
|
91
|
+
};
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/store/user.ts
|
|
98
|
+
function useSetSentryUser() {
|
|
99
|
+
const user = useUser();
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
let sentryUser = null;
|
|
102
|
+
if (user) {
|
|
103
|
+
const { credential: _credential, ...rest } = user;
|
|
104
|
+
sentryUser = {
|
|
105
|
+
id: rest.did,
|
|
106
|
+
username: rest.ens?.name,
|
|
107
|
+
...rest
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
setUser(sentryUser);
|
|
111
|
+
}, [user]);
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/components/load.tsx
|
|
115
|
+
async function loadComponent(localPackage) {
|
|
116
|
+
await seedPendingPgVersion();
|
|
117
|
+
await Promise.all([detectReactorPgMajor(), detectMigrationMajor()]);
|
|
118
|
+
applyConnectBranding(await loadRuntimeConfig());
|
|
119
|
+
await createReactor(localPackage);
|
|
120
|
+
return { default: ({ children }) => {
|
|
121
|
+
initTheme();
|
|
122
|
+
useSetSentryUser();
|
|
123
|
+
useCheckLatestVersion();
|
|
124
|
+
return children;
|
|
125
|
+
} };
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
export { loadComponent };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=load-D_BC1JxM.js.map
|
|
131
|
+
//# debugId=a7516642-2718-511e-9358-709d819df64a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-D_BC1JxM.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":"a7516642-2718-511e-9358-709d819df64a"}
|
package/dist/main.js
CHANGED
|
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
//#region main.tsx
|
|
7
7
|
if (!window.ph) window.ph = {};
|
|
8
8
|
await loadRuntimeConfig();
|
|
9
|
-
const { AppLoader } = await import("./app-loader-
|
|
9
|
+
const { AppLoader } = await import("./app-loader-D7RV-yqv.js");
|
|
10
10
|
createRoot(document.getElementById("root")).render(/* @__PURE__ */ jsx(AppLoader, {}));
|
|
11
11
|
//#endregion
|
|
12
12
|
|
|
@@ -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]="
|
|
3
|
-
import { l as invalidateReactorPgMajorCache, m as REACTOR_PGLITE_NAME } from "./connection-state-
|
|
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]="80c44266-18c5-5681-aebc-58df7e206589")}catch(e){}}();
|
|
3
|
+
import { l as invalidateReactorPgMajorCache, m as REACTOR_PGLITE_NAME } from "./connection-state-3w4liC1X.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-
|
|
49
|
-
//# debugId=
|
|
48
|
+
//# sourceMappingURL=pglite-seed-BqAUvNFw.js.map
|
|
49
|
+
//# debugId=80c44266-18c5-5681-aebc-58df7e206589
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pglite-seed-
|
|
1
|
+
{"version":3,"file":"pglite-seed-BqAUvNFw.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,oBAAoB;AACrD,KAAI,CAAC,IAAK;CAEV,MAAM,QAAQ,SAAS,KAAK,GAAG;AAC/B,SAAQ,KAAK,iCAAiC,MAAM,cAAc;AAElE,KAAI;AACF,MAAI,UAAU,IAAI;GAChB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,sBAAsB;AACrD,OAAI;AACF,UAAM,GAAG;aACD;AACR,UAAM,GAAG,OAAO;;aAET,UAAU,IAAI;GACvB,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,KAAK,IAAI,OAAO,SAAS,sBAAsB;AACrD,OAAI;AACF,UAAM,GAAG;aACD;AACR,UAAM,GAAG,OAAO;;SAEb;AACL,WAAQ,KAAK,qCAAqC,IAAI,YAAY;AAClE;;AAEF,UAAQ,KAAK,0BAA0B,MAAM,YAAY;WACjD;AACR,eAAa,WAAW,oBAAoB;AAC5C,iCAA+B","debug_id":"80c44266-18c5-5681-aebc-58df7e206589"}
|
|
@@ -0,0 +1,104 @@
|
|
|
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]="dbbeb3d8-22d7-5df6-a263-a0c970e9578b")}catch(e){}}();
|
|
3
|
+
import { r as connectConfig } from "./connect.config-DaHDEUrw.js";
|
|
4
|
+
import { useSyncExternalStore } from "react";
|
|
5
|
+
//#region src/hooks/useIsEmbedded.ts
|
|
6
|
+
/**
|
|
7
|
+
* Detects whether Connect is being rendered inside another app (e.g. inside
|
|
8
|
+
* an iframe in the vetra-cli drive editor). When `?embed=1` is present in the
|
|
9
|
+
* URL, chrome that doesn't make sense in the embedded context — the cookie
|
|
10
|
+
* banner, the outer sidebar — is suppressed.
|
|
11
|
+
*/
|
|
12
|
+
function getIsEmbedded() {
|
|
13
|
+
if (typeof window === "undefined") return false;
|
|
14
|
+
try {
|
|
15
|
+
const value = new URLSearchParams(window.location.search).get("embed");
|
|
16
|
+
return value !== null && value !== "0" && value !== "false";
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function useIsEmbedded() {
|
|
22
|
+
return getIsEmbedded();
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/hooks/preferences-store.ts
|
|
26
|
+
const namespace = connectConfig.routerBasename;
|
|
27
|
+
/**
|
|
28
|
+
* Block-proof home for Connect's consent and banner state.
|
|
29
|
+
*
|
|
30
|
+
* The file name deliberately avoids words that appear in ad-blocker
|
|
31
|
+
* filter lists (cookie, banner, consent, analytics, ...). Modules in the
|
|
32
|
+
* app's critical import chain import from here, never from files whose
|
|
33
|
+
* URLs match those filters. If an ad blocker blocks the lazy-loaded
|
|
34
|
+
* cookie-banner chunk instead, the app simply never shows the banner —
|
|
35
|
+
* which leaves the flags at their rejected defaults (analytics off) —
|
|
36
|
+
* and everything else keeps working.
|
|
37
|
+
*/
|
|
38
|
+
const ACCEPTED_COOKIES_KEY_STORAGE = `${namespace}:acceptedCookies`;
|
|
39
|
+
const REJECTED_COOKIES = {
|
|
40
|
+
analytics: false,
|
|
41
|
+
marketing: false,
|
|
42
|
+
functional: false
|
|
43
|
+
};
|
|
44
|
+
const cookieListeners = /* @__PURE__ */ new Set();
|
|
45
|
+
let acceptedCookies = getInitialAcceptedCookies();
|
|
46
|
+
function getInitialAcceptedCookies() {
|
|
47
|
+
try {
|
|
48
|
+
const value = localStorage.getItem(ACCEPTED_COOKIES_KEY_STORAGE);
|
|
49
|
+
return value ? JSON.parse(value) : REJECTED_COOKIES;
|
|
50
|
+
} catch {
|
|
51
|
+
return REJECTED_COOKIES;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function subscribeAcceptedCookies(fn) {
|
|
55
|
+
cookieListeners.add(fn);
|
|
56
|
+
return () => {
|
|
57
|
+
cookieListeners.delete(fn);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function getAcceptedCookies() {
|
|
61
|
+
return acceptedCookies;
|
|
62
|
+
}
|
|
63
|
+
function setAcceptedCookies(setter) {
|
|
64
|
+
acceptedCookies = setter(acceptedCookies);
|
|
65
|
+
localStorage.setItem(ACCEPTED_COOKIES_KEY_STORAGE, JSON.stringify(acceptedCookies));
|
|
66
|
+
cookieListeners.forEach((fn) => fn());
|
|
67
|
+
}
|
|
68
|
+
const useAcceptedCookies = () => {
|
|
69
|
+
return [useSyncExternalStore(subscribeAcceptedCookies, getAcceptedCookies, getAcceptedCookies), setAcceptedCookies];
|
|
70
|
+
};
|
|
71
|
+
const COOKIE_BANNER_KEY_STORAGE = `${namespace}:display-cookie-banner`;
|
|
72
|
+
const bannerListeners = /* @__PURE__ */ new Set();
|
|
73
|
+
let bannerShown = getInitialBannerShown();
|
|
74
|
+
function getInitialBannerShown() {
|
|
75
|
+
if (getIsEmbedded()) return false;
|
|
76
|
+
try {
|
|
77
|
+
return localStorage.getItem(COOKIE_BANNER_KEY_STORAGE) !== "false";
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(error);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function subscribeBannerShown(fn) {
|
|
84
|
+
bannerListeners.add(fn);
|
|
85
|
+
return () => {
|
|
86
|
+
bannerListeners.delete(fn);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function getBannerShown() {
|
|
90
|
+
return bannerShown;
|
|
91
|
+
}
|
|
92
|
+
function setBannerShown(state) {
|
|
93
|
+
bannerShown = state;
|
|
94
|
+
localStorage.setItem(COOKIE_BANNER_KEY_STORAGE, JSON.stringify(state));
|
|
95
|
+
bannerListeners.forEach((fn) => fn());
|
|
96
|
+
}
|
|
97
|
+
const useCookieBanner = () => {
|
|
98
|
+
return [useSyncExternalStore(subscribeBannerShown, getBannerShown, getBannerShown), setBannerShown];
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { useIsEmbedded as i, useCookieBanner as n, getIsEmbedded as r, useAcceptedCookies as t };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=preferences-store-_5Cw4_YV.js.map
|
|
104
|
+
//# debugId=dbbeb3d8-22d7-5df6-a263-a0c970e9578b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences-store-_5Cw4_YV.js","sources":["../src/hooks/useIsEmbedded.ts","../src/hooks/preferences-store.ts"],"sourcesContent":["/**\n * Detects whether Connect is being rendered inside another app (e.g. inside\n * an iframe in the vetra-cli drive editor). When `?embed=1` is present in the\n * URL, chrome that doesn't make sense in the embedded context — the cookie\n * banner, the outer sidebar — is suppressed.\n */\nexport function getIsEmbedded(): boolean {\n if (typeof window === \"undefined\") return false;\n try {\n const params = new URLSearchParams(window.location.search);\n const value = params.get(\"embed\");\n return value !== null && value !== \"0\" && value !== \"false\";\n } catch {\n return false;\n }\n}\n\nexport function useIsEmbedded(): boolean {\n return getIsEmbedded();\n}\n","import { connectConfig } from \"@powerhousedao/connect/config\";\nimport { useSyncExternalStore } from \"react\";\n\nimport { getIsEmbedded } from \"./useIsEmbedded.js\";\n\nconst namespace = connectConfig.routerBasename;\n\n/**\n * Block-proof home for Connect's consent and banner state.\n *\n * The file name deliberately avoids words that appear in ad-blocker\n * filter lists (cookie, banner, consent, analytics, ...). Modules in the\n * app's critical import chain import from here, never from files whose\n * URLs match those filters. If an ad blocker blocks the lazy-loaded\n * cookie-banner chunk instead, the app simply never shows the banner —\n * which leaves the flags at their rejected defaults (analytics off) —\n * and everything else keeps working.\n */\n\n// ---------------------------------------------------------------------------\n// Accepted cookies (analytics / marketing / functional)\n// ---------------------------------------------------------------------------\n\nexport const ACCEPTED_COOKIES_KEY_STORAGE = `${namespace}:acceptedCookies`;\n\nexport interface AcceptedCookies {\n analytics: boolean;\n marketing: boolean;\n functional: boolean;\n}\n\nconst REJECTED_COOKIES: AcceptedCookies = {\n analytics: false,\n marketing: false,\n functional: false,\n};\n\nconst cookieListeners = new Set<() => void>();\n\nlet acceptedCookies: AcceptedCookies = getInitialAcceptedCookies();\n\nfunction getInitialAcceptedCookies(): AcceptedCookies {\n try {\n const value = localStorage.getItem(ACCEPTED_COOKIES_KEY_STORAGE);\n return value ? (JSON.parse(value) as AcceptedCookies) : REJECTED_COOKIES;\n } catch {\n return REJECTED_COOKIES;\n }\n}\n\nfunction subscribeAcceptedCookies(fn: () => void) {\n cookieListeners.add(fn);\n return () => {\n cookieListeners.delete(fn);\n };\n}\n\nfunction getAcceptedCookies(): AcceptedCookies {\n return acceptedCookies;\n}\n\nexport function setAcceptedCookies(\n setter: (prev: AcceptedCookies) => AcceptedCookies,\n) {\n acceptedCookies = setter(acceptedCookies);\n localStorage.setItem(\n ACCEPTED_COOKIES_KEY_STORAGE,\n JSON.stringify(acceptedCookies),\n );\n cookieListeners.forEach((fn) => fn());\n}\n\nexport const useAcceptedCookies = () => {\n const cookies = useSyncExternalStore(\n subscribeAcceptedCookies,\n getAcceptedCookies,\n getAcceptedCookies,\n );\n return [cookies, setAcceptedCookies] as const;\n};\n\n// ---------------------------------------------------------------------------\n// Cookie banner visibility\n// ---------------------------------------------------------------------------\n\nexport const COOKIE_BANNER_KEY_STORAGE = `${namespace}:display-cookie-banner`;\n\nconst bannerListeners = new Set<() => void>();\n\nlet bannerShown = getInitialBannerShown();\n\nfunction getInitialBannerShown(): boolean {\n if (getIsEmbedded()) return false;\n try {\n const value = localStorage.getItem(COOKIE_BANNER_KEY_STORAGE);\n return value !== \"false\";\n } catch (error) {\n console.error(error);\n return true;\n }\n}\n\nfunction subscribeBannerShown(fn: () => void) {\n bannerListeners.add(fn);\n return () => {\n bannerListeners.delete(fn);\n };\n}\n\nfunction getBannerShown(): boolean {\n return bannerShown;\n}\n\nexport function setBannerShown(state: boolean) {\n bannerShown = state;\n localStorage.setItem(COOKIE_BANNER_KEY_STORAGE, JSON.stringify(state));\n bannerListeners.forEach((fn) => fn());\n}\n\nexport const useCookieBanner = () => {\n const shown = useSyncExternalStore(\n subscribeBannerShown,\n getBannerShown,\n getBannerShown,\n );\n return [shown, setBannerShown] as const;\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAMA,SAAgB,gBAAyB;AACvC,KAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,KAAI;EAEF,MAAM,QADS,IAAI,gBAAgB,OAAO,SAAS,OAAO,CACrC,IAAI,QAAQ;AACjC,SAAO,UAAU,QAAQ,UAAU,OAAO,UAAU;SAC9C;AACN,SAAO;;;AAIX,SAAgB,gBAAyB;AACvC,QAAO,eAAe;;;;ACbxB,MAAM,YAAY,cAAc;;;;;;;;;;;;AAkBhC,MAAa,+BAA+B,GAAG,UAAU;AAQzD,MAAM,mBAAoC;CACxC,WAAW;CACX,WAAW;CACX,YAAY;CACb;AAED,MAAM,kCAAkB,IAAI,KAAiB;AAE7C,IAAI,kBAAmC,2BAA2B;AAElE,SAAS,4BAA6C;AACpD,KAAI;EACF,MAAM,QAAQ,aAAa,QAAQ,6BAA6B;AAChE,SAAO,QAAS,KAAK,MAAM,MAAM,GAAuB;SAClD;AACN,SAAO;;;AAIX,SAAS,yBAAyB,IAAgB;AAChD,iBAAgB,IAAI,GAAG;AACvB,cAAa;AACX,kBAAgB,OAAO,GAAG;;;AAI9B,SAAS,qBAAsC;AAC7C,QAAO;;AAGT,SAAgB,mBACd,QACA;AACA,mBAAkB,OAAO,gBAAgB;AACzC,cAAa,QACX,8BACA,KAAK,UAAU,gBAAgB,CAChC;AACD,iBAAgB,SAAS,OAAO,IAAI,CAAC;;AAGvC,MAAa,2BAA2B;AAMtC,QAAO,CALS,qBACd,0BACA,oBACA,mBACD,EACgB,mBAAmB;;AAOtC,MAAa,4BAA4B,GAAG,UAAU;AAEtD,MAAM,kCAAkB,IAAI,KAAiB;AAE7C,IAAI,cAAc,uBAAuB;AAEzC,SAAS,wBAAiC;AACxC,KAAI,eAAe,CAAE,QAAO;AAC5B,KAAI;AAEF,SADc,aAAa,QAAQ,0BAA0B,KAC5C;UACV,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,SAAO;;;AAIX,SAAS,qBAAqB,IAAgB;AAC5C,iBAAgB,IAAI,GAAG;AACvB,cAAa;AACX,kBAAgB,OAAO,GAAG;;;AAI9B,SAAS,iBAA0B;AACjC,QAAO;;AAGT,SAAgB,eAAe,OAAgB;AAC7C,eAAc;AACd,cAAa,QAAQ,2BAA2B,KAAK,UAAU,MAAM,CAAC;AACtE,iBAAgB,SAAS,OAAO,IAAI,CAAC;;AAGvC,MAAa,wBAAwB;AAMnC,QAAO,CALO,qBACZ,sBACA,gBACA,eACD,EACc,eAAe","debug_id":"dbbeb3d8-22d7-5df6-a263-a0c970e9578b"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/utils/pwa-manifest-link.ts
|
|
2
|
+
|
|
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]="b41f4611-48ee-5074-90dd-4eba2ebbe97f")}catch(e){}}();
|
|
4
|
+
let manifestRevision = 0;
|
|
5
|
+
/**
|
|
6
|
+
* Force the browser to re-consume `manifest.webmanifest` by replacing the
|
|
7
|
+
* `<link rel="manifest">` element with a fresh, cache-busting one. No-op when
|
|
8
|
+
* there is no DOM or no manifest link (dev mode / offline disabled — the build
|
|
9
|
+
* only injects the link when the service worker is enabled).
|
|
10
|
+
*/
|
|
11
|
+
function refreshPwaManifestLink() {
|
|
12
|
+
if (typeof document === "undefined") return;
|
|
13
|
+
const existing = document.querySelector("link[rel=\"manifest\"]");
|
|
14
|
+
if (!existing) return;
|
|
15
|
+
if (!existing.getAttribute("href")) return;
|
|
16
|
+
let href;
|
|
17
|
+
try {
|
|
18
|
+
const url = new URL(existing.href, document.baseURI);
|
|
19
|
+
url.searchParams.set("ph-manifest-rev", String(++manifestRevision));
|
|
20
|
+
href = url.toString();
|
|
21
|
+
} catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const link = document.createElement("link");
|
|
25
|
+
link.rel = "manifest";
|
|
26
|
+
if (existing.crossOrigin) link.crossOrigin = existing.crossOrigin;
|
|
27
|
+
link.href = href;
|
|
28
|
+
existing.replaceWith(link);
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { refreshPwaManifestLink as t };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=pwa-manifest-link-DIgOSo2Q.js.map
|
|
34
|
+
//# debugId=b41f4611-48ee-5074-90dd-4eba2ebbe97f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pwa-manifest-link-DIgOSo2Q.js","sources":["../src/utils/pwa-manifest-link.ts"],"sourcesContent":["// After a runtime package install/removal updates the PWA fragment in\n// IndexedDB (BrowserPackageManager.#syncPwaFragments), the service worker\n// already serves an up-to-date `manifest.webmanifest` — it reads IndexedDB\n// fresh on every request. But the browser only parsed `<link rel=\"manifest\">`\n// ONCE, at page load, so its in-memory manifest (the install prompt, and the\n// manifest's declared fields as the browser reads them — visible in\n// DevTools → Application → Manifest) stays frozen until something makes it\n// re-consume. That \"something\" used to be a manual reload / service-worker\n// update.\n//\n// Re-attaching the manifest `<link>` with a fresh, cache-busting href triggers\n// Chromium's manifest-change invalidation (it recomputes the manifest URL and\n// notifies its consumers), so the install pipeline / DevTools re-fetch the\n// (dynamically served) manifest on demand — no full page reload. The SW route\n// matches on the pathname, so the extra query param doesn't change which\n// response is served, and `start_url`/`scope`/`id` are unaffected (they resolve\n// to the same directory, dropping the query).\n//\n// Caveat (unavoidable, not app-fixable): the OS-level registrations the manifest\n// drives — file associations and launch_handler — are snapshotted by the OS at\n// install time and only re-read on the browser's own throttled manifest-update\n// schedule, so those still lag. The reliable, immediate signal is the served\n// manifest itself (DevTools → Application → Manifest).\n\n// Monotonic per-session revision so each re-attach uses a distinct href (a\n// counter, not a timestamp — deterministic and dependency-free).\nlet manifestRevision = 0;\n\n/**\n * Force the browser to re-consume `manifest.webmanifest` by replacing the\n * `<link rel=\"manifest\">` element with a fresh, cache-busting one. No-op when\n * there is no DOM or no manifest link (dev mode / offline disabled — the build\n * only injects the link when the service worker is enabled).\n */\nexport function refreshPwaManifestLink(): void {\n if (typeof document === \"undefined\") return;\n const existing = document.querySelector<HTMLLinkElement>(\n 'link[rel=\"manifest\"]',\n );\n if (!existing) return;\n // An absent/empty href would resolve to the document URL (new URL(\"\", base)\n // does not throw), producing a manifest link pointing at the HTML page. Bail.\n if (!existing.getAttribute(\"href\")) return;\n\n let href: string;\n try {\n const url = new URL(existing.href, document.baseURI);\n url.searchParams.set(\"ph-manifest-rev\", String(++manifestRevision));\n href = url.toString();\n } catch {\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"manifest\";\n // Preserve crossorigin (vite-plugin-pwa sets it when useCredentials is on).\n if (existing.crossOrigin) link.crossOrigin = existing.crossOrigin;\n link.href = href;\n existing.replaceWith(link);\n}\n"],"names":[],"mappings":";;;AA0BA,IAAI,mBAAmB;;;;;;;AAQvB,SAAgB,yBAA+B;AAC7C,KAAI,OAAO,aAAa,YAAa;CACrC,MAAM,WAAW,SAAS,cACxB,yBACD;AACD,KAAI,CAAC,SAAU;AAGf,KAAI,CAAC,SAAS,aAAa,OAAO,CAAE;CAEpC,IAAI;AACJ,KAAI;EACF,MAAM,MAAM,IAAI,IAAI,SAAS,MAAM,SAAS,QAAQ;AACpD,MAAI,aAAa,IAAI,mBAAmB,OAAO,EAAE,iBAAiB,CAAC;AACnE,SAAO,IAAI,UAAU;SACf;AACN;;CAGF,MAAM,OAAO,SAAS,cAAc,OAAO;AAC3C,MAAK,MAAM;AAEX,KAAI,SAAS,YAAa,MAAK,cAAc,SAAS;AACtD,MAAK,OAAO;AACZ,UAAS,YAAY,KAAK","debug_id":"b41f4611-48ee-5074-90dd-4eba2ebbe97f"}
|