@buoy-gg/highlight-updates 7.0.38 → 7.0.40

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