UNPKG

react-native-flip

Version:
257 lines (216 loc) 7.44 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * * @format */ "use strict"; function _toConsumableArray(arr) { return ( _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread() ); } function _nonIterableSpread() { throw new TypeError( "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." ); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } const MAGIC_UNBUNDLE_FILE_HEADER = require("./magic-number"); const buildSourcemapWithMetadata = require("./buildSourcemapWithMetadata"); const fs = require("fs"); const relativizeSourceMapInline = require("../../../lib/relativizeSourceMap"); const writeSourceMap = require("./write-sourcemap"); const _require = require("./util"), joinModules = _require.joinModules; const SIZEOF_UINT32 = 4; /** * Saves all JS modules of an app as a single file, separated with null bytes. * The file begins with an offset table that contains module ids and their * lengths/offsets. * The module id for the startup code (prelude, polyfills etc.) is the * empty string. */ function saveAsIndexedFile(bundle, options, log) { const bundleOutput = options.bundleOutput, encoding = options.bundleEncoding, sourcemapOutput = options.sourcemapOutput, sourcemapSourcesRoot = options.sourcemapSourcesRoot; log("start"); const startupModules = bundle.startupModules, lazyModules = bundle.lazyModules, groups = bundle.groups; log("finish"); const moduleGroups = createModuleGroups(groups, lazyModules); const startupCode = joinModules(startupModules); log("Writing unbundle output to:", bundleOutput); const writeUnbundle = writeBuffers( fs.createWriteStream(bundleOutput), buildTableAndContents(startupCode, lazyModules, moduleGroups, encoding) ).then(() => log("Done writing unbundle output")); if (sourcemapOutput) { const sourceMap = buildSourcemapWithMetadata({ startupModules: startupModules.concat(), lazyModules: lazyModules.concat(), moduleGroups, fixWrapperOffset: true }); if (sourcemapSourcesRoot !== undefined) { relativizeSourceMapInline(sourceMap, sourcemapSourcesRoot); } const wroteSourceMap = writeSourceMap( sourcemapOutput, JSON.stringify(sourceMap), log ); return Promise.all([writeUnbundle, wroteSourceMap]); } else { return writeUnbundle; } } /* global Buffer: true */ const fileHeader = Buffer.alloc(4); fileHeader.writeUInt32LE(MAGIC_UNBUNDLE_FILE_HEADER, 0); const nullByteBuffer = Buffer.alloc(1).fill(0); function writeBuffers(stream, buffers) { buffers.forEach(buffer => stream.write(buffer)); return new Promise((resolve, reject) => { stream.on("error", reject); stream.on("finish", () => resolve()); stream.end(); }); } function nullTerminatedBuffer(contents, encoding) { return Buffer.concat([Buffer.from(contents, encoding), nullByteBuffer]); } function moduleToBuffer(id, code, encoding) { return { id, buffer: nullTerminatedBuffer(code, encoding) }; } function entryOffset(n) { // 2: num_entries + startup_code_len // n * 2: each entry consists of two uint32s return (2 + n * 2) * SIZEOF_UINT32; } function buildModuleTable(startupCode, moduleBuffers, moduleGroups) { // table format: // - num_entries: uint_32 number of entries // - startup_code_len: uint_32 length of the startup section // - entries: entry... // // entry: // - module_offset: uint_32 offset into the modules blob // - module_length: uint_32 length of the module code in bytes const moduleIds = _toConsumableArray(moduleGroups.modulesById.keys()); const maxId = moduleIds.reduce((max, id) => Math.max(max, id)); const numEntries = maxId + 1; const table = Buffer.alloc(entryOffset(numEntries)).fill(0); // num_entries table.writeUInt32LE(numEntries, 0); // startup_code_len table.writeUInt32LE(startupCode.length, SIZEOF_UINT32); // entries let codeOffset = startupCode.length; moduleBuffers.forEach(_ref => { let id = _ref.id, buffer = _ref.buffer; const group = moduleGroups.groups.get(id); const idsInGroup = group ? [id].concat(Array.from(group)) : [id]; idsInGroup.forEach(moduleId => { const offset = entryOffset(moduleId); // module_offset table.writeUInt32LE(codeOffset, offset); // module_length table.writeUInt32LE(buffer.length, offset + SIZEOF_UINT32); }); codeOffset += buffer.length; }); return table; } function groupCode(rootCode, moduleGroup, modulesById) { if (!moduleGroup || !moduleGroup.size) { return rootCode; } const code = [rootCode]; for (const id of moduleGroup) { code.push( ( modulesById.get(id) || { code: "" } ).code ); } return code.join("\n"); } function buildModuleBuffers(modules, moduleGroups, encoding) { return modules .filter(m => !moduleGroups.modulesInGroups.has(m.id)) .map(_ref2 => { let id = _ref2.id, code = _ref2.code; return moduleToBuffer( id, groupCode(code, moduleGroups.groups.get(id), moduleGroups.modulesById), encoding ); }); } function buildTableAndContents(startupCode, modules, moduleGroups, encoding) { // file contents layout: // - magic number char[4] 0xE5 0xD1 0x0B 0xFB (0xFB0BD1E5 uint32 LE) // - offset table table see `buildModuleTables` // - code blob char[] null-terminated code strings, starting with // the startup code const startupCodeBuffer = nullTerminatedBuffer(startupCode, encoding); const moduleBuffers = buildModuleBuffers(modules, moduleGroups, encoding); const table = buildModuleTable( startupCodeBuffer, moduleBuffers, moduleGroups ); return [fileHeader, table, startupCodeBuffer].concat( moduleBuffers.map(_ref3 => { let buffer = _ref3.buffer; return buffer; }) ); } function createModuleGroups(groups, modules) { return { groups, modulesById: new Map(modules.map(m => [m.id, m])), modulesInGroups: new Set(concat(groups.values())) }; } function* concat(iterators) { for (const it of iterators) { yield* it; } } exports.save = saveAsIndexedFile; exports.buildTableAndContents = buildTableAndContents; exports.createModuleGroups = createModuleGroups;