first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

181
node_modules/react-native/React/Base/RCTAssert.h generated vendored Normal file
View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
/*
* Defined in RCTUtils.m
*/
RCT_EXTERN BOOL RCTIsMainQueue(void);
/**
* This is the main assert macro that you should use. Asserts should be compiled out
* in production builds. You can customize the assert behaviour by setting a custom
* assert handler through `RCTSetAssertFunction`.
*/
#ifndef NS_BLOCK_ASSERTIONS
#define RCTAssert(condition, ...) \
do { \
if ((condition) == 0) { \
_RCTAssertFormat(#condition, __FILE__, __LINE__, __func__, __VA_ARGS__); \
if (RCT_NSASSERT) { \
[[NSAssertionHandler currentHandler] handleFailureInFunction:(NSString *_Nonnull)@(__func__) \
file:(NSString *_Nonnull)@(__FILE__) \
lineNumber:__LINE__ \
description:__VA_ARGS__]; \
} \
} \
} while (false)
#else
#define RCTAssert(condition, ...) \
do { \
} while (false)
#endif
RCT_EXTERN void _RCTAssertFormat(
const char * /*condition*/,
const char * /*fileName*/,
int /*lineNumber*/,
const char * /*function*/,
NSString * /*format*/,
...) NS_FORMAT_FUNCTION(5, 6);
/**
* Report a fatal condition when executing. These calls will _NOT_ be compiled out
* in production, and crash the app by default. You can customize the fatal behaviour
* by setting a custom fatal handler through `RCTSetFatalHandler` and
* `RCTSetFatalExceptionHandler`.
*/
RCT_EXTERN void RCTFatal(NSError *error);
RCT_EXTERN void RCTFatalException(NSException *exception);
/**
* The default error domain to be used for React errors.
*/
RCT_EXTERN NSString *const RCTErrorDomain;
/**
* JS Stack trace provided as part of an NSError's userInfo
*/
RCT_EXTERN NSString *const RCTJSStackTraceKey;
/**
* Raw JS Stack trace string provided as part of an NSError's userInfo
*/
RCT_EXTERN NSString *const RCTJSRawStackTraceKey;
/**
* Objective-C stack trace string provided as part of an NSError's userInfo
*/
RCT_EXTERN NSString *const RCTObjCStackTraceKey;
/**
* Name of fatal exceptions generated by RCTFatal
*/
RCT_EXTERN NSString *const RCTFatalExceptionName;
/**
* Stringified JSON object containing extra data to attach to the error from JavaScript.
*/
RCT_EXTERN NSString *const RCTJSExtraDataKey;
/**
* A block signature to be used for custom assertion handling.
*/
typedef void (^RCTAssertFunction)(
NSString *condition,
NSString *fileName,
NSNumber *lineNumber,
NSString *function,
NSString *message);
typedef void (^RCTFatalHandler)(NSError *error);
typedef void (^RCTFatalExceptionHandler)(NSException *exception);
/**
* Convenience macro for asserting that a parameter is non-nil/non-zero.
*/
#define RCTAssertParam(name) RCTAssert(name, @"'%s' is a required parameter", #name)
/**
* Convenience macro for asserting that we're running on main queue.
*/
#define RCTAssertMainQueue() RCTAssert(RCTIsMainQueue(), @"This function must be called on the main queue")
/**
* Convenience macro for asserting that we're running off the main queue.
*/
#define RCTAssertNotMainQueue() RCTAssert(!RCTIsMainQueue(), @"This function must not be called on the main queue")
/**
* These methods get and set the current assert function called by the RCTAssert
* macros. You can use these to replace the standard behavior with custom assert
* functionality.
*/
RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction);
RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);
/**
* This appends additional code to the existing assert function, without
* replacing the existing functionality. Useful if you just want to forward
* assert info to an extra service without changing the default behavior.
*/
RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
/**
* This method temporarily overrides the assert function while performing the
* specified block. This is useful for testing purposes (to detect if a given
* function asserts something) or to suppress or override assertions temporarily.
*/
RCT_EXTERN void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction);
/**
* These methods get and set the current fatal handler called by the `RCTFatal`
* and `RCTFatalException` methods.
*/
RCT_EXTERN void RCTSetFatalHandler(RCTFatalHandler fatalHandler);
RCT_EXTERN RCTFatalHandler RCTGetFatalHandler(void);
RCT_EXTERN void RCTSetFatalExceptionHandler(RCTFatalExceptionHandler fatalExceptionHandler);
RCT_EXTERN RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void);
/**
* Get the current thread's name (or the current queue, if in debug mode)
*/
RCT_EXTERN NSString *RCTCurrentThreadName(void);
/**
* Helper to get generate exception message from NSError
*/
RCT_EXTERN NSString *
RCTFormatError(NSString *message, NSArray<NSDictionary<NSString *, id> *> *stacktrace, NSUInteger maxMessageLength);
/**
* Formats a JS stack trace for logging.
*/
RCT_EXTERN NSString *RCTFormatStackTrace(NSArray<NSDictionary<NSString *, id> *> *stackTrace);
/**
* Convenience macro to assert which thread is currently running (DEBUG mode only)
*/
#ifdef DEBUG
#define RCTAssertThread(thread, ...) \
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") RCTAssert( \
[(id)thread isKindOfClass:[NSString class]] ? [RCTCurrentThreadName() isEqualToString:(NSString *)thread] \
: [(id)thread isKindOfClass:[NSThread class]] ? [NSThread currentThread] == (NSThread *)thread \
: dispatch_get_current_queue() == (dispatch_queue_t)thread, \
__VA_ARGS__); \
_Pragma("clang diagnostic pop")
#else
#define RCTAssertThread(thread, ...) \
do { \
} while (0)
#endif

233
node_modules/react-native/React/Base/RCTAssert.m generated vendored Normal file
View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTAssert.h"
#import "RCTLog.h"
NSString *const RCTErrorDomain = @"RCTErrorDomain";
NSString *const RCTJSStackTraceKey = @"RCTJSStackTraceKey";
NSString *const RCTJSRawStackTraceKey = @"RCTJSRawStackTraceKey";
NSString *const RCTObjCStackTraceKey = @"RCTObjCStackTraceKey";
NSString *const RCTFatalExceptionName = @"RCTFatalException";
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";
NSString *const RCTJSExtraDataKey = @"RCTJSExtraDataKey";
static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";
RCTAssertFunction RCTCurrentAssertFunction = nil;
RCTFatalHandler RCTCurrentFatalHandler = nil;
RCTFatalExceptionHandler RCTCurrentFatalExceptionHandler = nil;
NSException *_RCTNotImplementedException(SEL /*cmd*/, Class /*cls*/);
NSException *_RCTNotImplementedException(SEL cmd, Class cls)
{
NSString *msg = [NSString stringWithFormat:
@"%s is not implemented "
"for the class %@",
sel_getName(cmd),
cls];
return [NSException exceptionWithName:@"RCTNotDesignatedInitializerException" reason:msg userInfo:nil];
}
void RCTSetAssertFunction(RCTAssertFunction assertFunction)
{
RCTCurrentAssertFunction = assertFunction;
}
RCTAssertFunction RCTGetAssertFunction(void)
{
return RCTCurrentAssertFunction;
}
void RCTAddAssertFunction(RCTAssertFunction assertFunction)
{
RCTAssertFunction existing = RCTCurrentAssertFunction;
if (existing) {
RCTCurrentAssertFunction =
^(NSString *condition, NSString *fileName, NSNumber *lineNumber, NSString *function, NSString *message) {
existing(condition, fileName, lineNumber, function, message);
assertFunction(condition, fileName, lineNumber, function, message);
};
} else {
RCTCurrentAssertFunction = assertFunction;
}
}
/**
* returns the topmost stacked assert function for the current thread, which
* may not be the same as the current value of RCTCurrentAssertFunction.
*/
static RCTAssertFunction RCTGetLocalAssertFunction(void)
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSArray<RCTAssertFunction> *functionStack = threadDictionary[RCTAssertFunctionStack];
RCTAssertFunction assertFunction = functionStack.lastObject;
if (assertFunction) {
return assertFunction;
}
return RCTCurrentAssertFunction;
}
void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction)
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSMutableArray<RCTAssertFunction> *functionStack = threadDictionary[RCTAssertFunctionStack];
if (!functionStack) {
functionStack = [NSMutableArray new];
threadDictionary[RCTAssertFunctionStack] = functionStack;
}
[functionStack addObject:assertFunction];
block();
[functionStack removeLastObject];
}
NSString *RCTCurrentThreadName(void)
{
NSThread *thread = [NSThread currentThread];
NSString *threadName = RCTIsMainQueue() || thread.isMainThread ? @"main" : thread.name;
if (threadName.length == 0) {
const char *label = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
if (label && strlen(label) > 0) {
threadName = @(label);
} else {
threadName = [NSString stringWithFormat:@"%p", thread];
}
}
return threadName;
}
void _RCTAssertFormat(
const char *condition,
const char *fileName,
int lineNumber,
const char *function,
NSString *format,
...)
{
RCTAssertFunction assertFunction = RCTGetLocalAssertFunction();
if (assertFunction) {
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
assertFunction(@(condition), @(fileName), @(lineNumber), @(function), message);
}
}
void RCTFatal(NSError *error)
{
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@", error.localizedDescription);
RCTFatalHandler fatalHandler = RCTGetFatalHandler();
if (fatalHandler) {
fatalHandler(error);
} else {
#if DEBUG
@try {
#endif
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, error.localizedDescription];
// Truncate the localized description to 175 characters to avoid wild screen overflows
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 175);
// Attach an untruncated copy of the description to the userInfo, in case it is needed
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
[userInfo setObject:RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], -1)
forKey:RCTUntruncatedMessageKey];
// Expected resulting exception information:
// name: RCTFatalException: <underlying error description>
// reason: <underlying error description plus JS stack trace, truncated to 175 characters>
// userInfo: <underlying error userinfo, plus untruncated description plus JS stack trace>
@throw [[NSException alloc] initWithName:name reason:message userInfo:userInfo];
#if DEBUG
} @catch (NSException *e) {
}
#endif
}
}
void RCTSetFatalHandler(RCTFatalHandler fatalHandler)
{
RCTCurrentFatalHandler = fatalHandler;
}
RCTFatalHandler RCTGetFatalHandler(void)
{
return RCTCurrentFatalHandler;
}
NSString *
RCTFormatError(NSString *message, NSArray<NSDictionary<NSString *, id> *> *stackTrace, NSUInteger maxMessageLength)
{
if (maxMessageLength > 0 && message.length > maxMessageLength) {
message = [[message substringToIndex:maxMessageLength] stringByAppendingString:@"..."];
}
NSString *prettyStack = RCTFormatStackTrace(stackTrace);
return [NSString
stringWithFormat:@"%@%@%@", message, prettyStack ? @", stack:\n" : @"", prettyStack ? prettyStack : @""];
}
NSString *RCTFormatStackTrace(NSArray<NSDictionary<NSString *, id> *> *stackTrace)
{
if (stackTrace) {
NSMutableString *prettyStack = [NSMutableString string];
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:@"\\b((?:seg-\\d+(?:_\\d+)?|\\d+)\\.js)"
options:NSRegularExpressionCaseInsensitive
error:NULL];
for (NSDictionary<NSString *, id> *frame in stackTrace) {
NSString *fileName = [frame[@"file"] lastPathComponent];
NSTextCheckingResult *match =
fileName != nil ? [regex firstMatchInString:fileName options:0 range:NSMakeRange(0, fileName.length)] : nil;
if (match) {
fileName = [NSString stringWithFormat:@"%@:", [fileName substringWithRange:match.range]];
} else {
fileName = @"";
}
[prettyStack
appendFormat:@"%@@%@%@:%@\n", frame[@"methodName"], fileName, frame[@"lineNumber"], frame[@"column"]];
}
return prettyStack;
}
return nil;
}
void RCTFatalException(NSException *exception)
{
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@: %@", exception.name, exception.reason);
RCTFatalExceptionHandler fatalExceptionHandler = RCTGetFatalExceptionHandler();
if (fatalExceptionHandler) {
fatalExceptionHandler(exception);
} else {
#if DEBUG
@try {
#endif
@throw exception;
#if DEBUG
} @catch (NSException *e) {
}
#endif
}
}
void RCTSetFatalExceptionHandler(RCTFatalExceptionHandler fatalExceptionHandler)
{
RCTCurrentFatalExceptionHandler = fatalExceptionHandler;
}
RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void)
{
return RCTCurrentFatalExceptionHandler;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTBridge.h>
#ifdef __cplusplus
#import <jsinspector-modern/ReactCdp.h>
#endif
@interface RCTBridge (Inspector)
/**
* The HostTarget for this bridge, if one has been created. Exposed for RCTCxxBridge only.
*/
@property (nonatomic, assign, readonly)
#ifdef __cplusplus
facebook::react::jsinspector_modern::HostTarget *
#else
// The inspector infrastructure cannot be used in C or Swift code.
void *
#endif
inspectorTarget;
@property (nonatomic, readonly, getter=isInspectable) BOOL inspectable;
@end

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTBridge.h>
@class RCTModuleRegistry;
@class RCTModuleData;
@protocol RCTJavaScriptExecutor;
RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
RCT_EXTERN void RCTRegisterModule(Class);
@interface RCTBridge ()
#ifndef RCT_REMOVE_LEGACY_ARCH
// Private designated initializer
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
bundleURL:(NSURL *)bundleURL
moduleProvider:(RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER
__deprecated_msg("This API will be removed along with the legacy architecture.");
#endif // RCT_REMOVE_LEGACY_ARCH
// Used for the profiler flow events between JS and native
@property (nonatomic, assign) int64_t flowID;
@property (nonatomic, assign) CFMutableDictionaryRef flowIDMap;
@property (nonatomic, strong) NSLock *flowIDMapLock;
// Used by RCTDevMenu
@property (nonatomic, copy) NSString *bridgeDescription;
+ (instancetype)currentBridge;
+ (void)setCurrentBridge:(RCTBridge *)bridge;
/**
* Bridge setup code - creates an instance of RCTBachedBridge. Exposed for
* test only
*/
- (void)setUp;
/**
* This method is used to invoke a callback that was registered in the
* JavaScript application context. Safe to call from any thread.
*/
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args;
/**
* This property is mostly used on the main thread, but may be touched from
* a background thread if the RCTBridge happens to deallocate on a background
* thread. Therefore, we want all writes to it to be seen atomically.
*/
@property (atomic, strong) RCTBridge *batchedBridge;
/**
* The block that creates the modules' instances to be added to the bridge.
* Exposed for RCTCxxBridge
*/
@property (nonatomic, copy, readonly) RCTBridgeModuleListProvider moduleProvider;
/**
* Used by RCTDevMenu to override the `hot` param of the current bundleURL.
*/
@property (nonatomic, strong, readwrite) NSURL *bundleURL;
/**
* An object that allows one to require NativeModules/TurboModules.
* RCTModuleRegistry is implemented in bridgeless mode and bridge mode.
* Used by RCTRootView.
*/
@property (nonatomic, strong, readonly) RCTModuleRegistry *moduleRegistry;
@end
@interface RCTBridge (RCTCxxBridge)
/**
* Used by RCTModuleData
*/
@property (nonatomic, weak, readonly) RCTBridge *parentBridge;
/**
* Used by RCTModuleData
*/
@property (nonatomic, assign, readonly) BOOL moduleSetupComplete;
/**
* Called on the child bridge to run the executor and start loading.
*/
- (void)start;
/**
* Used by RCTModuleData to register the module for frame updates after it is
* lazily initialized.
*/
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData;
/**
* Dispatch work to a module's queue - this is also supports the fake RCTJSThread
* queue. Exposed for the RCTProfiler
*/
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
/**
* Get the module data for a given module name. Used by UIManager to implement
* the `dispatchViewManagerCommand` method.
*/
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName;
/**
* Registers additional classes with the ModuleRegistry.
*/
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)newModules;
/**
* Updates the ModuleRegistry with a pre-initialized instance.
*/
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance;
/**
* Systrace profiler toggling methods exposed for the RCTDevMenu
*/
- (void)startProfiling;
- (void)stopProfiling:(void (^)(NSData *))callback;
/**
* Synchronously call a specific native module's method and return the result
*/
- (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(NSArray *)params;
/**
* Hook exposed for RCTLog to send logs to JavaScript when not running in JSC
*/
- (void)logMessage:(NSString *)message level:(NSString *)level;
/**
* Allow super fast, one time, timers to skip the queue and be directly executed
*/
- (void)_immediatelyCallTimer:(NSNumber *)timer;
@end
@interface RCTCxxBridge : RCTBridge
// TODO(cjhopman): this seems unsafe unless we require that it is only called on the main js queue.
@property (nonatomic, readonly) void *runtime;
#ifndef RCT_REMOVE_LEGACY_ARCH
- (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER
__deprecated_msg("This API will be removed along with the legacy architecture.");
#endif // RCT_REMOVE_LEGACY_ARCH
@end

253
node_modules/react-native/React/Base/RCTBridge.h generated vendored Normal file
View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTBridgeModuleDecorator.h>
#import <React/RCTDefines.h>
#import <React/RCTFrameUpdate.h>
#import <React/RCTInvalidating.h>
#import "RCTBridgeConstants.h"
#import "RCTConstants.h"
@class JSValue;
@class RCTBridge;
@class RCTPerformanceLogger;
/**
* This block can be used to instantiate modules that require additional
* init parameters, or additional configuration prior to being used.
* The bridge will call this block to instantiate the modules, and will
* be responsible for invalidating/releasing them when the bridge is destroyed.
* For this reason, the block should always return new module instances, and
* module instances should not be shared between bridges.
*/
typedef NSArray<id<RCTBridgeModule>> * (^RCTBridgeModuleListProvider)(void);
RCT_EXTERN_C_BEGIN
/**
* This function returns the module name for a given class.
*/
NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
/**
* This function returns the list of modules that have been registered using the Old Architecture mechanism.
*/
NSMutableArray<NSString *> *getModulesLoadedWithOldArch(void);
/**
* Experimental.
* Check/set if JSI-bound NativeModule is enabled. By default it's off.
*/
BOOL RCTTurboModuleEnabled(void);
void RCTEnableTurboModule(BOOL enabled);
// Turn on TurboModule interop
BOOL RCTTurboModuleInteropEnabled(void);
void RCTEnableTurboModuleInterop(BOOL enabled);
// Turn on TurboModule interop's Bridge proxy
BOOL RCTTurboModuleInteropBridgeProxyEnabled(void);
void RCTEnableTurboModuleInteropBridgeProxy(BOOL enabled);
// Turn on the fabric interop layer
BOOL RCTFabricInteropLayerEnabled(void);
void RCTEnableFabricInteropLayer(BOOL enabled);
// Turn on TurboModule sync execution of void methods
BOOL RCTTurboModuleSyncVoidMethodsEnabled(void);
void RCTEnableTurboModuleSyncVoidMethods(BOOL enabled);
BOOL RCTUIManagerDispatchAccessibilityManagerInitOntoMain(void);
void RCTUIManagerSetDispatchAccessibilityManagerInitOntoMain(BOOL enabled);
typedef enum {
kRCTBridgeProxyLoggingLevelNone,
kRCTBridgeProxyLoggingLevelWarning,
kRCTBridgeProxyLoggingLevelError,
} RCTBridgeProxyLoggingLevel;
RCTBridgeProxyLoggingLevel RCTTurboModuleInteropBridgeProxyLogLevel(void);
void RCTSetTurboModuleInteropBridgeProxyLogLevel(RCTBridgeProxyLoggingLevel logLevel);
// Route all TurboModules through TurboModule interop
BOOL RCTTurboModuleInteropForAllTurboModulesEnabled(void);
void RCTEnableTurboModuleInteropForAllTurboModules(BOOL enabled);
typedef enum {
kRCTGlobalScope,
kRCTGlobalScopeUsingRetainJSCallback,
kRCTTurboModuleManagerScope,
} RCTTurboModuleCleanupMode;
RCTTurboModuleCleanupMode RCTGetTurboModuleCleanupMode(void);
void RCTSetTurboModuleCleanupMode(RCTTurboModuleCleanupMode mode);
RCT_EXTERN_C_END
/**
* Async batched bridge used to communicate with the JavaScript application.
*/
@interface RCTBridge : NSObject <RCTInvalidating>
/**
* Creates a new bridge with a custom RCTBridgeDelegate.
*
* All the interaction with the JavaScript context should be done using the bridge
* instance of the RCTBridgeModules. Modules will be automatically instantiated
* using the default constructor, but you can optionally pass in an array of
* pre-initialized module instances if they require additional init parameters
* or configuration.
*/
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
launchOptions:(NSDictionary *)launchOptions
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* DEPRECATED: Use initWithDelegate:launchOptions: instead
*
* The designated initializer. This creates a new bridge on top of the specified
* executor. The bridge should then be used for all subsequent communication
* with the JavaScript code running in the executor. Modules will be automatically
* instantiated using the default constructor, but you can optionally pass in an
* array of pre-initialized module instances if they require additional init
* parameters or configuration.
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleProvider:(RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* This method is used to call functions in the JavaScript application context.
* It is primarily intended for use by modules that require two-way communication
* with the JavaScript code. Safe to call from any thread.
*/
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
- (void)enqueueJSCall:(NSString *)module
method:(NSString *)method
args:(NSArray *)args
completion:(dispatch_block_t)completion;
/**
* This method registers the file path of an additional JS segment by its ID.
*
* @experimental
*/
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path;
/**
* Retrieve a bridge module instance by name or class. Note that modules are
* lazily instantiated, so calling these methods for the first time with a given
* module name/class may cause the class to be synchronously instantiated,
* potentially blocking both the calling thread and main thread for a short time.
*
* Note: This method does NOT lazily load the particular module if it's not yet loaded.
*/
- (id)moduleForName:(NSString *)moduleName;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
// Note: This method lazily load the module as necessary.
- (id)moduleForClass:(Class)moduleClass;
/**
* When a NativeModule performs a lookup for a TurboModule, we need to query
* the TurboModuleRegistry.
*/
- (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry;
/**
* This hook is called by the TurboModule infra with every ObjC module that's created.
* It allows the bridge to attach properties to ObjC modules that give those modules
* access to Bridge APIs.
*/
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator;
/**
* Convenience method for retrieving all modules conforming to a given protocol.
* Modules will be synchronously instantiated if they haven't already been,
* potentially blocking both the calling thread and main thread for a short time.
*/
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol;
/**
* Test if a module has been initialized. Use this prior to calling
* `moduleForClass:` or `moduleForName:` if you do not want to cause the module
* to be instantiated if it hasn't been already.
*/
- (BOOL)moduleIsInitialized:(Class)moduleClass;
/**
* All registered bridge module classes.
*/
@property (nonatomic, copy, readonly) NSArray<Class> *moduleClasses;
/**
* URL of the script that was loaded into the bridge.
*/
@property (nonatomic, strong, readonly) NSURL *bundleURL;
/**
* The class of the executor currently being used. Changes to this value will
* take effect after the bridge is reloaded.
*/
@property (nonatomic, strong) Class executorClass;
/**
* The delegate provided during the bridge initialization
*/
@property (nonatomic, weak, readonly) id<RCTBridgeDelegate> delegate;
/**
* The launch options that were used to initialize the bridge.
*/
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
/**
* Use this to check if the bridge is currently loading.
*/
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
/**
* Use this to check if the bridge has been invalidated.
*/
@property (nonatomic, readonly, getter=isValid) BOOL valid;
/**
* Link to the Performance Logger that logs React Native perf events.
*/
@property (nonatomic, readonly, strong) RCTPerformanceLogger *performanceLogger;
/**
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
- (void)reload __deprecated_msg("Use RCTReloadCommand instead");
/**
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
- (void)reloadWithReason:(NSString *)reason __deprecated_msg("Use RCTReloadCommand instead");
/**
* Handle notifications for a fast refresh. Safe to call from any thread.
*/
- (void)onFastRefresh;
/**
* Inform the bridge, and anything subscribing to it, that it should reload.
*/
- (void)requestReload __deprecated_msg("Use RCTReloadCommand instead");
/**
* Says whether bridge has started receiving calls from JavaScript.
*/
- (BOOL)isBatchActive;
@end

799
node_modules/react-native/React/Base/RCTBridge.mm generated vendored Normal file
View File

@@ -0,0 +1,799 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridge.h"
#import "RCTBridge+Inspector.h"
#import "RCTBridge+Private.h"
#import <objc/runtime.h>
#import "RCTConvert.h"
#if RCT_ENABLE_INSPECTOR
#import "RCTInspectorDevServerHelper.h"
#endif
#import <jsinspector-modern/InspectorFlags.h>
#import <jsinspector-modern/InspectorInterfaces.h>
#import <jsinspector-modern/ReactCdp.h>
#import <optional>
#import "RCTDevLoadingViewProtocol.h"
#import "RCTInspectorNetworkHelper.h"
#import "RCTInspectorUtils.h"
#import "RCTJSThread.h"
#import "RCTLog.h"
#import "RCTModuleData.h"
#import "RCTPausedInDebuggerOverlayController.h"
#import "RCTPerformanceLogger.h"
#import "RCTProfile.h"
#import "RCTReloadCommand.h"
#import "RCTUtils.h"
static NSMutableArray<Class> *RCTModuleClasses;
static dispatch_queue_t RCTModuleClassesSyncQueue;
NSArray<Class> *RCTGetModuleClasses(void)
{
__block NSArray<Class> *result;
dispatch_sync(RCTModuleClassesSyncQueue, ^{
result = [RCTModuleClasses copy];
});
return result;
}
NSSet<NSString *> *getCoreModuleClasses(void);
NSSet<NSString *> *getCoreModuleClasses(void)
{
static NSSet<NSString *> *coreModuleClasses = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
coreModuleClasses = [NSSet setWithArray:@[
@"RCTViewManager",
@"RCTActivityIndicatorViewManager",
@"RCTDebuggingOverlayManager",
@"RCTModalHostViewManager",
@"RCTModalManager",
@"RCTRefreshControlManager",
@"RCTSafeAreaViewManager",
@"RCTScrollContentViewManager",
@"RCTScrollViewManager",
@"RCTSwitchManager",
@"RCTUIManager",
@"RCTAccessibilityManager",
@"RCTActionSheetManager",
@"RCTAlertManager",
@"RCTAppearance",
@"RCTAppState",
@"RCTClipboard",
@"RCTDeviceInfo",
@"RCTDevLoadingView",
@"RCTDevMenu",
@"RCTDevSettings",
@"RCTDevToolsRuntimeSettingsModule",
@"RCTEventDispatcher",
@"RCTExceptionsManager",
@"RCTI18nManager",
@"RCTKeyboardObserver",
@"RCTLogBox",
@"RCTPerfMonitor",
@"RCTPlatform",
@"RCTRedBox",
@"RCTSourceCode",
@"RCTStatusBarManager",
@"RCTTiming",
@"RCTWebSocketModule",
@"RCTNativeAnimatedModule",
@"RCTNativeAnimatedTurboModule",
@"RCTBlobManager",
@"RCTFileReaderModule",
@"RCTBundleAssetImageLoader",
@"RCTGIFImageDecoder",
@"RCTImageEditingManager",
@"RCTImageLoader",
@"RCTImageStoreManager",
@"RCTImageViewManager",
@"RCTLocalAssetImageLoader",
@"RCTLinkingManager",
@"RCTDataRequestHandler",
@"RCTFileRequestHandler",
@"RCTHTTPRequestHandler",
@"RCTNetworking",
@"RCTPushNotificationManager",
@"RCTSettingsManager",
@"RCTBaseTextViewManager",
@"RCTBaseTextInputViewManager",
@"RCTInputAccessoryViewManager",
@"RCTMultilineTextInputViewManager",
@"RCTRawTextViewManager",
@"RCTSinglelineTextInputViewManager",
@"RCTTextViewManager",
@"RCTVirtualTextViewManager",
@"RCTVibration",
]];
});
return coreModuleClasses;
}
static NSMutableArray<NSString *> *modulesLoadedWithOldArch;
void addModuleLoadedWithOldArch(NSString * /*moduleName*/);
void addModuleLoadedWithOldArch(NSString *moduleName)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
modulesLoadedWithOldArch = [NSMutableArray new];
});
[modulesLoadedWithOldArch addObject:moduleName];
}
NSMutableArray<NSString *> *getModulesLoadedWithOldArch(void)
{
return modulesLoadedWithOldArch;
}
/**
* Register the given class as a bridge module. All modules must be registered
* prior to the first bridge initialization.
* TODO: (T115656171) Refactor RCTRegisterModule out of Bridge.m since it doesn't use the Bridge.
*/
void RCTRegisterModule(Class /*moduleClass*/);
void RCTRegisterModule(Class moduleClass)
{
if (RCTAreLegacyLogsEnabled() && ![getCoreModuleClasses() containsObject:[moduleClass description]]) {
addModuleLoadedWithOldArch([moduleClass description]);
}
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTModuleClasses = [NSMutableArray new];
RCTModuleClassesSyncQueue =
dispatch_queue_create("com.facebook.react.ModuleClassesSyncQueue", DISPATCH_QUEUE_CONCURRENT);
});
RCTAssert(
[moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
@"%@ does not conform to the RCTBridgeModule protocol",
moduleClass);
// Register module
dispatch_barrier_async(RCTModuleClassesSyncQueue, ^{
[RCTModuleClasses addObject:moduleClass];
});
}
/**
* This function returns the module name for a given class.
*/
NSString *RCTBridgeModuleNameForClass(Class cls)
{
#if RCT_DEBUG
RCTAssert(
[cls conformsToProtocol:@protocol(RCTBridgeModule)],
@"Bridge module `%@` does not conform to RCTBridgeModule",
cls);
#endif
NSString *name = [cls moduleName];
if (name.length == 0) {
name = NSStringFromClass(cls);
}
return RCTDropReactPrefixes(name);
}
static const BOOL turboModuleEnabled = YES;
BOOL RCTTurboModuleEnabled(void)
{
#if RCT_DEBUG
// TODO(T53341772): Allow TurboModule for test environment. Right now this breaks RNTester tests if enabled.
if (RCTRunningInTestEnvironment()) {
return NO;
}
#endif
return turboModuleEnabled;
}
void RCTEnableTurboModule(BOOL enabled)
{
// The new Architecture is enabled by default and we are ignoring changes to the TurboModule system.
}
static BOOL turboModuleInteropEnabled = NO;
BOOL RCTTurboModuleInteropEnabled(void)
{
return turboModuleInteropEnabled;
}
void RCTEnableTurboModuleInterop(BOOL enabled)
{
turboModuleInteropEnabled = enabled;
}
static BOOL turboModuleInteropBridgeProxyEnabled = NO;
BOOL RCTTurboModuleInteropBridgeProxyEnabled(void)
{
return turboModuleInteropBridgeProxyEnabled;
}
void RCTEnableTurboModuleInteropBridgeProxy(BOOL enabled)
{
turboModuleInteropBridgeProxyEnabled = enabled;
}
static BOOL fabricInteropLayerEnabled = YES;
BOOL RCTFabricInteropLayerEnabled()
{
return fabricInteropLayerEnabled;
}
void RCTEnableFabricInteropLayer(BOOL enabled)
{
fabricInteropLayerEnabled = enabled;
}
static RCTBridgeProxyLoggingLevel bridgeProxyLoggingLevel = kRCTBridgeProxyLoggingLevelNone;
RCTBridgeProxyLoggingLevel RCTTurboModuleInteropBridgeProxyLogLevel(void)
{
return bridgeProxyLoggingLevel;
}
void RCTSetTurboModuleInteropBridgeProxyLogLevel(RCTBridgeProxyLoggingLevel logLevel)
{
bridgeProxyLoggingLevel = logLevel;
}
// Turn on TurboModule sync execution of void methods
static BOOL gTurboModuleEnableSyncVoidMethods = NO;
BOOL RCTTurboModuleSyncVoidMethodsEnabled(void)
{
return gTurboModuleEnableSyncVoidMethods;
}
void RCTEnableTurboModuleSyncVoidMethods(BOOL enabled)
{
gTurboModuleEnableSyncVoidMethods = enabled;
}
BOOL kDispatchAccessibilityManagerInitOntoMain = NO;
BOOL RCTUIManagerDispatchAccessibilityManagerInitOntoMain(void)
{
return kDispatchAccessibilityManagerInitOntoMain;
}
void RCTUIManagerSetDispatchAccessibilityManagerInitOntoMain(BOOL enabled)
{
kDispatchAccessibilityManagerInitOntoMain = enabled;
}
#ifndef RCT_REMOVE_LEGACY_ARCH
class RCTBridgeHostTargetDelegate : public facebook::react::jsinspector_modern::HostTargetDelegate {
public:
RCTBridgeHostTargetDelegate(RCTBridge *bridge)
: bridge_(bridge),
pauseOverlayController_([[RCTPausedInDebuggerOverlayController alloc] init]),
networkHelper_([[RCTInspectorNetworkHelper alloc] init])
{
}
facebook::react::jsinspector_modern::HostTargetMetadata getMetadata() override
{
auto metadata = [RCTInspectorUtils getHostMetadata];
return {
.appDisplayName = [metadata.appDisplayName UTF8String],
.appIdentifier = [metadata.appIdentifier UTF8String],
.deviceName = [metadata.deviceName UTF8String],
.integrationName = "iOS Bridge (RCTBridge)",
.platform = [metadata.platform UTF8String],
.reactNativeVersion = [metadata.reactNativeVersion UTF8String],
};
}
void onReload(const PageReloadRequest &request) override
{
RCTAssertMainQueue();
RCTTriggerReloadCommandListeners(@"Reloading due to PageReloadRequest from DevTools.");
}
void onSetPausedInDebuggerMessage(const OverlaySetPausedInDebuggerMessageRequest &request) override
{
RCTAssertMainQueue();
if (!request.message.has_value()) {
[pauseOverlayController_ hide];
} else {
__weak RCTBridge *bridgeWeak = bridge_;
[pauseOverlayController_ showWithMessage:@(request.message.value().c_str())
onResume:^{
RCTAssertMainQueue();
RCTBridge *bridgeStrong = bridgeWeak;
if (!bridgeStrong) {
return;
}
if (!bridgeStrong.inspectorTarget) {
return;
}
bridgeStrong.inspectorTarget->sendCommand(
facebook::react::jsinspector_modern::HostCommand::DebuggerResume);
}];
}
}
void loadNetworkResource(const RCTInspectorLoadNetworkResourceRequest &params, RCTInspectorNetworkExecutor executor)
override
{
[networkHelper_ loadNetworkResourceWithParams:params executor:executor];
}
private:
__weak RCTBridge *bridge_;
RCTPausedInDebuggerOverlayController *pauseOverlayController_;
RCTInspectorNetworkHelper *networkHelper_;
};
@interface RCTBridge () <RCTReloadListener>
@end
@implementation RCTBridge {
NSURL *_delegateBundleURL;
std::unique_ptr<RCTBridgeHostTargetDelegate> _inspectorHostDelegate;
std::shared_ptr<facebook::react::jsinspector_modern::HostTarget> _inspectorTarget;
std::optional<int> _inspectorPageId;
}
+ (void)initialize
{
_RCTInitializeJSThreadConstantInternal();
}
static RCTBridge *RCTCurrentBridgeInstance = nil;
/**
* The last current active bridge instance. This is set automatically whenever
* the bridge is accessed. It can be useful for static functions or singletons
* that need to access the bridge for purposes such as logging, but should not
* be relied upon to return any particular instance, due to race conditions.
*/
+ (instancetype)currentBridge
{
return RCTCurrentBridgeInstance;
}
+ (void)setCurrentBridge:(RCTBridge *)currentBridge
{
RCTCurrentBridgeInstance = currentBridge;
}
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return [self initWithDelegate:delegate bundleURL:nil moduleProvider:nil launchOptions:launchOptions];
}
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleProvider:(RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions
{
return [self initWithDelegate:nil bundleURL:bundleURL moduleProvider:block launchOptions:launchOptions];
}
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
bundleURL:(NSURL *)bundleURL
moduleProvider:(RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions
{
// Only enabld this assertion in OSS
#if COCOAPODS
[RCTBridge throwIfOnLegacyArch];
#endif
if (self = [super init]) {
_delegate = delegate;
_bundleURL = bundleURL;
_moduleProvider = block;
_launchOptions = [launchOptions copy];
_inspectorHostDelegate = std::make_unique<RCTBridgeHostTargetDelegate>(self);
[self setUp];
}
return self;
}
// Wrap the exception throwing in a static method to avoid the warning: "The code following the exception will never be
// executed". This might create build failures internally where we treat warnings as errors.
+ (void)throwIfOnLegacyArch
{
@throw [NSException
exceptionWithName:NSInternalInconsistencyException
reason:
@"You are trying to initialize the legacy architecture. This is not supported anymore and will be removed in the next version of React Native. Please use the New Architecture instead."
userInfo:nil];
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)dealloc
{
RCTBridge *batchedBridge = self.batchedBridge;
/**
* This runs only on the main thread, but crashes the subclass
* RCTAssertMainQueue();
*/
// NOTE: RCTCxxBridge will use _inspectorTarget during [self invalidate], so we must
// keep it alive until after the call returns.
[self invalidate];
// `invalidate` is asynchronous if we aren't on the main queue. Unregister
// the HostTarget on the main queue so that `invalidate` can complete safely
// in that case.
if (_inspectorPageId.has_value()) {
// Since we can't keep using `self` after dealloc, steal its inspector
// state into block-mutable variables
__block auto inspectorPageId = std::move(_inspectorPageId);
__block auto inspectorTarget = std::move(_inspectorTarget);
RCTExecuteOnMainQueue(^{
facebook::react::jsinspector_modern::getInspectorInstance().removePage(*inspectorPageId);
inspectorPageId.reset();
// NOTE: RCTBridgeHostTargetDelegate holds a weak reference to RCTBridge.
// Conditionally call `inspectorTarget.reset()` to avoid a crash.
if (batchedBridge) {
[batchedBridge
dispatchBlock:^{
inspectorTarget.reset();
}
queue:RCTJSThread];
} else {
inspectorTarget.reset();
}
});
}
}
- (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry
{
[self.batchedBridge setRCTTurboModuleRegistry:turboModuleRegistry];
}
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator
{
return [self.batchedBridge bridgeModuleDecorator];
}
- (void)didReceiveReloadCommand
{
#if RCT_ENABLE_INSPECTOR
auto &inspectorFlags = facebook::react::jsinspector_modern::InspectorFlags::getInstance();
if (!inspectorFlags.getFuseboxEnabled()) {
// Disable debugger to resume the JsVM & avoid thread locks while reloading
[RCTInspectorDevServerHelper disableDebugger];
}
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillReloadNotification object:self userInfo:nil];
/**
* Any thread
*/
dispatch_async(dispatch_get_main_queue(), ^{
// WARNING: Invalidation is async, so it may not finish before re-setting up the bridge,
// causing some issues. TODO: revisit this post-Fabric/TurboModule.
[self invalidate];
// Reload is a special case, do not preserve launchOptions and treat reload as a fresh start
self->_launchOptions = nil;
[self setUp];
});
}
- (RCTModuleRegistry *)moduleRegistry
{
return self.batchedBridge.moduleRegistry;
}
- (NSArray<Class> *)moduleClasses
{
return self.batchedBridge.moduleClasses;
}
- (id)moduleForName:(NSString *)moduleName
{
return [self.batchedBridge moduleForName:moduleName];
}
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
return [self.batchedBridge moduleForName:moduleName lazilyLoadIfNecessary:lazilyLoad];
}
- (id)moduleForClass:(Class)moduleClass
{
id module = [self.batchedBridge moduleForClass:moduleClass];
if (!module) {
module = [self moduleForName:RCTBridgeModuleNameForClass(moduleClass)];
}
return module;
}
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol
{
NSMutableArray *modules = [NSMutableArray new];
for (Class moduleClass in [self.moduleClasses copy]) {
if ([moduleClass conformsToProtocol:protocol]) {
id module = [self moduleForClass:moduleClass];
if (module) {
[modules addObject:module];
}
}
}
return [modules copy];
}
- (BOOL)moduleIsInitialized:(Class)moduleClass
{
return [self.batchedBridge moduleIsInitialized:moduleClass];
}
/**
* DEPRECATED - please use RCTReloadCommand.
*/
- (void)reload
{
RCTTriggerReloadCommandListeners(@"Unknown from bridge");
}
/**
* DEPRECATED - please use RCTReloadCommand.
*/
- (void)reloadWithReason:(NSString *)reason
{
RCTTriggerReloadCommandListeners(reason);
}
- (void)onFastRefresh
{
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeFastRefreshNotification object:self];
}
/**
* DEPRECATED - please use RCTReloadCommand.
*/
- (void)requestReload
{
[self reloadWithReason:@"Requested from bridge"];
}
- (Class)bridgeClass
{
return [RCTCxxBridge class];
}
- (void)setUp
{
RCT_PROFILE_BEGIN_EVENT(0, @"-[RCTBridge setUp]", nil);
_performanceLogger = [RCTPerformanceLogger new];
[_performanceLogger markStartForTag:RCTPLInitReactRuntime];
[_performanceLogger markStartForTag:RCTPLBridgeStartup];
[_performanceLogger markStartForTag:RCTPLTTI];
auto &inspectorFlags = facebook::react::jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getFuseboxEnabled() && !_inspectorPageId.has_value()) {
_inspectorTarget =
facebook::react::jsinspector_modern::HostTarget::create(*_inspectorHostDelegate, [](auto callback) {
RCTExecuteOnMainQueue(^{
callback();
});
});
__weak RCTBridge *weakSelf = self;
_inspectorPageId = facebook::react::jsinspector_modern::getInspectorInstance().addPage(
"React Native Bridge",
/* vm */ "",
[weakSelf](std::unique_ptr<facebook::react::jsinspector_modern::IRemoteConnection> remote)
-> std::unique_ptr<facebook::react::jsinspector_modern::ILocalConnection> {
RCTBridge *strongSelf = weakSelf;
if (!strongSelf) {
// This can happen if we're about to be dealloc'd. Reject the connection.
return nullptr;
}
return strongSelf->_inspectorTarget->connect(std::move(remote));
},
{.nativePageReloads = true, .prefersFuseboxFrontend = true});
}
Class bridgeClass = self.bridgeClass;
// Only update bundleURL from delegate if delegate bundleURL has changed
NSURL *previousDelegateURL = _delegateBundleURL;
_delegateBundleURL = [self.delegate sourceURLForBridge:self];
if (_delegateBundleURL && ![_delegateBundleURL isEqual:previousDelegateURL]) {
_bundleURL = _delegateBundleURL;
}
// Sanitize the bundle URL
_bundleURL = [RCTConvert NSURL:_bundleURL.absoluteString];
RCTExecuteOnMainQueue(^{
RCTRegisterReloadCommandListener(self);
RCTReloadCommandSetBundleURL(self->_bundleURL);
});
self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
[self.batchedBridge start];
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
- (BOOL)isLoading
{
return self.batchedBridge.loading;
}
- (BOOL)isValid
{
return self.batchedBridge.valid;
}
- (BOOL)isBatchActive
{
return [_batchedBridge isBatchActive];
}
- (void)invalidate
{
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillBeInvalidatedNotification object:self];
RCTBridge *batchedBridge = self.batchedBridge;
self.batchedBridge = nil;
if (batchedBridge) {
RCTExecuteOnMainQueue(^{
[batchedBridge invalidate];
});
}
}
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance
{
[self.batchedBridge updateModuleWithInstance:instance];
}
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules
{
[self.batchedBridge registerAdditionalModuleClasses:modules];
}
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
{
NSArray<NSString *> *ids = [moduleDotMethod componentsSeparatedByString:@"."];
NSString *module = ids[0];
NSString *method = ids[1];
[self enqueueJSCall:module method:method args:args completion:NULL];
}
- (void)enqueueJSCall:(NSString *)module
method:(NSString *)method
args:(NSArray *)args
completion:(dispatch_block_t)completion
{
[self.batchedBridge enqueueJSCall:module method:method args:args completion:completion];
}
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args
{
[self.batchedBridge enqueueCallback:cbID args:args];
}
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
{
[self.batchedBridge registerSegmentWithId:segmentId path:path];
}
- (facebook::react::jsinspector_modern::HostTarget *)inspectorTarget
{
return _inspectorTarget.get();
}
@end
#else // RCT_REMOVE_LEGACY_ARCH
@implementation RCTBridge
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions
{
return self;
}
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleProvider:(__strong RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions
{
return self;
}
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
{
}
- (void)enqueueJSCall:(NSString *)module
method:(NSString *)method
args:(NSArray *)args
completion:(__strong dispatch_block_t)completion
{
}
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
{
}
- (id)moduleForName:(NSString *)moduleName
{
return nil;
}
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
return nil;
}
- (id)moduleForClass:(Class)moduleClass
{
return nil;
}
- (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry
{
}
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator
{
return nil;
}
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol
{
return @[];
}
- (BOOL)moduleIsInitialized:(Class)moduleClass
{
return NO;
}
- (void)reload __attribute__((deprecated("Use RCTReloadCommand instead")))
{
}
- (void)reloadWithReason:(NSString *)reason __attribute__((deprecated("Use RCTReloadCommand instead")))
{
}
- (void)onFastRefresh
{
}
- (void)requestReload __attribute__((deprecated("Use RCTReloadCommand instead")))
{
}
- (BOOL)isBatchActive
{
return NO;
}
- (void)setUp
{
}
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args
{
}
+ (void)setCurrentBridge:(RCTBridge *)bridge
{
}
- (void)invalidate
{
}
+ (instancetype)currentBridge
{
return nil;
}
@end
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
/**
* RCTBridgeConstants are constants that are only used in the legacy architecture.
* Please place constants used in the new architecture into RCTConstants.
*/
/**
* DEPRECATED - Use RCTReloadCommand instead. This notification fires just before the bridge starts
* processing a request to reload.
*/
RCT_EXTERN NSString *const RCTBridgeWillReloadNotification;
/**
* This notification fires whenever a fast refresh happens.
*/
RCT_EXTERN NSString *const RCTBridgeFastRefreshNotification;
/**
* This notification fires just before the bridge begins downloading a script
* from the packager.
*/
RCT_EXTERN NSString *const RCTBridgeWillDownloadScriptNotification;
/**
* This notification fires just after the bridge finishes downloading a script
* from the packager.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotification;
/**
* This notification fires right after the bridge is about to invalidate NativeModule
* instances during teardown. Handle this notification to perform additional invalidation.
*/
RCT_EXTERN NSString *const RCTBridgeWillInvalidateModulesNotification;
/**
* This notification fires right after the bridge finishes invalidating NativeModule
* instances during teardown. Handle this notification to perform additional invalidation.
*/
RCT_EXTERN NSString *const RCTBridgeDidInvalidateModulesNotification;
/**
* This notification fires right before the bridge starting invalidation process.
* Handle this notification to perform additional invalidation.
* The notification can be issued on any thread.
*/
RCT_EXTERN NSString *const RCTBridgeWillBeInvalidatedNotification;
/**
* Key for the RCTSource object in the RCTBridgeDidDownloadScriptNotification
* userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey;
/**
* Key for the reload reason in the RCTBridgeWillReloadNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationReasonKey;
/**
* Key for the bridge description (NSString_ in the
* RCTBridgeDidDownloadScriptNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey;

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridgeConstants.h"
NSString *const RCTBridgeWillReloadNotification = @"RCTBridgeWillReloadNotification";
NSString *const RCTBridgeFastRefreshNotification = @"RCTBridgeFastRefreshNotification";
NSString *const RCTBridgeWillDownloadScriptNotification = @"RCTBridgeWillDownloadScriptNotification";
NSString *const RCTBridgeDidDownloadScriptNotification = @"RCTBridgeDidDownloadScriptNotification";
NSString *const RCTBridgeWillInvalidateModulesNotification = @"RCTBridgeWillInvalidateModulesNotification";
NSString *const RCTBridgeDidInvalidateModulesNotification = @"RCTBridgeDidInvalidateModulesNotification";
NSString *const RCTBridgeWillBeInvalidatedNotification = @"RCTBridgeWillBeInvalidatedNotification";
NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey = @"source";
NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey = @"bridgeDescription";

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTJavaScriptLoader.h>
@class RCTBridge;
@protocol RCTBridgeModule;
NS_ASSUME_NONNULL_BEGIN
@protocol RCTBridgeDelegate <NSObject>
#ifndef RCT_REMOVE_LEGACY_ARCH
/**
* The location of the JavaScript source file. When running from the packager
* this should be an absolute URL, e.g. `http://localhost:8081/index.ios.bundle`.
* When running from a locally bundled JS file, this should be a `file://` url
* pointing to a path inside the app resources, e.g. `file://.../main.jsbundle`.
*/
- (NSURL *__nullable)sourceURLForBridge:(RCTBridge *)bridge
__deprecated_msg("This API will be removed along with the legacy architecture.");
@optional
/**
* The bridge initializes any registered RCTBridgeModules automatically, however
* if you wish to instantiate your own module instances, you can return them
* from this method.
*
* Note: You should always return a new instance for each call, rather than
* returning the same instance each time the bridge is reloaded. Module instances
* should not be shared between bridges, and this may cause unexpected behavior.
*
* It is also possible to override standard modules with your own implementations
* by returning a class with the same `moduleName` from this method, but this is
* not recommended in most cases - if the module methods and behavior do not
* match exactly, it may lead to bugs or crashes.
*/
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* The bridge will call this method when a module been called from JS
* cannot be found among registered modules.
* It should return YES if the module with name 'moduleName' was registered
* in the implementation, and the system must attempt to look for it again among registered.
* If the module was not registered, return NO to prevent further searches.
*/
- (BOOL)bridge:(RCTBridge *)bridge
didNotFindModule:(NSString *)moduleName
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* The bridge will automatically attempt to load the JS source code from the
* location specified by the `sourceURLForBridge:` method, however, if you want
* to handle loading the JS yourself, you can do so by implementing this method.
*/
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Similar to loadSourceForBridge:onProgress:onComplete: but without progress
* reporting.
*/
- (void)loadSourceForBridge:(RCTBridge *)bridge
withBlock:(RCTSourceLoadBlock)loadCallback
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Retrieve the list of lazy-native-modules names for the given bridge.
*/
- (NSDictionary<NSString *, Class> *)extraLazyModuleClassesForBridge:(RCTBridge *)bridge
__deprecated_msg("This API will be removed along with the legacy architecture.");
#endif // RCT_REMOVE_LEGACY_ARCH
@end
NS_ASSUME_NONNULL_END

38
node_modules/react-native/React/Base/RCTBridgeMethod.h generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTBridge;
typedef NS_ENUM(NSInteger, RCTFunctionType) {
RCTFunctionTypeNormal,
RCTFunctionTypePromise,
RCTFunctionTypeSync,
};
static inline const char *RCTFunctionDescriptorFromType(RCTFunctionType type)
{
switch (type) {
case RCTFunctionTypePromise:
return "promise";
case RCTFunctionTypeSync:
return "sync";
case RCTFunctionTypeNormal:
default:
return "async";
}
}
@protocol RCTBridgeMethod <NSObject>
@property (nonatomic, readonly) const char *JSMethodName;
@property (nonatomic, readonly) RCTFunctionType functionType;
- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments;
@end

422
node_modules/react-native/React/Base/RCTBridgeModule.h generated vendored Normal file
View File

@@ -0,0 +1,422 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <React/RCTDefines.h>
#import <React/RCTJSThread.h>
#import <RCTDeprecation/RCTDeprecation.h>
#import "RCTBundleManager.h"
@class RCTBridge;
@protocol RCTBridgeMethod;
@protocol RCTTurboModule;
@protocol RCTTurboModuleRegistry;
@class RCTModuleRegistry;
@class RCTViewRegistry;
@class RCTCallableJSModules;
/**
* The type of a block that is capable of sending a response to a bridged
* operation. Use this for returning callback methods to JS.
*/
typedef void (^RCTResponseSenderBlock)(NSArray *response);
/**
* The type of a block that is capable of sending an error response to a
* bridged operation. Use this for returning error information to JS.
*/
typedef void (^RCTResponseErrorBlock)(NSError *error);
/**
* Block that bridge modules use to resolve the JS promise waiting for a result.
* Nil results are supported and are converted to JS's undefined value.
*/
typedef void (^RCTPromiseResolveBlock)(id result);
/**
* Block that bridge modules use to reject the JS promise waiting for a result.
* The error may be nil but it is preferable to pass an NSError object for more
* precise error messages.
*/
typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
RCT_EXTERN_C_BEGIN
typedef struct RCTMethodInfo {
const char *const jsName;
const char *const objcName;
const BOOL isSync;
} RCTMethodInfo;
RCT_EXTERN_C_END
/**
* Provides the interface needed to register a bridge module.
*/
@protocol RCTBridgeModule <NSObject>
/**
* Place this macro in your class implementation to automatically register
* your module with the bridge when it loads. The optional js_name argument
* will be used as the JS module name. If omitted, the JS module name will
* match the Objective-C class name.
*/
#ifndef RCT_DISABLE_STATIC_MODULE_REGISTRATION
#define RCT_EXPORT_MODULE(js_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+(NSString *)moduleName \
{ \
return @ #js_name; \
} \
+(void)load \
{ \
RCTRegisterModule(self); \
}
#else
#define RCT_EXPORT_MODULE(js_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+(NSString *)moduleName \
{ \
return @ #js_name; \
}
#endif // RCT_DISABLE_STATIC_MODULE_REGISTRATION
/**
* Same as RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module
* registration. Useful for registering swift classes that forbids use of load
* Used in RCT_EXTERN_REMAP_MODULE
*/
#define RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+(NSString *)moduleName \
{ \
return @ #js_name; \
} \
__attribute__((constructor)) static void RCT_CONCAT(initialize_, objc_name)(void) \
{ \
RCTRegisterModule([objc_name class]); \
}
// Implemented by RCT_EXPORT_MODULE
+ (NSString *)moduleName;
@optional
/**
* A reference to the RCTModuleRegistry. Useful for modules that require access
* to other NativeModules. To implement this in your module, just add `@synthesize
* moduleRegistry = _moduleRegistry;`. If using Swift, add
* `@objc var moduleRegistry: RCTModuleRegistry!` to your module.
*/
@property (nonatomic, weak, readwrite) RCTModuleRegistry *moduleRegistry;
/**
* A reference to the RCTViewRegistry. Useful for modules that query UIViews,
* given a react tag. This API is deprecated, and only exists to help migrate
* NativeModules to Venice.
*
* To implement this in your module, just add `@synthesize
* viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;`. If using Swift, add
* `@objc var viewRegistry_DEPRECATED: RCTViewRegistry!` to your module.
*/
@property (nonatomic, weak, readwrite) RCTViewRegistry *viewRegistry_DEPRECATED;
/**
* A reference to the RCTBundleManager. Useful for modules that need to read
* or write to the app's bundle URL.
*
* To implement this in your module, just add `@synthesize bundleManager =
* _bundleManager;`. If using Swift, add `@objc var bundleManager:
* RCTBundleManager!` to your module.
*/
@property (nonatomic, weak, readwrite) RCTBundleManager *bundleManager;
/**
* A reference to an RCTCallableJSModules. Useful for modules that need to
* call into methods on JavaScript modules registered as callable with
* React Native.
*
* To implement this in your module, just add `@synthesize callableJSModules =
* _callableJSModules;`. If using Swift, add `@objc var callableJSModules:
* RCTCallableJSModules!` to your module.
*/
@property (nonatomic, weak, readwrite) RCTCallableJSModules *callableJSModules;
/**
* A reference to the RCTBridge. Useful for modules that require access
* to bridge features, such as sending events or making JS calls. This
* will be set automatically by the bridge when it initializes the module.
* To implement this in your module, just add `@synthesize bridge = _bridge;`
* If using Swift, add `@objc var bridge: RCTBridge!` to your module.
*/
@property (nonatomic, weak, readonly) RCTBridge *bridge RCT_DEPRECATED;
/**
* This property is deprecated. This selector used to support two functionalities.
*
* 1) Providing a queue to do additional async work.
* Instead of synthesizing this selector, retrieve a queue from GCD to do any asynchronous work.
* Example: _myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
*
* 2) Overriding this in order to run all the module's methods on a specific queue, usually main.
* Instead of overriding this, directly dispatch the code onto main queue when necessary.
* Example: dispatch_async(dispatch_get_main_queue, ^{ ... });
*/
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue RCT_DEPRECATED;
/**
* Wrap the parameter line of your method implementation with this macro to
* expose it to JS. By default the exposed method will match the first part of
* the Objective-C method selector name (up to the first colon). Use
* RCT_REMAP_METHOD to specify the JS name of the method.
*
* For example, in ModuleName.m:
*
* - (void)doSomething:(NSString *)aString withA:(NSInteger)a andB:(NSInteger)b
* { ... }
*
* becomes
*
* RCT_EXPORT_METHOD(doSomething:(NSString *)aString
* withA:(NSInteger)a
* andB:(NSInteger)b)
* { ... }
*
* and is exposed to JavaScript as `NativeModules.ModuleName.doSomething`.
*
* ## Promises
*
* Bridge modules can also define methods that are exported to JavaScript as
* methods that return a Promise, and are compatible with JS async functions.
*
* Declare the last two parameters of your native method to be a resolver block
* and a rejecter block. The resolver block must precede the rejecter block.
*
* For example:
*
* RCT_EXPORT_METHOD(doSomethingAsync:(NSString *)aString
* resolver:(RCTPromiseResolveBlock)resolve
* rejecter:(RCTPromiseRejectBlock)reject
* { ... }
*
* Calling `NativeModules.ModuleName.doSomethingAsync(aString)` from
* JavaScript will return a promise that is resolved or rejected when your
* native method implementation calls the respective block.
*
*/
#define RCT_EXPORT_METHOD(method) RCT_REMAP_METHOD(, method)
/**
* Same as RCT_EXPORT_METHOD but the method is called from JS
* synchronously **on the JS thread**, possibly returning a result.
*
* WARNING: in the vast majority of cases, you should use RCT_EXPORT_METHOD which
* allows your native module methods to be called asynchronously: calling
* methods synchronously can have strong performance penalties and introduce
* threading-related bugs to your native modules.
*
* The return type must be of object type (id) and should be serializable
* to JSON. This means that the hook can only return nil or JSON values
* (e.g. NSNumber, NSString, NSArray, NSDictionary).
*
* Calling these methods when running under the websocket executor
* is currently not supported.
*/
#define RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(method) RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(id, method)
#define RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(returnType, method) \
RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(, returnType, method)
/**
* Similar to RCT_EXPORT_METHOD but lets you set the JS name of the exported
* method. Example usage:
*
* RCT_REMAP_METHOD(executeQueryWithParameters,
* executeQuery:(NSString *)query parameters:(NSDictionary *)parameters)
* { ... }
*/
#define RCT_REMAP_METHOD(js_name, method) \
_RCT_EXTERN_REMAP_METHOD(js_name, method, NO) \
-(void)method RCT_DYNAMIC
/**
* Similar to RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD but lets you set
* the JS name of the exported method. Example usage:
*
* RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(executeQueryWithParameters,
* executeQuery:(NSString *)query parameters:(NSDictionary *)parameters)
* { ... }
*/
#define RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(js_name, returnType, method) \
_RCT_EXTERN_REMAP_METHOD(js_name, method, YES) \
-(returnType)method RCT_DYNAMIC
/**
* Use this macro in a private Objective-C implementation file to automatically
* register an external module with the bridge when it loads. This allows you to
* register Swift or private Objective-C classes with the bridge.
*
* For example if one wanted to export a Swift class to the bridge:
*
* MyModule.swift:
*
* @objc(MyModule) class MyModule: NSObject {
*
* @objc func doSomething(string: String! withFoo a: Int, bar b: Int) { ... }
*
* }
*
* MyModuleExport.m:
*
* #import <React/RCTBridgeModule.h>
*
* @interface RCT_EXTERN_MODULE(MyModule, NSObject)
*
* RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b)
*
* @end
*
* This will now expose MyModule and the method to JavaScript via
* `NativeModules.MyModule.doSomething`
*/
#define RCT_EXTERN_MODULE(objc_name, objc_supername) RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername)
/**
* Like RCT_EXTERN_MODULE, but allows setting a custom JavaScript name.
*/
#define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \
objc_name: \
objc_supername @ \
end @interface objc_name(RCTExternModule)<RCTBridgeModule> \
@end \
@implementation objc_name (RCTExternModule) \
RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name)
/**
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
* of an external module.
*/
#define RCT_EXTERN_METHOD(method) _RCT_EXTERN_REMAP_METHOD(, method, NO)
/**
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
* of an external module that should be invoked synchronously.
*/
#define RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(method) _RCT_EXTERN_REMAP_METHOD(, method, YES)
/**
* Like RCT_EXTERN_REMAP_METHOD, but allows setting a custom JavaScript name
* and also whether this method is synchronous.
*/
#define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
+(const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) \
{ \
static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
return &config; \
}
/**
* Most modules can be used from any thread. All of the modules exported non-sync method will be called on its
* methodQueue, and the module will be constructed lazily when its first invoked. Some modules have main need to access
* information that's main queue only (e.g. most UIKit classes). Since we don't want to dispatch synchronously to the
* main thread to this safely, we construct these modules and export their constants ahead-of-time.
*
* Note that when set to false, the module constructor will be called from any thread.
*
* This requirement is currently inferred by checking if the module has a custom initializer or if there's exported
* constants. In the future, we'll stop automatically inferring this and instead only rely on this method.
*/
+ (BOOL)requiresMainQueueSetup;
/**
* Injects methods into JS. Entries in this array are used in addition to any
* methods defined using the macros above. This method is called only once,
* before registration.
*/
- (NSArray<id<RCTBridgeMethod>> *)methodsToExport;
/**
* Injects constants into JS. These constants are made accessible via NativeModules.ModuleName.X. It is only called once
* for the lifetime of the bridge, so it is not suitable for returning dynamic values, but may be used for long-lived
* values such as session keys, that are regenerated only as part of a reload of the entire React application.
*
* If you implement this method and do not implement `requiresMainQueueSetup`, you will trigger deprecated logic
* that eagerly initializes your module on bridge startup. In the future, this behaviour will be changed to default
* to initializing lazily, and even modules with constants will be initialized lazily.
*/
- (NSDictionary *)constantsToExport;
/**
* Notifies the module that a batch of JS method invocations has just completed.
*/
- (void)batchDidComplete RCT_DEPRECATED;
@end
/**
* A class that allows NativeModules and TurboModules to look up one another.
*/
@interface RCTModuleRegistry : NSObject
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry;
- (id)moduleForName:(const char *)moduleName;
- (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
- (BOOL)moduleIsInitialized:(Class)moduleClass;
// Note: This method lazily load the module as necessary.
- (id)moduleForClass:(Class)moduleClass;
@end
typedef UIView * (^RCTBridgelessComponentViewProvider)(NSNumber *);
typedef void (^RCTViewRegistryUIBlock)(RCTViewRegistry *viewRegistry);
/**
* A class that allows NativeModules to query for views, given React Tags.
*/
@interface RCTViewRegistry : NSObject
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider)bridgelessComponentViewProvider;
- (UIView *)viewForReactTag:(NSNumber *)reactTag;
- (void)addUIBlock:(RCTViewRegistryUIBlock)block;
@end
typedef void (^RCTBridgelessJSModuleMethodInvoker)(
NSString *moduleName,
NSString *methodName,
NSArray *args,
dispatch_block_t onComplete);
/**
* A class that allows NativeModules to call methods on JavaScript modules registered
* as callable with React Native.
*/
@interface RCTCallableJSModules : NSObject
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker;
- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args;
- (void)invokeModule:(NSString *)moduleName
method:(NSString *)methodName
withArgs:(NSArray *)args
onComplete:(dispatch_block_t)onComplete;
@end

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridgeModule.h"
@class RCTBundleManager;
@class RCTCallableJSModules;
@class RCTModuleRegistry;
@class RCTViewRegistry;
/**
RCTBridgeModuleDecorator contains instances that can be initialized with @synthesize
in RCTBridgeModules. For the Fabric interop layer.
In Bridgeless, @synthesize ivars are passed from RCTBridgeModuleDecorator.
In Bridge, @synthesize ivars are passed from RCTModuleData.
*/
@interface RCTBridgeModuleDecorator : NSObject
@property (nonatomic, strong, readonly) RCTViewRegistry *viewRegistry_DEPRECATED;
@property (nonatomic, strong, readonly) RCTModuleRegistry *moduleRegistry;
@property (nonatomic, strong, readonly) RCTBundleManager *bundleManager;
@property (nonatomic, strong, readonly) RCTCallableJSModules *callableJSModules;
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules;
- (void)attachInteropAPIsToModule:(id<RCTBridgeModule>)bridgeModule;
@end

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridgeModuleDecorator.h"
@implementation RCTBridgeModuleDecorator
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
if (self = [super init]) {
_viewRegistry_DEPRECATED = viewRegistry;
_moduleRegistry = moduleRegistry;
_bundleManager = bundleManager;
_callableJSModules = callableJSModules;
}
return self;
}
- (void)attachInteropAPIsToModule:(id<RCTBridgeModule>)bridgeModule
{
/**
* Attach the RCTViewRegistry to this TurboModule, which allows this TurboModule
* To query a React component's UIView, given its reactTag.
*
* Usage: In the TurboModule @implementation, include:
* `@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED`
*/
if ([bridgeModule respondsToSelector:@selector(setViewRegistry_DEPRECATED:)]) {
bridgeModule.viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;
}
/**
* Attach the RCTBundleManager to this TurboModule, which allows this TurboModule to
* read from/write to the app's bundle URL.
*
* Usage: In the TurboModule @implementation, include:
* `@synthesize bundleManager = _bundleManager`
*/
if ([bridgeModule respondsToSelector:@selector(setBundleManager:)]) {
bridgeModule.bundleManager = _bundleManager;
}
/**
* Attach the RCTCallableJSModules to this TurboModule, which allows this TurboModule
* to call JS Module methods.
*
* Usage: In the TurboModule @implementation, include:
* `@synthesize callableJSModules = _callableJSModules`
*/
if ([bridgeModule respondsToSelector:@selector(setCallableJSModules:)]) {
bridgeModule.callableJSModules = _callableJSModules;
}
/**
* Attach the RCTModuleRegistry to this TurboModule, which allows this TurboModule
* to require other TurboModules/NativeModules.
*
* Usage: In the TurboModule @implementation, include:
* `@synthesize moduleRegistry = _moduleRegistry`
*/
if ([bridgeModule respondsToSelector:@selector(setModuleRegistry:)]) {
bridgeModule.moduleRegistry = _moduleRegistry;
}
}
@end

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifdef __cplusplus
#import <ReactCommon/CallInvoker.h>
#endif
#import "RCTBridgeProxy.h"
@interface RCTBridgeProxy (Cxx)
#ifdef __cplusplus
@property (nonatomic, readwrite) std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker;
#endif
@end

47
node_modules/react-native/React/Base/RCTBridgeProxy.h generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
NS_ASSUME_NONNULL_BEGIN
@class RCTBundleManager;
@class RCTCallableJSModules;
@class RCTModuleRegistry;
@class RCTViewRegistry;
@interface RCTBridgeProxy : NSProxy
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread
registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId
runtime:(void *)runtime
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (void)logWarning:(NSString *)message cmd:(SEL)cmd;
- (void)logError:(NSString *)message cmd:(SEL)cmd;
/**
* Methods required for RCTBridge class extensions
*/
- (id)moduleForClass:(Class)moduleClass;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
@end
NS_ASSUME_NONNULL_END

504
node_modules/react-native/React/Base/RCTBridgeProxy.mm generated vendored Normal file
View File

@@ -0,0 +1,504 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridgeProxy.h"
#import "RCTBridgeProxy+Cxx.h"
#import <React/RCTBridge+Private.h>
#import <React/RCTBridge.h>
#import <React/RCTLog.h>
#import <React/RCTUIManager.h>
#import <ReactCommon/CallInvoker.h>
#import <jsi/jsi.h>
using namespace facebook;
@interface RCTUIManagerProxy : NSProxy
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry NS_DESIGNATED_INITIALIZER;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
- (void)forwardInvocation:(NSInvocation *)invocation;
@end
@interface RCTBridgeProxy ()
@property (nonatomic, readwrite) std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker;
@end
@implementation RCTBridgeProxy {
RCTUIManagerProxy *_uiManagerProxy;
RCTModuleRegistry *_moduleRegistry;
RCTBundleManager *_bundleManager;
RCTCallableJSModules *_callableJSModules;
NSDictionary *_launchOptions;
void (^_dispatchToJSThread)(dispatch_block_t);
void (^_registerSegmentWithId)(NSNumber *, NSString *);
void *_runtime;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread
registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId
runtime:(void *)runtime
launchOptions:(nullable NSDictionary *)launchOptions
{
self = [super self];
if (self != nullptr) {
_uiManagerProxy = [[RCTUIManagerProxy alloc] initWithViewRegistry:viewRegistry];
_moduleRegistry = moduleRegistry;
_bundleManager = bundleManager;
_callableJSModules = callableJSModules;
_dispatchToJSThread = dispatchToJSThread;
_registerSegmentWithId = registerSegmentWithId;
_runtime = runtime;
_launchOptions = [launchOptions copy];
}
return self;
}
#pragma clang diagnostic pop
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue
{
[self logWarning:@"Please migrate to dispatchToJSThread: @synthesize dispatchToJSThread = _dispatchToJSThread"
cmd:_cmd];
if (queue == RCTJSThread) {
_dispatchToJSThread(block);
} else if (queue != nullptr) {
dispatch_async(queue, block);
}
}
/**
* Used By:
* - RCTDevSettings
*/
- (Class)executorClass
{
[self logWarning:@"This method is unsupported. Returning nil." cmd:_cmd];
return nil;
}
/**
* Used By:
* - RCTBlobCollector
*/
- (void *)runtime
{
[self logWarning:@"Please migrate to C++ TurboModule or RuntimeExecutor." cmd:_cmd];
return _runtime;
}
- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker
{
[self logWarning:@"Please migrate to RuntimeExecutor" cmd:_cmd];
return _jsCallInvoker;
}
/**
* RCTModuleRegistry
*/
- (id)moduleForName:(NSString *)moduleName
{
[self logWarning:@"Please migrate to RCTModuleRegistry: @synthesize moduleRegistry = _moduleRegistry." cmd:_cmd];
return [_moduleRegistry moduleForName:[moduleName UTF8String]];
}
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
[self logWarning:@"Please migrate to RCTModuleRegistry: @synthesize moduleRegistry = _moduleRegistry." cmd:_cmd];
return [_moduleRegistry moduleForName:[moduleName UTF8String] lazilyLoadIfNecessary:lazilyLoad];
}
- (id)moduleForClass:(Class)moduleClass
{
[self logWarning:@"Please migrate to RCTModuleRegistry: @synthesize moduleRegistry = _moduleRegistry." cmd:_cmd];
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
return [_moduleRegistry moduleForName:[moduleName UTF8String] lazilyLoadIfNecessary:YES];
}
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol
{
[self logError:@"The TurboModule system cannot load modules by protocol. Returning an empty NSArray*." cmd:_cmd];
return @[];
}
- (BOOL)moduleIsInitialized:(Class)moduleClass
{
[self logWarning:@"Please migrate to RCTModuleRegistry: @synthesize moduleRegistry = _moduleRegistry." cmd:_cmd];
return [_moduleRegistry moduleIsInitialized:moduleClass];
}
- (NSArray<Class> *)moduleClasses
{
[self logError:@"The TurboModuleManager does not implement this method. Returning an empty NSArray*." cmd:_cmd];
return @[];
}
/**
* RCTBundleManager
*/
- (void)setBundleURL:(NSURL *)bundleURL
{
[self logWarning:@"Please migrate to RCTBundleManager: @synthesize bundleManager = _bundleManager." cmd:_cmd];
[_bundleManager setBundleURL:bundleURL];
}
- (NSURL *)bundleURL
{
[self logWarning:@"Please migrate to RCTBundleManager: @synthesize bundleManager = _bundleManager." cmd:_cmd];
return [_bundleManager bundleURL];
}
/**
* RCTCallableJSModules
*/
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
{
[self logWarning:@"Please migrate to RCTCallableJSModules: @synthesize callableJSModules = _callableJSModules."
cmd:_cmd];
NSArray<NSString *> *ids = [moduleDotMethod componentsSeparatedByString:@"."];
NSString *module = ids[0];
NSString *method = ids[1];
[_callableJSModules invokeModule:module method:method withArgs:args];
}
- (void)enqueueJSCall:(NSString *)module
method:(NSString *)method
args:(NSArray *)args
completion:(dispatch_block_t)completion
{
[self logWarning:@"Please migrate to RCTCallableJSModules: @synthesize callableJSModules = _callableJSModules."
cmd:_cmd];
[_callableJSModules invokeModule:module method:method withArgs:args onComplete:completion];
}
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
{
_registerSegmentWithId(@(segmentId), path);
}
- (id<RCTBridgeDelegate>)delegate
{
[self logError:@"This method is unsupported. Returning nil." cmd:_cmd];
return nil;
}
- (NSDictionary *)launchOptions
{
return _launchOptions;
}
- (BOOL)loading
{
[self logWarning:@"This method is not implemented. Returning NO." cmd:_cmd];
return NO;
}
- (BOOL)valid
{
[self logWarning:@"This method is not implemented. Returning NO." cmd:_cmd];
return NO;
}
- (RCTPerformanceLogger *)performanceLogger
{
[self logWarning:@"This method is not supported. Returning nil." cmd:_cmd];
return nil;
}
- (void)reload
{
[self logError:@"Please use RCTReloadCommand instead. Nooping." cmd:_cmd];
}
- (void)reloadWithReason:(NSString *)reason
{
[self logError:@"Please use RCTReloadCommand instead. Nooping." cmd:_cmd];
}
- (void)onFastRefresh
{
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeFastRefreshNotification object:self];
}
- (void)requestReload __deprecated_msg("Use RCTReloadCommand instead")
{
[self logError:@"Please use RCTReloadCommand instead. Nooping." cmd:_cmd];
}
- (BOOL)isBatchActive
{
[self logWarning:@"This method is not supported. Returning NO." cmd:_cmd];
return NO;
}
/**
* RCTBridge ()
*/
- (NSString *)bridgeDescription
{
[self logWarning:@"This method is not supported. Returning \"BridgeProxy\"." cmd:_cmd];
return @"BridgeProxy";
}
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args
{
[self logError:@"This method is not supported. No-oping." cmd:_cmd];
}
- (RCTBridge *)batchedBridge
{
[self logWarning:@"This method is not supported. Returning bridge proxy." cmd:_cmd];
return (RCTBridge *)self;
}
- (void)setBatchedBridge
{
[self logError:@"This method is not supported. No-oping." cmd:_cmd];
}
- (RCTBridgeModuleListProvider)moduleProvider
{
[self logWarning:@"This method is not supported. Returning empty block" cmd:_cmd];
return ^{
return @[];
};
}
- (RCTModuleRegistry *)moduleRegistry
{
return _moduleRegistry;
}
/**
* RCTBridge (RCTCxxBridge)
*/
- (RCTBridge *)parentBridge
{
[self logWarning:@"This method is not supported. Returning bridge proxy." cmd:_cmd];
return (RCTBridge *)self;
}
- (BOOL)moduleSetupComplete
{
[self logWarning:@"This method is not supported. Returning YES." cmd:_cmd];
return YES;
}
- (void)start
{
[self
logError:
@"Starting the bridge proxy does nothing. If you want to start React Native, please use RCTHost start. Nooping"
cmd:_cmd];
}
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData
{
[self logError:@"This method is not supported. Nooping" cmd:_cmd];
}
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName
{
[self logError:@"This method is not supported. Returning nil." cmd:_cmd];
return nil;
}
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)newModules
{
[self
logError:
@"This API is unsupported. Please return all module classes from your app's RCTTurboModuleManagerDelegate getModuleClassFromName:. Nooping."
cmd:_cmd];
}
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance
{
[self logError:@"This method is not supported. Nooping." cmd:_cmd];
}
- (void)startProfiling
{
[self logWarning:@"This method is not supported. Nooping." cmd:_cmd];
}
- (void)stopProfiling:(void (^)(NSData *))callback
{
[self logWarning:@"This method is not supported. Nooping." cmd:_cmd];
}
- (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(NSArray *)params
{
[self logError:@"This method is not supported. Nooping and returning nil." cmd:_cmd];
return nil;
}
- (void)logMessage:(NSString *)message level:(NSString *)level
{
[self logWarning:@"This method is not supported. Nooping." cmd:_cmd];
}
- (void)_immediatelyCallTimer:(NSNumber *)timer
{
[self logWarning:@"This method is not supported. Nooping." cmd:_cmd];
}
/**
* RCTBridge (Inspector)
*/
- (BOOL)inspectable
{
[self logWarning:@"This method is not supported. Returning NO." cmd:_cmd];
return NO;
}
/**
* RCTBridge (RCTUIManager)
*/
- (RCTUIManager *)uiManager
{
return (RCTUIManager *)_uiManagerProxy;
}
- (RCTBridgeProxy *)object
{
return self;
}
/**
* NSProxy setup
*/
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
{
return [RCTCxxBridge instanceMethodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
[self logError:@"This method is unsupported." cmd:invocation.selector];
}
/**
* Logging
* TODO(155977839): Add a means to configure/disable these logs, so people do not ignore all LogBoxes
*/
- (void)logWarning:(NSString *)message cmd:(SEL)cmd
{
if (RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelWarning) {
RCTLogWarn(@"RCTBridgeProxy: Calling [bridge %@]. %@", NSStringFromSelector(cmd), message);
}
}
- (void)logError:(NSString *)message cmd:(SEL)cmd
{
if (RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelWarning ||
RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelError) {
RCTLogError(@"RCTBridgeProxy: Calling [bridge %@]. %@", NSStringFromSelector(cmd), message);
}
}
@end
@implementation RCTUIManagerProxy {
RCTViewRegistry *_viewRegistry;
NSMutableDictionary<NSNumber *, UIView *> *_legacyViewRegistry;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
{
self = [super self];
if (self != nullptr) {
_viewRegistry = viewRegistry;
_legacyViewRegistry = [NSMutableDictionary new];
}
return self;
}
#pragma clang diagnostic pop
/**
* RCTViewRegistry
*/
- (UIView *)viewForReactTag:(NSNumber *)reactTag
{
[self logWarning:@"Please migrate to RCTViewRegistry: @synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED."
cmd:_cmd];
UIView *view = ([_viewRegistry viewForReactTag:reactTag] != nullptr) ? [_viewRegistry viewForReactTag:reactTag]
: [_legacyViewRegistry objectForKey:reactTag];
return RCTPaperViewOrCurrentView(view);
}
- (void)addUIBlock:(RCTViewManagerUIBlock)block
{
[self
logWarning:
@"This method isn't implemented faithfully. Please migrate to RCTViewRegistry if possible: @synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED."
cmd:_cmd];
__weak __typeof(self) weakSelf = self;
RCTExecuteOnMainQueue(^{
__typeof(self) strongSelf = weakSelf;
if (strongSelf != nullptr) {
RCTUIManager *proxiedManager = (RCTUIManager *)strongSelf;
RCTComposedViewRegistry *composedViewRegistry =
[[RCTComposedViewRegistry alloc] initWithUIManager:proxiedManager
andRegistry:strongSelf->_legacyViewRegistry];
block(proxiedManager, composedViewRegistry);
}
});
}
/**
* NSProxy setup
*/
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
return [RCTUIManager instanceMethodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
[self logError:@"This method is unsupported." cmd:invocation.selector];
}
/**
* Logging
* TODO(155977839): Add a means to configure/disable these logs, so people do not ignore all LogBoxes
*/
- (void)logWarning:(NSString *)message cmd:(SEL)cmd
{
if (RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelWarning) {
RCTLogWarn(
@"RCTBridgeProxy (RCTUIManagerProxy): Calling [bridge.uiManager %@]. %@", NSStringFromSelector(cmd), message);
}
}
- (void)logError:(NSString *)message cmd:(SEL)cmd
{
if (RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelWarning ||
RCTTurboModuleInteropBridgeProxyLogLevel() == kRCTBridgeProxyLoggingLevelError) {
RCTLogError(
@"RCTBridgeProxy (RCTUIManagerProxy): Calling [bridge.uiManager %@]. %@", NSStringFromSelector(cmd), message);
}
}
@end

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTBridge;
typedef NSURL * (^RCTBridgelessBundleURLGetter)(void);
typedef void (^RCTBridgelessBundleURLSetter)(NSURL *bundleURL);
/**
* A class that allows NativeModules/TurboModules to read/write the bundleURL, with or without the bridge.
*/
@interface RCTBundleManager : NSObject
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter
andSetter:(RCTBridgelessBundleURLSetter)setter
andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter;
- (void)resetBundleURL;
@property NSURL *bundleURL;
@end

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBundleManager.h"
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
@implementation RCTBundleManager {
#ifndef RCT_REMOVE_LEGACY_ARCH
__weak RCTBridge *_bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
RCTBridgelessBundleURLGetter _bridgelessBundleURLGetter;
RCTBridgelessBundleURLSetter _bridgelessBundleURLSetter;
RCTBridgelessBundleURLGetter _bridgelessBundleURLDefaultGetter;
}
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
}
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter
andSetter:(RCTBridgelessBundleURLSetter)setter
andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter
{
_bridgelessBundleURLGetter = getter;
_bridgelessBundleURLSetter = setter;
_bridgelessBundleURLDefaultGetter = defaultGetter;
}
- (void)setBundleURL:(NSURL *)bundleURL
{
#ifndef RCT_REMOVE_LEGACY_ARCH
if (_bridge) {
_bridge.bundleURL = bundleURL;
return;
}
#endif // RCT_REMOVE_LEGACY_ARCH
RCTAssert(
_bridgelessBundleURLSetter != nil,
@"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLSetter must not be nil.");
_bridgelessBundleURLSetter(bundleURL);
}
- (NSURL *)bundleURL
{
#ifndef RCT_REMOVE_LEGACY_ARCH
if (_bridge) {
return _bridge.bundleURL;
}
#endif // RCT_REMOVE_LEGACY_ARCH
RCTAssert(
_bridgelessBundleURLGetter != nil,
@"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLGetter must not be nil.");
return _bridgelessBundleURLGetter();
}
- (void)resetBundleURL
{
#ifndef RCT_REMOVE_LEGACY_ARCH
RCTBridge *strongBridge = _bridge;
if (strongBridge) {
strongBridge.bundleURL = [strongBridge.delegate sourceURLForBridge:strongBridge];
return;
}
#endif // RCT_REMOVE_LEGACY_ARCH
RCTAssert(
_bridgelessBundleURLDefaultGetter != nil,
@"RCTBundleManager: In bridgeless mode, default RCTBridgelessBundleURLGetter must not be nil.");
RCTAssert(
_bridgelessBundleURLSetter != nil,
@"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLSetter must not be nil.");
_bridgelessBundleURLSetter(_bridgelessBundleURLDefaultGetter());
}
@end

View File

@@ -0,0 +1,186 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import "RCTDefines.h"
RCT_EXTERN NSString *_Nonnull const RCTBundleURLProviderUpdatedNotification;
RCT_EXTERN const NSUInteger kRCTBundleURLProviderDefaultPort;
#if RCT_DEV_MENU | RCT_PACKAGER_LOADING_FUNCTIONALITY
/**
* Allow/disallow accessing the packager server for various runtime scenario.
* For instance, if a test run should never access the packager, disable it
* by calling this function before initializing React Native (RCTBridge etc).
* By default the access is enabled.
*/
RCT_EXTERN void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed);
#endif
NS_ASSUME_NONNULL_BEGIN
@interface RCTBundleURLProvider : NSObject
/**
* Reset every settings to default.
*/
- (void)resetToDefaults;
/**
* Return the server host. If its a development build and there's no jsLocation defined,
* it will return the server host IP address
*/
- (NSString *)packagerServerHost;
/**
* Return the server host with optional port. If its a development build and there's no jsLocation defined,
* it will return the server host IP address
*/
- (NSString *)packagerServerHostPort;
/**
* Returns if there's a packager running at the given host port.
* The port is optional, if not specified, kRCTBundleURLProviderDefaultPort will be used
*/
+ (BOOL)isPackagerRunning:(NSString *)hostPort;
/**
* Returns if there's a packager running at the given scheme://host:port.
* The port is optional, if not specified, kRCTBundleURLProviderDefaultPort will be used
* The scheme is also optional, if not specified, a default http protocol will be used
*/
+ (BOOL)isPackagerRunning:(NSString *)hostPort scheme:(NSString *__nullable)scheme;
/**
* Returns the jsBundleURL for a given bundle entrypoint and
* the fallback offline JS bundle if the packager is not running.
*/
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
fallbackURLProvider:(NSURL *__nullable (^)(void))fallbackURLProvider;
/**
* Returns the jsBundleURL for a given split bundle entrypoint in development
*/
- (NSURL *__nullable)jsBundleURLForSplitBundleRoot:(NSString *)bundleRoot;
/**
* Returns the jsBundleURL for a given bundle entrypoint and
* the fallback offline JS bundle if the packager is not running.
* if extension is nil, "jsbundle" will be used.
*/
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackExtension:(NSString *__nullable)extension;
/**
* Returns the jsBundleURL for a given bundle entrypoint and
* the fallback offline JS bundle if the packager is not running.
*/
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot;
/**
* Returns the jsBundleURL for a given bundle entrypoint and
* the fallback offline JS bundle. If extension is nil,
* "jsbundle" will be used.
*/
- (NSURL *__nullable)jsBundleURLForFallbackExtension:(NSString *__nullable)extension;
/**
* Returns the resourceURL for a given bundle entrypoint and
* the fallback offline resource file if the packager is not running.
*/
- (NSURL *__nullable)resourceURLForResourceRoot:(NSString *)root
resourceName:(NSString *)name
resourceExtension:(NSString *)extension
offlineBundle:(NSBundle *)offlineBundle;
/**
* The IP address or hostname of the packager.
*/
@property (nonatomic, copy, nullable) NSString *jsLocation;
@property (nonatomic, assign) BOOL enableMinification;
@property (nonatomic, assign) BOOL enableDev;
@property (nonatomic, assign) BOOL inlineSourceMap;
/**
* The scheme/protocol used of the packager, the default is the http protocol
*/
@property (nonatomic, copy) NSString *packagerScheme;
+ (instancetype)sharedSettings;
/**
* Given a hostname for the packager and a bundle root, returns the URL to the js bundle. Generally you should use the
* instance method -jsBundleURLForBundleRoot:fallbackExtension: which includes logic to guess if the packager is running
* and fall back to a pre-packaged bundle if it is not.
*
* The options here mirror some of Metro's Bundling Options:
* - enableDev: Whether to keep or remove `__DEV__` blocks from the bundle.
* - enableMinification: Enables or disables minification. Usually production bundles are minified and development
* bundles are not.
* - inlineSourceMap: When true, the bundler will inline the source map in the bundle
* - modulesOnly: When true, will only send module definitions without polyfills and without the require-runtime.
* - runModule: When true, will run the main module after defining all modules. This is used in the main bundle but not
* in split bundles.
* - additionalOptions: A dictionary of name-value pairs of additional options to pass to the packager.
*/
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap;
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
additionalOptions:(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions;
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
packagerScheme:(NSString *__nullable)scheme
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
modulesOnly:(BOOL)modulesOnly
runModule:(BOOL)runModule;
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(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;
/**
* Given a hostname for the packager and a resource path (including "/"), return the URL to the resource.
* In general, please use the instance method to decide if the packager is running and fallback to the pre-packaged
* resource if it is not: -resourceURLForResourceRoot:resourceName:resourceExtension:offlineBundle:
*/
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
packagerHost:(NSString *)packagerHost
scheme:(NSString *__nullable)scheme
query:(NSString *__nullable)query
__deprecated_msg("Use version with queryItems parameter instead");
/**
* Given a hostname for the packager and a resource path (including "/"), return the URL to the resource.
* In general, please use the instance method to decide if the packager is running and fallback to the pre-packaged
* resource if it is not: -resourceURLForResourceRoot:resourceName:resourceExtension:offlineBundle:
*/
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
packagerHost:(NSString *)packagerHost
scheme:(NSString *)scheme
queryItems:(NSArray<NSURLQueryItem *> *__nullable)queryItems;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,460 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBundleURLProvider.h"
#import "RCTConstants.h"
#import "RCTConvert.h"
#import "RCTDefines.h"
#import "RCTLog.h"
#import <jsinspector-modern/InspectorFlags.h>
NSString *const RCTBundleURLProviderUpdatedNotification = @"RCTBundleURLProviderUpdatedNotification";
const NSUInteger kRCTBundleURLProviderDefaultPort = RCT_METRO_PORT;
#if RCT_DEV | RCT_PACKAGER_LOADING_FUNCTIONALITY
static BOOL kRCTAllowPackagerAccess = YES;
void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed)
{
kRCTAllowPackagerAccess = allowed;
}
#endif
static NSString *const kRCTPackagerSchemeKey = @"RCT_packager_scheme";
static NSString *const kRCTJsLocationKey = @"RCT_jsLocation";
static NSString *const kRCTEnableDevKey = @"RCT_enableDev";
static NSString *const kRCTEnableMinificationKey = @"RCT_enableMinification";
static NSString *const kRCTInlineSourceMapKey = @"RCT_inlineSourceMap";
@implementation RCTBundleURLProvider
- (instancetype)init
{
self = [super init];
if (self) {
[self _setDefaults];
}
return self;
}
- (NSDictionary *)defaults
{
return @{
kRCTEnableDevKey : @YES,
kRCTEnableMinificationKey : @NO,
};
}
- (void)settingsUpdated
{
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBundleURLProviderUpdatedNotification object:self];
}
- (void)resetToDefaults
{
for (NSString *key in [[self defaults] allKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
[self _setDefaults];
[self settingsUpdated];
}
static NSURL *serverRootWithHostPort(NSString *hostPort, NSString *scheme)
{
if (![scheme length]) {
scheme = @"http";
}
if ([hostPort rangeOfString:@":"].location != NSNotFound) {
return [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/", scheme, hostPort]];
}
return [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@:%lu/",
scheme,
hostPort,
(unsigned long)kRCTBundleURLProviderDefaultPort]];
}
#if RCT_DEV | RCT_PACKAGER_LOADING_FUNCTIONALITY
+ (BOOL)isPackagerRunning:(NSString *)hostPort
{
return [RCTBundleURLProvider isPackagerRunning:hostPort scheme:nil];
}
+ (BOOL)isPackagerRunning:(NSString *)hostPort scheme:(NSString *)scheme
{
if (!kRCTAllowPackagerAccess) {
return NO;
}
NSURL *url = [serverRootWithHostPort(hostPort, scheme) URLByAppendingPathComponent:@"status"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10];
__block NSURLResponse *response;
__block NSData *data;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[[session dataTaskWithRequest:request
completionHandler:^(NSData *d, NSURLResponse *res, __unused NSError *err) {
data = d;
response = res;
dispatch_semaphore_signal(semaphore);
}] resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSString *status = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return [status isEqualToString:@"packager-status:running"];
}
- (NSString *)guessPackagerHost
{
static NSString *ipGuess;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *ipPath = [[NSBundle mainBundle] pathForResource:@"ip" ofType:@"txt"];
ipGuess =
[[NSString stringWithContentsOfFile:ipPath encoding:NSUTF8StringEncoding
error:nil] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
});
NSString *host = ipGuess ?: @"localhost";
if ([RCTBundleURLProvider isPackagerRunning:host]) {
return host;
}
return nil;
}
#else
+ (BOOL)isPackagerRunning:(NSString *)hostPort
{
return false;
}
+ (BOOL)isPackagerRunning:(NSString *)hostPort scheme:(NSString *)scheme
{
return false;
}
#endif
- (NSString *)packagerServerHost
{
NSString *location = [self packagerServerHostPort];
if (location) {
NSInteger index = [location rangeOfString:@":"].location;
if (index != NSNotFound) {
location = [location substringToIndex:index];
}
}
return location;
}
- (NSString *)packagerServerHostPort
{
#if RCT_DEV | RCT_PACKAGER_LOADING_FUNCTIONALITY
if (!kRCTAllowPackagerAccess) {
RCTLogInfo(@"Packager server access is disabled in this environment");
return nil;
}
#endif
NSString *location = [self jsLocation];
#if RCT_DEV
NSString *scheme = [self packagerScheme];
if ([location length] && ![RCTBundleURLProvider isPackagerRunning:location scheme:scheme]) {
location = nil;
}
#endif
if (location != nil) {
return location;
}
#if RCT_DEV
NSString *host = [self guessPackagerHost];
if (host) {
return host;
}
#endif
return nil;
}
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackURLProvider:(NSURL * (^)(void))fallbackURLProvider
{
NSString *packagerServerHostPort = [self packagerServerHostPort];
if (!packagerServerHostPort) {
return fallbackURLProvider();
} else {
return [RCTBundleURLProvider jsBundleURLForBundleRoot:bundleRoot
packagerHost:packagerServerHostPort
packagerScheme:[self packagerScheme]
enableDev:[self enableDev]
enableMinification:[self enableMinification]
inlineSourceMap:[self inlineSourceMap]
modulesOnly:NO
runModule:YES];
}
}
- (NSURL *)jsBundleURLForSplitBundleRoot:(NSString *)bundleRoot
{
return [RCTBundleURLProvider jsBundleURLForBundleRoot:bundleRoot
packagerHost:[self packagerServerHostPort]
packagerScheme:[self packagerScheme]
enableDev:[self enableDev]
enableMinification:[self enableMinification]
inlineSourceMap:[self inlineSourceMap]
modulesOnly:YES
runModule:NO];
}
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackExtension:(NSString *)extension
{
return [self jsBundleURLForBundleRoot:bundleRoot
fallbackURLProvider:^NSURL * {
return [self jsBundleURLForFallbackExtension:extension];
}];
}
- (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
{
return [self jsBundleURLForBundleRoot:bundleRoot fallbackExtension:nil];
}
- (NSURL *)jsBundleURLForFallbackExtension:(NSString *)extension
{
extension = extension ?: @"jsbundle";
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:extension];
}
- (NSURL *)resourceURLForResourceRoot:(NSString *)root
resourceName:(NSString *)name
resourceExtension:(NSString *)extension
offlineBundle:(NSBundle *)offlineBundle
{
NSString *packagerServerHostPort = [self packagerServerHostPort];
NSString *packagerServerScheme = [self packagerScheme];
if (!packagerServerHostPort) {
// Serve offline bundle (local file)
NSBundle *bundle = offlineBundle ?: [NSBundle mainBundle];
return [bundle URLForResource:name withExtension:extension];
}
NSString *path = [NSString stringWithFormat:@"/%@/%@.%@", root, name, extension];
return [[self class] resourceURLForResourcePath:path
packagerHost:packagerServerHostPort
scheme:packagerServerScheme
queryItems:nil];
}
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
{
return [self jsBundleURLForBundleRoot:bundleRoot
packagerHost:packagerHost
packagerScheme:nil
enableDev:enableDev
enableMinification:enableMinification
inlineSourceMap:inlineSourceMap
modulesOnly:NO
runModule:YES
additionalOptions:nil];
}
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
additionalOptions:(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions
{
return [self jsBundleURLForBundleRoot:bundleRoot
packagerHost:packagerHost
packagerScheme:nil
enableDev:enableDev
enableMinification:enableMinification
inlineSourceMap:inlineSourceMap
modulesOnly:NO
runModule:YES
additionalOptions:additionalOptions];
}
+ (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(NSString *)packagerHost
packagerScheme:(NSString *)scheme
enableDev:(BOOL)enableDev
enableMinification:(BOOL)enableMinification
inlineSourceMap:(BOOL)inlineSourceMap
modulesOnly:(BOOL)modulesOnly
runModule:(BOOL)runModule
{
return [self jsBundleURLForBundleRoot:bundleRoot
packagerHost:packagerHost
packagerScheme:nil
enableDev:enableDev
enableMinification:enableMinification
inlineSourceMap:inlineSourceMap
modulesOnly:modulesOnly
runModule:runModule
additionalOptions:nil];
}
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
packagerHost:(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
{
NSString *path = [NSString stringWithFormat:@"/%@.bundle", bundleRoot];
BOOL lazy = enableDev;
NSMutableArray<NSURLQueryItem *> *queryItems = [[NSMutableArray alloc] initWithArray:@[
[[NSURLQueryItem alloc] initWithName:@"platform" value:RCTPlatformName],
[[NSURLQueryItem alloc] initWithName:@"dev" value:enableDev ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"lazy" value:lazy ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"minify" value:enableMinification ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"inlineSourceMap" value:inlineSourceMap ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"modulesOnly" value:modulesOnly ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"runModule" value:runModule ? @"true" : @"false"],
]];
auto &inspectorFlags = facebook::react::jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getFuseboxEnabled()) {
[queryItems addObject:[[NSURLQueryItem alloc] initWithName:@"excludeSource" value:@"true"]];
[queryItems addObject:[[NSURLQueryItem alloc] initWithName:@"sourcePaths" value:@"url-server"]];
}
NSString *bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleIdentifierKey];
if (bundleID) {
[queryItems addObject:[[NSURLQueryItem alloc] initWithName:@"app" value:bundleID]];
}
if (additionalOptions) {
for (NSString *key in additionalOptions) {
NSString *value = [additionalOptions objectForKey:key];
if (!value) {
NSLog(@"RCTBundleURLProvider: Ignoring the additional option: '%@' due to nil value.", key);
continue;
}
[queryItems addObject:[[NSURLQueryItem alloc] initWithName:key value:value]];
}
}
return [[self class] resourceURLForResourcePath:path
packagerHost:packagerHost
scheme:scheme
queryItems:[queryItems copy]];
}
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
packagerHost:(NSString *)packagerHost
scheme:(NSString *)scheme
query:(NSString *)query
{
NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHostPort(packagerHost, scheme)
resolvingAgainstBaseURL:NO];
components.path = path;
if (query != nil) {
components.query = query;
}
return components.URL;
}
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
packagerHost:(NSString *)packagerHost
scheme:(NSString *)scheme
queryItems:(NSArray<NSURLQueryItem *> *)queryItems
{
NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHostPort(packagerHost, scheme)
resolvingAgainstBaseURL:NO];
components.path = path;
if (queryItems != nil) {
components.queryItems = queryItems;
}
return components.URL;
}
- (void)updateValue:(id)object forKey:(NSString *)key
{
[[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
[self settingsUpdated];
}
- (BOOL)enableDev
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableDevKey];
}
- (BOOL)enableMinification
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableMinificationKey];
}
- (BOOL)inlineSourceMap
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTInlineSourceMapKey];
}
- (NSString *)jsLocation
{
return [[NSUserDefaults standardUserDefaults] stringForKey:kRCTJsLocationKey];
}
- (NSString *)packagerScheme
{
NSString *packagerScheme = [[NSUserDefaults standardUserDefaults] stringForKey:kRCTPackagerSchemeKey];
if (![packagerScheme length]) {
return @"http";
}
return packagerScheme;
}
- (void)setEnableDev:(BOOL)enableDev
{
[self updateValue:@(enableDev) forKey:kRCTEnableDevKey];
}
- (void)setJsLocation:(NSString *)jsLocation
{
[self updateValue:jsLocation forKey:kRCTJsLocationKey];
}
- (void)setEnableMinification:(BOOL)enableMinification
{
[self updateValue:@(enableMinification) forKey:kRCTEnableMinificationKey];
}
- (void)setInlineSourceMap:(BOOL)inlineSourceMap
{
[self updateValue:@(inlineSourceMap) forKey:kRCTInlineSourceMapKey];
}
- (void)setPackagerScheme:(NSString *)packagerScheme
{
[self updateValue:packagerScheme forKey:kRCTPackagerSchemeKey];
}
+ (instancetype)sharedSettings
{
static RCTBundleURLProvider *sharedInstance;
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
sharedInstance = [RCTBundleURLProvider new];
});
return sharedInstance;
}
#pragma mark - Private helpers
- (void)_setDefaults
{
[[NSUserDefaults standardUserDefaults] registerDefaults:[self defaults]];
}
@end

27
node_modules/react-native/React/Base/RCTCallInvoker.h generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <ReactCommon/CallInvoker.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@interface RCTCallInvoker : NSObject
#ifdef __cplusplus
- (instancetype)initWithCallInvoker:(std::shared_ptr<facebook::react::CallInvoker>)callInvoker
NS_DESIGNATED_INITIALIZER;
- (std::shared_ptr<facebook::react::CallInvoker>)callInvoker;
#endif
@end
NS_ASSUME_NONNULL_END

33
node_modules/react-native/React/Base/RCTCallInvoker.mm generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTCallInvoker.h"
@implementation RCTCallInvoker {
std::shared_ptr<facebook::react::CallInvoker> _callInvoker;
}
- (instancetype)init
{
return [self initWithCallInvoker:nullptr];
}
- (instancetype)initWithCallInvoker:(std::shared_ptr<facebook::react::CallInvoker>)callInvoker
{
if (self = [super init]) {
_callInvoker = callInvoker;
}
return self;
}
- (std::shared_ptr<facebook::react::CallInvoker>)callInvoker
{
return _callInvoker;
}
@end

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTCallInvoker;
/**
* Have your module conform to this protocol to access the CallInvoker.
*/
@protocol RCTCallInvokerModule <NSObject>
@property (nonatomic, nullable, readwrite) RCTCallInvoker *callInvoker;
@end

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridge.h"
#import "RCTBridgeModule.h"
@implementation RCTCallableJSModules {
RCTBridgelessJSModuleMethodInvoker _bridgelessJSModuleMethodInvoker;
#ifndef RCT_REMOVE_LEGACY_ARCH
__weak RCTBridge *_bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
}
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
}
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker
{
_bridgelessJSModuleMethodInvoker = bridgelessJSModuleMethodInvoker;
}
- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args
{
[self invokeModule:moduleName method:methodName withArgs:args onComplete:NULL];
}
- (void)invokeModule:(NSString *)moduleName
method:(NSString *)methodName
withArgs:(NSArray *)args
onComplete:(dispatch_block_t)onComplete
{
#ifndef RCT_REMOVE_LEGACY_ARCH
RCTBridge *bridge = _bridge;
if (bridge) {
[bridge enqueueJSCall:moduleName method:methodName args:args completion:onComplete];
return;
}
#endif // RCT_REMOVE_LEGACY_ARCH
if (_bridgelessJSModuleMethodInvoker) {
_bridgelessJSModuleMethodInvoker(moduleName, methodName, args, onComplete);
}
}
@end

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTEventDispatcherProtocol.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Generic untyped event for Components. Used internally by RCTDirectEventBlock and
* RCTBubblingEventBlock, for other use cases prefer using a class that implements
* RCTEvent to have a type safe way to initialize it.
*/
@interface RCTComponentEvent : NSObject <RCTEvent>
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag body:(NSDictionary *)body;
NS_ASSUME_NONNULL_END
@end

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTComponentEvent.h"
#import "RCTAssert.h"
@implementation RCTComponentEvent {
NSArray *_arguments;
}
@synthesize eventName = _eventName;
@synthesize viewTag = _viewTag;
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag body:(NSDictionary *)body
{
if (self = [super init]) {
NSMutableDictionary *mutableBody = [NSMutableDictionary dictionaryWithDictionary:body];
mutableBody[@"target"] = viewTag;
_eventName = RCTNormalizeInputEventName(name);
_viewTag = viewTag;
_arguments = @[ _viewTag, _eventName, mutableBody ];
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (NSArray *)arguments
{
return _arguments;
}
- (BOOL)canCoalesce
{
return NO;
}
+ (NSString *)moduleDotMethod
{
return @"RCTEventEmitter.receiveEvent";
}
@end

52
node_modules/react-native/React/Base/RCTConstants.h generated vendored Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
RCT_EXTERN NSString *const RCTPlatformName;
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;
RCT_EXTERN NSString *const RCTWindowFrameDidChangeNotification;
RCT_EXTERN NSString *const RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED;
/**
* This notification fires when the bridge initializes.
*/
RCT_EXTERN NSString *const RCTJavaScriptWillStartLoadingNotification;
/**
* This notification fires when the bridge starts executing the JS bundle.
*/
RCT_EXTERN NSString *const RCTJavaScriptWillStartExecutingNotification;
/**
* This notification fires when the bridge has finished loading the JS bundle.
*/
RCT_EXTERN NSString *const RCTJavaScriptDidLoadNotification;
/**
* This notification fires when the bridge failed to load the JS bundle. The
* `error` key can be used to determine the error that occurred.
*/
RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification;
/**
* This notification fires each time a native module is instantiated. The
* `module` key will contain a reference to the newly-created module instance.
* Note that this notification may be fired before the module is available via
* the `[bridge moduleForClass:]` method.
*/
RCT_EXTERN NSString *const RCTDidInitializeModuleNotification;
/*
* W3C Pointer Events
*/
RCT_EXTERN BOOL RCTGetDispatchW3CPointerEvents(void);
RCT_EXTERN void RCTSetDispatchW3CPointerEvents(BOOL value);

40
node_modules/react-native/React/Base/RCTConstants.m generated vendored Normal file
View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTConstants.h"
NSString *const RCTPlatformName = @"ios";
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey = @"traitCollection";
NSString *const RCTWindowFrameDidChangeNotification = @"RCTWindowFrameDidChangeNotification";
NSString *const RCTJavaScriptDidFailToLoadNotification = @"RCTJavaScriptDidFailToLoadNotification";
NSString *const RCTJavaScriptDidLoadNotification = @"RCTJavaScriptDidLoadNotification";
NSString *const RCTJavaScriptWillStartExecutingNotification = @"RCTJavaScriptWillStartExecutingNotification";
NSString *const RCTJavaScriptWillStartLoadingNotification = @"RCTJavaScriptWillStartLoadingNotification";
NSString *const RCTDidInitializeModuleNotification = @"RCTDidInitializeModuleNotification";
NSString *const RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED =
@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED";
/*
* W3C Pointer Events
*/
static BOOL RCTDispatchW3CPointerEvents = NO;
BOOL RCTGetDispatchW3CPointerEvents(void)
{
return RCTDispatchW3CPointerEvents;
}
void RCTSetDispatchW3CPointerEvents(BOOL value)
{
RCTDispatchW3CPointerEvents = value;
}

284
node_modules/react-native/React/Base/RCTConvert.h generated vendored Normal file
View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <React/RCTAnimationType.h>
#import <React/RCTBorderCurve.h>
#import <React/RCTBorderStyle.h>
#import <React/RCTCursor.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
#import <React/RCTPointerEvents.h>
#import <React/RCTTextDecorationLineType.h>
#import <yoga/Yoga.h>
typedef NS_ENUM(NSInteger, RCTColorSpace) {
RCTColorSpaceSRGB,
RCTColorSpaceDisplayP3,
};
// Change the default color space
RCTColorSpace RCTGetDefaultColorSpace(void);
RCT_EXTERN void RCTSetDefaultColorSpace(RCTColorSpace colorSpace);
/**
* This class provides a collection of conversion functions for mapping
* JSON objects to native types and classes. These are useful when writing
* custom RCTViewManager setter methods.
*/
@interface RCTConvert : NSObject
+ (id)id:(id)json;
+ (BOOL)BOOL:(id)json;
+ (double)double:(id)json;
+ (float)float:(id)json;
+ (int)int:(id)json;
+ (int64_t)int64_t:(id)json;
+ (uint64_t)uint64_t:(id)json;
+ (NSInteger)NSInteger:(id)json;
+ (NSUInteger)NSUInteger:(id)json;
+ (NSArray *)NSArray:(id)json;
+ (NSDictionary *)NSDictionary:(id)json;
+ (NSString *)NSString:(id)json;
+ (NSNumber *)NSNumber:(id)json;
+ (NSSet *)NSSet:(id)json;
+ (NSData *)NSData:(id)json;
+ (NSIndexSet *)NSIndexSet:(id)json;
+ (NSURLRequestCachePolicy)NSURLRequestCachePolicy:(id)json;
+ (NSURL *)NSURL:(id)json;
+ (NSURLRequest *)NSURLRequest:(id)json;
typedef NSURL RCTFileURL;
+ (RCTFileURL *)RCTFileURL:(id)json;
+ (NSDate *)NSDate:(id)json;
+ (NSLocale *)NSLocale:(id)json;
+ (NSTimeZone *)NSTimeZone:(id)json;
+ (NSTimeInterval)NSTimeInterval:(id)json;
+ (NSLineBreakMode)NSLineBreakMode:(id)json;
+ (NSTextAlignment)NSTextAlignment:(id)json;
+ (NSUnderlineStyle)NSUnderlineStyle:(id)json;
+ (NSWritingDirection)NSWritingDirection:(id)json;
+ (NSLineBreakStrategy)NSLineBreakStrategy:(id)json;
+ (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
+ (UITextFieldViewMode)UITextFieldViewMode:(id)json;
+ (UIKeyboardType)UIKeyboardType:(id)json;
+ (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
+ (UIUserInterfaceStyle)UIUserInterfaceStyle:(id)json API_AVAILABLE(ios(12));
+ (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(NSString *)orientation;
+ (UIModalPresentationStyle)UIModalPresentationStyle:(id)json;
#if !TARGET_OS_TV
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
#endif
+ (UIViewContentMode)UIViewContentMode:(id)json;
+ (RCTCursor)RCTCursor:(id)json;
+ (CGFloat)CGFloat:(id)json;
+ (CGPoint)CGPoint:(id)json;
+ (CGSize)CGSize:(id)json;
+ (CGRect)CGRect:(id)json;
+ (UIEdgeInsets)UIEdgeInsets:(id)json;
+ (CGLineCap)CGLineCap:(id)json;
+ (CGLineJoin)CGLineJoin:(id)json;
+ (CGAffineTransform)CGAffineTransform:(id)json;
+ (UIColor *)UIColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
+ (UIColor *)UIColorWithRed:(CGFloat)red
green:(CGFloat)green
blue:(CGFloat)blue
alpha:(CGFloat)alpha
andColorSpace:(RCTColorSpace)colorSpace;
+ (RCTColorSpace)RCTColorSpaceFromString:(NSString *)colorSpace;
+ (UIColor *)UIColor:(id)json;
+ (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
+ (YGValue)YGValue:(id)json;
+ (NSArray<NSArray *> *)NSArrayArray:(id)json;
+ (NSArray<NSString *> *)NSStringArray:(id)json;
+ (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
+ (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
+ (NSArray<NSURL *> *)NSURLArray:(id)json;
+ (NSArray<RCTFileURL *> *)RCTFileURLArray:(id)json;
+ (NSArray<NSNumber *> *)NSNumberArray:(id)json;
+ (NSArray<UIColor *> *)UIColorArray:(id)json;
typedef NSArray CGColorArray;
+ (CGColorArray *)CGColorArray:(id)json;
/**
* Convert a JSON object to a Plist-safe equivalent by stripping null values.
*/
typedef id NSPropertyList;
+ (NSPropertyList)NSPropertyList:(id)json;
typedef BOOL css_backface_visibility_t;
+ (YGOverflow)YGOverflow:(id)json;
+ (YGDisplay)YGDisplay:(id)json;
+ (css_backface_visibility_t)css_backface_visibility_t:(id)json;
+ (YGFlexDirection)YGFlexDirection:(id)json;
+ (YGJustify)YGJustify:(id)json;
+ (YGAlign)YGAlign:(id)json;
+ (YGPositionType)YGPositionType:(id)json;
+ (YGWrap)YGWrap:(id)json;
+ (YGDirection)YGDirection:(id)json;
+ (RCTPointerEvents)RCTPointerEvents:(id)json;
+ (RCTAnimationType)RCTAnimationType:(id)json;
+ (RCTBorderStyle)RCTBorderStyle:(id)json;
+ (RCTBorderCurve)RCTBorderCurve:(id)json;
+ (RCTTextDecorationLineType)RCTTextDecorationLineType:(id)json;
@end
@interface RCTConvert (Deprecated)
/**
* Use lightweight generics syntax instead, e.g. NSArray<NSString *>
*/
typedef NSArray NSArrayArray __deprecated_msg("Use NSArray<NSArray *>");
typedef NSArray NSStringArray __deprecated_msg("Use NSArray<NSString *>");
typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray<NSArray<NSString *> *>");
typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray<NSDictionary *>");
typedef NSArray NSURLArray __deprecated_msg("Use NSArray<NSURL *>");
typedef NSArray RCTFileURLArray __deprecated_msg("Use NSArray<RCTFileURL *>");
typedef NSArray NSNumberArray __deprecated_msg("Use NSArray<NSNumber *>");
typedef NSArray UIColorArray __deprecated_msg("Use NSArray<UIColor *>");
/**
* Synchronous image loading is generally a bad idea for performance reasons.
* If you need to pass image references, try to use `RCTImageSource` and then
* `RCTImageLoader` instead of converting directly to a UIImage.
*/
+ (UIImage *)UIImage:(id)json;
+ (CGImageRef)CGImage:(id)json CF_RETURNS_NOT_RETAINED;
@end
/**
* Underlying implementations of RCT_XXX_CONVERTER macros. Ignore these.
*/
RCT_EXTERN NSNumber *
RCTConvertEnumValue(const char * /*typeName*/, NSDictionary * /*mapping*/, NSNumber * /*defaultValue*/, id /*json*/);
RCT_EXTERN NSNumber *RCTConvertMultiEnumValue(
const char * /*typeName*/,
NSDictionary * /*mapping*/,
NSNumber * /*defaultValue*/,
id /*json*/);
RCT_EXTERN NSArray *RCTConvertArrayValue(SEL /*type*/, id /*json*/);
/**
* This macro is used for logging conversion errors. This is just used to
* avoid repeating the same boilerplate for every error message.
*/
#define RCTLogConvertError(json, typeName) \
RCTLogInfo(@"JSON value '%@' of type %@ cannot be converted to %@", json, [json classForCoder], typeName)
/**
* This macro is used for creating simple converter functions that just call
* the specified getter method on the json value.
*/
#define RCT_CONVERTER(type, name, getter) RCT_CUSTOM_CONVERTER(type, name, [json getter])
/**
* This macro is used for creating converter functions with arbitrary logic.
*/
#define RCT_CUSTOM_CONVERTER(type, name, code) \
+(type)name : (id)json RCT_DYNAMIC \
{ \
if (!RCT_DEBUG) { \
return code; \
} else { \
@try { \
return code; \
} @catch (__unused NSException * e) { \
RCTLogConvertError(json, @ #type); \
json = nil; \
return code; \
} \
} \
}
/**
* This macro is similar to RCT_CONVERTER, but specifically geared towards
* numeric types. It will handle string input correctly, and provides more
* detailed error reporting if an invalid value is passed in.
*/
#define RCT_NUMBER_CONVERTER(type, getter) \
RCT_CUSTOM_CONVERTER(type, type, [RCT_DEBUG ? [self NSNumber:json] : json getter])
/**
* When using RCT_ENUM_CONVERTER in ObjC, the compiler is OK with us returning
* the underlying NSInteger/NSUInteger. In ObjC++, this is a type mismatch and
* we need to explicitly cast the return value to expected enum return type.
*/
#ifdef __cplusplus
#define _RCT_CAST(type, expr) static_cast<type>(expr)
#else
#define _RCT_CAST(type, expr) expr
#endif
/**
* This macro is used for creating converters for enum types.
*/
#define RCT_ENUM_CONVERTER(type, values, default, getter) \
+(type)type : (id)json RCT_DYNAMIC \
{ \
static NSDictionary *mapping; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
mapping = values; \
}); \
return _RCT_CAST(type, [RCTConvertEnumValue(#type, mapping, @(default), json) getter]); \
}
/**
* This macro is used for creating converters for enum types for
* multiple enum values combined with | operator
*/
#define RCT_MULTI_ENUM_CONVERTER(type, values, default, getter) \
+(type)type : (id)json RCT_DYNAMIC \
{ \
static NSDictionary *mapping; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
mapping = values; \
}); \
return _RCT_CAST(type, [RCTConvertMultiEnumValue(#type, mapping, @(default), json) getter]); \
}
/**
* This macro is used for creating explicitly-named converter functions
* for typed arrays.
*/
#define RCT_ARRAY_CONVERTER_NAMED(type, name) \
+(NSArray<type *> *)name##Array : (id)json RCT_DYNAMIC \
{ \
return RCTConvertArrayValue(@selector(name:), json); \
}
/**
* This macro is used for creating converter functions for typed arrays.
* RCT_ARRAY_CONVERTER_NAMED may be used when type contains characters
* which are disallowed in selector names.
*/
#define RCT_ARRAY_CONVERTER(type) RCT_ARRAY_CONVERTER_NAMED(type, type)

1376
node_modules/react-native/React/Base/RCTConvert.mm generated vendored Normal file

File diff suppressed because it is too large Load Diff

18
node_modules/react-native/React/Base/RCTCxxConvert.h generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
/**
* This class provides a collection of conversion functions for mapping
* JSON objects to cxx types. Extensible via categories.
* Convert methods are expected to return cxx objects wrapped in RCTManagedPointer.
*/
@interface RCTCxxConvert : NSObject
@end

12
node_modules/react-native/React/Base/RCTCxxConvert.m generated vendored Normal file
View File

@@ -0,0 +1,12 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTCxxConvert.h"
@implementation RCTCxxConvert
@end

177
node_modules/react-native/React/Base/RCTDefines.h generated vendored Normal file
View File

@@ -0,0 +1,177 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#if __OBJC__
#import <Foundation/Foundation.h>
#endif
/**
* Make global functions usable in C++
*/
#if defined(__cplusplus)
#define RCT_EXTERN extern "C" __attribute__((visibility("default")))
#define RCT_EXTERN_C_BEGIN extern "C" {
#define RCT_EXTERN_C_END }
#else
#define RCT_EXTERN extern __attribute__((visibility("default")))
#define RCT_EXTERN_C_BEGIN
#define RCT_EXTERN_C_END
#endif
/**
* The RCT_DEBUG macro can be used to exclude error checking and logging code
* from release builds to improve performance and reduce binary size.
*/
#ifndef RCT_DEBUG
#ifdef DEBUG
#define RCT_DEBUG 1
#else
#define RCT_DEBUG 0
#endif
#endif
/**
* The RCT_DEV macro can be used to enable or disable development tools
* such as the debug executors, dev menu, red box, etc.
*/
#ifndef RCT_DEV
#ifdef DEBUG
#define RCT_DEV 1
#else
#define RCT_DEV 0
#endif
#endif
/**
* RCT_REMOTE_PROFILE: RCT_PROFILE + RCT_ENABLE_INSPECTOR + enable the
* connectivity functionality to control the profiler remotely, such as via Chrome DevTools.
* If Fusebox is enabled for release builds, enable the remote profile mode, fall back to RCT_DEV by default.
*/
#ifndef RCT_REMOTE_PROFILE
#ifdef REACT_NATIVE_DEBUGGER_MODE_PROD
#define RCT_REMOTE_PROFILE REACT_NATIVE_DEBUGGER_MODE_PROD
#else
#define RCT_REMOTE_PROFILE RCT_DEV
#endif
#endif
/**
* Enable the code to support making calls to the underlying sampling profiler mechanism.
*/
#ifndef RCT_PROFILE
#define RCT_PROFILE RCT_REMOTE_PROFILE
#endif
#ifndef RCT_ENABLE_INSPECTOR
#if (RCT_DEV || RCT_REMOTE_PROFILE) && __has_include(<React/RCTInspectorDevServerHelper.h>)
#define RCT_ENABLE_INSPECTOR 1
#else
#define RCT_ENABLE_INSPECTOR 0
#endif
#endif
/**
* Sanity check that these compile-time flags are compatible. RCT_REMOTE_PROFILE requires RCT_PROFILE and
* RCT_ENABLE_INSPECTOR
*/
#if RCT_REMOTE_PROFILE
#if !RCT_PROFILE
#error "RCT_PROFILE needs to be set to fulfill RCT_REMOTE_PROFILE"
#endif // RCT_PROFILE
#if !RCT_ENABLE_INSPECTOR
#error "RCT_ENABLE_INSPECTOR needs to be set to fulfill RCT_REMOTE_PROFILE"
#endif // RCT_ENABLE_INSPECTOR
#endif // RCT_REMOTE_PROFILE
/**
* RCT_DEV_MENU can be used to toggle the dev menu separately from RCT_DEV.
* By default though, it will inherit from RCT_DEV.
*/
#ifndef RCT_DEV_MENU
#define RCT_DEV_MENU RCT_DEV
#endif
#ifndef RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION
#if RCT_DEV && (__has_include("RCTPackagerConnection.h") || __has_include(<React/RCTPackagerConnection.h>))
#define RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION 1
#else
#define RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION 0
#endif
#endif
#if RCT_DEV
#define RCT_IF_DEV(...) __VA_ARGS__
#else
#define RCT_IF_DEV(...)
#endif
#ifndef RCT_PROFILE
#define RCT_PROFILE RCT_DEV
#endif
/**
* Add the default Metro packager port number
*/
#ifndef RCT_METRO_PORT
#define RCT_METRO_PORT 8081
#else
// test if RCT_METRO_PORT is empty
#define RCT_METRO_PORT_DO_EXPAND(VAL) VAL##1
#define RCT_METRO_PORT_EXPAND(VAL) RCT_METRO_PORT_DO_EXPAND(VAL)
#if !defined(RCT_METRO_PORT) || (RCT_METRO_PORT_EXPAND(RCT_METRO_PORT) == 1)
// Only here if RCT_METRO_PORT is not defined
// OR RCT_METRO_PORT is the empty string
#undef RCT_METRO_PORT
#define RCT_METRO_PORT 8081
#endif
#endif
/**
* Add the default packager name
*/
#ifndef RCT_PACKAGER_NAME
#define RCT_PACKAGER_NAME @"Metro"
#endif
/**
* By default, only raise an NSAssertion in debug mode
* (custom assert functions will still be called).
*/
#ifndef RCT_NSASSERT
#define RCT_NSASSERT RCT_DEBUG
#endif
/**
* Concat two literals. Supports macro expansions,
* e.g. RCT_CONCAT(foo, __FILE__).
*/
#define RCT_CONCAT2(A, B) A##B
#define RCT_CONCAT(A, B) RCT_CONCAT2(A, B)
/**
* This attribute is used for static analysis.
*/
#if !defined RCT_DYNAMIC
#if __has_attribute(objc_dynamic)
#define RCT_DYNAMIC __attribute__((objc_dynamic))
#else
#define RCT_DYNAMIC
#endif
#endif
/**
* Throw an assertion for unimplemented methods.
*/
#define RCT_NOT_IMPLEMENTED(method) \
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wmissing-method-return-type\"") \
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
RCT_EXTERN NSException *_RCTNotImplementedException(SEL, Class); \
method NS_UNAVAILABLE \
{ \
@throw _RCTNotImplementedException(_cmd, [self class]); \
} \
_Pragma("clang diagnostic pop")

27
node_modules/react-native/React/Base/RCTDisplayLink.h generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@protocol RCTBridgeModule;
@class RCTModuleData;
@protocol RCTDisplayLinkModuleHolder
- (id<RCTBridgeModule>)instance;
- (Class)moduleClass;
- (dispatch_queue_t)methodQueue;
@end
@interface RCTDisplayLink : NSObject
- (instancetype)init;
- (void)invalidate;
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module
withModuleHolder:(id<RCTDisplayLinkModuleHolder>)moduleHolder;
- (void)addToRunLoop:(NSRunLoop *)runLoop;
@end

165
node_modules/react-native/React/Base/RCTDisplayLink.m generated vendored Normal file
View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTDisplayLink.h"
#import <Foundation/Foundation.h>
#import <QuartzCore/CADisplayLink.h>
#import "RCTAssert.h"
#import "RCTBridgeModule.h"
#import "RCTFrameUpdate.h"
#import "RCTModuleData.h"
#import "RCTProfile.h"
#define RCTAssertRunLoop() \
RCTAssert(_runLoop == [NSRunLoop currentRunLoop], @"This method must be called on the CADisplayLink run loop")
@implementation RCTDisplayLink {
CADisplayLink *_jsDisplayLink;
NSMutableSet<id<RCTDisplayLinkModuleHolder>> *_frameUpdateObservers;
NSRunLoop *_runLoop;
}
- (instancetype)init
{
if ((self = [super init])) {
_frameUpdateObservers = [NSMutableSet new];
_jsDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_jsThreadUpdate:)];
}
return self;
}
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module
withModuleHolder:(id<RCTDisplayLinkModuleHolder>)moduleHolder
{
if (![moduleHolder.moduleClass conformsToProtocol:@protocol(RCTFrameUpdateObserver)] ||
[_frameUpdateObservers containsObject:moduleHolder]) {
return;
}
[_frameUpdateObservers addObject:moduleHolder];
// Don't access the module instance via moduleHolder, as this will cause deadlock
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)module;
__weak typeof(self) weakSelf = self;
observer.pauseCallback = ^{
typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
CFRunLoopRef cfRunLoop = [strongSelf->_runLoop getCFRunLoop];
if (!cfRunLoop) {
return;
}
if ([NSRunLoop currentRunLoop] == strongSelf->_runLoop) {
[weakSelf updateJSDisplayLinkState];
} else {
CFRunLoopPerformBlock(cfRunLoop, kCFRunLoopDefaultMode, ^{
@autoreleasepool {
[weakSelf updateJSDisplayLinkState];
}
});
CFRunLoopWakeUp(cfRunLoop);
}
};
// Assuming we're paused right now, we only need to update the display link's state
// when the new observer is not paused. If it not paused, the observer will immediately
// start receiving updates anyway.
if (![observer isPaused] && _runLoop) {
CFRunLoopPerformBlock([_runLoop getCFRunLoop], kCFRunLoopDefaultMode, ^{
@autoreleasepool {
[self updateJSDisplayLinkState];
}
});
}
}
- (void)addToRunLoop:(NSRunLoop *)runLoop
{
_runLoop = runLoop;
[_jsDisplayLink addToRunLoop:runLoop forMode:NSRunLoopCommonModes];
}
- (void)dealloc
{
[self invalidate];
}
- (void)invalidate
{
// ensure observer callbacks do not hold a reference to weak self via pauseCallback
for (id<RCTDisplayLinkModuleHolder> moduleHolder in _frameUpdateObservers) {
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleHolder.instance;
[observer setPauseCallback:nil];
}
[_frameUpdateObservers removeAllObjects]; // just to be explicit
[_jsDisplayLink invalidate];
}
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue
{
if (queue == RCTJSThread) {
block();
} else if (queue) {
dispatch_async(queue, block);
}
}
- (void)_jsThreadUpdate:(CADisplayLink *)displayLink
{
RCTAssertRunLoop();
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTDisplayLink _jsThreadUpdate:]", nil);
RCTFrameUpdate *frameUpdate = [[RCTFrameUpdate alloc] initWithDisplayLink:displayLink];
for (id<RCTDisplayLinkModuleHolder> moduleHolder in _frameUpdateObservers) {
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleHolder.instance;
if (!observer.paused) {
if (moduleHolder.methodQueue) {
RCTProfileBeginFlowEvent();
[self
dispatchBlock:^{
RCTProfileEndFlowEvent();
[observer didUpdateFrame:frameUpdate];
}
queue:moduleHolder.methodQueue];
} else {
[observer didUpdateFrame:frameUpdate];
}
}
}
[self updateJSDisplayLinkState];
RCTProfileImmediateEvent(RCTProfileTagAlways, @"JS Thread Tick", displayLink.timestamp, 'g');
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"objc_call");
}
- (void)updateJSDisplayLinkState
{
RCTAssertRunLoop();
BOOL pauseDisplayLink = YES;
for (id<RCTDisplayLinkModuleHolder> moduleHolder in _frameUpdateObservers) {
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleHolder.instance;
if (!observer.paused) {
pauseDisplayLink = NO;
break;
}
}
_jsDisplayLink.paused = pauseDisplayLink;
}
@end

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTErrorInfo;
/**
* Provides an interface to customize React Native error messages and stack
* traces from exceptions.
*/
@protocol RCTErrorCustomizer <NSObject>
/**
* Customizes the given error, returning the passed info argument if no
* customization is required.
*/
- (nonnull RCTErrorInfo *)customizeErrorInfo:(nonnull RCTErrorInfo *)info;
@end

21
node_modules/react-native/React/Base/RCTErrorInfo.h generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTJSStackFrame;
/**
* An ObjC wrapper for React Native errors.
*/
@interface RCTErrorInfo : NSObject
@property (nonatomic, copy, readonly) NSString *errorMessage;
@property (nonatomic, copy, readonly) NSArray<RCTJSStackFrame *> *stack;
- (instancetype)initWithErrorMessage:(NSString *)errorMessage stack:(NSArray<RCTJSStackFrame *> *)stack;
@end

24
node_modules/react-native/React/Base/RCTErrorInfo.m generated vendored Normal file
View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTErrorInfo.h"
#import "RCTJSStackFrame.h"
@implementation RCTErrorInfo
- (instancetype)initWithErrorMessage:(NSString *)errorMessage stack:(NSArray<RCTJSStackFrame *> *)stack
{
self = [super init];
if (self) {
_errorMessage = [errorMessage copy];
_stack = [stack copy];
}
return self;
}
@end

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTEventDispatcherProtocol.h"
const NSInteger RCTTextUpdateLagWarningThreshold = 3;
NSString *RCTNormalizeInputEventName(NSString *eventName)
{
if ([eventName hasPrefix:@"on"]) {
eventName = [eventName stringByReplacingCharactersInRange:(NSRange){0, 2} withString:@"top"];
} else if (![eventName hasPrefix:@"top"]) {
eventName = [[@"top" stringByAppendingString:[eventName substringToIndex:1].uppercaseString]
stringByAppendingString:[eventName substringFromIndex:1]];
}
return eventName;
}
@implementation RCTBridge (RCTEventDispatcher)
- (id<RCTEventDispatcherProtocol>)eventDispatcher
{
return [self moduleForName:@"EventDispatcher" lazilyLoadIfNecessary:YES];
}
@end
@implementation RCTBridgeProxy (RCTEventDispatcher)
- (id<RCTEventDispatcherProtocol>)eventDispatcher
{
return [self moduleForName:@"EventDispatcher" lazilyLoadIfNecessary:YES];
}
@end

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import <React/RCTBridgeProxy.h>
/**
* The threshold at which text inputs will start warning that the JS thread
* has fallen behind (resulting in poor input performance, missed keys, etc.)
*/
RCT_EXTERN const NSInteger RCTTextUpdateLagWarningThreshold;
/**
* Takes an input event name and normalizes it to the form that is required
* by the events system (currently that means starting with the "top" prefix,
* but that's an implementation detail that may change in future).
*/
RCT_EXTERN NSString *RCTNormalizeInputEventName(NSString *eventName);
typedef NS_ENUM(NSInteger, RCTTextEventType) {
RCTTextEventTypeFocus,
RCTTextEventTypeBlur,
RCTTextEventTypeChange,
RCTTextEventTypeSubmit,
RCTTextEventTypeEnd,
RCTTextEventTypeKeyPress
};
@protocol RCTEvent <NSObject>
@required
@property (nonatomic, strong, readonly) NSNumber *viewTag;
@property (nonatomic, copy, readonly) NSString *eventName;
- (BOOL)canCoalesce;
/** used directly for doing a JS call */
+ (NSString *)moduleDotMethod;
/** must contain only JSON compatible values */
- (NSArray *)arguments;
@optional
/**
* Coalescing related methods must only be implemented if canCoalesce
* returns YES.
*/
@property (nonatomic, assign, readonly) uint16_t coalescingKey;
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent;
@end
/**
* This protocol allows observing events dispatched by RCTEventDispatcher.
*/
@protocol RCTEventDispatcherObserver <NSObject>
/**
* Called before dispatching an event, on the same thread the event was
* dispatched from.
*/
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event;
@end
@protocol RCTJSDispatcherModule
@property (nonatomic, copy) void (^dispatchToJSThread)(dispatch_block_t block);
@end
/**
* This class wraps the -[RCTBridge enqueueJSCall:args:] method, and
* provides some convenience methods for generating event calls.
*/
@protocol RCTEventDispatcherProtocol <RCTBridgeModule, RCTJSDispatcherModule>
- (void)sendViewEventWithName:(NSString *)name reactTag:(NSNumber *)reactTag;
/**
* Deprecated, do not use.
*/
- (void)sendAppEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
/**
* Deprecated, do not use.
*/
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
/**
* Send a text input/focus event. For internal use only.
*/
- (void)sendTextEventWithType:(RCTTextEventType)type
reactTag:(NSNumber *)reactTag
text:(NSString *)text
key:(NSString *)key
eventCount:(NSInteger)eventCount;
/**
* Notify Observers of event
*/
- (void)notifyObserversOfEvent:(id<RCTEvent>)event;
/**
* Send a pre-prepared event object.
*
* Events are sent to JS as soon as the thread is free to process them.
* If an event can be coalesced and there is another compatible event waiting, the coalescing will happen immediately.
*/
- (void)sendEvent:(id<RCTEvent>)event;
/**
* Add an event dispatcher observer.
*/
- (void)addDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
/**
* Remove an event dispatcher observer.
*/
- (void)removeDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
@end
@interface RCTBridge (RCTEventDispatcher)
- (id<RCTEventDispatcherProtocol>)eventDispatcher;
@end
@interface RCTBridgeProxy (RCTEventDispatcher)
- (id<RCTEventDispatcherProtocol>)eventDispatcher;
@end

52
node_modules/react-native/React/Base/RCTFrameUpdate.h generated vendored Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class CADisplayLink;
/**
* Interface containing the information about the last screen refresh.
*/
@interface RCTFrameUpdate : NSObject
/**
* Timestamp for the actual screen refresh
*/
@property (nonatomic, readonly) NSTimeInterval timestamp;
/**
* Time since the last frame update ( >= 16.6ms )
*/
@property (nonatomic, readonly) NSTimeInterval deltaTime;
- (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink NS_DESIGNATED_INITIALIZER;
@end
/**
* Protocol that must be implemented for subscribing to display refreshes (DisplayLink updates)
*/
@protocol RCTFrameUpdateObserver <NSObject>
/**
* Method called on every screen refresh (if paused != YES)
*/
- (void)didUpdateFrame:(RCTFrameUpdate *)update;
/**
* Synthesize and set to true to pause the calls to -[didUpdateFrame:]
*/
@property (nonatomic, readonly, getter=isPaused) BOOL paused;
/**
* Callback for pause/resume observer.
* Observer should call it when paused property is changed.
*/
@property (nonatomic, copy) dispatch_block_t pauseCallback;
@end

27
node_modules/react-native/React/Base/RCTFrameUpdate.m generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <QuartzCore/CADisplayLink.h>
#import "RCTFrameUpdate.h"
#import "RCTUtils.h"
@implementation RCTFrameUpdate
RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink
{
if ((self = [super init])) {
_timestamp = displayLink.timestamp;
_deltaTime = displayLink.duration;
}
return self;
}
@end

40
node_modules/react-native/React/Base/RCTImageSource.h generated vendored Normal file
View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTConvert.h>
/**
* Object containing an image URL and associated metadata.
*/
@interface RCTImageSource : NSObject
@property (nonatomic, copy, readonly) NSURLRequest *request;
@property (nonatomic, assign, readonly) CGSize size;
@property (nonatomic, assign, readonly) CGFloat scale;
/**
* Create a new image source object.
* Pass a size of CGSizeZero if you do not know or wish to specify the image
* size. Pass a scale of zero if you do not know or wish to specify the scale.
*/
- (instancetype)initWithURLRequest:(NSURLRequest *)request size:(CGSize)size scale:(CGFloat)scale;
/**
* Create a copy of the image source with the specified size and scale.
*/
- (instancetype)imageSourceWithSize:(CGSize)size scale:(CGFloat)scale;
@end
@interface RCTConvert (ImageSource)
+ (RCTImageSource *)RCTImageSource:(id)json;
+ (NSArray<RCTImageSource *> *)RCTImageSourceArray:(id)json;
@end

89
node_modules/react-native/React/Base/RCTImageSource.m generated vendored Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTImageSource.h"
#import "RCTUtils.h"
@interface RCTImageSource ()
@property (nonatomic, assign) BOOL packagerAsset;
@end
@implementation RCTImageSource
- (instancetype)initWithURLRequest:(NSURLRequest *)request size:(CGSize)size scale:(CGFloat)scale
{
if ((self = [super init])) {
_request = [request copy];
_size = size;
_scale = scale;
}
return self;
}
- (instancetype)imageSourceWithSize:(CGSize)size scale:(CGFloat)scale
{
RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:_request size:size scale:scale];
imageSource.packagerAsset = _packagerAsset;
return imageSource;
}
- (BOOL)isEqual:(RCTImageSource *)object
{
if (![object isKindOfClass:[RCTImageSource class]]) {
return NO;
}
return [_request isEqual:object.request] && _scale == object.scale &&
(CGSizeEqualToSize(_size, object.size) || CGSizeEqualToSize(object.size, CGSizeZero));
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<RCTImageSource: %p URL=%@, size=%@, scale=%0.f>",
self,
_request.URL,
NSStringFromCGSize(_size),
_scale];
}
@end
@implementation RCTConvert (ImageSource)
+ (RCTImageSource *)RCTImageSource:(id)json
{
if (!json) {
return nil;
}
NSURLRequest *request;
CGSize size = CGSizeZero;
CGFloat scale = 1.0;
BOOL packagerAsset = NO;
if ([json isKindOfClass:[NSDictionary class]]) {
if (!(request = [self NSURLRequest:json])) {
return nil;
}
size = [self CGSize:json];
scale = [self CGFloat:json[@"scale"]] ?: [self BOOL:json[@"deprecated"]] ? 0.0 : 1.0;
packagerAsset = [self BOOL:json[@"__packager_asset"]];
} else if ([json isKindOfClass:[NSString class]]) {
request = [self NSURLRequest:json];
} else {
RCTLogConvertError(json, @"an image. Did you forget to call resolveAssetSource() on the JS side?");
return nil;
}
RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:request size:size scale:scale];
imageSource.packagerAsset = packagerAsset;
return imageSource;
}
RCT_ARRAY_CONVERTER(RCTImageSource)
@end

14
node_modules/react-native/React/Base/RCTInitializing.h generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@protocol RCTInitializing <NSObject>
- (void)initialize;
@end

14
node_modules/react-native/React/Base/RCTInvalidating.h generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@protocol RCTInvalidating <NSObject>
- (void)invalidate;
@end

30
node_modules/react-native/React/Base/RCTJSStackFrame.h generated vendored Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@interface RCTJSStackFrame : NSObject
@property (nonatomic, copy, readonly) NSString *methodName;
@property (nonatomic, copy, readonly) NSString *file;
@property (nonatomic, readonly) NSInteger lineNumber;
@property (nonatomic, readonly) NSInteger column;
@property (nonatomic, readonly) BOOL collapse;
- (instancetype)initWithMethodName:(NSString *)methodName
file:(NSString *)file
lineNumber:(NSInteger)lineNumber
column:(NSInteger)column
collapse:(BOOL)collapse;
- (NSDictionary *)toDictionary;
+ (instancetype)stackFrameWithLine:(NSString *)line;
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict;
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines;
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithDictionaries:(NSArray<NSDictionary *> *)dicts;
@end

150
node_modules/react-native/React/Base/RCTJSStackFrame.m generated vendored Normal file
View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTJSStackFrame.h"
#import "RCTLog.h"
#import "RCTUtils.h"
/**
* The RegEx used to parse Error.stack.
*
* JavaScriptCore has the following format:
*
* Exception: Error: argh
* func1@/path/to/file.js:2:18
* func2@/path/to/file.js:6:8
* eval@[native code]
* global code@/path/to/file.js:13:5
*
* Another supported format:
*
* Error: argh
* at func1 (/path/to/file.js:2:18)
* at func2 (/path/to/file.js:6:8)
* at eval (native)
* at global (/path/to/file.js:13:5)
*/
static NSRegularExpression *RCTJSStackFrameRegex(void)
{
static dispatch_once_t onceToken;
static NSRegularExpression *_regex;
dispatch_once(&onceToken, ^{
NSString *pattern =
@"\\s*(?:at)?\\s*" // Skip leading "at" and whitespace, noncapturing
@"(.+?)" // Capture the function name (group 1)
@"\\s*[@(]" // Skip whitespace, then @ or (
@"(.*):" // Capture the file name (group 2), then colon
@"(\\d+):(\\d+)" // Line and column number (groups 3 and 4)
@"\\)?$" // Optional closing paren and EOL
;
NSError *regexError;
_regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&regexError];
if (regexError) {
RCTLogError(@"Failed to build regex: %@", [regexError localizedDescription]);
}
});
return _regex;
}
@implementation RCTJSStackFrame
- (instancetype)initWithMethodName:(NSString *)methodName
file:(NSString *)file
lineNumber:(NSInteger)lineNumber
column:(NSInteger)column
collapse:(BOOL)collapse
{
if (self = [super init]) {
_methodName = methodName;
_file = file;
_lineNumber = lineNumber;
_column = column;
_collapse = collapse;
}
return self;
}
- (NSDictionary *)toDictionary
{
return @{
@"methodName" : RCTNullIfNil(self.methodName),
@"file" : RCTNullIfNil(self.file),
@"lineNumber" : @(self.lineNumber),
@"column" : @(self.column),
@"collapse" : @(self.collapse)
};
}
+ (instancetype)stackFrameWithLine:(NSString *)line
{
NSTextCheckingResult *match = [RCTJSStackFrameRegex() firstMatchInString:line
options:0
range:NSMakeRange(0, line.length)];
if (!match) {
return nil;
}
// methodName may not be present for e.g. anonymous functions
const NSRange methodNameRange = [match rangeAtIndex:1];
NSString *methodName = methodNameRange.location == NSNotFound ? nil : [line substringWithRange:methodNameRange];
NSString *file = [line substringWithRange:[match rangeAtIndex:2]];
NSString *lineNumber = [line substringWithRange:[match rangeAtIndex:3]];
NSString *column = [line substringWithRange:[match rangeAtIndex:4]];
return [[self alloc] initWithMethodName:methodName
file:file
lineNumber:[lineNumber integerValue]
column:[column integerValue]
collapse:NO];
}
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict
{
return [[self alloc] initWithMethodName:RCTNilIfNull(dict[@"methodName"])
file:dict[@"file"]
lineNumber:[RCTNilIfNull(dict[@"lineNumber"]) integerValue]
column:[RCTNilIfNull(dict[@"column"]) integerValue]
collapse:[RCTNilIfNull(dict[@"collapse"]) boolValue]];
}
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines
{
NSMutableArray *stack = [NSMutableArray new];
for (NSString *line in [lines componentsSeparatedByString:@"\n"]) {
RCTJSStackFrame *frame = [self stackFrameWithLine:line];
if (frame) {
[stack addObject:frame];
}
}
return stack;
}
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithDictionaries:(NSArray<NSDictionary *> *)dicts
{
NSMutableArray *stack = [NSMutableArray new];
for (NSDictionary *dict in dicts) {
RCTJSStackFrame *frame = [self stackFrameWithDictionary:dict];
if (frame) {
[stack addObject:frame];
}
}
return stack;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p method name: %@; file name: %@; line: %ld; column: %ld>",
self.class,
self,
self.methodName,
self.file,
(long)self.lineNumber,
(long)self.column];
}
@end

29
node_modules/react-native/React/Base/RCTJSThread.h generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <React/RCTDefines.h>
/**
* This constant can be returned from +methodQueue to force module
* methods to be called on the JavaScript thread. This can have serious
* implications for performance, so only use this if you're sure it's what
* you need.
*
* NOTE: RCTJSThread is not a real libdispatch queue
*/
RCT_EXTERN dispatch_queue_t RCTJSThread;
/**
* Initializes the RCTJSThread constant.
* Exported because the bridgeless initialization layer needs to initialize
* RCTJSThread. In bridgeless mode, RCTBridge isn't accessed, and RCTJSThread
* therefore isn't initialized.
*/
RCT_EXTERN void _RCTInitializeJSThreadConstantInternal(void);

19
node_modules/react-native/React/Base/RCTJSThread.m generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTJSThread.h"
dispatch_queue_t RCTJSThread;
void _RCTInitializeJSThreadConstantInternal(void)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Set up JS thread
RCTJSThread = (id)kCFNull;
});
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <objc/runtime.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTInvalidating.h>
typedef void (^RCTJavaScriptCompleteBlock)(NSError *__strong)
__deprecated_msg("This api will be removed along with the bridge.");
typedef void (^RCTJavaScriptCallback)(__strong id, NSError *__strong)
__deprecated_msg("This api will be removed along with the bridge.");
#ifndef RCT_REMOVE_LEGACY_ARCH
/**
* Abstracts away a JavaScript execution context - we may be running code in a
* web view (for debugging purposes), or may be running code in a `JSContext`.
*/
__deprecated_msg("This api will be removed along with the bridge.")
@protocol RCTJavaScriptExecutor<RCTInvalidating, RCTBridgeModule>
/**
* Used to set up the executor after the bridge has been fully initialized.
* Do any expensive setup in this method instead of `-init`.
*/
- (void)setUp;
/**
* Whether the executor has been invalidated
*/
@property (nonatomic, readonly, getter=isValid) BOOL valid;
/**
* Executes BatchedBridge.flushedQueue on JS thread and calls the given callback
* with JSValue, containing the next queue, and JSContext.
*/
- (void)flushedQueue:(RCTJavaScriptCallback)onComplete;
/**
* Executes BatchedBridge.callFunctionReturnFlushedQueue with the module name,
* method name and optional additional arguments on the JS thread and calls the
* given callback with JSValue, containing the next queue, and JSContext.
*/
- (void)callFunctionOnModule:(NSString *)module
method:(NSString *)method
arguments:(NSArray *)args
callback:(RCTJavaScriptCallback)onComplete;
/**
* Executes BatchedBridge.invokeCallbackAndReturnFlushedQueue with the cbID,
* and optional additional arguments on the JS thread and calls the
* given callback with JSValue, containing the next queue, and JSContext.
*/
- (void)invokeCallbackID:(NSNumber *)cbID arguments:(NSArray *)args callback:(RCTJavaScriptCallback)onComplete;
/**
* Runs an application script, and notifies of the script load being complete via `onComplete`.
*/
- (void)executeApplicationScript:(NSData *)script
sourceURL:(NSURL *)sourceURL
onComplete:(RCTJavaScriptCompleteBlock)onComplete;
- (void)injectJSONText:(NSString *)script
asGlobalObjectNamed:(NSString *)objectName
callback:(RCTJavaScriptCompleteBlock)onComplete;
/**
* Enqueue a block to run in the executors JS thread. Fallback to `dispatch_async`
* on the main queue if the executor doesn't own a thread.
*/
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block;
/**
* Special case for Timers + ContextExecutor - instead of the default
* if jsthread then call else dispatch call on jsthread
* ensure the call is made async on the jsthread
*/
- (void)executeAsyncBlockOnJavaScriptQueue:(dispatch_block_t)block;
@end
#endif // RCT_REMOVE_LEGACY_ARCH

93
node_modules/react-native/React/Base/RCTJavaScriptLoader.h generated vendored Executable file
View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTDefines.h>
extern NSString *const RCTJavaScriptLoaderErrorDomain;
NS_ENUM(NSInteger){
RCTJavaScriptLoaderErrorNoScriptURL = 1,
RCTJavaScriptLoaderErrorFailedOpeningFile = 2,
RCTJavaScriptLoaderErrorFailedReadingFile = 3,
RCTJavaScriptLoaderErrorFailedStatingFile = 3,
RCTJavaScriptLoaderErrorURLLoadFailed = 3,
RCTJavaScriptLoaderErrorBCVersion = 4,
RCTJavaScriptLoaderErrorBCNotSupported = 4,
RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000,
};
NS_ENUM(NSInteger){
RCTSourceFilesChangedCountNotBuiltByBundler = -2,
RCTSourceFilesChangedCountRebuiltFromScratch = -1,
};
@interface RCTLoadingProgress : NSObject
@property (nonatomic, copy) NSString *status;
@property (strong, nonatomic) NSNumber *done;
@property (strong, nonatomic) NSNumber *total;
@end
@interface RCTSource : NSObject
/**
* URL of the source object.
*/
@property (strong, nonatomic, readonly) NSURL *url;
/**
* JS source (or simply the binary header in the case of a RAM bundle).
*/
@property (strong, nonatomic, readonly) NSData *data;
/**
* Length of the entire JS bundle. Note that self.length != self.data.length in the case of certain bundle formats. For
* instance, when using RAM bundles:
*
* - self.data will point to the bundle header
* - self.data.length is the length of the bundle header, i.e. sizeof(facebook::react::BundleHeader)
* - self.length is the length of the entire bundle file (header + contents)
*/
@property (nonatomic, readonly) NSUInteger length;
/**
* Returns number of files changed when building this bundle:
*
* - RCTSourceFilesChangedCountNotBuiltByBundler if the source wasn't built by the bundler (e.g. read from disk)
* - RCTSourceFilesChangedCountRebuiltFromScratch if the source was rebuilt from scratch by the bundler
* - Otherwise, the number of files changed when incrementally rebuilding the source
*/
@property (nonatomic, readonly) NSInteger filesChangedCount;
@end
typedef void (^RCTSourceLoadProgressBlock)(RCTLoadingProgress *progressData);
typedef void (^RCTSourceLoadBlock)(NSError *error, RCTSource *source);
@interface RCTJavaScriptLoader : NSObject
+ (void)loadBundleAtURL:(NSURL *)scriptURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)onComplete;
/**
* @experimental
* Attempts to synchronously load the script at the given URL. The following two conditions must be met:
* 1. It must be a file URL.
* 2. It must not point to a text/javascript file.
* If the URL does not meet those conditions, this method will return nil and supply an error with the domain
* RCTJavaScriptLoaderErrorDomain and the code RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously.
*/
+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
sourceLength:(int64_t *)sourceLength
error:(NSError **)error;
@end

386
node_modules/react-native/React/Base/RCTJavaScriptLoader.mm generated vendored Executable file
View File

@@ -0,0 +1,386 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTJavaScriptLoader.h"
#import <sys/stat.h>
#import <cxxreact/JSBundleType.h>
#import "RCTBridge.h"
#import "RCTConvert.h"
#import "RCTMultipartDataTask.h"
#import "RCTPerformanceLogger.h"
#import "RCTUtils.h"
NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomain";
@interface RCTSource () {
@public
NSURL *_url;
NSData *_data;
NSUInteger _length;
NSInteger _filesChangedCount;
}
@end
@implementation RCTSource
static RCTSource *RCTSourceCreate(NSURL *url, NSData *data, int64_t length) NS_RETURNS_RETAINED
{
using facebook::react::ScriptTag;
facebook::react::BundleHeader header;
[data getBytes:&header length:sizeof(header)];
RCTSource *source = [RCTSource new];
source->_url = url;
source->_data = data;
source->_length = length;
source->_filesChangedCount = RCTSourceFilesChangedCountNotBuiltByBundler;
return source;
}
@end
@implementation RCTLoadingProgress
- (NSString *)description
{
NSMutableString *desc = [NSMutableString new];
[desc appendString:_status ?: @"Bundling"];
if ([_total integerValue] > 0 && [_done integerValue] > [_total integerValue]) {
[desc appendFormat:@" %ld%%", (long)100];
} else if ([_total integerValue] > 0) {
[desc appendFormat:@" %ld%%", (long)(100 * [_done integerValue] / [_total integerValue])];
} else {
[desc appendFormat:@" %ld%%", (long)0];
}
[desc appendString:@"\u2026"];
return desc;
}
@end
@implementation RCTJavaScriptLoader
RCT_NOT_IMPLEMENTED(-(instancetype)init)
+ (void)loadBundleAtURL:(NSURL *)scriptURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)onComplete
{
int64_t sourceLength;
NSError *error;
NSData *data = [self attemptSynchronousLoadOfBundleAtURL:scriptURL sourceLength:&sourceLength error:&error];
if (data) {
onComplete(nil, RCTSourceCreate(scriptURL, data, sourceLength));
return;
}
const BOOL isCannotLoadSyncError = [error.domain isEqualToString:RCTJavaScriptLoaderErrorDomain] &&
error.code == RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously;
if (isCannotLoadSyncError) {
attemptAsynchronousLoadOfBundleAtURL(scriptURL, onProgress, onComplete);
} else {
onComplete(error, nil);
}
}
+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
sourceLength:(int64_t *)sourceLength
error:(NSError **)error
{
NSString *unsanitizedScriptURLString = scriptURL.absoluteString;
// Sanitize the script URL
scriptURL = sanitizeURL(scriptURL);
if (!scriptURL) {
if (error) {
*error = [NSError
errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorNoScriptURL
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"No script URL provided. Make sure the packager is "
@"running or you have embedded a JS bundle in your application bundle.\n\n"
@"unsanitizedScriptURLString = %@",
unsanitizedScriptURLString]
}];
}
return nil;
}
// Load local script file
if (!scriptURL.fileURL) {
if (error) {
*error = [NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously
userInfo:@{
NSLocalizedDescriptionKey :
[NSString stringWithFormat:@"Cannot load %@ URLs synchronously", scriptURL.scheme]
}];
}
return nil;
}
// Load the first 4 bytes to check if the bundle is regular or RAM ("Random Access Modules" bundle).
// The RAM bundle has a magic number in the 4 first bytes `(0xFB0BD1E5)`.
// The benefit of RAM bundle over a regular bundle is that we can lazily inject
// modules into JSC as they're required.
FILE *bundle = fopen(scriptURL.path.UTF8String, "r");
if (!bundle) {
if (error) {
*error = [NSError
errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorFailedOpeningFile
userInfo:@{
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening bundle %@", scriptURL.path]
}];
}
return nil;
}
facebook::react::BundleHeader header;
size_t readResult = fread(&header, sizeof(header), 1, bundle);
fclose(bundle);
if (readResult != 1) {
if (error) {
*error = [NSError
errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorFailedReadingFile
userInfo:@{
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error reading bundle %@", scriptURL.path]
}];
}
return nil;
}
facebook::react::ScriptTag tag = facebook::react::parseTypeFromHeader(header);
switch (tag) {
case facebook::react::ScriptTag::RAMBundle:
break;
case facebook::react::ScriptTag::String: {
#if RCT_ENABLE_INSPECTOR
NSData *source = [NSData dataWithContentsOfFile:scriptURL.path options:NSDataReadingMappedIfSafe error:error];
if (sourceLength && source != nil) {
*sourceLength = source.length;
}
return source;
#else
if (error) {
*error =
[NSError errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously
userInfo:@{NSLocalizedDescriptionKey : @"Cannot load text/javascript files synchronously"}];
}
return nil;
#endif
}
}
struct stat statInfo;
if (stat(scriptURL.path.UTF8String, &statInfo) != 0) {
if (error) {
*error = [NSError
errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorFailedStatingFile
userInfo:@{
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error stating bundle %@", scriptURL.path]
}];
}
return nil;
}
if (sourceLength) {
*sourceLength = statInfo.st_size;
}
return [NSData dataWithBytes:&header length:sizeof(header)];
}
static void parseHeaders(NSDictionary *headers, RCTSource *source)
{
source->_filesChangedCount = [headers[@"X-Metro-Files-Changed-Count"] integerValue];
}
static void attemptAsynchronousLoadOfBundleAtURL(
NSURL *scriptURL,
RCTSourceLoadProgressBlock onProgress,
RCTSourceLoadBlock onComplete)
{
scriptURL = sanitizeURL(scriptURL);
if (scriptURL.fileURL) {
// Reading in a large bundle can be slow. Dispatch to the background queue to do it.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error = nil;
NSData *source = [NSData dataWithContentsOfFile:scriptURL.path options:NSDataReadingMappedIfSafe error:&error];
onComplete(error, RCTSourceCreate(scriptURL, source, source.length));
});
return;
}
RCTMultipartDataTask *task = [[RCTMultipartDataTask alloc] initWithURL:scriptURL
partHandler:^(NSInteger statusCode, NSDictionary *headers, NSData *data, NSError *error, BOOL done) {
if (!done) {
if (onProgress) {
onProgress(progressEventFromData(data));
}
return;
}
// Handle general request errors
if (error) {
if ([error.domain isEqualToString:NSURLErrorDomain]) {
error = [NSError
errorWithDomain:RCTJavaScriptLoaderErrorDomain
code:RCTJavaScriptLoaderErrorURLLoadFailed
userInfo:@{
NSLocalizedDescriptionKey :
[@"Could not connect to development server.\n\n"
"Ensure the following:\n"
"- Node server is running and available on the same network - run 'npm start' from react-native root\n"
"- Node server URL is correctly set in AppDelegate\n"
"- WiFi is enabled and connected to the same network as the Node Server\n\n"
"URL: " stringByAppendingString:scriptURL.absoluteString],
NSLocalizedFailureReasonErrorKey : error.localizedDescription,
NSUnderlyingErrorKey : error,
}];
}
onComplete(error, nil);
return;
}
// For multipart responses packager sets X-Http-Status header in case HTTP status code
// is different from 200 OK
NSString *statusCodeHeader = headers[@"X-Http-Status"];
if (statusCodeHeader) {
statusCode = [statusCodeHeader integerValue];
}
if (statusCode != 200) {
error =
[NSError errorWithDomain:@"JSServer"
code:statusCode
userInfo:userInfoForRawResponse([[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding])];
onComplete(error, nil);
return;
}
// Validate that the packager actually returned javascript.
NSString *contentType = headers[@"Content-Type"];
NSString *mimeType = [[contentType componentsSeparatedByString:@";"] firstObject];
if (![mimeType isEqualToString:@"application/javascript"] && ![mimeType isEqualToString:@"text/javascript"]) {
NSString *description;
if ([mimeType isEqualToString:@"application/json"]) {
NSError *parseError;
NSDictionary *jsonError = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (!parseError && [jsonError isKindOfClass:[NSDictionary class]] &&
[[jsonError objectForKey:@"message"] isKindOfClass:[NSString class]] &&
[[jsonError objectForKey:@"message"] length]) {
description = [jsonError objectForKey:@"message"];
} else {
description = [NSString stringWithFormat:@"Unknown error fetching '%@'.", scriptURL.absoluteString];
}
} else {
description = [NSString
stringWithFormat:
@"Expected MIME-Type to be 'application/javascript' or 'text/javascript', but got '%@'.", mimeType];
}
error = [NSError
errorWithDomain:@"JSServer"
code:NSURLErrorCannotParseResponse
userInfo:@{NSLocalizedDescriptionKey : description, @"headers" : headers, @"data" : data}];
onComplete(error, nil);
return;
}
// Prefer `Content-Location` as the canonical source URL, if given, or fall back to scriptURL.
NSURL *sourceURL = scriptURL;
NSString *contentLocationHeader = headers[@"Content-Location"];
if (contentLocationHeader) {
NSURL *contentLocationURL = [NSURL URLWithString:contentLocationHeader relativeToURL:scriptURL];
if (contentLocationURL) {
sourceURL = contentLocationURL;
}
}
RCTSource *source = RCTSourceCreate(sourceURL, data, data.length);
parseHeaders(headers, source);
onComplete(nil, source);
}
progressHandler:^(NSDictionary *headers, NSNumber *loaded, NSNumber *total) {
NSString *contentType = headers[@"Content-Type"];
NSString *mimeType = [[contentType componentsSeparatedByString:@";"] firstObject];
// Only care about download progress events for the javascript bundle part.
if ([mimeType isEqualToString:@"application/javascript"] ||
[mimeType isEqualToString:@"application/x-metro-bytecode-bundle"]) {
onProgress(progressEventFromDownloadProgress(loaded, total));
}
}];
[task startTask];
}
static NSURL *sanitizeURL(NSURL *url)
{
// Why we do this is lost to time. We probably shouldn't; passing a valid URL is the caller's responsibility not ours.
return [RCTConvert NSURL:url.absoluteString];
}
static RCTLoadingProgress *progressEventFromData(NSData *rawData)
{
NSString *text = [[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding];
id info = RCTJSONParse(text, nil);
if (!info || ![info isKindOfClass:[NSDictionary class]]) {
return nil;
}
RCTLoadingProgress *progress = [RCTLoadingProgress new];
progress.status = info[@"status"];
progress.done = info[@"done"];
progress.total = info[@"total"];
return progress;
}
static RCTLoadingProgress *progressEventFromDownloadProgress(NSNumber *total, NSNumber *done)
{
RCTLoadingProgress *progress = [RCTLoadingProgress new];
progress.status = @"Downloading";
// Progress values are in bytes transform them to kilobytes for smaller numbers.
progress.done = done != nil ? @([done integerValue] / 1024) : nil;
progress.total = total != nil ? @([total integerValue] / 1024) : nil;
return progress;
}
static NSDictionary *userInfoForRawResponse(NSString *rawText)
{
NSDictionary *parsedResponse = RCTJSONParse(rawText, nil);
if (![parsedResponse isKindOfClass:[NSDictionary class]]) {
return @{NSLocalizedDescriptionKey : rawText};
}
NSArray *errors = parsedResponse[@"errors"];
if (![errors isKindOfClass:[NSArray class]]) {
return @{NSLocalizedDescriptionKey : rawText};
}
NSMutableArray<NSDictionary *> *fakeStack = [NSMutableArray new];
for (NSDictionary *err in errors) {
[fakeStack addObject:@{
@"methodName" : err[@"description"] ?: @"",
@"file" : err[@"filename"] ?: @"",
@"lineNumber" : err[@"lineNumber"] ?: @0
}];
}
return
@{NSLocalizedDescriptionKey : parsedResponse[@"message"] ?: @"No message provided", @"stack" : [fakeStack copy]};
}
@end

31
node_modules/react-native/React/Base/RCTKeyCommands.h generated vendored Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
@interface RCTKeyCommands : NSObject
+ (instancetype)sharedInstance;
/**
* Register a keyboard command.
*/
- (void)registerKeyCommandWithInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
action:(void (^)(UIKeyCommand *command))block;
/**
* Unregister a keyboard command.
*/
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
/**
* Check if a command is registered.
*/
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
@end

275
node_modules/react-native/React/Base/RCTKeyCommands.m generated vendored Normal file
View File

@@ -0,0 +1,275 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTKeyCommands.h"
#import <UIKit/UIKit.h>
#import <objc/message.h>
#import <objc/runtime.h>
#import "RCTDefines.h"
#import "RCTUtils.h"
#if RCT_DEV && (TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST)
@interface UIEvent (UIPhysicalKeyboardEvent)
@property (nonatomic) NSString *_modifiedInput;
@property (nonatomic) NSString *_unmodifiedInput;
@property (nonatomic) UIKeyModifierFlags _modifierFlags;
@property (nonatomic) BOOL _isKeyDown;
@property (nonatomic) long _keyCode;
@end
@interface RCTKeyCommand : NSObject <NSCopying>
@property (nonatomic, copy, readonly) NSString *key;
@property (nonatomic, readonly) UIKeyModifierFlags flags;
@property (nonatomic, copy) void (^block)(UIKeyCommand *);
@end
@implementation RCTKeyCommand
- (instancetype)init:(NSString *)key flags:(UIKeyModifierFlags)flags block:(void (^)(UIKeyCommand *))block
{
if ((self = [super init])) {
_key = key;
_flags = flags;
_block = block;
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (id)copyWithZone:(__unused NSZone *)zone
{
return self;
}
- (NSUInteger)hash
{
return _key.hash ^ _flags;
}
- (BOOL)isEqual:(RCTKeyCommand *)object
{
if (![object isKindOfClass:[RCTKeyCommand class]]) {
return NO;
}
return [self matchesInput:object.key flags:object.flags];
}
- (BOOL)matchesInput:(NSString *)input flags:(UIKeyModifierFlags)flags
{
// We consider the key command a match if the modifier flags match
// exactly or is there are no modifier flags. This means that for
// `cmd + r`, we will match both `cmd + r` and `r` but not `opt + r`.
return [_key isEqual:input] && (_flags == flags || flags == 0);
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@:%p input=\"%@\" flags=%lld hasBlock=%@>",
[self class],
self,
_key,
(long long)_flags,
_block ? @"YES" : @"NO"];
}
@end
@interface RCTKeyCommands ()
@property (nonatomic, strong) NSMutableSet<RCTKeyCommand *> *commands;
@end
@implementation RCTKeyCommands
+ (void)initialize
{
SEL originalKeyEventSelector = NSSelectorFromString(@"handleKeyUIEvent:");
SEL swizzledKeyEventSelector = NSSelectorFromString(
[NSString stringWithFormat:@"_rct_swizzle_%x_%@", arc4random(), NSStringFromSelector(originalKeyEventSelector)]);
void (^handleKeyUIEventSwizzleBlock)(UIApplication *, UIEvent *) = ^(UIApplication *slf, UIEvent *event) {
[[[self class] sharedInstance] handleKeyUIEventSwizzle:event];
((void (*)(id, SEL, id))objc_msgSend)(slf, swizzledKeyEventSelector, event);
};
RCTSwapInstanceMethodWithBlock(
[UIApplication class], originalKeyEventSelector, handleKeyUIEventSwizzleBlock, swizzledKeyEventSelector);
}
- (void)handleKeyUIEventSwizzle:(UIEvent *)event
{
NSString *modifiedInput = nil;
UIKeyModifierFlags modifierFlags = 0;
BOOL isKeyDown = NO;
if ([event respondsToSelector:@selector(_modifiedInput)]) {
modifiedInput = [event _modifiedInput];
}
if ([event respondsToSelector:@selector(_modifierFlags)]) {
modifierFlags = [event _modifierFlags];
}
if ([event respondsToSelector:@selector(_isKeyDown)]) {
isKeyDown = [event _isKeyDown];
}
if (isKeyDown && modifiedInput.length > 0) {
UIResponder *firstResponder = nil;
for (UIWindow *window in [self allWindows]) {
firstResponder = [window valueForKey:@"firstResponder"];
if (firstResponder) {
break;
}
}
// Ignore key commands (except escape) when there's an active responder
if (!firstResponder) {
[self RCT_handleKeyCommand:modifiedInput flags:modifierFlags];
}
}
};
- (NSArray<UIWindow *> *)allWindows
{
BOOL includeInternalWindows = YES;
BOOL onlyVisibleWindows = NO;
// Obfuscating selector allWindowsIncludingInternalWindows:onlyVisibleWindows:
NSArray<NSString *> *allWindowsComponents =
@[ @"al", @"lWindo", @"wsIncl", @"udingInt", @"ernalWin", @"dows:o", @"nlyVisi", @"bleWin", @"dows:" ];
SEL allWindowsSelector = NSSelectorFromString([allWindowsComponents componentsJoinedByString:@""]);
NSMethodSignature *methodSignature = [[UIWindow class] methodSignatureForSelector:allWindowsSelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
invocation.target = [UIWindow class];
invocation.selector = allWindowsSelector;
[invocation setArgument:&includeInternalWindows atIndex:2];
[invocation setArgument:&onlyVisibleWindows atIndex:3];
[invocation invoke];
__unsafe_unretained NSArray<UIWindow *> *windows = nil;
[invocation getReturnValue:&windows];
return windows;
}
- (void)RCT_handleKeyCommand:(NSString *)input flags:(UIKeyModifierFlags)modifierFlags
{
// In Bridgeless mode we might incur in some concurrency issues
// where the React Native instance is invalidated while iterating on the
// list of available commands.
// That will cleanup the set while iterating, which is a not allowed mutation.
// To work around that, we store the commands that we need to execute in a separate
// array, local to this function call, so we don't incur in concurrency issues
NSMutableArray<RCTKeyCommand *> *commandsToExecute = [NSMutableArray new];
for (RCTKeyCommand *command in [RCTKeyCommands sharedInstance].commands) {
if ([command matchesInput:input flags:modifierFlags]) {
if (command.block) {
[commandsToExecute addObject:command];
}
}
}
for (RCTKeyCommand *command in commandsToExecute) {
command.block(nil);
}
}
+ (instancetype)sharedInstance
{
static RCTKeyCommands *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [self new];
});
return sharedInstance;
}
- (instancetype)init
{
if ((self = [super init])) {
_commands = [NSMutableSet new];
}
return self;
}
- (void)registerKeyCommandWithInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
action:(void (^)(UIKeyCommand *))block
{
RCTAssertMainQueue();
RCTKeyCommand *keyCommand = [[RCTKeyCommand alloc] init:input flags:flags block:block];
[_commands removeObject:keyCommand];
[_commands addObject:keyCommand];
}
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
{
RCTAssertMainQueue();
for (RCTKeyCommand *command in _commands.allObjects) {
if ([command matchesInput:input flags:flags]) {
[_commands removeObject:command];
break;
}
}
}
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
{
RCTAssertMainQueue();
for (RCTKeyCommand *command in _commands) {
if ([command matchesInput:input flags:flags]) {
return YES;
}
}
return NO;
}
@end
#else
@implementation RCTKeyCommands
+ (instancetype)sharedInstance
{
return nil;
}
- (void)registerKeyCommandWithInput:(NSString *)input
modifierFlags:(UIKeyModifierFlags)flags
action:(void (^)(UIKeyCommand *))block
{
}
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
{
}
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags
{
return NO;
}
@end
#endif

155
node_modules/react-native/React/Base/RCTLog.h generated vendored Normal file
View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTAssert.h>
#import <React/RCTDefines.h>
#import <React/RCTUtils.h>
@class RCTModuleRegistry;
@class RCTCallableJSModules;
#ifndef RCTLOG_ENABLED
#define RCTLOG_ENABLED 1
#endif
/**
* Thresholds for logs to display a redbox. You can override these values when debugging
* in order to tweak the default logging behavior.
*/
#ifndef RCTLOG_REDBOX_LEVEL
#define RCTLOG_REDBOX_LEVEL RCTLogLevelError
#endif
/**
* Logging macros. Use these to log information, warnings and errors in your
* own code.
*/
#define RCTLog(...) _RCTLog(RCTLogLevelInfo, __VA_ARGS__)
#define RCTLogTrace(...) _RCTLog(RCTLogLevelTrace, __VA_ARGS__)
#define RCTLogInfo(...) _RCTLog(RCTLogLevelInfo, __VA_ARGS__)
#define RCTLogAdvice(string, ...) RCTLogWarn([@"(ADVICE) " stringByAppendingString:(NSString *)string], __VA_ARGS__)
#define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__)
#define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__)
/**
* An enum representing the severity of the log message.
*/
typedef NS_ENUM(NSInteger, RCTLogLevel) {
RCTLogLevelTrace = 0,
RCTLogLevelInfo = 1,
RCTLogLevelWarning = 2,
RCTLogLevelError = 3,
RCTLogLevelFatal = 4
};
/**
* An enum representing the source of a log message.
*/
typedef NS_ENUM(NSInteger, RCTLogSource) { RCTLogSourceNative = 1, RCTLogSourceJavaScript = 2 };
/**
* A block signature to be used for custom logging functions. In most cases you
* will want to pass these arguments to the RCTFormatLog function in order to
* generate a string.
*/
typedef void (^RCTLogFunction)(
RCTLogLevel level,
RCTLogSource source,
NSString *fileName,
NSNumber *lineNumber,
NSString *message);
/**
* A method to generate a string from a collection of log data. To omit any
* particular data from the log, just pass nil or zero for the argument.
*/
RCT_EXTERN NSString *
RCTFormatLog(NSDate *timestamp, RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message);
/**
* A method to generate a string RCTLogLevel
*/
RCT_EXTERN NSString *RCTFormatLogLevel(RCTLogLevel /*level*/);
/**
* A method to generate a string from a RCTLogSource
*/
RCT_EXTERN NSString *RCTFormatLogSource(RCTLogSource /*source*/);
/**
* The default logging function used by RCTLogXX.
*/
extern RCTLogFunction RCTDefaultLogFunction;
/**
* These methods get and set the global logging threshold. This is the level
* below which logs will be ignored. Default is RCTLogLevelInfo for debug and
* RCTLogLevelError for production.
*/
RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold);
RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void);
/**
* These methods get and set the global logging function called by the RCTLogXX
* macros. You can use these to replace the standard behavior with custom log
* functionality.
*/
RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction);
RCT_EXTERN RCTLogFunction RCTGetLogFunction(void);
/**
* This appends additional code to the existing log function, without replacing
* the existing functionality. Useful if you just want to forward logs to an
* extra service without changing the default behavior.
*/
RCT_EXTERN void RCTAddLogFunction(RCTLogFunction logFunction);
/**
* This method temporarily overrides the log function while performing the
* specified block. This is useful for testing purposes (to detect if a given
* function logs something) or to suppress or override logging temporarily.
*/
RCT_EXTERN void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction);
/**
* This method adds a conditional prefix to any messages logged within the scope
* of the passed block. This is useful for adding additional context to log
* messages. The block will be performed synchronously on the current thread.
*/
RCT_EXTERN void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix);
/**
* These methods allows static methods in RCTLog to call NativeModules and TurboModules.
* TODO(T112035275) After Bridgeless mixed mode is removed, we can merge these methods
*/
RCT_EXTERN void RCTLogSetBridgeModuleRegistry(RCTModuleRegistry *moduleRegistry);
RCT_EXTERN void RCTLogSetBridgelessModuleRegistry(RCTModuleRegistry *moduleRegistry);
/**
* This methods allows static methods in RCTLog to call JS methods.
* TODO(T112035275) After Bridgeless mixed mode is removed, we can merge these methods
*/
RCT_EXTERN void RCTLogSetBridgeCallableJSModules(RCTCallableJSModules *callableJSModules);
RCT_EXTERN void RCTLogSetBridgelessCallableJSModules(RCTCallableJSModules *callableJSModules);
/**
* Private logging function - ignore this.
*/
#if RCTLOG_ENABLED
#define _RCTLog(lvl, ...) _RCTLogNativeInternal(lvl, __FILE__, __LINE__, __VA_ARGS__)
#else
#define _RCTLog(lvl, ...) \
do { \
} while (0)
#endif
RCT_EXTERN void
_RCTLogNativeInternal(RCTLogLevel /*level*/, const char * /*fileName*/, int /*lineNumber*/, NSString * /*format*/, ...)
NS_FORMAT_FUNCTION(4, 5);
RCT_EXTERN void _RCTLogJavaScriptInternal(RCTLogLevel /*level*/, NSString * /*message*/);

337
node_modules/react-native/React/Base/RCTLog.mm generated vendored Normal file
View File

@@ -0,0 +1,337 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTLog.h"
#include <cxxabi.h>
#import <objc/message.h>
#import <os/log.h>
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTDefines.h"
#import "RCTRedBoxSetEnabled.h"
#import "RCTUtils.h"
static NSString *const RCTLogFunctionStack = @"RCTLogFunctionStack";
const char *RCTLogLevels[] = {
"trace",
"info",
"warn",
"error",
"fatal",
};
/* os log will discard debug and info messages if they are not needed */
static const RCTLogLevel RCTDefaultLogThreshold = (RCTLogLevel)(RCTLogLevelInfo - 1);
static RCTLogFunction RCTCurrentLogFunction;
static RCTLogLevel RCTCurrentLogThreshold = RCTDefaultLogThreshold;
static __weak RCTModuleRegistry *RCTLogBridgeModuleRegistry;
static __weak RCTModuleRegistry *RCTLogBridgelessModuleRegistry;
static __weak RCTCallableJSModules *RCTLogBridgeCallableJSModules;
static __weak RCTCallableJSModules *RCTLogBridgelessCallableJSModules;
RCTLogLevel RCTGetLogThreshold()
{
return RCTCurrentLogThreshold;
}
void RCTSetLogThreshold(RCTLogLevel threshold)
{
RCTCurrentLogThreshold = threshold;
}
void RCTLogSetBridgeModuleRegistry(RCTModuleRegistry *moduleRegistry)
{
RCTLogBridgeModuleRegistry = moduleRegistry;
}
void RCTLogSetBridgelessModuleRegistry(RCTModuleRegistry *moduleRegistry)
{
RCTLogBridgelessModuleRegistry = moduleRegistry;
}
void RCTLogSetBridgeCallableJSModules(RCTCallableJSModules *callableJSModules)
{
RCTLogBridgeCallableJSModules = callableJSModules;
}
void RCTLogSetBridgelessCallableJSModules(RCTCallableJSModules *callableJSModules)
{
RCTLogBridgelessCallableJSModules = callableJSModules;
}
static os_log_type_t RCTLogTypeForLogLevel(RCTLogLevel logLevel)
{
if (logLevel < RCTLogLevelInfo) {
return OS_LOG_TYPE_DEBUG;
} else if (logLevel <= RCTLogLevelWarning) {
return OS_LOG_TYPE_INFO;
} else {
return OS_LOG_TYPE_ERROR;
}
}
static os_log_t RCTLogForLogSource(RCTLogSource source)
{
switch (source) {
case RCTLogSourceNative: {
static os_log_t nativeLog;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
nativeLog = os_log_create("com.facebook.react.log", "native");
});
return nativeLog;
}
case RCTLogSourceJavaScript: {
static os_log_t javaScriptLog;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
javaScriptLog = os_log_create("com.facebook.react.log", "javascript");
});
return javaScriptLog;
}
}
}
RCTLogFunction RCTDefaultLogFunction =
^(RCTLogLevel level,
RCTLogSource source,
__unused NSString *fileName,
__unused NSNumber *lineNumber,
NSString *message) {
os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String);
};
void RCTSetLogFunction(RCTLogFunction logFunction)
{
RCTCurrentLogFunction = logFunction;
}
RCTLogFunction RCTGetLogFunction()
{
if (!RCTCurrentLogFunction) {
RCTCurrentLogFunction = RCTDefaultLogFunction;
}
return RCTCurrentLogFunction;
}
void RCTAddLogFunction(RCTLogFunction logFunction)
{
RCTLogFunction existing = RCTGetLogFunction();
if (existing) {
RCTSetLogFunction(
^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
existing(level, source, fileName, lineNumber, message);
logFunction(level, source, fileName, lineNumber, message);
});
} else {
RCTSetLogFunction(logFunction);
}
}
/**
* returns the topmost stacked log function for the current thread, which
* may not be the same as the current value of RCTCurrentLogFunction.
*/
static RCTLogFunction RCTGetLocalLogFunction()
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSArray<RCTLogFunction> *functionStack = threadDictionary[RCTLogFunctionStack];
RCTLogFunction logFunction = functionStack.lastObject;
if (logFunction) {
return logFunction;
}
return RCTGetLogFunction();
}
void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction)
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSMutableArray<RCTLogFunction> *functionStack = threadDictionary[RCTLogFunctionStack];
if (!functionStack) {
functionStack = [NSMutableArray new];
threadDictionary[RCTLogFunctionStack] = functionStack;
}
[functionStack addObject:logFunction];
block();
[functionStack removeLastObject];
}
void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
if (logFunction) {
RCTPerformBlockWithLogFunction(
block, ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
logFunction(level, source, fileName, lineNumber, [prefix stringByAppendingString:message]);
});
}
}
NSString *
RCTFormatLog(NSDate *timestamp, RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message)
{
NSMutableString *log = [NSMutableString new];
if (timestamp) {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [NSDateFormatter new];
formatter.dateFormat = formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS ";
});
[log appendString:[formatter stringFromDate:timestamp]];
}
if (level) {
[log appendFormat:@"[%s]", RCTLogLevels[level]];
}
[log appendFormat:@"[tid:%@]", RCTCurrentThreadName()];
if (fileName) {
fileName = fileName.lastPathComponent;
if (lineNumber) {
[log appendFormat:@"[%@:%@]", fileName, lineNumber];
} else {
[log appendFormat:@"[%@]", fileName];
}
}
if (message) {
[log appendString:@" "];
[log appendString:message];
}
return log;
}
NSString *RCTFormatLogLevel(RCTLogLevel level)
{
NSDictionary *levelsToString = @{
@(RCTLogLevelTrace) : @"trace",
@(RCTLogLevelInfo) : @"info",
@(RCTLogLevelWarning) : @"warning",
@(RCTLogLevelFatal) : @"fatal",
@(RCTLogLevelError) : @"error"
};
return levelsToString[@(level)];
}
NSString *RCTFormatLogSource(RCTLogSource source)
{
NSDictionary *sourcesToString = @{@(RCTLogSourceNative) : @"native", @(RCTLogSourceJavaScript) : @"js"};
return sourcesToString[@(source)];
}
static NSRegularExpression *nativeStackFrameRegex()
{
static dispatch_once_t onceToken;
static NSRegularExpression *_regex;
dispatch_once(&onceToken, ^{
NSError *regexError;
_regex = [NSRegularExpression regularExpressionWithPattern:@"0x[0-9a-f]+ (.*) \\+ (\\d+)$"
options:0
error:&regexError];
if (regexError) {
RCTLogError(@"Failed to build regex: %@", [regexError localizedDescription]);
}
});
return _regex;
}
void _RCTLogNativeInternal(RCTLogLevel level, const char *fileName, int lineNumber, NSString *format, ...)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
BOOL log = RCT_DEBUG || (logFunction != nil);
if (log && level >= RCTGetLogThreshold()) {
// Get message
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
// Call log function
if (logFunction) {
logFunction(
level, RCTLogSourceNative, fileName ? @(fileName) : nil, lineNumber > 0 ? @(lineNumber) : nil, message);
}
// Log to red box if one is configured.
if (RCTSharedApplication() && RCTRedBoxGetEnabled() && level >= RCTLOG_REDBOX_LEVEL) {
NSArray<NSString *> *stackSymbols = [NSThread callStackSymbols];
NSMutableArray<NSDictionary *> *stack = [NSMutableArray arrayWithCapacity:(stackSymbols.count - 1)];
[stackSymbols enumerateObjectsUsingBlock:^(NSString *frameSymbols, NSUInteger idx, __unused BOOL *stop) {
if (idx == 0) {
// don't include the current frame
return;
}
NSRange range = NSMakeRange(0, frameSymbols.length);
NSTextCheckingResult *match = [nativeStackFrameRegex() firstMatchInString:frameSymbols options:0 range:range];
if (!match) {
return;
}
NSString *methodName = [frameSymbols substringWithRange:[match rangeAtIndex:1]];
char *demangledName = abi::__cxa_demangle([methodName UTF8String], NULL, NULL, NULL);
if (demangledName) {
methodName = @(demangledName);
free(demangledName);
}
if (idx == 1 && fileName) {
NSString *file = [@(fileName) componentsSeparatedByString:@"/"].lastObject;
[stack addObject:@{@"methodName" : methodName, @"file" : file, @"lineNumber" : @(lineNumber)}];
} else {
[stack addObject:@{@"methodName" : methodName}];
}
}];
dispatch_async(dispatch_get_main_queue(), ^{
// red box is thread safe, but by deferring to main queue we avoid a startup
// race condition that causes the module to be accessed before it has loaded
RCTModuleRegistry *moduleRegistry = RCTLogBridgeModuleRegistry ?: RCTLogBridgelessModuleRegistry;
id redbox = [moduleRegistry moduleForName:"RedBox" lazilyLoadIfNecessary:YES];
if (redbox) {
void (*showErrorMessage)(id, SEL, NSString *, NSMutableArray<NSDictionary *> *) =
(__typeof__(showErrorMessage))objc_msgSend;
SEL showErrorMessageSEL = NSSelectorFromString(@"showErrorMessage:withStack:");
if ([redbox respondsToSelector:showErrorMessageSEL]) {
showErrorMessage(redbox, showErrorMessageSEL, message, stack);
}
}
});
}
#if RCT_DEBUG
if (!RCTRunningInTestEnvironment()) {
// Log to JS executor
NSString *levelString = level ? @(RCTLogLevels[level]) : @"info";
RCTCallableJSModules *callableModule = RCTLogBridgeCallableJSModules ?: RCTLogBridgelessCallableJSModules;
[callableModule invokeModule:@"RCTLog" method:@"logIfNoNativeHook" withArgs:@[ levelString, message ]];
}
#endif
}
}
void _RCTLogJavaScriptInternal(RCTLogLevel level, NSString *message)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
BOOL log = RCT_DEBUG || (logFunction != nil);
if (log && level >= RCTGetLogThreshold()) {
if (logFunction) {
logFunction(level, RCTLogSourceJavaScript, nil, nil, message);
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifdef __cplusplus
#include <memory>
#import <Foundation/Foundation.h>
/**
* Type erased wrapper over any cxx value that can be passed as an argument
* to native method.
*/
@interface RCTManagedPointer : NSObject
@property (nonatomic, readonly) void *voidPointer;
- (instancetype)initWithPointer:(std::shared_ptr<void>)pointer;
@end
namespace facebook::react {
template <typename T, typename P>
RCTManagedPointer *managedPointer(P initializer)
{
auto ptr = std::shared_ptr<void>(new T(initializer));
return [[RCTManagedPointer alloc] initWithPointer:std::move(ptr)];
}
} // namespace facebook::react
#endif

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTManagedPointer.h"
@implementation RCTManagedPointer {
std::shared_ptr<void> _pointer;
}
- (instancetype)initWithPointer:(std::shared_ptr<void>)pointer
{
if (self = [super init]) {
_pointer = std::move(pointer);
}
return self;
}
- (void *)voidPointer
{
return _pointer.get();
}
@end

58
node_modules/react-native/React/Base/RCTMockDef.h generated vendored Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
/* These macros are used to stub C functions. Here's an example:
*
* Helpers.h
* ------
* boolean ReturnsTrueOrFalse(void);
*
* FileToBeTested.h
* ------
* RCT_MOCK_DEF(Testing, ReturnsTrueOrFalse);
* #define ReturnsTrueOrFalse RCT_MOCK_USE(Testing, ReturnsTrueOrFalse)
*
* int FunctionToBeTested(int input) {
* return ReturnsTrueOrFalse() ? input + 1 : input - 1;
* }
*
* Test.h
* -----
* RCT_MOCK_GET(Testing, ReturnsTrueOrFalse);
*
* boolean _ReturnsTrue(void) { return true; }
* boolean _ReturnsFalse(void) { return false; }
*
* void TestFunctionTrue(void) {
* RCT_MOCK_SET(Testing, ReturnsTrueOrFalse, _ReturnsTrue);
* assert(FunctionToBeTested(5) == 6);
* RCT_MOCK_RESET(Testing, ReturnsTrueOrFalse);
* }
*
* void TestFunctionFalse(void) {
* RCT_MOCK_SET(Testing, ReturnsTrueOrFalse, _ReturnsFalse);
* assert(FunctionToBeTested(5) == 4);
* RCT_MOCK_RESET(Testing, ReturnsTrueOrFalse);
* }
*
*/
#ifdef RCT_DEV
#define RCT_MOCK_DEF(context, api) __typeof(__typeof(api) *) mockptr_##context##_##api = &api;
#define RCT_MOCK_REF(context, api) extern __typeof(__typeof(api) *) mockptr_##context##_##api;
#define RCT_MOCK_SET(context, api, mockapi) (mockptr_##context##_##api = &mockapi)
#define RCT_MOCK_RESET(context, api) (mockptr_##context##_##api = &api)
#define RCT_MOCK_USE(context, api) (*mockptr_##context##_##api)
#else
#define RCT_MOCK_DEF(context, api)
#define RCT_MOCK_REF(context, api)
#define RCT_MOCK_SET(context, api, mockapi)
#define RCT_MOCK_RESET(context, api)
#define RCT_MOCK_USE(context, api) api
#endif

123
node_modules/react-native/React/Base/RCTModuleData.h generated vendored Normal file
View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTInvalidating.h>
@protocol RCTBridgeMethod;
@protocol RCTBridgeModule;
@class RCTBridge;
@class RCTModuleData;
@class RCTModuleRegistry;
@class RCTViewRegistry;
@class RCTBundleManager;
@class RCTCallableJSModules;
@class RCTCallInvoker;
typedef id<RCTBridgeModule> (^RCTBridgeModuleProvider)(void);
@protocol RCTModuleDataCallInvokerProvider <NSObject>
- (RCTCallInvoker *)callInvokerForModuleData:(RCTModuleData *)moduleData;
@end
@interface RCTModuleData : NSObject <RCTInvalidating>
- (instancetype)initWithModuleClass:(Class)moduleClass
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER
__deprecated_msg("This API will be removed along with the legacy architecture.");
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER
__deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Calls `constantsToExport` on the module and stores the result. Note that
* this will init the module if it has not already been created. This method
* can be called on any thread, but may block the main thread briefly if the
* module implements `constantsToExport`.
*/
- (void)gatherConstants __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, strong, readonly)
Class moduleClass __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, copy, readonly)
NSString *name __deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Returns the module methods. Note that this will gather the methods the first
* time it is called and then memoize the results.
*/
@property (nonatomic, copy, readonly) NSArray<id<RCTBridgeMethod>> *methods __deprecated_msg(
"This API will be removed along with the legacy architecture.");
/**
* Returns a map of the module methods. Note that this will gather the methods the first
* time it is called and then memoize the results.
*/
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id<RCTBridgeMethod>> *methodsByName __deprecated_msg(
"This API will be removed along with the legacy architecture.");
/**
* Returns the module's constants, if it exports any
*/
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *exportedConstants __deprecated_msg(
"This API will be removed along with the legacy architecture.");
/**
* Returns YES if module instance has already been initialized; NO otherwise.
*/
@property (nonatomic, assign, readonly)
BOOL hasInstance __deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Returns YES if module instance must be created on the main thread.
*/
@property (nonatomic, assign)
BOOL requiresMainQueueSetup __deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Returns YES if module has constants to export.
*/
@property (nonatomic, assign, readonly)
BOOL hasConstantsToExport __deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Returns the current module instance. Note that this will init the instance
* if it has not already been created. To check if the module instance exists
* without causing it to be created, use `hasInstance` instead.
*/
@property (nonatomic, strong, readwrite) id<RCTBridgeModule> instance __deprecated_msg(
"This API will be removed along with the legacy architecture.");
/**
* Returns the module method dispatch queue. Note that this will init both the
* queue and the module itself if they have not already been created.
*/
@property (nonatomic, strong, readonly)
dispatch_queue_t methodQueue __deprecated_msg("This API will be removed along with the legacy architecture.");
/**
* Whether the receiver has a valid `instance` which implements -batchDidComplete.
*/
@property (nonatomic, assign, readonly)
BOOL implementsBatchDidComplete __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, weak, readwrite) id<RCTModuleDataCallInvokerProvider> callInvokerProvider __deprecated_msg(
"This API will be removed along with the legacy architecture.");
@end

524
node_modules/react-native/React/Base/RCTModuleData.mm generated vendored Normal file
View File

@@ -0,0 +1,524 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTModuleData.h"
#ifndef RCT_REMOVE_LEGACY_ARCH
#import <objc/runtime.h>
#import <atomic>
#import <mutex>
#import <reactperflogger/BridgeNativeModulePerfLogger.h>
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTBridgeModuleDecorator.h"
#import "RCTCallInvokerModule.h"
#import "RCTConstants.h"
#import "RCTInitializing.h"
#import "RCTLog.h"
#import "RCTModuleMethod.h"
#import "RCTProfile.h"
#import "RCTUtils.h"
using namespace facebook::react;
namespace {
int32_t getUniqueId()
{
static std::atomic<int32_t> counter{0};
return counter++;
}
} // namespace
@implementation RCTModuleData {
NSDictionary<NSString *, id> *_constantsToExport;
NSString *_queueName;
__weak RCTBridge *_bridge;
RCTBridgeModuleProvider _moduleProvider;
std::mutex _instanceLock;
BOOL _setupComplete;
RCTModuleRegistry *_moduleRegistry;
RCTViewRegistry *_viewRegistry_DEPRECATED;
RCTBundleManager *_bundleManager;
RCTCallableJSModules *_callableJSModules;
BOOL _isInitialized;
}
@synthesize methods = _methods;
@synthesize methodsByName = _methodsByName;
@synthesize instance = _instance;
@synthesize methodQueue = _methodQueue;
- (void)_setUpWithBridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
// start with the ivars
{
_bridge = bridge;
_moduleRegistry = moduleRegistry;
_viewRegistry_DEPRECATED = viewRegistry_DEPRECATED;
_bundleManager = bundleManager;
_callableJSModules = callableJSModules;
}
_implementsBatchDidComplete = [_moduleClass instancesRespondToSelector:@selector(batchDidComplete)];
// If a module overrides `constantsToExport` and doesn't implement `requiresMainQueueSetup`, then we must assume
// that it must be called on the main thread, because it may need to access UIKit.
_hasConstantsToExport = [_moduleClass instancesRespondToSelector:@selector(constantsToExport)];
const BOOL implementsRequireMainQueueSetup = [_moduleClass respondsToSelector:@selector(requiresMainQueueSetup)];
if (implementsRequireMainQueueSetup) {
_requiresMainQueueSetup = [_moduleClass requiresMainQueueSetup];
} else {
static IMP objectInitMethod;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
objectInitMethod = [NSObject instanceMethodForSelector:@selector(init)];
});
// If a module overrides `init` then we must assume that it expects to be
// initialized on the main thread, because it may need to access UIKit.
const BOOL hasCustomInit =
!_instance && [_moduleClass instanceMethodForSelector:@selector(init)] != objectInitMethod;
_requiresMainQueueSetup = _hasConstantsToExport || hasCustomInit;
}
}
- (instancetype)initWithModuleClass:(Class)moduleClass
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
if (self = [super init]) {
_moduleClass = moduleClass;
_moduleProvider = [^id<RCTBridgeModule> {
return [moduleClass new];
} copy];
[self _setUpWithBridge:bridge
moduleRegistry:moduleRegistry
viewRegistry_DEPRECATED:viewRegistry_DEPRECATED
bundleManager:bundleManager
callableJSModules:callableJSModules];
}
return self;
}
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
if (self = [super init]) {
_instance = instance;
_moduleClass = [instance class];
[self _setUpWithBridge:bridge
moduleRegistry:moduleRegistry
viewRegistry_DEPRECATED:viewRegistry_DEPRECATED
bundleManager:bundleManager
callableJSModules:callableJSModules];
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)init);
#pragma mark - private setup methods
- (void)setUpInstanceAndBridge:(int32_t)requestId
{
NSString *moduleName = [self name];
RCT_PROFILE_BEGIN_EVENT(
RCTProfileTagAlways,
@"[RCTModuleData setUpInstanceAndBridge]",
@{@"moduleClass" : NSStringFromClass(_moduleClass)});
{
std::unique_lock<std::mutex> lock(_instanceLock);
BOOL shouldSetup = !_setupComplete && _bridge.valid;
if (shouldSetup) {
if (!_instance) {
if (RCT_DEBUG && _requiresMainQueueSetup) {
RCTAssertMainQueue();
}
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil);
BridgeNativeModulePerfLogger::moduleCreateConstructStart([moduleName UTF8String], requestId);
_instance = _moduleProvider ? _moduleProvider() : nil;
BridgeNativeModulePerfLogger::moduleCreateConstructEnd([moduleName UTF8String], requestId);
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
if (!_instance) {
// Module init returned nil, probably because automatic instantiation
// of the module is not supported, and it is supposed to be passed in to
// the bridge constructor. Mark setup complete to avoid doing more work.
_setupComplete = YES;
RCTLogWarn(
@"The module %@ is returning nil from its constructor. You "
"may need to instantiate it yourself and pass it into the "
"bridge.",
_moduleClass);
}
}
if (_instance && RCTProfileIsProfiling()) {
RCTProfileHookInstance(_instance);
}
}
if (_instance) {
BridgeNativeModulePerfLogger::moduleCreateSetUpStart([moduleName UTF8String], requestId);
}
if (shouldSetup) {
// Bridge must be set before methodQueue is set up, as methodQueue
// initialization requires it (View Managers get their queue by calling
// self.bridge.uiManager.methodQueue)
[self setBridgeForInstance];
RCTBridgeModuleDecorator *moduleDecorator =
[[RCTBridgeModuleDecorator alloc] initWithViewRegistry:_viewRegistry_DEPRECATED
moduleRegistry:_moduleRegistry
bundleManager:_bundleManager
callableJSModules:_callableJSModules];
[moduleDecorator attachInteropAPIsToModule:_instance];
// This is a more performant alternative for conformsToProtocol:@protocol(RCTCallInvokerModule)
if ([_instance respondsToSelector:@selector(setCallInvoker:)]) {
[(id<RCTCallInvokerModule>)_instance setCallInvoker:[self.callInvokerProvider callInvokerForModuleData:self]];
}
}
[self setUpMethodQueue];
if (shouldSetup) {
[self _initializeModule];
}
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
// This is called outside of the lock in order to prevent deadlock issues
// because the logic in `finishSetupForInstance` can cause
// `moduleData.instance` to be accessed re-entrantly.
if (_bridge.moduleSetupComplete) {
[self finishSetupForInstance];
} else {
// If we're here, then the module is completely initialized,
// except for what finishSetupForInstance does. When the instance
// method is called after moduleSetupComplete,
// finishSetupForInstance will run. If _requiresMainQueueSetup
// is true, getting the instance will block waiting for the main
// thread, which could take a while if the main thread is busy
// (I've seen 50ms in testing). So we clear that flag, since
// nothing in finishSetupForInstance needs to be run on the main
// thread.
_requiresMainQueueSetup = NO;
}
if (_instance) {
BridgeNativeModulePerfLogger::moduleCreateSetUpEnd([moduleName UTF8String], requestId);
}
}
- (void)setBridgeForInstance
{
if ([_instance respondsToSelector:@selector(bridge)] && _instance.bridge != _bridge) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setBridgeForInstance]", nil);
@try {
[(id)_instance setValue:_bridge forKey:@"bridge"];
} @catch (NSException *exception) {
RCTLogError(
@"%@ has no setter or ivar for its bridge, which is not "
"permitted. You must either @synthesize the bridge property, "
"or provide your own setter method.",
self.name);
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
}
- (void)_initializeModule
{
if (!_isInitialized && [_instance respondsToSelector:@selector(initialize)]) {
_isInitialized = YES;
[(id<RCTInitializing>)_instance initialize];
}
}
- (void)finishSetupForInstance
{
if (!_setupComplete && _instance) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData finishSetupForInstance]", nil);
_setupComplete = YES;
[_bridge registerModuleForFrameUpdates:_instance withModuleData:self];
[[NSNotificationCenter defaultCenter]
postNotificationName:RCTDidInitializeModuleNotification
object:_bridge
userInfo:@{@"module" : _instance, @"bridge" : RCTNullIfNil(_bridge.parentBridge)}];
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
}
- (void)setUpMethodQueue
{
if (_instance && !_methodQueue && _bridge.valid) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpMethodQueue]", nil);
BOOL implementsMethodQueue = [_instance respondsToSelector:@selector(methodQueue)];
if (implementsMethodQueue && _bridge.valid) {
_methodQueue = _instance.methodQueue;
}
if (!_methodQueue && _bridge.valid) {
// Create new queue (store queueName, as it isn't retained by dispatch_queue)
_queueName = [NSString stringWithFormat:@"com.facebook.react.%@Queue", self.name];
_methodQueue = dispatch_queue_create(_queueName.UTF8String, DISPATCH_QUEUE_SERIAL);
// assign it to the module
if (implementsMethodQueue) {
@try {
[(id)_instance setValue:_methodQueue forKey:@"methodQueue"];
} @catch (NSException *exception) {
RCTLogError(
@"%@ is returning nil for its methodQueue, which is not "
"permitted. You must either return a pre-initialized "
"queue, or @synthesize the methodQueue to let the bridge "
"create a queue for you.",
self.name);
}
}
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
}
- (void)calculateMethods
{
if (_methods && _methodsByName) {
return;
}
NSMutableArray<id<RCTBridgeMethod>> *moduleMethods = [NSMutableArray new];
NSMutableDictionary<NSString *, id<RCTBridgeMethod>> *moduleMethodsByName = [NSMutableDictionary new];
if ([_moduleClass instancesRespondToSelector:@selector(methodsToExport)]) {
[moduleMethods addObjectsFromArray:[self.instance methodsToExport]];
}
unsigned int methodCount;
Class cls = _moduleClass;
while (cls && cls != [NSObject class] && cls != [NSProxy class]) {
Method *methods = class_copyMethodList(object_getClass(cls), &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
SEL selector = method_getName(method);
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
IMP imp = method_getImplementation(method);
auto exportedMethod = ((const RCTMethodInfo *(*)(id, SEL))imp)(_moduleClass, selector);
id<RCTBridgeMethod> moduleMethod = [[RCTModuleMethod alloc] initWithExportedMethod:exportedMethod
moduleClass:_moduleClass];
NSString *str = [NSString stringWithUTF8String:moduleMethod.JSMethodName];
[moduleMethodsByName setValue:moduleMethod forKey:str];
[moduleMethods addObject:moduleMethod];
}
}
free(methods);
cls = class_getSuperclass(cls);
}
_methods = [moduleMethods copy];
_methodsByName = [moduleMethodsByName copy];
}
#pragma mark - public getters
- (BOOL)hasInstance
{
std::unique_lock<std::mutex> lock(_instanceLock);
return _instance != nil;
}
- (id<RCTBridgeModule>)instance
{
NSString *moduleName = [self name];
int32_t requestId = getUniqueId();
BridgeNativeModulePerfLogger::moduleCreateStart([moduleName UTF8String], requestId);
if (!_setupComplete) {
RCT_PROFILE_BEGIN_EVENT(
RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass]), nil);
if (_requiresMainQueueSetup) {
// The chances of deadlock here are low, because module init very rarely
// calls out to other threads, however we can't control when a module might
// get accessed by client code during bridge setup, and a very low risk of
// deadlock is better than a fairly high risk of an assertion being thrown.
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData instance] main thread setup", nil);
if (!RCTIsMainQueue()) {
RCTLogWarn(@"RCTBridge required dispatch_sync to load %@. This may lead to deadlocks", _moduleClass);
}
RCTUnsafeExecuteOnMainQueueSync(^{
[self setUpInstanceAndBridge:requestId];
});
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
} else {
[self setUpInstanceAndBridge:requestId];
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
} else {
BridgeNativeModulePerfLogger::moduleCreateCacheHit([moduleName UTF8String], requestId);
}
if (_instance) {
BridgeNativeModulePerfLogger::moduleCreateEnd([moduleName UTF8String], requestId);
} else {
BridgeNativeModulePerfLogger::moduleCreateFail([moduleName UTF8String], requestId);
}
return _instance;
}
- (NSString *)name
{
return RCTBridgeModuleNameForClass(_moduleClass);
}
- (NSArray<id<RCTBridgeMethod>> *)methods
{
[self calculateMethods];
return _methods;
}
- (NSDictionary<NSString *, id<RCTBridgeMethod>> *)methodsByName
{
[self calculateMethods];
return _methodsByName;
}
- (void)gatherConstants
{
return [self gatherConstantsAndSignalJSRequireEnding:NO];
}
- (void)gatherConstantsAndSignalJSRequireEnding:(BOOL)startMarkers
{
NSString *moduleName = [self name];
if (_hasConstantsToExport && !_constantsToExport) {
RCT_PROFILE_BEGIN_EVENT(
RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData gatherConstants] %@", _moduleClass]), nil);
(void)[self instance];
if (startMarkers) {
/**
* Why do we instrument moduleJSRequireEndingStart here?
* - NativeModule requires from JS go through ModuleRegistry::getConfig().
* - ModuleRegistry::getConfig() calls NativeModule::getConstants() first.
* - This delegates to RCTNativeModule::getConstants(), which calls RCTModuleData gatherConstants().
* - Therefore, this is the first statement that executes after the NativeModule is created/initialized in a JS
* require.
*/
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart([moduleName UTF8String]);
}
if (_requiresMainQueueSetup) {
if (!RCTIsMainQueue()) {
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
}
RCTUnsafeExecuteOnMainQueueSync(^{
self->_constantsToExport = [self->_instance constantsToExport] ?: @{};
});
} else {
_constantsToExport = [_instance constantsToExport] ?: @{};
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
} else if (startMarkers) {
/**
* If a NativeModule doesn't have constants, it isn't eagerly loaded until its methods are first invoked.
* Therefore, we should immediately start JSRequireEnding
*/
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart([moduleName UTF8String]);
}
}
- (NSDictionary<NSString *, id> *)exportedConstants
{
[self gatherConstantsAndSignalJSRequireEnding:YES];
NSDictionary<NSString *, id> *constants = _constantsToExport;
_constantsToExport = nil; // Not needed anymore
return constants;
}
- (dispatch_queue_t)methodQueue
{
if (_bridge.valid) {
__unused id instance = self.instance;
RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@)", self, instance);
}
return _methodQueue;
}
- (void)invalidate
{
_methodQueue = nil;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; name=\"%@\">", [self class], self, self.name];
}
@end
#else // RCT_REMOVE_LEGACY_ARCH
@implementation RCTModuleData
- (instancetype)initWithModuleClass:(Class)moduleClass
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
return self;
}
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance
bridge:(RCTBridge *)bridge
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
{
return self;
}
- (void)gatherConstants
{
}
- (void)invalidate
{
}
@end
#endif // RCT_REMOVE_LEGACY_ARCH

34
node_modules/react-native/React/Base/RCTModuleMethod.h generated vendored Normal file
View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTBridgeMethod.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTNullability.h>
@class RCTBridge;
@interface RCTMethodArgument : NSObject
@property (nonatomic, copy, readonly) NSString *type;
@property (nonatomic, readonly) RCTNullability nullability;
@property (nonatomic, readonly) BOOL unused;
@end
@interface RCTModuleMethod : NSObject <RCTBridgeMethod>
@property (nonatomic, readonly) Class moduleClass;
@property (nonatomic, readonly) SEL selector;
- (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportMethod
moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER;
@end
RCT_EXTERN NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments);

618
node_modules/react-native/React/Base/RCTModuleMethod.mm generated vendored Normal file
View File

@@ -0,0 +1,618 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTModuleMethod.h"
#import <objc/message.h>
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTConvert.h"
#import "RCTCxxConvert.h"
#import "RCTLog.h"
#import "RCTManagedPointer.h"
#import "RCTParserUtils.h"
#import "RCTProfile.h"
#import "RCTUtils.h"
typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
/**
* Get the converter function for the specified type
*/
static SEL selectorForType(NSString *type)
{
const char *input = type.UTF8String;
return NSSelectorFromString([RCTParseType(&input) stringByAppendingString:@":"]);
}
@implementation RCTMethodArgument
- (instancetype)initWithType:(NSString *)type nullability:(RCTNullability)nullability unused:(BOOL)unused
{
if (self = [super init]) {
_type = [type copy];
_nullability = nullability;
_unused = unused;
}
return self;
}
@end
@implementation RCTModuleMethod {
Class _moduleClass;
const RCTMethodInfo *_methodInfo;
NSString *_JSMethodName;
SEL _selector;
NSInvocation *_invocation;
NSArray<RCTArgumentBlock> *_argumentBlocks;
NSMutableArray *_retainedObjects;
}
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index, id valueOrType, const char *issue)
{
RCTLogError(
@"Argument %tu (%@) of %@.%s %s",
index,
valueOrType,
RCTBridgeModuleNameForClass(method->_moduleClass),
method.JSMethodName,
issue);
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
RCT_EXTERN_C_BEGIN
// returns YES if the selector ends in a colon (indicating that there is at
// least one argument, and maybe more selector parts) or NO if it doesn't.
static BOOL RCTParseSelectorPart(const char **input, NSMutableString *selector)
{
NSString *selectorPart;
if (RCTParseSelectorIdentifier(input, &selectorPart)) {
[selector appendString:selectorPart];
}
RCTSkipWhitespace(input);
if (RCTReadChar(input, ':')) {
[selector appendString:@":"];
RCTSkipWhitespace(input);
return YES;
}
return NO;
}
static BOOL RCTParseUnused(const char **input)
{
return RCTReadString(input, "__attribute__((unused))") || RCTReadString(input, "__attribute__((__unused__))") ||
RCTReadString(input, "__unused") || RCTReadString(input, "[[maybe_unused]]");
}
static RCTNullability RCTParseNullability(const char **input)
{
if (RCTReadString(input, "nullable")) {
return RCTNullable;
} else if (RCTReadString(input, "nonnull")) {
return RCTNonnullable;
}
return RCTNullabilityUnspecified;
}
static RCTNullability RCTParseNullabilityPostfix(const char **input)
{
if (RCTReadString(input, "_Nullable") || RCTReadString(input, "__nullable")) {
return RCTNullable;
} else if (RCTReadString(input, "_Nonnull") || RCTReadString(input, "__nonnull")) {
return RCTNonnullable;
}
return RCTNullabilityUnspecified;
}
// returns YES if execution is safe to proceed (enqueue callback invocation), NO if callback has already been invoked
#if RCT_DEBUG
static BOOL checkCallbackMultipleInvocations(BOOL *didInvoke)
{
if (*didInvoke) {
RCTFatal(RCTErrorWithMessage(
@"Illegal callback invocation from native module. This callback type only permits a single invocation from native code."));
return NO;
} else {
*didInvoke = YES;
return YES;
}
}
#endif
NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments)
{
RCTSkipWhitespace(&input);
NSMutableArray *args;
NSMutableString *selector = [NSMutableString new];
while (RCTParseSelectorPart(&input, selector)) {
if (!args) {
args = [NSMutableArray new];
}
// Parse type
if (RCTReadChar(&input, '(')) {
RCTSkipWhitespace(&input);
// 5 cases that both nullable and __unused exist
// 1: foo:(nullable __unused id)foo 2: foo:(nullable id __unused)foo
// 3: foo:(__unused id _Nullable)foo 4: foo:(id __unused _Nullable)foo
// 5: foo:(id _Nullable __unused)foo
RCTNullability nullability = RCTParseNullability(&input);
RCTSkipWhitespace(&input);
BOOL unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
NSString *type = RCTParseType(&input);
RCTSkipWhitespace(&input);
if (nullability == RCTNullabilityUnspecified) {
nullability = RCTParseNullabilityPostfix(&input);
RCTSkipWhitespace(&input);
if (!unused) {
unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
if (unused && nullability == RCTNullabilityUnspecified) {
nullability = RCTParseNullabilityPostfix(&input);
RCTSkipWhitespace(&input);
}
}
} else if (!unused) {
unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
}
[args addObject:[[RCTMethodArgument alloc] initWithType:type nullability:nullability unused:unused]];
RCTSkipWhitespace(&input);
RCTReadChar(&input, ')');
RCTSkipWhitespace(&input);
} else {
// Type defaults to id if unspecified
[args addObject:[[RCTMethodArgument alloc] initWithType:@"id" nullability:RCTNullable unused:NO]];
}
// Argument name
RCTParseArgumentIdentifier(&input, NULL);
RCTSkipWhitespace(&input);
}
*arguments = [args copy];
return selector;
}
RCT_EXTERN_C_END
- (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportedMethod moduleClass:(Class)moduleClass
{
if (self = [super init]) {
_moduleClass = moduleClass;
_methodInfo = exportedMethod;
}
return self;
}
- (void)processMethodSignature
{
NSArray<RCTMethodArgument *> *arguments;
_selector = NSSelectorFromString(RCTParseMethodSignature(_methodInfo->objcName, &arguments));
RCTAssert(_selector, @"%s is not a valid selector", _methodInfo->objcName);
// Create method invocation
NSMethodSignature *methodSignature = [_moduleClass instanceMethodSignatureForSelector:_selector];
RCTAssert(methodSignature, @"%s is not a recognized Objective-C method.", sel_getName(_selector));
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
invocation.selector = _selector;
_invocation = invocation;
NSMutableArray *retainedObjects = [NSMutableArray array];
_retainedObjects = retainedObjects;
// Process arguments
NSUInteger numberOfArguments = methodSignature.numberOfArguments;
NSMutableArray<RCTArgumentBlock> *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
#if RCT_DEBUG
__weak RCTModuleMethod *weakSelf = self;
#endif
#define RCT_RETAINED_ARG_BLOCK(_logic) \
[argumentBlocks addObject:^(__unused __weak RCTBridge * bridge, NSUInteger index, id json) { \
_logic [invocation setArgument:&value atIndex:(index) + 2]; \
if (value) { \
[retainedObjects addObject:value]; \
} \
return YES; \
}]
#define __PRIMITIVE_CASE(_type, _nullable) \
{ \
isNullableType = _nullable; \
_type (*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend; \
[argumentBlocks addObject:^(__unused RCTBridge * bridge, NSUInteger index, id json) { \
_type value = convert([RCTConvert class], selector, json); \
[invocation setArgument:&value atIndex:(index) + 2]; \
return YES; \
}]; \
break; \
}
#define PRIMITIVE_CASE(_type) __PRIMITIVE_CASE(_type, NO)
#define NULLABLE_PRIMITIVE_CASE(_type) __PRIMITIVE_CASE(_type, YES)
// Explicitly copy the block
#define __COPY_BLOCK(block...) \
id value = [block copy]; \
if (value) { \
[retainedObjects addObject:value]; \
}
#if RCT_DEBUG
#define BLOCK_CASE(_block_args, _block) \
RCT_RETAINED_ARG_BLOCK( \
if (json && ![json isKindOfClass:[NSNumber class]]) { \
RCTLogArgumentError(weakSelf, index, json, "should be a function"); \
return NO; \
} __block BOOL didInvoke = NO; \
__COPY_BLOCK(^_block_args { \
if (checkCallbackMultipleInvocations(&didInvoke)) \
_block \
});)
#else
#define BLOCK_CASE(_block_args, _block) \
RCT_RETAINED_ARG_BLOCK(__COPY_BLOCK(^_block_args{ \
_block});)
#endif
for (NSUInteger i = 2; i < numberOfArguments; i++) {
const char *objcType = [methodSignature getArgumentTypeAtIndex:i];
[[maybe_unused]] BOOL isNullableType = NO;
RCTMethodArgument *argument = arguments[i - 2];
NSString *typeName = argument.type;
SEL selector = selectorForType(typeName);
if ([RCTConvert respondsToSelector:selector]) {
switch (objcType[0]) {
// Primitives
case _C_CHR:
PRIMITIVE_CASE(char)
case _C_UCHR:
PRIMITIVE_CASE(unsigned char)
case _C_SHT:
PRIMITIVE_CASE(short)
case _C_USHT:
PRIMITIVE_CASE(unsigned short)
case _C_INT:
PRIMITIVE_CASE(int)
case _C_UINT:
PRIMITIVE_CASE(unsigned int)
case _C_LNG:
PRIMITIVE_CASE(long)
case _C_ULNG:
PRIMITIVE_CASE(unsigned long)
case _C_LNG_LNG:
PRIMITIVE_CASE(long long)
case _C_ULNG_LNG:
PRIMITIVE_CASE(unsigned long long)
case _C_FLT:
PRIMITIVE_CASE(float)
case _C_DBL:
PRIMITIVE_CASE(double)
case _C_BOOL:
PRIMITIVE_CASE(BOOL)
case _C_SEL:
NULLABLE_PRIMITIVE_CASE(SEL)
case _C_CHARPTR:
NULLABLE_PRIMITIVE_CASE(const char *)
case _C_PTR:
NULLABLE_PRIMITIVE_CASE(void *)
case _C_ID: {
isNullableType = YES;
id (*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
RCT_RETAINED_ARG_BLOCK(id value = convert([RCTConvert class], selector, json););
break;
}
case _C_STRUCT_B: {
NSMethodSignature *typeSignature = [RCTConvert methodSignatureForSelector:selector];
NSInvocation *typeInvocation = [NSInvocation invocationWithMethodSignature:typeSignature];
typeInvocation.selector = selector;
typeInvocation.target = [RCTConvert class];
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) {
void *returnValue = malloc(typeSignature.methodReturnLength);
if (!returnValue) {
// CWE - 391 : Unchecked error condition
// https://www.cvedetails.com/cwe-details/391/Unchecked-Error-Condition.html
// https://eli.thegreenplace.net/2009/10/30/handling-out-of-memory-conditions-in-c
abort();
}
[typeInvocation setArgument:&json atIndex:2];
[typeInvocation invoke];
[typeInvocation getReturnValue:returnValue];
[invocation setArgument:returnValue atIndex:index + 2];
free(returnValue);
return YES;
}];
break;
}
default: {
static const char *blockType = @encode(
__typeof__(^{
}));
if (!strcmp(objcType, blockType)) {
BLOCK_CASE((NSArray * args), { [bridge enqueueCallback:json args:args]; });
} else {
RCTLogError(@"Unsupported argument type '%@' in method %@.", typeName, [self methodName]);
}
}
}
} else if ([typeName isEqualToString:@"RCTResponseSenderBlock"]) {
BLOCK_CASE((NSArray * args), { [bridge enqueueCallback:json args:args]; });
} else if ([typeName isEqualToString:@"RCTResponseErrorBlock"]) {
BLOCK_CASE((NSError * error), { [bridge enqueueCallback:json args:@[ RCTJSErrorFromNSError(error) ]]; });
} else if ([typeName isEqualToString:@"RCTPromiseResolveBlock"]) {
RCTAssert(
i == numberOfArguments - 2,
@"The RCTPromiseResolveBlock must be the second to last parameter in %@",
[self methodName]);
BLOCK_CASE((id result), { [bridge enqueueCallback:json args:result ? @[ result ] : @[]]; });
} else if ([typeName isEqualToString:@"RCTPromiseRejectBlock"]) {
RCTAssert(
i == numberOfArguments - 1, @"The RCTPromiseRejectBlock must be the last parameter in %@", [self methodName]);
BLOCK_CASE((NSString * code, NSString * message, NSError * error), {
NSDictionary *errorJSON = RCTJSErrorFromCodeMessageAndNSError(code, message, error);
[bridge enqueueCallback:json args:@[ errorJSON ]];
});
} else if ([typeName hasPrefix:@"JS::"]) {
NSString *selectorNameForCxxType =
[[typeName stringByReplacingOccurrencesOfString:@"::" withString:@"_"] stringByAppendingString:@":"];
selector = NSSelectorFromString(selectorNameForCxxType);
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) {
RCTManagedPointer *(*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend;
RCTManagedPointer *box = convert([RCTCxxConvert class], selector, json);
void *pointer = box.voidPointer;
[invocation setArgument:&pointer atIndex:index + 2];
[retainedObjects addObject:box];
return YES;
}];
} else {
// Unknown argument type
RCTLogError(
@"Unknown argument type '%@' in method %@. Extend RCTConvert to support this type.",
typeName,
[self methodName]);
}
#if RCT_DEBUG
RCTNullability nullability = argument.nullability;
if (!isNullableType) {
if (nullability == RCTNullable) {
RCTLogArgumentError(
weakSelf,
i - 2,
typeName,
"is marked as "
"nullable, but is not a nullable type.");
}
nullability = RCTNonnullable;
}
/**
* Special case - Numbers are not nullable in Android, so we
* don't support this for now. In future we may allow it.
*/
if ([typeName isEqualToString:@"NSNumber"]) {
BOOL unspecified = (nullability == RCTNullabilityUnspecified);
if (!argument.unused && (nullability == RCTNullable || unspecified)) {
RCTLogArgumentError(
weakSelf,
i - 2,
typeName,
[unspecified ? @"has unspecified nullability" : @"is marked as nullable"
stringByAppendingString:@" but React requires that all NSNumber "
"arguments are explicitly marked as `nonnull` to ensure "
"compatibility with Android."]
.UTF8String);
}
nullability = RCTNonnullable;
}
if (nullability == RCTNonnullable) {
RCTArgumentBlock oldBlock = argumentBlocks[i - 2];
argumentBlocks[i - 2] = ^(RCTBridge *bridge, NSUInteger index, id json) {
if (json != nil) {
if (!oldBlock(bridge, index, json)) {
return NO;
}
if (isNullableType) {
// Check converted value wasn't null either, as method probably
// won't gracefully handle a nil value for a nonull argument
void *value;
[invocation getArgument:&value atIndex:index + 2];
if (value == NULL) {
return NO;
}
}
return YES;
}
RCTLogArgumentError(weakSelf, index, typeName, "must not be null");
return NO;
};
}
#endif
}
#if RCT_DEBUG
const char *objcType = _invocation.methodSignature.methodReturnType;
if (_methodInfo->isSync && objcType[0] != _C_ID) {
RCTLogError(
@"Return type of %@.%s should be (id) as the method is \"sync\"",
RCTBridgeModuleNameForClass(_moduleClass),
self.JSMethodName);
}
#endif
_argumentBlocks = argumentBlocks;
}
- (SEL)selector
{
if (_selector == NULL) {
RCT_PROFILE_BEGIN_EVENT(
RCTProfileTagAlways,
@"",
(@{@"module" : NSStringFromClass(_moduleClass), @"method" : @(_methodInfo->objcName)}));
[self processMethodSignature];
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
return _selector;
}
- (const char *)JSMethodName
{
NSString *methodName = _JSMethodName;
if (!methodName) {
const char *jsName = _methodInfo->jsName;
if (jsName && strlen(jsName) > 0) {
methodName = @(jsName);
} else {
methodName = @(_methodInfo->objcName);
NSRange colonRange = [methodName rangeOfString:@":"];
if (colonRange.location != NSNotFound) {
methodName = [methodName substringToIndex:colonRange.location];
}
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
RCTAssert(
methodName.length,
@"%s is not a valid JS function name, please"
" supply an alternative using RCT_REMAP_METHOD()",
_methodInfo->objcName);
}
_JSMethodName = methodName;
}
return methodName.UTF8String;
}
- (RCTFunctionType)functionType
{
if (strstr(_methodInfo->objcName, "RCTPromise") != NULL) {
RCTAssert(!_methodInfo->isSync, @"Promises cannot be used in sync functions");
return RCTFunctionTypePromise;
} else if (_methodInfo->isSync) {
return RCTFunctionTypeSync;
} else {
return RCTFunctionTypeNormal;
}
}
- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments
{
if (_argumentBlocks == nil) {
[self processMethodSignature];
}
#if RCT_DEBUG
// Sanity check
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
%@ on a module of class %@", [self methodName], [module class]);
// Safety check
if (arguments.count != _argumentBlocks.count) {
NSInteger actualCount = arguments.count;
NSInteger expectedCount = _argumentBlocks.count;
// Subtract the implicit Promise resolver and rejecter functions for implementations of async functions
if (self.functionType == RCTFunctionTypePromise) {
actualCount -= 2;
expectedCount -= 2;
}
RCTLogError(
@"%@.%s was called with %lld arguments but expects %lld arguments. "
@"If you haven\'t changed this method yourself, this usually means that "
@"your versions of the native code and JavaScript code are out of sync. "
@"Updating both should make this error go away.",
RCTBridgeModuleNameForClass(_moduleClass),
self.JSMethodName,
(long long)actualCount,
(long long)expectedCount);
return nil;
}
#endif
// Set arguments
NSUInteger index = 0;
for (id json in arguments) {
RCTArgumentBlock block = _argumentBlocks[index];
if (!block(bridge, index, RCTNilIfNull(json))) {
// Invalid argument, abort
RCTLogArgumentError(self, index, json, "could not be processed. Aborting method call.");
return nil;
}
index++;
}
// Invoke method
#ifdef RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD
if (RCTIsMainQueue()) {
CFTimeInterval start = CACurrentMediaTime();
[_invocation invokeWithTarget:module];
CFTimeInterval duration = CACurrentMediaTime() - start;
if (duration > RCT_MAIN_THREAD_WATCH_DOG_THRESHOLD) {
RCTLogWarn(
@"Main Thread Watchdog: Invocation of %@ blocked the main thread for %dms. "
"Consider using background-threaded modules and asynchronous calls "
"to spend less time on the main thread and keep the app's UI responsive.",
[self methodName],
(int)(duration * 1000));
}
} else {
[_invocation invokeWithTarget:module];
}
#else
[_invocation invokeWithTarget:module];
#endif
[_retainedObjects removeAllObjects];
if (_methodInfo->isSync) {
void *returnValue;
[_invocation getReturnValue:&returnValue];
return (__bridge id)returnValue;
}
return nil;
}
- (NSString *)methodName
{
if (!_selector) {
[self processMethodSignature];
}
return [NSString stringWithFormat:@"-[%@ %s]", _moduleClass, sel_getName(_selector)];
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; exports %@ as %s(); type: %s>",
[self class],
self,
[self methodName],
self.JSMethodName,
RCTFunctionDescriptorFromType(self.functionType)];
}
@end

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTBridge.h"
#import "RCTTurboModuleRegistry.h"
@class RCTBridgeModule;
@implementation RCTModuleRegistry {
__weak id<RCTTurboModuleRegistry> _turboModuleRegistry;
#ifndef RCT_REMOVE_LEGACY_ARCH
__weak RCTBridge *_bridge;
#endif // RCT_REMOVE_LEGACY_ARCH
}
#ifndef RCT_REMOVE_LEGACY_ARCH
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
}
#endif // RCT_REMOVE_LEGACY_ARCH
- (void)setTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry
{
_turboModuleRegistry = turboModuleRegistry;
}
- (id)moduleForName:(const char *)moduleName
{
return [self moduleForName:moduleName lazilyLoadIfNecessary:YES];
}
- (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
id<RCTBridgeModule> module = nil;
#ifndef RCT_REMOVE_LEGACY_ARCH
RCTBridge *bridge = _bridge;
if (bridge) {
module = [bridge moduleForName: [NSString stringWithUTF8String:moduleName] lazilyLoadIfNecessary:lazilyLoad];
}
#endif // RCT_REMOVE_LEGACY_ARCH
id<RCTTurboModuleRegistry> turboModuleRegistry = _turboModuleRegistry;
if (module == nil && turboModuleRegistry && (lazilyLoad || [turboModuleRegistry moduleIsInitialized:moduleName])) {
module = [turboModuleRegistry moduleForName:moduleName];
}
return module;
}
- (BOOL)moduleIsInitialized:(Class)moduleClass
{
#ifndef RCT_REMOVE_LEGACY_ARCH
RCTBridge *bridge = _bridge;
if (bridge) {
return [bridge moduleIsInitialized:moduleClass];
}
#endif // RCT_REMOVE_LEGACY_ARCH
id<RCTTurboModuleRegistry> turboModuleRegistry = _turboModuleRegistry;
if (turboModuleRegistry) {
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
return [turboModuleRegistry moduleIsInitialized:[moduleName UTF8String]];
}
return NO;
}
- (id)moduleForClass:(Class)moduleClass
{
return [self moduleForName:RCTBridgeModuleNameForClass(moduleClass).UTF8String];
}
@end

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTMultipartStreamReader.h>
typedef void (^RCTMultipartDataTaskCallback)(
NSInteger statusCode,
NSDictionary *headers,
NSData *content,
NSError *error,
BOOL done);
@interface RCTMultipartDataTask : NSObject
- (instancetype)initWithURL:(NSURL *)url
partHandler:(RCTMultipartDataTaskCallback)partHandler
progressHandler:(RCTMultipartProgressCallback)progressHandler;
- (void)startTask;
@end

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTMultipartDataTask.h"
@interface RCTMultipartDataTask () <NSURLSessionDataDelegate, NSURLSessionDataDelegate>
@end
@implementation RCTMultipartDataTask {
NSURL *_url;
RCTMultipartDataTaskCallback _partHandler;
RCTMultipartProgressCallback _progressHandler;
NSInteger _statusCode;
NSDictionary *_headers;
NSString *_boundary;
NSMutableData *_data;
}
- (instancetype)initWithURL:(NSURL *)url
partHandler:(RCTMultipartDataTaskCallback)partHandler
progressHandler:(RCTMultipartProgressCallback)progressHandler
{
if (self = [super init]) {
_url = url;
_partHandler = [partHandler copy];
_progressHandler = [progressHandler copy];
}
return self;
}
- (void)startTask
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self
delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
[request addValue:@"multipart/mixed" forHTTPHeaderField:@"Accept"];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
[session finishTasksAndInvalidate];
}
- (void)URLSession:(__unused NSURLSession *)session
dataTask:(__unused NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
_headers = [httpResponse allHeaderFields];
_statusCode = [httpResponse statusCode];
NSString *contentType = @"";
for (NSString *key in [_headers keyEnumerator]) {
if ([[key lowercaseString] isEqualToString:@"content-type"]) {
contentType = [_headers valueForKey:key];
break;
}
}
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:@"multipart/mixed;.*boundary=\"([^\"]+)\""
options:0
error:nil];
NSTextCheckingResult *match = [regex firstMatchInString:contentType
options:0
range:NSMakeRange(0, contentType.length)];
if (match) {
_boundary = [contentType substringWithRange:[match rangeAtIndex:1]];
completionHandler(NSURLSessionResponseBecomeStream);
return;
}
}
// In case the server doesn't support multipart/mixed responses, fallback to normal download
_data = [[NSMutableData alloc] initWithCapacity:1024 * 1024];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(__unused NSURLSession *)session
task:(__unused NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
if (_partHandler) {
_partHandler(_statusCode, _headers, _data, error, YES);
}
}
- (void)URLSession:(__unused NSURLSession *)session
dataTask:(__unused NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
[_data appendData:data];
}
- (void)URLSession:(__unused NSURLSession *)session
dataTask:(__unused NSURLSessionDataTask *)dataTask
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask
{
[streamTask captureStreams];
}
- (void)URLSession:(__unused NSURLSession *)session
streamTask:(__unused NSURLSessionStreamTask *)streamTask
didBecomeInputStream:(NSInputStream *)inputStream
outputStream:(__unused NSOutputStream *)outputStream
{
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream
boundary:_boundary];
RCTMultipartDataTaskCallback partHandler = _partHandler;
_partHandler = nil;
NSInteger statusCode = _statusCode;
BOOL completed = [reader
readAllPartsWithCompletionCallback:^(NSDictionary *headers, NSData *content, BOOL done) {
partHandler(statusCode, headers, content, nil, done);
}
progressCallback:_progressHandler];
if (!completed) {
partHandler(
statusCode, nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil], YES);
}
}
@end

View File

@@ -0,0 +1,21 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
typedef void (^RCTMultipartCallback)(NSDictionary *headers, NSData *content, BOOL done);
typedef void (^RCTMultipartProgressCallback)(NSDictionary *headers, NSNumber *loaded, NSNumber *total);
// RCTMultipartStreamReader can be used to parse responses with Content-Type: multipart/mixed
// See https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
@interface RCTMultipartStreamReader : NSObject
- (instancetype)initWithInputStream:(NSInputStream *)stream boundary:(NSString *)boundary;
- (BOOL)readAllPartsWithCompletionCallback:(RCTMultipartCallback)callback
progressCallback:(RCTMultipartProgressCallback)progressCallback;
@end

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTMultipartStreamReader.h"
#import <QuartzCore/QuartzCore.h>
#define CRLF @"\r\n"
@implementation RCTMultipartStreamReader {
__strong NSInputStream *_stream;
__strong NSString *_boundary;
CFTimeInterval _lastDownloadProgress;
}
- (instancetype)initWithInputStream:(NSInputStream *)stream boundary:(NSString *)boundary
{
if (self = [super init]) {
_stream = stream;
_boundary = boundary;
_lastDownloadProgress = CACurrentMediaTime();
}
return self;
}
- (NSDictionary *)parseHeaders:(NSData *)data
{
NSMutableDictionary *headers = [NSMutableDictionary new];
NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray<NSString *> *lines = [text componentsSeparatedByString:CRLF];
for (NSString *line in lines) {
NSUInteger location = [line rangeOfString:@":"].location;
if (location == NSNotFound) {
continue;
}
NSString *key = [line substringToIndex:location];
NSString *value = [[line substringFromIndex:location + 1]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[headers setValue:value forKey:key];
}
return headers;
}
- (void)emitChunk:(NSData *)data headers:(NSDictionary *)headers callback:(RCTMultipartCallback)callback done:(BOOL)done
{
NSData *marker = [CRLF CRLF dataUsingEncoding:NSUTF8StringEncoding];
NSRange range = [data rangeOfData:marker options:0 range:NSMakeRange(0, data.length)];
if (range.location == NSNotFound) {
callback(nil, data, done);
} else if (headers != nil) {
// If headers were parsed already just use that to avoid doing it twice.
NSInteger bodyStart = range.location + marker.length;
NSData *bodyData = [data subdataWithRange:NSMakeRange(bodyStart, data.length - bodyStart)];
callback(headers, bodyData, done);
} else {
NSData *headersData = [data subdataWithRange:NSMakeRange(0, range.location)];
NSInteger bodyStart = range.location + marker.length;
NSData *bodyData = [data subdataWithRange:NSMakeRange(bodyStart, data.length - bodyStart)];
callback([self parseHeaders:headersData], bodyData, done);
}
}
- (void)emitProgress:(NSDictionary *)headers
contentLength:(NSUInteger)contentLength
final:(BOOL)final
callback:(RCTMultipartProgressCallback)callback
{
if (headers == nil) {
return;
}
// Throttle progress events so we don't send more that around 60 per second.
CFTimeInterval currentTime = CACurrentMediaTime();
NSInteger headersContentLength = headers[@"Content-Length"] != nil ? [headers[@"Content-Length"] integerValue] : 0;
if (callback && (currentTime - _lastDownloadProgress > 0.016 || final)) {
_lastDownloadProgress = currentTime;
callback(headers, @(headersContentLength), @(contentLength));
}
}
- (BOOL)readAllPartsWithCompletionCallback:(RCTMultipartCallback)callback
progressCallback:(RCTMultipartProgressCallback)progressCallback
{
NSInteger chunkStart = 0;
NSInteger bytesSeen = 0;
NSData *delimiter =
[[NSString stringWithFormat:@"%@--%@%@", CRLF, _boundary, CRLF] dataUsingEncoding:NSUTF8StringEncoding];
NSData *closeDelimiter =
[[NSString stringWithFormat:@"%@--%@--%@", CRLF, _boundary, CRLF] dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *content = [[NSMutableData alloc] initWithCapacity:1];
NSDictionary *currentHeaders = nil;
NSUInteger currentHeadersLength = 0;
const NSUInteger bufferLen = 4 * 1024;
uint8_t buffer[bufferLen];
[_stream open];
while (true) {
BOOL isCloseDelimiter = NO;
// Search only a subset of chunk that we haven't seen before + few bytes
// to allow for the edge case when the delimiter is cut by read call
NSInteger searchStart = MAX(bytesSeen - (NSInteger)closeDelimiter.length, chunkStart);
NSRange remainingBufferRange = NSMakeRange(searchStart, content.length - searchStart);
// Check for delimiters.
NSRange range = [content rangeOfData:delimiter options:0 range:remainingBufferRange];
if (range.location == NSNotFound) {
isCloseDelimiter = YES;
range = [content rangeOfData:closeDelimiter options:0 range:remainingBufferRange];
}
if (range.location == NSNotFound) {
if (currentHeaders == nil) {
// Check for the headers delimiter.
NSData *headersMarker = [CRLF CRLF dataUsingEncoding:NSUTF8StringEncoding];
NSRange headersRange = [content rangeOfData:headersMarker options:0 range:remainingBufferRange];
if (headersRange.location != NSNotFound) {
NSData *headersData = [content subdataWithRange:NSMakeRange(chunkStart, headersRange.location - chunkStart)];
currentHeadersLength = headersData.length;
currentHeaders = [self parseHeaders:headersData];
}
} else {
// When headers are loaded start sending progress callbacks.
[self emitProgress:currentHeaders
contentLength:content.length - currentHeadersLength
final:NO
callback:progressCallback];
}
bytesSeen = content.length;
NSInteger bytesRead = [_stream read:buffer maxLength:bufferLen];
if (bytesRead <= 0 || _stream.streamError) {
return NO;
}
[content appendBytes:buffer length:bytesRead];
continue;
}
NSInteger chunkEnd = range.location;
NSInteger length = chunkEnd - chunkStart;
bytesSeen = chunkEnd;
// Ignore preamble
if (chunkStart > 0) {
NSData *chunk = [content subdataWithRange:NSMakeRange(chunkStart, length)];
[self emitProgress:currentHeaders
contentLength:chunk.length - currentHeadersLength
final:YES
callback:progressCallback];
[self emitChunk:chunk headers:currentHeaders callback:callback done:isCloseDelimiter];
currentHeaders = nil;
currentHeadersLength = 0;
}
if (isCloseDelimiter) {
return YES;
}
chunkStart = chunkEnd + delimiter.length;
}
}
@end

14
node_modules/react-native/React/Base/RCTNullability.h generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, RCTNullability) {
RCTNullabilityUnspecified,
RCTNullable,
RCTNonnullable,
};

31
node_modules/react-native/React/Base/RCTPLTag.h generated vendored Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
typedef NS_ENUM(NSInteger, RCTPLTag) {
RCTPLScriptDownload = 0,
RCTPLScriptExecution,
RCTPLRAMBundleLoad,
RCTPLRAMStartupCodeSize,
RCTPLRAMStartupNativeRequires,
RCTPLRAMStartupNativeRequiresCount,
RCTPLRAMNativeRequires,
RCTPLRAMNativeRequiresCount,
RCTPLNativeModuleInit,
RCTPLNativeModuleMainThread,
RCTPLNativeModulePrepareConfig,
RCTPLNativeModuleMainThreadUsesCount,
RCTPLNativeModuleSetup,
RCTPLTurboModuleSetup,
RCTPLJSCWrapperOpenLibrary,
RCTPLBridgeStartup,
RCTPLTTI,
RCTPLBundleSize,
RCTPLReactInstanceInit,
RCTPLAppStartup,
RCTPLInitReactRuntime,
RCTPLSize // This is used to count the size
};

30
node_modules/react-native/React/Base/RCTParserUtils.h generated vendored Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
@interface RCTParserUtils : NSObject
/**
* Generic utility functions for parsing Objective-C source code.
*/
RCT_EXTERN BOOL RCTReadChar(const char **input, char c);
RCT_EXTERN BOOL RCTReadString(const char **input, const char *string);
RCT_EXTERN void RCTSkipWhitespace(const char **input);
RCT_EXTERN BOOL RCTParseSelectorIdentifier(const char **input, NSString **string);
RCT_EXTERN BOOL RCTParseArgumentIdentifier(const char **input, NSString **string);
/**
* Parse an Objective-C type into a form that can be used by RCTConvert.
* This doesn't really belong here, but it's used by both RCTConvert and
* RCTModuleMethod, which makes it difficult to find a better home for it.
*/
RCT_EXTERN NSString *RCTParseType(const char **input);
@end

137
node_modules/react-native/React/Base/RCTParserUtils.m generated vendored Normal file
View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTParserUtils.h"
#import "RCTLog.h"
@implementation RCTParserUtils
BOOL RCTReadChar(const char **input, char c)
{
if (**input == c) {
(*input)++;
return YES;
}
return NO;
}
BOOL RCTReadString(const char **input, const char *string)
{
int i;
for (i = 0; string[i] != 0; i++) {
if (string[i] != (*input)[i]) {
return NO;
}
}
*input += i;
return YES;
}
void RCTSkipWhitespace(const char **input)
{
while (isspace(**input)) {
(*input)++;
}
}
static BOOL RCTIsIdentifierHead(const char c)
{
return isalpha(c) || c == '_';
}
static BOOL RCTIsIdentifierTail(const char c)
{
return isalnum(c) || c == '_';
}
BOOL RCTParseArgumentIdentifier(const char **input, NSString **string)
{
const char *start = *input;
do {
if (!RCTIsIdentifierHead(**input)) {
return NO;
}
(*input)++;
while (RCTIsIdentifierTail(**input)) {
(*input)++;
}
// allow namespace resolution operator
} while (RCTReadString(input, "::"));
if (string) {
*string = [[NSString alloc] initWithBytes:start length:(NSInteger)(*input - start) encoding:NSASCIIStringEncoding];
}
return YES;
}
BOOL RCTParseSelectorIdentifier(const char **input, NSString **string)
{
const char *start = *input;
if (!RCTIsIdentifierHead(**input)) {
return NO;
}
(*input)++;
while (RCTIsIdentifierTail(**input)) {
(*input)++;
}
if (string) {
*string = [[NSString alloc] initWithBytes:start length:(NSInteger)(*input - start) encoding:NSASCIIStringEncoding];
}
return YES;
}
static BOOL RCTIsCollectionType(NSString *type)
{
static NSSet *collectionTypes;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
collectionTypes = [[NSSet alloc] initWithObjects:@"NSArray", @"NSSet", @"NSDictionary", nil];
});
return [collectionTypes containsObject:type];
}
NSString *RCTParseType(const char **input)
{
NSString *type;
RCTParseArgumentIdentifier(input, &type);
RCTSkipWhitespace(input);
if (RCTReadChar(input, '<')) {
RCTSkipWhitespace(input);
NSString *subtype = RCTParseType(input);
if (RCTIsCollectionType(type)) {
if ([type isEqualToString:@"NSDictionary"]) {
// Dictionaries have both a key *and* value type, but the key type has
// to be a string for JSON, so we only care about the value type
if (RCT_DEBUG && ![subtype isEqualToString:@"NSString"]) {
RCTLogError(@"%@ is not a valid key type for a JSON dictionary", subtype);
}
RCTSkipWhitespace(input);
RCTReadChar(input, ',');
RCTSkipWhitespace(input);
subtype = RCTParseType(input);
}
if (![subtype isEqualToString:@"id"]) {
type = [type stringByReplacingCharactersInRange:(NSRange){0, 2 /* "NS" */} withString:subtype];
}
} else {
// It's a protocol rather than a generic collection - ignore it
}
RCTSkipWhitespace(input);
RCTReadChar(input, '>');
}
RCTSkipWhitespace(input);
if (!RCTReadChar(input, '*')) {
RCTReadChar(input, '&');
}
return type;
}
@end

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import "RCTPLTag.h"
@interface RCTPerformanceLogger : NSObject
/**
* Starts measuring a metric with the given tag.
* Overrides previous value if the measurement has been already started.
* If RCTProfile is enabled it also begins appropriate async event.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)markStartForTag:(RCTPLTag)tag;
/**
* Stops measuring a metric with given tag.
* Checks if RCTPerformanceLoggerStart() has been called before
* and doesn't do anything and log a message if it hasn't.
* If RCTProfile is enabled it also ends appropriate async event.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)markStopForTag:(RCTPLTag)tag;
/**
* Sets given value for a metric with given tag.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)setValue:(int64_t)value forTag:(RCTPLTag)tag;
/**
* Adds given value to the current value for a metric with given tag.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)addValue:(int64_t)value forTag:(RCTPLTag)tag;
/**
* Starts an additional measurement for a metric with given tag.
* It doesn't override previous measurement, instead it'll append a new value
* to the old one.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)appendStartForTag:(RCTPLTag)tag;
/**
* Stops measurement and appends the result to the metric with given tag.
* Checks if RCTPerformanceLoggerAppendStart() has been called before
* and doesn't do anything and log a message if it hasn't.
* All work is scheduled on the background queue so this doesn't block current thread.
*/
- (void)appendStopForTag:(RCTPLTag)tag;
/**
* Returns an array with values for all tags.
* Use RCTPLTag to go over the array, there's a pair of values
* for each tag: start and stop (with indexes 2 * tag and 2 * tag + 1).
*/
- (NSArray<NSNumber *> *)valuesForTags;
/**
* Returns a duration in ms (stop_time - start_time) for given RCTPLTag.
*/
- (int64_t)durationForTag:(RCTPLTag)tag;
/**
* Returns a value for given RCTPLTag.
*/
- (int64_t)valueForTag:(RCTPLTag)tag;
@end

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <QuartzCore/QuartzCore.h>
#import <cxxreact/ReactMarker.h>
#include <unordered_map>
#import "RCTLog.h"
#import "RCTPerformanceLogger.h"
#import "RCTPerformanceLoggerLabels.h"
#import "RCTProfile.h"
#import "RCTRootView.h"
using namespace facebook::react;
@interface RCTPerformanceLogger () {
int64_t _data[RCTPLSize][2];
NSInteger _cookies[RCTPLSize];
}
@end
@implementation RCTPerformanceLogger
static const std::unordered_map<RCTPLTag, ReactMarker::ReactMarkerId> &getStartTagToReactMarkerIdMap()
{
static std::unordered_map<RCTPLTag, ReactMarker::ReactMarkerId> StartTagToReactMarkerIdMap = {
{RCTPLAppStartup, ReactMarker::APP_STARTUP_START},
{RCTPLInitReactRuntime, ReactMarker::INIT_REACT_RUNTIME_START},
{RCTPLScriptExecution, ReactMarker::RUN_JS_BUNDLE_START}};
return StartTagToReactMarkerIdMap;
}
static const std::unordered_map<RCTPLTag, ReactMarker::ReactMarkerId> &getStopTagToReactMarkerIdMap()
{
static std::unordered_map<RCTPLTag, ReactMarker::ReactMarkerId> StopTagToReactMarkerIdMap = {
{RCTPLAppStartup, ReactMarker::APP_STARTUP_STOP},
{RCTPLInitReactRuntime, ReactMarker::INIT_REACT_RUNTIME_STOP},
{RCTPLScriptExecution, ReactMarker::RUN_JS_BUNDLE_STOP}};
return StopTagToReactMarkerIdMap;
}
- (void)markStartForTag:(RCTPLTag)tag
{
#if RCT_PROFILE
if (RCTProfileIsProfiling()) {
NSString *label = RCTPLLabelForTag(tag);
_cookies[tag] = RCTProfileBeginAsyncEvent(RCTProfileTagAlways, label, nil);
}
#endif
const NSTimeInterval currentTime = CACurrentMediaTime() * 1000;
_data[tag][0] = currentTime;
_data[tag][1] = 0;
// Notify RN ReactMarker when hosting platform log for markers
const auto &startTagToReactMarkerIdMap = getStartTagToReactMarkerIdMap();
if (startTagToReactMarkerIdMap.find(tag) != startTagToReactMarkerIdMap.end()) {
ReactMarker::logMarkerDone(startTagToReactMarkerIdMap.at(tag), currentTime);
}
}
- (void)markStopForTag:(RCTPLTag)tag
{
#if RCT_PROFILE
if (RCTProfileIsProfiling()) {
NSString *label = RCTPLLabelForTag(tag);
RCTProfileEndAsyncEvent(RCTProfileTagAlways, @"native", _cookies[tag], label, @"RCTPerformanceLogger");
}
#endif
const NSTimeInterval currentTime = CACurrentMediaTime() * 1000;
if (_data[tag][0] != 0 && _data[tag][1] == 0) {
_data[tag][1] = currentTime;
} else {
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
}
// Notify RN ReactMarker when hosting platform log for markers
const auto &stopTagToReactMarkerIdMap = getStopTagToReactMarkerIdMap();
if (stopTagToReactMarkerIdMap.find(tag) != stopTagToReactMarkerIdMap.end()) {
ReactMarker::logMarkerDone(stopTagToReactMarkerIdMap.at(tag), currentTime);
}
}
- (void)setValue:(int64_t)value forTag:(RCTPLTag)tag
{
_data[tag][0] = 0;
_data[tag][1] = value;
}
- (void)addValue:(int64_t)value forTag:(RCTPLTag)tag
{
_data[tag][0] = 0;
_data[tag][1] += value;
}
- (void)appendStartForTag:(RCTPLTag)tag
{
_data[tag][0] = CACurrentMediaTime() * 1000;
}
- (void)appendStopForTag:(RCTPLTag)tag
{
if (_data[tag][0] != 0) {
_data[tag][1] += CACurrentMediaTime() * 1000 - _data[tag][0];
_data[tag][0] = 0;
} else {
RCTLogInfo(@"Unbalanced calls start/end for tag %li", (unsigned long)tag);
}
}
- (NSArray<NSNumber *> *)valuesForTags
{
NSMutableArray *result = [NSMutableArray array];
for (NSUInteger index = 0; index < RCTPLSize; index++) {
[result addObject:@(_data[index][0])];
[result addObject:@(_data[index][1])];
}
return result;
}
- (int64_t)durationForTag:(RCTPLTag)tag
{
return _data[tag][1] - _data[tag][0];
}
- (int64_t)valueForTag:(RCTPLTag)tag
{
return _data[tag][1];
}
@end

View File

@@ -0,0 +1,12 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
#import "RCTPLTag.h"
// Return the string label for the enum RCTPLTag for performance logging
__attribute__((used)) RCT_EXTERN NSString *RCTPLLabelForTag(RCTPLTag tag);

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTPerformanceLoggerLabels.h"
#import <React/RCTAssert.h>
NSString *RCTPLLabelForTag(RCTPLTag tag)
{
switch (tag) {
case RCTPLScriptDownload:
return @"ScriptDownload";
case RCTPLScriptExecution:
return @"ScriptExecution";
case RCTPLRAMBundleLoad:
return @"RAMBundleLoad";
case RCTPLRAMStartupCodeSize:
return @"RAMStartupCodeSize";
case RCTPLRAMStartupNativeRequires:
return @"RAMStartupNativeRequires";
case RCTPLRAMStartupNativeRequiresCount:
return @"RAMStartupNativeRequiresCount";
case RCTPLRAMNativeRequires:
return @"RAMNativeRequires";
case RCTPLRAMNativeRequiresCount:
return @"RAMNativeRequiresCount";
case RCTPLNativeModuleInit:
return @"NativeModuleInit";
case RCTPLNativeModuleMainThread:
return @"NativeModuleMainThread";
case RCTPLNativeModulePrepareConfig:
return @"NativeModulePrepareConfig";
case RCTPLNativeModuleMainThreadUsesCount:
return @"NativeModuleMainThreadUsesCount";
case RCTPLNativeModuleSetup:
return @"NativeModuleSetup";
case RCTPLTurboModuleSetup:
return @"TurboModuleSetup";
case RCTPLJSCWrapperOpenLibrary:
return @"JSCWrapperOpenLibrary";
case RCTPLBridgeStartup:
return @"BridgeStartup";
case RCTPLTTI:
return @"RootViewTTI";
case RCTPLBundleSize:
return @"BundleSize";
case RCTPLReactInstanceInit:
return @"ReactInstanceInit";
case RCTPLAppStartup:
return @"AppStartup";
case RCTPLInitReactRuntime:
return @"InitReactRuntime";
case RCTPLSize: // Only used to count enum size
RCTAssert(NO, @"RCTPLSize should not be used to track performance timestamps.");
return nil;
}
}

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTDefines.h>
// In debug builds, the red box is enabled by default but it is further
// customizable using this method. However, this method only has an effect in
// builds where RCTRedBox is actually compiled in.
RCT_EXTERN void RCTRedBoxSetEnabled(BOOL enabled);
RCT_EXTERN BOOL RCTRedBoxGetEnabled(void);

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTRedBoxSetEnabled.h"
#if RCT_DEV
static BOOL redBoxEnabled = YES;
#else
static BOOL redBoxEnabled = NO;
#endif
void RCTRedBoxSetEnabled(BOOL enabled)
{
redBoxEnabled = enabled;
}
BOOL RCTRedBoxGetEnabled(void)
{
return redBoxEnabled;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
/**
* A protocol which should be conformed to in order to be notified of RN reload events. These events can be
* created by CMD+R or dev menu during development, or anywhere the trigger is exposed to JS.
* The listener must also register itself using the method below.
*/
@protocol RCTReloadListener
- (void)didReceiveReloadCommand;
@end
/**
* Registers a weakly-held observer of RN reload events.
*/
RCT_EXTERN void RCTRegisterReloadCommandListener(id<RCTReloadListener> listener);
/**
* Triggers a reload for all current listeners. Replaces [_bridge reload].
*/
RCT_EXTERN void RCTTriggerReloadCommandListeners(NSString *reason);
/**
* This notification fires anytime RCTTriggerReloadCommandListeners() is called.
*/
RCT_EXTERN NSString *const RCTTriggerReloadCommandNotification;
RCT_EXTERN NSString *const RCTTriggerReloadCommandReasonKey;
RCT_EXTERN NSString *const RCTTriggerReloadCommandBundleURLKey;
RCT_EXTERN void RCTReloadCommandSetBundleURL(NSURL *URL);

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTReloadCommand.h"
#import "RCTAssert.h"
#import "RCTKeyCommands.h"
#import "RCTUtils.h"
static NSHashTable<id<RCTReloadListener>> *listeners;
static NSLock *listenersLock;
static NSURL *bundleURL;
NSString *const RCTTriggerReloadCommandNotification = @"RCTTriggerReloadCommandNotification";
NSString *const RCTTriggerReloadCommandReasonKey = @"reason";
NSString *const RCTTriggerReloadCommandBundleURLKey = @"bundleURL";
void RCTRegisterReloadCommandListener(id<RCTReloadListener> listener)
{
if (!listenersLock) {
listenersLock = [NSLock new];
}
[listenersLock lock];
if (!listeners) {
listeners = [NSHashTable weakObjectsHashTable];
}
#if RCT_DEV
RCTAssertMainQueue(); // because registerKeyCommandWithInput: must be called on the main thread
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r"
modifierFlags:UIKeyModifierCommand
action:^(__unused UIKeyCommand *command) {
RCTTriggerReloadCommandListeners(@"Command + R");
}];
});
#endif
[listeners addObject:listener];
[listenersLock unlock];
}
void RCTTriggerReloadCommandListeners(NSString *reason)
{
[listenersLock lock];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTTriggerReloadCommandNotification
object:nil
userInfo:@{
RCTTriggerReloadCommandReasonKey : RCTNullIfNil(reason),
RCTTriggerReloadCommandBundleURLKey : RCTNullIfNil(bundleURL)
}];
for (id<RCTReloadListener> l in [listeners allObjects]) {
[l didReceiveReloadCommand];
}
[listenersLock unlock];
}
void RCTReloadCommandSetBundleURL(NSURL *URL)
{
bundleURL = URL;
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#ifndef RCT_REMOVE_LEGACY_ARCH
#import <React/RCTInvalidating.h>
#import <React/RCTRootView.h>
#import <React/RCTView.h>
@class RCTBridge;
@class RCTTouchHandler;
@interface RCTRootContentView : RCTView <RCTInvalidating>
@property (nonatomic, readonly, weak)
RCTBridge *bridge __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, readonly, assign)
BOOL contentHasAppeared __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, readonly, strong)
RCTTouchHandler *touchHandler __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, readonly, assign)
CGSize availableSize __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, assign)
BOOL passThroughTouches __deprecated_msg("This API will be removed along with the legacy architecture.");
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility __deprecated_msg(
"This API will be removed along with the legacy architecture.");
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
reactTag:(NSNumber *)reactTag
sizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility NS_DESIGNATED_INITIALIZER
__deprecated_msg("This API will be removed along with the legacy architecture.");
@end
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTRootContentView.h"
#ifndef RCT_REMOVE_LEGACY_ARCH
#import "RCTBridge.h"
#import "RCTPerformanceLogger.h"
#import "RCTRootView.h"
#import "RCTRootViewInternal.h"
#import "RCTTouchHandler.h"
#import "RCTUIManager.h"
#import "UIView+React.h"
@implementation RCTRootContentView
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
reactTag:(NSNumber *)reactTag
sizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
{
if ((self = [super initWithFrame:frame])) {
_bridge = bridge;
self.reactTag = reactTag;
_sizeFlexibility = sizeFlexibility;
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
[_touchHandler attachToView:self];
[_bridge.uiManager registerRootView:self];
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (nonnull NSCoder *)aDecoder)
- (void)layoutSubviews
{
[super layoutSubviews];
[self updateAvailableSize];
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
dispatch_async(dispatch_get_main_queue(), ^{
if (!self->_contentHasAppeared) {
self->_contentHasAppeared = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self.superview];
}
});
}
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
{
if (_sizeFlexibility == sizeFlexibility) {
return;
}
_sizeFlexibility = sizeFlexibility;
[self setNeedsLayout];
}
- (CGSize)availableSize
{
CGSize size = self.bounds.size;
return CGSizeMake(
_sizeFlexibility & RCTRootViewSizeFlexibilityWidth ? INFINITY : size.width,
_sizeFlexibility & RCTRootViewSizeFlexibilityHeight ? INFINITY : size.height);
}
- (void)updateAvailableSize
{
if (!self.reactTag || !_bridge.isValid) {
return;
}
[_bridge.uiManager setAvailableSize:self.availableSize forRootView:self];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// The root content view itself should never receive touches
UIView *hitView = [super hitTest:point withEvent:event];
if (_passThroughTouches && hitView == self) {
return nil;
}
return hitView;
}
- (void)invalidate
{
if (self.userInteractionEnabled) {
self.userInteractionEnabled = NO;
[(RCTRootView *)self.superview contentViewInvalidated];
[_bridge enqueueJSCall:@"AppRegistry"
method:@"unmountApplicationComponentAtRootTag"
args:@[ self.reactTag ]
completion:NULL];
}
}
@end
#endif // RCT_REMOVE_LEGACY_ARCH

181
node_modules/react-native/React/Base/RCTRootView.h generated vendored Normal file
View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventDispatcherProtocol.h>
@protocol RCTRootViewDelegate;
/**
* This enum is used to define size flexibility type of the root view.
* If a dimension is flexible, the view will recalculate that dimension
* so the content fits. Recalculations are performed when the root's frame,
* size flexibility mode or content size changes. After a recalculation,
* rootViewDidChangeIntrinsicSize method of the RCTRootViewDelegate will be called.
*/
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
RCTRootViewSizeFlexibilityNone = 0,
RCTRootViewSizeFlexibilityWidth = 1 << 0,
RCTRootViewSizeFlexibilityHeight = 1 << 1,
RCTRootViewSizeFlexibilityWidthAndHeight = RCTRootViewSizeFlexibilityWidth | RCTRootViewSizeFlexibilityHeight,
};
/**
* This notification is sent when the first subviews are added to the root view
* after the application has loaded. This is used to hide the `loadingView`, and
* is a good indicator that the application is ready to use.
*/
#if defined(__cplusplus)
extern "C"
#else
extern
#endif
NS_ASSUME_NONNULL_BEGIN
NSString *const RCTContentDidAppearNotification;
/**
* Native view used to host React-managed views within the app. Can be used just
* like any ordinary UIView. You can have multiple RCTRootViews on screen at
* once, all controlled by the same JavaScript application.
*/
__deprecated_msg("This API will be removed along with the legacy architecture.") @interface RCTRootView : UIView
/**
* - Designated initializer -
*/
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
/**
* - Convenience initializer -
* The frame will default to CGRectZero.
*/
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties;
/**
* - Convenience initializer -
* A bridge will be created internally.
* This initializer is intended to be used when the app has a single RCTRootView,
* otherwise create an `RCTBridge` and pass it in via `initWithBridge:moduleName:`
* to all the instances.
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties
launchOptions:(nullable NSDictionary *)launchOptions;
/**
* The name of the JavaScript module to execute within the
* specified scriptURL (required). Setting this will not have
* any immediate effect, but it must be done prior to loading
* the script.
*/
@property (nonatomic, copy, readonly) NSString *moduleName;
/**
* The bridge used by the root view. Bridges can be shared between multiple
* root views, so you can use this property to initialize another RCTRootView.
*/
@property (nonatomic, strong, readonly) RCTBridge *bridge;
/**
* The properties to apply to the view. Use this property to update
* application properties and rerender the view. Initialized with
* initialProperties argument of the initializer.
*
* Set this property only on the main thread.
*/
@property (nonatomic, copy, readwrite, nullable) NSDictionary *appProperties;
/**
* The size flexibility mode of the root view.
*/
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
/*
* The minimum size of the root view, defaults to CGSizeZero.
*/
@property (nonatomic, assign) CGSize minimumSize;
/**
* The delegate that handles intrinsic size updates.
*/
@property (nonatomic, weak, nullable) id<RCTRootViewDelegate> delegate;
/**
* The backing view controller of the root view.
*/
@property (nonatomic, weak, nullable) UIViewController *reactViewController;
/**
* The root view casted as UIView. Used by splash screen libraries.
*/
@property (nonatomic, strong, readonly) UIView *view;
/**
* The React-managed contents view of the root view.
*/
@property (nonatomic, strong, readonly) UIView *contentView;
/**
* A view to display while the JavaScript is loading, so users aren't presented
* with a blank screen. By default this is nil, but you can override it with
* (for example) a UIActivityIndicatorView or a placeholder image.
*/
@property (nonatomic, strong, nullable) UIView *loadingView;
/**
* When set, any touches on the RCTRootView that are not matched up to any of the child
* views will be passed to siblings of the RCTRootView. See -[UIView hitTest:withEvent:]
* for details on iOS hit testing.
*
* Enable this to support a semi-transparent RN view that occupies the whole screen but
* has visible content below it that the user can interact with.
*
* The default value is NO.
*/
@property (nonatomic, assign) BOOL passThroughTouches;
/**
* Timings for hiding the loading view after the content has loaded. Both of
* these values default to 0.25 seconds.
*/
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
@end
@interface RCTRootView (Deprecated)
/**
* The intrinsic size of the root view's content. This is set right before the
* `rootViewDidChangeIntrinsicSize` method of `RCTRootViewDelegate` is called.
* This property is deprecated and will be removed in next releases.
* Use UIKit `intrinsicContentSize` property instead.
*/
@property (readonly, nonatomic, assign) CGSize intrinsicSize __deprecated_msg("Use `intrinsicContentSize` instead.");
/**
* This methods is deprecated and will be removed soon.
* To interrupt a React Native gesture recognizer, use the standard
* `UIGestureRecognizer` negotiation process.
* See `UIGestureRecognizerDelegate` for more details.
*/
- (void)cancelTouches;
@end
NS_ASSUME_NONNULL_END

430
node_modules/react-native/React/Base/RCTRootView.m generated vendored Normal file
View File

@@ -0,0 +1,430 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTRootView.h"
#import "RCTRootViewDelegate.h"
#import "RCTRootViewInternal.h"
#import <objc/runtime.h>
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTConstants.h"
#import "RCTKeyCommands.h"
#import "RCTLog.h"
#import "RCTPerformanceLogger.h"
#import "RCTProfile.h"
#import "RCTRootContentView.h"
#import "RCTRootShadowView.h"
#import "RCTTouchHandler.h"
#import "RCTUIManager.h"
#import "RCTUIManagerUtils.h"
#import "RCTUtils.h"
#import "RCTView.h"
#import "UIView+React.h"
NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification";
#ifndef RCT_REMOVE_LEGACY_ARCH
@implementation RCTRootView {
RCTBridge *_bridge;
NSString *_moduleName;
RCTRootContentView *_contentView;
BOOL _passThroughTouches;
CGSize _intrinsicContentSize;
}
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
{
RCTAssertMainQueue();
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
RCTAssert(moduleName, @"A moduleName is required to create an RCTRootView");
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTRootView init]", nil);
if (!bridge.isLoading) {
[bridge.performanceLogger markStartForTag:RCTPLTTI];
}
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
_bridge = bridge;
_moduleName = moduleName;
_appProperties = [initialProperties copy];
_loadingViewFadeDelay = 0.25;
_loadingViewFadeDuration = 0.25;
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
_minimumSize = CGSizeZero;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(bridgeDidReload)
name:RCTJavaScriptWillStartLoadingNotification
object:_bridge];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(javaScriptDidLoad:)
name:RCTJavaScriptDidLoadNotification
object:_bridge];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(hideLoadingView)
name:RCTContentDidAppearNotification
object:self];
[self showLoadingView];
// Immediately schedule the application to be started.
// (Sometimes actual `_bridge` is already batched bridge here.)
[self bundleFinishedLoading:([_bridge batchedBridge] ?: _bridge)];
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
return self;
}
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
{
return [self initWithFrame:CGRectZero bridge:bridge moduleName:moduleName initialProperties:initialProperties];
}
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:bundleURL moduleProvider:nil launchOptions:launchOptions];
return [self initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
}
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
- (UIView *)view
{
return self;
}
#pragma mark - passThroughTouches
- (BOOL)passThroughTouches
{
return _contentView.passThroughTouches;
}
- (void)setPassThroughTouches:(BOOL)passThroughTouches
{
_passThroughTouches = passThroughTouches;
_contentView.passThroughTouches = passThroughTouches;
}
#pragma mark - Layout
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize fitSize = _intrinsicContentSize;
CGSize currentSize = self.bounds.size;
// Following the current `size` and current `sizeFlexibility` policy.
fitSize = CGSizeMake(
_sizeFlexibility & RCTRootViewSizeFlexibilityWidth ? fitSize.width : currentSize.width,
_sizeFlexibility & RCTRootViewSizeFlexibilityHeight ? fitSize.height : currentSize.height);
// Following the given size constraints.
fitSize = CGSizeMake(MIN(size.width, fitSize.width), MIN(size.height, fitSize.height));
return fitSize;
}
- (void)layoutSubviews
{
[super layoutSubviews];
_contentView.frame = self.bounds;
_loadingView.center = (CGPoint){CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)};
}
- (void)setMinimumSize:(CGSize)minimumSize
{
if (CGSizeEqualToSize(_minimumSize, minimumSize)) {
return;
}
_minimumSize = minimumSize;
__block NSNumber *tag = self.reactTag;
__weak typeof(self) weakSelf = self;
RCTExecuteOnUIManagerQueue(^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf && strongSelf->_bridge.isValid) {
RCTRootShadowView *shadowView = (RCTRootShadowView *)[strongSelf->_bridge.uiManager shadowViewForReactTag:tag];
shadowView.minimumSize = minimumSize;
}
});
}
- (UIViewController *)reactViewController
{
return _reactViewController ?: [super reactViewController];
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (void)setLoadingView:(UIView *)loadingView
{
_loadingView = loadingView;
if (!_contentView.contentHasAppeared) {
[self showLoadingView];
}
}
- (void)showLoadingView
{
if (_loadingView && !_contentView.contentHasAppeared) {
_loadingView.hidden = NO;
[self addSubview:_loadingView];
}
}
- (void)hideLoadingView
{
if (_loadingView.superview == self && _contentView.contentHasAppeared) {
if (_loadingViewFadeDuration > 0) {
dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_loadingViewFadeDelay * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
[UIView transitionWithView:self
duration:self->_loadingViewFadeDuration
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self->_loadingView.hidden = YES;
}
completion:^(__unused BOOL finished) {
[self->_loadingView removeFromSuperview];
}];
});
} else {
_loadingView.hidden = YES;
[_loadingView removeFromSuperview];
}
}
}
- (NSNumber *)reactTag
{
RCTAssertMainQueue();
if (!super.reactTag) {
/**
* Every root view that is created must have a unique react tag.
* Numbering of these tags goes from 1, 11, 21, 31, etc
*
* NOTE: Since the bridge persists, the RootViews might be reused, so the
* react tag must be re-assigned every time a new UIManager is created.
*/
self.reactTag = RCTAllocateRootViewTag();
}
return super.reactTag;
}
- (void)bridgeDidReload
{
RCTAssertMainQueue();
// Clear the reactTag so it can be re-assigned
self.reactTag = nil;
}
- (void)javaScriptDidLoad:(NSNotification *)notification
{
RCTAssertMainQueue();
// Use the (batched) bridge that's sent in the notification payload, so the
// RCTRootContentView is scoped to the right bridge
RCTBridge *bridge = notification.userInfo[@"bridge"];
if (bridge != _contentView.bridge) {
[self bundleFinishedLoading:bridge];
}
}
- (void)bundleFinishedLoading:(RCTBridge *)bridge
{
RCTAssert(bridge != nil, @"Bridge cannot be nil");
if (!bridge.valid) {
return;
}
[_contentView removeFromSuperview];
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds
bridge:bridge
reactTag:self.reactTag
sizeFlexibility:_sizeFlexibility];
[self runApplication:bridge];
_contentView.passThroughTouches = _passThroughTouches;
[self insertSubview:_contentView atIndex:0];
if (_sizeFlexibility == RCTRootViewSizeFlexibilityNone) {
self.intrinsicContentSize = self.bounds.size;
}
}
- (void)runApplication:(RCTBridge *)bridge
{
NSString *moduleName = _moduleName ?: @"";
NSDictionary *appParameters = @{
@"rootTag" : _contentView.reactTag,
@"initialProps" : _appProperties ?: @{},
};
RCTLogInfo(@"Running application %@ (%@)", moduleName, appParameters);
[bridge enqueueJSCall:@"AppRegistry" method:@"runApplication" args:@[ moduleName, appParameters ] completion:NULL];
}
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
{
if (_sizeFlexibility == sizeFlexibility) {
return;
}
_sizeFlexibility = sizeFlexibility;
[self setNeedsLayout];
_contentView.sizeFlexibility = _sizeFlexibility;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// The root view itself should never receive touches
UIView *hitView = [super hitTest:point withEvent:event];
if (self.passThroughTouches && hitView == self) {
return nil;
}
return hitView;
}
- (void)setAppProperties:(NSDictionary *)appProperties
{
RCTAssertMainQueue();
if ([_appProperties isEqualToDictionary:appProperties]) {
return;
}
_appProperties = [appProperties copy];
if (_contentView && _bridge.valid && !_bridge.loading) {
[self runApplication:_bridge];
}
}
- (void)setIntrinsicContentSize:(CGSize)intrinsicContentSize
{
BOOL oldSizeHasAZeroDimension = _intrinsicContentSize.height == 0 || _intrinsicContentSize.width == 0;
BOOL newSizeHasAZeroDimension = intrinsicContentSize.height == 0 || intrinsicContentSize.width == 0;
BOOL bothSizesHaveAZeroDimension = oldSizeHasAZeroDimension && newSizeHasAZeroDimension;
BOOL sizesAreEqual = CGSizeEqualToSize(_intrinsicContentSize, intrinsicContentSize);
_intrinsicContentSize = intrinsicContentSize;
// Don't notify the delegate if the content remains invisible or its size has not changed
if (bothSizesHaveAZeroDimension || sizesAreEqual) {
return;
}
[self invalidateIntrinsicContentSize];
[self.superview setNeedsLayout];
[_delegate rootViewDidChangeIntrinsicSize:self];
}
- (CGSize)intrinsicContentSize
{
return _intrinsicContentSize;
}
- (void)contentViewInvalidated
{
[_contentView removeFromSuperview];
_contentView = nil;
[self showLoadingView];
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
[super traitCollectionDidChange:previousTraitCollection];
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
return;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:RCTUserInterfaceStyleDidChangeNotification
object:self
userInfo:@{
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
}];
}
- (void)dealloc
{
[_contentView invalidate];
}
@end
@implementation RCTRootView (Deprecated)
- (CGSize)intrinsicSize
{
RCTLogWarn(@"Calling deprecated `[-RCTRootView intrinsicSize]`.");
return self.intrinsicContentSize;
}
- (void)cancelTouches
{
RCTLogWarn(@"`-[RCTRootView cancelTouches]` is deprecated and will be deleted soon.");
[[_contentView touchHandler] cancel];
}
@end
#else // RCT_REMOVE_LEGACY_ARCH
@implementation RCTRootView
- (nonnull instancetype)initWithFrame:(CGRect)frame
bridge:(nonnull RCTBridge *)bridge
moduleName:(nonnull NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties
{
return self;
}
- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge
moduleName:(nonnull NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties
{
return self;
}
- (nonnull instancetype)initWithBundleURL:(nonnull NSURL *)bundleURL
moduleName:(nonnull NSString *)moduleName
initialProperties:(nullable NSDictionary *)initialProperties
launchOptions:(nullable NSDictionary *)launchOptions
{
return self;
}
@end
#endif // RCT_REMOVE_LEGACY_ARCH

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@class RCTRootView;
@protocol RCTRootViewDelegate <NSObject>
/**
* Called after the root view's intrinsic content size is changed.
*
* The method is not called when both old size and new size have
* a dimension that equals to zero.
*
* The delegate can use this callback to appropriately resize
* the root view's frame to fit the new intrinsic content view size,
* but usually it is not necessary because the root view will also call
* `setNeedsLayout` for its superview which in its turn will trigger relayout.
*
* The new intrinsic content size is available via the `intrinsicContentSize`
* property of the root view. The view will not resize itself.
*/
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView;
@end

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTRootView.h>
#ifndef RCT_REMOVE_LEGACY_ARCH
/**
* The interface provides a set of functions that allow other internal framework
* classes to change the RCTRootViews's internal state.
*/
__deprecated_msg("This API will be removed along with the legacy architecture.") @interface RCTRootView()
/**
* This setter should be used only by RCTUIManager on react root view
* intrinsic content size update.
*/
@property (readwrite, nonatomic, assign) CGSize intrinsicContentSize;
- (void)contentViewInvalidated;
@end
#endif // RCT_REMOVE_LEGACY_ARCH

23
node_modules/react-native/React/Base/RCTTouchEvent.h generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTEventDispatcherProtocol.h>
/**
* Represents a touch event, which may be composed of several touches (one for every finger).
* For more information on contents of passed data structures see RCTTouchHandler.
*/
@interface RCTTouchEvent : NSObject <RCTEvent>
- (instancetype)initWithEventName:(NSString *)eventName
reactTag:(NSNumber *)reactTag
reactTouches:(NSArray<NSDictionary *> *)reactTouches
changedIndexes:(NSArray<NSNumber *> *)changedIndexes
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
@end

107
node_modules/react-native/React/Base/RCTTouchEvent.m generated vendored Normal file
View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTTouchEvent.h"
#import "RCTAssert.h"
@implementation RCTTouchEvent {
NSArray<NSDictionary *> *_reactTouches;
NSArray<NSNumber *> *_changedIndexes;
uint16_t _coalescingKey;
}
@synthesize eventName = _eventName;
@synthesize viewTag = _viewTag;
- (instancetype)initWithEventName:(NSString *)eventName
reactTag:(NSNumber *)reactTag
reactTouches:(NSArray<NSDictionary *> *)reactTouches
changedIndexes:(NSArray<NSNumber *> *)changedIndexes
coalescingKey:(uint16_t)coalescingKey
{
if (self = [super init]) {
_viewTag = reactTag;
_eventName = eventName;
_reactTouches = reactTouches;
_changedIndexes = changedIndexes;
_coalescingKey = coalescingKey;
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
#pragma mark - RCTEvent
- (BOOL)canCoalesce
{
return [_eventName isEqual:@"touchMove"];
}
// We coalesce only move events, while holding some assumptions that seem reasonable but there are no explicit
// guarantees about them.
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent
{
RCTAssert(
[newEvent isKindOfClass:[RCTTouchEvent class]],
@"Touch event cannot be coalesced with any other type of event, such as provided %@",
newEvent);
RCTTouchEvent *newTouchEvent = (RCTTouchEvent *)newEvent;
RCTAssert(
[_reactTouches count] == [newTouchEvent->_reactTouches count],
@"Touch events have different number of touches. %@ %@",
self,
newEvent);
BOOL newEventIsMoreRecent = NO;
__unused BOOL oldEventIsMoreRecent = NO;
NSInteger count = _reactTouches.count;
for (int i = 0; i < count; i++) {
NSDictionary *touch = _reactTouches[i];
NSDictionary *newTouch = newTouchEvent->_reactTouches[i];
RCTAssert(
[touch[@"identifier"] isEqual:newTouch[@"identifier"]],
@"Touch events doesn't have touches in the same order. %@ %@",
touch,
newTouch);
if ([touch[@"timestamp"] doubleValue] > [newTouch[@"timestamp"] doubleValue]) {
oldEventIsMoreRecent = YES;
} else {
newEventIsMoreRecent = YES;
}
}
RCTAssert(
!(oldEventIsMoreRecent && newEventIsMoreRecent),
@"Neither touch event is exclusively more recent than the other one. %@ %@",
_reactTouches,
newTouchEvent->_reactTouches);
return newEventIsMoreRecent ? newEvent : self;
}
+ (NSString *)moduleDotMethod
{
return @"RCTEventEmitter.receiveTouches";
}
- (NSArray *)arguments
{
return @[ RCTNormalizeInputEventName(_eventName), _reactTouches, _changedIndexes ];
}
- (uint16_t)coalescingKey
{
return _coalescingKey;
}
- (NSString *)description
{
return [NSString
stringWithFormat:@"<%@: %p; name = %@; coalescing key = %hu>", [self class], self, _eventName, _coalescingKey];
}
@end

23
node_modules/react-native/React/Base/RCTTouchHandler.h generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTFrameUpdate.h>
@class RCTBridge;
@interface RCTTouchHandler : UIGestureRecognizer
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
- (void)attachToView:(UIView *)view;
- (void)detachFromView:(UIView *)view;
- (void)cancel;
@end

377
node_modules/react-native/React/Base/RCTTouchHandler.m generated vendored Normal file
View File

@@ -0,0 +1,377 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTTouchHandler.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
#import "RCTAssert.h"
#import "RCTBridge.h"
#import "RCTEventDispatcherProtocol.h"
#import "RCTLog.h"
#import "RCTSurfaceView.h"
#import "RCTTouchEvent.h"
#import "RCTUIManager.h"
#import "RCTUtils.h"
#import "UIView+React.h"
@interface RCTTouchHandler () <UIGestureRecognizerDelegate>
@end
// TODO: this class behaves a lot like a module, and could be implemented as a
// module if we were to assume that modules and RootViews had a 1:1 relationship
@implementation RCTTouchHandler {
__weak id<RCTEventDispatcherProtocol> _eventDispatcher;
/**
* Arrays managed in parallel tracking native touch object along with the
* native view that was touched, and the React touch data dictionary.
* These must be kept track of because `UIKit` destroys the touch targets
* if touches are canceled, and we have no other way to recover this info.
*/
NSMutableOrderedSet<UITouch *> *_nativeTouches;
NSMutableArray<NSMutableDictionary *> *_reactTouches;
NSMutableArray<UIView *> *_touchViews;
__weak UIView *_cachedRootView;
uint16_t _coalescingKey;
}
- (instancetype)initWithBridge:(RCTBridge *)bridge
{
RCTAssertParam(bridge);
if ((self = [super initWithTarget:nil action:NULL])) {
_eventDispatcher = bridge.eventDispatcher;
_nativeTouches = [NSMutableOrderedSet new];
_reactTouches = [NSMutableArray new];
_touchViews = [NSMutableArray new];
// `cancelsTouchesInView` and `delaysTouches*` are needed in order to be used as a top level
// event delegated recognizer. Otherwise, lower-level components not built
// using RCT, will fail to recognize gestures.
self.cancelsTouchesInView = NO;
self.delaysTouchesBegan = NO; // This is default value.
self.delaysTouchesEnded = NO;
self.delegate = self;
}
return self;
}
RCT_NOT_IMPLEMENTED(-(instancetype)initWithTarget : (id)target action : (SEL)action)
- (void)attachToView:(UIView *)view
{
RCTAssert(self.view == nil, @"RCTTouchHandler already has attached view.");
[view addGestureRecognizer:self];
}
- (void)detachFromView:(UIView *)view
{
RCTAssertParam(view);
RCTAssert(self.view == view, @"RCTTouchHandler attached to another view.");
[view removeGestureRecognizer:self];
}
#pragma mark - Bookkeeping for touch indices
- (void)_recordNewTouches:(NSSet<UITouch *> *)touches
{
for (UITouch *touch in touches) {
RCTAssert(![_nativeTouches containsObject:touch], @"Touch is already recorded. This is a critical bug.");
// Find closest React-managed touchable view
UIView *targetView = touch.view;
while (targetView) {
if (targetView.reactTag && targetView.userInteractionEnabled) {
break;
}
targetView = targetView.superview;
}
NSNumber *reactTag = [targetView reactTagAtPoint:[touch locationInView:targetView]];
if (!reactTag || !targetView.userInteractionEnabled) {
continue;
}
// Get new, unique touch identifier for the react touch
const NSUInteger RCTMaxTouches = 11; // This is the maximum supported by iDevices
NSInteger touchID = ([_reactTouches.lastObject[@"identifier"] integerValue] + 1) % RCTMaxTouches;
for (NSDictionary *reactTouch in _reactTouches) {
NSInteger usedID = [reactTouch[@"identifier"] integerValue];
if (usedID == touchID) {
// ID has already been used, try next value
touchID++;
} else if (usedID > touchID) {
// If usedID > touchID, touchID must be unique, so we can stop looking
break;
}
}
// Create touch
NSMutableDictionary *reactTouch = [[NSMutableDictionary alloc] initWithCapacity:RCTMaxTouches];
reactTouch[@"target"] = reactTag;
reactTouch[@"identifier"] = @(touchID);
// Add to arrays
[_touchViews addObject:targetView];
[_nativeTouches addObject:touch];
[_reactTouches addObject:reactTouch];
}
}
- (void)_recordRemovedTouches:(NSSet<UITouch *> *)touches
{
for (UITouch *touch in touches) {
NSUInteger index = [_nativeTouches indexOfObject:touch];
if (index == NSNotFound) {
continue;
}
[_touchViews removeObjectAtIndex:index];
[_nativeTouches removeObjectAtIndex:index];
[_reactTouches removeObjectAtIndex:index];
}
}
- (void)_updateReactTouchAtIndex:(NSInteger)touchIndex
{
UITouch *nativeTouch = _nativeTouches[touchIndex];
CGPoint windowLocation = [nativeTouch locationInView:nativeTouch.window];
RCTAssert(_cachedRootView, @"We were unable to find a root view for the touch");
CGPoint rootViewLocation = [nativeTouch.window convertPoint:windowLocation toView:_cachedRootView];
UIView *touchView = _touchViews[touchIndex];
CGPoint touchViewLocation = [nativeTouch.window convertPoint:windowLocation toView:touchView];
NSMutableDictionary *reactTouch = _reactTouches[touchIndex];
reactTouch[@"pageX"] = @(RCTSanitizeNaNValue(rootViewLocation.x, @"touchEvent.pageX"));
reactTouch[@"pageY"] = @(RCTSanitizeNaNValue(rootViewLocation.y, @"touchEvent.pageY"));
reactTouch[@"locationX"] = @(RCTSanitizeNaNValue(touchViewLocation.x, @"touchEvent.locationX"));
reactTouch[@"locationY"] = @(RCTSanitizeNaNValue(touchViewLocation.y, @"touchEvent.locationY"));
reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS
// TODO: force for a 'normal' touch is usually 1.0;
// should we expose a `normalTouchForce` constant somewhere (which would
// have a value of `1.0 / nativeTouch.maximumPossibleForce`)?
if (RCTForceTouchAvailable()) {
reactTouch[@"force"] = @(RCTZeroIfNaN(nativeTouch.force / nativeTouch.maximumPossibleForce));
} else if (nativeTouch.type == UITouchTypePencil) {
reactTouch[@"force"] = @(RCTZeroIfNaN(nativeTouch.force / nativeTouch.maximumPossibleForce));
reactTouch[@"altitudeAngle"] = @(RCTZeroIfNaN(nativeTouch.altitudeAngle));
}
}
/**
* Constructs information about touch events to send across the serialized
* boundary. This data should be compliant with W3C `Touch` objects. This data
* alone isn't sufficient to construct W3C `Event` objects. To construct that,
* there must be a simple receiver on the other side of the bridge that
* organizes the touch objects into `Event`s.
*
* We send the data as an array of `Touch`es, the type of action
* (start/end/move/cancel) and the indices that represent "changed" `Touch`es
* from that array.
*/
- (void)_updateAndDispatchTouches:(NSSet<UITouch *> *)touches eventName:(NSString *)eventName
{
// Update touches
NSMutableArray<NSNumber *> *changedIndexes = [NSMutableArray new];
for (UITouch *touch in touches) {
NSInteger index = [_nativeTouches indexOfObject:touch];
if (index == NSNotFound) {
continue;
}
[self _updateReactTouchAtIndex:index];
[changedIndexes addObject:@(index)];
}
if (changedIndexes.count == 0) {
return;
}
// Deep copy the touches because they will be accessed from another thread
// TODO: would it be safer to do this in the bridge or executor, rather than trusting caller?
NSMutableArray<NSDictionary *> *reactTouches = [[NSMutableArray alloc] initWithCapacity:_reactTouches.count];
for (NSDictionary *touch in _reactTouches) {
[reactTouches addObject:[touch copy]];
}
BOOL canBeCoalesced = [eventName isEqualToString:@"touchMove"];
// We increment `_coalescingKey` twice here just for sure that
// this `_coalescingKey` will not be reused by another (preceding or following) event
// (yes, even if coalescing only happens (and makes sense) on events of the same type).
if (!canBeCoalesced) {
_coalescingKey++;
}
RCTTouchEvent *event = [[RCTTouchEvent alloc] initWithEventName:eventName
reactTag:self.view.reactTag
reactTouches:reactTouches
changedIndexes:changedIndexes
coalescingKey:_coalescingKey];
if (!canBeCoalesced) {
_coalescingKey++;
}
[_eventDispatcher sendEvent:event];
}
/***
* To ensure compatibility when using UIManager.measure and RCTTouchHandler, we have to adopt
* UIManager.measure's behavior in finding a "root view".
* Usually RCTTouchHandler is already attached to a root view but in some cases (e.g. Modal),
* we are instead attached to some RCTView subtree. This is also the case when embedding some RN
* views inside a separate ViewController not controlled by RN.
* This logic will either find the nearest rootView, or go all the way to the UIWindow.
* While this is not optimal, it is exactly what UIManager.measure does, and what Touchable.js
* relies on.
* We cache it here so that we don't have to repeat it for every touch in the gesture.
*/
- (void)_cacheRootView
{
UIView *rootView = self.view;
while (rootView.superview && ![rootView isReactRootView] && ![rootView isKindOfClass:[RCTSurfaceView class]]) {
rootView = rootView.superview;
}
_cachedRootView = rootView;
}
#pragma mark - Gesture Recognizer Delegate Callbacks
static BOOL RCTAllTouchesAreCancelledOrEnded(NSSet<UITouch *> *touches)
{
for (UITouch *touch in touches) {
if (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved || touch.phase == UITouchPhaseStationary) {
return NO;
}
}
return YES;
}
static BOOL RCTAnyTouchesChanged(NSSet<UITouch *> *touches)
{
for (UITouch *touch in touches) {
if (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved) {
return YES;
}
}
return NO;
}
#pragma mark - `UIResponder`-ish touch-delivery methods
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self _cacheRootView];
// "start" has to record new touches *before* extracting the event.
// "end"/"cancel" needs to remove the touch *after* extracting the event.
[self _recordNewTouches:touches];
[self _updateAndDispatchTouches:touches eventName:@"touchStart"];
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateBegan;
} else if (self.state == UIGestureRecognizerStateBegan) {
self.state = UIGestureRecognizerStateChanged;
}
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
[self _updateAndDispatchTouches:touches eventName:@"touchMove"];
self.state = UIGestureRecognizerStateChanged;
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[self _updateAndDispatchTouches:touches eventName:@"touchEnd"];
if (RCTAllTouchesAreCancelledOrEnded(event.allTouches)) {
self.state = UIGestureRecognizerStateEnded;
} else if (RCTAnyTouchesChanged(event.allTouches)) {
self.state = UIGestureRecognizerStateChanged;
}
[self _recordRemovedTouches:touches];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
[self _updateAndDispatchTouches:touches eventName:@"touchCancel"];
if (RCTAllTouchesAreCancelledOrEnded(event.allTouches)) {
self.state = UIGestureRecognizerStateCancelled;
} else if (RCTAnyTouchesChanged(event.allTouches)) {
self.state = UIGestureRecognizerStateChanged;
}
[self _recordRemovedTouches:touches];
}
- (BOOL)canPreventGestureRecognizer:(__unused UIGestureRecognizer *)preventedGestureRecognizer
{
return NO;
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
// We fail in favour of other external gesture recognizers.
// iOS will ask `delegate`'s opinion about this gesture recognizer little bit later.
return ![preventingGestureRecognizer.view isDescendantOfView:self.view];
}
- (void)reset
{
if (_nativeTouches.count != 0) {
[self _updateAndDispatchTouches:_nativeTouches.set eventName:@"touchCancel"];
[_nativeTouches removeAllObjects];
[_reactTouches removeAllObjects];
[_touchViews removeAllObjects];
_cachedRootView = nil;
}
}
#pragma mark - Other
- (void)cancel
{
self.enabled = NO;
self.enabled = YES;
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(__unused UIGestureRecognizer *)gestureRecognizer
shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// Same condition for `failure of` as for `be prevented by`.
return [self canBePreventedByGestureRecognizer:otherGestureRecognizer];
}
@end

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* A protocol that allows TurboModules to do lookup on other TurboModules.
* Calling these methods may cause a module to be synchronously instantiated.
*/
@protocol RCTTurboModuleRegistry <NSObject>
- (id)moduleForName:(const char *)moduleName;
/**
* Rationale:
* When TurboModules lookup other modules by name, we first check the TurboModule
* registry to see if a TurboModule exists with the respective name. In this case,
* we don't want a RedBox to be raised if the TurboModule isn't found.
*
* This method is deprecated and will be deleted after the migration from
* TurboModules to TurboModules is complete.
*/
- (id)moduleForName:(const char *)moduleName warnOnLookupFailure:(BOOL)warnOnLookupFailure;
- (BOOL)moduleIsInitialized:(const char *)moduleName;
@end

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
/**
* An abstract interface used by request handler modules to send
* data back over the bridge back to JS.
*/
@protocol RCTURLRequestDelegate <NSObject>
/**
* Call this when you send request data to the server. This is used to track
* upload progress, so should be called multiple times for large request bodies.
*/
- (void)URLRequest:(id)requestToken didSendDataWithProgress:(int64_t)bytesSent;
/**
* Call this when you first receives a response from the server. This should
* include response headers, etc.
*/
- (void)URLRequest:(id)requestToken didReceiveResponse:(NSURLResponse *)response;
/**
* Call this when you receive data from the server. This can be called multiple
* times with partial data chunks, or just once with the full data packet.
*/
- (void)URLRequest:(id)requestToken didReceiveData:(NSData *)data;
/**
* Call this when the request is complete and/or if an error is encountered.
* For a successful request, the error parameter should be nil.
*/
- (void)URLRequest:(id)requestToken didCompleteWithError:(NSError *)error;
@end

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTBridgeModule.h>
#import <React/RCTURLRequestDelegate.h>
/**
* Provides the interface needed to register a request handler. Request handlers
* are also bridge modules, so should be registered using RCT_EXPORT_MODULE().
*/
@protocol RCTURLRequestHandler <RCTBridgeModule>
/**
* Indicates whether this handler is capable of processing the specified
* request. Typically the handler would examine the scheme/protocol of the
* request URL (and possibly the HTTP method and/or headers) to determine this.
*/
- (BOOL)canHandleRequest:(NSURLRequest *)request;
/**
* Send a network request and call the delegate with the response data. The
* method should return a token, which can be anything, including the request
* itself. This will be used later to refer to the request in callbacks. The
* `sendRequest:withDelegate:` method *must* return before calling any of the
* delegate methods, or the delegate won't recognize the token.
* Following common Objective-C pattern, `delegate` will not be retained.
*/
- (id)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate;
@optional
/**
* Not all request types can be cancelled, but this method can be implemented
* for ones that can. It should be used to free up any resources on ongoing
* processes associated with the request.
*/
- (void)cancelRequest:(id)requestToken;
/**
* If more than one RCTURLRequestHandler responds YES to `canHandleRequest:`
* then `handlerPriority` is used to determine which one to use. The handler
* with the highest priority will be selected. Default priority is zero. If
* two or more valid handlers have the same priority, the selection order is
* undefined.
*/
- (float)handlerPriority;
@end

199
node_modules/react-native/React/Base/RCTUtils.h generated vendored Normal file
View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <React/RCTAssert.h>
#import <React/RCTDefines.h>
NS_ASSUME_NONNULL_BEGIN
// Whether the New Architecture is enabled or not
RCT_EXTERN BOOL RCTIsNewArchEnabled(void);
RCT_EXTERN void RCTSetNewArchEnabled(BOOL enabled) __attribute__((deprecated(
"This function is now no-op. You need to modify the Info.plist adding a RCTNewArchEnabled bool property to control whether the New Arch is enabled or not")));
;
// Whether React native should output logs for modules and components used
// through the interop layers
RCT_EXTERN BOOL RCTAreLegacyLogsEnabled(void);
// JSON serialization/deserialization
RCT_EXTERN NSString *__nullable RCTJSONStringify(id __nullable jsonObject, NSError **error);
RCT_EXTERN id __nullable RCTJSONParse(NSString *__nullable jsonString, NSError **error);
RCT_EXTERN id __nullable RCTJSONParseMutable(NSString *__nullable jsonString, NSError **error);
// Sanitize a JSON object by stripping invalid types and/or NaN values
RCT_EXTERN id RCTJSONClean(id object);
// Get MD5 hash of a string
RCT_EXTERN NSString *RCTMD5Hash(NSString *string);
// Check if we are currently on the main queue (not to be confused with
// the main thread, which is not necessarily the same thing)
// https://twitter.com/olebegemann/status/738656134731599872
RCT_EXTERN BOOL RCTIsMainQueue(void);
// Execute the specified block on the main queue. Unlike dispatch_async()
// this will execute immediately if we're already on the main queue.
RCT_EXTERN void RCTExecuteOnMainQueue(dispatch_block_t block);
// Legacy function to execute the specified block on the main queue synchronously.
// Please do not use this unless you know what you're doing.
RCT_EXTERN void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block);
// Get screen metrics in a thread-safe way
RCT_EXTERN CGFloat RCTScreenScale(void);
RCT_EXTERN CGFloat RCTFontSizeMultiplier(void);
RCT_EXTERN CGSize RCTScreenSize(void);
RCT_EXTERN CGSize RCTViewportSize(void);
RCT_EXTERN CGSize RCTSwitchSize(void);
// Round float coordinates to nearest whole screen pixel (not point)
RCT_EXTERN CGFloat RCTRoundPixelValue(CGFloat value);
RCT_EXTERN CGFloat RCTCeilPixelValue(CGFloat value);
// Convert a size in points to pixels, rounded up to the nearest integral size
RCT_EXTERN CGSize RCTSizeInPixels(CGSize pointSize, CGFloat scale);
// Method swizzling
RCT_EXTERN void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
RCT_EXTERN void RCTSwapInstanceMethodWithBlock(Class cls, SEL original, id replacementBlock, SEL replacementSelector);
// Module subclass support
RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
// Creates a standardized error object to return in callbacks
RCT_EXTERN NSDictionary<NSString *, id> *
RCTMakeError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
RCT_EXTERN NSDictionary<NSString *, id> *
RCTMakeAndLogError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromNSError(NSError *error);
RCT_EXTERN NSDictionary<NSString *, id> *
RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *__nullable error);
// The default error code to use as the `code` property for callback error objects
RCT_EXTERN NSString *const RCTErrorUnspecified;
// Returns YES if React is running in a test environment
RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
// Returns YES if React is running in an iOS App Extension
RCT_EXTERN BOOL RCTRunningInAppExtension(void);
// Returns the shared UIApplication instance, or nil if running in an App Extension
RCT_EXTERN UIApplication *__nullable RCTSharedApplication(void);
// Returns the current main window, useful if you need to access the root view
// or view controller
RCT_EXTERN UIWindow *__nullable RCTKeyWindow(void);
// Returns the presented view controller, useful if you need
// e.g. to present a modal view controller or alert over it
RCT_EXTERN UIViewController *__nullable RCTPresentedViewController(void);
// Retrieve current window UIStatusBarManager
RCT_EXTERN UIStatusBarManager *__nullable RCTUIStatusBarManager(void) API_AVAILABLE(ios(13));
// Does this device support force touch (aka 3D Touch)?
RCT_EXTERN BOOL RCTForceTouchAvailable(void);
// Create an NSError in the RCTErrorDomain
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
// Creates an NSError from given an NSException
RCT_EXTERN NSError *RCTErrorWithNSException(NSException *exception);
// Convert nil values to NSNull, and vice-versa
#define RCTNullIfNil(value) ((value) ? (value) : (id)kCFNull)
#define RCTNilIfNull(value) \
({ \
__typeof__(value) t = (value); \
(id) t == (id)kCFNull ? (__typeof(value))nil : t; \
})
// Convert NaN or infinite values to zero, as these aren't JSON-safe
RCT_EXTERN double RCTZeroIfNaN(double value);
// Returns `0` and log special warning if value is NaN or INF.
RCT_EXTERN double RCTSanitizeNaNValue(double value, NSString *property);
// Convert data to a Base64-encoded data URL
RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
// Gzip functionality - compression level in range 0 - 1 (-1 for default)
RCT_EXTERN NSData *__nullable RCTGzipData(NSData *__nullable data, float level);
// Returns the relative path within the main bundle for an absolute URL
// (or nil, if the URL does not specify a path within the main bundle)
RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL);
// Returns the Path of Library directory
RCT_EXTERN NSString *__nullable RCTLibraryPath(void);
// Returns the relative path within the library for an absolute URL
// (or nil, if the URL does not specify a path within the Library directory)
RCT_EXTERN NSString *__nullable RCTLibraryPathForURL(NSURL *__nullable URL);
// Determines if a given image URL refers to a image in bundle
RCT_EXTERN BOOL RCTIsBundleAssetURL(NSURL *__nullable imageURL);
// Determines if a given image URL refers to a image in library
RCT_EXTERN BOOL RCTIsLibraryAssetURL(NSURL *__nullable imageURL);
// Determines if a given image URL refers to a local image
RCT_EXTERN BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL);
// Returns an UIImage for a local image asset. Returns nil if the URL
// does not correspond to a local asset.
RCT_EXTERN UIImage *__nullable RCTImageFromLocalAssetURL(NSURL *imageURL);
// Only used in case when RCTImageFromLocalAssetURL fails to get an image
// This method basically checks for the image in the bundle location, instead
// of the CodePush location
RCT_EXTERN UIImage *__nullable RCTImageFromLocalBundleAssetURL(NSURL *imageURL);
// Creates a new, unique temporary file path with the specified extension
RCT_EXTERN NSString *__nullable RCTTempFilePath(NSString *__nullable extension, NSError **error);
// Get RGBA components of CGColor
RCT_EXTERN void RCTGetRGBAColorComponents(CGColorRef color, CGFloat rgba[_Nonnull 4]);
// Converts a CGColor to a hex string
RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
// Get standard localized string (if it exists)
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string);
// Get a human readable type string from an NSObject. For example NSString becomes string
RCT_EXTERN NSString *RCTHumanReadableType(NSObject *obj);
// URL manipulation
RCT_EXTERN NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param);
RCT_EXTERN NSURL *__nullable
RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value);
// Given a string, drop common RN prefixes (RCT, RK, etc.)
RCT_EXTERN NSString *RCTDropReactPrefixes(NSString *s);
RCT_EXTERN BOOL RCTUIManagerTypeForTagIsFabric(NSNumber *reactTag);
RCT_EXTERN BOOL RCTValidateTypeOfViewCommandArgument(
NSObject *obj,
id expectedClass,
const NSString *expectedType,
const NSString *componentName,
const NSString *commandName,
const NSString *argPos);
RCT_EXTERN BOOL RCTIsAppActive(void);
NS_ASSUME_NONNULL_END

1161
node_modules/react-native/React/Base/RCTUtils.mm generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface RCTUtilsUIOverride : NSObject
/**
Set the global presented view controller instance override.
*/
+ (void)setPresentedViewController:(UIViewController *)presentedViewController;
+ (UIViewController *)presentedViewController;
+ (BOOL)hasPresentedViewController;
@end

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTUtilsUIOverride.h"
@implementation RCTUtilsUIOverride
static UIViewController *_presentedViewController = nil;
+ (void)setPresentedViewController:(UIViewController *)presentedViewController
{
_presentedViewController = presentedViewController;
}
+ (UIViewController *)presentedViewController
{
return _presentedViewController;
}
+ (BOOL)hasPresentedViewController
{
return _presentedViewController != nil;
}
@end

17
node_modules/react-native/React/Base/RCTVersion.h generated vendored Normal file
View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
RCT_EXTERN NSString *const RCTVersionMajor;
RCT_EXTERN NSString *const RCTVersionMinor;
RCT_EXTERN NSString *const RCTVersionPatch;
RCT_EXTERN NSString *const RCTVersionPrerelease;
RCT_EXTERN NSDictionary *RCTGetReactNativeVersion(void);

31
node_modules/react-native/React/Base/RCTVersion.m generated vendored Normal file
View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated by scripts/releases/set-version.js
*/
#import "RCTVersion.h"
NSString* const RCTVersionMajor = @"major";
NSString* const RCTVersionMinor = @"minor";
NSString* const RCTVersionPatch = @"patch";
NSString* const RCTVersionPrerelease = @"prerelease";
NSDictionary* RCTGetReactNativeVersion(void)
{
static NSDictionary* __rnVersion;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(void){
__rnVersion = @{
RCTVersionMajor: @(0),
RCTVersionMinor: @(83),
RCTVersionPatch: @(2),
RCTVersionPrerelease: [NSNull null],
};
});
return __rnVersion;
}

Some files were not shown because too many files have changed in this diff Show More