From 745d701fda54329e455f3960247457b3d84f1ac6 Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Mon, 11 Nov 2024 20:23:22 -0800 Subject: [PATCH 1/9] fix: render type test issues with new_createPages --- e2e/fixtures/render-type/src/Echo.tsx | 7 ++-- e2e/fixtures/render-type/src/ServerEcho.tsx | 5 +-- e2e/fixtures/render-type/src/entries.tsx | 2 +- e2e/fixtures/render-type/src/main.tsx | 2 +- packages/waku/src/router/create-pages.ts | 40 +++++++++++++++++---- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/e2e/fixtures/render-type/src/Echo.tsx b/e2e/fixtures/render-type/src/Echo.tsx index 082fb77b2..572e3614c 100644 --- a/e2e/fixtures/render-type/src/Echo.tsx +++ b/e2e/fixtures/render-type/src/Echo.tsx @@ -1,8 +1,9 @@ -export function Echo({ echo, timestamp }: { echo: string; timestamp: number }) { +export function Echo(props: any) { + console.log('Echo', props); // FIXME echo is undefined return (
-

{echo}

-

{timestamp}

+

{props.echo}

+

{props.timestamp}

); } diff --git a/e2e/fixtures/render-type/src/ServerEcho.tsx b/e2e/fixtures/render-type/src/ServerEcho.tsx index 112efccda..f75616d2f 100644 --- a/e2e/fixtures/render-type/src/ServerEcho.tsx +++ b/e2e/fixtures/render-type/src/ServerEcho.tsx @@ -1,5 +1,6 @@ import { Echo } from './Echo.js'; -export function ServerEcho({ echo }: { echo: string }) { - return ; +export function ServerEcho(props: any) { + console.log('ServerEcho', props); // FIXME echo is undefined + return ; } diff --git a/e2e/fixtures/render-type/src/entries.tsx b/e2e/fixtures/render-type/src/entries.tsx index cee13f25b..27693e76f 100644 --- a/e2e/fixtures/render-type/src/entries.tsx +++ b/e2e/fixtures/render-type/src/entries.tsx @@ -1,4 +1,4 @@ -import { createPages } from 'waku/router/server'; +import { new_createPages as createPages } from 'waku/router/server'; import { ServerEcho } from './ServerEcho.js'; import { ClientEcho } from './ClientEcho.js'; diff --git a/e2e/fixtures/render-type/src/main.tsx b/e2e/fixtures/render-type/src/main.tsx index c79446e79..403e67cd2 100644 --- a/e2e/fixtures/render-type/src/main.tsx +++ b/e2e/fixtures/render-type/src/main.tsx @@ -1,6 +1,6 @@ import { StrictMode } from 'react'; import { createRoot, hydrateRoot } from 'react-dom/client'; -import { Router } from 'waku/router/client'; +import { NewRouter as Router } from 'waku/router/client'; const rootElement = ( diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index e199aa786..5cf83f31c 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -500,6 +500,22 @@ export const new_createPages = < let rootItem: RootItem | undefined = undefined; const noSsrSet = new WeakSet(); + /** helper to find dynamic path when slugs are used */ + const getRoutePath: (path: string) => string | undefined = (path) => { + if (staticComponentMap.has(joinPath(path, 'page').slice(1))) { + return path; + } + const allPaths = [ + ...dynamicPagePathMap.keys(), + ...wildcardPagePathMap.keys(), + ]; + for (const p of allPaths) { + if (new RegExp(path2regexp(parsePathWithSlug(p))).test(path)) { + return p; + } + } + }; + const registerStaticComponent = ( id: string, component: FunctionComponent, @@ -644,7 +660,11 @@ export const new_createPages = < if (segment === '') { return acc; } - acc.push(acc[index - 1] + '/' + segment); + if (acc[index - 1] === '/') { + acc.push('/' + segment); + } else { + acc.push(acc[index - 1] + '/' + segment); + } return acc; }, ['/'], @@ -755,9 +775,15 @@ export const new_createPages = < renderRoute: async (path) => { await configure(); + // path without slugs + const routePath = getRoutePath(path); + if (!routePath) { + throw new Error('Route not found: ' + path); + } + const pageComponent = (staticComponentMap.get( - joinPath(path, 'page').slice(1), // feels like a hack - ) ?? dynamicPagePathMap.get(path)?.[1])!; + joinPath(routePath, 'page').slice(1), // feels like a hack + ) ?? dynamicPagePathMap.get(routePath)?.[1])!; const result: Record = { root: createElement( @@ -765,19 +791,21 @@ export const new_createPages = < null, createElement(Children), ), - [`page:${path}`]: createElement( + [`page:${routePath}`]: createElement( pageComponent, null, createElement(Children), ), }; - const layoutPaths = getLayouts(path); + // this is wrong because getLayouts assumes normal path and routePath is a regex + const layoutPaths = getLayouts(routePath); for (const segment of layoutPaths) { const layout = dynamicLayoutPathMap.get(segment)?.[1] ?? staticComponentMap.get(joinPath(segment, 'layout').slice(1)); // feels like a hack + // console.log({ layout }); // always true if (layout) { const id = 'layout:' + segment; @@ -791,7 +819,7 @@ export const new_createPages = < component: Slot, props: { id: `layout:${lPath}` }, })), - { component: Slot, props: { id: `page:${path}` } }, + { component: Slot, props: { id: `page:${routePath}` } }, ]; return { From 15931b2ceea6a2cb0729b40fdb1051c3e4ba743c Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:45:53 -0800 Subject: [PATCH 2/9] wrong mapping --- packages/waku/src/router/create-pages.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index 5cf83f31c..528ca6615 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -785,6 +785,9 @@ export const new_createPages = < joinPath(routePath, 'page').slice(1), // feels like a hack ) ?? dynamicPagePathMap.get(routePath)?.[1])!; + const pathSpec = parsePathWithSlug(routePath); + const mapping = getPathMapping(pathSpec, routePath); + const result: Record = { root: createElement( rootItem ? rootItem.component : DefaultRoot, @@ -793,7 +796,7 @@ export const new_createPages = < ), [`page:${routePath}`]: createElement( pageComponent, - null, + mapping, createElement(Children), ), }; @@ -809,7 +812,7 @@ export const new_createPages = < // always true if (layout) { const id = 'layout:' + segment; - result[id] = createElement(layout, null, createElement(Children)); + result[id] = createElement(layout, createElement(Children)); } } From 0cf6fa645512dd9af40daf260237abe451379fe4 Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:10:33 -0800 Subject: [PATCH 3/9] fix: render type with right mapping --- e2e/fixtures/render-type/src/Echo.tsx | 7 +++---- e2e/fixtures/render-type/src/ServerEcho.tsx | 5 ++--- packages/waku/src/router/create-pages.ts | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/e2e/fixtures/render-type/src/Echo.tsx b/e2e/fixtures/render-type/src/Echo.tsx index 572e3614c..082fb77b2 100644 --- a/e2e/fixtures/render-type/src/Echo.tsx +++ b/e2e/fixtures/render-type/src/Echo.tsx @@ -1,9 +1,8 @@ -export function Echo(props: any) { - console.log('Echo', props); // FIXME echo is undefined +export function Echo({ echo, timestamp }: { echo: string; timestamp: number }) { return (
-

{props.echo}

-

{props.timestamp}

+

{echo}

+

{timestamp}

); } diff --git a/e2e/fixtures/render-type/src/ServerEcho.tsx b/e2e/fixtures/render-type/src/ServerEcho.tsx index f75616d2f..112efccda 100644 --- a/e2e/fixtures/render-type/src/ServerEcho.tsx +++ b/e2e/fixtures/render-type/src/ServerEcho.tsx @@ -1,6 +1,5 @@ import { Echo } from './Echo.js'; -export function ServerEcho(props: any) { - console.log('ServerEcho', props); // FIXME echo is undefined - return ; +export function ServerEcho({ echo }: { echo: string }) { + return ; } diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index 528ca6615..66dd673df 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -786,7 +786,7 @@ export const new_createPages = < ) ?? dynamicPagePathMap.get(routePath)?.[1])!; const pathSpec = parsePathWithSlug(routePath); - const mapping = getPathMapping(pathSpec, routePath); + const mapping = getPathMapping(pathSpec, path); const result: Record = { root: createElement( @@ -808,7 +808,7 @@ export const new_createPages = < const layout = dynamicLayoutPathMap.get(segment)?.[1] ?? staticComponentMap.get(joinPath(segment, 'layout').slice(1)); // feels like a hack - // console.log({ layout }); + // always true if (layout) { const id = 'layout:' + segment; From 474adb60a9c8c76e921aa16a386ef9d16b8788c2 Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:51:20 -0800 Subject: [PATCH 4/9] fix: regression to layouts --- packages/waku/src/router/create-pages.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index 66dd673df..2a812747e 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -654,12 +654,9 @@ export const new_createPages = < await ready; }; - const getLayouts = (path: string): string[] => { - const pathSegments = path.split('/').reduce( + const getLayouts = (spec: PathSpec): string[] => { + const pathSegments = spec.reduce( (acc, segment, index) => { - if (segment === '') { - return acc; - } if (acc[index - 1] === '/') { acc.push('/' + segment); } else { @@ -694,7 +691,7 @@ export const new_createPages = < const pattern = path2regexp(parsePathWithSlug(path)); - const layoutPaths = getLayouts(pattern); + const layoutPaths = getLayouts(pathSpec); const elements = { ...layoutPaths.reduce>( @@ -723,7 +720,7 @@ export const new_createPages = < for (const [path, [pathSpec]] of dynamicPagePathMap) { const noSsr = noSsrSet.has(pathSpec); const pattern = path2regexp(parsePathWithSlug(path)); - const layoutPaths = getLayouts(pattern); + const layoutPaths = getLayouts(pathSpec); const elements = { ...layoutPaths.reduce>( (acc, lPath) => { @@ -747,8 +744,7 @@ export const new_createPages = < } for (const [path, [pathSpec]] of wildcardPagePathMap) { const noSsr = noSsrSet.has(pathSpec); - const pattern = path2regexp(parsePathWithSlug(path)); - const layoutPaths = getLayouts(pattern); + const layoutPaths = getLayouts(pathSpec); const elements = { ...layoutPaths.reduce>( (acc, lPath) => { @@ -802,7 +798,7 @@ export const new_createPages = < }; // this is wrong because getLayouts assumes normal path and routePath is a regex - const layoutPaths = getLayouts(routePath); + const layoutPaths = getLayouts(pathSpec); for (const segment of layoutPaths) { const layout = @@ -812,7 +808,7 @@ export const new_createPages = < // always true if (layout) { const id = 'layout:' + segment; - result[id] = createElement(layout, createElement(Children)); + result[id] = createElement(layout, null, createElement(Children)); } } From 48bb258df3eff5d6fbcf76dff7fc6d726efde69d Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:51:58 -0800 Subject: [PATCH 5/9] fix: remove stale comment --- packages/waku/src/router/create-pages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index 2a812747e..e9c9d3d48 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -797,7 +797,6 @@ export const new_createPages = < ), }; - // this is wrong because getLayouts assumes normal path and routePath is a regex const layoutPaths = getLayouts(pathSpec); for (const segment of layoutPaths) { From bdfec7690ad6102f1c596a33881316b36f4ce48f Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Thu, 14 Nov 2024 23:12:40 -0800 Subject: [PATCH 6/9] refactor: use new_createPages for fs-router --- examples/11_fs-router/src/main.tsx | 2 +- packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts | 2 +- packages/waku/src/router/fs-router.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/11_fs-router/src/main.tsx b/examples/11_fs-router/src/main.tsx index bddb502d5..354c5d2f7 100644 --- a/examples/11_fs-router/src/main.tsx +++ b/examples/11_fs-router/src/main.tsx @@ -1,6 +1,6 @@ import { StrictMode } from 'react'; import { createRoot, hydrateRoot } from 'react-dom/client'; -import { Router } from 'waku/router/client'; +import { NewRouter as Router } from 'waku/router/client'; const rootElement = ( diff --git a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts index 0deb959c4..2c8ecdf69 100644 --- a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts +++ b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts @@ -22,7 +22,7 @@ export default fsRouter( const getManagedMain = () => ` import { Component, StrictMode } from 'react'; import { createRoot, hydrateRoot } from 'react-dom/client'; -import { Router } from 'waku/router/client'; +import { NewRouter as Router } from 'waku/router/client'; const rootElement = ( diff --git a/packages/waku/src/router/fs-router.ts b/packages/waku/src/router/fs-router.ts index 946e3ffa1..c15b15b7b 100644 --- a/packages/waku/src/router/fs-router.ts +++ b/packages/waku/src/router/fs-router.ts @@ -1,5 +1,5 @@ import { unstable_getPlatformObject } from '../server.js'; -import { createPages } from './create-pages.js'; +import { new_createPages as createPages } from './create-pages.js'; import { EXTENSIONS } from '../lib/constants.js'; From 4a8723c61ade674743d05c33b45ee8d401dbfcd6 Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:35:12 -0800 Subject: [PATCH 7/9] try updating rsc managed --- e2e/fixtures/ssg-wildcard/package.json | 2 +- e2e/fixtures/ssg-wildcard/src/main.tsx | 15 --------------- .../src/lib/plugins/vite-plugin-rsc-managed.ts | 2 +- 3 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 e2e/fixtures/ssg-wildcard/src/main.tsx diff --git a/e2e/fixtures/ssg-wildcard/package.json b/e2e/fixtures/ssg-wildcard/package.json index b149e5f89..3020f0035 100644 --- a/e2e/fixtures/ssg-wildcard/package.json +++ b/e2e/fixtures/ssg-wildcard/package.json @@ -1,5 +1,5 @@ { - "name": "waku-example", + "name": "ssg-wildcard", "version": "0.1.0", "type": "module", "private": true, diff --git a/e2e/fixtures/ssg-wildcard/src/main.tsx b/e2e/fixtures/ssg-wildcard/src/main.tsx deleted file mode 100644 index bddb502d5..000000000 --- a/e2e/fixtures/ssg-wildcard/src/main.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { StrictMode } from 'react'; -import { createRoot, hydrateRoot } from 'react-dom/client'; -import { Router } from 'waku/router/client'; - -const rootElement = ( - - - -); - -if ((globalThis as any).__WAKU_HYDRATE__) { - hydrateRoot(document, rootElement); -} else { - createRoot(document as any).render(rootElement); -} diff --git a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts index 2c8ecdf69..7946734c5 100644 --- a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts +++ b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts @@ -20,7 +20,7 @@ export default fsRouter( `; const getManagedMain = () => ` -import { Component, StrictMode } from 'react'; +import { StrictMode } from 'react'; import { createRoot, hydrateRoot } from 'react-dom/client'; import { NewRouter as Router } from 'waku/router/client'; From 4edcfa9521ec06dc97a77dc2554c31f1c7f4c72a Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:03:31 -0800 Subject: [PATCH 8/9] fix static paths in create pages --- packages/waku/src/router/create-pages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/waku/src/router/create-pages.ts b/packages/waku/src/router/create-pages.ts index ac641cc4f..324a3a21e 100644 --- a/packages/waku/src/router/create-pages.ts +++ b/packages/waku/src/router/create-pages.ts @@ -588,7 +588,7 @@ export const new_createPages = < } }); staticPathMap.set( - page.path, + '/' + pathItems.join('/'), pathItems.map((name) => ({ type: 'literal', name })), ); const id = joinPath(...pathItems, 'page'); From a20a2742966b46e8e051757c9da660c1168719c7 Mon Sep 17 00:00:00 2001 From: Tyler <26290074+thegitduck@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:20:53 -0800 Subject: [PATCH 9/9] add test --- packages/waku/tests/create-pages.test.ts | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/waku/tests/create-pages.test.ts b/packages/waku/tests/create-pages.test.ts index 3cf836ea1..e60830544 100644 --- a/packages/waku/tests/create-pages.test.ts +++ b/packages/waku/tests/create-pages.test.ts @@ -829,6 +829,56 @@ describe('createPages', () => { expect(TestPage).toHaveBeenCalledWith({ path: ['a', 'b'] }, undefined); }); + it('creates multiple static pages with wildcards', async () => { + const TestPage = vi.fn(); + createPages(async ({ createPage }) => [ + createPage({ + render: 'static', + path: '/test/[...path]', + staticPaths: [[], ['hi'], ['a', 'b']], + component: TestPage, + }), + ]); + const { getPathConfig, getComponent } = injectedFunctions(); + expect(await getPathConfig()).toEqual([ + { + pattern: '^/test/(.*)$', + path: [{ type: 'literal', name: 'test' }], + isStatic: true, + noSsr: false, + }, + { + pattern: '^/test/(.*)$', + path: [ + { type: 'literal', name: 'test' }, + { type: 'literal', name: 'hi' }, + ], + isStatic: true, + noSsr: false, + }, + { + pattern: '^/test/(.*)$', + path: [ + { type: 'literal', name: 'test' }, + { type: 'literal', name: 'a' }, + { type: 'literal', name: 'b' }, + ], + isStatic: true, + noSsr: false, + }, + ]); + const setShouldSkip = vi.fn(); + const WrappedComponent = await getComponent('test/a/b/page', { + unstable_setShouldSkip: setShouldSkip, + }); + assert(WrappedComponent); + expect(setShouldSkip).toHaveBeenCalledTimes(1); + expect(setShouldSkip).toHaveBeenCalledWith([]); + renderToString(createElement(WrappedComponent as any)); + expect(TestPage).toHaveBeenCalledTimes(1); + expect(TestPage).toHaveBeenCalledWith({ path: ['a', 'b'] }, undefined); + }); + it('creates a dynamic page with wildcards', async () => { const TestPage = vi.fn(); createPages(async ({ createPage }) => [