zebra-report: orchestrator + integration tests — mirror
This commit is contained in:
parent
910f92c52a
commit
e8ec50e3e3
1 changed files with 73 additions and 2 deletions
|
|
@ -1056,6 +1056,77 @@ const callSpec = {
|
|||
},
|
||||
};
|
||||
|
||||
/* ==================================================================
|
||||
* wireZebraMachines — orchestrator. Composes one CallFSM, one
|
||||
* SubscribeFSM, three PublishFSMs (mic/screen/camera), and a Map of
|
||||
* RemoteTileFSMs into a coherent room. Observers wire transitions
|
||||
* between machines; no side effects in this layer — the page's
|
||||
* runtime attaches its OWN observers on top to drive actual WebRTC
|
||||
* and DOM work. That separation keeps this function fully testable
|
||||
* in Node with synthetic events.
|
||||
*
|
||||
* Returns { call, sub, pubs, remoteTiles, tileFor, tileLeft }. */
|
||||
function wireZebraMachines(){
|
||||
const call = createFSM(callSpec);
|
||||
const sub = createFSM(subscribeSpec);
|
||||
const pubs = {
|
||||
mic: createFSM(publishSpec),
|
||||
screen: createFSM(publishSpec),
|
||||
camera: createFSM(publishSpec),
|
||||
};
|
||||
pubs.mic.context.kind = 'mic';
|
||||
pubs.screen.context.kind = 'screen';
|
||||
pubs.camera.context.kind = 'camera';
|
||||
|
||||
/* RemoteTileFSMs keyed by `${kind}:${pubHex}` — lazily created. */
|
||||
const remoteTiles = new Map();
|
||||
function tileFor(kind, pubHex){
|
||||
const key = kind + ':' + pubHex;
|
||||
let t = remoteTiles.get(key);
|
||||
if (!t){
|
||||
t = createFSM(remoteTileSpec);
|
||||
t.context.kind = kind;
|
||||
t.context.pubHex = pubHex;
|
||||
remoteTiles.set(key, t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
/* peer-left: any tile keyed by this pubHex (any kind) goes LEFT */
|
||||
function tileLeft(pubHex){
|
||||
for (const [key, t] of remoteTiles){
|
||||
if (key.endsWith(':' + pubHex)) t.send('LEFT');
|
||||
}
|
||||
}
|
||||
|
||||
/* CallFSM → SubscribeFSM: subscribe whenever joined, stop when not.
|
||||
* Coming back from reconnecting → joined doesn't re-START because the
|
||||
* SubscribeFSM stayed alive through the signal-WS drop. */
|
||||
call.observe(({ state, prev }) => {
|
||||
if (state === prev) return;
|
||||
if (state === 'joined' && prev !== 'reconnecting'){
|
||||
sub.send('START');
|
||||
}
|
||||
if (state === 'leaving' || state === 'booted'){
|
||||
sub.send('STOP');
|
||||
}
|
||||
});
|
||||
|
||||
/* CallFSM → PublishFSMs: tearing down the call stops every live publish */
|
||||
call.observe(({ state, prev }) => {
|
||||
if (state === prev) return;
|
||||
if (state === 'leaving' || state === 'booted'){
|
||||
for (const k of Object.keys(pubs)){
|
||||
const ps = pubs[k].state;
|
||||
if (ps === 'acquiring' || ps === 'negotiating' || ps === 'live'){
|
||||
pubs[k].send('STOP');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { call, sub, pubs, remoteTiles, tileFor, tileLeft };
|
||||
}
|
||||
|
||||
/* ==================================================================
|
||||
* identity — ed25519 keypair, persisted in localStorage as JWK.
|
||||
*
|
||||
|
|
@ -3124,8 +3195,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
|
|||
|
||||
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> · built <span class="stamp-date">2026-06-02</span><br>
|
||||
md5 <span class="stamp-md5">a871b9e9438f857dfd47cbaa578c676d</span><br>
|
||||
sha256 <span class="stamp-sha">bdfaeba6af0fd5765508ab816cf3bde5ab405a0864368320ba26d952e0218a72</span><br>
|
||||
md5 <span class="stamp-md5">4726e6221aa4643fe259cf38b6d747c9</span><br>
|
||||
sha256 <span class="stamp-sha">2b13c8c80049461809709c2ab8058f71d2bb83fe2f257a86382110e454deaa21</span><br>
|
||||
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
|
||||
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue