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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/README.md +244 -1
  3. package/dist/arrays/arrays.api.json +2621 -0
  4. package/dist/context/context.api.json +13 -13
  5. package/dist/declarative/declarative.api.json +8483 -0
  6. package/dist/di/di.api.json +16 -16
  7. package/dist/dts/__test__/helpers.d.ts +6 -0
  8. package/dist/dts/array-observer.d.ts +2 -0
  9. package/dist/dts/arrays.d.ts +2 -0
  10. package/dist/dts/attr.d.ts +1 -0
  11. package/dist/dts/binding/binding.d.ts +15 -5
  12. package/dist/dts/binding/one-time.d.ts +1 -1
  13. package/dist/dts/binding/one-way.d.ts +1 -1
  14. package/dist/dts/binding/signal.d.ts +6 -6
  15. package/dist/dts/binding/two-way.d.ts +2 -1
  16. package/dist/dts/binding.d.ts +7 -0
  17. package/dist/dts/components/attributes.d.ts +1 -4
  18. package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
  19. package/dist/dts/components/element-controller.d.ts +80 -114
  20. package/dist/dts/components/element-hydration.d.ts +1 -1
  21. package/dist/dts/components/enable-hydration.d.ts +54 -0
  22. package/dist/dts/components/fast-definitions.d.ts +98 -46
  23. package/dist/dts/components/fast-element.d.ts +43 -16
  24. package/dist/dts/components/hydration-tracker.d.ts +83 -0
  25. package/dist/dts/components/hydration.d.ts +23 -53
  26. package/dist/dts/components/schema.d.ts +205 -0
  27. package/dist/dts/context.d.ts +13 -13
  28. package/dist/dts/css.d.ts +3 -0
  29. package/dist/dts/debug.d.ts +5 -1
  30. package/dist/dts/declarative/attribute-map.d.ts +58 -0
  31. package/dist/dts/declarative/debug.d.ts +4 -0
  32. package/dist/dts/declarative/index.d.ts +14 -0
  33. package/dist/dts/declarative/interfaces.d.ts +8 -0
  34. package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
  35. package/dist/dts/declarative/observer-map.d.ts +89 -0
  36. package/dist/dts/declarative/runtime.d.ts +5 -0
  37. package/dist/dts/declarative/syntax.d.ts +21 -0
  38. package/dist/dts/declarative/template-bridge.d.ts +33 -0
  39. package/dist/dts/declarative/template-parser.d.ts +98 -0
  40. package/dist/dts/declarative/template.d.ts +10 -0
  41. package/dist/dts/declarative/utilities.d.ts +358 -0
  42. package/dist/dts/di/di.d.ts +7 -7
  43. package/dist/dts/directives/children.d.ts +2 -0
  44. package/dist/dts/directives/node-observation.d.ts +2 -0
  45. package/dist/dts/directives/ref.d.ts +2 -0
  46. package/dist/dts/directives/repeat.d.ts +4 -0
  47. package/dist/dts/directives/slotted.d.ts +2 -0
  48. package/dist/dts/directives/when.d.ts +3 -0
  49. package/dist/dts/dom-policy.d.ts +23 -5
  50. package/dist/dts/dom.d.ts +4 -16
  51. package/dist/dts/html.d.ts +5 -0
  52. package/dist/dts/hydration/diagnostics.d.ts +93 -0
  53. package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
  54. package/dist/dts/hydration/messages.d.ts +62 -0
  55. package/dist/dts/hydration/runtime.d.ts +7 -0
  56. package/dist/dts/hydration/target-builder.d.ts +40 -12
  57. package/dist/dts/hydration.d.ts +18 -0
  58. package/dist/dts/index.d.ts +42 -42
  59. package/dist/dts/index.debug.d.ts +0 -1
  60. package/dist/dts/index.rollup.debug.d.ts +0 -1
  61. package/dist/dts/interfaces.d.ts +2 -49
  62. package/dist/dts/observable.d.ts +3 -6
  63. package/dist/dts/observation/arrays.d.ts +1 -1
  64. package/dist/dts/observation/observable.d.ts +3 -3
  65. package/dist/dts/observation/update-queue.d.ts +1 -1
  66. package/dist/dts/platform.d.ts +45 -8
  67. package/dist/dts/registry.d.ts +1 -0
  68. package/dist/dts/render.d.ts +7 -0
  69. package/dist/dts/schema.d.ts +1 -0
  70. package/dist/dts/state/exports.d.ts +1 -1
  71. package/dist/dts/state/state.d.ts +2 -2
  72. package/dist/dts/styles/css-directive.d.ts +5 -12
  73. package/dist/dts/styles/css.d.ts +5 -7
  74. package/dist/dts/styles/element-styles.d.ts +0 -10
  75. package/dist/dts/styles.d.ts +6 -0
  76. package/dist/dts/templating/compiler.d.ts +1 -1
  77. package/dist/dts/templating/html-binding-directive.d.ts +10 -2
  78. package/dist/dts/templating/html-directive.d.ts +19 -1
  79. package/dist/dts/templating/hydration-view.d.ts +130 -0
  80. package/dist/dts/templating/render.d.ts +1 -1
  81. package/dist/dts/templating/repeat.d.ts +1 -1
  82. package/dist/dts/templating/template.d.ts +15 -7
  83. package/dist/dts/templating/view.d.ts +25 -102
  84. package/dist/dts/templating.d.ts +10 -0
  85. package/dist/dts/testing/exports.d.ts +2 -2
  86. package/dist/dts/testing/fakes.d.ts +4 -4
  87. package/dist/dts/updates.d.ts +1 -0
  88. package/dist/dts/volatile.d.ts +2 -0
  89. package/dist/esm/__test__/helpers.js +22 -0
  90. package/dist/esm/__test__/setup-node.js +18 -0
  91. package/dist/esm/array-observer.js +1 -0
  92. package/dist/esm/arrays.js +1 -0
  93. package/dist/esm/attr.js +1 -0
  94. package/dist/esm/binding/normalize.js +1 -1
  95. package/dist/esm/binding/signal.js +4 -4
  96. package/dist/esm/binding/two-way.js +3 -3
  97. package/dist/esm/binding.js +4 -0
  98. package/dist/esm/components/attributes.js +18 -11
  99. package/dist/esm/components/definition-schema-transforms.js +23 -0
  100. package/dist/esm/components/element-controller.js +206 -270
  101. package/dist/esm/components/element-hydration.js +1 -1
  102. package/dist/esm/components/enable-hydration.js +124 -0
  103. package/dist/esm/components/fast-definitions.js +219 -56
  104. package/dist/esm/components/fast-element.js +18 -27
  105. package/dist/esm/components/hydration-tracker.js +122 -0
  106. package/dist/esm/components/hydration.js +137 -140
  107. package/dist/esm/components/schema.js +253 -0
  108. package/dist/esm/context.js +6 -6
  109. package/dist/esm/css.js +3 -0
  110. package/dist/esm/debug.js +27 -26
  111. package/dist/esm/declarative/attribute-map.js +122 -0
  112. package/dist/esm/declarative/debug.js +4 -0
  113. package/dist/esm/declarative/index.js +4 -0
  114. package/dist/esm/declarative/interfaces.js +9 -0
  115. package/dist/esm/declarative/observer-map-utilities.js +565 -0
  116. package/dist/esm/declarative/observer-map.js +216 -0
  117. package/dist/esm/declarative/runtime.js +14 -0
  118. package/dist/esm/declarative/syntax.js +36 -0
  119. package/dist/esm/declarative/template-bridge.js +160 -0
  120. package/dist/esm/declarative/template-parser.js +306 -0
  121. package/dist/esm/declarative/template.js +143 -0
  122. package/dist/esm/declarative/utilities.js +1069 -0
  123. package/dist/esm/di/di.js +8 -9
  124. package/dist/esm/directives/children.js +1 -0
  125. package/dist/esm/directives/node-observation.js +1 -0
  126. package/dist/esm/directives/ref.js +1 -0
  127. package/dist/esm/directives/repeat.js +1 -0
  128. package/dist/esm/directives/slotted.js +1 -0
  129. package/dist/esm/directives/when.js +1 -0
  130. package/dist/esm/dom-policy.js +35 -6
  131. package/dist/esm/dom.js +1 -1
  132. package/dist/esm/html.js +2 -0
  133. package/dist/esm/hydration/diagnostics.js +50 -0
  134. package/dist/esm/hydration/hydration-debugger.js +112 -0
  135. package/dist/esm/hydration/messages.js +84 -0
  136. package/dist/esm/hydration/runtime.js +33 -0
  137. package/dist/esm/hydration/target-builder.js +144 -91
  138. package/dist/esm/hydration.js +6 -0
  139. package/dist/esm/index.debug.js +2 -1
  140. package/dist/esm/index.js +38 -29
  141. package/dist/esm/index.rollup.debug.js +3 -2
  142. package/dist/esm/index.rollup.js +1 -1
  143. package/dist/esm/interfaces.js +2 -45
  144. package/dist/esm/metadata.js +2 -8
  145. package/dist/esm/observable.js +1 -4
  146. package/dist/esm/observation/arrays.js +1 -1
  147. package/dist/esm/observation/notifier.js +2 -4
  148. package/dist/esm/observation/observable.js +5 -5
  149. package/dist/esm/observation/update-queue.js +47 -58
  150. package/dist/esm/platform.js +31 -30
  151. package/dist/esm/registry.js +1 -0
  152. package/dist/esm/render.js +1 -0
  153. package/dist/esm/schema.js +1 -0
  154. package/dist/esm/state/exports.js +1 -1
  155. package/dist/esm/styles/css-directive.js +1 -2
  156. package/dist/esm/styles/css.js +15 -56
  157. package/dist/esm/styles/element-styles.js +69 -15
  158. package/dist/esm/styles.js +2 -0
  159. package/dist/esm/templating/html-binding-directive.js +11 -9
  160. package/dist/esm/templating/hydration-view.js +228 -0
  161. package/dist/esm/templating/render.js +39 -18
  162. package/dist/esm/templating/repeat.js +69 -33
  163. package/dist/esm/templating/template.js +7 -7
  164. package/dist/esm/templating/view.js +25 -234
  165. package/dist/esm/templating.js +7 -0
  166. package/dist/esm/testing/exports.js +2 -2
  167. package/dist/esm/testing/fixture.js +2 -2
  168. package/dist/esm/testing/timeout.js +2 -2
  169. package/dist/esm/updates.js +1 -0
  170. package/dist/esm/volatile.js +1 -0
  171. package/dist/fast-element.api.json +14389 -11138
  172. package/dist/fast-element.d.ts +3651 -809
  173. package/dist/fast-element.debug.js +5666 -4722
  174. package/dist/fast-element.debug.min.js +2 -2
  175. package/dist/fast-element.js +5394 -4381
  176. package/dist/fast-element.min.js +2 -2
  177. package/dist/fast-element.untrimmed.d.ts +923 -472
  178. package/dist/hydration/hydration.api.json +6460 -0
  179. package/dist/styles/styles.api.json +2672 -0
  180. package/package.json +165 -45
  181. package/ARCHITECTURE_FASTELEMENT.md +0 -63
  182. package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +0 -36
  183. package/ARCHITECTURE_INTRO.md +0 -10
  184. package/ARCHITECTURE_OVERVIEW.md +0 -52
  185. package/ARCHITECTURE_UPDATES.md +0 -11
  186. package/CHANGELOG.json +0 -2275
  187. package/DESIGN.md +0 -510
  188. package/api-extractor.context.json +0 -14
  189. package/api-extractor.di.json +0 -14
  190. package/biome.json +0 -4
  191. package/dist/dts/components/install-hydration.d.ts +0 -1
  192. package/dist/dts/pending-task.d.ts +0 -32
  193. package/dist/dts/styles/css-binding-directive.d.ts +0 -60
  194. package/dist/dts/templating/install-hydratable-view-templates.d.ts +0 -1
  195. package/dist/esm/components/install-hydration.js +0 -3
  196. package/dist/esm/pending-task.js +0 -28
  197. package/dist/esm/polyfills.js +0 -60
  198. package/dist/esm/styles/css-binding-directive.js +0 -76
  199. package/dist/esm/templating/install-hydratable-view-templates.js +0 -23
  200. package/docs/ACKNOWLEDGEMENTS.md +0 -12
  201. package/docs/api-report.api.md +0 -1122
  202. package/docs/context/api-report.api.md +0 -69
  203. package/docs/di/api-report.api.md +0 -315
  204. package/docs/fast-element-2-changes.md +0 -15
  205. package/playwright.config.ts +0 -26
  206. package/scripts/run-api-extractor.js +0 -51
  207. package/test/index.html +0 -11
  208. package/test/main.ts +0 -104
  209. package/test/vite.config.ts +0 -19
  210. package/tsconfig.api-extractor.json +0 -6
  211. /package/dist/dts/{polyfills.d.ts → __test__/setup-node.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,12 +1,62 @@
1
1
  # Change Log - @microsoft/fast-element
2
2
 
3
- <!-- This log was last generated on Fri, 17 Apr 2026 00:26:33 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Fri, 19 Jun 2026 22:15:55 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.0.0-rc.2
8
+
9
+ Fri, 19 Jun 2026 22:15:55 GMT
10
+
11
+ ### Changes
12
+
13
+ - Filter late attribute MutationObserver records. (7559015+janechu@users.noreply.github.com)
14
+ - fix: align @attr({ mode: 'boolean' }) and booleanConverter with native HTML boolean attribute semantics (7559015+janechu@users.noreply.github.com)
15
+ - feat: expose declarative HTML syntax constants from declarative utilities (7559015+janechu@users.noreply.github.com)
16
+ - fix: restore CaptureType generic type capture for template directives (7559015+janechu@users.noreply.github.com)
17
+ - feat: change default attribute-name-strategy from none to camelCase (7559015+janechu@users.noreply.github.com)
18
+ - feat: auto-escape `{` and `}` inside `<code>` elements so binding-like syntax in code samples renders as literal text (mirrors webui-press and the server-side `escape_code_sample_elements` pass in `@microsoft/fast-build`, which additionally handles `<f-when>`/`<f-repeat>` directive tags) (7559015+janechu@users.noreply.github.com)
19
+ - Improve hydration mismatch behaviour: render() falls back to client rendering when SSR view boundaries are empty, repeat() reconciles SSR/client item-count mismatches by creating missing client views or removing extra SSR ranges, and unrecoverable mismatches throw via a pluggable HydrationDiagnostic. Opt in to the rich 'Expected / Received' format with the SSR HTML snippet and structured expected/received fields on HydrationBindingError / HydrationTargetElementError by passing enableHydration({ debugger: hydrationDebugger() }) (hydrationDebugger is exported from '@microsoft/fast-element/hydration.js'). (7559015+janechu@users.noreply.github.com)
20
+ - Add hydration configuration for streamed Declarative Shadow DOM. (7559015+janechu@users.noreply.github.com)
21
+ - Avoid mutating render template bindings (7559015+janechu@users.noreply.github.com)
22
+ - feat: propagate shadowroot attributes from f-template to declarative shadow DOM template (7559015+janechu@users.noreply.github.com)
23
+ - Preserve view context when rebinding the same source. (7559015+janechu@users.noreply.github.com)
24
+ - feat: warn when duplicate render instruction registrations replace existing entries (7559015+janechu@users.noreply.github.com)
25
+ - Add a registry path export for FAST element definition lookups. (7559015+janechu@users.noreply.github.com)
26
+ - Bump @microsoft/fast-build to v0.8.0-fast-element-v3-rc-20260615
27
+
28
+ ## 3.0.0-rc.1
29
+
30
+ Tue, 28 Apr 2026 04:42:02 GMT
31
+
32
+ ### Major changes
33
+
34
+ - remove FASTGlobal version tracking (7559015+janechu@users.noreply.github.com)
35
+ - Remove hydration view template side effect and unused export paths (7559015+janechu@users.noreply.github.com)
36
+ - Move optional helpers to dedicated flat fast-element subpath exports such as @microsoft/fast-element/children.js, @microsoft/fast-element/repeat.js, @microsoft/fast-element/two-way.js, @microsoft/fast-element/signal.js, @microsoft/fast-element/attribute-map.js, and @microsoft/fast-element/observer-map.js while keeping controller and definition internals on the root entrypoint. (7559015+janechu@users.noreply.github.com)
37
+ - Remove the public declarative TemplateElement configuration APIs and make declarative templates use an internal native f-template publisher with explicit hydration opt-in. (7559015+janechu@users.noreply.github.com)
38
+ - Replace HydratableElementController with automatic prerendered content optimization. When a component connects with an existing shadow root, bindings skip attribute/booleanAttribute DOM updates during initial render while still setting up event listeners, observers, and dependency tracking. Added isPrerendered flag to ElementController and ViewController. Added template-pending guard for defineAsync flow. (7559015+janechu@users.noreply.github.com)
39
+ - Move declarative HTML APIs into @microsoft/fast-element/declarative.js, expose schema map helpers from extension subpaths, and remove the @microsoft/fast-html package. (7559015+janechu@users.noreply.github.com)
40
+ - Remove ElementStyles.withBehaviors, CSS style behaviors, and CSS bindings in fast-element. (7559015+janechu@users.noreply.github.com)
41
+ - Remove TemplateOptions from fast-element definitions and drop templateOptions-based connection/define waiting. (7559015+janechu@users.noreply.github.com)
42
+ - Simplify hydration markers to data-free sequential format (fe:b, fe:/b, fe:r, fe:/r, fe:e, fe:/e). Replace regex parsing with string equality checks. Single data-fe attribute replaces three old formats. Breaking change: SSR output format changed. (7559015+janechu@users.noreply.github.com)
43
+ - remove deprecated declarative event e support (7559015+janechu@users.noreply.github.com)
44
+ - Make declarative runtime setup lazy and change @microsoft/fast-element/debug.js to require an explicit enableDebug() call. (7559015+janechu@users.noreply.github.com)
45
+ - Remove defineAsync and composeAsync — define() and compose() now return Promises (7559015+janechu@users.noreply.github.com)
46
+ - Remove the built-in globalThis polyfill; fast-element v3 now requires native globalThis (7559015+janechu@users.noreply.github.com)
47
+ - fix: remove the fast-kernel multi-kernel modes. Breaking change: FAST no longer supports configuring isolated or version-scoped kernels via the script attribute. (7559015+janechu@users.noreply.github.com)
48
+
49
+ ### Minor changes
50
+
51
+ - Add schema-driven attributeMap and observerMap extension subpaths, optional definition schema, and observerMap schema configuration. (7559015+janechu@users.noreply.github.com)
52
+ - add declarativeTemplate for auto-resolving <f-template> markup (7559015+janechu@users.noreply.github.com)
53
+ - Add extensions array argument to FASTElement.define() and FASTElementDefinition.define() (7559015+janechu@users.noreply.github.com)
54
+ - feat: modularize hydration and expose lifecycle callbacks via enableHydration() and declarativeTemplate() (7559015+janechu@users.noreply.github.com)
55
+ - add function-based template resolver sequencing (7559015+janechu@users.noreply.github.com)
56
+
7
57
  ## 2.10.4
8
58
 
9
- Fri, 17 Apr 2026 00:26:33 GMT
59
+ Fri, 17 Apr 2026 00:26:37 GMT
10
60
 
11
61
  ### Patches
12
62
 
package/README.md CHANGED
@@ -51,4 +51,247 @@ For simplicity, examples throughout the documentation will assume the library ha
51
51
 
52
52
  :::tip
53
53
  Looking for a quick guide on building components? Check out [our Cheat Sheet](../resources/cheat-sheet.md#building-components).
54
- :::
54
+ :::
55
+
56
+ ## Browser Requirements
57
+
58
+ FAST Element v3 assumes a client-side browser `Window` runtime with native
59
+ `globalThis`, Custom Elements, DOM, Shadow DOM, and `requestAnimationFrame`.
60
+ The `FAST` object is now a module-scoped export (not on `globalThis`). If you
61
+ need to support an older browser without `globalThis`, load that polyfill before
62
+ importing `@microsoft/fast-element`.
63
+
64
+ The FAST Element client runtime is not intended to execute in workers,
65
+ server-side JavaScript runtimes, or other non-window hosts. Use server-side
66
+ rendering tools to produce HTML for the browser, and run FAST Element in the
67
+ client window where custom elements connect, render, update, and hydrate.
68
+
69
+ ## Debug entrypoint
70
+
71
+ `@microsoft/fast-element/debug.js` exports `enableDebug()` instead of configuring
72
+ FAST at import time. The development root export and debug rollup bundle still
73
+ enable debug behavior automatically.
74
+
75
+ ```ts
76
+ import { enableDebug } from "@microsoft/fast-element/debug.js";
77
+
78
+ enableDebug();
79
+ ```
80
+
81
+ ## Export Sizes
82
+
83
+ Bundle sizes for each tree-shakeable export are tracked in [`SIZES.md`](./SIZES.md) and regenerated on every build. See the [Export Sizes](https://www.fast.design/docs/2.x/resources/export-sizes/) documentation page for the latest numbers.
84
+
85
+ ## Root Imports and Path Exports
86
+
87
+ The root `@microsoft/fast-element` entrypoint exports the FAST Element
88
+ implementation APIs, including the element base class, kernel, controller,
89
+ definition APIs, template APIs, binding helpers, directives, styles, and schema
90
+ helpers. The FAST element registry is also available from
91
+ `@microsoft/fast-element/registry.js` for focused definition lookups.
92
+ Declarative, hydration, context, and dependency injection APIs are available
93
+ from their focused path exports.
94
+
95
+ Focused package path exports remain available for consumers that want to import
96
+ a narrower entrypoint directly. The website's
97
+ [Path Exports](https://www.fast.design/docs/3.x/advanced/path-exports/) page is
98
+ generated from `package.json` and lists each supported path.
99
+
100
+ ## Dynamic Style Application
101
+
102
+ Import `css`, `CSSTemplateTag`, `CSSValue`, and style APIs such as
103
+ `ElementStyles`, `CSSDirective`, `cssDirective`, `ComposableStyles`,
104
+ `HostBehavior`, `HostController`, `StyleStrategy`, and `StyleTarget` from
105
+ `@microsoft/fast-element`:
106
+
107
+ ```ts
108
+ import { ElementStyles, css } from "@microsoft/fast-element";
109
+ ```
110
+
111
+ When runtime state or external signals need to add or remove styles, create the
112
+ `ElementStyles` with `css` and toggle it through
113
+ `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` from
114
+ the element lifecycle or change handlers.
115
+
116
+ `css` templates remain static style definitions. Runtime CSS bindings and
117
+ behavior-producing CSS directives are no longer supported; keep the condition on
118
+ the element and toggle a separate `ElementStyles` instance through the
119
+ controller when styles need to change.
120
+
121
+ ## Declarative HTML
122
+
123
+ FAST Element publishes its declarative HTML runtime from
124
+ `@microsoft/fast-element/declarative.js`. This entrypoint exports the
125
+ functional APIs for declarative templates: `declarativeTemplate()`,
126
+ `TemplateParser`, and related configuration types. `attributeMap()` and
127
+ `observerMap()` are available from their own focused path exports. The
128
+ declarative runtime is pure at import time; declarative APIs lazily install only
129
+ declarative debug messages. Hydration is separate and remains opt-in through
130
+ `enableHydration()` from `@microsoft/fast-element/hydration.js`.
131
+
132
+ ```ts
133
+ import { FASTElement } from "@microsoft/fast-element";
134
+ import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
135
+
136
+ class MyElement extends FASTElement {}
137
+
138
+ MyElement.define({
139
+ name: "my-element",
140
+ template: declarativeTemplate(),
141
+ });
142
+ ```
143
+
144
+ `declarativeTemplate()` automatically defines FAST's internal native
145
+ `<f-template>` publisher in the relevant registry, resolves the matching
146
+ `<f-template name="my-element">`, and keeps the definition template concrete
147
+ before `define()` resolves. If multiple matching `<f-template>` elements are
148
+ connected, the first connected element supplies the template and later duplicates
149
+ do not reassign it. Consumers should not import or define the `<f-template>`
150
+ implementation directly.
151
+
152
+ Declarative schema behavior is enabled with define extensions:
153
+
154
+ ```ts
155
+ import { attributeMap } from "@microsoft/fast-element/attribute-map.js";
156
+ import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
157
+ import { observerMap } from "@microsoft/fast-element/observer-map.js";
158
+
159
+ MyElement.define(
160
+ {
161
+ name: "my-element",
162
+ template: declarativeTemplate(),
163
+ },
164
+ [attributeMap(), observerMap()],
165
+ );
166
+ ```
167
+
168
+ `attributeMap()` creates `@attr`-style accessors for leaf bindings, and
169
+ `observerMap()` creates deep observable accessors for discovered root
170
+ properties. Declarative templates assign `definition.schema` during template
171
+ resolution so these extensions always have schema data when used with
172
+ `declarativeTemplate()`. For non-declarative/manual schema use, import `Schema`
173
+ from `@microsoft/fast-element` and pass it on the element definition;
174
+ `observerMap()` can also receive
175
+ `observerMap({ schema })` directly. When both extensions are present, attribute
176
+ mapping runs before observer mapping.
177
+
178
+ Declarative utilities such as `deepMerge` are available from
179
+ `@microsoft/fast-element/declarative-utilities.js`. See
180
+ [`DECLARATIVE_HTML.md`](./DECLARATIVE_HTML.md) for declarative implementation
181
+ details and the
182
+ [Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/)
183
+ for guides on writing f-templates, defining declarative elements, and
184
+ server-side rendering. Declarative event bindings use `$e` for the DOM event
185
+ object and `$c` for the execution context.
186
+
187
+ ## Prerendered Content Optimization
188
+
189
+ Hydration of prerendered content is **opt-in**. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` before any FAST elements connect to activate the hydration path:
190
+
191
+ ```typescript
192
+ import { enableHydration } from "@microsoft/fast-element/hydration.js";
193
+
194
+ enableHydration({
195
+ hydrationComplete() {
196
+ console.log("hydration complete");
197
+ },
198
+ });
199
+ ```
200
+
201
+ By default, hydration handles the initial prerendered batch and then no-ops
202
+ after `hydrationComplete` fires. If your app streams Declarative Shadow DOM
203
+ after the initial batch, keep the hydration hook active:
204
+
205
+ ```typescript
206
+ import { enableHydration, StopHydration } from "@microsoft/fast-element/hydration.js";
207
+
208
+ enableHydration({
209
+ stopHydration: StopHydration.never,
210
+ });
211
+ ```
212
+
213
+ When hydration is enabled and a FAST element connects with an existing shadow root (from server-side rendering or declarative shadow DOM), `ElementController` detects this and hydrates instead of re-rendering. Two properties on the controller let you inspect the result:
214
+
215
+ - **`isPrerendered: Promise<boolean>`** — resolves `true` when the element had a declarative shadow root (DSD) at connect time, regardless of whether hydration ran.
216
+ - **`isHydrated: Promise<boolean>`** — resolves `true` only when hydration actually ran successfully.
217
+
218
+ This enables several optimizations:
219
+
220
+ - **Hydration instead of re-render**: The template uses `hydrate()` to map existing DOM nodes to binding targets rather than cloning new DOM.
221
+ - **Declarative template resolution**: `declarativeTemplate()` waits for the
222
+ matching `<f-template>` before `define()` completes, so connected elements
223
+ hydrate with a concrete template.
224
+ - **Attribute skip**: `onAttributeChangedCallback()` skips processing during initial upgrade when the element is prerendered, since server-rendered attribute values are already correct.
225
+ - **Binding skip**: `HTMLBindingDirective.bind()` skips `updateTarget` for `attribute` and `booleanAttribute` aspect types when the view is prerendered.
226
+
227
+ ### Hydration Mismatch Diagnostics
228
+
229
+ If a prerendered DOM diverges from the client template in a way FAST cannot
230
+ reconcile (the `render()` empty-boundary and `repeat()` count-mismatch cases
231
+ recover silently), `HydrationBindingError` or `HydrationTargetElementError` is
232
+ thrown. By default the message is a single line pointing at the opt-in
233
+ `hydrationDebugger()`. Install the debugger to get a rich
234
+ "Expected … / Received …" report with the SSR HTML snippet and structured
235
+ `expected` / `received` fields on the thrown error:
236
+
237
+ ```typescript
238
+ import { enableHydration, hydrationDebugger } from "@microsoft/fast-element/hydration.js";
239
+
240
+ enableHydration({ debugger: hydrationDebugger() });
241
+ ```
242
+
243
+ The debugger module is tree-shaken out of production hydration bundles when
244
+ not imported, so the rich diagnostic helpers only land in builds that opt in.
245
+
246
+ Per-element lifecycle callbacks can be passed directly to `declarativeTemplate()`:
247
+
248
+ ```typescript
249
+ import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
250
+
251
+ MyComponent.define({
252
+ name: "my-component",
253
+ template: declarativeTemplate({
254
+ elementWillHydrate(source) {
255
+ console.log(`${source.localName} will hydrate`);
256
+ },
257
+ elementDidHydrate(source) {
258
+ console.log(`${source.localName} hydrated`);
259
+ },
260
+ }),
261
+ });
262
+ ```
263
+
264
+ Component authors can await both promises to distinguish prerendered content from successful hydration:
265
+
266
+ ```typescript
267
+ const controller = this.$fastController;
268
+ const prerendered = await controller.isPrerendered;
269
+ const hydrated = await controller.isHydrated;
270
+
271
+ if (prerendered && !hydrated) {
272
+ // Had DSD but hydration wasn't enabled — client-side rendered
273
+ }
274
+ ```
275
+
276
+ Custom directives can also await `controller.isPrerendered` and `controller.isHydrated` (both `Promise<boolean>` on the `ViewController` interface) to determine how the view's content was rendered.
277
+
278
+ ## Define Extensions
279
+
280
+ The static `define()` method on a `FASTElement` subclass accepts an optional second argument — an array of extension callbacks that are invoked with the resolved element definition before the element is registered with the platform. This enables a plugin pattern where reusable behaviors can hook into element registration.
281
+
282
+ ```typescript
283
+ import { FASTElement, type FASTElementExtension } from "@microsoft/fast-element";
284
+
285
+ function logger(): FASTElementExtension {
286
+ return definition => {
287
+ console.log(`Defining element: ${definition.name}`);
288
+ };
289
+ }
290
+
291
+ class MyComponent extends FASTElement {
292
+ // component code
293
+ }
294
+
295
+ MyComponent.define({ name: "my-component", template, styles }, [logger()]);
296
+ ```
297
+ Each extension receives the full `FASTElementDefinition`, which includes the resolved element name, type, template, styles, and attribute metadata. Extensions run before `customElements.define()`, so any setup they perform is available when existing DOM elements are upgraded.