serve-sim 0.1.37 → 0.1.38
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/bin/serve-sim-bin +0 -0
- package/dist/serve-sim.js +1 -1
- package/package.json +1 -1
package/bin/serve-sim-bin
CHANGED
|
Binary file
|
package/dist/serve-sim.js
CHANGED
|
@@ -92,7 +92,7 @@ Usage:
|
|
|
92
92
|
serve-sim permissions reset <permission|all> <bundle-id> [-d <udid|name>]
|
|
93
93
|
serve-sim permissions list [bundle-id] [-d <udid|name>]
|
|
94
94
|
|
|
95
|
-
Permissions: ${xe().join(", ")}`),process.exit(1);let s=t.device?Y(t.device):C_();if(!s)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(t.verb==="list"){let i={udid:s,bundleId:t.bundleId??null,tcc:Ti(s,t.bundleId),location:ci(s,t.bundleId),notifications:bi(s,t.bundleId)};console.log(JSON.stringify(i,null,e?0:2)),process.exit(0)}let C=t.bundleId;try{if(t.permission==="all")for(let i of xe())ft(s,"reset",i,void 0,C);else ft(s,t.verb,t.permission,t.value,C)}catch(i){console.error(i?.message??String(i)),process.exit(1)}if(e)console.log(JSON.stringify({udid:s,verb:t.verb,permission:t.permission,value:t.value??null,bundleId:C}));else{let i=t.value?` (${t.value})`:"";console.log(`\uD83D\uDD10 ${t.verb} ${t.permission}${i} for ${C} on ${s}`)}process.exit(0)}eS();var P_="./serve-sim-bin-
|
|
95
|
+
Permissions: ${xe().join(", ")}`),process.exit(1);let s=t.device?Y(t.device):C_();if(!s)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(t.verb==="list"){let i={udid:s,bundleId:t.bundleId??null,tcc:Ti(s,t.bundleId),location:ci(s,t.bundleId),notifications:bi(s,t.bundleId)};console.log(JSON.stringify(i,null,e?0:2)),process.exit(0)}let C=t.bundleId;try{if(t.permission==="all")for(let i of xe())ft(s,"reset",i,void 0,C);else ft(s,t.verb,t.permission,t.value,C)}catch(i){console.error(i?.message??String(i)),process.exit(1)}if(e)console.log(JSON.stringify({udid:s,verb:t.verb,permission:t.permission,value:t.value??null,bundleId:C}));else{let i=t.value?` (${t.value})`:"";console.log(`\uD83D\uDD10 ${t.verb} ${t.permission}${i} for ${C} on ${s}`)}process.exit(0)}eS();var P_="./serve-sim-bin-gr4fhr28.";var D_=at(import.meta.url);function LS(){if(!X(r_))Ne(r_,{recursive:!0})}function t_(_){if(_)return NS(Ae(_));for(let e of ye()){let S=NS(e);if(S)return S}return null}var we={at:0,booted:null};function gy(){let _=Date.now();if(we.booted&&_-we.at<1000)return we.booted;try{let e=k("xcrun simctl list devices booted -j",{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3000}),S=JSON.parse(e),t=new Set;for(let s of Object.values(S.devices))for(let C of s)if(C.state==="Booted")t.add(C.udid);return we={at:_,booted:t},t}catch{return null}}function NS(_){try{if(!X(_))return o_("state file missing %s",_),null;let e=JSON.parse(S_(_,"utf-8"));try{process.kill(e.pid,0)}catch{return o_("helper pid %d dead, removing stale state %s",e.pid,_),U_(_),null}let S=gy();if(S&&!S.has(e.device)){o_("helper pid %d bound to non-booted device %s — killing stale helper",e.pid,e.device),console.error(`[serve-sim] Helper pid ${e.pid} is bound to device ${e.device} which is no longer booted — killing stale helper.`);try{process.kill(e.pid,"SIGTERM")}catch{}try{U_(_)}catch{}return null}return o_("state ok pid=%d device=%s port=%d",e.pid,e.device,e.port),e}catch(e){return o_("readStateFile threw for %s: %o",_,e),null}}function ge(){let _=[];for(let e of ye()){let S=NS(e);if(S)_.push(S)}return _}function ps(_){LS(),ue(Ae(_.device),JSON.stringify(_,null,2)),o_("wrote state pid=%d device=%s port=%d",_.pid,_.device,_.port)}function Se(_){if(_){o_("clearState device=%s",_);try{U_(Ae(_))}catch{}}else{o_("clearState (all)");for(let e of ye())try{U_(e)}catch{}}}function py(){let _=P_.startsWith("/$bunfs/");if(!_&&X(P_))return P_;if(!_){let C=i_(D_,"../bin/serve-sim-bin");if(X(C))return C;throw Error(`serve-sim-bin not found. Run 'bun run build:swift' first.
|
|
96
96
|
Checked: ${P_}, ${C}`)}let e=S_(P_),S=pS("sha256").update(e).digest("hex").slice(0,16),t=i_(ly(),"Library/Caches/serve-sim");Ne(t,{recursive:!0});let s=i_(t,`serve-sim-bin-${S}`);if(!X(s)){ue(s,e),Ny(s,493);try{k(`codesign -s - -f ${JSON.stringify(s)}`,{stdio:"ignore"})}catch{}}return s}function hs(){let _=null;try{_=k("xcode-select -p",{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{}if(!_)return process.env;let e=`${_}/Library/PrivateFrameworks`;return{...process.env,DYLD_FRAMEWORK_PATH:process.env.DYLD_FRAMEWORK_PATH?`${e}:${process.env.DYLD_FRAMEWORK_PATH}`:e}}function Ws(){try{let _=k("xcrun simctl list devices -j",{encoding:"utf-8"}),e=JSON.parse(_),S=Object.keys(e.devices).filter((t)=>/SimRuntime\.iOS-/i.test(t)).sort((t,s)=>{let C=(t.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number),i=(s.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number);return(i[0]??0)-(C[0]??0)||(i[1]??0)-(C[1]??0)});for(let t of S){let C=(e.devices[t]??[]).find((i)=>i.isAvailable!==!1&&/^iPhone\b/i.test(i.name));if(C)return{udid:C.udid,name:C.name}}}catch{}return null}function Ls(_){try{let e=k("xcrun simctl list devices -j",{encoding:"utf-8"}),S=JSON.parse(e);for(let t of Object.values(S.devices))for(let s of t)if(s.udid===_)return s.name}catch{}return null}function ds(_){try{let e=k("xcrun simctl list devices -j",{encoding:"utf-8"}),S=JSON.parse(e);for(let t of Object.values(S.devices))for(let s of t)if(s.udid===_)return s.state==="Booted"}catch{}return!1}function N_(_){try{return process.kill(_,0),!0}catch{return!1}}function VS(_){try{process.kill(_,"SIGTERM")}catch{return}let e=Date.now()+500;while(Date.now()<e)try{process.kill(_,0),L_(25)}catch{return}try{process.kill(_,"SIGKILL")}catch{}let S=Date.now()+500;while(Date.now()<S)try{process.kill(_,0),L_(25)}catch{return}}function Ly(_){try{let e=k(`lsof -ti tcp:${_}`,{encoding:"utf-8",stdio:"pipe"}).trim();if(!e)return[];let S=process.pid;return e.split(`
|
|
97
97
|
`).map((t)=>parseInt(t,10)).filter((t)=>Number.isFinite(t)&&t!==S)}catch{return[]}}function hy(_){let e=Ly(_);if(e.length===0)return;console.log(`\x1B[90mPort ${_} busy, killing holder pid(s): ${e.join(", ")}\x1B[0m`);for(let S of e)try{process.kill(S,"SIGKILL")}catch{}L_(100)}function Wy(_){if(!ds(_))try{k(`xcrun simctl boot ${_}`,{encoding:"utf-8",stdio:"pipe"})}catch(e){let S=(e.stderr??e.message??"").toLowerCase();if(!S.includes("booted")&&!S.includes("current state"))throw Error(`Failed to boot device ${_}: ${e.stderr||e.message}`)}try{k("open -ga Simulator",{encoding:"utf-8",stdio:"pipe",timeout:3000})}catch{}}function dy(){let _=uy();for(let e of Object.values(_))for(let S of e??[])if(S.family==="IPv4"&&!S.internal)return S.address;return null}async function Gs(_){let e=new Set(ge().map((S)=>S.port));for(let S=_;S<_+100;S++){if(e.has(S))continue;if(await Tt(S))return S}throw Error(`No available port found in range ${_}-${_+99}`)}async function Gy(_){Wy(_);try{k(`xcrun simctl bootstatus ${_} -b`,{encoding:"utf-8",stdio:"pipe",timeout:60000})}catch(e){if(!ds(_))console.error(`Device ${_} failed to reach booted state: ${e.stderr||e.message}`),process.exit(1)}}async function Ps(_,e,S,t){let s=!1,C=Date.now();j("waitForHelperReady pid=%d url=%s",_,e);for(let R=0;R<30;R++){if(!t()){j("helper pid=%d died during /health polling (attempt %d)",_,R);break}try{if((await fetch(`${e}/health`)).ok){s=!0,j("helper pid=%d /health ok after %dms",_,Date.now()-C);break}}catch{}await new Promise((y)=>setTimeout(y,100))}if(!s)j("helper pid=%d /health never responded (%dms)",_,Date.now()-C);if(s){let R=Date.now(),y=R+8000,A=!1;while(Date.now()<y){if(await new Promise(($)=>setTimeout($,200)),!t()){j("helper pid=%d died while awaiting Capture started",_),s=!1;break}try{if(S_(S,"utf-8").includes("Capture started")){A=!0,j("helper pid=%d saw 'Capture started' after %dms",_,Date.now()-R);break}}catch{}}if(s&&!A)j("helper pid=%d ready but never logged 'Capture started' within %dms — stream may not produce frames",_,Date.now()-R)}let i="";try{i=S_(S,"utf-8").trim()}catch{}return{ready:s,log:i}}async function Py(_){let{helperPath:e,udid:S,port:t,host:s,logFile:C}=_,i=`http://${s}:${t}`;LS();let R=Ve(C,"w"),y=gS(e,[S,"--port",String(t)],{detached:!0,stdio:["ignore",R,R],env:hs()});y.unref(),le(R);let A=y.pid,$=!1;y.once("exit",()=>{$=!0});let{ready:o,log:B}=await Ps(A,i,C,()=>!$&&N_(A));return{ready:o,pid:A,exited:$||!N_(A),log:B}}async function My(_){let{helperPath:e,udid:S,port:t,host:s,logFile:C}=_,i=`http://${s}:${t}`;LS();let R=Ve(C,"w"),y=gS(e,[S,"--port",String(t)],{detached:!1,stdio:["ignore",R,R],env:hs()});le(R);let A=y.pid,$=!1;y.once("exit",()=>{$=!0});let{ready:o,log:B}=await Ps(A,i,C,()=>!$&&N_(A));return{ready:o,child:y,log:B}}async function Ms(_,e,S){j("startHelper udid=%s port=%d detach=%s",_,e,S.detach),await Gy(_);let t="127.0.0.1",s=py(),C=e_(r_,`server-${_}.log`);j("helper binary=%s logFile=%s",s,C);let i={helperPath:s,udid:_,port:e,host:t,logFile:C},R="",y=2;for(let $=1;$<=y;$++){if(j("spawn attempt %d/%d",$,y),hy(e),S.detach){let o=await Py(i);if(j("spawnHelperDetached result ready=%s pid=%d exited=%s",o.ready,o.pid,o.exited),o.ready){let B={pid:o.pid,port:e,device:_,url:`http://${t}:${e}`,streamUrl:`http://${t}:${e}/stream.mjpeg`,wsUrl:`ws://${t}:${e}/ws`};return ps(B),{pid:o.pid}}VS(o.pid),R=o.log}else{let o=await My(i);if(j("spawnHelperAttached result ready=%s pid=%d",o.ready,o.child.pid),o.ready){let B={pid:o.child.pid,port:e,device:_,url:`http://${t}:${e}`,streamUrl:`http://${t}:${e}/stream.mjpeg`,wsUrl:`ws://${t}:${e}/ws`};return ps(B),{pid:o.child.pid,child:o.child}}VS(o.child.pid),R=o.log}if($<y)await new Promise((o)=>setTimeout(o,500))}let A=R?`Helper failed:
|
|
98
98
|
${R}`:"Helper process failed to start";console.error(A),process.exit(1)}async function Uy(_,e,S){_S("follow devices=%o startPort=%d",_,e);let t=_.length>0?_.map(Y):(()=>{let A=C_();if(A)return[A];let $=Ws();if(!$)console.error("No device specified and no available iOS simulator found."),process.exit(1);if(!S)console.log(`No booted simulator — booting ${$.name}...`);return[$.udid]})(),s=new Map,C=[],i=e;for(let A of t){let $=t_(A);if($){if(!S){let v=Ls(A)??A;if(t.length>1)console.log(`
|