expo-router
Version:
Expo Router is a file-based router for React Native and web applications.
104 lines • 4.45 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderRscAsync = exports.renderRscWithImportsAsync = void 0;
const _async_server_import_1 = require("expo-router/_async-server-import");
const node_path_1 = __importDefault(require("node:path"));
const rsc_renderer_1 = require("./rsc-renderer");
const debug = require('debug')('expo:server:rsc-renderer');
// Tracking the implementation in expo/cli's MetroBundlerDevServer
const rscRenderContext = new Map();
function getRscRenderContext(platform) {
// NOTE(EvanBacon): We memoize this now that there's a persistent server storage cache for Server Actions.
if (rscRenderContext.has(platform)) {
return rscRenderContext.get(platform);
}
const context = {};
rscRenderContext.set(platform, context);
return context;
}
function interopDefault(mod) {
if ('default' in mod && typeof mod.default === 'object' && mod.default) {
const def = mod.default;
if ('default' in def && typeof def.default === 'object' && def.default) {
return def.default;
}
return mod.default;
}
return mod;
}
async function getServerActionManifest(distFolder, platform) {
const filePath = `../../rsc/${platform}/action-manifest.js`;
return interopDefault(await (0, _async_server_import_1.asyncServerImport)(filePath));
}
async function getSSRManifest(distFolder, platform) {
const filePath = `../../rsc/${platform}/ssr-manifest.js`;
return interopDefault(await (0, _async_server_import_1.asyncServerImport)(filePath));
}
async function renderRscWithImportsAsync(distFolder, imports, { body, platform, searchParams, config, method, input, contentType, headers }) {
if (method === 'POST' && !body) {
throw new Error('Server request must be provided when method is POST (server actions)');
}
const context = getRscRenderContext(platform);
context['__expo_requestHeaders'] = headers;
const entries = await imports.router();
const ssrManifest = await getSSRManifest(distFolder, platform);
const actionManifest = await getServerActionManifest(distFolder, platform);
return (0, rsc_renderer_1.renderRsc)({
body: body ?? undefined,
context,
config,
input,
contentType,
decodedBody: searchParams.get('x-expo-params'),
}, {
isExporting: true,
resolveClientEntry(file, isServer) {
debug('resolveClientEntry', file, { isServer });
if (isServer) {
if (!(file in actionManifest)) {
throw new Error(`Could not find file in server action manifest: ${file}. ${JSON.stringify(actionManifest)}`);
}
const [id, chunk] = actionManifest[file];
return {
id,
chunks: chunk ? [chunk] : [],
};
}
if (!(file in ssrManifest)) {
throw new Error(`Could not find file in SSR manifest: ${file}`);
}
const [id, chunk] = ssrManifest[file];
return {
id,
chunks: chunk ? [chunk] : [],
};
},
async loadServerModuleRsc(file) {
debug('loadServerModuleRsc', file);
const filePath = node_path_1.default.join('../../../', file);
const m = await (0, _async_server_import_1.asyncServerImport)(filePath);
// TODO: This is a hack to workaround a cloudflare/metro issue where there's an extra `default` wrapper.
if (typeof caches !== 'undefined') {
return m.default;
}
return m;
},
entries: entries,
});
}
exports.renderRscWithImportsAsync = renderRscWithImportsAsync;
async function renderRscAsync(distFolder, args) {
const platform = args.platform;
return renderRscWithImportsAsync(distFolder, {
router: () => {
// Assumes this file is saved to: `dist/server/_expo/functions/_flight/[...rsc].js`
const filePath = `../../rsc/${platform}/router.js`;
return (0, _async_server_import_1.asyncServerImport)(filePath);
},
}, args);
}
exports.renderRscAsync = renderRscAsync;
//# sourceMappingURL=middleware.js.map
;