Skip to content

Commit b883c4a

Browse files
authored
chore(examples): new_defineEntries (#993)
Migrating examples: - [x] 38_cookies - [x] 39_api - [x] 35_nesting
1 parent 75c9884 commit b883c4a

File tree

17 files changed

+122
-136
lines changed

17 files changed

+122
-136
lines changed

examples/31_minimal/src/main.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StrictMode } from 'react';
22
import { createRoot, hydrateRoot } from 'react-dom/client';
3-
import { Root, Slot } from 'waku/client';
3+
import { Root, Slot } from 'waku/minimal/client';
44

55
const rootElement = (
66
<StrictMode>

examples/31_minimal/waku.config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ export default defineConfig({
77
import('waku/middleware/context'),
88
import('waku/middleware/dev-server'),
99
import('waku/middleware/handler'),
10-
import('waku/middleware/fallback'),
1110
],
1211
});

examples/35_nesting/src/entries.tsx

+29-34
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
11
import type { ReactNode } from 'react';
2-
import { defineEntries } from 'waku/server';
3-
import { Slot } from 'waku/client';
2+
import { new_defineEntries } from 'waku/minimal/server';
3+
import { Slot } from 'waku/minimal/client';
44

55
import App from './components/App';
66
import InnerApp from './components/InnerApp';
77
import AppWithoutSsr from './components/AppWithoutSsr';
88

9-
export default defineEntries(
10-
// renderEntries
11-
async (rscPath) => {
12-
const params = new URLSearchParams(rscPath || 'App=Waku&InnerApp=0');
13-
const result: Record<string, ReactNode> = {};
14-
if (params.has('App')) {
15-
result.App = <App name={params.get('App')!} />;
9+
export default new_defineEntries({
10+
unstable_handleRequest: async (input, { renderRsc, renderHtml }) => {
11+
if (input.type === 'component') {
12+
const params = new URLSearchParams(
13+
input.rscPath || 'App=Waku&InnerApp=0',
14+
);
15+
const result: Record<string, ReactNode> = {};
16+
if (params.has('App')) {
17+
result.App = <App name={params.get('App')!} />;
18+
}
19+
if (params.has('InnerApp')) {
20+
result.InnerApp = <InnerApp count={Number(params.get('InnerApp'))} />;
21+
}
22+
if (params.has('AppWithoutSsr')) {
23+
result.AppWithoutSsr = <AppWithoutSsr />;
24+
}
25+
return renderRsc(result);
1626
}
17-
if (params.has('InnerApp')) {
18-
result.InnerApp = <InnerApp count={Number(params.get('InnerApp'))} />;
27+
if (input.type === 'custom' && input.pathname === '/') {
28+
return renderHtml(
29+
{ App: <App name="Waku" />, InnerApp: <InnerApp count={0} /> },
30+
<Slot id="App" />,
31+
'',
32+
);
1933
}
20-
if (params.has('AppWithoutSsr')) {
21-
result.AppWithoutSsr = <AppWithoutSsr />;
22-
}
23-
return result;
2434
},
25-
// getBuildConfig
26-
async () => [
35+
unstable_getBuildConfig: async () => [
2736
{
28-
pathname: '/',
37+
pathSpec: [],
2938
entries: [
3039
{ rscPath: '' },
3140
{ rscPath: 'InnerApp=1', skipPrefetch: true },
@@ -36,23 +45,9 @@ export default defineEntries(
3645
],
3746
},
3847
{
39-
pathname: '/no-ssr',
48+
pathSpec: [{ type: 'literal', name: '/no-ssr' }],
4049
entries: [{ rscPath: 'AppWithoutSsr' }],
4150
isStatic: true,
4251
},
4352
],
44-
// getSsrConfig
45-
async (pathname) => {
46-
switch (pathname) {
47-
case '/':
48-
return {
49-
rscPath: '',
50-
html: <Slot id="App" />,
51-
};
52-
case '/no-ssr':
53-
return null;
54-
default:
55-
return null;
56-
}
57-
},
58-
);
53+
});

examples/35_nesting/src/main.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StrictMode } from 'react';
22
import { createRoot, hydrateRoot } from 'react-dom/client';
3-
import { Root, Slot } from 'waku/client';
3+
import { Root, Slot } from 'waku/minimal/client';
44

55
const pathname = window.location.pathname;
66

examples/35_nesting/waku.config.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// This is a temporary file while experimenting new_defineEntries
2+
3+
import { defineConfig } from 'waku/config';
4+
5+
export default defineConfig({
6+
middleware: () => [
7+
import('waku/middleware/context'),
8+
import('waku/middleware/dev-server'),
9+
import('waku/middleware/handler'),
10+
],
11+
});

examples/38_cookies/src/components/App.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Suspense, cache } from 'react';
2-
import { unstable_getCustomContext as getCustomContext } from 'waku/server';
2+
import { getContextData } from 'waku/middleware/context';
33
import { getHonoContext } from 'waku/unstable_hono';
44

55
import { Counter } from './Counter';
@@ -13,14 +13,13 @@ const InternalAsyncComponent = async () => {
1313
if (val1 !== val2) {
1414
throw new Error('Cache not working');
1515
}
16-
// console.log(getCustomContext()); // fails when it's sent to the browser
17-
console.log('waku context', Object.keys(getCustomContext()));
16+
console.log('waku context', Object.keys(getContextData()));
1817
console.log('hono context', Object.keys(getHonoContext()));
1918
return null;
2019
};
2120

2221
const App = ({ name, items }: { name: string; items: unknown[] }) => {
23-
const context = getCustomContext<{ count: number }>();
22+
const data = getContextData() as { count?: number };
2423
return (
2524
<html>
2625
<head>
@@ -32,7 +31,7 @@ const App = ({ name, items }: { name: string; items: unknown[] }) => {
3231
>
3332
<h1>Hello {name}!!</h1>
3433
<h3>This is a server component.</h3>
35-
<p>Cookie count: {context.count}</p>
34+
<p>Cookie count: {data.count || 0}</p>
3635
<Counter />
3736
<p>Item count: {items.length}</p>
3837
<Suspense>

examples/38_cookies/src/entries.tsx

+22-29
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
import path from 'node:path';
22
import { fileURLToPath } from 'node:url';
33
import fsPromises from 'node:fs/promises';
4-
import {
5-
defineEntries,
6-
unstable_getCustomContext as getCustomContext,
7-
} from 'waku/server';
8-
import { Slot } from 'waku/client';
4+
import { new_defineEntries } from 'waku/minimal/server';
5+
import { Slot } from 'waku/minimal/client';
6+
import { getContextData } from 'waku/middleware/context';
97

108
import App from './components/App';
119

12-
export default defineEntries(
13-
// renderEntries
14-
async (rscPath) => {
15-
const context = getCustomContext<{ count: number }>();
16-
++context.count;
10+
export default new_defineEntries({
11+
unstable_handleRequest: async (input, { renderRsc, renderHtml }) => {
12+
const data = getContextData() as { count?: number };
13+
data.count = (data.count || 0) + 1;
1714
const items = JSON.parse(
1815
await fsPromises.readFile(
1916
path.join(
@@ -23,24 +20,20 @@ export default defineEntries(
2320
'utf8',
2421
),
2522
);
26-
return {
27-
App: <App name={rscPath || 'Waku'} items={items} />,
28-
};
29-
},
30-
// getBuildConfig
31-
async () => [
32-
{ pathname: '/', entries: [{ rscPath: '' }], context: { count: 0 } },
33-
],
34-
// getSsrConfig
35-
async (pathname) => {
36-
switch (pathname) {
37-
case '/':
38-
return {
39-
rscPath: '',
40-
html: <Slot id="App" />,
41-
};
42-
default:
43-
return null;
23+
if (input.type === 'component') {
24+
return renderRsc({
25+
App: <App name={input.rscPath || 'Waku'} items={items} />,
26+
});
27+
}
28+
if (input.type === 'custom' && input.pathname === '/') {
29+
return renderHtml(
30+
{ App: <App name={'Waku'} items={items} /> },
31+
<Slot id="App" />,
32+
'',
33+
);
4434
}
4535
},
46-
);
36+
unstable_getBuildConfig: async () => [
37+
{ pathSpec: [], entries: [{ rscPath: '' }] },
38+
],
39+
});

examples/38_cookies/src/main.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StrictMode } from 'react';
22
import { createRoot, hydrateRoot } from 'react-dom/client';
3-
import { Root, Slot } from 'waku/client';
3+
import { Root, Slot } from 'waku/minimal/client';
44

55
const rootElement = (
66
<StrictMode>

examples/38_cookies/src/middleware/cookie.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const COOKIE_OPTS = {};
88
const cookieMiddleware: Middleware = () => {
99
return async (ctx, next) => {
1010
const cookies = cookie.parse(ctx.req.headers.cookie || '');
11-
ctx.context.count = Number(cookies.count) || 0;
11+
ctx.data.count = Number(cookies.count) || 0;
1212
await next();
1313
ctx.res.headers ||= {};
1414
let origSetCookie = ctx.res.headers['set-cookie'] || ([] as string[]);
@@ -17,7 +17,7 @@ const cookieMiddleware: Middleware = () => {
1717
}
1818
ctx.res.headers['set-cookie'] = [
1919
...origSetCookie,
20-
cookie.serialize('count', String(ctx.context.count), COOKIE_OPTS),
20+
cookie.serialize('count', String(ctx.data.count), COOKIE_OPTS),
2121
];
2222
};
2323
};

examples/38_cookies/waku.config.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/** @type {import('waku/config').Config} */
2-
export default {
1+
import { defineConfig } from 'waku/config';
2+
3+
export default defineConfig({
34
middleware: () => [
45
import('waku/middleware/context'),
56
import('./src/middleware/cookie.js'),
67
import('waku/middleware/dev-server'),
7-
import('waku/middleware/rsc'),
8-
import('waku/middleware/ssr'),
8+
import('waku/middleware/handler'),
99
],
10-
};
10+
});

examples/39_api/src/entries.tsx

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
1-
import { defineEntries } from 'waku/server';
2-
import { Slot } from 'waku/client';
1+
import { new_defineEntries } from 'waku/minimal/server';
2+
import { Slot } from 'waku/minimal/client';
33

44
import App from './components/App';
55

6-
export default defineEntries(
7-
// renderEntries
8-
async (rscPath) => {
9-
return {
10-
App: <App name={rscPath || 'Waku'} />,
11-
};
12-
},
13-
// getBuildConfig
14-
async () => [{ pathname: '/', entries: [{ rscPath: '' }] }],
15-
// getSsrConfig
16-
async (pathname) => {
17-
switch (pathname) {
18-
case '/':
19-
return {
20-
rscPath: '',
21-
html: <Slot id="App" />,
22-
};
23-
default:
24-
return null;
6+
const stringToStream = (str: string): ReadableStream => {
7+
const encoder = new TextEncoder();
8+
return new ReadableStream({
9+
start(controller) {
10+
controller.enqueue(encoder.encode(str));
11+
controller.close();
12+
},
13+
});
14+
};
15+
16+
export default new_defineEntries({
17+
unstable_handleRequest: async (input, { renderRsc, renderHtml }) => {
18+
if (input.type === 'component') {
19+
return renderRsc({ App: <App name={input.rscPath || 'Waku'} /> });
20+
}
21+
if (input.type === 'custom' && input.pathname === '/') {
22+
return renderHtml({ App: <App name="Waku" /> }, <Slot id="App" />, '');
23+
}
24+
if (input.type === 'custom' && input.pathname === '/api/hello') {
25+
return stringToStream('world');
2526
}
2627
},
27-
);
28+
unstable_getBuildConfig: async () => [
29+
{ pathSpec: [], entries: [{ rscPath: '' }] },
30+
],
31+
});

examples/39_api/src/main.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StrictMode } from 'react';
22
import { createRoot, hydrateRoot } from 'react-dom/client';
3-
import { Root, Slot } from 'waku/client';
3+
import { Root, Slot } from 'waku/minimal/client';
44

55
const rootElement = (
66
<StrictMode>

examples/39_api/src/middleware/api.ts

-24
This file was deleted.

examples/39_api/waku.config.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
/** @type {import('waku/config').Config} */
2-
export default {
1+
// This is a temporary file while experimenting new_defineEntries
2+
3+
import { defineConfig } from 'waku/config';
4+
5+
export default defineConfig({
36
middleware: () => [
47
import('waku/middleware/context'),
5-
import('./src/middleware/api.js'),
68
import('waku/middleware/dev-server'),
7-
import('waku/middleware/rsc'),
8-
import('waku/middleware/ssr'),
9+
import('waku/middleware/handler'),
910
],
10-
};
11+
});

packages/waku/src/lib/hono/ctx.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { Context, Env } from 'hono';
22

33
// This can't be relative import
4-
import { getContext } from 'waku/middleware/context';
4+
import { getContextData } from 'waku/middleware/context';
55

66
// Internal context key
77
const HONO_CONTEXT = '__hono_context';
88

99
export const getHonoContext = <E extends Env = Env>() => {
10-
const c = getContext().data[HONO_CONTEXT];
10+
const c = getContextData()[HONO_CONTEXT];
1111
if (!c) {
1212
throw new Error('Hono context is not available');
1313
}

0 commit comments

Comments
 (0)