"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSortedModules = exports.Chunk = exports.graphToSerialAssetsAsync = void 0; /** * Copyright © 2023 650 Industries. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ const assert_1 = __importDefault(require("assert")); const sourceMapString_1 = __importDefault(require("metro/src/DeltaBundler/Serializers/sourceMapString")); const bundleToString_1 = __importDefault(require("metro/src/lib/bundleToString")); const path_1 = __importDefault(require("path")); const debugId_1 = require("./debugId"); const exportHermes_1 = require("./exportHermes"); const exportPath_1 = require("./exportPath"); const baseJSBundle_1 = require("./fork/baseJSBundle"); const getCssDeps_1 = require("./getCssDeps"); const getAssets_1 = __importDefault(require("../transform-worker/getAssets")); // Convert file paths to regex matchers. function pathToRegex(path) { // Escape regex special characters, except for '*' let regexSafePath = path.replace(/[-[\]{}()+?.,\\^$|#\s]/g, '\\$&'); // Replace '*' with '.*' to act as a wildcard in regex regexSafePath = regexSafePath.replace(/\*/g, '.*'); // Create a RegExp object with the modified string return new RegExp('^' + regexSafePath + '$'); } const sourceMapString = typeof sourceMapString_1.default !== 'function' ? sourceMapString_1.default.sourceMapString : sourceMapString_1.default; async function graphToSerialAssetsAsync(config, serializeChunkOptions, ...props) { const [entryFile, preModules, graph, options] = props; const cssDeps = (0, getCssDeps_1.getCssSerialAssets)(graph.dependencies, { projectRoot: options.projectRoot, processModuleFilter: options.processModuleFilter, }); // Create chunks for splitting. const chunks = new Set(); [ { test: pathToRegex(entryFile), }, ].map((chunkSettings) => gatherChunks(chunks, chunkSettings, preModules, graph, options, false)); // Get the common modules and extract them into a separate chunk. const entryChunk = [...chunks.values()].find((chunk) => !chunk.isAsync && chunk.hasAbsolutePath(entryFile)); if (entryChunk) { for (const chunk of chunks.values()) { if (chunk !== entryChunk && chunk.isAsync) { for (const dep of chunk.deps.values()) { if (entryChunk.deps.has(dep)) { // Remove the dependency from the async chunk since it will be loaded in the main chunk. chunk.deps.delete(dep); } } } } const toCompare = [...chunks.values()]; const commonDependencies = []; while (toCompare.length) { const chunk = toCompare.shift(); for (const chunk2 of toCompare) { if (chunk !== chunk2 && chunk.isAsync && chunk2.isAsync) { const commonDeps = [...chunk.deps].filter((dep) => chunk2.deps.has(dep)); for (const dep of commonDeps) { chunk.deps.delete(dep); chunk2.deps.delete(dep); } commonDependencies.push(...commonDeps); } } } // If common dependencies were found, extract them to the entry chunk. // TODO: Extract the metro-runtime to a common chunk apart from the entry chunk then load the common dependencies before the entry chunk. if (commonDependencies.length) { for (const dep of commonDependencies) { entryChunk.deps.add(dep); } // const commonDependenciesUnique = [...new Set(commonDependencies)]; // const commonChunk = new Chunk( // chunkIdForModules(commonDependenciesUnique), // commonDependenciesUnique, // graph, // options, // false, // true // ); // entryChunk.requiredChunks.add(commonChunk); // chunks.add(commonChunk); } // TODO: Optimize this pass more. // Remove all dependencies from async chunks that are already in the common chunk. for (const chunk of [...chunks.values()]) { if (chunk !== entryChunk) { for (const dep of chunk.deps) { if (entryChunk.deps.has(dep)) { chunk.deps.delete(dep); } } } } } const jsAssets = await serializeChunksAsync(chunks, config.serializer ?? {}, serializeChunkOptions); // TODO: Can this be anything besides true? const isExporting = true; const baseUrl = (0, baseJSBundle_1.getBaseUrlOption)(graph, { serializerOptions: serializeChunkOptions }); const assetPublicUrl = (baseUrl.replace(/\/+$/, '') ?? '') + '/assets'; const publicPath = isExporting ? graph.transformOptions.platform === 'web' ? `/assets?export_path=${assetPublicUrl}` : assetPublicUrl : '/assets/?unstable_path=.'; // TODO: Convert to serial assets // TODO: Disable this call dynamically in development since assets are fetched differently. const metroAssets = (await (0, getAssets_1.default)(graph.dependencies, { processModuleFilter: options.processModuleFilter, assetPlugins: config.transformer?.assetPlugins ?? [], platform: (0, baseJSBundle_1.getPlatformOption)(graph, options) ?? 'web', projectRoot: options.projectRoot, publicPath, })); return { artifacts: [...jsAssets, ...cssDeps], assets: metroAssets }; } exports.graphToSerialAssetsAsync = graphToSerialAssetsAsync; class Chunk { name; entries; graph; options; isAsync; isVendor; deps = new Set(); preModules = new Set(); // Chunks that are required to be loaded synchronously before this chunk. // These are included in the HTML as