From b9f21dc2be14cd51543e6b2d1e63a861e5f433d1 Mon Sep 17 00:00:00 2001 From: Jean Lauliac Date: Mon, 6 Nov 2017 03:30:10 -0800 Subject: [PATCH] react-native: BundleSegments Reviewed By: davidaurelio Differential Revision: D6231309 fbshipit-source-id: 565cbadedc5fd8ab25025b5846c098f24fb15a82 --- Libraries/Utilities/BundleSegments.js | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Libraries/Utilities/BundleSegments.js diff --git a/Libraries/Utilities/BundleSegments.js b/Libraries/Utilities/BundleSegments.js new file mode 100644 index 00000000000000..b7a2cd9332ff12 --- /dev/null +++ b/Libraries/Utilities/BundleSegments.js @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + * @format + * @providesModule BundleSegments + */ + +'use strict'; + +let segmentLoaders = new Map(); + +/** + * Ensure that a bundle segment is ready for use, for example requiring some of + * its module. We cache load promises so as to avoid calling `fetchBundle` twice + * for the same bundle. We assume that once a segment is fetched/loaded, it is + * never gettting removed during this instance of the JavaScript VM. + */ +async function loadForModule(moduleID: number): Promise { + const {segmentId} = (require: $FlowFixMe).unpackModuleId(moduleID); + if (segmentId === 0) { + return; + } + let segmentLoader = segmentLoaders.get(segmentId); + if (segmentLoader != null) { + return await segmentLoader; + } + // FIXME: `fetchBundle` should be renamed `fetchSegment`. + const {fetchBundle} = global; + if (fetchBundle == null) { + throw new Error( + 'When bundle splitting is enabled, the `global.fetchBundle` function ' + + 'must be provided to be able to load particular bundle segments.', + ); + } + segmentLoader = new Promise((resolve, reject) => { + fetchBundle(segmentId, error => { + if (error != null) { + reject(error); + return; + } + resolve(); + }); + }); + segmentLoaders.set(segmentId, segmentLoader); + return await segmentLoader; +} + +module.exports = {loadForModule};