@ogygia/devtools 0.0.0 → 0.11.1

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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -1
  3. package/dist/client.d.ts +3 -0
  4. package/dist/client.js +24 -0
  5. package/dist/devtools/BoundaryOverlay.svelte +396 -0
  6. package/dist/devtools/BoundaryOverlay.svelte.d.ts +19 -0
  7. package/dist/devtools/Devtools.svelte +663 -0
  8. package/dist/devtools/Devtools.svelte.d.ts +15 -0
  9. package/dist/devtools/HubTab.svelte +206 -0
  10. package/dist/devtools/HubTab.svelte.d.ts +11 -0
  11. package/dist/devtools/HydrationTab.svelte +237 -0
  12. package/dist/devtools/HydrationTab.svelte.d.ts +13 -0
  13. package/dist/devtools/IslandDetail.svelte +615 -0
  14. package/dist/devtools/IslandDetail.svelte.d.ts +15 -0
  15. package/dist/devtools/LedgerTab.svelte +287 -0
  16. package/dist/devtools/LedgerTab.svelte.d.ts +11 -0
  17. package/dist/devtools/LensTab.svelte +290 -0
  18. package/dist/devtools/LensTab.svelte.d.ts +19 -0
  19. package/dist/devtools/NavTab.svelte +229 -0
  20. package/dist/devtools/NavTab.svelte.d.ts +11 -0
  21. package/dist/devtools/PageTab.svelte +1122 -0
  22. package/dist/devtools/PageTab.svelte.d.ts +15 -0
  23. package/dist/devtools/ProfilerTab.svelte +755 -0
  24. package/dist/devtools/ProfilerTab.svelte.d.ts +15 -0
  25. package/dist/devtools/PropsTree.svelte +155 -0
  26. package/dist/devtools/PropsTree.svelte.d.ts +15 -0
  27. package/dist/devtools/SessionTab.svelte +796 -0
  28. package/dist/devtools/SessionTab.svelte.d.ts +11 -0
  29. package/dist/devtools/TimelineTab.svelte +267 -0
  30. package/dist/devtools/TimelineTab.svelte.d.ts +11 -0
  31. package/dist/devtools/WireTab.svelte +149 -0
  32. package/dist/devtools/WireTab.svelte.d.ts +11 -0
  33. package/dist/devtools/bytes.d.ts +70 -0
  34. package/dist/devtools/bytes.js +82 -0
  35. package/dist/devtools/cache-headers.d.ts +20 -0
  36. package/dist/devtools/cache-headers.js +81 -0
  37. package/dist/devtools/highlight.d.ts +7 -0
  38. package/dist/devtools/highlight.js +83 -0
  39. package/dist/devtools/hydration.d.ts +48 -0
  40. package/dist/devtools/hydration.js +93 -0
  41. package/dist/devtools/index.d.ts +3 -0
  42. package/dist/devtools/index.js +3 -0
  43. package/dist/devtools/ledger-dom.d.ts +7 -0
  44. package/dist/devtools/ledger-dom.js +151 -0
  45. package/dist/devtools/leftovers.d.ts +77 -0
  46. package/dist/devtools/leftovers.js +319 -0
  47. package/dist/devtools/names.d.ts +1 -0
  48. package/dist/devtools/names.js +34 -0
  49. package/dist/devtools/page.d.ts +96 -0
  50. package/dist/devtools/page.js +957 -0
  51. package/dist/devtools/profile-anchors.d.ts +22 -0
  52. package/dist/devtools/profile-anchors.js +135 -0
  53. package/dist/devtools/profile-store.d.ts +175 -0
  54. package/dist/devtools/profile-store.js +239 -0
  55. package/dist/devtools/regions.d.ts +77 -0
  56. package/dist/devtools/regions.js +132 -0
  57. package/dist/devtools/session.d.ts +31 -0
  58. package/dist/devtools/session.js +455 -0
  59. package/dist/devtools/since-load.d.ts +50 -0
  60. package/dist/devtools/since-load.js +89 -0
  61. package/dist/devtools/source-lines.d.ts +24 -0
  62. package/dist/devtools/source-lines.js +106 -0
  63. package/dist/devtools/styles.d.ts +52 -0
  64. package/dist/devtools/styles.js +248 -0
  65. package/dist/devtools/testing-engine.d.ts +83 -0
  66. package/dist/devtools/testing-engine.js +220 -0
  67. package/dist/devtools/ui-app.d.ts +5 -0
  68. package/dist/devtools/ui-app.js +69 -0
  69. package/dist/devtools/ui.d.ts +50 -0
  70. package/dist/devtools/ui.js +175 -0
  71. package/dist/profiler/alloc.d.ts +75 -0
  72. package/dist/profiler/alloc.js +76 -0
  73. package/dist/profiler/analyze.d.ts +437 -0
  74. package/dist/profiler/analyze.js +1941 -0
  75. package/dist/profiler/app-path.d.ts +7 -0
  76. package/dist/profiler/app-path.js +26 -0
  77. package/dist/profiler/async-io.d.ts +58 -0
  78. package/dist/profiler/async-io.js +187 -0
  79. package/dist/profiler/beacon-standalone.d.ts +4 -0
  80. package/dist/profiler/beacon-standalone.js +409 -0
  81. package/dist/profiler/browser-findings.d.ts +25 -0
  82. package/dist/profiler/browser-findings.js +260 -0
  83. package/dist/profiler/byte-strip.d.ts +58 -0
  84. package/dist/profiler/byte-strip.js +228 -0
  85. package/dist/profiler/client-files.d.ts +16 -0
  86. package/dist/profiler/client-files.js +60 -0
  87. package/dist/profiler/client-windows.d.ts +49 -0
  88. package/dist/profiler/client-windows.js +95 -0
  89. package/dist/profiler/client.d.ts +40 -0
  90. package/dist/profiler/client.js +82 -0
  91. package/dist/profiler/compare.d.ts +308 -0
  92. package/dist/profiler/compare.js +733 -0
  93. package/dist/profiler/compress.d.ts +10 -0
  94. package/dist/profiler/compress.js +36 -0
  95. package/dist/profiler/contention.d.ts +60 -0
  96. package/dist/profiler/contention.js +86 -0
  97. package/dist/profiler/crypto.d.ts +19 -0
  98. package/dist/profiler/crypto.js +101 -0
  99. package/dist/profiler/doc-diff.d.ts +47 -0
  100. package/dist/profiler/doc-diff.js +214 -0
  101. package/dist/profiler/dom-diff.d.ts +43 -0
  102. package/dist/profiler/dom-diff.js +121 -0
  103. package/dist/profiler/drill.d.ts +89 -0
  104. package/dist/profiler/drill.js +553 -0
  105. package/dist/profiler/embedded-maps.d.ts +37 -0
  106. package/dist/profiler/embedded-maps.js +135 -0
  107. package/dist/profiler/env.d.ts +6 -0
  108. package/dist/profiler/env.js +10 -0
  109. package/dist/profiler/forecast.d.ts +76 -0
  110. package/dist/profiler/forecast.js +225 -0
  111. package/dist/profiler/frames.d.ts +11 -0
  112. package/dist/profiler/frames.js +42 -0
  113. package/dist/profiler/gc.d.ts +144 -0
  114. package/dist/profiler/gc.js +271 -0
  115. package/dist/profiler/hole-slots.d.ts +31 -0
  116. package/dist/profiler/hole-slots.js +90 -0
  117. package/dist/profiler/index.d.ts +288 -0
  118. package/dist/profiler/index.js +4921 -0
  119. package/dist/profiler/insights.d.ts +96 -0
  120. package/dist/profiler/insights.js +239 -0
  121. package/dist/profiler/ledger.d.ts +121 -0
  122. package/dist/profiler/ledger.js +440 -0
  123. package/dist/profiler/lineage.d.ts +81 -0
  124. package/dist/profiler/lineage.js +359 -0
  125. package/dist/profiler/module-map.d.ts +12 -0
  126. package/dist/profiler/module-map.js +94 -0
  127. package/dist/profiler/net.d.ts +169 -0
  128. package/dist/profiler/net.js +586 -0
  129. package/dist/profiler/on-demand.d.ts +11 -0
  130. package/dist/profiler/on-demand.js +15 -0
  131. package/dist/profiler/own-requests.d.ts +9 -0
  132. package/dist/profiler/own-requests.js +17 -0
  133. package/dist/profiler/patterns.d.ts +476 -0
  134. package/dist/profiler/patterns.js +2203 -0
  135. package/dist/profiler/profiler-router.d.ts +245 -0
  136. package/dist/profiler/profiler-router.js +113 -0
  137. package/dist/profiler/refresh-stub.d.ts +2 -0
  138. package/dist/profiler/refresh-stub.js +37 -0
  139. package/dist/profiler/report.d.ts +1404 -0
  140. package/dist/profiler/report.js +2638 -0
  141. package/dist/profiler/river.d.ts +65 -0
  142. package/dist/profiler/river.js +298 -0
  143. package/dist/profiler/route-files.d.ts +22 -0
  144. package/dist/profiler/route-files.js +55 -0
  145. package/dist/profiler/route-imports.d.ts +14 -0
  146. package/dist/profiler/route-imports.js +83 -0
  147. package/dist/profiler/saving.d.ts +22 -0
  148. package/dist/profiler/saving.js +42 -0
  149. package/dist/profiler/score.d.ts +109 -0
  150. package/dist/profiler/score.js +261 -0
  151. package/dist/profiler/session-cookie.d.ts +28 -0
  152. package/dist/profiler/session-cookie.js +45 -0
  153. package/dist/profiler/sink.d.ts +81 -0
  154. package/dist/profiler/sink.js +124 -0
  155. package/dist/profiler/site-fixes.d.ts +25 -0
  156. package/dist/profiler/site-fixes.js +62 -0
  157. package/dist/profiler/source-scan.d.ts +210 -0
  158. package/dist/profiler/source-scan.js +1724 -0
  159. package/dist/profiler/span.d.ts +90 -0
  160. package/dist/profiler/span.js +109 -0
  161. package/dist/profiler/stacks.d.ts +43 -0
  162. package/dist/profiler/stacks.js +107 -0
  163. package/dist/profiler/standalone.d.ts +27 -0
  164. package/dist/profiler/standalone.js +98 -0
  165. package/dist/profiler/steps.d.ts +39 -0
  166. package/dist/profiler/steps.js +74 -0
  167. package/dist/profiler/storage/index.d.ts +87 -0
  168. package/dist/profiler/storage/index.js +76 -0
  169. package/dist/profiler/storage/postgres.d.ts +12 -0
  170. package/dist/profiler/storage/postgres.js +94 -0
  171. package/dist/profiler/storage/redis.d.ts +19 -0
  172. package/dist/profiler/storage/redis.js +148 -0
  173. package/dist/profiler/storage/sqlite.d.ts +2 -0
  174. package/dist/profiler/storage/sqlite.js +85 -0
  175. package/dist/profiler/storage/visits.d.ts +4 -0
  176. package/dist/profiler/storage/visits.js +6 -0
  177. package/dist/profiler/stream-tail.d.ts +26 -0
  178. package/dist/profiler/stream-tail.js +74 -0
  179. package/dist/profiler/timeline.d.ts +279 -0
  180. package/dist/profiler/timeline.js +690 -0
  181. package/dist/profiler/ui/AllocStrip.svelte +146 -0
  182. package/dist/profiler/ui/AllocStrip.svelte.d.ts +17 -0
  183. package/dist/profiler/ui/Awaits.svelte +363 -0
  184. package/dist/profiler/ui/Awaits.svelte.d.ts +16 -0
  185. package/dist/profiler/ui/ByteStrip.svelte +182 -0
  186. package/dist/profiler/ui/ByteStrip.svelte.d.ts +18 -0
  187. package/dist/profiler/ui/Compare.svelte +24 -0
  188. package/dist/profiler/ui/Compare.svelte.d.ts +16 -0
  189. package/dist/profiler/ui/CompareBody.svelte +429 -0
  190. package/dist/profiler/ui/CompareBody.svelte.d.ts +8 -0
  191. package/dist/profiler/ui/ComponentsTable.svelte +265 -0
  192. package/dist/profiler/ui/ComponentsTable.svelte.d.ts +20 -0
  193. package/dist/profiler/ui/Dashboard.svelte +492 -0
  194. package/dist/profiler/ui/Dashboard.svelte.d.ts +31 -0
  195. package/dist/profiler/ui/DataRiver.svelte +206 -0
  196. package/dist/profiler/ui/DataRiver.svelte.d.ts +13 -0
  197. package/dist/profiler/ui/DomTravel.svelte +207 -0
  198. package/dist/profiler/ui/DomTravel.svelte.d.ts +9 -0
  199. package/dist/profiler/ui/DownloadHtml.svelte +52 -0
  200. package/dist/profiler/ui/DownloadHtml.svelte.d.ts +10 -0
  201. package/dist/profiler/ui/Drill.svelte +276 -0
  202. package/dist/profiler/ui/Drill.svelte.d.ts +12 -0
  203. package/dist/profiler/ui/ExportButton.svelte +59 -0
  204. package/dist/profiler/ui/ExportButton.svelte.d.ts +8 -0
  205. package/dist/profiler/ui/Flame.svelte +222 -0
  206. package/dist/profiler/ui/Flame.svelte.d.ts +12 -0
  207. package/dist/profiler/ui/FrameDetails.svelte +308 -0
  208. package/dist/profiler/ui/FrameDetails.svelte.d.ts +16 -0
  209. package/dist/profiler/ui/FunctionsTable.svelte +156 -0
  210. package/dist/profiler/ui/FunctionsTable.svelte.d.ts +17 -0
  211. package/dist/profiler/ui/IslandHeatmap.svelte +151 -0
  212. package/dist/profiler/ui/IslandHeatmap.svelte.d.ts +16 -0
  213. package/dist/profiler/ui/IslandsTable.svelte +448 -0
  214. package/dist/profiler/ui/IslandsTable.svelte.d.ts +16 -0
  215. package/dist/profiler/ui/KeepLocal.svelte +46 -0
  216. package/dist/profiler/ui/KeepLocal.svelte.d.ts +8 -0
  217. package/dist/profiler/ui/Ledger.svelte +196 -0
  218. package/dist/profiler/ui/Ledger.svelte.d.ts +18 -0
  219. package/dist/profiler/ui/LocalCompare.svelte +48 -0
  220. package/dist/profiler/ui/LocalCompare.svelte.d.ts +8 -0
  221. package/dist/profiler/ui/LocalReports.svelte +68 -0
  222. package/dist/profiler/ui/LocalReports.svelte.d.ts +7 -0
  223. package/dist/profiler/ui/Login.svelte +13 -0
  224. package/dist/profiler/ui/Login.svelte.d.ts +12 -0
  225. package/dist/profiler/ui/LoginForm.svelte +42 -0
  226. package/dist/profiler/ui/LoginForm.svelte.d.ts +7 -0
  227. package/dist/profiler/ui/Message.svelte +10 -0
  228. package/dist/profiler/ui/Message.svelte.d.ts +12 -0
  229. package/dist/profiler/ui/OnThisPage.svelte +137 -0
  230. package/dist/profiler/ui/OnThisPage.svelte.d.ts +3 -0
  231. package/dist/profiler/ui/OneClock.svelte +297 -0
  232. package/dist/profiler/ui/OneClock.svelte.d.ts +27 -0
  233. package/dist/profiler/ui/Panel.svelte +10 -0
  234. package/dist/profiler/ui/Panel.svelte.d.ts +16 -0
  235. package/dist/profiler/ui/Paths.svelte +269 -0
  236. package/dist/profiler/ui/Paths.svelte.d.ts +15 -0
  237. package/dist/profiler/ui/Patterns.svelte +364 -0
  238. package/dist/profiler/ui/Patterns.svelte.d.ts +15 -0
  239. package/dist/profiler/ui/PermalinkGate.svelte +143 -0
  240. package/dist/profiler/ui/PermalinkGate.svelte.d.ts +10 -0
  241. package/dist/profiler/ui/RenderSteps.svelte +218 -0
  242. package/dist/profiler/ui/RenderSteps.svelte.d.ts +13 -0
  243. package/dist/profiler/ui/Report.svelte +28 -0
  244. package/dist/profiler/ui/Report.svelte.d.ts +20 -0
  245. package/dist/profiler/ui/ReportBody.svelte +2592 -0
  246. package/dist/profiler/ui/ReportBody.svelte.d.ts +21 -0
  247. package/dist/profiler/ui/Run.svelte +17 -0
  248. package/dist/profiler/ui/Run.svelte.d.ts +14 -0
  249. package/dist/profiler/ui/RunView.svelte +146 -0
  250. package/dist/profiler/ui/RunView.svelte.d.ts +10 -0
  251. package/dist/profiler/ui/ScoreCard.svelte +197 -0
  252. package/dist/profiler/ui/ScoreCard.svelte.d.ts +7 -0
  253. package/dist/profiler/ui/Scrub.svelte +293 -0
  254. package/dist/profiler/ui/Scrub.svelte.d.ts +18 -0
  255. package/dist/profiler/ui/SeedExplainer.svelte +193 -0
  256. package/dist/profiler/ui/SeedExplainer.svelte.d.ts +16 -0
  257. package/dist/profiler/ui/ShareLink.svelte +148 -0
  258. package/dist/profiler/ui/ShareLink.svelte.d.ts +8 -0
  259. package/dist/profiler/ui/Shell.svelte +50 -0
  260. package/dist/profiler/ui/Shell.svelte.d.ts +27 -0
  261. package/dist/profiler/ui/Sidebar.svelte +312 -0
  262. package/dist/profiler/ui/Sidebar.svelte.d.ts +7 -0
  263. package/dist/profiler/ui/Site.svelte +20 -0
  264. package/dist/profiler/ui/Site.svelte.d.ts +23 -0
  265. package/dist/profiler/ui/SiteView.svelte +385 -0
  266. package/dist/profiler/ui/SiteView.svelte.d.ts +27 -0
  267. package/dist/profiler/ui/ThemeSwitch.svelte +78 -0
  268. package/dist/profiler/ui/ThemeSwitch.svelte.d.ts +3 -0
  269. package/dist/profiler/ui/Timeline.svelte +672 -0
  270. package/dist/profiler/ui/Timeline.svelte.d.ts +22 -0
  271. package/dist/profiler/ui/Treemap.svelte +278 -0
  272. package/dist/profiler/ui/Treemap.svelte.d.ts +20 -0
  273. package/dist/profiler/ui/Upload.svelte +19 -0
  274. package/dist/profiler/ui/Upload.svelte.d.ts +10 -0
  275. package/dist/profiler/ui/UploadForm.svelte +59 -0
  276. package/dist/profiler/ui/UploadForm.svelte.d.ts +6 -0
  277. package/dist/profiler/ui/WaitingTable.svelte +55 -0
  278. package/dist/profiler/ui/WaitingTable.svelte.d.ts +14 -0
  279. package/dist/profiler/ui/Waterfall.svelte +371 -0
  280. package/dist/profiler/ui/Waterfall.svelte.d.ts +7 -0
  281. package/dist/profiler/ui/WhatIf.svelte +87 -0
  282. package/dist/profiler/ui/WhatIf.svelte.d.ts +18 -0
  283. package/dist/profiler/ui/fake-progress.svelte.d.ts +15 -0
  284. package/dist/profiler/ui/fake-progress.svelte.js +38 -0
  285. package/dist/profiler/ui/format.d.ts +20 -0
  286. package/dist/profiler/ui/format.js +71 -0
  287. package/dist/profiler/ui/permalink.d.ts +9 -0
  288. package/dist/profiler/ui/permalink.js +108 -0
  289. package/dist/profiler/ui/press.d.ts +5 -0
  290. package/dist/profiler/ui/press.js +19 -0
  291. package/dist/profiler/ui/profiler.css +650 -0
  292. package/dist/profiler/ui/report-data.d.ts +189 -0
  293. package/dist/profiler/ui/report-data.js +393 -0
  294. package/dist/profiler/ui/report-request.d.ts +6 -0
  295. package/dist/profiler/ui/report-request.js +50 -0
  296. package/dist/profiler/ui/row-anchor.svelte.d.ts +12 -0
  297. package/dist/profiler/ui/row-anchor.svelte.js +44 -0
  298. package/dist/profiler/ui/sort.svelte.d.ts +14 -0
  299. package/dist/profiler/ui/sort.svelte.js +37 -0
  300. package/dist/profiler/ui/store.d.ts +45 -0
  301. package/dist/profiler/ui/store.js +92 -0
  302. package/dist/profiler/visit.d.ts +389 -0
  303. package/dist/profiler/visit.js +1002 -0
  304. package/dist/report.d.ts +5 -0
  305. package/dist/report.js +4 -0
  306. package/dist/server.d.ts +11 -0
  307. package/dist/server.js +38 -0
  308. package/dist/vite.d.ts +12 -0
  309. package/dist/vite.js +78 -0
  310. package/package.json +99 -6
@@ -0,0 +1,359 @@
1
+ // src/profiler/lineage.ts
2
+ /**
3
+ * DATA LINEAGE FROM THE CODE — which `page.data` keys each component actually reads, joined to
4
+ * the loads that produced them and the seed that shipped them. The river (river.ts) draws the
5
+ * flow with the islands' keys from the build; this reads the SERVER components' sources too, so
6
+ * every key gets a verdict: read by an island (must ship), read on the server only (rendered
7
+ * into HTML, need not ship), read by nobody (fetched for nothing — the load's wait behind it is
8
+ * pure waste), or unknown (a component's reads could not be told).
9
+ *
10
+ * The scanner is a character walk, no regex: `data.key`, `data['key']`, `page.data.key`,
11
+ * `$page.data.key`, and the destructurings `const { a, b: c } = data` / `= page.data`.
12
+ */
13
+ const is_ident_start = (c) => c >= 97 && c <= 122 || c >= 65 && c <= 90 || c === 95 || c === 36;
14
+ const is_ident = (c) => is_ident_start(c) || c >= 48 && c <= 57;
15
+ const is_space = (c) => c === 32 || c === 9 || c === 10 || c === 13;
16
+ /** the identifier ending right before `end` (exclusive), or '' */
17
+ function ident_before(src, end) {
18
+ let i = end;
19
+ while (i > 0 && is_ident(src.charCodeAt(i - 1))) i--;
20
+ return src.slice(i, end);
21
+ }
22
+ /** the identifier starting at `i`, or '' */
23
+ function ident_at(src, i) {
24
+ if (i >= src.length || !is_ident_start(src.charCodeAt(i))) return "";
25
+ let j = i + 1;
26
+ while (j < src.length && is_ident(src.charCodeAt(j))) j++;
27
+ return src.slice(i, j);
28
+ }
29
+ /** the keys of a destructuring pattern `{ a, b: c, d = 1, ...rest }` given the index of its `{` */
30
+ function pattern_keys(src, open, out) {
31
+ let depth = 0;
32
+ let i = open;
33
+ let key_start = -1;
34
+ let took = false;
35
+ for (; i < src.length; i++) {
36
+ const c = src.charCodeAt(i);
37
+ if (c === 123 || c === 91 || c === 40) {
38
+ depth++;
39
+ if (depth === 1) {
40
+ key_start = -1;
41
+ took = false;
42
+ }
43
+ continue;
44
+ }
45
+ if (c === 125 || c === 93 || c === 41) {
46
+ depth--;
47
+ if (depth === 0) {
48
+ if (key_start >= 0 && !took) out.add(src.slice(key_start, i).trim());
49
+ return;
50
+ }
51
+ continue;
52
+ }
53
+ if (depth !== 1) continue;
54
+ if (c === 44) {
55
+ if (key_start >= 0 && !took) out.add(src.slice(key_start, i).trim());
56
+ key_start = -1;
57
+ took = false;
58
+ continue;
59
+ }
60
+ if (c === 58 || c === 61) {
61
+ if (key_start >= 0 && !took) out.add(src.slice(key_start, i).trim());
62
+ took = true;
63
+ continue;
64
+ }
65
+ if (key_start < 0 && !took && is_ident_start(c)) {
66
+ if (src.charCodeAt(i - 1) === 46) {
67
+ took = true;
68
+ continue;
69
+ }
70
+ key_start = i;
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * The `page.data` keys a component source reads, or `null` when it takes the whole object in a
76
+ * way that cannot be named (`...data`, `data` passed on, `Object.keys(data)`). `names` are the
77
+ * identifiers that hold the data (`data` by default; `page.data` / `$page.data` always count).
78
+ */
79
+ function data_reads(source, names = ["data"]) {
80
+ const src = blank_comments(source);
81
+ const keys = /* @__PURE__ */ new Set();
82
+ let whole = false;
83
+ const seen = /* @__PURE__ */ new Set();
84
+ for (const name of ["data", ...names]) {
85
+ if (seen.has(name)) continue;
86
+ seen.add(name);
87
+ if (scan(src, name, names.includes(name), keys)) whole = true;
88
+ }
89
+ if (whole && !keys.size) return null;
90
+ if (whole) return [...keys, "*"];
91
+ return [...keys];
92
+ }
93
+ /** The 1-based line of the first place the source takes the data WHOLE (`const d = $page.data`,
94
+ * `fn(data)`, `...data`), or null when it only reads named keys. Same scan as `data_reads`. */
95
+ function whole_read_line(source, names = ["data"]) {
96
+ const src = blank_comments(source);
97
+ const at = { pos: -1 };
98
+ const seen = /* @__PURE__ */ new Set();
99
+ for (const name of ["data", ...names]) {
100
+ if (seen.has(name)) continue;
101
+ seen.add(name);
102
+ scan(src, name, names.includes(name), /* @__PURE__ */ new Set(), at);
103
+ if (at.pos >= 0) break;
104
+ }
105
+ if (at.pos < 0) return null;
106
+ let line = 1;
107
+ for (let i = source.indexOf("\n"); i !== -1 && i < at.pos; i = source.indexOf("\n", i + 1)) line++;
108
+ return line;
109
+ }
110
+ /** The source with its comments (`//`, block, HTML) and string contents blanked to spaces, so
111
+ * a word in prose or a URL never reads as code; positions are kept. A character walk. */
112
+ function blank_comments(src) {
113
+ const out = src.split("");
114
+ const n = src.length;
115
+ let i = 0;
116
+ const blank = (from, to) => {
117
+ for (let k = from; k < to && k < n; k++) if (out[k] !== "\n") out[k] = " ";
118
+ };
119
+ while (i < n) {
120
+ const c = src.charCodeAt(i);
121
+ const next = src.charCodeAt(i + 1);
122
+ if (c === 47 && next === 47) {
123
+ let e = src.indexOf("\n", i);
124
+ if (e === -1) e = n;
125
+ blank(i, e);
126
+ i = e;
127
+ continue;
128
+ }
129
+ if (c === 47 && next === 42) {
130
+ let e = src.indexOf("*/", i + 2);
131
+ e = e === -1 ? n : e + 2;
132
+ blank(i, e);
133
+ i = e;
134
+ continue;
135
+ }
136
+ if (c === 60 && src.startsWith("<!--", i)) {
137
+ let e = src.indexOf("-->", i + 4);
138
+ e = e === -1 ? n : e + 3;
139
+ blank(i, e);
140
+ i = e;
141
+ continue;
142
+ }
143
+ if (c === 39 || c === 34 || c === 96) {
144
+ let e = i + 1;
145
+ while (e < n) {
146
+ const d = src.charCodeAt(e);
147
+ if (d === 92) {
148
+ e += 2;
149
+ continue;
150
+ }
151
+ if (d === c) break;
152
+ if (c === 96 && d === 36 && src.charCodeAt(e + 1) === 123) {
153
+ let depth = 1;
154
+ let k = e + 2;
155
+ while (k < n && depth) {
156
+ const q = src.charCodeAt(k);
157
+ if (q === 123) depth++;
158
+ else if (q === 125) depth--;
159
+ k++;
160
+ }
161
+ e = k;
162
+ continue;
163
+ }
164
+ if (c !== 96 && d === 10) break;
165
+ e++;
166
+ }
167
+ const inner = src.slice(i + 1, e);
168
+ if (inner.includes(" ") || inner.length > 40) blank(i + 1, e);
169
+ i = e + 1;
170
+ continue;
171
+ }
172
+ i++;
173
+ }
174
+ return out.join("");
175
+ }
176
+ /** one name's occurrences; returns true when the object was used whole somewhere */
177
+ function scan(src, name, bare_ok, keys, whole_at) {
178
+ let whole = false;
179
+ const mark = (pos) => {
180
+ if (whole_at && whole_at.pos < 0) whole_at.pos = pos;
181
+ };
182
+ const n = src.length;
183
+ const len = name.length;
184
+ let i = 0;
185
+ while (i < n) {
186
+ const j = src.indexOf(name, i);
187
+ if (j === -1) break;
188
+ i = j + len;
189
+ if (j > 0 && is_ident(src.charCodeAt(j - 1))) continue;
190
+ if (i < n && is_ident(src.charCodeAt(i))) continue;
191
+ if (j >= 3 && src.charCodeAt(j - 1) === 46 && src.charCodeAt(j - 2) === 46 && src.charCodeAt(j - 3) === 46) {
192
+ if (bare_ok) {
193
+ whole = true;
194
+ mark(j);
195
+ }
196
+ continue;
197
+ }
198
+ let owner = "";
199
+ if (j > 0 && src.charCodeAt(j - 1) === 46) {
200
+ owner = ident_before(src, j - 1);
201
+ if (name !== "data" || owner !== "page" && owner !== "$page") continue;
202
+ } else if (!bare_ok) continue;
203
+ let k = i;
204
+ while (k < n && is_space(src.charCodeAt(k))) k++;
205
+ const c = src.charCodeAt(k);
206
+ if (c === 46) {
207
+ const key = ident_at(src, k + 1);
208
+ if (key) keys.add(key);
209
+ continue;
210
+ }
211
+ if (c === 91) {
212
+ let q = k + 1;
213
+ while (q < n && is_space(src.charCodeAt(q))) q++;
214
+ const quote = src.charCodeAt(q);
215
+ if (quote === 39 || quote === 34 || quote === 96) {
216
+ const close = src.indexOf(src[q], q + 1);
217
+ if (close > q) keys.add(src.slice(q + 1, close));
218
+ } else {
219
+ whole = true;
220
+ mark(j);
221
+ }
222
+ continue;
223
+ }
224
+ let b = j - 1;
225
+ if (owner) b -= owner.length + 1;
226
+ while (b >= 0 && is_space(src.charCodeAt(b))) b--;
227
+ if (b >= 0 && src.charCodeAt(b) === 61) {
228
+ let e = b - 1;
229
+ while (e >= 0 && is_space(src.charCodeAt(e))) e--;
230
+ if (e >= 0 && src.charCodeAt(e) === 125) {
231
+ let depth = 0;
232
+ let o = e;
233
+ for (; o >= 0; o--) {
234
+ const cc = src.charCodeAt(o);
235
+ if (cc === 125) depth++;
236
+ else if (cc === 123 && --depth === 0) break;
237
+ }
238
+ if (o >= 0) {
239
+ pattern_keys(src, o, keys);
240
+ continue;
241
+ }
242
+ }
243
+ if (c === 59 || c === 10 || k >= n) {
244
+ whole = true;
245
+ mark(j);
246
+ continue;
247
+ }
248
+ }
249
+ if (c === 41 || c === 93 || c === 63 || c === 124 || c === 38) {
250
+ whole = true;
251
+ mark(j);
252
+ continue;
253
+ }
254
+ }
255
+ return whole;
256
+ }
257
+ /** the `let { data } = $props()` / `export let data` names a component gives its data prop —
258
+ * plus any rename (`let { data: page_data } = $props()`) */
259
+ function data_prop_names(src) {
260
+ const names = /* @__PURE__ */ new Set(["data"]);
261
+ const at = src.indexOf("$props()");
262
+ if (at !== -1) {
263
+ let e = at - 1;
264
+ while (e >= 0 && is_space(src.charCodeAt(e))) e--;
265
+ if (e >= 0 && src.charCodeAt(e) === 61) {
266
+ e--;
267
+ while (e >= 0 && is_space(src.charCodeAt(e))) e--;
268
+ if (e >= 0 && src.charCodeAt(e) === 125) {
269
+ let depth = 0;
270
+ let o = e;
271
+ for (; o >= 0; o--) {
272
+ const cc = src.charCodeAt(o);
273
+ if (cc === 125) depth++;
274
+ else if (cc === 123 && --depth === 0) break;
275
+ }
276
+ if (o >= 0) {
277
+ const body = src.slice(o, e + 1);
278
+ const d = body.indexOf("data");
279
+ if (d !== -1) {
280
+ let q = d + 4;
281
+ while (q < body.length && is_space(body.charCodeAt(q))) q++;
282
+ if (body.charCodeAt(q) === 58) {
283
+ q++;
284
+ while (q < body.length && is_space(body.charCodeAt(q))) q++;
285
+ const alias = ident_at(body, q);
286
+ if (alias) names.add(alias);
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+ }
293
+ return [...names];
294
+ }
295
+ function build_lineage(input) {
296
+ const notes = [];
297
+ const components = input.components.map((c) => {
298
+ const whole = c.reads?.includes("*") ?? false;
299
+ return {
300
+ name: c.name,
301
+ file: c.file,
302
+ island: c.island,
303
+ reads: c.reads ? c.reads.filter((k) => k !== "*") : null,
304
+ whole,
305
+ ...whole && c.whole_line ? { whole_line: c.whole_line } : {}
306
+ };
307
+ });
308
+ const from = /* @__PURE__ */ new Map();
309
+ const wait = /* @__PURE__ */ new Map();
310
+ let any_lane = false;
311
+ for (const l of input.lanes) {
312
+ if (!l.keys) continue;
313
+ any_lane = true;
314
+ for (const k of l.keys) {
315
+ if (!from.has(k)) from.set(k, l.file);
316
+ if (l.wait_ms !== void 0) wait.set(k, l.wait_ms);
317
+ }
318
+ }
319
+ const keys = /* @__PURE__ */ new Set([...from.keys(), ...Object.keys(input.seed)]);
320
+ for (const c of components) for (const k of c.reads ?? []) keys.add(k);
321
+ if (!keys.size) return void 0;
322
+ const blind = components.filter((c) => c.reads === null);
323
+ const whole_readers = components.filter((c) => c.whole);
324
+ if (blind.length) notes.push(`${blind.length} component${blind.length > 1 ? "s" : ""} read the data in a way the scan could not name (${blind.map((c) => c.name).slice(0, 3).join(", ")}${blind.length > 3 ? "…" : ""}): their keys are unknown, so no key is called unread.`);
325
+ if (whole_readers.length) notes.push(`${whole_readers.map((c) => c.name).slice(0, 3).join(", ")} take${whole_readers.length > 1 ? "" : "s"} the whole data object: every key may be read there.`);
326
+ if (!any_lane) notes.push("No load returned keys the profiler could read from its source: the keys come from the seed and the readers alone.");
327
+ const rows = [];
328
+ for (const key of keys) {
329
+ const named = components.filter((c) => c.reads?.includes(key));
330
+ const readers = [...named, ...whole_readers.filter((w) => !named.includes(w))].map((c) => ({
331
+ name: c.name,
332
+ island: c.island
333
+ }));
334
+ const shipped = input.seed[key] ?? 0;
335
+ let verdict;
336
+ if (named.some((c) => c.island)) verdict = "island";
337
+ else if (whole_readers.some((w) => w.island)) verdict = "unknown";
338
+ else if (named.length) verdict = shipped > 0 ? "server-only" : "server";
339
+ else if (blind.length || whole_readers.length) verdict = "unknown";
340
+ else verdict = "unread";
341
+ rows.push({
342
+ key,
343
+ from: from.get(key) ?? null,
344
+ shipped_bytes: shipped,
345
+ readers,
346
+ verdict,
347
+ load_wait_ms: wait.get(key) ?? null
348
+ });
349
+ }
350
+ rows.sort((a, b) => b.shipped_bytes - a.shipped_bytes || (b.load_wait_ms ?? 0) - (a.load_wait_ms ?? 0));
351
+ return {
352
+ keys: rows,
353
+ components,
354
+ unread: rows.filter((r) => r.verdict === "unread").sort((a, b) => (b.load_wait_ms ?? 0) - (a.load_wait_ms ?? 0)),
355
+ server_only: rows.filter((r) => r.verdict === "server-only").sort((a, b) => b.shipped_bytes - a.shipped_bytes),
356
+ notes
357
+ };
358
+ }
359
+ export { blank_comments, build_lineage, data_prop_names, data_reads, whole_read_line };
@@ -0,0 +1,12 @@
1
+ import { FrameCategory } from "./analyze.js";
2
+ /** `(url, line) → module id` over the module maps found beside the chunks (memoized per folder) */
3
+ export declare function module_lookup(): (url: string, line: number) => string | undefined;
4
+ /** a script that MAY be a built server chunk: JavaScript outside node_modules and Node's own — an
5
+ * absolute build path, or the RELATIVE name a Lambda / Amplify host hands V8 (`./chunks/x.js`). The
6
+ * module map beside it has the last word (no map, no entry: not a chunk) */
7
+ export declare const may_be_chunk: (file: string) => boolean;
8
+ /** a module id's kind: this profiler's code, ogygia's runtime, a package, or (undefined) the app's */
9
+ export declare function module_category(id: string): {
10
+ category: FrameCategory;
11
+ pkg?: string;
12
+ } | undefined;
@@ -0,0 +1,94 @@
1
+ import { embedded_module_at } from "./embedded-maps.js";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ // src/profiler/module-map.ts
6
+ /**
7
+ * THE MODULE MAP, read (the build writes it: vite/module-map.ts). A frame in a bundled server chunk
8
+ * (`…/output/server/chunks/frames.js:12`) with no sourcemap names only the chunk; the map says which
9
+ * source module is at that line, so the frame is filed by what it is — this profiler's own code
10
+ * (overhead, not the app's time), ogygia's runtime or a bundled package (a library), else the app.
11
+ * The map sits beside the chunks, found by walking up from the chunk's folder, wherever the host put
12
+ * the build.
13
+ */
14
+ const MODULE_MAP_FILE = "ogygia-modules.json";
15
+ /** `(url, line) → module id` over the module maps found beside the chunks (memoized per folder) */
16
+ function module_lookup() {
17
+ const by_dir = /* @__PURE__ */ new Map();
18
+ const find = (start) => {
19
+ const seen = [];
20
+ let dir = start;
21
+ let found = null;
22
+ for (let i = 0; i < 6; i++) {
23
+ if (by_dir.has(dir)) {
24
+ found = by_dir.get(dir);
25
+ break;
26
+ }
27
+ seen.push(dir);
28
+ const file = path.join(dir, MODULE_MAP_FILE);
29
+ if (fs.existsSync(file)) {
30
+ try {
31
+ found = {
32
+ dir,
33
+ chunks: JSON.parse(fs.readFileSync(file, "utf8")).chunks
34
+ };
35
+ } catch {
36
+ found = null;
37
+ }
38
+ break;
39
+ }
40
+ const up = path.dirname(dir);
41
+ if (up === dir) break;
42
+ dir = up;
43
+ }
44
+ for (const d of seen) by_dir.set(d, found);
45
+ return found;
46
+ };
47
+ return (url, line) => {
48
+ let file = url;
49
+ if (file.startsWith("file://")) try {
50
+ file = fileURLToPath(file);
51
+ } catch {
52
+ return;
53
+ }
54
+ if (!path.isAbsolute(file)) file = path.resolve(process.cwd(), file);
55
+ const m = find(path.dirname(file));
56
+ if (!m) return embedded_module_at(file, line);
57
+ const ranges = m.chunks[path.relative(m.dir, file).split(path.sep).join("/")];
58
+ if (!ranges) return embedded_module_at(file, line);
59
+ for (const [a, b, id] of ranges) if (line >= a && line <= b) return id;
60
+ };
61
+ }
62
+ /** a script that MAY be a built server chunk: JavaScript outside node_modules and Node's own — an
63
+ * absolute build path, or the RELATIVE name a Lambda / Amplify host hands V8 (`./chunks/x.js`). The
64
+ * module map beside it has the last word (no map, no entry: not a chunk) */
65
+ const may_be_chunk = (file) => !!file && !file.startsWith("node:") && !file.includes("/node_modules/") && !file.includes("\\node_modules\\") && (file.endsWith(".js") || file.endsWith(".mjs") || file.endsWith(".cjs"));
66
+ /** a module id's kind: this profiler's code, ogygia's runtime, a package, or (undefined) the app's */
67
+ function module_category(id) {
68
+ const posix = id.split("\\").join("/");
69
+ if (posix.includes("virtual:ogygia")) return {
70
+ category: "dependency",
71
+ pkg: "ogygia"
72
+ };
73
+ const nm = posix.lastIndexOf("node_modules/");
74
+ const own = (p) => p.includes("ogygia/src/") || p.includes("ogygia/dist/") || p.includes("/packages/core/src/") || p.includes("/packages/core/dist/") || p.includes("/devtools/src/profiler/") || p.includes("/devtools/dist/profiler/");
75
+ if (nm !== -1) {
76
+ const rest = posix.slice(nm + 13).split("/");
77
+ const folder = rest[0].startsWith("@") ? `${rest[0]}/${rest[1]}` : rest[0];
78
+ const pkg = folder === "@ogygia/core" ? "ogygia" : folder;
79
+ if ((pkg === "ogygia" || pkg === "@ogygia/devtools") && rest.includes("profiler")) return { category: "profiler" };
80
+ if (pkg === "svelte") return {
81
+ category: "svelte",
82
+ pkg
83
+ };
84
+ return {
85
+ category: "dependency",
86
+ pkg
87
+ };
88
+ }
89
+ if (own(posix)) return posix.includes("/profiler/") ? { category: "profiler" } : {
90
+ category: "dependency",
91
+ pkg: "ogygia"
92
+ };
93
+ }
94
+ export { may_be_chunk, module_category, module_lookup };
@@ -0,0 +1,169 @@
1
+ import { register_profiler_file } from "./frames.js";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+ export interface NetCall {
4
+ /** performance.now() at call start */
5
+ start: number;
6
+ /** Date.now() at call start (for window filtering) */
7
+ epoch: number;
8
+ /** ms until headers arrived; -1 while pending */
9
+ ms: number;
10
+ /** additional ms spent reading the body (json()/text()/stream end) */
11
+ body_ms?: number;
12
+ method: string;
13
+ url: string;
14
+ host: string;
15
+ /** 0 = errored before a response */
16
+ status: number;
17
+ /** DECODED response body size (what the app receives) — measured by counting a cloned body stream,
18
+ * so it's captured however the app reads (json/text/stream) and even when there's no content-length. */
19
+ bytes?: number;
20
+ /** wire/transfer size from `content-length` (compressed when `encoding` is set) */
21
+ transfer_bytes?: number;
22
+ /** a fingerprint of the decoded body (`<fnv1a>:<length>`): identical across renders = the same
23
+ * answer every time, one to cache across requests */
24
+ body_hash?: string;
25
+ /** the request carried a cookie or an authorization header: its answer may be per user */
26
+ personal?: boolean;
27
+ /** response `content-encoding` (gzip / br / …) when compressed */
28
+ encoding?: string;
29
+ /** short response `content-type` (params stripped) */
30
+ type?: string;
31
+ /** response headers (curated + capped) — shown in the request side panel */
32
+ headers?: Record<string, string>;
33
+ /** request body size in bytes, when it has one */
34
+ req_bytes?: number;
35
+ /** request body preview (truncated) — for string / form / URLSearchParams bodies */
36
+ req_payload?: string;
37
+ kind: "fetch" | "http";
38
+ /** route of the page render that made this call, when known */
39
+ route: string | null;
40
+ /** path of the page render that made this call, when known */
41
+ path: string | null;
42
+ /** resolved caller string, filled in at report time from caller_site */
43
+ caller?: string;
44
+ /** raw caller location (bundled), resolved to source at report time */
45
+ caller_site?: CallerSite;
46
+ /** the first-party call path above the caller (nearest first), raw; resolved into `callers` */
47
+ caller_chain?: CallerSite[];
48
+ /** the resolved call path: `fetchStock (lib/stock.ts:9)` ← `load (routes/+page.server.ts:44)` */
49
+ callers?: string[];
50
+ /** the caller's source position (the first app frame), for reading the call site's code */
51
+ caller_at?: {
52
+ path: string;
53
+ line: number;
54
+ };
55
+ /** the next app frame out (who called the caller): a helper's call site in its caller */
56
+ outer_at?: {
57
+ path: string;
58
+ line: number;
59
+ };
60
+ /** the upstream's own `Server-Timing` entries: what THEIR side spent the wait on */
61
+ timings?: ServerTiming[];
62
+ /** the upstream's own profiler's picture of this request (nested trace), when it answered */
63
+ trace?: UpstreamTrace;
64
+ error?: string;
65
+ }
66
+ /** One `Server-Timing` entry from an upstream response (`db;dur=180;desc="postgres"`). */
67
+ export interface ServerTiming {
68
+ name: string;
69
+ /** `dur`, ms; 0 when the entry carries none */
70
+ ms: number;
71
+ desc?: string;
72
+ }
73
+ export declare function parse_server_timing(header: string | null | undefined): ServerTiming[] | undefined;
74
+ export declare function set_stack_capture(on: boolean): void;
75
+ /** A caller location as the bundler sees it — resolved to source later, at
76
+ * report time, through the sourcemap resolver (we have no maps here). */
77
+ export interface CallerSite {
78
+ fn: string;
79
+ /** generated (bundled) file */
80
+ file: string;
81
+ /** 1-based line in the generated file */
82
+ line: number;
83
+ /** 1-based column in the generated file */
84
+ column: number;
85
+ }
86
+ /** The nearest first-party frame that issued an I/O call — skips node internals,
87
+ * node_modules, and the profiler's own frames, so the caller reads like your
88
+ * code. Shared by the network patch and the async_hooks I/O tracker. */
89
+ export declare function nearest_app_site(): CallerSite | undefined;
90
+ /** The first-party CALL PATH above an I/O call — the nearest app frame and the ones that called it
91
+ * (`fetchStock` ← `load`), skipping the same internals as `nearest_app_site`. Read off the one
92
+ * stack that call already captured, so it costs nothing extra beyond a few more frames. */
93
+ export declare function app_call_chain(limit?: number): CallerSite[];
94
+ /** Best-effort caller string with no sourcemap (fallback before resolution). */
95
+ export declare function nearest_app_frame(): string | undefined;
96
+ export interface NetContext {
97
+ route: string | null;
98
+ path: string | null;
99
+ on_net(call: NetCall): void;
100
+ /** the profiler's what-if render: an answer kept from the timed renders, for a call this request
101
+ * makes (`GET <url>`), instead of making it — undefined = make the call */
102
+ answer?(method: string, url: string): Response | undefined;
103
+ }
104
+ type Emit = (call: NetCall) => void;
105
+ /** start (clearing what was kept) or stop keeping answers */
106
+ export declare function keep_answers(on: boolean): void;
107
+ /** drop every kept answer */
108
+ export declare function drop_answers(): void;
109
+ /**
110
+ * WHAT CHANGED IN AN ANSWER between the first render and the last: the one stretch that differs
111
+ * (the bytes before it and after it are the same), and that stretch as text with a little around
112
+ * it — a timestamp, a request id. Undefined when either answer was not kept, or they are the same.
113
+ */
114
+ export declare function answer_diff(key: string): {
115
+ bytes: number;
116
+ size: number;
117
+ text: string;
118
+ } | undefined;
119
+ /** a kept answer as a fresh Response, or undefined */
120
+ export declare function kept_answer(key: string): Response | undefined;
121
+ /**
122
+ * Install the patches. `fallback` receives calls made outside any request
123
+ * context (startup work, background jobs) so window recordings still see them.
124
+ * Idempotent: a second call just re-asserts the fetch patch (see `ensure_fetch_patched`).
125
+ */
126
+ export declare function install_net_capture(als: AsyncLocalStorage<NetContext>, fallback: Emit): Promise<void>;
127
+ /**
128
+ * Re-assert the `globalThis.fetch` patch. `globalThis.fetch` can be REPLACED out from under us after
129
+ * install — a late undici init, a framework fetch polyfill, an HMR reload of this module — which
130
+ * silently kills capture, so reports "sometimes catch network, sometimes don't". Call this before every
131
+ * profile: if the live fetch isn't ours (identified by the brand symbol, so we never wrap our own
132
+ * wrapper) re-wrap whatever is there now with the same sink. One property read, idempotent — safe to
133
+ * call every request/run.
134
+ */
135
+ export declare function ensure_fetch_patched(): void;
136
+ /**
137
+ * KIT'S OWN `event.fetch` never reaches the global one for a same-origin call: it dispatches the
138
+ * request to the app's `respond()` in-process. A load that calls its own API through it is
139
+ * invisible to the global patch — so the profiler wraps `event.fetch` per attributed request with
140
+ * the same recorder. Idempotent (the brand), nothing when capture is not installed.
141
+ */
142
+ export declare function wrap_event_fetch<F extends typeof globalThis.fetch>(f: F): F;
143
+ /** the request header that asks, and the response header that answers */
144
+ export declare const TRACE_HEADER = "x-og-trace";
145
+ export interface UpstreamTrace {
146
+ /** the upstream's wall time for the request, ms */
147
+ ms: number;
148
+ cpu_ms: number;
149
+ /** waiting on its own outbound calls, ms, and how many */
150
+ wait_ms: number;
151
+ calls: number;
152
+ route?: string | null;
153
+ /** its own upstream calls, biggest first (a few) */
154
+ top?: {
155
+ url: string;
156
+ ms: number;
157
+ }[];
158
+ /** the profiler's own base on that host, so a report there can be opened */
159
+ profiler?: string;
160
+ }
161
+ export declare function encode_trace(t: UpstreamTrace): string;
162
+ export declare function decode_trace(h: string | null | undefined): UpstreamTrace | undefined;
163
+ /**
164
+ * How much of the wall time is explained by network calls running one after
165
+ * another (no overlap). High sequential time with several calls = the classic
166
+ * "await in a loop" page.
167
+ */
168
+ export declare function sequential_ms(calls: NetCall[]): number;
169
+ export { register_profiler_file };