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 @@
|
|
|
1
|
+
export declare const PKG_NAME = "vike-react-rsc-rudder";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/utils/getGlobalObject.ts
|
|
2
|
+
function getGlobalObject(key, defaultValue) {
|
|
3
|
+
const globalObjectsAll = globalThis[projectKey] = globalThis[projectKey] || {};
|
|
4
|
+
const globalObject = globalObjectsAll[key] = globalObjectsAll[key] || defaultValue;
|
|
5
|
+
return globalObject;
|
|
6
|
+
}
|
|
7
|
+
const projectKey = "_vike_react_rsc";
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getGlobalObject };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { usePageContext };
|
|
2
|
+
export { getPageContext };
|
|
3
|
+
export { PageContextProvider };
|
|
4
|
+
import React from "react";
|
|
5
|
+
import type { PageContext } from "vike/types";
|
|
6
|
+
declare function PageContextProvider({ pageContext, children }: {
|
|
7
|
+
pageContext: PageContext
|
|
8
|
+
children: React.ReactNode
|
|
9
|
+
}): React.ReactElement;
|
|
10
|
+
declare function usePageContext(): PageContext;
|
|
11
|
+
declare function getPageContext(): PageContext;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { usePageContext };
|
|
2
|
+
export { getPageContext };
|
|
3
|
+
export { providePageContext };
|
|
4
|
+
import type { PageContext } from "vike/types";
|
|
5
|
+
declare function providePageContext<T>(pageContext: PageContext, callback: () => T): T;
|
|
6
|
+
declare function getPageContext(): PageContext;
|
|
7
|
+
declare function usePageContext(): PageContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
2
|
+
import * as ReactClient from "@vitejs/plugin-rsc/react/browser";
|
|
3
|
+
|
|
4
|
+
//#region src/integration/client.ts
|
|
5
|
+
async function importClientRefrence(id) {
|
|
6
|
+
if (import.meta.env.DEV) return self.__raw_import(id);
|
|
7
|
+
else {
|
|
8
|
+
const clientReferences = await import("virtual:client-references");
|
|
9
|
+
const dynImport = clientReferences.default[id];
|
|
10
|
+
tinyassert(dynImport, `client reference not found '${id}'`);
|
|
11
|
+
return dynImport();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
ReactClient.setRequireModule({ load: importClientRefrence });
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { getPageElementRsc };
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type { PageContext } from "vike/types";
|
|
4
|
+
type EnsureArray<T> = NonNullable<T> extends Array<any> ? NonNullable<T> : NonNullable<T>[];
|
|
5
|
+
type ConfigMap = { [K in keyof PageContext["config"]] : EnsureArray<PageContext["config"][K]> };
|
|
6
|
+
declare global {
|
|
7
|
+
var __VIKE_RSC_PAGES_MANIFEST__: {
|
|
8
|
+
[pageId: string]: {
|
|
9
|
+
importPage: () => Promise<PageContext["Page"]>
|
|
10
|
+
getConfig: () => Promise<ConfigMap>
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare function getPageElementRsc(pageContext: PageContext): Promise<React.ReactElement>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import envName from "virtual:enviroment-name";
|
|
2
|
+
|
|
3
|
+
//#region src/integration/onBeforeRender.tsx
|
|
4
|
+
const onBeforeRender = envName === "ssr" && async function(pageContext) {
|
|
5
|
+
console.log("[Vike Hook] +onBeforeRender called.");
|
|
6
|
+
if (pageContext.handleServerAction) {
|
|
7
|
+
pageContext.handleServerAction(pageContext);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (pageContext.handleNavigation) {
|
|
11
|
+
pageContext.handleNavigation(pageContext);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { onBeforeRender };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "../getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import "../cache-BCYpxG4P.js";
|
|
3
|
+
import { onNavigate } from "../client-BpZo3JRu.js";
|
|
4
|
+
|
|
5
|
+
//#region src/integration/onPageTransitionStart.tsx
|
|
6
|
+
const onPageTransitionStart = (pageContext) => {
|
|
7
|
+
onNavigate(pageContext);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { onPageTransitionStart };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "../getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import { PageContextProvider } from "../pageContext-client-CmvZ4bmk.js";
|
|
3
|
+
import { getGlobalClientState } from "../cache-BCYpxG4P.js";
|
|
4
|
+
import { parseRscStream } from "../client-BpZo3JRu.js";
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import envName from "virtual:enviroment-name";
|
|
7
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
import ReactDOMClient from "react-dom/client";
|
|
10
|
+
|
|
11
|
+
//#region src/integration/onRenderClient.tsx
|
|
12
|
+
tinyassert(envName === "client", "Invalid environment");
|
|
13
|
+
const globalState = getGlobalClientState();
|
|
14
|
+
function Root({ initialPayload, initialPageContext }) {
|
|
15
|
+
const [payload, setPayload] = useState({
|
|
16
|
+
payload: initialPayload,
|
|
17
|
+
pageContext: initialPageContext
|
|
18
|
+
});
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
globalState.setPayload = setPayload;
|
|
21
|
+
}, []);
|
|
22
|
+
return /* @__PURE__ */ jsx(PageContextProvider, {
|
|
23
|
+
pageContext: payload.pageContext,
|
|
24
|
+
children: payload.payload.root
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const onRenderClient = async function(pageContext) {
|
|
28
|
+
globalState.pageContext = pageContext;
|
|
29
|
+
console.log("[Vike Hook] +onRenderClient called");
|
|
30
|
+
if (pageContext.isHydration) try {
|
|
31
|
+
console.log("[Client] Hydrating root");
|
|
32
|
+
const container = document.getElementById("root");
|
|
33
|
+
if (!container) {
|
|
34
|
+
console.error("[Client] Container #root not found!");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const rscPayloadStream = window.__rsc_payload_stream;
|
|
38
|
+
const initialPayload = await parseRscStream(rscPayloadStream);
|
|
39
|
+
ReactDOMClient.hydrateRoot(container, /* @__PURE__ */ jsx(Root, {
|
|
40
|
+
initialPayload,
|
|
41
|
+
initialPageContext: pageContext
|
|
42
|
+
}), { formState: initialPayload.formState });
|
|
43
|
+
console.log("[Client] Hydration complete");
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error("[Client] Hydration failed:", err);
|
|
46
|
+
}
|
|
47
|
+
else if (pageContext.isClientSideNavigation) try {
|
|
48
|
+
console.log("[Client] Client-side navigation", globalState.navigationPromise);
|
|
49
|
+
if (globalState.navigationPromise) {
|
|
50
|
+
const payload = await globalState.navigationPromise;
|
|
51
|
+
globalState.setPayload?.({
|
|
52
|
+
pageContext,
|
|
53
|
+
payload
|
|
54
|
+
});
|
|
55
|
+
} else console.error("[Client] No navigation promise found");
|
|
56
|
+
console.log("[Client] Navigation complete");
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error("[Client] Failed to navigate:", error);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { onRenderClient };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import envName from "virtual:enviroment-name";
|
|
2
|
+
import runtimeSsr from "virtual:runtime/ssr";
|
|
3
|
+
|
|
4
|
+
//#region src/integration/onRenderHtml.tsx
|
|
5
|
+
const onRenderHtml = envName === "ssr" && async function(pageContext) {
|
|
6
|
+
return runtimeSsr.onRenderHtmlSsr(pageContext);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { onRenderHtml };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import envName from "virtual:enviroment-name";
|
|
2
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
3
|
+
import { enhance } from "@universal-middleware/core";
|
|
4
|
+
import { renderPage } from "vike/server";
|
|
5
|
+
|
|
6
|
+
//#region src/integration/rscMiddleware.ts
|
|
7
|
+
tinyassert(envName === "ssr", "Invalid environment");
|
|
8
|
+
const serverActionMiddleware = envName === "ssr" && enhance(async (request) => {
|
|
9
|
+
const runtimeRsc = await import("virtual:runtime/server").then((m) => m.default);
|
|
10
|
+
const req = request;
|
|
11
|
+
const actionId = req.headers.get("x-rsc-action");
|
|
12
|
+
const urlOriginal = req.headers.get("x-vike-urloriginal");
|
|
13
|
+
if (!urlOriginal) return new Response("Missing x-vike-urloriginal header", { status: 400 });
|
|
14
|
+
const contentType = req.headers.get("content-type");
|
|
15
|
+
const body = contentType?.startsWith("multipart/form-data") ? await req.formData() : await req.text();
|
|
16
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
17
|
+
renderPage({
|
|
18
|
+
urlOriginal,
|
|
19
|
+
handleServerAction: actionId ? (pageContext) => resolve(runtimeRsc.handleServerAction({
|
|
20
|
+
actionId,
|
|
21
|
+
pageContext,
|
|
22
|
+
body
|
|
23
|
+
})) : null,
|
|
24
|
+
handleNavigation: !actionId ? (pageContext) => resolve(runtimeRsc.renderPageRsc(pageContext)) : null
|
|
25
|
+
});
|
|
26
|
+
return new Response(await promise, { headers: { "content-type": "text/x-component;charset=utf-8" } });
|
|
27
|
+
}, {
|
|
28
|
+
name: "rsc-handler",
|
|
29
|
+
method: ["GET", "POST"],
|
|
30
|
+
path: "/_rsc"
|
|
31
|
+
});
|
|
32
|
+
var rscMiddleware_default = serverActionMiddleware;
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { rscMiddleware_default as default };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getGlobalObject } from "./getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import React, { useContext } from "react";
|
|
3
|
+
import envName from "virtual:enviroment-name";
|
|
4
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/hooks/pageContext/pageContext-client.tsx
|
|
8
|
+
tinyassert(envName === "client" || envName === "ssr", "Invalid environment");
|
|
9
|
+
const globalObject = getGlobalObject("PageContextProvider.ts", { reactContext: React.createContext(void 0) });
|
|
10
|
+
function PageContextProvider({ pageContext, children }) {
|
|
11
|
+
const { reactContext } = globalObject;
|
|
12
|
+
return /* @__PURE__ */ jsx(reactContext.Provider, {
|
|
13
|
+
value: pageContext,
|
|
14
|
+
children
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function usePageContext() {
|
|
18
|
+
const { reactContext } = globalObject;
|
|
19
|
+
const pageContext = useContext(reactContext);
|
|
20
|
+
return pageContext;
|
|
21
|
+
}
|
|
22
|
+
function getPageContext() {
|
|
23
|
+
throw new Error("Cannot use getPageContext in a client component. Import usePageContext instead.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { PageContextProvider, getPageContext, usePageContext };
|
|
@@ -0,0 +1,22 @@
|
|
|
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/hooks/pageContext/pageContext-server.tsx
|
|
7
|
+
tinyassert(envName === "rsc", "Invalid environment");
|
|
8
|
+
const globalObject = getGlobalObject("PageContextProviderRsc.ts", { reactContextRsc: new AsyncLocalStorage() });
|
|
9
|
+
function providePageContext(pageContext, callback) {
|
|
10
|
+
const { reactContextRsc } = globalObject;
|
|
11
|
+
return reactContextRsc.run(pageContext, callback);
|
|
12
|
+
}
|
|
13
|
+
function getPageContext() {
|
|
14
|
+
const { reactContextRsc } = globalObject;
|
|
15
|
+
return reactContextRsc.getStore();
|
|
16
|
+
}
|
|
17
|
+
function usePageContext() {
|
|
18
|
+
throw new Error("Cannot use usePageContext in a server component or action. Import getPageContext instead.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { getPageContext as getPageContext$1, providePageContext, usePageContext as usePageContext$1 };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type PluginOption, type ViteDevServer } from "vite";
|
|
2
|
+
type GlobalState = {
|
|
3
|
+
clientReferences: Record<string, string>
|
|
4
|
+
serverReferences: Record<string, string>
|
|
5
|
+
devServer?: ViteDevServer
|
|
6
|
+
disableUseClientPlugin?: boolean
|
|
7
|
+
getCssDependencies(id: string): Promise<{
|
|
8
|
+
cssIds: string[]
|
|
9
|
+
jsIds: string[]
|
|
10
|
+
}>
|
|
11
|
+
pruneCssRegistry(id: string): void
|
|
12
|
+
isClientDependency(id: string): boolean
|
|
13
|
+
excludedModuleMap: {
|
|
14
|
+
[moduleId: string]: string[]
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
declare global {
|
|
18
|
+
var vikeReactRscGlobalState: GlobalState;
|
|
19
|
+
}
|
|
20
|
+
export default function vikeRscPlugin(): PluginOption[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { clientDepTrackerPlugin };
|
|
2
|
+
import type { Plugin } from "vite";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a client dependency tracker for handling client component dependencies
|
|
5
|
+
* Works in both development and build modes with on-demand dependency tracking
|
|
6
|
+
*/
|
|
7
|
+
declare function clientDepTrackerPlugin(): Plugin;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Plugin } from "vite";
|
|
2
|
+
import { type VitePluginServerEntryOptions } from "@brillout/vite-plugin-server-entry/plugin";
|
|
3
|
+
declare module "vite" {
|
|
4
|
+
interface UserConfig {
|
|
5
|
+
vitePluginServerEntry?: VitePluginServerEntryOptions;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export declare const configs: Plugin[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Plugin, ResolvedConfig, ViteDevServer } from "vite";
|
|
2
|
+
export { normalizeReferenceId, virtualNormalizeReferenceIdPlugin, createVirtualPlugin, hashString };
|
|
3
|
+
declare function hashString(value: string): string;
|
|
4
|
+
declare function normalizeReferenceId(id: string, name: "client" | "rsc", server: ViteDevServer, config: ResolvedConfig): Promise<string>;
|
|
5
|
+
declare function createVirtualPlugin(name: string, load: Plugin["load"]): Plugin;
|
|
6
|
+
declare function virtualNormalizeReferenceIdPlugin(): Plugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createServerReference, callServer } from "@vitejs/plugin-rsc/react/browser";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { registerClientReference, registerServerReference } from "@vitejs/plugin-rsc/react/rsc";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createServerReference, callServer } from "@vitejs/plugin-rsc/react/ssr";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { PageContext } from "vike/types";
|
|
2
|
+
import type { RscPayload } from "../types.js";
|
|
3
|
+
export type { CacheEntry } from "./client/globalState.js";
|
|
4
|
+
/**
|
|
5
|
+
* Get the cache key for a page context
|
|
6
|
+
*/
|
|
7
|
+
export declare function getCacheKey(pageContext: PageContext): string;
|
|
8
|
+
/**
|
|
9
|
+
* Get stale time from page context
|
|
10
|
+
*/
|
|
11
|
+
export declare function getStaleTime(pageContext: PageContext): number;
|
|
12
|
+
/**
|
|
13
|
+
* Get a cached entry if it exists and is not stale
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCachedPayload(pageContext: PageContext): RscPayload | null;
|
|
16
|
+
/**
|
|
17
|
+
* Store a payload in the cache
|
|
18
|
+
*/
|
|
19
|
+
export declare function cachePayload(pageContext: PageContext, payload: RscPayload): void;
|
|
20
|
+
/**
|
|
21
|
+
* Invalidate the cache entry for a specific page
|
|
22
|
+
*/
|
|
23
|
+
export declare function invalidateCache(pageContext: PageContext): void;
|
|
24
|
+
/**
|
|
25
|
+
* Mark all server component cache entries as stale
|
|
26
|
+
* This is useful when a server action changes data that server components depend on
|
|
27
|
+
*/
|
|
28
|
+
export declare function invalidateServerComponentCache(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Clear all pending server component requests
|
|
31
|
+
* This is useful when navigating between pages or when invalidating the cache
|
|
32
|
+
*/
|
|
33
|
+
export declare function clearPendingServerComponentRequests(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get a cached server component if it exists
|
|
36
|
+
* Returns the component even if it's stale (stale-while-revalidate pattern)
|
|
37
|
+
* The caller should check the isStale flag and trigger a revalidation if needed
|
|
38
|
+
*/
|
|
39
|
+
export declare function getCachedServerComponent<T>(key: string, pageContext: PageContext): {
|
|
40
|
+
component: T | null
|
|
41
|
+
isStale: boolean
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Mark a server component as being revalidated
|
|
45
|
+
*/
|
|
46
|
+
export declare function markServerComponentRevalidating(key: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Store a server component in the cache
|
|
49
|
+
*/
|
|
50
|
+
export declare function cacheServerComponent<T>(key: string, component: T, pageContext: PageContext): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PageContextClient } from "vike/types";
|
|
2
|
+
import type { RscPayload } from "../../types.js";
|
|
3
|
+
export interface GlobalClientState {
|
|
4
|
+
rscCache: Map<string, CacheEntry>;
|
|
5
|
+
serverComponentCache: Map<string, CacheEntry>;
|
|
6
|
+
pendingRequests: Map<string, Promise<any>>;
|
|
7
|
+
pageContext?: PageContextClient;
|
|
8
|
+
navigationPromise?: Promise<RscPayload>;
|
|
9
|
+
isRscCall: boolean;
|
|
10
|
+
setPayload?: React.Dispatch<React.SetStateAction<{
|
|
11
|
+
payload: RscPayload
|
|
12
|
+
pageContext: PageContextClient
|
|
13
|
+
}>>;
|
|
14
|
+
vikeRscCallServer?: Function;
|
|
15
|
+
}
|
|
16
|
+
export interface CacheEntry {
|
|
17
|
+
payload: RscPayload;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
isStale?: boolean;
|
|
20
|
+
revalidating?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function getGlobalClientState(): GlobalClientState;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PageContextClient } from "vike/types";
|
|
2
|
+
import type { RscPayload } from "../types.js";
|
|
3
|
+
export declare function callServer(id: string, args: unknown[]): Promise<RscPayload>;
|
|
4
|
+
export declare function onNavigate(pageContext: PageContextClient): Promise<RscPayload>;
|
|
5
|
+
export declare function parseRscStream(stream: ReadableStream<Uint8Array>): Promise<RscPayload>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PageContext } from "vike/types";
|
|
2
|
+
export declare function renderPageRsc(pageContext: PageContext): Promise<ReadableStream<Uint8Array<ArrayBufferLike>>>;
|
|
3
|
+
export declare function handleServerAction({ actionId, pageContext, body }: {
|
|
4
|
+
actionId: string
|
|
5
|
+
pageContext: PageContext
|
|
6
|
+
body: string | FormData
|
|
7
|
+
}): Promise<ReadableStream<Uint8Array>>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import "../getGlobalObject-CzWO6NfD.js";
|
|
2
|
+
import { provideServerActionContext } from "../serverActionContext-7Jnbh0-W.js";
|
|
3
|
+
import { providePageContext } from "../pageContext-server-B1QwrAws.js";
|
|
4
|
+
import React, { Suspense } from "react";
|
|
5
|
+
import envName from "virtual:enviroment-name";
|
|
6
|
+
import { tinyassert } from "@hiogawa/utils";
|
|
7
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
8
|
+
import * as ReactServer from "@vitejs/plugin-rsc/react/rsc";
|
|
9
|
+
|
|
10
|
+
//#region src/integration/getPageElement/getPageElement-server.tsx
|
|
11
|
+
tinyassert(envName === "rsc", "Invalid environment");
|
|
12
|
+
/**
|
|
13
|
+
* Gets page configuration from either dev or production environment
|
|
14
|
+
*/
|
|
15
|
+
async function getPageConfig(pageContext) {
|
|
16
|
+
if (!import.meta.env.DEV) return __VIKE_RSC_PAGES_MANIFEST__[pageContext.pageId].getConfig();
|
|
17
|
+
let result = {};
|
|
18
|
+
const entries = pageContext.configEntries || {};
|
|
19
|
+
for (const [key, configEntries] of Object.entries(entries).filter(([key$1]) => [
|
|
20
|
+
"Page",
|
|
21
|
+
"Layout",
|
|
22
|
+
"Wrapper",
|
|
23
|
+
"Loading"
|
|
24
|
+
].includes(key$1))) {
|
|
25
|
+
if (!configEntries?.length) continue;
|
|
26
|
+
const components = (await Promise.all(configEntries.map(async ({ configDefinedAt }) => {
|
|
27
|
+
const filePath = configDefinedAt.split(" at ").pop() || "";
|
|
28
|
+
if (!/[tj]sx?$/.test(filePath) || !(key in pageContext.config)) return null;
|
|
29
|
+
const module = await import(
|
|
30
|
+
/* @vite-ignore */
|
|
31
|
+
filePath
|
|
32
|
+
);
|
|
33
|
+
return module[key] || module.default;
|
|
34
|
+
}))).filter(Boolean);
|
|
35
|
+
result[key] = components;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
async function getPageElementRsc(pageContext) {
|
|
40
|
+
let Page = () => /* @__PURE__ */ jsx(Fragment, {});
|
|
41
|
+
let Layout = [];
|
|
42
|
+
let Wrapper = [];
|
|
43
|
+
let Loading = {};
|
|
44
|
+
if (!pageContext.pageId && !import.meta.env.DEV) throw new Error("Missing pageId in production environment");
|
|
45
|
+
const config = await getPageConfig(pageContext);
|
|
46
|
+
Page = config.Page?.[0] ?? Page;
|
|
47
|
+
Layout = config.Layout ?? Layout;
|
|
48
|
+
Wrapper = config.Wrapper ?? Wrapper;
|
|
49
|
+
Loading = config.Loading?.[0] ?? Loading;
|
|
50
|
+
let page = Page ? /* @__PURE__ */ jsx(Page, {}) : null;
|
|
51
|
+
const addSuspense = (el) => {
|
|
52
|
+
if (!Loading?.layout) return el;
|
|
53
|
+
return /* @__PURE__ */ jsx(Suspense, {
|
|
54
|
+
fallback: /* @__PURE__ */ jsx(Loading.layout, {}),
|
|
55
|
+
children: page
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
page = addSuspense(page);
|
|
59
|
+
[...Layout || [], ...Wrapper || []].forEach((Wrap) => {
|
|
60
|
+
page = /* @__PURE__ */ jsx(Wrap, { children: page });
|
|
61
|
+
page = addSuspense(page);
|
|
62
|
+
});
|
|
63
|
+
return page;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/runtime/server.tsx
|
|
68
|
+
tinyassert(envName === "rsc", "Invalid environment");
|
|
69
|
+
async function importServerReference(id) {
|
|
70
|
+
if (import.meta.env.DEV) return import(
|
|
71
|
+
/* @vite-ignore */
|
|
72
|
+
id
|
|
73
|
+
);
|
|
74
|
+
else {
|
|
75
|
+
const references = await import("virtual:server-references");
|
|
76
|
+
const dynImport = references.default[id];
|
|
77
|
+
tinyassert(dynImport, `server reference not found '${id}'`);
|
|
78
|
+
return dynImport();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
ReactServer.setRequireModule({ load: importServerReference });
|
|
82
|
+
async function renderPageRsc(pageContext) {
|
|
83
|
+
console.log("[Renderer] Rendering page to RSC stream");
|
|
84
|
+
const root = await getPageElementRsc(pageContext);
|
|
85
|
+
return providePageContext(pageContext, () => ReactServer.renderToReadableStream(
|
|
86
|
+
// TODO: add form when initial request is POST
|
|
87
|
+
{ root }
|
|
88
|
+
));
|
|
89
|
+
}
|
|
90
|
+
async function handleServerAction({ actionId, pageContext, body }) {
|
|
91
|
+
const isServerComponentCall = pageContext.headers?.["x-rsc-component-call"] === "true";
|
|
92
|
+
console.log("[Server] Handling server action:", actionId, isServerComponentCall ? "(from server component)" : "");
|
|
93
|
+
const context = { shouldRerender: false };
|
|
94
|
+
const [args, action] = await Promise.all([ReactServer.decodeReply(body), ReactServer.loadServerAction(actionId)]);
|
|
95
|
+
const returnValue = await provideServerActionContext(context, () => providePageContext(pageContext, () => action.apply(null, args)));
|
|
96
|
+
if (context.shouldRerender) {
|
|
97
|
+
console.log("[Server] Re-rendering page after server action");
|
|
98
|
+
const root = await getPageElementRsc(pageContext);
|
|
99
|
+
return providePageContext(pageContext, () => ReactServer.renderToReadableStream({
|
|
100
|
+
returnValue,
|
|
101
|
+
root
|
|
102
|
+
}));
|
|
103
|
+
} else {
|
|
104
|
+
console.log("[Server] Returning server action result without re-rendering");
|
|
105
|
+
return providePageContext(pageContext, () => ReactServer.renderToReadableStream({ returnValue }));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
export { handleServerAction, renderPageRsc };
|