Skip to content

Commit

Permalink
Introduce plugins and extract resources as a plugin (#192)
Browse files Browse the repository at this point in the history
  • Loading branch information
bobrovnik authored Feb 23, 2023
1 parent 2fd9c38 commit b735ec4
Show file tree
Hide file tree
Showing 36 changed files with 873 additions and 115 deletions.
2 changes: 1 addition & 1 deletion examples/basic-routing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const appRoutes = [

const App = () => {
return (
<Router routes={appRoutes} history={myHistory} basePath="/basic-routing">
<Router basePath="/basic-routing" history={myHistory} routes={appRoutes}>
<RouteComponent />
</Router>
);
Expand Down
2 changes: 1 addition & 1 deletion examples/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const Title = () => {

const App = () => {
return (
<Router routes={appRoutes} history={myHistory} basePath="/hooks">
<Router basePath="/hooks" history={myHistory} routes={appRoutes}>
<Title />
<RouteComponent />
</Router>
Expand Down
29 changes: 29 additions & 0 deletions examples/hydration-with-plugins/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import { createResource, useResource } from 'react-resource-router';

export const homeResource = createResource({
type: 'home',
getKey: () => 'breedList',
maxAge: 10000,
getData: async () => {
const response = await fetch('https://dog.ceo/api/breeds/image/random');
const result: { message: string } = await response.json();

return result;
},
});

export const Home = () => {
// eslint-disable-next-line
const { data, loading, error } = useResource(homeResource);

return (
<div>
<h1>Random Dog</h1>
<section>
{data?.message && <img src={data.message} style={{ width: '400px' }} />}
</section>
</div>
);
};
11 changes: 11 additions & 0 deletions examples/hydration-with-plugins/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Example - Hydration</title>
</head>

<body>
<div id="root"></div>
<script src="bundle.js" type="text/javascript"></script>
</body>
</html>
62 changes: 62 additions & 0 deletions examples/hydration-with-plugins/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { createMemoryHistory } from 'history';
import React from 'react';
import { render } from 'react-dom';
import { defaultRegistry } from 'react-sweet-state';

import { createResourcesPlugin } from '../../src/resources';

import { homeRoute } from './routes';

import {
Router,
RouteComponent,
createBrowserHistory,
invokePluginLoad,
} from 'react-resource-router';

const myHistory = createBrowserHistory();

const appRoutes = [homeRoute];

const getStateFromServer = async () => {
const resourcesPlugin = createResourcesPlugin({
resourceData: null,
});

invokePluginLoad([resourcesPlugin], {
history: createMemoryHistory({ initialEntries: [location] }),
routes: appRoutes,
basePath: '/hydration-with-plugins',
});

const resourceData = await resourcesPlugin.getSerializedResources();

// clearing the store
defaultRegistry.stores.clear();

return resourceData;
};

const main = async () => {
const data = await getStateFromServer();
const resourcesPlugin = createResourcesPlugin({
resourceData: data,
});

const App = () => {
return (
<Router
basePath="/hydration-with-plugins"
history={myHistory}
plugins={[resourcesPlugin]}
routes={appRoutes}
>
<RouteComponent />
</Router>
);
};

render(<App />, document.getElementById('root'));
};

main();
10 changes: 10 additions & 0 deletions examples/hydration-with-plugins/routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Home, homeResource } from './home';

export const homeRoute = {
name: 'home',
path: '/',
exact: true,
component: Home,
navigation: null,
resources: [homeResource],
};
2 changes: 1 addition & 1 deletion examples/hydration/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Home = () => {
<div>
<h1>Random Dog</h1>
<section>
{data?.message && <img style={{ width: '400px' }} src={data.message} />}
{data?.message && <img src={data.message} style={{ width: '400px' }} />}
</section>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions examples/hydration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ const main = async () => {
const App = () => {
return (
<Router
routes={appRoutes}
history={myHistory}
basePath="/hydration"
history={myHistory}
resourceData={data}
routes={appRoutes}
>
<RouteComponent />
</Router>
Expand Down
2 changes: 1 addition & 1 deletion examples/routing-with-resources/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const About = () => {
<h1>{breedName}</h1>
<Link to={homeRoute}>Go to home</Link>
<section>
{!loading && <img src={data?.message} alt="A cute dog!" />}
{!loading && <img alt="A cute dog!" src={data?.message} />}
</section>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion examples/routing-with-resources/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const Home = () => {
<ul>
{breeds.slice(0, 25).map(breed => (
<li key={breed}>
<Link to={aboutRoute} query={{ name: breed }} prefetch="hover">
<Link prefetch="hover" query={{ name: breed }} to={aboutRoute}>
{breed}
</Link>
</li>
Expand Down
4 changes: 2 additions & 2 deletions examples/routing-with-resources/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ const appRoutes = [homeRoute, aboutRoute];
const App = () => {
return (
<Router
routes={appRoutes}
history={myHistory}
basePath="/routing-with-resources"
history={myHistory}
onPrefetch={({ route }) => console.log('Prefetching route', route.name)}
routes={appRoutes}
>
<RouteComponent />
</Router>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions resources/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"main": "../build/cjs/resources.js",
"module": "../build/esm/resources.js",
"types": "../build/esm/resources.d.ts"
}
1 change: 1 addition & 0 deletions src/__tests__/integration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ describe('<Router /> client-side integration tests', () => {

expect(router.html()).toBe('loading:cache loading:network');
await waitForData();

router.update();
expect(router.html()).toBe('data:cache-1 data:network-1');

Expand Down
16 changes: 16 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,19 @@ export type FindRouterContextOptions = {
location: Location;
basePath?: string;
};

export type Plugin = {
beforeRouteLoad?: (params: {
context: RouterContext;
nextContext: RouterContext;
}) => void;
routeLoad?: (params: {
context: RouterContext;
prevContext?: RouterContext;
}) => void;
routePrefetch?: (params: {
context: RouterContext;
nextContext: RouterContext;
}) => void;
[key: string]: any;
};
11 changes: 6 additions & 5 deletions src/common/utils/is-server-environment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
*/
const isJsDomEnvironment = () =>
window.name === 'nodejs' ||
navigator.userAgent.includes('Node.js') ||
navigator.userAgent.includes('jsdom');
navigator?.userAgent.includes('Node.js') ||
navigator?.userAgent.includes('jsdom');

export const isServerEnvironment = () => {
if (
typeof process !== 'undefined' &&
process.versions != null &&
process.versions.node != null
typeof window === 'undefined' ||
(typeof process !== 'undefined' &&
process.versions != null &&
process.versions.node != null)
) {
return true;
}
Expand Down
24 changes: 24 additions & 0 deletions src/controllers/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { History, Plugin, Routes } from '../../common/types';
import { findRouterContext } from '../../common/utils';

export const invokePluginLoad = (
plugins: Plugin[],
{
routes,
history,
basePath,
}: {
history: History;
routes: Routes;
basePath?: string;
}
) => {
const context = findRouterContext(routes, {
location: history.location,
basePath,
});

plugins.forEach(p => {
p.routeLoad?.({ context });
});
};
28 changes: 28 additions & 0 deletions src/controllers/plugins/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createMemoryHistory } from 'history';

import { invokePluginLoad } from './index';

describe('invokePluginLoad', () => {
it('calls each plugin load method', () => {
// (findRouterContext as any).mockReturnValue(firstContextMock);
const pluginOne = {
routeLoad: jest.fn(),
};
const pluginTwo = {
routeLoad: jest.fn(),
};

const pluginThree = {
routeLoad: jest.fn(),
};

invokePluginLoad([pluginOne, pluginTwo, pluginThree], {
history: createMemoryHistory(),
routes: [],
});

expect(pluginOne.routeLoad).toBeCalled();
expect(pluginTwo.routeLoad).toBeCalled();
expect(pluginThree.routeLoad).toBeCalled();
});
});
Loading

0 comments on commit b735ec4

Please sign in to comment.