eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 3.16 kB
JavaScript
import{SESSION_INBOX_WIRE_VERSION,SESSION_INBOX_WIRE_VERSION_METADATA_KEY,WORKFLOW_TASK_AUTHORIZATION_METADATA_KEY}from"#execution/wire/session-inbox-contract.js";import{createHook}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";function createSessionCommandInbox(){let e,t,n,r=[],i=[],a=0,o=null,s,c,enqueue=e=>{i.push(e),i.sort((e,t)=>e.order-t.order),c?.(),c=void 0},arm=e=>{e.closed||e.pending||(e.pending=!0,e.resolved=void 0,(e.retired?Promise.resolve(e.hook).then(e=>({done:!1,value:e})):e.iterator.next()).then(t=>{let n={order:a++,result:t,state:e};e.resolved=n,e.enabled&&enqueue(n)},()=>{}))},enable=e=>{e.enabled=!0,e.resolved!==void 0&&enqueue(e.resolved)},createState=e=>{let t=createHook({metadata:{[SESSION_INBOX_WIRE_VERSION_METADATA_KEY]:SESSION_INBOX_WIRE_VERSION,[WORKFLOW_TASK_AUTHORIZATION_METADATA_KEY]:!0},token:e});return{closed:!1,enabled:!1,hook:t,iterator:t[Symbol.asyncIterator](),pending:!1,retired:!1}},states=()=>[e,t,n,...r].filter(e=>e!==void 0),nextRead=()=>{if(e===void 0)throw Error(`Cannot wait for session commands before claiming the stable inbox.`);if(o!==null)return o;let t=states();for(let e of t)arm(e);return t.every(e=>e.closed)?(s={order:a++,result:{done:!0,value:void 0},state:e},o=Promise.resolve(s.result),o):(o=(async()=>{for(;i.length===0;)await new Promise(e=>{c=e});let e=i.shift();return s=e,e.result})(),o)};return{async claimAuthorization(e){if(n!==void 0){if(n.hook.token===e)return;throw Error(`A session command inbox cannot change its authorization token.`)}let t=createState(e);await claimHookOwnership(t.hook),n=t},async claimStable(t){if(e!==void 0){if(e.hook.token===t)return;throw Error(`A session command inbox cannot change its stable token.`)}let n=createState(t);await claimHookOwnership(n.hook),enable(n),e=n},consumeNext(){if(s===void 0)throw Error(`Cannot consume a session command before it resolves.`);s.state.pending=!1,s.state.resolved=void 0,s.result.done&&(s.state.closed=!0),s=void 0,o=null},async dispose(){let r=[t,e,n].filter(e=>e!==void 0);t=void 0,e=void 0,n=void 0,await Promise.all(r.map(async e=>await disposeHook(e.hook)))},hasReadyAuthorization(){return n?.enabled!==!0||n.resolved===void 0?!1:s===void 0?i[0]?.state===n:s.state===n},next:nextRead,async nextWithSource(){return{result:await nextRead(),source:s!==void 0&&s.state===n?`authorization`:`session`}},setAuthorizationWindow(e){if(n===void 0){if(e)throw Error(`Cannot open the authorization window before claiming its hook.`);return}if(e){n.enabled||enable(n),s!==void 0&&s.state!==n&&n.resolved!==void 0&&n.resolved.order<s.order&&(enqueue(s),s=void 0,o=null),o!==null&&arm(n);return}n.enabled=!1;let t=i.findIndex(e=>e.state===n);t!==-1&&i.splice(t,1)},async rekeyContinuation(e){if(!e||t?.hook.token===e)return;let n=createState(e);if(t===void 0){await claimHookOwnership(n.hook),enable(n),t=n,o!==null&&arm(n);return}arm(n),await claimHookOwnership(n.hook),enable(n);let i=t;t=n,arm(i);try{await disposeHook(i.hook)}catch(e){t=void 0;try{await disposeHook(n.hook)}catch{}throw e}i.retired=!0,r.push(i)}}}export{createSessionCommandInbox};