UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines 2.73 kB
import{createGetSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createSendFn}from"#channel/send.js";import{createCrossChannelReceiveFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});let c=buildRouteArgs(e,i,a.name),l;try{if(a.handler)l=await a.handler(e.req,c.args);else{let t={agent:i.runtime,waitUntil:c.args.waitUntil,params:c.args.params,requestIp:c.args.requestIp};l=await a.fetch(e.req,t)}}catch(r){let i=logError(log,`channel handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),Response.json({error:`Channel handler failed.`,errorId:i,ok:!1},{status:500})}return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),l}async function dispatchChannelWebSocketRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0||a.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let c=buildRouteArgs(e,i,a.name);try{let n=await a.websocket(e.req,c.args);return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),n}catch(r){let i=logError(log,`channel websocket handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:i,ok:!1},500)}}function buildRouteArgs(t,n,o){let s=extractSocketIp(t),c=[],l=t.context.params??{},u={};for(let[e,t]of Object.entries(l))u[e]=decodeURIComponent(t);let waitUntil=e=>{c.push(e)},d=n.channels.find(e=>e.name===o)?.adapter??{kind:`channel`};return{args:{send:createSendFn(n.runtime,d,o),getSession:createGetSessionFn(n.runtime),receive:createCrossChannelReceiveFn(n.runtime,toCrossChannelTargets(n.channels)),params:u,waitUntil,requestIp:s},backgroundTasks:c}}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,r,i){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:r,channel:i})}))}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};