create-waku 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/cli.js +4 -0
  2. package/dist/index.js +1 -2
  3. package/package.json +2 -2
  4. package/template/01_template/package.json +6 -6
  5. package/template/01_template/src/components/counter.tsx +7 -2
  6. package/template/01_template/src/components/footer.tsx +6 -1
  7. package/template/01_template/src/components/header.tsx +1 -1
  8. package/template/01_template/src/styles.css +1 -13
  9. package/template/01_template/src/templates/about-page.tsx +6 -3
  10. package/template/01_template/src/templates/home-page.tsx +5 -2
  11. package/template/01_template/src/templates/root-layout.tsx +1 -1
  12. package/template/{04_callserver → 02_demo}/package.json +8 -6
  13. package/template/02_demo/postcss.config.js +7 -0
  14. package/template/02_demo/public/images/favicon.png +0 -0
  15. package/template/02_demo/src/components/error-boundary.tsx +28 -0
  16. package/template/02_demo/src/components/footer.tsx +18 -0
  17. package/template/02_demo/src/components/header.tsx +11 -0
  18. package/template/02_demo/src/entries.tsx +29 -0
  19. package/template/02_demo/src/lib/index.ts +26 -0
  20. package/template/02_demo/src/lib/pokemon.ts +2586 -0
  21. package/template/{05_mutation → 02_demo}/src/main.tsx +6 -4
  22. package/template/02_demo/src/styles.css +5 -0
  23. package/template/02_demo/src/templates/home-page.tsx +35 -0
  24. package/template/02_demo/src/templates/pokemon-page.tsx +69 -0
  25. package/template/02_demo/src/templates/root-layout.tsx +33 -0
  26. package/template/02_demo/tailwind.config.js +10 -0
  27. package/template/{05_mutation → 02_demo}/tsconfig.json +4 -1
  28. package/template/{02_minimal → 03_minimal}/package.json +5 -5
  29. package/template/{03_promise → 04_promise}/package.json +5 -5
  30. package/template/{05_mutation → 05_actions}/package.json +5 -5
  31. package/template/{05_mutation → 05_actions}/src/components/App.tsx +3 -2
  32. package/template/{04_callserver → 05_actions}/src/components/Counter.tsx +15 -9
  33. package/template/{05_mutation → 05_actions}/src/components/funcs.ts +2 -0
  34. package/template/05_actions/vite.config.ts +6 -0
  35. package/template/06_nesting/package.json +5 -5
  36. package/template/07_router/package.json +5 -5
  37. package/template/08_cookies/dev.js +1 -1
  38. package/template/08_cookies/package.json +6 -6
  39. package/template/08_cookies/start.js +3 -4
  40. package/template/09_cssmodules/package.json +5 -5
  41. package/template/09_cssmodules/src/components/Layout.tsx +22 -0
  42. package/template/09_cssmodules/src/components/styles.css +3 -0
  43. package/template/09_cssmodules/src/entries.tsx +6 -1
  44. package/template/10_dynamicroute/package.json +5 -5
  45. package/template/10_dynamicroute/src/entries.tsx +17 -16
  46. package/template/10_dynamicroute/vite.config.ts +0 -3
  47. package/template/11_form/package.json +5 -5
  48. package/template/12_css/package.json +10 -10
  49. package/template/12_css/vite.config.ts +3 -8
  50. package/template/13_path-alias/package.json +7 -7
  51. package/template/13_path-alias/vite.config.ts +9 -4
  52. package/template/04_callserver/src/components/App.tsx +0 -20
  53. package/template/04_callserver/src/components/funcs.ts +0 -3
  54. package/template/04_callserver/src/entries.tsx +0 -31
  55. package/template/05_mutation/src/components/Counter.tsx +0 -24
  56. /package/template/{02_minimal → 03_minimal}/src/components/App.tsx +0 -0
  57. /package/template/{02_minimal → 03_minimal}/src/components/Counter.tsx +0 -0
  58. /package/template/{02_minimal → 03_minimal}/src/entries.tsx +0 -0
  59. /package/template/{02_minimal → 03_minimal}/src/main.tsx +0 -0
  60. /package/template/{02_minimal → 03_minimal}/tsconfig.json +0 -0
  61. /package/template/{03_promise → 04_promise}/src/components/App.tsx +0 -0
  62. /package/template/{03_promise → 04_promise}/src/components/Counter.tsx +0 -0
  63. /package/template/{03_promise → 04_promise}/src/entries.tsx +0 -0
  64. /package/template/{03_promise → 04_promise}/src/main.tsx +0 -0
  65. /package/template/{03_promise → 04_promise}/tsconfig.json +0 -0
  66. /package/template/{04_callserver → 05_actions}/src/components/TextBox.tsx +0 -0
  67. /package/template/{05_mutation → 05_actions}/src/entries.tsx +0 -0
  68. /package/template/{04_callserver → 05_actions}/src/main.tsx +0 -0
  69. /package/template/{04_callserver → 05_actions}/tsconfig.json +0 -0
@@ -1,12 +1,14 @@
1
1
  import { StrictMode } from 'react';
2
2
  import { createRoot, hydrateRoot } from 'react-dom/client';
3
- import { Root, Slot } from 'waku/client';
3
+ import { Router } from 'waku/router/client';
4
+
5
+ import { ErrorBoundary } from './components/error-boundary.js';
4
6
 
5
7
  const rootElement = (
6
8
  <StrictMode>
7
- <Root>
8
- <Slot id="App" />
9
- </Root>
9
+ <ErrorBoundary fallback={(error) => <h1>{String(error)}</h1>}>
10
+ <Router />
11
+ </ErrorBoundary>
10
12
  </StrictMode>
11
13
  );
12
14
 
@@ -0,0 +1,5 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,700;1,400;1,700&display=swap');
2
+ @import url('https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;700&display=swap');
3
+ @tailwind base;
4
+ @tailwind components;
5
+ @tailwind utilities;
@@ -0,0 +1,35 @@
1
+ import { Link } from 'waku';
2
+
3
+ import { sql } from '../lib/index.js';
4
+
5
+ export const HomePage = async () => {
6
+ const { rows } = await sql`SELECT * FROM pokemon ORDER BY RANDOM() LIMIT 9`;
7
+
8
+ return (
9
+ <>
10
+ <title>Waku Pokemon</title>
11
+ <ul className="grid h-full w-full max-w-xl grid-cols-2 gap-6 px-6 py-20 leading-none md:grid-cols-3 md:px-0">
12
+ {rows.map((row) => (
13
+ <li key={row.id}>
14
+ <Link
15
+ to={`/${row.slug}`}
16
+ className="flex aspect-square w-full flex-shrink-0 flex-col items-center justify-center rounded-xl bg-gray-50 p-3 text-gray-950 transition-colors duration-500 ease-in-out hover:bg-gray-200"
17
+ >
18
+ <img
19
+ src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${row.id}.png`}
20
+ alt={row.slug}
21
+ className="size-[96px]"
22
+ />
23
+ <div className="flex flex-col items-center justify-center gap-1 font-bold">
24
+ <span className="font-bold">{row.name.english}</span>
25
+ <span className="font-zen-maru-gothic text-[0.875em] font-bold opacity-40">
26
+ {row.name.japanese}
27
+ </span>
28
+ </div>
29
+ </Link>
30
+ </li>
31
+ ))}
32
+ </ul>
33
+ </>
34
+ );
35
+ };
@@ -0,0 +1,69 @@
1
+ import { Link } from 'waku';
2
+ import { pokemon } from '../lib/pokemon.js';
3
+
4
+ type PokemonPageProps = { slug: string };
5
+
6
+ export const PokemonPage = async ({ slug }: PokemonPageProps) => {
7
+ const pokemon = await getPokemon(slug);
8
+
9
+ if (!pokemon) return null;
10
+
11
+ const stats = Object.entries(pokemon.base);
12
+
13
+ return (
14
+ <>
15
+ <title>{`Waku ${pokemon.name.english}`}</title>
16
+ <div className="mx-auto flex w-1/2 flex-col items-center justify-center gap-6 leading-none md:w-full md:max-w-xl">
17
+ <div>
18
+ <ul className="flex items-center justify-center gap-1.5">
19
+ {pokemon.type.map((type) => (
20
+ <div
21
+ key={type}
22
+ className="rounded-full bg-gray-100 px-3 py-1 text-xs font-bold uppercase leading-none tracking-wide text-black/60"
23
+ >
24
+ {type}
25
+ </div>
26
+ ))}
27
+ </ul>
28
+ </div>
29
+ <div className="inline-flex aspect-square flex-col items-center justify-center">
30
+ <img
31
+ src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemon.id}.png`}
32
+ alt={pokemon.slug}
33
+ className="size-[144px]"
34
+ />
35
+ <div className="flex flex-col items-center justify-center gap-1 text-2xl leading-none">
36
+ <span className="font-bold">{pokemon.name.english}</span>
37
+ <span className="font-zen-maru-gothic text-[0.875em] font-bold opacity-40">
38
+ {pokemon.name.japanese}
39
+ </span>
40
+ </div>
41
+ </div>
42
+ <div>
43
+ <ul className="mx-auto flex w-32 flex-col flex-wrap justify-center gap-1.5">
44
+ {stats.map(([stat, value]: any) => (
45
+ <li
46
+ key={stat}
47
+ className="inline-block rounded-sm bg-black px-1.5 py-1 text-[0.5rem] font-bold uppercase tracking-wider text-white"
48
+ >
49
+ {stat}: {value}
50
+ </li>
51
+ ))}
52
+ </ul>
53
+ </div>
54
+ <div className="mt-12">
55
+ <Link
56
+ to="/"
57
+ className="inline-block rounded-xl bg-gray-100 px-6 py-4 font-bold transition-colors duration-500 ease-in-out hover:bg-gray-200"
58
+ >
59
+ back
60
+ </Link>
61
+ </div>
62
+ </div>
63
+ </>
64
+ );
65
+ };
66
+
67
+ const getPokemon = async (slug: string) => {
68
+ return pokemon.find((row) => row.slug === slug) ?? null;
69
+ };
@@ -0,0 +1,33 @@
1
+ import '../styles.css';
2
+
3
+ import type { ReactNode } from 'react';
4
+
5
+ import { Header } from '../components/header.js';
6
+ import { Footer } from '../components/footer.js';
7
+
8
+ type RootLayoutProps = { children: ReactNode };
9
+
10
+ export const RootLayout = async ({ children }: RootLayoutProps) => {
11
+ const data = await getData();
12
+
13
+ return (
14
+ <div id="__waku" className="font-nunito">
15
+ <meta property="description" content={data.description} />
16
+ <link rel="icon" type="image/png" href={data.icon} />
17
+ <Header />
18
+ <main className="flex min-h-svh items-center justify-center">
19
+ {children}
20
+ </main>
21
+ <Footer />
22
+ </div>
23
+ );
24
+ };
25
+
26
+ const getData = async () => {
27
+ const data = {
28
+ description: 'An internet website!',
29
+ icon: '/images/favicon.png',
30
+ };
31
+
32
+ return data;
33
+ };
@@ -0,0 +1,10 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: ['./src/**/*.{js,jsx,ts,tsx}'],
4
+ theme: {
5
+ fontFamily: {
6
+ nunito: ['"Nunito"', 'sans-serif'],
7
+ 'zen-maru-gothic': ['"Zen Maru Gothic"', 'serif'],
8
+ },
9
+ },
10
+ };
@@ -9,6 +9,9 @@
9
9
  "noUncheckedIndexedAccess": true,
10
10
  "exactOptionalPropertyTypes": true,
11
11
  "types": ["react/experimental"],
12
- "jsx": "react-jsx"
12
+ "jsx": "react-jsx",
13
+ "paths": {
14
+ "~/*": ["./src/*"]
15
+ }
13
16
  }
14
17
  }
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "typescript": "5.3.3"
21
21
  }
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "typescript": "5.3.3"
21
21
  }
@@ -9,14 +9,14 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
15
  "react-wrap-balancer": "1.1.0",
16
- "waku": "0.19.0"
16
+ "waku": "0.19.2"
17
17
  },
18
18
  "devDependencies": {
19
- "@types/react": "18.2.46",
19
+ "@types/react": "18.2.54",
20
20
  "@types/react-dom": "18.2.18",
21
21
  "typescript": "5.3.3"
22
22
  }
@@ -1,7 +1,7 @@
1
1
  import { Balancer } from 'react-wrap-balancer';
2
2
 
3
- import { Counter } from './Counter.js';
4
- import { getCounter, increment } from './funcs.js';
3
+ import Counter from './Counter.js';
4
+ import { greet, getCounter, increment } from './funcs.js';
5
5
 
6
6
  type ServerFunction<T> = T extends (...args: infer A) => infer R
7
7
  ? (...args: A) => Promise<R>
@@ -15,6 +15,7 @@ const App = ({ name }: { name: string }) => {
15
15
  <h3>This is a server component.</h3>
16
16
  <p>Server counter: {getCounter()}</p>
17
17
  <Counter
18
+ greet={greet as unknown as ServerFunction<typeof greet>}
18
19
  increment={increment as unknown as ServerFunction<typeof increment>}
19
20
  />
20
21
  <Balancer>My Awesome Title</Balancer>
@@ -4,31 +4,37 @@ import { useState, useTransition } from 'react';
4
4
 
5
5
  import { TextBox } from './TextBox.js';
6
6
 
7
- export const Counter = ({
7
+ const Counter = ({
8
8
  greet,
9
+ increment,
9
10
  }: {
10
11
  greet: (name: string) => Promise<string>;
12
+ increment: () => void;
11
13
  }) => {
14
+ const [isPending, startTransition] = useTransition();
12
15
  const [count, setCount] = useState(0);
13
16
  const [text, setText] = useState<string | Promise<string>>('');
14
- const [isPending, startTransition] = useTransition();
15
- const handleClick = () => {
17
+ const handleClick1 = () => {
16
18
  startTransition(() => {
17
19
  setText(greet('c=' + count));
18
20
  });
19
21
  };
22
+ const handleClick2 = () => {
23
+ startTransition(() => {
24
+ increment();
25
+ });
26
+ };
20
27
  return (
21
28
  <div style={{ border: '3px blue dashed', margin: '1em', padding: '1em' }}>
29
+ {isPending ? 'Pending...' : ''}
22
30
  <p>Count: {count}</p>
23
31
  <button onClick={() => setCount((c) => c + 1)}>Increment</button>
24
- <p>
25
- <button onClick={handleClick}>
26
- greet(&quot;c=&quot; + count) = {text as string}
27
- </button>{' '}
28
- {isPending ? 'Pending...' : ''}
29
- </p>
32
+ <button onClick={handleClick1}>{text || 'Click to greet'}</button>
33
+ <button onClick={handleClick2}>Increment server counter</button>{' '}
30
34
  <h3>This is a client component.</h3>
31
35
  <TextBox />
32
36
  </div>
33
37
  );
34
38
  };
39
+
40
+ export default Counter;
@@ -2,6 +2,8 @@
2
2
 
3
3
  import type { RenderContext } from 'waku/server';
4
4
 
5
+ export const greet = (name: string) => `Hello ${name} from server!`;
6
+
5
7
  // module state on server
6
8
  let counter = 0;
7
9
 
@@ -0,0 +1,6 @@
1
+ /** @type {import('vite').UserConfig} */
2
+ export default {
3
+ ssr: {
4
+ noExternal: ['react-wrap-balancer'],
5
+ },
6
+ };
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "typescript": "5.3.3"
21
21
  }
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "server-only": "0.0.1",
21
21
  "typescript": "5.3.3"
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
2
  import cookieParser from 'cookie-parser';
3
- import { connectMiddleware } from 'waku/dev';
3
+ import { unstable_connectMiddleware as connectMiddleware } from 'waku/dev';
4
4
 
5
5
  const withSsr = process.argv[2] === '--with-ssr';
6
6
 
@@ -11,14 +11,14 @@
11
11
  "dependencies": {
12
12
  "cookie-parser": "1.4.6",
13
13
  "express": "4.18.2",
14
- "react": "18.3.0-canary-c5b937576-20231219",
15
- "react-dom": "18.3.0-canary-c5b937576-20231219",
16
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
17
- "waku": "0.19.0"
14
+ "react": "18.3.0-canary-4b2a1115a-20240202",
15
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
16
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
17
+ "waku": "0.19.2"
18
18
  },
19
19
  "devDependencies": {
20
- "@types/node": "^20.10.6",
21
- "@types/react": "18.2.46",
20
+ "@types/node": "20.11.16",
21
+ "@types/react": "18.2.54",
22
22
  "@types/react-dom": "18.2.18",
23
23
  "typescript": "5.3.3"
24
24
  }
@@ -2,7 +2,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
2
2
  import path from 'node:path';
3
3
  import express from 'express';
4
4
  import cookieParser from 'cookie-parser';
5
- import { connectMiddleware } from 'waku/prd';
5
+ import { unstable_connectMiddleware as connectMiddleware } from 'waku/prd';
6
6
 
7
7
  const withSsr = process.argv[2] === '--with-ssr';
8
8
 
@@ -12,9 +12,8 @@ const app = express();
12
12
  app.use(cookieParser());
13
13
  app.use(
14
14
  connectMiddleware({
15
- entries: import(
16
- pathToFileURL(path.join(root, 'dist', 'entries.js')).toString()
17
- ),
15
+ loadEntries: () =>
16
+ import(pathToFileURL(path.join(root, 'dist', 'entries.js')).toString()),
18
17
  unstable_prehook: (req) => {
19
18
  return { count: Number(req.orig.cookies.count) || 0 };
20
19
  },
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "typescript": "5.3.3"
21
21
  }
@@ -0,0 +1,22 @@
1
+ import { Suspense } from 'react';
2
+ import type { ReactNode } from 'react';
3
+
4
+ import './styles.css';
5
+
6
+ const Layout = ({ children }: { children: ReactNode }) => {
7
+ return (
8
+ <div>
9
+ {children}
10
+ <Suspense fallback="Pending...">
11
+ <ServerMessage />
12
+ </Suspense>
13
+ </div>
14
+ );
15
+ };
16
+
17
+ const ServerMessage = async () => {
18
+ await new Promise((resolve) => setTimeout(resolve, 2000));
19
+ return <p>Hello from server!</p>;
20
+ };
21
+
22
+ export default Layout;
@@ -0,0 +1,3 @@
1
+ body {
2
+ background-color: lightyellow;
3
+ }
@@ -2,13 +2,18 @@ import { lazy } from 'react';
2
2
  import { defineEntries } from 'waku/server';
3
3
  import { Slot } from 'waku/client';
4
4
 
5
+ const Layout = lazy(() => import('./components/Layout.js'));
5
6
  const App = lazy(() => import('./components/App.js'));
6
7
 
7
8
  export default defineEntries(
8
9
  // renderEntries
9
10
  async (input) => {
10
11
  return {
11
- App: <App name={input || 'Waku'} />,
12
+ App: (
13
+ <Layout>
14
+ <App name={input || 'Waku'} />
15
+ </Layout>
16
+ ),
12
17
  };
13
18
  },
14
19
  // getBuildConfig
@@ -10,13 +10,13 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "glob": "10.3.10",
13
- "react": "18.3.0-canary-c5b937576-20231219",
14
- "react-dom": "18.3.0-canary-c5b937576-20231219",
15
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
16
- "waku": "0.19.0"
13
+ "react": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
15
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
16
+ "waku": "0.19.2"
17
17
  },
18
18
  "devDependencies": {
19
- "@types/react": "18.2.46",
19
+ "@types/react": "18.2.54",
20
20
  "@types/react-dom": "18.2.18",
21
21
  "typescript": "5.3.3"
22
22
  }
@@ -54,24 +54,27 @@ const getMappingAndItems = async (id: string) => {
54
54
  return { mapping, items };
55
55
  };
56
56
 
57
- const getStaticPaths = async () => {
57
+ const getPathConfig = async () => {
58
58
  const files = await glob('**/page.{tsx,js}', { cwd: routesDir });
59
- return files
60
- .filter((file) => !/(^|\/)(\[\w+\]|_\w+_)\//.test(file))
61
- .map((file) => '/' + file.slice(0, Math.max(0, file.lastIndexOf('/'))));
59
+ return files.map((file) => {
60
+ const names = file.split('/').filter(Boolean).slice(0, -1);
61
+ const pathSpec = names.map((name) => {
62
+ const match = name.match(/^(\[\w+\]|_\w+_)$/);
63
+ if (match) {
64
+ return { type: 'group', name: match[1]!.slice(1, -1) } as const;
65
+ }
66
+ return { type: 'literal', name } as const;
67
+ });
68
+ return {
69
+ path: pathSpec,
70
+ isStatic: pathSpec.every(({ type }) => type === 'literal'),
71
+ };
72
+ });
62
73
  };
63
74
 
64
75
  export default defineRouter(
65
- // existsPath
66
- async (path: string) => {
67
- if ((await getStaticPaths()).includes(path)) {
68
- return 'static';
69
- }
70
- if ((await getMappingAndItems(path + '/page')) !== null) {
71
- return 'dynamic';
72
- }
73
- return null;
74
- },
76
+ // getPathConfig
77
+ () => getPathConfig(),
75
78
  // getComponent (id is "**/layout" or "**/page")
76
79
  async (id, unstable_setShouldSkip) => {
77
80
  unstable_setShouldSkip({}); // always skip if possible
@@ -86,6 +89,4 @@ export default defineRouter(
86
89
  );
87
90
  return Component;
88
91
  },
89
- // getPathsForBuild
90
- () => getStaticPaths(),
91
92
  );
@@ -7,9 +7,6 @@ const routeFiles = glob.sync('routes/**/*.{tsx,js}', { cwd: rootDir });
7
7
 
8
8
  /** @type {import('vite').UserConfig} */
9
9
  export default {
10
- ssr: {
11
- external: ['glob'],
12
- },
13
10
  build: {
14
11
  rollupOptions: {
15
12
  input: Object.fromEntries(
@@ -9,13 +9,13 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "react": "18.3.0-canary-c5b937576-20231219",
13
- "react-dom": "18.3.0-canary-c5b937576-20231219",
14
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
15
- "waku": "0.19.0"
12
+ "react": "18.3.0-canary-4b2a1115a-20240202",
13
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
14
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
15
+ "waku": "0.19.2"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/react": "18.2.46",
18
+ "@types/react": "18.2.54",
19
19
  "@types/react-dom": "18.2.18",
20
20
  "typescript": "5.3.3"
21
21
  }
@@ -9,20 +9,20 @@
9
9
  "start": "waku start --with-ssr"
10
10
  },
11
11
  "dependencies": {
12
- "@stylexjs/stylex": "0.4.1",
13
- "@vanilla-extract/css": "1.14.0",
12
+ "@stylexjs/stylex": "0.5.1",
13
+ "@vanilla-extract/css": "1.14.1",
14
14
  "classnames": "2.3.2",
15
- "react": "18.3.0-canary-c5b937576-20231219",
16
- "react-dom": "18.3.0-canary-c5b937576-20231219",
17
- "react-server-dom-webpack": "18.3.0-canary-c5b937576-20231219",
18
- "waku": "0.19.0"
15
+ "react": "18.3.0-canary-4b2a1115a-20240202",
16
+ "react-dom": "18.3.0-canary-4b2a1115a-20240202",
17
+ "react-server-dom-webpack": "18.3.0-canary-4b2a1115a-20240202",
18
+ "waku": "0.19.2"
19
19
  },
20
20
  "devDependencies": {
21
- "@types/react": "18.2.46",
21
+ "@types/react": "18.2.54",
22
22
  "@types/react-dom": "18.2.18",
23
- "@vanilla-extract/vite-plugin": "3.9.3",
23
+ "@vanilla-extract/vite-plugin": "3.9.5",
24
24
  "typescript": "5.3.3",
25
- "vite": "5.0.10",
26
- "vite-plugin-stylex-dev": "0.2.3"
25
+ "vite": "5.0.12",
26
+ "vite-plugin-stylex-dev": "0.3.0"
27
27
  }
28
28
  }
@@ -1,12 +1,7 @@
1
- import { defineConfig } from 'vite';
2
1
  import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
3
2
  import { stylexPlugin } from 'vite-plugin-stylex-dev';
4
3
 
5
- export default defineConfig(({ mode }) => ({
6
- ...(mode === 'development' && {
7
- ssr: {
8
- external: ['@stylexjs/stylex', 'classnames'],
9
- },
10
- }),
4
+ /** @type {import('vite').UserConfig} */
5
+ export default {
11
6
  plugins: [vanillaExtractPlugin({ emitCssInSsr: true }), stylexPlugin()],
12
- }));
7
+ };