@angular/core 16.0.0-next.3 → 16.0.0-next.5

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 (375) hide show
  1. package/{esm2020 → esm2022}/src/application_init.mjs +3 -3
  2. package/{esm2020 → esm2022}/src/application_module.mjs +4 -4
  3. package/esm2022/src/application_ref.mjs +908 -0
  4. package/esm2022/src/application_tokens.mjs +105 -0
  5. package/esm2022/src/change_detection/change_detector_ref.mjs +93 -0
  6. package/esm2022/src/change_detection/differs/iterable_differs.mjs +81 -0
  7. package/esm2022/src/change_detection/differs/keyvalue_differs.mjs +74 -0
  8. package/esm2022/src/compiler/compiler_facade_interface.mjs +29 -0
  9. package/{esm2020 → esm2022}/src/console.mjs +3 -3
  10. package/esm2022/src/core.mjs +56 -0
  11. package/esm2022/src/core_private_export.mjs +39 -0
  12. package/esm2022/src/core_reactivity_export_internal.mjs +12 -0
  13. package/esm2022/src/core_render3_private_export.mjs +37 -0
  14. package/esm2022/src/di/contextual.mjs +54 -0
  15. package/esm2022/src/di/index.mjs +29 -0
  16. package/esm2022/src/di/injector.mjs +62 -0
  17. package/esm2022/src/di/injector_compatibility.mjs +239 -0
  18. package/esm2022/src/di/provider_collection.mjs +279 -0
  19. package/esm2022/src/di/r3_injector.mjs +428 -0
  20. package/esm2022/src/di/reflective_injector.mjs +311 -0
  21. package/{esm2020 → esm2022}/src/errors.mjs +1 -1
  22. package/esm2022/src/hydration/annotate.mjs +426 -0
  23. package/esm2022/src/hydration/api.mjs +143 -0
  24. package/esm2022/src/hydration/cleanup.mjs +103 -0
  25. package/esm2022/src/hydration/compression.mjs +69 -0
  26. package/esm2022/src/hydration/error_handling.mjs +379 -0
  27. package/esm2022/src/hydration/interfaces.mjs +33 -0
  28. package/esm2022/src/hydration/node_lookup_utils.mjs +273 -0
  29. package/esm2022/src/hydration/utils.mjs +219 -0
  30. package/esm2022/src/hydration/views.mjs +84 -0
  31. package/esm2022/src/initial_render_pending_tasks.mjs +75 -0
  32. package/{esm2020 → esm2022}/src/linker/compiler.mjs +5 -5
  33. package/esm2022/src/linker/component_factory_resolver.mjs +42 -0
  34. package/esm2022/src/linker/destroy_ref.mjs +44 -0
  35. package/{esm2020 → esm2022}/src/linker/element_ref.mjs +6 -6
  36. package/esm2022/src/linker/query_list.mjs +169 -0
  37. package/{esm2020 → esm2022}/src/linker/template_ref.mjs +6 -6
  38. package/esm2022/src/linker/view_container_ref.mjs +395 -0
  39. package/esm2022/src/metadata/di.mjs +69 -0
  40. package/esm2022/src/metadata/directives.mjs +116 -0
  41. package/{esm2020 → esm2022}/src/metadata/do_boostrap.mjs +1 -1
  42. package/{esm2020 → esm2022}/src/metadata/ng_module.mjs +2 -2
  43. package/esm2022/src/metadata.mjs +18 -0
  44. package/{esm2020 → esm2022}/src/render/api.mjs +6 -6
  45. package/esm2022/src/render3/component_ref.mjs +386 -0
  46. package/{esm2020 → esm2022}/src/render3/context_discovery.mjs +1 -1
  47. package/esm2022/src/render3/features/standalone_feature.mjs +70 -0
  48. package/esm2022/src/render3/instructions/element.mjs +205 -0
  49. package/{esm2020 → esm2022}/src/render3/instructions/element_container.mjs +2 -5
  50. package/esm2022/src/render3/instructions/element_validation.mjs +271 -0
  51. package/esm2022/src/render3/instructions/listener.mjs +244 -0
  52. package/esm2022/src/render3/instructions/mark_view_dirty.mjs +35 -0
  53. package/esm2022/src/render3/instructions/projection.mjs +121 -0
  54. package/esm2022/src/render3/instructions/shared.mjs +1681 -0
  55. package/{esm2020 → esm2022}/src/render3/instructions/styling.mjs +5 -2
  56. package/esm2022/src/render3/instructions/template.mjs +117 -0
  57. package/esm2022/src/render3/instructions/text.mjs +67 -0
  58. package/esm2022/src/render3/interfaces/public_definitions.mjs +9 -0
  59. package/esm2022/src/render3/interfaces/type_checks.mjs +42 -0
  60. package/esm2022/src/render3/interfaces/view.mjs +49 -0
  61. package/esm2022/src/render3/jit/module.mjs +531 -0
  62. package/esm2022/src/render3/node_manipulation.mjs +960 -0
  63. package/esm2022/src/render3/node_selector_matcher.mjs +426 -0
  64. package/esm2022/src/render3/reactive_lview_consumer.mjs +80 -0
  65. package/esm2022/src/render3/reactivity/effect.mjs +67 -0
  66. package/{esm2020 → esm2022}/src/render3/util/change_detection_utils.mjs +2 -2
  67. package/{esm2020 → esm2022}/src/render3/util/view_utils.mjs +12 -1
  68. package/esm2022/src/render3/view_ref.mjs +307 -0
  69. package/{esm2020 → esm2022}/src/sanitization/sanitizer.mjs +7 -7
  70. package/esm2022/src/signals/index.mjs +15 -0
  71. package/esm2022/src/signals/src/api.mjs +47 -0
  72. package/esm2022/src/signals/src/computed.mjs +139 -0
  73. package/esm2022/src/signals/src/graph.mjs +165 -0
  74. package/esm2022/src/signals/src/signal.mjs +75 -0
  75. package/esm2022/src/signals/src/watch.mjs +62 -0
  76. package/esm2022/src/signals/src/weak_ref.mjs +35 -0
  77. package/{esm2020 → esm2022}/src/testability/testability.mjs +5 -5
  78. package/esm2022/src/transfer_state.mjs +153 -0
  79. package/esm2022/src/util/ng_dev_mode.mjs +79 -0
  80. package/{esm2020 → esm2022}/src/version.mjs +1 -1
  81. package/{esm2020 → esm2022}/testing/src/logger.mjs +4 -4
  82. package/{esm2020 → esm2022}/testing/src/ng_zone_mock.mjs +4 -4
  83. package/{esm2020 → esm2022}/testing/src/test_bed.mjs +2 -2
  84. package/esm2022/testing/src/test_bed_compiler.mjs +846 -0
  85. package/{fesm2020 → fesm2022}/core.mjs +1890 -779
  86. package/fesm2022/core.mjs.map +1 -0
  87. package/{fesm2020 → fesm2022}/testing.mjs +1203 -178
  88. package/fesm2022/testing.mjs.map +1 -0
  89. package/index.d.ts +453 -394
  90. package/package.json +8 -16
  91. package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +694 -0
  92. package/schematics/migrations/guard-and-resolve-interfaces/bundle.js.map +7 -0
  93. package/schematics/migrations/{router-link-with-href → remove-module-id}/bundle.js +153 -155
  94. package/schematics/migrations/remove-module-id/bundle.js.map +7 -0
  95. package/schematics/migrations.json +8 -8
  96. package/schematics/ng-generate/standalone-migration/bundle.js +1082 -619
  97. package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
  98. package/testing/index.d.ts +1 -1
  99. package/esm2020/src/application_ref.mjs +0 -907
  100. package/esm2020/src/application_tokens.mjs +0 -73
  101. package/esm2020/src/change_detection/change_detector_ref.mjs +0 -93
  102. package/esm2020/src/change_detection/differs/iterable_differs.mjs +0 -81
  103. package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +0 -74
  104. package/esm2020/src/compiler/compiler_facade_interface.mjs +0 -29
  105. package/esm2020/src/core.mjs +0 -55
  106. package/esm2020/src/core_private_export.mjs +0 -37
  107. package/esm2020/src/core_reactivity_export_internal.mjs +0 -9
  108. package/esm2020/src/core_render3_private_export.mjs +0 -38
  109. package/esm2020/src/di/contextual.mjs +0 -37
  110. package/esm2020/src/di/index.mjs +0 -29
  111. package/esm2020/src/di/injector.mjs +0 -62
  112. package/esm2020/src/di/injector_compatibility.mjs +0 -236
  113. package/esm2020/src/di/provider_collection.mjs +0 -279
  114. package/esm2020/src/di/r3_injector.mjs +0 -421
  115. package/esm2020/src/di/reflective_injector.mjs +0 -311
  116. package/esm2020/src/hydration/annotate.mjs +0 -271
  117. package/esm2020/src/hydration/api.mjs +0 -128
  118. package/esm2020/src/hydration/cleanup.mjs +0 -50
  119. package/esm2020/src/hydration/error_handling.mjs +0 -37
  120. package/esm2020/src/hydration/interfaces.mjs +0 -17
  121. package/esm2020/src/hydration/node_lookup_utils.mjs +0 -83
  122. package/esm2020/src/hydration/utils.mjs +0 -206
  123. package/esm2020/src/hydration/views.mjs +0 -80
  124. package/esm2020/src/linker/component_factory_resolver.mjs +0 -42
  125. package/esm2020/src/linker/destroy_ref.mjs +0 -41
  126. package/esm2020/src/linker/query_list.mjs +0 -169
  127. package/esm2020/src/linker/view_container_ref.mjs +0 -394
  128. package/esm2020/src/metadata/di.mjs +0 -108
  129. package/esm2020/src/metadata/directives.mjs +0 -111
  130. package/esm2020/src/metadata.mjs +0 -18
  131. package/esm2020/src/render3/component_ref.mjs +0 -377
  132. package/esm2020/src/render3/features/standalone_feature.mjs +0 -70
  133. package/esm2020/src/render3/instructions/element.mjs +0 -198
  134. package/esm2020/src/render3/instructions/element_validation.mjs +0 -271
  135. package/esm2020/src/render3/instructions/listener.mjs +0 -243
  136. package/esm2020/src/render3/instructions/projection.mjs +0 -118
  137. package/esm2020/src/render3/instructions/shared.mjs +0 -1696
  138. package/esm2020/src/render3/instructions/template.mjs +0 -120
  139. package/esm2020/src/render3/instructions/text.mjs +0 -67
  140. package/esm2020/src/render3/interfaces/public_definitions.mjs +0 -9
  141. package/esm2020/src/render3/interfaces/type_checks.mjs +0 -39
  142. package/esm2020/src/render3/interfaces/view.mjs +0 -47
  143. package/esm2020/src/render3/jit/module.mjs +0 -544
  144. package/esm2020/src/render3/node_manipulation.mjs +0 -961
  145. package/esm2020/src/render3/node_selector_matcher.mjs +0 -414
  146. package/esm2020/src/render3/view_ref.mjs +0 -306
  147. package/esm2020/src/signals/index.mjs +0 -15
  148. package/esm2020/src/signals/src/api.mjs +0 -46
  149. package/esm2020/src/signals/src/computed.mjs +0 -142
  150. package/esm2020/src/signals/src/effect.mjs +0 -69
  151. package/esm2020/src/signals/src/graph.mjs +0 -114
  152. package/esm2020/src/signals/src/signal.mjs +0 -78
  153. package/esm2020/src/signals/src/watch.mjs +0 -54
  154. package/esm2020/src/signals/src/weak_ref.mjs +0 -11
  155. package/esm2020/src/transfer_state.mjs +0 -153
  156. package/esm2020/src/util/ng_dev_mode.mjs +0 -78
  157. package/esm2020/testing/src/test_bed_compiler.mjs +0 -841
  158. package/fesm2015/core.mjs +0 -29585
  159. package/fesm2015/core.mjs.map +0 -1
  160. package/fesm2015/testing.mjs +0 -25669
  161. package/fesm2015/testing.mjs.map +0 -1
  162. package/fesm2020/core.mjs.map +0 -1
  163. package/fesm2020/testing.mjs.map +0 -1
  164. package/schematics/migrations/relative-link-resolution/bundle.js +0 -283
  165. package/schematics/migrations/relative-link-resolution/bundle.js.map +0 -7
  166. package/schematics/migrations/router-link-with-href/bundle.js.map +0 -7
  167. /package/{esm2020 → esm2022}/core.mjs +0 -0
  168. /package/{esm2020 → esm2022}/index.mjs +0 -0
  169. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
  170. /package/{esm2020 → esm2022}/src/application_config.mjs +0 -0
  171. /package/{esm2020 → esm2022}/src/change_detection/change_detection.mjs +0 -0
  172. /package/{esm2020 → esm2022}/src/change_detection/constants.mjs +0 -0
  173. /package/{esm2020 → esm2022}/src/change_detection/differs/default_iterable_differ.mjs +0 -0
  174. /package/{esm2020 → esm2022}/src/change_detection/differs/default_keyvalue_differ.mjs +0 -0
  175. /package/{esm2020 → esm2022}/src/change_detection/pipe_transform.mjs +0 -0
  176. /package/{esm2020 → esm2022}/src/change_detection.mjs +0 -0
  177. /package/{esm2020 → esm2022}/src/compiler/compiler_facade.mjs +0 -0
  178. /package/{esm2020 → esm2022}/src/core_reactivity_export.mjs +0 -0
  179. /package/{esm2020 → esm2022}/src/debug/debug_node.mjs +0 -0
  180. /package/{esm2020 → esm2022}/src/di/create_injector.mjs +0 -0
  181. /package/{esm2020 → esm2022}/src/di/forward_ref.mjs +0 -0
  182. /package/{esm2020 → esm2022}/src/di/initializer_token.mjs +0 -0
  183. /package/{esm2020 → esm2022}/src/di/inject_switch.mjs +0 -0
  184. /package/{esm2020 → esm2022}/src/di/injectable.mjs +0 -0
  185. /package/{esm2020 → esm2022}/src/di/injection_token.mjs +0 -0
  186. /package/{esm2020 → esm2022}/src/di/injector_marker.mjs +0 -0
  187. /package/{esm2020 → esm2022}/src/di/injector_token.mjs +0 -0
  188. /package/{esm2020 → esm2022}/src/di/interface/defs.mjs +0 -0
  189. /package/{esm2020 → esm2022}/src/di/interface/injector.mjs +0 -0
  190. /package/{esm2020 → esm2022}/src/di/interface/provider.mjs +0 -0
  191. /package/{esm2020 → esm2022}/src/di/internal_tokens.mjs +0 -0
  192. /package/{esm2020 → esm2022}/src/di/jit/environment.mjs +0 -0
  193. /package/{esm2020 → esm2022}/src/di/jit/injectable.mjs +0 -0
  194. /package/{esm2020 → esm2022}/src/di/jit/util.mjs +0 -0
  195. /package/{esm2020 → esm2022}/src/di/metadata.mjs +0 -0
  196. /package/{esm2020 → esm2022}/src/di/metadata_attr.mjs +0 -0
  197. /package/{esm2020 → esm2022}/src/di/null_injector.mjs +0 -0
  198. /package/{esm2020 → esm2022}/src/di/provider_token.mjs +0 -0
  199. /package/{esm2020 → esm2022}/src/di/reflective_errors.mjs +0 -0
  200. /package/{esm2020 → esm2022}/src/di/reflective_key.mjs +0 -0
  201. /package/{esm2020 → esm2022}/src/di/reflective_provider.mjs +0 -0
  202. /package/{esm2020 → esm2022}/src/di/scope.mjs +0 -0
  203. /package/{esm2020 → esm2022}/src/di.mjs +0 -0
  204. /package/{esm2020 → esm2022}/src/error_details_base_url.mjs +0 -0
  205. /package/{esm2020 → esm2022}/src/error_handler.mjs +0 -0
  206. /package/{esm2020 → esm2022}/src/event_emitter.mjs +0 -0
  207. /package/{esm2020 → esm2022}/src/hydration/skip_hydration.mjs +0 -0
  208. /package/{esm2020 → esm2022}/src/hydration/tokens.mjs +0 -0
  209. /package/{esm2020 → esm2022}/src/i18n/locale_data_api.mjs +0 -0
  210. /package/{esm2020 → esm2022}/src/i18n/locale_en.mjs +0 -0
  211. /package/{esm2020 → esm2022}/src/i18n/localization.mjs +0 -0
  212. /package/{esm2020 → esm2022}/src/i18n/tokens.mjs +0 -0
  213. /package/{esm2020 → esm2022}/src/interface/lifecycle_hooks.mjs +0 -0
  214. /package/{esm2020 → esm2022}/src/interface/simple_change.mjs +0 -0
  215. /package/{esm2020 → esm2022}/src/interface/type.mjs +0 -0
  216. /package/{esm2020 → esm2022}/src/linker/component_factory.mjs +0 -0
  217. /package/{esm2020 → esm2022}/src/linker/ng_module_factory.mjs +0 -0
  218. /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader.mjs +0 -0
  219. /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader_impl.mjs +0 -0
  220. /package/{esm2020 → esm2022}/src/linker/ng_module_registration.mjs +0 -0
  221. /package/{esm2020 → esm2022}/src/linker/view_ref.mjs +0 -0
  222. /package/{esm2020 → esm2022}/src/linker.mjs +0 -0
  223. /package/{esm2020 → esm2022}/src/metadata/ng_module_def.mjs +0 -0
  224. /package/{esm2020 → esm2022}/src/metadata/resource_loading.mjs +0 -0
  225. /package/{esm2020 → esm2022}/src/metadata/schema.mjs +0 -0
  226. /package/{esm2020 → esm2022}/src/metadata/view.mjs +0 -0
  227. /package/{esm2020 → esm2022}/src/platform_core_providers.mjs +0 -0
  228. /package/{esm2020 → esm2022}/src/r3_symbols.mjs +0 -0
  229. /package/{esm2020 → esm2022}/src/reflection/platform_reflection_capabilities.mjs +0 -0
  230. /package/{esm2020 → esm2022}/src/reflection/reflection_capabilities.mjs +0 -0
  231. /package/{esm2020 → esm2022}/src/render/api_flags.mjs +0 -0
  232. /package/{esm2020 → esm2022}/src/render.mjs +0 -0
  233. /package/{esm2020 → esm2022}/src/render3/assert.mjs +0 -0
  234. /package/{esm2020 → esm2022}/src/render3/bindings.mjs +0 -0
  235. /package/{esm2020 → esm2022}/src/render3/collect_native_nodes.mjs +0 -0
  236. /package/{esm2020 → esm2022}/src/render3/component.mjs +0 -0
  237. /package/{esm2020 → esm2022}/src/render3/definition.mjs +0 -0
  238. /package/{esm2020 → esm2022}/src/render3/definition_factory.mjs +0 -0
  239. /package/{esm2020 → esm2022}/src/render3/di.mjs +0 -0
  240. /package/{esm2020 → esm2022}/src/render3/di_setup.mjs +0 -0
  241. /package/{esm2020 → esm2022}/src/render3/errors.mjs +0 -0
  242. /package/{esm2020 → esm2022}/src/render3/errors_di.mjs +0 -0
  243. /package/{esm2020 → esm2022}/src/render3/features/copy_definition_feature.mjs +0 -0
  244. /package/{esm2020 → esm2022}/src/render3/features/host_directives_feature.mjs +0 -0
  245. /package/{esm2020 → esm2022}/src/render3/features/inherit_definition_feature.mjs +0 -0
  246. /package/{esm2020 → esm2022}/src/render3/features/ng_onchanges_feature.mjs +0 -0
  247. /package/{esm2020 → esm2022}/src/render3/features/providers_feature.mjs +0 -0
  248. /package/{esm2020 → esm2022}/src/render3/fields.mjs +0 -0
  249. /package/{esm2020 → esm2022}/src/render3/global_utils_api.mjs +0 -0
  250. /package/{esm2020 → esm2022}/src/render3/hooks.mjs +0 -0
  251. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_apply.mjs +0 -0
  252. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_debug.mjs +0 -0
  253. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_insert_before_index.mjs +0 -0
  254. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_locale_id.mjs +0 -0
  255. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_parse.mjs +0 -0
  256. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_postprocess.mjs +0 -0
  257. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_tree_shaking.mjs +0 -0
  258. /package/{esm2020 → esm2022}/src/render3/i18n/i18n_util.mjs +0 -0
  259. /package/{esm2020 → esm2022}/src/render3/index.mjs +0 -0
  260. /package/{esm2020 → esm2022}/src/render3/instructions/advance.mjs +0 -0
  261. /package/{esm2020 → esm2022}/src/render3/instructions/all.mjs +0 -0
  262. /package/{esm2020 → esm2022}/src/render3/instructions/attribute.mjs +0 -0
  263. /package/{esm2020 → esm2022}/src/render3/instructions/attribute_interpolation.mjs +0 -0
  264. /package/{esm2020 → esm2022}/src/render3/instructions/change_detection.mjs +0 -0
  265. /package/{esm2020 → esm2022}/src/render3/instructions/class_map_interpolation.mjs +0 -0
  266. /package/{esm2020 → esm2022}/src/render3/instructions/di.mjs +0 -0
  267. /package/{esm2020 → esm2022}/src/render3/instructions/di_attr.mjs +0 -0
  268. /package/{esm2020 → esm2022}/src/render3/instructions/get_current_view.mjs +0 -0
  269. /package/{esm2020 → esm2022}/src/render3/instructions/host_property.mjs +0 -0
  270. /package/{esm2020 → esm2022}/src/render3/instructions/i18n.mjs +0 -0
  271. /package/{esm2020 → esm2022}/src/render3/instructions/i18n_icu_container_visitor.mjs +0 -0
  272. /package/{esm2020 → esm2022}/src/render3/instructions/interpolation.mjs +0 -0
  273. /package/{esm2020 → esm2022}/src/render3/instructions/namespace.mjs +0 -0
  274. /package/{esm2020 → esm2022}/src/render3/instructions/next_context.mjs +0 -0
  275. /package/{esm2020 → esm2022}/src/render3/instructions/property.mjs +0 -0
  276. /package/{esm2020 → esm2022}/src/render3/instructions/property_interpolation.mjs +0 -0
  277. /package/{esm2020 → esm2022}/src/render3/instructions/storage.mjs +0 -0
  278. /package/{esm2020 → esm2022}/src/render3/instructions/style_map_interpolation.mjs +0 -0
  279. /package/{esm2020 → esm2022}/src/render3/instructions/style_prop_interpolation.mjs +0 -0
  280. /package/{esm2020 → esm2022}/src/render3/instructions/text_interpolation.mjs +0 -0
  281. /package/{esm2020 → esm2022}/src/render3/interfaces/container.mjs +0 -0
  282. /package/{esm2020 → esm2022}/src/render3/interfaces/context.mjs +0 -0
  283. /package/{esm2020 → esm2022}/src/render3/interfaces/definition.mjs +0 -0
  284. /package/{esm2020 → esm2022}/src/render3/interfaces/document.mjs +0 -0
  285. /package/{esm2020 → esm2022}/src/render3/interfaces/i18n.mjs +0 -0
  286. /package/{esm2020 → esm2022}/src/render3/interfaces/injector.mjs +0 -0
  287. /package/{esm2020 → esm2022}/src/render3/interfaces/lview_tracking.mjs +0 -0
  288. /package/{esm2020 → esm2022}/src/render3/interfaces/node.mjs +0 -0
  289. /package/{esm2020 → esm2022}/src/render3/interfaces/projection.mjs +0 -0
  290. /package/{esm2020 → esm2022}/src/render3/interfaces/query.mjs +0 -0
  291. /package/{esm2020 → esm2022}/src/render3/interfaces/renderer.mjs +0 -0
  292. /package/{esm2020 → esm2022}/src/render3/interfaces/renderer_dom.mjs +0 -0
  293. /package/{esm2020 → esm2022}/src/render3/interfaces/sanitization.mjs +0 -0
  294. /package/{esm2020 → esm2022}/src/render3/interfaces/styling.mjs +0 -0
  295. /package/{esm2020 → esm2022}/src/render3/jit/directive.mjs +0 -0
  296. /package/{esm2020 → esm2022}/src/render3/jit/environment.mjs +0 -0
  297. /package/{esm2020 → esm2022}/src/render3/jit/jit_options.mjs +0 -0
  298. /package/{esm2020 → esm2022}/src/render3/jit/module_patch.mjs +0 -0
  299. /package/{esm2020 → esm2022}/src/render3/jit/partial.mjs +0 -0
  300. /package/{esm2020 → esm2022}/src/render3/jit/pipe.mjs +0 -0
  301. /package/{esm2020 → esm2022}/src/render3/jit/util.mjs +0 -0
  302. /package/{esm2020 → esm2022}/src/render3/metadata.mjs +0 -0
  303. /package/{esm2020 → esm2022}/src/render3/namespaces.mjs +0 -0
  304. /package/{esm2020 → esm2022}/src/render3/ng_module_ref.mjs +0 -0
  305. /package/{esm2020 → esm2022}/src/render3/node_assert.mjs +0 -0
  306. /package/{esm2020 → esm2022}/src/render3/node_manipulation_i18n.mjs +0 -0
  307. /package/{esm2020 → esm2022}/src/render3/pipe.mjs +0 -0
  308. /package/{esm2020 → esm2022}/src/render3/profiler.mjs +0 -0
  309. /package/{esm2020 → esm2022}/src/render3/pure_function.mjs +0 -0
  310. /package/{esm2020 → esm2022}/src/render3/query.mjs +0 -0
  311. /package/{esm2020 → esm2022}/src/render3/state.mjs +0 -0
  312. /package/{esm2020 → esm2022}/src/render3/styling/class_differ.mjs +0 -0
  313. /package/{esm2020 → esm2022}/src/render3/styling/static_styling.mjs +0 -0
  314. /package/{esm2020 → esm2022}/src/render3/styling/style_binding_list.mjs +0 -0
  315. /package/{esm2020 → esm2022}/src/render3/styling/styling_parser.mjs +0 -0
  316. /package/{esm2020 → esm2022}/src/render3/tokens.mjs +0 -0
  317. /package/{esm2020 → esm2022}/src/render3/util/attrs_utils.mjs +0 -0
  318. /package/{esm2020 → esm2022}/src/render3/util/discovery_utils.mjs +0 -0
  319. /package/{esm2020 → esm2022}/src/render3/util/global_utils.mjs +0 -0
  320. /package/{esm2020 → esm2022}/src/render3/util/injector_utils.mjs +0 -0
  321. /package/{esm2020 → esm2022}/src/render3/util/misc_utils.mjs +0 -0
  322. /package/{esm2020 → esm2022}/src/render3/util/stringify_utils.mjs +0 -0
  323. /package/{esm2020 → esm2022}/src/render3/util/view_traversal_utils.mjs +0 -0
  324. /package/{esm2020 → esm2022}/src/render3/view_engine_compatibility_prebound.mjs +0 -0
  325. /package/{esm2020 → esm2022}/src/sanitization/bypass.mjs +0 -0
  326. /package/{esm2020 → esm2022}/src/sanitization/html_sanitizer.mjs +0 -0
  327. /package/{esm2020 → esm2022}/src/sanitization/iframe_attrs_validation.mjs +0 -0
  328. /package/{esm2020 → esm2022}/src/sanitization/inert_body.mjs +0 -0
  329. /package/{esm2020 → esm2022}/src/sanitization/sanitization.mjs +0 -0
  330. /package/{esm2020 → esm2022}/src/sanitization/security.mjs +0 -0
  331. /package/{esm2020 → esm2022}/src/sanitization/url_sanitizer.mjs +0 -0
  332. /package/{esm2020 → esm2022}/src/signals/src/untracked.mjs +0 -0
  333. /package/{esm2020 → esm2022}/src/util/array_utils.mjs +0 -0
  334. /package/{esm2020 → esm2022}/src/util/assert.mjs +0 -0
  335. /package/{esm2020 → esm2022}/src/util/char_code.mjs +0 -0
  336. /package/{esm2020 → esm2022}/src/util/closure.mjs +0 -0
  337. /package/{esm2020 → esm2022}/src/util/coercion.mjs +0 -0
  338. /package/{esm2020 → esm2022}/src/util/comparison.mjs +0 -0
  339. /package/{esm2020 → esm2022}/src/util/decorators.mjs +0 -0
  340. /package/{esm2020 → esm2022}/src/util/dom.mjs +0 -0
  341. /package/{esm2020 → esm2022}/src/util/empty.mjs +0 -0
  342. /package/{esm2020 → esm2022}/src/util/errors.mjs +0 -0
  343. /package/{esm2020 → esm2022}/src/util/global.mjs +0 -0
  344. /package/{esm2020 → esm2022}/src/util/is_dev_mode.mjs +0 -0
  345. /package/{esm2020 → esm2022}/src/util/iterable.mjs +0 -0
  346. /package/{esm2020 → esm2022}/src/util/lang.mjs +0 -0
  347. /package/{esm2020 → esm2022}/src/util/microtask.mjs +0 -0
  348. /package/{esm2020 → esm2022}/src/util/ng_i18n_closure_mode.mjs +0 -0
  349. /package/{esm2020 → esm2022}/src/util/ng_jit_mode.mjs +0 -0
  350. /package/{esm2020 → esm2022}/src/util/ng_reflect.mjs +0 -0
  351. /package/{esm2020 → esm2022}/src/util/noop.mjs +0 -0
  352. /package/{esm2020 → esm2022}/src/util/property.mjs +0 -0
  353. /package/{esm2020 → esm2022}/src/util/raf.mjs +0 -0
  354. /package/{esm2020 → esm2022}/src/util/security/trusted_type_defs.mjs +0 -0
  355. /package/{esm2020 → esm2022}/src/util/security/trusted_types.mjs +0 -0
  356. /package/{esm2020 → esm2022}/src/util/security/trusted_types_bypass.mjs +0 -0
  357. /package/{esm2020 → esm2022}/src/util/stringify.mjs +0 -0
  358. /package/{esm2020 → esm2022}/src/view/provider_flags.mjs +0 -0
  359. /package/{esm2020 → esm2022}/src/zone/async-stack-tagging.mjs +0 -0
  360. /package/{esm2020 → esm2022}/src/zone/ng_zone.mjs +0 -0
  361. /package/{esm2020 → esm2022}/src/zone.mjs +0 -0
  362. /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
  363. /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
  364. /package/{esm2020 → esm2022}/testing/src/async.mjs +0 -0
  365. /package/{esm2020 → esm2022}/testing/src/component_fixture.mjs +0 -0
  366. /package/{esm2020 → esm2022}/testing/src/fake_async.mjs +0 -0
  367. /package/{esm2020 → esm2022}/testing/src/metadata_override.mjs +0 -0
  368. /package/{esm2020 → esm2022}/testing/src/metadata_overrider.mjs +0 -0
  369. /package/{esm2020 → esm2022}/testing/src/resolvers.mjs +0 -0
  370. /package/{esm2020 → esm2022}/testing/src/styling.mjs +0 -0
  371. /package/{esm2020 → esm2022}/testing/src/test_bed_common.mjs +0 -0
  372. /package/{esm2020 → esm2022}/testing/src/test_hooks.mjs +0 -0
  373. /package/{esm2020 → esm2022}/testing/src/testing.mjs +0 -0
  374. /package/{esm2020 → esm2022}/testing/src/testing_internal.mjs +0 -0
  375. /package/{esm2020 → esm2022}/testing/testing.mjs +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.0.0-next.3
2
+ * @license Angular v16.0.0-next.5
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -7,6 +7,7 @@
7
7
  import { getDebugNode, RendererFactory2 as RendererFactory2$1, InjectionToken as InjectionToken$1, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef as resolveForwardRef$1, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID as LOCALE_ID$1, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, NgZone, ɵprovideNgZoneChangeDetection, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ɵisEnvironmentProviders, ModuleWithComponentFactories, ɵconvertToBitFlags, Injector as Injector$1, InjectFlags as InjectFlags$1, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode as ɵsetUnknownElementStrictMode$1, ɵsetUnknownPropertyStrictMode as ɵsetUnknownPropertyStrictMode$1, ɵgetUnknownElementStrictMode as ɵgetUnknownElementStrictMode$1, ɵgetUnknownPropertyStrictMode as ɵgetUnknownPropertyStrictMode$1, EnvironmentInjector as EnvironmentInjector$1, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
8
8
  import { ResourceLoader } from '@angular/compiler';
9
9
  import { Subject, Subscription } from 'rxjs';
10
+ import { first } from 'rxjs/operators';
10
11
 
11
12
  /**
12
13
  * Wraps a test function in an asynchronous test zone. The test will automatically
@@ -1638,6 +1639,7 @@ function ngDevModeResetPerfCounters() {
1638
1639
  hydratedNodes: 0,
1639
1640
  hydratedComponents: 0,
1640
1641
  dehydratedViewsRemoved: 0,
1642
+ dehydratedViewsCleanupRuns: 0,
1641
1643
  };
1642
1644
  // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
1643
1645
  const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
@@ -1840,6 +1842,9 @@ const SOURCE = '__source';
1840
1842
  * - Injector instance: Use the injector for resolution.
1841
1843
  */
1842
1844
  let _currentInjector = undefined;
1845
+ function getCurrentInjector() {
1846
+ return _currentInjector;
1847
+ }
1843
1848
  function setCurrentInjector(injector) {
1844
1849
  const former = _currentInjector;
1845
1850
  _currentInjector = injector;
@@ -1848,7 +1853,7 @@ function setCurrentInjector(injector) {
1848
1853
  function injectInjectorOnly(token, flags = InjectFlags.Default) {
1849
1854
  if (_currentInjector === undefined) {
1850
1855
  throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
1851
- `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`EnvironmentInjector#runInContext\`.`);
1856
+ `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`runInInjectionContext\`.`);
1852
1857
  }
1853
1858
  else if (_currentInjector === null) {
1854
1859
  return injectRootLimpMode(token, undefined, flags);
@@ -2446,12 +2451,19 @@ function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
2446
2451
  ngDevMode &&
2447
2452
  assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
2448
2453
  let i = 0;
2454
+ // Indicates whether we are processing value from the implicit
2455
+ // attribute section (i.e. before the first marker in the array).
2456
+ let isImplicitAttrsSection = true;
2449
2457
  while (i < attrs.length) {
2450
2458
  let item = attrs[i++];
2451
- if (isProjectionMode && item === 'class') {
2452
- item = attrs[i];
2453
- if (classIndexOf(item.toLowerCase(), cssClassToMatch, 0) !== -1) {
2454
- return true;
2459
+ if (typeof item === 'string' && isImplicitAttrsSection) {
2460
+ const value = attrs[i++];
2461
+ if (isProjectionMode && item === 'class') {
2462
+ // We found a `class` attribute in the implicit attribute section,
2463
+ // check if it matches the value of the `cssClassToMatch` argument.
2464
+ if (classIndexOf(value.toLowerCase(), cssClassToMatch, 0) !== -1) {
2465
+ return true;
2466
+ }
2455
2467
  }
2456
2468
  }
2457
2469
  else if (item === 1 /* AttributeMarker.Classes */) {
@@ -2463,6 +2475,11 @@ function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
2463
2475
  }
2464
2476
  return false;
2465
2477
  }
2478
+ else if (typeof item === 'number') {
2479
+ // We've came across a first marker, which indicates
2480
+ // that the implicit attribute section is over.
2481
+ isImplicitAttrsSection = false;
2482
+ }
2466
2483
  }
2467
2484
  return false;
2468
2485
  }
@@ -3217,6 +3234,8 @@ const ID = 20;
3217
3234
  const EMBEDDED_VIEW_INJECTOR = 21;
3218
3235
  const ON_DESTROY_HOOKS = 22;
3219
3236
  const HYDRATION = 23;
3237
+ const REACTIVE_TEMPLATE_CONSUMER = 24;
3238
+ const REACTIVE_HOST_BINDING_CONSUMER = 25;
3220
3239
  /**
3221
3240
  * Size of LView's header. Necessary to adjust for it when setting slots.
3222
3241
  *
@@ -3224,7 +3243,7 @@ const HYDRATION = 23;
3224
3243
  * instruction index into `LView` index. All other indexes should be in the `LView` index space and
3225
3244
  * there should be no need to refer to `HEADER_OFFSET` anywhere else.
3226
3245
  */
3227
- const HEADER_OFFSET = 24;
3246
+ const HEADER_OFFSET = 26;
3228
3247
  // Note: This hack is necessary so we don't erroneously get a circular dependency
3229
3248
  // failure based on types.
3230
3249
  const unusedValueExportToPlacateAjd$4 = 1;
@@ -3297,6 +3316,9 @@ function isComponentDef(def) {
3297
3316
  function isRootView(target) {
3298
3317
  return (target[FLAGS] & 256 /* LViewFlags.IsRoot */) !== 0;
3299
3318
  }
3319
+ function isProjectionTNode(tNode) {
3320
+ return (tNode.type & 16 /* TNodeType.Projection */) === 16 /* TNodeType.Projection */;
3321
+ }
3300
3322
 
3301
3323
  // [Assert functions do not constraint type when they are guarded by a truthy
3302
3324
  // expression.](https://github.com/microsoft/TypeScript/issues/37295)
@@ -3710,6 +3732,17 @@ function storeLViewOnDestroy(lView, onDestroyCallback) {
3710
3732
  }
3711
3733
  lView[ON_DESTROY_HOOKS].push(onDestroyCallback);
3712
3734
  }
3735
+ /**
3736
+ * Removes previously registered LView-specific destroy callback.
3737
+ */
3738
+ function removeLViewOnDestroy(lView, onDestroyCallback) {
3739
+ if (lView[ON_DESTROY_HOOKS] === null)
3740
+ return;
3741
+ const destroyCBIdx = lView[ON_DESTROY_HOOKS].indexOf(onDestroyCallback);
3742
+ if (destroyCBIdx !== -1) {
3743
+ lView[ON_DESTROY_HOOKS].splice(destroyCBIdx, 1);
3744
+ }
3745
+ }
3713
3746
 
3714
3747
  const instructionState = {
3715
3748
  lFrame: createLFrame(null),
@@ -6711,6 +6744,8 @@ function detachView(lContainer, removeIndex) {
6711
6744
  function destroyLView(tView, lView) {
6712
6745
  if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
6713
6746
  const renderer = lView[RENDERER];
6747
+ lView[REACTIVE_TEMPLATE_CONSUMER]?.destroy();
6748
+ lView[REACTIVE_HOST_BINDING_CONSUMER]?.destroy();
6714
6749
  if (renderer.destroyNode) {
6715
6750
  applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
6716
6751
  }
@@ -7111,15 +7146,12 @@ function nativeRemoveNode(renderer, rNode, isHostElement) {
7111
7146
  }
7112
7147
  }
7113
7148
  /**
7114
- * Removes the contents of a given RElement using a given renderer.
7149
+ * Clears the contents of a given RElement.
7115
7150
  *
7116
- * @param renderer A renderer to be used
7117
7151
  * @param rElement the native RElement to be cleared
7118
7152
  */
7119
- function clearElementContents(renderer, rElement) {
7120
- while (rElement.firstChild) {
7121
- nativeRemoveChild(renderer, rElement, rElement.firstChild, false);
7122
- }
7153
+ function clearElementContents(rElement) {
7154
+ rElement.textContent = '';
7123
7155
  }
7124
7156
  /**
7125
7157
  * Performs the operation of `action` on the node. Typically this involves inserting or removing
@@ -8512,7 +8544,7 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
8512
8544
  // Narrow `source` to access the internal type analogue for `ModuleWithProviders`.
8513
8545
  const internalSource = source;
8514
8546
  if (walkProviderTree(internalSource, providersOut, [], dedup)) {
8515
- injectorTypesWithProviders || (injectorTypesWithProviders = []);
8547
+ injectorTypesWithProviders ||= [];
8516
8548
  injectorTypesWithProviders.push(internalSource);
8517
8549
  }
8518
8550
  });
@@ -8608,7 +8640,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
8608
8640
  try {
8609
8641
  deepForEach(injDef.imports, imported => {
8610
8642
  if (walkProviderTree(imported, providersOut, parents, dedup)) {
8611
- importTypesWithProviders || (importTypesWithProviders = []);
8643
+ importTypesWithProviders ||= [];
8612
8644
  // If the processed import is an injector type with providers, we store it in the
8613
8645
  // list of import types with providers, so that we can process those afterwards.
8614
8646
  importTypesWithProviders.push(imported);
@@ -8805,6 +8837,7 @@ class R3Injector extends EnvironmentInjector {
8805
8837
  }
8806
8838
  onDestroy(callback) {
8807
8839
  this._onDestroyHooks.push(callback);
8840
+ return () => this.removeOnDestroy(callback);
8808
8841
  }
8809
8842
  runInContext(fn) {
8810
8843
  this.assertNotDestroyed();
@@ -8979,6 +9012,12 @@ class R3Injector extends EnvironmentInjector {
8979
9012
  return this.injectorDefTypes.has(providedIn);
8980
9013
  }
8981
9014
  }
9015
+ removeOnDestroy(callback) {
9016
+ const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
9017
+ if (destroyCBIdx !== -1) {
9018
+ this._onDestroyHooks.splice(destroyCBIdx, 1);
9019
+ }
9020
+ }
8982
9021
  }
8983
9022
  function injectableDefOrInjectorDefFactory(token) {
8984
9023
  // Most tokens will have an injectable def directly on them, which specifies a factory directly.
@@ -9164,6 +9203,37 @@ const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
9164
9203
  * @publicApi
9165
9204
  */
9166
9205
  const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
9206
+ // TODO(crisbeto): link to CSP guide here.
9207
+ /**
9208
+ * Token used to configure the [Content Security Policy](https://web.dev/strict-csp/) nonce that
9209
+ * Angular will apply when inserting inline styles. If not provided, Angular will look up its value
9210
+ * from the `ngCspNonce` attribute of the application root node.
9211
+ *
9212
+ * @publicApi
9213
+ */
9214
+ const CSP_NONCE = new InjectionToken('CSP nonce', {
9215
+ providedIn: 'root',
9216
+ factory: () => {
9217
+ // Ideally we wouldn't have to use `querySelector` here since we know that the nonce will be on
9218
+ // the root node, but because the token value is used in renderers, it has to be available
9219
+ // *very* early in the bootstrapping process. This should be a fairly shallow search, because
9220
+ // the app won't have been added to the DOM yet. Some approaches that were considered:
9221
+ // 1. Find the root node through `ApplicationRef.components[i].location` - normally this would
9222
+ // be enough for our purposes, but the token is injected very early so the `components` array
9223
+ // isn't populated yet.
9224
+ // 2. Find the root `LView` through the current `LView` - renderers are a prerequisite to
9225
+ // creating the `LView`. This means that no `LView` will have been entered when this factory is
9226
+ // invoked for the root component.
9227
+ // 3. Have the token factory return `() => string` which is invoked when a nonce is requested -
9228
+ // the slightly later execution does allow us to get an `LView` reference, but the fact that
9229
+ // it is a function means that it could be executed at *any* time (including immediately) which
9230
+ // may lead to weird bugs.
9231
+ // 4. Have the `ComponentFactory` read the attribute and provide it to the injector under the
9232
+ // hood - has the same problem as #1 and #2 in that the renderer is used to query for the root
9233
+ // node and the nonce value needs to be available when the renderer is created.
9234
+ return getDocument().body.querySelector('[ngCspNonce]')?.getAttribute('ngCspNonce') || null;
9235
+ },
9236
+ });
9167
9237
 
9168
9238
  function escapeTransferStateContent(text) {
9169
9239
  const escapedText = {
@@ -9228,6 +9298,13 @@ class TransferState {
9228
9298
  this.store = {};
9229
9299
  this.onSerializeCallbacks = {};
9230
9300
  }
9301
+ /** @nocollapse */
9302
+ static { this.ɵprov =
9303
+ /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
9304
+ token: TransferState,
9305
+ providedIn: 'root',
9306
+ factory: initTransferState,
9307
+ }); }
9231
9308
  /**
9232
9309
  * Get the value corresponding to a key. Return `defaultValue` if key is not found.
9233
9310
  */
@@ -9282,13 +9359,6 @@ class TransferState {
9282
9359
  return JSON.stringify(this.store);
9283
9360
  }
9284
9361
  }
9285
- /** @nocollapse */
9286
- TransferState.ɵprov =
9287
- /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
9288
- token: TransferState,
9289
- providedIn: 'root',
9290
- factory: initTransferState,
9291
- });
9292
9362
  function retrieveTransferredState(doc, appId) {
9293
9363
  // Locate the script tag with the JSON data transferred from the server.
9294
9364
  // The id of the script tag is set to the Angular appId + 'state'.
@@ -9306,6 +9376,19 @@ function retrieveTransferredState(doc, appId) {
9306
9376
  return initialState;
9307
9377
  }
9308
9378
 
9379
+ /** Encodes that the node lookup should start from the host node of this component. */
9380
+ const REFERENCE_NODE_HOST = 'h';
9381
+ /** Encodes that the node lookup should start from the document body node. */
9382
+ const REFERENCE_NODE_BODY = 'b';
9383
+ /**
9384
+ * Describes navigation steps that the runtime logic need to perform,
9385
+ * starting from a given (known) element.
9386
+ */
9387
+ var NodeNavigationStep;
9388
+ (function (NodeNavigationStep) {
9389
+ NodeNavigationStep["FirstChild"] = "f";
9390
+ NodeNavigationStep["NextSibling"] = "n";
9391
+ })(NodeNavigationStep || (NodeNavigationStep = {}));
9309
9392
  /**
9310
9393
  * Keys within serialized view data structure to represent various
9311
9394
  * parts. See the `SerializedView` interface below for additional information.
@@ -9313,8 +9396,11 @@ function retrieveTransferredState(doc, appId) {
9313
9396
  const ELEMENT_CONTAINERS = 'e';
9314
9397
  const TEMPLATES = 't';
9315
9398
  const CONTAINERS = 'c';
9399
+ const MULTIPLIER = 'x';
9316
9400
  const NUM_ROOT_NODES = 'r';
9317
9401
  const TEMPLATE_ID = 'i'; // as it's also an "id"
9402
+ const NODES = 'n';
9403
+ const DISCONNECTED_NODES = 'd';
9318
9404
 
9319
9405
  /**
9320
9406
  * The name of the key used in the TransferState collection,
@@ -9468,7 +9554,7 @@ function isRNodeClaimedForHydration(node) {
9468
9554
  return !!node.__claimed;
9469
9555
  }
9470
9556
  function setSegmentHead(hydrationInfo, index, node) {
9471
- hydrationInfo.segmentHeads ?? (hydrationInfo.segmentHeads = {});
9557
+ hydrationInfo.segmentHeads ??= {};
9472
9558
  hydrationInfo.segmentHeads[index] = node;
9473
9559
  }
9474
9560
  function getSegmentHead(hydrationInfo, index) {
@@ -9504,10 +9590,23 @@ function calcSerializedContainerSize(hydrationInfo, index) {
9504
9590
  const views = getSerializedContainerViews(hydrationInfo, index) ?? [];
9505
9591
  let numNodes = 0;
9506
9592
  for (let view of views) {
9507
- numNodes += view[NUM_ROOT_NODES];
9593
+ numNodes += view[NUM_ROOT_NODES] * (view[MULTIPLIER] ?? 1);
9508
9594
  }
9509
9595
  return numNodes;
9510
9596
  }
9597
+ /**
9598
+ * Checks whether a node is annotated as "disconnected", i.e. not present
9599
+ * in the DOM at serialization time. We should not attempt hydration for
9600
+ * such nodes and instead, use a regular "creation mode".
9601
+ */
9602
+ function isDisconnectedNode(hydrationInfo, index) {
9603
+ // Check if we are processing disconnected info for the first time.
9604
+ if (typeof hydrationInfo.disconnectedNodes === 'undefined') {
9605
+ const nodeIds = hydrationInfo.data[DISCONNECTED_NODES];
9606
+ hydrationInfo.disconnectedNodes = nodeIds ? (new Set(nodeIds)) : null;
9607
+ }
9608
+ return !!hydrationInfo.disconnectedNodes?.has(index);
9609
+ }
9511
9610
 
9512
9611
  /**
9513
9612
  * Represents a component created by a `ComponentFactory`.
@@ -9534,7 +9633,7 @@ class ComponentFactory$1 {
9534
9633
  }
9535
9634
 
9536
9635
  function noComponentFactoryError(component) {
9537
- const error = Error(`No component factory found for ${stringify(component)}. Did you add it to @NgModule.entryComponents?`);
9636
+ const error = Error(`No component factory found for ${stringify(component)}.`);
9538
9637
  error[ERROR_COMPONENT] = component;
9539
9638
  return error;
9540
9639
  }
@@ -9563,8 +9662,8 @@ class _NullComponentFactoryResolver {
9563
9662
  * Component class can be used directly.
9564
9663
  */
9565
9664
  class ComponentFactoryResolver$1 {
9665
+ static { this.NULL = ( /* @__PURE__ */new _NullComponentFactoryResolver()); }
9566
9666
  }
9567
- ComponentFactoryResolver$1.NULL = ( /* @__PURE__ */new _NullComponentFactoryResolver());
9568
9667
 
9569
9668
  /**
9570
9669
  * Creates an ElementRef from the most recent node.
@@ -9603,12 +9702,12 @@ class ElementRef {
9603
9702
  constructor(nativeElement) {
9604
9703
  this.nativeElement = nativeElement;
9605
9704
  }
9705
+ /**
9706
+ * @internal
9707
+ * @nocollapse
9708
+ */
9709
+ static { this.__NG_ELEMENT_ID__ = injectElementRef; }
9606
9710
  }
9607
- /**
9608
- * @internal
9609
- * @nocollapse
9610
- */
9611
- ElementRef.__NG_ELEMENT_ID__ = injectElementRef;
9612
9711
  /**
9613
9712
  * Unwraps `ElementRef` and return the `nativeElement`.
9614
9713
  *
@@ -9642,12 +9741,12 @@ class RendererFactory2 {
9642
9741
  * @publicApi
9643
9742
  */
9644
9743
  class Renderer2 {
9744
+ /**
9745
+ * @internal
9746
+ * @nocollapse
9747
+ */
9748
+ static { this.__NG_ELEMENT_ID__ = () => injectRenderer2(); }
9645
9749
  }
9646
- /**
9647
- * @internal
9648
- * @nocollapse
9649
- */
9650
- Renderer2.__NG_ELEMENT_ID__ = () => injectRenderer2();
9651
9750
  /** Injects a Renderer2 for the current component. */
9652
9751
  function injectRenderer2() {
9653
9752
  // We need the Renderer to be based on the component that it's being injected into, however since
@@ -9664,13 +9763,13 @@ function injectRenderer2() {
9664
9763
  * @publicApi
9665
9764
  */
9666
9765
  class Sanitizer {
9766
+ /** @nocollapse */
9767
+ static { this.ɵprov = ɵɵdefineInjectable({
9768
+ token: Sanitizer,
9769
+ providedIn: 'root',
9770
+ factory: () => null,
9771
+ }); }
9667
9772
  }
9668
- /** @nocollapse */
9669
- Sanitizer.ɵprov = ɵɵdefineInjectable({
9670
- token: Sanitizer,
9671
- providedIn: 'root',
9672
- factory: () => null,
9673
- });
9674
9773
 
9675
9774
  /**
9676
9775
  * @description Represents the version of Angular
@@ -9688,7 +9787,7 @@ class Version {
9688
9787
  /**
9689
9788
  * @publicApi
9690
9789
  */
9691
- const VERSION = new Version('16.0.0-next.3');
9790
+ const VERSION = new Version('16.0.0-next.5');
9692
9791
 
9693
9792
  // This default value is when checking the hierarchy for a token.
9694
9793
  //
@@ -9769,11 +9868,11 @@ class ErrorHandler {
9769
9868
  }
9770
9869
  }
9771
9870
 
9772
- const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
9871
+ const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
9773
9872
  /**
9774
9873
  * Internal token that specifies whether hydration is enabled.
9775
9874
  */
9776
- const IS_HYDRATION_FEATURE_ENABLED = new InjectionToken(NG_DEV_MODE ? 'IS_HYDRATION_FEATURE_ENABLED' : '');
9875
+ const IS_HYDRATION_FEATURE_ENABLED = new InjectionToken(NG_DEV_MODE$1 ? 'IS_HYDRATION_FEATURE_ENABLED' : '');
9777
9876
  // By default (in client rendering mode), we remove all the contents
9778
9877
  // of the host element and render an application after that.
9779
9878
  const PRESERVE_HOST_CONTENT_DEFAULT = false;
@@ -9781,7 +9880,7 @@ const PRESERVE_HOST_CONTENT_DEFAULT = false;
9781
9880
  * Internal token that indicates whether host element content should be
9782
9881
  * retained during the bootstrap.
9783
9882
  */
9784
- const PRESERVE_HOST_CONTENT = new InjectionToken(NG_DEV_MODE ? 'PRESERVE_HOST_CONTENT' : '', {
9883
+ const PRESERVE_HOST_CONTENT = new InjectionToken(NG_DEV_MODE$1 ? 'PRESERVE_HOST_CONTENT' : '', {
9785
9884
  providedIn: 'root',
9786
9885
  factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
9787
9886
  });
@@ -9891,6 +9990,285 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
9891
9990
  return { propName: undefined, oldValue, newValue };
9892
9991
  }
9893
9992
 
9993
+ /**
9994
+ * A `WeakRef`-compatible reference that fakes the API with a strong reference
9995
+ * internally.
9996
+ */
9997
+ class LeakyRef {
9998
+ constructor(ref) {
9999
+ this.ref = ref;
10000
+ }
10001
+ deref() {
10002
+ return this.ref;
10003
+ }
10004
+ }
10005
+ // `WeakRef` is not always defined in every TS environment where Angular is compiled. Instead,
10006
+ // read it off of the global context if available.
10007
+ // tslint:disable-next-line: no-toplevel-property-access
10008
+ let WeakRefImpl = _global$1['WeakRef'] ?? LeakyRef;
10009
+ function newWeakRef(value) {
10010
+ if (typeof ngDevMode !== 'undefined' && ngDevMode && WeakRefImpl === undefined) {
10011
+ throw new Error(`Angular requires a browser which supports the 'WeakRef' API`);
10012
+ }
10013
+ return new WeakRefImpl(value);
10014
+ }
10015
+ function setAlternateWeakRefImpl(impl) {
10016
+ // no-op since the alternate impl is included by default by the framework. Remove once internal
10017
+ // migration is complete.
10018
+ }
10019
+
10020
+ /**
10021
+ * Counter tracking the next `ProducerId` or `ConsumerId`.
10022
+ */
10023
+ let _nextReactiveId = 0;
10024
+ /**
10025
+ * Tracks the currently active reactive consumer (or `null` if there is no active
10026
+ * consumer).
10027
+ */
10028
+ let activeConsumer = null;
10029
+ function setActiveConsumer(consumer) {
10030
+ const prev = activeConsumer;
10031
+ activeConsumer = consumer;
10032
+ return prev;
10033
+ }
10034
+ /**
10035
+ * A node in the reactive graph.
10036
+ *
10037
+ * Nodes can be producers of reactive values, consumers of other reactive values, or both.
10038
+ *
10039
+ * Producers are nodes that produce values, and can be depended upon by consumer nodes.
10040
+ *
10041
+ * Producers expose a monotonic `valueVersion` counter, and are responsible for incrementing this
10042
+ * version when their value semantically changes. Some producers may produce their values lazily and
10043
+ * thus at times need to be polled for potential updates to their value (and by extension their
10044
+ * `valueVersion`). This is accomplished via the `onProducerUpdateValueVersion` method for
10045
+ * implemented by producers, which should perform whatever calculations are necessary to ensure
10046
+ * `valueVersion` is up to date.
10047
+ *
10048
+ * Consumers are nodes that depend on the values of producers and are notified when those values
10049
+ * might have changed.
10050
+ *
10051
+ * Consumers do not wrap the reads they consume themselves, but rather can be set as the active
10052
+ * reader via `setActiveConsumer`. Reads of producers that happen while a consumer is active will
10053
+ * result in those producers being added as dependencies of that consumer node.
10054
+ *
10055
+ * The set of dependencies of a consumer is dynamic. Implementers expose a monotonically increasing
10056
+ * `trackingVersion` counter, which increments whenever the consumer is about to re-run any reactive
10057
+ * reads it needs and establish a new set of dependencies as a result.
10058
+ *
10059
+ * Producers store the last `trackingVersion` they've seen from `Consumer`s which have read them.
10060
+ * This allows a producer to identify whether its record of the dependency is current or stale, by
10061
+ * comparing the consumer's `trackingVersion` to the version at which the dependency was
10062
+ * last observed.
10063
+ */
10064
+ class ReactiveNode {
10065
+ constructor() {
10066
+ this.id = _nextReactiveId++;
10067
+ /**
10068
+ * A cached weak reference to this node, which will be used in `ReactiveEdge`s.
10069
+ */
10070
+ this.ref = newWeakRef(this);
10071
+ /**
10072
+ * Edges to producers on which this node depends (in its consumer capacity).
10073
+ */
10074
+ this.producers = new Map();
10075
+ /**
10076
+ * Edges to consumers on which this node depends (in its producer capacity).
10077
+ */
10078
+ this.consumers = new Map();
10079
+ /**
10080
+ * Monotonically increasing counter representing a version of this `Consumer`'s
10081
+ * dependencies.
10082
+ */
10083
+ this.trackingVersion = 0;
10084
+ /**
10085
+ * Monotonically increasing counter which increases when the value of this `Producer`
10086
+ * semantically changes.
10087
+ */
10088
+ this.valueVersion = 0;
10089
+ }
10090
+ /**
10091
+ * Polls dependencies of a consumer to determine if they have actually changed.
10092
+ *
10093
+ * If this returns `false`, then even though the consumer may have previously been notified of a
10094
+ * change, the values of its dependencies have not actually changed and the consumer should not
10095
+ * rerun any reactions.
10096
+ */
10097
+ consumerPollProducersForChange() {
10098
+ for (const [producerId, edge] of this.producers) {
10099
+ const producer = edge.producerNode.deref();
10100
+ if (producer === undefined || edge.atTrackingVersion !== this.trackingVersion) {
10101
+ // This dependency edge is stale, so remove it.
10102
+ this.producers.delete(producerId);
10103
+ producer?.consumers.delete(this.id);
10104
+ continue;
10105
+ }
10106
+ if (producer.producerPollStatus(edge.seenValueVersion)) {
10107
+ // One of the dependencies reports a real value change.
10108
+ return true;
10109
+ }
10110
+ }
10111
+ // No dependency reported a real value change, so the `Consumer` has also not been
10112
+ // impacted.
10113
+ return false;
10114
+ }
10115
+ /**
10116
+ * Notify all consumers of this producer that its value may have changed.
10117
+ */
10118
+ producerMayHaveChanged() {
10119
+ for (const [consumerId, edge] of this.consumers) {
10120
+ const consumer = edge.consumerNode.deref();
10121
+ if (consumer === undefined || consumer.trackingVersion !== edge.atTrackingVersion) {
10122
+ this.consumers.delete(consumerId);
10123
+ consumer?.producers.delete(this.id);
10124
+ continue;
10125
+ }
10126
+ consumer.onConsumerDependencyMayHaveChanged();
10127
+ }
10128
+ }
10129
+ /**
10130
+ * Mark that this producer node has been accessed in the current reactive context.
10131
+ */
10132
+ producerAccessed() {
10133
+ if (activeConsumer === null) {
10134
+ return;
10135
+ }
10136
+ // Either create or update the dependency `Edge` in both directions.
10137
+ let edge = activeConsumer.producers.get(this.id);
10138
+ if (edge === undefined) {
10139
+ edge = {
10140
+ consumerNode: activeConsumer.ref,
10141
+ producerNode: this.ref,
10142
+ seenValueVersion: this.valueVersion,
10143
+ atTrackingVersion: activeConsumer.trackingVersion,
10144
+ };
10145
+ activeConsumer.producers.set(this.id, edge);
10146
+ this.consumers.set(activeConsumer.id, edge);
10147
+ }
10148
+ else {
10149
+ edge.seenValueVersion = this.valueVersion;
10150
+ edge.atTrackingVersion = activeConsumer.trackingVersion;
10151
+ }
10152
+ }
10153
+ /**
10154
+ * Whether this consumer currently has any producers registered.
10155
+ */
10156
+ get hasProducers() {
10157
+ return this.producers.size > 0;
10158
+ }
10159
+ /**
10160
+ * Checks if a `Producer` has a current value which is different than the value
10161
+ * last seen at a specific version by a `Consumer` which recorded a dependency on
10162
+ * this `Producer`.
10163
+ */
10164
+ producerPollStatus(lastSeenValueVersion) {
10165
+ // `producer.valueVersion` may be stale, but a mismatch still means that the value
10166
+ // last seen by the `Consumer` is also stale.
10167
+ if (this.valueVersion !== lastSeenValueVersion) {
10168
+ return true;
10169
+ }
10170
+ // Trigger the `Producer` to update its `valueVersion` if necessary.
10171
+ this.onProducerUpdateValueVersion();
10172
+ // At this point, we can trust `producer.valueVersion`.
10173
+ return this.valueVersion !== lastSeenValueVersion;
10174
+ }
10175
+ }
10176
+
10177
+ /**
10178
+ * Marks current view and all ancestors dirty.
10179
+ *
10180
+ * Returns the root view because it is found as a byproduct of marking the view tree
10181
+ * dirty, and can be used by methods that consume markViewDirty() to easily schedule
10182
+ * change detection. Otherwise, such methods would need to traverse up the view tree
10183
+ * an additional time to get the root view and schedule a tick on it.
10184
+ *
10185
+ * @param lView The starting LView to mark dirty
10186
+ * @returns the root LView
10187
+ */
10188
+ function markViewDirty(lView) {
10189
+ while (lView) {
10190
+ lView[FLAGS] |= 32 /* LViewFlags.Dirty */;
10191
+ const parent = getLViewParent(lView);
10192
+ // Stop traversing up as soon as you find a root view that wasn't attached to any container
10193
+ if (isRootView(lView) && !parent) {
10194
+ return lView;
10195
+ }
10196
+ // continue otherwise
10197
+ lView = parent;
10198
+ }
10199
+ return null;
10200
+ }
10201
+
10202
+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
10203
+ class ReactiveLViewConsumer extends ReactiveNode {
10204
+ constructor() {
10205
+ super(...arguments);
10206
+ this._lView = null;
10207
+ }
10208
+ set lView(lView) {
10209
+ NG_DEV_MODE && assertEqual(this._lView, null, 'Consumer already associated with a view.');
10210
+ this._lView = lView;
10211
+ }
10212
+ onConsumerDependencyMayHaveChanged() {
10213
+ NG_DEV_MODE &&
10214
+ assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
10215
+ markViewDirty(this._lView);
10216
+ }
10217
+ onProducerUpdateValueVersion() {
10218
+ // This type doesn't implement the producer side of a `ReactiveNode`.
10219
+ }
10220
+ get hasReadASignal() {
10221
+ return this.hasProducers;
10222
+ }
10223
+ runInContext(fn, rf, ctx) {
10224
+ const prevConsumer = setActiveConsumer(this);
10225
+ this.trackingVersion++;
10226
+ try {
10227
+ fn(rf, ctx);
10228
+ }
10229
+ finally {
10230
+ setActiveConsumer(prevConsumer);
10231
+ }
10232
+ }
10233
+ destroy() {
10234
+ // Incrementing the version means that every producer which tries to update this consumer will
10235
+ // consider its record stale, and not notify.
10236
+ this.trackingVersion++;
10237
+ }
10238
+ }
10239
+ let currentConsumer = null;
10240
+ function getOrCreateCurrentLViewConsumer() {
10241
+ currentConsumer ??= new ReactiveLViewConsumer();
10242
+ return currentConsumer;
10243
+ }
10244
+ /**
10245
+ * Create a new template consumer pointing at the specified LView.
10246
+ * Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
10247
+ * case, the LView will be updated.
10248
+ */
10249
+ function getReactiveLViewConsumer(lView, slot) {
10250
+ return lView[slot] ?? getOrCreateCurrentLViewConsumer();
10251
+ }
10252
+ /**
10253
+ * Assigns the `currentTemplateContext` to its LView's `REACTIVE_CONSUMER` slot if there are tracked
10254
+ * producers.
10255
+ *
10256
+ * The presence of producers means that a signal was read while the consumer was the active
10257
+ * consumer.
10258
+ *
10259
+ * If no producers are present, we do not assign the current template context. This also means we
10260
+ * can just reuse the template context for the next LView.
10261
+ */
10262
+ function commitLViewConsumerIfHasProducers(lView, slot) {
10263
+ const consumer = getOrCreateCurrentLViewConsumer();
10264
+ if (!consumer.hasReadASignal) {
10265
+ return;
10266
+ }
10267
+ lView[slot] = currentConsumer;
10268
+ consumer.lView = lView;
10269
+ currentConsumer = new ReactiveLViewConsumer();
10270
+ }
10271
+
9894
10272
  /** A special value which designates that a value has not changed. */
9895
10273
  const NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
9896
10274
 
@@ -9973,6 +10351,22 @@ function runInInjectionContext(injector, fn) {
9973
10351
  setInjectImplementation(previousInjectImplementation);
9974
10352
  }
9975
10353
  }
10354
+ /**
10355
+ * Asserts that the current stack frame is within an injection context and has access to `inject`.
10356
+ *
10357
+ * @param debugFn a reference to the function making the assertion (used for the error message).
10358
+ *
10359
+ * @publicApi
10360
+ */
10361
+ function assertInInjectionContext(debugFn) {
10362
+ // Taking a `Function` instead of a string name here prevents the unminified name of the function
10363
+ // from being retained in the bundle regardless of minification.
10364
+ if (!getInjectImplementation() && !getCurrentInjector()) {
10365
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
10366
+ (debugFn.name +
10367
+ '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
10368
+ }
10369
+ }
9976
10370
 
9977
10371
  /**
9978
10372
  * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
@@ -10125,6 +10519,8 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
10125
10519
  * @publicApi
10126
10520
  */
10127
10521
  class Injector {
10522
+ static { this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; }
10523
+ static { this.NULL = ( /* @__PURE__ */new NullInjector()); }
10128
10524
  static create(options, parent) {
10129
10525
  if (Array.isArray(options)) {
10130
10526
  return createInjector({ name: '' }, parent, options, '');
@@ -10134,20 +10530,18 @@ class Injector {
10134
10530
  return createInjector({ name }, options.parent, options.providers, name);
10135
10531
  }
10136
10532
  }
10533
+ /** @nocollapse */
10534
+ static { this.ɵprov = ɵɵdefineInjectable({
10535
+ token: Injector,
10536
+ providedIn: 'any',
10537
+ factory: () => ɵɵinject(INJECTOR),
10538
+ }); }
10539
+ /**
10540
+ * @internal
10541
+ * @nocollapse
10542
+ */
10543
+ static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
10137
10544
  }
10138
- Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
10139
- Injector.NULL = ( /* @__PURE__ */new NullInjector());
10140
- /** @nocollapse */
10141
- Injector.ɵprov = ɵɵdefineInjectable({
10142
- token: Injector,
10143
- providedIn: 'any',
10144
- factory: () => ɵɵinject(INJECTOR),
10145
- });
10146
- /**
10147
- * @internal
10148
- * @nocollapse
10149
- */
10150
- Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
10151
10545
 
10152
10546
  function findFirstClosedCycle(keys) {
10153
10547
  const res = [];
@@ -10748,6 +11142,7 @@ class ReflectiveInjector {
10748
11142
  }
10749
11143
  }
10750
11144
  class ReflectiveInjector_ {
11145
+ static { this.INJECTOR_KEY = ( /* @__PURE__ */ReflectiveKey.get(Injector)); }
10751
11146
  /**
10752
11147
  * Private
10753
11148
  */
@@ -10903,7 +11298,6 @@ class ReflectiveInjector_ {
10903
11298
  return this.displayName;
10904
11299
  }
10905
11300
  }
10906
- ReflectiveInjector_.INJECTOR_KEY = ( /* @__PURE__ */ReflectiveKey.get(Injector));
10907
11301
  function _mapProviders(injector, fn) {
10908
11302
  const res = [];
10909
11303
  for (let i = 0; i < injector._providers.length; ++i) {
@@ -10977,6 +11371,7 @@ function processHostBindingOpCodes(tView, lView) {
10977
11371
  const hostBindingOpCodes = tView.hostBindingOpCodes;
10978
11372
  if (hostBindingOpCodes === null)
10979
11373
  return;
11374
+ const consumer = getReactiveLViewConsumer(lView, REACTIVE_HOST_BINDING_CONSUMER);
10980
11375
  try {
10981
11376
  for (let i = 0; i < hostBindingOpCodes.length; i++) {
10982
11377
  const opCode = hostBindingOpCodes[i];
@@ -10991,11 +11386,13 @@ function processHostBindingOpCodes(tView, lView) {
10991
11386
  const hostBindingFn = hostBindingOpCodes[++i];
10992
11387
  setBindingRootForHostBindings(bindingRootIndx, directiveIdx);
10993
11388
  const context = lView[directiveIdx];
10994
- hostBindingFn(2 /* RenderFlags.Update */, context);
11389
+ consumer.runInContext(hostBindingFn, 2 /* RenderFlags.Update */, context);
10995
11390
  }
10996
11391
  }
10997
11392
  }
10998
11393
  finally {
11394
+ lView[REACTIVE_HOST_BINDING_CONSUMER] === null &&
11395
+ commitLViewConsumerIfHasProducers(lView, REACTIVE_HOST_BINDING_CONSUMER);
10999
11396
  setSelectedIndex(-1);
11000
11397
  }
11001
11398
  }
@@ -11051,6 +11448,7 @@ function createLView(parentLView, tView, context, flags, host, tHostNode, render
11051
11448
  lView[ID] = getUniqueLViewId();
11052
11449
  lView[HYDRATION] = hydrationInfo;
11053
11450
  lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
11451
+ lView[REACTIVE_TEMPLATE_CONSUMER] = null;
11054
11452
  ngDevMode &&
11055
11453
  assertEqual(tView.type == 2 /* TViewType.Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
11056
11454
  lView[DECLARATION_COMPONENT_VIEW] =
@@ -11335,6 +11733,7 @@ function refreshView(tView, lView, templateFn, context) {
11335
11733
  }
11336
11734
  }
11337
11735
  function executeTemplate(tView, lView, templateFn, rf, context) {
11736
+ const consumer = getReactiveLViewConsumer(lView, REACTIVE_TEMPLATE_CONSUMER);
11338
11737
  const prevSelectedIndex = getSelectedIndex();
11339
11738
  const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
11340
11739
  try {
@@ -11346,9 +11745,12 @@ function executeTemplate(tView, lView, templateFn, rf, context) {
11346
11745
  }
11347
11746
  const preHookType = isUpdatePhase ? 2 /* ProfilerEvent.TemplateUpdateStart */ : 0 /* ProfilerEvent.TemplateCreateStart */;
11348
11747
  profiler(preHookType, context);
11349
- templateFn(rf, context);
11748
+ consumer.runInContext(templateFn, rf, context);
11350
11749
  }
11351
11750
  finally {
11751
+ if (lView[REACTIVE_TEMPLATE_CONSUMER] === null) {
11752
+ commitLViewConsumerIfHasProducers(lView, REACTIVE_TEMPLATE_CONSUMER);
11753
+ }
11352
11754
  setSelectedIndex(prevSelectedIndex);
11353
11755
  const postHookType = isUpdatePhase ? 3 /* ProfilerEvent.TemplateUpdateEnd */ : 1 /* ProfilerEvent.TemplateCreateEnd */;
11354
11756
  profiler(postHookType, context);
@@ -12452,30 +12854,6 @@ function addToViewTree(lView, lViewOrLContainer) {
12452
12854
  ///////////////////////////////
12453
12855
  //// Change detection
12454
12856
  ///////////////////////////////
12455
- /**
12456
- * Marks current view and all ancestors dirty.
12457
- *
12458
- * Returns the root view because it is found as a byproduct of marking the view tree
12459
- * dirty, and can be used by methods that consume markViewDirty() to easily schedule
12460
- * change detection. Otherwise, such methods would need to traverse up the view tree
12461
- * an additional time to get the root view and schedule a tick on it.
12462
- *
12463
- * @param lView The starting LView to mark dirty
12464
- * @returns the root LView
12465
- */
12466
- function markViewDirty(lView) {
12467
- while (lView) {
12468
- lView[FLAGS] |= 32 /* LViewFlags.Dirty */;
12469
- const parent = getLViewParent(lView);
12470
- // Stop traversing up as soon as you find a root view that wasn't attached to any container
12471
- if (isRootView(lView) && !parent) {
12472
- return lView;
12473
- }
12474
- // continue otherwise
12475
- lView = parent;
12476
- }
12477
- return null;
12478
- }
12479
12857
  function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
12480
12858
  const rendererFactory = lView[RENDERER_FACTORY];
12481
12859
  // Check no changes mode is a dev only mode used to verify that bindings have not changed
@@ -13156,6 +13534,7 @@ class ComponentRef extends ComponentRef$1 {
13156
13534
  this.location = location;
13157
13535
  this._rootLView = _rootLView;
13158
13536
  this._tNode = _tNode;
13537
+ this.previousInputValues = null;
13159
13538
  this.instance = instance;
13160
13539
  this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
13161
13540
  this.componentType = componentType;
@@ -13164,8 +13543,16 @@ class ComponentRef extends ComponentRef$1 {
13164
13543
  const inputData = this._tNode.inputs;
13165
13544
  let dataValue;
13166
13545
  if (inputData !== null && (dataValue = inputData[name])) {
13546
+ this.previousInputValues ??= new Map();
13547
+ // Do not set the input if it is the same as the last value
13548
+ // This behavior matches `bindingUpdated` when binding inputs in templates.
13549
+ if (this.previousInputValues.has(name) &&
13550
+ Object.is(this.previousInputValues.get(name), value)) {
13551
+ return;
13552
+ }
13167
13553
  const lView = this._rootLView;
13168
13554
  setInputsForProperty(lView[TVIEW], lView, dataValue, name, value);
13555
+ this.previousInputValues.set(name, value);
13169
13556
  markDirtyIfOnPush(lView, this._tNode.index);
13170
13557
  }
13171
13558
  else {
@@ -14380,40 +14767,443 @@ function detectChanges(component) {
14380
14767
  detectChangesInternal(view[TVIEW], view, component);
14381
14768
  }
14382
14769
 
14770
+ const AT_THIS_LOCATION = '<-- AT THIS LOCATION';
14383
14771
  /**
14384
- * Verifies whether a given node matches an expected criteria,
14385
- * based on internal data structure state.
14772
+ * Retrieves a user friendly string for a given TNodeType for use in
14773
+ * friendly error messages
14774
+ *
14775
+ * @param tNodeType
14776
+ * @returns
14386
14777
  */
14387
- function validateMatchingNode(node, nodeType, tagName, lView, tNode) {
14388
- validateNodeExists(node);
14389
- if (node.nodeType !== nodeType ||
14390
- node.nodeType === Node.ELEMENT_NODE &&
14391
- node.tagName.toLowerCase() !== tagName?.toLowerCase()) {
14392
- // TODO: improve error message and use RuntimeError instead.
14393
- throw new Error(`Unexpected node found during hydration.`);
14778
+ function getFriendlyStringFromTNodeType(tNodeType) {
14779
+ switch (tNodeType) {
14780
+ case 4 /* TNodeType.Container */:
14781
+ return 'view container';
14782
+ case 2 /* TNodeType.Element */:
14783
+ return 'element';
14784
+ case 8 /* TNodeType.ElementContainer */:
14785
+ return 'ng-container';
14786
+ case 32 /* TNodeType.Icu */:
14787
+ return 'icu';
14788
+ case 64 /* TNodeType.Placeholder */:
14789
+ return 'i18n';
14790
+ case 16 /* TNodeType.Projection */:
14791
+ return 'projection';
14792
+ case 1 /* TNodeType.Text */:
14793
+ return 'text';
14794
+ default:
14795
+ // This should not happen as we cover all possible TNode types above.
14796
+ return '<unknown>';
14797
+ }
14798
+ }
14799
+ /**
14800
+ * Validates that provided nodes match during the hydration process.
14801
+ */
14802
+ function validateMatchingNode(node, nodeType, tagName, lView, tNode, isViewContainerAnchor = false) {
14803
+ if (!node ||
14804
+ (node.nodeType !== nodeType ||
14805
+ (node.nodeType === Node.ELEMENT_NODE &&
14806
+ node.tagName.toLowerCase() !== tagName?.toLowerCase()))) {
14807
+ const expectedNode = shortRNodeDescription(nodeType, tagName, null);
14808
+ let header = `During hydration Angular expected ${expectedNode} but `;
14809
+ const hostComponentDef = getDeclarationComponentDef(lView);
14810
+ const componentClassName = hostComponentDef?.type?.name;
14811
+ const expected = `Angular expected this DOM:\n\n${describeExpectedDom(lView, tNode, isViewContainerAnchor)}\n\n`;
14812
+ let actual = '';
14813
+ if (!node) {
14814
+ // No node found during hydration.
14815
+ header += `the node was not found.\n\n`;
14816
+ }
14817
+ else {
14818
+ const actualNode = shortRNodeDescription(node.nodeType, node.tagName ?? null, node.textContent ?? null);
14819
+ header += `found ${actualNode}.\n\n`;
14820
+ actual = `Actual DOM is:\n\n${describeDomFromNode(node)}\n\n`;
14821
+ }
14822
+ const footer = getHydrationErrorFooter(componentClassName);
14823
+ const message = header + expected + actual + getHydrationAttributeNote() + footer;
14824
+ throw new RuntimeError(500 /* RuntimeErrorCode.HYDRATION_NODE_MISMATCH */, message);
14394
14825
  }
14395
14826
  }
14396
14827
  /**
14397
- * Verifies whether next sibling node exists.
14828
+ * Validates that a given node has sibling nodes
14398
14829
  */
14399
14830
  function validateSiblingNodeExists(node) {
14400
14831
  validateNodeExists(node);
14401
14832
  if (!node.nextSibling) {
14402
- // TODO: improve error message and use RuntimeError instead.
14403
- throw new Error(`Unexpected state: insufficient number of sibling nodes.`);
14833
+ const header = 'During hydration Angular expected more sibling nodes to be present.\n\n';
14834
+ const actual = `Actual DOM is:\n\n${describeDomFromNode(node)}\n\n`;
14835
+ const footer = getHydrationErrorFooter();
14836
+ const message = header + actual + footer;
14837
+ throw new RuntimeError(501 /* RuntimeErrorCode.HYDRATION_MISSING_SIBLINGS */, message);
14404
14838
  }
14405
14839
  }
14840
+ /**
14841
+ * Validates that a node exists or throws
14842
+ */
14406
14843
  function validateNodeExists(node) {
14407
14844
  if (!node) {
14408
- // TODO: improve error message and use RuntimeError instead.
14409
- throw new Error(`Hydration expected an element to be present at this location.`);
14845
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, `Hydration expected an element to be present at this location.`);
14846
+ }
14847
+ }
14848
+ /**
14849
+ * Builds the hydration error message when a node is not found
14850
+ *
14851
+ * @param lView the LView where the node exists
14852
+ * @param tNode the TNode
14853
+ */
14854
+ function nodeNotFoundError(lView, tNode) {
14855
+ const header = 'During serialization, Angular was unable to find an element in the DOM:\n\n';
14856
+ const expected = `${describeExpectedDom(lView, tNode, false)}\n\n`;
14857
+ const footer = getHydrationErrorFooter();
14858
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + expected + footer);
14859
+ }
14860
+ /**
14861
+ * Builds a hydration error message when a node is not found at a path location
14862
+ *
14863
+ * @param host the Host Node
14864
+ * @param path the path to the node
14865
+ */
14866
+ function nodeNotFoundAtPathError(host, path) {
14867
+ const header = `During hydration Angular was unable to locate a node ` +
14868
+ `using the "${path}" path, starting from the ${describeRNode(host)} node.\n\n`;
14869
+ const footer = getHydrationErrorFooter();
14870
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + footer);
14871
+ }
14872
+ /**
14873
+ * Builds the hydration error message in the case that dom nodes are created outside of
14874
+ * the Angular context and are being used as projected nodes
14875
+ *
14876
+ * @param lView the LView
14877
+ * @param tNode the TNode
14878
+ * @returns an error
14879
+ */
14880
+ function unsupportedProjectionOfDomNodes(rNode) {
14881
+ const header = 'During serialization, Angular detected DOM nodes ' +
14882
+ 'that were created outside of Angular context and provided as projectable nodes ' +
14883
+ '(likely via `ViewContainerRef.createComponent` or `createComponent` APIs). ' +
14884
+ 'Hydration is not supported for such cases, consider refactoring the code to avoid ' +
14885
+ 'this pattern or using `ngSkipHydration` on the host element of the component.\n\n';
14886
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14887
+ const message = header + actual + getHydrationAttributeNote();
14888
+ return new RuntimeError(503 /* RuntimeErrorCode.UNSUPPORTED_PROJECTION_DOM_NODES */, message);
14889
+ }
14890
+ /**
14891
+ * Builds the hydration error message in the case that ngSkipHydration was used on a
14892
+ * node that is not a component host element or host binding
14893
+ *
14894
+ * @param rNode the HTML Element
14895
+ * @returns an error
14896
+ */
14897
+ function invalidSkipHydrationHost(rNode) {
14898
+ const header = 'The `ngSkipHydration` flag is applied on a node ' +
14899
+ 'that doesn\'t act as a component host. Hydration can be ' +
14900
+ 'skipped only on per-component basis.\n\n';
14901
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14902
+ const footer = 'Please move the `ngSkipHydration` attribute to the component host element.';
14903
+ const message = header + actual + footer;
14904
+ return new RuntimeError(504 /* RuntimeErrorCode.INVALID_SKIP_HYDRATION_HOST */, message);
14905
+ }
14906
+ /**
14907
+ * Builds the hydration error message in the case that a user is attempting to enable
14908
+ * hydration on internationalized nodes, which is not yet supported.
14909
+ *
14910
+ * @param rNode the HTML Element
14911
+ * @returns an error
14912
+ */
14913
+ function notYetSupportedI18nBlockError(rNode) {
14914
+ const header = 'Hydration for nodes marked with `i18n` is not yet supported. ' +
14915
+ 'You can opt-out a component that uses `i18n` in a template using ' +
14916
+ 'the `ngSkipHydration` attribute or fall back to the previous ' +
14917
+ 'hydration logic (which re-creates the application structure).\n\n';
14918
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14919
+ const message = header + actual;
14920
+ return new RuntimeError(518 /* RuntimeErrorCode.HYDRATION_I18N_NOT_YET_SUPPORTED */, message);
14921
+ }
14922
+ // Stringification methods
14923
+ /**
14924
+ * Stringifies a given TNode's attributes
14925
+ *
14926
+ * @param tNode a provided TNode
14927
+ * @returns string
14928
+ */
14929
+ function stringifyTNodeAttrs(tNode) {
14930
+ const results = [];
14931
+ if (tNode.attrs) {
14932
+ for (let i = 0; i < tNode.attrs.length;) {
14933
+ const attrName = tNode.attrs[i++];
14934
+ // Once we reach the first flag, we know that the list of
14935
+ // attributes is over.
14936
+ if (typeof attrName == 'number') {
14937
+ break;
14938
+ }
14939
+ const attrValue = tNode.attrs[i++];
14940
+ results.push(`${attrName}="${shorten(attrValue)}"`);
14941
+ }
14942
+ }
14943
+ return results.join(' ');
14944
+ }
14945
+ /**
14946
+ * The list of internal attributes that should be filtered out while
14947
+ * producing an error message.
14948
+ */
14949
+ const internalAttrs = new Set(['ngh', 'ng-version', 'ng-server-context']);
14950
+ /**
14951
+ * Stringifies an HTML Element's attributes
14952
+ *
14953
+ * @param rNode an HTML Element
14954
+ * @returns string
14955
+ */
14956
+ function stringifyRNodeAttrs(rNode) {
14957
+ const results = [];
14958
+ for (let i = 0; i < rNode.attributes.length; i++) {
14959
+ const attr = rNode.attributes[i];
14960
+ if (internalAttrs.has(attr.name))
14961
+ continue;
14962
+ results.push(`${attr.name}="${shorten(attr.value)}"`);
14963
+ }
14964
+ return results.join(' ');
14965
+ }
14966
+ // Methods for Describing the DOM
14967
+ /**
14968
+ * Converts a tNode to a helpful readable string value for use in error messages
14969
+ *
14970
+ * @param tNode a given TNode
14971
+ * @param innerContent the content of the node
14972
+ * @returns string
14973
+ */
14974
+ function describeTNode(tNode, innerContent = '…') {
14975
+ switch (tNode.type) {
14976
+ case 1 /* TNodeType.Text */:
14977
+ const content = tNode.value ? `(${tNode.value})` : '';
14978
+ return `#text${content}`;
14979
+ case 2 /* TNodeType.Element */:
14980
+ const attrs = stringifyTNodeAttrs(tNode);
14981
+ const tag = tNode.value.toLowerCase();
14982
+ return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
14983
+ case 8 /* TNodeType.ElementContainer */:
14984
+ return '<!-- ng-container -->';
14985
+ case 4 /* TNodeType.Container */:
14986
+ return '<!-- container -->';
14987
+ default:
14988
+ const typeAsString = getFriendlyStringFromTNodeType(tNode.type);
14989
+ return `#node(${typeAsString})`;
14990
+ }
14991
+ }
14992
+ /**
14993
+ * Converts an RNode to a helpful readable string value for use in error messages
14994
+ *
14995
+ * @param rNode a given RNode
14996
+ * @param innerContent the content of the node
14997
+ * @returns string
14998
+ */
14999
+ function describeRNode(rNode, innerContent = '…') {
15000
+ const node = rNode;
15001
+ switch (node.nodeType) {
15002
+ case Node.ELEMENT_NODE:
15003
+ const tag = node.tagName.toLowerCase();
15004
+ const attrs = stringifyRNodeAttrs(node);
15005
+ return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
15006
+ case Node.TEXT_NODE:
15007
+ const content = node.textContent ? shorten(node.textContent) : '';
15008
+ return `#text${content ? `(${content})` : ''}`;
15009
+ case Node.COMMENT_NODE:
15010
+ return `<!-- ${shorten(node.textContent ?? '')} -->`;
15011
+ default:
15012
+ return `#node(${node.nodeType})`;
15013
+ }
15014
+ }
15015
+ /**
15016
+ * Builds the string containing the expected DOM present given the LView and TNode
15017
+ * values for a readable error message
15018
+ *
15019
+ * @param lView the lView containing the DOM
15020
+ * @param tNode the tNode
15021
+ * @param isViewContainerAnchor boolean
15022
+ * @returns string
15023
+ */
15024
+ function describeExpectedDom(lView, tNode, isViewContainerAnchor) {
15025
+ const spacer = ' ';
15026
+ let content = '';
15027
+ if (tNode.prev) {
15028
+ content += spacer + '…\n';
15029
+ content += spacer + describeTNode(tNode.prev) + '\n';
15030
+ }
15031
+ else if (tNode.type && tNode.type & 12 /* TNodeType.AnyContainer */) {
15032
+ content += spacer + '…\n';
15033
+ }
15034
+ if (isViewContainerAnchor) {
15035
+ content += spacer + describeTNode(tNode) + '\n';
15036
+ content += spacer + `<!-- container --> ${AT_THIS_LOCATION}\n`;
15037
+ }
15038
+ else {
15039
+ content += spacer + describeTNode(tNode) + ` ${AT_THIS_LOCATION}\n`;
15040
+ }
15041
+ content += spacer + '…\n';
15042
+ const parentRNode = tNode.type ? getParentRElement(lView[TVIEW], tNode, lView) : null;
15043
+ if (parentRNode) {
15044
+ content = describeRNode(parentRNode, '\n' + content);
15045
+ }
15046
+ return content;
15047
+ }
15048
+ /**
15049
+ * Builds the string containing the DOM present around a given RNode for a
15050
+ * readable error message
15051
+ *
15052
+ * @param node the RNode
15053
+ * @returns string
15054
+ */
15055
+ function describeDomFromNode(node) {
15056
+ const spacer = ' ';
15057
+ let content = '';
15058
+ const currentNode = node;
15059
+ if (currentNode.previousSibling) {
15060
+ content += spacer + '…\n';
15061
+ content += spacer + describeRNode(currentNode.previousSibling) + '\n';
15062
+ }
15063
+ content += spacer + describeRNode(currentNode) + ` ${AT_THIS_LOCATION}\n`;
15064
+ if (node.nextSibling) {
15065
+ content += spacer + '…\n';
15066
+ }
15067
+ if (node.parentNode) {
15068
+ content = describeRNode(currentNode.parentNode, '\n' + content);
15069
+ }
15070
+ return content;
15071
+ }
15072
+ /**
15073
+ * Shortens the description of a given RNode by its type for readability
15074
+ *
15075
+ * @param nodeType the type of node
15076
+ * @param tagName the node tag name
15077
+ * @param textContent the text content in the node
15078
+ * @returns string
15079
+ */
15080
+ function shortRNodeDescription(nodeType, tagName, textContent) {
15081
+ switch (nodeType) {
15082
+ case Node.ELEMENT_NODE:
15083
+ return `<${tagName.toLowerCase()}>`;
15084
+ case Node.TEXT_NODE:
15085
+ const content = textContent ? ` (with the "${shorten(textContent)}" content)` : '';
15086
+ return `a text node${content}`;
15087
+ case Node.COMMENT_NODE:
15088
+ return 'a comment node';
15089
+ default:
15090
+ return `#node(nodeType=${nodeType})`;
15091
+ }
15092
+ }
15093
+ /**
15094
+ * Builds the footer hydration error message
15095
+ *
15096
+ * @param componentClassName the name of the component class
15097
+ * @returns string
15098
+ */
15099
+ function getHydrationErrorFooter(componentClassName) {
15100
+ const componentInfo = componentClassName ? `the "${componentClassName}"` : 'corresponding';
15101
+ return `To fix this problem:\n` +
15102
+ ` * check ${componentInfo} component for hydration-related issues\n` +
15103
+ ` * or skip hydration by adding the \`ngSkipHydration\` attribute ` +
15104
+ `to its host node in a template`;
15105
+ }
15106
+ /**
15107
+ * An attribute related note for hydration errors
15108
+ */
15109
+ function getHydrationAttributeNote() {
15110
+ return 'Note: attributes are only displayed to better represent the DOM' +
15111
+ ' but have no effect on hydration mismatches.\n\n';
15112
+ }
15113
+ // Node string utility functions
15114
+ /**
15115
+ * Strips all newlines out of a given string
15116
+ *
15117
+ * @param input a string to be cleared of new line characters
15118
+ * @returns
15119
+ */
15120
+ function stripNewlines(input) {
15121
+ return input.replace(/\s+/gm, '');
15122
+ }
15123
+ /**
15124
+ * Reduces a string down to a maximum length of characters with ellipsis for readability
15125
+ *
15126
+ * @param input a string input
15127
+ * @param maxLength a maximum length in characters
15128
+ * @returns string
15129
+ */
15130
+ function shorten(input, maxLength = 50) {
15131
+ if (!input) {
15132
+ return '';
15133
+ }
15134
+ input = stripNewlines(input);
15135
+ return input.length > maxLength ? `${input.substring(0, maxLength - 1)}…` : input;
15136
+ }
15137
+
15138
+ /**
15139
+ * Regexp that extracts a reference node information from the compressed node location.
15140
+ * The reference node is represented as either:
15141
+ * - a number which points to an LView slot
15142
+ * - the `b` char which indicates that the lookup should start from the `document.body`
15143
+ * - the `h` char to start lookup from the component host node (`lView[HOST]`)
15144
+ */
15145
+ const REF_EXTRACTOR_REGEXP = new RegExp(`^(\\d+)*(${REFERENCE_NODE_BODY}|${REFERENCE_NODE_HOST})*(.*)`);
15146
+ /**
15147
+ * Helper function that takes a reference node location and a set of navigation steps
15148
+ * (from the reference node) to a target node and outputs a string that represents
15149
+ * a location.
15150
+ *
15151
+ * For example, given: referenceNode = 'b' (body) and path = ['firstChild', 'firstChild',
15152
+ * 'nextSibling'], the function returns: `bf2n`.
15153
+ */
15154
+ function compressNodeLocation(referenceNode, path) {
15155
+ const result = [referenceNode];
15156
+ for (const segment of path) {
15157
+ const lastIdx = result.length - 1;
15158
+ if (lastIdx > 0 && result[lastIdx - 1] === segment) {
15159
+ // An empty string in a count slot represents 1 occurrence of an instruction.
15160
+ const value = (result[lastIdx] || 1);
15161
+ result[lastIdx] = value + 1;
15162
+ }
15163
+ else {
15164
+ // Adding a new segment to the path.
15165
+ // Using an empty string in a counter field to avoid encoding `1`s
15166
+ // into the path, since they are implicit (e.g. `f1n1` vs `fn`), so
15167
+ // it's enough to have a single char in this case.
15168
+ result.push(segment, '');
15169
+ }
15170
+ }
15171
+ return result.join('');
15172
+ }
15173
+ /**
15174
+ * Helper function that reverts the `compressNodeLocation` and transforms a given
15175
+ * string into an array where at 0th position there is a reference node info and
15176
+ * after that it contains information (in pairs) about a navigation step and the
15177
+ * number of repetitions.
15178
+ *
15179
+ * For example, the path like 'bf2n' will be transformed to:
15180
+ * ['b', 'firstChild', 2, 'nextSibling', 1].
15181
+ *
15182
+ * This information is later consumed by the code that navigates the DOM to find
15183
+ * a given node by its location.
15184
+ */
15185
+ function decompressNodeLocation(path) {
15186
+ const matches = path.match(REF_EXTRACTOR_REGEXP);
15187
+ const [_, refNodeId, refNodeName, rest] = matches;
15188
+ // If a reference node is represented by an index, transform it to a number.
15189
+ const ref = refNodeId ? parseInt(refNodeId, 10) : refNodeName;
15190
+ const steps = [];
15191
+ // Match all segments in a path.
15192
+ for (const [_, step, count] of rest.matchAll(/(f|n)(\d*)/g)) {
15193
+ const repeat = parseInt(count, 10) || 1;
15194
+ steps.push(step, repeat);
14410
15195
  }
15196
+ return [ref, ...steps];
14411
15197
  }
14412
15198
 
14413
15199
  /** Whether current TNode is a first node in an <ng-container>. */
14414
15200
  function isFirstElementInNgContainer(tNode) {
14415
15201
  return !tNode.prev && tNode.parent?.type === 8 /* TNodeType.ElementContainer */;
14416
15202
  }
15203
+ /** Returns an instruction index (subtracting HEADER_OFFSET). */
15204
+ function getNoOffsetIndex(tNode) {
15205
+ return tNode.index - HEADER_OFFSET;
15206
+ }
14417
15207
  /**
14418
15208
  * Locate a node in DOM tree that corresponds to a given TNode.
14419
15209
  *
@@ -14425,7 +15215,13 @@ function isFirstElementInNgContainer(tNode) {
14425
15215
  */
14426
15216
  function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14427
15217
  let native = null;
14428
- if (tView.firstChild === tNode) {
15218
+ const noOffsetIndex = getNoOffsetIndex(tNode);
15219
+ const nodes = hydrationInfo.data[NODES];
15220
+ if (nodes?.[noOffsetIndex]) {
15221
+ // We know the exact location of the node.
15222
+ native = locateRNodeByPath(nodes[noOffsetIndex], lView);
15223
+ }
15224
+ else if (tView.firstChild === tNode) {
14429
15225
  // We create a first node in this view, so we use a reference
14430
15226
  // to the first child in this DOM segment.
14431
15227
  native = hydrationInfo.firstChild;
@@ -14438,7 +15234,7 @@ function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14438
15234
  assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
14439
15235
  'to the previous node or a parent node.');
14440
15236
  if (isFirstElementInNgContainer(tNode)) {
14441
- const noOffsetParentIndex = tNode.parent.index - HEADER_OFFSET;
15237
+ const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
14442
15238
  native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
14443
15239
  }
14444
15240
  else {
@@ -14452,7 +15248,7 @@ function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14452
15248
  // represented in the DOM as `<div></div>...<!--container-->`.
14453
15249
  // In this case, there are nodes *after* this element and we need to skip
14454
15250
  // all of them to reach an element that we are looking for.
14455
- const noOffsetPrevSiblingIndex = previousTNode.index - HEADER_OFFSET;
15251
+ const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
14456
15252
  const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
14457
15253
  if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
14458
15254
  const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
@@ -14480,6 +15276,181 @@ function siblingAfter(skip, from) {
14480
15276
  }
14481
15277
  return currentNode;
14482
15278
  }
15279
+ /**
15280
+ * Helper function to produce a string representation of the navigation steps
15281
+ * (in terms of `nextSibling` and `firstChild` navigations). Used in error
15282
+ * messages in dev mode.
15283
+ */
15284
+ function stringifyNavigationInstructions(instructions) {
15285
+ const container = [];
15286
+ for (let i = 0; i < instructions.length; i += 2) {
15287
+ const step = instructions[i];
15288
+ const repeat = instructions[i + 1];
15289
+ for (let r = 0; r < repeat; r++) {
15290
+ container.push(step === NodeNavigationStep.FirstChild ? 'firstChild' : 'nextSibling');
15291
+ }
15292
+ }
15293
+ return container.join('.');
15294
+ }
15295
+ /**
15296
+ * Helper function that navigates from a starting point node (the `from` node)
15297
+ * using provided set of navigation instructions (within `path` argument).
15298
+ */
15299
+ function navigateToNode(from, instructions) {
15300
+ let node = from;
15301
+ for (let i = 0; i < instructions.length; i += 2) {
15302
+ const step = instructions[i];
15303
+ const repeat = instructions[i + 1];
15304
+ for (let r = 0; r < repeat; r++) {
15305
+ if (ngDevMode && !node) {
15306
+ throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
15307
+ }
15308
+ switch (step) {
15309
+ case NodeNavigationStep.FirstChild:
15310
+ node = node.firstChild;
15311
+ break;
15312
+ case NodeNavigationStep.NextSibling:
15313
+ node = node.nextSibling;
15314
+ break;
15315
+ }
15316
+ }
15317
+ }
15318
+ if (ngDevMode && !node) {
15319
+ throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
15320
+ }
15321
+ return node;
15322
+ }
15323
+ /**
15324
+ * Locates an RNode given a set of navigation instructions (which also contains
15325
+ * a starting point node info).
15326
+ */
15327
+ function locateRNodeByPath(path, lView) {
15328
+ const [referenceNode, ...navigationInstructions] = decompressNodeLocation(path);
15329
+ let ref;
15330
+ if (referenceNode === REFERENCE_NODE_HOST) {
15331
+ ref = lView[0];
15332
+ }
15333
+ else if (referenceNode === REFERENCE_NODE_BODY) {
15334
+ ref = ɵɵresolveBody(lView[0]);
15335
+ }
15336
+ else {
15337
+ const parentElementId = Number(referenceNode);
15338
+ ref = unwrapRNode(lView[parentElementId + HEADER_OFFSET]);
15339
+ }
15340
+ return navigateToNode(ref, navigationInstructions);
15341
+ }
15342
+ /**
15343
+ * Generate a list of DOM navigation operations to get from node `start` to node `finish`.
15344
+ *
15345
+ * Note: assumes that node `start` occurs before node `finish` in an in-order traversal of the DOM
15346
+ * tree. That is, we should be able to get from `start` to `finish` purely by using `.firstChild`
15347
+ * and `.nextSibling` operations.
15348
+ */
15349
+ function navigateBetween(start, finish) {
15350
+ if (start === finish) {
15351
+ return [];
15352
+ }
15353
+ else if (start.parentElement == null || finish.parentElement == null) {
15354
+ return null;
15355
+ }
15356
+ else if (start.parentElement === finish.parentElement) {
15357
+ return navigateBetweenSiblings(start, finish);
15358
+ }
15359
+ else {
15360
+ // `finish` is a child of its parent, so the parent will always have a child.
15361
+ const parent = finish.parentElement;
15362
+ const parentPath = navigateBetween(start, parent);
15363
+ const childPath = navigateBetween(parent.firstChild, finish);
15364
+ if (!parentPath || !childPath)
15365
+ return null;
15366
+ return [
15367
+ // First navigate to `finish`'s parent
15368
+ ...parentPath,
15369
+ // Then to its first child.
15370
+ NodeNavigationStep.FirstChild,
15371
+ // And finally from that node to `finish` (maybe a no-op if we're already there).
15372
+ ...childPath,
15373
+ ];
15374
+ }
15375
+ }
15376
+ /**
15377
+ * Calculates a path between 2 sibling nodes (generates a number of `NextSibling` navigations).
15378
+ */
15379
+ function navigateBetweenSiblings(start, finish) {
15380
+ const nav = [];
15381
+ let node = null;
15382
+ for (node = start; node != null && node !== finish; node = node.nextSibling) {
15383
+ nav.push(NodeNavigationStep.NextSibling);
15384
+ }
15385
+ return node === null ? [] : nav;
15386
+ }
15387
+ /**
15388
+ * Calculates a path between 2 nodes in terms of `nextSibling` and `firstChild`
15389
+ * navigations:
15390
+ * - the `from` node is a known node, used as an starting point for the lookup
15391
+ * (the `fromNodeName` argument is a string representation of the node).
15392
+ * - the `to` node is a node that the runtime logic would be looking up,
15393
+ * using the path generated by this function.
15394
+ */
15395
+ function calcPathBetween(from, to, fromNodeName) {
15396
+ const path = navigateBetween(from, to);
15397
+ return path === null ? null : compressNodeLocation(fromNodeName, path);
15398
+ }
15399
+ /**
15400
+ * Invoked at serialization time (on the server) when a set of navigation
15401
+ * instructions needs to be generated for a TNode.
15402
+ */
15403
+ function calcPathForNode(tNode, lView) {
15404
+ const parentTNode = tNode.parent;
15405
+ let parentIndex;
15406
+ let parentRNode;
15407
+ let referenceNodeName;
15408
+ if (parentTNode === null) {
15409
+ // No parent TNode - use host element as a reference node.
15410
+ parentIndex = referenceNodeName = REFERENCE_NODE_HOST;
15411
+ parentRNode = lView[HOST];
15412
+ }
15413
+ else {
15414
+ // Use parent TNode as a reference node.
15415
+ parentIndex = parentTNode.index;
15416
+ parentRNode = unwrapRNode(lView[parentIndex]);
15417
+ referenceNodeName = renderStringify(parentIndex - HEADER_OFFSET);
15418
+ }
15419
+ let rNode = unwrapRNode(lView[tNode.index]);
15420
+ if (tNode.type & 12 /* TNodeType.AnyContainer */) {
15421
+ // For <ng-container> nodes, instead of serializing a reference
15422
+ // to the anchor comment node, serialize a location of the first
15423
+ // DOM element. Paired with the container size (serialized as a part
15424
+ // of `ngh.containers`), it should give enough information for runtime
15425
+ // to hydrate nodes in this container.
15426
+ const firstRNode = getFirstNativeNode(lView, tNode);
15427
+ // If container is not empty, use a reference to the first element,
15428
+ // otherwise, rNode would point to an anchor comment node.
15429
+ if (firstRNode) {
15430
+ rNode = firstRNode;
15431
+ }
15432
+ }
15433
+ let path = calcPathBetween(parentRNode, rNode, referenceNodeName);
15434
+ if (path === null && parentRNode !== rNode) {
15435
+ // Searching for a path between elements within a host node failed.
15436
+ // Trying to find a path to an element starting from the `document.body` instead.
15437
+ //
15438
+ // Important note: this type of reference is relatively unstable, since Angular
15439
+ // may not be able to control parts of the page that the runtime logic navigates
15440
+ // through. This is mostly needed to cover "portals" use-case (like menus, dialog boxes,
15441
+ // etc), where nodes are content-projected (including direct DOM manipulations) outside
15442
+ // of the host node. The better solution is to provide APIs to work with "portals",
15443
+ // at which point this code path would not be needed.
15444
+ const body = parentRNode.ownerDocument.body;
15445
+ path = calcPathBetween(body, rNode, REFERENCE_NODE_BODY);
15446
+ if (path === null) {
15447
+ // If the path is still empty, it's likely that this node is detached and
15448
+ // won't be found during hydration.
15449
+ throw nodeNotFoundError(lView, tNode);
15450
+ }
15451
+ }
15452
+ return path;
15453
+ }
14483
15454
 
14484
15455
  function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
14485
15456
  ngDevMode && assertFirstCreatePass(tView);
@@ -14556,7 +15527,7 @@ function createContainerAnchorImpl(tView, lView, tNode, index) {
14556
15527
  */
14557
15528
  function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
14558
15529
  const hydrationInfo = lView[HYDRATION];
14559
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
15530
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
14560
15531
  lastNodeWasCreated(isNodeCreationMode);
14561
15532
  // Regular creation mode.
14562
15533
  if (isNodeCreationMode) {
@@ -14565,11 +15536,8 @@ function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
14565
15536
  // Hydration mode, looking up existing elements in DOM.
14566
15537
  const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
14567
15538
  ngDevMode && validateNodeExists(currentRNode);
15539
+ setSegmentHead(hydrationInfo, index, currentRNode);
14568
15540
  const viewContainerSize = calcSerializedContainerSize(hydrationInfo, index);
14569
- // If this container is non-empty, store the first node as a segment head,
14570
- // otherwise, this node is an anchor and segment head doesn't exist (thus `null`).
14571
- const segmentHead = viewContainerSize > 0 ? currentRNode : null;
14572
- setSegmentHead(hydrationInfo, index, segmentHead);
14573
15541
  const comment = siblingAfter(viewContainerSize, currentRNode);
14574
15542
  if (ngDevMode) {
14575
15543
  validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
@@ -14825,7 +15793,7 @@ let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) =>
14825
15793
  */
14826
15794
  function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, index) {
14827
15795
  const hydrationInfo = lView[HYDRATION];
14828
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
15796
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
14829
15797
  lastNodeWasCreated(isNodeCreationMode);
14830
15798
  // Regular creation mode.
14831
15799
  if (isNodeCreationMode) {
@@ -14849,10 +15817,17 @@ function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, inde
14849
15817
  // Checks if the skip hydration attribute is present during hydration so we know to
14850
15818
  // skip attempting to hydrate this block.
14851
15819
  if (hydrationInfo && hasNgSkipHydrationAttr(tNode)) {
14852
- enterSkipHydrationBlock(tNode);
14853
- // Since this isn't hydratable, we need to empty the node
14854
- // so there's no duplicate content after render
14855
- clearElementContents(renderer, native);
15820
+ if (isComponentHost(tNode)) {
15821
+ enterSkipHydrationBlock(tNode);
15822
+ // Since this isn't hydratable, we need to empty the node
15823
+ // so there's no duplicate content after render
15824
+ clearElementContents(native);
15825
+ }
15826
+ else if (ngDevMode) {
15827
+ // If this is not a component host, throw an error.
15828
+ // Hydration can be skipped on per-component basis only.
15829
+ throw invalidSkipHydrationHost(native);
15830
+ }
14856
15831
  }
14857
15832
  return native;
14858
15833
  }
@@ -14986,10 +15961,7 @@ function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
14986
15961
  ngDevMode &&
14987
15962
  assertNumber(ngContainerSize, 'Unexpected state: hydrating an <ng-container>, ' +
14988
15963
  'but no hydration info is available.');
14989
- // If this container is non-empty, store the first node as a segment head,
14990
- // otherwise, this node is an anchor and segment head doesn't exist (thus `null`).
14991
- const segmentHead = ngContainerSize > 0 ? currentRNode : null;
14992
- setSegmentHead(hydrationInfo, index, segmentHead);
15964
+ setSegmentHead(hydrationInfo, index, currentRNode);
14993
15965
  comment = siblingAfter(ngContainerSize, currentRNode);
14994
15966
  if (ngDevMode) {
14995
15967
  validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
@@ -15371,7 +16343,10 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
15371
16343
  tProjectionNode.projection = selectorIndex;
15372
16344
  // `<ng-content>` has no content
15373
16345
  setCurrentTNodeAsNotParent();
15374
- if ((tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
16346
+ const hydrationInfo = lView[HYDRATION];
16347
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
16348
+ if (isNodeCreationMode &&
16349
+ (tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15375
16350
  // re-distribution of projectable nodes is stored on a component's view level
15376
16351
  applyProjection(tView, lView, tProjectionNode);
15377
16352
  }
@@ -17292,8 +18267,11 @@ function isStylingValuePresent(value) {
17292
18267
  * @param suffix
17293
18268
  */
17294
18269
  function normalizeSuffix(value, suffix) {
17295
- if (value == null /** || value === undefined */) {
18270
+ if (value == null || value === '') {
17296
18271
  // do nothing
18272
+ // Do not add the suffix if the value is going to be empty.
18273
+ // As it produce invalid CSS, which the browsers will automatically omit but Domino will not.
18274
+ // Example: `"left": "px;"` instead of `"left": ""`.
17297
18275
  }
17298
18276
  else if (typeof suffix === 'string') {
17299
18277
  value = value + suffix;
@@ -17334,7 +18312,7 @@ function ɵɵtext(index, value = '') {
17334
18312
  const tNode = tView.firstCreatePass ?
17335
18313
  getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null) :
17336
18314
  tView.data[adjustedIndex];
17337
- const textNative = _locateOrCreateTextNode(tView, lView, tNode, value);
18315
+ const textNative = _locateOrCreateTextNode(tView, lView, tNode, value, index);
17338
18316
  lView[adjustedIndex] = textNative;
17339
18317
  if (wasLastNodeCreated()) {
17340
18318
  appendChild(tView, lView, textNative, tNode);
@@ -17342,7 +18320,7 @@ function ɵɵtext(index, value = '') {
17342
18320
  // Text nodes are self closing.
17343
18321
  setCurrentTNode(tNode, false);
17344
18322
  }
17345
- let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
18323
+ let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
17346
18324
  lastNodeWasCreated(true);
17347
18325
  return createTextNode(lView[RENDERER], value);
17348
18326
  };
@@ -17350,9 +18328,9 @@ let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
17350
18328
  * Enables hydration code path (to lookup existing elements in DOM)
17351
18329
  * in addition to the regular creation mode of text nodes.
17352
18330
  */
17353
- function locateOrCreateTextNodeImpl(tView, lView, tNode, value) {
18331
+ function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
17354
18332
  const hydrationInfo = lView[HYDRATION];
17355
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
18333
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
17356
18334
  lastNodeWasCreated(isNodeCreationMode);
17357
18335
  // Regular creation mode.
17358
18336
  if (isNodeCreationMode) {
@@ -21160,13 +22138,13 @@ class StandaloneService {
21160
22138
  this.cachedInjectors.clear();
21161
22139
  }
21162
22140
  }
22141
+ /** @nocollapse */
22142
+ static { this.ɵprov = ɵɵdefineInjectable({
22143
+ token: StandaloneService,
22144
+ providedIn: 'environment',
22145
+ factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22146
+ }); }
21163
22147
  }
21164
- /** @nocollapse */
21165
- StandaloneService.ɵprov = ɵɵdefineInjectable({
21166
- token: StandaloneService,
21167
- providedIn: 'environment',
21168
- factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
21169
- });
21170
22148
  /**
21171
22149
  * A feature that acts as a setup code for the {@link StandaloneService}.
21172
22150
  *
@@ -22208,6 +23186,7 @@ function symbolIterator() {
22208
23186
  * @publicApi
22209
23187
  */
22210
23188
  class QueryList {
23189
+ static { Symbol.iterator; }
22211
23190
  /**
22212
23191
  * Returns `Observable` of `QueryList` notifying the subscriber of changes.
22213
23192
  */
@@ -22335,7 +23314,6 @@ class QueryList {
22335
23314
  this.changes.unsubscribe();
22336
23315
  }
22337
23316
  }
22338
- Symbol.iterator;
22339
23317
 
22340
23318
  /**
22341
23319
  * Represents an embedded template that can be used to instantiate embedded views.
@@ -22356,12 +23334,12 @@ Symbol.iterator;
22356
23334
  * @publicApi
22357
23335
  */
22358
23336
  class TemplateRef {
23337
+ /**
23338
+ * @internal
23339
+ * @nocollapse
23340
+ */
23341
+ static { this.__NG_ELEMENT_ID__ = injectTemplateRef; }
22359
23342
  }
22360
- /**
22361
- * @internal
22362
- * @nocollapse
22363
- */
22364
- TemplateRef.__NG_ELEMENT_ID__ = injectTemplateRef;
22365
23343
  const ViewEngineTemplateRef = TemplateRef;
22366
23344
  // TODO(alxhub): combine interface and implementation. Currently this is challenging since something
22367
23345
  // in g3 depends on them being separate.
@@ -22460,6 +23438,56 @@ function removeDehydratedView(dehydratedView, renderer) {
22460
23438
  }
22461
23439
  }
22462
23440
  }
23441
+ /**
23442
+ * Walks over all views within this LContainer invokes dehydrated views
23443
+ * cleanup function for each one.
23444
+ */
23445
+ function cleanupLContainer(lContainer) {
23446
+ removeDehydratedViews(lContainer);
23447
+ for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
23448
+ cleanupLView(lContainer[i]);
23449
+ }
23450
+ }
23451
+ /**
23452
+ * Walks over `LContainer`s and components registered within
23453
+ * this LView and invokes dehydrated views cleanup function for each one.
23454
+ */
23455
+ function cleanupLView(lView) {
23456
+ const tView = lView[TVIEW];
23457
+ for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
23458
+ if (isLContainer(lView[i])) {
23459
+ const lContainer = lView[i];
23460
+ cleanupLContainer(lContainer);
23461
+ }
23462
+ else if (Array.isArray(lView[i])) {
23463
+ // This is a component, enter the `cleanupLView` recursively.
23464
+ cleanupLView(lView[i]);
23465
+ }
23466
+ }
23467
+ }
23468
+ /**
23469
+ * Walks over all views registered within the ApplicationRef and removes
23470
+ * all dehydrated views from all `LContainer`s along the way.
23471
+ */
23472
+ function cleanupDehydratedViews(appRef, pendingTasks) {
23473
+ // Wait once an app becomes stable and cleanup all views that
23474
+ // were not claimed during the application bootstrap process.
23475
+ // The timing is similar to when we kick off serialization on the server.
23476
+ const isStablePromise = appRef.isStable.pipe(first((isStable) => isStable)).toPromise();
23477
+ const pendingTasksPromise = pendingTasks.whenAllTasksComplete;
23478
+ return Promise.allSettled([isStablePromise, pendingTasksPromise]).then(() => {
23479
+ const viewRefs = appRef._views;
23480
+ for (const viewRef of viewRefs) {
23481
+ const lView = getComponentLViewForHydration(viewRef);
23482
+ // An `lView` might be `null` if a `ViewRef` represents
23483
+ // an embedded view (not a component view).
23484
+ if (lView !== null && lView[HOST] !== null) {
23485
+ cleanupLView(lView);
23486
+ ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
23487
+ }
23488
+ }
23489
+ });
23490
+ }
22463
23491
 
22464
23492
  /**
22465
23493
  * Given a current DOM node and a serialized information about the views
@@ -22469,20 +23497,24 @@ function removeDehydratedView(dehydratedView, renderer) {
22469
23497
  function locateDehydratedViewsInContainer(currentRNode, serializedViews) {
22470
23498
  const dehydratedViews = [];
22471
23499
  for (const serializedView of serializedViews) {
22472
- const view = {
22473
- data: serializedView,
22474
- firstChild: null,
22475
- };
22476
- if (serializedView[NUM_ROOT_NODES] > 0) {
22477
- // Keep reference to the first node in this view,
22478
- // so it can be accessed while invoking template instructions.
22479
- view.firstChild = currentRNode;
22480
- // Move over to the next node after this view, which can
22481
- // either be a first node of the next view or an anchor comment
22482
- // node after the last view in a container.
22483
- currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
23500
+ // Repeats a view multiple times as needed, based on the serialized information
23501
+ // (for example, for *ngFor-produced views).
23502
+ for (let i = 0; i < (serializedView[MULTIPLIER] ?? 1); i++) {
23503
+ const view = {
23504
+ data: serializedView,
23505
+ firstChild: null,
23506
+ };
23507
+ if (serializedView[NUM_ROOT_NODES] > 0) {
23508
+ // Keep reference to the first node in this view,
23509
+ // so it can be accessed while invoking template instructions.
23510
+ view.firstChild = currentRNode;
23511
+ // Move over to the next node after this view, which can
23512
+ // either be a first node of the next view or an anchor comment
23513
+ // node after the last view in a container.
23514
+ currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
23515
+ }
23516
+ dehydratedViews.push(view);
22484
23517
  }
22485
- dehydratedViews.push(view);
22486
23518
  }
22487
23519
  return [currentRNode, dehydratedViews];
22488
23520
  }
@@ -22546,12 +23578,12 @@ function findMatchingDehydratedView(lContainer, template) {
22546
23578
  * @publicApi
22547
23579
  */
22548
23580
  class ViewContainerRef {
23581
+ /**
23582
+ * @internal
23583
+ * @nocollapse
23584
+ */
23585
+ static { this.__NG_ELEMENT_ID__ = injectViewContainerRef; }
22549
23586
  }
22550
- /**
22551
- * @internal
22552
- * @nocollapse
22553
- */
22554
- ViewContainerRef.__NG_ELEMENT_ID__ = injectViewContainerRef;
22555
23587
  /**
22556
23588
  * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
22557
23589
  * already exists, retrieves the existing ViewContainerRef.
@@ -22863,21 +23895,22 @@ function locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
22863
23895
  if (lContainer[NATIVE] && lContainer[DEHYDRATED_VIEWS])
22864
23896
  return;
22865
23897
  const hydrationInfo = hostLView[HYDRATION];
22866
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock(hostTNode);
23898
+ const noOffsetIndex = hostTNode.index - HEADER_OFFSET;
23899
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock(hostTNode) ||
23900
+ isDisconnectedNode(hydrationInfo, noOffsetIndex);
22867
23901
  // Regular creation mode.
22868
23902
  if (isNodeCreationMode) {
22869
23903
  return createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
22870
23904
  }
22871
23905
  // Hydration mode, looking up an anchor node and dehydrated views in DOM.
22872
- const index = hostTNode.index - HEADER_OFFSET;
22873
- const currentRNode = getSegmentHead(hydrationInfo, index);
22874
- const serializedViews = hydrationInfo.data[CONTAINERS]?.[index];
23906
+ const currentRNode = getSegmentHead(hydrationInfo, noOffsetIndex);
23907
+ const serializedViews = hydrationInfo.data[CONTAINERS]?.[noOffsetIndex];
22875
23908
  ngDevMode &&
22876
23909
  assertDefined(serializedViews, 'Unexpected state: no hydration info available for a given TNode, ' +
22877
23910
  'which represents a view container.');
22878
23911
  const [commentNode, dehydratedViews] = locateDehydratedViewsInContainer(currentRNode, serializedViews);
22879
23912
  if (ngDevMode) {
22880
- validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode);
23913
+ validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode, true);
22881
23914
  // Do not throw in case this node is already claimed (thus `false` as a second
22882
23915
  // argument). If this container is created based on an `<ng-template>`, the comment
22883
23916
  // node would be already claimed from the `template` instruction. If an element acts
@@ -23716,7 +24749,6 @@ function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRo
23716
24749
  ];
23717
24750
  exports.forEach(verifyExportsAreDeclaredOrReExported);
23718
24751
  declarations.forEach(decl => verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot));
23719
- declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule);
23720
24752
  const ngModule = getAnnotation(moduleType, 'NgModule');
23721
24753
  if (ngModule) {
23722
24754
  ngModule.imports &&
@@ -23726,8 +24758,6 @@ function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRo
23726
24758
  });
23727
24759
  ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType);
23728
24760
  ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule);
23729
- ngModule.entryComponents &&
23730
- deepForEach(ngModule.entryComponents, verifyComponentIsPartOfNgModule);
23731
24761
  }
23732
24762
  // Throw Error if any errors were detected.
23733
24763
  if (errors.length) {
@@ -23805,16 +24835,6 @@ function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRo
23805
24835
  `function for bootstrap instead.`);
23806
24836
  }
23807
24837
  }
23808
- function verifyComponentEntryComponentsIsPartOfNgModule(type) {
23809
- type = resolveForwardRef(type);
23810
- if (getComponentDef$1(type)) {
23811
- // We know we are component
23812
- const component = getAnnotation(type, 'Component');
23813
- if (component && component.entryComponents) {
23814
- deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule);
23815
- }
23816
- }
23817
- }
23818
24838
  function verifySemanticsOfNgModuleImport(type, importingModule) {
23819
24839
  type = resolveForwardRef(type);
23820
24840
  const directiveDef = getComponentDef$1(type) || getDirectiveDef(type);
@@ -24715,10 +25735,11 @@ class TestBedCompiler {
24715
25735
  }
24716
25736
  }
24717
25737
  queueTypesFromModulesArray(arr) {
24718
- // Because we may encounter the same NgModule while processing the imports and exports of an
24719
- // NgModule tree, we cache them in this set so we can skip ones that have already been seen
24720
- // encountered. In some test setups, this caching resulted in 10X runtime improvement.
24721
- const processedNgModuleDefs = new Set();
25738
+ // Because we may encounter the same NgModule or a standalone Component while processing
25739
+ // the dependencies of an NgModule or a standalone Component, we cache them in this set so we
25740
+ // can skip ones that have already been seen encountered. In some test setups, this caching
25741
+ // resulted in 10X runtime improvement.
25742
+ const processedDefs = new Set();
24722
25743
  const queueTypesFromModulesArrayRecur = (arr) => {
24723
25744
  for (const value of arr) {
24724
25745
  if (Array.isArray(value)) {
@@ -24726,10 +25747,10 @@ class TestBedCompiler {
24726
25747
  }
24727
25748
  else if (hasNgModuleDef(value)) {
24728
25749
  const def = value.ɵmod;
24729
- if (processedNgModuleDefs.has(def)) {
25750
+ if (processedDefs.has(def)) {
24730
25751
  continue;
24731
25752
  }
24732
- processedNgModuleDefs.add(def);
25753
+ processedDefs.add(def);
24733
25754
  // Look through declarations, imports, and exports, and queue
24734
25755
  // everything found there.
24735
25756
  this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
@@ -24742,6 +25763,10 @@ class TestBedCompiler {
24742
25763
  else if (isStandaloneComponent(value)) {
24743
25764
  this.queueType(value, null);
24744
25765
  const def = getComponentDef(value);
25766
+ if (processedDefs.has(def)) {
25767
+ continue;
25768
+ }
25769
+ processedDefs.add(def);
24745
25770
  const dependencies = maybeUnwrapFn(def.dependencies ?? []);
24746
25771
  dependencies.forEach((dependency) => {
24747
25772
  // Note: in AOT, the `dependencies` might also contain regular
@@ -25109,6 +26134,7 @@ class TestBedImpl {
25109
26134
  */
25110
26135
  this.globalCompilationChecked = false;
25111
26136
  }
26137
+ static { this._INSTANCE = null; }
25112
26138
  static get INSTANCE() {
25113
26139
  return TestBedImpl._INSTANCE = TestBedImpl._INSTANCE || new TestBedImpl();
25114
26140
  }
@@ -25518,7 +26544,6 @@ class TestBedImpl {
25518
26544
  }
25519
26545
  }
25520
26546
  }
25521
- TestBedImpl._INSTANCE = null;
25522
26547
  /**
25523
26548
  * @description
25524
26549
  * Configures and initializes environment for unit testing and provides methods for