everything-dev 0.3.2 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/cli.js +10 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/api-contract.cjs +172 -0
- package/dist/api-contract.cjs.map +1 -0
- package/dist/api-contract.mjs +171 -0
- package/dist/api-contract.mjs.map +1 -0
- package/dist/api.cjs +124 -0
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.cts +36 -0
- package/dist/api.d.cts.map +1 -0
- package/dist/api.d.mts +36 -0
- package/dist/api.d.mts.map +1 -0
- package/dist/api.mjs +119 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app.cjs +156 -0
- package/dist/app.cjs.map +1 -0
- package/dist/app.mjs +153 -0
- package/dist/app.mjs.map +1 -0
- package/dist/cli/catalog.cjs +30 -0
- package/dist/cli/catalog.cjs.map +1 -0
- package/dist/cli/catalog.mjs +29 -0
- package/dist/cli/catalog.mjs.map +1 -0
- package/dist/cli/help.cjs +16 -0
- package/dist/cli/help.cjs.map +1 -0
- package/dist/cli/help.mjs +16 -0
- package/dist/cli/help.mjs.map +1 -0
- package/dist/cli/init.cjs +317 -0
- package/dist/cli/init.cjs.map +1 -0
- package/dist/cli/init.d.cts +36 -0
- package/dist/cli/init.d.cts.map +1 -0
- package/dist/cli/init.d.mts +36 -0
- package/dist/cli/init.d.mts.map +1 -0
- package/dist/cli/init.mjs +309 -0
- package/dist/cli/init.mjs.map +1 -0
- package/dist/cli/parse.cjs +96 -0
- package/dist/cli/parse.cjs.map +1 -0
- package/dist/cli/parse.mjs +95 -0
- package/dist/cli/parse.mjs.map +1 -0
- package/dist/cli/prompts.cjs +42 -0
- package/dist/cli/prompts.cjs.map +1 -0
- package/dist/cli/prompts.mjs +41 -0
- package/dist/cli/prompts.mjs.map +1 -0
- package/dist/cli.cjs +167 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +166 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/components/dev-view.cjs +307 -0
- package/dist/components/dev-view.cjs.map +1 -0
- package/dist/components/dev-view.mjs +306 -0
- package/dist/components/dev-view.mjs.map +1 -0
- package/dist/components/streaming-view.cjs +146 -0
- package/dist/components/streaming-view.cjs.map +1 -0
- package/dist/components/streaming-view.mjs +144 -0
- package/dist/components/streaming-view.mjs.map +1 -0
- package/dist/config.cjs +280 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +35 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +35 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +266 -0
- package/dist/config.mjs.map +1 -0
- package/dist/contract.cjs +209 -0
- package/dist/contract.cjs.map +1 -0
- package/dist/contract.d.cts +490 -0
- package/dist/contract.d.cts.map +1 -0
- package/dist/contract.d.mts +490 -0
- package/dist/contract.d.mts.map +1 -0
- package/dist/contract.meta.cjs +104 -0
- package/dist/contract.meta.cjs.map +1 -0
- package/dist/contract.meta.d.cts +141 -0
- package/dist/contract.meta.d.cts.map +1 -0
- package/dist/contract.meta.d.mts +141 -0
- package/dist/contract.meta.d.mts.map +1 -0
- package/dist/contract.meta.mjs +102 -0
- package/dist/contract.meta.mjs.map +1 -0
- package/dist/contract.mjs +186 -0
- package/dist/contract.mjs.map +1 -0
- package/dist/dev-logs.cjs +53 -0
- package/dist/dev-logs.cjs.map +1 -0
- package/dist/dev-logs.mjs +51 -0
- package/dist/dev-logs.mjs.map +1 -0
- package/dist/dev-session.cjs +195 -0
- package/dist/dev-session.cjs.map +1 -0
- package/dist/dev-session.mjs +194 -0
- package/dist/dev-session.mjs.map +1 -0
- package/dist/fastkv.cjs +89 -0
- package/dist/fastkv.cjs.map +1 -0
- package/dist/fastkv.d.cts +11 -0
- package/dist/fastkv.d.cts.map +1 -0
- package/dist/fastkv.d.mts +11 -0
- package/dist/fastkv.d.mts.map +1 -0
- package/dist/fastkv.mjs +82 -0
- package/dist/fastkv.mjs.map +1 -0
- package/dist/federation.server.cjs +27 -0
- package/dist/federation.server.cjs.map +1 -0
- package/dist/federation.server.mjs +27 -0
- package/dist/federation.server.mjs.map +1 -0
- package/dist/host.cjs +367 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.cts +22 -0
- package/dist/host.d.cts.map +1 -0
- package/dist/host.d.mts +22 -0
- package/dist/host.d.mts.map +1 -0
- package/dist/host.mjs +364 -0
- package/dist/host.mjs.map +1 -0
- package/dist/index.cjs +122 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +9 -0
- package/dist/integrity.cjs +39 -0
- package/dist/integrity.cjs.map +1 -0
- package/dist/integrity.d.cts +7 -0
- package/dist/integrity.d.cts.map +1 -0
- package/dist/integrity.d.mts +7 -0
- package/dist/integrity.d.mts.map +1 -0
- package/dist/integrity.mjs +35 -0
- package/dist/integrity.mjs.map +1 -0
- package/dist/mf.cjs +77 -0
- package/dist/mf.cjs.map +1 -0
- package/dist/mf.d.cts +19 -0
- package/dist/mf.d.cts.map +1 -0
- package/dist/mf.d.mts +19 -0
- package/dist/mf.d.mts.map +1 -0
- package/dist/mf.mjs +71 -0
- package/dist/mf.mjs.map +1 -0
- package/dist/near-cli.cjs +196 -0
- package/dist/near-cli.cjs.map +1 -0
- package/dist/near-cli.mjs +193 -0
- package/dist/near-cli.mjs.map +1 -0
- package/dist/network.cjs +9 -0
- package/dist/network.cjs.map +1 -0
- package/dist/network.mjs +8 -0
- package/dist/network.mjs.map +1 -0
- package/dist/orchestrator.cjs +441 -0
- package/dist/orchestrator.cjs.map +1 -0
- package/dist/orchestrator.d.cts +40 -0
- package/dist/orchestrator.d.cts.map +1 -0
- package/dist/orchestrator.d.mts +40 -0
- package/dist/orchestrator.d.mts.map +1 -0
- package/dist/orchestrator.mjs +436 -0
- package/dist/orchestrator.mjs.map +1 -0
- package/dist/plugin.cjs +825 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +347 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.mts +348 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +822 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/process-registry.cjs +120 -0
- package/dist/process-registry.cjs.map +1 -0
- package/dist/process-registry.d.cts +25 -0
- package/dist/process-registry.d.cts.map +1 -0
- package/dist/process-registry.d.mts +25 -0
- package/dist/process-registry.d.mts.map +1 -0
- package/dist/process-registry.mjs +119 -0
- package/dist/process-registry.mjs.map +1 -0
- package/dist/sdk.cjs +61 -0
- package/dist/sdk.d.cts +5 -0
- package/dist/sdk.d.mts +5 -0
- package/dist/sdk.mjs +6 -0
- package/dist/shared.cjs +143 -0
- package/dist/shared.cjs.map +1 -0
- package/dist/shared.d.cts +33 -0
- package/dist/shared.d.cts.map +1 -0
- package/dist/shared.d.mts +33 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +140 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types.cjs +160 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +269 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +269 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +144 -0
- package/dist/types.mjs.map +1 -0
- package/dist/ui/head.cjs +67 -0
- package/dist/ui/head.cjs.map +1 -0
- package/dist/ui/head.d.cts +19 -0
- package/dist/ui/head.d.cts.map +1 -0
- package/dist/ui/head.d.mts +19 -0
- package/dist/ui/head.d.mts.map +1 -0
- package/dist/ui/head.mjs +61 -0
- package/dist/ui/head.mjs.map +1 -0
- package/dist/ui/index.cjs +32 -0
- package/dist/ui/index.d.cts +7 -0
- package/dist/ui/index.d.mts +7 -0
- package/dist/ui/index.mjs +6 -0
- package/dist/ui/metadata.cjs +106 -0
- package/dist/ui/metadata.cjs.map +1 -0
- package/dist/ui/metadata.d.cts +35 -0
- package/dist/ui/metadata.d.cts.map +1 -0
- package/dist/ui/metadata.d.mts +35 -0
- package/dist/ui/metadata.d.mts.map +1 -0
- package/dist/ui/metadata.mjs +100 -0
- package/dist/ui/metadata.mjs.map +1 -0
- package/dist/ui/router.cjs +56 -0
- package/dist/ui/router.cjs.map +1 -0
- package/dist/ui/router.d.cts +11 -0
- package/dist/ui/router.d.cts.map +1 -0
- package/dist/ui/router.d.mts +11 -0
- package/dist/ui/router.d.mts.map +1 -0
- package/dist/ui/router.mjs +51 -0
- package/dist/ui/router.mjs.map +1 -0
- package/dist/ui/runtime.cjs +65 -0
- package/dist/ui/runtime.cjs.map +1 -0
- package/dist/ui/runtime.d.cts +29 -0
- package/dist/ui/runtime.d.cts.map +1 -0
- package/dist/ui/runtime.d.mts +29 -0
- package/dist/ui/runtime.d.mts.map +1 -0
- package/dist/ui/runtime.mjs +53 -0
- package/dist/ui/runtime.mjs.map +1 -0
- package/dist/ui/types.cjs +0 -0
- package/dist/ui/types.d.cts +52 -0
- package/dist/ui/types.d.cts.map +1 -0
- package/dist/ui/types.d.mts +52 -0
- package/dist/ui/types.d.mts.map +1 -0
- package/dist/ui/types.mjs +1 -0
- package/dist/utils/banner.cjs +24 -0
- package/dist/utils/banner.cjs.map +1 -0
- package/dist/utils/banner.mjs +23 -0
- package/dist/utils/banner.mjs.map +1 -0
- package/dist/utils/linkify.cjs +15 -0
- package/dist/utils/linkify.cjs.map +1 -0
- package/dist/utils/linkify.mjs +14 -0
- package/dist/utils/linkify.mjs.map +1 -0
- package/dist/utils/run.cjs +40 -0
- package/dist/utils/run.cjs.map +1 -0
- package/dist/utils/run.mjs +39 -0
- package/dist/utils/run.mjs.map +1 -0
- package/dist/utils/theme.cjs +44 -0
- package/dist/utils/theme.cjs.map +1 -0
- package/dist/utils/theme.mjs +37 -0
- package/dist/utils/theme.mjs.map +1 -0
- package/package.json +269 -80
- package/src/api-contract.ts +309 -0
- package/src/api.ts +181 -0
- package/src/app.ts +346 -0
- package/src/cli/catalog.ts +49 -0
- package/src/cli/help.ts +13 -0
- package/src/cli/init.ts +415 -0
- package/src/cli/parse.ts +130 -0
- package/src/cli/prompts.ts +64 -0
- package/src/cli.ts +203 -1507
- package/src/components/dev-view.tsx +104 -41
- package/src/components/streaming-view.ts +89 -22
- package/src/config.ts +462 -532
- package/src/contract.meta.ts +96 -0
- package/src/contract.ts +164 -561
- package/src/dev-logs.ts +85 -0
- package/src/dev-session.ts +318 -0
- package/src/fastkv.ts +153 -0
- package/src/federation.server.ts +43 -0
- package/src/host.ts +526 -0
- package/src/index.ts +6 -3
- package/src/integrity.ts +54 -0
- package/src/mf.ts +105 -0
- package/src/near-cli.ts +284 -0
- package/src/network.ts +3 -0
- package/src/orchestrator.ts +648 -0
- package/src/plugin.ts +1116 -2303
- package/src/process-registry.ts +154 -0
- package/src/scripts/sync-api-contract.ts +24 -0
- package/src/sdk.ts +14 -0
- package/src/shared.ts +206 -0
- package/src/types.ts +152 -206
- package/src/ui/head.ts +34 -27
- package/src/ui/index.ts +3 -3
- package/src/ui/metadata.ts +95 -0
- package/src/ui/router.ts +22 -6
- package/src/ui/runtime.ts +55 -6
- package/src/ui/types.ts +24 -11
- package/src/utils/banner.ts +10 -6
- package/src/utils/run.ts +26 -27
- package/src/utils/theme.ts +3 -66
- package/src/components/monitor-view.tsx +0 -475
- package/src/components/status-view.tsx +0 -173
- package/src/lib/env.ts +0 -109
- package/src/lib/near-cli.ts +0 -289
- package/src/lib/nova.ts +0 -266
- package/src/lib/orchestrator.ts +0 -276
- package/src/lib/process-registry.ts +0 -166
- package/src/lib/process.ts +0 -549
- package/src/lib/resource-monitor/assertions.ts +0 -234
- package/src/lib/resource-monitor/command.ts +0 -283
- package/src/lib/resource-monitor/diff.ts +0 -157
- package/src/lib/resource-monitor/errors.ts +0 -127
- package/src/lib/resource-monitor/index.ts +0 -305
- package/src/lib/resource-monitor/platform/darwin.ts +0 -306
- package/src/lib/resource-monitor/platform/index.ts +0 -35
- package/src/lib/resource-monitor/platform/linux.ts +0 -332
- package/src/lib/resource-monitor/platform/windows.ts +0 -298
- package/src/lib/resource-monitor/snapshot.ts +0 -217
- package/src/lib/resource-monitor/types.ts +0 -74
- package/src/lib/session-recorder/errors.ts +0 -102
- package/src/lib/session-recorder/flows/login.ts +0 -210
- package/src/lib/session-recorder/index.ts +0 -361
- package/src/lib/session-recorder/playwright.ts +0 -257
- package/src/lib/session-recorder/report.ts +0 -353
- package/src/lib/session-recorder/server.ts +0 -267
- package/src/lib/session-recorder/types.ts +0 -115
- package/src/lib/sync.ts +0 -1
- package/src/ui/files.ts +0 -134
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.cjs","names":["parsePort","getHostDevelopmentPort","Effect","getProjectRoot","Deferred","Ref","Fiber"],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { createConnection } from \"node:net\";\nimport { Deferred, Effect, Fiber, Ref } from \"effect\";\nimport { getHostDevelopmentPort, getProjectRoot, parsePort } from \"./config\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport type { ProcessRegistry } from \"./process-registry\";\nimport type { BosConfig, RuntimeConfig } from \"./types\";\n\nexport interface DevProcess {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n env?: Record<string, string>;\n port: number;\n readyPatterns: RegExp[];\n errorPatterns: RegExp[];\n}\n\nexport interface ProcessCallbacks {\n onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n name: string;\n pid: number | undefined;\n kill: () => Promise<void>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\ninterface ProcessConfigBase {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n readyPatterns: RegExp[];\n errorPatterns: RegExp[];\n}\n\nconst processConfigBases: Record<string, ProcessConfigBase> = {\n \"host-build\": {\n name: \"host-build\",\n command: \"bun\",\n args: [\"run\", \"build\"],\n cwd: \"host\",\n readyPatterns: [/built in/i, /compiled.*successfully/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n },\n host: {\n name: \"host\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"host\",\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n },\n ui: {\n name: \"ui\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"ui\",\n // Wait for the client build (mf) specifically, not just SSR.\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n },\n \"ui-ssr\": {\n name: \"ui-ssr\",\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n cwd: \"ui\",\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n },\n api: {\n name: \"api\",\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: \"api\",\n readyPatterns: [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i],\n errorPatterns: [/error/i, /failed/i],\n },\n};\n\nexport function getProcessConfig(\n pkg: string,\n env?: Record<string, string>,\n portOverride?: number,\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n): DevProcess | null {\n if (pkg.startsWith(\"plugin:\")) {\n const pluginId = pkg.slice(\"plugin:\".length);\n const pluginConfig = runtimeConfig?.plugins?.[pluginId] ?? null;\n const localPath = pluginConfig?.localPath;\n\n if (!localPath || pluginConfig?.source !== \"local\") return null;\n\n const port =\n portOverride ?? pluginConfig?.port ?? (pluginConfig?.url ? parsePort(pluginConfig.url) : 0);\n\n return {\n name: pkg,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n cwd: localPath,\n port,\n readyPatterns: [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i],\n errorPatterns: [/error/i, /failed/i],\n env,\n };\n }\n\n const base = processConfigBases[pkg];\n if (!base) return null;\n\n let port: number;\n if (pkg === \"host\") {\n port =\n portOverride ??\n (runtimeConfig?.hostUrl\n ? parsePort(runtimeConfig.hostUrl)\n : bosConfig\n ? getHostDevelopmentPort(bosConfig.app.host.development)\n : 3000);\n } else if (pkg === \"ui\") {\n port =\n runtimeConfig?.ui.port ?? (runtimeConfig?.ui.url ? parsePort(runtimeConfig.ui.url) : 3002);\n } else if (pkg === \"ui-ssr\") {\n const uiPort = runtimeConfig?.ui.ssrUrl\n ? parsePort(runtimeConfig.ui.ssrUrl)\n : runtimeConfig?.ui.port\n ? runtimeConfig.ui.port + 1\n : 3003;\n port = uiPort;\n } else if (pkg === \"api\") {\n port =\n runtimeConfig?.api.port ?? (runtimeConfig?.api.url ? parsePort(runtimeConfig.api.url) : 3014);\n } else {\n port = 0;\n }\n\n const cwd =\n pkg === \"ui\"\n ? (runtimeConfig?.ui.localPath ?? base.cwd)\n : pkg === \"api\"\n ? (runtimeConfig?.api.localPath ?? base.cwd)\n : base.cwd;\n\n return { ...base, cwd, port, env };\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = async (url: string, timeoutMs = 400): Promise<boolean> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n};\n\nconst probeTcpOpen = async (port: number, timeoutMs = 250): Promise<boolean> => {\n return new Promise((resolve) => {\n const socket = createConnection({ host: \"127.0.0.1\", port });\n const timer = setTimeout(() => {\n socket.destroy();\n resolve(false);\n }, timeoutMs);\n socket.once(\"connect\", () => {\n clearTimeout(timer);\n socket.destroy();\n resolve(true);\n });\n socket.once(\"error\", () => {\n clearTimeout(timer);\n resolve(false);\n });\n });\n};\n\nconst detectStatus = (\n line: string,\n config: DevProcess,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n for (const pattern of config.errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of config.readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\nconst killProcessTree = (pid: number) =>\n Effect.gen(function* () {\n const killSignal = (signal: NodeJS.Signals) =>\n Effect.try({\n try: () => {\n process.kill(-pid, signal);\n },\n catch: () => null,\n }).pipe(Effect.ignore);\n\n const killDirect = (signal: NodeJS.Signals) =>\n Effect.try({\n try: () => {\n process.kill(pid, signal);\n },\n catch: () => null,\n }).pipe(Effect.ignore);\n\n const isRunning = () =>\n Effect.try({\n try: () => {\n process.kill(pid, 0);\n return true;\n },\n catch: () => false,\n });\n\n yield* killSignal(\"SIGTERM\");\n yield* killDirect(\"SIGTERM\");\n\n yield* Effect.sleep(\"200 millis\");\n\n const stillRunning = yield* isRunning();\n if (stillRunning) {\n yield* killSignal(\"SIGKILL\");\n yield* killDirect(\"SIGKILL\");\n yield* Effect.sleep(\"100 millis\");\n }\n });\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n const originalLog = console.log;\n const originalError = console.error;\n const originalWarn = console.warn;\n const originalInfo = console.info;\n\n const formatArgs = (args: unknown[]): string => {\n return args\n .map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg)))\n .join(\" \");\n };\n\n console.log = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.error = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), true);\n };\n console.warn = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.info = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n\n return () => {\n console.log = originalLog;\n console.error = originalError;\n console.warn = originalWarn;\n console.info = originalInfo;\n };\n};\n\nexport const spawnRemoteHost = (\n config: DevProcess,\n callbacks: ProcessCallbacks,\n runtimeConfig: RuntimeConfig,\n) =>\n Effect.gen(function* () {\n const remoteUrl = config.env?.HOST_REMOTE_URL;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"HOST_REMOTE_URL not provided for remote host\"));\n }\n\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = value;\n }\n }\n\n callbacks.onStatus(config.name, \"starting\");\n callbacks.onLog(config.name, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(config.name, callbacks);\n callbacks.onLog(config.name, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const res = await fetch(manifestUrl);\n if (!res.ok) return remoteEntryUrl;\n const json = (await res.json()) as Record<string, unknown>;\n if (\n json &&\n typeof json === \"object\" &&\n \"metaData\" in json &&\n \"exposes\" in json &&\n \"shared\" in json\n ) {\n return manifestUrl;\n }\n } catch {}\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(config.name, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(config.name, \"Starting server...\");\n const serverHandle = hostModule.runServer({ config: runtimeConfig });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(config.name, \"ready\");\n\n return {\n name: config.name,\n pid: process.pid,\n kill: async () => {\n callbacks.onLog(config.name, \"Shutting down remote host...\");\n restoreConsole();\n await serverHandle.shutdown();\n },\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const spawnDevProcess = (\n config: DevProcess,\n callbacks: ProcessCallbacks,\n runtimeConfig?: RuntimeConfig,\n registry?: ProcessRegistry,\n) =>\n Effect.gen(function* () {\n let configDir: string;\n try {\n configDir = getProjectRoot();\n } catch {\n configDir = process.cwd();\n }\n const fullCwd = config.cwd.startsWith(\"/\") ? config.cwd : `${configDir}/${config.cwd}`;\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(config.name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n ...config.env,\n FORCE_COLOR: \"1\",\n ...(config.port > 0 ? { PORT: String(config.port) } : {}),\n };\n\n if (runtimeConfig && config.name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const proc = Bun.spawn({\n cmd: [config.command, ...config.args],\n cwd: fullCwd,\n env: envVars,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n callbacks.onStatus(config.name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n // Prefer probe-based readiness to avoid brittle log regexes.\n // This is best-effort and complements log detection.\n if (config.port > 0) {\n const readinessPath =\n config.name === \"host\" ? \"/health\" : config.name === \"ui-ssr\" ? \"/\" : \"/remoteEntry.js\";\n const url = `http://127.0.0.1:${config.port}${readinessPath}`;\n\n yield* Effect.fork(\n Effect.gen(function* () {\n const deadline = Date.now() + 90_000;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = url\n ? yield* Effect.tryPromise({\n try: () => probeHttpOk(url),\n catch: () => false,\n })\n : yield* Effect.tryPromise({\n try: () => probeTcpOpen(config.port),\n catch: () => false,\n });\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(\"200 millis\");\n }\n }),\n );\n }\n\n if (registry && proc.pid) {\n yield* registry.track({\n pid: proc.pid,\n name: config.name,\n port: config.port,\n startedAt: Date.now(),\n command: [config.command, ...config.args].join(\" \"),\n });\n }\n\n yield* Effect.fork(\n Effect.promise(() => proc.exited).pipe(\n Effect.andThen((code) =>\n Effect.gen(function* () {\n if (registry && proc.pid) {\n yield* registry.untrack(proc.pid).pipe(Effect.ignore);\n }\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\") return;\n callbacks.onLog(config.name, `Process exited before ready (exit code: ${code})`, true);\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(config.name, \"error\");\n yield* Deferred.fail(\n readyDeferred,\n new Error(`Process exited before ready: ${config.name}`),\n ).pipe(Effect.ignore);\n }),\n ),\n ),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n callbacks.onLog(config.name, line, isStderr);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\") return;\n\n const detected = detectStatus(line, config);\n if (detected) {\n yield* Ref.set(statusRef, detected.status);\n callbacks.onStatus(config.name, detected.status);\n if (detected.status === \"ready\" || detected.status === \"error\") {\n if (detected.status === \"ready\") {\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n } else {\n yield* Deferred.fail(readyDeferred, new Error(`Process failed: ${config.name}`)).pipe(\n Effect.ignore,\n );\n }\n }\n }\n });\n\n const decoder = new TextDecoder();\n\n const stdoutFiber = yield* Effect.fork(\n Effect.async<void>((resume) => {\n if (!proc.stdout) {\n resume(Effect.void);\n return;\n }\n const reader = proc.stdout.getReader();\n let buffer = \"\";\n\n const pump = (): Promise<void> =>\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer) {\n Effect.runSync(handleLine(buffer, false));\n }\n return;\n }\n buffer += decoder\n .decode(value, { stream: true })\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n Effect.runSync(handleLine(line, false));\n }\n return pump();\n });\n\n pump().then(() => resume(Effect.void));\n }),\n );\n\n const stderrFiber = yield* Effect.fork(\n Effect.async<void>((resume) => {\n if (!proc.stderr) {\n resume(Effect.void);\n return;\n }\n const reader = proc.stderr.getReader();\n let buffer = \"\";\n\n const pump = (): Promise<void> =>\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer) {\n Effect.runSync(handleLine(buffer, true));\n }\n return;\n }\n buffer += decoder\n .decode(value, { stream: true })\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\");\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n Effect.runSync(handleLine(line, true));\n }\n return pump();\n });\n\n pump().then(() => resume(Effect.void));\n }),\n );\n\n const handle: ProcessHandle = {\n name: config.name,\n pid: proc.pid,\n kill: async () => {\n const pid = proc.pid;\n if (pid) {\n await Effect.runPromise(killProcessTree(pid));\n } else {\n proc.kill(\"SIGTERM\");\n await new Promise((r) => setTimeout(r, 100));\n try {\n proc.kill(\"SIGKILL\");\n } catch {}\n }\n },\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.gen(function* () {\n yield* Fiber.joinAll([stdoutFiber, stderrFiber]);\n return yield* Effect.promise(() => proc.exited);\n }),\n };\n\n return handle;\n });\n\nexport const makeDevProcess = (\n pkg: string,\n env: Record<string, string> | undefined,\n callbacks: ProcessCallbacks,\n portOverride?: number,\n bosConfig?: BosConfig,\n runtimeConfig?: RuntimeConfig,\n registry?: ProcessRegistry,\n) =>\n Effect.gen(function* () {\n const config = getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig);\n if (!config) {\n return yield* Effect.fail(new Error(`Unknown package: ${pkg}`));\n }\n\n if (pkg === \"host\" && runtimeConfig) {\n if (env?.HOST_SOURCE === \"remote\") {\n return yield* spawnRemoteHost(config, callbacks, runtimeConfig);\n }\n return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);\n }\n\n return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);\n });\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BosConfig, RuntimeConfig } from "./types.cjs";
|
|
2
|
+
import { ProcessRegistry } from "./process-registry.cjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/orchestrator.d.ts
|
|
6
|
+
interface DevProcess {
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
args: string[];
|
|
10
|
+
cwd: string;
|
|
11
|
+
env?: Record<string, string>;
|
|
12
|
+
port: number;
|
|
13
|
+
readyPatterns: RegExp[];
|
|
14
|
+
errorPatterns: RegExp[];
|
|
15
|
+
}
|
|
16
|
+
interface ProcessCallbacks {
|
|
17
|
+
onStatus: (name: string, status: ProcessStatus, message?: string) => void;
|
|
18
|
+
onLog: (name: string, line: string, isError?: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
interface ProcessHandle {
|
|
21
|
+
name: string;
|
|
22
|
+
pid: number | undefined;
|
|
23
|
+
kill: () => Promise<void>;
|
|
24
|
+
waitForReady: Effect.Effect<void, Error>;
|
|
25
|
+
waitForExit: Effect.Effect<unknown>;
|
|
26
|
+
}
|
|
27
|
+
type ProcessStatus = "pending" | "starting" | "ready" | "error";
|
|
28
|
+
declare function getProcessConfig(pkg: string, env?: Record<string, string>, portOverride?: number, bosConfig?: BosConfig, runtimeConfig?: RuntimeConfig): DevProcess | null;
|
|
29
|
+
declare const spawnRemoteHost: (config: DevProcess, callbacks: ProcessCallbacks, runtimeConfig: RuntimeConfig) => Effect.Effect<{
|
|
30
|
+
name: string;
|
|
31
|
+
pid: number;
|
|
32
|
+
kill: () => Promise<void>;
|
|
33
|
+
waitForReady: Effect.Effect<undefined, never, never>;
|
|
34
|
+
waitForExit: Effect.Effect<never, never, never>;
|
|
35
|
+
}, string | Error, never>;
|
|
36
|
+
declare const spawnDevProcess: (config: DevProcess, callbacks: ProcessCallbacks, runtimeConfig?: RuntimeConfig, registry?: ProcessRegistry) => Effect.Effect<ProcessHandle, never, never>;
|
|
37
|
+
declare const makeDevProcess: (pkg: string, env: Record<string, string> | undefined, callbacks: ProcessCallbacks, portOverride?: number, bosConfig?: BosConfig, runtimeConfig?: RuntimeConfig, registry?: ProcessRegistry) => Effect.Effect<ProcessHandle, string | Error, never>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { DevProcess, ProcessCallbacks, ProcessHandle, ProcessStatus, getProcessConfig, makeDevProcess, spawnDevProcess, spawnRemoteHost };
|
|
40
|
+
//# sourceMappingURL=orchestrator.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.cts","names":[],"sources":["../src/orchestrator.ts"],"mappings":";;;;;UAOiB,UAAA;EACf,IAAA;EACA,OAAA;EACA,IAAA;EACA,GAAA;EACA,GAAA,GAAM,MAAA;EACN,IAAA;EACA,aAAA,EAAe,MAAA;EACf,aAAA,EAAe,MAAA;AAAA;AAAA,UAGA,gBAAA;EACf,QAAA,GAAW,IAAA,UAAc,MAAA,EAAQ,aAAA,EAAe,OAAA;EAChD,KAAA,GAAQ,IAAA,UAAc,IAAA,UAAc,OAAA;AAAA;AAAA,UAGrB,aAAA;EACf,IAAA;EACA,GAAA;EACA,IAAA,QAAY,OAAA;EACZ,YAAA,EAAc,MAAA,CAAO,MAAA,OAAa,KAAA;EAClC,WAAA,EAAa,MAAA,CAAO,MAAA;AAAA;AAAA,KAGV,aAAA;AAAA,iBAuDI,gBAAA,CACd,GAAA,UACA,GAAA,GAAM,MAAA,kBACN,YAAA,WACA,SAAA,GAAY,SAAA,EACZ,aAAA,GAAgB,aAAA,GACf,UAAA;AAAA,cA0MU,eAAA,GACX,MAAA,EAAQ,UAAA,EACR,SAAA,EAAW,gBAAA,EACX,aAAA,EAAe,aAAA,KAAa,MAAA,CAAA,MAAA;;;;;;;cAqGjB,eAAA,GACX,MAAA,EAAQ,UAAA,EACR,SAAA,EAAW,gBAAA,EACX,aAAA,GAAgB,aAAA,EAChB,QAAA,GAAW,eAAA,KAAe,MAAA,CAAA,MAAA,CAAA,aAAA;AAAA,cA8Nf,cAAA,GACX,GAAA,UACA,GAAA,EAAK,MAAA,8BACL,SAAA,EAAW,gBAAA,EACX,YAAA,WACA,SAAA,GAAY,SAAA,EACZ,aAAA,GAAgB,aAAA,EAChB,QAAA,GAAW,eAAA,KAAe,MAAA,CAAA,MAAA,CAAA,aAAA,WAAA,KAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BosConfig, RuntimeConfig } from "./types.mjs";
|
|
2
|
+
import { ProcessRegistry } from "./process-registry.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/orchestrator.d.ts
|
|
6
|
+
interface DevProcess {
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
args: string[];
|
|
10
|
+
cwd: string;
|
|
11
|
+
env?: Record<string, string>;
|
|
12
|
+
port: number;
|
|
13
|
+
readyPatterns: RegExp[];
|
|
14
|
+
errorPatterns: RegExp[];
|
|
15
|
+
}
|
|
16
|
+
interface ProcessCallbacks {
|
|
17
|
+
onStatus: (name: string, status: ProcessStatus, message?: string) => void;
|
|
18
|
+
onLog: (name: string, line: string, isError?: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
interface ProcessHandle {
|
|
21
|
+
name: string;
|
|
22
|
+
pid: number | undefined;
|
|
23
|
+
kill: () => Promise<void>;
|
|
24
|
+
waitForReady: Effect.Effect<void, Error>;
|
|
25
|
+
waitForExit: Effect.Effect<unknown>;
|
|
26
|
+
}
|
|
27
|
+
type ProcessStatus = "pending" | "starting" | "ready" | "error";
|
|
28
|
+
declare function getProcessConfig(pkg: string, env?: Record<string, string>, portOverride?: number, bosConfig?: BosConfig, runtimeConfig?: RuntimeConfig): DevProcess | null;
|
|
29
|
+
declare const spawnRemoteHost: (config: DevProcess, callbacks: ProcessCallbacks, runtimeConfig: RuntimeConfig) => Effect.Effect<{
|
|
30
|
+
name: string;
|
|
31
|
+
pid: number;
|
|
32
|
+
kill: () => Promise<void>;
|
|
33
|
+
waitForReady: Effect.Effect<undefined, never, never>;
|
|
34
|
+
waitForExit: Effect.Effect<never, never, never>;
|
|
35
|
+
}, string | Error, never>;
|
|
36
|
+
declare const spawnDevProcess: (config: DevProcess, callbacks: ProcessCallbacks, runtimeConfig?: RuntimeConfig, registry?: ProcessRegistry) => Effect.Effect<ProcessHandle, never, never>;
|
|
37
|
+
declare const makeDevProcess: (pkg: string, env: Record<string, string> | undefined, callbacks: ProcessCallbacks, portOverride?: number, bosConfig?: BosConfig, runtimeConfig?: RuntimeConfig, registry?: ProcessRegistry) => Effect.Effect<ProcessHandle, string | Error, never>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { DevProcess, ProcessCallbacks, ProcessHandle, ProcessStatus, getProcessConfig, makeDevProcess, spawnDevProcess, spawnRemoteHost };
|
|
40
|
+
//# sourceMappingURL=orchestrator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.mts","names":[],"sources":["../src/orchestrator.ts"],"mappings":";;;;;UAOiB,UAAA;EACf,IAAA;EACA,OAAA;EACA,IAAA;EACA,GAAA;EACA,GAAA,GAAM,MAAA;EACN,IAAA;EACA,aAAA,EAAe,MAAA;EACf,aAAA,EAAe,MAAA;AAAA;AAAA,UAGA,gBAAA;EACf,QAAA,GAAW,IAAA,UAAc,MAAA,EAAQ,aAAA,EAAe,OAAA;EAChD,KAAA,GAAQ,IAAA,UAAc,IAAA,UAAc,OAAA;AAAA;AAAA,UAGrB,aAAA;EACf,IAAA;EACA,GAAA;EACA,IAAA,QAAY,OAAA;EACZ,YAAA,EAAc,MAAA,CAAO,MAAA,OAAa,KAAA;EAClC,WAAA,EAAa,MAAA,CAAO,MAAA;AAAA;AAAA,KAGV,aAAA;AAAA,iBAuDI,gBAAA,CACd,GAAA,UACA,GAAA,GAAM,MAAA,kBACN,YAAA,WACA,SAAA,GAAY,SAAA,EACZ,aAAA,GAAgB,aAAA,GACf,UAAA;AAAA,cA0MU,eAAA,GACX,MAAA,EAAQ,UAAA,EACR,SAAA,EAAW,gBAAA,EACX,aAAA,EAAe,aAAA,KAAa,MAAA,CAAA,MAAA;;;;;;;cAqGjB,eAAA,GACX,MAAA,EAAQ,UAAA,EACR,SAAA,EAAW,gBAAA,EACX,aAAA,GAAgB,aAAA,EAChB,QAAA,GAAW,eAAA,KAAe,MAAA,CAAA,MAAA,CAAA,aAAA;AAAA,cA8Nf,cAAA,GACX,GAAA,UACA,GAAA,EAAK,MAAA,8BACL,SAAA,EAAW,gBAAA,EACX,YAAA,WACA,SAAA,GAAY,SAAA,EACZ,aAAA,GAAgB,aAAA,EAChB,QAAA,GAAW,eAAA,KAAe,MAAA,CAAA,MAAA,CAAA,aAAA,WAAA,KAAA"}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { getHostDevelopmentPort, getProjectRoot, parsePort } from "./config.mjs";
|
|
2
|
+
import { patchManifestFetchForSsrPublicPath } from "./mf.mjs";
|
|
3
|
+
import { Deferred, Effect, Fiber, Ref } from "effect";
|
|
4
|
+
import { createConnection } from "node:net";
|
|
5
|
+
|
|
6
|
+
//#region src/orchestrator.ts
|
|
7
|
+
const processConfigBases = {
|
|
8
|
+
"host-build": {
|
|
9
|
+
name: "host-build",
|
|
10
|
+
command: "bun",
|
|
11
|
+
args: ["run", "build"],
|
|
12
|
+
cwd: "host",
|
|
13
|
+
readyPatterns: [/built in/i, /compiled.*successfully/i],
|
|
14
|
+
errorPatterns: [
|
|
15
|
+
/error:/i,
|
|
16
|
+
/failed/i,
|
|
17
|
+
/exception/i
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
host: {
|
|
21
|
+
name: "host",
|
|
22
|
+
command: "bun",
|
|
23
|
+
args: ["run", "dev"],
|
|
24
|
+
cwd: "host",
|
|
25
|
+
readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],
|
|
26
|
+
errorPatterns: [
|
|
27
|
+
/error:/i,
|
|
28
|
+
/failed/i,
|
|
29
|
+
/exception/i
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
ui: {
|
|
33
|
+
name: "ui",
|
|
34
|
+
command: "bun",
|
|
35
|
+
args: ["run", "dev"],
|
|
36
|
+
cwd: "ui",
|
|
37
|
+
readyPatterns: [
|
|
38
|
+
/\bready\s+built in\b/i,
|
|
39
|
+
/\bLocal:\b/i,
|
|
40
|
+
/\bcompiled\b.*successfully/i
|
|
41
|
+
],
|
|
42
|
+
errorPatterns: [/error/i, /failed to compile/i]
|
|
43
|
+
},
|
|
44
|
+
"ui-ssr": {
|
|
45
|
+
name: "ui-ssr",
|
|
46
|
+
command: "bun",
|
|
47
|
+
args: ["run", "dev:ssr"],
|
|
48
|
+
cwd: "ui",
|
|
49
|
+
readyPatterns: [/\bready\s+built in\b/i, /\bcompiled\b.*successfully/i],
|
|
50
|
+
errorPatterns: [/error/i, /failed/i]
|
|
51
|
+
},
|
|
52
|
+
api: {
|
|
53
|
+
name: "api",
|
|
54
|
+
command: "bun",
|
|
55
|
+
args: ["run", "dev"],
|
|
56
|
+
cwd: "api",
|
|
57
|
+
readyPatterns: [
|
|
58
|
+
/ready in/i,
|
|
59
|
+
/compiled.*successfully/i,
|
|
60
|
+
/listening/i,
|
|
61
|
+
/started/i
|
|
62
|
+
],
|
|
63
|
+
errorPatterns: [/error/i, /failed/i]
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig) {
|
|
67
|
+
if (pkg.startsWith("plugin:")) {
|
|
68
|
+
const pluginId = pkg.slice(7);
|
|
69
|
+
const pluginConfig = runtimeConfig?.plugins?.[pluginId] ?? null;
|
|
70
|
+
const localPath = pluginConfig?.localPath;
|
|
71
|
+
if (!localPath || pluginConfig?.source !== "local") return null;
|
|
72
|
+
return {
|
|
73
|
+
name: pkg,
|
|
74
|
+
command: "bun",
|
|
75
|
+
args: ["run", "dev"],
|
|
76
|
+
cwd: localPath,
|
|
77
|
+
port: portOverride ?? pluginConfig?.port ?? (pluginConfig?.url ? parsePort(pluginConfig.url) : 0),
|
|
78
|
+
readyPatterns: [
|
|
79
|
+
/ready in/i,
|
|
80
|
+
/compiled.*successfully/i,
|
|
81
|
+
/listening/i,
|
|
82
|
+
/started/i
|
|
83
|
+
],
|
|
84
|
+
errorPatterns: [/error/i, /failed/i],
|
|
85
|
+
env
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const base = processConfigBases[pkg];
|
|
89
|
+
if (!base) return null;
|
|
90
|
+
let port;
|
|
91
|
+
if (pkg === "host") port = portOverride ?? (runtimeConfig?.hostUrl ? parsePort(runtimeConfig.hostUrl) : bosConfig ? getHostDevelopmentPort(bosConfig.app.host.development) : 3e3);
|
|
92
|
+
else if (pkg === "ui") port = runtimeConfig?.ui.port ?? (runtimeConfig?.ui.url ? parsePort(runtimeConfig.ui.url) : 3002);
|
|
93
|
+
else if (pkg === "ui-ssr") port = runtimeConfig?.ui.ssrUrl ? parsePort(runtimeConfig.ui.ssrUrl) : runtimeConfig?.ui.port ? runtimeConfig.ui.port + 1 : 3003;
|
|
94
|
+
else if (pkg === "api") port = runtimeConfig?.api.port ?? (runtimeConfig?.api.url ? parsePort(runtimeConfig.api.url) : 3014);
|
|
95
|
+
else port = 0;
|
|
96
|
+
const cwd = pkg === "ui" ? runtimeConfig?.ui.localPath ?? base.cwd : pkg === "api" ? runtimeConfig?.api.localPath ?? base.cwd : base.cwd;
|
|
97
|
+
return {
|
|
98
|
+
...base,
|
|
99
|
+
cwd,
|
|
100
|
+
port,
|
|
101
|
+
env
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const stripAnsi = (input) => {
|
|
105
|
+
const ESC = String.fromCharCode(27);
|
|
106
|
+
const BEL = String.fromCharCode(7);
|
|
107
|
+
return input.replace(new RegExp(`${ESC}\\][^${BEL}]*${BEL}`, "g"), "").replace(new RegExp(`${ESC}\\[[0-?]*[ -/]*[@-~]`, "g"), "");
|
|
108
|
+
};
|
|
109
|
+
const probeHttpOk = async (url, timeoutMs = 400) => {
|
|
110
|
+
const controller = new AbortController();
|
|
111
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
112
|
+
try {
|
|
113
|
+
return (await fetch(url, { signal: controller.signal })).ok;
|
|
114
|
+
} catch {
|
|
115
|
+
return false;
|
|
116
|
+
} finally {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const probeTcpOpen = async (port, timeoutMs = 250) => {
|
|
121
|
+
return new Promise((resolve) => {
|
|
122
|
+
const socket = createConnection({
|
|
123
|
+
host: "127.0.0.1",
|
|
124
|
+
port
|
|
125
|
+
});
|
|
126
|
+
const timer = setTimeout(() => {
|
|
127
|
+
socket.destroy();
|
|
128
|
+
resolve(false);
|
|
129
|
+
}, timeoutMs);
|
|
130
|
+
socket.once("connect", () => {
|
|
131
|
+
clearTimeout(timer);
|
|
132
|
+
socket.destroy();
|
|
133
|
+
resolve(true);
|
|
134
|
+
});
|
|
135
|
+
socket.once("error", () => {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
resolve(false);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
const detectStatus = (line, config) => {
|
|
142
|
+
const cleanLine = stripAnsi(line);
|
|
143
|
+
for (const pattern of config.errorPatterns) if (pattern.test(cleanLine)) return {
|
|
144
|
+
status: "error",
|
|
145
|
+
isError: true
|
|
146
|
+
};
|
|
147
|
+
for (const pattern of config.readyPatterns) if (pattern.test(cleanLine)) return {
|
|
148
|
+
status: "ready",
|
|
149
|
+
isError: false
|
|
150
|
+
};
|
|
151
|
+
return null;
|
|
152
|
+
};
|
|
153
|
+
const killProcessTree = (pid) => Effect.gen(function* () {
|
|
154
|
+
const killSignal = (signal) => Effect.try({
|
|
155
|
+
try: () => {
|
|
156
|
+
process.kill(-pid, signal);
|
|
157
|
+
},
|
|
158
|
+
catch: () => null
|
|
159
|
+
}).pipe(Effect.ignore);
|
|
160
|
+
const killDirect = (signal) => Effect.try({
|
|
161
|
+
try: () => {
|
|
162
|
+
process.kill(pid, signal);
|
|
163
|
+
},
|
|
164
|
+
catch: () => null
|
|
165
|
+
}).pipe(Effect.ignore);
|
|
166
|
+
const isRunning = () => Effect.try({
|
|
167
|
+
try: () => {
|
|
168
|
+
process.kill(pid, 0);
|
|
169
|
+
return true;
|
|
170
|
+
},
|
|
171
|
+
catch: () => false
|
|
172
|
+
});
|
|
173
|
+
yield* killSignal("SIGTERM");
|
|
174
|
+
yield* killDirect("SIGTERM");
|
|
175
|
+
yield* Effect.sleep("200 millis");
|
|
176
|
+
if (yield* isRunning()) {
|
|
177
|
+
yield* killSignal("SIGKILL");
|
|
178
|
+
yield* killDirect("SIGKILL");
|
|
179
|
+
yield* Effect.sleep("100 millis");
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const patchConsole = (name, callbacks) => {
|
|
183
|
+
const originalLog = console.log;
|
|
184
|
+
const originalError = console.error;
|
|
185
|
+
const originalWarn = console.warn;
|
|
186
|
+
const originalInfo = console.info;
|
|
187
|
+
const formatArgs = (args) => {
|
|
188
|
+
return args.map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ");
|
|
189
|
+
};
|
|
190
|
+
console.log = (...args) => {
|
|
191
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
192
|
+
};
|
|
193
|
+
console.error = (...args) => {
|
|
194
|
+
callbacks.onLog(name, formatArgs(args), true);
|
|
195
|
+
};
|
|
196
|
+
console.warn = (...args) => {
|
|
197
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
198
|
+
};
|
|
199
|
+
console.info = (...args) => {
|
|
200
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
201
|
+
};
|
|
202
|
+
return () => {
|
|
203
|
+
console.log = originalLog;
|
|
204
|
+
console.error = originalError;
|
|
205
|
+
console.warn = originalWarn;
|
|
206
|
+
console.info = originalInfo;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
const spawnRemoteHost = (config, callbacks, runtimeConfig) => Effect.gen(function* () {
|
|
210
|
+
const remoteUrl = config.env?.HOST_REMOTE_URL;
|
|
211
|
+
if (!remoteUrl) return yield* Effect.fail(/* @__PURE__ */ new Error("HOST_REMOTE_URL not provided for remote host"));
|
|
212
|
+
if (config.env) for (const [key, value] of Object.entries(config.env)) process.env[key] = value;
|
|
213
|
+
callbacks.onStatus(config.name, "starting");
|
|
214
|
+
callbacks.onLog(config.name, `Remote: ${remoteUrl}`);
|
|
215
|
+
const restoreConsole = patchConsole(config.name, callbacks);
|
|
216
|
+
callbacks.onLog(config.name, "Loading Module Federation runtime...");
|
|
217
|
+
const mfRuntime = yield* Effect.tryPromise({
|
|
218
|
+
try: () => import("@module-federation/enhanced/runtime"),
|
|
219
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load MF runtime: ${e}`)
|
|
220
|
+
});
|
|
221
|
+
const mfCore = yield* Effect.tryPromise({
|
|
222
|
+
try: () => import("@module-federation/runtime-core"),
|
|
223
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load MF core: ${e}`)
|
|
224
|
+
});
|
|
225
|
+
let mf = mfRuntime.getInstance();
|
|
226
|
+
if (!mf) {
|
|
227
|
+
mf = mfRuntime.createInstance({
|
|
228
|
+
name: "cli-host",
|
|
229
|
+
remotes: []
|
|
230
|
+
});
|
|
231
|
+
mfCore.setGlobalFederationInstance(mf);
|
|
232
|
+
}
|
|
233
|
+
patchManifestFetchForSsrPublicPath(mf);
|
|
234
|
+
const baseUrl = remoteUrl.replace(/\/remoteEntry\.js$/, "").replace(/\/mf-manifest\.json$/, "").replace(/\/$/, "");
|
|
235
|
+
const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;
|
|
236
|
+
const manifestUrl = `${baseUrl}/mf-manifest.json`;
|
|
237
|
+
const entryUrl = yield* Effect.tryPromise({
|
|
238
|
+
try: async () => {
|
|
239
|
+
try {
|
|
240
|
+
const res = await fetch(manifestUrl);
|
|
241
|
+
if (!res.ok) return remoteEntryUrl;
|
|
242
|
+
const json = await res.json();
|
|
243
|
+
if (json && typeof json === "object" && "metaData" in json && "exposes" in json && "shared" in json) return manifestUrl;
|
|
244
|
+
} catch {}
|
|
245
|
+
return remoteEntryUrl;
|
|
246
|
+
},
|
|
247
|
+
catch: () => remoteEntryUrl
|
|
248
|
+
});
|
|
249
|
+
mf.registerRemotes([{
|
|
250
|
+
name: "host",
|
|
251
|
+
entry: entryUrl
|
|
252
|
+
}]);
|
|
253
|
+
callbacks.onLog(config.name, `Loading host from ${entryUrl}...`);
|
|
254
|
+
const hostModule = yield* Effect.tryPromise({
|
|
255
|
+
try: () => mf.loadRemote("host/Server"),
|
|
256
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load host module: ${e}`)
|
|
257
|
+
});
|
|
258
|
+
if (!hostModule?.runServer) return yield* Effect.fail(/* @__PURE__ */ new Error("Host module does not export runServer function"));
|
|
259
|
+
callbacks.onLog(config.name, "Starting server...");
|
|
260
|
+
const serverHandle = hostModule.runServer({ config: runtimeConfig });
|
|
261
|
+
yield* Effect.tryPromise({
|
|
262
|
+
try: () => serverHandle.ready,
|
|
263
|
+
catch: (e) => /* @__PURE__ */ new Error(`Server failed to start: ${e}`)
|
|
264
|
+
});
|
|
265
|
+
callbacks.onStatus(config.name, "ready");
|
|
266
|
+
return {
|
|
267
|
+
name: config.name,
|
|
268
|
+
pid: process.pid,
|
|
269
|
+
kill: async () => {
|
|
270
|
+
callbacks.onLog(config.name, "Shutting down remote host...");
|
|
271
|
+
restoreConsole();
|
|
272
|
+
await serverHandle.shutdown();
|
|
273
|
+
},
|
|
274
|
+
waitForReady: Effect.succeed(void 0),
|
|
275
|
+
waitForExit: Effect.never
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
const spawnDevProcess = (config, callbacks, runtimeConfig, registry) => Effect.gen(function* () {
|
|
279
|
+
let configDir;
|
|
280
|
+
try {
|
|
281
|
+
configDir = getProjectRoot();
|
|
282
|
+
} catch {
|
|
283
|
+
configDir = process.cwd();
|
|
284
|
+
}
|
|
285
|
+
const fullCwd = config.cwd.startsWith("/") ? config.cwd : `${configDir}/${config.cwd}`;
|
|
286
|
+
const readyDeferred = yield* Deferred.make();
|
|
287
|
+
const statusRef = yield* Ref.make("starting");
|
|
288
|
+
callbacks.onStatus(config.name, "starting");
|
|
289
|
+
const envVars = {
|
|
290
|
+
...process.env,
|
|
291
|
+
...config.env,
|
|
292
|
+
FORCE_COLOR: "1",
|
|
293
|
+
...config.port > 0 ? { PORT: String(config.port) } : {}
|
|
294
|
+
};
|
|
295
|
+
if (runtimeConfig && config.name === "host") envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);
|
|
296
|
+
const proc = Bun.spawn({
|
|
297
|
+
cmd: [config.command, ...config.args],
|
|
298
|
+
cwd: fullCwd,
|
|
299
|
+
env: envVars,
|
|
300
|
+
stdio: [
|
|
301
|
+
"inherit",
|
|
302
|
+
"pipe",
|
|
303
|
+
"pipe"
|
|
304
|
+
]
|
|
305
|
+
});
|
|
306
|
+
const markReady = Effect.gen(function* () {
|
|
307
|
+
const currentStatus = yield* Ref.get(statusRef);
|
|
308
|
+
if (currentStatus === "ready" || currentStatus === "error") return;
|
|
309
|
+
yield* Ref.set(statusRef, "ready");
|
|
310
|
+
callbacks.onStatus(config.name, "ready");
|
|
311
|
+
yield* Deferred.succeed(readyDeferred, void 0).pipe(Effect.ignore);
|
|
312
|
+
});
|
|
313
|
+
if (config.port > 0) {
|
|
314
|
+
const readinessPath = config.name === "host" ? "/health" : config.name === "ui-ssr" ? "/" : "/remoteEntry.js";
|
|
315
|
+
const url = `http://127.0.0.1:${config.port}${readinessPath}`;
|
|
316
|
+
yield* Effect.fork(Effect.gen(function* () {
|
|
317
|
+
const deadline = Date.now() + 9e4;
|
|
318
|
+
while (Date.now() < deadline) {
|
|
319
|
+
const status = yield* Ref.get(statusRef);
|
|
320
|
+
if (status === "ready" || status === "error") return;
|
|
321
|
+
if (url ? yield* Effect.tryPromise({
|
|
322
|
+
try: () => probeHttpOk(url),
|
|
323
|
+
catch: () => false
|
|
324
|
+
}) : yield* Effect.tryPromise({
|
|
325
|
+
try: () => probeTcpOpen(config.port),
|
|
326
|
+
catch: () => false
|
|
327
|
+
})) {
|
|
328
|
+
yield* markReady;
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
yield* Effect.sleep("200 millis");
|
|
332
|
+
}
|
|
333
|
+
}));
|
|
334
|
+
}
|
|
335
|
+
if (registry && proc.pid) yield* registry.track({
|
|
336
|
+
pid: proc.pid,
|
|
337
|
+
name: config.name,
|
|
338
|
+
port: config.port,
|
|
339
|
+
startedAt: Date.now(),
|
|
340
|
+
command: [config.command, ...config.args].join(" ")
|
|
341
|
+
});
|
|
342
|
+
yield* Effect.fork(Effect.promise(() => proc.exited).pipe(Effect.andThen((code) => Effect.gen(function* () {
|
|
343
|
+
if (registry && proc.pid) yield* registry.untrack(proc.pid).pipe(Effect.ignore);
|
|
344
|
+
if ((yield* Ref.get(statusRef)) === "ready") return;
|
|
345
|
+
callbacks.onLog(config.name, `Process exited before ready (exit code: ${code})`, true);
|
|
346
|
+
yield* Ref.set(statusRef, "error");
|
|
347
|
+
callbacks.onStatus(config.name, "error");
|
|
348
|
+
yield* Deferred.fail(readyDeferred, /* @__PURE__ */ new Error(`Process exited before ready: ${config.name}`)).pipe(Effect.ignore);
|
|
349
|
+
}))));
|
|
350
|
+
const handleLine = (line, isStderr) => Effect.gen(function* () {
|
|
351
|
+
if (!line.trim()) return;
|
|
352
|
+
callbacks.onLog(config.name, line, isStderr);
|
|
353
|
+
if ((yield* Ref.get(statusRef)) === "ready") return;
|
|
354
|
+
const detected = detectStatus(line, config);
|
|
355
|
+
if (detected) {
|
|
356
|
+
yield* Ref.set(statusRef, detected.status);
|
|
357
|
+
callbacks.onStatus(config.name, detected.status);
|
|
358
|
+
if (detected.status === "ready" || detected.status === "error") if (detected.status === "ready") yield* Deferred.succeed(readyDeferred, void 0).pipe(Effect.ignore);
|
|
359
|
+
else yield* Deferred.fail(readyDeferred, /* @__PURE__ */ new Error(`Process failed: ${config.name}`)).pipe(Effect.ignore);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
const decoder = new TextDecoder();
|
|
363
|
+
const stdoutFiber = yield* Effect.fork(Effect.async((resume) => {
|
|
364
|
+
if (!proc.stdout) {
|
|
365
|
+
resume(Effect.void);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const reader = proc.stdout.getReader();
|
|
369
|
+
let buffer = "";
|
|
370
|
+
const pump = () => reader.read().then(({ done, value }) => {
|
|
371
|
+
if (done) {
|
|
372
|
+
if (buffer) Effect.runSync(handleLine(buffer, false));
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
376
|
+
const lines = buffer.split("\n");
|
|
377
|
+
buffer = lines.pop() ?? "";
|
|
378
|
+
for (const line of lines) Effect.runSync(handleLine(line, false));
|
|
379
|
+
return pump();
|
|
380
|
+
});
|
|
381
|
+
pump().then(() => resume(Effect.void));
|
|
382
|
+
}));
|
|
383
|
+
const stderrFiber = yield* Effect.fork(Effect.async((resume) => {
|
|
384
|
+
if (!proc.stderr) {
|
|
385
|
+
resume(Effect.void);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const reader = proc.stderr.getReader();
|
|
389
|
+
let buffer = "";
|
|
390
|
+
const pump = () => reader.read().then(({ done, value }) => {
|
|
391
|
+
if (done) {
|
|
392
|
+
if (buffer) Effect.runSync(handleLine(buffer, true));
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
396
|
+
const lines = buffer.split("\n");
|
|
397
|
+
buffer = lines.pop() ?? "";
|
|
398
|
+
for (const line of lines) Effect.runSync(handleLine(line, true));
|
|
399
|
+
return pump();
|
|
400
|
+
});
|
|
401
|
+
pump().then(() => resume(Effect.void));
|
|
402
|
+
}));
|
|
403
|
+
return {
|
|
404
|
+
name: config.name,
|
|
405
|
+
pid: proc.pid,
|
|
406
|
+
kill: async () => {
|
|
407
|
+
const pid = proc.pid;
|
|
408
|
+
if (pid) await Effect.runPromise(killProcessTree(pid));
|
|
409
|
+
else {
|
|
410
|
+
proc.kill("SIGTERM");
|
|
411
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
412
|
+
try {
|
|
413
|
+
proc.kill("SIGKILL");
|
|
414
|
+
} catch {}
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
waitForReady: Deferred.await(readyDeferred),
|
|
418
|
+
waitForExit: Effect.gen(function* () {
|
|
419
|
+
yield* Fiber.joinAll([stdoutFiber, stderrFiber]);
|
|
420
|
+
return yield* Effect.promise(() => proc.exited);
|
|
421
|
+
})
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
const makeDevProcess = (pkg, env, callbacks, portOverride, bosConfig, runtimeConfig, registry) => Effect.gen(function* () {
|
|
425
|
+
const config = getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig);
|
|
426
|
+
if (!config) return yield* Effect.fail(/* @__PURE__ */ new Error(`Unknown package: ${pkg}`));
|
|
427
|
+
if (pkg === "host" && runtimeConfig) {
|
|
428
|
+
if (env?.HOST_SOURCE === "remote") return yield* spawnRemoteHost(config, callbacks, runtimeConfig);
|
|
429
|
+
return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);
|
|
430
|
+
}
|
|
431
|
+
return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
//#endregion
|
|
435
|
+
export { getProcessConfig, makeDevProcess, spawnDevProcess, spawnRemoteHost };
|
|
436
|
+
//# sourceMappingURL=orchestrator.mjs.map
|