rwsdk 0.2.0-alpha.13 → 0.2.0-alpha.15
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/runtime/client/client.d.ts +10 -0
- package/dist/runtime/{client.js → client/client.js} +13 -10
- package/dist/runtime/{clientNavigation.test.js → client/navigation.test.js} +1 -1
- package/dist/runtime/client/setWebpackRequire.d.ts +1 -0
- package/dist/runtime/client/setWebpackRequire.js +2 -0
- package/dist/runtime/{client.d.ts → client/types.d.ts} +4 -10
- package/dist/runtime/client/types.js +1 -0
- package/dist/runtime/entries/client.d.ts +2 -2
- package/dist/runtime/entries/client.js +2 -2
- package/dist/runtime/imports/client.d.ts +3 -3
- package/dist/runtime/imports/client.js +6 -5
- package/dist/runtime/imports/ssr.d.ts +3 -3
- package/dist/runtime/imports/ssr.js +3 -3
- package/dist/runtime/imports/worker.d.ts +3 -3
- package/dist/runtime/imports/worker.js +3 -3
- package/dist/runtime/lib/manifest.d.ts +11 -2
- package/dist/runtime/lib/manifest.js +1 -1
- package/dist/runtime/lib/memoizeOnId.d.ts +1 -0
- package/dist/runtime/lib/memoizeOnId.js +11 -0
- package/dist/runtime/lib/realtime/client.d.ts +1 -1
- package/dist/runtime/lib/realtime/client.js +1 -1
- package/dist/runtime/register/ssr.d.ts +1 -1
- package/dist/runtime/register/ssr.js +2 -2
- package/dist/runtime/render/preloads.d.ts +6 -0
- package/dist/runtime/render/preloads.js +40 -0
- package/dist/runtime/render/renderRscThenableToHtmlStream.js +2 -1
- package/dist/runtime/render/stylesheets.js +1 -1
- package/dist/runtime/requestInfo/types.d.ts +3 -1
- package/dist/runtime/worker.js +1 -1
- package/dist/vite/miniflareHMRPlugin.mjs +3 -0
- package/package.json +1 -1
- /package/dist/runtime/{imports → client}/ClientOnly.d.ts +0 -0
- /package/dist/runtime/{imports → client}/ClientOnly.js +0 -0
- /package/dist/runtime/{clientNavigation.d.ts → client/navigation.d.ts} +0 -0
- /package/dist/runtime/{clientNavigation.js → client/navigation.js} +0 -0
- /package/dist/runtime/{clientNavigation.test.d.ts → client/navigation.test.d.ts} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "./setWebpackRequire";
|
|
2
|
+
export { ClientOnly } from "./ClientOnly.js";
|
|
3
|
+
export { default as React } from "react";
|
|
4
|
+
import type { Transport, HydrationOptions } from "./types";
|
|
5
|
+
export declare const fetchTransport: Transport;
|
|
6
|
+
export declare const initClient: ({ transport, hydrateRootOptions, handleResponse, }?: {
|
|
7
|
+
transport?: Transport;
|
|
8
|
+
hydrateRootOptions?: HydrationOptions;
|
|
9
|
+
handleResponse?: (response: Response) => boolean;
|
|
10
|
+
}) => Promise<void>;
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
2
|
+
// note(justinvdm, 14 Aug 2025): Rendering related imports and logic go here.
|
|
3
|
+
// See client.tsx for the actual client entrypoint.
|
|
4
|
+
// context(justinvdm, 14 Aug 2025): `react-server-dom-webpack` uses this global
|
|
5
|
+
// to load modules, so we need to define it here before importing
|
|
6
|
+
// "react-server-dom-webpack."
|
|
7
|
+
import "./setWebpackRequire";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { hydrateRoot } from "react-dom/client";
|
|
10
|
+
import { createFromReadableStream, createFromFetch, encodeReply, } from "react-server-dom-webpack/client.browser";
|
|
11
|
+
import { rscStream } from "rsc-html-stream/client";
|
|
12
|
+
export { ClientOnly } from "./ClientOnly.js";
|
|
13
|
+
export { default as React } from "react";
|
|
6
14
|
export const fetchTransport = (transportContext) => {
|
|
7
15
|
const fetchCallServer = async (id, args) => {
|
|
8
|
-
const { createFromFetch, encodeReply } = await import("react-server-dom-webpack/client.browser");
|
|
9
16
|
const url = new URL(window.location.href);
|
|
10
17
|
url.searchParams.set("__rsc", "");
|
|
11
18
|
if (id != null) {
|
|
@@ -41,8 +48,6 @@ export const fetchTransport = (transportContext) => {
|
|
|
41
48
|
return fetchCallServer;
|
|
42
49
|
};
|
|
43
50
|
export const initClient = async ({ transport = fetchTransport, hydrateRootOptions, handleResponse, } = {}) => {
|
|
44
|
-
const React = await import("react");
|
|
45
|
-
const { hydrateRoot } = await import("react-dom/client");
|
|
46
51
|
const transportContext = {
|
|
47
52
|
setRscPayload: () => { },
|
|
48
53
|
handleResponse,
|
|
@@ -50,7 +55,7 @@ export const initClient = async ({ transport = fetchTransport, hydrateRootOption
|
|
|
50
55
|
let transportCallServer = transport(transportContext);
|
|
51
56
|
const callServer = (id, args) => transportCallServer(id, args);
|
|
52
57
|
const upgradeToRealtime = async ({ key } = {}) => {
|
|
53
|
-
const { realtimeTransport } = await import("
|
|
58
|
+
const { realtimeTransport } = await import("../lib/realtime/client");
|
|
54
59
|
const createRealtimeTransport = realtimeTransport({ key });
|
|
55
60
|
transportCallServer = createRealtimeTransport(transportContext);
|
|
56
61
|
};
|
|
@@ -67,8 +72,6 @@ export const initClient = async ({ transport = fetchTransport, hydrateRootOption
|
|
|
67
72
|
// context(justinvdm, 18 Jun 2025): We inject the RSC payload
|
|
68
73
|
// unless render(Document, [...], { rscPayload: false }) was used.
|
|
69
74
|
if (globalThis.__FLIGHT_DATA) {
|
|
70
|
-
const { createFromReadableStream } = await import("react-server-dom-webpack/client.browser");
|
|
71
|
-
const { rscStream } = await import("rsc-html-stream/client");
|
|
72
75
|
rscPayload = createFromReadableStream(rscStream, {
|
|
73
76
|
callServer,
|
|
74
77
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { CallServerCallback } from "react-server-dom-webpack/client.browser";
|
|
2
|
+
export type { CallServerCallback } from "react-server-dom-webpack/client.browser";
|
|
3
|
+
export type { HydrationOptions } from "react-dom/client";
|
|
3
4
|
export type ActionResponse<Result> = {
|
|
4
5
|
node: React.ReactNode;
|
|
5
6
|
actionResult: Result;
|
|
6
7
|
};
|
|
7
|
-
type TransportContext = {
|
|
8
|
+
export type TransportContext = {
|
|
8
9
|
setRscPayload: <Result>(v: Promise<ActionResponse<Result>>) => void;
|
|
9
10
|
handleResponse?: (response: Response) => boolean;
|
|
10
11
|
};
|
|
11
12
|
export type Transport = (context: TransportContext) => CallServerCallback;
|
|
12
13
|
export type CreateCallServer = (context: TransportContext) => <Result>(id: null | string, args: null | unknown[]) => Promise<Result>;
|
|
13
|
-
export declare const fetchTransport: Transport;
|
|
14
|
-
export declare const initClient: ({ transport, hydrateRootOptions, handleResponse, }?: {
|
|
15
|
-
transport?: Transport;
|
|
16
|
-
hydrateRootOptions?: HydrationOptions;
|
|
17
|
-
handleResponse?: (response: Response) => boolean;
|
|
18
|
-
}) => Promise<void>;
|
|
19
|
-
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const loadModule: (
|
|
2
|
-
export declare const clientWebpackRequire: (
|
|
1
|
+
export declare const loadModule: (id: string) => Promise<any>;
|
|
2
|
+
export declare const clientWebpackRequire: (id: string) => Promise<{
|
|
3
3
|
[x: string]: any;
|
|
4
|
-
}
|
|
4
|
+
}>;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import { ClientOnly } from "../client/client";
|
|
3
|
+
import { memoizeOnId } from "../lib/memoizeOnId";
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import { useClientLookup } from "virtual:use-client-lookup.js";
|
|
6
|
+
export const loadModule = memoizeOnId(async (id) => {
|
|
4
7
|
if (import.meta.env.VITE_IS_DEV_SERVER) {
|
|
5
8
|
return await import(/* @vite-ignore */ id);
|
|
6
9
|
}
|
|
7
10
|
else {
|
|
8
|
-
const { useClientLookup } = await import("virtual:use-client-lookup.js");
|
|
9
11
|
const moduleFn = useClientLookup[id];
|
|
10
12
|
if (!moduleFn) {
|
|
11
13
|
throw new Error(`(client) No module found for '${id}' in module lookup for "use client" directive`);
|
|
@@ -14,7 +16,7 @@ export const loadModule = memoize(async (id) => {
|
|
|
14
16
|
}
|
|
15
17
|
});
|
|
16
18
|
// context(justinvdm, 2 Dec 2024): re memoize(): React relies on the same promise instance being returned for the same id
|
|
17
|
-
export const clientWebpackRequire =
|
|
19
|
+
export const clientWebpackRequire = memoizeOnId(async (id) => {
|
|
18
20
|
const [file, name] = id.split("#");
|
|
19
21
|
const promisedModule = loadModule(file);
|
|
20
22
|
const promisedComponent = promisedModule.then((module) => module[name]);
|
|
@@ -23,7 +25,6 @@ export const clientWebpackRequire = memoize(async (id) => {
|
|
|
23
25
|
const awaitedComponent = await promisedComponent;
|
|
24
26
|
return { [id]: awaitedComponent };
|
|
25
27
|
}
|
|
26
|
-
const { ClientOnly } = await import("./ClientOnly");
|
|
27
28
|
const promisedDefault = promisedComponent.then((Component) => ({
|
|
28
29
|
default: Component,
|
|
29
30
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const ssrLoadModule: (
|
|
1
|
+
export declare const ssrLoadModule: (id: string) => Promise<any>;
|
|
2
2
|
export declare const ssrGetModuleExport: (id: string) => Promise<any>;
|
|
3
|
-
export declare const ssrWebpackRequire: (
|
|
3
|
+
export declare const ssrWebpackRequire: (id: string) => Promise<{
|
|
4
4
|
[x: string]: any;
|
|
5
|
-
}
|
|
5
|
+
}>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
export const ssrLoadModule =
|
|
1
|
+
import { memoizeOnId } from "../lib/memoizeOnId";
|
|
2
|
+
export const ssrLoadModule = memoizeOnId(async (id) => {
|
|
3
3
|
const { useClientLookup } = await import("virtual:use-client-lookup.js");
|
|
4
4
|
const moduleFn = useClientLookup[id];
|
|
5
5
|
if (!moduleFn) {
|
|
@@ -13,7 +13,7 @@ export const ssrGetModuleExport = async (id) => {
|
|
|
13
13
|
return module[name];
|
|
14
14
|
};
|
|
15
15
|
// context(justinvdm, 2 Dec 2024): re memoize(): React relies on the same promise instance being returned for the same id
|
|
16
|
-
export const ssrWebpackRequire =
|
|
16
|
+
export const ssrWebpackRequire = memoizeOnId(async (id) => {
|
|
17
17
|
const [file, name] = id.split("#");
|
|
18
18
|
const module = await ssrLoadModule(file);
|
|
19
19
|
return { [id]: module[name] };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const loadServerModule: (
|
|
1
|
+
export declare const loadServerModule: (id: string) => Promise<any>;
|
|
2
2
|
export declare const getServerModuleExport: (id: string) => Promise<any>;
|
|
3
|
-
export declare const ssrWebpackRequire: (
|
|
3
|
+
export declare const ssrWebpackRequire: (id: string) => Promise<{
|
|
4
4
|
[x: string]: any;
|
|
5
|
-
}
|
|
5
|
+
}>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import memoize from "lodash/memoize";
|
|
2
1
|
import { requestInfo } from "../requestInfo/worker";
|
|
3
2
|
import { ssrWebpackRequire as baseSsrWebpackRequire } from "rwsdk/__ssr_bridge";
|
|
4
|
-
|
|
3
|
+
import { memoizeOnId } from "../lib/memoizeOnId";
|
|
4
|
+
export const loadServerModule = memoizeOnId(async (id) => {
|
|
5
5
|
const { useServerLookup } = await import("virtual:use-server-lookup.js");
|
|
6
6
|
const moduleFn = useServerLookup[id];
|
|
7
7
|
if (!moduleFn) {
|
|
@@ -14,7 +14,7 @@ export const getServerModuleExport = async (id) => {
|
|
|
14
14
|
const module = await loadServerModule(file);
|
|
15
15
|
return module[name];
|
|
16
16
|
};
|
|
17
|
-
export const ssrWebpackRequire =
|
|
17
|
+
export const ssrWebpackRequire = memoizeOnId(async (id) => {
|
|
18
18
|
if (!requestInfo.rw.ssr) {
|
|
19
19
|
return { [id]: () => null };
|
|
20
20
|
}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
export type Manifest = Record<string, ManifestChunk>;
|
|
2
|
+
export interface ManifestChunk {
|
|
3
|
+
file: string;
|
|
4
|
+
src?: string;
|
|
5
|
+
isEntry?: boolean;
|
|
6
|
+
isDynamicEntry?: boolean;
|
|
7
|
+
imports?: string[];
|
|
8
|
+
css?: string[];
|
|
9
|
+
assets?: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare const getManifest: () => Promise<Manifest>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const memoizeOnId: <Result>(fn: (id: string) => Result) => (id: string) => Result;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const memoizeOnId = (fn) => {
|
|
2
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
3
|
+
const results = {};
|
|
4
|
+
const memoizedFn = (id) => {
|
|
5
|
+
if (hasOwnProperty.call(results, id)) {
|
|
6
|
+
return results[id];
|
|
7
|
+
}
|
|
8
|
+
return (results[id] = fn(id));
|
|
9
|
+
};
|
|
10
|
+
return memoizedFn;
|
|
11
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { initClient } from "../../client";
|
|
1
|
+
import { initClient } from "../../client/client";
|
|
2
2
|
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
|
3
3
|
import { MESSAGE_TYPE } from "./shared";
|
|
4
4
|
import { packMessage, unpackMessage, } from "./protocol";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const loadServerModule: (
|
|
1
|
+
export declare const loadServerModule: (id: string) => Promise<any>;
|
|
2
2
|
export declare const getServerModuleExport: (id: string) => Promise<any>;
|
|
3
3
|
export declare const createServerReference: (id: string, name: string) => any;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import memoize from "lodash/memoize";
|
|
2
1
|
import { createServerReference as baseCreateServerReference } from "react-server-dom-webpack/client.edge";
|
|
3
|
-
|
|
2
|
+
import { memoizeOnId } from "../lib/memoizeOnId";
|
|
3
|
+
export const loadServerModule = memoizeOnId(async (id) => {
|
|
4
4
|
const { useServerLookup } = await import("virtual:use-server-lookup.js");
|
|
5
5
|
const moduleFn = useServerLookup[id];
|
|
6
6
|
if (!moduleFn) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RequestInfo } from "../requestInfo/types.js";
|
|
2
|
+
import type { Manifest, ManifestChunk } from "../lib/manifest.js";
|
|
3
|
+
export declare function findScriptForModule(id: string, manifest: Manifest): ManifestChunk | undefined;
|
|
4
|
+
export declare const Preloads: ({ requestInfo }: {
|
|
5
|
+
requestInfo: RequestInfo;
|
|
6
|
+
}) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { use } from "react";
|
|
3
|
+
import { getManifest } from "../lib/manifest.js";
|
|
4
|
+
export function findScriptForModule(id, manifest) {
|
|
5
|
+
const visited = new Set();
|
|
6
|
+
function find(id) {
|
|
7
|
+
if (visited.has(id)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
visited.add(id);
|
|
11
|
+
const manifestEntry = manifest[id];
|
|
12
|
+
if (!manifestEntry) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (manifestEntry.isEntry || manifestEntry.isDynamicEntry) {
|
|
16
|
+
return manifestEntry;
|
|
17
|
+
}
|
|
18
|
+
if (manifestEntry.imports) {
|
|
19
|
+
for (const dep of manifestEntry.imports) {
|
|
20
|
+
const entry = find(dep);
|
|
21
|
+
if (entry) {
|
|
22
|
+
return entry;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
return find(id);
|
|
29
|
+
}
|
|
30
|
+
export const Preloads = ({ requestInfo }) => {
|
|
31
|
+
const manifest = use(getManifest());
|
|
32
|
+
const allScripts = new Set();
|
|
33
|
+
for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
|
|
34
|
+
const script = findScriptForModule(scriptId, manifest);
|
|
35
|
+
if (script) {
|
|
36
|
+
allScripts.add(script.file);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return (_jsx(_Fragment, { children: Array.from(allScripts).map((href) => (_jsx("link", { rel: "modulepreload", href: href }, href))) }));
|
|
40
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { use } from "react";
|
|
3
3
|
import { renderToReadableStream } from "react-dom/server.edge";
|
|
4
|
+
import { Preloads } from "./preloads.js";
|
|
4
5
|
import { Stylesheets } from "./stylesheets.js";
|
|
5
6
|
export const renderRscThenableToHtmlStream = async ({ thenable, Document, requestInfo, shouldSSR, onError, }) => {
|
|
6
7
|
const Component = () => {
|
|
7
8
|
const RscApp = () => {
|
|
8
9
|
const node = use(thenable).node;
|
|
9
|
-
return (_jsxs(_Fragment, { children: [_jsx(Stylesheets, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: node })] }));
|
|
10
|
+
return (_jsxs(_Fragment, { children: [_jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: node })] }));
|
|
10
11
|
};
|
|
11
12
|
// todo(justinvdm, 18 Jun 2025): We can build on this later to allow users
|
|
12
13
|
// surface context. e.g:
|
|
@@ -23,7 +23,7 @@ const findCssForModule = (scriptId, manifest) => {
|
|
|
23
23
|
return Array.from(css);
|
|
24
24
|
};
|
|
25
25
|
export const Stylesheets = ({ requestInfo }) => {
|
|
26
|
-
const manifest = use(getManifest(
|
|
26
|
+
const manifest = use(getManifest());
|
|
27
27
|
const allStylesheets = new Set();
|
|
28
28
|
for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
|
|
29
29
|
const css = findCssForModule(scriptId, manifest);
|
package/dist/runtime/worker.js
CHANGED
|
@@ -66,6 +66,9 @@ export const miniflareHMRPlugin = (givenOptions) => [
|
|
|
66
66
|
};
|
|
67
67
|
},
|
|
68
68
|
async hotUpdate(ctx) {
|
|
69
|
+
if (ctx.file.includes(".wrangler")) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
69
72
|
if (hasErrored) {
|
|
70
73
|
const shortName = getShortName(ctx.file, ctx.server.config.root);
|
|
71
74
|
this.environment.logger.info(`${colors.cyan(`attempting to recover from error`)}: update to ${colors.dim(shortName)}`, {
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|