@ccslabs/xtend 0.1.0-rc.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 (664) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +201 -0
  3. package/README.md +184 -0
  4. package/a11y/motion-contrast-policy.d.ts +32 -0
  5. package/a11y/motion-contrast-policy.js +261 -0
  6. package/a11y/runtime-a11y-contract.d.ts +44 -0
  7. package/a11y/runtime-a11y-contract.js +385 -0
  8. package/a11y/screenreader-signals.d.ts +32 -0
  9. package/a11y/screenreader-signals.js +372 -0
  10. package/api.d.ts +168 -0
  11. package/api.js +864 -0
  12. package/catalog/catalog-public-types.d.ts +66 -0
  13. package/catalog/component-catalog-coverage.d.ts +20 -0
  14. package/catalog/component-catalog-coverage.js +377 -0
  15. package/catalog/component-long-tail-migration.d.ts +18 -0
  16. package/catalog/component-long-tail-migration.js +305 -0
  17. package/catalog/component-regression-priority.d.ts +20 -0
  18. package/catalog/component-regression-priority.js +305 -0
  19. package/catalog/enterprise-component-flex-release-handoff.d.ts +32 -0
  20. package/catalog/enterprise-component-flex-release-handoff.js +437 -0
  21. package/catalog/enterprise-component-style-audit.d.ts +22 -0
  22. package/catalog/enterprise-component-style-audit.js +353 -0
  23. package/catalog/enterprise-form-control-theme-a11y.d.ts +19 -0
  24. package/catalog/enterprise-form-control-theme-a11y.js +220 -0
  25. package/catalog/enterprise-icon-control-audit.d.ts +21 -0
  26. package/catalog/enterprise-icon-control-audit.js +258 -0
  27. package/catalog/enterprise-layout-display-media-tokenization.d.ts +20 -0
  28. package/catalog/enterprise-layout-display-media-tokenization.js +237 -0
  29. package/catalog/enterprise-navigation-routing-state-hardening.d.ts +20 -0
  30. package/catalog/enterprise-navigation-routing-state-hardening.js +255 -0
  31. package/catalog/enterprise-overlay-mode-token-parity.d.ts +15 -0
  32. package/catalog/enterprise-overlay-mode-token-parity.js +178 -0
  33. package/catalog/enterprise-third-party-authoring-guide.d.ts +23 -0
  34. package/catalog/enterprise-third-party-authoring-guide.js +310 -0
  35. package/catalog/enterprise-visual-dom-snapshot-matrix.d.ts +31 -0
  36. package/catalog/enterprise-visual-dom-snapshot-matrix.js +357 -0
  37. package/catalog/epic10-existing-component-metadata.d.ts +25 -0
  38. package/catalog/epic10-existing-component-metadata.js +534 -0
  39. package/catalog/epic10-p0-component-wave.d.ts +28 -0
  40. package/catalog/epic10-p0-component-wave.js +688 -0
  41. package/catalog/epic10-platform-gates.d.ts +31 -0
  42. package/catalog/epic10-platform-gates.js +425 -0
  43. package/catalog/epic10-release-handoff.d.ts +30 -0
  44. package/catalog/epic10-release-handoff.js +195 -0
  45. package/catalog/epic11-enterprise-ux-handoff.d.ts +29 -0
  46. package/catalog/epic11-enterprise-ux-handoff.js +403 -0
  47. package/catalog/epic12-docs-adoption.d.ts +29 -0
  48. package/catalog/epic12-docs-adoption.js +183 -0
  49. package/catalog/epic12-rc0-gate-matrix.d.ts +36 -0
  50. package/catalog/epic12-rc0-gate-matrix.js +439 -0
  51. package/catalog/epic12-rc0-handoff.d.ts +30 -0
  52. package/catalog/epic12-rc0-handoff.js +385 -0
  53. package/catalog/epic13-conditional-network-evidence-ci.d.ts +35 -0
  54. package/catalog/epic13-conditional-network-evidence-ci.js +278 -0
  55. package/catalog/epic13-conditional-network-evidence.d.ts +34 -0
  56. package/catalog/epic13-conditional-network-evidence.js +280 -0
  57. package/catalog/epic13-docs-rmt-production-hardening.d.ts +39 -0
  58. package/catalog/epic13-docs-rmt-production-hardening.js +286 -0
  59. package/catalog/epic13-hydration-performance-closure.d.ts +33 -0
  60. package/catalog/epic13-hydration-performance-closure.js +234 -0
  61. package/catalog/epic13-known-residual-triage.d.ts +32 -0
  62. package/catalog/epic13-known-residual-triage.js +339 -0
  63. package/catalog/epic13-package-export-lock.d.ts +41 -0
  64. package/catalog/epic13-package-export-lock.js +604 -0
  65. package/catalog/epic13-prod-browser-csp-smoke.d.ts +35 -0
  66. package/catalog/epic13-prod-browser-csp-smoke.js +218 -0
  67. package/catalog/epic13-rc1-gate-matrix-ci-handoff.d.ts +36 -0
  68. package/catalog/epic13-rc1-gate-matrix-ci-handoff.js +418 -0
  69. package/catalog/epic13-rc1-migration-notes.d.ts +36 -0
  70. package/catalog/epic13-rc1-migration-notes.js +271 -0
  71. package/catalog/epic13-rc1-readiness.d.ts +33 -0
  72. package/catalog/epic13-rc1-readiness.js +487 -0
  73. package/catalog/epic13-release-owner-acceptance.d.ts +33 -0
  74. package/catalog/epic13-release-owner-acceptance.js +354 -0
  75. package/catalog/epic13-release-report-pack-dry-run-evidence.d.ts +36 -0
  76. package/catalog/epic13-release-report-pack-dry-run-evidence.js +253 -0
  77. package/catalog/epic13-rmt-production-readiness.d.ts +35 -0
  78. package/catalog/epic13-rmt-production-readiness.js +314 -0
  79. package/catalog/epic13-trusted-dom-boundary.d.ts +36 -0
  80. package/catalog/epic13-trusted-dom-boundary.js +230 -0
  81. package/catalog/epic13-visual-owner-artifact.d.ts +35 -0
  82. package/catalog/epic13-visual-owner-artifact.js +233 -0
  83. package/catalog/epic14-lsp-handoff.d.ts +28 -0
  84. package/catalog/epic14-lsp-handoff.js +312 -0
  85. package/catalog/epic14-rmt-tooling.d.ts +33 -0
  86. package/catalog/epic14-rmt-tooling.js +282 -0
  87. package/catalog/surface-manager-adapter-runtime.d.ts +37 -0
  88. package/catalog/surface-manager-adapter-runtime.js +203 -0
  89. package/catalog/surface-manager-browser-lab.d.ts +39 -0
  90. package/catalog/surface-manager-browser-lab.js +225 -0
  91. package/catalog/surface-manager-controller.d.ts +43 -0
  92. package/catalog/surface-manager-controller.js +290 -0
  93. package/catalog/surface-manager-layout-engines.d.ts +32 -0
  94. package/catalog/surface-manager-layout-engines.js +161 -0
  95. package/catalog/surface-manager-lazy-loading.d.ts +35 -0
  96. package/catalog/surface-manager-lazy-loading.js +173 -0
  97. package/catalog/surface-manager-materialization.d.ts +37 -0
  98. package/catalog/surface-manager-materialization.js +202 -0
  99. package/catalog/surface-manager-native-rmt-surfaces.d.ts +48 -0
  100. package/catalog/surface-manager-native-rmt-surfaces.js +325 -0
  101. package/catalog/surface-manager-overlay-bridge.d.ts +42 -0
  102. package/catalog/surface-manager-overlay-bridge.js +247 -0
  103. package/catalog/surface-manager-persistence.d.ts +37 -0
  104. package/catalog/surface-manager-persistence.js +178 -0
  105. package/catalog/surface-manager-quality-gates.d.ts +48 -0
  106. package/catalog/surface-manager-quality-gates.js +324 -0
  107. package/catalog/surface-manager-release-handoff.d.ts +47 -0
  108. package/catalog/surface-manager-release-handoff.js +274 -0
  109. package/catalog/surface-manager-remote-policy.d.ts +34 -0
  110. package/catalog/surface-manager-remote-policy.js +199 -0
  111. package/catalog/surface-manager-rmt-authoring.d.ts +44 -0
  112. package/catalog/surface-manager-rmt-authoring.js +368 -0
  113. package/catalog/surface-manager-route-lifecycle.d.ts +32 -0
  114. package/catalog/surface-manager-route-lifecycle.js +162 -0
  115. package/catalog/surface-manager-runtime-release-handoff.d.ts +36 -0
  116. package/catalog/surface-manager-runtime-release-handoff.js +245 -0
  117. package/catalog/surface-manager-side-panel-runtime.d.ts +46 -0
  118. package/catalog/surface-manager-side-panel-runtime.js +307 -0
  119. package/catalog/surface-manager-stack-policy.d.ts +32 -0
  120. package/catalog/surface-manager-stack-policy.js +169 -0
  121. package/catalog/surface-manager-window-runtime.d.ts +45 -0
  122. package/catalog/surface-manager-window-runtime.js +285 -0
  123. package/catalog/surface-manager-workbench-fixture.d.ts +50 -0
  124. package/catalog/surface-manager-workbench-fixture.js +315 -0
  125. package/catalog/type-exports-api.js +236 -0
  126. package/catalog/type-exports-builder.js +405 -0
  127. package/catalog/type-exports-catalog.js +394 -0
  128. package/catalog/type-exports-loader.js +266 -0
  129. package/catalog/type-exports-policy.js +461 -0
  130. package/catalog/type-exports-rmt.js +407 -0
  131. package/catalog/type-exports-vendor.js +365 -0
  132. package/catalog/type-exports.js +574 -0
  133. package/components/icon-packs/core.js +154 -0
  134. package/components/icon-packs/lucide.js +136 -0
  135. package/components/manifest.json +44 -0
  136. package/components/prism.d.ts +73 -0
  137. package/components/prism.js +300 -0
  138. package/components/turndown.d.ts +34 -0
  139. package/components/turndown.js +107 -0
  140. package/components/x-rmt-lifecycle-demo-build.d.ts +78 -0
  141. package/components/x-rmt-lifecycle-demo-build.js +1175 -0
  142. package/components/x-rmt-lifecycle-demo.d.ts +83 -0
  143. package/components/x-rmt-lifecycle-demo.js +1175 -0
  144. package/components/xalert.d.ts +42 -0
  145. package/components/xalert.js +538 -0
  146. package/components/xbutton.d.ts +127 -0
  147. package/components/xbutton.js +612 -0
  148. package/components/xcalendar.d.ts +39 -0
  149. package/components/xcalendar.js +338 -0
  150. package/components/xcards.d.ts +34 -0
  151. package/components/xcards.js +253 -0
  152. package/components/xcheckbox.d.ts +48 -0
  153. package/components/xcheckbox.js +448 -0
  154. package/components/xcode.d.ts +35 -0
  155. package/components/xcode.js +370 -0
  156. package/components/xdialog.d.ts +48 -0
  157. package/components/xdialog.js +763 -0
  158. package/components/xdrawer.d.ts +61 -0
  159. package/components/xdrawer.js +654 -0
  160. package/components/xfooter.d.ts +41 -0
  161. package/components/xfooter.js +351 -0
  162. package/components/xform.d.ts +43 -0
  163. package/components/xform.js +456 -0
  164. package/components/xheader.d.ts +68 -0
  165. package/components/xheader.js +1253 -0
  166. package/components/xhero.d.ts +42 -0
  167. package/components/xhero.js +475 -0
  168. package/components/xicon.d.ts +146 -0
  169. package/components/xicon.js +688 -0
  170. package/components/xinput.d.ts +37 -0
  171. package/components/xinput.js +444 -0
  172. package/components/xlightbox.d.ts +48 -0
  173. package/components/xlightbox.js +571 -0
  174. package/components/xlink.d.ts +63 -0
  175. package/components/xlink.js +565 -0
  176. package/components/xmasonry.d.ts +35 -0
  177. package/components/xmasonry.js +666 -0
  178. package/components/xmenu.d.ts +118 -0
  179. package/components/xmenu.js +1005 -0
  180. package/components/xmodal.d.ts +64 -0
  181. package/components/xmodal.js +831 -0
  182. package/components/xplayer.d.ts +57 -0
  183. package/components/xplayer.js +1748 -0
  184. package/components/xpopover.d.ts +54 -0
  185. package/components/xpopover.js +466 -0
  186. package/components/xprogress.d.ts +40 -0
  187. package/components/xprogress.js +345 -0
  188. package/components/xradio.d.ts +50 -0
  189. package/components/xradio.js +474 -0
  190. package/components/xrouter.d.ts +244 -0
  191. package/components/xrouter.js +1841 -0
  192. package/components/xsection.d.ts +34 -0
  193. package/components/xsection.js +253 -0
  194. package/components/xselect.d.ts +46 -0
  195. package/components/xselect.js +463 -0
  196. package/components/xsidepanel.d.ts +56 -0
  197. package/components/xsidepanel.js +728 -0
  198. package/components/xspinner.d.ts +38 -0
  199. package/components/xspinner.js +388 -0
  200. package/components/xstate.d.ts +137 -0
  201. package/components/xstate.js +493 -0
  202. package/components/xstatus.d.ts +41 -0
  203. package/components/xstatus.js +381 -0
  204. package/components/xsummary.d.ts +43 -0
  205. package/components/xsummary.js +293 -0
  206. package/components/xsurfacemanager-controller.d.ts +130 -0
  207. package/components/xsurfacemanager-controller.js +699 -0
  208. package/components/xsurfacemanager.d.ts +452 -0
  209. package/components/xsurfacemanager.js +3775 -0
  210. package/components/xsurfaceoverlay-bridge.d.ts +43 -0
  211. package/components/xsurfaceoverlay-bridge.js +238 -0
  212. package/components/xsurfacewindow.d.ts +50 -0
  213. package/components/xsurfacewindow.js +576 -0
  214. package/components/xtabs.d.ts +73 -0
  215. package/components/xtabs.js +611 -0
  216. package/components/xtend-public-types.d.ts +208 -0
  217. package/components/xtextarea.d.ts +46 -0
  218. package/components/xtextarea.js +451 -0
  219. package/components/xtheme.d.ts +253 -0
  220. package/components/xtheme.js +1438 -0
  221. package/components/xtoast.d.ts +39 -0
  222. package/components/xtoast.js +389 -0
  223. package/components/xtooltip.d.ts +53 -0
  224. package/components/xtooltip.js +432 -0
  225. package/components/xtype.d.ts +42 -0
  226. package/components/xtype.js +244 -0
  227. package/components/xutils.d.ts +164 -0
  228. package/components/xutils.js +496 -0
  229. package/components/xwriter.d.ts +67 -0
  230. package/components/xwriter.js +854 -0
  231. package/design-tokens/themes/enterprise-light.json +40 -0
  232. package/design-tokens/themes/xtend-signature.json +126 -0
  233. package/design-tokens/xtend-design-tokens.d.ts +95 -0
  234. package/design-tokens/xtend-design-tokens.js +395 -0
  235. package/design-tokens/xtheme-token-alias-layer.d.ts +84 -0
  236. package/design-tokens/xtheme-token-alias-layer.js +423 -0
  237. package/docs/.htaccess +51 -0
  238. package/docs/README.md +340 -0
  239. package/docs/XTend-ADR.md +221 -0
  240. package/docs/a11y-keyboard-smokes.md +62 -0
  241. package/docs/about.md +18 -0
  242. package/docs/api.md +157 -0
  243. package/docs/best-practices.md +76 -0
  244. package/docs/component-catalog-coverage.md +58 -0
  245. package/docs/component-lab.md +103 -0
  246. package/docs/component-long-tail-migration.md +41 -0
  247. package/docs/component-platform.md +159 -0
  248. package/docs/component-ux-app-authoring.md +130 -0
  249. package/docs/component-ux-authoring.md +96 -0
  250. package/docs/component-ux-gates.md +45 -0
  251. package/docs/components/x-rmt-lifecycle-demo-build.md +60 -0
  252. package/docs/components/xalert.md +81 -0
  253. package/docs/components/xbutton.md +103 -0
  254. package/docs/components/xcalendar.md +82 -0
  255. package/docs/components/xcards.md +128 -0
  256. package/docs/components/xcheckbox.md +102 -0
  257. package/docs/components/xcode.md +126 -0
  258. package/docs/components/xdialog.md +92 -0
  259. package/docs/components/xdrawer.md +84 -0
  260. package/docs/components/xfooter.md +126 -0
  261. package/docs/components/xform.md +128 -0
  262. package/docs/components/xheader.md +308 -0
  263. package/docs/components/xhero.md +142 -0
  264. package/docs/components/xicon.md +125 -0
  265. package/docs/components/xinput.md +129 -0
  266. package/docs/components/xlightbox.md +98 -0
  267. package/docs/components/xlink.md +109 -0
  268. package/docs/components/xmasonry.md +124 -0
  269. package/docs/components/xmenu.md +158 -0
  270. package/docs/components/xmodal.md +82 -0
  271. package/docs/components/xplayer.md +104 -0
  272. package/docs/components/xpopover.md +67 -0
  273. package/docs/components/xprogress.md +56 -0
  274. package/docs/components/xradio.md +103 -0
  275. package/docs/components/xrouter.md +260 -0
  276. package/docs/components/xsection.md +125 -0
  277. package/docs/components/xselect.md +105 -0
  278. package/docs/components/xsidepanel.md +30 -0
  279. package/docs/components/xspinner.md +102 -0
  280. package/docs/components/xstate.md +148 -0
  281. package/docs/components/xstatus.md +55 -0
  282. package/docs/components/xsummary.md +78 -0
  283. package/docs/components/xsurfacemanager.md +27 -0
  284. package/docs/components/xsurfacewindow.md +21 -0
  285. package/docs/components/xtabs.md +160 -0
  286. package/docs/components/xtextarea.md +98 -0
  287. package/docs/components/xtheme.md +167 -0
  288. package/docs/components/xtoast.md +62 -0
  289. package/docs/components/xtooltip.md +66 -0
  290. package/docs/components/xtype.md +82 -0
  291. package/docs/components/xutils.md +144 -0
  292. package/docs/components/xwriter.md +94 -0
  293. package/docs/components.md +117 -0
  294. package/docs/conditional-network-evidence-ci.md +38 -0
  295. package/docs/conditional-network-evidence.md +50 -0
  296. package/docs/core-migration-guide.md +110 -0
  297. package/docs/design-tokens.md +116 -0
  298. package/docs/docs-rmt-production-hardening.md +31 -0
  299. package/docs/enterprise-adoption.md +411 -0
  300. package/docs/enterprise-component-flex-release-handoff.md +129 -0
  301. package/docs/epic10-platform-gates.md +62 -0
  302. package/docs/epic10-release-handoff.md +81 -0
  303. package/docs/epic11-enterprise-ux-handoff.md +70 -0
  304. package/docs/epic12-rc0-handoff.md +61 -0
  305. package/docs/existing-component-metadata.md +67 -0
  306. package/docs/hydration-performance-closure.md +34 -0
  307. package/docs/hydration-policies.md +71 -0
  308. package/docs/index.php +1625 -0
  309. package/docs/known-residual-triage.md +22 -0
  310. package/docs/manifest-import-policy.md +79 -0
  311. package/docs/manifest.md +106 -0
  312. package/docs/menu.json +1190 -0
  313. package/docs/motion-contrast.md +67 -0
  314. package/docs/package-export-lock.md +44 -0
  315. package/docs/performance-measurements.md +106 -0
  316. package/docs/performance-regression.md +89 -0
  317. package/docs/performance.md +94 -0
  318. package/docs/previews/README.md +17 -0
  319. package/docs/prod-browser-csp-smokes.md +40 -0
  320. package/docs/public-component-types.md +79 -0
  321. package/docs/quick-start-guide.md +152 -0
  322. package/docs/rc0-adoption-guide.md +102 -0
  323. package/docs/rc0-gate-matrix.md +58 -0
  324. package/docs/rc1-gate-matrix-ci-handoff.md +56 -0
  325. package/docs/rc1-migration-notes.md +69 -0
  326. package/docs/rc1-readiness.md +46 -0
  327. package/docs/release-owner-acceptance.md +56 -0
  328. package/docs/release-report-pack-dry-run-evidence.md +39 -0
  329. package/docs/rmt-dsl-authoring-polish.md +122 -0
  330. package/docs/rmt-first-demo-app.md +77 -0
  331. package/docs/rmt-first-xtend-apps.md +105 -0
  332. package/docs/rmt-kernel-panic-recovery-incident-handoff.md +61 -0
  333. package/docs/rmt-kernel-security-hardening-migration.md +50 -0
  334. package/docs/rmt-kernel-trusted-output-authoring.md +69 -0
  335. package/docs/rmt-language-server.md +177 -0
  336. package/docs/rmt-lifecycle-demo.md +25 -0
  337. package/docs/rmt-linter.md +140 -0
  338. package/docs/rmt-production-readiness.md +63 -0
  339. package/docs/rmt-tooling-release-gates.md +77 -0
  340. package/docs/rmt-vnext-authoring.md +60 -0
  341. package/docs/rmt-vnext-cross-surface-events.md +68 -0
  342. package/docs/rmt-vnext-enterprise-mfe-handoff.md +70 -0
  343. package/docs/rmt-vnext-migration-notes.md +62 -0
  344. package/docs/rmt-vnext-release-handoff.md +69 -0
  345. package/docs/rmt-vnext-remote-surfaces.md +90 -0
  346. package/docs/rmt-vnext-surface-registry-enterprise.md +76 -0
  347. package/docs/screenreader-signals.md +56 -0
  348. package/docs/supply-chain-gates.md +100 -0
  349. package/docs/surface-manager-authoring-guide.md +94 -0
  350. package/docs/surface-manager-browser-lab.md +45 -0
  351. package/docs/surface-manager-component-lab.md +43 -0
  352. package/docs/surface-manager-controller.md +66 -0
  353. package/docs/surface-manager-layout-engines.md +32 -0
  354. package/docs/surface-manager-lazy-hydration.md +63 -0
  355. package/docs/surface-manager-migration-guide.md +94 -0
  356. package/docs/surface-manager-native-rmt-surfaces.md +38 -0
  357. package/docs/surface-manager-overlay-bridge.md +53 -0
  358. package/docs/surface-manager-persistence.md +30 -0
  359. package/docs/surface-manager-quality-gates.md +51 -0
  360. package/docs/surface-manager-release-handoff.md +68 -0
  361. package/docs/surface-manager-remote-policy.md +54 -0
  362. package/docs/surface-manager-rmt-authoring.md +86 -0
  363. package/docs/surface-manager-route-lifecycle.md +59 -0
  364. package/docs/surface-manager-runtime-release-handoff.md +69 -0
  365. package/docs/surface-manager-side-panel-runtime.md +36 -0
  366. package/docs/surface-manager-stack-policy.md +39 -0
  367. package/docs/surface-manager-window-runtime.md +47 -0
  368. package/docs/surface-manager-workbench-fixture.md +43 -0
  369. package/docs/third-party-design-authoring.md +406 -0
  370. package/docs/trusted-dom-boundary-browser-proof.md +32 -0
  371. package/docs/trusted-dom-sanitizing.md +110 -0
  372. package/docs/type-exports.md +61 -0
  373. package/docs/typescript-components.md +63 -0
  374. package/docs/utils/fabric-runtime.js +650 -0
  375. package/docs/utils/pageloader.js +2823 -0
  376. package/docs/utils/parsedown.php +298 -0
  377. package/docs/visual-browser-regression.md +83 -0
  378. package/docs/visual-owner-artifacts.md +46 -0
  379. package/docs/visual-snapshot-automation.md +87 -0
  380. package/docs/xtend-api-types.md +55 -0
  381. package/docs/xtend-builder-types.md +55 -0
  382. package/docs/xtend-catalog-types.md +44 -0
  383. package/docs/xtend-fabric-rmt-lane-mapping.md +143 -0
  384. package/docs/xtend-fabric.md +474 -0
  385. package/docs/xtend-loader-types.md +58 -0
  386. package/docs/xtend-loader.md +265 -0
  387. package/docs/xtend-policy-types.md +38 -0
  388. package/docs/xtend-rmt-types.md +39 -0
  389. package/docs/xtend-vendor-types.md +36 -0
  390. package/docs/xtendrmt-app-dsl.md +269 -0
  391. package/docs/xtendrmt-migration-guide.md +235 -0
  392. package/docs/xtendrmt-native-authoring.md +337 -0
  393. package/docs/xtendrmt-overview.md +89 -0
  394. package/docs/xtendrmt-parsedown-docs.rmt +956 -0
  395. package/docs/xtendrmt-parsedown-scheduling.md +301 -0
  396. package/docs/xtendrmt-runtime-bridge.md +155 -0
  397. package/fabric/hydration-policy.d.ts +27 -0
  398. package/fabric/hydration-policy.js +306 -0
  399. package/fabric/package.json +58 -0
  400. package/fabric/rmt-lane-mapping.d.ts +47 -0
  401. package/fabric/rmt-lane-mapping.js +504 -0
  402. package/fabric/xtend-fabric.d.ts +81 -0
  403. package/fabric/xtend-fabric.js +2669 -0
  404. package/fabric/xtend-policy-public-types.d.ts +135 -0
  405. package/package.json +8225 -0
  406. package/security/README.md +54 -0
  407. package/security/manifest-import-policy.d.ts +43 -0
  408. package/security/manifest-import-policy.js +260 -0
  409. package/security/supply-chain-gate-policy.d.ts +45 -0
  410. package/security/supply-chain-gate-policy.js +249 -0
  411. package/security/trusted-dom-policy.d.ts +36 -0
  412. package/security/trusted-dom-policy.js +316 -0
  413. package/tools/package.json +77 -0
  414. package/tools/rmt-editor/vscode/README.md +33 -0
  415. package/tools/rmt-editor/vscode/extension.d.ts +9 -0
  416. package/tools/rmt-editor/vscode/extension.js +55 -0
  417. package/tools/rmt-editor/vscode/language-configuration.json +28 -0
  418. package/tools/rmt-editor/vscode/package.json +83 -0
  419. package/tools/rmt-editor/vscode/snippets/rmt.code-snippets +243 -0
  420. package/tools/rmt-editor/vscode/syntaxes/rmt.tmLanguage.json +13 -0
  421. package/tools/rmt-editor/vscode/xtend-rmt-language-0.0.0-enterprise-readiness.vsix +0 -0
  422. package/tools/rmt-language/code-actions.d.ts +15 -0
  423. package/tools/rmt-language/code-actions.js +566 -0
  424. package/tools/rmt-language/completions.d.ts +22 -0
  425. package/tools/rmt-language/completions.js +475 -0
  426. package/tools/rmt-language/definitions.d.ts +13 -0
  427. package/tools/rmt-language/definitions.js +212 -0
  428. package/tools/rmt-language/diagnostics.d.ts +23 -0
  429. package/tools/rmt-language/diagnostics.js +486 -0
  430. package/tools/rmt-language/format-adapter.d.ts +16 -0
  431. package/tools/rmt-language/format-adapter.js +270 -0
  432. package/tools/rmt-language/hover.d.ts +12 -0
  433. package/tools/rmt-language/hover.js +326 -0
  434. package/tools/rmt-language/kernel-escalation.d.ts +122 -0
  435. package/tools/rmt-language/kernel-escalation.js +427 -0
  436. package/tools/rmt-language/kernel-panic-monitor.d.ts +176 -0
  437. package/tools/rmt-language/kernel-panic-monitor.js +674 -0
  438. package/tools/rmt-language/kernel-policy-parity.d.ts +142 -0
  439. package/tools/rmt-language/kernel-policy-parity.js +629 -0
  440. package/tools/rmt-language/kernel-recovery.d.ts +173 -0
  441. package/tools/rmt-language/kernel-recovery.js +666 -0
  442. package/tools/rmt-language/kernel-scheduler-failure.d.ts +136 -0
  443. package/tools/rmt-language/kernel-scheduler-failure.js +486 -0
  444. package/tools/rmt-language/kernel-security-regression.d.ts +154 -0
  445. package/tools/rmt-language/kernel-security-regression.js +465 -0
  446. package/tools/rmt-language/kernel-trust-authority.d.ts +120 -0
  447. package/tools/rmt-language/kernel-trust-authority.js +549 -0
  448. package/tools/rmt-language/parser.d.ts +14 -0
  449. package/tools/rmt-language/parser.js +111 -0
  450. package/tools/rmt-language/rmt-tooling-public-types.d.ts +179 -0
  451. package/tools/rmt-language/rules/boundary-policy.js +81 -0
  452. package/tools/rmt-language/rules/document-policy.js +65 -0
  453. package/tools/rmt-language/rules/index.js +29 -0
  454. package/tools/rmt-language/rules/route-policy.js +81 -0
  455. package/tools/rmt-language/rules/scheduler-policy.js +66 -0
  456. package/tools/rmt-language/rules/template-policy.js +130 -0
  457. package/tools/rmt-language/semantic-graph.d.ts +18 -0
  458. package/tools/rmt-language/semantic-graph.js +827 -0
  459. package/tools/rmt-language/snippets/README.md +17 -0
  460. package/tools/rmt-language/snippets/index.d.ts +17 -0
  461. package/tools/rmt-language/snippets/index.js +417 -0
  462. package/tools/rmt-language/snippets/rmt.code-snippets +243 -0
  463. package/tools/rmt-language/source-model.d.ts +14 -0
  464. package/tools/rmt-language/source-model.js +731 -0
  465. package/tools/rmt-language/symbols.d.ts +13 -0
  466. package/tools/rmt-language/symbols.js +183 -0
  467. package/tools/rmt-language/vnext-compatibility.d.ts +28 -0
  468. package/tools/rmt-language/vnext-compatibility.js +675 -0
  469. package/tools/rmt-language/vnext-compiler.d.ts +17 -0
  470. package/tools/rmt-language/vnext-compiler.js +716 -0
  471. package/tools/rmt-language/vnext-composition.d.ts +30 -0
  472. package/tools/rmt-language/vnext-composition.js +595 -0
  473. package/tools/rmt-language/vnext-conditions.d.ts +25 -0
  474. package/tools/rmt-language/vnext-conditions.js +474 -0
  475. package/tools/rmt-language/vnext-cross-surface-events.d.ts +30 -0
  476. package/tools/rmt-language/vnext-cross-surface-events.js +607 -0
  477. package/tools/rmt-language/vnext-degradation.d.ts +23 -0
  478. package/tools/rmt-language/vnext-degradation.js +428 -0
  479. package/tools/rmt-language/vnext-enterprise-fixtures.d.ts +28 -0
  480. package/tools/rmt-language/vnext-enterprise-fixtures.js +487 -0
  481. package/tools/rmt-language/vnext-enterprise-registry.d.ts +21 -0
  482. package/tools/rmt-language/vnext-enterprise-registry.js +495 -0
  483. package/tools/rmt-language/vnext-enterprise-release.d.ts +44 -0
  484. package/tools/rmt-language/vnext-enterprise-release.js +472 -0
  485. package/tools/rmt-language/vnext-event-governance.d.ts +29 -0
  486. package/tools/rmt-language/vnext-event-governance.js +488 -0
  487. package/tools/rmt-language/vnext-events.d.ts +44 -0
  488. package/tools/rmt-language/vnext-events.js +680 -0
  489. package/tools/rmt-language/vnext-import-resolver.d.ts +28 -0
  490. package/tools/rmt-language/vnext-import-resolver.js +642 -0
  491. package/tools/rmt-language/vnext-lifecycle.d.ts +22 -0
  492. package/tools/rmt-language/vnext-lifecycle.js +404 -0
  493. package/tools/rmt-language/vnext-parser.d.ts +21 -0
  494. package/tools/rmt-language/vnext-parser.js +1391 -0
  495. package/tools/rmt-language/vnext-regression.d.ts +25 -0
  496. package/tools/rmt-language/vnext-regression.js +394 -0
  497. package/tools/rmt-language/vnext-release.d.ts +29 -0
  498. package/tools/rmt-language/vnext-release.js +293 -0
  499. package/tools/rmt-language/vnext-remote-compatibility.d.ts +33 -0
  500. package/tools/rmt-language/vnext-remote-compatibility.js +892 -0
  501. package/tools/rmt-language/vnext-remote-compiler.d.ts +14 -0
  502. package/tools/rmt-language/vnext-remote-compiler.js +520 -0
  503. package/tools/rmt-language/vnext-remote-manifest.d.ts +33 -0
  504. package/tools/rmt-language/vnext-remote-manifest.js +538 -0
  505. package/tools/rmt-language/vnext-remote-security.d.ts +27 -0
  506. package/tools/rmt-language/vnext-remote-security.js +380 -0
  507. package/tools/rmt-language/vnext-remote-tooling.d.ts +25 -0
  508. package/tools/rmt-language/vnext-remote-tooling.js +805 -0
  509. package/tools/rmt-language/vnext-scheduler.d.ts +24 -0
  510. package/tools/rmt-language/vnext-scheduler.js +469 -0
  511. package/tools/rmt-language/vnext-security.d.ts +28 -0
  512. package/tools/rmt-language/vnext-security.js +597 -0
  513. package/tools/rmt-language/vnext-streaming.d.ts +28 -0
  514. package/tools/rmt-language/vnext-streaming.js +593 -0
  515. package/tools/rmt-language/vnext-surfaces.d.ts +24 -0
  516. package/tools/rmt-language/vnext-surfaces.js +406 -0
  517. package/tools/rmt-language/vnext-tooling.d.ts +25 -0
  518. package/tools/rmt-language/vnext-tooling.js +728 -0
  519. package/tools/rmt-language-server/protocol.d.ts +22 -0
  520. package/tools/rmt-language-server/protocol.js +352 -0
  521. package/tools/rmt-language-server/server.d.ts +15 -0
  522. package/tools/rmt-language-server/server.js +622 -0
  523. package/tools/rmt-linter/cli.d.ts +14 -0
  524. package/tools/rmt-linter/cli.js +450 -0
  525. package/tools/rmt-linter/reporter.d.ts +16 -0
  526. package/tools/rmt-linter/reporter.js +472 -0
  527. package/xtend-builder/README.md +83 -0
  528. package/xtend-builder/a11y/README.md +42 -0
  529. package/xtend-builder/a11y/component-a11y-profile.d.ts +14 -0
  530. package/xtend-builder/a11y/component-a11y-profile.js +314 -0
  531. package/xtend-builder/blueprints/README.md +105 -0
  532. package/xtend-builder/blueprints/component-blueprint.contract.d.ts +16 -0
  533. package/xtend-builder/blueprints/component-blueprint.contract.js +343 -0
  534. package/xtend-builder/builder-public-types.d.ts +234 -0
  535. package/xtend-builder/extensions/README.md +26 -0
  536. package/xtend-builder/extensions/component-extension-points.d.ts +11 -0
  537. package/xtend-builder/extensions/component-extension-points.js +277 -0
  538. package/xtend-builder/generators/README.md +149 -0
  539. package/xtend-builder/generators/component-files.d.ts +5 -0
  540. package/xtend-builder/generators/component-files.js +769 -0
  541. package/xtend-builder/generators/component-plan.d.ts +4 -0
  542. package/xtend-builder/generators/component-plan.js +104 -0
  543. package/xtend-builder/generators/registry.d.ts +6 -0
  544. package/xtend-builder/generators/registry.js +118 -0
  545. package/xtend-builder/generators/rmt-build.js +738 -0
  546. package/xtend-builder/generators/rmt-lifecycle-demo.js +922 -0
  547. package/xtend-builder/lib/cli.d.ts +9 -0
  548. package/xtend-builder/lib/cli.js +543 -0
  549. package/xtend-builder/lib/layout.d.ts +6 -0
  550. package/xtend-builder/lib/layout.js +153 -0
  551. package/xtend-builder/lib/package-resolver.js +25 -0
  552. package/xtend-builder/package.json +90 -0
  553. package/xtend-builder/performance/README.md +31 -0
  554. package/xtend-builder/performance/component-performance-profile.d.ts +11 -0
  555. package/xtend-builder/performance/component-performance-profile.js +347 -0
  556. package/xtend-builder/performance/component-ux-performance-contract.d.ts +27 -0
  557. package/xtend-builder/performance/component-ux-performance-contract.js +424 -0
  558. package/xtend-builder/preview/README.md +61 -0
  559. package/xtend-builder/preview/component-lab-ux-inspector.d.ts +20 -0
  560. package/xtend-builder/preview/component-lab-ux-inspector.js +448 -0
  561. package/xtend-builder/preview/component-lab.d.ts +14 -0
  562. package/xtend-builder/preview/component-lab.js +278 -0
  563. package/xtend-builder/preview/component-preview.d.ts +5 -0
  564. package/xtend-builder/preview/component-preview.js +160 -0
  565. package/xtend-builder/scaffold.config.d.ts +4 -0
  566. package/xtend-builder/scaffold.config.js +2056 -0
  567. package/xtend-builder/scaffold.d.ts +3 -0
  568. package/xtend-builder/scaffold.js +11 -0
  569. package/xtend-builder/templates/README.md +33 -0
  570. package/xtend-builder/templates/component/a11y.template.ts +11 -0
  571. package/xtend-builder/templates/component/component-suite.template.d.ts +2 -0
  572. package/xtend-builder/templates/component/component-suite.template.js +108 -0
  573. package/xtend-builder/templates/component/contract.template.ts +10 -0
  574. package/xtend-builder/templates/component/demo-plan.template.md +73 -0
  575. package/xtend-builder/templates/component/docs.template.md +301 -0
  576. package/xtend-builder/templates/component/fixture-data.template.ts +28 -0
  577. package/xtend-builder/templates/component/fixture.template.html +37 -0
  578. package/xtend-builder/templates/component/manifest-plan.template.json +22 -0
  579. package/xtend-builder/templates/component/performance.template.ts +13 -0
  580. package/xtend-builder/templates/component/rmt.template.ts +12 -0
  581. package/xtend-builder/templates/component/source.template.d.ts +2 -0
  582. package/xtend-builder/templates/component/source.template.js +137 -0
  583. package/xtend-builder/templates/component/source.template.ts +110 -0
  584. package/xtend-builder/templates/component/types.template.d.ts +423 -0
  585. package/xtend-builder/templates/loader.d.ts +4 -0
  586. package/xtend-builder/templates/loader.js +51 -0
  587. package/xtend-builder/templates/registry.d.ts +6 -0
  588. package/xtend-builder/templates/registry.js +119 -0
  589. package/xtend-builder/typing/README.md +130 -0
  590. package/xtend-builder/typing/component-contract-v2.d.ts +15 -0
  591. package/xtend-builder/typing/component-contract-v2.js +248 -0
  592. package/xtend-builder/typing/component-network-contract.d.ts +22 -0
  593. package/xtend-builder/typing/component-network-contract.js +478 -0
  594. package/xtend-builder/typing/component-shell-contract.d.ts +21 -0
  595. package/xtend-builder/typing/component-shell-contract.js +312 -0
  596. package/xtend-builder/typing/component-styling-contract.d.ts +22 -0
  597. package/xtend-builder/typing/component-styling-contract.js +301 -0
  598. package/xtend-builder/typing/component-types.d.ts +10 -0
  599. package/xtend-builder/typing/component-types.js +551 -0
  600. package/xtend-builder/typing/enterprise-component-flex-hardening-contract.d.ts +20 -0
  601. package/xtend-builder/typing/enterprise-component-flex-hardening-contract.js +332 -0
  602. package/xtend-builder/typing/feedback-status-ux-contract.d.ts +25 -0
  603. package/xtend-builder/typing/feedback-status-ux-contract.js +347 -0
  604. package/xtend-builder/typing/form-controls-ux-contract.d.ts +25 -0
  605. package/xtend-builder/typing/form-controls-ux-contract.js +357 -0
  606. package/xtend-builder/typing/layout-display-media-ux-contract.d.ts +25 -0
  607. package/xtend-builder/typing/layout-display-media-ux-contract.js +420 -0
  608. package/xtend-builder/typing/navigation-routing-ux-contract.d.ts +17 -0
  609. package/xtend-builder/typing/navigation-routing-ux-contract.js +297 -0
  610. package/xtend-builder/typing/overlay-interaction-ux-contract.d.ts +25 -0
  611. package/xtend-builder/typing/overlay-interaction-ux-contract.js +383 -0
  612. package/xtend-builder/typing/rmt-dsl-authoring-polish.d.ts +27 -0
  613. package/xtend-builder/typing/rmt-dsl-authoring-polish.js +419 -0
  614. package/xtend-builder/typing/rmt-shell-authoring-contract.d.ts +26 -0
  615. package/xtend-builder/typing/rmt-shell-authoring-contract.js +315 -0
  616. package/xtend-builder/utils/README.md +8 -0
  617. package/xtend-builder/utils/naming.d.ts +7 -0
  618. package/xtend-builder/utils/naming.js +36 -0
  619. package/xtend-builder/utils/validation.d.ts +5 -0
  620. package/xtend-builder/utils/validation.js +95 -0
  621. package/xtend-builder/wiring/README.md +46 -0
  622. package/xtend-builder/wiring/features.d.ts +5 -0
  623. package/xtend-builder/wiring/features.js +165 -0
  624. package/xtend-builder/wiring/hydration.d.ts +4 -0
  625. package/xtend-builder/wiring/hydration.js +44 -0
  626. package/xtend-builder/wiring/manifest.d.ts +5 -0
  627. package/xtend-builder/wiring/manifest.js +48 -0
  628. package/xtend-builder/workflows/README.md +47 -0
  629. package/xtend-builder/workflows/developer-workflow.d.ts +6 -0
  630. package/xtend-builder/workflows/developer-workflow.js +125 -0
  631. package/xtend-builder/writing/manifest-patcher.d.ts +49 -0
  632. package/xtend-builder/writing/manifest-patcher.js +391 -0
  633. package/xtend-builder/writing/write-plan.d.ts +148 -0
  634. package/xtend-builder/writing/write-plan.js +646 -0
  635. package/xtend-dev.d.ts +23 -0
  636. package/xtend-dev.js +4 -0
  637. package/xtend-loader.d.ts +201 -0
  638. package/xtend-loader.js +1704 -0
  639. package/xtend.css +402 -0
  640. package/xtendrmt/package.json +64 -0
  641. package/xtendrmt/rmt-core.d.ts +4452 -0
  642. package/xtendrmt/rmt-core.esm.js +25793 -0
  643. package/xtendrmt/rmt-first-demo-app.js +265 -0
  644. package/xtendrmt/rmt-first-demo-app.rmt +737 -0
  645. package/xtendrmt/rmt-lifecycle-demo.app.js +493 -0
  646. package/xtendrmt/rmt-lifecycle-demo.core.json +810 -0
  647. package/xtendrmt/rmt-lifecycle-demo.rmt +35 -0
  648. package/xtendrmt/rmt-lifecycle-demo.rmt-build.app.js +153 -0
  649. package/xtendrmt/rmt-lifecycle-demo.rmt-build.core.json +810 -0
  650. package/xtendrmt/rmt-lifecycle-demo.rmt-build.scaffold.json +202 -0
  651. package/xtendrmt/rmt-lifecycle-demo.scaffold.json +187 -0
  652. package/xtendrmt/rmt-manifest.json +548 -0
  653. package/xtendrmt/rmt-runtime.browser.js +26183 -0
  654. package/xtendrmt/rmt-runtime.esm.js +26214 -0
  655. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.core.json +849 -0
  656. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.rmt +50 -0
  657. package/xtendrmt/rmt-vnext-reference-demo.core.json +1069 -0
  658. package/xtendrmt/rmt-vnext-reference-demo.rmt +50 -0
  659. package/xtendrmt/rmt.schema.json +3145 -0
  660. package/xtendrmt/surface-workbench.js +316 -0
  661. package/xtendrmt/surface-workbench.rmt +762 -0
  662. package/xtendrmt/xtendrmt-bestcase-demo.core.json +1187 -0
  663. package/xtendrmt/xtendrmt-bestcase-demo.js +1728 -0
  664. package/xtendrmt/xtendrmt-bestcase-demo.rmt +57 -0
@@ -0,0 +1,2669 @@
1
+ (function attachXtendFabric(globalTarget, factory) {
2
+ const api = factory(globalTarget);
3
+
4
+ if (typeof module === 'object' && module.exports) {
5
+ module.exports = api;
6
+ }
7
+
8
+ if (globalTarget && typeof globalTarget === 'object') {
9
+ globalTarget.XTendFabric = Object.freeze({
10
+ schema: api.CONTRACTS.api,
11
+ contracts: api.CONTRACTS,
12
+ createXtendFabric: api.createXtendFabric,
13
+ createNoopReporter: api.createNoopReporter,
14
+ createReporterAdapter: api.createReporterAdapter,
15
+ createConsoleReporter: api.createConsoleReporter,
16
+ createTestReporter: api.createTestReporter,
17
+ normalizeComponentLifecycleTelemetry: api.normalizeComponentLifecycleTelemetry,
18
+ summarizeComponentLifecycleTelemetry: api.summarizeComponentLifecycleTelemetry
19
+ });
20
+ }
21
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function createXtendFabricModule(globalTarget) {
22
+ const CONTRACTS = Object.freeze({
23
+ api: 'xtend.fabric.api.v1',
24
+ diagnostic: 'xtend.fabric.diagnostic.v1',
25
+ reporter: 'xtend.fabric.reporter.v1',
26
+ redaction: 'xtend.fabric.redaction.v1',
27
+ fiber: 'xtend.fabric.fiber.v1',
28
+ lane: 'xtend.fabric.lane.v1',
29
+ lifecycleBoundary: 'xtend.fabric.lifecycle-error-boundary.v1',
30
+ componentFiberInstrumentation: 'xtend.fabric.component-fiber-instrumentation.v1',
31
+ routeFiberInstrumentation: 'xtend.fabric.route-fiber-instrumentation.v1',
32
+ runtimeDiagnosticsBridge: 'xtend.fabric.runtime-diagnostics-bridge.v1',
33
+ telemetrySnapshot: 'xtend.fabric.telemetry-snapshot.v1',
34
+ backpressureSignal: 'xtend.fabric.backpressure-signal.v1',
35
+ performanceMeasurement: 'xtend.performance.measurement.v1',
36
+ componentLifecycleTelemetry: 'xtend.component.lifecycle-telemetry.v1'
37
+ });
38
+ const BROWSER_NAMESPACE = 'window.XTendFabric';
39
+
40
+ const DEFAULT_LANE_BY_KIND = Object.freeze({
41
+ 'loader.manifest': 'user-blocking',
42
+ 'loader.module': 'visible',
43
+ 'component.mount': 'visible',
44
+ 'component.hydrate': 'visible',
45
+ 'component.render': 'visible',
46
+ 'component.update': 'visible',
47
+ 'component.disconnect': 'background',
48
+ 'event.handler': 'user-blocking',
49
+ 'route.navigate': 'user-blocking',
50
+ 'route.render': 'transition',
51
+ 'theme.apply': 'visible',
52
+ 'state.sync': 'user-blocking',
53
+ 'api.call': 'user-blocking',
54
+ 'a11y.announce': 'a11y',
55
+ 'diagnostics.snapshot': 'diagnostics',
56
+ 'rmt.adapter-result': 'diagnostics'
57
+ });
58
+
59
+ const CANONICAL_LANES = Object.freeze({
60
+ 'user-blocking': Object.freeze({
61
+ schema: CONTRACTS.lane,
62
+ id: 'user-blocking',
63
+ priority: 100,
64
+ budgetClass: 'critical',
65
+ deadlineMs: 80,
66
+ preferIdle: false,
67
+ coalescePolicy: 'none'
68
+ }),
69
+ a11y: Object.freeze({
70
+ schema: CONTRACTS.lane,
71
+ id: 'a11y',
72
+ priority: 95,
73
+ budgetClass: 'critical',
74
+ deadlineMs: 80,
75
+ preferIdle: false,
76
+ coalescePolicy: 'stale-announcements'
77
+ }),
78
+ visible: Object.freeze({
79
+ schema: CONTRACTS.lane,
80
+ id: 'visible',
81
+ priority: 80,
82
+ budgetClass: 'interactive',
83
+ deadlineMs: 160,
84
+ preferIdle: false,
85
+ coalescePolicy: 'scope'
86
+ }),
87
+ transition: Object.freeze({
88
+ schema: CONTRACTS.lane,
89
+ id: 'transition',
90
+ priority: 65,
91
+ budgetClass: 'interactive',
92
+ deadlineMs: 240,
93
+ preferIdle: false,
94
+ coalescePolicy: 'route-or-scope'
95
+ }),
96
+ idle: Object.freeze({
97
+ schema: CONTRACTS.lane,
98
+ id: 'idle',
99
+ priority: 35,
100
+ budgetClass: 'background',
101
+ deadlineMs: 500,
102
+ preferIdle: true,
103
+ coalescePolicy: 'coalesce'
104
+ }),
105
+ background: Object.freeze({
106
+ schema: CONTRACTS.lane,
107
+ id: 'background',
108
+ priority: 25,
109
+ budgetClass: 'best_effort',
110
+ deadlineMs: 1000,
111
+ preferIdle: true,
112
+ coalescePolicy: 'coalesce'
113
+ }),
114
+ diagnostics: Object.freeze({
115
+ schema: CONTRACTS.lane,
116
+ id: 'diagnostics',
117
+ priority: 20,
118
+ budgetClass: 'diagnostics',
119
+ deadlineMs: 750,
120
+ preferIdle: true,
121
+ coalescePolicy: 'coalesce'
122
+ })
123
+ });
124
+
125
+ const LIFECYCLE_METHODS = Object.freeze([
126
+ 'connectedCallback',
127
+ 'attributeChangedCallback',
128
+ 'render',
129
+ 'hydrate',
130
+ 'disconnectedCallback'
131
+ ]);
132
+ const COMPONENT_LIFECYCLE_OPERATIONS = Object.freeze([
133
+ 'mount',
134
+ 'hydrate',
135
+ 'render',
136
+ 'update',
137
+ 'event',
138
+ 'unmount',
139
+ 'error'
140
+ ]);
141
+
142
+ const LIFECYCLE_PHASES = Object.freeze({
143
+ connectedCallback: Object.freeze({
144
+ phase: 'connectedCallback',
145
+ fiberKind: 'component.mount',
146
+ lane: 'visible',
147
+ severity: 'error'
148
+ }),
149
+ attributeChangedCallback: Object.freeze({
150
+ phase: 'attributeChangedCallback',
151
+ fiberKind: 'component.update',
152
+ lane: 'visible',
153
+ severity: 'error'
154
+ }),
155
+ render: Object.freeze({
156
+ phase: 'render',
157
+ fiberKind: 'component.render',
158
+ lane: 'visible',
159
+ severity: 'error'
160
+ }),
161
+ hydrate: Object.freeze({
162
+ phase: 'hydrate',
163
+ fiberKind: 'component.hydrate',
164
+ lane: 'visible',
165
+ severity: 'error'
166
+ }),
167
+ disconnectedCallback: Object.freeze({
168
+ phase: 'disconnectedCallback',
169
+ fiberKind: 'component.disconnect',
170
+ lane: 'background',
171
+ severity: 'error'
172
+ }),
173
+ eventHandler: Object.freeze({
174
+ phase: 'eventHandler',
175
+ fiberKind: 'event.handler',
176
+ lane: 'user-blocking',
177
+ severity: 'error'
178
+ })
179
+ });
180
+
181
+ const COMPONENT_FIBER_OPERATION_PROFILES = Object.freeze({
182
+ mount: Object.freeze({
183
+ operation: 'mount',
184
+ kind: 'component.mount',
185
+ phase: 'mount',
186
+ source: 'component',
187
+ lane: 'visible',
188
+ scheduleRef: 'component.visible.mount',
189
+ endpointNameHint: 'xtendrmt.component.mount',
190
+ diagnosticCode: 'xtend.fabric.component.mount.failed',
191
+ diagnosticMessage: 'XTend component mount failed',
192
+ coalesceSuffix: 'mount'
193
+ }),
194
+ hydrate: Object.freeze({
195
+ operation: 'hydrate',
196
+ kind: 'component.hydrate',
197
+ phase: 'hydrate',
198
+ source: 'component',
199
+ lane: 'idle',
200
+ scheduleRef: 'component.idle.hydrate',
201
+ endpointNameHint: 'xtendrmt.component.hydrate',
202
+ diagnosticCode: 'xtend.fabric.component.hydrate.failed',
203
+ diagnosticMessage: 'XTend component hydration failed',
204
+ coalesceSuffix: 'hydrate'
205
+ }),
206
+ preload: Object.freeze({
207
+ operation: 'preload',
208
+ kind: 'loader.module',
209
+ phase: 'preload',
210
+ source: 'loader',
211
+ lane: 'visible',
212
+ scheduleRef: 'component.visible.mount',
213
+ endpointNameHint: 'xtendrmt.component.mount',
214
+ diagnosticCode: 'xtend.fabric.component.preload.failed',
215
+ diagnosticMessage: 'XTend component preload failed',
216
+ coalesceSuffix: 'preload'
217
+ })
218
+ });
219
+
220
+ const ROUTE_FIBER_OPERATION_PROFILES = Object.freeze({
221
+ navigate: Object.freeze({
222
+ operation: 'navigate',
223
+ kind: 'route.navigate',
224
+ phase: 'navigate',
225
+ source: 'router',
226
+ lane: 'user-blocking',
227
+ scheduleRef: 'ui.user-blocking.input',
228
+ endpointNameHint: 'xtendrmt.ui.user-blocking',
229
+ diagnosticCode: 'xtend.fabric.route.navigate.failed',
230
+ diagnosticMessage: 'XTend route navigation failed',
231
+ coalesceSuffix: 'navigate'
232
+ }),
233
+ render: Object.freeze({
234
+ operation: 'render',
235
+ kind: 'route.render',
236
+ phase: 'render',
237
+ source: 'router',
238
+ lane: 'transition',
239
+ scheduleRef: 'route.transition.render',
240
+ endpointNameHint: 'xtendrmt.route.render',
241
+ diagnosticCode: 'xtend.fabric.route.render.failed',
242
+ diagnosticMessage: 'XTend route render failed',
243
+ coalesceSuffix: 'render'
244
+ })
245
+ });
246
+
247
+ const BACKPRESSURE_SCORE_THRESHOLDS = Object.freeze({
248
+ none: 0,
249
+ low: 1,
250
+ medium: 3,
251
+ high: 7,
252
+ critical: 12
253
+ });
254
+
255
+ const BACKPRESSURE_ACTION_BY_LEVEL = Object.freeze({
256
+ none: 'continue',
257
+ low: 'observe',
258
+ medium: 'coalesce-idle-work',
259
+ high: 'defer-background-work',
260
+ critical: 'protect-user-blocking-work'
261
+ });
262
+
263
+ const PERFORMANCE_MEASURE_PHASES = Object.freeze({
264
+ 'xtend.loader.manifest': 'load',
265
+ 'xtend.loader.module': 'load',
266
+ 'xtend.component.define': 'define',
267
+ 'xtend.component.mount': 'mount',
268
+ 'xtend.component.hydrate': 'hydrate',
269
+ 'xtend.component.render': 'render',
270
+ 'xtend.component.update': 'update',
271
+ 'xtend.event.handler': 'event',
272
+ 'xtend.route.navigate': 'route',
273
+ 'xtend.route.render': 'route',
274
+ 'xtend.diagnostics.snapshot': 'diagnostics'
275
+ });
276
+
277
+ const PERFORMANCE_MEASURE_NAME_BY_FIBER_KIND = Object.freeze({
278
+ 'loader.manifest': 'xtend.loader.manifest',
279
+ 'loader.module': 'xtend.loader.module',
280
+ 'component.define': 'xtend.component.define',
281
+ 'component.mount': 'xtend.component.mount',
282
+ 'component.hydrate': 'xtend.component.hydrate',
283
+ 'component.render': 'xtend.component.render',
284
+ 'component.update': 'xtend.component.update',
285
+ 'event.handler': 'xtend.event.handler',
286
+ 'route.navigate': 'xtend.route.navigate',
287
+ 'route.render': 'xtend.route.render',
288
+ 'diagnostics.snapshot': 'xtend.diagnostics.snapshot'
289
+ });
290
+
291
+ const PERFORMANCE_BUDGET_MS_BY_MEASURE = Object.freeze({
292
+ 'xtend.loader.manifest': 40,
293
+ 'xtend.loader.module': 50,
294
+ 'xtend.component.define': 40,
295
+ 'xtend.component.mount': 24,
296
+ 'xtend.component.hydrate': 32,
297
+ 'xtend.component.render': 24,
298
+ 'xtend.component.update': 24,
299
+ 'xtend.event.handler': 16,
300
+ 'xtend.route.navigate': 80,
301
+ 'xtend.route.render': 48,
302
+ 'xtend.diagnostics.snapshot': 750
303
+ });
304
+
305
+ const SENSITIVE_KEY_PATTERN = /(authorization|cookie|csrf|credential|form|header|password|query|secret|session|token)/i;
306
+ const REPORTER_LEVEL_ORDER = Object.freeze({
307
+ debug: 10,
308
+ info: 20,
309
+ warn: 30,
310
+ error: 40,
311
+ fatal: 50
312
+ });
313
+
314
+ let diagnosticCounter = 0;
315
+ let fiberCounter = 0;
316
+
317
+ function nowIso(clock) {
318
+ const value = typeof clock === 'function' ? clock() : new Date();
319
+ if (value instanceof Date) {
320
+ return value.toISOString();
321
+ }
322
+ if (typeof value === 'number') {
323
+ return new Date(value).toISOString();
324
+ }
325
+ return new Date(value || Date.now()).toISOString();
326
+ }
327
+
328
+ function asObject(value) {
329
+ return value && typeof value === 'object' ? value : {};
330
+ }
331
+
332
+ function clampString(value, fallback) {
333
+ return typeof value === 'string' && value.length > 0 ? value : fallback;
334
+ }
335
+
336
+ function normalizeDiagnosticCode(code, fallback = 'xtend.fabric.diagnostic') {
337
+ const value = clampString(code, fallback);
338
+ if (value.startsWith('xtend.')) return value;
339
+ if (value.startsWith('rmt.')) return `xtend.${value}`;
340
+ return value.includes('.') ? value : `xtend.fabric.${value}`;
341
+ }
342
+
343
+ function normalizeError(error, options = {}) {
344
+ if (!error) {
345
+ return null;
346
+ }
347
+
348
+ if (error instanceof Error) {
349
+ const normalized = {
350
+ name: error.name || 'Error',
351
+ message: error.message || 'Unknown error'
352
+ };
353
+ if (options.includeStack !== false && error.stack) {
354
+ normalized.stack = error.stack;
355
+ }
356
+ return normalized;
357
+ }
358
+
359
+ return {
360
+ name: typeof error,
361
+ message: String(error)
362
+ };
363
+ }
364
+
365
+ function isDomNode(value) {
366
+ return value && typeof value === 'object' && typeof value.nodeType === 'number';
367
+ }
368
+
369
+ function redactValue(value, seen = new WeakSet()) {
370
+ if (value == null) {
371
+ return value;
372
+ }
373
+
374
+ if (typeof value === 'function') {
375
+ return '[redacted:function]';
376
+ }
377
+
378
+ if (typeof value !== 'object') {
379
+ return value;
380
+ }
381
+
382
+ if (value instanceof Error) {
383
+ return normalizeError(value);
384
+ }
385
+
386
+ if (isDomNode(value)) {
387
+ return '[redacted:dom-node]';
388
+ }
389
+
390
+ if (seen.has(value)) {
391
+ return '[redacted:circular]';
392
+ }
393
+ seen.add(value);
394
+
395
+ if (Array.isArray(value)) {
396
+ return value.map((entry) => redactValue(entry, seen));
397
+ }
398
+
399
+ return Object.keys(value).reduce((safe, key) => {
400
+ if (SENSITIVE_KEY_PATTERN.test(key)) {
401
+ safe[key] = '[redacted]';
402
+ return safe;
403
+ }
404
+ safe[key] = redactValue(value[key], seen);
405
+ return safe;
406
+ }, {});
407
+ }
408
+
409
+ function redactDiagnostic(event) {
410
+ return {
411
+ ...event,
412
+ schema: CONTRACTS.diagnostic,
413
+ metadata: redactValue(event.metadata || {}),
414
+ cause: event.cause ? redactValue(event.cause) : undefined
415
+ };
416
+ }
417
+
418
+ function toFiniteDuration(value) {
419
+ const number = Number(value);
420
+ return Number.isFinite(number) ? number : 0;
421
+ }
422
+
423
+ function resolvePerformanceMeasureName(name) {
424
+ const entryName = clampString(name, '');
425
+ if (!entryName) return undefined;
426
+ return Object.keys(PERFORMANCE_MEASURE_PHASES).find((measureName) => (
427
+ entryName === measureName || entryName.startsWith(`${measureName}.`)
428
+ ));
429
+ }
430
+
431
+ function resolvePerformancePhase(name, fallback) {
432
+ const measureName = resolvePerformanceMeasureName(name);
433
+ return measureName ? PERFORMANCE_MEASURE_PHASES[measureName] : clampString(fallback, 'runtime');
434
+ }
435
+
436
+ function resolvePerformanceProfile(measureName, options = {}) {
437
+ if (options.performanceProfile) return options.performanceProfile;
438
+ if (!measureName) return 'runtime';
439
+ if (measureName.startsWith('xtend.route.')) return 'routing';
440
+ if (measureName.startsWith('xtend.event.')) return 'interactive';
441
+ if (measureName.startsWith('xtend.component.')) return 'display';
442
+ return 'runtime';
443
+ }
444
+
445
+ function resolvePerformanceBudgetMs(measureName, phase, options = {}) {
446
+ const budgetsByName = asObject(options.performanceBudgetByName);
447
+ const budgetsByPhase = asObject(options.performanceBudgetByPhase);
448
+ const explicit = measureName && Number(budgetsByName[measureName]);
449
+ if (Number.isFinite(explicit)) return explicit;
450
+ const phaseBudget = phase && Number(budgetsByPhase[phase]);
451
+ if (Number.isFinite(phaseBudget)) return phaseBudget;
452
+ const defaultBudget = measureName && PERFORMANCE_BUDGET_MS_BY_MEASURE[measureName];
453
+ return Number.isFinite(Number(defaultBudget)) ? Number(defaultBudget) : 0;
454
+ }
455
+
456
+ function classifyPerformanceStatus(durationMs, budgetMs) {
457
+ if (!Number.isFinite(Number(budgetMs)) || Number(budgetMs) <= 0) return 'pass';
458
+ if (durationMs <= budgetMs) return 'pass';
459
+ if (durationMs <= budgetMs * 1.5) return 'warn';
460
+ return 'fail';
461
+ }
462
+
463
+ function normalizePerformanceEntry(entry) {
464
+ const safeEntry = asObject(entry);
465
+ return {
466
+ name: safeEntry.name,
467
+ entryType: safeEntry.entryType || safeEntry.type,
468
+ startTime: toFiniteDuration(safeEntry.startTime),
469
+ duration: toFiniteDuration(safeEntry.duration)
470
+ };
471
+ }
472
+
473
+ function createPerformanceMeasurement(entry, options = {}, index = 0) {
474
+ const normalized = normalizePerformanceEntry(entry);
475
+ const measureName = resolvePerformanceMeasureName(normalized.name) || normalized.name;
476
+ const phase = resolvePerformancePhase(normalized.name, normalized.entryType);
477
+ const durationMs = toFiniteDuration(normalized.duration);
478
+ const budgetMs = resolvePerformanceBudgetMs(measureName, phase, options);
479
+ return {
480
+ schema: CONTRACTS.performanceMeasurement,
481
+ id: `${options.performanceMeasurementIdPrefix || 'xtend.performance.measurement'}.${index + 1}`,
482
+ name: measureName,
483
+ entryName: normalized.name,
484
+ entryType: normalized.entryType,
485
+ profile: resolvePerformanceProfile(measureName, options),
486
+ componentRef: options.componentRef,
487
+ fiberId: options.fiberId,
488
+ lane: options.lane,
489
+ phase,
490
+ durationMs: Number(durationMs.toFixed(2)),
491
+ budgetMs,
492
+ status: classifyPerformanceStatus(durationMs, budgetMs),
493
+ sampleKind: clampString(options.performanceSampleKind, 'telemetry'),
494
+ metadata: redactValue({
495
+ startTime: Number(toFiniteDuration(normalized.startTime).toFixed(2)),
496
+ source: 'performance-runtime',
497
+ metadata: options.performanceMetadata
498
+ })
499
+ };
500
+ }
501
+
502
+ function summarizePerformanceMeasurements(measurements = []) {
503
+ return measurements.reduce((summary, measurement) => {
504
+ const phase = measurement.phase || 'runtime';
505
+ if (!summary[phase]) {
506
+ summary[phase] = {
507
+ schema: CONTRACTS.performanceMeasurement,
508
+ phase,
509
+ measurementCount: 0,
510
+ durationMs: 0,
511
+ maxDurationMs: 0,
512
+ warnCount: 0,
513
+ failCount: 0,
514
+ names: []
515
+ };
516
+ }
517
+ const phaseSummary = summary[phase];
518
+ const durationMs = toFiniteDuration(measurement.durationMs);
519
+ phaseSummary.measurementCount += 1;
520
+ phaseSummary.durationMs = Number((phaseSummary.durationMs + durationMs).toFixed(2));
521
+ phaseSummary.maxDurationMs = Math.max(phaseSummary.maxDurationMs, durationMs);
522
+ if (measurement.status === 'warn') phaseSummary.warnCount += 1;
523
+ if (measurement.status === 'fail') phaseSummary.failCount += 1;
524
+ if (measurement.name && !phaseSummary.names.includes(measurement.name)) {
525
+ phaseSummary.names.push(measurement.name);
526
+ }
527
+ return summary;
528
+ }, {});
529
+ }
530
+
531
+ function normalizeComponentLifecycleOperation(operation, fallbackOperation = 'update') {
532
+ const requested = clampString(operation, '');
533
+ const aliases = {
534
+ mountComponent: 'mount',
535
+ hydrateComponent: 'hydrate',
536
+ renderComponent: 'render',
537
+ updateComponent: 'update',
538
+ unmountComponent: 'unmount',
539
+ disconnectComponent: 'unmount',
540
+ registerComponent: 'mount',
541
+ connectedCallback: 'mount',
542
+ hydrate: 'hydrate',
543
+ render: 'render',
544
+ attributeChangedCallback: 'update',
545
+ disconnectedCallback: 'unmount',
546
+ eventHandler: 'event',
547
+ emitDiagnostic: 'error',
548
+ captureError: 'error'
549
+ };
550
+ const normalized = aliases[requested] || requested;
551
+ return COMPONENT_LIFECYCLE_OPERATIONS.includes(normalized) ? normalized : fallbackOperation;
552
+ }
553
+
554
+ function normalizeComponentLifecycleStatus(status, ok) {
555
+ const requested = clampString(status, '');
556
+ if (['ok', 'degraded', 'skipped', 'failed'].includes(requested)) {
557
+ return requested;
558
+ }
559
+ if (requested === 'error') return 'failed';
560
+ if (ok === false) return 'failed';
561
+ return 'ok';
562
+ }
563
+
564
+ function normalizeComponentLifecycleTelemetry(recordInput = {}, defaultsInput = {}) {
565
+ const record = asObject(recordInput);
566
+ const defaults = asObject(defaultsInput);
567
+ const fabricContext = asObject(record.fabricContext || record.fabric || defaults.fabricContext || defaults.fabric);
568
+ const metadata = asObject(record.metadata);
569
+ const operation = normalizeComponentLifecycleOperation(record.operation || defaults.operation, 'update');
570
+ const status = normalizeComponentLifecycleStatus(record.status || defaults.status, record.ok);
571
+ const diagnostics = Array.isArray(record.diagnostics)
572
+ ? record.diagnostics
573
+ : (Array.isArray(defaults.diagnostics) ? defaults.diagnostics : []);
574
+ const durationMs = Number(toFiniteDuration(
575
+ Object.prototype.hasOwnProperty.call(record, 'durationMs') ? record.durationMs : defaults.durationMs
576
+ ).toFixed(2));
577
+ const backpressureSignal = record.backpressureSignal
578
+ || defaults.backpressureSignal
579
+ || metadata.backpressureSignal
580
+ || null;
581
+
582
+ return Object.freeze({
583
+ schema: CONTRACTS.componentLifecycleTelemetry,
584
+ id: clampString(record.id, defaults.id || `${defaults.idPrefix || 'xtend.component.telemetry'}.${defaults.index != null ? defaults.index + 1 : 'record'}`),
585
+ timestamp: record.timestamp || defaults.timestamp || nowIso(defaults.clock),
586
+ source: clampString(record.source, defaults.source || 'xtend.component-adapter'),
587
+ operation,
588
+ phase: clampString(record.phase || defaults.phase, operation),
589
+ status,
590
+ ok: status === 'ok' || status === 'degraded',
591
+ adapterId: clampString(record.adapterId || defaults.adapterId, 'xtend.component'),
592
+ componentId: clampString(record.componentId || record.componentRef || defaults.componentId || fabricContext.componentId, ''),
593
+ rmtComponentId: clampString(record.rmtComponentId || record.rmtId || defaults.rmtComponentId || record.componentId || fabricContext.componentId, ''),
594
+ tag: clampString(record.tag || defaults.tag || fabricContext.tag, ''),
595
+ routeRef: clampString(record.routeRef || record.routeId || defaults.routeRef || fabricContext.routeRef, ''),
596
+ scheduleRef: clampString(record.scheduleRef || defaults.scheduleRef || fabricContext.scheduleRef, ''),
597
+ fabricLane: clampString(record.fabricLane || record.lane || defaults.fabricLane || fabricContext.fabricLane || fabricContext.lane, ''),
598
+ rmtLane: clampString(record.rmtLane || defaults.rmtLane || fabricContext.rmtLane || fabricContext.lane, ''),
599
+ fiberKind: clampString(record.fiberKind || defaults.fiberKind || fabricContext.fiberKind, ''),
600
+ endpointNameHint: clampString(record.endpointNameHint || defaults.endpointNameHint || fabricContext.endpointNameHint, ''),
601
+ durationMs,
602
+ diagnosticCount: Number.isFinite(Number(record.diagnosticCount))
603
+ ? Number(record.diagnosticCount)
604
+ : diagnostics.length,
605
+ diagnostics: redactValue(diagnostics),
606
+ backpressureSignal: backpressureSignal ? redactValue(backpressureSignal) : null,
607
+ correlationId: record.correlationId || defaults.correlationId,
608
+ metadata: redactValue(metadata)
609
+ });
610
+ }
611
+
612
+ function normalizeComponentLifecycleTelemetryCollection(records = [], defaults = {}) {
613
+ return (Array.isArray(records) ? records : [])
614
+ .map((record, index) => normalizeComponentLifecycleTelemetry(record, { ...defaults, index }));
615
+ }
616
+
617
+ function createComponentTelemetryBucket(id) {
618
+ return {
619
+ schema: CONTRACTS.componentLifecycleTelemetry,
620
+ id,
621
+ recordCount: 0,
622
+ okCount: 0,
623
+ degradedCount: 0,
624
+ skippedCount: 0,
625
+ failedCount: 0,
626
+ diagnosticCount: 0,
627
+ backpressureSignalCount: 0,
628
+ durationMs: 0,
629
+ maxDurationMs: 0,
630
+ averageDurationMs: 0,
631
+ scheduleRefs: []
632
+ };
633
+ }
634
+
635
+ function summarizeComponentLifecycleTelemetry(records = []) {
636
+ const normalizedRecords = normalizeComponentLifecycleTelemetryCollection(records);
637
+ const summary = {
638
+ schema: CONTRACTS.componentLifecycleTelemetry,
639
+ recordCount: normalizedRecords.length,
640
+ operations: {},
641
+ components: {},
642
+ lanes: {},
643
+ statusCounts: {
644
+ ok: 0,
645
+ degraded: 0,
646
+ skipped: 0,
647
+ failed: 0
648
+ },
649
+ diagnosticCount: 0,
650
+ backpressureSignalCount: 0,
651
+ durationMs: 0,
652
+ maxDurationMs: 0,
653
+ averageDurationMs: 0,
654
+ records: normalizedRecords.slice(-50)
655
+ };
656
+
657
+ COMPONENT_LIFECYCLE_OPERATIONS.forEach((operation) => {
658
+ summary.operations[operation] = createComponentTelemetryBucket(operation);
659
+ });
660
+
661
+ normalizedRecords.forEach((record) => {
662
+ const operationBucket = summary.operations[record.operation] || (summary.operations[record.operation] = createComponentTelemetryBucket(record.operation));
663
+ const componentId = record.componentId || record.tag || 'unknown-component';
664
+ const componentBucket = summary.components[componentId] || (summary.components[componentId] = createComponentTelemetryBucket(componentId));
665
+ const laneId = record.fabricLane || record.rmtLane || 'unassigned';
666
+ const laneBucket = summary.lanes[laneId] || (summary.lanes[laneId] = createComponentTelemetryBucket(laneId));
667
+ const buckets = [operationBucket, componentBucket, laneBucket];
668
+ const durationMs = toFiniteDuration(record.durationMs);
669
+ const statusKey = ['ok', 'degraded', 'skipped', 'failed'].includes(record.status) ? record.status : 'failed';
670
+
671
+ summary.statusCounts[statusKey] += 1;
672
+ summary.diagnosticCount += Number(record.diagnosticCount) || 0;
673
+ summary.backpressureSignalCount += record.backpressureSignal ? 1 : 0;
674
+ summary.durationMs = Number((summary.durationMs + durationMs).toFixed(2));
675
+ summary.maxDurationMs = Math.max(summary.maxDurationMs, durationMs);
676
+
677
+ buckets.forEach((bucket) => {
678
+ bucket.recordCount += 1;
679
+ bucket[`${statusKey}Count`] += 1;
680
+ bucket.diagnosticCount += Number(record.diagnosticCount) || 0;
681
+ bucket.backpressureSignalCount += record.backpressureSignal ? 1 : 0;
682
+ bucket.durationMs = Number((bucket.durationMs + durationMs).toFixed(2));
683
+ bucket.maxDurationMs = Math.max(bucket.maxDurationMs, durationMs);
684
+ if (record.scheduleRef && !bucket.scheduleRefs.includes(record.scheduleRef)) {
685
+ bucket.scheduleRefs.push(record.scheduleRef);
686
+ }
687
+ });
688
+ });
689
+
690
+ Object.keys(summary.operations).forEach((key) => {
691
+ const bucket = summary.operations[key];
692
+ bucket.averageDurationMs = bucket.recordCount > 0 ? Number((bucket.durationMs / bucket.recordCount).toFixed(2)) : 0;
693
+ });
694
+ Object.keys(summary.components).forEach((key) => {
695
+ const bucket = summary.components[key];
696
+ bucket.averageDurationMs = bucket.recordCount > 0 ? Number((bucket.durationMs / bucket.recordCount).toFixed(2)) : 0;
697
+ });
698
+ Object.keys(summary.lanes).forEach((key) => {
699
+ const bucket = summary.lanes[key];
700
+ bucket.averageDurationMs = bucket.recordCount > 0 ? Number((bucket.durationMs / bucket.recordCount).toFixed(2)) : 0;
701
+ });
702
+ summary.averageDurationMs = summary.recordCount > 0 ? Number((summary.durationMs / summary.recordCount).toFixed(2)) : 0;
703
+
704
+ return Object.freeze(summary);
705
+ }
706
+
707
+ function createNoopReporter() {
708
+ return Object.freeze({
709
+ id: 'noop',
710
+ schema: CONTRACTS.reporter,
711
+ kind: 'noop',
712
+ delivery: 'none',
713
+ external: false,
714
+ publish() {},
715
+ flush() {},
716
+ dispose() {}
717
+ });
718
+ }
719
+
720
+ function normalizeReporterLevel(level, fallback = 'debug') {
721
+ return Object.prototype.hasOwnProperty.call(REPORTER_LEVEL_ORDER, level) ? level : fallback;
722
+ }
723
+
724
+ function shouldPublishForLevel(eventLevel, minimumLevel) {
725
+ const eventValue = REPORTER_LEVEL_ORDER[normalizeReporterLevel(eventLevel, 'info')];
726
+ const minimumValue = REPORTER_LEVEL_ORDER[normalizeReporterLevel(minimumLevel, 'debug')];
727
+ return eventValue >= minimumValue;
728
+ }
729
+
730
+ function createReporterAdapter(options = {}) {
731
+ const adapterOptions = asObject(options);
732
+ const sink = adapterOptions.sink || adapterOptions.publish || (adapterOptions.transport && adapterOptions.transport.publish);
733
+ if (typeof sink !== 'function') {
734
+ throw new TypeError('XTend-Fabric reporter adapter requires a sink(event, context) function.');
735
+ }
736
+
737
+ const id = clampString(adapterOptions.id, `reporter.${Date.now()}`);
738
+ const kind = clampString(adapterOptions.kind, 'custom');
739
+ const minimumLevel = normalizeReporterLevel(adapterOptions.minimumLevel || adapterOptions.minLevel || 'debug');
740
+ const enabled = adapterOptions.enabled !== false;
741
+ const filter = typeof adapterOptions.filter === 'function' ? adapterOptions.filter : () => true;
742
+ const mapEvent = typeof adapterOptions.mapEvent === 'function' ? adapterOptions.mapEvent : (event) => event;
743
+ const flush = adapterOptions.flush || (adapterOptions.transport && adapterOptions.transport.flush);
744
+ const dispose = adapterOptions.dispose || (adapterOptions.transport && adapterOptions.transport.dispose);
745
+
746
+ return Object.freeze({
747
+ id,
748
+ schema: CONTRACTS.reporter,
749
+ kind,
750
+ delivery: clampString(adapterOptions.delivery, 'adapter'),
751
+ external: adapterOptions.external === true,
752
+ minimumLevel,
753
+ capabilities: Array.isArray(adapterOptions.capabilities) ? adapterOptions.capabilities.slice() : ['diagnostics'],
754
+ publish(event, context = {}) {
755
+ if (!enabled) return false;
756
+ if (!shouldPublishForLevel(event && (event.severity || event.level), minimumLevel)) return false;
757
+ if (!filter(event, context)) return false;
758
+ const mapped = mapEvent(event, {
759
+ ...context,
760
+ reporterId: id,
761
+ reporterKind: kind,
762
+ reporterSchema: CONTRACTS.reporter
763
+ });
764
+ const safeEvent = redactDiagnostic(asObject(mapped));
765
+ return sink(safeEvent, {
766
+ ...context,
767
+ reporterId: id,
768
+ reporterKind: kind,
769
+ reporterSchema: CONTRACTS.reporter
770
+ });
771
+ },
772
+ flush(reason) {
773
+ return typeof flush === 'function' ? flush(reason) : undefined;
774
+ },
775
+ dispose() {
776
+ return typeof dispose === 'function' ? dispose() : undefined;
777
+ }
778
+ });
779
+ }
780
+
781
+ function createConsoleReporter(options = {}) {
782
+ const reporterOptions = asObject(options);
783
+ const targetConsole = reporterOptions.console || (globalTarget && globalTarget.console);
784
+ const methodByLevel = {
785
+ debug: 'debug',
786
+ info: 'info',
787
+ warn: 'warn',
788
+ error: 'error',
789
+ fatal: 'error',
790
+ ...(reporterOptions.methodByLevel || {})
791
+ };
792
+
793
+ return createReporterAdapter({
794
+ id: reporterOptions.id || 'console',
795
+ kind: 'console',
796
+ delivery: 'local-console',
797
+ external: false,
798
+ minimumLevel: reporterOptions.minimumLevel || reporterOptions.minLevel || 'debug',
799
+ filter: reporterOptions.filter,
800
+ mapEvent: reporterOptions.mapEvent,
801
+ capabilities: ['diagnostics', 'local-console'],
802
+ sink(event) {
803
+ if (!targetConsole) return false;
804
+ const method = methodByLevel[normalizeReporterLevel(event.severity || event.level, 'info')] || 'log';
805
+ const writer = typeof targetConsole[method] === 'function' ? targetConsole[method] : targetConsole.log;
806
+ if (typeof writer !== 'function') return false;
807
+ writer.call(targetConsole, event);
808
+ return true;
809
+ }
810
+ });
811
+ }
812
+
813
+ function createTestReporter(options = {}) {
814
+ const reporterOptions = asObject(options);
815
+ const events = Array.isArray(reporterOptions.events) ? reporterOptions.events : [];
816
+ const adapter = createReporterAdapter({
817
+ id: reporterOptions.id || 'test',
818
+ kind: 'test',
819
+ delivery: 'memory',
820
+ external: false,
821
+ minimumLevel: reporterOptions.minimumLevel || reporterOptions.minLevel || 'debug',
822
+ filter: reporterOptions.filter,
823
+ mapEvent: reporterOptions.mapEvent,
824
+ capabilities: ['diagnostics', 'memory'],
825
+ sink(event) {
826
+ events.push(event);
827
+ return true;
828
+ },
829
+ flush() {
830
+ return events.slice();
831
+ },
832
+ dispose() {
833
+ if (reporterOptions.clearOnDispose === true) {
834
+ events.splice(0, events.length);
835
+ }
836
+ }
837
+ });
838
+
839
+ return Object.freeze({
840
+ ...adapter,
841
+ getEvents() {
842
+ return events.slice();
843
+ },
844
+ clear() {
845
+ events.splice(0, events.length);
846
+ }
847
+ });
848
+ }
849
+
850
+ function normalizeReporter(reporter) {
851
+ if (!reporter || typeof reporter.publish !== 'function') {
852
+ throw new TypeError('XTend-Fabric reporter requires a publish(event, context) function.');
853
+ }
854
+
855
+ return {
856
+ id: clampString(reporter.id, `reporter.${Date.now()}`),
857
+ schema: clampString(reporter.schema, CONTRACTS.reporter),
858
+ kind: clampString(reporter.kind, 'custom'),
859
+ delivery: clampString(reporter.delivery, 'adapter'),
860
+ external: reporter.external === true,
861
+ capabilities: Array.isArray(reporter.capabilities) ? reporter.capabilities.slice() : ['diagnostics'],
862
+ publish: reporter.publish.bind(reporter),
863
+ flush: typeof reporter.flush === 'function' ? reporter.flush.bind(reporter) : () => {},
864
+ dispose: typeof reporter.dispose === 'function' ? reporter.dispose.bind(reporter) : () => {}
865
+ };
866
+ }
867
+
868
+ function normalizeDiagnostic(input = {}, defaults = {}, clock) {
869
+ const event = asObject(input);
870
+ const context = asObject(defaults);
871
+ const severity = ['debug', 'info', 'warn', 'error', 'fatal'].includes(event.severity)
872
+ ? event.severity
873
+ : (['debug', 'info', 'warn', 'error', 'fatal'].includes(event.level) ? event.level : (context.severity || context.level || 'info'));
874
+
875
+ return {
876
+ schema: CONTRACTS.diagnostic,
877
+ id: clampString(event.id, `${context.idPrefix || 'fabric.diagnostic'}.${++diagnosticCounter}`),
878
+ timestamp: clampString(event.timestamp, nowIso(clock)),
879
+ level: severity,
880
+ severity,
881
+ code: normalizeDiagnosticCode(event.code, context.code || 'xtend.fabric.diagnostic'),
882
+ message: clampString(event.message, context.message || 'XTend-Fabric diagnostic'),
883
+ source: clampString(event.source, context.source || 'fabric'),
884
+ phase: clampString(event.phase, context.phase || 'diagnose'),
885
+ component: event.component || context.component || event.componentRef || context.componentRef,
886
+ componentRef: event.componentRef || context.componentRef,
887
+ fiberId: event.fiberId || context.fiberId,
888
+ lane: event.lane || context.lane,
889
+ correlationId: event.correlationId || context.correlationId,
890
+ routeRef: event.routeRef || context.routeRef,
891
+ scheduleRef: event.scheduleRef || context.scheduleRef,
892
+ metadata: event.metadata || context.metadata || {},
893
+ cause: event.cause || context.cause
894
+ };
895
+ }
896
+
897
+ function inferLane(kind, lane) {
898
+ if (lane && CANONICAL_LANES[lane]) {
899
+ return lane;
900
+ }
901
+ return DEFAULT_LANE_BY_KIND[kind] || 'visible';
902
+ }
903
+
904
+ function resolveComponentFiberOperationProfile(operation) {
905
+ const operationName = clampString(operation, 'mount');
906
+ if (COMPONENT_FIBER_OPERATION_PROFILES[operationName]) {
907
+ return COMPONENT_FIBER_OPERATION_PROFILES[operationName];
908
+ }
909
+ return Object.freeze({
910
+ operation: operationName,
911
+ kind: `component.${operationName}`,
912
+ phase: operationName,
913
+ source: 'component',
914
+ lane: DEFAULT_LANE_BY_KIND[`component.${operationName}`] || 'visible',
915
+ scheduleRef: undefined,
916
+ endpointNameHint: undefined,
917
+ diagnosticCode: `xtend.fabric.component.${operationName}.failed`,
918
+ diagnosticMessage: `XTend component ${operationName} failed`,
919
+ coalesceSuffix: operationName
920
+ });
921
+ }
922
+
923
+ function resolveRouteFiberOperationProfile(operation) {
924
+ const operationName = clampString(operation, 'render');
925
+ if (ROUTE_FIBER_OPERATION_PROFILES[operationName]) {
926
+ return ROUTE_FIBER_OPERATION_PROFILES[operationName];
927
+ }
928
+ return Object.freeze({
929
+ operation: operationName,
930
+ kind: operationName === 'navigate' ? 'route.navigate' : `route.${operationName}`,
931
+ phase: operationName,
932
+ source: 'router',
933
+ lane: DEFAULT_LANE_BY_KIND[`route.${operationName}`] || 'transition',
934
+ scheduleRef: undefined,
935
+ endpointNameHint: undefined,
936
+ diagnosticCode: `xtend.fabric.route.${operationName}.failed`,
937
+ diagnosticMessage: `XTend route ${operationName} failed`,
938
+ coalesceSuffix: operationName
939
+ });
940
+ }
941
+
942
+ function normalizeFiber(input = {}, defaults = {}, clock) {
943
+ const candidate = asObject(input);
944
+ const context = asObject(defaults);
945
+ const kind = clampString(candidate.kind, context.kind || 'app.task');
946
+ const lane = inferLane(kind, candidate.lane || context.lane);
947
+
948
+ return {
949
+ schema: CONTRACTS.fiber,
950
+ id: clampString(candidate.id, `${context.idPrefix || 'fiber'}.${++fiberCounter}`),
951
+ kind,
952
+ lane,
953
+ phase: clampString(candidate.phase, context.phase || 'run'),
954
+ status: clampString(candidate.status, context.status || 'planned'),
955
+ source: clampString(candidate.source, context.source || 'app'),
956
+ scope: clampString(candidate.scope, context.scope || kind),
957
+ componentRef: candidate.componentRef || context.componentRef,
958
+ routeRef: candidate.routeRef || context.routeRef,
959
+ scheduleRef: candidate.scheduleRef || context.scheduleRef,
960
+ endpointNameHint: candidate.endpointNameHint || context.endpointNameHint,
961
+ fiberParentId: candidate.fiberParentId || context.fiberParentId,
962
+ correlationId: candidate.correlationId || context.correlationId,
963
+ budgetClass: candidate.budgetClass || context.budgetClass || CANONICAL_LANES[lane].budgetClass,
964
+ deadlineMs: candidate.deadlineMs || context.deadlineMs || CANONICAL_LANES[lane].deadlineMs,
965
+ preferIdle: typeof candidate.preferIdle === 'boolean' ? candidate.preferIdle : CANONICAL_LANES[lane].preferIdle,
966
+ coalesceKey: candidate.coalesceKey || context.coalesceKey,
967
+ startedAt: candidate.startedAt || context.startedAt,
968
+ endedAt: candidate.endedAt || context.endedAt,
969
+ durationMs: candidate.durationMs || context.durationMs,
970
+ result: candidate.result || context.result,
971
+ severity: candidate.severity || context.severity,
972
+ diagnosticCode: candidate.diagnosticCode || context.diagnosticCode,
973
+ diagnosticMessage: candidate.diagnosticMessage || context.diagnosticMessage,
974
+ diagnostics: Array.isArray(candidate.diagnostics) ? candidate.diagnostics.slice() : [],
975
+ metadata: redactValue(candidate.metadata || context.metadata || {})
976
+ };
977
+ }
978
+
979
+ function resolveLifecyclePhase(phase) {
980
+ const phaseName = clampString(phase, 'lifecycle');
981
+ if (LIFECYCLE_PHASES[phaseName]) {
982
+ return LIFECYCLE_PHASES[phaseName];
983
+ }
984
+ if (phaseName === 'event' || phaseName === 'event.handler' || phaseName.startsWith('on') || phaseName.startsWith('handle')) {
985
+ return {
986
+ ...LIFECYCLE_PHASES.eventHandler,
987
+ phase: phaseName
988
+ };
989
+ }
990
+ return Object.freeze({
991
+ phase: phaseName,
992
+ fiberKind: `component.${phaseName}`,
993
+ lane: 'visible',
994
+ severity: 'error'
995
+ });
996
+ }
997
+
998
+ function createXtendFabric(options = {}) {
999
+ const config = {
1000
+ idPrefix: options.idPrefix || 'xtend.fabric',
1001
+ storeLimit: Number.isInteger(options.storeLimit) ? options.storeLimit : 200,
1002
+ clock: options.clock || options.now,
1003
+ includeStack: options.includeStack !== false,
1004
+ performance: options.performance || options.performanceTarget || null,
1005
+ markPerformance: options.markPerformance !== false,
1006
+ window: options.window || (globalTarget && globalTarget.window ? globalTarget.window : null)
1007
+ };
1008
+ const diagnostics = [];
1009
+ const fibers = [];
1010
+ const componentTelemetry = [];
1011
+ const reporters = [createNoopReporter()];
1012
+ let telemetrySnapshotCounter = 0;
1013
+
1014
+ function trimStore(store) {
1015
+ while (store.length > config.storeLimit) {
1016
+ store.shift();
1017
+ }
1018
+ }
1019
+
1020
+ function dispatchDiagnostic(event) {
1021
+ const targetWindow = config.window;
1022
+ if (!targetWindow || typeof targetWindow.dispatchEvent !== 'function' || typeof targetWindow.CustomEvent !== 'function') {
1023
+ return;
1024
+ }
1025
+ targetWindow.dispatchEvent(new targetWindow.CustomEvent('xtend-fabric-diagnostic', { detail: event }));
1026
+ }
1027
+
1028
+ function emitDiagnostic(event = {}) {
1029
+ const normalized = redactDiagnostic(normalizeDiagnostic(event, { idPrefix: config.idPrefix }, config.clock));
1030
+ diagnostics.push(normalized);
1031
+ trimStore(diagnostics);
1032
+ dispatchDiagnostic(normalized);
1033
+
1034
+ reporters.forEach((reporter) => {
1035
+ try {
1036
+ reporter.publish(normalized, { fabric, reporterId: reporter.id });
1037
+ } catch (error) {
1038
+ diagnostics.push(redactDiagnostic(normalizeDiagnostic({
1039
+ level: 'error',
1040
+ code: 'xtend.fabric.reporter.failed',
1041
+ message: `Fabric reporter ${reporter.id} failed`,
1042
+ source: 'fabric',
1043
+ phase: 'report',
1044
+ cause: normalizeError(error, { includeStack: config.includeStack })
1045
+ }, { idPrefix: config.idPrefix }, config.clock)));
1046
+ trimStore(diagnostics);
1047
+ }
1048
+ });
1049
+
1050
+ return normalized;
1051
+ }
1052
+
1053
+ function captureError(error, context = {}) {
1054
+ const safeContext = asObject(context);
1055
+ return emitDiagnostic({
1056
+ level: safeContext.level || 'error',
1057
+ severity: safeContext.severity || safeContext.level || 'error',
1058
+ code: safeContext.code || 'xtend.fabric.error.captured',
1059
+ message: safeContext.message || (error && error.message ? error.message : 'XTend-Fabric captured an error'),
1060
+ source: safeContext.source || 'fabric',
1061
+ phase: safeContext.phase || 'error',
1062
+ componentRef: safeContext.componentRef,
1063
+ fiberId: safeContext.fiberId,
1064
+ lane: safeContext.lane,
1065
+ correlationId: safeContext.correlationId,
1066
+ routeRef: safeContext.routeRef,
1067
+ scheduleRef: safeContext.scheduleRef,
1068
+ metadata: safeContext.metadata || {},
1069
+ cause: normalizeError(error, { includeStack: config.includeStack })
1070
+ });
1071
+ }
1072
+
1073
+ function getPerformanceTarget() {
1074
+ return config.performance
1075
+ || (config.window && config.window.performance)
1076
+ || null;
1077
+ }
1078
+
1079
+ function startPerformanceMeasurement(fiber) {
1080
+ if (!config.markPerformance) return null;
1081
+ const target = getPerformanceTarget();
1082
+ const measureName = PERFORMANCE_MEASURE_NAME_BY_FIBER_KIND[fiber.kind];
1083
+ if (!target || !measureName || typeof target.mark !== 'function') {
1084
+ return null;
1085
+ }
1086
+
1087
+ const startMark = `${measureName}.start.${fiber.id}`;
1088
+ try {
1089
+ target.mark(startMark);
1090
+ return { target, measureName, startMark };
1091
+ } catch (_) {
1092
+ return null;
1093
+ }
1094
+ }
1095
+
1096
+ function finishPerformanceMeasurement(measurement, fiber) {
1097
+ if (!measurement || !measurement.target) return;
1098
+ const { target, measureName, startMark } = measurement;
1099
+ const endMark = `${measureName}.end.${fiber.id}`;
1100
+ try {
1101
+ if (typeof target.mark === 'function') {
1102
+ target.mark(endMark);
1103
+ }
1104
+ if (typeof target.measure === 'function') {
1105
+ target.measure(measureName, startMark, endMark);
1106
+ }
1107
+ } catch (_) {
1108
+ // Embedded hosts may provide partial Performance APIs; Fibers remain authoritative.
1109
+ }
1110
+ }
1111
+
1112
+ function finishFiber(fiber, status, result, diagnosticsForFiber = []) {
1113
+ const endedAt = nowIso(config.clock);
1114
+ const started = Date.parse(fiber.startedAt || endedAt);
1115
+ const ended = Date.parse(endedAt);
1116
+ const completed = {
1117
+ ...fiber,
1118
+ status,
1119
+ endedAt,
1120
+ durationMs: Number.isFinite(started) && Number.isFinite(ended) ? Math.max(0, ended - started) : 0,
1121
+ result,
1122
+ diagnostics: diagnosticsForFiber
1123
+ };
1124
+ fibers.push(completed);
1125
+ trimStore(fibers);
1126
+ return completed;
1127
+ }
1128
+
1129
+ function runFiber(fiberInput, callback) {
1130
+ if (typeof callback !== 'function') {
1131
+ throw new TypeError('fabric.runFiber requires a callback.');
1132
+ }
1133
+
1134
+ const runningFiber = normalizeFiber(fiberInput, {
1135
+ idPrefix: `${config.idPrefix}.fiber`,
1136
+ status: 'running'
1137
+ }, config.clock);
1138
+ runningFiber.startedAt = runningFiber.startedAt || nowIso(config.clock);
1139
+ const performanceMeasurement = startPerformanceMeasurement(runningFiber);
1140
+
1141
+ try {
1142
+ const value = callback(runningFiber);
1143
+ if (value && typeof value.then === 'function') {
1144
+ return value.then((resolved) => {
1145
+ const completedFiber = finishFiber(runningFiber, 'completed', 'ok');
1146
+ finishPerformanceMeasurement(performanceMeasurement, completedFiber);
1147
+ return resolved;
1148
+ }, (error) => {
1149
+ const diagnostic = captureError(error, {
1150
+ code: runningFiber.diagnosticCode || 'xtend.fabric.fiber.failed',
1151
+ message: runningFiber.diagnosticMessage || `Fabric fiber ${runningFiber.id} failed`,
1152
+ level: runningFiber.severity || 'error',
1153
+ severity: runningFiber.severity || 'error',
1154
+ source: runningFiber.source,
1155
+ phase: runningFiber.phase,
1156
+ componentRef: runningFiber.componentRef,
1157
+ fiberId: runningFiber.id,
1158
+ lane: runningFiber.lane,
1159
+ correlationId: runningFiber.correlationId,
1160
+ routeRef: runningFiber.routeRef,
1161
+ scheduleRef: runningFiber.scheduleRef,
1162
+ metadata: runningFiber.metadata
1163
+ });
1164
+ const failedFiber = finishFiber(runningFiber, 'failed', 'error', [diagnostic]);
1165
+ finishPerformanceMeasurement(performanceMeasurement, failedFiber);
1166
+ throw error;
1167
+ });
1168
+ }
1169
+ const completedFiber = finishFiber(runningFiber, 'completed', 'ok');
1170
+ finishPerformanceMeasurement(performanceMeasurement, completedFiber);
1171
+ return value;
1172
+ } catch (error) {
1173
+ const diagnostic = captureError(error, {
1174
+ code: runningFiber.diagnosticCode || 'xtend.fabric.fiber.failed',
1175
+ message: runningFiber.diagnosticMessage || `Fabric fiber ${runningFiber.id} failed`,
1176
+ level: runningFiber.severity || 'error',
1177
+ severity: runningFiber.severity || 'error',
1178
+ source: runningFiber.source,
1179
+ phase: runningFiber.phase,
1180
+ componentRef: runningFiber.componentRef,
1181
+ fiberId: runningFiber.id,
1182
+ lane: runningFiber.lane,
1183
+ correlationId: runningFiber.correlationId,
1184
+ routeRef: runningFiber.routeRef,
1185
+ scheduleRef: runningFiber.scheduleRef,
1186
+ metadata: runningFiber.metadata
1187
+ });
1188
+ const failedFiber = finishFiber(runningFiber, 'failed', 'error', [diagnostic]);
1189
+ finishPerformanceMeasurement(performanceMeasurement, failedFiber);
1190
+ throw error;
1191
+ }
1192
+ }
1193
+
1194
+ function backpressureLevelForScore(score, explicitLevel) {
1195
+ const requestedLevel = clampString(explicitLevel, '');
1196
+ if (Object.prototype.hasOwnProperty.call(BACKPRESSURE_SCORE_THRESHOLDS, requestedLevel)) {
1197
+ return requestedLevel;
1198
+ }
1199
+ const numericScore = Number.isFinite(Number(score)) ? Number(score) : 0;
1200
+ if (numericScore >= BACKPRESSURE_SCORE_THRESHOLDS.critical) return 'critical';
1201
+ if (numericScore >= BACKPRESSURE_SCORE_THRESHOLDS.high) return 'high';
1202
+ if (numericScore >= BACKPRESSURE_SCORE_THRESHOLDS.medium) return 'medium';
1203
+ if (numericScore >= BACKPRESSURE_SCORE_THRESHOLDS.low) return 'low';
1204
+ return 'none';
1205
+ }
1206
+
1207
+ function severityScoreForBackpressureLevel(level) {
1208
+ switch (level) {
1209
+ case 'critical':
1210
+ return 12;
1211
+ case 'high':
1212
+ return 7;
1213
+ case 'medium':
1214
+ return 3;
1215
+ case 'low':
1216
+ return 1;
1217
+ default:
1218
+ return 0;
1219
+ }
1220
+ }
1221
+
1222
+ function createBackpressureSignal(signalInput = {}, signalDefaults = {}) {
1223
+ const signal = asObject(signalInput);
1224
+ const defaults = asObject(signalDefaults);
1225
+ const lane = inferLane(signal.kind || defaults.kind || 'diagnostics.snapshot', signal.lane || defaults.lane);
1226
+ const score = Number.isFinite(Number(signal.score))
1227
+ ? Number(signal.score)
1228
+ : Number.isFinite(Number(defaults.score)) ? Number(defaults.score) : 0;
1229
+ const level = backpressureLevelForScore(score, signal.level || defaults.level);
1230
+ return Object.freeze({
1231
+ schema: CONTRACTS.backpressureSignal,
1232
+ id: clampString(signal.id, `${config.idPrefix}.backpressure.${++telemetrySnapshotCounter}`),
1233
+ timestamp: signal.timestamp || nowIso(config.clock),
1234
+ level,
1235
+ score: Math.max(score, severityScoreForBackpressureLevel(level)),
1236
+ action: signal.action || defaults.action || BACKPRESSURE_ACTION_BY_LEVEL[level],
1237
+ lane,
1238
+ source: clampString(signal.source, defaults.source || 'fabric'),
1239
+ reason: clampString(signal.reason, defaults.reason || 'backpressure'),
1240
+ componentRef: signal.componentRef || defaults.componentRef,
1241
+ routeRef: signal.routeRef || defaults.routeRef,
1242
+ scheduleRef: signal.scheduleRef || defaults.scheduleRef,
1243
+ fiberId: signal.fiberId || defaults.fiberId,
1244
+ correlationId: signal.correlationId || defaults.correlationId,
1245
+ metadata: redactValue(signal.metadata || defaults.metadata || {})
1246
+ });
1247
+ }
1248
+
1249
+ function recordComponentTelemetry(recordInput = {}, defaultsInput = {}) {
1250
+ const input = asObject(recordInput);
1251
+ const record = normalizeComponentLifecycleTelemetry(input, {
1252
+ idPrefix: `${config.idPrefix}.componentTelemetry`,
1253
+ id: input.id || `${config.idPrefix}.componentTelemetry.${++telemetrySnapshotCounter}`,
1254
+ clock: config.clock,
1255
+ source: input.source || 'fabric',
1256
+ ...asObject(defaultsInput)
1257
+ });
1258
+ componentTelemetry.push(record);
1259
+ trimStore(componentTelemetry);
1260
+ return record;
1261
+ }
1262
+
1263
+ function numericDuration(value) {
1264
+ const number = Number(value);
1265
+ return Number.isFinite(number) ? number : 0;
1266
+ }
1267
+
1268
+ function createLaneTelemetrySummary(laneId) {
1269
+ const lane = CANONICAL_LANES[laneId] || CANONICAL_LANES.visible;
1270
+ return {
1271
+ schema: CONTRACTS.lane,
1272
+ lane: laneId,
1273
+ priority: lane.priority,
1274
+ budgetClass: lane.budgetClass,
1275
+ deadlineMs: lane.deadlineMs,
1276
+ preferIdle: lane.preferIdle,
1277
+ fiberCount: 0,
1278
+ completedCount: 0,
1279
+ failedCount: 0,
1280
+ budgetMissCount: 0,
1281
+ durationMs: 0,
1282
+ maxDurationMs: 0,
1283
+ averageDurationMs: 0,
1284
+ scheduleRefs: []
1285
+ };
1286
+ }
1287
+
1288
+ function summarizeFibersForTelemetry(fiberRecords = []) {
1289
+ const lanes = {};
1290
+ Object.keys(CANONICAL_LANES).forEach((laneId) => {
1291
+ lanes[laneId] = createLaneTelemetrySummary(laneId);
1292
+ });
1293
+ const totals = {
1294
+ fiberCount: 0,
1295
+ completedCount: 0,
1296
+ failedCount: 0,
1297
+ budgetMissCount: 0,
1298
+ durationMs: 0,
1299
+ maxDurationMs: 0,
1300
+ averageDurationMs: 0
1301
+ };
1302
+
1303
+ fiberRecords.forEach((fiberRecord) => {
1304
+ const fiber = asObject(fiberRecord);
1305
+ const laneId = inferLane(fiber.kind, fiber.lane);
1306
+ const lane = lanes[laneId] || (lanes[laneId] = createLaneTelemetrySummary(laneId));
1307
+ const durationMs = numericDuration(fiber.durationMs);
1308
+ const deadlineMs = Number.isFinite(Number(fiber.deadlineMs))
1309
+ ? Number(fiber.deadlineMs)
1310
+ : (CANONICAL_LANES[laneId] || CANONICAL_LANES.visible).deadlineMs;
1311
+ const budgetMiss = durationMs > deadlineMs;
1312
+
1313
+ lane.fiberCount += 1;
1314
+ lane.durationMs += durationMs;
1315
+ lane.maxDurationMs = Math.max(lane.maxDurationMs, durationMs);
1316
+ if (fiber.status === 'failed') lane.failedCount += 1;
1317
+ if (fiber.status === 'completed') lane.completedCount += 1;
1318
+ if (budgetMiss) lane.budgetMissCount += 1;
1319
+ if (fiber.scheduleRef && !lane.scheduleRefs.includes(fiber.scheduleRef)) {
1320
+ lane.scheduleRefs.push(fiber.scheduleRef);
1321
+ }
1322
+
1323
+ totals.fiberCount += 1;
1324
+ totals.durationMs += durationMs;
1325
+ totals.maxDurationMs = Math.max(totals.maxDurationMs, durationMs);
1326
+ if (fiber.status === 'failed') totals.failedCount += 1;
1327
+ if (fiber.status === 'completed') totals.completedCount += 1;
1328
+ if (budgetMiss) totals.budgetMissCount += 1;
1329
+ });
1330
+
1331
+ Object.keys(lanes).forEach((laneId) => {
1332
+ const lane = lanes[laneId];
1333
+ lane.averageDurationMs = lane.fiberCount > 0 ? Number((lane.durationMs / lane.fiberCount).toFixed(2)) : 0;
1334
+ });
1335
+ totals.averageDurationMs = totals.fiberCount > 0 ? Number((totals.durationMs / totals.fiberCount).toFixed(2)) : 0;
1336
+
1337
+ return { lanes, totals };
1338
+ }
1339
+
1340
+ function collectBackpressureSignals(fiberRecords = [], diagnosticRecords = [], snapshotOptions = {}) {
1341
+ const options = asObject(snapshotOptions);
1342
+ const signals = [];
1343
+
1344
+ fiberRecords.forEach((fiberRecord) => {
1345
+ const fiber = asObject(fiberRecord);
1346
+ const durationMs = numericDuration(fiber.durationMs);
1347
+ const lane = inferLane(fiber.kind, fiber.lane);
1348
+ const deadlineMs = Number.isFinite(Number(fiber.deadlineMs))
1349
+ ? Number(fiber.deadlineMs)
1350
+ : (CANONICAL_LANES[lane] || CANONICAL_LANES.visible).deadlineMs;
1351
+ const base = {
1352
+ lane,
1353
+ fiberId: fiber.id,
1354
+ componentRef: fiber.componentRef,
1355
+ routeRef: fiber.routeRef,
1356
+ scheduleRef: fiber.scheduleRef,
1357
+ correlationId: fiber.correlationId,
1358
+ metadata: {
1359
+ kind: fiber.kind,
1360
+ phase: fiber.phase,
1361
+ durationMs,
1362
+ deadlineMs
1363
+ }
1364
+ };
1365
+
1366
+ if (fiber.status === 'failed') {
1367
+ signals.push(createBackpressureSignal({
1368
+ ...base,
1369
+ source: fiber.source || 'fiber',
1370
+ reason: 'fiber-failed',
1371
+ score: 4,
1372
+ level: 'medium'
1373
+ }));
1374
+ }
1375
+
1376
+ if (durationMs > deadlineMs) {
1377
+ const overshootRatio = deadlineMs > 0 ? durationMs / deadlineMs : durationMs;
1378
+ signals.push(createBackpressureSignal({
1379
+ ...base,
1380
+ source: fiber.source || 'fiber',
1381
+ reason: 'deadline-exceeded',
1382
+ score: Math.max(1, Math.ceil(overshootRatio)),
1383
+ level: overshootRatio >= 3 ? 'high' : 'medium'
1384
+ }));
1385
+ }
1386
+
1387
+ const signalMetadata = asObject(fiber.metadata).backpressureSignal;
1388
+ if (signalMetadata) {
1389
+ signals.push(createBackpressureSignal(
1390
+ typeof signalMetadata === 'object' ? signalMetadata : { reason: String(signalMetadata) },
1391
+ {
1392
+ ...base,
1393
+ source: fiber.source || 'fiber',
1394
+ reason: 'fiber-backpressure-signal',
1395
+ score: 2
1396
+ }
1397
+ ));
1398
+ }
1399
+ });
1400
+
1401
+ diagnosticRecords.forEach((record) => {
1402
+ const diagnostic = asObject(record);
1403
+ const metadata = asObject(diagnostic.metadata);
1404
+ const signal = diagnostic.backpressureSignal || metadata.backpressureSignal || metadata.metadata && metadata.metadata.backpressureSignal;
1405
+ if (signal) {
1406
+ signals.push(createBackpressureSignal(
1407
+ typeof signal === 'object' ? signal : { reason: String(signal) },
1408
+ {
1409
+ source: diagnostic.source || 'diagnostic',
1410
+ lane: diagnostic.lane || metadata.lane,
1411
+ reason: 'diagnostic-backpressure-signal',
1412
+ score: 2,
1413
+ componentRef: diagnostic.componentRef || metadata.componentRef,
1414
+ routeRef: diagnostic.routeRef || metadata.routeRef || metadata.routeId,
1415
+ scheduleRef: diagnostic.scheduleRef || metadata.scheduleRef,
1416
+ fiberId: diagnostic.fiberId || metadata.fiberId,
1417
+ correlationId: diagnostic.correlationId || metadata.correlationId,
1418
+ metadata: {
1419
+ diagnosticCode: diagnostic.code
1420
+ }
1421
+ }
1422
+ ));
1423
+ }
1424
+ });
1425
+
1426
+ const componentTelemetryRecords = normalizeComponentLifecycleTelemetryCollection(
1427
+ options.componentTelemetry || options.componentLifecycle || options.componentLifecycleTelemetry,
1428
+ {
1429
+ idPrefix: `${config.idPrefix}.componentTelemetry`,
1430
+ clock: config.clock
1431
+ }
1432
+ );
1433
+ componentTelemetryRecords.forEach((record) => {
1434
+ const lane = inferLane(record.fiberKind || 'component.update', record.fabricLane || record.rmtLane);
1435
+ const laneDeadline = (CANONICAL_LANES[lane] || CANONICAL_LANES.visible).deadlineMs;
1436
+ const base = {
1437
+ lane,
1438
+ componentRef: record.componentId,
1439
+ routeRef: record.routeRef,
1440
+ scheduleRef: record.scheduleRef,
1441
+ fiberId: record.fiberKind,
1442
+ correlationId: record.correlationId,
1443
+ metadata: {
1444
+ operation: record.operation,
1445
+ phase: record.phase,
1446
+ durationMs: record.durationMs,
1447
+ deadlineMs: laneDeadline,
1448
+ telemetryId: record.id
1449
+ }
1450
+ };
1451
+
1452
+ if (record.status === 'failed') {
1453
+ signals.push(createBackpressureSignal({
1454
+ ...base,
1455
+ source: record.source || 'component-telemetry',
1456
+ reason: 'component-lifecycle-failed',
1457
+ score: 4,
1458
+ level: 'medium'
1459
+ }));
1460
+ }
1461
+
1462
+ if (record.durationMs > laneDeadline) {
1463
+ const overshootRatio = laneDeadline > 0 ? record.durationMs / laneDeadline : record.durationMs;
1464
+ signals.push(createBackpressureSignal({
1465
+ ...base,
1466
+ source: record.source || 'component-telemetry',
1467
+ reason: 'component-lifecycle-deadline-exceeded',
1468
+ score: Math.max(1, Math.ceil(overshootRatio)),
1469
+ level: overshootRatio >= 3 ? 'high' : 'medium'
1470
+ }));
1471
+ }
1472
+
1473
+ if (record.backpressureSignal) {
1474
+ signals.push(createBackpressureSignal(record.backpressureSignal, {
1475
+ ...base,
1476
+ source: record.source || 'component-telemetry',
1477
+ reason: 'component-lifecycle-backpressure-signal',
1478
+ score: 2
1479
+ }));
1480
+ }
1481
+ });
1482
+
1483
+ if (Array.isArray(options.backpressureSignals)) {
1484
+ options.backpressureSignals.forEach((signal) => {
1485
+ signals.push(createBackpressureSignal(signal, { source: 'snapshot-options' }));
1486
+ });
1487
+ }
1488
+
1489
+ return signals;
1490
+ }
1491
+
1492
+ function createBackpressureSummary(signals = [], laneSummaries = {}) {
1493
+ const byLane = {};
1494
+ Object.keys(CANONICAL_LANES).forEach((laneId) => {
1495
+ const lane = laneSummaries[laneId] || {};
1496
+ const laneScore = (lane.failedCount || 0) * 4 + (lane.budgetMissCount || 0) * 2;
1497
+ byLane[laneId] = {
1498
+ schema: CONTRACTS.backpressureSignal,
1499
+ lane: laneId,
1500
+ score: laneScore,
1501
+ level: backpressureLevelForScore(laneScore),
1502
+ action: BACKPRESSURE_ACTION_BY_LEVEL[backpressureLevelForScore(laneScore)],
1503
+ signalCount: 0
1504
+ };
1505
+ });
1506
+
1507
+ let score = 0;
1508
+ signals.forEach((signal) => {
1509
+ const safeSignal = asObject(signal);
1510
+ const laneId = inferLane('diagnostics.snapshot', safeSignal.lane);
1511
+ if (!byLane[laneId]) {
1512
+ byLane[laneId] = {
1513
+ schema: CONTRACTS.backpressureSignal,
1514
+ lane: laneId,
1515
+ score: 0,
1516
+ level: 'none',
1517
+ action: BACKPRESSURE_ACTION_BY_LEVEL.none,
1518
+ signalCount: 0
1519
+ };
1520
+ }
1521
+ byLane[laneId].score += numericDuration(safeSignal.score);
1522
+ byLane[laneId].signalCount += 1;
1523
+ score += numericDuration(safeSignal.score);
1524
+ });
1525
+
1526
+ Object.keys(byLane).forEach((laneId) => {
1527
+ const lane = byLane[laneId];
1528
+ lane.level = backpressureLevelForScore(lane.score);
1529
+ lane.action = BACKPRESSURE_ACTION_BY_LEVEL[lane.level];
1530
+ });
1531
+
1532
+ const level = backpressureLevelForScore(score);
1533
+ return {
1534
+ schema: CONTRACTS.backpressureSignal,
1535
+ level,
1536
+ score,
1537
+ action: BACKPRESSURE_ACTION_BY_LEVEL[level],
1538
+ signalCount: signals.length,
1539
+ signals: signals.slice(-20),
1540
+ byLane
1541
+ };
1542
+ }
1543
+
1544
+ function readPerformanceRuntimeSnapshot(snapshotOptions = {}) {
1545
+ const options = asObject(snapshotOptions);
1546
+ const target = options.performance
1547
+ || options.performanceTarget
1548
+ || (config.window && config.window.performance)
1549
+ || (globalTarget && globalTarget.performance)
1550
+ || null;
1551
+ const entryLimit = Number.isInteger(options.performanceEntryLimit) ? options.performanceEntryLimit : 20;
1552
+ const prefix = Object.prototype.hasOwnProperty.call(options, 'performancePrefix')
1553
+ ? options.performancePrefix
1554
+ : 'xtend.';
1555
+ let entries = Array.isArray(options.performanceEntries) ? options.performanceEntries.slice() : [];
1556
+
1557
+ if (target && typeof target.getEntriesByType === 'function') {
1558
+ ['mark', 'measure'].forEach((type) => {
1559
+ try {
1560
+ entries = entries.concat(target.getEntriesByType(type) || []);
1561
+ } catch (_) {
1562
+ // Performance targets in tests or embedded hosts may expose partial APIs.
1563
+ }
1564
+ });
1565
+ } else if (target && typeof target.getEntries === 'function') {
1566
+ try {
1567
+ entries = entries.concat(target.getEntries() || []);
1568
+ } catch (_) {
1569
+ // Ignore partial host performance APIs.
1570
+ }
1571
+ }
1572
+
1573
+ const normalizedEntries = entries
1574
+ .map((entry) => asObject(entry))
1575
+ .filter((entry) => !prefix || String(entry.name || '').startsWith(prefix))
1576
+ .map(normalizePerformanceEntry);
1577
+
1578
+ const slicedEntries = normalizedEntries.slice(-entryLimit);
1579
+ const measurements = slicedEntries.map((entry, index) => createPerformanceMeasurement(entry, options, index));
1580
+ const phaseSummary = summarizePerformanceMeasurements(measurements);
1581
+ const totalDurationMs = slicedEntries.reduce((total, entry) => total + numericDuration(entry.duration), 0);
1582
+ const maxDurationMs = slicedEntries.reduce((max, entry) => Math.max(max, numericDuration(entry.duration)), 0);
1583
+
1584
+ return {
1585
+ supported: !!target || entries.length > 0,
1586
+ entryCount: normalizedEntries.length,
1587
+ entries: slicedEntries,
1588
+ measurementSchema: CONTRACTS.performanceMeasurement,
1589
+ measurementCount: measurements.length,
1590
+ measurements,
1591
+ phaseSummary,
1592
+ totalDurationMs: Number(totalDurationMs.toFixed(2)),
1593
+ maxDurationMs: Number(maxDurationMs.toFixed(2))
1594
+ };
1595
+ }
1596
+
1597
+ function recordSnapshotWithRmtBridge(snapshot, snapshotOptions = {}) {
1598
+ const options = asObject(snapshotOptions);
1599
+ const target = options.rmtTelemetryBridge
1600
+ || options.rmtBridge
1601
+ || options.rmt
1602
+ || (options.runtimeBridge && typeof options.runtimeBridge.recordTelemetrySnapshot === 'function' ? options.runtimeBridge : null);
1603
+ if (!target || typeof target.recordTelemetrySnapshot !== 'function' || options.recordRmtTelemetry === false) {
1604
+ return null;
1605
+ }
1606
+ try {
1607
+ return target.recordTelemetrySnapshot(snapshot, {
1608
+ xstate: options.xstate,
1609
+ diagnosticsHub: options.diagnosticsHub,
1610
+ scheduler: options.scheduler,
1611
+ schedule: options.schedule,
1612
+ scheduleRef: options.scheduleRef || 'diagnostics.snapshot',
1613
+ endpointName: options.endpointName || 'xtendrmt.diagnostics.snapshot',
1614
+ scope: options.scope || 'fabric.telemetry.snapshot',
1615
+ routeRef: options.routeRef || snapshot.routeRef || (snapshot.metadata && snapshot.metadata.activeRoute),
1616
+ correlationId: options.correlationId || snapshot.correlationId,
1617
+ source: options.source || snapshot.source || 'fabric',
1618
+ metadata: {
1619
+ bridge: options.bridge,
1620
+ snapshotId: snapshot.id
1621
+ }
1622
+ });
1623
+ } catch (error) {
1624
+ return emitDiagnostic({
1625
+ level: 'warn',
1626
+ code: 'xtend.fabric.rmt.telemetry.failed',
1627
+ message: 'XTend-Fabric could not forward telemetry snapshot to XTendRMT.',
1628
+ source: 'fabric',
1629
+ phase: 'telemetry',
1630
+ lane: 'diagnostics',
1631
+ correlationId: snapshot.correlationId || options.correlationId,
1632
+ metadata: {
1633
+ snapshotId: snapshot.id,
1634
+ error: error && error.message ? error.message : String(error)
1635
+ }
1636
+ });
1637
+ }
1638
+ }
1639
+
1640
+ function createTelemetrySnapshot(snapshotOptions = {}) {
1641
+ const options = asObject(snapshotOptions);
1642
+ const snapshotFibers = Array.isArray(options.fibers) ? options.fibers.slice() : fibers.slice();
1643
+ const snapshotDiagnostics = Array.isArray(options.diagnostics) ? options.diagnostics.slice() : diagnostics.slice();
1644
+ const componentTelemetryInput = Array.isArray(options.componentTelemetry)
1645
+ ? options.componentTelemetry
1646
+ : (Array.isArray(options.componentLifecycle)
1647
+ ? options.componentLifecycle
1648
+ : (Array.isArray(options.componentLifecycleTelemetry) ? options.componentLifecycleTelemetry : componentTelemetry.slice()));
1649
+ const componentTelemetryRecords = normalizeComponentLifecycleTelemetryCollection(
1650
+ componentTelemetryInput,
1651
+ {
1652
+ idPrefix: `${config.idPrefix}.componentTelemetry`,
1653
+ clock: config.clock,
1654
+ correlationId: options.correlationId
1655
+ }
1656
+ );
1657
+ const fiberSummary = summarizeFibersForTelemetry(snapshotFibers);
1658
+ const signals = collectBackpressureSignals(snapshotFibers, snapshotDiagnostics, {
1659
+ ...options,
1660
+ componentTelemetry: componentTelemetryRecords
1661
+ });
1662
+ const runtimeBridge = options.runtimeBridge || options.bridge || null;
1663
+ const runtimeSnapshot = runtimeBridge && typeof runtimeBridge.getSnapshot === 'function'
1664
+ ? runtimeBridge.getSnapshot({ source: 'telemetry-snapshot' })
1665
+ : options.runtimeSnapshot;
1666
+
1667
+ const snapshot = Object.freeze({
1668
+ schema: CONTRACTS.telemetrySnapshot,
1669
+ id: clampString(options.id, `${config.idPrefix}.telemetry.${++telemetrySnapshotCounter}`),
1670
+ timestamp: options.timestamp || nowIso(config.clock),
1671
+ source: clampString(options.source, 'fabric'),
1672
+ correlationId: options.correlationId,
1673
+ fiberCount: snapshotFibers.length,
1674
+ diagnosticCount: snapshotDiagnostics.length,
1675
+ reporterCount: reporters.length,
1676
+ totals: fiberSummary.totals,
1677
+ lanes: fiberSummary.lanes,
1678
+ componentTelemetry: summarizeComponentLifecycleTelemetry(componentTelemetryRecords),
1679
+ backpressure: createBackpressureSummary(signals, fiberSummary.lanes),
1680
+ performance: readPerformanceRuntimeSnapshot(options),
1681
+ runtime: runtimeSnapshot || null,
1682
+ metadata: redactValue(options.metadata || {})
1683
+ });
1684
+ recordSnapshotWithRmtBridge(snapshot, options);
1685
+ return snapshot;
1686
+ }
1687
+
1688
+ function publishTelemetrySnapshot(snapshotOrOptions = {}, publishOptions = {}) {
1689
+ const options = asObject(publishOptions);
1690
+ const snapshot = snapshotOrOptions && snapshotOrOptions.schema === CONTRACTS.telemetrySnapshot
1691
+ ? snapshotOrOptions
1692
+ : createTelemetrySnapshot(snapshotOrOptions);
1693
+ if (options.rmtBridge || options.rmtTelemetryBridge || options.rmt) {
1694
+ recordSnapshotWithRmtBridge(snapshot, options);
1695
+ }
1696
+ const level = options.level
1697
+ || (snapshot.backpressure.level === 'critical' || snapshot.backpressure.level === 'high' ? 'warn' : 'info');
1698
+ return emitDiagnostic({
1699
+ level,
1700
+ code: options.code || 'xtend.fabric.telemetry.snapshot',
1701
+ message: options.message || 'XTend-Fabric telemetry snapshot exported.',
1702
+ source: 'fabric',
1703
+ phase: 'telemetry',
1704
+ lane: 'diagnostics',
1705
+ correlationId: snapshot.correlationId || options.correlationId,
1706
+ metadata: {
1707
+ telemetrySnapshot: snapshot,
1708
+ snapshotId: snapshot.id,
1709
+ backpressureLevel: snapshot.backpressure.level,
1710
+ backpressureScore: snapshot.backpressure.score
1711
+ }
1712
+ });
1713
+ }
1714
+
1715
+ function createComponentFiberInstrumentation(componentRef, instrumentationOptions = {}) {
1716
+ const options = asObject(instrumentationOptions);
1717
+ const resolvedComponentRef = clampString(componentRef || options.componentRef || options.tag, 'xtend.component');
1718
+ const baseScope = clampString(options.scope, resolvedComponentRef);
1719
+ const swallowErrors = options.swallowErrors === true;
1720
+ const fallbackValue = Object.prototype.hasOwnProperty.call(options, 'fallbackValue')
1721
+ ? options.fallbackValue
1722
+ : undefined;
1723
+
1724
+ function optionFor(operation, suffix, fallback) {
1725
+ const key = `${operation}${suffix}`;
1726
+ return Object.prototype.hasOwnProperty.call(options, key) ? options[key] : fallback;
1727
+ }
1728
+
1729
+ function createFiberInput(operation, metadata = {}) {
1730
+ const profile = resolveComponentFiberOperationProfile(operation);
1731
+ const safeMetadata = asObject(metadata);
1732
+ const lane = inferLane(
1733
+ safeMetadata.kind || profile.kind,
1734
+ safeMetadata.lane || optionFor(profile.operation, 'Lane', options.lane || profile.lane)
1735
+ );
1736
+ const scheduleRef = safeMetadata.scheduleRef
1737
+ || optionFor(profile.operation, 'ScheduleRef', options.scheduleRef || profile.scheduleRef);
1738
+ const endpointNameHint = safeMetadata.endpointNameHint
1739
+ || optionFor(profile.operation, 'EndpointNameHint', options.endpointNameHint || profile.endpointNameHint);
1740
+ const coalesceKey = safeMetadata.coalesceKey
1741
+ || optionFor(profile.operation, 'CoalesceKey', options.coalesceKey || `${resolvedComponentRef}.${profile.coalesceSuffix}`);
1742
+ const scope = safeMetadata.scope || optionFor(profile.operation, 'Scope', `${baseScope}.${profile.operation}`);
1743
+
1744
+ return {
1745
+ kind: safeMetadata.kind || profile.kind,
1746
+ lane,
1747
+ phase: safeMetadata.phase || profile.phase,
1748
+ source: safeMetadata.source || profile.source,
1749
+ scope,
1750
+ componentRef: safeMetadata.componentRef || resolvedComponentRef,
1751
+ routeRef: safeMetadata.routeRef || options.routeRef,
1752
+ scheduleRef,
1753
+ endpointNameHint,
1754
+ fiberParentId: safeMetadata.fiberParentId || options.fiberParentId,
1755
+ correlationId: safeMetadata.correlationId || options.correlationId || `${resolvedComponentRef}.${profile.operation}`,
1756
+ budgetClass: safeMetadata.budgetClass || options.budgetClass,
1757
+ deadlineMs: safeMetadata.deadlineMs || options.deadlineMs,
1758
+ preferIdle: typeof safeMetadata.preferIdle === 'boolean'
1759
+ ? safeMetadata.preferIdle
1760
+ : (typeof options.preferIdle === 'boolean' ? options.preferIdle : CANONICAL_LANES[lane].preferIdle),
1761
+ coalesceKey,
1762
+ severity: safeMetadata.severity || options.severity || 'error',
1763
+ diagnosticCode: safeMetadata.diagnosticCode || options.diagnosticCode || profile.diagnosticCode,
1764
+ diagnosticMessage: safeMetadata.diagnosticMessage
1765
+ || options.diagnosticMessage
1766
+ || `${profile.diagnosticMessage}: ${resolvedComponentRef}`,
1767
+ metadata: {
1768
+ componentFiberInstrumentation: CONTRACTS.componentFiberInstrumentation,
1769
+ contract: CONTRACTS.componentFiberInstrumentation,
1770
+ operation: profile.operation,
1771
+ component: resolvedComponentRef,
1772
+ adapterRef: safeMetadata.adapterRef || options.adapterRef,
1773
+ hostRef: safeMetadata.hostRef || options.hostRef,
1774
+ scheduleRef,
1775
+ endpointNameHint,
1776
+ metadata: safeMetadata.metadata
1777
+ }
1778
+ };
1779
+ }
1780
+
1781
+ function runOperation(operation, task, metadata = {}) {
1782
+ if (typeof task !== 'function') {
1783
+ throw new TypeError('fabric component fiber instrumentation requires a task function.');
1784
+ }
1785
+ try {
1786
+ const value = runFiber(createFiberInput(operation, metadata), (fiber) => task(fiber));
1787
+ if (value && typeof value.then === 'function' && swallowErrors) {
1788
+ return value.catch(() => fallbackValue);
1789
+ }
1790
+ return value;
1791
+ } catch (error) {
1792
+ if (swallowErrors) {
1793
+ return fallbackValue;
1794
+ }
1795
+ throw error;
1796
+ }
1797
+ }
1798
+
1799
+ return Object.freeze({
1800
+ schema: CONTRACTS.componentFiberInstrumentation,
1801
+ componentRef: resolvedComponentRef,
1802
+ scope: baseScope,
1803
+ createFiberInput,
1804
+ runOperation,
1805
+ mount(task, metadata) {
1806
+ return runOperation('mount', task, metadata);
1807
+ },
1808
+ hydrate(task, metadata) {
1809
+ return runOperation('hydrate', task, metadata);
1810
+ },
1811
+ preload(task, metadata) {
1812
+ return runOperation('preload', task, metadata);
1813
+ }
1814
+ });
1815
+ }
1816
+
1817
+ function createRouteFiberInstrumentation(routerRef, instrumentationOptions = {}) {
1818
+ const options = asObject(instrumentationOptions);
1819
+ const resolvedRouterRef = clampString(routerRef || options.routerRef || options.adapterRef, 'xtend.xrouter');
1820
+ const baseScope = clampString(options.scope, resolvedRouterRef);
1821
+ const swallowErrors = options.swallowErrors === true;
1822
+ const fallbackValue = Object.prototype.hasOwnProperty.call(options, 'fallbackValue')
1823
+ ? options.fallbackValue
1824
+ : undefined;
1825
+
1826
+ function optionFor(operation, suffix, fallback) {
1827
+ const key = `${operation}${suffix}`;
1828
+ return Object.prototype.hasOwnProperty.call(options, key) ? options[key] : fallback;
1829
+ }
1830
+
1831
+ function resolveRouteRef(profile, metadata) {
1832
+ return metadata.routeRef
1833
+ || metadata.routeId
1834
+ || metadata.path
1835
+ || metadata.to
1836
+ || metadata.href
1837
+ || optionFor(profile.operation, 'RouteRef', options.routeRef);
1838
+ }
1839
+
1840
+ function createFiberInput(operation, metadata = {}) {
1841
+ const profile = resolveRouteFiberOperationProfile(operation);
1842
+ const safeMetadata = asObject(metadata);
1843
+ const routeRef = resolveRouteRef(profile, safeMetadata);
1844
+ const lane = inferLane(
1845
+ safeMetadata.kind || profile.kind,
1846
+ safeMetadata.lane || optionFor(profile.operation, 'Lane', options.lane || profile.lane)
1847
+ );
1848
+ const scheduleRef = safeMetadata.scheduleRef
1849
+ || optionFor(profile.operation, 'ScheduleRef', options.scheduleRef || profile.scheduleRef);
1850
+ const endpointNameHint = safeMetadata.endpointNameHint
1851
+ || optionFor(profile.operation, 'EndpointNameHint', options.endpointNameHint || profile.endpointNameHint);
1852
+ const coalesceKey = safeMetadata.coalesceKey
1853
+ || optionFor(profile.operation, 'CoalesceKey', options.coalesceKey || `${resolvedRouterRef}.${profile.coalesceSuffix}.${routeRef || 'route'}`);
1854
+ const scope = safeMetadata.scope || optionFor(profile.operation, 'Scope', `${baseScope}.${profile.operation}`);
1855
+
1856
+ return {
1857
+ kind: safeMetadata.kind || profile.kind,
1858
+ lane,
1859
+ phase: safeMetadata.phase || profile.phase,
1860
+ source: safeMetadata.source || profile.source,
1861
+ scope,
1862
+ componentRef: safeMetadata.componentRef || options.componentRef,
1863
+ routeRef,
1864
+ scheduleRef,
1865
+ endpointNameHint,
1866
+ fiberParentId: safeMetadata.fiberParentId || options.fiberParentId,
1867
+ correlationId: safeMetadata.correlationId
1868
+ || options.correlationId
1869
+ || `${resolvedRouterRef}.${profile.operation}.${routeRef || 'route'}`,
1870
+ budgetClass: safeMetadata.budgetClass || options.budgetClass,
1871
+ deadlineMs: safeMetadata.deadlineMs || options.deadlineMs,
1872
+ preferIdle: typeof safeMetadata.preferIdle === 'boolean'
1873
+ ? safeMetadata.preferIdle
1874
+ : (typeof options.preferIdle === 'boolean' ? options.preferIdle : CANONICAL_LANES[lane].preferIdle),
1875
+ coalesceKey,
1876
+ severity: safeMetadata.severity || options.severity || 'error',
1877
+ diagnosticCode: safeMetadata.diagnosticCode || options.diagnosticCode || profile.diagnosticCode,
1878
+ diagnosticMessage: safeMetadata.diagnosticMessage
1879
+ || options.diagnosticMessage
1880
+ || `${profile.diagnosticMessage}: ${routeRef || resolvedRouterRef}`,
1881
+ metadata: {
1882
+ routeFiberInstrumentation: CONTRACTS.routeFiberInstrumentation,
1883
+ contract: CONTRACTS.routeFiberInstrumentation,
1884
+ operation: profile.operation,
1885
+ router: resolvedRouterRef,
1886
+ routeId: safeMetadata.routeId || options.routeId,
1887
+ path: safeMetadata.path || options.path,
1888
+ from: safeMetadata.from,
1889
+ to: safeMetadata.to || safeMetadata.href,
1890
+ params: safeMetadata.params,
1891
+ query: safeMetadata.query,
1892
+ componentRef: safeMetadata.componentRef || options.componentRef,
1893
+ adapterRef: safeMetadata.adapterRef || options.adapterRef,
1894
+ hostRef: safeMetadata.hostRef || options.hostRef,
1895
+ scheduleRef,
1896
+ endpointNameHint,
1897
+ backpressureSignal: safeMetadata.backpressureSignal || options.backpressureSignal,
1898
+ metadata: safeMetadata.metadata
1899
+ }
1900
+ };
1901
+ }
1902
+
1903
+ function runOperation(operation, task, metadata = {}) {
1904
+ if (typeof task !== 'function') {
1905
+ throw new TypeError('fabric route fiber instrumentation requires a task function.');
1906
+ }
1907
+ try {
1908
+ const value = runFiber(createFiberInput(operation, metadata), (fiber) => task(fiber));
1909
+ if (value && typeof value.then === 'function' && swallowErrors) {
1910
+ return value.catch(() => fallbackValue);
1911
+ }
1912
+ return value;
1913
+ } catch (error) {
1914
+ if (swallowErrors) {
1915
+ return fallbackValue;
1916
+ }
1917
+ throw error;
1918
+ }
1919
+ }
1920
+
1921
+ return Object.freeze({
1922
+ schema: CONTRACTS.routeFiberInstrumentation,
1923
+ routerRef: resolvedRouterRef,
1924
+ scope: baseScope,
1925
+ createFiberInput,
1926
+ runOperation,
1927
+ navigate(task, metadata) {
1928
+ return runOperation('navigate', task, metadata);
1929
+ },
1930
+ render(task, metadata) {
1931
+ return runOperation('render', task, metadata);
1932
+ }
1933
+ });
1934
+ }
1935
+
1936
+ function createComponentLifecycleBoundary(componentRef, lifecycleOptions = {}) {
1937
+ const resolvedComponentRef = clampString(componentRef || lifecycleOptions.componentRef || lifecycleOptions.tag, 'xtend.component');
1938
+ const boundaryScope = clampString(lifecycleOptions.scope, resolvedComponentRef);
1939
+ const swallowErrors = lifecycleOptions.swallowErrors !== false;
1940
+ const fallbackValue = Object.prototype.hasOwnProperty.call(lifecycleOptions, 'fallbackValue')
1941
+ ? lifecycleOptions.fallbackValue
1942
+ : undefined;
1943
+
1944
+ function createLifecycleFiberInput(phase, metadata = {}) {
1945
+ const phaseContract = resolveLifecyclePhase(phase);
1946
+ const lane = inferLane(phaseContract.fiberKind, metadata.lane || lifecycleOptions.lane || phaseContract.lane);
1947
+ const normalizedPhase = phaseContract.phase || phase;
1948
+ return {
1949
+ kind: phaseContract.fiberKind,
1950
+ lane,
1951
+ phase: normalizedPhase,
1952
+ source: 'component',
1953
+ scope: boundaryScope,
1954
+ componentRef: resolvedComponentRef,
1955
+ routeRef: lifecycleOptions.routeRef,
1956
+ scheduleRef: lifecycleOptions.scheduleRef || metadata.scheduleRef,
1957
+ correlationId: lifecycleOptions.correlationId || metadata.correlationId,
1958
+ severity: metadata.severity || lifecycleOptions.severity || phaseContract.severity || 'error',
1959
+ diagnosticCode: metadata.diagnosticCode || lifecycleOptions.diagnosticCode || 'xtend.fabric.component.lifecycle.failed',
1960
+ diagnosticMessage: metadata.diagnosticMessage || lifecycleOptions.diagnosticMessage || `XTend component ${resolvedComponentRef} failed during ${normalizedPhase}`,
1961
+ metadata: {
1962
+ lifecycleBoundary: CONTRACTS.lifecycleBoundary,
1963
+ component: resolvedComponentRef,
1964
+ method: metadata.method || normalizedPhase,
1965
+ eventName: metadata.eventName,
1966
+ eventType: metadata.eventType,
1967
+ phase: normalizedPhase,
1968
+ contract: CONTRACTS.lifecycleBoundary,
1969
+ metadata: metadata.metadata
1970
+ }
1971
+ };
1972
+ }
1973
+
1974
+ function runPhase(phase, task, metadata = {}) {
1975
+ if (typeof task !== 'function') {
1976
+ throw new TypeError('fabric lifecycle boundary requires a task function.');
1977
+ }
1978
+
1979
+ try {
1980
+ const value = runFiber(createLifecycleFiberInput(phase, metadata), () => task());
1981
+ if (value && typeof value.then === 'function' && swallowErrors) {
1982
+ return value.catch(() => fallbackValue);
1983
+ }
1984
+ return value;
1985
+ } catch (error) {
1986
+ if (swallowErrors) {
1987
+ return fallbackValue;
1988
+ }
1989
+ throw error;
1990
+ }
1991
+ }
1992
+
1993
+ function wrapMethod(target, method, methodOptions = {}) {
1994
+ const original = target && target[method];
1995
+ if (typeof original !== 'function') {
1996
+ return target;
1997
+ }
1998
+ target[method] = function wrappedFabricLifecycleMethod(...args) {
1999
+ return runPhase(methodOptions.phase || method, () => original.apply(this, args), {
2000
+ method,
2001
+ metadata: methodOptions.metadata
2002
+ });
2003
+ };
2004
+ return target;
2005
+ }
2006
+
2007
+ function wrapEventHandler(handler, handlerOptions = {}) {
2008
+ if (typeof handler !== 'function') {
2009
+ throw new TypeError('fabric.wrapEventHandler requires a function.');
2010
+ }
2011
+ return function wrappedFabricEventHandler(...args) {
2012
+ const event = args[0];
2013
+ const eventType = event && typeof event.type === 'string' ? event.type : handlerOptions.eventType;
2014
+ return runPhase(handlerOptions.phase || 'eventHandler', () => handler.apply(this, args), {
2015
+ method: handlerOptions.method || handler.name || 'eventHandler',
2016
+ eventName: handlerOptions.eventName || eventType || handlerOptions.method || handler.name,
2017
+ eventType,
2018
+ metadata: handlerOptions.metadata
2019
+ });
2020
+ };
2021
+ }
2022
+
2023
+ function captureLifecycleError(error, context = {}) {
2024
+ const phaseContract = resolveLifecyclePhase(context.phase || 'lifecycle');
2025
+ return captureError(error, {
2026
+ code: context.code || 'xtend.fabric.component.lifecycle.failed',
2027
+ message: context.message || `XTend component ${resolvedComponentRef} failed during ${phaseContract.phase}`,
2028
+ source: 'component',
2029
+ phase: phaseContract.phase,
2030
+ componentRef: resolvedComponentRef,
2031
+ fiberId: context.fiberId,
2032
+ lane: context.lane || phaseContract.lane,
2033
+ correlationId: context.correlationId || lifecycleOptions.correlationId,
2034
+ routeRef: context.routeRef || lifecycleOptions.routeRef,
2035
+ scheduleRef: context.scheduleRef || lifecycleOptions.scheduleRef,
2036
+ severity: context.severity || phaseContract.severity,
2037
+ metadata: {
2038
+ lifecycleBoundary: CONTRACTS.lifecycleBoundary,
2039
+ component: resolvedComponentRef,
2040
+ method: context.method || phaseContract.phase,
2041
+ eventName: context.eventName,
2042
+ contract: CONTRACTS.lifecycleBoundary,
2043
+ metadata: context.metadata
2044
+ }
2045
+ });
2046
+ }
2047
+
2048
+ return Object.freeze({
2049
+ schema: CONTRACTS.lifecycleBoundary,
2050
+ componentRef: resolvedComponentRef,
2051
+ scope: boundaryScope,
2052
+ runPhase,
2053
+ wrapMethod,
2054
+ wrapEventHandler,
2055
+ capture: captureLifecycleError
2056
+ });
2057
+ }
2058
+
2059
+ function createBoundary(scope, boundaryOptions = {}) {
2060
+ const boundaryScope = clampString(scope, boundaryOptions.scope || 'fabric.boundary');
2061
+ const swallowErrors = boundaryOptions.swallowErrors === true;
2062
+ const fallbackValue = Object.prototype.hasOwnProperty.call(boundaryOptions, 'fallbackValue')
2063
+ ? boundaryOptions.fallbackValue
2064
+ : undefined;
2065
+
2066
+ function run(phase, task, metadata = {}) {
2067
+ const fiberInput = {
2068
+ kind: boundaryOptions.fiberKind || `${boundaryOptions.source || 'fabric'}.${phase || 'run'}`,
2069
+ lane: boundaryOptions.lane,
2070
+ phase: phase || boundaryOptions.phase || 'run',
2071
+ source: boundaryOptions.source || 'fabric',
2072
+ scope: boundaryScope,
2073
+ componentRef: boundaryOptions.componentRef,
2074
+ routeRef: boundaryOptions.routeRef,
2075
+ scheduleRef: boundaryOptions.scheduleRef,
2076
+ correlationId: boundaryOptions.correlationId,
2077
+ metadata
2078
+ };
2079
+
2080
+ try {
2081
+ const value = runFiber(fiberInput, () => task());
2082
+ if (value && typeof value.then === 'function' && swallowErrors) {
2083
+ return value.catch(() => fallbackValue);
2084
+ }
2085
+ return value;
2086
+ } catch (error) {
2087
+ if (swallowErrors) {
2088
+ return fallbackValue;
2089
+ }
2090
+ throw error;
2091
+ }
2092
+ }
2093
+
2094
+ return Object.freeze({
2095
+ schema: CONTRACTS.api,
2096
+ scope: boundaryScope,
2097
+ run,
2098
+ wrap(phase, task, metadata) {
2099
+ return (...args) => run(phase, () => task(...args), metadata);
2100
+ },
2101
+ capture(error, context = {}) {
2102
+ return captureError(error, {
2103
+ source: boundaryOptions.source || 'fabric',
2104
+ phase: context.phase || boundaryOptions.phase || 'error',
2105
+ componentRef: boundaryOptions.componentRef,
2106
+ routeRef: boundaryOptions.routeRef,
2107
+ scheduleRef: boundaryOptions.scheduleRef,
2108
+ correlationId: boundaryOptions.correlationId,
2109
+ metadata: context.metadata || {}
2110
+ });
2111
+ }
2112
+ });
2113
+ }
2114
+
2115
+ function wrapComponent(componentClassOrInstance, wrapOptions = {}) {
2116
+ const componentRef = wrapOptions.componentRef || wrapOptions.tag || (componentClassOrInstance && componentClassOrInstance.name) || 'xtend.component';
2117
+ const lifecycleBoundary = createComponentLifecycleBoundary(componentRef, {
2118
+ scope: wrapOptions.scope,
2119
+ lane: wrapOptions.lane,
2120
+ routeRef: wrapOptions.routeRef,
2121
+ scheduleRef: wrapOptions.scheduleRef,
2122
+ correlationId: wrapOptions.correlationId,
2123
+ swallowErrors: wrapOptions.swallowErrors !== false,
2124
+ fallbackValue: wrapOptions.fallbackValue,
2125
+ severity: wrapOptions.severity
2126
+ });
2127
+ const eventHandlers = Array.isArray(wrapOptions.eventHandlers) ? wrapOptions.eventHandlers.slice() : [];
2128
+
2129
+ function wrapMethod(target, method) {
2130
+ const original = target && target[method];
2131
+ if (typeof original !== 'function') {
2132
+ return;
2133
+ }
2134
+ lifecycleBoundary.wrapMethod(target, method);
2135
+ }
2136
+
2137
+ function wrapEventMethod(target, method) {
2138
+ const original = target && target[method];
2139
+ if (typeof original !== 'function') {
2140
+ return;
2141
+ }
2142
+ target[method] = lifecycleBoundary.wrapEventHandler(original, {
2143
+ method,
2144
+ eventName: method
2145
+ });
2146
+ }
2147
+
2148
+ if (typeof componentClassOrInstance === 'function') {
2149
+ const BaseComponent = componentClassOrInstance;
2150
+ class FabricWrappedComponent extends BaseComponent {}
2151
+ LIFECYCLE_METHODS.forEach((method) => {
2152
+ const original = BaseComponent.prototype[method];
2153
+ if (typeof original === 'function') {
2154
+ FabricWrappedComponent.prototype[method] = function fabricWrappedLifecycle(...args) {
2155
+ return lifecycleBoundary.runPhase(method, () => original.apply(this, args), { method });
2156
+ };
2157
+ }
2158
+ });
2159
+ eventHandlers.forEach((method) => {
2160
+ const original = BaseComponent.prototype[method];
2161
+ if (typeof original === 'function') {
2162
+ FabricWrappedComponent.prototype[method] = lifecycleBoundary.wrapEventHandler(function fabricWrappedEventMethod(...args) {
2163
+ return original.apply(this, args);
2164
+ }, {
2165
+ method,
2166
+ eventName: method
2167
+ });
2168
+ }
2169
+ });
2170
+ Object.defineProperty(FabricWrappedComponent, 'name', {
2171
+ value: `${BaseComponent.name || 'XTend'}FabricWrapped`
2172
+ });
2173
+ FabricWrappedComponent.xtendFabricBoundary = lifecycleBoundary;
2174
+ return FabricWrappedComponent;
2175
+ }
2176
+
2177
+ LIFECYCLE_METHODS.forEach((method) => wrapMethod(componentClassOrInstance, method));
2178
+ eventHandlers.forEach((method) => wrapEventMethod(componentClassOrInstance, method));
2179
+ return componentClassOrInstance;
2180
+ }
2181
+
2182
+ function registerReporter(reporter) {
2183
+ const normalized = normalizeReporter(reporter);
2184
+ reporters.push(normalized);
2185
+ return () => {
2186
+ const index = reporters.indexOf(normalized);
2187
+ if (index >= 0) {
2188
+ reporters.splice(index, 1);
2189
+ normalized.dispose();
2190
+ }
2191
+ };
2192
+ }
2193
+
2194
+ function writeStateValue(stateTarget, key, value) {
2195
+ const safeKey = clampString(key, '');
2196
+ if (!stateTarget || !safeKey) return false;
2197
+ if (typeof stateTarget.set === 'function') {
2198
+ stateTarget.set(safeKey, value);
2199
+ return true;
2200
+ }
2201
+ if (typeof stateTarget.setState === 'function') {
2202
+ stateTarget.setState(safeKey, value);
2203
+ return true;
2204
+ }
2205
+ return false;
2206
+ }
2207
+
2208
+ function readStateValue(stateTarget, key, fallbackValue) {
2209
+ const safeKey = clampString(key, '');
2210
+ if (!stateTarget || !safeKey) return fallbackValue;
2211
+ if (typeof stateTarget.get === 'function') {
2212
+ const value = stateTarget.get(safeKey);
2213
+ return value === undefined ? fallbackValue : value;
2214
+ }
2215
+ return fallbackValue;
2216
+ }
2217
+
2218
+ function createRuntimeDiagnosticsSnapshot(bridgeId, extra = {}) {
2219
+ return Object.freeze({
2220
+ schema: CONTRACTS.runtimeDiagnosticsBridge,
2221
+ bridgeId,
2222
+ diagnosticCount: diagnostics.length,
2223
+ fiberCount: fibers.length,
2224
+ reporterCount: reporters.length,
2225
+ lastDiagnostic: diagnostics.length > 0 ? diagnostics[diagnostics.length - 1] : null,
2226
+ timestamp: nowIso(config.clock),
2227
+ ...extra
2228
+ });
2229
+ }
2230
+
2231
+ function publishRmtDiagnosticEntry(entry, connectionOptions = {}) {
2232
+ const event = entry && entry.detail ? entry.detail : entry;
2233
+ const diagnostic = asObject(event);
2234
+ const metadata = asObject(diagnostic.metadata);
2235
+ return emitDiagnostic({
2236
+ level: diagnostic.level || connectionOptions.level || 'info',
2237
+ code: diagnostic.code || 'xtend.rmt.diagnostic',
2238
+ message: diagnostic.message || 'RMT diagnostic consumed by XTend-Fabric',
2239
+ source: 'rmt',
2240
+ phase: diagnostic.phase || diagnostic.operation || 'diagnose',
2241
+ componentRef: diagnostic.componentRef || metadata.componentRef || metadata.componentId,
2242
+ fiberId: diagnostic.fiberId || metadata.fiberId,
2243
+ lane: diagnostic.lane || metadata.lane,
2244
+ correlationId: diagnostic.correlationId || metadata.correlationId,
2245
+ routeRef: diagnostic.routeRef || metadata.routeRef || metadata.routeId,
2246
+ scheduleRef: diagnostic.scheduleRef || metadata.scheduleRef || metadata.schedule,
2247
+ metadata: {
2248
+ adapterId: diagnostic.adapterId || metadata.adapterId,
2249
+ bridge: diagnostic.bridge || connectionOptions.bridge || connectionOptions.bridgeId,
2250
+ operation: diagnostic.operation || metadata.operation,
2251
+ payload: diagnostic.payload,
2252
+ metadata
2253
+ }
2254
+ });
2255
+ }
2256
+
2257
+ function connectRmtDiagnostics(source, connectionOptions = {}) {
2258
+ const connection = {
2259
+ schema: 'xtend.fabric.rmt-diagnostics-connection.v1',
2260
+ source: 'rmt',
2261
+ disposed: false,
2262
+ dispose() {
2263
+ connection.disposed = true;
2264
+ if (typeof connection.unsubscribe === 'function') {
2265
+ connection.unsubscribe();
2266
+ }
2267
+ if (connection.target && typeof connection.target.removeEventListener === 'function') {
2268
+ connection.target.removeEventListener(connection.eventName, connection.listener);
2269
+ }
2270
+ }
2271
+ };
2272
+
2273
+ function publishRmtDiagnostic(entry) {
2274
+ if (connection.disposed) return null;
2275
+ return publishRmtDiagnosticEntry(entry, connectionOptions);
2276
+ }
2277
+
2278
+ if (Array.isArray(source)) {
2279
+ source.forEach(publishRmtDiagnostic);
2280
+ return Object.freeze(connection);
2281
+ }
2282
+
2283
+ if (source && Array.isArray(source.diagnostics)) {
2284
+ source.diagnostics.forEach(publishRmtDiagnostic);
2285
+ }
2286
+
2287
+ if (source && typeof source.listDiagnostics === 'function') {
2288
+ const listedDiagnostics = source.listDiagnostics();
2289
+ if (Array.isArray(listedDiagnostics)) {
2290
+ listedDiagnostics.forEach(publishRmtDiagnostic);
2291
+ }
2292
+ }
2293
+
2294
+ if (source && typeof source.subscribe === 'function') {
2295
+ connection.unsubscribe = source.subscribe(publishRmtDiagnostic);
2296
+ }
2297
+
2298
+ if (source && typeof source.addEventListener === 'function') {
2299
+ connection.target = source;
2300
+ connection.eventName = connectionOptions.eventName || 'rmt-diagnostic';
2301
+ connection.listener = publishRmtDiagnostic;
2302
+ source.addEventListener(connection.eventName, connection.listener);
2303
+ }
2304
+
2305
+ return Object.freeze(connection);
2306
+ }
2307
+
2308
+ function createRuntimeDiagnosticsBridge(bridgeOptions = {}) {
2309
+ const options = asObject(bridgeOptions);
2310
+ const bridgeId = clampString(options.id || options.bridgeId, 'xtend.fabric.runtime-diagnostics');
2311
+ const statePrefix = clampString(options.statePrefix, 'xtend.fabric');
2312
+ const bridgeReadyKey = clampString(options.bridgeReadyKey, `${statePrefix}.bridge.ready`);
2313
+ const diagnosticStateKey = clampString(options.diagnosticStateKey, `${statePrefix}.diagnostics.last`);
2314
+ const snapshotStateKey = clampString(options.snapshotStateKey, `${statePrefix}.diagnostics.snapshot`);
2315
+ const ignoredStatePrefixes = Array.isArray(options.ignoredStatePrefixes)
2316
+ ? options.ignoredStatePrefixes.slice()
2317
+ : [statePrefix];
2318
+ const connections = [];
2319
+ let disposed = false;
2320
+
2321
+ function isIgnoredStateKey(key) {
2322
+ return !key || ignoredStatePrefixes.some((prefix) => key === prefix || key.startsWith(`${prefix}.`));
2323
+ }
2324
+
2325
+ function getStateTarget(stateTarget) {
2326
+ return stateTarget || options.xstate || (config.window && config.window.xstate) || (globalTarget && globalTarget.xstate) || null;
2327
+ }
2328
+
2329
+ function mirrorDiagnosticToState(diagnostic, stateTarget = null, mirrorOptions = {}) {
2330
+ const target = getStateTarget(stateTarget);
2331
+ if (!target) return false;
2332
+ const safeDiagnostic = redactDiagnostic(asObject(diagnostic));
2333
+ const wroteLast = writeStateValue(target, mirrorOptions.diagnosticStateKey || diagnosticStateKey, safeDiagnostic);
2334
+ const wroteSnapshot = writeStateValue(target, mirrorOptions.snapshotStateKey || snapshotStateKey, createRuntimeDiagnosticsSnapshot(bridgeId, {
2335
+ mirroredToState: wroteLast,
2336
+ source: safeDiagnostic.source,
2337
+ code: safeDiagnostic.code
2338
+ }));
2339
+ return wroteLast || wroteSnapshot;
2340
+ }
2341
+
2342
+ function connectXState(stateTarget = null, connectionOptions = {}) {
2343
+ const target = getStateTarget(stateTarget);
2344
+ const connection = {
2345
+ schema: CONTRACTS.runtimeDiagnosticsBridge,
2346
+ kind: 'xstate',
2347
+ targetRef: connectionOptions.targetRef || 'xstate',
2348
+ disposed: false,
2349
+ dispose() {
2350
+ connection.disposed = true;
2351
+ if (typeof connection.unsubscribe === 'function') {
2352
+ connection.unsubscribe();
2353
+ }
2354
+ if (typeof connection.unregisterReporter === 'function') {
2355
+ connection.unregisterReporter();
2356
+ }
2357
+ }
2358
+ };
2359
+ connections.push(connection);
2360
+
2361
+ if (!target) {
2362
+ emitDiagnostic({
2363
+ level: 'warn',
2364
+ code: 'xtend.fabric.xstate.unavailable',
2365
+ message: 'XTend-Fabric runtime diagnostics bridge could not find an xstate target.',
2366
+ source: 'fabric',
2367
+ phase: 'state',
2368
+ metadata: {
2369
+ bridgeId,
2370
+ targetRef: connection.targetRef
2371
+ }
2372
+ });
2373
+ return Object.freeze(connection);
2374
+ }
2375
+
2376
+ connection.unregisterReporter = registerReporter(createReporterAdapter({
2377
+ id: connectionOptions.reporterId || `${bridgeId}.xstate-reporter`,
2378
+ kind: 'xstate',
2379
+ delivery: 'xstate',
2380
+ external: false,
2381
+ minimumLevel: connectionOptions.minimumLevel || 'debug',
2382
+ capabilities: ['diagnostics', 'stateMirror'],
2383
+ sink(event) {
2384
+ return mirrorDiagnosticToState(event, target, connectionOptions);
2385
+ }
2386
+ }));
2387
+
2388
+ writeStateValue(target, connectionOptions.bridgeReadyKey || bridgeReadyKey, {
2389
+ schema: CONTRACTS.runtimeDiagnosticsBridge,
2390
+ bridgeId,
2391
+ connected: true,
2392
+ targetRef: connection.targetRef
2393
+ });
2394
+
2395
+ if (typeof target.subscribe === 'function') {
2396
+ connection.unsubscribe = target.subscribe((key, value, allData) => {
2397
+ if (connection.disposed || disposed || !key || isIgnoredStateKey(key)) return;
2398
+ emitDiagnostic({
2399
+ level: connectionOptions.level || 'debug',
2400
+ code: 'xtend.fabric.xstate.changed',
2401
+ message: `XTend xstate changed "${key}".`,
2402
+ source: 'xstate',
2403
+ phase: 'state',
2404
+ correlationId: connectionOptions.correlationId,
2405
+ metadata: {
2406
+ bridgeId,
2407
+ key,
2408
+ value,
2409
+ stateSize: allData && typeof allData === 'object' ? Object.keys(allData).length : undefined
2410
+ }
2411
+ });
2412
+ }, connectionOptions.keyFilter);
2413
+ }
2414
+
2415
+ emitDiagnostic({
2416
+ level: 'info',
2417
+ code: 'xtend.fabric.xstate.connected',
2418
+ message: 'XTend-Fabric runtime diagnostics bridge connected xstate.',
2419
+ source: 'fabric',
2420
+ phase: 'state',
2421
+ correlationId: connectionOptions.correlationId,
2422
+ metadata: {
2423
+ bridgeId,
2424
+ targetRef: connection.targetRef,
2425
+ bridgeReadyKey,
2426
+ diagnosticStateKey,
2427
+ snapshotStateKey
2428
+ }
2429
+ });
2430
+
2431
+ return Object.freeze(connection);
2432
+ }
2433
+
2434
+ function connectApi(apiTarget = null, connectionOptions = {}) {
2435
+ const apiTargetCandidate = apiTarget || options.api || (config.window && config.window.XTend) || (globalTarget && globalTarget.XTend) || null;
2436
+ const api = asObject(apiTargetCandidate);
2437
+ const compliance = asObject(api.compliance);
2438
+ const hasApi = !!apiTargetCandidate;
2439
+ let coreContracts = null;
2440
+ let checklist = null;
2441
+ try {
2442
+ coreContracts = typeof compliance.getCoreContracts === 'function' ? compliance.getCoreContracts() : undefined;
2443
+ checklist = typeof compliance.getChecklist === 'function' ? compliance.getChecklist() : undefined;
2444
+ } catch (error) {
2445
+ captureError(error, {
2446
+ code: 'xtend.fabric.api.inspect.failed',
2447
+ message: 'XTend-Fabric could not inspect XTend API compliance metadata.',
2448
+ source: 'api',
2449
+ phase: 'connect',
2450
+ metadata: {
2451
+ bridgeId
2452
+ }
2453
+ });
2454
+ }
2455
+
2456
+ const diagnostic = emitDiagnostic({
2457
+ level: hasApi ? 'info' : 'warn',
2458
+ code: hasApi ? 'xtend.fabric.api.connected' : 'xtend.fabric.api.unavailable',
2459
+ message: hasApi
2460
+ ? 'XTend-Fabric runtime diagnostics bridge connected XTend API metadata.'
2461
+ : 'XTend-Fabric runtime diagnostics bridge could not find XTend API metadata.',
2462
+ source: 'api',
2463
+ phase: 'connect',
2464
+ correlationId: connectionOptions.correlationId || options.correlationId,
2465
+ metadata: {
2466
+ bridgeId,
2467
+ namespacePresent: hasApi,
2468
+ complianceVersion: compliance.version,
2469
+ coreContracts,
2470
+ checklist,
2471
+ capabilities: Object.keys(api).filter((key) => typeof api[key] !== 'function')
2472
+ }
2473
+ });
2474
+
2475
+ const connection = Object.freeze({
2476
+ schema: CONTRACTS.runtimeDiagnosticsBridge,
2477
+ kind: 'api',
2478
+ targetRef: connectionOptions.targetRef || 'window.XTend',
2479
+ diagnostic,
2480
+ dispose() {}
2481
+ });
2482
+ connections.push(connection);
2483
+ return connection;
2484
+ }
2485
+
2486
+ function connectRmtDiagnosticsBridge(source = null, connectionOptions = {}) {
2487
+ const target = source || options.rmt || options.rmtBridge || options.rmtDiagnostics || null;
2488
+ const connection = connectRmtDiagnostics(target, {
2489
+ bridge: bridgeId,
2490
+ ...connectionOptions
2491
+ });
2492
+ connections.push(connection);
2493
+ emitDiagnostic({
2494
+ level: target ? 'info' : 'warn',
2495
+ code: target ? 'xtend.fabric.rmt.connected' : 'xtend.fabric.rmt.unavailable',
2496
+ message: target
2497
+ ? 'XTend-Fabric runtime diagnostics bridge connected XTendRMT diagnostics.'
2498
+ : 'XTend-Fabric runtime diagnostics bridge could not find XTendRMT diagnostics.',
2499
+ source: 'fabric',
2500
+ phase: 'rmt',
2501
+ correlationId: connectionOptions.correlationId || options.correlationId,
2502
+ metadata: {
2503
+ bridgeId,
2504
+ sourceKind: Array.isArray(target) ? 'array' : typeof target
2505
+ }
2506
+ });
2507
+ return connection;
2508
+ }
2509
+
2510
+ function createRmtDiagnosticsHub(hubOptions = {}) {
2511
+ return Object.freeze({
2512
+ schema: 'xtend.fabric.rmt-diagnostics-hub.v1',
2513
+ bridgeId,
2514
+ publish(event, context = {}) {
2515
+ return publishRmtDiagnosticEntry({
2516
+ ...asObject(event),
2517
+ payload: asObject(context)
2518
+ }, {
2519
+ bridge: bridgeId,
2520
+ ...hubOptions
2521
+ });
2522
+ },
2523
+ emit(eventName, event = {}) {
2524
+ return publishRmtDiagnosticEntry({
2525
+ ...asObject(event),
2526
+ phase: eventName || event.phase || event.operation
2527
+ }, {
2528
+ bridge: bridgeId,
2529
+ ...hubOptions
2530
+ });
2531
+ },
2532
+ record(event) {
2533
+ return publishRmtDiagnosticEntry(event, {
2534
+ bridge: bridgeId,
2535
+ ...hubOptions
2536
+ });
2537
+ }
2538
+ });
2539
+ }
2540
+
2541
+ function connectAll(connectionOptions = {}) {
2542
+ const activeConnections = [];
2543
+ if (connectionOptions.xstate !== false) {
2544
+ activeConnections.push(connectXState(connectionOptions.xstate || options.xstate, connectionOptions.xstateOptions || {}));
2545
+ }
2546
+ if (connectionOptions.api !== false) {
2547
+ activeConnections.push(connectApi(connectionOptions.api || options.api, connectionOptions.apiOptions || {}));
2548
+ }
2549
+ if (connectionOptions.rmt !== false && (connectionOptions.rmt || options.rmt || options.rmtBridge || options.rmtDiagnostics)) {
2550
+ activeConnections.push(connectRmtDiagnosticsBridge(connectionOptions.rmt || options.rmt || options.rmtBridge || options.rmtDiagnostics, connectionOptions.rmtOptions || {}));
2551
+ }
2552
+ return Object.freeze(activeConnections);
2553
+ }
2554
+
2555
+ return Object.freeze({
2556
+ schema: CONTRACTS.runtimeDiagnosticsBridge,
2557
+ id: bridgeId,
2558
+ statePrefix,
2559
+ connectXState,
2560
+ connectApi,
2561
+ connectRmtDiagnostics: connectRmtDiagnosticsBridge,
2562
+ createRmtDiagnosticsHub,
2563
+ mirrorDiagnosticToState,
2564
+ connectAll,
2565
+ getSnapshot(extra = {}) {
2566
+ return createRuntimeDiagnosticsSnapshot(bridgeId, extra);
2567
+ },
2568
+ readState(key, fallbackValue = undefined, stateTarget = null) {
2569
+ return readStateValue(getStateTarget(stateTarget), key, fallbackValue);
2570
+ },
2571
+ dispose() {
2572
+ disposed = true;
2573
+ connections.forEach((connection) => {
2574
+ if (connection && typeof connection.dispose === 'function') {
2575
+ connection.dispose();
2576
+ }
2577
+ });
2578
+ connections.splice(0, connections.length);
2579
+ }
2580
+ });
2581
+ }
2582
+
2583
+ const fabric = {
2584
+ schema: CONTRACTS.api,
2585
+ contracts: CONTRACTS,
2586
+ lanes: CANONICAL_LANES,
2587
+ createBoundary,
2588
+ createComponentLifecycleBoundary,
2589
+ createReporterAdapter,
2590
+ createConsoleReporter,
2591
+ createTestReporter,
2592
+ createComponentFiberInstrumentation,
2593
+ createRouteFiberInstrumentation,
2594
+ createRuntimeDiagnosticsBridge,
2595
+ createBackpressureSignal,
2596
+ recordComponentTelemetry,
2597
+ normalizeComponentLifecycleTelemetry,
2598
+ summarizeComponentLifecycleTelemetry,
2599
+ createTelemetrySnapshot,
2600
+ publishTelemetrySnapshot,
2601
+ exportTelemetrySnapshot: publishTelemetrySnapshot,
2602
+ wrapComponent,
2603
+ runFiber,
2604
+ emitDiagnostic,
2605
+ registerReporter,
2606
+ captureError,
2607
+ connectRmtDiagnostics,
2608
+ getDiagnostics() {
2609
+ return diagnostics.slice();
2610
+ },
2611
+ getFibers() {
2612
+ return fibers.slice();
2613
+ },
2614
+ getComponentTelemetry() {
2615
+ return componentTelemetry.slice();
2616
+ },
2617
+ getReporters() {
2618
+ return reporters.slice();
2619
+ },
2620
+ clearDiagnostics() {
2621
+ diagnostics.splice(0, diagnostics.length);
2622
+ },
2623
+ clearFibers() {
2624
+ fibers.splice(0, fibers.length);
2625
+ },
2626
+ clearComponentTelemetry() {
2627
+ componentTelemetry.splice(0, componentTelemetry.length);
2628
+ },
2629
+ dispose() {
2630
+ reporters.splice(1).forEach((reporter) => reporter.dispose());
2631
+ diagnostics.splice(0, diagnostics.length);
2632
+ fibers.splice(0, fibers.length);
2633
+ componentTelemetry.splice(0, componentTelemetry.length);
2634
+ }
2635
+ };
2636
+
2637
+ return Object.freeze(fabric);
2638
+ }
2639
+
2640
+ return Object.freeze({
2641
+ CONTRACTS,
2642
+ BROWSER_NAMESPACE,
2643
+ DEFAULT_LANE_BY_KIND,
2644
+ CANONICAL_LANES,
2645
+ LIFECYCLE_METHODS,
2646
+ LIFECYCLE_PHASES,
2647
+ COMPONENT_FIBER_OPERATION_PROFILES,
2648
+ ROUTE_FIBER_OPERATION_PROFILES,
2649
+ COMPONENT_LIFECYCLE_OPERATIONS,
2650
+ BACKPRESSURE_SCORE_THRESHOLDS,
2651
+ BACKPRESSURE_ACTION_BY_LEVEL,
2652
+ PERFORMANCE_MEASURE_PHASES,
2653
+ PERFORMANCE_MEASURE_NAME_BY_FIBER_KIND,
2654
+ PERFORMANCE_BUDGET_MS_BY_MEASURE,
2655
+ createXtendFabric,
2656
+ createNoopReporter,
2657
+ createReporterAdapter,
2658
+ createConsoleReporter,
2659
+ createTestReporter,
2660
+ normalizeComponentLifecycleTelemetry,
2661
+ summarizeComponentLifecycleTelemetry,
2662
+ normalizeDiagnostic,
2663
+ normalizeDiagnosticCode,
2664
+ normalizeError,
2665
+ normalizeFiber,
2666
+ redactDiagnostic,
2667
+ redactValue
2668
+ });
2669
+ });