Skip to content

Commit

Permalink
Progress on gjs support
Browse files Browse the repository at this point in the history
  • Loading branch information
NullVoxPopuli committed Aug 1, 2024
1 parent 69d4e81 commit 82cfc71
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 24 deletions.
12 changes: 12 additions & 0 deletions packages/repl-sdk/example/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ export const svelte = `
<h1>Hello {name}!</h1>
`.trim();

export const gjs = `
const greeting = 'hello there';
<template>
<h1>{{greeting}}</h1>
<style>
h1 { color: orange; }
</style>
</template>
`.trim();

export const md = `
# Markdown
Expand Down
11 changes: 9 additions & 2 deletions packages/repl-sdk/src/compilers.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,17 @@ export const compilers = {
},
},
md: {
compiler: async (config = {}, api) => {
compiler: async (...args) => {
const markdown = await import('./compilers/markdown.js');

return markdown.compiler(config, api);
return markdown.compiler(...args);
},
},
gjs: {
compiler: async (...args) => {
const gjs = await import('./compilers/glimmer-js.js');

return gjs.compiler(...args);
},
},
};
64 changes: 64 additions & 0 deletions packages/repl-sdk/src/compilers/glimmer-js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { esmsh, jsdelivr } from './cdn.js';

Check failure on line 1 in packages/repl-sdk/src/compilers/glimmer-js.js

View workflow job for this annotation

GitHub Actions / autofix

'jsdelivr' is defined but never used

/**
* @param {import('../types.ts').ResolvedCompilerOptions} config
* @param {import('../types.ts').PublicMethods} api
*/
export async function compiler(config = {}, api) {

Check failure on line 7 in packages/repl-sdk/src/compilers/glimmer-js.js

View workflow job for this annotation

GitHub Actions / autofix

'api' is defined but never used
const versions = config.versions || {};

const [babel, templatePlugin, { default: templateCompiler }, { Preprocessor }] =
await esmsh.importAll(versions, [
'@babel/standalone',
'babel-plugin-ember-template-compilation',
'ember-source/dist/ember-template-compiler.js',
'content-tag',
// Failed to load (will need to PR for browser support),
// so we have to use babel's decorator transforms,
// which ... aren't great.
// They force over-transforming of classes.
// 'decorator-transforms',
]);

const preprocessor = new Preprocessor();

return {
compile: async (text) => {
let preprocessed = preprocessor.process(text, 'dynamic-repl.js');
let transformed = await transform({ babel, templatePlugin, templateCompiler }, preprocessed);

return transformed.code;
},
render: async (element, compiled, extra, compiler) => {

Check failure on line 32 in packages/repl-sdk/src/compilers/glimmer-js.js

View workflow job for this annotation

GitHub Actions / autofix

'extra' is defined but never used

Check failure on line 32 in packages/repl-sdk/src/compilers/glimmer-js.js

View workflow job for this annotation

GitHub Actions / autofix

'compiler' is defined but never used
element.innerHTML = compiled;
},
};
}

async function transform({ babel, templatePlugin, templateCompiler }, text) {
console.log(templateCompiler, templatePlugin);

Check failure on line 39 in packages/repl-sdk/src/compilers/glimmer-js.js

View workflow job for this annotation

GitHub Actions / autofix

Unexpected console statement
return babel.transform(text, {
filename: `dynamic-repl.js`,
plugins: [
[
templatePlugin,
{
compiler: templateCompiler,
},
],
// [babel.availablePlugins['proposal-decorators'], { legacy: true }],
// [babel.availablePlugins['proposal-class-properties']],
],
presets: [
[
babel.availablePresets['env'],
{
// false -- keeps ES Modules
modules: false,
targets: { esmodules: true },
forceAllTransforms: false,
},
],
],
});
}
40 changes: 18 additions & 22 deletions packages/repl-sdk/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
interface PublicMethods {
compile: (
format: string,
text: string,
options?: {
flavor?: string;
fileName?: string;
}
) => Promise<HTMLElement>;
compile: (format: string, text: string, options?: {
flavor?: string;
fileName?: string;
}) => Promise<HTMLElement>

optionsFor: (format: string, flavor?: string) => Omit<CompilerConfig, 'compiler'>;
optionsFor: (format: string, flavor?: string) => Omit<CompilerConfig, 'compiler'>
}
export interface ResolvedCompilerOptions {
importMap?: { [importPath: string]: string };
resolve?: { [importPath: string]: unknown };
importMap: { [importPath: string]: string; };
resolve: { [importPath: string]: unknown; };
needsLiveMeta?: boolean;
versions?: { [packageName: string]: string };
versions: { [packageName: string]: string };
}

export interface CompilerConfig {
Expand Down Expand Up @@ -86,7 +82,7 @@ export interface CompilerConfig {
element: HTMLElement,
defaultExport: any,
extras: { compiled: string } & Record<string, unknown>,
compiler: PublicMethods
compiler: PublicMethods,
) => void;
}>;
}
Expand All @@ -97,26 +93,26 @@ export interface Options {
*
* Thehse will take precedence over the default CDN fallback.
*/
importMap?: { [importPath: string]: string };
importMap?: { [importPath: string]: string; };
/**
* Map of pre-resolved JS values to use as the import map
* These could assume the role of runtime virtual modules.
*
* These will take precedence over the importMap, and implicit CDN fallback.
*/
resolve?: { [importPath: string]: unknown };
resolve?: { [importPath: string]: unknown; }

/**
* Specifies which vesions of dependencies to when pulling from a CDN.
* Defaults to latest.
*/
* Specifies which vesions of dependencies to when pulling from a CDN.
* Defaults to latest.
*/
versions?: { [packageName: string]: string };

formats: {
[fileExtension: string]:
| CompilerConfig
| {
[flavor: string]: CompilerConfig;
};
| CompilerConfig
| {
[flavor: string]: CompilerConfig;
};
};
}
64 changes: 64 additions & 0 deletions packages/repl-sdk/tests-self/tests/ember.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Compiler } from 'repl-sdk';
import { describe, expect, test } from 'vitest';

describe('ember', () => {
describe('gjs', () => {
test('template-only', async () => {
let compiler = new Compiler();
let element = await compiler.compile(
'gjs',
`
const name = 'world';
<template>
<h1>Hello {{name}}!</h1>
<style>
h1 { color: red; }
</style>
</template>
`
);

// getComputedStyle doesn't work without the element existing in the document
document.body.appendChild(element);

let h1 = element.querySelector('h1');

expect(h1).toBeTruthy();
expect(h1?.textContent).toContain('Hello world!');
expect(window.getComputedStyle(h1!).color).toBe('rgb(255, 0, 0)');
});

test('class component', async () => {
let compiler = new Compiler();
let element = await compiler.compile(
'gjs',
`
import Component from '@glimmer/component';
export default class Demo extends Component {
name = 'world';
<template>
<h1>Hello {{this.name}}!</h1>
<style>
h1 { color: red; }
</style>
</template>
}
`
);

// getComputedStyle doesn't work without the element existing in the document
document.body.appendChild(element);

let h1 = element.querySelector('h1');

expect(h1).toBeTruthy();
expect(h1?.textContent).toContain('Hello world!');
expect(window.getComputedStyle(h1!).color).toBe('rgb(255, 0, 0)');
});
});
});

0 comments on commit 82cfc71

Please sign in to comment.