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