Skip to content

Commit

Permalink
[FEAT] Upstream manager infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Garrett committed Nov 16, 2020
1 parent f4e2e65 commit 61fec74
Show file tree
Hide file tree
Showing 27 changed files with 324 additions and 465 deletions.
8 changes: 4 additions & 4 deletions packages/@glimmer/component/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"dependencies": {
"@glimmer/env": "^0.1.7",
"@glimmer/util": "0.62.4",
"@glimmer/util": "0.65.0",
"@glimmer/core": "2.0.0-beta.11",
"broccoli-file-creator": "^2.1.1",
"broccoli-merge-trees": "^3.0.2",
Expand All @@ -43,11 +43,11 @@
"devDependencies": {
"@ember/optional-features": "^0.6.1",
"@glimmer/application-test-helpers": "^1.0.0",
"@glimmer/compiler": "0.62.4",
"@glimmer/interfaces": "0.62.4",
"@glimmer/compiler": "0.65.0",
"@glimmer/interfaces": "0.65.0",
"@glimmer/resolver": "^0.3.0",
"@glimmer/tracking": "2.0.0-beta.11",
"@glimmer/wire-format": "0.62.4",
"@glimmer/wire-format": "0.65.0",
"@types/ember": "~3.0.29",
"@types/ember-qunit": "~3.4.3",
"@types/ember-test-helpers": "~1.0.6",
Expand Down
19 changes: 10 additions & 9 deletions packages/@glimmer/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ export {

export { BaseEnvDelegate } from './src/environment/delegates';

export { setComponentManager, setHelperManager, setModifierManager } from './src/managers';
export type {
ModifierManager,
ModifierCapabilities,
ComponentManager,
ComponentCapabilities,
} from '@glimmer/interfaces';

export { setComponentManager, setModifierManager } from '@glimmer/runtime';
export { setHelperManager } from './src/managers';

export { TemplateArgs } from './src/interfaces';

export {
ModifierManager,
ModifierDefinition,
capabilities as modifierCapabilities,
Capabilities as ModifierCapabilities,
} from './src/managers/modifier';
export { ModifierDefinition, capabilities as modifierCapabilities } from './src/managers/modifier';

export {
HelperManager,
Expand All @@ -26,10 +29,8 @@ export {
} from './src/managers/helper';

export {
ComponentManager,
ComponentDefinition,
capabilities as componentCapabilities,
Capabilities as ComponentCapabilities,
} from './src/managers/component/custom';

export { templateOnlyComponent } from './src/managers/component/template-only';
Expand Down
14 changes: 7 additions & 7 deletions packages/@glimmer/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
},
"dependencies": {
"@glimmer/env": "^0.1.7",
"@glimmer/global-context": "0.62.4",
"@glimmer/interfaces": "0.62.4",
"@glimmer/opcode-compiler": "0.62.4",
"@glimmer/program": "0.62.4",
"@glimmer/runtime": "0.62.4",
"@glimmer/validator": "0.62.4",
"@glimmer/global-context": "0.65.0",
"@glimmer/interfaces": "0.65.0",
"@glimmer/opcode-compiler": "0.65.0",
"@glimmer/program": "0.65.0",
"@glimmer/runtime": "0.65.0",
"@glimmer/validator": "0.65.0",
"@simple-dom/interface": "^1.4.0"
},
"devDependencies": {
"@glimmer/compiler": "0.62.4",
"@glimmer/compiler": "0.65.0",
"@glimmer/component": "2.0.0-beta.11",
"@glimmer/tracking": "2.0.0-beta.11"
},
Expand Down
7 changes: 2 additions & 5 deletions packages/@glimmer/core/src/environment/delegates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,8 @@ export abstract class BaseEnvDelegate implements EnvironmentDelegate {
abstract isInteractive: boolean;
abstract protocolForURL(url: string): string;

extra = undefined;

onTransactionBegin(): void {
// Do nothing
}
enableDebugTooling = false;
owner = {};

onTransactionCommit(): void {
for (let i = 0; i < scheduledDestroyables.length; i++) {
Expand Down
119 changes: 40 additions & 79 deletions packages/@glimmer/core/src/managers/component/custom.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { assert, unwrapTemplate } from '@glimmer/util';
import {
ComponentManager as VMComponentManager,
ComponentCapabilities as VMComponentCapabilities,
Dict,
InternalComponentManager,
InternalComponentCapabilities,
VMArguments,
CapturedArguments,
RuntimeResolver,
WithStaticLayout,
Template,
TemplateOk,
Environment,
CompilableProgram,
DynamicScope,
ComponentManager,
ComponentManagerWithUpdateHook,
ComponentManagerWithAsyncLifeCycleCallbacks,
ComponentCapabilitiesVersions,
ComponentCapabilities,
ComponentManagerWithAsyncUpdateHook,
ComponentManagerWithDestructors,
} from '@glimmer/interfaces';
import { valueForRef, createConstRef, Reference } from '@glimmer/reference';
import { OWNER_KEY, DEFAULT_OWNER } from '../../owner';

import { getComponentManager } from '..';
import { TemplateMeta } from '../../template';
import { TemplateArgs } from '../../interfaces';
import { argsProxyFor } from '../util';
import { registerDestructor } from '@glimmer/runtime';
import { registerDestructor, getComponentManager, buildCapabilities } from '@glimmer/runtime';

export const VM_CAPABILITIES: VMComponentCapabilities = {
export const VM_CAPABILITIES: InternalComponentCapabilities = {
createInstance: true,
dynamicLayout: false,
dynamicTag: false,
Expand All @@ -37,56 +39,34 @@ export const VM_CAPABILITIES: VMComponentCapabilities = {
willDestroy: false,
};

export interface Capabilities {
asyncLifecycleCallbacks: boolean;
destructor: boolean;
updateHook: boolean;
}

export type OptionalCapabilities = Partial<Capabilities>;

export type ManagerAPIVersion = '3.4' | '3.13';

export function capabilities(
managerAPI: ManagerAPIVersion,
options: OptionalCapabilities = {}
): Capabilities {
export function capabilities<Version extends keyof ComponentCapabilitiesVersions>(
managerAPI: Version,
options: ComponentCapabilitiesVersions[Version] = {}
): ComponentCapabilities {
assert(
managerAPI === '3.4' || managerAPI === '3.13',
'Invalid component manager compatibility specified'
);

const updateHook = managerAPI !== '3.4' ? Boolean(options.updateHook) : true;
let updateHook = true;

if (managerAPI === '3.13') {
updateHook = Boolean((options as ComponentCapabilitiesVersions['3.13']).updateHook);
}

return {
asyncLifecycleCallbacks: Boolean(options.asyncLifecycleCallbacks),
return buildCapabilities({
asyncLifeCycleCallbacks: Boolean(options.asyncLifecycleCallbacks),
destructor: Boolean(options.destructor),
updateHook,
};
});
}

///////////

/**
* This is the public facing component manager. Named `ComponentManager` so the
* type is nice to external users, but it is different from the internal VM
* component manager.
*/
export interface ComponentManager<ComponentInstance> {
capabilities: Capabilities;
createComponent(definition: unknown, args: TemplateArgs): ComponentInstance;
getContext(instance: ComponentInstance): unknown;
}

export function hasAsyncLifecycleCallbacks<ComponentInstance>(
delegate: ComponentManager<ComponentInstance>
): delegate is ComponentManagerWithAsyncLifecycleCallbacks<ComponentInstance> {
return delegate.capabilities.asyncLifecycleCallbacks;
}

export interface ComponentManagerWithAsyncLifecycleCallbacks<ComponentInstance>
extends ComponentManager<ComponentInstance> {
didCreateComponent(instance: ComponentInstance): void;
): delegate is ComponentManagerWithAsyncLifeCycleCallbacks<ComponentInstance> {
return delegate.capabilities.asyncLifeCycleCallbacks;
}

export function hasUpdateHook<ComponentInstance>(
Expand All @@ -95,39 +75,18 @@ export function hasUpdateHook<ComponentInstance>(
return delegate.capabilities.updateHook;
}

export interface ComponentManagerWithUpdateHook<ComponentInstance>
extends ComponentManager<ComponentInstance> {
updateComponent(instance: ComponentInstance, args: TemplateArgs): void;
}

export function hasAsyncUpdateHook<ComponentInstance>(
delegate: ComponentManager<ComponentInstance>
): delegate is ComponentManagerWithAsyncUpdateHook<ComponentInstance> {
return hasAsyncLifecycleCallbacks(delegate) && hasUpdateHook(delegate);
}

export interface ComponentManagerWithAsyncUpdateHook<ComponentInstance>
extends ComponentManagerWithAsyncLifecycleCallbacks<ComponentInstance>,
ComponentManagerWithUpdateHook<ComponentInstance> {
didUpdateComponent(instance: ComponentInstance): void;
}

export function hasDestructors<ComponentInstance>(
delegate: ComponentManager<ComponentInstance>
): delegate is ComponentManagerWithDestructors<ComponentInstance> {
return delegate.capabilities.destructor;
}

export interface ComponentManagerWithDestructors<ComponentInstance>
extends ComponentManager<ComponentInstance> {
destroyComponent(instance: ComponentInstance): void;
}

export interface ComponentArguments {
positional: unknown[];
named: Dict<unknown>;
}

///////////

/**
Expand Down Expand Up @@ -157,14 +116,13 @@ export interface ComponentArguments {
*/
export default class CustomComponentManager<ComponentInstance>
implements
VMComponentManager<
InternalComponentManager<
VMCustomComponentState<ComponentInstance>,
VMCustomComponentDefinitionState<ComponentInstance>
>,
WithStaticLayout<
VMCustomComponentState<ComponentInstance>,
VMCustomComponentDefinitionState<ComponentInstance>,
RuntimeResolver
VMCustomComponentDefinitionState<ComponentInstance>
> {
create(
env: Environment,
Expand All @@ -175,7 +133,9 @@ export default class CustomComponentManager<ComponentInstance>
const { ComponentDefinition } = definition;
const capturedArgs = args.capture();
const owner = valueForRef(dynamicScope.get(OWNER_KEY)) as object;
const delegate = getComponentManager(owner, ComponentDefinition)!;
const delegate = getComponentManager(owner, ComponentDefinition) as ComponentManager<
ComponentInstance
>;

const argsProxy = argsProxyFor(capturedArgs, 'component');
const component = delegate.createComponent(ComponentDefinition, argsProxy);
Expand Down Expand Up @@ -220,7 +180,7 @@ export default class CustomComponentManager<ComponentInstance>

getCapabilities({
capabilities,
}: VMCustomComponentDefinitionState<ComponentInstance>): VMComponentCapabilities {
}: VMCustomComponentDefinitionState<ComponentInstance>): InternalComponentCapabilities {
return Object.assign({}, VM_CAPABILITIES, {
updateHook: capabilities.updateHook,
});
Expand All @@ -229,10 +189,8 @@ export default class CustomComponentManager<ComponentInstance>
didRenderLayout(): void {} // eslint-disable-line @typescript-eslint/no-empty-function
didUpdateLayout(): void {} // eslint-disable-line @typescript-eslint/no-empty-function

getStaticLayout({
definition,
}: VMCustomComponentDefinitionState<ComponentInstance>): CompilableProgram {
return definition.template.asLayout();
getStaticLayout({ definition }: VMCustomComponentDefinitionState<ComponentInstance>): Template {
return definition.template;
}
}

Expand All @@ -257,7 +215,7 @@ export class VMCustomComponentState<ComponentInstance> {

export interface VMCustomComponentDefinitionState<ComponentInstance> {
ComponentDefinition: ComponentDefinition<ComponentInstance>;
capabilities: Capabilities;
capabilities: ComponentCapabilities;
definition: VMCustomComponentDefinition<ComponentInstance>;
}

Expand All @@ -266,18 +224,21 @@ export const CUSTOM_COMPONENT_MANAGER = new CustomComponentManager();
export class VMCustomComponentDefinition<ComponentInstance> {
public state: VMCustomComponentDefinitionState<ComponentInstance>;
public manager = CUSTOM_COMPONENT_MANAGER as CustomComponentManager<ComponentInstance>;
public template: TemplateOk<TemplateMeta>;
public template: TemplateOk;
public handle: number;

constructor(
handle: number,
ComponentDefinition: ComponentDefinition<ComponentInstance>,
template: Template<TemplateMeta>
template: Template
) {
this.handle = handle;
this.template = unwrapTemplate(template);

const capabilities = getComponentManager(DEFAULT_OWNER, ComponentDefinition)!.capabilities;
const manager = getComponentManager(DEFAULT_OWNER, ComponentDefinition) as ComponentManager<
ComponentInstance
>;
const capabilities = manager.capabilities;

this.state = {
ComponentDefinition,
Expand Down
Loading

0 comments on commit 61fec74

Please sign in to comment.