Skip to content

Commit 60ae054

Browse files
chore(deps): modernize toolchain (Vite 8, TS 6, ESLint 10, Hono) + cut 14 direct deps (−139 packages)
Toolchain to the latest working majors: - Vite 6→8 (Rolldown/Oxc), @vitejs/plugin-react 4→6, vite-plugin-dts 4→5 (rollupTypes→bundleTypes via @microsoft/api-extractor), TypeScript 5.7→6.0. - ESLint 9→10. eslint-plugin-react has no v10 release (it calls the removed context.getFilename()), so React linting moves to @eslint-react/eslint-plugin (flat-config, v10-native); eslint-plugin-react-hooks stays the hooks authority and @eslint-react's overlapping hook rules are disabled so each is reported once. Server runtime majors: - zod 3→4, redis 5→6 (pinned RESP2 to preserve the raw sendCommand reply shapes this code parses), pino 9→10, dotenv 16→17, ulid 2→3. - Express 5 → Hono 4 + @hono/node-server (both zero-runtime-dep), dropping express/cors/cookie/pino-http and ~18 transitives. Routes, status codes, bodies, headers, owner-cookie HMAC, CORS policy, zod error envelopes and the yjs WS relay are preserved; buildApp still returns an unstarted http.Server. Cuts: - uuid → an embed-safe crypto.getRandomValues RFC-4122 v4 (works in any context, unlike crypto.randomUUID which needs a secure context an embed can't assume). - cmdk + the unused command component; @ionic/react → a 45-line vendored platform.ts (its Stencil runtime was in the initial bundle for UA checks only) — webapp initial bundle nearly halved. - packages/ui: drop dead @vitest/coverage-v8 (no coverage config/script there). ~50 deps bumped to latest (modulo the repo's >24h minimumReleaseAge). Verified: pnpm install --frozen-lockfile; pnpm lint 0 errors; pnpm knip clean; builds (library single-entry incl. rolled .d.ts, webapp, server, vscode, ui types + stories typecheck); size-limit within budget (webapp initial 34.65/35 kB); tests library 1222 / webapp 256 / server 150 (Docker) / ui 37. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 91d36ad commit 60ae054

68 files changed

Lines changed: 3217 additions & 4944 deletions

Some content is hidden

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

.github/workflows/pr-health-checks.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,14 @@ jobs:
213213
# Browser-specific key: the chromium and firefox jobs share this cache
214214
# path but install different browsers, so they must not share a key
215215
# (a firefox-only cache would make this job skip its chromium install).
216-
key: playwright-chromium-${{ runner.os }}-v1.59.1-${{ hashFiles('standalone/webapp/package.json') }}
216+
key: playwright-chromium-${{ runner.os }}-v1.61.1-${{ hashFiles('standalone/webapp/package.json') }}
217217

218218
- name: Install Playwright browsers
219219
if: steps.playwright-cache.outputs.cache-hit != 'true'
220220
# Invoke @playwright/test's own CLI (not `pnpm exec playwright`): the
221-
# webapp also has `playwright@1.61` for Storybook's vitest browser runner,
222-
# so the bare `playwright` bin resolves to 1.61 and installs browsers the
223-
# 1.59.1 test runner can't find. cli.js installs 1.59.1's browsers.
221+
# webapp also has the `playwright` package (Storybook's vitest browser
222+
# runner), and both ship a `playwright` bin, so the bare bin can resolve
223+
# to the wrong package. cli.js pins the install to @playwright/test.
224224
run: pnpm --filter @tumaet/webapp exec node node_modules/@playwright/test/cli.js install chromium
225225

226226
# Shared with perf-firefox-tests; the dpkg-lock hang it guards is
@@ -232,8 +232,8 @@ jobs:
232232

233233
- name: Run E2E tests
234234
# Use the test:e2e script (node …/@playwright/test/cli.js): running via
235-
# `pnpm exec playwright test` picks up the 1.61 runner against 1.59.1 test
236-
# files → "did not expect test.describe()".
235+
# `pnpm exec playwright test` can pick up the `playwright` package's CLI
236+
# (bin collision) instead of @playwright/test's test runner.
237237
run: pnpm --filter @tumaet/webapp run test:e2e
238238

239239
# No chromium document-growth budget: the metric is engine-independent and
@@ -286,12 +286,13 @@ jobs:
286286
path: ~/.cache/ms-playwright
287287
# Firefox-specific key — must differ from the chromium jobs' key (same
288288
# cache path, different browser) so neither poisons the other's cache.
289-
key: playwright-firefox-${{ runner.os }}-v1.59.1-${{ hashFiles('standalone/webapp/package.json') }}
289+
key: playwright-firefox-${{ runner.os }}-v1.61.1-${{ hashFiles('standalone/webapp/package.json') }}
290290

291291
- name: Install Playwright Firefox
292292
if: steps.playwright-cache.outputs.cache-hit != 'true'
293-
# @playwright/test's own CLI, so Firefox matches the 1.59.1 test runner
294-
# (see the e2e job's install step for why `pnpm exec playwright` is wrong).
293+
# @playwright/test's own CLI, so the install targets the test runner's
294+
# package — both packages ship a `playwright` bin (see the e2e job's
295+
# install step for why `pnpm exec playwright` is wrong).
295296
run: pnpm --filter @tumaet/webapp exec node node_modules/@playwright/test/cli.js install firefox
296297

297298
# Shared with e2e-tests; the dpkg-lock hang it guards is documented in
@@ -393,7 +394,7 @@ jobs:
393394
runs-on: ubuntu-latest
394395
timeout-minutes: 30
395396
container:
396-
image: mcr.microsoft.com/playwright:v1.59.1-noble
397+
image: mcr.microsoft.com/playwright:v1.61.1-noble
397398
steps:
398399
- name: Checkout repository
399400
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

.github/workflows/update-visual-baselines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
runs-on: ubuntu-latest
3434
timeout-minutes: 30
3535
container:
36-
image: mcr.microsoft.com/playwright:v1.59.1-noble
36+
image: mcr.microsoft.com/playwright:v1.61.1-noble
3737
steps:
3838
- name: Checkout target branch
3939
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
"@docusaurus/faster": "3.10.1",
1919
"@docusaurus/preset-classic": "3.10.1",
2020
"@docusaurus/theme-mermaid": "3.10.1",
21-
"@easyops-cn/docusaurus-search-local": "0.55.1",
21+
"@easyops-cn/docusaurus-search-local": "0.55.2",
2222
"@mdx-js/react": "3.1.1",
23-
"@mermaid-js/layout-elk": "0.2.1",
23+
"@mermaid-js/layout-elk": "0.2.2",
2424
"@tumaet/apollon": "workspace:*",
2525
"@xyflow/react": "catalog:",
2626
"clsx": "catalog:",

docs/tsconfig.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
{
22
"extends": "@docusaurus/tsconfig",
33
"compilerOptions": {
4-
"baseUrl": ".",
5-
"jsx": "react-jsx"
4+
"jsx": "react-jsx",
5+
// @docusaurus/tsconfig (the external base) still sets `baseUrl`, which TS 6.0
6+
// flags as a hard deprecation error (TS5101). We can't edit that base, so opt
7+
// into the TS-sanctioned escape hatch until Docusaurus drops baseUrl.
8+
"ignoreDeprecations": "6.0"
69
},
710
"include": ["src/", "docusaurus.config.ts", "sidebars.*.ts"]
811
}

knip.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"tests/**/*.test.{ts,tsx}"
1616
],
1717
"project": ["src/**/*.{ts,tsx}", "tests/**/*.{ts,tsx}"],
18-
"ignoreDependencies": ["@tailwindcss/vite", "@vitest/coverage-v8"]
18+
"ignoreDependencies": ["@tailwindcss/vite"]
1919
},
2020
"standalone/webapp": {
2121
"entry": [
@@ -36,13 +36,11 @@
3636
]
3737
},
3838
"standalone/server": {
39-
"entry": ["src/workers/*.{ts,mjs}"],
40-
"ignoreDependencies": ["@types/express-serve-static-core"]
39+
"entry": ["src/workers/*.{ts,mjs}"]
4140
},
4241
"vscode-extension": {
4342
"entry": ["webview-vite.config.ts"],
44-
"ignoreBinaries": ["vsce"],
45-
"ignoreDependencies": ["babel-plugin-react-compiler"]
43+
"ignoreBinaries": ["vsce"]
4644
},
4745
"vscode-extension/editor": {
4846
"entry": ["src/index.tsx"],

library/eslint.config.mjs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import globals from "globals"
33
import pluginJs from "@eslint/js"
44
import tseslint from "typescript-eslint"
5-
import reactPlugin from "eslint-plugin-react"
5+
import eslintReact from "@eslint-react/eslint-plugin"
66
import reactHooks from "eslint-plugin-react-hooks"
77

88
/** @type {import('eslint').Linter.Config[]} */
@@ -12,19 +12,28 @@ export default [
1212
{ languageOptions: { globals: globals.browser } },
1313
pluginJs.configs.recommended,
1414
...tseslint.configs.recommended,
15-
reactPlugin.configs.flat.recommended,
16-
reactPlugin.configs.flat["jsx-runtime"],
15+
// recommended-typescript disables the prop-types rules TypeScript already enforces.
16+
eslintReact.configs["recommended-typescript"],
1717
{
18-
settings: { react: { version: "detect" } },
1918
plugins: { "react-hooks": reactHooks },
20-
// eslint-plugin-react-hooks v7 flat preset — bundles the React Compiler
21-
// lint rules (preserve-manual-memoization, refs, purity, immutability,
22-
// set-state-in-effect, …). exhaustive-deps stays at warn: the only
19+
// eslint-plugin-react-hooks is the hooks / React-Compiler authority here
20+
// (preserve-manual-memoization, refs, purity, immutability,
21+
// set-state-in-effect, …). @eslint-react ships its own copies of those hook
22+
// rules in `recommended-typescript`; turn them off so each concern is
23+
// reported once, by react-hooks. exhaustive-deps stays at warn: the only
2324
// remaining exhaustive-deps suppression is Apollon.tsx's mount-once lifecycle.
2425
rules: {
2526
...reactHooks.configs.flat.recommended.rules,
27+
"@eslint-react/error-boundaries": "off",
28+
"@eslint-react/exhaustive-deps": "off",
29+
"@eslint-react/purity": "off",
30+
"@eslint-react/rules-of-hooks": "off",
31+
"@eslint-react/set-state-in-effect": "off",
32+
"@eslint-react/set-state-in-render": "off",
33+
"@eslint-react/static-components": "off",
34+
"@eslint-react/unsupported-syntax": "off",
35+
"@eslint-react/use-memo": "off",
2636
"react-hooks/exhaustive-deps": "warn",
27-
"react/prop-types": "off",
2837
"no-console": "error",
2938
// Allow intentionally-unused `_`-prefixed bindings.
3039
"@typescript-eslint/no-unused-vars": [

library/lib/components/popovers/edgePopovers/ActivityDiagramEdgeEditPopover.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const ActivityDiagramEdgeEditPopover: React.FC<PopoverProps> = ({
3232
sideElements={[
3333
handleSwap && (
3434
<IconButton
35+
key="swap-source-target"
3536
ariaLabel="Swap source and target"
3637
tooltip="Swap source and target"
3738
onClick={handleSwap}

library/lib/components/popovers/edgePopovers/BPMNDiagramEdgeEditPopover.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const BPMNDiagramEdgeEditPopover: React.FC<PopoverProps> = ({
4747
sideElements={[
4848
handleSwap && (
4949
<IconButton
50+
key="swap-source-target"
5051
ariaLabel="Swap source and target"
5152
tooltip="Swap source and target"
5253
onClick={handleSwap}

library/lib/components/popovers/edgePopovers/ClassDiagramEdgeEditPopover.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const EdgeEditPopover: React.FC<PopoverProps> = ({ elementId }) => {
5555
sideElements={[
5656
handleSwap && (
5757
<IconButton
58+
key="swap-source-target"
5859
ariaLabel="Swap source and target"
5960
tooltip="Swap source and target"
6061
onClick={handleSwap}

library/lib/components/popovers/edgePopovers/ComponentDiagramEdgeEditPopover.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const ComponentEdgeEditPopover: React.FC<PopoverProps> = ({
4646
sideElements={[
4747
handleSwap && (
4848
<IconButton
49+
key="swap-source-target"
4950
ariaLabel="Swap source and target"
5051
tooltip="Swap source and target"
5152
onClick={handleSwap}

0 commit comments

Comments
 (0)