@ogygia/devtools 0.0.0-stage → 0.11.0

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 +25 -2
  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 +103 -3
@@ -0,0 +1,62 @@
1
+ // src/profiler/site-fixes.ts
2
+ /** keeping an answer, or the whole page, is a freshness decision per page, not one shared fix */
3
+ const NOT_SHARED = /* @__PURE__ */ new Set([
4
+ "same-answer",
5
+ "almost-same-answer",
6
+ "same-document",
7
+ "almost-same-document"
8
+ ]);
9
+ const bare = (t) => {
10
+ const i = t.lastIndexOf(" (");
11
+ return i !== -1 && (t.endsWith(" places)") || t.endsWith(" place)")) ? t.slice(0, i) : t;
12
+ };
13
+ function site_fixes(reports, limit = 8) {
14
+ const latest = /* @__PURE__ */ new Map();
15
+ for (const r of reports) {
16
+ const had = latest.get(r.page);
17
+ if (!had || r.created > had.created) latest.set(r.page, r);
18
+ }
19
+ const by = /* @__PURE__ */ new Map();
20
+ for (const r of latest.values()) {
21
+ const n = Math.max(1, r.runs);
22
+ for (const p of r.patterns ?? []) {
23
+ if (NOT_SHARED.has(p.kind) || p.kept_bytes || p.seed_bytes || !(p.save_ms > 0)) continue;
24
+ const per_render = p.wait ? p.save_ms : p.save_ms / n;
25
+ const cost = (s) => s.wait_ms ?? s.cpu_ms ?? 0;
26
+ const total = p.sites.reduce((t, s) => t + cost(s), 0);
27
+ for (const s of p.sites) {
28
+ const ms = per_render * (total > 0 ? cost(s) / total : 1 / p.sites.length);
29
+ if (ms <= 0) continue;
30
+ const where = s.module ?? s.file;
31
+ const key = `${p.kind}\0${where}\0${s.line}\0${(s.code ?? "").trim()}`;
32
+ const f = by.get(key) ?? by.set(key, {
33
+ kind: p.kind,
34
+ title: bare(p.title),
35
+ where,
36
+ line: s.line,
37
+ code: s.code,
38
+ pages: [],
39
+ total_ms: 0
40
+ }).get(key);
41
+ const on = f.pages.find((x) => x.page === r.page);
42
+ if (on) on.ms += ms;
43
+ else f.pages.push({
44
+ page: r.page,
45
+ ms,
46
+ report: r.id
47
+ });
48
+ f.total_ms += ms;
49
+ }
50
+ }
51
+ }
52
+ const r2 = (x) => Math.round(x * 100) / 100;
53
+ return [...by.values()].filter((f) => f.pages.length >= 2).map((f) => ({
54
+ ...f,
55
+ total_ms: r2(f.total_ms),
56
+ pages: f.pages.map((x) => ({
57
+ ...x,
58
+ ms: r2(x.ms)
59
+ })).sort((a, b) => b.ms - a.ms)
60
+ })).sort((a, b) => b.total_ms - a.total_ms).slice(0, limit);
61
+ }
62
+ export { site_fixes };
@@ -0,0 +1,210 @@
1
+ /**
2
+ * SOURCE SCAN — reading app code at report time, without regular expressions: a tokenizer, the
3
+ * extent of a function's body, a module's import aliases, the lines that call a name, and the
4
+ * names a wrapped function goes by. The line ledger (ledger.ts) and the pattern finder
5
+ * (patterns.ts) both read code through these, only for the handful of lines a report names.
6
+ */
7
+ /** lines `from`..`to` of a source (1-based, inclusive), untrimmed */
8
+ export type SourceReader = (path: string, from: number, to: number) => {
9
+ start: number;
10
+ lines: string[];
11
+ } | undefined;
12
+ /** One line of JS/TS as tokens: identifiers and keywords as they are, every string literal as
13
+ * `""`, every number as `0`, punctuation one token each (`...`, `=>`, `+=`, `?.` kept whole).
14
+ * Comments are dropped. A template literal is one string token followed by each `${…}` part's
15
+ * own tokens in parentheses (`\`t${i + k}\`` → `""`, `(`, `i`, `+`, `k`, `)`), so the code inside
16
+ * it is seen. */
17
+ export declare function tokens(line: string): string[];
18
+ /** The lines of a function from its first line to its closing brace (brace-balanced over tokens,
19
+ * so braces in strings and comments do not count); a braceless arrow is its one line. Capped. */
20
+ export declare function function_body(source: SourceReader, path: string, start: number, max?: number): {
21
+ start: number;
22
+ lines: string[];
23
+ } | undefined;
24
+ /** A module's import aliases: `import { renderToString as render } from 'x'` → renderToString → [render]. */
25
+ export declare function import_aliases(source: SourceReader, path: string): Map<string, string[]>;
26
+ /** The names a function also goes by in its module when it is WRAPPED:
27
+ * `const renderToString = instrument(render, 'ds.render')` → render → [renderToString].
28
+ * The shape is `const|let|var X = <call chain>(name` — the function is the wrapper's first argument. */
29
+ export declare function wrapper_aliases(source: SourceReader, path: string): Map<string, string[]>;
30
+ /** how V8 names a compiled regular expression's code in a CPU profile: `RegExp: ^(\w+\s?)*$` */
31
+ export declare const REGEXP_FRAME = "RegExp: ";
32
+ /**
33
+ * CAN THIS PATTERN BACKTRACK HARD? A repeated group that itself repeats something (`(\w+\s?)*`,
34
+ * `(a+)+`, `(?:x*y?)+`): the engine can split the same text many ways and tries them all before a
35
+ * match fails. (A repeated choice, `(a|aa)+`, can too, but `(foo|bar)+` is the usual one and
36
+ * harmless: not claimed.) A character scan, not a parse: escapes and classes are skipped over.
37
+ */
38
+ export declare function backtracks(source: string | undefined): boolean;
39
+ /**
40
+ * THE REGEX LITERALS WRITTEN ON A LINE (their source, without the slashes and flags): a `/` where
41
+ * an expression starts (after `(`, `,`, `=`, `:`, `[`, `!`, `&`, `|`, `?`, `{`, `;`, `return`, or
42
+ * at the start) opens one. Strings, template text and comments are skipped; a division is not a
43
+ * literal (it follows a value).
44
+ */
45
+ export declare function regex_literals(code: string): string[];
46
+ /** does this line call `name(` (plain or as a method), outside strings and comments? */
47
+ export declare function calls_name(line: string, names: readonly string[]): boolean;
48
+ /** The functions a hooks file's `handle` is made of, when they live in OTHER app modules:
49
+ * `export const handle = sequence(ds_ssr, auth)` with `import { ds_ssr } from '$lib/ds-ssr'` →
50
+ * ds_ssr → `ds-ssr`. The value is the module's file stem, so a CPU frame counts as that handle
51
+ * only when it is named so AND sits in that file. A handle written in the hooks file itself is
52
+ * not listed (its frames are in the hooks file already), and neither is one from a package (a
53
+ * library's frames say what they are) or one made by a call (`auth()`: what it returns has its
54
+ * own name). */
55
+ export declare function handle_parts(source: SourceReader, path: string): Map<string, string>;
56
+ /**
57
+ * WHERE EACH RETURNED KEY COMES FROM: the lines of a `load` whose values end up in each key of its
58
+ * `return { … }` — a key's expression, the variables it reads, the lines that declare or fill those
59
+ * (`const live = await fetch(…)`, `stock.push(await stockOf(…))`), and so on back through what they
60
+ * read. 1-based line numbers of `source`. A wait made on one of a key's lines is a wait for that
61
+ * key. Tokens only (no regex); null when there is no `load` or its return is not an object literal.
62
+ */
63
+ /**
64
+ * WHERE A FILE'S `load` IS: its `export` line, and the lines its block body opens and closes on
65
+ * (0-based). `export async function load(…): Promise<{ a: string }> {` — the return type's braces
66
+ * are skipped; `export const load = async (…) => {` — the block after its arrow (a `satisfies`
67
+ * wrapper around it too). An expression body (`=> ({ … })`) has no block: null, never the next
68
+ * function in the file.
69
+ */
70
+ export declare function load_span(T: readonly (readonly string[])[]): {
71
+ head: number;
72
+ body0: number;
73
+ body1: number;
74
+ } | null;
75
+ export declare function key_sources(source: string): Map<string, number[]> | null;
76
+ /** One line's reads and writes: the names it declares or assigns (`const a =`, `a =`, `a += `,
77
+ * `a[k] =`), the receivers it fills (`list.push(…)`), and the variables it reads (not a property,
78
+ * not a callback's own parameter, not a name it only writes). `declared`: written by a
79
+ * declaration (fresh each time the line runs: never carried from one loop turn to the next). */
80
+ export declare function line_rw(line: string): {
81
+ reads: string[];
82
+ writes: string[];
83
+ declared: string[];
84
+ accum: string[];
85
+ };
86
+ /**
87
+ * DOES THE LATER CALL NEED THE EARLIER ONE'S ANSWER? Two lines of one file: true when `to` reads a
88
+ * name `from` wrote, directly or through the lines between (`const a = await x()` → `const id =
89
+ * a.id` → `await y(id)`). One line (a loop making the calls): true when a turn feeds the next — a
90
+ * name assigned (not declared) on it or the few lines after it, that it reads (`cursor = (await
91
+ * get(cursor)).next`). Then the calls cannot run together, and "waits in a row" is not a fix.
92
+ */
93
+ export declare function needs_previous(source: SourceReader, path: string, from: number, to: number): boolean;
94
+ /**
95
+ * WHAT THE PAGE WAITED ON THE LAYOUT FOR: in a load that does `await parent()`, the line doing it,
96
+ * the names it sets (`const { session } = await parent()` → session), and the first line after it
97
+ * that reads one of them (null: none does). The `await`s in between waited on the layout's loads
98
+ * for data they never used. 1-based lines; null when there is no `await parent()`.
99
+ */
100
+ export declare function parent_use(source: string): {
101
+ line: number;
102
+ names: string[];
103
+ first_use: number | null;
104
+ awaits_before_use: number;
105
+ } | null;
106
+ /**
107
+ * THE SAME WORK EVERY REQUEST: the `const` lines of a `load` whose value depends on nothing the
108
+ * request brings — only on the module's own imports and top-level values, pure globals, and other
109
+ * such lines (`const valid = validateAll(PRODUCTS)`, then `const joined = attachBrands(valid)`).
110
+ * Each request computes the same thing again; computed once at module load, it costs nothing.
111
+ * Not a line that awaits (I/O is `same-answer`'s), nor one that reads the load's arguments
112
+ * (`url`, `params`, `locals`, …), a `let`, or anything the file does not declare. `calls`: the
113
+ * functions it runs (whose time is the line's cost). 1-based lines.
114
+ */
115
+ export declare function constant_work(source: string): {
116
+ line: number;
117
+ names: string[];
118
+ calls: string[];
119
+ }[];
120
+ /** with `spans`: EVERY constant `const` statement (a cheap alias too, `work: false`), each with its
121
+ * last line — what moves to module scope together, since one can read another */
122
+ export declare function constant_work(source: string, spans: true): {
123
+ line: number;
124
+ end: number;
125
+ names: string[];
126
+ calls: string[];
127
+ work: boolean;
128
+ }[];
129
+ /**
130
+ * THE MOVE, CHECKED: which of the load's constant statements go to the file's top level (the costly
131
+ * ones and what they read, nothing else) and the line they go above (the load's `export`, 1-based).
132
+ * Null when moving them could change what the file does:
133
+ * - the file declares a top-level `const` / `let` / `var` / `class` AFTER the load. A moved call can
134
+ * run a helper that reads it before it is set (its temporal dead zone), so no line is safe to move
135
+ * above it;
136
+ * - a moved name is already a top-level name of the file (an import, a const, a function).
137
+ */
138
+ export declare function hoist_plan(source: string): {
139
+ above: number;
140
+ stmts: {
141
+ line: number;
142
+ end: number;
143
+ names: string[];
144
+ }[];
145
+ } | null;
146
+ /**
147
+ * THE LOOPS IN A COMPONENT'S MARKUP: each `{#each … as …}` block, the page-data key it walks
148
+ * (`data.results`, `page.data.results` → results), and the components rendered inside it
149
+ * (`<ResultCard …>`, nested blocks included). What decides how many times a child renders.
150
+ * 1-based lines.
151
+ */
152
+ export declare function each_blocks(svelte: string): {
153
+ line: number;
154
+ key?: string;
155
+ components: string[];
156
+ }[];
157
+ /**
158
+ * DATA ONLY A LATE ISLAND NEEDS: in a page's markup, the page-data keys used ONLY as props of
159
+ * islands imported to wake late (`import Reviews from './Reviews.svelte' with { wake: 'visible' }`
160
+ * — or `idle`, `interaction`), never in the page's own markup or an eager island. The page waits
161
+ * for that data on every request for something seen later, if at all. An island already
162
+ * `render: 'deferred'` fetches later by itself and is not one. 1-based lines of each use.
163
+ */
164
+ export declare function late_island_keys(svelte: string): {
165
+ key: string;
166
+ island: string;
167
+ wake: string;
168
+ line: number;
169
+ }[];
170
+ /** What a `load` takes from the request: the names in its parameter list (`async ({ url, cookies })`
171
+ * → url, cookies). Empty when it takes nothing; null when there is no load. */
172
+ export declare function load_inputs(source: string): string[] | null;
173
+ /**
174
+ * THE CHANGE, WRITTEN: awaits in a row as one `Promise.all` — when they are plain one-line
175
+ * statements (`const user = await get('user');`), next to each other (blank and comment lines
176
+ * between are fine; any other statement between could feed a later call, so none is), the rewrite
177
+ * only moves the later calls up to start with the first. The caller has already proved no call
178
+ * reads what an earlier one produced. `lines`: the source from the first line to the last (1-based
179
+ * `start`); `at`: the chain's lines. Undefined when the shape is anything else.
180
+ */
181
+ export declare function promise_all_rewrite(lines: readonly string[], start: number, at: readonly number[]): {
182
+ before: string;
183
+ after: string;
184
+ } | undefined;
185
+ /**
186
+ * THE CHANGE, WRITTEN, for a formatter built on every call: `new Intl.NumberFormat(locale, {…})` on
187
+ * a line. Arguments that read nothing (literals only) → one formatter at the top of the file, used
188
+ * on the line. Arguments that read variables → a cached factory at the top (one formatter per
189
+ * locale + options, built once) called on the line in place of `new Intl.X(`. A `.localeCompare(y,
190
+ * 'de', {…})` with literal arguments → one `Intl.Collator`'s `compare`. `ts`: the file is TypeScript
191
+ * (the factory is typed). Undefined when the line is anything else.
192
+ */
193
+ export declare function formatter_rewrite(line: string, opts: FormatterRewriteOptions): {
194
+ before: string;
195
+ after: string;
196
+ } | undefined;
197
+ export interface FormatterRewriteOptions {
198
+ /** the file is TypeScript: the factory is typed */
199
+ ts: boolean;
200
+ /** a component: the addition goes in `<script module>` (its instance script runs per render) */
201
+ svelte?: boolean;
202
+ /** every name the file already uses; the names this adds join it */
203
+ taken?: Set<string>;
204
+ /** what earlier rewrites in the same file added (what → name): the same formatter is reused */
205
+ made?: Map<string, string>;
206
+ }
207
+ /** The functions a set of lines names — called (`newestReview(x)`) or handed over (`.sort(byName)`):
208
+ * every bare identifier on them (not a property, not a keyword). What a CPU row by that name, run
209
+ * from a helper file with no line of the load on its samples, was working for. */
210
+ export declare function names_on(source: string, lines: readonly number[]): string[];