{"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 LOCAL_PROBE_DEADLINE_MS = 90_000;\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\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  port?: number;\n  env?: Record<string, string>;\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 controller = new AbortController();\n          const timer = setTimeout(() => controller.abort(), 10_000);\n          let res: Response;\n          try {\n            res = await fetch(manifestUrl, { signal: controller.signal });\n          } finally {\n            clearTimeout(timer);\n          }\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 (e) {\n          console.warn(\n            `[Orchestrator] Failed to fetch or parse manifest from ${manifestUrl}, falling back to remoteEntryUrl: ${e}`,\n          );\n        }\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 hostPort = runtimeConfig.host?.port;\n    const hostEnv: Record<string, string> | undefined = hostPort\n      ? { PORT: String(hostPort) }\n      : undefined;\n    const serverHandle = hostModule.runServer({\n      config: runtimeConfig,\n      port: hostPort,\n      env: hostEnv,\n    });\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    const markError = (message: string) =>\n      Effect.gen(function* () {\n        const currentStatus = yield* Ref.get(statusRef);\n        if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n        yield* Ref.set(statusRef, \"error\");\n        callbacks.onStatus(name, \"error\");\n        yield* Deferred.fail(readyDeferred, new Error(message)).pipe(Effect.ignore);\n      });\n\n    yield* Effect.forkScoped(\n      Effect.gen(function* () {\n        const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;\n\n        if (port > 0) {\n          const readinessPath = descriptor.readinessPath;\n          const url = `http://127.0.0.1:${port}${readinessPath}`;\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(`${LOCAL_PROBE_INTERVAL_MS} millis`);\n          }\n        } else {\n          while (Date.now() < deadline) {\n            const status = yield* Ref.get(statusRef);\n            if (status === \"ready\" || status === \"error\") return;\n            yield* Effect.sleep(\"500 millis\");\n          }\n        }\n\n        const status = yield* Ref.get(statusRef);\n        if (status !== \"ready\" && status !== \"error\") {\n          callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n          yield* markError(`Probe deadline exceeded: ${name}`);\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* markError(`Process exited before ready: ${name}`);\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          if (detected.status === \"ready\") {\n            yield* markReady;\n          } else {\n            yield* markError(`Process failed: ${name}`);\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      const currentStatus = yield* Ref.get(statusRef);\n      if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n      yield* Ref.set(statusRef, \"ready\");\n      yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n      callbacks.onStatus(pkg, \"ready\", \"loaded\");\n    });\n\n    const markError = Effect.gen(function* () {\n      const currentStatus = yield* Ref.get(statusRef);\n      if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n      yield* Ref.set(statusRef, \"error\");\n      yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`)).pipe(\n        Effect.ignore,\n      );\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() + REMOTE_PROBE_DEADLINE_MS;\n        let delay = REMOTE_PROBE_BACKOFF_INITIAL_MS;\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, REMOTE_PROBE_TIMEOUT_MS);\n\n          if (ok) {\n            yield* markReady;\n            return;\n          }\n\n          const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n          if (fallbackOk) {\n            yield* markReady;\n            return;\n          }\n\n          yield* Effect.sleep(`${delay} millis`);\n          delay = Math.min(Math.round(delay * 1.5), REMOTE_PROBE_BACKOFF_MAX_MS);\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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"}