@ccslabs/xtend 0.1.0-rc.1 → 0.1.2

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 (566) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +4 -0
  3. package/catalog/component-catalog-coverage.js +2 -0
  4. package/catalog/epic13-package-export-lock.js +11 -1
  5. package/catalog/epic13-rmt-production-readiness.js +0 -1
  6. package/catalog/epic18-rmt-action-effect-runtime.d.ts +36 -0
  7. package/catalog/epic18-rmt-action-effect-runtime.js +249 -0
  8. package/catalog/epic18-rmt-app-platform-authoring.d.ts +39 -0
  9. package/catalog/epic18-rmt-app-platform-authoring.js +319 -0
  10. package/catalog/epic18-rmt-app-platform-fixture.d.ts +33 -0
  11. package/catalog/epic18-rmt-app-platform-fixture.js +221 -0
  12. package/catalog/epic18-rmt-app-platform-release-handoff.d.ts +30 -0
  13. package/catalog/epic18-rmt-app-platform-release-handoff.js +231 -0
  14. package/catalog/epic18-rmt-app-platform-tooling.d.ts +38 -0
  15. package/catalog/epic18-rmt-app-platform-tooling.js +242 -0
  16. package/catalog/epic18-rmt-component-template-primitives.d.ts +33 -0
  17. package/catalog/epic18-rmt-component-template-primitives.js +240 -0
  18. package/catalog/epic18-rmt-dom-descriptor-renderer.d.ts +35 -0
  19. package/catalog/epic18-rmt-dom-descriptor-renderer.js +232 -0
  20. package/catalog/epic18-rmt-event-routing-runtime.d.ts +35 -0
  21. package/catalog/epic18-rmt-event-routing-runtime.js +234 -0
  22. package/catalog/epic18-rmt-state-selector-runtime.d.ts +34 -0
  23. package/catalog/epic18-rmt-state-selector-runtime.js +216 -0
  24. package/catalog/epic18-rmt-surface-resource-graph-runtime.d.ts +36 -0
  25. package/catalog/epic18-rmt-surface-resource-graph-runtime.js +256 -0
  26. package/catalog/surface-manager-controller.js +5 -1
  27. package/catalog/surface-manager-materialization.js +7 -1
  28. package/catalog/surface-manager-overlay-bridge.js +41 -6
  29. package/catalog/surface-manager-workbench-fixture.js +1 -1
  30. package/catalog/surface-type-capability-matrix.d.ts +61 -0
  31. package/catalog/surface-type-capability-matrix.js +183 -0
  32. package/catalog/type-exports-rmt.js +37 -1
  33. package/catalog/type-exports.js +3 -3
  34. package/components/icon-packs/lucide.js +4 -0
  35. package/components/manifest.json +2 -0
  36. package/components/prism-rmt.d.ts +34 -0
  37. package/components/prism-rmt.js +130 -0
  38. package/components/xcards.js +15 -0
  39. package/components/xcode.d.ts +36 -1
  40. package/components/xcode.js +215 -20
  41. package/components/xfooter.js +17 -0
  42. package/components/xheader.js +14 -0
  43. package/components/xhero.js +16 -1
  44. package/components/xlink.js +97 -14
  45. package/components/xmasonry.js +15 -0
  46. package/components/xplayer.d.ts +44 -2
  47. package/components/xplayer.js +242 -15
  48. package/components/xrouter.js +27 -2
  49. package/components/xsection.js +15 -0
  50. package/components/xsidepanel.js +10 -2
  51. package/components/xsurfacemanager-controller.d.ts +2 -1
  52. package/components/xsurfacemanager-controller.js +27 -3
  53. package/components/xsurfacemanager.d.ts +2 -0
  54. package/components/xsurfacemanager.js +20 -8
  55. package/components/xsurfaceoverlay-bridge.d.ts +20 -5
  56. package/components/xsurfaceoverlay-bridge.js +114 -18
  57. package/components/xsurfaceportal.d.ts +29 -0
  58. package/components/xsurfaceportal.js +122 -0
  59. package/components/xsurfaceregion.d.ts +50 -0
  60. package/components/xsurfaceregion.js +285 -0
  61. package/components/xsurfacewindow.js +2 -1
  62. package/components/xtooltip.js +89 -23
  63. package/docs/README.md +222 -298
  64. package/docs/changelog.md +107 -0
  65. package/docs/component-catalog-coverage.md +9 -9
  66. package/docs/component-platform.md +19 -1
  67. package/docs/component-ux-app-authoring.md +56 -63
  68. package/docs/components/xcode.md +83 -53
  69. package/docs/components/xsurfaceportal.md +32 -0
  70. package/docs/components/xsurfaceregion.md +37 -0
  71. package/docs/components.md +105 -69
  72. package/docs/de/README.md +264 -0
  73. package/docs/de/XTend-ADR.md +221 -0
  74. package/docs/de/a11y-keyboard-smokes.md +62 -0
  75. package/docs/de/about.md +18 -0
  76. package/docs/de/api.md +157 -0
  77. package/docs/de/best-practices.md +76 -0
  78. package/docs/de/changelog.md +107 -0
  79. package/docs/de/component-catalog-coverage.md +58 -0
  80. package/docs/de/component-lab.md +103 -0
  81. package/docs/de/component-long-tail-migration.md +41 -0
  82. package/docs/de/component-platform.md +177 -0
  83. package/docs/de/component-ux-app-authoring.md +123 -0
  84. package/docs/de/component-ux-authoring.md +96 -0
  85. package/docs/de/component-ux-gates.md +45 -0
  86. package/docs/de/components/x-rmt-lifecycle-demo-build.md +60 -0
  87. package/docs/de/components/xalert.md +81 -0
  88. package/docs/de/components/xbutton.md +103 -0
  89. package/docs/de/components/xcalendar.md +82 -0
  90. package/docs/de/components/xcards.md +128 -0
  91. package/docs/de/components/xcheckbox.md +102 -0
  92. package/docs/de/components/xcode.md +156 -0
  93. package/docs/de/components/xdialog.md +92 -0
  94. package/docs/de/components/xdrawer.md +84 -0
  95. package/docs/de/components/xfooter.md +126 -0
  96. package/docs/de/components/xform.md +128 -0
  97. package/docs/de/components/xheader.md +308 -0
  98. package/docs/de/components/xhero.md +142 -0
  99. package/docs/de/components/xicon.md +125 -0
  100. package/docs/de/components/xinput.md +129 -0
  101. package/docs/de/components/xlightbox.md +98 -0
  102. package/docs/de/components/xlink.md +109 -0
  103. package/docs/de/components/xmasonry.md +124 -0
  104. package/docs/de/components/xmenu.md +158 -0
  105. package/docs/de/components/xmodal.md +82 -0
  106. package/docs/de/components/xplayer.md +104 -0
  107. package/docs/de/components/xpopover.md +67 -0
  108. package/docs/de/components/xprogress.md +56 -0
  109. package/docs/de/components/xradio.md +103 -0
  110. package/docs/de/components/xrouter.md +260 -0
  111. package/docs/de/components/xsection.md +125 -0
  112. package/docs/de/components/xselect.md +105 -0
  113. package/docs/de/components/xsidepanel.md +30 -0
  114. package/docs/de/components/xspinner.md +102 -0
  115. package/docs/de/components/xstate.md +148 -0
  116. package/docs/de/components/xstatus.md +55 -0
  117. package/docs/de/components/xsummary.md +78 -0
  118. package/docs/de/components/xsurfacemanager.md +27 -0
  119. package/docs/de/components/xsurfacewindow.md +21 -0
  120. package/docs/de/components/xtabs.md +160 -0
  121. package/docs/de/components/xtextarea.md +98 -0
  122. package/docs/de/components/xtheme.md +167 -0
  123. package/docs/de/components/xtoast.md +62 -0
  124. package/docs/de/components/xtooltip.md +66 -0
  125. package/docs/de/components/xtype.md +82 -0
  126. package/docs/de/components/xutils.md +144 -0
  127. package/docs/de/components/xwriter.md +94 -0
  128. package/docs/de/components.md +153 -0
  129. package/docs/de/conditional-network-evidence-ci.md +38 -0
  130. package/docs/de/conditional-network-evidence.md +50 -0
  131. package/docs/de/core-migration-guide.md +110 -0
  132. package/docs/de/design-tokens.md +116 -0
  133. package/docs/de/docs-rmt-production-hardening.md +31 -0
  134. package/docs/de/enterprise-adoption.md +413 -0
  135. package/docs/de/enterprise-component-flex-release-handoff.md +129 -0
  136. package/docs/de/epic10-platform-gates.md +62 -0
  137. package/docs/de/epic10-release-handoff.md +81 -0
  138. package/docs/de/epic11-enterprise-ux-handoff.md +70 -0
  139. package/docs/de/epic12-rc0-handoff.md +61 -0
  140. package/docs/de/epic18-media-manager-vendor-upstream.md +318 -0
  141. package/docs/de/epic18-rmt-app-platform-release-handoff.md +67 -0
  142. package/docs/de/epic18-vendor-bugfixes.md +34 -0
  143. package/docs/de/existing-component-metadata.md +67 -0
  144. package/docs/de/hydration-performance-closure.md +34 -0
  145. package/docs/de/hydration-policies.md +71 -0
  146. package/docs/de/known-residual-triage.md +22 -0
  147. package/docs/de/manifest-import-policy.md +79 -0
  148. package/docs/de/manifest.md +112 -0
  149. package/docs/de/motion-contrast.md +67 -0
  150. package/docs/de/package-export-lock.md +44 -0
  151. package/docs/de/performance-measurements.md +106 -0
  152. package/docs/de/performance-regression.md +89 -0
  153. package/docs/de/performance.md +94 -0
  154. package/docs/de/previews/README.md +17 -0
  155. package/docs/de/prod-browser-csp-smokes.md +40 -0
  156. package/docs/de/public-component-types.md +79 -0
  157. package/docs/de/quick-start-guide.md +220 -0
  158. package/docs/de/rc0-adoption-guide.md +102 -0
  159. package/docs/de/rc0-gate-matrix.md +58 -0
  160. package/docs/de/rc1-gate-matrix-ci-handoff.md +56 -0
  161. package/docs/de/rc1-migration-notes.md +69 -0
  162. package/docs/de/rc1-readiness.md +46 -0
  163. package/docs/de/release-owner-acceptance.md +56 -0
  164. package/docs/de/release-report-pack-dry-run-evidence.md +39 -0
  165. package/docs/de/rmt-action-effect-runtime.md +81 -0
  166. package/docs/de/rmt-app-platform-authoring.md +54 -0
  167. package/docs/de/rmt-app-platform-fixture.md +46 -0
  168. package/docs/de/rmt-app-platform-migration-guide.md +88 -0
  169. package/docs/de/rmt-app-platform-tooling.md +79 -0
  170. package/docs/de/rmt-component-template-primitives.md +57 -0
  171. package/docs/de/rmt-dom-descriptor-renderer.md +64 -0
  172. package/docs/de/rmt-dsl-authoring-polish.md +145 -0
  173. package/docs/de/rmt-event-routing-runtime.md +81 -0
  174. package/docs/de/rmt-first-demo-app.md +77 -0
  175. package/docs/de/rmt-first-xtend-apps.md +129 -0
  176. package/docs/de/rmt-kernel-panic-recovery-incident-handoff.md +61 -0
  177. package/docs/de/rmt-kernel-security-hardening-migration.md +50 -0
  178. package/docs/de/rmt-kernel-trusted-output-authoring.md +69 -0
  179. package/docs/de/rmt-language-server.md +234 -0
  180. package/docs/de/rmt-lifecycle-demo.md +24 -0
  181. package/docs/de/rmt-linter.md +140 -0
  182. package/docs/de/rmt-node-ssr-adapter.md +100 -0
  183. package/docs/de/rmt-php-ssr-adapter.md +120 -0
  184. package/docs/de/rmt-production-readiness.md +63 -0
  185. package/docs/de/rmt-state-selector-runtime.md +47 -0
  186. package/docs/de/rmt-surface-resource-graph-runtime.md +92 -0
  187. package/docs/de/rmt-tooling-release-gates.md +77 -0
  188. package/docs/de/rmt-vnext-authoring.md +170 -0
  189. package/docs/de/rmt-vnext-component-primitives.md +188 -0
  190. package/docs/de/rmt-vnext-cross-surface-events.md +68 -0
  191. package/docs/de/rmt-vnext-enterprise-mfe-handoff.md +70 -0
  192. package/docs/de/rmt-vnext-fabric-bridge-evidence.md +81 -0
  193. package/docs/de/rmt-vnext-migration-notes.md +62 -0
  194. package/docs/de/rmt-vnext-primitive-authoring-tooling.md +247 -0
  195. package/docs/de/rmt-vnext-primitive-grammar-design.md +289 -0
  196. package/docs/de/rmt-vnext-primitive-lowering.md +108 -0
  197. package/docs/de/rmt-vnext-primitive-migration.md +119 -0
  198. package/docs/de/rmt-vnext-primitive-parser-ast.md +76 -0
  199. package/docs/de/rmt-vnext-primitive-semantic-graph.md +118 -0
  200. package/docs/de/rmt-vnext-primitives-compiler-backlog.md +739 -0
  201. package/docs/de/rmt-vnext-release-handoff.md +83 -0
  202. package/docs/de/rmt-vnext-remote-surfaces.md +90 -0
  203. package/docs/de/rmt-vnext-source-to-sea-gate.md +612 -0
  204. package/docs/de/rmt-vnext-surface-registry-enterprise.md +76 -0
  205. package/docs/de/screenreader-signals.md +56 -0
  206. package/docs/de/supply-chain-gates.md +100 -0
  207. package/docs/de/surface-manager-authoring-guide.md +94 -0
  208. package/docs/de/surface-manager-browser-lab.md +45 -0
  209. package/docs/de/surface-manager-component-lab.md +43 -0
  210. package/docs/de/surface-manager-controller.md +66 -0
  211. package/docs/de/surface-manager-layout-engines.md +32 -0
  212. package/docs/de/surface-manager-lazy-hydration.md +63 -0
  213. package/docs/de/surface-manager-migration-guide.md +122 -0
  214. package/docs/de/surface-manager-native-rmt-surfaces.md +38 -0
  215. package/docs/de/surface-manager-overlay-bridge.md +53 -0
  216. package/docs/de/surface-manager-persistence.md +30 -0
  217. package/docs/de/surface-manager-quality-gates.md +51 -0
  218. package/docs/de/surface-manager-release-handoff.md +68 -0
  219. package/docs/de/surface-manager-remote-policy.md +54 -0
  220. package/docs/de/surface-manager-rmt-authoring.md +102 -0
  221. package/docs/de/surface-manager-route-lifecycle.md +59 -0
  222. package/docs/de/surface-manager-runtime-release-handoff.md +69 -0
  223. package/docs/de/surface-manager-side-panel-runtime.md +36 -0
  224. package/docs/de/surface-manager-stack-policy.md +39 -0
  225. package/docs/de/surface-manager-window-runtime.md +47 -0
  226. package/docs/de/surface-manager-workbench-fixture.md +43 -0
  227. package/docs/de/third-party-design-authoring.md +406 -0
  228. package/docs/de/trusted-dom-boundary-browser-proof.md +32 -0
  229. package/docs/de/trusted-dom-sanitizing.md +110 -0
  230. package/docs/de/type-exports.md +61 -0
  231. package/docs/de/typescript-components.md +63 -0
  232. package/docs/de/visual-browser-regression.md +83 -0
  233. package/docs/de/visual-owner-artifacts.md +46 -0
  234. package/docs/de/visual-snapshot-automation.md +87 -0
  235. package/docs/de/xtend-api-types.md +55 -0
  236. package/docs/de/xtend-builder-types.md +55 -0
  237. package/docs/de/xtend-catalog-types.md +44 -0
  238. package/docs/de/xtend-fabric-rmt-lane-mapping.md +143 -0
  239. package/docs/de/xtend-fabric.md +474 -0
  240. package/docs/de/xtend-loader-types.md +58 -0
  241. package/docs/de/xtend-loader.md +265 -0
  242. package/docs/de/xtend-policy-types.md +38 -0
  243. package/docs/de/xtend-rmt-types.md +40 -0
  244. package/docs/de/xtend-vendor-types.md +36 -0
  245. package/docs/de/xtendrmt-app-dsl.md +334 -0
  246. package/docs/de/xtendrmt-migration-guide.md +266 -0
  247. package/docs/de/xtendrmt-native-authoring.md +333 -0
  248. package/docs/de/xtendrmt-overview.md +109 -0
  249. package/docs/de/xtendrmt-parsedown-scheduling.md +301 -0
  250. package/docs/de/xtendrmt-runtime-bridge.md +155 -0
  251. package/docs/en/README.md +163 -0
  252. package/docs/en/XTend-ADR.md +221 -0
  253. package/docs/en/a11y-keyboard-smokes.md +68 -0
  254. package/docs/en/about.md +25 -0
  255. package/docs/en/api.md +171 -0
  256. package/docs/en/best-practices.md +125 -0
  257. package/docs/en/changelog.md +104 -0
  258. package/docs/en/component-catalog-coverage.md +104 -0
  259. package/docs/en/component-lab.md +103 -0
  260. package/docs/en/component-long-tail-migration.md +41 -0
  261. package/docs/en/component-platform.md +243 -0
  262. package/docs/en/component-ux-app-authoring.md +118 -0
  263. package/docs/en/component-ux-authoring.md +96 -0
  264. package/docs/en/component-ux-gates.md +45 -0
  265. package/docs/en/components/x-rmt-lifecycle-demo-build.md +75 -0
  266. package/docs/en/components/xalert.md +94 -0
  267. package/docs/en/components/xbutton.md +118 -0
  268. package/docs/en/components/xcalendar.md +95 -0
  269. package/docs/en/components/xcards.md +139 -0
  270. package/docs/en/components/xcheckbox.md +118 -0
  271. package/docs/en/components/xcode.md +153 -0
  272. package/docs/en/components/xdialog.md +108 -0
  273. package/docs/en/components/xdrawer.md +110 -0
  274. package/docs/en/components/xfooter.md +138 -0
  275. package/docs/en/components/xform.md +147 -0
  276. package/docs/en/components/xheader.md +308 -0
  277. package/docs/en/components/xhero.md +157 -0
  278. package/docs/en/components/xicon.md +149 -0
  279. package/docs/en/components/xinput.md +147 -0
  280. package/docs/en/components/xlightbox.md +113 -0
  281. package/docs/en/components/xlink.md +130 -0
  282. package/docs/en/components/xmasonry.md +136 -0
  283. package/docs/en/components/xmenu.md +185 -0
  284. package/docs/en/components/xmodal.md +102 -0
  285. package/docs/en/components/xplayer.md +114 -0
  286. package/docs/en/components/xpopover.md +87 -0
  287. package/docs/en/components/xprogress.md +73 -0
  288. package/docs/en/components/xradio.md +119 -0
  289. package/docs/en/components/xrouter.md +260 -0
  290. package/docs/en/components/xsection.md +136 -0
  291. package/docs/en/components/xselect.md +122 -0
  292. package/docs/en/components/xsidepanel.md +48 -0
  293. package/docs/en/components/xspinner.md +118 -0
  294. package/docs/en/components/xstate.md +163 -0
  295. package/docs/en/components/xstatus.md +71 -0
  296. package/docs/en/components/xsummary.md +90 -0
  297. package/docs/en/components/xsurfacemanager.md +42 -0
  298. package/docs/en/components/xsurfacewindow.md +31 -0
  299. package/docs/en/components/xtabs.md +187 -0
  300. package/docs/en/components/xtextarea.md +115 -0
  301. package/docs/en/components/xtheme.md +203 -0
  302. package/docs/en/components/xtoast.md +78 -0
  303. package/docs/en/components/xtooltip.md +85 -0
  304. package/docs/en/components/xtype.md +91 -0
  305. package/docs/en/components/xutils.md +161 -0
  306. package/docs/en/components/xwriter.md +106 -0
  307. package/docs/en/components.md +151 -0
  308. package/docs/en/conditional-network-evidence-ci.md +38 -0
  309. package/docs/en/conditional-network-evidence.md +50 -0
  310. package/docs/en/core-migration-guide.md +110 -0
  311. package/docs/en/design-tokens.md +137 -0
  312. package/docs/en/docs-rmt-production-hardening.md +31 -0
  313. package/docs/en/enterprise-adoption.md +413 -0
  314. package/docs/en/enterprise-component-flex-release-handoff.md +129 -0
  315. package/docs/en/epic10-platform-gates.md +62 -0
  316. package/docs/en/epic10-release-handoff.md +81 -0
  317. package/docs/en/epic11-enterprise-ux-handoff.md +70 -0
  318. package/docs/en/epic12-rc0-handoff.md +61 -0
  319. package/docs/en/epic18-media-manager-vendor-upstream.md +232 -0
  320. package/docs/en/epic18-rmt-app-platform-release-handoff.md +60 -0
  321. package/docs/en/epic18-vendor-bugfixes.md +29 -0
  322. package/docs/en/existing-component-metadata.md +67 -0
  323. package/docs/en/hydration-performance-closure.md +34 -0
  324. package/docs/en/hydration-policies.md +75 -0
  325. package/docs/en/known-residual-triage.md +22 -0
  326. package/docs/en/manifest-import-policy.md +81 -0
  327. package/docs/en/manifest.md +135 -0
  328. package/docs/en/motion-contrast.md +67 -0
  329. package/docs/en/package-export-lock.md +44 -0
  330. package/docs/en/performance-measurements.md +106 -0
  331. package/docs/en/performance-regression.md +89 -0
  332. package/docs/en/performance.md +132 -0
  333. package/docs/en/previews/README.md +17 -0
  334. package/docs/en/prod-browser-csp-smokes.md +40 -0
  335. package/docs/en/public-component-types.md +79 -0
  336. package/docs/en/quick-start-guide.md +189 -0
  337. package/docs/en/rc0-adoption-guide.md +102 -0
  338. package/docs/en/rc0-gate-matrix.md +58 -0
  339. package/docs/en/rc1-gate-matrix-ci-handoff.md +56 -0
  340. package/docs/en/rc1-migration-notes.md +69 -0
  341. package/docs/en/rc1-readiness.md +46 -0
  342. package/docs/en/release-owner-acceptance.md +56 -0
  343. package/docs/en/release-report-pack-dry-run-evidence.md +39 -0
  344. package/docs/en/rmt-action-effect-runtime.md +101 -0
  345. package/docs/en/rmt-app-platform-authoring.md +47 -0
  346. package/docs/en/rmt-app-platform-fixture.md +35 -0
  347. package/docs/en/rmt-app-platform-migration-guide.md +75 -0
  348. package/docs/en/rmt-app-platform-tooling.md +58 -0
  349. package/docs/en/rmt-component-template-primitives.md +49 -0
  350. package/docs/en/rmt-dom-descriptor-renderer.md +54 -0
  351. package/docs/en/rmt-dsl-authoring-polish.md +143 -0
  352. package/docs/en/rmt-event-routing-runtime.md +98 -0
  353. package/docs/en/rmt-first-demo-app.md +87 -0
  354. package/docs/en/rmt-first-xtend-apps.md +127 -0
  355. package/docs/en/rmt-kernel-panic-recovery-incident-handoff.md +60 -0
  356. package/docs/en/rmt-kernel-security-hardening-migration.md +49 -0
  357. package/docs/en/rmt-kernel-trusted-output-authoring.md +68 -0
  358. package/docs/en/rmt-language-server.md +243 -0
  359. package/docs/en/rmt-lifecycle-demo.md +23 -0
  360. package/docs/en/rmt-linter.md +146 -0
  361. package/docs/en/rmt-node-ssr-adapter.md +99 -0
  362. package/docs/en/rmt-php-ssr-adapter.md +118 -0
  363. package/docs/en/rmt-production-readiness.md +63 -0
  364. package/docs/en/rmt-state-selector-runtime.md +34 -0
  365. package/docs/en/rmt-surface-resource-graph-runtime.md +68 -0
  366. package/docs/en/rmt-tooling-release-gates.md +77 -0
  367. package/docs/en/rmt-vnext-authoring.md +102 -0
  368. package/docs/en/rmt-vnext-component-primitives.md +185 -0
  369. package/docs/en/rmt-vnext-cross-surface-events.md +59 -0
  370. package/docs/en/rmt-vnext-enterprise-mfe-handoff.md +62 -0
  371. package/docs/en/rmt-vnext-fabric-bridge-evidence.md +64 -0
  372. package/docs/en/rmt-vnext-migration-notes.md +62 -0
  373. package/docs/en/rmt-vnext-primitive-authoring-tooling.md +174 -0
  374. package/docs/en/rmt-vnext-primitive-grammar-design.md +268 -0
  375. package/docs/en/rmt-vnext-primitive-lowering.md +91 -0
  376. package/docs/en/rmt-vnext-primitive-migration.md +93 -0
  377. package/docs/en/rmt-vnext-primitive-parser-ast.md +59 -0
  378. package/docs/en/rmt-vnext-primitive-semantic-graph.md +103 -0
  379. package/docs/en/rmt-vnext-primitives-compiler-backlog.md +327 -0
  380. package/docs/en/rmt-vnext-release-handoff.md +83 -0
  381. package/docs/en/rmt-vnext-remote-surfaces.md +81 -0
  382. package/docs/en/rmt-vnext-source-to-sea-gate.md +482 -0
  383. package/docs/en/rmt-vnext-surface-registry-enterprise.md +68 -0
  384. package/docs/en/screenreader-signals.md +56 -0
  385. package/docs/en/supply-chain-gates.md +106 -0
  386. package/docs/en/surface-manager-authoring-guide.md +94 -0
  387. package/docs/en/surface-manager-browser-lab.md +45 -0
  388. package/docs/en/surface-manager-component-lab.md +43 -0
  389. package/docs/en/surface-manager-controller.md +66 -0
  390. package/docs/en/surface-manager-layout-engines.md +32 -0
  391. package/docs/en/surface-manager-lazy-hydration.md +63 -0
  392. package/docs/en/surface-manager-migration-guide.md +113 -0
  393. package/docs/en/surface-manager-native-rmt-surfaces.md +38 -0
  394. package/docs/en/surface-manager-overlay-bridge.md +53 -0
  395. package/docs/en/surface-manager-persistence.md +30 -0
  396. package/docs/en/surface-manager-quality-gates.md +51 -0
  397. package/docs/en/surface-manager-release-handoff.md +68 -0
  398. package/docs/en/surface-manager-remote-policy.md +54 -0
  399. package/docs/en/surface-manager-rmt-authoring.md +89 -0
  400. package/docs/en/surface-manager-route-lifecycle.md +59 -0
  401. package/docs/en/surface-manager-runtime-release-handoff.md +69 -0
  402. package/docs/en/surface-manager-side-panel-runtime.md +36 -0
  403. package/docs/en/surface-manager-stack-policy.md +39 -0
  404. package/docs/en/surface-manager-window-runtime.md +47 -0
  405. package/docs/en/surface-manager-workbench-fixture.md +43 -0
  406. package/docs/en/third-party-design-authoring.md +406 -0
  407. package/docs/en/trusted-dom-boundary-browser-proof.md +32 -0
  408. package/docs/en/trusted-dom-sanitizing.md +124 -0
  409. package/docs/en/type-exports.md +61 -0
  410. package/docs/en/typescript-components.md +63 -0
  411. package/docs/en/visual-browser-regression.md +83 -0
  412. package/docs/en/visual-owner-artifacts.md +46 -0
  413. package/docs/en/visual-snapshot-automation.md +87 -0
  414. package/docs/en/xtend-api-types.md +55 -0
  415. package/docs/en/xtend-builder-types.md +55 -0
  416. package/docs/en/xtend-catalog-types.md +44 -0
  417. package/docs/en/xtend-fabric-rmt-lane-mapping.md +143 -0
  418. package/docs/en/xtend-fabric.md +474 -0
  419. package/docs/en/xtend-loader-types.md +58 -0
  420. package/docs/en/xtend-loader.md +265 -0
  421. package/docs/en/xtend-policy-types.md +38 -0
  422. package/docs/en/xtend-rmt-types.md +40 -0
  423. package/docs/en/xtend-vendor-types.md +36 -0
  424. package/docs/en/xtendrmt-app-dsl.md +331 -0
  425. package/docs/en/xtendrmt-migration-guide.md +256 -0
  426. package/docs/en/xtendrmt-native-authoring.md +336 -0
  427. package/docs/en/xtendrmt-overview.md +63 -0
  428. package/docs/en/xtendrmt-parsedown-scheduling.md +301 -0
  429. package/docs/en/xtendrmt-runtime-bridge.md +155 -0
  430. package/docs/enterprise-adoption.md +4 -2
  431. package/docs/epic18-media-manager-vendor-upstream.md +318 -0
  432. package/docs/epic18-rmt-app-platform-release-handoff.md +67 -0
  433. package/docs/epic18-vendor-bugfixes.md +34 -0
  434. package/docs/index.php +1056 -109
  435. package/docs/manifest.md +8 -2
  436. package/docs/menu.json +986 -133
  437. package/docs/package-export-lock.md +2 -2
  438. package/docs/public-component-types.md +2 -2
  439. package/docs/quick-start-guide.md +126 -58
  440. package/docs/rmt-action-effect-runtime.md +101 -0
  441. package/docs/rmt-app-platform-authoring.md +54 -0
  442. package/docs/rmt-app-platform-fixture.md +46 -0
  443. package/docs/rmt-app-platform-migration-guide.md +88 -0
  444. package/docs/rmt-app-platform-tooling.md +79 -0
  445. package/docs/rmt-component-template-primitives.md +57 -0
  446. package/docs/rmt-dom-descriptor-renderer.md +64 -0
  447. package/docs/rmt-dsl-authoring-polish.md +67 -44
  448. package/docs/rmt-event-routing-runtime.md +98 -0
  449. package/docs/rmt-first-demo-app.md +2 -2
  450. package/docs/rmt-first-xtend-apps.md +70 -46
  451. package/docs/rmt-language-server.md +61 -4
  452. package/docs/rmt-lifecycle-demo.md +1 -2
  453. package/docs/rmt-node-ssr-adapter.md +144 -0
  454. package/docs/rmt-php-ssr-adapter.md +158 -0
  455. package/docs/rmt-state-selector-runtime.md +47 -0
  456. package/docs/rmt-surface-resource-graph-runtime.md +92 -0
  457. package/docs/rmt-vnext-authoring.md +128 -18
  458. package/docs/rmt-vnext-component-primitives.md +188 -0
  459. package/docs/rmt-vnext-fabric-bridge-evidence.md +81 -0
  460. package/docs/rmt-vnext-primitive-authoring-tooling.md +247 -0
  461. package/docs/rmt-vnext-primitive-grammar-design.md +289 -0
  462. package/docs/rmt-vnext-primitive-lowering.md +108 -0
  463. package/docs/rmt-vnext-primitive-migration.md +119 -0
  464. package/docs/rmt-vnext-primitive-parser-ast.md +76 -0
  465. package/docs/rmt-vnext-primitive-semantic-graph.md +118 -0
  466. package/docs/rmt-vnext-primitives-compiler-backlog.md +742 -0
  467. package/docs/rmt-vnext-release-handoff.md +14 -0
  468. package/docs/rmt-vnext-source-to-sea-gate.md +629 -0
  469. package/docs/surface-manager-migration-guide.md +34 -6
  470. package/docs/surface-manager-overlay-bridge.md +9 -4
  471. package/docs/surface-manager-rmt-authoring.md +50 -34
  472. package/docs/surface-manager-workbench-fixture.md +1 -2
  473. package/docs/third-party-design-authoring.md +1 -1
  474. package/docs/type-exports.md +3 -3
  475. package/docs/utils/pageloader.js +811 -62
  476. package/docs/visual-browser-regression.md +1 -1
  477. package/docs/xtend-rmt-types.md +3 -2
  478. package/docs/xtendrmt-app-dsl.md +187 -122
  479. package/docs/xtendrmt-docs-shell-vnext.rmt +165 -0
  480. package/docs/xtendrmt-migration-guide.md +48 -17
  481. package/docs/xtendrmt-native-authoring.md +213 -217
  482. package/docs/xtendrmt-overview.md +81 -61
  483. package/docs/xtendrmt-parsedown-scheduling.md +23 -8
  484. package/fabric/package.json +1 -1
  485. package/package.json +684 -21
  486. package/tools/package.json +5 -1
  487. package/tools/rmt-editor/vscode/README.md +72 -5
  488. package/tools/rmt-editor/vscode/XTend-Logo.png +0 -0
  489. package/tools/rmt-editor/vscode/extension.d.ts +33 -0
  490. package/tools/rmt-editor/vscode/extension.js +1816 -7
  491. package/tools/rmt-editor/vscode/language-configuration.json +2 -1
  492. package/tools/rmt-editor/vscode/package.json +193 -2
  493. package/tools/rmt-editor/vscode/snippets/rmt.code-snippets +41 -0
  494. package/tools/rmt-editor/vscode/syntaxes/rmt.tmLanguage.json +103 -1
  495. package/tools/rmt-editor/vscode/templates/launch.json +70 -0
  496. package/tools/rmt-editor/vscode/templates/tasks.json +172 -0
  497. package/tools/rmt-editor/vscode/xtend-rmt-language-0.0.0-enterprise-readiness.vsix +0 -0
  498. package/tools/rmt-language/app-platform-tooling.d.ts +128 -0
  499. package/tools/rmt-language/app-platform-tooling.js +677 -0
  500. package/tools/rmt-language/completions.d.ts +5 -0
  501. package/tools/rmt-language/completions.js +185 -3
  502. package/tools/rmt-language/diagnostics.js +54 -0
  503. package/tools/rmt-language/hover.js +36 -0
  504. package/tools/rmt-language/rmt-tooling-public-types.d.ts +7 -0
  505. package/tools/rmt-language/rules/app-platform-policy.js +39 -0
  506. package/tools/rmt-language/rules/index.js +5 -1
  507. package/tools/rmt-language/semantic-graph.d.ts +6 -0
  508. package/tools/rmt-language/semantic-graph.js +928 -0
  509. package/tools/rmt-language/snippets/index.js +44 -0
  510. package/tools/rmt-language/snippets/rmt.code-snippets +41 -0
  511. package/tools/rmt-language/vnext-compatibility.d.ts +10 -0
  512. package/tools/rmt-language/vnext-compatibility.js +642 -0
  513. package/tools/rmt-language/vnext-compiler.d.ts +5 -0
  514. package/tools/rmt-language/vnext-compiler.js +863 -17
  515. package/tools/rmt-language/vnext-parser.js +725 -9
  516. package/tools/rmt-language/vnext-release.d.ts +1 -0
  517. package/tools/rmt-language/vnext-release.js +20 -0
  518. package/tools/rmt-language/vnext-source-to-sea.d.ts +33 -0
  519. package/tools/rmt-language/vnext-source-to-sea.js +2227 -0
  520. package/tools/rmt-language/vnext-surfaces.js +111 -52
  521. package/tools/rmt-language/vnext-tooling.d.ts +19 -1
  522. package/tools/rmt-language/vnext-tooling.js +1247 -5
  523. package/tools/rmt-language-server/protocol.js +3 -0
  524. package/tools/rmt-language-server/server.d.ts +2 -0
  525. package/tools/rmt-language-server/server.js +176 -22
  526. package/tools/rmt-linter/cli.d.ts +2 -0
  527. package/tools/rmt-linter/cli.js +62 -0
  528. package/xtend-builder/generators/registry.js +11 -0
  529. package/xtend-builder/generators/rmt-app-platform.js +239 -0
  530. package/xtend-builder/generators/rmt-lifecycle-demo.js +3 -11
  531. package/xtend-builder/lib/cli.js +38 -0
  532. package/xtend-builder/package.json +3 -3
  533. package/xtend-builder/scaffold.config.js +29 -2
  534. package/xtend.css +49 -2
  535. package/xtendrmt/package.json +49 -1
  536. package/xtendrmt/rmt-action-effect-runtime.d.ts +126 -0
  537. package/xtendrmt/rmt-action-effect-runtime.js +494 -0
  538. package/xtendrmt/rmt-component-capability-registry.d.ts +180 -0
  539. package/xtendrmt/rmt-component-capability-registry.js +636 -0
  540. package/xtendrmt/rmt-core.d.ts +6 -0
  541. package/xtendrmt/rmt-core.esm.js +32 -6
  542. package/xtendrmt/rmt-dom-descriptor-renderer.d.ts +107 -0
  543. package/xtendrmt/rmt-dom-descriptor-renderer.js +1066 -0
  544. package/xtendrmt/rmt-event-routing-runtime.d.ts +144 -0
  545. package/xtendrmt/rmt-event-routing-runtime.js +666 -0
  546. package/xtendrmt/rmt-lifecycle-demo.app.js +2 -2
  547. package/xtendrmt/rmt-lifecycle-demo.core.json +4 -0
  548. package/xtendrmt/rmt-lifecycle-demo.rmt-build.app.js +1 -1
  549. package/xtendrmt/rmt-lifecycle-demo.rmt-build.scaffold.json +2 -2
  550. package/xtendrmt/rmt-lifecycle-demo.scaffold.json +4 -4
  551. package/xtendrmt/rmt-native-shell-runtime.d.ts +77 -0
  552. package/xtendrmt/rmt-native-shell-runtime.js +309 -0
  553. package/xtendrmt/rmt-node-ssr-adapter.d.ts +197 -0
  554. package/xtendrmt/rmt-node-ssr-adapter.js +1006 -0
  555. package/xtendrmt/rmt-php-ssr-adapter.php +976 -0
  556. package/xtendrmt/rmt-runtime.browser.js +32 -6
  557. package/xtendrmt/rmt-runtime.esm.js +32 -6
  558. package/xtendrmt/rmt-state-selector-runtime.d.ts +166 -0
  559. package/xtendrmt/rmt-state-selector-runtime.js +866 -0
  560. package/xtendrmt/rmt-surface-resource-graph-runtime.d.ts +224 -0
  561. package/xtendrmt/rmt-surface-resource-graph-runtime.js +932 -0
  562. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.core.json +3 -0
  563. package/xtendrmt/rmt-vnext-reference-demo.core.json +3 -0
  564. package/xtendrmt/xtendrmt-bestcase-demo.core.json +3420 -372
  565. package/xtendrmt/xtendrmt-bestcase-demo.js +424 -8
  566. package/xtendrmt/xtendrmt-bestcase-demo.rmt +214 -6
@@ -0,0 +1,2227 @@
1
+ const fs = require('fs');
2
+ const http = require('http');
3
+ const path = require('path');
4
+ const { spawn, spawnSync } = require('child_process');
5
+ const { pathToFileURL } = require('url');
6
+ const {
7
+ RMT_APP_PLATFORM_RECORDS_SCHEMA,
8
+ RMT_KERNEL_BOUNDARY,
9
+ RMT_KERNEL_RECORDS_SCHEMA,
10
+ compileRmtVNextSource
11
+ } = require('./vnext-compiler');
12
+ const {
13
+ createXtendFabric,
14
+ CONTRACTS: FABRIC_CONTRACTS
15
+ } = require('../../fabric/xtend-fabric');
16
+ const {
17
+ CONTRACTS: FABRIC_RMT_CONTRACTS,
18
+ resolveRmtScheduleForFiber
19
+ } = require('../../fabric/rmt-lane-mapping');
20
+
21
+ const RMT_VNEXT_SOURCE_TO_SEA_SCHEMA = 'xtend.rmt.vnext.source-to-sea-gate.v1';
22
+ const RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_SCHEMA = 'xtend.rmt.vnext.source-to-sea-evidence.v1';
23
+ const RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_SCHEMA = 'xtend.rmt.vnext.source-to-sea-evidence-report.v1';
24
+ const RMT_VNEXT_SOURCE_TO_SEA_OBJECT_MATRIX_SCHEMA = 'xtend.rmt.vnext.source-to-sea-object-matrix.v1';
25
+ const RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA = 'xtend.rmt.vnext.source-to-sea-ci-artifact-validation.v1';
26
+ const RMT_VNEXT_SOURCE_TO_SEA_BROWSER_PROBE_SCHEMA = 'xtend.rmt.vnext.source-to-sea-browser-probe.v1';
27
+ const RMT_VNEXT_SOURCE_TO_SEA_BROWSER_RESULT_VALIDATION_SCHEMA = 'xtend.rmt.vnext.source-to-sea-browser-result-validation.v1';
28
+ const RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE = 'RMT-VNEXT-PRIM-06';
29
+ const RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES = Object.freeze({
30
+ resourceMissing: 'rmt.vnext.source_to_sea.cleanup_resource_missing',
31
+ ownerMismatch: 'rmt.vnext.source_to_sea.cleanup_owner_mismatch',
32
+ disposePolicyMissing: 'rmt.vnext.source_to_sea.cleanup_dispose_policy_missing',
33
+ kindMismatch: 'rmt.vnext.source_to_sea.cleanup_kind_mismatch'
34
+ });
35
+ const RMT_VNEXT_FABRIC_BRIDGE_EVIDENCE_SCHEMA = 'xtend.rmt.vnext.fabric-bridge-evidence.v1';
36
+ const RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE = 'RMT-VNEXT-PRIM-05';
37
+ const RMT_VNEXT_BROWSER_EXECUTION_EVIDENCE_SCHEMA = 'xtend.rmt.vnext.browser-execution-evidence.v1';
38
+ const RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA = FABRIC_CONTRACTS.componentLifecycleTelemetry;
39
+ const RMT_VNEXT_ROUTE_COMPONENT_FIBER_EVIDENCE_SCHEMA = 'xtend.rmt.vnext.route-component-fiber-evidence.v1';
40
+ const RMT_VNEXT_ROUTE_COMPONENT_FIBER_SCENARIOS = Object.freeze({
41
+ component: Object.freeze({
42
+ componentRef: 'x-status',
43
+ routeRef: '/rmt-vnext-source-to-sea',
44
+ mountScheduleRef: 'component.visible.mount',
45
+ hydrateScheduleRef: 'component.idle.hydrate'
46
+ }),
47
+ route: Object.freeze({
48
+ routerRef: 'xtend.xrouter',
49
+ routeRef: '/rmt-vnext-source-to-sea',
50
+ routeId: 'rmt-vnext-source-to-sea',
51
+ navigateScheduleRef: 'ui.user-blocking.input',
52
+ renderScheduleRef: 'route.transition.render'
53
+ })
54
+ });
55
+ const RMT_VNEXT_FABRIC_BRIDGE_LANE_MATRIX = Object.freeze([
56
+ Object.freeze({ lane: 'user-blocking', kind: 'event.handler', phase: 'event' }),
57
+ Object.freeze({ lane: 'transition', kind: 'route.render', phase: 'render', routeRef: '/rmt-vnext-source-to-sea' }),
58
+ Object.freeze({ lane: 'idle', kind: 'component.hydrate', phase: 'hydrate' }),
59
+ Object.freeze({ lane: 'background', kind: 'component.disconnect', phase: 'disconnect' }),
60
+ Object.freeze({ lane: 'diagnostics', kind: 'diagnostics.snapshot', phase: 'diagnostics' })
61
+ ]);
62
+ const RMT_VNEXT_SOURCE_TO_SEA_MODULE_PATH = 'tools/rmt-language/vnext-source-to-sea.js';
63
+ const RMT_VNEXT_SOURCE_TO_SEA_SUITE_PATH = 'tests/rmt-language/rmt_vnext_source_to_sea_suite.js';
64
+ const RMT_VNEXT_SOURCE_TO_SEA_FIXTURE_PATH = 'tests/rmt-language/fixtures/vnext-source-to-sea.rmt';
65
+ const RMT_VNEXT_SOURCE_TO_SEA_BROWSER_FIXTURE_PATH = 'tests/browser/fixtures/rmt-vnext-source-to-sea-smoke.html';
66
+ const RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH = '.xtend-test-results/xtend-rmt-vnext-source-to-sea-evidence.json';
67
+ const RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY = '__xtendRmtVNextSourceToSeaResult';
68
+ const RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_DRIVER = 'chromedriver';
69
+ const RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_NAME = 'chrome';
70
+ const RMT_VNEXT_SOURCE_TO_SEA_CI_WEBDRIVER_PORT = 9515;
71
+ const RMT_VNEXT_SOURCE_TO_SEA_SUPPORTED_BROWSER_DRIVERS = Object.freeze([
72
+ 'webdriver',
73
+ 'chromedriver',
74
+ 'chrome',
75
+ 'chromium',
76
+ 'firefox',
77
+ 'geckodriver',
78
+ 'safari',
79
+ 'safaridriver',
80
+ 'edge',
81
+ 'msedge',
82
+ 'msedgedriver'
83
+ ]);
84
+
85
+ function toArray(value) {
86
+ return Array.isArray(value) ? value : [];
87
+ }
88
+
89
+ function escapeRegExp(value) {
90
+ return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
91
+ }
92
+
93
+ function parseJsonScript(html, scriptId) {
94
+ if (typeof html !== 'string' || !html) {
95
+ return null;
96
+ }
97
+
98
+ const pattern = new RegExp(`<script[^>]*id=["']${escapeRegExp(scriptId)}["'][^>]*>([\\s\\S]*?)<\\/script>`, 'i');
99
+ const match = html.match(pattern);
100
+ if (!match) {
101
+ return null;
102
+ }
103
+
104
+ try {
105
+ return JSON.parse(match[1]);
106
+ } catch (_) {
107
+ return null;
108
+ }
109
+ }
110
+
111
+ function artifactCount(coreDocument) {
112
+ if (!coreDocument) {
113
+ return 0;
114
+ }
115
+
116
+ return [
117
+ coreDocument.appPlatform,
118
+ coreDocument.kernelRecords,
119
+ coreDocument.sourceMap,
120
+ coreDocument.states,
121
+ coreDocument.selectors,
122
+ coreDocument.actions,
123
+ coreDocument.surfaces,
124
+ coreDocument.events,
125
+ coreDocument.resources
126
+ ].filter((artifact) => Array.isArray(artifact) ? artifact.length > 0 : Boolean(artifact)).length;
127
+ }
128
+
129
+ function findSurface(coreDocument, primitiveId) {
130
+ const appSurface = toArray(coreDocument && coreDocument.appPlatform && coreDocument.appPlatform.surfaces)
131
+ .find((surface) => surface.id === primitiveId);
132
+ const coreSurface = toArray(coreDocument && coreDocument.surfaces)
133
+ .find((surface) => surface.name === primitiveId || surface.id === `surface:${coreDocument.manifest && coreDocument.manifest.documentId}/${primitiveId}`);
134
+
135
+ return {
136
+ appSurface: appSurface || null,
137
+ coreSurface: coreSurface || null
138
+ };
139
+ }
140
+
141
+ function findEvent(coreDocument, coreSurface, actionId) {
142
+ const eventRefs = new Set(toArray(coreSurface && coreSurface.eventRefs));
143
+ return toArray(coreDocument && coreDocument.events)
144
+ .find((event) => event.action === actionId || eventRefs.has(event.id)) || null;
145
+ }
146
+
147
+ function findSourceMapEntry(coreDocument, record) {
148
+ return toArray(coreDocument && coreDocument.sourceMap)
149
+ .find((entry) => entry.id === (record && record.sourceRef)) || null;
150
+ }
151
+
152
+ function findSchedule(kernelRecords, coreSurface, preferredLane) {
153
+ const schedules = toArray(kernelRecords && kernelRecords.schedules);
154
+ return schedules.find((schedule) => schedule.scope && schedule.scope.surface === (coreSurface && coreSurface.id) && schedule.lane === preferredLane)
155
+ || schedules.find((schedule) => schedule.lane === preferredLane)
156
+ || schedules[0]
157
+ || null;
158
+ }
159
+
160
+ function findFiber(kernelRecords, schedule) {
161
+ const operationRefs = new Set(toArray(schedule && schedule.operationRefs));
162
+ return toArray(kernelRecords && kernelRecords.fibers)
163
+ .find((fiber) => operationRefs.has(fiber.operation))
164
+ || toArray(kernelRecords && kernelRecords.fibers)[0]
165
+ || null;
166
+ }
167
+
168
+ function containsKernelHostImport(kernelRecords) {
169
+ return String(JSON.stringify(kernelRecords || {})).includes('@ccslabs/xtend/components');
170
+ }
171
+
172
+ function createCheck(name, ok, details = null) {
173
+ return { name, ok: Boolean(ok), details };
174
+ }
175
+
176
+ function createIncrementingClock() {
177
+ let tick = 0;
178
+ return () => new Date(Date.UTC(2026, 4, 19, 12, 0, tick++));
179
+ }
180
+
181
+ function wait(ms) {
182
+ return new Promise((resolve) => setTimeout(resolve, ms));
183
+ }
184
+
185
+ function requestJson(options, payload) {
186
+ return new Promise((resolve, reject) => {
187
+ const body = payload ? JSON.stringify(payload) : '';
188
+ const request = http.request({
189
+ ...options,
190
+ headers: {
191
+ 'content-type': 'application/json',
192
+ 'content-length': Buffer.byteLength(body),
193
+ ...(options.headers || {})
194
+ }
195
+ }, (response) => {
196
+ let data = '';
197
+ response.setEncoding('utf8');
198
+ response.on('data', (chunk) => {
199
+ data += chunk;
200
+ });
201
+ response.on('end', () => {
202
+ let parsed = null;
203
+ if (data) {
204
+ try {
205
+ parsed = JSON.parse(data);
206
+ } catch (error) {
207
+ reject(error);
208
+ return;
209
+ }
210
+ }
211
+ resolve({
212
+ statusCode: response.statusCode,
213
+ body: parsed
214
+ });
215
+ });
216
+ });
217
+
218
+ request.on('error', reject);
219
+ if (body) {
220
+ request.write(body);
221
+ }
222
+ request.end();
223
+ });
224
+ }
225
+
226
+ function parseWebDriverUrl(value) {
227
+ const target = new URL(value);
228
+ return {
229
+ hostname: target.hostname,
230
+ port: target.port || (target.protocol === 'https:' ? 443 : 80),
231
+ prefix: target.pathname && target.pathname !== '/' ? target.pathname.replace(/\/$/u, '') : ''
232
+ };
233
+ }
234
+
235
+ function findSafariDriver() {
236
+ const candidates = [
237
+ '/System/Cryptexes/App/usr/bin/safaridriver',
238
+ '/usr/bin/safaridriver'
239
+ ];
240
+ return candidates.find((candidate) => {
241
+ try {
242
+ fs.accessSync(candidate);
243
+ return true;
244
+ } catch (_) {
245
+ return false;
246
+ }
247
+ }) || null;
248
+ }
249
+
250
+ function findExecutableOnPath(name) {
251
+ const pathEntries = String(process.env.PATH || '').split(path.delimiter).filter(Boolean);
252
+ for (const pathEntry of pathEntries) {
253
+ const candidate = path.join(pathEntry, name);
254
+ try {
255
+ fs.accessSync(candidate, fs.constants.X_OK);
256
+ return candidate;
257
+ } catch (_) {
258
+ // Keep scanning PATH.
259
+ }
260
+ }
261
+ return null;
262
+ }
263
+
264
+ function executableCandidate(value, executableName = 'chromedriver') {
265
+ if (!value) {
266
+ return [];
267
+ }
268
+ return [
269
+ value,
270
+ path.join(value, executableName)
271
+ ];
272
+ }
273
+
274
+ function findChromeDriver(options = {}) {
275
+ if (options.chromeDriverPathOnly === true && options.chromeDriverPath) {
276
+ return executableCandidate(options.chromeDriverPath).find((candidate) => {
277
+ try {
278
+ fs.accessSync(candidate, fs.constants.X_OK);
279
+ return true;
280
+ } catch (_) {
281
+ return false;
282
+ }
283
+ }) || null;
284
+ }
285
+
286
+ const candidates = [
287
+ ...executableCandidate(options.chromeDriverPath),
288
+ ...executableCandidate(process.env.RMT_VNEXT_SOURCE_TO_SEA_CHROMEDRIVER),
289
+ ...executableCandidate(process.env.CHROMEWEBDRIVER),
290
+ '/usr/local/share/chromedriver-linux64/chromedriver',
291
+ '/usr/bin/chromedriver',
292
+ '/snap/bin/chromium.chromedriver',
293
+ findExecutableOnPath('chromedriver')
294
+ ].filter(Boolean);
295
+
296
+ return candidates.find((candidate) => {
297
+ try {
298
+ fs.accessSync(candidate, fs.constants.X_OK);
299
+ return true;
300
+ } catch (_) {
301
+ return false;
302
+ }
303
+ }) || null;
304
+ }
305
+
306
+ function findGeckoDriver(options = {}) {
307
+ const candidates = [
308
+ ...executableCandidate(options.geckoDriverPath, 'geckodriver'),
309
+ ...executableCandidate(process.env.RMT_VNEXT_SOURCE_TO_SEA_GECKODRIVER, 'geckodriver'),
310
+ ...executableCandidate(process.env.GECKODRIVER, 'geckodriver'),
311
+ ...executableCandidate(process.env.FIREFOXWEBDRIVER, 'geckodriver'),
312
+ '/usr/local/bin/geckodriver',
313
+ '/usr/bin/geckodriver',
314
+ '/snap/bin/geckodriver',
315
+ findExecutableOnPath('geckodriver')
316
+ ].filter(Boolean);
317
+
318
+ return candidates.find((candidate) => {
319
+ try {
320
+ fs.accessSync(candidate, fs.constants.X_OK);
321
+ return true;
322
+ } catch (_) {
323
+ return false;
324
+ }
325
+ }) || null;
326
+ }
327
+
328
+ function findEdgeDriver(options = {}) {
329
+ const candidates = [
330
+ ...executableCandidate(options.edgeDriverPath, 'msedgedriver'),
331
+ ...executableCandidate(process.env.RMT_VNEXT_SOURCE_TO_SEA_EDGEDRIVER, 'msedgedriver'),
332
+ ...executableCandidate(process.env.MSEDGEDRIVER, 'msedgedriver'),
333
+ ...executableCandidate(process.env.EDGEWEBDRIVER, 'msedgedriver'),
334
+ '/usr/local/bin/msedgedriver',
335
+ '/usr/bin/msedgedriver',
336
+ findExecutableOnPath('msedgedriver')
337
+ ].filter(Boolean);
338
+
339
+ return candidates.find((candidate) => {
340
+ try {
341
+ fs.accessSync(candidate, fs.constants.X_OK);
342
+ return true;
343
+ } catch (_) {
344
+ return false;
345
+ }
346
+ }) || null;
347
+ }
348
+
349
+ function findBrowserBinary(options = {}, envNames = [], executableNames = []) {
350
+ const candidates = [
351
+ options.browserBinary,
352
+ ...envNames.map((name) => process.env[name]),
353
+ ...executableNames.map((name) => findExecutableOnPath(name))
354
+ ].filter(Boolean);
355
+ return candidates.find((candidate) => {
356
+ try {
357
+ fs.accessSync(candidate, fs.constants.X_OK);
358
+ return true;
359
+ } catch (_) {
360
+ return false;
361
+ }
362
+ }) || null;
363
+ }
364
+
365
+ function normalizeBrowserDriver(value) {
366
+ const driver = String(value || '').trim().toLowerCase();
367
+ if (driver === 'chrome' || driver === 'chromium') return 'chromedriver';
368
+ if (driver === 'safaridriver') return 'safari';
369
+ if (driver === 'gecko' || driver === 'geckodriver') return 'firefox';
370
+ if (driver === 'edge' || driver === 'msedge') return 'msedgedriver';
371
+ return driver;
372
+ }
373
+
374
+ function browserNameForDriver(driver, options = {}) {
375
+ if (options.browserName) return options.browserName;
376
+ if (driver === 'firefox') return 'firefox';
377
+ if (driver === 'safari') return 'safari';
378
+ if (driver === 'msedgedriver') return 'MicrosoftEdge';
379
+ if (driver === 'chromedriver') return process.env.RMT_VNEXT_SOURCE_TO_SEA_BROWSER_NAME || 'chrome';
380
+ return process.env.RMT_VNEXT_SOURCE_TO_SEA_BROWSER_NAME || 'chrome';
381
+ }
382
+
383
+ function supportedBrowserDriver(value) {
384
+ return RMT_VNEXT_SOURCE_TO_SEA_SUPPORTED_BROWSER_DRIVERS.includes(String(value || '').trim().toLowerCase())
385
+ || Boolean(normalizeBrowserDriver(value) && ['webdriver', 'chromedriver', 'firefox', 'safari', 'msedgedriver'].includes(normalizeBrowserDriver(value)));
386
+ }
387
+
388
+ function detectAvailableBrowserDriver(options = {}) {
389
+ if (options.webDriverUrl || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_URL) return 'webdriver';
390
+ if (findGeckoDriver(options)) return 'firefox';
391
+ if (findChromeDriver(options)) return 'chromedriver';
392
+ if (findEdgeDriver(options)) return 'msedgedriver';
393
+ if (findSafariDriver()) return 'safari';
394
+ return '';
395
+ }
396
+
397
+ async function waitForWebDriver(webDriver, timeoutMs = 5000) {
398
+ const started = Date.now();
399
+ while (Date.now() - started < timeoutMs) {
400
+ try {
401
+ const response = await requestJson({
402
+ hostname: webDriver.hostname,
403
+ port: webDriver.port,
404
+ path: `${webDriver.prefix}/status`,
405
+ method: 'GET'
406
+ });
407
+ if (response.statusCode >= 200 && response.statusCode < 500) {
408
+ return true;
409
+ }
410
+ } catch (_) {
411
+ await wait(150);
412
+ }
413
+ }
414
+ return false;
415
+ }
416
+
417
+ function childProcessHasExited(childProcess) {
418
+ return !childProcess || childProcess.exitCode !== null || childProcess.signalCode !== null;
419
+ }
420
+
421
+ function detachChildProcess(childProcess) {
422
+ if (!childProcess) return;
423
+ if (childProcess.stdout && typeof childProcess.stdout.destroy === 'function') childProcess.stdout.destroy();
424
+ if (childProcess.stderr && typeof childProcess.stderr.destroy === 'function') childProcess.stderr.destroy();
425
+ if (typeof childProcess.unref === 'function') childProcess.unref();
426
+ }
427
+
428
+ function waitForChildProcessExit(childProcess, timeoutMs = 3000) {
429
+ if (childProcessHasExited(childProcess)) {
430
+ return Promise.resolve(true);
431
+ }
432
+
433
+ return new Promise((resolve) => {
434
+ let settled = false;
435
+ const cleanup = () => {
436
+ childProcess.off('exit', onExit);
437
+ childProcess.off('close', onExit);
438
+ clearTimeout(timer);
439
+ };
440
+ const onExit = () => {
441
+ if (settled) {
442
+ return;
443
+ }
444
+ settled = true;
445
+ cleanup();
446
+ resolve(true);
447
+ };
448
+ const timer = setTimeout(() => {
449
+ if (settled) {
450
+ return;
451
+ }
452
+ settled = true;
453
+ cleanup();
454
+ resolve(childProcessHasExited(childProcess));
455
+ }, timeoutMs);
456
+
457
+ childProcess.once('exit', onExit);
458
+ childProcess.once('close', onExit);
459
+ });
460
+ }
461
+
462
+ function errorMessage(error) {
463
+ return error && error.message ? error.message : String(error);
464
+ }
465
+
466
+ function signalSnapGeckoDriver(childProcess, signal = 'TERM') {
467
+ const pid = Number(childProcess && childProcess.pid);
468
+ if (!Number.isFinite(pid) || pid <= 0 || !findExecutableOnPath('snap')) {
469
+ return false;
470
+ }
471
+ const result = spawnSync('snap', ['run', '--shell', 'firefox.geckodriver', '-c', `kill -${signal} ${pid}`], {
472
+ stdio: 'ignore'
473
+ });
474
+ return result.status === 0;
475
+ }
476
+
477
+ async function shutdownSpawnedWebDriver(childProcess, webDriver, options = {}) {
478
+ if (!childProcess) {
479
+ return {
480
+ ok: true,
481
+ method: 'none'
482
+ };
483
+ }
484
+
485
+ const timeoutMs = Number(options.shutdownTimeoutMs || 3000);
486
+ const errors = [];
487
+
488
+ if (childProcessHasExited(childProcess)) {
489
+ return {
490
+ ok: true,
491
+ method: 'already-exited'
492
+ };
493
+ }
494
+
495
+ if (options.driver === 'chromedriver') {
496
+ try {
497
+ const response = await requestJson({
498
+ hostname: webDriver.hostname,
499
+ port: webDriver.port,
500
+ path: `${webDriver.prefix}/shutdown`,
501
+ method: 'GET'
502
+ });
503
+ if (response.statusCode >= 200 && response.statusCode < 500) {
504
+ const exited = await waitForChildProcessExit(childProcess, timeoutMs);
505
+ if (exited) {
506
+ return {
507
+ ok: true,
508
+ method: 'webdriver-shutdown'
509
+ };
510
+ }
511
+ errors.push(`webdriver shutdown did not exit within ${timeoutMs}ms`);
512
+ } else {
513
+ errors.push(`webdriver shutdown returned ${response.statusCode}`);
514
+ }
515
+ } catch (error) {
516
+ errors.push(`webdriver shutdown failed: ${errorMessage(error)}`);
517
+ }
518
+ }
519
+
520
+ if (childProcessHasExited(childProcess)) {
521
+ return {
522
+ ok: true,
523
+ method: 'already-exited',
524
+ warnings: errors
525
+ };
526
+ }
527
+
528
+ try {
529
+ const signaled = childProcess.kill();
530
+ if (!signaled) {
531
+ errors.push('process signal was not accepted');
532
+ }
533
+ } catch (error) {
534
+ errors.push(`process signal failed: ${errorMessage(error)}`);
535
+ }
536
+
537
+ if (await waitForChildProcessExit(childProcess, timeoutMs)) {
538
+ return {
539
+ ok: true,
540
+ method: 'process-signal',
541
+ warnings: errors
542
+ };
543
+ }
544
+
545
+ if (options.driver === 'firefox' && String(options.driverPath || '').includes('/snap/')) {
546
+ const snapSignaled = signalSnapGeckoDriver(childProcess, 'TERM');
547
+ if (!snapSignaled) {
548
+ errors.push('snap geckodriver signal was not accepted');
549
+ }
550
+ if (await waitForChildProcessExit(childProcess, timeoutMs)) {
551
+ return {
552
+ ok: true,
553
+ method: 'snap-shell-signal',
554
+ warnings: errors
555
+ };
556
+ }
557
+ }
558
+
559
+ detachChildProcess(childProcess);
560
+
561
+ return {
562
+ ok: false,
563
+ method: 'process-signal',
564
+ reason: `WebDriver process cleanup failed${errors.length ? `: ${errors.join('; ')}` : ''}`
565
+ };
566
+ }
567
+
568
+ function createDefaultWebDriverCapabilities(options = {}) {
569
+ const browserName = browserNameForDriver(options.driver || 'webdriver', options);
570
+ const capabilities = {
571
+ browserName
572
+ };
573
+ if (browserName === 'chrome' || browserName === 'chromium') {
574
+ capabilities['goog:chromeOptions'] = {
575
+ args: [
576
+ '--headless=new',
577
+ '--disable-gpu',
578
+ '--no-sandbox',
579
+ '--window-size=1280,720'
580
+ ]
581
+ };
582
+ } else if (browserName === 'firefox') {
583
+ const firefoxBinary = findBrowserBinary(options, [
584
+ 'RMT_VNEXT_SOURCE_TO_SEA_FIREFOX_BINARY',
585
+ 'FIREFOX_BIN'
586
+ ]);
587
+ capabilities['moz:firefoxOptions'] = {
588
+ args: ['-headless']
589
+ };
590
+ if (firefoxBinary) {
591
+ capabilities['moz:firefoxOptions'].binary = firefoxBinary;
592
+ }
593
+ } else if (browserName === 'MicrosoftEdge' || browserName === 'edge' || browserName === 'msedge') {
594
+ capabilities.browserName = 'MicrosoftEdge';
595
+ capabilities['ms:edgeOptions'] = {
596
+ args: [
597
+ '--headless=new',
598
+ '--disable-gpu',
599
+ '--no-sandbox',
600
+ '--window-size=1280,720'
601
+ ]
602
+ };
603
+ }
604
+ return {
605
+ capabilities: {
606
+ alwaysMatch: capabilities
607
+ }
608
+ };
609
+ }
610
+
611
+ function createBrowserExecutionUrl(options = {}) {
612
+ if (options.browserUrl) {
613
+ return options.browserUrl;
614
+ }
615
+ const rootDir = options.rootDir || process.cwd();
616
+ const fixturePath = options.browserFixturePath || RMT_VNEXT_SOURCE_TO_SEA_BROWSER_FIXTURE_PATH;
617
+ return pathToFileURL(path.resolve(rootDir, fixturePath)).href;
618
+ }
619
+
620
+ async function executeWebDriverResult(webDriver, sessionId, resultKey, timeoutMs = 5000) {
621
+ const started = Date.now();
622
+ while (Date.now() - started < timeoutMs) {
623
+ const response = await requestJson({
624
+ hostname: webDriver.hostname,
625
+ port: webDriver.port,
626
+ path: `${webDriver.prefix}/session/${sessionId}/execute/sync`,
627
+ method: 'POST'
628
+ }, {
629
+ script: `return window[${JSON.stringify(resultKey)}] || null;`,
630
+ args: []
631
+ });
632
+ const value = response.body && response.body.value;
633
+ if (value && value.status && value.status !== 'pending') {
634
+ return value;
635
+ }
636
+ await wait(100);
637
+ }
638
+ throw new Error(`browser fixture did not publish ${resultKey}`);
639
+ }
640
+
641
+ async function runWebDriverBrowserProbe(options = {}) {
642
+ const driver = normalizeBrowserDriver(options.driver || 'webdriver');
643
+ let webDriverUrl = options.webDriverUrl || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_URL || '';
644
+ let spawnedDriver = null;
645
+ let spawnedDriverPath = '';
646
+ const timeoutMs = Number(options.timeoutMs || (driver === 'firefox' ? 15000 : 5000));
647
+
648
+ if (driver === 'chromedriver' && !webDriverUrl) {
649
+ const driverPath = findChromeDriver(options);
650
+ if (!driverPath) {
651
+ throw new Error('chromedriver was not found');
652
+ }
653
+ const driverPort = Number(options.webDriverPort || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_PORT || RMT_VNEXT_SOURCE_TO_SEA_CI_WEBDRIVER_PORT);
654
+ spawnedDriver = spawn(driverPath, [`--port=${driverPort}`], {
655
+ stdio: ['ignore', 'pipe', 'pipe']
656
+ });
657
+ spawnedDriverPath = driverPath;
658
+ webDriverUrl = `http://127.0.0.1:${driverPort}`;
659
+ }
660
+
661
+ if (driver === 'firefox' && !webDriverUrl) {
662
+ const driverPath = findGeckoDriver(options);
663
+ if (!driverPath) {
664
+ throw new Error('geckodriver was not found');
665
+ }
666
+ const driverPort = Number(options.webDriverPort || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_PORT || 4444);
667
+ spawnedDriver = spawn(driverPath, ['--port', String(driverPort)], {
668
+ stdio: ['ignore', 'pipe', 'pipe']
669
+ });
670
+ spawnedDriverPath = driverPath;
671
+ webDriverUrl = `http://127.0.0.1:${driverPort}`;
672
+ }
673
+
674
+ if (driver === 'safari' && !webDriverUrl) {
675
+ const driverPath = findSafariDriver();
676
+ if (!driverPath) {
677
+ throw new Error('safaridriver was not found');
678
+ }
679
+ const driverPort = Number(options.webDriverPort || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_PORT || 57932);
680
+ spawnedDriver = spawn(driverPath, ['-p', String(driverPort)], {
681
+ stdio: ['ignore', 'pipe', 'pipe']
682
+ });
683
+ spawnedDriverPath = driverPath;
684
+ webDriverUrl = `http://127.0.0.1:${driverPort}`;
685
+ }
686
+
687
+ if (driver === 'msedgedriver' && !webDriverUrl) {
688
+ const driverPath = findEdgeDriver(options);
689
+ if (!driverPath) {
690
+ throw new Error('msedgedriver was not found');
691
+ }
692
+ const driverPort = Number(options.webDriverPort || process.env.RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_PORT || 9516);
693
+ spawnedDriver = spawn(driverPath, [`--port=${driverPort}`], {
694
+ stdio: ['ignore', 'pipe', 'pipe']
695
+ });
696
+ spawnedDriverPath = driverPath;
697
+ webDriverUrl = `http://127.0.0.1:${driverPort}`;
698
+ }
699
+
700
+ if (!webDriverUrl) {
701
+ throw new Error('RMT_VNEXT_SOURCE_TO_SEA_WEBDRIVER_URL is required for webdriver mode');
702
+ }
703
+
704
+ const webDriver = parseWebDriverUrl(webDriverUrl);
705
+ let sessionId = null;
706
+
707
+ try {
708
+ const ready = await waitForWebDriver(webDriver, timeoutMs);
709
+ if (!ready) {
710
+ throw new Error(`WebDriver endpoint did not become ready at ${webDriverUrl}`);
711
+ }
712
+
713
+ const session = await requestJson({
714
+ hostname: webDriver.hostname,
715
+ port: webDriver.port,
716
+ path: `${webDriver.prefix}/session`,
717
+ method: 'POST'
718
+ }, createDefaultWebDriverCapabilities({ ...options, driver, browserName: browserNameForDriver(driver, options) }));
719
+ const sessionValue = session.body && session.body.value;
720
+ sessionId = sessionValue && (sessionValue.sessionId || sessionValue.id);
721
+ if (!sessionId) {
722
+ throw new Error(`WebDriver did not create a session: ${JSON.stringify(session.body || null)}`);
723
+ }
724
+
725
+ await requestJson({
726
+ hostname: webDriver.hostname,
727
+ port: webDriver.port,
728
+ path: `${webDriver.prefix}/session/${sessionId}/url`,
729
+ method: 'POST'
730
+ }, {
731
+ url: createBrowserExecutionUrl(options)
732
+ });
733
+
734
+ return await executeWebDriverResult(webDriver, sessionId, options.resultKey || RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY, timeoutMs);
735
+ } finally {
736
+ if (sessionId) {
737
+ await requestJson({
738
+ hostname: webDriver.hostname,
739
+ port: webDriver.port,
740
+ path: `${webDriver.prefix}/session/${sessionId}`,
741
+ method: 'DELETE'
742
+ }).catch(() => {});
743
+ }
744
+ if (spawnedDriver) {
745
+ const cleanup = await shutdownSpawnedWebDriver(spawnedDriver, webDriver, { driver, driverPath: spawnedDriverPath });
746
+ if (!cleanup.ok) {
747
+ throw new Error(cleanup.reason || 'WebDriver process cleanup failed');
748
+ }
749
+ }
750
+ }
751
+ }
752
+
753
+ function stripKernelLaneRef(value, fallback = 'visible') {
754
+ if (typeof value !== 'string' || value.length === 0) {
755
+ return fallback;
756
+ }
757
+ const segments = value.split('/');
758
+ const candidate = segments[segments.length - 1] || value;
759
+ return candidate.startsWith('lane:') ? fallback : candidate;
760
+ }
761
+
762
+ function lifecycleOpToFabricKind(op) {
763
+ switch (op) {
764
+ case 'mount':
765
+ return 'component.mount';
766
+ case 'destroy':
767
+ case 'disconnect':
768
+ return 'component.disconnect';
769
+ case 'render':
770
+ return 'component.render';
771
+ case 'hydrate':
772
+ default:
773
+ return 'component.hydrate';
774
+ }
775
+ }
776
+
777
+ function browserIncludesAttribute(html, attribute, value) {
778
+ if (typeof html !== 'string' || typeof attribute !== 'string' || typeof value !== 'string') {
779
+ return false;
780
+ }
781
+ return html.includes(`${attribute}="${value}"`);
782
+ }
783
+
784
+ function safeFiberSegment(value) {
785
+ return String(value || 'rmt-vnext').replace(/[^a-zA-Z0-9._:-]/g, '-');
786
+ }
787
+
788
+ function runFabricBridgeFiber(fabric, fiberInput = {}) {
789
+ const mapping = resolveRmtScheduleForFiber({
790
+ kind: fiberInput.kind,
791
+ lane: fiberInput.lane,
792
+ scope: fiberInput.scope,
793
+ componentRef: fiberInput.componentRef,
794
+ routeRef: fiberInput.routeRef
795
+ });
796
+ fabric.runFiber({
797
+ id: fiberInput.id,
798
+ kind: fiberInput.kind,
799
+ lane: mapping.fabricLane,
800
+ phase: fiberInput.phase,
801
+ source: fiberInput.source || 'rmt-vnext',
802
+ scope: fiberInput.scope,
803
+ componentRef: fiberInput.componentRef,
804
+ routeRef: fiberInput.routeRef,
805
+ correlationId: fiberInput.correlationId,
806
+ scheduleRef: mapping.scheduleRef,
807
+ endpointNameHint: mapping.endpointName,
808
+ metadata: fiberInput.metadata
809
+ }, () => ({ ok: true, lane: mapping.fabricLane, scheduleRef: mapping.scheduleRef }));
810
+
811
+ return {
812
+ requestedLane: fiberInput.lane,
813
+ kind: fiberInput.kind,
814
+ phase: fiberInput.phase,
815
+ id: fiberInput.id,
816
+ mapping
817
+ };
818
+ }
819
+
820
+ function createFabricBridgeLaneMatrix(fabric, context = {}) {
821
+ const primitiveSegment = safeFiberSegment(context.primitiveId);
822
+ return RMT_VNEXT_FABRIC_BRIDGE_LANE_MATRIX.map((entry, index) => runFabricBridgeFiber(fabric, {
823
+ id: `fiber:${primitiveSegment}/matrix/${entry.lane}/${index}`,
824
+ kind: entry.kind,
825
+ lane: entry.lane,
826
+ phase: entry.phase,
827
+ source: 'rmt-vnext-lane-matrix',
828
+ scope: context.primitiveId || entry.kind,
829
+ componentRef: context.componentRef,
830
+ routeRef: entry.routeRef,
831
+ correlationId: `${context.primitiveId || 'rmt-vnext'}:${entry.lane}`,
832
+ metadata: {
833
+ ...context.metadata,
834
+ matrixLane: entry.lane,
835
+ matrixKind: entry.kind,
836
+ matrixWorkpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE
837
+ }
838
+ }));
839
+ }
840
+
841
+ function createHostAdapterTelemetryInput(input = {}) {
842
+ const probeTelemetry = input.browserProbe && input.browserProbe.hostAdapterTelemetry;
843
+ const telemetry = probeTelemetry && typeof probeTelemetry === 'object' ? probeTelemetry : {};
844
+ const mapping = input.mapping || {};
845
+ const metadata = input.metadata || {};
846
+ return {
847
+ schema: RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA,
848
+ source: 'xtend.component-adapter',
849
+ operation: 'hydrate',
850
+ phase: 'hydrate',
851
+ status: 'ok',
852
+ adapterId: 'xtend.component',
853
+ componentId: input.primitiveId || metadata.primitiveId,
854
+ rmtComponentId: input.primitiveId || metadata.primitiveId,
855
+ tag: input.componentRef || metadata.componentRef,
856
+ scheduleRef: mapping.scheduleRef,
857
+ fabricLane: mapping.fabricLane,
858
+ rmtLane: mapping.rmtLane,
859
+ fiberKind: input.fabricKind || 'component.hydrate',
860
+ endpointNameHint: mapping.endpointName,
861
+ correlationId: input.primitiveId || metadata.primitiveId,
862
+ metadata: {
863
+ workpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE,
864
+ primitiveId: input.primitiveId || metadata.primitiveId,
865
+ kernelScheduleRef: metadata.kernelScheduleRef,
866
+ kernelFiberRef: metadata.kernelFiberRef,
867
+ sourcePointer: metadata.sourcePointer,
868
+ hostAdapterEvidence: true
869
+ },
870
+ ...telemetry,
871
+ metadata: {
872
+ workpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE,
873
+ primitiveId: input.primitiveId || metadata.primitiveId,
874
+ kernelScheduleRef: metadata.kernelScheduleRef,
875
+ kernelFiberRef: metadata.kernelFiberRef,
876
+ sourcePointer: metadata.sourcePointer,
877
+ hostAdapterEvidence: true,
878
+ ...(telemetry.metadata && typeof telemetry.metadata === 'object' ? telemetry.metadata : {})
879
+ }
880
+ };
881
+ }
882
+
883
+ function normalizeScenarioConfig(browserProbe) {
884
+ const probeConfig = browserProbe && browserProbe.routeComponentFibers && typeof browserProbe.routeComponentFibers === 'object'
885
+ ? browserProbe.routeComponentFibers
886
+ : {};
887
+ const componentConfig = probeConfig.component && typeof probeConfig.component === 'object' ? probeConfig.component : {};
888
+ const routeConfig = probeConfig.route && typeof probeConfig.route === 'object' ? probeConfig.route : {};
889
+ return {
890
+ component: {
891
+ ...RMT_VNEXT_ROUTE_COMPONENT_FIBER_SCENARIOS.component,
892
+ ...componentConfig
893
+ },
894
+ route: {
895
+ ...RMT_VNEXT_ROUTE_COMPONENT_FIBER_SCENARIOS.route,
896
+ ...routeConfig
897
+ }
898
+ };
899
+ }
900
+
901
+ function createRouteAndComponentFiberRecords(fabric, context = {}) {
902
+ const scenario = normalizeScenarioConfig(context.browserProbe);
903
+ const metadata = {
904
+ ...context.metadata,
905
+ routeComponentEvidence: true,
906
+ workpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE
907
+ };
908
+ const componentRef = scenario.component.componentRef || context.componentRef || 'x-status';
909
+ const routeRef = scenario.route.routeRef || scenario.component.routeRef || '/rmt-vnext-source-to-sea';
910
+ const componentFibers = fabric.createComponentFiberInstrumentation(componentRef, {
911
+ scope: `${context.primitiveId || componentRef}.component`,
912
+ routeRef,
913
+ adapterRef: 'xtend.component',
914
+ hostRef: 'rmt-vnext-source-to-sea',
915
+ correlationId: `${context.primitiveId || componentRef}:component`
916
+ });
917
+ const routeFibers = fabric.createRouteFiberInstrumentation(scenario.route.routerRef || 'xtend.xrouter', {
918
+ scope: `${context.primitiveId || routeRef}.route`,
919
+ adapterRef: 'xtendrmt.xrouter',
920
+ hostRef: 'rmt-vnext-source-to-sea',
921
+ correlationId: `${context.primitiveId || routeRef}:route`
922
+ });
923
+
924
+ componentFibers.mount((fiber) => ({ mounted: true, fiberId: fiber.id }), {
925
+ routeRef,
926
+ scheduleRef: scenario.component.mountScheduleRef,
927
+ endpointNameHint: 'xtendrmt.component.mount',
928
+ metadata
929
+ });
930
+ componentFibers.hydrate((fiber) => ({ hydrated: true, fiberId: fiber.id }), {
931
+ routeRef,
932
+ scheduleRef: scenario.component.hydrateScheduleRef,
933
+ endpointNameHint: 'xtendrmt.component.hydrate',
934
+ metadata
935
+ });
936
+ routeFibers.navigate((fiber) => ({ navigated: true, fiberId: fiber.id, to: scenario.route.routeRef }), {
937
+ from: '/',
938
+ to: routeRef,
939
+ routeId: scenario.route.routeId || routeRef,
940
+ routeRef,
941
+ scheduleRef: scenario.route.navigateScheduleRef,
942
+ endpointNameHint: 'xtendrmt.ui.user-blocking',
943
+ metadata
944
+ });
945
+ routeFibers.render((fiber) => ({ rendered: true, fiberId: fiber.id, routeRef }), {
946
+ routeRef,
947
+ componentRef,
948
+ scheduleRef: scenario.route.renderScheduleRef,
949
+ endpointNameHint: 'xtendrmt.route.render',
950
+ metadata
951
+ });
952
+
953
+ return {
954
+ schema: RMT_VNEXT_ROUTE_COMPONENT_FIBER_EVIDENCE_SCHEMA,
955
+ componentScenario: scenario.component,
956
+ routeScenario: scenario.route,
957
+ expected: {
958
+ component: [
959
+ { kind: 'component.mount', phase: 'mount', scheduleRef: scenario.component.mountScheduleRef, source: 'component' },
960
+ { kind: 'component.hydrate', phase: 'hydrate', scheduleRef: scenario.component.hydrateScheduleRef, source: 'component' }
961
+ ],
962
+ route: [
963
+ { kind: 'route.navigate', phase: 'navigate', scheduleRef: scenario.route.navigateScheduleRef, source: 'router' },
964
+ { kind: 'route.render', phase: 'render', scheduleRef: scenario.route.renderScheduleRef, source: 'router' }
965
+ ]
966
+ }
967
+ };
968
+ }
969
+
970
+ function summarizeExpectedFiber(fibers, expected, telemetrySnapshot) {
971
+ const fiber = fibers.find((record) => record.kind === expected.kind
972
+ && record.phase === expected.phase
973
+ && record.scheduleRef === expected.scheduleRef
974
+ && (!expected.source || record.source === expected.source)) || null;
975
+ const laneTelemetry = fiber && telemetrySnapshot && telemetrySnapshot.lanes
976
+ ? telemetrySnapshot.lanes[fiber.lane]
977
+ : null;
978
+ return {
979
+ ok: Boolean(fiber && fiber.schema === FABRIC_CONTRACTS.fiber && fiber.status === 'completed' && laneTelemetry && laneTelemetry.scheduleRefs.includes(expected.scheduleRef)),
980
+ kind: expected.kind,
981
+ phase: expected.phase,
982
+ expectedScheduleRef: expected.scheduleRef,
983
+ expectedSource: expected.source || null,
984
+ fiber: fiber ? {
985
+ schema: fiber.schema,
986
+ id: fiber.id,
987
+ kind: fiber.kind,
988
+ phase: fiber.phase,
989
+ source: fiber.source,
990
+ lane: fiber.lane,
991
+ status: fiber.status,
992
+ scheduleRef: fiber.scheduleRef,
993
+ endpointNameHint: fiber.endpointNameHint,
994
+ componentRef: fiber.componentRef,
995
+ routeRef: fiber.routeRef,
996
+ correlationId: fiber.correlationId
997
+ } : null,
998
+ telemetry: laneTelemetry ? {
999
+ lane: laneTelemetry.lane,
1000
+ fiberCount: laneTelemetry.fiberCount,
1001
+ scheduleRefs: laneTelemetry.scheduleRefs
1002
+ } : null
1003
+ };
1004
+ }
1005
+
1006
+ function summarizeRouteAndComponentFibers(plan, fibers, telemetrySnapshot) {
1007
+ const component = plan.expected.component.map((expected) => summarizeExpectedFiber(fibers, expected, telemetrySnapshot));
1008
+ const route = plan.expected.route.map((expected) => summarizeExpectedFiber(fibers, expected, telemetrySnapshot));
1009
+ return {
1010
+ schema: plan.schema,
1011
+ ok: component.every((entry) => entry.ok) && route.every((entry) => entry.ok),
1012
+ componentScenario: plan.componentScenario,
1013
+ routeScenario: plan.routeScenario,
1014
+ component,
1015
+ route,
1016
+ counts: {
1017
+ component: component.filter((entry) => entry.ok).length,
1018
+ route: route.filter((entry) => entry.ok).length,
1019
+ total: component.concat(route).filter((entry) => entry.ok).length
1020
+ }
1021
+ };
1022
+ }
1023
+
1024
+ function createRmtVNextFabricBridgeEvidence(input = {}) {
1025
+ const schedule = input.schedule || null;
1026
+ const kernelFiber = input.fiber || null;
1027
+ const lifecycleRecord = input.lifecycleRecord || null;
1028
+ const sourceMapEntry = input.sourceMapEntry || null;
1029
+ const browserFixtureText = typeof input.browserFixtureText === 'string' ? input.browserFixtureText : '';
1030
+ const browserProbe = input.browserProbe || parseJsonScript(browserFixtureText, 'rmt-source-to-sea-probe') || null;
1031
+ const primitiveId = input.primitiveId || null;
1032
+ const componentRef = input.componentRef || null;
1033
+ const lane = (schedule && schedule.lane) || stripKernelLaneRef(kernelFiber && kernelFiber.lane);
1034
+ const fabricKind = lifecycleOpToFabricKind((kernelFiber && kernelFiber.op) || (lifecycleRecord && lifecycleRecord.op));
1035
+ const mapping = resolveRmtScheduleForFiber({
1036
+ kind: fabricKind,
1037
+ lane,
1038
+ scope: primitiveId,
1039
+ componentRef
1040
+ });
1041
+ const fabric = createXtendFabric({
1042
+ idPrefix: 'rmt.vnext.source-to-sea.fabric',
1043
+ now: createIncrementingClock(),
1044
+ markPerformance: false
1045
+ });
1046
+ const metadata = {
1047
+ workpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE,
1048
+ primitiveId,
1049
+ componentRef,
1050
+ sourcePointer: sourceMapEntry && sourceMapEntry.corePointer,
1051
+ astPointer: sourceMapEntry && sourceMapEntry.astPointer,
1052
+ kernelScheduleRef: schedule && schedule.id,
1053
+ kernelFiberRef: kernelFiber && kernelFiber.id,
1054
+ kernelLifecycleRecordRef: lifecycleRecord && lifecycleRecord.id
1055
+ };
1056
+
1057
+ let primaryRecord = null;
1058
+ if (kernelFiber && kernelFiber.id) {
1059
+ primaryRecord = runFabricBridgeFiber(fabric, {
1060
+ id: kernelFiber.id,
1061
+ kind: fabricKind,
1062
+ lane: mapping.fabricLane,
1063
+ phase: (kernelFiber && kernelFiber.op) || 'hydrate',
1064
+ source: 'rmt-vnext',
1065
+ scope: primitiveId || (schedule && schedule.id) || fabricKind,
1066
+ componentRef,
1067
+ correlationId: primitiveId || (kernelFiber && kernelFiber.id),
1068
+ scheduleRef: mapping.scheduleRef,
1069
+ endpointNameHint: mapping.endpointName,
1070
+ metadata
1071
+ });
1072
+ }
1073
+ const laneMatrixRecords = createFabricBridgeLaneMatrix(fabric, {
1074
+ primitiveId,
1075
+ componentRef,
1076
+ metadata
1077
+ });
1078
+ const hostAdapterTelemetry = fabric.recordComponentTelemetry(createHostAdapterTelemetryInput({
1079
+ primitiveId,
1080
+ componentRef,
1081
+ fabricKind,
1082
+ mapping,
1083
+ metadata,
1084
+ browserProbe
1085
+ }));
1086
+ const routeComponentPlan = createRouteAndComponentFiberRecords(fabric, {
1087
+ primitiveId,
1088
+ componentRef,
1089
+ metadata,
1090
+ browserProbe
1091
+ });
1092
+
1093
+ const fabricFibers = fabric.getFibers();
1094
+ const completedFiber = fabricFibers.find((record) => record.id === (kernelFiber && kernelFiber.id)) || fabricFibers[0] || null;
1095
+ const telemetrySnapshot = fabric.createTelemetrySnapshot({
1096
+ id: 'telemetry:rmt-vnext-source-to-sea',
1097
+ source: 'rmt-vnext-source-to-sea',
1098
+ correlationId: primitiveId,
1099
+ metadata
1100
+ });
1101
+ const laneTelemetry = completedFiber && telemetrySnapshot.lanes
1102
+ ? telemetrySnapshot.lanes[completedFiber.lane]
1103
+ : null;
1104
+ const laneMatrix = laneMatrixRecords.map((record) => {
1105
+ const matrixFiber = fabricFibers.find((fiberRecord) => fiberRecord.id === record.id) || null;
1106
+ const matrixLaneTelemetry = matrixFiber && telemetrySnapshot.lanes
1107
+ ? telemetrySnapshot.lanes[matrixFiber.lane]
1108
+ : null;
1109
+ const ok = Boolean(
1110
+ record.mapping.ok === true
1111
+ && matrixFiber
1112
+ && matrixFiber.status === 'completed'
1113
+ && matrixFiber.schema === FABRIC_CONTRACTS.fiber
1114
+ && matrixLaneTelemetry
1115
+ && matrixLaneTelemetry.scheduleRefs.includes(record.mapping.scheduleRef)
1116
+ );
1117
+ return {
1118
+ ok,
1119
+ lane: record.requestedLane,
1120
+ kind: record.kind,
1121
+ phase: record.phase,
1122
+ fiber: matrixFiber ? {
1123
+ id: matrixFiber.id,
1124
+ schema: matrixFiber.schema,
1125
+ status: matrixFiber.status,
1126
+ lane: matrixFiber.lane,
1127
+ scheduleRef: matrixFiber.scheduleRef,
1128
+ endpointNameHint: matrixFiber.endpointNameHint,
1129
+ source: matrixFiber.source
1130
+ } : null,
1131
+ mapping: {
1132
+ schema: record.mapping.schema,
1133
+ source: record.mapping.source,
1134
+ fabricLane: record.mapping.fabricLane,
1135
+ rmtLane: record.mapping.rmtLane,
1136
+ scheduleRef: record.mapping.scheduleRef,
1137
+ endpointName: record.mapping.endpointName
1138
+ },
1139
+ telemetry: matrixLaneTelemetry ? {
1140
+ lane: matrixLaneTelemetry.lane,
1141
+ fiberCount: matrixLaneTelemetry.fiberCount,
1142
+ scheduleRefs: matrixLaneTelemetry.scheduleRefs
1143
+ } : null
1144
+ };
1145
+ });
1146
+ const expectedMatrixLanes = RMT_VNEXT_FABRIC_BRIDGE_LANE_MATRIX.map((entry) => entry.lane);
1147
+ const actualMatrixLanes = laneMatrix.map((entry) => entry.lane);
1148
+ const browserExposesLane = Boolean(completedFiber && browserIncludesAttribute(browserFixtureText, 'data-xtend-fabric-lane', completedFiber.lane));
1149
+ const browserExposesFiber = Boolean(completedFiber && browserIncludesAttribute(browserFixtureText, 'data-xtend-fabric-fiber', completedFiber.id));
1150
+ const browserExposesSchedule = Boolean(completedFiber && browserIncludesAttribute(browserFixtureText, 'data-xtend-fabric-schedule', completedFiber.scheduleRef));
1151
+ const browserExposesHostTelemetry = browserIncludesAttribute(browserFixtureText, 'data-xtend-host-adapter-telemetry', RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA)
1152
+ || browserFixtureText.includes(RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA);
1153
+ const componentTelemetrySummary = telemetrySnapshot.componentTelemetry;
1154
+ const componentTelemetryLane = componentTelemetrySummary && componentTelemetrySummary.lanes
1155
+ ? componentTelemetrySummary.lanes[hostAdapterTelemetry.fabricLane]
1156
+ : null;
1157
+ const routeComponentFibers = summarizeRouteAndComponentFibers(routeComponentPlan, fabricFibers, telemetrySnapshot);
1158
+ const checks = [
1159
+ createCheck('fabric bridge mapping resolved', mapping.ok === true && mapping.schema === FABRIC_RMT_CONTRACTS.mapping, mapping.scheduleRef),
1160
+ createCheck('fabric runtime records vNext fiber', Boolean(completedFiber && completedFiber.schema === FABRIC_CONTRACTS.fiber && completedFiber.status === 'completed'), completedFiber && completedFiber.id),
1161
+ createCheck('fabric runtime keeps vNext lane', Boolean(completedFiber && completedFiber.lane === lane), completedFiber && completedFiber.lane),
1162
+ createCheck('fabric telemetry records lane', Boolean(laneTelemetry && laneTelemetry.fiberCount >= 1), laneTelemetry && laneTelemetry.lane),
1163
+ createCheck('fabric telemetry records schedule', Boolean(laneTelemetry && laneTelemetry.scheduleRefs.includes(mapping.scheduleRef)), mapping.scheduleRef),
1164
+ createCheck('fabric bridge lane matrix covers target lanes', expectedMatrixLanes.every((matrixLane) => actualMatrixLanes.includes(matrixLane)), actualMatrixLanes),
1165
+ createCheck('fabric bridge lane matrix passes', laneMatrix.every((entry) => entry.ok), laneMatrix.map((entry) => `${entry.lane}:${entry.mapping.scheduleRef}`)),
1166
+ createCheck('host adapter telemetry recorded', hostAdapterTelemetry.schema === RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA, hostAdapterTelemetry.schema),
1167
+ createCheck('host adapter telemetry matches mapping', hostAdapterTelemetry.scheduleRef === mapping.scheduleRef && hostAdapterTelemetry.fabricLane === mapping.fabricLane, hostAdapterTelemetry.scheduleRef),
1168
+ createCheck('fabric snapshot includes host adapter telemetry', Boolean(componentTelemetrySummary && componentTelemetrySummary.recordCount >= 1), componentTelemetrySummary && componentTelemetrySummary.recordCount),
1169
+ createCheck('host adapter telemetry lane summarizes schedule', Boolean(componentTelemetryLane && componentTelemetryLane.scheduleRefs.includes(mapping.scheduleRef)), mapping.scheduleRef),
1170
+ createCheck('browser exposes host adapter telemetry', browserExposesHostTelemetry, RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA),
1171
+ createCheck('component fiber instrumentation records mount and hydrate', routeComponentFibers.component.every((entry) => entry.ok), routeComponentFibers.component.map((entry) => entry.expectedScheduleRef)),
1172
+ createCheck('route fiber instrumentation records navigate and render', routeComponentFibers.route.every((entry) => entry.ok), routeComponentFibers.route.map((entry) => entry.expectedScheduleRef)),
1173
+ createCheck('browser exposes fabric lane', browserExposesLane, completedFiber && completedFiber.lane),
1174
+ createCheck('browser exposes fabric fiber', browserExposesFiber, completedFiber && completedFiber.id),
1175
+ createCheck('browser exposes fabric schedule', browserExposesSchedule, completedFiber && completedFiber.scheduleRef)
1176
+ ];
1177
+
1178
+ return {
1179
+ schema: RMT_VNEXT_FABRIC_BRIDGE_EVIDENCE_SCHEMA,
1180
+ workpackage: RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE,
1181
+ ok: checks.every((check) => check.ok),
1182
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1183
+ mapping: {
1184
+ schema: mapping.schema,
1185
+ scheduleSchema: mapping.schedule && mapping.schedule.schema,
1186
+ source: mapping.source,
1187
+ fabricLane: mapping.fabricLane,
1188
+ rmtLane: mapping.rmtLane,
1189
+ scheduleRef: mapping.scheduleRef,
1190
+ endpointName: mapping.endpointName,
1191
+ diagnostics: mapping.diagnostics
1192
+ },
1193
+ primary: primaryRecord ? {
1194
+ lane: primaryRecord.requestedLane,
1195
+ kind: primaryRecord.kind,
1196
+ scheduleRef: primaryRecord.mapping.scheduleRef,
1197
+ endpointName: primaryRecord.mapping.endpointName
1198
+ } : null,
1199
+ fiber: completedFiber ? {
1200
+ schema: completedFiber.schema,
1201
+ id: completedFiber.id,
1202
+ kind: completedFiber.kind,
1203
+ phase: completedFiber.phase,
1204
+ source: completedFiber.source,
1205
+ lane: completedFiber.lane,
1206
+ status: completedFiber.status,
1207
+ scheduleRef: completedFiber.scheduleRef,
1208
+ endpointNameHint: completedFiber.endpointNameHint,
1209
+ correlationId: completedFiber.correlationId,
1210
+ metadata: completedFiber.metadata
1211
+ } : null,
1212
+ telemetry: {
1213
+ schema: telemetrySnapshot.schema,
1214
+ id: telemetrySnapshot.id,
1215
+ source: telemetrySnapshot.source,
1216
+ fiberCount: telemetrySnapshot.fiberCount,
1217
+ lane: laneTelemetry ? {
1218
+ lane: laneTelemetry.lane,
1219
+ fiberCount: laneTelemetry.fiberCount,
1220
+ completedCount: laneTelemetry.completedCount,
1221
+ scheduleRefs: laneTelemetry.scheduleRefs
1222
+ } : null,
1223
+ laneMatrix
1224
+ },
1225
+ laneMatrix,
1226
+ routeComponentFibers,
1227
+ hostAdapter: {
1228
+ schema: hostAdapterTelemetry.schema,
1229
+ source: hostAdapterTelemetry.source,
1230
+ operation: hostAdapterTelemetry.operation,
1231
+ phase: hostAdapterTelemetry.phase,
1232
+ status: hostAdapterTelemetry.status,
1233
+ adapterId: hostAdapterTelemetry.adapterId,
1234
+ componentId: hostAdapterTelemetry.componentId,
1235
+ scheduleRef: hostAdapterTelemetry.scheduleRef,
1236
+ fabricLane: hostAdapterTelemetry.fabricLane,
1237
+ rmtLane: hostAdapterTelemetry.rmtLane,
1238
+ fiberKind: hostAdapterTelemetry.fiberKind,
1239
+ endpointNameHint: hostAdapterTelemetry.endpointNameHint,
1240
+ correlationId: hostAdapterTelemetry.correlationId,
1241
+ metadata: hostAdapterTelemetry.metadata,
1242
+ summary: componentTelemetrySummary ? {
1243
+ schema: componentTelemetrySummary.schema,
1244
+ recordCount: componentTelemetrySummary.recordCount,
1245
+ lane: componentTelemetryLane ? {
1246
+ lane: hostAdapterTelemetry.fabricLane,
1247
+ recordCount: componentTelemetryLane.recordCount,
1248
+ scheduleRefs: componentTelemetryLane.scheduleRefs
1249
+ } : null
1250
+ } : null
1251
+ },
1252
+ browser: {
1253
+ laneVisible: browserExposesLane,
1254
+ fiberVisible: browserExposesFiber,
1255
+ scheduleVisible: browserExposesSchedule,
1256
+ hostAdapterTelemetryVisible: browserExposesHostTelemetry
1257
+ },
1258
+ correlation: [
1259
+ { layer: 'source', value: sourceMapEntry && sourceMapEntry.astPointer },
1260
+ { layer: 'kernel.schedule', value: schedule && schedule.id },
1261
+ { layer: 'kernel.fiber', value: kernelFiber && kernelFiber.id },
1262
+ { layer: 'fabric.mapping', value: mapping.scheduleRef },
1263
+ { layer: 'fabric.fiber', value: completedFiber && completedFiber.id },
1264
+ { layer: 'host.adapter', value: hostAdapterTelemetry.id },
1265
+ { layer: 'component.fibers', value: routeComponentFibers.component.map((entry) => entry.fiber && entry.fiber.id).filter(Boolean) },
1266
+ { layer: 'route.fibers', value: routeComponentFibers.route.map((entry) => entry.fiber && entry.fiber.id).filter(Boolean) },
1267
+ { layer: 'fabric.telemetry', value: telemetrySnapshot.id },
1268
+ { layer: 'browser', value: completedFiber && `[data-xtend-fabric-fiber="${completedFiber.id}"]` }
1269
+ ],
1270
+ checks
1271
+ };
1272
+ }
1273
+
1274
+ function createRmtVNextSourceToSeaEvidence(input, options = {}) {
1275
+ const compileResult = compileRmtVNextSource(input, options.compilerOptions || {});
1276
+ const coreDocument = compileResult.coreDocument || null;
1277
+ const appPlatform = coreDocument && coreDocument.appPlatform;
1278
+ const kernelRecords = coreDocument && coreDocument.kernelRecords;
1279
+ const browserFixtureText = typeof options.browserFixtureText === 'string' ? options.browserFixtureText : '';
1280
+ const browserProbe = options.browserProbe || parseJsonScript(browserFixtureText, 'rmt-source-to-sea-probe');
1281
+ const primitiveId = options.primitiveId
1282
+ || (browserProbe && browserProbe.primitiveId)
1283
+ || (toArray(appPlatform && appPlatform.surfaces)[0] && toArray(appPlatform && appPlatform.surfaces)[0].id)
1284
+ || null;
1285
+ const actionId = options.actionId
1286
+ || (browserProbe && browserProbe.expectedAction)
1287
+ || (toArray(appPlatform && appPlatform.actions)[0] && toArray(appPlatform && appPlatform.actions)[0].id)
1288
+ || null;
1289
+ const preferredLane = options.lane || (browserProbe && browserProbe.lane) || 'visible';
1290
+ const { appSurface, coreSurface } = findSurface(coreDocument, primitiveId);
1291
+ const eventRecord = findEvent(coreDocument, coreSurface, actionId);
1292
+ const eventSourceMap = findSourceMapEntry(coreDocument, eventRecord);
1293
+ const surfaceSourceMap = findSourceMapEntry(coreDocument, coreSurface);
1294
+ const sourceMapEntry = eventSourceMap || surfaceSourceMap || null;
1295
+ const schedule = findSchedule(kernelRecords, coreSurface, preferredLane);
1296
+ const fiber = findFiber(kernelRecords, schedule);
1297
+ const uiSelector = options.selector
1298
+ || (browserProbe && browserProbe.selector)
1299
+ || (primitiveId ? `[data-rmt-primitive-id="${primitiveId}"]` : null);
1300
+ const browserExposesPrimitive = Boolean(uiSelector && browserFixtureText.includes(uiSelector.replace(/\\"/g, '"')));
1301
+ const browserExposesResult = Boolean(browserFixtureText.includes(RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY));
1302
+ const browserText = options.expectedText || (browserProbe && browserProbe.expectedText);
1303
+ const expectedBrowserAction = options.expectedAction || (browserProbe && browserProbe.expectedAction);
1304
+ const browserEventObserved = Boolean(expectedBrowserAction === actionId && browserExposesResult);
1305
+ const browserViewportAsserted = Boolean(browserExposesPrimitive && browserFixtureText.includes('getBoundingClientRect'));
1306
+ const kernelLifecycleRecord = toArray(kernelRecords && kernelRecords.lifecycleRecords)
1307
+ .find((record) => fiber && record.id === fiber.operation) || null;
1308
+ const scheduleRef = schedule && schedule.id;
1309
+ const fiberRef = fiber && fiber.id;
1310
+ const fabricBridge = createRmtVNextFabricBridgeEvidence({
1311
+ primitiveId,
1312
+ componentRef: appSurface && appSurface.component,
1313
+ schedule,
1314
+ fiber,
1315
+ lifecycleRecord: kernelLifecycleRecord,
1316
+ sourceMapEntry,
1317
+ browserFixtureText,
1318
+ browserProbe
1319
+ });
1320
+
1321
+ const checks = [
1322
+ createCheck('compiler result ok', compileResult.ok === true, compileResult.status),
1323
+ createCheck('semantic graph ok', Boolean(compileResult.primitiveSemanticGraph && compileResult.primitiveSemanticGraph.ok), compileResult.primitiveSemanticGraph && compileResult.primitiveSemanticGraph.diagnostics),
1324
+ createCheck('app platform artifact emitted', Boolean(appPlatform && appPlatform.schema === RMT_APP_PLATFORM_RECORDS_SCHEMA), appPlatform && appPlatform.schema),
1325
+ createCheck('kernel records emitted', Boolean(kernelRecords && kernelRecords.schema === RMT_KERNEL_RECORDS_SCHEMA), kernelRecords && kernelRecords.schema),
1326
+ createCheck('kernel boundary preserved', Boolean(kernelRecords && kernelRecords.boundary === RMT_KERNEL_BOUNDARY), kernelRecords && kernelRecords.boundary),
1327
+ createCheck('primitive surface lowered', Boolean(appSurface && coreSurface), primitiveId),
1328
+ createCheck('event action lowered', Boolean(eventRecord && eventRecord.action === actionId), eventRecord && eventRecord.action),
1329
+ createCheck('source pointer available', Boolean(sourceMapEntry && sourceMapEntry.corePointer), sourceMapEntry && sourceMapEntry.corePointer),
1330
+ createCheck('kernel schedule available', Boolean(scheduleRef), scheduleRef),
1331
+ createCheck('fabric fiber derivable', Boolean(fiberRef && fiber && fiber.source && fiber.source.kind === 'selector'), fiberRef),
1332
+ createCheck('lifecycle record correlates to fiber', Boolean(kernelLifecycleRecord), fiber && fiber.operation),
1333
+ createCheck('browser fixture declares probe schema', Boolean(browserProbe && browserProbe.schema === RMT_VNEXT_SOURCE_TO_SEA_BROWSER_PROBE_SCHEMA), browserProbe && browserProbe.schema),
1334
+ createCheck('browser fixture exposes primitive marker', browserExposesPrimitive, uiSelector),
1335
+ createCheck('browser fixture asserts viewport', browserViewportAsserted, uiSelector),
1336
+ createCheck('browser fixture observes event', browserEventObserved, actionId),
1337
+ createCheck('fabric bridge evidence passes', fabricBridge.ok === true, fabricBridge.status),
1338
+ createCheck('kernel does not expose host imports', !containsKernelHostImport(kernelRecords), kernelRecords && kernelRecords.boundary)
1339
+ ];
1340
+ const ok = checks.every((check) => check.ok);
1341
+
1342
+ return {
1343
+ schema: RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_SCHEMA,
1344
+ gateSchema: RMT_VNEXT_SOURCE_TO_SEA_SCHEMA,
1345
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1346
+ ok,
1347
+ status: ok ? 'passed' : 'failed',
1348
+ source: input && (input.filePath || input.uri || null),
1349
+ primitiveId,
1350
+ sourcePointer: sourceMapEntry && sourceMapEntry.corePointer,
1351
+ sourceMap: sourceMapEntry ? {
1352
+ id: sourceMapEntry.id,
1353
+ astPointer: sourceMapEntry.astPointer,
1354
+ corePointer: sourceMapEntry.corePointer,
1355
+ range: sourceMapEntry.range
1356
+ } : null,
1357
+ compiler: {
1358
+ ok: compileResult.ok === true,
1359
+ status: compileResult.status,
1360
+ artifactCount: artifactCount(coreDocument),
1361
+ appPlatformSchema: appPlatform && appPlatform.schema,
1362
+ kernelRecordsSchema: kernelRecords && kernelRecords.schema
1363
+ },
1364
+ kernel: {
1365
+ ingested: Boolean(kernelRecords && scheduleRef && kernelLifecycleRecord),
1366
+ scheduleRef,
1367
+ lifecycleRecordRef: kernelLifecycleRecord && kernelLifecycleRecord.id,
1368
+ boundary: kernelRecords && kernelRecords.boundary
1369
+ },
1370
+ fabric: {
1371
+ schema: fabricBridge.schema,
1372
+ workpackage: fabricBridge.workpackage,
1373
+ lane: schedule && schedule.lane,
1374
+ rmtLane: fabricBridge.mapping.rmtLane,
1375
+ fiber: fiberRef,
1376
+ operation: fiber && fiber.operation,
1377
+ sourceKind: fiber && fiber.source && fiber.source.kind,
1378
+ scheduleRef: fabricBridge.mapping.scheduleRef,
1379
+ endpointName: fabricBridge.mapping.endpointName,
1380
+ telemetry: fabricBridge.telemetry,
1381
+ bridge: fabricBridge
1382
+ },
1383
+ ui: {
1384
+ selector: uiSelector,
1385
+ visible: browserViewportAsserted,
1386
+ text: browserText || null,
1387
+ component: appSurface && appSurface.component
1388
+ },
1389
+ browser: {
1390
+ fixture: options.browserFixturePath || null,
1391
+ resultKey: RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY,
1392
+ viewportAsserted: browserViewportAsserted,
1393
+ eventObserved: browserEventObserved,
1394
+ expectedAction: actionId,
1395
+ probeSchema: browserProbe && browserProbe.schema
1396
+ },
1397
+ correlation: [
1398
+ { layer: 'source', value: sourceMapEntry && sourceMapEntry.astPointer },
1399
+ { layer: 'compiler', value: primitiveId },
1400
+ { layer: 'kernel', value: scheduleRef },
1401
+ { layer: 'fabric', value: fiberRef },
1402
+ { layer: 'ui', value: uiSelector },
1403
+ { layer: 'browser', value: RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY }
1404
+ ],
1405
+ diagnostics: compileResult.diagnostics || [],
1406
+ checks
1407
+ };
1408
+ }
1409
+
1410
+ function createBrowserExecutionChecks(result, evidence = {}) {
1411
+ const kernelEvidence = evidence && evidence.kernel || {};
1412
+ const fabricEvidence = evidence && evidence.fabric || {};
1413
+ const expectedAction = evidence && evidence.browser && evidence.browser.expectedAction
1414
+ || 'demo.feedback.save';
1415
+ return [
1416
+ createCheck('browser execution returned result', Boolean(result), result && result.status),
1417
+ createCheck('browser execution status passed', result && result.status === 'passed', result && result.errors),
1418
+ createCheck('browser execution primitive matches evidence', result && result.primitiveId === evidence.primitiveId, result && result.primitiveId),
1419
+ createCheck('browser execution schedule matches kernel', result && result.scheduleRef === kernelEvidence.scheduleRef, result && result.scheduleRef),
1420
+ createCheck('browser execution fiber matches Fabric bridge', result && result.fiberRef === fabricEvidence.fiber, result && result.fiberRef),
1421
+ createCheck('browser execution lane matches Fabric lane', result && result.lane === fabricEvidence.lane, result && result.lane),
1422
+ createCheck('browser execution schedule reaches Fabric', result && result.fabricScheduleRef === fabricEvidence.scheduleRef, result && result.fabricScheduleRef),
1423
+ createCheck('browser execution host telemetry visible', result && result.hostAdapterTelemetrySchema === RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA, result && result.hostAdapterTelemetrySchema),
1424
+ createCheck('browser execution observed action event', Boolean(result && toArray(result.events).some((event) => event.action === expectedAction)), result && result.events),
1425
+ createCheck('browser execution viewport checks pass', Boolean(result && toArray(result.checks).length > 0 && toArray(result.checks).every((check) => check.ok === true)), result && result.checks),
1426
+ createCheck('browser execution object matrix passes', Boolean(!result || !Array.isArray(result.objects) || (result.objects.length >= 4 && result.objects.every((entry) => entry.status === 'passed'))), result && result.objects),
1427
+ createCheck('browser execution cross-primitive events pass', Boolean(!result || !Array.isArray(result.crossPrimitiveEvents) || (result.crossPrimitiveEvents.length >= 2 && result.crossPrimitiveEvents.every((entry) => entry.status === 'passed'))), result && result.crossPrimitiveEvents),
1428
+ createCheck('browser execution cross-route event passes', Boolean(!result || !Array.isArray(result.crossPrimitiveEvents) || result.crossPrimitiveEvents.some((entry) => entry.stage === 'route-target' && entry.status === 'passed' && entry.sourceLane === 'transition' && entry.targetLane === 'transition')), result && result.crossPrimitiveEvents),
1429
+ createCheck('browser execution route switches pass', Boolean(!result || !Array.isArray(result.routeSwitches) || (result.routeSwitches.length >= 2 && result.routeSwitches.every((entry) => entry.status === 'passed' && entry.targetMounted === true && entry.targetVisible === true))), result && result.routeSwitches),
1430
+ createCheck('browser execution route lifecycle cycles pass', Boolean(!result || !Array.isArray(result.routeLifecycleCycles) || (result.routeLifecycleCycles.length >= 2 && result.routeLifecycleCycles.every((entry) => entry.status === 'passed' && entry.unmounted === true && entry.remounted === true && entry.resourceDisposed === true && entry.countsMatch === true))), result && result.routeLifecycleCycles),
1431
+ createCheck('browser execution route lifecycle targets are distinct', Boolean(!result || !Array.isArray(result.routeLifecycleCycles) || new Set(result.routeLifecycleCycles.map((entry) => entry.targetPrimitiveId)).size >= 2), result && result.routeLifecycleCycles)
1432
+ ];
1433
+ }
1434
+
1435
+ function createRmtVNextSourceToSeaBrowserResultValidation(result, evidence = {}) {
1436
+ const checks = createBrowserExecutionChecks(result, evidence);
1437
+ const ok = checks.every((check) => check.ok);
1438
+ const routeSwitches = toArray(result && result.routeSwitches);
1439
+ const routeLifecycleCycles = toArray(result && result.routeLifecycleCycles);
1440
+ const failedChecks = checks.filter((check) => !check.ok).map((check) => check.name);
1441
+
1442
+ return {
1443
+ schema: RMT_VNEXT_SOURCE_TO_SEA_BROWSER_RESULT_VALIDATION_SCHEMA,
1444
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1445
+ ok,
1446
+ status: ok ? 'passed' : 'failed',
1447
+ resultStatus: result && result.status || null,
1448
+ primitiveId: result && result.primitiveId || null,
1449
+ routeSwitchCount: routeSwitches.length,
1450
+ routeLifecycleCycleCount: routeLifecycleCycles.length,
1451
+ failedChecks,
1452
+ checks
1453
+ };
1454
+ }
1455
+
1456
+ function normalizeSourceToSeaObjects(browserProbe) {
1457
+ const objects = toArray(browserProbe && browserProbe.objects)
1458
+ .filter((entry) => entry && typeof entry === 'object' && entry.primitiveId);
1459
+ if (objects.length > 0) {
1460
+ return objects;
1461
+ }
1462
+ if (browserProbe && browserProbe.primitiveId) {
1463
+ return [{
1464
+ primitiveId: browserProbe.primitiveId,
1465
+ selector: browserProbe.selector,
1466
+ expectedText: browserProbe.expectedText,
1467
+ expectedAction: browserProbe.expectedAction,
1468
+ scheduleRef: browserProbe.scheduleRef,
1469
+ fiberRef: browserProbe.fiberRef,
1470
+ lane: browserProbe.lane,
1471
+ fabricScheduleRef: browserProbe.fabricScheduleRef,
1472
+ fabricEndpoint: browserProbe.fabricEndpoint
1473
+ }];
1474
+ }
1475
+ return [];
1476
+ }
1477
+
1478
+ function createObjectHostAdapterTelemetry(browserProbe, objectProbe) {
1479
+ const directTelemetry = objectProbe && objectProbe.hostAdapterTelemetry;
1480
+ if (directTelemetry && typeof directTelemetry === 'object') {
1481
+ return directTelemetry;
1482
+ }
1483
+
1484
+ const inheritedTelemetry = browserProbe && browserProbe.hostAdapterTelemetry;
1485
+ if (!inheritedTelemetry || typeof inheritedTelemetry !== 'object') {
1486
+ return inheritedTelemetry || null;
1487
+ }
1488
+
1489
+ const primitiveId = objectProbe.primitiveId
1490
+ || inheritedTelemetry.componentId
1491
+ || inheritedTelemetry.rmtComponentId
1492
+ || null;
1493
+ const lane = objectProbe.lane
1494
+ || inheritedTelemetry.fabricLane
1495
+ || inheritedTelemetry.rmtLane
1496
+ || null;
1497
+ const componentRef = objectProbe.componentRef
1498
+ || inheritedTelemetry.tag
1499
+ || null;
1500
+ const scheduleRef = objectProbe.fabricScheduleRef
1501
+ || inheritedTelemetry.scheduleRef
1502
+ || null;
1503
+
1504
+ return {
1505
+ ...inheritedTelemetry,
1506
+ componentId: primitiveId,
1507
+ rmtComponentId: primitiveId,
1508
+ tag: componentRef,
1509
+ scheduleRef,
1510
+ fabricLane: lane,
1511
+ rmtLane: lane,
1512
+ endpointNameHint: objectProbe.fabricEndpoint || inheritedTelemetry.endpointNameHint,
1513
+ correlationId: primitiveId || inheritedTelemetry.correlationId,
1514
+ metadata: {
1515
+ ...(inheritedTelemetry.metadata && typeof inheritedTelemetry.metadata === 'object'
1516
+ ? inheritedTelemetry.metadata
1517
+ : {}),
1518
+ primitiveId,
1519
+ componentRef
1520
+ }
1521
+ };
1522
+ }
1523
+
1524
+ function createObjectRouteComponentFibers(browserProbe, objectProbe) {
1525
+ const directRouteComponentFibers = objectProbe && objectProbe.routeComponentFibers;
1526
+ if (directRouteComponentFibers && typeof directRouteComponentFibers === 'object') {
1527
+ return directRouteComponentFibers;
1528
+ }
1529
+
1530
+ const inheritedRouteComponentFibers = browserProbe && browserProbe.routeComponentFibers;
1531
+ if (!inheritedRouteComponentFibers || typeof inheritedRouteComponentFibers !== 'object') {
1532
+ return inheritedRouteComponentFibers || null;
1533
+ }
1534
+
1535
+ const componentConfig = inheritedRouteComponentFibers.component && typeof inheritedRouteComponentFibers.component === 'object'
1536
+ ? inheritedRouteComponentFibers.component
1537
+ : {};
1538
+ const routeConfig = inheritedRouteComponentFibers.route && typeof inheritedRouteComponentFibers.route === 'object'
1539
+ ? inheritedRouteComponentFibers.route
1540
+ : {};
1541
+
1542
+ return {
1543
+ ...inheritedRouteComponentFibers,
1544
+ component: {
1545
+ ...componentConfig,
1546
+ componentRef: objectProbe.componentRef || componentConfig.componentRef,
1547
+ routeRef: objectProbe.routeRef || componentConfig.routeRef || routeConfig.routeRef
1548
+ },
1549
+ route: routeConfig
1550
+ };
1551
+ }
1552
+
1553
+ function createObjectBrowserProbe(browserProbe, objectProbe) {
1554
+ return {
1555
+ ...(browserProbe || {}),
1556
+ ...objectProbe,
1557
+ hostAdapterTelemetry: createObjectHostAdapterTelemetry(browserProbe, objectProbe),
1558
+ routeComponentFibers: createObjectRouteComponentFibers(browserProbe, objectProbe)
1559
+ };
1560
+ }
1561
+
1562
+ function summarizeSourceToSeaObject(objectProbe, evidence) {
1563
+ const checks = [
1564
+ createCheck('object source-to-sea evidence passes', evidence.ok === true, evidence.status),
1565
+ createCheck('object primitive id matches', evidence.primitiveId === objectProbe.primitiveId, evidence.primitiveId),
1566
+ createCheck('object action matches browser probe', evidence.browser.expectedAction === objectProbe.expectedAction, evidence.browser.expectedAction),
1567
+ createCheck('object kernel schedule matches browser probe', !objectProbe.scheduleRef || evidence.kernel.scheduleRef === objectProbe.scheduleRef, evidence.kernel.scheduleRef),
1568
+ createCheck('object fabric fiber matches browser probe', !objectProbe.fiberRef || evidence.fabric.fiber === objectProbe.fiberRef, evidence.fabric.fiber),
1569
+ createCheck('object fabric schedule matches browser probe', !objectProbe.fabricScheduleRef || evidence.fabric.scheduleRef === objectProbe.fabricScheduleRef, evidence.fabric.scheduleRef),
1570
+ createCheck('object UI selector matches browser probe', !objectProbe.selector || evidence.ui.selector === objectProbe.selector, evidence.ui.selector),
1571
+ createCheck('object UI text matches browser probe', !objectProbe.expectedText || evidence.ui.text === objectProbe.expectedText, evidence.ui.text)
1572
+ ];
1573
+
1574
+ return {
1575
+ ok: checks.every((check) => check.ok),
1576
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1577
+ primitiveId: objectProbe.primitiveId,
1578
+ actionId: objectProbe.expectedAction || null,
1579
+ componentRef: objectProbe.componentRef || (evidence.ui && evidence.ui.component) || null,
1580
+ sourcePointer: evidence.sourcePointer,
1581
+ astPointer: evidence.sourceMap && evidence.sourceMap.astPointer,
1582
+ kernel: {
1583
+ scheduleRef: evidence.kernel.scheduleRef
1584
+ },
1585
+ fabric: {
1586
+ fiber: evidence.fabric.fiber,
1587
+ lane: evidence.fabric.lane,
1588
+ scheduleRef: evidence.fabric.scheduleRef,
1589
+ endpointName: evidence.fabric.endpointName
1590
+ },
1591
+ ui: evidence.ui,
1592
+ browser: evidence.browser,
1593
+ checks
1594
+ };
1595
+ }
1596
+
1597
+ function createCrossPrimitiveEventMatrix(crossPrimitiveEvents, coreDocument, objects) {
1598
+ const actions = toArray(coreDocument && coreDocument.actions);
1599
+ const objectIds = new Set(objects.map((entry) => entry.primitiveId));
1600
+ return toArray(crossPrimitiveEvents).map((crossEvent) => {
1601
+ const sourceObject = objects.find((entry) => entry.primitiveId === crossEvent.sourcePrimitiveId) || null;
1602
+ const targetObject = objects.find((entry) => entry.primitiveId === crossEvent.targetPrimitiveId) || null;
1603
+ const sourceLane = sourceObject && sourceObject.fabric && sourceObject.fabric.lane || null;
1604
+ const targetLane = targetObject && targetObject.fabric && targetObject.fabric.lane || null;
1605
+ const action = actions.find((entry) => entry.name === crossEvent.actionId || entry.id === crossEvent.actionId) || null;
1606
+ const reducer = toArray(action && action.reducers)
1607
+ .find((entry) => entry.target === crossEvent.targetState) || null;
1608
+ const emit = toArray(action && action.emits)
1609
+ .find((entry) => entry.event === crossEvent.eventId) || null;
1610
+ const routeTargetStateOk = crossEvent.stage !== 'route-target'
1611
+ || !crossEvent.targetState
1612
+ || String(crossEvent.targetState).startsWith(`state.${crossEvent.targetPrimitiveId}.`);
1613
+ const routeTargetEventOk = crossEvent.stage !== 'route-target'
1614
+ || !crossEvent.eventId
1615
+ || String(crossEvent.eventId).startsWith(`${crossEvent.targetPrimitiveId}.`);
1616
+ const routeTargetStageOk = crossEvent.stage !== 'route-target' || (sourceLane === 'transition' && targetLane === 'transition');
1617
+ const checks = [
1618
+ createCheck('cross event source object exists', objectIds.has(crossEvent.sourcePrimitiveId), crossEvent.sourcePrimitiveId),
1619
+ createCheck('cross event target object exists', objectIds.has(crossEvent.targetPrimitiveId), crossEvent.targetPrimitiveId),
1620
+ createCheck('cross event action exists', Boolean(action), crossEvent.actionId),
1621
+ createCheck('cross event reducer targets another primitive state', Boolean(reducer), crossEvent.targetState),
1622
+ createCheck('cross event emitted', Boolean(emit), crossEvent.eventId),
1623
+ createCheck('cross event target lane matches expected', !crossEvent.lane || targetLane === crossEvent.lane, crossEvent.lane),
1624
+ createCheck('cross event route-target state belongs to target primitive', routeTargetStateOk, crossEvent.targetState),
1625
+ createCheck('cross event route-target event belongs to target primitive', routeTargetEventOk, crossEvent.eventId),
1626
+ createCheck('cross event route-target stage uses transition lanes', routeTargetStageOk, `${sourceLane || '?'} -> ${targetLane || '?'}`)
1627
+ ];
1628
+ return {
1629
+ ok: checks.every((check) => check.ok),
1630
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1631
+ sourcePrimitiveId: crossEvent.sourcePrimitiveId,
1632
+ targetPrimitiveId: crossEvent.targetPrimitiveId,
1633
+ actionId: crossEvent.actionId,
1634
+ eventId: crossEvent.eventId || null,
1635
+ targetState: crossEvent.targetState || null,
1636
+ expectedText: crossEvent.expectedText || null,
1637
+ lane: crossEvent.lane || null,
1638
+ stage: crossEvent.stage || null,
1639
+ sourceLane,
1640
+ targetLane,
1641
+ reducer: reducer ? {
1642
+ target: reducer.target,
1643
+ value: reducer.value
1644
+ } : null,
1645
+ emit: emit ? {
1646
+ event: emit.event,
1647
+ payload: emit.payload
1648
+ } : null,
1649
+ checks
1650
+ };
1651
+ });
1652
+ }
1653
+
1654
+ function createRouteSwitchMatrix(routeSwitches, objects) {
1655
+ const objectIds = new Set(objects.map((entry) => entry.primitiveId));
1656
+ const defaultRouteScenario = RMT_VNEXT_ROUTE_COMPONENT_FIBER_SCENARIOS.route;
1657
+ return toArray(routeSwitches).map((routeSwitch) => {
1658
+ const targetObject = objects.find((entry) => entry.primitiveId === routeSwitch.targetPrimitiveId) || null;
1659
+ const hasRouteChange = Boolean(routeSwitch.from && routeSwitch.to && routeSwitch.from !== routeSwitch.to);
1660
+ const checks = [
1661
+ createCheck('route switch source object exists', objectIds.has(routeSwitch.sourcePrimitiveId), routeSwitch.sourcePrimitiveId),
1662
+ createCheck('route switch target object exists', !routeSwitch.targetPrimitiveId || objectIds.has(routeSwitch.targetPrimitiveId), routeSwitch.targetPrimitiveId),
1663
+ createCheck('route switch changes route', hasRouteChange, `${routeSwitch.from || '?'} -> ${routeSwitch.to || '?'}`),
1664
+ createCheck('route switch uses navigation schedule', routeSwitch.scheduleRef === defaultRouteScenario.navigateScheduleRef, routeSwitch.scheduleRef),
1665
+ createCheck('route switch uses render schedule', routeSwitch.renderScheduleRef === defaultRouteScenario.renderScheduleRef, routeSwitch.renderScheduleRef),
1666
+ createCheck('route switch uses transition lane', routeSwitch.lane === 'transition', routeSwitch.lane),
1667
+ createCheck('route switch target schedule matches object', !routeSwitch.targetScheduleRef || Boolean(targetObject && targetObject.kernel && targetObject.kernel.scheduleRef === routeSwitch.targetScheduleRef), routeSwitch.targetScheduleRef),
1668
+ createCheck('route switch target fiber matches object', !routeSwitch.targetFiberRef || Boolean(targetObject && targetObject.fabric && targetObject.fabric.fiber === routeSwitch.targetFiberRef), routeSwitch.targetFiberRef),
1669
+ createCheck('route switch target uses transition lane', !targetObject || targetObject.fabric.lane === 'transition', targetObject && targetObject.fabric && targetObject.fabric.lane)
1670
+ ];
1671
+ return {
1672
+ ok: checks.every((check) => check.ok),
1673
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1674
+ id: routeSwitch.id || null,
1675
+ sourcePrimitiveId: routeSwitch.sourcePrimitiveId || null,
1676
+ targetPrimitiveId: routeSwitch.targetPrimitiveId || null,
1677
+ actionId: routeSwitch.actionId || null,
1678
+ from: routeSwitch.from || null,
1679
+ to: routeSwitch.to || null,
1680
+ routeId: routeSwitch.routeId || null,
1681
+ scheduleRef: routeSwitch.scheduleRef || null,
1682
+ renderScheduleRef: routeSwitch.renderScheduleRef || null,
1683
+ lane: routeSwitch.lane || null,
1684
+ targetScheduleRef: routeSwitch.targetScheduleRef || null,
1685
+ targetFiberRef: routeSwitch.targetFiberRef || null,
1686
+ targetExpectedText: routeSwitch.targetExpectedText || null,
1687
+ checks
1688
+ };
1689
+ });
1690
+ }
1691
+
1692
+ function createRouteLifecycleMatrix(routeLifecycleCycles, coreDocument, objects) {
1693
+ const objectIds = new Set(objects.map((entry) => entry.primitiveId));
1694
+ const resources = toArray(coreDocument && coreDocument.resources);
1695
+ const normalizeCycleResources = (cycle) => {
1696
+ const normalized = [];
1697
+ const seen = new Set();
1698
+ const addResource = (entry) => {
1699
+ const resourceId = typeof entry === 'string'
1700
+ ? entry
1701
+ : entry && (entry.resourceId || entry.id || entry.name);
1702
+ if (!resourceId || seen.has(resourceId)) {
1703
+ return;
1704
+ }
1705
+ seen.add(resourceId);
1706
+ normalized.push({
1707
+ resourceId,
1708
+ kind: typeof entry === 'object' && entry ? entry.kind || null : null
1709
+ });
1710
+ };
1711
+ toArray(cycle.resources).forEach(addResource);
1712
+ toArray(cycle.resourceIds).forEach(addResource);
1713
+ addResource({
1714
+ resourceId: cycle.resourceId,
1715
+ kind: cycle.resourceKind || cycle.kind || null
1716
+ });
1717
+ return normalized;
1718
+ };
1719
+ return toArray(routeLifecycleCycles).map((cycle) => {
1720
+ const targetObject = objects.find((entry) => entry.primitiveId === cycle.targetPrimitiveId) || null;
1721
+ const resourceSpecs = normalizeCycleResources(cycle);
1722
+ const resourceResults = resourceSpecs.map((spec) => {
1723
+ const resource = resources.find((entry) => entry.name === spec.resourceId || entry.id === `resource:${String(spec.resourceId || '').toLowerCase()}`) || null;
1724
+ const diagnostics = [];
1725
+
1726
+ if (!resource) {
1727
+ diagnostics.push({
1728
+ code: RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES.resourceMissing,
1729
+ level: 'error',
1730
+ message: `Route lifecycle cleanup resource ${spec.resourceId || '<missing>'} was not emitted by vNext lowering.`,
1731
+ targetPrimitiveId: cycle.targetPrimitiveId || null,
1732
+ resourceId: spec.resourceId || null
1733
+ });
1734
+ } else if (!resource.owner || resource.owner.id !== cycle.targetPrimitiveId) {
1735
+ diagnostics.push({
1736
+ code: RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES.ownerMismatch,
1737
+ level: 'error',
1738
+ message: `Route lifecycle cleanup resource ${spec.resourceId} is not owned by ${cycle.targetPrimitiveId}.`,
1739
+ targetPrimitiveId: cycle.targetPrimitiveId || null,
1740
+ resourceId: spec.resourceId || null,
1741
+ owner: resource.owner || null
1742
+ });
1743
+ }
1744
+
1745
+ if (resource && (!resource.dispose || resource.dispose.text !== 'on surface.destroy')) {
1746
+ diagnostics.push({
1747
+ code: RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES.disposePolicyMissing,
1748
+ level: 'error',
1749
+ message: `Route lifecycle cleanup resource ${spec.resourceId} must dispose on surface.destroy.`,
1750
+ targetPrimitiveId: cycle.targetPrimitiveId || null,
1751
+ resourceId: spec.resourceId || null,
1752
+ dispose: resource.dispose || null
1753
+ });
1754
+ }
1755
+
1756
+ if (resource && spec.kind && resource.kind !== spec.kind) {
1757
+ diagnostics.push({
1758
+ code: RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES.kindMismatch,
1759
+ level: 'error',
1760
+ message: `Route lifecycle cleanup resource ${spec.resourceId} must use kind ${spec.kind}.`,
1761
+ targetPrimitiveId: cycle.targetPrimitiveId || null,
1762
+ resourceId: spec.resourceId || null,
1763
+ expectedKind: spec.kind,
1764
+ actualKind: resource.kind || null
1765
+ });
1766
+ }
1767
+
1768
+ return {
1769
+ ok: diagnostics.length === 0,
1770
+ resourceId: spec.resourceId || null,
1771
+ expectedKind: spec.kind || null,
1772
+ resource: resource ? {
1773
+ id: resource.id,
1774
+ name: resource.name,
1775
+ kind: resource.kind,
1776
+ owner: resource.owner,
1777
+ dispose: resource.dispose
1778
+ } : null,
1779
+ diagnostics
1780
+ };
1781
+ });
1782
+ const primaryResource = resourceResults[0] || null;
1783
+ const resourceChecks = resourceResults.flatMap((entry) => [
1784
+ createCheck('route lifecycle resource exists', Boolean(entry.resource), entry.resourceId),
1785
+ createCheck('route lifecycle resource owner matches target', Boolean(entry.resource && entry.resource.owner && entry.resource.owner.id === cycle.targetPrimitiveId), entry.resource && entry.resource.owner && entry.resource.owner.id),
1786
+ createCheck('route lifecycle resource dispose policy is surface destroy', Boolean(entry.resource && entry.resource.dispose && entry.resource.dispose.text === 'on surface.destroy'), entry.resource && entry.resource.dispose && entry.resource.dispose.text),
1787
+ createCheck('route lifecycle resource kind matches expected', !entry.expectedKind || Boolean(entry.resource && entry.resource.kind === entry.expectedKind), entry.expectedKind)
1788
+ ]);
1789
+ const diagnostics = resourceResults.flatMap((entry) => entry.diagnostics);
1790
+
1791
+ const checks = [
1792
+ createCheck('route lifecycle target object exists', objectIds.has(cycle.targetPrimitiveId), cycle.targetPrimitiveId),
1793
+ createCheck('route lifecycle target uses transition lane', Boolean(targetObject && targetObject.fabric && targetObject.fabric.lane === 'transition'), targetObject && targetObject.fabric && targetObject.fabric.lane),
1794
+ createCheck('route lifecycle unmount schedule declared', cycle.unmountScheduleRef === 'ui.background.work', cycle.unmountScheduleRef),
1795
+ createCheck('route lifecycle remount schedule declared', cycle.remountScheduleRef === 'route.transition.render', cycle.remountScheduleRef),
1796
+ createCheck('route lifecycle declares cleanup resources', resourceResults.length >= 1, cycle.resourceId || cycle.resources),
1797
+ ...resourceChecks,
1798
+ createCheck('route lifecycle expected unmount count declared', Number(cycle.expectedUnmountCount || 0) >= 1, cycle.expectedUnmountCount),
1799
+ createCheck('route lifecycle expected remount count declared', Number(cycle.expectedRemountCount || 0) >= 1, cycle.expectedRemountCount)
1800
+ ];
1801
+ return {
1802
+ ok: checks.every((check) => check.ok),
1803
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1804
+ id: cycle.id || null,
1805
+ targetPrimitiveId: cycle.targetPrimitiveId || null,
1806
+ from: cycle.from || null,
1807
+ to: cycle.to || null,
1808
+ unmountScheduleRef: cycle.unmountScheduleRef || null,
1809
+ remountScheduleRef: cycle.remountScheduleRef || null,
1810
+ resourceId: primaryResource && primaryResource.resourceId || cycle.resourceId || null,
1811
+ resourceIds: resourceResults.map((entry) => entry.resourceId).filter(Boolean),
1812
+ resourceKinds: resourceResults.map((entry) => entry.resource && entry.resource.kind || entry.expectedKind).filter(Boolean),
1813
+ resource: primaryResource && primaryResource.resource || null,
1814
+ resources: resourceResults,
1815
+ diagnostics,
1816
+ expectedUnmountCount: cycle.expectedUnmountCount || null,
1817
+ expectedRemountCount: cycle.expectedRemountCount || null,
1818
+ checks
1819
+ };
1820
+ });
1821
+ }
1822
+
1823
+ function createRmtVNextSourceToSeaObjectMatrix(input, options = {}) {
1824
+ const browserFixtureText = typeof options.browserFixtureText === 'string' ? options.browserFixtureText : '';
1825
+ const browserProbe = options.browserProbe || parseJsonScript(browserFixtureText, 'rmt-source-to-sea-probe') || {};
1826
+ const objects = normalizeSourceToSeaObjects(browserProbe);
1827
+ const compileResult = compileRmtVNextSource(input, options.compilerOptions || {});
1828
+ const coreDocument = compileResult.coreDocument || null;
1829
+ const primaryEvidence = options.primaryEvidence || null;
1830
+ const entries = objects.map((objectProbe) => {
1831
+ const objectBrowserProbe = createObjectBrowserProbe(browserProbe, objectProbe);
1832
+ const evidence = primaryEvidence && primaryEvidence.primitiveId === objectProbe.primitiveId
1833
+ ? primaryEvidence
1834
+ : createRmtVNextSourceToSeaEvidence(input, {
1835
+ ...options,
1836
+ browserProbe: objectBrowserProbe,
1837
+ primitiveId: objectProbe.primitiveId,
1838
+ actionId: objectProbe.expectedAction,
1839
+ expectedAction: objectProbe.expectedAction,
1840
+ expectedText: objectProbe.expectedText,
1841
+ selector: objectProbe.selector,
1842
+ lane: objectProbe.lane || options.lane,
1843
+ browserFixtureText,
1844
+ browserFixturePath: options.browserFixturePath
1845
+ });
1846
+ return summarizeSourceToSeaObject(objectProbe, evidence);
1847
+ });
1848
+ const crossPrimitiveEvents = createCrossPrimitiveEventMatrix(browserProbe.crossPrimitiveEvents, coreDocument, entries);
1849
+ const routeSwitches = createRouteSwitchMatrix(browserProbe.routeSwitches, entries);
1850
+ const routeLifecycleCycles = createRouteLifecycleMatrix(browserProbe.routeLifecycleCycles, coreDocument, entries);
1851
+ const primitiveIds = entries.map((entry) => entry.primitiveId);
1852
+ const lanes = entries.map((entry) => entry.fabric && entry.fabric.lane).filter(Boolean);
1853
+ const routeLifecycleTargets = routeLifecycleCycles.map((entry) => entry.targetPrimitiveId).filter(Boolean);
1854
+ const checks = [
1855
+ createCheck('object matrix compiler result ok', compileResult.ok === true, compileResult.status),
1856
+ createCheck('object matrix declares multiple objects', entries.length >= 4, primitiveIds),
1857
+ createCheck('object matrix primitive ids are unique', new Set(primitiveIds).size === primitiveIds.length, primitiveIds),
1858
+ createCheck('object matrix covers multiple lanes', new Set(lanes).size >= 2, lanes),
1859
+ createCheck('object matrix entries pass', entries.every((entry) => entry.ok), entries.filter((entry) => !entry.ok).map((entry) => entry.primitiveId)),
1860
+ createCheck('object matrix cross-primitive events pass', crossPrimitiveEvents.length >= 2 && crossPrimitiveEvents.every((entry) => entry.ok), crossPrimitiveEvents.map((entry) => `${entry.sourcePrimitiveId}->${entry.targetPrimitiveId}`)),
1861
+ createCheck('object matrix cross-route event passes', crossPrimitiveEvents.some((entry) => entry.stage === 'route-target' && entry.ok && entry.sourceLane === 'transition' && entry.targetLane === 'transition'), crossPrimitiveEvents.map((entry) => `${entry.stage || 'surface'}:${entry.sourcePrimitiveId}->${entry.targetPrimitiveId}`)),
1862
+ createCheck('object matrix route switches pass', routeSwitches.length >= 2 && routeSwitches.every((entry) => entry.ok), routeSwitches.map((entry) => `${entry.from}->${entry.to}`)),
1863
+ createCheck('object matrix route lifecycle cycles pass', routeLifecycleCycles.length >= 2 && routeLifecycleCycles.every((entry) => entry.ok), routeLifecycleTargets),
1864
+ createCheck('object matrix route lifecycle targets are distinct', new Set(routeLifecycleTargets).size >= 2, routeLifecycleTargets)
1865
+ ];
1866
+
1867
+ return {
1868
+ schema: RMT_VNEXT_SOURCE_TO_SEA_OBJECT_MATRIX_SCHEMA,
1869
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1870
+ ok: checks.every((check) => check.ok),
1871
+ status: checks.every((check) => check.ok) ? 'passed' : 'failed',
1872
+ objectCount: entries.length,
1873
+ primitiveIds,
1874
+ lanes,
1875
+ objects: entries,
1876
+ crossPrimitiveEvents,
1877
+ routeSwitches,
1878
+ routeLifecycleCycles,
1879
+ checks
1880
+ };
1881
+ }
1882
+
1883
+ function resolveReportOutputPath(outputPath, rootDir = process.cwd()) {
1884
+ return path.isAbsolute(outputPath)
1885
+ ? outputPath
1886
+ : path.resolve(rootDir, outputPath);
1887
+ }
1888
+
1889
+ function readSourceToSeaFixture(rootDir, sourcePath) {
1890
+ return fs.readFileSync(path.resolve(rootDir, sourcePath), 'utf8');
1891
+ }
1892
+
1893
+ function createRmtVNextSourceToSeaCiArtifactValidation(report = {}, options = {}) {
1894
+ const browserExecution = report.browserExecution || {};
1895
+ const result = browserExecution.result || {};
1896
+ const routeSwitches = toArray(result.routeSwitches);
1897
+ const routeLifecycleCycles = toArray(result.routeLifecycleCycles);
1898
+ const crossPrimitiveEvents = toArray(result.crossPrimitiveEvents);
1899
+ const auditLifecycle = routeLifecycleCycles.find((entry) => entry && entry.targetPrimitiveId === 'demo.feedback.audit') || {};
1900
+ const expectedAuditResources = ['demo.feedback.auditTimer', 'demo.feedback.auditSubscription'];
1901
+ const expectedAuditKinds = ['timer', 'subscription'];
1902
+ const shouldValidate = browserExecution.required === true || browserExecution.status === 'passed' || options.requireBrowserExecution === true;
1903
+ const expectedBrowserDriver = normalizeBrowserDriver(options.expectedBrowserDriver || RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_DRIVER);
1904
+
1905
+ if (!shouldValidate) {
1906
+ return {
1907
+ schema: RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA,
1908
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1909
+ ok: true,
1910
+ status: 'skipped',
1911
+ required: false,
1912
+ reason: 'CI artifact validation waits for browser-required evidence.',
1913
+ checks: [
1914
+ createCheck('ci artifact validation waits for required browser execution', browserExecution.status === 'skipped' || browserExecution.required !== true, browserExecution.status)
1915
+ ]
1916
+ };
1917
+ }
1918
+
1919
+ const checks = [
1920
+ createCheck('ci artifact report schema matches source-to-sea evidence report', report.schema === RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_SCHEMA, report.schema),
1921
+ createCheck('ci artifact report belongs to PRIM-06', report.workpackage === RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE, report.workpackage),
1922
+ createCheck('ci artifact report passed before validation', report.ok === true && report.status === 'passed', report.status),
1923
+ createCheck('ci artifact path is stable', report.artifact && report.artifact.path === RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH, report.artifact && report.artifact.path),
1924
+ createCheck('ci artifact browser execution is required', report.artifact && report.artifact.browserExecutionRequired === true && browserExecution.required === true, report.artifact && report.artifact.browserExecutionRequired),
1925
+ createCheck('ci artifact browser execution passed', report.artifact && report.artifact.browserExecutionStatus === 'passed' && browserExecution.status === 'passed', browserExecution.status),
1926
+ createCheck('ci artifact browser execution uses expected driver', normalizeBrowserDriver(browserExecution.driver) === expectedBrowserDriver, {
1927
+ actualDriver: browserExecution.driver,
1928
+ expectedDriver: expectedBrowserDriver
1929
+ }),
1930
+ createCheck('ci artifact object count matches Source-to-Sea contract', result.objectCount === 4, result.objectCount),
1931
+ createCheck('ci artifact cross-primitive event count matches contract', crossPrimitiveEvents.length === 2 && crossPrimitiveEvents.every((entry) => entry.status === 'passed'), crossPrimitiveEvents.length),
1932
+ createCheck('ci artifact includes cross-route event evidence', crossPrimitiveEvents.some((entry) => entry.stage === 'route-target' && entry.sourcePrimitiveId === 'demo.feedback.detail' && entry.targetPrimitiveId === 'demo.feedback.audit' && entry.sourceLane === 'transition' && entry.targetLane === 'transition'), crossPrimitiveEvents),
1933
+ createCheck('ci artifact route switches match contract', routeSwitches.length === 2 && routeSwitches.every((entry) => entry.status === 'passed' && entry.targetMounted === true && entry.targetVisible === true), routeSwitches),
1934
+ createCheck('ci artifact route lifecycle cycles match contract', routeLifecycleCycles.length === 2 && routeLifecycleCycles.every((entry) => entry.status === 'passed' && entry.unmounted === true && entry.remounted === true && entry.resourceDisposed === true && entry.countsMatch === true), routeLifecycleCycles),
1935
+ createCheck('ci artifact audit lifecycle records expected resources', expectedAuditResources.every((resourceId) => toArray(auditLifecycle.resourceIds).includes(resourceId)), auditLifecycle.resourceIds),
1936
+ createCheck('ci artifact audit lifecycle records expected resource kinds', expectedAuditKinds.every((kind) => toArray(auditLifecycle.resourceKinds).includes(kind)), auditLifecycle.resourceKinds),
1937
+ createCheck('ci artifact audit lifecycle keeps counts stable', auditLifecycle.unmountCount === 1 && auditLifecycle.remountCount === 1, {
1938
+ unmountCount: auditLifecycle.unmountCount,
1939
+ remountCount: auditLifecycle.remountCount
1940
+ })
1941
+ ];
1942
+ const ok = checks.every((check) => check.ok);
1943
+
1944
+ return {
1945
+ schema: RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA,
1946
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1947
+ ok,
1948
+ status: ok ? 'passed' : 'failed',
1949
+ required: true,
1950
+ driver: browserExecution.driver || null,
1951
+ artifactPath: report.artifact && report.artifact.path || null,
1952
+ checks
1953
+ };
1954
+ }
1955
+
1956
+ function validateRmtVNextSourceToSeaCiArtifactFile(artifactPath = RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH, options = {}) {
1957
+ const rootDir = options.rootDir || process.cwd();
1958
+ const resolvedPath = resolveReportOutputPath(
1959
+ artifactPath || RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH,
1960
+ rootDir
1961
+ );
1962
+
1963
+ if (!fs.existsSync(resolvedPath)) {
1964
+ return {
1965
+ schema: RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA,
1966
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1967
+ ok: false,
1968
+ status: 'failed',
1969
+ required: true,
1970
+ driver: null,
1971
+ artifactPath: resolvedPath,
1972
+ replayed: true,
1973
+ checks: [
1974
+ createCheck('ci artifact file exists', false, resolvedPath)
1975
+ ]
1976
+ };
1977
+ }
1978
+
1979
+ let report = null;
1980
+ try {
1981
+ report = JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));
1982
+ } catch (error) {
1983
+ return {
1984
+ schema: RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA,
1985
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
1986
+ ok: false,
1987
+ status: 'failed',
1988
+ required: true,
1989
+ driver: null,
1990
+ artifactPath: resolvedPath,
1991
+ replayed: true,
1992
+ checks: [
1993
+ createCheck('ci artifact file parses as JSON', false, error && error.message)
1994
+ ]
1995
+ };
1996
+ }
1997
+
1998
+ const validation = createRmtVNextSourceToSeaCiArtifactValidation(report, {
1999
+ requireBrowserExecution: true,
2000
+ expectedBrowserDriver: options.expectedBrowserDriver || RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_DRIVER
2001
+ });
2002
+
2003
+ return {
2004
+ ...validation,
2005
+ artifactPath: resolvedPath,
2006
+ replayed: true
2007
+ };
2008
+ }
2009
+
2010
+ async function createRmtVNextSourceToSeaEvidenceReport(options = {}) {
2011
+ const rootDir = options.rootDir || process.cwd();
2012
+ const sourcePath = options.sourcePath || RMT_VNEXT_SOURCE_TO_SEA_FIXTURE_PATH;
2013
+ const browserFixturePath = options.browserFixturePath || RMT_VNEXT_SOURCE_TO_SEA_BROWSER_FIXTURE_PATH;
2014
+ const sourceText = typeof options.sourceText === 'string'
2015
+ ? options.sourceText
2016
+ : readSourceToSeaFixture(rootDir, sourcePath);
2017
+ const browserFixtureText = typeof options.browserFixtureText === 'string'
2018
+ ? options.browserFixtureText
2019
+ : readSourceToSeaFixture(rootDir, browserFixturePath);
2020
+ const evidence = options.evidence || createRmtVNextSourceToSeaEvidence({
2021
+ text: sourceText,
2022
+ filePath: path.resolve(rootDir, sourcePath)
2023
+ }, {
2024
+ browserFixtureText,
2025
+ browserFixturePath
2026
+ });
2027
+ const browserExecution = options.browserExecution || await runRmtVNextSourceToSeaBrowserExecution(evidence, {
2028
+ rootDir,
2029
+ browserFixturePath,
2030
+ browserDriver: options.browserDriver,
2031
+ requireBrowserExecution: options.requireBrowserExecution,
2032
+ chromeDriverPath: options.chromeDriverPath,
2033
+ webDriverUrl: options.webDriverUrl,
2034
+ webDriverPort: options.webDriverPort,
2035
+ browserName: options.browserName,
2036
+ timeoutMs: options.timeoutMs
2037
+ });
2038
+ const objectMatrix = options.objectMatrix || createRmtVNextSourceToSeaObjectMatrix({
2039
+ text: sourceText,
2040
+ filePath: path.resolve(rootDir, sourcePath)
2041
+ }, {
2042
+ browserFixtureText,
2043
+ browserFixturePath,
2044
+ primaryEvidence: evidence
2045
+ });
2046
+ const baseChecks = [
2047
+ createCheck('source-to-sea evidence passes', evidence.ok === true, evidence.status),
2048
+ createCheck('source-to-sea object matrix passes', objectMatrix.ok === true, objectMatrix.primitiveIds),
2049
+ createCheck('browser execution evidence contract emitted', browserExecution.schema === RMT_VNEXT_BROWSER_EXECUTION_EVIDENCE_SCHEMA, browserExecution.schema),
2050
+ createCheck('browser execution policy satisfied', browserExecution.ok === true, browserExecution.reason || browserExecution.status)
2051
+ ];
2052
+ const baseOk = baseChecks.every((check) => check.ok);
2053
+ const baseReport = {
2054
+ schema: RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_SCHEMA,
2055
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
2056
+ ok: baseOk,
2057
+ status: baseOk ? 'passed' : 'failed',
2058
+ source: sourcePath,
2059
+ browserFixture: browserFixturePath,
2060
+ resultKey: RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY,
2061
+ artifact: {
2062
+ path: RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH,
2063
+ browserExecutionRequired: browserExecution.required === true,
2064
+ browserExecutionStatus: browserExecution.status
2065
+ },
2066
+ evidence,
2067
+ objectMatrix,
2068
+ browserExecution,
2069
+ checks: baseChecks
2070
+ };
2071
+ const ciArtifactValidation = createRmtVNextSourceToSeaCiArtifactValidation(baseReport, {
2072
+ requireBrowserExecution: browserExecution.required === true,
2073
+ expectedBrowserDriver: browserExecution.driver || RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_DRIVER
2074
+ });
2075
+ const checks = [
2076
+ ...baseChecks,
2077
+ createCheck('source-to-sea CI artifact validation passes when browser required', browserExecution.required !== true || ciArtifactValidation.ok === true, ciArtifactValidation.status)
2078
+ ];
2079
+ const ok = checks.every((check) => check.ok);
2080
+
2081
+ return {
2082
+ ...baseReport,
2083
+ ok,
2084
+ status: ok ? 'passed' : 'failed',
2085
+ ciArtifactValidation,
2086
+ checks
2087
+ };
2088
+ }
2089
+
2090
+ async function writeRmtVNextSourceToSeaEvidenceReport(options = {}) {
2091
+ const rootDir = options.rootDir || process.cwd();
2092
+ const report = await createRmtVNextSourceToSeaEvidenceReport(options);
2093
+ const outputPath = resolveReportOutputPath(
2094
+ options.outputPath || RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH,
2095
+ rootDir
2096
+ );
2097
+
2098
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
2099
+ fs.writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8');
2100
+
2101
+ return {
2102
+ outputPath,
2103
+ report
2104
+ };
2105
+ }
2106
+
2107
+ function resolveBrowserExecutionDriver(options = {}) {
2108
+ if (options.browserDriver) {
2109
+ return normalizeBrowserDriver(options.browserDriver);
2110
+ }
2111
+ if (options.requireBrowserExecution === true && process.env.RMT_VNEXT_SOURCE_TO_SEA_BROWSER_DRIVER) {
2112
+ return normalizeBrowserDriver(process.env.RMT_VNEXT_SOURCE_TO_SEA_BROWSER_DRIVER);
2113
+ }
2114
+ if (options.requireBrowserExecution === true && process.env.XTEND_BROWSER_SMOKE_DRIVER) {
2115
+ return normalizeBrowserDriver(process.env.XTEND_BROWSER_SMOKE_DRIVER);
2116
+ }
2117
+ if (options.requireBrowserExecution === true) {
2118
+ return detectAvailableBrowserDriver(options);
2119
+ }
2120
+ return normalizeBrowserDriver(process.env.RMT_VNEXT_SOURCE_TO_SEA_BROWSER_DRIVER || '');
2121
+ }
2122
+
2123
+ async function runRmtVNextSourceToSeaBrowserExecution(evidence, options = {}) {
2124
+ const driver = resolveBrowserExecutionDriver(options);
2125
+ const base = {
2126
+ schema: RMT_VNEXT_BROWSER_EXECUTION_EVIDENCE_SCHEMA,
2127
+ workpackage: RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
2128
+ resultKey: RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY,
2129
+ fixture: options.browserFixturePath || RMT_VNEXT_SOURCE_TO_SEA_BROWSER_FIXTURE_PATH,
2130
+ url: createBrowserExecutionUrl(options),
2131
+ driver: driver || null,
2132
+ required: options.requireBrowserExecution === true
2133
+ };
2134
+
2135
+ if (!driver) {
2136
+ return {
2137
+ ...base,
2138
+ ok: options.requireBrowserExecution !== true,
2139
+ status: options.requireBrowserExecution === true ? 'failed' : 'skipped',
2140
+ mode: 'fixture-contract',
2141
+ reason: 'set RMT_VNEXT_SOURCE_TO_SEA_BROWSER_DRIVER=firefox, chromedriver, webdriver, safari or edge to execute the fixture in a browser',
2142
+ checks: [
2143
+ createCheck('browser execution fixture contract available', Boolean(evidence && evidence.browser && evidence.browser.resultKey === RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY), evidence && evidence.browser)
2144
+ ]
2145
+ };
2146
+ }
2147
+
2148
+ if (!supportedBrowserDriver(driver)) {
2149
+ return {
2150
+ ...base,
2151
+ ok: options.requireBrowserExecution !== true,
2152
+ status: options.requireBrowserExecution === true ? 'failed' : 'skipped',
2153
+ mode: 'unsupported-driver',
2154
+ reason: `unsupported RMT vNext source-to-sea browser driver: ${driver}`,
2155
+ checks: [
2156
+ createCheck('browser execution driver supported', false, driver)
2157
+ ]
2158
+ };
2159
+ }
2160
+
2161
+ try {
2162
+ const result = await runWebDriverBrowserProbe({
2163
+ ...options,
2164
+ driver,
2165
+ resultKey: RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY
2166
+ });
2167
+ const resultValidation = createRmtVNextSourceToSeaBrowserResultValidation(result, evidence);
2168
+ return {
2169
+ ...base,
2170
+ ok: resultValidation.ok,
2171
+ status: resultValidation.status,
2172
+ mode: driver,
2173
+ result,
2174
+ resultValidation,
2175
+ checks: resultValidation.checks
2176
+ };
2177
+ } catch (error) {
2178
+ return {
2179
+ ...base,
2180
+ ok: options.requireBrowserExecution !== true,
2181
+ status: options.requireBrowserExecution === true ? 'failed' : 'skipped',
2182
+ mode: driver,
2183
+ reason: error && error.message ? error.message : String(error),
2184
+ checks: [
2185
+ createCheck('browser execution completed', false, error && error.message ? error.message : String(error))
2186
+ ]
2187
+ };
2188
+ }
2189
+ }
2190
+
2191
+ module.exports = {
2192
+ RMT_VNEXT_BROWSER_EXECUTION_EVIDENCE_SCHEMA,
2193
+ RMT_VNEXT_FABRIC_BRIDGE_EVIDENCE_SCHEMA,
2194
+ RMT_VNEXT_FABRIC_BRIDGE_LANE_MATRIX,
2195
+ RMT_VNEXT_FABRIC_BRIDGE_WORKPACKAGE,
2196
+ RMT_VNEXT_HOST_ADAPTER_TELEMETRY_SCHEMA,
2197
+ RMT_VNEXT_ROUTE_COMPONENT_FIBER_EVIDENCE_SCHEMA,
2198
+ RMT_VNEXT_ROUTE_COMPONENT_FIBER_SCENARIOS,
2199
+ RMT_VNEXT_SOURCE_TO_SEA_BROWSER_FIXTURE_PATH,
2200
+ RMT_VNEXT_SOURCE_TO_SEA_BROWSER_PROBE_SCHEMA,
2201
+ RMT_VNEXT_SOURCE_TO_SEA_BROWSER_RESULT_VALIDATION_SCHEMA,
2202
+ RMT_VNEXT_SOURCE_TO_SEA_CI_ARTIFACT_SCHEMA,
2203
+ RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_DRIVER,
2204
+ RMT_VNEXT_SOURCE_TO_SEA_CI_BROWSER_NAME,
2205
+ RMT_VNEXT_SOURCE_TO_SEA_CI_WEBDRIVER_PORT,
2206
+ RMT_VNEXT_SOURCE_TO_SEA_CLEANUP_DIAGNOSTIC_CODES,
2207
+ RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_SCHEMA,
2208
+ RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_PATH,
2209
+ RMT_VNEXT_SOURCE_TO_SEA_EVIDENCE_REPORT_SCHEMA,
2210
+ RMT_VNEXT_SOURCE_TO_SEA_FIXTURE_PATH,
2211
+ RMT_VNEXT_SOURCE_TO_SEA_MODULE_PATH,
2212
+ RMT_VNEXT_SOURCE_TO_SEA_OBJECT_MATRIX_SCHEMA,
2213
+ RMT_VNEXT_SOURCE_TO_SEA_RESULT_KEY,
2214
+ RMT_VNEXT_SOURCE_TO_SEA_SCHEMA,
2215
+ RMT_VNEXT_SOURCE_TO_SEA_SUITE_PATH,
2216
+ RMT_VNEXT_SOURCE_TO_SEA_SUPPORTED_BROWSER_DRIVERS,
2217
+ RMT_VNEXT_SOURCE_TO_SEA_WORKPACKAGE,
2218
+ createRmtVNextSourceToSeaCiArtifactValidation,
2219
+ createRmtVNextSourceToSeaBrowserResultValidation,
2220
+ validateRmtVNextSourceToSeaCiArtifactFile,
2221
+ createRmtVNextSourceToSeaEvidenceReport,
2222
+ createRmtVNextFabricBridgeEvidence,
2223
+ createRmtVNextSourceToSeaObjectMatrix,
2224
+ runRmtVNextSourceToSeaBrowserExecution,
2225
+ createRmtVNextSourceToSeaEvidence,
2226
+ writeRmtVNextSourceToSeaEvidenceReport
2227
+ };