Skip to content

Commit f3d9316

Browse files
refactor(core): moves incremental hydration codebase to better locations (#58616)
This eliminates the extra incremental.ts codepath and moves its functions to appropriate locations. PR Close #58616
1 parent 9fced64 commit f3d9316

File tree

7 files changed

+228
-251
lines changed

7 files changed

+228
-251
lines changed

packages/core/src/defer/triggering.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {Injector} from '../di';
1010
import {internalImportProvidersFrom} from '../di/provider_collection';
1111
import {RuntimeError, RuntimeErrorCode} from '../errors';
1212
import {cleanupDeferBlock} from '../hydration/cleanup';
13+
import {BlockSummary, ElementTrigger, NUM_ROOT_NODES} from '../hydration/interfaces';
1314
import {
1415
assertSsrIdDefined,
1516
getParentBlockHydrationQueue,
@@ -30,6 +31,8 @@ import {
3031
invokeTriggerCleanupFns,
3132
storeTriggerCleanupFn,
3233
} from './cleanup';
34+
import {onViewport} from './dom_triggers';
35+
import {onIdle} from './idle_scheduler';
3336
import {
3437
DeferBlockBehavior,
3538
DeferBlockState,
@@ -51,6 +54,7 @@ import {
5154
renderDeferStateAfterResourceLoading,
5255
renderPlaceholder,
5356
} from './rendering';
57+
import {onTimer} from './timer_scheduler';
5458
import {
5559
addDepsToRegistry,
5660
assertDeferredDependenciesLoaded,
@@ -494,3 +498,93 @@ export function getHydrateTriggers(
494498
export function getPrefetchTriggers(tDetails: TDeferBlockDetails): Set<DeferBlockTrigger> {
495499
return (tDetails.prefetchTriggers ??= new Set());
496500
}
501+
502+
/**
503+
* Loops through all defer block summaries and ensures all the blocks triggers are
504+
* properly initialized
505+
*/
506+
export function processAndInitTriggers(
507+
injector: Injector,
508+
blockData: Map<string, BlockSummary>,
509+
nodes: Map<string, Comment>,
510+
) {
511+
const idleElements: ElementTrigger[] = [];
512+
const timerElements: ElementTrigger[] = [];
513+
const viewportElements: ElementTrigger[] = [];
514+
const immediateElements: ElementTrigger[] = [];
515+
for (let [blockId, blockSummary] of blockData) {
516+
const commentNode = nodes.get(blockId);
517+
if (commentNode !== undefined) {
518+
const numRootNodes = blockSummary.data[NUM_ROOT_NODES];
519+
let currentNode: Comment | HTMLElement = commentNode;
520+
for (let i = 0; i < numRootNodes; i++) {
521+
currentNode = currentNode.previousSibling as HTMLElement;
522+
if (currentNode.nodeType !== Node.ELEMENT_NODE) {
523+
continue;
524+
}
525+
const elementTrigger: ElementTrigger = {el: currentNode, blockName: blockId};
526+
// hydrate
527+
if (blockSummary.hydrate.idle) {
528+
idleElements.push(elementTrigger);
529+
}
530+
if (blockSummary.hydrate.immediate) {
531+
immediateElements.push(elementTrigger);
532+
}
533+
if (blockSummary.hydrate.timer !== null) {
534+
elementTrigger.delay = blockSummary.hydrate.timer;
535+
timerElements.push(elementTrigger);
536+
}
537+
if (blockSummary.hydrate.viewport) {
538+
viewportElements.push(elementTrigger);
539+
}
540+
}
541+
}
542+
}
543+
544+
setIdleTriggers(injector, idleElements);
545+
setImmediateTriggers(injector, immediateElements);
546+
setViewportTriggers(injector, viewportElements);
547+
setTimerTriggers(injector, timerElements);
548+
}
549+
550+
async function setIdleTriggers(injector: Injector, elementTriggers: ElementTrigger[]) {
551+
for (const elementTrigger of elementTriggers) {
552+
const registry = injector.get(DEHYDRATED_BLOCK_REGISTRY);
553+
const onInvoke = () => triggerHydrationFromBlockName(injector, elementTrigger.blockName);
554+
const cleanupFn = onIdle(onInvoke, injector);
555+
registry.addCleanupFn(elementTrigger.blockName, cleanupFn);
556+
}
557+
}
558+
559+
async function setViewportTriggers(injector: Injector, elementTriggers: ElementTrigger[]) {
560+
if (elementTriggers.length > 0) {
561+
const registry = injector.get(DEHYDRATED_BLOCK_REGISTRY);
562+
for (let elementTrigger of elementTriggers) {
563+
const cleanupFn = onViewport(
564+
elementTrigger.el,
565+
async () => {
566+
await triggerHydrationFromBlockName(injector, elementTrigger.blockName);
567+
},
568+
injector,
569+
);
570+
registry.addCleanupFn(elementTrigger.blockName, cleanupFn);
571+
}
572+
}
573+
}
574+
575+
async function setTimerTriggers(injector: Injector, elementTriggers: ElementTrigger[]) {
576+
for (const elementTrigger of elementTriggers) {
577+
const registry = injector.get(DEHYDRATED_BLOCK_REGISTRY);
578+
const onInvoke = async () =>
579+
await triggerHydrationFromBlockName(injector, elementTrigger.blockName);
580+
const timerFn = onTimer(elementTrigger.delay!);
581+
const cleanupFn = timerFn(onInvoke, injector);
582+
registry.addCleanupFn(elementTrigger.blockName, cleanupFn);
583+
}
584+
}
585+
586+
async function setImmediateTriggers(injector: Injector, elementTriggers: ElementTrigger[]) {
587+
for (const elementTrigger of elementTriggers) {
588+
await triggerHydrationFromBlockName(injector, elementTrigger.blockName);
589+
}
590+
}

packages/core/src/hydration/api.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ import {
4444
} from './tokens';
4545
import {
4646
appendDeferBlocksToJSActionMap,
47+
enableRetrieveDeferBlockDataImpl,
4748
enableRetrieveHydrationInfoImpl,
4849
NGH_DATA_KEY,
50+
processBlockData,
4951
SSR_CONTENT_INTEGRITY_MARKER,
5052
} from './utils';
5153
import {enableFindMatchingDehydratedViewImpl} from './views';
52-
import {bootstrapIncrementalHydration, enableRetrieveDeferBlockDataImpl} from './incremental';
5354
import {DEHYDRATED_BLOCK_REGISTRY, DehydratedBlockRegistry} from '../defer/registry';
55+
import {gatherDeferBlocksCommentNodes} from './node_lookup_utils';
56+
import {processAndInitTriggers} from '../defer/triggering';
5457

5558
/**
5659
* Indicates whether the hydration-related code was added,
@@ -353,7 +356,9 @@ export function withIncrementalHydration(): Provider[] {
353356
const doc = getDocument();
354357

355358
return () => {
356-
bootstrapIncrementalHydration(doc, injector);
359+
const deferBlockData = processBlockData(injector);
360+
const commentsByBlockId = gatherDeferBlocksCommentNodes(doc, doc.body);
361+
processAndInitTriggers(injector, deferBlockData, commentsByBlockId);
357362
appendDeferBlocksToJSActionMap(doc, injector);
358363
};
359364
},

packages/core/src/hydration/incremental.ts

Lines changed: 0 additions & 246 deletions
This file was deleted.

0 commit comments

Comments
 (0)