From e0d00ed12f6445bf13654c6ac010a126b0c2880f Mon Sep 17 00:00:00 2001 From: Harry Brundage Date: Wed, 29 Jun 2022 13:55:34 -0400 Subject: [PATCH] Give layouts access to the props that the app is booted with --- .../src/client/react/Root.tsx | 11 +++- .../simple-react/BootPropsLayout.tsx | 14 +++++ packages/test-apps/simple-react/Home.tsx | 2 + packages/test-apps/simple-react/package.json | 1 + packages/test-apps/simple-react/server.ts | 12 +++- .../simple-react/test/boot-props.spec.ts | 17 ++++++ yarn.lock | 57 +++++++++++++++---- 7 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 packages/test-apps/simple-react/BootPropsLayout.tsx create mode 100644 packages/test-apps/simple-react/test/boot-props.spec.ts diff --git a/packages/fastify-renderer/src/client/react/Root.tsx b/packages/fastify-renderer/src/client/react/Root.tsx index 6ba05f1f..8700c66c 100644 --- a/packages/fastify-renderer/src/client/react/Root.tsx +++ b/packages/fastify-renderer/src/client/react/Root.tsx @@ -8,13 +8,18 @@ export interface LayoutProps { isNavigating: boolean navigationDestination: string children: React.ReactNode + bootProps: Record } -const RouteTable = (props: { Layout: React.FunctionComponent; routes: JSX.Element[] }) => { +const RouteTable = (props: { + Layout: React.FunctionComponent + routes: JSX.Element[] + bootProps: Record +}) => { const [isNavigating, navigationDestination] = useNavigationDetails() return ( - + {props.routes} ) @@ -75,7 +80,7 @@ export function Root(props: { return ( - + ) } diff --git a/packages/test-apps/simple-react/BootPropsLayout.tsx b/packages/test-apps/simple-react/BootPropsLayout.tsx new file mode 100644 index 00000000..f8ddb588 --- /dev/null +++ b/packages/test-apps/simple-react/BootPropsLayout.tsx @@ -0,0 +1,14 @@ +import React, { Suspense } from 'react' + +const Layout = (props: { children: React.ReactNode; bootProps: Record }) => { + return ( + Loading...}> +
+        {JSON.stringify(props.bootProps)}
+      
+ {props.children} +
+ ) +} + +export default Layout diff --git a/packages/test-apps/simple-react/Home.tsx b/packages/test-apps/simple-react/Home.tsx index f2f2dfbf..30bb7870 100644 --- a/packages/test-apps/simple-react/Home.tsx +++ b/packages/test-apps/simple-react/Home.tsx @@ -15,6 +15,8 @@ const Home = (props: { time: number }) => { Red About
+ Boot props test +
Navigation Test ) diff --git a/packages/test-apps/simple-react/package.json b/packages/test-apps/simple-react/package.json index 328b119d..0c335bf3 100644 --- a/packages/test-apps/simple-react/package.json +++ b/packages/test-apps/simple-react/package.json @@ -14,6 +14,7 @@ "react-dom": "*" }, "devDependencies": { + "@playwright/test": "^1.23.0", "html-validator": "^5.1.18" } } diff --git a/packages/test-apps/simple-react/server.ts b/packages/test-apps/simple-react/server.ts index aa80dc54..5ba14fa5 100644 --- a/packages/test-apps/simple-react/server.ts +++ b/packages/test-apps/simple-react/server.ts @@ -71,6 +71,14 @@ export const server = async () => { }) }) + await server.register(async (instance) => { + instance.setRenderConfig({ base: '/bootprops', layout: require.resolve('./BootPropsLayout') }) + + instance.get('/bootprops/test', { render: require.resolve('./About') }, async (request) => { + return { hostname: os.hostname(), requestIP: request.ip, bootProp: 'this is a boot prop' } + }) + }) + await server.ready() return server } @@ -78,6 +86,8 @@ export const server = async () => { if (require.main === module) { void server().then((server) => { console.warn(server.printRoutes()) - return server.listen(3000) + return server.listen(3000).then((address) => { + console.warn(`Test server listening on ${address}`) + }) }) } diff --git a/packages/test-apps/simple-react/test/boot-props.spec.ts b/packages/test-apps/simple-react/test/boot-props.spec.ts new file mode 100644 index 00000000..8812036c --- /dev/null +++ b/packages/test-apps/simple-react/test/boot-props.spec.ts @@ -0,0 +1,17 @@ +import { expect } from '@playwright/test' +import { Page } from 'playwright-chromium' +import { newTestPage, reactReady, rootURL } from '../../helpers' + +describe('boot props', () => { + let page: Page + + beforeEach(async () => { + page = await newTestPage() + }) + + test('should make the boot props available to the layout', async () => { + await page.goto(`${rootURL}/bootprops/test`) + await reactReady(page) + await (expect(page.locator('#bootprops')) as any).toContainText('this is a boot prop') + }) +}) diff --git a/yarn.lock b/yarn.lock index c39f755c..8d8bfd8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1195,6 +1195,14 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.1.0.tgz#563539048255bbe1a5f4f586a4a10a1bb737f44a" integrity sha512-hf+3bwuBwtXsugA2ULBc95qxrOqP2pOekLz34BJhcAKawt94vfeNyUKpYc0lZQ/3sCP6LqRa7UAdHA7i5UODzQ== +"@playwright/test@^1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.23.0.tgz#5d07ace37e1598a4a1a785b07856620b4e26fc43" + integrity sha512-RPWI8AHBVBiDyfTuxi1BhOaY3yaVy3S5ZsGKkSGGeWpZtSgN4SerInCYvgh9+EunIAK4RJQo+bzupbAn5pVqHQ== + dependencies: + "@types/node" "*" + playwright-core "1.23.0" + "@rollup/pluginutils@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec" @@ -1361,17 +1369,17 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== -"@types/react-dom@17.0.4", "@types/react-dom@^17.0.11": - version "17.0.4" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.4.tgz#d65159a847aca2a0fc87a7544a2f8fece8754d04" - integrity sha512-Wb6rlnPJfqbhpkvYN39y1NM/pOGGPzzIRquu0RdUMvTwgXNvASFO7pdtrtvyxGTQNb9wzBaQxXAWDdEqegZw2A== +"@types/react-dom@^17.0.11": + version "17.0.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" + integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg== dependencies: - "@types/react" "*" + "@types/react" "^17" -"@types/react@*", "@types/react@17.0.4", "@types/react@^17.0.43": - version "17.0.4" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.4.tgz#a67c6f7a460d2660e950d9ccc1c2f18525c28220" - integrity sha512-onz2BqScSFMoTRdJUZUDD/7xrusM8hBA2Fktk2qgaTYPCgPvWnDEgkrOs8hhPUf2jfcIXkJ5yK6VfYormJS3Jw== +"@types/react@^17", "@types/react@^17.0.43": + version "17.0.47" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.47.tgz#4ee71aaf4c5a9e290e03aa4d0d313c5d666b3b78" + integrity sha512-mk0BL8zBinf2ozNr3qPnlu1oyVTYq+4V7WA76RgxUAtf0Em/Wbid38KN6n4abEkvO4xMTBWmnP1FtQzgkEiJoA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -5697,6 +5705,11 @@ playwright-core@1.21.0: yauzl "2.10.0" yazl "2.5.1" +playwright-core@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.23.0.tgz#51e24121b3a5bbe759d79738d8eff7a63156293c" + integrity sha512-Zzhyr5RZGoJ1ek2sgfJCt2076kdOg8hnNwFBqAYeLySiutXyxSQk93vZ5gbnFiWV1sHvueCcwla9n35acUTxtA== + pngjs@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" @@ -5882,7 +5895,15 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -react-dom@*, react-dom@0.0.0-experimental-4ead6b530: +react-dom@*: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-dom@0.0.0-experimental-4ead6b530: version "0.0.0-experimental-4ead6b530" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-4ead6b530.tgz#6ca831f5aa7ab86f7299b9a2f7b81dffabfa4eb4" integrity sha512-a03ptS8lhhEENNgne6zQMXQWX/Z6WMEBGJQY0laOC0NgJywidePYpgkiE72fUAaj/r7t9a6XsdVyqx4UsEZijg== @@ -5906,7 +5927,14 @@ react-refresh@^0.10.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3" integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ== -react@*, react@0.0.0-experimental-4ead6b530: +react@*: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +react@0.0.0-experimental-4ead6b530: version "0.0.0-experimental-4ead6b530" resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-4ead6b530.tgz#88cdae012012a758dd039a63104758c6351115df" integrity sha512-tpbYm6FEuC1L6tCVXIKYAhgGAkS8DShzKpmXosowZvLqeByeLQQe77Ef6bi5HdEkFm2v0lZffLWckSM8R4TToA== @@ -6165,6 +6193,13 @@ scheduler@0.0.0-experimental-4ead6b530: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + secure-json-parse@^2.0.0: version "2.4.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.4.0.tgz#5aaeaaef85c7a417f76271a4f5b0cc3315ddca85"