@buoy-gg/highlight-updates 7.0.35 → 7.0.38

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 (107) hide show
  1. package/README.md +28 -6
  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 -466
  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 -446
  16. package/lib/commonjs/highlight-updates/utils/HighlightUpdatesController.js +1 -1920
  17. package/lib/commonjs/highlight-updates/utils/PerformanceLogger.js +1 -359
  18. package/lib/commonjs/highlight-updates/utils/ProfilerInterceptor.js +1 -371
  19. package/lib/commonjs/highlight-updates/utils/RenderCauseDetector.js +1 -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/renderExportFormatter.js +1 -58
  28. package/lib/commonjs/highlight-updates/utils/rendersExportFormatter.js +1 -485
  29. package/lib/commonjs/highlight-updates/utils/screenElements.js +1 -1046
  30. package/lib/commonjs/highlight-updates/utils/tapMatch.js +1 -58
  31. package/lib/commonjs/highlight-updates/utils/testIDs.js +1 -68
  32. package/lib/commonjs/highlight-updates/utils/touchCapture.js +1 -277
  33. package/lib/commonjs/index.js +1 -429
  34. package/lib/commonjs/preset.js +1 -278
  35. package/lib/commonjs/sync/highlightUpdatesSyncAdapter.js +1 -235
  36. package/lib/module/highlight-updates/HighlightUpdatesOverlay.js +1 -274
  37. package/lib/module/highlight-updates/components/HighlightFilterView.js +1 -1468
  38. package/lib/module/highlight-updates/components/HighlightUpdatesModal.js +1 -634
  39. package/lib/module/highlight-updates/components/IdentifierBadge.js +1 -265
  40. package/lib/module/highlight-updates/components/IsolatedRenderList.js +1 -183
  41. package/lib/module/highlight-updates/components/ModalHeaderContent.js +1 -288
  42. package/lib/module/highlight-updates/components/RenderCauseBadge.js +1 -499
  43. package/lib/module/highlight-updates/components/RenderDetailView.js +1 -840
  44. package/lib/module/highlight-updates/components/RenderHistoryViewer.js +1 -908
  45. package/lib/module/highlight-updates/components/RenderListItem.js +1 -230
  46. package/lib/module/highlight-updates/components/RendersCopySettingsView.js +1 -462
  47. package/lib/module/highlight-updates/components/StatsDisplay.js +1 -70
  48. package/lib/module/highlight-updates/types/copySettings.js +1 -102
  49. package/lib/module/highlight-updates/utils/CommitProfiler.js +1 -442
  50. package/lib/module/highlight-updates/utils/HighlightUpdatesController.js +1 -1916
  51. package/lib/module/highlight-updates/utils/PerformanceLogger.js +1 -353
  52. package/lib/module/highlight-updates/utils/ProfilerInterceptor.js +1 -358
  53. package/lib/module/highlight-updates/utils/RenderCauseDetector.js +1 -1830
  54. package/lib/module/highlight-updates/utils/RenderTracker.js +1 -949
  55. package/lib/module/highlight-updates/utils/ViewTypeMapper.js +1 -255
  56. package/lib/module/highlight-updates/utils/copySettingsStorage.js +1 -26
  57. package/lib/module/highlight-updates/utils/devtoolsComponentNames.js +1 -178
  58. package/lib/module/highlight-updates/utils/namedComposite.js +1 -36
  59. package/lib/module/highlight-updates/utils/ownStateChanged.js +1 -98
  60. package/lib/module/highlight-updates/utils/rawEventEmitter.js +1 -46
  61. package/lib/module/highlight-updates/utils/renderExportFormatter.js +1 -54
  62. package/lib/module/highlight-updates/utils/rendersExportFormatter.js +1 -478
  63. package/lib/module/highlight-updates/utils/screenElements.js +1 -1040
  64. package/lib/module/highlight-updates/utils/tapMatch.js +1 -52
  65. package/lib/module/highlight-updates/utils/testIDs.js +1 -60
  66. package/lib/module/highlight-updates/utils/touchCapture.js +1 -270
  67. package/lib/module/index.js +1 -130
  68. package/lib/module/preset.js +1 -272
  69. package/lib/module/sync/highlightUpdatesSyncAdapter.js +1 -230
  70. package/lib/typescript/highlight-updates/utils/screenElements.d.ts +52 -1
  71. package/lib/typescript/highlight-updates/utils/tapMatch.d.ts +11 -0
  72. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts +1 -1
  73. package/package.json +8 -8
  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/renderExportFormatter.d.ts.map +0 -1
  100. package/lib/typescript/highlight-updates/utils/rendersExportFormatter.d.ts.map +0 -1
  101. package/lib/typescript/highlight-updates/utils/screenElements.d.ts.map +0 -1
  102. package/lib/typescript/highlight-updates/utils/tapMatch.d.ts.map +0 -1
  103. package/lib/typescript/highlight-updates/utils/testIDs.d.ts.map +0 -1
  104. package/lib/typescript/highlight-updates/utils/touchCapture.d.ts.map +0 -1
  105. package/lib/typescript/index.d.ts.map +0 -1
  106. package/lib/typescript/preset.d.ts.map +0 -1
  107. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts.map +0 -1
@@ -1,462 +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
- const preset = COPY_PRESETS[name];
132
- updateSettings({
133
- ...preset,
134
- filterCauses: [...preset.filterCauses]
135
- });
136
- }, [updateSettings]);
137
- const handleOptionChange = useCallback((optionId, value) => {
138
- const [group, key] = optionId.split("::");
139
- if (group === "preset") {
140
- applyPreset(key);
141
- return;
142
- }
143
- if (group === "format") {
144
- updateSettings({
145
- ...settings,
146
- format: value
147
- });
148
- return;
149
- }
150
- if (group === "sort") {
151
- updateSettings({
152
- ...settings,
153
- sortBy: value
154
- });
155
- return;
156
- }
157
- if (group === "topN") {
158
- updateSettings({
159
- ...settings,
160
- topN: value
161
- });
162
- return;
163
- }
164
- if (group === "minRenders") {
165
- updateSettings({
166
- ...settings,
167
- minRenders: value
168
- });
169
- return;
170
- }
171
- if (group === "cause") {
172
- const cause = value;
173
- const has = settings.filterCauses.includes(cause);
174
- updateSettings({
175
- ...settings,
176
- filterCauses: has ? settings.filterCauses.filter(c => c !== cause) : [...settings.filterCauses, cause]
177
- });
178
- return;
179
- }
180
- if (group === "signal") {
181
- const k = key;
182
- updateSettings({
183
- ...settings,
184
- [k]: !settings[k]
185
- });
186
- return;
187
- }
188
- }, [settings, updateSettings, applyPreset]);
189
- const renderPreviewContent = useCallback(() => {
190
- const {
191
- totalComponents,
192
- totalRenders
193
- } = getExportSummary(previewRenders);
194
- return /*#__PURE__*/_jsx(ExportPreview, {
195
- expanded: isPreviewExpanded,
196
- onExpandedChange: setIsPreviewExpanded,
197
- summary: `${totalComponents} component${totalComponents !== 1 ? "s" : ""} · ${totalRenders} renders · ~${formatBytes(estimatedSize)}${!hasLiveData ? " (mock data)" : ""}`,
198
- warningLevel: sizeWarningLevel,
199
- warningText: {
200
- warning: "Large payload — preview may be slow",
201
- danger: "Very large payload — try a smaller topN or turn off history"
202
- },
203
- testIDs: {
204
- expand: "buoy-highlight-copy-preview-show",
205
- collapse: "buoy-highlight-copy-preview-hide",
206
- summary: "buoy-highlight-copy-preview-summary",
207
- warning: "buoy-highlight-copy-size-warning"
208
- },
209
- renderBody: () => {
210
- const exportText = generateCopyText();
211
- return /*#__PURE__*/_jsx(ScrollView, {
212
- testID: "buoy-highlight-copy-preview-scroll",
213
- style: styles.previewScroll,
214
- nestedScrollEnabled: true,
215
- children: /*#__PURE__*/_jsx(Text, {
216
- testID: "buoy-highlight-copy-preview-text",
217
- style: styles.previewText,
218
- selectable: true,
219
- children: exportText
220
- })
221
- });
222
- }
223
- });
224
- }, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
225
- const renderPreviewHeaderActions = useCallback(() => {
226
- const {
227
- totalComponents
228
- } = getExportSummary(previewRenders);
229
- const statusLabel = hasLiveData ? `${totalComponents} components` : "Mock data (no renders captured)";
230
- return /*#__PURE__*/_jsxs(_Fragment, {
231
- children: [/*#__PURE__*/_jsx(Text, {
232
- testID: "buoy-highlight-copy-status",
233
- style: styles.statusLabel,
234
- children: statusLabel
235
- }), /*#__PURE__*/_jsx(ToolbarCopyButton, {
236
- value: generateCopyText
237
- })]
238
- });
239
- }, [hasLiveData, previewRenders, generateCopyText]);
240
- const dynamicFilterConfig = useMemo(() => ({
241
- sections: [{
242
- id: "presets",
243
- title: "Presets",
244
- type: "custom",
245
- data: [{
246
- id: "preset::llm",
247
- label: PRESET_METADATA.llm.label,
248
- icon: Zap,
249
- color: PRESET_METADATA.llm.color,
250
- value: "llm",
251
- isActive: activePreset === "llm",
252
- description: PRESET_METADATA.llm.description
253
- }, {
254
- id: "preset::table",
255
- label: PRESET_METADATA.table.label,
256
- icon: FileText,
257
- color: PRESET_METADATA.table.color,
258
- value: "table",
259
- isActive: activePreset === "table",
260
- description: PRESET_METADATA.table.description
261
- }, {
262
- id: "preset::json",
263
- label: PRESET_METADATA.json.label,
264
- icon: FileCode,
265
- color: PRESET_METADATA.json.color,
266
- value: "json",
267
- isActive: activePreset === "json",
268
- description: PRESET_METADATA.json.description
269
- }, {
270
- id: "preset::full",
271
- label: PRESET_METADATA.full.label,
272
- icon: Layers,
273
- color: PRESET_METADATA.full.color,
274
- value: "full",
275
- isActive: activePreset === "full",
276
- description: PRESET_METADATA.full.description
277
- }, {
278
- id: "preset::custom",
279
- label: "Custom",
280
- icon: Settings,
281
- color: night.color.textSecondary,
282
- value: "custom",
283
- isActive: activePreset === null,
284
- description: "User-configured"
285
- }]
286
- }, {
287
- id: "format",
288
- title: "Format",
289
- type: "custom",
290
- data: [{
291
- id: "format::summary",
292
- label: "Summary",
293
- icon: Zap,
294
- color: macOSColors.semantic.success,
295
- value: "summary",
296
- isActive: settings.format === "summary",
297
- description: "Compact, LLM-ready"
298
- }, {
299
- id: "format::markdown-table",
300
- label: "Table",
301
- icon: FileText,
302
- color: macOSColors.semantic.info,
303
- value: "markdown-table",
304
- isActive: settings.format === "markdown-table",
305
- description: "Markdown table"
306
- }, {
307
- id: "format::json",
308
- label: "JSON",
309
- icon: FileCode,
310
- color: macOSColors.semantic.warning,
311
- value: "json",
312
- isActive: settings.format === "json",
313
- description: "Structured data"
314
- }]
315
- }, {
316
- id: "sort",
317
- title: "Sort By",
318
- type: "custom",
319
- data: [{
320
- id: "sort::renderCount",
321
- label: "Count",
322
- value: "renderCount",
323
- isActive: settings.sortBy === "renderCount",
324
- description: "Total renders"
325
- }, {
326
- id: "sort::rate",
327
- label: "Rate",
328
- value: "rate",
329
- isActive: settings.sortBy === "rate",
330
- description: "Renders / sec"
331
- }, {
332
- id: "sort::name",
333
- label: "Name",
334
- value: "name",
335
- isActive: settings.sortBy === "name",
336
- description: "Alphabetical"
337
- }]
338
- }, {
339
- id: "topN",
340
- title: "Top N",
341
- type: "custom",
342
- data: [{
343
- id: "topN::10",
344
- label: "10",
345
- value: 10,
346
- isActive: settings.topN === 10
347
- }, {
348
- id: "topN::25",
349
- label: "25",
350
- value: 25,
351
- isActive: settings.topN === 25
352
- }, {
353
- id: "topN::50",
354
- label: "50",
355
- value: 50,
356
- isActive: settings.topN === 50
357
- }, {
358
- id: "topN::100",
359
- label: "100",
360
- value: 100,
361
- isActive: settings.topN === 100
362
- }, {
363
- id: "topN::-1",
364
- label: "All",
365
- value: -1,
366
- isActive: settings.topN === -1
367
- }]
368
- }, {
369
- id: "minRenders",
370
- title: "Min Renders",
371
- type: "custom",
372
- data: [{
373
- id: "minRenders::1",
374
- label: "1",
375
- value: 1,
376
- isActive: settings.minRenders === 1
377
- }, {
378
- id: "minRenders::2",
379
- label: "2",
380
- value: 2,
381
- isActive: settings.minRenders === 2
382
- }, {
383
- id: "minRenders::3",
384
- label: "3",
385
- value: 3,
386
- isActive: settings.minRenders === 3
387
- }, {
388
- id: "minRenders::5",
389
- label: "5",
390
- value: 5,
391
- isActive: settings.minRenders === 5
392
- }, {
393
- id: "minRenders::10",
394
- label: "10",
395
- value: 10,
396
- isActive: settings.minRenders === 10
397
- }]
398
- }, {
399
- id: "causes",
400
- title: "Filter Causes",
401
- type: "custom",
402
- description: settings.filterCauses.length === 0 ? "All causes shown" : "Only the selected causes shown",
403
- data: CAUSE_OPTIONS.map(opt => ({
404
- id: `cause::${opt.value}`,
405
- label: opt.label,
406
- value: opt.value,
407
- isActive: settings.filterCauses.includes(opt.value)
408
- }))
409
- }, {
410
- id: "signal",
411
- title: "Signal Extraction",
412
- type: "custom",
413
- data: [{
414
- id: "signal::groupByName",
415
- label: "Group by name",
416
- value: "groupByName",
417
- isActive: settings.groupByName,
418
- description: "Collapse list items"
419
- }, {
420
- id: "signal::aggregateCauses",
421
- label: "Aggregate causes",
422
- value: "aggregateCauses",
423
- isActive: settings.aggregateCauses,
424
- description: "Hook x N"
425
- }, {
426
- id: "signal::includeHistory",
427
- label: "Include history",
428
- value: "includeHistory",
429
- isActive: settings.includeHistory,
430
- description: "JSON only — large"
431
- }]
432
- }],
433
- previewSection: {
434
- enabled: true,
435
- title: "PREVIEW",
436
- icon: Eye,
437
- content: renderPreviewContent,
438
- headerActions: renderPreviewHeaderActions
439
- },
440
- onFilterChange: handleOptionChange
441
- }), [settings, activePreset, handleOptionChange, renderPreviewContent, renderPreviewHeaderActions]);
442
- return /*#__PURE__*/_jsx(DynamicFilterView, {
443
- ...dynamicFilterConfig
444
- });
445
- }
446
- const styles = StyleSheet.create({
447
- previewScroll: {
448
- maxHeight: 360
449
- },
450
- previewText: {
451
- fontFamily: monoFont,
452
- fontSize: 11,
453
- color: night.color.text,
454
- lineHeight: 18
455
- },
456
- statusLabel: {
457
- fontSize: 11,
458
- fontWeight: "600",
459
- color: night.color.textTertiary,
460
- marginRight: 8
461
- }
462
- });
1
+ "use strict";import{useCallback,useEffect,useMemo,useState}from"react";import{Text,StyleSheet,ScrollView}from"react-native";import{DynamicFilterView,macOSColors,night,FileText,FileCode,Zap,Settings,Eye,Layers,ToolbarCopyButton,ExportPreview,monoFont}from"@buoy-gg/shared-ui";import{DEFAULT_COPY_SETTINGS,COPY_PRESETS,PRESET_METADATA,detectActivePreset}from"../types/copySettings";import{generateExport,estimateExportSize,getExportSummary}from"../utils/rendersExportFormatter";import{loadCopySettings,saveCopySettings}from"../utils/copySettingsStorage";import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";const SIZE_WARNING_THRESHOLD=51200,SIZE_DANGER_THRESHOLD=204800,CAUSE_OPTIONS=[{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 formatBytes(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function createMockRenders(){const e=Date.now();return[{id:"1",nativeTag:1,viewType:"RCTView",displayName:"View",componentName:"PokemonListItem",renderCount:30,firstRenderTime:e-5e3,lastRenderTime:e,color:"#10B981",lastRenderCause:{type:"parent",timestamp:e,componentCause:"parent"}},{id:"2",nativeTag:2,viewType:"RCTView",displayName:"View",componentName:"CartHeader",renderCount:12,firstRenderTime:e-4e3,lastRenderTime:e,color:"#3B82F6",lastRenderCause:{type:"hooks",timestamp:e,componentCause:"state",hookChanges:[{type:"useState",index:2,previousValue:4,currentValue:5}]}},{id:"3",nativeTag:3,viewType:"RCTView",displayName:"View",componentName:"SearchBar",renderCount:8,firstRenderTime:e-3e3,lastRenderTime:e,color:"#F59E0B",lastRenderCause:{type:"props",timestamp:e,componentCause:"props",changedKeys:["query","onChange"]}}]}export function RendersCopySettingsView({renders:e}){const[t,i]=useState(DEFAULT_COPY_SETTINGS),[o,a]=useState(!1);useEffect(()=>{let e=!0;return loadCopySettings().then(t=>{e&&t&&i(t)}),()=>{e=!1}},[]);const s=useCallback(e=>{i(e),saveCopySettings(e)},[]),l=e.length>0,r=l?e:createMockRenders(),n=useMemo(()=>detectActivePreset(t),[t]),c=useMemo(()=>estimateExportSize(r,t),[r,t]),u=useMemo(()=>c>=204800?"danger":c>=51200?"warning":"none",[c]),d=useCallback(()=>generateExport(r,t),[r,t]),m=useCallback(e=>{const t=COPY_PRESETS[e];t&&s({...t,filterCauses:[...t.filterCauses]})},[s]),p=useCallback((e,i)=>{const[o,a]=e.split("::");if("preset"!==o)if("format"!==o)if("sort"!==o)if("topN"!==o)if("minRenders"!==o){if("cause"===o){const e=i,o=t.filterCauses.includes(e);return void s({...t,filterCauses:o?t.filterCauses.filter(t=>t!==e):[...t.filterCauses,e]})}if("signal"===o){const e=a;return void s({...t,[e]:!t[e]})}}else s({...t,minRenders:i});else s({...t,topN:i});else s({...t,sortBy:i});else s({...t,format:i});else m(a)},[t,s,m]),y=useCallback(()=>{const{totalComponents:e,totalRenders:t}=getExportSummary(r);return _jsx(ExportPreview,{expanded:o,onExpandedChange:a,summary:`${e} component${1!==e?"s":""} · ${t} renders · ~${formatBytes(c)}${l?"":" (mock data)"}`,warningLevel:u,warningText:{warning:"Large payload — preview may be slow",danger:"Very large payload — 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 e=d();return _jsx(ScrollView,{testID:"buoy-highlight-copy-preview-scroll",style:styles.previewScroll,nestedScrollEnabled:!0,children:_jsx(Text,{testID:"buoy-highlight-copy-preview-text",style:styles.previewText,selectable:!0,children:e})})}})},[o,r,c,u,l,d]),v=useCallback(()=>{const{totalComponents:e}=getExportSummary(r),t=l?`${e} components`:"Mock data (no renders captured)";return _jsxs(_Fragment,{children:[_jsx(Text,{testID:"buoy-highlight-copy-status",style:styles.statusLabel,children:t}),_jsx(ToolbarCopyButton,{value:d})]})},[l,r,d]),g=useMemo(()=>({sections:[{id:"presets",title:"Presets",type:"custom",data:[{id:"preset::llm",label:PRESET_METADATA.llm.label,icon:Zap,color:PRESET_METADATA.llm.color,value:"llm",isActive:"llm"===n,description:PRESET_METADATA.llm.description},{id:"preset::table",label:PRESET_METADATA.table.label,icon:FileText,color:PRESET_METADATA.table.color,value:"table",isActive:"table"===n,description:PRESET_METADATA.table.description},{id:"preset::json",label:PRESET_METADATA.json.label,icon:FileCode,color:PRESET_METADATA.json.color,value:"json",isActive:"json"===n,description:PRESET_METADATA.json.description},{id:"preset::full",label:PRESET_METADATA.full.label,icon:Layers,color:PRESET_METADATA.full.color,value:"full",isActive:"full"===n,description:PRESET_METADATA.full.description},{id:"preset::custom",label:"Custom",icon:Settings,color:night.color.textSecondary,value:"custom",isActive:null===n,description:"User-configured"}]},{id:"format",title:"Format",type:"custom",data:[{id:"format::summary",label:"Summary",icon:Zap,color:macOSColors.semantic.success,value:"summary",isActive:"summary"===t.format,description:"Compact, LLM-ready"},{id:"format::markdown-table",label:"Table",icon:FileText,color:macOSColors.semantic.info,value:"markdown-table",isActive:"markdown-table"===t.format,description:"Markdown table"},{id:"format::json",label:"JSON",icon:FileCode,color:macOSColors.semantic.warning,value:"json",isActive:"json"===t.format,description:"Structured data"}]},{id:"sort",title:"Sort By",type:"custom",data:[{id:"sort::renderCount",label:"Count",value:"renderCount",isActive:"renderCount"===t.sortBy,description:"Total renders"},{id:"sort::rate",label:"Rate",value:"rate",isActive:"rate"===t.sortBy,description:"Renders / sec"},{id:"sort::name",label:"Name",value:"name",isActive:"name"===t.sortBy,description:"Alphabetical"}]},{id:"topN",title:"Top N",type:"custom",data:[{id:"topN::10",label:"10",value:10,isActive:10===t.topN},{id:"topN::25",label:"25",value:25,isActive:25===t.topN},{id:"topN::50",label:"50",value:50,isActive:50===t.topN},{id:"topN::100",label:"100",value:100,isActive:100===t.topN},{id:"topN::-1",label:"All",value:-1,isActive:-1===t.topN}]},{id:"minRenders",title:"Min Renders",type:"custom",data:[{id:"minRenders::1",label:"1",value:1,isActive:1===t.minRenders},{id:"minRenders::2",label:"2",value:2,isActive:2===t.minRenders},{id:"minRenders::3",label:"3",value:3,isActive:3===t.minRenders},{id:"minRenders::5",label:"5",value:5,isActive:5===t.minRenders},{id:"minRenders::10",label:"10",value:10,isActive:10===t.minRenders}]},{id:"causes",title:"Filter Causes",type:"custom",description:0===t.filterCauses.length?"All causes shown":"Only the selected causes shown",data:CAUSE_OPTIONS.map(e=>({id:`cause::${e.value}`,label:e.label,value:e.value,isActive:t.filterCauses.includes(e.value)}))},{id:"signal",title:"Signal Extraction",type:"custom",data:[{id:"signal::groupByName",label:"Group by name",value:"groupByName",isActive:t.groupByName,description:"Collapse list items"},{id:"signal::aggregateCauses",label:"Aggregate causes",value:"aggregateCauses",isActive:t.aggregateCauses,description:"Hook x N"},{id:"signal::includeHistory",label:"Include history",value:"includeHistory",isActive:t.includeHistory,description:"JSON only — large"}]}],previewSection:{enabled:!0,title:"PREVIEW",icon:Eye,content:y,headerActions:v},onFilterChange:p}),[t,n,p,y,v]);return _jsx(DynamicFilterView,{...g})}const styles=StyleSheet.create({previewScroll:{maxHeight:360},previewText:{fontFamily:monoFont,fontSize:11,color:night.color.text,lineHeight:18},statusLabel:{fontSize:11,fontWeight:"600",color:night.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 React,{useState,useEffect,memo}from"react";import{View,Text,StyleSheet}from"react-native";import{Activity,night,monoFont}from"@buoy-gg/shared-ui";import{RenderTracker}from"../utils/RenderTracker";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function StatsDisplayInner(){const[t,e]=useState({totalComponents:0,totalRenders:0});return useEffect(()=>RenderTracker.subscribe(()=>{e(RenderTracker.getStats())}),[]),_jsxs(View,{nativeID:"__rn_buoy__stats-row",testID:"buoy-highlight-stats",accessibilityLabel:`${t.totalComponents} components tracked`,style:styles.headerChip,children:[_jsx(Activity,{size:12,color:night.color.accent}),_jsx(Text,{testID:"buoy-highlight-stats-value",style:[styles.headerChipValue,{color:night.color.accent}],children:t.totalComponents})]})}export const StatsDisplay=memo(StatsDisplayInner);const styles=StyleSheet.create({headerChip:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:night.color.buttonSurface,paddingHorizontal:8,paddingVertical:5,borderRadius:12,borderWidth:1,borderColor:night.color.border},headerChipValue:{fontSize:12,fontWeight:"600",fontFamily:monoFont}});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:!0,aggregateCauses:!0,sortBy:"renderCount",includeHistory:!1};export const COPY_PRESETS={llm:{format:"summary",topN:25,minRenders:2,filterCauses:[],groupByName:!0,aggregateCauses:!0,sortBy:"renderCount",includeHistory:!1},table:{format:"markdown-table",topN:50,minRenders:2,filterCauses:[],groupByName:!0,aggregateCauses:!0,sortBy:"renderCount",includeHistory:!1},json:{format:"json",topN:-1,minRenders:1,filterCauses:[],groupByName:!1,aggregateCauses:!0,sortBy:"renderCount",includeHistory:!1},full:{format:"json",topN:-1,minRenders:1,filterCauses:[],groupByName:!1,aggregateCauses:!1,sortBy:"renderCount",includeHistory:!0}};export function detectActivePreset(e){for(const[r,t]of Object.entries(COPY_PRESETS))if(Object.keys(t).every(r=>{const o=e[r],s=t[r];return Array.isArray(o)&&Array.isArray(s)?o.length===s.length&&o.every((e,r)=>e===s[r]):o===s}))return r;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"}};