vike-react 0.5.11 → 0.5.13
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/dist/components/ClientOnly.d.ts +1 -1
- package/dist/components/Head/Head-server.d.ts +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +4 -0
- package/dist/hooks/useConfig/useConfig-server.js +4 -2
- package/dist/integration/onRenderClient.js +5 -9
- package/dist/integration/onRenderHtml.js +3 -1
- package/dist/integration/resolveReactOptions.d.ts +4 -0
- package/dist/integration/resolveReactOptions.js +32 -0
- package/dist/types/Config.d.ts +15 -0
- package/dist/utils/callCumulativeHooks.d.ts +1 -1
- package/dist/utils/callCumulativeHooks.js +2 -1
- package/dist/utils/isCallable.d.ts +1 -1
- package/dist/utils/objectEntries.d.ts +2 -0
- package/dist/utils/objectEntries.js +5 -0
- package/package.json +9 -10
@@ -8,4 +8,4 @@ declare function ClientOnly<T>({ load, children, fallback, deps, }: {
|
|
8
8
|
children: (Component: React.ComponentType<T>) => ReactNode;
|
9
9
|
fallback: ReactNode;
|
10
10
|
deps?: Parameters<typeof useEffect>[1];
|
11
|
-
}): string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
|
11
|
+
}): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
export { useConfig };
|
2
2
|
import { usePageContext } from '../usePageContext.js';
|
3
3
|
import { getPageContext } from 'vike/getPageContext';
|
4
|
-
import {
|
4
|
+
import { useStreamOptional } from 'react-streaming';
|
5
5
|
import { objectKeys } from '../../utils/objectKeys.js';
|
6
6
|
import { includes } from '../../utils/includes.js';
|
7
|
+
import { assert } from '../../utils/assert.js';
|
7
8
|
import { configsCumulative } from './configsCumulative.js';
|
8
9
|
/**
|
9
10
|
* Set configurations inside components and Vike hooks.
|
@@ -17,12 +18,13 @@ function useConfig() {
|
|
17
18
|
return (config) => setPageContextConfigFromHook(config, pageContext);
|
18
19
|
// Component
|
19
20
|
pageContext = usePageContext();
|
20
|
-
const stream =
|
21
|
+
const stream = useStreamOptional();
|
21
22
|
return (config) => {
|
22
23
|
if (!pageContext._headAlreadySet) {
|
23
24
|
setPageContextConfigFromHook(config, pageContext);
|
24
25
|
}
|
25
26
|
else {
|
27
|
+
assert(stream);
|
26
28
|
// <head> already sent to the browser => send DOM-manipulating scripts during HTML streaming
|
27
29
|
apply(config, stream);
|
28
30
|
}
|
@@ -6,6 +6,7 @@ import { getPageElement } from './getPageElement.js';
|
|
6
6
|
import './styles.css';
|
7
7
|
import { callCumulativeHooks } from '../utils/callCumulativeHooks.js';
|
8
8
|
import { applyHeadSettings } from './applyHeadSettings.js';
|
9
|
+
import { resolveReactOptions } from './resolveReactOptions.js';
|
9
10
|
let root;
|
10
11
|
const onRenderClient = async (pageContext) => {
|
11
12
|
pageContext._headAlreadySet = pageContext.isHydration;
|
@@ -14,27 +15,22 @@ const onRenderClient = async (pageContext) => {
|
|
14
15
|
await callCumulativeHooks(pageContext.config.onBeforeRenderClient, pageContext);
|
15
16
|
const { page, renderPromise } = getPageElement(pageContext);
|
16
17
|
pageContext.page = page;
|
17
|
-
// TODO: implement this? So that, upon errors, onRenderClient() throws an error and Vike can render the error. As of April 2024 it isn't released yet.
|
18
|
+
// TODO: implement this? So that, upon errors, onRenderClient() throws an error and Vike can render the error page. As of April 2024 it isn't released yet.
|
18
19
|
// - https://react-dev-git-fork-rickhanlonii-rh-root-options-fbopensource.vercel.app/reference/react-dom/client/createRoot#show-a-dialog-for-uncaught-errors
|
19
20
|
// - https://react-dev-git-fork-rickhanlonii-rh-root-options-fbopensource.vercel.app/reference/react-dom/client/hydrateRoot#show-a-dialog-for-uncaught-errors
|
20
21
|
const onUncaughtError = (_error, _errorInfo) => { };
|
21
22
|
const container = document.getElementById('root');
|
23
|
+
const { hydrateRootOptions, createRootOptions } = resolveReactOptions(pageContext);
|
22
24
|
if (pageContext.isHydration &&
|
23
25
|
// Whether the page was [Server-Side Rendered](https://vike.dev/ssr).
|
24
26
|
container.innerHTML !== '') {
|
25
27
|
// First render while using SSR, i.e. [hydration](https://vike.dev/hydration)
|
26
|
-
root = ReactDOM.hydrateRoot(container, page,
|
27
|
-
// @ts-expect-error
|
28
|
-
onUncaughtError,
|
29
|
-
});
|
28
|
+
root = ReactDOM.hydrateRoot(container, page, hydrateRootOptions);
|
30
29
|
}
|
31
30
|
else {
|
32
31
|
if (!root) {
|
33
32
|
// First render without SSR
|
34
|
-
root = ReactDOM.createRoot(container,
|
35
|
-
// @ts-expect-error
|
36
|
-
onUncaughtError,
|
37
|
-
});
|
33
|
+
root = ReactDOM.createRoot(container, createRootOptions);
|
38
34
|
}
|
39
35
|
root.render(page);
|
40
36
|
}
|
@@ -10,6 +10,7 @@ import { getPageElement } from './getPageElement.js';
|
|
10
10
|
import { isReactElement } from '../utils/isReactElement.js';
|
11
11
|
import { getTagAttributesString } from '../utils/getTagAttributesString.js';
|
12
12
|
import { callCumulativeHooks } from '../utils/callCumulativeHooks.js';
|
13
|
+
import { resolveReactOptions } from './resolveReactOptions.js';
|
13
14
|
addEcosystemStamp();
|
14
15
|
const onRenderHtml = async (pageContext) => {
|
15
16
|
const pageHtml = await getPageHtml(pageContext);
|
@@ -36,11 +37,12 @@ async function getPageHtml(pageContext) {
|
|
36
37
|
pageContext.page = getPageElement(pageContext).page;
|
37
38
|
// https://github.com/vikejs/vike-react/issues/87#issuecomment-2488742744
|
38
39
|
await callCumulativeHooks(pageContext.config.onBeforeRenderHtml, pageContext);
|
40
|
+
const { renderToStringOptions } = resolveReactOptions(pageContext);
|
39
41
|
let pageHtml = '';
|
40
42
|
if (pageContext.page) {
|
41
43
|
const { stream, streamIsRequired } = pageContext.config;
|
42
44
|
if (!stream && !streamIsRequired) {
|
43
|
-
const pageHtmlString = renderToString(pageContext.page);
|
45
|
+
const pageHtmlString = renderToString(pageContext.page, renderToStringOptions);
|
44
46
|
pageContext.pageHtmlString = pageHtmlString;
|
45
47
|
pageHtml = dangerouslySkipEscape(pageHtmlString);
|
46
48
|
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
export { resolveReactOptions };
|
2
|
+
import { isCallable } from '../utils/isCallable.js';
|
3
|
+
import { objectEntries } from '../utils/objectEntries.js';
|
4
|
+
function resolveReactOptions(pageContext) {
|
5
|
+
const optionsAcc = {};
|
6
|
+
(pageContext.config.react ?? []).forEach((valUnresolved) => {
|
7
|
+
const optionList = isCallable(valUnresolved) ? valUnresolved(pageContext) : valUnresolved;
|
8
|
+
if (!optionList)
|
9
|
+
return;
|
10
|
+
objectEntries(optionList).forEach(([fnName, options]) => {
|
11
|
+
if (!options)
|
12
|
+
return;
|
13
|
+
optionsAcc[fnName] ?? (optionsAcc[fnName] = {});
|
14
|
+
objectEntries(options).forEach(([key, val]) => {
|
15
|
+
var _a;
|
16
|
+
if (!isCallable(val)) {
|
17
|
+
// @ts-ignore
|
18
|
+
(_a = optionsAcc[fnName])[key] ?? (_a[key] = val);
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
const valPrevious = optionsAcc[fnName][key];
|
22
|
+
// @ts-ignore
|
23
|
+
optionsAcc[fnName][key] = (...args) => {
|
24
|
+
valPrevious?.(...args);
|
25
|
+
val(...args);
|
26
|
+
};
|
27
|
+
}
|
28
|
+
});
|
29
|
+
});
|
30
|
+
});
|
31
|
+
return optionsAcc;
|
32
|
+
}
|
package/dist/types/Config.d.ts
CHANGED
@@ -2,6 +2,9 @@ import type { ImportString, PageContextServer, PageContext, PageContextClient }
|
|
2
2
|
import type { TagAttributes } from '../utils/getTagAttributesString.js';
|
3
3
|
import type { Viewport } from '../integration/onRenderHtml.js';
|
4
4
|
import type { ConfigsCumulative } from '../hooks/useConfig/configsCumulative.js';
|
5
|
+
import type React from 'react';
|
6
|
+
import type { HydrationOptions, RootOptions } from 'react-dom/client';
|
7
|
+
import type { ServerOptions } from 'react-dom/server';
|
5
8
|
declare global {
|
6
9
|
namespace Vike {
|
7
10
|
interface Config {
|
@@ -186,6 +189,12 @@ declare global {
|
|
186
189
|
* https://vike.dev/Loading
|
187
190
|
*/
|
188
191
|
Loading?: Loading | ImportString;
|
192
|
+
/**
|
193
|
+
* Options passed to React functions such as `createRoot()` or `hydrateRoot()`.
|
194
|
+
*
|
195
|
+
* https://vike.dev/react-setting
|
196
|
+
*/
|
197
|
+
react?: ReactOptions | ((pageContext: PageContext) => ReactOptions) | ImportString;
|
189
198
|
}
|
190
199
|
interface ConfigResolved {
|
191
200
|
Wrapper?: Wrapper[];
|
@@ -199,6 +208,7 @@ declare global {
|
|
199
208
|
onAfterRenderHtml?: Function[];
|
200
209
|
onBeforeRenderClient?: Function[];
|
201
210
|
onAfterRenderClient?: Function[];
|
211
|
+
react?: Exclude<Config['react'], ImportString>[];
|
202
212
|
}
|
203
213
|
}
|
204
214
|
}
|
@@ -218,4 +228,9 @@ type PickWithoutGetter<T, K extends keyof T> = {
|
|
218
228
|
};
|
219
229
|
export type ConfigFromHook = PickWithoutGetter<Vike.Config, 'Head' | 'title' | 'description' | 'image' | 'favicon' | 'lang' | 'viewport' | 'bodyAttributes' | 'htmlAttributes'>;
|
220
230
|
export type ConfigFromHookResolved = Omit<ConfigFromHook, ConfigsCumulative> & Pick<Vike.ConfigResolved, ConfigsCumulative>;
|
231
|
+
export type ReactOptions = {
|
232
|
+
hydrateRootOptions?: HydrationOptions;
|
233
|
+
createRootOptions?: RootOptions;
|
234
|
+
renderToStringOptions?: ServerOptions;
|
235
|
+
};
|
221
236
|
export {};
|
@@ -1,2 +1,2 @@
|
|
1
1
|
export { callCumulativeHooks };
|
2
|
-
declare function callCumulativeHooks(values: undefined |
|
2
|
+
declare function callCumulativeHooks<T>(values: undefined | T[], pageContext: Record<string, any>): Promise<(undefined | null | Exclude<T, Function>)[]>;
|
@@ -1,10 +1,11 @@
|
|
1
1
|
export { callCumulativeHooks };
|
2
2
|
import { providePageContext } from 'vike/getPageContext';
|
3
|
+
import { isCallable } from './isCallable.js';
|
3
4
|
async function callCumulativeHooks(values, pageContext) {
|
4
5
|
if (!values)
|
5
6
|
return [];
|
6
7
|
const valuesPromises = values.map((val) => {
|
7
|
-
if (
|
8
|
+
if (isCallable(val)) {
|
8
9
|
providePageContext(pageContext);
|
9
10
|
// Hook
|
10
11
|
return val(pageContext);
|
@@ -1 +1 @@
|
|
1
|
-
export declare function isCallable<T extends (...args:
|
1
|
+
export declare function isCallable<T extends (...args: any[]) => any>(thing: T | unknown): thing is T;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "vike-react",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.13",
|
4
4
|
"repository": "https://github.com/vikejs/vike-react",
|
5
5
|
"type": "module",
|
6
6
|
"exports": {
|
@@ -27,7 +27,7 @@
|
|
27
27
|
"./__internal/integration/Loading": "./dist/integration/Loading.js"
|
28
28
|
},
|
29
29
|
"dependencies": {
|
30
|
-
"react-streaming": "^0.3.
|
30
|
+
"react-streaming": "^0.3.48"
|
31
31
|
},
|
32
32
|
"peerDependencies": {
|
33
33
|
"react": ">=18.0.0",
|
@@ -38,15 +38,14 @@
|
|
38
38
|
"@biomejs/biome": "^1.6.4",
|
39
39
|
"@brillout/release-me": "^0.4.2",
|
40
40
|
"@types/node": "^20.11.17",
|
41
|
-
"@types/react": "^
|
42
|
-
"@types/react-dom": "^
|
43
|
-
"react": "^
|
44
|
-
"react-dom": "^
|
45
|
-
"react-streaming": "^0.3.43",
|
41
|
+
"@types/react": "^19.0.8",
|
42
|
+
"@types/react-dom": "^19.0.3",
|
43
|
+
"react": "^19.0.0",
|
44
|
+
"react-dom": "^19.0.0",
|
46
45
|
"rimraf": "^5.0.5",
|
47
|
-
"typescript": "^5.
|
48
|
-
"vike": "^0.4.
|
49
|
-
"vite": "^
|
46
|
+
"typescript": "^5.7.3",
|
47
|
+
"vike": "^0.4.223",
|
48
|
+
"vite": "^6.1.0"
|
50
49
|
},
|
51
50
|
"typesVersions": {
|
52
51
|
"*": {
|