@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Puru Vijayvargia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,26 @@
1
1
  # @ogygia/devtools
2
2
 
3
- Reserved for [ogygia](https://ogygia.puruvj.dev). The first release is on its way.
3
+ Devtools for [ogygia](https://ogygiajs.dev): the in-page dock (each region boxed on the page, its real JS cost, what crossed the wire, when each island woke) and the SSR profiler (why a server render is slow, at `/__profiler`).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @ogygia/devtools
9
+ ```
10
+
11
+ ```ts
12
+ // vite.config.ts
13
+ import { ogygia } from 'ogygia/vite';
14
+ import { devtools } from '@ogygia/devtools/vite';
15
+
16
+ export default defineConfig(({ mode }) => ({
17
+ plugins: [ogygia(), ...(mode !== 'production' ? [devtools({ profiler: true })] : []), sveltekit()]
18
+ }));
19
+ ```
20
+
21
+ - `dock` (default `true`): the dock. On the dev server a launcher shows on every page. In a build it stays hidden until a browser turns it on with `?og-devtools=on`.
22
+ - `profiler` (default off): `true` or its options. In production, set `OGYGIA_PROFILER_SECRET`.
23
+
24
+ Code for the profiler: `@ogygia/devtools/profiler` (`span`, `instrument`), `@ogygia/devtools/profiler/client` (`mark`), and stores at `@ogygia/devtools/profiler/storage/sqlite`, `/redis`, `/postgres`.
25
+
26
+ Docs: [Devtools](https://ogygiajs.dev/docs/devtools/overview) and [the profiler](https://ogygiajs.dev/docs/profiler/overview).
@@ -0,0 +1,3 @@
1
+ import { ClientPlugin } from "@ogygia/core/plugin/client";
2
+ declare const client: ClientPlugin;
3
+ export { client as default };
package/dist/client.js ADDED
@@ -0,0 +1,24 @@
1
+ import { install_devtools_ui } from "./devtools/ui.js";
2
+ import { leftover_island_gone, leftover_island_seen, watch_leftovers } from "./devtools/leftovers.js";
3
+ import { defineClient } from "@ogygia/core/plugin/client";
4
+ // src/client.ts
5
+ /**
6
+ * The BROWSER half of `devtools()` (its `client`): the dock's launcher, and
7
+ * the leftovers watch (what a region's component leaves running after it leaves the page). With the dock off
8
+ * (`devtools({ dock: false })`, core's events not compiled in) every hook here folds to nothing.
9
+ */
10
+ const DOCK = typeof __OGYGIA_DEVTOOLS__ !== "undefined" ? __OGYGIA_DEVTOOLS__ : false;
11
+ const client = defineClient({
12
+ boot({ kitPage }) {
13
+ if (!DOCK) return;
14
+ install_devtools_ui(kitPage ? { csr_true: true } : void 0);
15
+ if (!kitPage) watch_leftovers();
16
+ },
17
+ regionMount(el, { entry, urls }) {
18
+ if (DOCK) leftover_island_seen(el, entry, [...urls]);
19
+ },
20
+ regionUnmount(el, { entry }) {
21
+ if (DOCK) leftover_island_gone(el, entry);
22
+ }
23
+ });
24
+ export { client as default };
@@ -0,0 +1,396 @@
1
+ <!-- (its CSS injected into the dock's shadow root: see Devtools.svelte) -->
2
+ <svelte:options css="injected" />
3
+
4
+ <script>
5
+ /**
6
+ * The boundary-lens OVERLAY: draws a labelled box over every `<ogygia-region>` on the page — tinted
7
+ * by kind (island / lake / hole), dashed while cold — and, on hover, a rich card that fuses DOM
8
+ * state with bus data (props bytes from the server render, hydrate ms from the client wake, joined
9
+ * by fingerprint) and the compiler's per-island JS cost. Each box is labelled by COMPONENT NAME, and
10
+ * islands show their JS-with-deps inline, so the page x-rays into the ogygia thesis at a glance.
11
+ *
12
+ * `focus` is a two-way bridge to the Lens tab: the region under the cursor here lights up the
13
+ * matching roster row there, and vice-versa; whichever region is focused stands out while the rest
14
+ * dim. The overlay is `pointer-events:none`, so the page stays fully interactive — hover is read off
15
+ * the real element under the cursor via `<svelte:window>`. A pure consumer, drawn only while on.
16
+ */
17
+ import { onMount } from 'svelte';
18
+ import {
19
+ all_regions,
20
+ region_info,
21
+ latest_event,
22
+ region_name,
23
+ region_transitive
24
+ } from './regions.js';
25
+
26
+ let {
27
+ overlay = false,
28
+ focus = $bindable(null),
29
+ selected = null,
30
+ picking = $bindable(false),
31
+ onpick
32
+ } = $props();
33
+
34
+ const kb = (n) => (n < 1024 ? n + ' B' : (n / 1024).toFixed(1) + ' KB');
35
+
36
+ function pick(el) {
37
+ onpick?.(el);
38
+ picking = false;
39
+ }
40
+ // A frame counter that advances only while the overlay is on — box rects follow scroll / hydration.
41
+ let frame = $state(0);
42
+ // One-time wiring (lifecycle, not an effect): Esc cancels a half-started pick. It reads `picking`
43
+ // live at call time.
44
+ onMount(() => {
45
+ const onkey = (e) => {
46
+ if (e.key === 'Escape' && picking) picking = false;
47
+ };
48
+ window.addEventListener('keydown', onkey);
49
+ return () => window.removeEventListener('keydown', onkey);
50
+ });
51
+ // The rAF loop runs ONLY while the overlay is on (it follows the `overlay` prop, hence an effect):
52
+ // a loop left running with the overlay off asked the browser for a frame sixty times a second on
53
+ // every page with devtools, the dock closed — ~90 ms of main-thread work each 5 s of idle
54
+ $effect(() => {
55
+ if (!overlay) return;
56
+ let raf = requestAnimationFrame(function loop() {
57
+ frame++;
58
+ raf = requestAnimationFrame(loop);
59
+ });
60
+ return () => cancelAnimationFrame(raf);
61
+ });
62
+
63
+ const boxes = $derived.by(() => {
64
+ void frame; // reactive dependency: recompute each animation frame
65
+ if (!overlay) return [];
66
+ return all_regions()
67
+ .map((r) => {
68
+ const t = r.kind === 'island' ? region_transitive(r.entry) : null;
69
+ return {
70
+ info: r,
71
+ name: region_name(r.entry),
72
+ js: t ? t.bytes : null,
73
+ rect: r.el.getBoundingClientRect()
74
+ };
75
+ })
76
+ .filter((b) => b.rect.width > 0 || b.rect.height > 0);
77
+ });
78
+
79
+ // Hover tooltip state (local — drives the card). `focus` is the shared cross-highlight key.
80
+ let hover = $state(/** @type {null | { x: number; y: number; el: Element }} */ (null));
81
+ function on_move(e) {
82
+ if (!overlay) {
83
+ hover = null;
84
+ return;
85
+ }
86
+ // The devtools lives in a shadow root, so `e.target` retargets to the host — read the composed
87
+ // path's innermost element to tell "over the page" from "over the dock".
88
+ const t = e.composedPath?.()[0] ?? e.target;
89
+ // Pointer over the dock UI → drop the page tip so it can't hover-cover the panel, but leave
90
+ // `focus` to the Lens tab (its roster rows drive it).
91
+ if (t instanceof Element && t.closest('[data-og-win],[data-og-panel-toggle]')) {
92
+ hover = null;
93
+ return;
94
+ }
95
+ let el = t instanceof Element ? t.closest('ogygia-region') : null;
96
+ // In pick mode the box catches the pointer (not the region under it) — resolve back by fp.
97
+ if (!el && t instanceof Element) {
98
+ const fp = t.closest('[data-og-box]')?.getAttribute('data-og-fp');
99
+ if (fp) el = document.querySelector(`ogygia-region[data-og-fp="${CSS.escape(fp)}"]`);
100
+ }
101
+ hover = el ? { x: e.clientX, y: e.clientY, el } : null;
102
+ focus = el;
103
+ }
104
+
105
+ const tip = $derived.by(() => {
106
+ if (!hover) return null;
107
+ const info = region_info(hover.el);
108
+ const rendered = info.fp
109
+ ? latest_event((ev) => ev.name === 'server.region.rendered' && ev.fp === info.fp)
110
+ : null;
111
+ const hyd = info.fp
112
+ ? latest_event((ev) => ev.name === 'region.hydrate.done' && ev.fp === info.fp)
113
+ : null;
114
+ const t = info.kind === 'island' ? region_transitive(info.entry) : null;
115
+ return {
116
+ name: region_name(info.entry),
117
+ kind: info.kind,
118
+ wake: info.wake,
119
+ fp: info.fp,
120
+ state:
121
+ info.kind === 'island'
122
+ ? info.hydrated
123
+ ? 'hydrated'
124
+ : 'cold'
125
+ : info.hydrated
126
+ ? 'filled'
127
+ : 'pending',
128
+ props: rendered && typeof rendered.propsBytes === 'number' ? rendered.propsBytes : null,
129
+ ms: hyd && typeof hyd.ms === 'number' ? hyd.ms : null,
130
+ js: t ? t.bytes : null,
131
+ mods: t ? t.modules : null,
132
+ serverRendered: !!rendered
133
+ };
134
+ });
135
+ </script>
136
+
137
+ <svelte:window onmousemove={on_move} />
138
+
139
+ {#if overlay}
140
+ <div class="og-overlay" data-og-overlay class:focusing={focus != null || selected != null}>
141
+ {#each boxes as b (b.info.el)}
142
+ <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
143
+ <div
144
+ class="box og-{b.info.kind}"
145
+ data-og-box={b.info.kind}
146
+ data-og-fp={b.info.fp}
147
+ class:cold={b.info.kind === 'island' && !b.info.hydrated}
148
+ class:on={focus === b.info.el || selected === b.info.el}
149
+ class:selected={selected === b.info.el}
150
+ class:pickable={picking}
151
+ onclick={picking ? () => pick(b.info.el) : null}
152
+ role={picking ? 'button' : null}
153
+ style:left="{b.rect.left}px"
154
+ style:top="{b.rect.top}px"
155
+ style:width="{b.rect.width}px"
156
+ style:height="{b.rect.height}px"
157
+ >
158
+ <span class="tag og-{b.info.kind}">
159
+ <b>{b.name}</b><span class="meta"
160
+ >{b.info.kind === 'island' ? ' ' + b.info.wake : ' ' + b.info.kind}{b.js != null
161
+ ? ' · ' + kb(b.js)
162
+ : ''}</span
163
+ >
164
+ </span>
165
+ </div>
166
+ {/each}
167
+ </div>
168
+
169
+ {#if picking}
170
+ <div class="pickhint">click an island to inspect · <b>Esc</b> to cancel</div>
171
+ {/if}
172
+
173
+ {#if tip}
174
+ <div
175
+ class="tip"
176
+ style:left="{Math.min(hover.x + 14, innerWidth - 300)}px"
177
+ style:top="{Math.min(hover.y + 14, innerHeight - 160)}px"
178
+ >
179
+ <div class="head">
180
+ <span class="dot og-{tip.kind}"></span><b>{tip.name}</b>
181
+ </div>
182
+ <div class="sub og-{tip.kind}">
183
+ {tip.kind}{tip.kind === 'island' ? ` · wakes on ${tip.wake}` : ''} · {tip.state}
184
+ </div>
185
+ <div class="rows">
186
+ {#if tip.js != null}
187
+ <div class="row">
188
+ <span class="k">js + deps</span><span
189
+ >{kb(tip.js)}<span class="mut"> · {tip.mods} mod</span></span
190
+ >
191
+ </div>
192
+ {/if}
193
+ {#if tip.props != null}
194
+ <div class="row"><span class="k">props</span><span>{tip.props} B</span></div>
195
+ {/if}
196
+ {#if tip.ms != null}
197
+ <div class="row">
198
+ <span class="k">hydrated in</span><span>{tip.ms.toFixed(1)} ms</span>
199
+ </div>
200
+ {/if}
201
+ <div class="row">
202
+ <span class="k">server-rendered</span><span>{tip.serverRendered ? 'yes' : 'no'}</span>
203
+ </div>
204
+ {#if tip.fp}<div class="row">
205
+ <span class="k">fp</span><span class="mono">{tip.fp}</span>
206
+ </div>{/if}
207
+ </div>
208
+ </div>
209
+ {/if}
210
+ {/if}
211
+
212
+ <style>
213
+ .og-overlay {
214
+ position: fixed;
215
+ inset: 0;
216
+ pointer-events: none;
217
+ z-index: 2147483000;
218
+ font:
219
+ 11px/1.4 ui-monospace,
220
+ SFMono-Regular,
221
+ Menlo,
222
+ monospace;
223
+ }
224
+ .box {
225
+ position: absolute;
226
+ box-sizing: border-box;
227
+ border-radius: 4px;
228
+ border: 1.5px solid;
229
+ transition: opacity 0.12s ease;
230
+ }
231
+ .box.og-island {
232
+ border-color: #14b8a6;
233
+ background: rgba(20, 184, 166, 0.12);
234
+ }
235
+ .box.og-lake {
236
+ border-color: #f59e0b;
237
+ background: rgba(245, 158, 11, 0.12);
238
+ }
239
+ .box.og-hole {
240
+ border-color: #8b5cf6;
241
+ background: rgba(139, 92, 246, 0.12);
242
+ }
243
+ .box.cold {
244
+ border-style: dashed;
245
+ }
246
+ /* When ANY region is focused, dim the rest so the focused one reads clearly. */
247
+ .og-overlay.focusing .box:not(.on) {
248
+ opacity: 0.3;
249
+ }
250
+ .box.on {
251
+ z-index: 1;
252
+ box-shadow:
253
+ 0 0 0 2px rgba(94, 234, 212, 0.5),
254
+ 0 6px 20px rgba(0, 0, 0, 0.35);
255
+ }
256
+ .box.selected {
257
+ box-shadow:
258
+ 0 0 0 2px #5eead4,
259
+ 0 8px 24px rgba(0, 0, 0, 0.4);
260
+ }
261
+ /* Pick mode: boxes catch the pointer (the rest of the overlay stays click-through). */
262
+ .box.pickable {
263
+ pointer-events: auto;
264
+ cursor: crosshair;
265
+ }
266
+ .pickhint {
267
+ position: fixed;
268
+ top: 12px;
269
+ left: 50%;
270
+ transform: translateX(-50%);
271
+ z-index: 2147483600;
272
+ pointer-events: none;
273
+ padding: 6px 14px;
274
+ border-radius: 999px;
275
+ background: #f59e0b;
276
+ color: #201400;
277
+ font-weight: 600;
278
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
279
+ }
280
+ .pickhint b {
281
+ font-weight: 700;
282
+ }
283
+ .box.on.og-island {
284
+ background: rgba(20, 184, 166, 0.22);
285
+ }
286
+ .box.on.og-lake {
287
+ background: rgba(245, 158, 11, 0.22);
288
+ }
289
+ .box.on.og-hole {
290
+ background: rgba(139, 92, 246, 0.22);
291
+ }
292
+ .tag {
293
+ position: absolute;
294
+ top: -1px;
295
+ left: -1px;
296
+ max-width: 100vw;
297
+ padding: 2px 6px;
298
+ border-radius: 4px 0 4px 0;
299
+ color: #021;
300
+ font-weight: 600;
301
+ white-space: nowrap;
302
+ overflow: hidden;
303
+ text-overflow: ellipsis;
304
+ }
305
+ .tag b {
306
+ font-weight: 700;
307
+ }
308
+ .tag .meta {
309
+ font-weight: 500;
310
+ opacity: 0.8;
311
+ }
312
+ .tag.og-island {
313
+ background: #14b8a6;
314
+ }
315
+ .tag.og-lake {
316
+ background: #f59e0b;
317
+ }
318
+ .tag.og-hole {
319
+ background: #8b5cf6;
320
+ }
321
+ .tip {
322
+ position: fixed;
323
+ z-index: 2147483600;
324
+ pointer-events: none;
325
+ min-width: 190px;
326
+ max-width: 320px;
327
+ padding: 9px 11px;
328
+ border-radius: 9px;
329
+ background: #0b1220;
330
+ color: #e2e8f0;
331
+ border: 1px solid rgba(148, 163, 184, 0.3);
332
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
333
+ font:
334
+ 11px/1.5 ui-monospace,
335
+ SFMono-Regular,
336
+ Menlo,
337
+ monospace;
338
+ }
339
+ .tip .head {
340
+ display: flex;
341
+ align-items: center;
342
+ gap: 6px;
343
+ font-size: 12px;
344
+ }
345
+ .tip .head b {
346
+ color: #e2e8f0;
347
+ font-weight: 700;
348
+ }
349
+ .tip .dot {
350
+ width: 8px;
351
+ height: 8px;
352
+ border-radius: 50%;
353
+ flex: none;
354
+ }
355
+ .tip .dot.og-island {
356
+ background: #14b8a6;
357
+ }
358
+ .tip .dot.og-lake {
359
+ background: #f59e0b;
360
+ }
361
+ .tip .dot.og-hole {
362
+ background: #8b5cf6;
363
+ }
364
+ .tip .sub {
365
+ margin: 1px 0 7px 14px;
366
+ color: #94a3b8;
367
+ }
368
+ .tip .sub.og-island {
369
+ color: #5eead4;
370
+ }
371
+ .tip .sub.og-lake {
372
+ color: #fbbf24;
373
+ }
374
+ .tip .sub.og-hole {
375
+ color: #c4b5fd;
376
+ }
377
+ .tip .rows {
378
+ display: flex;
379
+ flex-direction: column;
380
+ gap: 2px;
381
+ }
382
+ .tip .row {
383
+ display: flex;
384
+ gap: 12px;
385
+ justify-content: space-between;
386
+ }
387
+ .tip .k {
388
+ color: #94a3b8;
389
+ }
390
+ .tip .mut {
391
+ color: #94a3b8;
392
+ }
393
+ .tip .mono {
394
+ color: #cbd5e1;
395
+ }
396
+ </style>
@@ -0,0 +1,19 @@
1
+ export default BoundaryOverlay;
2
+ type BoundaryOverlay = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const BoundaryOverlay: import("svelte").Component<{
7
+ overlay?: boolean;
8
+ focus?: any;
9
+ selected?: any;
10
+ picking?: boolean;
11
+ onpick: any;
12
+ }, {}, "focus" | "picking">;
13
+ type $$ComponentProps = {
14
+ overlay?: boolean;
15
+ focus?: any;
16
+ selected?: any;
17
+ picking?: boolean;
18
+ onpick: any;
19
+ };