From 6ea585e3d7330ab652cb11f104e875654b512684 Mon Sep 17 00:00:00 2001 From: Rex Lorenzo Date: Fri, 17 Jul 2026 13:52:25 -0700 Subject: [PATCH 1/2] Add Gea (geajs.com) framework to the benchmark suite Implements the shared weather app in Gea, a compiler-first reactive UI framework, and wires it into the existing test/lint/build tooling. - apps/geajs: weather app using @geajs/core with a proxy-based Store, getter-derived computed values, and class/function JSX components compiled by @geajs/vite-plugin (Vite 8) - frameworks.json: register geajs with build, test, and meta config - tests/config: add playwright-geajs.config.js and base config entry - package.json: add dev/build/test/lint scripts for geajs - eslint.config.mjs: ignore JSX-only component references in apps/geajs - .github/docs/apps.md: add Gea (and the previously missing Lume.js) to the framework list and correct the count to 14 Behavior matches the reference implementations (react/vue/svelte/preact/ solid), including reading pressure from pressure_msl and single-item forecast expansion with scroll-into-view. The page uses the shared soft background like the majority of apps rather than painting the app container near-white. Full Playwright suite passes locally (22/22). Co-Authored-By: Claude --- .github/docs/apps.md | 3 +- apps/geajs/README.md | 65 + apps/geajs/index.html | 17 + apps/geajs/package-lock.json | 1147 ++++++++++++++++++ apps/geajs/package.json | 22 + apps/geajs/src/app.jsx | 32 + apps/geajs/src/components/CurrentWeather.jsx | 50 + apps/geajs/src/components/ErrorState.jsx | 13 + apps/geajs/src/components/Forecast.jsx | 20 + apps/geajs/src/components/ForecastItem.jsx | 67 + apps/geajs/src/components/LoadingState.jsx | 8 + apps/geajs/src/components/SearchForm.jsx | 39 + apps/geajs/src/components/WeatherContent.jsx | 16 + apps/geajs/src/components/WeatherDisplay.jsx | 17 + apps/geajs/src/main.js | 8 + apps/geajs/src/services/weather-service.js | 165 +++ apps/geajs/src/utils/weather-utils.js | 128 ++ apps/geajs/src/weather-store.js | 233 ++++ apps/geajs/styles.css | 47 + apps/geajs/vite.config.js | 19 + eslint.config.mjs | 12 + frameworks.json | 28 + package.json | 12 +- tests/config/playwright-geajs.config.js | 3 + tests/config/playwright.config.base.js | 7 + 25 files changed, 2173 insertions(+), 5 deletions(-) create mode 100644 apps/geajs/README.md create mode 100644 apps/geajs/index.html create mode 100644 apps/geajs/package-lock.json create mode 100644 apps/geajs/package.json create mode 100644 apps/geajs/src/app.jsx create mode 100644 apps/geajs/src/components/CurrentWeather.jsx create mode 100644 apps/geajs/src/components/ErrorState.jsx create mode 100644 apps/geajs/src/components/Forecast.jsx create mode 100644 apps/geajs/src/components/ForecastItem.jsx create mode 100644 apps/geajs/src/components/LoadingState.jsx create mode 100644 apps/geajs/src/components/SearchForm.jsx create mode 100644 apps/geajs/src/components/WeatherContent.jsx create mode 100644 apps/geajs/src/components/WeatherDisplay.jsx create mode 100644 apps/geajs/src/main.js create mode 100644 apps/geajs/src/services/weather-service.js create mode 100644 apps/geajs/src/utils/weather-utils.js create mode 100644 apps/geajs/src/weather-store.js create mode 100644 apps/geajs/styles.css create mode 100644 apps/geajs/vite.config.js create mode 100644 tests/config/playwright-geajs.config.js diff --git a/.github/docs/apps.md b/.github/docs/apps.md index 8f93a467f..7dc35e72f 100644 --- a/.github/docs/apps.md +++ b/.github/docs/apps.md @@ -1,6 +1,6 @@ # Framework Applications -This project contains the same weather application built using 14 different JavaScript frameworks. Each implementation provides identical functionality but uses the specific patterns and approaches of its framework. +This project contains the same weather application built using 15 different JavaScript frameworks. Each implementation provides identical functionality but uses the specific patterns and approaches of its framework. ## Available Frameworks @@ -19,6 +19,7 @@ The project includes implementations for: **VanJS** - Ultra-small vanilla framework **Lume.js** - Minimal reactive state library with no build step **Astro** - Static-first with zero JavaScript by default and opt-in islands +**Gea** - Compiler-first reactive framework with surgical DOM updates **Vanilla** - Pure JavaScript without any framework Each app lives in its own directory under `apps/{framework}/` and can be developed, built, and tested independently. diff --git a/apps/geajs/README.md b/apps/geajs/README.md new file mode 100644 index 000000000..cfe68bdaa --- /dev/null +++ b/apps/geajs/README.md @@ -0,0 +1,65 @@ +# Weather App — Gea + +A weather application built with [Gea](https://geajs.com/) — a compiler-first reactive UI framework that compiles JSX into surgical DOM updates at build time (a hello-world app ships ~121 B of brotli JavaScript). + +## Usage + +```bash +# Install dependencies +npm install + +# Dev server (Vite + @geajs/vite-plugin) +npm run dev + +# Production build +npm run build + +# Run tests (from repo root) +npm run test:geajs + +# Lint (from repo root) +npm run lint:geajs +``` + +## Implementation + +Gea doesn't use signals, hooks, dependency arrays, or a virtual DOM. You write ordinary JavaScript — classes with state and methods, getters for computed values — and the Vite plugin (`@geajs/vite-plugin`) analyzes the JSX at build time, works out which DOM nodes depend on which state paths, and generates the reactive wiring. At runtime only the affected nodes are patched. + +The implementation uses: + +- **`Store`** — [`weather-store.js`](src/weather-store.js) is a singleton class extending `Store`. Its fields (`searchQuery`, `isLoading`, `hasError`, `weatherData`, `activeForecastIndex`) are made reactive through a deep Proxy; mutations are plain assignments like `this.isLoading = true`. +- **Getters as computed values** — derived state such as `showContent`, `locationLabel`, `currentTemperature`, and `forecastDays` are ordinary JavaScript getters on the store. The compiler tracks which state paths they read and re-evaluates the dependent DOM bindings when those paths change. +- **Class components** — each UI piece ([`SearchForm`](src/components/SearchForm.jsx), [`CurrentWeather`](src/components/CurrentWeather.jsx), [`ForecastItem`](src/components/ForecastItem.jsx), …) extends `Component` and returns JSX from `template()`. JSX uses HTML-style attributes (`class`, `for`) and native-style event bindings (`click={...}`, `input={...}`, `submit={...}`) wired through document-level event delegation. +- **Function components** — stateless UI like [`LoadingState`](src/components/LoadingState.jsx) is a plain function; the compiler converts it to a class component at build time. +- **Conditional rendering** — `{condition && }` in [`WeatherDisplay`](src/components/WeatherDisplay.jsx) compiles into `