Skip to content

Commit 2add981

Browse files
authored
refactor(site): migrate islands from Lit to React (#149)
Replace the site's Lit islands with typed React components + SCSS Modules; swap Astro's Lit integration for @astrojs/react and Monaco for @monaco-editor/react (browser-only editor loading). Adds React-focused ESLint coverage for site/src. Scoped to the migration: only the two React ESLint plugins are added, no engine-tooling bumps.
1 parent e58f52c commit 2add981

81 files changed

Lines changed: 4476 additions & 5438 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

eslint.config.ts

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { coreInternalDirs, createImportBoundaries } from '@codexo/exojs-config/eslint';
2+
import eslintReact from '@eslint-react/eslint-plugin';
23
import js from '@eslint/js';
34
import { defineConfig } from 'eslint/config';
45
import prettier from 'eslint-config-prettier';
6+
import reactHooks from 'eslint-plugin-react-hooks';
57
import security from 'eslint-plugin-security';
68
import simpleImportSort from 'eslint-plugin-simple-import-sort';
79
import unicorn from 'eslint-plugin-unicorn';
@@ -11,17 +13,7 @@ import tseslint from 'typescript-eslint';
1113

1214
export default defineConfig([
1315
{
14-
ignores: [
15-
'dist/**',
16-
'node_modules/**',
17-
'src/vendor/**',
18-
'site/dist/**',
19-
'site/node_modules/**',
20-
'site/public/vendor/**',
21-
'site/src/**',
22-
'coverage/**',
23-
'**/*.min.*',
24-
],
16+
ignores: ['dist/**', 'node_modules/**', 'src/vendor/**', 'site/dist/**', 'site/node_modules/**', 'site/public/vendor/**', 'coverage/**', '**/*.min.*'],
2517
},
2618

2719
// Base JavaScript recommendations
@@ -590,6 +582,110 @@ export default defineConfig([
590582
},
591583
},
592584

585+
// Site React components. Astro files are type-checked by `astro check`; this
586+
// block covers the TypeScript/TSX islands that ship browser interactivity.
587+
{
588+
files: ['site/src/**/*.{ts,tsx}'],
589+
languageOptions: {
590+
ecmaVersion: 'latest',
591+
sourceType: 'module',
592+
parserOptions: {
593+
projectService: true,
594+
tsconfigRootDir: import.meta.dirname,
595+
},
596+
globals: {
597+
...globals.browser,
598+
...globals.es2024,
599+
},
600+
},
601+
plugins: {
602+
'@eslint-react': eslintReact,
603+
'react-hooks': reactHooks,
604+
'simple-import-sort': simpleImportSort,
605+
'unused-imports': unusedImports,
606+
},
607+
rules: {
608+
...eslintReact.configs['recommended-typescript'].rules,
609+
...eslintReact.configs['disable-conflict-eslint-plugin-react-hooks'].rules,
610+
...reactHooks.configs.recommended.rules,
611+
612+
'simple-import-sort/imports': 'error',
613+
'simple-import-sort/exports': 'error',
614+
'unused-imports/no-unused-imports': 'error',
615+
'unused-imports/no-unused-vars': [
616+
'warn',
617+
{
618+
argsIgnorePattern: '^_',
619+
caughtErrorsIgnorePattern: '^_',
620+
destructuredArrayIgnorePattern: '^_',
621+
varsIgnorePattern: '^_',
622+
ignoreRestSiblings: true,
623+
},
624+
],
625+
626+
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' }],
627+
'@typescript-eslint/array-type': 'off',
628+
'@typescript-eslint/consistent-indexed-object-style': 'off',
629+
'@typescript-eslint/consistent-type-definitions': 'off',
630+
'@typescript-eslint/no-floating-promises': 'error',
631+
'@typescript-eslint/no-misused-promises': [
632+
'error',
633+
{
634+
checksVoidReturn: {
635+
arguments: false,
636+
attributes: false,
637+
},
638+
},
639+
],
640+
'@typescript-eslint/no-unsafe-argument': 'off',
641+
'@typescript-eslint/no-unsafe-assignment': 'off',
642+
'@typescript-eslint/no-unsafe-call': 'off',
643+
'@typescript-eslint/no-unsafe-member-access': 'off',
644+
'@typescript-eslint/no-unsafe-return': 'off',
645+
'@typescript-eslint/no-unused-vars': 'off',
646+
'@typescript-eslint/prefer-regexp-exec': 'off',
647+
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
648+
'@typescript-eslint/prefer-optional-chain': 'warn',
649+
'@typescript-eslint/restrict-template-expressions': [
650+
'error',
651+
{
652+
allowNumber: true,
653+
allowBoolean: false,
654+
allowAny: false,
655+
allowNullish: false,
656+
allowRegExp: false,
657+
},
658+
],
659+
// Disabled for site/src to match the engine: `strict-boolean-expressions`
660+
// is turned off across every practical src/ directory (core, input, math,
661+
// rendering, audio, resources, …). The site's URL/version/runtime helpers
662+
// are the same class of nullable-string code, so holding only site code to
663+
// it would be an inconsistent double standard.
664+
'@typescript-eslint/strict-boolean-expressions': 'off',
665+
'@typescript-eslint/unbound-method': 'off',
666+
667+
'@eslint-react/dom-no-unsafe-iframe-sandbox': 'error',
668+
'@eslint-react/no-array-index-key': 'warn',
669+
'@eslint-react/no-nested-component-definitions': 'error',
670+
'@eslint-react/no-unstable-default-props': 'error',
671+
'react-hooks/exhaustive-deps': 'warn',
672+
'react-hooks/immutability': 'warn',
673+
'react-hooks/preserve-manual-memoization': 'warn',
674+
'react-hooks/set-state-in-effect': 'warn',
675+
676+
curly: 'error',
677+
eqeqeq: ['error', 'always'],
678+
// Allow console.error/console.warn for intentional diagnostics (e.g. the
679+
// fetch/parse error logging in request-manager.ts); only console.log/debug warn.
680+
'no-console': ['warn', { allow: ['warn', 'error'] }],
681+
'no-nested-ternary': 'warn',
682+
'object-shorthand': 'error',
683+
'prefer-object-spread': 'error',
684+
'prefer-template': 'error',
685+
radix: 'error',
686+
},
687+
},
688+
593689
// ---------------------------------------------------------------------------
594690
// Per-subsystem overrides for src/. Scoped narrowly because these directories
595691
// either have hot-path lifecycle invariants, browser-API variance, or typed-

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@
8787
"typecheck": "tsc --noEmit",
8888
"typecheck:examples": "tsc --noEmit -p tsconfig.examples.json",
8989
"typecheck:guides": "tsx scripts/extract-guide-snippets.ts && tsc --noEmit -p tsconfig.guides.json",
90-
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\" \"examples/**/*.js\"",
91-
"lint:fix": "eslint --fix \"src/**/*.ts\" \"test/**/*.ts\" \"examples/**/*.js\"",
90+
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\" \"examples/**/*.js\" \"site/src/**/*.{ts,tsx}\"",
91+
"lint:fix": "eslint --fix \"src/**/*.ts\" \"test/**/*.ts\" \"examples/**/*.js\" \"site/src/**/*.{ts,tsx}\"",
92+
"site:lint": "eslint \"site/src/**/*.{ts,tsx}\"",
9293
"lint:packages": "eslint \"packages/exojs-*/src/**/*.ts\" \"packages/exojs-*/test/**/*.ts\"",
9394
"lint:all": "pnpm lint && pnpm lint:packages",
9495
"lint:strict": "eslint --max-warnings=0 \"src/**/*.ts\"",
@@ -142,6 +143,7 @@
142143
},
143144
"devDependencies": {
144145
"@codexo/exojs-config": "workspace:*",
146+
"@eslint-react/eslint-plugin": "^5.9.0",
145147
"@eslint/js": "^10.0.1",
146148
"@rollup/plugin-node-resolve": "^16.0.3",
147149
"@rollup/plugin-replace": "^6.0.3",
@@ -155,6 +157,7 @@
155157
"@webgpu/types": "^0.1.69",
156158
"eslint": "~10.4.1",
157159
"eslint-config-prettier": "^10.1.8",
160+
"eslint-plugin-react-hooks": "^7.1.1",
158161
"eslint-plugin-security": "^4.0.0",
159162
"eslint-plugin-simple-import-sort": "^13.0.0",
160163
"eslint-plugin-unicorn": "^64.0.0",

0 commit comments

Comments
 (0)