expo-modules-core 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +46 -32
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +19 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -5
  13. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +2 -13
  14. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +11 -5
  15. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +5 -1
  16. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +17 -0
  17. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +14 -3
  18. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  19. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  20. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +25 -1
  21. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +6 -5
  22. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  23. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +61 -0
  24. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  25. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  26. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +14 -0
  27. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +176 -27
  28. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  29. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  30. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +0 -39
  31. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +59 -10
  32. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  33. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  34. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  35. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  36. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  37. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  38. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +49 -0
  39. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +64 -0
  41. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +4 -1
  42. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +15 -2
  43. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +3 -0
  44. package/build/NativeModulesProxy.native.d.ts +0 -4
  45. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  46. package/build/NativeModulesProxy.native.js +1 -14
  47. package/build/NativeModulesProxy.native.js.map +1 -1
  48. package/build/NativeModulesProxy.types.d.ts +0 -3
  49. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  50. package/build/NativeModulesProxy.types.js.map +1 -1
  51. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  52. package/build/NativeViewManagerAdapter.native.js +9 -33
  53. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  54. package/build/sweet/NativeErrorManager.js +1 -1
  55. package/build/sweet/NativeErrorManager.js.map +1 -1
  56. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  57. package/ios/AppDelegates/ExpoAppDelegate.swift +4 -10
  58. package/ios/EXAppDefines.h +1 -0
  59. package/ios/EXAppDefines.m +6 -0
  60. package/ios/EXUtilities.h +2 -0
  61. package/ios/EXUtilities.m +12 -0
  62. package/ios/ExpoModulesCore.h +4 -0
  63. package/ios/ExpoModulesCore.podspec +4 -2
  64. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  65. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  66. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +4 -1
  67. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +16 -5
  68. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +3 -3
  69. package/ios/JSI/EXJSIInstaller.mm +17 -0
  70. package/ios/JSI/{ExpoModulesProxySpec.h → EXJSIUtils.h} +0 -9
  71. package/ios/JSI/{ExpoModulesProxySpec.mm → EXJSIUtils.mm} +4 -48
  72. package/ios/JSI/EXJavaScriptObject.h +97 -0
  73. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  74. package/ios/JSI/{JavaScriptRuntime.h → EXJavaScriptRuntime.h} +27 -8
  75. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  76. package/ios/JSI/EXJavaScriptValue.h +57 -0
  77. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  78. package/ios/JSI/ExpoModulesHostObject.mm +2 -1
  79. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  80. package/ios/JSI/JavaScriptValue.swift +94 -0
  81. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -11
  82. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  83. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +24 -22
  84. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  85. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  86. package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
  87. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
  88. package/ios/Swift/AppContext.swift +27 -1
  89. package/ios/Swift/Functions/AsyncFunction.swift +17 -0
  90. package/ios/Swift/Functions/ConcreteFunction.swift +6 -1
  91. package/ios/Swift/JavaScriptUtils.swift +11 -0
  92. package/ios/Swift/ModuleHolder.swift +14 -3
  93. package/ios/Swift/ModulesProvider.swift +3 -10
  94. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +176 -0
  95. package/ios/Swift/SwiftInteropBridge.swift +14 -5
  96. package/ios/Swift/Views/ComponentData.swift +2 -1
  97. package/ios/Swift/Views/ExpoView.swift +8 -0
  98. package/ios/Swift.h +5 -0
  99. package/ios/Tests/ArgumentTypeSpec.swift +2 -3
  100. package/ios/Tests/ConstantsSpec.swift +2 -3
  101. package/ios/Tests/ConvertiblesSpec.swift +2 -3
  102. package/ios/Tests/ExceptionsSpec.swift +2 -3
  103. package/ios/Tests/ExpoModulesSpec.swift +76 -0
  104. package/ios/Tests/FunctionSpec.swift +2 -3
  105. package/ios/Tests/FunctionWithConvertiblesSpec.swift +2 -3
  106. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  107. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  108. package/ios/Tests/ModuleEventListenersSpec.swift +2 -3
  109. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  110. package/ios/Tests/RecordSpec.swift +2 -3
  111. package/package.json +2 -2
  112. package/src/NativeModulesProxy.native.ts +2 -22
  113. package/src/NativeModulesProxy.types.ts +0 -8
  114. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  115. package/src/sweet/NativeErrorManager.ts +1 -1
  116. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  117. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  118. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  119. package/ios/JSI/JSIInstaller.mm +0 -34
  120. package/ios/JSI/JavaScriptObject.h +0 -60
  121. package/ios/JSI/JavaScriptObject.mm +0 -93
  122. package/ios/JSI/JavaScriptRuntime.mm +0 -102
  123. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +0 -16
  124. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.m +0 -28
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class ModuleRegistrySpec: QuickSpec {
5
+ class ModuleRegistrySpec: ExpoSpec {
7
6
  override func spec() {
8
7
  let appContext = AppContext()
9
8
 
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class RecordSpec: QuickSpec {
5
+ class RecordSpec: ExpoSpec {
7
6
  override func spec() {
8
7
  it("initializes with empty dictionary") {
9
8
  struct TestRecord: Record { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -42,5 +42,5 @@
42
42
  "@testing-library/react-hooks": "^7.0.1",
43
43
  "expo-module-scripts": "^2.0.0"
44
44
  },
45
- "gitHead": "e1ff1a3d6bc62f374e6947a5e81428a1bb7cfa34"
45
+ "gitHead": "22dce752354bb429c84851bc4389abe47a766b1f"
46
46
  }
@@ -1,11 +1,6 @@
1
1
  import { NativeModules } from 'react-native';
2
2
 
3
- import { ProxyNativeModule, TurboNativeModuleProxy } from './NativeModulesProxy.types';
4
-
5
- // `ExpoModulesProxy` is not declared in TypeScript yet. It's installed via JSI.
6
- declare namespace global {
7
- const ExpoModulesProxy: TurboNativeModuleProxy;
8
- }
3
+ import { ProxyNativeModule } from './NativeModulesProxy.types';
9
4
 
10
5
  const NativeProxy = NativeModules.NativeUnimoduleProxy;
11
6
  const modulesConstantsKey = 'modulesConstants';
@@ -13,16 +8,6 @@ const exportedMethodsKey = 'exportedMethods';
13
8
 
14
9
  const NativeModulesProxy: { [moduleName: string]: ProxyNativeModule } = {};
15
10
 
16
- // Keep it opt-in for now. It's too risky without proper and thorough testing.
17
- let canUseExpoTurboModules = false;
18
-
19
- /**
20
- * Sets whether to use a TurboModule version of the proxy.
21
- */
22
- export function useExpoTurboModules(state: boolean = true) {
23
- canUseExpoTurboModules = state;
24
- }
25
-
26
11
  if (NativeProxy) {
27
12
  Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {
28
13
  NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
@@ -38,12 +23,7 @@ if (NativeProxy) {
38
23
  )
39
24
  );
40
25
  }
41
-
42
- if (canUseExpoTurboModules && global.ExpoModulesProxy) {
43
- return global.ExpoModulesProxy.callMethodAsync(moduleName, methodInfo.name, args);
44
- } else {
45
- return NativeProxy.callMethod(moduleName, key, args);
46
- }
26
+ return NativeProxy.callMethod(moduleName, key, args);
47
27
  };
48
28
  });
49
29
 
@@ -3,11 +3,3 @@ export type ProxyNativeModule = {
3
3
  addListener: (eventName: string) => void;
4
4
  removeListeners: (count: number) => void;
5
5
  };
6
-
7
- export type TurboNativeModuleProxy = {
8
- callMethodAsync: <ReturnType>(
9
- moduleName: string,
10
- methodName: string,
11
- args: any[]
12
- ) => Promise<ReturnType>;
13
- };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { NativeModules, UIManager, ViewPropTypes, requireNativeComponent } from 'react-native';
2
+ import { NativeModules, requireNativeComponent } from 'react-native';
3
3
 
4
4
  // To make the transition from React Native's `requireNativeComponent` to Expo's
5
5
  // `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
@@ -10,11 +10,6 @@ import { NativeModules, UIManager, ViewPropTypes, requireNativeComponent } from
10
10
  // passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
11
11
  // adapter view component in a prop called `proxiedProperties`.
12
12
 
13
- // NOTE: React Native is moving away from runtime PropTypes and may remove ViewPropTypes, in which
14
- // case we will need another way to separate standard React Native view props from other props,
15
- // which we proxy through the adapter
16
- const ViewPropTypesKeys = Object.keys(ViewPropTypes);
17
-
18
13
  type NativeExpoComponentProps = {
19
14
  proxiedProperties: object;
20
15
  };
@@ -23,14 +18,14 @@ type NativeExpoComponentProps = {
23
18
  * A drop-in replacement for `requireNativeComponent`.
24
19
  */
25
20
  export function requireNativeViewManager<P = any>(viewName: string): React.ComponentType<P> {
26
- if (__DEV__) {
27
- const { NativeUnimoduleProxy } = NativeModules;
28
- if (!NativeUnimoduleProxy.viewManagersNames.includes(viewName)) {
29
- const exportedViewManagerNames = NativeUnimoduleProxy.viewManagersNames.join(', ');
30
- console.warn(
31
- `The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`
32
- );
33
- }
21
+ const { viewManagersMetadata } = NativeModules.NativeUnimoduleProxy;
22
+ const viewManagerConfig = viewManagersMetadata?.[viewName];
23
+
24
+ if (__DEV__ && !viewManagerConfig) {
25
+ const exportedViewManagerNames = Object.keys(viewManagersMetadata).join(', ');
26
+ console.warn(
27
+ `The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`
28
+ );
34
29
  }
35
30
 
36
31
  // Set up the React Native native component, which is an adapter to the universal module's view
@@ -38,23 +33,12 @@ export function requireNativeViewManager<P = any>(viewName: string): React.Compo
38
33
  const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
39
34
  const ReactNativeComponent =
40
35
  requireNativeComponent<NativeExpoComponentProps>(reactNativeViewName);
41
- const reactNativeUIConfiguration = (UIManager.getViewManagerConfig
42
- ? UIManager.getViewManagerConfig(reactNativeViewName)
43
- : UIManager[reactNativeViewName]) || {
44
- NativeProps: {},
45
- directEventTypes: {},
46
- };
47
- const reactNativeComponentPropNames = [
48
- 'children',
49
- ...ViewPropTypesKeys,
50
- ...Object.keys(reactNativeUIConfiguration.NativeProps),
51
- ...Object.keys(reactNativeUIConfiguration.directEventTypes),
52
- ];
36
+ const proxiedPropsNames = viewManagerConfig?.propsNames ?? [];
53
37
 
54
38
  // Define a component for universal-module authors to access their native view manager
55
39
  function NativeComponentAdapter(props, ref) {
56
- const nativeProps = pick(props, reactNativeComponentPropNames);
57
- const proxiedProps = omit(props, reactNativeComponentPropNames);
40
+ const nativeProps = omit(props, proxiedPropsNames);
41
+ const proxiedProps = pick(props, proxiedPropsNames);
58
42
  return <ReactNativeComponent {...nativeProps} proxiedProperties={proxiedProps} ref={ref} />;
59
43
  }
60
44
  NativeComponentAdapter.displayName = `Adapter<${viewName}>`;
@@ -1,2 +1,2 @@
1
- import { NativeModulesProxy } from '..';
1
+ import NativeModulesProxy from '../NativeModulesProxy';
2
2
  export default NativeModulesProxy.ExpoModulesCoreErrorManager;
@@ -1,26 +0,0 @@
1
- package expo.modules.kotlin.events
2
-
3
- import android.os.Bundle
4
- import expo.modules.core.interfaces.services.EventEmitter
5
- import expo.modules.kotlin.ModuleHolder
6
-
7
- /**
8
- * In Swift, we check if the event is supported. Otherwise, we can't send such event through the bridge.
9
- * However, in Kotlin this is unnecessary, but to make our API consistent, we added similar check.
10
- * But because of that, we had to create a wrapper for EventEmitter.
11
- */
12
- class KEventEmitterWrapper(
13
- private val moduleHolder: ModuleHolder,
14
- private val legacyEventEmitter: EventEmitter
15
- ) : EventEmitter by legacyEventEmitter {
16
- override fun emit(eventName: String, eventBody: Bundle?) {
17
- require(
18
- moduleHolder
19
- .definition
20
- .eventsDefinition
21
- ?.names
22
- ?.contains(eventName) == true
23
- ) { "Unsupported event: $eventName." }
24
- legacyEventEmitter.emit(eventName, eventBody)
25
- }
26
- }
@@ -1,14 +0,0 @@
1
- package expo.modules.kotlin.methods
2
-
3
- import expo.modules.kotlin.Promise
4
- import expo.modules.kotlin.types.AnyType
5
-
6
- class Method(
7
- name: String,
8
- argsType: Array<AnyType>,
9
- private val body: (args: Array<out Any?>) -> Any?
10
- ) : AnyMethod(name, argsType) {
11
- override fun callImplementation(args: Array<out Any?>, promise: Promise) {
12
- promise.resolve(body(args))
13
- }
14
- }
@@ -1,15 +0,0 @@
1
- package expo.modules.kotlin.methods
2
-
3
- import expo.modules.kotlin.Promise
4
- import expo.modules.kotlin.types.AnyType
5
-
6
- class PromiseMethod(
7
- name: String,
8
- argsType: Array<AnyType>,
9
- private val body: (args: Array<out Any?>, promise: Promise) -> Unit
10
- ) : AnyMethod(name, argsType) {
11
-
12
- override fun callImplementation(args: Array<out Any?>, promise: Promise) {
13
- body(args, promise)
14
- }
15
- }
@@ -1,34 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <ExpoModulesCore/JSIInstaller.h>
4
- #import <ExpoModulesCore/ExpoModulesProxySpec.h>
5
- #import <ExpoModulesCore/ExpoModulesHostObject.h>
6
- #import <ExpoModulesCore/Swift.h>
7
-
8
- using namespace facebook;
9
- using namespace react;
10
-
11
- namespace expo {
12
-
13
- void installRuntimeObjects(jsi::Runtime &runtime, std::shared_ptr<CallInvoker> callInvoker, EXNativeModulesProxy *nativeModulesProxy)
14
- {
15
- auto expoModulesProxyModule = std::make_shared<ExpoModulesProxySpec>(callInvoker, nativeModulesProxy);
16
-
17
- runtime
18
- .global()
19
- .setProperty(runtime, "ExpoModulesProxy", jsi::Object::createFromHostObject(runtime, expoModulesProxyModule));
20
- }
21
-
22
- } // namespace expo
23
-
24
- @implementation JavaScriptRuntimeManager
25
-
26
- + (void)installExpoModulesToRuntime:(nonnull JavaScriptRuntime *)runtime withSwiftInterop:(nonnull SwiftInteropBridge *)swiftInterop
27
- {
28
- std::shared_ptr<expo::ExpoModulesHostObject> hostObjectPtr = std::make_shared<expo::ExpoModulesHostObject>(swiftInterop);
29
- JavaScriptObject *global = [runtime global];
30
-
31
- global[@"ExpoModules"] = [runtime createHostObject:hostObjectPtr];
32
- }
33
-
34
- @end
@@ -1,60 +0,0 @@
1
- // Copyright 2022-present 650 Industries. All rights reserved.
2
-
3
- #import <Foundation/Foundation.h>
4
- #import <React/RCTBridgeModule.h>
5
-
6
- #ifdef __cplusplus
7
- #import <jsi/jsi.h>
8
- #import <ReactCommon/CallInvoker.h>
9
-
10
- namespace jsi = facebook::jsi;
11
- #endif // __cplusplus
12
-
13
- typedef void (^JSAsyncFunctionBlock)(NSArray * _Nonnull, RCTPromiseResolveBlock _Nonnull, RCTPromiseRejectBlock _Nonnull);
14
- typedef id _Nullable (^JSSyncFunctionBlock)(NSArray * _Nonnull);
15
-
16
- @class JavaScriptRuntime;
17
-
18
- @interface JavaScriptObject : NSObject
19
-
20
- // Some parts of the interface must be hidden for Swift – it can't import any C++ code.
21
- #ifdef __cplusplus
22
- - (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObjectPtr
23
- runtime:(nonnull JavaScriptRuntime *)runtime;
24
-
25
- /**
26
- Returns the pointer to the underlying object.
27
- */
28
- - (nonnull jsi::Object *)get;
29
- #endif // __cplusplus
30
-
31
- #pragma mark - Subscripting
32
-
33
- /**
34
- Subscript getter. Supports only values convertible to Foundation types, otherwise `nil` is returned.
35
- */
36
- - (nullable id)objectForKeyedSubscript:(nonnull NSString *)key;
37
-
38
- /**
39
- Subscript setter. Only `JavaScriptObject` and Foundation object convertible to JSI values can be used as a value,
40
- otherwise the property is set to `undefined`.
41
- */
42
- - (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull NSString *)key;
43
-
44
- #pragma mark - Functions
45
-
46
- /**
47
- Sets given function block on the object as a host function returning a promise.
48
- */
49
- - (void)setAsyncFunction:(nonnull NSString *)key
50
- argsCount:(NSInteger)argsCount
51
- block:(nonnull JSAsyncFunctionBlock)block;
52
-
53
- /**
54
- Sets given synchronous function block as a host function on the object.
55
- */
56
- - (void)setSyncFunction:(nonnull NSString *)name
57
- argsCount:(NSInteger)argsCount
58
- block:(nonnull JSSyncFunctionBlock)block;
59
-
60
- @end
@@ -1,93 +0,0 @@
1
- // Copyright 2022-present 650 Industries. All rights reserved.
2
-
3
- #import <ExpoModulesCore/JSIConversions.h>
4
- #import <ExpoModulesCore/JavaScriptObject.h>
5
- #import <ExpoModulesCore/JavaScriptRuntime.h>
6
- #import <ExpoModulesCore/ExpoModulesProxySpec.h>
7
-
8
- @implementation JavaScriptObject {
9
- /**
10
- Pointer to the `JavaScriptRuntime` wrapper.
11
-
12
- \note It must be weak because only then the original runtime can be safely deallocated
13
- when the JS engine wants to without unsetting it on each created object.
14
- */
15
- __weak JavaScriptRuntime *_runtime;
16
-
17
- /**
18
- Shared pointer to the original JSI object that is being wrapped by `JavaScriptObject` class.
19
- */
20
- std::shared_ptr<jsi::Object> _jsObjectPtr;
21
- }
22
-
23
- - (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObjectPtr
24
- runtime:(nonnull JavaScriptRuntime *)runtime
25
- {
26
- if (self = [super init]) {
27
- _runtime = runtime;
28
- _jsObjectPtr = jsObjectPtr;
29
- }
30
- return self;
31
- }
32
-
33
- - (nonnull jsi::Object *)get
34
- {
35
- return _jsObjectPtr.get();
36
- }
37
-
38
- #pragma mark - Subscripting
39
-
40
- - (nullable id)objectForKeyedSubscript:(nonnull NSString *)key
41
- {
42
- auto runtime = [_runtime get];
43
- auto callInvoker = [_runtime callInvoker];
44
-
45
- if (runtime && callInvoker) {
46
- auto value = _jsObjectPtr->getProperty(*runtime, [key UTF8String]);
47
- return expo::convertJSIValueToObjCObject(*runtime, value, callInvoker);
48
- }
49
- return nil;
50
- }
51
-
52
- - (void)setObject:(nullable id)obj forKeyedSubscript:(nonnull NSString *)key
53
- {
54
- auto runtime = [_runtime get];
55
-
56
- if (!runtime) {
57
- NSLog(@"Cannot set '%@' property when the JavaScript runtime is no longer available.", key);
58
- return;
59
- }
60
- if ([obj isKindOfClass:[JavaScriptObject class]]) {
61
- _jsObjectPtr->setProperty(*runtime, [key UTF8String], *[obj get]);
62
- } else {
63
- _jsObjectPtr->setProperty(*runtime, [key UTF8String], expo::convertObjCObjectToJSIValue(*runtime, obj));
64
- }
65
- }
66
-
67
- #pragma mark - Functions
68
-
69
- - (void)setAsyncFunction:(nonnull NSString *)name
70
- argsCount:(NSInteger)argsCount
71
- block:(nonnull JSAsyncFunctionBlock)block
72
- {
73
- if (!_runtime) {
74
- NSLog(@"Cannot set '%@' async function when the JavaScript runtime is no longer available.", name);
75
- return;
76
- }
77
- jsi::Function function = [_runtime createAsyncFunction:name argsCount:argsCount block:block];
78
- _jsObjectPtr->setProperty(*[_runtime get], [name UTF8String], function);
79
- }
80
-
81
- - (void)setSyncFunction:(nonnull NSString *)name
82
- argsCount:(NSInteger)argsCount
83
- block:(nonnull JSSyncFunctionBlock)block
84
- {
85
- if (!_runtime) {
86
- NSLog(@"Cannot set '%@' sync function when the JavaScript runtime is no longer available.", name);
87
- return;
88
- }
89
- jsi::Function function = [_runtime createSyncFunction:name argsCount:argsCount block:block];
90
- _jsObjectPtr->setProperty(*[_runtime get], [name UTF8String], function);
91
- }
92
-
93
- @end
@@ -1,102 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <jsi/jsi.h>
4
-
5
- #import <ExpoModulesCore/JavaScriptRuntime.h>
6
- #import <ExpoModulesCore/ExpoModulesHostObject.h>
7
- #import <ExpoModulesCore/Swift.h>
8
-
9
- using namespace facebook;
10
-
11
- @implementation JavaScriptRuntime {
12
- jsi::Runtime *_runtime;
13
- std::shared_ptr<react::CallInvoker> _jsCallInvoker;
14
-
15
- JavaScriptObject *_global;
16
- }
17
-
18
- - (nonnull instancetype)initWithRuntime:(jsi::Runtime &)runtime callInvoker:(std::shared_ptr<react::CallInvoker>)callInvoker
19
- {
20
- if (self = [super init]) {
21
- _runtime = &runtime;
22
- _jsCallInvoker = callInvoker;
23
-
24
- auto jsGlobalPtr = std::make_shared<jsi::Object>(_runtime->global());
25
- _global = [[JavaScriptObject alloc] initWith:jsGlobalPtr runtime:self];
26
- }
27
- return self;
28
- }
29
-
30
- - (nonnull jsi::Runtime *)get
31
- {
32
- return _runtime;
33
- }
34
-
35
- - (std::shared_ptr<react::CallInvoker>)callInvoker
36
- {
37
- return _jsCallInvoker;
38
- }
39
-
40
- - (nonnull JavaScriptObject *)createObject
41
- {
42
- auto jsObjectPtr = std::make_shared<jsi::Object>(*_runtime);
43
- return [[JavaScriptObject alloc] initWith:jsObjectPtr runtime:self];
44
- }
45
-
46
- - (nonnull JavaScriptObject *)createHostObject:(std::shared_ptr<jsi::HostObject>)jsiHostObjectPtr
47
- {
48
- auto jsObjectPtr = std::make_shared<jsi::Object>(jsi::Object::createFromHostObject(*_runtime, jsiHostObjectPtr));
49
- return [[JavaScriptObject alloc] initWith:jsObjectPtr runtime:self];
50
- }
51
-
52
- - (nonnull JavaScriptObject *)global
53
- {
54
- return _global;
55
- }
56
-
57
- - (jsi::Function)createSyncFunction:(nonnull NSString *)name
58
- argsCount:(NSInteger)argsCount
59
- block:(nonnull JSSyncFunctionBlock)block
60
- {
61
- return [self createHostFunction:name argsCount:argsCount block:^jsi::Value(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray * _Nonnull arguments) {
62
- return expo::convertObjCObjectToJSIValue(runtime, block(arguments));
63
- }];
64
- }
65
-
66
- - (jsi::Function)createAsyncFunction:(nonnull NSString *)name
67
- argsCount:(NSInteger)argsCount
68
- block:(nonnull JSAsyncFunctionBlock)block
69
- {
70
- return [self createHostFunction:name argsCount:argsCount block:^jsi::Value(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray *arguments) {
71
- // The function that is invoked as a setup of the JavaScript `Promise`.
72
- auto promiseSetup = [callInvoker, block, arguments](jsi::Runtime &runtime, std::shared_ptr<Promise> promise) {
73
- expo::callPromiseSetupWithBlock(runtime, callInvoker, promise, ^(RCTPromiseResolveBlock resolver, RCTPromiseRejectBlock rejecter) {
74
- block(arguments, resolver, rejecter);
75
- });
76
- };
77
- return createPromiseAsJSIValue(runtime, promiseSetup);
78
- }];
79
- }
80
-
81
- #pragma mark - Private
82
-
83
- typedef jsi::Value (^JSHostFunctionBlock)(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray * _Nonnull arguments);
84
-
85
- - (jsi::Function)createHostFunction:(nonnull NSString *)name
86
- argsCount:(NSInteger)argsCount
87
- block:(nonnull JSHostFunctionBlock)block
88
- {
89
- jsi::PropNameID propNameId = jsi::PropNameID::forAscii(*_runtime, [name UTF8String], [name length]);
90
- std::weak_ptr<react::CallInvoker> weakCallInvoker = _jsCallInvoker;
91
- jsi::HostFunctionType function = [weakCallInvoker, block](jsi::Runtime &runtime, const jsi::Value &thisVal, const jsi::Value *args, size_t count) -> jsi::Value {
92
- if (auto callInvoker = weakCallInvoker.lock()) {
93
- NSArray *arguments = expo::convertJSIValuesToNSArray(runtime, args, count, callInvoker);
94
- return block(runtime, callInvoker, arguments);
95
- }
96
- // TODO: We should throw some kind of error.
97
- return jsi::Value::undefined();
98
- };
99
- return jsi::Function::createFromHostFunction(*_runtime, propNameId, (unsigned int)argsCount, function);
100
- }
101
-
102
- @end
@@ -1,16 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <React/RCTComponentData.h>
4
-
5
- /**
6
- * A compatible wrapper for `RCTComponentData` which has different designated initializers between different react-native versions.
7
- * This class unifies the interface to make react-native <= 0.64 backward compatible.
8
- * Remove when we drop support for SDK 44
9
- */
10
- @interface EXComponentDataCompatibleWrapper : RCTComponentData
11
-
12
- - (instancetype)initWithManagerClass:(Class)managerClass
13
- bridge:(RCTBridge *)bridge
14
- eventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher NS_DESIGNATED_INITIALIZER;
15
-
16
- @end
@@ -1,28 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <ExpoModulesCore/EXComponentDataCompatibleWrapper.h>
4
-
5
- @interface RCTComponentData (EXComponentDataCompatibleWrapper)
6
-
7
- // available in RN 0.65+
8
- - (instancetype)initWithManagerClass:(Class)managerClass
9
- bridge:(RCTBridge *)bridge
10
- eventDispatcher:(id<RCTEventDispatcherProtocol>) eventDispatcher;
11
-
12
- - (instancetype)initWithManagerClass:(Class)managerClass bridge:(RCTBridge *)bridge;
13
-
14
- @end
15
-
16
- @implementation EXComponentDataCompatibleWrapper
17
-
18
- - (instancetype)initWithManagerClass:(Class)managerClass
19
- bridge:(RCTBridge *)bridge
20
- eventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher
21
- {
22
- if ([self respondsToSelector:@selector(initWithManagerClass:bridge:)]) {
23
- return [super initWithManagerClass:managerClass bridge:bridge];
24
- }
25
- return [super initWithManagerClass:managerClass bridge:bridge eventDispatcher:eventDispatcher];
26
- }
27
-
28
- @end