marko
Version:
Optimized runtime for Marko templates.
155 lines (154 loc) • 8.82 kB
TypeScript
import { types as t } from "@marko/compiler";
import { type Binding, BindingType, type Getter, type ReferencedBindings } from "./bindings";
import { type OneMany, type Opt, type SortedOpt } from "./optional";
import { type KnownExprs, type Reason } from "./reasons";
import { type Section } from "./sections";
interface ReferencedFunctionExtra extends t.FunctionExtra, ReferencedExtra {
}
export interface Read {
binding: Binding;
extra: t.NodeExtra;
inOwnBody: boolean;
getter: Getter | undefined;
comparedTo: t.Node | undefined;
deferred: boolean;
/** The outermost function holding it; none when that escapes into a call. */
fnRoot: ReferencedFunctionExtra | undefined;
}
export interface ResolvedRead {
binding: Binding;
props: Opt<string>;
inOwnBody: boolean;
getter: Getter | undefined;
/** Set for same-section local reads: the function root that owns the read. */
localFn?: ReferencedFunctionExtra;
}
declare const kReferencedBindings: unique symbol;
declare const kLazyBindings: unique symbol;
declare const kReferencedBindingsInFunction: unique symbol;
declare const kConstantBindingsInFunction: unique symbol;
declare module "@marko/compiler/dist/types" {
interface ProgramExtra {
/** An expression reads `$global`, so HTML output declares a const for it. */
hasGlobalRead?: true;
}
interface MarkoTagExtra {
/** The dom binding the tag is addressed by: its node or marker; an only
* child control flow tag shares its parent's. */
nodeBinding?: Binding;
}
interface MarkoPlaceholderExtra {
/** The dom binding the placeholder's text node is held in. */
nodeBinding?: Binding;
}
interface NodeExtra {
section?: Section;
[kReferencedBindings]?: ReferencedBindings;
[kLazyBindings]?: ReferencedBindings;
/** The bindings it derives, in the order it derives them: call sites
* derive a child template's, so no one template's order sorts them. */
derives?: Opt<Binding>;
/** The initial value of the binding it derives, which keeps it rather than
* following it, so the binding derives no sources from it. */
initialValue?: true;
/** Its value has no side effect to evaluate, so an unread one can go: an
* expression's from `evaluate`, a tag's from its value attributes. */
pure?: boolean;
/** The tag-root `KnownExprs` of the call site that linked this expression
* to a derives template's binding, for dereferencing its reasons. */
callSiteExprs?: KnownExprs;
binding?: Binding;
assignment?: Binding;
assignmentTo?: Binding;
read?: ResolvedRead;
dropped?: true;
/** The expression this node sits in: dropped or merged as one. */
exprRoot?: NodeExtra;
isEffect?: true;
/** Retained past render (a change handler, a native spread, a dynamic tag's
* input), so client code may read a value here as it is, a function too. */
retained?: true;
/** Consumed where it is written (a handler its tag attaches, an
* effect's callback, a key function), so it reaches no client as is. */
consumed?: true;
/** Any function it holds is only ever invoked, never read as a value, so
* the reads inside resolve when it runs. */
invokeOnly?: true;
/** The bindings this expression reads only by spreading them as is. */
spreadFrom?: SortedOpt<Binding>;
/** A `content` it spreads is rendered (as the element's body, or as a
* `<meta>`'s attribute), so its effect never reads it. */
rendersContent?: true;
merged?: NodeExtra;
}
interface FunctionExtra {
referencesScope?: boolean;
[kReferencedBindingsInFunction]?: ReferencedBindings;
referencedLocalBindingsInFunction?: SortedOpt<Binding>;
[kConstantBindingsInFunction]?: ReferencedBindings;
name?: string;
registerId?: string;
/** When client code reads the function itself, which registers it. */
reason?: Reason;
exportRegisterId?: string;
}
interface ArrowFunctionExpressionExtra extends FunctionExtra {
}
interface FunctionDeclarationExtra extends FunctionExtra {
}
interface FunctionExpressionExtra extends FunctionExtra {
}
}
export declare function isTagVarUsed(tag: t.NodePath<t.MarkoTag>): boolean;
export declare function trackDomVarReferences(tag: t.NodePath<t.MarkoTag>, binding: Binding): Binding | undefined;
export declare function trackVarReferences(tag: t.NodePath<t.MarkoTag>, type: BindingType, aliased?: Binding["aliasOf"]): Binding | undefined;
export declare function trackParamsReferences(body: t.NodePath<t.MarkoTagBody | t.Program>, type: BindingType): Binding | undefined;
export declare function isReferenceHoisted(bindingPath: t.NodePath, reference: t.NodePath): boolean;
export declare function assertReferencedInRender(ref: t.NodePath, name: string, markoRoot?: import("./get-root").MarkoRootPath | null): void;
export declare function setReferencesScope(path: t.NodePath<any>): void;
export declare function trackGlobalReference(path: t.NodePath<t.Identifier>): void;
export declare function mergeReferences<T extends t.Node>(section: Section, target: T, nodes: (t.Node | undefined)[]): NonNullable<T["extra"]> & ReferencedExtra;
export declare function mergeTagReferences(section: Section, tag: t.MarkoTag): t.MarkoTagExtra & t.NodeExtra & ReferencedExtra;
export declare function mergeReferenceGroup(section: Section, nodes: (t.Node | undefined)[]): ReferencedExtra;
export declare function setDerivedFrom(binding: Binding, expr: boolean | Opt<t.NodeExtra>, exprs?: KnownExprs): void;
export declare const getAssignments: () => AssignedBindingExtra[];
export declare const getReadsByExpression: () => Map<ReferencedExtra, Opt<Read>>;
export declare const getFunctionReadsByExpression: () => Map<ReferencedExtra, Map<ReferencedFunctionExtra, OneMany<Read>>>;
export declare const getReferenceFinalizers: () => (() => void)[];
export declare function onFinalizeReferences(finalize: () => void): void;
export declare function addRead(exprExtra: ReferencedExtra, extra: t.NodeExtra, binding: Binding, section: Section, getter: Getter | undefined): Read;
export declare function dropNodes(node: t.Node | t.Node[]): void;
export declare function dropExtra(exprExtra: ReferencedExtra): void;
export declare function dropContent(body: t.MarkoTagBody): void;
export declare function getAllTagReferenceNodes(tag: t.MarkoTag, referenceNodes?: t.Node[], collectAttrTag?: (attrTag: t.MarkoTag) => void): t.Node[];
export declare function createResolvedRead(binding: Binding, props: Opt<string>, inOwnBody?: boolean): ResolvedRead;
export declare function createResolvedGetterRead(binding: Binding, props: Opt<string>, getter: Getter): ResolvedRead;
export interface ReferencedExtra extends t.NodeExtra {
section: Section;
}
export declare function isReferencedExtra(extra: t.NodeExtra | undefined): extra is ReferencedExtra;
export interface AssignedBindingExtra extends ReferencedExtra {
assignment: Binding;
exprRoot: t.NodeExtra;
/** The outermost function holding it; none when that escapes into a call. */
fnRoot: ReferencedFunctionExtra | undefined;
}
export declare function hasResumableAssignment(binding: Binding): boolean;
export declare function isAssignedBindingExtra(extra: t.NodeExtra | undefined): extra is AssignedBindingExtra;
export interface RegisteredFnExtra extends ReferencedExtra, t.FunctionExtra {
exprRoot: t.NodeExtra;
name: string;
registerId: string;
reason: Reason;
}
export declare function isRegisteredFnExtra(extra: t.NodeExtra | undefined): extra is RegisteredFnExtra;
export declare function getReferencedBindings(extra: t.NodeExtra | undefined): ReferencedBindings;
export declare function getBindingsDerivedFrom(binding: Binding): ReferencedBindings;
export declare function getValueReferences(exprs: Opt<t.NodeExtra>): ReferencedBindings;
export declare function getLazyBindings(extra: t.NodeExtra | undefined): ReferencedBindings;
export declare function getReferencedBindingsInFunction(extra: t.FunctionExtra): ReferencedBindings;
export declare function getConstantBindingsInFunction(extra: t.FunctionExtra): ReferencedBindings;
export declare function setResolvedFunctionReads(extra: t.FunctionExtra, referencedBindings: ReferencedBindings, constantBindings: ReferencedBindings): void;
export declare function setResolvedReads(extra: ReferencedExtra, referencedBindings: ReferencedBindings, lazyBindings: ReferencedBindings): void;
export declare function getCanonicalExtra<T extends t.NodeExtra>(extra: T): T;
export {};