refactor(core): change node navigation step to plain const (#59469)

We change the `enum` to a plain `const` to eliminate extra bytes, as `enum` is not really required. We might not be able to switch to `const enum` due to single-file compilation restrictions.

PR Close #59469
This commit is contained in:
arturovt 2025-01-10 18:40:47 +02:00 committed by kirjs
parent 9931030b0e
commit 783c5bb586
4 changed files with 19 additions and 12 deletions

View file

@ -19,11 +19,15 @@ export const REFERENCE_NODE_BODY = 'b';
/**
* Describes navigation steps that the runtime logic need to perform,
* starting from a given (known) element.
* We're not using enum `NodeNavigationStep` because it produces more code overhead;
* thus, using plain `const` eliminates extra bytes. We can't use `const enum` due
* to single-file compilation restrictions.
*/
export enum NodeNavigationStep {
FirstChild = 'f',
NextSibling = 'n',
}
export type NodeNavigationStep = 'f' | 'n';
export const NODE_NAVIGATION_STEP_FIRST_CHILD = 'f';
export const NODE_NAVIGATION_STEP_NEXT_SIBLING = 'n';
/**
* Keys within serialized view data structure to represent various

View file

@ -29,6 +29,8 @@ import {
} from './error_handling';
import {
DehydratedView,
NODE_NAVIGATION_STEP_FIRST_CHILD,
NODE_NAVIGATION_STEP_NEXT_SIBLING,
NodeNavigationStep,
NODES,
REFERENCE_NODE_BODY,
@ -198,7 +200,7 @@ function stringifyNavigationInstructions(instructions: (number | NodeNavigationS
const step = instructions[i];
const repeat = instructions[i + 1] as number;
for (let r = 0; r < repeat; r++) {
container.push(step === NodeNavigationStep.FirstChild ? 'firstChild' : 'nextSibling');
container.push(step === NODE_NAVIGATION_STEP_FIRST_CHILD ? 'firstChild' : 'nextSibling');
}
}
return container.join('.');
@ -218,10 +220,10 @@ function navigateToNode(from: Node, instructions: (number | NodeNavigationStep)[
throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
}
switch (step) {
case NodeNavigationStep.FirstChild:
case NODE_NAVIGATION_STEP_FIRST_CHILD:
node = node.firstChild!;
break;
case NodeNavigationStep.NextSibling:
case NODE_NAVIGATION_STEP_NEXT_SIBLING:
node = node.nextSibling!;
break;
}
@ -279,7 +281,7 @@ export function navigateBetween(start: Node, finish: Node): NodeNavigationStep[]
// First navigate to `finish`'s parent
...parentPath,
// Then to its first child.
NodeNavigationStep.FirstChild,
NODE_NAVIGATION_STEP_FIRST_CHILD,
// And finally from that node to `finish` (maybe a no-op if we're already there).
...childPath,
];
@ -294,7 +296,7 @@ function navigateBetweenSiblings(start: Node, finish: Node): NodeNavigationStep[
const nav: NodeNavigationStep[] = [];
let node: Node | null = null;
for (node = start; node != null && node !== finish; node = node.nextSibling) {
nav.push(NodeNavigationStep.NextSibling);
nav.push(NODE_NAVIGATION_STEP_NEXT_SIBLING);
}
// If the `node` becomes `null` or `undefined` at the end, that means that we
// didn't find the `end` node, thus return `null` (which would trigger serialization

View file

@ -100,7 +100,6 @@
"NodeInjector",
"NodeInjectorDestroyRef",
"NodeInjectorFactory",
"NodeNavigationStep",
"NoneEncapsulationDomRenderer",
"NoopNgZone",
"NullInjector",

View file

@ -8,6 +8,8 @@
import {compressNodeLocation, decompressNodeLocation} from '../../src/hydration/compression';
import {
NODE_NAVIGATION_STEP_FIRST_CHILD,
NODE_NAVIGATION_STEP_NEXT_SIBLING,
NodeNavigationStep,
REFERENCE_NODE_BODY,
REFERENCE_NODE_HOST,
@ -15,8 +17,8 @@ import {
describe('compression of node location', () => {
it('should handle basic cases', () => {
const fc = NodeNavigationStep.FirstChild;
const ns = NodeNavigationStep.NextSibling;
const fc = NODE_NAVIGATION_STEP_FIRST_CHILD;
const ns = NODE_NAVIGATION_STEP_NEXT_SIBLING;
const cases = [
[[REFERENCE_NODE_HOST, fc, 1], 'hf'],
[[REFERENCE_NODE_BODY, fc, 1], 'bf'],