prepare-parity.mjs (3629B)
1 import {readFile,writeFile,mkdir,copyFile} from 'node:fs/promises'; 2 import {pathToFileURL} from 'node:url'; 3 import path from 'node:path'; 4 import {createHash} from 'node:crypto'; 5 const [site,out,fixtures]=process.argv.slice(2); 6 const {makeBundle}=await import(pathToFileURL(path.join(site,'test/bundle-fixture.mjs'))); 7 await mkdir(out,{recursive:true}); 8 const index={}; 9 async function save(name,bytes){const hash=createHash('sha256').update(bytes).digest('hex');await writeFile(path.join(out,name+'.arboricx'),bytes);index[name]=hash;} 10 await save('identity',await readFile(path.join(fixtures,'id.arboricx'))); 11 const records=[[]];for(let i=1;i<=40;i++)records.push([i-1,i-1]); 12 await save('exponential',makeBundle(records)); 13 await save('wrong-profile',makeBundle([[]],[['root',0]],{evaluation:'wrong'})); 14 function fixture(name,build){ 15 const nodes=[],memo=new Map(); 16 const node=(...children)=>{const key=children.join(',');if(memo.has(key))return memo.get(key);const i=nodes.length;nodes.push(children);memo.set(key,i);return i;}; 17 const leaf=node(),stem=x=>node(x),fork=(a,b)=>node(a,b); 18 const num=n=>n===0?leaf:fork(n%2?stem(leaf):leaf,num(Math.floor(n/2))); 19 const list=xs=>xs.reduceRight((tail,x)=>fork(x,tail),leaf); 20 const text=s=>list(Array.from(s,c=>num(c.codePointAt(0)))); 21 const action=(tag,payload)=>fork(num(tag),payload); 22 const constant=t=>fork(leaf,t); 23 const result=build({leaf,stem,fork,num,list,text,action,constant}); 24 return save(name,makeBundle(nodes,[['root',result]])); 25 } 26 const io=(x,action,version=1)=>x.fork(x.text('tricuIO'),x.fork(x.num(version),action)); 27 await fixture('bad-version',x=>io(x,x.action(0,x.leaf),2)); 28 await fixture('unsupported-io',x=>io(x,x.action(99,x.leaf))); 29 await fixture('abort-io',x=>{let t=x.leaf;for(let i=0;i<40;i++)t=x.fork(t,t);return io(x,x.action(2,t));}); 30 await fixture('output-limit',x=>{ 31 let action=x.action(0,x.leaf);const output=x.action(10,x.text('x'.repeat(4096))); 32 for(let i=0;i<5;i++)action=x.action(1,x.fork(output,x.constant(action))); 33 return io(x,action); 34 }); 35 await fixture('action-limit',x=>{ 36 let action=x.action(0,x.leaf); 37 for(let i=0;i<65;i++)action=x.action(1,x.fork(x.action(0,x.leaf),x.constant(action))); 38 return io(x,action); 39 }); 40 const demos=JSON.parse(await readFile(path.join(site,'demos.json'))); 41 for(const id of ['parser','lexer'])demos.demos[id]=JSON.parse(await readFile(path.join(site,id+'-demo.json'))); 42 for(const [name,demo] of Object.entries(demos.demos))await save(name,await readFile(path.join(site,'bundles',demo.hash+'.arboricx'))); 43 await writeFile(path.join(out,'demos.json'),JSON.stringify(demos)); 44 const packages=JSON.parse(await readFile(path.join(site,'packages.json'))); 45 await writeFile(path.join(out,'packages.json'),JSON.stringify(packages)); 46 await mkdir(path.join(out,'modules'),{recursive:true}); 47 const refs=new Set(Object.values(demos.demos).flatMap(d=>[...d.source.matchAll(/^!import ([0-9a-f]{64}) /gm)].map(m=>m[1]))); 48 for(const ref of refs){ 49 const release=packages.releases.find(r=>r.manifest===ref);if(!release)throw Error('Unknown demo dependency'); 50 await copyFile(path.join(site,'bundles',release.hash+'.arboricx'),path.join(out,'modules',release.hash+'.arboricx')); 51 } 52 await copyFile(path.join(site,'environments.json'),path.join(out,'environments.json')); 53 const environments=JSON.parse(await readFile(path.join(site,'environments.json'))); 54 for(const [name,profile] of Object.entries(environments.profiles))if(profile)await save('environment-'+name,await readFile(path.join(site,'bundles',profile.hash+'.arboricx'))); 55 await writeFile(path.join(out,'index.json'),JSON.stringify(index,null,2)+'\n');