@angular/core 17.3.0-next.0 → 17.3.0-rc.0

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 (64) hide show
  1. package/esm2022/rxjs-interop/src/index.mjs +3 -1
  2. package/esm2022/rxjs-interop/src/output_from_observable.mjs +68 -0
  3. package/esm2022/rxjs-interop/src/output_to_observable.mjs +29 -0
  4. package/esm2022/rxjs-interop/src/to_observable.mjs +1 -1
  5. package/esm2022/src/application/application_ref.mjs +66 -40
  6. package/esm2022/src/authoring/input/input_type_checking.mjs +1 -1
  7. package/esm2022/src/authoring/model/model.mjs +4 -1
  8. package/esm2022/src/authoring/model/model_signal.mjs +9 -18
  9. package/esm2022/src/authoring/output/output.mjs +35 -0
  10. package/esm2022/src/authoring/output/output_emitter_ref.mjs +74 -0
  11. package/esm2022/src/authoring/output/output_ref.mjs +9 -0
  12. package/esm2022/src/authoring.mjs +3 -2
  13. package/esm2022/src/cached_injector_service.mjs +49 -0
  14. package/esm2022/src/core_private_export.mjs +4 -2
  15. package/esm2022/src/defer/instructions.mjs +29 -3
  16. package/esm2022/src/defer/interfaces.mjs +1 -1
  17. package/esm2022/src/di/host_attribute_token.mjs +40 -0
  18. package/esm2022/src/di/index.mjs +2 -1
  19. package/esm2022/src/di/injector_compatibility.mjs +3 -1
  20. package/esm2022/src/di/interface/provider.mjs +1 -1
  21. package/esm2022/src/di/metadata.mjs +1 -1
  22. package/esm2022/src/di/r3_injector.mjs +26 -15
  23. package/esm2022/src/errors.mjs +1 -1
  24. package/esm2022/src/event_emitter.mjs +19 -2
  25. package/esm2022/src/hydration/api.mjs +2 -2
  26. package/esm2022/src/is_internal.mjs +15 -0
  27. package/esm2022/src/render3/after_render_hooks.mjs +9 -6
  28. package/esm2022/src/render3/component_ref.mjs +103 -93
  29. package/esm2022/src/render3/instructions/listener.mjs +7 -9
  30. package/esm2022/src/render3/instructions/render.mjs +3 -2
  31. package/esm2022/src/render3/interfaces/view.mjs +1 -1
  32. package/esm2022/src/render3/node_manipulation.mjs +13 -4
  33. package/esm2022/src/render3/queue_state_update.mjs +41 -0
  34. package/esm2022/src/render3/reactivity/computed.mjs +3 -1
  35. package/esm2022/src/render3/reactivity/effect.mjs +13 -7
  36. package/esm2022/src/render3/reactivity/signal.mjs +5 -4
  37. package/esm2022/src/render3/view_manipulation.mjs +24 -17
  38. package/esm2022/src/util/assert.mjs +7 -1
  39. package/esm2022/src/version.mjs +1 -1
  40. package/esm2022/testing/src/component_fixture.mjs +78 -19
  41. package/esm2022/testing/src/logger.mjs +3 -3
  42. package/esm2022/testing/src/test_bed_compiler.mjs +26 -4
  43. package/fesm2022/core.mjs +13346 -13065
  44. package/fesm2022/core.mjs.map +1 -1
  45. package/fesm2022/primitives/signals.mjs +1 -1
  46. package/fesm2022/rxjs-interop.mjs +82 -3
  47. package/fesm2022/rxjs-interop.mjs.map +1 -1
  48. package/fesm2022/testing.mjs +102 -21
  49. package/fesm2022/testing.mjs.map +1 -1
  50. package/index.d.ts +219 -78
  51. package/package.json +1 -1
  52. package/primitives/signals/index.d.ts +1 -1
  53. package/rxjs-interop/index.d.ts +39 -1
  54. package/schematics/migrations/block-template-entities/bundle.js +19 -34
  55. package/schematics/migrations/block-template-entities/bundle.js.map +3 -3
  56. package/schematics/migrations/invalid-two-way-bindings/bundle.js +26381 -0
  57. package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +7 -0
  58. package/schematics/migrations.json +5 -0
  59. package/schematics/ng-generate/control-flow-migration/bundle.js +21 -36
  60. package/schematics/ng-generate/control-flow-migration/bundle.js.map +3 -3
  61. package/schematics/ng-generate/standalone-migration/bundle.js +6201 -3670
  62. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  63. package/testing/index.d.ts +1 -1
  64. package/esm2022/src/authoring/output.mjs +0 -33
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v17.3.0-next.0
2
+ * @license Angular v17.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v17.3.0-next.0
2
+ * @license Angular v17.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { assertInInjectionContext, inject, DestroyRef, Injector, effect, untracked, assertNotInReactiveContext, signal, ɵRuntimeError, computed } from '@angular/core';
7
+ import { assertInInjectionContext, inject, DestroyRef, ɵRuntimeError, ɵgetOutputDestroyRef, Injector, effect, untracked, assertNotInReactiveContext, signal, computed } from '@angular/core';
8
8
  import { Observable, ReplaySubject } from 'rxjs';
9
9
  import { takeUntil } from 'rxjs/operators';
10
10
 
@@ -32,6 +32,85 @@ function takeUntilDestroyed(destroyRef) {
32
32
  };
33
33
  }
34
34
 
35
+ /**
36
+ * Implementation of `OutputRef` that emits values from
37
+ * an RxJS observable source.
38
+ *
39
+ * @internal
40
+ */
41
+ class OutputFromObservableRef {
42
+ constructor(source) {
43
+ this.source = source;
44
+ this.destroyed = false;
45
+ this.destroyRef = inject(DestroyRef);
46
+ this.destroyRef.onDestroy(() => {
47
+ this.destroyed = true;
48
+ });
49
+ }
50
+ subscribe(callbackFn) {
51
+ if (this.destroyed) {
52
+ throw new ɵRuntimeError(953 /* ɵRuntimeErrorCode.OUTPUT_REF_DESTROYED */, ngDevMode &&
53
+ 'Unexpected subscription to destroyed `OutputRef`. ' +
54
+ 'The owning directive/component is destroyed.');
55
+ }
56
+ // Stop yielding more values when the directive/component is already destroyed.
57
+ const subscription = this.source.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
58
+ next: value => callbackFn(value),
59
+ });
60
+ return {
61
+ unsubscribe: () => subscription.unsubscribe(),
62
+ };
63
+ }
64
+ }
65
+ /**
66
+ * Declares an Angular output that is using an RxJS observable as a source
67
+ * for events dispatched to parent subscribers.
68
+ *
69
+ * The behavior for an observable as source is defined as followed:
70
+ * 1. New values are forwarded to the Angular output (next notifications).
71
+ * 2. Errors notifications are not handled by Angular. You need to handle these manually.
72
+ * For example by using `catchError`.
73
+ * 3. Completion notifications stop the output from emitting new values.
74
+ *
75
+ * @usageNotes
76
+ * Initialize an output in your directive by declaring a
77
+ * class field and initializing it with the `outputFromObservable()` function.
78
+ *
79
+ * ```ts
80
+ * @Directive({..})
81
+ * export class MyDir {
82
+ * nameChange$ = <some-observable>;
83
+ * nameChange = outputFromObservable(this.nameChange$);
84
+ * }
85
+ * ```
86
+ *
87
+ * @developerPreview
88
+ */
89
+ function outputFromObservable(observable, opts) {
90
+ ngDevMode && assertInInjectionContext(outputFromObservable);
91
+ return new OutputFromObservableRef(observable);
92
+ }
93
+
94
+ /**
95
+ * Converts an Angular output declared via `output()` or `outputFromObservable()`
96
+ * to an observable.
97
+ *
98
+ * You can subscribe to the output via `Observable.subscribe` then.
99
+ *
100
+ * @developerPreview
101
+ */
102
+ function outputToObservable(ref) {
103
+ const destroyRef = ɵgetOutputDestroyRef(ref);
104
+ return new Observable(observer => {
105
+ // Complete the observable upon directive/component destroy.
106
+ // Note: May be `undefined` if an `EventEmitter` is declared outside
107
+ // of an injection context.
108
+ destroyRef?.onDestroy(() => observer.complete());
109
+ const subscription = ref.subscribe(v => observer.next(v));
110
+ return () => subscription.unsubscribe();
111
+ });
112
+ }
113
+
35
114
  /**
36
115
  * Exposes the value of an Angular `Signal` as an RxJS `Observable`.
37
116
  *
@@ -150,5 +229,5 @@ function toSignal(source, options) {
150
229
  * Generated bundle index. Do not edit.
151
230
  */
152
231
 
153
- export { takeUntilDestroyed, toObservable, toSignal };
232
+ export { outputFromObservable, outputToObservable, takeUntilDestroyed, toObservable, toSignal };
154
233
  //# sourceMappingURL=rxjs-interop.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rxjs-interop.mjs","sources":["../../../../../../packages/core/rxjs-interop/src/take_until_destroyed.ts","../../../../../../packages/core/rxjs-interop/src/to_observable.ts","../../../../../../packages/core/rxjs-interop/src/to_signal.ts","../../../../../../packages/core/rxjs-interop/rxjs-interop.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, DestroyRef, inject} from '@angular/core';\nimport {MonoTypeOperatorFunction, Observable} from 'rxjs';\nimport {takeUntil} from 'rxjs/operators';\n\n/**\n * Operator which completes the Observable when the calling context (component, directive, service,\n * etc) is destroyed.\n *\n * @param destroyRef optionally, the `DestroyRef` representing the current context. This can be\n * passed explicitly to use `takeUntilDestroyed` outside of an [injection\n * context](guide/dependency-injection-context). Otherwise, the current `DestroyRef` is injected.\n *\n * @developerPreview\n */\nexport function takeUntilDestroyed<T>(destroyRef?: DestroyRef): MonoTypeOperatorFunction<T> {\n if (!destroyRef) {\n assertInInjectionContext(takeUntilDestroyed);\n destroyRef = inject(DestroyRef);\n }\n\n const destroyed$ = new Observable<void>(observer => {\n const unregisterFn = destroyRef!.onDestroy(observer.next.bind(observer));\n return unregisterFn;\n });\n\n return <T>(source: Observable<T>) => {\n return source.pipe(takeUntil(destroyed$));\n };\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, DestroyRef, effect, EffectRef, inject, Injector, Signal, untracked} from '@angular/core';\nimport {Observable, ReplaySubject} from 'rxjs';\n\n/**\n * Options for `toObservable`.\n *\n * @developerPreview\n */\nexport interface ToObservableOptions {\n /**\n * The `Injector` to use when creating the underlying `effect` which watches the signal.\n *\n * If this isn't specified, the current [injection context](guide/dependency-injection-context)\n * will be used.\n */\n injector?: Injector;\n}\n\n/**\n * Exposes the value of an Angular `Signal` as an RxJS `Observable`.\n *\n * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.\n *\n * `toObservable` must be called in an injection context unless an injector is provided via options.\n *\n * @developerPreview\n */\nexport function toObservable<T>(\n source: Signal<T>,\n options?: ToObservableOptions,\n ): Observable<T> {\n !options?.injector && assertInInjectionContext(toObservable);\n const injector = options?.injector ?? inject(Injector);\n const subject = new ReplaySubject<T>(1);\n\n const watcher = effect(() => {\n let value: T;\n try {\n value = source();\n } catch (err) {\n untracked(() => subject.error(err));\n return;\n }\n untracked(() => subject.next(value));\n }, {injector, manualCleanup: true});\n\n injector.get(DestroyRef).onDestroy(() => {\n watcher.destroy();\n subject.complete();\n });\n\n return subject.asObservable();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, assertNotInReactiveContext, computed, DestroyRef, inject, Injector, signal, Signal, WritableSignal, ɵRuntimeError, ɵRuntimeErrorCode} from '@angular/core';\nimport {Observable, Subscribable} from 'rxjs';\n\n/**\n * Options for `toSignal`.\n *\n * @publicApi\n */\nexport interface ToSignalOptions {\n /**\n * Initial value for the signal produced by `toSignal`.\n *\n * This will be the value of the signal until the observable emits its first value.\n */\n initialValue?: unknown;\n\n /**\n * Whether to require that the observable emits synchronously when `toSignal` subscribes.\n *\n * If this is `true`, `toSignal` will assert that the observable produces a value immediately upon\n * subscription. Setting this option removes the need to either deal with `undefined` in the\n * signal type or provide an `initialValue`, at the cost of a runtime error if this requirement is\n * not met.\n */\n requireSync?: boolean;\n\n /**\n * `Injector` which will provide the `DestroyRef` used to clean up the Observable subscription.\n *\n * If this is not provided, a `DestroyRef` will be retrieved from the current [injection\n * context](/guide/dependency-injection-context), unless manual cleanup is requested.\n */\n injector?: Injector;\n\n /**\n * Whether the subscription should be automatically cleaned up (via `DestroyRef`) when\n * `toObservable`'s creation context is destroyed.\n *\n * If manual cleanup is enabled, then `DestroyRef` is not used, and the subscription will persist\n * until the `Observable` itself completes.\n */\n manualCleanup?: boolean;\n\n /**\n * Whether `toSignal` should throw errors from the Observable error channel back to RxJS, where\n * they'll be processed as uncaught exceptions.\n *\n * In practice, this means that the signal returned by `toSignal` will keep returning the last\n * good value forever, as Observables which error produce no further values. This option emulates\n * the behavior of the `async` pipe.\n */\n rejectErrors?: boolean;\n}\n\n// Base case: no options -> `undefined` in the result type.\nexport function toSignal<T>(source: Observable<T>|Subscribable<T>): Signal<T|undefined>;\n// Options with `undefined` initial value and no `requiredSync` -> `undefined`.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: undefined, requireSync?: false}): Signal<T|undefined>;\n// Options with `null` initial value -> `null`.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: null, requireSync?: false}): Signal<T|null>;\n// Options with `undefined` initial value and `requiredSync` -> strict result type.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: undefined, requireSync: true}): Signal<T>;\n// Options with a more specific initial value type.\nexport function toSignal<T, const U extends T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue: U, requireSync?: false}): Signal<T|U>;\n\n/**\n * Get the current value of an `Observable` as a reactive `Signal`.\n *\n * `toSignal` returns a `Signal` which provides synchronous reactive access to values produced\n * by the given `Observable`, by subscribing to that `Observable`. The returned `Signal` will always\n * have the most recent value emitted by the subscription, and will throw an error if the\n * `Observable` errors.\n *\n * With `requireSync` set to `true`, `toSignal` will assert that the `Observable` produces a value\n * immediately upon subscription. No `initialValue` is needed in this case, and the returned signal\n * does not include an `undefined` type.\n *\n * By default, the subscription will be automatically cleaned up when the current [injection\n * context](/guide/dependency-injection-context) is destroyed. For example, when `toObservable` is\n * called during the construction of a component, the subscription will be cleaned up when the\n * component is destroyed. If an injection context is not available, an explicit `Injector` can be\n * passed instead.\n *\n * If the subscription should persist until the `Observable` itself completes, the `manualCleanup`\n * option can be specified instead, which disables the automatic subscription teardown. No injection\n * context is needed in this configuration as well.\n *\n * @developerPreview\n */\nexport function toSignal<T, U = undefined>(\n source: Observable<T>|Subscribable<T>,\n options?: ToSignalOptions&{initialValue?: U}): Signal<T|U> {\n ngDevMode &&\n assertNotInReactiveContext(\n toSignal,\n 'Invoking `toSignal` causes new subscriptions every time. ' +\n 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');\n\n const requiresCleanup = !options?.manualCleanup;\n requiresCleanup && !options?.injector && assertInInjectionContext(toSignal);\n const cleanupRef =\n requiresCleanup ? options?.injector?.get(DestroyRef) ?? inject(DestroyRef) : null;\n\n // Note: T is the Observable value type, and U is the initial value type. They don't have to be\n // the same - the returned signal gives values of type `T`.\n let state: WritableSignal<State<T|U>>;\n if (options?.requireSync) {\n // Initially the signal is in a `NoValue` state.\n state = signal({kind: StateKind.NoValue});\n } else {\n // If an initial value was passed, use it. Otherwise, use `undefined` as the initial value.\n state = signal<State<T|U>>({kind: StateKind.Value, value: options?.initialValue as U});\n }\n\n // Note: This code cannot run inside a reactive context (see assertion above). If we'd support\n // this, we would subscribe to the observable outside of the current reactive context, avoiding\n // that side-effect signal reads/writes are attribute to the current consumer. The current\n // consumer only needs to be notified when the `state` signal changes through the observable\n // subscription. Additional context (related to async pipe):\n // https://github.com/angular/angular/pull/50522.\n const sub = source.subscribe({\n next: value => state.set({kind: StateKind.Value, value}),\n error: error => {\n if (options?.rejectErrors) {\n // Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes\n // the error to end up as an uncaught exception.\n throw error;\n }\n state.set({kind: StateKind.Error, error});\n },\n // Completion of the Observable is meaningless to the signal. Signals don't have a concept of\n // \"complete\".\n });\n\n if (ngDevMode && options?.requireSync && state().kind === StateKind.NoValue) {\n throw new ɵRuntimeError(\n ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT,\n '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');\n }\n\n // Unsubscribe when the current context is destroyed, if requested.\n cleanupRef?.onDestroy(sub.unsubscribe.bind(sub));\n\n // The actual returned signal is a `computed` of the `State` signal, which maps the various states\n // to either values or errors.\n return computed(() => {\n const current = state();\n switch (current.kind) {\n case StateKind.Value:\n return current.value;\n case StateKind.Error:\n throw current.error;\n case StateKind.NoValue:\n // This shouldn't really happen because the error is thrown on creation.\n // TODO(alxhub): use a RuntimeError when we finalize the error semantics\n throw new ɵRuntimeError(\n ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT,\n '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');\n }\n });\n}\n\nconst enum StateKind {\n NoValue,\n Value,\n Error,\n}\n\ninterface NoValueState {\n kind: StateKind.NoValue;\n}\n\ninterface ValueState<T> {\n kind: StateKind.Value;\n value: T;\n}\n\ninterface ErrorState {\n kind: StateKind.Error;\n error: unknown;\n}\n\ntype State<T> = NoValueState|ValueState<T>|ErrorState;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rxjs-interop.mjs","sources":["../../../../../../packages/core/rxjs-interop/src/take_until_destroyed.ts","../../../../../../packages/core/rxjs-interop/src/output_from_observable.ts","../../../../../../packages/core/rxjs-interop/src/output_to_observable.ts","../../../../../../packages/core/rxjs-interop/src/to_observable.ts","../../../../../../packages/core/rxjs-interop/src/to_signal.ts","../../../../../../packages/core/rxjs-interop/rxjs-interop.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, DestroyRef, inject} from '@angular/core';\nimport {MonoTypeOperatorFunction, Observable} from 'rxjs';\nimport {takeUntil} from 'rxjs/operators';\n\n/**\n * Operator which completes the Observable when the calling context (component, directive, service,\n * etc) is destroyed.\n *\n * @param destroyRef optionally, the `DestroyRef` representing the current context. This can be\n * passed explicitly to use `takeUntilDestroyed` outside of an [injection\n * context](guide/dependency-injection-context). Otherwise, the current `DestroyRef` is injected.\n *\n * @developerPreview\n */\nexport function takeUntilDestroyed<T>(destroyRef?: DestroyRef): MonoTypeOperatorFunction<T> {\n if (!destroyRef) {\n assertInInjectionContext(takeUntilDestroyed);\n destroyRef = inject(DestroyRef);\n }\n\n const destroyed$ = new Observable<void>(observer => {\n const unregisterFn = destroyRef!.onDestroy(observer.next.bind(observer));\n return unregisterFn;\n });\n\n return <T>(source: Observable<T>) => {\n return source.pipe(takeUntil(destroyed$));\n };\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, DestroyRef, inject, OutputOptions, OutputRef, OutputRefSubscription, ɵRuntimeError, ɵRuntimeErrorCode} from '@angular/core';\nimport {Observable} from 'rxjs';\n\nimport {takeUntilDestroyed} from './take_until_destroyed';\n\n/**\n * Implementation of `OutputRef` that emits values from\n * an RxJS observable source.\n *\n * @internal\n */\nclass OutputFromObservableRef<T> implements OutputRef<T> {\n private destroyed = false;\n\n destroyRef = inject(DestroyRef);\n\n constructor(private source: Observable<T>) {\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n });\n }\n\n subscribe(callbackFn: (value: T) => void): OutputRefSubscription {\n if (this.destroyed) {\n throw new ɵRuntimeError(\n ɵRuntimeErrorCode.OUTPUT_REF_DESTROYED,\n ngDevMode &&\n 'Unexpected subscription to destroyed `OutputRef`. ' +\n 'The owning directive/component is destroyed.');\n }\n\n // Stop yielding more values when the directive/component is already destroyed.\n const subscription = this.source.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({\n next: value => callbackFn(value),\n });\n\n return {\n unsubscribe: () => subscription.unsubscribe(),\n };\n }\n}\n\n/**\n * Declares an Angular output that is using an RxJS observable as a source\n * for events dispatched to parent subscribers.\n *\n * The behavior for an observable as source is defined as followed:\n * 1. New values are forwarded to the Angular output (next notifications).\n * 2. Errors notifications are not handled by Angular. You need to handle these manually.\n * For example by using `catchError`.\n * 3. Completion notifications stop the output from emitting new values.\n *\n * @usageNotes\n * Initialize an output in your directive by declaring a\n * class field and initializing it with the `outputFromObservable()` function.\n *\n * ```ts\n * @Directive({..})\n * export class MyDir {\n * nameChange$ = <some-observable>;\n * nameChange = outputFromObservable(this.nameChange$);\n * }\n * ```\n *\n * @developerPreview\n */\nexport function outputFromObservable<T>(\n observable: Observable<T>, opts?: OutputOptions): OutputRef<T> {\n ngDevMode && assertInInjectionContext(outputFromObservable);\n return new OutputFromObservableRef<T>(observable);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {OutputRef, ɵgetOutputDestroyRef} from '@angular/core';\nimport {Observable} from 'rxjs';\n\n/**\n * Converts an Angular output declared via `output()` or `outputFromObservable()`\n * to an observable.\n *\n * You can subscribe to the output via `Observable.subscribe` then.\n *\n * @developerPreview\n */\nexport function outputToObservable<T>(ref: OutputRef<T>): Observable<T> {\n const destroyRef = ɵgetOutputDestroyRef(ref);\n\n return new Observable<T>(observer => {\n // Complete the observable upon directive/component destroy.\n // Note: May be `undefined` if an `EventEmitter` is declared outside\n // of an injection context.\n destroyRef?.onDestroy(() => observer.complete());\n\n const subscription = ref.subscribe(v => observer.next(v));\n return () => subscription.unsubscribe();\n });\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, DestroyRef, effect, inject, Injector, Signal, untracked} from '@angular/core';\nimport {Observable, ReplaySubject} from 'rxjs';\n\n/**\n * Options for `toObservable`.\n *\n * @developerPreview\n */\nexport interface ToObservableOptions {\n /**\n * The `Injector` to use when creating the underlying `effect` which watches the signal.\n *\n * If this isn't specified, the current [injection context](guide/dependency-injection-context)\n * will be used.\n */\n injector?: Injector;\n}\n\n/**\n * Exposes the value of an Angular `Signal` as an RxJS `Observable`.\n *\n * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.\n *\n * `toObservable` must be called in an injection context unless an injector is provided via options.\n *\n * @developerPreview\n */\nexport function toObservable<T>(\n source: Signal<T>,\n options?: ToObservableOptions,\n ): Observable<T> {\n !options?.injector && assertInInjectionContext(toObservable);\n const injector = options?.injector ?? inject(Injector);\n const subject = new ReplaySubject<T>(1);\n\n const watcher = effect(() => {\n let value: T;\n try {\n value = source();\n } catch (err) {\n untracked(() => subject.error(err));\n return;\n }\n untracked(() => subject.next(value));\n }, {injector, manualCleanup: true});\n\n injector.get(DestroyRef).onDestroy(() => {\n watcher.destroy();\n subject.complete();\n });\n\n return subject.asObservable();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertInInjectionContext, assertNotInReactiveContext, computed, DestroyRef, inject, Injector, signal, Signal, WritableSignal, ɵRuntimeError, ɵRuntimeErrorCode} from '@angular/core';\nimport {Observable, Subscribable} from 'rxjs';\n\n/**\n * Options for `toSignal`.\n *\n * @publicApi\n */\nexport interface ToSignalOptions {\n /**\n * Initial value for the signal produced by `toSignal`.\n *\n * This will be the value of the signal until the observable emits its first value.\n */\n initialValue?: unknown;\n\n /**\n * Whether to require that the observable emits synchronously when `toSignal` subscribes.\n *\n * If this is `true`, `toSignal` will assert that the observable produces a value immediately upon\n * subscription. Setting this option removes the need to either deal with `undefined` in the\n * signal type or provide an `initialValue`, at the cost of a runtime error if this requirement is\n * not met.\n */\n requireSync?: boolean;\n\n /**\n * `Injector` which will provide the `DestroyRef` used to clean up the Observable subscription.\n *\n * If this is not provided, a `DestroyRef` will be retrieved from the current [injection\n * context](/guide/dependency-injection-context), unless manual cleanup is requested.\n */\n injector?: Injector;\n\n /**\n * Whether the subscription should be automatically cleaned up (via `DestroyRef`) when\n * `toObservable`'s creation context is destroyed.\n *\n * If manual cleanup is enabled, then `DestroyRef` is not used, and the subscription will persist\n * until the `Observable` itself completes.\n */\n manualCleanup?: boolean;\n\n /**\n * Whether `toSignal` should throw errors from the Observable error channel back to RxJS, where\n * they'll be processed as uncaught exceptions.\n *\n * In practice, this means that the signal returned by `toSignal` will keep returning the last\n * good value forever, as Observables which error produce no further values. This option emulates\n * the behavior of the `async` pipe.\n */\n rejectErrors?: boolean;\n}\n\n// Base case: no options -> `undefined` in the result type.\nexport function toSignal<T>(source: Observable<T>|Subscribable<T>): Signal<T|undefined>;\n// Options with `undefined` initial value and no `requiredSync` -> `undefined`.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: undefined, requireSync?: false}): Signal<T|undefined>;\n// Options with `null` initial value -> `null`.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: null, requireSync?: false}): Signal<T|null>;\n// Options with `undefined` initial value and `requiredSync` -> strict result type.\nexport function toSignal<T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue?: undefined, requireSync: true}): Signal<T>;\n// Options with a more specific initial value type.\nexport function toSignal<T, const U extends T>(\n source: Observable<T>|Subscribable<T>,\n options: ToSignalOptions&{initialValue: U, requireSync?: false}): Signal<T|U>;\n\n/**\n * Get the current value of an `Observable` as a reactive `Signal`.\n *\n * `toSignal` returns a `Signal` which provides synchronous reactive access to values produced\n * by the given `Observable`, by subscribing to that `Observable`. The returned `Signal` will always\n * have the most recent value emitted by the subscription, and will throw an error if the\n * `Observable` errors.\n *\n * With `requireSync` set to `true`, `toSignal` will assert that the `Observable` produces a value\n * immediately upon subscription. No `initialValue` is needed in this case, and the returned signal\n * does not include an `undefined` type.\n *\n * By default, the subscription will be automatically cleaned up when the current [injection\n * context](/guide/dependency-injection-context) is destroyed. For example, when `toObservable` is\n * called during the construction of a component, the subscription will be cleaned up when the\n * component is destroyed. If an injection context is not available, an explicit `Injector` can be\n * passed instead.\n *\n * If the subscription should persist until the `Observable` itself completes, the `manualCleanup`\n * option can be specified instead, which disables the automatic subscription teardown. No injection\n * context is needed in this configuration as well.\n *\n * @developerPreview\n */\nexport function toSignal<T, U = undefined>(\n source: Observable<T>|Subscribable<T>,\n options?: ToSignalOptions&{initialValue?: U}): Signal<T|U> {\n ngDevMode &&\n assertNotInReactiveContext(\n toSignal,\n 'Invoking `toSignal` causes new subscriptions every time. ' +\n 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');\n\n const requiresCleanup = !options?.manualCleanup;\n requiresCleanup && !options?.injector && assertInInjectionContext(toSignal);\n const cleanupRef =\n requiresCleanup ? options?.injector?.get(DestroyRef) ?? inject(DestroyRef) : null;\n\n // Note: T is the Observable value type, and U is the initial value type. They don't have to be\n // the same - the returned signal gives values of type `T`.\n let state: WritableSignal<State<T|U>>;\n if (options?.requireSync) {\n // Initially the signal is in a `NoValue` state.\n state = signal({kind: StateKind.NoValue});\n } else {\n // If an initial value was passed, use it. Otherwise, use `undefined` as the initial value.\n state = signal<State<T|U>>({kind: StateKind.Value, value: options?.initialValue as U});\n }\n\n // Note: This code cannot run inside a reactive context (see assertion above). If we'd support\n // this, we would subscribe to the observable outside of the current reactive context, avoiding\n // that side-effect signal reads/writes are attribute to the current consumer. The current\n // consumer only needs to be notified when the `state` signal changes through the observable\n // subscription. Additional context (related to async pipe):\n // https://github.com/angular/angular/pull/50522.\n const sub = source.subscribe({\n next: value => state.set({kind: StateKind.Value, value}),\n error: error => {\n if (options?.rejectErrors) {\n // Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes\n // the error to end up as an uncaught exception.\n throw error;\n }\n state.set({kind: StateKind.Error, error});\n },\n // Completion of the Observable is meaningless to the signal. Signals don't have a concept of\n // \"complete\".\n });\n\n if (ngDevMode && options?.requireSync && state().kind === StateKind.NoValue) {\n throw new ɵRuntimeError(\n ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT,\n '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');\n }\n\n // Unsubscribe when the current context is destroyed, if requested.\n cleanupRef?.onDestroy(sub.unsubscribe.bind(sub));\n\n // The actual returned signal is a `computed` of the `State` signal, which maps the various states\n // to either values or errors.\n return computed(() => {\n const current = state();\n switch (current.kind) {\n case StateKind.Value:\n return current.value;\n case StateKind.Error:\n throw current.error;\n case StateKind.NoValue:\n // This shouldn't really happen because the error is thrown on creation.\n // TODO(alxhub): use a RuntimeError when we finalize the error semantics\n throw new ɵRuntimeError(\n ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT,\n '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');\n }\n });\n}\n\nconst enum StateKind {\n NoValue,\n Value,\n Error,\n}\n\ninterface NoValueState {\n kind: StateKind.NoValue;\n}\n\ninterface ValueState<T> {\n kind: StateKind.Value;\n value: T;\n}\n\ninterface ErrorState {\n kind: StateKind.Error;\n error: unknown;\n}\n\ntype State<T> = NoValueState|ValueState<T>|ErrorState;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v17.3.0-next.0
2
+ * @license Angular v17.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { ɵDeferBlockState, ɵtriggerResourceLoading, ɵrenderDeferBlockState, ɵCONTAINER_HEADER_OFFSET, ɵgetDeferBlocks, ɵDeferBlockBehavior, InjectionToken, inject as inject$1, ɵNoopNgZone, NgZone, ɵEffectScheduler, ApplicationRef, getDebugNode, RendererFactory2, ɵPendingTasks, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetAsyncClassMetadataFn, ɵgenerateStandaloneInDeclarationsError, ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ɵdepsTracker, ɵgetInjectableDef, resolveForwardRef, ɵNG_COMP_DEF, ɵisComponentDefPendingResolution, ɵresolveComponentResources, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, ɵclearResolutionOfComponentResourcesQueue, ɵrestoreComponentResolutionQueue, provideZoneChangeDetection, Compiler, ɵDEFER_BLOCK_CONFIG, COMPILER_OPTIONS, Injector, ɵisEnvironmentProviders, ɵNgModuleFactory, ModuleWithComponentFactories, ɵconvertToBitFlags, InjectFlags, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, runInInjectionContext, EnvironmentInjector, ɵChangeDetectionScheduler, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
7
+ import { ɵDeferBlockState, ɵtriggerResourceLoading, ɵrenderDeferBlockState, ɵCONTAINER_HEADER_OFFSET, ɵgetDeferBlocks, ɵDeferBlockBehavior, InjectionToken, inject as inject$1, ɵNoopNgZone, NgZone, ɵEffectScheduler, ApplicationRef, getDebugNode, RendererFactory2, ɵPendingTasks, ɵisG3, ɵdetectChangesInViewIfRequired, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetAsyncClassMetadataFn, ɵgenerateStandaloneInDeclarationsError, ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ɵdepsTracker, ɵgetInjectableDef, resolveForwardRef, ɵNG_COMP_DEF, ɵisComponentDefPendingResolution, ɵresolveComponentResources, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, ɵclearResolutionOfComponentResourcesQueue, ɵrestoreComponentResolutionQueue, provideZoneChangeDetection, Compiler, ɵDEFER_BLOCK_CONFIG, COMPILER_OPTIONS, Injector, ɵisEnvironmentProviders, ɵNgModuleFactory, ModuleWithComponentFactories, ɵconvertToBitFlags, InjectFlags, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, runInInjectionContext, EnvironmentInjector, ɵChangeDetectionScheduler, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
8
8
  export { ɵDeferBlockBehavior as DeferBlockBehavior, ɵDeferBlockState as DeferBlockState } from '@angular/core';
9
9
  import { Subscription } from 'rxjs';
10
10
  import { first } from 'rxjs/operators';
@@ -187,6 +187,8 @@ class ComponentFixture {
187
187
  // behavior.
188
188
  /** @internal */
189
189
  this._appRef = inject$1(ApplicationRef);
190
+ /** @internal */
191
+ this._testAppRef = this._appRef;
190
192
  // TODO(atscott): Remove this from public API
191
193
  this.ngZone = this._noZoneOptionIsSet ? null : this._ngZone;
192
194
  this.changeDetectorRef = componentRef.changeDetectorRef;
@@ -278,7 +280,7 @@ class ScheduledComponentFixture extends ComponentFixture {
278
280
  if (this.isStable()) {
279
281
  return Promise.resolve(false);
280
282
  }
281
- return this._appRef.isStable.pipe(first(stable => stable)).toPromise().then(() => true);
283
+ return this._appRef.isStable.pipe(first((stable) => stable)).toPromise().then(() => true);
282
284
  }
283
285
  autoDetectChanges(autoDetect) {
284
286
  throw new Error('Cannot call autoDetectChanges when using change detection scheduling.');
@@ -295,33 +297,44 @@ class PseudoApplicationComponentFixture extends ComponentFixture {
295
297
  this._isStable = true;
296
298
  this._promise = null;
297
299
  this._resolve = null;
300
+ this.afterTickSubscription = undefined;
301
+ this.beforeRenderSubscription = undefined;
298
302
  }
299
303
  initialize() {
304
+ if (this._autoDetect) {
305
+ this.subscribeToAppRefEvents();
306
+ }
307
+ this.componentRef.hostView.onDestroy(() => {
308
+ this.unsubscribeFromAppRefEvents();
309
+ });
300
310
  // Create subscriptions outside the NgZone so that the callbacks run outside
301
311
  // of NgZone.
302
312
  this._ngZone.runOutsideAngular(() => {
303
313
  this._subscriptions.add(this._ngZone.onUnstable.subscribe({
304
314
  next: () => {
305
315
  this._isStable = false;
306
- }
307
- }));
308
- this._subscriptions.add(this._ngZone.onMicrotaskEmpty.subscribe({
309
- next: () => {
310
- if (this._autoDetect) {
311
- // Do a change detection run with checkNoChanges set to true to check
312
- // there are no changes on the second run.
313
- this.detectChanges(true);
314
- }
315
- }
316
+ },
316
317
  }));
318
+ // TODO(atscott): Remove and make this a breaking change externally in v18
319
+ if (!ɵisG3) {
320
+ this._subscriptions.add(this._ngZone.onMicrotaskEmpty.subscribe({
321
+ next: () => {
322
+ if (this._autoDetect) {
323
+ // Do a change detection run with checkNoChanges set to true to check
324
+ // there are no changes on the second run.
325
+ this.detectChanges(true);
326
+ }
327
+ },
328
+ }));
329
+ }
317
330
  this._subscriptions.add(this._ngZone.onStable.subscribe({
318
331
  next: () => {
319
332
  this._isStable = true;
320
333
  // Check whether there is a pending whenStable() completer to resolve.
321
334
  if (this._promise !== null) {
322
335
  // If so check whether there are no pending macrotasks before resolving.
323
- // Do this check in the next tick so that ngZone gets a chance to update the state of
324
- // pending macrotasks.
336
+ // Do this check in the next tick so that ngZone gets a chance to update the state
337
+ // of pending macrotasks.
325
338
  queueMicrotask(() => {
326
339
  if (!this._ngZone.hasPendingMacrotasks) {
327
340
  if (this._promise !== null) {
@@ -332,12 +345,12 @@ class PseudoApplicationComponentFixture extends ComponentFixture {
332
345
  }
333
346
  });
334
347
  }
335
- }
348
+ },
336
349
  }));
337
350
  this._subscriptions.add(this._ngZone.onError.subscribe({
338
351
  next: (error) => {
339
352
  throw error;
340
- }
353
+ },
341
354
  }));
342
355
  });
343
356
  }
@@ -366,7 +379,7 @@ class PseudoApplicationComponentFixture extends ComponentFixture {
366
379
  return this._promise;
367
380
  }
368
381
  else {
369
- this._promise = new Promise(res => {
382
+ this._promise = new Promise((res) => {
370
383
  this._resolve = res;
371
384
  });
372
385
  return this._promise;
@@ -376,10 +389,56 @@ class PseudoApplicationComponentFixture extends ComponentFixture {
376
389
  if (this._noZoneOptionIsSet) {
377
390
  throw new Error('Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set.');
378
391
  }
392
+ if (autoDetect !== this._autoDetect) {
393
+ if (autoDetect) {
394
+ this.subscribeToAppRefEvents();
395
+ }
396
+ else {
397
+ this.unsubscribeFromAppRefEvents();
398
+ }
399
+ }
379
400
  this._autoDetect = autoDetect;
380
401
  this.detectChanges();
381
402
  }
403
+ subscribeToAppRefEvents() {
404
+ // TODO(atscott): Remove and make this a breaking change externally in v18
405
+ if (!ɵisG3) {
406
+ return;
407
+ }
408
+ this._ngZone.runOutsideAngular(() => {
409
+ this.afterTickSubscription = this._testAppRef.afterTick.subscribe(() => {
410
+ this.checkNoChanges();
411
+ });
412
+ this.beforeRenderSubscription = this._testAppRef.beforeRender.subscribe((isFirstPass) => {
413
+ try {
414
+ ɵdetectChangesInViewIfRequired(this.componentRef.hostView._lView, isFirstPass, this.componentRef.hostView.notifyErrorHandler);
415
+ }
416
+ catch (e) {
417
+ // If an error ocurred during change detection, remove the test view from the application
418
+ // ref tracking. Note that this isn't exactly desirable but done this way because of how
419
+ // things used to work with `autoDetect` and uncaught errors. Ideally we would surface
420
+ // this error to the error handler instead and continue refreshing the view like
421
+ // what would happen in the application.
422
+ this.unsubscribeFromAppRefEvents();
423
+ throw e;
424
+ }
425
+ });
426
+ this._testAppRef.externalTestViews.add(this.componentRef.hostView);
427
+ });
428
+ }
429
+ unsubscribeFromAppRefEvents() {
430
+ // TODO(atscott): Remove and make this a breaking change externally in v18
431
+ if (!ɵisG3) {
432
+ return;
433
+ }
434
+ this.afterTickSubscription?.unsubscribe();
435
+ this.beforeRenderSubscription?.unsubscribe();
436
+ this.afterTickSubscription = undefined;
437
+ this.beforeRenderSubscription = undefined;
438
+ this._testAppRef.externalTestViews.delete(this.componentRef.hostView);
439
+ }
382
440
  destroy() {
441
+ this.unsubscribeFromAppRefEvents();
383
442
  this._subscriptions.unsubscribe();
384
443
  super.destroy();
385
444
  }
@@ -773,6 +832,9 @@ class TestBedCompiler {
773
832
  this.pendingComponents = new Set();
774
833
  this.pendingDirectives = new Set();
775
834
  this.pendingPipes = new Set();
835
+ // Set of components with async metadata, i.e. components with `@defer` blocks
836
+ // in their templates.
837
+ this.componentsWithAsyncMetadata = new Set();
776
838
  // Keep track of all components and directives, so we can patch Providers onto defs later.
777
839
  this.seenComponents = new Set();
778
840
  this.seenDirectives = new Set();
@@ -860,6 +922,9 @@ class TestBedCompiler {
860
922
  this.verifyNoStandaloneFlagOverrides(component, override);
861
923
  this.resolvers.component.addOverride(component, override);
862
924
  this.pendingComponents.add(component);
925
+ // If this is a component with async metadata (i.e. a component with a `@defer` block
926
+ // in a template) - store it for future processing.
927
+ this.maybeRegisterComponentWithAsyncMetadata(component);
863
928
  }
864
929
  overrideDirective(directive, override) {
865
930
  this.verifyNoStandaloneFlagOverrides(directive, override);
@@ -933,17 +998,24 @@ class TestBedCompiler {
933
998
  this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
934
999
  }
935
1000
  async resolvePendingComponentsWithAsyncMetadata() {
936
- if (this.pendingComponents.size === 0)
1001
+ if (this.componentsWithAsyncMetadata.size === 0)
937
1002
  return;
938
1003
  const promises = [];
939
- for (const component of this.pendingComponents) {
1004
+ for (const component of this.componentsWithAsyncMetadata) {
940
1005
  const asyncMetadataFn = ɵgetAsyncClassMetadataFn(component);
941
1006
  if (asyncMetadataFn) {
942
1007
  promises.push(asyncMetadataFn());
943
1008
  }
944
1009
  }
1010
+ this.componentsWithAsyncMetadata.clear();
945
1011
  const resolvedDeps = await Promise.all(promises);
946
- this.queueTypesFromModulesArray(resolvedDeps.flat(2));
1012
+ const flatResolvedDeps = resolvedDeps.flat(2);
1013
+ this.queueTypesFromModulesArray(flatResolvedDeps);
1014
+ // Loaded standalone components might contain imports of NgModules
1015
+ // with providers, make sure we override providers there too.
1016
+ for (const component of flatResolvedDeps) {
1017
+ this.applyProviderOverridesInScope(component);
1018
+ }
947
1019
  }
948
1020
  async compileComponents() {
949
1021
  this.clearComponentResolutionQueue();
@@ -1211,7 +1283,16 @@ class TestBedCompiler {
1211
1283
  this.maybeStoreNgDef(ɵNG_INJ_DEF, ngModule);
1212
1284
  ɵcompileNgModuleDefs(ngModule, metadata);
1213
1285
  }
1286
+ maybeRegisterComponentWithAsyncMetadata(type) {
1287
+ const asyncMetadataFn = ɵgetAsyncClassMetadataFn(type);
1288
+ if (asyncMetadataFn) {
1289
+ this.componentsWithAsyncMetadata.add(type);
1290
+ }
1291
+ }
1214
1292
  queueType(type, moduleType) {
1293
+ // If this is a component with async metadata (i.e. a component with a `@defer` block
1294
+ // in a template) - store it for future processing.
1295
+ this.maybeRegisterComponentWithAsyncMetadata(type);
1215
1296
  const component = this.resolvers.component.resolve(type);
1216
1297
  if (component) {
1217
1298
  // Check whether a give Type has respective NG def (ɵcmp) and compile if def is