robodev 0.3.0 → 0.3.1

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": "robodev",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "CLI for Robodev Starbase — create, auth, link, and deploy file-based APIs",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  writeLink,
18
18
  writeViteApiUrl,
19
19
  } from "./config.js";
20
+ import { waitUntilLive } from "./wait-until-live.js";
20
21
 
21
22
  const execFileAsync = promisify(execFile);
22
23
 
@@ -245,6 +246,7 @@ async function runDeploy(forceFlag: boolean, root = process.cwd()): Promise<void
245
246
  method: "POST",
246
247
  body: JSON.stringify({ force, files }),
247
248
  });
249
+ await waitUntilLive(result.apiUrl);
248
250
  console.log(`Deployed to ${result.apiUrl}`);
249
251
  console.log(`Docs ${result.docsUrl}`);
250
252
  console.log(
@@ -0,0 +1,51 @@
1
+ const POLL_INTERVAL_MS = 400;
2
+ const OVERALL_TIMEOUT_MS = 30_000;
3
+ const ATTEMPT_TIMEOUT_MS = 3_000;
4
+
5
+ function sleep(ms: number): Promise<void> {
6
+ return new Promise((resolve) => setTimeout(resolve, ms));
7
+ }
8
+
9
+ async function probe(url: string, timeoutMs: number): Promise<{ status: number; error?: string }> {
10
+ const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
11
+ const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;
12
+ return {
13
+ status: res.status,
14
+ error: typeof body.error === "string" ? body.error : undefined,
15
+ };
16
+ }
17
+
18
+ /**
19
+ * Polls the public project host until it answers as live.
20
+ * Prefers `GET /_robodev/ready` (200). Falls back to `GET /openapi.json` when an
21
+ * older Starbase serves a user-route 404 (`error === "not_found"`).
22
+ */
23
+ export async function waitUntilLive(apiUrl: string): Promise<void> {
24
+ const base = apiUrl.replace(/\/$/, "");
25
+ const deadline = Date.now() + OVERALL_TIMEOUT_MS;
26
+ let path = "/_robodev/ready";
27
+
28
+ console.log("Waiting for endpoints to come online…");
29
+
30
+ while (Date.now() < deadline) {
31
+ const remaining = deadline - Date.now();
32
+ if (remaining <= 0) break;
33
+
34
+ try {
35
+ const result = await probe(`${base}${path}`, Math.min(ATTEMPT_TIMEOUT_MS, remaining));
36
+ if (result.status === 200) return;
37
+ if (path === "/_robodev/ready" && result.status === 404 && result.error === "not_found") {
38
+ path = "/openapi.json";
39
+ continue;
40
+ }
41
+ } catch {
42
+ // Connection, TLS, or attempt timeout — keep polling until the overall deadline.
43
+ }
44
+
45
+ const wait = Math.min(POLL_INTERVAL_MS, deadline - Date.now());
46
+ if (wait <= 0) break;
47
+ await sleep(wait);
48
+ }
49
+
50
+ throw new Error(`Deploy was accepted but the project host did not become reachable: ${base}`);
51
+ }