zooid 0.7.2 → 0.7.3

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/dist/bin.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  renderRegistration,
16
16
  startDaemonSocketServer,
17
17
  startWorkforcePublisher
18
- } from "./chunk-O6E4CDTV.js";
18
+ } from "./chunk-3IKBBKGI.js";
19
19
 
20
20
  // src/bin.ts
21
21
  import { resolve as resolve5 } from "path";
@@ -648,6 +648,9 @@ async function startDaemon(opts = {}) {
648
648
 
649
649
  // src/services/tuwunel.ts
650
650
  import { spawn } from "child_process";
651
+ import { execFile as execFile2 } from "child_process";
652
+ import { promisify as promisify2 } from "util";
653
+ var execFileAsync = promisify2(execFile2);
651
654
  var DEFAULT_IMAGE = "ghcr.io/matrix-construct/tuwunel:latest";
652
655
  function buildRunArgs(opts) {
653
656
  const image = opts.image ?? DEFAULT_IMAGE;
@@ -695,6 +698,16 @@ var TuwunelService = class {
695
698
  }
696
699
  async waitHealthy(opts) {
697
700
  const deadline = Date.now() + opts.timeoutMs;
701
+ while (Date.now() < deadline) {
702
+ const state = await this.inspectState().catch(() => null);
703
+ if (state?.status === "running") break;
704
+ if (state?.status === "exited") {
705
+ throw new Error(
706
+ `Tuwunel container exited before serving HTTP (exit=${state.exitCode}${state.error ? `, error=${state.error}` : ""}). Check the engine logs (\`${this.opts.engine} logs ${this.opts.name}\`).`
707
+ );
708
+ }
709
+ await new Promise((resolve6) => setTimeout(resolve6, 500));
710
+ }
698
711
  while (Date.now() < deadline) {
699
712
  try {
700
713
  const r = await fetch(`${opts.url}/_matrix/client/versions`);
@@ -703,10 +716,35 @@ var TuwunelService = class {
703
716
  }
704
717
  await new Promise((resolve6) => setTimeout(resolve6, 500));
705
718
  }
719
+ const finalState = await this.inspectState().catch(() => null);
720
+ const detail = finalState ? ` (container status=${finalState.status}${finalState.exitCode !== void 0 ? `, exit=${finalState.exitCode}` : ""})` : "";
706
721
  throw new Error(
707
- `Tuwunel did not become healthy at ${opts.url} in ${opts.timeoutMs}ms`
722
+ `Tuwunel did not become healthy at ${opts.url} in ${opts.timeoutMs}ms${detail}`
708
723
  );
709
724
  }
725
+ /**
726
+ * Read the engine's view of the container. Returns null if the container
727
+ * isn't known to the engine (e.g. before spawn completed or after `--rm`).
728
+ */
729
+ async inspectState() {
730
+ try {
731
+ const { stdout } = await execFileAsync(this.opts.engine, [
732
+ "inspect",
733
+ this.opts.name,
734
+ "--format",
735
+ "{{.State.Status}}|{{.State.ExitCode}}|{{.State.Error}}"
736
+ ]);
737
+ const [status, exitCodeRaw, error] = stdout.trim().split("|");
738
+ const exitCode = exitCodeRaw && exitCodeRaw !== "<no value>" ? Number(exitCodeRaw) : void 0;
739
+ return {
740
+ status: status ?? "unknown",
741
+ ...Number.isFinite(exitCode) ? { exitCode } : {},
742
+ ...error ? { error } : {}
743
+ };
744
+ } catch {
745
+ return null;
746
+ }
747
+ }
710
748
  };
711
749
  function execEngine(engine, args) {
712
750
  return new Promise((resolve6, reject) => {
@@ -1147,7 +1185,7 @@ async function runDev(flags) {
1147
1185
  title: "Wait for Tuwunel /_matrix/client/versions",
1148
1186
  task: async () => {
1149
1187
  if (!ctx.svc) throw new Error("service not started");
1150
- await ctx.svc.waitHealthy({ url: homeserver, timeoutMs: 6e4 });
1188
+ await ctx.svc.waitHealthy({ url: homeserver, timeoutMs: 18e4 });
1151
1189
  }
1152
1190
  },
1153
1191
  {