@anansi/core 0.11.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +18 -7
- package/dist/client.js +63 -47
- package/dist/client.js.map +1 -1
- package/dist/server.js +201 -190
- package/dist/server.js.map +1 -1
- package/lib/floodSpouts.d.ts +1 -1
- package/lib/floodSpouts.d.ts.map +1 -1
- package/lib/floodSpouts.js +2 -2
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -2
- package/lib/index.server.d.ts +3 -0
- package/lib/index.server.d.ts.map +1 -1
- package/lib/index.server.js +11 -2
- package/lib/laySpouts.d.ts +2 -1
- package/lib/laySpouts.d.ts.map +1 -1
- package/lib/laySpouts.js +45 -54
- package/lib/scripts/startDevserver.d.ts.map +1 -1
- package/lib/scripts/startDevserver.js +8 -3
- package/lib/spouts/app.d.ts +5 -0
- package/lib/spouts/app.d.ts.map +1 -0
- package/lib/spouts/app.js +12 -0
- package/lib/spouts/app.server.d.ts +6 -0
- package/lib/spouts/app.server.d.ts.map +1 -0
- package/lib/spouts/app.server.js +12 -0
- package/lib/spouts/document.d.ts +2 -8
- package/lib/spouts/document.d.ts.map +1 -1
- package/lib/spouts/document.js +4 -6
- package/lib/spouts/document.server.d.ts +4 -6
- package/lib/spouts/document.server.d.ts.map +1 -1
- package/lib/spouts/document.server.js +40 -42
- package/lib/spouts/json.d.ts +4 -2
- package/lib/spouts/json.d.ts.map +1 -1
- package/lib/spouts/json.js +7 -6
- package/lib/spouts/json.server.d.ts +4 -6
- package/lib/spouts/json.server.d.ts.map +1 -1
- package/lib/spouts/json.server.js +32 -34
- package/lib/spouts/prefetch.server.d.ts +1 -1
- package/lib/spouts/prefetch.server.d.ts.map +1 -1
- package/lib/spouts/prefetch.server.js +1 -1
- package/lib/spouts/restHooks.d.ts +3 -3
- package/lib/spouts/restHooks.d.ts.map +1 -1
- package/lib/spouts/restHooks.js +9 -11
- package/lib/spouts/restHooks.server.d.ts +8 -45
- package/lib/spouts/restHooks.server.d.ts.map +1 -1
- package/lib/spouts/restHooks.server.js +15 -12
- package/lib/spouts/router.d.ts +3 -4
- package/lib/spouts/router.d.ts.map +1 -1
- package/lib/spouts/router.js +14 -13
- package/lib/spouts/router.server.d.ts +3 -4
- package/lib/spouts/router.server.d.ts.map +1 -1
- package/lib/spouts/router.server.js +17 -15
- package/lib/spouts/types.d.ts +2 -0
- package/lib/spouts/types.d.ts.map +1 -1
- package/lib/spouts/types.js +1 -1
- package/package.json +5 -5
- package/src/floodSpouts.tsx +2 -2
- package/src/index.server.ts +3 -0
- package/src/index.ts +3 -0
- package/src/laySpouts.tsx +23 -29
- package/src/scripts/startDevserver.ts +6 -2
- package/src/spouts/app.server.tsx +8 -0
- package/src/spouts/app.tsx +6 -0
- package/src/spouts/document.server.tsx +64 -68
- package/src/spouts/document.tsx +5 -14
- package/src/spouts/json.server.tsx +41 -45
- package/src/spouts/json.tsx +8 -16
- package/src/spouts/prefetch.server.tsx +8 -4
- package/src/spouts/restHooks.server.tsx +27 -22
- package/src/spouts/restHooks.tsx +12 -18
- package/src/spouts/router.server.tsx +27 -21
- package/src/spouts/router.tsx +19 -19
- package/src/spouts/types.ts +18 -0
package/src/index.ts
CHANGED
|
@@ -3,3 +3,6 @@ export { default as documentSpout } from './spouts/document';
|
|
|
3
3
|
export { default as restHooksSpout } from './spouts/restHooks';
|
|
4
4
|
export { default as routerSpout } from './spouts/router';
|
|
5
5
|
export { default as JSONSpout } from './spouts/json';
|
|
6
|
+
export { default as appSpout } from './spouts/app';
|
|
7
|
+
export { ServerProps } from './spouts/types';
|
|
8
|
+
export { ClientSpout as Spout } from './spouts/types';
|
package/src/laySpouts.tsx
CHANGED
|
@@ -8,32 +8,19 @@ export default function laySpouts(
|
|
|
8
8
|
spouts: (props: ServerProps) => Promise<{
|
|
9
9
|
app: JSX.Element;
|
|
10
10
|
}>,
|
|
11
|
-
{
|
|
11
|
+
{
|
|
12
|
+
timeoutMS = 200,
|
|
13
|
+
onError,
|
|
14
|
+
}: { timeoutMS?: number; onError?: (error: unknown) => void } = {},
|
|
12
15
|
) {
|
|
13
16
|
const render: Render = async (clientManifest, req, res) => {
|
|
14
17
|
const nonce = crypto.randomBytes(16).toString('base64');
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
This is not documented, so included the types here for reference:
|
|
22
|
-
type Options = {|
|
|
23
|
-
identifierPrefix?: string,
|
|
24
|
-
namespaceURI?: string,
|
|
25
|
-
nonce?: string,
|
|
26
|
-
bootstrapScriptContent?: string,
|
|
27
|
-
bootstrapScripts?: Array<string>,
|
|
28
|
-
bootstrapModules?: Array<string>,
|
|
29
|
-
progressiveChunkSize?: number,
|
|
30
|
-
onShellReady?: () => void,
|
|
31
|
-
onShellError?: () => void,
|
|
32
|
-
onAllReady?: () => void,
|
|
33
|
-
onError?: (error: mixed) => void,
|
|
34
|
-
|};
|
|
35
|
-
*/
|
|
36
|
-
{
|
|
19
|
+
try {
|
|
20
|
+
const { app } = await spouts({ clientManifest, req, res, nonce });
|
|
21
|
+
|
|
22
|
+
let didError = false;
|
|
23
|
+
const { pipe, abort } = reactRender(app, {
|
|
37
24
|
nonce,
|
|
38
25
|
//bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
|
|
39
26
|
onShellReady() {
|
|
@@ -48,17 +35,24 @@ type Options = {|
|
|
|
48
35
|
res.statusCode = 500;
|
|
49
36
|
pipe(res);
|
|
50
37
|
},
|
|
51
|
-
onError(
|
|
38
|
+
onError(e: any) {
|
|
52
39
|
didError = true;
|
|
53
|
-
console.error(
|
|
40
|
+
console.error(e);
|
|
54
41
|
res.statusCode = 500;
|
|
55
42
|
//pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
|
|
43
|
+
if (onError) onError(e);
|
|
56
44
|
},
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
});
|
|
46
|
+
// Abandon and switch to client rendering if enough time passes.
|
|
47
|
+
// Try lowering this to see the client recover.
|
|
48
|
+
setTimeout(
|
|
49
|
+
() => (abort as any)(`Timeout of ${timeoutMS}ms exceeded`),
|
|
50
|
+
timeoutMS,
|
|
51
|
+
);
|
|
52
|
+
} catch (e: unknown) {
|
|
53
|
+
if (onError) onError(e);
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
62
56
|
};
|
|
63
57
|
return render;
|
|
64
58
|
}
|
|
@@ -134,8 +134,12 @@ export default function startDevServer(
|
|
|
134
134
|
) {
|
|
135
135
|
log.error('Errors for client build: ' + clientStats.compilation.errors);
|
|
136
136
|
log.error('Errors for server build: ' + serverStats.compilation.errors);
|
|
137
|
-
//
|
|
138
|
-
|
|
137
|
+
// first time, rather than re-render
|
|
138
|
+
if (Array.isArray(initRender)) {
|
|
139
|
+
process.exit(-1);
|
|
140
|
+
}
|
|
141
|
+
log.error('Above compiler errors blocking reload');
|
|
142
|
+
return;
|
|
139
143
|
} else {
|
|
140
144
|
log.info('Launching SSR');
|
|
141
145
|
}
|
|
@@ -2,15 +2,15 @@ import React from 'react';
|
|
|
2
2
|
import type { Route } from '@anansi/router';
|
|
3
3
|
import { StatsChunkGroup } from 'webpack';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { ServerSpout } from './types';
|
|
6
6
|
import type { Policy } from './csp';
|
|
7
7
|
import Document from './DocumentComponent';
|
|
8
8
|
|
|
9
|
-
type
|
|
9
|
+
type NeededNext = {
|
|
10
10
|
matchedRoutes: Route<any>[];
|
|
11
11
|
title?: string;
|
|
12
12
|
scripts?: React.ReactNode[];
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
|
|
15
15
|
export default function DocumentSpout(options: {
|
|
16
16
|
head?: React.ReactNode;
|
|
@@ -18,77 +18,73 @@ export default function DocumentSpout(options: {
|
|
|
18
18
|
rootId?: string;
|
|
19
19
|
charSet?: string;
|
|
20
20
|
csPolicy?: Policy;
|
|
21
|
-
}) {
|
|
22
|
-
return
|
|
23
|
-
next
|
|
24
|
-
) {
|
|
25
|
-
return async (props: ServerProps) => {
|
|
26
|
-
const nextProps = await next(props);
|
|
21
|
+
}): ServerSpout<Record<string, unknown>, Record<string, unknown>, NeededNext> {
|
|
22
|
+
return next => async props => {
|
|
23
|
+
const nextProps = await next(props);
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
const publicPath = props.clientManifest.publicPath;
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
if (
|
|
28
|
+
Object.keys(props.clientManifest?.entrypoints ?? {}).length < 1 ||
|
|
29
|
+
publicPath === undefined
|
|
30
|
+
)
|
|
31
|
+
throw new Error('Manifest missing entries needed');
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
// TODO: consider using this package for build stats in future:
|
|
34
|
+
// https://github.com/facebook/react/tree/main/packages/react-server-dom-webpack
|
|
35
|
+
const assetMap = (assets: { name: string; size?: number }[]) =>
|
|
36
|
+
assets.map(({ name }) => `${publicPath}${name}`);
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
38
|
+
const assetList: string[] = [];
|
|
39
|
+
Object.values(props.clientManifest?.entrypoints ?? {}).forEach(
|
|
40
|
+
entrypoint => {
|
|
41
|
+
assetList.push(...assetMap(entrypoint.assets ?? []));
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
new Set(
|
|
45
|
+
assetMap(
|
|
46
|
+
Object.values(props.clientManifest.namedChunkGroups ?? {})
|
|
47
|
+
.filter(({ name }) =>
|
|
48
|
+
nextProps.matchedRoutes.some(route => name?.includes(route.name)),
|
|
49
|
+
)
|
|
50
|
+
.flatMap(chunk => [
|
|
51
|
+
...(chunk.assets ?? []),
|
|
52
|
+
// any chunk preloads
|
|
53
|
+
...childrenAssets(chunk),
|
|
54
|
+
]),
|
|
55
|
+
),
|
|
56
|
+
).forEach(asset => assetList.push(asset));
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
// find additional assets to preload based on matched route
|
|
59
|
+
const assets: {
|
|
60
|
+
href: string;
|
|
61
|
+
as?: string | undefined;
|
|
62
|
+
rel?: string | undefined;
|
|
63
|
+
}[] = assetList
|
|
64
|
+
.filter(asset => !asset.endsWith('.hot-update.js'))
|
|
65
|
+
.map(asset =>
|
|
66
|
+
asset.endsWith('.css')
|
|
67
|
+
? { href: asset, rel: 'stylesheet' }
|
|
68
|
+
: asset.endsWith('.js')
|
|
69
|
+
? { href: asset, as: 'script' }
|
|
70
|
+
: { href: asset },
|
|
71
|
+
);
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
73
|
+
return {
|
|
74
|
+
...nextProps,
|
|
75
|
+
app: (
|
|
76
|
+
<Document
|
|
77
|
+
{...options}
|
|
78
|
+
title={nextProps.title ?? options.title}
|
|
79
|
+
assets={assets}
|
|
80
|
+
rootId={options.rootId}
|
|
81
|
+
nonce={props.nonce}
|
|
82
|
+
csPolicy={options.csPolicy}
|
|
83
|
+
scripts={nextProps.scripts}
|
|
84
|
+
>
|
|
85
|
+
{nextProps.app}
|
|
86
|
+
</Document>
|
|
87
|
+
),
|
|
92
88
|
};
|
|
93
89
|
};
|
|
94
90
|
}
|
package/src/spouts/document.tsx
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Route } from '@anansi/router';
|
|
3
3
|
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
type NeededProps = {
|
|
7
|
-
matchedRoutes: Route<any>[];
|
|
8
|
-
title?: string;
|
|
9
|
-
} & ResolveProps;
|
|
4
|
+
import type { ClientSpout } from './types';
|
|
10
5
|
|
|
11
6
|
export default function documentSpout(options: {
|
|
12
7
|
head?: React.ReactNode;
|
|
13
8
|
title: string;
|
|
14
|
-
}) {
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
) {
|
|
18
|
-
return async (initData: Record<string, unknown>) => {
|
|
19
|
-
const nextProps = await next(initData);
|
|
9
|
+
}): ClientSpout {
|
|
10
|
+
return next => async props => {
|
|
11
|
+
const nextProps = await next(props);
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
};
|
|
13
|
+
return nextProps;
|
|
23
14
|
};
|
|
24
15
|
}
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Route } from '@anansi/router';
|
|
3
|
-
import { StatsChunkGroup } from 'webpack';
|
|
4
2
|
|
|
5
|
-
import type {
|
|
6
|
-
import type { Policy } from './csp';
|
|
7
|
-
import Document from './DocumentComponent';
|
|
3
|
+
import type { ServerSpout } from './types';
|
|
8
4
|
|
|
9
|
-
type
|
|
5
|
+
type NeededNext = {
|
|
10
6
|
initData?: Record<string, () => unknown>;
|
|
11
7
|
scripts?: React.ReactNode[];
|
|
12
|
-
}
|
|
8
|
+
};
|
|
13
9
|
|
|
14
10
|
export default function JSONSpout({
|
|
15
11
|
id = 'anansi-json',
|
|
16
|
-
}: { id?: string } = {})
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
}: { id?: string } = {}): ServerSpout<
|
|
13
|
+
Record<string, unknown>,
|
|
14
|
+
Record<string, unknown>,
|
|
15
|
+
NeededNext
|
|
16
|
+
> {
|
|
17
|
+
return next => async props => {
|
|
18
|
+
const nextProps = await next(props);
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const scripts: React.ReactNode[] = nextProps.scripts ?? [];
|
|
21
|
+
/*
|
|
25
22
|
Object.entries(nextProps.initData ?? {}).forEach(([key, data]) => {
|
|
26
23
|
try {
|
|
27
24
|
const encoded = JSON.stringify(data);
|
|
@@ -41,37 +38,36 @@ export default function JSONSpout({
|
|
|
41
38
|
console.error(e);
|
|
42
39
|
}
|
|
43
40
|
});*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
41
|
+
const Script = () => {
|
|
42
|
+
try {
|
|
43
|
+
const data: any = {};
|
|
44
|
+
Object.entries(nextProps.initData ?? {}).forEach(([key, getData]) => {
|
|
45
|
+
data[key] = getData();
|
|
46
|
+
});
|
|
47
|
+
const encoded = JSON.stringify(data);
|
|
48
|
+
return (
|
|
49
|
+
<script
|
|
50
|
+
key={id}
|
|
51
|
+
id={id}
|
|
52
|
+
type="application/json"
|
|
53
|
+
dangerouslySetInnerHTML={{
|
|
54
|
+
__html: encoded,
|
|
55
|
+
}}
|
|
56
|
+
nonce={props.nonce}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// TODO: Use unified logging
|
|
61
|
+
console.error('Error serializing json');
|
|
62
|
+
console.error(e);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
scripts.push(<Script />);
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
68
|
+
return {
|
|
69
|
+
...nextProps,
|
|
70
|
+
scripts,
|
|
75
71
|
};
|
|
76
72
|
};
|
|
77
73
|
}
|
package/src/spouts/json.tsx
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { Route } from '@anansi/router';
|
|
3
|
-
|
|
4
|
-
import type { ResolveProps } from './types';
|
|
5
|
-
|
|
6
|
-
type NeededProps = ResolveProps;
|
|
1
|
+
import type { ClientSpout } from './types';
|
|
7
2
|
|
|
8
3
|
export default function JSONSpout({
|
|
9
4
|
id = 'anansi-json',
|
|
10
|
-
}: { id?: string } = {})
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return nextProps;
|
|
19
|
-
};
|
|
5
|
+
}: { id?: string } = {}): ClientSpout<
|
|
6
|
+
Record<string, unknown>,
|
|
7
|
+
{ initData: Record<string, unknown> }
|
|
8
|
+
> {
|
|
9
|
+
return next => async props => {
|
|
10
|
+
const initData = getDatafromDOM(id);
|
|
11
|
+
return { ...(await next({ ...props, initData })), initData };
|
|
20
12
|
};
|
|
21
13
|
}
|
|
22
14
|
function getDatafromDOM(id: string): Record<string, unknown> {
|
|
@@ -7,14 +7,18 @@ type NeededProps<RouteWith> = {
|
|
|
7
7
|
} & ResolveProps;
|
|
8
8
|
|
|
9
9
|
export default function prefetchSpout<F extends string>(field: F) {
|
|
10
|
-
return function <
|
|
11
|
-
|
|
10
|
+
return function <
|
|
11
|
+
RouteWith,
|
|
12
|
+
N extends NeededProps<RouteWith>,
|
|
13
|
+
I extends ServerProps,
|
|
14
|
+
>(
|
|
15
|
+
next: (props: I) => Promise<
|
|
12
16
|
{
|
|
13
17
|
[K in F]: RouteWith;
|
|
14
|
-
} &
|
|
18
|
+
} & N
|
|
15
19
|
>,
|
|
16
20
|
) {
|
|
17
|
-
return async (props:
|
|
21
|
+
return async (props: I) => {
|
|
18
22
|
const nextProps = await next(props);
|
|
19
23
|
|
|
20
24
|
try {
|
|
@@ -1,34 +1,39 @@
|
|
|
1
|
-
import { Manager, NetworkManager } from '@rest-hooks/core';
|
|
1
|
+
import { Controller, Manager, NetworkManager, State } from '@rest-hooks/core';
|
|
2
|
+
import type { Store } from 'redux';
|
|
2
3
|
|
|
3
4
|
import { createPersistedStore } from './rhHelp';
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
type NeededProps = { initData?: Record<string, () => unknown> } & ResolveProps;
|
|
5
|
+
import type { ServerSpout } from './types';
|
|
7
6
|
|
|
8
7
|
export default function restHooksSpout(
|
|
9
8
|
options: {
|
|
10
9
|
getManagers: () => Manager[];
|
|
11
10
|
} = { getManagers: () => [new NetworkManager()] },
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
)
|
|
11
|
+
): ServerSpout<
|
|
12
|
+
Record<string, unknown>,
|
|
13
|
+
{ controller: Controller; store: Store<State<unknown>> },
|
|
14
|
+
{ initData?: Record<string, () => unknown> }
|
|
15
|
+
> {
|
|
16
|
+
return next => async props => {
|
|
17
|
+
const [ServerCacheProvider, controller, store] = createPersistedStore(
|
|
18
|
+
options.getManagers(),
|
|
19
|
+
);
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const nextProps = await next({
|
|
22
|
+
...props,
|
|
23
|
+
controller,
|
|
24
|
+
store,
|
|
25
|
+
});
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
initData
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
return {
|
|
28
|
+
...nextProps,
|
|
29
|
+
initData: {
|
|
30
|
+
...nextProps.initData,
|
|
31
|
+
resthooks: () => store.getState(),
|
|
32
|
+
},
|
|
33
|
+
app: <ServerCacheProvider>{nextProps.app}</ServerCacheProvider>,
|
|
34
|
+
// TODO: figure out how to only inject in next and not have to also put here
|
|
35
|
+
controller,
|
|
36
|
+
store,
|
|
32
37
|
};
|
|
33
38
|
};
|
|
34
39
|
}
|
package/src/spouts/restHooks.tsx
CHANGED
|
@@ -5,31 +5,25 @@ import {
|
|
|
5
5
|
State,
|
|
6
6
|
} from '@rest-hooks/core';
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
|
|
10
|
-
type NeededProps = ResolveProps;
|
|
8
|
+
import type { ClientSpout } from './types';
|
|
11
9
|
|
|
12
10
|
export default function restHooksSpout(
|
|
13
11
|
options: {
|
|
14
12
|
getManagers: () => Manager[];
|
|
15
13
|
} = { getManagers: () => [new NetworkManager()] },
|
|
16
|
-
) {
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
) {
|
|
20
|
-
return async (initData: Record<string, unknown>) => {
|
|
21
|
-
const data = initData.resthooks as State<unknown>;
|
|
14
|
+
): ClientSpout<{ initData: Record<string, unknown> }> {
|
|
15
|
+
return next => async props => {
|
|
16
|
+
const data = props.initData.resthooks as State<unknown>;
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
const nextProps = await next(props);
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
20
|
+
return {
|
|
21
|
+
...nextProps,
|
|
22
|
+
app: (
|
|
23
|
+
<CacheProvider initialState={data} managers={options.getManagers()}>
|
|
24
|
+
{nextProps.app}
|
|
25
|
+
</CacheProvider>
|
|
26
|
+
),
|
|
33
27
|
};
|
|
34
28
|
};
|
|
35
29
|
}
|
|
@@ -2,15 +2,19 @@ import { Route, RouteProvider, RouteController } from '@anansi/router';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { createMemoryHistory } from 'history';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
type NeededProps = ResolveProps;
|
|
5
|
+
import type { CreateRouter, ServerSpout } from './types';
|
|
8
6
|
|
|
9
7
|
export default function routerSpout<ResolveWith>(options: {
|
|
10
8
|
resolveWith?: any;
|
|
11
9
|
useResolveWith: () => ResolveWith;
|
|
12
10
|
createRouter: CreateRouter<ResolveWith>;
|
|
13
|
-
})
|
|
11
|
+
}): ServerSpout<
|
|
12
|
+
Record<string, unknown>,
|
|
13
|
+
{
|
|
14
|
+
matchedRoutes: Route<ResolveWith>[];
|
|
15
|
+
router: RouteController<Route<ResolveWith, any>>;
|
|
16
|
+
}
|
|
17
|
+
> {
|
|
14
18
|
const createRouteComponent = (
|
|
15
19
|
router: RouteController<Route<ResolveWith, any>>,
|
|
16
20
|
) =>
|
|
@@ -24,25 +28,27 @@ export default function routerSpout<ResolveWith>(options: {
|
|
|
24
28
|
);
|
|
25
29
|
};
|
|
26
30
|
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
return next => async props => {
|
|
32
|
+
const url = props.req.url || '';
|
|
33
|
+
const router = options.createRouter(
|
|
34
|
+
createMemoryHistory({ initialEntries: [url] }),
|
|
35
|
+
);
|
|
36
|
+
const matchedRoutes: Route<ResolveWith>[] = router.getMatchedRoutes(url);
|
|
37
|
+
|
|
38
|
+
const nextProps = await next({
|
|
39
|
+
...props,
|
|
40
|
+
matchedRoutes,
|
|
41
|
+
router,
|
|
42
|
+
});
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
const Router = createRouteComponent(router);
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
};
|
|
46
|
+
return {
|
|
47
|
+
...nextProps,
|
|
48
|
+
app: <Router>{nextProps.app}</Router>,
|
|
49
|
+
// TODO: figure out how to only inject in next and not have to also put here
|
|
50
|
+
matchedRoutes,
|
|
51
|
+
router,
|
|
46
52
|
};
|
|
47
53
|
};
|
|
48
54
|
}
|