@buoy-gg/highlight-updates 7.0.32 → 7.0.34
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.
- package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +32 -31
- package/lib/commonjs/highlight-updates/components/ModalHeaderContent.js +17 -56
- package/lib/commonjs/highlight-updates/components/RenderHistoryViewer.js +14 -15
- package/lib/commonjs/highlight-updates/components/RendersCopySettingsView.js +28 -135
- package/lib/commonjs/highlight-updates/utils/copySettingsStorage.js +11 -28
- package/lib/module/highlight-updates/components/IsolatedRenderList.js +33 -32
- package/lib/module/highlight-updates/components/ModalHeaderContent.js +19 -58
- package/lib/module/highlight-updates/components/RenderHistoryViewer.js +15 -16
- package/lib/module/highlight-updates/components/RendersCopySettingsView.js +31 -138
- package/lib/module/highlight-updates/utils/copySettingsStorage.js +12 -29
- package/lib/typescript/highlight-updates/components/IsolatedRenderList.d.ts.map +1 -1
- package/lib/typescript/highlight-updates/components/ModalHeaderContent.d.ts.map +1 -1
- package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts +1 -1
- package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts.map +1 -1
- package/lib/typescript/highlight-updates/components/RendersCopySettingsView.d.ts.map +1 -1
- package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts +2 -1
- package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -110,21 +110,38 @@ function IsolatedRenderListInner({
|
|
|
110
110
|
|
|
111
111
|
// Show empty state when no renders
|
|
112
112
|
if (renders.length === 0) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
113
|
+
const term = searchText.trim();
|
|
114
|
+
|
|
115
|
+
// Read straight off the tracker rather than held in state: this runs only
|
|
116
|
+
// on the empty branch, so it costs nothing on the hot path, and it is
|
|
117
|
+
// always the current truth. `totalTracked` is every component the tracker
|
|
118
|
+
// holds; `unsearched` is what the settings and filters allow BEFORE the
|
|
119
|
+
// search box.
|
|
120
|
+
const totalTracked = _RenderTracker.RenderTracker.getStats().totalComponents;
|
|
121
|
+
const unsearched = term ? _RenderTracker.RenderTracker.getFilteredRenders("").length : 0;
|
|
122
|
+
const content = (0, _sharedUi.resolveListEmptyState)({
|
|
123
|
+
subject: "components",
|
|
124
|
+
verb: "tracked",
|
|
125
|
+
search: searchText,
|
|
126
|
+
// The denominator is what the FILTERS left, not the raw tracker count —
|
|
127
|
+
// "clear the search to see them" has to be true of what you get back.
|
|
128
|
+
total: term ? unsearched : totalTracked,
|
|
129
|
+
capturing: isTracking,
|
|
130
|
+
blocked: term && unsearched === 0 && totalTracked > 0 ? "The active filters hide everything tracked, so there is nothing to search." : undefined,
|
|
131
|
+
waiting: {
|
|
132
|
+
// stare = "watching for a specific event; recording armed".
|
|
133
|
+
otto: "stare",
|
|
134
|
+
title: "No renders tracked",
|
|
135
|
+
message: "Component renders will appear here"
|
|
136
|
+
},
|
|
137
|
+
paused: {
|
|
138
|
+
title: "No renders tracked",
|
|
139
|
+
message: "Enable tracking to start capturing"
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
143
|
+
...content,
|
|
144
|
+
testID: "buoy-highlight-empty"
|
|
128
145
|
});
|
|
129
146
|
}
|
|
130
147
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
|
|
@@ -149,22 +166,6 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
149
166
|
listContent: {
|
|
150
167
|
paddingTop: 8
|
|
151
168
|
},
|
|
152
|
-
emptyState: {
|
|
153
|
-
alignItems: "center",
|
|
154
|
-
paddingVertical: 40
|
|
155
|
-
},
|
|
156
|
-
emptyTitle: {
|
|
157
|
-
color: _sharedUi.night.color.text,
|
|
158
|
-
fontSize: 14,
|
|
159
|
-
fontWeight: "600",
|
|
160
|
-
marginTop: 12,
|
|
161
|
-
marginBottom: 6
|
|
162
|
-
},
|
|
163
|
-
emptyText: {
|
|
164
|
-
color: _sharedUi.night.color.textTertiary,
|
|
165
|
-
fontSize: 12,
|
|
166
|
-
textAlign: "center"
|
|
167
|
-
},
|
|
168
169
|
lockedBanner: {
|
|
169
170
|
flexDirection: "row",
|
|
170
171
|
alignItems: "center",
|
|
@@ -30,41 +30,23 @@ const SearchSectionInner = /*#__PURE__*/(0, _react.memo)(function SearchSection(
|
|
|
30
30
|
onSearchClose
|
|
31
31
|
}) {
|
|
32
32
|
if (!isActive) return null;
|
|
33
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
autoCapitalize: "none",
|
|
51
|
-
autoCorrect: false,
|
|
52
|
-
returnKeyType: "search",
|
|
53
|
-
autoFocus: true
|
|
54
|
-
}), searchText.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
55
|
-
testID: "buoy-highlight-search-clear",
|
|
56
|
-
accessibilityRole: "button",
|
|
57
|
-
accessibilityLabel: "Clear search",
|
|
58
|
-
onPress: () => {
|
|
59
|
-
onSearchChange("");
|
|
60
|
-
onSearchClose();
|
|
61
|
-
},
|
|
62
|
-
style: styles.headerSearchClear,
|
|
63
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
|
|
64
|
-
size: 14,
|
|
65
|
-
color: _sharedUi.night.color.textSecondary
|
|
66
|
-
})
|
|
67
|
-
}) : null]
|
|
33
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Search, {
|
|
34
|
+
value: searchText,
|
|
35
|
+
onChangeText: onSearchChange,
|
|
36
|
+
onCancel: () => {
|
|
37
|
+
onSearchChange("");
|
|
38
|
+
onSearchClose();
|
|
39
|
+
},
|
|
40
|
+
onDismiss: onSearchClose,
|
|
41
|
+
dismissOnBlur: true,
|
|
42
|
+
clearOnlyWhenText: true,
|
|
43
|
+
placeholder: "Search testID, nativeID, component...",
|
|
44
|
+
accessibilityLabel: "Search renders",
|
|
45
|
+
iconSize: 14,
|
|
46
|
+
testID: "buoy-highlight-search-field",
|
|
47
|
+
containerTestID: "buoy-highlight-search-container",
|
|
48
|
+
containerNativeID: "__rn_buoy__search-container",
|
|
49
|
+
clearTestID: "buoy-highlight-search-clear"
|
|
68
50
|
});
|
|
69
51
|
});
|
|
70
52
|
const SearchSection = exports.SearchSection = SearchSectionInner;
|
|
@@ -287,27 +269,6 @@ const CopySettingsViewHeader = exports.CopySettingsViewHeader = /*#__PURE__*/(0,
|
|
|
287
269
|
// ============================================================================
|
|
288
270
|
|
|
289
271
|
const styles = _reactNative.StyleSheet.create({
|
|
290
|
-
headerSearchContainer: {
|
|
291
|
-
flexDirection: "row",
|
|
292
|
-
alignItems: "center",
|
|
293
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
294
|
-
borderRadius: 10,
|
|
295
|
-
borderWidth: 1,
|
|
296
|
-
borderColor: _sharedUi.night.color.border,
|
|
297
|
-
paddingHorizontal: 12,
|
|
298
|
-
paddingVertical: 5
|
|
299
|
-
},
|
|
300
|
-
headerSearchInput: {
|
|
301
|
-
flex: 1,
|
|
302
|
-
color: _sharedUi.night.color.text,
|
|
303
|
-
fontSize: 13,
|
|
304
|
-
marginLeft: 6,
|
|
305
|
-
paddingVertical: 2
|
|
306
|
-
},
|
|
307
|
-
headerSearchClear: {
|
|
308
|
-
marginLeft: 6,
|
|
309
|
-
padding: 4
|
|
310
|
-
},
|
|
311
272
|
headerActionButton: {
|
|
312
273
|
width: 32,
|
|
313
274
|
height: 32,
|
|
@@ -10,6 +10,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
12
12
|
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
13
|
+
var _RenderTracker = require("../utils/RenderTracker");
|
|
13
14
|
var _RenderCauseBadge = require("./RenderCauseBadge");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
16
|
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); }
|
|
@@ -96,21 +97,19 @@ function RenderHistoryViewer({
|
|
|
96
97
|
|
|
97
98
|
// If no history, show empty state
|
|
98
99
|
if (totalEvents === 0) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
children: "Enable render history tracking in settings to see render events here."
|
|
113
|
-
})]
|
|
100
|
+
// The copy used to tell EVERYONE to go and enable the setting, including
|
|
101
|
+
// the people who already had. Asking the tracker which it is costs one
|
|
102
|
+
// synchronous read on a branch that renders nothing else.
|
|
103
|
+
const historyEnabled = _RenderTracker.RenderTracker.getSettings().enableRenderHistory;
|
|
104
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
105
|
+
testID: "buoy-highlight-history-empty"
|
|
106
|
+
// paused = the recorder is switched off; stare = armed and watching,
|
|
107
|
+
// which is the truth once the setting is on and this component simply
|
|
108
|
+
// has not re-rendered yet.
|
|
109
|
+
,
|
|
110
|
+
otto: historyEnabled ? "stare" : "paused",
|
|
111
|
+
title: "No Render History",
|
|
112
|
+
message: historyEnabled ? "History is on and armed — this component has not re-rendered since. Interact with the app to record one." : "Enable render history tracking in settings to see render events here."
|
|
114
113
|
});
|
|
115
114
|
}
|
|
116
115
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
@@ -195,77 +195,35 @@ function RendersCopySettingsView({
|
|
|
195
195
|
totalComponents,
|
|
196
196
|
totalRenders
|
|
197
197
|
} = (0, _rendersExportFormatter.getExportSummary)(previewRenders);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
size: 16,
|
|
225
|
-
color: _sharedUi.night.color.textTertiary
|
|
226
|
-
})]
|
|
198
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ExportPreview, {
|
|
199
|
+
expanded: isPreviewExpanded,
|
|
200
|
+
onExpandedChange: setIsPreviewExpanded,
|
|
201
|
+
summary: `${totalComponents} component${totalComponents !== 1 ? "s" : ""} · ${totalRenders} renders · ~${formatBytes(estimatedSize)}${!hasLiveData ? " (mock data)" : ""}`,
|
|
202
|
+
warningLevel: sizeWarningLevel,
|
|
203
|
+
warningText: {
|
|
204
|
+
warning: "Large payload — preview may be slow",
|
|
205
|
+
danger: "Very large payload — try a smaller topN or turn off history"
|
|
206
|
+
},
|
|
207
|
+
testIDs: {
|
|
208
|
+
expand: "buoy-highlight-copy-preview-show",
|
|
209
|
+
collapse: "buoy-highlight-copy-preview-hide",
|
|
210
|
+
summary: "buoy-highlight-copy-preview-summary",
|
|
211
|
+
warning: "buoy-highlight-copy-size-warning"
|
|
212
|
+
},
|
|
213
|
+
renderBody: () => {
|
|
214
|
+
const exportText = generateCopyText();
|
|
215
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
216
|
+
testID: "buoy-highlight-copy-preview-scroll",
|
|
217
|
+
style: styles.previewScroll,
|
|
218
|
+
nestedScrollEnabled: true,
|
|
219
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
220
|
+
testID: "buoy-highlight-copy-preview-text",
|
|
221
|
+
style: styles.previewText,
|
|
222
|
+
selectable: true,
|
|
223
|
+
children: exportText
|
|
227
224
|
})
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
style: [styles.sizeWarning, sizeWarningLevel === "danger" && styles.sizeWarningDanger],
|
|
231
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
232
|
-
size: 12,
|
|
233
|
-
color: warningColor
|
|
234
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
235
|
-
style: [styles.sizeWarningText, {
|
|
236
|
-
color: warningColor
|
|
237
|
-
}],
|
|
238
|
-
children: sizeWarningLevel === "danger" ? "Very large payload — try a smaller topN or turn off history" : "Large payload — preview may be slow"
|
|
239
|
-
})]
|
|
240
|
-
})]
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
const exportText = generateCopyText();
|
|
244
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
245
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
246
|
-
testID: "buoy-highlight-copy-preview-hide",
|
|
247
|
-
accessibilityRole: "button",
|
|
248
|
-
accessibilityLabel: "Hide preview",
|
|
249
|
-
style: styles.collapseButton,
|
|
250
|
-
onPress: () => setIsPreviewExpanded(false),
|
|
251
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
252
|
-
style: styles.collapseButtonText,
|
|
253
|
-
children: "Hide Preview"
|
|
254
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronUp, {
|
|
255
|
-
size: 14,
|
|
256
|
-
color: _sharedUi.night.color.textSecondary
|
|
257
|
-
})]
|
|
258
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
259
|
-
testID: "buoy-highlight-copy-preview-scroll",
|
|
260
|
-
style: styles.previewScroll,
|
|
261
|
-
nestedScrollEnabled: true,
|
|
262
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
263
|
-
testID: "buoy-highlight-copy-preview-text",
|
|
264
|
-
style: styles.previewText,
|
|
265
|
-
selectable: true,
|
|
266
|
-
children: exportText
|
|
267
|
-
})
|
|
268
|
-
})]
|
|
225
|
+
});
|
|
226
|
+
}
|
|
269
227
|
});
|
|
270
228
|
}, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
|
|
271
229
|
const renderPreviewHeaderActions = (0, _react.useCallback)(() => {
|
|
@@ -490,71 +448,6 @@ function RendersCopySettingsView({
|
|
|
490
448
|
});
|
|
491
449
|
}
|
|
492
450
|
const styles = _reactNative.StyleSheet.create({
|
|
493
|
-
collapsedPreview: {
|
|
494
|
-
gap: 8
|
|
495
|
-
},
|
|
496
|
-
expandButton: {
|
|
497
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
498
|
-
borderRadius: 8,
|
|
499
|
-
borderWidth: 1,
|
|
500
|
-
borderColor: _sharedUi.night.color.border,
|
|
501
|
-
padding: 12
|
|
502
|
-
},
|
|
503
|
-
expandButtonContent: {
|
|
504
|
-
flexDirection: "row",
|
|
505
|
-
alignItems: "center",
|
|
506
|
-
gap: 10
|
|
507
|
-
},
|
|
508
|
-
expandButtonTextContainer: {
|
|
509
|
-
flex: 1
|
|
510
|
-
},
|
|
511
|
-
expandButtonTitle: {
|
|
512
|
-
fontSize: 13,
|
|
513
|
-
fontWeight: "600",
|
|
514
|
-
color: _sharedUi.night.color.text
|
|
515
|
-
},
|
|
516
|
-
expandButtonSubtitle: {
|
|
517
|
-
fontSize: 11,
|
|
518
|
-
color: _sharedUi.night.color.textSecondary,
|
|
519
|
-
marginTop: 2
|
|
520
|
-
},
|
|
521
|
-
collapseButton: {
|
|
522
|
-
flexDirection: "row",
|
|
523
|
-
alignItems: "center",
|
|
524
|
-
justifyContent: "center",
|
|
525
|
-
gap: 6,
|
|
526
|
-
paddingVertical: 8,
|
|
527
|
-
marginBottom: 8,
|
|
528
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
529
|
-
borderRadius: 6,
|
|
530
|
-
borderWidth: 1,
|
|
531
|
-
borderColor: _sharedUi.night.color.border
|
|
532
|
-
},
|
|
533
|
-
collapseButtonText: {
|
|
534
|
-
fontSize: 12,
|
|
535
|
-
fontWeight: "500",
|
|
536
|
-
color: _sharedUi.night.color.textSecondary
|
|
537
|
-
},
|
|
538
|
-
sizeWarning: {
|
|
539
|
-
flexDirection: "row",
|
|
540
|
-
alignItems: "center",
|
|
541
|
-
gap: 6,
|
|
542
|
-
paddingHorizontal: 10,
|
|
543
|
-
paddingVertical: 6,
|
|
544
|
-
backgroundColor: _sharedUi.night.color.warningSoft,
|
|
545
|
-
borderRadius: 6,
|
|
546
|
-
borderWidth: 1,
|
|
547
|
-
borderColor: _sharedUi.night.color.warning + "30"
|
|
548
|
-
},
|
|
549
|
-
sizeWarningDanger: {
|
|
550
|
-
backgroundColor: _sharedUi.night.color.dangerSoft,
|
|
551
|
-
borderColor: _sharedUi.night.color.danger + "30"
|
|
552
|
-
},
|
|
553
|
-
sizeWarningText: {
|
|
554
|
-
fontSize: 11,
|
|
555
|
-
fontWeight: "500",
|
|
556
|
-
flex: 1
|
|
557
|
-
},
|
|
558
451
|
previewScroll: {
|
|
559
452
|
maxHeight: 360
|
|
560
453
|
},
|
|
@@ -11,39 +11,22 @@ var _copySettings = require("../types/copySettings");
|
|
|
11
11
|
/**
|
|
12
12
|
* Copy Settings Storage
|
|
13
13
|
*
|
|
14
|
-
* Persists the highlight-updates copy/export settings
|
|
14
|
+
* Persists the highlight-updates copy/export settings through the shared
|
|
15
|
+
* `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
|
|
15
16
|
*/
|
|
16
17
|
|
|
18
|
+
const copySettings = (0, _sharedUi.definePersistedSetting)(_sharedUi.devToolsStorageKeys.highlightUpdates.copySettings(), _copySettings.DEFAULT_COPY_SETTINGS, {
|
|
19
|
+
sanitize: (merged, stored) => ({
|
|
20
|
+
...merged,
|
|
21
|
+
filterCauses: stored?.filterCauses ?? _copySettings.DEFAULT_COPY_SETTINGS.filterCauses
|
|
22
|
+
})
|
|
23
|
+
});
|
|
17
24
|
async function saveCopySettings(settings) {
|
|
18
|
-
|
|
19
|
-
const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
|
|
20
|
-
await _sharedUi.persistentStorage.setItem(key, JSON.stringify(settings));
|
|
21
|
-
} catch {
|
|
22
|
-
// Silently fail — persistence is optional
|
|
23
|
-
}
|
|
25
|
+
await copySettings.save(settings);
|
|
24
26
|
}
|
|
25
27
|
async function loadCopySettings() {
|
|
26
|
-
|
|
27
|
-
const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
|
|
28
|
-
const value = await _sharedUi.persistentStorage.getItem(key);
|
|
29
|
-
if (value && value !== "") {
|
|
30
|
-
const parsed = JSON.parse(value);
|
|
31
|
-
return {
|
|
32
|
-
..._copySettings.DEFAULT_COPY_SETTINGS,
|
|
33
|
-
...parsed,
|
|
34
|
-
filterCauses: parsed.filterCauses ?? _copySettings.DEFAULT_COPY_SETTINGS.filterCauses
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
} catch {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
28
|
+
return copySettings.loadOrNull();
|
|
41
29
|
}
|
|
42
30
|
async function clearCopySettings() {
|
|
43
|
-
|
|
44
|
-
const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
|
|
45
|
-
await _sharedUi.persistentStorage.removeItem(key);
|
|
46
|
-
} catch {
|
|
47
|
-
// Silently fail
|
|
48
|
-
}
|
|
31
|
+
await copySettings.clear();
|
|
49
32
|
}
|
|
@@ -15,7 +15,7 @@ import React, { useState, useEffect, useRef, useCallback, memo, useMemo } from "
|
|
|
15
15
|
import { View, Text, FlatList, StyleSheet } from "react-native";
|
|
16
16
|
import { RenderTracker } from "../utils/RenderTracker";
|
|
17
17
|
import { RenderListItem } from "./RenderListItem";
|
|
18
|
-
import {
|
|
18
|
+
import { Lock, night, useLimit, ToolEmptyState, resolveListEmptyState } from "@buoy-gg/shared-ui";
|
|
19
19
|
|
|
20
20
|
// Free tier limit for tracked components
|
|
21
21
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -105,21 +105,38 @@ function IsolatedRenderListInner({
|
|
|
105
105
|
|
|
106
106
|
// Show empty state when no renders
|
|
107
107
|
if (renders.length === 0) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
108
|
+
const term = searchText.trim();
|
|
109
|
+
|
|
110
|
+
// Read straight off the tracker rather than held in state: this runs only
|
|
111
|
+
// on the empty branch, so it costs nothing on the hot path, and it is
|
|
112
|
+
// always the current truth. `totalTracked` is every component the tracker
|
|
113
|
+
// holds; `unsearched` is what the settings and filters allow BEFORE the
|
|
114
|
+
// search box.
|
|
115
|
+
const totalTracked = RenderTracker.getStats().totalComponents;
|
|
116
|
+
const unsearched = term ? RenderTracker.getFilteredRenders("").length : 0;
|
|
117
|
+
const content = resolveListEmptyState({
|
|
118
|
+
subject: "components",
|
|
119
|
+
verb: "tracked",
|
|
120
|
+
search: searchText,
|
|
121
|
+
// The denominator is what the FILTERS left, not the raw tracker count —
|
|
122
|
+
// "clear the search to see them" has to be true of what you get back.
|
|
123
|
+
total: term ? unsearched : totalTracked,
|
|
124
|
+
capturing: isTracking,
|
|
125
|
+
blocked: term && unsearched === 0 && totalTracked > 0 ? "The active filters hide everything tracked, so there is nothing to search." : undefined,
|
|
126
|
+
waiting: {
|
|
127
|
+
// stare = "watching for a specific event; recording armed".
|
|
128
|
+
otto: "stare",
|
|
129
|
+
title: "No renders tracked",
|
|
130
|
+
message: "Component renders will appear here"
|
|
131
|
+
},
|
|
132
|
+
paused: {
|
|
133
|
+
title: "No renders tracked",
|
|
134
|
+
message: "Enable tracking to start capturing"
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
138
|
+
...content,
|
|
139
|
+
testID: "buoy-highlight-empty"
|
|
123
140
|
});
|
|
124
141
|
}
|
|
125
142
|
return /*#__PURE__*/_jsx(FlatList, {
|
|
@@ -144,22 +161,6 @@ const styles = StyleSheet.create({
|
|
|
144
161
|
listContent: {
|
|
145
162
|
paddingTop: 8
|
|
146
163
|
},
|
|
147
|
-
emptyState: {
|
|
148
|
-
alignItems: "center",
|
|
149
|
-
paddingVertical: 40
|
|
150
|
-
},
|
|
151
|
-
emptyTitle: {
|
|
152
|
-
color: night.color.text,
|
|
153
|
-
fontSize: 14,
|
|
154
|
-
fontWeight: "600",
|
|
155
|
-
marginTop: 12,
|
|
156
|
-
marginBottom: 6
|
|
157
|
-
},
|
|
158
|
-
emptyText: {
|
|
159
|
-
color: night.color.textTertiary,
|
|
160
|
-
fontSize: 12,
|
|
161
|
-
textAlign: "center"
|
|
162
|
-
},
|
|
163
164
|
lockedBanner: {
|
|
164
165
|
flexDirection: "row",
|
|
165
166
|
alignItems: "center",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import React, { memo } from "react";
|
|
13
|
-
import {
|
|
14
|
-
import { Trash2, Search, Filter,
|
|
13
|
+
import { TouchableOpacity, StyleSheet } from "react-native";
|
|
14
|
+
import { Trash2, Search, Filter, Pause, Copy, ModalHeader, TabSelector, night, PowerToggleButton } from "@buoy-gg/shared-ui";
|
|
15
15
|
import { StatsDisplay } from "./StatsDisplay";
|
|
16
16
|
|
|
17
17
|
// ============================================================================
|
|
@@ -25,41 +25,23 @@ const SearchSectionInner = /*#__PURE__*/memo(function SearchSection({
|
|
|
25
25
|
onSearchClose
|
|
26
26
|
}) {
|
|
27
27
|
if (!isActive) return null;
|
|
28
|
-
return /*#__PURE__*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
autoCapitalize: "none",
|
|
46
|
-
autoCorrect: false,
|
|
47
|
-
returnKeyType: "search",
|
|
48
|
-
autoFocus: true
|
|
49
|
-
}), searchText.length > 0 ? /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
50
|
-
testID: "buoy-highlight-search-clear",
|
|
51
|
-
accessibilityRole: "button",
|
|
52
|
-
accessibilityLabel: "Clear search",
|
|
53
|
-
onPress: () => {
|
|
54
|
-
onSearchChange("");
|
|
55
|
-
onSearchClose();
|
|
56
|
-
},
|
|
57
|
-
style: styles.headerSearchClear,
|
|
58
|
-
children: /*#__PURE__*/_jsx(X, {
|
|
59
|
-
size: 14,
|
|
60
|
-
color: night.color.textSecondary
|
|
61
|
-
})
|
|
62
|
-
}) : null]
|
|
28
|
+
return /*#__PURE__*/_jsx(ModalHeader.Search, {
|
|
29
|
+
value: searchText,
|
|
30
|
+
onChangeText: onSearchChange,
|
|
31
|
+
onCancel: () => {
|
|
32
|
+
onSearchChange("");
|
|
33
|
+
onSearchClose();
|
|
34
|
+
},
|
|
35
|
+
onDismiss: onSearchClose,
|
|
36
|
+
dismissOnBlur: true,
|
|
37
|
+
clearOnlyWhenText: true,
|
|
38
|
+
placeholder: "Search testID, nativeID, component...",
|
|
39
|
+
accessibilityLabel: "Search renders",
|
|
40
|
+
iconSize: 14,
|
|
41
|
+
testID: "buoy-highlight-search-field",
|
|
42
|
+
containerTestID: "buoy-highlight-search-container",
|
|
43
|
+
containerNativeID: "__rn_buoy__search-container",
|
|
44
|
+
clearTestID: "buoy-highlight-search-clear"
|
|
63
45
|
});
|
|
64
46
|
});
|
|
65
47
|
export const SearchSection = SearchSectionInner;
|
|
@@ -282,27 +264,6 @@ export const CopySettingsViewHeader = /*#__PURE__*/memo(function CopySettingsVie
|
|
|
282
264
|
// ============================================================================
|
|
283
265
|
|
|
284
266
|
const styles = StyleSheet.create({
|
|
285
|
-
headerSearchContainer: {
|
|
286
|
-
flexDirection: "row",
|
|
287
|
-
alignItems: "center",
|
|
288
|
-
backgroundColor: night.color.surfaceElevated,
|
|
289
|
-
borderRadius: 10,
|
|
290
|
-
borderWidth: 1,
|
|
291
|
-
borderColor: night.color.border,
|
|
292
|
-
paddingHorizontal: 12,
|
|
293
|
-
paddingVertical: 5
|
|
294
|
-
},
|
|
295
|
-
headerSearchInput: {
|
|
296
|
-
flex: 1,
|
|
297
|
-
color: night.color.text,
|
|
298
|
-
fontSize: 13,
|
|
299
|
-
marginLeft: 6,
|
|
300
|
-
paddingVertical: 2
|
|
301
|
-
},
|
|
302
|
-
headerSearchClear: {
|
|
303
|
-
marginLeft: 6,
|
|
304
|
-
padding: 4
|
|
305
|
-
},
|
|
306
267
|
headerActionButton: {
|
|
307
268
|
width: 32,
|
|
308
269
|
height: 32,
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
import React, { useState, useCallback, useMemo } from "react";
|
|
12
12
|
import { View, Text, TouchableOpacity, ScrollView, StyleSheet } from "react-native";
|
|
13
|
-
import { Clock, GitBranch, Database, Lock, formatRelativeTime, SectionHeader, EventStepperFooter, buoyColors, night, useLimit } from "@buoy-gg/shared-ui";
|
|
13
|
+
import { Clock, GitBranch, Database, Lock, formatRelativeTime, SectionHeader, EventStepperFooter, buoyColors, night, useLimit, ToolEmptyState } from "@buoy-gg/shared-ui";
|
|
14
14
|
import { TreeDiffViewer } from "@buoy-gg/shared-ui/dataViewer";
|
|
15
|
+
import { RenderTracker } from "../utils/RenderTracker";
|
|
15
16
|
import { EnhancedCauseDisplay, CAUSE_CONFIG } from "./RenderCauseBadge";
|
|
16
17
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
17
18
|
/**
|
|
@@ -89,21 +90,19 @@ export function RenderHistoryViewer({
|
|
|
89
90
|
|
|
90
91
|
// If no history, show empty state
|
|
91
92
|
if (totalEvents === 0) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
children: "Enable render history tracking in settings to see render events here."
|
|
106
|
-
})]
|
|
93
|
+
// The copy used to tell EVERYONE to go and enable the setting, including
|
|
94
|
+
// the people who already had. Asking the tracker which it is costs one
|
|
95
|
+
// synchronous read on a branch that renders nothing else.
|
|
96
|
+
const historyEnabled = RenderTracker.getSettings().enableRenderHistory;
|
|
97
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
98
|
+
testID: "buoy-highlight-history-empty"
|
|
99
|
+
// paused = the recorder is switched off; stare = armed and watching,
|
|
100
|
+
// which is the truth once the setting is on and this component simply
|
|
101
|
+
// has not re-rendered yet.
|
|
102
|
+
,
|
|
103
|
+
otto: historyEnabled ? "stare" : "paused",
|
|
104
|
+
title: "No Render History",
|
|
105
|
+
message: historyEnabled ? "History is on and armed — this component has not re-rendered since. Interact with the app to record one." : "Enable render history tracking in settings to see render events here."
|
|
107
106
|
});
|
|
108
107
|
}
|
|
109
108
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
11
|
-
import { Text, StyleSheet, ScrollView
|
|
12
|
-
import { DynamicFilterView, macOSColors, night, FileText, FileCode, Zap, Settings, Eye,
|
|
11
|
+
import { Text, StyleSheet, ScrollView } from "react-native";
|
|
12
|
+
import { DynamicFilterView, macOSColors, night, FileText, FileCode, Zap, Settings, Eye, Layers, ToolbarCopyButton, ExportPreview } from "@buoy-gg/shared-ui";
|
|
13
13
|
import { DEFAULT_COPY_SETTINGS, COPY_PRESETS, PRESET_METADATA, detectActivePreset } from "../types/copySettings";
|
|
14
14
|
import { generateExport, estimateExportSize, getExportSummary } from "../utils/rendersExportFormatter";
|
|
15
15
|
import { loadCopySettings, saveCopySettings } from "../utils/copySettingsStorage";
|
|
16
|
-
import { jsx as _jsx,
|
|
16
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
17
|
const SIZE_WARNING_THRESHOLD = 50 * 1024;
|
|
18
18
|
const SIZE_DANGER_THRESHOLD = 200 * 1024;
|
|
19
19
|
const CAUSE_OPTIONS = [{
|
|
@@ -191,77 +191,35 @@ export function RendersCopySettingsView({
|
|
|
191
191
|
totalComponents,
|
|
192
192
|
totalRenders
|
|
193
193
|
} = getExportSummary(previewRenders);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
size: 16,
|
|
221
|
-
color: night.color.textTertiary
|
|
222
|
-
})]
|
|
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
|
|
223
220
|
})
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
style: [styles.sizeWarning, sizeWarningLevel === "danger" && styles.sizeWarningDanger],
|
|
227
|
-
children: [/*#__PURE__*/_jsx(AlertTriangle, {
|
|
228
|
-
size: 12,
|
|
229
|
-
color: warningColor
|
|
230
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
231
|
-
style: [styles.sizeWarningText, {
|
|
232
|
-
color: warningColor
|
|
233
|
-
}],
|
|
234
|
-
children: sizeWarningLevel === "danger" ? "Very large payload — try a smaller topN or turn off history" : "Large payload — preview may be slow"
|
|
235
|
-
})]
|
|
236
|
-
})]
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
const exportText = generateCopyText();
|
|
240
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
241
|
-
children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
242
|
-
testID: "buoy-highlight-copy-preview-hide",
|
|
243
|
-
accessibilityRole: "button",
|
|
244
|
-
accessibilityLabel: "Hide preview",
|
|
245
|
-
style: styles.collapseButton,
|
|
246
|
-
onPress: () => setIsPreviewExpanded(false),
|
|
247
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
248
|
-
style: styles.collapseButtonText,
|
|
249
|
-
children: "Hide Preview"
|
|
250
|
-
}), /*#__PURE__*/_jsx(ChevronUp, {
|
|
251
|
-
size: 14,
|
|
252
|
-
color: night.color.textSecondary
|
|
253
|
-
})]
|
|
254
|
-
}), /*#__PURE__*/_jsx(ScrollView, {
|
|
255
|
-
testID: "buoy-highlight-copy-preview-scroll",
|
|
256
|
-
style: styles.previewScroll,
|
|
257
|
-
nestedScrollEnabled: true,
|
|
258
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
259
|
-
testID: "buoy-highlight-copy-preview-text",
|
|
260
|
-
style: styles.previewText,
|
|
261
|
-
selectable: true,
|
|
262
|
-
children: exportText
|
|
263
|
-
})
|
|
264
|
-
})]
|
|
221
|
+
});
|
|
222
|
+
}
|
|
265
223
|
});
|
|
266
224
|
}, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
|
|
267
225
|
const renderPreviewHeaderActions = useCallback(() => {
|
|
@@ -486,71 +444,6 @@ export function RendersCopySettingsView({
|
|
|
486
444
|
});
|
|
487
445
|
}
|
|
488
446
|
const styles = StyleSheet.create({
|
|
489
|
-
collapsedPreview: {
|
|
490
|
-
gap: 8
|
|
491
|
-
},
|
|
492
|
-
expandButton: {
|
|
493
|
-
backgroundColor: night.color.surfaceElevated,
|
|
494
|
-
borderRadius: 8,
|
|
495
|
-
borderWidth: 1,
|
|
496
|
-
borderColor: night.color.border,
|
|
497
|
-
padding: 12
|
|
498
|
-
},
|
|
499
|
-
expandButtonContent: {
|
|
500
|
-
flexDirection: "row",
|
|
501
|
-
alignItems: "center",
|
|
502
|
-
gap: 10
|
|
503
|
-
},
|
|
504
|
-
expandButtonTextContainer: {
|
|
505
|
-
flex: 1
|
|
506
|
-
},
|
|
507
|
-
expandButtonTitle: {
|
|
508
|
-
fontSize: 13,
|
|
509
|
-
fontWeight: "600",
|
|
510
|
-
color: night.color.text
|
|
511
|
-
},
|
|
512
|
-
expandButtonSubtitle: {
|
|
513
|
-
fontSize: 11,
|
|
514
|
-
color: night.color.textSecondary,
|
|
515
|
-
marginTop: 2
|
|
516
|
-
},
|
|
517
|
-
collapseButton: {
|
|
518
|
-
flexDirection: "row",
|
|
519
|
-
alignItems: "center",
|
|
520
|
-
justifyContent: "center",
|
|
521
|
-
gap: 6,
|
|
522
|
-
paddingVertical: 8,
|
|
523
|
-
marginBottom: 8,
|
|
524
|
-
backgroundColor: night.color.surfaceElevated,
|
|
525
|
-
borderRadius: 6,
|
|
526
|
-
borderWidth: 1,
|
|
527
|
-
borderColor: night.color.border
|
|
528
|
-
},
|
|
529
|
-
collapseButtonText: {
|
|
530
|
-
fontSize: 12,
|
|
531
|
-
fontWeight: "500",
|
|
532
|
-
color: night.color.textSecondary
|
|
533
|
-
},
|
|
534
|
-
sizeWarning: {
|
|
535
|
-
flexDirection: "row",
|
|
536
|
-
alignItems: "center",
|
|
537
|
-
gap: 6,
|
|
538
|
-
paddingHorizontal: 10,
|
|
539
|
-
paddingVertical: 6,
|
|
540
|
-
backgroundColor: night.color.warningSoft,
|
|
541
|
-
borderRadius: 6,
|
|
542
|
-
borderWidth: 1,
|
|
543
|
-
borderColor: night.color.warning + "30"
|
|
544
|
-
},
|
|
545
|
-
sizeWarningDanger: {
|
|
546
|
-
backgroundColor: night.color.dangerSoft,
|
|
547
|
-
borderColor: night.color.danger + "30"
|
|
548
|
-
},
|
|
549
|
-
sizeWarningText: {
|
|
550
|
-
fontSize: 11,
|
|
551
|
-
fontWeight: "500",
|
|
552
|
-
flex: 1
|
|
553
|
-
},
|
|
554
447
|
previewScroll: {
|
|
555
448
|
maxHeight: 360
|
|
556
449
|
},
|
|
@@ -3,41 +3,24 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Copy Settings Storage
|
|
5
5
|
*
|
|
6
|
-
* Persists the highlight-updates copy/export settings
|
|
6
|
+
* Persists the highlight-updates copy/export settings through the shared
|
|
7
|
+
* `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
import {
|
|
10
|
+
import { definePersistedSetting, devToolsStorageKeys } from "@buoy-gg/shared-ui";
|
|
10
11
|
import { DEFAULT_COPY_SETTINGS } from "../types/copySettings";
|
|
12
|
+
const copySettings = definePersistedSetting(devToolsStorageKeys.highlightUpdates.copySettings(), DEFAULT_COPY_SETTINGS, {
|
|
13
|
+
sanitize: (merged, stored) => ({
|
|
14
|
+
...merged,
|
|
15
|
+
filterCauses: stored?.filterCauses ?? DEFAULT_COPY_SETTINGS.filterCauses
|
|
16
|
+
})
|
|
17
|
+
});
|
|
11
18
|
export async function saveCopySettings(settings) {
|
|
12
|
-
|
|
13
|
-
const key = devToolsStorageKeys.highlightUpdates.copySettings();
|
|
14
|
-
await persistentStorage.setItem(key, JSON.stringify(settings));
|
|
15
|
-
} catch {
|
|
16
|
-
// Silently fail — persistence is optional
|
|
17
|
-
}
|
|
19
|
+
await copySettings.save(settings);
|
|
18
20
|
}
|
|
19
21
|
export async function loadCopySettings() {
|
|
20
|
-
|
|
21
|
-
const key = devToolsStorageKeys.highlightUpdates.copySettings();
|
|
22
|
-
const value = await persistentStorage.getItem(key);
|
|
23
|
-
if (value && value !== "") {
|
|
24
|
-
const parsed = JSON.parse(value);
|
|
25
|
-
return {
|
|
26
|
-
...DEFAULT_COPY_SETTINGS,
|
|
27
|
-
...parsed,
|
|
28
|
-
filterCauses: parsed.filterCauses ?? DEFAULT_COPY_SETTINGS.filterCauses
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
} catch {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
22
|
+
return copySettings.loadOrNull();
|
|
35
23
|
}
|
|
36
24
|
export async function clearCopySettings() {
|
|
37
|
-
|
|
38
|
-
const key = devToolsStorageKeys.highlightUpdates.copySettings();
|
|
39
|
-
await persistentStorage.removeItem(key);
|
|
40
|
-
} catch {
|
|
41
|
-
// Silently fail
|
|
42
|
-
}
|
|
25
|
+
await copySettings.clear();
|
|
43
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IsolatedRenderList.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/IsolatedRenderList.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAkE,MAAM,OAAO,CAAC;AAEvF,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"IsolatedRenderList.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/IsolatedRenderList.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAkE,MAAM,OAAO,CAAC;AAEvF,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAW9F,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,cAAc,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IAC5F,aAAa,EAAE,CAAC,KAAK,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAClF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,iBAAS,uBAAuB,CAAC,EAC/B,UAAU,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,eAAe,EACf,UAAU,EACV,KAAa,GACd,EAAE,uBAAuB,qBAiIzB;AAGD,eAAO,MAAM,kBAAkB,2DAAgC,CAAC;AA0BhE,eAAe,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalHeaderContent.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/ModalHeaderContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EAIL,SAAS,EAEV,MAAM,cAAc,CAAC;AAmBtB,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"ModalHeaderContent.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/ModalHeaderContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EAIL,SAAS,EAEV,MAAM,cAAc,CAAC;AAmBtB,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAgCD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAyHD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,cAAc,iDAgDzB,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB,mDA4B3B,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAElD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,mDAyB3B,CAAC;AAMH,UAAU,2BAA2B;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,yDAYjC,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Shows current state view or diff view between renders.
|
|
7
7
|
*/
|
|
8
8
|
import React from "react";
|
|
9
|
-
import type
|
|
9
|
+
import { type TrackedRender } from "../utils/RenderTracker";
|
|
10
10
|
interface RenderHistoryViewerProps {
|
|
11
11
|
render: TrackedRender;
|
|
12
12
|
/** If true, use external footer (modal provides it) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderHistoryViewer.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RenderHistoryViewer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RenderHistoryViewer.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RenderHistoryViewer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;AAiB9D,OAAO,EAAiB,KAAK,aAAa,EAAoB,MAAM,wBAAwB,CAAC;AAG7F,UAAU,wBAAwB;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,uDAAuD;IACvD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,wCAAwC;IACxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wCAAwC;IACxC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAqBD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,qBAA6B,EAC7B,kBAAkB,EAAE,aAAa,EACjC,kBAAkB,EAAE,gBAAgB,EACpC,KAAa,GACd,EAAE,wBAAwB,qBAiN1B;AAyRD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,kBAAsB,EACtB,kBAA6B,EAC7B,KAAa,GACd,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,4BA6CA;AA+YD,eAAe,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RendersCopySettingsView.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RendersCopySettingsView.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"RendersCopySettingsView.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RendersCopySettingsView.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,wBAAwB,CAAC;AAmB7E,UAAU,4BAA4B;IACpC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AA+ED,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,GACR,EAAE,4BAA4B,+BAuY9B"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copy Settings Storage
|
|
3
3
|
*
|
|
4
|
-
* Persists the highlight-updates copy/export settings
|
|
4
|
+
* Persists the highlight-updates copy/export settings through the shared
|
|
5
|
+
* `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
|
|
5
6
|
*/
|
|
6
7
|
import type { RendersCopySettings } from "../types/copySettings";
|
|
7
8
|
export declare function saveCopySettings(settings: RendersCopySettings): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copySettingsStorage.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/utils/copySettingsStorage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"copySettingsStorage.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/utils/copySettingsStorage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAgBjE,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAE5E;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/highlight-updates",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.34",
|
|
4
4
|
"description": "Render highlighter for React Native — see every render with its cause: mount, state, props, or parent. Part of Buoy devtools.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
30
|
-
"@buoy-gg/floating-tools-core": "^7.0.
|
|
29
|
+
"@buoy-gg/shared-ui": "^7.0.34",
|
|
30
|
+
"@buoy-gg/floating-tools-core": "^7.0.34"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@buoy-gg/license": "7.0.
|
|
33
|
+
"@buoy-gg/license": "7.0.34",
|
|
34
34
|
"react": "*",
|
|
35
35
|
"react-native": "*",
|
|
36
|
-
"@buoy-gg/core": "^7.0.
|
|
36
|
+
"@buoy-gg/core": "^7.0.34"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@buoy-gg/core": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"@types/react": "^19.1.0",
|
|
45
45
|
"@types/react-native": "^0.73.0",
|
|
46
46
|
"typescript": "~5.8.3",
|
|
47
|
-
"@buoy-gg/core": "^7.0.
|
|
48
|
-
"@buoy-gg/license": "^7.0.
|
|
47
|
+
"@buoy-gg/core": "^7.0.34",
|
|
48
|
+
"@buoy-gg/license": "^7.0.34"
|
|
49
49
|
},
|
|
50
50
|
"react-native-builder-bob": {
|
|
51
51
|
"source": "src",
|