@microsoft/fast-element 3.0.0-rc.1 → 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 (286) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +50 -14
  3. package/dist/context/context.api.json +13 -13
  4. package/dist/declarative/declarative.api.json +654 -15
  5. package/dist/di/di.api.json +15 -15
  6. package/dist/dts/__test__/helpers.d.ts +6 -0
  7. package/dist/dts/__test__/setup-node.d.ts +0 -0
  8. package/dist/dts/binding/binding.d.ts +15 -5
  9. package/dist/dts/binding/one-time.d.ts +1 -1
  10. package/dist/dts/binding/one-way.d.ts +1 -1
  11. package/dist/dts/binding/signal.d.ts +1 -1
  12. package/dist/dts/binding/two-way.d.ts +1 -1
  13. package/dist/dts/components/attributes.d.ts +1 -1
  14. package/dist/dts/components/enable-hydration.d.ts +22 -2
  15. package/dist/dts/components/fast-definitions.d.ts +7 -4
  16. package/dist/dts/components/fast-element.d.ts +42 -12
  17. package/dist/dts/components/hydration-tracker.d.ts +47 -4
  18. package/dist/dts/components/hydration.d.ts +5 -0
  19. package/dist/dts/context.d.ts +7 -7
  20. package/dist/dts/declarative/debug.d.ts +2 -3
  21. package/dist/dts/declarative/index.d.ts +3 -2
  22. package/dist/dts/declarative/interfaces.d.ts +1 -2
  23. package/dist/dts/declarative/template.d.ts +2 -1
  24. package/dist/dts/declarative/utilities.d.ts +50 -4
  25. package/dist/dts/di/di.d.ts +6 -6
  26. package/dist/dts/dom-policy.d.ts +22 -4
  27. package/dist/dts/dom.d.ts +4 -16
  28. package/dist/dts/hydration/diagnostics.d.ts +93 -0
  29. package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
  30. package/dist/dts/hydration/messages.d.ts +62 -0
  31. package/dist/dts/hydration/target-builder.d.ts +26 -1
  32. package/dist/dts/hydration.d.ts +7 -3
  33. package/dist/dts/index.d.ts +7 -3
  34. package/dist/dts/interfaces.d.ts +1 -0
  35. package/dist/dts/observation/observable.d.ts +3 -3
  36. package/dist/dts/platform.d.ts +20 -4
  37. package/dist/dts/registry.d.ts +1 -0
  38. package/dist/dts/templating/children.d.ts +1 -1
  39. package/dist/dts/templating/compiler.d.ts +1 -1
  40. package/dist/dts/templating/html-binding-directive.d.ts +6 -2
  41. package/dist/dts/templating/html-directive.d.ts +2 -1
  42. package/dist/dts/templating/hydration-view.d.ts +24 -3
  43. package/dist/dts/templating/ref.d.ts +1 -1
  44. package/dist/dts/templating/render.d.ts +2 -2
  45. package/dist/dts/templating/repeat.d.ts +1 -1
  46. package/dist/dts/templating/slotted.d.ts +1 -1
  47. package/dist/dts/templating/template.d.ts +5 -5
  48. package/dist/dts/templating/when.d.ts +1 -1
  49. package/dist/dts/testing/fakes.d.ts +4 -4
  50. package/dist/esm/__test__/helpers.js +22 -0
  51. package/dist/esm/__test__/setup-node.js +18 -0
  52. package/dist/esm/binding/two-way.js +1 -2
  53. package/dist/esm/components/attributes.js +12 -8
  54. package/dist/esm/components/element-controller.js +11 -6
  55. package/dist/esm/components/enable-hydration.js +27 -3
  56. package/dist/esm/components/fast-definitions.js +19 -18
  57. package/dist/esm/components/hydration-tracker.js +34 -5
  58. package/dist/esm/components/hydration.js +85 -6
  59. package/dist/esm/debug.js +1 -0
  60. package/dist/esm/declarative/attribute-map.js +2 -1
  61. package/dist/esm/declarative/debug.js +0 -1
  62. package/dist/esm/declarative/index.js +1 -0
  63. package/dist/esm/declarative/interfaces.js +0 -1
  64. package/dist/esm/declarative/observer-map-utilities.js +58 -55
  65. package/dist/esm/declarative/template-bridge.js +4 -14
  66. package/dist/esm/declarative/template.js +4 -3
  67. package/dist/esm/declarative/utilities.js +236 -1
  68. package/dist/esm/di/di.js +2 -1
  69. package/dist/esm/dom-policy.js +33 -4
  70. package/dist/esm/hydration/diagnostics.js +50 -0
  71. package/dist/esm/hydration/hydration-debugger.js +112 -0
  72. package/dist/esm/hydration/messages.js +84 -0
  73. package/dist/esm/hydration/target-builder.js +65 -19
  74. package/dist/esm/hydration.js +3 -1
  75. package/dist/esm/index.js +6 -2
  76. package/dist/esm/interfaces.js +1 -0
  77. package/dist/esm/metadata.js +2 -8
  78. package/dist/esm/observation/notifier.js +2 -4
  79. package/dist/esm/registry.js +1 -0
  80. package/dist/esm/templating/html-binding-directive.js +1 -1
  81. package/dist/esm/templating/hydration-view.js +20 -27
  82. package/dist/esm/templating/render.js +39 -18
  83. package/dist/esm/templating/repeat.js +51 -17
  84. package/dist/esm/templating/view.js +1 -1
  85. package/dist/esm/testing/fixture.js +2 -2
  86. package/dist/esm/testing/timeout.js +2 -2
  87. package/dist/fast-element.api.json +1329 -99
  88. package/dist/fast-element.d.ts +147 -66
  89. package/dist/fast-element.debug.js +392 -99
  90. package/dist/fast-element.debug.min.js +2 -2
  91. package/dist/fast-element.js +392 -99
  92. package/dist/fast-element.min.js +2 -2
  93. package/dist/fast-element.untrimmed.d.ts +133 -70
  94. package/dist/hydration/hydration.api.json +1280 -57
  95. package/dist/styles/styles.api.json +1 -1
  96. package/package.json +21 -9
  97. package/ARCHITECTURE_FASTELEMENT.md +0 -63
  98. package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +0 -36
  99. package/ARCHITECTURE_INTRO.md +0 -10
  100. package/ARCHITECTURE_OVERVIEW.md +0 -52
  101. package/ARCHITECTURE_UPDATES.md +0 -11
  102. package/CHANGELOG.json +0 -2275
  103. package/DECLARATIVE_DESIGN.md +0 -806
  104. package/DECLARATIVE_HTML.md +0 -470
  105. package/DECLARATIVE_MIGRATION.md +0 -215
  106. package/DECLARATIVE_RENDERING.md +0 -530
  107. package/DECLARATIVE_RENDERING_LIFECYCLE.md +0 -288
  108. package/DECLARATIVE_SCHEMA_OBSERVER_MAP.md +0 -489
  109. package/DESIGN.md +0 -615
  110. package/MIGRATION.md +0 -387
  111. package/SIZES.md +0 -25
  112. package/api-extractor.arrays.json +0 -15
  113. package/api-extractor.context.json +0 -15
  114. package/api-extractor.declarative.json +0 -15
  115. package/api-extractor.di.json +0 -15
  116. package/api-extractor.hydration.json +0 -15
  117. package/api-extractor.styles.json +0 -15
  118. package/biome.json +0 -4
  119. package/docs/ACKNOWLEDGEMENTS.md +0 -12
  120. package/docs/api-report.api.md +0 -1299
  121. package/docs/arrays/api-report.api.md +0 -114
  122. package/docs/context/api-report.api.md +0 -69
  123. package/docs/declarative/api-report.api.md +0 -397
  124. package/docs/di/api-report.api.md +0 -315
  125. package/docs/fast-element-2-changes.md +0 -15
  126. package/docs/hydration/api-report.api.md +0 -285
  127. package/docs/styles/api-report.api.md +0 -135
  128. package/playwright.config.ts +0 -26
  129. package/playwright.declarative.config.ts +0 -26
  130. package/playwright.declarative.webui.config.ts +0 -20
  131. package/scripts/declarative/build-fixtures-with-webui.js +0 -135
  132. package/scripts/declarative/build-fixtures.js +0 -49
  133. package/scripts/declarative/build-fixtures.utilities.js +0 -101
  134. package/scripts/measure-sizes.js +0 -219
  135. package/scripts/run-api-extractor.js +0 -70
  136. package/test/declarative/fixtures/README.md +0 -72
  137. package/test/declarative/fixtures/WRITING_FIXTURES.md +0 -330
  138. package/test/declarative/fixtures/bindings/README.md +0 -12
  139. package/test/declarative/fixtures/bindings/attribute/entry.html +0 -13
  140. package/test/declarative/fixtures/bindings/attribute/fast-build.config.json +0 -6
  141. package/test/declarative/fixtures/bindings/attribute/index.html +0 -25
  142. package/test/declarative/fixtures/bindings/attribute/main.ts +0 -41
  143. package/test/declarative/fixtures/bindings/attribute/state.json +0 -8
  144. package/test/declarative/fixtures/bindings/attribute/templates.html +0 -11
  145. package/test/declarative/fixtures/bindings/content/entry.html +0 -12
  146. package/test/declarative/fixtures/bindings/content/fast-build.config.json +0 -6
  147. package/test/declarative/fixtures/bindings/content/index.html +0 -19
  148. package/test/declarative/fixtures/bindings/content/main.ts +0 -27
  149. package/test/declarative/fixtures/bindings/content/state.json +0 -4
  150. package/test/declarative/fixtures/bindings/content/templates.html +0 -6
  151. package/test/declarative/fixtures/bindings/dot-syntax/entry.html +0 -11
  152. package/test/declarative/fixtures/bindings/dot-syntax/fast-build.config.json +0 -6
  153. package/test/declarative/fixtures/bindings/dot-syntax/index.html +0 -47
  154. package/test/declarative/fixtures/bindings/dot-syntax/main.ts +0 -59
  155. package/test/declarative/fixtures/bindings/dot-syntax/state.json +0 -16
  156. package/test/declarative/fixtures/bindings/dot-syntax/templates.html +0 -17
  157. package/test/declarative/fixtures/bindings/event/entry.html +0 -11
  158. package/test/declarative/fixtures/bindings/event/fast-build.config.json +0 -6
  159. package/test/declarative/fixtures/bindings/event/index.html +0 -43
  160. package/test/declarative/fixtures/bindings/event/main.ts +0 -43
  161. package/test/declarative/fixtures/bindings/event/state.json +0 -3
  162. package/test/declarative/fixtures/bindings/event/templates.html +0 -18
  163. package/test/declarative/fixtures/bindings/host/entry.html +0 -40
  164. package/test/declarative/fixtures/bindings/host/fast-build.config.json +0 -6
  165. package/test/declarative/fixtures/bindings/host/index.html +0 -96
  166. package/test/declarative/fixtures/bindings/host/main.ts +0 -222
  167. package/test/declarative/fixtures/bindings/host/state.json +0 -9
  168. package/test/declarative/fixtures/bindings/host/templates.html +0 -55
  169. package/test/declarative/fixtures/directives/README.md +0 -12
  170. package/test/declarative/fixtures/directives/children/entry.html +0 -11
  171. package/test/declarative/fixtures/directives/children/fast-build.config.json +0 -6
  172. package/test/declarative/fixtures/directives/children/index.html +0 -15
  173. package/test/declarative/fixtures/directives/children/main.ts +0 -22
  174. package/test/declarative/fixtures/directives/children/state.json +0 -3
  175. package/test/declarative/fixtures/directives/children/templates.html +0 -3
  176. package/test/declarative/fixtures/directives/ref/entry.html +0 -11
  177. package/test/declarative/fixtures/directives/ref/fast-build.config.json +0 -6
  178. package/test/declarative/fixtures/directives/ref/index.html +0 -15
  179. package/test/declarative/fixtures/directives/ref/main.ts +0 -17
  180. package/test/declarative/fixtures/directives/ref/state.json +0 -1
  181. package/test/declarative/fixtures/directives/ref/templates.html +0 -3
  182. package/test/declarative/fixtures/directives/repeat/entry.html +0 -21
  183. package/test/declarative/fixtures/directives/repeat/fast-build.config.json +0 -6
  184. package/test/declarative/fixtures/directives/repeat/index.html +0 -133
  185. package/test/declarative/fixtures/directives/repeat/main.ts +0 -110
  186. package/test/declarative/fixtures/directives/repeat/sprites.svg +0 -8
  187. package/test/declarative/fixtures/directives/repeat/state.json +0 -10
  188. package/test/declarative/fixtures/directives/repeat/templates.html +0 -75
  189. package/test/declarative/fixtures/directives/slotted/entry.html +0 -17
  190. package/test/declarative/fixtures/directives/slotted/fast-build.config.json +0 -6
  191. package/test/declarative/fixtures/directives/slotted/index.html +0 -27
  192. package/test/declarative/fixtures/directives/slotted/main.ts +0 -29
  193. package/test/declarative/fixtures/directives/slotted/state.json +0 -1
  194. package/test/declarative/fixtures/directives/slotted/templates.html +0 -7
  195. package/test/declarative/fixtures/directives/when/entry.html +0 -51
  196. package/test/declarative/fixtures/directives/when/fast-build.config.json +0 -6
  197. package/test/declarative/fixtures/directives/when/index.html +0 -136
  198. package/test/declarative/fixtures/directives/when/main.ts +0 -172
  199. package/test/declarative/fixtures/directives/when/state.json +0 -12
  200. package/test/declarative/fixtures/directives/when/templates.html +0 -75
  201. package/test/declarative/fixtures/ecosystem/README.md +0 -11
  202. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/entry.html +0 -12
  203. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/fast-build.config.json +0 -6
  204. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/index.html +0 -20
  205. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/main.ts +0 -68
  206. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/state.json +0 -4
  207. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/templates.html +0 -7
  208. package/test/declarative/fixtures/ecosystem/errors/entry.html +0 -12
  209. package/test/declarative/fixtures/ecosystem/errors/fast-build.config.json +0 -6
  210. package/test/declarative/fixtures/ecosystem/errors/index.html +0 -20
  211. package/test/declarative/fixtures/ecosystem/errors/main.ts +0 -17
  212. package/test/declarative/fixtures/ecosystem/errors/state.json +0 -1
  213. package/test/declarative/fixtures/ecosystem/errors/templates.html +0 -7
  214. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/entry.html +0 -17
  215. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/fast-build.config.json +0 -6
  216. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/index.html +0 -56
  217. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/main.ts +0 -134
  218. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/state.json +0 -12
  219. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/templates.html +0 -34
  220. package/test/declarative/fixtures/ecosystem/performance-metrics/entry.html +0 -25
  221. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-build.config.json +0 -6
  222. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-card.css +0 -10
  223. package/test/declarative/fixtures/ecosystem/performance-metrics/index.html +0 -181
  224. package/test/declarative/fixtures/ecosystem/performance-metrics/main.ts +0 -58
  225. package/test/declarative/fixtures/ecosystem/performance-metrics/state.json +0 -6
  226. package/test/declarative/fixtures/ecosystem/performance-metrics/templates.html +0 -15
  227. package/test/declarative/fixtures/extensions/README.md +0 -15
  228. package/test/declarative/fixtures/extensions/attribute-map/entry.html +0 -14
  229. package/test/declarative/fixtures/extensions/attribute-map/fast-build.config.json +0 -6
  230. package/test/declarative/fixtures/extensions/attribute-map/index.html +0 -31
  231. package/test/declarative/fixtures/extensions/attribute-map/main.ts +0 -40
  232. package/test/declarative/fixtures/extensions/attribute-map/state.json +0 -4
  233. package/test/declarative/fixtures/extensions/attribute-map/templates.html +0 -14
  234. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/entry.html +0 -12
  235. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/fast-build.config.json +0 -7
  236. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/index.html +0 -25
  237. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/main.ts +0 -31
  238. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/state.json +0 -5
  239. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/templates.html +0 -11
  240. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/entry.html +0 -13
  241. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/fast-build.config.json +0 -7
  242. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/index.html +0 -23
  243. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/main.ts +0 -37
  244. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/state.json +0 -1
  245. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/templates.html +0 -9
  246. package/test/declarative/fixtures/extensions/observer-map/entry.html +0 -15
  247. package/test/declarative/fixtures/extensions/observer-map/fast-build.config.json +0 -6
  248. package/test/declarative/fixtures/extensions/observer-map/index.html +0 -442
  249. package/test/declarative/fixtures/extensions/observer-map/main.ts +0 -482
  250. package/test/declarative/fixtures/extensions/observer-map/state.json +0 -158
  251. package/test/declarative/fixtures/extensions/observer-map/templates.html +0 -172
  252. package/test/declarative/fixtures/extensions/observer-map-config-object/entry.html +0 -16
  253. package/test/declarative/fixtures/extensions/observer-map-config-object/fast-build.config.json +0 -6
  254. package/test/declarative/fixtures/extensions/observer-map-config-object/index.html +0 -27
  255. package/test/declarative/fixtures/extensions/observer-map-config-object/main.ts +0 -53
  256. package/test/declarative/fixtures/extensions/observer-map-config-object/state.json +0 -9
  257. package/test/declarative/fixtures/extensions/observer-map-config-object/templates.html +0 -12
  258. package/test/declarative/fixtures/extensions/observer-map-deep-merge/README.md +0 -98
  259. package/test/declarative/fixtures/extensions/observer-map-deep-merge/entry.html +0 -156
  260. package/test/declarative/fixtures/extensions/observer-map-deep-merge/fast-build.config.json +0 -6
  261. package/test/declarative/fixtures/extensions/observer-map-deep-merge/index.html +0 -376
  262. package/test/declarative/fixtures/extensions/observer-map-deep-merge/main.ts +0 -366
  263. package/test/declarative/fixtures/extensions/observer-map-deep-merge/state.json +0 -69
  264. package/test/declarative/fixtures/extensions/observer-map-deep-merge/templates.html +0 -91
  265. package/test/declarative/fixtures/extensions/observer-map-properties/entry.html +0 -14
  266. package/test/declarative/fixtures/extensions/observer-map-properties/fast-build.config.json +0 -6
  267. package/test/declarative/fixtures/extensions/observer-map-properties/index.html +0 -110
  268. package/test/declarative/fixtures/extensions/observer-map-properties/main.ts +0 -175
  269. package/test/declarative/fixtures/extensions/observer-map-properties/state.json +0 -29
  270. package/test/declarative/fixtures/extensions/observer-map-properties/templates.html +0 -55
  271. package/test/declarative/fixtures/scenarios/README.md +0 -7
  272. package/test/declarative/fixtures/scenarios/nested-elements/entry.html +0 -16
  273. package/test/declarative/fixtures/scenarios/nested-elements/fast-build.config.json +0 -6
  274. package/test/declarative/fixtures/scenarios/nested-elements/index.html +0 -126
  275. package/test/declarative/fixtures/scenarios/nested-elements/main.ts +0 -214
  276. package/test/declarative/fixtures/scenarios/nested-elements/state.json +0 -10
  277. package/test/declarative/fixtures/scenarios/nested-elements/templates.html +0 -54
  278. package/test/declarative/index.html +0 -12
  279. package/test/declarative/vite.config.ts +0 -55
  280. package/test/declarative-main.ts +0 -6
  281. package/test/extension-subpaths-main.ts +0 -9
  282. package/test/index.html +0 -11
  283. package/test/main.ts +0 -109
  284. package/test/pure-declarative-main.ts +0 -1
  285. package/test/vite.config.ts +0 -19
  286. package/tsconfig.api-extractor.json +0 -6
@@ -1,3 +1,4 @@
1
1
  export { Schema, schemaRegistry, } from "../components/schema.js";
2
+ export { DOMPolicy, } from "../dom-policy.js";
2
3
  export { declarativeTemplate } from "./template.js";
3
4
  export { TemplateParser } from "./template-parser.js";
@@ -6,5 +6,4 @@ export var Message;
6
6
  (function (Message) {
7
7
  Message[Message["noTemplateProvided"] = 2000] = "noTemplateProvided";
8
8
  Message[Message["moreThanOneTemplateProvided"] = 2001] = "moreThanOneTemplateProvided";
9
- Message[Message["moreThanOneMatchingTemplateProvided"] = 2002] = "moreThanOneMatchingTemplateProvided";
10
9
  })(Message || (Message = {}));
@@ -7,7 +7,7 @@ const objectTargetsMap = new WeakMap();
7
7
  /**
8
8
  * A map of arrays being observed.
9
9
  */
10
- const observedArraysMap = new WeakMap();
10
+ const observedArraysMap = new WeakSet();
11
11
  /**
12
12
  * Determines the data type of the provided data
13
13
  * @param data - The data to analyze
@@ -76,6 +76,37 @@ function hasObservedSchemaDescendant(schema) {
76
76
  function isSchemaExcluded(schema) {
77
77
  return (schema === null || schema === void 0 ? void 0 : schema.$observe) === false && !hasObservedSchemaDescendant(schema);
78
78
  }
79
+ function defineObservableProperty(targetObject, key, schema, rootSchema, target, rootProperty) {
80
+ if (!Observable.getAccessors(targetObject).some(accessor => accessor.name === key)) {
81
+ const field = `_${key}`;
82
+ const callback = `${key}Changed`;
83
+ const accessor = {
84
+ name: key,
85
+ getValue(source) {
86
+ Observable.track(source, key);
87
+ return source[field];
88
+ },
89
+ setValue(source, value) {
90
+ const oldValue = source[field];
91
+ const newValue = assignObservables(schema, rootSchema, value, target, rootProperty);
92
+ if (oldValue !== newValue) {
93
+ source[field] = newValue;
94
+ const changeCallback = source[callback];
95
+ if (typeof changeCallback === "function") {
96
+ changeCallback.call(source, oldValue, newValue);
97
+ }
98
+ Observable.notify(source, key);
99
+ }
100
+ },
101
+ };
102
+ Observable.defineProperty(targetObject, accessor);
103
+ }
104
+ }
105
+ function findArrayItemDef(schema) {
106
+ var _a;
107
+ const items = schema.items;
108
+ return (_a = findDef(schema)) !== null && _a !== void 0 ? _a : (items === undefined ? null : findDef(items));
109
+ }
79
110
  /**
80
111
  * Assigns Observable properties to items in an array and sets up change notifications
81
112
  * @param proxiedData - The array data to make observable
@@ -92,28 +123,31 @@ function assignObservablesToArray(proxiedData, schema, rootSchema, target, rootP
92
123
  const data = schemaProperties
93
124
  ? proxiedData.map((item) => {
94
125
  const originalItem = Object.assign({}, item);
95
- assignProxyToItemsInArray(item, originalItem, schema, rootSchema);
126
+ assignProxyToItemsInArray(item, originalItem, schema, rootSchema, target, rootProperty);
96
127
  return Object.assign(item, originalItem);
97
128
  })
98
129
  : proxiedData;
99
- Observable.getNotifier(data).subscribe({
100
- handleChange(subject, args) {
101
- args.forEach((arg) => {
102
- if (arg.addedCount > 0) {
103
- if (schemaProperties) {
104
- for (let i = arg.addedCount - 1; i >= 0; i--) {
105
- const item = subject[arg.index + i];
106
- const originalItem = Object.assign({}, item);
107
- assignProxyToItemsInArray(item, originalItem, schema, rootSchema);
108
- Object.assign(item, originalItem);
130
+ if (!observedArraysMap.has(data)) {
131
+ observedArraysMap.add(data);
132
+ Observable.getNotifier(data).subscribe({
133
+ handleChange(subject, args) {
134
+ args.forEach((arg) => {
135
+ if (arg.addedCount > 0) {
136
+ if (schemaProperties) {
137
+ for (let i = arg.addedCount - 1; i >= 0; i--) {
138
+ const item = subject[arg.index + i];
139
+ const originalItem = Object.assign({}, item);
140
+ assignProxyToItemsInArray(item, originalItem, schema, rootSchema, target, rootProperty);
141
+ Object.assign(item, originalItem);
142
+ }
109
143
  }
144
+ // Notify observers of the target object's root property
145
+ Observable.notify(target, rootProperty);
110
146
  }
111
- // Notify observers of the target object's root property
112
- Observable.notify(target, rootProperty);
113
- }
114
- });
115
- },
116
- });
147
+ });
148
+ },
149
+ });
150
+ }
117
151
  if (schemaProperties !== null) {
118
152
  return data;
119
153
  }
@@ -175,20 +209,6 @@ export function findDef(schema) {
175
209
  }
176
210
  return null;
177
211
  }
178
- /**
179
- * Subscribe to a notifier on data that is an observed array
180
- * @param data - The array being observed
181
- * @param updateArrayObservables - The function to call to update the array item
182
- */
183
- function assignSubscribeToObservableArray(data, updateArrayObservables) {
184
- Observable.getNotifier(data).subscribe({
185
- handleChange(subject, args) {
186
- args.forEach((arg) => {
187
- updateArrayObservables();
188
- });
189
- },
190
- });
191
- }
192
212
  /**
193
213
  * Assign observables to data
194
214
  * @param schema - The schema
@@ -205,15 +225,9 @@ export function assignObservables(schema, rootSchema, data, target, rootProperty
205
225
  let proxiedData = data;
206
226
  switch (dataType) {
207
227
  case "array": {
208
- const context = findDef(schema);
228
+ const context = findArrayItemDef(schema);
209
229
  if (context) {
210
230
  proxiedData = assignObservablesToArray(proxiedData, (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context], rootSchema, target, rootProperty);
211
- if (!observedArraysMap.has(proxiedData)) {
212
- observedArraysMap.set(proxiedData, assignSubscribeToObservableArray(proxiedData, () => {
213
- var _a;
214
- return assignObservablesToArray(proxiedData, (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context], rootSchema, target, rootProperty);
215
- }));
216
- }
217
231
  }
218
232
  else {
219
233
  // Primitive array (items have no schema $ref): wrap in a proxy so that
@@ -237,7 +251,7 @@ export function assignObservables(schema, rootSchema, data, target, rootProperty
237
251
  * @param schema - The schema mapping to the items in the array
238
252
  * @param rootSchema - The root schema assigned to the root property
239
253
  */
240
- function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSchema) {
254
+ function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSchema, target, rootProperty) {
241
255
  const schemaProperties = getSchemaProperties(schema);
242
256
  getObjectProperties(proxiableItem, schemaProperties).forEach(key => {
243
257
  const childSchema = schemaProperties[key];
@@ -252,7 +266,7 @@ function assignProxyToItemsInArray(proxiableItem, originalItem, schema, rootSche
252
266
  // Assign the proxy first
253
267
  originalItem[key] = assignProxyToItemsInObject(proxiableItem, key, originalItem[key], schemaProperties[key], rootSchema);
254
268
  // Then make the property observable
255
- Observable.defineProperty(proxiableItem, key);
269
+ defineObservableProperty(proxiableItem, key, childSchema, rootSchema, target, rootProperty);
256
270
  });
257
271
  }
258
272
  /**
@@ -303,14 +317,11 @@ function assignProxyToItemsInObject(target, rootProperty, data, schema, rootSche
303
317
  }
304
318
  }
305
319
  else if (type === "array") {
306
- const context = findDef(schema.items);
320
+ const context = findArrayItemDef(schema);
307
321
  if (context) {
308
322
  const definition = (_a = rootSchema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[context];
309
323
  if ((definition === null || definition === void 0 ? void 0 : definition.type) === "object") {
310
324
  proxiedData = assignObservablesToArray(proxiedData, definition, rootSchema, target, rootProperty);
311
- if (!observedArraysMap.has(proxiedData)) {
312
- observedArraysMap.set(proxiedData, assignSubscribeToObservableArray(proxiedData, () => assignObservablesToArray(proxiedData, definition, rootSchema, target, rootProperty)));
313
- }
314
325
  }
315
326
  }
316
327
  }
@@ -374,7 +385,7 @@ export function assignProxy(schema, rootSchema, target, rootProperty, object) {
374
385
  obj[prop] = value;
375
386
  return true;
376
387
  }
377
- obj[prop] = assignObservables(schema, rootSchema, value, target, rootProperty);
388
+ obj[prop] = assignObservables(childSchema !== null && childSchema !== void 0 ? childSchema : schema, rootSchema, value, target, rootProperty);
378
389
  notifyObservables(proxy);
379
390
  return true;
380
391
  },
@@ -531,16 +542,8 @@ export function deepMerge(target, source) {
531
542
  }
532
543
  hasChanges = true;
533
544
  if (Array.isArray(sourceValue)) {
534
- const isTargetArray = Array.isArray(targetValue);
535
545
  const clonedItems = sourceValue.map((item) => isPlainObject(item) ? Object.assign({}, item) : item);
536
- if (isTargetArray) {
537
- // Use splice to maintain observable array tracking
538
- targetValue.splice(0, targetValue.length, ...clonedItems);
539
- }
540
- else {
541
- // Target isn't an array, replace it
542
- target[key] = clonedItems;
543
- }
546
+ target[key] = clonedItems;
544
547
  continue;
545
548
  }
546
549
  if (isPlainObject(sourceValue)) {
@@ -1,5 +1,3 @@
1
- import { FAST } from "../platform.js";
2
- import { Message } from "./interfaces.js";
3
1
  /**
4
2
  * Coordinates declarative template publishers and FAST element definitions.
5
3
  * Requests are keyed by registry + element name so scoped registries can
@@ -75,20 +73,12 @@ export class DeclarativeTemplateBridge {
75
73
  if (!bucket) {
76
74
  return;
77
75
  }
78
- const publishers = [...bucket.publishers];
79
- if (publishers.length > 1) {
80
- const error = FAST.error(Message.moreThanOneMatchingTemplateProvided, {
81
- name,
82
- });
83
- for (const request of [...bucket.requests]) {
84
- this.rejectRequest(registry, name, bucket, request, error);
85
- }
86
- return;
87
- }
88
- if (publishers.length === 0) {
76
+ // Set iteration preserves insertion order, so duplicate publishers leave
77
+ // the first connected publisher responsible for pending requests.
78
+ const publisher = bucket.publishers.values().next().value;
79
+ if (publisher === undefined) {
89
80
  return;
90
81
  }
91
- const [publisher] = publishers;
92
82
  for (const request of bucket.requests) {
93
83
  if (request.settled) {
94
84
  continue;
@@ -14,7 +14,7 @@ import { Message } from "./interfaces.js";
14
14
  import { ensureDeclarativeRuntime } from "./runtime.js";
15
15
  import { declarativeTemplateBridge } from "./template-bridge.js";
16
16
  import { TemplateParser } from "./template-parser.js";
17
- import { transformInnerHTML } from "./utilities.js";
17
+ import { escapeBracesInCodeElements, transformInnerHTML } from "./utilities.js";
18
18
  const templateElementName = "f-template";
19
19
  const ensuredTemplateElements = new WeakMap();
20
20
  function isTemplateElementConstructor(value) {
@@ -114,7 +114,8 @@ class FTemplateElement extends HTMLElement {
114
114
  declarativeTemplateBridge.movePublisher(this.registry, previousName !== null && previousName !== void 0 ? previousName : undefined, nextName !== null && nextName !== void 0 ? nextName : undefined, this);
115
115
  }
116
116
  publishTemplate(definition) {
117
- var _a, _b, _c, _d, _e;
117
+ var _a, _b, _c, _d;
118
+ var _e;
118
119
  ensureDeclarativeRuntime();
119
120
  const name = definition.name;
120
121
  const templates = Array.from(this.children).filter((child) => child.tagName === "TEMPLATE");
@@ -130,7 +131,7 @@ class FTemplateElement extends HTMLElement {
130
131
  (_d = (_c = definition.lifecycleCallbacks) === null || _c === void 0 ? void 0 : _c.templateWillUpdate) === null || _d === void 0 ? void 0 : _d.call(_c, name);
131
132
  const schema = (_e = definition.schema) !== null && _e !== void 0 ? _e : new Schema(name);
132
133
  definition.schema = schema;
133
- const innerHTML = transformInnerHTML(this.innerHTML);
134
+ const innerHTML = transformInnerHTML(escapeBracesInCodeElements(this.innerHTML));
134
135
  const parser = new TemplateParser();
135
136
  const { strings, values } = parser.parse(innerHTML, schema);
136
137
  for (const transform of getDefinitionSchemaTransforms(definition)) {
@@ -6,7 +6,7 @@ export { assignObservables, assignProxy, deepEqual, deepMerge, findDef, isPlainO
6
6
  * @public
7
7
  */
8
8
  export const contextPrefixDot = `${executionContextAccessor}.`;
9
- export { eventArgAccessor, executionContextAccessor };
9
+ export { attributeDirectivePrefix, clientSideCloseExpression, clientSideOpenExpression, closeExpression, eventArgAccessor, executionContextAccessor, openExpression, };
10
10
  /**
11
11
  * Parses the arguments string of an event handler binding into an array of
12
12
  * typed argument descriptors. Unrecognised tokens are returned as `"binding"`
@@ -754,6 +754,241 @@ export function transformInnerHTML(innerHTML, index = 0) {
754
754
  }
755
755
  return transformedInnerHTML;
756
756
  }
757
+ /**
758
+ * Tag name of the HTML element whose contents are auto-escaped to render
759
+ * code samples literally. Inside this element FAST binding delimiters
760
+ * (`{{...}}`, `{{{...}}}`, `{...}`) are neutralised by replacing each
761
+ * `{` / `}` with the HTML numeric character reference `{` /
762
+ * `}` so the literal text is rendered instead of a binding.
763
+ *
764
+ * The escape behaviour is split between the server-side renderer
765
+ * (`escape_code_sample_elements` in `microsoft-fast-build`) and the
766
+ * client-side `<f-template>` parser (`escapeBracesInCodeElements`
767
+ * below):
768
+ *
769
+ * - Curly-brace escape runs in **both** server and client because
770
+ * `&#123;` / `&#125;` are decoded to literal `{` / `}` in the DOM
771
+ * and the `.innerHTML` serializer does not re-encode them — so the
772
+ * server-side escape would otherwise be undone on the client.
773
+ * - Angle brackets of FAST directive tags (`<f-when>`, `</f-when>`,
774
+ * `<f-repeat>`, `</f-repeat>`, case-insensitive) inside this element
775
+ * are escaped on the **server only**. The DOM serializer
776
+ * re-encodes `<` / `>` in text content automatically, so the client
777
+ * never sees raw directive tags inside `<code>` regardless of what
778
+ * the page source contained.
779
+ * - Real HTML elements (`<button>`) and custom elements (`<my-widget>`)
780
+ * inside this element keep their angle brackets and continue to
781
+ * render as live DOM elements; only the brace-binding syntax inside
782
+ * their text and attribute values is neutralised.
783
+ * @public
784
+ */
785
+ export const codeElementName = "code";
786
+ const CODE_ESCAPE_VOID_ELEMENTS = new Set([
787
+ "area",
788
+ "base",
789
+ "br",
790
+ "col",
791
+ "embed",
792
+ "hr",
793
+ "img",
794
+ "input",
795
+ "link",
796
+ "meta",
797
+ "param",
798
+ "source",
799
+ "track",
800
+ "wbr",
801
+ ]);
802
+ /**
803
+ * Parse an opening tag at `pos` (which points at `<`). Returns the parsed tag
804
+ * descriptor if `<` introduces an element opening tag, otherwise `null`
805
+ * (e.g. for `</tag>`, `<!--`, `<!doctype`, `<?...`, or end-of-input).
806
+ *
807
+ * The parser is tolerant of attribute values containing `>` only when they
808
+ * are quoted; quoted attribute values are correctly handled so that a `>`
809
+ * inside quotes does not terminate the tag.
810
+ */
811
+ function parseOpeningTagForCodeEscape(html, pos) {
812
+ if (html.charAt(pos) !== "<")
813
+ return null;
814
+ const next = html.charAt(pos + 1);
815
+ if (next === "/" || next === "!" || next === "?" || next === "")
816
+ return null;
817
+ if (!/[A-Za-z]/.test(next))
818
+ return null;
819
+ let nameEnd = pos + 1;
820
+ while (nameEnd < html.length && /[A-Za-z0-9-]/.test(html.charAt(nameEnd))) {
821
+ nameEnd++;
822
+ }
823
+ const tagName = html.slice(pos + 1, nameEnd).toLowerCase();
824
+ if (tagName === "")
825
+ return null;
826
+ let cursor = nameEnd;
827
+ while (cursor < html.length) {
828
+ while (cursor < html.length && /\s/.test(html.charAt(cursor)))
829
+ cursor++;
830
+ const ch = html.charAt(cursor);
831
+ if (ch === ">" || ch === "" || (ch === "/" && html.charAt(cursor + 1) === ">")) {
832
+ break;
833
+ }
834
+ while (cursor < html.length &&
835
+ !/[\s=>/]/.test(html.charAt(cursor)) &&
836
+ html.charAt(cursor) !== "") {
837
+ cursor++;
838
+ }
839
+ let attrTerminator = cursor;
840
+ while (attrTerminator < html.length && /\s/.test(html.charAt(attrTerminator))) {
841
+ attrTerminator++;
842
+ }
843
+ if (html.charAt(attrTerminator) === "=") {
844
+ cursor = attrTerminator + 1;
845
+ while (cursor < html.length && /\s/.test(html.charAt(cursor)))
846
+ cursor++;
847
+ const quote = html.charAt(cursor);
848
+ if (quote === '"' || quote === "'") {
849
+ const end = html.indexOf(quote, cursor + 1);
850
+ cursor = end === -1 ? html.length : end + 1;
851
+ }
852
+ else {
853
+ while (cursor < html.length && !/[\s>]/.test(html.charAt(cursor))) {
854
+ cursor++;
855
+ }
856
+ }
857
+ }
858
+ }
859
+ let isSelfClosing = false;
860
+ if (html.charAt(cursor) === "/" && html.charAt(cursor + 1) === ">") {
861
+ isSelfClosing = true;
862
+ cursor += 2;
863
+ }
864
+ else if (html.charAt(cursor) === ">") {
865
+ cursor += 1;
866
+ }
867
+ else {
868
+ return null;
869
+ }
870
+ return {
871
+ tagName,
872
+ tagStart: pos,
873
+ tagEnd: cursor,
874
+ contentStart: cursor,
875
+ isSelfClosing: isSelfClosing || CODE_ESCAPE_VOID_ELEMENTS.has(tagName),
876
+ };
877
+ }
878
+ /**
879
+ * Find the position of the matching close tag for an element opened at
880
+ * `contentStart` with name `tagName`. Returns the index of the `<` of the
881
+ * matching `</tagName>` close tag, or `html.length` if no matching tag is
882
+ * found. Nested same-name elements are tracked via a depth counter.
883
+ */
884
+ function findMatchingCloseTagForCodeEscape(html, contentStart, tagName) {
885
+ let depth = 1;
886
+ let pos = contentStart;
887
+ const closeNeedle = `</${tagName}`;
888
+ while (pos < html.length) {
889
+ const lt = html.indexOf("<", pos);
890
+ if (lt === -1)
891
+ return html.length;
892
+ const lowerSlice = html.slice(lt, lt + closeNeedle.length).toLowerCase();
893
+ if (lowerSlice === closeNeedle) {
894
+ const charAfter = html.charAt(lt + closeNeedle.length);
895
+ if (charAfter === ">" || /\s/.test(charAfter)) {
896
+ depth--;
897
+ if (depth === 0)
898
+ return lt;
899
+ const gt = html.indexOf(">", lt);
900
+ pos = gt === -1 ? html.length : gt + 1;
901
+ continue;
902
+ }
903
+ }
904
+ if (html.startsWith("<!--", lt)) {
905
+ const end = html.indexOf("-->", lt + 4);
906
+ pos = end === -1 ? html.length : end + 3;
907
+ continue;
908
+ }
909
+ if (html.charAt(lt + 1) === "!" || html.charAt(lt + 1) === "?") {
910
+ const end = html.indexOf(">", lt);
911
+ pos = end === -1 ? html.length : end + 1;
912
+ continue;
913
+ }
914
+ if (html.charAt(lt + 1) === "/") {
915
+ const end = html.indexOf(">", lt);
916
+ pos = end === -1 ? html.length : end + 1;
917
+ continue;
918
+ }
919
+ const opening = parseOpeningTagForCodeEscape(html, lt);
920
+ if (opening === null) {
921
+ pos = lt + 1;
922
+ continue;
923
+ }
924
+ if (opening.tagName === tagName && !opening.isSelfClosing) {
925
+ depth++;
926
+ }
927
+ pos = opening.tagEnd;
928
+ }
929
+ return html.length;
930
+ }
931
+ function escapeBracesInCodeContent(content) {
932
+ return content.replace(/[{}]/g, c => (c === "{" ? "&#123;" : "&#125;"));
933
+ }
934
+ /**
935
+ * Preprocess an HTML string by escaping FAST brace characters inside every
936
+ * `<code>` element. Mirrors part of the brace/angle-bracket escaping
937
+ * behaviour of Microsoft WebUI's `webui-press` markdown renderer so that
938
+ * example template snippets inside `<code>` render literally instead of
939
+ * being interpreted as bindings.
940
+ *
941
+ * Nested `<code>` elements are handled via depth tracking. The pass is
942
+ * idempotent because `{` / `}` inside an already-processed `<code>` have
943
+ * been replaced with entities, so a second pass finds nothing to escape.
944
+ *
945
+ * This is the client-side half of a two-stage escape — see the JSDoc on
946
+ * {@link codeElementName} for why only braces are handled here and
947
+ * `<` / `>` are exclusively handled on the server.
948
+ * @public
949
+ */
950
+ export function escapeBracesInCodeElements(innerHTML) {
951
+ if (innerHTML.indexOf("<code") === -1) {
952
+ return innerHTML;
953
+ }
954
+ let pos = 0;
955
+ let result = "";
956
+ while (pos < innerHTML.length) {
957
+ const lt = innerHTML.indexOf("<", pos);
958
+ if (lt === -1) {
959
+ result += innerHTML.slice(pos);
960
+ break;
961
+ }
962
+ if (innerHTML.startsWith("<!--", lt)) {
963
+ const end = innerHTML.indexOf("-->", lt + 4);
964
+ const tail = end === -1 ? innerHTML.length : end + 3;
965
+ result += innerHTML.slice(pos, tail);
966
+ pos = tail;
967
+ continue;
968
+ }
969
+ const opening = parseOpeningTagForCodeEscape(innerHTML, lt);
970
+ if (opening === null) {
971
+ result += innerHTML.slice(pos, lt + 1);
972
+ pos = lt + 1;
973
+ continue;
974
+ }
975
+ if (opening.tagName !== codeElementName) {
976
+ result += innerHTML.slice(pos, opening.tagEnd);
977
+ pos = opening.tagEnd;
978
+ continue;
979
+ }
980
+ result += innerHTML.slice(pos, opening.tagEnd);
981
+ if (opening.isSelfClosing) {
982
+ pos = opening.tagEnd;
983
+ continue;
984
+ }
985
+ const closeStart = findMatchingCloseTagForCodeEscape(innerHTML, opening.contentStart, codeElementName);
986
+ const innerContent = innerHTML.slice(opening.contentStart, closeStart);
987
+ result += escapeBracesInCodeContent(innerContent);
988
+ pos = closeStart;
989
+ }
990
+ return result;
991
+ }
757
992
  /**
758
993
  * Resolves boolean logic
759
994
  * used for f-when and boolean attributes
package/dist/esm/di/di.js CHANGED
@@ -800,7 +800,8 @@ export class ResolverImpl {
800
800
  }
801
801
  }
802
802
  getFactory(container) {
803
- var _a, _b, _c;
803
+ var _a, _b;
804
+ var _c;
804
805
  switch (this.strategy) {
805
806
  case ResolverStrategy.singleton:
806
807
  case ResolverStrategy.transient:
@@ -1,10 +1,40 @@
1
1
  import { DOMAspect } from "./dom.js";
2
2
  import { isString, Message } from "./interfaces.js";
3
3
  import { FAST } from "./platform.js";
4
+ const surroundingWhitespaceAndControlChars = /^[\u0000-\u0020\u007F]+|[\u0000-\u0020\u007F]+$/g;
5
+ const whitespaceAndControlChars = /[\u0000-\u0020\u007F]+/g;
6
+ const unsafeURLProtocol = /^(?:javascript|vbscript|data):/;
7
+ function trimURL(value) {
8
+ return value.replace(surroundingWhitespaceAndControlChars, "");
9
+ }
10
+ function decodeURL(value) {
11
+ try {
12
+ return decodeURIComponent(value);
13
+ }
14
+ catch (_a) {
15
+ return value;
16
+ }
17
+ }
18
+ function hasUnsafeURLProtocol(value) {
19
+ let normalized = trimURL(value);
20
+ for (let i = 0; i < 3; ++i) {
21
+ const decoded = decodeURL(normalized);
22
+ if (decoded === normalized) {
23
+ break;
24
+ }
25
+ normalized = trimURL(decoded);
26
+ }
27
+ normalized = normalized.replace(whitespaceAndControlChars, "").toLowerCase();
28
+ return unsafeURLProtocol.test(normalized);
29
+ }
30
+ function sanitizeURL(value) {
31
+ const trimmed = trimURL(value);
32
+ return hasUnsafeURLProtocol(trimmed) ? "" : trimmed;
33
+ }
4
34
  function safeURL(tagName, aspect, aspectName, sink) {
5
35
  return (target, name, value, ...rest) => {
6
36
  if (isString(value)) {
7
- value = value.replace(/(javascript:|vbscript:|data:)/, "");
37
+ value = sanitizeURL(value);
8
38
  }
9
39
  sink(target, name, value, ...rest);
10
40
  };
@@ -266,7 +296,7 @@ function createElementGuards(config, defaults) {
266
296
  break;
267
297
  case undefined:
268
298
  // keep the default
269
- result[tag] = createDOMAspectGuards(overrideValue, {});
299
+ result[tag] = createDOMAspectGuards(defaultValue, {});
270
300
  break;
271
301
  default:
272
302
  // override the default aspects
@@ -311,7 +341,7 @@ function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
311
341
  * A helper for creating DOM policies.
312
342
  * @public
313
343
  */
314
- const DOMPolicy = Object.freeze({
344
+ export const DOMPolicy = Object.freeze({
315
345
  /**
316
346
  * Creates a new DOM Policy object.
317
347
  * @param options - The options to use in creating the policy.
@@ -342,4 +372,3 @@ const DOMPolicy = Object.freeze({
342
372
  });
343
373
  },
344
374
  });
345
- export { DOMPolicy };
@@ -0,0 +1,50 @@
1
+ import { formatDefaultMismatchMessage, unknownHostName } from "./messages.js";
2
+ function formatMinimalMessage(hostName, detail) {
3
+ const host = (hostName !== null && hostName !== void 0 ? hostName : unknownHostName).toLowerCase();
4
+ return formatDefaultMismatchMessage(host, detail);
5
+ }
6
+ const defaultDiagnostic = {
7
+ formatBindingMismatch(_factory, _firstChild, _lastChild, hostName) {
8
+ return {
9
+ message: formatMinimalMessage(hostName, undefined),
10
+ };
11
+ },
12
+ formatStructuralError(_node, hostName, expectedDescription) {
13
+ return {
14
+ message: formatMinimalMessage(hostName, expectedDescription),
15
+ };
16
+ },
17
+ };
18
+ let activeDiagnostic = defaultDiagnostic;
19
+ /**
20
+ * Installs a {@link HydrationDiagnostic} as the active formatter for
21
+ * hydration mismatch errors. Called by `enableHydration()` when an opt-in
22
+ * debugger configuration is supplied; not exposed as `@public` because
23
+ * library consumers should always go through `enableHydration` to install
24
+ * a debugger.
25
+ * @internal
26
+ */
27
+ export function installHydrationDiagnostic(diagnostic) {
28
+ activeDiagnostic = diagnostic;
29
+ }
30
+ /**
31
+ * Returns the currently active {@link HydrationDiagnostic} — either the
32
+ * minimal default or one installed by an opt-in debugger.
33
+ * @internal
34
+ */
35
+ export function getHydrationDiagnostic() {
36
+ return activeDiagnostic;
37
+ }
38
+ /**
39
+ * Reads the host element's tag name from any node inside a hydration view.
40
+ * Returns `undefined` when the node is not inside a shadow root.
41
+ * @internal
42
+ */
43
+ export function getHostName(node) {
44
+ var _a;
45
+ if (!node) {
46
+ return undefined;
47
+ }
48
+ const root = node.getRootNode();
49
+ return (_a = root.host) === null || _a === void 0 ? void 0 : _a.nodeName;
50
+ }