{"version":3,"file":"orchestrator.mjs","names":[],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n  DevRuntimeConfig,\n  type ServiceDescriptor,\n  ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nprocess.on(\"unhandledRejection\", (reason) => {\n  console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n  console.error(\"[Orchestrator] Uncaught exception:\", err);\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: Effect.Effect<void, unknown>;\n  waitForReady: Effect.Effect<void, Error>;\n  waitForExit: Effect.Effect<ExitCode, unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n  name: string;\n  status: ProcessStatus;\n  port: number;\n  message?: string;\n  source?: \"local\" | \"remote\";\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 = (url: string, timeoutMs = 400) =>\n  Effect.tryPromise({\n    try: async () => {\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    catch: () => false,\n  });\n\nconst detectStatus = (\n  line: string,\n  descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n  const cleanLine = stripAnsi(line);\n  const errorPatterns = descriptor.errorPatterns ?? [];\n  const readyPatterns = descriptor.readyPatterns ?? [];\n  for (const pattern of errorPatterns) {\n    if (pattern.test(cleanLine)) {\n      return { status: \"error\", isError: true };\n    }\n  }\n  for (const pattern of readyPatterns) {\n    if (pattern.test(cleanLine)) {\n      return { status: \"ready\", isError: false };\n    }\n  }\n  return null;\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[], isError = false): string => {\n    return args\n      .map((arg) => {\n        if (arg instanceof Error) {\n          const parts = [`${arg.name}: ${arg.message}`];\n          if (arg.cause instanceof Error)\n            parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n          else if (arg.cause) parts.push(`(cause: ${String(arg.cause)})`);\n          if (isError && arg.stack) parts.push(arg.stack);\n          return parts.join(\"\\n\");\n        }\n        return typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg);\n      })\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), 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\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n  Effect.gen(function* () {\n    const runtimeConfig = yield* DevRuntimeConfig;\n    const remoteUrl = descriptor.remoteUrl;\n    if (!remoteUrl) {\n      return yield* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\n    }\n\n    callbacks.onStatus(descriptor.key, \"starting\");\n    callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n    const restoreConsole = patchConsole(descriptor.key, callbacks);\n    callbacks.onLog(descriptor.key, \"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(descriptor.key, `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(descriptor.key, \"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(descriptor.key, \"ready\");\n\n    return {\n      name: descriptor.key,\n      pid: process.pid,\n      kill: Effect.gen(function* () {\n        callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n        restoreConsole();\n        yield* Effect.tryPromise({\n          try: () => serverHandle.shutdown(),\n          catch: () => {},\n        }).pipe(Effect.ignore);\n      }),\n      waitForReady: Effect.succeed(undefined),\n      waitForExit: Effect.never,\n    } satisfies ProcessHandle;\n  });\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n  Effect.gen(function* () {\n    const runtimeConfig = yield* DevRuntimeConfig;\n\n    if (!descriptor.localPath) {\n      return yield* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n    }\n\n    const fullCwd = descriptor.localPath;\n    const command = descriptor.command ?? \"bun\";\n    const args = descriptor.args ?? [\"run\", \"dev\"];\n    const port = descriptor.port ?? descriptor.defaultPort;\n    const name = descriptor.key;\n\n    const readyDeferred = yield* Deferred.make<void, Error>();\n    const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n    callbacks.onStatus(name, \"starting\");\n\n    const envVars: Record<string, string> = {\n      ...(process.env as Record<string, string>),\n      FORCE_COLOR: \"1\",\n      ...(port > 0 ? { PORT: String(port) } : {}),\n    };\n\n    if (name === \"host\") {\n      envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n    }\n\n    const cmd = Command.make(command, ...args).pipe(\n      Command.workingDirectory(fullCwd),\n      Command.env(envVars),\n    );\n\n    const proc = yield* Command.start(cmd);\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(name, \"ready\");\n      yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n    });\n\n    if (port > 0) {\n      const readinessPath = descriptor.readinessPath;\n      const url = `http://127.0.0.1:${port}${readinessPath}`;\n\n      yield* Effect.forkScoped(\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 = yield* probeHttpOk(url);\n            if (ok) {\n              yield* markReady;\n              return;\n            }\n            yield* Effect.sleep(\"200 millis\");\n          }\n        }),\n      );\n    }\n\n    const pid = Number(proc.pid);\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const exitCode = yield* proc.exitCode;\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n        callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n        yield* Ref.set(statusRef, \"error\");\n        callbacks.onStatus(name, \"error\");\n        yield* Deferred.fail(readyDeferred, new Error(`Process exited before ready: ${name}`)).pipe(\n          Effect.ignore,\n        );\n      }),\n    );\n\n    const handleLine = (line: string, isStderr: boolean) =>\n      Effect.gen(function* () {\n        if (!line.trim()) return;\n\n        const cleanLine = stripAnsi(line);\n        const looksLikeError =\n          isStderr &&\n          /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n          !/^\\$/.test(cleanLine);\n        callbacks.onLog(name, line, looksLikeError);\n\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n\n        const detected = detectStatus(line, descriptor);\n        if (detected) {\n          yield* Ref.set(statusRef, detected.status);\n          callbacks.onStatus(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: ${name}`)).pipe(\n                Effect.ignore,\n              );\n            }\n          }\n        }\n      });\n\n    yield* Effect.forkScoped(\n      Stream.runForEach((line: string) => handleLine(line, false))(\n        Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n      ),\n    );\n\n    yield* Effect.forkScoped(\n      Stream.runForEach((line: string) => handleLine(line, true))(\n        Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n      ),\n    );\n\n    return {\n      name,\n      pid,\n      kill: Effect.gen(function* () {\n        const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n        if (Option.isNone(result)) {\n          const pid = Number(proc.pid);\n          yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n          yield* Effect.sleep(\"250 millis\");\n        }\n      }).pipe(Effect.ignore),\n      waitForReady: Deferred.await(readyDeferred),\n      waitForExit: proc.exitCode,\n    } satisfies ProcessHandle;\n  });\n\nconst spawnRemoteProbe = (\n  pkg: string,\n  descriptor: ServiceDescriptor,\n  callbacks: ProcessCallbacks,\n) =>\n  Effect.gen(function* () {\n    callbacks.onStatus(pkg, \"starting\");\n    const readyDeferred = yield* Deferred.make<void, Error>();\n    const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n    const markReady = Effect.gen(function* () {\n      yield* Ref.set(statusRef, \"ready\");\n      yield* Deferred.succeed(readyDeferred, undefined);\n      callbacks.onStatus(pkg, \"ready\", \"loaded\");\n    });\n\n    const markError = Effect.gen(function* () {\n      yield* Ref.set(statusRef, \"error\");\n      yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`));\n      callbacks.onStatus(pkg, \"error\", \"unreachable\");\n    });\n\n    const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n    const manifestUrl = `${baseUrl}/mf-manifest.json`;\n    const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n    const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const deadline = Date.now() + 60_000;\n        while (Date.now() < deadline) {\n          const status = yield* Ref.get(statusRef);\n          if (status === \"ready\" || status === \"error\") return;\n\n          const ok = yield* probeHttpOk(probeUrl, 400);\n\n          if (ok) {\n            yield* markReady;\n            return;\n          }\n\n          const fallbackOk = yield* probeHttpOk(entryUrl, 400);\n\n          if (fallbackOk) {\n            yield* markReady;\n            return;\n          }\n\n          yield* Effect.sleep(\"500 millis\");\n        }\n\n        const status = yield* Ref.get(statusRef);\n        if (status !== \"ready\") {\n          yield* markError;\n        }\n      }),\n    );\n\n    return {\n      name: pkg,\n      pid: undefined,\n      kill: Effect.gen(function* () {\n        yield* Ref.set(statusRef, \"error\");\n        yield* Deferred.fail(readyDeferred, new Error(\"Killed\")).pipe(Effect.ignore);\n      }),\n      waitForReady: Deferred.await(readyDeferred),\n      waitForExit: Effect.never,\n    } satisfies ProcessHandle;\n  });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n  Effect.gen(function* () {\n    const services = yield* ServiceDescriptorMap;\n    const descriptor = services.get(pkg);\n\n    if (!descriptor) {\n      callbacks.onStatus(pkg, \"ready\", \"Remote\");\n      return {\n        name: pkg,\n        pid: undefined,\n        kill: Effect.void,\n        waitForReady: Effect.void,\n        waitForExit: Effect.never,\n      } satisfies ProcessHandle;\n    }\n\n    if (pkg === \"host\" && descriptor.source === \"remote\") {\n      return yield* spawnRemoteHost(descriptor, callbacks);\n    }\n\n    if (descriptor.source === \"remote\" || !descriptor.localPath) {\n      return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n    }\n\n    const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n    return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n  });\n\nexport function getProcessStates(\n  packages: string[],\n  services: Map<string, ServiceDescriptor>,\n  portOverride?: number,\n): ProcessState[] {\n  return packages.map((pkg) => {\n    const descriptor = services.get(pkg);\n    return {\n      name: pkg,\n      status: \"pending\" as const,\n      port:\n        portOverride && pkg === \"host\"\n          ? portOverride\n          : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n      source: descriptor?.source,\n    };\n  });\n}\n"],"mappings":"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"}