Skip to content
This repository has been archived by the owner on Oct 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #108 from glimmerjs/inline-comments-1
Browse files Browse the repository at this point in the history
Inline API docs for @glimmer/application
  • Loading branch information
tomdale authored Feb 6, 2018
2 parents a28d11e + 97c9de9 commit 59b7e40
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 14 deletions.
10 changes: 9 additions & 1 deletion packages/@glimmer/application/src/application-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ function isTypeSpecifier(specifier: string) {
return specifier.indexOf(':') === -1;
}

/**
* A repository of application objects, indexed by type and name.
*
* {@link Initializer | Initializers} can add or override objects in the system
* before the application boots, customizing runtime behavior.
*
* @internal
*/
export default class ApplicationRegistry implements RegistryAccessor {
private _registry: Registry;
private _resolver: Resolver;
Expand Down Expand Up @@ -76,4 +84,4 @@ export default class ApplicationRegistry implements RegistryAccessor {
return this._toAbsoluteSpecifier(specifier);
}
}
}
}
60 changes: 47 additions & 13 deletions packages/@glimmer/application/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import Environment from './environment';
* browser a builder might construct DOM elements, while on the server it may
* instead construct HTML. An object implementing the Builder interface should
* return a concrete instance of an ElementBuilder from its getBuilder method.
*
* @public
*/
export interface Builder {
/**
Expand All @@ -44,6 +46,8 @@ export interface Builder {
* Loaders are responsible for loading and preparing all of the templates and
* other metadata required to get a Glimmer.js application into a functioning
* state.
*
* @public
*/
export interface Loader {
/**
Expand All @@ -57,6 +61,8 @@ export interface Loader {
* from a Loader, and re-rendering when component state has been invalidated.
* The Renderer may be either synchronous or asynchronous, and controls its own
* scheduling.
*
* @public
*/
export interface Renderer {
/**
Expand All @@ -73,6 +79,11 @@ export interface Renderer {
rerender(): void | Promise<void>;
}

/**
* Options for configuring an instance of [Application].
*
* @public
*/
export interface ApplicationOptions {
builder: Builder;
loader: Loader;
Expand All @@ -82,26 +93,46 @@ export interface ApplicationOptions {
document?: Simple.Document;
}

/**
* Initializers run when an [Application] boots and allow extending the
* application with additional functionality. See
* [Application#registerInitializer].
*
* @public
*/
export interface Initializer {
name?: string;
initialize(registry: RegistryWriter): void;
}

/**
* A data structure created when a root Glimmer component is rendered into the
* DOM via the [Application#renderComponent] method.
*
* @internal
*/
export interface AppRoot {
id: number;
component: string;
parent: Simple.Node;
nextSibling: Option<Simple.Node>;
}

/** @internal */
export interface ApplicationConstructor<T = Application> {
new (options: ApplicationOptions): T;
}

/** @internal */
export type Notifier = [() => void, (err: Error) => void];

const DEFAULT_DOCUMENT = typeof document === 'object' ? document : null;

/**
* The central control point for starting and running Glimmer components.
*
* @public
*/
export default class Application implements Owner {
public rootName: string;
public resolver: Resolver;
Expand Down Expand Up @@ -169,7 +200,9 @@ export default class Application implements Owner {

/**
* Initializes the application and renders any components that have been
* registered via `renderComponent()`.
* registered via [renderComponent].
*
* @public
*/
async boot(): Promise<void> {
this.initialize();
Expand Down Expand Up @@ -199,23 +232,23 @@ export default class Application implements Owner {
}, 0);
}

/** @hidden */
/** @internal */
initialize(): void {
this.initRegistry();
this.initContainer();
}

/** @hidden */
/** @internal */
registerInitializer(initializer: Initializer): void {
this._initializers.push(initializer);
}

/**
* @hidden
*
* Initializes the registry, which maps names to objects in the system. Addons
* and subclasses can customize the behavior of a Glimmer application by
* overriding objects in the registry.
*
* @internal
*/
protected initRegistry(): void {
let registry = this._registry = new Registry();
Expand All @@ -241,10 +274,10 @@ export default class Application implements Owner {
}

/**
* @hidden
*
* Initializes the container, which stores instances of objects that come from
* the registry.
*
* @internal
*/
protected initContainer(): void {
this._container = new Container(this._registry, this.resolver);
Expand All @@ -258,7 +291,7 @@ export default class Application implements Owner {
};
}

/** @hidden */
/** @internal */
protected async _render(): Promise<void> {
let { env } = this;

Expand Down Expand Up @@ -290,13 +323,14 @@ export default class Application implements Owner {
}
}

/** @hidden
*
/**
* Ensures the DOM is up-to-date by performing a revalidation on the root
* template's render result. This method should not be called directly;
* instead, any mutations in the program that could cause side-effects should
* call `scheduleRerender()`, which ensures that DOM updates only happen once
* at the end of the browser's event loop.
*
* @internal
*/
protected async _rerender() {
let { env } = this;
Expand Down Expand Up @@ -332,18 +366,18 @@ export default class Application implements Owner {
/**
* Owner interface implementation
*
* @hidden
* @internal
*/
identify(specifier: string, referrer?: string): string {
return this.resolver.identify(specifier, referrer);
}

/** @hidden */
/** @internal */
factoryFor(specifier: string, referrer?: string): Factory<any> {
return this._container.factoryFor(this.identify(specifier, referrer));
}

/** @hidden */
/** @internal */
lookup(specifier: string, referrer?: string): any {
return this._container.lookup(this.identify(specifier, referrer));
}
Expand Down
10 changes: 10 additions & 0 deletions packages/@glimmer/application/src/builders/dom-builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { Cursor, clientBuilder, Environment, ElementBuilder } from "@glimmer/runtime";
import { Builder } from "../application";

/**
* A {@link Builder} that creates DOM elements when templates render.
*
* Use a DOMBuilder for Glimmer.js applications that do not use server-side
* rendering. If you are using server-side rendering, the
* {@link RehydratingBuilder} can be used to rehydrate existing DOM instead of
* replacing it.
*
* @public
*/
export default class DOMBuilder implements Builder {
protected cursor: Cursor;

Expand Down
10 changes: 10 additions & 0 deletions packages/@glimmer/application/src/builders/rehydrating-builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import DOMBuilder from './dom-builder';
import { rehydrationBuilder, Environment, ElementBuilder } from '@glimmer/runtime';

/**
* A {@link Builder} that re-uses existing DOM provided via server-side rendering.
*
* The RehydratingBuilder attempts to use the DOM produced by SSR-generated HTML
* during template rendering. This allows components to "rehydrate" existing DOM
* elements, making initial render faster and preventing the browser from having
* to perform additional layout and paint operations.
*
* @public
*/
export default class RehydratingBuilder extends DOMBuilder {
getBuilder(env: Environment): ElementBuilder {
return rehydrationBuilder(env, this.cursor);
Expand Down
2 changes: 2 additions & 0 deletions packages/@glimmer/application/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import RuntimeResolver from './loaders/runtime-compiler/loader';

type KeyFor<T> = (item: Opaque, index: T) => string;

/** @internal */
export interface EnvironmentOptions {
document?: HTMLDocument;
appendOperations?: DOMTreeConstruction;
}

/** @internal */
export default class Environment extends GlimmerEnvironment {
private uselessAnchor: HTMLAnchorElement;
public resolver: RuntimeResolver;
Expand Down
2 changes: 2 additions & 0 deletions packages/@glimmer/application/src/helpers/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { UpdatableReference } from "@glimmer/component";
import { VM, Arguments } from "@glimmer/runtime";
import { Opaque } from '@glimmer/interfaces';

/** @internal */
export default function buildAction(vm: VM, _args: Arguments) {
let componentRef = vm.getSelf();
let args = _args.capture();
Expand Down Expand Up @@ -30,6 +31,7 @@ function throwNoActionError(actionFunc: any, actionFuncReference: Opaque) {
throw new Error(`You tried to create an action with the {{action}} helper, but the first argument ${referenceInfo}was ${typeof actionFunc} instead of a function.`);
}

/** @internal */
export function debugInfoForReference(reference: any): string {
let message = '';
let parent;
Expand Down
1 change: 1 addition & 0 deletions packages/@glimmer/application/src/helpers/if.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** @internal */
export default function ifHelper(params: any[]) {
return params[0] ? params[1] : params[2];
}
1 change: 1 addition & 0 deletions packages/@glimmer/application/src/iterable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class EmptyIterator implements OpaqueIterator {

const EMPTY_ITERATOR = new EmptyIterator();

/** @internal */
export default class Iterable implements AbstractIterable<Opaque, Opaque, IterationItem<Opaque, Opaque>, UpdatableReference<Opaque>, UpdatableReference<Opaque>> {
public tag: Tag;
private ref: Reference<Opaque>;
Expand Down
21 changes: 21 additions & 0 deletions packages/@glimmer/application/src/loaders/bytecode/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export interface Metadata {
table: ProgramSymbolTable;
}

/**
* Additional metadata that accompanies the binary bytecode data.
*
* @public
*/
export interface BytecodeData {
prefix: string;
mainEntry: number;
Expand All @@ -33,6 +38,22 @@ export interface BytecodeLoaderOptions {
data: BytecodeData;
}

/**
* Initializes an Application with a binary bytecode (.gbx) file containing
* compiled templates.
*
* @remarks
* Once all of the templates have been parsed into IR, the compiler performs a
* final pass that resolves symbolic addresses and writes the final opcodes into
* a shared binary buffer. In native compiler terms, you can think of this as
* the "linking" step that produces the final executable. This binary executable
* is saved to disk as a .gbx file that can be served to a browser and evaluated
* with the runtime.
*
* For details, see {@link Application}.
*
* @public
*/
export default class BytecodeLoader implements Loader {
protected data: BytecodeData;
protected bytecode: Promise<ArrayBuffer>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export interface TemplateMeta {
specifier: string;
}

/**
* @internal
*/
export const enum ModuleTypes {
HELPER_FACTORY,
HELPER
Expand All @@ -34,6 +37,8 @@ export interface TemplateLocator {
}
/**
* Exchanges VM handles for concrete implementations.
*
* @internal
*/
export default class BytecodeResolver implements RuntimeResolver<TemplateMeta> {
constructor(protected owner: Owner, protected table: Opaque[], protected meta: Dict<Metadata>, private prefix: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface Specifier {
* final template compilation step client-side. It configures the compiler to
* resolve templates, helpers and other objects from the runtime registry, and
* enables just-in-time compilation of templates as they are encountered.
*
* @public
*/
export default class RuntimeCompilerLoader implements Loader {
constructor(public resolver: Resolver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export interface SerializedTemplateWithLazyBlock<Specifier> {
meta: Specifier;
}

/** @public */
export default class RuntimeResolver implements IRuntimeResolver<Specifier> {
templateOptions: TemplateOptions<Specifier>;
handleLookup: TypedRegistry<Opaque>[] = [];
Expand Down
26 changes: 26 additions & 0 deletions packages/@glimmer/application/src/renderers/async-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,32 @@ export interface AsyncRendererOptions {

const DEFAULT_TIMEOUT = 250;

/**
* Performs an asynchronous initial render of templates using
* requestIdleCallback.
*
* @remarks
* The AsyncRenderer instructs Glimmer to perform the initial render
* asynchronously. That is, it will yield back control of the main thread to the
* browser every so often, so that the browser may respond to user events like
* taps or scrolls so a user's device remains responsive.
*
* Rather than completing the initial render as fast as possible, by consuming
* all of the main thread's resources until the render is complete, the
* AsyncRenderer instructs the VM to execute operations for a few milliseconds
* at a time.
*
* Afer a few milliseconds, the AsyncRenderer will pause rendering, schedule
* more rendering to happen in the future, then yield control back to the
* browser. This process continues until there are no more instructions for the
* VM to execute and the initial render is complete.
*
* Under the hood, work is scheduled using
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback | requestIdleCallback},
* which allows JavaScript programs to queue work to happen during idle periods.
*
* @public
*/
export default class AsyncRenderer implements Renderer {
public timeout: number;
protected result: RenderResult;
Expand Down
Loading

0 comments on commit 59b7e40

Please sign in to comment.