From e431f3b6d0179b0d144e2441dd434548efc381e1 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 22 Apr 2025 22:47:58 -0400 Subject: [PATCH 1/9] Try to work out vanilla renderer demo --- packages/@glimmer-workspace/jsbin/index.html | 90 ++++++ .../@glimmer-workspace/jsbin/package.json | 18 ++ .../@glimmer-workspace/jsbin/vite.config.ts | 22 ++ pnpm-lock.yaml | 285 ++++++++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 packages/@glimmer-workspace/jsbin/index.html create mode 100644 packages/@glimmer-workspace/jsbin/package.json create mode 100644 packages/@glimmer-workspace/jsbin/vite.config.ts diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html new file mode 100644 index 000000000..a78c7c277 --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -0,0 +1,90 @@ + + + + + + Minimal Glimmer Rendering + + + + diff --git a/packages/@glimmer-workspace/jsbin/package.json b/packages/@glimmer-workspace/jsbin/package.json new file mode 100644 index 000000000..eec61602c --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/package.json @@ -0,0 +1,18 @@ +{ + "private": true, + "name": "@glimmer-workspace/krausest", + "type": "module", + "scripts": { + "start": "vite" + }, + "dependencies": {}, + "devDependencies": { + "vite": "^5.4.10" + }, + "engines": { + "node": ">=18.0.0" + }, + "config": { + "tsconfig": "../../tsconfig.json" + } +} diff --git a/packages/@glimmer-workspace/jsbin/vite.config.ts b/packages/@glimmer-workspace/jsbin/vite.config.ts new file mode 100644 index 000000000..d7a14207f --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/vite.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from 'vite'; +import path from 'node:path'; +const currentPath = import.meta.dirname; + +const packagesPath = path.resolve(currentPath, '../../../packages'); +const packagePath = (name: string) => { + const result = path.join(packagesPath, name, 'dist/dev/index.js'); + return result; +}; + +export default defineConfig({ + resolve: { + alias: { + '@glimmer/opcode-compiler': packagePath('@glimmer/opcode-compiler'), + '@glimmer/compiler': packagePath('@glimmer/compiler'), + '@glimmer/manager': packagePath('@glimmer/manager'), + '@glimmer/program': packagePath('@glimmer/program'), + '@glimmer/validator': packagePath('@glimmer/validator'), + '@glimmer/runtime': packagePath('@glimmer/runtime'), + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 926812675..a77bc9269 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -740,6 +740,12 @@ importers: specifier: workspace:* version: link:../../../@glimmer/wire-format + packages/@glimmer-workspace/jsbin: + devDependencies: + vite: + specifier: ^5.4.10 + version: 5.4.18(@types/node@22.13.4)(terser@5.37.0) + packages/@glimmer-workspace/test-utils: dependencies: '@glimmer/interfaces': @@ -2278,6 +2284,12 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -2296,6 +2308,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.23.1': resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} @@ -2314,6 +2332,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.23.1': resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} @@ -2332,6 +2356,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.23.1': resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} @@ -2350,6 +2380,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.23.1': resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} @@ -2368,6 +2404,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.23.1': resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} @@ -2386,6 +2428,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.23.1': resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} @@ -2404,6 +2452,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.23.1': resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} @@ -2422,6 +2476,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.23.1': resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} @@ -2440,6 +2500,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.23.1': resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} @@ -2458,6 +2524,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.23.1': resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} @@ -2476,6 +2548,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.23.1': resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} @@ -2494,6 +2572,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.23.1': resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} @@ -2512,6 +2596,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.23.1': resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} @@ -2530,6 +2620,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.23.1': resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} @@ -2548,6 +2644,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.23.1': resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} @@ -2566,6 +2668,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.23.1': resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} @@ -2590,6 +2698,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.23.1': resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} @@ -2620,6 +2734,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.23.1': resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} @@ -2638,6 +2758,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.23.1': resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} @@ -2656,6 +2782,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.23.1': resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} @@ -2674,6 +2806,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.23.1': resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} @@ -2692,6 +2830,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.23.1': resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} @@ -5770,6 +5914,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.23.1: resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} @@ -10340,6 +10489,37 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite@5.4.18: + resolution: {integrity: sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^22.13.4 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@6.1.1: resolution: {integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -11429,6 +11609,9 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.23.1': optional: true @@ -11438,6 +11621,9 @@ snapshots: '@esbuild/android-arm64@0.18.20': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.23.1': optional: true @@ -11447,6 +11633,9 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.23.1': optional: true @@ -11456,6 +11645,9 @@ snapshots: '@esbuild/android-x64@0.18.20': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.23.1': optional: true @@ -11465,6 +11657,9 @@ snapshots: '@esbuild/darwin-arm64@0.18.20': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.23.1': optional: true @@ -11474,6 +11669,9 @@ snapshots: '@esbuild/darwin-x64@0.18.20': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.23.1': optional: true @@ -11483,6 +11681,9 @@ snapshots: '@esbuild/freebsd-arm64@0.18.20': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.23.1': optional: true @@ -11492,6 +11693,9 @@ snapshots: '@esbuild/freebsd-x64@0.18.20': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.23.1': optional: true @@ -11501,6 +11705,9 @@ snapshots: '@esbuild/linux-arm64@0.18.20': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.23.1': optional: true @@ -11510,6 +11717,9 @@ snapshots: '@esbuild/linux-arm@0.18.20': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.23.1': optional: true @@ -11519,6 +11729,9 @@ snapshots: '@esbuild/linux-ia32@0.18.20': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.23.1': optional: true @@ -11528,6 +11741,9 @@ snapshots: '@esbuild/linux-loong64@0.18.20': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.23.1': optional: true @@ -11537,6 +11753,9 @@ snapshots: '@esbuild/linux-mips64el@0.18.20': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.23.1': optional: true @@ -11546,6 +11765,9 @@ snapshots: '@esbuild/linux-ppc64@0.18.20': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.23.1': optional: true @@ -11555,6 +11777,9 @@ snapshots: '@esbuild/linux-riscv64@0.18.20': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.23.1': optional: true @@ -11564,6 +11789,9 @@ snapshots: '@esbuild/linux-s390x@0.18.20': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.23.1': optional: true @@ -11573,6 +11801,9 @@ snapshots: '@esbuild/linux-x64@0.18.20': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.23.1': optional: true @@ -11585,6 +11816,9 @@ snapshots: '@esbuild/netbsd-x64@0.18.20': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.23.1': optional: true @@ -11600,6 +11834,9 @@ snapshots: '@esbuild/openbsd-x64@0.18.20': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.23.1': optional: true @@ -11609,6 +11846,9 @@ snapshots: '@esbuild/sunos-x64@0.18.20': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.23.1': optional: true @@ -11618,6 +11858,9 @@ snapshots: '@esbuild/win32-arm64@0.18.20': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.23.1': optional: true @@ -11627,6 +11870,9 @@ snapshots: '@esbuild/win32-ia32@0.18.20': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.23.1': optional: true @@ -11636,6 +11882,9 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.23.1': optional: true @@ -15603,6 +15852,32 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.23.1: optionalDependencies: '@esbuild/aix-ppc64': 0.23.1 @@ -20950,6 +21225,16 @@ snapshots: - tsx - yaml + vite@5.4.18(@types/node@22.13.4)(terser@5.37.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + '@types/node': 22.13.4 + fsevents: 2.3.3 + terser: 5.37.0 + vite@6.1.1(@types/node@22.13.4)(jiti@2.4.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0): dependencies: esbuild: 0.24.2 From ccda492b24c04c0f772c685fa68b774e70cc3588 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 24 Apr 2025 08:56:03 -0400 Subject: [PATCH 2/9] wow --- .../@glimmer-workspace/jsbin/args-proxy.ts | 51 +++++++++++ .../boilerplate-example-component-manager.ts | 85 ++++++++++++++++++ packages/@glimmer-workspace/jsbin/index.html | 88 ++++++++++++++++--- .../@glimmer-workspace/jsbin/interfaces.ts | 3 + .../@glimmer-workspace/jsbin/package.json | 9 +- .../@glimmer-workspace/jsbin/vite.config.ts | 2 + pnpm-lock.yaml | 13 +++ 7 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 packages/@glimmer-workspace/jsbin/args-proxy.ts create mode 100644 packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts create mode 100644 packages/@glimmer-workspace/jsbin/interfaces.ts diff --git a/packages/@glimmer-workspace/jsbin/args-proxy.ts b/packages/@glimmer-workspace/jsbin/args-proxy.ts new file mode 100644 index 000000000..5d0dfb498 --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/args-proxy.ts @@ -0,0 +1,51 @@ +import type { CapturedArguments, CapturedNamedArguments, Reference } from '@glimmer/interfaces'; +import { valueForRef } from '@glimmer/reference'; + +import type { ComponentArgs } from './interfaces'; + +class ArgsProxy implements ProxyHandler { + isExtensible() { + return false; + } + + ownKeys(target: CapturedNamedArguments): string[] { + return Object.keys(target); + } + + getOwnPropertyDescriptor( + target: CapturedNamedArguments, + p: PropertyKey + ): PropertyDescriptor | undefined { + let desc: PropertyDescriptor | undefined; + if (typeof p === 'string' && p in target) { + const value = valueForRef(target[p] as Reference); + desc = { + enumerable: true, + configurable: false, + writable: false, + value, + }; + } + return desc; + } + + has(target: CapturedNamedArguments, p: PropertyKey): boolean { + return typeof p === 'string' ? p in target : false; + } + + get(target: CapturedNamedArguments, p: PropertyKey): unknown { + if (typeof p === 'string' && p in target) { + return valueForRef(target[p] as Reference); + } + + return; + } + + set() { + return false; + } +} + +export default function argsProxy(args: CapturedArguments): ComponentArgs { + return new Proxy(args.named, new ArgsProxy()); +} diff --git a/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts b/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts new file mode 100644 index 000000000..4d57223ec --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts @@ -0,0 +1,85 @@ +import type { Dict, Owner, Template, VMArguments, WithCreateInstance } from '@glimmer/interfaces'; +import type { Reference } from '@glimmer/reference'; +import { getComponentTemplate } from '@glimmer/manager'; +import { createConstRef } from '@glimmer/reference'; +import { EMPTY_ARGS } from '@glimmer/runtime'; + +import type { ComponentArgs } from './interfaces'; + +import argsProxy from './args-proxy'; + +const BASIC_COMPONENT_CAPABILITIES = { + dynamicLayout: false, + dynamicTag: false, + prepareArgs: false, + createArgs: true, + attributeHook: false, + elementHook: false, + dynamicScope: false, + createCaller: false, + updateHook: false, + createInstance: true, + wrapped: false, + willDestroy: false, + hasSubOwner: false, +}; + +interface BasicState { + self: Reference; + instance: object; +} + +class BasicComponentManager + implements WithCreateInstance) => object> +{ + create( + _owner: Owner, + Component: { new (args: ComponentArgs): object }, + args: VMArguments | null + ) { + const instance = new Component(argsProxy(args === null ? EMPTY_ARGS : args.capture())); + const self = createConstRef(instance, 'this'); + return { instance, self }; + } + + getDebugName() { + return 'basic-benchmark-component'; + } + + didCreate() { + // + } + + didRenderLayout() { + // + } + + didUpdate() { + // + } + + didUpdateLayout() { + // + } + + getCapabilities() { + return BASIC_COMPONENT_CAPABILITIES; + } + + getSelf(state: BasicState) { + return state.self; + } + + getDestroyable(state: BasicState) { + return state.instance; + } + + getStaticLayout(definition: object): Template { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme + return getComponentTemplate(definition)!(); + } +} + +const basicComponentManager = new BasicComponentManager(); + +export default basicComponentManager; diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index a78c7c277..52aa5c1ed 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -12,11 +12,13 @@ renderSync, on, } from "@glimmer/runtime"; - import { EvaluationContextImpl } from "@glimmer/opcode-compiler"; + import { EvaluationContextImpl, templateFactory } from "@glimmer/opcode-compiler"; import { artifacts, RuntimeOpImpl } from "@glimmer/program"; - import { setComponentTemplate } from "@glimmer/manager"; - import { templateFactory } from "@glimmer/opcode-compiler"; + import { setComponentTemplate, setInternalComponentManager } from "@glimmer/manager"; + import { precompile, precompileJSON } from "@glimmer/compiler"; import { trackedData } from "@glimmer/validator"; + import { preprocess, getTemplateLocals } from "@glimmer/syntax"; + import boilerplateComponentManager from "./boilerplate-example-component-manager"; const scheduledDestructors = []; const scheduledFinalizers = []; @@ -46,20 +48,73 @@ increment = () => this.#data["count"]++; static { + setInternalComponentManager(boilerplateComponentManager, this); setComponentTemplate( - templateFactory({ - id: null, - block: - '[[[1,"\\n "],[10,2],[12],[1,"You have clicked the button "],[1,[30,0,["count"]]],[1," times."],[13],[1,"\\n\\n "],[11,"button"],[4,[32,0],["click",[30,0,["increment"]]],null],[12],[1,"Click"],[13],[1,"\\n "]],[],[]]', - moduleName: "whatev", - scope: () => [on], - isStrictMode: true, - }), + /* Custom Compile Template because Glimmer Standalone is very unergonomic */ + compileTemplate( + `

You have clicked the button {{this.count}} times.

+ + `, + { scope: { on } }, + ), this, ); } } + /** + * + * Copied from limber/ember-repl + * + * The reason why we can't use precompile directly is because of this: + * https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/compiler/lib/compiler.ts#L132 + * + * Support for dynamically compiling templates in strict mode doesn't seem to be fully their yet. + * That JSON.stringify (and the lines after) prevent us from easily setting the scope function, + * which means that *everything* is undefined. + */ + function compileTemplate(source, { moduleName, scope = {} }) { + const localScope = { ...scope }; + const locals = getTemplateLocals(source); + + const options = { + strictMode: true, + moduleName, + locals, + isProduction: false, + meta: { moduleName }, + }; + + // Copied from @glimmer/compiler/lib/compiler#precompile + const [block, usedLocals] = precompileJSON(source, options); + + const usedScope = usedLocals.map((key) => { + const value = localScope[key]; + + if (!value) { + throw new Error( + `Attempt to use ${key} in compiled hbs, but it was not available in scope. ` + + `Available scope includes: ${Object.keys(localScope)}`, + ); + } + + return value; + }); + + const blockJSON = JSON.stringify(block); + const templateJSONObject = { + id: moduleName, + block: blockJSON, + moduleName: moduleName ?? "(dynamically compiled component)", + scope: () => usedScope, + isStrictMode: true, + }; + + const factory = templateFactory(templateJSONObject); + + return factory; + } + function render() { const element = document.body; const sharedArtifacts = artifacts(); @@ -68,7 +123,16 @@ const helpers = new Map(); const modifiers = new Map(); - const runtime = runtimeOptions({ document }, envDelegate, sharedArtifacts, null); + const resolver = { + lookupHelper: (name) => helpers.get(name) ?? null, + lookupModifier: (name) => modifiers.get(name) ?? null, + lookupComponent: (name) => components.get(name) ?? null, + + lookupBuiltInHelper: () => null, + lookupBuiltInModifier: () => null, + }; + + const runtime = runtimeOptions({ document }, envDelegate, sharedArtifacts, resolver); const context = new EvaluationContextImpl( sharedArtifacts, diff --git a/packages/@glimmer-workspace/jsbin/interfaces.ts b/packages/@glimmer-workspace/jsbin/interfaces.ts new file mode 100644 index 000000000..413482f7d --- /dev/null +++ b/packages/@glimmer-workspace/jsbin/interfaces.ts @@ -0,0 +1,3 @@ +import type { Dict } from '@glimmer/interfaces'; + +export type ComponentArgs = Readonly; diff --git a/packages/@glimmer-workspace/jsbin/package.json b/packages/@glimmer-workspace/jsbin/package.json index eec61602c..8b3f5c83a 100644 --- a/packages/@glimmer-workspace/jsbin/package.json +++ b/packages/@glimmer-workspace/jsbin/package.json @@ -1,11 +1,16 @@ { "private": true, - "name": "@glimmer-workspace/krausest", + "name": "@glimmer-workspace/js-bin", "type": "module", "scripts": { "start": "vite" }, - "dependencies": {}, + "dependencies": { + "@glimmer/interfaces": "workspace:*", + "@glimmer/manager": "workspace:*", + "@glimmer/reference": "workspace:*", + "@glimmer/runtime": "workspace:*" + }, "devDependencies": { "vite": "^5.4.10" }, diff --git a/packages/@glimmer-workspace/jsbin/vite.config.ts b/packages/@glimmer-workspace/jsbin/vite.config.ts index d7a14207f..d05695bf9 100644 --- a/packages/@glimmer-workspace/jsbin/vite.config.ts +++ b/packages/@glimmer-workspace/jsbin/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vite'; import path from 'node:path'; const currentPath = import.meta.dirname; +import virtual from 'vite-plugin-virtual'; const packagesPath = path.resolve(currentPath, '../../../packages'); const packagePath = (name: string) => { @@ -17,6 +18,7 @@ export default defineConfig({ '@glimmer/program': packagePath('@glimmer/program'), '@glimmer/validator': packagePath('@glimmer/validator'), '@glimmer/runtime': packagePath('@glimmer/runtime'), + '@glimmer/syntax': packagePath('@glimmer/syntax'), }, }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a77bc9269..8023cc552 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,6 +741,19 @@ importers: version: link:../../../@glimmer/wire-format packages/@glimmer-workspace/jsbin: + dependencies: + '@glimmer/interfaces': + specifier: workspace:* + version: link:../../@glimmer/interfaces + '@glimmer/manager': + specifier: workspace:* + version: link:../../@glimmer/manager + '@glimmer/reference': + specifier: workspace:* + version: link:../../@glimmer/reference + '@glimmer/runtime': + specifier: workspace:* + version: link:../../@glimmer/runtime devDependencies: vite: specifier: ^5.4.10 From a1ff17e38c129f4d92a76756f1e6e2034c27de91 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 24 Apr 2025 19:41:16 -0400 Subject: [PATCH 3/9] 'this' is undefined? --- packages/@glimmer-workspace/jsbin/index.html | 63 ++++++-------------- 1 file changed, 17 insertions(+), 46 deletions(-) diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index 52aa5c1ed..0d6052d13 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -45,17 +45,18 @@ get count() { return this.#data["count"]; } + increment = () => this.#data["count"]++; static { setInternalComponentManager(boilerplateComponentManager, this); setComponentTemplate( /* Custom Compile Template because Glimmer Standalone is very unergonomic */ - compileTemplate( + createTemplate( `

You have clicked the button {{this.count}} times.

`, - { scope: { on } }, + { on }, ), this, ); @@ -64,55 +65,25 @@ /** * - * Copied from limber/ember-repl - * - * The reason why we can't use precompile directly is because of this: - * https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/compiler/lib/compiler.ts#L132 + * Copied from @glimmer-workspace/integration-tests/lib/compile * - * Support for dynamically compiling templates in strict mode doesn't seem to be fully their yet. - * That JSON.stringify (and the lines after) prevent us from easily setting the scope function, - * which means that *everything* is undefined. + * We don't have a good way to do runtime compilation in glimmer. */ - function compileTemplate(source, { moduleName, scope = {} }) { - const localScope = { ...scope }; - const locals = getTemplateLocals(source); - - const options = { - strictMode: true, - moduleName, - locals, - isProduction: false, - meta: { moduleName }, - }; - - // Copied from @glimmer/compiler/lib/compiler#precompile - const [block, usedLocals] = precompileJSON(source, options); - - const usedScope = usedLocals.map((key) => { - const value = localScope[key]; - - if (!value) { - throw new Error( - `Attempt to use ${key} in compiled hbs, but it was not available in scope. ` + - `Available scope includes: ${Object.keys(localScope)}`, - ); - } - - return value; - }); - - const blockJSON = JSON.stringify(block); - const templateJSONObject = { - id: moduleName, - block: blockJSON, - moduleName: moduleName ?? "(dynamically compiled component)", - scope: () => usedScope, + function createTemplate(templateSource, scopeValues = {}) { + let options = {}; + options.locals = Object.keys(scopeValues ?? {}); + let [block, usedLocals] = precompileJSON(templateSource, { strictMode: true, ...options }); + let reifiedScopeValues = usedLocals.map((key) => scopeValues[key]); + + let templateBlock = { + id: `id-${Date.now()}`, + block: JSON.stringify(block), + moduleName: options.meta?.moduleName ?? "(unknown template module)", + scope: reifiedScopeValues.length > 0 ? () => reifiedScopeValues : null, isStrictMode: true, }; - const factory = templateFactory(templateJSONObject); - - return factory; + return templateFactory(templateBlock); } function render() { From 9bf9d84787f8709c851afb718d8e6d4f8b763f78 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:18:02 -0400 Subject: [PATCH 4/9] omg, what a ride --- packages/@glimmer-workspace/jsbin/index.html | 114 +++++++++++++++++- .../@glimmer-workspace/jsbin/package.json | 3 +- .../@glimmer-workspace/jsbin/vite.config.ts | 18 ++- pnpm-lock.yaml | 3 + 4 files changed, 128 insertions(+), 10 deletions(-) diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index 0d6052d13..5ec0b885a 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -16,9 +16,10 @@ import { artifacts, RuntimeOpImpl } from "@glimmer/program"; import { setComponentTemplate, setInternalComponentManager } from "@glimmer/manager"; import { precompile, precompileJSON } from "@glimmer/compiler"; - import { trackedData } from "@glimmer/validator"; + import { dirtyTagFor, tagFor, consumeTag } from "@glimmer/validator"; import { preprocess, getTemplateLocals } from "@glimmer/syntax"; import boilerplateComponentManager from "./boilerplate-example-component-manager"; + import setGlobalContext from "@glimmer/global-context"; const scheduledDestructors = []; const scheduledFinalizers = []; @@ -28,6 +29,100 @@ queue.length = 0; } + let result; + + function registerResult(_result) { + result = _result; + } + + let revalidateScheduled = false; + + setGlobalContext({ + scheduleRevalidate() { + if (!revalidateScheduled) { + Promise.resolve() + .then(() => { + const { env } = result; + env.begin(); + result.rerender(); + revalidateScheduled = false; + env.commit(); + }) + .catch((e) => console.error(e)); + } + }, + + getProp(obj, prop) { + return obj[prop]; + }, + + setProp(obj, prop, value) { + obj[prop] = value; + }, + + getPath(obj, path) { + let parts = path.split("."); + + let current = obj; + + for (let part of parts) { + if ( + typeof current === "function" || + (typeof current === "object" && current !== null) + ) { + current = current[part]; + } + } + + return current; + }, + + setPath(obj, path, value) { + let parts = path.split("."); + + let current = obj; + let pathToSet = parts.pop(); + + for (let part of parts) { + current = current[part]; + } + + current[pathToSet] = value; + }, + + toBool(value) { + return Boolean(value); + }, + + toIterator() { + return null; + }, + + warnIfStyleNotTrusted() { + // noop + }, + + scheduleDestroy(destroyable, destructor) { + scheduledDestructors.push(() => destructor(destroyable)); + }, + + scheduleDestroyed(fn) { + scheduledFinalizers.push(fn); + }, + + assert(test, msg) { + if (!test) { + throw new Error(msg); + } + }, + + deprecate(msg, test) { + if (!test) { + console.warn(msg); + } + }, + }); + function createEnvDelegate(isInteractive) { return { isInteractive: true, @@ -40,13 +135,18 @@ } class Counter { - #data = trackedData({ count: 0 }); + _count = 0; get count() { - return this.#data["count"]; + consumeTag(tagFor(this, "_count")); + return this._count; + } + set count(value) { + this._count = value; + dirtyTagFor(this, "_count"); } - increment = () => this.#data["count"]++; + increment = () => this.count++; static { setInternalComponentManager(boilerplateComponentManager, this); @@ -55,7 +155,7 @@ createTemplate( `

You have clicked the button {{this.count}} times.

- `, + `, { on }, ), this, @@ -115,7 +215,9 @@ const cursor = { element, nextSibling: null }; const treeBuilder = NewTreeBuilder.forInitialRender(env, cursor); - renderSync(env, renderComponent(context, treeBuilder, {}, Counter, {})); + const result = renderSync(env, renderComponent(context, treeBuilder, {}, Counter, {})); + + registerResult(result); } render(); diff --git a/packages/@glimmer-workspace/jsbin/package.json b/packages/@glimmer-workspace/jsbin/package.json index 8b3f5c83a..710df289f 100644 --- a/packages/@glimmer-workspace/jsbin/package.json +++ b/packages/@glimmer-workspace/jsbin/package.json @@ -9,7 +9,8 @@ "@glimmer/interfaces": "workspace:*", "@glimmer/manager": "workspace:*", "@glimmer/reference": "workspace:*", - "@glimmer/runtime": "workspace:*" + "@glimmer/runtime": "workspace:*", + "@glimmer/global-context": "workspace:*" }, "devDependencies": { "vite": "^5.4.10" diff --git a/packages/@glimmer-workspace/jsbin/vite.config.ts b/packages/@glimmer-workspace/jsbin/vite.config.ts index d05695bf9..ee0000809 100644 --- a/packages/@glimmer-workspace/jsbin/vite.config.ts +++ b/packages/@glimmer-workspace/jsbin/vite.config.ts @@ -1,7 +1,6 @@ import { defineConfig } from 'vite'; import path from 'node:path'; const currentPath = import.meta.dirname; -import virtual from 'vite-plugin-virtual'; const packagesPath = path.resolve(currentPath, '../../../packages'); const packagePath = (name: string) => { @@ -12,13 +11,26 @@ const packagePath = (name: string) => { export default defineConfig({ resolve: { alias: { - '@glimmer/opcode-compiler': packagePath('@glimmer/opcode-compiler'), '@glimmer/compiler': packagePath('@glimmer/compiler'), + '@glimmer/constants': packagePath('@glimmer/constants'), + '@glimmer/debug': packagePath('@glimmer/debug'), + '@glimmer/debug-util': packagePath('@glimmer/debug-util'), + '@glimmer/destroyable': packagePath('@glimmer/destroyable'), + '@glimmer/encoder': packagePath('@glimmer/encoder'), + '@glimmer/global-context': packagePath('@glimmer/global-context'), + '@glimmer/interfaces': packagePath('@glimmer/interfaces'), '@glimmer/manager': packagePath('@glimmer/manager'), + '@glimmer/node': packagePath('@glimmer/node'), + '@glimmer/opcode-compiler': packagePath('@glimmer/opcode-compiler'), + '@glimmer/owner': packagePath('@glimmer/owner'), '@glimmer/program': packagePath('@glimmer/program'), - '@glimmer/validator': packagePath('@glimmer/validator'), + '@glimmer/reference': packagePath('@glimmer/reference'), '@glimmer/runtime': packagePath('@glimmer/runtime'), '@glimmer/syntax': packagePath('@glimmer/syntax'), + '@glimmer/validator': packagePath('@glimmer/validator'), + '@glimmer/util': packagePath('@glimmer/util'), + '@glimmer/vm': packagePath('@glimmer/vm'), + '@glimmer/wire-format': packagePath('@glimmer/wire-format'), }, }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8023cc552..d190f26ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -742,6 +742,9 @@ importers: packages/@glimmer-workspace/jsbin: dependencies: + '@glimmer/global-context': + specifier: workspace:* + version: link:../../@glimmer/global-context '@glimmer/interfaces': specifier: workspace:* version: link:../../@glimmer/interfaces From c56f13fa7a540420540cf2467755aafaf3d6fd45 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:25:59 -0400 Subject: [PATCH 5/9] All in the HTML --- .../@glimmer-workspace/jsbin/args-proxy.ts | 51 --------- .../boilerplate-example-component-manager.ts | 85 -------------- packages/@glimmer-workspace/jsbin/index.html | 108 +++++++++++++++++- .../@glimmer-workspace/jsbin/interfaces.ts | 3 - 4 files changed, 106 insertions(+), 141 deletions(-) delete mode 100644 packages/@glimmer-workspace/jsbin/args-proxy.ts delete mode 100644 packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts delete mode 100644 packages/@glimmer-workspace/jsbin/interfaces.ts diff --git a/packages/@glimmer-workspace/jsbin/args-proxy.ts b/packages/@glimmer-workspace/jsbin/args-proxy.ts deleted file mode 100644 index 5d0dfb498..000000000 --- a/packages/@glimmer-workspace/jsbin/args-proxy.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { CapturedArguments, CapturedNamedArguments, Reference } from '@glimmer/interfaces'; -import { valueForRef } from '@glimmer/reference'; - -import type { ComponentArgs } from './interfaces'; - -class ArgsProxy implements ProxyHandler { - isExtensible() { - return false; - } - - ownKeys(target: CapturedNamedArguments): string[] { - return Object.keys(target); - } - - getOwnPropertyDescriptor( - target: CapturedNamedArguments, - p: PropertyKey - ): PropertyDescriptor | undefined { - let desc: PropertyDescriptor | undefined; - if (typeof p === 'string' && p in target) { - const value = valueForRef(target[p] as Reference); - desc = { - enumerable: true, - configurable: false, - writable: false, - value, - }; - } - return desc; - } - - has(target: CapturedNamedArguments, p: PropertyKey): boolean { - return typeof p === 'string' ? p in target : false; - } - - get(target: CapturedNamedArguments, p: PropertyKey): unknown { - if (typeof p === 'string' && p in target) { - return valueForRef(target[p] as Reference); - } - - return; - } - - set() { - return false; - } -} - -export default function argsProxy(args: CapturedArguments): ComponentArgs { - return new Proxy(args.named, new ArgsProxy()); -} diff --git a/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts b/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts deleted file mode 100644 index 4d57223ec..000000000 --- a/packages/@glimmer-workspace/jsbin/boilerplate-example-component-manager.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { Dict, Owner, Template, VMArguments, WithCreateInstance } from '@glimmer/interfaces'; -import type { Reference } from '@glimmer/reference'; -import { getComponentTemplate } from '@glimmer/manager'; -import { createConstRef } from '@glimmer/reference'; -import { EMPTY_ARGS } from '@glimmer/runtime'; - -import type { ComponentArgs } from './interfaces'; - -import argsProxy from './args-proxy'; - -const BASIC_COMPONENT_CAPABILITIES = { - dynamicLayout: false, - dynamicTag: false, - prepareArgs: false, - createArgs: true, - attributeHook: false, - elementHook: false, - dynamicScope: false, - createCaller: false, - updateHook: false, - createInstance: true, - wrapped: false, - willDestroy: false, - hasSubOwner: false, -}; - -interface BasicState { - self: Reference; - instance: object; -} - -class BasicComponentManager - implements WithCreateInstance) => object> -{ - create( - _owner: Owner, - Component: { new (args: ComponentArgs): object }, - args: VMArguments | null - ) { - const instance = new Component(argsProxy(args === null ? EMPTY_ARGS : args.capture())); - const self = createConstRef(instance, 'this'); - return { instance, self }; - } - - getDebugName() { - return 'basic-benchmark-component'; - } - - didCreate() { - // - } - - didRenderLayout() { - // - } - - didUpdate() { - // - } - - didUpdateLayout() { - // - } - - getCapabilities() { - return BASIC_COMPONENT_CAPABILITIES; - } - - getSelf(state: BasicState) { - return state.self; - } - - getDestroyable(state: BasicState) { - return state.instance; - } - - getStaticLayout(definition: object): Template { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme - return getComponentTemplate(definition)!(); - } -} - -const basicComponentManager = new BasicComponentManager(); - -export default basicComponentManager; diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index 5ec0b885a..d74ca7d7e 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -14,12 +14,116 @@ } from "@glimmer/runtime"; import { EvaluationContextImpl, templateFactory } from "@glimmer/opcode-compiler"; import { artifacts, RuntimeOpImpl } from "@glimmer/program"; - import { setComponentTemplate, setInternalComponentManager } from "@glimmer/manager"; + import { + setComponentTemplate, + setInternalComponentManager, + getComponentTemplate, + } from "@glimmer/manager"; import { precompile, precompileJSON } from "@glimmer/compiler"; import { dirtyTagFor, tagFor, consumeTag } from "@glimmer/validator"; import { preprocess, getTemplateLocals } from "@glimmer/syntax"; - import boilerplateComponentManager from "./boilerplate-example-component-manager"; import setGlobalContext from "@glimmer/global-context"; + import { createConstRef, valueForRef } from "@glimmer/reference"; + import { EMPTY_ARGS } from "@glimmer/runtime"; + + class ArgsProxy { + isExtensible() { + return false; + } + + ownKeys(target) { + return Object.keys(target); + } + + getOwnPropertyDescriptor(target, p) { + let desc; + if (typeof p === "string" && p in target) { + const value = valueForRef(target[p]); + desc = { + enumerable: true, + configurable: false, + writable: false, + value, + }; + } + return desc; + } + + has(target, p) { + return typeof p === "string" ? p in target : false; + } + + get(target, p) { + if (typeof p === "string" && p in target) { + return valueForRef(target[p]); + } + + return; + } + + set() { + return false; + } + } + + function argsProxy(args) { + return new Proxy(args.named, new ArgsProxy()); + } + + /** + This repo has no component managers + */ + class BasicComponentManager { + create(_owner, Component, args) { + const instance = new Component(argsProxy(args === null ? EMPTY_ARGS : args.capture())); + const self = createConstRef(instance, "this"); + return { instance, self }; + } + + getDebugName() { + return "example"; + } + + didCreate() {} + + didRenderLayout() {} + + didUpdate() {} + + didUpdateLayout() {} + + getCapabilities() { + return { + dynamicLayout: false, + dynamicTag: false, + prepareArgs: false, + createArgs: true, + attributeHook: false, + elementHook: false, + dynamicScope: false, + createCaller: false, + updateHook: false, + createInstance: true, + wrapped: false, + willDestroy: false, + hasSubOwner: false, + }; + } + + getSelf(state) { + return state.self; + } + + getDestroyable(state) { + return state.instance; + } + + getStaticLayout(definition) { + return getComponentTemplate(definition)(); + } + } + + const boilerplateComponentManager = new BasicComponentManager(); const scheduledDestructors = []; const scheduledFinalizers = []; diff --git a/packages/@glimmer-workspace/jsbin/interfaces.ts b/packages/@glimmer-workspace/jsbin/interfaces.ts deleted file mode 100644 index 413482f7d..000000000 --- a/packages/@glimmer-workspace/jsbin/interfaces.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { Dict } from '@glimmer/interfaces'; - -export type ComponentArgs = Readonly; From 42d7e33b7828103975aff4bd1ed169e360cde9ac Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:28:17 -0400 Subject: [PATCH 6/9] Lint:fix --- packages/@glimmer-workspace/jsbin/package.json | 5 +++-- repo-metadata/metadata.json | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/@glimmer-workspace/jsbin/package.json b/packages/@glimmer-workspace/jsbin/package.json index 710df289f..7e9812523 100644 --- a/packages/@glimmer-workspace/jsbin/package.json +++ b/packages/@glimmer-workspace/jsbin/package.json @@ -1,16 +1,17 @@ { "private": true, "name": "@glimmer-workspace/js-bin", + "version": "0.92.0", "type": "module", "scripts": { "start": "vite" }, "dependencies": { + "@glimmer/global-context": "workspace:*", "@glimmer/interfaces": "workspace:*", "@glimmer/manager": "workspace:*", "@glimmer/reference": "workspace:*", - "@glimmer/runtime": "workspace:*", - "@glimmer/global-context": "workspace:*" + "@glimmer/runtime": "workspace:*" }, "devDependencies": { "vite": "^5.4.10" diff --git a/repo-metadata/metadata.json b/repo-metadata/metadata.json index 67b44db03..d20a87fef 100644 --- a/repo-metadata/metadata.json +++ b/repo-metadata/metadata.json @@ -135,6 +135,18 @@ "./package.json": [[["default"], "./package.json"]] } }, + { + "root": "packages/@glimmer-workspace/jsbin", + "name": "@glimmer-workspace/js-bin", + "type": "module", + "private": true, + "repo-meta": { + "built": false + }, + "entryPoints": { + "./package.json": [[["default"], "./package.json"]] + } + }, { "root": "packages/@glimmer-workspace/test-utils", "name": "@glimmer-workspace/test-utils", From c5bebff67be3d7428c51541835b239e40eacfaac Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:42:56 -0400 Subject: [PATCH 7/9] Updates --- .../@glimmer-workspace/jsbin/vite.config.ts | 61 ++++++++++--------- repo-metadata/metadata.json | 2 + 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/packages/@glimmer-workspace/jsbin/vite.config.ts b/packages/@glimmer-workspace/jsbin/vite.config.ts index ee0000809..7c2ec69e9 100644 --- a/packages/@glimmer-workspace/jsbin/vite.config.ts +++ b/packages/@glimmer-workspace/jsbin/vite.config.ts @@ -3,34 +3,39 @@ import path from 'node:path'; const currentPath = import.meta.dirname; const packagesPath = path.resolve(currentPath, '../../../packages'); -const packagePath = (name: string) => { - const result = path.join(packagesPath, name, 'dist/dev/index.js'); - return result; -}; -export default defineConfig({ - resolve: { - alias: { - '@glimmer/compiler': packagePath('@glimmer/compiler'), - '@glimmer/constants': packagePath('@glimmer/constants'), - '@glimmer/debug': packagePath('@glimmer/debug'), - '@glimmer/debug-util': packagePath('@glimmer/debug-util'), - '@glimmer/destroyable': packagePath('@glimmer/destroyable'), - '@glimmer/encoder': packagePath('@glimmer/encoder'), - '@glimmer/global-context': packagePath('@glimmer/global-context'), - '@glimmer/interfaces': packagePath('@glimmer/interfaces'), - '@glimmer/manager': packagePath('@glimmer/manager'), - '@glimmer/node': packagePath('@glimmer/node'), - '@glimmer/opcode-compiler': packagePath('@glimmer/opcode-compiler'), - '@glimmer/owner': packagePath('@glimmer/owner'), - '@glimmer/program': packagePath('@glimmer/program'), - '@glimmer/reference': packagePath('@glimmer/reference'), - '@glimmer/runtime': packagePath('@glimmer/runtime'), - '@glimmer/syntax': packagePath('@glimmer/syntax'), - '@glimmer/validator': packagePath('@glimmer/validator'), - '@glimmer/util': packagePath('@glimmer/util'), - '@glimmer/vm': packagePath('@glimmer/vm'), - '@glimmer/wire-format': packagePath('@glimmer/wire-format'), +export default defineConfig(({ mode }) => { + let subDir = mode === 'production' ? 'prod' : 'dev'; + + const packagePath = (name: string) => { + const result = path.join(packagesPath, name, 'dist/' + subDir + '/index.js'); + return result; + }; + + return { + resolve: { + alias: { + '@glimmer/compiler': packagePath('@glimmer/compiler'), + '@glimmer/constants': packagePath('@glimmer/constants'), + '@glimmer/debug': packagePath('@glimmer/debug'), + '@glimmer/debug-util': packagePath('@glimmer/debug-util'), + '@glimmer/destroyable': packagePath('@glimmer/destroyable'), + '@glimmer/encoder': packagePath('@glimmer/encoder'), + '@glimmer/global-context': packagePath('@glimmer/global-context'), + '@glimmer/interfaces': packagePath('@glimmer/interfaces'), + '@glimmer/manager': packagePath('@glimmer/manager'), + '@glimmer/node': packagePath('@glimmer/node'), + '@glimmer/opcode-compiler': packagePath('@glimmer/opcode-compiler'), + '@glimmer/owner': packagePath('@glimmer/owner'), + '@glimmer/program': packagePath('@glimmer/program'), + '@glimmer/reference': packagePath('@glimmer/reference'), + '@glimmer/runtime': packagePath('@glimmer/runtime'), + '@glimmer/syntax': packagePath('@glimmer/syntax'), + '@glimmer/validator': packagePath('@glimmer/validator'), + '@glimmer/util': packagePath('@glimmer/util'), + '@glimmer/vm': packagePath('@glimmer/vm'), + '@glimmer/wire-format': packagePath('@glimmer/wire-format'), + }, }, - }, + }; }); diff --git a/repo-metadata/metadata.json b/repo-metadata/metadata.json index d20a87fef..43ff66285 100644 --- a/repo-metadata/metadata.json +++ b/repo-metadata/metadata.json @@ -138,12 +138,14 @@ { "root": "packages/@glimmer-workspace/jsbin", "name": "@glimmer-workspace/js-bin", + "version": "0.92.0", "type": "module", "private": true, "repo-meta": { "built": false }, "entryPoints": { + "./dist/assets/index-Dqd22NCS.js": [[["default"], "./dist/assets/index-Dqd22NCS.js"]], "./package.json": [[["default"], "./package.json"]] } }, From 844f30a0febe93a0b9ae7cc1ff6084bd1356e3e6 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 11:57:34 -0400 Subject: [PATCH 8/9] We don't need the ArgsProxy --- packages/@glimmer-workspace/jsbin/index.html | 47 +------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index d74ca7d7e..bf57db98e 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -24,58 +24,13 @@ import { preprocess, getTemplateLocals } from "@glimmer/syntax"; import setGlobalContext from "@glimmer/global-context"; import { createConstRef, valueForRef } from "@glimmer/reference"; - import { EMPTY_ARGS } from "@glimmer/runtime"; - - class ArgsProxy { - isExtensible() { - return false; - } - - ownKeys(target) { - return Object.keys(target); - } - - getOwnPropertyDescriptor(target, p) { - let desc; - if (typeof p === "string" && p in target) { - const value = valueForRef(target[p]); - desc = { - enumerable: true, - configurable: false, - writable: false, - value, - }; - } - return desc; - } - - has(target, p) { - return typeof p === "string" ? p in target : false; - } - - get(target, p) { - if (typeof p === "string" && p in target) { - return valueForRef(target[p]); - } - - return; - } - - set() { - return false; - } - } - - function argsProxy(args) { - return new Proxy(args.named, new ArgsProxy()); - } /** This repo has no component managers */ class BasicComponentManager { create(_owner, Component, args) { - const instance = new Component(argsProxy(args === null ? EMPTY_ARGS : args.capture())); + const instance = new Component(args.capture()); const self = createConstRef(instance, "this"); return { instance, self }; } From 7188f4449e8f0b453ed64dacf4756f97be6bc1cf Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 25 Apr 2025 13:17:37 -0400 Subject: [PATCH 9/9] Add comments --- packages/@glimmer-workspace/jsbin/index.html | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/@glimmer-workspace/jsbin/index.html b/packages/@glimmer-workspace/jsbin/index.html index bf57db98e..15a6c86e1 100644 --- a/packages/@glimmer-workspace/jsbin/index.html +++ b/packages/@glimmer-workspace/jsbin/index.html @@ -96,16 +96,29 @@ let revalidateScheduled = false; + /** + * The Global Context provides some core swappable utilities, feature flag configuration, and some hooks for some of the Render Phases. + * This is required to be configured, but could be entirely unneeded in modern code. + * + * + * This feels like it could have been designed to try to allow for different reactivity systems over time. + * But we don't need those use cases anymore. + * Additionally, we can configure the render phases in scheduleRevalidate + * it is *required* to do this, else updates to the DOM do not occur + */ setGlobalContext({ scheduleRevalidate() { if (!revalidateScheduled) { Promise.resolve() .then(() => { const { env } = result; + console.log("env.begin"); env.begin(); + console.log("env.rerender"); result.rerender(); revalidateScheduled = false; env.commit(); + console.log("env.commit"); }) .catch((e) => console.error(e)); } @@ -193,14 +206,23 @@ }; } + /** + * With the component manager we've configured, we don't need a super class + * but also, we don't interact with any args (this.args doesn't exist). + */ class Counter { _count = 0; + /** + * This is a simplified version of @tracked + */ get count() { + console.log("read: count"); consumeTag(tagFor(this, "_count")); return this._count; } set count(value) { + console.log("set: count"); this._count = value; dirtyTagFor(this, "_count"); } @@ -214,7 +236,7 @@ createTemplate( `

You have clicked the button {{this.count}} times.

- `, + `, { on }, ), this, @@ -245,6 +267,11 @@ return templateFactory(templateBlock); } + /** + * Main entrypoint for the demo. + * This configures a whole bunch of legacy features that shouldn't be needed, especially in + strict mode. + */ function render() { const element = document.body; const sharedArtifacts = artifacts(); @@ -274,6 +301,7 @@ const cursor = { element, nextSibling: null }; const treeBuilder = NewTreeBuilder.forInitialRender(env, cursor); + console.log("renderSync"); const result = renderSync(env, renderComponent(context, treeBuilder, {}, Counter, {})); registerResult(result);