Skip to content

Instantly share code, notes, and snippets.

@tomdale
Last active August 10, 2017 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomdale/5dad6671d2621ec35d3ca4fee78742ff to your computer and use it in GitHub Desktop.
Save tomdale/5dad6671d2621ec35d3ca4fee78742ff to your computer and use it in GitHub Desktop.
// PDI lazy evaluation of webpack modules
// 1. during compile time, answering what is in scope
// 1a. if it is in scope, what is the fully qualified path?
// 2. compilation handle + metadata
// 3. please map this handle to a ComponentSpec (manager + definition)
// 4. please resolve (component name, referrer) into handle (for dynamic component helper)
// return wire format as metadata for compile step
// need to add hasComponentHelper
// DI feedback
type Specifier = [string, string];
type AbsoluteSpecifier = [string, string, boolean];
function specifierFor(type: string, name: string): Specifier {
return [type, name];
}
function resolveSpecifier(specifier: Specifier, referrer: AbsoluteSpecifier, owner: Owner): AbsoluteSpecifier {
if (isAbsolute(specifier)) { return specifier; }
return owner.identify(specifier, referrer);
}
function isAbsolute(specifier: Specifier | AbsoluteSpecifier): specifier is AbsoluteSpecifier {
return !!specifier[2];
}
type Handle = number;
/**
* Describes the results of compiling a single component's template.
*/
interface CompilationResult {
/**
* The unique numerical identifier for this component. At runtime in the
* browser, the application will be asked to provide the Glimmer VM with the
* corresponding component manager and component definition for this handle.
*/
handle: Handle;
/**
* Whether the template contained any uses of the `{{partial}}` helper.
*/
hasEval: boolean;
/**
* Whether the template contained any dynamic invocations of the
* `{{component}}` helper. Note that this only includes *dynamic* use; for
* example, `{{component 'MyComponent'}}` can be resolved at compilation times
* and from the compiler perspective is identical to `<MyComponent />`.
*/
hasDynamicComponentHelper: boolean;
}
/**
* Incrementally compiles component templates, building up a binary
* representation of the components of the entire application.
*/
abstract class BundleCompiler {
abstract compile(templateSource: string, specifier: Specifier, delegate: CompilerDelegate): Handle;
}
interface CompilerDelegate {
/**
* During compilation, the compiler will ask the delegate about each component
* invocation found in the passed template. If the component exists in scope,
* the delegate should return `true`. If the component does not exist in
* scope, return `false`. (Note that returning `false` will cause the
* compilation process to fail.)
*/
hasComponentInScope(componentName: string, referrer: Specifier): boolean;
/**
* If the delegate returns `true` from `hasComponentInScope()`, the compiler
* will next ask the delegate to turn the relative specifier into an
* globally-unique absolute specifier. By providing this unique identifier,
* the compiler avoids having to compile the same component multiple times if
* invoked from different locations.
*/
resolveComponentSpecifier(componentName: string, referrer: Specifier): AbsoluteSpecifier;
}
// Contains component definition and component manager
interface ComponentSpec {}
abstract class Environment {
/**
* Provides the hydrated component spec for a given component's handle.
*/
abstract resolveHandle(handle: Handle): ComponentSpec;
/**
* When the `{{component}}` helper is invoked dynamically, this method is
* called to convert the opaque user string into a `Handle` so the appropriate
* component can be created.
*
* The absolute specifier of the component where the helper was invoked is
* passed so that scoping rules can be applied. Depending on how dynamic the
* host environment is, additional data will need to be included at runtime to
* allow scoping rules to be resolved.
*
* Implementer Note: this means we will need to store the absolute specifier
* of the *invoking* component in the constants pool for templates that
* contain dynamic `{{component}}` helpers, so we can provide the referrer at
* runtime.
*/
abstract handleForComponent(name: string, referrer: AbsoluteSpecifier): Handle;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment