@buoy-gg/js-top 7.0.41 → 7.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +12 -71
  2. package/lib/commonjs/index.js +1 -99
  3. package/lib/commonjs/js-top/components/BusySparkline.js +1 -56
  4. package/lib/commonjs/js-top/components/JsTopHudOverlay.js +1 -79
  5. package/lib/commonjs/js-top/components/JsTopModal.js +1 -349
  6. package/lib/commonjs/js-top/components/TaskDetailView.js +1 -330
  7. package/lib/commonjs/js-top/components/TaskTable.js +1 -360
  8. package/lib/commonjs/js-top/engine/JsTopController.js +1 -350
  9. package/lib/commonjs/js-top/engine/aggregator.js +1 -148
  10. package/lib/commonjs/js-top/engine/busyProbe.js +1 -101
  11. package/lib/commonjs/js-top/engine/frameStack.js +1 -133
  12. package/lib/commonjs/js-top/engine/longtasks.js +1 -141
  13. package/lib/commonjs/js-top/engine/now.js +1 -38
  14. package/lib/commonjs/js-top/engine/originRegistry.js +1 -402
  15. package/lib/commonjs/js-top/engine/patches/bridge.js +1 -60
  16. package/lib/commonjs/js-top/engine/patches/microtasks.js +1 -27
  17. package/lib/commonjs/js-top/engine/patches/promises.js +1 -65
  18. package/lib/commonjs/js-top/engine/patches/timers.js +1 -66
  19. package/lib/commonjs/js-top/engine/state.js +1 -63
  20. package/lib/commonjs/js-top/engine/symbolicate.js +1 -95
  21. package/lib/commonjs/js-top/sync/jsTopSyncAdapter.js +1 -74
  22. package/lib/commonjs/js-top/types/index.js +1 -46
  23. package/lib/commonjs/js-top/utils/preferences.js +1 -31
  24. package/lib/commonjs/preset.js +1 -75
  25. package/lib/module/index.js +1 -49
  26. package/lib/module/js-top/components/BusySparkline.js +1 -52
  27. package/lib/module/js-top/components/JsTopHudOverlay.js +1 -75
  28. package/lib/module/js-top/components/JsTopModal.js +1 -345
  29. package/lib/module/js-top/components/TaskDetailView.js +1 -326
  30. package/lib/module/js-top/components/TaskTable.js +1 -353
  31. package/lib/module/js-top/engine/JsTopController.js +1 -347
  32. package/lib/module/js-top/engine/aggregator.js +1 -136
  33. package/lib/module/js-top/engine/busyProbe.js +1 -94
  34. package/lib/module/js-top/engine/frameStack.js +1 -126
  35. package/lib/module/js-top/engine/longtasks.js +1 -133
  36. package/lib/module/js-top/engine/now.js +1 -33
  37. package/lib/module/js-top/engine/originRegistry.js +1 -388
  38. package/lib/module/js-top/engine/patches/bridge.js +1 -56
  39. package/lib/module/js-top/engine/patches/microtasks.js +1 -23
  40. package/lib/module/js-top/engine/patches/promises.js +1 -62
  41. package/lib/module/js-top/engine/patches/timers.js +1 -62
  42. package/lib/module/js-top/engine/state.js +1 -54
  43. package/lib/module/js-top/engine/symbolicate.js +1 -91
  44. package/lib/module/js-top/sync/jsTopSyncAdapter.js +1 -70
  45. package/lib/module/js-top/types/index.js +1 -42
  46. package/lib/module/js-top/utils/preferences.js +1 -26
  47. package/lib/module/preset.js +1 -71
  48. package/lib/web/index.mjs +2 -3
  49. package/package.json +3 -6
  50. package/lib/commonjs/index.js.map +0 -1
  51. package/lib/commonjs/js-top/components/BusySparkline.js.map +0 -1
  52. package/lib/commonjs/js-top/components/JsTopHudOverlay.js.map +0 -1
  53. package/lib/commonjs/js-top/components/JsTopModal.js.map +0 -1
  54. package/lib/commonjs/js-top/components/TaskDetailView.js.map +0 -1
  55. package/lib/commonjs/js-top/components/TaskTable.js.map +0 -1
  56. package/lib/commonjs/js-top/engine/JsTopController.js.map +0 -1
  57. package/lib/commonjs/js-top/engine/aggregator.js.map +0 -1
  58. package/lib/commonjs/js-top/engine/busyProbe.js.map +0 -1
  59. package/lib/commonjs/js-top/engine/frameStack.js.map +0 -1
  60. package/lib/commonjs/js-top/engine/longtasks.js.map +0 -1
  61. package/lib/commonjs/js-top/engine/now.js.map +0 -1
  62. package/lib/commonjs/js-top/engine/originRegistry.js.map +0 -1
  63. package/lib/commonjs/js-top/engine/patches/bridge.js.map +0 -1
  64. package/lib/commonjs/js-top/engine/patches/microtasks.js.map +0 -1
  65. package/lib/commonjs/js-top/engine/patches/promises.js.map +0 -1
  66. package/lib/commonjs/js-top/engine/patches/timers.js.map +0 -1
  67. package/lib/commonjs/js-top/engine/state.js.map +0 -1
  68. package/lib/commonjs/js-top/engine/symbolicate.js.map +0 -1
  69. package/lib/commonjs/js-top/sync/jsTopSyncAdapter.js.map +0 -1
  70. package/lib/commonjs/js-top/types/index.js.map +0 -1
  71. package/lib/commonjs/js-top/utils/preferences.js.map +0 -1
  72. package/lib/commonjs/preset.js.map +0 -1
  73. package/lib/module/index.js.map +0 -1
  74. package/lib/module/js-top/components/BusySparkline.js.map +0 -1
  75. package/lib/module/js-top/components/JsTopHudOverlay.js.map +0 -1
  76. package/lib/module/js-top/components/JsTopModal.js.map +0 -1
  77. package/lib/module/js-top/components/TaskDetailView.js.map +0 -1
  78. package/lib/module/js-top/components/TaskTable.js.map +0 -1
  79. package/lib/module/js-top/engine/JsTopController.js.map +0 -1
  80. package/lib/module/js-top/engine/aggregator.js.map +0 -1
  81. package/lib/module/js-top/engine/busyProbe.js.map +0 -1
  82. package/lib/module/js-top/engine/frameStack.js.map +0 -1
  83. package/lib/module/js-top/engine/longtasks.js.map +0 -1
  84. package/lib/module/js-top/engine/now.js.map +0 -1
  85. package/lib/module/js-top/engine/originRegistry.js.map +0 -1
  86. package/lib/module/js-top/engine/patches/bridge.js.map +0 -1
  87. package/lib/module/js-top/engine/patches/microtasks.js.map +0 -1
  88. package/lib/module/js-top/engine/patches/promises.js.map +0 -1
  89. package/lib/module/js-top/engine/patches/timers.js.map +0 -1
  90. package/lib/module/js-top/engine/state.js.map +0 -1
  91. package/lib/module/js-top/engine/symbolicate.js.map +0 -1
  92. package/lib/module/js-top/sync/jsTopSyncAdapter.js.map +0 -1
  93. package/lib/module/js-top/types/index.js.map +0 -1
  94. package/lib/module/js-top/utils/preferences.js.map +0 -1
  95. package/lib/module/preset.js.map +0 -1
  96. package/lib/typescript/index.d.ts.map +0 -1
  97. package/lib/typescript/js-top/components/BusySparkline.d.ts.map +0 -1
  98. package/lib/typescript/js-top/components/JsTopHudOverlay.d.ts.map +0 -1
  99. package/lib/typescript/js-top/components/JsTopModal.d.ts.map +0 -1
  100. package/lib/typescript/js-top/components/TaskDetailView.d.ts.map +0 -1
  101. package/lib/typescript/js-top/components/TaskTable.d.ts.map +0 -1
  102. package/lib/typescript/js-top/engine/JsTopController.d.ts.map +0 -1
  103. package/lib/typescript/js-top/engine/aggregator.d.ts.map +0 -1
  104. package/lib/typescript/js-top/engine/busyProbe.d.ts.map +0 -1
  105. package/lib/typescript/js-top/engine/frameStack.d.ts.map +0 -1
  106. package/lib/typescript/js-top/engine/longtasks.d.ts.map +0 -1
  107. package/lib/typescript/js-top/engine/now.d.ts.map +0 -1
  108. package/lib/typescript/js-top/engine/originRegistry.d.ts.map +0 -1
  109. package/lib/typescript/js-top/engine/patches/bridge.d.ts.map +0 -1
  110. package/lib/typescript/js-top/engine/patches/microtasks.d.ts.map +0 -1
  111. package/lib/typescript/js-top/engine/patches/promises.d.ts.map +0 -1
  112. package/lib/typescript/js-top/engine/patches/timers.d.ts.map +0 -1
  113. package/lib/typescript/js-top/engine/state.d.ts.map +0 -1
  114. package/lib/typescript/js-top/engine/symbolicate.d.ts.map +0 -1
  115. package/lib/typescript/js-top/sync/jsTopSyncAdapter.d.ts.map +0 -1
  116. package/lib/typescript/js-top/types/index.d.ts.map +0 -1
  117. package/lib/typescript/js-top/utils/preferences.d.ts.map +0 -1
  118. package/lib/typescript/preset.d.ts.map +0 -1
@@ -1,330 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.TaskDetailView = void 0;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _TaskTable = require("./TaskTable");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- /**
13
- * TaskDetailView — the "inspect process" screen behind a row tap.
14
- *
15
- * Shows everything the engine knows about one origin: a 5s activity bar
16
- * chart (the per-origin bucket ring, rendered nowhere else), the full stat
17
- * grid (schedules vs runs, avg/max/total, freezes), the captured scheduling
18
- * site (caller + raw frames), and a plain-language explanation of what this
19
- * origin type means. Data refreshes with the modal's snapshot tick — the
20
- * parent re-renders us and we re-pull the detail.
21
- */
22
-
23
- const API_EXPLAINER = {
24
- timeout: "Work scheduled with setTimeout. Time shown is the callback's exclusive run time on the JS thread.",
25
- interval: "A repeating setInterval. One scheduling site, many runs — a hot interval is the classic silent JS-FPS killer.",
26
- immediate: "Work scheduled with setImmediate — runs at the end of the current event-loop turn.",
27
- raf: "requestAnimationFrame work — runs once per frame while scheduled. Cost here directly trades against 60fps.",
28
- microtask: "queueMicrotask work — runs after the current task, before the thread yields.",
29
- then: "Promise reaction (.then/.catch/.finally). Named by the function that attached the reaction. Note: async/await bodies bypass .then and land in the System row instead.",
30
- bridge: "A native→JS call-in over the legacy bridge (events, module callbacks), measured as its un-nested remainder.",
31
- unattributed: "Thread time the probe measured but no JS wrapper could claim: touch handlers, React commits, native call-ins, and async/await bodies. High here on New Architecture is normal — it's where UI work lives.",
32
- other: "Origins evicted from the table when the registry hit its cap — their totals are preserved here."
33
- };
34
- function explainerFor(api) {
35
- return API_EXPLAINER[api] ?? API_EXPLAINER.other;
36
- }
37
- function fmt(n) {
38
- if (n >= 10_000) return `${Math.round(n / 1000)}k`;
39
- if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;
40
- if (n >= 100) return `${Math.round(n)}`;
41
- return `${Math.round(n * 100) / 100}`;
42
- }
43
- function agoFmt(ms) {
44
- if (ms <= 0) return "—";
45
- const sec = ms / 1000;
46
- if (sec < 1) return "just now";
47
- if (sec < 60) return `${Math.round(sec)}s ago`;
48
- return `${Math.floor(sec / 60)}m ago`;
49
- }
50
- function Stat({
51
- label,
52
- value,
53
- accent
54
- }) {
55
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
56
- style: styles.stat,
57
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
58
- style: styles.statLabel,
59
- children: label
60
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
61
- style: [styles.statValue, accent ? {
62
- color: accent
63
- } : null],
64
- children: value
65
- })]
66
- });
67
- }
68
- const TaskDetailView = exports.TaskDetailView = /*#__PURE__*/(0, _react.memo)(function TaskDetailView({
69
- detail
70
- }) {
71
- const badge = (0, _TaskTable.badgeFor)(detail.api);
72
- const insets = (0, _sharedUi.useSafeAreaInsets)({
73
- minBottom: 12
74
- });
75
- const maxBucket = Math.max(1, ...detail.buckets);
76
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
77
- style: styles.root,
78
- contentContainerStyle: {
79
- paddingBottom: insets.bottom
80
- },
81
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
82
- style: styles.identityRow,
83
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
84
- style: [styles.badge, {
85
- borderColor: badge.color,
86
- backgroundColor: `${badge.color}1A`
87
- }],
88
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
89
- style: [styles.badgeText, {
90
- color: badge.color
91
- }],
92
- children: badge.text
93
- })
94
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
95
- style: styles.name,
96
- numberOfLines: 2,
97
- children: (0, _TaskTable.displayName)(detail)
98
- })]
99
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
100
- style: styles.explainer,
101
- children: explainerFor(detail.api)
102
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
103
- style: styles.sectionTitle,
104
- children: "ACTIVITY \xB7 LAST 5S"
105
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
106
- style: styles.chartRow,
107
- children: detail.buckets.map((ms, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
108
- style: styles.chartBarSlot,
109
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
110
- style: [styles.chartBar, {
111
- height: Math.max(2, ms / maxBucket * 44),
112
- backgroundColor: badge.color
113
- }]
114
- })
115
- }, `bk${i}`))
116
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
117
- style: styles.chartLegend,
118
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
119
- style: styles.chartLegendText,
120
- children: [fmt(detail.windowMs), " ms in window \xB7 ", detail.pctOfBusy.toFixed(1), "% of busy time"]
121
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
122
- style: styles.chartLegendText,
123
- children: ["peak ", fmt(maxBucket), " ms/250ms"]
124
- })]
125
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
126
- style: styles.sectionTitle,
127
- children: "STATS \xB7 SINCE START"
128
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
129
- style: styles.statGrid,
130
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
131
- label: "RUNS",
132
- value: detail.calls > 0 ? fmt(detail.calls) : "—"
133
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
134
- label: "SCHEDULED",
135
- value: detail.scheduleCount > 0 ? fmt(detail.scheduleCount) : "—"
136
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
137
- label: "AVG / RUN",
138
- value: detail.calls > 0 ? `${fmt(detail.avgMs)} ms` : "—"
139
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
140
- label: "MAX / RUN",
141
- value: detail.maxMs > 0 ? `${fmt(detail.maxMs)} ms` : "—",
142
- accent: detail.maxMs >= 50 ? _sharedUi.macOSColors.semantic.warning : undefined
143
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
144
- label: "TOTAL",
145
- value: detail.totalMs > 0 ? `${fmt(detail.totalMs)} ms` : "—"
146
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
147
- label: "LAST RUN",
148
- value: agoFmt(detail.lastSeenAgoMs)
149
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
150
- label: "FREEZES \xB7 60S",
151
- value: detail.freezes > 0 ? `${detail.freezes}` : "0",
152
- accent: detail.freezes > 0 ? _sharedUi.macOSColors.semantic.error : undefined
153
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Stat, {
154
- label: "WORST FREEZE",
155
- value: detail.worstFreezeMs > 0 ? `${detail.worstFreezeMs} ms` : "—",
156
- accent: detail.worstFreezeMs >= 100 ? _sharedUi.macOSColors.semantic.error : detail.worstFreezeMs > 0 ? _sharedUi.macOSColors.semantic.warning : undefined
157
- })]
158
- }), (detail.caller || (detail.frames?.length ?? 0) > 0) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
159
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
160
- style: styles.sectionTitle,
161
- children: "SCHEDULED FROM"
162
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
163
- style: styles.siteCard,
164
- children: [detail.caller && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
165
- style: styles.siteCaller,
166
- children: [detail.caller, "()"]
167
- }), detail.file && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
168
- style: styles.siteFile,
169
- children: [detail.file, detail.line != null ? `:${detail.line}` : ""]
170
- }), detail.frames?.map((f, i) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
171
- style: styles.siteFrame,
172
- numberOfLines: 1,
173
- children: [f.file, ":", f.line, ":", f.col]
174
- }, `fr${i}`)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
175
- style: styles.siteNote,
176
- children: "Frames are bundle offsets (Hermes) \u2014 the caller name above is the readable part. Captured once when this origin got hot."
177
- })]
178
- })]
179
- }), !detail.caller && (detail.frames?.length ?? 0) === 0 && detail.api !== "unattributed" && detail.api !== "other" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
180
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
181
- style: styles.sectionTitle,
182
- children: "SCHEDULED FROM"
183
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
184
- style: styles.sitePending,
185
- children: detail.promoted ? "Stack capture pending — next schedule from this site will record it." : "Not hot enough yet — the scheduling stack is captured once an origin passes 25 schedules or 50ms total."
186
- })]
187
- })]
188
- });
189
- });
190
- const styles = _reactNative.StyleSheet.create({
191
- root: {
192
- flex: 1,
193
- // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
194
- backgroundColor: "transparent",
195
- paddingHorizontal: 12
196
- },
197
- identityRow: {
198
- flexDirection: "row",
199
- alignItems: "center",
200
- gap: 8,
201
- paddingTop: 12
202
- },
203
- badge: {
204
- borderWidth: 1,
205
- borderRadius: 3,
206
- paddingHorizontal: 5,
207
- paddingVertical: 2
208
- },
209
- badgeText: {
210
- fontSize: 9,
211
- fontWeight: "700",
212
- letterSpacing: 0.4
213
- },
214
- name: {
215
- flex: 1,
216
- color: _sharedUi.night.color.text,
217
- fontSize: 15,
218
- fontWeight: "600"
219
- },
220
- explainer: {
221
- color: _sharedUi.night.color.textTertiary,
222
- fontSize: 11,
223
- lineHeight: 15,
224
- marginTop: 6,
225
- marginBottom: 4
226
- },
227
- sectionTitle: {
228
- color: _sharedUi.night.color.textTertiary,
229
- fontSize: 9,
230
- fontWeight: "700",
231
- letterSpacing: 0.5,
232
- marginTop: 14,
233
- marginBottom: 6
234
- },
235
- chartRow: {
236
- flexDirection: "row",
237
- alignItems: "flex-end",
238
- height: 48,
239
- gap: 2,
240
- backgroundColor: _sharedUi.night.color.surface,
241
- borderRadius: 6,
242
- borderWidth: 1,
243
- borderColor: _sharedUi.night.color.border,
244
- paddingHorizontal: 6,
245
- paddingTop: 2
246
- },
247
- chartBarSlot: {
248
- flex: 1,
249
- alignItems: "center",
250
- justifyContent: "flex-end"
251
- },
252
- chartBar: {
253
- width: "70%",
254
- borderTopLeftRadius: 2,
255
- borderTopRightRadius: 2,
256
- opacity: 0.9
257
- },
258
- chartLegend: {
259
- flexDirection: "row",
260
- justifyContent: "space-between",
261
- marginTop: 4
262
- },
263
- chartLegendText: {
264
- color: _sharedUi.night.color.textTertiary,
265
- fontSize: 10,
266
- fontVariant: ["tabular-nums"]
267
- },
268
- statGrid: {
269
- flexDirection: "row",
270
- flexWrap: "wrap",
271
- gap: 8
272
- },
273
- stat: {
274
- width: "23%",
275
- minWidth: 76,
276
- flexGrow: 1,
277
- backgroundColor: _sharedUi.night.color.surface,
278
- borderWidth: 1,
279
- borderColor: _sharedUi.night.color.border,
280
- borderRadius: 6,
281
- paddingHorizontal: 8,
282
- paddingVertical: 6
283
- },
284
- statLabel: {
285
- color: _sharedUi.night.color.textTertiary,
286
- fontSize: 8,
287
- fontWeight: "700",
288
- letterSpacing: 0.4,
289
- marginBottom: 3
290
- },
291
- statValue: {
292
- color: _sharedUi.night.color.text,
293
- fontSize: 13,
294
- fontWeight: "600",
295
- fontVariant: ["tabular-nums"]
296
- },
297
- siteCard: {
298
- backgroundColor: _sharedUi.night.color.surface,
299
- borderWidth: 1,
300
- borderColor: _sharedUi.night.color.border,
301
- borderRadius: 6,
302
- padding: 10,
303
- gap: 3
304
- },
305
- siteCaller: {
306
- color: _sharedUi.night.color.text,
307
- fontSize: 13,
308
- fontWeight: "600"
309
- },
310
- siteFile: {
311
- color: _sharedUi.night.color.info,
312
- fontSize: 11
313
- },
314
- siteFrame: {
315
- color: _sharedUi.night.color.textTertiary,
316
- fontSize: 10,
317
- fontVariant: ["tabular-nums"]
318
- },
319
- siteNote: {
320
- color: _sharedUi.night.color.textTertiary,
321
- fontSize: 9,
322
- opacity: 0.8,
323
- marginTop: 4
324
- },
325
- sitePending: {
326
- color: _sharedUi.night.color.textTertiary,
327
- fontSize: 11
328
- }
329
- });
330
- //# sourceMappingURL=TaskDetailView.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.TaskDetailView=void 0;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _TaskTable=require("./TaskTable");var _jsxRuntime=require("react/jsx-runtime");const API_EXPLAINER={timeout:"Work scheduled with setTimeout. Time shown is the callback's exclusive run time on the JS thread.",interval:"A repeating setInterval. One scheduling site, many runs \u2014 a hot interval is the classic silent JS-FPS killer.",immediate:"Work scheduled with setImmediate \u2014 runs at the end of the current event-loop turn.",raf:"requestAnimationFrame work \u2014 runs once per frame while scheduled. Cost here directly trades against 60fps.",microtask:"queueMicrotask work \u2014 runs after the current task, before the thread yields.",then:"Promise reaction (.then/.catch/.finally). Named by the function that attached the reaction. Note: async/await bodies bypass .then and land in the System row instead.",bridge:"A native\u2192JS call-in over the legacy bridge (events, module callbacks), measured as its un-nested remainder.",unattributed:"Thread time the probe measured but no JS wrapper could claim: touch handlers, React commits, native call-ins, and async/await bodies. High here on New Architecture is normal \u2014 it's where UI work lives.",other:"Origins evicted from the table when the registry hit its cap \u2014 their totals are preserved here."};function explainerFor(t){return API_EXPLAINER[t]??API_EXPLAINER.other}function fmt(t){if(t>=1e4)return`${Math.round(t/1e3)}k`;if(t>=1e3)return`${(t/1e3).toFixed(1)}k`;if(t>=100)return`${Math.round(t)}`;return`${Math.round(t*100)/100}`}function agoFmt(t){if(t<=0)return"\u2014";const e=t/1e3;if(e<1)return"just now";if(e<60)return`${Math.round(e)}s ago`;return`${Math.floor(e/60)}m ago`}function Stat({label:t,value:e,accent:r}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stat,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:t}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.statValue,r?{color:r}:null],children:e})]})}const TaskDetailView=exports.TaskDetailView=(0,_react.memo)(function t({detail:e}){const r=(0,_TaskTable.badgeFor)(e.api);const s=(0,_sharedUi.useSafeAreaInsets)({minBottom:12});const i=Math.max(1,...e.buckets);return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.root,contentContainerStyle:{paddingBottom:s.bottom},children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.identityRow,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.badge,{borderColor:r.color,backgroundColor:`${r.color}1A`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.badgeText,{color:r.color}],children:r.text})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.name,numberOfLines:2,children:(0,_TaskTable.displayName)(e)})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.explainer,children:explainerFor(e.api)}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"ACTIVITY \xB7 LAST 5S"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.chartRow,children:e.buckets.map((o,n)=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.chartBarSlot,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.chartBar,{height:Math.max(2,o/i*44),backgroundColor:r.color}]})},`bk${n}`))}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.chartLegend,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.chartLegendText,children:[fmt(e.windowMs)," ms in window \xB7 ",e.pctOfBusy.toFixed(1),"% of busy time"]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.chartLegendText,children:["peak ",fmt(i)," ms/250ms"]})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"STATS \xB7 SINCE START"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statGrid,children:[(0,_jsxRuntime.jsx)(Stat,{label:"RUNS",value:e.calls>0?fmt(e.calls):"\u2014"}),(0,_jsxRuntime.jsx)(Stat,{label:"SCHEDULED",value:e.scheduleCount>0?fmt(e.scheduleCount):"\u2014"}),(0,_jsxRuntime.jsx)(Stat,{label:"AVG / RUN",value:e.calls>0?`${fmt(e.avgMs)} ms`:"\u2014"}),(0,_jsxRuntime.jsx)(Stat,{label:"MAX / RUN",value:e.maxMs>0?`${fmt(e.maxMs)} ms`:"\u2014",accent:e.maxMs>=50?_sharedUi.macOSColors.semantic.warning:void 0}),(0,_jsxRuntime.jsx)(Stat,{label:"TOTAL",value:e.totalMs>0?`${fmt(e.totalMs)} ms`:"\u2014"}),(0,_jsxRuntime.jsx)(Stat,{label:"LAST RUN",value:agoFmt(e.lastSeenAgoMs)}),(0,_jsxRuntime.jsx)(Stat,{label:"FREEZES \xB7 60S",value:e.freezes>0?`${e.freezes}`:"0",accent:e.freezes>0?_sharedUi.macOSColors.semantic.error:void 0}),(0,_jsxRuntime.jsx)(Stat,{label:"WORST FREEZE",value:e.worstFreezeMs>0?`${e.worstFreezeMs} ms`:"\u2014",accent:e.worstFreezeMs>=100?_sharedUi.macOSColors.semantic.error:e.worstFreezeMs>0?_sharedUi.macOSColors.semantic.warning:void 0})]}),(e.caller||(e.frames?.length??0)>0)&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"SCHEDULED FROM"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.siteCard,children:[e.caller&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.siteCaller,children:[e.caller,"()"]}),e.file&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.siteFile,children:[e.file,e.line!=null?`:${e.line}`:""]}),e.frames?.map((o,n)=>(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.siteFrame,numberOfLines:1,children:[o.file,":",o.line,":",o.col]},`fr${n}`)),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.siteNote,children:"Frames are bundle offsets (Hermes) \u2014 the caller name above is the readable part. Captured once when this origin got hot."})]})]}),!e.caller&&(e.frames?.length??0)===0&&e.api!=="unattributed"&&e.api!=="other"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"SCHEDULED FROM"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sitePending,children:e.promoted?"Stack capture pending \u2014 next schedule from this site will record it.":"Not hot enough yet \u2014 the scheduling stack is captured once an origin passes 25 schedules or 50ms total."})]})]})});const styles=_reactNative.StyleSheet.create({root:{flex:1,backgroundColor:"transparent",paddingHorizontal:12},identityRow:{flexDirection:"row",alignItems:"center",gap:8,paddingTop:12},badge:{borderWidth:1,borderRadius:3,paddingHorizontal:5,paddingVertical:2},badgeText:{fontSize:9,fontWeight:"700",letterSpacing:.4},name:{flex:1,color:_sharedUi.night.color.text,fontSize:15,fontWeight:"600"},explainer:{color:_sharedUi.night.color.textTertiary,fontSize:11,lineHeight:15,marginTop:6,marginBottom:4},sectionTitle:{color:_sharedUi.night.color.textTertiary,fontSize:9,fontWeight:"700",letterSpacing:.5,marginTop:14,marginBottom:6},chartRow:{flexDirection:"row",alignItems:"flex-end",height:48,gap:2,backgroundColor:_sharedUi.night.color.surface,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:6,paddingTop:2},chartBarSlot:{flex:1,alignItems:"center",justifyContent:"flex-end"},chartBar:{width:"70%",borderTopLeftRadius:2,borderTopRightRadius:2,opacity:.9},chartLegend:{flexDirection:"row",justifyContent:"space-between",marginTop:4},chartLegendText:{color:_sharedUi.night.color.textTertiary,fontSize:10,fontVariant:["tabular-nums"]},statGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},stat:{width:"23%",minWidth:76,flexGrow:1,backgroundColor:_sharedUi.night.color.surface,borderWidth:1,borderColor:_sharedUi.night.color.border,borderRadius:6,paddingHorizontal:8,paddingVertical:6},statLabel:{color:_sharedUi.night.color.textTertiary,fontSize:8,fontWeight:"700",letterSpacing:.4,marginBottom:3},statValue:{color:_sharedUi.night.color.text,fontSize:13,fontWeight:"600",fontVariant:["tabular-nums"]},siteCard:{backgroundColor:_sharedUi.night.color.surface,borderWidth:1,borderColor:_sharedUi.night.color.border,borderRadius:6,padding:10,gap:3},siteCaller:{color:_sharedUi.night.color.text,fontSize:13,fontWeight:"600"},siteFile:{color:_sharedUi.night.color.info,fontSize:11},siteFrame:{color:_sharedUi.night.color.textTertiary,fontSize:10,fontVariant:["tabular-nums"]},siteNote:{color:_sharedUi.night.color.textTertiary,fontSize:9,opacity:.8,marginTop:4},sitePending:{color:_sharedUi.night.color.textTertiary,fontSize:11}});