( baseUrl: string, )
| 655 | // daemon process on the user's behalf only makes sense when "the user's machine" is |
| 656 | // also where the request will land. |
| 657 | const ensureDaemon = ( |
| 658 | baseUrl: string, |
| 659 | ): Effect.Effect<string, Error, FileSystem.FileSystem | PlatformPath.Path> => |
| 660 | Effect.gen(function* () { |
| 661 | const resolvedTarget = yield* resolveDaemonTarget(baseUrl); |
| 662 | if (resolvedTarget.fromPointer && (yield* isServerReachable(resolvedTarget.baseUrl))) { |
| 663 | return resolvedTarget.baseUrl; |
| 664 | } |
| 665 | |
| 666 | const active = yield* readActiveLocalServerManifest(); |
| 667 | const activeOrigin = active |
| 668 | ? normalizeExecutorServerConnection({ origin: active.connection.origin }).origin |
| 669 | : null; |
| 670 | const targetOrigin = normalizeExecutorServerConnection({ |
| 671 | origin: resolvedTarget.baseUrl, |
| 672 | }).origin; |
| 673 | if (activeOrigin === targetOrigin) { |
| 674 | return resolvedTarget.baseUrl; |
| 675 | } |
| 676 | |
| 677 | if (active && activeOrigin !== targetOrigin) { |
| 678 | return yield* Effect.fail( |
| 679 | new Error( |
| 680 | [ |
| 681 | `A local Executor ${active.kind} is already running at ${active.connection.origin} (pid ${active.pid}).`, |
| 682 | `It owns the current data directory: ${active.dataDir}`, |
| 683 | "Refusing to start another local daemon against the same database.", |
| 684 | ].join("\n"), |
| 685 | ), |
| 686 | ); |
| 687 | } |
| 688 | |
| 689 | const parsed = yield* parseDaemonUrl(baseUrl); |
| 690 | const host = canonicalDaemonHost(parsed.hostname); |
| 691 | |
| 692 | if (!canAutoStartLocalDaemonForHost(host)) { |
| 693 | return yield* Effect.fail( |
| 694 | new Error( |
| 695 | [ |
| 696 | `Executor daemon is not reachable at ${baseUrl}.`, |
| 697 | "Auto-start is only supported for local hosts.", |
| 698 | `Start it manually: ${cliPrefix} daemon run --port ${parsed.port} --hostname ${host}`, |
| 699 | ].join("\n"), |
| 700 | ), |
| 701 | ); |
| 702 | } |
| 703 | |
| 704 | return yield* spawnAndWaitForDaemon({ |
| 705 | host, |
| 706 | scopeId: resolvedTarget.scopeId, |
| 707 | preferredPort: parsed.port, |
| 708 | allowedHosts: [], |
| 709 | }); |
| 710 | }).pipe(Effect.mapError(toError)); |
| 711 | |
| 712 | const resolveRequestedExecutorServerConnection = ( |
| 713 | target: ServerTarget, |
no test coverage detected