UNPKG

3.41 kBTypeScriptView Raw
1/**
2 * This file describes the interface between compilation time
3 * and runtime.
4 *
5 * # Locators
6 *
7 * Compile time and runtime must share the same Locator. A Locator is an
8 * object that describes the location of a template, and is roughly a
9 * module name. The compiler and runtime may use the Locator to locally
10 * resolve names relative to the template the name was found in, but must
11 * share resolution rules between compilation time and runtime.
12 *
13 * For example, given this template with Locator
14 * `{ module: 'components/Articles/Container' }:
15 *
16 * ```
17 * <TabBar />
18 * ```
19 *
20 * The compiler may resolve `<TabBar>` to `components/Articles/TabBar`. The
21 * important thing is that the compiler and runtime share resolution rules.
22 *
23 * # CompileTimeLookup
24 *
25 * When compiling an application, the `CompileTimeLookup` is responsible
26 * for resolving helpers, modifiers, and components into "handles"
27 * (numbers) that can be embedded into the program and used at runtime.
28 *
29 * # RuntimeResolver
30 *
31 * The `RuntimeResolver` has two responsibilities.
32 *
33 * 1. To turn handles created by the `CompileTimeLookup` into live helpers,
34 * modifiers, and components.
35 * 2. To resolve dynamic components at runtime that come from
36 * calls to `{{component dynamic}}`.
37 *
38 * The `CompileTimeLookup` and `RuntimeResolver` must maintain symmetry
39 * between:
40 *
41 * * `resolver.resolve(lookup.lookupComponentDefinition(name, referrer))`; and
42 * * `resolver.lookupComponentDefinition(name, referrer))`
43 *
44 * # Coupling
45 *
46 * In practice, the `CompileTimeLookup` and `RuntimeResolver` are two parts
47 * of one system. The goal of this system is to allow the `CompileTimeLookup`
48 * to do as much resolution as possible ahead of time, while still allowing
49 * the `RuntimeResolver` to do dynamic resolution when necessary.
50 */
51
52import type {
53 CapabilityMask,
54 ComponentDefinitionState,
55 ComponentInstanceState,
56} from './components.js';
57import type { Nullable } from './core.js';
58import type { InternalComponentManager } from './managers.js';
59import type { HelperDefinitionState, ModifierDefinitionState, Owner } from './runtime.js';
60import type { CompilableProgram, Template } from './template.js';
61
62export interface CompileTimeComponent {
63 handle: number;
64 capabilities: CapabilityMask;
65 compilable: Nullable<CompilableProgram>;
66}
67
68export interface ResolvedComponentDefinition<
69 D = ComponentDefinitionState,
70 I = ComponentInstanceState,
71 M extends InternalComponentManager<I, D> = InternalComponentManager<I, D>,
72> {
73 state: D;
74 manager: M;
75 template: Template | null;
76}
77
78export enum ResolverContext {
79 Component,
80 Modifier,
81 Helper,
82 HelperOrComponent,
83}
84
85export interface CompileTimeResolver<O extends Owner = Owner> {
86 lookupHelper(name: string, owner: O): Nullable<HelperDefinitionState>;
87 lookupModifier(name: string, owner: O): Nullable<ModifierDefinitionState>;
88 lookupComponent(name: string, owner: O): Nullable<ResolvedComponentDefinition>;
89
90 // TODO: These are used to lookup keywords that are implemented as helpers/modifiers.
91 // We should try to figure out a cleaner way to do this.
92 lookupBuiltInHelper(name: string): Nullable<HelperDefinitionState>;
93 lookupBuiltInModifier(name: string): Nullable<ModifierDefinitionState>;
94}
95
96export interface RuntimeResolver<O extends Owner = Owner> {
97 lookupComponent(name: string, owner: O): Nullable<ResolvedComponentDefinition>;
98}