@buoy-gg/js-top 7.0.3

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 (168) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +56 -0
  3. package/lib/commonjs/index.js +97 -0
  4. package/lib/commonjs/index.js.map +1 -0
  5. package/lib/commonjs/js-top/components/BusySparkline.js +56 -0
  6. package/lib/commonjs/js-top/components/BusySparkline.js.map +1 -0
  7. package/lib/commonjs/js-top/components/JsTopHudOverlay.js +79 -0
  8. package/lib/commonjs/js-top/components/JsTopHudOverlay.js.map +1 -0
  9. package/lib/commonjs/js-top/components/JsTopModal.js +347 -0
  10. package/lib/commonjs/js-top/components/JsTopModal.js.map +1 -0
  11. package/lib/commonjs/js-top/components/TaskDetailView.js +329 -0
  12. package/lib/commonjs/js-top/components/TaskDetailView.js.map +1 -0
  13. package/lib/commonjs/js-top/components/TaskTable.js +360 -0
  14. package/lib/commonjs/js-top/components/TaskTable.js.map +1 -0
  15. package/lib/commonjs/js-top/engine/JsTopController.js +350 -0
  16. package/lib/commonjs/js-top/engine/JsTopController.js.map +1 -0
  17. package/lib/commonjs/js-top/engine/aggregator.js +148 -0
  18. package/lib/commonjs/js-top/engine/aggregator.js.map +1 -0
  19. package/lib/commonjs/js-top/engine/busyProbe.js +101 -0
  20. package/lib/commonjs/js-top/engine/busyProbe.js.map +1 -0
  21. package/lib/commonjs/js-top/engine/frameStack.js +133 -0
  22. package/lib/commonjs/js-top/engine/frameStack.js.map +1 -0
  23. package/lib/commonjs/js-top/engine/longtasks.js +141 -0
  24. package/lib/commonjs/js-top/engine/longtasks.js.map +1 -0
  25. package/lib/commonjs/js-top/engine/now.js +38 -0
  26. package/lib/commonjs/js-top/engine/now.js.map +1 -0
  27. package/lib/commonjs/js-top/engine/originRegistry.js +402 -0
  28. package/lib/commonjs/js-top/engine/originRegistry.js.map +1 -0
  29. package/lib/commonjs/js-top/engine/patches/bridge.js +60 -0
  30. package/lib/commonjs/js-top/engine/patches/bridge.js.map +1 -0
  31. package/lib/commonjs/js-top/engine/patches/microtasks.js +27 -0
  32. package/lib/commonjs/js-top/engine/patches/microtasks.js.map +1 -0
  33. package/lib/commonjs/js-top/engine/patches/promises.js +65 -0
  34. package/lib/commonjs/js-top/engine/patches/promises.js.map +1 -0
  35. package/lib/commonjs/js-top/engine/patches/timers.js +66 -0
  36. package/lib/commonjs/js-top/engine/patches/timers.js.map +1 -0
  37. package/lib/commonjs/js-top/engine/state.js +63 -0
  38. package/lib/commonjs/js-top/engine/state.js.map +1 -0
  39. package/lib/commonjs/js-top/engine/symbolicate.js +95 -0
  40. package/lib/commonjs/js-top/engine/symbolicate.js.map +1 -0
  41. package/lib/commonjs/js-top/sync/jsTopSyncAdapter.js +74 -0
  42. package/lib/commonjs/js-top/sync/jsTopSyncAdapter.js.map +1 -0
  43. package/lib/commonjs/js-top/types/index.js +46 -0
  44. package/lib/commonjs/js-top/types/index.js.map +1 -0
  45. package/lib/commonjs/js-top/utils/preferences.js +39 -0
  46. package/lib/commonjs/js-top/utils/preferences.js.map +1 -0
  47. package/lib/commonjs/package.json +1 -0
  48. package/lib/commonjs/preset.js +75 -0
  49. package/lib/commonjs/preset.js.map +1 -0
  50. package/lib/module/index.js +47 -0
  51. package/lib/module/index.js.map +1 -0
  52. package/lib/module/js-top/components/BusySparkline.js +52 -0
  53. package/lib/module/js-top/components/BusySparkline.js.map +1 -0
  54. package/lib/module/js-top/components/JsTopHudOverlay.js +75 -0
  55. package/lib/module/js-top/components/JsTopHudOverlay.js.map +1 -0
  56. package/lib/module/js-top/components/JsTopModal.js +343 -0
  57. package/lib/module/js-top/components/JsTopModal.js.map +1 -0
  58. package/lib/module/js-top/components/TaskDetailView.js +325 -0
  59. package/lib/module/js-top/components/TaskDetailView.js.map +1 -0
  60. package/lib/module/js-top/components/TaskTable.js +353 -0
  61. package/lib/module/js-top/components/TaskTable.js.map +1 -0
  62. package/lib/module/js-top/engine/JsTopController.js +347 -0
  63. package/lib/module/js-top/engine/JsTopController.js.map +1 -0
  64. package/lib/module/js-top/engine/aggregator.js +136 -0
  65. package/lib/module/js-top/engine/aggregator.js.map +1 -0
  66. package/lib/module/js-top/engine/busyProbe.js +94 -0
  67. package/lib/module/js-top/engine/busyProbe.js.map +1 -0
  68. package/lib/module/js-top/engine/frameStack.js +126 -0
  69. package/lib/module/js-top/engine/frameStack.js.map +1 -0
  70. package/lib/module/js-top/engine/longtasks.js +133 -0
  71. package/lib/module/js-top/engine/longtasks.js.map +1 -0
  72. package/lib/module/js-top/engine/now.js +33 -0
  73. package/lib/module/js-top/engine/now.js.map +1 -0
  74. package/lib/module/js-top/engine/originRegistry.js +388 -0
  75. package/lib/module/js-top/engine/originRegistry.js.map +1 -0
  76. package/lib/module/js-top/engine/patches/bridge.js +56 -0
  77. package/lib/module/js-top/engine/patches/bridge.js.map +1 -0
  78. package/lib/module/js-top/engine/patches/microtasks.js +23 -0
  79. package/lib/module/js-top/engine/patches/microtasks.js.map +1 -0
  80. package/lib/module/js-top/engine/patches/promises.js +62 -0
  81. package/lib/module/js-top/engine/patches/promises.js.map +1 -0
  82. package/lib/module/js-top/engine/patches/timers.js +62 -0
  83. package/lib/module/js-top/engine/patches/timers.js.map +1 -0
  84. package/lib/module/js-top/engine/state.js +54 -0
  85. package/lib/module/js-top/engine/state.js.map +1 -0
  86. package/lib/module/js-top/engine/symbolicate.js +91 -0
  87. package/lib/module/js-top/engine/symbolicate.js.map +1 -0
  88. package/lib/module/js-top/sync/jsTopSyncAdapter.js +70 -0
  89. package/lib/module/js-top/sync/jsTopSyncAdapter.js.map +1 -0
  90. package/lib/module/js-top/types/index.js +42 -0
  91. package/lib/module/js-top/types/index.js.map +1 -0
  92. package/lib/module/js-top/utils/preferences.js +34 -0
  93. package/lib/module/js-top/utils/preferences.js.map +1 -0
  94. package/lib/module/preset.js +71 -0
  95. package/lib/module/preset.js.map +1 -0
  96. package/lib/typescript/index.d.ts +21 -0
  97. package/lib/typescript/index.d.ts.map +1 -0
  98. package/lib/typescript/js-top/components/BusySparkline.d.ts +8 -0
  99. package/lib/typescript/js-top/components/BusySparkline.d.ts.map +1 -0
  100. package/lib/typescript/js-top/components/JsTopHudOverlay.d.ts +8 -0
  101. package/lib/typescript/js-top/components/JsTopHudOverlay.d.ts.map +1 -0
  102. package/lib/typescript/js-top/components/JsTopModal.d.ts +39 -0
  103. package/lib/typescript/js-top/components/JsTopModal.d.ts.map +1 -0
  104. package/lib/typescript/js-top/components/TaskDetailView.d.ts +15 -0
  105. package/lib/typescript/js-top/components/TaskDetailView.d.ts.map +1 -0
  106. package/lib/typescript/js-top/components/TaskTable.d.ts +38 -0
  107. package/lib/typescript/js-top/components/TaskTable.d.ts.map +1 -0
  108. package/lib/typescript/js-top/engine/JsTopController.d.ts +78 -0
  109. package/lib/typescript/js-top/engine/JsTopController.d.ts.map +1 -0
  110. package/lib/typescript/js-top/engine/__tests__/engine.test.d.ts +9 -0
  111. package/lib/typescript/js-top/engine/__tests__/engine.test.d.ts.map +1 -0
  112. package/lib/typescript/js-top/engine/aggregator.d.ts +33 -0
  113. package/lib/typescript/js-top/engine/aggregator.d.ts.map +1 -0
  114. package/lib/typescript/js-top/engine/busyProbe.d.ts +25 -0
  115. package/lib/typescript/js-top/engine/busyProbe.d.ts.map +1 -0
  116. package/lib/typescript/js-top/engine/frameStack.d.ts +44 -0
  117. package/lib/typescript/js-top/engine/frameStack.d.ts.map +1 -0
  118. package/lib/typescript/js-top/engine/longtasks.d.ts +37 -0
  119. package/lib/typescript/js-top/engine/longtasks.d.ts.map +1 -0
  120. package/lib/typescript/js-top/engine/now.d.ts +9 -0
  121. package/lib/typescript/js-top/engine/now.d.ts.map +1 -0
  122. package/lib/typescript/js-top/engine/originRegistry.d.ts +82 -0
  123. package/lib/typescript/js-top/engine/originRegistry.d.ts.map +1 -0
  124. package/lib/typescript/js-top/engine/patches/bridge.d.ts +17 -0
  125. package/lib/typescript/js-top/engine/patches/bridge.d.ts.map +1 -0
  126. package/lib/typescript/js-top/engine/patches/microtasks.d.ts +6 -0
  127. package/lib/typescript/js-top/engine/patches/microtasks.d.ts.map +1 -0
  128. package/lib/typescript/js-top/engine/patches/promises.d.ts +18 -0
  129. package/lib/typescript/js-top/engine/patches/promises.d.ts.map +1 -0
  130. package/lib/typescript/js-top/engine/patches/timers.d.ts +11 -0
  131. package/lib/typescript/js-top/engine/patches/timers.d.ts.map +1 -0
  132. package/lib/typescript/js-top/engine/state.d.ts +35 -0
  133. package/lib/typescript/js-top/engine/state.d.ts.map +1 -0
  134. package/lib/typescript/js-top/engine/symbolicate.d.ts +16 -0
  135. package/lib/typescript/js-top/engine/symbolicate.d.ts.map +1 -0
  136. package/lib/typescript/js-top/sync/jsTopSyncAdapter.d.ts +43 -0
  137. package/lib/typescript/js-top/sync/jsTopSyncAdapter.d.ts.map +1 -0
  138. package/lib/typescript/js-top/types/index.d.ts +130 -0
  139. package/lib/typescript/js-top/types/index.d.ts.map +1 -0
  140. package/lib/typescript/js-top/utils/preferences.d.ts +13 -0
  141. package/lib/typescript/js-top/utils/preferences.d.ts.map +1 -0
  142. package/lib/typescript/preset.d.ts +49 -0
  143. package/lib/typescript/preset.d.ts.map +1 -0
  144. package/package.json +67 -0
  145. package/src/index.tsx +69 -0
  146. package/src/js-top/components/BusySparkline.tsx +59 -0
  147. package/src/js-top/components/JsTopHudOverlay.tsx +78 -0
  148. package/src/js-top/components/JsTopModal.tsx +421 -0
  149. package/src/js-top/components/TaskDetailView.tsx +349 -0
  150. package/src/js-top/components/TaskTable.tsx +365 -0
  151. package/src/js-top/engine/JsTopController.ts +401 -0
  152. package/src/js-top/engine/__tests__/engine.test.ts +337 -0
  153. package/src/js-top/engine/aggregator.ts +148 -0
  154. package/src/js-top/engine/busyProbe.ts +100 -0
  155. package/src/js-top/engine/frameStack.ts +142 -0
  156. package/src/js-top/engine/longtasks.ts +137 -0
  157. package/src/js-top/engine/now.ts +33 -0
  158. package/src/js-top/engine/originRegistry.ts +495 -0
  159. package/src/js-top/engine/patches/bridge.ts +69 -0
  160. package/src/js-top/engine/patches/microtasks.ts +25 -0
  161. package/src/js-top/engine/patches/promises.ts +57 -0
  162. package/src/js-top/engine/patches/timers.ts +80 -0
  163. package/src/js-top/engine/state.ts +66 -0
  164. package/src/js-top/engine/symbolicate.ts +109 -0
  165. package/src/js-top/sync/jsTopSyncAdapter.ts +72 -0
  166. package/src/js-top/types/index.ts +144 -0
  167. package/src/js-top/utils/preferences.ts +35 -0
  168. package/src/preset.tsx +67 -0
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Shared engine state + pre-patch originals.
5
+ *
6
+ * `active` is the single gate every patched global checks at schedule time:
7
+ * patches install once and are NEVER removed (restoring originals would
8
+ * clobber any wrapper another library — Sentry, Reanimated — layered on top
9
+ * of ours after install; same reasoning as highlight-updates' CommitProfiler
10
+ * hook). When inactive, a patched global forwards the raw callback to the
11
+ * original at the cost of one boolean check.
12
+ *
13
+ * `originals` are captured BEFORE patching so the engine's own probe and
14
+ * notify timers never flow through the wrappers — JS TOP must not list
15
+ * itself as a task.
16
+ */
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ export const g =
20
+ // eslint-disable-next-line no-restricted-globals
21
+ typeof globalThis !== "undefined" ? globalThis : {};
22
+ let active = false;
23
+ export function isActive() {
24
+ return active;
25
+ }
26
+ export function setActive(on) {
27
+ active = on;
28
+ }
29
+ let originals = null;
30
+
31
+ /** Capture pre-patch globals. Idempotent; first call wins. */
32
+ export function captureOriginals() {
33
+ if (!originals) {
34
+ originals = {
35
+ setTimeout: g.setTimeout?.bind(g),
36
+ setInterval: g.setInterval?.bind(g),
37
+ clearInterval: g.clearInterval?.bind(g),
38
+ clearTimeout: g.clearTimeout?.bind(g),
39
+ setImmediate: g.setImmediate?.bind(g),
40
+ requestAnimationFrame: g.requestAnimationFrame?.bind(g),
41
+ queueMicrotask: g.queueMicrotask?.bind(g)
42
+ };
43
+ }
44
+ return originals;
45
+ }
46
+ export function getOriginals() {
47
+ return captureOriginals();
48
+ }
49
+
50
+ /** Tag interned on patched globals so duplicate module instances skip re-patching. */
51
+ export const PATCHED_TAG = Symbol.for("buoy.jsTop.patched");
52
+ /** Marker set on wrapper functions so a wrapped fn is never wrapped twice. */
53
+ export const WRAPPED_TAG = Symbol.for("buoy.jsTop.wrapped");
54
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["g","globalThis","active","isActive","setActive","on","originals","captureOriginals","setTimeout","bind","setInterval","clearInterval","clearTimeout","setImmediate","requestAnimationFrame","queueMicrotask","getOriginals","PATCHED_TAG","Symbol","for","WRAPPED_TAG"],"sourceRoot":"../../../../src","sources":["js-top/engine/state.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO,MAAMA,CAAM;AACjB;AACA,OAAOC,UAAU,KAAK,WAAW,GAAGA,UAAU,GAAG,CAAC,CAAC;AAErD,IAAIC,MAAM,GAAG,KAAK;AAElB,OAAO,SAASC,QAAQA,CAAA,EAAY;EAClC,OAAOD,MAAM;AACf;AAEA,OAAO,SAASE,SAASA,CAACC,EAAW,EAAQ;EAC3CH,MAAM,GAAGG,EAAE;AACb;AAYA,IAAIC,SAA2B,GAAG,IAAI;;AAEtC;AACA,OAAO,SAASC,gBAAgBA,CAAA,EAAc;EAC5C,IAAI,CAACD,SAAS,EAAE;IACdA,SAAS,GAAG;MACVE,UAAU,EAAER,CAAC,CAACQ,UAAU,EAAEC,IAAI,CAACT,CAAC,CAAC;MACjCU,WAAW,EAAEV,CAAC,CAACU,WAAW,EAAED,IAAI,CAACT,CAAC,CAAC;MACnCW,aAAa,EAAEX,CAAC,CAACW,aAAa,EAAEF,IAAI,CAACT,CAAC,CAAC;MACvCY,YAAY,EAAEZ,CAAC,CAACY,YAAY,EAAEH,IAAI,CAACT,CAAC,CAAC;MACrCa,YAAY,EAAEb,CAAC,CAACa,YAAY,EAAEJ,IAAI,CAACT,CAAC,CAAC;MACrCc,qBAAqB,EAAEd,CAAC,CAACc,qBAAqB,EAAEL,IAAI,CAACT,CAAC,CAAC;MACvDe,cAAc,EAAEf,CAAC,CAACe,cAAc,EAAEN,IAAI,CAACT,CAAC;IAC1C,CAAC;EACH;EACA,OAAOM,SAAS;AAClB;AAEA,OAAO,SAASU,YAAYA,CAAA,EAAc;EACxC,OAAOT,gBAAgB,CAAC,CAAC;AAC3B;;AAEA;AACA,OAAO,MAAMU,WAAW,GAAGC,MAAM,CAACC,GAAG,CAAC,oBAAoB,CAAC;AAC3D;AACA,OAAO,MAAMC,WAAW,GAAGF,MAAM,CAACC,GAAG,CAAC,oBAAoB,CAAC","ignoreList":[]}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Dev-only origin symbolication via Metro's /symbolicate endpoint (the same
5
+ * one LogBox uses). Hermes stacks give function names + bundle offsets; for
6
+ * anonymous scheduling sites (the typical `useEffect(() => setInterval(…))`)
7
+ * that leaves an unreadable label. Metro maps the offset back to the real
8
+ * source file — so a row can say `setInterval ← ChatScreen.tsx:42`, which is
9
+ * component-level attribution in practice.
10
+ *
11
+ * Fire-and-forget with hard caps: one attempt per origin, few in flight,
12
+ * silent on any failure (release builds, tunnels, Metro gone). The origin's
13
+ * label/file/line are upgraded in place when the answer lands — the table
14
+ * re-renders every tick and picks it up.
15
+ */
16
+
17
+ const MAX_IN_FLIGHT = 3;
18
+ let inFlight = 0;
19
+ function isDev() {
20
+ return typeof __DEV__ !== "undefined" && __DEV__;
21
+ }
22
+
23
+ /** Last two path segments of a source path — "screens/ChatScreen.tsx". */
24
+ function tailPath(file) {
25
+ const clean = file.split("?")[0] ?? file;
26
+ const parts = clean.split("/").filter(Boolean);
27
+ return parts.slice(-2).join("/");
28
+ }
29
+
30
+ /** True for names like ChatScreen / PokemonScreen — reads as a component. */
31
+ function looksLikeComponent(name) {
32
+ return /^[A-Z][A-Za-z0-9]*$/.test(name);
33
+ }
34
+ export function buoyJsTopSymbolicateOrigin(o, apiLabelText) {
35
+ if (!isDev()) return;
36
+ if (o.symbolicated || !o.frames || o.frames.length === 0) return;
37
+ if (inFlight >= MAX_IN_FLIGHT) return; // retried implicitly? no — one shot
38
+ o.symbolicated = true;
39
+ const top = o.frames[0];
40
+ if (!top || !/^https?:\/\//.test(top.file)) return;
41
+ let endpoint;
42
+ try {
43
+ endpoint = `${new URL(top.file).origin}/symbolicate`;
44
+ } catch {
45
+ return;
46
+ }
47
+ inFlight++;
48
+ const body = JSON.stringify({
49
+ stack: o.frames.map(f => ({
50
+ file: f.file,
51
+ lineNumber: f.line,
52
+ column: f.col,
53
+ methodName: ""
54
+ }))
55
+ });
56
+ fetch(endpoint, {
57
+ method: "POST",
58
+ body
59
+ }).then(res => res.ok ? res.json() : null).then(data => {
60
+ let frame = data?.stack?.find(f => f.file && !f.file.includes("node_modules")) ?? data?.stack?.[0];
61
+ // Some Metro configs (serialized source maps) reject full
62
+ // symbolication but still NAME the module in the error — that file
63
+ // path is exactly the scheduling site, so harvest it.
64
+ if (!frame?.file && data?.error) {
65
+ const m = /found: (\/.+)$/.exec(data.error);
66
+ if (m) frame = {
67
+ file: m[1]
68
+ };
69
+ }
70
+ if (!frame?.file) return;
71
+ const file = tailPath(frame.file);
72
+ const line = frame.lineNumber;
73
+ const method = frame.methodName && frame.methodName !== "<unknown>" ? frame.methodName : undefined;
74
+ o.file = file;
75
+ o.line = line ?? o.line;
76
+ // The existing label is name-anchored — append the source site
77
+ // once, and promote a component-looking method name.
78
+ const site = `${file.split("/").pop()}${line != null ? `:${line}` : ""}`;
79
+ if (method && looksLikeComponent(method) && !o.caller) {
80
+ o.caller = method;
81
+ o.label = `${o.label} ← <${method}> · ${site}`;
82
+ } else {
83
+ o.label = `${o.label} · ${site}`;
84
+ }
85
+ }).catch(() => {
86
+ // Symbolication is best-effort decoration — never surface failures.
87
+ }).finally(() => {
88
+ inFlight--;
89
+ });
90
+ }
91
+ //# sourceMappingURL=symbolicate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["MAX_IN_FLIGHT","inFlight","isDev","__DEV__","tailPath","file","clean","split","parts","filter","Boolean","slice","join","looksLikeComponent","name","test","buoyJsTopSymbolicateOrigin","o","apiLabelText","symbolicated","frames","length","top","endpoint","URL","origin","body","JSON","stringify","stack","map","f","lineNumber","line","column","col","methodName","fetch","method","then","res","ok","json","data","frame","find","includes","error","m","exec","undefined","site","pop","caller","label","catch","finally"],"sourceRoot":"../../../../src","sources":["js-top/engine/symbolicate.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Sync adapter for the JS TOP tool, consumed by @buoy-gg/external-sync's
5
+ * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
6
+ * this package doesn't need a dependency on it — same pattern as
7
+ * perf-monitor's adapter).
8
+ *
9
+ * `subscribe` is only called while a dashboard is watching, and subscribing
10
+ * to JsTopController is exactly what starts the engine — so a desktop
11
+ * watcher auto-starts sampling and closing the desktop tool stops it. The
12
+ * snapshot IS the live channel; there is no heavy persisted state.
13
+ */
14
+
15
+ import { JsTopController } from "../engine/JsTopController";
16
+ export const jsTopSyncAdapter = {
17
+ version: 1,
18
+ getSnapshot: () => ({
19
+ live: JsTopController.getSnapshot(),
20
+ // "enabled" mirrors perf-monitor semantics: is the device sampling for
21
+ // any viewer (its own HUD/modal or a desktop's silent remote sampling).
22
+ enabled: JsTopController.isEnabled() || JsTopController.isRemoteSampling()
23
+ }),
24
+ subscribe: onChange => {
25
+ const unsubSnapshot = JsTopController.subscribe(() => onChange());
26
+ const unsubEnabled = JsTopController.subscribeEnabled(() => onChange());
27
+ return () => {
28
+ unsubSnapshot();
29
+ unsubEnabled();
30
+ };
31
+ },
32
+ actions: {
33
+ /**
34
+ * Silent sampling for a desktop viewer: streams snapshots without
35
+ * showing the device's own HUD. (Subscribing via `subscribe` already
36
+ * runs the engine while watched; this exists so MCP / scripted callers
37
+ * can force sampling on without a watch.)
38
+ */
39
+ setEnabled: params => {
40
+ const enabled = params.enabled;
41
+ JsTopController.setRemoteSampling(enabled);
42
+ },
43
+ pause: () => JsTopController.pause(),
44
+ resume: () => JsTopController.resume(),
45
+ clear: () => JsTopController.clear(),
46
+ /** Full detail for one origin (desktop tap-through parity). */
47
+ getOriginDetail: params => JsTopController.getOriginDetail(params.key),
48
+ /**
49
+ * One-shot sample for MCP/automation: ensure the engine is running,
50
+ * observe for `durationMs` (default 3s, capped 30s), return the
51
+ * resulting snapshot. `clearFirst` resets all stats before sampling so
52
+ * the result attributes exactly one interaction/window. Leaves sampling
53
+ * in its prior state.
54
+ */
55
+ sample: async params => {
56
+ const p = params;
57
+ const durationMs = Math.min(Math.max(p?.durationMs ?? 3000, 250), 30_000);
58
+ const wasSampling = JsTopController.isRemoteSampling() || JsTopController.isEnabled();
59
+ if (!wasSampling) JsTopController.setRemoteSampling(true);
60
+ if (p?.clearFirst) JsTopController.clear();
61
+ try {
62
+ await new Promise(resolve => setTimeout(resolve, durationMs));
63
+ return JsTopController.getSnapshot();
64
+ } finally {
65
+ if (!wasSampling) JsTopController.setRemoteSampling(false);
66
+ }
67
+ }
68
+ }
69
+ };
70
+ //# sourceMappingURL=jsTopSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["JsTopController","jsTopSyncAdapter","version","getSnapshot","live","enabled","isEnabled","isRemoteSampling","subscribe","onChange","unsubSnapshot","unsubEnabled","subscribeEnabled","actions","setEnabled","params","setRemoteSampling","pause","resume","clear","getOriginDetail","key","sample","p","durationMs","Math","min","max","wasSampling","clearFirst","Promise","resolve","setTimeout"],"sourceRoot":"../../../../src","sources":["js-top/sync/jsTopSyncAdapter.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,eAAe,QAAQ,2BAA2B;AAG3D,OAAO,MAAMC,gBAAgB,GAAG;EAC9BC,OAAO,EAAE,CAAC;EACVC,WAAW,EAAEA,CAAA,MAAkD;IAC7DC,IAAI,EAAEJ,eAAe,CAACG,WAAW,CAAC,CAAC;IACnC;IACA;IACAE,OAAO,EACLL,eAAe,CAACM,SAAS,CAAC,CAAC,IAAIN,eAAe,CAACO,gBAAgB,CAAC;EACpE,CAAC,CAAC;EACFC,SAAS,EAAGC,QAAoB,IAAK;IACnC,MAAMC,aAAa,GAAGV,eAAe,CAACQ,SAAS,CAAC,MAAMC,QAAQ,CAAC,CAAC,CAAC;IACjE,MAAME,YAAY,GAAGX,eAAe,CAACY,gBAAgB,CAAC,MAAMH,QAAQ,CAAC,CAAC,CAAC;IACvE,OAAO,MAAM;MACXC,aAAa,CAAC,CAAC;MACfC,YAAY,CAAC,CAAC;IAChB,CAAC;EACH,CAAC;EACDE,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;AACA;IACIC,UAAU,EAAGC,MAAe,IAAK;MAC/B,MAAMV,OAAO,GAAIU,MAAM,CAA0BV,OAAO;MACxDL,eAAe,CAACgB,iBAAiB,CAACX,OAAO,CAAC;IAC5C,CAAC;IACDY,KAAK,EAAEA,CAAA,KAAMjB,eAAe,CAACiB,KAAK,CAAC,CAAC;IACpCC,MAAM,EAAEA,CAAA,KAAMlB,eAAe,CAACkB,MAAM,CAAC,CAAC;IACtCC,KAAK,EAAEA,CAAA,KAAMnB,eAAe,CAACmB,KAAK,CAAC,CAAC;IACpC;IACAC,eAAe,EAAGL,MAAe,IAC/Bf,eAAe,CAACoB,eAAe,CAAEL,MAAM,CAAqBM,GAAG,CAAC;IAClE;AACJ;AACA;AACA;AACA;AACA;AACA;IACIC,MAAM,EAAE,MAAOP,MAAe,IAAK;MACjC,MAAMQ,CAAC,GAAGR,MAAuD;MACjE,MAAMS,UAAU,GAAGC,IAAI,CAACC,GAAG,CAACD,IAAI,CAACE,GAAG,CAACJ,CAAC,EAAEC,UAAU,IAAI,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC;MACzE,MAAMI,WAAW,GACf5B,eAAe,CAACO,gBAAgB,CAAC,CAAC,IAAIP,eAAe,CAACM,SAAS,CAAC,CAAC;MACnE,IAAI,CAACsB,WAAW,EAAE5B,eAAe,CAACgB,iBAAiB,CAAC,IAAI,CAAC;MACzD,IAAIO,CAAC,EAAEM,UAAU,EAAE7B,eAAe,CAACmB,KAAK,CAAC,CAAC;MAC1C,IAAI;QACF,MAAM,IAAIW,OAAO,CAAEC,OAAO,IAAKC,UAAU,CAACD,OAAO,EAAEP,UAAU,CAAC,CAAC;QAC/D,OAAOxB,eAAe,CAACG,WAAW,CAAC,CAAC;MACtC,CAAC,SAAS;QACR,IAAI,CAACyB,WAAW,EAAE5B,eAAe,CAACgB,iBAAiB,CAAC,KAAK,CAAC;MAC5D;IACF;EACF;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * JS TOP — live Task Manager for the React Native JS thread.
5
+ *
6
+ * Attribution model: the engine wraps every JS-thread entry point it can
7
+ * reach (timers, rAF, microtasks, Promise reactions, legacy-bridge call-ins)
8
+ * and books EXCLUSIVE time per "origin" (the place a callback was scheduled
9
+ * from). A high-frequency probe measures true thread occupancy; the gap
10
+ * between measured busy time and attributed time is surfaced honestly as an
11
+ * "unattributed" row rather than hidden.
12
+ */
13
+
14
+ /** Which entry-point API a task came through. */
15
+
16
+ /** One captured stack frame from an origin's scheduling site (dev-readable). */
17
+
18
+ /**
19
+ * Which coverage tiers are live on this device. UIs gray out / banner what a
20
+ * runtime can't see (e.g. bridge call-ins don't exist on bridgeless).
21
+ */
22
+
23
+ /** One row of the live table — a task origin ("process" in Task Manager terms). */
24
+
25
+ /** A 50ms+ blocking task reported by the runtime, with our best attribution. */
26
+
27
+ /** The JSON-serializable live snapshot (device UI + external-sync payload). */
28
+
29
+ /** Everything the engine knows about one origin — the tap-through detail. */
30
+
31
+ /** Engine tuning constants — exported for tests. */
32
+ export const BUCKET_MS = 250;
33
+ /** Rolling "recent" window: 20 buckets = 5s. */
34
+ export const WINDOW_BUCKETS = 20;
35
+ /** Global busy history ring: 120 buckets = 30s. */
36
+ export const HISTORY_BUCKETS = 120;
37
+ export const MAX_ORIGINS = 500;
38
+ /** Promotion thresholds: capture a scheduling stack once an origin is hot. */
39
+ export const PROMOTE_MIN_CALLS = 25;
40
+ export const PROMOTE_MIN_TOTAL_MS = 50;
41
+ export const SNAPSHOT_ROWS = 30;
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BUCKET_MS","WINDOW_BUCKETS","HISTORY_BUCKETS","MAX_ORIGINS","PROMOTE_MIN_CALLS","PROMOTE_MIN_TOTAL_MS","SNAPSHOT_ROWS"],"sourceRoot":"../../../../src","sources":["js-top/types/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAYA;;AAOA;AACA;AACA;AACA;;AAYA;;AA0BA;;AAWA;;AAwBA;;AA2BA;AACA,OAAO,MAAMA,SAAS,GAAG,GAAG;AAC5B;AACA,OAAO,MAAMC,cAAc,GAAG,EAAE;AAChC;AACA,OAAO,MAAMC,eAAe,GAAG,GAAG;AAClC,OAAO,MAAMC,WAAW,GAAG,GAAG;AAC9B;AACA,OAAO,MAAMC,iBAAiB,GAAG,EAAE;AACnC,OAAO,MAAMC,oBAAoB,GAAG,EAAE;AACtC,OAAO,MAAMC,aAAa,GAAG,EAAE","ignoreList":[]}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Persisted JS TOP preferences. Same load-then-save contract as
5
+ * perf-monitor's hudPreferences: rehydrate async, and only persist
6
+ * user-driven changes after the load resolves so defaults never clobber
7
+ * last session's state.
8
+ */
9
+
10
+ import { persistentStorage } from "@buoy-gg/shared-ui";
11
+ const KEY = "@react_buoy/js-top/prefs";
12
+ const DEFAULTS = {
13
+ enabled: false
14
+ };
15
+ export async function loadJsTopPrefs() {
16
+ try {
17
+ const raw = await persistentStorage.getItem(KEY);
18
+ if (!raw) return DEFAULTS;
19
+ const parsed = JSON.parse(raw);
20
+ return {
21
+ enabled: parsed.enabled === true
22
+ };
23
+ } catch {
24
+ return DEFAULTS;
25
+ }
26
+ }
27
+ export async function saveJsTopPrefs(prefs) {
28
+ try {
29
+ await persistentStorage.setItem(KEY, JSON.stringify(prefs));
30
+ } catch {
31
+ // Storage unavailable — non-fatal.
32
+ }
33
+ }
34
+ //# sourceMappingURL=preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["persistentStorage","KEY","DEFAULTS","enabled","loadJsTopPrefs","raw","getItem","parsed","JSON","parse","saveJsTopPrefs","prefs","setItem","stringify"],"sourceRoot":"../../../../src","sources":["js-top/utils/preferences.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB,QAAQ,oBAAoB;AAEtD,MAAMC,GAAG,GAAG,0BAA0B;AAMtC,MAAMC,QAAoB,GAAG;EAAEC,OAAO,EAAE;AAAM,CAAC;AAE/C,OAAO,eAAeC,cAAcA,CAAA,EAAwB;EAC1D,IAAI;IACF,MAAMC,GAAG,GAAG,MAAML,iBAAiB,CAACM,OAAO,CAACL,GAAG,CAAC;IAChD,IAAI,CAACI,GAAG,EAAE,OAAOH,QAAQ;IACzB,MAAMK,MAAM,GAAGC,IAAI,CAACC,KAAK,CAACJ,GAAG,CAAwB;IACrD,OAAO;MAAEF,OAAO,EAAEI,MAAM,CAACJ,OAAO,KAAK;IAAK,CAAC;EAC7C,CAAC,CAAC,MAAM;IACN,OAAOD,QAAQ;EACjB;AACF;AAEA,OAAO,eAAeQ,cAAcA,CAACC,KAAiB,EAAiB;EACrE,IAAI;IACF,MAAMX,iBAAiB,CAACY,OAAO,CAACX,GAAG,EAAEO,IAAI,CAACK,SAAS,CAACF,KAAK,CAAC,CAAC;EAC7D,CAAC,CAAC,MAAM;IACN;EAAA;AAEJ","ignoreList":[]}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Pre-configured JS TOP tools for FloatingDevTools.
5
+ *
6
+ * Two presets:
7
+ * - jsTopPreset: toggle-only chip that turns the floating busy% pill on/off.
8
+ * - jsTopModalPreset: opens the Task Manager window (ranked live table).
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { jsTopPreset, jsTopModalPreset } from '@buoy-gg/js-top';
13
+ *
14
+ * <FloatingDevTools apps={[jsTopPreset, jsTopModalPreset]} />
15
+ * ```
16
+ */
17
+
18
+ import { useEffect, useState } from "react";
19
+ import { Activity } from "@buoy-gg/shared-ui";
20
+ import { JsTopController } from "./js-top/engine/JsTopController";
21
+ import { JsTopModal } from "./js-top/components/JsTopModal";
22
+ import { jsx as _jsx } from "react/jsx-runtime";
23
+ export const JS_TOP_ENABLED_COLOR = "#34D399";
24
+ export const JS_TOP_DISABLED_COLOR = "#6B7280";
25
+ function JsTopToggleIcon({
26
+ size
27
+ }) {
28
+ const [enabled, setEnabled] = useState(() => JsTopController.isEnabled());
29
+ useEffect(() => JsTopController.subscribeEnabled(setEnabled), []);
30
+ return /*#__PURE__*/_jsx(Activity, {
31
+ size: size,
32
+ color: enabled ? JS_TOP_ENABLED_COLOR : JS_TOP_DISABLED_COLOR
33
+ });
34
+ }
35
+ function EmptyComponent() {
36
+ return null;
37
+ }
38
+
39
+ /** Toggle-only preset: show/hide the floating busy% pill. */
40
+ export const jsTopPreset = {
41
+ id: "js-top",
42
+ name: "JS TOP",
43
+ description: "Toggle the floating JS-thread busy pill",
44
+ slot: "row",
45
+ icon: JsTopToggleIcon,
46
+ component: EmptyComponent,
47
+ props: {},
48
+ launchMode: "toggle-only",
49
+ onPress: () => {
50
+ JsTopController.setEnabled(!JsTopController.isEnabled());
51
+ }
52
+ };
53
+
54
+ /** Modal preset: the live Task Manager window. */
55
+ export const jsTopModalPreset = {
56
+ id: "js-top-modal",
57
+ name: "TASKS",
58
+ description: "Live Task Manager for the JS thread",
59
+ slot: "both",
60
+ icon: ({
61
+ size
62
+ }) => /*#__PURE__*/_jsx(Activity, {
63
+ size: size,
64
+ color: JS_TOP_ENABLED_COLOR
65
+ }),
66
+ component: JsTopModal,
67
+ props: {
68
+ enableSharedModalDimensions: false
69
+ }
70
+ };
71
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","useState","Activity","JsTopController","JsTopModal","jsx","_jsx","JS_TOP_ENABLED_COLOR","JS_TOP_DISABLED_COLOR","JsTopToggleIcon","size","enabled","setEnabled","isEnabled","subscribeEnabled","color","EmptyComponent","jsTopPreset","id","name","description","slot","icon","component","props","launchMode","onPress","jsTopModalPreset","enableSharedModalDimensions"],"sourceRoot":"../../src","sources":["preset.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,QAAQ,QAAQ,oBAAoB;AAC7C,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,UAAU,QAAQ,gCAAgC;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAE5D,OAAO,MAAMC,oBAAoB,GAAG,SAAS;AAC7C,OAAO,MAAMC,qBAAqB,GAAG,SAAS;AAE9C,SAASC,eAAeA,CAAC;EAAEC;AAAuB,CAAC,EAAE;EACnD,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGX,QAAQ,CAAC,MAAME,eAAe,CAACU,SAAS,CAAC,CAAC,CAAC;EACzEb,SAAS,CAAC,MAAMG,eAAe,CAACW,gBAAgB,CAACF,UAAU,CAAC,EAAE,EAAE,CAAC;EACjE,oBACEN,IAAA,CAACJ,QAAQ;IACPQ,IAAI,EAAEA,IAAK;IACXK,KAAK,EAAEJ,OAAO,GAAGJ,oBAAoB,GAAGC;EAAsB,CAC/D,CAAC;AAEN;AAEA,SAASQ,cAAcA,CAAA,EAAG;EACxB,OAAO,IAAI;AACb;;AAEA;AACA,OAAO,MAAMC,WAAW,GAAG;EACzBC,EAAE,EAAE,QAAQ;EACZC,IAAI,EAAE,QAAQ;EACdC,WAAW,EAAE,yCAAyC;EACtDC,IAAI,EAAE,KAAc;EACpBC,IAAI,EAAEb,eAAe;EACrBc,SAAS,EAAEP,cAAc;EACzBQ,KAAK,EAAE,CAAC,CAAC;EACTC,UAAU,EAAE,aAAsB;EAClCC,OAAO,EAAEA,CAAA,KAAM;IACbvB,eAAe,CAACS,UAAU,CAAC,CAACT,eAAe,CAACU,SAAS,CAAC,CAAC,CAAC;EAC1D;AACF,CAAC;;AAED;AACA,OAAO,MAAMc,gBAAgB,GAAG;EAC9BT,EAAE,EAAE,cAAc;EAClBC,IAAI,EAAE,OAAO;EACbC,WAAW,EAAE,qCAAqC;EAClDC,IAAI,EAAE,MAAe;EACrBC,IAAI,EAAEA,CAAC;IAAEZ;EAAuB,CAAC,kBAC/BJ,IAAA,CAACJ,QAAQ;IAACQ,IAAI,EAAEA,IAAK;IAACK,KAAK,EAAER;EAAqB,CAAE,CACrD;EACDgB,SAAS,EAAEnB,UAAU;EACrBoB,KAAK,EAAE;IACLI,2BAA2B,EAAE;EAC/B;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @buoy-gg/js-top — live Task Manager for the React Native JS thread.
3
+ *
4
+ * Pure JS (Expo Go + release compatible): wraps timers / rAF / microtasks /
5
+ * Promise reactions / legacy-bridge call-ins and books exclusive time per
6
+ * scheduling origin; a calibrated busy probe measures true thread occupancy
7
+ * so unattributable work is surfaced honestly instead of hidden.
8
+ *
9
+ * Coverage tiers beyond the core (promises, bridge, longtask correlation)
10
+ * are registered here at module scope — the controller installs them lazily
11
+ * on first engine start, so importing this package costs nothing until a
12
+ * viewer opens the tool.
13
+ */
14
+ export { JsTopController } from "./js-top/engine/JsTopController";
15
+ export { jsTopSyncAdapter } from "./js-top/sync/jsTopSyncAdapter";
16
+ export { JsTopModal } from "./js-top/components/JsTopModal";
17
+ export type { JsTopModalProps, JsTopRemoteActions, } from "./js-top/components/JsTopModal";
18
+ export { JsTopHudOverlay } from "./js-top/components/JsTopHudOverlay";
19
+ export { jsTopPreset, jsTopModalPreset, JS_TOP_ENABLED_COLOR, JS_TOP_DISABLED_COLOR, } from "./preset";
20
+ export type { JsTopSnapshot, JsTopRow, JsTopLongtask, JsTopOriginDetail, JsTopTiers, JsTopStatus, TaskApi, } from "./js-top/types";
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkCH,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,YAAY,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,OAAO,GACR,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Busy% history sparkline — plain View bars (no SVG dependency), tinted by
3
+ * severity. Renders at most the trailing 60 buckets (15s).
4
+ */
5
+ export declare const BusySparkline: import("react").NamedExoticComponent<{
6
+ history: number[];
7
+ }>;
8
+ //# sourceMappingURL=BusySparkline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BusySparkline.d.ts","sourceRoot":"","sources":["../../../../src/js-top/components/BusySparkline.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,eAAO,MAAM,aAAa;aAGf,MAAM,EAAE;EAsBjB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Minimal floating HUD pill: busy% + the current top offender. Rendered by
3
+ * FloatingDevTools (guarded require) when the JS TOP toggle chip is on —
4
+ * same auto-mount pattern as the perf-monitor overlay. Display-only in v1
5
+ * (no drag; sits under the status bar on the left).
6
+ */
7
+ export declare function JsTopHudOverlay(): import("react").JSX.Element | null;
8
+ //# sourceMappingURL=JsTopHudOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsTopHudOverlay.d.ts","sourceRoot":"","sources":["../../../../src/js-top/components/JsTopHudOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,wBAAgB,eAAe,uCA8B9B"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * JS TOP modal — the Task Manager window.
3
+ *
4
+ * Layout: header (busy% pill + pause/clear controls) → busy sparkline →
5
+ * coverage banner (when bridge tier is unavailable) → ranked task table →
6
+ * blocking-task list.
7
+ *
8
+ * Data source is the local JsTopController by default. The desktop
9
+ * dashboard mounts this same component via react-native-web and injects the
10
+ * synced device snapshot + remote actions through `remoteSnapshot` /
11
+ * `remoteActions` — the modal never samples the Electron renderer.
12
+ */
13
+ import { type ModalState } from "@buoy-gg/shared-ui";
14
+ import type { JsTopSnapshot } from "../types";
15
+ export interface JsTopRemoteActions {
16
+ pause: () => void;
17
+ resume: () => void;
18
+ clear: () => void;
19
+ }
20
+ export interface JsTopModalProps {
21
+ visible: boolean;
22
+ onClose: () => void;
23
+ /** App-stack back (from the floating menu's AppHost). */
24
+ onBack?: () => void;
25
+ onMinimize?: (modalState: ModalState) => void;
26
+ initialModalState?: ModalState;
27
+ minimizeTargetPosition?: {
28
+ x: number;
29
+ y: number;
30
+ };
31
+ enableSharedModalDimensions?: boolean;
32
+ /** Desktop dashboard: render from a synced device snapshot. */
33
+ remoteSnapshot?: JsTopSnapshot | null;
34
+ remoteActions?: JsTopRemoteActions;
35
+ /** Desktop Workbench: render inline, parent supplies window chrome. */
36
+ embedded?: boolean;
37
+ }
38
+ export declare function JsTopModal({ visible, onClose, onBack, onMinimize, initialModalState, minimizeTargetPosition, remoteSnapshot, remoteActions, embedded, }: JsTopModalProps): import("react").JSX.Element;
39
+ //# sourceMappingURL=JsTopModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsTopModal.d.ts","sourceRoot":"","sources":["../../../../src/js-top/components/JsTopModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAO9C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,sBAAsB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2DD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,aAAa,EACb,QAAgB,GACjB,EAAE,eAAe,+BA+LjB"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * TaskDetailView — the "inspect process" screen behind a row tap.
3
+ *
4
+ * Shows everything the engine knows about one origin: a 5s activity bar
5
+ * chart (the per-origin bucket ring, rendered nowhere else), the full stat
6
+ * grid (schedules vs runs, avg/max/total, freezes), the captured scheduling
7
+ * site (caller + raw frames), and a plain-language explanation of what this
8
+ * origin type means. Data refreshes with the modal's snapshot tick — the
9
+ * parent re-renders us and we re-pull the detail.
10
+ */
11
+ import type { JsTopOriginDetail } from "../types";
12
+ export declare const TaskDetailView: import("react").NamedExoticComponent<{
13
+ detail: JsTopOriginDetail;
14
+ }>;
15
+ //# sourceMappingURL=TaskDetailView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskDetailView.d.ts","sourceRoot":"","sources":["../../../../src/js-top/components/TaskDetailView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,UAAU,CAAC;AAoD3D,eAAO,MAAM,cAAc;YAGjB,iBAAiB;EA2IzB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The ranked task table — the "process list".
3
+ *
4
+ * Row layout (phone-first): the API is a small colored badge and the FULL
5
+ * width goes to the task name (the part that varies); numbers live on a
6
+ * second stats line instead of fixed-width columns, so nothing truncates:
7
+ *
8
+ * 1 [INTERVAL] hotIntervalWork 1240 ms 41%
9
+ * ▓▓▓▓▓░░░░░ 50 calls · avg 24.8 · max 31.0 · total 1.2k
10
+ *
11
+ * Sorting is a chip row above the list (column headers don't survive on a
12
+ * narrow screen). Rows keyed by origin key (never index: rows re-rank every
13
+ * tick) and memoized with a precise comparator so a tick only re-renders
14
+ * rows whose numbers moved.
15
+ */
16
+ import type { JsTopRow, TaskApi } from "../types";
17
+ export type SortKey = "windowMs" | "calls" | "avgMs" | "maxMs" | "totalMs";
18
+ export declare const API_BADGE: Record<string, {
19
+ text: string;
20
+ color: string;
21
+ prefix?: string;
22
+ }>;
23
+ export declare function badgeFor(api: TaskApi): {
24
+ text: string;
25
+ color: string;
26
+ prefix?: string;
27
+ };
28
+ /** The row label minus its API prefix — the badge already says the API. */
29
+ export declare function displayName(row: {
30
+ api: TaskApi;
31
+ label: string;
32
+ }): string;
33
+ export declare function TaskTable({ rows, onSelectRow, }: {
34
+ rows: JsTopRow[];
35
+ /** Tap-through to the origin detail view. Rows are static when absent. */
36
+ onSelectRow?: (row: JsTopRow) => void;
37
+ }): import("react").JSX.Element;
38
+ //# sourceMappingURL=TaskTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskTable.d.ts","sourceRoot":"","sources":["../../../../src/js-top/components/TaskTable.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAU3E,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B,MAAM,EACN;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAWjD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO;UAb3B,MAAM;WAAS,MAAM;aAAW,MAAM;EAe/C;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQxE;AAgHD,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;CACvC,+BAyCA"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * JsTopController — singleton orchestrating the task-accounting engine.
3
+ *
4
+ * Lifecycle mirrors PerfMonitorController: the engine runs only while
5
+ * someone is looking (snapshot subscribers — the HUD/modal — or a desktop
6
+ * dashboard's silent remote sampling). Patches install once on first start
7
+ * and stay installed; stopping just clears the `active` gate and the probe,
8
+ * so a closed tool costs one boolean per schedule and nothing else.
9
+ */
10
+ import { type JsTopOriginDetail, type JsTopSnapshot, type JsTopStatus, type JsTopTiers } from "../types";
11
+ type SnapshotSubscriber = (snapshot: JsTopSnapshot) => void;
12
+ type EnabledSubscriber = (enabled: boolean) => void;
13
+ type FreezeStatsFn = (now: number) => {
14
+ count: number;
15
+ worstMs: number;
16
+ byOrigin: Record<string, {
17
+ count: number;
18
+ maxMs: number;
19
+ }>;
20
+ };
21
+ declare class JsTopControllerImpl {
22
+ private enabled;
23
+ private enabledLoaded;
24
+ private paused;
25
+ private remoteSampling;
26
+ private engineRunning;
27
+ private tiers;
28
+ private notifyHandle;
29
+ private appStateSub;
30
+ private snapshot;
31
+ private subscribers;
32
+ private enabledSubscribers;
33
+ /** Phase-2 seam: extra tier installers (promises/bridge/longtasks) register
34
+ * here so the controller stays ignorant of their internals. */
35
+ private tierInstallers;
36
+ private longtaskProvider;
37
+ private freezeStatsProvider;
38
+ private clearHooks;
39
+ constructor();
40
+ subscribe(fn: SnapshotSubscriber): () => void;
41
+ subscribeEnabled(fn: EnabledSubscriber): () => void;
42
+ /** HUD visibility toggle (persisted). Not required for the engine to run —
43
+ * the modal or a desktop watcher subscribing is what starts sampling. */
44
+ setEnabled(on: boolean): void;
45
+ isEnabled(): boolean;
46
+ /** Silent sampling for a desktop viewer — engine runs, device HUD stays
47
+ * hidden (same contract as perf-monitor's setRemoteSampling). */
48
+ setRemoteSampling(on: boolean): void;
49
+ isRemoteSampling(): boolean;
50
+ getStatus(): JsTopStatus;
51
+ pause(): void;
52
+ resume(): void;
53
+ clear(): void;
54
+ registerClearHook(fn: () => void): void;
55
+ getSnapshot(): JsTopSnapshot;
56
+ /**
57
+ * Full detail for one origin (tap-through view). Returns null when the
58
+ * origin was evicted or never existed. The pinned "unattributed" row gets
59
+ * a synthetic detail built from the probe residuals.
60
+ */
61
+ getOriginDetail(key: string): JsTopOriginDetail | null;
62
+ /** Phase-2 registration seam for additional patch tiers. */
63
+ registerTierInstaller(install: () => Partial<JsTopTiers>): void;
64
+ registerLongtaskProvider(fn: () => JsTopSnapshot["longtasks"]): void;
65
+ registerFreezeStatsProvider(fn: FreezeStatsFn): void;
66
+ private shouldRun;
67
+ private syncEngineState;
68
+ private runInstaller;
69
+ private startEngine;
70
+ private stopEngine;
71
+ private buildSnapshot;
72
+ private emitSnapshot;
73
+ /** Engine active state, for diagnostics/tests. */
74
+ isEngineActive(): boolean;
75
+ }
76
+ export declare const JsTopController: JsTopControllerImpl;
77
+ export type { JsTopControllerImpl };
78
+ //# sourceMappingURL=JsTopController.d.ts.map