diff --git a/goldens/public-api/core/primitives/signals/index.api.md b/goldens/public-api/core/primitives/signals/index.api.md index c5443f89748..86630c8f7e3 100644 --- a/goldens/public-api/core/primitives/signals/index.api.md +++ b/goldens/public-api/core/primitives/signals/index.api.md @@ -66,6 +66,9 @@ export function createWatch(fn: (onCleanup: WatchCleanupRegisterFn) => void, sch // @public export function defaultEquals(a: T, b: T): boolean; +// @public +export function finalizeConsumerAfterComputation(node: ReactiveNode): void; + // @public (undocumented) export function getActiveConsumer(): ReactiveNode | null; @@ -151,6 +154,9 @@ export interface ReactiveNode { version: Version; } +// @public +export function resetConsumerBeforeComputation(node: ReactiveNode): void; + // @public (undocumented) export function runEffect(node: BaseEffectNode): void; diff --git a/packages/core/primitives/signals/index.ts b/packages/core/primitives/signals/index.ts index 4f9544b2c75..51c0240f29e 100644 --- a/packages/core/primitives/signals/index.ts +++ b/packages/core/primitives/signals/index.ts @@ -28,6 +28,7 @@ export { consumerDestroy, consumerMarkDirty, consumerPollProducersForChange, + finalizeConsumerAfterComputation, getActiveConsumer, isInNotificationPhase, isReactive, @@ -37,6 +38,7 @@ export { producerNotifyConsumers, producerUpdateValueVersion, producerUpdatesAllowed, + resetConsumerBeforeComputation, runPostProducerCreatedFn, setActiveConsumer, setPostProducerCreatedFn, diff --git a/packages/core/primitives/signals/src/graph.ts b/packages/core/primitives/signals/src/graph.ts index f3c3b5efdc2..99acd3b2482 100644 --- a/packages/core/primitives/signals/src/graph.ts +++ b/packages/core/primitives/signals/src/graph.ts @@ -359,21 +359,34 @@ export function producerMarkClean(node: ReactiveNode): void { } /** - * Prepare this consumer to run a computation in its reactive context. + * Prepare this consumer to run a computation in its reactive context and set + * it as the active consumer. * * Must be called by subclasses which represent reactive computations, before those computations * begin. */ export function consumerBeforeComputation(node: ReactiveNode | null): ReactiveNode | null { - if (node) { - node.producersTail = undefined; - node.recomputing = true; - } + if (node) resetConsumerBeforeComputation(node); + return setActiveConsumer(node); } /** - * Finalize this consumer's state after a reactive computation has run. + * Prepare this consumer to run a computation in its reactive context. + * + * We expose this mainly for code where we manually batch effects into a single + * consumer. In those cases we may wish to "reopen" a consumer multiple times + * in initial render before finalizing it. Most code should just call + * `consumerBeforeComputation` instead of calling this directly. + */ +export function resetConsumerBeforeComputation(node: ReactiveNode): void { + node.producersTail = undefined; + node.recomputing = true; +} + +/** + * Finalize this consumer's state and set previous consumer as the active consumer after a + * reactive computation has run. * * Must be called by subclasses which represent reactive computations, after those computations * have finished. @@ -384,10 +397,18 @@ export function consumerAfterComputation( ): void { setActiveConsumer(prevConsumer); - if (!node) { - return; - } + if (node) finalizeConsumerAfterComputation(node); +} +/** + * Finalize this consumer's state after a reactive computation has run. + * + * We expose this mainly for code where we manually batch effects into a single + * consumer. In those cases we may wish to "reopen" a consumer multiple times + * in initial render before finalizing it. Most code should just call + * `consumerAfterComputation` instead of calling this directly. + */ +export function finalizeConsumerAfterComputation(node: ReactiveNode): void { node.recomputing = false; // We've finished incrementally rebuilding the producers list, now if there are any producers diff --git a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json index 44b3c8562fa..4af71f194f4 100644 --- a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json +++ b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json @@ -549,6 +549,7 @@ "extractDirectiveDef", "extractStyleParams", "filterNonAnimatableStyles", + "finalizeConsumerAfterComputation", "findAttrIndexInNode", "findDirectiveDefMatches", "flattenGroupPlayers", @@ -850,6 +851,7 @@ "replacePostStylesAsPre", "reportUnhandledError", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveDirectives", "resolveElementFromTarget", diff --git a/packages/core/test/bundling/defer/bundle.golden_symbols.json b/packages/core/test/bundling/defer/bundle.golden_symbols.json index ac65d6d46de..f3701a3756e 100644 --- a/packages/core/test/bundling/defer/bundle.golden_symbols.json +++ b/packages/core/test/bundling/defer/bundle.golden_symbols.json @@ -468,6 +468,7 @@ "extractAttrsAndClassesFromSelector", "extractDefListOrFactory", "extractDirectiveDef", + "finalizeConsumerAfterComputation", "findAttrIndexInNode", "findDirectiveDefMatches", "findMatchingDehydratedViewForDeferBlock", @@ -722,6 +723,7 @@ "renderView", "reportUnhandledError", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveDirectives", "resolveForwardRef", diff --git a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json index 71cf4510b7a..59ca61487cd 100644 --- a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json @@ -605,6 +605,7 @@ "extractDefListOrFactory", "extractDirectiveDef", "fillProperties", + "finalizeConsumerAfterComputation", "findAttrIndexInNode", "findDirectiveDefMatches", "findExistingListener", @@ -982,6 +983,7 @@ "requiredTrueValidator", "requiredValidator", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveComponentResources", "resolveDirectives", diff --git a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json index 97f421fb450..8da5e89932f 100644 --- a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json @@ -604,6 +604,7 @@ "extractDefListOrFactory", "extractDirectiveDef", "fillProperties", + "finalizeConsumerAfterComputation", "findAttrIndexInNode", "findDirectiveDefMatches", "findExistingListener", @@ -975,6 +976,7 @@ "reportUnhandledError", "requiredValidator", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveComponentResources", "resolveDirectives", diff --git a/packages/core/test/bundling/hydration/bundle.golden_symbols.json b/packages/core/test/bundling/hydration/bundle.golden_symbols.json index 05aa030d9f5..2d12e08ce20 100644 --- a/packages/core/test/bundling/hydration/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hydration/bundle.golden_symbols.json @@ -485,6 +485,7 @@ "extractAttrsAndClassesFromSelector", "extractDefListOrFactory", "extractDirectiveDef", + "finalizeConsumerAfterComputation", "findAndReconcileMatchingDehydratedViewsImpl", "findMatchingDehydratedView", "findMatchingDehydratedViewImpl", @@ -764,6 +765,7 @@ "renderView", "reportUnhandledError", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveDirectives", "resolveForwardRef", diff --git a/packages/core/test/bundling/router/bundle.golden_symbols.json b/packages/core/test/bundling/router/bundle.golden_symbols.json index dee3c0a8e26..ba880fd3434 100644 --- a/packages/core/test/bundling/router/bundle.golden_symbols.json +++ b/packages/core/test/bundling/router/bundle.golden_symbols.json @@ -719,6 +719,7 @@ "extractDirectiveDef", "filter", "finalize", + "finalizeConsumerAfterComputation", "findAttrIndexInNode", "findDirectiveDefMatches", "findExistingListener", @@ -1116,6 +1117,7 @@ "replaceSegment", "reportUnhandledError", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveData", "resolveDirectives", diff --git a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json index d89df4e859b..aadab4880e9 100644 --- a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json +++ b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json @@ -399,6 +399,7 @@ "extractAttrsAndClassesFromSelector", "extractDefListOrFactory", "extractDirectiveDef", + "finalizeConsumerAfterComputation", "forEachSingleProvider", "forkInnerZoneWithAngularBehavior", "formatErrorMessage", @@ -616,6 +617,7 @@ "renderView", "reportUnhandledError", "requiresRefreshOrTraversal", + "resetConsumerBeforeComputation", "resetPreOrderHookFlags", "resolveDirectives", "resolveForwardRef",