From 7a3c88691bca7a85c15e38cdedd2c5756ab36b81 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Tue, 24 Mar 2026 21:14:34 +0100 Subject: [PATCH 1/2] feat(examples): add Arrow.js SSR example Todo app showcasing reactive state, components with props, keyed lists, computed filtering, watch effects, and SSR with client-side takeover. --- examples/vite-ssr-arrow/package.json | 20 ++ examples/vite-ssr-arrow/src/app.ts | 141 +++++++++ examples/vite-ssr-arrow/src/entry-client.ts | 5 + examples/vite-ssr-arrow/src/entry-server.ts | 41 +++ examples/vite-ssr-arrow/src/styles.css | 159 ++++++++++ examples/vite-ssr-arrow/tsconfig.json | 11 + examples/vite-ssr-arrow/vite.config.ts | 27 ++ pnpm-lock.yaml | 314 +++++++++++++++++++- 8 files changed, 713 insertions(+), 5 deletions(-) create mode 100644 examples/vite-ssr-arrow/package.json create mode 100644 examples/vite-ssr-arrow/src/app.ts create mode 100644 examples/vite-ssr-arrow/src/entry-client.ts create mode 100644 examples/vite-ssr-arrow/src/entry-server.ts create mode 100644 examples/vite-ssr-arrow/src/styles.css create mode 100644 examples/vite-ssr-arrow/tsconfig.json create mode 100644 examples/vite-ssr-arrow/vite.config.ts diff --git a/examples/vite-ssr-arrow/package.json b/examples/vite-ssr-arrow/package.json new file mode 100644 index 0000000000..8a4cc463d1 --- /dev/null +++ b/examples/vite-ssr-arrow/package.json @@ -0,0 +1,20 @@ +{ + "type": "module", + "scripts": { + "build": "vite build", + "preview": "vite preview", + "dev": "vite dev" + }, + "devDependencies": { + "@arrow-js/core": "latest", + "@arrow-js/framework": "latest", + "@arrow-js/hydrate": "latest", + "@arrow-js/ssr": "latest", + "nitro": "latest", + "vite": "latest" + }, + "TODO": [ + "@arrow-js/vite-plugin-arrow - investigate workspace alias plugin for external use", + "@arrow-js/hydrate - investigate hydration adoption (currently using client-side takeover)" + ] +} diff --git a/examples/vite-ssr-arrow/src/app.ts b/examples/vite-ssr-arrow/src/app.ts new file mode 100644 index 0000000000..68645e90d5 --- /dev/null +++ b/examples/vite-ssr-arrow/src/app.ts @@ -0,0 +1,141 @@ +import { html, reactive, component, watch } from "@arrow-js/core"; +import type { Props } from "@arrow-js/core"; + +type Todo = { id: number; text: string; done: boolean }; +type Filter = "all" | "active" | "done"; + +const TodoItem = component( + ( + props: Props<{ + todo: Todo; + onToggle: (id: number) => void; + onRemove: (id: number) => void; + }> + ) => { + return html` +
  • + + ${() => props.todo.text} + +
  • + `; + } +); + +const Filters = component((props: Props<{ filter: Filter }>) => { + const filters: Filter[] = ["all", "active", "done"]; + return html` + + `; +}); + +export function App() { + const state = reactive({ + todos: [ + { id: 1, text: "Learn reactive state", done: true }, + { id: 2, text: "Build a component", done: false }, + { id: 3, text: "Render a keyed list", done: false }, + ] as Todo[], + input: "", + filter: "all" as Filter, + nextId: 4, + }); + + const filtered = () => { + if (state.filter === "active") return state.todos.filter((t) => !t.done); + if (state.filter === "done") return state.todos.filter((t) => t.done); + return state.todos; + }; + + const remaining = () => state.todos.filter((t) => !t.done).length; + + const addTodo = () => { + const text = state.input.trim(); + if (!text) return; + state.todos.push({ id: state.nextId, text, done: false }); + state.nextId++; + state.input = ""; + }; + + const onToggle = (id: number) => { + const todo = state.todos.find((t) => t.id === id); + if (todo) todo.done = !todo.done; + }; + + const onRemove = (id: number) => { + const i = state.todos.findIndex((t) => t.id === id); + if (i >= 0) state.todos.splice(i, 1); + }; + + watch(() => { + console.log( + `[Arrow.js] ${remaining()} of ${state.todos.length} todos remaining` + ); + }); + + return html` +
    +

    Nitro + Arrow.js

    +

    A ~3KB reactive UI with SSR

    + +
    + + +
    + + ${Filters(state)} + + + +
    + ${() => remaining()} items left + +
    +
    + `; +} diff --git a/examples/vite-ssr-arrow/src/entry-client.ts b/examples/vite-ssr-arrow/src/entry-client.ts new file mode 100644 index 0000000000..84c3fa2b70 --- /dev/null +++ b/examples/vite-ssr-arrow/src/entry-client.ts @@ -0,0 +1,5 @@ +import { App } from "./app.ts"; + +const root = document.getElementById("app")!; +root.textContent = ""; +App()(root); diff --git a/examples/vite-ssr-arrow/src/entry-server.ts b/examples/vite-ssr-arrow/src/entry-server.ts new file mode 100644 index 0000000000..14070ca224 --- /dev/null +++ b/examples/vite-ssr-arrow/src/entry-server.ts @@ -0,0 +1,41 @@ +import "./styles.css"; +import { renderToString } from "@arrow-js/ssr"; +import { App } from "./app.ts"; + +import clientAssets from "./entry-client?assets=client"; +import serverAssets from "./entry-server?assets=ssr"; + +export default { + async fetch(_req: Request) { + const assets = clientAssets.merge(serverAssets); + const view = App(); + const result = await renderToString(view); + + const head = [ + ``, + ...assets.css.map( + (attr: Record) => + `` + ), + ...assets.js.map( + (attr: Record) => + `` + ), + ``, + ].join("\n "); + + const html = ` + + + ${head} + + +
    ${result.html}
    + +`; + + return new Response(html, { + headers: { "Content-Type": "text/html;charset=utf-8" }, + }); + }, +}; diff --git a/examples/vite-ssr-arrow/src/styles.css b/examples/vite-ssr-arrow/src/styles.css new file mode 100644 index 0000000000..4abfd3cf0b --- /dev/null +++ b/examples/vite-ssr-arrow/src/styles.css @@ -0,0 +1,159 @@ +* { + box-sizing: border-box; + margin: 0; +} + +body { + font-family: system-ui, sans-serif; + background: #1a1a2e; + color: #eee; + display: flex; + justify-content: center; + padding: 2rem 1rem; +} + +.app { + max-width: 480px; + width: 100%; +} + +h1 { + font-size: 1.8rem; + color: #e2b340; +} + +.subtitle { + color: #888; + margin-bottom: 1.5rem; +} + +.input-row { + display: flex; + gap: 0.5rem; + margin-bottom: 1rem; +} + +.input-row input { + flex: 1; + padding: 0.6rem 0.8rem; + border: 1px solid #333; + border-radius: 6px; + background: #16213e; + color: #eee; + font-size: 0.95rem; +} + +.input-row input:focus { + outline: none; + border-color: #e2b340; +} + +button { + cursor: pointer; + border: none; + border-radius: 6px; + font-size: 0.85rem; + padding: 0.5rem 0.8rem; + background: #16213e; + color: #ccc; + transition: background 0.15s; +} + +button:hover { + background: #1a2744; +} + +button.add { + background: #e2b340; + color: #1a1a2e; + font-weight: 600; +} + +button.add:hover { + background: #f0c850; +} + +.filters { + display: flex; + gap: 0.4rem; + margin-bottom: 1rem; +} + +.filters button.active { + background: #e2b340; + color: #1a1a2e; +} + +.todo-list { + list-style: none; + padding: 0; +} + +.todo { + display: flex; + align-items: center; + gap: 0.6rem; + padding: 0.6rem 0; + border-bottom: 1px solid #222; +} + +.todo.done span { + text-decoration: line-through; + opacity: 0.5; +} + +.todo span { + flex: 1; +} + +.todo .toggle { + width: 28px; + height: 28px; + border-radius: 50%; + border: 2px solid #444; + background: transparent; + color: #4caf50; + font-size: 1rem; + display: flex; + align-items: center; + justify-content: center; + padding: 0; +} + +.todo.done .toggle { + border-color: #4caf50; +} + +.todo .remove { + background: transparent; + color: #e74c3c; + font-size: 1.1rem; + opacity: 0; + transition: opacity 0.15s; + padding: 0.2rem 0.5rem; +} + +.todo:hover .remove { + opacity: 1; +} + +.footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 1rem; + padding-top: 0.8rem; + border-top: 1px solid #222; + color: #888; + font-size: 0.85rem; +} + +button.clear { + color: #e74c3c; + background: transparent; + font-size: 0.8rem; +} + +button.clear:hover { + background: rgba(231, 76, 60, 0.1); +} diff --git a/examples/vite-ssr-arrow/tsconfig.json b/examples/vite-ssr-arrow/tsconfig.json new file mode 100644 index 0000000000..19fb5a7a25 --- /dev/null +++ b/examples/vite-ssr-arrow/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/examples/vite-ssr-arrow/vite.config.ts b/examples/vite-ssr-arrow/vite.config.ts new file mode 100644 index 0000000000..748ba26c0a --- /dev/null +++ b/examples/vite-ssr-arrow/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "vite"; +import { nitro } from "nitro/vite"; + +export default defineConfig({ + plugins: [nitro()], + environments: { + client: { + build: { rollupOptions: { input: "./src/entry-client.ts" } }, + }, + }, + optimizeDeps: { + exclude: [ + "@arrow-js/core", + "@arrow-js/framework", + "@arrow-js/ssr", + "@arrow-js/hydrate", + ], + }, + ssr: { + noExternal: [ + "@arrow-js/core", + "@arrow-js/framework", + "@arrow-js/ssr", + "@arrow-js/hydrate", + ], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe509f626b..4b06c5c710 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,7 +132,7 @@ importers: version: 7.0.0-dev.20260323.1 '@vitest/coverage-v8': specifier: ^4.1.1 - version: 4.1.1(vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))) + version: 4.1.1(vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(jsdom@26.1.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))) automd: specifier: ^0.4.3 version: 0.4.3(magicast@0.5.2) @@ -309,7 +309,7 @@ importers: version: vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.3) vitest: specifier: ^4.1.1 - version: 4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(jsdom@26.1.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) wrangler: specifier: ^4.76.0 version: 4.76.0(@cloudflare/workers-types@4.20260317.1) @@ -510,6 +510,27 @@ importers: specifier: latest version: 8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) + examples/vite-ssr-arrow: + devDependencies: + '@arrow-js/core': + specifier: latest + version: 1.0.0 + '@arrow-js/framework': + specifier: latest + version: 1.0.0 + '@arrow-js/hydrate': + specifier: latest + version: 1.0.0 + '@arrow-js/ssr': + specifier: latest + version: 1.0.0 + nitro: + specifier: link:../.. + version: link:../.. + vite: + specifier: latest + version: 8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) + examples/vite-ssr-html: devDependencies: '@tailwindcss/vite': @@ -778,6 +799,22 @@ packages: peerDependencies: vue: ^3.3.4 + '@arrow-js/core@1.0.0': + resolution: {integrity: sha512-/JnQINO4f79yPT+GNOt8p7TI96jCAfSnGPyYtEUNPlNZOiZTyTq1Mpzwl6pdbbARg36G7/4VLSNAEQ9EnXx0dQ==} + engines: {node: '>=20.19.0 || >=22.12.0'} + + '@arrow-js/framework@1.0.0': + resolution: {integrity: sha512-SIC92g959BdgAmE97XHtSo2E0ocsXGtuWFlhf+fKr5LV1FQrcIv89moEEx3UHl5DA9R+6nGZJu3nNpqGM5BBCA==} + + '@arrow-js/hydrate@1.0.0': + resolution: {integrity: sha512-JMpjde1suEIrelG5bWXXIIpsIcmSAJ4N6QNIiLclUvHRzRlU/FImoRBkRys60l+n8todA7EbsCSoRCFOjmBq/g==} + + '@arrow-js/ssr@1.0.0': + resolution: {integrity: sha512-2uOhlOGE8PAjZOlm/a16KSu2ThoQrUhkcKF4VtK0SyaIk3r7CqS8pbgDFlVlpeoR0yHZlf0OXnMiZIMUu7LPyg==} + + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@azure/abort-controller@1.1.0': resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} engines: {node: '>=12.0.0'} @@ -1083,6 +1120,34 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@deno/types@0.0.1': resolution: {integrity: sha512-KTB6Blr05Iw7k7aMzPWlJX0kv08xXZ5Mu7fxSp0M1HnaOHDRnFC956I4PxYdOtN27+b2723Id2G2oofxLvA35A==} @@ -2938,6 +3003,9 @@ packages: '@types/http-proxy@1.17.17': resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + '@types/jsdom@28.0.1': + resolution: {integrity: sha512-GJq2QE4TAZ5ajSoCasn5DOFm8u1mI3tIFvM5tIq3W5U/RTB6gsHwc6Yhpl91X9VSDOUVblgXmG+2+sSvFQrdlw==} + '@types/jsesc@2.5.1': resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} @@ -3004,6 +3072,9 @@ packages: '@types/tmp@0.0.33': resolution: {integrity: sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -3758,6 +3829,10 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + engines: {node: '>=18'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -3777,6 +3852,10 @@ packages: typescript: optional: true + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} @@ -3829,6 +3908,9 @@ packages: supports-color: optional: true + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} @@ -4487,6 +4569,10 @@ packages: hookable@6.1.0: resolution: {integrity: sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + html-entities@2.3.3: resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} @@ -4664,6 +4750,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} @@ -4766,6 +4855,15 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -5363,6 +5461,9 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + nypm@0.6.5: resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} engines: {node: '>=18'} @@ -5886,6 +5987,9 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + rsc-html-stream@0.0.7: resolution: {integrity: sha512-v9+fuY7usTgvXdNl8JmfXCvSsQbq2YMd60kOeeMIqCJFZ69fViuIxztHei7v5mlMMa2h3SqS+v44Gu9i9xANZA==} @@ -5914,6 +6018,10 @@ packages: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -6213,6 +6321,9 @@ packages: peerDependencies: vue: '>=3.2.26 < 4' + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} @@ -6274,6 +6385,13 @@ packages: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -6294,9 +6412,17 @@ packages: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -6390,6 +6516,9 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + undici-types@7.24.5: + resolution: {integrity: sha512-kNh333UBSbgK35OIW7FwJTr9tTfVIG51Fm1tSVT7m8foPHfDVjsb7OIee/q/rs3bB2aV/3qOPgG5mHNWl1odiA==} + undici@7.24.4: resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} engines: {node: '>=20.18.1'} @@ -6792,6 +6921,10 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + wait-on@7.2.0: resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} engines: {node: '>=12.0.0'} @@ -6809,6 +6942,10 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -6821,6 +6958,10 @@ packages: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -6891,6 +7032,10 @@ packages: resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + xml2js@0.6.2: resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} engines: {node: '>=4.0.0'} @@ -6903,6 +7048,9 @@ packages: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -6989,6 +7137,46 @@ snapshots: transitivePeerDependencies: - zod + '@arrow-js/core@1.0.0': {} + + '@arrow-js/framework@1.0.0': + dependencies: + '@arrow-js/core': 1.0.0 + '@types/jsdom': 28.0.1 + jsdom: 26.1.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + '@arrow-js/hydrate@1.0.0': + dependencies: + '@arrow-js/core': 1.0.0 + '@arrow-js/framework': 1.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + '@arrow-js/ssr@1.0.0': + dependencies: + '@arrow-js/framework': 1.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + '@azure/abort-controller@1.1.0': dependencies: tslib: 2.8.1 @@ -7471,6 +7659,26 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + '@deno/types@0.0.1': {} '@edge-runtime/format@4.0.0': {} @@ -9200,6 +9408,13 @@ snapshots: dependencies: '@types/node': 25.5.0 + '@types/jsdom@28.0.1': + dependencies: + '@types/node': 25.5.0 + '@types/tough-cookie': 4.0.5 + parse5: 7.3.0 + undici-types: 7.24.5 + '@types/jsesc@2.5.1': {} '@types/lodash@4.17.24': {} @@ -9269,6 +9484,8 @@ snapshots: '@types/tmp@0.0.33': {} + '@types/tough-cookie@4.0.5': {} + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.20': {} @@ -9354,7 +9571,7 @@ snapshots: vite: 8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) vue: 3.5.30(typescript@6.0.2) - '@vitest/coverage-v8@4.1.1(vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)))': + '@vitest/coverage-v8@4.1.1(vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(jsdom@26.1.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.1 @@ -9366,7 +9583,7 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: 4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(jsdom@26.1.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/expect@4.1.1': dependencies: @@ -10059,6 +10276,11 @@ snapshots: css-what@6.2.2: {} + cssstyle@4.6.0: + dependencies: + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 + csstype@3.2.3: {} cva@1.0.0-beta.2(typescript@6.0.2): @@ -10073,6 +10295,11 @@ snapshots: optionalDependencies: typescript: 6.0.2 + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + date-fns@2.30.0: dependencies: '@babel/runtime': 7.29.2 @@ -10091,6 +10318,8 @@ snapshots: dependencies: ms: 2.1.3 + decimal.js@10.6.0: {} + decode-named-character-reference@1.3.0: dependencies: character-entities: 2.0.2 @@ -10889,6 +11118,10 @@ snapshots: hookable@6.1.0: {} + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + html-entities@2.3.3: {} html-escaper@2.0.2: {} @@ -11040,6 +11273,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} is-reference@1.2.1: @@ -11129,6 +11364,33 @@ snapshots: dependencies: argparse: 2.0.1 + jsdom@26.1.0: + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.23 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.18.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + jsesc@3.1.0: {} json-schema-library@9.3.5: @@ -11862,6 +12124,8 @@ snapshots: dependencies: boolbase: 1.0.0 + nwsapi@2.2.23: {} + nypm@0.6.5: dependencies: citty: 0.2.1 @@ -12551,6 +12815,8 @@ snapshots: transitivePeerDependencies: - supports-color + rrweb-cssom@0.8.0: {} + rsc-html-stream@0.0.7: {} run-applescript@7.1.0: {} @@ -12571,6 +12837,10 @@ snapshots: sax@1.6.0: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.27.0: {} scule@1.3.0: {} @@ -12920,6 +13190,8 @@ snapshots: dependencies: vue: 3.5.30(typescript@6.0.2) + symbol-tree@3.2.4: {} + tabbable@6.4.0: {} tagged-tag@1.0.0: {} @@ -12974,6 +13246,12 @@ snapshots: tinyrainbow@3.1.0: {} + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -12992,8 +13270,16 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + tr46@0.0.3: {} + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -13070,6 +13356,8 @@ snapshots: undici-types@7.18.2: {} + undici-types@7.24.5: {} + undici@7.24.4: {} undici@7.24.5: {} @@ -13308,7 +13596,7 @@ snapshots: optionalDependencies: vite: 8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3) - vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.1(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(jsdom@26.1.0)(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.1 '@vitest/mocker': 4.1.1(vite@8.0.2(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)) @@ -13334,6 +13622,7 @@ snapshots: '@edge-runtime/vm': 5.0.0 '@opentelemetry/api': 1.9.0 '@types/node': 25.5.0 + jsdom: 26.1.0 transitivePeerDependencies: - msw @@ -13398,6 +13687,10 @@ snapshots: w3c-keyname@2.2.8: {} + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + wait-on@7.2.0: dependencies: axios: 1.13.6(debug@4.4.3) @@ -13418,6 +13711,8 @@ snapshots: webidl-conversions@3.0.1: {} + webidl-conversions@7.0.0: {} + webpack-virtual-modules@0.6.2: {} whatwg-encoding@3.1.1: @@ -13426,6 +13721,11 @@ snapshots: whatwg-mimetype@4.0.0: {} + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -13499,6 +13799,8 @@ snapshots: xdg-basedir@5.1.0: {} + xml-name-validator@5.0.0: {} + xml2js@0.6.2: dependencies: sax: 1.6.0 @@ -13513,6 +13815,8 @@ snapshots: xmlbuilder@11.0.1: {} + xmlchars@2.2.0: {} + y18n@5.0.8: {} yallist@3.1.1: {} From 49b60e81f1a94ef0152160458af78ae24653d4e7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:16:50 +0000 Subject: [PATCH 2/2] chore: apply automated updates --- examples/vite-ssr-arrow/src/app.ts | 9 ++------- examples/vite-ssr-arrow/src/entry-server.ts | 6 ++---- examples/vite-ssr-arrow/vite.config.ts | 14 ++------------ 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/examples/vite-ssr-arrow/src/app.ts b/examples/vite-ssr-arrow/src/app.ts index 68645e90d5..3f5f4ce0e5 100644 --- a/examples/vite-ssr-arrow/src/app.ts +++ b/examples/vite-ssr-arrow/src/app.ts @@ -91,9 +91,7 @@ export function App() { }; watch(() => { - console.log( - `[Arrow.js] ${remaining()} of ${state.todos.length} todos remaining` - ); + console.log(`[Arrow.js] ${remaining()} of ${state.todos.length} todos remaining`); }); return html` @@ -119,10 +117,7 @@ export function App() { ${Filters(state)}
      - ${() => - filtered().map((todo) => - TodoItem({ todo, onToggle, onRemove }).key(todo.id) - )} + ${() => filtered().map((todo) => TodoItem({ todo, onToggle, onRemove }).key(todo.id))}