bundle-fixture.mjs (2294B)
1 const u16=n=>{const b=Buffer.alloc(2);b.writeUInt16BE(n);return b;}; 2 const u32=n=>{const b=Buffer.alloc(4);b.writeUInt32BE(n);return b;}; 3 const u64=n=>{const b=Buffer.alloc(8);b.writeBigUInt64BE(BigInt(n));return b;}; 4 const str=s=>{const b=Buffer.from(s);return Buffer.concat([u32(b.length),b]);}; 5 export function makeBundle(records, namedRoots=[['root',records.length-1]], options={}){ 6 const fields=['arboricx.bundle.manifest.v1','tree-calculus-executable-object','tree-calculus.v1','indexed', 7 'arboricx.indexed.node.v1','arboricx.indexed.payload.v1','tree-calculus.v1',options.evaluation??'normal-order','arboricx.abi.tree.v1']; 8 const manifest=Buffer.concat([Buffer.from('ARBMNFST'),u16(1),u16(1),...fields.map(str),u32(0),Buffer.from([0]), 9 u32(namedRoots.length),...namedRoots.flatMap(([,root],i)=>[u32(root),str(i?'root':'default')]), 10 u32(namedRoots.length),...namedRoots.flatMap(([name,root])=>[str(name),u32(root),str('term'),str(options.abi??'arboricx.abi.tree.v1')]),u32(0),u32(0)]); 11 const nodes=Buffer.concat([u64(records.length),...records.map(record=>{ 12 const payload=record.length===0?Buffer.from([0]):record.length===1?Buffer.concat([Buffer.from([1]),u32(record[0])]):Buffer.concat([Buffer.from([2]),u32(record[0]),u32(record[1])]); 13 return Buffer.concat([u32(payload.length),payload]); 14 })]); 15 const section=(type,offset,length)=>Buffer.concat([u32(type),u16(1),u16(1),u32(0),u64(offset),u64(length),u32(0)]); 16 return Buffer.concat([Buffer.from('ARBORICX'),u16(1),u16(0),u32(2),u64(0),u64(32),section(1,96,manifest.length),section(2,96+manifest.length,nodes.length),manifest,nodes]); 17 } 18 // A valid tiny DAG plus one opaque, noncritical section: byte-boundary controls 19 // without relaxing node limits or manufacturing enormous executable trees. 20 export function sizedBundle(size){ 21 const small=makeBundle([[]]); 22 if(size<small.length+32)throw Error('Sized fixture too small'); 23 const out=Buffer.alloc(size); 24 small.copy(out,0,0,96);out.writeUInt32BE(3,12); 25 for(let i=0;i<2;i++)out.writeBigUInt64BE(small.readBigUInt64BE(44+32*i)+32n,44+32*i); 26 out.writeUInt32BE(100,96);out.writeUInt16BE(1,100); 27 out.writeBigUInt64BE(BigInt(small.length+32),108); 28 out.writeBigUInt64BE(BigInt(size-small.length-32),116); 29 small.copy(out,128,96); 30 return out; 31 }