watch-tail 0.3.1 → 0.5.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 (382) hide show
  1. package/README.md +157 -3
  2. package/build/client/_app/immutable/assets/0.BQQ1YLPc.css +2 -0
  3. package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css +1 -0
  6. package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.br +0 -0
  7. package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css +1 -0
  9. package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.br +0 -0
  10. package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css +1 -0
  12. package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.br +1 -0
  13. package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css +1 -0
  15. package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.br +0 -0
  16. package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css +1 -0
  18. package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css.br +0 -0
  19. package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/Labels.sEaJtb97.css +1 -0
  21. package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.br +0 -0
  22. package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.gz +0 -0
  23. package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css +1 -0
  24. package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.br +0 -0
  25. package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.gz +0 -0
  26. package/build/client/_app/immutable/assets/Path.B0wDzTrn.css +1 -0
  27. package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.br +0 -0
  28. package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.gz +0 -0
  29. package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css +1 -0
  30. package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.br +0 -0
  31. package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.gz +0 -0
  32. package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css +1 -0
  33. package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.br +0 -0
  34. package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.gz +0 -0
  35. package/build/client/_app/immutable/chunks/AUlz4-kZ.js +1 -0
  36. package/build/client/_app/immutable/chunks/AUlz4-kZ.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/AUlz4-kZ.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/B1t8v2wP.js +1 -0
  39. package/build/client/_app/immutable/chunks/B1t8v2wP.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/B1t8v2wP.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/B6nyufJR.js +1 -0
  42. package/build/client/_app/immutable/chunks/B6nyufJR.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/B6nyufJR.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/BR2LaRms.js +1 -0
  45. package/build/client/_app/immutable/chunks/BR2LaRms.js.br +1 -0
  46. package/build/client/_app/immutable/chunks/BR2LaRms.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/BR7qH0F5.js +1 -0
  48. package/build/client/_app/immutable/chunks/BR7qH0F5.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/BR7qH0F5.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/BkXArOra.js +1 -0
  51. package/build/client/_app/immutable/chunks/BkXArOra.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/BkXArOra.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/Bl052uUt.js +1 -0
  54. package/build/client/_app/immutable/chunks/Bl052uUt.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/Bl052uUt.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/Bmk_Voz6.js +1 -0
  57. package/build/client/_app/immutable/chunks/Bmk_Voz6.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/Bmk_Voz6.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/Bp63j1zN.js +1 -0
  60. package/build/client/_app/immutable/chunks/Bp63j1zN.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/Bp63j1zN.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/BwntJtbK.js +1 -0
  63. package/build/client/_app/immutable/chunks/BwntJtbK.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/BwntJtbK.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/C20WvNRq.js +1 -0
  66. package/build/client/_app/immutable/chunks/C20WvNRq.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/C20WvNRq.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/C58PZtCD.js +4 -0
  69. package/build/client/_app/immutable/chunks/C58PZtCD.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/C58PZtCD.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/CCch3uox.js +1 -0
  72. package/build/client/_app/immutable/chunks/CCch3uox.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/CCch3uox.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/CDbeYGlD.js +1 -0
  75. package/build/client/_app/immutable/chunks/CDbeYGlD.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/CDbeYGlD.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/CJFHBop_.js +1 -0
  78. package/build/client/_app/immutable/chunks/CJFHBop_.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/CJFHBop_.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/CYw9ugj1.js +1 -0
  81. package/build/client/_app/immutable/chunks/CYw9ugj1.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/CYw9ugj1.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/CjJd0uRB.js +1 -0
  84. package/build/client/_app/immutable/chunks/CjJd0uRB.js.br +1 -0
  85. package/build/client/_app/immutable/chunks/CjJd0uRB.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/CoEFQJcr.js +1 -0
  87. package/build/client/_app/immutable/chunks/CoEFQJcr.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/CoEFQJcr.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/D-JtVVAo.js +1 -0
  90. package/build/client/_app/immutable/chunks/D-JtVVAo.js.br +0 -0
  91. package/build/client/_app/immutable/chunks/D-JtVVAo.js.gz +0 -0
  92. package/build/client/_app/immutable/chunks/DJDlf6lC.js +1 -0
  93. package/build/client/_app/immutable/chunks/DJDlf6lC.js.br +0 -0
  94. package/build/client/_app/immutable/chunks/DJDlf6lC.js.gz +0 -0
  95. package/build/client/_app/immutable/chunks/DJLYkl5w.js +1 -0
  96. package/build/client/_app/immutable/chunks/DJLYkl5w.js.br +0 -0
  97. package/build/client/_app/immutable/chunks/DJLYkl5w.js.gz +0 -0
  98. package/build/client/_app/immutable/chunks/DPKdNiYi.js +1 -0
  99. package/build/client/_app/immutable/chunks/DPKdNiYi.js.br +0 -0
  100. package/build/client/_app/immutable/chunks/DPKdNiYi.js.gz +0 -0
  101. package/build/client/_app/immutable/chunks/DQi7bc16.js +1 -0
  102. package/build/client/_app/immutable/chunks/DQi7bc16.js.br +0 -0
  103. package/build/client/_app/immutable/chunks/DQi7bc16.js.gz +0 -0
  104. package/build/client/_app/immutable/chunks/DVTgeA2y.js +2 -0
  105. package/build/client/_app/immutable/chunks/DVTgeA2y.js.br +0 -0
  106. package/build/client/_app/immutable/chunks/DVTgeA2y.js.gz +0 -0
  107. package/build/client/_app/immutable/chunks/Db0q5_zr.js +1 -0
  108. package/build/client/_app/immutable/chunks/Db0q5_zr.js.br +0 -0
  109. package/build/client/_app/immutable/chunks/Db0q5_zr.js.gz +0 -0
  110. package/build/client/_app/immutable/chunks/Dfvzj6n2.js +1 -0
  111. package/build/client/_app/immutable/chunks/Dfvzj6n2.js.br +0 -0
  112. package/build/client/_app/immutable/chunks/Dfvzj6n2.js.gz +0 -0
  113. package/build/client/_app/immutable/chunks/Di37PX72.js +1 -0
  114. package/build/client/_app/immutable/chunks/Di37PX72.js.br +0 -0
  115. package/build/client/_app/immutable/chunks/Di37PX72.js.gz +0 -0
  116. package/build/client/_app/immutable/chunks/{DyIYFD7i.js → DkyYNO4U.js} +1 -1
  117. package/build/client/_app/immutable/chunks/DkyYNO4U.js.br +0 -0
  118. package/build/client/_app/immutable/chunks/DkyYNO4U.js.gz +0 -0
  119. package/build/client/_app/immutable/chunks/DmRhEzIa.js +1 -0
  120. package/build/client/_app/immutable/chunks/DmRhEzIa.js.br +0 -0
  121. package/build/client/_app/immutable/chunks/DmRhEzIa.js.gz +0 -0
  122. package/build/client/_app/immutable/chunks/Dp8S9ymS.js +1 -0
  123. package/build/client/_app/immutable/chunks/Dp8S9ymS.js.br +0 -0
  124. package/build/client/_app/immutable/chunks/Dp8S9ymS.js.gz +0 -0
  125. package/build/client/_app/immutable/chunks/DslUcEd-.js +1 -0
  126. package/build/client/_app/immutable/chunks/DslUcEd-.js.br +0 -0
  127. package/build/client/_app/immutable/chunks/DslUcEd-.js.gz +0 -0
  128. package/build/client/_app/immutable/chunks/Dt_Zd6U2.js +1 -0
  129. package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.br +0 -0
  130. package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.gz +0 -0
  131. package/build/client/_app/immutable/chunks/DwezeuNE.js +5 -0
  132. package/build/client/_app/immutable/chunks/DwezeuNE.js.br +0 -0
  133. package/build/client/_app/immutable/chunks/DwezeuNE.js.gz +0 -0
  134. package/build/client/_app/immutable/chunks/HclGiUj8.js +1 -0
  135. package/build/client/_app/immutable/chunks/HclGiUj8.js.br +0 -0
  136. package/build/client/_app/immutable/chunks/HclGiUj8.js.gz +0 -0
  137. package/build/client/_app/immutable/chunks/PYzEcuyd.js +10 -0
  138. package/build/client/_app/immutable/chunks/PYzEcuyd.js.br +0 -0
  139. package/build/client/_app/immutable/chunks/PYzEcuyd.js.gz +0 -0
  140. package/build/client/_app/immutable/chunks/RobXhXPM.js +1 -0
  141. package/build/client/_app/immutable/chunks/RobXhXPM.js.br +1 -0
  142. package/build/client/_app/immutable/chunks/RobXhXPM.js.gz +0 -0
  143. package/build/client/_app/immutable/chunks/UySfXNq7.js +1 -0
  144. package/build/client/_app/immutable/chunks/UySfXNq7.js.br +0 -0
  145. package/build/client/_app/immutable/chunks/UySfXNq7.js.gz +0 -0
  146. package/build/client/_app/immutable/chunks/Y5urAfNy.js +1 -0
  147. package/build/client/_app/immutable/chunks/Y5urAfNy.js.br +0 -0
  148. package/build/client/_app/immutable/chunks/Y5urAfNy.js.gz +0 -0
  149. package/build/client/_app/immutable/chunks/_Zq76xnA.js +15 -0
  150. package/build/client/_app/immutable/chunks/_Zq76xnA.js.br +0 -0
  151. package/build/client/_app/immutable/chunks/_Zq76xnA.js.gz +0 -0
  152. package/build/client/_app/immutable/chunks/dbhDrJmm.js +1 -0
  153. package/build/client/_app/immutable/chunks/dbhDrJmm.js.br +0 -0
  154. package/build/client/_app/immutable/chunks/dbhDrJmm.js.gz +0 -0
  155. package/build/client/_app/immutable/chunks/pqiPC7Y8.js +3 -0
  156. package/build/client/_app/immutable/chunks/pqiPC7Y8.js.br +0 -0
  157. package/build/client/_app/immutable/chunks/pqiPC7Y8.js.gz +0 -0
  158. package/build/client/_app/immutable/chunks/yCfI4PCa.js +1 -0
  159. package/build/client/_app/immutable/chunks/yCfI4PCa.js.br +0 -0
  160. package/build/client/_app/immutable/chunks/yCfI4PCa.js.gz +0 -0
  161. package/build/client/_app/immutable/entry/app.vMZB8_Zr.js +2 -0
  162. package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.br +0 -0
  163. package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.gz +0 -0
  164. package/build/client/_app/immutable/entry/start.pM5lNk_5.js +1 -0
  165. package/build/client/_app/immutable/entry/start.pM5lNk_5.js.br +0 -0
  166. package/build/client/_app/immutable/entry/start.pM5lNk_5.js.gz +0 -0
  167. package/build/client/_app/immutable/nodes/0.CZO0sIxX.js +1 -0
  168. package/build/client/_app/immutable/nodes/0.CZO0sIxX.js.br +0 -0
  169. package/build/client/_app/immutable/nodes/0.CZO0sIxX.js.gz +0 -0
  170. package/build/client/_app/immutable/nodes/1.zcN3R_zF.js +1 -0
  171. package/build/client/_app/immutable/nodes/1.zcN3R_zF.js.br +0 -0
  172. package/build/client/_app/immutable/nodes/1.zcN3R_zF.js.gz +0 -0
  173. package/build/client/_app/immutable/nodes/2.DxevVqut.js +2 -0
  174. package/build/client/_app/immutable/nodes/2.DxevVqut.js.br +0 -0
  175. package/build/client/_app/immutable/nodes/2.DxevVqut.js.gz +0 -0
  176. package/build/client/_app/version.json +1 -1
  177. package/build/client/_app/version.json.br +0 -0
  178. package/build/client/_app/version.json.gz +0 -0
  179. package/build/handler.js +9 -7
  180. package/build/handler.js.map +1 -1
  181. package/build/index.js +9 -7
  182. package/build/index.js.map +1 -1
  183. package/build/server/chunks/chunks/Arc.canvas.js-D6g58nSp.js +701 -0
  184. package/build/server/chunks/chunks/Arc.canvas.js-D6g58nSp.js.map +1 -0
  185. package/build/server/chunks/chunks/Arc.js-D78Cf_4M.js +31 -0
  186. package/build/server/chunks/chunks/Arc.js-D78Cf_4M.js.map +1 -0
  187. package/build/server/chunks/chunks/Bar.js-Cv73T8_D.js +448 -0
  188. package/build/server/chunks/chunks/Bar.js-Cv73T8_D.js.map +1 -0
  189. package/build/server/chunks/chunks/ChartAnnotations.js-Ci22VB_6.js +983 -0
  190. package/build/server/chunks/chunks/ChartAnnotations.js-Ci22VB_6.js.map +1 -0
  191. package/build/server/chunks/chunks/Circle.html.js-BjwyNRG3.js +355 -0
  192. package/build/server/chunks/chunks/Circle.html.js-BjwyNRG3.js.map +1 -0
  193. package/build/server/chunks/chunks/ClipPath.canvas.js-CFTBDWVU.js +170 -0
  194. package/build/server/chunks/chunks/ClipPath.canvas.js-CFTBDWVU.js.map +1 -0
  195. package/build/server/chunks/chunks/DefaultTooltip.js-0r5rbE-1.js +352 -0
  196. package/build/server/chunks/chunks/DefaultTooltip.js-0r5rbE-1.js.map +1 -0
  197. package/build/server/chunks/chunks/EventScatter.js-DqCMPeHG.js +7304 -0
  198. package/build/server/chunks/chunks/EventScatter.js-DqCMPeHG.js.map +1 -0
  199. package/build/server/chunks/chunks/Labels.js-DpagpV6d.js +497 -0
  200. package/build/server/chunks/chunks/Labels.js-DpagpV6d.js.map +1 -0
  201. package/build/server/chunks/chunks/Legend.js-BOpwpe5s.js +343 -0
  202. package/build/server/chunks/chunks/Legend.js-BOpwpe5s.js.map +1 -0
  203. package/build/server/chunks/chunks/Line.html.js-BM5tR11G.js +423 -0
  204. package/build/server/chunks/chunks/Line.html.js-BM5tR11G.js.map +1 -0
  205. package/build/server/chunks/chunks/Link.canvas.js-P8ySzEAw.js +756 -0
  206. package/build/server/chunks/chunks/Link.canvas.js-P8ySzEAw.js.map +1 -0
  207. package/build/server/chunks/chunks/Path.canvas.js-DNAtnEBt.js +1259 -0
  208. package/build/server/chunks/chunks/Path.canvas.js-DNAtnEBt.js.map +1 -0
  209. package/build/server/chunks/chunks/Points.html.js-CLbHD6OP.js +228 -0
  210. package/build/server/chunks/chunks/Points.html.js-CLbHD6OP.js.map +1 -0
  211. package/build/server/chunks/chunks/Points.js-e6g0Re6H.js +14 -0
  212. package/build/server/chunks/chunks/Points.js-e6g0Re6H.js.map +1 -0
  213. package/build/server/chunks/chunks/Points2.js-BMGdkzTE.js +25 -0
  214. package/build/server/chunks/chunks/Points2.js-BMGdkzTE.js.map +1 -0
  215. package/build/server/chunks/chunks/Rect.html.js-Q3UvRwNn.js +547 -0
  216. package/build/server/chunks/chunks/Rect.html.js-Q3UvRwNn.js.map +1 -0
  217. package/build/server/chunks/chunks/Spline.js-BuZPz2PJ.js +516 -0
  218. package/build/server/chunks/chunks/Spline.js-BuZPz2PJ.js.map +1 -0
  219. package/build/server/chunks/chunks/Text.html.js-C8xO5Nz6.js +847 -0
  220. package/build/server/chunks/chunks/Text.html.js-C8xO5Nz6.js.map +1 -0
  221. package/build/server/chunks/chunks/TooltipItem.js-T0cKLjLu.js +314 -0
  222. package/build/server/chunks/chunks/TooltipItem.js-T0cKLjLu.js.map +1 -0
  223. package/build/server/chunks/chunks/Voronoi.js-DevTsXQE.js +2052 -0
  224. package/build/server/chunks/chunks/Voronoi.js-DevTsXQE.js.map +1 -0
  225. package/build/server/chunks/chunks/archive.js-C6rz09rJ.js +584 -0
  226. package/build/server/chunks/chunks/archive.js-C6rz09rJ.js.map +1 -0
  227. package/build/server/chunks/chunks/array.js-CBp0H4t3.js +8 -0
  228. package/build/server/chunks/chunks/array.js-CBp0H4t3.js.map +1 -0
  229. package/build/server/chunks/chunks/attributes.js-BVWo7wbg.js +25 -0
  230. package/build/server/chunks/chunks/attributes.js-BVWo7wbg.js.map +1 -0
  231. package/build/server/chunks/chunks/{env2.js-D7xrfc37.js → aws.js-DkPqAybc.js} +13 -64
  232. package/build/server/chunks/chunks/aws.js-DkPqAybc.js.map +1 -0
  233. package/build/server/chunks/chunks/band.js-C7izXphE.js +155 -0
  234. package/build/server/chunks/chunks/band.js-C7izXphE.js.map +1 -0
  235. package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js +1356 -0
  236. package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js.map +1 -0
  237. package/build/server/chunks/chunks/common.js-BWQB8Die.js +5760 -0
  238. package/build/server/chunks/chunks/common.js-BWQB8Die.js.map +1 -0
  239. package/build/server/chunks/chunks/env2.js-CcIskxOZ.js +60 -0
  240. package/build/server/chunks/chunks/env2.js-CcIskxOZ.js.map +1 -0
  241. package/build/server/chunks/chunks/{exports.js-CvFPPbaH.js → exports.js-ClPPfcHj.js} +6 -1
  242. package/build/server/chunks/chunks/exports.js-ClPPfcHj.js.map +1 -0
  243. package/build/server/chunks/chunks/group.js-DBFzWAox.js +30 -0
  244. package/build/server/chunks/chunks/group.js-DBFzWAox.js.map +1 -0
  245. package/build/server/chunks/chunks/index-server.js-DNLOKvM0.js +248 -0
  246. package/build/server/chunks/chunks/index-server.js-DNLOKvM0.js.map +1 -0
  247. package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js +2 -0
  248. package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js.map +1 -0
  249. package/build/server/chunks/chunks/{internal2.js-DZ8ZzzjN.js → internal.js-DZ8ZzzjN.js} +1 -1
  250. package/build/server/chunks/chunks/internal.js-DZ8ZzzjN.js.map +1 -0
  251. package/build/server/chunks/chunks/internal2.js-DDcktblR.js +188 -0
  252. package/build/server/chunks/chunks/internal2.js-DDcktblR.js.map +1 -0
  253. package/build/server/chunks/chunks/key.svelte.js-CWIvXc6L.js +695 -0
  254. package/build/server/chunks/chunks/key.svelte.js-CWIvXc6L.js.map +1 -0
  255. package/build/server/chunks/chunks/{internal.js-B-DZpK-L.js → legacy-client.js-DJmDw3Zx.js} +13 -439
  256. package/build/server/chunks/chunks/legacy-client.js-DJmDw3Zx.js.map +1 -0
  257. package/build/server/chunks/chunks/level-filter.js-H_AdNbCw.js +297 -0
  258. package/build/server/chunks/chunks/level-filter.js-H_AdNbCw.js.map +1 -0
  259. package/build/server/chunks/chunks/lineRadial.js-Dm0GMqo3.js +126 -0
  260. package/build/server/chunks/chunks/lineRadial.js-Dm0GMqo3.js.map +1 -0
  261. package/build/server/chunks/chunks/linear.js-CTOKrHn9.js +1046 -0
  262. package/build/server/chunks/chunks/linear.js-CTOKrHn9.js.map +1 -0
  263. package/build/server/chunks/chunks/log-buffer.js-CpI7gyom.js +471 -0
  264. package/build/server/chunks/chunks/log-buffer.js-CpI7gyom.js.map +1 -0
  265. package/build/server/chunks/chunks/math.js-BqujbaBs.js +50 -0
  266. package/build/server/chunks/chunks/math.js-BqujbaBs.js.map +1 -0
  267. package/build/server/chunks/chunks/max.js-CuS0BpRI.js +11 -0
  268. package/build/server/chunks/chunks/max.js-CuS0BpRI.js.map +1 -0
  269. package/build/server/chunks/chunks/min.js-DZWt5tPl.js +11 -0
  270. package/build/server/chunks/chunks/min.js-DZWt5tPl.js.map +1 -0
  271. package/build/server/chunks/chunks/motion.svelte.js-DCHSFMu-.js +677 -0
  272. package/build/server/chunks/chunks/motion.svelte.js-DCHSFMu-.js.map +1 -0
  273. package/build/server/chunks/chunks/occlusion.js-DJ-AdK9u.js +33 -0
  274. package/build/server/chunks/chunks/occlusion.js-DJ-AdK9u.js.map +1 -0
  275. package/build/server/chunks/chunks/path.js-BizMrlzb.js +488 -0
  276. package/build/server/chunks/chunks/path.js-BizMrlzb.js.map +1 -0
  277. package/build/server/chunks/chunks/path2.js-pquT2Kg6.js +27 -0
  278. package/build/server/chunks/chunks/path2.js-pquT2Kg6.js.map +1 -0
  279. package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js +7 -0
  280. package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js.map +1 -0
  281. package/build/server/chunks/chunks/rect.svelte.js-zeS7FWjB.js +187 -0
  282. package/build/server/chunks/chunks/rect.svelte.js-zeS7FWjB.js.map +1 -0
  283. package/build/server/chunks/chunks/scales.svelte.js-D_1popPi.js +276 -0
  284. package/build/server/chunks/chunks/scales.svelte.js-D_1popPi.js.map +1 -0
  285. package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js +123 -0
  286. package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js.map +1 -0
  287. package/build/server/chunks/chunks/{server.js-ByNB8uti.js → server.js-CAEBuMIH.js} +167 -2
  288. package/build/server/chunks/chunks/server.js-CAEBuMIH.js.map +1 -0
  289. package/build/server/chunks/chunks/source.js-DZEVvuho.js +21 -0
  290. package/build/server/chunks/chunks/source.js-DZEVvuho.js.map +1 -0
  291. package/build/server/chunks/chunks/{state.js-V2NYGhy_.js → state.js-Dves8H8h.js} +5 -4
  292. package/build/server/chunks/chunks/state.js-Dves8H8h.js.map +1 -0
  293. package/build/server/chunks/chunks/types.js-x3GyGPOz.js +11 -0
  294. package/build/server/chunks/chunks/types.js-x3GyGPOz.js.map +1 -0
  295. package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-sNd3lS0y.js +39 -0
  296. package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-sNd3lS0y.js.map +1 -0
  297. package/build/server/chunks/entries/endpoints/api/health/{_server.ts.js-aiNZfkco.js → _server.ts.js-VctnBhIJ.js} +5 -3
  298. package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-VctnBhIJ.js.map +1 -0
  299. package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-Dt540Sio.js +73 -0
  300. package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-Dt540Sio.js.map +1 -0
  301. package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-D143-vRl.js → _server.ts.js-BGyWbj78.js} +57 -7
  302. package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-BGyWbj78.js.map +1 -0
  303. package/build/server/chunks/entries/endpoints/api/regions/{_server.ts.js-CDNL7msU.js → _server.ts.js-CBqfN6Pg.js} +5 -3
  304. package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-CBqfN6Pg.js.map +1 -0
  305. package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DjGMqXKo.js +194 -0
  306. package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DjGMqXKo.js.map +1 -0
  307. package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-D_i-xW6_.js → _server.ts.js-C-XDemlx.js} +324 -222
  308. package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-C-XDemlx.js.map +1 -0
  309. package/build/server/chunks/entries/fallbacks/{error.svelte.js-CAasf3PF.js → error.svelte.js-DdUYlUJV.js} +7 -5
  310. package/build/server/chunks/entries/fallbacks/{error.svelte.js-CAasf3PF.js.map → error.svelte.js-DdUYlUJV.js.map} +1 -1
  311. package/build/server/chunks/entries/pages/_layout.svelte.js-CBQpEToy.js +22 -0
  312. package/build/server/chunks/entries/pages/_layout.svelte.js-CBQpEToy.js.map +1 -0
  313. package/build/server/chunks/entries/pages/{_page.svelte.js-DzAAqWz2.js → _page.svelte.js-B-kVwiNh.js} +563 -349
  314. package/build/server/chunks/entries/pages/_page.svelte.js-B-kVwiNh.js.map +1 -0
  315. package/build/server/chunks/{handler-CuWqZDuC.js → handler-BHf-eLnl.js} +3 -3
  316. package/build/server/chunks/{handler-CuWqZDuC.js.map → handler-BHf-eLnl.js.map} +1 -1
  317. package/build/server/chunks/{index.js-NHTL74z2.js → index.js-D6Auup1Z.js} +6 -5
  318. package/build/server/chunks/index.js-D6Auup1Z.js.map +1 -0
  319. package/build/server/chunks/manifest.js-B3Q7n9I6.js +91 -0
  320. package/build/server/chunks/manifest.js-B3Q7n9I6.js.map +1 -0
  321. package/build/server/chunks/nodes/0.js-BMP_Yttt.js +9 -0
  322. package/build/server/chunks/nodes/{0.js-Bg4_hDjk.js.map → 0.js-BMP_Yttt.js.map} +1 -1
  323. package/build/server/chunks/nodes/1.js-2HQHUOse.js +9 -0
  324. package/build/server/chunks/nodes/{1.js-CDSk3TvW.js.map → 1.js-2HQHUOse.js.map} +1 -1
  325. package/build/server/chunks/nodes/2.js-7RtHpiHN.js +9 -0
  326. package/build/server/chunks/nodes/2.js-7RtHpiHN.js.map +1 -0
  327. package/dist/cli/completions.js +6 -0
  328. package/dist/cli/index.js +149 -30
  329. package/dist/cli/options.js +28 -2
  330. package/dist/cli/preflight.js +72 -0
  331. package/dist/cli/ui.js +7 -3
  332. package/dist/lib/cli/aws.js +12 -4
  333. package/dist/lib/log-buffer.js +314 -0
  334. package/dist/lib/log-format.js +185 -0
  335. package/dist/lib/types.js +0 -4
  336. package/package.json +7 -2
  337. package/build/client/_app/immutable/assets/0.CocWI5K4.css +0 -2
  338. package/build/client/_app/immutable/assets/0.CocWI5K4.css.br +0 -0
  339. package/build/client/_app/immutable/assets/0.CocWI5K4.css.gz +0 -0
  340. package/build/client/_app/immutable/chunks/05WsiB4A.js +0 -1
  341. package/build/client/_app/immutable/chunks/05WsiB4A.js.br +0 -0
  342. package/build/client/_app/immutable/chunks/05WsiB4A.js.gz +0 -0
  343. package/build/client/_app/immutable/chunks/DyIYFD7i.js.br +0 -0
  344. package/build/client/_app/immutable/chunks/DyIYFD7i.js.gz +0 -0
  345. package/build/client/_app/immutable/chunks/ZAD2y5xJ.js +0 -3
  346. package/build/client/_app/immutable/chunks/ZAD2y5xJ.js.br +0 -0
  347. package/build/client/_app/immutable/chunks/ZAD2y5xJ.js.gz +0 -0
  348. package/build/client/_app/immutable/entry/app.D0_YFW4X.js +0 -2
  349. package/build/client/_app/immutable/entry/app.D0_YFW4X.js.br +0 -0
  350. package/build/client/_app/immutable/entry/app.D0_YFW4X.js.gz +0 -0
  351. package/build/client/_app/immutable/entry/start.D1rrHrg2.js +0 -1
  352. package/build/client/_app/immutable/entry/start.D1rrHrg2.js.br +0 -0
  353. package/build/client/_app/immutable/entry/start.D1rrHrg2.js.gz +0 -0
  354. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js +0 -1
  355. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js.br +0 -0
  356. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js.gz +0 -0
  357. package/build/client/_app/immutable/nodes/1.D1vhnOgO.js +0 -1
  358. package/build/client/_app/immutable/nodes/1.D1vhnOgO.js.br +0 -0
  359. package/build/client/_app/immutable/nodes/1.D1vhnOgO.js.gz +0 -0
  360. package/build/client/_app/immutable/nodes/2.BPdL6B7F.js +0 -5
  361. package/build/client/_app/immutable/nodes/2.BPdL6B7F.js.br +0 -0
  362. package/build/client/_app/immutable/nodes/2.BPdL6B7F.js.gz +0 -0
  363. package/build/server/chunks/chunks/env2.js-D7xrfc37.js.map +0 -1
  364. package/build/server/chunks/chunks/exports.js-CvFPPbaH.js.map +0 -1
  365. package/build/server/chunks/chunks/internal.js-B-DZpK-L.js.map +0 -1
  366. package/build/server/chunks/chunks/internal2.js-DZ8ZzzjN.js.map +0 -1
  367. package/build/server/chunks/chunks/server.js-ByNB8uti.js.map +0 -1
  368. package/build/server/chunks/chunks/state.js-V2NYGhy_.js.map +0 -1
  369. package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-aiNZfkco.js.map +0 -1
  370. package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-D143-vRl.js.map +0 -1
  371. package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-CDNL7msU.js.map +0 -1
  372. package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-D_i-xW6_.js.map +0 -1
  373. package/build/server/chunks/entries/pages/_layout.svelte.js-Bx7lXkAi.js +0 -22
  374. package/build/server/chunks/entries/pages/_layout.svelte.js-Bx7lXkAi.js.map +0 -1
  375. package/build/server/chunks/entries/pages/_page.svelte.js-DzAAqWz2.js.map +0 -1
  376. package/build/server/chunks/index.js-NHTL74z2.js.map +0 -1
  377. package/build/server/chunks/manifest.js-8g4gjxwf.js +0 -70
  378. package/build/server/chunks/manifest.js-8g4gjxwf.js.map +0 -1
  379. package/build/server/chunks/nodes/0.js-Bg4_hDjk.js +0 -9
  380. package/build/server/chunks/nodes/1.js-CDSk3TvW.js +0 -9
  381. package/build/server/chunks/nodes/2.js-BVhBcWrN.js +0 -9
  382. package/build/server/chunks/nodes/2.js-BVhBcWrN.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts.js-DjGMqXKo.js","sources":["../../../../../../../.svelte-kit/output/server/entries/endpoints/api/series/_server.ts.js"],"sourcesContent":["import { t as getArchive } from \"../../../../chunks/archive.js\";\nimport { t as readEnv } from \"../../../../chunks/env2.js\";\nimport { l as apiError, n as REGION_PARAM_HINT, o as parseRegionParam, s as resolveAwsConfig } from \"../../../../chunks/aws.js\";\nimport { n as parseSourceParam, t as SOURCE_PARAM_HINT } from \"../../../../chunks/source.js\";\nimport { i as parseGroupParams, n as parseLevelParam, o as parseDurationMs, s as resolveWindow, t as LEVEL_PARAM_HINT } from \"../../../../chunks/level-filter.js\";\nimport { json } from \"@sveltejs/kit\";\n//#region src/lib/server/series.ts\n/** Message used when a caller asks for a series the app cannot aggregate. */\nvar SERIES_SOURCE_HINT = \"Series are only aggregated for source=archive; a live CloudWatch view buckets the events it has loaded\";\n/** Bucket widths offered to an automatic window, smallest first. */\nvar BUCKET_LADDER = [\n\t1e3,\n\t5e3,\n\t1e4,\n\t3e4,\n\t6e4,\n\t3e5,\n\t9e5,\n\t18e5,\n\t36e5,\n\t108e5,\n\t216e5,\n\t432e5,\n\t864e5,\n\t6048e5\n];\n/** Bounds on an explicit bucket width. */\nvar MIN_BUCKET_MS = 1e3;\nvar MAX_BUCKET_MS = 6048e5;\n/**\n* Picks a bucket width for a window.\n*\n* The smallest ladder step that keeps the number of buckets at or below\n* {@link TARGET_BUCKETS} wins, so a fifteen-minute window is bucketed in seconds\n* and a week in hours, and the axis never renders thousands of ticks.\n*/\nfunction chooseBucketMs(windowMs, target = 90) {\n\tconst span = Number.isFinite(windowMs) && windowMs > 0 ? windowMs : 6e4;\n\tconst wanted = Math.max(1, Math.round(target));\n\tfor (const step of BUCKET_LADDER) if (span / step <= wanted) return step;\n\treturn BUCKET_LADDER.at(-1);\n}\n/**\n* Reads an explicit `bucket` parameter.\n*\n* Accepts a duration (`30s`, `5m`, `2h`) or plain milliseconds, and returns\n* `null` for anything unusable so the caller falls back to an automatic width.\n* The result is clamped to {@link MIN_BUCKET_MS}..{@link MAX_BUCKET_MS}.\n*/\nfunction parseBucketParam(value) {\n\tif (typeof value !== \"string\") return null;\n\tconst trimmed = value.trim();\n\tif (trimmed.length === 0) return null;\n\tconst ms = /^\\d+$/.test(trimmed) ? Number(trimmed) : parseDurationMs(trimmed);\n\tif (ms === null || !Number.isFinite(ms) || ms <= 0) return null;\n\treturn Math.min(Math.max(Math.round(ms), MIN_BUCKET_MS), MAX_BUCKET_MS);\n}\n/** Sums rows per level, in a fixed severity order. */\nfunction summariseLevels(points) {\n\tconst order = [\n\t\t\"error\",\n\t\t\"warn\",\n\t\t\"info\",\n\t\t\"debug\",\n\t\t\"unknown\"\n\t];\n\tconst totals = /* @__PURE__ */ new Map();\n\tfor (const point of points) totals.set(point.level, (totals.get(point.level) ?? 0) + point.events);\n\treturn order.filter((level) => totals.has(level)).map((level) => ({\n\t\tlevel,\n\t\tevents: totals.get(level)\n\t}));\n}\n/** Sums rows per group, busiest first. */\nfunction summariseGroups(points) {\n\tconst totals = /* @__PURE__ */ new Map();\n\tfor (const point of points) totals.set(point.group, (totals.get(point.group) ?? 0) + point.events);\n\treturn [...totals.entries()].map(([group, events]) => ({\n\t\tgroup,\n\t\tevents\n\t})).toSorted((a, b) => b.events === a.events ? a.group.localeCompare(b.group) : b.events - a.events);\n}\n/** Builds the response body from raw bucket rows. */\nfunction buildSeriesResponse(input) {\n\tconst points = input.rows.map((row) => ({\n\t\tt: row.t,\n\t\tgroup: row.group,\n\t\tlevel: row.level,\n\t\tevents: row.events\n\t}));\n\treturn {\n\t\tfrom: input.from,\n\t\tto: input.to,\n\t\tbucketMs: input.bucketMs,\n\t\tlevels: summariseLevels(points),\n\t\tgroups: summariseGroups(points),\n\t\tpoints,\n\t\ttotals: {\n\t\t\tevents: points.reduce((sum, point) => sum + point.events, 0),\n\t\t\tpoints: points.length\n\t\t}\n\t};\n}\n/**\n* Reads the archived counts for a window.\n*\n* An unavailable archive answers an empty series rather than an error, so the\n* chart can show \"nothing archived yet\" instead of a failure.\n*/\nasync function readSeries(input) {\n\tconst bucketMs = input.bucketMs ?? chooseBucketMs(input.to - input.from);\n\tconst empty = buildSeriesResponse({\n\t\tfrom: input.from,\n\t\tto: input.to,\n\t\tbucketMs,\n\t\trows: []\n\t});\n\tif (!input.archive.available) return empty;\n\tconst rows = await input.archive.seriesQuery({\n\t\tregion: input.region,\n\t\tlogGroups: input.logGroups,\n\t\tstartTime: input.from,\n\t\tendTime: input.to,\n\t\tbucketMs,\n\t\tlevels: input.levels ?? null\n\t});\n\treturn buildSeriesResponse({\n\t\tfrom: input.from,\n\t\tto: input.to,\n\t\tbucketMs,\n\t\trows\n\t});\n}\n//#endregion\n//#region src/routes/api/series/+server.ts\n/**\n* `GET /api/series` - event counts per time bucket, per group and level.\n*\n* This is the chart's data. Only the archive can answer it: DuckDB counts a\n* whole window in one statement, while CloudWatch Logs has no aggregate API, so\n* the UI buckets the events it already streamed for a live or CloudWatch view.\n*\n* The window is not clamped to CloudWatch's 14 days, because the archive keeps\n* what CloudWatch has already dropped.\n*/\nvar GET = async ({ url }) => {\n\tconst parsedRegion = parseRegionParam(url.searchParams.get(\"region\"));\n\tif (!parsedRegion.ok) return apiError(400, REGION_PARAM_HINT, \"invalid-region\");\n\tconst source = parseSourceParam(url.searchParams.get(\"source\"));\n\tif (source === null) return apiError(400, SOURCE_PARAM_HINT, \"invalid-source\");\n\tif (source !== \"archive\") return apiError(400, SERIES_SOURCE_HINT, \"unsupported-source\");\n\tconst groups = parseGroupParams(url.searchParams.get(\"group\"), url.searchParams.get(\"groups\"));\n\tif (!groups.ok) return apiError(400, groups.message, groups.code);\n\tconst levels = parseLevelParam(url.searchParams.get(\"level\"));\n\tif (levels === void 0) return apiError(400, LEVEL_PARAM_HINT, \"invalid-level\");\n\tconst env = readEnv();\n\tconst region = resolveAwsConfig(env, parsedRegion.region).region ?? \"\";\n\tif (region === \"\") return apiError(400, \"Query parameter \\\"region\\\" is required when source=archive\", \"missing-region-param\");\n\tconst window = resolveWindow({\n\t\tmode: \"historic\",\n\t\trange: url.searchParams.get(\"range\"),\n\t\tfrom: url.searchParams.get(\"from\"),\n\t\tto: url.searchParams.get(\"to\"),\n\t\tnow: Date.now()\n\t}, { maxLookbackMs: null });\n\tif (!window.ok) return apiError(400, window.message, window.code);\n\tconst endTime = window.endTime ?? Date.now();\n\tconst series = await readSeries({\n\t\tarchive: await getArchive(env),\n\t\tregion,\n\t\tlogGroups: groups.names,\n\t\tfrom: window.startTime,\n\t\tto: endTime,\n\t\tlevels,\n\t\tbucketMs: parseBucketParam(url.searchParams.get(\"bucket\"))\n\t});\n\treturn json(series);\n};\n//#endregion\nexport { GET };\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAMA;AACA;AACA,IAAI,kBAAkB,GAAG,wGAAwG;AACjI;AACA,IAAI,aAAa,GAAG;AACpB,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,GAAG;AACJ,CAAC,IAAI;AACL,CAAC,IAAI;AACL,CAAC,KAAK;AACN,CAAC,KAAK;AACN,CAAC,KAAK;AACN,CAAC,KAAK;AACN,CAAC;AACD,CAAC;AACD;AACA,IAAI,aAAa,GAAG,GAAG;AACvB,IAAI,aAAa,GAAG,MAAM;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,EAAE;AAC/C,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,GAAG,QAAQ,GAAG,GAAG;AACxE,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,EAAE,OAAO,IAAI;AACzE,CAAC,OAAO,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,KAAK,EAAE;AACjC,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,IAAI;AAC3C,CAAC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE;AAC7B,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI;AACtC,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC;AAC9E,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,IAAI;AAChE,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC;AACxE;AACA;AACA,SAAS,eAAe,CAAC,MAAM,EAAE;AACjC,CAAC,MAAM,KAAK,GAAG;AACf,EAAE,OAAO;AACT,EAAE,MAAM;AACR,EAAE,MAAM;AACR,EAAE,OAAO;AACT,EAAE;AACF,EAAE;AACF,CAAC,MAAM,MAAM,mBAAmB,IAAI,GAAG,EAAE;AACzC,CAAC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;AACnG,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AACnE,EAAE,KAAK;AACP,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK;AAC1B,EAAE,CAAC,CAAC;AACJ;AACA;AACA,SAAS,eAAe,CAAC,MAAM,EAAE;AACjC,CAAC,MAAM,MAAM,mBAAmB,IAAI,GAAG,EAAE;AACzC,CAAC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;AACnG,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM;AACxD,EAAE,KAAK;AACP,EAAE;AACF,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;AACrG;AACA;AACA,SAAS,mBAAmB,CAAC,KAAK,EAAE;AACpC,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;AACzC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACV,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK;AAClB,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK;AAClB,EAAE,MAAM,EAAE,GAAG,CAAC;AACd,EAAE,CAAC,CAAC;AACJ,CAAC,OAAO;AACR,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI;AAClB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE;AACd,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ;AAC1B,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;AACjC,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;AACjC,EAAE,MAAM;AACR,EAAE,MAAM,EAAE;AACV,GAAG,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/D,GAAG,MAAM,EAAE,MAAM,CAAC;AAClB;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU,CAAC,KAAK,EAAE;AACjC,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;AACzE,CAAC,MAAM,KAAK,GAAG,mBAAmB,CAAC;AACnC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI;AAClB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE;AACd,EAAE,QAAQ;AACV,EAAE,IAAI,EAAE;AACR,EAAE,CAAC;AACH,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,KAAK;AAC3C,CAAC,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;AAC9C,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM;AACtB,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS;AAC5B,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI;AACvB,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE;AACnB,EAAE,QAAQ;AACV,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI;AAC1B,EAAE,CAAC;AACH,CAAC,OAAO,mBAAmB,CAAC;AAC5B,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI;AAClB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE;AACd,EAAE,QAAQ;AACV,EAAE;AACF,EAAE,CAAC;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG,IAAC,GAAG,GAAG,OAAO,EAAE,GAAG,EAAE,KAAK;AAC7B,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACtE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;AAChF,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAChE,CAAC,IAAI,MAAM,KAAK,IAAI,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;AAC/E,CAAC,IAAI,MAAM,KAAK,SAAS,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,kBAAkB,EAAE,oBAAoB,CAAC;AACzF,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/F,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC;AAClE,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC,IAAI,MAAM,KAAK,MAAM,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,gBAAgB,EAAE,eAAe,CAAC;AAC/E,CAAC,MAAM,GAAG,GAAG,OAAO,EAAE;AACtB,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,MAAM,IAAI,EAAE;AACvE,CAAC,IAAI,MAAM,KAAK,EAAE,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,4DAA4D,EAAE,sBAAsB,CAAC;AAC9H,CAAC,MAAM,MAAM,GAAG,aAAa,CAAC;AAC9B,EAAE,IAAI,EAAE,UAAU;AAClB,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;AACtC,EAAE,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;AACpC,EAAE,EAAE,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAChC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG;AACf,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC;AAClE,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE;AAC7C,CAAC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;AACjC,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC;AAChC,EAAE,MAAM;AACR,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK;AACzB,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS;AACxB,EAAE,EAAE,EAAE,OAAO;AACb,EAAE,MAAM;AACR,EAAE,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC3D,EAAE,CAAC;AACH,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC;AACpB;;"}
@@ -1,208 +1,169 @@
1
- import { a as apiError, p as parseRegionParam, b as readEnv, r as resolveAwsConfig, c as createLogsClient, d as resolveEffectiveRegion, e as describeAwsError, R as REGION_PARAM_HINT } from '../../../../chunks/env2.js-D7xrfc37.js';
2
- import { H as HISTORIC_PRESETS, p as presetDurationMs, i as isHistoricPreset } from '../../../../chunks/time-range.js-BLMT8aU3.js';
1
+ import { g as getArchive } from '../../../../chunks/archive.js-C6rz09rJ.js';
2
+ import { r as readEnv } from '../../../../chunks/env2.js-CcIskxOZ.js';
3
+ import { a as apiError, p as parseRegionParam, r as resolveAwsConfig, c as createLogsClient, d as describeAwsError, b as resolveEffectiveRegion, R as REGION_PARAM_HINT } from '../../../../chunks/aws.js-DkPqAybc.js';
4
+ import { p as parseSourceParam, S as SOURCE_PARAM_HINT } from '../../../../chunks/source.js-DZEVvuho.js';
5
+ import { p as parseGroupParams, a as parseLevelParam, r as resolveWindow, c as clampPollMs, w as withLevels, L as LEVEL_PARAM_HINT } from '../../../../chunks/level-filter.js-H_AdNbCw.js';
3
6
  import '../../../../chunks/utils.js-BIlHjgGW.js';
4
7
  import { FilterLogEventsCommand } from '@aws-sdk/client-cloudwatch-logs';
5
- import '../../../../chunks/shared-server.js-Dn5XheXH.js';
8
+ import '../../../../chunks/log-buffer.js-CpI7gyom.js';
6
9
  import 'node:fs';
10
+ import 'node:os';
7
11
  import 'node:path';
12
+ import 'node:timers/promises';
13
+ import 'node:crypto';
14
+ import '../../../../chunks/shared-server.js-Dn5XheXH.js';
15
+ import '@aws-sdk/client-sts';
16
+ import '../../../../chunks/time-range.js-BLMT8aU3.js';
8
17
  import '../../../../chunks/shared.js-CgjUIvRK.js';
9
18
  import '../../../../chunks/uneval.js-DaakSYFQ.js';
10
19
 
11
- //#region src/lib/server/filter.ts
12
- /** Default lookback window when neither `startTime` nor `lookback` is usable. */
13
- var DEFAULT_LOOKBACK_MS = 3e5;
14
- /** CloudWatch Logs rejects `startTime` older than 14 days. */
15
- var MAX_LOOKBACK_MS = 12096e5;
16
- var DEFAULT_POLL_MS$1 = 1e3;
17
- var MIN_POLL_MS = 250;
18
- var MAX_POLL_MS = 15e3;
19
- var DURATION_UNITS = {
20
- ms: 1,
21
- s: 1e3,
22
- m: 6e4,
23
- h: 36e5,
24
- d: 864e5,
25
- w: 6048e5
26
- };
27
- var DURATION_PATTERN = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/i;
28
- var EPOCH_PATTERN = /^\d+$/;
29
- /**
30
- * Parses a single-unit duration such as `500ms`, `30s`, `15m`, `2h`, `3d` or
31
- * `1w`. Returns `null` for anything invalid, negative or zero.
32
- */
33
- function parseDurationMs(value) {
34
- if (typeof value !== "string") return null;
35
- const match = DURATION_PATTERN.exec(value.trim());
36
- if (match === null) return null;
37
- const amount = Number(match[1]);
38
- const unit = DURATION_UNITS[match[2].toLowerCase()];
39
- if (unit === void 0 || !Number.isFinite(amount)) return null;
40
- const ms = amount * unit;
41
- if (!Number.isFinite(ms) || ms <= 0) return null;
42
- return Math.round(ms);
20
+ //#region src/lib/server/archive-tail.ts
21
+ /** Page size used when the caller does not ask for one. */
22
+ var DEFAULT_ARCHIVE_PAGE_SIZE = 1e3;
23
+ /** Upper bound on one page, so a huge window cannot exhaust memory. */
24
+ var MAX_ARCHIVE_PAGE_SIZE = 5e3;
25
+ /** Events one archive request may return before it stops (matches the tailer). */
26
+ var DEFAULT_ARCHIVE_MAX_EVENTS = 1e4;
27
+ /** Message shown when DuckDB is missing or the file cannot be opened. */
28
+ function archiveUnavailableMessage(archive) {
29
+ const reason = archive.error;
30
+ const base = "The local archive is not available on this machine";
31
+ return reason === null || reason.length === 0 ? base : `${base}: ${reason}`;
43
32
  }
44
33
  /**
45
- * Parses a start point into epoch milliseconds.
34
+ * Yields archived events for one window, oldest first.
46
35
  *
47
- * Accepts epoch milliseconds (`1700000000000`), a duration relative to `now`
48
- * (`15m`) and ISO 8601 timestamps. Returns `null` when the value is missing or
49
- * cannot be understood.
36
+ * An unavailable archive produces a single `error` batch instead of throwing, so
37
+ * the browser shows a normal stream error. An aborted signal ends the generator
38
+ * without yielding an `end` batch, which is what the route treats as a
39
+ * client disconnect.
50
40
  */
51
- function parseStartTime(value, now) {
52
- if (typeof value !== "string") return null;
53
- const trimmed = value.trim();
54
- if (trimmed.length === 0) return null;
55
- if (EPOCH_PATTERN.test(trimmed)) return Number(trimmed);
56
- const duration = parseDurationMs(trimmed);
57
- if (duration !== null) return now - duration;
58
- const parsed = Date.parse(trimmed);
59
- return Number.isNaN(parsed) ? null : parsed;
60
- }
61
- /** Resolves the effective start time, clamped to the last 14 days and to `now`. */
62
- function resolveStartTime(input) {
63
- const { now } = input;
64
- let start = parseStartTime(input.startTime, now);
65
- if (start === null) start = now - (parseDurationMs(input.lookback ?? "") ?? DEFAULT_LOOKBACK_MS);
66
- const oldestAllowed = now - MAX_LOOKBACK_MS;
67
- if (start > now) start = now;
68
- if (start < oldestAllowed) start = oldestAllowed;
69
- return Math.round(start);
70
- }
71
- /** Parses a poll interval in milliseconds, defaulting to 1000 and clamped to 250..15000. */
72
- function clampPollMs(value) {
73
- if (typeof value !== "string") return DEFAULT_POLL_MS$1;
74
- const trimmed = value.trim();
75
- if (trimmed.length === 0) return DEFAULT_POLL_MS$1;
76
- const parsed = Number(trimmed);
77
- if (!Number.isFinite(parsed)) return DEFAULT_POLL_MS$1;
78
- return Math.min(Math.max(Math.round(parsed), MIN_POLL_MS), MAX_POLL_MS);
79
- }
80
- /** Default historic window when neither `range` nor `from`/`to` is given. */
81
- var DEFAULT_HISTORIC_PRESET = "15m";
82
- /** Parses the `mode` parameter; `null` for an unrecognised value. */
83
- function parseMode(value) {
84
- if (typeof value !== "string") return null;
85
- const trimmed = value.trim().toLowerCase();
86
- if (trimmed === "live" || trimmed === "historic") return trimmed;
87
- return null;
88
- }
89
- /**
90
- * Parses an absolute instant: epoch milliseconds or an ISO 8601 timestamp.
91
- *
92
- * Relative durations are deliberately rejected here so an end bound can never
93
- * move with the clock.
94
- */
95
- function parseInstant(value) {
96
- if (typeof value !== "string") return null;
97
- const trimmed = value.trim();
98
- if (trimmed.length === 0) return null;
99
- if (EPOCH_PATTERN.test(trimmed)) return Number(trimmed);
100
- const parsed = Date.parse(trimmed);
101
- return Number.isNaN(parsed) ? null : parsed;
41
+ async function* tailArchivedEvents(options) {
42
+ const { archive, region, logGroups, startTime, endTime, search = null, streamPrefix = null, levels = null, signal } = options;
43
+ if (!archive.available) {
44
+ yield {
45
+ type: "error",
46
+ message: archiveUnavailableMessage(archive),
47
+ code: "archive-unavailable"
48
+ };
49
+ return;
50
+ }
51
+ const requestedPageSize = options.pageSize ?? 1e3;
52
+ const pageSize = Math.min(Math.max(Number.isFinite(requestedPageSize) ? Math.round(requestedPageSize) : DEFAULT_ARCHIVE_PAGE_SIZE, 1), MAX_ARCHIVE_PAGE_SIZE);
53
+ const requestedMax = options.maxEvents ?? 1e4;
54
+ const maxEvents = Number.isFinite(requestedMax) && requestedMax > 0 ? Math.floor(requestedMax) : DEFAULT_ARCHIVE_MAX_EVENTS;
55
+ let cursor = null;
56
+ let emitted = 0;
57
+ for (;;) {
58
+ if (signal?.aborted === true) return;
59
+ const page = await archive.page({
60
+ region,
61
+ logGroups,
62
+ startTime,
63
+ endTime,
64
+ search,
65
+ streamPrefix,
66
+ levels,
67
+ after: cursor,
68
+ limit: pageSize
69
+ });
70
+ if (page.events.length === 0) {
71
+ yield {
72
+ type: "end",
73
+ reason: "window-complete"
74
+ };
75
+ return;
76
+ }
77
+ emitted += page.events.length;
78
+ yield {
79
+ type: "events",
80
+ events: page.events
81
+ };
82
+ cursor = page.last;
83
+ if (cursor === null || page.events.length < pageSize) {
84
+ yield {
85
+ type: "end",
86
+ reason: "window-complete"
87
+ };
88
+ return;
89
+ }
90
+ if (emitted >= maxEvents) {
91
+ yield {
92
+ type: "end",
93
+ reason: "event-limit"
94
+ };
95
+ return;
96
+ }
97
+ }
102
98
  }
103
- /**
104
- * Clamps a window to what CloudWatch Logs can return: 14 days back, ending now.
105
- *
106
- * Returns `null` when the requested window ends before the retention floor, so
107
- * a request for month-old data fails loudly instead of returning a stub window.
108
- */
109
- function clampWindow(start, end, now) {
110
- const oldest = now - MAX_LOOKBACK_MS;
111
- if (end <= oldest) return null;
112
- const clampedStart = Math.min(Math.max(start, oldest), now);
113
- const clampedEnd = Math.min(Math.max(end, clampedStart + 1), now);
114
- return {
115
- start: Math.round(clampedStart),
116
- end: Math.round(clampedEnd),
117
- clamped: clampedStart !== Math.round(start) || clampedEnd !== Math.round(end)
118
- };
99
+ //#endregion
100
+ //#region src/lib/server/multi-tail.ts
101
+ /** Events-payload batch reasons, worst first. */
102
+ var END_PRECEDENCE = [
103
+ "repeated-errors",
104
+ "event-limit",
105
+ "window-complete"
106
+ ];
107
+ /** Picks the most serious end reason from the sources. */
108
+ function mergeEndReason(reasons) {
109
+ for (const candidate of END_PRECEDENCE) if (reasons.includes(candidate)) return candidate;
110
+ return "window-complete";
119
111
  }
120
112
  /**
121
- * Resolves the request window into a start time plus, for historic mode, an end
122
- * time.
113
+ * Yields every batch of every source, then one `end`.
123
114
  *
124
- * Historic windows come from a preset (`range=24h`), from explicit bounds
125
- * (`from`/`to`, epoch ms or ISO 8601) or, when neither is given, from the
126
- * smallest preset. Windows are clamped to the last 14 days and to `now` so the
127
- * request can never ask CloudWatch for data it will not return.
115
+ * A failing source yields its own `error` batch; it never cancels the others, so
116
+ * one unreadable group does not silence the rest of the view.
128
117
  */
129
- function resolveWindow(input) {
130
- const { now } = input;
131
- const requestedMode = input.mode === null || input.mode === void 0 ? "live" : input.mode.trim();
132
- const mode = requestedMode === "" ? "live" : parseMode(requestedMode);
133
- if (mode === null) return {
134
- ok: false,
135
- code: "invalid-mode",
136
- message: "Invalid mode: expected \"live\" or \"historic\""
137
- };
138
- if (mode === "live") return {
139
- ok: true,
140
- mode,
141
- startTime: resolveStartTime({
142
- startTime: input.startTime,
143
- lookback: input.lookback,
144
- now
145
- }),
146
- endTime: null,
147
- preset: null,
148
- clamped: false
149
- };
150
- const from = input.from?.trim() ?? "";
151
- const to = input.to?.trim() ?? "";
152
- if (from.length > 0 || to.length > 0) {
153
- if (from.length === 0 || to.length === 0) return {
154
- ok: false,
155
- code: "invalid-window",
156
- message: "A custom window needs both \"from\" and \"to\""
157
- };
158
- const parsedFrom = parseStartTime(from, now);
159
- const parsedTo = parseInstant(to);
160
- if (parsedFrom === null) return {
161
- ok: false,
162
- code: "invalid-time",
163
- message: `Invalid "from": expected epoch milliseconds, a duration such as 3h, or an ISO 8601 timestamp`
164
- };
165
- if (parsedTo === null) return {
166
- ok: false,
167
- code: "invalid-time",
168
- message: "Invalid \"to\": expected epoch milliseconds or an ISO 8601 timestamp"
169
- };
170
- if (parsedTo <= parsedFrom) return {
171
- ok: false,
172
- code: "invalid-window",
173
- message: "The end of the window must be after its start"
174
- };
175
- const clamped = clampWindow(parsedFrom, parsedTo, now);
176
- if (clamped === null || clamped.end <= clamped.start) return {
177
- ok: false,
178
- code: "invalid-window",
179
- message: "The requested window is outside the 14 days CloudWatch Logs keeps"
180
- };
181
- return {
182
- ok: true,
183
- mode,
184
- startTime: clamped.start,
185
- endTime: clamped.end,
186
- preset: null,
187
- clamped: clamped.clamped
188
- };
118
+ async function* mergeTails(sources) {
119
+ if (sources.length === 0) return;
120
+ if (sources.length === 1) {
121
+ yield* sources[0];
122
+ return;
189
123
  }
190
- const requestedRange = input.range?.trim() ?? "";
191
- const preset = requestedRange === "" ? DEFAULT_HISTORIC_PRESET : isHistoricPreset(requestedRange) ? requestedRange : null;
192
- if (preset === null) return {
193
- ok: false,
194
- code: "invalid-range",
195
- message: `Invalid range: expected one of ${HISTORIC_PRESETS.join(", ")} or an explicit from/to window`
196
- };
197
- const end = Math.round(now);
198
- return {
199
- ok: true,
200
- mode,
201
- startTime: Math.round(now - presetDurationMs(preset)),
202
- endTime: end,
203
- preset,
204
- clamped: false
124
+ const queue = [];
125
+ let waiting = null;
126
+ /** Sources whose end marker has been consumed, so their batches are all out. */
127
+ let completed = 0;
128
+ const endReasons = [];
129
+ const push = (item) => {
130
+ queue.push(item);
131
+ const wake = waiting;
132
+ waiting = null;
133
+ wake?.();
205
134
  };
135
+ for (const source of sources) (async () => {
136
+ let endReason = null;
137
+ try {
138
+ for await (const batch of source) if (batch.type === "end") endReason = batch.reason;
139
+ else push({ batch });
140
+ } catch {} finally {
141
+ if (endReason !== null) endReasons.push(endReason);
142
+ push({ done: true });
143
+ }
144
+ })();
145
+ for (;;) {
146
+ if (queue.length === 0) {
147
+ if (completed >= sources.length) {
148
+ yield {
149
+ type: "end",
150
+ reason: mergeEndReason(endReasons)
151
+ };
152
+ return;
153
+ }
154
+ await new Promise((resolve) => {
155
+ waiting = resolve;
156
+ if (queue.length > 0 || completed >= sources.length) {
157
+ waiting = null;
158
+ resolve();
159
+ }
160
+ });
161
+ continue;
162
+ }
163
+ const item = queue.shift();
164
+ if ("batch" in item) yield item.batch;
165
+ else completed += 1;
166
+ }
206
167
  }
207
168
  //#endregion
208
169
  //#region src/lib/server/sse.ts
@@ -434,6 +395,16 @@ async function* tailLogEvents(options) {
434
395
  var PING_INTERVAL_MS = 15e3;
435
396
  /** Stop the stream after this many consecutive failed polls. */
436
397
  var MAX_CONSECUTIVE_ERRORS = 8;
398
+ /** Bounds for the archive `pageSize` parameter. */
399
+ var ARCHIVE_PAGE_LIMITS = {
400
+ min: 1,
401
+ max: 5e3
402
+ };
403
+ /** Bounds for the archive `max` parameter (events per request). */
404
+ var ARCHIVE_MAX_LIMITS = {
405
+ min: 1,
406
+ max: 1e5
407
+ };
437
408
  var SSE_HEADERS = {
438
409
  "content-type": "text/event-stream; charset=utf-8",
439
410
  "cache-control": "no-cache, no-transform",
@@ -441,44 +412,180 @@ var SSE_HEADERS = {
441
412
  "x-accel-buffering": "no"
442
413
  };
443
414
  /**
415
+ * Tags every event of one tail with its log group.
416
+ *
417
+ * A merged multi-group stream has to say which group each line came from, both
418
+ * for the archive and for the group column in the viewer.
419
+ */
420
+ async function* taggedEvents(source, group) {
421
+ for await (const batch of source) {
422
+ if (batch.type !== "events") {
423
+ yield batch;
424
+ continue;
425
+ }
426
+ const events = [];
427
+ for (const event of batch.events) events.push({
428
+ ...event,
429
+ group
430
+ });
431
+ yield {
432
+ type: "events",
433
+ events
434
+ };
435
+ }
436
+ }
437
+ /**
438
+ * Writes one batch to the archive, under the right group.
439
+ *
440
+ * A merged multi-group stream tags every event with its own group, so a batch
441
+ * that mixes groups is split; a single-group stream falls back to the group the
442
+ * request named.
443
+ */
444
+ async function recordBatch(archive, region, groupNames, events) {
445
+ const fallback = groupNames[0] ?? "";
446
+ const byGroup = /* @__PURE__ */ new Map();
447
+ for (const event of events) {
448
+ const group = event.group ?? fallback;
449
+ const bucket = byGroup.get(group);
450
+ if (bucket === void 0) byGroup.set(group, [event]);
451
+ else bucket.push(event);
452
+ }
453
+ for (const [group, groupEvents] of byGroup) await archive.record(region, group, groupEvents);
454
+ }
455
+ /**
456
+ * Parses a positive integer parameter within `limits`.
457
+ *
458
+ * Returns `null` for a missing value (meaning "use the default") and for an
459
+ * unusable one, so a typo falls back to the default instead of failing the
460
+ * stream; an out-of-range value is clamped rather than rejected.
461
+ */
462
+ function parseBoundedInt(value, limits) {
463
+ if (value === null) return null;
464
+ const trimmed = value.trim();
465
+ if (trimmed.length === 0) return null;
466
+ const parsed = Number(trimmed);
467
+ if (!Number.isFinite(parsed)) return null;
468
+ return Math.min(Math.max(Math.round(parsed), limits.min), limits.max);
469
+ }
470
+ /**
471
+ * Builds the feed for a request.
472
+ *
473
+ * The archive path never creates a CloudWatch client, so browsing history works
474
+ * with no credentials and no network; it does need a region, because archived
475
+ * rows are stored per region. Failures come back as an `apiError` response the
476
+ * route returns unchanged.
477
+ */
478
+ async function resolveFeed(request) {
479
+ const { source, config, env, groupNames, startTime, endTime, signal } = request;
480
+ if (source === "archive") {
481
+ const region = config.region ?? "";
482
+ if (region === "") return apiError(400, "Query parameter \"region\" is required when source=archive", "missing-region-param");
483
+ return {
484
+ region,
485
+ groupNames,
486
+ generator: tailArchivedEvents({
487
+ archive: await getArchive(env),
488
+ region,
489
+ logGroups: groupNames,
490
+ startTime,
491
+ endTime: endTime ?? Date.now(),
492
+ search: request.search,
493
+ levels: request.levels,
494
+ ...request.pageSize === null ? {} : { pageSize: request.pageSize },
495
+ ...request.maxEvents === null ? {} : { maxEvents: request.maxEvents },
496
+ signal
497
+ }),
498
+ release: () => void 0
499
+ };
500
+ }
501
+ let client;
502
+ try {
503
+ client = createLogsClient(config);
504
+ } catch (error) {
505
+ const described = describeAwsError(error);
506
+ return apiError(502, described.message, described.code);
507
+ }
508
+ let region;
509
+ try {
510
+ region = await resolveEffectiveRegion(client, config);
511
+ } catch (error) {
512
+ client.destroy();
513
+ const described = describeAwsError(error);
514
+ return apiError(502, described.message, described.code);
515
+ }
516
+ const tails = groupNames.map((group) => taggedEvents(tailLogEvents({
517
+ client,
518
+ logGroupName: group,
519
+ startTime,
520
+ endTime,
521
+ pollIntervalMs: request.pollIntervalMs,
522
+ filterPattern: request.filterPattern,
523
+ signal,
524
+ maxConsecutiveErrors: MAX_CONSECUTIVE_ERRORS
525
+ }), group));
526
+ return {
527
+ region,
528
+ groupNames,
529
+ generator: mergeTails(tails),
530
+ release: () => client.destroy()
531
+ };
532
+ }
533
+ /**
444
534
  * `GET /api/stream` - server-sent events for one log group.
445
535
  *
446
536
  * Emits `ready` first, then `log` per batch, `ping` after 15 s of silence and
447
- * a final `end`. The region is optional: without it the tailer uses a client
448
- * that resolves the region from the ambient AWS configuration. The tailer is
449
- * cancelled through `request.signal`, and every timer and listener is removed
450
- * so the dev server can exit.
537
+ * a final `end`. `source=cloudwatch` (the default) polls CloudWatch Logs with
538
+ * the ambient credentials; `source=archive` replays the local DuckDB archive and
539
+ * needs neither credentials nor a region parameter resolution.
540
+ *
541
+ * The stream is cancelled through `request.signal`, and every timer and listener
542
+ * is removed so the dev server can exit.
451
543
  */
452
544
  var GET = async ({ url, request }) => {
453
- const logGroupName = url.searchParams.get("group")?.trim() ?? "";
454
- if (logGroupName.length === 0) return apiError(400, "Query parameter \"group\" is required", "missing-group");
545
+ const groupSelection = parseGroupParams(url.searchParams.get("group"), url.searchParams.get("groups"));
546
+ if (!groupSelection.ok) return apiError(400, groupSelection.message, groupSelection.code);
547
+ const groupNames = groupSelection.names;
455
548
  const parsedRegion = parseRegionParam(url.searchParams.get("region"));
456
549
  if (!parsedRegion.ok) return apiError(400, REGION_PARAM_HINT, "invalid-region");
550
+ const source = parseSourceParam(url.searchParams.get("source"));
551
+ if (source === null) return apiError(400, SOURCE_PARAM_HINT, "invalid-source");
457
552
  const env = readEnv();
458
553
  const config = resolveAwsConfig(env, parsedRegion.region);
459
554
  const filterPattern = url.searchParams.get("filterPattern")?.trim();
555
+ const search = url.searchParams.get("search")?.trim() ?? "";
556
+ const levels = parseLevelParam(url.searchParams.get("level"));
557
+ if (levels === void 0) return apiError(400, LEVEL_PARAM_HINT, "invalid-level");
558
+ if (levels !== null && source !== "archive") return apiError(400, "The \"level\" filter applies to source=archive; use filterPattern to filter CloudWatch", "invalid-level");
460
559
  const streamWindow = resolveWindow({
461
- mode: url.searchParams.get("mode"),
560
+ mode: url.searchParams.get("mode") ?? (source === "archive" ? "historic" : null),
462
561
  range: url.searchParams.get("range"),
463
562
  from: url.searchParams.get("from"),
464
563
  to: url.searchParams.get("to"),
465
564
  startTime: url.searchParams.get("startTime"),
466
565
  lookback: url.searchParams.get("lookback"),
467
566
  now: Date.now()
468
- });
567
+ }, source === "archive" ? { maxLookbackMs: null } : {});
469
568
  if (!streamWindow.ok) return apiError(400, streamWindow.message, streamWindow.code);
470
- const pollIntervalMs = clampPollMs(url.searchParams.get("poll"));
471
- let client;
472
- let region;
473
- try {
474
- client = createLogsClient(config);
475
- region = await resolveEffectiveRegion(client, config);
476
- } catch (error) {
477
- const described = describeAwsError(error);
478
- return apiError(502, described.message, described.code);
479
- }
480
- const encoder = new TextEncoder();
569
+ if (source === "archive" && streamWindow.mode === "live") return apiError(400, "The local archive only serves historic windows: use mode=historic, or source=cloudwatch to tail live", "invalid-mode");
481
570
  const bodyAbort = new AbortController();
571
+ const feed = await resolveFeed({
572
+ source,
573
+ config,
574
+ env,
575
+ groupNames,
576
+ startTime: streamWindow.startTime,
577
+ endTime: streamWindow.endTime,
578
+ filterPattern,
579
+ search: search.length === 0 ? null : search,
580
+ levels,
581
+ pageSize: parseBoundedInt(url.searchParams.get("pageSize"), ARCHIVE_PAGE_LIMITS),
582
+ maxEvents: parseBoundedInt(url.searchParams.get("max"), ARCHIVE_MAX_LIMITS),
583
+ pollIntervalMs: clampPollMs(url.searchParams.get("poll")),
584
+ signal: bodyAbort.signal
585
+ });
586
+ if (feed instanceof Response) return feed;
587
+ const archive = source === "cloudwatch" ? await getArchive(env) : null;
588
+ const encoder = new TextEncoder();
482
589
  let streamController;
483
590
  let closed = false;
484
591
  let pingTimer;
@@ -532,27 +639,20 @@ var GET = async ({ url, request }) => {
532
639
  cleanedUp = true;
533
640
  clearPing();
534
641
  request.signal.removeEventListener("abort", onAbort);
535
- client.destroy();
642
+ feed.release();
536
643
  };
537
644
  const pump = async () => {
538
645
  let consecutiveErrors = 0;
539
646
  let reason = "completed";
540
647
  try {
541
- for await (const batch of tailLogEvents({
542
- client,
543
- logGroupName,
544
- startTime: streamWindow.startTime,
545
- endTime: streamWindow.endTime,
546
- pollIntervalMs,
547
- filterPattern,
548
- signal: bodyAbort.signal,
549
- maxConsecutiveErrors: MAX_CONSECUTIVE_ERRORS
550
- })) {
648
+ for await (const batch of feed.generator) {
551
649
  if (closed || bodyAbort.signal.aborted) break;
552
650
  if (batch.type === "events") {
553
- const payload = { events: batch.events };
651
+ const events = source === "cloudwatch" ? withLevels(batch.events) : batch.events;
652
+ const payload = { events };
554
653
  consecutiveErrors = 0;
555
654
  enqueue(sseFrame("log", payload));
655
+ if (archive !== null) await recordBatch(archive, feed.region, feed.groupNames, events);
556
656
  } else if (batch.type === "end") {
557
657
  reason = batch.reason;
558
658
  break;
@@ -583,9 +683,11 @@ var GET = async ({ url, request }) => {
583
683
  start(controller) {
584
684
  streamController = controller;
585
685
  const payload = {
586
- region,
587
- logGroupName,
588
- endpoint: config.endpoint,
686
+ region: feed.region,
687
+ logGroupName: feed.groupNames[0] ?? "",
688
+ groups: [...feed.groupNames],
689
+ endpoint: source === "archive" ? null : config.endpoint,
690
+ source,
589
691
  startTime: streamWindow.startTime,
590
692
  endTime: streamWindow.endTime,
591
693
  mode: streamWindow.mode,
@@ -607,4 +709,4 @@ var GET = async ({ url, request }) => {
607
709
  };
608
710
 
609
711
  export { GET };
610
- //# sourceMappingURL=_server.ts.js-D_i-xW6_.js.map
712
+ //# sourceMappingURL=_server.ts.js-C-XDemlx.js.map