@anansi/core 0.11.1 → 0.13.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 +47 -0
- package/README.md +18 -7
- package/dist/client.js +29 -12
- package/dist/client.js.map +1 -1
- package/dist/server.js +97 -79
- 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 +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -2
- package/lib/index.server.d.ts +2 -0
- package/lib/index.server.d.ts.map +1 -1
- package/lib/index.server.js +10 -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/DocumentComponent.d.ts.map +1 -1
- package/lib/spouts/DocumentComponent.js +3 -2
- 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 -2
- package/lib/spouts/document.d.ts.map +1 -1
- package/lib/spouts/document.js +3 -3
- package/lib/spouts/document.server.d.ts +2 -2
- package/lib/spouts/document.server.d.ts.map +1 -1
- package/lib/spouts/document.server.js +1 -1
- package/lib/spouts/json.d.ts +3 -1
- package/lib/spouts/json.d.ts.map +1 -1
- package/lib/spouts/json.js +6 -5
- package/lib/spouts/json.server.d.ts +2 -2
- package/lib/spouts/json.server.d.ts.map +1 -1
- package/lib/spouts/json.server.js +1 -1
- 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 -1
- package/lib/spouts/restHooks.d.ts.map +1 -1
- package/lib/spouts/restHooks.js +4 -4
- package/lib/spouts/restHooks.server.d.ts +44 -4
- package/lib/spouts/restHooks.server.d.ts.map +1 -1
- package/lib/spouts/restHooks.server.js +9 -4
- package/lib/spouts/router.d.ts +1 -1
- package/lib/spouts/router.d.ts.map +1 -1
- package/lib/spouts/router.js +3 -3
- package/lib/spouts/router.server.d.ts +5 -2
- package/lib/spouts/router.server.d.ts.map +1 -1
- package/lib/spouts/router.server.js +8 -4
- package/package.json +6 -6
- package/src/floodSpouts.tsx +2 -2
- package/src/index.server.ts +2 -0
- package/src/index.ts +2 -0
- package/src/laySpouts.tsx +23 -29
- package/src/scripts/startDevserver.ts +6 -2
- package/src/spouts/DocumentComponent.tsx +6 -1
- package/src/spouts/app.server.tsx +8 -0
- package/src/spouts/app.tsx +6 -0
- package/src/spouts/document.server.tsx +4 -4
- package/src/spouts/document.tsx +5 -5
- package/src/spouts/json.server.tsx +4 -8
- package/src/spouts/json.tsx +7 -12
- package/src/spouts/prefetch.server.tsx +8 -4
- package/src/spouts/restHooks.server.tsx +16 -7
- package/src/spouts/restHooks.tsx +6 -6
- package/src/spouts/router.server.tsx +17 -6
- package/src/spouts/router.tsx +5 -5
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
|
}
|
|
@@ -30,7 +30,12 @@ export default function Document({
|
|
|
30
30
|
const policy = {
|
|
31
31
|
...csPolicy,
|
|
32
32
|
};
|
|
33
|
-
if (
|
|
33
|
+
if (
|
|
34
|
+
nonce &&
|
|
35
|
+
// nonces negate 'unsafe-inline' so do not add it if that directive exists
|
|
36
|
+
(!policy['script-src'] ||
|
|
37
|
+
!policy['script-src'].includes("'unsafe-inline'"))
|
|
38
|
+
) {
|
|
34
39
|
if (typeof policy['script-src'] === 'string') {
|
|
35
40
|
policy['script-src'] = [policy['script-src'], `'nonce-${nonce}'`];
|
|
36
41
|
} else {
|
|
@@ -6,7 +6,7 @@ import type { ServerProps, ResolveProps } 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[];
|
|
@@ -19,10 +19,10 @@ export default function DocumentSpout(options: {
|
|
|
19
19
|
charSet?: string;
|
|
20
20
|
csPolicy?: Policy;
|
|
21
21
|
}) {
|
|
22
|
-
return function <
|
|
23
|
-
next: (props:
|
|
22
|
+
return function <N extends NeededNext, I extends ServerProps>(
|
|
23
|
+
next: (props: I) => Promise<N>,
|
|
24
24
|
) {
|
|
25
|
-
return async (props:
|
|
25
|
+
return async (props: I) => {
|
|
26
26
|
const nextProps = await next(props);
|
|
27
27
|
|
|
28
28
|
const publicPath = props.clientManifest.publicPath;
|
package/src/spouts/document.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import type { Route } from '@anansi/router';
|
|
|
3
3
|
|
|
4
4
|
import type { ResolveProps } from './types';
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type NeededNext = {
|
|
7
7
|
matchedRoutes: Route<any>[];
|
|
8
8
|
title?: string;
|
|
9
9
|
} & ResolveProps;
|
|
@@ -12,11 +12,11 @@ export default function documentSpout(options: {
|
|
|
12
12
|
head?: React.ReactNode;
|
|
13
13
|
title: string;
|
|
14
14
|
}) {
|
|
15
|
-
return function <
|
|
16
|
-
next: (
|
|
15
|
+
return function <N extends NeededNext, I extends Record<string, unknown>>(
|
|
16
|
+
next: (props: I) => Promise<N>,
|
|
17
17
|
) {
|
|
18
|
-
return async (
|
|
19
|
-
const nextProps = await next(
|
|
18
|
+
return async (props: I) => {
|
|
19
|
+
const nextProps = await next(props);
|
|
20
20
|
|
|
21
21
|
return nextProps;
|
|
22
22
|
};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Route } from '@anansi/router';
|
|
3
|
-
import { StatsChunkGroup } from 'webpack';
|
|
4
2
|
|
|
5
3
|
import type { ServerProps, ResolveProps } from './types';
|
|
6
|
-
import type { Policy } from './csp';
|
|
7
|
-
import Document from './DocumentComponent';
|
|
8
4
|
|
|
9
|
-
type
|
|
5
|
+
type NeededNext = {
|
|
10
6
|
initData?: Record<string, () => unknown>;
|
|
11
7
|
scripts?: React.ReactNode[];
|
|
12
8
|
} & ResolveProps;
|
|
@@ -14,10 +10,10 @@ type NeededProps = {
|
|
|
14
10
|
export default function JSONSpout({
|
|
15
11
|
id = 'anansi-json',
|
|
16
12
|
}: { id?: string } = {}) {
|
|
17
|
-
return function <
|
|
18
|
-
next: (props:
|
|
13
|
+
return function <N extends NeededNext, I extends ServerProps>(
|
|
14
|
+
next: (props: I) => Promise<N>,
|
|
19
15
|
) {
|
|
20
|
-
return async (props:
|
|
16
|
+
return async (props: I) => {
|
|
21
17
|
const nextProps = await next(props);
|
|
22
18
|
|
|
23
19
|
const scripts: React.ReactNode[] = nextProps.scripts ?? [];
|
package/src/spouts/json.tsx
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { Route } from '@anansi/router';
|
|
3
|
-
|
|
4
1
|
import type { ResolveProps } from './types';
|
|
5
2
|
|
|
6
|
-
type
|
|
3
|
+
type NeededNext = ResolveProps;
|
|
7
4
|
|
|
8
5
|
export default function JSONSpout({
|
|
9
6
|
id = 'anansi-json',
|
|
10
7
|
}: { id?: string } = {}) {
|
|
11
|
-
return function <
|
|
12
|
-
next: (initData: Record<string, unknown>) => Promise<
|
|
8
|
+
return function <N extends NeededNext, I extends Record<string, unknown>>(
|
|
9
|
+
next: (props: I & { initData: Record<string, unknown> }) => Promise<N>,
|
|
13
10
|
) {
|
|
14
|
-
return async () => {
|
|
11
|
+
return async (props: I) => {
|
|
15
12
|
const initData = getDatafromDOM(id);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return nextProps;
|
|
13
|
+
return await next({ ...props, initData });
|
|
19
14
|
};
|
|
20
15
|
};
|
|
21
16
|
}
|
|
22
17
|
function getDatafromDOM(id: string): Record<string, unknown> {
|
|
23
|
-
const element = document.querySelector(`#${id}`);
|
|
24
|
-
return element?.
|
|
18
|
+
const element: HTMLScriptElement | null = document.querySelector(`#${id}`);
|
|
19
|
+
return element?.text ? JSON.parse(element?.text) : undefined;
|
|
25
20
|
}
|
|
@@ -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,33 +1,42 @@
|
|
|
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
5
|
import type { ResolveProps, ServerProps } from './types';
|
|
5
6
|
|
|
6
|
-
type
|
|
7
|
+
type NeededNext = { initData?: Record<string, () => unknown> } & ResolveProps;
|
|
7
8
|
|
|
8
9
|
export default function restHooksSpout(
|
|
9
10
|
options: {
|
|
10
11
|
getManagers: () => Manager[];
|
|
11
12
|
} = { getManagers: () => [new NetworkManager()] },
|
|
12
13
|
) {
|
|
13
|
-
return function <
|
|
14
|
-
next: (
|
|
14
|
+
return function <N extends NeededNext, I extends ServerProps>(
|
|
15
|
+
next: (
|
|
16
|
+
props: I & { controller: Controller; store: Store<State<unknown>> },
|
|
17
|
+
) => Promise<N>,
|
|
15
18
|
) {
|
|
16
|
-
return async (props:
|
|
19
|
+
return async (props: I) => {
|
|
17
20
|
const [ServerCacheProvider, controller, store] = createPersistedStore(
|
|
18
21
|
options.getManagers(),
|
|
19
22
|
);
|
|
20
23
|
|
|
21
|
-
const nextProps = await next(
|
|
24
|
+
const nextProps = await next({
|
|
25
|
+
...props,
|
|
26
|
+
controller,
|
|
27
|
+
store,
|
|
28
|
+
});
|
|
22
29
|
|
|
23
30
|
return {
|
|
24
31
|
...nextProps,
|
|
25
|
-
controller,
|
|
26
32
|
initData: {
|
|
27
33
|
...nextProps.initData,
|
|
28
34
|
resthooks: () => store.getState(),
|
|
29
35
|
},
|
|
30
36
|
app: <ServerCacheProvider>{nextProps.app}</ServerCacheProvider>,
|
|
37
|
+
// TODO: figure out how to only inject in next and not have to also put here
|
|
38
|
+
controller,
|
|
39
|
+
store,
|
|
31
40
|
};
|
|
32
41
|
};
|
|
33
42
|
};
|
package/src/spouts/restHooks.tsx
CHANGED
|
@@ -7,20 +7,20 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import type { ResolveProps } from './types';
|
|
9
9
|
|
|
10
|
-
type
|
|
10
|
+
type NeededNext = ResolveProps;
|
|
11
11
|
|
|
12
12
|
export default function restHooksSpout(
|
|
13
13
|
options: {
|
|
14
14
|
getManagers: () => Manager[];
|
|
15
15
|
} = { getManagers: () => [new NetworkManager()] },
|
|
16
16
|
) {
|
|
17
|
-
return function <
|
|
18
|
-
next: (
|
|
17
|
+
return function <N extends NeededNext, I extends Record<string, unknown>>(
|
|
18
|
+
next: (props: I) => Promise<N>,
|
|
19
19
|
) {
|
|
20
|
-
return async (initData: Record<string, unknown>) => {
|
|
21
|
-
const data = initData.resthooks as State<unknown>;
|
|
20
|
+
return async (props: I & { initData: Record<string, unknown> }) => {
|
|
21
|
+
const data = props.initData.resthooks as State<unknown>;
|
|
22
22
|
|
|
23
|
-
const nextProps = await next(
|
|
23
|
+
const nextProps = await next(props);
|
|
24
24
|
|
|
25
25
|
return {
|
|
26
26
|
...nextProps,
|
|
@@ -4,7 +4,7 @@ import { createMemoryHistory } from 'history';
|
|
|
4
4
|
|
|
5
5
|
import type { ResolveProps, ServerProps, CreateRouter } from './types';
|
|
6
6
|
|
|
7
|
-
type
|
|
7
|
+
type NeededNext = ResolveProps;
|
|
8
8
|
|
|
9
9
|
export default function routerSpout<ResolveWith>(options: {
|
|
10
10
|
resolveWith?: any;
|
|
@@ -24,24 +24,35 @@ export default function routerSpout<ResolveWith>(options: {
|
|
|
24
24
|
);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
return function <
|
|
28
|
-
next: (
|
|
27
|
+
return function <N extends NeededNext, I extends ServerProps>(
|
|
28
|
+
next: (
|
|
29
|
+
props: I & {
|
|
30
|
+
matchedRoutes: Route<ResolveWith>[];
|
|
31
|
+
router: RouteController<Route<ResolveWith, any>>;
|
|
32
|
+
},
|
|
33
|
+
) => Promise<N>,
|
|
29
34
|
) {
|
|
30
|
-
return async (props:
|
|
35
|
+
return async (props: I) => {
|
|
31
36
|
const url = props.req.url || '';
|
|
32
37
|
const router = options.createRouter(
|
|
33
38
|
createMemoryHistory({ initialEntries: [url] }),
|
|
34
39
|
);
|
|
35
40
|
const matchedRoutes: Route<ResolveWith>[] = router.getMatchedRoutes(url);
|
|
36
41
|
|
|
37
|
-
const nextProps = await next(
|
|
42
|
+
const nextProps = await next({
|
|
43
|
+
...props,
|
|
44
|
+
matchedRoutes,
|
|
45
|
+
router,
|
|
46
|
+
});
|
|
38
47
|
|
|
39
48
|
const Router = createRouteComponent(router);
|
|
49
|
+
|
|
40
50
|
return {
|
|
41
51
|
...nextProps,
|
|
52
|
+
app: <Router>{nextProps.app}</Router>,
|
|
53
|
+
// TODO: figure out how to only inject in next and not have to also put here
|
|
42
54
|
matchedRoutes,
|
|
43
55
|
router,
|
|
44
|
-
app: <Router>{nextProps.app}</Router>,
|
|
45
56
|
};
|
|
46
57
|
};
|
|
47
58
|
};
|
package/src/spouts/router.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import type { Update } from 'history';
|
|
|
5
5
|
|
|
6
6
|
import type { ResolveProps, CreateRouter } from './types';
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type NeededNext = ResolveProps;
|
|
9
9
|
|
|
10
10
|
export default function routerSpout<ResolveWith>(options: {
|
|
11
11
|
resolveWith?: any;
|
|
@@ -30,15 +30,15 @@ export default function routerSpout<ResolveWith>(options: {
|
|
|
30
30
|
);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
return function <
|
|
34
|
-
next: (initData: Record<string, unknown>) => Promise<
|
|
33
|
+
return function <N extends NeededNext, I extends Record<string, unknown>>(
|
|
34
|
+
next: (initData: Record<string, unknown>) => Promise<N>,
|
|
35
35
|
) {
|
|
36
|
-
return async (
|
|
36
|
+
return async (props: I) => {
|
|
37
37
|
const history = createBrowserHistory();
|
|
38
38
|
const router = options.createRouter(history);
|
|
39
39
|
const matchedRoutes = router.getMatchedRoutes(history.location.pathname);
|
|
40
40
|
|
|
41
|
-
const nextProps = await next(
|
|
41
|
+
const nextProps = await next(props);
|
|
42
42
|
|
|
43
43
|
const Router = createRouteComponent(router);
|
|
44
44
|
return {
|