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