@buoy-gg/highlight-updates 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 -71
  2. package/lib/commonjs/highlight-updates/HighlightUpdatesOverlay.js +1 -281
  3. package/lib/commonjs/highlight-updates/components/HighlightFilterView.js +1 -1474
  4. package/lib/commonjs/highlight-updates/components/HighlightUpdatesModal.js +1 -641
  5. package/lib/commonjs/highlight-updates/components/IdentifierBadge.js +1 -273
  6. package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +1 -188
  7. package/lib/commonjs/highlight-updates/components/ModalHeaderContent.js +1 -293
  8. package/lib/commonjs/highlight-updates/components/RenderCauseBadge.js +1 -508
  9. package/lib/commonjs/highlight-updates/components/RenderDetailView.js +1 -846
  10. package/lib/commonjs/highlight-updates/components/RenderHistoryViewer.js +1 -915
  11. package/lib/commonjs/highlight-updates/components/RenderListItem.js +1 -235
  12. package/lib/commonjs/highlight-updates/components/RendersCopySettingsView.js +1 -469
  13. package/lib/commonjs/highlight-updates/components/StatsDisplay.js +1 -73
  14. package/lib/commonjs/highlight-updates/types/copySettings.js +1 -107
  15. package/lib/commonjs/highlight-updates/utils/CommitProfiler.js +1 -455
  16. package/lib/commonjs/highlight-updates/utils/HighlightUpdatesController.js +1 -1929
  17. package/lib/commonjs/highlight-updates/utils/PerformanceLogger.js +26 -359
  18. package/lib/commonjs/highlight-updates/utils/ProfilerInterceptor.js +1 -371
  19. package/lib/commonjs/highlight-updates/utils/RenderCauseDetector.js +5 -1840
  20. package/lib/commonjs/highlight-updates/utils/RenderTracker.js +1 -952
  21. package/lib/commonjs/highlight-updates/utils/ViewTypeMapper.js +1 -264
  22. package/lib/commonjs/highlight-updates/utils/copySettingsStorage.js +1 -32
  23. package/lib/commonjs/highlight-updates/utils/devtoolsComponentNames.js +1 -188
  24. package/lib/commonjs/highlight-updates/utils/namedComposite.js +1 -41
  25. package/lib/commonjs/highlight-updates/utils/ownStateChanged.js +1 -103
  26. package/lib/commonjs/highlight-updates/utils/rawEventEmitter.js +1 -50
  27. package/lib/commonjs/highlight-updates/utils/rawEventEmitter.web.js +1 -12
  28. package/lib/commonjs/highlight-updates/utils/renderExportFormatter.js +1 -58
  29. package/lib/commonjs/highlight-updates/utils/rendersExportFormatter.js +1 -485
  30. package/lib/commonjs/highlight-updates/utils/screenElements.js +1 -1269
  31. package/lib/commonjs/highlight-updates/utils/tapMatch.js +1 -83
  32. package/lib/commonjs/highlight-updates/utils/testIDs.js +1 -68
  33. package/lib/commonjs/highlight-updates/utils/touchCapture.js +1 -277
  34. package/lib/commonjs/index.js +1 -429
  35. package/lib/commonjs/preset.js +1 -278
  36. package/lib/commonjs/sync/highlightUpdatesSyncAdapter.js +1 -235
  37. package/lib/module/highlight-updates/HighlightUpdatesOverlay.js +1 -274
  38. package/lib/module/highlight-updates/components/HighlightFilterView.js +1 -1468
  39. package/lib/module/highlight-updates/components/HighlightUpdatesModal.js +1 -634
  40. package/lib/module/highlight-updates/components/IdentifierBadge.js +1 -265
  41. package/lib/module/highlight-updates/components/IsolatedRenderList.js +1 -183
  42. package/lib/module/highlight-updates/components/ModalHeaderContent.js +1 -288
  43. package/lib/module/highlight-updates/components/RenderCauseBadge.js +1 -499
  44. package/lib/module/highlight-updates/components/RenderDetailView.js +1 -840
  45. package/lib/module/highlight-updates/components/RenderHistoryViewer.js +1 -908
  46. package/lib/module/highlight-updates/components/RenderListItem.js +1 -230
  47. package/lib/module/highlight-updates/components/RendersCopySettingsView.js +1 -465
  48. package/lib/module/highlight-updates/components/StatsDisplay.js +1 -70
  49. package/lib/module/highlight-updates/types/copySettings.js +1 -102
  50. package/lib/module/highlight-updates/utils/CommitProfiler.js +1 -451
  51. package/lib/module/highlight-updates/utils/HighlightUpdatesController.js +1 -1925
  52. package/lib/module/highlight-updates/utils/PerformanceLogger.js +26 -353
  53. package/lib/module/highlight-updates/utils/ProfilerInterceptor.js +1 -358
  54. package/lib/module/highlight-updates/utils/RenderCauseDetector.js +5 -1830
  55. package/lib/module/highlight-updates/utils/RenderTracker.js +1 -949
  56. package/lib/module/highlight-updates/utils/ViewTypeMapper.js +1 -255
  57. package/lib/module/highlight-updates/utils/copySettingsStorage.js +1 -26
  58. package/lib/module/highlight-updates/utils/devtoolsComponentNames.js +1 -178
  59. package/lib/module/highlight-updates/utils/namedComposite.js +1 -36
  60. package/lib/module/highlight-updates/utils/ownStateChanged.js +1 -98
  61. package/lib/module/highlight-updates/utils/rawEventEmitter.js +1 -46
  62. package/lib/module/highlight-updates/utils/rawEventEmitter.web.js +1 -3
  63. package/lib/module/highlight-updates/utils/renderExportFormatter.js +1 -54
  64. package/lib/module/highlight-updates/utils/rendersExportFormatter.js +1 -478
  65. package/lib/module/highlight-updates/utils/screenElements.js +1 -1263
  66. package/lib/module/highlight-updates/utils/tapMatch.js +1 -76
  67. package/lib/module/highlight-updates/utils/testIDs.js +1 -60
  68. package/lib/module/highlight-updates/utils/touchCapture.js +1 -270
  69. package/lib/module/index.js +1 -130
  70. package/lib/module/preset.js +1 -272
  71. package/lib/module/sync/highlightUpdatesSyncAdapter.js +1 -230
  72. package/lib/web/index.mjs +28 -29
  73. package/package.json +7 -7
  74. package/lib/typescript/highlight-updates/HighlightUpdatesOverlay.d.ts.map +0 -1
  75. package/lib/typescript/highlight-updates/components/HighlightFilterView.d.ts.map +0 -1
  76. package/lib/typescript/highlight-updates/components/HighlightUpdatesModal.d.ts.map +0 -1
  77. package/lib/typescript/highlight-updates/components/IdentifierBadge.d.ts.map +0 -1
  78. package/lib/typescript/highlight-updates/components/IsolatedRenderList.d.ts.map +0 -1
  79. package/lib/typescript/highlight-updates/components/ModalHeaderContent.d.ts.map +0 -1
  80. package/lib/typescript/highlight-updates/components/RenderCauseBadge.d.ts.map +0 -1
  81. package/lib/typescript/highlight-updates/components/RenderDetailView.d.ts.map +0 -1
  82. package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts.map +0 -1
  83. package/lib/typescript/highlight-updates/components/RenderListItem.d.ts.map +0 -1
  84. package/lib/typescript/highlight-updates/components/RendersCopySettingsView.d.ts.map +0 -1
  85. package/lib/typescript/highlight-updates/components/StatsDisplay.d.ts.map +0 -1
  86. package/lib/typescript/highlight-updates/types/copySettings.d.ts.map +0 -1
  87. package/lib/typescript/highlight-updates/utils/CommitProfiler.d.ts.map +0 -1
  88. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts.map +0 -1
  89. package/lib/typescript/highlight-updates/utils/PerformanceLogger.d.ts.map +0 -1
  90. package/lib/typescript/highlight-updates/utils/ProfilerInterceptor.d.ts.map +0 -1
  91. package/lib/typescript/highlight-updates/utils/RenderCauseDetector.d.ts.map +0 -1
  92. package/lib/typescript/highlight-updates/utils/RenderTracker.d.ts.map +0 -1
  93. package/lib/typescript/highlight-updates/utils/ViewTypeMapper.d.ts.map +0 -1
  94. package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts.map +0 -1
  95. package/lib/typescript/highlight-updates/utils/devtoolsComponentNames.d.ts.map +0 -1
  96. package/lib/typescript/highlight-updates/utils/namedComposite.d.ts.map +0 -1
  97. package/lib/typescript/highlight-updates/utils/ownStateChanged.d.ts.map +0 -1
  98. package/lib/typescript/highlight-updates/utils/rawEventEmitter.d.ts.map +0 -1
  99. package/lib/typescript/highlight-updates/utils/rawEventEmitter.web.d.ts.map +0 -1
  100. package/lib/typescript/highlight-updates/utils/renderExportFormatter.d.ts.map +0 -1
  101. package/lib/typescript/highlight-updates/utils/rendersExportFormatter.d.ts.map +0 -1
  102. package/lib/typescript/highlight-updates/utils/screenElements.d.ts.map +0 -1
  103. package/lib/typescript/highlight-updates/utils/tapMatch.d.ts.map +0 -1
  104. package/lib/typescript/highlight-updates/utils/testIDs.d.ts.map +0 -1
  105. package/lib/typescript/highlight-updates/utils/touchCapture.d.ts.map +0 -1
  106. package/lib/typescript/index.d.ts.map +0 -1
  107. package/lib/typescript/preset.d.ts.map +0 -1
  108. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts.map +0 -1
@@ -1,465 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * RendersCopySettingsView
5
- *
6
- * Settings UI for configuring render report export.
7
- * Mirrors EventsCopySettingsView but with renders-specific options.
8
- */
9
-
10
- import { useCallback, useEffect, useMemo, useState } from "react";
11
- import { Text, StyleSheet, ScrollView } from "react-native";
12
- import { DynamicFilterView, macOSColors, night, FileText, FileCode, Zap, Settings, Eye, Layers, ToolbarCopyButton, ExportPreview, monoFont } from "@buoy-gg/shared-ui";
13
- import { DEFAULT_COPY_SETTINGS, COPY_PRESETS, PRESET_METADATA, detectActivePreset } from "../types/copySettings";
14
- import { generateExport, estimateExportSize, getExportSummary } from "../utils/rendersExportFormatter";
15
- import { loadCopySettings, saveCopySettings } from "../utils/copySettingsStorage";
16
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
17
- const SIZE_WARNING_THRESHOLD = 50 * 1024;
18
- const SIZE_DANGER_THRESHOLD = 200 * 1024;
19
- const CAUSE_OPTIONS = [{
20
- value: "mount",
21
- label: "Mount"
22
- }, {
23
- value: "props",
24
- label: "Props"
25
- }, {
26
- value: "hooks",
27
- label: "Hooks"
28
- }, {
29
- value: "state",
30
- label: "State"
31
- }, {
32
- value: "parent",
33
- label: "Parent"
34
- }, {
35
- value: "context",
36
- label: "Context"
37
- }, {
38
- value: "unknown",
39
- label: "Unknown"
40
- }];
41
- function formatBytes(bytes) {
42
- if (bytes < 1024) return `${bytes} B`;
43
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
44
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
45
- }
46
- function createMockRenders() {
47
- const now = Date.now();
48
- return [{
49
- id: "1",
50
- nativeTag: 1,
51
- viewType: "RCTView",
52
- displayName: "View",
53
- componentName: "PokemonListItem",
54
- renderCount: 30,
55
- firstRenderTime: now - 5000,
56
- lastRenderTime: now,
57
- color: "#10B981",
58
- lastRenderCause: {
59
- type: "parent",
60
- timestamp: now,
61
- componentCause: "parent"
62
- }
63
- }, {
64
- id: "2",
65
- nativeTag: 2,
66
- viewType: "RCTView",
67
- displayName: "View",
68
- componentName: "CartHeader",
69
- renderCount: 12,
70
- firstRenderTime: now - 4000,
71
- lastRenderTime: now,
72
- color: "#3B82F6",
73
- lastRenderCause: {
74
- type: "hooks",
75
- timestamp: now,
76
- componentCause: "state",
77
- hookChanges: [{
78
- type: "useState",
79
- index: 2,
80
- previousValue: 4,
81
- currentValue: 5
82
- }]
83
- }
84
- }, {
85
- id: "3",
86
- nativeTag: 3,
87
- viewType: "RCTView",
88
- displayName: "View",
89
- componentName: "SearchBar",
90
- renderCount: 8,
91
- firstRenderTime: now - 3000,
92
- lastRenderTime: now,
93
- color: "#F59E0B",
94
- lastRenderCause: {
95
- type: "props",
96
- timestamp: now,
97
- componentCause: "props",
98
- changedKeys: ["query", "onChange"]
99
- }
100
- }];
101
- }
102
- export function RendersCopySettingsView({
103
- renders
104
- }) {
105
- const [settings, setSettings] = useState(DEFAULT_COPY_SETTINGS);
106
- const [isPreviewExpanded, setIsPreviewExpanded] = useState(false);
107
- useEffect(() => {
108
- let mounted = true;
109
- loadCopySettings().then(saved => {
110
- if (mounted && saved) setSettings(saved);
111
- });
112
- return () => {
113
- mounted = false;
114
- };
115
- }, []);
116
- const updateSettings = useCallback(next => {
117
- setSettings(next);
118
- saveCopySettings(next);
119
- }, []);
120
- const hasLiveData = renders.length > 0;
121
- const previewRenders = hasLiveData ? renders : createMockRenders();
122
- const activePreset = useMemo(() => detectActivePreset(settings), [settings]);
123
- const estimatedSize = useMemo(() => estimateExportSize(previewRenders, settings), [previewRenders, settings]);
124
- const sizeWarningLevel = useMemo(() => {
125
- if (estimatedSize >= SIZE_DANGER_THRESHOLD) return "danger";
126
- if (estimatedSize >= SIZE_WARNING_THRESHOLD) return "warning";
127
- return "none";
128
- }, [estimatedSize]);
129
- const generateCopyText = useCallback(() => generateExport(previewRenders, settings), [previewRenders, settings]);
130
- const applyPreset = useCallback(name => {
131
- // "Custom" is what the list shows once the settings match no preset;
132
- // choosing it changes nothing.
133
- const preset = COPY_PRESETS[name];
134
- if (!preset) return;
135
- updateSettings({
136
- ...preset,
137
- filterCauses: [...preset.filterCauses]
138
- });
139
- }, [updateSettings]);
140
- const handleOptionChange = useCallback((optionId, value) => {
141
- const [group, key] = optionId.split("::");
142
- if (group === "preset") {
143
- applyPreset(key);
144
- return;
145
- }
146
- if (group === "format") {
147
- updateSettings({
148
- ...settings,
149
- format: value
150
- });
151
- return;
152
- }
153
- if (group === "sort") {
154
- updateSettings({
155
- ...settings,
156
- sortBy: value
157
- });
158
- return;
159
- }
160
- if (group === "topN") {
161
- updateSettings({
162
- ...settings,
163
- topN: value
164
- });
165
- return;
166
- }
167
- if (group === "minRenders") {
168
- updateSettings({
169
- ...settings,
170
- minRenders: value
171
- });
172
- return;
173
- }
174
- if (group === "cause") {
175
- const cause = value;
176
- const has = settings.filterCauses.includes(cause);
177
- updateSettings({
178
- ...settings,
179
- filterCauses: has ? settings.filterCauses.filter(c => c !== cause) : [...settings.filterCauses, cause]
180
- });
181
- return;
182
- }
183
- if (group === "signal") {
184
- const k = key;
185
- updateSettings({
186
- ...settings,
187
- [k]: !settings[k]
188
- });
189
- return;
190
- }
191
- }, [settings, updateSettings, applyPreset]);
192
- const renderPreviewContent = useCallback(() => {
193
- const {
194
- totalComponents,
195
- totalRenders
196
- } = getExportSummary(previewRenders);
197
- return /*#__PURE__*/_jsx(ExportPreview, {
198
- expanded: isPreviewExpanded,
199
- onExpandedChange: setIsPreviewExpanded,
200
- summary: `${totalComponents} component${totalComponents !== 1 ? "s" : ""} · ${totalRenders} renders · ~${formatBytes(estimatedSize)}${!hasLiveData ? " (mock data)" : ""}`,
201
- warningLevel: sizeWarningLevel,
202
- warningText: {
203
- warning: "Large payload — preview may be slow",
204
- danger: "Very large payload — try a smaller topN or turn off history"
205
- },
206
- testIDs: {
207
- expand: "buoy-highlight-copy-preview-show",
208
- collapse: "buoy-highlight-copy-preview-hide",
209
- summary: "buoy-highlight-copy-preview-summary",
210
- warning: "buoy-highlight-copy-size-warning"
211
- },
212
- renderBody: () => {
213
- const exportText = generateCopyText();
214
- return /*#__PURE__*/_jsx(ScrollView, {
215
- testID: "buoy-highlight-copy-preview-scroll",
216
- style: styles.previewScroll,
217
- nestedScrollEnabled: true,
218
- children: /*#__PURE__*/_jsx(Text, {
219
- testID: "buoy-highlight-copy-preview-text",
220
- style: styles.previewText,
221
- selectable: true,
222
- children: exportText
223
- })
224
- });
225
- }
226
- });
227
- }, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
228
- const renderPreviewHeaderActions = useCallback(() => {
229
- const {
230
- totalComponents
231
- } = getExportSummary(previewRenders);
232
- const statusLabel = hasLiveData ? `${totalComponents} components` : "Mock data (no renders captured)";
233
- return /*#__PURE__*/_jsxs(_Fragment, {
234
- children: [/*#__PURE__*/_jsx(Text, {
235
- testID: "buoy-highlight-copy-status",
236
- style: styles.statusLabel,
237
- children: statusLabel
238
- }), /*#__PURE__*/_jsx(ToolbarCopyButton, {
239
- value: generateCopyText
240
- })]
241
- });
242
- }, [hasLiveData, previewRenders, generateCopyText]);
243
- const dynamicFilterConfig = useMemo(() => ({
244
- sections: [{
245
- id: "presets",
246
- title: "Presets",
247
- type: "custom",
248
- data: [{
249
- id: "preset::llm",
250
- label: PRESET_METADATA.llm.label,
251
- icon: Zap,
252
- color: PRESET_METADATA.llm.color,
253
- value: "llm",
254
- isActive: activePreset === "llm",
255
- description: PRESET_METADATA.llm.description
256
- }, {
257
- id: "preset::table",
258
- label: PRESET_METADATA.table.label,
259
- icon: FileText,
260
- color: PRESET_METADATA.table.color,
261
- value: "table",
262
- isActive: activePreset === "table",
263
- description: PRESET_METADATA.table.description
264
- }, {
265
- id: "preset::json",
266
- label: PRESET_METADATA.json.label,
267
- icon: FileCode,
268
- color: PRESET_METADATA.json.color,
269
- value: "json",
270
- isActive: activePreset === "json",
271
- description: PRESET_METADATA.json.description
272
- }, {
273
- id: "preset::full",
274
- label: PRESET_METADATA.full.label,
275
- icon: Layers,
276
- color: PRESET_METADATA.full.color,
277
- value: "full",
278
- isActive: activePreset === "full",
279
- description: PRESET_METADATA.full.description
280
- }, {
281
- id: "preset::custom",
282
- label: "Custom",
283
- icon: Settings,
284
- color: night.color.textSecondary,
285
- value: "custom",
286
- isActive: activePreset === null,
287
- description: "User-configured"
288
- }]
289
- }, {
290
- id: "format",
291
- title: "Format",
292
- type: "custom",
293
- data: [{
294
- id: "format::summary",
295
- label: "Summary",
296
- icon: Zap,
297
- color: macOSColors.semantic.success,
298
- value: "summary",
299
- isActive: settings.format === "summary",
300
- description: "Compact, LLM-ready"
301
- }, {
302
- id: "format::markdown-table",
303
- label: "Table",
304
- icon: FileText,
305
- color: macOSColors.semantic.info,
306
- value: "markdown-table",
307
- isActive: settings.format === "markdown-table",
308
- description: "Markdown table"
309
- }, {
310
- id: "format::json",
311
- label: "JSON",
312
- icon: FileCode,
313
- color: macOSColors.semantic.warning,
314
- value: "json",
315
- isActive: settings.format === "json",
316
- description: "Structured data"
317
- }]
318
- }, {
319
- id: "sort",
320
- title: "Sort By",
321
- type: "custom",
322
- data: [{
323
- id: "sort::renderCount",
324
- label: "Count",
325
- value: "renderCount",
326
- isActive: settings.sortBy === "renderCount",
327
- description: "Total renders"
328
- }, {
329
- id: "sort::rate",
330
- label: "Rate",
331
- value: "rate",
332
- isActive: settings.sortBy === "rate",
333
- description: "Renders / sec"
334
- }, {
335
- id: "sort::name",
336
- label: "Name",
337
- value: "name",
338
- isActive: settings.sortBy === "name",
339
- description: "Alphabetical"
340
- }]
341
- }, {
342
- id: "topN",
343
- title: "Top N",
344
- type: "custom",
345
- data: [{
346
- id: "topN::10",
347
- label: "10",
348
- value: 10,
349
- isActive: settings.topN === 10
350
- }, {
351
- id: "topN::25",
352
- label: "25",
353
- value: 25,
354
- isActive: settings.topN === 25
355
- }, {
356
- id: "topN::50",
357
- label: "50",
358
- value: 50,
359
- isActive: settings.topN === 50
360
- }, {
361
- id: "topN::100",
362
- label: "100",
363
- value: 100,
364
- isActive: settings.topN === 100
365
- }, {
366
- id: "topN::-1",
367
- label: "All",
368
- value: -1,
369
- isActive: settings.topN === -1
370
- }]
371
- }, {
372
- id: "minRenders",
373
- title: "Min Renders",
374
- type: "custom",
375
- data: [{
376
- id: "minRenders::1",
377
- label: "1",
378
- value: 1,
379
- isActive: settings.minRenders === 1
380
- }, {
381
- id: "minRenders::2",
382
- label: "2",
383
- value: 2,
384
- isActive: settings.minRenders === 2
385
- }, {
386
- id: "minRenders::3",
387
- label: "3",
388
- value: 3,
389
- isActive: settings.minRenders === 3
390
- }, {
391
- id: "minRenders::5",
392
- label: "5",
393
- value: 5,
394
- isActive: settings.minRenders === 5
395
- }, {
396
- id: "minRenders::10",
397
- label: "10",
398
- value: 10,
399
- isActive: settings.minRenders === 10
400
- }]
401
- }, {
402
- id: "causes",
403
- title: "Filter Causes",
404
- type: "custom",
405
- description: settings.filterCauses.length === 0 ? "All causes shown" : "Only the selected causes shown",
406
- data: CAUSE_OPTIONS.map(opt => ({
407
- id: `cause::${opt.value}`,
408
- label: opt.label,
409
- value: opt.value,
410
- isActive: settings.filterCauses.includes(opt.value)
411
- }))
412
- }, {
413
- id: "signal",
414
- title: "Signal Extraction",
415
- type: "custom",
416
- data: [{
417
- id: "signal::groupByName",
418
- label: "Group by name",
419
- value: "groupByName",
420
- isActive: settings.groupByName,
421
- description: "Collapse list items"
422
- }, {
423
- id: "signal::aggregateCauses",
424
- label: "Aggregate causes",
425
- value: "aggregateCauses",
426
- isActive: settings.aggregateCauses,
427
- description: "Hook x N"
428
- }, {
429
- id: "signal::includeHistory",
430
- label: "Include history",
431
- value: "includeHistory",
432
- isActive: settings.includeHistory,
433
- description: "JSON only — large"
434
- }]
435
- }],
436
- previewSection: {
437
- enabled: true,
438
- title: "PREVIEW",
439
- icon: Eye,
440
- content: renderPreviewContent,
441
- headerActions: renderPreviewHeaderActions
442
- },
443
- onFilterChange: handleOptionChange
444
- }), [settings, activePreset, handleOptionChange, renderPreviewContent, renderPreviewHeaderActions]);
445
- return /*#__PURE__*/_jsx(DynamicFilterView, {
446
- ...dynamicFilterConfig
447
- });
448
- }
449
- const styles = StyleSheet.create({
450
- previewScroll: {
451
- maxHeight: 360
452
- },
453
- previewText: {
454
- fontFamily: monoFont,
455
- fontSize: 11,
456
- color: night.color.text,
457
- lineHeight: 18
458
- },
459
- statusLabel: {
460
- fontSize: 11,
461
- fontWeight: "600",
462
- color: night.color.textTertiary,
463
- marginRight: 8
464
- }
465
- });
1
+ "use strict";import{useCallback as u,useEffect as V,useMemo as g,useState as N}from"react";import{Text as E,StyleSheet as D,ScrollView as _}from"react-native";import{DynamicFilterView as O,macOSColors as y,night as f,FileText as k,FileCode as B,Zap as P,Settings as $,Eye as M,Layers as z,ToolbarCopyButton as G,ExportPreview as U,monoFont as W}from"@buoy-gg/shared-ui";import{DEFAULT_COPY_SETTINGS as Z,COPY_PRESETS as J,PRESET_METADATA as r,detectActivePreset as K}from"../types/copySettings";import{generateExport as Y,estimateExportSize as q,getExportSummary as F}from"../utils/rendersExportFormatter";import{loadCopySettings as Q,saveCopySettings as X}from"../utils/copySettingsStorage";import{jsx as d,Fragment as ee,jsxs as te}from"react/jsx-runtime";const ie=50*1024;const oe=200*1024;const re=[{value:"mount",label:"Mount"},{value:"props",label:"Props"},{value:"hooks",label:"Hooks"},{value:"state",label:"State"},{value:"parent",label:"Parent"},{value:"context",label:"Context"},{value:"unknown",label:"Unknown"}];function ae(i){if(i<1024)return`${i} B`;if(i<1024*1024)return`${(i/1024).toFixed(1)} KB`;return`${(i/(1024*1024)).toFixed(1)} MB`}function ne(){const i=Date.now();return[{id:"1",nativeTag:1,viewType:"RCTView",displayName:"View",componentName:"PokemonListItem",renderCount:30,firstRenderTime:i-5e3,lastRenderTime:i,color:"#10B981",lastRenderCause:{type:"parent",timestamp:i,componentCause:"parent"}},{id:"2",nativeTag:2,viewType:"RCTView",displayName:"View",componentName:"CartHeader",renderCount:12,firstRenderTime:i-4e3,lastRenderTime:i,color:"#3B82F6",lastRenderCause:{type:"hooks",timestamp:i,componentCause:"state",hookChanges:[{type:"useState",index:2,previousValue:4,currentValue:5}]}},{id:"3",nativeTag:3,viewType:"RCTView",displayName:"View",componentName:"SearchBar",renderCount:8,firstRenderTime:i-3e3,lastRenderTime:i,color:"#F59E0B",lastRenderCause:{type:"props",timestamp:i,componentCause:"props",changedKeys:["query","onChange"]}}]}export function RendersCopySettingsView({renders:i}){const[e,h]=N(Z);const[C,L]=N(false);V(()=>{let t=true;Q().then(o=>{if(t&&o)h(o)});return()=>{t=false}},[]);const a=u(t=>{h(t);X(t)},[]);const p=i.length>0;const s=p?i:ne();const l=g(()=>K(e),[e]);const m=g(()=>q(s,e),[s,e]);const w=g(()=>{if(m>=oe)return"danger";if(m>=ie)return"warning";return"none"},[m]);const v=u(()=>Y(s,e),[s,e]);const S=u(t=>{const o=J[t];if(!o)return;a({...o,filterCauses:[...o.filterCauses]})},[a]);const R=u((t,o)=>{const[n,x]=t.split("::");if(n==="preset"){S(x);return}if(n==="format"){a({...e,format:o});return}if(n==="sort"){a({...e,sortBy:o});return}if(n==="topN"){a({...e,topN:o});return}if(n==="minRenders"){a({...e,minRenders:o});return}if(n==="cause"){const c=o;const H=e.filterCauses.includes(c);a({...e,filterCauses:H?e.filterCauses.filter(I=>I!==c):[...e.filterCauses,c]});return}if(n==="signal"){const c=x;a({...e,[c]:!e[c]});return}},[e,a,S]);const A=u(()=>{const{totalComponents:t,totalRenders:o}=F(s);return d(U,{expanded:C,onExpandedChange:L,summary:`${t} component${t!==1?"s":""} \xB7 ${o} renders \xB7 ~${ae(m)}${!p?" (mock data)":""}`,warningLevel:w,warningText:{warning:"Large payload \u2014 preview may be slow",danger:"Very large payload \u2014 try a smaller topN or turn off history"},testIDs:{expand:"buoy-highlight-copy-preview-show",collapse:"buoy-highlight-copy-preview-hide",summary:"buoy-highlight-copy-preview-summary",warning:"buoy-highlight-copy-size-warning"},renderBody:()=>{const n=v();return d(_,{testID:"buoy-highlight-copy-preview-scroll",style:b.previewScroll,nestedScrollEnabled:true,children:d(E,{testID:"buoy-highlight-copy-preview-text",style:b.previewText,selectable:true,children:n})})}})},[C,s,m,w,p,v]);const T=u(()=>{const{totalComponents:t}=F(s);const o=p?`${t} components`:"Mock data (no renders captured)";return te(ee,{children:[d(E,{testID:"buoy-highlight-copy-status",style:b.statusLabel,children:o}),d(G,{value:v})]})},[p,s,v]);const j=g(()=>({sections:[{id:"presets",title:"Presets",type:"custom",data:[{id:"preset::llm",label:r.llm.label,icon:P,color:r.llm.color,value:"llm",isActive:l==="llm",description:r.llm.description},{id:"preset::table",label:r.table.label,icon:k,color:r.table.color,value:"table",isActive:l==="table",description:r.table.description},{id:"preset::json",label:r.json.label,icon:B,color:r.json.color,value:"json",isActive:l==="json",description:r.json.description},{id:"preset::full",label:r.full.label,icon:z,color:r.full.color,value:"full",isActive:l==="full",description:r.full.description},{id:"preset::custom",label:"Custom",icon:$,color:f.color.textSecondary,value:"custom",isActive:l===null,description:"User-configured"}]},{id:"format",title:"Format",type:"custom",data:[{id:"format::summary",label:"Summary",icon:P,color:y.semantic.success,value:"summary",isActive:e.format==="summary",description:"Compact, LLM-ready"},{id:"format::markdown-table",label:"Table",icon:k,color:y.semantic.info,value:"markdown-table",isActive:e.format==="markdown-table",description:"Markdown table"},{id:"format::json",label:"JSON",icon:B,color:y.semantic.warning,value:"json",isActive:e.format==="json",description:"Structured data"}]},{id:"sort",title:"Sort By",type:"custom",data:[{id:"sort::renderCount",label:"Count",value:"renderCount",isActive:e.sortBy==="renderCount",description:"Total renders"},{id:"sort::rate",label:"Rate",value:"rate",isActive:e.sortBy==="rate",description:"Renders / sec"},{id:"sort::name",label:"Name",value:"name",isActive:e.sortBy==="name",description:"Alphabetical"}]},{id:"topN",title:"Top N",type:"custom",data:[{id:"topN::10",label:"10",value:10,isActive:e.topN===10},{id:"topN::25",label:"25",value:25,isActive:e.topN===25},{id:"topN::50",label:"50",value:50,isActive:e.topN===50},{id:"topN::100",label:"100",value:100,isActive:e.topN===100},{id:"topN::-1",label:"All",value:-1,isActive:e.topN===-1}]},{id:"minRenders",title:"Min Renders",type:"custom",data:[{id:"minRenders::1",label:"1",value:1,isActive:e.minRenders===1},{id:"minRenders::2",label:"2",value:2,isActive:e.minRenders===2},{id:"minRenders::3",label:"3",value:3,isActive:e.minRenders===3},{id:"minRenders::5",label:"5",value:5,isActive:e.minRenders===5},{id:"minRenders::10",label:"10",value:10,isActive:e.minRenders===10}]},{id:"causes",title:"Filter Causes",type:"custom",description:e.filterCauses.length===0?"All causes shown":"Only the selected causes shown",data:re.map(t=>({id:`cause::${t.value}`,label:t.label,value:t.value,isActive:e.filterCauses.includes(t.value)}))},{id:"signal",title:"Signal Extraction",type:"custom",data:[{id:"signal::groupByName",label:"Group by name",value:"groupByName",isActive:e.groupByName,description:"Collapse list items"},{id:"signal::aggregateCauses",label:"Aggregate causes",value:"aggregateCauses",isActive:e.aggregateCauses,description:"Hook x N"},{id:"signal::includeHistory",label:"Include history",value:"includeHistory",isActive:e.includeHistory,description:"JSON only \u2014 large"}]}],previewSection:{enabled:true,title:"PREVIEW",icon:M,content:A,headerActions:T},onFilterChange:R}),[e,l,R,A,T]);return d(O,{...j})}const b=D.create({previewScroll:{maxHeight:360},previewText:{fontFamily:W,fontSize:11,color:f.color.text,lineHeight:18},statusLabel:{fontSize:11,fontWeight:"600",color:f.color.textTertiary,marginRight:8}});
@@ -1,70 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * StatsDisplay
5
- *
6
- * Isolated component for displaying render statistics in the header.
7
- * Subscribes to RenderTracker updates independently so parent header
8
- * doesn't re-render when stats change.
9
- *
10
- * Following the optimization guide: move subscriptions to child components.
11
- */
12
-
13
- import React, { useState, useEffect, memo } from "react";
14
- import { View, Text, StyleSheet } from "react-native";
15
- import { Activity, night, monoFont } from "@buoy-gg/shared-ui";
16
- import { RenderTracker } from "../utils/RenderTracker";
17
-
18
- /**
19
- * Isolated stats display that owns its own subscription.
20
- * Only this component re-renders when stats change.
21
- */
22
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
- function StatsDisplayInner() {
24
- const [stats, setStats] = useState({
25
- totalComponents: 0,
26
- totalRenders: 0
27
- });
28
- useEffect(() => {
29
- const unsubscribe = RenderTracker.subscribe(() => {
30
- setStats(RenderTracker.getStats());
31
- });
32
- return unsubscribe;
33
- }, []);
34
- return /*#__PURE__*/_jsxs(View, {
35
- nativeID: "__rn_buoy__stats-row",
36
- testID: "buoy-highlight-stats",
37
- accessibilityLabel: `${stats.totalComponents} components tracked`,
38
- style: styles.headerChip,
39
- children: [/*#__PURE__*/_jsx(Activity, {
40
- size: 12,
41
- color: night.color.accent
42
- }), /*#__PURE__*/_jsx(Text, {
43
- testID: "buoy-highlight-stats-value",
44
- style: [styles.headerChipValue, {
45
- color: night.color.accent
46
- }],
47
- children: stats.totalComponents
48
- })]
49
- });
50
- }
51
- export const StatsDisplay = /*#__PURE__*/memo(StatsDisplayInner);
52
- const styles = StyleSheet.create({
53
- headerChip: {
54
- flexDirection: "row",
55
- alignItems: "center",
56
- gap: 4,
57
- backgroundColor: night.color.buttonSurface,
58
- paddingHorizontal: 8,
59
- paddingVertical: 5,
60
- borderRadius: 12,
61
- borderWidth: 1,
62
- borderColor: night.color.border
63
- },
64
- headerChipValue: {
65
- fontSize: 12,
66
- fontWeight: "600",
67
- fontFamily: monoFont
68
- }
69
- });
70
- export default StatsDisplay;
1
+ "use strict";import y,{useState as n,useEffect as c,memo as l}from"react";import{View as d,Text as h,StyleSheet as p}from"react-native";import{Activity as u,night as t,monoFont as m}from"@buoy-gg/shared-ui";import{RenderTracker as o}from"../utils/RenderTracker";import{jsx as r,jsxs as b}from"react/jsx-runtime";function f(){const[e,a]=n({totalComponents:0,totalRenders:0});c(()=>{const i=o.subscribe(()=>{a(o.getStats())});return i},[]);return b(d,{nativeID:"__rn_buoy__stats-row",testID:"buoy-highlight-stats",accessibilityLabel:`${e.totalComponents} components tracked`,style:s.headerChip,children:[r(u,{size:12,color:t.color.accent}),r(h,{testID:"buoy-highlight-stats-value",style:[s.headerChipValue,{color:t.color.accent}],children:e.totalComponents})]})}export const StatsDisplay=l(f);const s=p.create({headerChip:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:t.color.buttonSurface,paddingHorizontal:8,paddingVertical:5,borderRadius:12,borderWidth:1,borderColor:t.color.border},headerChipValue:{fontSize:12,fontWeight:"600",fontFamily:m}});export default StatsDisplay;
@@ -1,102 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Highlight Updates Copy Settings
5
- *
6
- * Configuration for exporting render reports as compact debug-focused output.
7
- */
8
-
9
- // -1 = all
10
-
11
- export const DEFAULT_COPY_SETTINGS = {
12
- format: "summary",
13
- topN: 25,
14
- minRenders: 2,
15
- filterCauses: [],
16
- groupByName: true,
17
- aggregateCauses: true,
18
- sortBy: "renderCount",
19
- includeHistory: false
20
- };
21
- export const COPY_PRESETS = {
22
- /** LLM-pasteable summary — the default */
23
- llm: {
24
- format: "summary",
25
- topN: 25,
26
- minRenders: 2,
27
- filterCauses: [],
28
- groupByName: true,
29
- aggregateCauses: true,
30
- sortBy: "renderCount",
31
- includeHistory: false
32
- },
33
- /** Markdown table for PR descriptions */
34
- table: {
35
- format: "markdown-table",
36
- topN: 50,
37
- minRenders: 2,
38
- filterCauses: [],
39
- groupByName: true,
40
- aggregateCauses: true,
41
- sortBy: "renderCount",
42
- includeHistory: false
43
- },
44
- /** Compact JSON, no history */
45
- json: {
46
- format: "json",
47
- topN: -1,
48
- minRenders: 1,
49
- filterCauses: [],
50
- groupByName: false,
51
- aggregateCauses: true,
52
- sortBy: "renderCount",
53
- includeHistory: false
54
- },
55
- /** Full JSON dump including history (escape hatch) */
56
- full: {
57
- format: "json",
58
- topN: -1,
59
- minRenders: 1,
60
- filterCauses: [],
61
- groupByName: false,
62
- aggregateCauses: false,
63
- sortBy: "renderCount",
64
- includeHistory: true
65
- }
66
- };
67
- export function detectActivePreset(settings) {
68
- for (const [name, preset] of Object.entries(COPY_PRESETS)) {
69
- const matches = Object.keys(preset).every(key => {
70
- const a = settings[key];
71
- const b = preset[key];
72
- if (Array.isArray(a) && Array.isArray(b)) {
73
- return a.length === b.length && a.every((v, i) => v === b[i]);
74
- }
75
- return a === b;
76
- });
77
- if (matches) return name;
78
- }
79
- return null;
80
- }
81
- export const PRESET_METADATA = {
82
- llm: {
83
- label: "LLM",
84
- description: "Compact summary for AI",
85
- color: "#10B981"
86
- },
87
- table: {
88
- label: "Table",
89
- description: "Markdown table",
90
- color: "#3B82F6"
91
- },
92
- json: {
93
- label: "JSON",
94
- description: "Structured data",
95
- color: "#F59E0B"
96
- },
97
- full: {
98
- label: "Full",
99
- description: "Everything incl. history",
100
- color: "#6B7280"
101
- }
102
- };
1
+ "use strict";export const DEFAULT_COPY_SETTINGS={format:"summary",topN:25,minRenders:2,filterCauses:[],groupByName:true,aggregateCauses:true,sortBy:"renderCount",includeHistory:false};export const COPY_PRESETS={llm:{format:"summary",topN:25,minRenders:2,filterCauses:[],groupByName:true,aggregateCauses:true,sortBy:"renderCount",includeHistory:false},table:{format:"markdown-table",topN:50,minRenders:2,filterCauses:[],groupByName:true,aggregateCauses:true,sortBy:"renderCount",includeHistory:false},json:{format:"json",topN:-1,minRenders:1,filterCauses:[],groupByName:false,aggregateCauses:true,sortBy:"renderCount",includeHistory:false},full:{format:"json",topN:-1,minRenders:1,filterCauses:[],groupByName:false,aggregateCauses:false,sortBy:"renderCount",includeHistory:true}};export function detectActivePreset(o){for(const[a,t]of Object.entries(COPY_PRESETS)){const n=Object.keys(t).every(s=>{const e=o[s];const r=t[s];if(Array.isArray(e)&&Array.isArray(r)){return e.length===r.length&&e.every((l,u)=>l===r[u])}return e===r});if(n)return a}return null}export const PRESET_METADATA={llm:{label:"LLM",description:"Compact summary for AI",color:"#10B981"},table:{label:"Table",description:"Markdown table",color:"#3B82F6"},json:{label:"JSON",description:"Structured data",color:"#F59E0B"},full:{label:"Full",description:"Everything incl. history",color:"#6B7280"}};