@powerhousedao/builder-tools 6.2.3-dev.60 → 6.2.3-dev.62

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["dirname","pathDirname","importTarget","pathDirname","dirname","pathDirname","withBase","FILE_HANDLER_ACTION","dirname","pathDirname"],"sources":["../connect-utils/constants.ts","../connect-utils/vite-plugins/build-hash.ts","../connect-utils/vite-plugins/dynamic-base.ts","../connect-utils/externalize-vendor.ts","../connect-utils/reactor-worker-build.ts","../connect-utils/worker-packages-build.ts","../connect-utils/helpers.ts","../connect-utils/runtime-config-schema.ts","../connect-utils/vite-plugins/ph-bundled-packages.ts","../connect-utils/vite-plugins/dev-external-react.ts","../connect-utils/vite-plugins/favicon.ts","../connect-utils/vite-plugins/ph-config.ts","../connect-utils/vite-plugins/pwa-packages.ts","../connect-utils/vite-plugins/pwa-icons.ts","../connect-utils/vite-plugins/pwa-overrides.ts","../connect-utils/vite-plugins/pwa.ts","../connect-utils/vite-plugins/react-self-host.ts","../connect-utils/vite-plugins/reactor-worker-dev.ts","../connect-utils/vite-plugins/theme-boot.ts","../connect-utils/vite-plugins/vendor-import-map.ts","../connect-utils/vite-config.ts"],"sourcesContent":["export const EXTERNAL_PACKAGES_IMPORT = \"PH:EXTERNAL_PACKAGES\";\nexport const IMPORT_SCRIPT_FILE = \"external-packages.js\";\nexport const LOCAL_PACKAGE_ID = \"ph:local-package\";\nexport const PH_DIR_NAME = \".ph\";\n","import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\n/** Name of the build-identity file emitted into the build output. */\nexport const BUILD_HASH_FILE = \"build-hash.json\" as const;\n\nexport interface BuildHashInput {\n /** Monorepo workspace git SHA (CI/dev builds); empty outside the monorepo. */\n workspaceGitSha: string;\n /** Monorepo workspace version (CI/dev builds); empty outside it. */\n workspaceVersion: string;\n /** Version of @powerhousedao/connect installed in the project — the\n * published Connect code identity for standalone/Docker builds. */\n connectPackageVersion: string;\n /** Full powerhouse.config.json contents (drives, connect block, packages…). */\n projectConfig: unknown;\n /** Effective package list (config + PH_PACKAGES env override). */\n packages: string[];\n /** Resolved deploy base path (affects emitted asset URLs). */\n connectBasePath: string;\n /** Whether the offline/PWA build variant is emitted. */\n offlineEnabled: boolean;\n /** Packages registry URL baked into the runtime config. */\n packageRegistryUrl: string;\n}\n\n/**\n * Deterministic identity of a Connect build. Differs whenever the deployed\n * content differs (published Connect version, project config, package list,\n * build options) so the SPA can detect \"the server is serving a different\n * build than the one this bundle was built from\" by comparing its baked copy\n * (define `PH_CONNECT_BUILD_HASH`) to `build-hash.json`, which the build\n * emits alongside the app and the server must serve no-cache.\n */\nexport function computeBuildHash(input: BuildHashInput): string {\n return createHash(\"sha256\")\n .update(JSON.stringify(input))\n .digest(\"hex\")\n .slice(0, 16);\n}\n\n/**\n * Read the installed @powerhousedao/connect version. The package's `exports`\n * map does not expose a `./package.json` subpath, so `require.resolve(\n * \"…/package.json\")` throws — resolve the main entry and walk up to the\n * package root instead.\n */\nfunction readConnectVersion(projectRoot: string): string {\n try {\n const require = createRequire(join(projectRoot, \"package.json\"));\n const entry = require.resolve(\"@powerhousedao/connect\", {\n paths: [projectRoot],\n });\n let dir = dirname(entry);\n for (;;) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf-8\"),\n ) as { name?: string; version?: string };\n if (pkg.name === \"@powerhousedao/connect\") {\n return pkg.version ?? \"unknown\";\n }\n } catch {\n // no readable package.json at this level; keep walking up\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // Connect not resolvable from this project; fall through to \"unknown\".\n }\n return \"unknown\";\n}\n\nexport function buildHashFromBuildOptions(options: {\n dirname: string;\n phConfig: unknown;\n packages: ReadonlyArray<{\n packageName: string;\n version?: string;\n provider?: string;\n }>;\n connectBasePath?: string | null;\n offlineEnabled: boolean;\n packageRegistryUrl?: string | null;\n}): string {\n return computeBuildHash({\n workspaceGitSha: process.env.WORKSPACE_GIT_SHA ?? \"\",\n workspaceVersion: process.env.WORKSPACE_VERSION ?? \"\",\n connectPackageVersion: readConnectVersion(options.dirname),\n projectConfig: options.phConfig,\n packages: options.packages.map(\n (p) => `${p.packageName}@${p.version ?? \"\"}:${p.provider ?? \"\"}`,\n ),\n connectBasePath: options.connectBasePath ?? \"\",\n offlineEnabled: options.offlineEnabled,\n packageRegistryUrl: options.packageRegistryUrl ?? \"\",\n });\n}\n\n/**\n * Emits `build-hash.json` (`{\"hash\": \"<build id>\"}`) into the build output.\n * Emitted as an asset so it lands at the deploy base like every other file.\n * Build-only: dev (studio) never runs generateBundle, and the SPA check\n * treats a missing file as \"nothing to compare\" and stays silent.\n */\nexport function connectBuildHashPlugin(buildHash: string): Plugin {\n return {\n name: \"ph-connect-build-hash\",\n apply: \"build\",\n generateBundle() {\n this.emitFile({\n type: \"asset\",\n fileName: BUILD_HASH_FILE,\n source: `${JSON.stringify({ hash: buildHash }, null, 2)}\\n`,\n });\n },\n };\n}\n","import { DYNAMIC_BASE_PLACEHOLDER } from \"@powerhousedao/shared/connect\";\nimport MagicString from \"magic-string\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Placeholder base used when Connect is built in dynamic-base mode. The Vite\n * `base` option is set to this token; this plugin rewrites it in the emitted\n * output so the effective base is resolved at serve time from a global instead\n * of being baked at build time.\n *\n * Trailing slash matches `normalizeBasePath` output, so the token sits in the\n * same syntactic position as a concrete base would.\n *\n * It is defined in the browser-safe shared package (and only re-exported here,\n * where every build-side importer already reaches for it) so Connect's own\n * runtime code can read it without importing this node-only build toolchain.\n */\nexport { DYNAMIC_BASE_PLACEHOLDER };\n\n/**\n * Global the runtime (ph-clint proxy) must set before the entry bundle loads.\n * Value is the normalized deploy base, e.g. \"/myagent/\" or \"/\". The JS rewrite\n * below resolves all asset / lazy-chunk / BASE_URL references against it.\n */\nconst RUNTIME_GLOBAL = \"globalThis.__PH_DYNAMIC_BASE__\";\n\n// `(globalThis.__PH_DYNAMIC_BASE__||\"/\")` — used everywhere the placeholder\n// base prefix appears in emitted JS.\nconst BASE_EXPR = `(${RUNTIME_GLOBAL}||\"/\")`;\n\n// Worker prelude: derive the deploy base in worker scope from the worker's own\n// URL (proxy sets the global on the main thread only).\nfunction workerPrelude(stripPrefix: string): string {\n // `stripPrefix` is the segment between the deploy base and `assets/` (default\n // \"\" → strip `assets/<file>`; vendor passes \"__vendor__/\").\n const prefix = escapeForRegExp(stripPrefix).replace(/\\//g, \"\\\\/\");\n return `${RUNTIME_GLOBAL}=self.location.pathname.replace(/${prefix}assets\\\\/[^/]*$/,\"\");\\n`;\n}\n\n// Match a string literal whose content STARTS with the placeholder, in any of\n// the three JS quote styles Rolldown emits (double, single, backtick). Group 1\n// captures the opening quote; the closing quote must be the same character\n// (backreference), so a double-quoted literal may contain ' or ` and vice\n// versa. Group 2 captures the literal text after the placeholder up to the\n// closing quote. Rolldown emits the base both as a bare literal (the inlined\n// BASE_URL) and as a `<base>`+suffix (preload/asset URL prefix); both start at\n// the placeholder. The content stops at `$`, so a template literal that\n// interpolates after the token (`` `<token>...${expr}` ``) is NOT rewritten —\n// the residual-token assertion in `generateBundle` fails the build instead of\n// shipping the raw placeholder.\nconst PLACEHOLDER_LITERAL = new RegExp(\n `([\"'\\`])${escapeForRegExp(DYNAMIC_BASE_PLACEHOLDER)}((?:(?!\\\\1)[^$])*)\\\\1`,\n \"g\",\n);\n\n/**\n * Rewrites the placeholder base in emitted JS chunks to a runtime expression so\n * one built `dist/connect` serves under any subpath. Rolldown-native: per-match\n * MagicString edits in `renderChunk`, no AST splicing (the SWC byte-offset\n * splicing in vite-plugin-dynamic-base corrupts Rolldown chunks). Each edited\n * chunk returns a hires sourcemap that the bundler composes into the chunk's\n * map chain, so the emitted `.map` files track the rewrite (and the worker\n * prelude's line shift).\n *\n * What gets rewritten in JS, all of which emit the base as a quoted string\n * literal beginning with the placeholder:\n * - asset URLs (`new URL(\"/__PH_DYNAMIC_BASE__/assets/x.png\", ...)`)\n * - dynamic-import / lazy-chunk preload URLs\n * - the inlined `import.meta.env.BASE_URL` (drives Connect's router basename\n * and BASE_URL-relative fetches such as `${BASE_URL}ph-packages.json`)\n *\n * A literal `\"/__PH_DYNAMIC_BASE__/foo\"` becomes `((globalThis.__PH_DYNAMIC_BASE__||\"/\")+\"foo\")`;\n * a bare `\"/__PH_DYNAMIC_BASE__/\"` (the BASE_URL value) becomes `(globalThis.__PH_DYNAMIC_BASE__||\"/\")`.\n *\n * HTML is left untouched: the entry `<script>`/`<link>` tags keep the literal\n * placeholder so the proxy substitutes it with the concrete base at serve time\n * (the same proxy also sets the runtime global for the JS rewrite). See the\n * plugin's module doc / report for the exact serve-time contract.\n *\n * CSS `url(...)` references resolve relative to the stylesheet's own URL, so\n * they need no rewrite once the stylesheet itself is loaded from the right\n * prefix (which the HTML substitution handles).\n */\nexport function connectDynamicBasePlugin(\n options: { forWorker?: boolean; workerStripPrefix?: string } = {},\n): Plugin {\n return {\n name: \"ph-connect-dynamic-base\",\n enforce: \"post\",\n renderChunk(code, chunk) {\n if (!code.includes(DYNAMIC_BASE_PLACEHOLDER)) return null;\n\n const s = new MagicString(code);\n for (const match of code.matchAll(PLACEHOLDER_LITERAL)) {\n const rest = match[2];\n s.overwrite(\n match.index,\n match.index + match[0].length,\n rest.length === 0\n ? BASE_EXPR\n : `(${BASE_EXPR}+${JSON.stringify(rest)})`,\n );\n }\n\n // Worker chunks run in their own global scope where the proxy never\n // sets the runtime global; derive it from the worker's script URL so\n // the rewritten references above resolve against the deploy base.\n if (options.forWorker) {\n s.prepend(workerPrelude(options.workerStripPrefix ?? \"\"));\n this.info(\n `dynamic-base: worker prelude prepended to ${chunk.fileName}`,\n );\n }\n\n if (!s.hasChanged()) return null;\n return { code: s.toString(), map: s.generateMap({ hires: true }) };\n },\n generateBundle(_options, bundle) {\n // A residual token in JS (a literal the regex couldn't rewrite, e.g. a\n // template interpolating after the token) or CSS (url() must stay\n // stylesheet-relative; the placeholder would ship verbatim and 404)\n // would fail silently at runtime — fail the build instead. HTML keeps\n // the token by design: the proxy substitutes it at serve time.\n for (const file of Object.values(bundle)) {\n const content =\n file.type === \"chunk\"\n ? file.code\n : file.fileName.endsWith(\".css\") && typeof file.source === \"string\"\n ? file.source\n : undefined;\n if (content?.includes(DYNAMIC_BASE_PLACEHOLDER)) {\n this.error(\n `dynamic-base: unrewritten placeholder ${DYNAMIC_BASE_PLACEHOLDER} remains in ${file.fileName}`,\n );\n }\n }\n },\n };\n}\n\nexport function escapeForRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","/**\n * Prebuild the heavy, stable Connect dependencies into a static ESM \"vendor\"\n * bundle so the dev server never runs (or holds) the dependency optimizer /\n * module graph for them.\n *\n * The reactor-project preview dev-optimizes a large UI graph (Connect itself,\n * design-system, document-engineering, reactor-browser, …) every session —\n * ~1–2 GB resident — even though those libs don't change; only the project's\n * editors do. This module builds them ONCE with `vite build` (in a throwaway\n * subprocess that exits, freeing the build's peak memory): `vite build` handles\n * CSS/asset imports, web workers, and WASM (Connect's in-browser PGlite ships\n * all three), and a multi-entry build with `preserveEntrySignatures: 'strict'`\n * dedupes shared code into shared chunks. Entries for CJS deps re-export the\n * module's named API explicitly (so `import { createRoot }` works); ESM deps\n * use `export *`. The build runs under a dynamic-base placeholder + vendor\n * segment (`connectDynamicBasePlugin`), so emitted asset/chunk URLs\n * (`new URL(…, import.meta.url)` for .wasm/.data/workers) carry the placeholder\n * and resolve at serve time to `<deploy-base>__vendor__/`, while the vendored\n * Connect's `import.meta.env.BASE_URL` resolves to the deploy base.\n *\n * The React family stays EXTERNAL (see `VENDOR_EXTERNAL`); `esmExternalRequirePlugin`\n * owns that externalization and rewrites CJS `require(\"react\")` → import. Vendor\n * chunks keep bare React imports, which the dev import map resolves to Vite's\n * pre-bundled React (`devReactImportmapPlugin`) — one React instance across the\n * vendor, the project's editors, and CDN-loaded editors.\n *\n * `devReactImportmapPlugin` consumes the result: it externalizes these\n * specifiers in the long-lived dev server, points the page import map at the\n * vendor URLs, and serves the bundle. With Connect vendored, the dev server only\n * processes the project's own `main` + local package; HMR for them is unaffected.\n */\nimport { spawn } from \"node:child_process\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { DYNAMIC_BASE_PLACEHOLDER } from \"./vite-plugins/dynamic-base.js\";\n\nexport interface VendorPrebuildOptions {\n /** Project root the vendor deps resolve from. */\n dirname: string;\n /** Specifiers to prebuild into the vendor (defaults to the dev set). */\n include?: string[];\n /** Specifiers left external to the build (defaults to the React family). */\n external?: string[];\n /** Directory to hold the static vendor bundle + import map. */\n vendorDir?: string;\n /** Filled with the failure cause when the prebuild returns null. */\n errorRef?: { message?: string };\n /**\n * The APP's base — the same string the app build uses (the dynamic-base\n * placeholder, or a normalized deploy base like \"/app/\"). The vendor's own\n * build base is this plus the vendor segment, so emitted asset URLs land\n * under <app-base>__vendor__/. Default: the dynamic placeholder + segment\n * (dev behavior). Import-map values stay base-relative; the production\n * build strips the leading slash (values then resolve against the page URL\n * under any deploy base), the dev flow prefixes its own base.\n */\n base?: string;\n /** NODE_ENV define for the vendor build (default \"development\"). */\n nodeEnv?: \"development\" | \"production\";\n}\n\n/**\n * The stable Connect libraries worth prebuilding. The React family is NOT here —\n * it's externalized from the build (see `VENDOR_EXTERNAL`) so the vendor shares\n * the dev server's single React instance via the import map.\n */\nexport const DEFAULT_VENDOR_INCLUDE = [\n \"@powerhousedao/connect\",\n \"document-model\",\n \"zod\",\n \"@powerhousedao/design-system/connect\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/document-engineering\",\n];\n\n/**\n * React-family specifiers kept external to the vendor build. The vendor's chunks\n * emit bare imports for these; `devReactImportmapPlugin`'s import map resolves\n * them to Vite's pre-bundled React, so there is exactly one React instance.\n */\nexport const VENDOR_EXTERNAL = [\n \"react\",\n \"react-dom\",\n \"react-dom/client\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n // Dev-server virtual module (bundled local packages). Connect imports it in a\n // try/catch; left external so the build doesn't try to resolve it and the dev\n // server / import map resolves it at runtime.\n \"ph-bundled-packages-virtual\",\n];\n\nexport interface PrebuiltVendor {\n vendorDir: string;\n /** import map: bare specifier -> \"/__vendor__/<entry>.js\" (base-relative). */\n imports: Record<string, string>;\n /** Resolved versions of every included + external package. */\n versions: Record<string, string>;\n}\n\n/** URL prefix the vendor bundle is served under by the dev middleware. */\nexport const VENDOR_URL_PREFIX = \"/__vendor__/\";\n\n// Vite `base` for the vendor build: dynamic-base placeholder + vendor segment.\n// connectDynamicBasePlugin rewrites it so chunk/asset URLs resolve at serve time.\nconst VENDOR_DYNAMIC_BASE = `${DYNAMIC_BASE_PLACEHOLDER}${VENDOR_URL_PREFIX.replace(/^\\/+/, \"\")}`;\n\n/**\n * Build the prebuilt vendor (once, in a throwaway subprocess) and return its dir\n * + import map. Idempotent: reuses a cached vendor built for the same dep set.\n * Returns null on any failure (caller falls back to a normal dev server).\n */\nexport async function prebuildConnectVendor(\n options: VendorPrebuildOptions,\n): Promise<PrebuiltVendor | null> {\n const include = expandIncludeSubpaths(\n options.dirname,\n options.include ?? DEFAULT_VENDOR_INCLUDE,\n );\n const external = options.external ?? VENDOR_EXTERNAL;\n const vendorDir =\n options.vendorDir ?? join(options.dirname, \"node_modules/.ph-vendor\");\n const importMapPath = join(vendorDir, \"import-map.json\");\n // A version change of any vendored dep must invalidate the cache, so the\n // resolved versions are part of the key (not just the specifier lists).\n const versionDigest = resolveVersionDigest(options.dirname, [\n ...include,\n ...external,\n ]);\n const versions = resolveDepVersions(options.dirname, [\n ...include,\n ...external,\n ]);\n const base = options.base ?? VENDOR_DYNAMIC_BASE;\n const nodeEnv = options.nodeEnv ?? \"development\";\n\n try {\n const hit = readCacheHit(importMapPath, include, external, versionDigest);\n if (hit) return { vendorDir, ...hit };\n\n // Serialize concurrent builders on a lock dir; a loser waits for the\n // winner's result instead of clobbering the shared output.\n const lockDir = `${vendorDir}.lock`;\n const lock = acquireLock(lockDir);\n if (!lock) {\n const hit = await waitForCacheHit(\n importMapPath,\n include,\n external,\n versionDigest,\n lockDir,\n );\n return hit ? { vendorDir, ...hit } : null;\n }\n\n try {\n // Recheck under the lock: another builder may have finished while we\n // were acquiring it.\n const raced = readCacheHit(\n importMapPath,\n include,\n external,\n versionDigest,\n );\n if (raced) return { vendorDir, ...raced };\n\n const result = await buildVendorAtomic(\n options.dirname,\n vendorDir,\n include,\n external,\n versionDigest,\n versions,\n base,\n nodeEnv,\n );\n return result ? { vendorDir, ...result } : null;\n } finally {\n releaseLock(lock);\n }\n } catch (err) {\n if (options.errorRef)\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n return null;\n }\n}\n\ninterface VendorCacheMeta {\n include?: string[];\n external?: string[];\n versionDigest?: string;\n imports: Record<string, string>;\n versions?: Record<string, string>;\n}\n\n// Return the cached import map + versions iff the specifier sets AND the\n// resolved-version digest all match; otherwise null (forces a rebuild).\nfunction readCacheHit(\n importMapPath: string,\n include: string[],\n external: string[],\n versionDigest: string,\n): {\n imports: Record<string, string>;\n versions: Record<string, string>;\n} | null {\n if (!existsSync(importMapPath)) return null;\n try {\n const cached = JSON.parse(\n readFileSync(importMapPath, \"utf8\"),\n ) as VendorCacheMeta;\n if (\n sameSet(cached.include, include) &&\n sameSet(cached.external, external) &&\n cached.versionDigest === versionDigest\n ) {\n return { imports: cached.imports, versions: cached.versions ?? {} };\n }\n } catch {\n // partial/corrupt import-map.json → treat as miss\n }\n return null;\n}\n\n/**\n * Resolve the installed version of each spec's owning package, deduped by\n * package name. Resolution order per spec:\n * 1. the project itself, when it IS the owning package (a self-vendoring\n * app has no node_modules self-link);\n * 2. the project's own node_modules link (works for pnpm-strict and\n * hoisted layouts alike, and — unlike `require.resolve` — for\n * ESM-only packages whose exports map has no CJS condition);\n * 3. Node's own module resolution (covers transitive installs), walking\n * the entry up to the owning package's package.json.\n * Unresolvable specs contribute a \"missing\" sentinel, unknown versions\n * \"unknown\".\n */\nfunction resolveDepVersions(\n dirname: string,\n specs: string[],\n): Record<string, string> {\n const req = createRequire(join(dirname, \"noop.js\"));\n const seen: Record<string, string> = {};\n let selfMeta: { name?: string; version?: string } | null = null;\n for (const spec of specs) {\n const { pkg } = parsePkg(spec);\n if (pkg in seen) continue;\n if (selfMeta === null) {\n try {\n selfMeta = JSON.parse(\n readFileSync(join(dirname, \"package.json\"), \"utf8\"),\n ) as { name?: string; version?: string };\n } catch {\n selfMeta = {};\n }\n }\n let version: string;\n if (\n typeof selfMeta.name === \"string\" &&\n selfMeta.name === pkg &&\n typeof selfMeta.version === \"string\"\n ) {\n version = selfMeta.version;\n } else {\n version = \"missing\";\n try {\n const pkgRoot = realpathSync(join(dirname, \"node_modules\", pkg));\n const meta = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n version = String(meta.version ?? \"unknown\");\n } catch {\n try {\n const entry = req.resolve(spec);\n // Walk up to the owning package root (entry is usually a few\n // levels below it, e.g. dist/zod.js or\n // .pnpm/<pkg>@<v>/node_modules/<pkg>/…).\n let dir = pathDirname(entry);\n for (let depth = 0; depth < 8; depth++) {\n if (existsSync(join(dir, \"package.json\"))) {\n const meta = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n version = String(meta.version ?? \"unknown\");\n break;\n }\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // leave sentinel\n }\n }\n }\n seen[pkg] = version;\n }\n return seen;\n}\n\n// Hash the resolved version of each spec's owning package (from its installed\n// package.json). A bump or branch checkout that changes any version yields a\n// different digest, invalidating the cache. Unresolvable specs contribute a\n// sentinel so they don't silently collide.\nfunction resolveVersionDigest(dirname: string, specs: string[]): string {\n const versions = resolveDepVersions(dirname, specs);\n const h = createHash(\"sha256\");\n // Fold in the build worker so a logic/build-option change busts stale bundles,\n // not just a dep version bump.\n const workerHash = createHash(\"sha256\")\n .update(VENDOR_BUILD_WORKER)\n .digest(\"hex\");\n h.update(`worker:${workerHash}\\n`);\n for (const pkg of Object.keys(versions).sort()) {\n h.update(`${pkg}@${versions[pkg]}\\n`);\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n\nfunction sameSet(a: string[] | undefined, b: string[]): boolean {\n if (!a || a.length !== b.length) return false;\n const s = new Set(a);\n return b.every((x) => s.has(x));\n}\n\n// Exclusive lock via mkdir (atomic on POSIX). The holder heartbeats an owner\n// file so a live (slow) build keeps it fresh; a crashed builder lets it go stale.\nexport const LOCK_STALE_MS = 5 * 60_000;\nconst LOCK_HEARTBEAT_MS = 60_000;\n\nexport interface VendorLock {\n dir: string;\n token: string;\n timer: ReturnType<typeof setInterval>;\n}\n\nconst ownerFile = (lockDir: string): string => join(lockDir, \"owner\");\n\n// Stale iff the owner file hasn't been heartbeated within LOCK_STALE_MS. A\n// missing owner file means a builder mid-acquire — treat as fresh, don't steal.\nfunction lockIsStale(lockDir: string): boolean {\n try {\n return Date.now() - statSync(ownerFile(lockDir)).mtimeMs > LOCK_STALE_MS;\n } catch {\n return false;\n }\n}\n\nexport function acquireLock(lockDir: string): VendorLock | null {\n let made = false;\n try {\n mkdirSync(lockDir);\n made = true;\n } catch {\n if (lockIsStale(lockDir)) {\n try {\n rmSync(lockDir, { recursive: true, force: true });\n mkdirSync(lockDir);\n made = true;\n } catch {\n // lost the reclaim race to another builder\n }\n }\n }\n if (!made) return null;\n const token = `${process.pid}-${randomUUID()}`;\n writeFileSync(ownerFile(lockDir), token);\n // Refresh mtime while we still own it; stop if a stale-reclaim handed it off.\n const timer = setInterval(() => {\n try {\n if (readFileSync(ownerFile(lockDir), \"utf8\") === token) {\n writeFileSync(ownerFile(lockDir), token);\n } else {\n clearInterval(timer);\n }\n } catch {\n clearInterval(timer);\n }\n }, LOCK_HEARTBEAT_MS);\n timer.unref();\n return { dir: lockDir, token, timer };\n}\n\n// Remove only if we still own it — a stale-reclaim may have handed the lock to\n// another builder, whose dir we must not delete.\nexport function releaseLock(lock: VendorLock): void {\n clearInterval(lock.timer);\n try {\n if (readFileSync(ownerFile(lock.dir), \"utf8\") === lock.token) {\n rmSync(lock.dir, { recursive: true, force: true });\n }\n } catch {\n // owner file gone/unreadable — leave it for the stale path\n }\n}\n\n// Loser path: poll for the winner to publish a matching import-map.json, until\n// the lock is released or a timeout elapses.\nasync function waitForCacheHit(\n importMapPath: string,\n include: string[],\n external: string[],\n versionDigest: string,\n lockDir: string,\n): Promise<{\n imports: Record<string, string>;\n versions: Record<string, string>;\n} | null> {\n const deadline = Date.now() + LOCK_STALE_MS;\n while (Date.now() < deadline) {\n const hit = readCacheHit(importMapPath, include, external, versionDigest);\n if (hit) return hit;\n if (!existsSync(lockDir)) {\n // winner finished (or gave up); one last read\n return readCacheHit(importMapPath, include, external, versionDigest);\n }\n await new Promise((r) => setTimeout(r, 250));\n }\n return null;\n}\n\n// Resolve an exports entry to the file it loads under browser/import\n// conditions, or null if none (e.g. document-model's node-only `./node`). Used\n// to skip node-only and CSS/JSON subpaths the browser-targeted build can't take.\nfunction importTarget(value: unknown): string | null {\n if (typeof value === \"string\") return value;\n if (!value || typeof value !== \"object\") return null;\n const o = value as Record<string, unknown>;\n for (const c of [\"browser\", \"import\", \"module\", \"default\"]) {\n if (c in o) {\n const t = importTarget(o[c]);\n if (t) return t;\n }\n }\n return null;\n}\n\nfunction parsePkg(spec: string): { pkg: string; sub: string } {\n if (spec.startsWith(\"@\")) {\n const parts = spec.split(\"/\");\n return { pkg: parts.slice(0, 2).join(\"/\"), sub: parts.slice(2).join(\"/\") };\n }\n const i = spec.indexOf(\"/\");\n return i === -1\n ? { pkg: spec, sub: \"\" }\n : { pkg: spec.slice(0, i), sub: spec.slice(i + 1) };\n}\n\n/**\n * Connect imports the heavy libs by subpath too (e.g.\n * `@powerhousedao/design-system/connect/toast`, `zod/v4/core`). Those bare\n * imports need their own import-map entry, so expand each listed spec to its\n * package's concrete (non-wildcard, JS) subpath exports that share the spec's\n * prefix. Unresolvable / CSS / JSON targets are skipped.\n *\n * A spec whose package isn't installed in `dirname` is dropped entirely\n * rather than kept for the worker: the worker cannot build an entry for a\n * missing package (its `await import` and the vite resolution both fail),\n * and a bare re-export entry would fail the whole vendor build. The\n * importer of a missing shared dep simply bundles its own copy.\n */\nfunction expandIncludeSubpaths(dirname: string, include: string[]): string[] {\n const out = new Set<string>();\n for (const spec of include) {\n const { pkg, sub } = parsePkg(spec);\n let exp: unknown;\n let pkgRoot: string;\n try {\n pkgRoot = realpathSync(join(dirname, \"node_modules\", pkg));\n const pkgJson = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { exports?: unknown };\n exp = pkgJson.exports;\n } catch {\n continue;\n }\n out.add(sub ? spec : pkg);\n if (!exp || typeof exp !== \"object\") continue;\n const expMap = exp as Record<string, unknown>;\n const prefixKey = sub ? `./${sub}` : \".\";\n for (const key of Object.keys(expMap)) {\n if (key.includes(\"*\") || key === \"./package.json\") continue;\n if (/\\.(css|json|scss)$/.test(key)) continue;\n const matches =\n prefixKey === \".\"\n ? key === \".\" || key.startsWith(\"./\")\n : key === prefixKey || key.startsWith(`${prefixKey}/`);\n if (!matches) continue;\n const target = importTarget(expMap[key]);\n if (!target || /\\.(css|json|scss)$/.test(target)) continue;\n // Skip subpaths whose target file isn't shipped (e.g. a `./test` export\n // pointing at unbuilt dist) — they'd fail the build.\n if (!existsSync(join(pkgRoot, target))) continue;\n out.add(key === \".\" ? pkg : pkg + key.slice(1));\n }\n }\n return [...out];\n}\n\n/**\n * The published specifiers whose entry file the vendor build never emitted.\n * URLs are base-less (`/__vendor__/x.js`) and resolve inside `vendorDir`.\n */\nexport function missingVendorEntries(\n vendorDir: string,\n imports: Record<string, string>,\n): { spec: string; url: string }[] {\n const prefix = VENDOR_URL_PREFIX;\n return Object.entries(imports)\n .filter(([, url]) => {\n const rel = url.startsWith(prefix) ? url.slice(prefix.length) : url;\n return !existsSync(join(vendorDir, rel));\n })\n .map(([spec, url]) => ({ spec, url }));\n}\n\n/**\n * Rebase the vendor's base-less entry URLs (`/__vendor__/x.js`) onto the\n * deploy base, so a consumer that resolves them against the page origin lands\n * under that base rather than the server root. A dynamic-base build keeps its\n * placeholder, which the runtime substitutes.\n *\n * `base` is the app base from `prebuildConnectVendor` callers, but the\n * VENDOR_DYNAMIC_BASE default already carries the vendor segment — that\n * trailing segment is dropped first so it is never doubled.\n */\nexport function withVendorBase(\n imports: Record<string, string>,\n base: string,\n): Record<string, string> {\n const segment = VENDOR_URL_PREFIX.replace(/^\\/+/, \"\");\n const appBase = base.endsWith(segment)\n ? base.slice(0, base.length - segment.length)\n : base;\n return Object.fromEntries(\n Object.entries(imports).map(([spec, url]) => [\n spec,\n `${appBase}/${url}`\n .replace(/([^:])\\/{2,}/g, \"$1/\")\n .replace(/^\\/{2,}/, \"/\"),\n ]),\n );\n}\n\n/**\n * Build the vendor into a unique temp dir, then atomically swap it into place,\n * so a concurrent reader never sees a partial bundle or import-map.json. Runs\n * the build in a throwaway subprocess (its peak memory is reclaimed on exit);\n * the parent augments the import map with the version digest + the version\n * table, writes the runtime shared-deps module, and does the swap.\n * Returns the published import map + versions, or null on failure.\n */\nasync function buildVendorAtomic(\n dirname: string,\n vendorDir: string,\n include: string[],\n external: string[],\n versionDigest: string,\n versions: Record<string, string>,\n base: string,\n nodeEnv: \"development\" | \"production\",\n): Promise<{\n imports: Record<string, string>;\n versions: Record<string, string>;\n} | null> {\n const parent = pathDirname(vendorDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-vendor.tmp-\"));\n try {\n const { ok, stderr } = await runBuildWorker(\n dirname,\n tmpDir,\n include,\n external,\n base,\n nodeEnv,\n );\n const tmpMap = join(tmpDir, \"import-map.json\");\n if (!ok || !existsSync(tmpMap)) {\n const detail = stderr.trim();\n throw new Error(\n `vendor build failed${detail ? `:\\n${detail}` : \" (no output captured)\"}`,\n );\n }\n // Stamp the version digest + version table into the published metadata so\n // the cache check can detect a dep bump and cache hits restore versions.\n const meta = JSON.parse(readFileSync(tmpMap, \"utf8\")) as VendorCacheMeta;\n // Every published specifier must have a file behind it. An entry the map\n // claims but the build never emitted becomes a bare import the app\n // externalizes onto a URL that 404s — and since a SPA answers an unknown\n // path with index.html, the browser reports only an opaque MIME-type\n // error. Fail the build here, where the missing entries can be named.\n const unbacked = missingVendorEntries(tmpDir, meta.imports);\n if (unbacked.length > 0) {\n throw new Error(\n `vendor build published ${unbacked.length} import-map ` +\n `${unbacked.length === 1 ? \"entry\" : \"entries\"} with no file behind ` +\n `${unbacked.length === 1 ? \"it\" : \"them\"}:\\n` +\n unbacked.map((e) => ` ${e.spec} -> ${e.url}`).join(\"\\n\"),\n );\n }\n meta.versionDigest = versionDigest;\n meta.versions = versions;\n writeFileSync(tmpMap, JSON.stringify(meta, null, 2));\n\n // The runtime data module: a real .js (not .json) so the Workbox precache\n // glob picks it up and the main thread can dynamic-import it without\n // import attributes.\n //\n // Its URLs carry the build's base (import-map.json stays base-less\n // because the dev plugin applies the base itself). The worker resolves\n // these against the page origin, so a base-less path would point at\n // /__vendor__/ on a subpath deploy and 404.\n writeFileSync(\n join(tmpDir, \"shared-deps.js\"),\n `export const imports = ${JSON.stringify(\n withVendorBase(meta.imports, base),\n )};\\n` + `export const versions = ${JSON.stringify(versions)};\\n`,\n );\n\n // Swap: move any existing dir aside, rename temp into place, drop the old.\n const oldDir = `${vendorDir}.old-${process.pid}-${Date.now()}`;\n if (existsSync(vendorDir)) renameSync(vendorDir, oldDir);\n renameSync(tmpDir, vendorDir);\n // mkdtemp creates the staging dir 0700, and the rename carries that mode\n // onto the published vendor. The build and the server are not always the\n // same user — in a container image the build runs as root and nginx as\n // `nginx` — and a directory nobody else can traverse makes every vendor\n // URL unreadable. A SPA then answers each one with index.html, so the\n // browser reports an opaque MIME-type error and the whole shared-dep\n // mechanism is silently inert. Publish it as readable as the rest of the\n // build output.\n chmodSync(vendorDir, 0o755);\n rmSync(oldDir, { recursive: true, force: true });\n return { imports: meta.imports, versions };\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw err;\n }\n}\n\n// The worker imports connectDynamicBasePlugin from this module's own loadable\n// form. In the published/built bundle that is import.meta.url itself; when\n// running from source (vitest), node cannot load the .ts graph, so fall back\n// to the package's built entry (dist/index.mjs).\nfunction resolveSelfModulePath(): string {\n const selfPath = fileURLToPath(import.meta.url);\n if (!selfPath.endsWith(\".ts\")) return selfPath;\n let dir = pathDirname(selfPath);\n for (let depth = 0; depth < 4; depth++) {\n const candidate = join(dir, \"dist\", \"index.mjs\");\n if (existsSync(candidate)) return candidate;\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"vendor build needs the built builder-tools bundle (dist/index.mjs); build the package first\",\n );\n}\n\n/**\n * Spawn a throwaway worker that generates one entry per specifier (CJS deps get\n * explicit named re-exports, ESM deps `export *`), `vite build`s them into the\n * given out dir, and writes the import map. Captures stdout/stderr so a failure\n * is debuggable; the normal path stays quiet.\n */\nfunction runBuildWorker(\n dirname: string,\n outDir: string,\n include: string[],\n external: string[],\n base: string,\n nodeEnv: \"development\" | \"production\",\n): Promise<{ ok: boolean; stderr: string }> {\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, VENDOR_BUILD_WORKER);\n // A path the worker (raw node) can import to get connectDynamicBasePlugin:\n // the built bundle itself, or the built package entry when this module is\n // being run from source (vitest).\n const selfModulePath = resolveSelfModulePath();\n return new Promise((resolve) => {\n const child = spawn(\n process.execPath,\n [\n workerPath,\n dirname,\n outDir,\n JSON.stringify(include),\n VENDOR_URL_PREFIX,\n JSON.stringify(external),\n VENDOR_DYNAMIC_BASE,\n selfModulePath,\n base,\n nodeEnv,\n ],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let stderr = \"\";\n child.stdout.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.stderr.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.on(\"exit\", (code) => resolve({ ok: code === 0, stderr }));\n child.on(\"error\", (e) => resolve({ ok: false, stderr: String(e) }));\n });\n}\n\n/**\n * The vendor build worker, written to disk and run as a subprocess. Loads\n * `vite` from the project and `connectDynamicBasePlugin` from builder-tools' own\n * built bundle (selfModulePath). argv: dirname, vendorDir, includeJSON,\n * urlPrefix, externalJSON, dynamicBase, selfModulePath, base (app base),\n * nodeEnv.\n */\nconst VENDOR_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { mkdirSync, writeFileSync, rmSync } from 'node:fs';\nimport { join, isAbsolute } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nconst [dirname, vendorDir, includeJSON, urlPrefix, externalJSON, dynamicBase, selfModulePath, baseArg, nodeEnvArg] = process.argv.slice(2);\n// Trailing argv are optional (older callers): base defaults to the dynamic\n// placeholder behavior, nodeEnv to development. baseArg is the APP base —\n// the same string the app build uses; the build base appends the vendor\n// segment so emitted asset URLs land under <app-base>__vendor__/.\nconst segment = urlPrefix.replace(/^\\\\/+/, '');\nconst base = baseArg ? baseArg + segment : dynamicBase;\nconst nodeEnv = nodeEnvArg ?? 'development';\nconst include = JSON.parse(includeJSON);\nconst external = JSON.parse(externalJSON ?? '[]');\nconst externalSet = new Set(external);\nconst reqProj = createRequire(join(dirname, 'noop.js'));\n// pathToFileURL: require.resolve returns an absolute path, and on Windows\n// import('D:\\\\...') parses \"D:\" as a URL scheme (ERR_UNSUPPORTED_ESM_URL_SCHEME).\nconst { build, esmExternalRequirePlugin } = await import(pathToFileURL(reqProj.resolve('vite')).href);\n// Load the dynamic-base plugin from builder-tools' own built bundle (passed as\n// an absolute path) — it isn't resolvable as a bare specifier from the worker.\nconst { connectDynamicBasePlugin, DYNAMIC_BASE_PLACEHOLDER } = await import(pathToFileURL(selfModulePath));\nconst srcDir = join(vendorDir, '.entries');\nmkdirSync(srcDir, { recursive: true });\nconst entryName = (spec) => spec.replace(/[^\\\\w]+/g, '_');\nconst RESERVED = new Set('enum void null function in instanceof typeof new delete do if else return switch case break continue for while this true false class const let var default export import extends super with yield debugger finally throw try catch await implements interface package private protected public static eval arguments'.split(' '));\nconst input = {};\nfor (const spec of include) {\n const name = entryName(spec);\n let src;\n try {\n // Import the bare spec (not reqProj.resolve(spec)) so Node picks the same\n // import/browser-condition module the build resolves — resolving first can\n // pick a CJS sibling whose default-export shape differs from the ESM build.\n const ns = await import(spec);\n // Only fall back to re-exporting from default when the module exposes NO\n // top-level named exports (a true CJS-interop module). If it does (e.g. zod\n // exposes \\`z\\`), \\`export *\\` captures them; destructuring default would miss\n // top-level names that aren't keys of the default object.\n const named = Object.keys(ns).filter((k) => k !== 'default');\n const cjs = named.length === 0 && ns.default && typeof ns.default === 'object';\n if (cjs) {\n const names = Object.keys(ns.default).filter((k) => k !== 'default' && k !== '__esModule' && /^[A-Za-z_$][\\\\w$]*$/.test(k));\n const plain = names.filter((n) => !RESERVED.has(n));\n const reserved = names.filter((n) => RESERVED.has(n));\n src = 'import d from ' + JSON.stringify(spec) + ';\\\\nexport default d;\\\\n'\n + (plain.length ? 'export const { ' + plain.join(', ') + ' } = d;\\\\n' : '');\n // reserved words are invalid as const-binding names but valid as export\n // aliases (export { x as enum }).\n reserved.forEach((n, i) => {\n src += 'const __r' + i + ' = d[' + JSON.stringify(n) + '];\\\\nexport { __r' + i + ' as ' + n + ' };\\\\n';\n });\n } else {\n src = 'export * from ' + JSON.stringify(spec) + ';\\\\n'\n + (('default' in ns) ? 'export { default } from ' + JSON.stringify(spec) + ';\\\\n' : '');\n }\n } catch {\n src = 'export * from ' + JSON.stringify(spec) + ';\\\\n';\n }\n const file = join(srcDir, name + '.js');\n writeFileSync(file, src);\n input[name] = file;\n}\n// Prefer the bundler's browser-condition-aware resolution; fall back to resolving\n// from the worker (real install path) only for Rolldown's realpath-anchoring bug.\nconst phResolveCache = new Map();\nconst phVendorResolve = {\n name: 'ph-vendor-resolve', enforce: 'pre',\n async resolveId(source, importer, options) {\n if (externalSet.has(source)) return null;\n if (source[0] === '\\\\0' || source[0] === '.' || isAbsolute(source)) return null;\n if (source.startsWith('node:') || source.startsWith('data:')) return null;\n let viaBundler = null;\n try { viaBundler = await this.resolve(source, importer, { ...options, skipSelf: true }); } catch {}\n if (viaBundler) return viaBundler;\n if (phResolveCache.has(source)) return phResolveCache.get(source);\n let resolved = null;\n try { resolved = fileURLToPath(import.meta.resolve(source)); } catch {}\n phResolveCache.set(source, resolved);\n return resolved;\n },\n};\nawait build({\n root: dirname, configFile: false, logLevel: 'error',\n // Caller-provided build base (or the dynamic placeholder default):\n // connectDynamicBasePlugin rewrites emitted chunk/asset URLs to resolve\n // against the deploy base at serve time.\n base,\n define: {\n 'process.env.NODE_ENV': JSON.stringify(nodeEnv),\n // BASE_URL resolves to the deploy base (not the vendor prefix) so vendored\n // Connect's router basename + BASE_URL-relative fetches use the right path.\n // The app base when provided (concrete or placeholder), the placeholder\n // otherwise (dev flow — rewritten at serve time by the dynamic-base plugin).\n 'import.meta.env.BASE_URL': JSON.stringify(baseArg ?? DYNAMIC_BASE_PLACEHOLDER),\n },\n // phVendorResolve (pre) resolves bares from the worker; esmExternalRequirePlugin owns\n // react/virtual externalization; connectDynamicBasePlugin (post) rewrites the placeholder base.\n plugins: [phVendorResolve, esmExternalRequirePlugin({ external }), connectDynamicBasePlugin()],\n // pglite ships web workers as ES-module chunks. workerStripPrefix is the vendor\n // segment so the worker recovers the deploy base, not the vendor prefix.\n worker: { format: 'es', plugins: () => [connectDynamicBasePlugin({ forWorker: true, workerStripPrefix: urlPrefix.replace(/^\\\\/+/, '') })] },\n build: {\n // Production ships this to every visitor, so minify it like the app's own\n // chunks; dev keeps readable output and the faster build.\n outDir: vendorDir, emptyOutDir: false, minify: nodeEnv === 'production', target: 'esnext', cssCodeSplit: true,\n rollupOptions: {\n input, preserveEntrySignatures: 'strict',\n output: { format: 'es', entryFileNames: '[name].js', chunkFileNames: 'chunks/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]' },\n },\n },\n});\nrmSync(srcDir, { recursive: true, force: true });\nconst imports = {};\nfor (const spec of include) imports[spec] = urlPrefix + entryName(spec) + '.js';\nwriteFileSync(join(vendorDir, 'import-map.json'), JSON.stringify({ include, external, imports }, null, 2));\n`;\n","/**\n * Prebuild Connect's reactor SharedWorker into a browser-loadable bundle.\n *\n * The published `@powerhousedao/connect` dist ships `reactor.worker.js` as a\n * library artifact: its dependencies are externalized onto bare specifiers\n * (`@powerhousedao/reactor`, `kysely`, ...). The page resolves those through\n * its `<script type=\"importmap\">`, but import maps are a document feature —\n * a worker never inherits one and no Worker/SharedWorker constructor option\n * can supply one. A bare specifier inside a worker is unresolvable by the\n * platform, so the shipped file can never run as a worker script.\n *\n * This module builds the worker's module graph into a self-contained bundle\n * (one `vite build` in a throwaway subprocess, same pattern as the vendor\n * prebuild). Two modes:\n *\n * - With `vendorImports` (production builds that also ship the `__vendor__/`\n * bundle): specifiers present in the vendor import map are externalized and\n * rewritten to `../__vendor__/<entry>.js`. The worker bundle is served as a\n * sibling of `__vendor__/`, so those relative imports hit the exact URLs\n * the page's import map uses — one fetch and one HTTP-cache entry per\n * shared dep for the page and the worker together.\n * - Without (dev servers, `PH_CONNECT_VENDOR=0` builds): everything is\n * bundled; the worker is self-contained.\n *\n * The build uses Vite's relative base (`\"./\"`), so emitted chunk and asset\n * URLs resolve against the worker script's own URL. That sidesteps the\n * dynamic-base machinery entirely: the bundle works under any deploy base,\n * concrete or proxy-substituted, as long as it is served under\n * `<app-base>/__reactor_worker__/`.\n */\nimport { createHash } from \"node:crypto\";\nimport { spawn } from \"node:child_process\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n acquireLock,\n LOCK_STALE_MS,\n releaseLock,\n} from \"./externalize-vendor.js\";\n\n/** URL prefix the worker bundle is served under, next to `__vendor__/`. */\nexport const REACTOR_WORKER_URL_PREFIX = \"/__reactor_worker__/\";\n\n/** Entry filename of the bundle; the tab constructs its SharedWorker from it. */\nexport const REACTOR_WORKER_ENTRY = \"reactor.worker.js\";\n\n/** Metadata file the cache check reads; lives inside the bundle dir. */\nconst META_FILE = \"worker-meta.json\";\n\n/** Content-Type for the extensions the worker build emits; JS is the default. */\nexport const REACTOR_WORKER_MIME: Record<string, string> = {\n \".map\": \"application/json\",\n \".json\": \"application/json\",\n \".wasm\": \"application/wasm\",\n \".data\": \"application/octet-stream\",\n};\n\nexport interface ReactorWorkerVendorOptions {\n /** The vendor's import map (`spec -> /__vendor__/<entry>.js`). */\n imports: Record<string, string>;\n /** The built vendor dir, needed to verify which entries are worker-safe. */\n dir: string;\n}\n\nexport interface ReactorWorkerBuildOptions {\n /** Project root the worker's dependencies resolve from. */\n dirname: string;\n /** Directory to hold the bundle (e.g. `<dist>/__reactor_worker__`). */\n outDir: string;\n /**\n * The prebuilt vendor to share dependencies with. Only the worker-safe\n * subset of its entries is externalized (see\n * {@link workerSafeVendorImports}); omit to bundle everything.\n */\n vendor?: ReactorWorkerVendorOptions;\n /**\n * Worker entry to build. Defaults to the installed Connect dist's\n * `reactor.worker.js`; tests inject a fixture entry here.\n */\n entryPath?: string;\n /** NODE_ENV define for the build (default \"development\"). */\n nodeEnv?: \"development\" | \"production\";\n /** Filled with the failure cause when the prebuild returns null. */\n errorRef?: { message?: string };\n}\n\nexport interface PrebuiltReactorWorker {\n outDir: string;\n /** Entry filename inside outDir ({@link REACTOR_WORKER_ENTRY}). */\n entry: string;\n /**\n * Digest of everything that shaped this bundle's output (see\n * {@link computeSourceDigest}); identical for a cache hit and a fresh\n * build. The dev plugin serves it in `worker-meta.json` next to the\n * bundle; `apps/connect/src/utils/reactor-worker-url.ts` fetches it to\n * fold the actual built worker code into the tab's version fingerprint\n * (W0.6).\n */\n sourceDigest: string;\n /**\n * The worker-safe vendor subset this bundle externalizes (see\n * {@link workerSafeVendorImports}); empty without a vendor.\n */\n vendorImports: Record<string, string>;\n}\n\n/**\n * The installed Connect dist's worker entry, or null when the installed\n * version predates the worker (the feature is then unavailable, not broken).\n */\nexport function resolveReactorWorkerSource(dirname: string): string | null {\n try {\n const candidate = join(\n realpathSync(join(dirname, \"node_modules\", \"@powerhousedao/connect\")),\n \"dist\",\n REACTOR_WORKER_ENTRY,\n );\n return existsSync(candidate) ? candidate : null;\n } catch {\n return null;\n }\n}\n\n/** `/__vendor__/<entry>.js` -> `../__vendor__/<entry>.js` (sibling dirs). */\nexport function vendorRelativePath(vendorUrl: string): string {\n const file = vendorUrl.slice(vendorUrl.lastIndexOf(\"/\") + 1);\n return `../__vendor__/${file}`;\n}\n\n// Import/export specifier positions in emitted ES output, minified included:\n// static imports/re-exports, side-effect imports, and dynamic import(). The\n// lookbehind keeps member calls like `map.import(\"x\")` out.\nconst SPECIFIER_PATTERNS = [\n /(?<![.\\w$])import\\s*\\(\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])import\\s*[^\"'()]*?from\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])export\\s*[^\"'()]*?from\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])import\\s*[\"']([^\"']+)[\"']/g,\n];\n\n/**\n * Module specifiers a worker cannot resolve: anything that is not relative,\n * root-relative, or an http(s)/data/blob URL. Used as a post-build guard so a\n * leftover bare (or `node:`) import fails the build with a name instead of\n * shipping a worker that dies on its first import statement.\n *\n * Expects minified (comment-free) output: a raw-text scan cannot tell a real\n * import from a JSDoc code sample, and unminified kysely/viem are full of the\n * latter. The build below always minifies for exactly this reason.\n */\nexport function findDisallowedSpecifiers(code: string): string[] {\n const found = new Set<string>();\n for (const pattern of SPECIFIER_PATTERNS) {\n for (const match of code.matchAll(pattern)) {\n const spec = match[1];\n if (\n !spec.startsWith(\"./\") &&\n !spec.startsWith(\"../\") &&\n !spec.startsWith(\"/\") &&\n !/^(https?:|data:|blob:)/.test(spec)\n ) {\n found.add(spec);\n }\n }\n }\n return [...found].sort();\n}\n\ninterface WorkerBundleMeta {\n sourceDigest?: string;\n vendorKey?: string;\n nodeEnv?: string;\n}\n\n/**\n * Fallback list of packages whose BUILT dist shapes the worker bundle's output,\n * used only when the installed Connect's package.json cannot be read (see\n * {@link upstreamWorkerPackages}).\n */\nconst FALLBACK_UPSTREAM_WORKER_PACKAGES = [\n \"@powerhousedao/reactor\",\n \"@powerhousedao/reactor-browser\",\n];\n\n/** Dependency scopes whose installed dist can change the bundle's output. */\nconst UPSTREAM_SCOPES = [\"@powerhousedao/\", \"@renown/\"];\n\n/**\n * Packages whose BUILT dist shapes the worker bundle's output even when\n * connect's own dist/reactor.worker.js entry file did not change.\n *\n * That entry is a library artifact whose bare imports this build resolves\n * through node_modules at BUILD time, so a rebuilt dist anywhere in its\n * closure changes the bundle output without touching the entry file's own\n * size/mtime. The list is DERIVED from the installed Connect's own\n * dependencies rather than hardcoded: the bundle pulls `@renown/sdk`,\n * `@powerhousedao/powerhouse-vetra-packages` and `@powerhousedao/shared` out\n * of node_modules too, and a hardcoded pair left every one of those able to be\n * rebuilt behind a cache hit. Connect's dependency list is the cheap stand-in\n * for the resolved bundle graph: every workspace package the worker can reach\n * is reachable through it, and a package not in the bundle only costs a readdir.\n */\nexport function upstreamWorkerPackages(dirname: string): string[] {\n const connectDir = resolveWorkspacePackageDir(\n dirname,\n \"@powerhousedao/connect\",\n );\n if (!connectDir) return [...FALLBACK_UPSTREAM_WORKER_PACKAGES];\n let meta: { dependencies?: Record<string, string> };\n try {\n meta = JSON.parse(\n readFileSync(join(connectDir, \"package.json\"), \"utf8\"),\n ) as { dependencies?: Record<string, string> };\n } catch {\n return [...FALLBACK_UPSTREAM_WORKER_PACKAGES];\n }\n const names = Object.keys(meta.dependencies ?? {}).filter((name) =>\n UPSTREAM_SCOPES.some((scope) => name.startsWith(scope)),\n );\n for (const name of FALLBACK_UPSTREAM_WORKER_PACKAGES) {\n if (!names.includes(name)) names.push(name);\n }\n return names.sort();\n}\n\n/**\n * This module's own installed version, read by walking up from its file to\n * the nearest `package.json` named \"@powerhousedao/builder-tools\" (same\n * technique as `build-hash.ts`'s `readConnectVersion`: builder-tools'\n * `exports` map has no `./package.json` subpath, so node resolution can't\n * get there). Works whether this runs from source (tests, this monorepo) or\n * the built dist.\n */\nexport function resolveOwnPackageVersion(): string {\n try {\n let dir = pathDirname(fileURLToPath(import.meta.url));\n for (;;) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as { name?: string; version?: string };\n if (pkg.name === \"@powerhousedao/builder-tools\") {\n return pkg.version ?? \"unknown\";\n }\n } catch {\n // no readable package.json at this level; keep walking up\n }\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // fall through to \"unknown\" below\n }\n return \"unknown\";\n}\n\n/**\n * This package's own version, computed once. Folded into the worker bundle\n * cache key so a builder-tools release — which can change how the bundle is\n * built (anything in this module beyond {@link WORKER_BUILD_WORKER} itself,\n * e.g. `workerSafeVendorImports`, the resolve plugin) — invalidates bundles\n * a prior builder-tools version cached.\n */\nexport const BUILDER_TOOLS_VERSION = resolveOwnPackageVersion();\n\n/**\n * A workspace package's real directory, resolved the way Node's resolver\n * would (through `node_modules`), or null when it is not installed (e.g. a\n * non-monorepo consumer project — graceful, not an error). pnpm's\n * node_modules symlinks resolve to the real package directory, so this\n * reflects the monorepo's actual dist state, not a stale symlink target.\n */\nexport function resolveWorkspacePackageDir(\n dirname: string,\n pkgName: string,\n): string | null {\n try {\n return realpathSync(join(dirname, \"node_modules\", ...pkgName.split(\"/\")));\n } catch {\n return null;\n }\n}\n\n/**\n * Cheap content fingerprint of a directory's immediate files: no file bytes\n * are read, just each entry's name/size/mtime, so it stays fast even for a\n * large dist. Sensitive to a rebuild in the common cases: Vite's\n * content-hashed chunk filenames change the name itself; a stable-named file\n * (an entry point) changes size or mtime. Bounded (`maxFiles`) so a\n * pathological directory cannot make this slow — deliberately not a\n * full-tree hash.\n *\n * The names are sorted BEFORE the bound is applied, so the subset the bound\n * keeps is the same subset on every run: readdir order is unspecified, and\n * truncating it first made the fingerprint of a directory past the bound a\n * function of whatever order the filesystem happened to report.\n */\nexport function distDirFingerprint(dir: string, maxFiles = 1000): string {\n try {\n const names = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name)\n .sort();\n return names\n .slice(0, maxFiles)\n .map((name) => {\n const stat = statSync(join(dir, name));\n return `${name}:${stat.size}:${Math.round(stat.mtimeMs)}`;\n })\n .join(\"|\");\n } catch {\n return \"unreadable\";\n }\n}\n\n// Digest of everything that shapes the output: the connect dist the entry\n// comes from (version + entry mtime/size cover a rebuild in place), the\n// upstream packages the entry's bare imports resolve into at build time\n// (dist fingerprint, over the list {@link upstreamWorkerPackages} derives —\n// covers an upstream rebuild that never touched connect's own dist), the\n// vendor the externals point at (its\n// import-map.json changes whenever the vendor is rebuilt), NODE_ENV, the\n// build-worker source, and the builder-tools version, so a logic change\n// (in either the inline build-worker script or this module more broadly)\n// busts stale bundles.\nexport function computeSourceDigest(\n dirname: string,\n entryPath: string,\n vendorDir?: string,\n builderToolsVersion: string = BUILDER_TOOLS_VERSION,\n): string {\n const h = createHash(\"sha256\");\n h.update(`builder:${WORKER_BUILD_WORKER_HASH}\\n`);\n h.update(`builder-tools:${builderToolsVersion}\\n`);\n try {\n const pkgRoot = resolveWorkspacePackageDir(\n dirname,\n \"@powerhousedao/connect\",\n );\n if (!pkgRoot) throw new Error(\"unresolved\");\n const meta = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n h.update(`connect:${meta.version ?? \"unknown\"}\\n`);\n } catch {\n h.update(\"connect:unresolved\\n\");\n }\n try {\n const stat = statSync(entryPath);\n h.update(`entry:${stat.size}:${Math.round(stat.mtimeMs)}\\n`);\n } catch {\n h.update(\"entry:unstatable\\n\");\n }\n for (const pkg of upstreamWorkerPackages(dirname)) {\n const pkgDir = resolveWorkspacePackageDir(dirname, pkg);\n h.update(\n `${pkg}:${pkgDir ? distDirFingerprint(join(pkgDir, \"dist\")) : \"unresolved\"}\\n`,\n );\n }\n if (vendorDir) {\n try {\n h.update(\n `vendor:${createHash(\"sha256\")\n .update(readFileSync(join(vendorDir, \"import-map.json\")))\n .digest(\"hex\")}\\n`,\n );\n } catch {\n h.update(\"vendor:unreadable\\n\");\n }\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n\nfunction vendorKeyOf(vendorImports: Record<string, string>): string {\n const entries = Object.entries(vendorImports).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n return createHash(\"sha256\")\n .update(JSON.stringify(entries))\n .digest(\"hex\")\n .slice(0, 16);\n}\n\nfunction readWorkerCacheHit(\n metaPath: string,\n sourceDigest: string,\n vendorKey: string,\n nodeEnv: string,\n): boolean {\n if (!existsSync(metaPath)) return false;\n try {\n const cached = JSON.parse(\n readFileSync(metaPath, \"utf8\"),\n ) as WorkerBundleMeta;\n return (\n cached.sourceDigest === sourceDigest &&\n cached.vendorKey === vendorKey &&\n cached.nodeEnv === nodeEnv &&\n existsSync(join(pathDirname(metaPath), REACTOR_WORKER_ENTRY))\n );\n } catch {\n return false;\n }\n}\n\nasync function waitForWorkerCacheHit(\n metaPath: string,\n sourceDigest: string,\n vendorKey: string,\n nodeEnv: string,\n lockDir: string,\n): Promise<boolean> {\n const deadline = Date.now() + LOCK_STALE_MS;\n while (Date.now() < deadline) {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return true;\n }\n if (!existsSync(lockDir)) {\n return readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv);\n }\n await new Promise((r) => setTimeout(r, 250));\n }\n return false;\n}\n\n/**\n * Build the worker bundle (once, in a throwaway subprocess) into `outDir`.\n * Idempotent: reuses a cached bundle built from the same connect dist, vendor\n * mapping, and builder logic. Returns null on failure (`errorRef` carries the\n * cause) or when the installed Connect has no worker entry.\n */\nexport async function prebuildReactorWorker(\n options: ReactorWorkerBuildOptions,\n): Promise<PrebuiltReactorWorker | null> {\n const entryPath =\n options.entryPath ?? resolveReactorWorkerSource(options.dirname);\n if (!entryPath) {\n if (options.errorRef) {\n options.errorRef.message =\n \"the installed @powerhousedao/connect ships no dist/reactor.worker.js\";\n }\n return null;\n }\n const vendorImports = options.vendor\n ? workerSafeVendorImports(options.vendor.dir, options.vendor.imports)\n : {};\n const nodeEnv = options.nodeEnv ?? \"development\";\n const outDir = options.outDir;\n const metaPath = join(outDir, META_FILE);\n const sourceDigest = computeSourceDigest(\n options.dirname,\n entryPath,\n options.vendor?.dir,\n );\n const vendorKey = vendorKeyOf(vendorImports);\n const result: PrebuiltReactorWorker = {\n outDir,\n entry: REACTOR_WORKER_ENTRY,\n sourceDigest,\n vendorImports,\n };\n\n try {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return result;\n }\n\n const lockDir = `${outDir}.lock`;\n const lock = acquireLock(lockDir);\n if (!lock) {\n const hit = await waitForWorkerCacheHit(\n metaPath,\n sourceDigest,\n vendorKey,\n nodeEnv,\n lockDir,\n );\n return hit ? result : null;\n }\n\n try {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return result;\n }\n await buildWorkerAtomic(\n options.dirname,\n outDir,\n entryPath,\n vendorImports,\n nodeEnv,\n { sourceDigest, vendorKey, nodeEnv },\n );\n return result;\n } finally {\n releaseLock(lock);\n }\n } catch (err) {\n if (options.errorRef) {\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n }\n return null;\n }\n}\n\nasync function buildWorkerAtomic(\n dirname: string,\n outDir: string,\n entryPath: string,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n meta: WorkerBundleMeta,\n): Promise<void> {\n const parent = pathDirname(outDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-reactor-worker.tmp-\"));\n try {\n const { ok, stderr } = await runWorkerBuild(\n dirname,\n tmpDir,\n { \"reactor.worker\": entryPath },\n vendorImports,\n nodeEnv,\n );\n if (!ok || !existsSync(join(tmpDir, REACTOR_WORKER_ENTRY))) {\n const detail = stderr.trim();\n throw new Error(\n `reactor worker build failed${detail ? `:\\n${detail}` : \" (no output captured)\"}`,\n );\n }\n\n // A worker dies on its first unresolvable import, and the browser reports\n // only an opaque load failure. Fail here instead, naming the specifiers.\n assertWorkerResolvable(tmpDir);\n\n writeFileSync(join(tmpDir, META_FILE), JSON.stringify(meta, null, 2));\n publishDirAtomic(tmpDir, outDir);\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw err;\n }\n}\n\n/** Replace `outDir` with the finished `tmpDir`, old contents removed last. */\nexport function publishDirAtomic(tmpDir: string, outDir: string): void {\n const oldDir = `${outDir}.old-${process.pid}-${Date.now()}`;\n if (existsSync(outDir)) renameSync(outDir, oldDir);\n renameSync(tmpDir, outDir);\n // mkdtemp creates 0700; the build and the server are not always the same\n // user (see the vendor swap for the full story).\n chmodSync(outDir, 0o755);\n rmSync(oldDir, { recursive: true, force: true });\n}\n\n// Relative specifiers in import positions, used to walk the emitted graph.\nconst RELATIVE_SPECIFIER_PATTERNS = SPECIFIER_PATTERNS;\n\nfunction findRelativeSpecifiers(code: string): string[] {\n const found = new Set<string>();\n for (const pattern of RELATIVE_SPECIFIER_PATTERNS) {\n for (const match of code.matchAll(pattern)) {\n const spec = match[1];\n if (spec.startsWith(\"./\") || spec.startsWith(\"../\")) found.add(spec);\n }\n }\n return [...found];\n}\n\n// Normalize a bundle-relative path: forward slashes, `.`/`..` folded. Paths\n// escaping the bundle (e.g. the ../__vendor__/ externals) come back empty.\nfunction normalizeBundlePath(fromFile: string, spec: string): string {\n const segments = fromFile.split(\"/\").slice(0, -1);\n for (const part of spec.split(\"/\")) {\n if (part === \"\" || part === \".\") continue;\n if (part === \"..\") {\n if (segments.length === 0) return \"\";\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return segments.join(\"/\");\n}\n\n/**\n * Scan the emitted JS files REACHABLE from the entry via import statements\n * for specifiers a worker cannot resolve. Vendor externals were rewritten to\n * ../__vendor__/ relative paths, so anything bare that survives in the graph\n * is a real defect.\n *\n * Deliberately a graph walk, not a directory walk: the bundled reactor code\n * carries `new URL(..., import.meta.url)` references to its node\n * worker-thread entries (executor/projection workers), which Vite emits as\n * stray assets full of node-only imports. They are unreachable dead weight in\n * a browser bundle — the production vendor output tolerates the same files —\n * and must not fail the build.\n */\nexport function findBundleSpecifierOffenders(\n bundleDir: string,\n entry: string = REACTOR_WORKER_ENTRY,\n): { file: string; specs: string[] }[] {\n const offenders: { file: string; specs: string[] }[] = [];\n walkBundleGraph(bundleDir, entry, (file, code) => {\n const specs = findDisallowedSpecifiers(code);\n if (specs.length > 0) offenders.push({ file, specs });\n return true;\n });\n return offenders;\n}\n\n// Visits each JS file reachable from `entry` via relative imports. Stops and\n// returns false as soon as `visit` does.\nfunction walkBundleGraph(\n bundleDir: string,\n entry: string,\n visit: (file: string, code: string) => boolean,\n): boolean {\n const seen = new Set<string>();\n const queue = [entry];\n while (queue.length > 0) {\n const rel = queue.shift()!;\n if (seen.has(rel)) continue;\n seen.add(rel);\n const full = join(bundleDir, rel);\n if (!existsSync(full) || statSync(full).isDirectory()) continue;\n if (!rel.endsWith(\".js\") && !rel.endsWith(\".mjs\")) continue;\n const code = readFileSync(full, \"utf8\");\n if (!visit(rel, code)) return false;\n for (const spec of findRelativeSpecifiers(code)) {\n const next = normalizeBundlePath(rel, spec);\n if (next) queue.push(next);\n }\n }\n return true;\n}\n\nfunction assertWorkerResolvable(bundleDir: string): void {\n const offenders = findBundleSpecifierOffenders(bundleDir);\n if (offenders.length > 0) {\n throw new Error(\n \"reactor worker bundle contains module specifiers a worker cannot resolve:\\n\" +\n offenders.map((o) => ` ${o.file}: ${o.specs.join(\", \")}`).join(\"\\n\"),\n );\n }\n}\n\n// Page-only code that survives minification: the dynamic-base expression\n// (`(globalThis.__PH_DYNAMIC_BASE__||\"/\")`, set by the serving proxy on the\n// main thread only) and the event Vite's preload helper dispatches on\n// `window` (the helper also appends `<link>` tags to `document`).\nconst WORKER_UNSAFE_MARKERS = [\"__PH_DYNAMIC_BASE__\", \"vite:preloadError\"];\n\n/** The page-only markers present in `code`, in a fixed order. */\nexport function findWorkerUnsafeMarkers(code: string): string[] {\n return WORKER_UNSAFE_MARKERS.filter((marker) => code.includes(marker));\n}\n\n/**\n * The subset of the vendor's entries a worker may import.\n *\n * The vendor build keeps the React family external: its chunks carry bare\n * `import \"react\"` statements that the PAGE resolves through its import map.\n * A worker resolves no import map, so externalizing a vendor spec whose chunk\n * closure reaches such an import would kill the worker on its first load —\n * and the chunk graph is shared across vendor entries, so even a React-free\n * module (e.g. an rpc subpath) can be entangled with React through a shared\n * chunk. The vendor is also built for the page: a dynamic-base build rewrites\n * its asset URLs onto a global only the page sets, and its dynamic imports go\n * through Vite's preload helper, which needs `document`. Each entry's own\n * closure inside the vendor dir decides: clean closure, worker-safe; anything\n * bare or page-only in it (see {@link findWorkerUnsafeMarkers}), or a missing\n * entry file, bundled into the worker instead.\n */\nexport function workerSafeVendorImports(\n vendorDir: string,\n vendorImports: Record<string, string>,\n): Record<string, string> {\n const safe: Record<string, string> = {};\n for (const [spec, url] of Object.entries(vendorImports)) {\n const entryFile = url.slice(url.lastIndexOf(\"/\") + 1);\n if (!existsSync(join(vendorDir, entryFile))) continue;\n const clean = walkBundleGraph(\n vendorDir,\n entryFile,\n (_file, code) =>\n findDisallowedSpecifiers(code).length === 0 &&\n findWorkerUnsafeMarkers(code).length === 0,\n );\n if (clean) safe[spec] = url;\n }\n return safe;\n}\n\n/**\n * Builds arbitrary worker-loadable entries with the worker build config.\n * Exported for the local-package bundles, which need the same self-contained\n * output and vendor externalization at a different depth.\n */\nexport function runWorkerBuildEntries(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n vendorPrefix = \"../__vendor__/\",\n): Promise<{ ok: boolean; stderr: string }> {\n return runWorkerBuild(\n dirname,\n outDir,\n entries,\n vendorImports,\n nodeEnv,\n vendorPrefix,\n );\n}\n\nfunction runWorkerBuild(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n vendorPrefix = \"../__vendor__/\",\n): Promise<{ ok: boolean; stderr: string }> {\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, WORKER_BUILD_WORKER);\n return new Promise((resolve) => {\n const child = spawn(\n process.execPath,\n [\n workerPath,\n dirname,\n outDir,\n JSON.stringify(entries),\n JSON.stringify(vendorImports),\n nodeEnv,\n resolveBuilderVite() ?? \"\",\n vendorPrefix,\n ],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let stderr = \"\";\n child.stdout.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.stderr.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.on(\"exit\", (code) => {\n rmSync(workerPath, { force: true });\n resolve({ ok: code === 0, stderr });\n });\n child.on(\"error\", (e) => resolve({ ok: false, stderr: String(e) }));\n });\n}\n\n/**\n * The vite installed next to this module. The subprocess must run the vite\n * this build config was written against: a consumer project can pin an older\n * vite/rolldown (overrides) whose bundler leaves unresolvable specifiers bare\n * instead of erroring and shims node builtins differently — the output guard\n * then correctly rejects the bundle. builder-tools declares vite as a direct\n * dependency, so this resolution works wherever builder-tools is installed.\n */\nfunction resolveBuilderVite(): string | null {\n try {\n return createRequire(import.meta.url).resolve(\"vite\");\n } catch {\n return null;\n }\n}\n\n/**\n * The build subprocess (same pattern as the vendor's). Loads builder-tools'\n * own vite (argv; project fallback) and builds the given entries with\n * relative base, so chunk/asset URLs resolve against each script's own URL\n * under any deploy base. argv: dirname, outDir, entriesJSON (name ->\n * absolute entry path), vendorImportsJSON, nodeEnv, vitePath, vendorPrefix\n * (relative path from the out dir to __vendor__/, e.g. \"../__vendor__/\").\n */\nconst WORKER_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { isAbsolute } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nconst [dirname, outDir, entriesJSON, vendorImportsJSON, nodeEnvArg, vitePathArg, vendorPrefixArg] = process.argv.slice(2);\nconst nodeEnv = nodeEnvArg ?? 'development';\nconst entries = JSON.parse(entriesJSON);\nconst vendorImports = JSON.parse(vendorImportsJSON ?? '{}');\nconst vendorPrefix = vendorPrefixArg || '../__vendor__/';\nconst externalSet = new Set(Object.keys(vendorImports));\nconst vendorPath = (spec) => {\n const url = vendorImports[spec];\n return vendorPrefix + url.slice(url.lastIndexOf('/') + 1);\n};\nconst reqProj = createRequire(dirname + '/noop.js');\n// pathToFileURL: on Windows import('D:\\\\\\\\...') parses \"D:\" as a URL scheme.\nconst vitePath = vitePathArg || reqProj.resolve('vite');\nconst { build } = await import(pathToFileURL(vitePath).href);\n// Resolve bare specifiers from the project (same plugin as the vendor build):\n// prefer the bundler's browser-condition-aware resolution, fall back to the\n// worker's own resolution for Rolldown's realpath-anchoring bug.\nconst phResolveCache = new Map();\nconst phWorkerResolve = {\n name: 'ph-reactor-worker-resolve', enforce: 'pre',\n async resolveId(source, importer, options) {\n if (externalSet.has(source)) return null;\n if (source[0] === '\\\\0' || source[0] === '.' || isAbsolute(source)) return null;\n if (source.startsWith('node:') || source.startsWith('data:')) return null;\n let viaBundler = null;\n try { viaBundler = await this.resolve(source, importer, { ...options, skipSelf: true }); } catch {}\n if (viaBundler) return viaBundler;\n if (phResolveCache.has(source)) return phResolveCache.get(source);\n let resolved = null;\n try { resolved = fileURLToPath(import.meta.resolve(source)); } catch {}\n phResolveCache.set(source, resolved);\n return resolved;\n },\n};\n// A worker has no window: on a failed dynamic import, the preload helper's\n// window.dispatchEvent would throw a ReferenceError in place of the real error.\nconst PRELOAD_HELPER_ID = '\\\\0vite/preload-helper.js';\nconst PRELOAD_DISPATCH = 'window.dispatchEvent(';\nconst phWorkerPreloadHelper = {\n name: 'ph-reactor-worker-preload-helper',\n transform(code, id) {\n if (id !== PRELOAD_HELPER_ID) return null;\n if (code.split(PRELOAD_DISPATCH).length !== 2) {\n this.error('expected exactly one ' + PRELOAD_DISPATCH + ' in ' + PRELOAD_HELPER_ID);\n }\n return { code: code.replace(PRELOAD_DISPATCH, 'globalThis.dispatchEvent?.('), map: null };\n },\n};\nawait build({\n root: dirname, configFile: false, logLevel: 'error',\n // The project's public/ dir belongs to the app build, not this bundle.\n publicDir: false,\n // Relative base: emitted chunk/asset URLs resolve against the worker\n // script's own URL, so the bundle works under any deploy base.\n base: './',\n define: {\n 'process.env.NODE_ENV': JSON.stringify(nodeEnv),\n 'import.meta.env.BASE_URL': JSON.stringify('./'),\n },\n plugins: [phWorkerResolve, phWorkerPreloadHelper],\n // pglite ships nested web workers as ES-module chunks.\n worker: { format: 'es' },\n build: {\n // Always minified, dev included: the bundle is browser-served output\n // (sourcemaps carry the debugging story), and minification strips the\n // JSDoc comments whose embedded code samples (kysely's, viem's) would\n // otherwise trip the bare-specifier guard below.\n outDir, emptyOutDir: false, minify: true, target: 'esnext', sourcemap: true,\n // No document in a worker: the module-preload polyfill and preload helper\n // touch the DOM, so dynamic imports must stay plain import().\n modulePreload: false,\n rollupOptions: {\n input: entries,\n // A models entry is pure re-exports; without this the bundler treats\n // its exports as unused and tree-shakes the whole file to nothing.\n // Harmless for the worker entry, which exports nothing to preserve.\n preserveEntrySignatures: 'strict',\n external: (id) => externalSet.has(id),\n output: {\n format: 'es', entryFileNames: '[name].js',\n // Chunks live at the bundle root, not a chunks/ subdir: the vendor\n // paths below are emitted VERBATIM into every chunk, so all modules\n // must sit at the same depth for ../__vendor__/ to resolve.\n chunkFileNames: '[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]',\n paths: (id) => (externalSet.has(id) ? vendorPath(id) : id),\n },\n },\n },\n});\n`;\n\nconst WORKER_BUILD_WORKER_HASH = createHash(\"sha256\")\n .update(WORKER_BUILD_WORKER)\n .digest(\"hex\")\n .slice(0, 16);\n","/**\n * Prebuild a project's local packages into worker-loadable model bundles.\n *\n * The reactor worker gets document models from the registry CDN or from what\n * Connect statically bundled. A project's own (`provider: \"local\"`) package is\n * in neither, so its document types have no reducer in the worker and their\n * load jobs fail. Dev solves this by pointing the worker at the dev server's\n * transformed models entry; a production deployment has no dev server, so the\n * entry is prebuilt here, next to the worker bundle it is loaded beside.\n *\n * Each package's `browser/document-models/index.js` (reducers only: no React,\n * no CSS, no editors) is built self-contained, with the worker-safe subset of\n * the vendor externalized onto `../../__vendor__/` - two levels up, since\n * these land in `__reactor_worker__/packages/`. A `manifest.json` names what\n * was built so the tab can turn it into package sources without guessing.\n */\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n realpathSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname as pathDirname, join } from \"node:path\";\nimport { workerPackageFileName } from \"@powerhousedao/shared/connect\";\nimport {\n findBundleSpecifierOffenders,\n publishDirAtomic,\n runWorkerBuildEntries,\n workerSafeVendorImports,\n type ReactorWorkerVendorOptions,\n} from \"./reactor-worker-build.js\";\n\n/** Served under `<base>__reactor_worker__/packages/`. */\nexport const WORKER_PACKAGES_MANIFEST = \"manifest.json\";\n\n/** Vendor is two levels up from `__reactor_worker__/packages/`. */\nconst VENDOR_PREFIX = \"../../__vendor__/\";\n\nexport interface WorkerPackagesBuildOptions {\n /** Project root the packages resolve from. */\n dirname: string;\n /** Local package names (`provider: \"local\"` in powerhouse.config.json). */\n packages: string[];\n /** Directory to hold the bundles (`<dist>/__reactor_worker__/packages`). */\n outDir: string;\n /** The prebuilt vendor to share dependencies with, when one was built. */\n vendor?: ReactorWorkerVendorOptions;\n /**\n * The vendor's worker-safe subset, when the caller already computed it\n * (`PrebuiltReactorWorker.vendorImports`); skips walking the vendor again.\n */\n safeVendorImports?: Record<string, string>;\n nodeEnv?: \"development\" | \"production\";\n errorRef?: { message?: string };\n}\n\nexport interface WorkerPackageManifestEntry {\n name: string;\n version?: string;\n /** Filename inside outDir, as {@link workerPackageFileName} spells it. */\n file: string;\n}\n\nfunction readVersion(root: string): string | undefined {\n try {\n const meta = JSON.parse(\n readFileSync(join(root, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n return typeof meta.version === \"string\" ? meta.version : undefined;\n } catch {\n // version is decoration; the bundle is what matters\n return undefined;\n }\n}\n\n/**\n * A package root's models entry, or null when it ships none.\n *\n * Two roots are possible and both are normal: an installed dependency under\n * `node_modules/<name>`, and the project itself - the vetra case, where the\n * project *is* the local package and has no self-link in node_modules.\n */\nfunction resolvePackageModels(\n dirname: string,\n name: string,\n): { entryPath: string; version?: string } | null {\n const roots: string[] = [];\n try {\n roots.push(realpathSync(join(dirname, \"node_modules\", name)));\n } catch {\n // not installed; the project itself may still be the package\n }\n if (readProjectName(dirname) === name) {\n roots.push(dirname);\n }\n for (const root of roots) {\n const entryPath = join(\n root,\n \"dist\",\n \"browser\",\n \"document-models\",\n \"index.js\",\n );\n if (existsSync(entryPath)) {\n return { entryPath, version: readVersion(root) };\n }\n }\n return null;\n}\n\nfunction readProjectName(dirname: string): string | undefined {\n try {\n const meta = JSON.parse(\n readFileSync(join(dirname, \"package.json\"), \"utf8\"),\n ) as { name?: string };\n return typeof meta.name === \"string\" ? meta.name : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The project's own package name when it ships a models bundle, so a caller\n * can include it beside the configured `provider: \"local\"` packages. A vetra\n * project declares no package entry for itself, yet its models are exactly\n * the ones the worker is missing.\n */\nexport function ownProjectPackage(dirname: string): string | undefined {\n const name = readProjectName(dirname);\n if (!name) return undefined;\n return resolvePackageModels(dirname, name) ? name : undefined;\n}\n\n/**\n * Build each local package's models entry into `outDir` and write the\n * manifest the tab reads. Returns the manifest entries (empty when no local\n * package ships a models bundle), or null when the build itself failed -\n * `errorRef` then carries the cause. Both of those remove `outDir`, so a\n * previous build's bundles never outlive the packages they came from.\n */\nexport async function prebuildWorkerPackages(\n options: WorkerPackagesBuildOptions,\n): Promise<WorkerPackageManifestEntry[] | null> {\n const nodeEnv = options.nodeEnv ?? \"production\";\n const resolved: {\n entry: WorkerPackageManifestEntry;\n entryPath: string;\n }[] = [];\n for (const name of options.packages) {\n const models = resolvePackageModels(options.dirname, name);\n if (!models) continue;\n resolved.push({\n entry: {\n name,\n version: models.version,\n file: workerPackageFileName(name),\n },\n entryPath: models.entryPath,\n });\n }\n if (resolved.length === 0) {\n rmSync(options.outDir, { recursive: true, force: true });\n return [];\n }\n\n const vendorImports =\n options.safeVendorImports ??\n (options.vendor\n ? workerSafeVendorImports(options.vendor.dir, options.vendor.imports)\n : {});\n // Entry names are the filenames minus `.js`; the subprocess appends it.\n const entries = Object.fromEntries(\n resolved.map((item) => [\n item.entry.file.replace(/\\.js$/, \"\"),\n item.entryPath,\n ]),\n );\n\n const parent = pathDirname(options.outDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-worker-packages.tmp-\"));\n try {\n const { ok, stderr } = await runWorkerBuildEntries(\n options.dirname,\n tmpDir,\n entries,\n vendorImports,\n nodeEnv,\n VENDOR_PREFIX,\n );\n const missing = resolved.filter(\n (item) => !existsSync(join(tmpDir, item.entry.file)),\n );\n if (!ok || missing.length > 0) {\n const detail = stderr.trim();\n throw new Error(\n `worker package bundles failed to build${\n missing.length > 0\n ? ` (missing: ${missing.map((m) => m.entry.name).join(\", \")})`\n : \"\"\n }${detail ? `:\\n${detail}` : \"\"}`,\n );\n }\n\n // Same guard as the worker entry: a bare specifier here kills the import\n // inside the worker, with only an opaque failure to show for it.\n for (const item of resolved) {\n const offenders = findBundleSpecifierOffenders(tmpDir, item.entry.file);\n if (offenders.length > 0) {\n throw new Error(\n `worker package bundle for ${item.entry.name} contains module ` +\n `specifiers a worker cannot resolve:\\n` +\n offenders\n .map((o) => ` ${o.file}: ${o.specs.join(\", \")}`)\n .join(\"\\n\"),\n );\n }\n }\n\n const manifest = resolved.map((item) => item.entry);\n writeFileSync(\n join(tmpDir, WORKER_PACKAGES_MANIFEST),\n JSON.stringify(manifest, null, 2),\n );\n\n publishDirAtomic(tmpDir, options.outDir);\n return manifest;\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n rmSync(options.outDir, { recursive: true, force: true });\n if (options.errorRef) {\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n }\n return null;\n }\n}\n","import type { PowerhouseConfig } from \"@powerhousedao/config\";\nimport { exec, execSync } from \"node:child_process\";\nimport fs, { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path, { join, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { Plugin } from \"vite\";\nimport { LOCAL_PACKAGE_ID } from \"./constants.js\";\nimport type { ConnectCommonOptions } from \"./types.js\";\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport function resolveViteConfigPath(\n options: Pick<ConnectCommonOptions, \"projectRoot\" | \"viteConfigFile\">,\n) {\n const { projectRoot = cwd(), viteConfigFile } = options;\n return viteConfigFile || join(projectRoot, \"vite.config.ts\");\n}\n\nexport function resolvePackage(packageName: string, root = process.cwd()) {\n // find connect installation\n const require = createRequire(root);\n return require.resolve(packageName, { paths: [root] });\n}\n\nexport function resolveConnectPackageJson(root = process.cwd()) {\n try {\n const connectPackageJsonPath = resolvePackage(\n \"@powerhousedao/connect/package.json\",\n root,\n );\n const fileContents = fs.readFileSync(connectPackageJsonPath, \"utf-8\");\n return JSON.parse(fileContents) as JSON;\n } catch (error) {\n console.error(`Error reading Connect package.json:`, error);\n return null;\n }\n}\n\n/**\n * Finds the dist dir of Connect on the local machine\n */\nexport function resolveConnectBundle(root = process.cwd()) {\n const connectIndexPath = resolvePackage(\"@powerhousedao/connect\", root);\n const connectRootPath = connectIndexPath.substring(\n 0,\n connectIndexPath.indexOf(\"connect\") + \"connect\".length,\n );\n return join(connectRootPath, \"dist/\");\n}\n\nexport function resolveConnectPublicDir(root = process.cwd()) {\n const connectIconPath = resolvePackage(\n \"@powerhousedao/connect/public/icon.ico\",\n root,\n );\n return path.join(connectIconPath, \"../\");\n}\n\n/**\n * Copies the Connect dist dir to the target path\n */\nexport function copyConnect(sourcePath: string, targetPath: string) {\n try {\n // Ensure targetPath is removed before copying\n fs.rmSync(targetPath, { recursive: true, force: true });\n\n // Copy everything from sourcePath to targetPath\n fs.cpSync(sourcePath, targetPath, { recursive: true });\n } catch (error) {\n console.error(`❌ Error copying ${sourcePath} to ${targetPath}:`, error);\n }\n}\n\n/**\n * Backs up the index.html file\n *\n * Needed when running the Connect Studio dev server on Windows\n */\nexport function backupIndexHtml(appPath: string, restore = false) {\n const filePath = join(appPath, \"index.html\");\n const backupPath = join(appPath, \"index.html.bak\");\n\n const paths = restore ? [backupPath, filePath] : [filePath, backupPath];\n\n if (fs.existsSync(paths[0])) {\n fs.copyFileSync(paths[0], paths[1]);\n }\n}\n\nexport function removeBase64EnvValues(appPath: string) {\n backupIndexHtml(appPath);\n\n const filePath = join(appPath, \"index.html\");\n\n // Read the HTML file\n fs.readFile(filePath, \"utf-8\", (err, data) => {\n if (err) {\n console.error(\"Error reading file:\", err);\n return;\n }\n\n // Use regex to replace the dynamic Base64 values with empty strings\n // TODO is this needed?\n const modifiedData = data\n .replace(\n /\"LOCAL_DOCUMENT_MODELS\":\\s*\".*?\",/,\n `\"LOCAL_DOCUMENT_MODELS\": \"\",`,\n )\n .replace(\n /\"LOCAL_DOCUMENT_EDITORS\":\\s*\".*?\"/,\n `\"LOCAL_DOCUMENT_EDITORS\": \"\"`,\n );\n\n console.log(\"Modified data:\", modifiedData);\n // Write the modified content back to the file\n fs.writeFile(filePath, modifiedData, \"utf-8\", (err) => {\n if (err) {\n console.error(\"Error writing file:\", err);\n return;\n }\n });\n });\n}\n\nexport function readJsonFile(filePath: string): PowerhouseConfig | null {\n try {\n const absolutePath = resolve(filePath);\n const fileContents = fs.readFileSync(absolutePath, \"utf-8\");\n return JSON.parse(fileContents) as PowerhouseConfig;\n } catch (_error) {\n console.error(`Error reading file: ${filePath}`);\n return null;\n }\n}\n\n/**\n * Takes a list of Powerhouse project packages and optionally local Powerhouse packages and outputs a js file which exports those packages for use in Connect Studio.\n */\nexport function makeImportScriptFromPackages(args: {\n packages: string[];\n importStyles?: boolean;\n localJsPath?: string;\n localCssPath?: string;\n}) {\n const { packages, localJsPath, localCssPath, importStyles = true } = args;\n const imports: string[] = [];\n const moduleNames: string[] = [];\n let counter = 0;\n\n for (const packageName of packages) {\n const moduleName = `module${counter}`;\n moduleNames.push(moduleName);\n imports.push(`import * as ${moduleName} from '${packageName}';`);\n if (importStyles) {\n imports.push(`import '${packageName}/style.css';`);\n }\n counter++;\n }\n\n const exports = moduleNames.map(\n (name, index) => `{\n id: \"${packages[index]}\",\n ...${name},\n }`,\n );\n\n const hasModule = localJsPath !== undefined;\n const hasStyles = importStyles && localCssPath !== undefined;\n const hasLocalPackage = hasModule || hasStyles;\n\n if (hasLocalPackage) {\n if (hasStyles) {\n imports.push(`import '${localCssPath}';`);\n }\n if (hasModule) {\n const moduleName = `module${counter}`;\n imports.push(`import * as ${moduleName} from '${localJsPath}';`);\n exports.push(`{\n id: \"${LOCAL_PACKAGE_ID}\",\n ...${moduleName},\n }`);\n }\n }\n const exportsString = exports.length\n ? `\n ${exports.join(\",\\n\")}\n `\n : \"\";\n\n const exportStatement = `export default [${exportsString}];`;\n\n const fileContent = `${imports.join(\"\\n\")}\\n\\n${exportStatement}`;\n\n return fileContent;\n}\n\nexport function ensureNodeVersion(minVersion = \"24\") {\n const version = process.versions.node;\n if (!version) {\n return;\n }\n\n if (version < minVersion) {\n console.error(\n `Node version ${minVersion} or higher is required. Current version: ${version}`,\n );\n process.exit(1);\n }\n}\n\nexport function runShellScriptPlugin(\n scriptName: string,\n connectPath: string,\n): Plugin {\n return {\n name: \"vite-plugin-run-shell-script\",\n buildStart() {\n const scriptPath = join(connectPath, scriptName);\n if (fs.existsSync(scriptPath)) {\n exec(`sh ${scriptPath}`, (error, stdout, stderr) => {\n if (error) {\n console.error(`Error executing the script: ${error.message}`);\n removeBase64EnvValues(connectPath);\n return;\n }\n if (stderr) {\n console.error(stderr);\n }\n });\n }\n },\n };\n}\n\n/**\n * Shared helper to modify the <head> tag of an HTML file by transforming its contents.\n */\nasync function modifyHtmlHead(\n pathToHtml: string,\n contents: string,\n transform: (html: string, contents: string) => string,\n) {\n if (!existsSync(pathToHtml)) {\n throw new Error(`File ${pathToHtml} does not exist.`);\n }\n let html = await readFile(pathToHtml, \"utf8\");\n html = transform(html, contents);\n await writeFile(pathToHtml, html, \"utf8\");\n}\n\n/**\n * Appends the contents to the <head> tag of the index.html file\n */\nexport async function appendToHtmlHead(pathToHtml: string, contents: string) {\n return modifyHtmlHead(pathToHtml, contents, (html, contents) => {\n if (!html.includes(\"</head>\")) {\n throw new Error(\"No </head> tag found in the HTML file.\");\n }\n return html.replace(\"</head>\", `\\n${contents}\\n</head>`);\n });\n}\n\n/**\n * Prepends the contents to the <head> tag of the index.html file\n */\nexport async function prependToHtmlHead(pathToHtml: string, contents: string) {\n return modifyHtmlHead(pathToHtml, contents, (html, contents) => {\n if (!html.includes(\"</head>\")) {\n throw new Error(\"No </head> tag found in the HTML file.\");\n }\n return html.replace(\"<head>\", `<head>\\n${contents}\\n`);\n });\n}\n\nexport function runTsc(outDir: string) {\n execSync(`npx tsc --outDir ${outDir}`, { stdio: \"inherit\" });\n}\n\n// Helper function to remove version suffix from package name\n// Handles formats like: @scope/package@version -> @scope/package\nexport function stripVersionFromPackage(packageName: string): string {\n const trimmed = packageName.trim();\n if (!trimmed) return \"\";\n const lastAtIndex = trimmed.lastIndexOf(\"@\");\n if (lastAtIndex > 0) {\n return trimmed.substring(0, lastAtIndex);\n }\n\n return trimmed;\n}\n","// JSON Schema (draft-07) for dist/powerhouse.config.json — the runtime\n// artifact emitted into the build output and fetched by the Connect SPA at\n// boot.\n//\n// A strict SUBSET of the source PowerhouseConfig schema plus two runtime-only\n// fields (schemaVersion, localPackage). Field shapes shared with the source\n// schema (PowerhousePackage, PHConnectRuntimeConfig) are imported from the\n// shared fragments module so the two schemas stay in sync by construction.\n\nimport {\n phConnectRuntimeConfigSchema,\n powerhousePackageSchema,\n} from \"@powerhousedao/shared/connect\";\n\nexport const RUNTIME_CONFIG_SCHEMA_ID =\n \"https://powerhouse.inc/schemas/powerhouse.config.json\";\n\n// GitHub-hosted schema URL. Points at the JSON artifact committed alongside\n// this TS module. Currently tracks the `main` branch — schema edits go live\n// for editors as soon as they merge. Migrate to a `schema-v<N>` tag pinned\n// to schemaVersion if/when stability across edits becomes a concern.\nexport const RUNTIME_CONFIG_SCHEMA_URL =\n \"https://raw.githubusercontent.com/powerhouse-inc/powerhouse/main/packages/builder-tools/connect-utils/runtime-config.schema.json\";\n\nexport const runtimeConfigSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n $id: RUNTIME_CONFIG_SCHEMA_ID,\n title: \"Powerhouse Connect runtime configuration\",\n description:\n \"Runtime configuration loaded by Connect at boot from /powerhouse.config.json.\",\n type: \"object\",\n additionalProperties: false,\n required: [\"schemaVersion\", \"packages\", \"localPackage\"],\n properties: {\n $schema: {\n type: \"string\",\n description:\n \"Optional JSON Schema reference for editor autocomplete. Set to the GitHub-hosted schema URL.\",\n },\n schemaVersion: {\n const: 2,\n description:\n \"Schema version. Must match the SPA bundle that ships with this dist. The SPA throws on mismatch to prevent SPA/config skew.\",\n },\n packages: {\n type: \"array\",\n description:\n \"Powerhouse packages this Connect instance loads at runtime.\",\n items: powerhousePackageSchema,\n },\n packageRegistryUrl: {\n type: \"string\",\n description:\n \"Project-wide package registry endpoint. Copied verbatim from the source `powerhouse.config.json` top-level field — the SPA's Package Manager UI reads this directly.\",\n },\n localPackage: {\n description:\n \"Identity of the consumer project itself, captured at build time. null for Docker images and other generic deploys with no host project.\",\n oneOf: [\n { type: \"null\" },\n {\n type: \"object\",\n additionalProperties: false,\n required: [\"name\", \"version\"],\n properties: {\n name: { type: \"string\" },\n version: { type: \"string\" },\n },\n },\n ],\n },\n connect: phConnectRuntimeConfigSchema,\n },\n} as const;\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\n\nexport type PhBundledPackagesPluginOptions = {\n /**\n * Package names (with `provider: \"local\"` in powerhouse.config.json)\n * that should be bundled into Connect at build time. Each must be\n * resolvable from node_modules.\n */\n packages: string[];\n /** Project root used to read each bundled package's package.json version. */\n projectRoot?: string;\n};\n\nexport const VIRTUAL_ID = \"ph-bundled-packages-virtual\";\nexport const RESOLVED_VIRTUAL_ID = \"\\0virtual:\" + VIRTUAL_ID;\n// Vite serves a resolved id at /@id/<id with \\0 → __x00__>.\nexport const BUNDLED_PACKAGES_DEV_URL =\n \"@id/\" + RESOLVED_VIRTUAL_ID.replace(\"\\0\", \"__x00__\");\n\nfunction readBundledPackageVersion(\n projectRoot: string,\n name: string,\n): string | undefined {\n try {\n const raw = fs.readFileSync(\n path.join(projectRoot, \"node_modules\", name, \"package.json\"),\n \"utf-8\",\n );\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === \"string\" ? pkg.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction makeRegisterModule(packages: string[], projectRoot: string): string {\n if (packages.length === 0) {\n return \"export default () => {};\\n\";\n }\n const imports: string[] = [];\n const calls: string[] = [];\n\n packages.forEach((name, i) => {\n const moduleName = `pkg${i}`;\n const version = readBundledPackageVersion(projectRoot, name);\n imports.push(`import * as ${moduleName} from ${JSON.stringify(name)};`);\n imports.push(`import ${JSON.stringify(`${name}/style.css`)};`);\n calls.push(\n ` pm.addLocalPackage(${JSON.stringify(name)}, ${moduleName}, ${JSON.stringify(version)});`,\n );\n });\n\n return `${imports.join(\"\\n\")}\\n\\nexport default function register(pm) {\\n${calls.join(\"\\n\")}\\n};\\n`;\n}\n\n/**\n * Emits a virtual module `ph-bundled-packages-virtual` whose default export\n * is a `register(packageManager)` function. When called at runtime (from\n * Connect's bootstrap), it registers each bundled package with the package\n * manager the same way Common/Vetra are registered — meaning they work\n * offline without the registry being reachable.\n *\n * When the list is empty, the module exports a no-op function so Connect's\n * bootstrap code can always import it unconditionally.\n */\nexport function phBundledPackagesPlugin(\n options: PhBundledPackagesPluginOptions,\n): Plugin {\n const projectRoot = options.projectRoot ?? process.cwd();\n const moduleSource = makeRegisterModule(options.packages, projectRoot);\n\n return {\n name: \"vite-plugin-ph-bundled-packages\",\n enforce: \"pre\",\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n load(id) {\n if (id === RESOLVED_VIRTUAL_ID) return moduleSource;\n },\n };\n}\n","import { createRequire } from \"node:module\";\nimport { createReadStream } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport {\n DEFAULT_VENDOR_INCLUDE,\n VENDOR_URL_PREFIX,\n prebuildConnectVendor,\n type PrebuiltVendor,\n} from \"../externalize-vendor.js\";\nimport { BUNDLED_PACKAGES_DEV_URL } from \"./ph-bundled-packages.js\";\n\nconst REACT_DEPS = [\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n \"react-dom/client\",\n];\n\nconst SHIM_PATH = \"__ph/dev-react-shim/\";\nconst VITE_DEPS_PATH = \"node_modules/.vite/deps\";\n\n// Content-Type for the asset extensions the vendor build emits; JS is the default.\nconst VENDOR_MIME: Record<string, string> = {\n \".css\": \"text/css\",\n \".map\": \"application/json\",\n \".json\": \"application/json\",\n \".wasm\": \"application/wasm\",\n \".data\": \"application/octet-stream\",\n \".woff2\": \"font/woff2\",\n \".woff\": \"font/woff\",\n \".ttf\": \"font/ttf\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n};\n\n// Opt-in: also serve the heavy stable Connect libs from a prebuilt vendor\n// bundle, so the long-lived dev server never dep-optimizes them (~1–2 GB\n// resident). Set PH_CONNECT_EXTERNALIZE_VENDOR=1 to enable.\nconst VENDOR_MODE = process.env.PH_CONNECT_EXTERNALIZE_VENDOR === \"1\";\n// Extra specifiers to vendor on top of the defaults, comma-separated. Lets a\n// project add its own stable heavy deps without code changes.\nconst VENDOR_EXTRA = (process.env.PH_CONNECT_VENDOR_EXTRA ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\nconst HEAVY_LIBS = [...DEFAULT_VENDOR_INCLUDE, ...VENDOR_EXTRA];\n\n// Vite serves dev module URLs under the resolved `base`. Join base + path\n// while collapsing the double slash so `base: \"/\"` stays byte-identical.\nfunction withBase(base: string, p: string): string {\n return `${base}${p}`.replace(/\\/{2,}/g, \"/\");\n}\n\n// Keep the matched specifiers bare in dev (Vite otherwise rewrites externals to\n// \"/@id/<spec>\") so the import map resolves them; predicate matching supported.\ntype Externals = Array<string | ((id: string) => boolean)>;\nfunction externalizePlugin(externals: Externals): Plugin | undefined {\n try {\n const require = createRequire(import.meta.url);\n const mod = require(\"vite-plugin-externalize-dependencies\") as {\n default?: (o: { externals: Externals }) => Plugin;\n } & ((o: { externals: Externals }) => Plugin);\n const factory = mod.default ?? mod;\n return factory({ externals });\n } catch {\n return undefined;\n }\n}\n\n/**\n * Dev-only sibling of `esmExternalRequirePlugin`. The build path externalizes\n * React via Rolldown so an importmap hands the same React instance to both\n * Connect and CDN-served editor packages. Rolldown plugins don't run in\n * `vite createServer`, and Vite's pre-bundled CJS deps only expose a `default`\n * export — so a CDN editor that does `import { lazy } from \"react\"` would\n * fail with \"no named export 'lazy'\".\n *\n * This plugin owns the page import map. It always:\n * 1. Forces React into `optimizeDeps.include` so the optimizer always knows\n * about it.\n * 2. Serves a shim per React module at a stable URL. Each shim imports\n * from Vite's live pre-bundled URL (sharing Connect's React instance)\n * and re-exports React's named members so editors importing\n * `{ lazy }`, `{ jsx }`, etc. work.\n * 3. Rewrites the page importmap to point at those shim URLs.\n *\n * When PH_CONNECT_EXTERNALIZE_VENDOR=1 it additionally prebuilds the heavy\n * stable libs (design-system, reactor-browser, …) into a static vendor bundle,\n * externalizes them from the dev server, serves the bundle, and adds them to\n * the SAME import map. The vendor's React imports stay bare → resolve through\n * the React shims above → one React instance across Connect, the vendor, and\n * CDN editors.\n */\n// Async factory: in VENDOR_MODE it runs the vendor prebuild up front (Vite\n// awaits a Promise<PluginOption>), so `vendor` is known before any plugin hook\n// fires. The heavy libs are excluded from the optimizer — and the externalize\n// plugin is added — ONLY when a valid bundle will be served. On prebuild\n// failure they stay dev-optimized (no broken bare imports) and neither the\n// import map nor the externalizer touch them.\nexport async function devReactImportmapPlugin(\n projectRoot: string = process.cwd(),\n): Promise<Plugin | Plugin[]> {\n let namedExports = new Map<string, string[]>();\n let base = \"/\";\n let vendor: PrebuiltVendor | null = null;\n\n if (VENDOR_MODE) {\n const errorRef: { message?: string } = {};\n vendor = await prebuildConnectVendor({\n dirname: projectRoot,\n include: HEAVY_LIBS,\n errorRef,\n });\n if (!vendor) {\n const detail = errorRef.message ? `: ${errorRef.message}` : \"\";\n console.warn(\n `[connect] PH_CONNECT_EXTERNALIZE_VENDOR set but vendor prebuild failed; falling back to dep-optimizing the heavy libs${detail}`,\n );\n }\n }\n\n // Externalize exactly the specifiers in the vendor import map (not broad\n // prefixes) so an undiscovered subpath stays resolvable instead of 404ing.\n const ext = vendor\n ? externalizePlugin([(id) => id in vendor!.imports])\n : undefined;\n if (vendor && !ext) {\n console.warn(\n \"[connect] PH_CONNECT_EXTERNALIZE_VENDOR set and vendor prebuilt, but vite-plugin-externalize-dependencies is not installed; falling back to dep-optimizing the heavy libs (install it to enable the vendor)\",\n );\n }\n const vendorActive = !!(vendor && ext);\n\n const main: Plugin = {\n name: \"ph-dev-react-importmap\",\n apply: \"serve\",\n config(cfg) {\n cfg.optimizeDeps ??= {};\n const include = new Set(cfg.optimizeDeps.include ?? []);\n REACT_DEPS.forEach((d) => include.add(d));\n if (vendorActive) {\n // The heavy libs are served from the prebuilt vendor; force-including\n // them would pre-bundle them anyway (and leave their excluded deps —\n // e.g. zod subpaths — as unmapped bare imports). Drop them from include\n // and exclude them so the optimizer never touches them.\n HEAVY_LIBS.forEach((d) => include.delete(d));\n cfg.optimizeDeps.exclude = [\n ...new Set([...(cfg.optimizeDeps.exclude ?? []), ...HEAVY_LIBS]),\n ];\n }\n cfg.optimizeDeps.include = [...include];\n },\n configResolved(config) {\n base = config.base;\n },\n configureServer(server) {\n // Resolve React's named exports from the consumer project so we don't\n // hardcode lists that drift across React versions.\n const requireFromRoot = createRequire(\n path.join(server.config.root, \"package.json\"),\n );\n namedExports = new Map(\n REACT_DEPS.map((id) => {\n try {\n const mod = requireFromRoot(id) as Record<string, unknown>;\n return [id, Object.keys(mod).filter((k) => k !== \"default\")];\n } catch {\n return [id, []];\n }\n }),\n );\n\n // Serve the prebuilt vendor bundle. Match the base-prefixed URL (chunk/asset\n // URLs carry the deploy base) and the bare prefix; strip whichever matched.\n if (vendorActive) {\n const vendorDir = vendor!.vendorDir;\n const vendorPrefixes = [\n withBase(base, VENDOR_URL_PREFIX),\n VENDOR_URL_PREFIX,\n ];\n server.middlewares.use((req, res, next) => {\n const url = (req.url ?? \"\").split(\"?\")[0];\n const prefix = vendorPrefixes.find((p) => url.startsWith(p));\n if (!prefix) return next();\n const name = url.slice(prefix.length).replace(/^\\/+/, \"\");\n const file = path.join(vendorDir, name);\n // Path-segment containment (not a string prefix): reject anything that\n // escapes vendorDir, incl. siblings like `.ph-vendor.lock`.\n const rel = path.relative(vendorDir, file);\n if (!name || rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n return next();\n }\n // Stream (don't buffer multi-MB wasm/.data); a missing file → next().\n const stream = createReadStream(file);\n stream.on(\"error\", () => {\n if (!res.headersSent) next();\n });\n stream.once(\"open\", () => {\n const ext = file.slice(file.lastIndexOf(\".\"));\n res.setHeader(\n \"Content-Type\",\n VENDOR_MIME[ext] ?? \"text/javascript\",\n );\n // Content-hashed chunks/assets are immutable; entries + map can change.\n const hashed =\n name.startsWith(\"chunks/\") || name.startsWith(\"assets/\");\n res.setHeader(\n \"Cache-Control\",\n hashed ? \"public, max-age=31536000, immutable\" : \"no-cache\",\n );\n stream.pipe(res);\n });\n });\n }\n\n // Match the base-prefixed shim URL, and the bare path for robustness.\n const shimPrefixes = [withBase(base, SHIM_PATH), `/${SHIM_PATH}`];\n server.middlewares.use((req, res, next) => {\n const prefix = shimPrefixes.find((p) => req.url?.startsWith(p));\n if (!prefix) return next();\n const id = req.url!.slice(prefix.length).replace(/\\.js(\\?.*)?$/, \"\");\n if (!REACT_DEPS.includes(id)) return next();\n\n const optimizer = server.environments.client.depsOptimizer;\n const info =\n optimizer?.metadata.optimized[id] ??\n optimizer?.metadata.discovered[id];\n if (!optimizer || !info) {\n res.statusCode = 404;\n res.end();\n return;\n }\n\n const browserHash = info.browserHash ?? optimizer.metadata.browserHash;\n const depUrl = `${withBase(base, VITE_DEPS_PATH)}/${path.basename(info.file)}?v=${browserHash}`;\n const names = namedExports.get(id) ?? [];\n\n res.setHeader(\"Content-Type\", \"application/javascript\");\n res.end(\n `import * as M from ${JSON.stringify(depUrl)};\\n` +\n `const ns = M.default ?? M;\\n` +\n `export default ns;\\n` +\n (names.length\n ? `export const { ${names.join(\", \")} } = ns;\\n`\n : \"\"),\n );\n });\n },\n transformIndexHtml: {\n order: \"post\",\n handler(html, ctx) {\n const browserHash =\n ctx.server?.environments.client.depsOptimizer?.metadata.browserHash;\n if (!browserHash) return;\n const shimPrefix = withBase(base, SHIM_PATH);\n const imports: Record<string, string> = Object.fromEntries(\n REACT_DEPS.map((id) => [\n id,\n `${shimPrefix}${id}.js?v=${browserHash}`,\n ]),\n );\n // Heavy libs resolve to the prebuilt vendor (base-prefixed); their bare\n // React imports fall through to the React shim entries above.\n let dynamicBaseScript = \"\";\n if (vendorActive) {\n for (const [spec, url] of Object.entries(vendor!.imports)) {\n imports[spec] = withBase(base, url);\n }\n // Connect vendored isn't dev-processed, so its dynamic\n // `import(\"ph-bundled-packages-virtual\")` points at the virtual URL.\n if (vendor!.imports[\"@powerhousedao/connect\"]) {\n imports[\"ph-bundled-packages-virtual\"] = withBase(\n base,\n BUNDLED_PACKAGES_DEV_URL,\n );\n }\n // Set the runtime base global so the vendor's rewritten URL exprs\n // resolve to the dev/deploy base (mirrors the proxy at serve time).\n dynamicBaseScript = `<script>globalThis.__PH_DYNAMIC_BASE__=${JSON.stringify(base)};</script>\\n`;\n }\n return html.replace(\n /<script type=\"importmap\">[\\s\\S]*?<\\/script>/,\n `${dynamicBaseScript}<script type=\"importmap\">${JSON.stringify({ imports }, null, 2)}</script>`,\n );\n },\n },\n };\n\n // The externalizer runs alongside `main` so Connect's source leaves the heavy\n // libs bare (→ import map → vendor); React stays optimized via the shims.\n return vendorActive ? [ext!, main] : main;\n}\n","import { readFileSync } from \"node:fs\";\nimport { extname, isAbsolute, resolve } from \"node:path\";\nimport type { Connect, Plugin } from \"vite\";\n\nconst CONTENT_TYPE_BY_EXT: Record<string, string> = {\n \".ico\": \"image/x-icon\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n};\n\n/**\n * Vite plugin to serve the Connect favicon (icon.ico) from the connect package,\n * or from a caller-supplied file when `faviconPath` is set (e.g. `ph connect\n * build --favicon`). The served/emitted name is always `icon.ico` so the static\n * `<link rel=\"icon\" href=\"%BASE_URL%icon.ico\">` in index.html stays valid.\n */\nexport function connectFaviconPlugin(\n opts: { faviconPath?: string } = {},\n): Plugin {\n // Build input, not runtime config: a non-absolute path resolves against the\n // build cwd (= the project dir during `ph connect build`).\n const customPath = opts.faviconPath\n ? isAbsolute(opts.faviconPath)\n ? opts.faviconPath\n : resolve(process.cwd(), opts.faviconPath)\n : undefined;\n const customContentType = customPath\n ? (CONTENT_TYPE_BY_EXT[extname(customPath).toLowerCase()] ?? \"image/x-icon\")\n : \"image/x-icon\";\n\n return {\n name: \"copy-connect-favicon\",\n configureServer(server) {\n // Vite rewrites the favicon link against `base`, so serve the\n // base-prefixed path. Keep the bare path for robustness.\n const base = server.config.base;\n const faviconRoute = `${base}icon.ico`.replace(/\\/{2,}/g, \"/\");\n const handler: Connect.NextHandleFunction = (_req, res, next) => {\n if (customPath) {\n try {\n res.setHeader(\"Content-Type\", customContentType);\n res.end(readFileSync(customPath));\n } catch {\n next();\n }\n return;\n }\n server.pluginContainer\n .resolveId(\"@powerhousedao/connect/assets/icon.ico\")\n .then((resolved) => {\n if (!resolved) return next();\n res.setHeader(\"Content-Type\", \"image/x-icon\");\n res.end(readFileSync(resolved.id));\n })\n .catch(() => next());\n };\n // Mount on the exact route(s) so the handler only runs for icon.ico.\n // Connect strips the mount prefix before matching, so mounting on\n // \"/icon.ico\" matches that path exactly.\n const paths = new Set([faviconRoute, \"/icon.ico\"]);\n for (const path of paths) {\n server.middlewares.use(path, handler);\n }\n },\n async generateBundle(_options, bundle) {\n try {\n if (\"icon.ico\" in bundle) return;\n let source: Uint8Array | undefined;\n if (customPath) {\n source = readFileSync(customPath);\n } else {\n const resolved = await this.resolve(\n \"@powerhousedao/connect/assets/icon.ico\",\n );\n if (resolved) source = readFileSync(resolved.id);\n }\n if (!source) return;\n this.emitFile({\n type: \"asset\",\n fileName: \"icon.ico\",\n source,\n });\n } catch {\n // favicon source not found, skip\n }\n },\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport type { PowerhousePackage } from \"@powerhousedao/config\";\nimport type {\n PHConnectRuntimeConfig,\n PowerhouseConfig,\n} from \"@powerhousedao/shared/clis\";\nimport {\n buildRuntimeConfig,\n deepMerge,\n resolveSourceConnect,\n workflowsSettingConflict,\n} from \"@powerhousedao/shared/connect\";\nimport { RUNTIME_CONFIG_SCHEMA_URL } from \"../runtime-config-schema.js\";\n\nexport type PhConfigPluginOptions = {\n packages: PowerhousePackage[];\n projectRoot?: string;\n connect?: PHConnectRuntimeConfig;\n /** The source's top-level `workflows` block; `connect.app.workflowsEnabled` falls back to it. */\n workflows?: PowerhouseConfig[\"workflows\"];\n /**\n * Project-wide package registry URL — the effective value (CLI override\n * `??` source) the caller has already resolved. Copied verbatim into the\n * emitted runtime config (no namespace change); the SPA reads\n * `runtimeConfig.packageRegistryUrl` directly.\n */\n packageRegistryUrl?: string;\n /**\n * CLI-supplied connect override (final merge layer, beats source).\n * Forwarded from `ph connect build`'s `--json` + individual `--flag` parsing.\n * See clis/ph-cli/src/utils/cli-connect-override.ts.\n */\n cliConnectOverride?: PHConnectRuntimeConfig;\n};\n\nfunction readProjectPackageInfo(\n projectRoot: string | undefined,\n): { name: string; version: string } | null {\n if (!projectRoot) return null;\n try {\n const raw = fs.readFileSync(\n path.join(projectRoot, \"package.json\"),\n \"utf-8\",\n );\n const pkg = JSON.parse(raw) as { name?: unknown; version?: unknown };\n if (typeof pkg.name !== \"string\" || typeof pkg.version !== \"string\") {\n return null;\n }\n return { name: pkg.name, version: pkg.version };\n } catch {\n return null;\n }\n}\n\nexport function phConfigPlugin(options: PhConfigPluginOptions): Plugin {\n const projectRoot = options.projectRoot ?? process.cwd();\n const localPackage = readProjectPackageInfo(projectRoot);\n\n // Precedence ladder (lowest → highest) for the emitted connect.* block:\n // DEFAULT_CONNECT_CONFIG (base — fills in any field nothing else supplied)\n // < source.workflows (project-wide `workflows.enabled`)\n // < source.connect (user's hand-edited powerhouse.config.json)\n // < cliConnectOverride (`ph connect build --json` + individual flags)\n //\n // Env vars are NOT a layer in this ladder. The Connect SPA's runtime\n // configuration is exclusively set via `powerhouse.config.json` or CLI\n // overrides (`ph connect build --<field>` / `ph connect config --<field>`).\n const sourceSettings = {\n connect: options.connect,\n workflows: options.workflows,\n };\n const conflict = workflowsSettingConflict(sourceSettings);\n if (conflict) console.warn(`[powerhouse] ${conflict}`);\n const withDefaults = resolveSourceConnect(sourceSettings);\n const mergedConnect = options.cliConnectOverride\n ? deepMerge(withDefaults, options.cliConnectOverride)\n : withDefaults;\n const source = {\n packages: options.packages,\n packageRegistryUrl: options.packageRegistryUrl,\n connect: mergedConnect,\n };\n\n const runtimeConfig = buildRuntimeConfig(source, localPackage);\n const content = JSON.stringify(\n { $schema: RUNTIME_CONFIG_SCHEMA_URL, ...runtimeConfig },\n null,\n 2,\n );\n\n return {\n name: \"vite-plugin-ph-config\",\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n if (req.url?.endsWith(\"/powerhouse.config.json\")) {\n res.setHeader(\"Content-Type\", \"application/json\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(content);\n return;\n }\n next();\n });\n },\n hotUpdate: {\n order: \"pre\",\n handler(ctx) {\n return ctx.modules.filter((mod) => {\n if (mod.importers.size > 1) {\n return true;\n }\n const importer = mod.importers.values().next();\n return !importer.value?.file?.endsWith(\".css\");\n });\n },\n },\n generateBundle() {\n this.emitFile({\n type: \"asset\",\n fileName: \"powerhouse.config.json\",\n source: content,\n });\n },\n };\n}\n","import type { PowerhousePackage } from \"@powerhousedao/config\";\nimport type {\n PHConnectPwa,\n PwaContribution,\n} from \"@powerhousedao/shared/connect\";\nimport { withInferredCategory } from \"@powerhousedao/shared/connect\";\nimport { PwaConfigSchema } from \"@powerhousedao/shared/document-model\";\nimport { toCdnUrl } from \"@powerhousedao/shared/registry/urls\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { ZodError } from \"zod\";\n\n// Collects the serialisable `pwa` fragments that build-time-known packages ship\n// in their `powerhouse.manifest.json`, from three sources:\n// - the project's own manifest (`collectProjectPwaContribution`);\n// - `provider: \"local\"` packages, read from node_modules (a package's\n// manifest is emitted to `dist/powerhouse.manifest.json` and exposed via\n// its `./manifest` export, so the Connect build can read it as JSON — no\n// need to execute package code, whose main entry pulls browser-only\n// modules that would crash in Node);\n// - `provider: \"registry\"` packages, fetched from the registry CDN (they are\n// not installed in node_modules; production Connect loads them from the\n// CDN at runtime, so the CDN copy is the build-time source of truth).\n// Fragments are validated with `PwaConfigSchema`; anything unreadable,\n// unreachable or malformed is warned about and skipped, never fatal to the\n// build. Only the project's `connect.pwa` block is strict — see\n// `validateProjectPwaConfig`.\n\nconst REGISTRY_FETCH_TIMEOUT_MS = 10_000;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction formatZodIssues(error: ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \");\n}\n\n/** Turn a parsed manifest JSON into a contribution: its `pwa` fragment (a\n * malformed one → warn + skip that fragment, not the whole contribution) plus a\n * `categories` entry derived from the manifest's `category` field. Returns null\n * only when the manifest yields neither — no `pwa` and no `category`. */\nfunction toPwaContribution(\n manifest: unknown,\n fallbackLabel: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n if (!isPlainObject(manifest)) return null;\n const label =\n typeof manifest.name === \"string\" && manifest.name\n ? manifest.name\n : fallbackLabel;\n\n let config: PHConnectPwa = {};\n if (manifest.pwa !== undefined) {\n if (!isPlainObject(manifest.pwa)) {\n onWarn(\n `PWA config: ${label} declares a non-object 'pwa' field in its manifest; ignored.`,\n );\n } else {\n const parsed = PwaConfigSchema.safeParse(manifest.pwa);\n if (!parsed.success) {\n onWarn(\n `PWA config: ${label}'s pwa fragment is invalid; ignored. ${formatZodIssues(parsed.error)}`,\n );\n } else {\n config = parsed.data;\n }\n }\n }\n\n config = withInferredCategory(config, manifest.category);\n if (Object.keys(config).length === 0) return null;\n return { source: label, config };\n}\n\n/** Read the first parseable manifest among `candidates` (relative to `dir`)\n * and extract its pwa contribution. Candidates that resolve outside `dir`\n * (a hostile `./manifest` export) are warned about and skipped. */\nfunction readPwaFragmentFromDir(\n dir: string,\n candidates: string[],\n fallbackLabel: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n for (const rel of candidates) {\n const manifestPath = path.resolve(dir, rel);\n if (path.relative(dir, manifestPath).startsWith(\"..\")) {\n onWarn(\n `PWA config: ${fallbackLabel} declares a manifest path outside its package directory (${rel}); ignored.`,\n );\n continue;\n }\n if (!fs.existsSync(manifestPath)) continue;\n try {\n const manifest: unknown = JSON.parse(\n fs.readFileSync(manifestPath, \"utf-8\"),\n );\n return toPwaContribution(manifest, fallbackLabel, onWarn);\n } catch {\n onWarn(\n `PWA config: could not parse ${fallbackLabel}'s manifest at ${rel}; ignored.`,\n );\n return null;\n }\n }\n return null;\n}\n\nfunction readLocalPackagePwaFragment(\n projectRoot: string,\n name: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n const pkgDir = path.join(projectRoot, \"node_modules\", name);\n let manifestRel: string | undefined;\n try {\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(pkgDir, \"package.json\"), \"utf-8\"),\n ) as { exports?: Record<string, unknown> };\n const exported = pkgJson.exports?.[\"./manifest\"];\n if (typeof exported === \"string\") manifestRel = exported;\n } catch {\n // No package.json / unreadable — fall back to the conventional paths.\n }\n\n // The package's declared `./manifest` export first, then the conventional\n // build output and source locations.\n const candidates = [\n manifestRel,\n \"dist/powerhouse.manifest.json\",\n \"powerhouse.manifest.json\",\n ].filter((rel): rel is string => typeof rel === \"string\");\n\n return readPwaFragmentFromDir(pkgDir, candidates, name, onWarn);\n}\n\nasync function fetchRegistryPwaFragment(\n cdnUrl: string,\n pkg: PowerhousePackage,\n onWarn: (message: string) => void,\n fetchImpl: typeof fetch,\n): Promise<PwaContribution | null> {\n // Same version-pinned spec production Connect uses to load the package, so\n // the fragment matches the code that will actually run.\n const spec = pkg.version\n ? `${pkg.packageName}@${pkg.version}`\n : pkg.packageName;\n const url = `${cdnUrl}/${spec}/powerhouse.manifest.json`;\n try {\n const response = await fetchImpl(url, {\n signal: AbortSignal.timeout(REGISTRY_FETCH_TIMEOUT_MS),\n });\n // 404 = the package ships no manifest on the CDN — silent, like a local\n // package without a manifest file.\n if (response.status === 404) return null;\n if (!response.ok) {\n onWarn(\n `PWA config: registry returned ${response.status} for ${spec}'s manifest; its pwa fragment (if any) is skipped.`,\n );\n return null;\n }\n const manifest: unknown = await response.json();\n return toPwaContribution(manifest, pkg.packageName, onWarn);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n onWarn(\n `PWA config: could not fetch ${spec}'s manifest from the registry (${message}); its pwa fragment (if any) is skipped.`,\n );\n return null;\n }\n}\n\n/**\n * Read the `pwa` fragment of each package in `packages`, in the given order\n * (which becomes their merge precedence — later packages win scalar\n * conflicts). `provider: \"local\"` packages are read from node_modules;\n * everything else is fetched from the registry CDN (skipped with a warning\n * when `registryUrl` is missing or the registry is unreachable). Packages\n * with no `pwa` fragment are simply absent from the result.\n */\nexport async function collectPackagePwaContributions(options: {\n packages: PowerhousePackage[];\n projectRoot?: string;\n registryUrl?: string | null;\n onWarn?: (message: string) => void;\n /** Injectable for tests. */\n fetchImpl?: typeof fetch;\n}): Promise<PwaContribution[]> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const onWarn = options.onWarn ?? (() => {});\n const fetchImpl = options.fetchImpl ?? fetch;\n const cdnUrl = options.registryUrl ? toCdnUrl(options.registryUrl) : null;\n\n const results = await Promise.all(\n options.packages.map(async (pkg) => {\n if (pkg.provider === \"local\") {\n return readLocalPackagePwaFragment(\n projectRoot,\n pkg.packageName,\n onWarn,\n );\n }\n if (!cdnUrl) {\n onWarn(\n `PWA config: no packageRegistryUrl configured; cannot read ${pkg.packageName}'s pwa fragment (if any) from the registry.`,\n );\n return null;\n }\n return fetchRegistryPwaFragment(cdnUrl, pkg, onWarn, fetchImpl);\n }),\n );\n return results.filter(\n (contribution): contribution is PwaContribution => contribution !== null,\n );\n}\n\n/**\n * Read the pwa fragment from the project's OWN manifest\n * (`powerhouse.manifest.json` under the project root, falling back to the\n * `dist/` copy the project build emits). The root file comes first — it is\n * the source the dist copy is made from, and a stale dist left by an older\n * build must not shadow it. Returns null silently when no manifest exists —\n * not every project ships one — or when it carries neither a `pwa` block nor a\n * `category` to derive `categories` from.\n *\n * The `pwa` block is parsed STRICTLY, like `connect.pwa` and unlike third-party\n * package fragments: the project's own manifest is the developer's config, so\n * an invalid `pwa` block (a typo, or a removed/unknown field such as\n * `protocol_handlers`) FAILS the build instead of being silently skipped — a\n * silently-dropped field would be far harder to notice.\n */\nexport function collectProjectPwaContribution(options: {\n projectRoot?: string;\n}): PwaContribution | null {\n const projectRoot = options.projectRoot ?? process.cwd();\n for (const rel of [\n \"powerhouse.manifest.json\",\n \"dist/powerhouse.manifest.json\",\n ]) {\n const manifestPath = path.resolve(projectRoot, rel);\n if (!fs.existsSync(manifestPath)) continue;\n let manifest: unknown;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Could not parse ${manifestPath}: ${message}`);\n }\n if (!isPlainObject(manifest)) return null;\n const label =\n typeof manifest.name === \"string\" && manifest.name\n ? manifest.name\n : \"project manifest\";\n const config =\n manifest.pwa === undefined\n ? {}\n : parsePwaConfigStrict(manifest.pwa, `pwa in ${manifestPath}`);\n const withCategory = withInferredCategory(config, manifest.category);\n if (Object.keys(withCategory).length === 0) return null;\n return { source: label, config: withCategory };\n }\n return null;\n}\n\n/** Strictly parse a PWA config block, throwing a build-failing error (naming\n * the offending field) when it is invalid. Used for the developer's own config\n * (`connect.pwa` and the project manifest's `pwa`), where a silent drop would\n * be a footgun — unlike third-party package fragments, which warn + skip. */\nfunction parsePwaConfigStrict(\n config: unknown,\n description: string,\n): PHConnectPwa {\n const parsed = PwaConfigSchema.safeParse(config);\n if (!parsed.success) {\n throw new Error(\n `Invalid ${description}: ${formatZodIssues(parsed.error)}. Fix it or remove the field.`,\n );\n }\n return parsed.data;\n}\n\n/**\n * Validate the project's `connect.pwa` block. Unlike package fragments\n * (third-party, warn + skip), the user's own config fails the build: a typo\n * that silently dropped offline coverage would be far harder to notice.\n */\nexport function validateProjectPwaConfig(\n config: unknown,\n configPath: string,\n): PHConnectPwa {\n return parsePwaConfigStrict(config, `connect.pwa in ${configPath}`);\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Plugin } from \"vite\";\n\n// PWA manifest icons emitted into the build from the @powerhousedao/connect\n// package assets. The `ph connect build` Vite root is a scaffolded project that\n// has no PWA icons of its own, so — like connectFaviconPlugin does for the\n// favicon — we resolve them out of the installed connect package and emit them\n// as build assets. vite-plugin-pwa references these filenames in the generated\n// manifest and precaches them via its png glob. The document icons are the\n// OS-level file-type icons referenced by the .phd/.phdm file_handlers.\nconst PWA_ICONS = [\n \"pwa-192x192.png\",\n \"pwa-512x512.png\",\n \"pwa-512x512-maskable.png\",\n \"document-icon-192x192.png\",\n \"document-icon-512x512.png\",\n] as const;\n\nexport function connectPwaIconsPlugin(): Plugin {\n return {\n name: \"copy-connect-pwa-icons\",\n async generateBundle(_options, bundle) {\n for (const icon of PWA_ICONS) {\n try {\n if (icon in bundle) continue;\n const resolved = await this.resolve(\n `@powerhousedao/connect/assets/${icon}`,\n );\n if (!resolved) continue;\n this.emitFile({\n type: \"asset\",\n fileName: icon,\n source: readFileSync(resolved.id),\n });\n } catch {\n // connect package or icon not found — skip; the manifest still\n // generates, the icon URL just 404s (non-fatal for offline caching).\n }\n }\n },\n };\n}\n","import {\n mergeManifest,\n PWA_FILE_HANDLER_ACTION,\n unionStrings,\n type PHConnectPwa,\n type PwaWebManifest,\n} from \"@powerhousedao/shared/connect\";\nimport type { ManifestOptions } from \"vite-plugin-pwa\";\n\n// Applies the effective (already merged, see mergePwaConfig) serialisable PWA\n// fragment onto Connect's hardcoded base. The manifest merge is delegated to\n// the browser-safe `mergeManifest` in @powerhousedao/shared/connect so the\n// exact same code shapes the manifest here (build time) and inside the service\n// worker (runtime, for dynamically-installed packages). This module only adds\n// the vite-plugin-pwa manifest TYPES and the precache-glob merge; the Workbox\n// runtime-caching / navigation behaviour now lives in the hand-written service\n// worker (see connect-utils/service-worker/service-worker.ts), because\n// `injectManifest` has no declarative runtimeCaching option.\n\n// Re-exported so existing importers (pwa.ts, the e2e test) keep a stable name\n// while the constant's source of truth moves to @powerhousedao/shared/connect.\nexport { PWA_FILE_HANDLER_ACTION as FILE_HANDLER_ACTION };\n\n/** A manifest file-handler entry. vite-plugin-pwa's own type stops at\n * `{ action; accept }`; the spec'd `icons`/`launch_type` members are added\n * here — the manifest is emitted as verbatim JSON, so they ship through. */\nexport type ConnectPwaFileHandler = NonNullable<\n ManifestOptions[\"file_handlers\"]\n>[number] & {\n icons?: ManifestOptions[\"icons\"];\n launch_type?: \"single-client\" | \"multiple-clients\";\n};\n\n/** The web-app manifest exactly as VitePWA accepts it, with the file-handler\n * entries widened to their full spec'd shape. */\nexport type ConnectPwaManifest = Omit<\n Partial<ManifestOptions>,\n \"file_handlers\"\n> & {\n file_handlers?: ConnectPwaFileHandler[];\n};\n\n/** The precache-driving subset of the old Workbox config. Under injectManifest\n * these are the `injectManifest` options; `self.__WB_MANIFEST` is generated\n * from them. Everything else (runtimeCaching, navigation, clientsClaim, …) is\n * imperative code in the service worker. */\nexport type ConnectPrecacheOptions = {\n globPatterns: string[];\n globIgnores: string[];\n maximumFileSizeToCacheInBytes: number;\n};\n\n/**\n * Lay an effective PWA fragment over the plugin's hardcoded manifest + precache\n * base. The manifest is merged by the shared `mergeManifest` with\n * `fragment-wins` scalars (the build-time effective config is the authority);\n * icons and file handlers concatenate after the base set (contributed handlers\n * get Connect's fixed action injected — the open route is not configurable);\n * globs union; the size ceiling takes the max.\n *\n * The serialisable `runtimeCaching` / `navigateFallbackDenylist` overrides are\n * NOT handled here — they are passed straight to the service worker (which\n * registers them after its built-in rules), because injectManifest has no\n * declarative runtimeCaching and Workbox is first-match-wins, so an override\n * can only be appended after the built-ins (intentional for v1).\n */\nexport function applyPwaOverrides(\n base: { manifest: ConnectPwaManifest; precache: ConnectPrecacheOptions },\n override: PHConnectPwa,\n): { manifest: ConnectPwaManifest; precache: ConnectPrecacheOptions } {\n const manifest = mergeManifest(\n base.manifest as PwaWebManifest,\n override.manifest,\n { scalarPolicy: \"fragment-wins\" },\n ) as ConnectPwaManifest;\n\n const precache: ConnectPrecacheOptions = {\n globPatterns: override.globPatterns?.length\n ? unionStrings(base.precache.globPatterns, override.globPatterns)\n : base.precache.globPatterns,\n globIgnores: override.globIgnores?.length\n ? unionStrings(base.precache.globIgnores, override.globIgnores)\n : base.precache.globIgnores,\n maximumFileSizeToCacheInBytes:\n typeof override.maximumFileSizeToCacheInBytes === \"number\"\n ? Math.max(\n base.precache.maximumFileSizeToCacheInBytes,\n override.maximumFileSizeToCacheInBytes,\n )\n : base.precache.maximumFileSizeToCacheInBytes,\n };\n\n return { manifest, precache };\n}\n","import { type PHConnectPwa } from \"@powerhousedao/shared/connect\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Plugin, PluginOption } from \"vite\";\nimport { VitePWA } from \"vite-plugin-pwa\";\nimport { connectPwaIconsPlugin } from \"./pwa-icons.js\";\nimport {\n applyPwaOverrides,\n FILE_HANDLER_ACTION,\n type ConnectPrecacheOptions,\n type ConnectPwaManifest,\n} from \"./pwa-overrides.js\";\n\n/**\n * Connect's hardcoded PWA manifest. The base layer of the override ladder —\n * package `pwa` fragments and the project's `connect.pwa` block are laid on\n * top of this by `applyPwaOverrides`.\n */\nconst BASE_MANIFEST: ConnectPwaManifest = {\n name: \"Powerhouse Connect\",\n short_name: \"Connect\",\n description:\n \"A navigation, collaboration and reporting tool for decentralised and open organisations.\",\n theme_color: \"#ffffff\",\n background_color: \"#ffffff\",\n display: \"standalone\",\n start_url: \".\",\n scope: \".\",\n icons: [\n { src: \"pwa-192x192.png\", sizes: \"192x192\", type: \"image/png\" },\n { src: \"pwa-512x512.png\", sizes: \"512x512\", type: \"image/png\" },\n {\n // Full-bleed variant: maskable icons get cropped to the platform shape,\n // so the logo sits inside the safe zone instead of reusing the rounded\n // \"any\" icon (whose transparent corners would show through the mask).\n src: \"pwa-512x512-maskable.png\",\n sizes: \"512x512\",\n type: \"image/png\",\n purpose: \"maskable\",\n },\n ],\n // OS-level file associations for the installed PWA (File Handling API,\n // Chromium desktop). Powerhouse documents are zip archives, but keying on\n // application/zip would make Connect a candidate handler for EVERY zip on\n // MIME-keyed platforms — hence the vendor types with the RFC 6839 +zip\n // suffix. Config-contributed handlers are appended after this entry, and\n // Chromium is first-registered-wins per extension, so .phd/.phdm cannot be\n // hijacked by a package. Consuming the launched files happens in the\n // Connect SPA (launchQueue consumer).\n file_handlers: [\n {\n action: FILE_HANDLER_ACTION,\n accept: {\n \"application/vnd.powerhouse.document+zip\": [\".phd\"],\n \"application/vnd.powerhouse.document-model+zip\": [\".phdm\"],\n },\n // OS file-type icons: the same Powerhouse document icon the in-app\n // import list shows. Declared per spec, but note Chromium doesn't\n // consume them on desktop yet — macOS synthesizes document icons from\n // the app icon (no CFBundleTypeIconFile is written), and Windows\n // support is unimplemented (FileHandlingIconsSupportedByOs() is false,\n // crbug.com/40185571). Shipping them is forward-compatible and costs\n // nothing. Assets emitted by connectPwaIconsPlugin, precached via the\n // png glob.\n icons: [\n {\n src: \"document-icon-192x192.png\",\n sizes: \"192x192\",\n type: \"image/png\",\n },\n {\n src: \"document-icon-512x512.png\",\n sizes: \"512x512\",\n type: \"image/png\",\n },\n ],\n },\n ],\n // Opening a handled file focuses the running Connect window (launchQueue\n // delivers the file there) instead of spawning a new window per file.\n launch_handler: { client_mode: \"focus-existing\" },\n};\n\n/**\n * Connect's hardcoded precache config — the base layer for the `injectManifest`\n * precache. Overridable additively (extra globs) or by raising the size ceiling\n * via package/project `pwa` config. The rest of the old Workbox config\n * (runtime-caching rules with their function urlPatterns, the navigation\n * fallback, clientsClaim/skipWaiting/cleanupOutdatedCaches) now lives as\n * imperative code in the hand-written service worker\n * (../service-worker/service-worker.ts), because `injectManifest` has no\n * declarative runtimeCaching option.\n */\nexport const BASE_PRECACHE: ConnectPrecacheOptions = {\n // PGlite's wasm + fs bundles are several MB each; Workbox's 2 MiB\n // default would silently skip them and the in-browser Postgres would\n // fail to initialise offline. Raise the ceiling so they precache.\n maximumFileSizeToCacheInBytes: 16 * 1024 * 1024,\n // Precache the app shell AND the PGlite assets. The default glob omits\n // `.wasm`/`.data`, but PGlite's Postgres-in-wasm needs both its `.wasm`\n // and its `.data` filesystem bundles, or the in-browser DB fails to\n // initialise offline (\"Failed to fetch\").\n // The reactor worker's metadata and package manifest are fetched at boot;\n // without them an offline boot cannot find the worker bundle.\n globPatterns: [\n \"**/*.{js,css,html,wasm,data,ico,png,svg,webp,woff,woff2}\",\n \"__reactor_worker__/**/*.json\",\n ],\n // index.html stays OUT of the precache on purpose: the SPA navigation\n // route serves it NetworkFirst (see service-worker.ts). The precache\n // strategy is cache-first with no network revalidation, so a precached\n // shell would pin every page load — reloads included — to the build that\n // was active when the controlling worker installed. Excluding the shell\n // lets a reload after a deploy (or a different project on the same\n // localhost port) fetch the fresh index.html from the network.\n // powerhouse.config.json is operator-editable and served no-cache, so\n // precaching it would freeze runtime config; source maps don't belong\n // in the precache either. manifest.webmanifest is added at wiring time so\n // the SW's dynamic manifest route is the sole producer at that URL.\n globIgnores: [\"**/powerhouse.config.json\", \"**/*.map\", \"index.html\"],\n};\n\nconst SW_FILENAME = \"service-worker.ts\";\n\n/**\n * Absolute directory holding the hand-written service-worker source. Resolved\n * relative to THIS module so it works from source\n * (connect-utils/vite-plugins → ../service-worker) and from the bundled dist\n * (dist/index.mjs → ./service-worker, where tsdown copies it). vite-plugin-pwa\n * resolves `swSrc = path.resolve(root, srcDir, filename)`, and `path.resolve`\n * ignores `root` when `srcDir` is absolute — so the SW ships with\n * builder-tools instead of every project needing its own copy.\n */\nfunction resolveServiceWorkerDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(here, \"../service-worker\"), // source layout\n resolve(here, \"service-worker\"), // bundled dist layout\n ];\n return (\n candidates.find((dir) => existsSync(join(dir, SW_FILENAME))) ??\n candidates[0]\n );\n}\n\n/**\n * Virtual module that feeds the hand-written SW its build-time data. Passed\n * into vite-plugin-pwa's SEPARATE injectManifest build via\n * `injectManifest.buildPlugins.vite`: that build runs with `configFile: false`,\n * so the app's own plugins aren't present, but buildPlugins (and `define`) are.\n */\nfunction phSwConfigPlugin(data: Record<string, unknown>): Plugin {\n const virtualId = \"virtual:ph-sw-config\";\n const resolvedId = `\\0${virtualId}`;\n return {\n name: \"ph-sw-config\",\n resolveId(id) {\n if (id === virtualId) return resolvedId;\n },\n load(id) {\n if (id !== resolvedId) return;\n return Object.entries(data)\n .map(\n ([key, value]) => `export const ${key} = ${JSON.stringify(value)};`,\n )\n .join(\"\\n\");\n },\n };\n}\n\n/**\n * Service-worker / PWA support for Connect, gated by `connect.app.offline`.\n *\n * When enabled (the default), Workbox `injectManifest` bundles Connect's\n * hand-written service worker (../service-worker/service-worker.ts), which\n * precaches the built app shell so Connect loads with no network, runtime-\n * caches the Google-hosted Inter font + the registry CDN + the runtime config,\n * AND serves a dynamic web-app manifest so packages installed AT RUNTIME can\n * extend it (their fragments are mirrored into IndexedDB by the SPA; the base\n * the SW merges onto is embedded here at build time). The manifest and precache\n * config start from the BASE_* defaults above and are extended by `pwa` — the\n * effective, already-merged overrides from build-time packages and the\n * project's `connect.pwa` block (see mergePwaConfig). Registration is left to\n * the Connect SPA (`serviceWorkerManager`, `injectRegister: null`).\n *\n * When disabled, a self-destroying worker is emitted at the same URL so any\n * worker a previous offline-enabled build installed unregisters itself and\n * clears its caches on the browser's next service-worker update check.\n */\nexport function connectPwaPlugins(options: {\n offlineEnabled: boolean;\n /** Effective PWA overrides (packages + project), already merged. */\n pwa?: PHConnectPwa;\n}): PluginOption[] {\n const { offlineEnabled, pwa } = options;\n\n if (!offlineEnabled) {\n return [\n VitePWA({\n selfDestroying: true,\n strategies: \"generateSW\",\n injectRegister: null,\n filename: \"service-worker.js\",\n devOptions: { enabled: false },\n }),\n ];\n }\n\n const { manifest, precache } = applyPwaOverrides(\n { manifest: BASE_MANIFEST, precache: BASE_PRECACHE },\n pwa ?? {},\n );\n\n // Build-time data handed to the SW via the virtual module. EMBEDDED_BASE_\n // MANIFEST is the base the runtime manifest route merges dynamically-\n // installed package fragments onto; the two EXTRA_* arrays are the\n // serialisable build-time contributions the SW registers after its built-ins.\n const swConfig = {\n EMBEDDED_BASE_MANIFEST: manifest,\n EXTRA_RUNTIME_CACHING: pwa?.runtimeCaching ?? [],\n NAVIGATE_FALLBACK_DENYLIST_EXTRA: pwa?.navigateFallbackDenylist ?? [],\n };\n\n return [\n connectPwaIconsPlugin(),\n VitePWA({\n strategies: \"injectManifest\",\n // Absolute srcDir → swSrc is builder-tools' own SW source; the emitted\n // file is service-worker.js (vite-plugin-pwa maps the .ts source).\n srcDir: resolveServiceWorkerDir(),\n filename: SW_FILENAME,\n // prompt → the new worker waits; the SPA surfaces a refresh prompt and\n // posts SKIP_WAITING when the user accepts (see serviceWorkerManager).\n registerType: \"prompt\",\n injectRegister: null,\n // ph connect studio keeps running without a service worker.\n devOptions: { enabled: false },\n // Icons are emitted by connectPwaIconsPlugin and precached via the png\n // glob, so the plugin must not also try to resolve them from /public.\n includeManifestIcons: false,\n // Still emitted as the static base/offline fallback + the <link>.\n manifest,\n injectManifest: {\n globPatterns: precache.globPatterns,\n // Exclude the webmanifest from precache so the SW's dynamic route is\n // the sole producer at that URL.\n globIgnores: [...precache.globIgnores, \"**/manifest.webmanifest\"],\n maximumFileSizeToCacheInBytes: precache.maximumFileSizeToCacheInBytes,\n buildPlugins: { vite: [phSwConfigPlugin(swConfig)] },\n },\n }),\n ];\n}\n","// Self-host React: emit the React family into the Connect dist and point the\n// page import map at it, instead of resolving react/react-dom from esm.sh.\nimport { spawn } from \"node:child_process\";\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join, resolve } from \"node:path\";\nimport type { Plugin } from \"vite\";\n\n// URL path (under base) the React bundle is emitted/served at.\nconst REACT_URL_DIR = \"__react__\";\n\n// Packages whose every browser-importable subpath is self-hosted.\nconst REACT_PACKAGES = [\"react\", \"react-dom\"];\n\n// Resolve an exports value to its browser-preferred target, or null.\nfunction importTarget(value: unknown): string | null {\n if (typeof value === \"string\") return value;\n if (!value || typeof value !== \"object\") return null;\n const o = value as Record<string, unknown>;\n for (const c of [\"browser\", \"import\", \"module\", \"default\"]) {\n if (c in o) {\n const t = importTarget(o[c]);\n if (t) return t;\n }\n }\n return null;\n}\n\n// All browser-usable subpaths of react/react-dom, mapped to the absolute file\n// their browser condition resolves to. Node/bun-only targets are skipped.\nfunction resolveReactEntries(dirname: string): Record<string, string> {\n const require = createRequire(join(dirname, \"noop.js\"));\n const out: Record<string, string> = {};\n for (const pkg of REACT_PACKAGES) {\n let pkgRoot: string;\n let exp: unknown;\n try {\n const pkgJsonPath = require.resolve(`${pkg}/package.json`);\n pkgRoot = pathDirname(pkgJsonPath);\n exp = (\n JSON.parse(readFileSync(pkgJsonPath, \"utf8\")) as { exports?: unknown }\n ).exports;\n } catch {\n continue;\n }\n if (!exp || typeof exp !== \"object\") continue;\n for (const key of Object.keys(exp as Record<string, unknown>)) {\n if (key === \"./package.json\" || key.includes(\"*\")) continue;\n const target = importTarget((exp as Record<string, unknown>)[key]);\n // Skip non-JS and runtime-only (node/bun) targets — unusable in a browser.\n if (!target || /\\.(json|css)$/.test(target)) continue;\n if (/\\.(node|bun)\\.js$/.test(target)) continue;\n const file = join(pkgRoot, target);\n if (!existsSync(file)) continue;\n out[key === \".\" ? pkg : `${pkg}${key.slice(1)}`] = file;\n }\n }\n return out;\n}\n\nexport interface ReactSelfHostOptions {\n // Project root used to resolve react/react-dom and run the sub-build.\n dirname: string;\n // Emit the development React build (warnings/act) instead of production.\n dev?: boolean;\n}\n\n// Emits one React variant (dev or prod, per options.dev) into the dist and\n// injects a static import map pointing every react/react-dom subpath at it.\nexport function reactSelfHostPlugin(options: ReactSelfHostOptions): Plugin {\n const entries = resolveReactEntries(options.dirname);\n let absOutDir = resolve(options.dirname, \"dist\");\n let importMap: Record<string, string> = {};\n return {\n name: \"ph-react-self-host\",\n apply: \"build\",\n configResolved(config) {\n absOutDir = resolve(config.root, config.build.outDir);\n // Entry URLs mirror the specifier (react-dom/client -> __react__/react-dom/client.js)\n // so the trailing-slash catch-alls below resolve any subpath to the same file.\n importMap = Object.fromEntries(\n Object.keys(entries).map((spec) => [\n spec,\n `${config.base}${REACT_URL_DIR}/${spec}.js`,\n ]),\n );\n // Catch-all per package: an unenumerated react/* import resolves to the single\n // self-hosted instance (same-origin) instead of failing import-map resolution.\n for (const pkg of REACT_PACKAGES) {\n importMap[`${pkg}/`] = `${config.base}${REACT_URL_DIR}/${pkg}/`;\n }\n },\n transformIndexHtml() {\n if (!Object.keys(importMap).length) return;\n return [\n {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: importMap }),\n injectTo: \"head-prepend\",\n },\n ];\n },\n async closeBundle() {\n if (!Object.keys(entries).length) return;\n const { ok, stderr } = await runReactBuild(\n options.dirname,\n join(absOutDir, REACT_URL_DIR),\n entries,\n options.dev ? \"development\" : \"production\",\n );\n if (!ok) {\n this.error(\n `react self-host build failed${stderr.trim() ? `:\\n${stderr.trim()}` : \"\"}`,\n );\n }\n },\n };\n}\n\n// Spawn a throwaway worker that builds the React family; peak build memory is\n// reclaimed when the subprocess exits.\nfunction runReactBuild(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n): Promise<{ ok: boolean; stderr: string }> {\n mkdirSync(outDir, { recursive: true });\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, REACT_BUILD_WORKER);\n return new Promise((resolvePromise) => {\n const child = spawn(\n process.execPath,\n [workerPath, dirname, outDir, JSON.stringify(entries), nodeEnv],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += String(d)));\n child.stderr.on(\"data\", (d) => (out += String(d)));\n const done = (r: { ok: boolean; stderr: string }) => {\n rmSync(workerPath, { force: true });\n resolvePromise(r);\n };\n child.on(\"exit\", (code) => done({ ok: code === 0, stderr: out }));\n child.on(\"error\", (e) => done({ ok: false, stderr: String(e) }));\n });\n}\n\n// Worker: one ESM entry per subpath with explicit named re-exports. Names come\n// from the browser-resolved file (node names differ for server/static).\nconst REACT_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { mkdirSync, writeFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nconst [dirname, outDir, entriesJSON, nodeEnv] = process.argv.slice(2);\nconst entries = JSON.parse(entriesJSON);\nconst reqProj = createRequire(join(dirname, 'noop.js'));\n// pathToFileURL: require.resolve returns an absolute path, and on Windows\n// import('D:\\\\...') parses \"D:\" as a URL scheme (ERR_UNSUPPORTED_ESM_URL_SCHEME).\nconst { build } = await import(pathToFileURL(reqProj.resolve('vite')).href);\nconst srcDir = join(outDir, '.entries');\nmkdirSync(srcDir, { recursive: true });\nconst entryName = (spec) => spec.replace(/[^\\\\w]+/g, '_');\nconst RESERVED = new Set('enum void null function in instanceof typeof new delete do if else return switch case break continue for while this true false class const let var default export import extends super with yield debugger finally throw try catch await implements interface package private protected public static eval arguments'.split(' '));\nconst input = {};\nfor (const [spec, file] of Object.entries(entries)) {\n const name = entryName(spec);\n let names = [];\n try {\n const ns = await import(pathToFileURL(file).href);\n const obj = (ns.default && typeof ns.default === 'object') ? ns.default : ns;\n names = Object.keys(obj).filter((k) => k !== 'default' && k !== '__esModule' && /^[A-Za-z_$][\\\\w$]*$/.test(k));\n } catch {}\n const plain = names.filter((n) => !RESERVED.has(n));\n const reserved = names.filter((n) => RESERVED.has(n));\n let src = 'import __m from ' + JSON.stringify(spec) + ';\\\\nexport default __m;\\\\n';\n if (plain.length) src += 'export const { ' + plain.join(', ') + ' } = __m;\\\\n';\n reserved.forEach((n, i) => {\n src += 'const __r' + i + ' = __m[' + JSON.stringify(n) + '];\\\\nexport { __r' + i + ' as ' + n + ' };\\\\n';\n });\n const entryFile = join(srcDir, name + '.js');\n writeFileSync(entryFile, src);\n // Key by the full spec so the output path mirrors the subpath\n // (react-dom/client -> react-dom/client.js), matching the catch-all import map.\n input[spec] = entryFile;\n}\ntry {\n await build({\n root: dirname, configFile: false, logLevel: 'error',\n base: './', publicDir: false,\n define: { 'process.env.NODE_ENV': JSON.stringify(nodeEnv) },\n resolve: { conditions: ['browser', 'import', 'module', 'default'] },\n build: {\n outDir, emptyOutDir: false, minify: nodeEnv === 'production', target: 'esnext',\n rollupOptions: {\n input, preserveEntrySignatures: 'strict',\n output: { format: 'es', entryFileNames: '[name].js', chunkFileNames: 'chunks/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]' },\n },\n },\n });\n rmSync(srcDir, { recursive: true, force: true });\n // Force exit: rolldown can leave native worker threads alive that keep the\n // event loop open, hanging the parent's spawn() promise indefinitely.\n process.exit(0);\n} catch (err) {\n console.error(err instanceof Error ? (err.stack ?? err.message) : String(err));\n process.exit(1);\n}\n`;\n","import { createReadStream } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport {\n prebuildReactorWorker,\n REACTOR_WORKER_ENTRY,\n REACTOR_WORKER_MIME,\n REACTOR_WORKER_URL_PREFIX,\n type PrebuiltReactorWorker,\n} from \"../reactor-worker-build.js\";\n\n// Dev bundle cache, sibling of the vendor's `.ph-vendor`.\nconst DEV_BUNDLE_DIR = \"node_modules/.ph-reactor-worker\";\n\nfunction withBase(base: string, p: string): string {\n return `${base}${p}`.replace(/\\/{2,}/g, \"/\");\n}\n\n/**\n * Dev-only: serve Connect's reactor SharedWorker bundle under\n * `<base>__reactor_worker__/`, building it lazily on first request.\n *\n * The dev server serves Connect from its prebuilt dist in node_modules, where\n * `dist/reactor.worker.js` is a library artifact no worker can resolve. The\n * tab GETs `worker-meta.json` here (JSON, no-cache, written by\n * `prebuildReactorWorker`) to find the bundle and fold its `sourceDigest`\n * into its version fingerprint; without this plugin that GET fails and the\n * worker feature reports itself unavailable instead of dying opaquely.\n *\n * Lazy because it is a full `vite build` of the reactor + PGlite graph. The\n * result is cached in node_modules/.ph-reactor-worker until the installed\n * Connect, its upstream dists, or builder-tools change (`computeSourceDigest`).\n */\nexport function reactorWorkerDevPlugin(projectRoot: string): Plugin {\n let base = \"/\";\n let building: Promise<PrebuiltReactorWorker | null> | null = null;\n\n const ensureBuilt = (): Promise<PrebuiltReactorWorker | null> => {\n building ??= (async () => {\n const errorRef: { message?: string } = {};\n const built = await prebuildReactorWorker({\n dirname: projectRoot,\n outDir: path.join(projectRoot, DEV_BUNDLE_DIR),\n nodeEnv: \"development\",\n errorRef,\n });\n if (!built) {\n console.warn(\n `[connect] reactor worker bundle build failed${\n errorRef.message ? `: ${errorRef.message}` : \"\"\n }`,\n );\n // Allow a retry on the next request instead of caching the failure\n // for the server's lifetime.\n building = null;\n }\n return built;\n })();\n return building;\n };\n\n return {\n name: \"ph-reactor-worker-dev\",\n apply: \"serve\",\n configResolved(config) {\n base = config.base;\n },\n configureServer(server) {\n const prefixes = [\n withBase(base, REACTOR_WORKER_URL_PREFIX),\n REACTOR_WORKER_URL_PREFIX,\n ];\n server.middlewares.use((req, res, next) => {\n const url = (req.url ?? \"\").split(\"?\")[0];\n const prefix = prefixes.find((p) => url.startsWith(p));\n if (!prefix) return next();\n const name = url.slice(prefix.length).replace(/^\\/+/, \"\");\n if (!name) return next();\n\n void (async () => {\n const built = await ensureBuilt();\n if (!built) {\n res.statusCode = 503;\n res.setHeader(\"Content-Type\", \"text/plain\");\n res.end(\n \"reactor worker bundle unavailable (build failed; see server log)\",\n );\n return;\n }\n const file = path.join(built.outDir, name);\n // Path-segment containment: reject anything escaping the bundle dir.\n const rel = path.relative(built.outDir, file);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n next();\n return;\n }\n const stream = createReadStream(file);\n stream.on(\"error\", () => {\n if (!res.headersSent) next();\n });\n stream.once(\"open\", () => {\n const ext = file.slice(file.lastIndexOf(\".\"));\n res.setHeader(\n \"Content-Type\",\n REACTOR_WORKER_MIME[ext] ?? \"text/javascript\",\n );\n // Everything except the entry (stable name, changes with the\n // installed Connect) and the metadata is content-hashed.\n const hashed =\n !name.startsWith(REACTOR_WORKER_ENTRY) && !name.endsWith(\".json\");\n res.setHeader(\n \"Cache-Control\",\n hashed ? \"public, max-age=31536000, immutable\" : \"no-cache\",\n );\n stream.pipe(res);\n });\n })();\n });\n },\n };\n}\n","import type { Plugin } from \"vite\";\n\n/**\n * Marker attribute on the injected script. Serve-time injectors (e.g. the\n * ph-clint connect proxy) and this plugin both check it, so the script is\n * applied exactly once no matter which layer runs first.\n */\nexport const THEME_BOOT_MARKER = \"data-ph-theme-boot\";\n\n/**\n * Pre-paint theme boot: `?theme=dark|light` persists to `ph:theme`, then the\n * stored choice (or system preference) decides the `.dark` root class before\n * hydration. Fail-silent — storage access can throw in embed/privacy contexts.\n * Keep semantically identical to the runtime store in\n * `@powerhousedao/reactor-browser` (hooks/theme.ts).\n */\nconst THEME_BOOT_SCRIPT =\n `(function(){try{` +\n `var p=new URLSearchParams(location.search).get('theme');` +\n `if(p==='dark'||p==='light')localStorage.setItem('ph:theme',p);` +\n `var s=localStorage.getItem('ph:theme');` +\n `var d=s==='dark'||((!s||s==='system')&&matchMedia('(prefers-color-scheme: dark)').matches);` +\n `document.documentElement.classList.toggle('dark',d);` +\n `}catch(e){}})();`;\n\n/**\n * Injects the theme boot script at the top of `<head>` of every emitted\n * index.html, so built Connect apps render the stored theme from first paint\n * without depending on a serve-time injector.\n */\nexport function connectThemeBootPlugin(): Plugin {\n return {\n name: \"ph-connect-theme-boot\",\n transformIndexHtml(html) {\n if (html.includes(THEME_BOOT_MARKER)) return;\n return {\n html,\n tags: [\n {\n tag: \"script\",\n attrs: { [THEME_BOOT_MARKER]: \"\" },\n children: THEME_BOOT_SCRIPT,\n injectTo: \"head-prepend\",\n },\n ],\n };\n },\n };\n}\n","// Merge the production vendor's import-map entries into the page's\n// `<script type=\"importmap\">`. Build-only.\n//\n// Connect already self-hosts React: `reactSelfHostPlugin` (registered before\n// this plugin) returns an import-map tag, which Vite injects into the HTML\n// string before the next transformIndexHtml hook runs. So by the time this\n// hook sees the HTML, the React map is an inline script — we merge the\n// vendor entries into it. If no import map exists (a consumer disabled\n// react self-host), we inject one.\nimport type { HtmlTagDescriptor, Plugin } from \"vite\";\n\nexport type VendorImportMapOptions = {\n /** bare specifier -> URL (already base-prefixed by the caller). */\n imports: Record<string, string>;\n};\n\n// Pull the `imports` table out of a parsed import-map document without\n// trusting its shape: anything that isn't a string specifier->string value\n// is ignored, and malformed documents yield an empty table instead of a\n// throw.\nfunction extractImports(raw: unknown): Record<string, string> {\n if (typeof raw !== \"object\" || raw === null) return {};\n const imports = \"imports\" in raw ? raw.imports : undefined;\n if (typeof imports !== \"object\" || imports === null) return {};\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(imports)) {\n if (typeof value === \"string\") out[key] = value;\n }\n return out;\n}\n\nfunction parseImportMap(raw: string): Record<string, string> {\n try {\n return extractImports(JSON.parse(raw));\n } catch {\n return {};\n }\n}\n\nconst INLINE_IMPORTMAP = /<script type=\"importmap\">([\\s\\S]*?)<\\/script>/;\n\nexport function vendorImportMapPlugin(options: VendorImportMapOptions): Plugin {\n const vendorEntries = Object.keys(options.imports).length;\n return {\n name: \"ph-vendor-import-map\",\n apply: \"build\",\n transformIndexHtml(html) {\n if (!vendorEntries) return;\n\n // Merge into the existing map (the react self-host one, or a\n // consumer-provided one). Vendor entries win on specifier conflicts.\n const match = INLINE_IMPORTMAP.exec(html);\n if (match) {\n const merged = {\n imports: { ...parseImportMap(match[1]), ...options.imports },\n };\n return html.replace(\n INLINE_IMPORTMAP,\n `<script type=\"importmap\">${JSON.stringify(merged)}</script>`,\n );\n }\n\n // No map at all: inject one (head-prepend, the same position the\n // react map uses).\n const injected: HtmlTagDescriptor = {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: options.imports }),\n injectTo: \"head-prepend\",\n };\n return [injected];\n },\n };\n}\n","import type { PowerhouseConfig } from \"@powerhousedao/config\";\nimport { getConfig } from \"@powerhousedao/config/node\";\nimport {\n deepMerge,\n loadConnectEnv,\n mergePwaConfig,\n normalizeBasePath,\n setConnectEnv,\n} from \"@powerhousedao/shared/connect\";\nimport tailwind from \"@tailwindcss/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { realpathSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n createLogger,\n esmExternalRequirePlugin,\n loadEnv,\n searchForWorkspaceRoot,\n type HtmlTagDescriptor,\n type InlineConfig,\n type PluginOption,\n} from \"vite\";\nimport { createHtmlPlugin } from \"vite-plugin-html\";\nimport type { IConnectOptions } from \"./types.js\";\nimport {\n buildHashFromBuildOptions,\n connectBuildHashPlugin,\n} from \"./vite-plugins/build-hash.js\";\nimport { devReactImportmapPlugin } from \"./vite-plugins/dev-external-react.js\";\nimport {\n DYNAMIC_BASE_PLACEHOLDER,\n connectDynamicBasePlugin,\n} from \"./vite-plugins/dynamic-base.js\";\nimport { connectFaviconPlugin } from \"./vite-plugins/favicon.js\";\nimport { phBundledPackagesPlugin } from \"./vite-plugins/ph-bundled-packages.js\";\nimport { phConfigPlugin } from \"./vite-plugins/ph-config.js\";\nimport {\n collectPackagePwaContributions,\n collectProjectPwaContribution,\n validateProjectPwaConfig,\n} from \"./vite-plugins/pwa-packages.js\";\nimport { connectPwaPlugins } from \"./vite-plugins/pwa.js\";\nimport { reactSelfHostPlugin } from \"./vite-plugins/react-self-host.js\";\nimport { reactorWorkerDevPlugin } from \"./vite-plugins/reactor-worker-dev.js\";\nimport { connectThemeBootPlugin } from \"./vite-plugins/theme-boot.js\";\nimport { vendorImportMapPlugin } from \"./vite-plugins/vendor-import-map.js\";\n\nexport function getConnectHtmlTags(\n options: {\n registryUrl?: string | null;\n injectTo?: HtmlTagDescriptor[\"injectTo\"];\n } = {},\n) {\n const { registryUrl, injectTo = \"head\" } = options;\n return [\n {\n tag: \"meta\",\n attrs: {\n \"http-equiv\": \"Content-Security-Policy\",\n content: `script-src 'self' 'unsafe-inline' 'unsafe-eval'${registryUrl ? \" \" + registryUrl : \"\"}; worker-src 'self' blob:; object-src 'none'; base-uri 'self';`,\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:title\",\n content: \"Connect\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:type\",\n content: \"website\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:url\",\n content: \"https://apps.powerhouse.io/powerhouse/connect/\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:description\",\n content:\n \"Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation.\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:image\",\n content:\n \"https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:card\",\n content: \"summary_large_image\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:image\",\n content:\n \"https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:title\",\n content: \"Connect\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:description\",\n content:\n \"Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation.\",\n },\n injectTo,\n },\n ] as const satisfies HtmlTagDescriptor[];\n}\n\nfunction viteLogger({\n silence,\n}: {\n silence?: { warnings?: string[]; errors?: string[] };\n}) {\n const logger = createLogger();\n const loggerWarn = logger.warn.bind(logger);\n const loggerError = logger.error.bind(logger);\n\n logger.warn = (msg, options) => {\n if (silence?.warnings?.some((warning) => msg.includes(warning))) {\n return;\n }\n loggerWarn(msg, options);\n };\n\n logger.error = (msg, options) => {\n if (silence?.errors?.some((error) => msg.includes(error))) {\n return;\n }\n loggerError(msg, options);\n };\n\n return logger;\n}\n\nfunction parsePackagesEnvOverride(phPackagesStr: string) {\n return phPackagesStr\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean)\n .map((entry) => {\n const lastAt = entry.lastIndexOf(\"@\");\n if (lastAt > 0) {\n return {\n packageName: entry.slice(0, lastAt),\n version: entry.slice(lastAt + 1),\n provider: \"registry\" as const,\n };\n }\n return { packageName: entry, provider: \"registry\" as const };\n });\n}\n\nfunction getLocalPackageNamesFromPowerhouseConfig({\n packages,\n}: PowerhouseConfig) {\n if (!packages) return [];\n return packages\n .filter((p) => p.provider === \"local\")\n .map((p) => p.packageName);\n}\n\nexport function getConnectBaseViteConfig(options: IConnectOptions) {\n const mode = options.mode;\n const envDir = options.envDir ?? options.dirname;\n const fileEnv = loadEnv(mode, envDir, \"PH_\");\n\n // Load and validate environment with priority: process.env > fileEnv > defaults\n const env = loadConnectEnv({\n processEnv: process.env,\n fileEnv,\n });\n\n // set the resolved env to process.env so it's loaded by vite\n setConnectEnv(env);\n\n // Source config is always the project-root powerhouse.config.json.\n const phConfigPath = join(options.dirname, \"powerhouse.config.json\");\n\n const phConfig = options.powerhouseConfig ?? getConfig(phConfigPath);\n\n const packagesFromConfig = phConfig.packages ?? [];\n const localPackagesFromConfig =\n getLocalPackageNamesFromPowerhouseConfig(phConfig);\n const phPackagesStr = env.PH_PACKAGES;\n const envPhPackages = phPackagesStr\n ? parsePackagesEnvOverride(phPackagesStr)\n : undefined;\n\n const phPackages = envPhPackages ?? packagesFromConfig;\n\n // Precedence (highest → lowest): `ph connect build --packages-registry`\n // CLI override > source-config `packageRegistryUrl`. The resolved value\n // flows both into the CSP header (script-src allowance for the registry\n // CDN) and into the emitted runtime config so the SPA reads the same\n // value.\n const phPackageRegistryUrl =\n options.cliPackageRegistryUrl ?? phConfig.packageRegistryUrl ?? null;\n\n // Base path is a runtime-config field (connect.app.basePath), not an env\n // var. Resolve it with the same precedence as the rest of the connect\n // config: CLI override > source powerhouse.config.json.\n const connectBasePath =\n options.cliConnectOverride?.app?.basePath ??\n phConfig.connect?.app?.basePath;\n\n const offlineEnabled =\n options.cliConnectOverride?.app?.offline ??\n phConfig.connect?.app?.offline ??\n true;\n\n const authToken = env.PH_SENTRY_AUTH_TOKEN;\n const org = env.PH_SENTRY_ORG;\n const project = env.PH_SENTRY_PROJECT;\n // Release tag derived from the workspace version so it matches the\n // sourcemap upload tag CI uses.\n const release =\n process.env.WORKSPACE_VERSION ??\n process.env.npm_package_version ??\n env.PH_CONNECT_VERSION;\n const uploadSentrySourcemaps = authToken && org && project;\n\n // Build identity: baked into the bundle (define PH_CONNECT_BUILD_HASH) and\n // emitted as build-hash.json (which the server must serve no-cache). The\n // SPA compares the two; a mismatch means the server is serving a different\n // build than the one this bundle was built from — a same-origin \"new\n // deploy\" signal that works on localhost, where the old GitHub-branch\n // version check was meaningless.\n const buildHash = buildHashFromBuildOptions({\n dirname: options.dirname,\n phConfig,\n packages: phPackages,\n connectBasePath,\n offlineEnabled,\n packageRegistryUrl: phPackageRegistryUrl,\n });\n\n const connectHtmlTags = getConnectHtmlTags({\n registryUrl: phPackageRegistryUrl,\n });\n\n // Dev needs a placeholder importmap for devReactImportmapPlugin to rewrite;\n // builds get their map from reactSelfHostPlugin's boot script instead.\n const devImportmapTag =\n mode === \"development\"\n ? [\n {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: {} }),\n injectTo: \"head-prepend\" as const,\n },\n ]\n : [];\n\n const plugins: PluginOption[] = [\n tailwind(),\n react(),\n createHtmlPlugin({\n minify: false,\n inject: {\n tags: [...connectHtmlTags, ...devImportmapTag],\n },\n }),\n ] as const;\n\n if (uploadSentrySourcemaps) {\n plugins.push(\n import(\"@sentry/vite-plugin\").then(({ sentryVitePlugin }) =>\n sentryVitePlugin({\n release: {\n name: release ?? \"unknown\",\n inject: false, // prevent it from injecting the release id in the service worker code, this is done in 'src/app/sentry.ts' instead\n },\n authToken,\n org,\n project,\n bundleSizeOptimizations: {\n excludeDebugStatements: true,\n },\n reactComponentAnnotation: {\n enabled: true,\n },\n }),\n ) as PluginOption,\n );\n }\n\n // hide warnings unless LOG_LEVEL is set to debug, or the source config\n // declares connect.app.logLevel = \"debug\"\n const isDebug =\n process.env.LOG_LEVEL === \"debug\" ||\n phConfig.connect?.app?.logLevel === \"debug\";\n const customLogger = isDebug\n ? undefined\n : viteLogger({\n silence: {\n warnings: [\n \"@import must precede all other statements (besides @charset or empty @layer)\", // tailwindcss error when importing font file\n ],\n errors: [\"Unterminated string literal\"],\n },\n });\n\n // PWA overrides ladder: build-time-known package `pwa` fragments merge UNDER\n // the project's `connect.pwa` block (source deep-merged with the CLI/operator\n // override, CLI wins). Scalars are project-wins; arrays (icons, globs,\n // runtime-caching rules, denylist) are additive; the size ceiling takes the\n // max. Fragments come from the configured packages (local from node_modules,\n // registry from the CDN) and, last among packages, the project's own\n // manifest. The user's own connect.pwa is validated strictly (fails the\n // build); package fragments warn + skip inside the collectors.\n const projectPwa = validateProjectPwaConfig(\n deepMerge(\n phConfig.connect?.pwa ?? {},\n options.cliConnectOverride?.pwa ?? {},\n ),\n phConfigPath,\n );\n const pwaWarn = (msg: string) => (customLogger ?? console).warn(msg);\n // Registry fragments need the network, so only production builds fetch them\n // (dev/studio runs without a service worker and must not depend on the\n // registry being reachable). Async: Vite resolves promised plugins, same\n // pattern as the sentry plugin below.\n const pwaPackagesForFragments =\n mode === \"production\"\n ? phPackages\n : phPackages.filter((p) => p.provider === \"local\");\n const pwaPlugins: PluginOption = (async () => {\n if (!offlineEnabled) return connectPwaPlugins({ offlineEnabled });\n const contributions = await collectPackagePwaContributions({\n packages: pwaPackagesForFragments,\n projectRoot: options.dirname,\n registryUrl: phPackageRegistryUrl,\n onWarn: pwaWarn,\n });\n const projectContribution = collectProjectPwaContribution({\n projectRoot: options.dirname,\n });\n if (projectContribution) contributions.push(projectContribution);\n const mergedPwa = mergePwaConfig(contributions, projectPwa, pwaWarn);\n return connectPwaPlugins({ offlineEnabled, pwa: mergedPwa });\n })();\n\n const reactExternal = [\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react-dom/client\",\n ];\n\n // pnpm `link:` deps (e.g. a downstream project linking @powerhousedao/*\n // packages from a sibling monorepo checkout) live outside Vite's\n // auto-detected workspace root. Their `node_modules/.pnpm/...` assets\n // then 403 through `/@fs/`, returning a 760-byte HTML body where the\n // binary should be — which breaks PGlite at startup with \"Invalid FS\n // bundle size: 760 !== 4939170\". Resolve key linked packages back to\n // their real workspace roots and allow Vite to serve from there.\n const linkedRoots = [\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/connect\",\n \"@electric-sql/pglite\",\n ]\n .map((pkg) => {\n try {\n return searchForWorkspaceRoot(\n realpathSync(join(options.dirname, \"node_modules\", pkg)),\n );\n } catch {\n return null;\n }\n })\n .filter((p): p is string => p !== null);\n\n const config: InlineConfig = {\n configFile: false,\n mode,\n // Prefix served/built asset URLs so Connect can run under a path prefix\n // (reverse proxy). Mirrors the client router basename; normalize so a bare\n // `app` or `/app` becomes `/app/` and matches the router.\n //\n // Dynamic-base mode: set a placeholder token instead of a concrete base.\n // connectDynamicBasePlugin (below) rewrites it in the emitted JS to a\n // runtime expression so one bundle serves under any subpath; the proxy\n // substitutes it in the HTML and sets the runtime global at serve time.\n base: options.dynamicBase\n ? DYNAMIC_BASE_PLACEHOLDER\n : connectBasePath\n ? normalizeBasePath(connectBasePath)\n : undefined,\n server: {\n watch: {\n ignored: [\"**/backup-documents/**\", \"**/.ph/**\"],\n },\n fs: {\n allow: [searchForWorkspaceRoot(options.dirname), ...linkedRoots],\n },\n },\n resolve: {\n dedupe: [\"react\", \"react-dom\"],\n tsconfigPaths: true,\n },\n define: {\n PH_CONNECT_SENTRY_RELEASE: JSON.stringify(release || \"unknown\"),\n PH_CONNECT_BUILD_HASH: JSON.stringify(buildHash),\n },\n customLogger,\n envPrefix: [\"PH_CONNECT_\"],\n optimizeDeps: {\n include: [\n \"document-model\",\n \"zod\",\n \"@powerhousedao/design-system/connect\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/document-engineering\",\n ],\n exclude: [\"@electric-sql/pglite\", \"@electric-sql/pglite-tools\"],\n },\n plugins: [\n // phConfigPlugin must be registered before tailwind so its hotUpdate\n // hook runs first and can suppress HMR updates for codegen-generated\n // files, preventing tailwind from triggering full page reloads.\n phConfigPlugin({\n packages: phPackages,\n projectRoot: options.dirname,\n connect: phConfig.connect,\n workflows: phConfig.workflows,\n packageRegistryUrl: phPackageRegistryUrl ?? undefined,\n cliConnectOverride: options.cliConnectOverride,\n }),\n phBundledPackagesPlugin({\n packages: localPackagesFromConfig,\n projectRoot: options.dirname,\n }),\n // Dev-only: rewrite the importmap to Vite's pre-bundled React so Connect\n // and CDN editors share one instance (build uses reactSelfHostPlugin).\n devReactImportmapPlugin(options.dirname),\n // Dev-only: serve the reactor SharedWorker bundle (built lazily) at the\n // stable URL the tab probes; production builds emit it via\n // prebuildReactorWorker in `ph connect build`.\n reactorWorkerDevPlugin(options.dirname),\n ...plugins,\n // Externalize React so Connect + CDN editors share one instance via the\n // import map (reactSelfHostPlugin URLs); also rewrites external require().\n // Production vendor builds additionally externalize the shared package\n // set — the Connect app's own imports of them resolve through the\n // import map at runtime instead of being bundled.\n //\n // The externals are the vendor's *published* specifiers, not a static\n // list: the vendor drops entries whose package is not installed in the\n // project, and never publishes the bare `@powerhousedao/shared` root.\n // Externalizing a specifier the import map has no entry for leaves a\n // bare specifier in the chunk, and the browser kills it with \"Failed to\n // resolve module specifier\". Taking the keys keeps the two in step by\n // construction — the dev plugin matches on the same map.\n esmExternalRequirePlugin({\n external: [\n ...reactExternal,\n ...(options.vendor && mode === \"production\"\n ? Object.keys(options.vendor.imports)\n : []),\n ],\n }),\n // Build-only: emit the React family into the dist + static import map, so\n // React is self-hosted (not esm.sh). Dev React for non-prod/debug builds.\n reactSelfHostPlugin({\n dirname: options.dirname,\n dev: mode !== \"production\" || isDebug,\n }),\n // After the react map is injected: merge the production vendor's\n // specifier entries into that same import map.\n ...(options.vendor && mode === \"production\"\n ? [vendorImportMapPlugin({ imports: options.vendor.imports })]\n : []),\n connectFaviconPlugin({ faviconPath: options.favicon }),\n // Pre-paint theme boot in every emitted index.html (marker-idempotent\n // with the serve-time injection in the ph-clint connect proxy).\n connectThemeBootPlugin(),\n // Emits build-hash.json (the SPA's same-origin \"is my build current?\"\n // probe; must be served no-cache — see docker/nginx.conf.template).\n connectBuildHashPlugin(buildHash),\n // enforce: \"post\" — rewrites the placeholder base after all other\n // transforms have emitted their asset/chunk URLs.\n ...(options.dynamicBase ? [connectDynamicBasePlugin()] : []),\n // PWA / service worker last, so its precache manifest sees every emitted\n // asset (including the icons connectPwaIconsPlugin emits).\n pwaPlugins,\n ],\n worker: {\n format: \"es\",\n // Worker chunks are emitted by a separate Rolldown build, so the main\n // bundle's generateBundle never sees them. The worker instance both\n // rewrites the placeholder and prepends a prelude that resolves the base\n // in worker scope (forWorker) — the proxy only sets the global on the\n // main thread.\n ...(options.dynamicBase\n ? { plugins: () => [connectDynamicBasePlugin({ forWorker: true })] }\n : {}),\n },\n build: {\n sourcemap: true,\n // npm can nest privy's optional Solana peers out of its reach; vite\n // stubs them, so named imports from the stub must not fail the build.\n rolldownOptions: { shimMissingExports: true },\n },\n };\n return config;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["dirname","pathDirname","importTarget","pathDirname","dirname","pathDirname","withBase","FILE_HANDLER_ACTION","dirname","pathDirname","getConfig"],"sources":["../connect-utils/constants.ts","../connect-utils/helpers.ts","../connect-utils/vite-plugins/app-shell.ts","../connect-utils/vite-plugins/build-hash.ts","../connect-utils/vite-plugins/connect-routes.ts","../connect-utils/vite-plugins/dynamic-base.ts","../connect-utils/externalize-vendor.ts","../connect-utils/reactor-worker-build.ts","../connect-utils/worker-packages-build.ts","../connect-utils/runtime-config-schema.ts","../connect-utils/vite-plugins/ph-bundled-packages.ts","../connect-utils/vite-plugins/dev-external-react.ts","../connect-utils/vite-plugins/favicon.ts","../connect-utils/vite-plugins/ph-config.ts","../connect-utils/vite-plugins/pwa-packages.ts","../connect-utils/vite-plugins/pwa-icons.ts","../connect-utils/vite-plugins/pwa-overrides.ts","../connect-utils/vite-plugins/pwa.ts","../connect-utils/vite-plugins/react-self-host.ts","../connect-utils/vite-plugins/reactor-worker-dev.ts","../connect-utils/vite-plugins/theme-boot.ts","../connect-utils/vite-plugins/vendor-import-map.ts","../connect-utils/vite-config.ts"],"sourcesContent":["export const EXTERNAL_PACKAGES_IMPORT = \"PH:EXTERNAL_PACKAGES\";\nexport const IMPORT_SCRIPT_FILE = \"external-packages.js\";\nexport const LOCAL_PACKAGE_ID = \"ph:local-package\";\nexport const PH_DIR_NAME = \".ph\";\n","import type { PowerhouseConfig } from \"@powerhousedao/config\";\nimport { exec, execSync } from \"node:child_process\";\nimport fs, { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path, { join, resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport type { Plugin } from \"vite\";\nimport { LOCAL_PACKAGE_ID } from \"./constants.js\";\nimport type { ConnectCommonOptions } from \"./types.js\";\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport function resolveViteConfigPath(\n options: Pick<ConnectCommonOptions, \"projectRoot\" | \"viteConfigFile\">,\n) {\n const { projectRoot = cwd(), viteConfigFile } = options;\n return viteConfigFile || join(projectRoot, \"vite.config.ts\");\n}\n\nexport function resolvePackage(packageName: string, root = process.cwd()) {\n // find connect installation\n const require = createRequire(root);\n return require.resolve(packageName, { paths: [root] });\n}\n\nexport function resolveConnectPackageJson(root = process.cwd()) {\n try {\n const connectPackageJsonPath = resolvePackage(\n \"@powerhousedao/connect/package.json\",\n root,\n );\n const fileContents = fs.readFileSync(connectPackageJsonPath, \"utf-8\");\n return JSON.parse(fileContents) as JSON;\n } catch (error) {\n console.error(`Error reading Connect package.json:`, error);\n return null;\n }\n}\n\n/**\n * Finds the dist dir of Connect on the local machine\n */\nexport function resolveConnectBundle(root = process.cwd()) {\n const connectIndexPath = resolvePackage(\"@powerhousedao/connect\", root);\n const connectRootPath = connectIndexPath.substring(\n 0,\n connectIndexPath.indexOf(\"connect\") + \"connect\".length,\n );\n return join(connectRootPath, \"dist/\");\n}\n\nexport function resolveConnectPublicDir(root = process.cwd()) {\n const connectIconPath = resolvePackage(\n \"@powerhousedao/connect/public/icon.ico\",\n root,\n );\n return path.join(connectIconPath, \"../\");\n}\n\n/**\n * Copies the Connect dist dir to the target path\n */\nexport function copyConnect(sourcePath: string, targetPath: string) {\n try {\n // Ensure targetPath is removed before copying\n fs.rmSync(targetPath, { recursive: true, force: true });\n\n // Copy everything from sourcePath to targetPath\n fs.cpSync(sourcePath, targetPath, { recursive: true });\n } catch (error) {\n console.error(`❌ Error copying ${sourcePath} to ${targetPath}:`, error);\n }\n}\n\n/**\n * Backs up the index.html file\n *\n * Needed when running the Connect Studio dev server on Windows\n */\nexport function backupIndexHtml(appPath: string, restore = false) {\n const filePath = join(appPath, \"index.html\");\n const backupPath = join(appPath, \"index.html.bak\");\n\n const paths = restore ? [backupPath, filePath] : [filePath, backupPath];\n\n if (fs.existsSync(paths[0])) {\n fs.copyFileSync(paths[0], paths[1]);\n }\n}\n\nexport function removeBase64EnvValues(appPath: string) {\n backupIndexHtml(appPath);\n\n const filePath = join(appPath, \"index.html\");\n\n // Read the HTML file\n fs.readFile(filePath, \"utf-8\", (err, data) => {\n if (err) {\n console.error(\"Error reading file:\", err);\n return;\n }\n\n // Use regex to replace the dynamic Base64 values with empty strings\n // TODO is this needed?\n const modifiedData = data\n .replace(\n /\"LOCAL_DOCUMENT_MODELS\":\\s*\".*?\",/,\n `\"LOCAL_DOCUMENT_MODELS\": \"\",`,\n )\n .replace(\n /\"LOCAL_DOCUMENT_EDITORS\":\\s*\".*?\"/,\n `\"LOCAL_DOCUMENT_EDITORS\": \"\"`,\n );\n\n console.log(\"Modified data:\", modifiedData);\n // Write the modified content back to the file\n fs.writeFile(filePath, modifiedData, \"utf-8\", (err) => {\n if (err) {\n console.error(\"Error writing file:\", err);\n return;\n }\n });\n });\n}\n\nexport function readJsonFile(filePath: string): PowerhouseConfig | null {\n try {\n const absolutePath = resolve(filePath);\n const fileContents = fs.readFileSync(absolutePath, \"utf-8\");\n return JSON.parse(fileContents) as PowerhouseConfig;\n } catch (_error) {\n console.error(`Error reading file: ${filePath}`);\n return null;\n }\n}\n\n/**\n * Takes a list of Powerhouse project packages and optionally local Powerhouse packages and outputs a js file which exports those packages for use in Connect Studio.\n */\nexport function makeImportScriptFromPackages(args: {\n packages: string[];\n importStyles?: boolean;\n localJsPath?: string;\n localCssPath?: string;\n}) {\n const { packages, localJsPath, localCssPath, importStyles = true } = args;\n const imports: string[] = [];\n const moduleNames: string[] = [];\n let counter = 0;\n\n for (const packageName of packages) {\n const moduleName = `module${counter}`;\n moduleNames.push(moduleName);\n imports.push(`import * as ${moduleName} from '${packageName}';`);\n if (importStyles) {\n imports.push(`import '${packageName}/style.css';`);\n }\n counter++;\n }\n\n const exports = moduleNames.map(\n (name, index) => `{\n id: \"${packages[index]}\",\n ...${name},\n }`,\n );\n\n const hasModule = localJsPath !== undefined;\n const hasStyles = importStyles && localCssPath !== undefined;\n const hasLocalPackage = hasModule || hasStyles;\n\n if (hasLocalPackage) {\n if (hasStyles) {\n imports.push(`import '${localCssPath}';`);\n }\n if (hasModule) {\n const moduleName = `module${counter}`;\n imports.push(`import * as ${moduleName} from '${localJsPath}';`);\n exports.push(`{\n id: \"${LOCAL_PACKAGE_ID}\",\n ...${moduleName},\n }`);\n }\n }\n const exportsString = exports.length\n ? `\n ${exports.join(\",\\n\")}\n `\n : \"\";\n\n const exportStatement = `export default [${exportsString}];`;\n\n const fileContent = `${imports.join(\"\\n\")}\\n\\n${exportStatement}`;\n\n return fileContent;\n}\n\nexport function ensureNodeVersion(minVersion = \"24\") {\n const version = process.versions.node;\n if (!version) {\n return;\n }\n\n if (version < minVersion) {\n console.error(\n `Node version ${minVersion} or higher is required. Current version: ${version}`,\n );\n process.exit(1);\n }\n}\n\nexport function runShellScriptPlugin(\n scriptName: string,\n connectPath: string,\n): Plugin {\n return {\n name: \"vite-plugin-run-shell-script\",\n buildStart() {\n const scriptPath = join(connectPath, scriptName);\n if (fs.existsSync(scriptPath)) {\n exec(`sh ${scriptPath}`, (error, stdout, stderr) => {\n if (error) {\n console.error(`Error executing the script: ${error.message}`);\n removeBase64EnvValues(connectPath);\n return;\n }\n if (stderr) {\n console.error(stderr);\n }\n });\n }\n },\n };\n}\n\n/**\n * Shared helper to modify the <head> tag of an HTML file by transforming its contents.\n */\nasync function modifyHtmlHead(\n pathToHtml: string,\n contents: string,\n transform: (html: string, contents: string) => string,\n) {\n if (!existsSync(pathToHtml)) {\n throw new Error(`File ${pathToHtml} does not exist.`);\n }\n let html = await readFile(pathToHtml, \"utf8\");\n html = transform(html, contents);\n await writeFile(pathToHtml, html, \"utf8\");\n}\n\n/**\n * Appends the contents to the <head> tag of the index.html file\n */\nexport async function appendToHtmlHead(pathToHtml: string, contents: string) {\n return modifyHtmlHead(pathToHtml, contents, (html, contents) => {\n if (!html.includes(\"</head>\")) {\n throw new Error(\"No </head> tag found in the HTML file.\");\n }\n return html.replace(\"</head>\", `\\n${contents}\\n</head>`);\n });\n}\n\n/**\n * Prepends the contents to the <head> tag of the index.html file\n */\nexport async function prependToHtmlHead(pathToHtml: string, contents: string) {\n return modifyHtmlHead(pathToHtml, contents, (html, contents) => {\n if (!html.includes(\"</head>\")) {\n throw new Error(\"No </head> tag found in the HTML file.\");\n }\n return html.replace(\"<head>\", `<head>\\n${contents}\\n`);\n });\n}\n\nexport function runTsc(outDir: string) {\n execSync(`npx tsc --outDir ${outDir}`, { stdio: \"inherit\" });\n}\n\n// Helper function to remove version suffix from package name\n// Handles formats like: @scope/package@version -> @scope/package\nexport function stripVersionFromPackage(packageName: string): string {\n const trimmed = packageName.trim();\n if (!trimmed) return \"\";\n const lastAtIndex = trimmed.lastIndexOf(\"@\");\n if (lastAtIndex > 0) {\n return trimmed.substring(0, lastAtIndex);\n }\n\n return trimmed;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport { resolvePackage } from \"../helpers.js\";\n\n/** On the prerendered shell's elements; marks an index.html that has it. */\nexport const APP_SHELL_MARKER = \"data-ph-shell\";\n\nexport type AppShell = {\n /** `#root`'s markup. */\n body: string;\n /** Critical CSS and the pre-paint guard, for `<head>`. */\n head: string;\n};\n\n/** The shell Connect's build prerendered, if the installed Connect ships one. */\nexport function readAppShell(projectRoot: string): AppShell | undefined {\n let distDir: string;\n try {\n distDir = join(\n dirname(\n resolvePackage(\"@powerhousedao/connect/package.json\", projectRoot),\n ),\n \"dist\",\n );\n } catch {\n return undefined;\n }\n const body = join(distDir, \"shell.html\");\n const head = join(distDir, \"shell-head.html\");\n if (!existsSync(body) || !existsSync(head)) return undefined;\n return {\n body: readFileSync(body, \"utf8\"),\n head: readFileSync(head, \"utf8\"),\n };\n}\n\n/** On the boot-recovery script; its sessionStorage key guards against reload loops. */\nexport const BOOT_RECOVER_MARKER = \"data-ph-boot-recover\";\nexport const BOOT_RECOVER_KEY = \"ph:sw-recover\";\n\n// Until the app releases the shell (its <style data-ph-shell> goes), a module\n// failure or a stall with a new service worker pending activates it and reloads once.\nexport const BOOT_RECOVER_SCRIPT =\n `(function(){try{` +\n `var K='${BOOT_RECOVER_KEY}',n=navigator.serviceWorker,done=0;` +\n `if(!n||sessionStorage.getItem(K))return;` +\n `var up=function(){return !document.querySelector('style[${APP_SHELL_MARKER}]')};` +\n `var reload=function(){location.reload()};` +\n `var skip=function(w){try{sessionStorage.setItem(K,'1')}catch(e){}` +\n `n.addEventListener('controllerchange',reload);` +\n `w.postMessage({type:'SKIP_WAITING'});setTimeout(reload,3000)};` +\n `var watch=function(w){w.addEventListener('statechange',function(){if(w.state==='installed')skip(w)})};` +\n `var go=function(){if(done||up())return;done=1;` +\n `n.getRegistration().then(function(r){if(!r)return;` +\n `if(r.waiting)return skip(r.waiting);` +\n `if(r.installing)return watch(r.installing);` +\n `r.addEventListener('updatefound',function(){if(r.installing)watch(r.installing)});` +\n `return r.update()}).catch(function(){})};` +\n `addEventListener('error',function(e){var t=e.target;` +\n `if(e.error instanceof SyntaxError||e.error instanceof TypeError||(t&&t.tagName==='SCRIPT'))go()},true);` +\n `addEventListener('unhandledrejection',function(e){` +\n `if(e.reason instanceof SyntaxError||e.reason instanceof TypeError)go()});` +\n `setTimeout(go,8000)` +\n `}catch(e){}})();`;\n\n/** Prefixes the shell's root-relative links with the deploy base. */\nexport function rebaseShellLinks(body: string, base: string) {\n if (base === \"/\" || !base) return body;\n const prefix = base.endsWith(\"/\") ? base : `${base}/`;\n return body.replace(/(\\shref=\")\\/(?!\\/)/g, `$1${prefix}`);\n}\n\nconst STYLESHEET_LINK = /<link\\b(?=[^>]*\\brel=[\"']?stylesheet\\b)[^>]*>/gi;\n\n// Loads a stylesheet without blocking paint; the inline critical CSS covers the shell.\nfunction deferStylesheet(link: string) {\n const preload = link\n .replace(/\\brel=[\"']?stylesheet[\"']?/i, 'rel=\"preload\" as=\"style\"')\n .replace(/\\/?>$/, ` onload=\"this.onload=null;this.rel='stylesheet'\">`);\n return `${preload}<noscript>${link}</noscript>`;\n}\n\n/** Inlines `shell` into an empty `#root`, adds its critical CSS and defers the\n * stylesheets; React replaces the markup when the app renders. */\nexport function injectAppShell(html: string, shell: AppShell, base = \"/\") {\n if (html.includes(APP_SHELL_MARKER)) return html;\n const root = /<div id=\"root\"><\\/div>/;\n if (!root.test(html)) return html;\n // Before the stylesheets, so equal-specificity rules in the full CSS win.\n const firstSheet = html.search(STYLESHEET_LINK);\n const at = firstSheet >= 0 ? firstSheet : html.indexOf(\"</head>\");\n const recover = `<script ${BOOT_RECOVER_MARKER}>${BOOT_RECOVER_SCRIPT}</script>`;\n const body = rebaseShellLinks(shell.body, base);\n return (html.slice(0, at) + shell.head + recover + html.slice(at))\n .replace(STYLESHEET_LINK, deferStylesheet)\n .replace(root, () => `<div id=\"root\">${body}</div>`);\n}\n\n/** Build only: dev keeps the empty root and blocking CSS for HMR. */\nexport function connectAppShellPlugin(projectRoot: string): Plugin {\n let shell: AppShell | undefined;\n let base = \"/\";\n return {\n name: \"ph-connect-app-shell\",\n apply: \"build\",\n configResolved(config) {\n base = config.base;\n },\n buildStart() {\n shell = readAppShell(projectRoot);\n },\n transformIndexHtml: {\n // After Vite injects the built CSS links.\n order: \"post\",\n handler: (html) => (shell ? injectAppShell(html, shell, base) : html),\n },\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\n/** Name of the build-identity file emitted into the build output. */\nexport const BUILD_HASH_FILE = \"build-hash.json\" as const;\n\nexport interface BuildHashInput {\n /** Monorepo workspace git SHA (CI/dev builds); empty outside the monorepo. */\n workspaceGitSha: string;\n /** Monorepo workspace version (CI/dev builds); empty outside it. */\n workspaceVersion: string;\n /** Version of @powerhousedao/connect installed in the project — the\n * published Connect code identity for standalone/Docker builds. */\n connectPackageVersion: string;\n /** Full powerhouse.config.json contents (drives, connect block, packages…). */\n projectConfig: unknown;\n /** Effective package list (config + PH_PACKAGES env override). */\n packages: string[];\n /** Resolved deploy base path (affects emitted asset URLs). */\n connectBasePath: string;\n /** Whether the offline/PWA build variant is emitted. */\n offlineEnabled: boolean;\n /** Packages registry URL baked into the runtime config. */\n packageRegistryUrl: string;\n}\n\n/**\n * Deterministic identity of a Connect build. Differs whenever the deployed\n * content differs (published Connect version, project config, package list,\n * build options) so the SPA can detect \"the server is serving a different\n * build than the one this bundle was built from\" by comparing its baked copy\n * (define `PH_CONNECT_BUILD_HASH`) to `build-hash.json`, which the build\n * emits alongside the app and the server must serve no-cache.\n */\nexport function computeBuildHash(input: BuildHashInput): string {\n return createHash(\"sha256\")\n .update(JSON.stringify(input))\n .digest(\"hex\")\n .slice(0, 16);\n}\n\n/**\n * Read the installed @powerhousedao/connect version. The package's `exports`\n * map does not expose a `./package.json` subpath, so `require.resolve(\n * \"…/package.json\")` throws — resolve the main entry and walk up to the\n * package root instead.\n */\nfunction readConnectVersion(projectRoot: string): string {\n try {\n const require = createRequire(join(projectRoot, \"package.json\"));\n const entry = require.resolve(\"@powerhousedao/connect\", {\n paths: [projectRoot],\n });\n let dir = dirname(entry);\n for (;;) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf-8\"),\n ) as { name?: string; version?: string };\n if (pkg.name === \"@powerhousedao/connect\") {\n return pkg.version ?? \"unknown\";\n }\n } catch {\n // no readable package.json at this level; keep walking up\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // Connect not resolvable from this project; fall through to \"unknown\".\n }\n return \"unknown\";\n}\n\nexport function buildHashFromBuildOptions(options: {\n dirname: string;\n phConfig: unknown;\n packages: ReadonlyArray<{\n packageName: string;\n version?: string;\n provider?: string;\n }>;\n connectBasePath?: string | null;\n offlineEnabled: boolean;\n packageRegistryUrl?: string | null;\n}): string {\n return computeBuildHash({\n workspaceGitSha: process.env.WORKSPACE_GIT_SHA ?? \"\",\n workspaceVersion: process.env.WORKSPACE_VERSION ?? \"\",\n connectPackageVersion: readConnectVersion(options.dirname),\n projectConfig: options.phConfig,\n packages: options.packages.map(\n (p) => `${p.packageName}@${p.version ?? \"\"}:${p.provider ?? \"\"}`,\n ),\n connectBasePath: options.connectBasePath ?? \"\",\n offlineEnabled: options.offlineEnabled,\n packageRegistryUrl: options.packageRegistryUrl ?? \"\",\n });\n}\n\n/**\n * Emits `build-hash.json` (`{\"hash\": \"<build id>\"}`) into the build output.\n * Emitted as an asset so it lands at the deploy base like every other file.\n * Build-only: dev (studio) never runs generateBundle, and the SPA check\n * treats a missing file as \"nothing to compare\" and stays silent.\n */\nexport function connectBuildHashPlugin(buildHash: string): Plugin {\n return {\n name: \"ph-connect-build-hash\",\n apply: \"build\",\n generateBundle() {\n this.emitFile({\n type: \"asset\",\n fileName: BUILD_HASH_FILE,\n source: `${JSON.stringify({ hash: buildHash }, null, 2)}\\n`,\n });\n },\n };\n}\n","import { Generator, getConfig } from \"@tanstack/router-generator\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\nimport { layout, physical, rootRoute } from \"@tanstack/virtual-file-routes\";\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport type { Alias, Plugin, PluginOption } from \"vite\";\nimport { resolvePackage } from \"../helpers.js\";\n\n/** A project's routes for its Connect deployment, beside Connect's own. */\nexport const HOST_ROUTES_DIR = \"hosts/connect/routes\";\n/** The generated tree of Connect's and the project's routes. */\nexport const CONNECT_ROUTES_GEN = \".ph/connect-routes.gen.ts\";\n/** Connect's dist imports its route tree by this specifier. */\nexport const ROUTE_TREE_SPECIFIER = \"@powerhousedao/connect/route-tree\";\n\n/** The project's routes folder, `hosts/connect/routes/`; undefined if none. */\nexport function resolveConnectRoutesDir(\n projectRoot: string,\n): string | undefined {\n const dir = join(projectRoot, HOST_ROUTES_DIR);\n return existsSync(dir) ? dir : undefined;\n}\n\n/** Connect's pathless sidebar layout; a project's routes in `_app/` render in it. */\nexport const APP_LAYOUT = \"_app\";\n\nfunction findRouteFile(dir: string, name: string) {\n return [\".tsx\", \".ts\", \".jsx\", \".js\"]\n .map((ext) => join(dir, `${name}${ext}`))\n .find((file) => existsSync(file));\n}\n\nexport type ConnectRoutes = {\n /** Points Connect at the tree to route with. */\n alias: Alias;\n /** The router plugin, only when the project has routes. */\n plugins: PluginOption[];\n /** Connect's route files and the project's share one router. */\n dedupe: string[];\n};\n\n/** The router plugin's config: Connect's root, its core routes and the project's. */\nexport function connectRoutesGeneratorConfig(\n connectDir: string,\n projectRoot: string,\n projectRoutes: string,\n) {\n const routesDirectory = join(connectDir, \"src/routes\");\n const fromRoutes = (path: string) => relative(routesDirectory, path);\n // A project's _app.tsx replaces Connect's layout; its _app/ routes nest in it.\n const appLayout = findRouteFile(projectRoutes, APP_LAYOUT);\n const appRoutes = join(projectRoutes, APP_LAYOUT);\n return getConfig(\n {\n target: \"react\",\n routesDirectory,\n generatedRouteTree: join(projectRoot, CONNECT_ROUTES_GEN),\n virtualRouteConfig: rootRoute(\"__root.tsx\", [\n layout(\n APP_LAYOUT,\n appLayout ? fromRoutes(appLayout) : `core/${APP_LAYOUT}.tsx`,\n [\n physical(\"\", `core/${APP_LAYOUT}`),\n ...(existsSync(appRoutes)\n ? [physical(\"\", fromRoutes(appRoutes))]\n : []),\n ],\n ),\n physical(\"\", fromRoutes(projectRoutes)),\n ]),\n // The project's _app layout and folder are mounted above, not again at the root.\n routeFileIgnorePattern: `^${APP_LAYOUT}(\\\\.[cm]?[jt]sx?)?$`,\n quoteStyle: \"double\",\n semicolons: true,\n addExtensions: \"js\",\n autoCodeSplitting: true,\n disableLogging: true,\n routeTreeFileFooter: [\n 'import type { ConnectRouterFor } from \"@powerhousedao/connect/router\";',\n 'declare module \"@tanstack/react-router\" {',\n \" interface Register {\",\n \" router: ConnectRouterFor<typeof routeTree>;\",\n \" }\",\n \"}\",\n ],\n },\n projectRoot,\n );\n}\n\n/** Writes the route tree of Connect's and the project's routes; throws on a\n * collision with a core route, which the router plugin would only log. */\nexport async function generateConnectRoutes(\n projectRoot: string,\n routesDir: string,\n config = connectRoutesGeneratorConfig(\n connectDirOf(projectRoot),\n projectRoot,\n routesDir,\n ),\n) {\n mkdirSync(dirname(config.generatedRouteTree), { recursive: true });\n try {\n await new Generator({ config, root: projectRoot }).run();\n assertNoDuplicateRoutes(config.generatedRouteTree);\n importCoreRoutesByPackage(\n config.generatedRouteTree,\n config.routesDirectory,\n );\n } catch (error) {\n const errors: unknown[] = Array.isArray(error) ? error : [error];\n const message = errors\n .map((e) => (e instanceof Error ? e.message : String(e)))\n .join(\"\\n\");\n const shown = relative(projectRoot, routesDir).split(sep).join(\"/\");\n throw new Error(\n `Connect could not mount the routes in ${shown}/:\\n${message}`,\n { cause: error },\n );\n }\n}\n\n/** Connect's route files, as the generated tree imports them. */\nexport const CONNECT_ROUTES_SPECIFIER = \"@powerhousedao/connect/routes\";\n\n// By package name, Connect's route files are a library to tsc: no rootDir error\n// and no declarations emitted for them. Vite resolves either form.\nfunction importCoreRoutesByPackage(treeFile: string, routesDirectory: string) {\n const relativeDir = relative(dirname(treeFile), routesDirectory);\n const prefix = `\"./${relativeDir.split(sep).join(\"/\")}/`;\n const tree = readFileSync(treeFile, \"utf8\");\n const rewritten = tree.replace(\n new RegExp(`${escapeRegExp(prefix)}([^\"]+)\\\\.js\"`, \"g\"),\n `\"${CONNECT_ROUTES_SPECIFIER}/$1\"`,\n );\n if (rewritten !== tree) writeFileSync(treeFile, rewritten);\n}\n\n// The plugin checks only leaf routes; a layout twice, e.g. settings.tsx, shows as one import name twice.\nfunction assertNoDuplicateRoutes(treeFile: string) {\n const tree = readFileSync(treeFile, \"utf8\");\n const files = new Map<string, string[]>();\n for (const [, name, file] of tree.matchAll(\n /^import \\{ Route as (\\w+) \\} from \"([^\"]+)\";$/gm,\n )) {\n files.set(name, [...(files.get(name) ?? []), file]);\n }\n const conflicts = [...files.values()].filter((list) => list.length > 1);\n if (conflicts.length === 0) return;\n throw new Error(\n `Conflicting configuration paths were found for a layout route.\\nConflicting files: \\n ${conflicts.flat().join(\"\\n \")}\\n`,\n );\n}\n\nfunction escapeRegExp(text: string) {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Generates the tree when the project has routes, else drops a stale one. */\nexport async function syncConnectRoutes(\n projectRoot: string,\n routesDir = resolveConnectRoutesDir(projectRoot),\n) {\n if (routesDir) {\n await generateConnectRoutes(projectRoot, routesDir);\n } else {\n rmSync(join(projectRoot, CONNECT_ROUTES_GEN), { force: true });\n }\n}\n\nfunction connectDirOf(projectRoot: string) {\n return dirname(\n resolvePackage(\"@powerhousedao/connect/package.json\", projectRoot),\n );\n}\n\n/** Mounts a project's routes folder beside Connect's core routes; without one,\n * Connect keeps its prebuilt core tree and no router plugin runs. */\nexport function connectRoutes(\n projectRoot: string,\n routesDir = resolveConnectRoutesDir(projectRoot),\n): ConnectRoutes {\n const connectDir = connectDirOf(projectRoot);\n const find = new RegExp(`^${ROUTE_TREE_SPECIFIER}$`);\n if (!routesDir) {\n rmSync(join(projectRoot, CONNECT_ROUTES_GEN), { force: true });\n return {\n alias: { find, replacement: join(connectDir, \"dist/route-tree.js\") },\n plugins: [],\n dedupe: [],\n };\n }\n const config = connectRoutesGeneratorConfig(\n connectDir,\n projectRoot,\n routesDir,\n );\n mkdirSync(dirname(config.generatedRouteTree), { recursive: true });\n const check: Plugin = {\n name: \"ph-connect-routes-check\",\n buildStart: () => generateConnectRoutes(projectRoot, routesDir, config),\n };\n return {\n alias: { find, replacement: config.generatedRouteTree },\n plugins: [\n check,\n // Before react(): it splits route files ahead of the JSX transform.\n tanstackRouter(config),\n ],\n dedupe: [\"@tanstack/react-router\"],\n };\n}\n\nconst ROUTER_PACKAGES =\n /[\\\\/]node_modules[\\\\/]@tanstack[\\\\/](react-router|router-core|history|react-store|store)[\\\\/]/;\n\n/** One chunk for the router and the project's route configs, which the split\n * route components would otherwise spread over several shared chunks. */\nexport function connectRouterChunkGroups(routesDir?: string) {\n const routes = routesDir && join(routesDir, sep);\n return [\n // Its own chunk: the entry imports it, and must not load the router with it.\n { name: \"preload-helper\", test: /vite[\\\\/]preload-helper/, priority: 1 },\n // Shared with non-router libraries, which must not load the router for it.\n {\n name: \"use-sync-external-store\",\n test: /[\\\\/]node_modules[\\\\/]use-sync-external-store[\\\\/]/,\n priority: 1,\n },\n {\n name: \"router\",\n test: (id: string) =>\n ROUTER_PACKAGES.test(id) ||\n (!!routes && id.startsWith(routes) && !id.includes(\"tsr-split\")),\n },\n ];\n}\n","import { DYNAMIC_BASE_PLACEHOLDER } from \"@powerhousedao/shared/connect\";\nimport MagicString from \"magic-string\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Placeholder base used when Connect is built in dynamic-base mode. The Vite\n * `base` option is set to this token; this plugin rewrites it in the emitted\n * output so the effective base is resolved at serve time from a global instead\n * of being baked at build time.\n *\n * Trailing slash matches `normalizeBasePath` output, so the token sits in the\n * same syntactic position as a concrete base would.\n *\n * It is defined in the browser-safe shared package (and only re-exported here,\n * where every build-side importer already reaches for it) so Connect's own\n * runtime code can read it without importing this node-only build toolchain.\n */\nexport { DYNAMIC_BASE_PLACEHOLDER };\n\n/**\n * Global the runtime (ph-clint proxy) must set before the entry bundle loads.\n * Value is the normalized deploy base, e.g. \"/myagent/\" or \"/\". The JS rewrite\n * below resolves all asset / lazy-chunk / BASE_URL references against it.\n */\nconst RUNTIME_GLOBAL = \"globalThis.__PH_DYNAMIC_BASE__\";\n\n// `(globalThis.__PH_DYNAMIC_BASE__||\"/\")` — used everywhere the placeholder\n// base prefix appears in emitted JS.\nconst BASE_EXPR = `(${RUNTIME_GLOBAL}||\"/\")`;\n\n// Worker prelude: derive the deploy base in worker scope from the worker's own\n// URL (proxy sets the global on the main thread only).\nfunction workerPrelude(stripPrefix: string): string {\n // `stripPrefix` is the segment between the deploy base and `assets/` (default\n // \"\" → strip `assets/<file>`; vendor passes \"__vendor__/\").\n const prefix = escapeForRegExp(stripPrefix).replace(/\\//g, \"\\\\/\");\n return `${RUNTIME_GLOBAL}=self.location.pathname.replace(/${prefix}assets\\\\/[^/]*$/,\"\");\\n`;\n}\n\n// Match a string literal whose content STARTS with the placeholder, in any of\n// the three JS quote styles Rolldown emits (double, single, backtick). Group 1\n// captures the opening quote; the closing quote must be the same character\n// (backreference), so a double-quoted literal may contain ' or ` and vice\n// versa. Group 2 captures the literal text after the placeholder up to the\n// closing quote. Rolldown emits the base both as a bare literal (the inlined\n// BASE_URL) and as a `<base>`+suffix (preload/asset URL prefix); both start at\n// the placeholder. The content stops at `$`, so a template literal that\n// interpolates after the token (`` `<token>...${expr}` ``) is NOT rewritten —\n// the residual-token assertion in `generateBundle` fails the build instead of\n// shipping the raw placeholder.\nconst PLACEHOLDER_LITERAL = new RegExp(\n `([\"'\\`])${escapeForRegExp(DYNAMIC_BASE_PLACEHOLDER)}((?:(?!\\\\1)[^$])*)\\\\1`,\n \"g\",\n);\n\nconst PLACEHOLDER_CSS_URL = new RegExp(\n `url\\\\(\\\\s*([\"']?)${escapeForRegExp(DYNAMIC_BASE_PLACEHOLDER)}([^\"')]*)\\\\1\\\\s*\\\\)`,\n \"g\",\n);\n\n/** Rewrites `url(<placeholder>assets/x)` relative to the stylesheet at `fileName`. */\nexport function relativeCssUrls(css: string, fileName: string): string {\n const dir = path.posix.dirname(fileName);\n return css.replace(\n PLACEHOLDER_CSS_URL,\n (_match, quote: string, target: string) => {\n const relative = path.posix.relative(dir, target);\n return `url(${quote}${relative.startsWith(\".\") ? relative : `./${relative}`}${quote})`;\n },\n );\n}\n\n/**\n * Rewrites the placeholder base in emitted JS chunks to a runtime expression so\n * one built `dist/connect` serves under any subpath. Rolldown-native: per-match\n * MagicString edits in `renderChunk`, no AST splicing (the SWC byte-offset\n * splicing in vite-plugin-dynamic-base corrupts Rolldown chunks). Each edited\n * chunk returns a hires sourcemap that the bundler composes into the chunk's\n * map chain, so the emitted `.map` files track the rewrite (and the worker\n * prelude's line shift).\n *\n * What gets rewritten in JS, all of which emit the base as a quoted string\n * literal beginning with the placeholder:\n * - asset URLs (`new URL(\"/__PH_DYNAMIC_BASE__/assets/x.png\", ...)`)\n * - dynamic-import / lazy-chunk preload URLs\n * - the inlined `import.meta.env.BASE_URL` (drives Connect's router basename\n * and BASE_URL-relative fetches such as `${BASE_URL}ph-packages.json`)\n *\n * A literal `\"/__PH_DYNAMIC_BASE__/foo\"` becomes `((globalThis.__PH_DYNAMIC_BASE__||\"/\")+\"foo\")`;\n * a bare `\"/__PH_DYNAMIC_BASE__/\"` (the BASE_URL value) becomes `(globalThis.__PH_DYNAMIC_BASE__||\"/\")`.\n *\n * HTML is left untouched: the entry `<script>`/`<link>` tags keep the literal\n * placeholder so the proxy substitutes it with the concrete base at serve time\n * (the same proxy also sets the runtime global for the JS rewrite). See the\n * plugin's module doc / report for the exact serve-time contract.\n *\n * CSS `url(...)` references that Vite emits with the placeholder (e.g. bundled\n * fonts) are rewritten relative to the stylesheet, which the HTML substitution\n * already loads from the right prefix.\n */\nexport function connectDynamicBasePlugin(\n options: { forWorker?: boolean; workerStripPrefix?: string } = {},\n): Plugin {\n return {\n name: \"ph-connect-dynamic-base\",\n enforce: \"post\",\n renderChunk(code, chunk) {\n if (!code.includes(DYNAMIC_BASE_PLACEHOLDER)) return null;\n\n const s = new MagicString(code);\n for (const match of code.matchAll(PLACEHOLDER_LITERAL)) {\n const rest = match[2];\n s.overwrite(\n match.index,\n match.index + match[0].length,\n rest.length === 0\n ? BASE_EXPR\n : `(${BASE_EXPR}+${JSON.stringify(rest)})`,\n );\n }\n\n // Worker chunks run in their own global scope where the proxy never\n // sets the runtime global; derive it from the worker's script URL so\n // the rewritten references above resolve against the deploy base.\n if (options.forWorker) {\n s.prepend(workerPrelude(options.workerStripPrefix ?? \"\"));\n this.info(\n `dynamic-base: worker prelude prepended to ${chunk.fileName}`,\n );\n }\n\n if (!s.hasChanged()) return null;\n return { code: s.toString(), map: s.generateMap({ hires: true }) };\n },\n generateBundle(_options, bundle) {\n for (const file of Object.values(bundle)) {\n if (file.type === \"asset\" && file.fileName.endsWith(\".css\")) {\n file.source = relativeCssUrls(String(file.source), file.fileName);\n }\n }\n // A residual token in JS (a literal the regex couldn't rewrite, e.g. a\n // template interpolating after the token) or CSS (url() must stay\n // stylesheet-relative; the placeholder would ship verbatim and 404)\n // would fail silently at runtime — fail the build instead. HTML keeps\n // the token by design: the proxy substitutes it at serve time.\n for (const file of Object.values(bundle)) {\n const content =\n file.type === \"chunk\"\n ? file.code\n : file.fileName.endsWith(\".css\") && typeof file.source === \"string\"\n ? file.source\n : undefined;\n if (content?.includes(DYNAMIC_BASE_PLACEHOLDER)) {\n this.error(\n `dynamic-base: unrewritten placeholder ${DYNAMIC_BASE_PLACEHOLDER} remains in ${file.fileName}`,\n );\n }\n }\n },\n };\n}\n\nexport function escapeForRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","/**\n * Prebuild the heavy, stable Connect dependencies into a static ESM \"vendor\"\n * bundle so the dev server never runs (or holds) the dependency optimizer /\n * module graph for them.\n *\n * The reactor-project preview dev-optimizes a large UI graph (Connect itself,\n * design-system, document-engineering, reactor-browser, …) every session —\n * ~1–2 GB resident — even though those libs don't change; only the project's\n * editors do. This module builds them ONCE with `vite build` (in a throwaway\n * subprocess that exits, freeing the build's peak memory): `vite build` handles\n * CSS/asset imports, web workers, and WASM (Connect's in-browser PGlite ships\n * all three), and a multi-entry build with `preserveEntrySignatures: 'strict'`\n * dedupes shared code into shared chunks. Entries for CJS deps re-export the\n * module's named API explicitly (so `import { createRoot }` works); ESM deps\n * use `export *`. The build runs under a dynamic-base placeholder + vendor\n * segment (`connectDynamicBasePlugin`), so emitted asset/chunk URLs\n * (`new URL(…, import.meta.url)` for .wasm/.data/workers) carry the placeholder\n * and resolve at serve time to `<deploy-base>__vendor__/`, while the vendored\n * Connect's `import.meta.env.BASE_URL` resolves to the deploy base.\n *\n * The React family stays EXTERNAL (see `VENDOR_EXTERNAL`); `esmExternalRequirePlugin`\n * owns that externalization and rewrites CJS `require(\"react\")` → import. Vendor\n * chunks keep bare React imports, which the dev import map resolves to Vite's\n * pre-bundled React (`devReactImportmapPlugin`) — one React instance across the\n * vendor, the project's editors, and CDN-loaded editors.\n *\n * `devReactImportmapPlugin` consumes the result: it externalizes these\n * specifiers in the long-lived dev server, points the page import map at the\n * vendor URLs, and serves the bundle. With Connect vendored, the dev server only\n * processes the project's own `main` + local package; HMR for them is unaffected.\n */\nimport { spawn } from \"node:child_process\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { DYNAMIC_BASE_PLACEHOLDER } from \"./vite-plugins/dynamic-base.js\";\n\nexport interface VendorPrebuildOptions {\n /** Project root the vendor deps resolve from. */\n dirname: string;\n /** Specifiers to prebuild into the vendor (defaults to the dev set). */\n include?: string[];\n /** Specifiers left external to the build (defaults to the React family). */\n external?: string[];\n /** Directory to hold the static vendor bundle + import map. */\n vendorDir?: string;\n /** Filled with the failure cause when the prebuild returns null. */\n errorRef?: { message?: string };\n /**\n * The APP's base — the same string the app build uses (the dynamic-base\n * placeholder, or a normalized deploy base like \"/app/\"). The vendor's own\n * build base is this plus the vendor segment, so emitted asset URLs land\n * under <app-base>__vendor__/. Default: the dynamic placeholder + segment\n * (dev behavior). Import-map values stay base-relative; the production\n * build strips the leading slash (values then resolve against the page URL\n * under any deploy base), the dev flow prefixes its own base.\n */\n base?: string;\n /** NODE_ENV define for the vendor build (default \"development\"). */\n nodeEnv?: \"development\" | \"production\";\n /** The app's own deps the vendored packages also bundle: vendored as listed,\n * resolved from `from` (projects don't install them). */\n ownDeps?: { specs: string[]; from: string };\n}\n\n/**\n * The stable Connect libraries worth prebuilding. The React family is NOT here —\n * it's externalized from the build (see `VENDOR_EXTERNAL`) so the vendor shares\n * the dev server's single React instance via the import map.\n */\nexport const DEFAULT_VENDOR_INCLUDE = [\n \"@powerhousedao/connect\",\n \"document-model\",\n \"zod\",\n \"@powerhousedao/design-system/connect\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/document-engineering\",\n];\n\n/**\n * React-family specifiers kept external to the vendor build. The vendor's chunks\n * emit bare imports for these; `devReactImportmapPlugin`'s import map resolves\n * them to Vite's pre-bundled React, so there is exactly one React instance.\n */\nexport const VENDOR_EXTERNAL = [\n \"react\",\n \"react-dom\",\n \"react-dom/client\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n // Dev-server virtual module (bundled local packages). Connect imports it in a\n // try/catch; left external so the build doesn't try to resolve it and the dev\n // server / import map resolves it at runtime.\n \"ph-bundled-packages-virtual\",\n];\n\nexport interface PrebuiltVendor {\n vendorDir: string;\n /** import map: bare specifier -> \"/__vendor__/<entry>-<hash>.js\" (base-relative). */\n imports: Record<string, string>;\n /** Resolved versions of every included + external package. */\n versions: Record<string, string>;\n /** Content-hashed shared-deps module (\"/__vendor__/shared-deps-<hash>.js\", base-relative). */\n sharedDeps: string;\n}\n\n/** URL prefix the vendor bundle is served under by the dev middleware. */\nexport const VENDOR_URL_PREFIX = \"/__vendor__/\";\n\n// Vite `base` for the vendor build: dynamic-base placeholder + vendor segment.\n// connectDynamicBasePlugin rewrites it so chunk/asset URLs resolve at serve time.\nconst VENDOR_DYNAMIC_BASE = `${DYNAMIC_BASE_PLACEHOLDER}${VENDOR_URL_PREFIX.replace(/^\\/+/, \"\")}`;\n\n/**\n * Build the prebuilt vendor (once, in a throwaway subprocess) and return its dir\n * + import map. Idempotent: reuses a cached vendor built for the same dep set.\n * Returns null on any failure (caller falls back to a normal dev server).\n */\nexport async function prebuildConnectVendor(\n options: VendorPrebuildOptions,\n): Promise<PrebuiltVendor | null> {\n const include = expandIncludeSubpaths(\n options.dirname,\n options.include ?? DEFAULT_VENDOR_INCLUDE,\n );\n const own = options.ownDeps\n ? resolveOwnDeps(options.ownDeps.from, options.ownDeps.specs)\n : {};\n for (const spec of Object.keys(own)) {\n if (!include.includes(spec)) include.push(spec);\n }\n const external = options.external ?? VENDOR_EXTERNAL;\n const vendorDir =\n options.vendorDir ?? join(options.dirname, \"node_modules/.ph-vendor\");\n const importMapPath = join(vendorDir, \"import-map.json\");\n // A version change of any vendored dep must invalidate the cache, so the\n // resolved versions are part of the key (not just the specifier lists).\n // One dist walk per linked package for both the versions and the digest.\n const stamps = new Map<string, string>();\n const versions = resolveDepVersions(\n options.dirname,\n [...include, ...external],\n stamps,\n );\n const base = options.base ?? VENDOR_DYNAMIC_BASE;\n const nodeEnv = options.nodeEnv ?? \"development\";\n const versionDigest = resolveVersionDigest(versions, own, stamps, {\n base,\n nodeEnv,\n });\n\n try {\n const hit = readCacheHit(importMapPath, include, external, versionDigest);\n if (hit) return { vendorDir, ...hit };\n\n // Serialize concurrent builders on a lock dir; a loser waits for the\n // winner's result instead of clobbering the shared output.\n const lockDir = `${vendorDir}.lock`;\n const lock = acquireLock(lockDir);\n if (!lock) {\n const hit = await waitForCacheHit(\n importMapPath,\n include,\n external,\n versionDigest,\n lockDir,\n );\n return hit ? { vendorDir, ...hit } : null;\n }\n\n try {\n // Recheck under the lock: another builder may have finished while we\n // were acquiring it.\n const raced = readCacheHit(\n importMapPath,\n include,\n external,\n versionDigest,\n );\n if (raced) return { vendorDir, ...raced };\n\n const result = await buildVendorAtomic(\n options.dirname,\n vendorDir,\n include,\n external,\n versionDigest,\n versions,\n base,\n nodeEnv,\n own,\n );\n return result ? { vendorDir, ...result } : null;\n } finally {\n releaseLock(lock);\n }\n } catch (err) {\n if (options.errorRef)\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n return null;\n }\n}\n\ninterface VendorCacheMeta {\n include?: string[];\n external?: string[];\n versionDigest?: string;\n imports: Record<string, string>;\n versions?: Record<string, string>;\n sharedDeps?: string;\n base?: string;\n nodeEnv?: string;\n}\n\ntype VendorCacheHit = Omit<PrebuiltVendor, \"vendorDir\">;\n\n// Return the cached import map + versions iff the specifier sets AND the\n// resolved-version digest all match; otherwise null (forces a rebuild).\nfunction readCacheHit(\n importMapPath: string,\n include: string[],\n external: string[],\n versionDigest: string,\n): VendorCacheHit | null {\n if (!existsSync(importMapPath)) return null;\n try {\n const cached = JSON.parse(\n readFileSync(importMapPath, \"utf8\"),\n ) as VendorCacheMeta;\n if (\n sameSet(cached.include, include) &&\n sameSet(cached.external, external) &&\n cached.versionDigest === versionDigest &&\n typeof cached.sharedDeps === \"string\"\n ) {\n return {\n imports: cached.imports,\n versions: cached.versions ?? {},\n sharedDeps: cached.sharedDeps,\n };\n }\n } catch {\n // partial/corrupt import-map.json → treat as miss\n }\n return null;\n}\n\n// Files a vendor bundle never reads; their writes must not force a rebuild.\nconst NON_RUNTIME_FILE = /\\.(map|d\\.[cm]?ts|tsbuildinfo)$/;\n\n// A linked (workspace) package keeps its version across rebuilds, so the\n// newest mtime in its dist joins the digest; installed packages add nothing.\nexport function linkedBuildStamp(pkgRoot: string): string {\n if (pkgRoot.split(/[\\\\/]/).includes(\"node_modules\")) return \"\";\n let newest = 0;\n try {\n const entries = readdirSync(join(pkgRoot, \"dist\"), {\n recursive: true,\n withFileTypes: true,\n });\n for (const entry of entries) {\n if (!entry.isFile() || NON_RUNTIME_FILE.test(entry.name)) continue;\n const { mtimeMs } = statSync(join(entry.parentPath, entry.name));\n if (mtimeMs > newest) newest = mtimeMs;\n }\n } catch {\n return \"\";\n }\n return newest ? `+dist.${Math.trunc(newest)}` : \"\";\n}\n\nfunction cachedStamp(stamps: Map<string, string>, pkgRoot: string) {\n let stamp = stamps.get(pkgRoot);\n if (stamp === undefined) {\n stamp = linkedBuildStamp(pkgRoot);\n stamps.set(pkgRoot, stamp);\n }\n return stamp;\n}\n\n/**\n * Resolve the installed version of each spec's owning package, deduped by\n * package name. Resolution order per spec:\n * 1. the project itself, when it IS the owning package (a self-vendoring\n * app has no node_modules self-link);\n * 2. the project's own node_modules link (works for pnpm-strict and\n * hoisted layouts alike, and — unlike `require.resolve` — for\n * ESM-only packages whose exports map has no CJS condition);\n * 3. Node's own module resolution (covers transitive installs), walking\n * the entry up to the owning package's package.json.\n * Unresolvable specs contribute a \"missing\" sentinel, unknown versions\n * \"unknown\".\n */\nfunction resolveDepVersions(\n dirname: string,\n specs: string[],\n stamps = new Map<string, string>(),\n): Record<string, string> {\n const req = createRequire(join(dirname, \"noop.js\"));\n const seen: Record<string, string> = {};\n let selfMeta: { name?: string; version?: string } | null = null;\n for (const spec of specs) {\n const { pkg } = parsePkg(spec);\n if (pkg in seen) continue;\n if (selfMeta === null) {\n try {\n selfMeta = JSON.parse(\n readFileSync(join(dirname, \"package.json\"), \"utf8\"),\n ) as { name?: string; version?: string };\n } catch {\n selfMeta = {};\n }\n }\n let version: string;\n if (\n typeof selfMeta.name === \"string\" &&\n selfMeta.name === pkg &&\n typeof selfMeta.version === \"string\"\n ) {\n version = selfMeta.version;\n } else {\n version = \"missing\";\n try {\n const pkgRoot = realpathSync(join(dirname, \"node_modules\", pkg));\n const meta = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n version =\n String(meta.version ?? \"unknown\") + cachedStamp(stamps, pkgRoot);\n } catch {\n try {\n const entry = req.resolve(spec);\n // Walk up to the owning package root (entry is usually a few\n // levels below it, e.g. dist/zod.js or\n // .pnpm/<pkg>@<v>/node_modules/<pkg>/…).\n let dir = pathDirname(entry);\n for (let depth = 0; depth < 8; depth++) {\n if (existsSync(join(dir, \"package.json\"))) {\n const meta = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n version = String(meta.version ?? \"unknown\");\n break;\n }\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // leave sentinel\n }\n }\n }\n seen[pkg] = version;\n }\n return seen;\n}\n\n// Hash the resolved version of each spec's owning package (from its installed\n// package.json). A bump or branch checkout that changes any version yields a\n// different digest, invalidating the cache. Unresolvable specs contribute a\n// sentinel so they don't silently collide.\nexport function resolveVersionDigest(\n versions: Record<string, string>,\n own: Record<string, string>,\n stamps: Map<string, string>,\n build: { base: string; nodeEnv: string },\n): string {\n const h = createHash(\"sha256\");\n // The base is baked into emitted asset/preload URLs, NODE_ENV into the code.\n h.update(`base:${build.base}\\nnodeEnv:${build.nodeEnv}\\n`);\n // Fold in the build worker so a logic/build-option change busts stale bundles,\n // not just a dep version bump.\n const workerHash = createHash(\"sha256\")\n .update(VENDOR_BUILD_WORKER)\n .digest(\"hex\");\n h.update(`worker:${workerHash}\\n`);\n for (const pkg of Object.keys(versions).sort()) {\n h.update(`${pkg}@${versions[pkg]}\\n`);\n }\n // Own deps resolve outside the project; their real path carries the version.\n for (const spec of Object.keys(own).sort()) {\n const stamp = cachedStamp(stamps, ownPackageRoot(own[spec]));\n h.update(`own:${spec}=${own[spec]}${stamp}\\n`);\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n\nfunction sameSet(a: string[] | undefined, b: string[]): boolean {\n if (!a || a.length !== b.length) return false;\n const s = new Set(a);\n return b.every((x) => s.has(x));\n}\n\n// Exclusive lock via mkdir (atomic on POSIX). The holder heartbeats an owner\n// file so a live (slow) build keeps it fresh; a crashed builder lets it go stale.\nexport const LOCK_STALE_MS = 5 * 60_000;\nconst LOCK_HEARTBEAT_MS = 60_000;\n\nexport interface VendorLock {\n dir: string;\n token: string;\n timer: ReturnType<typeof setInterval>;\n}\n\nconst ownerFile = (lockDir: string): string => join(lockDir, \"owner\");\n\n// Stale iff the owner file hasn't been heartbeated within LOCK_STALE_MS. A\n// missing owner file means a builder mid-acquire — treat as fresh, don't steal.\nfunction lockIsStale(lockDir: string): boolean {\n try {\n return Date.now() - statSync(ownerFile(lockDir)).mtimeMs > LOCK_STALE_MS;\n } catch {\n return false;\n }\n}\n\nexport function acquireLock(lockDir: string): VendorLock | null {\n let made = false;\n try {\n mkdirSync(lockDir);\n made = true;\n } catch {\n if (lockIsStale(lockDir)) {\n try {\n rmSync(lockDir, { recursive: true, force: true });\n mkdirSync(lockDir);\n made = true;\n } catch {\n // lost the reclaim race to another builder\n }\n }\n }\n if (!made) return null;\n const token = `${process.pid}-${randomUUID()}`;\n writeFileSync(ownerFile(lockDir), token);\n // Refresh mtime while we still own it; stop if a stale-reclaim handed it off.\n const timer = setInterval(() => {\n try {\n if (readFileSync(ownerFile(lockDir), \"utf8\") === token) {\n writeFileSync(ownerFile(lockDir), token);\n } else {\n clearInterval(timer);\n }\n } catch {\n clearInterval(timer);\n }\n }, LOCK_HEARTBEAT_MS);\n timer.unref();\n return { dir: lockDir, token, timer };\n}\n\n// Remove only if we still own it — a stale-reclaim may have handed the lock to\n// another builder, whose dir we must not delete.\nexport function releaseLock(lock: VendorLock): void {\n clearInterval(lock.timer);\n try {\n if (readFileSync(ownerFile(lock.dir), \"utf8\") === lock.token) {\n rmSync(lock.dir, { recursive: true, force: true });\n }\n } catch {\n // owner file gone/unreadable — leave it for the stale path\n }\n}\n\n// Loser path: poll for the winner to publish a matching import-map.json, until\n// the lock is released or a timeout elapses.\nasync function waitForCacheHit(\n importMapPath: string,\n include: string[],\n external: string[],\n versionDigest: string,\n lockDir: string,\n): Promise<VendorCacheHit | null> {\n const deadline = Date.now() + LOCK_STALE_MS;\n while (Date.now() < deadline) {\n const hit = readCacheHit(importMapPath, include, external, versionDigest);\n if (hit) return hit;\n if (!existsSync(lockDir)) {\n // winner finished (or gave up); one last read\n return readCacheHit(importMapPath, include, external, versionDigest);\n }\n await new Promise((r) => setTimeout(r, 250));\n }\n return null;\n}\n\n// Resolve an exports entry to the file it loads under browser/import\n// conditions, or null if none (e.g. document-model's node-only `./node`). Used\n// to skip node-only and CSS/JSON subpaths the browser-targeted build can't take.\nfunction importTarget(value: unknown): string | null {\n if (typeof value === \"string\") return value;\n if (!value || typeof value !== \"object\") return null;\n const o = value as Record<string, unknown>;\n for (const c of [\"browser\", \"import\", \"module\", \"default\"]) {\n if (c in o) {\n const t = importTarget(o[c]);\n if (t) return t;\n }\n }\n return null;\n}\n\n/** The package root at or above `from` that Node would load `pkg` from, or null. */\nexport function findPackageRoot(from: string, pkg: string): string | null {\n let dir = from;\n for (;;) {\n const candidate = join(dir, \"node_modules\", pkg);\n if (existsSync(join(candidate, \"package.json\"))) {\n return realpathSync(candidate);\n }\n const parent = pathDirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n// Roots of the dependency-free own deps: a group also takes in its modules'\n// dependencies, so only these can get one chunk without absorbing others.\nfunction ownRoots(own: Record<string, string>): string[] {\n const roots = new Set<string>();\n for (const file of Object.values(own)) {\n const root = ownPackageRoot(file);\n try {\n const meta = JSON.parse(\n readFileSync(join(root, \"package.json\"), \"utf8\"),\n ) as {\n dependencies?: Record<string, string>;\n };\n if (Object.keys(meta.dependencies ?? {}).length === 0)\n roots.add(root + sep);\n } catch {\n // no readable package.json: no group\n }\n }\n return [...roots];\n}\n\nfunction ownPackageRoot(file: string): string {\n let dir = pathDirname(file);\n for (;;) {\n try {\n const meta = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as { name?: string };\n if (meta.name) return dir;\n } catch {\n // no package.json here\n }\n const parent = pathDirname(dir);\n if (parent === dir) return dir;\n dir = parent;\n }\n}\n\n/** Each spec's browser/import entry file when resolved from `from`; unresolvable specs are left out. */\nexport function resolveOwnDeps(\n from: string,\n specs: string[],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const spec of specs) {\n const { pkg, sub } = parsePkg(spec);\n const root = findPackageRoot(from, pkg);\n if (!root) continue;\n try {\n const meta = JSON.parse(\n readFileSync(join(root, \"package.json\"), \"utf8\"),\n ) as { exports?: unknown; module?: string; main?: string };\n const key = sub ? `./${sub}` : \".\";\n let target: string | null = null;\n if (meta.exports && typeof meta.exports === \"object\") {\n const exp = meta.exports as Record<string, unknown>;\n const keyed = Object.keys(exp).some((k) => k.startsWith(\".\"));\n target = keyed\n ? key in exp\n ? importTarget(exp[key])\n : null\n : sub\n ? null\n : importTarget(exp);\n } else if (typeof meta.exports === \"string\") {\n target = sub ? null : meta.exports;\n } else if (!sub) {\n target = meta.module ?? meta.main ?? null;\n }\n if (!target || /\\.(css|json|scss)$/.test(target)) continue;\n const file = join(root, target);\n if (existsSync(file)) out[spec] = realpathSync(file);\n } catch {\n // unreadable package.json: leave the spec out\n }\n }\n return out;\n}\n\nfunction parsePkg(spec: string): { pkg: string; sub: string } {\n if (spec.startsWith(\"@\")) {\n const parts = spec.split(\"/\");\n return { pkg: parts.slice(0, 2).join(\"/\"), sub: parts.slice(2).join(\"/\") };\n }\n const i = spec.indexOf(\"/\");\n return i === -1\n ? { pkg: spec, sub: \"\" }\n : { pkg: spec.slice(0, i), sub: spec.slice(i + 1) };\n}\n\n/**\n * Connect imports the heavy libs by subpath too (e.g.\n * `@powerhousedao/design-system/connect/toast`, `zod/v4/core`). Those bare\n * imports need their own import-map entry, so expand each listed spec to its\n * package's concrete (non-wildcard, JS) subpath exports that share the spec's\n * prefix. Unresolvable / CSS / JSON targets are skipped.\n *\n * A spec whose package isn't installed in `dirname` is dropped entirely\n * rather than kept for the worker: the worker cannot build an entry for a\n * missing package (its `await import` and the vite resolution both fail),\n * and a bare re-export entry would fail the whole vendor build. The\n * importer of a missing shared dep simply bundles its own copy.\n */\nfunction expandIncludeSubpaths(dirname: string, include: string[]): string[] {\n const out = new Set<string>();\n for (const spec of include) {\n const { pkg, sub } = parsePkg(spec);\n let exp: unknown;\n let pkgRoot: string;\n try {\n pkgRoot = realpathSync(join(dirname, \"node_modules\", pkg));\n const pkgJson = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { exports?: unknown };\n exp = pkgJson.exports;\n } catch {\n continue;\n }\n out.add(sub ? spec : pkg);\n if (!exp || typeof exp !== \"object\") continue;\n const expMap = exp as Record<string, unknown>;\n const prefixKey = sub ? `./${sub}` : \".\";\n for (const key of Object.keys(expMap)) {\n if (key.includes(\"*\") || key === \"./package.json\") continue;\n if (/\\.(css|json|scss)$/.test(key)) continue;\n const matches =\n prefixKey === \".\"\n ? key === \".\" || key.startsWith(\"./\")\n : key === prefixKey || key.startsWith(`${prefixKey}/`);\n if (!matches) continue;\n const target = importTarget(expMap[key]);\n if (!target || /\\.(css|json|scss)$/.test(target)) continue;\n // Skip subpaths whose target file isn't shipped (e.g. a `./test` export\n // pointing at unbuilt dist) — they'd fail the build.\n if (!existsSync(join(pkgRoot, target))) continue;\n out.add(key === \".\" ? pkg : pkg + key.slice(1));\n }\n }\n return [...out];\n}\n\n/**\n * The published specifiers whose entry file the vendor build never emitted.\n * URLs are base-less (`/__vendor__/x.js`) and resolve inside `vendorDir`.\n */\nexport function missingVendorEntries(\n vendorDir: string,\n imports: Record<string, string>,\n): { spec: string; url: string }[] {\n const prefix = VENDOR_URL_PREFIX;\n return Object.entries(imports)\n .filter(([, url]) => {\n const rel = url.startsWith(prefix) ? url.slice(prefix.length) : url;\n return !existsSync(join(vendorDir, rel));\n })\n .map(([spec, url]) => ({ spec, url }));\n}\n\n/**\n * Rebase the vendor's base-less entry URLs (`/__vendor__/x.js`) onto the\n * deploy base, so a consumer that resolves them against the page origin lands\n * under that base rather than the server root. A dynamic-base build keeps its\n * placeholder, which the runtime substitutes.\n *\n * `base` is the app base from `prebuildConnectVendor` callers, but the\n * VENDOR_DYNAMIC_BASE default already carries the vendor segment — that\n * trailing segment is dropped first so it is never doubled.\n */\nexport function withVendorBase(\n imports: Record<string, string>,\n base: string,\n): Record<string, string> {\n const segment = VENDOR_URL_PREFIX.replace(/^\\/+/, \"\");\n const appBase = base.endsWith(segment)\n ? base.slice(0, base.length - segment.length)\n : base;\n return Object.fromEntries(\n Object.entries(imports).map(([spec, url]) => [\n spec,\n `${appBase}/${url}`\n .replace(/([^:])\\/{2,}/g, \"$1/\")\n .replace(/^\\/{2,}/, \"/\"),\n ]),\n );\n}\n\n/**\n * Build the vendor into a unique temp dir, then atomically swap it into place,\n * so a concurrent reader never sees a partial bundle or import-map.json. Runs\n * the build in a throwaway subprocess (its peak memory is reclaimed on exit);\n * the parent augments the import map with the version digest + the version\n * table, writes the runtime shared-deps module, and does the swap.\n * Returns the published import map + versions, or null on failure.\n */\nasync function buildVendorAtomic(\n dirname: string,\n vendorDir: string,\n include: string[],\n external: string[],\n versionDigest: string,\n versions: Record<string, string>,\n base: string,\n nodeEnv: \"development\" | \"production\",\n own: Record<string, string> = {},\n): Promise<VendorCacheHit | null> {\n const parent = pathDirname(vendorDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-vendor.tmp-\"));\n try {\n const { ok, stderr } = await runBuildWorker(\n dirname,\n tmpDir,\n include,\n external,\n base,\n nodeEnv,\n own,\n );\n const tmpMap = join(tmpDir, \"import-map.json\");\n if (!ok || !existsSync(tmpMap)) {\n const detail = stderr.trim();\n throw new Error(\n `vendor build failed${detail ? `:\\n${detail}` : \" (no output captured)\"}`,\n );\n }\n // Stamp the version digest + version table into the published metadata so\n // the cache check can detect a dep bump and cache hits restore versions.\n const meta = JSON.parse(readFileSync(tmpMap, \"utf8\")) as VendorCacheMeta;\n // Every published specifier must have a file behind it. An entry the map\n // claims but the build never emitted becomes a bare import the app\n // externalizes onto a URL that 404s — and since a SPA answers an unknown\n // path with index.html, the browser reports only an opaque MIME-type\n // error. Fail the build here, where the missing entries can be named.\n const unbacked = missingVendorEntries(tmpDir, meta.imports);\n if (unbacked.length > 0) {\n throw new Error(\n `vendor build published ${unbacked.length} import-map ` +\n `${unbacked.length === 1 ? \"entry\" : \"entries\"} with no file behind ` +\n `${unbacked.length === 1 ? \"it\" : \"them\"}:\\n` +\n unbacked.map((e) => ` ${e.spec} -> ${e.url}`).join(\"\\n\"),\n );\n }\n meta.versionDigest = versionDigest;\n meta.versions = versions;\n meta.base = base;\n meta.nodeEnv = nodeEnv;\n\n // The runtime data module: a real .js (not .json) so the Workbox precache\n // glob picks it up and the main thread can dynamic-import it without\n // import attributes.\n //\n // Its URLs carry the build's base (import-map.json stays base-less\n // because the dev plugin applies the base itself). The worker resolves\n // these against the page origin, so a base-less path would point at\n // /__vendor__/ on a subpath deploy and 404.\n const sharedDepsSource =\n `export const imports = ${JSON.stringify(\n withVendorBase(meta.imports, base),\n )};\\n` + `export const versions = ${JSON.stringify(versions)};\\n`;\n // The hashed copy is what production loads; the stable name serves dev.\n const sharedDepsFile = `shared-deps-${createHash(\"sha256\")\n .update(sharedDepsSource)\n .digest(\"hex\")\n .slice(0, 12)}.js`;\n writeFileSync(join(tmpDir, sharedDepsFile), sharedDepsSource);\n writeFileSync(join(tmpDir, \"shared-deps.js\"), sharedDepsSource);\n meta.sharedDeps = VENDOR_URL_PREFIX + sharedDepsFile;\n writeFileSync(tmpMap, JSON.stringify(meta, null, 2));\n\n // Swap: move any existing dir aside, rename temp into place, drop the old.\n const oldDir = `${vendorDir}.old-${process.pid}-${Date.now()}`;\n if (existsSync(vendorDir)) renameSync(vendorDir, oldDir);\n renameSync(tmpDir, vendorDir);\n // mkdtemp creates the staging dir 0700, and the rename carries that mode\n // onto the published vendor. The build and the server are not always the\n // same user — in a container image the build runs as root and nginx as\n // `nginx` — and a directory nobody else can traverse makes every vendor\n // URL unreadable. A SPA then answers each one with index.html, so the\n // browser reports an opaque MIME-type error and the whole shared-dep\n // mechanism is silently inert. Publish it as readable as the rest of the\n // build output.\n chmodSync(vendorDir, 0o755);\n rmSync(oldDir, { recursive: true, force: true });\n return { imports: meta.imports, versions, sharedDeps: meta.sharedDeps };\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw err;\n }\n}\n\n// The worker imports connectDynamicBasePlugin from this module's own loadable\n// form. In the published/built bundle that is import.meta.url itself; when\n// running from source (vitest), node cannot load the .ts graph, so fall back\n// to the package's built entry (dist/index.mjs).\nfunction resolveSelfModulePath(): string {\n const selfPath = fileURLToPath(import.meta.url);\n if (!selfPath.endsWith(\".ts\")) return selfPath;\n let dir = pathDirname(selfPath);\n for (let depth = 0; depth < 4; depth++) {\n const candidate = join(dir, \"dist\", \"index.mjs\");\n if (existsSync(candidate)) return candidate;\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"vendor build needs the built builder-tools bundle (dist/index.mjs); build the package first\",\n );\n}\n\n/**\n * Spawn a throwaway worker that generates one entry per specifier (CJS deps get\n * explicit named re-exports, ESM deps `export *`), `vite build`s them into the\n * given out dir, and writes the import map. Captures stdout/stderr so a failure\n * is debuggable; the normal path stays quiet.\n */\nfunction runBuildWorker(\n dirname: string,\n outDir: string,\n include: string[],\n external: string[],\n base: string,\n nodeEnv: \"development\" | \"production\",\n own: Record<string, string> = {},\n): Promise<{ ok: boolean; stderr: string }> {\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, VENDOR_BUILD_WORKER);\n // A path the worker (raw node) can import to get connectDynamicBasePlugin:\n // the built bundle itself, or the built package entry when this module is\n // being run from source (vitest).\n const selfModulePath = resolveSelfModulePath();\n return new Promise((resolve) => {\n const child = spawn(\n process.execPath,\n [\n workerPath,\n dirname,\n outDir,\n JSON.stringify(include),\n VENDOR_URL_PREFIX,\n JSON.stringify(external),\n VENDOR_DYNAMIC_BASE,\n selfModulePath,\n base,\n nodeEnv,\n JSON.stringify({ files: own, roots: ownRoots(own) }),\n ],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let stderr = \"\";\n child.stdout.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.stderr.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.on(\"exit\", (code) => resolve({ ok: code === 0, stderr }));\n child.on(\"error\", (e) => resolve({ ok: false, stderr: String(e) }));\n });\n}\n\n/**\n * The vendor build worker, written to disk and run as a subprocess. Loads\n * `vite` from the project and `connectDynamicBasePlugin` from builder-tools' own\n * built bundle (selfModulePath). argv: dirname, vendorDir, includeJSON,\n * urlPrefix, externalJSON, dynamicBase, selfModulePath, base (app base),\n * nodeEnv.\n */\nconst VENDOR_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { mkdirSync, writeFileSync, rmSync } from 'node:fs';\nimport { join, isAbsolute } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nconst [dirname, vendorDir, includeJSON, urlPrefix, externalJSON, dynamicBase, selfModulePath, baseArg, nodeEnvArg, ownJSON] = process.argv.slice(2);\n// ownDeps: spec -> absolute entry file, plus each one's package root.\nconst { files: own = {}, roots: ownRootList = [] } = JSON.parse(ownJSON || '{}');\n// One chunk per own-dep package: split between an entry and a shared chunk, a\n// barrel can re-export from the entry and run before the classes it extends.\nconst ownGroups = ownRootList.map((root, i) => ({ name: 'own-' + i, test: (id) => id.startsWith(root) }));\n// Trailing argv are optional (older callers): base defaults to the dynamic\n// placeholder behavior, nodeEnv to development. baseArg is the APP base —\n// the same string the app build uses; the build base appends the vendor\n// segment so emitted asset URLs land under <app-base>__vendor__/.\nconst segment = urlPrefix.replace(/^\\\\/+/, '');\nconst base = baseArg ? baseArg + segment : dynamicBase;\nconst nodeEnv = nodeEnvArg ?? 'development';\nconst include = JSON.parse(includeJSON);\nconst external = JSON.parse(externalJSON ?? '[]');\nconst externalSet = new Set(external);\nconst reqProj = createRequire(join(dirname, 'noop.js'));\n// pathToFileURL: require.resolve returns an absolute path, and on Windows\n// import('D:\\\\...') parses \"D:\" as a URL scheme (ERR_UNSUPPORTED_ESM_URL_SCHEME).\nconst { build, esmExternalRequirePlugin } = await import(pathToFileURL(reqProj.resolve('vite')).href);\n// Load the dynamic-base plugin from builder-tools' own built bundle (passed as\n// an absolute path) — it isn't resolvable as a bare specifier from the worker.\nconst { connectDynamicBasePlugin, DYNAMIC_BASE_PLACEHOLDER } = await import(pathToFileURL(selfModulePath));\nconst srcDir = join(vendorDir, '.entries');\nmkdirSync(srcDir, { recursive: true });\nconst entryName = (spec) => spec.replace(/[^\\\\w]+/g, '_');\nconst RESERVED = new Set('enum void null function in instanceof typeof new delete do if else return switch case break continue for while this true false class const let var default export import extends super with yield debugger finally throw try catch await implements interface package private protected public static eval arguments'.split(' '));\nconst input = {};\nfor (const spec of include) {\n const name = entryName(spec);\n const from = own[spec] ?? spec;\n let src;\n try {\n // Import the bare spec (not reqProj.resolve(spec)) so Node picks the same\n // import/browser-condition module the build resolves — resolving first can\n // pick a CJS sibling whose default-export shape differs from the ESM build.\n const ns = await import(own[spec] ? pathToFileURL(own[spec]).href : spec);\n // Only fall back to re-exporting from default when the module exposes NO\n // top-level named exports (a true CJS-interop module). If it does (e.g. zod\n // exposes \\`z\\`), \\`export *\\` captures them; destructuring default would miss\n // top-level names that aren't keys of the default object.\n const named = Object.keys(ns).filter((k) => k !== 'default');\n const cjs = named.length === 0 && ns.default && typeof ns.default === 'object';\n // A strict entry keeps every export, and zod's \\`locales\\` (also reachable via \\`z\\`) pins\n // ~50 locales; publish them without it. zod/locales stays its own entry.\n const zodNs = (spec === 'zod' || spec.startsWith('zod/')) && !spec.includes('locales') && named.includes('locales');\n if (zodNs) {\n const keep = named.filter((k) => k !== 'locales' && k !== 'z' && /^[A-Za-z_$][\\\\w$]*$/.test(k));\n // \\`core\\` is zod/v4/core's namespace, which exports locales too: rebuild it without them.\n const coreKeys = keep.includes('core') ? Object.keys(await import('zod/v4/core')).filter((k) => k !== 'locales' && k !== 'default') : [];\n const reexport = keep.filter((k) => !(k === 'core' && coreKeys.length));\n src = 'export { ' + reexport.join(', ') + ' } from ' + JSON.stringify(from) + ';\\\\n'\n + 'import { ' + reexport.map((k) => k + ' as __z_' + k).join(', ') + ' } from ' + JSON.stringify(from) + ';\\\\n';\n if (coreKeys.length) {\n src += 'import { ' + coreKeys.map((k) => k + ' as __c_' + k).join(', ') + ' } from \"zod/v4/core\";\\\\n'\n + 'const __z_core = Object.freeze({ ' + coreKeys.map((k) => JSON.stringify(k) + ': __c_' + k).join(', ') + ' });\\\\n'\n + 'export { __z_core as core };\\\\n';\n }\n src += 'const z = Object.freeze({ ' + keep.map((k) => JSON.stringify(k) + ': __z_' + k).join(', ') + ' });\\\\n'\n + (named.includes('z') ? 'export { z };\\\\n' : '')\n + (('default' in ns) && ns.default === ns.z ? 'export { z as default };\\\\n' : '');\n } else if (cjs) {\n const names = Object.keys(ns.default).filter((k) => k !== 'default' && k !== '__esModule' && /^[A-Za-z_$][\\\\w$]*$/.test(k));\n const plain = names.filter((n) => !RESERVED.has(n));\n const reserved = names.filter((n) => RESERVED.has(n));\n src = 'import d from ' + JSON.stringify(from) + ';\\\\nexport default d;\\\\n'\n + (plain.length ? 'export const { ' + plain.join(', ') + ' } = d;\\\\n' : '');\n // reserved words are invalid as const-binding names but valid as export\n // aliases (export { x as enum }).\n reserved.forEach((n, i) => {\n src += 'const __r' + i + ' = d[' + JSON.stringify(n) + '];\\\\nexport { __r' + i + ' as ' + n + ' };\\\\n';\n });\n } else {\n src = 'export * from ' + JSON.stringify(from) + ';\\\\n'\n + (('default' in ns) ? 'export { default } from ' + JSON.stringify(from) + ';\\\\n' : '');\n }\n } catch {\n src = 'export * from ' + JSON.stringify(from) + ';\\\\n';\n }\n const file = join(srcDir, name + '.js');\n writeFileSync(file, src);\n input[name] = file;\n}\n// Prefer the bundler's browser-condition-aware resolution; fall back to resolving\n// from the worker (real install path) only for Rolldown's realpath-anchoring bug.\nconst phResolveCache = new Map();\nconst phVendorResolve = {\n name: 'ph-vendor-resolve', enforce: 'pre',\n async resolveId(source, importer, options) {\n if (externalSet.has(source)) return null;\n if (source[0] === '\\\\0' || source[0] === '.' || isAbsolute(source)) return null;\n if (source.startsWith('node:') || source.startsWith('data:')) return null;\n let viaBundler = null;\n try { viaBundler = await this.resolve(source, importer, { ...options, skipSelf: true }); } catch {}\n if (viaBundler) return viaBundler;\n if (phResolveCache.has(source)) return phResolveCache.get(source);\n let resolved = null;\n try { resolved = fileURLToPath(import.meta.resolve(source)); } catch {}\n phResolveCache.set(source, resolved);\n return resolved;\n },\n};\nconst result = await build({\n root: dirname, configFile: false, logLevel: 'error',\n // Caller-provided build base (or the dynamic placeholder default):\n // connectDynamicBasePlugin rewrites emitted chunk/asset URLs to resolve\n // against the deploy base at serve time.\n base,\n define: {\n 'process.env.NODE_ENV': JSON.stringify(nodeEnv),\n // BASE_URL resolves to the deploy base (not the vendor prefix) so vendored\n // Connect's router basename + BASE_URL-relative fetches use the right path.\n // The app base when provided (concrete or placeholder), the placeholder\n // otherwise (dev flow — rewritten at serve time by the dynamic-base plugin).\n 'import.meta.env.BASE_URL': JSON.stringify(baseArg ?? DYNAMIC_BASE_PLACEHOLDER),\n },\n // phVendorResolve (pre) resolves bares from the worker; esmExternalRequirePlugin owns\n // react/virtual externalization; connectDynamicBasePlugin (post) rewrites the placeholder base.\n plugins: [phVendorResolve, esmExternalRequirePlugin({ external }), connectDynamicBasePlugin()],\n // pglite ships web workers as ES-module chunks. workerStripPrefix is the vendor\n // segment so the worker recovers the deploy base, not the vendor prefix.\n worker: { format: 'es', plugins: () => [connectDynamicBasePlugin({ forWorker: true, workerStripPrefix: urlPrefix.replace(/^\\\\/+/, '') })] },\n build: {\n // Production ships this to every visitor, so minify it like the app's own\n // chunks; dev keeps readable output and the faster build.\n outDir: vendorDir, emptyOutDir: false, minify: nodeEnv === 'production', target: 'esnext', cssCodeSplit: true,\n rollupOptions: {\n input, preserveEntrySignatures: 'strict',\n // Content-hashed entry names: each build's import map points at new URLs.\n output: { format: 'es', entryFileNames: '[name]-[hash].js', chunkFileNames: 'chunks/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]', ...(ownGroups.length ? { codeSplitting: { groups: ownGroups } } : {}) },\n },\n },\n});\nrmSync(srcDir, { recursive: true, force: true });\nconst emitted = {};\nfor (const out of Array.isArray(result) ? result : [result]) {\n for (const chunk of out?.output ?? []) {\n if (chunk.type === 'chunk' && chunk.isEntry) emitted[chunk.name] = chunk.fileName;\n }\n}\nconst imports = {};\n// An entry the build never emitted keeps its unhashed name; the caller reports it as missing.\nfor (const spec of include) imports[spec] = urlPrefix + (emitted[entryName(spec)] ?? entryName(spec) + '.js');\nwriteFileSync(join(vendorDir, 'import-map.json'), JSON.stringify({ include, external, imports }, null, 2));\n`;\n","/**\n * Prebuild Connect's reactor SharedWorker into a browser-loadable bundle.\n *\n * The published `@powerhousedao/connect` dist ships `reactor.worker.js` as a\n * library artifact: its dependencies are externalized onto bare specifiers\n * (`@powerhousedao/reactor`, `kysely`, ...). The page resolves those through\n * its `<script type=\"importmap\">`, but import maps are a document feature —\n * a worker never inherits one and no Worker/SharedWorker constructor option\n * can supply one. A bare specifier inside a worker is unresolvable by the\n * platform, so the shipped file can never run as a worker script.\n *\n * This module builds the worker's module graph into a self-contained bundle\n * (one `vite build` in a throwaway subprocess, same pattern as the vendor\n * prebuild). Two modes:\n *\n * - With `vendorImports` (production builds that also ship the `__vendor__/`\n * bundle): specifiers present in the vendor import map are externalized and\n * rewritten to `../__vendor__/<entry>.js`. The worker bundle is served as a\n * sibling of `__vendor__/`, so those relative imports hit the exact URLs\n * the page's import map uses — one fetch and one HTTP-cache entry per\n * shared dep for the page and the worker together.\n * - Without (dev servers, `PH_CONNECT_VENDOR=0` builds): everything is\n * bundled; the worker is self-contained.\n *\n * The build uses Vite's relative base (`\"./\"`), so emitted chunk and asset\n * URLs resolve against the worker script's own URL. That sidesteps the\n * dynamic-base machinery entirely: the bundle works under any deploy base,\n * concrete or proxy-substituted, as long as it is served under\n * `<app-base>/__reactor_worker__/`.\n */\nimport { createHash } from \"node:crypto\";\nimport { spawn } from \"node:child_process\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n acquireLock,\n LOCK_STALE_MS,\n releaseLock,\n} from \"./externalize-vendor.js\";\n\n/** URL prefix the worker bundle is served under, next to `__vendor__/`. */\nexport const REACTOR_WORKER_URL_PREFIX = \"/__reactor_worker__/\";\n\n/** Entry filename of the bundle; the tab constructs its SharedWorker from it. */\nexport const REACTOR_WORKER_ENTRY = \"reactor.worker.js\";\n\n/** Metadata file the cache check reads; lives inside the bundle dir. */\nconst META_FILE = \"worker-meta.json\";\n\n/** Content-Type for the extensions the worker build emits; JS is the default. */\nexport const REACTOR_WORKER_MIME: Record<string, string> = {\n \".map\": \"application/json\",\n \".json\": \"application/json\",\n \".wasm\": \"application/wasm\",\n \".data\": \"application/octet-stream\",\n};\n\nexport interface ReactorWorkerVendorOptions {\n /** The vendor's import map (`spec -> /__vendor__/<entry>.js`). */\n imports: Record<string, string>;\n /** The built vendor dir, needed to verify which entries are worker-safe. */\n dir: string;\n}\n\nexport interface ReactorWorkerBuildOptions {\n /** Project root the worker's dependencies resolve from. */\n dirname: string;\n /** Directory to hold the bundle (e.g. `<dist>/__reactor_worker__`). */\n outDir: string;\n /**\n * The prebuilt vendor to share dependencies with. Only the worker-safe\n * subset of its entries is externalized (see\n * {@link workerSafeVendorImports}); omit to bundle everything.\n */\n vendor?: ReactorWorkerVendorOptions;\n /**\n * Worker entry to build. Defaults to the installed Connect dist's\n * `reactor.worker.js`; tests inject a fixture entry here.\n */\n entryPath?: string;\n /** NODE_ENV define for the build (default \"development\"). */\n nodeEnv?: \"development\" | \"production\";\n /** Filled with the failure cause when the prebuild returns null. */\n errorRef?: { message?: string };\n}\n\nexport interface PrebuiltReactorWorker {\n outDir: string;\n /** Entry filename inside outDir ({@link REACTOR_WORKER_ENTRY}). */\n entry: string;\n /**\n * Digest of everything that shaped this bundle's output (see\n * {@link computeSourceDigest}); identical for a cache hit and a fresh\n * build. The dev plugin serves it in `worker-meta.json` next to the\n * bundle; `apps/connect/src/utils/reactor-worker-url.ts` fetches it to\n * fold the actual built worker code into the tab's version fingerprint\n * (W0.6).\n */\n sourceDigest: string;\n /**\n * The worker-safe vendor subset this bundle externalizes (see\n * {@link workerSafeVendorImports}); empty without a vendor.\n */\n vendorImports: Record<string, string>;\n}\n\n/**\n * The installed Connect dist's worker entry, or null when the installed\n * version predates the worker (the feature is then unavailable, not broken).\n */\nexport function resolveReactorWorkerSource(dirname: string): string | null {\n try {\n const candidate = join(\n realpathSync(join(dirname, \"node_modules\", \"@powerhousedao/connect\")),\n \"dist\",\n REACTOR_WORKER_ENTRY,\n );\n return existsSync(candidate) ? candidate : null;\n } catch {\n return null;\n }\n}\n\n/** `/__vendor__/<entry>.js` -> `../__vendor__/<entry>.js` (sibling dirs). */\nexport function vendorRelativePath(vendorUrl: string): string {\n const file = vendorUrl.slice(vendorUrl.lastIndexOf(\"/\") + 1);\n return `../__vendor__/${file}`;\n}\n\n// Import/export specifier positions in emitted ES output, minified included:\n// static imports/re-exports, side-effect imports, and dynamic import(). The\n// lookbehind keeps member calls like `map.import(\"x\")` out.\nconst SPECIFIER_PATTERNS = [\n /(?<![.\\w$])import\\s*\\(\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])import\\s*[^\"'()]*?from\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])export\\s*[^\"'()]*?from\\s*[\"']([^\"']+)[\"']/g,\n /(?<![.\\w$])import\\s*[\"']([^\"']+)[\"']/g,\n];\n\n/**\n * Module specifiers a worker cannot resolve: anything that is not relative,\n * root-relative, or an http(s)/data/blob URL. Used as a post-build guard so a\n * leftover bare (or `node:`) import fails the build with a name instead of\n * shipping a worker that dies on its first import statement.\n *\n * Expects minified (comment-free) output: a raw-text scan cannot tell a real\n * import from a JSDoc code sample, and unminified kysely/viem are full of the\n * latter. The build below always minifies for exactly this reason.\n */\nexport function findDisallowedSpecifiers(code: string): string[] {\n const found = new Set<string>();\n for (const pattern of SPECIFIER_PATTERNS) {\n for (const match of code.matchAll(pattern)) {\n const spec = match[1];\n if (\n !spec.startsWith(\"./\") &&\n !spec.startsWith(\"../\") &&\n !spec.startsWith(\"/\") &&\n !/^(https?:|data:|blob:)/.test(spec)\n ) {\n found.add(spec);\n }\n }\n }\n return [...found].sort();\n}\n\ninterface WorkerBundleMeta {\n sourceDigest?: string;\n vendorKey?: string;\n nodeEnv?: string;\n}\n\n/**\n * Fallback list of packages whose BUILT dist shapes the worker bundle's output,\n * used only when the installed Connect's package.json cannot be read (see\n * {@link upstreamWorkerPackages}).\n */\nconst FALLBACK_UPSTREAM_WORKER_PACKAGES = [\n \"@powerhousedao/reactor\",\n \"@powerhousedao/reactor-browser\",\n];\n\n/** Dependency scopes whose installed dist can change the bundle's output. */\nconst UPSTREAM_SCOPES = [\"@powerhousedao/\", \"@renown/\"];\n\n/**\n * Packages whose BUILT dist shapes the worker bundle's output even when\n * connect's own dist/reactor.worker.js entry file did not change.\n *\n * That entry is a library artifact whose bare imports this build resolves\n * through node_modules at BUILD time, so a rebuilt dist anywhere in its\n * closure changes the bundle output without touching the entry file's own\n * size/mtime. The list is DERIVED from the installed Connect's own\n * dependencies rather than hardcoded: the bundle pulls `@renown/sdk`,\n * `@powerhousedao/powerhouse-vetra-packages` and `@powerhousedao/shared` out\n * of node_modules too, and a hardcoded pair left every one of those able to be\n * rebuilt behind a cache hit. Connect's dependency list is the cheap stand-in\n * for the resolved bundle graph: every workspace package the worker can reach\n * is reachable through it, and a package not in the bundle only costs a readdir.\n */\nexport function upstreamWorkerPackages(dirname: string): string[] {\n const connectDir = resolveWorkspacePackageDir(\n dirname,\n \"@powerhousedao/connect\",\n );\n if (!connectDir) return [...FALLBACK_UPSTREAM_WORKER_PACKAGES];\n let meta: { dependencies?: Record<string, string> };\n try {\n meta = JSON.parse(\n readFileSync(join(connectDir, \"package.json\"), \"utf8\"),\n ) as { dependencies?: Record<string, string> };\n } catch {\n return [...FALLBACK_UPSTREAM_WORKER_PACKAGES];\n }\n const names = Object.keys(meta.dependencies ?? {}).filter((name) =>\n UPSTREAM_SCOPES.some((scope) => name.startsWith(scope)),\n );\n for (const name of FALLBACK_UPSTREAM_WORKER_PACKAGES) {\n if (!names.includes(name)) names.push(name);\n }\n return names.sort();\n}\n\n/**\n * This module's own installed version, read by walking up from its file to\n * the nearest `package.json` named \"@powerhousedao/builder-tools\" (same\n * technique as `build-hash.ts`'s `readConnectVersion`: builder-tools'\n * `exports` map has no `./package.json` subpath, so node resolution can't\n * get there). Works whether this runs from source (tests, this monorepo) or\n * the built dist.\n */\nexport function resolveOwnPackageVersion(): string {\n try {\n let dir = pathDirname(fileURLToPath(import.meta.url));\n for (;;) {\n try {\n const pkg = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as { name?: string; version?: string };\n if (pkg.name === \"@powerhousedao/builder-tools\") {\n return pkg.version ?? \"unknown\";\n }\n } catch {\n // no readable package.json at this level; keep walking up\n }\n const parent = pathDirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // fall through to \"unknown\" below\n }\n return \"unknown\";\n}\n\n/**\n * This package's own version, computed once. Folded into the worker bundle\n * cache key so a builder-tools release — which can change how the bundle is\n * built (anything in this module beyond {@link WORKER_BUILD_WORKER} itself,\n * e.g. `workerSafeVendorImports`, the resolve plugin) — invalidates bundles\n * a prior builder-tools version cached.\n */\nexport const BUILDER_TOOLS_VERSION = resolveOwnPackageVersion();\n\n/**\n * A workspace package's real directory, resolved the way Node's resolver\n * would (through `node_modules`), or null when it is not installed (e.g. a\n * non-monorepo consumer project — graceful, not an error). pnpm's\n * node_modules symlinks resolve to the real package directory, so this\n * reflects the monorepo's actual dist state, not a stale symlink target.\n */\nexport function resolveWorkspacePackageDir(\n dirname: string,\n pkgName: string,\n): string | null {\n try {\n return realpathSync(join(dirname, \"node_modules\", ...pkgName.split(\"/\")));\n } catch {\n return null;\n }\n}\n\n/**\n * Cheap content fingerprint of a directory's immediate files: no file bytes\n * are read, just each entry's name/size/mtime, so it stays fast even for a\n * large dist. Sensitive to a rebuild in the common cases: Vite's\n * content-hashed chunk filenames change the name itself; a stable-named file\n * (an entry point) changes size or mtime. Bounded (`maxFiles`) so a\n * pathological directory cannot make this slow — deliberately not a\n * full-tree hash.\n *\n * The names are sorted BEFORE the bound is applied, so the subset the bound\n * keeps is the same subset on every run: readdir order is unspecified, and\n * truncating it first made the fingerprint of a directory past the bound a\n * function of whatever order the filesystem happened to report.\n */\nexport function distDirFingerprint(dir: string, maxFiles = 1000): string {\n try {\n const names = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name)\n .sort();\n return names\n .slice(0, maxFiles)\n .map((name) => {\n const stat = statSync(join(dir, name));\n return `${name}:${stat.size}:${Math.round(stat.mtimeMs)}`;\n })\n .join(\"|\");\n } catch {\n return \"unreadable\";\n }\n}\n\n// Digest of everything that shapes the output: the connect dist the entry\n// comes from (version + entry mtime/size cover a rebuild in place), the\n// upstream packages the entry's bare imports resolve into at build time\n// (dist fingerprint, over the list {@link upstreamWorkerPackages} derives —\n// covers an upstream rebuild that never touched connect's own dist), the\n// vendor the externals point at (its\n// import-map.json changes whenever the vendor is rebuilt), NODE_ENV, the\n// build-worker source, and the builder-tools version, so a logic change\n// (in either the inline build-worker script or this module more broadly)\n// busts stale bundles.\nexport function computeSourceDigest(\n dirname: string,\n entryPath: string,\n vendorDir?: string,\n builderToolsVersion: string = BUILDER_TOOLS_VERSION,\n): string {\n const h = createHash(\"sha256\");\n h.update(`builder:${WORKER_BUILD_WORKER_HASH}\\n`);\n h.update(`builder-tools:${builderToolsVersion}\\n`);\n try {\n const pkgRoot = resolveWorkspacePackageDir(\n dirname,\n \"@powerhousedao/connect\",\n );\n if (!pkgRoot) throw new Error(\"unresolved\");\n const meta = JSON.parse(\n readFileSync(join(pkgRoot, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n h.update(`connect:${meta.version ?? \"unknown\"}\\n`);\n } catch {\n h.update(\"connect:unresolved\\n\");\n }\n try {\n const stat = statSync(entryPath);\n h.update(`entry:${stat.size}:${Math.round(stat.mtimeMs)}\\n`);\n } catch {\n h.update(\"entry:unstatable\\n\");\n }\n for (const pkg of upstreamWorkerPackages(dirname)) {\n const pkgDir = resolveWorkspacePackageDir(dirname, pkg);\n h.update(\n `${pkg}:${pkgDir ? distDirFingerprint(join(pkgDir, \"dist\")) : \"unresolved\"}\\n`,\n );\n }\n if (vendorDir) {\n try {\n h.update(\n `vendor:${createHash(\"sha256\")\n .update(readFileSync(join(vendorDir, \"import-map.json\")))\n .digest(\"hex\")}\\n`,\n );\n } catch {\n h.update(\"vendor:unreadable\\n\");\n }\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n\nfunction vendorKeyOf(vendorImports: Record<string, string>): string {\n const entries = Object.entries(vendorImports).sort(([a], [b]) =>\n a.localeCompare(b),\n );\n return createHash(\"sha256\")\n .update(JSON.stringify(entries))\n .digest(\"hex\")\n .slice(0, 16);\n}\n\nfunction readWorkerCacheHit(\n metaPath: string,\n sourceDigest: string,\n vendorKey: string,\n nodeEnv: string,\n): boolean {\n if (!existsSync(metaPath)) return false;\n try {\n const cached = JSON.parse(\n readFileSync(metaPath, \"utf8\"),\n ) as WorkerBundleMeta;\n return (\n cached.sourceDigest === sourceDigest &&\n cached.vendorKey === vendorKey &&\n cached.nodeEnv === nodeEnv &&\n existsSync(join(pathDirname(metaPath), REACTOR_WORKER_ENTRY))\n );\n } catch {\n return false;\n }\n}\n\n/** Content digest of a directory tree (relative paths + bytes; source maps skipped). */\nexport function directoryContentDigest(dir: string): string {\n const h = createHash(\"sha256\");\n const files = readdirSync(dir, { recursive: true, withFileTypes: true })\n .filter((e) => e.isFile() && !e.name.endsWith(\".map\"))\n .map((e) => join(e.parentPath, e.name))\n .sort();\n for (const file of files) {\n h.update(`${file.slice(dir.length).split(\"\\\\\").join(\"/\")}\\n`);\n h.update(readFileSync(file));\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n\nasync function waitForWorkerCacheHit(\n metaPath: string,\n sourceDigest: string,\n vendorKey: string,\n nodeEnv: string,\n lockDir: string,\n): Promise<boolean> {\n const deadline = Date.now() + LOCK_STALE_MS;\n while (Date.now() < deadline) {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return true;\n }\n if (!existsSync(lockDir)) {\n return readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv);\n }\n await new Promise((r) => setTimeout(r, 250));\n }\n return false;\n}\n\n/**\n * Build the worker bundle (once, in a throwaway subprocess) into `outDir`.\n * Idempotent: reuses a cached bundle built from the same connect dist, vendor\n * mapping, and builder logic. Returns null on failure (`errorRef` carries the\n * cause) or when the installed Connect has no worker entry.\n */\nexport async function prebuildReactorWorker(\n options: ReactorWorkerBuildOptions,\n): Promise<PrebuiltReactorWorker | null> {\n const entryPath =\n options.entryPath ?? resolveReactorWorkerSource(options.dirname);\n if (!entryPath) {\n if (options.errorRef) {\n options.errorRef.message =\n \"the installed @powerhousedao/connect ships no dist/reactor.worker.js\";\n }\n return null;\n }\n const vendorImports = options.vendor\n ? workerSafeVendorImports(options.vendor.dir, options.vendor.imports)\n : {};\n const nodeEnv = options.nodeEnv ?? \"development\";\n const outDir = options.outDir;\n const metaPath = join(outDir, META_FILE);\n const sourceDigest = computeSourceDigest(\n options.dirname,\n entryPath,\n options.vendor?.dir,\n );\n const vendorKey = vendorKeyOf(vendorImports);\n const result: PrebuiltReactorWorker = {\n outDir,\n entry: REACTOR_WORKER_ENTRY,\n sourceDigest,\n vendorImports,\n };\n\n try {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return result;\n }\n\n const lockDir = `${outDir}.lock`;\n const lock = acquireLock(lockDir);\n if (!lock) {\n const hit = await waitForWorkerCacheHit(\n metaPath,\n sourceDigest,\n vendorKey,\n nodeEnv,\n lockDir,\n );\n return hit ? result : null;\n }\n\n try {\n if (readWorkerCacheHit(metaPath, sourceDigest, vendorKey, nodeEnv)) {\n return result;\n }\n await buildWorkerAtomic(\n options.dirname,\n outDir,\n entryPath,\n vendorImports,\n nodeEnv,\n { sourceDigest, vendorKey, nodeEnv },\n );\n return result;\n } finally {\n releaseLock(lock);\n }\n } catch (err) {\n if (options.errorRef) {\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n }\n return null;\n }\n}\n\nasync function buildWorkerAtomic(\n dirname: string,\n outDir: string,\n entryPath: string,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n meta: WorkerBundleMeta,\n): Promise<void> {\n const parent = pathDirname(outDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-reactor-worker.tmp-\"));\n try {\n const { ok, stderr } = await runWorkerBuild(\n dirname,\n tmpDir,\n { \"reactor.worker\": entryPath },\n vendorImports,\n nodeEnv,\n );\n if (!ok || !existsSync(join(tmpDir, REACTOR_WORKER_ENTRY))) {\n const detail = stderr.trim();\n throw new Error(\n `reactor worker build failed${detail ? `:\\n${detail}` : \" (no output captured)\"}`,\n );\n }\n\n // A worker dies on its first unresolvable import, and the browser reports\n // only an opaque load failure. Fail here instead, naming the specifiers.\n assertWorkerResolvable(tmpDir);\n\n writeFileSync(join(tmpDir, META_FILE), JSON.stringify(meta, null, 2));\n publishDirAtomic(tmpDir, outDir);\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw err;\n }\n}\n\n/** Replace `outDir` with the finished `tmpDir`, old contents removed last. */\nexport function publishDirAtomic(tmpDir: string, outDir: string): void {\n const oldDir = `${outDir}.old-${process.pid}-${Date.now()}`;\n if (existsSync(outDir)) renameSync(outDir, oldDir);\n renameSync(tmpDir, outDir);\n // mkdtemp creates 0700; the build and the server are not always the same\n // user (see the vendor swap for the full story).\n chmodSync(outDir, 0o755);\n rmSync(oldDir, { recursive: true, force: true });\n}\n\n// Relative specifiers in import positions, used to walk the emitted graph.\nconst RELATIVE_SPECIFIER_PATTERNS = SPECIFIER_PATTERNS;\n\nfunction findRelativeSpecifiers(code: string): string[] {\n const found = new Set<string>();\n for (const pattern of RELATIVE_SPECIFIER_PATTERNS) {\n for (const match of code.matchAll(pattern)) {\n const spec = match[1];\n if (spec.startsWith(\"./\") || spec.startsWith(\"../\")) found.add(spec);\n }\n }\n return [...found];\n}\n\n// Normalize a bundle-relative path: forward slashes, `.`/`..` folded. Paths\n// escaping the bundle (e.g. the ../__vendor__/ externals) come back empty.\nfunction normalizeBundlePath(fromFile: string, spec: string): string {\n const segments = fromFile.split(\"/\").slice(0, -1);\n for (const part of spec.split(\"/\")) {\n if (part === \"\" || part === \".\") continue;\n if (part === \"..\") {\n if (segments.length === 0) return \"\";\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return segments.join(\"/\");\n}\n\n/**\n * Scan the emitted JS files REACHABLE from the entry via import statements\n * for specifiers a worker cannot resolve. Vendor externals were rewritten to\n * ../__vendor__/ relative paths, so anything bare that survives in the graph\n * is a real defect.\n *\n * Deliberately a graph walk, not a directory walk: the bundled reactor code\n * carries `new URL(..., import.meta.url)` references to its node\n * worker-thread entries (executor/projection workers), which Vite emits as\n * stray assets full of node-only imports. They are unreachable dead weight in\n * a browser bundle — the production vendor output tolerates the same files —\n * and must not fail the build.\n */\nexport function findBundleSpecifierOffenders(\n bundleDir: string,\n entry: string = REACTOR_WORKER_ENTRY,\n): { file: string; specs: string[] }[] {\n const offenders: { file: string; specs: string[] }[] = [];\n walkBundleGraph(bundleDir, entry, (file, code) => {\n const specs = findDisallowedSpecifiers(code);\n if (specs.length > 0) offenders.push({ file, specs });\n return true;\n });\n return offenders;\n}\n\n// Visits each JS file reachable from `entry` via relative imports. Stops and\n// returns false as soon as `visit` does.\nfunction walkBundleGraph(\n bundleDir: string,\n entry: string,\n visit: (file: string, code: string) => boolean,\n): boolean {\n const seen = new Set<string>();\n const queue = [entry];\n while (queue.length > 0) {\n const rel = queue.shift()!;\n if (seen.has(rel)) continue;\n seen.add(rel);\n const full = join(bundleDir, rel);\n if (!existsSync(full) || statSync(full).isDirectory()) continue;\n if (!rel.endsWith(\".js\") && !rel.endsWith(\".mjs\")) continue;\n const code = readFileSync(full, \"utf8\");\n if (!visit(rel, code)) return false;\n for (const spec of findRelativeSpecifiers(code)) {\n const next = normalizeBundlePath(rel, spec);\n if (next) queue.push(next);\n }\n }\n return true;\n}\n\nfunction assertWorkerResolvable(bundleDir: string): void {\n const offenders = findBundleSpecifierOffenders(bundleDir);\n if (offenders.length > 0) {\n throw new Error(\n \"reactor worker bundle contains module specifiers a worker cannot resolve:\\n\" +\n offenders.map((o) => ` ${o.file}: ${o.specs.join(\", \")}`).join(\"\\n\"),\n );\n }\n}\n\n// Page-only code that survives minification: the dynamic-base expression\n// (`(globalThis.__PH_DYNAMIC_BASE__||\"/\")`, set by the serving proxy on the\n// main thread only) and the event Vite's preload helper dispatches on\n// `window` (the helper also appends `<link>` tags to `document`).\nconst WORKER_UNSAFE_MARKERS = [\"__PH_DYNAMIC_BASE__\", \"vite:preloadError\"];\n\n/** The page-only markers present in `code`, in a fixed order. */\nexport function findWorkerUnsafeMarkers(code: string): string[] {\n return WORKER_UNSAFE_MARKERS.filter((marker) => code.includes(marker));\n}\n\n/**\n * The subset of the vendor's entries a worker may import.\n *\n * The vendor build keeps the React family external: its chunks carry bare\n * `import \"react\"` statements that the PAGE resolves through its import map.\n * A worker resolves no import map, so externalizing a vendor spec whose chunk\n * closure reaches such an import would kill the worker on its first load —\n * and the chunk graph is shared across vendor entries, so even a React-free\n * module (e.g. an rpc subpath) can be entangled with React through a shared\n * chunk. The vendor is also built for the page: a dynamic-base build rewrites\n * its asset URLs onto a global only the page sets, and its dynamic imports go\n * through Vite's preload helper, which needs `document`. Each entry's own\n * closure inside the vendor dir decides: clean closure, worker-safe; anything\n * bare or page-only in it (see {@link findWorkerUnsafeMarkers}), or a missing\n * entry file, bundled into the worker instead.\n */\nexport function workerSafeVendorImports(\n vendorDir: string,\n vendorImports: Record<string, string>,\n): Record<string, string> {\n const safe: Record<string, string> = {};\n for (const [spec, url] of Object.entries(vendorImports)) {\n const entryFile = url.slice(url.lastIndexOf(\"/\") + 1);\n if (!existsSync(join(vendorDir, entryFile))) continue;\n const clean = walkBundleGraph(\n vendorDir,\n entryFile,\n (_file, code) =>\n findDisallowedSpecifiers(code).length === 0 &&\n findWorkerUnsafeMarkers(code).length === 0,\n );\n if (clean) safe[spec] = url;\n }\n return safe;\n}\n\n/**\n * Builds arbitrary worker-loadable entries with the worker build config.\n * Exported for the local-package bundles, which need the same self-contained\n * output and vendor externalization at a different depth.\n */\nexport function runWorkerBuildEntries(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n vendorPrefix = \"../__vendor__/\",\n): Promise<{ ok: boolean; stderr: string }> {\n return runWorkerBuild(\n dirname,\n outDir,\n entries,\n vendorImports,\n nodeEnv,\n vendorPrefix,\n );\n}\n\nfunction runWorkerBuild(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n vendorImports: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n vendorPrefix = \"../__vendor__/\",\n): Promise<{ ok: boolean; stderr: string }> {\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, WORKER_BUILD_WORKER);\n return new Promise((resolve) => {\n const child = spawn(\n process.execPath,\n [\n workerPath,\n dirname,\n outDir,\n JSON.stringify(entries),\n JSON.stringify(vendorImports),\n nodeEnv,\n resolveBuilderVite() ?? \"\",\n vendorPrefix,\n ],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let stderr = \"\";\n child.stdout.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.stderr.on(\"data\", (d) => {\n stderr += String(d);\n });\n child.on(\"exit\", (code) => {\n rmSync(workerPath, { force: true });\n resolve({ ok: code === 0, stderr });\n });\n child.on(\"error\", (e) => resolve({ ok: false, stderr: String(e) }));\n });\n}\n\n/**\n * The vite installed next to this module. The subprocess must run the vite\n * this build config was written against: a consumer project can pin an older\n * vite/rolldown (overrides) whose bundler leaves unresolvable specifiers bare\n * instead of erroring and shims node builtins differently — the output guard\n * then correctly rejects the bundle. builder-tools declares vite as a direct\n * dependency, so this resolution works wherever builder-tools is installed.\n */\nfunction resolveBuilderVite(): string | null {\n try {\n return createRequire(import.meta.url).resolve(\"vite\");\n } catch {\n return null;\n }\n}\n\n/**\n * The build subprocess (same pattern as the vendor's). Loads builder-tools'\n * own vite (argv; project fallback) and builds the given entries with\n * relative base, so chunk/asset URLs resolve against each script's own URL\n * under any deploy base. argv: dirname, outDir, entriesJSON (name ->\n * absolute entry path), vendorImportsJSON, nodeEnv, vitePath, vendorPrefix\n * (relative path from the out dir to __vendor__/, e.g. \"../__vendor__/\").\n */\nconst WORKER_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { isAbsolute } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nconst [dirname, outDir, entriesJSON, vendorImportsJSON, nodeEnvArg, vitePathArg, vendorPrefixArg] = process.argv.slice(2);\nconst nodeEnv = nodeEnvArg ?? 'development';\nconst entries = JSON.parse(entriesJSON);\nconst vendorImports = JSON.parse(vendorImportsJSON ?? '{}');\nconst vendorPrefix = vendorPrefixArg || '../__vendor__/';\nconst externalSet = new Set(Object.keys(vendorImports));\nconst vendorPath = (spec) => {\n const url = vendorImports[spec];\n return vendorPrefix + url.slice(url.lastIndexOf('/') + 1);\n};\nconst reqProj = createRequire(dirname + '/noop.js');\n// pathToFileURL: on Windows import('D:\\\\\\\\...') parses \"D:\" as a URL scheme.\nconst vitePath = vitePathArg || reqProj.resolve('vite');\nconst { build } = await import(pathToFileURL(vitePath).href);\n// Resolve bare specifiers from the project (same plugin as the vendor build):\n// prefer the bundler's browser-condition-aware resolution, fall back to the\n// worker's own resolution for Rolldown's realpath-anchoring bug.\nconst phResolveCache = new Map();\nconst phWorkerResolve = {\n name: 'ph-reactor-worker-resolve', enforce: 'pre',\n async resolveId(source, importer, options) {\n if (externalSet.has(source)) return null;\n if (source[0] === '\\\\0' || source[0] === '.' || isAbsolute(source)) return null;\n if (source.startsWith('node:') || source.startsWith('data:')) return null;\n let viaBundler = null;\n try { viaBundler = await this.resolve(source, importer, { ...options, skipSelf: true }); } catch {}\n if (viaBundler) return viaBundler;\n if (phResolveCache.has(source)) return phResolveCache.get(source);\n let resolved = null;\n try { resolved = fileURLToPath(import.meta.resolve(source)); } catch {}\n phResolveCache.set(source, resolved);\n return resolved;\n },\n};\n// A worker has no window: on a failed dynamic import, the preload helper's\n// window.dispatchEvent would throw a ReferenceError in place of the real error.\nconst PRELOAD_HELPER_ID = '\\\\0vite/preload-helper.js';\nconst PRELOAD_DISPATCH = 'window.dispatchEvent(';\nconst phWorkerPreloadHelper = {\n name: 'ph-reactor-worker-preload-helper',\n transform(code, id) {\n if (id !== PRELOAD_HELPER_ID) return null;\n if (code.split(PRELOAD_DISPATCH).length !== 2) {\n this.error('expected exactly one ' + PRELOAD_DISPATCH + ' in ' + PRELOAD_HELPER_ID);\n }\n return { code: code.replace(PRELOAD_DISPATCH, 'globalThis.dispatchEvent?.('), map: null };\n },\n};\nawait build({\n root: dirname, configFile: false, logLevel: 'error',\n // The project's public/ dir belongs to the app build, not this bundle.\n publicDir: false,\n // Relative base: emitted chunk/asset URLs resolve against the worker\n // script's own URL, so the bundle works under any deploy base.\n base: './',\n define: {\n 'process.env.NODE_ENV': JSON.stringify(nodeEnv),\n 'import.meta.env.BASE_URL': JSON.stringify('./'),\n },\n plugins: [phWorkerResolve, phWorkerPreloadHelper],\n // pglite ships nested web workers as ES-module chunks.\n worker: { format: 'es' },\n build: {\n // Always minified, dev included: the bundle is browser-served output\n // (sourcemaps carry the debugging story), and minification strips the\n // JSDoc comments whose embedded code samples (kysely's, viem's) would\n // otherwise trip the bare-specifier guard below.\n outDir, emptyOutDir: false, minify: true, target: 'esnext', sourcemap: true,\n // No document in a worker: the module-preload polyfill and preload helper\n // touch the DOM, so dynamic imports must stay plain import().\n modulePreload: false,\n rollupOptions: {\n input: entries,\n // A models entry is pure re-exports; without this the bundler treats\n // its exports as unused and tree-shakes the whole file to nothing.\n // Harmless for the worker entry, which exports nothing to preserve.\n preserveEntrySignatures: 'strict',\n external: (id) => externalSet.has(id),\n output: {\n format: 'es', entryFileNames: '[name].js',\n // Chunks live at the bundle root, not a chunks/ subdir: the vendor\n // paths below are emitted VERBATIM into every chunk, so all modules\n // must sit at the same depth for ../__vendor__/ to resolve.\n chunkFileNames: '[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]',\n paths: (id) => (externalSet.has(id) ? vendorPath(id) : id),\n },\n },\n },\n});\n`;\n\nconst WORKER_BUILD_WORKER_HASH = createHash(\"sha256\")\n .update(WORKER_BUILD_WORKER)\n .digest(\"hex\")\n .slice(0, 16);\n","/**\n * Prebuild a project's local packages into worker-loadable model bundles.\n *\n * The reactor worker gets document models from the registry CDN or from what\n * Connect statically bundled. A project's own (`provider: \"local\"`) package is\n * in neither, so its document types have no reducer in the worker and their\n * load jobs fail. Dev solves this by pointing the worker at the dev server's\n * transformed models entry; a production deployment has no dev server, so the\n * entry is prebuilt here, next to the worker bundle it is loaded beside.\n *\n * Each package's `browser/document-models/index.js` (reducers only: no React,\n * no CSS, no editors) is built self-contained, with the worker-safe subset of\n * the vendor externalized onto `../../__vendor__/` - two levels up, since\n * these land in `__reactor_worker__/packages/`. A `manifest.json` names what\n * was built so the tab can turn it into package sources without guessing.\n */\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n realpathSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname as pathDirname, join } from \"node:path\";\nimport { workerPackageFileName } from \"@powerhousedao/shared/connect\";\nimport {\n findBundleSpecifierOffenders,\n publishDirAtomic,\n runWorkerBuildEntries,\n workerSafeVendorImports,\n type ReactorWorkerVendorOptions,\n} from \"./reactor-worker-build.js\";\n\n/** Served under `<base>__reactor_worker__/packages/`. */\nexport const WORKER_PACKAGES_MANIFEST = \"manifest.json\";\n\n/** Vendor is two levels up from `__reactor_worker__/packages/`. */\nconst VENDOR_PREFIX = \"../../__vendor__/\";\n\nexport interface WorkerPackagesBuildOptions {\n /** Project root the packages resolve from. */\n dirname: string;\n /** Local package names (`provider: \"local\"` in powerhouse.config.json). */\n packages: string[];\n /** Directory to hold the bundles (`<dist>/__reactor_worker__/packages`). */\n outDir: string;\n /** The prebuilt vendor to share dependencies with, when one was built. */\n vendor?: ReactorWorkerVendorOptions;\n /**\n * The vendor's worker-safe subset, when the caller already computed it\n * (`PrebuiltReactorWorker.vendorImports`); skips walking the vendor again.\n */\n safeVendorImports?: Record<string, string>;\n nodeEnv?: \"development\" | \"production\";\n errorRef?: { message?: string };\n}\n\nexport interface WorkerPackageManifestEntry {\n name: string;\n version?: string;\n /** Filename inside outDir, as {@link workerPackageFileName} spells it. */\n file: string;\n}\n\nfunction readVersion(root: string): string | undefined {\n try {\n const meta = JSON.parse(\n readFileSync(join(root, \"package.json\"), \"utf8\"),\n ) as { version?: string };\n return typeof meta.version === \"string\" ? meta.version : undefined;\n } catch {\n // version is decoration; the bundle is what matters\n return undefined;\n }\n}\n\n/**\n * A package root's models entry, or null when it ships none.\n *\n * Two roots are possible and both are normal: an installed dependency under\n * `node_modules/<name>`, and the project itself - the vetra case, where the\n * project *is* the local package and has no self-link in node_modules.\n */\nfunction resolvePackageModels(\n dirname: string,\n name: string,\n): { entryPath: string; version?: string } | null {\n const roots: string[] = [];\n try {\n roots.push(realpathSync(join(dirname, \"node_modules\", name)));\n } catch {\n // not installed; the project itself may still be the package\n }\n if (readProjectName(dirname) === name) {\n roots.push(dirname);\n }\n for (const root of roots) {\n const entryPath = join(\n root,\n \"dist\",\n \"browser\",\n \"document-models\",\n \"index.js\",\n );\n if (existsSync(entryPath)) {\n return { entryPath, version: readVersion(root) };\n }\n }\n return null;\n}\n\nfunction readProjectName(dirname: string): string | undefined {\n try {\n const meta = JSON.parse(\n readFileSync(join(dirname, \"package.json\"), \"utf8\"),\n ) as { name?: string };\n return typeof meta.name === \"string\" ? meta.name : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The project's own package name when it ships a models bundle, so a caller\n * can include it beside the configured `provider: \"local\"` packages. A vetra\n * project declares no package entry for itself, yet its models are exactly\n * the ones the worker is missing.\n */\nexport function ownProjectPackage(dirname: string): string | undefined {\n const name = readProjectName(dirname);\n if (!name) return undefined;\n return resolvePackageModels(dirname, name) ? name : undefined;\n}\n\n/**\n * Build each local package's models entry into `outDir` and write the\n * manifest the tab reads. Returns the manifest entries (empty when no local\n * package ships a models bundle), or null when the build itself failed -\n * `errorRef` then carries the cause. Both of those remove `outDir`, so a\n * previous build's bundles never outlive the packages they came from.\n */\nexport async function prebuildWorkerPackages(\n options: WorkerPackagesBuildOptions,\n): Promise<WorkerPackageManifestEntry[] | null> {\n const nodeEnv = options.nodeEnv ?? \"production\";\n const resolved: {\n entry: WorkerPackageManifestEntry;\n entryPath: string;\n }[] = [];\n for (const name of options.packages) {\n const models = resolvePackageModels(options.dirname, name);\n if (!models) continue;\n resolved.push({\n entry: {\n name,\n version: models.version,\n file: workerPackageFileName(name),\n },\n entryPath: models.entryPath,\n });\n }\n if (resolved.length === 0) {\n rmSync(options.outDir, { recursive: true, force: true });\n return [];\n }\n\n const vendorImports =\n options.safeVendorImports ??\n (options.vendor\n ? workerSafeVendorImports(options.vendor.dir, options.vendor.imports)\n : {});\n // Entry names are the filenames minus `.js`; the subprocess appends it.\n const entries = Object.fromEntries(\n resolved.map((item) => [\n item.entry.file.replace(/\\.js$/, \"\"),\n item.entryPath,\n ]),\n );\n\n const parent = pathDirname(options.outDir);\n mkdirSync(parent, { recursive: true });\n const tmpDir = mkdtempSync(join(parent, \".ph-worker-packages.tmp-\"));\n try {\n const { ok, stderr } = await runWorkerBuildEntries(\n options.dirname,\n tmpDir,\n entries,\n vendorImports,\n nodeEnv,\n VENDOR_PREFIX,\n );\n const missing = resolved.filter(\n (item) => !existsSync(join(tmpDir, item.entry.file)),\n );\n if (!ok || missing.length > 0) {\n const detail = stderr.trim();\n throw new Error(\n `worker package bundles failed to build${\n missing.length > 0\n ? ` (missing: ${missing.map((m) => m.entry.name).join(\", \")})`\n : \"\"\n }${detail ? `:\\n${detail}` : \"\"}`,\n );\n }\n\n // Same guard as the worker entry: a bare specifier here kills the import\n // inside the worker, with only an opaque failure to show for it.\n for (const item of resolved) {\n const offenders = findBundleSpecifierOffenders(tmpDir, item.entry.file);\n if (offenders.length > 0) {\n throw new Error(\n `worker package bundle for ${item.entry.name} contains module ` +\n `specifiers a worker cannot resolve:\\n` +\n offenders\n .map((o) => ` ${o.file}: ${o.specs.join(\", \")}`)\n .join(\"\\n\"),\n );\n }\n }\n\n const manifest = resolved.map((item) => item.entry);\n writeFileSync(\n join(tmpDir, WORKER_PACKAGES_MANIFEST),\n JSON.stringify(manifest, null, 2),\n );\n\n publishDirAtomic(tmpDir, options.outDir);\n return manifest;\n } catch (err) {\n rmSync(tmpDir, { recursive: true, force: true });\n rmSync(options.outDir, { recursive: true, force: true });\n if (options.errorRef) {\n options.errorRef.message =\n err instanceof Error ? err.message : String(err);\n }\n return null;\n }\n}\n","// JSON Schema (draft-07) for dist/powerhouse.config.json — the runtime\n// artifact emitted into the build output and fetched by the Connect SPA at\n// boot.\n//\n// A strict SUBSET of the source PowerhouseConfig schema plus two runtime-only\n// fields (schemaVersion, localPackage). Field shapes shared with the source\n// schema (PowerhousePackage, PHConnectRuntimeConfig) are imported from the\n// shared fragments module so the two schemas stay in sync by construction.\n\nimport {\n phConnectRuntimeConfigSchema,\n powerhousePackageSchema,\n} from \"@powerhousedao/shared/connect\";\n\nexport const RUNTIME_CONFIG_SCHEMA_ID =\n \"https://powerhouse.inc/schemas/powerhouse.config.json\";\n\n// GitHub-hosted schema URL. Points at the JSON artifact committed alongside\n// this TS module. Currently tracks the `main` branch — schema edits go live\n// for editors as soon as they merge. Migrate to a `schema-v<N>` tag pinned\n// to schemaVersion if/when stability across edits becomes a concern.\nexport const RUNTIME_CONFIG_SCHEMA_URL =\n \"https://raw.githubusercontent.com/powerhouse-inc/powerhouse/main/packages/builder-tools/connect-utils/runtime-config.schema.json\";\n\nexport const runtimeConfigSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n $id: RUNTIME_CONFIG_SCHEMA_ID,\n title: \"Powerhouse Connect runtime configuration\",\n description:\n \"Runtime configuration loaded by Connect at boot from /powerhouse.config.json.\",\n type: \"object\",\n additionalProperties: false,\n required: [\"schemaVersion\", \"packages\", \"localPackage\"],\n properties: {\n $schema: {\n type: \"string\",\n description:\n \"Optional JSON Schema reference for editor autocomplete. Set to the GitHub-hosted schema URL.\",\n },\n schemaVersion: {\n const: 2,\n description:\n \"Schema version. Must match the SPA bundle that ships with this dist. The SPA throws on mismatch to prevent SPA/config skew.\",\n },\n packages: {\n type: \"array\",\n description:\n \"Powerhouse packages this Connect instance loads at runtime.\",\n items: powerhousePackageSchema,\n },\n packageRegistryUrl: {\n type: \"string\",\n description:\n \"Project-wide package registry endpoint. Copied verbatim from the source `powerhouse.config.json` top-level field — the SPA's Package Manager UI reads this directly.\",\n },\n localPackage: {\n description:\n \"Identity of the consumer project itself, captured at build time. null for Docker images and other generic deploys with no host project.\",\n oneOf: [\n { type: \"null\" },\n {\n type: \"object\",\n additionalProperties: false,\n required: [\"name\", \"version\"],\n properties: {\n name: { type: \"string\" },\n version: { type: \"string\" },\n },\n },\n ],\n },\n connect: phConnectRuntimeConfigSchema,\n },\n} as const;\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\n\nexport type PhBundledPackagesPluginOptions = {\n /**\n * Package names (with `provider: \"local\"` in powerhouse.config.json)\n * that should be bundled into Connect at build time. Each must be\n * resolvable from node_modules.\n */\n packages: string[];\n /** Project root used to read each bundled package's package.json version. */\n projectRoot?: string;\n};\n\nexport const VIRTUAL_ID = \"ph-bundled-packages-virtual\";\nexport const RESOLVED_VIRTUAL_ID = \"\\0virtual:\" + VIRTUAL_ID;\n// Vite serves a resolved id at /@id/<id with \\0 → __x00__>.\nexport const BUNDLED_PACKAGES_DEV_URL =\n \"@id/\" + RESOLVED_VIRTUAL_ID.replace(\"\\0\", \"__x00__\");\n\nfunction readBundledPackageVersion(\n projectRoot: string,\n name: string,\n): string | undefined {\n try {\n const raw = fs.readFileSync(\n path.join(projectRoot, \"node_modules\", name, \"package.json\"),\n \"utf-8\",\n );\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === \"string\" ? pkg.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction makeRegisterModule(packages: string[], projectRoot: string): string {\n if (packages.length === 0) {\n return \"export default () => {};\\n\";\n }\n const imports: string[] = [];\n const calls: string[] = [];\n\n packages.forEach((name, i) => {\n const moduleName = `pkg${i}`;\n const version = readBundledPackageVersion(projectRoot, name);\n imports.push(`import * as ${moduleName} from ${JSON.stringify(name)};`);\n imports.push(`import ${JSON.stringify(`${name}/style.css`)};`);\n calls.push(\n ` pm.addLocalPackage(${JSON.stringify(name)}, ${moduleName}, ${JSON.stringify(version)});`,\n );\n });\n\n return `${imports.join(\"\\n\")}\\n\\nexport default function register(pm) {\\n${calls.join(\"\\n\")}\\n};\\n`;\n}\n\n/**\n * Emits a virtual module `ph-bundled-packages-virtual` whose default export\n * is a `register(packageManager)` function. When called at runtime (from\n * Connect's bootstrap), it registers each bundled package with the package\n * manager the same way Common/Vetra are registered — meaning they work\n * offline without the registry being reachable.\n *\n * When the list is empty, the module exports a no-op function so Connect's\n * bootstrap code can always import it unconditionally.\n */\nexport function phBundledPackagesPlugin(\n options: PhBundledPackagesPluginOptions,\n): Plugin {\n const projectRoot = options.projectRoot ?? process.cwd();\n const moduleSource = makeRegisterModule(options.packages, projectRoot);\n\n return {\n name: \"vite-plugin-ph-bundled-packages\",\n enforce: \"pre\",\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n load(id) {\n if (id === RESOLVED_VIRTUAL_ID) return moduleSource;\n },\n };\n}\n","import { createRequire } from \"node:module\";\nimport { createReadStream } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport {\n DEFAULT_VENDOR_INCLUDE,\n VENDOR_URL_PREFIX,\n prebuildConnectVendor,\n type PrebuiltVendor,\n} from \"../externalize-vendor.js\";\nimport { resolveConnectRoutesDir } from \"./connect-routes.js\";\nimport { BUNDLED_PACKAGES_DEV_URL } from \"./ph-bundled-packages.js\";\n\nconst REACT_DEPS = [\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n \"react-dom/client\",\n];\n\nconst SHIM_PATH = \"__ph/dev-react-shim/\";\nconst VITE_DEPS_PATH = \"node_modules/.vite/deps\";\n\n// Content-Type for the asset extensions the vendor build emits; JS is the default.\nconst VENDOR_MIME: Record<string, string> = {\n \".css\": \"text/css\",\n \".map\": \"application/json\",\n \".json\": \"application/json\",\n \".wasm\": \"application/wasm\",\n \".data\": \"application/octet-stream\",\n \".woff2\": \"font/woff2\",\n \".woff\": \"font/woff\",\n \".ttf\": \"font/ttf\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n};\n\n// Opt-in: also serve the heavy stable Connect libs from a prebuilt vendor\n// bundle, so the long-lived dev server never dep-optimizes them (~1–2 GB\n// resident). Set PH_CONNECT_EXTERNALIZE_VENDOR=1 to enable.\nconst VENDOR_MODE = process.env.PH_CONNECT_EXTERNALIZE_VENDOR === \"1\";\n// Extra specifiers to vendor on top of the defaults, comma-separated. Lets a\n// project add its own stable heavy deps without code changes.\nconst VENDOR_EXTRA = (process.env.PH_CONNECT_VENDOR_EXTRA ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\nconst HEAVY_LIBS = [...DEFAULT_VENDOR_INCLUDE, ...VENDOR_EXTRA];\n// A project with routes compiles Connect's route tree, so Connect is not vendored.\nconst heavyLibsFor = (routesDir: string | undefined) =>\n routesDir\n ? HEAVY_LIBS.filter((lib) => lib !== \"@powerhousedao/connect\")\n : HEAVY_LIBS;\n\n// Vite serves dev module URLs under the resolved `base`. Join base + path\n// while collapsing the double slash so `base: \"/\"` stays byte-identical.\nfunction withBase(base: string, p: string): string {\n return `${base}${p}`.replace(/\\/{2,}/g, \"/\");\n}\n\n// Keep the matched specifiers bare in dev (Vite otherwise rewrites externals to\n// \"/@id/<spec>\") so the import map resolves them; predicate matching supported.\ntype Externals = Array<string | ((id: string) => boolean)>;\nfunction externalizePlugin(externals: Externals): Plugin | undefined {\n try {\n const require = createRequire(import.meta.url);\n const mod = require(\"vite-plugin-externalize-dependencies\") as {\n default?: (o: { externals: Externals }) => Plugin;\n } & ((o: { externals: Externals }) => Plugin);\n const factory = mod.default ?? mod;\n return factory({ externals });\n } catch {\n return undefined;\n }\n}\n\n/**\n * Dev-only sibling of `esmExternalRequirePlugin`. The build path externalizes\n * React via Rolldown so an importmap hands the same React instance to both\n * Connect and CDN-served editor packages. Rolldown plugins don't run in\n * `vite createServer`, and Vite's pre-bundled CJS deps only expose a `default`\n * export — so a CDN editor that does `import { lazy } from \"react\"` would\n * fail with \"no named export 'lazy'\".\n *\n * This plugin owns the page import map. It always:\n * 1. Forces React into `optimizeDeps.include` so the optimizer always knows\n * about it.\n * 2. Serves a shim per React module at a stable URL. Each shim imports\n * from Vite's live pre-bundled URL (sharing Connect's React instance)\n * and re-exports React's named members so editors importing\n * `{ lazy }`, `{ jsx }`, etc. work.\n * 3. Rewrites the page importmap to point at those shim URLs.\n *\n * When PH_CONNECT_EXTERNALIZE_VENDOR=1 it additionally prebuilds the heavy\n * stable libs (design-system, reactor-browser, …) into a static vendor bundle,\n * externalizes them from the dev server, serves the bundle, and adds them to\n * the SAME import map. The vendor's React imports stay bare → resolve through\n * the React shims above → one React instance across Connect, the vendor, and\n * CDN editors.\n */\n// Async factory: in VENDOR_MODE it runs the vendor prebuild up front (Vite\n// awaits a Promise<PluginOption>), so `vendor` is known before any plugin hook\n// fires. The heavy libs are excluded from the optimizer — and the externalize\n// plugin is added — ONLY when a valid bundle will be served. On prebuild\n// failure they stay dev-optimized (no broken bare imports) and neither the\n// import map nor the externalizer touch them.\nexport async function devReactImportmapPlugin(\n projectRoot: string = process.cwd(),\n routesDir = resolveConnectRoutesDir(projectRoot),\n): Promise<Plugin | Plugin[]> {\n let namedExports = new Map<string, string[]>();\n let base = \"/\";\n let vendor: PrebuiltVendor | null = null;\n const heavyLibs = heavyLibsFor(routesDir);\n\n if (VENDOR_MODE) {\n const errorRef: { message?: string } = {};\n vendor = await prebuildConnectVendor({\n dirname: projectRoot,\n include: heavyLibs,\n errorRef,\n });\n if (!vendor) {\n const detail = errorRef.message ? `: ${errorRef.message}` : \"\";\n console.warn(\n `[connect] PH_CONNECT_EXTERNALIZE_VENDOR set but vendor prebuild failed; falling back to dep-optimizing the heavy libs${detail}`,\n );\n }\n }\n\n // Externalize exactly the specifiers in the vendor import map (not broad\n // prefixes) so an undiscovered subpath stays resolvable instead of 404ing.\n const ext = vendor\n ? externalizePlugin([(id) => id in vendor!.imports])\n : undefined;\n if (vendor && !ext) {\n console.warn(\n \"[connect] PH_CONNECT_EXTERNALIZE_VENDOR set and vendor prebuilt, but vite-plugin-externalize-dependencies is not installed; falling back to dep-optimizing the heavy libs (install it to enable the vendor)\",\n );\n }\n const vendorActive = !!(vendor && ext);\n\n const main: Plugin = {\n name: \"ph-dev-react-importmap\",\n apply: \"serve\",\n config(cfg) {\n cfg.optimizeDeps ??= {};\n const include = new Set(cfg.optimizeDeps.include ?? []);\n REACT_DEPS.forEach((d) => include.add(d));\n if (vendorActive) {\n // The heavy libs are served from the prebuilt vendor; force-including\n // them would pre-bundle them anyway (and leave their excluded deps —\n // e.g. zod subpaths — as unmapped bare imports). Drop them from include\n // and exclude them so the optimizer never touches them.\n heavyLibs.forEach((d) => include.delete(d));\n cfg.optimizeDeps.exclude = [\n ...new Set([...(cfg.optimizeDeps.exclude ?? []), ...heavyLibs]),\n ];\n }\n cfg.optimizeDeps.include = [...include];\n },\n configResolved(config) {\n base = config.base;\n },\n configureServer(server) {\n // Resolve React's named exports from the consumer project so we don't\n // hardcode lists that drift across React versions.\n const requireFromRoot = createRequire(\n path.join(server.config.root, \"package.json\"),\n );\n namedExports = new Map(\n REACT_DEPS.map((id) => {\n try {\n const mod = requireFromRoot(id) as Record<string, unknown>;\n return [id, Object.keys(mod).filter((k) => k !== \"default\")];\n } catch {\n return [id, []];\n }\n }),\n );\n\n // Serve the prebuilt vendor bundle. Match the base-prefixed URL (chunk/asset\n // URLs carry the deploy base) and the bare prefix; strip whichever matched.\n if (vendorActive) {\n const vendorDir = vendor!.vendorDir;\n const vendorPrefixes = [\n withBase(base, VENDOR_URL_PREFIX),\n VENDOR_URL_PREFIX,\n ];\n server.middlewares.use((req, res, next) => {\n const url = (req.url ?? \"\").split(\"?\")[0];\n const prefix = vendorPrefixes.find((p) => url.startsWith(p));\n if (!prefix) return next();\n const name = url.slice(prefix.length).replace(/^\\/+/, \"\");\n const file = path.join(vendorDir, name);\n // Path-segment containment (not a string prefix): reject anything that\n // escapes vendorDir, incl. siblings like `.ph-vendor.lock`.\n const rel = path.relative(vendorDir, file);\n if (!name || rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n return next();\n }\n // Stream (don't buffer multi-MB wasm/.data); a missing file → next().\n const stream = createReadStream(file);\n stream.on(\"error\", () => {\n if (!res.headersSent) next();\n });\n stream.once(\"open\", () => {\n const ext = file.slice(file.lastIndexOf(\".\"));\n res.setHeader(\n \"Content-Type\",\n VENDOR_MIME[ext] ?? \"text/javascript\",\n );\n // Content-hashed chunks/assets are immutable; entries + map can change.\n const hashed =\n name.startsWith(\"chunks/\") || name.startsWith(\"assets/\");\n res.setHeader(\n \"Cache-Control\",\n hashed ? \"public, max-age=31536000, immutable\" : \"no-cache\",\n );\n stream.pipe(res);\n });\n });\n }\n\n // Match the base-prefixed shim URL, and the bare path for robustness.\n const shimPrefixes = [withBase(base, SHIM_PATH), `/${SHIM_PATH}`];\n server.middlewares.use((req, res, next) => {\n const prefix = shimPrefixes.find((p) => req.url?.startsWith(p));\n if (!prefix) return next();\n const id = req.url!.slice(prefix.length).replace(/\\.js(\\?.*)?$/, \"\");\n if (!REACT_DEPS.includes(id)) return next();\n\n const optimizer = server.environments.client.depsOptimizer;\n const info =\n optimizer?.metadata.optimized[id] ??\n optimizer?.metadata.discovered[id];\n if (!optimizer || !info) {\n res.statusCode = 404;\n res.end();\n return;\n }\n\n const browserHash = info.browserHash ?? optimizer.metadata.browserHash;\n const depUrl = `${withBase(base, VITE_DEPS_PATH)}/${path.basename(info.file)}?v=${browserHash}`;\n const names = namedExports.get(id) ?? [];\n\n res.setHeader(\"Content-Type\", \"application/javascript\");\n res.end(\n `import * as M from ${JSON.stringify(depUrl)};\\n` +\n `const ns = M.default ?? M;\\n` +\n `export default ns;\\n` +\n (names.length\n ? `export const { ${names.join(\", \")} } = ns;\\n`\n : \"\"),\n );\n });\n },\n transformIndexHtml: {\n order: \"post\",\n handler(html, ctx) {\n const browserHash =\n ctx.server?.environments.client.depsOptimizer?.metadata.browserHash;\n if (!browserHash) return;\n const shimPrefix = withBase(base, SHIM_PATH);\n const imports: Record<string, string> = Object.fromEntries(\n REACT_DEPS.map((id) => [\n id,\n `${shimPrefix}${id}.js?v=${browserHash}`,\n ]),\n );\n // Heavy libs resolve to the prebuilt vendor (base-prefixed); their bare\n // React imports fall through to the React shim entries above.\n let dynamicBaseScript = \"\";\n if (vendorActive) {\n for (const [spec, url] of Object.entries(vendor!.imports)) {\n imports[spec] = withBase(base, url);\n }\n // Connect vendored isn't dev-processed, so its dynamic\n // `import(\"ph-bundled-packages-virtual\")` points at the virtual URL.\n if (vendor!.imports[\"@powerhousedao/connect\"]) {\n imports[\"ph-bundled-packages-virtual\"] = withBase(\n base,\n BUNDLED_PACKAGES_DEV_URL,\n );\n }\n // Set the runtime base global so the vendor's rewritten URL exprs\n // resolve to the dev/deploy base (mirrors the proxy at serve time).\n dynamicBaseScript = `<script>globalThis.__PH_DYNAMIC_BASE__=${JSON.stringify(base)};</script>\\n`;\n }\n return html.replace(\n /<script type=\"importmap\">[\\s\\S]*?<\\/script>/,\n `${dynamicBaseScript}<script type=\"importmap\">${JSON.stringify({ imports }, null, 2)}</script>`,\n );\n },\n },\n };\n\n // The externalizer runs alongside `main` so Connect's source leaves the heavy\n // libs bare (→ import map → vendor); React stays optimized via the shims.\n return vendorActive ? [ext!, main] : main;\n}\n","import { readFileSync } from \"node:fs\";\nimport { extname, isAbsolute, resolve } from \"node:path\";\nimport type { Connect, Plugin } from \"vite\";\n\nconst CONTENT_TYPE_BY_EXT: Record<string, string> = {\n \".ico\": \"image/x-icon\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n};\n\n/**\n * Vite plugin to serve the Connect favicon (icon.ico) from the connect package,\n * or from a caller-supplied file when `faviconPath` is set (e.g. `ph connect\n * build --favicon`). The served/emitted name is always `icon.ico` so the static\n * `<link rel=\"icon\" href=\"%BASE_URL%icon.ico\">` in index.html stays valid.\n */\nexport function connectFaviconPlugin(\n opts: { faviconPath?: string } = {},\n): Plugin {\n // Build input, not runtime config: a non-absolute path resolves against the\n // build cwd (= the project dir during `ph connect build`).\n const customPath = opts.faviconPath\n ? isAbsolute(opts.faviconPath)\n ? opts.faviconPath\n : resolve(process.cwd(), opts.faviconPath)\n : undefined;\n const customContentType = customPath\n ? (CONTENT_TYPE_BY_EXT[extname(customPath).toLowerCase()] ?? \"image/x-icon\")\n : \"image/x-icon\";\n\n return {\n name: \"copy-connect-favicon\",\n configureServer(server) {\n // Vite rewrites the favicon link against `base`, so serve the\n // base-prefixed path. Keep the bare path for robustness.\n const base = server.config.base;\n const faviconRoute = `${base}icon.ico`.replace(/\\/{2,}/g, \"/\");\n const handler: Connect.NextHandleFunction = (_req, res, next) => {\n if (customPath) {\n try {\n res.setHeader(\"Content-Type\", customContentType);\n res.end(readFileSync(customPath));\n } catch {\n next();\n }\n return;\n }\n server.pluginContainer\n .resolveId(\"@powerhousedao/connect/assets/icon.ico\")\n .then((resolved) => {\n if (!resolved) return next();\n res.setHeader(\"Content-Type\", \"image/x-icon\");\n res.end(readFileSync(resolved.id));\n })\n .catch(() => next());\n };\n // Mount on the exact route(s) so the handler only runs for icon.ico.\n // Connect strips the mount prefix before matching, so mounting on\n // \"/icon.ico\" matches that path exactly.\n const paths = new Set([faviconRoute, \"/icon.ico\"]);\n for (const path of paths) {\n server.middlewares.use(path, handler);\n }\n },\n async generateBundle(_options, bundle) {\n try {\n if (\"icon.ico\" in bundle) return;\n let source: Uint8Array | undefined;\n if (customPath) {\n source = readFileSync(customPath);\n } else {\n const resolved = await this.resolve(\n \"@powerhousedao/connect/assets/icon.ico\",\n );\n if (resolved) source = readFileSync(resolved.id);\n }\n if (!source) return;\n this.emitFile({\n type: \"asset\",\n fileName: \"icon.ico\",\n source,\n });\n } catch {\n // favicon source not found, skip\n }\n },\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport type { PowerhousePackage } from \"@powerhousedao/config\";\nimport type {\n PHConnectRuntimeConfig,\n PowerhouseConfig,\n} from \"@powerhousedao/shared/clis\";\nimport {\n buildRuntimeConfig,\n deepMerge,\n resolveSourceConnect,\n workflowsSettingConflict,\n} from \"@powerhousedao/shared/connect\";\nimport { RUNTIME_CONFIG_SCHEMA_URL } from \"../runtime-config-schema.js\";\n\nexport type PhConfigPluginOptions = {\n packages: PowerhousePackage[];\n projectRoot?: string;\n connect?: PHConnectRuntimeConfig;\n /** The source's top-level `workflows` block; `connect.app.workflowsEnabled` falls back to it. */\n workflows?: PowerhouseConfig[\"workflows\"];\n /**\n * Project-wide package registry URL — the effective value (CLI override\n * `??` source) the caller has already resolved. Copied verbatim into the\n * emitted runtime config (no namespace change); the SPA reads\n * `runtimeConfig.packageRegistryUrl` directly.\n */\n packageRegistryUrl?: string;\n /**\n * CLI-supplied connect override (final merge layer, beats source).\n * Forwarded from `ph connect build`'s `--json` + individual `--flag` parsing.\n * See clis/ph-cli/src/utils/cli-connect-override.ts.\n */\n cliConnectOverride?: PHConnectRuntimeConfig;\n};\n\nfunction readProjectPackageInfo(\n projectRoot: string | undefined,\n): { name: string; version: string } | null {\n if (!projectRoot) return null;\n try {\n const raw = fs.readFileSync(\n path.join(projectRoot, \"package.json\"),\n \"utf-8\",\n );\n const pkg = JSON.parse(raw) as { name?: unknown; version?: unknown };\n if (typeof pkg.name !== \"string\" || typeof pkg.version !== \"string\") {\n return null;\n }\n return { name: pkg.name, version: pkg.version };\n } catch {\n return null;\n }\n}\n\n/** `html` with its `<title>` text set to `appName`, when one is configured. */\nexport function withAppTitle(html: string, appName: string | undefined) {\n if (!appName) return html;\n const escaped = appName\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\");\n return html.replace(\n /<title>[^<]*<\\/title>/,\n () => `<title>${escaped}</title>`,\n );\n}\n\nexport function phConfigPlugin(options: PhConfigPluginOptions): Plugin {\n const projectRoot = options.projectRoot ?? process.cwd();\n const localPackage = readProjectPackageInfo(projectRoot);\n\n // Precedence ladder (lowest → highest) for the emitted connect.* block:\n // DEFAULT_CONNECT_CONFIG (base — fills in any field nothing else supplied)\n // < source.workflows (project-wide `workflows.enabled`)\n // < source.connect (user's hand-edited powerhouse.config.json)\n // < cliConnectOverride (`ph connect build --json` + individual flags)\n //\n // Env vars are NOT a layer in this ladder. The Connect SPA's runtime\n // configuration is exclusively set via `powerhouse.config.json` or CLI\n // overrides (`ph connect build --<field>` / `ph connect config --<field>`).\n const sourceSettings = {\n connect: options.connect,\n workflows: options.workflows,\n };\n const conflict = workflowsSettingConflict(sourceSettings);\n if (conflict) console.warn(`[powerhouse] ${conflict}`);\n const withDefaults = resolveSourceConnect(sourceSettings);\n const mergedConnect = options.cliConnectOverride\n ? deepMerge(withDefaults, options.cliConnectOverride)\n : withDefaults;\n const source = {\n packages: options.packages,\n packageRegistryUrl: options.packageRegistryUrl,\n connect: mergedConnect,\n };\n\n const runtimeConfig = buildRuntimeConfig(source, localPackage);\n const content = JSON.stringify(\n { $schema: RUNTIME_CONFIG_SCHEMA_URL, ...runtimeConfig },\n null,\n 2,\n );\n\n return {\n name: \"vite-plugin-ph-config\",\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n if (req.url?.endsWith(\"/powerhouse.config.json\")) {\n res.setHeader(\"Content-Type\", \"application/json\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(content);\n return;\n }\n next();\n });\n },\n hotUpdate: {\n order: \"pre\",\n handler(ctx) {\n return ctx.modules.filter((mod) => {\n if (mod.importers.size > 1) {\n return true;\n }\n const importer = mod.importers.values().next();\n return !importer.value?.file?.endsWith(\".css\");\n });\n },\n },\n // The tab shows the app's name before the app sets each page's title.\n transformIndexHtml(html) {\n return withAppTitle(html, runtimeConfig.connect.branding?.appName);\n },\n generateBundle() {\n this.emitFile({\n type: \"asset\",\n fileName: \"powerhouse.config.json\",\n source: content,\n });\n },\n };\n}\n","import type { PowerhousePackage } from \"@powerhousedao/config\";\nimport type {\n PHConnectPwa,\n PwaContribution,\n} from \"@powerhousedao/shared/connect\";\nimport { withInferredCategory } from \"@powerhousedao/shared/connect\";\nimport { PwaConfigSchema } from \"@powerhousedao/shared/document-model\";\nimport { toCdnUrl } from \"@powerhousedao/shared/registry/urls\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { ZodError } from \"zod\";\n\n// Collects the serialisable `pwa` fragments that build-time-known packages ship\n// in their `powerhouse.manifest.json`, from three sources:\n// - the project's own manifest (`collectProjectPwaContribution`);\n// - `provider: \"local\"` packages, read from node_modules (a package's\n// manifest is emitted to `dist/powerhouse.manifest.json` and exposed via\n// its `./manifest` export, so the Connect build can read it as JSON — no\n// need to execute package code, whose main entry pulls browser-only\n// modules that would crash in Node);\n// - `provider: \"registry\"` packages, fetched from the registry CDN (they are\n// not installed in node_modules; production Connect loads them from the\n// CDN at runtime, so the CDN copy is the build-time source of truth).\n// Fragments are validated with `PwaConfigSchema`; anything unreadable,\n// unreachable or malformed is warned about and skipped, never fatal to the\n// build. Only the project's `connect.pwa` block is strict — see\n// `validateProjectPwaConfig`.\n\nconst REGISTRY_FETCH_TIMEOUT_MS = 10_000;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction formatZodIssues(error: ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \");\n}\n\n/** Turn a parsed manifest JSON into a contribution: its `pwa` fragment (a\n * malformed one → warn + skip that fragment, not the whole contribution) plus a\n * `categories` entry derived from the manifest's `category` field. Returns null\n * only when the manifest yields neither — no `pwa` and no `category`. */\nfunction toPwaContribution(\n manifest: unknown,\n fallbackLabel: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n if (!isPlainObject(manifest)) return null;\n const label =\n typeof manifest.name === \"string\" && manifest.name\n ? manifest.name\n : fallbackLabel;\n\n let config: PHConnectPwa = {};\n if (manifest.pwa !== undefined) {\n if (!isPlainObject(manifest.pwa)) {\n onWarn(\n `PWA config: ${label} declares a non-object 'pwa' field in its manifest; ignored.`,\n );\n } else {\n const parsed = PwaConfigSchema.safeParse(manifest.pwa);\n if (!parsed.success) {\n onWarn(\n `PWA config: ${label}'s pwa fragment is invalid; ignored. ${formatZodIssues(parsed.error)}`,\n );\n } else {\n config = parsed.data;\n }\n }\n }\n\n config = withInferredCategory(config, manifest.category);\n if (Object.keys(config).length === 0) return null;\n return { source: label, config };\n}\n\n/** Read the first parseable manifest among `candidates` (relative to `dir`)\n * and extract its pwa contribution. Candidates that resolve outside `dir`\n * (a hostile `./manifest` export) are warned about and skipped. */\nfunction readPwaFragmentFromDir(\n dir: string,\n candidates: string[],\n fallbackLabel: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n for (const rel of candidates) {\n const manifestPath = path.resolve(dir, rel);\n if (path.relative(dir, manifestPath).startsWith(\"..\")) {\n onWarn(\n `PWA config: ${fallbackLabel} declares a manifest path outside its package directory (${rel}); ignored.`,\n );\n continue;\n }\n if (!fs.existsSync(manifestPath)) continue;\n try {\n const manifest: unknown = JSON.parse(\n fs.readFileSync(manifestPath, \"utf-8\"),\n );\n return toPwaContribution(manifest, fallbackLabel, onWarn);\n } catch {\n onWarn(\n `PWA config: could not parse ${fallbackLabel}'s manifest at ${rel}; ignored.`,\n );\n return null;\n }\n }\n return null;\n}\n\nfunction readLocalPackagePwaFragment(\n projectRoot: string,\n name: string,\n onWarn: (message: string) => void,\n): PwaContribution | null {\n const pkgDir = path.join(projectRoot, \"node_modules\", name);\n let manifestRel: string | undefined;\n try {\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(pkgDir, \"package.json\"), \"utf-8\"),\n ) as { exports?: Record<string, unknown> };\n const exported = pkgJson.exports?.[\"./manifest\"];\n if (typeof exported === \"string\") manifestRel = exported;\n } catch {\n // No package.json / unreadable — fall back to the conventional paths.\n }\n\n // The package's declared `./manifest` export first, then the conventional\n // build output and source locations.\n const candidates = [\n manifestRel,\n \"dist/powerhouse.manifest.json\",\n \"powerhouse.manifest.json\",\n ].filter((rel): rel is string => typeof rel === \"string\");\n\n return readPwaFragmentFromDir(pkgDir, candidates, name, onWarn);\n}\n\nasync function fetchRegistryPwaFragment(\n cdnUrl: string,\n pkg: PowerhousePackage,\n onWarn: (message: string) => void,\n fetchImpl: typeof fetch,\n): Promise<PwaContribution | null> {\n // Same version-pinned spec production Connect uses to load the package, so\n // the fragment matches the code that will actually run.\n const spec = pkg.version\n ? `${pkg.packageName}@${pkg.version}`\n : pkg.packageName;\n const url = `${cdnUrl}/${spec}/powerhouse.manifest.json`;\n try {\n const response = await fetchImpl(url, {\n signal: AbortSignal.timeout(REGISTRY_FETCH_TIMEOUT_MS),\n });\n // 404 = the package ships no manifest on the CDN — silent, like a local\n // package without a manifest file.\n if (response.status === 404) return null;\n if (!response.ok) {\n onWarn(\n `PWA config: registry returned ${response.status} for ${spec}'s manifest; its pwa fragment (if any) is skipped.`,\n );\n return null;\n }\n const manifest: unknown = await response.json();\n return toPwaContribution(manifest, pkg.packageName, onWarn);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n onWarn(\n `PWA config: could not fetch ${spec}'s manifest from the registry (${message}); its pwa fragment (if any) is skipped.`,\n );\n return null;\n }\n}\n\n/**\n * Read the `pwa` fragment of each package in `packages`, in the given order\n * (which becomes their merge precedence — later packages win scalar\n * conflicts). `provider: \"local\"` packages are read from node_modules;\n * everything else is fetched from the registry CDN (skipped with a warning\n * when `registryUrl` is missing or the registry is unreachable). Packages\n * with no `pwa` fragment are simply absent from the result.\n */\nexport async function collectPackagePwaContributions(options: {\n packages: PowerhousePackage[];\n projectRoot?: string;\n registryUrl?: string | null;\n onWarn?: (message: string) => void;\n /** Injectable for tests. */\n fetchImpl?: typeof fetch;\n}): Promise<PwaContribution[]> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const onWarn = options.onWarn ?? (() => {});\n const fetchImpl = options.fetchImpl ?? fetch;\n const cdnUrl = options.registryUrl ? toCdnUrl(options.registryUrl) : null;\n\n const results = await Promise.all(\n options.packages.map(async (pkg) => {\n if (pkg.provider === \"local\") {\n return readLocalPackagePwaFragment(\n projectRoot,\n pkg.packageName,\n onWarn,\n );\n }\n if (!cdnUrl) {\n onWarn(\n `PWA config: no packageRegistryUrl configured; cannot read ${pkg.packageName}'s pwa fragment (if any) from the registry.`,\n );\n return null;\n }\n return fetchRegistryPwaFragment(cdnUrl, pkg, onWarn, fetchImpl);\n }),\n );\n return results.filter(\n (contribution): contribution is PwaContribution => contribution !== null,\n );\n}\n\n/**\n * Read the pwa fragment from the project's OWN manifest\n * (`powerhouse.manifest.json` under the project root, falling back to the\n * `dist/` copy the project build emits). The root file comes first — it is\n * the source the dist copy is made from, and a stale dist left by an older\n * build must not shadow it. Returns null silently when no manifest exists —\n * not every project ships one — or when it carries neither a `pwa` block nor a\n * `category` to derive `categories` from.\n *\n * The `pwa` block is parsed STRICTLY, like `connect.pwa` and unlike third-party\n * package fragments: the project's own manifest is the developer's config, so\n * an invalid `pwa` block (a typo, or a removed/unknown field such as\n * `protocol_handlers`) FAILS the build instead of being silently skipped — a\n * silently-dropped field would be far harder to notice.\n */\nexport function collectProjectPwaContribution(options: {\n projectRoot?: string;\n}): PwaContribution | null {\n const projectRoot = options.projectRoot ?? process.cwd();\n for (const rel of [\n \"powerhouse.manifest.json\",\n \"dist/powerhouse.manifest.json\",\n ]) {\n const manifestPath = path.resolve(projectRoot, rel);\n if (!fs.existsSync(manifestPath)) continue;\n let manifest: unknown;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Could not parse ${manifestPath}: ${message}`);\n }\n if (!isPlainObject(manifest)) return null;\n const label =\n typeof manifest.name === \"string\" && manifest.name\n ? manifest.name\n : \"project manifest\";\n const config =\n manifest.pwa === undefined\n ? {}\n : parsePwaConfigStrict(manifest.pwa, `pwa in ${manifestPath}`);\n const withCategory = withInferredCategory(config, manifest.category);\n if (Object.keys(withCategory).length === 0) return null;\n return { source: label, config: withCategory };\n }\n return null;\n}\n\n/** Strictly parse a PWA config block, throwing a build-failing error (naming\n * the offending field) when it is invalid. Used for the developer's own config\n * (`connect.pwa` and the project manifest's `pwa`), where a silent drop would\n * be a footgun — unlike third-party package fragments, which warn + skip. */\nfunction parsePwaConfigStrict(\n config: unknown,\n description: string,\n): PHConnectPwa {\n const parsed = PwaConfigSchema.safeParse(config);\n if (!parsed.success) {\n throw new Error(\n `Invalid ${description}: ${formatZodIssues(parsed.error)}. Fix it or remove the field.`,\n );\n }\n return parsed.data;\n}\n\n/**\n * Validate the project's `connect.pwa` block. Unlike package fragments\n * (third-party, warn + skip), the user's own config fails the build: a typo\n * that silently dropped offline coverage would be far harder to notice.\n */\nexport function validateProjectPwaConfig(\n config: unknown,\n configPath: string,\n): PHConnectPwa {\n return parsePwaConfigStrict(config, `connect.pwa in ${configPath}`);\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Plugin } from \"vite\";\n\n// PWA manifest icons emitted into the build from the @powerhousedao/connect\n// package assets. The `ph connect build` Vite root is a scaffolded project that\n// has no PWA icons of its own, so — like connectFaviconPlugin does for the\n// favicon — we resolve them out of the installed connect package and emit them\n// as build assets. vite-plugin-pwa references these filenames in the generated\n// manifest and precaches them via its png glob. The document icons are the\n// OS-level file-type icons referenced by the .phd/.phdm file_handlers.\nconst PWA_ICONS = [\n \"pwa-192x192.png\",\n \"pwa-512x512.png\",\n \"pwa-512x512-maskable.png\",\n \"document-icon-192x192.png\",\n \"document-icon-512x512.png\",\n] as const;\n\nexport function connectPwaIconsPlugin(): Plugin {\n return {\n name: \"copy-connect-pwa-icons\",\n async generateBundle(_options, bundle) {\n for (const icon of PWA_ICONS) {\n try {\n if (icon in bundle) continue;\n const resolved = await this.resolve(\n `@powerhousedao/connect/assets/${icon}`,\n );\n if (!resolved) continue;\n this.emitFile({\n type: \"asset\",\n fileName: icon,\n source: readFileSync(resolved.id),\n });\n } catch {\n // connect package or icon not found — skip; the manifest still\n // generates, the icon URL just 404s (non-fatal for offline caching).\n }\n }\n },\n };\n}\n","import {\n mergeManifest,\n PWA_FILE_HANDLER_ACTION,\n unionStrings,\n type PHConnectPwa,\n type PwaWebManifest,\n} from \"@powerhousedao/shared/connect\";\nimport type { ManifestOptions } from \"vite-plugin-pwa\";\n\n// Applies the effective (already merged, see mergePwaConfig) serialisable PWA\n// fragment onto Connect's hardcoded base. The manifest merge is delegated to\n// the browser-safe `mergeManifest` in @powerhousedao/shared/connect so the\n// exact same code shapes the manifest here (build time) and inside the service\n// worker (runtime, for dynamically-installed packages). This module only adds\n// the vite-plugin-pwa manifest TYPES and the precache-glob merge; the Workbox\n// runtime-caching / navigation behaviour now lives in the hand-written service\n// worker (see connect-utils/service-worker/service-worker.ts), because\n// `injectManifest` has no declarative runtimeCaching option.\n\n// Re-exported so existing importers (pwa.ts, the e2e test) keep a stable name\n// while the constant's source of truth moves to @powerhousedao/shared/connect.\nexport { PWA_FILE_HANDLER_ACTION as FILE_HANDLER_ACTION };\n\n/** A manifest file-handler entry. vite-plugin-pwa's own type stops at\n * `{ action; accept }`; the spec'd `icons`/`launch_type` members are added\n * here — the manifest is emitted as verbatim JSON, so they ship through. */\nexport type ConnectPwaFileHandler = NonNullable<\n ManifestOptions[\"file_handlers\"]\n>[number] & {\n icons?: ManifestOptions[\"icons\"];\n launch_type?: \"single-client\" | \"multiple-clients\";\n};\n\n/** The web-app manifest exactly as VitePWA accepts it, with the file-handler\n * entries widened to their full spec'd shape. */\nexport type ConnectPwaManifest = Omit<\n Partial<ManifestOptions>,\n \"file_handlers\"\n> & {\n file_handlers?: ConnectPwaFileHandler[];\n};\n\n/** The precache-driving subset of the old Workbox config. Under injectManifest\n * these are the `injectManifest` options; `self.__WB_MANIFEST` is generated\n * from them. Everything else (runtimeCaching, navigation, clientsClaim, …) is\n * imperative code in the service worker. */\nexport type ConnectPrecacheOptions = {\n globPatterns: string[];\n globIgnores: string[];\n maximumFileSizeToCacheInBytes: number;\n};\n\n/**\n * Lay an effective PWA fragment over the plugin's hardcoded manifest + precache\n * base. The manifest is merged by the shared `mergeManifest` with\n * `fragment-wins` scalars (the build-time effective config is the authority);\n * icons and file handlers concatenate after the base set (contributed handlers\n * get Connect's fixed action injected — the open route is not configurable);\n * globs union; the size ceiling takes the max.\n *\n * The serialisable `runtimeCaching` / `navigateFallbackDenylist` overrides are\n * NOT handled here — they are passed straight to the service worker (which\n * registers them after its built-in rules), because injectManifest has no\n * declarative runtimeCaching and Workbox is first-match-wins, so an override\n * can only be appended after the built-ins (intentional for v1).\n */\nexport function applyPwaOverrides(\n base: { manifest: ConnectPwaManifest; precache: ConnectPrecacheOptions },\n override: PHConnectPwa,\n): { manifest: ConnectPwaManifest; precache: ConnectPrecacheOptions } {\n const manifest = mergeManifest(\n base.manifest as PwaWebManifest,\n override.manifest,\n { scalarPolicy: \"fragment-wins\" },\n ) as ConnectPwaManifest;\n\n const precache: ConnectPrecacheOptions = {\n globPatterns: override.globPatterns?.length\n ? unionStrings(base.precache.globPatterns, override.globPatterns)\n : base.precache.globPatterns,\n globIgnores: override.globIgnores?.length\n ? unionStrings(base.precache.globIgnores, override.globIgnores)\n : base.precache.globIgnores,\n maximumFileSizeToCacheInBytes:\n typeof override.maximumFileSizeToCacheInBytes === \"number\"\n ? Math.max(\n base.precache.maximumFileSizeToCacheInBytes,\n override.maximumFileSizeToCacheInBytes,\n )\n : base.precache.maximumFileSizeToCacheInBytes,\n };\n\n return { manifest, precache };\n}\n","import { type PHConnectPwa } from \"@powerhousedao/shared/connect\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Plugin, PluginOption } from \"vite\";\nimport { VitePWA } from \"vite-plugin-pwa\";\nimport { connectPwaIconsPlugin } from \"./pwa-icons.js\";\nimport {\n applyPwaOverrides,\n FILE_HANDLER_ACTION,\n type ConnectPrecacheOptions,\n type ConnectPwaManifest,\n} from \"./pwa-overrides.js\";\n\n/**\n * Connect's hardcoded PWA manifest. The base layer of the override ladder —\n * package `pwa` fragments and the project's `connect.pwa` block are laid on\n * top of this by `applyPwaOverrides`.\n */\nconst BASE_MANIFEST: ConnectPwaManifest = {\n name: \"Powerhouse Connect\",\n short_name: \"Connect\",\n description:\n \"A navigation, collaboration and reporting tool for decentralised and open organisations.\",\n theme_color: \"#ffffff\",\n background_color: \"#ffffff\",\n display: \"standalone\",\n start_url: \".\",\n scope: \".\",\n icons: [\n { src: \"pwa-192x192.png\", sizes: \"192x192\", type: \"image/png\" },\n { src: \"pwa-512x512.png\", sizes: \"512x512\", type: \"image/png\" },\n {\n // Full-bleed variant: maskable icons get cropped to the platform shape,\n // so the logo sits inside the safe zone instead of reusing the rounded\n // \"any\" icon (whose transparent corners would show through the mask).\n src: \"pwa-512x512-maskable.png\",\n sizes: \"512x512\",\n type: \"image/png\",\n purpose: \"maskable\",\n },\n ],\n // OS-level file associations for the installed PWA (File Handling API,\n // Chromium desktop). Powerhouse documents are zip archives, but keying on\n // application/zip would make Connect a candidate handler for EVERY zip on\n // MIME-keyed platforms — hence the vendor types with the RFC 6839 +zip\n // suffix. Config-contributed handlers are appended after this entry, and\n // Chromium is first-registered-wins per extension, so .phd/.phdm cannot be\n // hijacked by a package. Consuming the launched files happens in the\n // Connect SPA (launchQueue consumer).\n file_handlers: [\n {\n action: FILE_HANDLER_ACTION,\n accept: {\n \"application/vnd.powerhouse.document+zip\": [\".phd\"],\n \"application/vnd.powerhouse.document-model+zip\": [\".phdm\"],\n },\n // OS file-type icons: the same Powerhouse document icon the in-app\n // import list shows. Declared per spec, but note Chromium doesn't\n // consume them on desktop yet — macOS synthesizes document icons from\n // the app icon (no CFBundleTypeIconFile is written), and Windows\n // support is unimplemented (FileHandlingIconsSupportedByOs() is false,\n // crbug.com/40185571). Shipping them is forward-compatible and costs\n // nothing. Assets emitted by connectPwaIconsPlugin, precached via the\n // png glob.\n icons: [\n {\n src: \"document-icon-192x192.png\",\n sizes: \"192x192\",\n type: \"image/png\",\n },\n {\n src: \"document-icon-512x512.png\",\n sizes: \"512x512\",\n type: \"image/png\",\n },\n ],\n },\n ],\n // Opening a handled file focuses the running Connect window (launchQueue\n // delivers the file there) instead of spawning a new window per file.\n launch_handler: { client_mode: \"focus-existing\" },\n};\n\n/**\n * Connect's hardcoded precache config — the base layer for the `injectManifest`\n * precache. Overridable additively (extra globs) or by raising the size ceiling\n * via package/project `pwa` config. The rest of the old Workbox config\n * (runtime-caching rules with their function urlPatterns, the navigation\n * fallback, clientsClaim/skipWaiting/cleanupOutdatedCaches) now lives as\n * imperative code in the hand-written service worker\n * (../service-worker/service-worker.ts), because `injectManifest` has no\n * declarative runtimeCaching option.\n */\nexport const BASE_PRECACHE: ConnectPrecacheOptions = {\n // PGlite's wasm + fs bundles are several MB each; Workbox's 2 MiB\n // default would silently skip them and the in-browser Postgres would\n // fail to initialise offline. Raise the ceiling so they precache.\n maximumFileSizeToCacheInBytes: 16 * 1024 * 1024,\n // Precache the app shell AND the PGlite assets. The default glob omits\n // `.wasm`/`.data`, but PGlite's Postgres-in-wasm needs both its `.wasm`\n // and its `.data` filesystem bundles, or the in-browser DB fails to\n // initialise offline (\"Failed to fetch\").\n // The reactor worker's metadata and package manifest are fetched at boot;\n // without them an offline boot cannot find the worker bundle.\n globPatterns: [\n \"**/*.{js,css,html,wasm,data,ico,png,svg,webp,woff,woff2}\",\n \"__reactor_worker__/**/*.json\",\n ],\n // index.html stays OUT of the precache on purpose: the SPA navigation\n // route serves it NetworkFirst (see service-worker.ts). The precache\n // strategy is cache-first with no network revalidation, so a precached\n // shell would pin every page load — reloads included — to the build that\n // was active when the controlling worker installed. Excluding the shell\n // lets a reload after a deploy (or a different project on the same\n // localhost port) fetch the fresh index.html from the network.\n // powerhouse.config.json is operator-editable and served no-cache, so\n // precaching it would freeze runtime config; source maps don't belong\n // in the precache either. manifest.webmanifest is added at wiring time so\n // the SW's dynamic manifest route is the sole producer at that URL.\n globIgnores: [\"**/powerhouse.config.json\", \"**/*.map\", \"index.html\"],\n};\n\nconst SW_FILENAME = \"service-worker.ts\";\n\n/**\n * Absolute directory holding the hand-written service-worker source. Resolved\n * relative to THIS module so it works from source\n * (connect-utils/vite-plugins → ../service-worker) and from the bundled dist\n * (dist/index.mjs → ./service-worker, where tsdown copies it). vite-plugin-pwa\n * resolves `swSrc = path.resolve(root, srcDir, filename)`, and `path.resolve`\n * ignores `root` when `srcDir` is absolute — so the SW ships with\n * builder-tools instead of every project needing its own copy.\n */\nfunction resolveServiceWorkerDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(here, \"../service-worker\"), // source layout\n resolve(here, \"service-worker\"), // bundled dist layout\n ];\n return (\n candidates.find((dir) => existsSync(join(dir, SW_FILENAME))) ??\n candidates[0]\n );\n}\n\n/**\n * Virtual module that feeds the hand-written SW its build-time data. Passed\n * into vite-plugin-pwa's SEPARATE injectManifest build via\n * `injectManifest.buildPlugins.vite`: that build runs with `configFile: false`,\n * so the app's own plugins aren't present, but buildPlugins (and `define`) are.\n */\nfunction phSwConfigPlugin(data: Record<string, unknown>): Plugin {\n const virtualId = \"virtual:ph-sw-config\";\n const resolvedId = `\\0${virtualId}`;\n return {\n name: \"ph-sw-config\",\n resolveId(id) {\n if (id === virtualId) return resolvedId;\n },\n load(id) {\n if (id !== resolvedId) return;\n return Object.entries(data)\n .map(\n ([key, value]) => `export const ${key} = ${JSON.stringify(value)};`,\n )\n .join(\"\\n\");\n },\n };\n}\n\n/**\n * Service-worker / PWA support for Connect, gated by `connect.app.offline`.\n *\n * When enabled (the default), Workbox `injectManifest` bundles Connect's\n * hand-written service worker (../service-worker/service-worker.ts), which\n * precaches the built app shell so Connect loads with no network, runtime-\n * caches the Google-hosted Inter font + the registry CDN + the runtime config,\n * AND serves a dynamic web-app manifest so packages installed AT RUNTIME can\n * extend it (their fragments are mirrored into IndexedDB by the SPA; the base\n * the SW merges onto is embedded here at build time). The manifest and precache\n * config start from the BASE_* defaults above and are extended by `pwa` — the\n * effective, already-merged overrides from build-time packages and the\n * project's `connect.pwa` block (see mergePwaConfig). Registration is left to\n * the Connect SPA (`serviceWorkerManager`, `injectRegister: null`).\n *\n * When disabled, a self-destroying worker is emitted at the same URL so any\n * worker a previous offline-enabled build installed unregisters itself and\n * clears its caches on the browser's next service-worker update check.\n */\nexport function connectPwaPlugins(options: {\n offlineEnabled: boolean;\n /** Effective PWA overrides (packages + project), already merged. */\n pwa?: PHConnectPwa;\n}): PluginOption[] {\n const { offlineEnabled, pwa } = options;\n\n if (!offlineEnabled) {\n return [\n VitePWA({\n selfDestroying: true,\n strategies: \"generateSW\",\n injectRegister: null,\n filename: \"service-worker.js\",\n devOptions: { enabled: false },\n }),\n ];\n }\n\n const { manifest, precache } = applyPwaOverrides(\n { manifest: BASE_MANIFEST, precache: BASE_PRECACHE },\n pwa ?? {},\n );\n\n // Build-time data handed to the SW via the virtual module. EMBEDDED_BASE_\n // MANIFEST is the base the runtime manifest route merges dynamically-\n // installed package fragments onto; the two EXTRA_* arrays are the\n // serialisable build-time contributions the SW registers after its built-ins.\n const swConfig = {\n EMBEDDED_BASE_MANIFEST: manifest,\n EXTRA_RUNTIME_CACHING: pwa?.runtimeCaching ?? [],\n NAVIGATE_FALLBACK_DENYLIST_EXTRA: pwa?.navigateFallbackDenylist ?? [],\n };\n\n return [\n connectPwaIconsPlugin(),\n VitePWA({\n strategies: \"injectManifest\",\n // Absolute srcDir → swSrc is builder-tools' own SW source; the emitted\n // file is service-worker.js (vite-plugin-pwa maps the .ts source).\n srcDir: resolveServiceWorkerDir(),\n filename: SW_FILENAME,\n // prompt → the new worker waits; the SPA surfaces a refresh prompt and\n // posts SKIP_WAITING when the user accepts (see serviceWorkerManager).\n registerType: \"prompt\",\n injectRegister: null,\n // ph connect studio keeps running without a service worker.\n devOptions: { enabled: false },\n // Icons are emitted by connectPwaIconsPlugin and precached via the png\n // glob, so the plugin must not also try to resolve them from /public.\n includeManifestIcons: false,\n // Still emitted as the static base/offline fallback + the <link>.\n manifest,\n injectManifest: {\n globPatterns: precache.globPatterns,\n // Exclude the webmanifest from precache so the SW's dynamic route is\n // the sole producer at that URL.\n globIgnores: [...precache.globIgnores, \"**/manifest.webmanifest\"],\n maximumFileSizeToCacheInBytes: precache.maximumFileSizeToCacheInBytes,\n buildPlugins: { vite: [phSwConfigPlugin(swConfig)] },\n },\n }),\n ];\n}\n","// Self-host React: emit the React family into the Connect dist and point the\n// page import map at it, instead of resolving react/react-dom from esm.sh.\nimport { spawn } from \"node:child_process\";\nimport {\n chmodSync,\n cpSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname as pathDirname, join, resolve } from \"node:path\";\nimport type { Plugin } from \"vite\";\n\n// URL path (under base) the React bundle is emitted/served at.\nconst REACT_URL_DIR = \"__react__\";\n\n// Packages whose every browser-importable subpath is self-hosted.\nconst REACT_PACKAGES = [\"react\", \"react-dom\"];\n\n// Resolve an exports value to its browser-preferred target, or null.\nfunction importTarget(value: unknown): string | null {\n if (typeof value === \"string\") return value;\n if (!value || typeof value !== \"object\") return null;\n const o = value as Record<string, unknown>;\n for (const c of [\"browser\", \"import\", \"module\", \"default\"]) {\n if (c in o) {\n const t = importTarget(o[c]);\n if (t) return t;\n }\n }\n return null;\n}\n\n// All browser-usable subpaths of react/react-dom, mapped to the absolute file\n// their browser condition resolves to. Node/bun-only targets are skipped.\nfunction resolveReactEntries(dirname: string): Record<string, string> {\n const require = createRequire(join(dirname, \"noop.js\"));\n const out: Record<string, string> = {};\n for (const pkg of REACT_PACKAGES) {\n let pkgRoot: string;\n let exp: unknown;\n try {\n const pkgJsonPath = require.resolve(`${pkg}/package.json`);\n pkgRoot = pathDirname(pkgJsonPath);\n exp = (\n JSON.parse(readFileSync(pkgJsonPath, \"utf8\")) as { exports?: unknown }\n ).exports;\n } catch {\n continue;\n }\n if (!exp || typeof exp !== \"object\") continue;\n for (const key of Object.keys(exp as Record<string, unknown>)) {\n if (key === \"./package.json\" || key.includes(\"*\")) continue;\n const target = importTarget((exp as Record<string, unknown>)[key]);\n // Skip non-JS and runtime-only (node/bun) targets — unusable in a browser.\n if (!target || /\\.(json|css)$/.test(target)) continue;\n if (/\\.(node|bun)\\.js$/.test(target)) continue;\n const file = join(pkgRoot, target);\n if (!existsSync(file)) continue;\n out[key === \".\" ? pkg : `${pkg}${key.slice(1)}`] = file;\n }\n }\n return out;\n}\n\nexport interface ReactSelfHostOptions {\n // Project root used to resolve react/react-dom and run the sub-build.\n dirname: string;\n // Emit the development React build (warnings/act) instead of production.\n dev?: boolean;\n}\n\n// Import map for the self-hosted React, from the build's spec -> emitted file table.\nexport function reactImportMap(\n base: string,\n files: Record<string, string>,\n): Record<string, string> {\n const map: Record<string, string> = {};\n for (const [spec, file] of Object.entries(files)) {\n map[spec] = `${base}${REACT_URL_DIR}/${file}`;\n // Subpaths imported with their extension resolve to the same instance.\n if (spec.includes(\"/\")) map[`${spec}.js`] = map[spec];\n }\n // No `react/` catch-all: emitted names are hashed, so it could only reach a 404.\n return map;\n}\n\n// Content-hashed React entries: built before the HTML transform into staging\n// (the out dir may be emptied), copied into the dist at closeBundle.\nexport function reactSelfHostPlugin(options: ReactSelfHostOptions): Plugin {\n const entries = resolveReactEntries(options.dirname);\n let absOutDir = resolve(options.dirname, \"dist\");\n let base = \"/\";\n let staging: string | undefined;\n let files: Record<string, string> = {};\n let importMap: Record<string, string> = {};\n return {\n name: \"ph-react-self-host\",\n apply: \"build\",\n configResolved(config) {\n absOutDir = resolve(config.root, config.build.outDir);\n base = config.base;\n },\n async buildStart() {\n files = {};\n importMap = {};\n if (!Object.keys(entries).length) return;\n // Inside the project: the generated entries import react bare.\n const stagingParent = join(options.dirname, \"node_modules\");\n staging = mkdtempSync(\n join(\n existsSync(stagingParent) ? stagingParent : options.dirname,\n \".ph-react-self-host-\",\n ),\n );\n const { ok, stderr } = await runReactBuild(\n options.dirname,\n staging,\n entries,\n options.dev ? \"development\" : \"production\",\n );\n if (!ok) {\n this.error(\n `react self-host build failed${stderr.trim() ? `:\\n${stderr.trim()}` : \"\"}`,\n );\n }\n const manifest = join(staging, FILES_MANIFEST);\n files = JSON.parse(readFileSync(manifest, \"utf8\")) as Record<\n string,\n string\n >;\n rmSync(manifest, { force: true });\n importMap = reactImportMap(base, files);\n },\n transformIndexHtml() {\n if (!Object.keys(importMap).length) return;\n return [\n {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: importMap }),\n injectTo: \"head-prepend\",\n },\n ];\n },\n closeBundle() {\n if (!staging) return;\n const dest = join(absOutDir, REACT_URL_DIR);\n rmSync(dest, { recursive: true, force: true });\n mkdirSync(absOutDir, { recursive: true });\n cpSync(staging, dest, { recursive: true });\n // Newer Node cpSync keeps mkdtemp's 0700, which a server user can't read.\n chmodSync(dest, 0o755);\n rmSync(staging, { recursive: true, force: true });\n staging = undefined;\n const missing = Object.entries(files).filter(\n ([, file]) => !existsSync(join(dest, file)),\n );\n if (missing.length) {\n this.error(\n `react self-host: import map entries have no file in ${dest}:\\n` +\n missing.map(([spec, file]) => ` ${spec} -> ${file}`).join(\"\\n\"),\n );\n }\n },\n };\n}\n\n// spec -> emitted file, written by the build worker next to its output.\nconst FILES_MANIFEST = \"files.json\";\n\n// Spawn a throwaway worker that builds the React family; peak build memory is\n// reclaimed when the subprocess exits.\nfunction runReactBuild(\n dirname: string,\n outDir: string,\n entries: Record<string, string>,\n nodeEnv: \"development\" | \"production\",\n): Promise<{ ok: boolean; stderr: string }> {\n mkdirSync(outDir, { recursive: true });\n const workerPath = join(outDir, \"build-worker.mjs\");\n writeFileSync(workerPath, REACT_BUILD_WORKER);\n return new Promise((resolvePromise) => {\n const child = spawn(\n process.execPath,\n [workerPath, dirname, outDir, JSON.stringify(entries), nodeEnv],\n { cwd: dirname, stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n );\n let out = \"\";\n child.stdout.on(\"data\", (d) => (out += String(d)));\n child.stderr.on(\"data\", (d) => (out += String(d)));\n const done = (r: { ok: boolean; stderr: string }) => {\n rmSync(workerPath, { force: true });\n resolvePromise(r);\n };\n child.on(\"exit\", (code) => done({ ok: code === 0, stderr: out }));\n child.on(\"error\", (e) => done({ ok: false, stderr: String(e) }));\n });\n}\n\n// Worker: one ESM entry per subpath with explicit named re-exports. Names come\n// from the browser-resolved file (node names differ for server/static).\nconst REACT_BUILD_WORKER = `\nimport { createRequire } from 'node:module';\nimport { mkdirSync, writeFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nconst [dirname, outDir, entriesJSON, nodeEnv] = process.argv.slice(2);\nconst entries = JSON.parse(entriesJSON);\nconst reqProj = createRequire(join(dirname, 'noop.js'));\n// pathToFileURL: require.resolve returns an absolute path, and on Windows\n// import('D:\\\\...') parses \"D:\" as a URL scheme (ERR_UNSUPPORTED_ESM_URL_SCHEME).\nconst { build } = await import(pathToFileURL(reqProj.resolve('vite')).href);\nconst srcDir = join(outDir, '.entries');\nmkdirSync(srcDir, { recursive: true });\nconst entryName = (spec) => spec.replace(/[^\\\\w]+/g, '_');\nconst RESERVED = new Set('enum void null function in instanceof typeof new delete do if else return switch case break continue for while this true false class const let var default export import extends super with yield debugger finally throw try catch await implements interface package private protected public static eval arguments'.split(' '));\nconst input = {};\nfor (const [spec, file] of Object.entries(entries)) {\n const name = entryName(spec);\n let names = [];\n try {\n const ns = await import(pathToFileURL(file).href);\n const obj = (ns.default && typeof ns.default === 'object') ? ns.default : ns;\n names = Object.keys(obj).filter((k) => k !== 'default' && k !== '__esModule' && /^[A-Za-z_$][\\\\w$]*$/.test(k));\n } catch {}\n const plain = names.filter((n) => !RESERVED.has(n));\n const reserved = names.filter((n) => RESERVED.has(n));\n let src = 'import __m from ' + JSON.stringify(spec) + ';\\\\nexport default __m;\\\\n';\n if (plain.length) src += 'export const { ' + plain.join(', ') + ' } = __m;\\\\n';\n reserved.forEach((n, i) => {\n src += 'const __r' + i + ' = __m[' + JSON.stringify(n) + '];\\\\nexport { __r' + i + ' as ' + n + ' };\\\\n';\n });\n const entryFile = join(srcDir, name + '.js');\n writeFileSync(entryFile, src);\n // Key by the full spec so the output path mirrors the subpath\n // (react-dom/client -> react-dom/client.js), matching the catch-all import map.\n input[spec] = entryFile;\n}\ntry {\n const result = await build({\n root: dirname, configFile: false, logLevel: 'error',\n base: './', publicDir: false,\n define: { 'process.env.NODE_ENV': JSON.stringify(nodeEnv) },\n resolve: { conditions: ['browser', 'import', 'module', 'default'] },\n build: {\n outDir, emptyOutDir: false, minify: nodeEnv === 'production', target: 'esnext',\n rollupOptions: {\n input, preserveEntrySignatures: 'strict',\n output: { format: 'es', entryFileNames: '[name]-[hash].js', chunkFileNames: 'chunks/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]' },\n },\n },\n });\n rmSync(srcDir, { recursive: true, force: true });\n const files = {};\n for (const out of Array.isArray(result) ? result : [result]) {\n for (const chunk of out?.output ?? []) {\n if (chunk.type === 'chunk' && chunk.isEntry) files[chunk.name] = chunk.fileName;\n }\n }\n writeFileSync(join(outDir, 'files.json'), JSON.stringify(files));\n // Force exit: rolldown can leave native worker threads alive that keep the\n // event loop open, hanging the parent's spawn() promise indefinitely.\n process.exit(0);\n} catch (err) {\n console.error(err instanceof Error ? (err.stack ?? err.message) : String(err));\n process.exit(1);\n}\n`;\n","import { createReadStream } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Plugin } from \"vite\";\nimport {\n prebuildReactorWorker,\n REACTOR_WORKER_ENTRY,\n REACTOR_WORKER_MIME,\n REACTOR_WORKER_URL_PREFIX,\n type PrebuiltReactorWorker,\n} from \"../reactor-worker-build.js\";\n\n// Dev bundle cache, sibling of the vendor's `.ph-vendor`.\nconst DEV_BUNDLE_DIR = \"node_modules/.ph-reactor-worker\";\n\nfunction withBase(base: string, p: string): string {\n return `${base}${p}`.replace(/\\/{2,}/g, \"/\");\n}\n\n/**\n * Dev-only: serve Connect's reactor SharedWorker bundle under\n * `<base>__reactor_worker__/`, building it lazily on first request.\n *\n * The dev server serves Connect from its prebuilt dist in node_modules, where\n * `dist/reactor.worker.js` is a library artifact no worker can resolve. The\n * tab GETs `worker-meta.json` here (JSON, no-cache, written by\n * `prebuildReactorWorker`) to find the bundle and fold its `sourceDigest`\n * into its version fingerprint; without this plugin that GET fails and the\n * worker feature reports itself unavailable instead of dying opaquely.\n *\n * Lazy because it is a full `vite build` of the reactor + PGlite graph. The\n * result is cached in node_modules/.ph-reactor-worker until the installed\n * Connect, its upstream dists, or builder-tools change (`computeSourceDigest`).\n */\nexport function reactorWorkerDevPlugin(projectRoot: string): Plugin {\n let base = \"/\";\n let building: Promise<PrebuiltReactorWorker | null> | null = null;\n\n const ensureBuilt = (): Promise<PrebuiltReactorWorker | null> => {\n building ??= (async () => {\n const errorRef: { message?: string } = {};\n const built = await prebuildReactorWorker({\n dirname: projectRoot,\n outDir: path.join(projectRoot, DEV_BUNDLE_DIR),\n nodeEnv: \"development\",\n errorRef,\n });\n if (!built) {\n console.warn(\n `[connect] reactor worker bundle build failed${\n errorRef.message ? `: ${errorRef.message}` : \"\"\n }`,\n );\n // Allow a retry on the next request instead of caching the failure\n // for the server's lifetime.\n building = null;\n }\n return built;\n })();\n return building;\n };\n\n return {\n name: \"ph-reactor-worker-dev\",\n apply: \"serve\",\n configResolved(config) {\n base = config.base;\n },\n configureServer(server) {\n const prefixes = [\n withBase(base, REACTOR_WORKER_URL_PREFIX),\n REACTOR_WORKER_URL_PREFIX,\n ];\n server.middlewares.use((req, res, next) => {\n const url = (req.url ?? \"\").split(\"?\")[0];\n const prefix = prefixes.find((p) => url.startsWith(p));\n if (!prefix) return next();\n const name = url.slice(prefix.length).replace(/^\\/+/, \"\");\n if (!name) return next();\n\n void (async () => {\n const built = await ensureBuilt();\n if (!built) {\n res.statusCode = 503;\n res.setHeader(\"Content-Type\", \"text/plain\");\n res.end(\n \"reactor worker bundle unavailable (build failed; see server log)\",\n );\n return;\n }\n const file = path.join(built.outDir, name);\n // Path-segment containment: reject anything escaping the bundle dir.\n const rel = path.relative(built.outDir, file);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n next();\n return;\n }\n const stream = createReadStream(file);\n stream.on(\"error\", () => {\n if (!res.headersSent) next();\n });\n stream.once(\"open\", () => {\n const ext = file.slice(file.lastIndexOf(\".\"));\n res.setHeader(\n \"Content-Type\",\n REACTOR_WORKER_MIME[ext] ?? \"text/javascript\",\n );\n // Everything except the entry (stable name, changes with the\n // installed Connect) and the metadata is content-hashed.\n const hashed =\n !name.startsWith(REACTOR_WORKER_ENTRY) && !name.endsWith(\".json\");\n res.setHeader(\n \"Cache-Control\",\n hashed ? \"public, max-age=31536000, immutable\" : \"no-cache\",\n );\n stream.pipe(res);\n });\n })();\n });\n },\n };\n}\n","import type { Plugin } from \"vite\";\n\n/**\n * Marker attribute on the injected script. Serve-time injectors (e.g. the\n * ph-clint connect proxy) and this plugin both check it, so the script is\n * applied exactly once no matter which layer runs first.\n */\nexport const THEME_BOOT_MARKER = \"data-ph-theme-boot\";\n\n/**\n * Pre-paint theme boot: `?theme=dark|light` persists to `ph:theme`, then the\n * stored choice (or system preference) decides the `.dark` root class before\n * hydration. Fail-silent — storage access can throw in embed/privacy contexts.\n * Keep semantically identical to the runtime store in\n * `@powerhousedao/reactor-browser` (hooks/theme.ts).\n */\nconst THEME_BOOT_SCRIPT =\n `(function(){try{` +\n `var p=new URLSearchParams(location.search).get('theme');` +\n `if(p==='dark'||p==='light')localStorage.setItem('ph:theme',p);` +\n `var s=localStorage.getItem('ph:theme');` +\n `var m=matchMedia('(prefers-color-scheme: dark)');` +\n `var d=s==='dark'||((!s||s==='system')&&m.matches);` +\n `document.documentElement.classList.toggle('dark',d);` +\n // Some browsers settle the OS preference after boot; follow it until the app does.\n `if(!s||s==='system'){var f=function(){var t=localStorage.getItem('ph:theme');` +\n `if(!t||t==='system')document.documentElement.classList.toggle('dark',m.matches);};` +\n `m.addEventListener('change',f);requestAnimationFrame(f);}` +\n `}catch(e){}})();`;\n\n/**\n * Injects the theme boot script at the top of `<head>` of every emitted\n * index.html, so built Connect apps render the stored theme from first paint\n * without depending on a serve-time injector.\n */\nexport function connectThemeBootPlugin(): Plugin {\n return {\n name: \"ph-connect-theme-boot\",\n transformIndexHtml(html) {\n if (html.includes(THEME_BOOT_MARKER)) return;\n return {\n html,\n tags: [\n {\n tag: \"script\",\n attrs: { [THEME_BOOT_MARKER]: \"\" },\n children: THEME_BOOT_SCRIPT,\n injectTo: \"head-prepend\",\n },\n ],\n };\n },\n };\n}\n","// Merge the production vendor's import-map entries into the page's\n// `<script type=\"importmap\">`. Build-only.\n//\n// Connect already self-hosts React: `reactSelfHostPlugin` (registered before\n// this plugin) returns an import-map tag, which Vite injects into the HTML\n// string before the next transformIndexHtml hook runs. So by the time this\n// hook sees the HTML, the React map is an inline script — we merge the\n// vendor entries into it. If no import map exists (a consumer disabled\n// react self-host), we inject one.\nimport type { HtmlTagDescriptor, Plugin } from \"vite\";\n\nexport type VendorImportMapOptions = {\n /** bare specifier -> URL (already base-prefixed by the caller). */\n imports: Record<string, string>;\n};\n\n// Pull the `imports` table out of a parsed import-map document without\n// trusting its shape: anything that isn't a string specifier->string value\n// is ignored, and malformed documents yield an empty table instead of a\n// throw.\nfunction extractImports(raw: unknown): Record<string, string> {\n if (typeof raw !== \"object\" || raw === null) return {};\n const imports = \"imports\" in raw ? raw.imports : undefined;\n if (typeof imports !== \"object\" || imports === null) return {};\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(imports)) {\n if (typeof value === \"string\") out[key] = value;\n }\n return out;\n}\n\nfunction parseImportMap(raw: string): Record<string, string> {\n try {\n return extractImports(JSON.parse(raw));\n } catch {\n return {};\n }\n}\n\nconst INLINE_IMPORTMAP = /<script type=\"importmap\">([\\s\\S]*?)<\\/script>/;\n\nexport function vendorImportMapPlugin(options: VendorImportMapOptions): Plugin {\n const vendorEntries = Object.keys(options.imports).length;\n return {\n name: \"ph-vendor-import-map\",\n apply: \"build\",\n transformIndexHtml(html) {\n if (!vendorEntries) return;\n\n // Merge into the existing map (the react self-host one, or a\n // consumer-provided one). Vendor entries win on specifier conflicts.\n const match = INLINE_IMPORTMAP.exec(html);\n if (match) {\n const merged = {\n imports: { ...parseImportMap(match[1]), ...options.imports },\n };\n return html.replace(\n INLINE_IMPORTMAP,\n `<script type=\"importmap\">${JSON.stringify(merged)}</script>`,\n );\n }\n\n // No map at all: inject one (head-prepend, the same position the\n // react map uses).\n const injected: HtmlTagDescriptor = {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: options.imports }),\n injectTo: \"head-prepend\",\n };\n return [injected];\n },\n };\n}\n","import type { PowerhouseConfig } from \"@powerhousedao/config\";\nimport { getConfig } from \"@powerhousedao/config/node\";\nimport {\n deepMerge,\n loadConnectEnv,\n mergePwaConfig,\n normalizeBasePath,\n setConnectEnv,\n} from \"@powerhousedao/shared/connect\";\nimport tailwind from \"@tailwindcss/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { realpathSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n createLogger,\n esmExternalRequirePlugin,\n loadEnv,\n searchForWorkspaceRoot,\n type HtmlTagDescriptor,\n type InlineConfig,\n type PluginOption,\n} from \"vite\";\nimport { createHtmlPlugin } from \"vite-plugin-html\";\nimport type { IConnectOptions } from \"./types.js\";\nimport {\n buildHashFromBuildOptions,\n connectBuildHashPlugin,\n} from \"./vite-plugins/build-hash.js\";\nimport { devReactImportmapPlugin } from \"./vite-plugins/dev-external-react.js\";\nimport {\n DYNAMIC_BASE_PLACEHOLDER,\n connectDynamicBasePlugin,\n} from \"./vite-plugins/dynamic-base.js\";\nimport { connectAppShellPlugin } from \"./vite-plugins/app-shell.js\";\nimport {\n connectRouterChunkGroups,\n connectRoutes,\n resolveConnectRoutesDir,\n} from \"./vite-plugins/connect-routes.js\";\nimport { connectFaviconPlugin } from \"./vite-plugins/favicon.js\";\nimport { phBundledPackagesPlugin } from \"./vite-plugins/ph-bundled-packages.js\";\nimport { phConfigPlugin } from \"./vite-plugins/ph-config.js\";\nimport {\n collectPackagePwaContributions,\n collectProjectPwaContribution,\n validateProjectPwaConfig,\n} from \"./vite-plugins/pwa-packages.js\";\nimport { connectPwaPlugins } from \"./vite-plugins/pwa.js\";\nimport { reactSelfHostPlugin } from \"./vite-plugins/react-self-host.js\";\nimport { reactorWorkerDevPlugin } from \"./vite-plugins/reactor-worker-dev.js\";\nimport { connectThemeBootPlugin } from \"./vite-plugins/theme-boot.js\";\nimport { vendorImportMapPlugin } from \"./vite-plugins/vendor-import-map.js\";\n\nexport function getConnectHtmlTags(\n options: {\n registryUrl?: string | null;\n injectTo?: HtmlTagDescriptor[\"injectTo\"];\n } = {},\n) {\n const { registryUrl, injectTo = \"head\" } = options;\n return [\n {\n tag: \"meta\",\n attrs: {\n \"http-equiv\": \"Content-Security-Policy\",\n content: `script-src 'self' 'unsafe-inline' 'unsafe-eval'${registryUrl ? \" \" + registryUrl : \"\"}; worker-src 'self' blob:; object-src 'none'; base-uri 'self';`,\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:title\",\n content: \"Connect\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:type\",\n content: \"website\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:url\",\n content: \"https://apps.powerhouse.io/powerhouse/connect/\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:description\",\n content:\n \"Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation.\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n property: \"og:image\",\n content:\n \"https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:card\",\n content: \"summary_large_image\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:image\",\n content:\n \"https://cf-ipfs.com/ipfs/bafkreigrmclndf2jpbolaq22535q2sw5t44uad3az3dpvkzrnt4lpjt63e\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:title\",\n content: \"Connect\",\n },\n injectTo,\n },\n {\n tag: \"meta\",\n attrs: {\n name: \"twitter:description\",\n content:\n \"Navigate your organisation’s toughest operational challenges and steer your contributors to success with Connect. A navigation, collaboration and reporting tool for decentralised and open organisation.\",\n },\n injectTo,\n },\n ] as const satisfies HtmlTagDescriptor[];\n}\n\nfunction viteLogger({\n silence,\n}: {\n silence?: { warnings?: string[]; errors?: string[] };\n}) {\n const logger = createLogger();\n const loggerWarn = logger.warn.bind(logger);\n const loggerError = logger.error.bind(logger);\n\n logger.warn = (msg, options) => {\n if (silence?.warnings?.some((warning) => msg.includes(warning))) {\n return;\n }\n loggerWarn(msg, options);\n };\n\n logger.error = (msg, options) => {\n if (silence?.errors?.some((error) => msg.includes(error))) {\n return;\n }\n loggerError(msg, options);\n };\n\n return logger;\n}\n\nfunction parsePackagesEnvOverride(phPackagesStr: string) {\n return phPackagesStr\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean)\n .map((entry) => {\n const lastAt = entry.lastIndexOf(\"@\");\n if (lastAt > 0) {\n return {\n packageName: entry.slice(0, lastAt),\n version: entry.slice(lastAt + 1),\n provider: \"registry\" as const,\n };\n }\n return { packageName: entry, provider: \"registry\" as const };\n });\n}\n\nfunction getLocalPackageNamesFromPowerhouseConfig({\n packages,\n}: PowerhouseConfig) {\n if (!packages) return [];\n return packages\n .filter((p) => p.provider === \"local\")\n .map((p) => p.packageName);\n}\n\nexport function getConnectBaseViteConfig(options: IConnectOptions) {\n const mode = options.mode;\n const envDir = options.envDir ?? options.dirname;\n const fileEnv = loadEnv(mode, envDir, \"PH_\");\n\n // Load and validate environment with priority: process.env > fileEnv > defaults\n const env = loadConnectEnv({\n processEnv: process.env,\n fileEnv,\n });\n\n // set the resolved env to process.env so it's loaded by vite\n setConnectEnv(env);\n\n // Source config is always the project-root powerhouse.config.json.\n const phConfigPath = join(options.dirname, \"powerhouse.config.json\");\n\n const phConfig = options.powerhouseConfig ?? getConfig(phConfigPath);\n\n const packagesFromConfig = phConfig.packages ?? [];\n const localPackagesFromConfig =\n getLocalPackageNamesFromPowerhouseConfig(phConfig);\n const phPackagesStr = env.PH_PACKAGES;\n const envPhPackages = phPackagesStr\n ? parsePackagesEnvOverride(phPackagesStr)\n : undefined;\n\n const phPackages = envPhPackages ?? packagesFromConfig;\n\n // Precedence (highest → lowest): `ph connect build --packages-registry`\n // CLI override > source-config `packageRegistryUrl`. The resolved value\n // flows both into the CSP header (script-src allowance for the registry\n // CDN) and into the emitted runtime config so the SPA reads the same\n // value.\n const phPackageRegistryUrl =\n options.cliPackageRegistryUrl ?? phConfig.packageRegistryUrl ?? null;\n\n // Base path is a runtime-config field (connect.app.basePath), not an env\n // var. Resolve it with the same precedence as the rest of the connect\n // config: CLI override > source powerhouse.config.json.\n const connectBasePath =\n options.cliConnectOverride?.app?.basePath ??\n phConfig.connect?.app?.basePath;\n\n const offlineEnabled =\n options.cliConnectOverride?.app?.offline ??\n phConfig.connect?.app?.offline ??\n true;\n\n const authToken = env.PH_SENTRY_AUTH_TOKEN;\n const org = env.PH_SENTRY_ORG;\n const project = env.PH_SENTRY_PROJECT;\n // Release tag derived from the workspace version so it matches the\n // sourcemap upload tag CI uses.\n const release =\n process.env.WORKSPACE_VERSION ??\n process.env.npm_package_version ??\n env.PH_CONNECT_VERSION;\n const uploadSentrySourcemaps = authToken && org && project;\n\n // Build identity: baked into the bundle (define PH_CONNECT_BUILD_HASH) and\n // emitted as build-hash.json (which the server must serve no-cache). The\n // SPA compares the two; a mismatch means the server is serving a different\n // build than the one this bundle was built from — a same-origin \"new\n // deploy\" signal that works on localhost, where the old GitHub-branch\n // version check was meaningless.\n const buildHash = buildHashFromBuildOptions({\n dirname: options.dirname,\n phConfig,\n packages: phPackages,\n connectBasePath,\n offlineEnabled,\n packageRegistryUrl: phPackageRegistryUrl,\n });\n\n const connectHtmlTags = getConnectHtmlTags({\n registryUrl: phPackageRegistryUrl,\n });\n\n // Dev needs a placeholder importmap for devReactImportmapPlugin to rewrite;\n // builds get their map from reactSelfHostPlugin's boot script instead.\n const devImportmapTag =\n mode === \"development\"\n ? [\n {\n tag: \"script\",\n attrs: { type: \"importmap\" },\n children: JSON.stringify({ imports: {} }),\n injectTo: \"head-prepend\" as const,\n },\n ]\n : [];\n\n const plugins: PluginOption[] = [\n tailwind(),\n react(),\n createHtmlPlugin({\n minify: false,\n inject: {\n tags: [...connectHtmlTags, ...devImportmapTag],\n },\n }),\n ] as const;\n\n if (uploadSentrySourcemaps) {\n plugins.push(\n import(\"@sentry/vite-plugin\").then(({ sentryVitePlugin }) =>\n sentryVitePlugin({\n release: {\n name: release ?? \"unknown\",\n inject: false, // prevent it from injecting the release id in the service worker code, this is done in 'src/app/sentry.ts' instead\n },\n authToken,\n org,\n project,\n bundleSizeOptimizations: {\n excludeDebugStatements: true,\n },\n reactComponentAnnotation: {\n enabled: true,\n },\n }),\n ) as PluginOption,\n );\n }\n\n // hide warnings unless LOG_LEVEL is set to debug, or the source config\n // declares connect.app.logLevel = \"debug\"\n const isDebug =\n process.env.LOG_LEVEL === \"debug\" ||\n phConfig.connect?.app?.logLevel === \"debug\";\n const customLogger = isDebug\n ? undefined\n : viteLogger({\n silence: {\n warnings: [\n \"@import must precede all other statements (besides @charset or empty @layer)\", // tailwindcss error when importing font file\n ],\n errors: [\"Unterminated string literal\"],\n },\n });\n\n // PWA overrides ladder: build-time-known package `pwa` fragments merge UNDER\n // the project's `connect.pwa` block (source deep-merged with the CLI/operator\n // override, CLI wins). Scalars are project-wins; arrays (icons, globs,\n // runtime-caching rules, denylist) are additive; the size ceiling takes the\n // max. Fragments come from the configured packages (local from node_modules,\n // registry from the CDN) and, last among packages, the project's own\n // manifest. The user's own connect.pwa is validated strictly (fails the\n // build); package fragments warn + skip inside the collectors.\n const projectPwa = validateProjectPwaConfig(\n deepMerge(\n phConfig.connect?.pwa ?? {},\n options.cliConnectOverride?.pwa ?? {},\n ),\n phConfigPath,\n );\n const pwaWarn = (msg: string) => (customLogger ?? console).warn(msg);\n // Registry fragments need the network, so only production builds fetch them\n // (dev/studio runs without a service worker and must not depend on the\n // registry being reachable). Async: Vite resolves promised plugins, same\n // pattern as the sentry plugin below.\n const pwaPackagesForFragments =\n mode === \"production\"\n ? phPackages\n : phPackages.filter((p) => p.provider === \"local\");\n const pwaPlugins: PluginOption = (async () => {\n if (!offlineEnabled) return connectPwaPlugins({ offlineEnabled });\n const contributions = await collectPackagePwaContributions({\n packages: pwaPackagesForFragments,\n projectRoot: options.dirname,\n registryUrl: phPackageRegistryUrl,\n onWarn: pwaWarn,\n });\n const projectContribution = collectProjectPwaContribution({\n projectRoot: options.dirname,\n });\n if (projectContribution) contributions.push(projectContribution);\n const mergedPwa = mergePwaConfig(contributions, projectPwa, pwaWarn);\n return connectPwaPlugins({ offlineEnabled, pwa: mergedPwa });\n })();\n\n const reactExternal = [\n \"react\",\n \"react-dom\",\n \"react/jsx-runtime\",\n \"react-dom/client\",\n ];\n\n // pnpm `link:` deps (e.g. a downstream project linking @powerhousedao/*\n // packages from a sibling monorepo checkout) live outside Vite's\n // auto-detected workspace root. Their `node_modules/.pnpm/...` assets\n // then 403 through `/@fs/`, returning a 760-byte HTML body where the\n // binary should be — which breaks PGlite at startup with \"Invalid FS\n // bundle size: 760 !== 4939170\". Resolve key linked packages back to\n // their real workspace roots and allow Vite to serve from there.\n const linkedRoots = [\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/connect\",\n \"@electric-sql/pglite\",\n ]\n .map((pkg) => {\n try {\n return searchForWorkspaceRoot(\n realpathSync(join(options.dirname, \"node_modules\", pkg)),\n );\n } catch {\n return null;\n }\n })\n .filter((p): p is string => p !== null);\n\n const routesDir = resolveConnectRoutesDir(options.dirname);\n const routes = connectRoutes(options.dirname, routesDir);\n\n const config: InlineConfig = {\n configFile: false,\n mode,\n // Prefix served/built asset URLs so Connect can run under a path prefix\n // (reverse proxy). Mirrors the client router basename; normalize so a bare\n // `app` or `/app` becomes `/app/` and matches the router.\n //\n // Dynamic-base mode: set a placeholder token instead of a concrete base.\n // connectDynamicBasePlugin (below) rewrites it in the emitted JS to a\n // runtime expression so one bundle serves under any subpath; the proxy\n // substitutes it in the HTML and sets the runtime global at serve time.\n base: options.dynamicBase\n ? DYNAMIC_BASE_PLACEHOLDER\n : connectBasePath\n ? normalizeBasePath(connectBasePath)\n : undefined,\n server: {\n watch: {\n ignored: [\"**/backup-documents/**\", \"**/.ph/**\"],\n },\n fs: {\n allow: [searchForWorkspaceRoot(options.dirname), ...linkedRoots],\n },\n },\n resolve: {\n alias: [routes.alias],\n dedupe: [\"react\", \"react-dom\", ...routes.dedupe],\n tsconfigPaths: true,\n },\n define: {\n PH_CONNECT_SENTRY_RELEASE: JSON.stringify(release || \"unknown\"),\n PH_CONNECT_BUILD_HASH: JSON.stringify(buildHash),\n // Per-build URLs, so a stale service worker never serves an older copy.\n ...(options.vendor?.sharedDeps && mode === \"production\"\n ? {\n PH_CONNECT_SHARED_DEPS_URL: JSON.stringify(\n options.vendor.sharedDeps,\n ),\n }\n : {}),\n ...(options.reactorWorkerVersion\n ? {\n PH_CONNECT_REACTOR_WORKER_VERSION: JSON.stringify(\n options.reactorWorkerVersion,\n ),\n }\n : {}),\n },\n customLogger,\n envPrefix: [\"PH_CONNECT_\"],\n optimizeDeps: {\n include: [\n \"document-model\",\n \"zod\",\n \"@powerhousedao/design-system/connect\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/document-engineering\",\n ],\n exclude: [\"@electric-sql/pglite\", \"@electric-sql/pglite-tools\"],\n },\n plugins: [\n // phConfigPlugin must be registered before tailwind so its hotUpdate\n // hook runs first and can suppress HMR updates for codegen-generated\n // files, preventing tailwind from triggering full page reloads.\n phConfigPlugin({\n packages: phPackages,\n projectRoot: options.dirname,\n connect: phConfig.connect,\n workflows: phConfig.workflows,\n packageRegistryUrl: phPackageRegistryUrl ?? undefined,\n cliConnectOverride: options.cliConnectOverride,\n }),\n phBundledPackagesPlugin({\n packages: localPackagesFromConfig,\n projectRoot: options.dirname,\n }),\n // Dev-only: rewrite the importmap to Vite's pre-bundled React so Connect\n // and CDN editors share one instance (build uses reactSelfHostPlugin).\n devReactImportmapPlugin(options.dirname, routesDir),\n // Dev-only: serve the reactor SharedWorker bundle (built lazily) at the\n // stable URL the tab probes; production builds emit it via\n // prebuildReactorWorker in `ph connect build`.\n reactorWorkerDevPlugin(options.dirname),\n // The project's routes beside Connect's; ahead of react().\n ...routes.plugins,\n ...plugins,\n // Externalize React so Connect + CDN editors share one instance via the\n // import map (reactSelfHostPlugin URLs); also rewrites external require().\n // Production vendor builds additionally externalize the shared package\n // set — the Connect app's own imports of them resolve through the\n // import map at runtime instead of being bundled.\n //\n // The externals are the vendor's *published* specifiers, not a static\n // list: the vendor drops entries whose package is not installed in the\n // project, and never publishes the bare `@powerhousedao/shared` root.\n // Externalizing a specifier the import map has no entry for leaves a\n // bare specifier in the chunk, and the browser kills it with \"Failed to\n // resolve module specifier\". Taking the keys keeps the two in step by\n // construction — the dev plugin matches on the same map.\n esmExternalRequirePlugin({\n external: [\n ...reactExternal,\n ...(options.vendor && mode === \"production\"\n ? Object.keys(options.vendor.imports)\n : []),\n ],\n }),\n // Build-only: emit the React family into the dist + static import map, so\n // React is self-hosted (not esm.sh). Dev React for non-prod/debug builds.\n reactSelfHostPlugin({\n dirname: options.dirname,\n dev: mode !== \"production\" || isDebug,\n }),\n // After the react map is injected: merge the production vendor's\n // specifier entries into that same import map.\n ...(options.vendor && mode === \"production\"\n ? [vendorImportMapPlugin({ imports: options.vendor.imports })]\n : []),\n connectFaviconPlugin({ faviconPath: options.favicon }),\n // Pre-paint theme boot in every emitted index.html (marker-idempotent\n // with the serve-time injection in the ph-clint connect proxy).\n connectThemeBootPlugin(),\n // Build-time: Connect's prerendered app shell in #root, critical CSS inline.\n connectAppShellPlugin(options.dirname),\n // Emits build-hash.json (the SPA's same-origin \"is my build current?\"\n // probe; must be served no-cache — see docker/nginx.conf.template).\n connectBuildHashPlugin(buildHash),\n // enforce: \"post\" — rewrites the placeholder base after all other\n // transforms have emitted their asset/chunk URLs.\n ...(options.dynamicBase ? [connectDynamicBasePlugin()] : []),\n // PWA / service worker last, so its precache manifest sees every emitted\n // asset (including the icons connectPwaIconsPlugin emits).\n pwaPlugins,\n ],\n worker: {\n format: \"es\",\n // Worker chunks are emitted by a separate Rolldown build, so the main\n // bundle's generateBundle never sees them. The worker instance both\n // rewrites the placeholder and prepends a prelude that resolves the base\n // in worker scope (forWorker) — the proxy only sets the global on the\n // main thread.\n ...(options.dynamicBase\n ? { plugins: () => [connectDynamicBasePlugin({ forWorker: true })] }\n : {}),\n },\n build: {\n sourcemap: true,\n // npm can nest privy's optional Solana peers out of its reach; vite\n // stubs them, so named imports from the stub must not fail the build.\n rolldownOptions: {\n shimMissingExports: true,\n output: {\n codeSplitting: { groups: connectRouterChunkGroups(routesDir) },\n },\n },\n },\n };\n return config;\n}\n"],"mappings":"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"}