@@ -16,8 +16,6 @@ import {
1616 SIGNAL_NODE ,
1717 type SignalNode ,
1818} from '../../../primitives/signals' ;
19- import { type EffectCleanupFn , type EffectCleanupRegisterFn } from './effect' ;
20- import { type Signal } from '../reactivity/api' ;
2119import { TracingService , TracingSnapshot } from '../../application/tracing' ;
2220import {
2321 ChangeDetectionScheduler ,
@@ -35,13 +33,16 @@ import {
3533 AfterRenderManager ,
3634 AfterRenderSequence ,
3735} from '../after_render/manager' ;
38- import { LView } from '../interfaces/view' ;
39- import { ViewContext } from '../view_context' ;
40- import { assertNotInReactiveContext } from './asserts' ;
4136import {
4237 emitAfterRenderEffectPhaseCreatedEvent ,
4338 setInjectorProfilerContext ,
4439} from '../debug/injector_profiler' ;
40+ import { LView } from '../interfaces/view' ;
41+ import { type Signal } from '../reactivity/api' ;
42+ import { ViewContext } from '../view_context' ;
43+ import { assertNotInReactiveContext } from './asserts' ;
44+ import { type EffectCleanupFn , type EffectCleanupRegisterFn } from './effect' ;
45+ import { untracked } from './untracked' ;
4546
4647const NOT_SET = /* @__PURE__ */ Symbol ( 'NOT_SET' ) ;
4748const EMPTY_CLEANUP_SET = /* @__PURE__ */ new Set < ( ) => void > ( ) ;
@@ -306,6 +307,11 @@ export function afterRenderEffect(
306307 callback : ( onCleanup : EffectCleanupRegisterFn ) => void ,
307308 options ?: AfterRenderOptions ,
308309) : AfterRenderRef ;
310+ export function afterRenderEffect < T > (
311+ reactiveFn : ( ) => T ,
312+ effectFn : ( params : T , onCleanup : EffectCleanupRegisterFn ) => void ,
313+ options ?: AfterRenderOptions ,
314+ ) : AfterRenderRef ;
309315/**
310316 * Register effects that, when triggered, are invoked when the application finishes rendering,
311317 * during the specified phases. The available phases are:
@@ -380,7 +386,7 @@ export function afterRenderEffect<E = never, W = never, M = never>(
380386 * @publicApi
381387 */
382388export function afterRenderEffect < E = never , W = never , M = never > (
383- callbackOrSpec :
389+ callbackSpecOrReactiveFn :
384390 | ( ( onCleanup : EffectCleanupRegisterFn ) => void )
385391 | {
386392 earlyRead ?: ( onCleanup : EffectCleanupRegisterFn ) => E ;
@@ -390,8 +396,47 @@ export function afterRenderEffect<E = never, W = never, M = never>(
390396 ) => M ;
391397 read ?: ( ...args : [ ...ɵFirstAvailableSignal < [ M , W , E ] > , EffectCleanupRegisterFn ] ) => void ;
392398 } ,
393- options ?: AfterRenderOptions ,
399+ optionsOrEffectFn ?:
400+ | AfterRenderOptions
401+ | ( ( params : unknown , onCleanup : EffectCleanupRegisterFn ) => void ) ,
402+ explicitOptions ?: AfterRenderOptions ,
394403) : AfterRenderRef {
404+ let callbackOrSpec :
405+ | ( ( onCleanup : EffectCleanupRegisterFn ) => void )
406+ | {
407+ earlyRead ?: ( onCleanup : EffectCleanupRegisterFn ) => E ;
408+ write ?: ( ...args : [ ...ɵFirstAvailableSignal < [ E ] > , EffectCleanupRegisterFn ] ) => W ;
409+ mixedReadWrite ?: (
410+ ...args : [ ...ɵFirstAvailableSignal < [ W , E ] > , EffectCleanupRegisterFn ]
411+ ) => M ;
412+ read ?: ( ...args : [ ...ɵFirstAvailableSignal < [ M , W , E ] > , EffectCleanupRegisterFn ] ) => void ;
413+ } ;
414+ let options : AfterRenderOptions | undefined ;
415+
416+ if ( typeof callbackSpecOrReactiveFn === 'function' && typeof optionsOrEffectFn === 'function' ) {
417+ const reactiveFn = callbackSpecOrReactiveFn as ( ) => unknown ;
418+ const effectFn = optionsOrEffectFn ;
419+ callbackOrSpec = {
420+ mixedReadWrite : ( ( onCleanup : EffectCleanupRegisterFn ) => {
421+ const params = reactiveFn ( ) ;
422+ untracked ( ( ) => effectFn ( params , onCleanup ) ) ;
423+ } ) as any ,
424+ } as any ;
425+ options = explicitOptions ;
426+ } else {
427+ callbackOrSpec = callbackSpecOrReactiveFn as
428+ | ( ( onCleanup : EffectCleanupRegisterFn ) => void )
429+ | {
430+ earlyRead ?: ( onCleanup : EffectCleanupRegisterFn ) => E ;
431+ write ?: ( ...args : [ ...ɵFirstAvailableSignal < [ E ] > , EffectCleanupRegisterFn ] ) => W ;
432+ mixedReadWrite ?: (
433+ ...args : [ ...ɵFirstAvailableSignal < [ W , E ] > , EffectCleanupRegisterFn ]
434+ ) => M ;
435+ read ?: ( ...args : [ ...ɵFirstAvailableSignal < [ M , W , E ] > , EffectCleanupRegisterFn ] ) => void ;
436+ } ;
437+ options = optionsOrEffectFn as AfterRenderOptions | undefined ;
438+ }
439+
395440 ngDevMode &&
396441 assertNotInReactiveContext (
397442 afterRenderEffect ,
0 commit comments