1// Test fixture: boots an RpcSpawner, POSTs once with the child entry given by
2// the first CLI arg, and prints `PARENT_PID=<n>` and `CHILD_PID=<n>` lines to
3// stdout so the test harness can observe them. Then idles until killed.
4// Relative imports (not `@/` alias) so this file runs under both Bun and
5// Node without a paths-aware loader. This fixture is excluded from the test
6// project's typecheck (see tsconfig.test.json) because the relative path
7// crosses composite-project boundaries.
8import * as Deferred from "effect/Deferred";
9import * as Effect from "effect/Effect";
10import * as Layer from "effect/Layer";
11import * as FetchHttpClient from "effect/http/FetchHttpClient";
12import * as HttpBody from "effect/http/HttpBody";
13import * as HttpClient from "effect/http/HttpClient";
14import { layerServer, RpcSpawner } from "../../../src/Local/RpcSpawner.ts";
15import { PlatformServices } from "../../../src/Util/PlatformServices.ts";
16
17const childEntry = process.argv[2];
18if (!childEntry) {
19 console.error("usage: rpc-spawner-parent.ts <child-entry-url>");
20 process.exit(2);
21}
22
23const program = Effect.gen(function* () {
24 const sp = yield* RpcSpawner;
25 const http = yield* HttpClient.HttpClient;
26 const res = yield* http
27 .post(sp.url, {
28 body: yield* HttpBody.json({
29 serverEntryUrl: childEntry,
30 alchemyContext: {
31 dotAlchemy: "/tmp/.alchemy",
32 updateStateStore: false,
33 dev: true,
34 adopt: false,
35 },
36 stack: { name: "test", stage: "dev" },
37 }),
38 })
39 .pipe(Effect.flatMap((res) => res.text));
40
41 // The child's pid is whatever owns the listening port returned in res.
42 // We surface it for the test harness via stdout.
43 console.log(`PARENT_PID=${process.pid}\n`);
44 console.log(`CHILD_URL=${res}\n`);
45
46 const stop = yield* Deferred.make<void>();
47 yield* Deferred.await(stop);
48});
49
50program
51 .pipe(
52 Effect.provide([
53 Layer.provide(
54 layerServer({ profile: undefined, envFile: undefined }),
55 PlatformServices,
56 ),
57 FetchHttpClient.layer,
58 ]),
59 Effect.scoped,
60 Effect.runPromise,
61 )
62 .catch((e) => {
63 console.error(e);
64 process.exit(1);
65 });