symbiote-ui 0.3.0-alpha.4

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 (322) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +76 -0
  4. package/canvas/AutoLayout.js +731 -0
  5. package/canvas/Breadcrumb/Breadcrumb.css.js +75 -0
  6. package/canvas/Breadcrumb/Breadcrumb.js +96 -0
  7. package/canvas/Breadcrumb/Breadcrumb.tpl.js +7 -0
  8. package/canvas/CanvasConnectionRenderer.js +971 -0
  9. package/canvas/CanvasGraph/CanvasGraph.css.js +29 -0
  10. package/canvas/CanvasGraph/CanvasGraph.js +1697 -0
  11. package/canvas/CanvasGraph/CanvasGraphDrawState.js +280 -0
  12. package/canvas/CanvasGraph/CanvasGraphGeometry.js +194 -0
  13. package/canvas/CanvasViewport.js +550 -0
  14. package/canvas/ConnectionRenderer.js +1283 -0
  15. package/canvas/FlowSimulator.js +326 -0
  16. package/canvas/ForceLayout.js +226 -0
  17. package/canvas/ForceWorker.js +1303 -0
  18. package/canvas/FrameManager.js +223 -0
  19. package/canvas/GraphExplorerShell/GraphExplorerShell.css.js +136 -0
  20. package/canvas/GraphExplorerShell/GraphExplorerShell.js +129 -0
  21. package/canvas/GraphExplorerShell/GraphExplorerShell.tpl.js +12 -0
  22. package/canvas/GraphTabs/GraphTabs.css.js +101 -0
  23. package/canvas/GraphTabs/GraphTabs.js +189 -0
  24. package/canvas/GraphTabs/GraphTabs.tpl.js +12 -0
  25. package/canvas/LODManager.js +88 -0
  26. package/canvas/Minimap/Minimap.css.js +73 -0
  27. package/canvas/Minimap/Minimap.js +210 -0
  28. package/canvas/Minimap/Minimap.tpl.js +7 -0
  29. package/canvas/NodeCanvas/NodeCanvas.css.js +398 -0
  30. package/canvas/NodeCanvas/NodeCanvas.js +1499 -0
  31. package/canvas/NodeCanvas/NodeCanvas.tpl.js +22 -0
  32. package/canvas/NodeSearch/NodeSearch.css.js +97 -0
  33. package/canvas/NodeSearch/NodeSearch.js +140 -0
  34. package/canvas/NodeSearch/NodeSearch.tpl.js +25 -0
  35. package/canvas/NodeViewManager.js +748 -0
  36. package/canvas/PcbRouteDiagnostics.js +463 -0
  37. package/canvas/PcbRouter.js +1127 -0
  38. package/canvas/PinExpansion.js +134 -0
  39. package/canvas/PseudoConnection.js +84 -0
  40. package/canvas/SelectionSync.js +163 -0
  41. package/canvas/SubgraphManager.js +203 -0
  42. package/canvas/SubgraphRouter.js +452 -0
  43. package/canvas/ViewportActions.js +473 -0
  44. package/canvas/graph-explorer.js +339 -0
  45. package/canvas/graph-layout.js +148 -0
  46. package/canvas/graph-model.js +68 -0
  47. package/canvas/html-in-canvas.js +202 -0
  48. package/canvas/project-graph-builder.js +440 -0
  49. package/canvas/project-graph-model.js +183 -0
  50. package/chat/ChatComposer/ChatComposer.css.js +652 -0
  51. package/chat/ChatComposer/ChatComposer.js +304 -0
  52. package/chat/ChatList/ChatList.css.js +102 -0
  53. package/chat/ChatList/ChatList.js +99 -0
  54. package/chat/ChatList/ChatList.tpl.js +20 -0
  55. package/chat/ChatListItem/ChatListItem.css.js +117 -0
  56. package/chat/ChatListItem/ChatListItem.js +32 -0
  57. package/chat/ChatListItem/ChatListItem.tpl.js +17 -0
  58. package/chat/ChatMessageItem/ChatMessageItem.css.js +628 -0
  59. package/chat/ChatMessageItem/ChatMessageItem.js +156 -0
  60. package/chat/ChatSidebar/ChatSidebar.css.js +150 -0
  61. package/chat/ChatSidebar/ChatSidebar.js +230 -0
  62. package/chat/ChatSidebar/ChatSidebar.tpl.js +18 -0
  63. package/chat/ChatSidebar/constants.js +11 -0
  64. package/chat/ChatSidebarItem/ChatSidebarItem.css.js +445 -0
  65. package/chat/ChatSidebarItem/ChatSidebarItem.js +304 -0
  66. package/chat/ChatTranscript/ChatTranscript.css.js +90 -0
  67. package/chat/ChatTranscript/ChatTranscript.js +244 -0
  68. package/chat/chat-context.js +123 -0
  69. package/chat/message-model.js +156 -0
  70. package/cli.js +20 -0
  71. package/control/Button/Button.css.js +93 -0
  72. package/control/Button/Button.js +78 -0
  73. package/control/Button/Button.tpl.js +3 -0
  74. package/control/Field/Field.css.js +91 -0
  75. package/control/Field/Field.js +17 -0
  76. package/control/Field/Field.tpl.js +3 -0
  77. package/core/Connection.js +47 -0
  78. package/core/Editor.js +449 -0
  79. package/core/Frame.js +33 -0
  80. package/core/GraphMermaid.js +348 -0
  81. package/core/GraphText.js +228 -0
  82. package/core/Node.js +145 -0
  83. package/core/Portal.js +106 -0
  84. package/core/Socket.js +187 -0
  85. package/core/SubgraphNode.js +121 -0
  86. package/core/base-path.js +55 -0
  87. package/core/dom-utils.js +14 -0
  88. package/core/index.js +18 -0
  89. package/core/local-cache.js +26 -0
  90. package/core/state-sync.js +227 -0
  91. package/custom-elements.json +6380 -0
  92. package/discover.js +240 -0
  93. package/display/Badge/Badge.css.js +44 -0
  94. package/display/Badge/Badge.js +17 -0
  95. package/display/Badge/Badge.tpl.js +3 -0
  96. package/display/Banner/Banner.css.js +61 -0
  97. package/display/Banner/Banner.js +17 -0
  98. package/display/Banner/Banner.tpl.js +3 -0
  99. package/display/CodeBlock/CodeBlock.css.js +194 -0
  100. package/display/CodeBlock/CodeBlock.js +220 -0
  101. package/display/CodeBlock/CodeBlock.tpl.js +11 -0
  102. package/display/DataTable/DataTable.css.js +101 -0
  103. package/display/DataTable/DataTable.js +136 -0
  104. package/display/DataTable/DataTable.tpl.js +13 -0
  105. package/display/EmptyState/EmptyState.css.js +33 -0
  106. package/display/EmptyState/EmptyState.js +17 -0
  107. package/display/EmptyState/EmptyState.tpl.js +3 -0
  108. package/display/EventFeed/EventFeed.css.js +145 -0
  109. package/display/EventFeed/EventFeed.js +64 -0
  110. package/display/EventFeed/EventFeed.tpl.js +14 -0
  111. package/display/EventFeed/EventFeedItem.js +116 -0
  112. package/display/EventFeed/EventFeedItem.tpl.js +22 -0
  113. package/display/LoadingOverlay/LoadingOverlay.css.js +91 -0
  114. package/display/LoadingOverlay/LoadingOverlay.js +48 -0
  115. package/display/LoadingOverlay/LoadingOverlay.tpl.js +12 -0
  116. package/display/Metric/Metric.css.js +60 -0
  117. package/display/Metric/Metric.js +17 -0
  118. package/display/Metric/Metric.tpl.js +6 -0
  119. package/display/OutputGraphPreview/OutputGraphPreview.css.js +122 -0
  120. package/display/OutputGraphPreview/OutputGraphPreview.js +89 -0
  121. package/display/OutputGraphPreview/OutputGraphPreview.tpl.js +13 -0
  122. package/display/OutputListPreview/OutputListPreview.css.js +109 -0
  123. package/display/OutputListPreview/OutputListPreview.js +77 -0
  124. package/display/OutputListPreview/OutputListPreview.tpl.js +13 -0
  125. package/display/SourceEditor/SourceEditor.css.js +39 -0
  126. package/display/SourceEditor/SourceEditor.js +129 -0
  127. package/display/SourceEditor/SourceEditor.tpl.js +10 -0
  128. package/display/SourceViewer/SourceViewer.css.js +80 -0
  129. package/display/SourceViewer/SourceViewer.js +418 -0
  130. package/display/SourceViewer/SourceViewer.tpl.js +17 -0
  131. package/display/StatusRibbon/StatusRibbon.css.js +73 -0
  132. package/display/StatusRibbon/StatusRibbon.js +87 -0
  133. package/display/StatusRibbon/StatusRibbon.tpl.js +7 -0
  134. package/display/event-feed-adapter.js +72 -0
  135. package/display/format-utils.js +29 -0
  136. package/display/highlight.js +659 -0
  137. package/display/icons.js +37 -0
  138. package/display/markdown-formatter.js +60 -0
  139. package/display/network-approval-page.js +487 -0
  140. package/display/output-preview.js +261 -0
  141. package/effects/CellBg/CellBg.css.js +33 -0
  142. package/effects/CellBg/CellBg.js +410 -0
  143. package/effects/CellBg/CellBg.tpl.js +5 -0
  144. package/graph/canvas-adapter.js +223 -0
  145. package/graph/graph-algorithms.js +31 -0
  146. package/graph/index.js +46 -0
  147. package/graph/model.js +176 -0
  148. package/graph/project-graph-build.js +66 -0
  149. package/graph/project-graph-metadata.js +253 -0
  150. package/graph/project-package.js +128 -0
  151. package/graph/project-runtime.js +116 -0
  152. package/graph/project-transaction.js +284 -0
  153. package/graph/skeleton-utils.js +84 -0
  154. package/graph/theme-contract.js +36 -0
  155. package/graph/transaction-parser.js +56 -0
  156. package/icons/MaterialSymbols.js +69 -0
  157. package/icons/material-symbols-outlined-400.ttf +0 -0
  158. package/icons/material-symbols.css +24 -0
  159. package/index.js +95 -0
  160. package/inspector/InspectorPanel/InspectorPanel.css.js +375 -0
  161. package/inspector/InspectorPanel/InspectorPanel.js +368 -0
  162. package/inspector/InspectorPanel/InspectorPanel.tpl.js +96 -0
  163. package/inspector/TemplatePreview/TemplatePreview.css.js +104 -0
  164. package/inspector/TemplatePreview/TemplatePreview.js +145 -0
  165. package/inspector/TemplatePreview/TemplatePreview.tpl.js +33 -0
  166. package/interactions/ConnectFlow.js +304 -0
  167. package/interactions/Drag.js +104 -0
  168. package/interactions/Selector.js +133 -0
  169. package/interactions/SnapGrid.js +66 -0
  170. package/interactions/Zoom.js +139 -0
  171. package/layout/ActionZone/ActionZone.css.js +88 -0
  172. package/layout/ActionZone/ActionZone.js +261 -0
  173. package/layout/ActionZone/ActionZone.tpl.js +11 -0
  174. package/layout/CrossLayoutPortalBridge/CrossLayoutPortalBridge.js +255 -0
  175. package/layout/Layout/Layout.css.js +91 -0
  176. package/layout/Layout/Layout.js +637 -0
  177. package/layout/Layout/Layout.tpl.js +27 -0
  178. package/layout/LayoutNode/LayoutNode.css.js +302 -0
  179. package/layout/LayoutNode/LayoutNode.js +509 -0
  180. package/layout/LayoutNode/LayoutNode.tpl.js +39 -0
  181. package/layout/LayoutPreview/LayoutPreview.css.js +46 -0
  182. package/layout/LayoutPreview/LayoutPreview.js +102 -0
  183. package/layout/LayoutPreview/LayoutPreview.tpl.js +6 -0
  184. package/layout/LayoutRouter/LayoutRouter.js +274 -0
  185. package/layout/LayoutRouter/SectionRegistry.js +135 -0
  186. package/layout/LayoutRouter/routerSync.js +250 -0
  187. package/layout/LayoutSidebar/LayoutSidebar.css.js +411 -0
  188. package/layout/LayoutSidebar/LayoutSidebar.js +368 -0
  189. package/layout/LayoutSidebar/LayoutSidebar.tpl.js +26 -0
  190. package/layout/LayoutSidebar/SidebarSection.css.js +20 -0
  191. package/layout/LayoutSidebar/SidebarSection.js +184 -0
  192. package/layout/LayoutSidebar/SidebarSection.tpl.js +22 -0
  193. package/layout/LayoutTree.js +373 -0
  194. package/layout/PanelMenu/PanelMenu.css.js +43 -0
  195. package/layout/PanelMenu/PanelMenu.js +95 -0
  196. package/layout/PanelMenu/PanelMenu.tpl.js +17 -0
  197. package/layout/ProjectTabs/ProjectTabs.css.js +188 -0
  198. package/layout/ProjectTabs/ProjectTabs.js +77 -0
  199. package/layout/ProjectTabs/ProjectTabs.tpl.js +15 -0
  200. package/layout/index.js +40 -0
  201. package/list/ListDetailShell/ListDetailShell.css.js +128 -0
  202. package/list/ListDetailShell/ListDetailShell.js +72 -0
  203. package/list/ListDetailShell/ListDetailShell.tpl.js +36 -0
  204. package/list/ListItem/ListItem.css.js +111 -0
  205. package/list/ListItem/ListItem.js +66 -0
  206. package/list/ListItem/ListItem.tpl.js +18 -0
  207. package/locale/index.js +503 -0
  208. package/manifest/component-registry.js +2446 -0
  209. package/manifest/graph-schema.js +285 -0
  210. package/manifest/index.js +6 -0
  211. package/manifest/project-schema-catalog.js +246 -0
  212. package/manifest/rule-catalog.js +201 -0
  213. package/manifest/theme-catalog.js +2149 -0
  214. package/manifest/ui-schema-catalog.js +334 -0
  215. package/menu/ContextMenu/ContextMenu.css.js +61 -0
  216. package/menu/ContextMenu/ContextMenu.js +82 -0
  217. package/menu/ContextMenu/ContextMenu.tpl.js +19 -0
  218. package/navigation/QuickOpen/QuickOpen.css.js +92 -0
  219. package/navigation/QuickOpen/QuickOpen.js +185 -0
  220. package/navigation/QuickOpen/QuickOpen.tpl.js +15 -0
  221. package/navigation/quick-open-utils.js +101 -0
  222. package/node/CtrlItem/CtrlItem.css.js +41 -0
  223. package/node/CtrlItem/CtrlItem.js +24 -0
  224. package/node/CtrlItem/CtrlItem.tpl.js +17 -0
  225. package/node/GraphFrame/GraphFrame.css.js +66 -0
  226. package/node/GraphFrame/GraphFrame.js +32 -0
  227. package/node/GraphFrame/GraphFrame.tpl.js +13 -0
  228. package/node/GraphNode/GraphNode.css.js +815 -0
  229. package/node/GraphNode/GraphNode.js +173 -0
  230. package/node/GraphNode/GraphNode.tpl.js +33 -0
  231. package/node/NodeCallout/NodeCallout.css.js +91 -0
  232. package/node/NodeCallout/NodeCallout.js +281 -0
  233. package/node/NodeCallout/NodeCallout.tpl.js +8 -0
  234. package/node/NodeSocket/NodeSocket.css.js +68 -0
  235. package/node/NodeSocket/NodeSocket.js +26 -0
  236. package/node/NodeSocket/NodeSocket.tpl.js +7 -0
  237. package/node/PortItem/PortItem.css.js +93 -0
  238. package/node/PortItem/PortItem.js +87 -0
  239. package/node/PortItem/PortItem.tpl.js +10 -0
  240. package/package.json +165 -0
  241. package/palette/PaletteBrowser/PaletteBrowser.css.js +143 -0
  242. package/palette/PaletteBrowser/PaletteBrowser.js +152 -0
  243. package/palette/PaletteBrowser/PaletteBrowser.tpl.js +23 -0
  244. package/plugins/History.js +408 -0
  245. package/plugins/Readonly.js +60 -0
  246. package/rules/symbiote-3x.json +170 -0
  247. package/schemas/component-descriptor-v1.json +91 -0
  248. package/schemas/component-descriptor-v2.json +145 -0
  249. package/schemas/graph-model-v1.json +179 -0
  250. package/schemas/graph-v1.json +91 -0
  251. package/schemas/project-package-v1.json +102 -0
  252. package/schemas/project-transaction-v1.json +114 -0
  253. package/schemas/runtime-ui-v1.json +80 -0
  254. package/schemas/theme-rule-block-v1.json +73 -0
  255. package/shapes/CircleShape.js +79 -0
  256. package/shapes/CommentShape.js +35 -0
  257. package/shapes/DiamondShape.js +130 -0
  258. package/shapes/NodeShape.js +79 -0
  259. package/shapes/PillShape.js +91 -0
  260. package/shapes/RectShape.js +84 -0
  261. package/shapes/SVGShape.js +525 -0
  262. package/shapes/index.js +63 -0
  263. package/surface/Card/Card.css.js +57 -0
  264. package/surface/Card/Card.js +17 -0
  265. package/surface/Card/Card.tpl.js +3 -0
  266. package/themes/Palette.js +30 -0
  267. package/themes/Skin.js +113 -0
  268. package/themes/Theme.js +82 -0
  269. package/themes/carbon.js +135 -0
  270. package/themes/dark.js +140 -0
  271. package/themes/default-dark.js +714 -0
  272. package/themes/default-provider.css +635 -0
  273. package/themes/default-provider.js +718 -0
  274. package/themes/ebook.js +136 -0
  275. package/themes/grey.js +137 -0
  276. package/themes/light.js +139 -0
  277. package/themes/neon.js +138 -0
  278. package/themes/pcb.js +273 -0
  279. package/themes/synthwave.js +138 -0
  280. package/tokens/base.json +29 -0
  281. package/tokens/themes/carbon.json +11 -0
  282. package/tokens/themes/dark.json +12 -0
  283. package/tokens/themes/default-dark.json +1543 -0
  284. package/tokens/themes/default-provider.json +1543 -0
  285. package/tokens/themes/ebook.json +11 -0
  286. package/tokens/themes/grey.json +11 -0
  287. package/tokens/themes/light.json +12 -0
  288. package/tokens/themes/neon.json +11 -0
  289. package/tokens/themes/pcb.json +11 -0
  290. package/tokens/themes/synthwave.json +11 -0
  291. package/toolbar/QuickToolbar/QuickToolbar.css.js +152 -0
  292. package/toolbar/QuickToolbar/QuickToolbar.js +529 -0
  293. package/toolbar/QuickToolbar/QuickToolbar.tpl.js +34 -0
  294. package/tree/TreePanel/TreePanel.css.js +112 -0
  295. package/tree/TreePanel/TreePanel.js +147 -0
  296. package/tree/TreePanel/TreePanel.tpl.js +18 -0
  297. package/tree/TreeView/TreeView.css.js +122 -0
  298. package/tree/TreeView/TreeView.js +365 -0
  299. package/tree/TreeView/TreeView.tpl.js +10 -0
  300. package/ui/dialogs.js +221 -0
  301. package/ui/host-adapters.js +114 -0
  302. package/ui/index.js +660 -0
  303. package/ui/locale.js +50 -0
  304. package/ui/overlay-stack.js +89 -0
  305. package/ui/shared-styles.js +26 -0
  306. package/webmcp.js +37 -0
  307. package/xr/deep-graph.js +646 -0
  308. package/xr/emulation.js +198 -0
  309. package/xr/gesture.js +228 -0
  310. package/xr/html-canvas-renderer.js +472 -0
  311. package/xr/index.js +15 -0
  312. package/xr/layout-projection.js +1046 -0
  313. package/xr/panel-frame.js +128 -0
  314. package/xr/panel-host.js +267 -0
  315. package/xr/pointer.js +258 -0
  316. package/xr/scene-controller.js +242 -0
  317. package/xr/spatial-scene.js +212 -0
  318. package/xr/theme-bridge.js +105 -0
  319. package/xr/three-webxr-adapter.js +3439 -0
  320. package/xr/webgl-layer-renderer.js +419 -0
  321. package/xr/webxr.js +679 -0
  322. package/xr/workbench.js +516 -0
@@ -0,0 +1,472 @@
1
+ import {
2
+ createHtmlInCanvasAdapter,
3
+ } from '../canvas/html-in-canvas.js';
4
+
5
+ const MODE_PRIORITY = Object.freeze(['webgl', 'webgpu', 'canvas2d']);
6
+ export const HTML_IN_CANVAS_ORIGIN_TRIAL_HEADER = 'Origin-Trial';
7
+
8
+ function selectMode(support, requestedMode) {
9
+ if (requestedMode && support.modes?.[requestedMode]) return requestedMode;
10
+ return MODE_PRIORITY.find((mode) => support.modes?.[mode]) || null;
11
+ }
12
+
13
+ function targetForMode(target, mode) {
14
+ if (!target) return null;
15
+ if (mode === 'webgl') return target.gl || target.webgl || target;
16
+ if (mode === 'webgpu') return target.queue || target.webgpuQueue || target;
17
+ return target.ctx || target.context || target;
18
+ }
19
+
20
+ function getCanvas2dContext(canvas) {
21
+ return canvas?.getContext?.('2d') || null;
22
+ }
23
+
24
+ function isDirectCanvasChild(canvas, element) {
25
+ if (!canvas || !element) return false;
26
+ return element.parentElement === canvas || element.parentNode === canvas;
27
+ }
28
+
29
+ function createOriginTrialSummary(options = {}) {
30
+ return {
31
+ name: 'html-in-canvas',
32
+ status: options.originTrialStatus || 'origin-trial',
33
+ chromeMilestoneRange: options.chromeMilestoneRange || '148-150',
34
+ localTestBrowser: options.localTestBrowser || 'Chrome Canary 149+',
35
+ requiredFlag: options.requiredFlag || 'CanvasDrawElement',
36
+ flagUrl: options.flagUrl || 'chrome://flags/#canvas-draw-element',
37
+ source: options.source || 'https://developer.chrome.com/blog/html-in-canvas-origin-trial',
38
+ };
39
+ }
40
+
41
+ export function createXRHtmlCanvasEnablementSummary(root = globalThis, options = {}) {
42
+ let document = root?.document || root;
43
+ let metas = [];
44
+ if (document?.querySelectorAll) {
45
+ metas = [...document.querySelectorAll('meta')].filter((meta) =>
46
+ String(meta.getAttribute?.('http-equiv') || '').toLowerCase() === 'origin-trial');
47
+ }
48
+ let originTrialMetaCount = metas.length;
49
+ let originTrialMetaPresent = originTrialMetaCount > 0;
50
+ let originTrialTokenPresent = options.originTrialTokenPresent;
51
+ if (originTrialTokenPresent == null) {
52
+ originTrialTokenPresent = metas.some((meta) => String(meta.getAttribute?.('content') || '').trim().length > 0);
53
+ }
54
+
55
+ return {
56
+ version: 'xr-html-in-canvas-enablement-v1',
57
+ secureContext: root?.isSecureContext !== false,
58
+ originTrialMetaPresent,
59
+ originTrialMetaCount,
60
+ originTrialTokenPresent: Boolean(originTrialTokenPresent),
61
+ originTrialConfigured: Boolean(originTrialTokenPresent),
62
+ requiredFlag: options.requiredFlag || 'CanvasDrawElement',
63
+ flagUrl: options.flagUrl || 'chrome://flags/#canvas-draw-element',
64
+ source: options.source || 'https://developer.chrome.com/blog/html-in-canvas-origin-trial',
65
+ };
66
+ }
67
+
68
+ export function createXRHtmlCanvasDiagnostics(support = {}, options = {}) {
69
+ let apis = support.apis || {};
70
+ let modes = support.modes || {};
71
+ let requiredFlag = options.requiredFlag || 'CanvasDrawElement';
72
+ let enablement = options.enablement || support.enablement || createXRHtmlCanvasEnablementSummary(null, options);
73
+ let renderTargetAvailable = Boolean(modes.canvas2d || modes.offscreen2d || modes.webgl || modes.webgpu);
74
+ let textureUploadAvailable = Boolean(modes.webgl || modes.webgpu);
75
+ let blockingMissing = [];
76
+ let missing = [];
77
+ if (!apis.layoutSubtreeAvailable) missing.push('layoutsubtree');
78
+ if (!renderTargetAvailable) missing.push('render-target-api');
79
+ if (!apis.requestPaintAvailable) missing.push('requestPaint');
80
+ if (!apis.canvas2dDrawAvailable) missing.push('drawElementImage');
81
+ if (!modes.webgl) missing.push('texElementImage2D');
82
+ if (!modes.webgpu) missing.push('copyElementImageToTexture');
83
+ if (!apis.layoutSubtreeAvailable) blockingMissing.push('layoutsubtree');
84
+ if (!renderTargetAvailable) blockingMissing.push('render-target-api');
85
+
86
+ let supported = Boolean(support.supported && !blockingMissing.length);
87
+ let availability = supported
88
+ ? textureUploadAvailable ? 'texture-ready' : 'canvas-ready'
89
+ : renderTargetAvailable ? 'missing-layout-subtree'
90
+ : enablement.originTrialTokenPresent ? 'origin-trial-token-present-api-missing'
91
+ : 'origin-trial-or-flag-required';
92
+
93
+ return {
94
+ name: 'xr-html-in-canvas-diagnostics',
95
+ supported,
96
+ availability,
97
+ mode: support.preferredMode || null,
98
+ fallback: support.fallback || 'dom-overlay',
99
+ requiredFlag,
100
+ originTrial: createOriginTrialSummary({ ...options, requiredFlag }),
101
+ enablement,
102
+ renderTargetAvailable,
103
+ textureUploadAvailable,
104
+ apis: {
105
+ layoutsubtree: Boolean(apis.layoutSubtreeAvailable),
106
+ drawElementImage: Boolean(apis.canvas2dDrawAvailable),
107
+ paintEvent: Boolean(apis.requestPaintAvailable),
108
+ webglTextureUpload: Boolean(modes.webgl),
109
+ webgpuTextureCopy: Boolean(modes.webgpu),
110
+ elementTransform: Boolean(apis.elementTransformAvailable),
111
+ },
112
+ missing,
113
+ blockingMissing,
114
+ optionalMissing: missing.filter((item) => !blockingMissing.includes(item)),
115
+ missingCore: blockingMissing,
116
+ missingTexture: missing.filter((item) => item === 'texElementImage2D' || item === 'copyElementImageToTexture'),
117
+ recommendation: blockingMissing.length ? `enable-${requiredFlag}` : 'use-html-in-canvas',
118
+ };
119
+ }
120
+
121
+ export function createXRHtmlCanvasHeaderDiagnostics(response = null, options = {}) {
122
+ let originTrialHeader = options.originTrialHeader || HTML_IN_CANVAS_ORIGIN_TRIAL_HEADER;
123
+ let diagnosticHeaderName = options.diagnosticHeader || options.diagnosticHeaderName || null;
124
+ let headers = response?.headers || null;
125
+ let ok = response?.ok;
126
+ let status = response?.status;
127
+ let originTrialPresent = Boolean(headers?.has?.(originTrialHeader));
128
+ let diagnosticHeader = diagnosticHeaderName ? headers?.get?.(diagnosticHeaderName) || null : null;
129
+ let error = null;
130
+ if (ok === false) {
131
+ error = `status-${status}`;
132
+ }
133
+
134
+ return {
135
+ version: 'xr-html-in-canvas-header-diagnostics-v1',
136
+ checked: true,
137
+ originTrialHeader,
138
+ originTrialPresent,
139
+ present: originTrialPresent,
140
+ diagnosticHeaderName,
141
+ diagnosticHeader,
142
+ status: Number.isFinite(Number(status)) ? Number(status) : null,
143
+ ok: ok == null ? null : Boolean(ok),
144
+ error,
145
+ };
146
+ }
147
+
148
+ function resolveHeaderProbeUrl(urlSource, options = {}) {
149
+ let baseUrl = options.baseUrl || options.location?.href || globalThis?.location?.href || 'http://localhost/';
150
+ if (typeof urlSource === 'string') {
151
+ return new URL(urlSource, baseUrl);
152
+ }
153
+ if (urlSource?.href) {
154
+ return new URL(urlSource.href, baseUrl);
155
+ }
156
+ let pathname = urlSource?.pathname || options.location?.pathname || globalThis?.location?.pathname || '/';
157
+ let search = urlSource?.search || options.location?.search || globalThis?.location?.search || '';
158
+ return new URL(`${pathname}${search}`, baseUrl);
159
+ }
160
+
161
+ export async function readXRHtmlCanvasOriginTrialHeaderStatus(urlSource = null, options = {}) {
162
+ let fetchImpl = options.fetch || globalThis?.fetch;
163
+ if (typeof fetchImpl !== 'function') {
164
+ return {
165
+ version: 'xr-html-in-canvas-header-diagnostics-v1',
166
+ checked: true,
167
+ originTrialHeader: options.originTrialHeader || HTML_IN_CANVAS_ORIGIN_TRIAL_HEADER,
168
+ originTrialPresent: false,
169
+ present: false,
170
+ diagnosticHeaderName: options.diagnosticHeader || options.diagnosticHeaderName || null,
171
+ diagnosticHeader: null,
172
+ status: null,
173
+ ok: null,
174
+ error: 'fetch-unavailable',
175
+ };
176
+ }
177
+
178
+ try {
179
+ let url = resolveHeaderProbeUrl(urlSource, options);
180
+ let response = await fetchImpl(`${url.pathname}${url.search}`, {
181
+ method: 'HEAD',
182
+ cache: 'no-store',
183
+ });
184
+ return createXRHtmlCanvasHeaderDiagnostics(response, options);
185
+ } catch (error) {
186
+ return {
187
+ version: 'xr-html-in-canvas-header-diagnostics-v1',
188
+ checked: true,
189
+ originTrialHeader: options.originTrialHeader || HTML_IN_CANVAS_ORIGIN_TRIAL_HEADER,
190
+ originTrialPresent: false,
191
+ present: false,
192
+ diagnosticHeaderName: options.diagnosticHeader || options.diagnosticHeaderName || null,
193
+ diagnosticHeader: null,
194
+ status: null,
195
+ ok: false,
196
+ error: error?.message || 'origin-trial-header-check-failed',
197
+ };
198
+ }
199
+ }
200
+
201
+ export function createXRPanelTextureSourceSummary(panel = {}, prepareResult = {}, support = {}, options = {}) {
202
+ let diagnostics = support.diagnostics || createXRHtmlCanvasDiagnostics(support, options);
203
+ let requestedMode = prepareResult.mode || support.preferredMode || diagnostics.mode || null;
204
+ let prepared = prepareResult.prepared === true;
205
+ let supported = prepareResult.supported === true || Boolean(prepared && requestedMode && requestedMode !== 'unsupported');
206
+ let reason = prepareResult.reason || (supported ? null : diagnostics.recommendation || 'html-in-canvas-unsupported');
207
+ let source = 'unsupported';
208
+ if (supported) {
209
+ source = 'html-in-canvas';
210
+ } else if (options.allowMaterialFallback !== false) {
211
+ source = 'provider-material-fallback';
212
+ }
213
+ return {
214
+ version: 'xr-panel-texture-source-v1',
215
+ panelId: panel.id || null,
216
+ source,
217
+ mode: requestedMode || 'unsupported',
218
+ prepared,
219
+ supported,
220
+ reason,
221
+ fallback: source !== 'html-in-canvas',
222
+ strict: options.allowMaterialFallback === false,
223
+ missing: diagnostics.missing || [],
224
+ blockingMissing: diagnostics.blockingMissing || [],
225
+ };
226
+ }
227
+
228
+ function normalizeTextureBridgeRecord(record = {}) {
229
+ let source = record.summary?.source || record.source || null;
230
+ let ok = record.ok === true && source === 'html-in-canvas';
231
+ return {
232
+ panelId: record.panelId || record.summary?.panelId || null,
233
+ stage: record.stage || (ok ? 'three-material-applied' : 'html-in-canvas-support'),
234
+ source,
235
+ mode: record.summary?.mode || null,
236
+ ok,
237
+ reason: record.reason || record.summary?.reason || null,
238
+ textureApplied: record.textureApplied === true,
239
+ support: record.support || null,
240
+ };
241
+ }
242
+
243
+ function normalizeTextureResolverRecord(record = {}) {
244
+ return {
245
+ panelId: record.panelId || null,
246
+ stage: record.stage || null,
247
+ ok: record.ok === true,
248
+ reason: record.reason || null,
249
+ textureApplied: record.textureApplied === true,
250
+ width: Number.isFinite(Number(record.width)) ? Number(record.width) : null,
251
+ height: Number.isFinite(Number(record.height)) ? Number(record.height) : null,
252
+ mode: record.mode || null,
253
+ };
254
+ }
255
+
256
+ function textureRequiredApi(diagnostics = {}, record = null) {
257
+ let blockingMissing = record?.support?.blockingMissing || diagnostics.blockingMissing;
258
+ if (Array.isArray(blockingMissing) && blockingMissing.length) return [...blockingMissing];
259
+ let recommendation = record?.support?.recommendation || diagnostics.recommendation;
260
+ return recommendation ? [recommendation] : [];
261
+ }
262
+
263
+ export function createXRTextureDebugModeSummary(options = {}) {
264
+ let requested = String(options.requestedMode || options.texture || options.mode || '').trim().toLowerCase();
265
+ let defaultMode = String(options.defaultMode || 'strict').trim().toLowerCase();
266
+ let mode = requested || defaultMode;
267
+ if (mode === '1' || mode === 'true' || mode === 'required') mode = 'strict';
268
+ if (mode === '0' || mode === 'false' || mode === 'visible' || mode === 'material') mode = 'fallback';
269
+ if (mode !== 'strict' && mode !== 'fallback') mode = defaultMode === 'fallback' ? 'fallback' : 'strict';
270
+ let strict = mode === 'strict';
271
+
272
+ return {
273
+ version: 'xr-texture-debug-mode-v1',
274
+ mode,
275
+ strict,
276
+ requireTextureUpload: strict,
277
+ hideStrictTextureFailures: strict,
278
+ allowMaterialFallback: !strict,
279
+ queryValue: strict ? 'strict' : 'fallback',
280
+ label: strict ? 'strict texture validation' : 'material fallback visible',
281
+ reason: strict ? 'validate-live-html-textures' : 'inspect-world-space-layout-without-live-textures',
282
+ };
283
+ }
284
+
285
+ export function createXRTextureGateSummary(options = {}) {
286
+ let records = Array.isArray(options.records) ? options.records.map(normalizeTextureBridgeRecord) : [];
287
+ let resolverState = options.resolverState || null;
288
+ let resolverRecords = Array.isArray(options.resolverRecords)
289
+ ? options.resolverRecords.map(normalizeTextureResolverRecord)
290
+ : Array.isArray(resolverState?.records) ? resolverState.records.map(normalizeTextureResolverRecord) : [];
291
+ let support = options.support || {};
292
+ let diagnostics = support.diagnostics || createXRHtmlCanvasDiagnostics(support, options);
293
+ let debugMode = options.debugMode ? createXRTextureDebugModeSummary(options.debugMode) : null;
294
+ let strict = options.strict == null ? debugMode?.strict === true : options.strict === true;
295
+ let total = records.length || Math.max(0, Number(options.panelCount) || 0);
296
+ let ready = records.length
297
+ ? records.filter((record) => record.ok).length
298
+ : diagnostics.supported === true ? total : 0;
299
+ let firstBlockingRecord = records.find((record) => !record.ok) || null;
300
+ let blocked = strict && total > 0 && ready !== total;
301
+ let reason = blocked
302
+ ? firstBlockingRecord?.reason || options.reason || (diagnostics.supported ? 'html-in-canvas-required' : 'html-in-canvas-unsupported')
303
+ : null;
304
+ let stage = firstBlockingRecord?.stage || (diagnostics.supported ? 'html-in-canvas-ready' : 'html-in-canvas-support');
305
+
306
+ return {
307
+ version: 'xr-texture-gate-summary-v1',
308
+ strict,
309
+ debugMode,
310
+ total,
311
+ ready,
312
+ blocked,
313
+ reason,
314
+ stage,
315
+ requiredApi: textureRequiredApi(diagnostics, firstBlockingRecord),
316
+ bridgeVersion: options.bridgeVersion || null,
317
+ bridgeStages: records,
318
+ resolverVersion: options.resolverVersion || resolverState?.version || null,
319
+ resolverTextures: Number.isFinite(Number(options.resolverTextures ?? resolverState?.textureCount))
320
+ ? Number(options.resolverTextures ?? resolverState?.textureCount)
321
+ : resolverRecords.filter((record) => record.textureApplied).length,
322
+ resolverStages: resolverRecords,
323
+ };
324
+ }
325
+
326
+ export function createXRHtmlCanvasRenderer(options = {}) {
327
+ let adapter = createHtmlInCanvasAdapter({ globalThis: options.globalThis || globalThis });
328
+ let panels = new Map();
329
+ let lastMode = selectMode(adapter.support, options.mode);
330
+ let lastRender = null;
331
+
332
+ function getSupport() {
333
+ let enablement = createXRHtmlCanvasEnablementSummary(options.globalThis || globalThis, options);
334
+ let support = {
335
+ ...adapter.support,
336
+ preferredMode: selectMode(adapter.support, options.mode),
337
+ enablement,
338
+ };
339
+ return {
340
+ ...support,
341
+ diagnostics: createXRHtmlCanvasDiagnostics(support, { ...options, enablement }),
342
+ };
343
+ }
344
+
345
+ function getState() {
346
+ return {
347
+ supported: adapter.support.supported,
348
+ preferredMode: lastMode,
349
+ prepared: panels.size,
350
+ panelIds: [...panels.keys()],
351
+ lastRender,
352
+ };
353
+ }
354
+
355
+ function preparePanel(panelElement, panel, prepareOptions = {}) {
356
+ if (!panelElement || !panel?.id) {
357
+ return { prepared: false, reason: 'missing-panel-element' };
358
+ }
359
+ let mode = selectMode(adapter.support, prepareOptions.mode || options.mode);
360
+ if (mode && prepareOptions.canvas && !isDirectCanvasChild(prepareOptions.canvas, panelElement)) {
361
+ return {
362
+ prepared: false,
363
+ panelId: panel.id,
364
+ mode,
365
+ supported: false,
366
+ reason: 'panel-outside-canvas-direct-child',
367
+ };
368
+ }
369
+ panels.set(panel.id, {
370
+ panel,
371
+ element: panelElement,
372
+ mode,
373
+ canvas: prepareOptions.canvas || null,
374
+ });
375
+ lastMode = mode;
376
+ if (prepareOptions.canvas) {
377
+ adapter.setupCanvas(prepareOptions.canvas);
378
+ adapter.requestPaint(prepareOptions.canvas);
379
+ }
380
+ return {
381
+ prepared: true,
382
+ panelId: panel.id,
383
+ mode: mode || 'unsupported',
384
+ supported: Boolean(mode),
385
+ reason: mode ? null : 'html-in-canvas-unsupported',
386
+ canvas: prepareOptions.canvas || null,
387
+ };
388
+ }
389
+
390
+ function renderPanel(panelId, target, renderOptions = {}) {
391
+ let record = panels.get(panelId);
392
+ if (!record) {
393
+ return { rendered: false, reason: 'panel-not-prepared' };
394
+ }
395
+ let mode = selectMode(adapter.support, renderOptions.mode || record.mode || options.mode);
396
+ if (!mode) {
397
+ return { rendered: false, mode: 'unsupported', reason: 'html-in-canvas-unsupported' };
398
+ }
399
+
400
+ let targetHandle = targetForMode(target, mode);
401
+ if (!targetHandle) {
402
+ return { rendered: false, mode, reason: 'missing-render-target' };
403
+ }
404
+
405
+ lastMode = mode;
406
+ let result = null;
407
+ if (mode === 'webgl') {
408
+ result = adapter.uploadWebGLTexture(targetHandle, record.element, renderOptions);
409
+ } else if (mode === 'webgpu') {
410
+ result = adapter.copyWebGPUTexture(targetHandle, record.element, renderOptions);
411
+ } else {
412
+ result = adapter.draw2d(targetHandle, record.element, renderOptions);
413
+ }
414
+ lastRender = { panelId, ...result };
415
+ return result;
416
+ }
417
+
418
+ function renderPanelPreview(panelId, canvas, renderOptions = {}) {
419
+ let record = panels.get(panelId);
420
+ if (!record) {
421
+ return { rendered: false, mode: 'canvas2d', reason: 'panel-not-prepared' };
422
+ }
423
+ if (!adapter.support.modes.canvas2d) {
424
+ return { rendered: false, mode: 'canvas2d', reason: 'html-in-canvas-unsupported' };
425
+ }
426
+ let ctx = getCanvas2dContext(canvas);
427
+ if (!ctx) {
428
+ return { rendered: false, mode: 'canvas2d', reason: 'missing-canvas2d-context' };
429
+ }
430
+ if (!isDirectCanvasChild(canvas, record.element)) {
431
+ return {
432
+ rendered: false,
433
+ mode: 'canvas2d',
434
+ reason: 'panel-outside-canvas-direct-child',
435
+ panelId,
436
+ };
437
+ }
438
+ adapter.setupCanvas(canvas);
439
+ let result = null;
440
+ try {
441
+ result = adapter.draw2d(ctx, record.element, {
442
+ syncTransform: false,
443
+ ...renderOptions,
444
+ x: renderOptions.x ?? 0,
445
+ y: renderOptions.y ?? 0,
446
+ });
447
+ } catch (error) {
448
+ result = {
449
+ rendered: false,
450
+ mode: 'canvas2d',
451
+ reason: error?.name || 'html-canvas-preview-render-failed',
452
+ message: error?.message || '',
453
+ };
454
+ }
455
+ adapter.requestPaint(canvas);
456
+ lastMode = 'canvas2d';
457
+ lastRender = {
458
+ panelId,
459
+ preview: true,
460
+ ...result,
461
+ };
462
+ return lastRender;
463
+ }
464
+
465
+ return {
466
+ preparePanel,
467
+ renderPanel,
468
+ renderPanelPreview,
469
+ getSupport,
470
+ getState,
471
+ };
472
+ }
package/xr/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export * from './webxr.js';
2
+ export * from './layout-projection.js';
3
+ export * from './pointer.js';
4
+ export * from './spatial-scene.js';
5
+ export * from './theme-bridge.js';
6
+ export * from './scene-controller.js';
7
+ export * from './panel-host.js';
8
+ export * from './html-canvas-renderer.js';
9
+ export * from './webgl-layer-renderer.js';
10
+ export * from './three-webxr-adapter.js';
11
+ export * from './gesture.js';
12
+ export * from './emulation.js';
13
+ export * from './deep-graph.js';
14
+ export * from './workbench.js';
15
+ export * from './panel-frame.js';