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