UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

283 lines (235 loc) 7.17 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 _slicedToArray(arr, i) { return ( _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest() ); } function _nonIterableRest() { throw new TypeError( "Invalid attempt to destructure 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 _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; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for ( var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true ) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const babelTypes = require("@babel/types"); const babylon = require("@babel/parser"); const nullthrows = require("nullthrows"); const template = require("@babel/template").default; const assetPropertyBlockList = new Set(["files", "fileSystemLocation", "path"]); function generateAssetCodeFileAst(assetRegistryPath, assetDescriptor) { const properDescriptor = filterObject( assetDescriptor, assetPropertyBlockList ); // {...} const descriptorAst = babylon.parseExpression( JSON.stringify(properDescriptor) ); const t = babelTypes; // require('AssetRegistry').registerAsset({...}) const buildRequire = template.statement(` module.exports = require(ASSET_REGISTRY_PATH).registerAsset(DESCRIPTOR_AST) `); return t.file( t.program([ buildRequire({ ASSET_REGISTRY_PATH: t.stringLiteral(assetRegistryPath), DESCRIPTOR_AST: descriptorAst }) ]) ); } /** * Generates the code involved in requiring an asset, but to be loaded remotely. * If the asset cannot be found within the map, then it falls back to the * standard asset. */ function generateRemoteAssetCodeFileAst( assetSourceResolverPath, assetDescriptor, remoteServer, remoteFileMap ) { const t = babelTypes; const file = remoteFileMap[assetDescriptor.fileSystemLocation]; const descriptor = file && file[assetDescriptor.name]; const data = {}; if (!descriptor) { return null; } for (const scale in descriptor) { data[+scale] = descriptor[+scale].handle; } // {2: 'path/to/image@2x', 3: 'path/to/image@3x', ...} const astData = babylon.parseExpression(JSON.stringify(data)); // URI to remote server const URI = t.stringLiteral(remoteServer); // Size numbers. const WIDTH = t.numericLiteral(nullthrows(assetDescriptor.width)); const HEIGHT = t.numericLiteral(nullthrows(assetDescriptor.height)); const buildRequire = template.statement(` module.exports = { "width": WIDTH, "height": HEIGHT, "uri": URI + OBJECT_AST[require(ASSET_SOURCE_RESOLVER_PATH).pickScale(SCALE_ARRAY)] }; `); return t.file( t.program([ buildRequire({ WIDTH, HEIGHT, URI, OBJECT_AST: astData, ASSET_SOURCE_RESOLVER_PATH: t.stringLiteral(assetSourceResolverPath), SCALE_ARRAY: t.arrayExpression( Object.keys(descriptor) .map(Number) .sort((a, b) => a - b) .map(scale => t.numericLiteral(scale)) ) }) ]) ); } // Test extension against all types supported by image-size module. // If it's not one of these, we won't treat it as an image. function isAssetTypeAnImage(type) { return ( ["png", "jpg", "jpeg", "bmp", "gif", "webp", "psd", "svg", "tiff"].indexOf( type ) !== -1 ); } function filterObject(object, blockList) { const copied = Object.assign({}, object); for (const key of blockList) { delete copied[key]; } return copied; } function createRamBundleGroups(ramGroups, groupableModules, subtree) { // build two maps that allow to lookup module data // by path or (numeric) module id; const byPath = new Map(); const byId = new Map(); groupableModules.forEach(m => { byPath.set(m.sourcePath, m); byId.set(m.id, m.sourcePath); }); // build a map of group root IDs to an array of module IDs in the group const result = new Map( ramGroups.map(modulePath => { const root = byPath.get(modulePath); if (root == null) { throw Error(`Group root ${modulePath} is not part of the bundle`); } return [ root.id, // `subtree` yields the IDs of all transitive dependencies of a module new Set(subtree(root, byPath)) ]; }) ); if (ramGroups.length > 1) { // build a map of all grouped module IDs to an array of group root IDs const all = new ArrayMap(); for (const _ref of result) { var _ref2 = _slicedToArray(_ref, 2); const parent = _ref2[0]; const children = _ref2[1]; for (const module of children) { all.get(module).push(parent); } } // find all module IDs that are part of more than one group const doubles = filter(all, _ref3 => { let _ref4 = _slicedToArray(_ref3, 2), parents = _ref4[1]; return parents.length > 1; }); for (const _ref5 of doubles) { var _ref6 = _slicedToArray(_ref5, 2); const moduleId = _ref6[0]; const parents = _ref6[1]; const parentNames = parents.map(byId.get, byId); const lastName = parentNames.pop(); throw new Error( `Module ${byId.get(moduleId) || moduleId} belongs to groups ${parentNames.join(", ")}, and ${String( lastName )}. Ensure that each module is only part of one group.` ); } } return result; } function* filter(iterator, predicate) { for (const value of iterator) { if (predicate(value)) { yield value; } } } class ArrayMap extends Map { get(key) { let array = super.get(key); if (!array) { array = []; this.set(key, array); } return array; } } module.exports = { createRamBundleGroups, generateAssetCodeFileAst, generateRemoteAssetCodeFileAst, isAssetTypeAnImage };