Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions fixtures/flight-parcel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"scripts": {
"predev": "cp -r ../../build/oss-experimental/* ./node_modules/",
"prebuild": "cp -r ../../build/oss-experimental/* ./node_modules/",
"dev": "concurrently \"npm run dev:watch\" \"npm run dev:start\"",
"dev": "concurrently \"npm run dev:watch\" \"sleep 2 && npm run dev:start\"",
"dev:watch": "NODE_ENV=development parcel watch",
"dev:start": "NODE_ENV=development node dist/server.js",
"build": "parcel build",
Expand All @@ -28,16 +28,16 @@
"packageExports": true
},
"dependencies": {
"@parcel/config-default": "2.0.0-dev.1789",
"@parcel/runtime-rsc": "2.13.3-dev.3412",
"@parcel/config-default": "2.0.0-dev.1795",
"@parcel/runtime-rsc": "2.13.3-dev.3418",
"@types/parcel-env": "^0.0.6",
"@types/express": "*",
"@types/node": "^22.10.1",
"@types/react": "^19",
"@types/react-dom": "^19",
"concurrently": "^7.3.0",
"express": "^4.18.2",
"parcel": "2.0.0-dev.1787",
"parcel": "2.0.0-dev.1793",
"process": "^0.11.10",
"react": "experimental",
"react-dom": "experimental",
Expand Down
7 changes: 4 additions & 3 deletions fixtures/flight-parcel/src/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {injectRSCPayload} from 'rsc-html-stream/server';

// Client dependencies, used for SSR.
// These must run in the same environment as client components (e.g. same instance of React).
import {createFromReadableStream} from 'react-server-dom-parcel/client' with {env: 'react-client'};
import {renderToReadableStream as renderHTMLToReadableStream} from 'react-dom/server' with {env: 'react-client'};
import {createFromReadableStream} from 'react-server-dom-parcel/client.edge' with {env: 'react-client'};
import {renderToReadableStream as renderHTMLToReadableStream} from 'react-dom/server.edge' with {env: 'react-client'};
import ReactClient, {ReactElement} from 'react' with {env: 'react-client'};

// Page components. These must have "use server-entry" so they are treated as code splitting entry points.
Expand Down Expand Up @@ -66,8 +66,9 @@ async function render(

// Use client react to render the RSC payload to HTML.
let [s1, s2] = stream.tee();
let data = createFromReadableStream<ReactElement>(s1);
let data: Promise<ReactElement>;
function Content() {
data ??= createFromReadableStream<ReactElement>(s1);
return ReactClient.use(data);
}

Expand Down
10 changes: 9 additions & 1 deletion fixtures/flight-parcel/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

declare module 'react-server-dom-parcel/client' {
export function createFromFetch<T>(res: Promise<Response>): Promise<T>;
export function createFromReadableStream<T>(stream: ReadableStream): Promise<T>;
export function encodeReply(value: any): Promise<string | URLSearchParams | FormData>;

type CallServerCallback = <T>(id: string, args: any[]) => Promise<T>;
export function setServerCallback(cb: CallServerCallback): void;
}

declare module 'react-server-dom-parcel/client.edge' {
export function createFromReadableStream<T>(stream: ReadableStream): Promise<T>;
}

declare module 'react-server-dom-parcel/server.edge' {
export function renderToReadableStream(value: any): ReadableStream;
export function loadServerAction(id: string): Promise<(...args: any[]) => any>;
Expand All @@ -17,5 +20,10 @@ declare module 'react-server-dom-parcel/server.edge' {
}

declare module '@parcel/runtime-rsc' {
import {JSX} from 'react';
export function Resources(): JSX.Element;
}

declare module 'react-dom/server.edge' {
export * from 'react-dom/server';
}
847 changes: 424 additions & 423 deletions fixtures/flight-parcel/yarn.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const rendererPackageName = 'react-server-dom-parcel';
export * from 'react-client/src/ReactFlightClientStreamConfigWeb';
export * from 'react-client/src/ReactClientConsoleConfigBrowser';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigTargetParcelBrowser';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = false;
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const rendererPackageName = 'react-server-dom-parcel';
export * from 'react-client/src/ReactFlightClientStreamConfigWeb';
export * from 'react-client/src/ReactClientConsoleConfigServer';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigTargetParcelServer';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const rendererPackageName = 'react-server-dom-parcel';
export * from 'react-client/src/ReactFlightClientStreamConfigNode';
export * from 'react-client/src/ReactClientConsoleConfigServer';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel';
export * from 'react-server-dom-parcel/src/client/ReactFlightClientConfigTargetParcelServer';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {Thenable} from 'shared/ReactTypes';
import type {ImportMetadata} from '../shared/ReactFlightImportMetadata';

import {ID, NAME, BUNDLES} from '../shared/ReactFlightImportMetadata';
import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientConfig';

export type ServerManifest = {
[string]: Array<string>,
Expand All @@ -24,33 +25,22 @@ export type ServerReferenceId = string;
export opaque type ClientReferenceMetadata = ImportMetadata;

// eslint-disable-next-line no-unused-vars
export opaque type ClientReference<T> = {
// Module id.
id: string,
// Export name.
name: string,
// List of bundle URLs, relative to the distDir.
bundles: Array<string>,
};
export opaque type ClientReference<T> = ImportMetadata;

export function prepareDestinationForModule(
moduleLoading: ModuleLoading,
nonce: ?string,
metadata: ClientReferenceMetadata,
) {
return;
prepareDestinationWithChunks(moduleLoading, metadata[BUNDLES], nonce);
}

export function resolveClientReference<T>(
bundlerConfig: null,
metadata: ClientReferenceMetadata,
): ClientReference<T> {
// Reference is already resolved during the build.
return {
id: metadata[ID],
name: metadata[NAME],
bundles: metadata[BUNDLES],
};
return metadata;
}

export function resolveServerReference<T>(
Expand All @@ -64,20 +54,19 @@ export function resolveServerReference<T>(
if (!bundles) {
throw new Error('Invalid server action: ' + ref);
}
return {
id,
name,
bundles,
};
return [id, name, bundles];
}

export function preloadModule<T>(
metadata: ClientReference<T>,
): null | Thenable<any> {
return Promise.all(metadata.bundles.map(url => parcelRequire.load(url)));
if (metadata[BUNDLES].length === 0) {
return null;
}
return Promise.all(metadata[BUNDLES].map(url => parcelRequire.load(url)));
}

export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata.id);
return moduleExports[metadata.name];
const moduleExports = parcelRequire(metadata[ID]);
return moduleExports[metadata[NAME]];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {ModuleLoading} from './ReactFlightClientConfigBundlerParcel';

export function prepareDestinationWithChunks(
moduleLoading: ModuleLoading,
bundles: Array<string>,
nonce: ?string,
) {
// In the browser we don't need to prepare our destination since the browser is the Destination
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {ModuleLoading} from './ReactFlightClientConfigBundlerParcel';
import {preinitModuleForSSR} from 'react-client/src/ReactFlightClientConfig';

export function prepareDestinationWithChunks(
moduleLoading: ModuleLoading,
bundles: Array<string>,
nonce: ?string,
) {
for (let i = 0; i < bundles.length; i++) {
preinitModuleForSSR(parcelRequire.meta.publicUrl + bundles[i], nonce);
}
}
3 changes: 3 additions & 0 deletions scripts/flow/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ declare const __turbopack_require__: ((id: string) => any) & {
declare var parcelRequire: {
(id: string): any,
load: (url: string) => Promise<mixed>,
meta: {
publicUrl: string,
},
};

declare module 'fs/promises' {
Expand Down
Loading