[{"data":1,"prerenderedAt":4275},["ShallowReactive",2],{"navigation_docs":3,"-extend-consumer-recipes":444,"-extend-consumer-recipes-surround":4270},[4,30,80,245,358,413],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"Integrate","\u002Fintegrate","3.integrate",[85,89,157],{"title":36,"path":86,"stem":87,"icon":88},"\u002Fintegrate\u002Foverview","3.integrate\u002F0.overview","i-lucide-plug",{"title":90,"path":91,"stem":92,"children":93,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","3.integrate\u002Fadapters",[94,97,137],{"title":36,"path":95,"stem":96,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","3.integrate\u002Fadapters\u002F01.overview",{"title":98,"path":99,"stem":100,"children":101,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","3.integrate\u002Fadapters\u002Fcloud",[102,107,112,117,122,127,132],{"title":103,"path":104,"stem":105,"icon":106},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","3.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":108,"path":109,"stem":110,"icon":111},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","3.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":113,"path":114,"stem":115,"icon":116},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","3.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":118,"path":119,"stem":120,"icon":121},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","3.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":123,"path":124,"stem":125,"icon":126},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","3.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":128,"path":129,"stem":130,"icon":131},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","3.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":133,"path":134,"stem":135,"icon":136},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","3.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","3.integrate\u002Fadapters\u002Fself-hosted",[142,147,152],{"title":143,"path":144,"stem":145,"icon":146},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","3.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":148,"path":149,"stem":150,"icon":151},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","3.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":153,"path":154,"stem":155,"icon":156},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","3.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":158,"path":159,"stem":160,"children":161,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","3.integrate\u002Fframeworks",[162,166,171,176,181,186,191,196,201,206,211,216,221,226,230,235,240],{"title":36,"path":163,"stem":164,"icon":165},"\u002Fintegrate\u002Fframeworks\u002Foverview","3.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":167,"path":168,"stem":169,"icon":170},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","3.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":172,"path":173,"stem":174,"icon":175},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","3.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":177,"path":178,"stem":179,"icon":180},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","3.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":182,"path":183,"stem":184,"icon":185},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","3.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":187,"path":188,"stem":189,"icon":190},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","3.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":192,"path":193,"stem":194,"icon":195},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","3.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":197,"path":198,"stem":199,"icon":200},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","3.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":202,"path":203,"stem":204,"icon":205},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","3.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":207,"path":208,"stem":209,"icon":210},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","3.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":212,"path":213,"stem":214,"icon":215},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","3.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":217,"path":218,"stem":219,"icon":220},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","3.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":222,"path":223,"stem":224,"icon":225},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","3.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":227,"path":228,"stem":229,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","3.integrate\u002Fframeworks\u002F13.standalone",{"title":231,"path":232,"stem":233,"icon":234},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","3.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":236,"path":237,"stem":238,"icon":239},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","3.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":241,"path":242,"stem":243,"icon":244},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","3.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":246,"path":247,"stem":248,"children":249,"page":29},"Use Cases","\u002Fuse-cases","4.use-cases",[250,254,259,288,316,348,353],{"title":36,"path":251,"stem":252,"icon":253},"\u002Fuse-cases\u002Foverview","4.use-cases\u002F0.overview","i-lucide-list-checks",{"title":255,"path":256,"stem":257,"icon":258},"Client Logging","\u002Fuse-cases\u002Fclient-logging","4.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":260,"icon":261,"path":262,"stem":263,"children":264,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","4.use-cases\u002F2.ai-sdk",[265,268,273,278,283],{"title":36,"path":266,"stem":267,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","4.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":269,"path":270,"stem":271,"icon":272},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","4.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":274,"path":275,"stem":276,"icon":277},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","4.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":279,"path":280,"stem":281,"icon":282},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","4.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":284,"path":285,"stem":286,"icon":287},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","4.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":289,"icon":290,"path":291,"stem":292,"children":293,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","4.use-cases\u002F3.better-auth",[294,297,302,307,311],{"title":36,"path":295,"stem":296,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","4.use-cases\u002F3.better-auth\u002F01.overview",{"title":298,"path":299,"stem":300,"icon":301},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","4.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":303,"path":304,"stem":305,"icon":306},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","4.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":308,"path":309,"stem":310,"icon":258},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","4.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":312,"path":313,"stem":314,"icon":315},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","4.use-cases\u002F3.better-auth\u002F05.performance","i-lucide-gauge",{"title":317,"icon":318,"path":319,"stem":320,"children":321,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","4.use-cases\u002F4.audit",[322,325,330,335,340,344],{"title":36,"path":323,"stem":324,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","4.use-cases\u002F4.audit\u002F01.overview",{"title":326,"path":327,"stem":328,"icon":329},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","4.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":331,"path":332,"stem":333,"icon":334},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","4.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":336,"path":337,"stem":338,"icon":339},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","4.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":341,"path":342,"stem":343,"icon":318},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","4.use-cases\u002F4.audit\u002F05.compliance",{"title":345,"path":346,"stem":347,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","4.use-cases\u002F4.audit\u002F06.recipes",{"title":349,"path":350,"stem":351,"icon":352},"Enrichers","\u002Fuse-cases\u002Fenrichers","4.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":354,"path":355,"stem":356,"icon":357},"eve","\u002Fuse-cases\u002Feve","4.use-cases\u002F5.eve","i-custom-eve",{"title":359,"path":360,"stem":361,"children":362,"page":29},"Extend","\u002Fextend","5.extend",[363,367,372,377,382,386,390,394,398,403,408],{"title":36,"path":364,"stem":365,"icon":366},"\u002Fextend\u002Foverview","5.extend\u002F0.overview","i-lucide-blocks",{"title":368,"path":369,"stem":370,"icon":371},"Stream","\u002Fextend\u002Fstream","5.extend\u002F1.stream","i-lucide-radio-tower",{"title":373,"path":374,"stem":375,"icon":376},"Custom framework","\u002Fextend\u002Fcustom-framework","5.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":378,"path":379,"stem":380,"icon":381},"FS reader","\u002Fextend\u002Ffs-reader","5.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":345,"path":383,"stem":384,"icon":385},"\u002Fextend\u002Fconsumer-recipes","5.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":387,"path":388,"stem":389,"icon":366},"Plugins","\u002Fextend\u002Fplugins","5.extend\u002F4.plugins",{"title":391,"path":392,"stem":393,"icon":352},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","5.extend\u002F5.custom-enrichers",{"title":395,"path":396,"stem":397,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","5.extend\u002F6.tail-sampling",{"title":399,"path":400,"stem":401,"icon":402},"Identity headers","\u002Fextend\u002Fidentity-headers","5.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":404,"path":405,"stem":406,"icon":407},"Custom drains","\u002Fextend\u002Fcustom-drains","5.extend\u002F8.custom-drains","i-lucide-share-2",{"title":409,"path":410,"stem":411,"icon":412},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","5.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":414,"path":415,"stem":416,"children":417,"page":29},"Reference","\u002Freference","6.reference",[418,423,426,431,435,440],{"title":419,"path":420,"stem":421,"icon":422},"Configuration","\u002Freference\u002Fconfiguration","6.reference\u002F1.configuration","i-lucide-settings",{"title":312,"path":424,"stem":425,"icon":315},"\u002Freference\u002Fperformance","6.reference\u002F2.performance",{"title":427,"path":428,"stem":429,"icon":430},"Vite Plugin","\u002Freference\u002Fvite-plugin","6.reference\u002F3.vite-plugin","i-custom-vite",{"title":432,"path":433,"stem":434,"icon":318},"Best Practices","\u002Freference\u002Fbest-practices","6.reference\u002F4.best-practices",{"title":436,"path":437,"stem":438,"icon":439},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","6.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":441,"path":442,"stem":443,"icon":352},"Agent Skills","\u002Freference\u002Fagent-skills","6.reference\u002F6.agent-skills",{"id":445,"title":345,"body":446,"description":4263,"extension":4264,"links":4265,"meta":4266,"navigation":4267,"path":383,"seo":4268,"stem":384,"__hash__":4269},"docs\u002F5.extend\u002F3.consumer-recipes.md",{"type":447,"value":448,"toc":4250},"minimark",[449,462,537,542,563,568,1567,1574,1578,2186,2190,2556,2564,2568,2573,2627,2630,2734,2747,2751,2754,3174,3183,3187,3193,3691,3695,3698,4054,4058,4061,4220,4223,4227,4247],[450,451,452,453,457,458,461],"p",{},"Real-world patterns that combine the ",[454,455,456],"a",{"href":369},"in-process bus and stream server"," with the ",[454,459,460],{"href":379},"filesystem reader",".",[463,464,467,470,529],"prompt",{":actions":465,"description":466,"icon":385},"[\"copy\",\"cursor\",\"windsurf\"]","Build a custom evlog devtool \u002F dashboard",[450,468,469],{},"Bootstrap a local devtool or dashboard that consumes evlog wide events.",[471,472,473,486,497,516,523,526],"ul",{},[474,475,476,477,481,482,485],"li",{},"Pick the source: live (stream server over SSE) or history (",[478,479,480],"code",{},"readFsLogs"," from ",[478,483,484],{},".evlog\u002Flogs",") or both (replay then live tail)",[474,487,488,489,492,493,496],{},"For SSE: discover the URL via ",[478,490,491],{},".evlog\u002Fstream.url"," or ",[478,494,495],{},"GET \u002Fapi\u002F_evlog\u002Fstream-info",", never hard-code the port",[474,498,499,500,503,504,507,508,511,512,515],{},"Open an ",[478,501,502],{},"EventSource"," and decode messages as ",[478,505,506],{},"{ evlog: '1', type, data }"," envelopes (",[478,509,510],{},"type"," is ",[478,513,514],{},"hello | event | replay | ping",")",[474,517,518,519,522],{},"For browser tabs running on a different origin from the dev server, configure CORS via the stream server ",[478,520,521],{},"cors"," option and forward credentials carefully",[474,524,525],{},"Aggregate on the consumer side (counts, latency histograms, error groups) — keep the server simple",[474,527,528],{},"Skip on serverless platforms — the stream is in-process",[450,530,531,532],{},"Docs: ",[454,533,534],{"href":534,"rel":535},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fconsumer-recipes",[536],"nofollow",[538,539,541],"h2",{"id":540},"_1-build-a-minimal-devtool","1. Build a minimal devtool",[450,543,544,545,547,548,550,551,554,555,557,558,562],{},"A live event panel is essentially ",[478,546,502],{}," + a list. The full wire format and discovery rules — ",[478,549,491],{},", ",[478,552,553],{},"\u002Fapi\u002F_evlog\u002Fstream-info",", the ",[478,556,506],{}," envelope, and auth — are documented on the ",[454,559,561],{"href":560},"\u002Fextend\u002Fstream#wire-format","stream page",". Each recipe below assumes you've grabbed the URL via either of those mechanisms.",[564,565,567],"h3",{"id":566},"vanilla-html-js-drop-into-any-page","Vanilla HTML + JS (drop into any page)",[569,570,575],"pre",{"className":571,"code":572,"language":573,"meta":574,"style":574},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!doctype html>\n\u003Chtml>\n\u003Chead>\n  \u003Cmeta charset=\"utf-8\">\n  \u003Ctitle>evlog mini devtool\u003C\u002Ftitle>\n  \u003Cstyle>\n    body { font: 13px ui-sans-serif, system-ui; margin: 0; padding: 0; }\n    table { width: 100%; border-collapse: collapse; }\n    td, th { padding: 6px 10px; border-bottom: 1px solid #eee; text-align: left; }\n    .lvl-error { color: #ef4444 }\n    .lvl-warn  { color: #f59e0b }\n    .lvl-info  { color: #3b82f6 }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Ctable id=\"t\">\n    \u003Cthead>\u003Ctr>\u003Cth>time\u003C\u002Fth>\u003Cth>level\u003C\u002Fth>\u003Cth>service\u003C\u002Fth>\u003Cth>action\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\n    \u003Ctbody>\u003C\u002Ftbody>\n  \u003C\u002Ftable>\n\n  \u003Cscript>\n    \u002F\u002F Replace with the URL printed at startup, or fetch it from \u002Fapi\u002F_evlog\u002Fstream-info\n    const STREAM_URL = 'http:\u002F\u002F127.0.0.1:51203'\n    const tbody = document.querySelector('#t tbody')\n    const es = new EventSource(STREAM_URL)\n\n    es.onmessage = (e) => {\n      const env = JSON.parse(e.data)\n      if (env.evlog !== '1') return\n      if (env.type !== 'event' && env.type !== 'replay') return\n\n      const w = env.data\n      const tr = document.createElement('tr')\n      tr.innerHTML = `\n        \u003Ctd>${new Date(w.timestamp).toLocaleTimeString()}\u003C\u002Ftd>\n        \u003Ctd class=\"lvl-${w.level}\">${w.level}\u003C\u002Ftd>\n        \u003Ctd>${w.service ?? ''}\u003C\u002Ftd>\n        \u003Ctd>${w.action ?? w.message ?? w.path ?? ''}\u003C\u002Ftd>\n      `\n      tbody.prepend(tr)\n      while (tbody.children.length > 200) tbody.lastElementChild.remove()\n    }\n  \u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[478,576,577,597,607,617,643,665,675,730,760,816,841,863,884,894,903,913,935,1014,1028,1037,1044,1054,1061,1081,1114,1133,1138,1167,1197,1230,1274,1279,1296,1323,1339,1376,1408,1430,1468,1474,1491,1534,1540,1549,1558],{"__ignoreMap":574},[578,579,582,586,590,594],"span",{"class":580,"line":581},"line",1,[578,583,585],{"class":584},"sMK4o","\u003C!",[578,587,589],{"class":588},"swJcz","doctype",[578,591,593],{"class":592},"spNyl"," html",[578,595,596],{"class":584},">\n",[578,598,600,603,605],{"class":580,"line":599},2,[578,601,602],{"class":584},"\u003C",[578,604,573],{"class":588},[578,606,596],{"class":584},[578,608,610,612,615],{"class":580,"line":609},3,[578,611,602],{"class":584},[578,613,614],{"class":588},"head",[578,616,596],{"class":584},[578,618,620,623,626,629,632,635,639,641],{"class":580,"line":619},4,[578,621,622],{"class":584},"  \u003C",[578,624,625],{"class":588},"meta",[578,627,628],{"class":592}," charset",[578,630,631],{"class":584},"=",[578,633,634],{"class":584},"\"",[578,636,638],{"class":637},"sfazB","utf-8",[578,640,634],{"class":584},[578,642,596],{"class":584},[578,644,646,648,651,654,658,661,663],{"class":580,"line":645},5,[578,647,622],{"class":584},[578,649,650],{"class":588},"title",[578,652,653],{"class":584},">",[578,655,657],{"class":656},"sTEyZ","evlog mini devtool",[578,659,660],{"class":584},"\u003C\u002F",[578,662,650],{"class":588},[578,664,596],{"class":584},[578,666,668,670,673],{"class":580,"line":667},6,[578,669,622],{"class":584},[578,671,672],{"class":588},"style",[578,674,596],{"class":584},[578,676,678,682,685,689,692,696,699,702,705,708,711,713,716,718,721,723,725,727],{"class":580,"line":677},7,[578,679,681],{"class":680},"sBMFI","    body",[578,683,684],{"class":584}," {",[578,686,688],{"class":687},"sqsOY"," font",[578,690,691],{"class":584},":",[578,693,695],{"class":694},"sbssI"," 13px",[578,697,698],{"class":656}," ui-sans-serif",[578,700,701],{"class":584},",",[578,703,704],{"class":656}," system-ui",[578,706,707],{"class":584},";",[578,709,710],{"class":687}," margin",[578,712,691],{"class":584},[578,714,715],{"class":694}," 0",[578,717,707],{"class":584},[578,719,720],{"class":687}," padding",[578,722,691],{"class":584},[578,724,715],{"class":694},[578,726,707],{"class":584},[578,728,729],{"class":584}," }\n",[578,731,733,736,738,741,743,746,748,751,753,756,758],{"class":580,"line":732},8,[578,734,735],{"class":680},"    table",[578,737,684],{"class":584},[578,739,740],{"class":687}," width",[578,742,691],{"class":584},[578,744,745],{"class":694}," 100%",[578,747,707],{"class":584},[578,749,750],{"class":687}," border-collapse",[578,752,691],{"class":584},[578,754,755],{"class":656}," collapse",[578,757,707],{"class":584},[578,759,729],{"class":584},[578,761,763,766,768,771,773,775,777,780,783,785,788,790,793,796,799,802,804,807,809,812,814],{"class":580,"line":762},9,[578,764,765],{"class":680},"    td",[578,767,701],{"class":584},[578,769,770],{"class":680}," th",[578,772,684],{"class":584},[578,774,720],{"class":687},[578,776,691],{"class":584},[578,778,779],{"class":694}," 6px",[578,781,782],{"class":694}," 10px",[578,784,707],{"class":584},[578,786,787],{"class":687}," border-bottom",[578,789,691],{"class":584},[578,791,792],{"class":694}," 1px",[578,794,795],{"class":656}," solid ",[578,797,798],{"class":584},"#",[578,800,801],{"class":656},"eee",[578,803,707],{"class":584},[578,805,806],{"class":687}," text-align",[578,808,691],{"class":584},[578,810,811],{"class":656}," left",[578,813,707],{"class":584},[578,815,729],{"class":584},[578,817,819,822,825,827,830,832,835,838],{"class":580,"line":818},10,[578,820,821],{"class":584},"    .",[578,823,824],{"class":680},"lvl-error",[578,826,684],{"class":584},[578,828,829],{"class":687}," color",[578,831,691],{"class":584},[578,833,834],{"class":584}," #",[578,836,837],{"class":656},"ef4444 ",[578,839,840],{"class":584},"}\n",[578,842,844,846,849,852,854,856,858,861],{"class":580,"line":843},11,[578,845,821],{"class":584},[578,847,848],{"class":680},"lvl-warn",[578,850,851],{"class":584},"  {",[578,853,829],{"class":687},[578,855,691],{"class":584},[578,857,834],{"class":584},[578,859,860],{"class":656},"f59e0b ",[578,862,840],{"class":584},[578,864,866,868,871,873,875,877,879,882],{"class":580,"line":865},12,[578,867,821],{"class":584},[578,869,870],{"class":680},"lvl-info",[578,872,851],{"class":584},[578,874,829],{"class":687},[578,876,691],{"class":584},[578,878,834],{"class":584},[578,880,881],{"class":656},"3b82f6 ",[578,883,840],{"class":584},[578,885,887,890,892],{"class":580,"line":886},13,[578,888,889],{"class":584},"  \u003C\u002F",[578,891,672],{"class":588},[578,893,596],{"class":584},[578,895,897,899,901],{"class":580,"line":896},14,[578,898,660],{"class":584},[578,900,614],{"class":588},[578,902,596],{"class":584},[578,904,906,908,911],{"class":580,"line":905},15,[578,907,602],{"class":584},[578,909,910],{"class":588},"body",[578,912,596],{"class":584},[578,914,916,918,921,924,926,928,931,933],{"class":580,"line":915},16,[578,917,622],{"class":584},[578,919,920],{"class":588},"table",[578,922,923],{"class":592}," id",[578,925,631],{"class":584},[578,927,634],{"class":584},[578,929,930],{"class":637},"t",[578,932,634],{"class":584},[578,934,596],{"class":584},[578,936,938,941,944,947,950,952,955,957,960,962,964,966,968,970,973,975,977,979,981,983,986,988,990,992,994,996,999,1001,1003,1006,1008,1010,1012],{"class":580,"line":937},17,[578,939,940],{"class":584},"    \u003C",[578,942,943],{"class":588},"thead",[578,945,946],{"class":584},">\u003C",[578,948,949],{"class":588},"tr",[578,951,946],{"class":584},[578,953,954],{"class":588},"th",[578,956,653],{"class":584},[578,958,959],{"class":656},"time",[578,961,660],{"class":584},[578,963,954],{"class":588},[578,965,946],{"class":584},[578,967,954],{"class":588},[578,969,653],{"class":584},[578,971,972],{"class":656},"level",[578,974,660],{"class":584},[578,976,954],{"class":588},[578,978,946],{"class":584},[578,980,954],{"class":588},[578,982,653],{"class":584},[578,984,985],{"class":656},"service",[578,987,660],{"class":584},[578,989,954],{"class":588},[578,991,946],{"class":584},[578,993,954],{"class":588},[578,995,653],{"class":584},[578,997,998],{"class":656},"action",[578,1000,660],{"class":584},[578,1002,954],{"class":588},[578,1004,1005],{"class":584},">\u003C\u002F",[578,1007,949],{"class":588},[578,1009,1005],{"class":584},[578,1011,943],{"class":588},[578,1013,596],{"class":584},[578,1015,1017,1019,1022,1024,1026],{"class":580,"line":1016},18,[578,1018,940],{"class":584},[578,1020,1021],{"class":588},"tbody",[578,1023,1005],{"class":584},[578,1025,1021],{"class":588},[578,1027,596],{"class":584},[578,1029,1031,1033,1035],{"class":580,"line":1030},19,[578,1032,889],{"class":584},[578,1034,920],{"class":588},[578,1036,596],{"class":584},[578,1038,1040],{"class":580,"line":1039},20,[578,1041,1043],{"emptyLinePlaceholder":1042},true,"\n",[578,1045,1047,1049,1052],{"class":580,"line":1046},21,[578,1048,622],{"class":584},[578,1050,1051],{"class":588},"script",[578,1053,596],{"class":584},[578,1055,1057],{"class":580,"line":1056},22,[578,1058,1060],{"class":1059},"sHwdD","    \u002F\u002F Replace with the URL printed at startup, or fetch it from \u002Fapi\u002F_evlog\u002Fstream-info\n",[578,1062,1064,1067,1070,1072,1075,1078],{"class":580,"line":1063},23,[578,1065,1066],{"class":592},"    const",[578,1068,1069],{"class":656}," STREAM_URL ",[578,1071,631],{"class":584},[578,1073,1074],{"class":584}," '",[578,1076,1077],{"class":637},"http:\u002F\u002F127.0.0.1:51203",[578,1079,1080],{"class":584},"'\n",[578,1082,1084,1086,1089,1091,1094,1096,1100,1103,1106,1109,1111],{"class":580,"line":1083},24,[578,1085,1066],{"class":592},[578,1087,1088],{"class":656}," tbody ",[578,1090,631],{"class":584},[578,1092,1093],{"class":656}," document",[578,1095,461],{"class":584},[578,1097,1099],{"class":1098},"s2Zo4","querySelector",[578,1101,1102],{"class":656},"(",[578,1104,1105],{"class":584},"'",[578,1107,1108],{"class":637},"#t tbody",[578,1110,1105],{"class":584},[578,1112,1113],{"class":656},")\n",[578,1115,1117,1119,1122,1124,1127,1130],{"class":580,"line":1116},25,[578,1118,1066],{"class":592},[578,1120,1121],{"class":656}," es ",[578,1123,631],{"class":584},[578,1125,1126],{"class":584}," new",[578,1128,1129],{"class":1098}," EventSource",[578,1131,1132],{"class":656},"(STREAM_URL)\n",[578,1134,1136],{"class":580,"line":1135},26,[578,1137,1043],{"emptyLinePlaceholder":1042},[578,1139,1141,1144,1146,1149,1152,1155,1159,1161,1164],{"class":580,"line":1140},27,[578,1142,1143],{"class":656},"    es",[578,1145,461],{"class":584},[578,1147,1148],{"class":1098},"onmessage",[578,1150,1151],{"class":584}," =",[578,1153,1154],{"class":584}," (",[578,1156,1158],{"class":1157},"sHdIc","e",[578,1160,515],{"class":584},[578,1162,1163],{"class":592}," =>",[578,1165,1166],{"class":584}," {\n",[578,1168,1170,1173,1176,1178,1181,1183,1186,1188,1190,1192,1195],{"class":580,"line":1169},28,[578,1171,1172],{"class":592},"      const",[578,1174,1175],{"class":656}," env",[578,1177,1151],{"class":584},[578,1179,1180],{"class":656}," JSON",[578,1182,461],{"class":584},[578,1184,1185],{"class":1098},"parse",[578,1187,1102],{"class":588},[578,1189,1158],{"class":656},[578,1191,461],{"class":584},[578,1193,1194],{"class":656},"data",[578,1196,1113],{"class":588},[578,1198,1200,1204,1206,1209,1211,1214,1217,1219,1222,1224,1227],{"class":580,"line":1199},29,[578,1201,1203],{"class":1202},"s7zQu","      if",[578,1205,1154],{"class":588},[578,1207,1208],{"class":656},"env",[578,1210,461],{"class":584},[578,1212,1213],{"class":656},"evlog",[578,1215,1216],{"class":584}," !==",[578,1218,1074],{"class":584},[578,1220,1221],{"class":637},"1",[578,1223,1105],{"class":584},[578,1225,1226],{"class":588},") ",[578,1228,1229],{"class":1202},"return\n",[578,1231,1233,1235,1237,1239,1241,1243,1245,1247,1250,1252,1255,1257,1259,1261,1263,1265,1268,1270,1272],{"class":580,"line":1232},30,[578,1234,1203],{"class":1202},[578,1236,1154],{"class":588},[578,1238,1208],{"class":656},[578,1240,461],{"class":584},[578,1242,510],{"class":656},[578,1244,1216],{"class":584},[578,1246,1074],{"class":584},[578,1248,1249],{"class":637},"event",[578,1251,1105],{"class":584},[578,1253,1254],{"class":584}," &&",[578,1256,1175],{"class":656},[578,1258,461],{"class":584},[578,1260,510],{"class":656},[578,1262,1216],{"class":584},[578,1264,1074],{"class":584},[578,1266,1267],{"class":637},"replay",[578,1269,1105],{"class":584},[578,1271,1226],{"class":588},[578,1273,1229],{"class":1202},[578,1275,1277],{"class":580,"line":1276},31,[578,1278,1043],{"emptyLinePlaceholder":1042},[578,1280,1282,1284,1287,1289,1291,1293],{"class":580,"line":1281},32,[578,1283,1172],{"class":592},[578,1285,1286],{"class":656}," w",[578,1288,1151],{"class":584},[578,1290,1175],{"class":656},[578,1292,461],{"class":584},[578,1294,1295],{"class":656},"data\n",[578,1297,1299,1301,1304,1306,1308,1310,1313,1315,1317,1319,1321],{"class":580,"line":1298},33,[578,1300,1172],{"class":592},[578,1302,1303],{"class":656}," tr",[578,1305,1151],{"class":584},[578,1307,1093],{"class":656},[578,1309,461],{"class":584},[578,1311,1312],{"class":1098},"createElement",[578,1314,1102],{"class":588},[578,1316,1105],{"class":584},[578,1318,949],{"class":637},[578,1320,1105],{"class":584},[578,1322,1113],{"class":588},[578,1324,1326,1329,1331,1334,1336],{"class":580,"line":1325},34,[578,1327,1328],{"class":656},"      tr",[578,1330,461],{"class":584},[578,1332,1333],{"class":656},"innerHTML",[578,1335,1151],{"class":584},[578,1337,1338],{"class":584}," `\n",[578,1340,1342,1345,1348,1351,1354,1357,1359,1362,1364,1367,1370,1373],{"class":580,"line":1341},35,[578,1343,1344],{"class":637},"        \u003Ctd>",[578,1346,1347],{"class":584},"${",[578,1349,1350],{"class":584},"new",[578,1352,1353],{"class":1098}," Date",[578,1355,1356],{"class":656},"(w",[578,1358,461],{"class":584},[578,1360,1361],{"class":656},"timestamp)",[578,1363,461],{"class":584},[578,1365,1366],{"class":1098},"toLocaleTimeString",[578,1368,1369],{"class":656},"()",[578,1371,1372],{"class":584},"}",[578,1374,1375],{"class":637},"\u003C\u002Ftd>\n",[578,1377,1379,1382,1384,1387,1389,1391,1393,1396,1398,1400,1402,1404,1406],{"class":580,"line":1378},36,[578,1380,1381],{"class":637},"        \u003Ctd class=\"lvl-",[578,1383,1347],{"class":584},[578,1385,1386],{"class":656},"w",[578,1388,461],{"class":584},[578,1390,972],{"class":656},[578,1392,1372],{"class":584},[578,1394,1395],{"class":637},"\">",[578,1397,1347],{"class":584},[578,1399,1386],{"class":656},[578,1401,461],{"class":584},[578,1403,972],{"class":656},[578,1405,1372],{"class":584},[578,1407,1375],{"class":637},[578,1409,1411,1413,1415,1417,1419,1422,1425,1428],{"class":580,"line":1410},37,[578,1412,1344],{"class":637},[578,1414,1347],{"class":584},[578,1416,1386],{"class":656},[578,1418,461],{"class":584},[578,1420,1421],{"class":656},"service ",[578,1423,1424],{"class":584},"??",[578,1426,1427],{"class":584}," ''}",[578,1429,1375],{"class":637},[578,1431,1433,1435,1437,1439,1441,1444,1446,1448,1450,1453,1455,1457,1459,1462,1464,1466],{"class":580,"line":1432},38,[578,1434,1344],{"class":637},[578,1436,1347],{"class":584},[578,1438,1386],{"class":656},[578,1440,461],{"class":584},[578,1442,1443],{"class":656},"action ",[578,1445,1424],{"class":584},[578,1447,1286],{"class":656},[578,1449,461],{"class":584},[578,1451,1452],{"class":656},"message ",[578,1454,1424],{"class":584},[578,1456,1286],{"class":656},[578,1458,461],{"class":584},[578,1460,1461],{"class":656},"path ",[578,1463,1424],{"class":584},[578,1465,1427],{"class":584},[578,1467,1375],{"class":637},[578,1469,1471],{"class":580,"line":1470},39,[578,1472,1473],{"class":584},"      `\n",[578,1475,1477,1480,1482,1485,1487,1489],{"class":580,"line":1476},40,[578,1478,1479],{"class":656},"      tbody",[578,1481,461],{"class":584},[578,1483,1484],{"class":1098},"prepend",[578,1486,1102],{"class":588},[578,1488,949],{"class":656},[578,1490,1113],{"class":588},[578,1492,1494,1497,1499,1501,1503,1506,1508,1511,1514,1517,1519,1521,1523,1526,1528,1531],{"class":580,"line":1493},41,[578,1495,1496],{"class":1202},"      while",[578,1498,1154],{"class":588},[578,1500,1021],{"class":656},[578,1502,461],{"class":584},[578,1504,1505],{"class":656},"children",[578,1507,461],{"class":584},[578,1509,1510],{"class":656},"length",[578,1512,1513],{"class":584}," >",[578,1515,1516],{"class":694}," 200",[578,1518,1226],{"class":588},[578,1520,1021],{"class":656},[578,1522,461],{"class":584},[578,1524,1525],{"class":656},"lastElementChild",[578,1527,461],{"class":584},[578,1529,1530],{"class":1098},"remove",[578,1532,1533],{"class":588},"()\n",[578,1535,1537],{"class":580,"line":1536},42,[578,1538,1539],{"class":584},"    }\n",[578,1541,1543,1545,1547],{"class":580,"line":1542},43,[578,1544,889],{"class":584},[578,1546,1051],{"class":588},[578,1548,596],{"class":584},[578,1550,1552,1554,1556],{"class":580,"line":1551},44,[578,1553,660],{"class":584},[578,1555,910],{"class":588},[578,1557,596],{"class":584},[578,1559,1561,1563,1565],{"class":580,"line":1560},45,[578,1562,660],{"class":584},[578,1564,573],{"class":588},[578,1566,596],{"class":584},[450,1568,1569,1570,1573],{},"Save as ",[478,1571,1572],{},"devtool.html",", open in any browser tab while your evlog-instrumented dev server is running. That's the whole MVP.",[564,1575,1577],{"id":1576},"vue-3-component","Vue 3 component",[569,1579,1583],{"className":1580,"code":1581,"language":1582,"meta":574,"style":574},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref } from 'vue'\nimport type { WideEvent } from 'evlog'\n\nconst events = ref\u003CWideEvent[]>([])\nlet es: EventSource | null = null\n\nonMounted(async () => {\n  \u002F\u002F Discover URL via the same-origin info endpoint (Nuxt)\n  const { url } = await $fetch\u003C{ url: string | null }>('\u002Fapi\u002F_evlog\u002Fstream-info')\n  if (!url) return\n\n  es = new EventSource(url)\n  es.onmessage = (e) => {\n    const env = JSON.parse(e.data)\n    if (env.evlog !== '1') return\n    if (env.type === 'event' || env.type === 'replay') {\n      events.value.unshift(env.data as WideEvent)\n      if (events.value.length > 500) events.value.length = 500\n    }\n  }\n})\n\nonBeforeUnmount(() => es?.close())\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cul>\n    \u003Cli v-for=\"(e, i) in events\" :key=\"`${e.timestamp}-${i}`\">\n      \u003Ccode>{{ e.level }}\u003C\u002Fcode>\n      \u003Cstrong>{{ e.service }}\u003C\u002Fstrong>\n      \u003Cspan>{{ e.action ?? e.message ?? e.path }}\u003C\u002Fspan>\n    \u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Ftemplate>\n","vue",[478,1584,1585,1608,1640,1662,1666,1691,1714,1718,1735,1740,1787,1804,1808,1825,1845,1869,1894,1937,1967,2006,2010,2015,2021,2025,2047,2055,2059,2068,2076,2108,2126,2144,2161,2170,2178],{"__ignoreMap":574},[578,1586,1587,1589,1591,1594,1597,1599,1601,1604,1606],{"class":580,"line":581},[578,1588,602],{"class":584},[578,1590,1051],{"class":588},[578,1592,1593],{"class":592}," setup",[578,1595,1596],{"class":592}," lang",[578,1598,631],{"class":584},[578,1600,634],{"class":584},[578,1602,1603],{"class":637},"ts",[578,1605,634],{"class":584},[578,1607,596],{"class":584},[578,1609,1610,1613,1615,1618,1620,1623,1625,1628,1631,1634,1636,1638],{"class":580,"line":599},[578,1611,1612],{"class":1202},"import",[578,1614,684],{"class":584},[578,1616,1617],{"class":656}," onBeforeUnmount",[578,1619,701],{"class":584},[578,1621,1622],{"class":656}," onMounted",[578,1624,701],{"class":584},[578,1626,1627],{"class":656}," ref",[578,1629,1630],{"class":584}," }",[578,1632,1633],{"class":1202}," from",[578,1635,1074],{"class":584},[578,1637,1582],{"class":637},[578,1639,1080],{"class":584},[578,1641,1642,1644,1647,1649,1652,1654,1656,1658,1660],{"class":580,"line":609},[578,1643,1612],{"class":1202},[578,1645,1646],{"class":1202}," type",[578,1648,684],{"class":584},[578,1650,1651],{"class":656}," WideEvent",[578,1653,1630],{"class":584},[578,1655,1633],{"class":1202},[578,1657,1074],{"class":584},[578,1659,1213],{"class":637},[578,1661,1080],{"class":584},[578,1663,1664],{"class":580,"line":619},[578,1665,1043],{"emptyLinePlaceholder":1042},[578,1667,1668,1671,1674,1676,1678,1680,1683,1686,1688],{"class":580,"line":645},[578,1669,1670],{"class":592},"const",[578,1672,1673],{"class":656}," events ",[578,1675,631],{"class":584},[578,1677,1627],{"class":1098},[578,1679,602],{"class":584},[578,1681,1682],{"class":680},"WideEvent",[578,1684,1685],{"class":656},"[]",[578,1687,653],{"class":584},[578,1689,1690],{"class":656},"([])\n",[578,1692,1693,1696,1699,1701,1703,1706,1709,1711],{"class":580,"line":667},[578,1694,1695],{"class":592},"let",[578,1697,1698],{"class":656}," es",[578,1700,691],{"class":584},[578,1702,1129],{"class":680},[578,1704,1705],{"class":584}," |",[578,1707,1708],{"class":680}," null",[578,1710,1151],{"class":584},[578,1712,1713],{"class":584}," null\n",[578,1715,1716],{"class":580,"line":677},[578,1717,1043],{"emptyLinePlaceholder":1042},[578,1719,1720,1723,1725,1728,1731,1733],{"class":580,"line":732},[578,1721,1722],{"class":1098},"onMounted",[578,1724,1102],{"class":656},[578,1726,1727],{"class":592},"async",[578,1729,1730],{"class":584}," ()",[578,1732,1163],{"class":592},[578,1734,1166],{"class":584},[578,1736,1737],{"class":580,"line":762},[578,1738,1739],{"class":1059},"  \u002F\u002F Discover URL via the same-origin info endpoint (Nuxt)\n",[578,1741,1742,1745,1747,1750,1752,1754,1757,1760,1763,1765,1767,1770,1772,1774,1777,1779,1781,1783,1785],{"class":580,"line":818},[578,1743,1744],{"class":592},"  const",[578,1746,684],{"class":584},[578,1748,1749],{"class":656}," url",[578,1751,1630],{"class":584},[578,1753,1151],{"class":584},[578,1755,1756],{"class":1202}," await",[578,1758,1759],{"class":1098}," $fetch",[578,1761,1762],{"class":584},"\u003C{",[578,1764,1749],{"class":588},[578,1766,691],{"class":584},[578,1768,1769],{"class":680}," string",[578,1771,1705],{"class":584},[578,1773,1708],{"class":680},[578,1775,1776],{"class":584}," }>",[578,1778,1102],{"class":588},[578,1780,1105],{"class":584},[578,1782,553],{"class":637},[578,1784,1105],{"class":584},[578,1786,1113],{"class":588},[578,1788,1789,1792,1794,1797,1800,1802],{"class":580,"line":843},[578,1790,1791],{"class":1202},"  if",[578,1793,1154],{"class":588},[578,1795,1796],{"class":584},"!",[578,1798,1799],{"class":656},"url",[578,1801,1226],{"class":588},[578,1803,1229],{"class":1202},[578,1805,1806],{"class":580,"line":865},[578,1807,1043],{"emptyLinePlaceholder":1042},[578,1809,1810,1813,1815,1817,1819,1821,1823],{"class":580,"line":886},[578,1811,1812],{"class":656},"  es",[578,1814,1151],{"class":584},[578,1816,1126],{"class":584},[578,1818,1129],{"class":1098},[578,1820,1102],{"class":588},[578,1822,1799],{"class":656},[578,1824,1113],{"class":588},[578,1826,1827,1829,1831,1833,1835,1837,1839,1841,1843],{"class":580,"line":896},[578,1828,1812],{"class":656},[578,1830,461],{"class":584},[578,1832,1148],{"class":1098},[578,1834,1151],{"class":584},[578,1836,1154],{"class":584},[578,1838,1158],{"class":1157},[578,1840,515],{"class":584},[578,1842,1163],{"class":592},[578,1844,1166],{"class":584},[578,1846,1847,1849,1851,1853,1855,1857,1859,1861,1863,1865,1867],{"class":580,"line":905},[578,1848,1066],{"class":592},[578,1850,1175],{"class":656},[578,1852,1151],{"class":584},[578,1854,1180],{"class":656},[578,1856,461],{"class":584},[578,1858,1185],{"class":1098},[578,1860,1102],{"class":588},[578,1862,1158],{"class":656},[578,1864,461],{"class":584},[578,1866,1194],{"class":656},[578,1868,1113],{"class":588},[578,1870,1871,1874,1876,1878,1880,1882,1884,1886,1888,1890,1892],{"class":580,"line":915},[578,1872,1873],{"class":1202},"    if",[578,1875,1154],{"class":588},[578,1877,1208],{"class":656},[578,1879,461],{"class":584},[578,1881,1213],{"class":656},[578,1883,1216],{"class":584},[578,1885,1074],{"class":584},[578,1887,1221],{"class":637},[578,1889,1105],{"class":584},[578,1891,1226],{"class":588},[578,1893,1229],{"class":1202},[578,1895,1896,1898,1900,1902,1904,1906,1909,1911,1913,1915,1918,1920,1922,1924,1926,1928,1930,1932,1934],{"class":580,"line":937},[578,1897,1873],{"class":1202},[578,1899,1154],{"class":588},[578,1901,1208],{"class":656},[578,1903,461],{"class":584},[578,1905,510],{"class":656},[578,1907,1908],{"class":584}," ===",[578,1910,1074],{"class":584},[578,1912,1249],{"class":637},[578,1914,1105],{"class":584},[578,1916,1917],{"class":584}," ||",[578,1919,1175],{"class":656},[578,1921,461],{"class":584},[578,1923,510],{"class":656},[578,1925,1908],{"class":584},[578,1927,1074],{"class":584},[578,1929,1267],{"class":637},[578,1931,1105],{"class":584},[578,1933,1226],{"class":588},[578,1935,1936],{"class":584},"{\n",[578,1938,1939,1942,1944,1947,1949,1952,1954,1956,1958,1960,1963,1965],{"class":580,"line":1016},[578,1940,1941],{"class":656},"      events",[578,1943,461],{"class":584},[578,1945,1946],{"class":656},"value",[578,1948,461],{"class":584},[578,1950,1951],{"class":1098},"unshift",[578,1953,1102],{"class":588},[578,1955,1208],{"class":656},[578,1957,461],{"class":584},[578,1959,1194],{"class":656},[578,1961,1962],{"class":1202}," as",[578,1964,1651],{"class":680},[578,1966,1113],{"class":588},[578,1968,1969,1971,1973,1976,1978,1980,1982,1984,1986,1989,1991,1993,1995,1997,1999,2001,2003],{"class":580,"line":1030},[578,1970,1203],{"class":1202},[578,1972,1154],{"class":588},[578,1974,1975],{"class":656},"events",[578,1977,461],{"class":584},[578,1979,1946],{"class":656},[578,1981,461],{"class":584},[578,1983,1510],{"class":656},[578,1985,1513],{"class":584},[578,1987,1988],{"class":694}," 500",[578,1990,1226],{"class":588},[578,1992,1975],{"class":656},[578,1994,461],{"class":584},[578,1996,1946],{"class":656},[578,1998,461],{"class":584},[578,2000,1510],{"class":656},[578,2002,1151],{"class":584},[578,2004,2005],{"class":694}," 500\n",[578,2007,2008],{"class":580,"line":1039},[578,2009,1539],{"class":584},[578,2011,2012],{"class":580,"line":1046},[578,2013,2014],{"class":584},"  }\n",[578,2016,2017,2019],{"class":580,"line":1056},[578,2018,1372],{"class":584},[578,2020,1113],{"class":656},[578,2022,2023],{"class":580,"line":1063},[578,2024,1043],{"emptyLinePlaceholder":1042},[578,2026,2027,2030,2032,2034,2036,2038,2041,2044],{"class":580,"line":1083},[578,2028,2029],{"class":1098},"onBeforeUnmount",[578,2031,1102],{"class":656},[578,2033,1369],{"class":584},[578,2035,1163],{"class":592},[578,2037,1698],{"class":656},[578,2039,2040],{"class":584},"?.",[578,2042,2043],{"class":1098},"close",[578,2045,2046],{"class":656},"())\n",[578,2048,2049,2051,2053],{"class":580,"line":1116},[578,2050,660],{"class":584},[578,2052,1051],{"class":588},[578,2054,596],{"class":584},[578,2056,2057],{"class":580,"line":1135},[578,2058,1043],{"emptyLinePlaceholder":1042},[578,2060,2061,2063,2066],{"class":580,"line":1140},[578,2062,602],{"class":584},[578,2064,2065],{"class":588},"template",[578,2067,596],{"class":584},[578,2069,2070,2072,2074],{"class":580,"line":1169},[578,2071,622],{"class":584},[578,2073,471],{"class":588},[578,2075,596],{"class":584},[578,2077,2078,2080,2082,2085,2087,2089,2092,2094,2097,2099,2101,2104,2106],{"class":580,"line":1199},[578,2079,940],{"class":584},[578,2081,474],{"class":588},[578,2083,2084],{"class":592}," v-for",[578,2086,631],{"class":584},[578,2088,634],{"class":584},[578,2090,2091],{"class":637},"(e, i) in events",[578,2093,634],{"class":584},[578,2095,2096],{"class":592}," :key",[578,2098,631],{"class":584},[578,2100,634],{"class":584},[578,2102,2103],{"class":637},"`${e.timestamp}-${i}`",[578,2105,634],{"class":584},[578,2107,596],{"class":584},[578,2109,2110,2113,2115,2117,2120,2122,2124],{"class":580,"line":1232},[578,2111,2112],{"class":584},"      \u003C",[578,2114,478],{"class":588},[578,2116,653],{"class":584},[578,2118,2119],{"class":656},"{{ e.level }}",[578,2121,660],{"class":584},[578,2123,478],{"class":588},[578,2125,596],{"class":584},[578,2127,2128,2130,2133,2135,2138,2140,2142],{"class":580,"line":1276},[578,2129,2112],{"class":584},[578,2131,2132],{"class":588},"strong",[578,2134,653],{"class":584},[578,2136,2137],{"class":656},"{{ e.service }}",[578,2139,660],{"class":584},[578,2141,2132],{"class":588},[578,2143,596],{"class":584},[578,2145,2146,2148,2150,2152,2155,2157,2159],{"class":580,"line":1281},[578,2147,2112],{"class":584},[578,2149,578],{"class":588},[578,2151,653],{"class":584},[578,2153,2154],{"class":656},"{{ e.action ?? e.message ?? e.path }}",[578,2156,660],{"class":584},[578,2158,578],{"class":588},[578,2160,596],{"class":584},[578,2162,2163,2166,2168],{"class":580,"line":1298},[578,2164,2165],{"class":584},"    \u003C\u002F",[578,2167,474],{"class":588},[578,2169,596],{"class":584},[578,2171,2172,2174,2176],{"class":580,"line":1325},[578,2173,889],{"class":584},[578,2175,471],{"class":588},[578,2177,596],{"class":584},[578,2179,2180,2182,2184],{"class":580,"line":1341},[578,2181,660],{"class":584},[578,2183,2065],{"class":588},[578,2185,596],{"class":584},[564,2187,2189],{"id":2188},"react-hook","React hook",[569,2191,2194],{"className":2192,"code":2193,"language":1603,"meta":574,"style":574},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { useEffect, useState } from 'react'\nimport type { WideEvent } from 'evlog'\n\nexport function useEvlogStream(url: string) {\n  const [events, setEvents] = useState\u003CWideEvent[]>([])\n\n  useEffect(() => {\n    if (!url) return\n    const es = new EventSource(url)\n    es.onmessage = (e) => {\n      const env = JSON.parse(e.data)\n      if (env.evlog !== '1') return\n      if (env.type === 'event' || env.type === 'replay') {\n        setEvents(prev => [env.data, ...prev].slice(0, 500))\n      }\n    }\n    return () => es.close()\n  }, [url])\n\n  return events\n}\n",[478,2195,2196,2221,2241,2245,2268,2299,2303,2316,2330,2348,2368,2392,2416,2456,2502,2507,2511,2528,2540,2544,2552],{"__ignoreMap":574},[578,2197,2198,2200,2202,2205,2207,2210,2212,2214,2216,2219],{"class":580,"line":581},[578,2199,1612],{"class":1202},[578,2201,684],{"class":584},[578,2203,2204],{"class":656}," useEffect",[578,2206,701],{"class":584},[578,2208,2209],{"class":656}," useState",[578,2211,1630],{"class":584},[578,2213,1633],{"class":1202},[578,2215,1074],{"class":584},[578,2217,2218],{"class":637},"react",[578,2220,1080],{"class":584},[578,2222,2223,2225,2227,2229,2231,2233,2235,2237,2239],{"class":580,"line":599},[578,2224,1612],{"class":1202},[578,2226,1646],{"class":1202},[578,2228,684],{"class":584},[578,2230,1651],{"class":656},[578,2232,1630],{"class":584},[578,2234,1633],{"class":1202},[578,2236,1074],{"class":584},[578,2238,1213],{"class":637},[578,2240,1080],{"class":584},[578,2242,2243],{"class":580,"line":609},[578,2244,1043],{"emptyLinePlaceholder":1042},[578,2246,2247,2250,2253,2256,2258,2260,2262,2264,2266],{"class":580,"line":619},[578,2248,2249],{"class":1202},"export",[578,2251,2252],{"class":592}," function",[578,2254,2255],{"class":1098}," useEvlogStream",[578,2257,1102],{"class":584},[578,2259,1799],{"class":1157},[578,2261,691],{"class":584},[578,2263,1769],{"class":680},[578,2265,515],{"class":584},[578,2267,1166],{"class":584},[578,2269,2270,2272,2275,2277,2279,2282,2285,2287,2289,2291,2293,2295,2297],{"class":580,"line":645},[578,2271,1744],{"class":592},[578,2273,2274],{"class":584}," [",[578,2276,1975],{"class":656},[578,2278,701],{"class":584},[578,2280,2281],{"class":656}," setEvents",[578,2283,2284],{"class":584},"]",[578,2286,1151],{"class":584},[578,2288,2209],{"class":1098},[578,2290,602],{"class":584},[578,2292,1682],{"class":680},[578,2294,1685],{"class":588},[578,2296,653],{"class":584},[578,2298,1690],{"class":588},[578,2300,2301],{"class":580,"line":667},[578,2302,1043],{"emptyLinePlaceholder":1042},[578,2304,2305,2308,2310,2312,2314],{"class":580,"line":677},[578,2306,2307],{"class":1098},"  useEffect",[578,2309,1102],{"class":588},[578,2311,1369],{"class":584},[578,2313,1163],{"class":592},[578,2315,1166],{"class":584},[578,2317,2318,2320,2322,2324,2326,2328],{"class":580,"line":732},[578,2319,1873],{"class":1202},[578,2321,1154],{"class":588},[578,2323,1796],{"class":584},[578,2325,1799],{"class":656},[578,2327,1226],{"class":588},[578,2329,1229],{"class":1202},[578,2331,2332,2334,2336,2338,2340,2342,2344,2346],{"class":580,"line":762},[578,2333,1066],{"class":592},[578,2335,1698],{"class":656},[578,2337,1151],{"class":584},[578,2339,1126],{"class":584},[578,2341,1129],{"class":1098},[578,2343,1102],{"class":588},[578,2345,1799],{"class":656},[578,2347,1113],{"class":588},[578,2349,2350,2352,2354,2356,2358,2360,2362,2364,2366],{"class":580,"line":818},[578,2351,1143],{"class":656},[578,2353,461],{"class":584},[578,2355,1148],{"class":1098},[578,2357,1151],{"class":584},[578,2359,1154],{"class":584},[578,2361,1158],{"class":1157},[578,2363,515],{"class":584},[578,2365,1163],{"class":592},[578,2367,1166],{"class":584},[578,2369,2370,2372,2374,2376,2378,2380,2382,2384,2386,2388,2390],{"class":580,"line":843},[578,2371,1172],{"class":592},[578,2373,1175],{"class":656},[578,2375,1151],{"class":584},[578,2377,1180],{"class":656},[578,2379,461],{"class":584},[578,2381,1185],{"class":1098},[578,2383,1102],{"class":588},[578,2385,1158],{"class":656},[578,2387,461],{"class":584},[578,2389,1194],{"class":656},[578,2391,1113],{"class":588},[578,2393,2394,2396,2398,2400,2402,2404,2406,2408,2410,2412,2414],{"class":580,"line":865},[578,2395,1203],{"class":1202},[578,2397,1154],{"class":588},[578,2399,1208],{"class":656},[578,2401,461],{"class":584},[578,2403,1213],{"class":656},[578,2405,1216],{"class":584},[578,2407,1074],{"class":584},[578,2409,1221],{"class":637},[578,2411,1105],{"class":584},[578,2413,1226],{"class":588},[578,2415,1229],{"class":1202},[578,2417,2418,2420,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446,2448,2450,2452,2454],{"class":580,"line":886},[578,2419,1203],{"class":1202},[578,2421,1154],{"class":588},[578,2423,1208],{"class":656},[578,2425,461],{"class":584},[578,2427,510],{"class":656},[578,2429,1908],{"class":584},[578,2431,1074],{"class":584},[578,2433,1249],{"class":637},[578,2435,1105],{"class":584},[578,2437,1917],{"class":584},[578,2439,1175],{"class":656},[578,2441,461],{"class":584},[578,2443,510],{"class":656},[578,2445,1908],{"class":584},[578,2447,1074],{"class":584},[578,2449,1267],{"class":637},[578,2451,1105],{"class":584},[578,2453,1226],{"class":588},[578,2455,1936],{"class":584},[578,2457,2458,2461,2463,2466,2468,2470,2472,2474,2476,2478,2481,2483,2485,2487,2490,2492,2495,2497,2499],{"class":580,"line":896},[578,2459,2460],{"class":1098},"        setEvents",[578,2462,1102],{"class":588},[578,2464,2465],{"class":1157},"prev",[578,2467,1163],{"class":592},[578,2469,2274],{"class":588},[578,2471,1208],{"class":656},[578,2473,461],{"class":584},[578,2475,1194],{"class":656},[578,2477,701],{"class":584},[578,2479,2480],{"class":584}," ...",[578,2482,2465],{"class":656},[578,2484,2284],{"class":588},[578,2486,461],{"class":584},[578,2488,2489],{"class":1098},"slice",[578,2491,1102],{"class":588},[578,2493,2494],{"class":694},"0",[578,2496,701],{"class":584},[578,2498,1988],{"class":694},[578,2500,2501],{"class":588},"))\n",[578,2503,2504],{"class":580,"line":905},[578,2505,2506],{"class":584},"      }\n",[578,2508,2509],{"class":580,"line":915},[578,2510,1539],{"class":584},[578,2512,2513,2516,2518,2520,2522,2524,2526],{"class":580,"line":937},[578,2514,2515],{"class":1202},"    return",[578,2517,1730],{"class":584},[578,2519,1163],{"class":592},[578,2521,1698],{"class":656},[578,2523,461],{"class":584},[578,2525,2043],{"class":1098},[578,2527,1533],{"class":588},[578,2529,2530,2533,2535,2537],{"class":580,"line":1016},[578,2531,2532],{"class":584},"  },",[578,2534,2274],{"class":588},[578,2536,1799],{"class":656},[578,2538,2539],{"class":588},"])\n",[578,2541,2542],{"class":580,"line":1030},[578,2543,1043],{"emptyLinePlaceholder":1042},[578,2545,2546,2549],{"class":580,"line":1039},[578,2547,2548],{"class":1202},"  return",[578,2550,2551],{"class":656}," events\n",[578,2553,2554],{"class":580,"line":1046},[578,2555,840],{"class":584},[450,2557,2558,2559,2561,2562,461],{},"That's the entire integration surface. No SDK, no special types beyond ",[478,2560,1682],{}," exported from ",[478,2563,1213],{},[538,2565,2567],{"id":2566},"_2-quick-cli-inspection-with-curl-jq","2. Quick CLI inspection with curl + jq",[450,2569,2570,2571,691],{},"The URL is in ",[478,2572,491],{},[569,2574,2578],{"className":2575,"code":2576,"language":2577,"meta":574,"style":574},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","URL=$(cat .evlog\u002Fstream.url)\ncurl -N \"$URL\" | jq -c 'select(.type == \"event\") | .data'\n","bash",[478,2579,2580,2596],{"__ignoreMap":574},[578,2581,2582,2585,2588,2591,2594],{"class":580,"line":581},[578,2583,2584],{"class":656},"URL",[578,2586,2587],{"class":584},"=$(",[578,2589,2590],{"class":680},"cat",[578,2592,2593],{"class":637}," .evlog\u002Fstream.url",[578,2595,1113],{"class":584},[578,2597,2598,2601,2604,2607,2610,2612,2614,2617,2620,2622,2625],{"class":580,"line":599},[578,2599,2600],{"class":680},"curl",[578,2602,2603],{"class":637}," -N",[578,2605,2606],{"class":584}," \"",[578,2608,2609],{"class":656},"$URL",[578,2611,634],{"class":584},[578,2613,1705],{"class":584},[578,2615,2616],{"class":680}," jq",[578,2618,2619],{"class":637}," -c",[578,2621,1074],{"class":584},[578,2623,2624],{"class":637},"select(.type == \"event\") | .data",[578,2626,1080],{"class":584},[450,2628,2629],{},"Filter on the client side as needed:",[569,2631,2633],{"className":2575,"code":2632,"language":2577,"meta":574,"style":574},"# Only errors\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.level == \"error\") | .data'\n\n# Only one service\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.service == \"checkout\") | .data'\n\n# Slow requests\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.duration > 500) | .data'\n",[478,2634,2635,2640,2666,2670,2675,2700,2704,2709],{"__ignoreMap":574},[578,2636,2637],{"class":580,"line":581},[578,2638,2639],{"class":1059},"# Only errors\n",[578,2641,2642,2644,2647,2649,2651,2653,2655,2657,2659,2661,2664],{"class":580,"line":599},[578,2643,2600],{"class":680},[578,2645,2646],{"class":637}," -sN",[578,2648,2606],{"class":584},[578,2650,2609],{"class":656},[578,2652,634],{"class":584},[578,2654,1705],{"class":584},[578,2656,2616],{"class":680},[578,2658,2619],{"class":637},[578,2660,1074],{"class":584},[578,2662,2663],{"class":637},"select(.type == \"event\" and .data.level == \"error\") | .data",[578,2665,1080],{"class":584},[578,2667,2668],{"class":580,"line":609},[578,2669,1043],{"emptyLinePlaceholder":1042},[578,2671,2672],{"class":580,"line":619},[578,2673,2674],{"class":1059},"# Only one service\n",[578,2676,2677,2679,2681,2683,2685,2687,2689,2691,2693,2695,2698],{"class":580,"line":645},[578,2678,2600],{"class":680},[578,2680,2646],{"class":637},[578,2682,2606],{"class":584},[578,2684,2609],{"class":656},[578,2686,634],{"class":584},[578,2688,1705],{"class":584},[578,2690,2616],{"class":680},[578,2692,2619],{"class":637},[578,2694,1074],{"class":584},[578,2696,2697],{"class":637},"select(.type == \"event\" and .data.service == \"checkout\") | .data",[578,2699,1080],{"class":584},[578,2701,2702],{"class":580,"line":667},[578,2703,1043],{"emptyLinePlaceholder":1042},[578,2705,2706],{"class":580,"line":677},[578,2707,2708],{"class":1059},"# Slow requests\n",[578,2710,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729,2732],{"class":580,"line":732},[578,2712,2600],{"class":680},[578,2714,2646],{"class":637},[578,2716,2606],{"class":584},[578,2718,2609],{"class":656},[578,2720,634],{"class":584},[578,2722,1705],{"class":584},[578,2724,2616],{"class":680},[578,2726,2619],{"class":637},[578,2728,1074],{"class":584},[578,2730,2731],{"class":637},"select(.type == \"event\" and .data.duration > 500) | .data",[578,2733,1080],{"class":584},[450,2735,2736,2739,2740,2742,2743,2746],{},[478,2737,2738],{},"-N"," keeps ",[478,2741,2600],{}," in streaming mode (no buffering). ",[478,2744,2745],{},"-s"," is silent.",[538,2748,2750],{"id":2749},"_3-replay-history-then-go-live","3. Replay history then go live",[450,2752,2753],{},"History on disk (filesystem drain) + live updates from the stream server = a full picture from any point in time.",[569,2755,2757],{"className":2192,"code":2756,"language":1603,"meta":574,"style":574},"import { readFsLogs } from 'evlog\u002Ffs'\nimport { readFile } from 'node:fs\u002Fpromises'\nimport type { WideEvent } from 'evlog'\n\nasync function bootstrap(handle: (e: WideEvent) => void) {\n  \u002F\u002F 1. Replay the last hour from `.evlog\u002Flogs\u002F`\n  const since = new Date(Date.now() - 60 * 60 * 1000)\n  for await (const event of readFsLogs({ since })) {\n    handle(event)\n  }\n\n  \u002F\u002F 2. Switch to the live SSE stream\n  const url = (await readFile('.evlog\u002Fstream.url', 'utf-8')).trim()\n  const es = new EventSource(url)\n  es.onmessage = (e) => {\n    const env = JSON.parse(e.data)\n    if (env.evlog !== '1') return\n    if (env.type === 'event' || env.type === 'replay') {\n      handle(env.data)\n    }\n  }\n  return () => es.close()\n}\n",[478,2758,2759,2779,2799,2819,2823,2858,2863,2907,2940,2951,2955,2959,2964,3005,3023,3043,3067,3091,3131,3146,3150,3154,3170],{"__ignoreMap":574},[578,2760,2761,2763,2765,2768,2770,2772,2774,2777],{"class":580,"line":581},[578,2762,1612],{"class":1202},[578,2764,684],{"class":584},[578,2766,2767],{"class":656}," readFsLogs",[578,2769,1630],{"class":584},[578,2771,1633],{"class":1202},[578,2773,1074],{"class":584},[578,2775,2776],{"class":637},"evlog\u002Ffs",[578,2778,1080],{"class":584},[578,2780,2781,2783,2785,2788,2790,2792,2794,2797],{"class":580,"line":599},[578,2782,1612],{"class":1202},[578,2784,684],{"class":584},[578,2786,2787],{"class":656}," readFile",[578,2789,1630],{"class":584},[578,2791,1633],{"class":1202},[578,2793,1074],{"class":584},[578,2795,2796],{"class":637},"node:fs\u002Fpromises",[578,2798,1080],{"class":584},[578,2800,2801,2803,2805,2807,2809,2811,2813,2815,2817],{"class":580,"line":609},[578,2802,1612],{"class":1202},[578,2804,1646],{"class":1202},[578,2806,684],{"class":584},[578,2808,1651],{"class":656},[578,2810,1630],{"class":584},[578,2812,1633],{"class":1202},[578,2814,1074],{"class":584},[578,2816,1213],{"class":637},[578,2818,1080],{"class":584},[578,2820,2821],{"class":580,"line":619},[578,2822,1043],{"emptyLinePlaceholder":1042},[578,2824,2825,2827,2829,2832,2834,2837,2839,2841,2843,2845,2847,2849,2851,2854,2856],{"class":580,"line":645},[578,2826,1727],{"class":592},[578,2828,2252],{"class":592},[578,2830,2831],{"class":1098}," bootstrap",[578,2833,1102],{"class":584},[578,2835,2836],{"class":1098},"handle",[578,2838,691],{"class":584},[578,2840,1154],{"class":584},[578,2842,1158],{"class":1157},[578,2844,691],{"class":584},[578,2846,1651],{"class":680},[578,2848,515],{"class":584},[578,2850,1163],{"class":592},[578,2852,2853],{"class":680}," void",[578,2855,515],{"class":584},[578,2857,1166],{"class":584},[578,2859,2860],{"class":580,"line":667},[578,2861,2862],{"class":1059},"  \u002F\u002F 1. Replay the last hour from `.evlog\u002Flogs\u002F`\n",[578,2864,2865,2867,2870,2872,2874,2876,2878,2881,2883,2886,2889,2892,2895,2898,2900,2902,2905],{"class":580,"line":677},[578,2866,1744],{"class":592},[578,2868,2869],{"class":656}," since",[578,2871,1151],{"class":584},[578,2873,1126],{"class":584},[578,2875,1353],{"class":1098},[578,2877,1102],{"class":588},[578,2879,2880],{"class":656},"Date",[578,2882,461],{"class":584},[578,2884,2885],{"class":1098},"now",[578,2887,2888],{"class":588},"() ",[578,2890,2891],{"class":584},"-",[578,2893,2894],{"class":694}," 60",[578,2896,2897],{"class":584}," *",[578,2899,2894],{"class":694},[578,2901,2897],{"class":584},[578,2903,2904],{"class":694}," 1000",[578,2906,1113],{"class":588},[578,2908,2909,2912,2914,2916,2918,2921,2924,2926,2928,2931,2933,2935,2938],{"class":580,"line":732},[578,2910,2911],{"class":1202},"  for",[578,2913,1756],{"class":1202},[578,2915,1154],{"class":588},[578,2917,1670],{"class":592},[578,2919,2920],{"class":656}," event",[578,2922,2923],{"class":584}," of",[578,2925,2767],{"class":1098},[578,2927,1102],{"class":588},[578,2929,2930],{"class":584},"{",[578,2932,2869],{"class":656},[578,2934,1630],{"class":584},[578,2936,2937],{"class":588},")) ",[578,2939,1936],{"class":584},[578,2941,2942,2945,2947,2949],{"class":580,"line":762},[578,2943,2944],{"class":1098},"    handle",[578,2946,1102],{"class":588},[578,2948,1249],{"class":656},[578,2950,1113],{"class":588},[578,2952,2953],{"class":580,"line":818},[578,2954,2014],{"class":584},[578,2956,2957],{"class":580,"line":843},[578,2958,1043],{"emptyLinePlaceholder":1042},[578,2960,2961],{"class":580,"line":865},[578,2962,2963],{"class":1059},"  \u002F\u002F 2. Switch to the live SSE stream\n",[578,2965,2966,2968,2970,2972,2974,2977,2979,2981,2983,2985,2987,2989,2991,2993,2995,2998,3000,3003],{"class":580,"line":886},[578,2967,1744],{"class":592},[578,2969,1749],{"class":656},[578,2971,1151],{"class":584},[578,2973,1154],{"class":588},[578,2975,2976],{"class":1202},"await",[578,2978,2787],{"class":1098},[578,2980,1102],{"class":588},[578,2982,1105],{"class":584},[578,2984,491],{"class":637},[578,2986,1105],{"class":584},[578,2988,701],{"class":584},[578,2990,1074],{"class":584},[578,2992,638],{"class":637},[578,2994,1105],{"class":584},[578,2996,2997],{"class":588},"))",[578,2999,461],{"class":584},[578,3001,3002],{"class":1098},"trim",[578,3004,1533],{"class":588},[578,3006,3007,3009,3011,3013,3015,3017,3019,3021],{"class":580,"line":896},[578,3008,1744],{"class":592},[578,3010,1698],{"class":656},[578,3012,1151],{"class":584},[578,3014,1126],{"class":584},[578,3016,1129],{"class":1098},[578,3018,1102],{"class":588},[578,3020,1799],{"class":656},[578,3022,1113],{"class":588},[578,3024,3025,3027,3029,3031,3033,3035,3037,3039,3041],{"class":580,"line":905},[578,3026,1812],{"class":656},[578,3028,461],{"class":584},[578,3030,1148],{"class":1098},[578,3032,1151],{"class":584},[578,3034,1154],{"class":584},[578,3036,1158],{"class":1157},[578,3038,515],{"class":584},[578,3040,1163],{"class":592},[578,3042,1166],{"class":584},[578,3044,3045,3047,3049,3051,3053,3055,3057,3059,3061,3063,3065],{"class":580,"line":915},[578,3046,1066],{"class":592},[578,3048,1175],{"class":656},[578,3050,1151],{"class":584},[578,3052,1180],{"class":656},[578,3054,461],{"class":584},[578,3056,1185],{"class":1098},[578,3058,1102],{"class":588},[578,3060,1158],{"class":656},[578,3062,461],{"class":584},[578,3064,1194],{"class":656},[578,3066,1113],{"class":588},[578,3068,3069,3071,3073,3075,3077,3079,3081,3083,3085,3087,3089],{"class":580,"line":937},[578,3070,1873],{"class":1202},[578,3072,1154],{"class":588},[578,3074,1208],{"class":656},[578,3076,461],{"class":584},[578,3078,1213],{"class":656},[578,3080,1216],{"class":584},[578,3082,1074],{"class":584},[578,3084,1221],{"class":637},[578,3086,1105],{"class":584},[578,3088,1226],{"class":588},[578,3090,1229],{"class":1202},[578,3092,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129],{"class":580,"line":1016},[578,3094,1873],{"class":1202},[578,3096,1154],{"class":588},[578,3098,1208],{"class":656},[578,3100,461],{"class":584},[578,3102,510],{"class":656},[578,3104,1908],{"class":584},[578,3106,1074],{"class":584},[578,3108,1249],{"class":637},[578,3110,1105],{"class":584},[578,3112,1917],{"class":584},[578,3114,1175],{"class":656},[578,3116,461],{"class":584},[578,3118,510],{"class":656},[578,3120,1908],{"class":584},[578,3122,1074],{"class":584},[578,3124,1267],{"class":637},[578,3126,1105],{"class":584},[578,3128,1226],{"class":588},[578,3130,1936],{"class":584},[578,3132,3133,3136,3138,3140,3142,3144],{"class":580,"line":1030},[578,3134,3135],{"class":1098},"      handle",[578,3137,1102],{"class":588},[578,3139,1208],{"class":656},[578,3141,461],{"class":584},[578,3143,1194],{"class":656},[578,3145,1113],{"class":588},[578,3147,3148],{"class":580,"line":1039},[578,3149,1539],{"class":584},[578,3151,3152],{"class":580,"line":1046},[578,3153,2014],{"class":584},[578,3155,3156,3158,3160,3162,3164,3166,3168],{"class":580,"line":1056},[578,3157,2548],{"class":1202},[578,3159,1730],{"class":584},[578,3161,1163],{"class":592},[578,3163,1698],{"class":656},[578,3165,461],{"class":584},[578,3167,2043],{"class":1098},[578,3169,1533],{"class":588},[578,3171,3172],{"class":580,"line":1063},[578,3173,840],{"class":584},[450,3175,3176,3178,3179,3182],{},[478,3177,480],{}," skips files outside the date range, so the replay step is fast even if you keep weeks of history. For a tail-only mode without on-disk replay, hit the stream server with ",[478,3180,3181],{},"?since=\u003Ciso>"," to reuse the in-process ring buffer instead.",[538,3184,3186],{"id":3185},"_4-node-bun-client-fetch-readablestream","4. Node \u002F Bun client (fetch + ReadableStream)",[450,3188,3189,3190,3192],{},"Same protocol, no ",[478,3191,502],{}," polyfill needed:",[569,3194,3196],{"className":2192,"code":3195,"language":1603,"meta":574,"style":574},"import { readFile } from 'node:fs\u002Fpromises'\n\nconst url = (await readFile('.evlog\u002Fstream.url', 'utf-8')).trim()\nconst res = await fetch(url)\nconst reader = res.body!.getReader()\nconst decoder = new TextDecoder()\nlet buffer = ''\n\nwhile (true) {\n  const { value, done } = await reader.read()\n  if (done) break\n  buffer += decoder.decode(value, { stream: true })\n\n  let idx\n  while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n    const frame = buffer.slice(0, idx)\n    buffer = buffer.slice(idx + 2)\n    const dataLine = frame.split('\\n').find(l => l.startsWith('data:'))\n    if (!dataLine) continue\n    const env = JSON.parse(dataLine.slice(5).trim())\n    if (env.type === 'event') console.log(env.data)\n  }\n}\n",[478,3197,3198,3216,3220,3259,3276,3300,3316,3328,3332,3347,3377,3391,3427,3431,3439,3483,3509,3534,3592,3608,3643,3683,3687],{"__ignoreMap":574},[578,3199,3200,3202,3204,3206,3208,3210,3212,3214],{"class":580,"line":581},[578,3201,1612],{"class":1202},[578,3203,684],{"class":584},[578,3205,2787],{"class":656},[578,3207,1630],{"class":584},[578,3209,1633],{"class":1202},[578,3211,1074],{"class":584},[578,3213,2796],{"class":637},[578,3215,1080],{"class":584},[578,3217,3218],{"class":580,"line":599},[578,3219,1043],{"emptyLinePlaceholder":1042},[578,3221,3222,3224,3227,3229,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257],{"class":580,"line":609},[578,3223,1670],{"class":592},[578,3225,3226],{"class":656}," url ",[578,3228,631],{"class":584},[578,3230,1154],{"class":656},[578,3232,2976],{"class":1202},[578,3234,2787],{"class":1098},[578,3236,1102],{"class":656},[578,3238,1105],{"class":584},[578,3240,491],{"class":637},[578,3242,1105],{"class":584},[578,3244,701],{"class":584},[578,3246,1074],{"class":584},[578,3248,638],{"class":637},[578,3250,1105],{"class":584},[578,3252,2997],{"class":656},[578,3254,461],{"class":584},[578,3256,3002],{"class":1098},[578,3258,1533],{"class":656},[578,3260,3261,3263,3266,3268,3270,3273],{"class":580,"line":619},[578,3262,1670],{"class":592},[578,3264,3265],{"class":656}," res ",[578,3267,631],{"class":584},[578,3269,1756],{"class":1202},[578,3271,3272],{"class":1098}," fetch",[578,3274,3275],{"class":656},"(url)\n",[578,3277,3278,3280,3283,3285,3288,3290,3292,3295,3298],{"class":580,"line":645},[578,3279,1670],{"class":592},[578,3281,3282],{"class":656}," reader ",[578,3284,631],{"class":584},[578,3286,3287],{"class":656}," res",[578,3289,461],{"class":584},[578,3291,910],{"class":656},[578,3293,3294],{"class":584},"!.",[578,3296,3297],{"class":1098},"getReader",[578,3299,1533],{"class":656},[578,3301,3302,3304,3307,3309,3311,3314],{"class":580,"line":667},[578,3303,1670],{"class":592},[578,3305,3306],{"class":656}," decoder ",[578,3308,631],{"class":584},[578,3310,1126],{"class":584},[578,3312,3313],{"class":1098}," TextDecoder",[578,3315,1533],{"class":656},[578,3317,3318,3320,3323,3325],{"class":580,"line":677},[578,3319,1695],{"class":592},[578,3321,3322],{"class":656}," buffer ",[578,3324,631],{"class":584},[578,3326,3327],{"class":584}," ''\n",[578,3329,3330],{"class":580,"line":732},[578,3331,1043],{"emptyLinePlaceholder":1042},[578,3333,3334,3337,3339,3343,3345],{"class":580,"line":762},[578,3335,3336],{"class":1202},"while",[578,3338,1154],{"class":656},[578,3340,3342],{"class":3341},"sfNiH","true",[578,3344,1226],{"class":656},[578,3346,1936],{"class":584},[578,3348,3349,3351,3353,3356,3358,3361,3363,3365,3367,3370,3372,3375],{"class":580,"line":818},[578,3350,1744],{"class":592},[578,3352,684],{"class":584},[578,3354,3355],{"class":656}," value",[578,3357,701],{"class":584},[578,3359,3360],{"class":656}," done",[578,3362,1630],{"class":584},[578,3364,1151],{"class":584},[578,3366,1756],{"class":1202},[578,3368,3369],{"class":656}," reader",[578,3371,461],{"class":584},[578,3373,3374],{"class":1098},"read",[578,3376,1533],{"class":588},[578,3378,3379,3381,3383,3386,3388],{"class":580,"line":843},[578,3380,1791],{"class":1202},[578,3382,1154],{"class":588},[578,3384,3385],{"class":656},"done",[578,3387,1226],{"class":588},[578,3389,3390],{"class":1202},"break\n",[578,3392,3393,3396,3399,3402,3404,3407,3409,3411,3413,3415,3418,3420,3423,3425],{"class":580,"line":865},[578,3394,3395],{"class":656},"  buffer",[578,3397,3398],{"class":584}," +=",[578,3400,3401],{"class":656}," decoder",[578,3403,461],{"class":584},[578,3405,3406],{"class":1098},"decode",[578,3408,1102],{"class":588},[578,3410,1946],{"class":656},[578,3412,701],{"class":584},[578,3414,684],{"class":584},[578,3416,3417],{"class":588}," stream",[578,3419,691],{"class":584},[578,3421,3422],{"class":3341}," true",[578,3424,1630],{"class":584},[578,3426,1113],{"class":588},[578,3428,3429],{"class":580,"line":886},[578,3430,1043],{"emptyLinePlaceholder":1042},[578,3432,3433,3436],{"class":580,"line":896},[578,3434,3435],{"class":592},"  let",[578,3437,3438],{"class":656}," idx\n",[578,3440,3441,3444,3447,3450,3452,3455,3457,3460,3462,3464,3467,3469,3471,3474,3477,3479,3481],{"class":580,"line":905},[578,3442,3443],{"class":1202},"  while",[578,3445,3446],{"class":588}," ((",[578,3448,3449],{"class":656},"idx",[578,3451,1151],{"class":584},[578,3453,3454],{"class":656}," buffer",[578,3456,461],{"class":584},[578,3458,3459],{"class":1098},"indexOf",[578,3461,1102],{"class":588},[578,3463,1105],{"class":584},[578,3465,3466],{"class":656},"\\n\\n",[578,3468,1105],{"class":584},[578,3470,2937],{"class":588},[578,3472,3473],{"class":584},"!==",[578,3475,3476],{"class":584}," -",[578,3478,1221],{"class":694},[578,3480,1226],{"class":588},[578,3482,1936],{"class":584},[578,3484,3485,3487,3490,3492,3494,3496,3498,3500,3502,3504,3507],{"class":580,"line":915},[578,3486,1066],{"class":592},[578,3488,3489],{"class":656}," frame",[578,3491,1151],{"class":584},[578,3493,3454],{"class":656},[578,3495,461],{"class":584},[578,3497,2489],{"class":1098},[578,3499,1102],{"class":588},[578,3501,2494],{"class":694},[578,3503,701],{"class":584},[578,3505,3506],{"class":656}," idx",[578,3508,1113],{"class":588},[578,3510,3511,3514,3516,3518,3520,3522,3524,3526,3529,3532],{"class":580,"line":937},[578,3512,3513],{"class":656},"    buffer",[578,3515,1151],{"class":584},[578,3517,3454],{"class":656},[578,3519,461],{"class":584},[578,3521,2489],{"class":1098},[578,3523,1102],{"class":588},[578,3525,3449],{"class":656},[578,3527,3528],{"class":584}," +",[578,3530,3531],{"class":694}," 2",[578,3533,1113],{"class":588},[578,3535,3536,3538,3541,3543,3545,3547,3550,3552,3554,3557,3559,3561,3563,3566,3568,3571,3573,3576,3578,3581,3583,3585,3588,3590],{"class":580,"line":1016},[578,3537,1066],{"class":592},[578,3539,3540],{"class":656}," dataLine",[578,3542,1151],{"class":584},[578,3544,3489],{"class":656},[578,3546,461],{"class":584},[578,3548,3549],{"class":1098},"split",[578,3551,1102],{"class":588},[578,3553,1105],{"class":584},[578,3555,3556],{"class":656},"\\n",[578,3558,1105],{"class":584},[578,3560,515],{"class":588},[578,3562,461],{"class":584},[578,3564,3565],{"class":1098},"find",[578,3567,1102],{"class":588},[578,3569,3570],{"class":1157},"l",[578,3572,1163],{"class":592},[578,3574,3575],{"class":656}," l",[578,3577,461],{"class":584},[578,3579,3580],{"class":1098},"startsWith",[578,3582,1102],{"class":588},[578,3584,1105],{"class":584},[578,3586,3587],{"class":637},"data:",[578,3589,1105],{"class":584},[578,3591,2501],{"class":588},[578,3593,3594,3596,3598,3600,3603,3605],{"class":580,"line":1030},[578,3595,1873],{"class":1202},[578,3597,1154],{"class":588},[578,3599,1796],{"class":584},[578,3601,3602],{"class":656},"dataLine",[578,3604,1226],{"class":588},[578,3606,3607],{"class":1202},"continue\n",[578,3609,3610,3612,3614,3616,3618,3620,3622,3624,3626,3628,3630,3632,3635,3637,3639,3641],{"class":580,"line":1039},[578,3611,1066],{"class":592},[578,3613,1175],{"class":656},[578,3615,1151],{"class":584},[578,3617,1180],{"class":656},[578,3619,461],{"class":584},[578,3621,1185],{"class":1098},[578,3623,1102],{"class":588},[578,3625,3602],{"class":656},[578,3627,461],{"class":584},[578,3629,2489],{"class":1098},[578,3631,1102],{"class":588},[578,3633,3634],{"class":694},"5",[578,3636,515],{"class":588},[578,3638,461],{"class":584},[578,3640,3002],{"class":1098},[578,3642,2046],{"class":588},[578,3644,3645,3647,3649,3651,3653,3655,3657,3659,3661,3663,3665,3668,3670,3673,3675,3677,3679,3681],{"class":580,"line":1046},[578,3646,1873],{"class":1202},[578,3648,1154],{"class":588},[578,3650,1208],{"class":656},[578,3652,461],{"class":584},[578,3654,510],{"class":656},[578,3656,1908],{"class":584},[578,3658,1074],{"class":584},[578,3660,1249],{"class":637},[578,3662,1105],{"class":584},[578,3664,1226],{"class":588},[578,3666,3667],{"class":656},"console",[578,3669,461],{"class":584},[578,3671,3672],{"class":1098},"log",[578,3674,1102],{"class":588},[578,3676,1208],{"class":656},[578,3678,461],{"class":584},[578,3680,1194],{"class":656},[578,3682,1113],{"class":588},[578,3684,3685],{"class":580,"line":1056},[578,3686,2014],{"class":584},[578,3688,3689],{"class":580,"line":1063},[578,3690,840],{"class":584},[538,3692,3694],{"id":3693},"_5-filter-transform-aggregate-on-the-consumer","5. Filter, transform, aggregate on the consumer",[450,3696,3697],{},"Keep the server dumb — every consumer picks what it cares about:",[569,3699,3701],{"className":2192,"code":3700,"language":1603,"meta":574,"style":574},"\u002F\u002F Just errors\nconst errors = events.filter(e => e.level === 'error')\n\n\u002F\u002F Slow requests\nconst slowReqs = events.filter(e => typeof e.duration === 'number' && e.duration > 500)\n\n\u002F\u002F Group by service\nconst byService = Object.groupBy(events, e => e.service)\n\n\u002F\u002F Rolling error rate (last 100 events)\nconst last100 = events.slice(0, 100)\nconst errorRate = last100.filter(e => e.level === 'error').length \u002F last100.length\n\n\u002F\u002F Ad-hoc cost analytics — works because evlog\u002Fai writes ai.* fields on every AI call\nconst totalCost = events\n  .filter(e => typeof e.ai?.estimatedCost === 'number')\n  .reduce((sum, e) => sum + (e.ai?.estimatedCost as number), 0)\n",[478,3702,3703,3708,3751,3755,3760,3814,3818,3823,3856,3860,3865,3891,3944,3948,3953,3964,4001],{"__ignoreMap":574},[578,3704,3705],{"class":580,"line":581},[578,3706,3707],{"class":1059},"\u002F\u002F Just errors\n",[578,3709,3710,3712,3715,3717,3720,3722,3725,3727,3729,3731,3734,3736,3739,3742,3744,3747,3749],{"class":580,"line":599},[578,3711,1670],{"class":592},[578,3713,3714],{"class":656}," errors ",[578,3716,631],{"class":584},[578,3718,3719],{"class":656}," events",[578,3721,461],{"class":584},[578,3723,3724],{"class":1098},"filter",[578,3726,1102],{"class":656},[578,3728,1158],{"class":1157},[578,3730,1163],{"class":592},[578,3732,3733],{"class":656}," e",[578,3735,461],{"class":584},[578,3737,3738],{"class":656},"level ",[578,3740,3741],{"class":584},"===",[578,3743,1074],{"class":584},[578,3745,3746],{"class":637},"error",[578,3748,1105],{"class":584},[578,3750,1113],{"class":656},[578,3752,3753],{"class":580,"line":609},[578,3754,1043],{"emptyLinePlaceholder":1042},[578,3756,3757],{"class":580,"line":619},[578,3758,3759],{"class":1059},"\u002F\u002F Slow requests\n",[578,3761,3762,3764,3767,3769,3771,3773,3775,3777,3779,3781,3784,3786,3788,3791,3793,3795,3798,3800,3802,3804,3806,3808,3810,3812],{"class":580,"line":645},[578,3763,1670],{"class":592},[578,3765,3766],{"class":656}," slowReqs ",[578,3768,631],{"class":584},[578,3770,3719],{"class":656},[578,3772,461],{"class":584},[578,3774,3724],{"class":1098},[578,3776,1102],{"class":656},[578,3778,1158],{"class":1157},[578,3780,1163],{"class":592},[578,3782,3783],{"class":584}," typeof",[578,3785,3733],{"class":656},[578,3787,461],{"class":584},[578,3789,3790],{"class":656},"duration ",[578,3792,3741],{"class":584},[578,3794,1074],{"class":584},[578,3796,3797],{"class":637},"number",[578,3799,1105],{"class":584},[578,3801,1254],{"class":584},[578,3803,3733],{"class":656},[578,3805,461],{"class":584},[578,3807,3790],{"class":656},[578,3809,653],{"class":584},[578,3811,1988],{"class":694},[578,3813,1113],{"class":656},[578,3815,3816],{"class":580,"line":667},[578,3817,1043],{"emptyLinePlaceholder":1042},[578,3819,3820],{"class":580,"line":677},[578,3821,3822],{"class":1059},"\u002F\u002F Group by service\n",[578,3824,3825,3827,3830,3832,3835,3837,3840,3843,3845,3847,3849,3851,3853],{"class":580,"line":732},[578,3826,1670],{"class":592},[578,3828,3829],{"class":656}," byService ",[578,3831,631],{"class":584},[578,3833,3834],{"class":656}," Object",[578,3836,461],{"class":584},[578,3838,3839],{"class":1098},"groupBy",[578,3841,3842],{"class":656},"(events",[578,3844,701],{"class":584},[578,3846,3733],{"class":1157},[578,3848,1163],{"class":592},[578,3850,3733],{"class":656},[578,3852,461],{"class":584},[578,3854,3855],{"class":656},"service)\n",[578,3857,3858],{"class":580,"line":762},[578,3859,1043],{"emptyLinePlaceholder":1042},[578,3861,3862],{"class":580,"line":818},[578,3863,3864],{"class":1059},"\u002F\u002F Rolling error rate (last 100 events)\n",[578,3866,3867,3869,3872,3874,3876,3878,3880,3882,3884,3886,3889],{"class":580,"line":843},[578,3868,1670],{"class":592},[578,3870,3871],{"class":656}," last100 ",[578,3873,631],{"class":584},[578,3875,3719],{"class":656},[578,3877,461],{"class":584},[578,3879,2489],{"class":1098},[578,3881,1102],{"class":656},[578,3883,2494],{"class":694},[578,3885,701],{"class":584},[578,3887,3888],{"class":694}," 100",[578,3890,1113],{"class":656},[578,3892,3893,3895,3898,3900,3903,3905,3907,3909,3911,3913,3915,3917,3919,3921,3923,3925,3927,3929,3931,3934,3937,3939,3941],{"class":580,"line":865},[578,3894,1670],{"class":592},[578,3896,3897],{"class":656}," errorRate ",[578,3899,631],{"class":584},[578,3901,3902],{"class":656}," last100",[578,3904,461],{"class":584},[578,3906,3724],{"class":1098},[578,3908,1102],{"class":656},[578,3910,1158],{"class":1157},[578,3912,1163],{"class":592},[578,3914,3733],{"class":656},[578,3916,461],{"class":584},[578,3918,3738],{"class":656},[578,3920,3741],{"class":584},[578,3922,1074],{"class":584},[578,3924,3746],{"class":637},[578,3926,1105],{"class":584},[578,3928,515],{"class":656},[578,3930,461],{"class":584},[578,3932,3933],{"class":656},"length ",[578,3935,3936],{"class":584},"\u002F",[578,3938,3902],{"class":656},[578,3940,461],{"class":584},[578,3942,3943],{"class":656},"length\n",[578,3945,3946],{"class":580,"line":886},[578,3947,1043],{"emptyLinePlaceholder":1042},[578,3949,3950],{"class":580,"line":896},[578,3951,3952],{"class":1059},"\u002F\u002F Ad-hoc cost analytics — works because evlog\u002Fai writes ai.* fields on every AI call\n",[578,3954,3955,3957,3960,3962],{"class":580,"line":905},[578,3956,1670],{"class":592},[578,3958,3959],{"class":656}," totalCost ",[578,3961,631],{"class":584},[578,3963,2551],{"class":656},[578,3965,3966,3969,3971,3973,3975,3977,3979,3981,3983,3986,3988,3991,3993,3995,3997,3999],{"class":580,"line":915},[578,3967,3968],{"class":584},"  .",[578,3970,3724],{"class":1098},[578,3972,1102],{"class":656},[578,3974,1158],{"class":1157},[578,3976,1163],{"class":592},[578,3978,3783],{"class":584},[578,3980,3733],{"class":656},[578,3982,461],{"class":584},[578,3984,3985],{"class":656},"ai",[578,3987,2040],{"class":584},[578,3989,3990],{"class":656},"estimatedCost ",[578,3992,3741],{"class":584},[578,3994,1074],{"class":584},[578,3996,3797],{"class":637},[578,3998,1105],{"class":584},[578,4000,1113],{"class":656},[578,4002,4003,4005,4008,4010,4012,4015,4017,4019,4021,4023,4026,4029,4032,4034,4036,4038,4040,4043,4046,4048,4050,4052],{"class":580,"line":937},[578,4004,3968],{"class":584},[578,4006,4007],{"class":1098},"reduce",[578,4009,1102],{"class":656},[578,4011,1102],{"class":584},[578,4013,4014],{"class":1157},"sum",[578,4016,701],{"class":584},[578,4018,3733],{"class":1157},[578,4020,515],{"class":584},[578,4022,1163],{"class":592},[578,4024,4025],{"class":656}," sum ",[578,4027,4028],{"class":584},"+",[578,4030,4031],{"class":656}," (e",[578,4033,461],{"class":584},[578,4035,3985],{"class":656},[578,4037,2040],{"class":584},[578,4039,3990],{"class":656},[578,4041,4042],{"class":1202},"as",[578,4044,4045],{"class":680}," number",[578,4047,515],{"class":656},[578,4049,701],{"class":584},[578,4051,715],{"class":694},[578,4053,1113],{"class":656},[538,4055,4057],{"id":4056},"_6-self-hosted-tail-f-replacement","6. Self-hosted \"tail -f\" replacement",[450,4059,4060],{},"Skip the network entirely if the consumer runs on the same machine:",[569,4062,4064],{"className":2192,"code":4063,"language":1603,"meta":574,"style":574},"import { tailFsLogs } from 'evlog\u002Ffs'\n\nconst ac = new AbortController()\nprocess.on('SIGINT', () => ac.abort())\n\nfor await (const event of tailFsLogs({ signal: ac.signal })) {\n  if (event.level === 'error') notifyOps(event)\n}\n",[478,4065,4066,4085,4089,4105,4140,4144,4185,4216],{"__ignoreMap":574},[578,4067,4068,4070,4072,4075,4077,4079,4081,4083],{"class":580,"line":581},[578,4069,1612],{"class":1202},[578,4071,684],{"class":584},[578,4073,4074],{"class":656}," tailFsLogs",[578,4076,1630],{"class":584},[578,4078,1633],{"class":1202},[578,4080,1074],{"class":584},[578,4082,2776],{"class":637},[578,4084,1080],{"class":584},[578,4086,4087],{"class":580,"line":599},[578,4088,1043],{"emptyLinePlaceholder":1042},[578,4090,4091,4093,4096,4098,4100,4103],{"class":580,"line":609},[578,4092,1670],{"class":592},[578,4094,4095],{"class":656}," ac ",[578,4097,631],{"class":584},[578,4099,1126],{"class":584},[578,4101,4102],{"class":1098}," AbortController",[578,4104,1533],{"class":656},[578,4106,4107,4110,4112,4115,4117,4119,4122,4124,4126,4128,4130,4133,4135,4138],{"class":580,"line":619},[578,4108,4109],{"class":656},"process",[578,4111,461],{"class":584},[578,4113,4114],{"class":1098},"on",[578,4116,1102],{"class":656},[578,4118,1105],{"class":584},[578,4120,4121],{"class":637},"SIGINT",[578,4123,1105],{"class":584},[578,4125,701],{"class":584},[578,4127,1730],{"class":584},[578,4129,1163],{"class":592},[578,4131,4132],{"class":656}," ac",[578,4134,461],{"class":584},[578,4136,4137],{"class":1098},"abort",[578,4139,2046],{"class":656},[578,4141,4142],{"class":580,"line":645},[578,4143,1043],{"emptyLinePlaceholder":1042},[578,4145,4146,4149,4151,4153,4155,4158,4161,4163,4165,4167,4170,4172,4174,4176,4179,4181,4183],{"class":580,"line":667},[578,4147,4148],{"class":1202},"for",[578,4150,1756],{"class":1202},[578,4152,1154],{"class":656},[578,4154,1670],{"class":592},[578,4156,4157],{"class":656}," event ",[578,4159,4160],{"class":584},"of",[578,4162,4074],{"class":1098},[578,4164,1102],{"class":656},[578,4166,2930],{"class":584},[578,4168,4169],{"class":588}," signal",[578,4171,691],{"class":584},[578,4173,4132],{"class":656},[578,4175,461],{"class":584},[578,4177,4178],{"class":656},"signal ",[578,4180,1372],{"class":584},[578,4182,2937],{"class":656},[578,4184,1936],{"class":584},[578,4186,4187,4189,4191,4193,4195,4197,4199,4201,4203,4205,4207,4210,4212,4214],{"class":580,"line":677},[578,4188,1791],{"class":1202},[578,4190,1154],{"class":588},[578,4192,1249],{"class":656},[578,4194,461],{"class":584},[578,4196,972],{"class":656},[578,4198,1908],{"class":584},[578,4200,1074],{"class":584},[578,4202,3746],{"class":637},[578,4204,1105],{"class":584},[578,4206,1226],{"class":588},[578,4208,4209],{"class":1098},"notifyOps",[578,4211,1102],{"class":588},[578,4213,1249],{"class":656},[578,4215,1113],{"class":588},[578,4217,4218],{"class":580,"line":732},[578,4219,840],{"class":584},[450,4221,4222],{},"Works without instrumenting the running app — useful for sidecar \u002F observer processes that watch a directory.",[538,4224,4226],{"id":4225},"what-not-to-do","What not to do",[471,4228,4229,4235,4241],{},[474,4230,4231,4234],{},[2132,4232,4233],{},"Don't run the stream server on Vercel Functions \u002F Cloudflare Workers \u002F Lambda."," Each invocation is a separate isolate; subscribers in one isolate never see events emitted by other isolates. Use a real broker (Redis Streams, NATS, Pub\u002FSub) for cross-instance fan-out.",[474,4236,4237,4240],{},[2132,4238,4239],{},"Don't put auth-sensitive data in wide events"," unless your evlog config redacts them. The server relays exactly what your app emitted — including any unredacted PII.",[474,4242,4243,4246],{},[2132,4244,4245],{},"Don't filter at the server"," (\"only error events please\"). The server is purpose-built to be transparent. Filter on the consumer side; that way one filter doesn't starve another consumer.",[672,4248,4249],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":574,"searchDepth":599,"depth":599,"links":4251},[4252,4257,4258,4259,4260,4261,4262],{"id":540,"depth":599,"text":541,"children":4253},[4254,4255,4256],{"id":566,"depth":609,"text":567},{"id":1576,"depth":609,"text":1577},{"id":2188,"depth":609,"text":2189},{"id":2566,"depth":599,"text":2567},{"id":2749,"depth":599,"text":2750},{"id":3185,"depth":599,"text":3186},{"id":3693,"depth":599,"text":3694},{"id":4056,"depth":599,"text":4057},{"id":4225,"depth":599,"text":4226},"Concrete copy-paste recipes — build your own minimal devtool, pipe to curl + jq, replay history then go live, and aggregate on the consumer side.","md",null,{},{"title":345,"icon":385},{"title":345,"description":4263},"UWlQ6YkbWVRkxFsBAgUV9TJT-nyWLOCTF6AlvHZW0w0",[4271,4273],{"title":378,"path":379,"stem":380,"description":4272,"icon":381,"children":-1},"Replay and tail the local NDJSON drain with readFsLogs and tailFsLogs — works in-process or from any external Node tool, survives restarts.",{"title":387,"path":388,"stem":389,"description":4274,"icon":366,"children":-1},"definePlugin is the canonical extension point for evlog — opt into any subset of setup, onRequestStart, enrich, keep, drain, onRequestFinish, onClientLog, extendLogger from a single cohesive object.",1782925731800]