'use strict'; const {BrokerAuditEventSchema}=require('../../packages/core/broker-audit.cjs'); // Parent-only adapter. persistQueue must synchronously encrypt, write, fsync and // commit the complete queue, return undefined on success and throw on failure. // An OTLP send, boolean result or asynchronous enqueue is insufficient. // Bind current() to the authenticated child and the accepted policy generation. function createBrokerAuditPersistence({current,policyVersion,getQueue,persistQueue,onFailure}={}){ if(![current,getQueue,persistQueue,onFailure].every(fn=>typeof fn==='function')||!Number.isSafeInteger(policyVersion)||policyVersion<1)throw Error('broker-audit-parent-invalid'); let failed=false; const fail=()=>{const first=!failed;failed=true;if(first)try{onFailure();}catch{}throw Error('broker-audit-parent-unavailable');}; const active=()=>{try{return !failed&¤t()===true;}catch{return false;}}; return Object.freeze({ persist(input){ if(!active())return fail(); let event,queue; try{ let nodes=0; const plain=(value,depth=0)=>{ if(++nodes>128||depth>6)return false; if(!value||typeof value!=='object')return true; if(![Object.prototype,null].includes(Object.getPrototypeOf(value)))return false; return Object.values(Object.getOwnPropertyDescriptors(value)).every(item=>'value'in item&&plain(item.value,depth+1)); }; if(!input||typeof input!=='object'||!plain(input))return fail(); event=BrokerAuditEventSchema.parse(input);queue=getQueue(); if(event.policyVersion!==policyVersion||!Array.isArray(queue)||queue.length>=10000||queue.some(item=>item.eventId===event.eventId))return fail(); Object.freeze(event.request);if(event.file)Object.freeze(event.file);if(event.broker)Object.freeze(event.broker);Object.freeze(event); queue.push(event); const result=persistQueue(); // Fail closed for an accidentally asynchronous writer; suppress its rejected // promise without issuing a receipt or retrying uncertain persistence. if(result&&typeof result.then==='function'){Promise.resolve(result).catch(()=>{});return fail();} if(result!==undefined)return fail(); if(!active())return fail(); return Object.freeze({persisted:true,eventId:event.eventId}); }catch{return fail();} } }); } module.exports={createBrokerAuditPersistence};