Skip to content

Commit d96ecc3

Browse files
Merge pull request #875 from grahammendick/rsc-structure
2 parents 780c08e + 39aab7e commit d96ecc3

24 files changed

+283
-251
lines changed

NavigationReact/sample/rsc-parcel/src/App.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use server-entry';
22
import './client';
33
import { SceneView } from 'navigation-react';
4-
import RootProvider from './RootProvider';
4+
import NavigationProvider from './NavigationProvider';
5+
import HmrProvider from './HmrProvider';
56
import People from './People';
67
import Person from './Person';
78

@@ -12,14 +13,16 @@ const App = async ({url}: any) => {
1213
<title>Navigation React</title>
1314
</head>
1415
<body>
15-
<RootProvider url={url}>
16-
<SceneView active="people">
17-
<People />
18-
</SceneView>
19-
<SceneView active="person" dataKeyDeps={['id']}>
20-
<Person />
21-
</SceneView>
22-
</RootProvider>
16+
<NavigationProvider url={url}>
17+
<HmrProvider>
18+
<SceneView active="people">
19+
<People />
20+
</SceneView>
21+
<SceneView active="person" dataKeyDeps={['id']}>
22+
<Person />
23+
</SceneView>
24+
</HmrProvider>
25+
</NavigationProvider>
2326
</body>
2427
</html>
2528
);

NavigationReact/sample/rsc-parcel/src/HmrContext.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use client'
2+
import { useContext, useEffect } from 'react';
3+
import { BundlerContext, useNavigationEvent } from 'navigation-react';
4+
5+
const HmrProvider = ({children}: any) => {
6+
const {setRoot, deserialize} = useContext(BundlerContext);
7+
const {stateNavigator} = useNavigationEvent();
8+
useEffect(() => {
9+
const onHmrReload = (e: any) => {
10+
e.preventDefault();
11+
const {stateContext: {state, data, crumbs, nextCrumb: {crumblessUrl}}} = stateNavigator;
12+
const root = deserialize(stateNavigator.historyManager.getHref(crumblessUrl), {
13+
method: 'put',
14+
headers: {'Content-Type': 'application/json'},
15+
body: {
16+
crumbs: crumbs.map(({state, data}) => ({state: state.key, data})),
17+
state: state.key,
18+
data
19+
}
20+
});
21+
stateNavigator.historyManager.stop();
22+
setRoot(root);
23+
}
24+
window.addEventListener('parcelhmrreload', onHmrReload);
25+
return () => window.removeEventListener('parcelhmrreload', onHmrReload);
26+
});
27+
return children;
28+
}
29+
30+
export default HmrProvider;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use client'
2+
import { useMemo } from 'react';
3+
import { StateNavigator, HTML5HistoryManager } from 'navigation';
4+
import { NavigationHandler } from 'navigation-react';
5+
import stateNavigator from './stateNavigator';
6+
7+
const historyManager = new HTML5HistoryManager();
8+
9+
const NavigationProvider = ({url, children}: any) => {
10+
const clientNavigator = useMemo(() => {
11+
historyManager.stop();
12+
const clientNavigator = new StateNavigator(stateNavigator, historyManager);
13+
clientNavigator.navigateLink(url);
14+
return clientNavigator;
15+
}, []);
16+
return (
17+
<NavigationHandler stateNavigator={clientNavigator}>
18+
{children}
19+
</NavigationHandler>
20+
)
21+
}
22+
23+
export default NavigationProvider;

NavigationReact/sample/rsc-parcel/src/RootProvider.tsx

Lines changed: 0 additions & 45 deletions
This file was deleted.

NavigationReact/sample/rsc-parcel/src/client.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
'use client-entry';
2-
import { useState, startTransition } from 'react';
2+
import { useState, useMemo, startTransition } from 'react';
33
import ReactDOM from 'react-dom/client';
44
import { createFromReadableStream } from 'react-server-dom-parcel/client';
55
import { rscStream } from 'rsc-html-stream/client';
6-
import HmrContext from './HmrContext';
6+
import { fetchRSC } from '@parcel/rsc/client';
7+
import { BundlerContext } from 'navigation-react';
78

89
function Shell() {
9-
let [root, setRoot] = useState(() => createFromReadableStream(rscStream));
10+
const [root, setRoot] = useState(() => createFromReadableStream(rscStream));
11+
const bundler = useMemo(() => ({setRoot, deserialize: fetchRSC}), []);
1012
return (
11-
<HmrContext.Provider value={setRoot}>
13+
<BundlerContext.Provider value={bundler}>
1214
{root}
13-
</HmrContext.Provider>
15+
</BundlerContext.Provider>
1416
);
1517
}
1618

NavigationReact/sample/rsc-webpack/src/App.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import { SceneView } from 'navigation-react';
3-
import RootProvider from './RootProvider.js';
3+
import NavigationProvider from './NavigationProvider.js';
4+
import HmrProvider from './HmrProvider.js';
45
import People from './People.js';
56
import Person from './Person.js';
67

@@ -11,14 +12,16 @@ const App = async ({url}) => {
1112
<title>Navigation React</title>
1213
</head>
1314
<body>
14-
<RootProvider url={url}>
15-
<SceneView active="people">
16-
<People />
17-
</SceneView>
18-
<SceneView active="person" dataKeyDeps={['id']}>
19-
<Person />
20-
</SceneView>
21-
</RootProvider>
15+
<NavigationProvider url={url}>
16+
<HmrProvider>
17+
<SceneView active="people">
18+
<People />
19+
</SceneView>
20+
<SceneView active="person" dataKeyDeps={['id']}>
21+
<Person />
22+
</SceneView>
23+
</HmrProvider>
24+
</NavigationProvider>
2225
</body>
2326
</html>
2427
);

NavigationReact/sample/rsc-webpack/src/HmrContext.js

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use client'
2+
import * as React from 'react';
3+
import { useContext, useEffect } from 'react';
4+
import { BundlerContext, useNavigationEvent } from 'navigation-react';
5+
6+
const HmrProvider = ({children}) => {
7+
const {setRoot, deserialize} = useContext(BundlerContext);
8+
const {stateNavigator} = useNavigationEvent();
9+
useEffect(() => {
10+
const onHmrReload = (status) => {
11+
if (status !== 'idle') return;
12+
const {stateContext: {state, data, crumbs, nextCrumb: {crumblessUrl}}} = stateNavigator;
13+
const root = deserialize(stateNavigator.historyManager.getHref(crumblessUrl), {
14+
method: 'put',
15+
headers: {'Content-Type': 'application/json'},
16+
body: {
17+
crumbs: crumbs.map(({state, data}) => ({state: state.key, data})),
18+
state: state.key,
19+
data
20+
}
21+
});
22+
stateNavigator.historyManager.stop();
23+
setRoot(root);
24+
}
25+
import.meta.webpackHot?.addStatusHandler(onHmrReload);
26+
return () => import.meta.webpackHot?.removeStatusHandler(onHmrReload);
27+
});
28+
return children;
29+
}
30+
31+
export default HmrProvider;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use client'
2+
import * as React from 'react';
3+
import { useMemo } from 'react';
4+
import { StateNavigator, HTML5HistoryManager } from 'navigation';
5+
import { NavigationHandler } from 'navigation-react';
6+
import stateNavigator from './stateNavigator.js';
7+
8+
const historyManager = new HTML5HistoryManager();
9+
10+
const NavigationProvider = ({url, children}) => {
11+
const clientNavigator = useMemo(() => {
12+
historyManager.stop();
13+
const clientNavigator = new StateNavigator(stateNavigator, historyManager);
14+
clientNavigator.navigateLink(url);
15+
return clientNavigator;
16+
}, []);
17+
return (
18+
<NavigationHandler stateNavigator={clientNavigator}>
19+
{children}
20+
</NavigationHandler>
21+
)
22+
}
23+
24+
export default NavigationProvider;

0 commit comments

Comments
 (0)