UNPKG

43.9 kBTypeScriptView Raw
1import { RichIteratorResult, Bounds, Cursor, Nullable, SimpleElement, SimpleNode, InternalComponentCapabilities, InternalComponentManager, CapturedArguments, CurriedType, Owner, GlimmerTreeChanges, SimpleDocument, SimpleComment, SimpleText, AttrNamespace, ElementNamespace, GlimmerTreeConstruction, ClassicResolver, ComponentInstanceWithCreate, Environment, EnvironmentOptions, ModifierInstance, RuntimeArtifacts, RuntimeOptions, Transaction, TransactionSymbol, CapturedRenderNode, DebugRenderTree, RenderNode, Arguments, CompilableProgram, ComponentDefinitionState, DynamicScope, EvaluationContext, RenderResult, TemplateIterator, TreeBuilder, Dict, Scope, ScopeBlock, ScopeSlot, CompilableTemplate, DebugVmSnapshot, DebugVmTrace, Destroyable, Program, ProgramConstants, UpdatingOpcode, RuntimeOp, BlockArguments, BlockValue, CapturedBlockArguments, CapturedNamedArguments, CapturedPositionalArguments, NamedArguments, PositionalArguments, VMArguments, AppendingBlock, ExceptionHandler, ResettableBlock, ElementOperations, Maybe, SimpleDocumentFragment, AttributeCursor, AttributeOperation } from '@glimmer/interfaces';
2import { UpdatingVM as IUpdatingVM } from "@glimmer/interfaces";
3import { Reference, OpaqueIterationItem, OpaqueIterator } from "@glimmer/reference";
4import { Cache, Tag } from "@glimmer/validator";
5import { MachineRegister, Register, SyscallRegister } from "@glimmer/vm";
6import { Stack } from "@glimmer/util";
7declare class CursorImpl implements Cursor {
8 element: SimpleElement;
9 nextSibling: Nullable<SimpleNode>;
10 constructor(element: SimpleElement, nextSibling: Nullable<SimpleNode>);
11}
12declare class ConcreteBounds implements Bounds {
13 parentNode: SimpleElement;
14 private first;
15 private last;
16 constructor(parentNode: SimpleElement, first: SimpleNode, last: SimpleNode);
17 parentElement(): SimpleElement;
18 firstNode(): SimpleNode;
19 lastNode(): SimpleNode;
20}
21declare function clear(bounds: Bounds): Nullable<SimpleNode>;
22type DebugGet = (path: string) => unknown;
23type DebugCallback = (context: unknown, get: DebugGet) => void;
24// For testing purposes
25declare function setDebuggerCallback(cb: DebugCallback): void;
26declare function resetDebuggerCallback(): void;
27declare class TemplateOnlyComponentManager implements InternalComponentManager {
28 getCapabilities(): InternalComponentCapabilities;
29 getDebugName({ name }: TemplateOnlyComponentDefinition): string;
30 getSelf(): Reference;
31 getDestroyable(): null;
32}
33declare const TEMPLATE_ONLY_COMPONENT_MANAGER: TemplateOnlyComponentManager;
34// This is only exported for types, don't use this class directly
35declare class TemplateOnlyComponentDefinition {
36 moduleName: string;
37 name: string;
38 constructor(moduleName?: string, name?: string);
39 toString(): string;
40}
41/**
42 This utility function is used to declare a given component has no backing class. When the rendering engine detects this it
43 is able to perform a number of optimizations. Templates that are associated with `templateOnly()` will be rendered _as is_
44 without adding a wrapping `<div>` (or any of the other element customization behaviors of [@ember/component](/ember/release/classes/Component)).
45 Specifically, this means that the template will be rendered as "outer HTML".
46
47 In general, this method will be used by build time tooling and would not be directly written in an application. However,
48 at times it may be useful to use directly to leverage the "outer HTML" semantics mentioned above. For example, if an addon would like
49 to use these semantics for its templates but cannot be certain it will only be consumed by applications that have enabled the
50 `template-only-glimmer-components` optional feature.
51
52 @example
53
54 ```js
55 import { templateOnlyComponent } from '@glimmer/runtime';
56
57 export default templateOnlyComponent();
58 ```
59
60 @public
61 @method templateOnly
62 @param {String} moduleName the module name that the template only component represents, this will be used for debugging purposes
63 @category EMBER_GLIMMER_SET_COMPONENT_TEMPLATE
64 */
65declare function templateOnlyComponent(moduleName?: string, name?: string): TemplateOnlyComponentDefinition;
66declare const TYPE: unique symbol;
67declare const INNER: unique symbol;
68declare const OWNER: unique symbol;
69declare const ARGS: unique symbol;
70declare const RESOLVED: unique symbol;
71declare class CurriedValue<T extends CurriedType = CurriedType> {
72 [TYPE]: T;
73 [INNER]: object | string | CurriedValue<T>;
74 [OWNER]: Owner;
75 [ARGS]: CapturedArguments | null;
76 [RESOLVED]: boolean;
77 /** @internal */
78 constructor(type: T, inner: object | string | CurriedValue<T>, owner: Owner, args: CapturedArguments | null, resolved?: boolean);
79}
80declare function curry<T extends CurriedType>(type: T, spec: object | string | CurriedValue<T>, owner: Owner, args: CapturedArguments | null, resolved?: boolean): CurriedValue<T>;
81declare class DOMOperations {
82 protected document: SimpleDocument;
83 protected uselessElement: SimpleElement; // Set by this.setupUselessElement() in constructor
84 constructor(document: SimpleDocument);
85 // split into separate method so that NodeDOMTreeConstruction
86 // can override it.
87 protected setupUselessElement(): void;
88 createElement(tag: string, context?: SimpleElement): SimpleElement;
89 insertBefore(parent: SimpleElement, node: SimpleNode, reference: Nullable<SimpleNode>): void;
90 insertHTMLBefore(parent: SimpleElement, nextSibling: Nullable<SimpleNode>, html: string): Bounds;
91 createTextNode(text: string): SimpleText;
92 createComment(data: string): SimpleComment;
93}
94declare function isWhitespace(string: string): boolean;
95declare class DOMChangesImpl extends DOMOperations implements GlimmerTreeChanges {
96 protected document: SimpleDocument;
97 protected namespace: Nullable<string>;
98 constructor(document: SimpleDocument);
99 setAttribute(element: SimpleElement, name: string, value: string): void;
100 removeAttribute(element: SimpleElement, name: string): void;
101 insertAfter(element: SimpleElement, node: SimpleNode, reference: SimpleNode): void;
102}
103declare const DOMChanges: typeof DOMChangesImpl;
104declare class TreeConstruction extends DOMOperations implements GlimmerTreeConstruction {
105 createElementNS(namespace: ElementNamespace, tag: string): SimpleElement;
106 setAttribute(element: SimpleElement, name: string, value: string, namespace?: Nullable<AttrNamespace>): void;
107}
108declare const DOMTreeConstruction: typeof TreeConstruction;
109type DOMTreeConstruction = TreeConstruction;
110/*
111* @method normalizeProperty
112* @param element {HTMLElement}
113* @param slotName {String}
114* @returns {Object} { name, type }
115*/
116declare function normalizeProperty(element: SimpleElement, slotName: string): {
117 normalized: any;
118 type: any;
119};
120declare class DebugRenderTreeImpl<TBucket extends object> implements DebugRenderTree<TBucket> {
121 private stack;
122 private refs;
123 private roots;
124 private nodes;
125 begin(): void;
126 create(state: TBucket, node: RenderNode): void;
127 update(state: TBucket): void;
128 didRender(state: TBucket, bounds: Bounds): void;
129 willDestroy(state: TBucket): void;
130 commit(): void;
131 capture(): CapturedRenderNode[];
132 private reset;
133 private enter;
134 private exit;
135 private nodeFor;
136 private appendChild;
137 private captureRefs;
138 private captureNode;
139 private captureTemplate;
140 private captureBounds;
141}
142declare module DebugRenderTreeImplWrapper {
143 export { DebugRenderTreeImpl };
144}
145import DebugRenderTree$0 = DebugRenderTreeImplWrapper.DebugRenderTreeImpl;
146declare const TRANSACTION: TransactionSymbol;
147declare class TransactionImpl implements Transaction {
148 scheduledInstallModifiers: ModifierInstance[];
149 scheduledUpdateModifiers: ModifierInstance[];
150 createdComponents: ComponentInstanceWithCreate[];
151 updatedComponents: ComponentInstanceWithCreate[];
152 didCreate(component: ComponentInstanceWithCreate): void;
153 didUpdate(component: ComponentInstanceWithCreate): void;
154 scheduleInstallModifier(modifier: ModifierInstance): void;
155 scheduleUpdateModifier(modifier: ModifierInstance): void;
156 commit(): void;
157}
158declare class EnvironmentImpl implements Environment {
159 private delegate;
160 [TRANSACTION]: Nullable<TransactionImpl>;
161 protected appendOperations: GlimmerTreeConstruction;
162 protected updateOperations?: GlimmerTreeChanges | undefined;
163 // Delegate methods and values
164 isInteractive: boolean;
165 // eslint-disable-next-line @typescript-eslint/no-explicit-any
166 isArgumentCaptureError: ((error: any) => boolean) | undefined;
167 debugRenderTree: DebugRenderTree$0<object> | undefined;
168 constructor(options: EnvironmentOptions, delegate: EnvironmentDelegate);
169 getAppendOperations(): GlimmerTreeConstruction;
170 getDOM(): GlimmerTreeChanges;
171 begin(): void;
172 private get transaction();
173 didCreate(component: ComponentInstanceWithCreate): void;
174 didUpdate(component: ComponentInstanceWithCreate): void;
175 scheduleInstallModifier(modifier: ModifierInstance): void;
176 scheduleUpdateModifier(modifier: ModifierInstance): void;
177 commit(): void;
178}
179interface EnvironmentDelegate {
180 /**
181 * Used to determine the the environment is interactive (e.g. SSR is not
182 * interactive). Interactive environments schedule modifiers, among other things.
183 */
184 isInteractive: boolean;
185 /**
186 * Used to enable debug tooling
187 */
188 enableDebugTooling: boolean;
189 /**
190 * Callback to be called when an environment transaction commits
191 */
192 onTransactionCommit: () => void;
193}
194declare function runtimeOptions(options: EnvironmentOptions, delegate: EnvironmentDelegate, artifacts: RuntimeArtifacts, resolver: Nullable<ClassicResolver>): RuntimeOptions;
195declare function inTransaction(env: Environment, block: () => void): void;
196/**
197 Use the `{{array}}` helper to create an array to pass as an option to your
198 components.
199
200 ```handlebars
201 <MyComponent @people={{array
202 'Tom Dale'
203 'Yehuda Katz'
204 this.myOtherPerson}}
205 />
206 ```
207 or
208 ```handlebars
209 {{my-component people=(array
210 'Tom Dale'
211 'Yehuda Katz'
212 this.myOtherPerson)
213 }}
214 ```
215
216 Would result in an object such as:
217
218 ```js
219 ['Tom Dale', 'Yehuda Katz', this.get('myOtherPerson')]
220 ```
221
222 Where the 3rd item in the array is bound to updates of the `myOtherPerson` property.
223
224 @method array
225 @param {Array} options
226 @return {Array} Array
227 @public
228 */
229declare const array: object;
230/**
231 Concatenates the given arguments into a string.
232
233 Example:
234
235 ```handlebars
236 {{some-component name=(concat firstName " " lastName)}}
237
238 {{! would pass name="<first name value> <last name value>" to the component}}
239 ```
240
241 or for angle bracket invocation, you actually don't need concat at all.
242
243 ```handlebars
244 <SomeComponent @name="{{firstName}} {{lastName}}" />
245 ```
246
247 @public
248 @method concat
249 */
250declare const concat: object;
251/**
252 The `fn` helper allows you to ensure a function that you are passing off
253 to another component, helper, or modifier has access to arguments that are
254 available in the template.
255
256 For example, if you have an `each` helper looping over a number of items, you
257 may need to pass a function that expects to receive the item as an argument
258 to a component invoked within the loop. Here's how you could use the `fn`
259 helper to pass both the function and its arguments together:
260
261 ```app/templates/components/items-listing.hbs
262 {{#each @items as |item|}}
263 <DisplayItem @item=item @select={{fn this.handleSelected item}} />
264 {{/each}}
265 ```
266
267 ```app/components/items-list.js
268 import Component from '@glimmer/component';
269 import { action } from '@ember/object';
270
271 export default class ItemsList extends Component {
272 handleSelected = (item) => {
273 // ...snip...
274 }
275 }
276 ```
277
278 In this case the `display-item` component will receive a normal function
279 that it can invoke. When it invokes the function, the `handleSelected`
280 function will receive the `item` and any arguments passed, thanks to the
281 `fn` helper.
282
283 Let's take look at what that means in a couple circumstances:
284
285 - When invoked as `this.args.select()` the `handleSelected` function will
286 receive the `item` from the loop as its first and only argument.
287 - When invoked as `this.args.select('foo')` the `handleSelected` function
288 will receive the `item` from the loop as its first argument and the
289 string `'foo'` as its second argument.
290
291 In the example above, we used an arrow function to ensure that
292 `handleSelected` is properly bound to the `items-list`, but let's explore what
293 happens if we left out the arrow function:
294
295 ```app/components/items-list.js
296 import Component from '@glimmer/component';
297
298 export default class ItemsList extends Component {
299 handleSelected(item) {
300 // ...snip...
301 }
302 }
303 ```
304
305 In this example, when `handleSelected` is invoked inside the `display-item`
306 component, it will **not** have access to the component instance. In other
307 words, it will have no `this` context, so please make sure your functions
308 are bound (via an arrow function or other means) before passing into `fn`!
309
310 See also [partial application](https://en.wikipedia.org/wiki/Partial_application).
311
312 @method fn
313 @public
314 */
315declare const fn: object;
316/**
317 Dynamically look up a property on an object. The second argument to `{{get}}`
318 should have a string value, although it can be bound.
319
320 For example, these two usages are equivalent:
321
322 ```app/components/developer-detail.js
323 import Component from '@glimmer/component';
324 import { tracked } from '@glimmer/tracking';
325
326 export default class extends Component {
327 @tracked developer = {
328 name: "Sandi Metz",
329 language: "Ruby"
330 }
331 }
332 ```
333
334 ```handlebars
335 {{this.developer.name}}
336 {{get this.developer "name"}}
337 ```
338
339 If there were several facts about a person, the `{{get}}` helper can dynamically
340 pick one:
341
342 ```app/templates/application.hbs
343 <DeveloperDetail @factName="language" />
344 ```
345
346 ```handlebars
347 {{get this.developer @factName}}
348 ```
349
350 For a more complex example, this template would allow the user to switch
351 between showing the user's height and weight with a click:
352
353 ```app/components/developer-detail.js
354 import Component from '@glimmer/component';
355 import { tracked } from '@glimmer/tracking';
356
357 export default class extends Component {
358 @tracked developer = {
359 name: "Sandi Metz",
360 language: "Ruby"
361 }
362
363 @tracked currentFact = 'name'
364
365 showFact = (fact) => {
366 this.currentFact = fact;
367 }
368 }
369 ```
370
371 ```app/components/developer-detail.js
372 {{get this.developer this.currentFact}}
373
374 <button {{on 'click' (fn this.showFact "name")}}>Show name</button>
375 <button {{on 'click' (fn this.showFact "language")}}>Show language</button>
376 ```
377
378 The `{{get}}` helper can also respect mutable values itself. For example:
379
380 ```app/components/developer-detail.js
381 <Input @value={{mut (get this.person this.currentFact)}} />
382
383 <button {{on 'click' (fn this.showFact "name")}}>Show name</button>
384 <button {{on 'click' (fn this.showFact "language")}}>Show language</button>
385 ```
386
387 Would allow the user to swap what fact is being displayed, and also edit
388 that fact via a two-way mutable binding.
389
390 @public
391 @method get
392 */
393declare const get: object;
394/**
395 Use the `{{hash}}` helper to create a hash to pass as an option to your
396 components. This is specially useful for contextual components where you can
397 just yield a hash:
398
399 ```handlebars
400 {{yield (hash
401 name='Sarah'
402 title=office
403 )}}
404 ```
405
406 Would result in an object such as:
407
408 ```js
409 { name: 'Sarah', title: this.get('office') }
410 ```
411
412 Where the `title` is bound to updates of the `office` property.
413
414 Note that the hash is an empty object with no prototype chain, therefore
415 common methods like `toString` are not available in the resulting hash.
416 If you need to use such a method, you can use the `call` or `apply`
417 approach:
418
419 ```js
420 function toString(obj) {
421 return Object.prototype.toString.apply(obj);
422 }
423 ```
424
425 @method hash
426 @param {Object} options
427 @return {Object} Hash
428 @public
429 */
430declare const hash: object;
431////////////
432declare function invokeHelper(context: object, definition: object, computeArgs?: (context: object) => Partial<Arguments>): Cache<unknown>;
433declare const on: {};
434declare function renderSync(env: Environment, iterator: TemplateIterator): RenderResult;
435declare function renderMain(context: EvaluationContext, owner: Owner, self: Reference, tree: TreeBuilder, layout: CompilableProgram, dynamicScope?: DynamicScope): TemplateIterator;
436declare function renderComponent(context: EvaluationContext, tree: TreeBuilder, owner: Owner, definition: ComponentDefinitionState, args?: Record<string, unknown>, dynamicScope?: DynamicScope): TemplateIterator;
437declare class DynamicScopeImpl implements DynamicScope {
438 private bucket;
439 constructor(bucket?: Dict<Reference>);
440 get(key: string): Reference;
441 set(key: string, reference: Reference): Reference;
442 child(): DynamicScopeImpl;
443}
444interface ScopeOptions {
445 /** @default {UNDEFINED_REFERENCE} */
446 self: Reference<unknown>;
447 /** @default {0} */
448 size?: number | undefined;
449}
450declare class ScopeImpl implements Scope {
451 static root(owner: Owner, { self, size }: ScopeOptions): Scope;
452 static sized(owner: Owner, size?: number): Scope;
453 readonly owner: Owner;
454 private slots;
455 private callerScope;
456 constructor(owner: Owner,
457 // the 0th slot is `self`
458 slots: Array<ScopeSlot>,
459 // a single program can mix owners via curried components, and the state lives on root scopes
460 callerScope: Nullable<Scope>);
461 init({ self }: {
462 self: Reference<unknown>;
463 }): this;
464 /**
465 * @debug
466 */
467 snapshot(): ScopeSlot[];
468 getSelf(): Reference<unknown>;
469 getSymbol(symbol: number): Reference<unknown>;
470 getBlock(symbol: number): Nullable<ScopeBlock>;
471 bind(symbol: number, value: ScopeSlot): void;
472 bindSelf(self: Reference<unknown>): void;
473 bindSymbol(symbol: number, value: Reference<unknown>): void;
474 bindBlock(symbol: number, value: Nullable<ScopeBlock>): void;
475 bindCallerScope(scope: Nullable<Scope>): void;
476 getCallerScope(): Nullable<Scope>;
477 child(): Scope;
478 private get;
479 private set;
480}
481interface SafeString {
482 toHTML(): string;
483}
484type LowLevelRegisters = [
485 $pc: number,
486 $ra: number,
487 $sp: number,
488 $fp: number
489];
490interface VmStack {
491 readonly registers: LowLevelRegisters;
492 push(value: unknown): void;
493 get(position: number): number;
494 pop<T>(): T;
495 snapshot?(): unknown[];
496}
497interface Externs {
498 debugBefore(opcode: RuntimeOp): unknown;
499 debugAfter(state: unknown): void;
500}
501declare class LowLevelVM {
502 stack: VmStack;
503 externs: Externs | undefined;
504 currentOpSize: number;
505 readonly registers: LowLevelRegisters;
506 readonly context: EvaluationContext;
507 constructor(stack: VmStack, context: EvaluationContext, externs: Externs | undefined, registers: LowLevelRegisters);
508 fetchRegister(register: MachineRegister): number;
509 loadRegister(register: MachineRegister, value: number): void;
510 setPc(pc: number): void;
511 // Start a new frame and save $ra and $fp on the stack
512 pushFrame(): void;
513 // Restore $ra, $sp and $fp
514 popFrame(): void;
515 pushSmallFrame(): void;
516 popSmallFrame(): void;
517 // Jump to an address in `program`
518 goto(offset: number): void;
519 target(offset: number): number;
520 // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS)
521 call(handle: number): void;
522 // Put a specific `program` address in $ra
523 returnTo(offset: number): void;
524 // Return to the `program` address stored in $ra
525 return(): void;
526 nextStatement(): Nullable<RuntimeOp>;
527 evaluateOuter(opcode: RuntimeOp, vm: VM): void;
528 evaluateInner(opcode: RuntimeOp, vm: VM): void;
529 evaluateMachine(opcode: RuntimeOp, vm: VM): void;
530 evaluateSyscall(opcode: RuntimeOp, vm: VM): void;
531}
532interface EvaluationStack {
533 readonly registers: LowLevelRegisters;
534 push(value: unknown): void;
535 dup(position?: number): void;
536 copy(from: number, to: number): void;
537 pop<T>(n?: number): T;
538 peek<T>(offset?: number): T;
539 get<T>(offset: number, base?: number): T;
540 set(value: unknown, offset: number, base?: number): void;
541 slice<T = unknown>(start: number, end: number): T[];
542 capture(items: number): unknown[];
543 reset(): void;
544 snapshot?(): unknown[];
545}
546/*
547The calling convention is:
548
549* 0-N block arguments at the bottom
550* 0-N positional arguments next (left-to-right)
551* 0-N named arguments next
552*/
553declare class VMArgumentsImpl implements VMArguments {
554 private stack;
555 positional: PositionalArgumentsImpl;
556 named: NamedArgumentsImpl;
557 blocks: BlockArgumentsImpl;
558 constructor();
559 empty(stack: EvaluationStack): this;
560 setup(stack: EvaluationStack, names: readonly string[], blockNames: readonly string[], positionalCount: number, atNames: boolean): void;
561 get base(): number;
562 get length(): number;
563 at(pos: number): Reference;
564 realloc(offset: number): void;
565 capture(): CapturedArguments;
566 clear(): void;
567}
568declare class PositionalArgumentsImpl implements PositionalArguments {
569 base: number;
570 length: number;
571 // eslint-disable-next-line @typescript-eslint/no-explicit-any
572 private stack;
573 private _references;
574 constructor();
575 empty(stack: EvaluationStack, base: number): void;
576 setup(stack: EvaluationStack, base: number, length: number): void;
577 at(position: number): Reference;
578 capture(): CapturedPositionalArguments;
579 prepend(other: Reference[]): void;
580 private get references();
581}
582declare class NamedArgumentsImpl implements NamedArguments {
583 base: number;
584 length: number;
585 private stack;
586 private _references;
587 private _names;
588 private _atNames;
589 constructor();
590 empty(stack: EvaluationStack, base: number): void;
591 setup(stack: EvaluationStack, base: number, length: number, names: readonly string[], atNames: boolean): void;
592 get names(): readonly string[];
593 get atNames(): readonly string[];
594 has(name: string): boolean;
595 get(name: string, atNames?: boolean): Reference;
596 capture(): CapturedNamedArguments;
597 merge(other: Record<string, Reference>): void;
598 private get references();
599 private toSyntheticName;
600 private toAtName;
601}
602declare class BlockArgumentsImpl implements BlockArguments {
603 private stack;
604 private internalValues;
605 private _symbolNames;
606 internalTag: Nullable<Tag>;
607 names: readonly string[];
608 length: number;
609 base: number;
610 constructor();
611 empty(stack: EvaluationStack, base: number): void;
612 setup(stack: EvaluationStack, base: number, length: number, names: readonly string[]): void;
613 get values(): readonly BlockValue[];
614 has(name: string): boolean;
615 get(name: string): Nullable<ScopeBlock>;
616 capture(): CapturedBlockArguments;
617 get symbolNames(): readonly string[];
618}
619declare function createCapturedArgs(named: Dict<Reference>, positional: Reference[]): CapturedArguments;
620declare function reifyNamed(named: CapturedNamedArguments): Dict<unknown>;
621declare function reifyPositional(positional: CapturedPositionalArguments): unknown[];
622declare function reifyArgs(args: CapturedArguments): {
623 named: Dict<unknown>;
624 positional: unknown[];
625};
626declare const EMPTY_NAMED: CapturedNamedArguments;
627declare const EMPTY_POSITIONAL: CapturedPositionalArguments;
628declare const EMPTY_ARGS: CapturedArguments;
629declare function dynamicAttribute(element: SimpleElement, attr: string, namespace: Nullable<AttrNamespace>, isTrusting?: boolean): DynamicAttribute;
630declare abstract class DynamicAttribute implements AttributeOperation {
631 attribute: AttributeCursor;
632 constructor(attribute: AttributeCursor);
633 abstract set(dom: TreeBuilder, value: unknown, env: Environment): void;
634 abstract update(value: unknown, env: Environment): void;
635}
636declare class SimpleDynamicAttribute extends DynamicAttribute {
637 set(dom: TreeBuilder, value: unknown, _env: Environment): void;
638 update(value: unknown, _env: Environment): void;
639}
640interface FirstNode {
641 debug?: {
642 first: () => Nullable<SimpleNode>;
643 };
644 firstNode(): SimpleNode;
645}
646interface LastNode {
647 debug?: {
648 last: () => Nullable<SimpleNode>;
649 };
650 lastNode(): SimpleNode;
651}
652declare class NewTreeBuilder implements TreeBuilder {
653 debug?: () => {
654 blocks: AppendingBlock[];
655 constructing: Nullable<SimpleElement>;
656 cursors: Cursor[];
657 };
658 dom: GlimmerTreeConstruction;
659 updateOperations: GlimmerTreeChanges;
660 constructing: Nullable<SimpleElement>;
661 operations: Nullable<ElementOperations>;
662 private env;
663 readonly cursors: Stack<Cursor>;
664 private modifierStack;
665 private blockStack;
666 static forInitialRender(env: Environment, cursor: CursorImpl): NewTreeBuilder;
667 static resume(env: Environment, block: ResettableBlock): NewTreeBuilder;
668 constructor(env: Environment, parentNode: SimpleElement, nextSibling: Nullable<SimpleNode>);
669 protected initialize(): this;
670 debugBlocks(): AppendingBlock[];
671 get element(): SimpleElement;
672 get nextSibling(): Nullable<SimpleNode>;
673 get hasBlocks(): boolean;
674 protected block(): AppendingBlock;
675 popElement(): void;
676 pushAppendingBlock(): AppendingBlock;
677 pushResettableBlock(): ResettableBlockImpl;
678 pushBlockList(list: AppendingBlock[]): AppendingBlockList;
679 protected pushBlock<T extends AppendingBlock>(block: T, isRemote?: boolean): T;
680 popBlock(): AppendingBlock;
681 __openBlock(): void;
682 __closeBlock(): void;
683 // todo return seems unused
684 openElement(tag: string): SimpleElement;
685 __openElement(tag: string): SimpleElement;
686 flushElement(modifiers: Nullable<ModifierInstance[]>): void;
687 __flushElement(parent: SimpleElement, constructing: SimpleElement): void;
688 closeElement(): Nullable<ModifierInstance[]>;
689 pushRemoteElement(element: SimpleElement, guid: string, insertBefore: Maybe<SimpleNode>): RemoteBlock;
690 __pushRemoteElement(element: SimpleElement, _guid: string, insertBefore: Maybe<SimpleNode>): RemoteBlock;
691 popRemoteElement(): RemoteBlock;
692 protected pushElement(element: SimpleElement, nextSibling?: Maybe<SimpleNode>): void;
693 private pushModifiers;
694 private popModifiers;
695 didAppendBounds(bounds: Bounds): Bounds;
696 didAppendNode<T extends SimpleNode>(node: T): T;
697 didOpenElement(element: SimpleElement): SimpleElement;
698 willCloseElement(): void;
699 appendText(string: string): SimpleText;
700 __appendText(text: string): SimpleText;
701 __appendNode(node: SimpleNode): SimpleNode;
702 __appendFragment(fragment: SimpleDocumentFragment): Bounds;
703 __appendHTML(html: string): Bounds;
704 appendDynamicHTML(value: string): void;
705 appendDynamicText(value: string): SimpleText;
706 appendDynamicFragment(value: SimpleDocumentFragment): void;
707 appendDynamicNode(value: SimpleNode): void;
708 private trustedContent;
709 private untrustedContent;
710 appendComment(string: string): SimpleComment;
711 __appendComment(string: string): SimpleComment;
712 __setAttribute(name: string, value: string, namespace: Nullable<AttrNamespace>): void;
713 __setProperty(name: string, value: unknown): void;
714 setStaticAttribute(name: string, value: string, namespace: Nullable<AttrNamespace>): void;
715 setDynamicAttribute(name: string, value: unknown, trusting: boolean, namespace: Nullable<AttrNamespace>): DynamicAttribute;
716}
717declare class AppendingBlockImpl implements AppendingBlock {
718 private parent;
719 debug?: {
720 first: () => Nullable<SimpleNode>;
721 last: () => Nullable<SimpleNode>;
722 };
723 protected first: Nullable<FirstNode>;
724 protected last: Nullable<LastNode>;
725 protected nesting: number;
726 constructor(parent: SimpleElement);
727 parentElement(): SimpleElement;
728 firstNode(): SimpleNode;
729 lastNode(): SimpleNode;
730 openElement(element: SimpleElement): void;
731 closeElement(): void;
732 didAppendNode(node: SimpleNode): void;
733 didAppendBounds(bounds: Bounds): void;
734 finalize(stack: TreeBuilder): void;
735}
736declare class RemoteBlock extends AppendingBlockImpl {
737 constructor(parent: SimpleElement);
738}
739declare class ResettableBlockImpl extends AppendingBlockImpl implements ResettableBlock {
740 constructor(parent: SimpleElement);
741 reset(): Nullable<SimpleNode>;
742}
743// FIXME: All the noops in here indicate a modelling problem
744declare class AppendingBlockList implements AppendingBlock {
745 private readonly parent;
746 boundList: AppendingBlock[];
747 constructor(parent: SimpleElement, boundList: AppendingBlock[]);
748 parentElement(): SimpleElement;
749 firstNode(): SimpleNode;
750 lastNode(): SimpleNode;
751 openElement(_element: SimpleElement): void;
752 closeElement(): void;
753 didAppendNode(_node: SimpleNode): void;
754 didAppendBounds(_bounds: Bounds): void;
755 finalize(_stack: TreeBuilder): void;
756}
757declare function clientBuilder(env: Environment, cursor: CursorImpl): TreeBuilder;
758declare class UpdatingVM implements IUpdatingVM {
759 env: Environment;
760 dom: GlimmerTreeChanges;
761 alwaysRevalidate: boolean;
762 private frameStack;
763 constructor(env: Environment, { alwaysRevalidate }: {
764 alwaysRevalidate?: boolean;
765 });
766 execute(opcodes: UpdatingOpcode[], handler: ExceptionHandler): void;
767 private _execute;
768 private get frame();
769 goto(index: number): void;
770 try(ops: UpdatingOpcode[], handler: Nullable<ExceptionHandler>): void;
771 throw(): void;
772}
773declare abstract class BlockOpcode implements UpdatingOpcode, Bounds {
774 protected state: Closure;
775 protected context: EvaluationContext;
776 children: UpdatingOpcode[];
777 protected readonly bounds: AppendingBlock;
778 constructor(state: Closure, context: EvaluationContext, bounds: AppendingBlock, children: UpdatingOpcode[]);
779 parentElement(): import("@glimmer/interfaces").SimpleElement;
780 firstNode(): import("@glimmer/interfaces").SimpleNode;
781 lastNode(): import("@glimmer/interfaces").SimpleNode;
782 evaluate(vm: UpdatingVM): void;
783}
784declare class TryOpcode extends BlockOpcode implements ExceptionHandler {
785 type: string;
786 protected bounds: ResettableBlock; // Shadows property on base class
787 evaluate(vm: UpdatingVM): void;
788 handleException(): void;
789}
790declare class ListItemOpcode extends TryOpcode {
791 key: unknown;
792 memo: Reference;
793 value: Reference;
794 retained: boolean;
795 index: number;
796 constructor(state: Closure, context: EvaluationContext, bounds: ResettableBlock, key: unknown, memo: Reference, value: Reference);
797 shouldRemove(): boolean;
798 reset(): void;
799}
800declare class VM {
801 #private;
802 readonly args: VMArgumentsImpl;
803 readonly lowlevel: LowLevelVM;
804 readonly debug?: () => DebugVmSnapshot;
805 readonly trace?: () => DebugVmTrace;
806 get stack(): EvaluationStack;
807 /* Registers */
808 get pc(): number;
809 /**
810 * Fetch a value from a syscall register onto the stack.
811 *
812 * ## Opcodes
813 *
814 * - Append: `Fetch`
815 *
816 * ## State changes
817 *
818 * [!] push Eval Stack <- $register
819 */
820 fetch(register: SyscallRegister): void;
821 /**
822 * Load a value from the stack into a syscall register.
823 *
824 * ## Opcodes
825 *
826 * - Append: `Load`
827 *
828 * ## State changes
829 *
830 * [!] pop Eval Stack -> `value`
831 * [$] $register <- `value`
832 */
833 load(register: SyscallRegister): void;
834 /**
835 * Load a value into a syscall register.
836 *
837 * ## State changes
838 *
839 * [$] $register <- `value`
840 *
841 * @utility
842 */
843 loadValue<T>(register: SyscallRegister, value: T): void;
844 /**
845 * Fetch a value from a register (machine or syscall).
846 *
847 * ## State changes
848 *
849 * [ ] get $register
850 *
851 * @utility
852 */
853 fetchValue(register: MachineRegister): number;
854 fetchValue<T>(register: Register): T;
855 // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS)
856 call(handle: number | null): void;
857 // Return to the `program` address stored in $ra
858 return(): void;
859 readonly context: EvaluationContext;
860 constructor({ scope, dynamicScope, stack, pc }: ClosureState, context: EvaluationContext, tree: TreeBuilder);
861 static initial(context: EvaluationContext, options: InitialVmState): VM;
862 compile(block: CompilableTemplate): number;
863 get constants(): ProgramConstants;
864 get program(): Program;
865 get env(): Environment;
866 private captureClosure;
867 capture(args: number, pc?: number): Closure;
868 /**
869 * ## Opcodes
870 *
871 * - Append: `BeginComponentTransaction`
872 *
873 * ## State Changes
874 *
875 * [ ] create `guard` (`JumpIfNotModifiedOpcode`)
876 * [ ] create `tracker` (`BeginTrackFrameOpcode`)
877 * [!] push Updating Stack <- `guard`
878 * [!] push Updating Stack <- `tracker`
879 * [!] push Cache Stack <- `guard`
880 * [!] push Tracking Stack
881 */
882 beginCacheGroup(name?: string): void;
883 /**
884 * ## Opcodes
885 *
886 * - Append: `CommitComponentTransaction`
887 *
888 * ## State Changes
889 *
890 * Create a new `EndTrackFrameOpcode` (`end`)
891 *
892 * [!] pop CacheStack -> `guard`
893 * [!] pop Tracking Stack -> `tag`
894 * [ ] create `end` (`EndTrackFrameOpcode`) with `guard`
895 * [-] consume `tag`
896 */
897 commitCacheGroup(): void;
898 /**
899 * ## Opcodes
900 *
901 * - Append: `Enter`
902 *
903 * ## State changes
904 *
905 * [!] push Element Stack as `block`
906 * [ ] create `try` (`TryOpcode`) with `block`, capturing `args` from the Eval Stack
907 *
908 * Did Enter (`try`):
909 * [-] associate destroyable `try`
910 * [!] push Destroyable Stack <- `try`
911 * [!] push Updating List <- `try`
912 * [!] push Updating Stack <- `try.children`
913 */
914 enter(args: number): void;
915 /**
916 * ## Opcodes
917 *
918 * - Append: `Iterate`
919 * - Update: `ListBlock`
920 *
921 * ## State changes
922 *
923 * Create a new ref for the iterator item (`value`).
924 * Create a new ref for the iterator key (`key`).
925 *
926 * [ ] create `valueRef` (`Reference`) from `value`
927 * [ ] create `keyRef` (`Reference`) from `key`
928 * [!] push Eval Stack <- `valueRef`
929 * [!] push Eval Stack <- `keyRef`
930 * [!] push Element Stack <- `UpdatableBlock` as `block`
931 * [ ] capture `closure` with *2* items from the Eval Stack
932 * [ ] create `iteration` (`ListItemOpcode`) with `closure`, `block`, `key`, `keyRef` and `valueRef`
933 *
934 * Did Enter (`iteration`):
935 * [-] associate destroyable `iteration`
936 * [!] push Destroyable Stack <- `iteration`
937 * [!] push Updating List <- `iteration`
938 * [!] push Updating Stack <- `iteration.children`
939 */
940 enterItem({ key, value, memo }: OpaqueIterationItem): ListItemOpcode;
941 registerItem(opcode: ListItemOpcode): void;
942 /**
943 * ## Opcodes
944 *
945 * - Append: `EnterList`
946 *
947 * ## State changes
948 *
949 * [ ] capture `closure` with *0* items from the Eval Stack, and `$pc` from `offset`
950 * [ ] create `updating` (empty `Array`)
951 * [!] push Element Stack <- `list` (`BlockList`) with `updating`
952 * [ ] create `list` (`ListBlockOpcode`) with `closure`, `list`, `updating` and `iterableRef`
953 * [!] push List Stack <- `list`
954 *
955 * Did Enter (`list`):
956 * [-] associate destroyable `list`
957 * [!] push Destroyable Stack <- `list`
958 * [!] push Updating List <- `list`
959 * [!] push Updating Stack <- `list.children`
960 */
961 enterList(iterableRef: Reference<OpaqueIterator>, offset: number): void;
962 /**
963 * ## Opcodes
964 *
965 * - Append: `Enter`
966 * - Append: `Iterate`
967 * - Append: `EnterList`
968 * - Update: `ListBlock`
969 *
970 * ## State changes
971 *
972 * [-] associate destroyable `opcode`
973 * [!] push Destroyable Stack <- `opcode`
974 * [!] push Updating List <- `opcode`
975 * [!] push Updating Stack <- `opcode.children`
976 *
977 */
978 private didEnter;
979 /**
980 * ## Opcodes
981 *
982 * - Append: `Exit`
983 * - Append: `ExitList`
984 *
985 * ## State changes
986 *
987 * [!] pop Destroyable Stack
988 * [!] pop Element Stack
989 * [!] pop Updating Stack
990 */
991 exit(): void;
992 /**
993 * ## Opcodes
994 *
995 * - Append: `ExitList`
996 *
997 * ## State changes
998 *
999 * Pop List:
1000 * [!] pop Destroyable Stack
1001 * [!] pop Element Stack
1002 * [!] pop Updating Stack
1003 *
1004 * [!] pop List Stack
1005 */
1006 exitList(): void;
1007 /**
1008 * ## Opcodes
1009 *
1010 * - Append: `RootScope`
1011 * - Append: `VirtualRootScope`
1012 *
1013 * ## State changes
1014 *
1015 * [!] push Scope Stack
1016 */
1017 pushRootScope(size: number, owner: Owner): Scope;
1018 /**
1019 * ## Opcodes
1020 *
1021 * - Append: `ChildScope`
1022 *
1023 * ## State changes
1024 *
1025 * [!] push Scope Stack <- `child` of current Scope
1026 */
1027 pushChildScope(): void;
1028 /**
1029 * ## Opcodes
1030 *
1031 * - Append: `Yield`
1032 *
1033 * ## State changes
1034 *
1035 * [!] push Scope Stack <- `scope`
1036 */
1037 pushScope(scope: Scope): void;
1038 /**
1039 * ## Opcodes
1040 *
1041 * - Append: `PopScope`
1042 *
1043 * ## State changes
1044 *
1045 * [!] pop Scope Stack
1046 */
1047 popScope(): void;
1048 /**
1049 * ## Opcodes
1050 *
1051 * - Append: `PushDynamicScope`
1052 *
1053 * ## State changes:
1054 *
1055 * [!] push Dynamic Scope Stack <- child of current Dynamic Scope
1056 */
1057 pushDynamicScope(): DynamicScope;
1058 /**
1059 * ## Opcodes
1060 *
1061 * - Append: `BindDynamicScope`
1062 *
1063 * ## State changes:
1064 *
1065 * [!] pop Dynamic Scope Stack `names.length` times
1066 */
1067 bindDynamicScope(names: string[]): void;
1068 /**
1069 * ## State changes
1070 *
1071 * - [!] push Updating Stack
1072 *
1073 * @utility
1074 */
1075 pushUpdating(list?: UpdatingOpcode[]): void;
1076 /**
1077 * ## State changes
1078 *
1079 * [!] pop Updating Stack
1080 *
1081 * @utility
1082 */
1083 popUpdating(): UpdatingOpcode[];
1084 /**
1085 * ## State changes
1086 *
1087 * [!] push Updating List
1088 *
1089 * @utility
1090 */
1091 updateWith(opcode: UpdatingOpcode): void;
1092 private listBlock;
1093 /**
1094 * ## State changes
1095 *
1096 * [-] associate destroyable `child`
1097 *
1098 * @utility
1099 */
1100 associateDestroyable(child: Destroyable): void;
1101 private updating;
1102 /**
1103 * Get Tree Builder
1104 */
1105 tree(): TreeBuilder;
1106 /**
1107 * Get current Scope
1108 */
1109 scope(): Scope;
1110 /**
1111 * Get current Dynamic Scope
1112 */
1113 dynamicScope(): DynamicScope;
1114 popDynamicScope(): void;
1115 /// SCOPE HELPERS
1116 getOwner(): Owner;
1117 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1118 getSelf(): Reference<any>;
1119 referenceForSymbol(symbol: number): Reference;
1120 /// EXECUTION
1121 execute(initialize?: (vm: this) => void): RenderResult;
1122 private _execute;
1123 next(): RichIteratorResult<null, RenderResult>;
1124}
1125interface InitialVmState {
1126 /**
1127 * The address of the compiled template. This is converted into a
1128 * pc when the VM is created.
1129 */
1130 handle: number;
1131 /**
1132 * Optionally, specify the root scope for the VM. If not specified,
1133 * the VM will use a root scope with no `this` reference and no
1134 * symbols.
1135 */
1136 scope?: ScopeOptions;
1137 /**
1138 *
1139 */
1140 tree: TreeBuilder;
1141 dynamicScope: DynamicScope;
1142 owner: Owner;
1143}
1144interface ClosureState {
1145 /**
1146 * The program counter that subsequent evaluations should start from.
1147 */
1148 readonly pc: number;
1149 /**
1150 * The current value of the VM's scope (which changes whenever a component is invoked or a block
1151 * with block params is entered).
1152 */
1153 readonly scope: Scope;
1154 /**
1155 * The current value of the VM's dynamic scope
1156 */
1157 readonly dynamicScope: DynamicScope;
1158 /**
1159 * A number of stack elements captured during the initial evaluation, and which should be restored
1160 * to the stack when the block is re-evaluated.
1161 */
1162 readonly stack: unknown[];
1163}
1164/**
1165 * A closure captures the state of the VM for a particular block of code that is necessary to
1166 * re-invoke the block in the future.
1167 *
1168 * In practice, this allows us to clear the previous render and "replay" the block's execution,
1169 * rendering content in the same position as the first render.
1170 */
1171declare class Closure {
1172 private state;
1173 private context;
1174 constructor(state: ClosureState, context: EvaluationContext);
1175 evaluate(tree: TreeBuilder): VM;
1176}
1177declare const SERIALIZATION_FIRST_NODE_STRING = "%+b:0%";
1178declare function isSerializationFirstNode(node: SimpleNode): boolean;
1179declare class RehydratingCursor extends CursorImpl {
1180 readonly startingBlockDepth: number;
1181 candidate: Nullable<SimpleNode>;
1182 openBlockDepth: number;
1183 injectedOmittedNode: boolean;
1184 constructor(element: SimpleElement, nextSibling: Nullable<SimpleNode>, startingBlockDepth: number);
1185}
1186declare class RehydrateTree extends NewTreeBuilder implements TreeBuilder {
1187 private unmatchedAttributes;
1188 cursors: Stack<RehydratingCursor>; // Hides property on base class
1189 blockDepth: number;
1190 startingBlockOffset: number;
1191 constructor(env: Environment, parentNode: SimpleElement, nextSibling: Nullable<SimpleNode>);
1192 get currentCursor(): Nullable<RehydratingCursor>;
1193 get candidate(): Nullable<SimpleNode>;
1194 set candidate(node: Nullable<SimpleNode>);
1195 disableRehydration(nextSibling: Nullable<SimpleNode>): void;
1196 enableRehydration(candidate: Nullable<SimpleNode>): void;
1197 pushElement(/** called from parent constructor before we initialize this */
1198 this: RehydrateTree | (NewTreeBuilder & Partial<Pick<RehydrateTree, "blockDepth" | "candidate">>), element: SimpleElement, nextSibling?: Maybe<SimpleNode>): void;
1199 // clears until the end of the current container
1200 // either the current open block or higher
1201 private clearMismatch;
1202 __openBlock(): void;
1203 __closeBlock(): void;
1204 __appendNode(node: SimpleNode): SimpleNode;
1205 __appendHTML(html: string): Bounds;
1206 protected remove(node: SimpleNode): Nullable<SimpleNode>;
1207 private markerBounds;
1208 __appendText(string: string): SimpleText;
1209 __appendComment(string: string): SimpleComment;
1210 __openElement(tag: string): SimpleElement;
1211 __setAttribute(name: string, value: string, namespace: Nullable<AttrNamespace>): void;
1212 __setProperty(name: string, value: string): void;
1213 __flushElement(parent: SimpleElement, constructing: SimpleElement): void;
1214 willCloseElement(): void;
1215 getMarker(element: HTMLElement, guid: string): Nullable<SimpleNode>;
1216 __pushRemoteElement(element: SimpleElement, cursorId: string, insertBefore: Maybe<SimpleNode>): RemoteBlock;
1217 didAppendBounds(bounds: Bounds): Bounds;
1218}
1219declare function rehydrationBuilder(env: Environment, cursor: CursorImpl): TreeBuilder;
1220type IteratorResult<T> = RichIteratorResult<null, T>;
1221export { clear, ConcreteBounds, CursorImpl, DebugCallback, resetDebuggerCallback, setDebuggerCallback, TEMPLATE_ONLY_COMPONENT_MANAGER, TemplateOnlyComponentDefinition as TemplateOnlyComponent, templateOnlyComponent, TemplateOnlyComponentManager, CurriedValue, curry, DOMChanges, DOMTreeConstruction, DOMChangesImpl as IDOMChanges, isWhitespace, normalizeProperty, EnvironmentDelegate, EnvironmentImpl, inTransaction, runtimeOptions, array, concat, fn, get, hash, invokeHelper, on, renderComponent, renderMain, renderSync, DynamicScopeImpl, ScopeImpl, UpdatingVM, VM, createCapturedArgs, EMPTY_ARGS, EMPTY_NAMED, EMPTY_POSITIONAL, reifyArgs, reifyNamed, reifyPositional, DynamicAttribute, dynamicAttribute, SimpleDynamicAttribute, clientBuilder, NewTreeBuilder, RemoteBlock, ResettableBlockImpl, LowLevelVM, isSerializationFirstNode, RehydrateTree, rehydrationBuilder, SERIALIZATION_FIRST_NODE_STRING, IteratorResult };
1222export type { SafeString };
1223export { destroy, isDestroyed, isDestroying, registerDestructor } from "@glimmer/destroyable";
1224//# sourceMappingURL=index.d.ts.map
\No newline at end of file