From 97c9de91b2089e8628c4ba49f9bf82859499d460 Mon Sep 17 00:00:00 2001 From: Tom Dale Date: Mon, 5 Feb 2018 08:26:00 -0500 Subject: [PATCH] Pass at inline API docs Annotates all exports from @glimmer/application as either public or internal, using AEDoc syntax. --- .../application/src/application-registry.ts | 10 +++- .../@glimmer/application/src/application.ts | 60 +++++++++++++++---- .../application/src/builders/dom-builder.ts | 10 ++++ .../src/builders/rehydrating-builder.ts | 10 ++++ .../@glimmer/application/src/environment.ts | 2 + .../application/src/helpers/action.ts | 2 + .../@glimmer/application/src/helpers/if.ts | 1 + packages/@glimmer/application/src/iterable.ts | 1 + .../src/loaders/bytecode/loader.ts | 21 +++++++ .../src/loaders/bytecode/resolver.ts | 5 ++ .../src/loaders/runtime-compiler/loader.ts | 2 + .../src/loaders/runtime-compiler/resolver.ts | 1 + .../src/renderers/async-renderer.ts | 26 ++++++++ .../src/renderers/sync-renderer.ts | 16 +++++ 14 files changed, 153 insertions(+), 14 deletions(-) diff --git a/packages/@glimmer/application/src/application-registry.ts b/packages/@glimmer/application/src/application-registry.ts index 60b23d127..124be414a 100644 --- a/packages/@glimmer/application/src/application-registry.ts +++ b/packages/@glimmer/application/src/application-registry.ts @@ -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; @@ -76,4 +84,4 @@ export default class ApplicationRegistry implements RegistryAccessor { return this._toAbsoluteSpecifier(specifier); } } -} +} \ No newline at end of file diff --git a/packages/@glimmer/application/src/application.ts b/packages/@glimmer/application/src/application.ts index 32a28f23f..19c331f27 100644 --- a/packages/@glimmer/application/src/application.ts +++ b/packages/@glimmer/application/src/application.ts @@ -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 { /** @@ -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 { /** @@ -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 { /** @@ -73,6 +79,11 @@ export interface Renderer { rerender(): void | Promise; } +/** + * Options for configuring an instance of [Application]. + * + * @public + */ export interface ApplicationOptions { builder: Builder; loader: Loader; @@ -82,11 +93,24 @@ 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; @@ -94,14 +118,21 @@ export interface AppRoot { nextSibling: Option; } +/** @internal */ export interface ApplicationConstructor { 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; @@ -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 { this.initialize(); @@ -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(); @@ -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); @@ -258,7 +291,7 @@ export default class Application implements Owner { }; } - /** @hidden */ + /** @internal */ protected async _render(): Promise { let { env } = this; @@ -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; @@ -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 { return this._container.factoryFor(this.identify(specifier, referrer)); } - /** @hidden */ + /** @internal */ lookup(specifier: string, referrer?: string): any { return this._container.lookup(this.identify(specifier, referrer)); } diff --git a/packages/@glimmer/application/src/builders/dom-builder.ts b/packages/@glimmer/application/src/builders/dom-builder.ts index 67144402a..012f9d676 100644 --- a/packages/@glimmer/application/src/builders/dom-builder.ts +++ b/packages/@glimmer/application/src/builders/dom-builder.ts @@ -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; diff --git a/packages/@glimmer/application/src/builders/rehydrating-builder.ts b/packages/@glimmer/application/src/builders/rehydrating-builder.ts index f2a6d2b83..8cc04ce7b 100644 --- a/packages/@glimmer/application/src/builders/rehydrating-builder.ts +++ b/packages/@glimmer/application/src/builders/rehydrating-builder.ts @@ -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); diff --git a/packages/@glimmer/application/src/environment.ts b/packages/@glimmer/application/src/environment.ts index 3599e415d..73a380028 100644 --- a/packages/@glimmer/application/src/environment.ts +++ b/packages/@glimmer/application/src/environment.ts @@ -21,11 +21,13 @@ import RuntimeResolver from './loaders/runtime-compiler/loader'; type KeyFor = (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; diff --git a/packages/@glimmer/application/src/helpers/action.ts b/packages/@glimmer/application/src/helpers/action.ts index a66f08257..9faf3081b 100644 --- a/packages/@glimmer/application/src/helpers/action.ts +++ b/packages/@glimmer/application/src/helpers/action.ts @@ -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(); @@ -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; diff --git a/packages/@glimmer/application/src/helpers/if.ts b/packages/@glimmer/application/src/helpers/if.ts index 4e7d33528..ec5c8c61b 100644 --- a/packages/@glimmer/application/src/helpers/if.ts +++ b/packages/@glimmer/application/src/helpers/if.ts @@ -1,3 +1,4 @@ +/** @internal */ export default function ifHelper(params: any[]) { return params[0] ? params[1] : params[2]; } diff --git a/packages/@glimmer/application/src/iterable.ts b/packages/@glimmer/application/src/iterable.ts index 648ac3e17..65f3349ae 100644 --- a/packages/@glimmer/application/src/iterable.ts +++ b/packages/@glimmer/application/src/iterable.ts @@ -88,6 +88,7 @@ class EmptyIterator implements OpaqueIterator { const EMPTY_ITERATOR = new EmptyIterator(); +/** @internal */ export default class Iterable implements AbstractIterable, UpdatableReference, UpdatableReference> { public tag: Tag; private ref: Reference; diff --git a/packages/@glimmer/application/src/loaders/bytecode/loader.ts b/packages/@glimmer/application/src/loaders/bytecode/loader.ts index 6cb9c5879..6747fdec6 100644 --- a/packages/@glimmer/application/src/loaders/bytecode/loader.ts +++ b/packages/@glimmer/application/src/loaders/bytecode/loader.ts @@ -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; @@ -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; diff --git a/packages/@glimmer/application/src/loaders/bytecode/resolver.ts b/packages/@glimmer/application/src/loaders/bytecode/resolver.ts index baa8642a3..29c90b300 100644 --- a/packages/@glimmer/application/src/loaders/bytecode/resolver.ts +++ b/packages/@glimmer/application/src/loaders/bytecode/resolver.ts @@ -23,6 +23,9 @@ export interface TemplateMeta { specifier: string; } +/** + * @internal + */ export const enum ModuleTypes { HELPER_FACTORY, HELPER @@ -34,6 +37,8 @@ export interface TemplateLocator { } /** * Exchanges VM handles for concrete implementations. + * + * @internal */ export default class BytecodeResolver implements RuntimeResolver { constructor(protected owner: Owner, protected table: Opaque[], protected meta: Dict, private prefix: string) { diff --git a/packages/@glimmer/application/src/loaders/runtime-compiler/loader.ts b/packages/@glimmer/application/src/loaders/runtime-compiler/loader.ts index fa82a8c54..b2093463d 100644 --- a/packages/@glimmer/application/src/loaders/runtime-compiler/loader.ts +++ b/packages/@glimmer/application/src/loaders/runtime-compiler/loader.ts @@ -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) { diff --git a/packages/@glimmer/application/src/loaders/runtime-compiler/resolver.ts b/packages/@glimmer/application/src/loaders/runtime-compiler/resolver.ts index 49b092b06..038586118 100644 --- a/packages/@glimmer/application/src/loaders/runtime-compiler/resolver.ts +++ b/packages/@glimmer/application/src/loaders/runtime-compiler/resolver.ts @@ -49,6 +49,7 @@ export interface SerializedTemplateWithLazyBlock { meta: Specifier; } +/** @public */ export default class RuntimeResolver implements IRuntimeResolver { templateOptions: TemplateOptions; handleLookup: TypedRegistry[] = []; diff --git a/packages/@glimmer/application/src/renderers/async-renderer.ts b/packages/@glimmer/application/src/renderers/async-renderer.ts index c590f8e73..36c23721a 100644 --- a/packages/@glimmer/application/src/renderers/async-renderer.ts +++ b/packages/@glimmer/application/src/renderers/async-renderer.ts @@ -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; diff --git a/packages/@glimmer/application/src/renderers/sync-renderer.ts b/packages/@glimmer/application/src/renderers/sync-renderer.ts index 80bfd625c..4371a952d 100644 --- a/packages/@glimmer/application/src/renderers/sync-renderer.ts +++ b/packages/@glimmer/application/src/renderers/sync-renderer.ts @@ -1,6 +1,22 @@ import { TemplateIterator, RenderResult } from '@glimmer/runtime'; import { Renderer } from '../application'; +/** + * Performs a synchronous initial render of templates. + * + * @remarks + * + * The SyncRenderer will render a template as fast as possible, continuing to + * work until the template has been completely rendered. + * + * While this delivers the fastest absolute rendering performance, large + * templates may cause the main thread to be consumed for long periods of time, + * leading to user-noticeable performance degradation, or jank. + * + * See also: {@link AsyncRenderer} + * + * @public + */ export default class SyncRenderer implements Renderer { result: RenderResult;