@yahoo/uds-create-config 2.45.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/README.md +129 -0
  2. package/dist/ai-lanes.d.ts +23 -0
  3. package/dist/ai-lanes.js +34 -0
  4. package/dist/authoring/define-component.d.ts +85 -0
  5. package/dist/configs/CanvasConfig.d.ts +3237 -0
  6. package/dist/configs/CanvasConfig.js +332 -0
  7. package/dist/configs/build-options.d.ts +10 -0
  8. package/dist/configs/build-options.js +68 -0
  9. package/dist/configs/platform.d.ts +15 -0
  10. package/dist/configs/platform.js +17 -0
  11. package/dist/configs/react-native-system.d.ts +3026 -0
  12. package/dist/configs/react-native-system.js +64 -0
  13. package/dist/configs/system.d.ts +2771 -0
  14. package/dist/configs/system.js +74 -0
  15. package/dist/css/properties.generated.d.ts +14 -0
  16. package/dist/css/properties.generated.js +6260 -0
  17. package/dist/css/value-type.d.ts +48 -0
  18. package/dist/css/value-type.js +131 -0
  19. package/dist/css/values.d.ts +33 -0
  20. package/dist/css/values.js +116 -0
  21. package/dist/entities/native/NativeModifier.d.ts +25 -0
  22. package/dist/entities/native/NativeModifier.js +41 -0
  23. package/dist/entities/native/NativeSettings.d.ts +44 -0
  24. package/dist/entities/native/NativeSettings.js +39 -0
  25. package/dist/entities/native/NativeStyleProperty.d.ts +355 -0
  26. package/dist/entities/native/NativeStyleProperty.js +28 -0
  27. package/dist/entities/native/NativeToken.d.ts +31 -0
  28. package/dist/entities/native/NativeToken.js +49 -0
  29. package/dist/entities/system/CanvasRole.d.ts +34 -0
  30. package/dist/entities/system/CanvasRole.js +45 -0
  31. package/dist/entities/system/Component.d.ts +1287 -0
  32. package/dist/entities/system/Component.js +1840 -0
  33. package/dist/entities/system/Composite.d.ts +12 -0
  34. package/dist/entities/system/Composite.js +26 -0
  35. package/dist/entities/system/Device.d.ts +11 -0
  36. package/dist/entities/system/Device.js +18 -0
  37. package/dist/entities/system/File.d.ts +72 -0
  38. package/dist/entities/system/File.js +136 -0
  39. package/dist/entities/system/Font.d.ts +48 -0
  40. package/dist/entities/system/Font.js +56 -0
  41. package/dist/entities/system/GlobalStyle.d.ts +26 -0
  42. package/dist/entities/system/GlobalStyle.js +54 -0
  43. package/dist/entities/system/Guidance.d.ts +85 -0
  44. package/dist/entities/system/Guidance.js +59 -0
  45. package/dist/entities/system/GuidanceStyle.d.ts +14 -0
  46. package/dist/entities/system/GuidanceStyle.js +8 -0
  47. package/dist/entities/system/Icon.d.ts +46 -0
  48. package/dist/entities/system/Icon.js +46 -0
  49. package/dist/entities/system/LinkedSystem.d.ts +504 -0
  50. package/dist/entities/system/LinkedSystem.js +814 -0
  51. package/dist/entities/system/Modifier.d.ts +92 -0
  52. package/dist/entities/system/Modifier.js +120 -0
  53. package/dist/entities/system/Motion.d.ts +28 -0
  54. package/dist/entities/system/Motion.js +48 -0
  55. package/dist/entities/system/Operation.d.ts +100 -0
  56. package/dist/entities/system/Operation.js +236 -0
  57. package/dist/entities/system/Package.d.ts +42 -0
  58. package/dist/entities/system/Package.js +75 -0
  59. package/dist/entities/system/Settings.d.ts +94 -0
  60. package/dist/entities/system/Settings.js +166 -0
  61. package/dist/entities/system/StyleProperty.d.ts +135 -0
  62. package/dist/entities/system/StyleProperty.js +438 -0
  63. package/dist/entities/system/Token.d.ts +67 -0
  64. package/dist/entities/system/Token.js +129 -0
  65. package/dist/entities/system/Tool.d.ts +134 -0
  66. package/dist/entities/system/Tool.js +124 -0
  67. package/dist/entities/system/color.d.ts +64 -0
  68. package/dist/entities/system/color.js +123 -0
  69. package/dist/entities/system/component-module.d.ts +63 -0
  70. package/dist/entities/system/component-module.js +258 -0
  71. package/dist/entities/system/copy-plan.d.ts +98 -0
  72. package/dist/entities/system/copy-plan.js +451 -0
  73. package/dist/entities/system/defineComponent.d.ts +428 -0
  74. package/dist/entities/system/defineComponent.js +337 -0
  75. package/dist/entities/system/element.d.ts +101 -0
  76. package/dist/entities/system/element.js +171 -0
  77. package/dist/entities/system/icon-library.d.ts +64 -0
  78. package/dist/entities/system/icon-library.js +112 -0
  79. package/dist/entities/system/icon-metadata.d.ts +72 -0
  80. package/dist/entities/system/icon-metadata.js +111 -0
  81. package/dist/entities/system/link-declaration.d.ts +27 -0
  82. package/dist/entities/system/link-declaration.js +64 -0
  83. package/dist/entities/system/link-plan.d.ts +160 -0
  84. package/dist/entities/system/link-plan.js +770 -0
  85. package/dist/entities/system/runtime-modules.d.ts +25 -0
  86. package/dist/entities/system/runtime-modules.js +38 -0
  87. package/dist/entities/system/style-bag.d.ts +20 -0
  88. package/dist/entities/system/style-bag.js +246 -0
  89. package/dist/entities/system/token-index.d.ts +89 -0
  90. package/dist/entities/system/token-index.js +112 -0
  91. package/dist/framework/Config.d.ts +2472 -0
  92. package/dist/framework/Config.js +5023 -0
  93. package/dist/framework/Entity.d.ts +127 -0
  94. package/dist/framework/Entity.js +125 -0
  95. package/dist/framework/authoring.d.ts +24 -0
  96. package/dist/framework/authoring.js +7 -0
  97. package/dist/framework/change-hooks.d.ts +119 -0
  98. package/dist/framework/change-hooks.js +131 -0
  99. package/dist/framework/changes.d.ts +88 -0
  100. package/dist/framework/changes.js +246 -0
  101. package/dist/framework/class-names.d.ts +260 -0
  102. package/dist/framework/class-names.js +630 -0
  103. package/dist/framework/coalesce.d.ts +25 -0
  104. package/dist/framework/coalesce.js +60 -0
  105. package/dist/framework/config-op.d.ts +76 -0
  106. package/dist/framework/config-op.js +43 -0
  107. package/dist/framework/config-operation-kind.d.ts +14 -0
  108. package/dist/framework/config-operation-kind.js +14 -0
  109. package/dist/framework/config-ops.d.ts +34 -0
  110. package/dist/framework/config-ops.js +187 -0
  111. package/dist/framework/defineConfig.d.ts +196 -0
  112. package/dist/framework/defineConfig.js +100 -0
  113. package/dist/framework/defineDerivedEntity.d.ts +74 -0
  114. package/dist/framework/defineDerivedEntity.js +83 -0
  115. package/dist/framework/defineEntity.d.ts +318 -0
  116. package/dist/framework/defineEntity.js +183 -0
  117. package/dist/framework/defineSubEntity.d.ts +148 -0
  118. package/dist/framework/defineSubEntity.js +121 -0
  119. package/dist/framework/derived-mutations.d.ts +20 -0
  120. package/dist/framework/derived-mutations.js +38 -0
  121. package/dist/framework/entity-search.d.ts +29 -0
  122. package/dist/framework/entity-search.js +117 -0
  123. package/dist/framework/inline-sources.d.ts +49 -0
  124. package/dist/framework/inline-sources.js +388 -0
  125. package/dist/framework/layer-styles.d.ts +25 -0
  126. package/dist/framework/layer-styles.js +49 -0
  127. package/dist/framework/memo.d.ts +48 -0
  128. package/dist/framework/memo.js +84 -0
  129. package/dist/framework/overlay.d.ts +49 -0
  130. package/dist/framework/overlay.js +17 -0
  131. package/dist/framework/plan.d.ts +49 -0
  132. package/dist/framework/plan.js +73 -0
  133. package/dist/framework/projections.d.ts +480 -0
  134. package/dist/framework/projections.js +974 -0
  135. package/dist/framework/prop-surface.d.ts +132 -0
  136. package/dist/framework/prop-surface.js +278 -0
  137. package/dist/framework/ref-graph.d.ts +71 -0
  138. package/dist/framework/ref-graph.js +158 -0
  139. package/dist/framework/ref-integrity.d.ts +55 -0
  140. package/dist/framework/ref-integrity.js +171 -0
  141. package/dist/framework/registered.d.ts +95 -0
  142. package/dist/framework/registry-dir.d.ts +42 -0
  143. package/dist/framework/registry-dir.js +48 -0
  144. package/dist/framework/registry.d.ts +300 -0
  145. package/dist/framework/registry.js +104 -0
  146. package/dist/framework/rejection.d.ts +58 -0
  147. package/dist/framework/rejection.js +111 -0
  148. package/dist/framework/rename-inference.d.ts +26 -0
  149. package/dist/framework/rename-inference.js +50 -0
  150. package/dist/framework/render-spec.d.ts +296 -0
  151. package/dist/framework/render-spec.js +809 -0
  152. package/dist/framework/schema-version.d.ts +140 -0
  153. package/dist/framework/schema-version.js +214 -0
  154. package/dist/framework/schemas.d.ts +109 -0
  155. package/dist/framework/schemas.js +615 -0
  156. package/dist/framework/session.d.ts +196 -0
  157. package/dist/framework/session.js +367 -0
  158. package/dist/framework/signature.d.ts +15 -0
  159. package/dist/framework/signature.js +83 -0
  160. package/dist/framework/snapshot.d.ts +115 -0
  161. package/dist/framework/snapshot.js +277 -0
  162. package/dist/framework/source-integrity.d.ts +226 -0
  163. package/dist/framework/source-integrity.js +478 -0
  164. package/dist/framework/sources.d.ts +211 -0
  165. package/dist/framework/sources.js +89 -0
  166. package/dist/framework/utils/compiled-schema.d.ts +23 -0
  167. package/dist/framework/utils/compiled-schema.js +46 -0
  168. package/dist/framework/utils/content-key.d.ts +15 -0
  169. package/dist/framework/utils/content-key.js +33 -0
  170. package/dist/framework/utils/enumerated.d.ts +13 -0
  171. package/dist/framework/utils/enumerated.js +19 -0
  172. package/dist/framework/utils/field-path.d.ts +95 -0
  173. package/dist/framework/utils/field-path.js +136 -0
  174. package/dist/framework/utils/field-schema.d.ts +55 -0
  175. package/dist/framework/utils/field-schema.js +183 -0
  176. package/dist/framework/utils/group.d.ts +37 -0
  177. package/dist/framework/utils/group.js +13 -0
  178. package/dist/framework/utils/package-path.d.ts +37 -0
  179. package/dist/framework/utils/package-path.js +61 -0
  180. package/dist/framework/utils/refs.d.ts +194 -0
  181. package/dist/framework/utils/refs.js +403 -0
  182. package/dist/framework/validate-spec.d.ts +27 -0
  183. package/dist/framework/validate-spec.js +45 -0
  184. package/dist/framework/value-domain.d.ts +26 -0
  185. package/dist/framework/value-domain.js +202 -0
  186. package/dist/framework/views-facade.d.ts +15 -0
  187. package/dist/framework/views-facade.js +19 -0
  188. package/dist/index.d.ts +90 -42
  189. package/dist/index.js +86 -37
  190. package/dist/migrations/2.0.0/raw-css.d.ts +11 -0
  191. package/dist/migrations/2.0.0/raw-css.js +72 -0
  192. package/dist/migrations/2.0.0/v1-artifact.d.ts +1559 -0
  193. package/dist/migrations/2.0.0/v1-artifact.js +1018 -0
  194. package/dist/migrations/20260908171448_settings_as_kind.d.ts +22 -0
  195. package/dist/migrations/20260908171448_settings_as_kind.js +89 -0
  196. package/dist/migrations/20260908194245_visible_state_pointer.d.ts +19 -0
  197. package/dist/migrations/20260908194245_visible_state_pointer.js +115 -0
  198. package/dist/migrations/20260909183001_icon_knockout_variants.d.ts +18 -0
  199. package/dist/migrations/20260909183001_icon_knockout_variants.js +8 -0
  200. package/dist/migrations/20260910212453_linked_system_link_ops.d.ts +13 -0
  201. package/dist/migrations/20260910212453_linked_system_link_ops.js +8 -0
  202. package/dist/migrations/index.d.ts +2 -0
  203. package/dist/migrations/index.js +2 -0
  204. package/dist/react-native/style-keys.generated.d.ts +10 -0
  205. package/dist/react-native/style-keys.generated.js +167 -0
  206. package/dist/renderer/RendererErrorBoundary.d.ts +32 -5
  207. package/dist/renderer/RendererErrorBoundary.js +59 -10
  208. package/dist/renderer/UdsRenderer.d.ts +11 -10
  209. package/dist/renderer/UdsRenderer.js +1 -1
  210. package/dist/renderer/assetEntries.d.ts +37 -0
  211. package/dist/renderer/assetEntries.js +39 -0
  212. package/dist/renderer/assetRenderable.d.ts +14 -6
  213. package/dist/renderer/assetRenderable.js +8 -2
  214. package/dist/renderer/componentEntry.d.ts +58 -0
  215. package/dist/renderer/componentEntry.js +71 -0
  216. package/dist/renderer/icon-library.d.ts +20 -0
  217. package/dist/renderer/index.d.ts +7 -7
  218. package/dist/renderer/index.js +5 -5
  219. package/dist/renderer/primitives/SlotRenderer.d.ts +1 -1
  220. package/dist/renderer/primitives/SlotRenderer.js +1 -1
  221. package/dist/renderer/runtimeComponent.d.ts +33 -0
  222. package/dist/renderer/runtimeComponent.js +113 -0
  223. package/dist/renderer/spec-content.d.ts +43 -0
  224. package/dist/renderer/spec-content.js +95 -0
  225. package/dist/renderer/wrapRegistry.d.ts +22 -37
  226. package/dist/renderer/wrapRegistry.js +10 -20
  227. package/dist/renderer/wrappers/event-bridge.js +6 -5
  228. package/dist/renderer/wrappers/hex-normalize.js +6 -5
  229. package/dist/renderer/wrappers/html-aliases.d.ts +7 -2
  230. package/dist/renderer/wrappers/html-aliases.js +36 -19
  231. package/dist/renderer/wrappers/inline-styles.js +7 -6
  232. package/dist/spec/asset-jsx.d.ts +18 -5
  233. package/dist/spec/asset-jsx.js +27 -16
  234. package/dist/spec/collapse-text-labels.d.ts +5 -15
  235. package/dist/spec/collapse-text-labels.js +26 -19
  236. package/dist/spec/empty-node-slots.d.ts +56 -34
  237. package/dist/spec/empty-node-slots.js +87 -47
  238. package/dist/spec/index.d.ts +21 -10
  239. package/dist/spec/index.js +21 -10
  240. package/dist/spec/jsxToSpec.d.ts +14 -9
  241. package/dist/spec/jsxToSpec.js +20 -3
  242. package/dist/spec/preview-elements.d.ts +63 -0
  243. package/dist/spec/preview-elements.js +89 -0
  244. package/dist/spec/rewrite-refs.d.ts +58 -0
  245. package/dist/spec/rewrite-refs.js +250 -0
  246. package/dist/spec/specToJsx.js +18 -29
  247. package/dist/tsconfig.tsbuildinfo +1 -1
  248. package/package.json +39 -52
  249. package/dist/AssetGroup.d.ts +0 -77
  250. package/dist/AssetGroup.js +0 -125
  251. package/dist/Component.d.ts +0 -333
  252. package/dist/Component.js +0 -1061
  253. package/dist/ComponentGroup.d.ts +0 -22
  254. package/dist/ComponentGroup.js +0 -51
  255. package/dist/CompositeStyle.d.ts +0 -30
  256. package/dist/CompositeStyle.js +0 -59
  257. package/dist/Config.d.ts +0 -528
  258. package/dist/Config.js +0 -1712
  259. package/dist/Mode.d.ts +0 -41
  260. package/dist/Mode.js +0 -81
  261. package/dist/Modifier.d.ts +0 -51
  262. package/dist/Modifier.js +0 -97
  263. package/dist/MotionDef.d.ts +0 -81
  264. package/dist/MotionDef.js +0 -212
  265. package/dist/Props.d.ts +0 -332
  266. package/dist/Props.js +0 -35
  267. package/dist/Provider.d.ts +0 -20
  268. package/dist/Provider.js +0 -14
  269. package/dist/StyleProp.d.ts +0 -145
  270. package/dist/StyleProp.js +0 -239
  271. package/dist/Token.d.ts +0 -76
  272. package/dist/Token.js +0 -133
  273. package/dist/TokenGroup.d.ts +0 -33
  274. package/dist/TokenGroup.js +0 -69
  275. package/dist/asset-kind.d.ts +0 -55
  276. package/dist/asset-kind.js +0 -29
  277. package/dist/asset-value.d.ts +0 -23
  278. package/dist/asset-value.js +0 -40
  279. package/dist/brands.d.ts +0 -30
  280. package/dist/brands.js +0 -20
  281. package/dist/captureCallerPath.d.ts +0 -48
  282. package/dist/captureCallerPath.js +0 -95
  283. package/dist/colorExpressions.d.ts +0 -131
  284. package/dist/colorExpressions.js +0 -148
  285. package/dist/component-referrers.d.ts +0 -30
  286. package/dist/component-referrers.js +0 -40
  287. package/dist/config-diagnostics.d.ts +0 -21
  288. package/dist/config-diagnostics.js +0 -12
  289. package/dist/defineAssetGroup.d.ts +0 -200
  290. package/dist/defineAssetGroup.js +0 -323
  291. package/dist/defineProvider.d.ts +0 -29
  292. package/dist/defineProvider.js +0 -60
  293. package/dist/element-marker.d.ts +0 -63
  294. package/dist/element-marker.js +0 -113
  295. package/dist/entity-utils.d.ts +0 -56
  296. package/dist/entity-utils.js +0 -105
  297. package/dist/extension.d.ts +0 -55
  298. package/dist/extension.js +0 -214
  299. package/dist/factories.d.ts +0 -863
  300. package/dist/factories.js +0 -475
  301. package/dist/font-face.d.ts +0 -25
  302. package/dist/font-face.js +0 -72
  303. package/dist/foreign-component-name.d.ts +0 -21
  304. package/dist/foreign-component-name.js +0 -42
  305. package/dist/interpolate.d.ts +0 -20
  306. package/dist/interpolate.js +0 -10
  307. package/dist/jsx/__fixtures__/cross-component-preview.d.ts +0 -3
  308. package/dist/jsx/__fixtures__/cross-component-preview.js +0 -15
  309. package/dist/jsx/jsx-dev-runtime.d.ts +0 -15
  310. package/dist/jsx/jsx-dev-runtime.js +0 -11
  311. package/dist/jsx/jsx-runtime.d.ts +0 -48
  312. package/dist/jsx/jsx-runtime.js +0 -305
  313. package/dist/linked-system-pins.d.ts +0 -30
  314. package/dist/linked-system-pins.js +0 -45
  315. package/dist/linkedNodePrefixes.d.ts +0 -73
  316. package/dist/linkedNodePrefixes.js +0 -99
  317. package/dist/markers.d.ts +0 -235
  318. package/dist/markers.js +0 -70
  319. package/dist/motion-constants.d.ts +0 -37
  320. package/dist/motion-constants.js +0 -61
  321. package/dist/native/NativeConfig.d.ts +0 -56
  322. package/dist/native/NativeConfig.js +0 -162
  323. package/dist/native/assets.d.ts +0 -20
  324. package/dist/native/assets.js +0 -17
  325. package/dist/native/components.d.ts +0 -139
  326. package/dist/native/components.js +0 -67
  327. package/dist/native/index.d.ts +0 -18
  328. package/dist/native/index.js +0 -17
  329. package/dist/native/modes.d.ts +0 -10
  330. package/dist/native/modes.js +0 -11
  331. package/dist/native/types.d.ts +0 -95
  332. package/dist/native/types.js +0 -0
  333. package/dist/native/validation.d.ts +0 -8
  334. package/dist/native/validation.js +0 -885
  335. package/dist/native/values.d.ts +0 -7
  336. package/dist/native/values.js +0 -15
  337. package/dist/native.d.ts +0 -12
  338. package/dist/native.js +0 -10
  339. package/dist/refs.d.ts +0 -204
  340. package/dist/refs.js +0 -129
  341. package/dist/registry-aliases.d.ts +0 -33
  342. package/dist/registry-aliases.js +0 -35
  343. package/dist/registry-dir.d.ts +0 -22
  344. package/dist/registry-dir.js +0 -10
  345. package/dist/renderer/makeRegistry.d.ts +0 -34
  346. package/dist/renderer/makeRegistry.js +0 -52
  347. package/dist/renderer/makeUdsRenderer.d.ts +0 -13
  348. package/dist/renderer/makeUdsRenderer.js +0 -51
  349. package/dist/renderer/wrappers/component-slots.d.ts +0 -41
  350. package/dist/renderer/wrappers/component-slots.js +0 -66
  351. package/dist/renderer/wrappers/slot-resolution.d.ts +0 -25
  352. package/dist/renderer/wrappers/slot-resolution.js +0 -68
  353. package/dist/renderer/wrappers/void-elements.d.ts +0 -37
  354. package/dist/renderer/wrappers/void-elements.js +0 -40
  355. package/dist/spec/layer-props.d.ts +0 -52
  356. package/dist/spec/layer-props.js +0 -149
  357. package/dist/spec/preview-controls.d.ts +0 -44
  358. package/dist/spec/preview-controls.js +0 -139
  359. package/dist/spec/slot-refs.d.ts +0 -39
  360. package/dist/spec/slot-refs.js +0 -56
  361. package/dist/token-override-rows.d.ts +0 -68
  362. package/dist/token-override-rows.js +0 -233
  363. package/dist/tokenValueType.d.ts +0 -34
  364. package/dist/tokenValueType.js +0 -138
  365. package/dist/types/css-properties.d.ts +0 -233
  366. package/dist/types/css-properties.js +0 -14
  367. package/dist/types/css-property-keywords.d.ts +0 -156
  368. package/dist/types/css-property-keywords.js +0 -616
  369. package/dist/types/css-values.d.ts +0 -63
  370. package/dist/types/css-values.js +0 -16
  371. package/dist/types.d.ts +0 -1138
  372. package/dist/types.js +0 -12
  373. package/dist/units.d.ts +0 -14
  374. package/dist/units.js +0 -16
  375. package/dist/utils/index.d.ts +0 -4
  376. package/dist/utils/index.js +0 -4
@@ -0,0 +1,132 @@
1
+ import { Config } from "./Config.js";
2
+
3
+ //#region src/framework/prop-surface.d.ts
4
+ /** What a prop IS — the config's own prop types, and nothing invented. */
5
+ type SurfacePropKind = 'variant' | 'styleProperty' | 'composite' | 'motion' | 'slot' | 'string' | 'number' | 'boolean';
6
+ interface SurfacePropBase {
7
+ readonly name: string;
8
+ readonly required: boolean;
9
+ }
10
+ interface SurfaceVariantProp extends SurfacePropBase {
11
+ readonly kind: 'variant';
12
+ /** The values it offers, as the leaves a consumer authors. */
13
+ readonly values: string[];
14
+ /** An icon LIBRARY the values delegate to, when the domain is the group itself — a surface
15
+ * offers the glyph picker rather than a select over every member. A FACET ref
16
+ * (`icon:phosphor#variants`) stays a plain list: its leaves are the group node's own field
17
+ * values, a menu-sized set. Mirrors {@link SurfaceSlotProp.acceptsIconLibrary}. */
18
+ readonly iconLibrary?: string;
19
+ }
20
+ interface SurfaceStylePropertyProp extends SurfacePropBase {
21
+ readonly kind: 'styleProperty';
22
+ /** The style property this prop writes through. */
23
+ readonly styleProperty: string;
24
+ }
25
+ interface SurfaceCompositeProp extends SurfacePropBase {
26
+ readonly kind: 'composite';
27
+ readonly compositeName: string;
28
+ }
29
+ interface SurfaceScalarProp extends SurfacePropBase {
30
+ readonly kind: 'string' | 'number' | 'boolean' | 'motion';
31
+ }
32
+ interface SurfaceSlotProp extends SurfacePropBase {
33
+ readonly kind: 'slot';
34
+ /** Declared a TEXT surface — content typed in place rather than dropped into. */
35
+ readonly text: boolean;
36
+ /** The layer this routes into, when it targets one. */
37
+ readonly targetLayer?: string;
38
+ /** The prop on that layer's element it arrives as (`children` unless stated). */
39
+ readonly into?: string;
40
+ /** Components this slot may be filled with (`accepts`), as paths. Empty when unconstrained. */
41
+ readonly accepts: string[];
42
+ /** The icon library this slot accepts, when `accepts` names one — the picker offers its glyphs
43
+ * beside any accepted components. The library is the group the glyphs live in; Studio labels it
44
+ * the slot's icon set. */
45
+ readonly acceptsIconLibrary?: string;
46
+ /** What the prop on the other end of the routing is, when this slot targets a layer. Absent for an
47
+ * open slot (content the render places itself). */
48
+ readonly valueKind?: SurfacePropKind;
49
+ /** That prop's own value domain, for the kinds that have one. */
50
+ readonly valueOptions?: string[];
51
+ /** That prop's composite, when it forwards into one. */
52
+ readonly compositeName?: string;
53
+ }
54
+ type SurfaceProp = SurfaceVariantProp | SurfaceStylePropertyProp | SurfaceCompositeProp | SurfaceScalarProp | SurfaceSlotProp;
55
+ /** A prop declaration, as far as this reads it. An index signature because `propValueDomain` takes a
56
+ * declaration as an open record — it resolves the domain off `type`/`value` generically. */
57
+ interface PropDecl extends Record<string, unknown> {
58
+ type?: string;
59
+ value?: unknown;
60
+ required?: boolean;
61
+ target?: unknown;
62
+ into?: string;
63
+ text?: boolean;
64
+ accepts?: unknown;
65
+ }
66
+ /**
67
+ * The prop a slot routes INTO, resolved through the layer it targets: the layer's element is a
68
+ * component, and `into` names one of that component's props. `undefined` when the slot targets
69
+ * nothing, when the layer renders a bare tag (which declares no props), or when the named prop isn't
70
+ * one that component exposes.
71
+ */
72
+ /**
73
+ * The prop name a route addresses, whichever spelling `into` is in.
74
+ *
75
+ * A NAME between the schema's target split and registration; a MEMBER REF once `storedForward` has
76
+ * minted one (`component:Input#props/disabled`), which is the form that puts the edge in the dependency
77
+ * graph. Readers want the name either way, and `'children'` is the default a content route means.
78
+ */
79
+ declare function intoName(into: unknown): string;
80
+ /**
81
+ * The prop a route ROUTES INTO — the declaration at `<layer>/<prop>`, reached through the layer's
82
+ * element.
83
+ *
84
+ * `undefined` when the layer's element is a TAG rather than a component: a tag's props are the DOM's and
85
+ * there is no declaration to resolve. That is not a failure, and {@link routesContent} reads it as one
86
+ * of the two answers it needs.
87
+ */
88
+ declare function routedPropIn(config: Config, layers: Readonly<Record<string, unknown>> | undefined, decl: {
89
+ target?: unknown;
90
+ into?: unknown;
91
+ }): PropDecl | undefined;
92
+ /** {@link routedPropIn} for a component the config already holds. The layers are what the resolution
93
+ * needs; a path is the convenience for a caller that has one instead. */
94
+ declare function routedProp(config: Config, componentPath: string, decl: {
95
+ target?: unknown;
96
+ into?: unknown;
97
+ }): PropDecl | undefined;
98
+ declare function routesContent(config: Config, layers: Readonly<Record<string, unknown>> | undefined, decl: {
99
+ target?: unknown;
100
+ into?: unknown;
101
+ }): boolean;
102
+ /**
103
+ * Every prop a component exposes, in declaration order, projected for a control surface.
104
+ *
105
+ * A `motion` prop is included as a scalar so it can't silently disappear from a surface that lists
106
+ * what a component accepts; a caller with no editor for it can fall back to a generic one.
107
+ */
108
+ declare function surfaceProps(config: Config, componentPath: string, /** Forwards already followed, so a routing loop terminates. Internal — callers pass nothing. */
109
+
110
+ seen?: ReadonlySet<string>): SurfaceProp[];
111
+ /** One prop by name, or `undefined` when the component doesn't expose it. */
112
+ declare function surfaceProp(config: Config, componentPath: string, name: string): SurfaceProp | undefined;
113
+ /**
114
+ * Each non-root layer a component forwards to, and the sorted prop names each one receives — the
115
+ * emitter's view, which writes a literal key set per layer. Root is absent on purpose: it takes
116
+ * whatever is left, which every emitter already gives it unconditionally.
117
+ */
118
+ declare function forwardedLayers(config: Config, componentPath: string): Map<string, string[]>;
119
+ /**
120
+ * Who delivers each name a consumer can pass to this component: the component's own declaration, or
121
+ * the layer whose `forwards` entry exposes it. Root is included, since a picker attributing a claim
122
+ * needs to name root as a claimer; `forwardedLayers` is the emitter's view and leaves root out.
123
+ */
124
+ interface ForwardClaims {
125
+ /** Names declared in the component's own `props`. A forward of one of these never reaches a consumer. */
126
+ readonly own: ReadonlySet<string>;
127
+ /** Forwarded name → the layer whose entry delivers it. The first entry in key order wins an overlap. */
128
+ readonly forwarded: ReadonlyMap<string, string>;
129
+ }
130
+ declare function forwardClaims(config: Config, componentPath: string): ForwardClaims;
131
+ //#endregion
132
+ export { ForwardClaims, SurfaceCompositeProp, SurfaceProp, SurfacePropKind, SurfaceScalarProp, SurfaceSlotProp, SurfaceStylePropertyProp, SurfaceVariantProp, forwardClaims, forwardedLayers, intoName, routedProp, routedPropIn, routesContent, surfaceProp, surfaceProps };
@@ -0,0 +1,278 @@
1
+ import { isRef, kindOf, memberOf, pathOf } from "./utils/refs.js";
2
+ import { forwardsOf, rootLayerOf } from "../entities/system/element.js";
3
+ import { propValueDomain, resolveComponentProps } from "./projections.js";
4
+ import { Component } from "../entities/system/Component.js";
5
+ //#region src/framework/prop-surface.ts
6
+ /**
7
+ * A component's public API, projected for a surface that has to render a CONTROL per prop.
8
+ *
9
+ * The config states each prop as a declaration keyed by name — its type, and what it delegates its
10
+ * value domain to. A control needs one more thing the declarations only imply: for a SLOT that routes
11
+ * into a layer, *what does the prop on the other end accept?* A `label` slot targeting a Text layer's
12
+ * `children` is a text input; one targeting a Pressable layer's `variant` is a select over that
13
+ * component's variant values. So the routing is resolved here, once, and callers switch on the answer
14
+ * instead of re-walking layers per control — which is the whole reason this is a projection rather
15
+ * than each surface reading `props` itself.
16
+ *
17
+ * Everything else is a straight read: `resolveComponentProps` merges what a component exposes through
18
+ * `forwards`, and `propValueDomain` answers what each prop accepts — including a prop that DELEGATES
19
+ * its domain (an icon prop drawing its names from the icon library rather than copying them in),
20
+ * which is why value lists are never read straight off `value`.
21
+ */
22
+ /** The tail of a ref, when the value is one. */
23
+ function refPath(value) {
24
+ return isRef(value) ? pathOf(value.__ref) : void 0;
25
+ }
26
+ /** Every ref in an `accepts` declaration (one, or a list). */
27
+ function acceptsRefs(accepts) {
28
+ return (Array.isArray(accepts) ? accepts : [accepts]).filter(isRef).map((ref) => ref.__ref);
29
+ }
30
+ /**
31
+ * The icon library a variant's value domain delegates to, when the domain is
32
+ * the GROUP itself (`icon:phosphor` — one leaf per glyph). A facet ref keeps
33
+ * its `#field` marker and is not a library: its leaves are the group node's
34
+ * own field values, which a plain list control serves fine. A ref at one ITEM
35
+ * (`icon:phosphor/StarIcon`) is a single-leaf domain, not a library either.
36
+ */
37
+ function variantIconLibrary(config, value) {
38
+ if (!isRef(value) || kindOf(value) !== "icon") return void 0;
39
+ if (memberOf(value) !== void 0) return void 0;
40
+ const path = pathOf(value);
41
+ if (config.resolve("icon", path)) return void 0;
42
+ return path;
43
+ }
44
+ /**
45
+ * The prop a slot routes INTO, resolved through the layer it targets: the layer's element is a
46
+ * component, and `into` names one of that component's props. `undefined` when the slot targets
47
+ * nothing, when the layer renders a bare tag (which declares no props), or when the named prop isn't
48
+ * one that component exposes.
49
+ */
50
+ /**
51
+ * The prop name a route addresses, whichever spelling `into` is in.
52
+ *
53
+ * A NAME between the schema's target split and registration; a MEMBER REF once `storedForward` has
54
+ * minted one (`component:Input#props/disabled`), which is the form that puts the edge in the dependency
55
+ * graph. Readers want the name either way, and `'children'` is the default a content route means.
56
+ */
57
+ function intoName(into) {
58
+ if (typeof into === "string") return into;
59
+ if (!isRef(into)) return "children";
60
+ const member = memberOf(into) ?? into.__ref;
61
+ return member.slice(member.indexOf("/") + 1);
62
+ }
63
+ /**
64
+ * The prop a route ROUTES INTO — the declaration at `<layer>/<prop>`, reached through the layer's
65
+ * element.
66
+ *
67
+ * `undefined` when the layer's element is a TAG rather than a component: a tag's props are the DOM's and
68
+ * there is no declaration to resolve. That is not a failure, and {@link routesContent} reads it as one
69
+ * of the two answers it needs.
70
+ */
71
+ function routedPropIn(config, layers, decl) {
72
+ const layerKey = refPath(decl.target);
73
+ if (!layerKey) return void 0;
74
+ const target = refPath(layers?.[layerKey]);
75
+ if (!target) return void 0;
76
+ return resolveComponentProps(config, target)[intoName(decl.into)];
77
+ }
78
+ /** {@link routedPropIn} for a component the config already holds. The layers are what the resolution
79
+ * needs; a path is the convenience for a caller that has one instead. */
80
+ function routedProp(config, componentPath, decl) {
81
+ const body = Component.get(config, componentPath)?.toJSON();
82
+ return routedPropIn(config, body?.layers, decl);
83
+ }
84
+ function routesContent(config, layers, decl) {
85
+ const routed = routedPropIn(config, layers, decl);
86
+ if (routed) return routed.type === "slot";
87
+ return refPath(decl.target) !== void 0 && intoName(decl.into) === "children";
88
+ }
89
+ function slotProp(config, componentPath, name, decl) {
90
+ const refs = acceptsRefs(decl.accepts);
91
+ const icons = refs.find((ref) => kindOf(ref) === "icon");
92
+ const routed = routedProp(config, componentPath, decl);
93
+ const routedKind = routed?.type;
94
+ const targetLayer = refPath(decl.target);
95
+ const routesIntoText = routed?.type === "slot" && routed.text === true;
96
+ return {
97
+ name,
98
+ kind: "slot",
99
+ required: decl.required === true,
100
+ text: decl.text === true || routesIntoText,
101
+ ...targetLayer ? {
102
+ targetLayer,
103
+ into: decl.into ?? "children"
104
+ } : {},
105
+ accepts: refs.filter((ref) => kindOf(ref) === "component").map((ref) => pathOf(ref)),
106
+ ...icons ? { acceptsIconLibrary: pathOf(icons) } : {},
107
+ ...routedKind ? { valueKind: routedKind } : {},
108
+ ...routed ? { valueOptions: propValueDomain(config, routed)?.leaves } : {},
109
+ ...routedKind === "composite" ? { compositeName: refPath(routed?.value) } : {}
110
+ };
111
+ }
112
+ /**
113
+ * Every prop a component exposes, in declaration order, projected for a control surface.
114
+ *
115
+ * A `motion` prop is included as a scalar so it can't silently disappear from a surface that lists
116
+ * what a component accepts; a caller with no editor for it can fall back to a generic one.
117
+ */
118
+ function surfaceProps(config, componentPath, seen = /* @__PURE__ */ new Set()) {
119
+ const declared = resolveComponentProps(config, componentPath);
120
+ const layers = (Component.get(config, componentPath)?.toJSON())?.layers;
121
+ const props = [];
122
+ for (const [name, decl] of Object.entries(declared)) {
123
+ const required = decl.required === true;
124
+ if (decl.type === "forward") {
125
+ if (routesContent(config, layers, decl)) {
126
+ props.push(slotProp(config, componentPath, name, decl));
127
+ continue;
128
+ }
129
+ const routed = boundProp(config, layers, decl, seen);
130
+ if (routed) props.push({
131
+ ...routed,
132
+ name,
133
+ required
134
+ });
135
+ continue;
136
+ }
137
+ if (decl.type === "slot") {
138
+ props.push(slotProp(config, componentPath, name, decl));
139
+ continue;
140
+ }
141
+ if (decl.type === "variant") {
142
+ const iconLibrary = variantIconLibrary(config, decl.value);
143
+ props.push({
144
+ name,
145
+ kind: "variant",
146
+ required,
147
+ values: propValueDomain(config, decl)?.leaves ?? [],
148
+ ...iconLibrary !== void 0 ? { iconLibrary } : {}
149
+ });
150
+ continue;
151
+ }
152
+ if (decl.type === "styleProperty") {
153
+ const styleProperty = refPath(decl.value);
154
+ if (!styleProperty) continue;
155
+ props.push({
156
+ name,
157
+ kind: "styleProperty",
158
+ required,
159
+ styleProperty
160
+ });
161
+ continue;
162
+ }
163
+ if (decl.type === "composite") {
164
+ const compositeName = refPath(decl.value);
165
+ if (!compositeName) continue;
166
+ props.push({
167
+ name,
168
+ kind: "composite",
169
+ required,
170
+ compositeName
171
+ });
172
+ continue;
173
+ }
174
+ if (decl.type === "string" || decl.type === "number" || decl.type === "boolean" || decl.type === "motion") props.push({
175
+ name,
176
+ kind: decl.type,
177
+ required
178
+ });
179
+ }
180
+ return props;
181
+ }
182
+ /**
183
+ * The prop a forward routes to, resolved as a surface prop of its own.
184
+ *
185
+ * `seen` guards a forward that routes to a forward that routes back: the chain is data, so nothing
186
+ * stops an author writing a loop, and the surface is read on every panel render.
187
+ */
188
+ function boundProp(config, layers, decl, seen) {
189
+ const propName = intoName(decl.into);
190
+ const target = isRef(decl.into) ? pathOf(decl.into) : refPath(layers?.[refPath(decl.target) ?? ""]);
191
+ if (!target) return void 0;
192
+ const key = `${target}#${propName}`;
193
+ if (seen.has(key)) return void 0;
194
+ return surfaceProps(config, target, new Set([...seen, key])).find((prop) => prop.name === propName);
195
+ }
196
+ /** One prop by name, or `undefined` when the component doesn't expose it. */
197
+ function surfaceProp(config, componentPath, name) {
198
+ return surfaceProps(config, componentPath).find((prop) => prop.name === name);
199
+ }
200
+ /**
201
+ * The one precedence walk behind {@link forwardedLayers} and {@link forwardClaims}: every name a
202
+ * `forwards` entry exposes, attributed to the layer that delivers it.
203
+ *
204
+ * The other half of prop routing. {@link surfaceProps} answers what a prop IS by resolving a forward
205
+ * THROUGH to the declaration on the far end; this answers the inverse — given a layer, which of the
206
+ * call site's props land on it. An emitter needs that to write a literal key set per layer, and a
207
+ * design surface needs it to say which layer an edit will actually reach.
208
+ *
209
+ * Two precedence rules, and both are failure modes somebody has already paid for:
210
+ *
211
+ * - **Own props beat every forward, tombstones included.** A tombstone means the prop is declared
212
+ * GONE, not merely undeclared; treating it as absent routed the dropped prop to an inner layer at
213
+ * runtime even though every config projection agreed it did not exist.
214
+ * - **Among forwards, the first entry wins.** Validation rejects overlaps on write, but a later
215
+ * rename or an added prop can create one without rewriting this component, so the total
216
+ * resolution is implemented here rather than assumed.
217
+ *
218
+ * Root claims its forwarded names like any other layer, so a later layer cannot also receive one when
219
+ * an overlap appears after validation.
220
+ *
221
+ * Lives here because prop routing is the config's to answer — the web and native emitters each had
222
+ * their own copy of this walk, and two copies of a precedence rule is two chances for a prop to reach
223
+ * a different layer depending on which platform you built for.
224
+ */
225
+ function computeForwardClaims(config, componentPath) {
226
+ const body = Component.get(config, componentPath)?.toJSON();
227
+ const own = /* @__PURE__ */ new Set();
228
+ const forwarded = /* @__PURE__ */ new Map();
229
+ if (!body) return {
230
+ own,
231
+ forwarded,
232
+ rootLayer: void 0
233
+ };
234
+ const { layers = {}, props = {}, forwards } = body;
235
+ const [rootLayer] = rootLayerOf(layers);
236
+ for (const name of Object.keys(props)) own.add(name);
237
+ for (const [layer, entry] of Object.entries(forwardsOf({ forwards }))) {
238
+ const element = layers[layer];
239
+ if (!isRef(element)) continue;
240
+ const exposed = resolveComponentProps(config, pathOf(element.__ref));
241
+ const names = entry === "*" ? Object.keys(exposed) : (Array.isArray(entry) ? entry : []).map((ref) => isRef(ref) ? memberOf(ref)?.split("/").pop() : void 0).filter((name) => !!name && name in exposed);
242
+ for (const name of names) {
243
+ if (own.has(name) || forwarded.has(name)) continue;
244
+ forwarded.set(name, layer);
245
+ }
246
+ }
247
+ return {
248
+ own,
249
+ forwarded,
250
+ rootLayer
251
+ };
252
+ }
253
+ /**
254
+ * Each non-root layer a component forwards to, and the sorted prop names each one receives — the
255
+ * emitter's view, which writes a literal key set per layer. Root is absent on purpose: it takes
256
+ * whatever is left, which every emitter already gives it unconditionally.
257
+ */
258
+ function forwardedLayers(config, componentPath) {
259
+ const { forwarded, rootLayer } = computeForwardClaims(config, componentPath);
260
+ const out = /* @__PURE__ */ new Map();
261
+ for (const [name, layer] of forwarded) {
262
+ if (layer === rootLayer) continue;
263
+ const names = out.get(layer);
264
+ if (names) names.push(name);
265
+ else out.set(layer, [name]);
266
+ }
267
+ for (const names of out.values()) names.sort();
268
+ return out;
269
+ }
270
+ function forwardClaims(config, componentPath) {
271
+ const { own, forwarded } = computeForwardClaims(config, componentPath);
272
+ return {
273
+ own,
274
+ forwarded
275
+ };
276
+ }
277
+ //#endregion
278
+ export { forwardClaims, forwardedLayers, intoName, routedProp, routedPropIn, routesContent, surfaceProp, surfaceProps };
@@ -0,0 +1,71 @@
1
+ import { Ref } from "./utils/refs.js";
2
+
3
+ //#region src/framework/ref-graph.d.ts
4
+ /** One entity to index: its own `kind:path` ref, and the data to harvest refs from. */
5
+ interface RefGraphEntry {
6
+ readonly ref: string;
7
+ readonly data: unknown;
8
+ /**
9
+ * Edges this entity's data implies by NAME rather than by ref — a style bag keyed `bg` depends on
10
+ * `style-property:bg`, and no `{ __ref }` says so.
11
+ *
12
+ * Supplied by the caller (a kind declares how to read its own names — see `EntityKind.nameEdges`)
13
+ * because nothing generic can find identity in a KEY. Kept a PURE function of the entity's own
14
+ * data, which is what lets these edges ride the same incremental update as the ref-borne ones: an
15
+ * edge that needed another kind's state to compute would go stale whenever that state moved and
16
+ * this entity didn't.
17
+ */
18
+ readonly extra?: readonly string[];
19
+ }
20
+ interface TraverseOptions {
21
+ /** Follow chains rather than stopping at direct edges (default false). */
22
+ readonly transitive?: boolean;
23
+ }
24
+ /** A node to ask about: the entity's own ref (`Token.ref('color/brand')`) or its string form.
25
+ * Taking the ref itself means a caller names an entity the way it names one everywhere else. */
26
+ type RefTarget = string | Ref;
27
+ interface RefGraph {
28
+ /** Entities that point AT `target` — what breaks if it changes or goes away. */
29
+ dependents(target: RefTarget, opts?: TraverseOptions): string[];
30
+ /** Entities `target` points at — what it needs in order to resolve. */
31
+ dependencies(target: RefTarget, opts?: TraverseOptions): string[];
32
+ /**
33
+ * The shortest dependency chain `from` → … → `to`, inclusive of both ends, or `undefined` when
34
+ * `from` doesn't reach `to`. This is what turns "42 things affected" into a sentence a person can
35
+ * act on: `token:color/brand → modifier:dark → mode:colorMode/dark`.
36
+ */
37
+ path(from: RefTarget, to: RefTarget): string[] | undefined;
38
+ }
39
+ /**
40
+ * The raw two-way index behind a {@link RefGraph} — separated from the query facade so it can be
41
+ * carried on an immutable `Snapshot` and UPDATED for the handful of entities a patch touched,
42
+ * instead of rebuilt by a full pass over every item on each mutation.
43
+ */
44
+ interface RefIndex {
45
+ /** `ref` → the refs it points at. */
46
+ readonly out: ReadonlyMap<string, ReadonlySet<string>>;
47
+ /** `ref` → the refs pointing at it. */
48
+ readonly incoming: ReadonlyMap<string, ReadonlySet<string>>;
49
+ }
50
+ /** One entity's edges changing — `data: undefined` means the entity went away. */
51
+ interface RefIndexChange {
52
+ readonly ref: string;
53
+ readonly data: unknown | undefined;
54
+ /** Name-borne edges for the new data — see {@link RefGraphEntry.extra}. */
55
+ readonly extra?: readonly string[];
56
+ }
57
+ /** Index `entries` in both directions. Pure — callers memoize (see `Snapshot.refs`). */
58
+ declare function buildRefIndex(entries: readonly RefGraphEntry[], linkKinds?: readonly string[], singletonKinds?: readonly string[]): RefIndex;
59
+ /**
60
+ * Re-index only the entities in `changes`, returning a new index that shares nothing mutable with
61
+ * the old one. The top-level maps are copied per CALL (a batch), and only the edge sets actually
62
+ * touched are copied — so the deep `collectRefs` walk, which is the expensive part, runs for the
63
+ * changed entities alone rather than for the whole config.
64
+ */
65
+ declare function updateRefIndex(index: RefIndex, changes: readonly RefIndexChange[], linkKinds?: readonly string[], singletonKinds?: readonly string[]): RefIndex;
66
+ /** The query facade over a built index — the shape every consumer asks questions through. */
67
+ declare function refGraphOf(index: RefIndex): RefGraph;
68
+ /** Build and query in one step — for a caller with no snapshot to carry the index on. */
69
+ declare function buildRefGraph(entries: readonly RefGraphEntry[]): RefGraph;
70
+ //#endregion
71
+ export { RefGraph, RefGraphEntry, RefIndex, RefIndexChange, RefTarget, TraverseOptions, buildRefGraph, buildRefIndex, refGraphOf, updateRefIndex };
@@ -0,0 +1,158 @@
1
+ import { collectRefs, entityRefOf, isRef, kindOf, singletonRef, sourceOf } from "./utils/refs.js";
2
+ //#region src/framework/ref-graph.ts
3
+ /**
4
+ * The reference graph — every `{ __ref }` in the config, indexed both ways.
5
+ *
6
+ * `collectRefs` already harvests an entity's outgoing edges generically, so the graph needs no
7
+ * per-entity wiring; this just runs it over every item once and keeps both directions. That one
8
+ * index answers the questions each surface asks separately today: what breaks if I delete this
9
+ * (dependents), what does this pull in (dependencies), and — because renames and deletes have to be
10
+ * explained, not just counted — the CHAIN between two entities.
11
+ *
12
+ * Traversal is transitive on request: an edge chain like `token → modifier → mode` is the norm once
13
+ * an entity can point at another that points on, so "which tokens vary in dark mode" is a closure
14
+ * question, not a one-hop one.
15
+ *
16
+ * A MEMBER ref (`component:Pressable#props/gap`) is indexed under both its own form and its
17
+ * entity's, so a lookup by either resolves; traversal normalizes to the entity, since only entities
18
+ * have data to walk on from.
19
+ */
20
+ /** A target's string form — the key both indexes are built on. */
21
+ const key = (target) => isRef(target) ? target.__ref : target;
22
+ /** The refs `data` points at plus any name-borne ones, minus self-references (never a dependency). */
23
+ function edgesOf(ref, data, extra = [], linkKinds = [], singletonKinds = []) {
24
+ const collected = collectRefs(data);
25
+ const targets = new Set(collected);
26
+ if (singletonKinds.length > 0) for (const target of collected) {
27
+ if (!singletonKinds.includes(kindOf(target))) continue;
28
+ const canonical = singletonRef(target);
29
+ if (canonical === target) continue;
30
+ targets.add(entityRefOf(canonical));
31
+ targets.add(canonical);
32
+ }
33
+ if (linkKinds.length > 0) for (const target of collected) {
34
+ const slug = sourceOf(target);
35
+ if (slug === void 0) continue;
36
+ for (const kind of linkKinds) targets.add(`${kind}:${slug}`);
37
+ }
38
+ for (const target of extra) targets.add(target);
39
+ targets.delete(ref);
40
+ return targets;
41
+ }
42
+ function link(index, from, to) {
43
+ const set = index.get(from) ?? /* @__PURE__ */ new Set();
44
+ set.add(to);
45
+ index.set(from, set);
46
+ }
47
+ /** Index `entries` in both directions. Pure — callers memoize (see `Snapshot.refs`). */
48
+ function buildRefIndex(entries, linkKinds = [], singletonKinds = []) {
49
+ const out = /* @__PURE__ */ new Map();
50
+ const incoming = /* @__PURE__ */ new Map();
51
+ for (const { ref, data, extra } of entries) for (const target of edgesOf(ref, data, extra, linkKinds, singletonKinds)) {
52
+ link(out, ref, target);
53
+ link(incoming, target, ref);
54
+ }
55
+ return {
56
+ out,
57
+ incoming
58
+ };
59
+ }
60
+ /**
61
+ * Re-index only the entities in `changes`, returning a new index that shares nothing mutable with
62
+ * the old one. The top-level maps are copied per CALL (a batch), and only the edge sets actually
63
+ * touched are copied — so the deep `collectRefs` walk, which is the expensive part, runs for the
64
+ * changed entities alone rather than for the whole config.
65
+ */
66
+ function updateRefIndex(index, changes, linkKinds = [], singletonKinds = []) {
67
+ if (changes.length === 0) return index;
68
+ const out = /* @__PURE__ */ new Map();
69
+ for (const [node, set] of index.out) out.set(node, set);
70
+ const incoming = /* @__PURE__ */ new Map();
71
+ for (const [node, set] of index.incoming) incoming.set(node, set);
72
+ /** Copy-on-write a single edge set, so sets shared with the previous index are never mutated. */
73
+ const mutable = (map, node) => {
74
+ const next = new Set(map.get(node));
75
+ map.set(node, next);
76
+ return next;
77
+ };
78
+ for (const { ref, data, extra } of changes) {
79
+ for (const target of index.out.get(ref) ?? []) {
80
+ const back = mutable(incoming, target);
81
+ back.delete(ref);
82
+ if (back.size === 0) incoming.delete(target);
83
+ }
84
+ out.delete(ref);
85
+ if (data === void 0) continue;
86
+ const targets = edgesOf(ref, data, extra, linkKinds, singletonKinds);
87
+ if (targets.size === 0) continue;
88
+ out.set(ref, targets);
89
+ for (const target of targets) mutable(incoming, target).add(ref);
90
+ }
91
+ return {
92
+ out,
93
+ incoming
94
+ };
95
+ }
96
+ /** The query facade over a built index — the shape every consumer asks questions through. */
97
+ function refGraphOf(index) {
98
+ const { out, incoming } = index;
99
+ /** Outgoing edges of a node — a member ref has none of its own, so read its entity's. */
100
+ const edgesOut = (node) => out.get(node) ?? out.get(entityRefOf(node));
101
+ const walk = (start, step) => {
102
+ const seen = /* @__PURE__ */ new Set();
103
+ const queue = [start];
104
+ while (queue.length) {
105
+ const node = queue.shift();
106
+ for (const next of step(node) ?? []) {
107
+ if (seen.has(next)) continue;
108
+ seen.add(next);
109
+ queue.push(next);
110
+ }
111
+ }
112
+ seen.delete(start);
113
+ return [...seen];
114
+ };
115
+ return {
116
+ dependents(target, opts) {
117
+ const node = key(target);
118
+ if (!opts?.transitive) return [...incoming.get(node) ?? []];
119
+ return walk(node, (at) => incoming.get(at));
120
+ },
121
+ dependencies(target, opts) {
122
+ const node = key(target);
123
+ if (!opts?.transitive) return [...edgesOut(node) ?? []];
124
+ return walk(node, edgesOut);
125
+ },
126
+ path(fromTarget, toTarget) {
127
+ const from = key(fromTarget);
128
+ const to = key(toTarget);
129
+ if (from === to) return [from];
130
+ const cameFrom = new Map([[from, from]]);
131
+ const queue = [from];
132
+ while (queue.length) {
133
+ const node = queue.shift();
134
+ for (const next of edgesOut(node) ?? []) {
135
+ if (cameFrom.has(next)) continue;
136
+ cameFrom.set(next, node);
137
+ if (next === to) {
138
+ const chain = [next];
139
+ let step = node;
140
+ while (step !== from) {
141
+ chain.unshift(step);
142
+ step = cameFrom.get(step);
143
+ }
144
+ chain.unshift(from);
145
+ return chain;
146
+ }
147
+ queue.push(next);
148
+ }
149
+ }
150
+ }
151
+ };
152
+ }
153
+ /** Build and query in one step — for a caller with no snapshot to carry the index on. */
154
+ function buildRefGraph(entries) {
155
+ return refGraphOf(buildRefIndex(entries));
156
+ }
157
+ //#endregion
158
+ export { buildRefGraph, buildRefIndex, refGraphOf, updateRefIndex };