refactor(core): Update interfaces for handling defer completion (#58206)

This adds properties to the LDeferBlockDetails and ensures the completion functions exist for future incremental hydration use cases.

PR Close #58206
This commit is contained in:
Jessica Janiuk 2024-10-15 10:37:08 -04:00 committed by Paul Gschwendtner
parent 73c95f521c
commit d760cbe71b
3 changed files with 55 additions and 0 deletions

View file

@ -73,6 +73,7 @@ import {
LDeferBlockDetails,
LOADING_AFTER_CLEANUP_FN,
NEXT_DEFER_BLOCK_STATE,
ON_COMPLETE_FNS,
STATE_IS_FROZEN_UNTIL,
TDeferBlockDetails,
TriggerType,
@ -230,6 +231,10 @@ export function ɵɵdefer(
null, // LOADING_AFTER_CLEANUP_FN
null, // TRIGGER_CLEANUP_FNS
null, // PREFETCH_TRIGGER_CLEANUP_FNS
null, // UNIQUE_SSR_ID
null, // SSR_STATE
null, // ON_COMPLETE_FNS
null, // HYDRATE_TRIGGER_CLEANUP_FNS
];
setLDeferBlockDetails(lView, adjustedIndex, lDetails);
@ -757,6 +762,13 @@ function applyDeferBlockState(
);
markViewDirty(embeddedLView, NotificationSource.DeferBlockStateUpdate);
}
if (newState === DeferBlockState.Complete && Array.isArray(lDetails[ON_COMPLETE_FNS])) {
for (const callback of lDetails[ON_COMPLETE_FNS]) {
callback();
}
lDetails[ON_COMPLETE_FNS] = null;
}
}
/**
@ -1082,3 +1094,19 @@ function triggerDeferBlock(lView: LView, tNode: TNode) {
}
}
}
export function triggerAndWaitForCompletion(deferBlock: any): Promise<void> {
const lDetails = getLDeferBlockDetails(deferBlock.lView, deferBlock.tNode);
const promise = new Promise<void>((resolve) => {
onDeferBlockCompletion(lDetails, resolve);
});
triggerDeferBlock(deferBlock.lView, deferBlock.tNode);
return promise;
}
function onDeferBlockCompletion(lDetails: LDeferBlockDetails, callback: VoidFunction) {
if (!Array.isArray(lDetails[ON_COMPLETE_FNS])) {
lDetails[ON_COMPLETE_FNS] = [];
}
lDetails[ON_COMPLETE_FNS].push(callback);
}

View file

@ -158,6 +158,10 @@ export const STATE_IS_FROZEN_UNTIL = 2;
export const LOADING_AFTER_CLEANUP_FN = 3;
export const TRIGGER_CLEANUP_FNS = 4;
export const PREFETCH_TRIGGER_CLEANUP_FNS = 5;
export const UNIQUE_SSR_ID = 6;
export const SSR_STATE = 7;
export const ON_COMPLETE_FNS = 8;
export const HYDRATE_TRIGGER_CLEANUP_FNS = 9;
/**
* Describes instance-specific defer block data.
@ -199,6 +203,26 @@ export interface LDeferBlockDetails extends Array<unknown> {
* List of cleanup functions for prefetch triggers.
*/
[PREFETCH_TRIGGER_CLEANUP_FNS]: VoidFunction[] | null;
/**
* Unique id of this defer block assigned during SSR.
*/
[UNIQUE_SSR_ID]: string | null;
/**
* Defer block state after SSR.
*/
[SSR_STATE]: number | null;
/**
* A set of callbacks to be invoked once the main content is rendered.
*/
[ON_COMPLETE_FNS]: VoidFunction[] | null;
/**
* List of cleanup functions for hydrate triggers.
*/
[HYDRATE_TRIGGER_CLEANUP_FNS]: VoidFunction[] | null;
}
/**

View file

@ -377,6 +377,9 @@
{
"name": "NullInjector"
},
{
"name": "ON_COMPLETE_FNS"
},
{
"name": "ObjectUnsubscribedError"
},