main
js 108 lines 3.16 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
11 import type {
12 ImportMetadata,
13 ImportManifestEntry,
14 } from '../shared/ReactFlightImportMetadata';
15
16 import type {
17 ClientReference,
18 ServerReference,
19 } from '../ReactFlightWebpackReferences';
20
21 export type {ClientReference, ServerReference};
22
23 export type ClientManifest = {
24 [id: string]: ClientReferenceManifestEntry,
25 };
26
27 export type ServerReferenceId = string;
28
29 export type ClientReferenceMetadata = ImportMetadata;
30 export opaque type ClientReferenceManifestEntry = ImportManifestEntry;
31
32 export type ClientReferenceKey = string;
33
34 export {
35 isClientReference,
36 isServerReference,
37 } from '../ReactFlightWebpackReferences';
38
39 export function getClientReferenceKey(
40 reference: ClientReference<any>,
41 ): ClientReferenceKey {
42 return reference.$$async ? reference.$$id + '#async' : reference.$$id;
43 }
44
45 export function resolveClientReferenceMetadata<T>(
46 config: ClientManifest,
47 clientReference: ClientReference<T>,
48 ): ClientReferenceMetadata {
49 const modulePath = clientReference.$$id;
50 let name = '';
51 let resolvedModuleData = config[modulePath];
52 if (resolvedModuleData) {
53 // The potentially aliased name.
54 name = resolvedModuleData.name;
55 } else {
56 // We didn't find this specific export name but we might have the * export
57 // which contains this name as well.
58 // TODO: It's unfortunate that we now have to parse this string. We should
59 // probably go back to encoding path and name separately on the client reference.
60 const idx = modulePath.lastIndexOf('#');
61 if (idx !== -1) {
62 name = modulePath.slice(idx + 1);
63 resolvedModuleData = config[modulePath.slice(0, idx)];
64 }
65 if (!resolvedModuleData) {
66 throw new Error(
67 'Could not find the module "' +
68 modulePath +
69 '" in the React Client Manifest. ' +
70 'This is probably a bug in the React Server Components bundler.',
71 );
72 }
73 }
74 if (resolvedModuleData.async === true && clientReference.$$async === true) {
75 throw new Error(
76 'The module "' +
77 modulePath +
78 '" is marked as an async ESM module but was loaded as a CJS proxy. ' +
79 'This is probably a bug in the React Server Components bundler.',
80 );
81 }
82 if (resolvedModuleData.async === true || clientReference.$$async === true) {
83 return [resolvedModuleData.id, resolvedModuleData.chunks, name, 1];
84 } else {
85 return [resolvedModuleData.id, resolvedModuleData.chunks, name];
86 }
87 }
88
89 export function getServerReferenceId<T>(
90 config: ClientManifest,
91 serverReference: ServerReference<T>,
92 ): ServerReferenceId {
93 return serverReference.$$id;
94 }
95
96 export function getServerReferenceBoundArguments<T>(
97 config: ClientManifest,
98 serverReference: ServerReference<T>,
99 ): null | Array<ReactClientValue> {
100 return serverReference.$$bound;
101 }
102
103 export function getServerReferenceLocation<T>(
104 config: ClientManifest,
105 serverReference: ServerReference<T>,
106 ): void | Error {
107 return serverReference.$$location;
108 }