@yahoo/uds-create-config 2.45.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,127 @@
1
+ //#region src/framework/Entity.d.ts
2
+ /**
3
+ * One flat, path-keyed entity — an item or a group node. The base owns hydration and
4
+ * serialization from the kind's declared field names, so a kind adds no per-entity ctor
5
+ * or `toJSON`. Identity IS the qualified path; the group is simply its prefix.
6
+ */
7
+ declare class Entity {
8
+ #private;
9
+ readonly path: string;
10
+ private readonly fieldKeys;
11
+ /**
12
+ * VIRTUAL fields — read like any other, and deliberately absent from {@link toJSON}.
13
+ *
14
+ * The split is the whole point of having them separately. A computed field is a function of the
15
+ * entity and its config, so persisting one writes a derivation into the artifact: it goes stale the
16
+ * moment either input changes, and the stale copy wins on the next hydrate. Provenance is the
17
+ * clearest case — whether an item borrows is read off the source qualifier in its own fields, so a
18
+ * stored answer could contradict the value sitting next to it.
19
+ */
20
+ private readonly computedKeys;
21
+ readonly label?: string;
22
+ readonly description?: string;
23
+ /** Where a copied entity was taken from, as `<path>@<slug>`; `undefined` for one authored here. */
24
+ readonly copiedFrom?: string;
25
+ /** Kept and resolving, but not offered by authoring surfaces. This entity's own flag only; the
26
+ * answer that also reads its folders and its pin is `Config.hidden`. */
27
+ readonly hidden?: boolean;
28
+ /** Withdrawn from new work: hidden, and every existing use flagged. This entity's own flag only;
29
+ * the answer that also reads its folders is `Config.deprecated`. */
30
+ readonly deprecated?: boolean;
31
+ /** How to use this entity, as prose for a model. Collected into the guidance document per kind. */
32
+ readonly guidance?: string;
33
+ /**
34
+ * The DEPENDENCIES this item's own fields point through, deduped and sorted — the framework installs
35
+ * this computed on every kind, so it is declared here rather than per kind.
36
+ *
37
+ * `declare` because the value arrives through the computed pass like any other field; this only says
38
+ * that every entity has it, which is what lets a kind-agnostic reader (`config.resolve(kind, path)`)
39
+ * ask without a cast.
40
+ *
41
+ * Empty for an item the config owns. Reads never need it — `resolveFieldValue` chases a local and a
42
+ * sourced ref identically — so a caller asking whether this is non-empty is a WRITER, gating an edit
43
+ * that would turn someone else's value into a copy of itself. A caller wanting to NAME where it comes
44
+ * from asks {@link source}.
45
+ */
46
+ readonly sources: readonly string[];
47
+ /**
48
+ * The dependency this item is borrowed FROM — `undefined` for one this config authored, and that
49
+ * includes one whose own fields point through a link. The framework installs this computed on every
50
+ * kind too, so it is declared here beside {@link sources}.
51
+ *
52
+ * The pair is easy to conflate and gates opposite things. `sources` is about the VALUE: it says a
53
+ * badge should name another system, and it is set for `{ value: token:accent@ds }` — a pointer this
54
+ * config wrote, into someone else's token. This is about the ENTITY: it is set only when the item is
55
+ * stored AS a pointer (`Token.ref('accent@ds').extend({ … })`), which makes the item the source's
56
+ * with our fields laid over it.
57
+ *
58
+ * So a WRITER asks this one. Gating on `sources` locks the first case, where nothing but our own
59
+ * artifact changes when the ref is retargeted — which is how repointing a local alias came to be
60
+ * impossible in the token rail. See `borrowedSlug`.
61
+ */
62
+ readonly borrowedFrom: string | undefined;
63
+ constructor(path: string, raw: Record<string, unknown>, fieldKeys: readonly string[],
64
+ /**
65
+ * VIRTUAL fields — read like any other, and deliberately absent from {@link toJSON}.
66
+ *
67
+ * The split is the whole point of having them separately. A computed field is a function of the
68
+ * entity and its config, so persisting one writes a derivation into the artifact: it goes stale the
69
+ * moment either input changes, and the stale copy wins on the next hydrate. Provenance is the
70
+ * clearest case — whether an item borrows is read off the source qualifier in its own fields, so a
71
+ * stored answer could contradict the value sitting next to it.
72
+ */
73
+ computedKeys?: readonly string[]);
74
+ /**
75
+ * The ONE source this item comes from, or `undefined` when it comes from none — what a surface names
76
+ * when it says where something came from.
77
+ *
78
+ * Folds BOTH ways an item can involve another system, because a provenance surface does not care
79
+ * which: an item borrowed and locally extended came from its source, and an item we authored whose
80
+ * value points into a source draws from it. Reading only {@link sources} left a borrowed COMPONENT
81
+ * unbadged, because resolving an extension merges the source's own literal fields in and there is no
82
+ * qualified ref left to find.
83
+ *
84
+ * `undefined` when the answer is not unanimous, which is the case worth stating: an item involving two
85
+ * systems has no single answer, and naming either would label the other wrongly. That is the same rule
86
+ * a group follows — see `Config.groupSource`.
87
+ *
88
+ * NOT the write gate. Whose the item is has one answer and it is {@link borrowedFrom}.
89
+ *
90
+ * A getter rather than a computed field so there is one walk and one stored answer; this is a read of
91
+ * it.
92
+ */
93
+ get source(): string | undefined;
94
+ /** The pin a copied entity came through — the `@<slug>` half of {@link copiedFrom}. */
95
+ get copiedThrough(): string | undefined;
96
+ /** The path a copied entity was taken from, as the source spells it — the half of {@link copiedFrom}
97
+ * before the `@`. */
98
+ get copiedPath(): string | undefined;
99
+ /** Identity is the whole qualified path (`color/brand`). */
100
+ get identity(): string;
101
+ /** The emergent group — everything before the last segment (`color/brand` → `color`);
102
+ * `undefined` for a top-level item. Membership is never stored, only derived. */
103
+ get group(): string | undefined;
104
+ /** The bare last segment (`color/brand` → `brand`) — what a UI renders. */
105
+ get leaf(): string;
106
+ /**
107
+ * What a UI calls this item: its authored `label` field, else the bare
108
+ * {@link leaf}. Never identity — a label is metadata and two items may share
109
+ * one — and never a `kind:` marker, which no person should read.
110
+ */
111
+ get displayLabel(): string;
112
+ /**
113
+ * This item's declared fields as a plain bag.
114
+ *
115
+ * For a reader whose KIND is only known at runtime — a prompt catalogue walking every kind, an op
116
+ * form rendering whatever collection its tool names. A reader that knows the kind asks the entity
117
+ * class instead (`Component.get(config, path).styles`), which answers typed.
118
+ *
119
+ * Deliberately not `toJSON`: serialization is for storage and the wire, and a display surface
120
+ * reaching for it is how a raw-shape cast gets in. (No kind declares a field called `body`; one
121
+ * that did would shadow this, since fields are assigned as own properties.)
122
+ */
123
+ get body(): Record<string, unknown>;
124
+ toJSON(): Record<string, unknown>;
125
+ }
126
+ //#endregion
127
+ export { Entity };
@@ -0,0 +1,125 @@
1
+ //#region src/framework/Entity.ts
2
+ /**
3
+ * One flat, path-keyed entity — an item or a group node. The base owns hydration and
4
+ * serialization from the kind's declared field names, so a kind adds no per-entity ctor
5
+ * or `toJSON`. Identity IS the qualified path; the group is simply its prefix.
6
+ */
7
+ var Entity = class {
8
+ label;
9
+ description;
10
+ /** Where a copied entity was taken from, as `<path>@<slug>`; `undefined` for one authored here. */
11
+ copiedFrom;
12
+ /** Kept and resolving, but not offered by authoring surfaces. This entity's own flag only; the
13
+ * answer that also reads its folders and its pin is `Config.hidden`. */
14
+ hidden;
15
+ /** Withdrawn from new work: hidden, and every existing use flagged. This entity's own flag only;
16
+ * the answer that also reads its folders is `Config.deprecated`. */
17
+ deprecated;
18
+ /** How to use this entity, as prose for a model. Collected into the guidance document per kind. */
19
+ guidance;
20
+ constructor(path, raw, fieldKeys, computedKeys = []) {
21
+ this.path = path;
22
+ this.fieldKeys = fieldKeys;
23
+ this.computedKeys = computedKeys;
24
+ const hydrated = {};
25
+ for (const key of [...fieldKeys, ...computedKeys]) if (raw[key] !== void 0) hydrated[key] = raw[key];
26
+ Object.assign(this, hydrated);
27
+ this.label = raw.label;
28
+ this.description = raw.description;
29
+ this.copiedFrom = raw.copiedFrom;
30
+ this.hidden = raw.hidden;
31
+ this.deprecated = raw.deprecated;
32
+ this.guidance = raw.guidance;
33
+ }
34
+ /**
35
+ * The ONE source this item comes from, or `undefined` when it comes from none — what a surface names
36
+ * when it says where something came from.
37
+ *
38
+ * Folds BOTH ways an item can involve another system, because a provenance surface does not care
39
+ * which: an item borrowed and locally extended came from its source, and an item we authored whose
40
+ * value points into a source draws from it. Reading only {@link sources} left a borrowed COMPONENT
41
+ * unbadged, because resolving an extension merges the source's own literal fields in and there is no
42
+ * qualified ref left to find.
43
+ *
44
+ * `undefined` when the answer is not unanimous, which is the case worth stating: an item involving two
45
+ * systems has no single answer, and naming either would label the other wrongly. That is the same rule
46
+ * a group follows — see `Config.groupSource`.
47
+ *
48
+ * NOT the write gate. Whose the item is has one answer and it is {@link borrowedFrom}.
49
+ *
50
+ * A getter rather than a computed field so there is one walk and one stored answer; this is a read of
51
+ * it.
52
+ */
53
+ get source() {
54
+ if (this.borrowedFrom !== void 0) return this.borrowedFrom;
55
+ return this.sources.length === 1 ? this.sources[0] : void 0;
56
+ }
57
+ /** The pin a copied entity came through — the `@<slug>` half of {@link copiedFrom}. */
58
+ get copiedThrough() {
59
+ const at = this.copiedFrom?.lastIndexOf("@") ?? -1;
60
+ return at === -1 ? void 0 : this.copiedFrom?.slice(at + 1);
61
+ }
62
+ /** The path a copied entity was taken from, as the source spells it — the half of {@link copiedFrom}
63
+ * before the `@`. */
64
+ get copiedPath() {
65
+ const at = this.copiedFrom?.lastIndexOf("@") ?? -1;
66
+ return at === -1 ? void 0 : this.copiedFrom?.slice(0, at);
67
+ }
68
+ /** Identity is the whole qualified path (`color/brand`). */
69
+ get identity() {
70
+ return this.path;
71
+ }
72
+ /** The emergent group — everything before the last segment (`color/brand` → `color`);
73
+ * `undefined` for a top-level item. Membership is never stored, only derived. */
74
+ get group() {
75
+ const slash = this.path.lastIndexOf("/");
76
+ return slash === -1 ? void 0 : this.path.slice(0, slash);
77
+ }
78
+ /** The bare last segment (`color/brand` → `brand`) — what a UI renders. */
79
+ get leaf() {
80
+ const slash = this.path.lastIndexOf("/");
81
+ return slash === -1 ? this.path : this.path.slice(slash + 1);
82
+ }
83
+ /**
84
+ * What a UI calls this item: its authored `label` field, else the bare
85
+ * {@link leaf}. Never identity — a label is metadata and two items may share
86
+ * one — and never a `kind:` marker, which no person should read.
87
+ */
88
+ get displayLabel() {
89
+ const label = this.label?.trim();
90
+ return label ? label : this.leaf;
91
+ }
92
+ /**
93
+ * This item's declared fields as a plain bag.
94
+ *
95
+ * For a reader whose KIND is only known at runtime — a prompt catalogue walking every kind, an op
96
+ * form rendering whatever collection its tool names. A reader that knows the kind asks the entity
97
+ * class instead (`Component.get(config, path).styles`), which answers typed.
98
+ *
99
+ * Deliberately not `toJSON`: serialization is for storage and the wire, and a display surface
100
+ * reaching for it is how a raw-shape cast gets in. (No kind declares a field called `body`; one
101
+ * that did would shadow this, since fields are assigned as own properties.)
102
+ */
103
+ get body() {
104
+ return this.#bag([...this.fieldKeys, ...this.computedKeys]);
105
+ }
106
+ toJSON() {
107
+ return this.#bag(this.fieldKeys);
108
+ }
109
+ /** The fields named by `keys`, as a plain bag. `body` and `toJSON` differ only in which keys they
110
+ * ask for — the READ shape includes computeds, the WIRE shape cannot. */
111
+ #bag(keys) {
112
+ const self = this;
113
+ const out = {};
114
+ for (const key of keys) if (self[key] !== void 0) out[key] = self[key];
115
+ if (this.label !== void 0) out.label = this.label;
116
+ if (this.description !== void 0) out.description = this.description;
117
+ if (this.copiedFrom !== void 0) out.copiedFrom = this.copiedFrom;
118
+ if (this.hidden !== void 0) out.hidden = this.hidden;
119
+ if (this.deprecated !== void 0) out.deprecated = this.deprecated;
120
+ if (this.guidance !== void 0) out.guidance = this.guidance;
121
+ return out;
122
+ }
123
+ };
124
+ //#endregion
125
+ export { Entity };
@@ -0,0 +1,24 @@
1
+ //#region src/framework/authoring.d.ts
2
+ /**
3
+ * The bridge between any typed authoring surface and the live `Config`.
4
+ *
5
+ * An authoring API (like `defineComponent`) produces sugar — markers, builders, handles —
6
+ * that isn't the entity's stored shape. `Authored` is the one contract that lets `Config`
7
+ * ingest ANY such output without knowing its specifics: it exposes the target `kind`, a
8
+ * `toStored()` that normalizes the sugar into the entity's wire def (validated on the way
9
+ * in like any create), and an optional `assignPath` so a ref-handle can adopt its
10
+ * qualified identity at registration (enabling cross-references).
11
+ *
12
+ * New authoring APIs need only return an `Authored`; `Config.author` (see Config.ts) and
13
+ * the rest of the system stay unchanged.
14
+ */
15
+ interface Authored {
16
+ readonly kind: string;
17
+ /** Normalize the authoring sugar into the entity's stored/wire def. */
18
+ toStored(): Record<string, unknown>;
19
+ /** Adopt the qualified path assigned at registration (so refs to this resolve). */
20
+ assignPath?(path: string): void;
21
+ }
22
+ declare function isAuthored(value: unknown): value is Authored;
23
+ //#endregion
24
+ export { Authored, isAuthored };
@@ -0,0 +1,7 @@
1
+ //#region src/framework/authoring.ts
2
+ function isAuthored(value) {
3
+ if (typeof value !== "object" && typeof value !== "function") return false;
4
+ return value !== null && "kind" in value && typeof value.toStored === "function";
5
+ }
6
+ //#endregion
7
+ export { isAuthored };
@@ -0,0 +1,119 @@
1
+ import { Config } from "./Config.js";
2
+
3
+ //#region src/framework/change-hooks.d.ts
4
+ /**
5
+ * The previous result, and the config it came from.
6
+ *
7
+ * `from` is what makes a cheap path expressible at all — a delta needs the state it is a delta from.
8
+ * A hook that keeps a partial result must keep the config that part came from with it, not accept
9
+ * `from` as the base: after one cheap run, `from` is the config the cheap run answered, which is no
10
+ * longer the state the kept part describes. (`stylesOnChange` carries a `base` in its value for
11
+ * exactly this reason — the overlay is always a delta from the sheet's own config, never from the
12
+ * previous edit.)
13
+ */
14
+ interface LastDerived<T> {
15
+ readonly from: Config;
16
+ readonly value: T;
17
+ }
18
+ /**
19
+ * When a scheduled derivation actually runs.
20
+ *
21
+ * `'idle'` is the editor answer: after the frame the edit landed on, so the click paints first.
22
+ * `'sync'` runs it immediately, which is what a test and a server want. A function is anything else.
23
+ */
24
+ type ChangeSchedule = 'sync' | 'idle' | ((fire: () => void) => void);
25
+ /** One derived value that follows the config. */
26
+ interface ChangeHook<C extends Config = Config, T = unknown> {
27
+ /**
28
+ * Every kind the derivation can reach, including ones it only touches by chasing refs. A change
29
+ * that moves none of them is skipped, so under-declaring means a paint that never happens —
30
+ * declare the same list the memo inside `run` declares.
31
+ */
32
+ readonly kinds: readonly string[];
33
+ /**
34
+ * Declared as a method rather than as a function property on purpose: method parameters are checked
35
+ * bivariantly, which is what lets a `ChangeHook<C, LiveStyles>` sit in a map of
36
+ * `ChangeHook<C, unknown>` without an `any` to paper over the variance.
37
+ */
38
+ run(config: C, last: LastDerived<T> | undefined): T | Promise<T>;
39
+ /** Default `'sync'`: a caller that wants the derivation off the interaction path asks for it. */
40
+ readonly schedule?: ChangeSchedule;
41
+ }
42
+ /** Where the live config comes from — a session, a store, anything that can be read and watched. */
43
+ interface ConfigFeed<C extends Config = Config> {
44
+ current(): C | null;
45
+ subscribe(listener: () => void): () => void;
46
+ }
47
+ /**
48
+ * A set of hooks, keyed by the name their result is read under.
49
+ *
50
+ * The entries are heterogeneous — each produces its own type — so the map is stated at `unknown` and
51
+ * the real type is recovered at the read by {@link DerivedOf}, off the literal type of what the caller
52
+ * passed. That is why `run` is a method: it makes this widening legal without an `any`.
53
+ */
54
+ type ChangeHookMap<C extends Config> = Record<string, ChangeHook<C, unknown>>;
55
+ /** The result type an entry of the map produces, so `derived('styles')` is typed without a cast. */
56
+ type DerivedOf<H> = H extends ChangeHook<Config, infer T> ? T : never;
57
+ /** What registering a hook set hands back: the values, a way to watch them, and the teardown. */
58
+ interface ChangeHookRun<H> {
59
+ /** The current value, or `undefined` before the first run has published one. */
60
+ derived<K extends keyof H>(name: K): DerivedOf<H[K]> | undefined;
61
+ /**
62
+ * Called on every publish, and immediately with the current value if there already is one.
63
+ *
64
+ * The replay is what makes this safe to use from an effect: a sink that only heard about future
65
+ * publishes would miss the derivation that ran before it mounted, and the miss looks exactly like
66
+ * a value that never derived. Returns the disposer.
67
+ */
68
+ onDerived<K extends keyof H>(name: K, listener: (value: DerivedOf<H[K]>) => void): () => void;
69
+ /** Stop watching and drop anything scheduled. Safe to call twice. */
70
+ dispose(): void;
71
+ }
72
+ interface ChangeHookOptions {
73
+ /**
74
+ * A derivation that threw. Never swallowed silently: the surface waiting on the value is showing
75
+ * something stale, and only the caller knows how to say so.
76
+ */
77
+ readonly onError?: (name: string, error: unknown) => void;
78
+ }
79
+ /**
80
+ * A hook must not move what it reads — the one way to use this that does not terminate.
81
+ *
82
+ * The skip test below keys on {@link sliceKeys}, which includes every attached source by identity —
83
+ * load-bearing, since a config that swapped a source has the same slices and different data. A hook
84
+ * whose published value is applied back onto the feed, and that changes one of those keys, re-triggers
85
+ * itself: the driver cannot tell that cycle from ordinary progress, since each run sees genuinely
86
+ * different keys and is genuinely not skippable. A hook that fetches sources and attaches them, for
87
+ * instance, mints a fresh `Config` per answer — an unbounded loop of requests, paced only by network
88
+ * latency.
89
+ *
90
+ * So a hook that derives a value something else writes back into the same feed owns the fixed point:
91
+ * it must compare against what is already there and write nothing when the answer hasn't moved.
92
+ * There's no guard here, because "the value changed" and "the value changed because I changed it" are
93
+ * the same event from this side.
94
+ */
95
+ /**
96
+ * Run `hooks` against `feed` until disposed.
97
+ *
98
+ * Each entry gets its own coalescer, so a slow derivation cannot hold up a fast one, and each is
99
+ * driven by the key of what it declares it reads rather than by config identity. That distinction is
100
+ * the whole correctness argument:
101
+ *
102
+ * - **Skipping.** A config change that moves none of a hook's kinds cannot change its result, so
103
+ * there is nothing to run.
104
+ * - **Discarding.** A result computed for a config the feed has moved past is only stale if the
105
+ * newer config reads differently — and if it does, the change that superseded it will run. Keyed
106
+ * on config identity instead, a result would be discarded by an edit its own kinds never saw
107
+ * (a label, a description) and then never recomputed, because the follow-up run would be skipped
108
+ * by the rule above. That combination is a canvas that silently stops repainting.
109
+ */
110
+ declare function runChangeHooks<C extends Config, H extends ChangeHookMap<C>>({
111
+ feed,
112
+ hooks,
113
+ onError
114
+ }: {
115
+ readonly feed: ConfigFeed<C>;
116
+ readonly hooks: H;
117
+ } & ChangeHookOptions): ChangeHookRun<H>;
118
+ //#endregion
119
+ export { ChangeHook, ChangeHookMap, ChangeHookRun, runChangeHooks };
@@ -0,0 +1,131 @@
1
+ import { sameSliceKeys, sliceKeys } from "./memo.js";
2
+ import { coalesceLatest } from "./coalesce.js";
3
+ //#region src/framework/change-hooks.ts
4
+ /** How long an idle derivation can be held back — one frame's worth, so the canvas repaints in the
5
+ * same beat as the panel rather than whenever the tab next goes quiet. */
6
+ const IDLE_TIMEOUT_MS = 48;
7
+ function scheduler(schedule) {
8
+ if (typeof schedule === "function") return schedule;
9
+ if (schedule === "sync") return (fire) => fire();
10
+ return (fire) => {
11
+ if (typeof requestIdleCallback === "function") {
12
+ requestIdleCallback(fire, { timeout: IDLE_TIMEOUT_MS });
13
+ return;
14
+ }
15
+ setTimeout(fire, 0);
16
+ };
17
+ }
18
+ /**
19
+ * A hook must not move what it reads — the one way to use this that does not terminate.
20
+ *
21
+ * The skip test below keys on {@link sliceKeys}, which includes every attached source by identity —
22
+ * load-bearing, since a config that swapped a source has the same slices and different data. A hook
23
+ * whose published value is applied back onto the feed, and that changes one of those keys, re-triggers
24
+ * itself: the driver cannot tell that cycle from ordinary progress, since each run sees genuinely
25
+ * different keys and is genuinely not skippable. A hook that fetches sources and attaches them, for
26
+ * instance, mints a fresh `Config` per answer — an unbounded loop of requests, paced only by network
27
+ * latency.
28
+ *
29
+ * So a hook that derives a value something else writes back into the same feed owns the fixed point:
30
+ * it must compare against what is already there and write nothing when the answer hasn't moved.
31
+ * There's no guard here, because "the value changed" and "the value changed because I changed it" are
32
+ * the same event from this side.
33
+ */
34
+ /**
35
+ * Run `hooks` against `feed` until disposed.
36
+ *
37
+ * Each entry gets its own coalescer, so a slow derivation cannot hold up a fast one, and each is
38
+ * driven by the key of what it declares it reads rather than by config identity. That distinction is
39
+ * the whole correctness argument:
40
+ *
41
+ * - **Skipping.** A config change that moves none of a hook's kinds cannot change its result, so
42
+ * there is nothing to run.
43
+ * - **Discarding.** A result computed for a config the feed has moved past is only stale if the
44
+ * newer config reads differently — and if it does, the change that superseded it will run. Keyed
45
+ * on config identity instead, a result would be discarded by an edit its own kinds never saw
46
+ * (a label, a description) and then never recomputed, because the follow-up run would be skipped
47
+ * by the rule above. That combination is a canvas that silently stops repainting.
48
+ */
49
+ function runChangeHooks({ feed, hooks, onError }) {
50
+ const values = /* @__PURE__ */ new Map();
51
+ const listeners = /* @__PURE__ */ new Map();
52
+ const requests = [];
53
+ const cancels = [];
54
+ let disposed = false;
55
+ for (const [name, hook] of Object.entries(hooks)) {
56
+ let last;
57
+ let lastKeys;
58
+ const publish = (value, from) => {
59
+ last = {
60
+ from,
61
+ value
62
+ };
63
+ values.set(name, value);
64
+ for (const listener of listeners.get(name) ?? []) listener(value);
65
+ };
66
+ const derive = coalesceLatest({
67
+ schedule: scheduler(hook.schedule ?? "sync"),
68
+ run: async (config) => {
69
+ const keys = sliceKeys({
70
+ config,
71
+ kinds: hook.kinds
72
+ });
73
+ if (lastKeys && sameSliceKeys({
74
+ before: lastKeys,
75
+ after: keys
76
+ })) return;
77
+ let value;
78
+ try {
79
+ value = await hook.run(config, last);
80
+ } catch (error) {
81
+ onError?.(name, error);
82
+ return;
83
+ }
84
+ const live = feed.current();
85
+ if (disposed || !live || !sameSliceKeys({
86
+ before: keys,
87
+ after: sliceKeys({
88
+ config: live,
89
+ kinds: hook.kinds
90
+ })
91
+ })) return;
92
+ lastKeys = keys;
93
+ publish(value, config);
94
+ }
95
+ });
96
+ requests.push(derive);
97
+ cancels.push(derive.cancel);
98
+ }
99
+ const request = () => {
100
+ const config = feed.current();
101
+ if (!config || disposed) return;
102
+ for (const derive of requests) derive(config);
103
+ };
104
+ request();
105
+ const unsubscribe = feed.subscribe(request);
106
+ return {
107
+ derived: (name) => values.get(String(name)),
108
+ onDerived: (name, listener) => {
109
+ const key = String(name);
110
+ let set = listeners.get(key);
111
+ if (!set) {
112
+ set = /* @__PURE__ */ new Set();
113
+ listeners.set(key, set);
114
+ }
115
+ set.add(listener);
116
+ if (values.has(key)) listener(values.get(key));
117
+ return () => {
118
+ set?.delete(listener);
119
+ };
120
+ },
121
+ dispose: () => {
122
+ if (disposed) return;
123
+ disposed = true;
124
+ unsubscribe();
125
+ for (const cancel of cancels) cancel();
126
+ listeners.clear();
127
+ }
128
+ };
129
+ }
130
+ //#endregion
131
+ export { runChangeHooks };
@@ -0,0 +1,88 @@
1
+ import { StampedPatch } from "./overlay.js";
2
+ import { Config } from "./Config.js";
3
+
4
+ //#region src/framework/changes.d.ts
5
+ /** What a patch addresses: one item, one group node, or a kind's order. */
6
+ type ChangeTarget = 'item' | 'group' | 'order';
7
+ interface Change {
8
+ /** The pending patch's id — what `ConfigSession.drop` takes. */
9
+ readonly id: string;
10
+ /** The gesture that wrote this patch alongside others, when it was one of several. */
11
+ readonly changeset?: string;
12
+ readonly kind: string;
13
+ readonly operation: string;
14
+ readonly target: ChangeTarget;
15
+ /** The item or group path the patch addresses. Absent for a reorder, which names no one path. */
16
+ readonly path?: string;
17
+ /** Where a rename moved the path. */
18
+ readonly to?: string;
19
+ /**
20
+ * The dotted path within the body the patch wrote, when it wrote one place: a partial write's
21
+ * single key (`modifiers.dark`), or a sub-op's member (`layers.root`). Absent when the patch wrote
22
+ * the whole body or several fields, in which case `before` and `after` are bodies.
23
+ */
24
+ readonly field?: string;
25
+ /** The value on the base. `undefined` when the path did not exist there. */
26
+ readonly before: unknown;
27
+ /** The value on the draft. `undefined` when the path no longer exists. */
28
+ readonly after: unknown;
29
+ }
30
+ /** The base as a config of its own — the branch with no draft applied. */
31
+ declare function baseOf(config: Config): Config;
32
+ /** The value a change addresses in one config — the body, or the field within it. */
33
+ declare function changeValueAt({
34
+ config,
35
+ change,
36
+ side
37
+ }: {
38
+ config: Config;
39
+ change: Pick<Change, 'kind' | 'path' | 'field' | 'target'>;
40
+ side: 'before' | 'after';
41
+ }): unknown;
42
+ /** One pending patch as a change, with its values read off `base` and `draft`. */
43
+ declare function changeOf(entry: StampedPatch, {
44
+ base,
45
+ draft
46
+ }: {
47
+ base: Config;
48
+ draft: Config;
49
+ }): Change;
50
+ /** Every pending patch of `config` as a change, in draft order. */
51
+ declare function changesOf(config: Config, base?: Config): Change[];
52
+ /**
53
+ * What a set of changes on one entity did, in words — the line a card carries under the entity's
54
+ * name. `entity` is the path the changes are grouped under, which may be a prefix of what each
55
+ * change addresses (a token group over its tokens) or the item itself (a component).
56
+ */
57
+ declare function summarizeChanges({
58
+ config,
59
+ kind,
60
+ entity,
61
+ changes
62
+ }: {
63
+ config: Config;
64
+ kind: string; /** The grouping path; absent when the changes are a kind's order. */
65
+ entity: string | undefined;
66
+ changes: readonly Change[];
67
+ }): string;
68
+ /**
69
+ * A body summarized as what it contains — the cell for a created or deleted container, where the
70
+ * body itself is too much to show. `undefined` for a value that is not a body.
71
+ *
72
+ * `config` is the one the body was read from, since a group's members are counted there.
73
+ */
74
+ declare function describeBody({
75
+ config,
76
+ kind,
77
+ path,
78
+ target,
79
+ value
80
+ }: {
81
+ config: Config;
82
+ kind: string;
83
+ path: string;
84
+ target: ChangeTarget;
85
+ value: unknown;
86
+ }): string | undefined;
87
+ //#endregion
88
+ export { Change, ChangeTarget, baseOf, changeOf, changeValueAt, changesOf, describeBody, summarizeChanges };