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,299 @@
1
+ #include "JSIUtils.h"
2
+ #include "EventEmitter.h"
3
+ #include "LazyObject.h"
4
+
5
+ namespace expo::EventEmitter {
6
+
7
+ #pragma mark - Listeners
8
+
9
+ void Listeners::add(jsi::Runtime &runtime, std::string eventName, const jsi::Function &listener) noexcept {
10
+ listenersMap[eventName].emplace_back(runtime, listener);
11
+ }
12
+
13
+ void Listeners::remove(jsi::Runtime &runtime, std::string eventName, const jsi::Function &listener) noexcept {
14
+ if (!listenersMap.contains(eventName)) {
15
+ return;
16
+ }
17
+ jsi::Value listenerValue(runtime, listener);
18
+
19
+ listenersMap[eventName].remove_if([&](const jsi::Value &item) {
20
+ return jsi::Value::strictEquals(runtime, listenerValue, item);
21
+ });
22
+ }
23
+
24
+ void Listeners::removeAll(std::string eventName) noexcept {
25
+ if (listenersMap.contains(eventName)) {
26
+ listenersMap[eventName].clear();
27
+ }
28
+ }
29
+
30
+ void Listeners::clear() noexcept {
31
+ listenersMap.clear();
32
+ }
33
+
34
+ size_t Listeners::listenersCount(std::string eventName) noexcept {
35
+ if (!listenersMap.contains(eventName)) {
36
+ return 0;
37
+ }
38
+ return listenersMap[eventName].size();
39
+ }
40
+
41
+ void Listeners::call(jsi::Runtime &runtime, std::string eventName, const jsi::Object &thisObject, const jsi::Value *args, size_t count) noexcept {
42
+ if (!listenersMap.contains(eventName)) {
43
+ return;
44
+ }
45
+ ListenersList &listenersList = listenersMap[eventName];
46
+ size_t listSize = listenersList.size();
47
+
48
+ if (listSize == 0) {
49
+ // Nothing to call.
50
+ return;
51
+ }
52
+ if (listSize == 1) {
53
+ // The most common scenario – just call the only listener.
54
+ listenersList
55
+ .front()
56
+ .asObject(runtime)
57
+ .asFunction(runtime)
58
+ .callWithThis(runtime, thisObject, args, count);
59
+ return;
60
+ }
61
+ // When there are more than one listener, we copy the list to a vector as the list may be modified during the loop.
62
+ std::vector<jsi::Function> listenersVector;
63
+ listenersVector.reserve(listSize);
64
+
65
+ // Copy listeners to vector already as jsi::Function so we don't additionally copy jsi::Value
66
+ for (const jsi::Value &listener : listenersList) {
67
+ listenersVector.push_back(listener.asObject(runtime).asFunction(runtime));
68
+ }
69
+
70
+ // Call listeners from the vector. The list can be modified by the listeners but it will not affect this loop,
71
+ // i.e. newly added listeners will not be called and removed listeners will be called one last time.
72
+ // This is compliant with the EventEmitter in Node.js
73
+ for (const jsi::Function &listener : listenersVector) {
74
+ listener.callWithThis(runtime, thisObject, args, count);
75
+ }
76
+ }
77
+
78
+ #pragma mark - NativeState
79
+
80
+ NativeState::NativeState() : jsi::NativeState() {}
81
+
82
+ NativeState::~NativeState() {
83
+ listeners.clear();
84
+ }
85
+
86
+ NativeState::Shared NativeState::get(jsi::Runtime &runtime, const jsi::Object &object, bool createIfMissing) {
87
+ if (object.hasNativeState<NativeState>(runtime)) {
88
+ return object.getNativeState<NativeState>(runtime);
89
+ }
90
+ if (createIfMissing) {
91
+ NativeState::Shared state = std::make_shared<NativeState>();
92
+ object.setNativeState(runtime, state);
93
+ return state;
94
+ }
95
+ return nullptr;
96
+ }
97
+
98
+ #pragma mark - Utils
99
+
100
+ void callObservingFunction(jsi::Runtime &runtime, const jsi::Object &object, const char* functionName, std::string eventName) {
101
+ jsi::Value fnValue = object.getProperty(runtime, functionName);
102
+
103
+ if (!fnValue.isObject()) {
104
+ // Skip it if there is no observing function.
105
+ return;
106
+ }
107
+
108
+ fnValue
109
+ .getObject(runtime)
110
+ .asFunction(runtime)
111
+ .callWithThis(runtime, object, {
112
+ jsi::Value(runtime, jsi::String::createFromUtf8(runtime, eventName))
113
+ });
114
+ }
115
+
116
+ void addListener(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Function &listener) {
117
+ if (NativeState::Shared state = NativeState::get(runtime, emitter, true)) {
118
+ state->listeners.add(runtime, eventName, listener);
119
+
120
+ if (state->listeners.listenersCount(eventName) == 1) {
121
+ callObservingFunction(runtime, emitter, "startObserving", eventName);
122
+ }
123
+ }
124
+ }
125
+
126
+ void removeListener(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Function &listener) {
127
+ if (NativeState::Shared state = NativeState::get(runtime, emitter, false)) {
128
+ size_t listenersCountBefore = state->listeners.listenersCount(eventName);
129
+
130
+ state->listeners.remove(runtime, eventName, listener);
131
+
132
+ if (listenersCountBefore >= 1 && state->listeners.listenersCount(eventName) == 0) {
133
+ callObservingFunction(runtime, emitter, "stopObserving", eventName);
134
+ }
135
+ }
136
+ }
137
+
138
+ void removeAllListeners(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName) {
139
+ if (NativeState::Shared state = NativeState::get(runtime, emitter, false)) {
140
+ size_t listenersCountBefore = state->listeners.listenersCount(eventName);
141
+
142
+ state->listeners.removeAll(eventName);
143
+
144
+ if (listenersCountBefore >= 1) {
145
+ callObservingFunction(runtime, emitter, "stopObserving", eventName);
146
+ }
147
+ }
148
+ }
149
+
150
+ void emitEvent(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Value *args, size_t count) {
151
+ if (NativeState::Shared state = NativeState::get(runtime, emitter, false)) {
152
+ state->listeners.call(runtime, eventName, emitter, args, count);
153
+ }
154
+ }
155
+
156
+ size_t getListenerCount(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName) {
157
+ if (NativeState::Shared state = NativeState::get(runtime, emitter, false)) {
158
+ return state->listeners.listenersCount(eventName);
159
+ }
160
+ return 0;
161
+ }
162
+
163
+ jsi::Value createEventSubscription(jsi::Runtime &runtime, const std::string &eventName, const jsi::Object &emitter, const jsi::Function &listener) {
164
+ jsi::Object subscription(runtime);
165
+ jsi::PropNameID removeProp = jsi::PropNameID::forAscii(runtime, "remove", 6);
166
+ std::shared_ptr<jsi::Value> emitterValue = std::make_shared<jsi::Value>(runtime, emitter);
167
+ std::shared_ptr<jsi::Value> listenerValue = std::make_shared<jsi::Value>(runtime, listener);
168
+
169
+ jsi::HostFunctionType removeSubscription = [eventName, emitterValue, listenerValue](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
170
+ jsi::Object emitter = emitterValue->getObject(runtime);
171
+ jsi::Function listener = listenerValue->getObject(runtime).getFunction(runtime);
172
+
173
+ removeListener(runtime, emitter, eventName, listener);
174
+ return jsi::Value::undefined();
175
+ };
176
+
177
+ subscription.setProperty(runtime, removeProp, jsi::Function::createFromHostFunction(runtime, removeProp, 0, removeSubscription));
178
+
179
+ return jsi::Value(runtime, subscription);
180
+ }
181
+
182
+ #pragma mark - Public API
183
+
184
+ void emitEvent(jsi::Runtime &runtime, jsi::Object &emitter, const std::string &eventName, const std::vector<jsi::Value> &arguments) {
185
+ emitEvent(runtime, emitter, eventName, arguments.data(), arguments.size());
186
+ }
187
+
188
+ jsi::Function getClass(jsi::Runtime &runtime) {
189
+ return common::getCoreObject(runtime)
190
+ .getPropertyAsFunction(runtime, "EventEmitter");
191
+ }
192
+
193
+ void installClass(jsi::Runtime &runtime) {
194
+ jsi::Function eventEmitterClass = common::createClass(runtime, "EventEmitter", [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
195
+ // To provide backwards compatibility with the old EventEmitter where the native module object was passed as an argument.
196
+ // We're checking if the argument is already an instance of the new emitter and if so, just return it without unnecessarily wrapping it.
197
+ if (count > 0) {
198
+ jsi::Object firstArg = args[0].asObject(runtime);
199
+ jsi::Function constructor = thisValue.asObject(runtime).getPropertyAsFunction(runtime, "constructor");
200
+
201
+ if (firstArg.instanceOf(runtime, constructor)) {
202
+ return jsi::Value(runtime, args[0]);
203
+ }
204
+ }
205
+ return jsi::Value(runtime, thisValue);
206
+ });
207
+ jsi::Object prototype = eventEmitterClass.getPropertyAsObject(runtime, "prototype");
208
+
209
+ jsi::HostFunctionType addListenerHost = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
210
+ std::string eventName = args[0].asString(runtime).utf8(runtime);
211
+ jsi::Function listener = args[1].asObject(runtime).asFunction(runtime);
212
+ jsi::Object thisObject = thisValue.getObject(runtime);
213
+
214
+ // `this` might be an object that is representing a host object, in which case it's not possible to get the native state.
215
+ // For native modules we need to unwrap it to get the object used under the hood by `LazyObject` host object.
216
+ const jsi::Object &emitter = LazyObject::unwrapObjectIfNecessary(runtime, thisObject);
217
+
218
+ addListener(runtime, emitter, eventName, listener);
219
+ return createEventSubscription(runtime, eventName, emitter, listener);
220
+ };
221
+
222
+ jsi::HostFunctionType removeListenerHost = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
223
+ std::string eventName = args[0].asString(runtime).utf8(runtime);
224
+ jsi::Function listener = args[1].asObject(runtime).asFunction(runtime);
225
+ jsi::Object thisObject = thisValue.getObject(runtime);
226
+
227
+ // Unwrap `this` object if it's a lazy object (e.g. native module).
228
+ const jsi::Object &emitter = LazyObject::unwrapObjectIfNecessary(runtime, thisObject);
229
+
230
+ removeListener(runtime, emitter, eventName, listener);
231
+ return jsi::Value::undefined();
232
+ };
233
+
234
+ jsi::HostFunctionType removeAllListenersHost = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
235
+ std::string eventName = args[0].asString(runtime).utf8(runtime);
236
+ jsi::Object thisObject = thisValue.getObject(runtime);
237
+
238
+ // Unwrap `this` object if it's a lazy object (e.g. native module).
239
+ const jsi::Object &emitter = LazyObject::unwrapObjectIfNecessary(runtime, thisObject);
240
+
241
+ removeAllListeners(runtime, emitter, eventName);
242
+ return jsi::Value::undefined();
243
+ };
244
+
245
+ jsi::HostFunctionType emit = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
246
+ std::string eventName = args[0].asString(runtime).utf8(runtime);
247
+ jsi::Object thisObject = thisValue.getObject(runtime);
248
+
249
+ // Unwrap `this` object if it's a lazy object (e.g. native module).
250
+ const jsi::Object &emitter = LazyObject::unwrapObjectIfNecessary(runtime, thisObject);
251
+
252
+ // Make a new pointer that skips the first argument which is the event name.
253
+ const jsi::Value *eventArgs = count > 1 ? &args[1] : nullptr;
254
+
255
+ emitEvent(runtime, emitter, eventName, eventArgs, count - 1);
256
+ return jsi::Value::undefined();
257
+ };
258
+
259
+ jsi::HostFunctionType listenerCountHost = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
260
+ std::string eventName = args[0].asString(runtime).utf8(runtime);
261
+ jsi::Object thisObject = thisValue.getObject(runtime);
262
+
263
+ // Unwrap `this` object if it's a lazy object (e.g. native module).
264
+ const jsi::Object &emitter = LazyObject::unwrapObjectIfNecessary(runtime, thisObject);
265
+
266
+ return jsi::Value((int)getListenerCount(runtime, emitter, eventName));
267
+ };
268
+
269
+ // Added for compatibility with the old EventEmitter API.
270
+ jsi::HostFunctionType removeSubscriptionHost = [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
271
+ jsi::Object subscription = args[0].asObject(runtime);
272
+
273
+ subscription.getProperty(runtime, "remove")
274
+ .asObject(runtime)
275
+ .asFunction(runtime)
276
+ .callWithThis(runtime, subscription, {});
277
+
278
+ return jsi::Value::undefined();
279
+ };
280
+
281
+ jsi::PropNameID addListenerProp = jsi::PropNameID::forAscii(runtime, "addListener", 11);
282
+ jsi::PropNameID removeListenerProp = jsi::PropNameID::forAscii(runtime, "removeListener", 14);
283
+ jsi::PropNameID removeAllListenersProp = jsi::PropNameID::forAscii(runtime, "removeAllListeners", 18);
284
+ jsi::PropNameID emitProp = jsi::PropNameID::forAscii(runtime, "emit", 4);
285
+ jsi::PropNameID listenerCountProp = jsi::PropNameID::forAscii(runtime, "listenerCount", 13);
286
+ jsi::PropNameID removeSubscriptionProp = jsi::PropNameID::forAscii(runtime, "removeSubscription", 18);
287
+
288
+ prototype.setProperty(runtime, addListenerProp, jsi::Function::createFromHostFunction(runtime, addListenerProp, 2, addListenerHost));
289
+ prototype.setProperty(runtime, removeListenerProp, jsi::Function::createFromHostFunction(runtime, removeListenerProp, 2, removeListenerHost));
290
+ prototype.setProperty(runtime, removeAllListenersProp, jsi::Function::createFromHostFunction(runtime, removeAllListenersProp, 1, removeAllListenersHost));
291
+ prototype.setProperty(runtime, emitProp, jsi::Function::createFromHostFunction(runtime, emitProp, 2, emit));
292
+ prototype.setProperty(runtime, listenerCountProp, jsi::Function::createFromHostFunction(runtime, listenerCountProp, 1, listenerCountHost));
293
+ prototype.setProperty(runtime, removeSubscriptionProp, jsi::Function::createFromHostFunction(runtime, removeSubscriptionProp, 1, removeSubscriptionHost));
294
+
295
+ common::getCoreObject(runtime)
296
+ .setProperty(runtime, "EventEmitter", eventEmitterClass);
297
+ }
298
+
299
+ } // namespace expo::EventEmitter
@@ -0,0 +1,111 @@
1
+ #pragma once
2
+
3
+ #ifdef __cplusplus
4
+
5
+ #include <unordered_map>
6
+ #include <list>
7
+ #include <jsi/jsi.h>
8
+
9
+ namespace jsi = facebook::jsi;
10
+
11
+ namespace expo::EventEmitter {
12
+
13
+ /**
14
+ Class containing and managing listeners of the event emitter.
15
+ */
16
+ class Listeners {
17
+ private:
18
+ friend class NativeState;
19
+ friend void addListener(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Function &listener);
20
+ friend void removeListener(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Function &listener);
21
+ friend void removeAllListeners(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName);
22
+ friend void emitEvent(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName, const jsi::Value *args, size_t count);
23
+ friend size_t getListenerCount(jsi::Runtime &runtime, const jsi::Object &emitter, const std::string &eventName);
24
+
25
+ /**
26
+ Type of the list containing listeners for the specific event name.
27
+ */
28
+ using ListenersList = std::list<jsi::Value>;
29
+
30
+ /**
31
+ Type of the map where the keys are event names and the values are lists of listeners.
32
+ */
33
+ using ListenersMap = std::unordered_map<std::string, ListenersList>;
34
+
35
+ /**
36
+ Map with the events and listeners.
37
+ */
38
+ ListenersMap listenersMap;
39
+
40
+ /**
41
+ Adds a listener for the given event name.
42
+ */
43
+ void add(jsi::Runtime &runtime, std::string eventName, const jsi::Function &listener) noexcept;
44
+
45
+ /**
46
+ Removes the listener for the given event name.
47
+ */
48
+ void remove(jsi::Runtime &runtime, std::string eventName, const jsi::Function &listener) noexcept;
49
+
50
+ /**
51
+ Removes all listeners for the given event name.
52
+ */
53
+ void removeAll(std::string eventName) noexcept;
54
+
55
+ /**
56
+ Clears the entire map of events and listeners.
57
+ */
58
+ void clear() noexcept;
59
+
60
+ /**
61
+ Returns a number of listeners added for the given event name.
62
+ */
63
+ size_t listenersCount(std::string eventName) noexcept;
64
+
65
+ /**
66
+ Calls listeners for the given event name, with the given `this` object and payload arguments.
67
+ */
68
+ void call(jsi::Runtime &runtime, std::string eventName, const jsi::Object &thisObject, const jsi::Value *args, size_t count) noexcept;
69
+ };
70
+
71
+ /**
72
+ Class representing a native state of objects that emit events.
73
+ */
74
+ class JSI_EXPORT NativeState : public jsi::NativeState {
75
+ public:
76
+ using Shared = std::shared_ptr<NativeState>;
77
+
78
+ NativeState();
79
+ virtual ~NativeState();
80
+
81
+ /**
82
+ A structure containing event listeners.
83
+ */
84
+ Listeners listeners;
85
+
86
+ /**
87
+ Gets event emitter's native state from the given object.
88
+ If `createIfMissing` is set to `true`, the state will be automatically created.
89
+ */
90
+ static Shared get(jsi::Runtime &runtime, const jsi::Object &object, bool createIfMissing = false);
91
+ };
92
+
93
+ /**
94
+ Emits an event with the given name and arguments to the emitter object.
95
+ Does nothing if the given object is not an instance of the EventEmitter class.
96
+ */
97
+ void emitEvent(jsi::Runtime &runtime, jsi::Object &emitter, const std::string &eventName, const std::vector<jsi::Value> &arguments);
98
+
99
+ /**
100
+ Gets `expo.EventEmitter` class from the given runtime.
101
+ */
102
+ jsi::Function getClass(jsi::Runtime &runtime);
103
+
104
+ /**
105
+ Installs `expo.EventEmitter` class in the given runtime.
106
+ */
107
+ void installClass(jsi::Runtime &runtime);
108
+
109
+ } // namespace expo::EventEmitter
110
+
111
+ #endif // __cplusplus
@@ -1,9 +1,75 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
+ #include <sstream>
3
4
  #include "JSIUtils.h"
4
5
 
5
6
  namespace expo::common {
6
7
 
8
+ jsi::Function createClass(jsi::Runtime &runtime, const char *name, ClassConstructor constructor) {
9
+ std::string nativeConstructorKey("__native_constructor__");
10
+
11
+ // Create a string buffer of the source code to evaluate.
12
+ std::stringstream source;
13
+ source << "(function " << name << "(...args) { return this." << nativeConstructorKey << "(...args); })";
14
+ std::shared_ptr<jsi::StringBuffer> sourceBuffer = std::make_shared<jsi::StringBuffer>(source.str());
15
+
16
+ // Evaluate the code and obtain returned value (the constructor function).
17
+ jsi::Object klass = runtime.evaluateJavaScript(sourceBuffer, "").asObject(runtime);
18
+
19
+ // Set the native constructor in the prototype.
20
+ jsi::Object prototype = klass.getPropertyAsObject(runtime, "prototype");
21
+ jsi::PropNameID nativeConstructorPropId = jsi::PropNameID::forAscii(runtime, nativeConstructorKey);
22
+ jsi::Function nativeConstructor = jsi::Function::createFromHostFunction(
23
+ runtime,
24
+ nativeConstructorPropId,
25
+ // The paramCount is not obligatory to match, it only affects the `length` property of the function.
26
+ 0,
27
+ [constructor](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
28
+ if (constructor) {
29
+ return constructor(runtime, thisValue, args, count);
30
+ }
31
+ return jsi::Value(runtime, thisValue);
32
+ });
33
+
34
+ jsi::Object descriptor(runtime);
35
+ descriptor.setProperty(runtime, "value", jsi::Value(runtime, nativeConstructor));
36
+
37
+ defineProperty(runtime, &prototype, nativeConstructorKey.c_str(), std::move(descriptor));
38
+
39
+ return klass.asFunction(runtime);
40
+ }
41
+
42
+ jsi::Function createInheritingClass(jsi::Runtime &runtime, const char *className, jsi::Function &baseClass, ClassConstructor constructor) {
43
+ jsi::PropNameID prototypePropNameId = jsi::PropNameID::forAscii(runtime, "prototype", 9);
44
+ jsi::Object baseClassPrototype = baseClass
45
+ .getProperty(runtime, prototypePropNameId)
46
+ .asObject(runtime);
47
+
48
+ jsi::Function klass = createClass(runtime, className, constructor);
49
+ jsi::Object klassPrototype = klass.getProperty(runtime, prototypePropNameId).asObject(runtime);
50
+
51
+ klassPrototype.setProperty(runtime, "__proto__", baseClassPrototype);
52
+
53
+ return klass;
54
+ }
55
+
56
+ jsi::Object createObjectWithPrototype(jsi::Runtime &runtime, jsi::Object *prototype) {
57
+ // Get the "Object" class.
58
+ jsi::Object objectClass = runtime
59
+ .global()
60
+ .getPropertyAsObject(runtime, "Object");
61
+
62
+ // Call "Object.create(prototype)" to create an object with the given prototype without calling the constructor.
63
+ jsi::Object object = objectClass
64
+ .getPropertyAsFunction(runtime, "create")
65
+ .callWithThis(runtime, objectClass, {
66
+ jsi::Value(runtime, *prototype)
67
+ })
68
+ .asObject(runtime);
69
+
70
+ return object;
71
+ }
72
+
7
73
  std::vector<jsi::PropNameID> jsiArrayToPropNameIdsVector(jsi::Runtime &runtime, const jsi::Array &array) {
8
74
  size_t size = array.size(runtime);
9
75
  std::vector<jsi::PropNameID> vector;
@@ -17,22 +83,61 @@ std::vector<jsi::PropNameID> jsiArrayToPropNameIdsVector(jsi::Runtime &runtime,
17
83
  return vector;
18
84
  }
19
85
 
20
- void definePropertyOnJSIObject(
21
- jsi::Runtime &runtime,
22
- jsi::Object *jsthis,
23
- const char *name,
24
- jsi::Object descriptor
25
- ) {
86
+ void defineProperty(jsi::Runtime &runtime, jsi::Object *object, const char *name, const PropertyDescriptor descriptor) {
87
+ jsi::Object jsDescriptor(runtime);
88
+
89
+ // These three flags are all `false` by default, so set the property only when `true`.
90
+ if (descriptor.configurable) {
91
+ jsDescriptor.setProperty(runtime, "configurable", jsi::Value(true));
92
+ }
93
+ if (descriptor.enumerable) {
94
+ jsDescriptor.setProperty(runtime, "enumerable", jsi::Value(true));
95
+ }
96
+ if (descriptor.writable) {
97
+ jsDescriptor.setProperty(runtime, "writable", jsi::Value(true));
98
+ }
99
+
100
+ if (descriptor.get) {
101
+ jsi::PropNameID getPropName = jsi::PropNameID::forAscii(runtime, "get", 3);
102
+ jsi::Function get = jsi::Function::createFromHostFunction(
103
+ runtime,
104
+ getPropName,
105
+ 0,
106
+ [getter = descriptor.get](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
107
+ return getter(runtime, thisValue.asObject(runtime));
108
+ });
109
+
110
+ jsDescriptor.setProperty(runtime, getPropName, get);
111
+ }
112
+ if (descriptor.set) {
113
+ jsi::PropNameID setPropName = jsi::PropNameID::forAscii(runtime, "set", 3);
114
+ jsi::Function set = jsi::Function::createFromHostFunction(
115
+ runtime,
116
+ setPropName,
117
+ 1,
118
+ [setter = descriptor.set](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
119
+ setter(runtime, thisValue.asObject(runtime), jsi::Value(runtime, args[0]));
120
+ return jsi::Value::undefined();
121
+ });
122
+
123
+ jsDescriptor.setProperty(runtime, setPropName, set);
124
+ }
125
+ if (!descriptor.value.isUndefined()) {
126
+ jsi::PropNameID valuePropName = jsi::PropNameID::forAscii(runtime, "value", 5);
127
+ jsDescriptor.setProperty(runtime, valuePropName, descriptor.value);
128
+ }
129
+
130
+ defineProperty(runtime, object, name, std::move(jsDescriptor));
131
+ }
132
+
133
+ void defineProperty(jsi::Runtime &runtime, jsi::Object *object, const char *name, jsi::Object descriptor) {
26
134
  jsi::Object global = runtime.global();
27
135
  jsi::Object objectClass = global.getPropertyAsObject(runtime, "Object");
28
- jsi::Function definePropertyFunction = objectClass.getPropertyAsFunction(
29
- runtime,
30
- "defineProperty"
31
- );
136
+ jsi::Function definePropertyFunction = objectClass.getPropertyAsFunction(runtime, "defineProperty");
32
137
 
33
138
  // This call is basically the same as `Object.defineProperty(object, name, descriptor)` in JS
34
139
  definePropertyFunction.callWithThis(runtime, objectClass, {
35
- jsi::Value(runtime, *jsthis),
140
+ jsi::Value(runtime, *object),
36
141
  jsi::String::createFromUtf8(runtime, name),
37
142
  std::move(descriptor),
38
143
  });
@@ -9,20 +9,67 @@ namespace jsi = facebook::jsi;
9
9
 
10
10
  namespace expo::common {
11
11
 
12
+ #pragma mark - Helpers
13
+
14
+ /**
15
+ Gets the core Expo object, i.e. `global.expo`.
16
+ */
17
+ inline jsi::Object getCoreObject(jsi::Runtime &runtime) {
18
+ return runtime.global().getPropertyAsObject(runtime, "expo");
19
+ }
20
+
21
+ #pragma mark - Classes
22
+
23
+ /**
24
+ Type of the native constructor of the JS classes.
25
+ */
26
+ typedef std::function<jsi::Value(jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count)> ClassConstructor;
27
+
28
+ /**
29
+ Creates a class with the given name and native constructor.
30
+ */
31
+ jsi::Function createClass(jsi::Runtime &runtime, const char *name, ClassConstructor constructor = nullptr);
32
+
33
+ /**
34
+ Creates a class (function) that inherits from the provided base class.
35
+ */
36
+ jsi::Function createInheritingClass(jsi::Runtime &runtime, const char *className, jsi::Function &baseClass, ClassConstructor constructor = nullptr);
37
+
38
+ /**
39
+ Creates an object from the given prototype, without calling the constructor.
40
+ */
41
+ jsi::Object createObjectWithPrototype(jsi::Runtime &runtime, jsi::Object *prototype);
42
+
43
+ #pragma mark - Conversions
44
+
12
45
  /**
13
46
  Converts `jsi::Array` to a vector with prop name ids (`std::vector<jsi::PropNameID>`).
14
47
  */
15
48
  std::vector<jsi::PropNameID> jsiArrayToPropNameIdsVector(jsi::Runtime &runtime, const jsi::Array &array);
16
49
 
50
+ #pragma mark - Properties
51
+
52
+ /**
53
+ Represents a JS property descriptor used in the `Object.defineProperty` function.
54
+ */
55
+ struct PropertyDescriptor {
56
+ const bool configurable = false;
57
+ const bool enumerable = false;
58
+ const bool writable = false;
59
+ const jsi::Value value = jsi::Value::undefined();
60
+ const std::function<jsi::Value(jsi::Runtime &runtime, jsi::Object thisObject)> get = 0;
61
+ const std::function<void(jsi::Runtime &runtime, jsi::Object thisObject, jsi::Value newValue)> set = 0;
62
+ }; // PropertyDescriptor
63
+
64
+ /**
65
+ Defines the property on the object with the provided descriptor options.
66
+ */
67
+ void defineProperty(jsi::Runtime &runtime, jsi::Object *object, const char *name, const PropertyDescriptor descriptor);
68
+
17
69
  /**
18
- Calls Object.defineProperty(jsThis, name, descriptor)`.
70
+ Calls `Object.defineProperty(object, name, descriptor)`.
19
71
  */
20
- void definePropertyOnJSIObject(
21
- jsi::Runtime &runtime,
22
- jsi::Object *jsthis,
23
- const char *name,
24
- jsi::Object descriptor
25
- );
72
+ void defineProperty(jsi::Runtime &runtime, jsi::Object *object, const char *name, jsi::Object descriptor);
26
73
 
27
74
  } // namespace expo::common
28
75
 
@@ -17,14 +17,14 @@ jsi::Value LazyObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
17
17
  // React Native asks for this property for some reason, we can just ignore it.
18
18
  return jsi::Value::undefined();
19
19
  }
20
- backedObject = initializer(runtime);
20
+ initializeBackedObject(runtime);
21
21
  }
22
22
  return backedObject ? backedObject->getProperty(runtime, name) : jsi::Value::undefined();
23
23
  }
24
24
 
25
25
  void LazyObject::set(jsi::Runtime &runtime, const jsi::PropNameID &name, const jsi::Value &value) {
26
26
  if (!backedObject) {
27
- backedObject = initializer(runtime);
27
+ initializeBackedObject(runtime);
28
28
  }
29
29
  if (backedObject) {
30
30
  backedObject->setProperty(runtime, name, value);
@@ -33,7 +33,7 @@ void LazyObject::set(jsi::Runtime &runtime, const jsi::PropNameID &name, const j
33
33
 
34
34
  std::vector<jsi::PropNameID> LazyObject::getPropertyNames(jsi::Runtime &runtime) {
35
35
  if (!backedObject) {
36
- backedObject = initializer(runtime);
36
+ initializeBackedObject(runtime);
37
37
  }
38
38
  if (backedObject) {
39
39
  jsi::Array propertyNames = backedObject->getPropertyNames(runtime);
@@ -42,4 +42,16 @@ std::vector<jsi::PropNameID> LazyObject::getPropertyNames(jsi::Runtime &runtime)
42
42
  return {};
43
43
  }
44
44
 
45
+ const jsi::Object &LazyObject::unwrapObjectIfNecessary(jsi::Runtime &runtime, const jsi::Object &object) {
46
+ if (object.isHostObject<LazyObject>(runtime)) {
47
+ LazyObject::Shared lazyObject = object.getHostObject<LazyObject>(runtime);
48
+
49
+ if (!lazyObject->backedObject) {
50
+ lazyObject->initializeBackedObject(runtime);
51
+ }
52
+ return *lazyObject->backedObject;
53
+ }
54
+ return object;
55
+ }
56
+
45
57
  } // namespace expo