diff --git a/.env b/.env
new file mode 100644
index 0000000000..5f4193d478
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+NODE_OPTIONS="--no-warnings"
diff --git a/.env.testing b/.env.testing
new file mode 100644
index 0000000000..c0d6652113
--- /dev/null
+++ b/.env.testing
@@ -0,0 +1 @@
+NODE_ENV=development
diff --git a/.eslintignore b/.eslintignore
index b6326c2727..1e98e7c352 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,10 +1,13 @@
# compiled output
/dist/
+**/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
+**/node_modules/
+**/.yalc/
# misc
/coverage/
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000000..d581099185
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,82 @@
+// @ts-check
+
+const { resolve } = require('path');
+
+const cjsTsconfig = resolve(__dirname, 'tsconfig.cjs.json');
+
+/** @type {import("eslint").Linter.Config} */
+module.exports = {
+ root: true,
+ reportUnusedDisableDirectives: true,
+ extends: [],
+ ignorePatterns: [
+ 'dist',
+ 'ts-dist',
+ 'node_modules',
+ 'tmp',
+ '**/node_modules',
+ '**/dist',
+ '**/fixtures',
+ '!**/.eslintrc.cjs',
+ ],
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ ecmaVersion: 'latest',
+ project: [],
+ },
+ settings: {
+ 'import/parsers': {
+ '@typescript-eslint/parser': ['.js', '.cjs', '.mjs', '.mts', '.ts', '.d.ts'],
+ },
+ 'import/resolver': {
+ typescript: {},
+ },
+ node: {
+ allowModules: ['@glimmer/debug', '@glimmer/local-debug-flags'],
+ tryExtensions: ['.js', '.ts', '.d.ts', '.json'],
+ },
+ },
+ plugins: [
+ '@typescript-eslint',
+ 'prettier',
+ 'qunit',
+ 'simple-import-sort',
+ 'unused-imports',
+ 'prettier',
+ 'n',
+ ],
+
+ rules: {},
+ overrides: [
+ {
+ files: ['.eslintrc.cjs', '**/.eslintrc.cjs'],
+ parserOptions: {
+ project: [cjsTsconfig],
+ },
+ extends: [
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:import/errors',
+ 'plugin:import/typescript',
+ 'plugin:qunit/recommended',
+ 'prettier',
+ ],
+ rules: {
+ '@typescript-eslint/no-var-requires': 'off',
+ },
+ },
+
+ {
+ // these packages need to be fixed to avoid these warnings, but in the
+ // meantime we should not regress the other packages
+ files: [
+ // this specific test imports from @glimmer/runtime (causing a cyclic
+ // dependency), it should either be refactored to use the interfaces
+ // directly (instead of the impls) or moved into @glimmer/runtime
+ 'packages/@glimmer/reference/test/template-test.ts',
+ ],
+ rules: {
+ 'n/no-extraneous-import': 'warn',
+ },
+ },
+ ],
+};
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 47fbd0e54f..0000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,316 +0,0 @@
-{
- "root": true,
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:qunit/recommended",
- "plugin:n/recommended",
- "plugin:import/errors",
- "prettier"
- ],
- "ignorePatterns": ["dist", "ts-dist", "node_modules", "tmp", "**/node_modules", "**/dist"],
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "ecmaVersion": "latest"
- },
- "settings": {
- "import/parsers": {
- "@typescript-eslint/parser": [".js", ".ts", ".d.ts"]
- },
- "import/resolver": {
- "typescript": {}
- },
- "node": {
- "allowModules": ["@glimmer/debug", "@glimmer/local-debug-flags"],
- "tryExtensions": [".js", ".ts", ".d.ts", ".json"]
- }
- },
- "plugins": ["@typescript-eslint", "prettier", "qunit", "simple-import-sort", "unused-imports"],
- "rules": {
- "@typescript-eslint/no-array-constructor": "error",
- "@typescript-eslint/no-empty-function": "error",
- "@typescript-eslint/no-unused-vars": "error",
- "accessor-pairs": "error",
- "array-callback-return": "error",
- "block-scoped-var": "error",
- // replace ESLint rules with TypeScript-compatible rules
- "camelcase": "off",
- "capitalized-comments": "off",
- "class-methods-use-this": "off",
- "complexity": "off",
- "consistent-return": "error",
- "consistent-this": "error",
- "default-case": "error",
- "dot-notation": [
- "error",
- {
- "allowKeywords": true
- }
- ],
- "eqeqeq": "error",
- "func-name-matching": "error",
- "func-names": "off",
- "func-style": ["error", "declaration"],
- "guard-for-in": "error",
- "id-denylist": "error",
- "id-length": "off",
- "id-match": "error",
- "import/default": "off",
- "import/export": "off",
- "import/first": ["error"],
- "import/newline-after-import": ["error"],
- "import/no-duplicates": ["error"],
- "import/no-extraneous-dependencies": ["error"],
- "import/order": "off",
- "init-declarations": "off",
- "max-depth": "off",
- "max-lines": "off",
- "max-nested-callbacks": "error",
- "max-params": "off",
- "n/callback-return": "error",
- "n/global-require": "off",
- "n/handle-callback-err": "error",
- // this is handled by import/no-extraneous-dependencies
- "n/no-extraneous-import": "off",
- "n/no-missing-import": "off",
- "n/no-mixed-requires": "error",
- "n/no-new-require": "error",
- "n/no-path-concat": "off",
- "n/no-process-env": "off",
- "n/no-process-exit": "off",
- "n/no-restricted-import": "error",
- "n/no-sync": "off",
- "n/no-unsupported-features/es-builtins": [
- "error",
- {
- "version": "16.0.0"
- }
- ],
- "new-cap": "error",
- "no-alert": "error",
- "no-array-constructor": "off",
- "no-await-in-loop": "off",
- "no-bitwise": "error",
- "no-caller": "error",
- "no-console": "error",
- "no-continue": "error",
- "no-div-regex": "error",
- "no-duplicate-imports": "error",
- "no-else-return": "error",
- "no-empty-function": "off",
- "no-eq-null": "error",
- "no-eval": "error",
- "no-extend-native": "error",
- "no-extra-bind": "error",
- "no-extra-label": "error",
- "no-global-assign": "error",
- "no-implicit-globals": "off",
- "no-implied-eval": "error",
- "no-inline-comments": "error",
- "no-invalid-this": "error",
- "no-iterator": "error",
- "no-label-var": "error",
- "no-labels": "error",
- "no-lone-blocks": "error",
- "no-lonely-if": "error",
- "no-loop-func": "error",
- "no-magic-numbers": "off",
- "no-multi-assign": "error",
- "no-multi-spaces": "error",
- "no-multi-str": "error",
- "no-negated-condition": "error",
- "no-nested-ternary": "error",
- "no-new": "error",
- "no-new-func": "error",
- "no-new-object": "error",
- "no-new-wrappers": "error",
- "no-octal-escape": "error",
- "no-param-reassign": "off",
- "no-plusplus": "off",
- "no-proto": "error",
- "no-restricted-globals": "error",
- "no-restricted-imports": "error",
- "no-restricted-properties": "error",
- "no-restricted-syntax": "error",
- "no-return-assign": "error",
- "no-return-await": "error",
- "no-script-url": "error",
- "no-self-compare": "error",
- "no-sequences": "error",
- "no-shadow": "error",
- "no-template-curly-in-string": "error",
- "no-ternary": "off",
- "no-throw-literal": "error",
- "no-undef-init": "error",
- "no-undefined": "off",
- "no-unmodified-loop-condition": "error",
- "no-unneeded-ternary": "error",
- "no-unsafe-negation": "error",
- "no-unused-expressions": "error",
- "no-unused-labels": "error",
- "no-unused-vars": "off",
- "no-use-before-define": "off",
- "no-useless-call": "error",
- "no-useless-computed-key": "error",
- "no-useless-concat": "error",
- "no-useless-constructor": "error",
- "no-useless-rename": "error",
- "no-useless-return": "error",
- "no-var": "error",
- "no-void": "error",
- "no-warning-comments": "error",
- "object-shorthand": "error",
- "one-var": "off",
- "operator-assignment": "error",
- "prefer-const": "off",
- "prefer-destructuring": [
- "error",
- {
- "array": false,
- "object": false
- }
- ],
- "prefer-numeric-literals": "error",
- "prefer-promise-reject-errors": "error",
- "prefer-rest-params": "error",
- "prefer-spread": "error",
- "prefer-template": "off",
- "prettier/prettier": "error",
- // disabled because we still have a few commented tests
- "qunit/no-commented-tests": "off",
- // disabled due to false positives
- "qunit/no-global-expect": "off",
- // disabled because we still use this pattern everywhere
- "qunit/no-global-module-test": "off",
- // disabled due to false positives
- "qunit/no-global-stop-start": "off",
- "radix": "error",
- "require-await": "error",
- "require-jsdoc": "off",
- "simple-import-sort/exports": ["error"],
- "simple-import-sort/imports": ["error"],
- "sort-imports": "off",
- "sort-keys": "off",
- "sort-vars": "off",
- "spaced-comment": ["error", "always"],
- "strict": "off",
- "symbol-description": "error",
- "unused-imports/no-unused-imports": "error",
- "unused-imports/no-unused-vars": [
- "warn",
- {
- "args": "after-used",
- "argsIgnorePattern": "^_",
- "vars": "all",
- "varsIgnorePattern": "^_"
- }
- ],
- "valid-jsdoc": "off",
- "vars-on-top": "error",
- "yoda": ["error", "never"]
- },
- "overrides": [
- {
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/recommended",
- "plugin:import/errors",
- "plugin:import/typescript",
- "plugin:qunit/recommended",
- "prettier"
- ],
- "files": [
- "packages/@glimmer/compiler/**/*.ts",
- "packages/@glimmer/syntax/lib/**/*.ts",
- "packages/@glimmer/syntax/index.ts"
- ],
- "rules": {
- "@typescript-eslint/ban-types": [
- "error",
- {
- "extendDefaults": true,
- "types": {
- "object": false
- }
- }
- ],
- "@typescript-eslint/no-explicit-any": [
- "error",
- {
- "ignoreRestArgs": true
- }
- ],
- "@typescript-eslint/unbound-method": [
- "error",
- {
- "ignoreStatic": true
- }
- ],
- // this is handled by import/errors
- "n/no-extraneous-import": "off",
- "prefer-const": ["off"],
- "qunit/no-global-expect": ["off"]
- }
- },
- {
- "files": ["**/*.d.ts"],
- "parserOptions": {
- "sourceType": "module"
- },
- "rules": {
- "n/no-missing-import": "off",
- "no-useless-constructor": "off"
- }
- },
-
- {
- "env": {
- "browser": true,
- "es6": true
- },
- "extends": ["plugin:import/errors"],
- "files": ["benchmark/**/*.js", "benchmark/**/*.d.ts"],
- "parserOptions": {
- "sourceType": "module"
- },
- "rules": {
- "n/no-unsupported-features/es-syntax": "off",
- "no-console": "off"
- }
- },
- {
- "env": {
- "es6": true,
- "mocha": true,
- "node": true
- },
- "files": ["packages/build-utils/@glimmer/*/test/**/*.js"],
- "rules": {
- "n/no-unpublished-import": "off",
- "n/no-unsupported-features/es-syntax": "off",
- "no-console": "off"
- }
- },
- // source packages
- {
- "files": ["packages/**/*.js"],
- "parserOptions": {
- "sourceType": "module"
- }
- },
-
- {
- // these packages need to be fixed to avoid these warnings, but in the
- // meantime we should not regress the other packages
- "files": [
- // this specific test imports from @glimmer/runtime (causing a cyclic
- // dependency), it should either be refactored to use the interfaces
- // directly (instead of the impls) or moved into @glimmer/runtime
- "packages/@glimmer/reference/test/template-test.ts"
- ],
- "rules": {
- "n/no-extraneous-import": "warn"
- }
- }
- ]
-}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5e025ba72d..3048ffe754 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- - uses: NullVoxPopuli/action-setup-pnpm@v2
+ - uses: NullVoxPopuli/action-setup-pnpm@NullVoxPopuli-patch-1
lint:
name: Linting
diff --git a/.gitignore b/.gitignore
index ada2025bb1..63554302cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
/control-dist/
node_modules/
**/node_modules/
+**/.turbo
tmp/
/ts-dist/
**/ts-dist
@@ -12,3 +13,4 @@ tmp/
*.pdf
instrumentation.*.json
.cache
+**/.yalc
diff --git a/.npmcheckrc b/.npmcheckrc
new file mode 100644
index 0000000000..4d07f2dba8
--- /dev/null
+++ b/.npmcheckrc
@@ -0,0 +1,7 @@
+{
+ "depcheck": {
+ "ignoreMatches": [
+ "@handlebars/parser"
+ ]
+ }
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0f6bce1902..fc8e324a56 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -14,27 +14,29 @@
"editor.formatOnSave": true,
"eslint.enable": true,
"eslint.packageManager": "npm",
+ "eslint.codeAction.showDocumentation": {
+ "enable": true
+ },
+ "eslint.codeActionsOnSave.mode": "all",
+ "eslint.lintTask.enable": true,
+ "eslint.onIgnoredFiles": "warn",
"eslint.workingDirectories": [
{
- "mode": "location"
+ "mode": "auto"
}
],
- "explorer.excludeGitIgnore": true,
+ "explorer.excludeGitIgnore": false,
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true,
- "**/dist/**": true,
"**/node_modules/**": true,
- "dist/**": true,
"node_modules/**": true
},
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"files.watcherExclude": {
"**/.git/objects/**": true,
- "**/.git/subtree-cache/**": true,
- "**/dist/**": true,
- "dist": true
+ "**/.git/subtree-cache/**": true
},
"javascript.updateImportsOnFileMove.enabled": "always",
"typescript.updateImportsOnFileMove.enabled": "always",
@@ -48,5 +50,6 @@
"typescript.tsc.autoDetect": "on",
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.tsserver.experimental.enableProjectDiagnostics": false,
- "typescript.workspaceSymbols.scope": "currentProject"
+ "typescript.workspaceSymbols.scope": "currentProject",
+ "eslint.problems.shortenToSingleLine": true
}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000000..c91b044925
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,22 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "shell",
+ "command": "pnpm",
+ "args": ["dotenv", "--", "turbo", "lint"],
+ // "script": "lint:files",
+ "problemMatcher": ["$eslint-stylish"],
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": false,
+ "panel": "shared",
+ "showReuseMessage": true,
+ "clear": false
+ },
+ "label": "turbo: lint",
+ "detail": "dotenv -- turbo lint"
+ }
+ ]
+}
diff --git a/packages/build-utils/.eslintrc.cjs b/benchmark/.eslintrc.cjs
similarity index 91%
rename from packages/build-utils/.eslintrc.cjs
rename to benchmark/.eslintrc.cjs
index 8209270007..0ce1239d85 100644
--- a/packages/build-utils/.eslintrc.cjs
+++ b/benchmark/.eslintrc.cjs
@@ -1,21 +1,26 @@
+const { resolve } = require('node:path');
+
+const tsconfig = resolve(__dirname, 'tsconfig.json');
+
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: false,
overrides: [
{
- files: ['*.d.ts', '*.js'],
- excludedFiles: ['*/node_modules'],
+ files: ['*.{js,ts,d.ts,mts'],
parserOptions: {
ecmaVersion: 'latest',
- project: ['packages/build-utils/tsconfig.json'],
+ project: [tsconfig],
},
extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
rules: {
+ '@typescript-eslint/restrict-plus-operands': 'off',
'@typescript-eslint/no-require-imports': 'off',
+ '@typescript-eslint/no-import-type-side-effects': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{
- fixStyle: 'inline-type-imports',
+ disallowTypeAnnotations: false,
},
],
'@typescript-eslint/consistent-type-exports': [
diff --git a/benchmark/benchmarks/krausest/index.html b/benchmark/benchmarks/krausest/index.html
new file mode 100644
index 0000000000..8c330daa39
--- /dev/null
+++ b/benchmark/benchmarks/krausest/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ krausest benchmark
+
+
+
+
diff --git a/benchmark/benchmarks/krausest/lib/components/Application.hbs.d.ts b/benchmark/benchmarks/krausest/lib/components/Application.hbs.d.ts
index 39c5906cec..b6a3edc840 100644
--- a/benchmark/benchmarks/krausest/lib/components/Application.hbs.d.ts
+++ b/benchmark/benchmarks/krausest/lib/components/Application.hbs.d.ts
@@ -1,2 +1,2 @@
-declare const template: import('@glimmer/interfaces').SerializedTemplateWithLazyBlock;
+declare const template: import('../../../../../packages/@glimmer/interfaces').SerializedTemplateWithLazyBlock;
export default template;
diff --git a/benchmark/benchmarks/krausest/lib/components/Row.hbs.d.ts b/benchmark/benchmarks/krausest/lib/components/Row.hbs.d.ts
index 39c5906cec..b6a3edc840 100644
--- a/benchmark/benchmarks/krausest/lib/components/Row.hbs.d.ts
+++ b/benchmark/benchmarks/krausest/lib/components/Row.hbs.d.ts
@@ -1,2 +1,2 @@
-declare const template: import('@glimmer/interfaces').SerializedTemplateWithLazyBlock;
+declare const template: import('../../../../../packages/@glimmer/interfaces').SerializedTemplateWithLazyBlock;
export default template;
diff --git a/benchmark/benchmarks/krausest/lib/index.js b/benchmark/benchmarks/krausest/lib/index.js
index ff342d56a4..5fba1ffdb8 100644
--- a/benchmark/benchmarks/krausest/lib/index.js
+++ b/benchmark/benchmarks/krausest/lib/index.js
@@ -1,4 +1,4 @@
-import { createBenchmark } from '@glimmer/benchmark-env';
+import { createBenchmark } from '@glimmer-workspace/benchmark-env';
import Application from './components/Application';
import ApplicationTemplate from './components/Application.hbs';
@@ -7,7 +7,7 @@ import RowTemplate from './components/Row.hbs';
import buildData from './utils/data';
/**
- * @param {HTMLElement | import('@simple-dom/interface').SimpleElement} element
+ * @param {HTMLElement | import('../../../../packages/@glimmer/interfaces').SimpleElement} element
* @param {boolean} isInteractive
*/
export default async function render(element, isInteractive) {
diff --git a/benchmark/benchmarks/krausest/lib/utils/data.js b/benchmark/benchmarks/krausest/lib/utils/data.js
index 385f5b71eb..1bc633c868 100644
--- a/benchmark/benchmarks/krausest/lib/utils/data.js
+++ b/benchmark/benchmarks/krausest/lib/utils/data.js
@@ -1,4 +1,4 @@
-import { createCell } from '@glimmer/benchmark-env';
+import { createCell } from '@glimmer-workspace/benchmark-env';
export class Item {
/** @type {number} */
@@ -7,7 +7,6 @@ export class Item {
/** @type {string} */
label;
- // eslint-disable-next-line no-invalid-this
_selected = createCell(this, 'selected', false);
/**
@@ -32,7 +31,6 @@ export class Item {
* @param {number} max
*/
function _random(max) {
- // eslint-disable-next-line no-bitwise
return (Math.random() * max) | 0;
}
diff --git a/benchmark/benchmarks/krausest/package.json b/benchmark/benchmarks/krausest/package.json
new file mode 100644
index 0000000000..b34108a115
--- /dev/null
+++ b/benchmark/benchmarks/krausest/package.json
@@ -0,0 +1,26 @@
+{
+ "private": true,
+ "name": "@glimmer-workspace/krausest",
+ "dependencies": {
+ "@glimmer-workspace/benchmark-env": "workspace:^",
+ "@glimmer/interfaces": "workspace:^",
+ "@simple-dom/document": "^1.4.0",
+ "@simple-dom/serializer": "^1.4.0",
+ "@simple-dom/void-map": "^1.4.0",
+ "@glimmer/compiler": "workspace:^"
+ },
+ "devDependencies": {
+ "vite": "^4.3.5",
+ "@types/node": "^18.16.7"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "config": {
+ "tsconfig": "../../tsconfig.json"
+ },
+ "scripts": {
+ "test:lint": "eslint .",
+ "test:types": "tsc --noEmit -p ../../tsconfig.json"
+ }
+}
\ No newline at end of file
diff --git a/benchmark/benchmarks/krausest/vite.config.mts b/benchmark/benchmarks/krausest/vite.config.mts
new file mode 100644
index 0000000000..3c4e573d03
--- /dev/null
+++ b/benchmark/benchmarks/krausest/vite.config.mts
@@ -0,0 +1,24 @@
+import fs from 'node:fs';
+
+import { precompile } from '@glimmer/compiler';
+import { defineConfig, type Plugin } from 'vite';
+
+export default defineConfig({
+ plugins: [benchmark()],
+});
+
+function benchmark(): Plugin {
+ return {
+ name: '@glimmer/benchmark',
+ load(id) {
+ /** @type {string | undefined} */
+ let result: string | undefined;
+ if (id.endsWith('.hbs')) {
+ const source = fs.readFileSync(id, 'utf8');
+ const compiled = precompile(source);
+ result = `export default ${compiled};`;
+ }
+ return result;
+ },
+ };
+}
diff --git a/benchmark/benchmarks/krausest/yalc.lock b/benchmark/benchmarks/krausest/yalc.lock
new file mode 100644
index 0000000000..18c9d06057
--- /dev/null
+++ b/benchmark/benchmarks/krausest/yalc.lock
@@ -0,0 +1,10 @@
+{
+ "version": "v1",
+ "packages": {
+ "@glimmer/compiler": {
+ "signature": "46d50e94d7d37d54f6d9ba4314abf1be",
+ "file": true,
+ "replaced": "workspace:^"
+ }
+ }
+}
\ No newline at end of file
diff --git a/benchmark/bin/control.js b/benchmark/bin/control.js
index 5f8ee55ca0..c476f26c0a 100644
--- a/benchmark/bin/control.js
+++ b/benchmark/bin/control.js
@@ -1,4 +1,4 @@
-// eslint-disable-next-line n/no-unpublished-require
+
const express = require('express');
const app = express();
diff --git a/benchmark/bin/experiment.js b/benchmark/bin/experiment.js
index bcb574e2fd..11bbb5ca0b 100644
--- a/benchmark/bin/experiment.js
+++ b/benchmark/bin/experiment.js
@@ -1,4 +1,4 @@
-// eslint-disable-next-line n/no-unpublished-require
+
const express = require('express');
const app = express();
diff --git a/benchmark/lib/build.js b/benchmark/lib/build.js
index 14a924871e..03a806f23f 100644
--- a/benchmark/lib/build.js
+++ b/benchmark/lib/build.js
@@ -1,6 +1,11 @@
-/* eslint-disable no-inline-comments */
+// @ts-check
+
+
const path = require('path');
-const rollup = require('rollup');
+const rollup = /** @type {{rollup: import("rollup").rollup}} */ (
+ /** @type {unknown} */
+ (require('rollup'))
+);
const sourcemap = /** @type {import("@rollup/plugin-terser").default} */ (
/** @type {unknown} */
(require('rollup-plugin-sourcemaps'))
@@ -37,7 +42,7 @@ async function build(dist, out) {
}),
terser({
compress: {
- // eslint-disable-next-line @typescript-eslint/naming-convention
+
negate_iife: false,
sequences: 0,
},
diff --git a/benchmark/package.json b/benchmark/package.json
index 8054c40f58..18853414d7 100644
--- a/benchmark/package.json
+++ b/benchmark/package.json
@@ -3,7 +3,7 @@
"version": "0.84.3",
"private": true,
"dependencies": {
- "@glimmer/benchmark-env": "workspace:^",
+ "@glimmer-workspace/benchmark-env": "workspace:^",
"@simple-dom/document": "^1.4.0",
"@simple-dom/serializer": "^1.4.0",
"@simple-dom/void-map": "^1.4.0"
@@ -17,7 +17,7 @@
"@types/symlink-or-copy": "^1.2.0",
"express": "^4.18.2",
"fs-extra": "^11.1.1",
- "rollup": "^3.21.3",
+ "rollup": "^3.21.6",
"rollup-plugin-sourcemaps": "^0.6.3",
"symlink-or-copy": "^1.3.1"
}
diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json
index 1a50ab8914..bb93e8772f 100644
--- a/benchmark/tsconfig.json
+++ b/benchmark/tsconfig.json
@@ -3,10 +3,12 @@
"composite": true,
"strict": true,
"baseUrl": ".",
+ "allowJs": true,
+ "checkJs": true,
"target": "es2020",
- "module": "NodeNext",
- "moduleResolution": "nodenext",
+ "module": "esnext",
+ "moduleResolution": "bundler",
"verbatimModuleSyntax": true,
"suppressImplicitAnyIndexErrors": false,
@@ -19,10 +21,21 @@
"outDir": "../ts-dist/bench"
},
- "include": ["./index.js", "./lib/**/*.js", "./bin/**/*.js"],
+ "include": [
+ "./index.js",
+ "./lib/**/*.js",
+ "./bin/**/*.js",
+ "./benchmarks/krausest/*.js",
+ "./benchmarks/krausest/lib/**/*.js",
+ "./benchmarks/krausest/vite.config.mts"
+ ],
+ "exclude": ["**/.yalc"],
"references": [
{
"path": "../packages/@glimmer/tsconfig.json"
+ },
+ {
+ "path": "../packages/@glimmer-workspace/tsconfig.json"
}
]
}
diff --git a/bin/.eslintrc.cjs b/bin/.eslintrc.cjs
new file mode 100644
index 0000000000..ff785c7aa5
--- /dev/null
+++ b/bin/.eslintrc.cjs
@@ -0,0 +1,36 @@
+const { resolve } = require('path');
+
+const tsconfig = resolve(__dirname, 'tsconfig.json');
+
+// node files
+module.exports = {
+ root: false,
+ env: {
+ es6: true,
+ node: true,
+ },
+ overrides: [
+ {
+ files: ['*.{ts,js,d.ts}'],
+ parserOptions: {
+ ecmaVersion: 'latest',
+ project: [tsconfig],
+ },
+ extends: ['plugin:@typescript-eslint/recommended'],
+
+ rules: {
+ 'dot-notation': 'off',
+ 'no-console': 'off',
+ 'no-continue': 'off',
+ 'n/no-unsupported-features/es-syntax': [
+ 'error',
+ {
+ ignores: [],
+ version: '>=16.0.0',
+ },
+ ],
+ 'n/shebang': 'off',
+ },
+ },
+ ],
+};
diff --git a/bin/.eslintrc.json b/bin/.eslintrc.json
deleted file mode 100644
index db02bfda69..0000000000
--- a/bin/.eslintrc.json
+++ /dev/null
@@ -1,26 +0,0 @@
-// node files
-{
- "root": false,
- "env": {
- "es6": true,
- "node": true
- },
- "parserOptions": {
- "ecmaVersion": "latest",
- "project": ["bin/tsconfig.json"]
- },
- "extends": ["plugin:@typescript-eslint/recommended"],
-
- "rules": {
- "dot-notation": "off",
- "no-console": "off",
- "n/no-unsupported-features/es-syntax": [
- "error",
- {
- "ignores": [],
- "version": ">=16.0.0"
- }
- ],
- "n/shebang": "off"
- }
-}
diff --git a/bin/package.json b/bin/package.json
index 1cb23732e7..7b52d9822e 100644
--- a/bin/package.json
+++ b/bin/package.json
@@ -1,17 +1,28 @@
{
+ "name": "@glimmer-workspace/bin",
"private": true,
"dependencies": {
"puppeteer-chromium-resolver": "^20.0.0",
"chalk": "^5.2.0",
"execa": "^7.1.1",
"js-yaml": "^4.1.0",
- "glob": "^10.2.2",
+ "glob": "^10.2.3",
"@types/glob": "^8.1.0",
"@types/js-yaml": "^4.0.5",
- "@types/node": "^20.1.1",
+ "@types/node": "^18.16.7",
"@types/puppeteer-chromium-resolver": "workspace:^"
},
+ "devDependencies": {
+ "esno": "^0.16.3"
+ },
"engines": {
- "node": ">=16.0.0"
+ "node": ">=18.0.0"
+ },
+ "config": {
+ "tsconfig": "./tsconfig.json"
+ },
+ "scripts": {
+ "test:lint": "eslint .",
+ "test:types": "tsc --noEmit -p ./tsconfig.json"
}
-}
+}
\ No newline at end of file
diff --git a/bin/packages.mts b/bin/packages.mts
new file mode 100644
index 0000000000..0a49eca317
--- /dev/null
+++ b/bin/packages.mts
@@ -0,0 +1,16 @@
+import { execSync } from 'node:child_process';
+
+export interface Package {
+ readonly name: string;
+ readonly version: string;
+ readonly path: string;
+ readonly private: boolean;
+}
+
+export function packages(namespace: string): Package[] {
+ return JSON.parse(
+ execSync(`pnpm ls -r --depth -1 --filter "${namespace}/*" --json`, {
+ encoding: 'utf-8',
+ })
+ ) as Package[];
+}
diff --git a/bin/run-types-tests.mjs b/bin/run-types-tests.mjs
index dd2907247b..a96b64607a 100755
--- a/bin/run-types-tests.mjs
+++ b/bin/run-types-tests.mjs
@@ -23,24 +23,10 @@ async function main() {
for (const pkg of packages) {
try {
console.log(`# Smoke testing ${pkg.name}`);
- await execa(
- 'tsc',
- [
- '--noEmit',
- '--target',
- 'ES2015',
- '--module',
- 'esnext',
- '--moduleResolution',
- 'nodenext',
- '-p',
- resolve(root, 'tsconfig.dist.json'),
- ],
- {
- cwd: resolve(pkg.path, 'dist'),
- preferLocal: true,
- }
- );
+ await execa('tsc', ['-p', resolve(root, 'tsconfig.dist.json')], {
+ cwd: resolve(pkg.path, 'dist'),
+ preferLocal: true,
+ });
console.log(`ok ${testNo++} - ${pkg.name} types passed`);
} catch (err) {
let message = getMessage(err);
diff --git a/bin/tsconfig.json b/bin/tsconfig.json
index b069d6c72d..cba49b2922 100644
--- a/bin/tsconfig.json
+++ b/bin/tsconfig.json
@@ -22,5 +22,5 @@
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true
},
- "include": ["*.mjs"]
+ "include": ["*.mjs", "*.mts", "*.ts"]
}
diff --git a/bin/update-package-json.mts b/bin/update-package-json.mts
new file mode 100644
index 0000000000..a5196ad04f
--- /dev/null
+++ b/bin/update-package-json.mts
@@ -0,0 +1,177 @@
+import { existsSync, readFileSync, writeFileSync } from 'node:fs';
+import { resolve } from 'node:path';
+
+import chalk from 'chalk';
+
+import { type Package, packages } from './packages.mjs';
+
+const ROLLUP_CONFIG = [
+ `import { Package } from '@glimmer-workspace/build-support'`,
+ `export default Package.config(import.meta)`,
+]
+ .map((line) => `${line};\n`)
+ .join('\n');
+
+for (const pkg of packages('@glimmer')) {
+ if (pkg.private) {
+ console.error(`Unexpected private package in @glimmer namespace`, pkg.name);
+ } else {
+ const updated = [];
+ const { updates, packageJSON } = update(pkg, updatePublic);
+ updated.push(...updates);
+ updated.push(...updateRollupConfig(pkg, packageJSON));
+
+ report(pkg, updated);
+ }
+}
+
+for (const pkg of packages('@glimmer-workspace')) {
+ const { updates } = update(pkg, updateUniversalScripts);
+ report(pkg, updates);
+}
+
+function report(pkg: Package, updates: string[]) {
+ if (updates.length > 0) {
+ const marker = updates.length > 1 ? chalk.magenta(` (${updates.length}) `) : '';
+ console.log(
+ `${chalk.gray('-')} ${chalk.yellowBright(pkg.name)}${marker} ${chalk.gray(
+ updates.join(', ')
+ )}`
+ );
+ } else {
+ console.log(`${chalk.gray('-')} ${chalk.gray(pkg.name)}`);
+ }
+}
+
+interface PackageJSON extends Record {
+ name?: string | undefined;
+ main?: string | undefined;
+ types?: string | undefined;
+ scripts?: Record | undefined;
+ devDependencies?: Record | undefined;
+ config?:
+ | {
+ tsconfig?: string | undefined;
+ }
+ | undefined;
+}
+
+function update(
+ pkg: Package,
+ updater: (packageJSON: PackageJSON) => PackageJSON
+): { updates: string[]; packageJSON: PackageJSON } {
+ let packageJSON: PackageJSON = JSON.parse(
+ readFileSync(`${pkg.path}/package.json`, { encoding: 'utf-8' })
+ );
+ const original = JSON.stringify(packageJSON);
+
+ packageJSON = updater(packageJSON);
+
+ if (original === JSON.stringify(packageJSON)) {
+ return { updates: [], packageJSON };
+ }
+ writeFileSync(`${pkg.path}/package.json`, JSON.stringify(packageJSON, null, 2), {
+ encoding: 'utf-8',
+ });
+
+ return { updates: ['package.json'], packageJSON };
+}
+
+function updateRollupConfig(pkg: Package, packageJSON: PackageJSON): string[] {
+ if (packageJSON.main === 'index.d.ts') return [];
+
+ const config = resolve(pkg.path, 'rollup.config.mjs');
+
+ if (existsSync(config)) {
+ const contents = readFileSync(config, { encoding: 'utf-8' });
+ if (contents === ROLLUP_CONFIG) return [];
+ }
+
+ writeFileSync(config, ROLLUP_CONFIG, { encoding: 'utf-8' });
+ return ['rollup.config.mjs'];
+}
+
+function updatePublic(packageJSON: PackageJSON) {
+ return updateExports(updatePublicDependencies(updatePublicScripts(packageJSON)));
+}
+
+function updatePublicScripts(packageJSON: PackageJSON) {
+ return updateBuildScripts(updateUniversalScripts(packageJSON));
+}
+
+function updatePublicDependencies(packageJSON: PackageJSON) {
+ return {
+ ...packageJSON,
+ devDependencies: {
+ ...packageJSON.devDependencies,
+ '@glimmer-workspace/build-support': 'workspace:^',
+ },
+ };
+}
+
+function updateBuildScripts(packageJSON: PackageJSON) {
+ if (packageJSON.main === 'index.d.ts') return packageJSON;
+
+ return updateScripts(packageJSON, {
+ build: 'rollup -c rollup.config.mjs',
+ });
+}
+
+function updateExports(packageJSON: PackageJSON) {
+ if (packageJSON.main === 'index.js' || packageJSON.main === 'index.mjs') {
+ if (packageJSON.types === 'index.d.ts' || packageJSON.types === 'index.d.mts') {
+ return {
+ ...packageJSON,
+ exports: {
+ types: `./${packageJSON.types}`,
+ default: `./${packageJSON.main}`,
+ },
+ };
+ }
+ return {
+ ...packageJSON,
+ exports: {
+ default: './index.js',
+ },
+ };
+ }
+
+ if (packageJSON.main === 'index.d.ts') {
+ return { ...packageJSON, types: 'index.d.ts', exports: { types: './index.d.ts' } };
+ }
+
+ return {
+ ...packageJSON,
+ main: 'index.ts',
+ types: 'index.ts',
+ publishConfig: {
+ access: 'public',
+ main: 'dist/index.js',
+ types: 'dist/index.d.ts',
+ exports: {
+ types: './dist/index.d.ts',
+ require: './dist/index.cjs',
+ default: './dist/index.js',
+ },
+ },
+ };
+}
+
+function updateUniversalScripts(packageJSON: PackageJSON) {
+ const tsconfig = packageJSON.config?.tsconfig ?? '../tsconfig.json';
+
+ return updateScripts(packageJSON, {
+ 'test:lint': 'eslint .',
+ 'test:types': `tsc --noEmit -p ${tsconfig}`,
+ });
+}
+
+function updateScripts(packageJSON: PackageJSON, updates: Record) {
+ return {
+ ...packageJSON,
+ scripts: {
+ ...packageJSON.scripts,
+ ...updates,
+ },
+ };
+}
diff --git a/bin/yalc-publish.mts b/bin/yalc-publish.mts
new file mode 100644
index 0000000000..82da0f4b33
--- /dev/null
+++ b/bin/yalc-publish.mts
@@ -0,0 +1,13 @@
+import { execSync } from 'node:child_process';
+
+import chalk from 'chalk';
+
+import { packages } from './packages.mjs';
+
+for (const pkg of packages('@glimmer')) {
+ console.log(`${chalk.gray('# publishing')} ${chalk.cyanBright(pkg.name)}`);
+ execSync('yalc publish --push', {
+ cwd: pkg.path,
+ stdio: 'inherit',
+ });
+}
diff --git a/build/.eslintrc.json b/build/.eslintrc.json
deleted file mode 100644
index f9f025563d..0000000000
--- a/build/.eslintrc.json
+++ /dev/null
@@ -1,16 +0,0 @@
-// node files
-{
- "root": false,
- "env": {
- "es6": true,
- "node": true
- },
- "parserOptions": {
- "ecmaVersion": "latest",
- "project": ["build/tsconfig.json"]
- },
-
- "rules": {
- "no-console": "off"
- }
-}
diff --git a/build/debug.js b/build/debug.js
deleted file mode 100644
index b854d201b3..0000000000
--- a/build/debug.js
+++ /dev/null
@@ -1,85 +0,0 @@
-// @ts-check
-
-const fs = require('node:fs');
-const toml = require('toml');
-const prettier = require('prettier');
-const { normalizeAll, buildEnum, buildMetas, strip } = require('@glimmer/debug');
-
-function parse(file) {
- let opcodes = fs.readFileSync(file, { encoding: 'utf8' });
- let raw = toml.parse(opcodes);
- return normalizeAll(raw);
-}
-
-let parsed = parse('./packages/@glimmer/vm/lib/opcodes.toml');
-
-let machine = buildEnum('MachineOp', parsed.machine, 0, 15);
-let syscall = buildEnum('Op', parsed.syscall, 16);
-
-write(
- './packages/@glimmer/vm/lib/opcodes.ts',
- `import { Op, MachineOp } from '@glimmer/interfaces';\n\n` +
- machine.predicate +
- '\n' +
- syscall.predicate
-);
-
-write(
- './packages/@glimmer/interfaces/lib/vm-opcodes.d.ts',
- machine.enumString + '\n\n' + syscall.enumString
-);
-
-let debugMetadata = strip`
- import { MachineOp, Op, Option } from '@glimmer/interfaces';
- import { NormalizedMetadata } from './metadata';
-
- function fillNulls(count: number): T[] {
- let arr = new Array(count);
-
- for (let i = 0; i < count; i++) {
- arr[i] = null;
- }
-
- return arr;
- }
-
- export function opcodeMetadata(op: MachineOp | Op, isMachine: 0 | 1): Option {
- let value = isMachine ? MACHINE_METADATA[op] : METADATA[op];
-
- return value || null;
- }
-
- const METADATA: Option[] = fillNulls(Op.Size);
- const MACHINE_METADATA: Option[] = fillNulls(MachineOp.Size);
-`;
-
-debugMetadata += buildMetas('MACHINE_METADATA', parsed.machine);
-debugMetadata += buildMetas('METADATA', parsed.syscall);
-
-write('./packages/@glimmer/debug/lib/opcode-metadata.ts', debugMetadata);
-
-function write(file, contents) {
- console.log(`Generating ${file}`);
-
- format(
- file,
- strip`
-/* This file is generated by build/debug.js */
-
-${contents}
- `
- );
-}
-
-/*
- Formats the string in accordance with our prettier rules to avoid
- test failures.
-*/
-function format(file, contents) {
- let options = prettier.resolveConfig.sync(file);
- let newContents = prettier.format(contents, Object.assign({}, options, { filepath: file }));
-
- if (newContents !== contents) {
- fs.writeFileSync(file, newContents, { encoding: 'utf8' });
- }
-}
diff --git a/build/package.json b/build/package.json
deleted file mode 100644
index 0562e8112e..0000000000
--- a/build/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "private": true,
- "dependencies": {
- "@glimmer/debug": "workspace:^",
- "toml": "^3.0.0",
- "prettier": "^2.8.8"
- },
- "devDependencies": {
- "@types/prettier": "^2.7.2",
- "@types/node": "^20.1.1"
- }
-}
diff --git a/build/tsconfig.json b/build/tsconfig.json
deleted file mode 100644
index 72e5e046e5..0000000000
--- a/build/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "composite": true,
- "baseUrl": ".",
- "allowJs": true,
- "outDir": "../ts-dist/build",
- "skipLibCheck": true
- },
- "files": ["debug.js"],
- "references": [{ "path": "../packages/@glimmer/tsconfig.json" }]
-}
diff --git a/index.html b/index.html
index d923761d6a..1c25f9143b 100644
--- a/index.html
+++ b/index.html
@@ -1,39 +1,43 @@
-
-
-
- Glimmer Test Suite
-
-
-
-
-
+
-
-
+ await pkg();
+ }
+ QUnit.start();
+
+