@buoy-gg/console 7.0.41 → 7.0.43

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 +3 -6
  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,79 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * useConsoleController — owns all Console view state so the header and the body
5
- * can be composed separately (the shared ModalHeader pattern: controls live in
6
- * the modal header's `customContent`, the list/sub-views live in the body).
7
- */
8
-
9
- import { useCallback, useState } from "react";
10
- import { useConsoleMessages } from "./useConsoleMessages";
11
- import { DEFAULT_LEVELS, levelMenuSummary } from "./consoleFilter";
12
- import { clearEntries } from "../store/consoleLogStore";
13
-
14
- /** Which screen the modal body shows (list, or the back-navigable filters page). */
15
-
16
- export function useConsoleController() {
17
- const [query, setQuery] = useState("");
18
- const [searchActive, setSearchActive] = useState(false);
19
- const [levelsMask, setLevelsMask] = useState({
20
- ...DEFAULT_LEVELS
21
- });
22
- const [showTimestamps, setShowTimestamps] = useState(false);
23
- const [collapsedOverrides, setCollapsedOverrides] = useState({});
24
- const [layoutMode, setLayoutMode] = useState("chrono");
25
- const [view, setView] = useState("list");
26
- const [clusterExpanded, setClusterExpanded] = useState({});
27
- const {
28
- rows,
29
- hiddenCount
30
- } = useConsoleMessages({
31
- levelsMask,
32
- query,
33
- showTimestamps,
34
- collapsedOverrides,
35
- groupDimension: "function",
36
- layoutMode,
37
- clusterExpanded
38
- });
39
- const onToggleGroup = useCallback((groupId, currentlyCollapsed) => {
40
- setCollapsedOverrides(prev => ({
41
- ...prev,
42
- [groupId]: !currentlyCollapsed
43
- }));
44
- }, []);
45
- const onToggleCluster = useCallback(key => {
46
- setClusterExpanded(prev => ({
47
- ...prev,
48
- [key]: !(prev[key] ?? false)
49
- }));
50
- }, []);
51
- const clear = useCallback(() => {
52
- clearEntries();
53
- setCollapsedOverrides({});
54
- }, []);
55
- const levelSummary = levelMenuSummary(levelsMask);
56
- const isLevelCustom = levelSummary !== "All levels" && levelSummary !== "Default levels";
57
- return {
58
- query,
59
- setQuery,
60
- searchActive,
61
- setSearchActive,
62
- levelsMask,
63
- setLevelsMask,
64
- showTimestamps,
65
- setShowTimestamps,
66
- layoutMode,
67
- setLayoutMode,
68
- view,
69
- setView,
70
- rows,
71
- hiddenCount,
72
- onToggleGroup,
73
- onToggleCluster,
74
- clear,
75
- levelSummary,
76
- isLevelCustom
77
- };
78
- }
79
- //# sourceMappingURL=useConsoleController.js.map
1
+ "use strict";import{useCallback as n,useState as e}from"react";import{useConsoleMessages as D}from"./useConsoleMessages";import{DEFAULT_LEVELS as k,levelMenuSummary as O}from"./consoleFilter";import{clearEntries as V}from"../store/consoleLogStore";export function useConsoleController(){const[r,i]=e("");const[m,d]=e(false);const[t,p]=e({...k});const[c,v]=e(false);const[f,a]=e({});const[u,C]=e("chrono");const[g,h]=e("list");const[E,L]=e({});const{rows:M,hiddenCount:S}=D({levelsMask:t,query:r,showTimestamps:c,collapsedOverrides:f,groupDimension:"function",layoutMode:u,clusterExpanded:E});const w=n((s,o)=>{a(x=>({...x,[s]:!o}))},[]);const y=n(s=>{L(o=>({...o,[s]:!(o[s]??false)}))},[]);const T=n(()=>{V();a({})},[]);const l=O(t);const A=l!=="All levels"&&l!=="Default levels";return{query:r,setQuery:i,searchActive:m,setSearchActive:d,levelsMask:t,setLevelsMask:p,showTimestamps:c,setShowTimestamps:v,layoutMode:u,setLayoutMode:C,view:g,setView:h,rows:M,hiddenCount:S,onToggleGroup:w,onToggleCluster:y,clear:T,levelSummary:l,isLevelCustom:A}}
@@ -1,238 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * useConsoleMessages — derives the displayed row model from raw captured
5
- * entries, mirroring DevTools `ConsoleView.updateMessageList`:
6
- *
7
- * - level + text filtering (consoleFilter)
8
- * - consecutive-identical collapse into a repeat-count badge (when timestamps
9
- * are off, matching `tryToCollapseMessages`)
10
- * - console.group / groupCollapsed nesting + collapse/expand
11
- *
12
- * Returns the visible rows plus the count of messages hidden by filters
13
- * ("N hidden"), and per-level totals for the toolbar.
14
- */
15
-
16
- import { useMemo, useSyncExternalStore } from "react";
17
- import { subscribe, getEntries } from "../store/consoleLogStore";
18
- import { parseFilterQuery, shouldBeVisible } from "./consoleFilter";
19
- import { sourceKey, sourceLabel, colorForKey, bracketGlyph } from "./origin";
20
-
21
- /** How the origin gutter is laid out. */
22
-
23
- /** One swimlane gutter cell. */
24
-
25
- const MAX_LANES = 5;
26
-
27
- /** Grouped mode collapses any source cluster larger than this into a header. */
28
- const CLUSTER_THRESHOLD = 5;
29
-
30
- /** First pass: tag each row with its origin source key, color, and label. */
31
- function computeSourceInfo(rows, dim) {
32
- for (const row of rows) {
33
- const key = sourceKey(row.entry.origin, dim);
34
- row.sourceKey = key;
35
- row.originColor = key ? colorForKey(key) : undefined;
36
- row.originLabel = dim === "off" ? undefined : sourceLabel(row.entry.origin, dim);
37
- }
38
- }
39
-
40
- /** lnav single-column gutter: bracket consecutive same-source runs. */
41
- function attachContiguousBrackets(rows) {
42
- for (let i = 0; i < rows.length; i++) {
43
- const key = rows[i].sourceKey;
44
- if (key == null) {
45
- rows[i].bracketGlyph = undefined;
46
- continue;
47
- }
48
- const sameAsPrev = i > 0 && rows[i - 1].sourceKey === key;
49
- const sameAsNext = i < rows.length - 1 && rows[i + 1].sourceKey === key;
50
- const bracket = !sameAsPrev && !sameAsNext ? "single" : !sameAsPrev ? "top" : !sameAsNext ? "bottom" : "mid";
51
- rows[i].bracketGlyph = bracketGlyph(bracket);
52
- }
53
- }
54
-
55
- /**
56
- * Re-order rows so all rows of one source are contiguous (groups ordered by
57
- * first appearance, chronological within each). Clusters larger than
58
- * CLUSTER_THRESHOLD collapse into a single expandable header (Chrome-style),
59
- * unless the user has expanded that cluster.
60
- */
61
- function clusterRows(rows, expanded) {
62
- const order = [];
63
- const groups = new Map();
64
- for (const r of rows) {
65
- const k = r.sourceKey ?? "—";
66
- let g = groups.get(k);
67
- if (!g) {
68
- g = [];
69
- groups.set(k, g);
70
- order.push(k);
71
- }
72
- g.push(r);
73
- }
74
- const out = [];
75
- for (const k of order) {
76
- const group = groups.get(k);
77
- for (const r of group) r.depth = 0; // clustering ignores console.group nesting
78
-
79
- const isLarge = group.length > CLUSTER_THRESHOLD;
80
- const isExpanded = expanded[k] ?? false;
81
- if (isLarge) {
82
- out.push({
83
- key: `cluster:${k}`,
84
- entry: group[0].entry,
85
- depth: 0,
86
- repeatCount: 1,
87
- isGroupHeader: false,
88
- sourceKey: k,
89
- originColor: group[0].originColor,
90
- originLabel: group[0].originLabel,
91
- clusterHeader: {
92
- key: k,
93
- count: group.length,
94
- expanded: isExpanded
95
- }
96
- });
97
- if (!isExpanded) continue;
98
- }
99
- group.forEach((r, i) => {
100
- const single = group.length === 1;
101
- const bracket = single ? "single" : i === 0 ? "top" : i === group.length - 1 ? "bottom" : "mid";
102
- r.bracketGlyph = bracketGlyph(bracket);
103
- out.push(r);
104
- });
105
- }
106
- return out;
107
- }
108
-
109
- /** Git-graph swimlanes: each source gets a continuous vertical track so its
110
- * line stays unbroken when other sources interrupt it. */
111
- function attachSwimlanes(rows) {
112
- const first = new Map();
113
- const last = new Map();
114
- rows.forEach((r, i) => {
115
- const k = r.sourceKey;
116
- if (k == null) return;
117
- if (!first.has(k)) first.set(k, i);
118
- last.set(k, i);
119
- });
120
-
121
- // Assign each source a lane, reusing a lane once its occupant's run ended.
122
- const sources = [...first.keys()].sort((a, b) => first.get(a) - first.get(b));
123
- const laneOf = new Map();
124
- const laneEnd = [];
125
- for (const s of sources) {
126
- let lane = laneEnd.findIndex(end => end < first.get(s));
127
- if (lane === -1) {
128
- lane = laneEnd.length < MAX_LANES ? laneEnd.length : MAX_LANES - 1;
129
- if (lane >= laneEnd.length) laneEnd.push(0);
130
- }
131
- laneOf.set(s, lane);
132
- laneEnd[lane] = Math.max(laneEnd[lane] ?? 0, last.get(s));
133
- }
134
- const laneCount = Math.max(1, Math.min(laneEnd.length, MAX_LANES));
135
- rows.forEach((r, i) => {
136
- const cells = Array.from({
137
- length: laneCount
138
- }, () => ({
139
- glyph: " "
140
- }));
141
- for (const s of sources) {
142
- const lane = laneOf.get(s);
143
- if (lane >= laneCount) continue;
144
- if (i >= first.get(s) && i <= last.get(s)) {
145
- cells[lane] = {
146
- glyph: r.sourceKey === s ? "●" : "│",
147
- color: colorForKey(s)
148
- };
149
- }
150
- }
151
- r.lanes = cells;
152
- });
153
- }
154
- const GROUP_STARTS = new Set(["group", "groupCollapsed"]);
155
- function buildDisplayRows(entries, opts) {
156
- const {
157
- levelsMask,
158
- query,
159
- showTimestamps,
160
- collapsedOverrides
161
- } = opts;
162
- const parsed = parseFilterQuery(query.trim());
163
- const rows = [];
164
- const levelCounts = {
165
- verbose: 0,
166
- info: 0,
167
- warning: 0,
168
- error: 0
169
- };
170
- let hiddenCount = 0;
171
- const stack = [];
172
- const anyAncestorCollapsed = () => stack.some(g => g.collapsed);
173
- for (const entry of entries) {
174
- levelCounts[entry.level]++;
175
- if (entry.method === "groupEnd") {
176
- stack.pop();
177
- continue;
178
- }
179
- const isHeader = GROUP_STARTS.has(entry.method);
180
- const hiddenByGroup = anyAncestorCollapsed();
181
- const passesFilter = shouldBeVisible(entry, levelsMask, parsed);
182
- if (!passesFilter) {
183
- hiddenCount++;
184
- } else if (!hiddenByGroup) {
185
- // Repeat-count collapse: only when timestamps are hidden and the previous
186
- // visible row is an identical, non-header message at the same depth.
187
- const prev = rows[rows.length - 1];
188
- if (!showTimestamps && !isHeader && prev && !prev.isGroupHeader && prev.depth === stack.length && prev.entry.method === entry.method && prev.entry.message === entry.message) {
189
- prev.repeatCount++;
190
- } else {
191
- rows.push({
192
- key: String(entry.id),
193
- entry,
194
- depth: stack.length,
195
- repeatCount: 1,
196
- isGroupHeader: isHeader,
197
- groupId: isHeader ? entry.id : undefined,
198
- groupCollapsed: undefined
199
- });
200
- }
201
- }
202
- if (isHeader) {
203
- const defaultCollapsed = entry.method === "groupCollapsed";
204
- const collapsed = collapsedOverrides[entry.id] ?? defaultCollapsed;
205
- // Record the collapse state on the just-pushed header row (if visible).
206
- const headerRow = rows[rows.length - 1];
207
- if (headerRow && headerRow.groupId === entry.id) {
208
- headerRow.groupCollapsed = collapsed;
209
- }
210
- stack.push({
211
- id: entry.id,
212
- collapsed: collapsed || hiddenByGroup
213
- });
214
- }
215
- }
216
- computeSourceInfo(rows, opts.groupDimension);
217
- let finalRows = rows;
218
- if (opts.groupDimension !== "off") {
219
- if (opts.layoutMode === "cluster") {
220
- finalRows = clusterRows(rows, opts.clusterExpanded);
221
- } else if (opts.layoutMode === "swimlane") {
222
- attachSwimlanes(rows);
223
- } else {
224
- attachContiguousBrackets(rows);
225
- }
226
- }
227
- return {
228
- rows: finalRows,
229
- hiddenCount,
230
- levelCounts,
231
- totalCount: entries.length
232
- };
233
- }
234
- export function useConsoleMessages(opts) {
235
- const entries = useSyncExternalStore(subscribe, getEntries, getEntries);
236
- return useMemo(() => buildDisplayRows(entries, opts), [entries, opts.levelsMask, opts.query, opts.showTimestamps, opts.collapsedOverrides, opts.groupDimension, opts.layoutMode, opts.clusterExpanded]);
237
- }
238
- //# sourceMappingURL=useConsoleMessages.js.map
1
+ "use strict";import{useMemo as w,useSyncExternalStore as x}from"react";import{subscribe as K,getEntries as b}from"../store/consoleLogStore";import{parseFilterQuery as v,shouldBeVisible as G}from"./consoleFilter";import{sourceKey as L,sourceLabel as R,colorForKey as M,bracketGlyph as E}from"./origin";const m=5;const A=5;function H(t,e){for(const r of t){const i=L(r.entry.origin,e);r.sourceKey=i;r.originColor=i?M(i):void 0;r.originLabel=e==="off"?void 0:R(r.entry.origin,e)}}function T(t){for(let e=0;e<t.length;e++){const r=t[e].sourceKey;if(r==null){t[e].bracketGlyph=void 0;continue}const i=e>0&&t[e-1].sourceKey===r;const d=e<t.length-1&&t[e+1].sourceKey===r;const n=!i&&!d?"single":!i?"top":!d?"bottom":"mid";t[e].bracketGlyph=E(n)}}function D(t,e){const r=[];const i=new Map;for(const n of t){const l=n.sourceKey??"\u2014";let o=i.get(l);if(!o){o=[];i.set(l,o);r.push(l)}o.push(n)}const d=[];for(const n of r){const l=i.get(n);for(const c of l)c.depth=0;const o=l.length>A;const s=e[n]??false;if(o){d.push({key:`cluster:${n}`,entry:l[0].entry,depth:0,repeatCount:1,isGroupHeader:false,sourceKey:n,originColor:l[0].originColor,originLabel:l[0].originLabel,clusterHeader:{key:n,count:l.length,expanded:s}});if(!s)continue}l.forEach((c,u)=>{const p=l.length===1;const g=p?"single":u===0?"top":u===l.length-1?"bottom":"mid";c.bracketGlyph=E(g);d.push(c)})}return d}function O(t){const e=new Map;const r=new Map;t.forEach((o,s)=>{const c=o.sourceKey;if(c==null)return;if(!e.has(c))e.set(c,s);r.set(c,s)});const i=[...e.keys()].sort((o,s)=>e.get(o)-e.get(s));const d=new Map;const n=[];for(const o of i){let s=n.findIndex(c=>c<e.get(o));if(s===-1){s=n.length<m?n.length:m-1;if(s>=n.length)n.push(0)}d.set(o,s);n[s]=Math.max(n[s]??0,r.get(o))}const l=Math.max(1,Math.min(n.length,m));t.forEach((o,s)=>{const c=Array.from({length:l},()=>({glyph:" "}));for(const u of i){const p=d.get(u);if(p>=l)continue;if(s>=e.get(u)&&s<=r.get(u)){c[p]={glyph:o.sourceKey===u?"\u25CF":"\u2502",color:M(u)}}}o.lanes=c})}const I=new Set(["group","groupCollapsed"]);function B(t,e){const{levelsMask:r,query:i,showTimestamps:d,collapsedOverrides:n}=e;const l=v(i.trim());const o=[];const s={verbose:0,info:0,warning:0,error:0};let c=0;const u=[];const p=()=>u.some(a=>a.collapsed);for(const a of t){s[a.level]++;if(a.method==="groupEnd"){u.pop();continue}const h=I.has(a.method);const k=p();const S=G(a,r,l);if(!S){c++}else if(!k){const f=o[o.length-1];if(!d&&!h&&f&&!f.isGroupHeader&&f.depth===u.length&&f.entry.method===a.method&&f.entry.message===a.message){f.repeatCount++}else{o.push({key:String(a.id),entry:a,depth:u.length,repeatCount:1,isGroupHeader:h,groupId:h?a.id:void 0,groupCollapsed:void 0})}}if(h){const f=a.method==="groupCollapsed";const C=n[a.id]??f;const y=o[o.length-1];if(y&&y.groupId===a.id){y.groupCollapsed=C}u.push({id:a.id,collapsed:C||k})}}H(o,e.groupDimension);let g=o;if(e.groupDimension!=="off"){if(e.layoutMode==="cluster"){g=D(o,e.clusterExpanded)}else if(e.layoutMode==="swimlane"){O(o)}else{T(o)}}return{rows:g,hiddenCount:c,levelCounts:s,totalCount:t.length}}export function useConsoleMessages(t){const e=x(K,b,b);return w(()=>B(e,t),[e,t.levelsMask,t.query,t.showTimestamps,t.collapsedOverrides,t.groupDimension,t.layoutMode,t.clusterExpanded])}
@@ -1,19 +1 @@
1
- "use strict";
2
-
3
- import { useSyncExternalStore, useEffect } from "react";
4
- import { subscribe, getEntries, installConsoleCapture } from "../store/consoleLogStore";
5
- /**
6
- * Subscribe to captured console logs. Installs the console interceptor on mount
7
- * (idempotent) and re-renders whenever a new entry is captured or the buffer is
8
- * cleared.
9
- */
10
- export function useConsoleLogs() {
11
- useEffect(() => {
12
- installConsoleCapture();
13
- }, []);
14
- const logs = useSyncExternalStore(subscribe, getEntries, getEntries);
15
- return {
16
- logs
17
- };
18
- }
19
- //# sourceMappingURL=useConsoleLogs.js.map
1
+ "use strict";import{useSyncExternalStore as o,useEffect as s}from"react";import{subscribe as r,getEntries as e,installConsoleCapture as n}from"../store/consoleLogStore";export function useConsoleLogs(){s(()=>{n()},[]);const t=o(r,e,e);return{logs:t}}
@@ -1,52 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * @buoy-gg/console
5
- *
6
- * Captures global `console.*` output and renders it as a Buoy devtool.
7
- *
8
- * This is the BASIC version: direct console patching + a flat list, used to
9
- * verify the capture pipeline end to end. Next step is a 1:1 port of Chrome
10
- * DevTools' console view.
11
- */
12
-
13
- // =============================================================================
14
- // PRESET (Primary entry point — pass to <FloatingDevTools apps={[...]} />)
15
- // =============================================================================
16
- export { consoleToolPreset, createConsoleTool } from "./preset";
17
-
18
- // =============================================================================
19
- // ROOT (Mount once at app root to capture logs from startup)
20
- // =============================================================================
21
- export { ConsoleRoot } from "./components/ConsoleRoot";
22
-
23
- // =============================================================================
24
- // COMPONENTS
25
- // =============================================================================
26
- export { ConsoleModal } from "./components/ConsoleModal";
27
- export { ConsoleIcon, CONSOLE_ICON_COLOR } from "./components/ConsoleIcon";
28
-
29
- // DevTools-style console panel (the 1:1 Chrome console port)
30
- export { ConsoleView } from "./devtools/ConsoleView";
31
- export { ConsoleMessageRow } from "./devtools/ConsoleMessageRow";
32
- export { ConsoleValue } from "./devtools/ConsoleValue";
33
- export { useConsoleMessages } from "./devtools/useConsoleMessages";
34
- export { consoleTheme, levelStyles } from "./devtools/theme";
35
-
36
- // Basic flat list (kept for simple/embedded use)
37
- export { ConsoleLogList } from "./components/ConsoleLogList";
38
-
39
- // =============================================================================
40
- // HOOK
41
- // =============================================================================
42
- export { useConsoleLogs } from "./hooks/useConsoleLogs";
43
- // =============================================================================
44
- // EXTERNAL SYNC (device → desktop dashboard)
45
- // =============================================================================
46
- export { consoleSyncAdapter } from "./sync/consoleSyncAdapter";
47
-
48
- // =============================================================================
49
- // CAPTURE STORE (install/teardown + types)
50
- // =============================================================================
51
- export { installConsoleCapture, installFatalErrorCapture, uninstallConsoleCapture, clearEntries, getEntries, subscribe, replaceEntries, onClear, initConsolePersistence, getPreserveLog, setPreserveLog, subscribePreserveLog } from "./store/consoleLogStore";
52
- //# sourceMappingURL=index.js.map
1
+ "use strict";export{consoleToolPreset,createConsoleTool}from"./preset";export{ConsoleRoot}from"./components/ConsoleRoot";export{ConsoleModal}from"./components/ConsoleModal";export{ConsoleIcon,CONSOLE_ICON_COLOR}from"./components/ConsoleIcon";export{ConsoleView}from"./devtools/ConsoleView";export{ConsoleMessageRow}from"./devtools/ConsoleMessageRow";export{ConsoleValue}from"./devtools/ConsoleValue";export{useConsoleMessages}from"./devtools/useConsoleMessages";export{consoleTheme,levelStyles}from"./devtools/theme";export{ConsoleLogList}from"./components/ConsoleLogList";export{useConsoleLogs}from"./hooks/useConsoleLogs";export{consoleSyncAdapter}from"./sync/consoleSyncAdapter";export{installConsoleCapture,installFatalErrorCapture,uninstallConsoleCapture,clearEntries,getEntries,subscribe,replaceEntries,onClear,initConsolePersistence,getPreserveLog,setPreserveLog,subscribePreserveLog}from"./store/consoleLogStore";
@@ -1,61 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Pre-configured Console tool for FloatingDevTools.
5
- *
6
- * @example
7
- * ```tsx
8
- * import { consoleToolPreset } from '@buoy-gg/console';
9
- *
10
- * <FloatingDevTools apps={[consoleToolPreset]} />
11
- * ```
12
- */
13
-
14
- import { ConsoleIcon, CONSOLE_ICON_COLOR } from "./components/ConsoleIcon";
15
- import { ConsoleModal } from "./components/ConsoleModal";
16
- import { installConsoleCapture } from "./store/consoleLogStore";
17
- import { createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
18
-
19
- /**
20
- * Install console + fatal-error capture at IMPORT time, not first UI mount.
21
- *
22
- * Deliberately a module side effect (same pattern as @buoy-gg/network's
23
- * override hydration): a fatal error thrown during the app's FIRST render
24
- * kills the tree before FloatingDevTools' effects ever run, so mount-time
25
- * install (`ConsoleRoot`) captured nothing for exactly the crashes that most
26
- * need capturing. Importing the preset happens at bundle-eval, before any
27
- * rendering, so the `console.*` patch and both fatal-error hooks (`ErrorUtils`
28
- * and RN's native exception listener) are live from the first line of app code.
29
- *
30
- * Guards:
31
- * - `ErrorUtils` OR `RN$registerExceptionListener` present = a real React Native
32
- * runtime. The desktop dashboard and web mirrors import this package too, and
33
- * must never patch their OWN console (they mirror device entries via
34
- * `replaceEntries`).
35
- * - Dev-only. In production the existing mount-time path still applies (the
36
- * tools only mount there for licensed users), so end-user builds are never
37
- * patched at import.
38
- */
39
- import { jsx as _jsx } from "react/jsx-runtime";
40
- const rnGlobals = globalThis;
41
- const isReactNativeRuntime = typeof rnGlobals.ErrorUtils?.setGlobalHandler === "function" || typeof rnGlobals.RN$registerExceptionListener === "function";
42
- if (isReactNativeRuntime && typeof __DEV__ !== "undefined" && __DEV__) {
43
- installConsoleCapture();
44
- }
45
- export const consoleToolPreset = defineToolPreset({
46
- id: "console",
47
- name: "CONSOLE",
48
- description: "Captured console.* output",
49
- slot: "both",
50
- color: CONSOLE_ICON_COLOR,
51
- icon: ({
52
- size
53
- }) => /*#__PURE__*/_jsx(ConsoleIcon, {
54
- size: size
55
- }),
56
- component: ConsoleModal
57
- });
58
-
59
- /** Create a custom Console tool configuration. */
60
- export const createConsoleTool = createToolFactory(consoleToolPreset);
61
- //# sourceMappingURL=preset.js.map
1
+ "use strict";import{ConsoleIcon as t,CONSOLE_ICON_COLOR as n}from"./components/ConsoleIcon";import{ConsoleModal as r}from"./components/ConsoleModal";import{installConsoleCapture as s}from"./store/consoleLogStore";import{createToolFactory as i,defineToolPreset as l}from"@buoy-gg/shared-ui";import{jsx as c}from"react/jsx-runtime";const o=globalThis;const p=typeof o.ErrorUtils?.setGlobalHandler==="function"||typeof o.RN$registerExceptionListener==="function";if(p&&typeof __DEV__!=="undefined"&&__DEV__){s()}export const consoleToolPreset=l({id:"console",name:"CONSOLE",description:"Captured console.* output",slot:"both",color:n,icon:({size:e})=>c(t,{size:e}),component:r});export const createConsoleTool=i(consoleToolPreset);