expo-modules-core 0.9.2 → 0.11.1

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 (193) hide show
  1. package/CHANGELOG.md +33 -3
  2. package/README.md +3 -3
  3. package/android/CMakeLists.txt +163 -0
  4. package/android/build.gradle +343 -5
  5. package/android/src/main/cpp/CachedReferencesRegistry.cpp +65 -0
  6. package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
  7. package/android/src/main/cpp/Exceptions.cpp +22 -0
  8. package/android/src/main/cpp/Exceptions.h +38 -0
  9. package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
  10. package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
  11. package/android/src/main/cpp/JNIFunctionBody.cpp +44 -0
  12. package/android/src/main/cpp/JNIFunctionBody.h +50 -0
  13. package/android/src/main/cpp/JNIInjector.cpp +23 -0
  14. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
  15. package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
  16. package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
  17. package/android/src/main/cpp/JSITypeConverter.h +84 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +219 -0
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +144 -0
  20. package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
  21. package/android/src/main/cpp/JavaScriptObject.h +131 -0
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
  23. package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
  24. package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +78 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +340 -0
  27. package/android/src/main/cpp/MethodMetadata.h +131 -0
  28. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
  29. package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
  30. package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
  31. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +98 -3
  32. package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
  33. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
  34. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +45 -3
  35. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
  36. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
  37. package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
  38. package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
  39. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
  40. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
  41. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
  42. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
  43. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
  45. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
  46. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
  48. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +53 -15
  49. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +35 -7
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -121
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +21 -0
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +21 -0
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +63 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +36 -0
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +19 -0
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +46 -0
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
  61. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +16 -6
  62. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -500
  63. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +30 -5
  64. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
  65. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
  66. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
  67. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
  68. package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
  69. package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
  70. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
  71. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
  72. package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
  73. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
  74. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
  75. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
  76. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
  77. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
  78. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
  79. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
  80. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +12 -0
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
  83. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  84. package/build/NativeModulesProxy.native.js +9 -3
  85. package/build/NativeModulesProxy.native.js.map +1 -1
  86. package/build/PermissionsInterface.d.ts +29 -0
  87. package/build/PermissionsInterface.d.ts.map +1 -1
  88. package/build/PermissionsInterface.js +9 -0
  89. package/build/PermissionsInterface.js.map +1 -1
  90. package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
  91. package/ios/ExpoModulesCore.podspec +3 -2
  92. package/ios/JSI/EXJSIConversions.mm +6 -0
  93. package/ios/JSI/EXJSIInstaller.h +15 -21
  94. package/ios/JSI/EXJSIInstaller.mm +39 -3
  95. package/ios/JSI/EXJSIUtils.h +48 -3
  96. package/ios/JSI/EXJSIUtils.mm +88 -4
  97. package/ios/JSI/EXJavaScriptObject.h +11 -18
  98. package/ios/JSI/EXJavaScriptObject.mm +37 -18
  99. package/ios/JSI/EXJavaScriptRuntime.h +43 -9
  100. package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
  101. package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
  102. package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
  103. package/ios/JSI/EXJavaScriptValue.h +3 -2
  104. package/ios/JSI/EXJavaScriptValue.mm +17 -20
  105. package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
  106. package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
  107. package/ios/JSI/EXObjectDeallocator.h +27 -0
  108. package/ios/JSI/ExpoModulesHostObject.h +3 -3
  109. package/ios/JSI/ExpoModulesHostObject.mm +4 -4
  110. package/ios/JSI/JavaScriptRuntime.swift +38 -1
  111. package/ios/JSI/JavaScriptValue.swift +7 -0
  112. package/ios/JSI/TypedArray.cpp +67 -0
  113. package/ios/JSI/TypedArray.h +46 -0
  114. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
  115. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
  116. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +86 -77
  117. package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
  118. package/ios/Services/EXReactNativeEventEmitter.h +2 -2
  119. package/ios/Services/EXReactNativeEventEmitter.m +11 -6
  120. package/ios/Swift/AppContext.swift +206 -28
  121. package/ios/Swift/Arguments/AnyArgument.swift +18 -0
  122. package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
  123. package/ios/Swift/Classes/ClassComponent.swift +95 -0
  124. package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
  125. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
  126. package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
  131. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
  132. package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
  133. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
  134. package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
  135. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
  136. package/ios/Swift/Exceptions/ChainableException.swift +3 -3
  137. package/ios/Swift/Exceptions/CodedError.swift +1 -1
  138. package/ios/Swift/Exceptions/Exception.swift +8 -6
  139. package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
  140. package/ios/Swift/ExpoBridgeModule.m +5 -0
  141. package/ios/Swift/ExpoBridgeModule.swift +79 -0
  142. package/ios/Swift/Functions/AnyFunction.swift +33 -31
  143. package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
  144. package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
  145. package/ios/Swift/JavaScriptUtils.swift +32 -57
  146. package/ios/Swift/Logging/LogHandlers.swift +39 -0
  147. package/ios/Swift/Logging/LogType.swift +62 -0
  148. package/ios/Swift/Logging/Logger.swift +201 -0
  149. package/ios/Swift/ModuleHolder.swift +19 -54
  150. package/ios/Swift/ModuleRegistry.swift +7 -1
  151. package/ios/Swift/Modules/AnyModule.swift +3 -3
  152. package/ios/Swift/ModulesProvider.swift +2 -0
  153. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
  154. package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
  155. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
  156. package/ios/Swift/Objects/PropertyComponent.swift +147 -0
  157. package/ios/Swift/Promise.swift +17 -4
  158. package/ios/Swift/Records/Field.swift +2 -2
  159. package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
  160. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
  161. package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
  162. package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
  163. package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
  164. package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
  165. package/ios/Swift/Utilities.swift +28 -0
  166. package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
  167. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
  168. package/ios/Tests/ClassComponentSpec.swift +210 -0
  169. package/ios/Tests/DynamicTypeSpec.swift +336 -0
  170. package/ios/Tests/EnumArgumentSpec.swift +48 -0
  171. package/ios/Tests/ExpoModulesSpec.swift +17 -3
  172. package/ios/Tests/FunctionSpec.swift +167 -118
  173. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  174. package/ios/Tests/PropertyComponentSpec.swift +95 -0
  175. package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
  176. package/ios/Tests/TypedArraysSpec.swift +136 -0
  177. package/package.json +2 -2
  178. package/src/NativeModulesProxy.native.ts +13 -3
  179. package/src/PermissionsInterface.ts +29 -0
  180. package/src/ts-declarations/ExpoModules.d.ts +7 -0
  181. package/tsconfig.json +1 -1
  182. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
  183. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
  184. package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
  185. package/ios/Swift/Arguments/ArgumentType.swift +0 -28
  186. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
  187. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
  188. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
  189. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
  190. package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
  191. package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
  192. package/ios/Swift/SwiftInteropBridge.swift +0 -155
  193. package/ios/Tests/ArgumentTypeSpec.swift +0 -143
@@ -0,0 +1,56 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type representing array types. Requires the array's element type
5
+ for the initialization as it delegates casting to that type for each element in the array.
6
+ */
7
+ internal struct DynamicArrayType: AnyDynamicType {
8
+ let elementType: AnyDynamicType
9
+
10
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
11
+ if let ArrayType = InnerType.self as? AnyArray.Type {
12
+ return elementType.equals(ArrayType.getElementDynamicType())
13
+ }
14
+ return false
15
+ }
16
+
17
+ func equals(_ type: AnyDynamicType) -> Bool {
18
+ if let arrayType = type as? Self {
19
+ return arrayType.elementType.equals(elementType)
20
+ }
21
+ return false
22
+ }
23
+
24
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
25
+ if let value = value as? [Any] {
26
+ return try value.map { try elementType.cast($0) }
27
+ }
28
+ // We should probably throw an error if we get here. On the other side, the array type
29
+ // requirement can be more loosen so we can try to arrayize values that are not arrays.
30
+ return [try elementType.cast(value)]
31
+ }
32
+
33
+ var description: String {
34
+ "[\(elementType.description)]"
35
+ }
36
+ }
37
+
38
+ /**
39
+ A type-erased protocol used to recognize if the generic type is an array type.
40
+ `Array` is a generic type, so it's impossible to check the inheritance directly.
41
+ */
42
+ internal protocol AnyArray {
43
+ /**
44
+ Exposes the `Element` generic type wrapped by the dynamic type to preserve its metadata.
45
+ */
46
+ static func getElementDynamicType() -> AnyDynamicType
47
+ }
48
+
49
+ /**
50
+ Extends the `Array` type to expose its generic `Element` as a dynamic type.
51
+ */
52
+ extension Array: AnyArray {
53
+ static func getElementDynamicType() -> AnyDynamicType {
54
+ return DynamicType(Element.self)
55
+ }
56
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type that wraps any type conforming to `ConvertibleArgument` protocol.
5
+ */
6
+ internal struct DynamicConvertibleType: AnyDynamicType {
7
+ let innerType: ConvertibleArgument.Type
8
+
9
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
10
+ return innerType == InnerType.self
11
+ }
12
+
13
+ func equals(_ type: AnyDynamicType) -> Bool {
14
+ if let convertibleType = type as? Self {
15
+ return convertibleType.innerType == innerType
16
+ }
17
+ return false
18
+ }
19
+
20
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
21
+ return try innerType.convert(from: value)
22
+ }
23
+
24
+ var description: String {
25
+ String(describing: innerType.self)
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type representing an enum that conforms to `EnumArgument`.
5
+ */
6
+ internal struct DynamicEnumType: AnyDynamicType {
7
+ let innerType: EnumArgument.Type
8
+
9
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
10
+ return innerType == InnerType.self
11
+ }
12
+
13
+ func equals(_ type: AnyDynamicType) -> Bool {
14
+ if let enumType = type as? Self {
15
+ return enumType.innerType == innerType
16
+ }
17
+ return false
18
+ }
19
+
20
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
21
+ return try innerType.create(fromRawValue: value)
22
+ }
23
+
24
+ var description: String {
25
+ "Enum<\(innerType)>"
26
+ }
27
+ }
@@ -0,0 +1,63 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type that represents an optional type, which allows `nil` to be passed when casting.
5
+ Requires the optional's wrapped type as it delegates casting to that type for non-nil values.
6
+ */
7
+ internal struct DynamicOptionalType: AnyDynamicType {
8
+ let wrappedType: AnyDynamicType
9
+
10
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
11
+ if let OptionalType = InnerType.self as? AnyOptional.Type {
12
+ return wrappedType.equals(OptionalType.getWrappedDynamicType())
13
+ }
14
+ return false
15
+ }
16
+
17
+ func equals(_ type: AnyDynamicType) -> Bool {
18
+ if let optionalType = type as? Self {
19
+ return optionalType.wrappedType.equals(wrappedType)
20
+ }
21
+ return false
22
+ }
23
+
24
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
25
+ if Optional.isNil(value) || value is NSNull {
26
+ return Optional<Any>.none as Any
27
+ }
28
+ return try wrappedType.cast(value)
29
+ }
30
+
31
+ var description: String {
32
+ "\(wrappedType)?"
33
+ }
34
+ }
35
+
36
+ /**
37
+ A type-erased protocol used to recognize if the generic type is an optional type.
38
+ `Optional` is a generic enum, so it's impossible to check the inheritance directly.
39
+ */
40
+ internal protocol AnyOptional {
41
+ /**
42
+ Exposes the `Wrapped` generic type wrapped by the dynamic type to preserve its metadata.`
43
+ */
44
+ static func getWrappedDynamicType() -> AnyDynamicType
45
+ }
46
+
47
+ /**
48
+ Make generic `Optional` implement non-generic `AnyOptional` and add handy check against type-erased `nil`.
49
+ */
50
+ extension Optional: AnyOptional {
51
+ static func getWrappedDynamicType() -> AnyDynamicType {
52
+ return DynamicType(Wrapped.self)
53
+ }
54
+
55
+ static func isNil(_ object: Wrapped) -> Bool {
56
+ switch object as Any {
57
+ case Optional<Any>.none:
58
+ return true
59
+ default:
60
+ return false
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,33 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type that can wrap any type, but it casts only type-compatible values using `as?` keyword.
5
+ The innermost type of the other dynamic types like `ArrayArgumentType` and `OptionalArgumentType`.
6
+ */
7
+ internal struct DynamicRawType<InnerType>: AnyDynamicType {
8
+ let innerType: InnerType.Type
9
+
10
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
11
+ return type == innerType
12
+ }
13
+
14
+ func equals(_ type: AnyDynamicType) -> Bool {
15
+ return type is Self
16
+ }
17
+
18
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
19
+ if let value = value as? InnerType {
20
+ return value
21
+ }
22
+ // Raw types are always non-optional, but they may receive `nil` values.
23
+ // Let's throw more specific error in this case.
24
+ if Optional.isNil(value) {
25
+ throw Conversions.NullCastException<InnerType>()
26
+ }
27
+ throw Conversions.CastingException<InnerType>(value)
28
+ }
29
+
30
+ var description: String {
31
+ String(describing: innerType.self)
32
+ }
33
+ }
@@ -0,0 +1,37 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A dynamic type representing the `SharedObject` type and its subclasses.
5
+ */
6
+ internal struct DynamicSharedObjectType: AnyDynamicType {
7
+ let innerType: SharedObject.Type
8
+
9
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
10
+ return innerType == InnerType.self
11
+ }
12
+
13
+ func equals(_ type: AnyDynamicType) -> Bool {
14
+ if let sharedObjectType = type as? Self {
15
+ return sharedObjectType.innerType == innerType
16
+ }
17
+ return false
18
+ }
19
+
20
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
21
+ if let jsObject = try (value as? JavaScriptValue)?.asObject(),
22
+ let nativeSharedObject = SharedObjectRegistry.toNativeObject(jsObject) {
23
+ return nativeSharedObject
24
+ }
25
+ throw NativeSharedObjectNotFoundException()
26
+ }
27
+
28
+ var description: String {
29
+ return "SharedObject<\(innerType)>"
30
+ }
31
+ }
32
+
33
+ internal final class NativeSharedObjectNotFoundException: Exception {
34
+ override var reason: String {
35
+ "Unable to find the native shared object associated with given JavaScript object"
36
+ }
37
+ }
@@ -0,0 +1,39 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ // Function names should start with a lowercase character, but in this one case
4
+ // we want it to be uppercase as we treat it more like a generic class.
5
+ // swiftlint:disable identifier_name
6
+
7
+ /**
8
+ Factory creating an instance of the dynamic type wrapper conforming to `AnyDynamicType`.
9
+ Depending on the given type, it may return one of `DynamicArrayType`, `DynamicOptionalType`, `DynamicConvertibleType`, etc.
10
+ */
11
+ internal func DynamicType<T>(_ type: T.Type) -> AnyDynamicType {
12
+ if let ArrayType = T.self as? AnyArray.Type {
13
+ return DynamicArrayType(elementType: ArrayType.getElementDynamicType())
14
+ }
15
+ if let OptionalType = T.self as? AnyOptional.Type {
16
+ return DynamicOptionalType(wrappedType: OptionalType.getWrappedDynamicType())
17
+ }
18
+ if let ConvertibleType = T.self as? ConvertibleArgument.Type {
19
+ return DynamicConvertibleType(innerType: ConvertibleType)
20
+ }
21
+ if let EnumType = T.self as? EnumArgument.Type {
22
+ return DynamicEnumType(innerType: EnumType)
23
+ }
24
+ if let SharedObjectType = T.self as? SharedObject.Type {
25
+ return DynamicSharedObjectType(innerType: SharedObjectType)
26
+ }
27
+ if let TypedArrayType = T.self as? AnyTypedArray.Type {
28
+ return DynamicTypedArrayType(innerType: TypedArrayType)
29
+ }
30
+ return DynamicRawType(innerType: T.self)
31
+ }
32
+
33
+ /**
34
+ Handy prefix operator that makes the dynamic type from the static type.
35
+ */
36
+ prefix operator ~
37
+ public prefix func ~ <T>(type: T.Type) -> AnyDynamicType {
38
+ return DynamicType(type)
39
+ }
@@ -0,0 +1,46 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ internal struct DynamicTypedArrayType: AnyDynamicType {
4
+ let innerType: AnyTypedArray.Type
5
+
6
+ func wraps<InnerType>(_ type: InnerType.Type) -> Bool {
7
+ return innerType == InnerType.self
8
+ }
9
+
10
+ func equals(_ type: AnyDynamicType) -> Bool {
11
+ if let typedArrayType = type as? Self {
12
+ return typedArrayType.innerType == innerType
13
+ }
14
+ return false
15
+ }
16
+
17
+ func cast<ValueType>(_ value: ValueType) throws -> Any {
18
+ // It must be a JavaScript typed array.
19
+ guard let value = value as? JavaScriptValue, let jsTypedArray = value.getTypedArray() else {
20
+ throw NotTypedArrayException(innerType)
21
+ }
22
+ let typedArray = TypedArray.create(from: jsTypedArray)
23
+
24
+ // Concrete typed arrays must be the same as the inner type.
25
+ guard innerType == TypedArray.self || type(of: typedArray) == innerType else {
26
+ throw ArrayTypeMismatchException((received: type(of: typedArray), expected: innerType))
27
+ }
28
+ return typedArray
29
+ }
30
+
31
+ var description: String {
32
+ return String(describing: innerType)
33
+ }
34
+ }
35
+
36
+ internal final class ArrayTypeMismatchException: GenericException<(received: Any.Type, expected: Any.Type)> {
37
+ override var reason: String {
38
+ "Received a typed array of type \(param.received), expected \(param.expected)"
39
+ }
40
+ }
41
+
42
+ internal final class NotTypedArrayException: GenericException<AnyTypedArray.Type> {
43
+ override var reason: String {
44
+ "Given argument is not an instance of \(param)"
45
+ }
46
+ }
@@ -17,7 +17,7 @@ public protocol ChainableException: Error, AnyObject {
17
17
  /**
18
18
  Sets the direct cause of the exception and returns itself.
19
19
  */
20
- func causedBy(_ error: Error) -> Self
20
+ func causedBy(_ error: Error?) -> Self
21
21
 
22
22
  /**
23
23
  Tells whether any of the cause in chain is of given type.
@@ -34,8 +34,8 @@ public extension ChainableException {
34
34
  }
35
35
 
36
36
  @discardableResult
37
- func causedBy(_ error: Error) -> Self {
38
- cause = error
37
+ func causedBy(_ error: Error?) -> Self {
38
+ cause = error ?? cause
39
39
  return self
40
40
  }
41
41
 
@@ -3,7 +3,7 @@ import Foundation
3
3
  /**
4
4
  A protocol for errors specyfing its `code` and providing the `description`.
5
5
  */
6
- public protocol CodedError: Error {
6
+ public protocol CodedError: Error, CustomStringConvertible {
7
7
  var code: String { get }
8
8
  var description: String { get }
9
9
  }
@@ -1,9 +1,7 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
3
  open class Exception: CodedError, ChainableException, CustomStringConvertible, CustomDebugStringConvertible {
4
- open var name: String {
5
- return String(describing: Self.self)
6
- }
4
+ open lazy var name: String = String(describing: Self.self)
7
5
 
8
6
  /**
9
7
  String describing the reason of the exception.
@@ -25,15 +23,19 @@ open class Exception: CodedError, ChainableException, CustomStringConvertible, C
25
23
  self.origin = ExceptionOrigin(file: file, line: line, function: function)
26
24
  }
27
25
 
26
+ public init(name: String, description: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
27
+ self.origin = ExceptionOrigin(file: file, line: line, function: function)
28
+ self.name = name
29
+ self.description = description
30
+ }
31
+
28
32
  // MARK: ChainableException
29
33
 
30
34
  open var cause: Error?
31
35
 
32
36
  // MARK: CustomStringConvertible
33
37
 
34
- open var description: String {
35
- return concatDescription(reason, withCause: cause, debug: false)
36
- }
38
+ open lazy var description: String = concatDescription(reason, withCause: cause, debug: false)
37
39
 
38
40
  // MARK: CustomDebugStringConvertible
39
41
 
@@ -6,8 +6,9 @@
6
6
  public class UnexpectedException: Exception {
7
7
  private let errorDescription: String
8
8
 
9
- public init(_ error: Error) {
9
+ public init(_ error: Error, file: String = #fileID, line: UInt = #line, function: String = #function) {
10
10
  self.errorDescription = error.localizedDescription
11
+ super.init(file: file, line: line, function: function)
11
12
  }
12
13
 
13
14
  public override var reason: String {
@@ -0,0 +1,5 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RCT_EXTERN_MODULE(ExpoBridgeModule, NSObject)
4
+
5
+ @end
@@ -0,0 +1,79 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import React
4
+ import Foundation
5
+
6
+ /**
7
+ The classic bridge module that is responsible for:
8
+ - Creating and owning the `AppContext` when the Expo modules architecture is automatically initialized
9
+ by React Native (as opposed to native unit tests, where React Native is not used at all).
10
+ - Installing the host object to the runtime.
11
+ */
12
+ @objc(ExpoBridgeModule)
13
+ public final class ExpoBridgeModule: NSObject, RCTBridgeModule {
14
+ @objc
15
+ public let appContext: AppContext
16
+
17
+ /**
18
+ The initializer that is used by React Native when it loads bridge modules.
19
+ In this scenario, we create an `AppContext` that manages the
20
+ architecture of Expo modules and the app itself.
21
+ */
22
+ override init() {
23
+ appContext = AppContext()
24
+ super.init()
25
+
26
+ // Listen to React Native notifications posted just before the JS is executed.
27
+ NotificationCenter.default.addObserver(self,
28
+ selector: #selector(javaScriptWillStartExecutingNotification(_:)),
29
+ name: NSNotification.Name.RCTJavaScriptWillStartExecuting,
30
+ object: nil)
31
+ }
32
+
33
+ deinit {
34
+ NotificationCenter.default.removeObserver(self)
35
+ }
36
+
37
+ // MARK: - RCTBridgeModule
38
+
39
+ public static func moduleName() -> String! {
40
+ return "Expo"
41
+ }
42
+
43
+ public static func requiresMainQueueSetup() -> Bool {
44
+ return true
45
+ }
46
+
47
+ public var bridge: RCTBridge! {
48
+ didSet {
49
+ appContext.reactBridge = bridge
50
+ }
51
+ }
52
+
53
+ /**
54
+ This should be called inside EXNativeModulesProxy.setBridge()
55
+ */
56
+ @objc
57
+ public func legacyProxyDidSetBridge(legacyModulesProxy: LegacyNativeModulesProxy,
58
+ legacyModuleRegistry: EXModuleRegistry) {
59
+ appContext.legacyModuleRegistry = legacyModuleRegistry
60
+ appContext.legacyModulesProxy = legacyModulesProxy
61
+
62
+ // we need to register all the modules after the legacy module registry is set
63
+ // otherwise legacy modules (e.g. permissions) won't be available in OnCreate { }
64
+ appContext.useModulesProvider("ExpoModulesProvider")
65
+ appContext.moduleRegistry.register(moduleType: NativeModulesProxyModule.self)
66
+ }
67
+
68
+ // MARK: - Notifications
69
+
70
+ @objc
71
+ public func javaScriptWillStartExecutingNotification(_ notification: Notification) {
72
+ if (notification.object as? RCTBridge)?.batched == bridge {
73
+ // The JavaScript bundle will start executing in a moment,
74
+ // so the runtime is already initialized and we can get it from the bridge.
75
+ // This should automatically install the ExpoModules host object.
76
+ appContext.runtime = EXJavaScriptRuntimeManager.runtime(fromBridge: bridge)
77
+ }
78
+ }
79
+ }
@@ -1,57 +1,59 @@
1
- import Dispatch
1
+ /**
2
+ An alias to `Result<Any, Exception>` which can be passed to the function callback.
3
+ */
4
+ public typealias FunctionCallResult = Result<Any, Exception>
2
5
 
3
6
  /**
4
7
  A protocol for any type-erased function.
5
8
  */
6
- public protocol AnyFunction: AnyDefinition {
9
+ internal protocol AnyFunction: AnyDefinition, JavaScriptObjectBuilder {
7
10
  /**
8
11
  Name of the function. JavaScript refers to the function by this name.
9
12
  */
10
13
  var name: String { get }
11
14
 
12
15
  /**
13
- Bool value indicating whether the function takes promise as the last argument.
14
- */
15
- var takesPromise: Bool { get }
16
-
17
- /**
18
- An array of argument types that the function takes. If the last type is `Promise`, it's not included.
16
+ An array of the dynamic types that the function takes. If the last type is `Promise`, it's not included.
19
17
  */
20
- var argumentTypes: [AnyArgumentType] { get }
18
+ var dynamicArgumentTypes: [AnyDynamicType] { get }
21
19
 
22
20
  /**
23
- A number of arguments the function takes. If the last argument is of type `Promise`, it is not counted.
21
+ A number of arguments the function takes. If the function expects to receive an owner (`this`) as the first argument, it's not counted.
22
+ Similarly, if the last argument is of type `Promise`, it is not counted.
24
23
  */
25
24
  var argumentsCount: Int { get }
26
25
 
27
26
  /**
28
- Dispatch queue on which each function's call is run.
29
- */
30
- var queue: DispatchQueue? { get }
31
-
32
- /**
33
- Whether the function needs to be called asynchronously from JavaScript.
27
+ Indicates whether the function's arguments starts from the owner that calls this function.
34
28
  */
35
- var isAsync: Bool { get }
29
+ var takesOwner: Bool { get set }
36
30
 
37
31
  /**
38
- Calls the function on given module with arguments and a promise.
32
+ Calls the function with a given owner and arguments and returns a result through the callback block.
33
+ - Parameters:
34
+ - owner: An object that calls this function. If the `takesOwner` property is true
35
+ and type of the first argument matches the owner type, it's being passed as the argument.
36
+ - args: An array of arguments to pass to the function. They could be Swift primitives
37
+ when invoked through the bridge and in unit tests or `JavaScriptValue`s
38
+ when the function is called through the JSI.
39
+ - callback: A callback that receives a result of the function execution.
39
40
  */
40
- func call(args: [Any], promise: Promise)
41
-
42
- /**
43
- Synchronously calls the function with given arguments. If the function takes a promise,
44
- the current thread will be locked until the promise rejects or resolves with the return value.
45
- */
46
- func callSync(args: [Any]) -> Any
41
+ func call(by owner: AnyObject?, withArguments args: [Any], callback: @escaping (FunctionCallResult) -> ())
42
+ }
47
43
 
44
+ extension AnyFunction {
48
45
  /**
49
- Specifies on which queue the function should run.
46
+ Calls the function just like `call(by:withArguments:callback:)`, but without an owner
47
+ and with an empty callback. Might be useful when you only want to call the function,
48
+ but don't care about the result.
50
49
  */
51
- func runOnQueue(_ queue: DispatchQueue?) -> Self
50
+ func call(withArguments args: [Any]) {
51
+ call(by: nil, withArguments: args, callback: { _ in })
52
+ }
53
+ }
52
54
 
53
- /**
54
- Makes the JavaScript function synchronous.
55
- */
56
- func runSynchronously() -> Self
55
+ internal class FunctionCallException: GenericException<String> {
56
+ override var reason: String {
57
+ "Calling the '\(param)' function has failed"
58
+ }
57
59
  }