mirror of
https://github.com/SteamFramelyHomebrew/framely.git
synced 2026-10-23 20:00:39 +02:00
43 lines
2.7 KiB
JavaScript
43 lines
2.7 KiB
JavaScript
import {build} from 'esbuild';
|
|
import {mkdtemp,rm} from 'node:fs/promises';
|
|
import {tmpdir} from 'node:os';
|
|
import {join} from 'node:path';
|
|
import {pathToFileURL} from 'node:url';
|
|
import assert from 'node:assert/strict';
|
|
const dir=await mkdtemp(join(process.env.TMPDIR??tmpdir(),'framely-visibility-'));
|
|
try {
|
|
const file=join(dir,'visibility.mjs');
|
|
await build({entryPoints:['sdk/src/visibility.ts'],bundle:true,platform:'node',format:'esm',outfile:file});
|
|
const {createVisibilityApi,registerVisibility}=await import(pathToFileURL(file));
|
|
let deliver,resolve,unsubscribed=false;
|
|
const bridge={request:()=>new Promise(r=>resolve=r),subscribe:f=>{deliver=f;return()=>{unsubscribed=true;}}};
|
|
const states=[],api=createVisibilityApi(()=>bridge);
|
|
const off=api.onVisibilityChanged(s=>states.push(s));
|
|
const newer={known:true,captureObscured:true,pageVisible:true,sequence:2};
|
|
deliver({type:'ui.visibility.changed',data:newer});
|
|
resolve({known:true,captureObscured:false,pageVisible:false,sequence:1});
|
|
await new Promise(r=>setImmediate(r));
|
|
assert.deepEqual(states,[newer],'stale initial query must not overwrite a newer event');
|
|
off();deliver({type:'ui.visibility.changed',data:{...newer,sequence:3}});
|
|
assert(unsubscribed);assert.equal(states.length,1,'unsubscribe suppresses later callbacks');
|
|
let lateResolve;
|
|
const lateStates=[];
|
|
const late=createVisibilityApi(()=>({request:()=>new Promise(r=>lateResolve=r),subscribe:()=>()=>{}}));
|
|
late.onVisibilityChanged(s=>lateStates.push(s))();lateResolve(newer);
|
|
await new Promise(r=>setImmediate(r));assert.deepEqual(lateStates,[],'unmount suppresses pending initial query');
|
|
const restarted=[],epochApi=createVisibilityApi(()=>bridge);
|
|
const epochOff=epochApi.onVisibilityChanged(s=>restarted.push(s));
|
|
deliver({type:'ui.visibility.changed',data:{...newer,sequence:100,sessionId:'old'}});
|
|
deliver({type:'ui.visibility.changed',data:{...newer,sequence:1,sessionId:'new'}});
|
|
deliver({type:'ui.visibility.changed',data:{...newer,sequence:101,sessionId:'old'}});
|
|
assert.equal(restarted.length,2,'new host session resets ordering; retired sessions cannot overwrite it');epochOff();
|
|
let error;
|
|
const failed=createVisibilityApi(()=>({request:()=>Promise.reject(Error('disconnected')),subscribe:()=>()=>{}}));
|
|
failed.onVisibilityChanged(()=>{},e=>error=e);
|
|
await new Promise(r=>setImmediate(r));assert.equal(error.message,'disconnected');
|
|
const dispatch=registerVisibility(state=>state.captureObscured);
|
|
assert.equal(await dispatch('framely.ui.visibility',newer),true);
|
|
await assert.rejects(dispatch('fake',newer));
|
|
console.log('PASS SDK visibility initial query, event ordering, unsubscribe, disconnect and backend dispatcher');
|
|
} finally {await rm(dir,{recursive:true,force:true});}
|