Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 59 additions & 7 deletions packages/react-native/React/Base/RCTBundleManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,71 @@

@class RCTBridge;

typedef NSURL * (^RCTBridgelessBundleURLGetter)(void);
typedef void (^RCTBridgelessBundleURLSetter)(NSURL *bundleURL);
typedef NSURL *_Nullable (^RCTBridgelessBundleURLGetter)(void);
typedef void (^RCTBridgelessBundleURLSetter)(NSURL *_Nullable bundleURL);
typedef NSMutableArray<NSURLQueryItem *> *_Nullable (^RCTPackagerOptionsUpdater)(
NSMutableArray<NSURLQueryItem *> *_Nullable options);

/**
* Configuration class for setting up custom bundle locations
*/
@interface RCTBundleConfiguration : NSObject

+ (nonnull instancetype)defaultConfiguration;

/**
* The URL of the bundle to load from the file system
*/
@property (nonatomic, readonly, nullable) NSURL *bundleFilePath;

/**
* The server scheme (e.g. http or https) to use when loading from the packager
*/
@property (nonatomic, readonly, nullable) NSString *packagerServerScheme;

/**
* The server host (e.g. localhost) to use when loading from the packager
*/
@property (nonatomic, readonly, nullable) NSString *packagerServerHost;

/**
* A block that modifies the packager options when loading from the packager
*/
@property (nonatomic, copy, nullable) RCTPackagerOptionsUpdater packagerOptionsUpdater;

/**
* The relative path to the bundle.
*/
@property (nonatomic, readonly, nullable) NSString *bundlePath;

- (nonnull instancetype)initWithBundleFilePath:(nullable NSURL *)bundleFilePath;

- (nonnull instancetype)initWithPackagerServerScheme:(nullable NSString *)packagerServerScheme
packagerServerHost:(nullable NSString *)packagerServerHost
bundlePath:(nullable NSString *)bundlePath;

- (nullable NSURL *)getBundleURL:(NSURL *_Nullable (^_Nullable)(void))fallbackURLProvider;

- (nullable NSString *)getPackagerServerScheme;

- (nullable NSString *)getPackagerServerHost;

@end

/**
* A class that allows NativeModules/TurboModules to read/write the bundleURL, with or without the bridge.
*/
@interface RCTBundleManager : NSObject

- (nullable instancetype)initWithBundleConfig:(nullable RCTBundleConfiguration *)bundleConfig;

#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge;
- (void)setBridge:(nullable RCTBridge *)bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter
andSetter:(RCTBridgelessBundleURLSetter)setter
andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter;
- (void)setBridgelessBundleURLGetter:(nullable RCTBridgelessBundleURLGetter)getter
andSetter:(nullable RCTBridgelessBundleURLSetter)setter
andDefaultGetter:(nullable RCTBridgelessBundleURLGetter)defaultGetter;
- (void)resetBundleURL;
@property NSURL *bundleURL;
@property (nonatomic, nullable) NSURL *bundleURL;
@property (nonatomic, nonnull) RCTBundleConfiguration *bundleConfig;
@end
98 changes: 98 additions & 0 deletions packages/react-native/React/Base/RCTBundleManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,93 @@
*/

#import "RCTBundleManager.h"
#import <React/RCTBundleURLProvider.h>
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTLog.h"

@implementation RCTBundleConfiguration

+ (instancetype)defaultConfiguration
{
return [[self alloc] initWithBundleFilePath:nil packagerServerScheme:nil packagerServerHost:nil bundlePath:nil];
}

- (instancetype)initWithBundleFilePath:(NSURL *)bundleFilePath
{
return [self initWithBundleFilePath:bundleFilePath packagerServerScheme:nil packagerServerHost:nil bundlePath:nil];
}

- (instancetype)initWithPackagerServerScheme:(NSString *)packagerServerScheme
packagerServerHost:(NSString *)packagerServerHost
bundlePath:(NSString *)bundlePath
{
return [self initWithBundleFilePath:nil
packagerServerScheme:packagerServerScheme
packagerServerHost:packagerServerHost
bundlePath:bundlePath];
}

- (instancetype)initWithBundleFilePath:(NSURL *)bundleFilePath
packagerServerScheme:(NSString *)packagerServerScheme
packagerServerHost:(NSString *)packagerServerHost
bundlePath:(NSString *)bundlePath
{
if (self = [super init]) {
_bundleFilePath = bundleFilePath;
_packagerServerScheme = packagerServerScheme;
_packagerServerHost = packagerServerHost;
_bundlePath = bundlePath;
_packagerOptionsUpdater = ^NSMutableArray<NSURLQueryItem *> *(NSMutableArray<NSURLQueryItem *> *options)
{
return options;
};
}

return self;
}

- (NSString *)getPackagerServerScheme
{
if (!_packagerServerScheme) {
return [[RCTBundleURLProvider sharedSettings] packagerScheme];
}

return _packagerServerScheme;
}

- (NSString *)getPackagerServerHost
{
if (!_packagerServerHost) {
return [[RCTBundleURLProvider sharedSettings] packagerServerHostPort];
}

return _packagerServerHost;
}

- (NSURL *)getBundleURL:(NSURL * (^)(void))fallbackURLProvider
{
if (_packagerServerScheme && _packagerServerHost) {
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:_bundlePath
packagerServerScheme:_packagerServerScheme
packagerServerHost:_packagerServerHost
packagerOptionsUpdater:_packagerOptionsUpdater];
}

if (_bundleFilePath) {
if (!_bundleFilePath.fileURL) {
RCTLogError(@"Bundle file path must be a file URL");
return nil;
}

return _bundleFilePath;
}

return fallbackURLProvider();
}

@end

@implementation RCTBundleManager {
#ifndef RCT_REMOVE_LEGACY_ARCH
Expand All @@ -19,6 +103,20 @@ @implementation RCTBundleManager {
RCTBridgelessBundleURLGetter _bridgelessBundleURLDefaultGetter;
}

- (instancetype)initWithBundleConfig:(RCTBundleConfiguration *)bundleConfig
{
if (self = [super init]) {
self.bundleConfig = bundleConfig ? bundleConfig : [RCTBundleConfiguration defaultConfiguration];
}

return self;
}

- (instancetype)init
{
return [self initWithBundleConfig:[RCTBundleConfiguration defaultConfiguration]];
}

#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge
{
Expand Down
24 changes: 24 additions & 0 deletions packages/react-native/React/Base/RCTBundleURLProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#import <Foundation/Foundation.h>

#import "RCTBundleManager.h"
#import "RCTDefines.h"

RCT_EXTERN NSString *_Nonnull const RCTBundleURLProviderUpdatedNotification;
Expand Down Expand Up @@ -88,6 +89,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (NSURL *__nullable)jsBundleURLForFallbackExtension:(NSString *__nullable)extension;

/**
* Returns the jsBundleURL for a given bundle entrypoint,
* the packager scheme, server host and options updater
* for modifying default packager options.
*/
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerServerScheme:(NSString *)packagerServerScheme
packagerServerHost:(NSString *)packagerServerHost
packagerOptionsUpdater:(RCTPackagerOptionsUpdater)packagerOptionsUpdater;

/**
* Returns the resourceURL for a given bundle entrypoint and
* the fallback offline resource file if the packager is not running.
Expand All @@ -97,6 +108,19 @@ NS_ASSUME_NONNULL_BEGIN
resourceExtension:(NSString *)extension
offlineBundle:(NSBundle *)offlineBundle;

/**
* Returns the query items for given options used to create the jsBundleURL.
*/
+ (NSArray<NSURLQueryItem *> *)createJSBundleURLQuery:(NSString *)packagerHost
packagerScheme:(NSString *__nullable)scheme
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
modulesOnly:(BOOL)modulesOnly
runModule:(BOOL)runModule
additionalOptions:
(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions;

/**
* The IP address or hostname of the packager.
*/
Expand Down
53 changes: 49 additions & 4 deletions packages/react-native/React/Base/RCTBundleURLProvider.mm
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,54 @@ + (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
additionalOptions:(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions
{
NSString *path = [NSString stringWithFormat:@"/%@.bundle", bundleRoot];
NSArray<NSURLQueryItem *> *queryItems = [self createJSBundleURLQuery:packagerHost
packagerScheme:scheme
enableDev:enableDev
enableMinification:enableMinification
inlineSourceMap:inlineSourceMap
modulesOnly:modulesOnly
runModule:runModule
additionalOptions:additionalOptions];

return [RCTBundleURLProvider resourceURLForResourcePath:path
packagerHost:packagerHost
scheme:scheme
queryItems:[queryItems copy]];
}

- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerServerScheme:(NSString *)packagerServerScheme
packagerServerHost:(NSString *)packagerServerHost
packagerOptionsUpdater:(RCTPackagerOptionsUpdater)packagerOptionsUpdater
{
NSArray<NSURLQueryItem *> *queryItems = [RCTBundleURLProvider createJSBundleURLQuery:packagerServerHost
packagerScheme:packagerServerScheme
enableDev:[self enableDev]
enableMinification:[self enableMinification]
inlineSourceMap:[self inlineSourceMap]
modulesOnly:NO
runModule:YES
additionalOptions:nil];

NSArray<NSURLQueryItem *> *updatedQueryItems = packagerOptionsUpdater((NSMutableArray *)queryItems);
NSString *path = [NSString stringWithFormat:@"/%@.bundle", bundleRoot];

return [RCTBundleURLProvider resourceURLForResourcePath:path
packagerHost:packagerServerHost
scheme:packagerServerScheme
queryItems:updatedQueryItems];
}

+ (NSArray<NSURLQueryItem *> *)createJSBundleURLQuery:(NSString *)packagerHost
packagerScheme:(NSString *__nullable)scheme
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
modulesOnly:(BOOL)modulesOnly
runModule:(BOOL)runModule
additionalOptions:
(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions
{
BOOL lazy = enableDev;
NSMutableArray<NSURLQueryItem *> *queryItems = [[NSMutableArray alloc] initWithArray:@[
[[NSURLQueryItem alloc] initWithName:@"platform" value:RCTPlatformName],
Expand Down Expand Up @@ -345,10 +393,7 @@ + (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
}
}

return [[self class] resourceURLForResourcePath:path
packagerHost:packagerHost
scheme:scheme
queryItems:[queryItems copy]];
return queryItems;
}

+ (NSURL *)resourceURLForResourcePath:(NSString *)path
Expand Down
Loading