@mks2508/mks-ui 0.5.4 → 0.5.8

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 (262) hide show
  1. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +23 -4
  2. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -1
  3. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +2 -2
  4. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -1
  5. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +292 -31
  6. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts +7 -0
  7. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts.map +1 -1
  8. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.js +6 -1
  9. package/dist/react-ui/ui/DynamicToggle/{DynamicToggle-Cm6-VceQ.css → DynamicToggle-DJLwEkHr.css} +116 -51
  10. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +116 -51
  11. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +1 -0
  12. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
  13. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +9 -3
  14. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +61 -31
  15. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
  16. package/dist/react-ui/ui/DynamicToggle/index.d.ts +9 -3
  17. package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
  18. package/dist/react-ui/ui/DynamicToggle/index.js +68 -37
  19. package/package.json +52 -13
  20. package/src/assets/react.svg +0 -1
  21. package/src/core/index.ts +0 -7
  22. package/src/core/types.ts +0 -82
  23. package/src/css.d.ts +0 -7
  24. package/src/index.css +0 -129
  25. package/src/index.ts +0 -29
  26. package/src/react-ui/blocks/Terminal/ResttyAdapter.ts +0 -278
  27. package/src/react-ui/blocks/Terminal/Terminal.adapter.ts +0 -97
  28. package/src/react-ui/blocks/Terminal/Terminal.theme.restty.ts +0 -155
  29. package/src/react-ui/blocks/Terminal/Terminal.theme.ts +0 -80
  30. package/src/react-ui/blocks/Terminal/Terminal.types.ts +0 -438
  31. package/src/react-ui/blocks/Terminal/TerminalDisplay.styles.ts +0 -38
  32. package/src/react-ui/blocks/Terminal/TerminalDisplay.tsx +0 -254
  33. package/src/react-ui/blocks/Terminal/TerminalDisplay.types.ts +0 -73
  34. package/src/react-ui/blocks/Terminal/TerminalPanel.tsx +0 -269
  35. package/src/react-ui/blocks/Terminal/TerminalRestty.tsx +0 -326
  36. package/src/react-ui/blocks/Terminal/TerminalXterm.tsx +0 -230
  37. package/src/react-ui/blocks/Terminal/XTermAdapter.ts +0 -163
  38. package/src/react-ui/blocks/Terminal/chrome.ts +0 -25
  39. package/src/react-ui/blocks/Terminal/components/LogLineBadges.tsx +0 -316
  40. package/src/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.tsx +0 -218
  41. package/src/react-ui/blocks/Terminal/components/SyntaxHighlight.tsx +0 -386
  42. package/src/react-ui/blocks/Terminal/components/TerminalLogBadge.tsx +0 -67
  43. package/src/react-ui/blocks/Terminal/components/index.ts +0 -10
  44. package/src/react-ui/blocks/Terminal/display.ts +0 -46
  45. package/src/react-ui/blocks/Terminal/hooks/index.ts +0 -22
  46. package/src/react-ui/blocks/Terminal/hooks/useTerminalSettings.ts +0 -229
  47. package/src/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.ts +0 -292
  48. package/src/react-ui/blocks/Terminal/index.ts +0 -111
  49. package/src/react-ui/blocks/Terminal/panel/LogLinesViewer.tsx +0 -330
  50. package/src/react-ui/blocks/Terminal/panel/TerminalDebugPanel.tsx +0 -242
  51. package/src/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.tsx +0 -202
  52. package/src/react-ui/blocks/Terminal/panel/TerminalFilterTabs.tsx +0 -140
  53. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.tsx +0 -68
  54. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.ts +0 -85
  55. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.tsx +0 -383
  56. package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.tsx +0 -439
  57. package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.tsx +0 -550
  58. package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.ts +0 -259
  59. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.styles.ts +0 -75
  60. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.tsx +0 -266
  61. package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.ts +0 -82
  62. package/src/react-ui/blocks/Terminal/panel/TerminalPanelFooter.tsx +0 -112
  63. package/src/react-ui/blocks/Terminal/panel/TerminalPanelHeader.tsx +0 -178
  64. package/src/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.tsx +0 -203
  65. package/src/react-ui/blocks/Terminal/panel/TerminalSessionControl.tsx +0 -252
  66. package/src/react-ui/blocks/Terminal/panel/TerminalSessionTabs.tsx +0 -334
  67. package/src/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.tsx +0 -261
  68. package/src/react-ui/blocks/Terminal/panel/TerminalThemeSelector.tsx +0 -248
  69. package/src/react-ui/blocks/Terminal/panel/index.ts +0 -72
  70. package/src/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.css +0 -59
  71. package/src/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.css +0 -59
  72. package/src/react-ui/blocks/Terminal/parsing/BadgeFormatter.ts +0 -180
  73. package/src/react-ui/blocks/Terminal/parsing/HttpLogParser.ts +0 -248
  74. package/src/react-ui/blocks/Terminal/parsing/LogParser.types.ts +0 -283
  75. package/src/react-ui/blocks/Terminal/parsing/LogParserService.ts +0 -686
  76. package/src/react-ui/blocks/Terminal/parsing/MultilineAggregator.ts +0 -466
  77. package/src/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.ts +0 -343
  78. package/src/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.ts +0 -167
  79. package/src/react-ui/blocks/Terminal/parsing/TableParser.ts +0 -348
  80. package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.ts +0 -251
  81. package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.ts +0 -390
  82. package/src/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.ts +0 -320
  83. package/src/react-ui/blocks/Terminal/parsing/ansi/index.ts +0 -20
  84. package/src/react-ui/blocks/Terminal/parsing/index.ts +0 -69
  85. package/src/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.ts +0 -68
  86. package/src/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.ts +0 -436
  87. package/src/react-ui/blocks/Terminal/parsing/levels/index.ts +0 -14
  88. package/src/react-ui/blocks/index.ts +0 -11
  89. package/src/react-ui/components/MorphingPopover/MorphingPopover.types.ts +0 -49
  90. package/src/react-ui/components/MorphingPopover/index.tsx +0 -186
  91. package/src/react-ui/components/MorphingPopover/morphing-popover.module.css +0 -153
  92. package/src/react-ui/components/index.ts +0 -9
  93. package/src/react-ui/hooks/Animation/UseAutoHeight.tsx +0 -123
  94. package/src/react-ui/hooks/DOM/UseIsInView.tsx +0 -44
  95. package/src/react-ui/hooks/Formatting/UseListFormat.ts +0 -134
  96. package/src/react-ui/hooks/State/UseControlledState.tsx +0 -57
  97. package/src/react-ui/hooks/State/UseDataState.tsx +0 -76
  98. package/src/react-ui/hooks/index.ts +0 -20
  99. package/src/react-ui/icons/index.ts +0 -12
  100. package/src/react-ui/icons/lucide-animated/activity.tsx +0 -109
  101. package/src/react-ui/icons/lucide-animated/arrow-down-to-line.tsx +0 -51
  102. package/src/react-ui/icons/lucide-animated/arrow-up.tsx +0 -50
  103. package/src/react-ui/icons/lucide-animated/bell-electric.tsx +0 -124
  104. package/src/react-ui/icons/lucide-animated/bell.tsx +0 -93
  105. package/src/react-ui/icons/lucide-animated/bot.tsx +0 -122
  106. package/src/react-ui/icons/lucide-animated/box.tsx +0 -117
  107. package/src/react-ui/icons/lucide-animated/check.tsx +0 -21
  108. package/src/react-ui/icons/lucide-animated/circle-check.tsx +0 -107
  109. package/src/react-ui/icons/lucide-animated/delete.tsx +0 -133
  110. package/src/react-ui/icons/lucide-animated/download.tsx +0 -99
  111. package/src/react-ui/icons/lucide-animated/edit-2.tsx +0 -21
  112. package/src/react-ui/icons/lucide-animated/globe.tsx +0 -23
  113. package/src/react-ui/icons/lucide-animated/home.tsx +0 -103
  114. package/src/react-ui/icons/lucide-animated/index.ts +0 -38
  115. package/src/react-ui/icons/lucide-animated/layers.tsx +0 -23
  116. package/src/react-ui/icons/lucide-animated/layout-panel-top.tsx +0 -143
  117. package/src/react-ui/icons/lucide-animated/list.tsx +0 -54
  118. package/src/react-ui/icons/lucide-animated/package.tsx +0 -24
  119. package/src/react-ui/icons/lucide-animated/palette.tsx +0 -25
  120. package/src/react-ui/icons/lucide-animated/plus.tsx +0 -92
  121. package/src/react-ui/icons/lucide-animated/refresh-cw.tsx +0 -24
  122. package/src/react-ui/icons/lucide-animated/rocket.tsx +0 -24
  123. package/src/react-ui/icons/lucide-animated/save.tsx +0 -23
  124. package/src/react-ui/icons/lucide-animated/search.tsx +0 -94
  125. package/src/react-ui/icons/lucide-animated/settings.tsx +0 -92
  126. package/src/react-ui/icons/lucide-animated/terminal.tsx +0 -46
  127. package/src/react-ui/icons/lucide-animated/trash-2.tsx +0 -25
  128. package/src/react-ui/icons/lucide-animated/trending-down.tsx +0 -151
  129. package/src/react-ui/icons/lucide-animated/trending-up.tsx +0 -150
  130. package/src/react-ui/icons/lucide-animated/type.tsx +0 -23
  131. package/src/react-ui/icons/lucide-animated/upload.tsx +0 -23
  132. package/src/react-ui/icons/lucide-animated/x.tsx +0 -102
  133. package/src/react-ui/index.ts +0 -30
  134. package/src/react-ui/lib/get-strict-context.tsx +0 -56
  135. package/src/react-ui/lib/icon-wrapper.tsx +0 -70
  136. package/src/react-ui/lib/index.ts +0 -9
  137. package/src/react-ui/lib/utils.ts +0 -24
  138. package/src/react-ui/primitives/AutoHeight/index.tsx +0 -74
  139. package/src/react-ui/primitives/CountingNumber/index.tsx +0 -147
  140. package/src/react-ui/primitives/Highlight/Highlight.types.ts +0 -136
  141. package/src/react-ui/primitives/Highlight/index.tsx +0 -577
  142. package/src/react-ui/primitives/Slot/index.tsx +0 -128
  143. package/src/react-ui/primitives/index.ts +0 -16
  144. package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +0 -123
  145. package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +0 -80
  146. package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +0 -77
  147. package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +0 -58
  148. package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +0 -244
  149. package/src/react-ui/primitives/waapi/Gooey/index.ts +0 -50
  150. package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +0 -48
  151. package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +0 -106
  152. package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +0 -21
  153. package/src/react-ui/primitives/waapi/Morph/index.tsx +0 -56
  154. package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +0 -12
  155. package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +0 -89
  156. package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +0 -176
  157. package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +0 -87
  158. package/src/react-ui/primitives/waapi/Morph/useMorph.ts +0 -101
  159. package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +0 -177
  160. package/src/react-ui/primitives/waapi/Reorder/index.tsx +0 -260
  161. package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +0 -47
  162. package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +0 -209
  163. package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +0 -104
  164. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +0 -14
  165. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +0 -84
  166. package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +0 -474
  167. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +0 -32
  168. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +0 -69
  169. package/src/react-ui/primitives/waapi/SlidingText/index.tsx +0 -140
  170. package/src/react-ui/primitives/waapi/core/animationConstants.ts +0 -215
  171. package/src/react-ui/primitives/waapi/core/index.ts +0 -53
  172. package/src/react-ui/primitives/waapi/core/types.ts +0 -200
  173. package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +0 -430
  174. package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +0 -81
  175. package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +0 -138
  176. package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +0 -106
  177. package/src/react-ui/primitives/waapi/index.ts +0 -139
  178. package/src/react-ui/styles/animations.css +0 -369
  179. package/src/react-ui/ui/Accordion/Accordion.styles.ts +0 -72
  180. package/src/react-ui/ui/Accordion/Accordion.types.ts +0 -199
  181. package/src/react-ui/ui/Accordion/index.tsx +0 -362
  182. package/src/react-ui/ui/AlertDialog/AlertDialog.styles.ts +0 -38
  183. package/src/react-ui/ui/AlertDialog/AlertDialog.types.ts +0 -296
  184. package/src/react-ui/ui/AlertDialog/index.tsx +0 -540
  185. package/src/react-ui/ui/Badge/Badge.styles.ts +0 -43
  186. package/src/react-ui/ui/Badge/Badge.types.ts +0 -26
  187. package/src/react-ui/ui/Badge/index.tsx +0 -34
  188. package/src/react-ui/ui/Button/Button.styles.ts +0 -57
  189. package/src/react-ui/ui/Button/Button.types.ts +0 -63
  190. package/src/react-ui/ui/Button/index.tsx +0 -155
  191. package/src/react-ui/ui/Card/Card.styles.ts +0 -32
  192. package/src/react-ui/ui/Card/Card.types.ts +0 -39
  193. package/src/react-ui/ui/Card/index.tsx +0 -130
  194. package/src/react-ui/ui/Checkbox/Checkbox.styles.ts +0 -40
  195. package/src/react-ui/ui/Checkbox/Checkbox.types.ts +0 -98
  196. package/src/react-ui/ui/Checkbox/index.tsx +0 -233
  197. package/src/react-ui/ui/Combobox/Combobox.styles.ts +0 -34
  198. package/src/react-ui/ui/Combobox/Combobox.types.ts +0 -89
  199. package/src/react-ui/ui/Combobox/index.tsx +0 -331
  200. package/src/react-ui/ui/CornerBracket/CornerBracket.styles.ts +0 -38
  201. package/src/react-ui/ui/CornerBracket/CornerBracket.types.ts +0 -15
  202. package/src/react-ui/ui/CornerBracket/index.tsx +0 -49
  203. package/src/react-ui/ui/DataCard/DataCard.styles.ts +0 -94
  204. package/src/react-ui/ui/DataCard/DataCard.types.ts +0 -125
  205. package/src/react-ui/ui/DataCard/index.tsx +0 -340
  206. package/src/react-ui/ui/Dialog/Dialog.styles.ts +0 -59
  207. package/src/react-ui/ui/Dialog/Dialog.types.ts +0 -284
  208. package/src/react-ui/ui/Dialog/index.tsx +0 -452
  209. package/src/react-ui/ui/DropdownMenu/DropdownMenu.styles.ts +0 -35
  210. package/src/react-ui/ui/DropdownMenu/DropdownMenu.types.ts +0 -81
  211. package/src/react-ui/ui/DropdownMenu/index.tsx +0 -300
  212. package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +0 -303
  213. package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +0 -85
  214. package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +0 -174
  215. package/src/react-ui/ui/DynamicToggle/index.tsx +0 -294
  216. package/src/react-ui/ui/DynamicToggle/prototype-v7.html +0 -615
  217. package/src/react-ui/ui/DynamicToggle/prototype.html +0 -419
  218. package/src/react-ui/ui/Field/Field.styles.ts +0 -47
  219. package/src/react-ui/ui/Field/Field.types.ts +0 -60
  220. package/src/react-ui/ui/Field/index.tsx +0 -254
  221. package/src/react-ui/ui/Input/Input.styles.ts +0 -11
  222. package/src/react-ui/ui/Input/Input.types.ts +0 -10
  223. package/src/react-ui/ui/Input/index.tsx +0 -32
  224. package/src/react-ui/ui/InputGroup/InputGroup.styles.ts +0 -53
  225. package/src/react-ui/ui/InputGroup/InputGroup.types.ts +0 -44
  226. package/src/react-ui/ui/InputGroup/index.tsx +0 -149
  227. package/src/react-ui/ui/Label/Label.styles.ts +0 -10
  228. package/src/react-ui/ui/Label/Label.types.ts +0 -9
  229. package/src/react-ui/ui/Label/index.tsx +0 -27
  230. package/src/react-ui/ui/Menu/Menu.styles.ts +0 -71
  231. package/src/react-ui/ui/Menu/Menu.types.ts +0 -425
  232. package/src/react-ui/ui/Menu/index.tsx +0 -900
  233. package/src/react-ui/ui/Popover/Popover.styles.ts +0 -55
  234. package/src/react-ui/ui/Popover/Popover.types.ts +0 -261
  235. package/src/react-ui/ui/Popover/index.tsx +0 -422
  236. package/src/react-ui/ui/Progress/Progress.styles.ts +0 -36
  237. package/src/react-ui/ui/Progress/Progress.types.ts +0 -162
  238. package/src/react-ui/ui/Progress/index.tsx +0 -254
  239. package/src/react-ui/ui/Select/Select.styles.ts +0 -30
  240. package/src/react-ui/ui/Select/Select.types.ts +0 -51
  241. package/src/react-ui/ui/Select/index.tsx +0 -225
  242. package/src/react-ui/ui/Separator/Separator.styles.ts +0 -10
  243. package/src/react-ui/ui/Separator/Separator.types.ts +0 -10
  244. package/src/react-ui/ui/Separator/index.tsx +0 -37
  245. package/src/react-ui/ui/Switch/Switch.styles.ts +0 -50
  246. package/src/react-ui/ui/Switch/Switch.types.ts +0 -155
  247. package/src/react-ui/ui/Switch/index.tsx +0 -253
  248. package/src/react-ui/ui/Tabs/Tabs.css +0 -39
  249. package/src/react-ui/ui/Tabs/Tabs.styles.ts +0 -148
  250. package/src/react-ui/ui/Tabs/Tabs.types.ts +0 -255
  251. package/src/react-ui/ui/Tabs/index.tsx +0 -529
  252. package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +0 -36
  253. package/src/react-ui/ui/TextFlow/TextFlow.types.ts +0 -118
  254. package/src/react-ui/ui/TextFlow/index.tsx +0 -276
  255. package/src/react-ui/ui/Textarea/Textarea.styles.ts +0 -10
  256. package/src/react-ui/ui/Textarea/Textarea.types.ts +0 -9
  257. package/src/react-ui/ui/Textarea/index.tsx +0 -27
  258. package/src/react-ui/ui/Tooltip/Tooltip.styles.ts +0 -43
  259. package/src/react-ui/ui/Tooltip/Tooltip.types.ts +0 -253
  260. package/src/react-ui/ui/Tooltip/index.tsx +0 -394
  261. package/src/react-ui/ui/index.ts +0 -41
  262. package/src/types/css-modules.d.ts +0 -18
@@ -1,466 +0,0 @@
1
- /**
2
- * Multiline log aggregator for JSON and structured data.
3
- *
4
- * Detects and aggregates multiline log entries such as JSON objects,
5
- * tables, and structured data that span multiple lines. Prevents
6
- * timestamp/level repetition on continuation lines.
7
- *
8
- * @module components/devenv/terminal/parsing/multiline
9
- */
10
-
11
- import type { IParsedLogEntry, TLogLevel } from './LogParser.types';
12
-
13
- /**
14
- * Box-drawing characters used for table borders.
15
- * Unicode range: U+2500-U+257F
16
- */
17
- const TABLE_CHARS = [
18
- '─', '│', '┌', '┐', '└', '┘',
19
- '├', '┤', '┬', '┴', '┼',
20
- '═', '║', '╔', '╗', '╚', '╝',
21
- '╠', '╣', '╦', '╩', '╬',
22
- ];
23
-
24
- /**
25
- * Multiline aggregation state.
26
- *
27
- * Tracks buffer and context while aggregating multiline logs.
28
- */
29
- export interface IMultilineState {
30
- /** Buffered lines for current multiline entry */
31
- buffer: string[];
32
-
33
- /** Parent entry for continuation lines (only line_number is used) */
34
- parentEntry?: {
35
- line_number: number;
36
- level: TLogLevel;
37
- };
38
-
39
- /** Whether currently in multiline mode */
40
- isMultiline: boolean;
41
-
42
- /** Expected closing bracket/brace for current multiline */
43
- expectedClose?: '}' | ']';
44
-
45
- /** Current depth of nested braces/brackets */
46
- depth: number;
47
- }
48
-
49
- /**
50
- * Multiline log aggregator class.
51
- *
52
- * Detects and aggregates lines that are part of a multiline JSON
53
- * or structured data entry. Marks continuation lines so they don't
54
- * get timestamp/level prefixes.
55
- *
56
- * @example
57
- * ```ts
58
- * const aggregator = new MultilineAggregator();
59
- * const aggregated = aggregator.aggregate(entries);
60
- * // Lines like '{', ' filter: {},', '}' get marked as continuation
61
- * ```
62
- */
63
- export class MultilineAggregator {
64
- /**
65
- * Detect if a line is a continuation of multiline JSON/structured data.
66
- *
67
- * Continuation indicators:
68
- * - Line starts with `{` or `[` alone → opens multiline
69
- * - Line has indentation + `key: value,` → continuation
70
- * - Line is just `}` or `]` → closes multiline
71
- * - Line ends with `{` or `[` without match → opens multiline
72
- * - When in multiline mode: lines ending with comma or containing key-value patterns
73
- *
74
- * @param line - Line to check
75
- * @param state - Current multiline state
76
- * @returns true if line is a continuation
77
- */
78
- detectContinuation(line: string, state: IMultilineState): boolean {
79
- const trimmed = line.trim();
80
-
81
- // Already in multiline mode - more permissive detection
82
- if (state.isMultiline) {
83
- // Check if this closes the multiline
84
- if (this.isClosingBrace(trimmed, state.expectedClose)) {
85
- return true;
86
- }
87
- // Check if this opens another level
88
- if (this.isOpeningBrace(trimmed)) {
89
- return true;
90
- }
91
- // Check if this looks like a continuation (indented content)
92
- if (this.isContinuationLine(line)) {
93
- return true;
94
- }
95
- // NEW: When in multiline mode, lines ending with comma or containing JSON patterns
96
- // are continuations even if they have their own timestamp/level metadata
97
- if (this.isJsonContinuation(trimmed)) {
98
- return true;
99
- }
100
- return false;
101
- }
102
-
103
- // Not in multiline mode - check if this opens one
104
- return this.opensMultiline(trimmed);
105
- }
106
-
107
- /**
108
- * Aggregate entries, marking continuation lines.
109
- *
110
- * Processes entries and marks lines that are continuations
111
- * of a previous multiline entry. Handles:
112
- * - JSON/structured data blocks
113
- * - Table borders (box-drawing characters)
114
- * - Indented continuation lines
115
- *
116
- * @param entries - Parsed log entries to aggregate
117
- * @param initialState - Optional initial multiline state (for persistence across chunks)
118
- * @returns Entries with continuation marking and new multiline state
119
- */
120
- aggregate(entries: IParsedLogEntry[], initialState?: IMultilineState): { entries: IParsedLogEntry[]; state: IMultilineState } {
121
- const result: IParsedLogEntry[] = [];
122
- const state: IMultilineState = initialState ?? {
123
- buffer: [],
124
- isMultiline: false,
125
- depth: 0,
126
- };
127
-
128
- for (const entry of entries) {
129
- const raw = entry.raw;
130
- const trimmed = raw.trim();
131
-
132
- // Skip empty lines (end previous blocks)
133
- if (trimmed.length === 0) {
134
- if (state.isMultiline) {
135
- // End the current block
136
- state.isMultiline = false;
137
- state.buffer = [];
138
- state.parentEntry = undefined;
139
- state.depth = 0;
140
- state.expectedClose = undefined;
141
- }
142
- // Don't add empty lines to result
143
- continue;
144
- }
145
-
146
- // Check if this line starts a multiline block
147
- if (!state.isMultiline && this.opensMultiline(trimmed)) {
148
- // This is the start of multiline
149
- state.isMultiline = true;
150
- state.parentEntry = entry;
151
- state.depth = this.countOpeningBraces(trimmed);
152
- state.expectedClose = this.getExpectedClose(trimmed);
153
-
154
- // Mark entry as multiline start (not a continuation)
155
- entry.is_continuation = false;
156
- result.push(entry);
157
- continue;
158
- }
159
-
160
- // Check if this is a continuation line
161
- if (state.isMultiline) {
162
- // Check if this line closes the multiline
163
- if (this.isClosingBrace(trimmed, state.expectedClose)) {
164
- state.depth--;
165
- if (state.depth <= 0) {
166
- // This closes the multiline block
167
- entry.is_continuation = true;
168
- entry.parent_line_number = state.parentEntry?.line_number;
169
- result.push(entry);
170
-
171
- // Reset state
172
- state.isMultiline = false;
173
- state.buffer = [];
174
- state.parentEntry = undefined;
175
- state.depth = 0;
176
- state.expectedClose = undefined;
177
- continue;
178
- }
179
- }
180
-
181
- // Check if this opens another level
182
- if (this.isOpeningBrace(trimmed)) {
183
- state.depth += this.countOpeningBraces(trimmed);
184
- }
185
-
186
- // Check if this looks like a continuation (even with timestamp)
187
- if (this.isJsonContinuation(trimmed)) {
188
- entry.is_continuation = true;
189
- entry.parent_line_number = state.parentEntry?.line_number;
190
- result.push(entry);
191
- continue;
192
- }
193
-
194
- // If we're in multiline mode but this line doesn't look like a continuation,
195
- // it might be a new log entry ending the multiline block
196
- if (this.looksLikeNewEntry(trimmed)) {
197
- // End the multiline block
198
- state.isMultiline = false;
199
- state.parentEntry = undefined;
200
- state.depth = 0;
201
- state.expectedClose = undefined;
202
-
203
- // Check if this new line also starts a multiline
204
- if (this.opensMultiline(trimmed)) {
205
- state.isMultiline = true;
206
- state.parentEntry = entry;
207
- state.depth = this.countOpeningBraces(trimmed);
208
- state.expectedClose = this.getExpectedClose(trimmed);
209
- }
210
-
211
- entry.is_continuation = false;
212
- result.push(entry);
213
- continue;
214
- }
215
-
216
- // Default: treat as continuation if in multiline mode
217
- entry.is_continuation = true;
218
- entry.parent_line_number = state.parentEntry?.line_number;
219
- result.push(entry);
220
- continue;
221
- }
222
-
223
- // Normal line, not part of multiline
224
- entry.is_continuation = false;
225
- result.push(entry);
226
- }
227
-
228
- return { entries: result, state };
229
- }
230
-
231
- /**
232
- * Check if a line opens a multiline block.
233
- *
234
- * @param trimmed - Trimmed line to check
235
- * @returns true if line opens multiline
236
- * @private
237
- */
238
- private opensMultiline(trimmed: string): boolean {
239
- // Line is just an opening brace
240
- if (trimmed === '{' || trimmed === '[') {
241
- return true;
242
- }
243
-
244
- // Line ends with opening brace without match
245
- const openCount = (trimmed.match(/\{/g) ?? []).length;
246
- const closeCount = (trimmed.match(/\}/g) ?? []).length;
247
- const bracketOpen = (trimmed.match(/\[/g) ?? []).length;
248
- const bracketClose = (trimmed.match(/\]/g) ?? []).length;
249
-
250
- // More opening than closing = multiline start
251
- if ((openCount > closeCount) || (bracketOpen > bracketClose)) {
252
- return true;
253
- }
254
-
255
- // Line ends with opening brace (e.g., "GET /api/endpoint {")
256
- if (trimmed.endsWith('{') || trimmed.endsWith('[')) {
257
- return true;
258
- }
259
-
260
- return false;
261
- }
262
-
263
- /**
264
- * Check if a line is an opening brace/bracket.
265
- *
266
- * @param trimmed - Trimmed line to check
267
- * @returns true if line contains opening brace/bracket
268
- * @private
269
- */
270
- private isOpeningBrace(trimmed: string): boolean {
271
- return trimmed.includes('{') || trimmed.includes('[');
272
- }
273
-
274
- /**
275
- * Check if a line is a closing brace/bracket for expected type.
276
- *
277
- * @param trimmed - Trimmed line to check
278
- * @param expected - Expected close type
279
- * @returns true if line closes the multiline block
280
- * @private
281
- */
282
- private isClosingBrace(trimmed: string, expected?: '}' | ']'): boolean {
283
- if (!expected) return false;
284
-
285
- if (expected === '}' && trimmed === '}') {
286
- return true;
287
- }
288
- if (expected === ']' && trimmed === ']') {
289
- return true;
290
- }
291
-
292
- return false;
293
- }
294
-
295
- /**
296
- * Get the expected closing character for a line.
297
- *
298
- * @param trimmed - Trimmed line to check
299
- * @returns Expected closing character or undefined
300
- * @private
301
- */
302
- private getExpectedClose(trimmed: string): '}' | ']' | undefined {
303
- if (trimmed.includes('{')) return '}';
304
- if (trimmed.includes('[')) return ']';
305
- return undefined;
306
- }
307
-
308
- /**
309
- * Count opening braces/brackets in a line.
310
- *
311
- * @param trimmed - Trimmed line to check
312
- * @returns Count of opening braces/brackets
313
- * @private
314
- */
315
- private countOpeningBraces(trimmed: string): number {
316
- const openCount = (trimmed.match(/\{/g) ?? []).length;
317
- const bracketOpen = (trimmed.match(/\[/g) ?? []).length;
318
- return openCount + bracketOpen;
319
- }
320
-
321
- /**
322
- * Check if a line is a table line (contains box-drawing characters).
323
- *
324
- * @param trimmed - Trimmed line to check
325
- * @returns true if line contains table borders
326
- * @private
327
- */
328
- private isTableLine(trimmed: string): boolean {
329
- // Check if line contains multiple box-drawing characters
330
- // (to avoid false positives on single characters)
331
- let count = 0;
332
- for (const char of TABLE_CHARS) {
333
- if (trimmed.includes(char)) count++;
334
- if (count >= 2) return true;
335
- }
336
- return count >= 2;
337
- }
338
-
339
- /**
340
- * Check if a line looks like a new log entry (not a continuation).
341
- *
342
- * New entries typically start with:
343
- * - Timestamp followed by log level
344
- * - HTTP method followed by path
345
- * - Component/module tag
346
- *
347
- * @param trimmed - Trimmed line to check
348
- * @returns true if line looks like a new entry
349
- * @private
350
- */
351
- private looksLikeNewEntry(trimmed: string): boolean {
352
- // Pattern: timestamp followed by level (e.g., "01:18:52 INFO")
353
- const timestampLevelPattern = /^\d{1,2}:\d{2}:\d{2}(\.\d+)?\s+(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)/i;
354
- if (timestampLevelPattern.test(trimmed)) {
355
- return true;
356
- }
357
-
358
- // Pattern: ISO timestamp followed by level
359
- const isoTimestampPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;
360
- if (isoTimestampPattern.test(trimmed)) {
361
- return true;
362
- }
363
-
364
- // Pattern: HTTP method at start (e.g., "GET /api/...")
365
- const httpPattern = /^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS|CONNECT|TRACE)\s+/i;
366
- if (httpPattern.test(trimmed)) {
367
- return true;
368
- }
369
-
370
- // Pattern: Component tag at start (e.g., "⦗API⦘")
371
- if (trimmed.startsWith('⦗') && trimmed.includes('⦘')) {
372
- return true;
373
- }
374
-
375
- return false;
376
- }
377
-
378
- /**
379
- * Check if a trimmed line is a JSON/structured data continuation.
380
- *
381
- * This handles lines that have their own timestamp/level metadata
382
- * but are actually continuations of a multiline JSON block.
383
- *
384
- * Examples:
385
- * - `container: "name",` - ends with comma
386
- * - `tail: 100,` - ends with comma
387
- * - `key: "value"` - key-value pattern
388
- * - `}` - closing brace
389
- * - Lines with pipe characters (table rows)
390
- *
391
- * @param trimmed - Trimmed line to check
392
- * @returns true if line is a JSON continuation
393
- * @private
394
- */
395
- private isJsonContinuation(trimmed: string): boolean {
396
- // Line is just a closing brace - closes the multiline
397
- if (trimmed === '}' || trimmed === ']') {
398
- return true;
399
- }
400
-
401
- // Line ends with comma - likely JSON continuation
402
- if (trimmed.endsWith(',')) {
403
- return true;
404
- }
405
-
406
- // Line ends with opening brace - extends multiline
407
- if (trimmed.endsWith('{') || trimmed.endsWith('[')) {
408
- return true;
409
- }
410
-
411
- // Line contains pipe characters (table row with content)
412
- // Pattern: │ key │ value │
413
- if (trimmed.includes('│') && !this.isTableLine(trimmed)) {
414
- // Has pipe but not enough box-drawing chars to be a border line
415
- // This is likely a table content row
416
- return true;
417
- }
418
-
419
- // Check for key-value pattern after timestamp/level removal
420
- // Remove common prefixes: "01:18:52 INFO " or "[INFO] "
421
- let content = trimmed
422
- .replace(/^\d{1,2}:\d{2}:\d{2}(\.\d+)?\s+(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\s*/i, '')
423
- .replace(/^\[(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\]\s*/i, '')
424
- .replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*?\s+/, '')
425
- .trim();
426
-
427
- // Pattern: "key": value or key: value or "key": "value"
428
- const keyValuePatterns = [
429
- /^[\w"']+\s*:\s*[\w"'\{[]/, // "key": { or key: [
430
- /^[\w"']+\s*:\s*".*",?\s*$/, // "key": "value",
431
- /^[\w"']+\s*:\s*\d+/, // key: 123
432
- /^[\w"']+\s*:\s*true|false/, // key: true
433
- ];
434
-
435
- if (keyValuePatterns.some(pattern => pattern.test(content))) {
436
- return true;
437
- }
438
-
439
- return false;
440
- }
441
-
442
- /**
443
- * Check if a line looks like a continuation line (indented content).
444
- *
445
- * @param line - Line to check (not trimmed, to check indentation)
446
- * @returns true if line appears to be a continuation
447
- * @private
448
- */
449
- private isContinuationLine(line: string): boolean {
450
- // Check if line starts with whitespace (indented)
451
- return line.length > 0 && (line[0] === ' ' || line[0] === '\t');
452
- }
453
-
454
- /**
455
- * Create initial multiline state.
456
- *
457
- * @returns Fresh multiline state
458
- */
459
- createInitialState(): IMultilineState {
460
- return {
461
- buffer: [],
462
- isMultiline: false,
463
- depth: 0,
464
- };
465
- }
466
- }