watch-tail 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -10
- package/build/client/_app/immutable/assets/0.B5hI3s8c.css +2 -0
- package/build/client/_app/immutable/assets/2.Cn4w1JYv.css +1 -0
- package/build/client/_app/immutable/chunks/0bp2Fczu.js +1 -0
- package/build/client/_app/immutable/chunks/B2En4t_E.js +3 -0
- package/build/client/_app/immutable/chunks/{DS3cLPAu.js → B7X5bVGV.js} +1 -1
- package/build/client/_app/immutable/chunks/BDcWO4cr.js +1 -0
- package/build/client/_app/immutable/chunks/{Dkh4Dwm8.js → BDdUgtQ9.js} +1 -1
- package/build/client/_app/immutable/chunks/{0b2v80OK.js → BP77Fyht.js} +1 -1
- package/build/client/_app/immutable/chunks/{dqF8mxBW.js → B_Mg_9D4.js} +1 -1
- package/build/client/_app/immutable/chunks/BvE-N_5_.js +1 -0
- package/build/client/_app/immutable/chunks/C0Fq51PS.js +1 -0
- package/build/client/_app/immutable/chunks/CBu7zaX6.js +15 -0
- package/build/client/_app/immutable/chunks/CDs2jokv.js +1 -0
- package/build/client/_app/immutable/chunks/{B5RiPG8Z.js → CL6wPCzw.js} +1 -1
- package/build/client/_app/immutable/chunks/CMPe3AwH.js +1 -0
- package/build/client/_app/immutable/chunks/{b77-bq1n.js → CRxuTO84.js} +1 -1
- package/build/client/_app/immutable/chunks/CXlCR4o6.js +10 -0
- package/build/client/_app/immutable/chunks/{DQqLOGLe.js → CZZUqHxO.js} +1 -1
- package/build/client/_app/immutable/chunks/{aI_O2VuQ.js → CaFHnwyo.js} +1 -1
- package/build/client/_app/immutable/chunks/CbtqT1c8.js +1 -0
- package/build/client/_app/immutable/chunks/{DGYKsRyW.js → CfRqDrzx.js} +1 -1
- package/build/client/_app/immutable/chunks/CwzJ9AB4.js +1 -0
- package/build/client/_app/immutable/chunks/{DwOZdLDj.js → Cy2yzzl5.js} +1 -1
- package/build/client/_app/immutable/chunks/D067lFSc.js +2 -0
- package/build/client/_app/immutable/chunks/{C_U_Jvk5.js → D27MZEE2.js} +1 -1
- package/build/client/_app/immutable/chunks/{IlwbfbOu.js → D9KJP6hv.js} +1 -1
- package/build/client/_app/immutable/chunks/DO938hpm.js +1 -0
- package/build/client/_app/immutable/chunks/DrLgrJ3k.js +1 -0
- package/build/client/_app/immutable/chunks/DrupwIIS.js +1 -0
- package/build/client/_app/immutable/chunks/LGzrUxfF.js +1 -0
- package/build/client/_app/immutable/chunks/{D7vimbmk.js → PUpq0Ki5.js} +1 -1
- package/build/client/_app/immutable/chunks/{DvxMaQv_.js → kSuEE8Bt.js} +1 -1
- package/build/client/_app/immutable/chunks/y79YFfGW.js +1 -0
- package/build/client/_app/immutable/chunks/zP_HZRCk.js +1 -0
- package/build/client/_app/immutable/entry/app.BEq8gOel.js +2 -0
- package/build/client/_app/immutable/entry/start.DmBlaUbV.js +1 -0
- package/build/client/_app/immutable/nodes/0.D63E8Q6i.js +1 -0
- package/build/client/_app/immutable/nodes/1.DXfG5P6X.js +1 -0
- package/build/client/_app/immutable/nodes/2.45XrHxUU.js +5 -0
- package/build/client/_app/version.json +1 -1
- package/build/env.js +0 -1
- package/build/handler.js +6 -9
- package/build/index.js +6 -9
- package/build/server/chunks/chunks/{archive.js-D2jtMmDo.js → archive.js-D7cGVWaq.js} +331 -31
- package/build/server/chunks/chunks/env.js-l0sNRNKZ.js +0 -1
- package/build/server/chunks/chunks/env2.js-C5BgBJDY.js +0 -1
- package/build/server/chunks/chunks/{exports.js-ClPPfcHj.js → exports.js-CvFPPbaH.js} +0 -6
- package/build/server/chunks/chunks/identity.js-NmGXxBz3.js +0 -1
- package/build/server/chunks/chunks/{index-server.js-CtH9Hqwf.js → index-server.js-DOq0LmqS.js} +87 -112
- package/build/server/chunks/chunks/internal.js-DZ8ZzzjN.js +0 -1
- package/build/server/chunks/chunks/{legacy-client.js-DAqKExQD.js → internal2.js-B2FekELn.js} +279 -7
- package/build/server/chunks/chunks/{level-filter.js-D9MNrew3.js → level-filter.js-kKdNjmbR.js} +2 -3
- package/build/server/chunks/chunks/{log-buffer.js-A9FA-Qv8.js → log-buffer.js-BjT3sJlh.js} +1 -2
- package/build/server/chunks/chunks/regions.js-COf7DgnH.js +0 -1
- package/build/server/chunks/chunks/shared-server.js-Dn5XheXH.js +0 -1
- package/build/server/chunks/chunks/shared.js-CgjUIvRK.js +0 -1
- package/build/server/chunks/chunks/source.js-DZEVvuho.js +0 -1
- package/build/server/chunks/chunks/{state.js-i-NVNGIq.js → state.js-CdO6iuBd.js} +3 -4
- package/build/server/chunks/chunks/text-size.svelte.js-D09gVgvI.js +309 -0
- package/build/server/chunks/chunks/{time-range.js-BLMT8aU3.js → time-range.js-__87ZPq6.js} +9 -5
- package/build/server/chunks/chunks/uneval.js-DaakSYFQ.js +0 -1
- package/build/server/chunks/chunks/utils.js-BIlHjgGW.js +0 -1
- package/build/server/chunks/entries/endpoints/api/archive/{_server.ts.js-C4hWyXuu.js → _server.ts.js-D-97I3hr.js} +2 -3
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-C5tfrpmC.js +0 -1
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-PWRPScuN.js +0 -1
- package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-D4y43Vwe.js → _server.ts.js-BBBsBX5h.js} +2 -3
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-9_g0ojki.js +0 -1
- package/build/server/chunks/entries/endpoints/api/series/{_server.ts.js-DibT3Hjc.js → _server.ts.js-bsGqvQ1O.js} +4 -5
- package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-BxXw5K0R.js → _server.ts.js-B6obpUbh.js} +211 -49
- package/build/server/chunks/entries/fallbacks/{error.svelte.js-ylsqA41Y.js → error.svelte.js-BupH3lxJ.js} +4 -7
- package/build/server/chunks/entries/pages/_layout.svelte.js-C3CVxu2T.js +621 -0
- package/build/server/chunks/entries/pages/{_page.svelte.js-C9-7d7mD.js → _page.svelte.js-DS9p1LVo.js} +643 -191
- package/build/server/chunks/{handler-Bqo8aDgP.js → handler-DrjCpeeA.js} +4 -5
- package/build/server/chunks/{index.js-fPvMujCL.js → index.js-BLTOesya.js} +3 -4
- package/build/server/chunks/{manifest.js-Bkj-8GaD.js → manifest.js-C1_IS4sj.js} +8 -9
- package/build/server/chunks/nodes/0.js-BHXaR9OX.js +8 -0
- package/build/server/chunks/nodes/1.js-C-coUSdu.js +8 -0
- package/build/server/chunks/nodes/2.js-Dor6Xgc7.js +8 -0
- package/build/shims.js +0 -1
- package/dist/cli/completions.js +24 -0
- package/dist/cli/index.js +144 -3
- package/dist/cli/mcp/agents.js +344 -0
- package/dist/cli/mcp/backend.js +235 -0
- package/dist/cli/mcp/run.js +245 -0
- package/dist/cli/mcp/stdio.js +103 -0
- package/dist/cli/mcp/tools.js +245 -0
- package/dist/cli/options.js +138 -25
- package/dist/cli/server.js +28 -0
- package/dist/cli/ui.js +20 -1
- package/dist/lib/time-range.js +14 -3
- package/package.json +21 -6
- package/build/client/_app/immutable/assets/0.ChTKqSf6.css +0 -2
- package/build/client/_app/immutable/assets/0.ChTKqSf6.css.br +0 -0
- package/build/client/_app/immutable/assets/0.ChTKqSf6.css.gz +0 -0
- package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.br +0 -0
- package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.br +0 -0
- package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.gz +0 -0
- package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.br +0 -1
- package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.gz +0 -0
- package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.br +0 -0
- package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.gz +0 -0
- package/build/client/_app/immutable/assets/EventScatter.0BkgJO-l.css.br +0 -0
- package/build/client/_app/immutable/assets/EventScatter.0BkgJO-l.css.gz +0 -0
- package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.br +0 -0
- package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.gz +0 -0
- package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.br +0 -0
- package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.gz +0 -0
- package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.br +0 -0
- package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.gz +0 -0
- package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.br +0 -0
- package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.gz +0 -0
- package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.br +0 -0
- package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.gz +0 -0
- package/build/client/_app/immutable/chunks/0b2v80OK.js.br +0 -0
- package/build/client/_app/immutable/chunks/0b2v80OK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/5EFAIHuJ.js +0 -1
- package/build/client/_app/immutable/chunks/5EFAIHuJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/5EFAIHuJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B15XBe8D.js +0 -1
- package/build/client/_app/immutable/chunks/B15XBe8D.js.br +0 -0
- package/build/client/_app/immutable/chunks/B15XBe8D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B5RiPG8Z.js.br +0 -2
- package/build/client/_app/immutable/chunks/B5RiPG8Z.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BR2LaRms.js.br +0 -1
- package/build/client/_app/immutable/chunks/BR2LaRms.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B_KVdCQT.js +0 -10
- package/build/client/_app/immutable/chunks/B_KVdCQT.js.br +0 -0
- package/build/client/_app/immutable/chunks/B_KVdCQT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bjy-W4x2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bjy-W4x2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bl052uUt.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bl052uUt.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BuCpRsEL.js +0 -1
- package/build/client/_app/immutable/chunks/BuCpRsEL.js.br +0 -0
- package/build/client/_app/immutable/chunks/BuCpRsEL.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BvZtsVvW.js +0 -1
- package/build/client/_app/immutable/chunks/BvZtsVvW.js.br +0 -0
- package/build/client/_app/immutable/chunks/BvZtsVvW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C3Y15ONf.js +0 -2
- package/build/client/_app/immutable/chunks/C3Y15ONf.js.br +0 -0
- package/build/client/_app/immutable/chunks/C3Y15ONf.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C58PZtCD.js.br +0 -0
- package/build/client/_app/immutable/chunks/C58PZtCD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C9GPQYs7.js +0 -1
- package/build/client/_app/immutable/chunks/C9GPQYs7.js.br +0 -0
- package/build/client/_app/immutable/chunks/C9GPQYs7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CBZpkDc1.js.br +0 -0
- package/build/client/_app/immutable/chunks/CBZpkDc1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CCch3uox.js.br +0 -0
- package/build/client/_app/immutable/chunks/CCch3uox.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C_U_Jvk5.js.br +0 -0
- package/build/client/_app/immutable/chunks/C_U_Jvk5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cd7JqZj9.js +0 -1
- package/build/client/_app/immutable/chunks/Cd7JqZj9.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cd7JqZj9.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D2PbcyDU.js +0 -1
- package/build/client/_app/immutable/chunks/D2PbcyDU.js.br +0 -0
- package/build/client/_app/immutable/chunks/D2PbcyDU.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D7vimbmk.js.br +0 -0
- package/build/client/_app/immutable/chunks/D7vimbmk.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DAqXSYzi.js +0 -1
- package/build/client/_app/immutable/chunks/DAqXSYzi.js.br +0 -0
- package/build/client/_app/immutable/chunks/DAqXSYzi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DGYKsRyW.js.br +0 -0
- package/build/client/_app/immutable/chunks/DGYKsRyW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DPaulGql.js +0 -1
- package/build/client/_app/immutable/chunks/DPaulGql.js.br +0 -1
- package/build/client/_app/immutable/chunks/DPaulGql.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DQqLOGLe.js.br +0 -0
- package/build/client/_app/immutable/chunks/DQqLOGLe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DS3cLPAu.js.br +0 -0
- package/build/client/_app/immutable/chunks/DS3cLPAu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Db0q5_zr.js.br +0 -0
- package/build/client/_app/immutable/chunks/Db0q5_zr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dfvzj6n2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dfvzj6n2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dkh4Dwm8.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dkh4Dwm8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DnqfXHAL.js +0 -15
- package/build/client/_app/immutable/chunks/DnqfXHAL.js.br +0 -0
- package/build/client/_app/immutable/chunks/DnqfXHAL.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DsYron7_.js +0 -1
- package/build/client/_app/immutable/chunks/DsYron7_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DsYron7_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DuM1cPdZ.js +0 -1
- package/build/client/_app/immutable/chunks/DuM1cPdZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/DuM1cPdZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DvxMaQv_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DvxMaQv_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DwOZdLDj.js.br +0 -0
- package/build/client/_app/immutable/chunks/DwOZdLDj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js.br +0 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/IlwbfbOu.js.br +0 -0
- package/build/client/_app/immutable/chunks/IlwbfbOu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/RobXhXPM.js.br +0 -1
- package/build/client/_app/immutable/chunks/RobXhXPM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Y5urAfNy.js.br +0 -0
- package/build/client/_app/immutable/chunks/Y5urAfNy.js.gz +0 -0
- package/build/client/_app/immutable/chunks/aI_O2VuQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/aI_O2VuQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/b77-bq1n.js.br +0 -0
- package/build/client/_app/immutable/chunks/b77-bq1n.js.gz +0 -0
- package/build/client/_app/immutable/chunks/dqF8mxBW.js.br +0 -0
- package/build/client/_app/immutable/chunks/dqF8mxBW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/gkAHSOnS.js +0 -1
- package/build/client/_app/immutable/chunks/gkAHSOnS.js.br +0 -0
- package/build/client/_app/immutable/chunks/gkAHSOnS.js.gz +0 -0
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js +0 -3
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js.br +0 -0
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ti8ecMFX.js +0 -1
- package/build/client/_app/immutable/chunks/ti8ecMFX.js.br +0 -0
- package/build/client/_app/immutable/chunks/ti8ecMFX.js.gz +0 -0
- package/build/client/_app/immutable/chunks/xihTtKlq.js.br +0 -1
- package/build/client/_app/immutable/chunks/xihTtKlq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/yCfI4PCa.js.br +0 -0
- package/build/client/_app/immutable/chunks/yCfI4PCa.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CTR4aUFT.js +0 -2
- package/build/client/_app/immutable/entry/app.CTR4aUFT.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CTR4aUFT.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.CC6Ln8E2.js +0 -1
- package/build/client/_app/immutable/entry/start.CC6Ln8E2.js.br +0 -0
- package/build/client/_app/immutable/entry/start.CC6Ln8E2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CvUxmLsM.js +0 -1
- package/build/client/_app/immutable/nodes/0.CvUxmLsM.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CvUxmLsM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.CbSHqfEx.js +0 -1
- package/build/client/_app/immutable/nodes/1.CbSHqfEx.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.CbSHqfEx.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DcD5v8dU.js +0 -5
- package/build/client/_app/immutable/nodes/2.DcD5v8dU.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DcD5v8dU.js.gz +0 -0
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/client/robots.txt.br +0 -0
- package/build/client/robots.txt.gz +0 -0
- package/build/env.js.map +0 -1
- package/build/handler.js.map +0 -1
- package/build/index.js.map +0 -1
- package/build/server/chunks/chunks/Arc.canvas.js-CN0KDoHG.js +0 -701
- package/build/server/chunks/chunks/Arc.canvas.js-CN0KDoHG.js.map +0 -1
- package/build/server/chunks/chunks/Arc.js-C8EC9NoE.js +0 -31
- package/build/server/chunks/chunks/Arc.js-C8EC9NoE.js.map +0 -1
- package/build/server/chunks/chunks/Bar.js-DtAb3LZZ.js +0 -448
- package/build/server/chunks/chunks/Bar.js-DtAb3LZZ.js.map +0 -1
- package/build/server/chunks/chunks/ChartAnnotations.js-twzDSVzY.js +0 -983
- package/build/server/chunks/chunks/ChartAnnotations.js-twzDSVzY.js.map +0 -1
- package/build/server/chunks/chunks/Circle.html.js-BJywADGK.js +0 -355
- package/build/server/chunks/chunks/Circle.html.js-BJywADGK.js.map +0 -1
- package/build/server/chunks/chunks/ClipPath.canvas.js-9Fc0bTEM.js +0 -170
- package/build/server/chunks/chunks/ClipPath.canvas.js-9Fc0bTEM.js.map +0 -1
- package/build/server/chunks/chunks/DefaultTooltip.js-C2NWK2AD.js +0 -352
- package/build/server/chunks/chunks/DefaultTooltip.js-C2NWK2AD.js.map +0 -1
- package/build/server/chunks/chunks/EventScatter.js-CO2GonW-.js +0 -7370
- package/build/server/chunks/chunks/EventScatter.js-CO2GonW-.js.map +0 -1
- package/build/server/chunks/chunks/Labels.js-DB9qoyZ3.js +0 -497
- package/build/server/chunks/chunks/Labels.js-DB9qoyZ3.js.map +0 -1
- package/build/server/chunks/chunks/Legend.js-B_ArjxQ7.js +0 -343
- package/build/server/chunks/chunks/Legend.js-B_ArjxQ7.js.map +0 -1
- package/build/server/chunks/chunks/Line.html.js-B1REcOFe.js +0 -423
- package/build/server/chunks/chunks/Line.html.js-B1REcOFe.js.map +0 -1
- package/build/server/chunks/chunks/Link.canvas.js-nWimAHfH.js +0 -756
- package/build/server/chunks/chunks/Link.canvas.js-nWimAHfH.js.map +0 -1
- package/build/server/chunks/chunks/Path.canvas.js-5A9wB8zQ.js +0 -1259
- package/build/server/chunks/chunks/Path.canvas.js-5A9wB8zQ.js.map +0 -1
- package/build/server/chunks/chunks/Points.html.js-B2o3k-ZZ.js +0 -228
- package/build/server/chunks/chunks/Points.html.js-B2o3k-ZZ.js.map +0 -1
- package/build/server/chunks/chunks/Points.js-D7ozN9W5.js +0 -14
- package/build/server/chunks/chunks/Points.js-D7ozN9W5.js.map +0 -1
- package/build/server/chunks/chunks/Points2.js-BVbWugLT.js +0 -25
- package/build/server/chunks/chunks/Points2.js-BVbWugLT.js.map +0 -1
- package/build/server/chunks/chunks/Rect.html.js-DnQ6ObhQ.js +0 -547
- package/build/server/chunks/chunks/Rect.html.js-DnQ6ObhQ.js.map +0 -1
- package/build/server/chunks/chunks/Spline.js-YnAxvrKY.js +0 -516
- package/build/server/chunks/chunks/Spline.js-YnAxvrKY.js.map +0 -1
- package/build/server/chunks/chunks/Text.html.js-LbmYJb11.js +0 -847
- package/build/server/chunks/chunks/Text.html.js-LbmYJb11.js.map +0 -1
- package/build/server/chunks/chunks/TooltipItem.js-Ce-blieA.js +0 -314
- package/build/server/chunks/chunks/TooltipItem.js-Ce-blieA.js.map +0 -1
- package/build/server/chunks/chunks/Voronoi.js-CalFJAXH.js +0 -2052
- package/build/server/chunks/chunks/Voronoi.js-CalFJAXH.js.map +0 -1
- package/build/server/chunks/chunks/archive.js-D2jtMmDo.js.map +0 -1
- package/build/server/chunks/chunks/array.js-CBp0H4t3.js +0 -8
- package/build/server/chunks/chunks/array.js-CBp0H4t3.js.map +0 -1
- package/build/server/chunks/chunks/attributes.js-CbKEpZKa.js +0 -25
- package/build/server/chunks/chunks/attributes.js-CbKEpZKa.js.map +0 -1
- package/build/server/chunks/chunks/band.js-CjzHWr4k.js +0 -155
- package/build/server/chunks/chunks/band.js-CjzHWr4k.js.map +0 -1
- package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js +0 -1356
- package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js.map +0 -1
- package/build/server/chunks/chunks/common.js-BvQnfkFo.js +0 -5760
- package/build/server/chunks/chunks/common.js-BvQnfkFo.js.map +0 -1
- package/build/server/chunks/chunks/env.js-l0sNRNKZ.js.map +0 -1
- package/build/server/chunks/chunks/env2.js-C5BgBJDY.js.map +0 -1
- package/build/server/chunks/chunks/events.js-zIVaXIP1.js +0 -95
- package/build/server/chunks/chunks/events.js-zIVaXIP1.js.map +0 -1
- package/build/server/chunks/chunks/exports.js-ClPPfcHj.js.map +0 -1
- package/build/server/chunks/chunks/group.js-D0SfevId.js +0 -30
- package/build/server/chunks/chunks/group.js-D0SfevId.js.map +0 -1
- package/build/server/chunks/chunks/identity.js-NmGXxBz3.js.map +0 -1
- package/build/server/chunks/chunks/index-server.js-CtH9Hqwf.js.map +0 -1
- package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js +0 -2
- package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js.map +0 -1
- package/build/server/chunks/chunks/internal.js-DZ8ZzzjN.js.map +0 -1
- package/build/server/chunks/chunks/internal2.js-CfVVfAb5.js +0 -188
- package/build/server/chunks/chunks/internal2.js-CfVVfAb5.js.map +0 -1
- package/build/server/chunks/chunks/key.svelte.js-Cq0L6YlN.js +0 -695
- package/build/server/chunks/chunks/key.svelte.js-Cq0L6YlN.js.map +0 -1
- package/build/server/chunks/chunks/legacy-client.js-DAqKExQD.js.map +0 -1
- package/build/server/chunks/chunks/level-filter.js-D9MNrew3.js.map +0 -1
- package/build/server/chunks/chunks/lineRadial.js-B7ZNP_Jp.js +0 -126
- package/build/server/chunks/chunks/lineRadial.js-B7ZNP_Jp.js.map +0 -1
- package/build/server/chunks/chunks/linear.js-CHlwr1I4.js +0 -1046
- package/build/server/chunks/chunks/linear.js-CHlwr1I4.js.map +0 -1
- package/build/server/chunks/chunks/log-buffer.js-A9FA-Qv8.js.map +0 -1
- package/build/server/chunks/chunks/math.js-BqujbaBs.js +0 -50
- package/build/server/chunks/chunks/math.js-BqujbaBs.js.map +0 -1
- package/build/server/chunks/chunks/max.js-CuS0BpRI.js +0 -11
- package/build/server/chunks/chunks/max.js-CuS0BpRI.js.map +0 -1
- package/build/server/chunks/chunks/min.js-DZWt5tPl.js +0 -11
- package/build/server/chunks/chunks/min.js-DZWt5tPl.js.map +0 -1
- package/build/server/chunks/chunks/motion.svelte.js-Crk8ri1u.js +0 -677
- package/build/server/chunks/chunks/motion.svelte.js-Crk8ri1u.js.map +0 -1
- package/build/server/chunks/chunks/occlusion.js-ot9_OqWn.js +0 -33
- package/build/server/chunks/chunks/occlusion.js-ot9_OqWn.js.map +0 -1
- package/build/server/chunks/chunks/path.js-BizMrlzb.js +0 -488
- package/build/server/chunks/chunks/path.js-BizMrlzb.js.map +0 -1
- package/build/server/chunks/chunks/path2.js-DLVU8nc9.js +0 -27
- package/build/server/chunks/chunks/path2.js-DLVU8nc9.js.map +0 -1
- package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js +0 -7
- package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js.map +0 -1
- package/build/server/chunks/chunks/rect.svelte.js-_0PgI5fe.js +0 -187
- package/build/server/chunks/chunks/rect.svelte.js-_0PgI5fe.js.map +0 -1
- package/build/server/chunks/chunks/regions.js-COf7DgnH.js.map +0 -1
- package/build/server/chunks/chunks/scales.svelte.js-DeNkKcI-.js +0 -276
- package/build/server/chunks/chunks/scales.svelte.js-DeNkKcI-.js.map +0 -1
- package/build/server/chunks/chunks/series-buckets.js-C-vMEJT2.js +0 -316
- package/build/server/chunks/chunks/series-buckets.js-C-vMEJT2.js.map +0 -1
- package/build/server/chunks/chunks/shared-server.js-Dn5XheXH.js.map +0 -1
- package/build/server/chunks/chunks/shared.js-CgjUIvRK.js.map +0 -1
- package/build/server/chunks/chunks/source.js-DZEVvuho.js.map +0 -1
- package/build/server/chunks/chunks/state.js-i-NVNGIq.js.map +0 -1
- package/build/server/chunks/chunks/time-range.js-BLMT8aU3.js.map +0 -1
- package/build/server/chunks/chunks/types.js-x3GyGPOz.js +0 -11
- package/build/server/chunks/chunks/types.js-x3GyGPOz.js.map +0 -1
- package/build/server/chunks/chunks/uneval.js-DaakSYFQ.js.map +0 -1
- package/build/server/chunks/chunks/utils.js-BIlHjgGW.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-C4hWyXuu.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-C5tfrpmC.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-PWRPScuN.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-D4y43Vwe.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-9_g0ojki.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DibT3Hjc.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-BxXw5K0R.js.map +0 -1
- package/build/server/chunks/entries/fallbacks/error.svelte.js-ylsqA41Y.js.map +0 -1
- package/build/server/chunks/entries/pages/_layout.svelte.js-D7sAdBVX.js +0 -113
- package/build/server/chunks/entries/pages/_layout.svelte.js-D7sAdBVX.js.map +0 -1
- package/build/server/chunks/entries/pages/_page.svelte.js-C9-7d7mD.js.map +0 -1
- package/build/server/chunks/handler-Bqo8aDgP.js.map +0 -1
- package/build/server/chunks/index.js-fPvMujCL.js.map +0 -1
- package/build/server/chunks/manifest.js-Bkj-8GaD.js.map +0 -1
- package/build/server/chunks/nodes/0.js-7J6kXnEo.js +0 -9
- package/build/server/chunks/nodes/0.js-7J6kXnEo.js.map +0 -1
- package/build/server/chunks/nodes/1.js-DZXnUx67.js +0 -9
- package/build/server/chunks/nodes/1.js-DZXnUx67.js.map +0 -1
- package/build/server/chunks/nodes/2.js-85y9-1SS.js +0 -9
- package/build/server/chunks/nodes/2.js-85y9-1SS.js.map +0 -1
- package/build/shims.js.map +0 -1
|
@@ -1,17 +1,65 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ae as escape_html, ac as attr, ad as attr_class, af as attr_style, a6 as ensure_array_like, ag as stringify, P as derived, ah as spread_props, al as bind_props, am as clsx } from '../../chunks/index-server.js-DOq0LmqS.js';
|
|
2
|
+
import { c as LogStore, f as filterByLevel, g as filterEvents, h as effectiveLevel, t as tokenizeJson, b as detectLevel, j as formatLogMessage, k as eventKey, l as levelColorClass, d as detectRequestId, m as mostCriticalLevel, e as eventDurationMs } from '../../chunks/log-buffer.js-BjT3sJlh.js';
|
|
3
3
|
import { R as REGION_CODES } from '../../chunks/regions.js-COf7DgnH.js';
|
|
4
|
-
import { P as PRESET_LABELS, a as presetLabel, H as HISTORIC_PRESETS, t as toDateTimeLocal, d as describeWindow } from '../../chunks/time-range.js-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { P as PRESET_LABELS, a as presetLabel, H as HISTORIC_PRESETS, t as toDateTimeLocal, d as describeWindow } from '../../chunks/time-range.js-__87ZPq6.js';
|
|
5
|
+
import { I as Icon, t as textSize, p as puppy } from '../../chunks/text-size.svelte.js-D09gVgvI.js';
|
|
6
|
+
import { p as page, r as replaceState } from '../../chunks/state.js-CdO6iuBd.js';
|
|
7
7
|
import '../../chunks/uneval.js-DaakSYFQ.js';
|
|
8
8
|
import '../../chunks/shared.js-CgjUIvRK.js';
|
|
9
|
-
import '../../chunks/exports.js-
|
|
10
|
-
import '../../chunks/internal2.js-
|
|
11
|
-
import '../../chunks/legacy-client.js-DAqKExQD.js';
|
|
12
|
-
import '../../chunks/events.js-zIVaXIP1.js';
|
|
9
|
+
import '../../chunks/exports.js-CvFPPbaH.js';
|
|
10
|
+
import '../../chunks/internal2.js-B2FekELn.js';
|
|
13
11
|
import '../../chunks/utils.js-BIlHjgGW.js';
|
|
14
12
|
|
|
13
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.47.0_svelte@5.57.0/node_modules/@lucide/svelte/dist/icons/arrow-right.svelte
|
|
14
|
+
function Arrow_right($$renderer, $$props) {
|
|
15
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
16
|
+
Icon($$renderer, spread_props([props, { icon: {
|
|
17
|
+
"name": "arrow-right",
|
|
18
|
+
"size": 24,
|
|
19
|
+
"node": [["path", { "d": "M5 12h14" }], ["path", { "d": "m12 5 7 7-7 7" }]]
|
|
20
|
+
} }]));
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.47.0_svelte@5.57.0/node_modules/@lucide/svelte/dist/icons/chevron-down.svelte
|
|
24
|
+
function Chevron_down($$renderer, $$props) {
|
|
25
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
26
|
+
Icon($$renderer, spread_props([props, { icon: {
|
|
27
|
+
"name": "chevron-down",
|
|
28
|
+
"size": 24,
|
|
29
|
+
"node": [["path", { "d": "m6 9 6 6 6-6" }]]
|
|
30
|
+
} }]));
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.47.0_svelte@5.57.0/node_modules/@lucide/svelte/dist/icons/chevron-left.svelte
|
|
34
|
+
function Chevron_left($$renderer, $$props) {
|
|
35
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
36
|
+
Icon($$renderer, spread_props([props, { icon: {
|
|
37
|
+
"name": "chevron-left",
|
|
38
|
+
"size": 24,
|
|
39
|
+
"node": [["path", { "d": "m15 18-6-6 6-6" }]]
|
|
40
|
+
} }]));
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.47.0_svelte@5.57.0/node_modules/@lucide/svelte/dist/icons/chevron-right.svelte
|
|
44
|
+
function Chevron_right($$renderer, $$props) {
|
|
45
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
46
|
+
Icon($$renderer, spread_props([props, { icon: {
|
|
47
|
+
"name": "chevron-right",
|
|
48
|
+
"size": 24,
|
|
49
|
+
"node": [["path", { "d": "m9 18 6-6-6-6" }]]
|
|
50
|
+
} }]));
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.47.0_svelte@5.57.0/node_modules/@lucide/svelte/dist/icons/chevron-up.svelte
|
|
54
|
+
function Chevron_up($$renderer, $$props) {
|
|
55
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
56
|
+
Icon($$renderer, spread_props([props, { icon: {
|
|
57
|
+
"name": "chevron-up",
|
|
58
|
+
"size": 24,
|
|
59
|
+
"node": [["path", { "d": "m18 15-6-6-6 6" }]]
|
|
60
|
+
} }]));
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
15
63
|
//#region src/lib/format.ts
|
|
16
64
|
/**
|
|
17
65
|
* Formatting helpers for the watch-tail UI. Every function here is pure so it can be unit
|
|
@@ -149,6 +197,318 @@ function EndpointBadge($$renderer, $$props) {
|
|
|
149
197
|
});
|
|
150
198
|
}
|
|
151
199
|
//#endregion
|
|
200
|
+
//#region src/lib/request-groups.ts
|
|
201
|
+
/**
|
|
202
|
+
* Request grouping: the one place that decides what a "request" is.
|
|
203
|
+
*
|
|
204
|
+
* CloudWatch Logs has no concept of a request. A request is a set of lines that
|
|
205
|
+
* share a log group and detected request id - a Lambda `REPORT RequestId: ...` line, an API
|
|
206
|
+
* Gateway access log, a framework's structured `requestId` - and the same id
|
|
207
|
+
* must produce the same group in the log view and in the chart. Both call the
|
|
208
|
+
* helpers here, so a line that reads as one request in one view reads as one
|
|
209
|
+
* request in the other.
|
|
210
|
+
*
|
|
211
|
+
* Design decisions:
|
|
212
|
+
*
|
|
213
|
+
* - A request is placed where it *starts* (its first line), because a request
|
|
214
|
+
* that logs for two minutes is one event that happened, not two.
|
|
215
|
+
* - A request's level is its most critical line. An error is what a reader
|
|
216
|
+
* needs to see, even when twenty lines around it are info.
|
|
217
|
+
* - Lines without a request id are not grouped: they keep their own row and
|
|
218
|
+
* their own chart mark, which is honest about what the log contains.
|
|
219
|
+
*/
|
|
220
|
+
/**
|
|
221
|
+
* Request id of an event.
|
|
222
|
+
*
|
|
223
|
+
* A value the server already detected wins, because it is the same value the
|
|
224
|
+
* archive stored; only an event that carries no verdict is detected here.
|
|
225
|
+
*/
|
|
226
|
+
function requestIdOf(event) {
|
|
227
|
+
if (event.requestId !== void 0) {
|
|
228
|
+
const declared = event.requestId;
|
|
229
|
+
return declared === null || declared === "" ? null : declared;
|
|
230
|
+
}
|
|
231
|
+
return detectRequestId(event.message ?? "");
|
|
232
|
+
}
|
|
233
|
+
/** Level of a request: its worst line, or `unknown` when no line has a level. */
|
|
234
|
+
function requestLevel(events) {
|
|
235
|
+
return mostCriticalLevel(events.map((event) => effectiveLevel(event))) ?? "unknown";
|
|
236
|
+
}
|
|
237
|
+
/** Groups events by log group and request id, keeping every timestamp and byte of the originals. */
|
|
238
|
+
function collectRequests(events) {
|
|
239
|
+
const byId = /* @__PURE__ */ new Map();
|
|
240
|
+
events.forEach((event, index) => {
|
|
241
|
+
const id = requestIdOf(event);
|
|
242
|
+
if (id === null) return;
|
|
243
|
+
const key = JSON.stringify([event.group ?? "", id]);
|
|
244
|
+
const existing = byId.get(key);
|
|
245
|
+
if (existing === void 0) {
|
|
246
|
+
byId.set(key, {
|
|
247
|
+
id,
|
|
248
|
+
level: "unknown",
|
|
249
|
+
first: event.timestamp,
|
|
250
|
+
last: event.timestamp,
|
|
251
|
+
events: [{
|
|
252
|
+
event,
|
|
253
|
+
index
|
|
254
|
+
}]
|
|
255
|
+
});
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
existing.events.push({
|
|
259
|
+
event,
|
|
260
|
+
index
|
|
261
|
+
});
|
|
262
|
+
if (Number.isFinite(event.timestamp)) {
|
|
263
|
+
if (event.timestamp < existing.first) existing.first = event.timestamp;
|
|
264
|
+
if (event.timestamp > existing.last) existing.last = event.timestamp;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
const groups = [...byId.values()];
|
|
268
|
+
for (const group of groups) group.level = requestLevel(group.events.map((entry) => entry.event));
|
|
269
|
+
return groups;
|
|
270
|
+
}
|
|
271
|
+
/** True when an event belongs to a request. */
|
|
272
|
+
function hasRequestId(event) {
|
|
273
|
+
return requestIdOf(event) !== null;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Builds the log view's rows for a buffer.
|
|
277
|
+
*
|
|
278
|
+
* A request is placed where its first line appeared, so the view stays in time
|
|
279
|
+
* order and a request never jumps down the list when its last line lands. The
|
|
280
|
+
* lines inside a request keep their own order.
|
|
281
|
+
*/
|
|
282
|
+
function requestRows(events) {
|
|
283
|
+
const at = /* @__PURE__ */ new Map();
|
|
284
|
+
for (const group of collectRequests(events)) {
|
|
285
|
+
const first = group.events[0];
|
|
286
|
+
if (first !== void 0) at.set(first.index, group);
|
|
287
|
+
}
|
|
288
|
+
const rows = [];
|
|
289
|
+
events.forEach((event, index) => {
|
|
290
|
+
const group = at.get(index);
|
|
291
|
+
if (group !== void 0) {
|
|
292
|
+
rows.push({
|
|
293
|
+
kind: "request",
|
|
294
|
+
key: `req:${JSON.stringify([group.events[0]?.event.group ?? "", group.id])}`,
|
|
295
|
+
request: group
|
|
296
|
+
});
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (hasRequestId(event)) return;
|
|
300
|
+
rows.push({
|
|
301
|
+
kind: "line",
|
|
302
|
+
key: `line:${index}`,
|
|
303
|
+
event,
|
|
304
|
+
index
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
return rows;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Counts requests into buckets, one mark per request, per group and level.
|
|
311
|
+
*
|
|
312
|
+
* A request is counted in the bucket its first line falls in, and only when
|
|
313
|
+
* that first line is inside the window: a request that started before the window
|
|
314
|
+
* is not re-counted in every bucket it touches. Lines that belong to no request
|
|
315
|
+
* are still counted, each as one mark, so nothing disappears from the chart when
|
|
316
|
+
* grouping is on. The level filter is applied to the request's most critical
|
|
317
|
+
* level, matching what the archive answers, so the chips mean the same thing in
|
|
318
|
+
* both sources.
|
|
319
|
+
*/
|
|
320
|
+
function bucketRequests(events, options) {
|
|
321
|
+
const bucketMs = options.bucketMs > 0 ? Math.round(options.bucketMs) : 6e4;
|
|
322
|
+
const levelFilter = options.level ?? null;
|
|
323
|
+
const fallbackGroup = options.fallbackGroup ?? "";
|
|
324
|
+
const marks = [];
|
|
325
|
+
for (const group of collectRequests(events)) marks.push({
|
|
326
|
+
t: group.first,
|
|
327
|
+
group: group.events[0]?.event.group ?? fallbackGroup,
|
|
328
|
+
level: group.level
|
|
329
|
+
});
|
|
330
|
+
for (const event of events) {
|
|
331
|
+
if (requestIdOf(event) !== null) continue;
|
|
332
|
+
marks.push({
|
|
333
|
+
t: event.timestamp,
|
|
334
|
+
group: event.group ?? fallbackGroup,
|
|
335
|
+
level: effectiveLevel(event) ?? "unknown"
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
const counts = /* @__PURE__ */ new Map();
|
|
339
|
+
for (const mark of marks) {
|
|
340
|
+
const timestamp = mark.t;
|
|
341
|
+
if (!Number.isFinite(timestamp)) continue;
|
|
342
|
+
if (timestamp < options.from || timestamp >= options.to) continue;
|
|
343
|
+
if (levelFilter !== null && mark.level !== levelFilter) continue;
|
|
344
|
+
const t = Math.floor(timestamp / bucketMs) * bucketMs;
|
|
345
|
+
const name = mark.group;
|
|
346
|
+
const key = `${t}\u0000${name}\u0000${mark.level}`;
|
|
347
|
+
const existing = counts.get(key);
|
|
348
|
+
if (existing === void 0) counts.set(key, {
|
|
349
|
+
t,
|
|
350
|
+
group: name,
|
|
351
|
+
level: mark.level,
|
|
352
|
+
events: 1
|
|
353
|
+
});
|
|
354
|
+
else existing.events += 1;
|
|
355
|
+
}
|
|
356
|
+
return [...counts.values()].toSorted((a, b) => a.t === b.t ? a.level.localeCompare(b.level) : a.t - b.t);
|
|
357
|
+
}
|
|
358
|
+
//#endregion
|
|
359
|
+
//#region src/lib/series-buckets.ts
|
|
360
|
+
/**
|
|
361
|
+
* Client-side bucketing for the chart.
|
|
362
|
+
*
|
|
363
|
+
* The archive answers `/api/series` with counts it can compute in DuckDB, but a
|
|
364
|
+
* CloudWatch view has no aggregate API, so the events already streamed into the
|
|
365
|
+
* view are bucketed here instead. Both paths produce the same
|
|
366
|
+
* {@link SeriesPoint} shape, so the chart has one data contract.
|
|
367
|
+
*/
|
|
368
|
+
/** Severity order used wherever levels are listed. */
|
|
369
|
+
var LEVEL_ORDER = [
|
|
370
|
+
"error",
|
|
371
|
+
"warn",
|
|
372
|
+
"info",
|
|
373
|
+
"debug",
|
|
374
|
+
"unknown"
|
|
375
|
+
];
|
|
376
|
+
/** Label shown for a level. */
|
|
377
|
+
var LEVEL_LABELS = {
|
|
378
|
+
error: "Error",
|
|
379
|
+
warn: "Warn",
|
|
380
|
+
info: "Info",
|
|
381
|
+
debug: "Debug",
|
|
382
|
+
unknown: "No level"
|
|
383
|
+
};
|
|
384
|
+
/**
|
|
385
|
+
* Chart palette per level, matching the colours the log viewer uses for lines.
|
|
386
|
+
*
|
|
387
|
+
* SVG needs real colour values rather than Tailwind classes, so the palette is
|
|
388
|
+
* kept next to the level helpers instead of in the component.
|
|
389
|
+
*/
|
|
390
|
+
var SERIES_LEVEL_COLOR = {
|
|
391
|
+
error: "var(--chart-error, #f87171)",
|
|
392
|
+
warn: "var(--chart-warn, #fcd34d)",
|
|
393
|
+
info: "var(--chart-info, #a3a3a3)",
|
|
394
|
+
debug: "var(--chart-debug, #737373)",
|
|
395
|
+
unknown: "var(--chart-unknown, #525252)"
|
|
396
|
+
};
|
|
397
|
+
/** Bucket width used when a caller does not ask for one. */
|
|
398
|
+
var DEFAULT_BUCKET_MS = 6e4;
|
|
399
|
+
/** Level of an event as the chart counts it. */
|
|
400
|
+
function seriesLevelOf(event) {
|
|
401
|
+
return effectiveLevel(event) ?? "unknown";
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Counts events into buckets of one width, per group and level.
|
|
405
|
+
*
|
|
406
|
+
* Events outside the window are ignored, as are events without a usable
|
|
407
|
+
* timestamp: the chart describes exactly the window it is drawn for. With
|
|
408
|
+
* `byRequest`, a request is one mark instead of its lines being many, which is
|
|
409
|
+
* the same thing the archive counts in SQL.
|
|
410
|
+
*/
|
|
411
|
+
function bucketEvents(events, options) {
|
|
412
|
+
const requested = options.bucketMs ?? 6e4;
|
|
413
|
+
const bucketMs = Number.isFinite(requested) && requested > 0 ? Math.round(requested) : DEFAULT_BUCKET_MS;
|
|
414
|
+
const levelFilter = options.level ?? null;
|
|
415
|
+
const fallbackGroup = options.fallbackGroup ?? "";
|
|
416
|
+
if (options.byRequest === true) return bucketRequests(events, {
|
|
417
|
+
from: options.from,
|
|
418
|
+
to: options.to,
|
|
419
|
+
bucketMs,
|
|
420
|
+
level: levelFilter,
|
|
421
|
+
fallbackGroup
|
|
422
|
+
});
|
|
423
|
+
const counts = /* @__PURE__ */ new Map();
|
|
424
|
+
for (const event of events) {
|
|
425
|
+
const timestamp = event.timestamp;
|
|
426
|
+
if (!Number.isFinite(timestamp)) continue;
|
|
427
|
+
if (timestamp < options.from || timestamp >= options.to) continue;
|
|
428
|
+
const level = seriesLevelOf(event);
|
|
429
|
+
if (levelFilter !== null && level !== levelFilter) continue;
|
|
430
|
+
const t = Math.floor(timestamp / bucketMs) * bucketMs;
|
|
431
|
+
const group = event.group ?? fallbackGroup;
|
|
432
|
+
const key = `${t}\u0000${group}\u0000${level}`;
|
|
433
|
+
const existing = counts.get(key);
|
|
434
|
+
if (existing === void 0) counts.set(key, {
|
|
435
|
+
t,
|
|
436
|
+
group,
|
|
437
|
+
level,
|
|
438
|
+
events: 1
|
|
439
|
+
});
|
|
440
|
+
else existing.events += 1;
|
|
441
|
+
}
|
|
442
|
+
return [...counts.values()].toSorted((a, b) => a.t === b.t ? a.level.localeCompare(b.level) : a.t - b.t);
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Splits points into one series per level, in severity order.
|
|
446
|
+
*
|
|
447
|
+
* A level with no events is left out, so the legend only names what is drawn.
|
|
448
|
+
*/
|
|
449
|
+
function groupByLevel(points) {
|
|
450
|
+
const byLevel = /* @__PURE__ */ new Map();
|
|
451
|
+
for (const point of points) {
|
|
452
|
+
const bucket = byLevel.get(point.level);
|
|
453
|
+
if (bucket === void 0) byLevel.set(point.level, [point]);
|
|
454
|
+
else bucket.push(point);
|
|
455
|
+
}
|
|
456
|
+
return LEVEL_ORDER.filter((level) => byLevel.has(level)).map((level) => {
|
|
457
|
+
const levelPoints = (byLevel.get(level) ?? []).toSorted((a, b) => a.t - b.t);
|
|
458
|
+
return {
|
|
459
|
+
level,
|
|
460
|
+
label: LEVEL_LABELS[level],
|
|
461
|
+
points: levelPoints,
|
|
462
|
+
events: levelPoints.reduce((sum, point) => sum + point.events, 0)
|
|
463
|
+
};
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
/** Fraction of the window a brush must stay under to count as a zoom. */
|
|
467
|
+
var MAX_BRUSH_FRACTION = .98;
|
|
468
|
+
/**
|
|
469
|
+
* True when a brushed range is a deliberate zoom rather than a stray click.
|
|
470
|
+
*
|
|
471
|
+
* A pointer down and up a couple of pixels apart still produces a range (the
|
|
472
|
+
* chart has a minimum selection width), and a double click on empty space
|
|
473
|
+
* selects the whole domain. Acting on either would re-scope the log view to a
|
|
474
|
+
* window with nothing in it, so a brush is only applied when it spans at least
|
|
475
|
+
* two buckets and a floor of {@link MIN_BRUSH_MS}, and is narrower than almost
|
|
476
|
+
* the whole window.
|
|
477
|
+
*/
|
|
478
|
+
function isMeaningfulBrush(range, window, bucketMs) {
|
|
479
|
+
const span = range.to - range.from;
|
|
480
|
+
if (!Number.isFinite(span) || span <= 0) return false;
|
|
481
|
+
const windowSpan = window.to - window.from;
|
|
482
|
+
if (!Number.isFinite(windowSpan) || windowSpan <= 0) return false;
|
|
483
|
+
if (span < Math.max(3e4, bucketMs * 2)) return false;
|
|
484
|
+
return span <= windowSpan * MAX_BRUSH_FRACTION;
|
|
485
|
+
}
|
|
486
|
+
/** One point per identified request, using its observed first/last events in the window. */
|
|
487
|
+
function requestDurations(events, options) {
|
|
488
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
489
|
+
for (const event of events) {
|
|
490
|
+
if (!Number.isFinite(event.timestamp) || event.timestamp < options.from || event.timestamp > options.to) continue;
|
|
491
|
+
const group = event.group ?? options.fallbackGroup ?? "";
|
|
492
|
+
const rows = byGroup.get(group) ?? [];
|
|
493
|
+
rows.push(event);
|
|
494
|
+
byGroup.set(group, rows);
|
|
495
|
+
}
|
|
496
|
+
const points = [];
|
|
497
|
+
for (const [group, rows] of byGroup) for (const request of collectRequests(rows)) {
|
|
498
|
+
if (options.level && request.level !== options.level) continue;
|
|
499
|
+
const last = request.events.reduce((latest, entry) => entry.event.timestamp >= latest.timestamp ? entry.event : latest, request.events[0].event);
|
|
500
|
+
points.push({
|
|
501
|
+
t: request.first,
|
|
502
|
+
group,
|
|
503
|
+
level: request.level,
|
|
504
|
+
events: 1,
|
|
505
|
+
requestId: request.id,
|
|
506
|
+
durationMs: request.last - request.first + eventDurationMs(last.message)
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
return points.toSorted((a, b) => a.t - b.t || a.group.localeCompare(b.group) || (a.requestId ?? "").localeCompare(b.requestId ?? ""));
|
|
510
|
+
}
|
|
511
|
+
//#endregion
|
|
152
512
|
//#region src/lib/resize.ts
|
|
153
513
|
/**
|
|
154
514
|
* Pure helpers for the drag-resizable columns in the UI.
|
|
@@ -159,12 +519,14 @@ function EndpointBadge($$renderer, $$props) {
|
|
|
159
519
|
/** `localStorage` keys, prefixed so they are easy to spot in a browser. */
|
|
160
520
|
var STORAGE_KEYS = {
|
|
161
521
|
sidebarWidth: "watch-tail:sidebar-width",
|
|
522
|
+
sidebarOpen: "watch-tail:sidebar-open",
|
|
162
523
|
prefixWidth: "watch-tail:prefix-width",
|
|
163
524
|
timestampWidth: "watch-tail:timestamp-width",
|
|
164
525
|
groupWidth: "watch-tail:group-width",
|
|
165
526
|
wrap: "watch-tail:wrap",
|
|
166
527
|
jsonView: "watch-tail:json-view",
|
|
167
528
|
chartOpen: "watch-tail:chart-open",
|
|
529
|
+
logOpen: "watch-tail:log-open",
|
|
168
530
|
groupRequests: "watch-tail:group-requests"
|
|
169
531
|
};
|
|
170
532
|
/** Default width of the group-list pane, in rem (matches the original layout). */
|
|
@@ -203,8 +565,11 @@ function EventScatterPanel($$renderer, $$props) {
|
|
|
203
565
|
/**
|
|
204
566
|
* The real loader: a dynamic import, which is what keeps layerchart out of the
|
|
205
567
|
* initial bundle. It only runs in the browser, and only once the panel is open.
|
|
568
|
+
* The server build gets a stub instead: without it, layerchart and d3 are
|
|
569
|
+
* compiled into the server chunks (and shipped in the npm package) for code
|
|
570
|
+
* that never runs there.
|
|
206
571
|
*/
|
|
207
|
-
const loadChartModule = () =>
|
|
572
|
+
const loadChartModule = () => Promise.reject(/* @__PURE__ */ new Error("the chart is client-only"));
|
|
208
573
|
/** Bucketed counts for the window. */
|
|
209
574
|
/** Inclusive start of the window, epoch ms. */
|
|
210
575
|
/** Inclusive end of the window, epoch ms. */
|
|
@@ -214,9 +579,10 @@ function EventScatterPanel($$renderer, $$props) {
|
|
|
214
579
|
/** True while the counts are being fetched. */
|
|
215
580
|
/** Called with the brushed range when the drag ends, or `null` on clear. */
|
|
216
581
|
/** Chart height in px. */
|
|
582
|
+
/** True to grow into the space its parent gives instead of a fixed height. */
|
|
217
583
|
/** Start open, which is also what the first visit uses. */
|
|
218
584
|
/** Chart module loader; defaults to the dynamic import. */
|
|
219
|
-
let { metric = "duration", onMetricChange, onSelect, points = [], from = 0, to = 0, bucketMs = 0, groups = [], loading = false, byRequest = true, onBrush, height = 200, open = true, loadChart = loadChartModule } = $$props;
|
|
585
|
+
let { metric = "duration", onMetricChange, onSelect, points = [], from = 0, to = 0, bucketMs = 0, groups = [], loading = false, byRequest = true, onBrush, height = 200, fill = false, open = true, loadChart = loadChartModule } = $$props;
|
|
220
586
|
let expanded = derived(() => open);
|
|
221
587
|
/** Totals and labels per level, in severity order. */
|
|
222
588
|
let levelGroups = derived(() => groupByLevel(points));
|
|
@@ -224,54 +590,51 @@ function EventScatterPanel($$renderer, $$props) {
|
|
|
224
590
|
let totalEvents = derived(() => levelGroups().reduce((sum, entry) => sum + entry.events, 0));
|
|
225
591
|
/** Buckets drawn. */
|
|
226
592
|
let bucketCount = derived(() => new Set(points.map((point) => point.t)).size);
|
|
227
|
-
/** True when there is something to draw. */
|
|
228
|
-
let hasPoints = derived(() => points.length > 0);
|
|
229
593
|
/** What one mark stands for, which is what the totals count. */
|
|
230
594
|
let unit = derived(() => metric === "duration" || byRequest ? "requests" : "events");
|
|
231
595
|
/** Clears the brush, for the host's Reset zoom control. */
|
|
232
596
|
function reset() {
|
|
233
597
|
onBrush?.(null);
|
|
234
598
|
}
|
|
235
|
-
$$renderer.push(`<section
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
599
|
+
$$renderer.push(`<section${attr_class(`flex min-w-0 flex-col border-b border-neutral-800 bg-neutral-950/60 ${fill && expanded() ? "min-h-0 flex-1" : "shrink-0"}`)} data-testid="event-scatter"${attr("aria-label", metric === "duration" ? "Request duration over time" : "Events over time")}><div class="flex min-h-9 flex-none flex-wrap items-center gap-x-3 gap-y-1 border-b border-neutral-800 bg-neutral-900/40 px-3 py-1.5 text-[0.6875rem]"><button type="button"${attr("aria-expanded", expanded())}${attr("title", expanded() ? "Hide the chart" : "Show the chart")} data-testid="scatter-toggle" class="flex items-center gap-1 text-sm font-semibold text-neutral-200 transition-colors hover:text-sky-300">`);
|
|
600
|
+
if (expanded()) {
|
|
601
|
+
$$renderer.push("<!--[0-->");
|
|
602
|
+
Chevron_down($$renderer, { size: "1em" });
|
|
603
|
+
} else {
|
|
604
|
+
$$renderer.push("<!--[-1-->");
|
|
605
|
+
Chevron_right($$renderer, { size: "1em" });
|
|
240
606
|
}
|
|
241
|
-
$$renderer.push(`<!--]
|
|
242
|
-
${escape_html(unit())}`);
|
|
243
|
-
if (metric === "count") $$renderer.push(`<!--[0--> in ${escape_html(formatCount(bucketCount()))} buckets`);
|
|
244
|
-
else $$renderer.push("<!--[-1-->");
|
|
245
|
-
$$renderer.push(`<!--]--></span> `);
|
|
607
|
+
$$renderer.push(`<!--]--> Chart - ${escape_html(metric === "duration" ? "Request duration" : "Events over time")}</button> `);
|
|
246
608
|
if (groups.length > 1) $$renderer.push(`<!--[0--><span class="text-neutral-500" data-testid="scatter-groups">across ${escape_html(groups.length)} groups</span>`);
|
|
247
609
|
else $$renderer.push("<!--[-1-->");
|
|
248
610
|
$$renderer.push(`<!--]--> <!--[-->`);
|
|
249
|
-
const
|
|
250
|
-
for (let $$
|
|
251
|
-
let entry =
|
|
611
|
+
const each_array = ensure_array_like(levelGroups());
|
|
612
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
613
|
+
let entry = each_array[$$index];
|
|
252
614
|
$$renderer.push(`<span class="flex items-center gap-1 text-neutral-400"${attr("data-testid", `scatter-legend-${stringify(entry.level)}`)}><span class="inline-block h-2 w-2 rounded-full"${attr_style(`background-color: ${stringify(SERIES_LEVEL_COLOR[entry.level])}`)}></span> ${escape_html(entry.label)} <span class="text-neutral-500">${escape_html(formatCount(entry.events))}</span></span>`);
|
|
253
615
|
}
|
|
254
616
|
$$renderer.push(`<!--]--> `);
|
|
255
617
|
if (loading && expanded()) $$renderer.push(`<!--[0--><span class="text-amber-300" data-testid="scatter-loading">loading…</span>`);
|
|
256
618
|
else $$renderer.push("<!--[-1-->");
|
|
257
|
-
$$renderer.push(`<!--]-->
|
|
619
|
+
$$renderer.push(`<!--]--> <span class="ml-auto text-neutral-400" data-testid="scatter-summary">${escape_html(formatCount(totalEvents()))}
|
|
620
|
+
${escape_html(unit())}`);
|
|
621
|
+
if (metric === "count") $$renderer.push(`<!--[0--> in ${escape_html(formatCount(bucketCount()))} buckets`);
|
|
622
|
+
else $$renderer.push("<!--[-1-->");
|
|
623
|
+
$$renderer.push(`<!--]--></span></div> `);
|
|
258
624
|
if (expanded()) {
|
|
259
|
-
$$renderer.push("
|
|
625
|
+
$$renderer.push(`<!--[0--><div${attr_class(`flex flex-col gap-1 p-2 ${fill ? "min-h-0 flex-1" : ""}`)}><div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-[0.6875rem]"><div role="group" aria-label="Chart metric" class="flex rounded-md border border-neutral-800 p-0.5"><!--[-->`);
|
|
626
|
+
const each_array_1 = ensure_array_like(["count", "duration"]);
|
|
627
|
+
for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
|
|
628
|
+
let choice = each_array_1[$$index_1];
|
|
629
|
+
$$renderer.push(`<button type="button"${attr("data-testid", `chart-metric-${choice}`)}${attr("aria-pressed", metric === choice)}${attr_class(`rounded px-2 py-0.5 transition-colors ${metric === choice ? "bg-sky-950 text-sky-300" : "text-neutral-400 hover:text-neutral-200"}`)}>${escape_html(choice === "count" ? "Count" : "Duration (ms)")}</button>`);
|
|
630
|
+
}
|
|
631
|
+
$$renderer.push(`<!--]--></div> `);
|
|
260
632
|
$$renderer.push(`<!--[-1--><span class="ml-auto text-neutral-500" data-testid="scatter-hint">select a point to show logs · drag to zoom · click background to clear</span>`);
|
|
261
|
-
$$renderer.push(`<!--]
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (expanded()) {
|
|
265
|
-
$$renderer.push("<!--[0-->");
|
|
633
|
+
$$renderer.push(`<!--]--></div> <div${attr_class(`relative overflow-hidden ${fill ? "min-h-0 flex-1" : ""}`)}${attr_style(fill ? void 0 : `height: ${height}px`)} data-testid="chart-body">`);
|
|
634
|
+
$$renderer.push(`<!--[-1--><div${attr_class(`w-full animate-pulse rounded bg-neutral-900/60 ${fill ? "h-full" : ""}`)}${attr_style(fill ? void 0 : `height: ${height}px`)}></div>`);
|
|
635
|
+
$$renderer.push(`<!--]--></div> `);
|
|
266
636
|
if (metric === "duration") $$renderer.push(`<!--[0--><p class="px-1 text-[0.6875rem] text-neutral-500" data-testid="duration-note">Observed duration (ms) · last event + its duration − first event · partial requests may
|
|
267
|
-
|
|
268
|
-
else $$renderer.push("<!--[-1-->");
|
|
269
|
-
$$renderer.push(`<!--]--> <div class="overflow-hidden"${attr_style(`height: ${stringify(height)}px`)} data-testid="chart-body">`);
|
|
270
|
-
if (hasPoints()) {
|
|
271
|
-
$$renderer.push("<!--[1-->");
|
|
272
|
-
$$renderer.push(`<!--[-1--><div class="w-full animate-pulse rounded bg-neutral-900/60"${attr_style(`height: ${stringify(height)}px`)}></div>`);
|
|
273
|
-
$$renderer.push(`<!--]-->`);
|
|
274
|
-
} else if (!loading) $$renderer.push(`<!--[2--><p class="px-1 py-6 text-xs text-neutral-500" data-testid="scatter-empty">${escape_html(metric === "duration" ? "No requests with a request ID in this window yet." : "No events in this window yet.")}</p>`);
|
|
637
|
+
appear shorter</p>`);
|
|
275
638
|
else $$renderer.push("<!--[-1-->");
|
|
276
639
|
$$renderer.push(`<!--]--></div>`);
|
|
277
640
|
} else $$renderer.push("<!--[-1-->");
|
|
@@ -310,8 +673,12 @@ function RangeControls($$renderer, $$props) {
|
|
|
310
673
|
/** True when the source cannot follow live events, such as the local archive. */
|
|
311
674
|
/** Called when the user switches mode or applies a range. */
|
|
312
675
|
let { mode = "live", range = "15m", from = null, to = null, disabled = false, loading = false, liveDisabled = false} = $$props;
|
|
313
|
-
/**
|
|
314
|
-
let
|
|
676
|
+
/** True when the custom chip stands for an explicit window with both bounds. */
|
|
677
|
+
let customActive = derived(() => mode === "historic" && range === "" && from !== null && to !== null);
|
|
678
|
+
/** Start bound on the custom chip, formatted for display. */
|
|
679
|
+
let customFromLabel = derived(() => from === null ? "" : toDateTimeLocal(from).replace("T", " "));
|
|
680
|
+
/** End bound on the custom chip, formatted for display. */
|
|
681
|
+
let customToLabel = derived(() => to === null ? "" : toDateTimeLocal(to).replace("T", " "));
|
|
315
682
|
$$renderer.push(`<div class="flex flex-wrap items-center gap-2" data-testid="range-controls"><div class="flex items-center gap-1 rounded-lg border border-neutral-800 bg-neutral-900 p-0.5" role="group" aria-label="Tail mode"><button type="button"${attr("aria-pressed", mode === "live")}${attr("disabled", liveDisabled, true)}${attr("title", liveDisabled ? "There is nothing to tail: the local archive holds historic windows" : void 0)} data-testid="mode-live"${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${mode === "live" ? "border-sky-700 bg-sky-950/60 text-sky-300" : "border-transparent text-neutral-400 hover:text-neutral-200"} disabled:opacity-40`)}>Live</button> <button type="button"${attr("aria-pressed", mode === "historic")} data-testid="mode-historic"${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${mode === "historic" ? "border-amber-700 bg-amber-950/50 text-amber-300" : "border-transparent text-neutral-400 hover:text-neutral-200"}`)}>Historic</button></div> `);
|
|
316
683
|
if (mode === "historic") {
|
|
317
684
|
$$renderer.push(`<!--[0--><div class="flex flex-wrap items-center gap-1" role="group" aria-label="Historic range"><!--[-->`);
|
|
@@ -320,7 +687,13 @@ function RangeControls($$renderer, $$props) {
|
|
|
320
687
|
let preset = each_array[$$index];
|
|
321
688
|
$$renderer.push(`<button type="button"${attr("aria-pressed", range === preset)}${attr("data-testid", `preset-${stringify(preset)}`)}${attr("disabled", disabled, true)}${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${range === preset ? "border-amber-700 bg-amber-950/50 text-amber-200" : "border-neutral-800 bg-neutral-900 text-neutral-300 hover:border-neutral-700"} disabled:opacity-40`)}>${escape_html(PRESET_LABELS[preset])}</button>`);
|
|
322
689
|
}
|
|
323
|
-
$$renderer.push(`<!--]--> <button type="button"${attr("aria-pressed", range === "")} data-testid="preset-custom"${attr("disabled", disabled, true)}${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${range === "" ? "border-amber-700 bg-amber-950/50 text-amber-200" : "border-neutral-800 bg-neutral-900 text-neutral-300 hover:border-neutral-700"}`)}
|
|
690
|
+
$$renderer.push(`<!--]--> <button type="button"${attr("aria-pressed", range === "")} data-testid="preset-custom"${attr("disabled", disabled, true)}${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${range === "" ? "border-amber-700 bg-amber-950/50 text-amber-200" : "border-neutral-800 bg-neutral-900 text-neutral-300 hover:border-neutral-700"}`)}>`);
|
|
691
|
+
if (customActive()) {
|
|
692
|
+
$$renderer.push(`<!--[0--><span class="inline-flex items-center gap-1"><span>${escape_html(customFromLabel())}</span> `);
|
|
693
|
+
Arrow_right($$renderer, { size: "1em" });
|
|
694
|
+
$$renderer.push(`<!----> <span>${escape_html(customToLabel())}</span></span>`);
|
|
695
|
+
} else $$renderer.push(`<!--[-1-->Custom…`);
|
|
696
|
+
$$renderer.push(`<!--]--></button></div>`);
|
|
324
697
|
} else $$renderer.push("<!--[-1-->");
|
|
325
698
|
$$renderer.push(`<!--]--> `);
|
|
326
699
|
if (loading) $$renderer.push(`<!--[0--><span class="text-xs text-amber-300" data-testid="range-loading">loading window…</span>`);
|
|
@@ -526,7 +899,7 @@ function LogGroupList($$renderer, $$props) {
|
|
|
526
899
|
function rowTone(name) {
|
|
527
900
|
return isSelected(name) ? "border-sky-800 bg-sky-950/50 text-sky-200" : "border-transparent bg-neutral-900/60 text-neutral-300 hover:border-neutral-800 hover:text-neutral-100";
|
|
528
901
|
}
|
|
529
|
-
$$renderer.push(`<section class="flex min-h-0 flex-1 flex-col gap-3"><div class="flex items-center justify-between gap-2"><div class="flex items-baseline gap-2"><
|
|
902
|
+
$$renderer.push(`<section class="flex min-h-0 flex-1 flex-col gap-3"><div class="flex items-center justify-between gap-2"><div class="flex items-baseline gap-2"><span class="text-xs text-neutral-500" data-testid="group-count">${escape_html(formatCount(filtered().length))} of ${escape_html(formatCount(groups.length))}</span> `);
|
|
530
903
|
if (activeSelection().length > 1) $$renderer.push(`<!--[0--><span class="text-xs font-medium text-sky-400" data-testid="selected-count">${escape_html(formatCount(activeSelection().length))} selected</span>`);
|
|
531
904
|
else $$renderer.push("<!--[-1-->");
|
|
532
905
|
$$renderer.push(`<!--]--> `);
|
|
@@ -545,17 +918,17 @@ function LogGroupList($$renderer, $$props) {
|
|
|
545
918
|
} else if (groups.length === 0) $$renderer.push(`<!--[2--><p data-testid="group-empty" class="rounded-md border border-neutral-800 bg-neutral-900/60 px-3 py-2 text-xs leading-5 text-neutral-400">${escape_html(archived() ? noArchivedGroupsMessage(region) : noGroupsMessage(region))}</p>`);
|
|
546
919
|
else if (visible().length === 0) $$renderer.push(`<!--[3--><p data-testid="group-no-match" class="px-1 py-2 text-xs text-neutral-500">No log groups match “${escape_html(query())}”.</p>`);
|
|
547
920
|
else {
|
|
548
|
-
$$renderer.push(`<!--[-1--><ul class="flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto pr-1"><!--[-->`);
|
|
921
|
+
$$renderer.push(`<!--[-1--><ul class="@container flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto pr-1"><!--[-->`);
|
|
549
922
|
const each_array_1 = ensure_array_like(visible());
|
|
550
923
|
for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
|
|
551
924
|
let group = each_array_1[$$index_1];
|
|
552
|
-
$$renderer.push(`<li class="flex items-center gap-1.5"><input type="checkbox"${attr("data-testid", `group-check-${stringify(group.name)}`)}${attr("aria-label", `Include ${group.name} in the selection`)}${attr("checked", isSelected(group.name), true)} class="size-3.5 shrink-0 cursor-pointer accent-sky-500"/> <button type="button" data-testid="group-row"${attr("data-group-name", group.name)}${attr("aria-label", group.name)}${attr("title", group.name)}${attr("aria-current", isSelected(group.name) ? "true" : void 0)}${attr_class(`flex min-w-0 flex-1 items-center justify-between gap-2 rounded-md border px-2.5 py-1.5 text-left text-xs transition-colors ${stringify(rowTone(group.name))}`)}><span class="min-w-
|
|
925
|
+
$$renderer.push(`<li class="flex items-center gap-1.5"><input type="checkbox"${attr("data-testid", `group-check-${stringify(group.name)}`)}${attr("aria-label", `Include ${group.name} in the selection`)}${attr("checked", isSelected(group.name), true)} class="size-3.5 shrink-0 cursor-pointer accent-sky-500"/> <button type="button" data-testid="group-row"${attr("data-group-name", group.name)}${attr("aria-label", group.name)}${attr("title", group.name)}${attr("aria-current", isSelected(group.name) ? "true" : void 0)}${attr_class(`flex min-w-0 flex-1 items-center justify-between gap-2 rounded-md border px-2.5 py-1.5 text-left text-xs transition-colors ${stringify(rowTone(group.name))}`)}><span class="min-w-16 flex-1 overflow-hidden whitespace-nowrap font-mono" aria-hidden="true">${escape_html(group.name)}</span> `);
|
|
553
926
|
if (archived()) {
|
|
554
927
|
$$renderer.push(`<!--[0--><span class="flex shrink-0 items-center gap-1.5">`);
|
|
555
928
|
if (archivedCount(group) !== null) $$renderer.push(`<!--[0--><span data-testid="group-archived-count"${attr("title", archivedSpan(group) ?? "Events held in the local DuckDB archive")} class="rounded-full border border-teal-900 bg-teal-950/50 px-1.5 py-0.5 text-[0.625rem] font-medium text-teal-300">${escape_html(archivedCount(group))}</span>`);
|
|
556
929
|
else $$renderer.push("<!--[-1-->");
|
|
557
930
|
$$renderer.push(`<!--]--> `);
|
|
558
|
-
if (archivedSpan(group) !== null) $$renderer.push(`<!--[0--><span class="hidden text-[0.6875rem] text-neutral-500
|
|
931
|
+
if (archivedSpan(group) !== null) $$renderer.push(`<!--[0--><span class="hidden text-[0.6875rem] text-neutral-500 @2xl:inline" data-testid="group-archived-span">${escape_html(archivedSpan(group))}</span>`);
|
|
559
932
|
else $$renderer.push("<!--[-1-->");
|
|
560
933
|
$$renderer.push(`<!--]--></span>`);
|
|
561
934
|
} else if (group.storedBytes !== void 0) $$renderer.push(`<!--[1--><span class="shrink-0 text-[0.6875rem] text-neutral-500">${escape_html(formatBytes(group.storedBytes))}</span>`);
|
|
@@ -657,11 +1030,13 @@ function LogViewer($$renderer, $$props) {
|
|
|
657
1030
|
* default, and owned by the page so the chart counts the same requests.
|
|
658
1031
|
*/
|
|
659
1032
|
/** Called when the grouping toggle is pressed. */
|
|
660
|
-
|
|
1033
|
+
/** True while the lines are shown; collapsed, the viewer keeps only its header. */
|
|
1034
|
+
/** Called when the header's collapse toggle is pressed. */
|
|
1035
|
+
let { selection = null, onSelectionClear, lines = [], status = "idle", error = null, region = "", group = null, filter = "", paused = false, autoScroll = true, pendingCount = 0, droppedCount = 0, receivedCount = 0, mode = "live", ready = null, endReason = null, archivePath = null, groups = [], level = void 0, onLevelChange, groupRequests = true, onGroupToggle, open = true, onToggle, onFilterChange, onPauseToggle, onClear, onAutoScrollToggle } = $$props;
|
|
661
1036
|
let timestampPx = remToPx(7.5);
|
|
662
1037
|
let groupPx = 144;
|
|
663
|
-
|
|
664
|
-
|
|
1038
|
+
let rowPaddingPx = derived(() => remToPx(.75, textSize.rootFontPx));
|
|
1039
|
+
let rowGapPx = derived(() => remToPx(.5, textSize.rootFontPx));
|
|
665
1040
|
const PREFIX_MIN_PX = remToPx(PREFIX_WIDTH.minRem);
|
|
666
1041
|
const PREFIX_MAX_PX = remToPx(PREFIX_WIDTH.maxRem);
|
|
667
1042
|
const PREFIX_DEFAULT_PX = remToPx(PREFIX_WIDTH.defaultRem);
|
|
@@ -859,7 +1234,7 @@ function LogViewer($$renderer, $$props) {
|
|
|
859
1234
|
/** Message cell: wrapped text or a single long line that scrolls sideways. */
|
|
860
1235
|
let messageClass = derived(() => "whitespace-pre");
|
|
861
1236
|
/** Left edge of the prefix resize handle, in pixels from the scrolled content edge. */
|
|
862
|
-
let handleLeft = derived(() =>
|
|
1237
|
+
let handleLeft = derived(() => rowPaddingPx() + timestampPx + rowGapPx() + (groups.length > 1 ? groupPx + rowGapPx() : 0) + prefixPx);
|
|
863
1238
|
/** Prefix column width as a CSS length. */
|
|
864
1239
|
let prefixStyle = derived(() => `width: ${prefixPx}px`);
|
|
865
1240
|
/** Rows the user has opened, keyed by row key. */
|
|
@@ -884,7 +1259,15 @@ function LogViewer($$renderer, $$props) {
|
|
|
884
1259
|
function savePrefixWidth() {
|
|
885
1260
|
writePref(STORAGE_KEYS.prefixWidth, String(Math.round(prefixPx)));
|
|
886
1261
|
}
|
|
887
|
-
$$renderer.push(`<section
|
|
1262
|
+
$$renderer.push(`<section${attr_class(`flex min-h-0 min-w-0 flex-col overflow-hidden bg-neutral-950 ${open ? "flex-1" : "flex-none"}`)}><div class="flex min-h-9 flex-none flex-wrap items-center gap-x-3 gap-y-2 border-b border-neutral-800 bg-neutral-900/40 px-3 py-1"><button type="button"${attr("aria-expanded", open)}${attr("title", open ? "Hide the log lines" : "Show the log lines")} data-testid="log-toggle" class="flex items-center gap-1 text-sm font-semibold text-neutral-200 transition-colors hover:text-sky-300">`);
|
|
1263
|
+
if (open) {
|
|
1264
|
+
$$renderer.push("<!--[0-->");
|
|
1265
|
+
Chevron_down($$renderer, { size: "1em" });
|
|
1266
|
+
} else {
|
|
1267
|
+
$$renderer.push("<!--[-1-->");
|
|
1268
|
+
Chevron_right($$renderer, { size: "1em" });
|
|
1269
|
+
}
|
|
1270
|
+
$$renderer.push(`<!--]--> Log lines</button> <div class="ml-auto flex flex-wrap items-center gap-x-3 gap-y-1">`);
|
|
888
1271
|
StatusBadge($$renderer, { status: displayStatus() });
|
|
889
1272
|
$$renderer.push(`<!----> `);
|
|
890
1273
|
if (archived()) $$renderer.push(`<!--[0--><span data-testid="archive-badge"${attr("title", archiveTitle())} class="rounded-full border border-teal-900 bg-teal-950/60 px-2 py-0.5 text-[0.6875rem] font-medium text-teal-300">local archive</span>`);
|
|
@@ -898,144 +1281,187 @@ function LogViewer($$renderer, $$props) {
|
|
|
898
1281
|
$$renderer.push(`<!--]--> `);
|
|
899
1282
|
if (droppedCount > 0) $$renderer.push(`<!--[0--><span class="text-xs text-amber-300/80" data-testid="dropped-count">${escape_html(formatCount(droppedCount))} dropped</span>`);
|
|
900
1283
|
else $$renderer.push("<!--[-1-->");
|
|
901
|
-
$$renderer.push(`<!--]--> <span${attr_class(`rounded-full border px-2 py-0.5 text-[0.6875rem] font-medium ${windowSummary().mode === "historic" ? "border-amber-900 bg-amber-950/40 text-amber-300" : "border-neutral-800 bg-neutral-900 text-neutral-400"}`)}${attr("title", windowSummary().title)} data-testid="window-chip"
|
|
1284
|
+
$$renderer.push(`<!--]--> <span${attr_class(`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[0.6875rem] font-medium ${windowSummary().mode === "historic" ? "border-amber-900 bg-amber-950/40 text-amber-300" : "border-neutral-800 bg-neutral-900 text-neutral-400"}`)}${attr("title", windowSummary().title)} data-testid="window-chip">`);
|
|
1285
|
+
if (windowSummary().mode === "live") $$renderer.push(`<!--[0--><span>live</span>`);
|
|
1286
|
+
else {
|
|
1287
|
+
$$renderer.push("<!--[-1-->");
|
|
1288
|
+
if (windowSummary().preset !== null) $$renderer.push(`<!--[0--><span>${escape_html(windowSummary().preset)} ·</span>`);
|
|
1289
|
+
else $$renderer.push("<!--[-1-->");
|
|
1290
|
+
$$renderer.push(`<!--]--> <span>${escape_html(windowSummary().from)}</span> `);
|
|
1291
|
+
Arrow_right($$renderer, { size: "1em" });
|
|
1292
|
+
$$renderer.push(`<!----> <span>${escape_html(windowSummary().to)}</span>`);
|
|
1293
|
+
}
|
|
1294
|
+
$$renderer.push(`<!--]--></span> `);
|
|
902
1295
|
if (windowSummary().clamped) $$renderer.push(`<!--[0--><span class="text-[0.6875rem] text-amber-400/80" data-testid="window-clamped">14-day limit</span>`);
|
|
903
1296
|
else $$renderer.push("<!--[-1-->");
|
|
904
1297
|
$$renderer.push(`<!--]--> `);
|
|
905
1298
|
if (windowComplete()) $$renderer.push(`<!--[0--><span class="text-[0.6875rem] text-emerald-400/80" data-testid="window-complete">window complete</span>`);
|
|
906
1299
|
else $$renderer.push("<!--[-1-->");
|
|
907
|
-
$$renderer.push(`<!--]
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
$$renderer.push(`<!--]--></div> <input type="search" aria-label="Filter log lines" placeholder="Filter lines"${attr("value", filter)} class="w-40 rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs text-neutral-100 outline-none transition-colors placeholder:text-neutral-600 hover:border-neutral-700 focus:border-sky-600"/> <button type="button"${attr("aria-pressed", wrapLines)} title="Wrap long lines instead of scrolling sideways" data-testid="wrap-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${wrapTone()}`)}>Wrap</button> <button type="button"${attr("aria-pressed", jsonView)} title="Pretty-print JSON log entries (off: click a line to open its JSON)" data-testid="json-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${jsonTone()}`)}>JSON</button> <button type="button"${attr("aria-pressed", groupRequests)} title="Group the lines of one request into a single row, coloured by its most critical line (off: one row per line)" data-testid="group-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${groupTone()}`)}>By request</button> <button type="button"${attr("aria-pressed", paused)} class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">${escape_html(paused ? "Resume" : "Pause")}</button> <button type="button" class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">Clear</button> <button type="button"${attr("aria-pressed", autoScroll)}${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${autoScrollTone()}`)}>Auto-scroll</button></div></div> `);
|
|
917
|
-
if (errorText() !== null) $$renderer.push(`<!--[0--><p role="alert" data-testid="stream-error" class="border-b border-red-900 bg-red-950/50 px-3 py-2 text-xs leading-5 text-red-300">${escape_html(errorText())}</p>`);
|
|
918
|
-
else $$renderer.push("<!--[-1-->");
|
|
919
|
-
$$renderer.push(`<!--]--> `);
|
|
920
|
-
if (selection !== null) {
|
|
921
|
-
$$renderer.push(`<!--[0--><div class="flex items-center gap-2 px-3 py-1 text-xs text-sky-300" role="status" data-testid="chart-selection-status">`);
|
|
922
|
-
if (selectedEvents().size === 0) $$renderer.push(`<!--[0-->Selected logs are not in the loaded buffer. Zoom into this time range to load them.`);
|
|
923
|
-
else $$renderer.push(`<!--[-1-->${escape_html(visibleSelectedCount())} of ${escape_html(selectedEvents().size)} selected log lines visible${escape_html(visibleSelectedCount() < selectedEvents().size ? " — clear the text or level filter to see all" : "")}.`);
|
|
924
|
-
$$renderer.push(`<!--]--> <button type="button" class="ml-auto underline">Clear selection</button></div>`);
|
|
925
|
-
} else $$renderer.push("<!--[-1-->");
|
|
926
|
-
$$renderer.push(`<!--]--> <div class="min-h-0 min-w-0 flex-1 overflow-auto bg-neutral-950" data-testid="log-scroller">`);
|
|
927
|
-
if (group === null || group === "") $$renderer.push(`<!--[0--><p class="px-3 py-6 text-sm text-neutral-500" data-testid="viewer-idle">Select a log group to start tailing.</p>`);
|
|
928
|
-
else if (displayRows().length === 0) $$renderer.push(`<!--[1--><p class="px-3 py-6 text-sm text-neutral-500" data-testid="viewer-empty">${escape_html(emptyText())}</p>`);
|
|
929
|
-
else {
|
|
930
|
-
$$renderer.push("<!--[-1-->");
|
|
931
|
-
function logLine($$renderer, row, child) {
|
|
932
|
-
const expandable = row.expandable !== null;
|
|
933
|
-
const open = expandable && isExpanded(row.key);
|
|
934
|
-
$$renderer.push(`<li${attr_class(`flex flex-wrap items-baseline gap-2 px-3 py-0.5 hover:bg-neutral-900/60 ${listClass()} ${expandable ? "cursor-pointer" : ""}`, void 0, {
|
|
935
|
-
"bg-sky-950": row.selected,
|
|
936
|
-
"ring-1": row.selected,
|
|
937
|
-
"ring-inset": row.selected,
|
|
938
|
-
"ring-sky-700": row.selected
|
|
939
|
-
})} data-testid="log-line"${attr("data-chart-selected", row.selected ? "true" : void 0)}${attr("data-request-child", child ? "true" : void 0)}${attr("data-level", row.level ?? "unknown")}${attr("data-expandable", expandable ? "true" : void 0)}${attr("data-expanded", open ? "true" : void 0)}${attr("role", expandable ? "button" : void 0)}${attr("tabindex", expandable ? 0 : void 0)}${attr("aria-expanded", expandable ? open : void 0)}${attr("title", expandable ? open ? "Hide the JSON in this line" : "Show this line as JSON" : void 0)}><span class="shrink-0 truncate text-neutral-500"${attr_style(`width: ${stringify(timestampPx)}px`)}${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
|
|
940
|
-
if (groups.length > 1) $$renderer.push(`<!--[0--><span class="shrink-0 truncate text-teal-400/80"${attr_style(`width: ${stringify(groupPx)}px`)}${attr("title", row.group ?? "")} data-testid="log-group">${escape_html(row.group ?? "")}</span>`);
|
|
941
|
-
else $$renderer.push("<!--[-1-->");
|
|
942
|
-
$$renderer.push(`<!--]--> <span class="shrink-0 truncate text-sky-400/80"${attr_style(prefixStyle())}${attr("title", row.streamName ?? "")} data-testid="log-stream">${escape_html(row.streamName ?? "")}</span> `);
|
|
943
|
-
if (expandable) $$renderer.push(`<!--[0--><span class="shrink-0 text-neutral-600" aria-hidden="true">${escape_html(open ? "▾" : "▸")}</span>`);
|
|
1300
|
+
$$renderer.push(`<!--]--></div></div> `);
|
|
1301
|
+
if (open) {
|
|
1302
|
+
$$renderer.push(`<!--[0--><div class="flex flex-none flex-wrap items-center gap-2 border-b border-neutral-800 bg-neutral-900/40 px-3 py-1.5"><div class="flex items-center gap-1" role="group" aria-label="Filter by level"><button type="button"${attr("aria-pressed", levelFilter() === null)} title="Show every level, including lines with no level" data-testid="level-all"${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${levelFilter() === null ? "border-sky-700 bg-sky-950/60 text-sky-200" : "border-neutral-800 bg-neutral-900 text-neutral-400 hover:border-neutral-700"}`)}>All</button> <!--[-->`);
|
|
1303
|
+
const each_array = ensure_array_like(LEVEL_CHIPS);
|
|
1304
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
1305
|
+
let chip = each_array[$$index];
|
|
1306
|
+
$$renderer.push(`<button type="button"${attr("aria-pressed", levelFilter() === chip.level)}${attr("title", `Show only ${stringify(chip.label)} lines (${stringify(levelCounts()[chip.level] ?? 0)} loaded)`)}${attr("data-testid", `level-${stringify(chip.level)}`)}${attr_class(`rounded-md border px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${stringify(levelFilter() === chip.level ? chip.activeClass : "border-neutral-800 bg-neutral-900 text-neutral-400 hover:border-neutral-700")}`)}>${escape_html(chip.label)} `);
|
|
1307
|
+
if ((levelCounts()[chip.level] ?? 0) > 0) $$renderer.push(`<!--[0--><span class="ml-1 opacity-70">${escape_html(formatCount(levelCounts()[chip.level] ?? 0))}</span>`);
|
|
944
1308
|
else $$renderer.push("<!--[-1-->");
|
|
945
|
-
$$renderer.push(`<!--]
|
|
946
|
-
if (row.tokens !== null) {
|
|
947
|
-
$$renderer.push(`<!--[0--><!--[-->`);
|
|
948
|
-
const each_array_1 = ensure_array_like(row.tokens);
|
|
949
|
-
for (let tokenIndex = 0, $$length = each_array_1.length; tokenIndex < $$length; tokenIndex++) {
|
|
950
|
-
let token = each_array_1[tokenIndex];
|
|
951
|
-
$$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
|
|
952
|
-
}
|
|
953
|
-
$$renderer.push(`<!--]-->`);
|
|
954
|
-
} else $$renderer.push(`<!--[-1-->${escape_html(row.message)}`);
|
|
955
|
-
$$renderer.push(`<!--]--></span> `);
|
|
956
|
-
if (open && row.expandable !== null) {
|
|
957
|
-
$$renderer.push(`<!--[0--><span class="w-full whitespace-pre text-xs text-neutral-300" data-testid="log-json-expanded"><!--[-->`);
|
|
958
|
-
const each_array_2 = ensure_array_like(tokenizeJson(row.expandable));
|
|
959
|
-
for (let tokenIndex = 0, $$length = each_array_2.length; tokenIndex < $$length; tokenIndex++) {
|
|
960
|
-
let token = each_array_2[tokenIndex];
|
|
961
|
-
$$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
|
|
962
|
-
}
|
|
963
|
-
$$renderer.push(`<!--]--></span>`);
|
|
964
|
-
} else $$renderer.push("<!--[-1-->");
|
|
965
|
-
$$renderer.push(`<!--]--></li>`);
|
|
1309
|
+
$$renderer.push(`<!--]--></button>`);
|
|
966
1310
|
}
|
|
967
|
-
$$renderer.push(
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1311
|
+
$$renderer.push(`<!--]--></div> <input type="search" aria-label="Filter log lines" placeholder="Filter lines"${attr("value", filter)} class="w-40 rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs text-neutral-100 outline-none transition-colors placeholder:text-neutral-600 hover:border-neutral-700 focus:border-sky-600"/> <button type="button"${attr("aria-pressed", wrapLines)} title="Wrap long lines instead of scrolling sideways" data-testid="wrap-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${wrapTone()}`)}>Wrap</button> <button type="button"${attr("aria-pressed", jsonView)} title="Pretty-print JSON log entries (off: click a line to open its JSON)" data-testid="json-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${jsonTone()}`)}>JSON</button> <button type="button"${attr("aria-pressed", groupRequests)} title="Group the lines of one request into a single row, coloured by its most critical line (off: one row per line)" data-testid="group-toggle"${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${groupTone()}`)}>By request</button> <button type="button"${attr("aria-pressed", paused)} class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">${escape_html(paused ? "Resume" : "Pause")}</button> <button type="button" class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">Clear</button> <button type="button"${attr("aria-pressed", autoScroll)}${attr_class(`rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 text-xs font-medium transition-colors hover:border-neutral-700 ${autoScrollTone()}`)}>Auto-scroll</button></div> `);
|
|
1312
|
+
if (errorText() !== null) $$renderer.push(`<!--[0--><p role="alert" data-testid="stream-error" class="border-b border-red-900 bg-red-950/50 px-3 py-2 text-xs leading-5 text-red-300">${escape_html(errorText())}</p>`);
|
|
1313
|
+
else $$renderer.push("<!--[-1-->");
|
|
1314
|
+
$$renderer.push(`<!--]--> `);
|
|
1315
|
+
if (selection !== null) {
|
|
1316
|
+
$$renderer.push(`<!--[0--><div class="flex items-center gap-2 px-3 py-1 text-xs text-sky-300" role="status" data-testid="chart-selection-status">`);
|
|
1317
|
+
if (selectedEvents().size === 0) $$renderer.push(`<!--[0-->Selected logs are not in the loaded buffer. Zoom into this time range to load them.`);
|
|
1318
|
+
else $$renderer.push(`<!--[-1-->${escape_html(visibleSelectedCount())} of ${escape_html(selectedEvents().size)} selected log lines visible${escape_html(visibleSelectedCount() < selectedEvents().size ? " — clear the text or level filter to see all" : "")}.`);
|
|
1319
|
+
$$renderer.push(`<!--]--> <button type="button" class="ml-auto underline">Clear selection</button></div>`);
|
|
1320
|
+
} else $$renderer.push("<!--[-1-->");
|
|
1321
|
+
$$renderer.push(`<!--]--> <div class="min-h-0 min-w-0 flex-1 overflow-auto bg-neutral-950" data-testid="log-scroller">`);
|
|
1322
|
+
if (group === null || group === "") $$renderer.push(`<!--[0--><p class="px-3 py-6 text-sm text-neutral-500" data-testid="viewer-idle">Select a log group to start tailing.</p>`);
|
|
1323
|
+
else if (displayRows().length === 0) $$renderer.push(`<!--[1--><p class="px-3 py-6 text-sm text-neutral-500" data-testid="viewer-empty">${escape_html(emptyText())}</p>`);
|
|
1324
|
+
else {
|
|
1325
|
+
$$renderer.push("<!--[-1-->");
|
|
1326
|
+
function logLine($$renderer, row, child) {
|
|
1327
|
+
const expandable = row.expandable !== null;
|
|
1328
|
+
const open = expandable && isExpanded(row.key);
|
|
1329
|
+
$$renderer.push(`<li${attr_class(`flex flex-wrap items-baseline gap-2 px-3 py-0.5 hover:bg-neutral-900/60 ${listClass()} ${expandable ? "cursor-pointer" : ""}`, void 0, {
|
|
1330
|
+
"bg-sky-950": row.selected,
|
|
1331
|
+
"ring-1": row.selected,
|
|
1332
|
+
"ring-inset": row.selected,
|
|
1333
|
+
"ring-sky-700": row.selected
|
|
1334
|
+
})} data-testid="log-line"${attr("data-chart-selected", row.selected ? "true" : void 0)}${attr("data-request-child", child ? "true" : void 0)}${attr("data-level", row.level ?? "unknown")}${attr("data-expandable", expandable ? "true" : void 0)}${attr("data-expanded", open ? "true" : void 0)}${attr("role", expandable ? "button" : void 0)}${attr("tabindex", expandable ? 0 : void 0)}${attr("aria-expanded", expandable ? open : void 0)}${attr("title", expandable ? open ? "Hide the JSON in this line" : "Show this line as JSON" : void 0)}><span class="shrink-0 truncate text-neutral-500"${attr_style(`width: ${stringify(timestampPx)}px`)}${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
|
|
975
1335
|
if (groups.length > 1) $$renderer.push(`<!--[0--><span class="shrink-0 truncate text-teal-400/80"${attr_style(`width: ${stringify(groupPx)}px`)}${attr("title", row.group ?? "")} data-testid="log-group">${escape_html(row.group ?? "")}</span>`);
|
|
976
1336
|
else $$renderer.push("<!--[-1-->");
|
|
977
|
-
$$renderer.push(`<!--]--> <span class="shrink-0 truncate text-sky-400/80"${attr_style(prefixStyle())}${attr("title", row.streamName ?? "")} data-testid="log-stream">${escape_html(row.streamName ?? "")}</span>
|
|
978
|
-
if (
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1337
|
+
$$renderer.push(`<!--]--> <span class="shrink-0 truncate text-sky-400/80"${attr_style(prefixStyle())}${attr("title", row.streamName ?? "")} data-testid="log-stream">${escape_html(row.streamName ?? "")}</span> `);
|
|
1338
|
+
if (expandable) {
|
|
1339
|
+
$$renderer.push("<!--[0-->");
|
|
1340
|
+
if (open) {
|
|
1341
|
+
$$renderer.push("<!--[0-->");
|
|
1342
|
+
Chevron_down($$renderer, {
|
|
1343
|
+
class: "shrink-0 text-neutral-600",
|
|
1344
|
+
size: "1em"
|
|
1345
|
+
});
|
|
1346
|
+
} else {
|
|
1347
|
+
$$renderer.push("<!--[-1-->");
|
|
1348
|
+
Chevron_right($$renderer, {
|
|
1349
|
+
class: "shrink-0 text-neutral-600",
|
|
1350
|
+
size: "1em"
|
|
1351
|
+
});
|
|
987
1352
|
}
|
|
988
|
-
$$renderer.push(`<!--]
|
|
1353
|
+
$$renderer.push(`<!--]-->`);
|
|
1354
|
+
} else $$renderer.push("<!--[-1-->");
|
|
1355
|
+
$$renderer.push(`<!--]--> <span${attr_class(`${messageClass()} ${stringify(row.levelClass)}`)} data-testid="log-message">`);
|
|
1356
|
+
if (row.tokens !== null) {
|
|
1357
|
+
$$renderer.push(`<!--[0--><!--[-->`);
|
|
1358
|
+
const each_array_1 = ensure_array_like(row.tokens);
|
|
1359
|
+
for (let tokenIndex = 0, $$length = each_array_1.length; tokenIndex < $$length; tokenIndex++) {
|
|
1360
|
+
let token = each_array_1[tokenIndex];
|
|
1361
|
+
$$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
|
|
1362
|
+
}
|
|
1363
|
+
$$renderer.push(`<!--]-->`);
|
|
1364
|
+
} else $$renderer.push(`<!--[-1-->${escape_html(row.message)}`);
|
|
1365
|
+
$$renderer.push(`<!--]--></span> `);
|
|
1366
|
+
if (open && row.expandable !== null) {
|
|
1367
|
+
$$renderer.push(`<!--[0--><span class="w-full whitespace-pre text-xs text-neutral-300" data-testid="log-json-expanded"><!--[-->`);
|
|
1368
|
+
const each_array_2 = ensure_array_like(tokenizeJson(row.expandable));
|
|
1369
|
+
for (let tokenIndex = 0, $$length = each_array_2.length; tokenIndex < $$length; tokenIndex++) {
|
|
1370
|
+
let token = each_array_2[tokenIndex];
|
|
1371
|
+
$$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
|
|
1372
|
+
}
|
|
1373
|
+
$$renderer.push(`<!--]--></span>`);
|
|
989
1374
|
} else $$renderer.push("<!--[-1-->");
|
|
990
1375
|
$$renderer.push(`<!--]--></li>`);
|
|
991
|
-
} else {
|
|
992
|
-
$$renderer.push("<!--[-1-->");
|
|
993
|
-
logLine($$renderer, row, false);
|
|
994
1376
|
}
|
|
995
|
-
$$renderer.push(
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1377
|
+
$$renderer.push(`<div${attr_class(`relative min-h-full ${listClass()}`)} data-testid="log-canvas"${attr_style("", { "min-width": void 0 })}><ol class="font-mono text-xs leading-5" data-testid="log-lines"><!--[-->`);
|
|
1378
|
+
const each_array_3 = ensure_array_like(displayRows());
|
|
1379
|
+
for (let $$index_4 = 0, $$length = each_array_3.length; $$index_4 < $$length; $$index_4++) {
|
|
1380
|
+
let row = each_array_3[$$index_4];
|
|
1381
|
+
if (row.kind === "request") {
|
|
1382
|
+
$$renderer.push("<!--[0-->");
|
|
1383
|
+
const open = isExpanded(row.key);
|
|
1384
|
+
$$renderer.push(`<li${attr_class(clsx(listClass()), void 0, { "bg-sky-950": row.children.some((child) => child.selected) })} data-testid="log-request-group"${attr("data-chart-selected", row.children.some((child) => child.selected) ? "true" : void 0)}${attr("data-request-id", row.id)}${attr("data-level", row.level)}${attr("data-expanded", open ? "true" : void 0)}${attr("data-lines", row.count)}><button type="button" class="flex w-full flex-wrap items-baseline gap-2 px-3 py-0.5 text-left hover:bg-neutral-900/60"${attr("aria-expanded", open)}${attr("title", open ? "Hide the lines of this request" : "Show every line of this request")} data-testid="request-group-summary"><span class="shrink-0 truncate text-neutral-500"${attr_style(`width: ${stringify(timestampPx)}px`)}${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
|
|
1385
|
+
if (groups.length > 1) $$renderer.push(`<!--[0--><span class="shrink-0 truncate text-teal-400/80"${attr_style(`width: ${stringify(groupPx)}px`)}${attr("title", row.group ?? "")} data-testid="log-group">${escape_html(row.group ?? "")}</span>`);
|
|
1386
|
+
else $$renderer.push("<!--[-1-->");
|
|
1387
|
+
$$renderer.push(`<!--]--> <span class="shrink-0 truncate text-sky-400/80"${attr_style(prefixStyle())}${attr("title", row.streamName ?? "")} data-testid="log-stream">${escape_html(row.streamName ?? "")}</span> `);
|
|
1388
|
+
if (open) {
|
|
1389
|
+
$$renderer.push("<!--[0-->");
|
|
1390
|
+
Chevron_down($$renderer, {
|
|
1391
|
+
class: "shrink-0 text-neutral-600",
|
|
1392
|
+
size: "1em"
|
|
1393
|
+
});
|
|
1394
|
+
} else {
|
|
1395
|
+
$$renderer.push("<!--[-1-->");
|
|
1396
|
+
Chevron_right($$renderer, {
|
|
1397
|
+
class: "shrink-0 text-neutral-600",
|
|
1398
|
+
size: "1em"
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
$$renderer.push(`<!--]--> <span class="shrink-0 rounded border border-neutral-700 bg-neutral-900 px-1.5 font-mono text-[0.6875rem] text-sky-200" data-testid="request-group-id" title="Request id shared by these lines">${escape_html(row.id)}</span> <span class="shrink-0 text-neutral-400" data-testid="request-group-count">${escape_html(formatCount(row.count))} lines</span> <span class="shrink-0 text-neutral-500" data-testid="request-group-span">${escape_html(row.span)}</span> <span${attr_class(`shrink-0 font-medium ${stringify(row.levelClass)}`)} data-testid="request-group-level">${escape_html(row.levelLabel)}</span> `);
|
|
1402
|
+
if (!open) $$renderer.push(`<!--[0--><span class="min-w-0 truncate text-neutral-500" data-testid="request-group-preview">${escape_html(row.preview)}</span>`);
|
|
1403
|
+
else $$renderer.push("<!--[-1-->");
|
|
1404
|
+
$$renderer.push(`<!--]--></button> `);
|
|
1405
|
+
if (open) {
|
|
1406
|
+
$$renderer.push(`<!--[0--><ul class="contents"><!--[-->`);
|
|
1407
|
+
const each_array_4 = ensure_array_like(row.children);
|
|
1408
|
+
for (let $$index_3 = 0, $$length = each_array_4.length; $$index_3 < $$length; $$index_3++) {
|
|
1409
|
+
let child = each_array_4[$$index_3];
|
|
1410
|
+
logLine($$renderer, child, true);
|
|
1411
|
+
}
|
|
1412
|
+
$$renderer.push(`<!--]--></ul>`);
|
|
1413
|
+
} else $$renderer.push("<!--[-1-->");
|
|
1414
|
+
$$renderer.push(`<!--]--></li>`);
|
|
1415
|
+
} else {
|
|
1416
|
+
$$renderer.push("<!--[-1-->");
|
|
1417
|
+
logLine($$renderer, row, false);
|
|
1418
|
+
}
|
|
1419
|
+
$$renderer.push(`<!--]-->`);
|
|
1420
|
+
}
|
|
1421
|
+
$$renderer.push(`<!--]--></ol> `);
|
|
1012
1422
|
ColumnResizer($$renderer, {
|
|
1013
|
-
label: "Resize
|
|
1014
|
-
width:
|
|
1423
|
+
label: "Resize timestamp column",
|
|
1424
|
+
width: timestampPx,
|
|
1015
1425
|
min: 64,
|
|
1016
|
-
max:
|
|
1017
|
-
testId: "
|
|
1018
|
-
onChange: (next) =>
|
|
1019
|
-
onCommit: (next) => writePref(STORAGE_KEYS.
|
|
1426
|
+
max: 320,
|
|
1427
|
+
testId: "timestamp-resizer",
|
|
1428
|
+
onChange: (next) => timestampPx = next,
|
|
1429
|
+
onCommit: (next) => writePref(STORAGE_KEYS.timestampWidth, String(next)),
|
|
1020
1430
|
class: "absolute inset-y-0 w-2 border-r border-neutral-800/40",
|
|
1021
|
-
style: `left: ${stringify(
|
|
1431
|
+
style: `left: ${stringify(rowPaddingPx() + timestampPx - 4)}px`
|
|
1022
1432
|
});
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1433
|
+
$$renderer.push(`<!----> `);
|
|
1434
|
+
if (groups.length > 1) {
|
|
1435
|
+
$$renderer.push("<!--[0-->");
|
|
1436
|
+
ColumnResizer($$renderer, {
|
|
1437
|
+
label: "Resize log group column",
|
|
1438
|
+
width: groupPx,
|
|
1439
|
+
min: 64,
|
|
1440
|
+
max: 640,
|
|
1441
|
+
testId: "group-resizer",
|
|
1442
|
+
onChange: (next) => groupPx = next,
|
|
1443
|
+
onCommit: (next) => writePref(STORAGE_KEYS.groupWidth, String(next)),
|
|
1444
|
+
class: "absolute inset-y-0 w-2 border-r border-neutral-800/40",
|
|
1445
|
+
style: `left: ${stringify(rowPaddingPx() + timestampPx + rowGapPx() + groupPx - 4)}px`
|
|
1446
|
+
});
|
|
1447
|
+
} else $$renderer.push("<!--[-1-->");
|
|
1448
|
+
$$renderer.push(`<!--]--> `);
|
|
1449
|
+
ColumnResizer($$renderer, {
|
|
1450
|
+
label: "Resize stream column",
|
|
1451
|
+
width: prefixPx,
|
|
1452
|
+
min: PREFIX_MIN_PX,
|
|
1453
|
+
max: PREFIX_MAX_PX,
|
|
1454
|
+
testId: "prefix-resizer",
|
|
1455
|
+
onChange: (next) => prefixPx = next,
|
|
1456
|
+
onCommit: () => savePrefixWidth(),
|
|
1457
|
+
class: "absolute inset-y-0 w-2 border-r border-neutral-800/40",
|
|
1458
|
+
style: `left: ${stringify(handleLeft() - 4)}px`
|
|
1459
|
+
});
|
|
1460
|
+
$$renderer.push(`<!----></div>`);
|
|
1461
|
+
}
|
|
1462
|
+
$$renderer.push(`<!--]--></div>`);
|
|
1463
|
+
} else $$renderer.push("<!--[-1-->");
|
|
1464
|
+
$$renderer.push(`<!--]--></section>`);
|
|
1039
1465
|
});
|
|
1040
1466
|
}
|
|
1041
1467
|
//#endregion
|
|
@@ -1377,6 +1803,10 @@ function _page($$renderer, $$props) {
|
|
|
1377
1803
|
* A stored preference wins, so a reader who wants every line keeps every line.
|
|
1378
1804
|
*/
|
|
1379
1805
|
let groupRequests = true;
|
|
1806
|
+
/** True while the group-list sidebar is open; collapsing gives the logs the full width. */
|
|
1807
|
+
let sidebarOpen = true;
|
|
1808
|
+
/** True while the log lines are shown; collapsing keeps only the viewer's header. */
|
|
1809
|
+
let logOpen = true;
|
|
1380
1810
|
/** Bucketed counts behind the chart. */
|
|
1381
1811
|
let chartSelection = null;
|
|
1382
1812
|
let seriesBucketMs = 6e4;
|
|
@@ -1396,7 +1826,7 @@ function _page($$renderer, $$props) {
|
|
|
1396
1826
|
/** Largest sidebar width allowed: 44vw, but never below the minimum. */
|
|
1397
1827
|
let sidebarMaxPx = derived(() => remToPx(SIDEBAR_WIDTH.defaultRem));
|
|
1398
1828
|
let sidebarMinPx = remToPx(SIDEBAR_WIDTH.minRem);
|
|
1399
|
-
let sidebarStyle = derived(() =>
|
|
1829
|
+
let sidebarStyle = derived(() => `--sidebar-width: min(${sidebarPx}px, ${SIDEBAR_WIDTH.maxVw}vw)`);
|
|
1400
1830
|
/** Persists the sidebar width; failures are ignored (private mode, quota). */
|
|
1401
1831
|
function saveSidebarWidth() {
|
|
1402
1832
|
try {
|
|
@@ -1434,6 +1864,7 @@ function _page($$renderer, $$props) {
|
|
|
1434
1864
|
if (target !== region || requestedSource !== source) return;
|
|
1435
1865
|
if (response.endpoint !== null) endpoint = response.endpoint;
|
|
1436
1866
|
groups = response.groups;
|
|
1867
|
+
puppy.wag();
|
|
1437
1868
|
} catch (error) {
|
|
1438
1869
|
if (target !== region || requestedSource !== source) return;
|
|
1439
1870
|
groups = [];
|
|
@@ -1509,6 +1940,14 @@ function _page($$renderer, $$props) {
|
|
|
1509
1940
|
localStorage?.setItem(STORAGE_KEYS.groupRequests, groupRequests ? "true" : "false");
|
|
1510
1941
|
} catch {}
|
|
1511
1942
|
}
|
|
1943
|
+
/** Collapses or expands the log lines, and remembers the choice. */
|
|
1944
|
+
function toggleLog() {
|
|
1945
|
+
logOpen = !logOpen;
|
|
1946
|
+
puppy.wag();
|
|
1947
|
+
try {
|
|
1948
|
+
localStorage?.setItem(STORAGE_KEYS.logOpen, logOpen ? "true" : "false");
|
|
1949
|
+
} catch {}
|
|
1950
|
+
}
|
|
1512
1951
|
/** Switches region: stops the stream, clears the list and reloads the groups. */
|
|
1513
1952
|
function changeRegion(next) {
|
|
1514
1953
|
if (next === "" || next === region) return;
|
|
@@ -1555,6 +1994,7 @@ function _page($$renderer, $$props) {
|
|
|
1555
1994
|
* Keeps the chart in step with the view: a new window, selection, source, level
|
|
1556
1995
|
* or a new batch of lines all re-load the counts.
|
|
1557
1996
|
*/
|
|
1997
|
+
/** Every batch of log lines that arrives gives the puppy (when shown) a wag. */
|
|
1558
1998
|
/**
|
|
1559
1999
|
* Reacts to `archive-unavailable` from the stream (the file was locked or removed after boot) by
|
|
1560
2000
|
* re-checking the archive, so the toggle hides itself instead of offering a source that fails.
|
|
@@ -1638,6 +2078,7 @@ function _page($$renderer, $$props) {
|
|
|
1638
2078
|
if (request === seriesRequest) {
|
|
1639
2079
|
seriesPoints = series.points;
|
|
1640
2080
|
seriesBucketMs = series.bucketMs;
|
|
2081
|
+
puppy.wag();
|
|
1641
2082
|
}
|
|
1642
2083
|
} catch {
|
|
1643
2084
|
if (request === seriesRequest) seriesPoints = [];
|
|
@@ -1645,7 +2086,16 @@ function _page($$renderer, $$props) {
|
|
|
1645
2086
|
if (request === seriesRequest) seriesLoading = false;
|
|
1646
2087
|
}
|
|
1647
2088
|
}
|
|
1648
|
-
$$renderer.push(`<div class="flex flex-wrap items-center gap-x-3 gap-y-2"
|
|
2089
|
+
$$renderer.push(`<div class="flex flex-wrap items-center gap-x-3 gap-y-2">`);
|
|
2090
|
+
RangeControls($$renderer, {
|
|
2091
|
+
mode,
|
|
2092
|
+
range,
|
|
2093
|
+
from: windowFrom,
|
|
2094
|
+
to: windowTo,
|
|
2095
|
+
loading: rangeLoading,
|
|
2096
|
+
disabled: selectedGroup() === null,
|
|
2097
|
+
liveDisabled: source === "archive"});
|
|
2098
|
+
$$renderer.push(`<!----> <div class="ml-auto flex flex-wrap items-center gap-x-3 gap-y-2"><span class="text-[0.6875rem] font-semibold uppercase tracking-wider text-neutral-500">Watching</span> <span class="max-w-[22rem] truncate rounded-md border border-neutral-800 bg-neutral-900 px-2 py-1 font-mono text-xs text-neutral-200">${escape_html(selectedGroup() ?? "no group selected")}</span> <span class="text-xs text-neutral-500">in</span> <span class="font-mono text-xs text-neutral-300">${escape_html(region === "" ? "resolving region…" : region)}</span> `);
|
|
1649
2099
|
if (source === "archive") {
|
|
1650
2100
|
$$renderer.push("<!--[0-->");
|
|
1651
2101
|
EndpointBadge($$renderer, {
|
|
@@ -1662,18 +2112,15 @@ function _page($$renderer, $$props) {
|
|
|
1662
2112
|
}
|
|
1663
2113
|
$$renderer.push(`<!--]--> `);
|
|
1664
2114
|
$$renderer.push("<!--[-1-->");
|
|
1665
|
-
$$renderer.push(`<!--]--></div> `);
|
|
2115
|
+
$$renderer.push(`<!--]--></div></div> `);
|
|
1666
2116
|
$$renderer.push("<!--[-1-->");
|
|
1667
|
-
$$renderer.push(`<!--]--> `);
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
disabled: selectedGroup() === null,
|
|
1675
|
-
liveDisabled: source === "archive"});
|
|
1676
|
-
$$renderer.push(`<!----> <div class="flex min-h-0 min-w-0 flex-1 flex-col gap-3 lg:flex-row"><div class="flex min-h-0 w-full flex-col gap-3 rounded-lg border border-neutral-800 bg-neutral-950/60 p-3 lg:shrink-0"${attr_style(sidebarStyle())} data-testid="sidebar">`);
|
|
2117
|
+
$$renderer.push(`<!--]--> <div class="flex min-h-0 min-w-0 flex-1 flex-col border border-neutral-800 lg:flex-row"><div id="log-group-sidebar"${attr_class(`relative flex min-h-0 w-full flex-col border-b border-neutral-800 bg-neutral-950/60 lg:shrink-0 lg:border-b-0 lg:border-r `, "svelte-1uha8ag")}${attr_style(sidebarStyle())} data-testid="sidebar"><div class="flex min-h-9 flex-none items-center gap-x-3 border-b border-neutral-800 bg-neutral-900/40 px-3 py-1.5"><button type="button"${attr("aria-expanded", sidebarOpen)} aria-controls="log-group-sidebar"${attr("title", "Hide the group list")} data-testid="sidebar-collapse" class="flex items-center gap-1 text-sm font-semibold text-neutral-200 transition-colors hover:text-sky-300"><span class="hidden lg:inline-flex">`);
|
|
2118
|
+
Chevron_left($$renderer, { size: "1em" });
|
|
2119
|
+
$$renderer.push(`<!----></span> <span class="lg:hidden">`);
|
|
2120
|
+
$$renderer.push("<!--[0-->");
|
|
2121
|
+
Chevron_up($$renderer, { size: "1em" });
|
|
2122
|
+
$$renderer.push(`<!--]--></span> ${escape_html(source === "archive" ? "Archived groups" : "Log groups")}</button></div> `);
|
|
2123
|
+
$$renderer.push(`<!--[0--><div class="flex min-h-0 flex-1 flex-col gap-3 p-3" data-testid="sidebar-body">`);
|
|
1677
2124
|
SourceControls($$renderer, {
|
|
1678
2125
|
source,
|
|
1679
2126
|
archiveAvailable: archiveAvailable(),
|
|
@@ -1701,9 +2148,12 @@ function _page($$renderer, $$props) {
|
|
|
1701
2148
|
testId: "sidebar-resizer",
|
|
1702
2149
|
onChange: (next) => sidebarPx = next,
|
|
1703
2150
|
onCommit: () => saveSidebarWidth(),
|
|
1704
|
-
class: "hidden lg:block
|
|
2151
|
+
class: "absolute inset-y-0 -right-1 z-10 hidden w-2 lg:block"
|
|
1705
2152
|
});
|
|
1706
|
-
$$renderer.push(
|
|
2153
|
+
$$renderer.push(`<!---->`);
|
|
2154
|
+
$$renderer.push(`<!--]--></div> `);
|
|
2155
|
+
$$renderer.push("<!--[-1-->");
|
|
2156
|
+
$$renderer.push(`<!--]--> <div class="flex min-h-0 min-w-0 flex-1 flex-col">`);
|
|
1707
2157
|
EventScatterPanel($$renderer, {
|
|
1708
2158
|
points: seriesPoints,
|
|
1709
2159
|
from: chartWindow().from,
|
|
@@ -1711,6 +2161,7 @@ function _page($$renderer, $$props) {
|
|
|
1711
2161
|
bucketMs: seriesBucketMs,
|
|
1712
2162
|
groups: selectedGroups,
|
|
1713
2163
|
byRequest: groupRequests,
|
|
2164
|
+
fill: !logOpen,
|
|
1714
2165
|
metric: chartMetric,
|
|
1715
2166
|
onMetricChange: (metric) => {
|
|
1716
2167
|
chartSelection = null;
|
|
@@ -1729,7 +2180,7 @@ function _page($$renderer, $$props) {
|
|
|
1729
2180
|
onBrush: applyBrush
|
|
1730
2181
|
});
|
|
1731
2182
|
$$renderer.push(`<!----> `);
|
|
1732
|
-
if (windowFrom !== null && windowTo !== null && mode === "historic") $$renderer.push(`<!--[0--><div class="flex flex-wrap items-center gap-2 text-[0.6875rem] text-neutral-500"><span data-testid="brush-window">zoomed to ${escape_html(new Date(windowFrom).toLocaleTimeString())} – ${escape_html(new Date(windowTo).toLocaleTimeString())}</span> <button type="button" data-testid="brush-clear" class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-0.5 font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">Reset zoom</button></div>`);
|
|
2183
|
+
if (windowFrom !== null && windowTo !== null && mode === "historic") $$renderer.push(`<!--[0--><div class="flex flex-wrap items-center gap-2 border-b border-neutral-800 bg-neutral-950/60 px-3 py-1.5 text-[0.6875rem] text-neutral-500"><span data-testid="brush-window">zoomed to ${escape_html(new Date(windowFrom).toLocaleTimeString())} – ${escape_html(new Date(windowTo).toLocaleTimeString())}</span> <button type="button" data-testid="brush-clear" class="rounded-md border border-neutral-800 bg-neutral-900 px-2 py-0.5 font-medium text-neutral-300 transition-colors hover:border-neutral-700 hover:text-neutral-100">Reset zoom</button></div>`);
|
|
1733
2184
|
else $$renderer.push("<!--[-1-->");
|
|
1734
2185
|
$$renderer.push(`<!--]--> `);
|
|
1735
2186
|
LogViewer($$renderer, {
|
|
@@ -1749,6 +2200,8 @@ function _page($$renderer, $$props) {
|
|
|
1749
2200
|
onLevelChange: (next) => levelFilter = next,
|
|
1750
2201
|
groupRequests,
|
|
1751
2202
|
onGroupToggle: toggleGroupRequests,
|
|
2203
|
+
open: logOpen,
|
|
2204
|
+
onToggle: toggleLog,
|
|
1752
2205
|
filter,
|
|
1753
2206
|
paused: stream.paused,
|
|
1754
2207
|
autoScroll,
|
|
@@ -1771,4 +2224,3 @@ function _page($$renderer, $$props) {
|
|
|
1771
2224
|
}
|
|
1772
2225
|
|
|
1773
2226
|
export { _page as default };
|
|
1774
|
-
//# sourceMappingURL=_page.svelte.js-C9-7d7mD.js.map
|