@microsoft/fast-element 2.10.4 → 3.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +1 -1
  2. package/ARCHITECTURE_OVERVIEW.md +2 -2
  3. package/CHANGELOG.json +1 -1
  4. package/CHANGELOG.md +2 -2
  5. package/DECLARATIVE_DESIGN.md +806 -0
  6. package/DECLARATIVE_HTML.md +470 -0
  7. package/DECLARATIVE_MIGRATION.md +215 -0
  8. package/DECLARATIVE_RENDERING.md +530 -0
  9. package/DECLARATIVE_RENDERING_LIFECYCLE.md +288 -0
  10. package/DECLARATIVE_SCHEMA_OBSERVER_MAP.md +489 -0
  11. package/DESIGN.md +138 -33
  12. package/MIGRATION.md +387 -0
  13. package/README.md +208 -1
  14. package/SIZES.md +25 -0
  15. package/api-extractor.arrays.json +15 -0
  16. package/api-extractor.context.json +1 -0
  17. package/api-extractor.declarative.json +15 -0
  18. package/api-extractor.di.json +1 -0
  19. package/api-extractor.hydration.json +15 -0
  20. package/api-extractor.styles.json +15 -0
  21. package/dist/arrays/arrays.api.json +2621 -0
  22. package/dist/declarative/declarative.api.json +7844 -0
  23. package/dist/di/di.api.json +1 -1
  24. package/dist/dts/array-observer.d.ts +2 -0
  25. package/dist/dts/arrays.d.ts +2 -0
  26. package/dist/dts/attr.d.ts +1 -0
  27. package/dist/dts/binding/signal.d.ts +6 -6
  28. package/dist/dts/binding/two-way.d.ts +1 -0
  29. package/dist/dts/binding.d.ts +7 -0
  30. package/dist/dts/components/attributes.d.ts +2 -5
  31. package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
  32. package/dist/dts/components/element-controller.d.ts +80 -114
  33. package/dist/dts/components/element-hydration.d.ts +1 -1
  34. package/dist/dts/components/enable-hydration.d.ts +34 -0
  35. package/dist/dts/components/fast-definitions.d.ts +91 -42
  36. package/dist/dts/components/fast-element.d.ts +5 -8
  37. package/dist/dts/components/hydration-tracker.d.ts +40 -0
  38. package/dist/dts/components/hydration.d.ts +18 -53
  39. package/dist/dts/components/schema.d.ts +205 -0
  40. package/dist/dts/context.d.ts +6 -6
  41. package/dist/dts/css.d.ts +3 -0
  42. package/dist/dts/debug.d.ts +5 -1
  43. package/dist/dts/declarative/attribute-map.d.ts +58 -0
  44. package/dist/dts/declarative/debug.d.ts +5 -0
  45. package/dist/dts/declarative/index.d.ts +13 -0
  46. package/dist/dts/declarative/interfaces.d.ts +9 -0
  47. package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
  48. package/dist/dts/declarative/observer-map.d.ts +89 -0
  49. package/dist/dts/declarative/runtime.d.ts +5 -0
  50. package/dist/dts/declarative/syntax.d.ts +21 -0
  51. package/dist/dts/declarative/template-bridge.d.ts +33 -0
  52. package/dist/dts/declarative/template-parser.d.ts +98 -0
  53. package/dist/dts/declarative/template.d.ts +9 -0
  54. package/dist/dts/declarative/utilities.d.ts +312 -0
  55. package/dist/dts/di/di.d.ts +1 -1
  56. package/dist/dts/directives/children.d.ts +2 -0
  57. package/dist/dts/directives/node-observation.d.ts +2 -0
  58. package/dist/dts/directives/ref.d.ts +2 -0
  59. package/dist/dts/directives/repeat.d.ts +4 -0
  60. package/dist/dts/directives/slotted.d.ts +2 -0
  61. package/dist/dts/directives/when.d.ts +3 -0
  62. package/dist/dts/dom-policy.d.ts +1 -1
  63. package/dist/dts/html.d.ts +5 -0
  64. package/dist/dts/hydration/runtime.d.ts +7 -0
  65. package/dist/dts/hydration/target-builder.d.ts +15 -12
  66. package/dist/dts/hydration.d.ts +14 -0
  67. package/dist/dts/index.d.ts +38 -42
  68. package/dist/dts/index.debug.d.ts +0 -1
  69. package/dist/dts/index.rollup.debug.d.ts +0 -1
  70. package/dist/dts/interfaces.d.ts +1 -49
  71. package/dist/dts/observable.d.ts +3 -6
  72. package/dist/dts/observation/arrays.d.ts +1 -1
  73. package/dist/dts/observation/update-queue.d.ts +1 -1
  74. package/dist/dts/platform.d.ts +25 -4
  75. package/dist/dts/render.d.ts +7 -0
  76. package/dist/dts/schema.d.ts +1 -0
  77. package/dist/dts/state/exports.d.ts +1 -1
  78. package/dist/dts/state/state.d.ts +2 -2
  79. package/dist/dts/styles/css-directive.d.ts +5 -12
  80. package/dist/dts/styles/css.d.ts +5 -7
  81. package/dist/dts/styles/element-styles.d.ts +0 -10
  82. package/dist/dts/styles.d.ts +6 -0
  83. package/dist/dts/templating/children.d.ts +1 -1
  84. package/dist/dts/templating/html-binding-directive.d.ts +4 -0
  85. package/dist/dts/templating/html-directive.d.ts +17 -0
  86. package/dist/dts/templating/hydration-view.d.ts +109 -0
  87. package/dist/dts/templating/ref.d.ts +1 -1
  88. package/dist/dts/templating/render.d.ts +1 -1
  89. package/dist/dts/templating/repeat.d.ts +2 -2
  90. package/dist/dts/templating/slotted.d.ts +1 -1
  91. package/dist/dts/templating/template.d.ts +17 -9
  92. package/dist/dts/templating/view.d.ts +25 -102
  93. package/dist/dts/templating/when.d.ts +1 -1
  94. package/dist/dts/templating.d.ts +10 -0
  95. package/dist/dts/testing/exports.d.ts +2 -2
  96. package/dist/dts/updates.d.ts +1 -0
  97. package/dist/dts/volatile.d.ts +2 -0
  98. package/dist/esm/array-observer.js +1 -0
  99. package/dist/esm/arrays.js +1 -0
  100. package/dist/esm/attr.js +1 -0
  101. package/dist/esm/binding/normalize.js +1 -1
  102. package/dist/esm/binding/signal.js +4 -4
  103. package/dist/esm/binding/two-way.js +2 -1
  104. package/dist/esm/binding.js +4 -0
  105. package/dist/esm/components/attributes.js +8 -5
  106. package/dist/esm/components/definition-schema-transforms.js +23 -0
  107. package/dist/esm/components/element-controller.js +200 -269
  108. package/dist/esm/components/element-hydration.js +1 -1
  109. package/dist/esm/components/enable-hydration.js +100 -0
  110. package/dist/esm/components/fast-definitions.js +211 -49
  111. package/dist/esm/components/fast-element.js +18 -27
  112. package/dist/esm/components/hydration-tracker.js +93 -0
  113. package/dist/esm/components/hydration.js +62 -144
  114. package/dist/esm/components/schema.js +253 -0
  115. package/dist/esm/context.js +6 -6
  116. package/dist/esm/css.js +3 -0
  117. package/dist/esm/debug.js +26 -26
  118. package/dist/esm/declarative/attribute-map.js +121 -0
  119. package/dist/esm/declarative/debug.js +5 -0
  120. package/dist/esm/declarative/index.js +3 -0
  121. package/dist/esm/declarative/interfaces.js +10 -0
  122. package/dist/esm/declarative/observer-map-utilities.js +562 -0
  123. package/dist/esm/declarative/observer-map.js +216 -0
  124. package/dist/esm/declarative/runtime.js +14 -0
  125. package/dist/esm/declarative/syntax.js +36 -0
  126. package/dist/esm/declarative/template-bridge.js +170 -0
  127. package/dist/esm/declarative/template-parser.js +306 -0
  128. package/dist/esm/declarative/template.js +142 -0
  129. package/dist/esm/declarative/utilities.js +834 -0
  130. package/dist/esm/di/di.js +6 -8
  131. package/dist/esm/directives/children.js +1 -0
  132. package/dist/esm/directives/node-observation.js +1 -0
  133. package/dist/esm/directives/ref.js +1 -0
  134. package/dist/esm/directives/repeat.js +1 -0
  135. package/dist/esm/directives/slotted.js +1 -0
  136. package/dist/esm/directives/when.js +1 -0
  137. package/dist/esm/dom-policy.js +2 -2
  138. package/dist/esm/dom.js +1 -1
  139. package/dist/esm/html.js +2 -0
  140. package/dist/esm/hydration/runtime.js +33 -0
  141. package/dist/esm/hydration/target-builder.js +97 -90
  142. package/dist/esm/hydration.js +4 -0
  143. package/dist/esm/index.debug.js +2 -1
  144. package/dist/esm/index.js +34 -29
  145. package/dist/esm/index.rollup.debug.js +3 -2
  146. package/dist/esm/index.rollup.js +1 -1
  147. package/dist/esm/interfaces.js +1 -45
  148. package/dist/esm/observable.js +1 -4
  149. package/dist/esm/observation/arrays.js +1 -1
  150. package/dist/esm/observation/observable.js +5 -5
  151. package/dist/esm/observation/update-queue.js +47 -58
  152. package/dist/esm/platform.js +31 -30
  153. package/dist/esm/render.js +1 -0
  154. package/dist/esm/schema.js +1 -0
  155. package/dist/esm/state/exports.js +1 -1
  156. package/dist/esm/styles/css-directive.js +1 -2
  157. package/dist/esm/styles/css.js +15 -56
  158. package/dist/esm/styles/element-styles.js +69 -15
  159. package/dist/esm/styles.js +2 -0
  160. package/dist/esm/templating/html-binding-directive.js +10 -8
  161. package/dist/esm/templating/hydration-view.js +235 -0
  162. package/dist/esm/templating/render.js +1 -1
  163. package/dist/esm/templating/repeat.js +36 -34
  164. package/dist/esm/templating/template.js +7 -7
  165. package/dist/esm/templating/view.js +24 -233
  166. package/dist/esm/templating.js +7 -0
  167. package/dist/esm/testing/exports.js +2 -2
  168. package/dist/esm/updates.js +1 -0
  169. package/dist/esm/volatile.js +1 -0
  170. package/dist/fast-element.api.json +9016 -6995
  171. package/dist/fast-element.d.ts +3557 -796
  172. package/dist/fast-element.debug.js +5088 -4437
  173. package/dist/fast-element.debug.min.js +2 -2
  174. package/dist/fast-element.js +5369 -4649
  175. package/dist/fast-element.min.js +2 -2
  176. package/dist/fast-element.untrimmed.d.ts +863 -475
  177. package/dist/hydration/hydration.api.json +5237 -0
  178. package/dist/styles/styles.api.json +2672 -0
  179. package/docs/api-report.api.md +343 -166
  180. package/docs/arrays/api-report.api.md +114 -0
  181. package/docs/declarative/api-report.api.md +397 -0
  182. package/docs/hydration/api-report.api.md +285 -0
  183. package/docs/styles/api-report.api.md +135 -0
  184. package/package.json +149 -41
  185. package/playwright.declarative.config.ts +26 -0
  186. package/playwright.declarative.webui.config.ts +20 -0
  187. package/scripts/declarative/build-fixtures-with-webui.js +135 -0
  188. package/scripts/declarative/build-fixtures.js +49 -0
  189. package/scripts/declarative/build-fixtures.utilities.js +101 -0
  190. package/scripts/measure-sizes.js +219 -0
  191. package/scripts/run-api-extractor.js +39 -20
  192. package/test/declarative/fixtures/README.md +72 -0
  193. package/test/declarative/fixtures/WRITING_FIXTURES.md +330 -0
  194. package/test/declarative/fixtures/bindings/README.md +12 -0
  195. package/test/declarative/fixtures/bindings/attribute/entry.html +13 -0
  196. package/test/declarative/fixtures/bindings/attribute/fast-build.config.json +6 -0
  197. package/test/declarative/fixtures/bindings/attribute/index.html +25 -0
  198. package/test/declarative/fixtures/bindings/attribute/main.ts +41 -0
  199. package/test/declarative/fixtures/bindings/attribute/state.json +8 -0
  200. package/test/declarative/fixtures/bindings/attribute/templates.html +11 -0
  201. package/test/declarative/fixtures/bindings/content/entry.html +12 -0
  202. package/test/declarative/fixtures/bindings/content/fast-build.config.json +6 -0
  203. package/test/declarative/fixtures/bindings/content/index.html +19 -0
  204. package/test/declarative/fixtures/bindings/content/main.ts +27 -0
  205. package/test/declarative/fixtures/bindings/content/state.json +4 -0
  206. package/test/declarative/fixtures/bindings/content/templates.html +6 -0
  207. package/test/declarative/fixtures/bindings/dot-syntax/entry.html +11 -0
  208. package/test/declarative/fixtures/bindings/dot-syntax/fast-build.config.json +6 -0
  209. package/test/declarative/fixtures/bindings/dot-syntax/index.html +47 -0
  210. package/test/declarative/fixtures/bindings/dot-syntax/main.ts +59 -0
  211. package/test/declarative/fixtures/bindings/dot-syntax/state.json +16 -0
  212. package/test/declarative/fixtures/bindings/dot-syntax/templates.html +17 -0
  213. package/test/declarative/fixtures/bindings/event/entry.html +11 -0
  214. package/test/declarative/fixtures/bindings/event/fast-build.config.json +6 -0
  215. package/test/declarative/fixtures/bindings/event/index.html +43 -0
  216. package/test/declarative/fixtures/bindings/event/main.ts +43 -0
  217. package/test/declarative/fixtures/bindings/event/state.json +3 -0
  218. package/test/declarative/fixtures/bindings/event/templates.html +18 -0
  219. package/test/declarative/fixtures/bindings/host/entry.html +40 -0
  220. package/test/declarative/fixtures/bindings/host/fast-build.config.json +6 -0
  221. package/test/declarative/fixtures/bindings/host/index.html +96 -0
  222. package/test/declarative/fixtures/bindings/host/main.ts +222 -0
  223. package/test/declarative/fixtures/bindings/host/state.json +9 -0
  224. package/test/declarative/fixtures/bindings/host/templates.html +55 -0
  225. package/test/declarative/fixtures/directives/README.md +12 -0
  226. package/test/declarative/fixtures/directives/children/entry.html +11 -0
  227. package/test/declarative/fixtures/directives/children/fast-build.config.json +6 -0
  228. package/test/declarative/fixtures/directives/children/index.html +15 -0
  229. package/test/declarative/fixtures/directives/children/main.ts +22 -0
  230. package/test/declarative/fixtures/directives/children/state.json +3 -0
  231. package/test/declarative/fixtures/directives/children/templates.html +3 -0
  232. package/test/declarative/fixtures/directives/ref/entry.html +11 -0
  233. package/test/declarative/fixtures/directives/ref/fast-build.config.json +6 -0
  234. package/test/declarative/fixtures/directives/ref/index.html +15 -0
  235. package/test/declarative/fixtures/directives/ref/main.ts +17 -0
  236. package/test/declarative/fixtures/directives/ref/state.json +1 -0
  237. package/test/declarative/fixtures/directives/ref/templates.html +3 -0
  238. package/test/declarative/fixtures/directives/repeat/entry.html +21 -0
  239. package/test/declarative/fixtures/directives/repeat/fast-build.config.json +6 -0
  240. package/test/declarative/fixtures/directives/repeat/index.html +133 -0
  241. package/test/declarative/fixtures/directives/repeat/main.ts +110 -0
  242. package/test/declarative/fixtures/directives/repeat/sprites.svg +8 -0
  243. package/test/declarative/fixtures/directives/repeat/state.json +10 -0
  244. package/test/declarative/fixtures/directives/repeat/templates.html +75 -0
  245. package/test/declarative/fixtures/directives/slotted/entry.html +17 -0
  246. package/test/declarative/fixtures/directives/slotted/fast-build.config.json +6 -0
  247. package/test/declarative/fixtures/directives/slotted/index.html +27 -0
  248. package/test/declarative/fixtures/directives/slotted/main.ts +29 -0
  249. package/test/declarative/fixtures/directives/slotted/state.json +1 -0
  250. package/test/declarative/fixtures/directives/slotted/templates.html +7 -0
  251. package/test/declarative/fixtures/directives/when/entry.html +51 -0
  252. package/test/declarative/fixtures/directives/when/fast-build.config.json +6 -0
  253. package/test/declarative/fixtures/directives/when/index.html +136 -0
  254. package/test/declarative/fixtures/directives/when/main.ts +172 -0
  255. package/test/declarative/fixtures/directives/when/state.json +12 -0
  256. package/test/declarative/fixtures/directives/when/templates.html +75 -0
  257. package/test/declarative/fixtures/ecosystem/README.md +11 -0
  258. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/entry.html +12 -0
  259. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/fast-build.config.json +6 -0
  260. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/index.html +20 -0
  261. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/main.ts +68 -0
  262. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/state.json +4 -0
  263. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/templates.html +7 -0
  264. package/test/declarative/fixtures/ecosystem/errors/entry.html +12 -0
  265. package/test/declarative/fixtures/ecosystem/errors/fast-build.config.json +6 -0
  266. package/test/declarative/fixtures/ecosystem/errors/index.html +20 -0
  267. package/test/declarative/fixtures/ecosystem/errors/main.ts +17 -0
  268. package/test/declarative/fixtures/ecosystem/errors/state.json +1 -0
  269. package/test/declarative/fixtures/ecosystem/errors/templates.html +7 -0
  270. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/entry.html +17 -0
  271. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/fast-build.config.json +6 -0
  272. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/index.html +56 -0
  273. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/main.ts +134 -0
  274. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/state.json +12 -0
  275. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/templates.html +34 -0
  276. package/test/declarative/fixtures/ecosystem/performance-metrics/entry.html +25 -0
  277. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-build.config.json +6 -0
  278. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-card.css +10 -0
  279. package/test/declarative/fixtures/ecosystem/performance-metrics/index.html +181 -0
  280. package/test/declarative/fixtures/ecosystem/performance-metrics/main.ts +58 -0
  281. package/test/declarative/fixtures/ecosystem/performance-metrics/state.json +6 -0
  282. package/test/declarative/fixtures/ecosystem/performance-metrics/templates.html +15 -0
  283. package/test/declarative/fixtures/extensions/README.md +15 -0
  284. package/test/declarative/fixtures/extensions/attribute-map/entry.html +14 -0
  285. package/test/declarative/fixtures/extensions/attribute-map/fast-build.config.json +6 -0
  286. package/test/declarative/fixtures/extensions/attribute-map/index.html +31 -0
  287. package/test/declarative/fixtures/extensions/attribute-map/main.ts +40 -0
  288. package/test/declarative/fixtures/extensions/attribute-map/state.json +4 -0
  289. package/test/declarative/fixtures/extensions/attribute-map/templates.html +14 -0
  290. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/entry.html +12 -0
  291. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/fast-build.config.json +7 -0
  292. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/index.html +25 -0
  293. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/main.ts +31 -0
  294. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/state.json +5 -0
  295. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/templates.html +11 -0
  296. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/entry.html +13 -0
  297. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/fast-build.config.json +7 -0
  298. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/index.html +23 -0
  299. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/main.ts +37 -0
  300. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/state.json +1 -0
  301. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/templates.html +9 -0
  302. package/test/declarative/fixtures/extensions/observer-map/entry.html +15 -0
  303. package/test/declarative/fixtures/extensions/observer-map/fast-build.config.json +6 -0
  304. package/test/declarative/fixtures/extensions/observer-map/index.html +442 -0
  305. package/test/declarative/fixtures/extensions/observer-map/main.ts +482 -0
  306. package/test/declarative/fixtures/extensions/observer-map/state.json +158 -0
  307. package/test/declarative/fixtures/extensions/observer-map/templates.html +172 -0
  308. package/test/declarative/fixtures/extensions/observer-map-config-object/entry.html +16 -0
  309. package/test/declarative/fixtures/extensions/observer-map-config-object/fast-build.config.json +6 -0
  310. package/test/declarative/fixtures/extensions/observer-map-config-object/index.html +27 -0
  311. package/test/declarative/fixtures/extensions/observer-map-config-object/main.ts +53 -0
  312. package/test/declarative/fixtures/extensions/observer-map-config-object/state.json +9 -0
  313. package/test/declarative/fixtures/extensions/observer-map-config-object/templates.html +12 -0
  314. package/test/declarative/fixtures/extensions/observer-map-deep-merge/README.md +98 -0
  315. package/test/declarative/fixtures/extensions/observer-map-deep-merge/entry.html +156 -0
  316. package/test/declarative/fixtures/extensions/observer-map-deep-merge/fast-build.config.json +6 -0
  317. package/test/declarative/fixtures/extensions/observer-map-deep-merge/index.html +376 -0
  318. package/test/declarative/fixtures/extensions/observer-map-deep-merge/main.ts +366 -0
  319. package/test/declarative/fixtures/extensions/observer-map-deep-merge/state.json +69 -0
  320. package/test/declarative/fixtures/extensions/observer-map-deep-merge/templates.html +91 -0
  321. package/test/declarative/fixtures/extensions/observer-map-properties/entry.html +14 -0
  322. package/test/declarative/fixtures/extensions/observer-map-properties/fast-build.config.json +6 -0
  323. package/test/declarative/fixtures/extensions/observer-map-properties/index.html +110 -0
  324. package/test/declarative/fixtures/extensions/observer-map-properties/main.ts +175 -0
  325. package/test/declarative/fixtures/extensions/observer-map-properties/state.json +29 -0
  326. package/test/declarative/fixtures/extensions/observer-map-properties/templates.html +55 -0
  327. package/test/declarative/fixtures/scenarios/README.md +7 -0
  328. package/test/declarative/fixtures/scenarios/nested-elements/entry.html +16 -0
  329. package/test/declarative/fixtures/scenarios/nested-elements/fast-build.config.json +6 -0
  330. package/test/declarative/fixtures/scenarios/nested-elements/index.html +126 -0
  331. package/test/declarative/fixtures/scenarios/nested-elements/main.ts +214 -0
  332. package/test/declarative/fixtures/scenarios/nested-elements/state.json +10 -0
  333. package/test/declarative/fixtures/scenarios/nested-elements/templates.html +54 -0
  334. package/test/declarative/index.html +12 -0
  335. package/test/declarative/vite.config.ts +55 -0
  336. package/test/declarative-main.ts +6 -0
  337. package/test/extension-subpaths-main.ts +9 -0
  338. package/test/main.ts +38 -33
  339. package/test/pure-declarative-main.ts +1 -0
  340. package/dist/dts/components/install-hydration.d.ts +0 -1
  341. package/dist/dts/pending-task.d.ts +0 -32
  342. package/dist/dts/polyfills.d.ts +0 -0
  343. package/dist/dts/styles/css-binding-directive.d.ts +0 -60
  344. package/dist/dts/templating/install-hydratable-view-templates.d.ts +0 -1
  345. package/dist/esm/components/install-hydration.js +0 -3
  346. package/dist/esm/pending-task.js +0 -28
  347. package/dist/esm/polyfills.js +0 -60
  348. package/dist/esm/styles/css-binding-directive.js +0 -76
  349. package/dist/esm/templating/install-hydratable-view-templates.js +0 -23
@@ -0,0 +1,489 @@
1
+ # Schema and Observer Map Architecture
2
+
3
+ This document provides a technical explainer for how the `Schema` and
4
+ `ObserverMap` classes work together to describe data objects and automatically
5
+ observe them in FAST elements. Declarative `<f-template>` markup creates schemas
6
+ automatically, but the schema and observer map implementation are factored so
7
+ they can also be used without declarative templating.
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Overview](#overview)
12
+ 2. [The Schema Class](#the-schema-class)
13
+ 3. [The Observer Map Class](#the-observer-map-class)
14
+ 4. [Integration with f-template](#integration-with-f-template)
15
+ 5. [Initial Path Processing Flow](#initial-path-processing-flow)
16
+ 6. [Dynamic Path Processing Updates](#dynamic-path-processing-updates)
17
+ 7. [Observable Proxy System](#observable-proxy-system)
18
+ 8. [Examples](#examples)
19
+ 9. [Technical Details](#technical-details)
20
+
21
+ ## Overview
22
+
23
+ The Schema and Observer Map architecture enables automatic observation of complex nested data objects in FAST HTML templates. This system solves the problem of manually tracking all the binding paths used in declarative HTML templates, automatically creating observables for nested properties that are referenced in the template bindings.
24
+
25
+ **Important**: This system is designed specifically for observable data objects (objects, arrays, and primitives). It explicitly does not handle binding paths that are assumed to be functions, methods, or other non-data constructs like event handlers.
26
+
27
+ ### Key Components
28
+
29
+ - **Schema Class**: Generates JSON schemas that describe the structure and binding paths of data objects based on template analysis or manually registered paths
30
+ - **Observer Map Class**: Uses the schema information to automatically define observable properties and create proxies for nested object observation
31
+ - **f-template Integration**: Template processing automatically populates schemas and configures observer maps during template compilation
32
+ - **Map helpers**: `@microsoft/fast-element` exposes the map helpers independently from declarative templating
33
+
34
+ ### Supported Data Types
35
+
36
+ The system automatically handles:
37
+ - **Objects**: Nested object structures with observable properties
38
+ - **Arrays**: Arrays with observable mutations and nested object elements
39
+ - **Primitives**: String, number, boolean values as object properties
40
+
41
+ ### Explicitly Not Handled
42
+
43
+ The system does not process:
44
+ - **Function bindings**: Event handlers and method calls like `@click="{handleClick()}"`
45
+ - **Context paths**: Bindings using the `$c` prefix (e.g., `$c.parent.showNames`) resolve directly from the `ExecutionContext` and are not part of the data model
46
+ - **Computed expressions**: Complex expressions that evaluate to non-data values
47
+ - **Non-observable constructs**: Any binding assumed to reference functions or non-data objects
48
+
49
+ ## The Schema Class
50
+
51
+ The `Schema` class is responsible for building JSON Schema definitions that map the structure of data objects used in template bindings. It analyzes binding paths from template processing and constructs schemas that describe:
52
+
53
+ - Root properties and their nested structures
54
+ - Array contexts for repeat operations
55
+ - Object property relationships
56
+ - Cross-references to child components
57
+
58
+ **Important**: Each schema created corresponds to a property that will belong to the custom element's class. The schema describes the expected structure and relationships of data that will be assigned to that property, enabling automatic observation of nested objects and arrays within that property's data structure.
59
+
60
+ ### Core Methods
61
+
62
+ #### Constructor
63
+ ```typescript
64
+ constructor(name: string)
65
+ ```
66
+ Creates a new schema instance for a specific custom element name and initializes an instance-level `schemaMap`. The instance also registers itself in the module-level `schemaRegistry` for cross-element `$ref` resolution. `FASTElementDefinition.schema` is optional; declarative templates assign it after parsing, while manual schema users can pass one in the element definition or directly to `observerMap({ schema })`.
67
+
68
+ #### addPath
69
+ ```typescript
70
+ public addPath(config: RegisterPathConfig)
71
+ ```
72
+ Registers a binding path discovered during template processing. The configuration includes:
73
+ - `pathConfig`: Describes the path type (`access`, `default`, `repeat`, `event`)
74
+ - `rootPropertyName`: The root property this path belongs to
75
+ - `childrenMap`: Information about child components referenced in this path
76
+
77
+ **Note**: Only `access`, `default`, and `repeat` path types result in schema entries. Event paths are identified but not processed since they represent function calls rather than observable data.
78
+
79
+ #### getSchema
80
+ ```typescript
81
+ public getSchema(rootPropertyName: string): JSONSchema | null
82
+ ```
83
+ Retrieves the JSON schema for a specific root property.
84
+
85
+ ### Path Types
86
+
87
+ The schema handles different types of binding paths:
88
+
89
+ - **`access`/`default`**: Direct property access like `{{user.name}}`
90
+ - **`repeat`**: Array iteration contexts like `{{item}}` within `<f-repeat>`
91
+ - **`event`**: Event handler bindings like `@click="{handleClick()}"` - **Note: These are explicitly not processed by the schema system as they are assumed to be functions rather than observable data objects**
92
+
93
+ ### Schema Structure
94
+
95
+ Generated schemas follow JSON Schema format with FAST-specific extensions:
96
+
97
+ ```typescript
98
+ {
99
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
100
+ "$id": "https://fast.design/schemas/my-element/users.json",
101
+ "type": "array",
102
+ "$ref": "#/$defs/user",
103
+ "$defs": {
104
+ "user": {
105
+ "$fast_context": "users",
106
+ "$fast_parent_contexts": [null],
107
+ "type": "object",
108
+ "properties": {
109
+ "name": {},
110
+ "details": {
111
+ "type": "object",
112
+ "properties": {
113
+ "age": {}
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ **Note on Property Types**: Properties accessed through binding paths (like `name` and `age` above) are defined with empty objects `{}` rather than specific JSON Schema types. This is because it's not possible to determine the exact primitive type (string, number, boolean, etc.) from the path syntax alone. The system focuses on structural relationships rather than specific data types for leaf properties.
123
+
124
+ ## The Observer Map Class
125
+
126
+ The `ObserverMap` class uses schema information to automatically configure observable properties on custom element prototypes. It creates the infrastructure needed to observe nested object changes without manual setup.
127
+
128
+ ### Constructor
129
+ ```typescript
130
+ constructor(classPrototype: any, schema: Schema, config?: ObserverMapConfig)
131
+ ```
132
+ Creates an observer map instance that will configure the provided class prototype using the schema information.
133
+
134
+ ### defineProperties
135
+ ```typescript
136
+ public defineProperties(): void
137
+ ```
138
+ The main method that:
139
+ 1. Iterates through all root properties defined in the schema (each schema instance contains multiple root property schemas)
140
+ 2. Defines observable properties using FAST Element's `Observable.defineProperty` (an alternative to the `@observable` decorator syntax used in custom element classes)
141
+ 3. Sets up property change handlers that create proxies for nested objects
142
+
143
+ ### Property Change Handling
144
+
145
+ When a root property transitions from `undefined` to a defined value, the observer map:
146
+ 1. Analyzes the schema to understand the expected object structure
147
+ 2. Creates proxies using the `assignObservables` utility function
148
+ 3. Establishes deep observation of nested properties based on the schema of that root property
149
+
150
+ ## Integration with f-template and manual schemas
151
+
152
+ The Schema and Observer Map classes integrate seamlessly with the f-template system, but they are not tied to it:
153
+
154
+ ### Template Processing Flow
155
+
156
+ 1. **Template Parsing**: When an `f-template` element is processed, it creates a `Schema` instance
157
+ 2. **Binding Discovery**: As template bindings are processed, paths are registered with `schema.addPath()`
158
+ 3. **Observer Map Creation**: If enabled, an `ObserverMap` is instantiated with the populated schema
159
+ 4. **Property Definition**: The observer map defines observable properties on the custom element prototype
160
+
161
+ ### Configuration
162
+
163
+ Observer Map functionality is enabled through the `observerMap()` definition
164
+ extension exported from `@microsoft/fast-element/observer-map.js`:
165
+
166
+ ```typescript
167
+ import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
168
+ import { observerMap } from "@microsoft/fast-element/observer-map.js";
169
+
170
+ MyElement.define(
171
+ {
172
+ name: "my-custom-element",
173
+ template: declarativeTemplate(),
174
+ },
175
+ [observerMap()]
176
+ );
177
+ ```
178
+
179
+ When the `properties` key is omitted, all root properties discovered in the
180
+ template are observed. Add a `properties` object to opt into selective
181
+ observation behavior.
182
+
183
+ For non-declarative/manual schema use, pass the schema in the observer map
184
+ configuration:
185
+
186
+ ```typescript
187
+ import { FASTElement, Schema } from "@microsoft/fast-element";
188
+ import { observerMap } from "@microsoft/fast-element/observer-map.js";
189
+
190
+ class MyElement extends FASTElement {}
191
+
192
+ const schema = new Schema("my-custom-element");
193
+ schema.addPath({
194
+ rootPropertyName: "user",
195
+ pathConfig: {
196
+ type: "default",
197
+ parentContext: null,
198
+ currentContext: null,
199
+ path: "user.name",
200
+ },
201
+ childrenMap: null,
202
+ });
203
+
204
+ MyElement.define(
205
+ {
206
+ name: "my-custom-element",
207
+ },
208
+ [observerMap({ schema })]
209
+ );
210
+ ```
211
+
212
+ You can also attach a manual schema to the FAST element definition. This is the
213
+ path used automatically by `declarativeTemplate()` after it parses a template:
214
+
215
+ ```typescript
216
+ MyElement.define(
217
+ {
218
+ name: "my-custom-element",
219
+ schema,
220
+ },
221
+ [observerMap()]
222
+ );
223
+ ```
224
+
225
+ ## Initial Path Processing Flow
226
+
227
+ Here's how binding paths flow through the system during initial template processing:
228
+
229
+ 1. **Template Binding**: `{{user.details.personal.name}}`
230
+ 2. **Path Analysis**: Utilities identify root property (`user`) and nested path (`details.personal.name`)
231
+ 3. **Type Check**: Confirms this is a data binding (not an event handler like `@click="{handleClick()}"`)
232
+ 4. **Schema Registration**:
233
+ ```typescript
234
+ schema.addPath({
235
+ pathConfig: {
236
+ type: "access",
237
+ currentContext: null,
238
+ parentContext: null,
239
+ path: "user.details.personal.name"
240
+ },
241
+ rootPropertyName: "user",
242
+ childrenMap: null
243
+ });
244
+ ```
245
+ 5. **Schema Building**: Creates nested object structure in JSON schema
246
+ 6. **Observable Definition**: Observer map makes `user` property observable
247
+ 7. **Proxy Creation**: When `user` is assigned, proxies are created for deep observation
248
+
249
+ ### Event Handler and Context Path Exclusion
250
+
251
+ Event handlers are identified but explicitly excluded from schema processing:
252
+ - **Template Binding**: `@click="{handleClick()}"`
253
+ - **Path Analysis**: Utilities identify this as an event handler
254
+ - **Type Check**: Confirms this is type `"event"`
255
+ - **Schema Registration**: **Skipped** - Event handlers are not added to schemas since they represent function calls
256
+
257
+ Context paths (`$c` prefix) are also excluded from schema processing:
258
+ - **Template Binding**: `{{$c.parent.showNames}}` or `@click="{$c.parent.handleClick($c.event)}"`
259
+ - **Path Analysis**: Utilities detect the `$c.` prefix
260
+ - **Schema Registration**: **Skipped** - These paths resolve from the `ExecutionContext`, not from observable data properties
261
+
262
+ ## Dynamic Path Processing Updates
263
+
264
+ After initial schema creation and observer map setup, the system continues to dynamically update observation as data structures evolve:
265
+
266
+ ### Runtime Object Assignment
267
+
268
+ When nested objects or array items become defined after initial setup:
269
+
270
+ 1. **Property Assignment**: A previously undefined nested property gets assigned a value
271
+ ```typescript
272
+ // Initially: user.details was undefined
273
+ user.details = { age: 30, location: { city: "Seattle" } };
274
+ ```
275
+
276
+ 2. **Schema Consultation**: The system consults the existing schema for this root property to understand expected nested structure
277
+
278
+ 3. **Proxy Creation**: New proxies are automatically created for the newly assigned nested objects based on the schema definition
279
+
280
+ 4. **Deep Observation Extension**: Observation is extended to all nested properties defined in the schema
281
+
282
+ ### Array Item Addition
283
+
284
+ When new items are added to observed arrays:
285
+
286
+ 1. **Array Mutation**: Items are added via push, splice, or direct assignment
287
+ ```typescript
288
+ users.push({ name: "John", details: { age: 25 } });
289
+ ```
290
+
291
+ 2. **Array Observer Trigger**: The array proxy detects the mutation and triggers observation setup
292
+
293
+ 3. **Item Processing**: Each new array item is processed according to the array's context schema definition
294
+
295
+ 4. **Nested Object Proxying**: New nested objects within array items are automatically proxied based on the schema structure
296
+
297
+ ## Observable Proxy System
298
+
299
+ The proxy system in `utilities.ts` provides the deep observation capabilities:
300
+
301
+ ### assignObservables Function
302
+
303
+ ```typescript
304
+ export function assignObservables(
305
+ schema: JSONSchema | JSONSchemaDefinition,
306
+ rootSchema: JSONSchema,
307
+ data: any,
308
+ target: any,
309
+ rootProperty: string
310
+ ): typeof Proxy
311
+ ```
312
+
313
+ This function:
314
+ - Analyzes the data type (object, array, primitive)
315
+ - Creates proxies for objects and arrays
316
+ - Establishes property observation for nested structures
317
+ - Handles array mutations and object property changes
318
+
319
+ ### Proxy Behavior
320
+
321
+ Proxied objects:
322
+ - Trigger Observable notifications when properties change
323
+ - Automatically proxy newly assigned nested objects
324
+ - Track array mutations and splice operations
325
+ - Maintain references to root properties for change notifications
326
+
327
+ ## Examples
328
+
329
+ ### Basic Object Observation
330
+
331
+ **Template:**
332
+ ```html
333
+ <f-template name="user-profile">
334
+ <template>
335
+ <div>{{user.name}} - {{user.details.age}} years old</div>
336
+ <div>Location: {{user.details.location.city}}</div>
337
+ </template>
338
+ </f-template>
339
+ ```
340
+
341
+ **Generated Schema Structure:**
342
+ ```typescript
343
+ // Root property: "user"
344
+ {
345
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
346
+ "$id": "https://fast.design/schemas/user-profile/user.json",
347
+ "type": "object",
348
+ "properties": {
349
+ "name": {},
350
+ "details": {
351
+ "type": "object",
352
+ "properties": {
353
+ "age": {},
354
+ "location": {
355
+ "type": "object",
356
+ "properties": {
357
+ "city": {}
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ ```
365
+
366
+ ### Array with Repeat Context
367
+
368
+ **Template:**
369
+ ```html
370
+ <f-template name="user-list">
371
+ <template>
372
+ <f-repeat value="{{user in users}}">
373
+ <div>{{user.name}} has {{user.posts.length}} posts</div>
374
+ </f-repeat>
375
+ </template>
376
+ </f-template>
377
+ ```
378
+
379
+ **Generated Schema Structure:**
380
+ ```typescript
381
+ // Root property: "users"
382
+ {
383
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
384
+ "$id": "https://fast.design/schemas/user-list/users.json",
385
+ "type": "array",
386
+ "$ref": "#/$defs/user",
387
+ "$defs": {
388
+ "user": {
389
+ "$fast_context": "users",
390
+ "$fast_parent_contexts": [null],
391
+ "type": "object",
392
+ "properties": {
393
+ "name": {},
394
+ "posts": {
395
+ "type": "array"
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
401
+ ```
402
+
403
+ ### Nested Repeat Contexts
404
+
405
+ **Template:**
406
+ ```html
407
+ <f-template name="complex-data">
408
+ <template>
409
+ <f-repeat value="{{user in users}}">
410
+ <div>{{user.name}}</div>
411
+ <f-repeat value="{{post in user.posts}}">
412
+ <div>{{post.title}} - {{post.metadata.views}} views</div>
413
+ </f-repeat>
414
+ </f-repeat>
415
+ </template>
416
+ </f-template>
417
+ ```
418
+
419
+ This creates nested context definitions where the `post` context understands its relationship to the parent `user` context.
420
+
421
+ ## Technical Details
422
+
423
+ ### Schema Registry
424
+
425
+ The `Schema` module exports a module-level `schemaRegistry`:
426
+ ```typescript
427
+ export const schemaRegistry: CachedPathMap = new Map();
428
+ ```
429
+
430
+ Each `Schema` instance owns an instance-level `schemaMap: Map<string, JSONSchema>` and registers itself in `schemaRegistry` on construction.
431
+
432
+ The registry structure is: `Map<customElementName, Map<rootPropertyName, JSONSchema>>`
433
+
434
+ **Rationale for Module-level Registry**: The registry allows cross-element `$ref` resolution for nested components inside f-templates. When an object or array is passed to another custom element within an f-template, that nested component needs to observe the entire root property's structure based on the binding paths within that nested component. The registry allows all components to access and contribute to the same schema definitions, ensuring consistent observation behavior across component boundaries.
435
+
436
+ ### Context Tracking
437
+
438
+ The schema system tracks binding contexts using special metadata:
439
+ - `$fast_context`: The array property name that created this context
440
+ - `$fast_parent_contexts`: Chain of parent contexts leading to the root
441
+
442
+ ### Performance Considerations
443
+
444
+ - **Lazy Proxy Creation**: Proxies are only created when objects are assigned to observable properties
445
+ - **Weak Map Caching**: The system uses WeakMaps to avoid memory leaks when tracking proxied objects
446
+ - **Schema Reuse**: Schemas are generated once per custom element and reused across instances
447
+
448
+ ### Memory Management
449
+
450
+ - **WeakMap Usage**: `objectTargetsMap` and `observedArraysMap` use WeakMaps to automatically clean up references
451
+ - **Proxy Identification**: Proxies are marked with `$isProxy` to prevent double-proxying
452
+ - **Reference Tracking**: Target elements and root properties are tracked for proper change notification
453
+
454
+ ## Debugging and Troubleshooting
455
+
456
+ ### Schema Inspection
457
+
458
+ You can inspect generated schemas using the module-level `schemaRegistry` import:
459
+
460
+ ```typescript
461
+ import { schemaRegistry } from "@microsoft/fast-element";
462
+
463
+ // Get all schemas for an element:
464
+ const elementSchemas = schemaRegistry.get('my-element');
465
+ const userSchema = elementSchemas?.get('users');
466
+ console.log(JSON.stringify(userSchema, null, 2));
467
+ ```
468
+
469
+ ### Observer Map Status
470
+
471
+ `observerMap()` is applied as a definition extension before the element is
472
+ registered. There is no public `TemplateElement.options()` state to inspect.
473
+ To verify that observer mapping ran, inspect the generated schema and the
474
+ observable accessors on the element prototype:
475
+
476
+ ```typescript
477
+ import { Observable, schemaRegistry } from "@microsoft/fast-element";
478
+
479
+ const schemas = schemaRegistry.get("my-element");
480
+ const accessors = Observable.getAccessors(MyElement.prototype).map(a => a.name);
481
+ console.log(schemas, accessors);
482
+ ```
483
+
484
+ ### Proxy Detection
485
+
486
+ Objects processed by the system will have a `$isProxy` property:
487
+ ```typescript
488
+ console.log('Is proxied:', myObject.$isProxy === true);
489
+ ```