vike-react-rsc-rudder 1.0.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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/cache-BCYpxG4P.js +164 -0
- package/dist/client-BpZo3JRu.js +86 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +53 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +875 -0
- package/dist/constants.d.ts +1 -0
- package/dist/getGlobalObject-CzWO6NfD.js +10 -0
- package/dist/hooks/pageContext/pageContext-client.d.ts +11 -0
- package/dist/hooks/pageContext/pageContext-client.js +4 -0
- package/dist/hooks/pageContext/pageContext-server.d.ts +7 -0
- package/dist/hooks/pageContext/pageContext-server.js +4 -0
- package/dist/integration/client.d.ts +1 -0
- package/dist/integration/client.js +16 -0
- package/dist/integration/getPageElement/getPageElement-server.d.ts +14 -0
- package/dist/integration/onBeforeRender.d.ts +2 -0
- package/dist/integration/onBeforeRender.js +17 -0
- package/dist/integration/onPageTransitionStart.d.ts +2 -0
- package/dist/integration/onPageTransitionStart.js +11 -0
- package/dist/integration/onRenderClient.d.ts +2 -0
- package/dist/integration/onRenderClient.js +63 -0
- package/dist/integration/onRenderHtml.d.ts +2 -0
- package/dist/integration/onRenderHtml.js +10 -0
- package/dist/integration/rscMiddleware.d.ts +3 -0
- package/dist/integration/rscMiddleware.js +35 -0
- package/dist/pageContext-client-CmvZ4bmk.js +27 -0
- package/dist/pageContext-server-B1QwrAws.js +22 -0
- package/dist/plugin/index.d.ts +20 -0
- package/dist/plugin/plugins/clientDepTrackerPlugin.d.ts +7 -0
- package/dist/plugin/plugins/config.d.ts +8 -0
- package/dist/plugin/plugins/cssTrackerPlugin.d.ts +6 -0
- package/dist/plugin/plugins/dev.d.ts +2 -0
- package/dist/plugin/plugins/hmrPlugin.d.ts +2 -0
- package/dist/plugin/plugins/injectManifestBuild.d.ts +6 -0
- package/dist/plugin/plugins/serverComponentExclusionPlugin.d.ts +6 -0
- package/dist/plugin/plugins/useClientPlugin.d.ts +2 -0
- package/dist/plugin/plugins/useServerPlugin.d.ts +2 -0
- package/dist/plugin/plugins/virtuals.d.ts +2 -0
- package/dist/plugin/utils.d.ts +6 -0
- package/dist/register/browser.d.ts +1 -0
- package/dist/register/browser.js +3 -0
- package/dist/register/server.d.ts +1 -0
- package/dist/register/server.js +3 -0
- package/dist/register/ssr.d.ts +1 -0
- package/dist/register/ssr.js +3 -0
- package/dist/runtime/cache.d.ts +50 -0
- package/dist/runtime/client/globalState.d.ts +22 -0
- package/dist/runtime/client.d.ts +5 -0
- package/dist/runtime/rscBridge.d.ts +7 -0
- package/dist/runtime/server.d.ts +7 -0
- package/dist/runtime/server.js +110 -0
- package/dist/runtime/serverActionContext.d.ts +23 -0
- package/dist/runtime/ssr.d.ts +2 -0
- package/dist/runtime/ssr.js +107 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +4 -0
- package/dist/serverActionContext-7Jnbh0-W.js +38 -0
- package/dist/types/Config.d.ts +59 -0
- package/dist/types.d.ts +22 -0
- package/dist/utils/getGlobalObject.d.ts +1 -0
- package/dist/utils/isReactElement.d.ts +5 -0
- package/package.json +81 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { rerender };
|
|
2
|
+
export { getServerActionContext };
|
|
3
|
+
export { provideServerActionContext };
|
|
4
|
+
export interface ServerActionContextType {
|
|
5
|
+
shouldRerender: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Provides a server action context for the duration of the callback execution
|
|
9
|
+
* @param context The server action context
|
|
10
|
+
* @param callback The function to execute within the context
|
|
11
|
+
* @returns The result of the callback
|
|
12
|
+
*/
|
|
13
|
+
declare function provideServerActionContext<T>(context: ServerActionContextType, callback: () => T): T;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the current server action context
|
|
16
|
+
* @returns The current server action context or undefined if not in a server action
|
|
17
|
+
*/
|
|
18
|
+
declare function getServerActionContext(): ServerActionContextType | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Call this function within a server action to trigger a re-render of the page
|
|
21
|
+
* If not called, the server action will only return the action result without re-rendering
|
|
22
|
+
*/
|
|
23
|
+
declare function rerender(): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import "../getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import { PageContextProvider } from "../pageContext-client-CmvZ4bmk.js";
|
|
3
|
+
import React, { isValidElement } from "react";
|
|
4
|
+
import envName from "virtual:enviroment-name";
|
|
5
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { dangerouslySkipEscape, escapeInject } from "vike/server";
|
|
8
|
+
import * as ReactServerDOMClient from "@vitejs/plugin-rsc/react/ssr";
|
|
9
|
+
import { renderToStream } from "react-streaming/server.web";
|
|
10
|
+
import runtimeRsc from "virtual:runtime/server";
|
|
11
|
+
import { renderToStaticMarkup } from "react-dom/server.edge";
|
|
12
|
+
|
|
13
|
+
//#region src/utils/isReactElement.ts
|
|
14
|
+
function isReactElement(value) {
|
|
15
|
+
return isValidElement(value) || Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/runtime/ssr.tsx
|
|
20
|
+
tinyassert(envName === "ssr", "Invalid environment");
|
|
21
|
+
const INIT_SCRIPT = `
|
|
22
|
+
self.__raw_import = (id) => import(id);
|
|
23
|
+
self.__rsc_web_stream = new ReadableStream({
|
|
24
|
+
start(controller) {
|
|
25
|
+
self.__rsc_web_stream_push = (chunk) => { controller.enqueue(chunk); };
|
|
26
|
+
self.__rsc_web_stream_close = () => { controller.close(); };
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (!self.TextEncoderStream) {
|
|
30
|
+
self.TextEncoderStream = class { _controller; encoder = new TextEncoder(); readable = new ReadableStream({ start: c => this._controller = c }); writable = new WritableStream({ write: chunk => this._controller.enqueue(this.encoder.encode(chunk)), close: () => this._controller.close() }); };
|
|
31
|
+
}
|
|
32
|
+
self.__rsc_payload_stream = self.__rsc_web_stream.pipeThrough(new TextEncoderStream());
|
|
33
|
+
console.log('[RSC Init Script] Payload stream setup on window.__rsc_payload_stream');
|
|
34
|
+
`;
|
|
35
|
+
async function importClientReference(id) {
|
|
36
|
+
if (import.meta.env.DEV) return import(
|
|
37
|
+
/* @vite-ignore */
|
|
38
|
+
id
|
|
39
|
+
);
|
|
40
|
+
else {
|
|
41
|
+
const clientReferences = await import("virtual:client-references");
|
|
42
|
+
const dynImport = clientReferences.default[id];
|
|
43
|
+
console.log("[RSC] Importing client reference", id);
|
|
44
|
+
tinyassert(dynImport, `client reference not found '${id}'`);
|
|
45
|
+
return dynImport();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
ReactServerDOMClient.setRequireModule({ load: importClientReference });
|
|
49
|
+
const onRenderHtmlSsr = async function(pageContext) {
|
|
50
|
+
const rscPayloadStream = await runtimeRsc.renderPageRsc(pageContext);
|
|
51
|
+
const [rscStreamForHtml, rscStreamForClientScript] = rscPayloadStream.tee();
|
|
52
|
+
const payload = await ReactServerDOMClient.createFromReadableStream(rscStreamForHtml);
|
|
53
|
+
const htmlStream = await renderToStream(/* @__PURE__ */ jsx(PageContextProvider, {
|
|
54
|
+
pageContext,
|
|
55
|
+
children: payload.root
|
|
56
|
+
}), {
|
|
57
|
+
userAgent: pageContext.headers?.["user-agent"],
|
|
58
|
+
streamOptions: { formState: payload.formState }
|
|
59
|
+
});
|
|
60
|
+
const canClose = htmlStream.doNotClose();
|
|
61
|
+
rscStreamForClientScript.pipeThrough(new TextDecoderStream()).pipeTo(new WritableStream({
|
|
62
|
+
write(rscChunk) {
|
|
63
|
+
htmlStream.injectToStream(`<script>self.__rsc_web_stream_push(${JSON.stringify(rscChunk)})</script>`);
|
|
64
|
+
},
|
|
65
|
+
async close() {
|
|
66
|
+
console.log("RSC stream closed, injecting close script.");
|
|
67
|
+
htmlStream.injectToStream(`<script>self.__rsc_web_stream_close()</script>`);
|
|
68
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
69
|
+
canClose();
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
const headHtml = getHeadHtml(pageContext);
|
|
73
|
+
const documentHtml = escapeInject`<!DOCTYPE html>
|
|
74
|
+
<html>
|
|
75
|
+
<head>
|
|
76
|
+
<meta charset="UTF-8" />
|
|
77
|
+
<script>${dangerouslySkipEscape(INIT_SCRIPT)}</script>
|
|
78
|
+
${headHtml}
|
|
79
|
+
</head>
|
|
80
|
+
<body>
|
|
81
|
+
<div id="root">${htmlStream}</div>
|
|
82
|
+
</body>
|
|
83
|
+
</html>`;
|
|
84
|
+
return {
|
|
85
|
+
documentHtml,
|
|
86
|
+
pageContext: { enableEagerStreaming: true }
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
function getHeadHtml(pageContext) {
|
|
90
|
+
const headElementsHtml = dangerouslySkipEscape([...pageContext.config.Head ?? []].filter((Head) => Head !== null && Head !== void 0).map((Head) => getHeadElementHtml(Head, pageContext)).join("\n"));
|
|
91
|
+
const headHtml = escapeInject`
|
|
92
|
+
${headElementsHtml}
|
|
93
|
+
`;
|
|
94
|
+
return headHtml;
|
|
95
|
+
}
|
|
96
|
+
function getHeadElementHtml(Head, pageContext) {
|
|
97
|
+
let headElement;
|
|
98
|
+
if (isReactElement(Head)) headElement = Head;
|
|
99
|
+
else headElement = /* @__PURE__ */ jsx(PageContextProvider, {
|
|
100
|
+
pageContext,
|
|
101
|
+
children: /* @__PURE__ */ jsx(Head, {})
|
|
102
|
+
});
|
|
103
|
+
return renderToStaticMarkup(headElement);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//#endregion
|
|
107
|
+
export { onRenderHtmlSsr };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { rerender } from "./runtime/serverActionContext.js";
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getGlobalObject } from "./getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import envName from "virtual:enviroment-name";
|
|
3
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
4
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/serverActionContext.ts
|
|
7
|
+
tinyassert(envName === "rsc", "Invalid environment");
|
|
8
|
+
const globalObject = getGlobalObject("ServerActionContext.ts", { serverActionContext: new AsyncLocalStorage() });
|
|
9
|
+
/**
|
|
10
|
+
* Provides a server action context for the duration of the callback execution
|
|
11
|
+
* @param context The server action context
|
|
12
|
+
* @param callback The function to execute within the context
|
|
13
|
+
* @returns The result of the callback
|
|
14
|
+
*/
|
|
15
|
+
function provideServerActionContext(context, callback) {
|
|
16
|
+
const { serverActionContext } = globalObject;
|
|
17
|
+
return serverActionContext.run(context, callback);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Gets the current server action context
|
|
21
|
+
* @returns The current server action context or undefined if not in a server action
|
|
22
|
+
*/
|
|
23
|
+
function getServerActionContext() {
|
|
24
|
+
const { serverActionContext } = globalObject;
|
|
25
|
+
return serverActionContext.getStore();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Call this function within a server action to trigger a re-render of the page
|
|
29
|
+
* If not called, the server action will only return the action result without re-rendering
|
|
30
|
+
*/
|
|
31
|
+
function rerender() {
|
|
32
|
+
const context = getServerActionContext();
|
|
33
|
+
if (context) context.shouldRerender = true;
|
|
34
|
+
else console.warn("[Server] rerender() called outside of a server action context");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { provideServerActionContext, rerender };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { ImportString } from "vike/types";
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Vike {
|
|
5
|
+
interface Config {
|
|
6
|
+
/**
|
|
7
|
+
* The page's root React component.
|
|
8
|
+
*
|
|
9
|
+
* https://vike.dev/Page
|
|
10
|
+
*/
|
|
11
|
+
Page?: () => React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Add arbitrary `<head>` tags.
|
|
14
|
+
*
|
|
15
|
+
* https://vike.dev/Head
|
|
16
|
+
*/
|
|
17
|
+
Head?: Head;
|
|
18
|
+
/**
|
|
19
|
+
* A component that defines the visual layout common to several pages.
|
|
20
|
+
*
|
|
21
|
+
* Technically: the `<Layout>` component wraps the root component `<Page>`.
|
|
22
|
+
*
|
|
23
|
+
* https://vike.dev/Layout
|
|
24
|
+
*/
|
|
25
|
+
Layout?: Layout;
|
|
26
|
+
/**
|
|
27
|
+
* A component wrapping the the root component `<Page>`.
|
|
28
|
+
*
|
|
29
|
+
* https://vike.dev/Wrapper
|
|
30
|
+
*/
|
|
31
|
+
Wrapper?: Wrapper | ImportString;
|
|
32
|
+
/**
|
|
33
|
+
* Define loading animations.
|
|
34
|
+
*
|
|
35
|
+
* https://vike.dev/Loading
|
|
36
|
+
*/
|
|
37
|
+
Loading?: Loading | ImportString;
|
|
38
|
+
rsc?: RscConfig;
|
|
39
|
+
}
|
|
40
|
+
interface ConfigResolved {
|
|
41
|
+
Wrapper?: Wrapper[];
|
|
42
|
+
Layout?: Layout[];
|
|
43
|
+
Head?: Head[];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export type Head = React.ReactNode | (() => React.ReactNode);
|
|
48
|
+
type Wrapper = (props: {
|
|
49
|
+
children: React.ReactNode
|
|
50
|
+
}) => React.ReactNode;
|
|
51
|
+
type Layout = Wrapper;
|
|
52
|
+
type Loading = {
|
|
53
|
+
component?: () => React.ReactNode
|
|
54
|
+
layout?: () => React.ReactNode
|
|
55
|
+
};
|
|
56
|
+
type RscConfig = {
|
|
57
|
+
staleTime?: number
|
|
58
|
+
};
|
|
59
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactFormState } from "react-dom/client";
|
|
2
|
+
export interface ImportManifestEntry {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
chunks: string[];
|
|
6
|
+
async?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface BundlerConfig {
|
|
9
|
+
[bundlerId: string]: ImportManifestEntry;
|
|
10
|
+
}
|
|
11
|
+
export type RscPayload = {
|
|
12
|
+
root?: React.ReactNode
|
|
13
|
+
formState?: ReactFormState
|
|
14
|
+
returnValue?: unknown
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* User-defined RSC configuration
|
|
18
|
+
*/
|
|
19
|
+
export interface RscConfig {
|
|
20
|
+
/** How long (in ms) a cache entry is considered fresh. Set to 0 to disable caching. */
|
|
21
|
+
staleTime?: number;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T;
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vike-react-rsc-rudder",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React Server Components for Vike — RudderJS-maintained fork of vike-react-rsc by nitedani (MIT). See README.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "nitedani (original); RudderJS (fork)",
|
|
7
|
+
"homepage": "https://github.com/rudderjs/rudder/tree/main/packages/vike-react-rsc#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/rudderjs/rudder.git",
|
|
11
|
+
"directory": "packages/vike-react-rsc"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/rudderjs/rudder/issues"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"vike",
|
|
21
|
+
"rsc",
|
|
22
|
+
"react-server-components",
|
|
23
|
+
"react",
|
|
24
|
+
"ssr",
|
|
25
|
+
"rudderjs"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
"./config": "./dist/config.js",
|
|
29
|
+
"./server": "./dist/server.js",
|
|
30
|
+
"./client": "./dist/client.js",
|
|
31
|
+
"./pageContext": {
|
|
32
|
+
"react-server": "./dist/hooks/pageContext/pageContext-server.js",
|
|
33
|
+
"default": "./dist/hooks/pageContext/pageContext-client.js"
|
|
34
|
+
},
|
|
35
|
+
"./__internal/integration/onRenderHtml": "./dist/integration/onRenderHtml.js",
|
|
36
|
+
"./__internal/integration/onRenderClient": "./dist/integration/onRenderClient.js",
|
|
37
|
+
"./__internal/integration/onBeforeRender": "./dist/integration/onBeforeRender.js",
|
|
38
|
+
"./__internal/integration/onPageTransitionStart": "./dist/integration/onPageTransitionStart.js",
|
|
39
|
+
"./__internal/integration/rscMiddleware": "./dist/integration/rscMiddleware.js",
|
|
40
|
+
"./__internal/integration/client": "./dist/integration/client.js",
|
|
41
|
+
"./__internal/register/browser": "./dist/register/browser.js",
|
|
42
|
+
"./__internal/register/server": "./dist/register/server.js",
|
|
43
|
+
"./__internal/register/ssr": "./dist/register/ssr.js",
|
|
44
|
+
"./__internal/runtime/server": "./dist/runtime/server.js",
|
|
45
|
+
"./__internal/runtime/ssr": "./dist/runtime/ssr.js"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist"
|
|
49
|
+
],
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": "*",
|
|
53
|
+
"react-dom": "*",
|
|
54
|
+
"vike": "*",
|
|
55
|
+
"vite": "*"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@brillout/json-serializer": "^0.5.15",
|
|
59
|
+
"@brillout/vite-plugin-server-entry": "^0.7.5",
|
|
60
|
+
"@hiogawa/transforms": "^0.0.0",
|
|
61
|
+
"@hiogawa/utils": "^1.7.0",
|
|
62
|
+
"@universal-middleware/core": "^0.4.17",
|
|
63
|
+
"@vitejs/plugin-rsc": "0.5.1",
|
|
64
|
+
"react-streaming": "^0.4.12"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/react": "^19.2.0",
|
|
68
|
+
"@types/react-dom": "^19.2.0",
|
|
69
|
+
"react": "^19.2.0",
|
|
70
|
+
"react-dom": "^19.2.0",
|
|
71
|
+
"tsdown": "^0.6.10",
|
|
72
|
+
"typescript": "^5.4.0",
|
|
73
|
+
"vike": "^0.4.257",
|
|
74
|
+
"vite": "^7.2.0",
|
|
75
|
+
"vitefu": "^1.1.1"
|
|
76
|
+
},
|
|
77
|
+
"scripts": {
|
|
78
|
+
"build": "tsdown --clean",
|
|
79
|
+
"dev": "tsdown --watch --sourcemap"
|
|
80
|
+
}
|
|
81
|
+
}
|