@buoy-gg/js-top 7.0.41 → 7.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +2 -2
  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,402 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.OTHER_KEY = void 0;
7
- exports.buildRows = buildRows;
8
- exports.buoyJsTopBookExclusive = buoyJsTopBookExclusive;
9
- exports.buoyJsTopOriginExists = buoyJsTopOriginExists;
10
- exports.buoyJsTopScheduleOrigin = buoyJsTopScheduleOrigin;
11
- exports.debugGetOrigin = debugGetOrigin;
12
- exports.getOriginDetailBase = getOriginDetailBase;
13
- exports.labelForOrigin = labelForOrigin;
14
- exports.originCount = originCount;
15
- exports.parseStack = parseStack;
16
- exports.resetOrigins = resetOrigins;
17
- var _types = require("../types");
18
- var _aggregator = require("./aggregator");
19
- var _symbolicate = require("./symbolicate");
20
- /**
21
- * Origin registry — the "process table". An origin is the identity of a task
22
- * scheduling site.
23
- *
24
- * Two-stage identity keeps the hot path free of stack captures:
25
- * - Cheap key `${api}|${fnName}` — computed on every schedule, just string
26
- * concat + Map lookup.
27
- * - Once an origin gets hot (PROMOTE_MIN_CALLS schedules or
28
- * PROMOTE_MIN_TOTAL_MS booked), the next schedule captures ONE
29
- * `Error().stack` (throttled per-key and globally) and refines the key
30
- * with the scheduling site's caller frame. Hermes dev stacks reference
31
- * bundle offsets, not source files — the CALLER FUNCTION NAME is the
32
- * readable part, so labels read `setInterval ← startPolling`; raw frames
33
- * are kept on the origin for future desktop symbolication.
34
- */
35
-
36
- const STACK_CAPTURE_MIN_INTERVAL_PER_KEY_MS = 500;
37
- const STACK_CAPTURES_PER_SEC_GLOBAL = 20;
38
- const origins = new Map();
39
-
40
- /** Pinned bucket that absorbs evicted cold origins. */
41
- const OTHER_KEY = exports.OTHER_KEY = "other";
42
- let globalCaptureWindowStart = 0;
43
- let globalCapturesInWindow = 0;
44
- function makeOrigin(key, api, label) {
45
- return {
46
- key,
47
- api,
48
- label,
49
- calls: 0,
50
- totalMs: 0,
51
- maxMs: 0,
52
- scheduleCount: 0,
53
- lastSeenAt: 0,
54
- promoted: false,
55
- lastCaptureAt: 0,
56
- ring: new Float64Array(_types.WINDOW_BUCKETS),
57
- ringStamps: new Float64Array(_types.WINDOW_BUCKETS).fill(-1)
58
- };
59
- }
60
- function windowMsOf(o, nowT) {
61
- const current = (0, _aggregator.epochOf)(nowT);
62
- let sum = 0;
63
- for (let e = current - _types.WINDOW_BUCKETS + 1; e <= current; e++) {
64
- const i = e % _types.WINDOW_BUCKETS;
65
- if (i >= 0 && o.ringStamps[i] === e) sum += o.ring[i];
66
- }
67
- return sum;
68
- }
69
- function evictColdest(nowT) {
70
- let coldest = null;
71
- let coldestScore = Infinity;
72
- for (const o of origins.values()) {
73
- if (o.key === OTHER_KEY) continue;
74
- // Rank by recent cost, tiebreak by staleness.
75
- const score = windowMsOf(o, nowT) * 1e6 + o.lastSeenAt;
76
- if (score < coldestScore) {
77
- coldestScore = score;
78
- coldest = o;
79
- }
80
- }
81
- if (!coldest) return;
82
- const other = getOrCreate(OTHER_KEY, "other", "other (evicted origins)");
83
- other.calls += coldest.calls;
84
- other.totalMs += coldest.totalMs;
85
- other.maxMs = Math.max(other.maxMs, coldest.maxMs);
86
- other.lastSeenAt = Math.max(other.lastSeenAt, coldest.lastSeenAt);
87
- origins.delete(coldest.key);
88
- }
89
- function getOrCreate(key, api, label) {
90
- let o = origins.get(key);
91
- if (!o) {
92
- o = makeOrigin(key, api, label);
93
- origins.set(key, o);
94
- }
95
- return o;
96
- }
97
-
98
- /**
99
- * Parse a Hermes stack into frames, skipping engine/wrapper frames. Engine
100
- * functions are deliberately named with a `buoyJsTop` prefix so they are
101
- * identifiable here even in bundle-offset stacks.
102
- */
103
- function parseStack(stack) {
104
- const frames = [];
105
- let caller;
106
- const lines = stack.split("\n");
107
- for (const lineText of lines) {
108
- const m = /at\s+(.*?)\s+\((?:address at\s+)?(.*?):(\d+):(\d+)\)/.exec(lineText) ?? /at\s+()(.*?):(\d+):(\d+)$/.exec(lineText.trim());
109
- if (!m) continue;
110
- const fnName = m[1] ?? "";
111
- if (fnName.includes("buoyJsTop") || fnName === "Error" || m[2]?.includes("/js-top/")) {
112
- continue;
113
- }
114
- frames.push({
115
- file: m[2] ?? "",
116
- line: Number(m[3]),
117
- col: Number(m[4])
118
- });
119
- // React splices internal frame names around effect callbacks
120
- // (react_stack_bottom_frame etc.) — their OFFSETS map to user code, so
121
- // keep the frame, but never present them as the "caller".
122
- const isReactInternal = /^(react_stack_bottom_frame|runWithFiberInDEV|commitHookEffectList|flushPassive|performWork|renderWithHooks|safelyCall)/.test(fnName) ||
123
- // Promise/polyfill machinery — technically the caller, never the answer.
124
- /^(then|catch|finally|resolve|reject|fulfilled|rejected|step|tryCallOne|tryCallTwo|tryCatch|invokeCallback|notify)$/.test(fnName);
125
- if (!caller && fnName && fnName !== "anonymous" && !isReactInternal) {
126
- caller = fnName;
127
- }
128
- if (frames.length >= 3) break;
129
- }
130
- return {
131
- caller,
132
- frames
133
- };
134
- }
135
- function allowCapture(o, nowT) {
136
- if (nowT - o.lastCaptureAt < STACK_CAPTURE_MIN_INTERVAL_PER_KEY_MS) {
137
- return false;
138
- }
139
- if (nowT - globalCaptureWindowStart > 1000) {
140
- globalCaptureWindowStart = nowT;
141
- globalCapturesInWindow = 0;
142
- }
143
- if (globalCapturesInWindow >= STACK_CAPTURES_PER_SEC_GLOBAL) return false;
144
- globalCapturesInWindow++;
145
- o.lastCaptureAt = nowT;
146
- return true;
147
- }
148
- function shortFile(file) {
149
- if (!file) return undefined;
150
- // Strip scheme://host:port/ and query — keeps the bundle-relative tail.
151
- // Metro dev URLs carry params after "//&" instead of "?" — strip both.
152
- const noQuery = (file.split("?")[0] ?? file).replace(/\/\/&.*$/, "");
153
- const m = /^[a-z]+:\/\/[^/]+\/(.*)$/.exec(noQuery);
154
- const tail = m ? m[1] : noQuery;
155
- const parts = tail.split("/");
156
- return parts.slice(-2).join("/");
157
- }
158
-
159
- /**
160
- * Resolve the origin key for a schedule. Called from patched globals at
161
- * schedule time — this is the hot path; the common case is one Map get and
162
- * two counter bumps.
163
- */
164
- function buoyJsTopOriginExists(key) {
165
- return origins.has(key);
166
- }
167
- function buoyJsTopScheduleOrigin(api, fn, nowT,
168
- /**
169
- * False when identity is resolved at FIRE time (callback scheduled while
170
- * the engine was off, or stats cleared since): a runtime stack is not a
171
- * scheduling site, so stack capture is skipped on that path.
172
- */
173
- allowStackCapture = true) {
174
- const fnLike = fn;
175
- const name = typeof fnLike.displayName === "string" && fnLike.displayName || typeof fnLike.name === "string" && fnLike.name || "anonymous";
176
- const cheapKey = `${api}|${name}`;
177
- let o = origins.get(cheapKey);
178
- if (!o) {
179
- if (origins.size >= _types.MAX_ORIGINS) evictColdest(nowT);
180
- o = makeOrigin(cheapKey, api, name === "anonymous" ? apiLabel(api) : `${apiLabel(api)} ${name}`);
181
- origins.set(cheapKey, o);
182
- }
183
- o.scheduleCount++;
184
- if (!o.promoted && (o.scheduleCount >= _types.PROMOTE_MIN_CALLS || o.totalMs >= _types.PROMOTE_MIN_TOTAL_MS)) {
185
- o.promoted = true;
186
- }
187
- // Intervals schedule exactly ONCE — this call is the only chance to see
188
- // their scheduling stack, so capture eagerly instead of waiting for
189
- // promotion (which is driven by schedule counts they'll never accrue).
190
- if ((o.promoted || api === "interval") && allowStackCapture && allowCapture(o, nowT)) {
191
- const {
192
- caller,
193
- frames
194
- } = parseStack(new Error().stack ?? "");
195
- const top = frames[0];
196
- if (top || caller) {
197
- // Keys stay short + token-cheap: bundle URLs are stripped down to the
198
- // trailing path segment (full frames live on the origin record).
199
- const site = top ? `${shortFile(top.file) ?? "?"}:${top.line}` : "?";
200
- const refinedKey = `${cheapKey}@${caller ?? "?"}:${site}`;
201
- let refined = origins.get(refinedKey);
202
- if (!refined) {
203
- if (origins.size >= _types.MAX_ORIGINS) evictColdest(nowT);
204
- // Label rule: the function name (when it exists) is the anchor and
205
- // is never discarded; a readable caller or site is appended.
206
- const base = name === "anonymous" ? apiLabel(api) : `${apiLabel(api)} ${name}`;
207
- refined = makeOrigin(refinedKey, api, caller ? `${base} ← ${caller}` : name === "anonymous" ? `${base} @ ${shortFile(top?.file ?? "") ?? "?"}` : base);
208
- refined.caller = caller;
209
- refined.file = top ? shortFile(top.file) : undefined;
210
- refined.line = top?.line;
211
- refined.frames = frames;
212
- refined.promoted = true;
213
- // Migrate the cheap origin's accumulated stats into the refined one
214
- // and zero the cheap record — the table must never show the same
215
- // scheduling site as two rows (pre- and post-refinement).
216
- refined.calls = o.calls;
217
- refined.totalMs = o.totalMs;
218
- refined.maxMs = o.maxMs;
219
- refined.scheduleCount = o.scheduleCount;
220
- refined.lastSeenAt = o.lastSeenAt;
221
- refined.ring.set(o.ring);
222
- refined.ringStamps.set(o.ringStamps);
223
- o.calls = 0;
224
- o.totalMs = 0;
225
- o.maxMs = 0;
226
- o.ring.fill(0);
227
- o.ringStamps.fill(-1);
228
- origins.set(refinedKey, refined);
229
- // Upgrade the label to real source coordinates when Metro is around.
230
- (0, _symbolicate.buoyJsTopSymbolicateOrigin)(refined, apiLabel(api));
231
- }
232
- o.activeRefinedKey = refinedKey;
233
- }
234
- }
235
- return o.activeRefinedKey ?? cheapKey;
236
- }
237
- function apiLabel(api) {
238
- switch (api) {
239
- case "timeout":
240
- return "setTimeout";
241
- case "interval":
242
- return "setInterval";
243
- case "immediate":
244
- return "setImmediate";
245
- case "raf":
246
- return "requestAnimationFrame";
247
- case "microtask":
248
- return "queueMicrotask";
249
- case "then":
250
- return "Promise.then";
251
- case "bridge":
252
- return "bridge";
253
- default:
254
- return api;
255
- }
256
- }
257
-
258
- /** Book a completed call's exclusive time onto its origin + global buckets. */
259
- function buoyJsTopBookExclusive(originKey, exclusiveMs, start, end) {
260
- const o = origins.get(originKey);
261
- if (!o) return;
262
- o.calls++;
263
- o.totalMs += exclusiveMs;
264
- if (exclusiveMs > o.maxMs) o.maxMs = exclusiveMs;
265
- o.lastSeenAt = end;
266
- // Promotion by accumulated cost must ALSO happen at book time: an
267
- // interval never re-schedules, so the schedule-time check alone would
268
- // leave a 1000ms/run interval "not hot" forever.
269
- if (!o.promoted && o.totalMs >= _types.PROMOTE_MIN_TOTAL_MS) o.promoted = true;
270
- // Per-origin ring, spread across the call's span like the global buckets.
271
- const span = end - start;
272
- const ratio = span > 0 ? Math.min(1, exclusiveMs / span) : 1;
273
- const clampedStart = Math.max(start, end - _types.WINDOW_BUCKETS * _types.BUCKET_MS);
274
- let e = (0, _aggregator.epochOf)(clampedStart);
275
- const lastEpoch = (0, _aggregator.epochOf)(end);
276
- let cursor = clampedStart;
277
- while (e <= lastEpoch) {
278
- const bucketEnd = (e + 1) * _types.BUCKET_MS;
279
- const sliceEnd = Math.min(end, bucketEnd);
280
- const ms = sliceEnd - cursor;
281
- if (ms > 0) {
282
- const i = e % _types.WINDOW_BUCKETS;
283
- if (i >= 0) {
284
- if (o.ringStamps[i] !== e) {
285
- o.ringStamps[i] = e;
286
- o.ring[i] = 0;
287
- }
288
- o.ring[i] += span > 0 ? ms * ratio : exclusiveMs;
289
- }
290
- }
291
- cursor = sliceEnd;
292
- e++;
293
- }
294
- (0, _aggregator.bookAttributedRange)(start, end, exclusiveMs);
295
- }
296
- function labelForOrigin(key) {
297
- return origins.get(key)?.label ?? null;
298
- }
299
-
300
- /** Build the ranked table rows (excludes the pinned unattributed row — the
301
- * controller assembles that from aggregator residuals). */
302
- function buildRows(nowT, windowBusy, topN) {
303
- const rows = [];
304
- for (const o of origins.values()) {
305
- // Cheap keys that have handed off to a refined key stop accumulating new
306
- // work but keep their pre-promotion totals; hide them once idle.
307
- const windowMs = windowMsOf(o, nowT);
308
- if (windowMs <= 0 && o.totalMs < 1) continue;
309
- rows.push({
310
- key: o.key,
311
- label: o.label,
312
- api: o.api,
313
- file: o.file,
314
- line: o.line,
315
- windowMs: Math.round(windowMs * 10) / 10,
316
- pctOfBusy: windowBusy > 0 ? Math.min(100, Math.round(windowMs / windowBusy * 1000) / 10) : 0,
317
- totalMs: Math.round(o.totalMs * 10) / 10,
318
- calls: o.calls,
319
- avgMs: o.calls > 0 ? Math.round(o.totalMs / o.calls * 100) / 100 : 0,
320
- maxMs: Math.round(o.maxMs * 100) / 100,
321
- lastSeenAgoMs: o.lastSeenAt > 0 ? Math.max(0, nowT - o.lastSeenAt) : 0,
322
- // Filled in by the controller from the freeze-stats provider.
323
- freezes: 0,
324
- worstFreezeMs: 0
325
- });
326
- }
327
- rows.sort((a, b) => b.windowMs - a.windowMs || b.totalMs - a.totalMs);
328
- // Noise gate: rows that can't matter (<1ms window, <0.5% busy, no freezes)
329
- // collapse into a single aggregate so the table stays a shortlist.
330
- const majors = [];
331
- const minors = [];
332
- for (const r of rows) {
333
- (r.windowMs >= 1 || r.pctOfBusy >= 0.5 || r.freezes > 0 ? majors : minors).push(r);
334
- }
335
- if (minors.length >= 2) {
336
- majors.push({
337
- key: "minor",
338
- label: `${minors.length} minor origins (≤1ms each)`,
339
- api: "other",
340
- windowMs: Math.round(minors.reduce((sum, r) => sum + r.windowMs, 0) * 10) / 10,
341
- pctOfBusy: Math.round(minors.reduce((sum, r) => sum + r.pctOfBusy, 0) * 10) / 10,
342
- totalMs: Math.round(minors.reduce((sum, r) => sum + r.totalMs, 0) * 10) / 10,
343
- calls: minors.reduce((sum, r) => sum + r.calls, 0),
344
- avgMs: 0,
345
- maxMs: Math.max(0, ...minors.map(r => r.maxMs)),
346
- lastSeenAgoMs: Math.min(...minors.map(r => r.lastSeenAgoMs)),
347
- freezes: 0,
348
- worstFreezeMs: 0
349
- });
350
- return majors.slice(0, topN);
351
- }
352
- return rows.slice(0, topN);
353
- }
354
-
355
- /**
356
- * Full origin detail minus freeze stats (the controller merges those). The
357
- * bucket array is the origin's 5s activity trend, oldest→newest.
358
- */
359
- function getOriginDetailBase(key, nowT, windowBusy) {
360
- const o = origins.get(key);
361
- if (!o) return null;
362
- const current = (0, _aggregator.epochOf)(nowT);
363
- const buckets = [];
364
- let windowMs = 0;
365
- for (let e = current - _types.WINDOW_BUCKETS + 1; e <= current; e++) {
366
- const i = e % _types.WINDOW_BUCKETS;
367
- const ms = i >= 0 && o.ringStamps[i] === e ? Math.round(o.ring[i] * 10) / 10 : 0;
368
- buckets.push(ms);
369
- windowMs += ms;
370
- }
371
- return {
372
- key: o.key,
373
- label: o.label,
374
- api: o.api,
375
- caller: o.caller,
376
- file: o.file,
377
- line: o.line,
378
- frames: o.frames,
379
- promoted: o.promoted,
380
- scheduleCount: o.scheduleCount,
381
- calls: o.calls,
382
- totalMs: Math.round(o.totalMs * 10) / 10,
383
- avgMs: o.calls > 0 ? Math.round(o.totalMs / o.calls * 100) / 100 : 0,
384
- maxMs: Math.round(o.maxMs * 100) / 100,
385
- windowMs: Math.round(windowMs * 10) / 10,
386
- pctOfBusy: windowBusy > 0 ? Math.min(100, Math.round(windowMs / windowBusy * 1000) / 10) : 0,
387
- lastSeenAgoMs: o.lastSeenAt > 0 ? Math.max(0, nowT - o.lastSeenAt) : 0,
388
- buckets
389
- };
390
- }
391
- function resetOrigins() {
392
- origins.clear();
393
- }
394
-
395
- /** Test-only introspection. */
396
- function debugGetOrigin(key) {
397
- return origins.get(key);
398
- }
399
- function originCount() {
400
- return origins.size;
401
- }
402
- //# sourceMappingURL=originRegistry.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.OTHER_KEY=void 0;exports.buildRows=buildRows;exports.buoyJsTopBookExclusive=buoyJsTopBookExclusive;exports.buoyJsTopOriginExists=buoyJsTopOriginExists;exports.buoyJsTopScheduleOrigin=buoyJsTopScheduleOrigin;exports.debugGetOrigin=debugGetOrigin;exports.getOriginDetailBase=getOriginDetailBase;exports.labelForOrigin=labelForOrigin;exports.originCount=originCount;exports.parseStack=parseStack;exports.resetOrigins=resetOrigins;var _types=require("../types");var _aggregator=require("./aggregator");var _symbolicate=require("./symbolicate");const STACK_CAPTURE_MIN_INTERVAL_PER_KEY_MS=500;const STACK_CAPTURES_PER_SEC_GLOBAL=20;const origins=new Map;const OTHER_KEY=exports.OTHER_KEY="other";let globalCaptureWindowStart=0;let globalCapturesInWindow=0;function makeOrigin(n,o,l){return{key:n,api:o,label:l,calls:0,totalMs:0,maxMs:0,scheduleCount:0,lastSeenAt:0,promoted:false,lastCaptureAt:0,ring:new Float64Array(_types.WINDOW_BUCKETS),ringStamps:new Float64Array(_types.WINDOW_BUCKETS).fill(-1)}}function windowMsOf(n,o){const l=(0,_aggregator.epochOf)(o);let e=0;for(let r=l-_types.WINDOW_BUCKETS+1;r<=l;r++){const a=r%_types.WINDOW_BUCKETS;if(a>=0&&n.ringStamps[a]===r)e+=n.ring[a]}return e}function evictColdest(n){let o=null;let l=Infinity;for(const r of origins.values()){if(r.key===OTHER_KEY)continue;const a=windowMsOf(r,n)*1e6+r.lastSeenAt;if(a<l){l=a;o=r}}if(!o)return;const e=getOrCreate(OTHER_KEY,"other","other (evicted origins)");e.calls+=o.calls;e.totalMs+=o.totalMs;e.maxMs=Math.max(e.maxMs,o.maxMs);e.lastSeenAt=Math.max(e.lastSeenAt,o.lastSeenAt);origins.delete(o.key)}function getOrCreate(n,o,l){let e=origins.get(n);if(!e){e=makeOrigin(n,o,l);origins.set(n,e)}return e}function parseStack(n){const o=[];let l;const e=n.split("\n");for(const r of e){const a=/at\s+(.*?)\s+\((?:address at\s+)?(.*?):(\d+):(\d+)\)/.exec(r)??/at\s+()(.*?):(\d+):(\d+)$/.exec(r.trim());if(!a)continue;const t=a[1]??"";if(t.includes("buoyJsTop")||t==="Error"||a[2]?.includes("/js-top/")){continue}o.push({file:a[2]??"",line:Number(a[3]),col:Number(a[4])});const s=/^(react_stack_bottom_frame|runWithFiberInDEV|commitHookEffectList|flushPassive|performWork|renderWithHooks|safelyCall)/.test(t)||/^(then|catch|finally|resolve|reject|fulfilled|rejected|step|tryCallOne|tryCallTwo|tryCatch|invokeCallback|notify)$/.test(t);if(!l&&t&&t!=="anonymous"&&!s){l=t}if(o.length>=3)break}return{caller:l,frames:o}}function allowCapture(n,o){if(o-n.lastCaptureAt<STACK_CAPTURE_MIN_INTERVAL_PER_KEY_MS){return false}if(o-globalCaptureWindowStart>1e3){globalCaptureWindowStart=o;globalCapturesInWindow=0}if(globalCapturesInWindow>=STACK_CAPTURES_PER_SEC_GLOBAL)return false;globalCapturesInWindow++;n.lastCaptureAt=o;return true}function shortFile(n){if(!n)return void 0;const o=(n.split("?")[0]??n).replace(/\/\/&.*$/,"");const l=/^[a-z]+:\/\/[^/]+\/(.*)$/.exec(o);const e=l?l[1]:o;const r=e.split("/");return r.slice(-2).join("/")}function buoyJsTopOriginExists(n){return origins.has(n)}function buoyJsTopScheduleOrigin(n,o,l,e=true){const r=o;const a=typeof r.displayName==="string"&&r.displayName||typeof r.name==="string"&&r.name||"anonymous";const t=`${n}|${a}`;let s=origins.get(t);if(!s){if(origins.size>=_types.MAX_ORIGINS)evictColdest(l);s=makeOrigin(t,n,a==="anonymous"?apiLabel(n):`${apiLabel(n)} ${a}`);origins.set(t,s)}s.scheduleCount++;if(!s.promoted&&(s.scheduleCount>=_types.PROMOTE_MIN_CALLS||s.totalMs>=_types.PROMOTE_MIN_TOTAL_MS)){s.promoted=true}if((s.promoted||n==="interval")&&e&&allowCapture(s,l)){const{caller:c,frames:m}=parseStack(new Error().stack??"");const u=m[0];if(u||c){const d=u?`${shortFile(u.file)??"?"}:${u.line}`:"?";const M=`${t}@${c??"?"}:${d}`;let i=origins.get(M);if(!i){if(origins.size>=_types.MAX_ORIGINS)evictColdest(l);const f=a==="anonymous"?apiLabel(n):`${apiLabel(n)} ${a}`;i=makeOrigin(M,n,c?`${f} \u2190 ${c}`:a==="anonymous"?`${f} @ ${shortFile(u?.file??"")??"?"}`:f);i.caller=c;i.file=u?shortFile(u.file):void 0;i.line=u?.line;i.frames=m;i.promoted=true;i.calls=s.calls;i.totalMs=s.totalMs;i.maxMs=s.maxMs;i.scheduleCount=s.scheduleCount;i.lastSeenAt=s.lastSeenAt;i.ring.set(s.ring);i.ringStamps.set(s.ringStamps);s.calls=0;s.totalMs=0;s.maxMs=0;s.ring.fill(0);s.ringStamps.fill(-1);origins.set(M,i);(0,_symbolicate.buoyJsTopSymbolicateOrigin)(i,apiLabel(n))}s.activeRefinedKey=M}}return s.activeRefinedKey??t}function apiLabel(n){switch(n){case"timeout":return"setTimeout";case"interval":return"setInterval";case"immediate":return"setImmediate";case"raf":return"requestAnimationFrame";case"microtask":return"queueMicrotask";case"then":return"Promise.then";case"bridge":return"bridge";default:return n}}function buoyJsTopBookExclusive(n,o,l,e){const r=origins.get(n);if(!r)return;r.calls++;r.totalMs+=o;if(o>r.maxMs)r.maxMs=o;r.lastSeenAt=e;if(!r.promoted&&r.totalMs>=_types.PROMOTE_MIN_TOTAL_MS)r.promoted=true;const a=e-l;const t=a>0?Math.min(1,o/a):1;const s=Math.max(l,e-_types.WINDOW_BUCKETS*_types.BUCKET_MS);let c=(0,_aggregator.epochOf)(s);const m=(0,_aggregator.epochOf)(e);let u=s;while(c<=m){const d=(c+1)*_types.BUCKET_MS;const M=Math.min(e,d);const i=M-u;if(i>0){const f=c%_types.WINDOW_BUCKETS;if(f>=0){if(r.ringStamps[f]!==c){r.ringStamps[f]=c;r.ring[f]=0}r.ring[f]+=a>0?i*t:o}}u=M;c++}(0,_aggregator.bookAttributedRange)(l,e,o)}function labelForOrigin(n){return origins.get(n)?.label??null}function buildRows(n,o,l){const e=[];for(const t of origins.values()){const s=windowMsOf(t,n);if(s<=0&&t.totalMs<1)continue;e.push({key:t.key,label:t.label,api:t.api,file:t.file,line:t.line,windowMs:Math.round(s*10)/10,pctOfBusy:o>0?Math.min(100,Math.round(s/o*1e3)/10):0,totalMs:Math.round(t.totalMs*10)/10,calls:t.calls,avgMs:t.calls>0?Math.round(t.totalMs/t.calls*100)/100:0,maxMs:Math.round(t.maxMs*100)/100,lastSeenAgoMs:t.lastSeenAt>0?Math.max(0,n-t.lastSeenAt):0,freezes:0,worstFreezeMs:0})}e.sort((t,s)=>s.windowMs-t.windowMs||s.totalMs-t.totalMs);const r=[];const a=[];for(const t of e){(t.windowMs>=1||t.pctOfBusy>=.5||t.freezes>0?r:a).push(t)}if(a.length>=2){r.push({key:"minor",label:`${a.length} minor origins (\u22641ms each)`,api:"other",windowMs:Math.round(a.reduce((t,s)=>t+s.windowMs,0)*10)/10,pctOfBusy:Math.round(a.reduce((t,s)=>t+s.pctOfBusy,0)*10)/10,totalMs:Math.round(a.reduce((t,s)=>t+s.totalMs,0)*10)/10,calls:a.reduce((t,s)=>t+s.calls,0),avgMs:0,maxMs:Math.max(0,...a.map(t=>t.maxMs)),lastSeenAgoMs:Math.min(...a.map(t=>t.lastSeenAgoMs)),freezes:0,worstFreezeMs:0});return r.slice(0,l)}return e.slice(0,l)}function getOriginDetailBase(n,o,l){const e=origins.get(n);if(!e)return null;const r=(0,_aggregator.epochOf)(o);const a=[];let t=0;for(let s=r-_types.WINDOW_BUCKETS+1;s<=r;s++){const c=s%_types.WINDOW_BUCKETS;const m=c>=0&&e.ringStamps[c]===s?Math.round(e.ring[c]*10)/10:0;a.push(m);t+=m}return{key:e.key,label:e.label,api:e.api,caller:e.caller,file:e.file,line:e.line,frames:e.frames,promoted:e.promoted,scheduleCount:e.scheduleCount,calls:e.calls,totalMs:Math.round(e.totalMs*10)/10,avgMs:e.calls>0?Math.round(e.totalMs/e.calls*100)/100:0,maxMs:Math.round(e.maxMs*100)/100,windowMs:Math.round(t*10)/10,pctOfBusy:l>0?Math.min(100,Math.round(t/l*1e3)/10):0,lastSeenAgoMs:e.lastSeenAt>0?Math.max(0,o-e.lastSeenAt):0,buckets:a}}function resetOrigins(){origins.clear()}function debugGetOrigin(n){return origins.get(n)}function originCount(){return origins.size}
@@ -1,60 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.installBridgePatch = installBridgePatch;
7
- var _frameStack = require("../frameStack");
8
- var _state = require("../state");
9
- /**
10
- * Tier 2 patch: legacy-bridge call-ins. On Paper/legacy-bridge runtimes,
11
- * every native→JS call (touch events via RCTEventEmitter, timer flushes via
12
- * JSTimers.callTimers, module callbacks) enters through
13
- * `__fbBatchedBridge.callFunctionReturnFlushedQueue` /
14
- * `invokeCallbackAndReturnFlushedQueue`. Wrapping them attributes event and
15
- * native-callback cost by module.method.
16
- *
17
- * On New Architecture (bridgeless) these globals don't exist — install
18
- * reports `bridge: false` and the UI banners the coverage gap. Nested
19
- * wrapped work (e.g. our wrapped rAF callbacks running inside a
20
- * callTimers call-in) books exclusively via the frame stack, so this tier
21
- * only ever adds its own un-nested remainder.
22
- */
23
-
24
- function installBridgePatch() {
25
- const bridge = _state.g.__fbBatchedBridge;
26
- if (!bridge) return {
27
- bridge: false
28
- };
29
- let patchedAny = false;
30
- if (typeof bridge.callFunctionReturnFlushedQueue === "function" && !bridge.callFunctionReturnFlushedQueue[_state.PATCHED_TAG]) {
31
- const original = bridge.callFunctionReturnFlushedQueue.bind(bridge);
32
- const buoyJsTopCallFunction = function (module, method,
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
- args) {
35
- if (!(0, _state.isActive)()) return original(module, method, args);
36
- return (0, _frameStack.buoyJsTopRunAs)("bridge", `${module}.${method}`, () => original(module, method, args));
37
- };
38
- buoyJsTopCallFunction[_state.PATCHED_TAG] = true;
39
- bridge.callFunctionReturnFlushedQueue = buoyJsTopCallFunction;
40
- patchedAny = true;
41
- }
42
- if (typeof bridge.invokeCallbackAndReturnFlushedQueue === "function" && !bridge.invokeCallbackAndReturnFlushedQueue[_state.PATCHED_TAG]) {
43
- const original = bridge.invokeCallbackAndReturnFlushedQueue.bind(bridge);
44
- // Callback ids are per-call and meaningless as identity — one shared
45
- // origin covers all native-module completion callbacks.
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- const buoyJsTopInvokeCallback = function (cbID, args) {
48
- if (!(0, _state.isActive)()) return original(cbID, args);
49
- return (0, _frameStack.buoyJsTopRunAs)("bridge", "nativeModuleCallback", () => original(cbID, args));
50
- };
51
- buoyJsTopInvokeCallback[_state.PATCHED_TAG] = true;
52
- bridge.invokeCallbackAndReturnFlushedQueue = buoyJsTopInvokeCallback;
53
- patchedAny = true;
54
- }
55
- const alreadyPatched = bridge.callFunctionReturnFlushedQueue?.[_state.PATCHED_TAG] === true;
56
- return {
57
- bridge: patchedAny || alreadyPatched
58
- };
59
- }
60
- //# sourceMappingURL=bridge.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.installBridgePatch=installBridgePatch;var _frameStack=require("../frameStack");var _state=require("../state");function installBridgePatch(){const e=_state.g.__fbBatchedBridge;if(!e)return{bridge:false};let i=false;if(typeof e.callFunctionReturnFlushedQueue==="function"&&!e.callFunctionReturnFlushedQueue[_state.PATCHED_TAG]){const t=e.callFunctionReturnFlushedQueue.bind(e);const r=function(u,n,l){if(!(0,_state.isActive)())return t(u,n,l);return(0,_frameStack.buoyJsTopRunAs)("bridge",`${u}.${n}`,()=>t(u,n,l))};r[_state.PATCHED_TAG]=true;e.callFunctionReturnFlushedQueue=r;i=true}if(typeof e.invokeCallbackAndReturnFlushedQueue==="function"&&!e.invokeCallbackAndReturnFlushedQueue[_state.PATCHED_TAG]){const t=e.invokeCallbackAndReturnFlushedQueue.bind(e);const r=function(u,n){if(!(0,_state.isActive)())return t(u,n);return(0,_frameStack.buoyJsTopRunAs)("bridge","nativeModuleCallback",()=>t(u,n))};r[_state.PATCHED_TAG]=true;e.invokeCallbackAndReturnFlushedQueue=r;i=true}const a=e.callFunctionReturnFlushedQueue?.[_state.PATCHED_TAG]===true;return{bridge:i||a}}
@@ -1,27 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.installMicrotaskPatches = installMicrotaskPatches;
7
- var _frameStack = require("../frameStack");
8
- var _state = require("../state");
9
- /**
10
- * Tier 1 patch: queueMicrotask. Same install-once contract as timers.ts.
11
- * (Promise reactions are Tier 1.5 — see promises.ts.)
12
- */
13
-
14
- function installMicrotaskPatches() {
15
- const originals = (0, _state.captureOriginals)();
16
- if (typeof _state.g.queueMicrotask === "function" && !_state.g.queueMicrotask[_state.PATCHED_TAG] && originals.queueMicrotask) {
17
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- const buoyJsTopQueueMicrotask = function (fn) {
19
- const cb = (0, _frameStack.buoyJsTopWrapTask)(fn, "microtask");
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- return originals.queueMicrotask(cb);
22
- };
23
- buoyJsTopQueueMicrotask[_state.PATCHED_TAG] = true;
24
- _state.g.queueMicrotask = buoyJsTopQueueMicrotask;
25
- }
26
- }
27
- //# sourceMappingURL=microtasks.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.installMicrotaskPatches=installMicrotaskPatches;var _frameStack=require("../frameStack");var _state=require("../state");function installMicrotaskPatches(){const e=(0,_state.captureOriginals)();if(typeof _state.g.queueMicrotask==="function"&&!_state.g.queueMicrotask[_state.PATCHED_TAG]&&e.queueMicrotask){const t=function(r){const s=(0,_frameStack.buoyJsTopWrapTask)(r,"microtask");return e.queueMicrotask(s)};t[_state.PATCHED_TAG]=true;_state.g.queueMicrotask=t}}
@@ -1,65 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.installPromisePatches = installPromisePatches;
7
- var _frameStack = require("../frameStack");
8
- var _state = require("../state");
9
- /**
10
- * Tier 1.5 patch: Promise reactions via Promise.prototype.then/catch/finally.
11
- *
12
- * All three are patched: in Hermes, catch/finally delegate to then, and the
13
- * WRAPPED_TAG check in wrapTask makes the delegation harmless (a reaction
14
- * wrapped by our catch patch passes through our then patch untouched).
15
- *
16
- * Known, documented gap: native async/await resumption never goes through
17
- * `.then` — async-function bodies land in the "unattributed" row, not here.
18
- *
19
- * The wrapper is passthrough-first: non-function reactions
20
- * (`.then(undefined, fn)`), `this` binding, and return values are preserved
21
- * exactly; when the engine is inactive the original is called with the raw
22
- * arguments.
23
- */
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
-
27
- function patchMethod(
28
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
- proto, name) {
30
- const original = proto[name];
31
- if (typeof original !== "function") return false;
32
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
- if (original[_state.PATCHED_TAG]) return true;
34
-
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- const patched = function (...reactions) {
37
- for (let i = 0; i < reactions.length; i++) {
38
- if (typeof reactions[i] === "function") {
39
- reactions[i] = (0, _frameStack.buoyJsTopWrapTask)(reactions[i], "then");
40
- }
41
- }
42
- return original.apply(this, reactions);
43
- };
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- patched[_state.PATCHED_TAG] = true;
46
- Object.defineProperty(patched, "name", {
47
- value: name,
48
- configurable: true
49
- });
50
- proto[name] = patched;
51
- return true;
52
- }
53
- function installPromisePatches() {
54
- const proto = _state.g.Promise?.prototype;
55
- if (!proto) return {
56
- promises: false
57
- };
58
- const ok = patchMethod(proto, "then");
59
- patchMethod(proto, "catch");
60
- patchMethod(proto, "finally");
61
- return {
62
- promises: ok
63
- };
64
- }
65
- //# sourceMappingURL=promises.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.installPromisePatches=installPromisePatches;var _frameStack=require("../frameStack");var _state=require("../state");function patchMethod(e,t){const n=e[t];if(typeof n!=="function")return false;if(n[_state.PATCHED_TAG])return true;const u=function(...r){for(let o=0;o<r.length;o++){if(typeof r[o]==="function"){r[o]=(0,_frameStack.buoyJsTopWrapTask)(r[o],"then")}}return n.apply(this,r)};u[_state.PATCHED_TAG]=true;Object.defineProperty(u,"name",{value:t,configurable:true});e[t]=u;return true}function installPromisePatches(){const e=_state.g.Promise?.prototype;if(!e)return{promises:false};const t=patchMethod(e,"then");patchMethod(e,"catch");patchMethod(e,"finally");return{promises:t}}
@@ -1,66 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.installTimerPatches = installTimerPatches;
7
- var _frameStack = require("../frameStack");
8
- var _state = require("../state");
9
- /**
10
- * Tier 1 patches: setTimeout / setInterval / setImmediate /
11
- * requestAnimationFrame. Public globals only — RN internals (JSTimers) are
12
- * private API and churn across versions.
13
- *
14
- * Install-once, never unpatch (see state.ts). Handles are returned from the
15
- * originals unchanged, so clearTimeout/clearInterval/cancelAnimationFrame
16
- * need no patching. Extra setTimeout args pass through.
17
- */
18
-
19
- function installTimerPatches() {
20
- const originals = (0, _state.captureOriginals)();
21
- if (typeof _state.g.setTimeout === "function" && !_state.g.setTimeout[_state.PATCHED_TAG]) {
22
- const buoyJsTopSetTimeout = function (
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
- fn, timeout,
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- ...args) {
27
- const cb = (0, _frameStack.buoyJsTopWrapTask)(fn, "timeout");
28
- return originals.setTimeout(cb, timeout, ...args);
29
- };
30
- buoyJsTopSetTimeout[_state.PATCHED_TAG] = true;
31
- _state.g.setTimeout = buoyJsTopSetTimeout;
32
- }
33
- if (typeof _state.g.setInterval === "function" && !_state.g.setInterval[_state.PATCHED_TAG]) {
34
- const buoyJsTopSetInterval = function (
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- fn, timeout,
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- ...args) {
39
- const cb = (0, _frameStack.buoyJsTopWrapTask)(fn, "interval");
40
- return originals.setInterval(cb, timeout, ...args);
41
- };
42
- buoyJsTopSetInterval[_state.PATCHED_TAG] = true;
43
- _state.g.setInterval = buoyJsTopSetInterval;
44
- }
45
- if (typeof _state.g.setImmediate === "function" && !_state.g.setImmediate[_state.PATCHED_TAG] && originals.setImmediate) {
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- const buoyJsTopSetImmediate = function (fn, ...args) {
48
- const cb = (0, _frameStack.buoyJsTopWrapTask)(fn, "immediate");
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- return originals.setImmediate(cb, ...args);
51
- };
52
- buoyJsTopSetImmediate[_state.PATCHED_TAG] = true;
53
- _state.g.setImmediate = buoyJsTopSetImmediate;
54
- }
55
- if (typeof _state.g.requestAnimationFrame === "function" && !_state.g.requestAnimationFrame[_state.PATCHED_TAG] && originals.requestAnimationFrame) {
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
- const buoyJsTopRequestAnimationFrame = function (fn) {
58
- const cb = (0, _frameStack.buoyJsTopWrapTask)(fn, "raf");
59
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
- return originals.requestAnimationFrame(cb);
61
- };
62
- buoyJsTopRequestAnimationFrame[_state.PATCHED_TAG] = true;
63
- _state.g.requestAnimationFrame = buoyJsTopRequestAnimationFrame;
64
- }
65
- }
66
- //# sourceMappingURL=timers.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.installTimerPatches=installTimerPatches;var _frameStack=require("../frameStack");var _state=require("../state");function installTimerPatches(){const n=(0,_state.captureOriginals)();if(typeof _state.g.setTimeout==="function"&&!_state.g.setTimeout[_state.PATCHED_TAG]){const e=function(t,o,...r){const s=(0,_frameStack.buoyJsTopWrapTask)(t,"timeout");return n.setTimeout(s,o,...r)};e[_state.PATCHED_TAG]=true;_state.g.setTimeout=e}if(typeof _state.g.setInterval==="function"&&!_state.g.setInterval[_state.PATCHED_TAG]){const e=function(t,o,...r){const s=(0,_frameStack.buoyJsTopWrapTask)(t,"interval");return n.setInterval(s,o,...r)};e[_state.PATCHED_TAG]=true;_state.g.setInterval=e}if(typeof _state.g.setImmediate==="function"&&!_state.g.setImmediate[_state.PATCHED_TAG]&&n.setImmediate){const e=function(t,...o){const r=(0,_frameStack.buoyJsTopWrapTask)(t,"immediate");return n.setImmediate(r,...o)};e[_state.PATCHED_TAG]=true;_state.g.setImmediate=e}if(typeof _state.g.requestAnimationFrame==="function"&&!_state.g.requestAnimationFrame[_state.PATCHED_TAG]&&n.requestAnimationFrame){const e=function(t){const o=(0,_frameStack.buoyJsTopWrapTask)(t,"raf");return n.requestAnimationFrame(o)};e[_state.PATCHED_TAG]=true;_state.g.requestAnimationFrame=e}}