├── modules ├── astro │ ├── src │ │ ├── env.d.ts │ │ └── pages │ │ │ ├── index.astro │ │ │ └── _favicon.svg │ ├── astro.config.mjs │ └── package.json ├── nuxt │ ├── app.vue │ ├── tsconfig.json │ ├── nuxt.config.ts │ ├── components │ │ ├── Entry.vue │ │ └── Table.vue │ ├── package.json │ └── .gitignore ├── marko │ ├── src │ │ ├── vite-env.d.ts │ │ ├── index.ts │ │ └── template.marko │ ├── vite.config.ts │ ├── tsconfig.node.json │ ├── .gitignore │ ├── package.json │ └── tsconfig.json ├── react │ ├── src │ │ ├── vite-env.d.ts │ │ ├── entry-server.tsx │ │ └── App.tsx │ ├── vite.config.ts │ ├── tsconfig.node.json │ ├── .gitignore │ ├── package.json │ └── tsconfig.json ├── solid │ ├── src │ │ ├── vite-env.d.ts │ │ ├── entry-server.tsx │ │ └── App.tsx │ ├── vite.config.ts │ ├── tsconfig.node.json │ ├── .gitignore │ ├── package.json │ ├── tsconfig.json │ └── package-lock.json ├── remix │ ├── .gitignore │ ├── public │ │ └── favicon.ico │ ├── vite.config.ts │ ├── app │ │ ├── entry.client.tsx │ │ ├── root.tsx │ │ ├── routes │ │ │ └── _index.tsx │ │ └── entry.server.tsx │ ├── tsconfig.json │ ├── package.json │ └── .eslintrc.cjs ├── testdata │ ├── index.d.ts │ ├── package.json │ └── index.js ├── sveltekit │ ├── src │ │ ├── lib │ │ │ ├── index.ts │ │ │ └── type.ts │ │ ├── routes │ │ │ ├── +page.server.ts │ │ │ └── +page.svelte │ │ ├── components │ │ │ ├── Entry.svelte │ │ │ └── Table.svelte │ │ ├── app.d.ts │ │ └── app.html │ ├── static │ │ └── favicon.png │ ├── vite.config.ts │ ├── .gitignore │ ├── svelte.config.js │ ├── package.json │ └── tsconfig.json ├── next │ ├── next.config.mjs │ ├── app │ │ ├── layout.tsx │ │ └── page.tsx │ ├── package.json │ ├── .gitignore │ ├── public │ │ ├── vercel.svg │ │ └── next.svg │ ├── tsconfig.json │ └── package-lock.json ├── next-pages │ ├── next.config.mjs │ ├── package.json │ ├── .gitignore │ ├── tsconfig.json │ └── pages │ │ └── index.tsx ├── vue │ ├── src │ │ ├── App.vue │ │ ├── main.ts │ │ ├── vite-env.d.ts │ │ ├── components │ │ │ ├── Entry.vue │ │ │ └── Table.vue │ │ └── entry-server.ts │ ├── vite.config.ts │ ├── tsconfig.node.json │ ├── .gitignore │ ├── package.json │ └── tsconfig.json ├── mfng │ ├── src │ │ ├── page.tsx │ │ ├── app.tsx │ │ └── entry-server.tsx │ ├── tsconfig.json │ ├── package.json │ └── webpack.config.js ├── hono │ ├── .gitignore │ ├── tsconfig.json │ ├── package.json │ └── src │ │ ├── App.tsx │ │ └── entry-server.tsx └── kita │ ├── .gitignore │ ├── src │ ├── entry-server.tsx │ └── App.tsx │ ├── package.json │ └── tsconfig.json ├── src ├── astro.js ├── nuxt.js ├── svelte.js ├── remix.js ├── next.js ├── result-format.js ├── http.js └── index.js ├── .gitignore ├── package.json └── readme.md /modules/astro/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /modules/nuxt/app.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /modules/marko/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /modules/react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /modules/solid/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /modules/remix/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /modules/testdata/index.d.ts: -------------------------------------------------------------------------------- 1 | export const testData: () => Promise<{ id: string; name: string }[]>; 2 | -------------------------------------------------------------------------------- /modules/sveltekit/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /modules/remix/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyx990803/ssr-benchmark/HEAD/modules/remix/public/favicon.ico -------------------------------------------------------------------------------- /modules/sveltekit/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yyx990803/ssr-benchmark/HEAD/modules/sveltekit/static/favicon.png -------------------------------------------------------------------------------- /modules/next/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /modules/nuxt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /modules/sveltekit/src/lib/type.ts: -------------------------------------------------------------------------------- 1 | import type { testData } from "testdata"; 2 | export type EntryData = Awaited>[0] 3 | -------------------------------------------------------------------------------- /modules/nuxt/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtConfig } from 'nuxt/config' 2 | 3 | export default defineNuxtConfig({ 4 | nitro: { preset: 'node' } 5 | }) 6 | -------------------------------------------------------------------------------- /src/astro.js: -------------------------------------------------------------------------------- 1 | import { handler } from "astro-benchmark/dist/server/entry.mjs"; 2 | 3 | export async function buildAstroHandler() { 4 | return handler; 5 | } 6 | -------------------------------------------------------------------------------- /src/nuxt.js: -------------------------------------------------------------------------------- 1 | import { handler } from 'nuxt-benchmark/.output/server/index.mjs'; 2 | 3 | export async function buildNuxtHandler() { 4 | return handler; 5 | } 6 | -------------------------------------------------------------------------------- /src/svelte.js: -------------------------------------------------------------------------------- 1 | import { handler } from "svelte-benchmark/build/handler.js"; 2 | 3 | export async function buildSveltekitHandler() { 4 | return handler; 5 | } 6 | -------------------------------------------------------------------------------- /modules/testdata/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testdata", 3 | "type": "module", 4 | "main": "index.js", 5 | "scripts": { 6 | "build": "true" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /modules/next-pages/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | }; 5 | 6 | export default nextConfig; 7 | -------------------------------------------------------------------------------- /modules/sveltekit/src/routes/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { testData } from "testdata"; 2 | 3 | export const load = async () => { 4 | return { entries: await testData() }; 5 | }; 6 | -------------------------------------------------------------------------------- /modules/sveltekit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()] 6 | }); 7 | -------------------------------------------------------------------------------- /modules/vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /modules/vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createSSRApp } from "vue"; 2 | import App from "./App.vue"; 3 | 4 | export function createApp() { 5 | const app = createSSRApp(App); 6 | return { app }; 7 | } 8 | -------------------------------------------------------------------------------- /modules/marko/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import marko from "@marko/vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [marko({ 6 | linked: false 7 | })], 8 | }); 9 | -------------------------------------------------------------------------------- /modules/sveltekit/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | -------------------------------------------------------------------------------- /modules/vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()] 7 | }) 8 | -------------------------------------------------------------------------------- /modules/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .pnp 3 | .pnp.js 4 | .yarn/install-state.gz 5 | 6 | dist 7 | build 8 | 9 | .DS_Store 10 | *.pem 11 | 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | .env*.local 17 | -------------------------------------------------------------------------------- /modules/solid/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import solid from "vite-plugin-solid"; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [solid({ ssr: true })], 7 | }); 8 | -------------------------------------------------------------------------------- /modules/sveltekit/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 | 9 | 10 | -------------------------------------------------------------------------------- /modules/vue/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /modules/next/app/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ 2 | children, 3 | }: Readonly<{ 4 | children: React.ReactNode; 5 | }>) { 6 | return ( 7 | 8 | {children} 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /modules/sveltekit/src/components/Entry.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /modules/nuxt/components/Entry.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /modules/vue/src/components/Entry.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /src/remix.js: -------------------------------------------------------------------------------- 1 | import * as remix from "remix-benchmark"; 2 | import { createRequestHandler } from "@mcansh/remix-raw-http"; 3 | 4 | export async function buildRemixHandler() { 5 | return createRequestHandler({ 6 | build: remix, 7 | mode: remix.mode, 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /modules/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import node from "@astrojs/node"; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | output: "server", 7 | adapter: node({ 8 | mode: "middleware" 9 | }) 10 | }); 11 | -------------------------------------------------------------------------------- /modules/testdata/index.js: -------------------------------------------------------------------------------- 1 | const data = Array(1000) 2 | .fill(0) 3 | .map((_, i) => ({ 4 | id: crypto.randomUUID(), 5 | name: crypto.randomUUID(), 6 | })); 7 | 8 | export function testData() { 9 | return new Promise((res) => setImmediate(() => res(data))); 10 | } 11 | -------------------------------------------------------------------------------- /modules/marko/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /modules/vue/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /modules/react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "jsx": "preserve" 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /modules/solid/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "jsx": "preserve" 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /modules/nuxt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "nuxt build" 8 | }, 9 | "dependencies": { 10 | "nuxt": "^3.11.2", 11 | "vue": "^3.4.21", 12 | "vue-router": "^4.3.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /modules/sveltekit/src/components/Table.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
{entry.id}{entry.name}
9 | {#each entries as entry} 10 | 11 | {/each} 12 |
13 | -------------------------------------------------------------------------------- /modules/nuxt/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /modules/nuxt/components/Table.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /modules/remix/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { vitePlugin as remix } from "@remix-run/dev"; 2 | import { installGlobals } from "@remix-run/node"; 3 | import { defineConfig } from "vite"; 4 | import tsconfigPaths from "vite-tsconfig-paths"; 5 | 6 | installGlobals(); 7 | 8 | export default defineConfig({ 9 | plugins: [remix(), tsconfigPaths()], 10 | }); 11 | -------------------------------------------------------------------------------- /modules/sveltekit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface PageState {} 9 | // interface Platform {} 10 | } 11 | } 12 | 13 | export {}; 14 | -------------------------------------------------------------------------------- /modules/marko/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { IncomingMessage, ServerResponse } from "node:http"; 2 | import template from "./template.marko"; 3 | 4 | export async function buildHandler() { 5 | return function handler(_: IncomingMessage, res: ServerResponse) { 6 | res.setHeader("content-type", "text/html"); 7 | template.render({}, res); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /modules/sveltekit/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; 2 | import adapter from "@sveltejs/adapter-node"; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | preprocess: vitePreprocess(), 7 | 8 | kit: { 9 | adapter: adapter(), 10 | }, 11 | }; 12 | 13 | export default config; 14 | -------------------------------------------------------------------------------- /modules/mfng/src/page.tsx: -------------------------------------------------------------------------------- 1 | import { App } from "./app"; 2 | 3 | export function Page() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /modules/hono/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/kita/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/kita/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import { renderToStream } from '@kitajs/html/suspense.js'; 2 | import { IncomingMessage, ServerResponse } from 'http'; 3 | import App from './App.js'; 4 | 5 | export function handler(_: IncomingMessage, res: ServerResponse) { 6 | const stream = renderToStream(App); 7 | res.setHeader('content-type', 'text/html'); 8 | stream.pipe(res); 9 | } 10 | -------------------------------------------------------------------------------- /modules/marko/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/react/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/solid/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/vue/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /modules/astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-benchmark", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "astro": "^4.6.0", 14 | "@astrojs/node": "^8.2.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /modules/hono/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "ES2022", 5 | "skipLibCheck": true, 6 | "moduleResolution": "Bundler", 7 | "noEmit": true, 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "hono/jsx", 10 | "strict": true, 11 | "types": [ 12 | "node" 13 | ] 14 | }, 15 | "include": [ 16 | "src" 17 | ] 18 | } -------------------------------------------------------------------------------- /modules/vue/src/components/Table.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | -------------------------------------------------------------------------------- /modules/sveltekit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /modules/marko/src/template.marko: -------------------------------------------------------------------------------- 1 | import { testData } from "testdata"; 2 | 3 | 4 | 5 | 6 | 7 | <@then|data|> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
${entry.id}${entry.name}
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /modules/solid/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import { renderToStream } from "solid-js/web"; 2 | import App from "./App"; 3 | import { IncomingMessage, ServerResponse } from "http"; 4 | 5 | export async function buildHandler() { 6 | return async function handler(_: IncomingMessage, res: ServerResponse) { 7 | const stream = renderToStream(() => ); 8 | res.setHeader("content-type", "text/html"); 9 | stream.pipe(res); 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /modules/kita/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kita-benchmark", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "main": "dist/entry-server.js", 7 | "types": "dist/entry-server.d.ts", 8 | "scripts": { 9 | "build": "tsc" 10 | }, 11 | "dependencies": { 12 | "@kitajs/html": "^4.1.0", 13 | "tslib": "^2.6.2" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20.10.5", 17 | "typescript": "^5.4.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /modules/marko/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marko-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "cross-env NODE_ENV=production vite build --ssr src/index.ts" 8 | }, 9 | "dependencies": { 10 | "marko": "^5.33.15" 11 | }, 12 | "devDependencies": { 13 | "@marko/vite": "^4.1.4", 14 | "cross-env": "^7.0.3", 15 | "vite": "^5.2.8" 16 | }, 17 | "main": "dist/index.js" 18 | } 19 | -------------------------------------------------------------------------------- /modules/react/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOMServer from "react-dom/server"; 2 | import App from "./App"; 3 | 4 | import { IncomingMessage, ServerResponse } from "http"; 5 | 6 | export async function buildHandler() { 7 | return async function handler(_: IncomingMessage, res: ServerResponse) { 8 | const stream = ReactDOMServer.renderToPipeableStream(); 9 | res.setHeader("content-type", "text/plain"); 10 | stream.pipe(res); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /modules/solid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solid-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build --ssr src/entry-server.tsx --outDir dist" 8 | }, 9 | "dependencies": { 10 | "solid-js": "^1.8.7" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "^20.12.7", 14 | "typescript": "^5.4.4", 15 | "vite": "^5.0.10", 16 | "vite-plugin-solid": "^2.8.0" 17 | }, 18 | "main": "dist/entry-server.js" 19 | } 20 | -------------------------------------------------------------------------------- /modules/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build --ssr src/entry-server.ts --outDir dist" 8 | }, 9 | "dependencies": { 10 | "vue": "^3.4.21" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "^20.10.5", 14 | "@vitejs/plugin-vue": "^4.5.2", 15 | "typescript": "^5.3.3", 16 | "vite": "^5.0.10", 17 | "vue-tsc": "^1.8.26" 18 | }, 19 | "main": "dist/entry-server.js" 20 | } 21 | -------------------------------------------------------------------------------- /modules/vue/src/entry-server.ts: -------------------------------------------------------------------------------- 1 | import { renderToNodeStream } from "vue/server-renderer"; 2 | import { createApp } from "./main"; 3 | import { IncomingMessage, ServerResponse } from "node:http"; 4 | 5 | export async function buildHandler() { 6 | return async function handler(_: IncomingMessage, res: ServerResponse) { 7 | const { app } = createApp(); 8 | const ctx = {}; 9 | 10 | const stream = renderToNodeStream(app, ctx); 11 | res.setHeader("content-type", "text/html"); 12 | stream.pipe(res); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /modules/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-benchmark", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "react": "^18", 13 | "react-dom": "^18", 14 | "next": "14.1.4" 15 | }, 16 | "devDependencies": { 17 | "typescript": "^5", 18 | "@types/node": "^20", 19 | "@types/react": "^18", 20 | "@types/react-dom": "^18" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /modules/hono/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hono-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build --ssr src/entry-server.tsx --outDir dist" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^20.10.5", 11 | "typescript": "^5.3.3", 12 | "vite": "^5.0.10" 13 | }, 14 | "types": "dist/entry-server.d.ts", 15 | "main": "dist/entry-server.js", 16 | "dependencies": { 17 | "@hono/node-server": "^1.9.1", 18 | "hono": "^4.2.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /modules/next-pages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-pages-benchmark", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "react": "^18", 13 | "react-dom": "^18", 14 | "next": "14.1.4" 15 | }, 16 | "devDependencies": { 17 | "typescript": "^5", 18 | "@types/node": "^20", 19 | "@types/react": "^18", 20 | "@types/react-dom": "^18" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /modules/next/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /src/next.js: -------------------------------------------------------------------------------- 1 | import next from "next"; 2 | 3 | export async function buildNextHandler() { 4 | const app = next({ 5 | dev: false, 6 | hostname: "localhost", 7 | port: 3000, 8 | dir: "./modules/next", 9 | }); 10 | await app.prepare(); 11 | return app.getRequestHandler(); 12 | } 13 | 14 | export async function buildNextPagesHandler() { 15 | const app = next({ 16 | dev: false, 17 | hostname: "localhost", 18 | port: 3000, 19 | dir: "./modules/next-pages", 20 | }); 21 | await app.prepare(); 22 | return app.getRequestHandler(); 23 | } 24 | -------------------------------------------------------------------------------- /modules/next-pages/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /modules/sveltekit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-benchmark", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "build": "vite build" 7 | }, 8 | "devDependencies": { 9 | "@sveltejs/adapter-auto": "^3.0.0", 10 | "@sveltejs/kit": "^2.0.0", 11 | "@sveltejs/vite-plugin-svelte": "^3.0.0", 12 | "svelte": "^4.2.7", 13 | "svelte-check": "^3.6.0", 14 | "tslib": "^2.4.1", 15 | "typescript": "^5.0.0", 16 | "vite": "^5.0.3" 17 | }, 18 | "type": "module", 19 | "dependencies": { 20 | "@sveltejs/adapter-node": "^5.0.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /modules/next-pages/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "paths": { 16 | "@/*": ["./*"] 17 | } 18 | }, 19 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /modules/next/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/remix/app/entry.client.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * By default, Remix will handle hydrating your app on the client for you. 3 | * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ 4 | * For more information, see https://remix.run/file-conventions/entry.client 5 | */ 6 | 7 | import { RemixBrowser } from "@remix-run/react"; 8 | import { startTransition, StrictMode } from "react"; 9 | import { hydrateRoot } from "react-dom/client"; 10 | 11 | startTransition(() => { 12 | hydrateRoot( 13 | document, 14 | 15 | 16 | 17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /modules/remix/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Links, 3 | Meta, 4 | Outlet, 5 | Scripts, 6 | ScrollRestoration, 7 | } from "@remix-run/react"; 8 | 9 | export function Layout({ children }: { children: React.ReactNode }) { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {children} 20 | 21 | 22 | 23 | 24 | ); 25 | } 26 | 27 | export default function App() { 28 | return ; 29 | } 30 | -------------------------------------------------------------------------------- /modules/mfng/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { testData } from "testdata"; 2 | 3 | export async function App() { 4 | return ; 5 | } 6 | 7 | function Table({ data }: { data: Awaited> }) { 8 | return ( 9 |
10 | 11 | {data.map((entry) => ( 12 | 13 | ))} 14 | 15 |
16 | ); 17 | } 18 | 19 | function Entry(props: { 20 | entry: { id: string; name: string; asyncData?: () => Promise }; 21 | }) { 22 | return ( 23 | 24 | {props.entry.id} 25 | {props.entry.name} 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /modules/next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /modules/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-benchmark", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build --ssr src/entry-server.tsx --outDir dist" 8 | }, 9 | "dependencies": { 10 | "react": "^19.0.0-canary-4c12339ce-20240408", 11 | "react-dom": "^19.0.0-canary-4c12339ce-20240408" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^20.10.5", 15 | "@types/react": "^18.2.45", 16 | "@types/react-dom": "^18.2.18", 17 | "@vitejs/plugin-react": "^4.2.1", 18 | "typescript": "^5.3.3", 19 | "vite": "^5.0.10" 20 | }, 21 | "types": "dist/entry-server.d.ts", 22 | "main": "dist/entry-server.js" 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ssr-benchmark", 3 | "version": "1.0.0", 4 | "description": "Testing various Web Frameworks SSR rendering performance", 5 | "main": "index.js", 6 | "author": "Ekin Koc", 7 | "license": "ISC", 8 | "scripts": { 9 | "build": "npm run build --ws", 10 | "start": "cross-env NODE_ENV=production node src/index.js" 11 | }, 12 | "workspaces": [ 13 | "modules/*" 14 | ], 15 | "devDependencies": { 16 | "@types/node": "^20.12.7", 17 | "typescript": "^5.4.4" 18 | }, 19 | "type": "module", 20 | "dependencies": { 21 | "@mcansh/remix-raw-http": "^1.0.2", 22 | "cross-env": "^7.0.3", 23 | "next": "14.1.4", 24 | "tinybench": "^2.6.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/marko/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | "types": ["node"] 23 | }, 24 | "include": ["src"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /modules/solid/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { For, Suspense, createResource } from "solid-js"; 2 | import { testData } from "testdata"; 3 | 4 | function App() { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | 12 | function Table() { 13 | const [tdata] = createResource(testData); 14 | 15 | return ( 16 |
17 | 18 | {(entry) => } 19 | 20 |
21 | ); 22 | } 23 | 24 | function Entry(props: { entry: { id: string; name: string } }) { 25 | return ( 26 | 27 | {props.entry.id} 28 | {props.entry.name} 29 | 30 | ); 31 | } 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /modules/astro/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import favicon from "./_favicon.svg" 3 | import { testData } from "testdata" 4 | 5 | const entries = await testData() 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | 13 | Astro 14 | 15 | 16 |
17 | {entries.map(entry => 18 | 19 | 20 | 21 | 22 | )}
{entry.id}{entry.name}
23 |
24 | 25 | -------------------------------------------------------------------------------- /modules/sveltekit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true, 12 | "moduleResolution": "bundler" 13 | } 14 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 15 | // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files 16 | // 17 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 18 | // from the referenced tsconfig.json - TypeScript does not merge them in 19 | } 20 | -------------------------------------------------------------------------------- /modules/next/app/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = "force-dynamic"; 2 | 3 | import { testData } from "testdata"; 4 | 5 | export default async function App() { 6 | return ; 7 | } 8 | 9 | function Table({ data }: { data: Awaited> }) { 10 | return ( 11 |
12 | 13 | {data.map((entry) => ( 14 | 15 | ))} 16 | 17 |
18 | ); 19 | } 20 | 21 | function Entry(props: { 22 | entry: { id: string; name: string; asyncData?: () => Promise }; 23 | }) { 24 | return ( 25 | 26 | {props.entry.id} 27 | {props.entry.name} 28 | 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /modules/solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "noEmit": true, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "jsxImportSource": "solid-js", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true 23 | }, 24 | "include": ["src"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /modules/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /modules/mfng/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | "checkJs": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "Bundler", 12 | "allowImportingTsExtensions": true, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | 24 | "types": ["react/experimental", "node"] 25 | }, 26 | "include": ["src", "webpack.config.js"] 27 | } 28 | -------------------------------------------------------------------------------- /modules/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | "types": ["react/canary", "node"] 24 | }, 25 | "include": ["src"], 26 | "references": [{ "path": "./tsconfig.node.json" }] 27 | } 28 | -------------------------------------------------------------------------------- /modules/astro/src/pages/_favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /modules/kita/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "Bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "react", 15 | "jsxFactory": "Html.createElement", 16 | "jsxFragmentFactory": "Html.Fragment", 17 | "outDir": "dist", 18 | 19 | /* Linting */ 20 | "strict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true, 24 | 25 | "types": [ "node"] 26 | }, 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /modules/hono/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { testData } from "testdata"; 2 | import { Suspense } from "hono/jsx"; 3 | 4 | function App() { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | 12 | async function Table({ data }: { data: ReturnType }) { 13 | const entries = await data; 14 | return ( 15 |
16 | 17 | {entries.map((entry) => ( 18 | 19 | ))} 20 | 21 |
22 | ); 23 | } 24 | 25 | function Entry(props: { entry: { id: string; name: string } }) { 26 | return ( 27 | 28 | {props.entry.id} 29 | {props.entry.name} 30 | 31 | ); 32 | } 33 | 34 | export default App; 35 | -------------------------------------------------------------------------------- /modules/remix/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.ts", "**/*.tsx", "**/.server/**/*.ts", "**/.server/**/*.tsx", "**/.client/**/*.ts", "**/.client/**/*.tsx"], 3 | "compilerOptions": { 4 | "lib": ["DOM", "DOM.Iterable", "ES2022"], 5 | "types": ["@remix-run/node", "vite/client"], 6 | "isolatedModules": true, 7 | "esModuleInterop": true, 8 | "jsx": "react-jsx", 9 | "module": "ESNext", 10 | "moduleResolution": "Bundler", 11 | "resolveJsonModule": true, 12 | "target": "ES2022", 13 | "strict": true, 14 | "allowJs": true, 15 | "skipLibCheck": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": ["./app/*"] 20 | }, 21 | 22 | // Vite takes care of building everything, not tsc. 23 | "noEmit": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /modules/mfng/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mfng-benchmark", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "main": "dist/index.js", 7 | "scripts": { 8 | "build": "webpack --mode production" 9 | }, 10 | "dependencies": { 11 | "@mfng/core": "^4.1.3", 12 | "react": "^19.0.0-canary-4c12339ce-20240408", 13 | "react-dom": "^19.0.0-canary-4c12339ce-20240408", 14 | "react-server-dom-webpack": "^19.0.0-canary-4c12339ce-20240408" 15 | }, 16 | "devDependencies": { 17 | "@mfng/webpack-rsc": "^4.0.1", 18 | "@swc/core": "^1.4.13", 19 | "@types/node": "^20.10.5", 20 | "@types/react": "^18.2.45", 21 | "@types/react-dom": "^18.2.18", 22 | "swc-loader": "^0.2.6", 23 | "typescript": "^5.3.3", 24 | "webpack": "^5.91.0", 25 | "webpack-cli": "^5.1.4" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /modules/mfng/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import { createRscAppStream } from "@mfng/core/server/rsc"; 2 | import { createHtmlStream } from "@mfng/core/server/ssr"; 3 | import { IncomingMessage, ServerResponse } from "http"; 4 | import { Readable } from "stream"; 5 | import { ReadableStream } from "stream/web"; 6 | import { Page } from "./page"; 7 | 8 | export async function buildHandler() { 9 | return async function handler(_: IncomingMessage, res: ServerResponse) { 10 | const rscAppStream = createRscAppStream(, { 11 | reactClientManifest: {}, 12 | }); 13 | 14 | const htmlStream = await createHtmlStream(rscAppStream, { 15 | reactSsrManifest: {}, 16 | }); 17 | 18 | res.setHeader("content-type", "text/html; charset=utf-8"); 19 | Readable.fromWeb(htmlStream as ReadableStream).pipe(res); 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /modules/hono/src/entry-server.tsx: -------------------------------------------------------------------------------- 1 | import App from "./App"; 2 | import { Hono } from "hono"; 3 | import { renderToReadableStream } from "hono/jsx/streaming"; 4 | import { getRequestListener } from "@hono/node-server"; 5 | 6 | const app = new Hono(); 7 | 8 | app.get("/", async (c) => { 9 | return c.body( 10 | renderToReadableStream( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ), 21 | { 22 | headers: { 23 | "Content-Type": "text/html; charset=UTF-8", 24 | "Transfer-Encoding": "chunked", 25 | }, 26 | } 27 | ); 28 | }); 29 | 30 | export async function buildHandler() { 31 | return getRequestListener(app.fetch); 32 | } 33 | -------------------------------------------------------------------------------- /modules/kita/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from '@kitajs/html/suspense.js'; 2 | import { testData } from 'testdata'; 3 | import Html from '@kitajs/html'; 4 | 5 | export default function App(rid: number | string) { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | async function Table({ data }: { data: ReturnType }) { 14 | return ( 15 |
16 | 17 | {(await data).map((entry) => ( 18 | 19 | ))} 20 | 21 |
22 | ); 23 | } 24 | 25 | function Entry(props: { 26 | entry: { id: string; name: string; asyncData?: () => Promise }; 27 | }) { 28 | return ( 29 | 30 | {props.entry.id} 31 | {props.entry.name} 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /modules/next-pages/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense, useRef, use } from "react"; 2 | import { testData } from "testdata"; 3 | 4 | export const getServerSideProps = async () => { 5 | return { 6 | props: { 7 | data: await testData(), 8 | }, 9 | }; 10 | }; 11 | 12 | function App({ data }: { data: Awaited> }) { 13 | return ; 14 | } 15 | 16 | function Table({ data }: { data: Awaited> }) { 17 | return ( 18 |
19 | 20 | {data.map((entry) => ( 21 | 22 | ))} 23 | 24 |
25 | ); 26 | } 27 | 28 | function Entry(props: { 29 | entry: { id: string; name: string; asyncData?: () => Promise }; 30 | }) { 31 | return ( 32 | 33 | {props.entry.id} 34 | {props.entry.name} 35 | 36 | ); 37 | } 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /modules/react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense, useRef, use } from "react"; 2 | import { testData } from "testdata"; 3 | 4 | function App() { 5 | const dataRef = useRef>(); 6 | 7 | if (!dataRef.current) dataRef.current = testData(); 8 | 9 | return ( 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | function Table({ data }: { data: ReturnType }) { 17 | const tdata = use(data); 18 | 19 | return ( 20 |
21 | 22 | {tdata.map((entry) => ( 23 | 24 | ))} 25 | 26 |
27 | ); 28 | } 29 | 30 | function Entry(props: { entry: { id: string; name: string; asyncData?: () => Promise } }) { 31 | return ( 32 | 33 | {props.entry.id} 34 | {props.entry.name} 35 | 36 | ); 37 | } 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /modules/remix/app/routes/_index.tsx: -------------------------------------------------------------------------------- 1 | import { defer } from "@remix-run/node"; 2 | import { Await, useLoaderData } from "@remix-run/react"; 3 | import { Suspense } from "react"; 4 | import { testData } from "testdata"; 5 | 6 | export const loader = async () => { 7 | return defer({ testData: testData() }); 8 | }; 9 | 10 | export default function App() { 11 | const data = useLoaderData(); 12 | 13 | return ( 14 | Loading...}> 15 | 16 | {(data) => ( 17 | 18 | 19 | {data.map((entry) => ( 20 | 21 | ))} 22 | 23 |
24 | )} 25 |
26 |
27 | ); 28 | } 29 | 30 | function Entry(props: { 31 | entry: { id: string; name: string; asyncData?: () => Promise }; 32 | }) { 33 | return ( 34 | 35 | {props.entry.id} 36 | {props.entry.name} 37 | 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /modules/remix/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remix-benchmark", 3 | "private": true, 4 | "sideEffects": false, 5 | "type": "module", 6 | "scripts": { 7 | "build": "remix vite:build" 8 | }, 9 | "dependencies": { 10 | "@remix-run/node": "^2.8.1", 11 | "@remix-run/react": "^2.8.1", 12 | "@remix-run/serve": "^2.8.1", 13 | "isbot": "^4.1.0", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@remix-run/dev": "^2.8.1", 19 | "@types/react": "^18.2.20", 20 | "@types/react-dom": "^18.2.7", 21 | "@typescript-eslint/eslint-plugin": "^6.7.4", 22 | "@typescript-eslint/parser": "^6.7.4", 23 | "eslint": "^8.38.0", 24 | "eslint-import-resolver-typescript": "^3.6.1", 25 | "eslint-plugin-import": "^2.28.1", 26 | "eslint-plugin-jsx-a11y": "^6.7.1", 27 | "eslint-plugin-react": "^7.33.2", 28 | "eslint-plugin-react-hooks": "^4.6.0", 29 | "typescript": "^5.1.6", 30 | "vite": "^5.1.0", 31 | "vite-tsconfig-paths": "^4.2.1" 32 | }, 33 | "engines": { 34 | "node": ">=18.0.0" 35 | }, 36 | "main": "build/server/index.js" 37 | } 38 | -------------------------------------------------------------------------------- /modules/next/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/result-format.js: -------------------------------------------------------------------------------- 1 | export function logResultsTable(bench) { 2 | const table = bench.tasks.map((task) => ({ 3 | name: task.name, 4 | "ops/sec": task.result.error 5 | ? "NaN" 6 | : parseInt(task.result.hz.toString(), 10).toString(), 7 | "average (ms)": task.result.error ? "NaN" : task.result.mean.toFixed(3), 8 | samples: task.result.error ? "NaN" : task.result.samples.length, 9 | "body (kb)": task.result.error 10 | ? "NaN" 11 | : (task.result.bodyLength / 1024).toFixed(2), 12 | duplication: task.result.error 13 | ? "NaN" 14 | : `x${task.result.duplicationFactor.toFixed(2)}`, 15 | })); 16 | 17 | const results = table 18 | .map((x) => ({ ...x, "ops/sec": parseFloat(x["ops/sec"]) })) 19 | .toSorted((a, b) => b["ops/sec"] - a["ops/sec"]); 20 | 21 | const maxOps = Math.max(...results.map((x) => x["ops/sec"])); 22 | 23 | console.table( 24 | results.map((x, i) => ({ 25 | ...x, 26 | [`relative to ${results[0]["name"]}`]: 27 | i === 0 28 | ? "" 29 | : `${(maxOps / parseInt(x["ops/sec"])).toFixed(2)} x slower`, 30 | })) 31 | ); 32 | } 33 | 34 | export function getDuplicationFactor(body) { 35 | let samples = {}; 36 | let matches = body.matchAll( 37 | /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi 38 | ); 39 | 40 | for (let match of matches) { 41 | samples[match[0]] = (samples[match[0]] ?? 0) + 1; 42 | } 43 | 44 | let values = Object.values(samples); 45 | return Array.from(values).reduce((a, b) => a + b, 0) / values.length; 46 | } 47 | -------------------------------------------------------------------------------- /modules/mfng/webpack.config.js: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import { 3 | WebpackRscServerPlugin, 4 | createWebpackRscServerLoader, 5 | createWebpackRscSsrLoader, 6 | webpackRscLayerName, 7 | } from "@mfng/webpack-rsc"; 8 | 9 | const outputDirname = path.join(process.cwd(), "dist"); 10 | 11 | /** 12 | * @type {import('@mfng/webpack-rsc').ClientReferencesMap} 13 | */ 14 | const clientReferencesMap = new Map(); 15 | const serverReferencesMap = new Map(); 16 | 17 | /** 18 | * @type {import('webpack').RuleSetUseItem} 19 | */ 20 | const serverSwcLoader = { 21 | loader: "swc-loader", 22 | options: { 23 | env: { 24 | targets: { node: 20 }, 25 | }, 26 | jsc: { transform: { react: { runtime: "automatic" } } }, 27 | }, 28 | }; 29 | 30 | /** 31 | * @type {import('webpack').Configuration} 32 | */ 33 | export default { 34 | name: "server", 35 | entry: "./src/entry-server.tsx", 36 | target: "node", 37 | output: { 38 | filename: "index.js", 39 | path: outputDirname, 40 | libraryTarget: "module", 41 | chunkFormat: "module", 42 | }, 43 | resolve: { 44 | extensions: [".tsx", "..."], 45 | }, 46 | module: { 47 | rules: [ 48 | { 49 | resource: [/[/\\]server[/\\]rsc[/\\]/, /[/\\]page\.tsx$/], 50 | layer: webpackRscLayerName, 51 | }, 52 | { 53 | issuerLayer: webpackRscLayerName, 54 | resolve: { conditionNames: ["react-server", "..."] }, 55 | }, 56 | { 57 | oneOf: [ 58 | { 59 | issuerLayer: webpackRscLayerName, 60 | test: /\.tsx?$/, 61 | use: [ 62 | createWebpackRscServerLoader({ 63 | clientReferencesMap, 64 | serverReferencesMap, 65 | }), 66 | serverSwcLoader, 67 | ], 68 | }, 69 | { 70 | test: /\.tsx?$/, 71 | use: [ 72 | createWebpackRscSsrLoader({ serverReferencesMap }), 73 | serverSwcLoader, 74 | ], 75 | }, 76 | ], 77 | }, 78 | ], 79 | }, 80 | plugins: [ 81 | new WebpackRscServerPlugin({ clientReferencesMap, serverReferencesMap }), 82 | ], 83 | experiments: { outputModule: true, layers: true }, 84 | }; 85 | -------------------------------------------------------------------------------- /modules/remix/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * This is intended to be a basic starting point for linting in your app. 3 | * It relies on recommended configs out of the box for simplicity, but you can 4 | * and should modify this configuration to best suit your team's needs. 5 | */ 6 | 7 | /** @type {import('eslint').Linter.Config} */ 8 | module.exports = { 9 | root: true, 10 | parserOptions: { 11 | ecmaVersion: "latest", 12 | sourceType: "module", 13 | ecmaFeatures: { 14 | jsx: true, 15 | }, 16 | }, 17 | env: { 18 | browser: true, 19 | commonjs: true, 20 | es6: true, 21 | }, 22 | ignorePatterns: ["!**/.server", "!**/.client"], 23 | 24 | // Base config 25 | extends: ["eslint:recommended"], 26 | 27 | overrides: [ 28 | // React 29 | { 30 | files: ["**/*.{js,jsx,ts,tsx}"], 31 | plugins: ["react", "jsx-a11y"], 32 | extends: [ 33 | "plugin:react/recommended", 34 | "plugin:react/jsx-runtime", 35 | "plugin:react-hooks/recommended", 36 | "plugin:jsx-a11y/recommended", 37 | ], 38 | settings: { 39 | react: { 40 | version: "detect", 41 | }, 42 | formComponents: ["Form"], 43 | linkComponents: [ 44 | { name: "Link", linkAttribute: "to" }, 45 | { name: "NavLink", linkAttribute: "to" }, 46 | ], 47 | "import/resolver": { 48 | typescript: {}, 49 | }, 50 | }, 51 | }, 52 | 53 | // Typescript 54 | { 55 | files: ["**/*.{ts,tsx}"], 56 | plugins: ["@typescript-eslint", "import"], 57 | parser: "@typescript-eslint/parser", 58 | settings: { 59 | "import/internal-regex": "^~/", 60 | "import/resolver": { 61 | node: { 62 | extensions: [".ts", ".tsx"], 63 | }, 64 | typescript: { 65 | alwaysTryTypes: true, 66 | }, 67 | }, 68 | }, 69 | extends: [ 70 | "plugin:@typescript-eslint/recommended", 71 | "plugin:import/recommended", 72 | "plugin:import/typescript", 73 | ], 74 | }, 75 | 76 | // Node 77 | { 78 | files: [".eslintrc.cjs"], 79 | env: { 80 | node: true, 81 | }, 82 | }, 83 | ], 84 | }; 85 | -------------------------------------------------------------------------------- /src/http.js: -------------------------------------------------------------------------------- 1 | import { Readable, Writable } from "node:stream"; 2 | 3 | export class IncomingMessage extends Readable { 4 | aborted = false; 5 | httpVersion = "1.1"; 6 | httpVersionMajor = 1; 7 | httpVersionMinor = 1; 8 | complete = true; 9 | connection; 10 | socket; 11 | headers = {}; 12 | trailers = {}; 13 | method = "GET"; 14 | url = "/"; 15 | statusCode = 200; 16 | statusMessage = ""; 17 | closed = false; 18 | errored = null; 19 | 20 | readable = false; 21 | 22 | socket = {}; 23 | 24 | constructor() { 25 | super(); 26 | } 27 | 28 | get rawHeaders() { 29 | return [""]; 30 | } 31 | 32 | get rawTrailers() { 33 | return []; 34 | } 35 | 36 | setTimeout(_msecs, _callback) { 37 | return this; 38 | } 39 | 40 | get headersDistinct() { 41 | return {}; 42 | } 43 | 44 | get trailersDistinct() { 45 | return {}; 46 | } 47 | } 48 | 49 | const decoder = new TextDecoder(); 50 | 51 | export class ServerResponse extends Writable { 52 | _res; 53 | 54 | body; 55 | length = 0; 56 | times = { start: performance.now(), end: 0, headers: 0 }; 57 | await = new Promise((res) => (this._res = res)); 58 | 59 | statusCode = 200; 60 | statusMessage = ""; 61 | upgrading = false; 62 | chunkedEncoding = false; 63 | shouldKeepAlive = false; 64 | useChunkedEncodingByDefault = false; 65 | sendDate = false; 66 | finished = false; 67 | headersSent = false; 68 | strictContentLength = false; 69 | connection = null; 70 | socket = null; 71 | 72 | req; 73 | 74 | _headers = {}; 75 | 76 | constructor(req, collect = false) { 77 | super({ 78 | write: (chunk, _, callback) => { 79 | if (!this.headersSent) { 80 | this.writeHead(); 81 | } 82 | 83 | this.length += chunk.length; 84 | 85 | if (collect) { 86 | this.body = (this.body || "") + decoder.decode(chunk); 87 | } 88 | 89 | callback(); 90 | }, 91 | destroy: () => { 92 | this.times.end = performance.now(); 93 | this.finished = true; 94 | this._res?.(null); 95 | }, 96 | }); 97 | 98 | this.req = req; 99 | } 100 | 101 | writeHead(status) { 102 | this.times.headers = performance.now(); 103 | 104 | if (status) { 105 | this.statusCode = status; 106 | } 107 | 108 | this.headersSent = true; 109 | 110 | return this; 111 | } 112 | 113 | setTimeout() { 114 | return this; 115 | } 116 | 117 | appendHeader(name, value) { 118 | return this.setHeader(name, value); 119 | } 120 | 121 | setHeader(name, value) { 122 | this._headers[name.toLowerCase()] = value; 123 | return this; 124 | } 125 | 126 | getHeader(name) { 127 | return this._headers[name.toLowerCase()]; 128 | } 129 | 130 | getHeaders() { 131 | return this._headers; 132 | } 133 | 134 | getHeaderNames() { 135 | return Object.keys(this._headers); 136 | } 137 | 138 | hasHeader(name) { 139 | return name.toLowerCase() in this._headers; 140 | } 141 | 142 | removeHeader(name) { 143 | delete this._headers[name.toLowerCase()]; 144 | } 145 | 146 | addTrailers() {} 147 | flushHeaders() {} 148 | assignSocket() {} 149 | detachSocket() {} 150 | writeContinue() {} 151 | writeProcessing() {} 152 | _implicitHeader() {} 153 | 154 | writeEarlyHints(_headers, cb) { 155 | if (typeof cb === "function") { 156 | cb(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { Bench } from "tinybench"; 2 | import { IncomingMessage, ServerResponse } from "./http.js"; 3 | import { buildRemixHandler } from "./remix.js"; 4 | import { buildNextHandler, buildNextPagesHandler } from "./next.js"; 5 | import { buildNuxtHandler } from "./nuxt.js"; 6 | import { buildSveltekitHandler } from "./svelte.js"; 7 | import { buildAstroHandler } from "./astro.js"; 8 | import http from "node:http"; 9 | import { getDuplicationFactor, logResultsTable } from "./result-format.js"; 10 | 11 | async function run(handler, collect = false) { 12 | const request = new IncomingMessage(); 13 | const response = new ServerResponse(request, collect); 14 | 15 | handler(request, response); 16 | 17 | await response.await; 18 | return response; 19 | } 20 | 21 | async function runHandlers(handlers) { 22 | const bench = new Bench({ 23 | time: 10_000, 24 | setup: async (task, mode) => { 25 | if (mode == "run") console.log(`Running ${task.name} benchmark...`); 26 | }, 27 | }); 28 | 29 | for (let handler of handlers) { 30 | bench.add(handler.name, async () => { 31 | await run(handler.handler); 32 | }); 33 | } 34 | 35 | await bench.warmup(); 36 | await bench.run(); 37 | 38 | for (let handler of handlers) { 39 | let response = await run(handler.handler, true); 40 | 41 | bench.getTask(handler.name).setResult({ 42 | bodyLength: response.length, 43 | duplicationFactor: getDuplicationFactor(response.body), 44 | }); 45 | } 46 | 47 | logResultsTable(bench); 48 | } 49 | 50 | const handlers = [ 51 | { 52 | name: "solid", 53 | group: "renderers", 54 | handler: await import("solid-benchmark").then((x) => x.buildHandler()), 55 | }, 56 | { 57 | name: "react", 58 | handler: await import("react-benchmark").then((x) => x.buildHandler()), 59 | }, 60 | { 61 | name: "vue", 62 | group: "renderers", 63 | handler: await import("vue-benchmark").then((x) => x.buildHandler()), 64 | }, 65 | { 66 | name: "mfng", 67 | group: "frameworks", 68 | handler: await import("mfng-benchmark").then((x) => x.buildHandler()), 69 | }, 70 | { name: "remix", group: "frameworks", handler: await buildRemixHandler() }, 71 | { name: "next", group: "frameworks", handler: await buildNextHandler() }, 72 | { 73 | name: "next-pages", 74 | group: "frameworks", 75 | handler: await buildNextPagesHandler(), 76 | }, 77 | { name: "nuxt", group: "frameworks", handler: await buildNuxtHandler() }, 78 | { 79 | name: "sveltekit", 80 | group: "frameworks", 81 | handler: await buildSveltekitHandler(), 82 | }, 83 | { name: "astro", group: "frameworks", handler: await buildAstroHandler() }, 84 | { 85 | name: "hono", 86 | group: "renderers", 87 | handler: await import("hono-benchmark").then((x) => x.buildHandler()), 88 | }, 89 | { 90 | name: "marko", 91 | group: "renderers", 92 | handler: await import("marko-benchmark").then((x) => x.buildHandler()), 93 | }, 94 | { 95 | name: "kita", 96 | group: "renderers", 97 | handler: await import("kita-benchmark").then((x) => x.handler), 98 | }, 99 | ]; 100 | 101 | console.log("Benchmarking frameworks"); 102 | await runHandlers(handlers.filter((x) => !x.group || x.group == "frameworks")); 103 | 104 | console.log("Benchmarking renderers"); 105 | await runHandlers(handlers.filter((x) => !x.group || x.group == "renderers")); 106 | 107 | console.log(); 108 | console.log("Check out the actual render results:"); 109 | 110 | for (let handler of handlers) { 111 | console.log(handler.name, `http://localhost:8080/${handler.name}`); 112 | } 113 | 114 | http 115 | .createServer(async function (req, res) { 116 | const handler = handlers.find((x) => "/" + x.name == req.url); 117 | 118 | if (handler) { 119 | req.url = "/"; 120 | handler.handler(req, res); 121 | } else { 122 | res.writeHead(404); 123 | res.end(); 124 | } 125 | }) 126 | .listen(8080); 127 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # SSR Framework Benchmark 2 | 3 | This is an experiment in response to https://twitter.com/thdxr/status/1777782835249553517 where it is stated that Next.JS is a lot slower on server side rendering compared to Vanilla React. 4 | 5 | This is not a comprehensive or scientific test. Just wanted to compare each in a setup a little complex than just printing `hello world`. 6 | 7 | ## Frameworks 8 | 9 | | (index) | name | ops/sec | average (ms) | samples | body (kb) | duplication | relative to react | 10 | | ------- | ------------ | ------- | ------------ | ------- | --------- | ----------- | ----------------- | 11 | | 0 | 'react' | 779 | '1.283' | 7793 | '97.28' | 'x1.00' | '' | 12 | | 1 | 'sveltekit' | 607 | '1.647' | 6073 | '184.46' | 'x2.00' | '1.28 x slower' | 13 | | 2 | 'remix' | 462 | '2.163' | 4624 | '189.10' | 'x2.00' | '1.69 x slower' | 14 | | 3 | 'nuxt' | 198 | '5.040' | 1985 | '201.05' | 'x2.00' | '3.93 x slower' | 15 | | 4 | 'next-pages' | 114 | '8.766' | 1141 | '187.67' | 'x2.00' | '6.83 x slower' | 16 | | 5 | 'astro' | 105 | '9.447' | 1059 | '99.91' | 'x1.00' | '7.42 x slower' | 17 | | 6 | 'mfng' | 68 | '14.609' | 685 | '317.31' | 'x2.50' | '11.46 x slower' | 18 | | 7 | 'next' | 53 | '18.578' | 539 | '284.64' | 'x2.00' | '14.70 x slower' | 19 | 20 | - **react** is here only as a baseline renderer to compare framework performance with. 21 | 22 | ## Renderers 23 | 24 | | (index) | name | ops/sec | average (ms) | samples | body (kb) | duplication | relative to marko | 25 | | ------- | ------- | ------- | ------------ | ------- | --------- | ----------- | ----------------- | 26 | | 0 | 'marko' | 6678 | '0.150' | 66784 | '96.74' | 'x1.00' | '' | 27 | | 1 | 'kita' | 3151 | '0.317' | 31518 | '97.34' | 'x1.00' | '2.12 x slower' | 28 | | 2 | 'hono' | 948 | '1.054' | 9486 | '97.15' | 'x1.00' | '7.04 x slower' | 29 | | 3 | 'react' | 775 | '1.289' | 7760 | '97.28' | 'x1.00' | '8.62 x slower' | 30 | | 4 | 'solid' | 616 | '1.622' | 6167 | '215.93' | 'x2.00' | '10.84 x slower' | 31 | | 5 | 'vue' | 289 | '3.458' | 2892 | '96.72' | 'x1.00' | '23.11 x slower' | 32 | 33 | - **solid** is here but it also carries hydration data for client side hydration, it is more comparable to frameworks in that way. 34 | 35 | - **body** is the response body length in kb 36 | - **duplication** is the data duplication factor. 2x means each rendered data item has been observed twice in the response. It is required for hydration to work. 37 | 38 | - Table has been updated thanks to [kiliman](https://github.com/kiliman). Remix now uses [defer](https://remix.run/docs/en/main/utils/defer) yielding much better results. 39 | - **mfng** is a minimal RSC implementation. Important to see its results compared to Next as they both reflect the RSC rendering performance. 40 | 41 | ## Test Environment 42 | 43 | - Only SSR. We do not even build the client bundles for most of the modules. 44 | - Next.JS route cache is disabled using `const dynamic = 'force-dynamic'`. (Otherwise we would be benchmarking a static http server because there is no dynamic code like accessing cookies.) 45 | - Instead of going through the http server, the benchmark code creates mock http requests and responses. This ensures that we do not pay for tcp overhead. 46 | - Tests ran on Node.JS `v20.6.1` on my Macbook Pro M1 Pro 47 | - Each framework renders a table of 1000 rows, each containing two uuid columns. 48 | - The table data is emulated as async and requires Suspense on react, solid and vue. On Next it is loaded in an async RSC component. On Remix it is loaded in a route `loader` function. 49 | - Streaming rendering used on solid, react and vue. 50 | 51 | ## Running 52 | 53 | ```sh 54 | $ npm install 55 | $ npm run build 56 | $ npm start 57 | ``` 58 | -------------------------------------------------------------------------------- /modules/remix/app/entry.server.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * By default, Remix will handle generating the HTTP Response for you. 3 | * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ 4 | * For more information, see https://remix.run/file-conventions/entry.server 5 | */ 6 | 7 | import { PassThrough } from "node:stream"; 8 | 9 | import type { AppLoadContext, EntryContext } from "@remix-run/node"; 10 | import { createReadableStreamFromReadable } from "@remix-run/node"; 11 | import { RemixServer } from "@remix-run/react"; 12 | import { isbot } from "isbot"; 13 | import { renderToPipeableStream } from "react-dom/server"; 14 | 15 | const ABORT_DELAY = 5_000; 16 | 17 | export default function handleRequest( 18 | request: Request, 19 | responseStatusCode: number, 20 | responseHeaders: Headers, 21 | remixContext: EntryContext, 22 | // This is ignored so we can keep it in the template for visibility. Feel 23 | // free to delete this parameter in your app if you're not using it! 24 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 25 | loadContext: AppLoadContext 26 | ) { 27 | return isbot(request.headers.get("user-agent") || "") 28 | ? handleBotRequest( 29 | request, 30 | responseStatusCode, 31 | responseHeaders, 32 | remixContext 33 | ) 34 | : handleBrowserRequest( 35 | request, 36 | responseStatusCode, 37 | responseHeaders, 38 | remixContext 39 | ); 40 | } 41 | 42 | function handleBotRequest( 43 | request: Request, 44 | responseStatusCode: number, 45 | responseHeaders: Headers, 46 | remixContext: EntryContext 47 | ) { 48 | return new Promise((resolve, reject) => { 49 | let shellRendered = false; 50 | const { pipe, abort } = renderToPipeableStream( 51 | , 56 | { 57 | onAllReady() { 58 | shellRendered = true; 59 | const body = new PassThrough(); 60 | const stream = createReadableStreamFromReadable(body); 61 | 62 | responseHeaders.set("Content-Type", "text/html"); 63 | 64 | resolve( 65 | new Response(stream, { 66 | headers: responseHeaders, 67 | status: responseStatusCode, 68 | }) 69 | ); 70 | 71 | pipe(body); 72 | }, 73 | onShellError(error: unknown) { 74 | reject(error); 75 | }, 76 | onError(error: unknown) { 77 | responseStatusCode = 500; 78 | // Log streaming rendering errors from inside the shell. Don't log 79 | // errors encountered during initial shell rendering since they'll 80 | // reject and get logged in handleDocumentRequest. 81 | if (shellRendered) { 82 | console.error(error); 83 | } 84 | }, 85 | } 86 | ); 87 | 88 | setTimeout(abort, ABORT_DELAY); 89 | }); 90 | } 91 | 92 | function handleBrowserRequest( 93 | request: Request, 94 | responseStatusCode: number, 95 | responseHeaders: Headers, 96 | remixContext: EntryContext 97 | ) { 98 | return new Promise((resolve, reject) => { 99 | let shellRendered = false; 100 | const { pipe, abort } = renderToPipeableStream( 101 | , 106 | { 107 | onShellReady() { 108 | shellRendered = true; 109 | const body = new PassThrough(); 110 | const stream = createReadableStreamFromReadable(body); 111 | 112 | responseHeaders.set("Content-Type", "text/html"); 113 | 114 | resolve( 115 | new Response(stream, { 116 | headers: responseHeaders, 117 | status: responseStatusCode, 118 | }) 119 | ); 120 | 121 | pipe(body); 122 | }, 123 | onShellError(error: unknown) { 124 | reject(error); 125 | }, 126 | onError(error: unknown) { 127 | responseStatusCode = 500; 128 | // Log streaming rendering errors from inside the shell. Don't log 129 | // errors encountered during initial shell rendering since they'll 130 | // reject and get logged in handleDocumentRequest. 131 | if (shellRendered) { 132 | console.error(error); 133 | } 134 | }, 135 | } 136 | ); 137 | 138 | setTimeout(abort, ABORT_DELAY); 139 | }); 140 | } 141 | -------------------------------------------------------------------------------- /modules/next/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "next", 9 | "version": "0.1.0", 10 | "dependencies": { 11 | "next": "14.1.4", 12 | "react": "^18", 13 | "react-dom": "^18" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20", 17 | "@types/react": "^18", 18 | "@types/react-dom": "^18", 19 | "typescript": "^5" 20 | } 21 | }, 22 | "node_modules/@next/env": { 23 | "version": "14.1.4", 24 | "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz", 25 | "integrity": "sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==" 26 | }, 27 | "node_modules/@next/swc-darwin-arm64": { 28 | "version": "14.1.4", 29 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz", 30 | "integrity": "sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==", 31 | "cpu": [ 32 | "arm64" 33 | ], 34 | "optional": true, 35 | "os": [ 36 | "darwin" 37 | ], 38 | "engines": { 39 | "node": ">= 10" 40 | } 41 | }, 42 | "node_modules/@next/swc-darwin-x64": { 43 | "version": "14.1.4", 44 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz", 45 | "integrity": "sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==", 46 | "cpu": [ 47 | "x64" 48 | ], 49 | "optional": true, 50 | "os": [ 51 | "darwin" 52 | ], 53 | "engines": { 54 | "node": ">= 10" 55 | } 56 | }, 57 | "node_modules/@next/swc-linux-arm64-gnu": { 58 | "version": "14.1.4", 59 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz", 60 | "integrity": "sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==", 61 | "cpu": [ 62 | "arm64" 63 | ], 64 | "optional": true, 65 | "os": [ 66 | "linux" 67 | ], 68 | "engines": { 69 | "node": ">= 10" 70 | } 71 | }, 72 | "node_modules/@next/swc-linux-arm64-musl": { 73 | "version": "14.1.4", 74 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz", 75 | "integrity": "sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==", 76 | "cpu": [ 77 | "arm64" 78 | ], 79 | "optional": true, 80 | "os": [ 81 | "linux" 82 | ], 83 | "engines": { 84 | "node": ">= 10" 85 | } 86 | }, 87 | "node_modules/@next/swc-linux-x64-gnu": { 88 | "version": "14.1.4", 89 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz", 90 | "integrity": "sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==", 91 | "cpu": [ 92 | "x64" 93 | ], 94 | "optional": true, 95 | "os": [ 96 | "linux" 97 | ], 98 | "engines": { 99 | "node": ">= 10" 100 | } 101 | }, 102 | "node_modules/@next/swc-linux-x64-musl": { 103 | "version": "14.1.4", 104 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz", 105 | "integrity": "sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==", 106 | "cpu": [ 107 | "x64" 108 | ], 109 | "optional": true, 110 | "os": [ 111 | "linux" 112 | ], 113 | "engines": { 114 | "node": ">= 10" 115 | } 116 | }, 117 | "node_modules/@next/swc-win32-arm64-msvc": { 118 | "version": "14.1.4", 119 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz", 120 | "integrity": "sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==", 121 | "cpu": [ 122 | "arm64" 123 | ], 124 | "optional": true, 125 | "os": [ 126 | "win32" 127 | ], 128 | "engines": { 129 | "node": ">= 10" 130 | } 131 | }, 132 | "node_modules/@next/swc-win32-ia32-msvc": { 133 | "version": "14.1.4", 134 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz", 135 | "integrity": "sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==", 136 | "cpu": [ 137 | "ia32" 138 | ], 139 | "optional": true, 140 | "os": [ 141 | "win32" 142 | ], 143 | "engines": { 144 | "node": ">= 10" 145 | } 146 | }, 147 | "node_modules/@next/swc-win32-x64-msvc": { 148 | "version": "14.1.4", 149 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz", 150 | "integrity": "sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==", 151 | "cpu": [ 152 | "x64" 153 | ], 154 | "optional": true, 155 | "os": [ 156 | "win32" 157 | ], 158 | "engines": { 159 | "node": ">= 10" 160 | } 161 | }, 162 | "node_modules/@swc/helpers": { 163 | "version": "0.5.2", 164 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", 165 | "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", 166 | "dependencies": { 167 | "tslib": "^2.4.0" 168 | } 169 | }, 170 | "node_modules/@types/node": { 171 | "version": "20.12.6", 172 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", 173 | "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", 174 | "dev": true, 175 | "dependencies": { 176 | "undici-types": "~5.26.4" 177 | } 178 | }, 179 | "node_modules/@types/prop-types": { 180 | "version": "15.7.12", 181 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", 182 | "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", 183 | "dev": true 184 | }, 185 | "node_modules/@types/react": { 186 | "version": "18.2.75", 187 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.75.tgz", 188 | "integrity": "sha512-+DNnF7yc5y0bHkBTiLKqXFe+L4B3nvOphiMY3tuA5X10esmjqk7smyBZzbGTy2vsiy/Bnzj8yFIBL8xhRacoOg==", 189 | "dev": true, 190 | "dependencies": { 191 | "@types/prop-types": "*", 192 | "csstype": "^3.0.2" 193 | } 194 | }, 195 | "node_modules/@types/react-dom": { 196 | "version": "18.2.24", 197 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.24.tgz", 198 | "integrity": "sha512-cN6upcKd8zkGy4HU9F1+/s98Hrp6D4MOcippK4PoE8OZRngohHZpbJn1GsaDLz87MqvHNoT13nHvNqM9ocRHZg==", 199 | "dev": true, 200 | "dependencies": { 201 | "@types/react": "*" 202 | } 203 | }, 204 | "node_modules/busboy": { 205 | "version": "1.6.0", 206 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", 207 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", 208 | "dependencies": { 209 | "streamsearch": "^1.1.0" 210 | }, 211 | "engines": { 212 | "node": ">=10.16.0" 213 | } 214 | }, 215 | "node_modules/caniuse-lite": { 216 | "version": "1.0.30001607", 217 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001607.tgz", 218 | "integrity": "sha512-WcvhVRjXLKFB/kmOFVwELtMxyhq3iM/MvmXcyCe2PNf166c39mptscOc/45TTS96n2gpNV2z7+NakArTWZCQ3w==", 219 | "funding": [ 220 | { 221 | "type": "opencollective", 222 | "url": "https://opencollective.com/browserslist" 223 | }, 224 | { 225 | "type": "tidelift", 226 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 227 | }, 228 | { 229 | "type": "github", 230 | "url": "https://github.com/sponsors/ai" 231 | } 232 | ] 233 | }, 234 | "node_modules/client-only": { 235 | "version": "0.0.1", 236 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", 237 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" 238 | }, 239 | "node_modules/csstype": { 240 | "version": "3.1.3", 241 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", 242 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", 243 | "dev": true 244 | }, 245 | "node_modules/graceful-fs": { 246 | "version": "4.2.11", 247 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 248 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 249 | }, 250 | "node_modules/js-tokens": { 251 | "version": "4.0.0", 252 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 253 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 254 | }, 255 | "node_modules/loose-envify": { 256 | "version": "1.4.0", 257 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 258 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 259 | "dependencies": { 260 | "js-tokens": "^3.0.0 || ^4.0.0" 261 | }, 262 | "bin": { 263 | "loose-envify": "cli.js" 264 | } 265 | }, 266 | "node_modules/nanoid": { 267 | "version": "3.3.7", 268 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 269 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 270 | "funding": [ 271 | { 272 | "type": "github", 273 | "url": "https://github.com/sponsors/ai" 274 | } 275 | ], 276 | "bin": { 277 | "nanoid": "bin/nanoid.cjs" 278 | }, 279 | "engines": { 280 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 281 | } 282 | }, 283 | "node_modules/next": { 284 | "version": "14.1.4", 285 | "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz", 286 | "integrity": "sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==", 287 | "dependencies": { 288 | "@next/env": "14.1.4", 289 | "@swc/helpers": "0.5.2", 290 | "busboy": "1.6.0", 291 | "caniuse-lite": "^1.0.30001579", 292 | "graceful-fs": "^4.2.11", 293 | "postcss": "8.4.31", 294 | "styled-jsx": "5.1.1" 295 | }, 296 | "bin": { 297 | "next": "dist/bin/next" 298 | }, 299 | "engines": { 300 | "node": ">=18.17.0" 301 | }, 302 | "optionalDependencies": { 303 | "@next/swc-darwin-arm64": "14.1.4", 304 | "@next/swc-darwin-x64": "14.1.4", 305 | "@next/swc-linux-arm64-gnu": "14.1.4", 306 | "@next/swc-linux-arm64-musl": "14.1.4", 307 | "@next/swc-linux-x64-gnu": "14.1.4", 308 | "@next/swc-linux-x64-musl": "14.1.4", 309 | "@next/swc-win32-arm64-msvc": "14.1.4", 310 | "@next/swc-win32-ia32-msvc": "14.1.4", 311 | "@next/swc-win32-x64-msvc": "14.1.4" 312 | }, 313 | "peerDependencies": { 314 | "@opentelemetry/api": "^1.1.0", 315 | "react": "^18.2.0", 316 | "react-dom": "^18.2.0", 317 | "sass": "^1.3.0" 318 | }, 319 | "peerDependenciesMeta": { 320 | "@opentelemetry/api": { 321 | "optional": true 322 | }, 323 | "sass": { 324 | "optional": true 325 | } 326 | } 327 | }, 328 | "node_modules/picocolors": { 329 | "version": "1.0.0", 330 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 331 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" 332 | }, 333 | "node_modules/postcss": { 334 | "version": "8.4.31", 335 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 336 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 337 | "funding": [ 338 | { 339 | "type": "opencollective", 340 | "url": "https://opencollective.com/postcss/" 341 | }, 342 | { 343 | "type": "tidelift", 344 | "url": "https://tidelift.com/funding/github/npm/postcss" 345 | }, 346 | { 347 | "type": "github", 348 | "url": "https://github.com/sponsors/ai" 349 | } 350 | ], 351 | "dependencies": { 352 | "nanoid": "^3.3.6", 353 | "picocolors": "^1.0.0", 354 | "source-map-js": "^1.0.2" 355 | }, 356 | "engines": { 357 | "node": "^10 || ^12 || >=14" 358 | } 359 | }, 360 | "node_modules/react": { 361 | "version": "18.2.0", 362 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", 363 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", 364 | "dependencies": { 365 | "loose-envify": "^1.1.0" 366 | }, 367 | "engines": { 368 | "node": ">=0.10.0" 369 | } 370 | }, 371 | "node_modules/react-dom": { 372 | "version": "18.2.0", 373 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", 374 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", 375 | "dependencies": { 376 | "loose-envify": "^1.1.0", 377 | "scheduler": "^0.23.0" 378 | }, 379 | "peerDependencies": { 380 | "react": "^18.2.0" 381 | } 382 | }, 383 | "node_modules/scheduler": { 384 | "version": "0.23.0", 385 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", 386 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", 387 | "dependencies": { 388 | "loose-envify": "^1.1.0" 389 | } 390 | }, 391 | "node_modules/source-map-js": { 392 | "version": "1.2.0", 393 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 394 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 395 | "engines": { 396 | "node": ">=0.10.0" 397 | } 398 | }, 399 | "node_modules/streamsearch": { 400 | "version": "1.1.0", 401 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", 402 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", 403 | "engines": { 404 | "node": ">=10.0.0" 405 | } 406 | }, 407 | "node_modules/styled-jsx": { 408 | "version": "5.1.1", 409 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", 410 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", 411 | "dependencies": { 412 | "client-only": "0.0.1" 413 | }, 414 | "engines": { 415 | "node": ">= 12.0.0" 416 | }, 417 | "peerDependencies": { 418 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" 419 | }, 420 | "peerDependenciesMeta": { 421 | "@babel/core": { 422 | "optional": true 423 | }, 424 | "babel-plugin-macros": { 425 | "optional": true 426 | } 427 | } 428 | }, 429 | "node_modules/tslib": { 430 | "version": "2.6.2", 431 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", 432 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" 433 | }, 434 | "node_modules/typescript": { 435 | "version": "5.4.4", 436 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", 437 | "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", 438 | "dev": true, 439 | "bin": { 440 | "tsc": "bin/tsc", 441 | "tsserver": "bin/tsserver" 442 | }, 443 | "engines": { 444 | "node": ">=14.17" 445 | } 446 | }, 447 | "node_modules/undici-types": { 448 | "version": "5.26.5", 449 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 450 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 451 | "dev": true 452 | } 453 | } 454 | } 455 | -------------------------------------------------------------------------------- /modules/solid/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solid", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "solid", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "solid-js": "^1.8.7" 12 | }, 13 | "devDependencies": { 14 | "@types/express": "^4.17.21", 15 | "@types/node": "^20.12.7", 16 | "vite": "^5.0.10", 17 | "vite-plugin-solid": "^2.8.0" 18 | } 19 | }, 20 | "node_modules/@ampproject/remapping": { 21 | "version": "2.3.0", 22 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 23 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 24 | "dev": true, 25 | "dependencies": { 26 | "@jridgewell/gen-mapping": "^0.3.5", 27 | "@jridgewell/trace-mapping": "^0.3.24" 28 | }, 29 | "engines": { 30 | "node": ">=6.0.0" 31 | } 32 | }, 33 | "node_modules/@babel/code-frame": { 34 | "version": "7.24.2", 35 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", 36 | "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", 37 | "dev": true, 38 | "dependencies": { 39 | "@babel/highlight": "^7.24.2", 40 | "picocolors": "^1.0.0" 41 | }, 42 | "engines": { 43 | "node": ">=6.9.0" 44 | } 45 | }, 46 | "node_modules/@babel/compat-data": { 47 | "version": "7.24.4", 48 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", 49 | "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", 50 | "dev": true, 51 | "engines": { 52 | "node": ">=6.9.0" 53 | } 54 | }, 55 | "node_modules/@babel/core": { 56 | "version": "7.24.4", 57 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", 58 | "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", 59 | "dev": true, 60 | "dependencies": { 61 | "@ampproject/remapping": "^2.2.0", 62 | "@babel/code-frame": "^7.24.2", 63 | "@babel/generator": "^7.24.4", 64 | "@babel/helper-compilation-targets": "^7.23.6", 65 | "@babel/helper-module-transforms": "^7.23.3", 66 | "@babel/helpers": "^7.24.4", 67 | "@babel/parser": "^7.24.4", 68 | "@babel/template": "^7.24.0", 69 | "@babel/traverse": "^7.24.1", 70 | "@babel/types": "^7.24.0", 71 | "convert-source-map": "^2.0.0", 72 | "debug": "^4.1.0", 73 | "gensync": "^1.0.0-beta.2", 74 | "json5": "^2.2.3", 75 | "semver": "^6.3.1" 76 | }, 77 | "engines": { 78 | "node": ">=6.9.0" 79 | }, 80 | "funding": { 81 | "type": "opencollective", 82 | "url": "https://opencollective.com/babel" 83 | } 84 | }, 85 | "node_modules/@babel/generator": { 86 | "version": "7.24.4", 87 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", 88 | "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", 89 | "dev": true, 90 | "dependencies": { 91 | "@babel/types": "^7.24.0", 92 | "@jridgewell/gen-mapping": "^0.3.5", 93 | "@jridgewell/trace-mapping": "^0.3.25", 94 | "jsesc": "^2.5.1" 95 | }, 96 | "engines": { 97 | "node": ">=6.9.0" 98 | } 99 | }, 100 | "node_modules/@babel/helper-compilation-targets": { 101 | "version": "7.23.6", 102 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", 103 | "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", 104 | "dev": true, 105 | "dependencies": { 106 | "@babel/compat-data": "^7.23.5", 107 | "@babel/helper-validator-option": "^7.23.5", 108 | "browserslist": "^4.22.2", 109 | "lru-cache": "^5.1.1", 110 | "semver": "^6.3.1" 111 | }, 112 | "engines": { 113 | "node": ">=6.9.0" 114 | } 115 | }, 116 | "node_modules/@babel/helper-environment-visitor": { 117 | "version": "7.22.20", 118 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", 119 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", 120 | "dev": true, 121 | "engines": { 122 | "node": ">=6.9.0" 123 | } 124 | }, 125 | "node_modules/@babel/helper-function-name": { 126 | "version": "7.23.0", 127 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", 128 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", 129 | "dev": true, 130 | "dependencies": { 131 | "@babel/template": "^7.22.15", 132 | "@babel/types": "^7.23.0" 133 | }, 134 | "engines": { 135 | "node": ">=6.9.0" 136 | } 137 | }, 138 | "node_modules/@babel/helper-hoist-variables": { 139 | "version": "7.22.5", 140 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", 141 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", 142 | "dev": true, 143 | "dependencies": { 144 | "@babel/types": "^7.22.5" 145 | }, 146 | "engines": { 147 | "node": ">=6.9.0" 148 | } 149 | }, 150 | "node_modules/@babel/helper-module-imports": { 151 | "version": "7.24.3", 152 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", 153 | "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", 154 | "dev": true, 155 | "dependencies": { 156 | "@babel/types": "^7.24.0" 157 | }, 158 | "engines": { 159 | "node": ">=6.9.0" 160 | } 161 | }, 162 | "node_modules/@babel/helper-module-transforms": { 163 | "version": "7.23.3", 164 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", 165 | "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", 166 | "dev": true, 167 | "dependencies": { 168 | "@babel/helper-environment-visitor": "^7.22.20", 169 | "@babel/helper-module-imports": "^7.22.15", 170 | "@babel/helper-simple-access": "^7.22.5", 171 | "@babel/helper-split-export-declaration": "^7.22.6", 172 | "@babel/helper-validator-identifier": "^7.22.20" 173 | }, 174 | "engines": { 175 | "node": ">=6.9.0" 176 | }, 177 | "peerDependencies": { 178 | "@babel/core": "^7.0.0" 179 | } 180 | }, 181 | "node_modules/@babel/helper-plugin-utils": { 182 | "version": "7.24.0", 183 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", 184 | "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", 185 | "dev": true, 186 | "engines": { 187 | "node": ">=6.9.0" 188 | } 189 | }, 190 | "node_modules/@babel/helper-simple-access": { 191 | "version": "7.22.5", 192 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", 193 | "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", 194 | "dev": true, 195 | "dependencies": { 196 | "@babel/types": "^7.22.5" 197 | }, 198 | "engines": { 199 | "node": ">=6.9.0" 200 | } 201 | }, 202 | "node_modules/@babel/helper-split-export-declaration": { 203 | "version": "7.22.6", 204 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", 205 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", 206 | "dev": true, 207 | "dependencies": { 208 | "@babel/types": "^7.22.5" 209 | }, 210 | "engines": { 211 | "node": ">=6.9.0" 212 | } 213 | }, 214 | "node_modules/@babel/helper-string-parser": { 215 | "version": "7.24.1", 216 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", 217 | "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", 218 | "dev": true, 219 | "engines": { 220 | "node": ">=6.9.0" 221 | } 222 | }, 223 | "node_modules/@babel/helper-validator-identifier": { 224 | "version": "7.22.20", 225 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", 226 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", 227 | "dev": true, 228 | "engines": { 229 | "node": ">=6.9.0" 230 | } 231 | }, 232 | "node_modules/@babel/helper-validator-option": { 233 | "version": "7.23.5", 234 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", 235 | "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", 236 | "dev": true, 237 | "engines": { 238 | "node": ">=6.9.0" 239 | } 240 | }, 241 | "node_modules/@babel/helpers": { 242 | "version": "7.24.4", 243 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", 244 | "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", 245 | "dev": true, 246 | "dependencies": { 247 | "@babel/template": "^7.24.0", 248 | "@babel/traverse": "^7.24.1", 249 | "@babel/types": "^7.24.0" 250 | }, 251 | "engines": { 252 | "node": ">=6.9.0" 253 | } 254 | }, 255 | "node_modules/@babel/highlight": { 256 | "version": "7.24.2", 257 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", 258 | "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", 259 | "dev": true, 260 | "dependencies": { 261 | "@babel/helper-validator-identifier": "^7.22.20", 262 | "chalk": "^2.4.2", 263 | "js-tokens": "^4.0.0", 264 | "picocolors": "^1.0.0" 265 | }, 266 | "engines": { 267 | "node": ">=6.9.0" 268 | } 269 | }, 270 | "node_modules/@babel/parser": { 271 | "version": "7.24.4", 272 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", 273 | "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", 274 | "dev": true, 275 | "bin": { 276 | "parser": "bin/babel-parser.js" 277 | }, 278 | "engines": { 279 | "node": ">=6.0.0" 280 | } 281 | }, 282 | "node_modules/@babel/plugin-syntax-jsx": { 283 | "version": "7.24.1", 284 | "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", 285 | "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", 286 | "dev": true, 287 | "dependencies": { 288 | "@babel/helper-plugin-utils": "^7.24.0" 289 | }, 290 | "engines": { 291 | "node": ">=6.9.0" 292 | }, 293 | "peerDependencies": { 294 | "@babel/core": "^7.0.0-0" 295 | } 296 | }, 297 | "node_modules/@babel/template": { 298 | "version": "7.24.0", 299 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", 300 | "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", 301 | "dev": true, 302 | "dependencies": { 303 | "@babel/code-frame": "^7.23.5", 304 | "@babel/parser": "^7.24.0", 305 | "@babel/types": "^7.24.0" 306 | }, 307 | "engines": { 308 | "node": ">=6.9.0" 309 | } 310 | }, 311 | "node_modules/@babel/traverse": { 312 | "version": "7.24.1", 313 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", 314 | "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", 315 | "dev": true, 316 | "dependencies": { 317 | "@babel/code-frame": "^7.24.1", 318 | "@babel/generator": "^7.24.1", 319 | "@babel/helper-environment-visitor": "^7.22.20", 320 | "@babel/helper-function-name": "^7.23.0", 321 | "@babel/helper-hoist-variables": "^7.22.5", 322 | "@babel/helper-split-export-declaration": "^7.22.6", 323 | "@babel/parser": "^7.24.1", 324 | "@babel/types": "^7.24.0", 325 | "debug": "^4.3.1", 326 | "globals": "^11.1.0" 327 | }, 328 | "engines": { 329 | "node": ">=6.9.0" 330 | } 331 | }, 332 | "node_modules/@babel/types": { 333 | "version": "7.24.0", 334 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", 335 | "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", 336 | "dev": true, 337 | "dependencies": { 338 | "@babel/helper-string-parser": "^7.23.4", 339 | "@babel/helper-validator-identifier": "^7.22.20", 340 | "to-fast-properties": "^2.0.0" 341 | }, 342 | "engines": { 343 | "node": ">=6.9.0" 344 | } 345 | }, 346 | "node_modules/@esbuild/aix-ppc64": { 347 | "version": "0.20.2", 348 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", 349 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", 350 | "cpu": [ 351 | "ppc64" 352 | ], 353 | "dev": true, 354 | "optional": true, 355 | "os": [ 356 | "aix" 357 | ], 358 | "engines": { 359 | "node": ">=12" 360 | } 361 | }, 362 | "node_modules/@esbuild/android-arm": { 363 | "version": "0.20.2", 364 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", 365 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", 366 | "cpu": [ 367 | "arm" 368 | ], 369 | "dev": true, 370 | "optional": true, 371 | "os": [ 372 | "android" 373 | ], 374 | "engines": { 375 | "node": ">=12" 376 | } 377 | }, 378 | "node_modules/@esbuild/android-arm64": { 379 | "version": "0.20.2", 380 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", 381 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", 382 | "cpu": [ 383 | "arm64" 384 | ], 385 | "dev": true, 386 | "optional": true, 387 | "os": [ 388 | "android" 389 | ], 390 | "engines": { 391 | "node": ">=12" 392 | } 393 | }, 394 | "node_modules/@esbuild/android-x64": { 395 | "version": "0.20.2", 396 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", 397 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", 398 | "cpu": [ 399 | "x64" 400 | ], 401 | "dev": true, 402 | "optional": true, 403 | "os": [ 404 | "android" 405 | ], 406 | "engines": { 407 | "node": ">=12" 408 | } 409 | }, 410 | "node_modules/@esbuild/darwin-arm64": { 411 | "version": "0.20.2", 412 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", 413 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", 414 | "cpu": [ 415 | "arm64" 416 | ], 417 | "dev": true, 418 | "optional": true, 419 | "os": [ 420 | "darwin" 421 | ], 422 | "engines": { 423 | "node": ">=12" 424 | } 425 | }, 426 | "node_modules/@esbuild/darwin-x64": { 427 | "version": "0.20.2", 428 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", 429 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", 430 | "cpu": [ 431 | "x64" 432 | ], 433 | "dev": true, 434 | "optional": true, 435 | "os": [ 436 | "darwin" 437 | ], 438 | "engines": { 439 | "node": ">=12" 440 | } 441 | }, 442 | "node_modules/@esbuild/freebsd-arm64": { 443 | "version": "0.20.2", 444 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", 445 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", 446 | "cpu": [ 447 | "arm64" 448 | ], 449 | "dev": true, 450 | "optional": true, 451 | "os": [ 452 | "freebsd" 453 | ], 454 | "engines": { 455 | "node": ">=12" 456 | } 457 | }, 458 | "node_modules/@esbuild/freebsd-x64": { 459 | "version": "0.20.2", 460 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", 461 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", 462 | "cpu": [ 463 | "x64" 464 | ], 465 | "dev": true, 466 | "optional": true, 467 | "os": [ 468 | "freebsd" 469 | ], 470 | "engines": { 471 | "node": ">=12" 472 | } 473 | }, 474 | "node_modules/@esbuild/linux-arm": { 475 | "version": "0.20.2", 476 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", 477 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", 478 | "cpu": [ 479 | "arm" 480 | ], 481 | "dev": true, 482 | "optional": true, 483 | "os": [ 484 | "linux" 485 | ], 486 | "engines": { 487 | "node": ">=12" 488 | } 489 | }, 490 | "node_modules/@esbuild/linux-arm64": { 491 | "version": "0.20.2", 492 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", 493 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", 494 | "cpu": [ 495 | "arm64" 496 | ], 497 | "dev": true, 498 | "optional": true, 499 | "os": [ 500 | "linux" 501 | ], 502 | "engines": { 503 | "node": ">=12" 504 | } 505 | }, 506 | "node_modules/@esbuild/linux-ia32": { 507 | "version": "0.20.2", 508 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", 509 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", 510 | "cpu": [ 511 | "ia32" 512 | ], 513 | "dev": true, 514 | "optional": true, 515 | "os": [ 516 | "linux" 517 | ], 518 | "engines": { 519 | "node": ">=12" 520 | } 521 | }, 522 | "node_modules/@esbuild/linux-loong64": { 523 | "version": "0.20.2", 524 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", 525 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", 526 | "cpu": [ 527 | "loong64" 528 | ], 529 | "dev": true, 530 | "optional": true, 531 | "os": [ 532 | "linux" 533 | ], 534 | "engines": { 535 | "node": ">=12" 536 | } 537 | }, 538 | "node_modules/@esbuild/linux-mips64el": { 539 | "version": "0.20.2", 540 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", 541 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", 542 | "cpu": [ 543 | "mips64el" 544 | ], 545 | "dev": true, 546 | "optional": true, 547 | "os": [ 548 | "linux" 549 | ], 550 | "engines": { 551 | "node": ">=12" 552 | } 553 | }, 554 | "node_modules/@esbuild/linux-ppc64": { 555 | "version": "0.20.2", 556 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", 557 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", 558 | "cpu": [ 559 | "ppc64" 560 | ], 561 | "dev": true, 562 | "optional": true, 563 | "os": [ 564 | "linux" 565 | ], 566 | "engines": { 567 | "node": ">=12" 568 | } 569 | }, 570 | "node_modules/@esbuild/linux-riscv64": { 571 | "version": "0.20.2", 572 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", 573 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", 574 | "cpu": [ 575 | "riscv64" 576 | ], 577 | "dev": true, 578 | "optional": true, 579 | "os": [ 580 | "linux" 581 | ], 582 | "engines": { 583 | "node": ">=12" 584 | } 585 | }, 586 | "node_modules/@esbuild/linux-s390x": { 587 | "version": "0.20.2", 588 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", 589 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", 590 | "cpu": [ 591 | "s390x" 592 | ], 593 | "dev": true, 594 | "optional": true, 595 | "os": [ 596 | "linux" 597 | ], 598 | "engines": { 599 | "node": ">=12" 600 | } 601 | }, 602 | "node_modules/@esbuild/linux-x64": { 603 | "version": "0.20.2", 604 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", 605 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", 606 | "cpu": [ 607 | "x64" 608 | ], 609 | "dev": true, 610 | "optional": true, 611 | "os": [ 612 | "linux" 613 | ], 614 | "engines": { 615 | "node": ">=12" 616 | } 617 | }, 618 | "node_modules/@esbuild/netbsd-x64": { 619 | "version": "0.20.2", 620 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", 621 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", 622 | "cpu": [ 623 | "x64" 624 | ], 625 | "dev": true, 626 | "optional": true, 627 | "os": [ 628 | "netbsd" 629 | ], 630 | "engines": { 631 | "node": ">=12" 632 | } 633 | }, 634 | "node_modules/@esbuild/openbsd-x64": { 635 | "version": "0.20.2", 636 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", 637 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", 638 | "cpu": [ 639 | "x64" 640 | ], 641 | "dev": true, 642 | "optional": true, 643 | "os": [ 644 | "openbsd" 645 | ], 646 | "engines": { 647 | "node": ">=12" 648 | } 649 | }, 650 | "node_modules/@esbuild/sunos-x64": { 651 | "version": "0.20.2", 652 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", 653 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", 654 | "cpu": [ 655 | "x64" 656 | ], 657 | "dev": true, 658 | "optional": true, 659 | "os": [ 660 | "sunos" 661 | ], 662 | "engines": { 663 | "node": ">=12" 664 | } 665 | }, 666 | "node_modules/@esbuild/win32-arm64": { 667 | "version": "0.20.2", 668 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", 669 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", 670 | "cpu": [ 671 | "arm64" 672 | ], 673 | "dev": true, 674 | "optional": true, 675 | "os": [ 676 | "win32" 677 | ], 678 | "engines": { 679 | "node": ">=12" 680 | } 681 | }, 682 | "node_modules/@esbuild/win32-ia32": { 683 | "version": "0.20.2", 684 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", 685 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", 686 | "cpu": [ 687 | "ia32" 688 | ], 689 | "dev": true, 690 | "optional": true, 691 | "os": [ 692 | "win32" 693 | ], 694 | "engines": { 695 | "node": ">=12" 696 | } 697 | }, 698 | "node_modules/@esbuild/win32-x64": { 699 | "version": "0.20.2", 700 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", 701 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", 702 | "cpu": [ 703 | "x64" 704 | ], 705 | "dev": true, 706 | "optional": true, 707 | "os": [ 708 | "win32" 709 | ], 710 | "engines": { 711 | "node": ">=12" 712 | } 713 | }, 714 | "node_modules/@jridgewell/gen-mapping": { 715 | "version": "0.3.5", 716 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 717 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 718 | "dev": true, 719 | "dependencies": { 720 | "@jridgewell/set-array": "^1.2.1", 721 | "@jridgewell/sourcemap-codec": "^1.4.10", 722 | "@jridgewell/trace-mapping": "^0.3.24" 723 | }, 724 | "engines": { 725 | "node": ">=6.0.0" 726 | } 727 | }, 728 | "node_modules/@jridgewell/resolve-uri": { 729 | "version": "3.1.2", 730 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 731 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 732 | "dev": true, 733 | "engines": { 734 | "node": ">=6.0.0" 735 | } 736 | }, 737 | "node_modules/@jridgewell/set-array": { 738 | "version": "1.2.1", 739 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 740 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 741 | "dev": true, 742 | "engines": { 743 | "node": ">=6.0.0" 744 | } 745 | }, 746 | "node_modules/@jridgewell/sourcemap-codec": { 747 | "version": "1.4.15", 748 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 749 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 750 | "dev": true 751 | }, 752 | "node_modules/@jridgewell/trace-mapping": { 753 | "version": "0.3.25", 754 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 755 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 756 | "dev": true, 757 | "dependencies": { 758 | "@jridgewell/resolve-uri": "^3.1.0", 759 | "@jridgewell/sourcemap-codec": "^1.4.14" 760 | } 761 | }, 762 | "node_modules/@rollup/rollup-android-arm-eabi": { 763 | "version": "4.14.1", 764 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", 765 | "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", 766 | "cpu": [ 767 | "arm" 768 | ], 769 | "dev": true, 770 | "optional": true, 771 | "os": [ 772 | "android" 773 | ] 774 | }, 775 | "node_modules/@rollup/rollup-android-arm64": { 776 | "version": "4.14.1", 777 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", 778 | "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", 779 | "cpu": [ 780 | "arm64" 781 | ], 782 | "dev": true, 783 | "optional": true, 784 | "os": [ 785 | "android" 786 | ] 787 | }, 788 | "node_modules/@rollup/rollup-darwin-arm64": { 789 | "version": "4.14.1", 790 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", 791 | "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", 792 | "cpu": [ 793 | "arm64" 794 | ], 795 | "dev": true, 796 | "optional": true, 797 | "os": [ 798 | "darwin" 799 | ] 800 | }, 801 | "node_modules/@rollup/rollup-darwin-x64": { 802 | "version": "4.14.1", 803 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", 804 | "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", 805 | "cpu": [ 806 | "x64" 807 | ], 808 | "dev": true, 809 | "optional": true, 810 | "os": [ 811 | "darwin" 812 | ] 813 | }, 814 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 815 | "version": "4.14.1", 816 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", 817 | "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", 818 | "cpu": [ 819 | "arm" 820 | ], 821 | "dev": true, 822 | "optional": true, 823 | "os": [ 824 | "linux" 825 | ] 826 | }, 827 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 828 | "version": "4.14.1", 829 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", 830 | "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", 831 | "cpu": [ 832 | "arm64" 833 | ], 834 | "dev": true, 835 | "optional": true, 836 | "os": [ 837 | "linux" 838 | ] 839 | }, 840 | "node_modules/@rollup/rollup-linux-arm64-musl": { 841 | "version": "4.14.1", 842 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", 843 | "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", 844 | "cpu": [ 845 | "arm64" 846 | ], 847 | "dev": true, 848 | "optional": true, 849 | "os": [ 850 | "linux" 851 | ] 852 | }, 853 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 854 | "version": "4.14.1", 855 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", 856 | "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", 857 | "cpu": [ 858 | "ppc64le" 859 | ], 860 | "dev": true, 861 | "optional": true, 862 | "os": [ 863 | "linux" 864 | ] 865 | }, 866 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 867 | "version": "4.14.1", 868 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", 869 | "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", 870 | "cpu": [ 871 | "riscv64" 872 | ], 873 | "dev": true, 874 | "optional": true, 875 | "os": [ 876 | "linux" 877 | ] 878 | }, 879 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 880 | "version": "4.14.1", 881 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", 882 | "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", 883 | "cpu": [ 884 | "s390x" 885 | ], 886 | "dev": true, 887 | "optional": true, 888 | "os": [ 889 | "linux" 890 | ] 891 | }, 892 | "node_modules/@rollup/rollup-linux-x64-gnu": { 893 | "version": "4.14.1", 894 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", 895 | "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", 896 | "cpu": [ 897 | "x64" 898 | ], 899 | "dev": true, 900 | "optional": true, 901 | "os": [ 902 | "linux" 903 | ] 904 | }, 905 | "node_modules/@rollup/rollup-linux-x64-musl": { 906 | "version": "4.14.1", 907 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", 908 | "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", 909 | "cpu": [ 910 | "x64" 911 | ], 912 | "dev": true, 913 | "optional": true, 914 | "os": [ 915 | "linux" 916 | ] 917 | }, 918 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 919 | "version": "4.14.1", 920 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", 921 | "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", 922 | "cpu": [ 923 | "arm64" 924 | ], 925 | "dev": true, 926 | "optional": true, 927 | "os": [ 928 | "win32" 929 | ] 930 | }, 931 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 932 | "version": "4.14.1", 933 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", 934 | "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", 935 | "cpu": [ 936 | "ia32" 937 | ], 938 | "dev": true, 939 | "optional": true, 940 | "os": [ 941 | "win32" 942 | ] 943 | }, 944 | "node_modules/@rollup/rollup-win32-x64-msvc": { 945 | "version": "4.14.1", 946 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", 947 | "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", 948 | "cpu": [ 949 | "x64" 950 | ], 951 | "dev": true, 952 | "optional": true, 953 | "os": [ 954 | "win32" 955 | ] 956 | }, 957 | "node_modules/@types/babel__core": { 958 | "version": "7.20.5", 959 | "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", 960 | "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", 961 | "dev": true, 962 | "dependencies": { 963 | "@babel/parser": "^7.20.7", 964 | "@babel/types": "^7.20.7", 965 | "@types/babel__generator": "*", 966 | "@types/babel__template": "*", 967 | "@types/babel__traverse": "*" 968 | } 969 | }, 970 | "node_modules/@types/babel__generator": { 971 | "version": "7.6.8", 972 | "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", 973 | "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", 974 | "dev": true, 975 | "dependencies": { 976 | "@babel/types": "^7.0.0" 977 | } 978 | }, 979 | "node_modules/@types/babel__template": { 980 | "version": "7.4.4", 981 | "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", 982 | "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", 983 | "dev": true, 984 | "dependencies": { 985 | "@babel/parser": "^7.1.0", 986 | "@babel/types": "^7.0.0" 987 | } 988 | }, 989 | "node_modules/@types/babel__traverse": { 990 | "version": "7.20.5", 991 | "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", 992 | "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", 993 | "dev": true, 994 | "dependencies": { 995 | "@babel/types": "^7.20.7" 996 | } 997 | }, 998 | "node_modules/@types/body-parser": { 999 | "version": "1.19.5", 1000 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", 1001 | "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", 1002 | "dev": true, 1003 | "dependencies": { 1004 | "@types/connect": "*", 1005 | "@types/node": "*" 1006 | } 1007 | }, 1008 | "node_modules/@types/connect": { 1009 | "version": "3.4.38", 1010 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", 1011 | "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", 1012 | "dev": true, 1013 | "dependencies": { 1014 | "@types/node": "*" 1015 | } 1016 | }, 1017 | "node_modules/@types/estree": { 1018 | "version": "1.0.5", 1019 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 1020 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 1021 | "dev": true 1022 | }, 1023 | "node_modules/@types/express": { 1024 | "version": "4.17.21", 1025 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", 1026 | "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", 1027 | "dev": true, 1028 | "dependencies": { 1029 | "@types/body-parser": "*", 1030 | "@types/express-serve-static-core": "^4.17.33", 1031 | "@types/qs": "*", 1032 | "@types/serve-static": "*" 1033 | } 1034 | }, 1035 | "node_modules/@types/express-serve-static-core": { 1036 | "version": "4.19.0", 1037 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", 1038 | "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", 1039 | "dev": true, 1040 | "dependencies": { 1041 | "@types/node": "*", 1042 | "@types/qs": "*", 1043 | "@types/range-parser": "*", 1044 | "@types/send": "*" 1045 | } 1046 | }, 1047 | "node_modules/@types/http-errors": { 1048 | "version": "2.0.4", 1049 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", 1050 | "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", 1051 | "dev": true 1052 | }, 1053 | "node_modules/@types/mime": { 1054 | "version": "1.3.5", 1055 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", 1056 | "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", 1057 | "dev": true 1058 | }, 1059 | "node_modules/@types/node": { 1060 | "version": "20.12.7", 1061 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", 1062 | "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", 1063 | "dev": true, 1064 | "dependencies": { 1065 | "undici-types": "~5.26.4" 1066 | } 1067 | }, 1068 | "node_modules/@types/qs": { 1069 | "version": "6.9.14", 1070 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", 1071 | "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", 1072 | "dev": true 1073 | }, 1074 | "node_modules/@types/range-parser": { 1075 | "version": "1.2.7", 1076 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", 1077 | "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", 1078 | "dev": true 1079 | }, 1080 | "node_modules/@types/send": { 1081 | "version": "0.17.4", 1082 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", 1083 | "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", 1084 | "dev": true, 1085 | "dependencies": { 1086 | "@types/mime": "^1", 1087 | "@types/node": "*" 1088 | } 1089 | }, 1090 | "node_modules/@types/serve-static": { 1091 | "version": "1.15.7", 1092 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", 1093 | "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", 1094 | "dev": true, 1095 | "dependencies": { 1096 | "@types/http-errors": "*", 1097 | "@types/node": "*", 1098 | "@types/send": "*" 1099 | } 1100 | }, 1101 | "node_modules/ansi-styles": { 1102 | "version": "3.2.1", 1103 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1104 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1105 | "dev": true, 1106 | "dependencies": { 1107 | "color-convert": "^1.9.0" 1108 | }, 1109 | "engines": { 1110 | "node": ">=4" 1111 | } 1112 | }, 1113 | "node_modules/babel-plugin-jsx-dom-expressions": { 1114 | "version": "0.37.19", 1115 | "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.37.19.tgz", 1116 | "integrity": "sha512-nef2eLpWBgFggwrYwN6O3dNKn3RnlX6n4DIamNEAeHwp03kVQUaKUiLaEPnHPJHwxie1KwPelyIY9QikU03vUA==", 1117 | "dev": true, 1118 | "dependencies": { 1119 | "@babel/helper-module-imports": "7.18.6", 1120 | "@babel/plugin-syntax-jsx": "^7.18.6", 1121 | "@babel/types": "^7.20.7", 1122 | "html-entities": "2.3.3", 1123 | "validate-html-nesting": "^1.2.1" 1124 | }, 1125 | "peerDependencies": { 1126 | "@babel/core": "^7.20.12" 1127 | } 1128 | }, 1129 | "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { 1130 | "version": "7.18.6", 1131 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", 1132 | "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", 1133 | "dev": true, 1134 | "dependencies": { 1135 | "@babel/types": "^7.18.6" 1136 | }, 1137 | "engines": { 1138 | "node": ">=6.9.0" 1139 | } 1140 | }, 1141 | "node_modules/babel-preset-solid": { 1142 | "version": "1.8.16", 1143 | "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.8.16.tgz", 1144 | "integrity": "sha512-b4HFg/xaKM+H3Tu5iUlZ/43TJOZnhi85xrm3JrXDQ0s4cmtmU37bXXYzb2m55G4QKiFjxLAjvb7sUorPrAMs5w==", 1145 | "dev": true, 1146 | "dependencies": { 1147 | "babel-plugin-jsx-dom-expressions": "^0.37.19" 1148 | }, 1149 | "peerDependencies": { 1150 | "@babel/core": "^7.0.0" 1151 | } 1152 | }, 1153 | "node_modules/browserslist": { 1154 | "version": "4.23.0", 1155 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", 1156 | "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", 1157 | "dev": true, 1158 | "funding": [ 1159 | { 1160 | "type": "opencollective", 1161 | "url": "https://opencollective.com/browserslist" 1162 | }, 1163 | { 1164 | "type": "tidelift", 1165 | "url": "https://tidelift.com/funding/github/npm/browserslist" 1166 | }, 1167 | { 1168 | "type": "github", 1169 | "url": "https://github.com/sponsors/ai" 1170 | } 1171 | ], 1172 | "dependencies": { 1173 | "caniuse-lite": "^1.0.30001587", 1174 | "electron-to-chromium": "^1.4.668", 1175 | "node-releases": "^2.0.14", 1176 | "update-browserslist-db": "^1.0.13" 1177 | }, 1178 | "bin": { 1179 | "browserslist": "cli.js" 1180 | }, 1181 | "engines": { 1182 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 1183 | } 1184 | }, 1185 | "node_modules/caniuse-lite": { 1186 | "version": "1.0.30001608", 1187 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001608.tgz", 1188 | "integrity": "sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA==", 1189 | "dev": true, 1190 | "funding": [ 1191 | { 1192 | "type": "opencollective", 1193 | "url": "https://opencollective.com/browserslist" 1194 | }, 1195 | { 1196 | "type": "tidelift", 1197 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 1198 | }, 1199 | { 1200 | "type": "github", 1201 | "url": "https://github.com/sponsors/ai" 1202 | } 1203 | ] 1204 | }, 1205 | "node_modules/chalk": { 1206 | "version": "2.4.2", 1207 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1208 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1209 | "dev": true, 1210 | "dependencies": { 1211 | "ansi-styles": "^3.2.1", 1212 | "escape-string-regexp": "^1.0.5", 1213 | "supports-color": "^5.3.0" 1214 | }, 1215 | "engines": { 1216 | "node": ">=4" 1217 | } 1218 | }, 1219 | "node_modules/color-convert": { 1220 | "version": "1.9.3", 1221 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1222 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1223 | "dev": true, 1224 | "dependencies": { 1225 | "color-name": "1.1.3" 1226 | } 1227 | }, 1228 | "node_modules/color-name": { 1229 | "version": "1.1.3", 1230 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1231 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 1232 | "dev": true 1233 | }, 1234 | "node_modules/convert-source-map": { 1235 | "version": "2.0.0", 1236 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", 1237 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 1238 | "dev": true 1239 | }, 1240 | "node_modules/csstype": { 1241 | "version": "3.1.3", 1242 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", 1243 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" 1244 | }, 1245 | "node_modules/debug": { 1246 | "version": "4.3.4", 1247 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1248 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1249 | "dev": true, 1250 | "dependencies": { 1251 | "ms": "2.1.2" 1252 | }, 1253 | "engines": { 1254 | "node": ">=6.0" 1255 | }, 1256 | "peerDependenciesMeta": { 1257 | "supports-color": { 1258 | "optional": true 1259 | } 1260 | } 1261 | }, 1262 | "node_modules/electron-to-chromium": { 1263 | "version": "1.4.731", 1264 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.731.tgz", 1265 | "integrity": "sha512-+TqVfZjpRz2V/5SPpmJxq9qK620SC5SqCnxQIOi7i/U08ZDcTpKbT7Xjj9FU5CbXTMUb4fywbIr8C7cGv4hcjw==", 1266 | "dev": true 1267 | }, 1268 | "node_modules/esbuild": { 1269 | "version": "0.20.2", 1270 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", 1271 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", 1272 | "dev": true, 1273 | "hasInstallScript": true, 1274 | "bin": { 1275 | "esbuild": "bin/esbuild" 1276 | }, 1277 | "engines": { 1278 | "node": ">=12" 1279 | }, 1280 | "optionalDependencies": { 1281 | "@esbuild/aix-ppc64": "0.20.2", 1282 | "@esbuild/android-arm": "0.20.2", 1283 | "@esbuild/android-arm64": "0.20.2", 1284 | "@esbuild/android-x64": "0.20.2", 1285 | "@esbuild/darwin-arm64": "0.20.2", 1286 | "@esbuild/darwin-x64": "0.20.2", 1287 | "@esbuild/freebsd-arm64": "0.20.2", 1288 | "@esbuild/freebsd-x64": "0.20.2", 1289 | "@esbuild/linux-arm": "0.20.2", 1290 | "@esbuild/linux-arm64": "0.20.2", 1291 | "@esbuild/linux-ia32": "0.20.2", 1292 | "@esbuild/linux-loong64": "0.20.2", 1293 | "@esbuild/linux-mips64el": "0.20.2", 1294 | "@esbuild/linux-ppc64": "0.20.2", 1295 | "@esbuild/linux-riscv64": "0.20.2", 1296 | "@esbuild/linux-s390x": "0.20.2", 1297 | "@esbuild/linux-x64": "0.20.2", 1298 | "@esbuild/netbsd-x64": "0.20.2", 1299 | "@esbuild/openbsd-x64": "0.20.2", 1300 | "@esbuild/sunos-x64": "0.20.2", 1301 | "@esbuild/win32-arm64": "0.20.2", 1302 | "@esbuild/win32-ia32": "0.20.2", 1303 | "@esbuild/win32-x64": "0.20.2" 1304 | } 1305 | }, 1306 | "node_modules/escalade": { 1307 | "version": "3.1.2", 1308 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", 1309 | "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", 1310 | "dev": true, 1311 | "engines": { 1312 | "node": ">=6" 1313 | } 1314 | }, 1315 | "node_modules/escape-string-regexp": { 1316 | "version": "1.0.5", 1317 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1318 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 1319 | "dev": true, 1320 | "engines": { 1321 | "node": ">=0.8.0" 1322 | } 1323 | }, 1324 | "node_modules/fsevents": { 1325 | "version": "2.3.3", 1326 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1327 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1328 | "dev": true, 1329 | "hasInstallScript": true, 1330 | "optional": true, 1331 | "os": [ 1332 | "darwin" 1333 | ], 1334 | "engines": { 1335 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1336 | } 1337 | }, 1338 | "node_modules/gensync": { 1339 | "version": "1.0.0-beta.2", 1340 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 1341 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 1342 | "dev": true, 1343 | "engines": { 1344 | "node": ">=6.9.0" 1345 | } 1346 | }, 1347 | "node_modules/globals": { 1348 | "version": "11.12.0", 1349 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1350 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1351 | "dev": true, 1352 | "engines": { 1353 | "node": ">=4" 1354 | } 1355 | }, 1356 | "node_modules/has-flag": { 1357 | "version": "3.0.0", 1358 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1359 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 1360 | "dev": true, 1361 | "engines": { 1362 | "node": ">=4" 1363 | } 1364 | }, 1365 | "node_modules/html-entities": { 1366 | "version": "2.3.3", 1367 | "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", 1368 | "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", 1369 | "dev": true 1370 | }, 1371 | "node_modules/is-what": { 1372 | "version": "4.1.16", 1373 | "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", 1374 | "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", 1375 | "dev": true, 1376 | "engines": { 1377 | "node": ">=12.13" 1378 | }, 1379 | "funding": { 1380 | "url": "https://github.com/sponsors/mesqueeb" 1381 | } 1382 | }, 1383 | "node_modules/js-tokens": { 1384 | "version": "4.0.0", 1385 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1386 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1387 | "dev": true 1388 | }, 1389 | "node_modules/jsesc": { 1390 | "version": "2.5.2", 1391 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1392 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1393 | "dev": true, 1394 | "bin": { 1395 | "jsesc": "bin/jsesc" 1396 | }, 1397 | "engines": { 1398 | "node": ">=4" 1399 | } 1400 | }, 1401 | "node_modules/json5": { 1402 | "version": "2.2.3", 1403 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", 1404 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", 1405 | "dev": true, 1406 | "bin": { 1407 | "json5": "lib/cli.js" 1408 | }, 1409 | "engines": { 1410 | "node": ">=6" 1411 | } 1412 | }, 1413 | "node_modules/lru-cache": { 1414 | "version": "5.1.1", 1415 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", 1416 | "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", 1417 | "dev": true, 1418 | "dependencies": { 1419 | "yallist": "^3.0.2" 1420 | } 1421 | }, 1422 | "node_modules/merge-anything": { 1423 | "version": "5.1.7", 1424 | "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-5.1.7.tgz", 1425 | "integrity": "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==", 1426 | "dev": true, 1427 | "dependencies": { 1428 | "is-what": "^4.1.8" 1429 | }, 1430 | "engines": { 1431 | "node": ">=12.13" 1432 | }, 1433 | "funding": { 1434 | "url": "https://github.com/sponsors/mesqueeb" 1435 | } 1436 | }, 1437 | "node_modules/ms": { 1438 | "version": "2.1.2", 1439 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1440 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1441 | "dev": true 1442 | }, 1443 | "node_modules/nanoid": { 1444 | "version": "3.3.7", 1445 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 1446 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 1447 | "dev": true, 1448 | "funding": [ 1449 | { 1450 | "type": "github", 1451 | "url": "https://github.com/sponsors/ai" 1452 | } 1453 | ], 1454 | "bin": { 1455 | "nanoid": "bin/nanoid.cjs" 1456 | }, 1457 | "engines": { 1458 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1459 | } 1460 | }, 1461 | "node_modules/node-releases": { 1462 | "version": "2.0.14", 1463 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", 1464 | "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", 1465 | "dev": true 1466 | }, 1467 | "node_modules/picocolors": { 1468 | "version": "1.0.0", 1469 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1470 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1471 | "dev": true 1472 | }, 1473 | "node_modules/postcss": { 1474 | "version": "8.4.38", 1475 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 1476 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 1477 | "dev": true, 1478 | "funding": [ 1479 | { 1480 | "type": "opencollective", 1481 | "url": "https://opencollective.com/postcss/" 1482 | }, 1483 | { 1484 | "type": "tidelift", 1485 | "url": "https://tidelift.com/funding/github/npm/postcss" 1486 | }, 1487 | { 1488 | "type": "github", 1489 | "url": "https://github.com/sponsors/ai" 1490 | } 1491 | ], 1492 | "dependencies": { 1493 | "nanoid": "^3.3.7", 1494 | "picocolors": "^1.0.0", 1495 | "source-map-js": "^1.2.0" 1496 | }, 1497 | "engines": { 1498 | "node": "^10 || ^12 || >=14" 1499 | } 1500 | }, 1501 | "node_modules/rollup": { 1502 | "version": "4.14.1", 1503 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", 1504 | "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", 1505 | "dev": true, 1506 | "dependencies": { 1507 | "@types/estree": "1.0.5" 1508 | }, 1509 | "bin": { 1510 | "rollup": "dist/bin/rollup" 1511 | }, 1512 | "engines": { 1513 | "node": ">=18.0.0", 1514 | "npm": ">=8.0.0" 1515 | }, 1516 | "optionalDependencies": { 1517 | "@rollup/rollup-android-arm-eabi": "4.14.1", 1518 | "@rollup/rollup-android-arm64": "4.14.1", 1519 | "@rollup/rollup-darwin-arm64": "4.14.1", 1520 | "@rollup/rollup-darwin-x64": "4.14.1", 1521 | "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", 1522 | "@rollup/rollup-linux-arm64-gnu": "4.14.1", 1523 | "@rollup/rollup-linux-arm64-musl": "4.14.1", 1524 | "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", 1525 | "@rollup/rollup-linux-riscv64-gnu": "4.14.1", 1526 | "@rollup/rollup-linux-s390x-gnu": "4.14.1", 1527 | "@rollup/rollup-linux-x64-gnu": "4.14.1", 1528 | "@rollup/rollup-linux-x64-musl": "4.14.1", 1529 | "@rollup/rollup-win32-arm64-msvc": "4.14.1", 1530 | "@rollup/rollup-win32-ia32-msvc": "4.14.1", 1531 | "@rollup/rollup-win32-x64-msvc": "4.14.1", 1532 | "fsevents": "~2.3.2" 1533 | } 1534 | }, 1535 | "node_modules/semver": { 1536 | "version": "6.3.1", 1537 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 1538 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 1539 | "dev": true, 1540 | "bin": { 1541 | "semver": "bin/semver.js" 1542 | } 1543 | }, 1544 | "node_modules/seroval": { 1545 | "version": "1.0.5", 1546 | "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.0.5.tgz", 1547 | "integrity": "sha512-TM+Z11tHHvQVQKeNlOUonOWnsNM+2IBwZ4vwoi4j3zKzIpc5IDw8WPwCfcc8F17wy6cBcJGbZbFOR0UCuTZHQA==", 1548 | "engines": { 1549 | "node": ">=10" 1550 | } 1551 | }, 1552 | "node_modules/seroval-plugins": { 1553 | "version": "1.0.5", 1554 | "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.0.5.tgz", 1555 | "integrity": "sha512-8+pDC1vOedPXjKG7oz8o+iiHrtF2WswaMQJ7CKFpccvSYfrzmvKY9zOJWCg+881722wIHfwkdnRmiiDm9ym+zQ==", 1556 | "engines": { 1557 | "node": ">=10" 1558 | }, 1559 | "peerDependencies": { 1560 | "seroval": "^1.0" 1561 | } 1562 | }, 1563 | "node_modules/solid-js": { 1564 | "version": "1.8.16", 1565 | "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.16.tgz", 1566 | "integrity": "sha512-rja94MNU9flF3qQRLNsu60QHKBDKBkVE1DldJZPIfn2ypIn3NV2WpSbGTQIvsyGPBo+9E2IMjwqnqpbgfWuzeg==", 1567 | "dependencies": { 1568 | "csstype": "^3.1.0", 1569 | "seroval": "^1.0.4", 1570 | "seroval-plugins": "^1.0.3" 1571 | } 1572 | }, 1573 | "node_modules/solid-refresh": { 1574 | "version": "0.6.3", 1575 | "resolved": "https://registry.npmjs.org/solid-refresh/-/solid-refresh-0.6.3.tgz", 1576 | "integrity": "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==", 1577 | "dev": true, 1578 | "dependencies": { 1579 | "@babel/generator": "^7.23.6", 1580 | "@babel/helper-module-imports": "^7.22.15", 1581 | "@babel/types": "^7.23.6" 1582 | }, 1583 | "peerDependencies": { 1584 | "solid-js": "^1.3" 1585 | } 1586 | }, 1587 | "node_modules/source-map-js": { 1588 | "version": "1.2.0", 1589 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 1590 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 1591 | "dev": true, 1592 | "engines": { 1593 | "node": ">=0.10.0" 1594 | } 1595 | }, 1596 | "node_modules/supports-color": { 1597 | "version": "5.5.0", 1598 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1599 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1600 | "dev": true, 1601 | "dependencies": { 1602 | "has-flag": "^3.0.0" 1603 | }, 1604 | "engines": { 1605 | "node": ">=4" 1606 | } 1607 | }, 1608 | "node_modules/to-fast-properties": { 1609 | "version": "2.0.0", 1610 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1611 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", 1612 | "dev": true, 1613 | "engines": { 1614 | "node": ">=4" 1615 | } 1616 | }, 1617 | "node_modules/undici-types": { 1618 | "version": "5.26.5", 1619 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1620 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1621 | "dev": true 1622 | }, 1623 | "node_modules/update-browserslist-db": { 1624 | "version": "1.0.13", 1625 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", 1626 | "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", 1627 | "dev": true, 1628 | "funding": [ 1629 | { 1630 | "type": "opencollective", 1631 | "url": "https://opencollective.com/browserslist" 1632 | }, 1633 | { 1634 | "type": "tidelift", 1635 | "url": "https://tidelift.com/funding/github/npm/browserslist" 1636 | }, 1637 | { 1638 | "type": "github", 1639 | "url": "https://github.com/sponsors/ai" 1640 | } 1641 | ], 1642 | "dependencies": { 1643 | "escalade": "^3.1.1", 1644 | "picocolors": "^1.0.0" 1645 | }, 1646 | "bin": { 1647 | "update-browserslist-db": "cli.js" 1648 | }, 1649 | "peerDependencies": { 1650 | "browserslist": ">= 4.21.0" 1651 | } 1652 | }, 1653 | "node_modules/validate-html-nesting": { 1654 | "version": "1.2.2", 1655 | "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", 1656 | "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==", 1657 | "dev": true 1658 | }, 1659 | "node_modules/vite": { 1660 | "version": "5.2.8", 1661 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", 1662 | "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", 1663 | "dev": true, 1664 | "dependencies": { 1665 | "esbuild": "^0.20.1", 1666 | "postcss": "^8.4.38", 1667 | "rollup": "^4.13.0" 1668 | }, 1669 | "bin": { 1670 | "vite": "bin/vite.js" 1671 | }, 1672 | "engines": { 1673 | "node": "^18.0.0 || >=20.0.0" 1674 | }, 1675 | "funding": { 1676 | "url": "https://github.com/vitejs/vite?sponsor=1" 1677 | }, 1678 | "optionalDependencies": { 1679 | "fsevents": "~2.3.3" 1680 | }, 1681 | "peerDependencies": { 1682 | "@types/node": "^18.0.0 || >=20.0.0", 1683 | "less": "*", 1684 | "lightningcss": "^1.21.0", 1685 | "sass": "*", 1686 | "stylus": "*", 1687 | "sugarss": "*", 1688 | "terser": "^5.4.0" 1689 | }, 1690 | "peerDependenciesMeta": { 1691 | "@types/node": { 1692 | "optional": true 1693 | }, 1694 | "less": { 1695 | "optional": true 1696 | }, 1697 | "lightningcss": { 1698 | "optional": true 1699 | }, 1700 | "sass": { 1701 | "optional": true 1702 | }, 1703 | "stylus": { 1704 | "optional": true 1705 | }, 1706 | "sugarss": { 1707 | "optional": true 1708 | }, 1709 | "terser": { 1710 | "optional": true 1711 | } 1712 | } 1713 | }, 1714 | "node_modules/vite-plugin-solid": { 1715 | "version": "2.10.2", 1716 | "resolved": "https://registry.npmjs.org/vite-plugin-solid/-/vite-plugin-solid-2.10.2.tgz", 1717 | "integrity": "sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==", 1718 | "dev": true, 1719 | "dependencies": { 1720 | "@babel/core": "^7.23.3", 1721 | "@types/babel__core": "^7.20.4", 1722 | "babel-preset-solid": "^1.8.4", 1723 | "merge-anything": "^5.1.7", 1724 | "solid-refresh": "^0.6.3", 1725 | "vitefu": "^0.2.5" 1726 | }, 1727 | "peerDependencies": { 1728 | "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", 1729 | "solid-js": "^1.7.2", 1730 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" 1731 | }, 1732 | "peerDependenciesMeta": { 1733 | "@testing-library/jest-dom": { 1734 | "optional": true 1735 | } 1736 | } 1737 | }, 1738 | "node_modules/vitefu": { 1739 | "version": "0.2.5", 1740 | "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", 1741 | "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", 1742 | "dev": true, 1743 | "peerDependencies": { 1744 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" 1745 | }, 1746 | "peerDependenciesMeta": { 1747 | "vite": { 1748 | "optional": true 1749 | } 1750 | } 1751 | }, 1752 | "node_modules/yallist": { 1753 | "version": "3.1.1", 1754 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 1755 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", 1756 | "dev": true 1757 | } 1758 | } 1759 | } 1760 | --------------------------------------------------------------------------------