Skip to content

Commit a67ad7b

Browse files
committed
Register Studio provider bridge
1 parent c35d5be commit a67ad7b

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

scripts/studio-provider-bridge.mjs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,25 @@ const providerToken = requiredEnv("PROVIDER_TOKEN");
66
const localUrl = (
77
process.env.SIMDECK_LOCAL_URL || "http://127.0.0.1:4310"
88
).replace(/\/$/, "");
9+
const registerIntervalMs = Number(
10+
process.env.SIMDECK_PROVIDER_REGISTER_INTERVAL_MS || 15000,
11+
);
912

1013
let stopped = false;
14+
let lastRegisterAt = 0;
1115
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
1216
process.once(signal, () => {
1317
stopped = true;
1418
});
1519
}
1620

21+
await registerProvider();
22+
1723
while (!stopped) {
1824
try {
25+
if (Date.now() - lastRegisterAt > registerIntervalMs) {
26+
await registerProvider();
27+
}
1928
const next = await fetchJson(`${cloudUrl}/api/actions/providers/rpc/next`, {
2029
previewId,
2130
providerToken,
@@ -33,6 +42,44 @@ while (!stopped) {
3342
}
3443
}
3544

45+
async function registerProvider() {
46+
try {
47+
const metadata = await localProviderMetadata();
48+
await fetchJson(`${cloudUrl}/api/actions/providers/register`, {
49+
previewId,
50+
providerToken,
51+
baseUrl: `${cloudUrl}/simulator/${encodeURIComponent(previewId)}`,
52+
status: metadata.ok ? "ready" : "provider-online",
53+
simulatorUdid: metadata.simulator?.udid,
54+
simulatorName: metadata.simulator?.name,
55+
runtimeName: metadata.simulator?.runtimeName,
56+
});
57+
lastRegisterAt = Date.now();
58+
} catch (error) {
59+
console.error(
60+
`[simdeck-provider-bridge] provider registration failed: ${error instanceof Error ? error.message : String(error)}`,
61+
);
62+
}
63+
}
64+
65+
async function localProviderMetadata() {
66+
try {
67+
const simulators = await localJson("/api/simulators");
68+
const selected =
69+
simulators.simulators?.find((simulator) => simulator.isBooted) ??
70+
simulators.simulators?.[0] ??
71+
null;
72+
return { ok: true, simulator: selected };
73+
} catch {
74+
try {
75+
await localJson("/api/health");
76+
return { ok: true, simulator: null };
77+
} catch {
78+
return { ok: false, simulator: null };
79+
}
80+
}
81+
}
82+
3683
async function handleRequest(request) {
3784
try {
3885
const target = new URL(request.path, `${localUrl}/`);
@@ -80,6 +127,20 @@ async function handleRequest(request) {
80127
}
81128
}
82129

130+
async function localJson(path) {
131+
const target = new URL(path, `${localUrl}/`);
132+
target.searchParams.set("simdeckToken", providerToken);
133+
const response = await fetch(target, {
134+
headers: { "x-simdeck-token": providerToken },
135+
});
136+
if (!response.ok) {
137+
throw new Error(
138+
`${target.href} failed with ${response.status}: ${await response.text()}`,
139+
);
140+
}
141+
return response.json();
142+
}
143+
83144
async function complete(payload) {
84145
await fetchJson(`${cloudUrl}/api/actions/providers/rpc/complete`, {
85146
previewId,

0 commit comments

Comments
 (0)