watch-tail 0.5.0 → 0.6.0

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.
Files changed (242) hide show
  1. package/README.md +30 -2
  2. package/build/client/_app/immutable/assets/{0.BQQ1YLPc.css → 0.Dfts6BC4.css} +1 -1
  3. package/build/client/_app/immutable/assets/0.Dfts6BC4.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.Dfts6BC4.css.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{D-JtVVAo.js → Amq8zxdJ.js} +1 -1
  6. package/build/client/_app/immutable/chunks/Amq8zxdJ.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/Amq8zxdJ.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{B6nyufJR.js → B3p3umIY.js} +1 -1
  9. package/build/client/_app/immutable/chunks/B3p3umIY.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/B3p3umIY.js.gz +0 -0
  11. package/build/client/_app/immutable/chunks/{DJDlf6lC.js → B43Eeyih.js} +1 -1
  12. package/build/client/_app/immutable/chunks/B43Eeyih.js.br +0 -0
  13. package/build/client/_app/immutable/chunks/B43Eeyih.js.gz +0 -0
  14. package/build/client/_app/immutable/chunks/{CoEFQJcr.js → B5q6rkQ-.js} +1 -1
  15. package/build/client/_app/immutable/chunks/B5q6rkQ-.js.br +0 -0
  16. package/build/client/_app/immutable/chunks/B5q6rkQ-.js.gz +0 -0
  17. package/build/client/_app/immutable/chunks/{BR7qH0F5.js → BAynhd7i.js} +1 -1
  18. package/build/client/_app/immutable/chunks/BAynhd7i.js.br +0 -0
  19. package/build/client/_app/immutable/chunks/BAynhd7i.js.gz +0 -0
  20. package/build/client/_app/immutable/chunks/{DQi7bc16.js → BDlvDAqe.js} +1 -1
  21. package/build/client/_app/immutable/chunks/BDlvDAqe.js.br +0 -0
  22. package/build/client/_app/immutable/chunks/BDlvDAqe.js.gz +0 -0
  23. package/build/client/_app/immutable/chunks/{PYzEcuyd.js → BGmgUZMc.js} +5 -5
  24. package/build/client/_app/immutable/chunks/BGmgUZMc.js.br +0 -0
  25. package/build/client/_app/immutable/chunks/BGmgUZMc.js.gz +0 -0
  26. package/build/client/_app/immutable/chunks/{DJLYkl5w.js → BJpWBbAS.js} +1 -1
  27. package/build/client/_app/immutable/chunks/BJpWBbAS.js.br +0 -0
  28. package/build/client/_app/immutable/chunks/BJpWBbAS.js.gz +0 -0
  29. package/build/client/_app/immutable/chunks/{Dp8S9ymS.js → BOT2hFMn.js} +1 -1
  30. package/build/client/_app/immutable/chunks/BOT2hFMn.js.br +0 -0
  31. package/build/client/_app/immutable/chunks/BOT2hFMn.js.gz +0 -0
  32. package/build/client/_app/immutable/chunks/{Bp63j1zN.js → BZFYtRPj.js} +1 -1
  33. package/build/client/_app/immutable/chunks/BZFYtRPj.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/BZFYtRPj.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/BjxZ_neZ.js +5 -0
  36. package/build/client/_app/immutable/chunks/BjxZ_neZ.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/BjxZ_neZ.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/{DkyYNO4U.js → BsH4MNzX.js} +1 -1
  39. package/build/client/_app/immutable/chunks/BsH4MNzX.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/BsH4MNzX.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/{DmRhEzIa.js → ByhwhtiG.js} +1 -1
  42. package/build/client/_app/immutable/chunks/ByhwhtiG.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/ByhwhtiG.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/{CDbeYGlD.js → C1lycbEF.js} +1 -1
  45. package/build/client/_app/immutable/chunks/C1lycbEF.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/C1lycbEF.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/{DslUcEd-.js → CEU4ihsz.js} +1 -1
  48. package/build/client/_app/immutable/chunks/CEU4ihsz.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/CEU4ihsz.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/{DVTgeA2y.js → CG6rRxUy.js} +1 -1
  51. package/build/client/_app/immutable/chunks/CG6rRxUy.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/CG6rRxUy.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/{AUlz4-kZ.js → CM5sQDq_.js} +1 -1
  54. package/build/client/_app/immutable/chunks/CM5sQDq_.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/CM5sQDq_.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/{UySfXNq7.js → CT_NYh_-.js} +1 -1
  57. package/build/client/_app/immutable/chunks/CT_NYh_-.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/CT_NYh_-.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/{DPKdNiYi.js → CZIk93qi.js} +1 -1
  60. package/build/client/_app/immutable/chunks/CZIk93qi.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/CZIk93qi.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/{B1t8v2wP.js → C_aXFBl3.js} +1 -1
  63. package/build/client/_app/immutable/chunks/C_aXFBl3.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/C_aXFBl3.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/CqWPu3PG.js +1 -0
  66. package/build/client/_app/immutable/chunks/CqWPu3PG.js.br +1 -0
  67. package/build/client/_app/immutable/chunks/CqWPu3PG.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/{CJFHBop_.js → CyncJW0D.js} +1 -1
  69. package/build/client/_app/immutable/chunks/CyncJW0D.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/CyncJW0D.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/{Bmk_Voz6.js → D4sC5v3c.js} +1 -1
  72. package/build/client/_app/immutable/chunks/D4sC5v3c.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/D4sC5v3c.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/{dbhDrJmm.js → D76YLq-2.js} +1 -1
  75. package/build/client/_app/immutable/chunks/D76YLq-2.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/D76YLq-2.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/{C20WvNRq.js → D8H_ivbb.js} +1 -1
  78. package/build/client/_app/immutable/chunks/D8H_ivbb.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/D8H_ivbb.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/{Di37PX72.js → DU0OQtdJ.js} +1 -1
  81. package/build/client/_app/immutable/chunks/DU0OQtdJ.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/DU0OQtdJ.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/{CYw9ugj1.js → Yk6ZJZnu.js} +1 -1
  84. package/build/client/_app/immutable/chunks/Yk6ZJZnu.js.br +0 -0
  85. package/build/client/_app/immutable/chunks/Yk6ZJZnu.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/{BwntJtbK.js → jO4fmY1N.js} +1 -1
  87. package/build/client/_app/immutable/chunks/jO4fmY1N.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/jO4fmY1N.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/{Dt_Zd6U2.js → snfmbqby.js} +1 -1
  90. package/build/client/_app/immutable/chunks/snfmbqby.js.br +0 -0
  91. package/build/client/_app/immutable/chunks/snfmbqby.js.gz +0 -0
  92. package/build/client/_app/immutable/chunks/{_Zq76xnA.js → wx-wtMGx.js} +1 -1
  93. package/build/client/_app/immutable/chunks/wx-wtMGx.js.br +0 -0
  94. package/build/client/_app/immutable/chunks/wx-wtMGx.js.gz +0 -0
  95. package/build/client/_app/immutable/chunks/{BkXArOra.js → zHL7lw4G.js} +1 -1
  96. package/build/client/_app/immutable/chunks/zHL7lw4G.js.br +0 -0
  97. package/build/client/_app/immutable/chunks/zHL7lw4G.js.gz +0 -0
  98. package/build/client/_app/immutable/entry/{app.vMZB8_Zr.js → app.DFSifnlU.js} +2 -2
  99. package/build/client/_app/immutable/entry/app.DFSifnlU.js.br +0 -0
  100. package/build/client/_app/immutable/entry/app.DFSifnlU.js.gz +0 -0
  101. package/build/client/_app/immutable/entry/start.2H5s3Lol.js +1 -0
  102. package/build/client/_app/immutable/entry/start.2H5s3Lol.js.br +1 -0
  103. package/build/client/_app/immutable/entry/start.2H5s3Lol.js.gz +0 -0
  104. package/build/client/_app/immutable/nodes/{1.zcN3R_zF.js → 1.Djdw1GzA.js} +1 -1
  105. package/build/client/_app/immutable/nodes/{1.zcN3R_zF.js.br → 1.Djdw1GzA.js.br} +0 -0
  106. package/build/client/_app/immutable/nodes/1.Djdw1GzA.js.gz +0 -0
  107. package/build/client/_app/immutable/nodes/2.CjvaJDQJ.js +4 -0
  108. package/build/client/_app/immutable/nodes/2.CjvaJDQJ.js.br +0 -0
  109. package/build/client/_app/immutable/nodes/2.CjvaJDQJ.js.gz +0 -0
  110. package/build/client/_app/version.json +1 -1
  111. package/build/client/_app/version.json.br +0 -0
  112. package/build/client/_app/version.json.gz +0 -0
  113. package/build/handler.js +4 -4
  114. package/build/index.js +4 -4
  115. package/build/server/chunks/chunks/{EventScatter.js-DqCMPeHG.js → EventScatter.js-D3Jaw_Cw.js} +7 -3
  116. package/build/server/chunks/chunks/{EventScatter.js-DqCMPeHG.js.map → EventScatter.js-D3Jaw_Cw.js.map} +1 -1
  117. package/build/server/chunks/chunks/{archive.js-C6rz09rJ.js → archive.js-C2D-5edp.js} +258 -19
  118. package/build/server/chunks/chunks/archive.js-C2D-5edp.js.map +1 -0
  119. package/build/server/chunks/chunks/{internal2.js-DDcktblR.js → internal2.js-BPo5dcDi.js} +2 -2
  120. package/build/server/chunks/chunks/{internal2.js-DDcktblR.js.map → internal2.js-BPo5dcDi.js.map} +1 -1
  121. package/build/server/chunks/chunks/{level-filter.js-H_AdNbCw.js → level-filter.js-B3o2hyWD.js} +32 -16
  122. package/build/server/chunks/chunks/level-filter.js-B3o2hyWD.js.map +1 -0
  123. package/build/server/chunks/chunks/{log-buffer.js-CpI7gyom.js → log-buffer.js-BI_gQOls.js} +118 -2
  124. package/build/server/chunks/chunks/log-buffer.js-BI_gQOls.js.map +1 -0
  125. package/build/server/chunks/chunks/series-buckets.js-BjigySff.js +290 -0
  126. package/build/server/chunks/chunks/series-buckets.js-BjigySff.js.map +1 -0
  127. package/build/server/chunks/chunks/{state.js-Dves8H8h.js → state.js-DgkwfYFo.js} +2 -2
  128. package/build/server/chunks/chunks/{state.js-Dves8H8h.js.map → state.js-DgkwfYFo.js.map} +1 -1
  129. package/build/server/chunks/entries/endpoints/api/archive/{_server.ts.js-sNd3lS0y.js → _server.ts.js-83Ch7djd.js} +3 -3
  130. package/build/server/chunks/entries/endpoints/api/archive/{_server.ts.js-sNd3lS0y.js.map → _server.ts.js-83Ch7djd.js.map} +1 -1
  131. package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-BGyWbj78.js → _server.ts.js-drLgUdvB.js} +3 -3
  132. package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-BGyWbj78.js.map → _server.ts.js-drLgUdvB.js.map} +1 -1
  133. package/build/server/chunks/entries/endpoints/api/series/{_server.ts.js-DjGMqXKo.js → _server.ts.js-DOvBhEDU.js} +39 -8
  134. package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DOvBhEDU.js.map +1 -0
  135. package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-C-XDemlx.js → _server.ts.js-BWRHawY8.js} +5 -5
  136. package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-BWRHawY8.js.map +1 -0
  137. package/build/server/chunks/entries/fallbacks/{error.svelte.js-DdUYlUJV.js → error.svelte.js-CsCL5PMW.js} +3 -3
  138. package/build/server/chunks/entries/fallbacks/{error.svelte.js-DdUYlUJV.js.map → error.svelte.js-CsCL5PMW.js.map} +1 -1
  139. package/build/server/chunks/entries/pages/{_page.svelte.js-B-kVwiNh.js → _page.svelte.js-qqtU0apo.js} +191 -28
  140. package/build/server/chunks/entries/pages/_page.svelte.js-qqtU0apo.js.map +1 -0
  141. package/build/server/chunks/{handler-BHf-eLnl.js → handler-DlfTB05m.js} +3 -3
  142. package/build/server/chunks/{handler-BHf-eLnl.js.map → handler-DlfTB05m.js.map} +1 -1
  143. package/build/server/chunks/{index.js-D6Auup1Z.js → index.js-BMrd9hfO.js} +2 -2
  144. package/build/server/chunks/{index.js-D6Auup1Z.js.map → index.js-BMrd9hfO.js.map} +1 -1
  145. package/build/server/chunks/{manifest.js-B3Q7n9I6.js → manifest.js-D1kCuVe5.js} +9 -9
  146. package/build/server/chunks/{manifest.js-B3Q7n9I6.js.map → manifest.js-D1kCuVe5.js.map} +1 -1
  147. package/build/server/chunks/nodes/{0.js-BMP_Yttt.js → 0.js-CNFDDPj5.js} +3 -3
  148. package/build/server/chunks/nodes/{0.js-BMP_Yttt.js.map → 0.js-CNFDDPj5.js.map} +1 -1
  149. package/build/server/chunks/nodes/{1.js-2HQHUOse.js → 1.js-B5FPLYnf.js} +3 -3
  150. package/build/server/chunks/nodes/{1.js-2HQHUOse.js.map → 1.js-B5FPLYnf.js.map} +1 -1
  151. package/build/server/chunks/nodes/{2.js-7RtHpiHN.js → 2.js-BEuxzw6b.js} +3 -3
  152. package/build/server/chunks/nodes/{2.js-7RtHpiHN.js.map → 2.js-BEuxzw6b.js.map} +1 -1
  153. package/dist/cli/index.js +127 -104
  154. package/dist/cli/ui.js +18 -3
  155. package/dist/lib/log-buffer.js +129 -0
  156. package/package.json +1 -1
  157. package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.br +0 -0
  158. package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.gz +0 -0
  159. package/build/client/_app/immutable/chunks/AUlz4-kZ.js.br +0 -0
  160. package/build/client/_app/immutable/chunks/AUlz4-kZ.js.gz +0 -0
  161. package/build/client/_app/immutable/chunks/B1t8v2wP.js.br +0 -0
  162. package/build/client/_app/immutable/chunks/B1t8v2wP.js.gz +0 -0
  163. package/build/client/_app/immutable/chunks/B6nyufJR.js.br +0 -0
  164. package/build/client/_app/immutable/chunks/B6nyufJR.js.gz +0 -0
  165. package/build/client/_app/immutable/chunks/BR7qH0F5.js.br +0 -0
  166. package/build/client/_app/immutable/chunks/BR7qH0F5.js.gz +0 -0
  167. package/build/client/_app/immutable/chunks/BkXArOra.js.br +0 -0
  168. package/build/client/_app/immutable/chunks/BkXArOra.js.gz +0 -0
  169. package/build/client/_app/immutable/chunks/Bmk_Voz6.js.br +0 -0
  170. package/build/client/_app/immutable/chunks/Bmk_Voz6.js.gz +0 -0
  171. package/build/client/_app/immutable/chunks/Bp63j1zN.js.br +0 -0
  172. package/build/client/_app/immutable/chunks/Bp63j1zN.js.gz +0 -0
  173. package/build/client/_app/immutable/chunks/BwntJtbK.js.br +0 -0
  174. package/build/client/_app/immutable/chunks/BwntJtbK.js.gz +0 -0
  175. package/build/client/_app/immutable/chunks/C20WvNRq.js.br +0 -0
  176. package/build/client/_app/immutable/chunks/C20WvNRq.js.gz +0 -0
  177. package/build/client/_app/immutable/chunks/CDbeYGlD.js.br +0 -0
  178. package/build/client/_app/immutable/chunks/CDbeYGlD.js.gz +0 -0
  179. package/build/client/_app/immutable/chunks/CJFHBop_.js.br +0 -0
  180. package/build/client/_app/immutable/chunks/CJFHBop_.js.gz +0 -0
  181. package/build/client/_app/immutable/chunks/CYw9ugj1.js.br +0 -0
  182. package/build/client/_app/immutable/chunks/CYw9ugj1.js.gz +0 -0
  183. package/build/client/_app/immutable/chunks/CjJd0uRB.js +0 -1
  184. package/build/client/_app/immutable/chunks/CjJd0uRB.js.br +0 -1
  185. package/build/client/_app/immutable/chunks/CjJd0uRB.js.gz +0 -0
  186. package/build/client/_app/immutable/chunks/CoEFQJcr.js.br +0 -0
  187. package/build/client/_app/immutable/chunks/CoEFQJcr.js.gz +0 -0
  188. package/build/client/_app/immutable/chunks/D-JtVVAo.js.br +0 -0
  189. package/build/client/_app/immutable/chunks/D-JtVVAo.js.gz +0 -0
  190. package/build/client/_app/immutable/chunks/DJDlf6lC.js.br +0 -0
  191. package/build/client/_app/immutable/chunks/DJDlf6lC.js.gz +0 -0
  192. package/build/client/_app/immutable/chunks/DJLYkl5w.js.br +0 -0
  193. package/build/client/_app/immutable/chunks/DJLYkl5w.js.gz +0 -0
  194. package/build/client/_app/immutable/chunks/DPKdNiYi.js.br +0 -0
  195. package/build/client/_app/immutable/chunks/DPKdNiYi.js.gz +0 -0
  196. package/build/client/_app/immutable/chunks/DQi7bc16.js.br +0 -0
  197. package/build/client/_app/immutable/chunks/DQi7bc16.js.gz +0 -0
  198. package/build/client/_app/immutable/chunks/DVTgeA2y.js.br +0 -0
  199. package/build/client/_app/immutable/chunks/DVTgeA2y.js.gz +0 -0
  200. package/build/client/_app/immutable/chunks/Di37PX72.js.br +0 -0
  201. package/build/client/_app/immutable/chunks/Di37PX72.js.gz +0 -0
  202. package/build/client/_app/immutable/chunks/DkyYNO4U.js.br +0 -0
  203. package/build/client/_app/immutable/chunks/DkyYNO4U.js.gz +0 -0
  204. package/build/client/_app/immutable/chunks/DmRhEzIa.js.br +0 -0
  205. package/build/client/_app/immutable/chunks/DmRhEzIa.js.gz +0 -0
  206. package/build/client/_app/immutable/chunks/Dp8S9ymS.js.br +0 -0
  207. package/build/client/_app/immutable/chunks/Dp8S9ymS.js.gz +0 -0
  208. package/build/client/_app/immutable/chunks/DslUcEd-.js.br +0 -0
  209. package/build/client/_app/immutable/chunks/DslUcEd-.js.gz +0 -0
  210. package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.br +0 -0
  211. package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.gz +0 -0
  212. package/build/client/_app/immutable/chunks/DwezeuNE.js +0 -5
  213. package/build/client/_app/immutable/chunks/DwezeuNE.js.br +0 -0
  214. package/build/client/_app/immutable/chunks/DwezeuNE.js.gz +0 -0
  215. package/build/client/_app/immutable/chunks/PYzEcuyd.js.br +0 -0
  216. package/build/client/_app/immutable/chunks/PYzEcuyd.js.gz +0 -0
  217. package/build/client/_app/immutable/chunks/UySfXNq7.js.br +0 -0
  218. package/build/client/_app/immutable/chunks/UySfXNq7.js.gz +0 -0
  219. package/build/client/_app/immutable/chunks/_Zq76xnA.js.br +0 -0
  220. package/build/client/_app/immutable/chunks/_Zq76xnA.js.gz +0 -0
  221. package/build/client/_app/immutable/chunks/dbhDrJmm.js.br +0 -0
  222. package/build/client/_app/immutable/chunks/dbhDrJmm.js.gz +0 -0
  223. package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.br +0 -0
  224. package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.gz +0 -0
  225. package/build/client/_app/immutable/entry/start.pM5lNk_5.js +0 -1
  226. package/build/client/_app/immutable/entry/start.pM5lNk_5.js.br +0 -0
  227. package/build/client/_app/immutable/entry/start.pM5lNk_5.js.gz +0 -0
  228. package/build/client/_app/immutable/nodes/1.zcN3R_zF.js.gz +0 -0
  229. package/build/client/_app/immutable/nodes/2.DxevVqut.js +0 -2
  230. package/build/client/_app/immutable/nodes/2.DxevVqut.js.br +0 -0
  231. package/build/client/_app/immutable/nodes/2.DxevVqut.js.gz +0 -0
  232. package/build/server/chunks/chunks/archive.js-C6rz09rJ.js.map +0 -1
  233. package/build/server/chunks/chunks/level-filter.js-H_AdNbCw.js.map +0 -1
  234. package/build/server/chunks/chunks/log-buffer.js-CpI7gyom.js.map +0 -1
  235. package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js +0 -123
  236. package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js.map +0 -1
  237. package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DjGMqXKo.js.map +0 -1
  238. package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-C-XDemlx.js.map +0 -1
  239. package/build/server/chunks/entries/pages/_page.svelte.js-B-kVwiNh.js.map +0 -1
  240. /package/build/client/_app/immutable/nodes/{0.CZO0sIxX.js → 0.BN3NguWs.js} +0 -0
  241. /package/build/client/_app/immutable/nodes/{0.CZO0sIxX.js.br → 0.BN3NguWs.js.br} +0 -0
  242. /package/build/client/_app/immutable/nodes/{0.CZO0sIxX.js.gz → 0.BN3NguWs.js.gz} +0 -0
@@ -1,14 +1,14 @@
1
1
  import { ah as escape_html, ag as attr, ai as attr_style, ac as derived, aj as attr_class, ak as ensure_array_like, al as stringify, am as bind_props, an as clsx } from '../../chunks/server.js-CAEBuMIH.js';
2
- import { L as LogStore, t as tokenizeJson, f as filterByLevel, b as filterEvents, e as effectiveLevel, a as detectLevel, c as formatLogMessage, g as eventKey, l as levelColorClass } from '../../chunks/log-buffer.js-CpI7gyom.js';
2
+ import { c as LogStore, f as filterByLevel, g as filterEvents, e as effectiveLevel, t as tokenizeJson, b as detectLevel, h as formatLogMessage, j as eventKey, l as levelColorClass } from '../../chunks/log-buffer.js-BI_gQOls.js';
3
3
  import { R as REGION_CODES } from '../../chunks/regions.js-IQPMyP5C.js';
4
4
  import { P as PRESET_LABELS, a as presetLabel, H as HISTORIC_PRESETS, t as toDateTimeLocal, d as describeWindow } from '../../chunks/time-range.js-BLMT8aU3.js';
5
- import { p as page, r as replaceState } from '../../chunks/state.js-Dves8H8h.js';
6
- import { S as SERIES_LEVEL_COLOR, g as groupByLevel, i as isMeaningfulBrush, b as bucketEvents } from '../../chunks/series-buckets.js-CX_rWCeH.js';
5
+ import { p as page, r as replaceState } from '../../chunks/state.js-DgkwfYFo.js';
6
+ import { S as SERIES_LEVEL_COLOR, g as groupByLevel, r as requestRows, L as LEVEL_LABELS, i as isMeaningfulBrush, b as bucketEvents } from '../../chunks/series-buckets.js-BjigySff.js';
7
7
  import '../../chunks/uneval.js-DaakSYFQ.js';
8
8
  import '../../chunks/index-server.js-DNLOKvM0.js';
9
9
  import '../../chunks/shared.js-CgjUIvRK.js';
10
10
  import '../../chunks/exports.js-ClPPfcHj.js';
11
- import '../../chunks/internal2.js-DDcktblR.js';
11
+ import '../../chunks/internal2.js-BPo5dcDi.js';
12
12
  import '../../chunks/legacy-client.js-DJmDw3Zx.js';
13
13
  import '../../chunks/utils.js-BIlHjgGW.js';
14
14
 
@@ -46,6 +46,25 @@ function trimZero(value) {
46
46
  return fixed.endsWith(".0") ? fixed.slice(0, -2) : fixed;
47
47
  }
48
48
  /**
49
+ * Formats a duration as `250ms`, `1.2s`, `2m 5s` or `1h 2m`, for a request's span.
50
+ * Sub-second spans keep a millisecond value, because that is what a slow request
51
+ * is measured in; longer spans stop at the first two units a reader needs.
52
+ */
53
+ function formatSpan(ms) {
54
+ if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) return "—";
55
+ const total = Math.round(ms);
56
+ if (total < 1e3) return `${total}ms`;
57
+ const seconds = total / 1e3;
58
+ if (seconds < 60) return `${trimZero(seconds)}s`;
59
+ const wholeSeconds = Math.floor(seconds);
60
+ const minutes = Math.floor(wholeSeconds / 60);
61
+ const restSeconds = wholeSeconds % 60;
62
+ if (minutes < 60) return restSeconds === 0 ? `${minutes}m` : `${minutes}m ${restSeconds}s`;
63
+ const hours = Math.floor(minutes / 60);
64
+ const restMinutes = minutes % 60;
65
+ return restMinutes === 0 ? `${hours}h` : `${hours}h ${restMinutes}m`;
66
+ }
67
+ /**
49
68
  * Formats a byte count as `B`, `KiB`, `MiB` or `GiB`, with at most one decimal for scaled units.
50
69
  * Returns {@link EMPTY_VALUE} for a missing or negative value.
51
70
  */
@@ -143,7 +162,8 @@ var STORAGE_KEYS = {
143
162
  prefixWidth: "watch-stream:prefix-width",
144
163
  wrap: "watch-stream:wrap",
145
164
  jsonView: "watch-stream:json-view",
146
- chartOpen: "watch-stream:chart-open"
165
+ chartOpen: "watch-stream:chart-open",
166
+ groupRequests: "watch-stream:group-requests"
147
167
  };
148
168
  /** Default width of the group-list pane, in rem (matches the original layout). */
149
169
  var SIDEBAR_WIDTH = {
@@ -187,18 +207,19 @@ function EventScatterPanel($$renderer, $$props) {
187
207
  * The real loader: a dynamic import, which is what keeps layerchart out of the
188
208
  * initial bundle. It only runs in the browser, and only once the panel is open.
189
209
  */
190
- const loadChartModule = () => import('../../chunks/EventScatter.js-DqCMPeHG.js');
210
+ const loadChartModule = () => import('../../chunks/EventScatter.js-D3Jaw_Cw.js');
191
211
  /** Bucketed counts for the window. */
192
212
  /** Inclusive start of the window, epoch ms. */
193
213
  /** Inclusive end of the window, epoch ms. */
194
214
  /** Bucket width in ms, shown in the summary. */
195
215
  /** Log groups the points cover, for the summary. */
216
+ /** True when one mark stands for one request rather than one line. */
196
217
  /** True while the counts are being fetched. */
197
218
  /** Called with the brushed range when the drag ends, or `null` on clear. */
198
219
  /** Chart height in px. */
199
220
  /** Start open, which is also what the first visit uses. */
200
221
  /** Chart module loader; defaults to the dynamic import. */
201
- let { points = [], from = 0, to = 0, bucketMs = 0, groups = [], loading = false, onBrush, height = 200, open = true, loadChart = loadChartModule } = $$props;
222
+ let { points = [], from = 0, to = 0, bucketMs = 0, groups = [], loading = false, byRequest = true, onBrush, height = 200, open = true, loadChart = loadChartModule } = $$props;
202
223
  let expanded = derived(() => open);
203
224
  /** Totals and labels per level, in severity order. */
204
225
  let levelGroups = derived(() => groupByLevel(points));
@@ -208,11 +229,14 @@ function EventScatterPanel($$renderer, $$props) {
208
229
  let bucketCount = derived(() => new Set(points.map((point) => point.t)).size);
209
230
  /** True when there is something to draw. */
210
231
  let hasPoints = derived(() => points.length > 0);
232
+ /** What one mark stands for, which is what the totals count. */
233
+ let unit = derived(() => byRequest ? "requests" : "events");
211
234
  /** Clears the brush, for the host's Reset zoom control. */
212
235
  function reset() {
213
236
  onBrush?.(null);
214
237
  }
215
- $$renderer.push(`<section class="flex min-w-0 flex-col gap-1 rounded-lg border border-neutral-800 bg-neutral-950/60 p-2" data-testid="event-scatter" aria-label="Events over time"><div class="flex flex-wrap items-center gap-x-3 gap-y-1 px-1 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 rounded-md border border-neutral-800 bg-neutral-900 px-2 py-0.5 font-semibold uppercase tracking-wider text-neutral-400 transition-colors hover:border-neutral-700 hover:text-neutral-200"><span aria-hidden="true">${escape_html(expanded() ? "▾" : "▸")}</span> Events over time</button> <span class="text-neutral-400" data-testid="scatter-summary">${escape_html(formatCount(totalEvents()))} events in ${escape_html(formatCount(bucketCount()))} buckets</span> `);
238
+ $$renderer.push(`<section class="flex min-w-0 flex-col gap-1 rounded-lg border border-neutral-800 bg-neutral-950/60 p-2" data-testid="event-scatter" aria-label="Events over time"><div class="flex flex-wrap items-center gap-x-3 gap-y-1 px-1 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 rounded-md border border-neutral-800 bg-neutral-900 px-2 py-0.5 font-semibold uppercase tracking-wider text-neutral-400 transition-colors hover:border-neutral-700 hover:text-neutral-200"><span aria-hidden="true">${escape_html(expanded() ? "▾" : "▸")}</span> Events over time</button> <span class="text-neutral-400" data-testid="scatter-summary">${escape_html(formatCount(totalEvents()))}
239
+ ${escape_html(unit())} in ${escape_html(formatCount(bucketCount()))} buckets</span> `);
216
240
  if (groups.length > 1) $$renderer.push(`<!--[0--><span class="text-neutral-500" data-testid="scatter-groups">across ${escape_html(groups.length)} groups</span>`);
217
241
  else $$renderer.push("<!--[-1-->");
218
242
  $$renderer.push(`<!--]--> <!--[-->`);
@@ -353,6 +377,7 @@ function buildSeriesUrl(query) {
353
377
  if (typeof query.to === "number" && Number.isFinite(query.to)) search.set("to", String(Math.round(query.to)));
354
378
  const levels = (query.levels ?? []).filter((level) => level.length > 0);
355
379
  if (levels.length > 0) search.set("level", levels.join(","));
380
+ if (query.by === "request" || query.by === "event") search.set("by", query.by);
356
381
  if (typeof query.bucketMs === "number" && Number.isFinite(query.bucketMs) && query.bucketMs > 0) search.set("bucket", String(Math.round(query.bucketMs)));
357
382
  return `/api/series?${search.toString()}`;
358
383
  }
@@ -587,7 +612,12 @@ function LogViewer($$renderer, $$props) {
587
612
  * the chart above stays in step with the chips.
588
613
  */
589
614
  /** Called when the level filter changes while it is controlled. */
590
- let { 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, onFilterChange, onPauseToggle, onClear, onAutoScrollToggle } = $$props;
615
+ /**
616
+ * Group lines that share a request id into one row, opened on demand. On by
617
+ * default, and owned by the page so the chart counts the same requests.
618
+ */
619
+ /** Called when the grouping toggle is pressed. */
620
+ let { 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, onFilterChange, onPauseToggle, onClear, onAutoScrollToggle } = $$props;
591
621
  const TIMESTAMP_COLUMN_PX = remToPx(7.5);
592
622
  const ROW_PADDING_PX = remToPx(.75);
593
623
  const ROW_GAP_PX = remToPx(.5);
@@ -656,8 +686,8 @@ function LogViewer($$renderer, $$props) {
656
686
  }
657
687
  return counts;
658
688
  });
659
- /** Presentation rows for the visible lines. */
660
- let rows = derived(() => visible().map((event, index) => {
689
+ /** Presentation rows for the visible lines, one per line in buffer order. */
690
+ let lineRows = derived(() => visible().map((event, index) => {
661
691
  const rowLevel = event.level !== void 0 ? event.level : detectLevel(event.message);
662
692
  const formatted = formatLogMessage(event.message, { prettyJson: jsonView });
663
693
  const levelClass = levelColorClass(rowLevel);
@@ -674,6 +704,87 @@ function LogViewer($$renderer, $$props) {
674
704
  levelClass
675
705
  };
676
706
  }));
707
+ /**
708
+ * One row of the list: a line, or a request that holds its lines.
709
+ *
710
+ * A request row carries everything the header shows, so the template stays
711
+ * declarative and the list never re-formats a line it already formatted.
712
+ */
713
+ /** Request id every line in the group carries. */
714
+ /** Clock time of the first line, and its full timestamp for the tooltip. */
715
+ /** Number of lines in the group. */
716
+ /** First to last line, as `1.2s`. */
717
+ /** Most critical level in the group. */
718
+ /** Log group and stream, when every line in the request shares them. */
719
+ /** Worst line, trimmed to one short line for the collapsed row. */
720
+ /** Longest preview kept for a collapsed request, in characters. */
721
+ const PREVIEW_LENGTH = 160;
722
+ /** Prefixes a formatted line row with its kind. */
723
+ function asLine(row) {
724
+ return {
725
+ kind: "line",
726
+ ...row
727
+ };
728
+ }
729
+ /** Builds the request header row from the lines it holds. */
730
+ function requestDisplayRow(row) {
731
+ const children = row.request.events.map((entry) => lineRows()[entry.index]).filter((child) => child !== void 0);
732
+ const worstLevel = row.request.level;
733
+ const first = children[0];
734
+ return {
735
+ kind: "request",
736
+ key: row.key,
737
+ id: row.request.id,
738
+ time: first?.time ?? "",
739
+ timestamp: first?.timestamp ?? "",
740
+ count: children.length,
741
+ span: formatSpan(row.request.last - row.request.first),
742
+ level: worstLevel,
743
+ levelLabel: LEVEL_LABELS[worstLevel],
744
+ levelClass: levelColorClass(worstLevel === "unknown" ? null : worstLevel),
745
+ group: sharedField(children.map((child) => child.group)),
746
+ streamName: sharedField(children.map((child) => child.streamName)),
747
+ preview: requestPreview(row.request),
748
+ children
749
+ };
750
+ }
751
+ /** The value every entry shares, or `null` when they differ. */
752
+ function sharedField(values) {
753
+ const first = values[0];
754
+ if (first === null || first === void 0) return null;
755
+ return values.every((value) => value === first) ? first : null;
756
+ }
757
+ /**
758
+ * One short line for a collapsed request: its most critical line, because that
759
+ * is the line that explains why the request is coloured the way it is.
760
+ */
761
+ function requestPreview(request) {
762
+ const worst = request.events.find((entry) => effectiveLevel(visible()[entry.index] ?? { message: "" }) === request.level) ?? request.events[0];
763
+ const [firstLine = ""] = (visible()[worst?.index ?? -1]?.message ?? "").split("\n");
764
+ return firstLine.replace(/\s+/g, " ").trim().slice(0, PREVIEW_LENGTH);
765
+ }
766
+ /** Rows the list renders: grouped by request when the preference is on. */
767
+ let displayRows = derived(() => {
768
+ if (!groupRequests) return lineRows().map(asLine);
769
+ const rows = [];
770
+ for (const row of requestRows(visible())) {
771
+ if (row.kind === "line") {
772
+ rows.push(asLine(lineRows()[row.index]));
773
+ continue;
774
+ }
775
+ if (row.request.events.length === 1) {
776
+ const only = lineRows()[row.request.events[0]?.index ?? -1];
777
+ if (only !== void 0) rows.push(asLine(only));
778
+ continue;
779
+ }
780
+ rows.push(requestDisplayRow(row));
781
+ }
782
+ return rows;
783
+ });
784
+ /** True when the list is showing request rows. */
785
+ let grouped = derived(() => displayRows().some((row) => row.kind === "request"));
786
+ /** Requests in view, shown next to the line count while grouping. */
787
+ let requestCount = derived(() => displayRows().filter((row) => row.kind === "request").length);
677
788
  /** Keeps the newest line in view while auto-scroll is on (vertical only). */
678
789
  /** Error text with the group and region context. */
679
790
  let errorText = derived(() => error === null ? null : describeStreamError(region, group, error.message));
@@ -698,6 +809,8 @@ function LogViewer($$renderer, $$props) {
698
809
  let wrapTone = derived(() => "text-neutral-400");
699
810
  /** JSON toggle colour. */
700
811
  let jsonTone = derived(() => "text-sky-300");
812
+ /** Grouping toggle colour. */
813
+ let groupTone = derived(() => groupRequests ? "text-sky-300" : "text-neutral-400");
701
814
  /** Rows fill the window when wrapping, and grow to their content otherwise. */
702
815
  let listClass = derived(() => "w-max min-w-full");
703
816
  /** Message cell: wrapped text or a single long line that scrolls sideways. */
@@ -733,7 +846,10 @@ function LogViewer($$renderer, $$props) {
733
846
  $$renderer.push(`<!----> `);
734
847
  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>`);
735
848
  else $$renderer.push("<!--[-1-->");
736
- $$renderer.push(`<!--]--> <span class="text-xs text-neutral-400" data-testid="visible-count">${escape_html(formatCount(visible().length))} shown</span> <span class="text-xs text-neutral-500" data-testid="received-count">${escape_html(formatCount(receivedCount))} received</span> `);
849
+ $$renderer.push(`<!--]--> <span class="text-xs text-neutral-400" data-testid="visible-count">${escape_html(formatCount(visible().length))} shown</span> `);
850
+ if (grouped()) $$renderer.push(`<!--[0--><span class="text-xs text-neutral-400" data-testid="request-count">${escape_html(formatCount(requestCount()))} requests</span>`);
851
+ else $$renderer.push("<!--[-1-->");
852
+ $$renderer.push(`<!--]--> <span class="text-xs text-neutral-500" data-testid="received-count">${escape_html(formatCount(receivedCount))} received</span> `);
737
853
  if (pendingCount > 0) $$renderer.push(`<!--[0--><span class="text-xs text-amber-300" data-testid="pending-count">${escape_html(formatCount(pendingCount))} buffered</span>`);
738
854
  else $$renderer.push("<!--[-1-->");
739
855
  $$renderer.push(`<!--]--> `);
@@ -754,20 +870,18 @@ function LogViewer($$renderer, $$props) {
754
870
  else $$renderer.push("<!--[-1-->");
755
871
  $$renderer.push(`<!--]--></button>`);
756
872
  }
757
- $$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", 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> `);
873
+ $$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> `);
758
874
  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>`);
759
875
  else $$renderer.push("<!--[-1-->");
760
876
  $$renderer.push(`<!--]--> <div class="min-h-0 min-w-0 flex-1 overflow-auto bg-neutral-950" data-testid="log-scroller">`);
761
877
  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>`);
762
- else if (rows().length === 0) $$renderer.push(`<!--[1--><p class="px-3 py-6 text-sm text-neutral-500" data-testid="viewer-empty">${escape_html(emptyText())}</p>`);
878
+ 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>`);
763
879
  else {
764
- $$renderer.push(`<!--[-1--><div${attr_class(`relative min-h-full ${listClass()}`)} data-testid="log-canvas"><ol class="font-mono text-xs leading-5" data-testid="log-lines"><!--[-->`);
765
- const each_array_1 = ensure_array_like(rows());
766
- for (let $$index_3 = 0, $$length = each_array_1.length; $$index_3 < $$length; $$index_3++) {
767
- let row = each_array_1[$$index_3];
880
+ $$renderer.push("<!--[-1-->");
881
+ function logLine($$renderer, row, child) {
768
882
  const expandable = row.expandable !== null;
769
883
  const open = expandable && isExpanded(row.key);
770
- $$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" : ""}`)} data-testid="log-line"${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="w-[7.5rem] shrink-0 text-neutral-500"${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
884
+ $$renderer.push(`<li${attr_class(`flex flex-wrap items-baseline gap-2 ${child ? "pl-8" : "px-3"} py-0.5 hover:bg-neutral-900/60 ${listClass()} ${expandable ? "cursor-pointer" : ""}`)} data-testid="log-line"${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="w-[7.5rem] shrink-0 text-neutral-500"${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
771
885
  if (groups.length > 1) $$renderer.push(`<!--[0--><span class="w-[9rem] shrink-0 truncate text-teal-400/80"${attr("title", row.group ?? "")} data-testid="log-group">${escape_html(row.group ?? "")}</span>`);
772
886
  else $$renderer.push("<!--[-1-->");
773
887
  $$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> `);
@@ -776,9 +890,9 @@ function LogViewer($$renderer, $$props) {
776
890
  $$renderer.push(`<!--]--> <span${attr_class(`${messageClass()} ${stringify(row.levelClass)}`)} data-testid="log-message">`);
777
891
  if (row.tokens !== null) {
778
892
  $$renderer.push(`<!--[0--><!--[-->`);
779
- const each_array_2 = ensure_array_like(row.tokens);
780
- for (let tokenIndex = 0, $$length = each_array_2.length; tokenIndex < $$length; tokenIndex++) {
781
- let token = each_array_2[tokenIndex];
893
+ const each_array_1 = ensure_array_like(row.tokens);
894
+ for (let tokenIndex = 0, $$length = each_array_1.length; tokenIndex < $$length; tokenIndex++) {
895
+ let token = each_array_1[tokenIndex];
782
896
  $$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
783
897
  }
784
898
  $$renderer.push(`<!--]-->`);
@@ -786,15 +900,45 @@ function LogViewer($$renderer, $$props) {
786
900
  $$renderer.push(`<!--]--></span> `);
787
901
  if (open && row.expandable !== null) {
788
902
  $$renderer.push(`<!--[0--><span class="w-full whitespace-pre text-xs text-neutral-300" data-testid="log-json-expanded"><!--[-->`);
789
- const each_array_3 = ensure_array_like(tokenizeJson(row.expandable));
790
- for (let tokenIndex = 0, $$length = each_array_3.length; tokenIndex < $$length; tokenIndex++) {
791
- let token = each_array_3[tokenIndex];
903
+ const each_array_2 = ensure_array_like(tokenizeJson(row.expandable));
904
+ for (let tokenIndex = 0, $$length = each_array_2.length; tokenIndex < $$length; tokenIndex++) {
905
+ let token = each_array_2[tokenIndex];
792
906
  $$renderer.push(`<span${attr_class(clsx(tokenClass(token.type)))}>${escape_html(token.text)}</span>`);
793
907
  }
794
908
  $$renderer.push(`<!--]--></span>`);
795
909
  } else $$renderer.push("<!--[-1-->");
796
910
  $$renderer.push(`<!--]--></li>`);
797
911
  }
912
+ $$renderer.push(`<div${attr_class(`relative min-h-full ${listClass()}`)} data-testid="log-canvas"><ol class="font-mono text-xs leading-5" data-testid="log-lines"><!--[-->`);
913
+ const each_array_3 = ensure_array_like(displayRows());
914
+ for (let $$index_4 = 0, $$length = each_array_3.length; $$index_4 < $$length; $$index_4++) {
915
+ let row = each_array_3[$$index_4];
916
+ if (row.kind === "request") {
917
+ $$renderer.push("<!--[0-->");
918
+ const open = isExpanded(row.key);
919
+ $$renderer.push(`<li${attr_class(clsx(listClass()))} data-testid="log-request-group"${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="w-[7.5rem] shrink-0 text-neutral-500"${attr("title", row.timestamp)}>${escape_html(row.time)}</span> `);
920
+ if (groups.length > 1) $$renderer.push(`<!--[0--><span class="w-[9rem] shrink-0 truncate text-teal-400/80"${attr("title", row.group ?? "")} data-testid="log-group">${escape_html(row.group ?? "")}</span>`);
921
+ else $$renderer.push("<!--[-1-->");
922
+ $$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> <span class="shrink-0 text-neutral-600" aria-hidden="true">${escape_html(open ? "▾" : "▸")}</span> <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> `);
923
+ if (!open) $$renderer.push(`<!--[0--><span class="min-w-0 truncate text-neutral-500" data-testid="request-group-preview">${escape_html(row.preview)}</span>`);
924
+ else $$renderer.push("<!--[-1-->");
925
+ $$renderer.push(`<!--]--></button> `);
926
+ if (open) {
927
+ $$renderer.push(`<!--[0--><ul class="contents"><!--[-->`);
928
+ const each_array_4 = ensure_array_like(row.children);
929
+ for (let $$index_3 = 0, $$length = each_array_4.length; $$index_3 < $$length; $$index_3++) {
930
+ let child = each_array_4[$$index_3];
931
+ logLine($$renderer, child, true);
932
+ }
933
+ $$renderer.push(`<!--]--></ul>`);
934
+ } else $$renderer.push("<!--[-1-->");
935
+ $$renderer.push(`<!--]--></li>`);
936
+ } else {
937
+ $$renderer.push("<!--[-1-->");
938
+ logLine($$renderer, row, false);
939
+ }
940
+ $$renderer.push(`<!--]-->`);
941
+ }
798
942
  $$renderer.push(`<!--]--></ol> `);
799
943
  ColumnResizer($$renderer, {
800
944
  label: "Resize prefix column",
@@ -1142,6 +1286,13 @@ function _page($$renderer, $$props) {
1142
1286
  let selectedGroup = derived(() => selectedGroups[0] ?? null);
1143
1287
  /** Level filter shared by the log view and the chart. */
1144
1288
  let levelFilter = null;
1289
+ /**
1290
+ * Group lines by request id, in the log view and in the chart.
1291
+ *
1292
+ * On by default: an incident is read as requests, not as the lines they wrote.
1293
+ * A stored preference wins, so a reader who wants every line keeps every line.
1294
+ */
1295
+ let groupRequests = true;
1145
1296
  /** Bucketed counts behind the chart. */
1146
1297
  let seriesPoints = [];
1147
1298
  /** True while the archive counts are being fetched. */
@@ -1250,6 +1401,13 @@ function _page($$renderer, $$props) {
1250
1401
  to: selection.to
1251
1402
  });
1252
1403
  }
1404
+ /** Turns request grouping on or off, and remembers the choice. */
1405
+ function toggleGroupRequests() {
1406
+ groupRequests = !groupRequests;
1407
+ try {
1408
+ localStorage?.setItem(STORAGE_KEYS.groupRequests, groupRequests ? "true" : "false");
1409
+ } catch {}
1410
+ }
1253
1411
  /** Switches region: stops the stream, clears the list and reloads the groups. */
1254
1412
  function changeRegion(next) {
1255
1413
  if (next === "" || next === region) return;
@@ -1355,7 +1513,8 @@ function _page($$renderer, $$props) {
1355
1513
  to,
1356
1514
  bucketMs: chartBucketMs(from, to),
1357
1515
  level: levelFilter,
1358
- fallbackGroup: selectedGroup() ?? ""
1516
+ fallbackGroup: selectedGroup() ?? "",
1517
+ byRequest: groupRequests
1359
1518
  });
1360
1519
  return;
1361
1520
  }
@@ -1366,7 +1525,8 @@ function _page($$renderer, $$props) {
1366
1525
  groups: selectedGroups,
1367
1526
  from,
1368
1527
  to,
1369
- levels: levelFilter === null ? [] : [levelFilter]
1528
+ levels: levelFilter === null ? [] : [levelFilter],
1529
+ by: groupRequests ? "request" : "event"
1370
1530
  })).points;
1371
1531
  } catch {
1372
1532
  seriesPoints = [];
@@ -1439,6 +1599,7 @@ function _page($$renderer, $$props) {
1439
1599
  to: chartWindow().to,
1440
1600
  bucketMs: chartBucketMs(chartWindow().from, chartWindow().to),
1441
1601
  groups: selectedGroups,
1602
+ byRequest: groupRequests,
1442
1603
  loading: seriesLoading,
1443
1604
  onBrush: applyBrush
1444
1605
  });
@@ -1459,6 +1620,8 @@ function _page($$renderer, $$props) {
1459
1620
  groups: selectedGroups,
1460
1621
  level: levelFilter,
1461
1622
  onLevelChange: (next) => levelFilter = next,
1623
+ groupRequests,
1624
+ onGroupToggle: toggleGroupRequests,
1462
1625
  filter,
1463
1626
  paused: stream.paused,
1464
1627
  autoScroll,
@@ -1475,4 +1638,4 @@ function _page($$renderer, $$props) {
1475
1638
  }
1476
1639
 
1477
1640
  export { _page as default };
1478
- //# sourceMappingURL=_page.svelte.js-B-kVwiNh.js.map
1641
+ //# sourceMappingURL=_page.svelte.js-qqtU0apo.js.map