From c887f80b830ef60cf7019adfc3729d723fe082f7 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Sun, 21 Jul 2024 16:44:38 -0400 Subject: [PATCH 01/11] I think I figured out how to make a repl out of es-module-shim Progress Progress wip lockfile Hmm, why is react-dom not working as expected React tests work Tweak CI wip Cleanup a bit Vue tests Need to figure out mermaid Yay example Woo And Svelte eh Start planning how markdown is going to work Work on markdown compiler Progress Simplify, combine test-app Some fixes Markdown works (basically) Tests pass Lints Ah-ha, something I hav to fix Options are now passable Lint fix Progress on gjs support Ugh, too much node So much babel --- .eslintignore | 1 + .github/workflows/ci.yml | 4 +- .gitignore | 1 + apps/repl/package.json | 3 +- apps/tutorial/package.json | 3 +- dev/package.json | 3 +- .../limber-ui/test-app/package.json | 3 +- packages/ember-repl/addon/package.json | 1 + .../ember-repl/addon/src/compile/formats.ts | 5 + .../ember-repl/addon/src/compile/imports.ts | 36 + .../ember-repl/addon/src/compile/index.ts | 8 + .../ember-repl/addon/src/compile/types.ts | 21 +- .../tests/rendering/compiled-test.gts | 64 +- packages/repl-sdk/.eslintignore | 1 + packages/repl-sdk/.eslintrc.cjs | 32 + packages/repl-sdk/.prettierignore | 1 + packages/repl-sdk/.prettierrc.cjs | 1 + packages/repl-sdk/NOTES.md | 6 + packages/repl-sdk/README.md | 15 + packages/repl-sdk/example/index.html | 147 ++ packages/repl-sdk/example/samples.js | 91 + packages/repl-sdk/example/vite.config.mts | 3 + packages/repl-sdk/package.json | 55 + packages/repl-sdk/src/compilers.js | 170 ++ packages/repl-sdk/src/compilers/cdn.js | 83 + packages/repl-sdk/src/compilers/glimmer-js.js | 232 ++ packages/repl-sdk/src/compilers/markdown.js | 385 +++ packages/repl-sdk/src/compilers/packages.js | 14 + packages/repl-sdk/src/index.d.ts | 19 + packages/repl-sdk/src/index.js | 203 ++ packages/repl-sdk/src/types.ts | 118 + packages/repl-sdk/src/utils.js | 16 + packages/repl-sdk/tests-self/.eslintrc.cjs | 20 + packages/repl-sdk/tests-self/package.json | 30 + .../repl-sdk/tests-self/tests/custom.test.ts | 27 + .../repl-sdk/tests-self/tests/ember.test.ts | 64 + .../tests-self/tests/jsx/react.test.ts | 27 + .../tests-self/tests/markdown.test.ts | 123 + .../repl-sdk/tests-self/tests/mermaid.test.ts | 26 + .../repl-sdk/tests-self/tests/svelte.test.ts | 29 + .../repl-sdk/tests-self/tests/vue.test.ts | 38 + packages/repl-sdk/tests-self/tsconfig.json | 7 + packages/repl-sdk/tests-self/vite.config.js | 11 + packages/repl-sdk/tests-self/vitest.config.ts | 11 + packages/repl-sdk/tsconfig.json | 9 + packages/repl-sdk/vite.config.mts | 52 + .../glimdown/codemirror/tests/package.json | 3 +- .../glimmer-s-expression/lezer/.eslintignore | 10 +- .../lezer/.prettierignore | 16 +- packages/syntax/glimmer/lezer/.eslintignore | 8 +- packages/syntax/glimmer/lezer/.prettierignore | 14 +- packages/syntax/glimmer/lezer/.prettierrc.cjs | 36 +- .../syntax/glimmer/lezer/tests/package.json | 3 +- pnpm-lock.yaml | 2101 ++++++++++++++++- pnpm-workspace.yaml | 1 + spikes/es-module-shim/index.html | 152 ++ spikes/es-module-shim/package.json | 18 + spikes/unified/package.json | 3 +- spikes/url-shortening/package.json | 3 +- turbo.json | 7 +- 60 files changed, 4460 insertions(+), 134 deletions(-) create mode 100644 packages/ember-repl/addon/src/compile/imports.ts create mode 120000 packages/repl-sdk/.eslintignore create mode 100644 packages/repl-sdk/.eslintrc.cjs create mode 120000 packages/repl-sdk/.prettierignore create mode 120000 packages/repl-sdk/.prettierrc.cjs create mode 100644 packages/repl-sdk/NOTES.md create mode 100644 packages/repl-sdk/README.md create mode 100644 packages/repl-sdk/example/index.html create mode 100644 packages/repl-sdk/example/samples.js create mode 100644 packages/repl-sdk/example/vite.config.mts create mode 100644 packages/repl-sdk/package.json create mode 100644 packages/repl-sdk/src/compilers.js create mode 100644 packages/repl-sdk/src/compilers/cdn.js create mode 100644 packages/repl-sdk/src/compilers/glimmer-js.js create mode 100644 packages/repl-sdk/src/compilers/markdown.js create mode 100644 packages/repl-sdk/src/compilers/packages.js create mode 100644 packages/repl-sdk/src/index.d.ts create mode 100644 packages/repl-sdk/src/index.js create mode 100644 packages/repl-sdk/src/types.ts create mode 100644 packages/repl-sdk/src/utils.js create mode 100644 packages/repl-sdk/tests-self/.eslintrc.cjs create mode 100644 packages/repl-sdk/tests-self/package.json create mode 100644 packages/repl-sdk/tests-self/tests/custom.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/ember.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/jsx/react.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/markdown.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/mermaid.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/svelte.test.ts create mode 100644 packages/repl-sdk/tests-self/tests/vue.test.ts create mode 100644 packages/repl-sdk/tests-self/tsconfig.json create mode 100644 packages/repl-sdk/tests-self/vite.config.js create mode 100644 packages/repl-sdk/tests-self/vitest.config.ts create mode 100644 packages/repl-sdk/tsconfig.json create mode 100644 packages/repl-sdk/vite.config.mts mode change 100644 => 120000 packages/syntax/glimmer-s-expression/lezer/.eslintignore mode change 100644 => 120000 packages/syntax/glimmer-s-expression/lezer/.prettierignore mode change 100644 => 120000 packages/syntax/glimmer/lezer/.eslintignore mode change 100644 => 120000 packages/syntax/glimmer/lezer/.prettierignore mode change 100644 => 120000 packages/syntax/glimmer/lezer/.prettierrc.cjs create mode 100644 spikes/es-module-shim/index.html create mode 100644 spikes/es-module-shim/package.json diff --git a/.eslintignore b/.eslintignore index b9ef98ff5..cf040d311 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,3 +6,4 @@ vendor/ public/ coverage/ *.ember-try +tests-self/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23b6e4cdb..b05102401 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: tests: - name: "Ember Tests" + name: "Browser Tests" strategy: matrix: # os: [ubuntu-latest, macOS-latest, windows-latest] @@ -109,7 +109,7 @@ jobs: echo "NPM: $( npm --version )" echo "pnpm: $( pnpm --version )" - name: Test - run: pnpm turbo test:ember + run: pnpm turbo test:chrome test:firefox env: CI_BROWSER: ${{ matrix.ci_browser }} diff --git a/.gitignore b/.gitignore index 17b9a529d..4989d8ffb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # compiled output dist/ declarations/ +__screenshots__/ /tmp/ /out/ diff --git a/apps/repl/package.json b/apps/repl/package.json index a5c97976e..2ce9a1a4b 100644 --- a/apps/repl/package.json +++ b/apps/repl/package.json @@ -24,7 +24,8 @@ "start": "ember serve -p 4201", "start:iframe": "pnpx http-server ./public -i -p 4204", "test:browserstack": "./scripts/browserstack.sh", - "test:ember": "ember test --test-port 0", + "test:chrome": "CI_BROWSER=Chrome ember test --test-port 0", + "test:firefox": "CI_BROWSER=Firefox ember test --test-port 0", "lint": "pnpm -w exec lint", "lint:js": "pnpm -w exec lint js", "lint:js:fix": "pnpm -w exec lint js:fix", diff --git a/apps/tutorial/package.json b/apps/tutorial/package.json index bc2fe4ff2..c0f0ed834 100644 --- a/apps/tutorial/package.json +++ b/apps/tutorial/package.json @@ -17,7 +17,8 @@ "lint:fix": "pnpm -w exec lint fix", "cf": "cd dist && npx wrangler pages dev --port 42000 ./", "start": "ember serve", - "test:ember": "ember test --test-port 0", + "test:chrome": "CI_BROWSER=Chrome ember test --test-port 0", + "test:firefox": "CI_BROWSER=Firefox ember test --test-port 0", "lint:js": "pnpm -w exec lint js", "lint:js:fix": "pnpm -w exec lint js:fix", "lint:hbs": "pnpm -w exec lint hbs", diff --git a/dev/package.json b/dev/package.json index d80c7b572..50b71cb22 100644 --- a/dev/package.json +++ b/dev/package.json @@ -46,5 +46,6 @@ "directory": "dev" }, "license": "MIT", - "author": "NullVoxPopuli" + "author": "NullVoxPopuli", + "version": "0.0.0" } diff --git a/packages/app-support/limber-ui/test-app/package.json b/packages/app-support/limber-ui/test-app/package.json index e631c6695..d30a0b793 100644 --- a/packages/app-support/limber-ui/test-app/package.json +++ b/packages/app-support/limber-ui/test-app/package.json @@ -12,7 +12,8 @@ "scripts": { "lint:fix": "pnpm -w exec lint fix", "start": "ember serve", - "test:ember": "ember test --test-port 0", + "test:chrome": "CI_BROWSER=Chrome ember test --test-port 0", + "test:firefox": "CI_BROWSER=Firefox ember test --test-port 0", "lint": "pnpm -w exec lint", "lint:js": "pnpm -w exec lint js", "lint:js:fix": "pnpm -w exec lint js:fix", diff --git a/packages/ember-repl/addon/package.json b/packages/ember-repl/addon/package.json index 94d0c6a23..ab23d1ab7 100644 --- a/packages/ember-repl/addon/package.json +++ b/packages/ember-repl/addon/package.json @@ -76,6 +76,7 @@ "dependencies": { "@babel/helper-plugin-utils": "^7.25.7", "@babel/standalone": "^7.25.7", + "@ember/test-waiters": "^3.1.0", "@embroider/addon-shim": "1.8.9", "@embroider/macros": "1.16.9", "babel-import-util": "^3.0.0", diff --git a/packages/ember-repl/addon/src/compile/formats.ts b/packages/ember-repl/addon/src/compile/formats.ts index e148335a8..8e072753a 100644 --- a/packages/ember-repl/addon/src/compile/formats.ts +++ b/packages/ember-repl/addon/src/compile/formats.ts @@ -1,3 +1,4 @@ +// import { resolveImportMap } from './imports.ts'; import { invocationName } from './utils.ts'; import type { ExtractedCode } from './formats/markdown.ts'; @@ -21,6 +22,10 @@ export async function compileGJS( try { let { compileJS } = await import('./formats/gjs/index.ts'); + // let importMap2 = await resolveImportMap(gjsInput, importMap); + // + // console.log(importMap2); + return await compileJS(gjsInput, importMap); } catch (error) { return { error: error as Error, name: 'unknown' }; diff --git a/packages/ember-repl/addon/src/compile/imports.ts b/packages/ember-repl/addon/src/compile/imports.ts new file mode 100644 index 000000000..2b7196c18 --- /dev/null +++ b/packages/ember-repl/addon/src/compile/imports.ts @@ -0,0 +1,36 @@ +/** + * We can't use es-module-lexer because it wants syntatically valid + * JavaScript. + * + * import { parse } from 'es-module-lexer'; + * + * We may not have syntactically valid javascript, + * but it's still useful to pull the imported modules into the + * browser's module cache. + */ +// + +import type { EvalImportMap } from './types.ts'; + +export async function resolveImportMap(doc: string, importMap?: EvalImportMap) { + if (!importMap) { + return {}; + } + + return importMap; + + // const [imports] = await parse(doc); + // + // + // console.log(imports); + + // let result = {}; + + // for (let [key, maybeFn] of Object.entries(importMap)) { + // if (typeof maybeFn === 'function') { + // + // } + // } + + // return result; +} diff --git a/packages/ember-repl/addon/src/compile/index.ts b/packages/ember-repl/addon/src/compile/index.ts index 5f146fea5..3c8f8e9cb 100644 --- a/packages/ember-repl/addon/src/compile/index.ts +++ b/packages/ember-repl/addon/src/compile/index.ts @@ -1,3 +1,5 @@ +import { buildWaiter } from '@ember/test-waiters'; + import { cell, resource, resourceFactory } from 'ember-resources'; import { @@ -14,6 +16,8 @@ type Format = 'glimdown' | 'gjs' | 'hbs'; export const CACHE = new Map(); +const compileWaiter = buildWaiter('ember-repl::compile'); + interface Events { onSuccess: (component: ComponentLike) => Promise | unknown; onError: (error: string) => Promise | unknown; @@ -189,6 +193,8 @@ export function Compiled( let error = cell(); let result = cell(); + let token = compileWaiter.beginAsync(); + if (input) { compile(input, { // narrowing is hard here, but this is an implementation detail @@ -197,9 +203,11 @@ export function Compiled( result.current = component; ready.set(true); error.set(null); + compileWaiter.endAsync(token); }, onError: async (e) => { error.set(e); + compileWaiter.endAsync(token); }, onCompileStart: async () => { ready.set(false); diff --git a/packages/ember-repl/addon/src/compile/types.ts b/packages/ember-repl/addon/src/compile/types.ts index afbccc790..a1d5e5815 100644 --- a/packages/ember-repl/addon/src/compile/types.ts +++ b/packages/ember-repl/addon/src/compile/types.ts @@ -2,10 +2,29 @@ import type { ComponentLike } from '@glint/template'; import type { Pluggable } from 'unified'; export interface EvalImportMap { - [moduleName: string]: ScopeMap; + /** + * The name of the module to import and the value that will be imported. + * For example: + * ```js + * { + * 'my-library': () => import('my-library'), + * } + * ``` + * + * or, if you want to make a fake module, you may specify its exports + * ```js + * { + * 'my-library': { Foo, Bar } + * } + * ``` + */ + [moduleName: string]: ScopeMap | (() => Promise); } export interface ScopeMap { + /** + * Key-value pairs of values and their export names + */ [localName: string]: unknown; } diff --git a/packages/ember-repl/test-app/tests/rendering/compiled-test.gts b/packages/ember-repl/test-app/tests/rendering/compiled-test.gts index 33f452f5a..92ce0b288 100644 --- a/packages/ember-repl/test-app/tests/rendering/compiled-test.gts +++ b/packages/ember-repl/test-app/tests/rendering/compiled-test.gts @@ -1,25 +1,24 @@ import { renderSettled } from '@ember/renderer'; import { render, settled } from '@ember/test-helpers'; -import { module, test } from 'qunit'; +import QUnit, { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { stripIndent } from 'common-tags'; import { Compiled } from 'ember-repl'; +const { assert } = QUnit; +const { Boolean } = globalThis; + module('Rendering | Compiled()', function (hooks) { setupRenderingTest(hooks); - test('it works', async function (assert) { - let doc = stripIndent` - hello there - `; - + async function renderTest(doc, options = {}) { render(