Skip to content

Commit

Permalink
Remove rollup plugin ts, use glimmer imports (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinkucharczyk authored Sep 28, 2023
1 parent 483b24b commit 2682766
Show file tree
Hide file tree
Showing 12 changed files with 3,219 additions and 3,086 deletions.
24 changes: 13 additions & 11 deletions ember-context/babel.config.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
{
"presets": [["@babel/preset-typescript", { "allExtensions": true, "onlyRemoveTypeImports": true }]],
"presets": [
[
"@babel/preset-typescript",
{ "allExtensions": true, "onlyRemoveTypeImports": true }
]
],
"plugins": [
"@embroider/addon-dev/template-colocation-plugin",
"@babel/plugin-transform-class-static-block",
["babel-plugin-ember-template-compilation", {
"targetFormat": "wire",
"compilerPath": "ember-source/dist/ember-template-compiler.js",
"transforms": [],
"enableLegacyModules": [
"ember-cli-htmlbars",
"ember-cli-htmlbars-inline-precompile",
"htmlbars-inline-precompile"
]
}],
[
"babel-plugin-ember-template-compilation",
{
"targetFormat": "hbs",
"transforms": []
}
],
["@babel/plugin-proposal-decorators", { "version": "legacy" }],
"@babel/plugin-proposal-class-properties"
]
Expand Down
9 changes: 6 additions & 3 deletions ember-context/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
},
"dependencies": {
"@embroider/addon-shim": "^1.0.0",
"@glimmer/component": "^1.1.2",
"ember-cli-htmlbars": "^6.2.0"
"@glimmer/component": "^1.1.2"
},
"devDependencies": {
"@babel/core": "^7.17.0",
Expand All @@ -64,10 +63,14 @@
"@babel/preset-typescript": "^7.18.6",
"@babel/runtime": "^7.17.0",
"@embroider/addon-dev": "^4.1.0",
"@glimmer/interfaces": "^0.84.3",
"@glimmer/runtime": "^0.84.3",
"@glimmer/util": "^0.84.3",
"@glint/core": "^1.1.0",
"@glint/environment-ember-loose": "^1.1.0",
"@glint/template": "^1.1.0",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-node-resolve": "^15.2.1",
"@tsconfig/ember": "^2.0.0",
"@types/ember": "^4.0.4",
"@types/ember__application": "^4.0.6",
Expand All @@ -91,6 +94,7 @@
"@typescript-eslint/parser": "^6.7.2",
"babel-plugin-ember-template-compilation": "^2.2.0",
"concurrently": "^8.0.1",
"ember-cli-htmlbars": "^6.2.0",
"ember-template-lint": "^5.11.2",
"eslint": "^8.33.0",
"eslint-config-prettier": "^9.0.0",
Expand All @@ -101,7 +105,6 @@
"prettier-plugin-ember-template-tag": "^1.1.0",
"rollup": "^3.21.8",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-ts": "^3.4.5",
"typescript": "^5.0.4"
},
"publishConfig": {
Expand Down
21 changes: 12 additions & 9 deletions ember-context/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { babel } from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import copy from 'rollup-plugin-copy';
import { Addon } from '@embroider/addon-dev/rollup';
import ts from 'rollup-plugin-ts';

const addon = new Addon({
srcDir: 'src',
destDir: 'dist',
});

// Add extensions here, such as ts, gjs, etc that you may import
const extensions = ['.js', '.ts'];

export default {
// This provides defaults that work well alongside `publicEntrypoints` below.
// You can augment this if you need to.
Expand Down Expand Up @@ -35,16 +39,15 @@ export default {
// This babel config should *not* apply presets or compile away ES modules.
// It exists only to provide development niceties for you, like automatic
// template colocation.
//
// By default, this will load the actual babel config from the file
// babel.config.json.
ts({
transpiler: 'babel',
transpileOnly: true,
babelConfig: './babel.config.json',
browserslist: ['last 2 firefox versions', 'last 2 chrome versions'],
// See `babel.config.json` for the actual Babel configuration!
babel({
extensions,
babelHelpers: 'bundled',
}),

// Allows rollup to resolve imports of files with the specified extensions
nodeResolve({ extensions }),

// Ensure that standalone .hbs files are properly integrated as Javascript.
addon.hbs(),

Expand Down
104 changes: 8 additions & 96 deletions ember-context/src/-private/@glimmer/opcodes.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1,12 @@
//github.com/glimmerjs/glimmer-vm/blob/14413355ef6b48c1ab416a91fb7ff950cf8511d8/packages/%40glimmer/interfaces/lib/vm-opcodes.d.ts#L14

// We can't use enums from @glimmer/interfaces due to the issue below:
// https://github.com/glimmerjs/glimmer-vm/issues/1294
// We can use type imports, but an enum would need to be transformed into JS,
// which fails.
// We copy the opcodes from the source into here, and only the ones that are
// relevant to us.
// This is safe, because the opcodes should be stable.
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/vm/lib/opcodes.ts#L196
export const enum Op {
Helper = 16,
SetNamedVariables = 17,
SetBlocks = 18,
SetVariable = 19,
SetBlock = 20,
GetVariable = 21,
GetProperty = 22,
GetBlock = 23,
SpreadBlock = 24,
HasBlock = 25,
HasBlockParams = 26,
Concat = 27,
Constant = 28,
ConstantReference = 29,
Primitive = 30,
PrimitiveReference = 31,
ReifyU32 = 32,
Dup = 33,
Pop = 34,
Load = 35,
Fetch = 36,
RootScope = 37,
VirtualRootScope = 38,
ChildScope = 39,
PopScope = 40,
Text = 41,
Comment = 42,
AppendHTML = 43,
AppendSafeHTML = 44,
AppendDocumentFragment = 45,
AppendNode = 46,
AppendText = 47,
OpenElement = 48,
OpenDynamicElement = 49,
PushRemoteElement = 50,
StaticAttr = 51,
DynamicAttr = 52,
ComponentAttr = 53,
FlushElement = 54,
CloseElement = 55,
PopRemoteElement = 56,
Modifier = 57,
BindDynamicScope = 58,
PushDynamicScope = 59,
PopDynamicScope = 60,
CompileBlock = 61,
PushBlockScope = 62,
PushSymbolTable = 63,
InvokeYield = 64,
JumpIf = 65,
JumpUnless = 66,
JumpEq = 67,
AssertSame = 68,
Enter = 69,
Exit = 70,
ToBoolean = 71,
EnterList = 72,
ExitList = 73,
Iterate = 74,
Main = 75,
ContentType = 76,
Curry = 77,
PushComponentDefinition = 78,
PushDynamicComponentInstance = 79,
ResolveDynamicComponent = 80,
ResolveCurriedComponent = 81,
PushArgs = 82,
PushEmptyArgs = 83,
PopArgs = 84,
PrepareArgs = 85,
CaptureArgs = 86,
CreateComponent = 87,
RegisterComponentDestructor = 88,
PutComponentOperations = 89,
GetComponentSelf = 90,
GetComponentTagName = 91,
GetComponentLayout = 92,
BindEvalScope = 93,
SetupForEval = 94,
PopulateLayout = 95,
InvokeComponentLayout = 96,
BeginComponentTransaction = 97,
CommitComponentTransaction = 98,
DidCreateElement = 99,
DidRenderLayout = 100,
ResolveMaybeLocal = 102,
Debugger = 103,
Size = 104,
StaticComponentAttr = 105,
DynamicContentType = 106,
DynamicHelper = 107,
DynamicModifier = 108,
IfInline = 109,
Not = 110,
GetDynamicVar = 111,
Log = 112,
}
11 changes: 7 additions & 4 deletions ember-context/src/-private/opcodes.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import type { ComponentInstance } from '@glimmer/interfaces';
import type { UpdatingVM } from '@glimmer/runtime';

export class ProvideConsumeContextUpdateOpcode {
// "instance" is a VM component instance
constructor(private instance: any) {}
constructor(private instance: ComponentInstance) {}

// vm is an instance of the updating VM:
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/vm/update.ts#L33
evaluate(vm: any) {
evaluate(vm: UpdatingVM) {
vm.env.provideConsumeContextContainer?.enter(this.instance);
}
}

export class ProvideConsumeContextDidRenderOpcode {
// "instance" is a VM component instance
constructor(private instance: any) {}
constructor(private instance: ComponentInstance) {}

// vm is an instance of the updating VM:
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/vm/update.ts#L33
evaluate(vm: any) {
evaluate(vm: UpdatingVM) {
vm.env.provideConsumeContextContainer?.exit(this.instance);
}
}
34 changes: 18 additions & 16 deletions ember-context/src/-private/override-glimmer-runtime-classes.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,79 @@
import { Op } from './@glimmer/opcodes';
import {
ProvideConsumeContextDidRenderOpcode,
ProvideConsumeContextUpdateOpcode,
} from './opcodes';
import { ProvideConsumeContextContainer } from './provide-consume-context-container';
import type { ComponentInstance } from '@glimmer/interfaces';
import type {
LowLevelVM as GlimmerLowLevelVM,
EnvironmentImpl as GlimmerEnvironmentImpl,
} from '@glimmer/runtime';
import { Op } from './@glimmer/opcodes';

function overrideVM(runtime: any) {
const LowLevelVM = runtime.LowLevelVM;
const LowLevelVM = runtime.LowLevelVM as typeof GlimmerLowLevelVM;
const originalNext = LowLevelVM.prototype.next;

// We can't reach into the opcode definitions themselves, but we can hook into
// when they're evaluated ("next"), and execute additional code when the
// opcodes we're interested are called.
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/vm/append.ts#L603C1-L603C1
LowLevelVM.prototype.next = function (...args: any) {
LowLevelVM.prototype.next = function () {
// The actual evaluation happens in the "low level VM":
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/vm/low-level.ts#L112
// but that isn't exposed to us.
// Luckily, the VM we do have access to exposes the "pc" register, and the
// "program" instance, which is all we need to get the current opcode.
const opcode = this.program.opcode(this.pc);

// GetComponentSelf opcode
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/vm/lib/opcodes.ts#L196
if (opcode.type === Op.GetComponentSelf) {
// Get the component instance from the VM
// (that's the VM's component instance, not the Glimmer Component one)
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/compiled/opcodes/component.ts#L579
const instance = this.fetchValue(opcode.op1);
const instance = this.fetchValue<ComponentInstance>(opcode.op1);

// Add the component to the stack
this.env.provideConsumeContextContainer?.enter(instance);
// When there are updates/rerenders, make sure we add to the stack again
this.updateWith(new ProvideConsumeContextUpdateOpcode(instance));
}

// DidRenderLayout opcode
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/vm/lib/opcodes.ts#L206
if (opcode.type === Op.DidRenderLayout) {
// Get the component instance from the VM
// (that's the VM's component instance, not the Glimmer Component one)
// https://github.com/glimmerjs/glimmer-vm/blob/68d371bdccb41bc239b8f70d832e956ce6c349d8/packages/%40glimmer/runtime/lib/compiled/opcodes/component.ts#L832
const instance = this.fetchValue(opcode.op1);
const instance = this.fetchValue<ComponentInstance>(opcode.op1);

// After the component has rendered, remove it from the stack
this.env.provideConsumeContextContainer?.exit(instance);
// On updates/rerenders, make sure to remove from the stack again
this.updateWith(new ProvideConsumeContextDidRenderOpcode(instance));
}

return originalNext.apply(this, ...args);
return originalNext.apply(this);
};
}

function overrideEnvironment(runtime: any) {
const EnvironmentImpl = runtime.EnvironmentImpl;
const EnvironmentImpl =
runtime.EnvironmentImpl as typeof GlimmerEnvironmentImpl;

const originalBegin = EnvironmentImpl.prototype.begin;
EnvironmentImpl.prototype.begin = function (...args: any[]) {
EnvironmentImpl.prototype.begin = function () {
if (this.provideConsumeContextContainer == null) {
this.provideConsumeContextContainer =
new ProvideConsumeContextContainer();
}

// When a render transaction is started, let our container know to reset
// the stack
this.provideConsumeContextContainer?.begin();
(this as any).provideConsumeContextContainer?.begin();

return originalBegin.apply(this, ...args);
return originalBegin.apply(this);
};

const originalCommit = EnvironmentImpl.prototype.commit;
EnvironmentImpl.prototype.commit = function (...args: any[]) {
EnvironmentImpl.prototype.commit = function () {
if (this.provideConsumeContextContainer == null) {
this.provideConsumeContextContainer =
new ProvideConsumeContextContainer();
Expand All @@ -81,7 +83,7 @@ function overrideEnvironment(runtime: any) {
// the stack
this.provideConsumeContextContainer?.commit();

return originalCommit.apply(this, ...args);
return originalCommit.apply(this);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Stack } from './stack';
import type { ComponentInstance } from '@glimmer/interfaces';
import { Stack } from '@glimmer/util';

// Map of component class that contain @provide decorated properties, with their
// respective context keys and property names
Expand Down Expand Up @@ -65,7 +66,7 @@ export class ProvideConsumeContextContainer {
}
}

enter(instance: any): void {
enter(instance: ComponentInstance): void {
const componentDefinitionClass = instance.definition.state;
const actualComponentInstance = (instance?.state as any)?.component;

Expand Down Expand Up @@ -105,7 +106,7 @@ export class ProvideConsumeContextContainer {
}
}

exit(instance: any): void {
exit(instance: ComponentInstance): void {
const actualComponentInstance = (instance?.state as any)?.component;

if (actualComponentInstance != null) {
Expand Down
Loading

0 comments on commit 2682766

Please sign in to comment.