@buoy-gg/console 7.0.41 → 7.0.42

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 (108) hide show
  1. package/README.md +11 -69
  2. package/lib/commonjs/components/ConsoleIcon.js +1 -19
  3. package/lib/commonjs/components/ConsoleLogList.js +1 -152
  4. package/lib/commonjs/components/ConsoleModal.js +1 -48
  5. package/lib/commonjs/components/ConsoleRoot.js +1 -37
  6. package/lib/commonjs/devtools/ConsoleBody.js +1 -234
  7. package/lib/commonjs/devtools/ConsoleHeader.js +1 -114
  8. package/lib/commonjs/devtools/ConsoleMessageRow.js +1 -356
  9. package/lib/commonjs/devtools/ConsoleValue.js +1 -254
  10. package/lib/commonjs/devtools/ConsoleView.js +1 -54
  11. package/lib/commonjs/devtools/consoleFilter.js +1 -125
  12. package/lib/commonjs/devtools/consoleFormat.js +1 -313
  13. package/lib/commonjs/devtools/origin.js +1 -191
  14. package/lib/commonjs/devtools/theme.js +1 -152
  15. package/lib/commonjs/devtools/useConsoleController.js +1 -82
  16. package/lib/commonjs/devtools/useConsoleMessages.js +1 -241
  17. package/lib/commonjs/hooks/useConsoleLogs.js +1 -23
  18. package/lib/commonjs/index.js +1 -181
  19. package/lib/commonjs/preset.js +1 -63
  20. package/lib/commonjs/store/consoleLogStore.js +6 -589
  21. package/lib/commonjs/store/sanitize.js +1 -83
  22. package/lib/commonjs/sync/consoleSyncAdapter.js +1 -86
  23. package/lib/module/components/ConsoleIcon.js +1 -12
  24. package/lib/module/components/ConsoleLogList.js +1 -147
  25. package/lib/module/components/ConsoleModal.js +1 -44
  26. package/lib/module/components/ConsoleRoot.js +1 -33
  27. package/lib/module/devtools/ConsoleBody.js +1 -229
  28. package/lib/module/devtools/ConsoleHeader.js +1 -109
  29. package/lib/module/devtools/ConsoleMessageRow.js +1 -352
  30. package/lib/module/devtools/ConsoleValue.js +1 -249
  31. package/lib/module/devtools/ConsoleView.js +1 -49
  32. package/lib/module/devtools/consoleFilter.js +1 -119
  33. package/lib/module/devtools/consoleFormat.js +1 -309
  34. package/lib/module/devtools/origin.js +1 -183
  35. package/lib/module/devtools/theme.js +1 -143
  36. package/lib/module/devtools/useConsoleController.js +1 -79
  37. package/lib/module/devtools/useConsoleMessages.js +1 -238
  38. package/lib/module/hooks/useConsoleLogs.js +1 -19
  39. package/lib/module/index.js +1 -52
  40. package/lib/module/preset.js +1 -61
  41. package/lib/module/store/consoleLogStore.js +6 -575
  42. package/lib/module/store/sanitize.js +1 -77
  43. package/lib/module/sync/consoleSyncAdapter.js +1 -82
  44. package/lib/web/index.mjs +11 -12
  45. package/package.json +2 -2
  46. package/lib/commonjs/components/ConsoleIcon.js.map +0 -1
  47. package/lib/commonjs/components/ConsoleLogList.js.map +0 -1
  48. package/lib/commonjs/components/ConsoleModal.js.map +0 -1
  49. package/lib/commonjs/components/ConsoleRoot.js.map +0 -1
  50. package/lib/commonjs/devtools/ConsoleBody.js.map +0 -1
  51. package/lib/commonjs/devtools/ConsoleHeader.js.map +0 -1
  52. package/lib/commonjs/devtools/ConsoleMessageRow.js.map +0 -1
  53. package/lib/commonjs/devtools/ConsoleValue.js.map +0 -1
  54. package/lib/commonjs/devtools/ConsoleView.js.map +0 -1
  55. package/lib/commonjs/devtools/consoleFilter.js.map +0 -1
  56. package/lib/commonjs/devtools/consoleFormat.js.map +0 -1
  57. package/lib/commonjs/devtools/origin.js.map +0 -1
  58. package/lib/commonjs/devtools/theme.js.map +0 -1
  59. package/lib/commonjs/devtools/useConsoleController.js.map +0 -1
  60. package/lib/commonjs/devtools/useConsoleMessages.js.map +0 -1
  61. package/lib/commonjs/hooks/useConsoleLogs.js.map +0 -1
  62. package/lib/commonjs/index.js.map +0 -1
  63. package/lib/commonjs/preset.js.map +0 -1
  64. package/lib/commonjs/store/consoleLogStore.js.map +0 -1
  65. package/lib/commonjs/store/sanitize.js.map +0 -1
  66. package/lib/commonjs/sync/consoleSyncAdapter.js.map +0 -1
  67. package/lib/module/components/ConsoleIcon.js.map +0 -1
  68. package/lib/module/components/ConsoleLogList.js.map +0 -1
  69. package/lib/module/components/ConsoleModal.js.map +0 -1
  70. package/lib/module/components/ConsoleRoot.js.map +0 -1
  71. package/lib/module/devtools/ConsoleBody.js.map +0 -1
  72. package/lib/module/devtools/ConsoleHeader.js.map +0 -1
  73. package/lib/module/devtools/ConsoleMessageRow.js.map +0 -1
  74. package/lib/module/devtools/ConsoleValue.js.map +0 -1
  75. package/lib/module/devtools/ConsoleView.js.map +0 -1
  76. package/lib/module/devtools/consoleFilter.js.map +0 -1
  77. package/lib/module/devtools/consoleFormat.js.map +0 -1
  78. package/lib/module/devtools/origin.js.map +0 -1
  79. package/lib/module/devtools/theme.js.map +0 -1
  80. package/lib/module/devtools/useConsoleController.js.map +0 -1
  81. package/lib/module/devtools/useConsoleMessages.js.map +0 -1
  82. package/lib/module/hooks/useConsoleLogs.js.map +0 -1
  83. package/lib/module/index.js.map +0 -1
  84. package/lib/module/preset.js.map +0 -1
  85. package/lib/module/store/consoleLogStore.js.map +0 -1
  86. package/lib/module/store/sanitize.js.map +0 -1
  87. package/lib/module/sync/consoleSyncAdapter.js.map +0 -1
  88. package/lib/typescript/components/ConsoleIcon.d.ts.map +0 -1
  89. package/lib/typescript/components/ConsoleLogList.d.ts.map +0 -1
  90. package/lib/typescript/components/ConsoleModal.d.ts.map +0 -1
  91. package/lib/typescript/components/ConsoleRoot.d.ts.map +0 -1
  92. package/lib/typescript/devtools/ConsoleBody.d.ts.map +0 -1
  93. package/lib/typescript/devtools/ConsoleHeader.d.ts.map +0 -1
  94. package/lib/typescript/devtools/ConsoleMessageRow.d.ts.map +0 -1
  95. package/lib/typescript/devtools/ConsoleValue.d.ts.map +0 -1
  96. package/lib/typescript/devtools/ConsoleView.d.ts.map +0 -1
  97. package/lib/typescript/devtools/consoleFilter.d.ts.map +0 -1
  98. package/lib/typescript/devtools/consoleFormat.d.ts.map +0 -1
  99. package/lib/typescript/devtools/origin.d.ts.map +0 -1
  100. package/lib/typescript/devtools/theme.d.ts.map +0 -1
  101. package/lib/typescript/devtools/useConsoleController.d.ts.map +0 -1
  102. package/lib/typescript/devtools/useConsoleMessages.d.ts.map +0 -1
  103. package/lib/typescript/hooks/useConsoleLogs.d.ts.map +0 -1
  104. package/lib/typescript/index.d.ts.map +0 -1
  105. package/lib/typescript/preset.d.ts.map +0 -1
  106. package/lib/typescript/store/consoleLogStore.d.ts.map +0 -1
  107. package/lib/typescript/store/sanitize.d.ts.map +0 -1
  108. package/lib/typescript/sync/consoleSyncAdapter.d.ts.map +0 -1
@@ -1,109 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * ConsoleHeader — the Console tool's header, built from the shared ModalHeader
5
- * pattern so it matches Network/Events 1:1. Controls live here: the
6
- * Timeline/Grouped TabSelector (or the search field when active), plus action
7
- * icons for search, level filter, clear, and settings. Tapping the level/filter
8
- * or settings icon swaps the body to a back-navigable sub-view.
9
- */
10
-
11
- import React from "react";
12
- import { TouchableOpacity, StyleSheet } from "react-native";
13
- import { ModalHeader, TabSelector, night, Search, Filter, Trash2 } from "@buoy-gg/shared-ui";
14
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
- const LAYOUT_TABS = [{
16
- key: "chrono",
17
- label: "Timeline"
18
- }, {
19
- key: "cluster",
20
- label: "Grouped"
21
- }];
22
- export function ConsoleHeader({
23
- c,
24
- onBack
25
- }) {
26
- // Filters sub-view: a back chevron returns to the list.
27
- if (c.view === "filters") {
28
- return /*#__PURE__*/_jsxs(ModalHeader, {
29
- children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
30
- onBack: () => c.setView("list")
31
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
32
- title: "Filters"
33
- })]
34
- });
35
- }
36
- const hasRows = c.rows.length > 0;
37
- return /*#__PURE__*/_jsxs(ModalHeader, {
38
- children: [onBack ? /*#__PURE__*/_jsx(ModalHeader.Navigation, {
39
- onBack: onBack
40
- }) : null, /*#__PURE__*/_jsx(ModalHeader.Content, {
41
- title: "",
42
- noMargin: true,
43
- children: c.searchActive ? /*#__PURE__*/_jsx(ModalHeader.Search, {
44
- value: c.query,
45
- onChangeText: c.setQuery
46
- // The ✕ only clears; submit is what closes the field.
47
- ,
48
- onCancel: () => c.setQuery(""),
49
- clearOnlyWhenText: true,
50
- placeholder: "Filter logs\u2026 /regex/ -exclude",
51
- iconSize: 14,
52
- inputProps: {
53
- onSubmitEditing: () => c.setSearchActive(false)
54
- }
55
- }) : /*#__PURE__*/_jsx(TabSelector, {
56
- tabs: LAYOUT_TABS,
57
- activeTab: c.layoutMode,
58
- onTabChange: key => c.setLayoutMode(key)
59
- })
60
- }), /*#__PURE__*/_jsxs(ModalHeader.Actions, {
61
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
62
- onPress: () => c.setSearchActive(a => !a),
63
- style: [styles.actionBtn, c.searchActive && styles.actionBtnActive],
64
- accessibilityLabel: "Search logs",
65
- children: /*#__PURE__*/_jsx(Search, {
66
- size: 14,
67
- color: c.searchActive ? night.color.accent : night.color.textSecondary
68
- })
69
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
70
- onPress: () => c.setView("filters"),
71
- style: [styles.actionBtn, c.isLevelCustom && styles.actionBtnActive],
72
- accessibilityLabel: "Filters",
73
- children: /*#__PURE__*/_jsx(Filter, {
74
- size: 14,
75
- color: c.isLevelCustom ? night.color.accent : night.color.textSecondary
76
- })
77
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
78
- onPress: c.clear,
79
- disabled: !hasRows,
80
- style: [styles.actionBtn, !hasRows && styles.actionBtnDisabled],
81
- accessibilityLabel: "Clear console",
82
- children: /*#__PURE__*/_jsx(Trash2, {
83
- size: 14,
84
- color: hasRows ? night.color.textSecondary : night.color.textTertiary
85
- })
86
- })]
87
- })]
88
- });
89
- }
90
- const styles = StyleSheet.create({
91
- actionBtn: {
92
- width: 32,
93
- height: 32,
94
- borderRadius: 8,
95
- backgroundColor: night.color.buttonSurface,
96
- borderWidth: 1,
97
- borderColor: night.color.border,
98
- alignItems: "center",
99
- justifyContent: "center"
100
- },
101
- actionBtnActive: {
102
- backgroundColor: night.color.accentSoft,
103
- borderColor: night.color.accentBorderStrong
104
- },
105
- actionBtnDisabled: {
106
- opacity: 0.55
107
- }
108
- });
109
- //# sourceMappingURL=ConsoleHeader.js.map
1
+ "use strict";import v from"react";import{TouchableOpacity as a,StyleSheet as d}from"react-native";import{ModalHeader as r,TabSelector as h,night as o,Search as u,Filter as b,Trash2 as y}from"@buoy-gg/shared-ui";import{jsx as t,jsxs as c}from"react/jsx-runtime";const S=[{key:"chrono",label:"Timeline"},{key:"cluster",label:"Grouped"}];export function ConsoleHeader({c:e,onBack:s}){if(e.view==="filters"){return c(r,{children:[t(r.Navigation,{onBack:()=>e.setView("list")}),t(r.Content,{title:"Filters"})]})}const n=e.rows.length>0;return c(r,{children:[s?t(r.Navigation,{onBack:s}):null,t(r.Content,{title:"",noMargin:true,children:e.searchActive?t(r.Search,{value:e.query,onChangeText:e.setQuery,onCancel:()=>e.setQuery(""),clearOnlyWhenText:true,placeholder:"Filter logs\u2026 /regex/ -exclude",iconSize:14,inputProps:{onSubmitEditing:()=>e.setSearchActive(false)}}):t(h,{tabs:S,activeTab:e.layoutMode,onTabChange:l=>e.setLayoutMode(l)})}),c(r.Actions,{children:[t(a,{onPress:()=>e.setSearchActive(l=>!l),style:[i.actionBtn,e.searchActive&&i.actionBtnActive],accessibilityLabel:"Search logs",children:t(u,{size:14,color:e.searchActive?o.color.accent:o.color.textSecondary})}),t(a,{onPress:()=>e.setView("filters"),style:[i.actionBtn,e.isLevelCustom&&i.actionBtnActive],accessibilityLabel:"Filters",children:t(b,{size:14,color:e.isLevelCustom?o.color.accent:o.color.textSecondary})}),t(a,{onPress:e.clear,disabled:!n,style:[i.actionBtn,!n&&i.actionBtnDisabled],accessibilityLabel:"Clear console",children:t(y,{size:14,color:n?o.color.textSecondary:o.color.textTertiary})})]})]})}const i=d.create({actionBtn:{width:32,height:32,borderRadius:8,backgroundColor:o.color.buttonSurface,borderWidth:1,borderColor:o.color.border,alignItems:"center",justifyContent:"center"},actionBtnActive:{backgroundColor:o.color.accentSoft,borderColor:o.color.accentBorderStrong},actionBtnDisabled:{opacity:.55}});
@@ -1,352 +1 @@
1
- "use strict";
2
-
3
- import { memo } from "react";
4
- /**
5
- * ConsoleMessageRow — RN port of a single DevTools `.console-message-wrapper`.
6
- *
7
- * Anatomy (mirrors ConsoleViewMessage):
8
- * [nesting markers] [group triangle] [level icon] [timestamp] [content] [repeat badge]
9
- * Error/warning rows get the surface background + text colors; non-error/warning
10
- * rows get a hairline top divider. Group headers show a bold title with an
11
- * expand triangle; error/warn/trace rows can expand a captured stack trace.
12
- */
13
-
14
- import React, { useState } from "react";
15
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
16
- import { consoleTheme, levelStyles, monoFont } from "./theme";
17
- import { formatConsoleMessage } from "./consoleFormat";
18
- import { ConsoleValue } from "./ConsoleValue";
19
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
- function formatTimestamp(ts) {
21
- const d = new Date(ts);
22
- const pad = (n, len = 2) => String(n).padStart(len, "0");
23
- return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`;
24
- }
25
-
26
- /** Small filled level glyph (warning triangle / error cross), DevTools-style. */
27
- function LevelIcon({
28
- icon,
29
- color
30
- }) {
31
- return /*#__PURE__*/_jsx(Text, {
32
- style: [styles.levelIcon, {
33
- color
34
- }],
35
- children: icon === "warning" ? "⚠" : "⊘"
36
- });
37
- }
38
-
39
- /** The repeat-count bubble (dt-small-bubble). */
40
- function RepeatBadge({
41
- count,
42
- color
43
- }) {
44
- return /*#__PURE__*/_jsx(View, {
45
- style: [styles.repeatBadge, {
46
- borderColor: color
47
- }],
48
- children: /*#__PURE__*/_jsx(Text, {
49
- style: [styles.repeatBadgeText, {
50
- color
51
- }],
52
- children: count
53
- })
54
- });
55
- }
56
- // Memo with a precise comparator, justified by profiling (tool-bench
57
- // 2026-07-06): ~30 windowed rows re-rendered on every commit (172 row
58
- // renders in a 5s dwell) because buildDisplayRows recreates row OBJECTS
59
- // each emission — so default shallow compare can never bail. Entries are
60
- // immutable; the comparator lists every display-affecting row field.
61
- export const ConsoleMessageRow = /*#__PURE__*/memo(function ConsoleMessageRow({
62
- row,
63
- showTimestamps,
64
- onToggleGroup,
65
- onToggleCluster
66
- }) {
67
- const {
68
- entry
69
- } = row;
70
- const level = levelStyles[entry.level];
71
- const isErrorOrWarn = entry.level === "error" || entry.level === "warning";
72
- const textColor = level.text;
73
- // One "open" state per row: shows the stack trace (when there is one) AND
74
- // lifts the single-line clamp so long/structured messages stay reachable.
75
- const [expanded, setExpanded] = useState(entry.method === "trace");
76
-
77
- // Collapsed/large cluster header (Grouped mode): tap to expand/collapse.
78
- if (row.clusterHeader) {
79
- const ch = row.clusterHeader;
80
- return /*#__PURE__*/_jsx(TouchableOpacity, {
81
- style: [styles.wrapper, styles.dividerTop],
82
- activeOpacity: 0.7,
83
- onPress: () => onToggleCluster(ch.key),
84
- children: /*#__PURE__*/_jsxs(View, {
85
- style: styles.rowWrapper,
86
- children: [/*#__PURE__*/_jsx(Text, {
87
- style: [styles.originGutter, {
88
- color: row.originColor
89
- }],
90
- children: ch.expanded ? "▼" : "▶"
91
- }), /*#__PURE__*/_jsx(View, {
92
- style: styles.messageColumn,
93
- children: /*#__PURE__*/_jsxs(View, {
94
- style: styles.messageLine,
95
- children: [/*#__PURE__*/_jsx(Text, {
96
- style: [styles.text, styles.clusterTitle, {
97
- color: row.originColor
98
- }],
99
- children: row.originLabel
100
- }), /*#__PURE__*/_jsxs(Text, {
101
- style: styles.clusterCount,
102
- children: [" \xB7 ", ch.count, " logs"]
103
- })]
104
- })
105
- })]
106
- })
107
- });
108
- }
109
- const tokens = formatConsoleMessage(entry.args);
110
- const hasStack = Boolean(entry.stack) && (isErrorOrWarn || entry.method === "trace");
111
- const content = /*#__PURE__*/_jsx(View, {
112
- style: [styles.contentWrap, !expanded && styles.contentWrapClamped],
113
- children: tokens.map((token, i) => token.type === "string" ? /*#__PURE__*/_jsx(Text, {
114
- style: [styles.text, {
115
- color: textColor
116
- }, row.isGroupHeader && styles.groupTitle, token.style],
117
- children: token.value
118
- }, i) : /*#__PURE__*/_jsx(ConsoleValue, {
119
- value: token.value,
120
- generic: token.mode === "generic"
121
- }, i))
122
- });
123
- const inner = /*#__PURE__*/_jsxs(View, {
124
- style: styles.messageColumn,
125
- children: [row.originLabel ? /*#__PURE__*/_jsx(Text, {
126
- style: [styles.originLabel, {
127
- color: row.originColor
128
- }],
129
- numberOfLines: 1,
130
- children: row.originLabel
131
- }) : null, /*#__PURE__*/_jsxs(View, {
132
- style: styles.messageLine,
133
- children: [row.isGroupHeader ? /*#__PURE__*/_jsx(Text, {
134
- style: [styles.groupTriangle, {
135
- color: textColor
136
- }],
137
- children: row.groupCollapsed ? "▶" : "▼"
138
- }) : null, level.icon ? /*#__PURE__*/_jsx(LevelIcon, {
139
- icon: level.icon,
140
- color: textColor
141
- }) : null, showTimestamps ? /*#__PURE__*/_jsx(Text, {
142
- style: styles.timestamp,
143
- children: formatTimestamp(entry.timestamp)
144
- }) : null, hasStack ? /*#__PURE__*/_jsx(Text, {
145
- style: [styles.stackTriangle, {
146
- color: textColor
147
- }],
148
- children: expanded ? "▼" : "▶"
149
- }) : null, content, row.repeatCount > 1 ? /*#__PURE__*/_jsx(RepeatBadge, {
150
- count: row.repeatCount,
151
- color: textColor
152
- }) : null]
153
- }), hasStack && expanded ? /*#__PURE__*/_jsx(View, {
154
- style: styles.stackTrace,
155
- children: (entry.stack ?? "").split("\n").filter(l => l.trim()).map((line, i) => /*#__PURE__*/_jsx(Text, {
156
- style: styles.stackFrame,
157
- children: line.trim()
158
- }, i))
159
- }) : null]
160
- });
161
- const rowStyle = [styles.wrapper, level.background ? {
162
- backgroundColor: level.background
163
- } : styles.dividerTop];
164
-
165
- // Nesting indentation markers.
166
- const markers = Array.from({
167
- length: row.depth
168
- }, (_, i) => /*#__PURE__*/_jsx(View, {
169
- style: styles.nestingMarker
170
- }, i));
171
-
172
- // Origin gutter: swimlane columns (multi-track) or a single bracket.
173
- const gutter = row.lanes ? /*#__PURE__*/_jsx(View, {
174
- style: styles.laneGutter,
175
- children: row.lanes.map((cell, i) => /*#__PURE__*/_jsx(Text, {
176
- style: [styles.laneCell, cell.color ? {
177
- color: cell.color
178
- } : null],
179
- children: cell.glyph
180
- }, i))
181
- }) : row.bracketGlyph ? /*#__PURE__*/_jsx(Text, {
182
- style: [styles.originGutter, {
183
- color: row.originColor
184
- }],
185
- children: row.bracketGlyph
186
- }) : null;
187
- const body = /*#__PURE__*/_jsxs(View, {
188
- style: styles.rowWrapper,
189
- children: [gutter, markers, inner]
190
- });
191
- const rowTestID = `buoy-console-row-${entry.id}`;
192
- const rowLabel = [row.originLabel, tokens.find(t => t.type === "string")?.value].filter(Boolean).join(" — ").slice(0, 80);
193
-
194
- // Group headers and stack-bearing rows are pressable.
195
- if (row.isGroupHeader && row.groupId !== undefined) {
196
- const gid = row.groupId;
197
- return /*#__PURE__*/_jsx(TouchableOpacity, {
198
- style: rowStyle,
199
- activeOpacity: 0.7,
200
- onPress: () => onToggleGroup(gid, Boolean(row.groupCollapsed)),
201
- testID: rowTestID,
202
- accessibilityLabel: rowLabel || "Console group",
203
- children: body
204
- });
205
- }
206
- // Every other row toggles expanded on tap — the collapsed line is clamped
207
- // to a single line, so the tap is the way to read a long/structured log.
208
- return /*#__PURE__*/_jsx(TouchableOpacity, {
209
- style: rowStyle,
210
- activeOpacity: 0.7,
211
- onPress: () => setExpanded(o => !o),
212
- testID: rowTestID,
213
- accessibilityLabel: rowLabel || "Console message",
214
- children: body
215
- });
216
- }, (prev, next) => prev.row.key === next.row.key &&
217
- // Reference check: swimlane gutter cells are rebuilt per emission, so
218
- // swimlane mode simply keeps its previous (correct) behavior.
219
- prev.row.lanes === next.row.lanes && prev.row.repeatCount === next.row.repeatCount && prev.row.groupCollapsed === next.row.groupCollapsed && prev.row.depth === next.row.depth && prev.row.bracketGlyph === next.row.bracketGlyph && prev.row.originLabel === next.row.originLabel && prev.row.clusterHeader?.count === next.row.clusterHeader?.count && prev.row.clusterHeader?.expanded === next.row.clusterHeader?.expanded && prev.showTimestamps === next.showTimestamps && prev.onToggleGroup === next.onToggleGroup && prev.onToggleCluster === next.onToggleCluster);
220
- const styles = StyleSheet.create({
221
- wrapper: {
222
- paddingVertical: 2,
223
- paddingRight: 8,
224
- minHeight: 18
225
- },
226
- dividerTop: {
227
- borderTopWidth: StyleSheet.hairlineWidth,
228
- borderTopColor: consoleTheme.divider
229
- },
230
- rowWrapper: {
231
- flexDirection: "row",
232
- alignItems: "flex-start"
233
- },
234
- originGutter: {
235
- width: 11,
236
- fontFamily: monoFont,
237
- fontSize: 13,
238
- lineHeight: 18,
239
- textAlign: "center"
240
- },
241
- laneGutter: {
242
- flexDirection: "row"
243
- },
244
- laneCell: {
245
- width: 9,
246
- fontFamily: monoFont,
247
- fontSize: 13,
248
- lineHeight: 18,
249
- textAlign: "center"
250
- },
251
- originLabel: {
252
- fontFamily: monoFont,
253
- fontSize: 10,
254
- lineHeight: 16,
255
- marginBottom: 1,
256
- opacity: 0.9
257
- },
258
- nestingMarker: {
259
- width: 14,
260
- alignSelf: "stretch",
261
- borderRightWidth: StyleSheet.hairlineWidth,
262
- borderRightColor: consoleTheme.divider,
263
- marginLeft: 2
264
- },
265
- messageColumn: {
266
- flex: 1,
267
- flexDirection: "column",
268
- paddingLeft: 6
269
- },
270
- messageLine: {
271
- flexDirection: "row",
272
- flexWrap: "wrap",
273
- alignItems: "flex-start"
274
- },
275
- contentWrap: {
276
- flexDirection: "row",
277
- flexWrap: "wrap",
278
- alignItems: "flex-start",
279
- flexShrink: 1
280
- },
281
- // Collapsed rows clamp to one line; tap the row to expand.
282
- contentWrapClamped: {
283
- flexWrap: "nowrap",
284
- overflow: "hidden",
285
- maxHeight: 16
286
- },
287
- text: {
288
- fontFamily: monoFont,
289
- fontSize: 12,
290
- lineHeight: 16
291
- },
292
- groupTitle: {
293
- fontWeight: "bold"
294
- },
295
- clusterTitle: {
296
- fontWeight: "600"
297
- },
298
- clusterCount: {
299
- color: consoleTheme.tokenSubtle,
300
- fontFamily: monoFont,
301
- fontSize: 12,
302
- lineHeight: 16
303
- },
304
- groupTriangle: {
305
- fontSize: 9,
306
- lineHeight: 16,
307
- marginRight: 4
308
- },
309
- stackTriangle: {
310
- fontSize: 8,
311
- lineHeight: 16,
312
- marginRight: 4
313
- },
314
- levelIcon: {
315
- fontSize: 12,
316
- lineHeight: 16,
317
- marginRight: 5
318
- },
319
- timestamp: {
320
- color: consoleTheme.tokenSubtle,
321
- fontFamily: monoFont,
322
- fontSize: 11,
323
- lineHeight: 16,
324
- marginRight: 6
325
- },
326
- repeatBadge: {
327
- borderWidth: 1,
328
- borderRadius: 9,
329
- paddingHorizontal: 5,
330
- minWidth: 16,
331
- alignItems: "center",
332
- justifyContent: "center",
333
- marginLeft: 6,
334
- marginTop: 1
335
- },
336
- repeatBadgeText: {
337
- fontSize: 10,
338
- fontWeight: "700",
339
- lineHeight: 14
340
- },
341
- stackTrace: {
342
- marginTop: 2,
343
- marginLeft: 12
344
- },
345
- stackFrame: {
346
- color: consoleTheme.tokenSubtle,
347
- fontFamily: monoFont,
348
- fontSize: 11,
349
- lineHeight: 15
350
- }
351
- });
352
- //# sourceMappingURL=ConsoleMessageRow.js.map
1
+ "use strict";import{memo as v}from"react";import V,{useState as B}from"react";import{View as i,Text as n,TouchableOpacity as b,StyleSheet as C}from"react-native";import{consoleTheme as m,levelStyles as F,monoFont as c}from"./theme";import{formatConsoleMessage as D}from"./consoleFormat";import{ConsoleValue as M}from"./ConsoleValue";import{jsx as o,jsxs as d}from"react/jsx-runtime";function j(l){const e=new Date(l);const g=(h,f=2)=>String(h).padStart(f,"0");return`${g(e.getHours())}:${g(e.getMinutes())}:${g(e.getSeconds())}.${g(e.getMilliseconds(),3)}`}function O({icon:l,color:e}){return o(n,{style:[t.levelIcon,{color:e}],children:l==="warning"?"\u26A0":"\u2298"})}function $({count:l,color:e}){return o(i,{style:[t.repeatBadge,{borderColor:e}],children:o(n,{style:[t.repeatBadgeText,{color:e}],children:l})})}export const ConsoleMessageRow=v(function l({row:e,showTimestamps:g,onToggleGroup:h,onToggleCluster:f}){const{entry:a}=e;const p=F[a.level];const L=a.level==="error"||a.level==="warning";const u=p.text;const[y,W]=B(a.method==="trace");if(e.clusterHeader){const r=e.clusterHeader;return o(b,{style:[t.wrapper,t.dividerTop],activeOpacity:.7,onPress:()=>f(r.key),children:d(i,{style:t.rowWrapper,children:[o(n,{style:[t.originGutter,{color:e.originColor}],children:r.expanded?"\u25BC":"\u25B6"}),o(i,{style:t.messageColumn,children:d(i,{style:t.messageLine,children:[o(n,{style:[t.text,t.clusterTitle,{color:e.originColor}],children:e.originLabel}),d(n,{style:t.clusterCount,children:[" \xB7 ",r.count," logs"]})]})})]})})}const T=D(a.args);const S=Boolean(a.stack)&&(L||a.method==="trace");const G=o(i,{style:[t.contentWrap,!y&&t.contentWrapClamped],children:T.map((r,s)=>r.type==="string"?o(n,{style:[t.text,{color:u},e.isGroupHeader&&t.groupTitle,r.style],children:r.value},s):o(M,{value:r.value,generic:r.mode==="generic"},s))});const z=d(i,{style:t.messageColumn,children:[e.originLabel?o(n,{style:[t.originLabel,{color:e.originColor}],numberOfLines:1,children:e.originLabel}):null,d(i,{style:t.messageLine,children:[e.isGroupHeader?o(n,{style:[t.groupTriangle,{color:u}],children:e.groupCollapsed?"\u25B6":"\u25BC"}):null,p.icon?o(O,{icon:p.icon,color:u}):null,g?o(n,{style:t.timestamp,children:j(a.timestamp)}):null,S?o(n,{style:[t.stackTriangle,{color:u}],children:y?"\u25BC":"\u25B6"}):null,G,e.repeatCount>1?o($,{count:e.repeatCount,color:u}):null]}),S&&y?o(i,{style:t.stackTrace,children:(a.stack??"").split("\n").filter(r=>r.trim()).map((r,s)=>o(n,{style:t.stackFrame,children:r.trim()},s))}):null]});const x=[t.wrapper,p.background?{backgroundColor:p.background}:t.dividerTop];const I=Array.from({length:e.depth},(r,s)=>o(i,{style:t.nestingMarker},s));const R=e.lanes?o(i,{style:t.laneGutter,children:e.lanes.map((r,s)=>o(n,{style:[t.laneCell,r.color?{color:r.color}:null],children:r.glyph},s))}):e.bracketGlyph?o(n,{style:[t.originGutter,{color:e.originColor}],children:e.bracketGlyph}):null;const H=d(i,{style:t.rowWrapper,children:[R,I,z]});const k=`buoy-console-row-${a.id}`;const w=[e.originLabel,T.find(r=>r.type==="string")?.value].filter(Boolean).join(" \u2014 ").slice(0,80);if(e.isGroupHeader&&e.groupId!==void 0){const r=e.groupId;return o(b,{style:x,activeOpacity:.7,onPress:()=>h(r,Boolean(e.groupCollapsed)),testID:k,accessibilityLabel:w||"Console group",children:H})}return o(b,{style:x,activeOpacity:.7,onPress:()=>W(r=>!r),testID:k,accessibilityLabel:w||"Console message",children:H})},(l,e)=>l.row.key===e.row.key&&l.row.lanes===e.row.lanes&&l.row.repeatCount===e.row.repeatCount&&l.row.groupCollapsed===e.row.groupCollapsed&&l.row.depth===e.row.depth&&l.row.bracketGlyph===e.row.bracketGlyph&&l.row.originLabel===e.row.originLabel&&l.row.clusterHeader?.count===e.row.clusterHeader?.count&&l.row.clusterHeader?.expanded===e.row.clusterHeader?.expanded&&l.showTimestamps===e.showTimestamps&&l.onToggleGroup===e.onToggleGroup&&l.onToggleCluster===e.onToggleCluster);const t=C.create({wrapper:{paddingVertical:2,paddingRight:8,minHeight:18},dividerTop:{borderTopWidth:C.hairlineWidth,borderTopColor:m.divider},rowWrapper:{flexDirection:"row",alignItems:"flex-start"},originGutter:{width:11,fontFamily:c,fontSize:13,lineHeight:18,textAlign:"center"},laneGutter:{flexDirection:"row"},laneCell:{width:9,fontFamily:c,fontSize:13,lineHeight:18,textAlign:"center"},originLabel:{fontFamily:c,fontSize:10,lineHeight:16,marginBottom:1,opacity:.9},nestingMarker:{width:14,alignSelf:"stretch",borderRightWidth:C.hairlineWidth,borderRightColor:m.divider,marginLeft:2},messageColumn:{flex:1,flexDirection:"column",paddingLeft:6},messageLine:{flexDirection:"row",flexWrap:"wrap",alignItems:"flex-start"},contentWrap:{flexDirection:"row",flexWrap:"wrap",alignItems:"flex-start",flexShrink:1},contentWrapClamped:{flexWrap:"nowrap",overflow:"hidden",maxHeight:16},text:{fontFamily:c,fontSize:12,lineHeight:16},groupTitle:{fontWeight:"bold"},clusterTitle:{fontWeight:"600"},clusterCount:{color:m.tokenSubtle,fontFamily:c,fontSize:12,lineHeight:16},groupTriangle:{fontSize:9,lineHeight:16,marginRight:4},stackTriangle:{fontSize:8,lineHeight:16,marginRight:4},levelIcon:{fontSize:12,lineHeight:16,marginRight:5},timestamp:{color:m.tokenSubtle,fontFamily:c,fontSize:11,lineHeight:16,marginRight:6},repeatBadge:{borderWidth:1,borderRadius:9,paddingHorizontal:5,minWidth:16,alignItems:"center",justifyContent:"center",marginLeft:6,marginTop:1},repeatBadgeText:{fontSize:10,fontWeight:"700",lineHeight:14},stackTrace:{marginTop:2,marginLeft:12},stackFrame:{color:m.tokenSubtle,fontFamily:c,fontSize:11,lineHeight:15}});