{"version":3,"file":"service-descriptor.mjs","names":[],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface ServiceDescriptor {\n  key: string;\n  source: SourceMode;\n  url: string;\n  remoteUrl?: string;\n  entry: string;\n  name: string;\n  localPath?: string;\n  port?: number;\n  readinessPath: string;\n  defaultPort: number;\n  integrity?: string;\n  proxy?: string;\n  variables?: Record<string, string>;\n  secrets?: string[];\n  ssr?: boolean;\n  command?: string;\n  args?: string[];\n  readyPatterns?: RegExp[];\n  errorPatterns?: RegExp[];\n}\n\nexport class ServiceDescriptorMap extends Context.Tag(\"ServiceDescriptorMap\")<\n  ServiceDescriptorMap,\n  Map<string, ServiceDescriptor>\n>() {}\n\nexport class DevRuntimeConfig extends Context.Tag(\"DevRuntimeConfig\")<\n  DevRuntimeConfig,\n  RuntimeConfig\n>() {}\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];\n\nconst SERVICE_CONFIGS: Record<\n  string,\n  Pick<\n    ServiceDescriptor,\n    \"command\" | \"args\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n  >\n> = {\n  host: {\n    command: \"bun\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n    errorPatterns: [/error:/i, /failed/i, /exception/i],\n    defaultPort: 3000,\n    readinessPath: \"/health\",\n  },\n  auth: {\n    command: \"bun\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: PLUGIN_READY_PATTERNS,\n    errorPatterns: PLUGIN_ERROR_PATTERNS,\n    defaultPort: 3002,\n    readinessPath: \"/remoteEntry.js\",\n  },\n  ui: {\n    command: \"bun\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n    errorPatterns: [/error/i, /failed to compile/i],\n    defaultPort: 3003,\n    readinessPath: \"/remoteEntry.js\",\n  },\n  \"ui-ssr\": {\n    command: \"bun\",\n    args: [\"run\", \"dev:ssr\"],\n    readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n    errorPatterns: [/error/i, /failed/i],\n    defaultPort: 3004,\n    readinessPath: \"/\",\n  },\n  api: {\n    command: \"bun\",\n    args: [\"run\", \"dev\"],\n    readyPatterns: PLUGIN_READY_PATTERNS,\n    errorPatterns: PLUGIN_ERROR_PATTERNS,\n    defaultPort: 3001,\n    readinessPath: \"/remoteEntry.js\",\n  },\n};\n\nexport function buildServiceDescriptorMap(\n  runtimeConfig: RuntimeConfig,\n  options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n  const map = new Map<string, ServiceDescriptor>();\n  const ssr = options?.ssr ?? false;\n\n  const hostIsRemote = runtimeConfig.host.source === \"remote\";\n  const hostProbeUrl = hostIsRemote\n    ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n    : runtimeConfig.host.url;\n  map.set(\"host\", {\n    key: \"host\",\n    source: runtimeConfig.host.source,\n    url: hostProbeUrl,\n    remoteUrl: runtimeConfig.host.remoteUrl,\n    entry: hostIsRemote\n      ? hostProbeUrl\n        ? `${hostProbeUrl}/mf-manifest.json`\n        : \"/mf-manifest.json\"\n      : runtimeConfig.host.entry,\n    name: runtimeConfig.host.name,\n    localPath: runtimeConfig.host.localPath,\n    port: runtimeConfig.host.port,\n    integrity: runtimeConfig.host.integrity,\n    secrets: runtimeConfig.host.secrets,\n    ...SERVICE_CONFIGS.host,\n  });\n\n  map.set(\"ui\", {\n    key: \"ui\",\n    source: runtimeConfig.ui.source,\n    url: runtimeConfig.ui.url,\n    remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n    entry: runtimeConfig.ui.entry,\n    name: runtimeConfig.ui.name,\n    localPath: runtimeConfig.ui.localPath,\n    port: runtimeConfig.ui.port,\n    integrity: runtimeConfig.ui.integrity,\n    ssr,\n    ...SERVICE_CONFIGS.ui,\n  });\n\n  if (ssr && runtimeConfig.ui.source === \"local\") {\n    map.set(\"ui-ssr\", {\n      key: \"ui-ssr\",\n      source: runtimeConfig.ui.source,\n      url: runtimeConfig.ui.ssrUrl ?? \"\",\n      entry: \"\",\n      name: \"ui-ssr\",\n      localPath: runtimeConfig.ui.localPath,\n      port: runtimeConfig.ui.ssrUrl\n        ? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)\n        : (runtimeConfig.ui.port ?? 3003) + 1,\n      ...SERVICE_CONFIGS[\"ui-ssr\"],\n    });\n  }\n\n  map.set(\"api\", {\n    key: \"api\",\n    source: runtimeConfig.api.source,\n    url: runtimeConfig.api.url,\n    remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n    entry: runtimeConfig.api.entry,\n    name: runtimeConfig.api.name,\n    localPath: runtimeConfig.api.localPath,\n    port: runtimeConfig.api.port,\n    integrity: runtimeConfig.api.integrity,\n    proxy: runtimeConfig.api.proxy,\n    variables: runtimeConfig.api.variables,\n    secrets: runtimeConfig.api.secrets,\n    ...SERVICE_CONFIGS.api,\n  });\n\n  if (runtimeConfig.auth) {\n    map.set(\"auth\", {\n      key: \"auth\",\n      source: runtimeConfig.auth.source,\n      url: runtimeConfig.auth.url,\n      remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n      entry: runtimeConfig.auth.entry,\n      name: runtimeConfig.auth.name,\n      localPath: runtimeConfig.auth.localPath,\n      port: runtimeConfig.auth.port,\n      integrity: runtimeConfig.auth.integrity,\n      proxy: runtimeConfig.auth.proxy,\n      variables: runtimeConfig.auth.variables,\n      secrets: runtimeConfig.auth.secrets,\n      ...SERVICE_CONFIGS.auth,\n    });\n  }\n\n  if (runtimeConfig.plugins) {\n    let pluginBasePort = 3010;\n    for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n      const pluginKey = `plugin:${pluginId}`;\n      const resolvedPort = pluginConfig.port ?? pluginBasePort;\n      pluginBasePort = resolvedPort + 1;\n\n      map.set(pluginKey, {\n        key: pluginKey,\n        source: pluginConfig.source,\n        url: pluginConfig.url,\n        remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n        entry: pluginConfig.entry,\n        name: pluginConfig.name,\n        localPath: pluginConfig.localPath,\n        port: resolvedPort,\n        integrity: pluginConfig.integrity,\n        proxy: pluginConfig.proxy,\n        variables: pluginConfig.variables,\n        secrets: pluginConfig.secrets,\n        command: \"bun\",\n        args: [\"run\", \"dev\"],\n        readyPatterns: PLUGIN_READY_PATTERNS,\n        errorPatterns: PLUGIN_ERROR_PATTERNS,\n        defaultPort: resolvedPort,\n        readinessPath: \"/remoteEntry.js\",\n      });\n\n      if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\") {\n        const uiKey = `plugin-ui:${pluginId}`;\n        const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n        pluginBasePort = uiPort + 1;\n\n        map.set(uiKey, {\n          key: uiKey,\n          source: pluginConfig.ui.source,\n          url: pluginConfig.ui.url,\n          entry: pluginConfig.ui.entry,\n          name: pluginConfig.ui.name,\n          localPath: pluginConfig.ui.localPath,\n          port: uiPort,\n          integrity: pluginConfig.ui.integrity,\n          command: \"bun\",\n          args: [\"run\", \"dev\"],\n          readyPatterns: PLUGIN_READY_PATTERNS,\n          errorPatterns: PLUGIN_ERROR_PATTERNS,\n          defaultPort: uiPort,\n          readinessPath: \"/remoteEntry.js\",\n        });\n      }\n    }\n  }\n\n  return map;\n}\n\nexport interface AppOrchestrator {\n  packages: string[];\n  description: string;\n  env: Record<string, string>;\n  port?: number;\n  interactive?: boolean;\n  noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n  Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n  Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildDescription(map: Map<string, ServiceDescriptor>): string {\n  const descriptors = [...map.values()].filter(\n    (d) => d.key !== \"ui-ssr\" && !d.key.startsWith(\"plugin:\"),\n  );\n\n  const allLocal = descriptors.every((d) => d.source === \"local\");\n  const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n  if (allLocal && !hasProxy) return \"Full Local Development\";\n\n  const parts: string[] = [];\n  for (const d of descriptors) {\n    if (d.source === \"remote\") {\n      const label =\n        d.key === \"host\"\n          ? \"Remote Host\"\n          : d.key === \"ui\"\n            ? \"Remote UI\"\n            : d.key === \"api\"\n              ? hasProxy\n                ? undefined\n                : \"Remote API\"\n              : d.key === \"auth\"\n                ? \"Remote Auth\"\n                : undefined;\n      if (label) parts.push(label);\n    }\n  }\n  if (hasProxy) parts.push(\"Proxy API → Production\");\n  return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}