expo-modules-core 1.11.13 → 1.12.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 (408) hide show
  1. package/CHANGELOG.md +77 -13
  2. package/ExpoModulesCore.podspec +7 -4
  3. package/android/ExpoModulesCorePlugin.gradle +40 -28
  4. package/android/build.gradle +12 -93
  5. package/android/proguard-rules.pro +0 -8
  6. package/android/src/main/cpp/Exceptions.cpp +1 -1
  7. package/android/src/main/cpp/Exceptions.h +1 -1
  8. package/android/src/main/cpp/ExpoModulesHostObject.cpp +7 -6
  9. package/android/src/main/cpp/ExpoModulesHostObject.h +3 -3
  10. package/android/src/main/cpp/JNIInjector.cpp +4 -2
  11. package/android/src/main/cpp/JSIContext.cpp +354 -0
  12. package/android/src/main/cpp/{JSIInteropModuleRegistry.h → JSIContext.h} +90 -9
  13. package/android/src/main/cpp/JavaCallback.cpp +210 -24
  14. package/android/src/main/cpp/JavaCallback.h +42 -7
  15. package/android/src/main/cpp/JavaScriptFunction.cpp +20 -6
  16. package/android/src/main/cpp/JavaScriptFunction.h +4 -1
  17. package/android/src/main/cpp/JavaScriptModuleObject.cpp +118 -82
  18. package/android/src/main/cpp/JavaScriptModuleObject.h +21 -18
  19. package/android/src/main/cpp/JavaScriptObject.cpp +7 -8
  20. package/android/src/main/cpp/JavaScriptObject.h +4 -2
  21. package/android/src/main/cpp/JavaScriptRuntime.cpp +18 -41
  22. package/android/src/main/cpp/JavaScriptRuntime.h +2 -8
  23. package/android/src/main/cpp/JavaScriptTypedArray.cpp +3 -3
  24. package/android/src/main/cpp/JavaScriptTypedArray.h +1 -1
  25. package/android/src/main/cpp/JavaScriptValue.cpp +7 -7
  26. package/android/src/main/cpp/JavaScriptValue.h +1 -1
  27. package/android/src/main/cpp/JavaScriptWeakObject.cpp +4 -4
  28. package/android/src/main/cpp/JavaScriptWeakObject.h +1 -1
  29. package/android/src/main/cpp/MethodMetadata.cpp +44 -120
  30. package/android/src/main/cpp/MethodMetadata.h +5 -11
  31. package/android/src/main/cpp/WeakRuntimeHolder.cpp +3 -3
  32. package/android/src/main/cpp/WeakRuntimeHolder.h +2 -2
  33. package/android/src/main/cpp/types/AnyType.cpp +1 -1
  34. package/android/src/main/cpp/types/AnyType.h +1 -1
  35. package/android/src/main/cpp/types/FrontendConverter.cpp +32 -43
  36. package/android/src/main/cpp/types/FrontendConverter.h +1 -23
  37. package/android/src/main/cpp/types/JNIToJSIConverter.cpp +5 -10
  38. package/android/src/main/cpp/types/JNIToJSIConverter.h +6 -2
  39. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +3 -0
  40. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +14 -100
  41. package/android/src/main/java/expo/modules/adapters/react/ReactAdapterPackage.java +3 -5
  42. package/android/src/main/java/expo/modules/adapters/react/ReactModuleRegistryProvider.java +6 -22
  43. package/android/src/main/java/expo/modules/adapters/react/apploader/RNHeadlessAppLoader.kt +8 -4
  44. package/android/src/main/java/expo/modules/adapters/react/services/EventEmitterModule.java +0 -1
  45. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +23 -8
  46. package/android/src/main/java/expo/modules/core/BasePackage.java +0 -10
  47. package/android/src/main/java/expo/modules/core/ModulePriorities.kt +1 -0
  48. package/android/src/main/java/expo/modules/core/ModuleRegistry.java +2 -32
  49. package/android/src/main/java/expo/modules/core/ModuleRegistryProvider.java +0 -18
  50. package/android/src/main/java/expo/modules/core/Promise.java +2 -0
  51. package/android/src/main/java/expo/modules/core/interfaces/Package.java +0 -17
  52. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +0 -9
  53. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +24 -31
  54. package/android/src/main/java/expo/modules/core/logging/LogHandler.kt +1 -7
  55. package/android/src/main/java/expo/modules/core/logging/LogHandlers.kt +11 -0
  56. package/android/src/main/java/expo/modules/core/logging/Logger.kt +18 -29
  57. package/android/src/main/java/expo/modules/core/logging/LoggerTimer.kt +11 -0
  58. package/android/src/main/java/expo/modules/core/logging/OSLogHandler.kt +2 -4
  59. package/android/src/main/java/expo/modules/core/logging/PersistentFileLogHandler.kt +1 -3
  60. package/android/src/main/java/expo/modules/interfaces/constants/ConstantsInterface.java +0 -2
  61. package/android/src/main/java/expo/modules/interfaces/permissions/PermissionsStatus.java +1 -1
  62. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +44 -24
  63. package/android/src/main/java/expo/modules/kotlin/ArrayExtenstions.kt +15 -0
  64. package/android/src/main/java/expo/modules/kotlin/CoreLogger.kt +2 -2
  65. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +0 -3
  66. package/android/src/main/java/expo/modules/kotlin/ExpoBridgeModule.kt +41 -0
  67. package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +1 -2
  68. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +1 -2
  69. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -33
  70. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +7 -6
  71. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +12 -12
  72. package/android/src/main/java/expo/modules/kotlin/Promise.kt +10 -0
  73. package/android/src/main/java/expo/modules/kotlin/ReactExtensions.kt +14 -0
  74. package/android/src/main/java/expo/modules/kotlin/Utils.kt +4 -1
  75. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +1 -1
  76. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +1 -1
  77. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +6 -6
  78. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +44 -15
  79. package/android/src/main/java/expo/modules/kotlin/defaultmodules/CoreModule.kt +31 -1
  80. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -4
  81. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +11 -4
  82. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +2 -3
  83. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +136 -43
  84. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +71 -2
  85. package/android/src/main/java/expo/modules/kotlin/functions/FunctionBuilder.kt +39 -12
  86. package/android/src/main/java/expo/modules/kotlin/jni/ExpectedType.kt +2 -2
  87. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +1 -1
  88. package/android/src/main/java/expo/modules/kotlin/jni/{JSIInteropModuleRegistry.kt → JSIContext.kt} +90 -14
  89. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +51 -24
  90. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +3 -3
  91. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +4 -1
  92. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +1 -0
  93. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +1 -0
  94. package/android/src/main/java/expo/modules/kotlin/jni/PromiseImpl.kt +20 -0
  95. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -1
  96. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +1 -1
  97. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +164 -65
  98. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +3 -4
  99. package/android/src/main/java/expo/modules/kotlin/sharedobjects/ClassRegistry.kt +21 -0
  100. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +34 -1
  101. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +23 -8
  102. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedRef.kt +7 -1
  103. package/android/src/main/java/expo/modules/kotlin/tracing/ExpoTrace.kt +4 -0
  104. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +134 -2
  105. package/android/src/main/java/expo/modules/kotlin/types/EnforceType.kt +60 -0
  106. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +2 -2
  107. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +0 -2
  108. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +3 -27
  109. package/android/src/main/java/expo/modules/kotlin/types/UnitTypeConverter.kt +3 -7
  110. package/android/src/main/java/expo/modules/kotlin/types/io/PathTypeConverter.kt +3 -0
  111. package/android/src/main/java/expo/modules/kotlin/viewevent/ViewEvent.kt +2 -5
  112. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +137 -48
  113. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +2 -5
  114. package/build/EventEmitter.d.ts +2 -2
  115. package/build/EventEmitter.d.ts.map +1 -1
  116. package/build/EventEmitter.js +8 -8
  117. package/build/EventEmitter.js.map +1 -1
  118. package/build/NativeModule.d.ts +4 -0
  119. package/build/NativeModule.d.ts.map +1 -0
  120. package/build/NativeModule.js +4 -0
  121. package/build/NativeModule.js.map +1 -0
  122. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  123. package/build/NativeModulesProxy.native.js +4 -0
  124. package/build/NativeModulesProxy.native.js.map +1 -1
  125. package/build/NativeModulesProxy.types.d.ts +2 -2
  126. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  127. package/build/NativeModulesProxy.types.js.map +1 -1
  128. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  129. package/build/NativeViewManagerAdapter.native.js +20 -1
  130. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  131. package/build/PermissionsHook.d.ts.map +1 -1
  132. package/build/PermissionsHook.js +2 -0
  133. package/build/PermissionsHook.js.map +1 -1
  134. package/build/Refs.d.ts +8 -0
  135. package/build/Refs.d.ts.map +1 -0
  136. package/build/Refs.js +10 -0
  137. package/build/Refs.js.map +1 -0
  138. package/build/SharedObject.d.ts +4 -0
  139. package/build/SharedObject.d.ts.map +1 -0
  140. package/build/SharedObject.js +4 -0
  141. package/build/SharedObject.js.map +1 -0
  142. package/build/createWebModule.d.ts +2 -0
  143. package/build/createWebModule.d.ts.map +1 -0
  144. package/build/createWebModule.js +6 -0
  145. package/build/createWebModule.js.map +1 -0
  146. package/build/createWebModule.web.d.ts +2 -0
  147. package/build/createWebModule.web.d.ts.map +1 -0
  148. package/build/createWebModule.web.js +6 -0
  149. package/build/createWebModule.web.js.map +1 -0
  150. package/build/ensureNativeModulesAreInstalled.d.ts +6 -0
  151. package/build/ensureNativeModulesAreInstalled.d.ts.map +1 -0
  152. package/build/ensureNativeModulesAreInstalled.js +26 -0
  153. package/build/ensureNativeModulesAreInstalled.js.map +1 -0
  154. package/build/hooks/useReleasingSharedObject.d.ts +7 -0
  155. package/build/hooks/useReleasingSharedObject.d.ts.map +1 -0
  156. package/build/hooks/useReleasingSharedObject.js +40 -0
  157. package/build/hooks/useReleasingSharedObject.js.map +1 -0
  158. package/build/index.d.ts +8 -1
  159. package/build/index.d.ts.map +1 -1
  160. package/build/index.js +8 -0
  161. package/build/index.js.map +1 -1
  162. package/build/requireNativeModule.d.ts +0 -17
  163. package/build/requireNativeModule.d.ts.map +1 -1
  164. package/build/requireNativeModule.js +2 -23
  165. package/build/requireNativeModule.js.map +1 -1
  166. package/build/ts-declarations/EventEmitter.d.ts +50 -0
  167. package/build/ts-declarations/EventEmitter.d.ts.map +1 -0
  168. package/build/ts-declarations/EventEmitter.js +2 -0
  169. package/build/ts-declarations/EventEmitter.js.map +1 -0
  170. package/build/ts-declarations/NativeModule.d.ts +14 -0
  171. package/build/ts-declarations/NativeModule.d.ts.map +1 -0
  172. package/build/ts-declarations/NativeModule.js +2 -0
  173. package/build/ts-declarations/NativeModule.js.map +1 -0
  174. package/build/ts-declarations/SharedObject.d.ts +14 -0
  175. package/build/ts-declarations/SharedObject.d.ts.map +1 -0
  176. package/build/ts-declarations/SharedObject.js +2 -0
  177. package/build/ts-declarations/SharedObject.js.map +1 -0
  178. package/build/ts-declarations/global.d.ts +49 -0
  179. package/build/ts-declarations/global.d.ts.map +1 -0
  180. package/build/ts-declarations/global.js +2 -0
  181. package/build/ts-declarations/global.js.map +1 -0
  182. package/build/web/CoreModule.d.ts +17 -0
  183. package/build/web/CoreModule.d.ts.map +1 -0
  184. package/build/web/CoreModule.js +51 -0
  185. package/build/web/CoreModule.js.map +1 -0
  186. package/build/web/index.d.ts +1 -0
  187. package/build/web/index.d.ts.map +1 -0
  188. package/build/web/index.js +1 -0
  189. package/build/web/index.js.map +1 -0
  190. package/build/web/index.web.d.ts +2 -0
  191. package/build/web/index.web.d.ts.map +1 -0
  192. package/build/web/index.web.js +2 -0
  193. package/build/web/index.web.js.map +1 -0
  194. package/common/cpp/BridgelessJSCallInvoker.h +41 -0
  195. package/common/cpp/EventEmitter.cpp +299 -0
  196. package/common/cpp/EventEmitter.h +111 -0
  197. package/common/cpp/JSIUtils.cpp +116 -11
  198. package/common/cpp/JSIUtils.h +54 -7
  199. package/common/cpp/LazyObject.cpp +15 -3
  200. package/common/cpp/LazyObject.h +13 -0
  201. package/common/cpp/NativeModule.cpp +16 -0
  202. package/common/cpp/NativeModule.h +34 -0
  203. package/common/cpp/ObjectDeallocator.cpp +3 -5
  204. package/common/cpp/ObjectDeallocator.h +2 -3
  205. package/common/cpp/SharedObject.cpp +69 -0
  206. package/common/cpp/SharedObject.h +59 -0
  207. package/common/cpp/TestingSyncJSCallInvoker.h +44 -0
  208. package/ios/Api/Builders/ClassComponentBuilder.swift +34 -0
  209. package/ios/{Objects → Api/Builders}/ObjectDefinitionBuilder.swift +3 -3
  210. package/ios/Api/Builders/ViewDefinitionBuilder.swift +53 -0
  211. package/ios/Api/Factories/AsyncFunctionFactories.swift +173 -0
  212. package/ios/{Classes/ClassComponentFactories.swift → Api/Factories/ClassFactories.swift} +19 -19
  213. package/ios/{Functions/ConcurrentFunctionDefinition.swift → Api/Factories/ConcurrentFunctionFactories.swift} +0 -113
  214. package/ios/{Modules/ModuleDefinitionComponents.swift → Api/Factories/EventListenersFactories.swift} +0 -20
  215. package/ios/Api/Factories/ModuleFactories.swift +6 -0
  216. package/ios/{Objects/ObjectDefinitionComponents.swift → Api/Factories/ObjectFactories.swift} +5 -5
  217. package/ios/Api/Factories/PropertyFactories.swift +50 -0
  218. package/ios/Api/Factories/SyncFunctionFactories.swift +173 -0
  219. package/ios/{Views/ViewManagerDefinitionComponents.swift → Api/Factories/ViewFactories.swift} +7 -6
  220. package/ios/AppDelegates/EXAppDelegateWrapper.h +0 -21
  221. package/ios/AppDelegates/EXAppDelegateWrapper.mm +37 -29
  222. package/ios/{AppContext.swift → Core/AppContext.swift} +34 -11
  223. package/ios/Core/Classes/AnyClassDefinitionElement.swift +37 -0
  224. package/ios/{Classes/ClassComponent.swift → Core/Classes/ClassDefinition.swift} +10 -10
  225. package/ios/{Conversions.swift → Core/Conversions.swift} +1 -1
  226. package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicSharedObjectType.swift +3 -3
  227. package/ios/Core/Events/EventObservingDefinition.swift +79 -0
  228. package/ios/Core/Events/LegacyEventEmitterCompat.swift +32 -0
  229. package/ios/Core/ExpoBridgeModule.h +18 -0
  230. package/ios/Core/ExpoBridgeModule.mm +88 -0
  231. package/ios/Core/ExpoRuntime.swift +6 -0
  232. package/ios/{Functions/AnyFunction.swift → Core/Functions/AnyFunctionDefinition.swift} +9 -2
  233. package/ios/Core/Functions/AsyncFunctionDefinition.swift +150 -0
  234. package/ios/Core/Functions/ConcurrentFunctionDefinition.swift +112 -0
  235. package/ios/Core/Functions/SyncFunctionDefinition.swift +108 -0
  236. package/ios/{JavaScriptUtils.swift → Core/JavaScriptUtils.swift} +4 -4
  237. package/ios/{Logging → Core/Logging}/LogHandlers.swift +12 -5
  238. package/ios/{Logging → Core/Logging}/Logger.swift +14 -92
  239. package/ios/Core/Logging/LoggerTimer.swift +22 -0
  240. package/ios/{ModuleHolder.swift → Core/ModuleHolder.swift} +2 -10
  241. package/ios/Core/Modules/CoreModule.swift +43 -0
  242. package/ios/{Modules → Core/Modules}/ModuleDefinition.swift +20 -12
  243. package/ios/{Modules → Core/Modules}/ModuleDefinitionBuilder.swift +1 -3
  244. package/ios/{Objects → Core/Objects}/ObjectDefinition.swift +9 -9
  245. package/ios/{Objects/PropertyComponent.swift → Core/Objects/PropertyDefinition.swift} +11 -64
  246. package/ios/Core/Protocols/AnyDefinition.swift +4 -0
  247. package/ios/Core/Protocols/AnyExpoView.swift +7 -0
  248. package/ios/Core/Protocols/AnyModule.swift +17 -0
  249. package/ios/Core/Protocols/AnyViewDefinition.swift +34 -0
  250. package/ios/Core/SharedObjects/SharedObject.swift +80 -0
  251. package/ios/{SharedObjects → Core/SharedObjects}/SharedObjectRegistry.swift +45 -19
  252. package/ios/{Views → Core/Views}/AnyViewProp.swift +1 -1
  253. package/ios/{Views → Core/Views}/ComponentData.swift +7 -7
  254. package/ios/{Views → Core/Views}/ExpoView.swift +1 -1
  255. package/ios/Core/Views/ViewDefinition.swift +97 -0
  256. package/ios/{Views → Core/Views}/ViewLifecycleMethod.swift +1 -1
  257. package/ios/{Views → Core/Views}/ViewModuleWrapper.swift +1 -1
  258. package/ios/Fabric/ExpoFabricView.swift +5 -6
  259. package/ios/FileSystemUtilities/FileSystemLegacyUtilities.swift +111 -0
  260. package/ios/JSI/EXJSIInstaller.h +28 -0
  261. package/ios/JSI/EXJSIInstaller.mm +54 -10
  262. package/ios/JSI/EXJSIUtils.h +15 -11
  263. package/ios/JSI/EXJSIUtils.mm +21 -49
  264. package/ios/JSI/EXJavaScriptObject.mm +2 -2
  265. package/ios/JSI/EXJavaScriptRuntime.h +15 -0
  266. package/ios/JSI/EXJavaScriptRuntime.mm +53 -26
  267. package/ios/JSI/EXSharedObjectUtils.h +15 -0
  268. package/ios/JSI/EXSharedObjectUtils.mm +18 -0
  269. package/ios/JSI/JavaScriptRuntime.swift +16 -0
  270. package/ios/Legacy/ModuleRegistry/EXModuleRegistry.m +1 -0
  271. package/ios/Legacy/ModuleRegistryProvider/EXModuleRegistryProvider.m +5 -0
  272. package/ios/Legacy/NativeModulesProxy/EXNativeModulesProxy.mm +5 -4
  273. package/ios/Legacy/Services/EXReactNativeAdapter.mm +34 -28
  274. package/ios/ReactDelegates/EXReactDelegateWrapper.h +4 -12
  275. package/ios/ReactDelegates/EXReactDelegateWrapper.mm +41 -0
  276. package/ios/ReactDelegates/EXReactRootViewFactory.h +38 -0
  277. package/ios/ReactDelegates/EXReactRootViewFactory.mm +54 -0
  278. package/ios/ReactDelegates/ExpoReactDelegate.swift +22 -15
  279. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +10 -21
  280. package/ios/ReactDelegates/RCTAppDelegate+Recreate.h +28 -0
  281. package/ios/ReactDelegates/RCTAppDelegate+Recreate.mm +47 -0
  282. package/ios/Tests/{ClassComponentSpec.swift → ClassDefinitionSpec.swift} +6 -6
  283. package/ios/Tests/ConvertiblesSpec.swift +6 -1
  284. package/ios/Tests/CoreModuleSpec.swift +0 -4
  285. package/ios/Tests/DynamicTypeSpec.swift +1 -1
  286. package/ios/Tests/EventEmitterSpec.swift +274 -0
  287. package/ios/Tests/ExceptionsSpec.swift +114 -54
  288. package/ios/Tests/ExpoModulesSpec.swift +4 -3
  289. package/ios/Tests/LoggerSpec.swift +80 -0
  290. package/ios/Tests/{PropertyComponentSpec.swift → PropertyDefinitionSpec.swift} +1 -1
  291. package/ios/Tests/SharedObjectRegistrySpec.swift +34 -28
  292. package/ios/Tests/SharedObjectSpec.swift +141 -0
  293. package/ios/Tests/ViewDefinitionSpec.swift +1 -1
  294. package/package.json +2 -2
  295. package/src/EventEmitter.ts +15 -18
  296. package/src/NativeModule.ts +6 -0
  297. package/src/NativeModulesProxy.native.ts +5 -0
  298. package/src/NativeModulesProxy.types.ts +2 -2
  299. package/src/NativeViewManagerAdapter.native.tsx +25 -1
  300. package/src/PermissionsHook.ts +4 -0
  301. package/src/Refs.ts +10 -0
  302. package/src/SharedObject.ts +6 -0
  303. package/src/createWebModule.ts +5 -0
  304. package/src/createWebModule.web.ts +6 -0
  305. package/src/ensureNativeModulesAreInstalled.ts +24 -0
  306. package/src/hooks/useReleasingSharedObject.ts +51 -0
  307. package/src/index.ts +13 -0
  308. package/src/requireNativeModule.ts +2 -51
  309. package/src/ts-declarations/EventEmitter.ts +65 -0
  310. package/src/ts-declarations/ExpoModules.d.ts +0 -5
  311. package/src/ts-declarations/NativeModule.ts +18 -0
  312. package/src/ts-declarations/SharedObject.ts +16 -0
  313. package/src/ts-declarations/global.ts +60 -0
  314. package/src/web/CoreModule.ts +83 -0
  315. package/src/web/index.ts +0 -0
  316. package/src/web/index.web.ts +1 -0
  317. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +0 -196
  318. package/android/src/main/java/expo/modules/adapters/react/ArgumentsHelper.java +0 -48
  319. package/android/src/main/java/expo/modules/adapters/react/PromiseWrapper.java +0 -38
  320. package/android/src/main/java/expo/modules/adapters/react/services/CookieManagerModule.java +0 -53
  321. package/android/src/main/java/expo/modules/core/ArgumentsHelper.java +0 -44
  322. package/android/src/main/java/expo/modules/core/ExportedModule.java +0 -173
  323. package/android/src/main/java/expo/modules/core/ModuleRegistryDelegate.kt +0 -12
  324. package/android/src/main/java/expo/modules/core/ViewManager.java +0 -9
  325. package/android/src/main/java/expo/modules/core/interfaces/ExpoMethod.java +0 -12
  326. package/android/src/main/java/expo/modules/core/interfaces/ExpoProp.java +0 -10
  327. package/android/src/main/java/expo/modules/core/logging/LoggerOptions.kt +0 -29
  328. package/android-annotation/build.gradle +0 -48
  329. package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +0 -7
  330. package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +0 -7
  331. package/android-annotation-processor/build.gradle +0 -54
  332. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +0 -175
  333. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +0 -10
  334. package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +0 -1
  335. package/ios/Classes/ClassComponentElement.swift +0 -37
  336. package/ios/Classes/ClassComponentElementsBuilder.swift +0 -34
  337. package/ios/ExpoBridgeModule.m +0 -7
  338. package/ios/ExpoBridgeModule.swift +0 -108
  339. package/ios/ExpoRuntime.swift +0 -28
  340. package/ios/Functions/AsyncFunctionComponent.swift +0 -327
  341. package/ios/Functions/SyncFunctionComponent.swift +0 -282
  342. package/ios/Interfaces/Font/EXFontManagerInterface.h +0 -9
  343. package/ios/Interfaces/Font/EXFontProcessorInterface.h +0 -15
  344. package/ios/Interfaces/Font/EXFontScalerInterface.h +0 -9
  345. package/ios/Interfaces/Font/EXFontScalersManagerInterface.h +0 -9
  346. package/ios/Legacy/Services/EXReactFontManager.h +0 -6
  347. package/ios/Legacy/Services/EXReactFontManager.m +0 -130
  348. package/ios/Modules/AnyModule.swift +0 -53
  349. package/ios/Modules/CoreModule.swift +0 -17
  350. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.h +0 -16
  351. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.m +0 -49
  352. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +0 -15
  353. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +0 -25
  354. package/ios/ReactDelegates/EXReactDelegateWrapper.m +0 -53
  355. package/ios/SharedObjects/SharedObject.swift +0 -31
  356. package/ios/Views/ViewDefinition.swift +0 -114
  357. package/ios/Views/ViewFactory.swift +0 -16
  358. package/ios/Views/ViewManagerDefinition.swift +0 -77
  359. package/ios/Views/ViewManagerDefinitionBuilder.swift +0 -11
  360. /package/ios/{AppContextConfig.swift → Core/AppContextConfig.swift} +0 -0
  361. /package/ios/{Arguments → Core/Arguments}/AnyArgument.swift +0 -0
  362. /package/ios/{Arguments → Core/Arguments}/Convertible.swift +0 -0
  363. /package/ios/{Arguments → Core/Arguments}/Convertibles.swift +0 -0
  364. /package/ios/{Arguments → Core/Arguments}/Enumerable.swift +0 -0
  365. /package/ios/{Classes → Core/Classes}/ClassRegistry.swift +0 -0
  366. /package/ios/{Convertibles → Core/Convertibles}/Convertibles+Color.swift +0 -0
  367. /package/ios/{Convertibles → Core/Convertibles}/Either.swift +0 -0
  368. /package/ios/{DynamicTypes → Core/DynamicTypes}/AnyDynamicType.swift +0 -0
  369. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicArrayType.swift +0 -0
  370. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicConvertibleType.swift +0 -0
  371. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicDataType.swift +0 -0
  372. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicDictionaryType.swift +0 -0
  373. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicEnumType.swift +0 -0
  374. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicJavaScriptType.swift +0 -0
  375. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicOptionalType.swift +0 -0
  376. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicRawType.swift +0 -0
  377. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicType.swift +0 -0
  378. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicTypedArrayType.swift +0 -0
  379. /package/ios/{DynamicTypes → Core/DynamicTypes}/DynamicViewType.swift +0 -0
  380. /package/ios/{EventListener.swift → Core/EventListener.swift} +0 -0
  381. /package/ios/{Events → Core/Events}/Callback.swift +0 -0
  382. /package/ios/{Events → Core/Events}/EventDispatcher.swift +0 -0
  383. /package/ios/{Exceptions → Core/Exceptions}/ChainableException.swift +0 -0
  384. /package/ios/{Exceptions → Core/Exceptions}/CodedError.swift +0 -0
  385. /package/ios/{Exceptions → Core/Exceptions}/CommonExceptions.swift +0 -0
  386. /package/ios/{Exceptions → Core/Exceptions}/Exception.swift +0 -0
  387. /package/ios/{Exceptions → Core/Exceptions}/ExceptionOrigin.swift +0 -0
  388. /package/ios/{Exceptions → Core/Exceptions}/GenericException.swift +0 -0
  389. /package/ios/{Exceptions → Core/Exceptions}/UnexpectedException.swift +0 -0
  390. /package/ios/{JavaScriptFunction.swift → Core/JavaScriptFunction.swift} +0 -0
  391. /package/ios/{Logging → Core/Logging}/LogType.swift +0 -0
  392. /package/ios/{Logging → Core/Logging}/PersistentFileLog.swift +0 -0
  393. /package/ios/{ModuleRegistry.swift → Core/ModuleRegistry.swift} +0 -0
  394. /package/ios/{Modules → Core/Modules}/Module.swift +0 -0
  395. /package/ios/{ModulesProvider.swift → Core/ModulesProvider.swift} +0 -0
  396. /package/ios/{Objects → Core/Objects}/JavaScriptObjectBuilder.swift +0 -0
  397. /package/ios/{Promise.swift → Core/Promise.swift} +0 -0
  398. /package/ios/{Records → Core/Records}/AnyField.swift +0 -0
  399. /package/ios/{Records → Core/Records}/Field.swift +0 -0
  400. /package/ios/{Records → Core/Records}/FieldExtensions.swift +0 -0
  401. /package/ios/{Records → Core/Records}/FieldOption.swift +0 -0
  402. /package/ios/{Records → Core/Records}/Record.swift +0 -0
  403. /package/ios/{SharedObjects → Core/SharedObjects}/SharedRef.swift +0 -0
  404. /package/ios/{TypedArrays → Core/TypedArrays}/AnyTypedArray.swift +0 -0
  405. /package/ios/{TypedArrays → Core/TypedArrays}/ConcreteTypedArrays.swift +0 -0
  406. /package/ios/{TypedArrays → Core/TypedArrays}/GenericTypedArray.swift +0 -0
  407. /package/ios/{TypedArrays → Core/TypedArrays}/TypedArray.swift +0 -0
  408. /package/ios/{Views → Core/Views}/ConcreteViewProp.swift +0 -0
@@ -0,0 +1,37 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ A type-erased protocol that must be implemented by the definitions passed as ``ClassDefinition`` elements.
5
+ */
6
+ public protocol AnyClassDefinitionElement: AnyDefinition {}
7
+
8
+ /**
9
+ Class definition element with an associated owner type. The `OwnerType` should refer to
10
+ the type that the parent `Class` definition is associated with (e.g. the shared object type).
11
+ */
12
+ public protocol ClassDefinitionElement: AnyClassDefinitionElement {
13
+ associatedtype OwnerType
14
+ }
15
+
16
+ // MARK: - Conformance
17
+ // Allow some other definitions to be used as the class definition elements.
18
+
19
+ extension SyncFunctionDefinition: ClassDefinitionElement {
20
+ public typealias OwnerType = FirstArgType
21
+ }
22
+
23
+ extension AsyncFunctionDefinition: ClassDefinitionElement {
24
+ public typealias OwnerType = FirstArgType
25
+ }
26
+
27
+ extension ConcurrentFunctionDefinition: ClassDefinitionElement {
28
+ public typealias OwnerType = FirstArgType
29
+ }
30
+
31
+ extension PropertyDefinition: ClassDefinitionElement {
32
+ // It already has the `OwnerType`
33
+ }
34
+
35
+ extension ConstantsDefinition: ClassDefinitionElement {
36
+ public typealias OwnerType = Void
37
+ }
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  Represents a JavaScript class.
5
5
  */
6
- public final class ClassComponent: ObjectDefinition {
6
+ public final class ClassDefinition: ObjectDefinition {
7
7
  /**
8
8
  Name of the class.
9
9
  */
@@ -12,7 +12,7 @@ public final class ClassComponent: ObjectDefinition {
12
12
  /**
13
13
  A synchronous function that gets called when the object of this class is initializing.
14
14
  */
15
- let constructor: AnySyncFunctionComponent?
15
+ let constructor: AnySyncFunctionDefinition?
16
16
 
17
17
  /**
18
18
  A dynamic type for the associated object class.
@@ -22,13 +22,13 @@ public final class ClassComponent: ObjectDefinition {
22
22
  init<AssociatedObject: ClassAssociatedObject>(
23
23
  name: String,
24
24
  associatedType: AssociatedObject.Type,
25
- elements: [AnyClassComponentElement] = []
25
+ elements: [AnyClassDefinitionElement] = []
26
26
  ) {
27
27
  self.name = name
28
- self.constructor = elements.first(where: isConstructor) as? AnySyncFunctionComponent
28
+ self.constructor = elements.first(where: isConstructor) as? AnySyncFunctionDefinition
29
29
  self.associatedType = ~AssociatedObject.self
30
30
 
31
- // Constructors can't be passed down to the object component
31
+ // Constructors can't be passed down to the object definition
32
32
  // as we shouldn't override the default `<Class>.prototype.constructor`.
33
33
  let elementsWithoutConstructors = elements.filter({ !isConstructor($0) })
34
34
 
@@ -38,7 +38,7 @@ public final class ClassComponent: ObjectDefinition {
38
38
  // MARK: - JavaScriptObjectBuilder
39
39
 
40
40
  public override func build(appContext: AppContext) throws -> JavaScriptObject {
41
- let klass = try appContext.runtime.createClass(name) { [weak self, weak appContext] this, arguments in
41
+ let klass = try appContext.runtime.createSharedObjectClass(name) { [weak self, weak appContext] this, arguments in
42
42
  guard let self = self, let appContext else {
43
43
  // TODO: Throw an exception? (@tsapeta)
44
44
  return
@@ -49,7 +49,7 @@ public final class ClassComponent: ObjectDefinition {
49
49
 
50
50
  // Register the shared object if returned by the constructor.
51
51
  if let result = result as? SharedObject {
52
- SharedObjectRegistry.add(native: result, javaScript: this)
52
+ appContext.sharedObjectRegistry.add(native: result, javaScript: this)
53
53
  }
54
54
  }
55
55
 
@@ -78,7 +78,7 @@ public final class ClassComponent: ObjectDefinition {
78
78
  // MARK: - ClassAssociatedObject
79
79
 
80
80
  /**
81
- A protocol for types that can be used an associated type of the `ClassComponent`.
81
+ A protocol for types that can be used an associated type of the ``ClassDefinition``.
82
82
  */
83
83
  internal protocol ClassAssociatedObject {}
84
84
 
@@ -99,10 +99,10 @@ extension SharedObject: ClassAssociatedObject {}
99
99
  Checks whether the definition item is a constructor — a synchronous function whose name is "constructor".
100
100
 
101
101
  We do it that way for the following two reasons:
102
- - It's easier to reuse existing `SyncFunctionComponent`.
102
+ - It's easier to reuse existing `SyncFunctionDefinition`.
103
103
  - Redefining prototype's `constructor` is a bad idea so a function with this name
104
104
  needs to be filtered out when decorating the prototype.
105
105
  */
106
106
  fileprivate func isConstructor(_ item: AnyDefinition) -> Bool {
107
- return (item as? AnySyncFunctionComponent)?.name == "constructor"
107
+ return (item as? AnySyncFunctionDefinition)?.name == "constructor"
108
108
  }
@@ -173,7 +173,7 @@ internal final class Conversions {
173
173
  log.warn("Unable to create a JS object for \(dynamicType.description)")
174
174
  return Optional<Any>.none
175
175
  }
176
- SharedObjectRegistry.add(native: value, javaScript: object)
176
+ appContext.sharedObjectRegistry.add(native: value, javaScript: object)
177
177
  return object
178
178
  }
179
179
  }
@@ -36,7 +36,7 @@ internal struct DynamicSharedObjectType: AnyDynamicType {
36
36
 
37
37
  // If the given value is a shared object id, search the registry for its native representation
38
38
  if let sharedObjectId = value as? SharedObjectId,
39
- let nativeSharedObject = SharedObjectRegistry.get(sharedObjectId)?.native {
39
+ let nativeSharedObject = appContext.sharedObjectRegistry.get(sharedObjectId)?.native {
40
40
  return nativeSharedObject
41
41
  }
42
42
  throw NativeSharedObjectNotFoundException()
@@ -46,13 +46,13 @@ internal struct DynamicSharedObjectType: AnyDynamicType {
46
46
  if jsValue.kind == .number {
47
47
  let sharedObjectId = jsValue.getInt() as SharedObjectId
48
48
 
49
- guard let nativeSharedObject = SharedObjectRegistry.get(sharedObjectId)?.native else {
49
+ guard let nativeSharedObject = appContext.sharedObjectRegistry.get(sharedObjectId)?.native else {
50
50
  throw NativeSharedObjectNotFoundException()
51
51
  }
52
52
  return nativeSharedObject
53
53
  }
54
54
  if let jsObject = try? jsValue.asObject(),
55
- let nativeSharedObject = SharedObjectRegistry.toNativeObject(jsObject) {
55
+ let nativeSharedObject = appContext.sharedObjectRegistry.toNativeObject(jsObject) {
56
56
  return nativeSharedObject
57
57
  }
58
58
  throw NativeSharedObjectNotFoundException()
@@ -0,0 +1,79 @@
1
+ // Copyright 2024-present 650 Industries. All rights reserved.
2
+
3
+ internal enum EventObservingType: String {
4
+ case startObserving
5
+ case stopObserving
6
+ }
7
+
8
+ internal protocol AnyEventObservingDefinition: AnyDefinition {
9
+ var event: String? { get }
10
+
11
+ var type: EventObservingType { get }
12
+
13
+ func call()
14
+ }
15
+
16
+ public final class EventObservingDefinition: AnyEventObservingDefinition {
17
+ public typealias ClosureType = () -> Void
18
+
19
+ let type: EventObservingType
20
+
21
+ let event: String?
22
+
23
+ let closure: ClosureType
24
+
25
+ init(type: EventObservingType, event: String?, _ closure: @escaping ClosureType) {
26
+ self.type = type
27
+ self.event = event
28
+ self.closure = closure
29
+ }
30
+
31
+ func call() {
32
+ closure()
33
+ }
34
+ }
35
+
36
+ public struct EventObservingDecorator: JavaScriptObjectDecorator {
37
+ let definitions: [any AnyEventObservingDefinition]
38
+
39
+ /**
40
+ Decorates the given object with `startObserving` and `stopObserving` functions.
41
+ These functions are automatically called by the `EventEmitter` implementation.
42
+ */
43
+ func decorate(object: JavaScriptObject, appContext: AppContext) throws {
44
+ // We need to keep track the number of observed events
45
+ // so we can call observers not attached to any event in the right moment.
46
+ var observingEvents: Int = 0
47
+
48
+ let startObserving = AsyncFunctionDefinition(
49
+ EventObservingType.startObserving.rawValue,
50
+ firstArgType: String.self,
51
+ dynamicArgumentTypes: [~String.self]
52
+ ) { (event: String) in
53
+ observingEvents += 1
54
+
55
+ for definition in definitions where definition.type == .startObserving {
56
+ if definition.event == event || (observingEvents == 1 && definition.event == nil) {
57
+ definition.call()
58
+ }
59
+ }
60
+ }
61
+
62
+ let stopObserving = AsyncFunctionDefinition(
63
+ EventObservingType.stopObserving.rawValue,
64
+ firstArgType: String.self,
65
+ dynamicArgumentTypes: [~String.self]
66
+ ) { (event: String) in
67
+ observingEvents -= 1
68
+
69
+ for definition in definitions where definition.type == .stopObserving {
70
+ if definition.event == event || (observingEvents == 0 && definition.event == nil) {
71
+ definition.call()
72
+ }
73
+ }
74
+ }
75
+
76
+ object.setProperty(startObserving.name, value: try startObserving.build(appContext: appContext))
77
+ object.setProperty(stopObserving.name, value: try stopObserving.build(appContext: appContext))
78
+ }
79
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright 2024-present 650 Industries. All rights reserved.
2
+
3
+ public final class LegacyEventEmitterCompat: EXEventEmitterService {
4
+ internal weak var appContext: AppContext?
5
+
6
+ init(appContext: AppContext) {
7
+ self.appContext = appContext
8
+ }
9
+
10
+ // Objective-C protocol doesn't specify nullability
11
+ // swiftlint:disable:next implicitly_unwrapped_optional
12
+ public func sendEvent(withName name: String!, body: Any!) {
13
+ guard let appContext, let runtime = try? appContext.runtime else {
14
+ log.warn("Unable to send an event '\(name)' because the runtime is not available")
15
+ return
16
+ }
17
+
18
+ // Send the event to all modules that declare support for this particular event.
19
+ // That's how it works in the device event emitter provided by React Native.
20
+ let moduleHoldersWithEvent = appContext.moduleRegistry.filter { holder in
21
+ return holder.definition.eventNames.contains(name)
22
+ }
23
+
24
+ runtime.schedule {
25
+ for holder in moduleHoldersWithEvent {
26
+ if let jsObject = holder.javaScriptObject {
27
+ JSIUtils.emitEvent(name, to: jsObject, withArguments: [body], in: runtime)
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,18 @@
1
+ // Copyright 2024-present 650 Industries. All rights reserved.
2
+
3
+ #import <React/RCTBridgeModule.h>
4
+ #import <ExpoModulesCore/EXNativeModulesProxy.h>
5
+ #import <ExpoModulesCore/EXModuleRegistry.h>
6
+
7
+ @class EXAppContext;
8
+
9
+ @interface ExpoBridgeModule : NSObject <RCTBridgeModule>
10
+
11
+ @property (nonatomic, nullable, strong) EXAppContext *appContext;
12
+
13
+ - (nonnull instancetype)initWithAppContext:(nonnull EXAppContext *) appContext;
14
+
15
+ - (void)legacyProxyDidSetBridge:(nonnull EXNativeModulesProxy *)moduleProxy
16
+ legacyModuleRegistry:(nonnull EXModuleRegistry *)moduleRegistry;
17
+
18
+ @end
@@ -0,0 +1,88 @@
1
+ // Copyright 2024-present 650 Industries. All rights reserved.
2
+
3
+ #import <ReactCommon/RCTTurboModule.h>
4
+ #import <ExpoModulesCore/ExpoBridgeModule.h>
5
+ #import <ExpoModulesCore/Swift.h>
6
+
7
+ // The runtime executor is included as of React Native 0.74 in bridgeless mode.
8
+ #if __has_include(<ReactCommon/RCTRuntimeExecutor.h>)
9
+ #import <ReactCommon/RCTRuntimeExecutor.h>
10
+ #endif // React Native >=0.74
11
+
12
+ @implementation ExpoBridgeModule
13
+
14
+ @synthesize bridge = _bridge;
15
+
16
+ RCT_EXPORT_MODULE(ExpoModulesCore);
17
+
18
+ - (instancetype)init
19
+ {
20
+ if (self = [super init]) {
21
+ _appContext = [[EXAppContext alloc] init];
22
+ }
23
+ return self;
24
+ }
25
+
26
+ - (instancetype)initWithAppContext:(EXAppContext *) appContext
27
+ {
28
+ if (self = [super init]) {
29
+ _appContext = appContext;
30
+ }
31
+ return self;
32
+ }
33
+
34
+ + (BOOL)requiresMainQueueSetup
35
+ {
36
+ // We do want to run the initialization (`setBridge`) on the JS thread.
37
+ return NO;
38
+ }
39
+
40
+ - (void)setBridge:(RCTBridge *)bridge
41
+ {
42
+ // As of React Native 0.74 with the New Architecture enabled,
43
+ // it's actually an instance of `RCTBridgeProxy` that provides backwards compatibility.
44
+ // Also, hold on with initializing the runtime until `setRuntimeExecutor` is called.
45
+ _bridge = bridge;
46
+ _appContext.reactBridge = bridge;
47
+
48
+ #if !__has_include(<ReactCommon/RCTRuntimeExecutor.h>)
49
+ _appContext._runtime = [EXJavaScriptRuntimeManager runtimeFromBridge:bridge];
50
+ #endif // React Native <0.74
51
+ }
52
+
53
+ #if __has_include(<ReactCommon/RCTRuntimeExecutor.h>)
54
+ - (void)setRuntimeExecutor:(RCTRuntimeExecutor *)runtimeExecutor
55
+ {
56
+ _appContext._runtime = [EXJavaScriptRuntimeManager runtimeFromBridge:_bridge withExecutor:runtimeExecutor];
57
+ }
58
+ #endif // React Native >=0.74
59
+
60
+ /**
61
+ This should be called inside `[EXNativeModulesProxy setBridge:]`.
62
+ */
63
+ - (void)legacyProxyDidSetBridge:(nonnull EXNativeModulesProxy *)moduleProxy
64
+ legacyModuleRegistry:(nonnull EXModuleRegistry *)moduleRegistry
65
+ {
66
+ _appContext.legacyModulesProxy = moduleProxy;
67
+ _appContext.legacyModuleRegistry = moduleRegistry;
68
+
69
+ // We need to register all the modules after the legacy module registry is set
70
+ // otherwise legacy modules (e.g. permissions) won't be available in OnCreate { }
71
+ [_appContext useModulesProvider:@"ExpoModulesProvider"];
72
+ }
73
+
74
+ /**
75
+ A synchronous method that is called from JS before requiring
76
+ any module to ensure that all necessary bindings are installed.
77
+ */
78
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(installModules)
79
+ {
80
+ if (_bridge && !_appContext._runtime) {
81
+ // TODO: Keep this condition until we remove the other way of installing modules.
82
+ // See `setBridge` method above.
83
+ _appContext._runtime = [EXJavaScriptRuntimeManager runtimeFromBridge:_bridge];
84
+ }
85
+ return nil;
86
+ }
87
+
88
+ @end
@@ -0,0 +1,6 @@
1
+ @objc(EXRuntime)
2
+ public final class ExpoRuntime: JavaScriptRuntime {
3
+ internal func initializeCoreObject(_ coreObject: JavaScriptObject) throws {
4
+ global().defineProperty(EXGlobalCoreObjectPropertyName, value: coreObject, options: .enumerable)
5
+ }
6
+ }
@@ -6,7 +6,7 @@ public typealias FunctionCallResult = Result<Any, Exception>
6
6
  /**
7
7
  A protocol for any type-erased function.
8
8
  */
9
- internal protocol AnyFunction: AnyDefinition, JavaScriptObjectBuilder {
9
+ internal protocol AnyFunctionDefinition: AnyDefinition, JavaScriptObjectBuilder {
10
10
  /**
11
11
  Name of the function. JavaScript refers to the function by this name.
12
12
  */
@@ -47,7 +47,7 @@ internal protocol AnyFunction: AnyDefinition, JavaScriptObjectBuilder {
47
47
  func call(by owner: AnyObject?, withArguments args: [Any], appContext: AppContext, callback: @escaping (FunctionCallResult) -> ())
48
48
  }
49
49
 
50
- extension AnyFunction {
50
+ extension AnyFunctionDefinition {
51
51
  var requiredArgumentsCount: Int {
52
52
  var trailingOptionalArgumentsCount: Int = 0
53
53
 
@@ -79,4 +79,11 @@ internal class FunctionCallException: GenericException<String> {
79
79
  override var reason: String {
80
80
  "Calling the '\(param)' function has failed"
81
81
  }
82
+
83
+ override var code: String {
84
+ guard let cause = cause as? Exception else {
85
+ return super.code
86
+ }
87
+ return cause.code
88
+ }
82
89
  }
@@ -0,0 +1,150 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import Dispatch
4
+
5
+ /**
6
+ Type-erased protocol for asynchronous functions.
7
+ */
8
+ internal protocol AnyAsyncFunctionDefinition: AnyFunctionDefinition {
9
+ /**
10
+ Specifies on which queue the function should run.
11
+ */
12
+ func runOnQueue(_ queue: DispatchQueue?) -> Self
13
+ }
14
+
15
+ /**
16
+ The default queue used for module's async function calls.
17
+ */
18
+ private let defaultQueue = DispatchQueue(label: "expo.modules.AsyncFunctionQueue", qos: .userInitiated)
19
+
20
+ /**
21
+ Represents a function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
22
+ */
23
+ public final class AsyncFunctionDefinition<Args, FirstArgType, ReturnType>: AnyAsyncFunctionDefinition {
24
+ typealias ClosureType = (Args) throws -> ReturnType
25
+
26
+ /**
27
+ The underlying closure to run when the function is called.
28
+ */
29
+ let body: ClosureType
30
+
31
+ /**
32
+ Bool value indicating whether the function takes promise as the last argument.
33
+ */
34
+ let takesPromise: Bool
35
+
36
+ /**
37
+ Dispatch queue on which each function's call is run.
38
+ */
39
+ var queue: DispatchQueue?
40
+
41
+ init(
42
+ _ name: String,
43
+ firstArgType: FirstArgType.Type,
44
+ dynamicArgumentTypes: [AnyDynamicType],
45
+ _ body: @escaping ClosureType
46
+ ) {
47
+ self.name = name
48
+ self.takesPromise = dynamicArgumentTypes.last?.wraps(Promise.self) ?? false
49
+ self.dynamicArgumentTypes = dynamicArgumentTypes
50
+ self.body = body
51
+ }
52
+
53
+ // MARK: - AnyFunction
54
+
55
+ let name: String
56
+
57
+ let dynamicArgumentTypes: [AnyDynamicType]
58
+
59
+ var argumentsCount: Int {
60
+ return dynamicArgumentTypes.count - (takesOwner ? 1 : 0) - (takesPromise ? 1 : 0)
61
+ }
62
+
63
+ var takesOwner: Bool = false
64
+
65
+ func call(by owner: AnyObject?, withArguments args: [Any], appContext: AppContext, callback: @escaping (FunctionCallResult) -> ()) {
66
+ let promise = Promise { value in
67
+ callback(.success(Conversions.convertFunctionResult(value)))
68
+ } rejecter: { exception in
69
+ callback(.failure(exception))
70
+ }
71
+ var arguments: [Any] = concat(
72
+ arguments: args,
73
+ withOwner: owner,
74
+ withPromise: takesPromise ? promise : nil,
75
+ forFunction: self,
76
+ appContext: appContext
77
+ )
78
+
79
+ do {
80
+ try validateArgumentsNumber(function: self, received: args.count)
81
+
82
+ // All `JavaScriptValue` args must be preliminarly converted on the JS thread, so before we jump to the function's queue.
83
+ arguments = try cast(jsValues: arguments, forFunction: self, appContext: appContext)
84
+ } catch let error as Exception {
85
+ callback(.failure(error))
86
+ return
87
+ } catch {
88
+ callback(.failure(UnexpectedException(error)))
89
+ return
90
+ }
91
+
92
+ let queue = queue ?? defaultQueue
93
+
94
+ queue.async { [body, name] in
95
+ let returnedValue: ReturnType?
96
+
97
+ do {
98
+ // Convert arguments to the types desired by the function.
99
+ arguments = try cast(arguments: arguments, forFunction: self, appContext: appContext)
100
+
101
+ // swiftlint:disable:next force_cast
102
+ let argumentsTuple = try Conversions.toTuple(arguments) as! Args
103
+
104
+ returnedValue = try body(argumentsTuple)
105
+ } catch let error as Exception {
106
+ promise.reject(FunctionCallException(name).causedBy(error))
107
+ return
108
+ } catch {
109
+ promise.reject(UnexpectedException(error))
110
+ return
111
+ }
112
+ if !self.takesPromise {
113
+ promise.resolve(returnedValue)
114
+ }
115
+ }
116
+ }
117
+
118
+ // MARK: - JavaScriptObjectBuilder
119
+
120
+ func build(appContext: AppContext) throws -> JavaScriptObject {
121
+ // It seems to be safe to capture a strong reference to `self` here. This is needed for detached functions, that are not part of the module definition.
122
+ // Module definitions are held in memory anyway, but detached definitions (returned by other functions) are not, so we need to capture them here.
123
+ // It will be deallocated when that JS host function is garbage-collected by the JS VM.
124
+ return try appContext.runtime.createAsyncFunction(name, argsCount: argumentsCount) { [self] this, args, resolve, reject in
125
+ self.call(by: this, withArguments: args, appContext: appContext) { result in
126
+ switch result {
127
+ case .failure(let error):
128
+ reject(error.code, error.description, nil)
129
+ case .success(let value):
130
+ resolve(value)
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ // MARK: - AnyAsyncFunctionDefinition
137
+
138
+ public func runOnQueue(_ queue: DispatchQueue?) -> Self {
139
+ self.queue = queue
140
+ return self
141
+ }
142
+ }
143
+
144
+ // MARK: - Exceptions
145
+
146
+ internal final class NativeFunctionUnavailableException: GenericException<String> {
147
+ override var reason: String {
148
+ return "Native function '\(param)' is no longer available in memory"
149
+ }
150
+ }
@@ -0,0 +1,112 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ Represents a concurrent function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
5
+ As opposed to `AsyncFunctionDefinition`, it can leverage the new Swift's concurrency model and take the async/await closure.
6
+ */
7
+ public final class ConcurrentFunctionDefinition<Args, FirstArgType, ReturnType>: AnyFunctionDefinition {
8
+ typealias ClosureType = (Args) async throws -> ReturnType
9
+
10
+ let body: ClosureType
11
+
12
+ init(
13
+ _ name: String,
14
+ firstArgType: FirstArgType.Type,
15
+ dynamicArgumentTypes: [AnyDynamicType],
16
+ _ body: @escaping ClosureType
17
+ ) {
18
+ self.name = name
19
+ self.body = body
20
+ self.dynamicArgumentTypes = dynamicArgumentTypes
21
+ }
22
+
23
+ // MARK: - AnyFunction
24
+
25
+ let name: String
26
+
27
+ let dynamicArgumentTypes: [AnyDynamicType]
28
+
29
+ var argumentsCount: Int {
30
+ return dynamicArgumentTypes.count - (takesOwner ? 1 : 0)
31
+ }
32
+
33
+ var takesOwner: Bool = false
34
+
35
+ func call(by owner: AnyObject?, withArguments args: [Any], appContext: AppContext, callback: @escaping (FunctionCallResult) -> Void) {
36
+ var arguments: [Any]
37
+
38
+ do {
39
+ try validateArgumentsNumber(function: self, received: args.count)
40
+
41
+ arguments = concat(
42
+ arguments: args,
43
+ withOwner: owner,
44
+ withPromise: nil,
45
+ forFunction: self,
46
+ appContext: appContext
47
+ )
48
+
49
+ // All `JavaScriptValue` args must be preliminarly converted on the JS thread, before we jump to the function's queue.
50
+ arguments = try cast(jsValues: arguments, forFunction: self, appContext: appContext)
51
+ } catch let error as Exception {
52
+ callback(.failure(error))
53
+ return
54
+ } catch {
55
+ callback(.failure(UnexpectedException(error)))
56
+ return
57
+ }
58
+
59
+ // Switch from the synchronous context to asynchronous
60
+ Task { [arguments] in
61
+ let result: Result<Any, Exception>
62
+
63
+ do {
64
+ // Convert arguments to the types desired by the function.
65
+ let finalArguments = try cast(arguments: arguments, forFunction: self, appContext: appContext)
66
+
67
+ // TODO: Right now we force cast the tuple in all types of functions, but we should throw another exception here.
68
+ // swiftlint:disable force_cast
69
+ let argumentsTuple = try Conversions.toTuple(finalArguments) as! Args
70
+ let returnValue = try await body(argumentsTuple)
71
+
72
+ result = .success(returnValue)
73
+ } catch let error as Exception {
74
+ result = .failure(FunctionCallException(name).causedBy(error))
75
+ } catch {
76
+ result = .failure(UnexpectedException(error))
77
+ }
78
+
79
+ // Go back to the JS thread to execute the callback
80
+ appContext.executeOnJavaScriptThread {
81
+ callback(result)
82
+ }
83
+ }
84
+ }
85
+
86
+ // MARK: - JavaScriptObjectBuilder
87
+
88
+ func build(appContext: AppContext) throws -> JavaScriptObject {
89
+ return try appContext.runtime.createAsyncFunction(name, argsCount: argumentsCount) {
90
+ [weak appContext, weak self, name] this, args, resolve, reject in
91
+
92
+ guard let appContext else {
93
+ let exception = Exceptions.AppContextLost()
94
+ return reject(exception.code, exception.description, nil)
95
+ }
96
+ guard let self else {
97
+ let exception = NativeFunctionUnavailableException(name)
98
+ return reject(exception.code, exception.description, nil)
99
+ }
100
+ self.call(by: this, withArguments: args, appContext: appContext) { result in
101
+ switch result {
102
+ case .failure(let error):
103
+ reject(error.code, error.description, nil)
104
+ case .success(let value):
105
+ // Convert some results to primitive types (e.g. records) or JS values (e.g. shared objects)
106
+ let convertedResult = Conversions.convertFunctionResult(value, appContext: appContext, dynamicType: ~ReturnType.self)
107
+ resolve(convertedResult)
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }