eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 5.77 kB
JavaScript
import{existsSync}from"node:fs";import{dirname,join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{AUTHORED_ARTIFACTS_UPDATED_LOG_LINE,STRUCTURAL_RELOAD_LOG_LINE,formatChangeDetectedLogLine}from"#internal/nitro/host/dev-watcher-log.js";import{clearCompiledRuntimeAgentBundleCache}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDevelopmentSourceSnapshotWatchPaths}from"#internal/nitro/dev-runtime-source-snapshot.js";import{resolveTsConfigDependencyPaths}from"#internal/application/tsconfig-dependencies.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{computeChannelRouteRegistrations,syncChannelVirtualHandlers}from"#internal/nitro/host/channel-routes.js";import{watch}from"#compiled/chokidar/index.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{registerDevelopmentRebuildHandle}from"#internal/nitro/host/dev-rebuild-registry.js";const WATCHED_LOCKFILE_NAMES=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],WATCH_ROOT_MARKER_NAMES=[`.git`,`pnpm-workspace.yaml`],WATCHER_IGNORED_DIRECTORY_NAMES=new Set([`.generated`,`.eve`,`.git`,`.next`,`.output`,`.turbo`,`.vercel`,`.workflow-data`,`build`,`dist`,`node_modules`]);async function startAuthoredSourceWatcher(e){let t=e.preparedHost,n=!1,r=Promise.resolve(),i,o=!1,s=new Map,c=new Set,d=await resolveAuthoredWatchPaths(t),f=createWatchPathMap(d),p=watch(d,{awaitWriteFinish:{pollInterval:50,stabilityThreshold:160},followSymlinks:!1,ignoreInitial:!0,ignored:shouldIgnoreWatcherPath}),m=waitForWatcherReady(p),flush=async()=>{n||(i!==void 0&&(clearTimeout(i),i=void 0),r=r.then(async()=>{if(n)return;let r=[...s.values()];if(r.length===0)return;let i=[...c];s.clear(),c.clear();let o=t,l=hasSandboxRelatedChange(o.compileResult.project.agentRoot,i),u=hasDevelopmentEnvironmentFileChange(o.appRoot,i);console.log(formatChangeDetectedLogLine(o.appRoot,r));try{u&&loadDevelopmentEnvironmentFiles(o.appRoot);let n=await prepareApplicationHost(o.appRoot,{dev:e.nitro.options.dev===!0}),r=createNitroArtifactsConfig({appRoot:n.appRoot,dev:e.nitro.options.dev===!0});l&&startDevelopmentSandboxPrewarmInBackground({appRoot:n.appRoot,compiledArtifactsSource:resolveNitroCompiledArtifactsSource(r),log:e=>console.log(e)});let i=syncChannelVirtualHandlers(e.nitro,{artifactsConfig:r,next:computeChannelRouteRegistrations(n),previous:computeChannelRouteRegistrations(o)});clearCompiledRuntimeAgentBundleCache(),t=n,i||u?(console.log(STRUCTURAL_RELOAD_LOG_LINE),await e.nitro.hooks.callHook(`rollup:reload`)):console.log(AUTHORED_ARTIFACTS_UPDATED_LOG_LINE),f=syncWatcherPaths({nextWatchPaths:await resolveAuthoredWatchPaths(n),previousWatchPathsByKey:f,watcher:p})}catch(e){console.error(`[eve:dev] rebuild failed: ${toErrorMessage(e)}`)}}).catch(e=>{console.error(`[eve:dev] rebuild queue error: ${toErrorMessage(e)}`)}),await r)},h=registerDevelopmentRebuildHandle(t.appRoot,{flush});return p.on(`all`,(e,t)=>{n||!o||(s.set(`${e}:${t}`,{event:e,path:t}),c.add(t),i!==void 0&&clearTimeout(i),i=setTimeout(()=>{i=void 0,flush()},120))}),await m,o=!0,{async close(){n=!0,h(),i!==void 0&&(clearTimeout(i),i=void 0),await p.close(),await r},flush}}async function waitForWatcherReady(e){await new Promise((t,n)=>{e.on(`ready`,()=>{t()}),e.on(`error`,e=>{n(e)})})}async function resolveAuthoredWatchPaths(e){let t=new Set([e.compileResult.project.agentRoot,join(e.appRoot,`package.json`),join(e.appRoot,`jsconfig.json`),join(e.appRoot,`tsconfig.json`),join(e.appRoot,`tsconfig.*.json`)]),r=await resolveTsConfigWatchPaths(e.appRoot),i=await resolveDevelopmentSourceSnapshotWatchPaths(e.appRoot);for(let n of getDevelopmentEnvironmentFilePaths(e.appRoot))t.add(n);for(let e of i)t.add(e);for(let e of r)t.add(e);for(let r of resolveLockfileSearchDirectories(e.appRoot))for(let e of WATCHED_LOCKFILE_NAMES)t.add(join(r,e));return[...t].sort((e,t)=>e.localeCompare(t))}function createWatchPathMap(e){let t=new Map;for(let n of e)t.set(toWatchPathKey(n),n);return t}function syncWatcherPaths(e){let t=createWatchPathMap(e.nextWatchPaths),n=[],r=[];for(let[r,i]of t)e.previousWatchPathsByKey.has(r)||n.push(i);for(let[n,i]of e.previousWatchPathsByKey)t.has(n)||r.push(i);return n.length>0&&e.watcher.add(n),r.length>0&&e.watcher.unwatch(r),t}function toWatchPathKey(e){return e.replaceAll(`\\`,`/`)}function hasDevelopmentEnvironmentFileChange(e,t){let n=new Set(getDevelopmentEnvironmentFilePaths(e).map(e=>toWatchPathKey(resolve(e))));return t.some(e=>n.has(toWatchPathKey(resolve(e))))}function hasSandboxRelatedChange(e,t){return t.some(t=>{let n=toAgentRelativePath(e,t);return n===`sandbox.ts`||n.startsWith(`sandbox/`)||n===`workspace`||n.startsWith(`workspace/`)||n===`skills`||n.startsWith(`skills/`)})}function toAgentRelativePath(e,t){let n=toWatchPathKey(relative(resolve(e),resolve(t)));return n===`..`||n.startsWith(`../`)||n===``?``:n}function resolveLockfileSearchDirectories(e){let n=resolve(e),r=[n],a=n;for(;;){if(hasWatchRootMarker(a))return r;let e=dirname(a);if(e===a)return[n];a=e,r.push(a)}}function hasWatchRootMarker(t){return WATCH_ROOT_MARKER_NAMES.some(r=>existsSync(join(t,r)))}async function resolveTsConfigWatchPaths(e){return await resolveTsConfigDependencyPaths(e)}function shouldIgnoreWatcherPath(e){return e.replaceAll(`\\`,`/`).split(`/`).filter(Boolean).some(e=>WATCHER_IGNORED_DIRECTORY_NAMES.has(e))}export{startAuthoredSourceWatcher};