main
js 197 lines 5.11 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
8 'use strict';
9
10 const url = require('url');
11
12 let turbopackModuleIdx = 0;
13 const turbopackServerModules = {};
14 const turbopackClientModules = {};
15 const turbopackErroredModules = {};
16 const turbopackServerMap = {};
17 const turbopackClientMap = {};
18 global.__turbopack_require__ = function (id) {
19 if (turbopackErroredModules[id]) {
20 throw turbopackErroredModules[id];
21 }
22 return turbopackClientModules[id] || turbopackServerModules[id];
23 };
24
25 const Server = require('react-server-dom-turbopack/server');
26 const registerClientReference = Server.registerClientReference;
27 const registerServerReference = Server.registerServerReference;
28 const createClientModuleProxy = Server.createClientModuleProxy;
29
30 exports.turbopackMap = turbopackClientMap;
31 exports.turbopackModules = turbopackClientModules;
32 exports.turbopackServerMap = turbopackServerMap;
33 exports.moduleLoading = {
34 prefix: '/prefix/',
35 };
36
37 exports.clientExports = function clientExports(moduleExports, chunkUrl) {
38 const chunks = [];
39 if (chunkUrl !== undefined) {
40 chunks.push(chunkUrl);
41 }
42 const idx = '' + turbopackModuleIdx++;
43 turbopackClientModules[idx] = moduleExports;
44 const path = url.pathToFileURL(idx).href;
45 turbopackClientMap[path] = {
46 id: idx,
47 chunks,
48 name: '*',
49 };
50 // We only add this if this test is testing ESM compat.
51 if ('__esModule' in moduleExports) {
52 turbopackClientMap[path + '#'] = {
53 id: idx,
54 chunks,
55 name: '',
56 };
57 }
58 if (typeof moduleExports.then === 'function') {
59 moduleExports.then(
60 asyncModuleExports => {
61 for (const name in asyncModuleExports) {
62 turbopackClientMap[path + '#' + name] = {
63 id: idx,
64 chunks,
65 name: name,
66 };
67 }
68 },
69 () => {},
70 );
71 }
72 if ('split' in moduleExports) {
73 // If we're testing module splitting, we encode this name in a separate module id.
74 const splitIdx = '' + turbopackModuleIdx++;
75 turbopackClientModules[splitIdx] = {
76 s: moduleExports.split,
77 };
78 turbopackClientMap[path + '#split'] = {
79 id: splitIdx,
80 chunks,
81 name: 's',
82 };
83 }
84 return createClientModuleProxy(path);
85 };
86
87 exports.clientExportsESM = function clientExportsESM(
88 moduleExports,
89 options?: {forceClientModuleProxy?: boolean} = {},
90 ) {
91 const chunks = [];
92 const idx = '' + turbopackModuleIdx++;
93 turbopackClientModules[idx] = moduleExports;
94 const path = url.pathToFileURL(idx).href;
95
96 const createClientReferencesForExports = ({exports, async}) => {
97 turbopackClientMap[path] = {
98 id: idx,
99 chunks,
100 name: '*',
101 async: true,
102 };
103
104 if (options.forceClientModuleProxy) {
105 return createClientModuleProxy(path);
106 }
107
108 if (typeof exports === 'object') {
109 const references = {};
110
111 for (const name in exports) {
112 const id = path + '#' + name;
113 turbopackClientMap[path + '#' + name] = {
114 id: idx,
115 chunks,
116 name: name,
117 async,
118 };
119 references[name] = registerClientReference(() => {}, id, name);
120 }
121
122 return references;
123 }
124
125 return registerClientReference(() => {}, path, '*');
126 };
127
128 if (
129 moduleExports &&
130 typeof moduleExports === 'object' &&
131 typeof moduleExports.then === 'function'
132 ) {
133 return moduleExports.then(
134 asyncModuleExports =>
135 createClientReferencesForExports({
136 exports: asyncModuleExports,
137 async: true,
138 }),
139 () => {},
140 );
141 }
142
143 return createClientReferencesForExports({exports: moduleExports});
144 };
145
146 // This tests server to server references. There's another case of client to server references.
147 exports.serverExports = function serverExports(moduleExports) {
148 const idx = '' + turbopackModuleIdx++;
149 turbopackServerModules[idx] = moduleExports;
150 const path = url.pathToFileURL(idx).href;
151 turbopackServerMap[path] = {
152 id: idx,
153 chunks: [],
154 name: '*',
155 };
156 // We only add this if this test is testing ESM compat.
157 if ('__esModule' in moduleExports) {
158 turbopackServerMap[path + '#'] = {
159 id: idx,
160 chunks: [],
161 name: '',
162 };
163 }
164 if ('split' in moduleExports) {
165 // If we're testing module splitting, we encode this name in a separate module id.
166 const splitIdx = '' + turbopackModuleIdx++;
167 turbopackServerModules[splitIdx] = {
168 s: moduleExports.split,
169 };
170 turbopackServerMap[path + '#split'] = {
171 id: splitIdx,
172 chunks: [],
173 name: 's',
174 };
175 }
176
177 if (typeof exports === 'function') {
178 // The module exports a function directly,
179 registerServerReference(
180 (exports: any),
181 idx,
182 // Represents the whole Module object instead of a particular import.
183 null,
184 );
185 } else {
186 const keys = Object.keys(exports);
187 for (let i = 0; i < keys.length; i++) {
188 const key = keys[i];
189 const value = exports[keys[i]];
190 if (typeof value === 'function') {
191 registerServerReference((value: any), idx, key);
192 }
193 }
194 }
195
196 return moduleExports;
197 };