expo-modules-core 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/android/build.gradle +26 -19
  3. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +19 -2
  4. package/android/src/main/cpp/JSIInteropModuleRegistry.h +11 -1
  5. package/android/src/main/cpp/JavaScriptModuleObject.cpp +14 -13
  6. package/android/src/main/cpp/JavaScriptModuleObject.h +4 -1
  7. package/android/src/main/cpp/JavaScriptObject.cpp +12 -27
  8. package/android/src/main/cpp/JavaScriptObject.h +2 -8
  9. package/android/src/main/cpp/JavaScriptRuntime.cpp +44 -17
  10. package/android/src/main/cpp/JavaScriptRuntime.h +9 -16
  11. package/android/src/main/cpp/MethodMetadata.cpp +12 -13
  12. package/android/src/main/cpp/types/FrontendConverter.cpp +20 -3
  13. package/android/src/main/cpp/types/JNIToJSIConverter.cpp +7 -8
  14. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +1 -14
  15. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +1 -11
  16. package/android/src/main/java/expo/modules/adapters/react/views/ViewManagerAdapterUtils.java +0 -54
  17. package/android/src/main/java/expo/modules/core/ModuleRegistry.java +0 -16
  18. package/android/src/main/java/expo/modules/core/ViewManager.java +3 -130
  19. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +21 -3
  20. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +3 -2
  21. package/android/src/main/java/expo/modules/kotlin/Promise.kt +5 -1
  22. package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +1 -2
  23. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +18 -1
  24. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +12 -1
  25. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +1 -0
  26. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +1 -13
  27. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +106 -13
  28. package/android/src/main/java/expo/modules/kotlin/functions/FunctionBuilder.kt +103 -0
  29. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +2 -1
  30. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +10 -2
  31. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +32 -1
  32. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +43 -20
  33. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +11 -7
  34. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +35 -3
  35. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +12 -2
  36. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +11 -3
  37. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +0 -1
  38. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +0 -2
  39. package/android/src/main/java/expo/modules/kotlin/types/ReadableArgumentsTypeConverter.kt +24 -0
  40. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +3 -2
  41. package/android/src/main/java/expo/modules/kotlin/viewevent/ViewEventDelegate.kt +0 -2
  42. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +2 -1
  43. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -2
  44. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +1 -2
  45. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +3 -4
  46. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerType.kt +5 -0
  47. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +1 -1
  48. package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +3 -3
  49. package/android/src/reactnative/expo/modules/kotlin/ReactNativeCompatibleHelper.kt +12 -0
  50. package/android/src/reactnative72/expo/modules/kotlin/ReactNativeCompatibleHelper.kt +12 -0
  51. package/android-annotation/build.gradle +6 -3
  52. package/android-annotation-processor/build.gradle +6 -3
  53. package/build/errors/UnavailabilityError.d.ts.map +1 -1
  54. package/build/errors/UnavailabilityError.js +1 -1
  55. package/build/errors/UnavailabilityError.js.map +1 -1
  56. package/build/sweet/setUpErrorManager.fx.js +5 -1
  57. package/build/sweet/setUpErrorManager.fx.js.map +1 -1
  58. package/build/uuid/v4.js +2 -7
  59. package/build/uuid/v4.js.map +1 -1
  60. package/common/cpp/JSIUtils.cpp +23 -2
  61. package/common/cpp/JSIUtils.h +12 -2
  62. package/common/cpp/LazyObject.cpp +1 -1
  63. package/common/cpp/ObjectDeallocator.cpp +21 -0
  64. package/common/cpp/ObjectDeallocator.h +37 -0
  65. package/ios/JSI/EXJSIUtils.h +1 -12
  66. package/ios/JSI/EXJSIUtils.mm +5 -27
  67. package/ios/JSI/EXJavaScriptObject.mm +8 -21
  68. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +7 -7
  69. package/ios/Swift/Views/ViewModuleWrapper.swift +3 -1
  70. package/package.json +2 -2
  71. package/src/errors/UnavailabilityError.ts +1 -1
  72. package/src/sweet/setUpErrorManager.fx.ts +6 -1
  73. package/src/uuid/v4.ts +2 -6
  74. package/tsconfig.json +1 -1
  75. package/android/src/main/cpp/ObjectDeallocator.h +0 -25
  76. package/android/src/main/java/expo/modules/adapters/react/views/SimpleViewManagerAdapter.java +0 -62
  77. package/android/src/main/java/expo/modules/adapters/react/views/ViewGroupManagerAdapter.java +0 -62
  78. package/ios/JSI/EXObjectDeallocator.h +0 -27
@@ -12,8 +12,6 @@ import java.util.Objects;
12
12
  import androidx.annotation.Nullable;
13
13
 
14
14
  import expo.modules.BuildConfig;
15
- import expo.modules.adapters.react.views.SimpleViewManagerAdapter;
16
- import expo.modules.adapters.react.views.ViewGroupManagerAdapter;
17
15
  import expo.modules.core.ModuleRegistry;
18
16
  import expo.modules.core.interfaces.Consumer;
19
17
  import expo.modules.core.interfaces.InternalModule;
@@ -105,17 +103,6 @@ public class ModuleRegistryAdapter implements ReactPackage {
105
103
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
106
104
  List<ViewManager> viewManagerList = new ArrayList<>(mModuleRegistryProvider.getReactViewManagers(reactContext));
107
105
 
108
- for (expo.modules.core.ViewManager viewManager : mModuleRegistryProvider.getViewManagers(reactContext)) {
109
- switch (viewManager.getViewManagerType()) {
110
- case GROUP:
111
- viewManagerList.add(new ViewGroupManagerAdapter(viewManager));
112
- break;
113
- case SIMPLE:
114
- viewManagerList.add(new SimpleViewManagerAdapter(viewManager));
115
- break;
116
- }
117
- }
118
-
119
106
  NativeModulesProxy modulesProxy = Objects.requireNonNull(getOrCreateNativeModulesProxy(reactContext, null));
120
107
  KotlinInteropModuleRegistry kotlinInteropModuleRegistry = modulesProxy.getKotlinInteropModuleRegistry();
121
108
  List<ViewManager<?, ?>> kViewManager = kotlinInteropModuleRegistry.exportViewManagers();
@@ -135,7 +122,7 @@ public class ModuleRegistryAdapter implements ReactPackage {
135
122
  @Nullable ModuleRegistry moduleRegistry
136
123
  ) {
137
124
  if (mModulesProxy != null && mModulesProxy.getReactContext() != reactContext) {
138
- setModulesProxy(mModulesProxy);
125
+ setModulesProxy(null);
139
126
  }
140
127
  if (mModulesProxy == null) {
141
128
  ModuleRegistry registry = moduleRegistry != null ? moduleRegistry : mModuleRegistryProvider.get(reactContext);
@@ -1,6 +1,5 @@
1
1
  package expo.modules.adapters.react;
2
2
 
3
- import android.util.Log;
4
3
  import android.util.SparseArray;
5
4
 
6
5
  import com.facebook.react.bridge.Dynamic;
@@ -24,7 +23,6 @@ import javax.annotation.Nullable;
24
23
 
25
24
  import expo.modules.core.ExportedModule;
26
25
  import expo.modules.core.ModuleRegistry;
27
- import expo.modules.core.ViewManager;
28
26
  import expo.modules.core.interfaces.ExpoMethod;
29
27
  import expo.modules.kotlin.CoreLoggerKt;
30
28
  import expo.modules.kotlin.ExpoModulesHelper;
@@ -102,11 +100,9 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
102
100
  getKotlinInteropModuleRegistry().installJSIInterop();
103
101
 
104
102
  Collection<ExportedModule> exportedModules = mModuleRegistry.getAllExportedModules();
105
- Collection<ViewManager> viewManagers = mModuleRegistry.getAllViewManagers();
106
103
 
107
104
  Map<String, Object> modulesConstants = new HashMap<>(exportedModules.size());
108
105
  Map<String, Object> exportedMethodsMap = new HashMap<>(exportedModules.size());
109
- Map<String, Object> viewManagersMetadata = new HashMap<>(viewManagers.size());
110
106
 
111
107
  for (ExportedModule exportedModule : exportedModules) {
112
108
  String moduleName = exportedModule.getName();
@@ -124,16 +120,10 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
124
120
  return null;
125
121
  }));
126
122
 
127
- for (ViewManager viewManager : viewManagers) {
128
- viewManagersMetadata.put(viewManager.getName(), viewManager.getMetadata());
129
- }
130
-
131
- viewManagersMetadata.putAll(mKotlinInteropModuleRegistry.viewManagersMetadata());
132
-
133
123
  Map<String, Object> constants = new HashMap<>(3);
134
124
  constants.put(MODULES_CONSTANTS_KEY, modulesConstants);
135
125
  constants.put(EXPORTED_METHODS_KEY, exportedMethodsMap);
136
- constants.put(VIEW_MANAGERS_METADATA_KEY, viewManagersMetadata);
126
+ constants.put(VIEW_MANAGERS_METADATA_KEY, mKotlinInteropModuleRegistry.viewManagersMetadata());
137
127
 
138
128
  CoreLoggerKt.getLogger().info("✅ Constants were exported");
139
129
 
@@ -1,60 +1,6 @@
1
1
  package expo.modules.adapters.react.views;
2
2
 
3
- import android.util.Log;
4
- import android.view.View;
5
-
6
- import com.facebook.react.bridge.Dynamic;
7
- import com.facebook.react.bridge.ReadableMap;
8
- import com.facebook.react.bridge.ReadableMapKeySetIterator;
9
- import com.facebook.react.common.MapBuilder;
10
-
11
- import java.util.HashMap;
12
- import java.util.Map;
13
-
14
- import expo.modules.adapters.react.ArgumentsHelper;
15
- import expo.modules.core.ViewManager;
16
-
17
3
  public class ViewManagerAdapterUtils {
18
- /* package */ static String getViewManagerAdapterName(ViewManager viewManager) {
19
- return "ViewManagerAdapter_" + viewManager.getName();
20
- }
21
-
22
- /* package */ static Map<String, Object> getConstants(ViewManager viewManager) {
23
- Map<String, Object> constants = new HashMap<>();
24
- constants.put("eventNames", viewManager.getExportedEventNames());
25
- return constants;
26
- }
27
-
28
- /* package */ static Map<String, Object> getExportedCustomDirectEventTypeConstants(ViewManager viewManager) {
29
- MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
30
- // Somehow Java compiler thinks getExportedEventNames() returns list of Objects.
31
- // ¯\_(ツ)_/¯
32
- for (Object eventName : viewManager.getExportedEventNames()) {
33
- if (eventName instanceof String) {
34
- builder.put(normalizeEventName((String) eventName), MapBuilder.of("registrationName", eventName));
35
- }
36
- }
37
- return builder.build();
38
- }
39
-
40
- /* package */ static <V extends View> void setProxiedProperties(String viewManagerAdapterName, ViewManager<V> viewManager, V view, ReadableMap proxiedProperties) {
41
- ReadableMapKeySetIterator keyIterator = proxiedProperties.keySetIterator();
42
- while (keyIterator.hasNextKey()) {
43
- String key = keyIterator.nextKey();
44
- try {
45
- ViewManager.PropSetterInfo propSetterInfo = viewManager.getPropSetterInfos().get(key);
46
- if (propSetterInfo == null) {
47
- throw new IllegalArgumentException("No setter found for prop " + key + " in " + viewManagerAdapterName);
48
- }
49
- Dynamic dynamicPropertyValue = proxiedProperties.getDynamic(key);
50
- Object castPropertyValue = ArgumentsHelper.getNativeArgumentForExpectedClass(dynamicPropertyValue, propSetterInfo.getExpectedValueClass());
51
- viewManager.updateProp(view, key, castPropertyValue);
52
- } catch (Exception e) {
53
- Log.e(viewManagerAdapterName, "Error when setting prop " + key + ". " + e.getMessage());
54
- }
55
- }
56
- }
57
-
58
4
  public static String normalizeEventName(final String eventName) {
59
5
  if (eventName.startsWith("on")) {
60
6
  return "top" + eventName.substring(2);
@@ -13,7 +13,6 @@ import java.util.Map;
13
13
 
14
14
  public class ModuleRegistry {
15
15
  private final Map<Class, InternalModule> mInternalModulesMap = new HashMap<>();
16
- private final Map<String, ViewManager> mViewManagersMap = new HashMap<>();
17
16
  private final Map<String, ExportedModule> mExportedModulesMap = new HashMap<>();
18
17
  private final Map<Class, ExportedModule> mExportedModulesByClassMap = new HashMap<>();
19
18
  private final Map<String, SingletonModule> mSingletonModulesMap = new HashMap<>();
@@ -33,10 +32,6 @@ public class ModuleRegistry {
33
32
  registerExportedModule(module);
34
33
  }
35
34
 
36
- for (ViewManager manager : viewManagers) {
37
- registerViewManager(manager);
38
- }
39
-
40
35
  for (SingletonModule singleton : singletonModules) {
41
36
  registerSingletonModule(singleton);
42
37
  }
@@ -61,10 +56,6 @@ public class ModuleRegistry {
61
56
  return mExportedModulesByClassMap.get(moduleClass);
62
57
  }
63
58
 
64
- public Collection<ViewManager> getAllViewManagers() {
65
- return mViewManagersMap.values();
66
- }
67
-
68
59
  public Collection<ExportedModule> getAllExportedModules() {
69
60
  return mExportedModulesMap.values();
70
61
  }
@@ -95,11 +86,6 @@ public class ModuleRegistry {
95
86
  mExportedModulesByClassMap.put(module.getClass(), module);
96
87
  }
97
88
 
98
- public void registerViewManager(ViewManager manager) {
99
- String managerName = manager.getName();
100
- mViewManagersMap.put(managerName, manager);
101
- }
102
-
103
89
  public void registerSingletonModule(SingletonModule singleton) {
104
90
  String singletonName = singleton.getName();
105
91
  mSingletonModulesMap.put(singletonName, singleton);
@@ -137,7 +123,6 @@ public class ModuleRegistry {
137
123
  List<RegistryLifecycleListener> lifecycleListeners = new ArrayList<>();
138
124
  lifecycleListeners.addAll(mExportedModulesMap.values());
139
125
  lifecycleListeners.addAll(mInternalModulesMap.values());
140
- lifecycleListeners.addAll(mViewManagersMap.values());
141
126
 
142
127
  for (WeakReference<RegistryLifecycleListener> ref : mExtraRegistryLifecycleListeners) {
143
128
  if (ref.get() != null) {
@@ -154,7 +139,6 @@ public class ModuleRegistry {
154
139
  List<RegistryLifecycleListener> lifecycleListeners = new ArrayList<>();
155
140
  lifecycleListeners.addAll(mExportedModulesMap.values());
156
141
  lifecycleListeners.addAll(mInternalModulesMap.values());
157
- lifecycleListeners.addAll(mViewManagersMap.values());
158
142
 
159
143
  for (WeakReference<RegistryLifecycleListener> ref : mExtraRegistryLifecycleListeners) {
160
144
  if (ref.get() != null) {
@@ -1,136 +1,9 @@
1
1
  package expo.modules.core;
2
2
 
3
- import android.content.Context;
4
3
  import android.view.View;
5
4
 
6
- import java.lang.reflect.InvocationTargetException;
7
- import java.lang.reflect.Method;
8
- import java.util.Collections;
9
- import java.util.HashMap;
10
- import java.util.List;
11
- import java.util.Map;
12
-
13
5
  import expo.modules.core.interfaces.RegistryLifecycleListener;
14
- import expo.modules.core.interfaces.ExpoProp;
15
-
16
- public abstract class ViewManager<V extends View> implements RegistryLifecycleListener {
17
- /**
18
- * A helper class for passing information about prop setter so that
19
- * eg. adapter can infer the expected class of the property value.
20
- */
21
- public class PropSetterInfo {
22
- private Class<?> mExpectedPropertyClass;
23
- PropSetterInfo(Class<?>[] parameterTypes) {
24
- mExpectedPropertyClass = parameterTypes[parameterTypes.length - 1];
25
- }
26
-
27
- public Class<?> getExpectedValueClass() {
28
- return mExpectedPropertyClass;
29
- }
30
- }
31
-
32
- public enum ViewManagerType {
33
- SIMPLE,
34
- GROUP
35
- }
36
-
37
- private Map<String, PropSetterInfo> mPropSetterInfos;
38
- private Map<String, Method> mPropSetters;
39
-
40
-
41
- public abstract String getName();
42
- public abstract V createViewInstance(Context context);
43
- public abstract ViewManagerType getViewManagerType();
44
-
45
- public List<String> getExportedEventNames() {
46
- return Collections.emptyList();
47
- }
48
-
49
- public void onDropViewInstance(V view) {
50
- // by default do nothing
51
- }
52
-
53
- /**
54
- * Returns a map of view manager's metadata that will be exposed to JavaScript.
55
- */
56
- public Map<String, Object> getMetadata() {
57
- Map<String, Object> metadata = new HashMap<>();
58
- metadata.put("propsNames", getPropSetters().keySet().toArray());
59
- return metadata;
60
- }
61
-
62
- /**
63
- * Returns a map of { propName => propInfo } so that platform adapter knows value of what class
64
- * does the propsetter expect.
65
- */
66
- public Map<String, PropSetterInfo> getPropSetterInfos() {
67
- if (mPropSetterInfos != null) {
68
- return mPropSetterInfos;
69
- }
70
-
71
- Map<String, PropSetterInfo> propSetterInfos = new HashMap<>();
72
- for (Map.Entry<String, Method> entry : getPropSetters().entrySet()) {
73
- propSetterInfos.put(entry.getKey(), new PropSetterInfo(entry.getValue().getParameterTypes()));
74
- }
75
-
76
- mPropSetterInfos = propSetterInfos;
77
- return mPropSetterInfos;
78
- }
79
-
80
- public void updateProp(V view, String propName, Object propValue) throws RuntimeException {
81
- Method propSetter = getPropSetters().get(propName);
82
- if (propSetter == null) {
83
- throw new IllegalArgumentException("There is no propSetter in " + getName() + " for prop of name " + propName + ".");
84
- }
85
-
86
- // We've validated parameter types length in getPropSetterInfos()
87
- Object transformedPropertyValue = transformArgumentToClass(propValue, getPropSetterInfos().get(propName).getExpectedValueClass());
88
-
89
- try {
90
- propSetter.invoke(this, view, transformedPropertyValue);
91
- } catch (IllegalAccessException | InvocationTargetException e) {
92
- throw new RuntimeException("Exception occurred while updating property " + propName
93
- + " on module " + getName() + ": " + e.getMessage(), e);
94
- }
95
- }
96
-
97
- protected Object transformArgumentToClass(Object argument, Class<?> expectedArgumentClass) {
98
- return ArgumentsHelper.validatedArgumentForClass(argument, expectedArgumentClass);
99
- }
100
-
101
- /**
102
- * Creates or returns a cached map of propName => methodSettingThatProp. Validates returned methods.
103
- * @return Map of { propName => methodSettingThatProp }
104
- */
105
- private Map<String, Method> getPropSetters() {
106
- if (mPropSetters != null) {
107
- return mPropSetters;
108
- }
109
-
110
- mPropSetters = new HashMap<>();
111
- Method[] declaredMethodsArray = getClass().getDeclaredMethods();
112
-
113
- for (Method method : declaredMethodsArray) {
114
- if (method.getAnnotation(ExpoProp.class) != null) {
115
- ExpoProp propAnnotation = method.getAnnotation(ExpoProp.class);
116
- String propName = propAnnotation.name();
117
- Class<?>[] methodParameterTypes = method.getParameterTypes();
118
- if (methodParameterTypes.length != 2) {
119
- throw new IllegalArgumentException(
120
- "Expo prop setter should define at least two arguments: view and prop value. Propsetter for " + propName + " of module " + getName() + " does not define these arguments."
121
- );
122
- }
123
-
124
- if (mPropSetters.containsKey(propName)) {
125
- throw new IllegalArgumentException(
126
- "View manager " + getName() + " prop setter name already registered: " + propName + "."
127
- );
128
- }
129
-
130
- mPropSetters.put(propName, method);
131
- }
132
- }
133
6
 
134
- return mPropSetters;
135
- }
136
- }
7
+ @Deprecated
8
+ // TODO(@lukmccall): Remove in the SDK 51. We leave it for now because that class was used in the unimodules package interface.
9
+ public abstract class ViewManager<V extends View> implements RegistryLifecycleListener { }
@@ -9,8 +9,9 @@ import android.view.View
9
9
  import androidx.annotation.UiThread
10
10
  import androidx.appcompat.app.AppCompatActivity
11
11
  import com.facebook.react.bridge.ReactApplicationContext
12
- import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
13
12
  import com.facebook.react.uimanager.UIManagerHelper
13
+ import com.facebook.react.uimanager.UIManagerModule
14
+ import com.facebook.react.uimanager.common.UIManagerType
14
15
  import expo.modules.adapters.react.NativeModulesProxy
15
16
  import expo.modules.core.errors.ContextDestroyedException
16
17
  import expo.modules.core.errors.ModuleNotFoundException
@@ -36,6 +37,7 @@ import expo.modules.kotlin.events.EventName
36
37
  import expo.modules.kotlin.events.KEventEmitterWrapper
37
38
  import expo.modules.kotlin.events.KModuleEventEmitterWrapper
38
39
  import expo.modules.kotlin.events.OnActivityResultPayload
40
+ import expo.modules.kotlin.exception.Exceptions
39
41
  import expo.modules.kotlin.jni.JNIDeallocator
40
42
  import expo.modules.kotlin.jni.JSIInteropModuleRegistry
41
43
  import expo.modules.kotlin.modules.Module
@@ -148,7 +150,7 @@ class AppContext(
148
150
  it,
149
151
  jniDeallocator,
150
152
  jsContextProvider.jsCallInvokerHolder,
151
- catalystInstance.nativeCallInvokerHolder as CallInvokerHolderImpl
153
+ ReactNativeCompatibleHelper.getNativeMethodCallInvokerHolderImplCompatible(catalystInstance)
152
154
  )
153
155
  logger.info("✅ JSI interop was installed")
154
156
  }
@@ -283,7 +285,7 @@ class AppContext(
283
285
  return KEventEmitterWrapper(legacyEventEmitter, reactContextHolder)
284
286
  }
285
287
 
286
- internal val errorManager: ErrorManagerModule?
288
+ val errorManager: ErrorManagerModule?
287
289
  get() = registry.getModule()
288
290
 
289
291
  internal fun onDestroy() = trace("AppContext.onDestroy") {
@@ -350,6 +352,22 @@ class AppContext(
350
352
  return UIManagerHelper.getUIManagerForReactTag(reactContext, viewTag)?.resolveView(viewTag) as? T
351
353
  }
352
354
 
355
+ internal fun dispatchOnMainUsingUIManager(block: () -> Unit) {
356
+ val reactContext = reactContextHolder.get() ?: throw Exceptions.ReactContextLost()
357
+ val uiManager = UIManagerHelper.getUIManagerForReactTag(
358
+ reactContext,
359
+ UIManagerType.DEFAULT
360
+ ) as UIManagerModule
361
+
362
+ uiManager.addUIBlock {
363
+ block()
364
+ }
365
+ }
366
+
367
+ internal fun assertMainThread() {
368
+ Utils.assertMainThread()
369
+ }
370
+
353
371
  /**
354
372
  * Runs a code block on the JavaScript thread.
355
373
  */
@@ -4,6 +4,7 @@ import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.bridge.ReadableArray
5
5
  import com.facebook.react.uimanager.ViewManager
6
6
  import expo.modules.adapters.react.NativeModulesProxy
7
+ import expo.modules.kotlin.views.ViewManagerType
7
8
  import expo.modules.kotlin.defaultmodules.NativeModulesProxyModuleName
8
9
  import expo.modules.kotlin.exception.CodedException
9
10
  import expo.modules.kotlin.exception.UnexpectedException
@@ -77,8 +78,8 @@ class KotlinInteropModuleRegistry(
77
78
  .map {
78
79
  val wrapperDelegate = ViewManagerWrapperDelegate(it)
79
80
  when (it.definition.viewManagerDefinition!!.getViewManagerType()) {
80
- expo.modules.core.ViewManager.ViewManagerType.SIMPLE -> SimpleViewManagerWrapper(wrapperDelegate)
81
- expo.modules.core.ViewManager.ViewManagerType.GROUP -> GroupViewManagerWrapper(wrapperDelegate)
81
+ ViewManagerType.SIMPLE -> SimpleViewManagerWrapper(wrapperDelegate)
82
+ ViewManagerType.GROUP -> GroupViewManagerWrapper(wrapperDelegate)
82
83
  }
83
84
  }
84
85
  }
@@ -9,6 +9,10 @@ private const val unknownCode = "UnknownCode"
9
9
  interface Promise {
10
10
  fun resolve(value: Any?)
11
11
 
12
+ fun resolve() {
13
+ resolve(null)
14
+ }
15
+
12
16
  fun reject(code: String, message: String?, cause: Throwable?)
13
17
 
14
18
  fun reject(exception: CodedException) {
@@ -18,7 +22,7 @@ interface Promise {
18
22
 
19
23
  fun Promise.toBridgePromise(): com.facebook.react.bridge.Promise {
20
24
  val expoPromise = this
21
- val resolveMethod = if (expoPromise is PromiseImpl) {
25
+ val resolveMethod: (value: Any?) -> Unit = if (expoPromise is PromiseImpl) {
22
26
  expoPromise.resolveBlock::invoke
23
27
  } else {
24
28
  expoPromise::resolve
@@ -1,5 +1,3 @@
1
- @file:OptIn(DelicateCoroutinesApi::class)
2
-
3
1
  package expo.modules.kotlin.activityresult
4
2
 
5
3
  import android.app.Activity
@@ -22,6 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger
22
20
  * Manager class that takes care of proper communication with [AppContextActivityResultRegistry]
23
21
  * It also monitors the needed lifecycle state using [AppCompatActivityAwareHelper]
24
22
  */
23
+ @OptIn(DelicateCoroutinesApi::class)
25
24
  class ActivityResultsManager(
26
25
  currentActivityProvider: CurrentActivityProvider
27
26
  ) : AppContextActivityResultCaller, AppCompatActivityAware {
@@ -4,6 +4,7 @@ package expo.modules.kotlin.classcomponent
4
4
 
5
5
  import expo.modules.kotlin.functions.SyncFunctionComponent
6
6
  import expo.modules.kotlin.objects.ObjectDefinitionBuilder
7
+ import expo.modules.kotlin.objects.PropertyComponentBuilderWithThis
7
8
  import expo.modules.kotlin.types.toAnyType
8
9
  import kotlin.reflect.KClass
9
10
  import kotlin.reflect.KType
@@ -12,7 +13,7 @@ import kotlin.reflect.typeOf
12
13
  class ClassComponentBuilder<SharedObjectType : Any>(
13
14
  val name: String,
14
15
  private val ownerClass: KClass<SharedObjectType>,
15
- private val ownerType: KType
16
+ val ownerType: KType
16
17
  ) : ObjectDefinitionBuilder() {
17
18
  var constructor: SyncFunctionComponent? = null
18
19
 
@@ -109,4 +110,20 @@ class ClassComponentBuilder<SharedObjectType : Any>(
109
110
  constructor = it
110
111
  }
111
112
  }
113
+
114
+ /**
115
+ * Creates the read-only property whose getter takes the caller as an argument.
116
+ */
117
+ inline fun <T> Property(name: String, crossinline body: (owner: SharedObjectType) -> T): PropertyComponentBuilderWithThis<SharedObjectType> {
118
+ return PropertyComponentBuilderWithThis<SharedObjectType>(ownerType, name).also {
119
+ it.get(body)
120
+ properties[name] = it
121
+ }
122
+ }
123
+
124
+ override fun Property(name: String): PropertyComponentBuilderWithThis<SharedObjectType> {
125
+ return PropertyComponentBuilderWithThis<SharedObjectType>(ownerType, name).also {
126
+ properties[name] = it
127
+ }
128
+ }
112
129
  }
@@ -6,11 +6,12 @@ import expo.modules.kotlin.modules.Module
6
6
  import expo.modules.kotlin.modules.ModuleDefinition
7
7
 
8
8
  private const val onNewException = "ExpoModulesCoreErrorManager.onNewException"
9
+ private const val onNewWarning = "ExpoModulesCoreErrorManager.onNewWarning"
9
10
 
10
11
  class ErrorManagerModule : Module() {
11
12
  override fun definition() = ModuleDefinition {
12
13
  Name("ExpoModulesCoreErrorManager")
13
- Events(onNewException)
14
+ Events(onNewException, onNewWarning)
14
15
  }
15
16
 
16
17
  fun reportExceptionToLogBox(codedException: CodedException) {
@@ -22,4 +23,14 @@ class ErrorManagerModule : Module() {
22
23
  }
23
24
  )
24
25
  }
26
+
27
+ fun reportWarningToLogBox(warning: String) {
28
+ val eventEmitter = appContext.eventEmitter(this) ?: return
29
+ eventEmitter.emit(
30
+ onNewWarning,
31
+ Bundle().apply {
32
+ putString("message", warning)
33
+ }
34
+ )
35
+ }
25
36
  }
@@ -24,6 +24,7 @@ abstract class AnyFunction(
24
24
  ) {
25
25
  internal val argsCount get() = desiredArgsTypes.size
26
26
 
27
+ @PublishedApi
27
28
  internal var canTakeOwner: Boolean = false
28
29
 
29
30
  @PublishedApi
@@ -1,16 +1,11 @@
1
1
  package expo.modules.kotlin.functions
2
2
 
3
- import com.facebook.react.bridge.ReactContext
4
3
  import com.facebook.react.bridge.ReadableArray
5
- import com.facebook.react.uimanager.UIManagerHelper
6
- import com.facebook.react.uimanager.UIManagerModule
7
- import com.facebook.react.uimanager.common.UIManagerType
8
4
  import expo.modules.BuildConfig
9
5
  import expo.modules.kotlin.AppContext
10
6
  import expo.modules.kotlin.ModuleHolder
11
7
  import expo.modules.kotlin.Promise
12
8
  import expo.modules.kotlin.exception.CodedException
13
- import expo.modules.kotlin.exception.Exceptions
14
9
  import expo.modules.kotlin.exception.FunctionCallException
15
10
  import expo.modules.kotlin.exception.UnexpectedException
16
11
  import expo.modules.kotlin.exception.exceptionDecorator
@@ -98,14 +93,7 @@ abstract class AsyncFunction(
98
93
  // but the JavaScript code has already received the future tag of the view.
99
94
  // To avoid this issue, we have decided to temporarily utilize
100
95
  // the UIManagerModule for dispatching functions on the main thread.
101
- val uiManager = UIManagerHelper.getUIManagerForReactTag(
102
- appContext.reactContext as? ReactContext ?: throw Exceptions.ReactContextLost(),
103
- UIManagerType.DEFAULT
104
- ) as UIManagerModule
105
-
106
- uiManager.addUIBlock {
107
- functionBody()
108
- }
96
+ appContext.dispatchOnMainUsingUIManager(functionBody)
109
97
  return@registerAsyncFunction
110
98
  }
111
99