@angular/core 19.2.0-next.2 → 19.2.0-next.3

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 (35) hide show
  1. package/fesm2022/core.mjs +128 -83
  2. package/fesm2022/core.mjs.map +1 -1
  3. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  4. package/fesm2022/primitives/signals.mjs +1 -1
  5. package/fesm2022/rxjs-interop.mjs +1 -1
  6. package/fesm2022/testing.mjs +5 -5
  7. package/index.d.ts +25 -10
  8. package/package.json +1 -1
  9. package/primitives/event-dispatch/index.d.ts +1 -1
  10. package/primitives/signals/index.d.ts +1 -1
  11. package/rxjs-interop/index.d.ts +1 -1
  12. package/schematics/bundles/{apply_import_manager-d8ea426b.js → apply_import_manager-f4d044b2.js} +3 -3
  13. package/schematics/bundles/{checker-9af84be9.js → checker-32db85a6.js} +87 -50
  14. package/schematics/bundles/cleanup-unused-imports.js +6 -6
  15. package/schematics/bundles/{compiler_host-dbff2781.js → compiler_host-540e221c.js} +2 -2
  16. package/schematics/bundles/control-flow-migration.js +10 -3
  17. package/schematics/bundles/explicit-standalone-flag.js +5 -5
  18. package/schematics/bundles/{imports-31a38653.js → imports-abe29092.js} +1 -1
  19. package/schematics/bundles/{index-93e324de.js → index-7ee8967e.js} +4 -4
  20. package/schematics/bundles/{index-23b503a4.js → index-d5020c9c.js} +4 -4
  21. package/schematics/bundles/inject-migration.js +6 -6
  22. package/schematics/bundles/{leading_space-6e7a8ec6.js → leading_space-d190b83b.js} +1 -1
  23. package/schematics/bundles/{migrate_ts_type_references-c6615b87.js → migrate_ts_type_references-26986908.js} +6 -6
  24. package/schematics/bundles/{nodes-88c2157f.js → nodes-a9f0b985.js} +2 -2
  25. package/schematics/bundles/output-migration.js +6 -6
  26. package/schematics/bundles/pending-tasks.js +5 -5
  27. package/schematics/bundles/{program-66386e72.js → program-507de2f1.js} +34 -20
  28. package/schematics/bundles/{project_tsconfig_paths-6c9cde78.js → project_tsconfig_paths-e9ccccbf.js} +1 -1
  29. package/schematics/bundles/provide-initializer.js +5 -5
  30. package/schematics/bundles/route-lazy-loading.js +4 -4
  31. package/schematics/bundles/signal-input-migration.js +8 -8
  32. package/schematics/bundles/signal-queries-migration.js +8 -8
  33. package/schematics/bundles/signals.js +8 -8
  34. package/schematics/bundles/standalone-migration.js +8 -8
  35. package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v19.2.0-next.2
2
+ * @license Angular v19.2.0-next.3
3
3
  * (c) 2010-2024 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -377,13 +377,11 @@ function stringify(token) {
377
377
  * @returns concatenated string.
378
378
  */
379
379
  function concatStringsWithSpace(before, after) {
380
- return before == null || before === ''
381
- ? after === null
382
- ? ''
383
- : after
384
- : after == null || after === ''
385
- ? before
386
- : before + ' ' + after;
380
+ if (!before)
381
+ return after || '';
382
+ if (!after)
383
+ return before;
384
+ return `${before} ${after}`;
387
385
  }
388
386
  /**
389
387
  * Ellipses the string in the middle when longer than the max length
@@ -2902,6 +2900,7 @@ const ON_DESTROY_HOOKS = 21;
2902
2900
  const EFFECTS_TO_SCHEDULE = 22;
2903
2901
  const EFFECTS = 23;
2904
2902
  const REACTIVE_TEMPLATE_CONSUMER = 24;
2903
+ const AFTER_RENDER_SEQUENCES_TO_ADD = 25;
2905
2904
  /**
2906
2905
  * Size of LView's header. Necessary to adjust for it when setting slots.
2907
2906
  *
@@ -2909,7 +2908,7 @@ const REACTIVE_TEMPLATE_CONSUMER = 24;
2909
2908
  * instruction index into `LView` index. All other indexes should be in the `LView` index space and
2910
2909
  * there should be no need to refer to `HEADER_OFFSET` anywhere else.
2911
2910
  */
2912
- const HEADER_OFFSET = 25;
2911
+ const HEADER_OFFSET = 26;
2913
2912
 
2914
2913
  /**
2915
2914
  * Special location which allows easy identification of type. If we have an array which was
@@ -3419,7 +3418,7 @@ function requiresRefreshOrTraversal(lView) {
3419
3418
  * parents above.
3420
3419
  */
3421
3420
  function updateAncestorTraversalFlagsOnAttach(lView) {
3422
- lView[ENVIRONMENT].changeDetectionScheduler?.notify(9 /* NotificationSource.ViewAttached */);
3421
+ lView[ENVIRONMENT].changeDetectionScheduler?.notify(8 /* NotificationSource.ViewAttached */);
3423
3422
  if (lView[FLAGS] & 64 /* LViewFlags.Dirty */) {
3424
3423
  lView[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
3425
3424
  }
@@ -6162,7 +6161,7 @@ class PendingTasks {
6162
6161
  return;
6163
6162
  }
6164
6163
  // Notifying the scheduler will hold application stability open until the next tick.
6165
- this.scheduler.notify(12 /* NotificationSource.PendingTaskRemoved */);
6164
+ this.scheduler.notify(11 /* NotificationSource.PendingTaskRemoved */);
6166
6165
  this.internalPendingTasks.remove(taskId);
6167
6166
  };
6168
6167
  }
@@ -8656,6 +8655,23 @@ function assertNotInReactiveContext(debugFn, extraContext) {
8656
8655
  }
8657
8656
  }
8658
8657
 
8658
+ class ViewContext {
8659
+ view;
8660
+ node;
8661
+ constructor(view, node) {
8662
+ this.view = view;
8663
+ this.node = node;
8664
+ }
8665
+ /**
8666
+ * @internal
8667
+ * @nocollapse
8668
+ */
8669
+ static __NG_ELEMENT_ID__ = injectViewContext;
8670
+ }
8671
+ function injectViewContext() {
8672
+ return new ViewContext(getLView(), getCurrentTNode());
8673
+ }
8674
+
8659
8675
  /**
8660
8676
  * The phase to run an `afterRender` or `afterNextRender` callback in.
8661
8677
  *
@@ -8794,7 +8810,7 @@ class AfterRenderImpl {
8794
8810
  this.sequences.add(sequence);
8795
8811
  }
8796
8812
  if (this.deferredRegistrations.size > 0) {
8797
- this.scheduler.notify(8 /* NotificationSource.DeferredRenderHook */);
8813
+ this.scheduler.notify(7 /* NotificationSource.RenderHook */);
8798
8814
  }
8799
8815
  this.deferredRegistrations.clear();
8800
8816
  if (hasSequencesToExecute) {
@@ -8802,16 +8818,27 @@ class AfterRenderImpl {
8802
8818
  }
8803
8819
  }
8804
8820
  register(sequence) {
8805
- if (!this.executing) {
8806
- this.sequences.add(sequence);
8807
- // Trigger an `ApplicationRef.tick()` if one is not already pending/running, because we have a
8808
- // new render hook that needs to run.
8809
- this.scheduler.notify(7 /* NotificationSource.RenderHook */);
8821
+ const { view } = sequence;
8822
+ if (view !== undefined) {
8823
+ // Delay adding it to the manager, add it to the view instead.
8824
+ (view[AFTER_RENDER_SEQUENCES_TO_ADD] ??= []).push(sequence);
8825
+ // Mark the view for traversal to ensure we eventually schedule the afterNextRender.
8826
+ markAncestorsForTraversal(view);
8827
+ view[FLAGS] |= 8192 /* LViewFlags.HasChildViewsToRefresh */;
8828
+ }
8829
+ else if (!this.executing) {
8830
+ this.addSequence(sequence);
8810
8831
  }
8811
8832
  else {
8812
8833
  this.deferredRegistrations.add(sequence);
8813
8834
  }
8814
8835
  }
8836
+ addSequence(sequence) {
8837
+ this.sequences.add(sequence);
8838
+ // Trigger an `ApplicationRef.tick()` if one is not already pending/running, because we have a
8839
+ // new render hook that needs to run.
8840
+ this.scheduler.notify(7 /* NotificationSource.RenderHook */);
8841
+ }
8815
8842
  unregister(sequence) {
8816
8843
  if (this.executing && this.sequences.has(sequence)) {
8817
8844
  // We can't remove an `AfterRenderSequence` in the middle of iteration.
@@ -8841,6 +8868,7 @@ class AfterRenderImpl {
8841
8868
  class AfterRenderSequence {
8842
8869
  impl;
8843
8870
  hooks;
8871
+ view;
8844
8872
  once;
8845
8873
  snapshot;
8846
8874
  /**
@@ -8854,9 +8882,10 @@ class AfterRenderSequence {
8854
8882
  */
8855
8883
  pipelinedValue = undefined;
8856
8884
  unregisterOnDestroy;
8857
- constructor(impl, hooks, once, destroyRef, snapshot = null) {
8885
+ constructor(impl, hooks, view, once, destroyRef, snapshot = null) {
8858
8886
  this.impl = impl;
8859
8887
  this.hooks = hooks;
8888
+ this.view = view;
8860
8889
  this.once = once;
8861
8890
  this.snapshot = snapshot;
8862
8891
  this.unregisterOnDestroy = destroyRef?.onDestroy(() => this.destroy());
@@ -8874,6 +8903,10 @@ class AfterRenderSequence {
8874
8903
  destroy() {
8875
8904
  this.impl.unregister(this);
8876
8905
  this.unregisterOnDestroy?.();
8906
+ const scheduled = this.view?.[AFTER_RENDER_SEQUENCES_TO_ADD];
8907
+ if (scheduled) {
8908
+ this.view[AFTER_RENDER_SEQUENCES_TO_ADD] = scheduled.filter((s) => s !== this);
8909
+ }
8877
8910
  }
8878
8911
  }
8879
8912
 
@@ -8924,7 +8957,8 @@ function afterRenderImpl(callbackOrSpec, injector, options, once) {
8924
8957
  const tracing = injector.get(TracingService, null, { optional: true });
8925
8958
  const hooks = options?.phase ?? AfterRenderPhase.MixedReadWrite;
8926
8959
  const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
8927
- const sequence = new AfterRenderSequence(manager.impl, getHooks(callbackOrSpec, hooks), once, destroyRef, tracing?.snapshot(null));
8960
+ const viewContext = injector.get(ViewContext, null, { optional: true });
8961
+ const sequence = new AfterRenderSequence(manager.impl, getHooks(callbackOrSpec, hooks), viewContext?.view, once, destroyRef, tracing?.snapshot(null));
8928
8962
  manager.impl.register(sequence);
8929
8963
  return sequence;
8930
8964
  }
@@ -9396,9 +9430,11 @@ function getTriggerElement(triggerLView, triggerIndex) {
9396
9430
  function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, registerFn, callback, type) {
9397
9431
  const injector = initialLView[INJECTOR];
9398
9432
  const zone = injector.get(NgZone);
9433
+ let poll;
9399
9434
  function pollDomTrigger() {
9400
9435
  // If the initial view was destroyed, we don't need to do anything.
9401
9436
  if (isDestroyed(initialLView)) {
9437
+ poll.destroy();
9402
9438
  return;
9403
9439
  }
9404
9440
  const lDetails = getLDeferBlockDetails(initialLView, tNode);
@@ -9406,14 +9442,16 @@ function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, regi
9406
9442
  // If the block was loaded before the trigger was resolved, we don't need to do anything.
9407
9443
  if (renderedState !== DeferBlockInternalState.Initial &&
9408
9444
  renderedState !== DeferBlockState.Placeholder) {
9445
+ poll.destroy();
9409
9446
  return;
9410
9447
  }
9411
9448
  const triggerLView = getTriggerLView(initialLView, tNode, walkUpTimes);
9412
9449
  // Keep polling until we resolve the trigger's LView.
9413
9450
  if (!triggerLView) {
9414
- afterNextRender({ read: pollDomTrigger }, { injector });
9451
+ // Keep polling.
9415
9452
  return;
9416
9453
  }
9454
+ poll.destroy();
9417
9455
  // It's possible that the trigger's view was destroyed before we resolved the trigger element.
9418
9456
  if (isDestroyed(triggerLView)) {
9419
9457
  return;
@@ -9440,7 +9478,7 @@ function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, regi
9440
9478
  storeTriggerCleanupFn(type, lDetails, cleanup);
9441
9479
  }
9442
9480
  // Begin polling for the trigger.
9443
- afterNextRender({ read: pollDomTrigger }, { injector });
9481
+ poll = afterRender({ read: pollDomTrigger }, { injector });
9444
9482
  }
9445
9483
 
9446
9484
  const DEFER_BLOCK_SSR_ID_ATTRIBUTE = 'ngb';
@@ -13205,7 +13243,7 @@ function detachViewFromDOM(tView, lView) {
13205
13243
  // When we remove a view from the DOM, we need to rerun afterRender hooks
13206
13244
  // We don't necessarily needs to run change detection. DOM removal only requires
13207
13245
  // change detection if animations are enabled (this notification is handled by animations).
13208
- lView[ENVIRONMENT].changeDetectionScheduler?.notify(10 /* NotificationSource.ViewDetachedFromDOM */);
13246
+ lView[ENVIRONMENT].changeDetectionScheduler?.notify(9 /* NotificationSource.ViewDetachedFromDOM */);
13209
13247
  applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
13210
13248
  }
13211
13249
  /**
@@ -14095,6 +14133,15 @@ function collectNativeNodesInLContainer(lContainer, result) {
14095
14133
  }
14096
14134
  }
14097
14135
 
14136
+ function addAfterRenderSequencesForView(lView) {
14137
+ if (lView[AFTER_RENDER_SEQUENCES_TO_ADD] !== null) {
14138
+ for (const sequence of lView[AFTER_RENDER_SEQUENCES_TO_ADD]) {
14139
+ sequence.impl.addSequence(sequence);
14140
+ }
14141
+ lView[AFTER_RENDER_SEQUENCES_TO_ADD].length = 0;
14142
+ }
14143
+ }
14144
+
14098
14145
  let freeConsumers = [];
14099
14146
  /**
14100
14147
  * Create a new template consumer pointing at the specified LView.
@@ -14440,6 +14487,7 @@ function refreshView(tView, lView, templateFn, context) {
14440
14487
  // no changes cycle, the component would be not be dirty for the next update pass. This would
14441
14488
  // be different in production mode where the component dirty state is not reset.
14442
14489
  if (!isInCheckNoChangesPass) {
14490
+ addAfterRenderSequencesForView(lView);
14443
14491
  lView[FLAGS] &= ~(64 /* LViewFlags.Dirty */ | 8 /* LViewFlags.FirstLViewPass */);
14444
14492
  }
14445
14493
  }
@@ -14557,12 +14605,17 @@ function detectChangesInView(lView, mode) {
14557
14605
  refreshView(tView, lView, tView.template, lView[CONTEXT]);
14558
14606
  }
14559
14607
  else if (flags & 8192 /* LViewFlags.HasChildViewsToRefresh */) {
14560
- runEffectsInView(lView);
14608
+ if (!isInCheckNoChangesPass) {
14609
+ runEffectsInView(lView);
14610
+ }
14561
14611
  detectChangesInEmbeddedViews(lView, 1 /* ChangeDetectionMode.Targeted */);
14562
14612
  const components = tView.components;
14563
14613
  if (components !== null) {
14564
14614
  detectChangesInChildComponents(lView, components, 1 /* ChangeDetectionMode.Targeted */);
14565
14615
  }
14616
+ if (!isInCheckNoChangesPass) {
14617
+ addAfterRenderSequencesForView(lView);
14618
+ }
14566
14619
  }
14567
14620
  }
14568
14621
  /** Refreshes child components in the current view (update mode). */
@@ -17967,7 +18020,7 @@ class ComponentFactory extends ComponentFactory$1 {
17967
18020
  const cmpDef = this.componentDef;
17968
18021
  ngDevMode && verifyNotAnOrphanComponent(cmpDef);
17969
18022
  const tAttributes = rootSelectorOrNode
17970
- ? ['ng-version', '19.2.0-next.2']
18023
+ ? ['ng-version', '19.2.0-next.3']
17971
18024
  : // Extract attributes and classes from the first selector only to match VE behavior.
17972
18025
  extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
17973
18026
  // Create the root view. Uses empty TView and ContentTemplate.
@@ -23415,12 +23468,6 @@ class ApplicationRef {
23415
23468
  * @internal
23416
23469
  */
23417
23470
  dirtyFlags = 0 /* ApplicationRefDirtyFlags.None */;
23418
- /**
23419
- * Like `dirtyFlags` but don't cause `tick()` to loop.
23420
- *
23421
- * @internal
23422
- */
23423
- deferredDirtyFlags = 0 /* ApplicationRefDirtyFlags.None */;
23424
23471
  /**
23425
23472
  * Most recent snapshot from the `TracingService`, if any.
23426
23473
  *
@@ -23634,9 +23681,6 @@ class ApplicationRef {
23634
23681
  if (this._rendererFactory === null && !this._injector.destroyed) {
23635
23682
  this._rendererFactory = this._injector.get(RendererFactory2, null, { optional: true });
23636
23683
  }
23637
- // When beginning synchronization, all deferred dirtiness becomes active dirtiness.
23638
- this.dirtyFlags |= this.deferredDirtyFlags;
23639
- this.deferredDirtyFlags = 0 /* ApplicationRefDirtyFlags.None */;
23640
23684
  let runs = 0;
23641
23685
  while (this.dirtyFlags !== 0 /* ApplicationRefDirtyFlags.None */ && runs++ < MAXIMUM_REFRESH_RERUNS) {
23642
23686
  profiler(14 /* ProfilerEvent.ChangeDetectionSyncStart */);
@@ -23654,9 +23698,6 @@ class ApplicationRef {
23654
23698
  * Perform a single synchronization pass.
23655
23699
  */
23656
23700
  synchronizeOnce() {
23657
- // If we happened to loop, deferred dirtiness can be processed as active dirtiness again.
23658
- this.dirtyFlags |= this.deferredDirtyFlags;
23659
- this.deferredDirtyFlags = 0 /* ApplicationRefDirtyFlags.None */;
23660
23701
  // First, process any dirty root effects.
23661
23702
  if (this.dirtyFlags & 16 /* ApplicationRefDirtyFlags.RootEffects */) {
23662
23703
  this.dirtyFlags &= ~16 /* ApplicationRefDirtyFlags.RootEffects */;
@@ -33333,9 +33374,13 @@ function ɵsetClassDebugInfo(type, debugInfo) {
33333
33374
  * @param applyMetadata Callback that will apply a new set of metadata on the `type` when invoked.
33334
33375
  * @param environment Syntehtic namespace imports that need to be passed along to the callback.
33335
33376
  * @param locals Local symbols from the source location that have to be exposed to the callback.
33377
+ * @param importMeta `import.meta` from the call site of the replacement function. Optional since
33378
+ * it isn't used internally.
33379
+ * @param id ID to the class being replaced. **Not** the same as the component definition ID.
33380
+ * Optional since the ID might not be available internally.
33336
33381
  * @codeGenApi
33337
33382
  */
33338
- function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals) {
33383
+ function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals, importMeta = null, id = null) {
33339
33384
  ngDevMode && assertComponentDef(type);
33340
33385
  const currentDef = getComponentDef(type);
33341
33386
  // The reason `applyMetadata` is a callback that is invoked (almost) immediately is because
@@ -33357,7 +33402,7 @@ function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals) {
33357
33402
  // Note: we have the additional check, because `IsRoot` can also indicate
33358
33403
  // a component created through something like `createComponent`.
33359
33404
  if (isRootView(root) && root[PARENT] === null) {
33360
- recreateMatchingLViews(newDef, oldDef, root);
33405
+ recreateMatchingLViews(importMeta, id, newDef, oldDef, root);
33361
33406
  }
33362
33407
  }
33363
33408
  }
@@ -33393,10 +33438,12 @@ function mergeWithExistingDefinition(currentDef, newDef) {
33393
33438
  }
33394
33439
  /**
33395
33440
  * Finds all LViews matching a specific component definition and recreates them.
33441
+ * @param importMeta `import.meta` information.
33442
+ * @param id HMR ID of the component.
33396
33443
  * @param oldDef Component definition to search for.
33397
33444
  * @param rootLView View from which to start the search.
33398
33445
  */
33399
- function recreateMatchingLViews(newDef, oldDef, rootLView) {
33446
+ function recreateMatchingLViews(importMeta, id, newDef, oldDef, rootLView) {
33400
33447
  ngDevMode &&
33401
33448
  assertDefined(oldDef.tView, 'Expected a component definition that has been instantiated at least once');
33402
33449
  const tView = rootLView[TVIEW];
@@ -33404,7 +33451,7 @@ function recreateMatchingLViews(newDef, oldDef, rootLView) {
33404
33451
  // produce false positives when using inheritance.
33405
33452
  if (tView === oldDef.tView) {
33406
33453
  ngDevMode && assertComponentDef(oldDef.type);
33407
- recreateLView(newDef, oldDef, rootLView);
33454
+ recreateLView(importMeta, id, newDef, oldDef, rootLView);
33408
33455
  return;
33409
33456
  }
33410
33457
  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
@@ -33412,14 +33459,14 @@ function recreateMatchingLViews(newDef, oldDef, rootLView) {
33412
33459
  if (isLContainer(current)) {
33413
33460
  // The host can be an LView if a component is injecting `ViewContainerRef`.
33414
33461
  if (isLView(current[HOST])) {
33415
- recreateMatchingLViews(newDef, oldDef, current[HOST]);
33462
+ recreateMatchingLViews(importMeta, id, newDef, oldDef, current[HOST]);
33416
33463
  }
33417
33464
  for (let j = CONTAINER_HEADER_OFFSET; j < current.length; j++) {
33418
- recreateMatchingLViews(newDef, oldDef, current[j]);
33465
+ recreateMatchingLViews(importMeta, id, newDef, oldDef, current[j]);
33419
33466
  }
33420
33467
  }
33421
33468
  else if (isLView(current)) {
33422
- recreateMatchingLViews(newDef, oldDef, current);
33469
+ recreateMatchingLViews(importMeta, id, newDef, oldDef, current);
33423
33470
  }
33424
33471
  }
33425
33472
  }
@@ -33438,11 +33485,13 @@ function clearRendererCache(factory, def) {
33438
33485
  }
33439
33486
  /**
33440
33487
  * Recreates an LView in-place from a new component definition.
33488
+ * @param importMeta `import.meta` information.
33489
+ * @param id HMR ID for the component.
33441
33490
  * @param newDef Definition from which to recreate the view.
33442
33491
  * @param oldDef Previous component definition being swapped out.
33443
33492
  * @param lView View to be recreated.
33444
33493
  */
33445
- function recreateLView(newDef, oldDef, lView) {
33494
+ function recreateLView(importMeta, id, newDef, oldDef, lView) {
33446
33495
  const instance = lView[CONTEXT];
33447
33496
  let host = lView[HOST];
33448
33497
  // In theory the parent can also be an LContainer, but it appears like that's
@@ -33494,10 +33543,29 @@ function recreateLView(newDef, oldDef, lView) {
33494
33543
  };
33495
33544
  // The callback isn't guaranteed to be inside the Zone so we need to bring it in ourselves.
33496
33545
  if (zone === null) {
33497
- recreate();
33546
+ executeWithInvalidateFallback(importMeta, id, recreate);
33498
33547
  }
33499
33548
  else {
33500
- zone.run(recreate);
33549
+ zone.run(() => executeWithInvalidateFallback(importMeta, id, recreate));
33550
+ }
33551
+ }
33552
+ /**
33553
+ * Runs an HMR-related function and falls back to
33554
+ * invalidating the HMR data if it throws an error.
33555
+ */
33556
+ function executeWithInvalidateFallback(importMeta, id, callback) {
33557
+ try {
33558
+ callback();
33559
+ }
33560
+ catch (e) {
33561
+ const errorMessage = e.message;
33562
+ // If we have all the necessary information and APIs to send off the invalidation
33563
+ // request, send it before rethrowing so the dev server can decide what to do.
33564
+ if (id !== null && errorMessage) {
33565
+ importMeta?.hot?.send?.('angular:invalidate', { id, message: errorMessage, error: true });
33566
+ }
33567
+ // Throw the error in case the page doesn't get refreshed.
33568
+ throw e;
33501
33569
  }
33502
33570
  }
33503
33571
  /**
@@ -34925,7 +34993,7 @@ class Version {
34925
34993
  /**
34926
34994
  * @publicApi
34927
34995
  */
34928
- const VERSION = new Version('19.2.0-next.2');
34996
+ const VERSION = new Version('19.2.0-next.3');
34929
34997
 
34930
34998
  /**
34931
34999
  * Combination of NgModuleFactory and ComponentFactories.
@@ -35335,13 +35403,6 @@ class ChangeDetectionSchedulerImpl {
35335
35403
  this.appRef.dirtyFlags |= 4 /* ApplicationRefDirtyFlags.ViewTreeCheck */;
35336
35404
  break;
35337
35405
  }
35338
- case 8 /* NotificationSource.DeferredRenderHook */: {
35339
- // Render hooks are "deferred" when they're triggered from other render hooks. Using the
35340
- // deferred dirty flags ensures that adding new hooks doesn't automatically trigger a loop
35341
- // inside tick().
35342
- this.appRef.deferredDirtyFlags |= 8 /* ApplicationRefDirtyFlags.AfterRender */;
35343
- break;
35344
- }
35345
35406
  case 6 /* NotificationSource.CustomElement */: {
35346
35407
  // We use `ViewTreeTraversal` to ensure we refresh the element even if this is triggered
35347
35408
  // during CD. In practice this is a no-op since the elements code also calls via a
@@ -35350,7 +35411,7 @@ class ChangeDetectionSchedulerImpl {
35350
35411
  force = true;
35351
35412
  break;
35352
35413
  }
35353
- case 13 /* NotificationSource.RootEffect */: {
35414
+ case 12 /* NotificationSource.RootEffect */: {
35354
35415
  this.appRef.dirtyFlags |= 16 /* ApplicationRefDirtyFlags.RootEffects */;
35355
35416
  // Root effects still force a CD, even if the scheduler is disabled. This ensures that
35356
35417
  // effects always run, even when triggered from outside the zone when the scheduler is
@@ -35358,7 +35419,7 @@ class ChangeDetectionSchedulerImpl {
35358
35419
  force = true;
35359
35420
  break;
35360
35421
  }
35361
- case 14 /* NotificationSource.ViewEffect */: {
35422
+ case 13 /* NotificationSource.ViewEffect */: {
35362
35423
  // This is technically a no-op, since view effects will also send a
35363
35424
  // `MarkAncestorsForTraversal` notification. Still, we set this for logical consistency.
35364
35425
  this.appRef.dirtyFlags |= 2 /* ApplicationRefDirtyFlags.ViewTreeTraversal */;
@@ -35368,7 +35429,7 @@ class ChangeDetectionSchedulerImpl {
35368
35429
  force = true;
35369
35430
  break;
35370
35431
  }
35371
- case 12 /* NotificationSource.PendingTaskRemoved */: {
35432
+ case 11 /* NotificationSource.PendingTaskRemoved */: {
35372
35433
  // Removing a pending task via the public API forces a scheduled tick, ensuring that
35373
35434
  // stability is async and delayed until there was at least an opportunity to run
35374
35435
  // application synchronization. This prevents some footguns when working with the
@@ -35377,10 +35438,10 @@ class ChangeDetectionSchedulerImpl {
35377
35438
  force = true;
35378
35439
  break;
35379
35440
  }
35380
- case 10 /* NotificationSource.ViewDetachedFromDOM */:
35381
- case 9 /* NotificationSource.ViewAttached */:
35441
+ case 9 /* NotificationSource.ViewDetachedFromDOM */:
35442
+ case 8 /* NotificationSource.ViewAttached */:
35382
35443
  case 7 /* NotificationSource.RenderHook */:
35383
- case 11 /* NotificationSource.AsyncAnimationsLoaded */:
35444
+ case 10 /* NotificationSource.AsyncAnimationsLoaded */:
35384
35445
  default: {
35385
35446
  // These notifications only schedule a tick but do not change whether we should refresh
35386
35447
  // views. Instead, we only need to run render hooks unless another notification from the
@@ -40589,23 +40650,6 @@ function untracked(nonReactiveReadsFn) {
40589
40650
  }
40590
40651
  }
40591
40652
 
40592
- class ViewContext {
40593
- view;
40594
- node;
40595
- constructor(view, node) {
40596
- this.view = view;
40597
- this.node = node;
40598
- }
40599
- /**
40600
- * @internal
40601
- * @nocollapse
40602
- */
40603
- static __NG_ELEMENT_ID__ = injectViewContext;
40604
- }
40605
- function injectViewContext() {
40606
- return new ViewContext(getLView(), getCurrentTNode());
40607
- }
40608
-
40609
40653
  /**
40610
40654
  * Controls whether effects use the legacy `microtaskEffect` by default.
40611
40655
  */
@@ -40873,7 +40917,7 @@ const ROOT_EFFECT_NODE =
40873
40917
  ...BASE_EFFECT_NODE,
40874
40918
  consumerMarkedDirty() {
40875
40919
  this.scheduler.schedule(this);
40876
- this.notifier.notify(13 /* NotificationSource.RootEffect */);
40920
+ this.notifier.notify(12 /* NotificationSource.RootEffect */);
40877
40921
  },
40878
40922
  destroy() {
40879
40923
  consumerDestroy$1(this);
@@ -40888,7 +40932,7 @@ const VIEW_EFFECT_NODE =
40888
40932
  consumerMarkedDirty() {
40889
40933
  this.view[FLAGS] |= 8192 /* LViewFlags.HasChildViewsToRefresh */;
40890
40934
  markAncestorsForTraversal(this.view);
40891
- this.notifier.notify(14 /* NotificationSource.ViewEffect */);
40935
+ this.notifier.notify(13 /* NotificationSource.ViewEffect */);
40892
40936
  },
40893
40937
  destroy() {
40894
40938
  consumerDestroy$1(this);
@@ -40915,7 +40959,7 @@ function createRootEffect(fn, scheduler, notifier) {
40915
40959
  node.notifier = notifier;
40916
40960
  node.zone = typeof Zone !== 'undefined' ? Zone.current : null;
40917
40961
  node.scheduler.schedule(node);
40918
- node.notifier.notify(13 /* NotificationSource.RootEffect */);
40962
+ node.notifier.notify(12 /* NotificationSource.RootEffect */);
40919
40963
  return node;
40920
40964
  }
40921
40965
 
@@ -41006,10 +41050,10 @@ class AfterRenderEffectSequence extends AfterRenderSequence {
41006
41050
  * These are initialized to `undefined` but set in the constructor.
41007
41051
  */
41008
41052
  nodes = [undefined, undefined, undefined, undefined];
41009
- constructor(impl, effectHooks, scheduler, destroyRef, snapshot = null) {
41053
+ constructor(impl, effectHooks, view, scheduler, destroyRef, snapshot = null) {
41010
41054
  // Note that we also initialize the underlying `AfterRenderSequence` hooks to `undefined` and
41011
41055
  // populate them as we create reactive nodes below.
41012
- super(impl, [undefined, undefined, undefined, undefined], false, destroyRef, snapshot);
41056
+ super(impl, [undefined, undefined, undefined, undefined], view, false, destroyRef, snapshot);
41013
41057
  this.scheduler = scheduler;
41014
41058
  // Setup a reactive node for each phase.
41015
41059
  for (const phase of AFTER_RENDER_PHASES) {
@@ -41068,7 +41112,8 @@ function afterRenderEffect(callbackOrSpec, options) {
41068
41112
  if (typeof spec === 'function') {
41069
41113
  spec = { mixedReadWrite: callbackOrSpec };
41070
41114
  }
41071
- const sequence = new AfterRenderEffectSequence(manager.impl, [spec.earlyRead, spec.write, spec.mixedReadWrite, spec.read], scheduler, injector.get(DestroyRef), tracing?.snapshot(null));
41115
+ const viewContext = injector.get(ViewContext, null, { optional: true });
41116
+ const sequence = new AfterRenderEffectSequence(manager.impl, [spec.earlyRead, spec.write, spec.mixedReadWrite, spec.read], viewContext?.view, scheduler, injector.get(DestroyRef), tracing?.snapshot(null));
41072
41117
  manager.impl.register(sequence);
41073
41118
  return sequence;
41074
41119
  }