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