@@ -6,16 +6,25 @@ const providerToken = requiredEnv("PROVIDER_TOKEN");
66const 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
1013let stopped = false ;
14+ let lastRegisterAt = 0 ;
1115for ( const signal of [ "SIGINT" , "SIGTERM" , "SIGHUP" ] ) {
1216 process . once ( signal , ( ) => {
1317 stopped = true ;
1418 } ) ;
1519}
1620
21+ await registerProvider ( ) ;
22+
1723while ( ! 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+
3683async 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+
83144async function complete ( payload ) {
84145 await fetchJson ( `${ cloudUrl } /api/actions/providers/rpc/complete` , {
85146 previewId,
0 commit comments