UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

1,385 lines (1,339 loc) 59.5 kB
import * as _glimmer_interfaces from '@glimmer/interfaces'; import { Nullable, Dict, BlockMetadata, SimpleNode, AnyFn, VmMachineOp, VmOp, DebugVmSnapshot, DebugRegisters, Cursor, SimpleElement, ScopeSlot, DynamicScope, Scope, Owner, ScopeBlock, RuntimeOp, EvaluationContext, VMArguments, PositionalArguments, CapturedPositionalArguments, NamedArguments, CapturedNamedArguments, BlockArguments, BlockValue, CapturedBlockArguments, CapturedArguments, AttributeOperation, AttributeCursor, TreeBuilder, Environment, AttrNamespace, Bounds, AppendingBlock, GlimmerTreeConstruction, GlimmerTreeChanges, ElementOperations, ResettableBlock, ModifierInstance, Maybe, SimpleText, SimpleDocumentFragment, SimpleComment, UpdatingVM as UpdatingVM$1, UpdatingOpcode, ExceptionHandler, DebugVmTrace, CompilableTemplate, ProgramConstants, Program, Destroyable, RenderResult, RichIteratorResult, Optional, InternalComponentManager, InternalComponentCapabilities, CurriedType, SimpleDocument, ElementNamespace, DebugRenderTree, RenderNode, CapturedRenderNode, TransactionSymbol, Transaction, ComponentInstanceWithCreate, EnvironmentOptions, RuntimeArtifacts, ClassicResolver, RuntimeOptions, Arguments, ComponentDefinitionState, TemplateIterator, CompilableProgram } from '@glimmer/interfaces'; import { Reference, OpaqueIterationItem, OpaqueIterator } from '@glimmer/reference'; import { MachineRegister, SyscallRegister, Register } from '@glimmer/vm'; import { Tag, Cache } from '@glimmer/validator'; import { Stack } from '@glimmer/util'; export { destroy, isDestroyed, isDestroying, registerDestructor } from '@glimmer/destroyable'; declare const OPERAND_TYPES: readonly ["imm/u32", "imm/i32", "imm/bool", "imm/u32{todo}", "imm/i32{todo}", "imm/enum<curry>", "imm/block:handle", "imm/pc", "handle", "handle/block", "const/i32[]", "const/str?", "const/any[]", "const/str[]?", "const/bool", "const/fn", "const/any", "const/primitive", "const/definition", "register", "register/instruction", "register/stack", "register/sN", "register/tN", "register/v0", "variable", "instruction/relative"]; type OPERAND_TYPE = (typeof OPERAND_TYPES)[number]; type NonNullableOperandType = Exclude<OPERAND_TYPE, `${string}?`>; type NullableOperandType = Extract<OPERAND_TYPE, `${string}?`> extends `${infer S}?` ? S : never; type OperandType = NonNullableOperandType | NullableOperandType | `${NullableOperandType}?`; interface NormalizedOperand { type: OperandType; name: string; } type Primitive = undefined | null | boolean | number | string; type RegisterName = '$pc' | '$ra' | '$fp' | '$sp' | '$s0' | '$s1' | '$t0' | '$t1' | '$v0' | `$bug${number}`; type Expand<T> = T extends infer O ? { [K in keyof O]: O[K]; } : never; type DefineOperand<T extends string, V, Options = undefined> = undefined extends Options ? readonly [type: T, value: V] : readonly [type: T, value: V, options: Options]; type DefineNullableOperand<T extends string, V, Options = undefined> = Options extends undefined ? readonly [type: T, value: V] | readonly [type: T, value: Nullable<V>, options: { nullable: true; }] | readonly [type: T, value: V, options: { nullable?: false; }] : readonly [type: T, value: Nullable<V>, options: Expand<Options & { nullable: true; }>] | readonly [type: T, value: V, options: Expand<Options & { nullable?: false; }>] | readonly [type: T, value: V, options: Options]; /** * A dynamic operand has a value that can't be easily represented as an embedded string. */ type RawDynamicDisassembledOperand = DefineOperand<'dynamic', unknown> | DefineOperand<'constant', number> | DefineNullableOperand<'array', unknown[]> | DefineOperand<'variable', number, { name?: string | null; }>; type RawStaticDisassembledOperand = DefineOperand<'error:operand', number, { label: NormalizedOperand; }> | DefineOperand<'error:opcode', number, { kind: number; }> | DefineOperand<'number', number> | DefineOperand<'boolean', boolean> | DefineOperand<'primitive', Primitive> | DefineOperand<'register', RegisterName> | DefineOperand<'instruction', number> | DefineOperand<'enum<curry>', 'component' | 'helper' | 'modifier'> | DefineOperand<'array', number[], { kind: typeof Number; }> | DefineNullableOperand<'array', string[], { kind: typeof String; }> /** * A variable is a numeric offset into the stack (relative to the $fp register). */ | DefineNullableOperand<'string', string>; type RawDisassembledOperand = RawStaticDisassembledOperand | RawDynamicDisassembledOperand; type ObjectForRaw<R> = R extends RawDisassembledOperand ? R[2] extends undefined ? { type: R[0]; value: R[1]; options?: R[2]; } : { type: R[0]; value: R[1]; options: R[2]; } : never; type StaticDisassembledOperand = ObjectForRaw<RawStaticDisassembledOperand> & { isDynamic: false; }; type DynamicDisassembledOperand = ObjectForRaw<RawDynamicDisassembledOperand> & { isDynamic: true; }; type SomeDisassembledOperand = StaticDisassembledOperand | DynamicDisassembledOperand; interface DebugOp { name: string; params: Dict<SomeDisassembledOperand>; meta: BlockMetadata | null; } /** * A Loggable is either: * * 1. a single log line * 2. a log line as a header followed by a group of log entries */ type Loggable = [LogLine, ...LogEntry[]]; type LogEntry = LogLine | LogGroup; /** * LogLine represents a single line in the log. The line is logged *either* by passing the `line` * values to `console.{log,info,debug,warn,error}` *or* by passing them to `console.group` to * represent the header of a group. */ interface LogLine { readonly type: 'line'; readonly line: unknown[]; } /** * LogGroup represents a group of log entries. It is logged by calling *either* `console.group` or * `console.groupCollapsed` (depending on the value of `collapsed`). */ interface LogGroup { type: 'group'; collapsed: boolean; heading: unknown[]; children: LogEntry[]; } declare const STYLES: { readonly var: "color: grey"; readonly varReference: "color: blue; text-decoration: underline"; readonly varBinding: "color: blue;"; readonly specialVar: "color: blue"; readonly prop: "color: grey"; readonly specialProp: "color: red"; readonly token: "color: green"; readonly def: "color: blue"; readonly builtin: "color: blue"; readonly punct: "color: GrayText"; readonly kw: "color: rgb(185 0 99 / 100%);"; readonly type: "color: teal"; readonly number: "color: blue"; readonly string: "color: red"; readonly null: "color: grey"; readonly specialString: "color: darkred"; readonly atom: "color: blue"; readonly attrName: "color: orange"; readonly attrValue: "color: blue"; readonly boolean: "color: blue"; readonly comment: "color: green"; readonly meta: "color: grey"; readonly register: "color: purple"; readonly constant: "color: purple"; readonly dim: "color: grey"; readonly internals: "color: lightgrey; font-style: italic"; readonly diffAdd: "color: Highlight"; readonly diffDelete: "color: SelectedItemText; background-color: SelectedItem"; readonly diffChange: "color: MarkText; background-color: Mark"; readonly sublabel: "font-style: italic; color: grey"; readonly error: "color: red"; readonly label: "text-decoration: underline"; readonly errorLabel: "color: darkred; font-style: italic"; readonly errorMessage: "color: darkred; text-decoration: underline"; readonly stack: "color: grey; font-style: italic"; readonly unbold: "font-weight: normal"; readonly pointer: "background-color: lavender; color: indigo"; readonly pointee: "background-color: lavender; color: indigo"; readonly focus: "font-weight: bold"; readonly focusColor: "background-color: lightred; color: darkred"; }; type StyleName = keyof typeof STYLES; type IntoFormat = { style: string; } | StyleName; interface AbstractLeafFragment { readonly value: unknown; readonly style?: string | undefined; readonly subtle?: boolean; } /** * A leaf fragment that represents an arbitrary value. * * When the value is a primitive, the fragment is appended to the buffer as if it was an instance of * the appropriate leaf fragment type (e.g. strings are appended as if they were `StringFragment`). * * Otherwise, `ValueFragment` is appended to the current line as a footnote reference and the value * itself is appended to a later line that *defines* the footnote using the `%O` format specifier. */ interface ValueFragment extends AbstractLeafFragment { readonly kind: 'value'; readonly value: unknown; /** * The `ValueFragment` is appended to the current line as a footnote reference (e.g. `[1]`) and * the value itself is appended to a later line that *defines* the footnote (e.g. `[1] * ObjectHere`). * * By default, the footnote reference is an incrementing number per log line, and the footnote * value is formatted using the `%O` format specifier. * * The `display` property can be provided to override these defaults. */ readonly display?: { ref: string; footnote?: Fragment | undefined; } | { inline: Fragment; } | undefined; } /** * A leaf fragment that represents a string value. * * Corresponds to the `%s` format specifier. */ interface StringFragment extends AbstractLeafFragment { readonly kind: 'string'; readonly value: string; } /** * A leaf fragment that represents an integer value. * * Corresponds to the `%d` format specifier. */ interface IntegerFragment extends AbstractLeafFragment { readonly kind: 'integer'; readonly value: number; } /** * A leaf fragment that represents a float value. * * Corresponds to the `%f` format specifier. */ interface FloatFragment extends AbstractLeafFragment { readonly kind: 'float'; readonly value: number; } /** * A leaf fragment that represents a DOM node. * * Corresponds to the `%o` format specifier. */ interface SpecialFragment extends AbstractLeafFragment { readonly kind: 'special'; readonly value: SimpleNode | Node | AnyFn | unknown[]; } /** * The list of leaf fragment types correspond exactly to the list of console.log * format specifiers. */ type LeafFragmentType = StringFragment | IntegerFragment | FloatFragment | ValueFragment | SpecialFragment; type FragmentType = LeafFragmentType | { kind: 'multi'; value: LeafFragment[]; }; type LeafFragment = Fragment<LeafFragmentType>; interface DisplayFragmentOptions { readonly showSubtle: boolean; } type FlushedLines = [LogLine, ...LogEntry[]]; /** * The `LogFragmentBuffer` is responsible for collecting the fragments that are logged to the * `DebugLogger` so that they can be accumulated during a group and flushed together. * * This queuing serves two purposes: * * 1. To allow the individual fragments that make up a single line to append their values to * the current line. To accomplish this, each fragment can append static content and its * formatting specifier (e.g. `%o`) to the accumulated {@link #template} *and* append the * value to format to the {@link #substitutions} array. * 2. To allow logs that refer to objects to be represented as footnotes in the current line, * with the footnote to be printed in a later line. * * This allows a list of fragments, each of which represent formattable values, to be flattened * into a single template string and an array of values to format. * * ## Footnotes * * An opcode slice containing constant references will be logged like this: * * ``` * ... * 362. (PushArgs names=[] block-names=[] flags=16) * 366. (Helper helper=[0]) * [0] glimmerHelper() * 368. (PopFrame) * 369. (Fetch register=$v0) * 371. (Primitive constant="/index.html") * ... * ``` * * The fragment for line `366` includes an `ObjectFragment` for the helper value. When logged, * the object will be represented as a footnote and the value will be printed in a later * line. */ declare class LogFragmentBuffer { #private; constructor(options: DisplayFragmentOptions); /** * Add a footnoted value to the current buffer. * * If the `subtle` option is set, the fragment will only be printed if the buffer is configured * to show subtle content. * * This method takes two callbacks: `add` and `append`. * * The `append` callback behaves like {@linkcode append}, but without the `subtle` argument. If * `addFootnoted` is called with `subtle: false`, then the callback will never be called, so * there is no need to pass the `subtle` argument again. * * The `add` callback is responsible for appending the footnote itself to the buffer. The first * parameter to `add` (`useNumber`) specifies whether the caller has used the footnote number * to refer to the footnote. * * This is typically true, but fragments can specify an alternative annotation that should be used * instead of the default footnote number. In that case, the footnote number is not used, and the * next footnote is free to use it. * * The `add` callback also takes a template string and an optional list of substitutions, which * describe the way the footnote itself should be formatted. */ addFootnoted(subtle: boolean, add: (footnote: { n: number; style: string; }, child: LogFragmentBuffer) => boolean): void; /** * Append a fragment to the current buffer. * * If the `subtle` option is set, the fragment will only be printed if the buffer is configured * to show subtle content. */ append(subtle: boolean, template: string, ...substitutions: unknown[]): void; flush(): FlushedLines; } /** * @import { StyleName } from './styles'; */ /** * Fragment is the most fundamental building block of the debug logger. * */ declare class Fragment<T extends FragmentType = FragmentType> { #private; static integer(this: void, value: number, options?: Omit<IntegerFragment, 'kind' | 'value'>): Fragment<IntegerFragment>; static float(this: void, value: number, options?: Omit<FloatFragment, 'kind' | 'value'>): Fragment<FloatFragment>; static string(this: void, value: string, options?: Omit<StringFragment, 'kind' | 'value'>): Fragment<StringFragment>; static special(this: void, value: Node | SimpleNode | AnyFn | unknown[], options?: Omit<SpecialFragment, 'kind' | 'value'>): Fragment<SpecialFragment>; constructor(type: T); /** * A subtle fragment is only printed if the `showSubtle` option is set. * * Returns true if this fragment is a subtle leaf or is a multi fragment * with all subtle leaves. */ isSubtle(): boolean; /** * If the current fragment is not empty, apply `ifPresent` to the current * fragment. Otherwise, do nothing. * * If the current fragment is subtle, the result is also subtle. */ map(ifPresent: (value: Fragment) => Fragment): Fragment; /** * A fragment is empty if it should not be printed with the provided display options. * * This means that if a fragment is subtle and `showSubtle` is false, the fragment is empty. */ isEmpty(options?: DisplayFragmentOptions): boolean; /** * Returns an array of {@linkcode LeafFragment}s that make up the current * fragment. * * This effectively flattens any number of nested multi-fragments into a flat array of leaf * fragments. */ leaves(): LeafFragment[]; /** * Returns a fragment with the specified subtle status without mutating the current fragment. * * If `isSubtle` is true, the fragment will also be styled with the `subtle` style. */ subtle(isSubtle?: boolean): Fragment<T>; /** * Apply the specified styles to the current fragment (if it's a leaf) or all * of its children (if it's a multi-fragment). * * Keep in mind that merging styles might be very difficult to undo, so treat * this as a low-level operation, and prefer to use higher-level concepts like * `subtle` if you can instead. */ styleAll(...allFormats: IntoFormat[]): Fragment<T>; /** * Convert the current fragment into a string with no additional formatting. * The primary purpose for this method is to support converting a fragment * into a string for inclusion in thrown Errors. If you're going to *log* * a fragment, log it using `DebugLogger` and don't convert it to * a string first. */ stringify(options: DisplayFragmentOptions): string; /** * Convert this fragment into a Loggable for logging through the `DebugLogger`. */ toLoggable(options: DisplayFragmentOptions): Loggable; /** * Append this fragment to the low-level `LogFragmentBuffer`. */ appendTo(buffer: LogFragmentBuffer): void; } interface RuntimeOpSnapshot { type: VmMachineOp | VmOp; isMachine: 0 | 1; size: number; } declare class VmSnapshot { #private; constructor(opcode: RuntimeOpSnapshot, snapshot: DebugVmSnapshot); diff(other: VmSnapshot): VmDiff; } type GetRegisterDiffs<D extends DebugRegisters> = { [P in keyof D]: VmSnapshotValueDiff<P, D[P]>; }; type RegisterDiffs = GetRegisterDiffs<DebugRegisters>; declare class VmDiff { readonly opcode: RuntimeOpSnapshot; readonly registers: RegisterDiffs; readonly stack: VmSnapshotArrayDiff<'stack', unknown[]>; readonly blocks: VmSnapshotArrayDiff<'blocks', object[]>; readonly cursors: VmSnapshotArrayDiff<'cursors', Cursor[]>; readonly constructing: VmSnapshotValueDiff<'constructing', Nullable<SimpleElement>>; readonly destructors: VmSnapshotArrayDiff<'destructors', object[]>; readonly scope: VmSnapshotArrayDiff<'scope', ScopeSlot[]>; constructor(opcode: RuntimeOpSnapshot, before: DebugVmSnapshot, after: DebugVmSnapshot); } declare class VmSnapshotArrayDiff<N extends string | number, T extends unknown[]> { readonly name: N; readonly before: T; readonly after: T; readonly change: boolean | 'reset'; constructor(name: N, before: T, after: T, change?: boolean | 'reset'); describe(): Fragment; } declare class VmSnapshotValueDiff<N extends string | number, T> { readonly name: N; readonly before: T; readonly after: T; readonly didChange: boolean; constructor(name: N, before: T, after: T); describe(): Fragment; } declare class DynamicScopeImpl implements DynamicScope { private bucket; constructor(bucket?: Dict<Reference>); get(key: string): Reference; set(key: string, reference: Reference): Reference; child(): DynamicScopeImpl; } interface ScopeOptions { /** @default {UNDEFINED_REFERENCE} */ self: Reference; /** @default {0} */ size?: number | undefined; } declare class ScopeImpl implements Scope { static root(owner: Owner, { self, size }: ScopeOptions): Scope; static sized(owner: Owner, size?: number): Scope; readonly owner: Owner; private slots; private callerScope; constructor(owner: Owner, slots: Array<ScopeSlot>, callerScope: Nullable<Scope>); init({ self }: { self: Reference; }): this; /** * @debug */ snapshot(): ScopeSlot[]; getSelf(): Reference; getSymbol(symbol: number): Reference; getBlock(symbol: number): Nullable<ScopeBlock>; bind(symbol: number, value: ScopeSlot): void; bindSelf(self: Reference): void; bindSymbol(symbol: number, value: Reference): void; bindBlock(symbol: number, value: Nullable<ScopeBlock>): void; bindCallerScope(scope: Nullable<Scope>): void; getCallerScope(): Nullable<Scope>; child(): Scope; private get; private set; } type LowLevelRegisters = [$pc: number, $ra: number, $sp: number, $fp: number]; interface VmStack { readonly registers: LowLevelRegisters; push(value: unknown): void; get(position: number): number; pop<T>(): T; snapshot?(): unknown[]; } interface Externs { debugBefore: (opcode: RuntimeOp) => DebugState; debugAfter: (state: DebugState) => void; } declare class LowLevelVM { stack: VmStack; externs: Externs | undefined; currentOpSize: number; readonly registers: LowLevelRegisters; readonly context: EvaluationContext; constructor(stack: VmStack, context: EvaluationContext, externs: Externs | undefined, registers: LowLevelRegisters); fetchRegister(register: MachineRegister): number; loadRegister(register: MachineRegister, value: number): void; setPc(pc: number): void; pushFrame(): void; popFrame(): void; pushSmallFrame(): void; popSmallFrame(): void; goto(offset: number): void; target(offset: number): number; call(handle: number): void; returnTo(offset: number): void; return(): void; nextStatement(): Nullable<RuntimeOp>; evaluateOuter(opcode: RuntimeOp, vm: VM): void; evaluateInner(opcode: RuntimeOp, vm: VM): void; evaluateMachine(opcode: RuntimeOp, vm: VM): undefined; evaluateSyscall(opcode: RuntimeOp, vm: VM): void; } interface EvaluationStack { readonly registers: LowLevelRegisters; push(value: unknown): void; dup(position?: number): void; copy(from: number, to: number): void; pop<T>(n?: number): T; peek<T>(offset?: number): T; get<T>(offset: number, base?: number): T; set(value: unknown, offset: number, base?: number): void; slice<T = unknown>(start: number, end: number): T[]; capture(items: number): unknown[]; reset(): void; snapshot?(): unknown[]; } declare class VMArgumentsImpl implements VMArguments { private stack; positional: PositionalArgumentsImpl; named: NamedArgumentsImpl; blocks: BlockArgumentsImpl; constructor(); empty(stack: EvaluationStack): this; setup(stack: EvaluationStack, names: readonly string[], blockNames: readonly string[], positionalCount: number, atNames: boolean): void; get base(): number; get length(): number; at(pos: number): Reference; realloc(offset: number): void; capture(): CapturedArguments; clear(): void; } declare class PositionalArgumentsImpl implements PositionalArguments { base: number; length: number; private stack; private _references; constructor(); empty(stack: EvaluationStack, base: number): void; setup(stack: EvaluationStack, base: number, length: number): void; at(position: number): Reference; capture(): CapturedPositionalArguments; prepend(other: Reference[]): void; private get references(); } declare class NamedArgumentsImpl implements NamedArguments { base: number; length: number; private stack; private _references; private _names; private _atNames; constructor(); empty(stack: EvaluationStack, base: number): void; setup(stack: EvaluationStack, base: number, length: number, names: readonly string[], atNames: boolean): void; get names(): readonly string[]; get atNames(): readonly string[]; has(name: string): boolean; get(name: string, atNames?: boolean): Reference; capture(): CapturedNamedArguments; merge(other: Record<string, Reference>): void; private get references(); private toSyntheticName; private toAtName; } declare class BlockArgumentsImpl implements BlockArguments { private stack; private internalValues; private _symbolNames; internalTag: Nullable<Tag>; names: readonly string[]; length: number; base: number; constructor(); empty(stack: EvaluationStack, base: number): void; setup(stack: EvaluationStack, base: number, length: number, names: readonly string[]): void; get values(): readonly BlockValue[]; has(name: string): boolean; get(name: string): Nullable<ScopeBlock>; capture(): CapturedBlockArguments; get symbolNames(): readonly string[]; } declare function createCapturedArgs(named: Dict<Reference>, positional: Reference[]): CapturedArguments; declare function reifyNamed(named: CapturedNamedArguments): Dict<unknown>; declare function reifyPositional(positional: CapturedPositionalArguments): unknown[]; declare function reifyArgs(args: CapturedArguments): { named: Dict<unknown>; positional: unknown[]; }; declare const EMPTY_NAMED: CapturedNamedArguments; declare const EMPTY_POSITIONAL: CapturedPositionalArguments; declare const EMPTY_ARGS: CapturedArguments; declare function dynamicAttribute(element: SimpleElement, attr: string, namespace: Nullable<AttrNamespace>, isTrusting?: boolean): DynamicAttribute; declare abstract class DynamicAttribute implements AttributeOperation { attribute: AttributeCursor; constructor(attribute: AttributeCursor); abstract set(dom: TreeBuilder, value: unknown, env: Environment): void; abstract update(value: unknown, env: Environment): void; } declare class SimpleDynamicAttribute extends DynamicAttribute { set(dom: TreeBuilder, value: unknown, _env: Environment): void; update(value: unknown, _env: Environment): void; } declare class CursorImpl implements Cursor { element: SimpleElement; nextSibling: Nullable<SimpleNode>; constructor(element: SimpleElement, nextSibling: Nullable<SimpleNode>); } declare class ConcreteBounds implements Bounds { parentNode: SimpleElement; private first; private last; constructor(parentNode: SimpleElement, first: SimpleNode, last: SimpleNode); parentElement(): SimpleElement; firstNode(): SimpleNode; lastNode(): SimpleNode; } declare function clear(bounds: Bounds): Nullable<SimpleNode>; interface FirstNode { debug?: { first: () => Nullable<SimpleNode>; }; firstNode(): SimpleNode; } interface LastNode { debug?: { last: () => Nullable<SimpleNode>; }; lastNode(): SimpleNode; } declare class NewTreeBuilder implements TreeBuilder { debug?: () => { blocks: AppendingBlock[]; constructing: Nullable<SimpleElement>; cursors: Cursor[]; }; dom: GlimmerTreeConstruction; updateOperations: GlimmerTreeChanges; constructing: Nullable<SimpleElement>; operations: Nullable<ElementOperations>; private env; readonly cursors: Stack<Cursor>; private modifierStack; private blockStack; static forInitialRender(env: Environment, cursor: CursorImpl): NewTreeBuilder; static resume(env: Environment, block: ResettableBlock): NewTreeBuilder; constructor(env: Environment, parentNode: SimpleElement, nextSibling: Nullable<SimpleNode>); protected initialize(): this; debugBlocks(): AppendingBlock[]; get element(): SimpleElement; get nextSibling(): Nullable<SimpleNode>; get hasBlocks(): boolean; protected block(): AppendingBlock; popElement(): void; pushAppendingBlock(): AppendingBlock; pushResettableBlock(): ResettableBlockImpl; pushBlockList(list: AppendingBlock[]): AppendingBlockList; protected pushBlock<T extends AppendingBlock>(block: T, isRemote?: boolean): T; popBlock(): AppendingBlock; __openBlock(): void; __closeBlock(): void; openElement(tag: string): SimpleElement; __openElement(tag: string): SimpleElement; flushElement(modifiers: Nullable<ModifierInstance[]>): void; __flushElement(parent: SimpleElement, constructing: SimpleElement): void; closeElement(): Nullable<ModifierInstance[]>; pushRemoteElement(element: SimpleElement, guid: string, insertBefore: Maybe<SimpleNode>): RemoteBlock; __pushRemoteElement(element: SimpleElement, _guid: string, insertBefore: Maybe<SimpleNode>): RemoteBlock; popRemoteElement(): RemoteBlock; protected pushElement(element: SimpleElement, nextSibling?: Maybe<SimpleNode>): void; private pushModifiers; private popModifiers; didAppendBounds(bounds: Bounds): Bounds; didAppendNode<T extends SimpleNode>(node: T): T; didOpenElement(element: SimpleElement): SimpleElement; willCloseElement(): void; appendText(string: string): SimpleText; __appendText(text: string): SimpleText; __appendNode(node: SimpleNode): SimpleNode; __appendFragment(fragment: SimpleDocumentFragment): Bounds; __appendHTML(html: string): Bounds; appendDynamicHTML(value: string): void; appendDynamicText(value: string): SimpleText; appendDynamicFragment(value: SimpleDocumentFragment): void; appendDynamicNode(value: SimpleNode): void; private trustedContent; private untrustedContent; appendComment(string: string): SimpleComment; __appendComment(string: string): SimpleComment; __setAttribute(name: string, value: string, namespace: Nullable<AttrNamespace>): void; __setProperty(name: string, value: unknown): void; setStaticAttribute(name: string, value: string, namespace: Nullable<AttrNamespace>): void; setDynamicAttribute(name: string, value: unknown, trusting: boolean, namespace: Nullable<AttrNamespace>): DynamicAttribute; } declare class AppendingBlockImpl implements AppendingBlock { private parent; debug?: { first: () => Nullable<SimpleNode>; last: () => Nullable<SimpleNode>; }; protected first: Nullable<FirstNode>; protected last: Nullable<LastNode>; protected nesting: number; constructor(parent: SimpleElement); parentElement(): SimpleElement; firstNode(): SimpleNode; lastNode(): SimpleNode; openElement(element: SimpleElement): void; closeElement(): void; didAppendNode(node: SimpleNode): void; didAppendBounds(bounds: Bounds): void; finalize(stack: TreeBuilder): void; } declare class RemoteBlock extends AppendingBlockImpl { constructor(parent: SimpleElement); } declare class ResettableBlockImpl extends AppendingBlockImpl implements ResettableBlock { constructor(parent: SimpleElement); reset(): Nullable<SimpleNode>; } declare class AppendingBlockList implements AppendingBlock { private readonly parent; boundList: AppendingBlock[]; constructor(parent: SimpleElement, boundList: AppendingBlock[]); parentElement(): SimpleElement; firstNode(): SimpleNode; lastNode(): SimpleNode; openElement(_element: SimpleElement): void; closeElement(): void; didAppendNode(_node: SimpleNode): void; didAppendBounds(_bounds: Bounds): void; finalize(_stack: TreeBuilder): void; } declare function clientBuilder(env: Environment, cursor: CursorImpl): TreeBuilder; declare class UpdatingVM implements UpdatingVM$1 { env: Environment; dom: GlimmerTreeChanges; alwaysRevalidate: boolean; private frameStack; constructor(env: Environment, { alwaysRevalidate }: { alwaysRevalidate?: boolean | undefined; }); execute(opcodes: UpdatingOpcode[], handler: ExceptionHandler): void; private _execute; private get frame(); goto(index: number): void; try(ops: UpdatingOpcode[], handler: Nullable<ExceptionHandler>): void; throw(): void; } declare abstract class BlockOpcode implements UpdatingOpcode, Bounds { protected state: Closure; protected context: EvaluationContext; children: UpdatingOpcode[]; protected readonly bounds: AppendingBlock; constructor(state: Closure, context: EvaluationContext, bounds: AppendingBlock, children: UpdatingOpcode[]); parentElement(): _glimmer_interfaces.SimpleElement; firstNode(): _glimmer_interfaces.SimpleNode; lastNode(): _glimmer_interfaces.SimpleNode; evaluate(vm: UpdatingVM): void; } declare class TryOpcode extends BlockOpcode implements ExceptionHandler { type: string; protected bounds: ResettableBlock; evaluate(vm: UpdatingVM): void; handleException(): void; } declare class ListItemOpcode extends TryOpcode { key: unknown; memo: Reference; value: Reference; retained: boolean; index: number; constructor(state: Closure, context: EvaluationContext, bounds: ResettableBlock, key: unknown, memo: Reference, value: Reference); shouldRemove(): boolean; reset(): void; } declare class VM { #private; readonly args: VMArgumentsImpl; readonly lowlevel: LowLevelVM; readonly debug?: () => DebugVmSnapshot; readonly trace?: () => DebugVmTrace; get stack(): EvaluationStack; get pc(): number; /** * Fetch a value from a syscall register onto the stack. * * ## Opcodes * * - Append: `Fetch` * * ## State changes * * [!] push Eval Stack <- $register */ fetch(register: SyscallRegister): void; /** * Load a value from the stack into a syscall register. * * ## Opcodes * * - Append: `Load` * * ## State changes * * [!] pop Eval Stack -> `value` * [$] $register <- `value` */ load(register: SyscallRegister): void; /** * Load a value into a syscall register. * * ## State changes * * [$] $register <- `value` * * @utility */ loadValue<T>(register: SyscallRegister, value: T): void; /** * Fetch a value from a register (machine or syscall). * * ## State changes * * [ ] get $register * * @utility */ fetchValue(register: MachineRegister): number; fetchValue<T>(register: Register): T; call(handle: number | null): void; return(): void; readonly context: EvaluationContext; constructor({ scope, dynamicScope, stack, pc }: ClosureState, context: EvaluationContext, tree: TreeBuilder); static initial(context: EvaluationContext, options: InitialVmState): VM; compile(block: CompilableTemplate): number; get constants(): ProgramConstants; get program(): Program; get env(): Environment; private captureClosure; capture(args: number, pc?: number): Closure; /** * ## Opcodes * * - Append: `BeginComponentTransaction` * * ## State Changes * * [ ] create `guard` (`JumpIfNotModifiedOpcode`) * [ ] create `tracker` (`BeginTrackFrameOpcode`) * [!] push Updating Stack <- `guard` * [!] push Updating Stack <- `tracker` * [!] push Cache Stack <- `guard` * [!] push Tracking Stack */ beginCacheGroup(name?: string): void; /** * ## Opcodes * * - Append: `CommitComponentTransaction` * * ## State Changes * * Create a new `EndTrackFrameOpcode` (`end`) * * [!] pop CacheStack -> `guard` * [!] pop Tracking Stack -> `tag` * [ ] create `end` (`EndTrackFrameOpcode`) with `guard` * [-] consume `tag` */ commitCacheGroup(): void; /** * ## Opcodes * * - Append: `Enter` * * ## State changes * * [!] push Element Stack as `block` * [ ] create `try` (`TryOpcode`) with `block`, capturing `args` from the Eval Stack * * Did Enter (`try`): * [-] associate destroyable `try` * [!] push Destroyable Stack <- `try` * [!] push Updating List <- `try` * [!] push Updating Stack <- `try.children` */ enter(args: number): void; /** * ## Opcodes * * - Append: `Iterate` * - Update: `ListBlock` * * ## State changes * * Create a new ref for the iterator item (`value`). * Create a new ref for the iterator key (`key`). * * [ ] create `valueRef` (`Reference`) from `value` * [ ] create `keyRef` (`Reference`) from `key` * [!] push Eval Stack <- `valueRef` * [!] push Eval Stack <- `keyRef` * [!] push Element Stack <- `UpdatableBlock` as `block` * [ ] capture `closure` with *2* items from the Eval Stack * [ ] create `iteration` (`ListItemOpcode`) with `closure`, `block`, `key`, `keyRef` and `valueRef` * * Did Enter (`iteration`): * [-] associate destroyable `iteration` * [!] push Destroyable Stack <- `iteration` * [!] push Updating List <- `iteration` * [!] push Updating Stack <- `iteration.children` */ enterItem({ key, value, memo }: OpaqueIterationItem): ListItemOpcode; registerItem(opcode: ListItemOpcode): void; /** * ## Opcodes * * - Append: `EnterList` * * ## State changes * * [ ] capture `closure` with *0* items from the Eval Stack, and `$pc` from `offset` * [ ] create `updating` (empty `Array`) * [!] push Element Stack <- `list` (`BlockList`) with `updating` * [ ] create `list` (`ListBlockOpcode`) with `closure`, `list`, `updating` and `iterableRef` * [!] push List Stack <- `list` * * Did Enter (`list`): * [-] associate destroyable `list` * [!] push Destroyable Stack <- `list` * [!] push Updating List <- `list` * [!] push Updating Stack <- `list.children` */ enterList(iterableRef: Reference<OpaqueIterator>, offset: number): void; /** * ## Opcodes * * - Append: `Enter` * - Append: `Iterate` * - Append: `EnterList` * - Update: `ListBlock` * * ## State changes * * [-] associate destroyable `opcode` * [!] push Destroyable Stack <- `opcode` * [!] push Updating List <- `opcode` * [!] push Updating Stack <- `opcode.children` * */ private didEnter; /** * ## Opcodes * * - Append: `Exit` * - Append: `ExitList` * * ## State changes * * [!] pop Destroyable Stack * [!] pop Element Stack * [!] pop Updating Stack */ exit(): void; /** * ## Opcodes * * - Append: `ExitList` * * ## State changes * * Pop List: * [!] pop Destroyable Stack * [!] pop Element Stack * [!] pop Updating Stack * * [!] pop List Stack */ exitList(): void; /** * ## Opcodes * * - Append: `RootScope` * - Append: `VirtualRootScope` * * ## State changes * * [!] push Scope Stack */ pushRootScope(size: number, owner: Owner): Scope; /** * ## Opcodes * * - Append: `ChildScope` * * ## State changes * * [!] push Scope Stack <- `child` of current Scope */ pushChildScope(): void; /** * ## Opcodes * * - Append: `Yield` * * ## State changes * * [!] push Scope Stack <- `scope` */ pushScope(scope: Scope): void; /** * ## Opcodes * * - Append: `PopScope` * * ## State changes * * [!] pop Scope Stack */ popScope(): void; /** * ## Opcodes * * - Append: `PushDynamicScope` * * ## State changes: * * [!] push Dynamic Scope Stack <- child of current Dynamic Scope */ pushDynamicScope(): DynamicScope; /** * ## Opcodes * * - Append: `BindDynamicScope` * * ## State changes: * * [!] pop Dynamic Scope Stack `names.length` times */ bindDynamicScope(names: string[]): void; /** * ## State changes * * - [!] push Updating Stack * * @utility */ pushUpdating(list?: UpdatingOpcode[]): void; /** * ## State changes * * [!] pop Updating Stack * * @utility */ popUpdating(): UpdatingOpcode[]; /** * ## State changes * * [!] push Updating List * * @utility */ updateWith(opcode: UpdatingOpcode): void; private listBlock; /** * ## State changes * * [-] associate destroyable `child` * * @utility */ associateDestroyable(child: Destroyable): void; private updating; /** * Get Tree Builder */ tree(): TreeBuilder; /** * Get current Scope */ scope(): Scope; /** * Get current Dynamic Scope */ dynamicScope(): DynamicScope; popDynamicScope(): void; getOwner(): Owner; getSelf(): Reference<any>; referenceForSymbol(symbol: number): Reference; execute(initialize?: (vm: this) => void): RenderResult; private _execute; next(): RichIteratorResult<null, RenderResult>; } interface InitialVmState { /** * The address of the compiled template. This is converted into a * pc when the VM is created. */ handle: number; /** * Optionally, specify the root scope for the VM. If not specified, * the VM will use a root scope with no `this` reference and no * symbols. */ scope?: ScopeOptions; /** * */ tree: TreeBuilder; dynamicScope: DynamicScope; owner: Owner; } interface ClosureState { /** * The program counter that subsequent evaluations should start from. */ readonly pc: number; /** * The current value of the VM's scope (which changes whenever a component is invoked or a block * with block params is entered). */ readonly scope: Scope; /** * The current value of the VM's dynamic scope */ readonly dynamicScope: DynamicScope; /** * A number of stack elements captured during the initial evaluation, and which should be restored * to the stack when the block is re-evaluated. */ readonly stack: unknown[]; } /** * A closure captures the state of the VM for a particular block of code that is necessary to * re-invoke the block in the future. * * In practice, this allows us to clear the previous render and "replay" the block's execution, * rendering content in the same position as the first render. */ declare class Closure { private state; private context; constructor(state: ClosureState, context: EvaluationContext); evaluate(tree: TreeBuilder): VM; } type DebugState = { opcode: { type: VmMachineOp | VmOp; isMachine: 0 | 1; size: number; }; closeGroup?: undefined | (() => void); params?: Optional<Dict<SomeDisassembledOperand>>; op?: Optional<DebugOp>; debug: DebugVmSnapshot; snapshot: VmSnapshot; }; type DebugGet = (path: string) => unknown; type DebugCallback = (context: unknown, get: DebugGet) => void; declare function setDebuggerCallback(cb: DebugCallback): void; declare function resetDebuggerCallback(): void; declare class TemplateOnlyComponentManager implements InternalComponentManager { getCapabilities(): InternalComponentCapabilities; getDebugName({ name }: TemplateOnlyComponentDefinition): string; getSelf(): Reference; getDestroyable(): null; } declare const TEMPLATE_ONLY_COMPONENT_MANAGER: TemplateOnlyComponentManager; declare class TemplateOnlyComponentDefinition { moduleName: string; name: string; constructor(moduleName?: string, name?: string); toString(): string; } /** This utility function is used to declare a given component has no backing class. When the rendering engine detects this it is able to perform a number of optimizations. Templates that are associated with `templateOnly()` will be rendered _as is_ without adding a wrapping `<div>` (or any of the other element customization behaviors of [@ember/component](/ember/release/classes/Component)). Specifically, this means that the template will be rendered as "outer HTML". In general, this method will be used by build time tooling and would not be directly written in an application. However, at times it may be useful to use directly to leverage the "outer HTML" semantics mentioned above. For example, if an addon would like to use these semantics for its templates but cannot be certain it will only be consumed by applications that have enabled the `template-only-glimmer-components` optional feature. @example ```js import { templateOnlyComponent } from '@glimmer/runtime'; export default templateOnlyComponent(); ``` @public @method templateOnly @param {String} moduleName the module name that the template only component represents, this will be used for debugging purposes @category EMBER_GLIMMER_SET_COMPONENT_TEMPLATE */ declare function templateOnlyComponent(moduleName?: string, name?: string): TemplateOnlyComponentDefinition; declare const TYPE: unique symbol; declare const INNER: unique symbol; declare const OWNER: unique symbol; declare const ARGS: unique symbol; declare const RESOLVED: unique symbol; declare class CurriedValue<T extends CurriedType = CurriedType> { [TYPE]: T; [INNER]: object | string | CurriedValue<T>; [OWNER]: Owner; [ARGS]: CapturedArguments | null; [RESOLVED]: boolean; } declare function curry<T extends CurriedType>(type: T, spec: object | string | CurriedValue<T>, owner: Owner, args: CapturedArguments | null, resolved?: boolean): CurriedValue<T>; declare class DOMOperations { protected document: SimpleDocument; protected uselessElement: SimpleElement; constructor(document: SimpleDocument); protected setupUselessElement(): void; createElement(tag: string, context?: SimpleElement): SimpleElement; insertBefore(parent: SimpleElement, node: SimpleNode, reference: Nullable<SimpleNode>): void; insertHTMLBefore(parent: SimpleElement, nextSibling: Nullable<SimpleNode>, html: string): Bounds; createTextNode(text: string): SimpleText; createComment(data: string): SimpleComment; } declare class TreeConstruction extends DOMOperations implements GlimmerTreeConstruction { createElementNS(namespace: ElementNamespace, tag: string): SimpleElement; setAttribute(element: SimpleElement, name: string, value: string, namespace?: Nullable<AttrNamespace>): void; } declare const DOMTreeConstruction: typeof TreeConstruction; type DOMTreeConstruction = TreeConstruction; declare function isWhitespace(string: string): boolean; declare class DOMChangesImpl extends DOMOperations implements GlimmerTreeChanges { protected document: SimpleDocument; protected namespace: Nullable<string>; constructor(document: SimpleDocument); setAttribute(element: SimpleElement, name: string, value: string): void; removeAttribute(element: SimpleElement, name: string): void; insertAfter(element: SimpleElement, node: SimpleNode, reference: SimpleNode): void; } declare const DOMChanges: typeof DOMChangesImpl; declare function normalizeProperty(element: SimpleElement, slotName: string): { normalized: string; type: string; }; declare class DebugRenderTreeImpl<TBucket extends object> implements DebugRenderTree<TBucket> { private stack; private refs; private roots; private nodes; begin(): void; create(state: TBucket, node: RenderNode): void; update(state: TBucket): void; didRender(state: TBucket, bounds: Bounds): void; willDestroy(state: TBucket): void; commit(): void; capture(): CapturedRenderNode[]; private reset; private enter; private exit; private nodeFor; private appendChild; private captureRefs; private captureNode; private captureTemplate; private captureBounds; } declare const TRANSACTION: TransactionSymbol; declare class TransactionImpl implements Transaction { scheduledInstallModifiers: ModifierInstance[]; scheduledUpdateModifiers: ModifierInstance[]; createdComponents: ComponentInstanceWithCreate[]; updatedComponents: ComponentInstanceWithCreate[]; didCreate(component: ComponentInstanceWithCreate): void; didUpdate(component: ComponentInstanceWithCreate): void; scheduleInstallModifier(modifier: ModifierInstance): void; scheduleUpdateModifier(modifier: ModifierInstance): void; commit(): void; } declare class EnvironmentImpl implements Environment { private delegate; [TRANSACTION]: Nullable<TransactionImpl>; protected appendOperations: GlimmerTreeConstruction; protected updateOperations?: GlimmerTreeChanges | undefined; isInteractive: boolean; isArgumentCaptureError: ((error: any) => boolean) | undefined; debugRenderTree: DebugRenderTreeImpl<object> | undefined; constructor(options: EnvironmentOptions, delegate: EnvironmentDelegate); getAppendOperations(): GlimmerTreeConstruction; getDOM(): GlimmerTreeChanges; begin(): void; private get transaction(); didCreate(component: ComponentInstanceWithCreate): void; didUpdate(component: ComponentInstanceWithCreate): void; scheduleInstallModifier(modifier: ModifierInstance): void; scheduleUpdateModifier(modifier: ModifierInstance): void; commit(): void; } interface EnvironmentDelegate { /** * Used to determine the the environment is interactive (e.g. SSR is not * interactive). Interactive environments schedule modifiers, among other things. */ isInteractive: boolean; /** * Used to enable debug tooling */ enableDebugTooling: boolean; /** * Callback to be called when an environment transaction commits */ onTransactionCommit: () => void; } declare function runtimeOptions(options: EnvironmentOptions, delegate: EnvironmentDelegate, artifacts: RuntimeArtifacts, resolver: Nullable<ClassicResolver>): RuntimeOptions; declare function inTransaction(env: Environment, block: () => void): void; /** Use the `{{array}}` helper to create an array to pass as an option to your components. ```handlebars <MyComponent @people={{array 'Tom Dale' 'Yehuda Katz' this.myOtherPerson}} /> ``` or ```handlebars {{my-component people=(array 'Tom Dale' 'Yehuda Katz' this.myOtherPerson) }} ``` Would result in an object such as: ```js ['Tom Dale', 'Yehuda Katz', this.get('myOtherPerson')] ``` Where the 3rd item in the array is bound to updates of the `myOtherPerson` property. @method array @param {Array} options @return {Array} Array @public */ declare const array: object; /** Concatenates the given arguments into a string. Example: ```handlebars {{some-component name=(concat firstName " " lastName)}} {{! would pass name="<first name value> <last name value>" to the component}} ``` or for angle bracket inv