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