@effectstream/orchestrator 0.100.20 → 0.100.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effectstream/orchestrator",
3
- "version": "0.100.20",
3
+ "version": "0.100.21",
4
4
  "license": "MIT",
5
5
  "homepage": "https://effectstream.github.io/docs/",
6
6
  "repository": {
@@ -32,7 +32,7 @@
32
32
  "start": "bun src/cli.ts start"
33
33
  },
34
34
  "dependencies": {
35
- "@effectstream/db": "0.100.20"
35
+ "@effectstream/db": "0.100.21"
36
36
  },
37
37
  "description": "Multi-chain local development environment for EffectStream"
38
38
  }
@@ -8,21 +8,43 @@ export const DbNames = {
8
8
  PGLITE_WAIT: "pglite-wait",
9
9
  } as const;
10
10
 
11
+ /**
12
+ * Spawns the embedded PGlite database used by e2e suites — unless
13
+ * `PGLITE=false` is set in the environment, in which case it assumes an
14
+ * external Postgres is already running on `DB_PORT` (or `port`) and emits a
15
+ * single wait task that other processes can still depend on via
16
+ * `DbNames.PGLITE_WAIT`. This keeps the launcher.cli.ts call sites unchanged
17
+ * while letting e2e_postgres.sh exercise the engine against a real Postgres
18
+ * (e.g. to verify the pg_ivm-optional fallback path).
19
+ */
11
20
  export function launchPglite(opts?: { port?: number }): ProcessConfig[] {
12
- const port = opts?.port ?? 5432;
21
+ const defaultPort = opts?.port ?? 5432;
22
+
23
+ if (process.env.PGLITE === "false") {
24
+ const externalPort = process.env.DB_PORT ?? String(defaultPort);
25
+ return [
26
+ {
27
+ name: DbNames.PGLITE_WAIT,
28
+ description: `Wait for external Postgres on port ${externalPort}`,
29
+ args: [waitTcpScript, String(externalPort)],
30
+ waitToExit: true,
31
+ },
32
+ ];
33
+ }
34
+
13
35
  return [
14
36
  {
15
37
  name: DbNames.PGLITE,
16
- description: `PGLite embedded database (port ${port})`,
17
- args: [startPgliteScript, "--port", String(port)],
18
- stopProcessAtPort: [port],
38
+ description: `PGLite embedded database (port ${defaultPort})`,
39
+ args: [startPgliteScript, "--port", String(defaultPort)],
40
+ stopProcessAtPort: [defaultPort],
19
41
  waitToExit: false,
20
42
  critical: true,
21
43
  },
22
44
  {
23
45
  name: DbNames.PGLITE_WAIT,
24
- description: `Wait for PGLite on port ${port}`,
25
- args: [waitTcpScript, String(port)],
46
+ description: `Wait for PGLite on port ${defaultPort}`,
47
+ args: [waitTcpScript, String(defaultPort)],
26
48
  waitToExit: true,
27
49
  dependsOn: [DbNames.PGLITE],
28
50
  },
package/src/api-server.ts CHANGED
@@ -31,7 +31,15 @@ export type ApiServerOptions = {
31
31
  /** Called when the /shutdown endpoint is hit. */
32
32
  onShutdown: () => Promise<void>;
33
33
  /** Callback hooks for task events (used by both local and remote starts). */
34
- runCallbacks?: Pick<RunOptions, "onTaskStart" | "onTaskRunning" | "onTaskDone" | "onTaskFailed" | "onShutdown">;
34
+ runCallbacks?: Pick<
35
+ RunOptions,
36
+ | "onTaskStart"
37
+ | "onTaskRunning"
38
+ | "onTaskDone"
39
+ | "onTaskFailed"
40
+ | "onWaitingForExit"
41
+ | "onShutdown"
42
+ >;
35
43
  };
36
44
 
37
45
  /**
@@ -17,6 +17,7 @@ import {
17
17
  logTaskRunning,
18
18
  logTaskDone,
19
19
  logTaskFailed,
20
+ logWaitingForExit,
20
21
  logInfo,
21
22
  logWarn,
22
23
  logError,
@@ -148,6 +149,7 @@ export async function runStartCommand(opts: StartOptions): Promise<void> {
148
149
  onTaskRunning: logTaskRunning,
149
150
  onTaskDone: logTaskDone,
150
151
  onTaskFailed: logTaskFailed,
152
+ onWaitingForExit: logWaitingForExit,
151
153
  onShutdown: undefined as ((reason: string) => void) | undefined,
152
154
  };
153
155
 
package/src/display.ts CHANGED
@@ -188,3 +188,11 @@ export function logError(msg: string): void {
188
188
  export function logWarn(msg: string): void {
189
189
  console.warn(`${c.yellow}⚠${c.reset} ${msg}`);
190
190
  }
191
+
192
+ export function logWaitingForExit(names: string[]): void {
193
+ const list = names.join(", ");
194
+ console.log(
195
+ `${c.gray}…${c.reset} ${c.dim}waiting on${c.reset} ${c.bold}${list}${c.reset}` +
196
+ `${c.dim} (see logs/*.log — often midnight-indexer-wait or midnight-contract)${c.reset}`,
197
+ );
198
+ }
@@ -87,12 +87,26 @@ export class ProcessManager {
87
87
  // Otherwise, pipe output so we can suppress silenced processes.
88
88
  const usesPipe = typeof outFd !== "number";
89
89
 
90
+ // Build child env. When writing to a file fd, suppress ANSI/TTY noise:
91
+ // - Strip FORCE_COLOR (inherited from parent or set by orchestrator) so
92
+ // children don't emit color escapes.
93
+ // - Set NO_COLOR=1 (broadly respected) and CI=1 to coax bun's
94
+ // `--filter` runner out of its live-redraw TTY mode, which would
95
+ // otherwise leave cursor-move escapes and "[N lines elided]" in logs.
96
+ const childEnv: Record<string, string | undefined> = {
97
+ ...process.env,
98
+ ...config.env,
99
+ };
100
+ if (usesPipe) {
101
+ childEnv.FORCE_COLOR = "true";
102
+ } else {
103
+ delete childEnv.FORCE_COLOR;
104
+ childEnv.NO_COLOR = "1";
105
+ childEnv.CI = "1";
106
+ }
107
+
90
108
  const proc = Bun.spawn([command, ...config.args], {
91
- env: {
92
- ...process.env,
93
- ...config.env,
94
- FORCE_COLOR: "true",
95
- },
109
+ env: childEnv,
96
110
  cwd: config.cwd ?? process.cwd(),
97
111
  stdout: usesPipe ? "pipe" : outFd,
98
112
  stderr: usesPipe ? "pipe" : outFd,
@@ -27,6 +27,8 @@ export type RunOptions = {
27
27
  onTaskRunning?: (name: string) => void;
28
28
  onTaskDone?: (name: string) => void;
29
29
  onTaskFailed?: (name: string, code: number) => void;
30
+ /** Called when the scheduler blocks until one or more waitToExit processes finish. */
31
+ onWaitingForExit?: (names: string[]) => void;
30
32
  /** Called when a critical process fails and the whole run should stop. */
31
33
  onShutdown?: (reason: string) => void;
32
34
  };
@@ -170,6 +172,7 @@ export async function runProcesses(
170
172
  };
171
173
 
172
174
  let shutdownRequested = false;
175
+ let lastWaitingForExitKey = "";
173
176
 
174
177
  while (pending.size > 0 || waitingToExit.size > 0) {
175
178
  if (shutdownRequested) break;
@@ -259,6 +262,11 @@ export async function runProcesses(
259
262
  );
260
263
  } else if (waitingToExit.size > 0) {
261
264
  // All ready tasks are launched; wait for a waitToExit one to finish
265
+ const waitingKey = [...waitingToExit].sort().join("\0");
266
+ if (waitingKey !== lastWaitingForExitKey) {
267
+ lastWaitingForExitKey = waitingKey;
268
+ options.onWaitingForExit?.([...waitingToExit].sort());
269
+ }
262
270
  await waitForWake();
263
271
  } else {
264
272
  // pending > 0 but nothing is ready and nothing is waiting — circular dep