Skip to content

Commit

Permalink
Make browser context creation implicit on the client (#843)
Browse files Browse the repository at this point in the history
  • Loading branch information
lemonmade authored Oct 15, 2024
1 parent c365777 commit 5a8036d
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 85 deletions.
6 changes: 6 additions & 0 deletions .changeset/wild-moose-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@quilted/preact-browser': patch
'@quilted/create': patch
---

Make browser context creation implicit on the client
15 changes: 3 additions & 12 deletions packages/create/templates/app-basic/browser.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import '@quilted/quilt/globals';
import {hydrate} from 'preact';
import {Browser, BrowserContext} from '@quilted/quilt/browser';
import {hydrate} from '@quilted/quilt/browser';
import {Router} from '@quilted/quilt/navigation';

import type {AppContext} from '~/shared/context.ts';
import {App} from './App.tsx';

const element = document.querySelector('#app')!;
const browser = new Browser();

const context = {
router: new Router(browser.request.url),
router: new Router(),
} satisfies AppContext;

// Makes key parts of the app available in the browser console
Object.assign(globalThis, {app: context});

hydrate(
<BrowserContext browser={browser}>
<App context={context} />
</BrowserContext>,
element,
);
hydrate(<App context={context} />);
9 changes: 6 additions & 3 deletions packages/create/templates/app-basic/tests/render/render.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {createRender} from '@quilted/quilt/testing';
import {BrowserContext, BrowserTestMock} from '@quilted/quilt/browser/testing';
import {
BrowserDetailsContext,
BrowserTestMock,
} from '@quilted/quilt/browser/testing';
import {Navigation, TestRouter} from '@quilted/quilt/navigation/testing';
import {Localization} from '@quilted/quilt/localize';

Expand Down Expand Up @@ -29,11 +32,11 @@ export const renderApp = createRender<

return (
<AppContextReact.Provider value={context}>
<BrowserContext browser={browser}>
<BrowserDetailsContext.Provider value={browser}>
<Localization locale={locale}>
<Navigation router={router}>{element}</Navigation>
</Localization>
</BrowserContext>
</BrowserDetailsContext.Provider>
</AppContextReact.Provider>
);
},
Expand Down
17 changes: 4 additions & 13 deletions packages/create/templates/app-graphql/browser.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import '@quilted/quilt/globals';

import {hydrate} from 'preact';
import {createGraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql';
import {Browser, BrowserContext} from '@quilted/quilt/browser';
import {hydrate} from '@quilted/quilt/browser';
import {Router} from '@quilted/quilt/navigation';
import {createGraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql';

import type {AppContext} from '~/shared/context.ts';

import {App} from './App.tsx';

const element = document.querySelector('#app')!;
const browser = new Browser();

const graphQLFetch = createGraphQLFetch({url: '/api/graphql'});
const graphQLCache = new GraphQLCache({fetch: graphQLFetch});

const context = {
router: new Router(browser.request.url),
router: new Router(),
graphql: {
fetch: graphQLFetch,
cache: graphQLCache,
Expand All @@ -26,9 +22,4 @@ const context = {
// Makes key parts of the app available in the browser console
Object.assign(globalThis, {app: context});

hydrate(
<BrowserContext browser={browser}>
<App context={context} />
</BrowserContext>,
element,
);
hydrate(<App context={context} />);
9 changes: 6 additions & 3 deletions packages/create/templates/app-graphql/tests/render/render.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {Suspense} from 'preact/compat';

import {createRender} from '@quilted/quilt/testing';
import {BrowserContext, BrowserTestMock} from '@quilted/quilt/browser/testing';
import {
BrowserDetailsContext,
BrowserTestMock,
} from '@quilted/quilt/browser/testing';
import {Navigation, TestRouter} from '@quilted/quilt/navigation/testing';
import {Localization} from '@quilted/quilt/localize';
import {GraphQLCache} from '@quilted/quilt/graphql';
Expand Down Expand Up @@ -44,7 +47,7 @@ export const renderApp = createRender<

return (
<AppContextReact.Provider value={context}>
<BrowserContext browser={browser}>
<BrowserDetailsContext.Provider value={browser}>
<Localization locale={locale}>
<Navigation router={router}>
<GraphQLTesting
Expand All @@ -55,7 +58,7 @@ export const renderApp = createRender<
</GraphQLTesting>
</Navigation>
</Localization>
</BrowserContext>
</BrowserDetailsContext.Provider>
</AppContextReact.Provider>
);
},
Expand Down
18 changes: 5 additions & 13 deletions packages/create/templates/app-trpc/browser.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
import '@quilted/quilt/globals';

import {hydrate} from 'preact';
import {hydrate} from '@quilted/quilt/browser';
import {Router} from '@quilted/quilt/navigation';

import {httpBatchLink} from '@trpc/client';
import {QueryClient} from '@tanstack/react-query';
import {Browser, BrowserContext} from '@quilted/quilt/browser';
import {Router} from '@quilted/quilt/navigation';

import type {AppContext} from '~/shared/context.ts';
import {trpc} from '~/shared/trpc.ts';

import {App} from './App.tsx';

const element = document.querySelector('#app')!;
const browser = new Browser();

const queryClient = new QueryClient();
const trpcClient = trpc.createClient({
links: [httpBatchLink({url: new URL('/api', window.location.href).href})],
});

const context = {
router: new Router(browser.request.url),
router: new Router(),
trpc: trpcClient,
queryClient,
} satisfies AppContext;

// Makes key parts of the app available in the browser console
Object.assign(globalThis, {app: context});

hydrate(
<BrowserContext browser={browser}>
<App context={context} />
</BrowserContext>,
element,
);
hydrate(<App context={context} />);
9 changes: 6 additions & 3 deletions packages/create/templates/app-trpc/tests/render/render.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {createRender} from '@quilted/quilt/testing';
import {BrowserContext, BrowserTestMock} from '@quilted/quilt/browser/testing';
import {
BrowserDetailsContext,
BrowserTestMock,
} from '@quilted/quilt/browser/testing';
import {Navigation, TestRouter} from '@quilted/quilt/navigation/testing';
import {Localization} from '@quilted/quilt/localize';

Expand Down Expand Up @@ -37,7 +40,7 @@ export const renderApp = createRender<

return (
<AppContextReact.Provider value={context}>
<BrowserContext browser={browser}>
<BrowserDetailsContext.Provider value={browser}>
<Localization locale={locale}>
<Navigation router={router}>
<trpc.Provider client={trpcClient} queryClient={queryClient}>
Expand All @@ -47,7 +50,7 @@ export const renderApp = createRender<
</trpc.Provider>
</Navigation>
</Localization>
</BrowserContext>
</BrowserDetailsContext.Provider>
</AppContextReact.Provider>
);
},
Expand Down
49 changes: 49 additions & 0 deletions packages/preact-browser/source/browser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
hydrate as preactHydrate,
render as preactRender,
type ComponentChild,
} from 'preact';

import {Browser} from '@quilted/browser';

import {BrowserDetailsContext} from './context.ts';

export function render(
component: ComponentChild,
{element}: {element?: string | Element} = {},
) {
const browser = new Browser();

return preactRender(
<BrowserDetailsContext.Provider value={browser}>
{component}
</BrowserDetailsContext.Provider>,
resolveContainerNode(element),
);
}

export function hydrate(
component: ComponentChild,
{element}: {element?: string | Element} = {},
) {
const browser = new Browser();

return preactHydrate(
<BrowserDetailsContext.Provider value={browser}>
{component}
</BrowserDetailsContext.Provider>,
resolveContainerNode(element),
);
}

function resolveContainerNode(selectorOrElement: string | Element = '#app') {
if (typeof selectorOrElement !== 'string') return selectorOrElement;

const element = document.querySelector(selectorOrElement);

if (element == null) {
throw new Error(`No element found for selector: ${selectorOrElement}`);
}

return element;
}
17 changes: 0 additions & 17 deletions packages/preact-browser/source/components/BrowserContext.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion packages/preact-browser/source/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from '@quilted/browser';

export {render, hydrate} from './browser.tsx';
export {BrowserDetailsContext, useBrowserDetails} from './context.ts';

export {useAlternateUrl} from './hooks/alternate-url.ts';
Expand All @@ -17,7 +18,6 @@ export {useThemeColor} from './hooks/theme-color.ts';
export {useTitle} from './hooks/title.ts';

export {Alternate} from './components/Alternate.tsx';
export {BrowserContext} from './components/BrowserContext.tsx';
export {BodyAttributes} from './components/BodyAttributes.tsx';
export {HTMLAttributes} from './components/HTMLAttributes.tsx';
export {Link} from './components/Link.tsx';
Expand Down
2 changes: 1 addition & 1 deletion packages/preact-browser/source/testing.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from '@quilted/browser/testing';
export {BrowserContext} from './components/BrowserContext.tsx';
export {BrowserDetailsContext} from './context.ts';
13 changes: 2 additions & 11 deletions tests/e2e/fixtures/basic-app/browser.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import '@quilted/quilt/globals';
import {hydrate} from 'preact';
import {Browser, BrowserContext} from '@quilted/quilt/browser';
import {hydrate} from '@quilted/quilt/browser';

import App from './App.tsx';

const element = document.querySelector('#app')!;
const browser = new Browser();

hydrate(
<BrowserContext browser={browser}>
<App />
</BrowserContext>,
element,
);
hydrate(<App />);
11 changes: 3 additions & 8 deletions tests/e2e/integrations/trpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,26 @@ describe('trpc', () => {
`,
'browser.tsx': multiline`
import '@quilted/quilt/globals';
import {hydrate} from 'preact';
import {Browser, BrowserContext} from '@quilted/quilt/browser';
import {hydrate} from '@quilted/quilt/browser';
import {httpBatchLink} from '@trpc/client';
import {QueryClient} from '@tanstack/react-query';
import {App, trpc} from './App.tsx';
const element = document.querySelector('#app')!;
const browser = new Browser();
const trpcClient = trpc.createClient({
links: [
httpBatchLink({
url: new URL('/api', browser.request.url).href,
url: new URL('/api').href,
}),
],
});
const queryClient = new QueryClient();
hydrate(
<BrowserContext browser={browser}>
<App trpcClient={trpcClient} queryClient={queryClient} />
</BrowserContext>,
element,
<App trpcClient={trpcClient} queryClient={queryClient} />,
);
`,
'server.tsx': multiline`
Expand Down

0 comments on commit 5a8036d

Please sign in to comment.