expo-modules-core 0.11.6 → 0.11.8
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.
- package/CHANGELOG.md +15 -0
- package/android/build.gradle +2 -2
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +7 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +1 -1
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +12 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +2 -0
- package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +24 -8
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +12 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +24 -17
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +1 -0
- package/ios/AppDelegates/EXLegacyAppDelegateWrapper.m +14 -6
- package/ios/AppDelegates/ExpoAppDelegate.swift +24 -8
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,21 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.11.8 — 2022-10-13
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fixed `Updates.reloadAsync` from `expo-updates` occasionally crashes the app. ([#19539](https://github.com/expo/expo/pull/19539) by [@kudo](https://github.com/kudo), [@kudo](https://github.com/kudo))
|
|
18
|
+
- Fixed `JSCRuntime destroyed with a dangling API object` on Android. ([#19487](https://github.com/expo/expo/pull/19487) by [@lukmccall](https://github.com/lukmccall))
|
|
19
|
+
|
|
20
|
+
## 0.11.7 — 2022-10-06
|
|
21
|
+
|
|
22
|
+
### 🐛 Bug fixes
|
|
23
|
+
|
|
24
|
+
- Fixed `ModuleRegistry` be initialized twice when startup on Android. ([#19384](https://github.com/expo/expo/pull/19384) by [@kudo](https://github.com/kudo) and [@lukmccall](https://github.com/lukmccall))
|
|
25
|
+
- Ensure that AppDelegate callbacks are invoked. ([#19393](https://github.com/expo/expo/pull/19393) by [@ferologics](https://github.com/ferologics))
|
|
26
|
+
- Fixed Android crash when Activity is destroyed before `AppContext.onHostDestroy` call. ([#19406](https://github.com/expo/expo/pull/19406) by [@kudo](https://github.com/kudo))
|
|
27
|
+
|
|
13
28
|
## 0.11.6 — 2022-10-02
|
|
14
29
|
|
|
15
30
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
|
|
|
6
6
|
apply plugin: "de.undercouch.download"
|
|
7
7
|
|
|
8
8
|
group = 'host.exp.exponent'
|
|
9
|
-
version = '0.11.
|
|
9
|
+
version = '0.11.8'
|
|
10
10
|
|
|
11
11
|
buildscript {
|
|
12
12
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -161,7 +161,7 @@ android {
|
|
|
161
161
|
targetSdkVersion safeExtGet("targetSdkVersion", 31)
|
|
162
162
|
consumerProguardFiles 'proguard-rules.pro'
|
|
163
163
|
versionCode 1
|
|
164
|
-
versionName "0.11.
|
|
164
|
+
versionName "0.11.8"
|
|
165
165
|
|
|
166
166
|
testInstrumentationRunner "expo.modules.TestRunner"
|
|
167
167
|
|
|
@@ -12,6 +12,13 @@ namespace expo {
|
|
|
12
12
|
ExpoModulesHostObject::ExpoModulesHostObject(JSIInteropModuleRegistry *installer)
|
|
13
13
|
: installer(installer) {}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Clears jsi references held by JSRegistry and JavaScriptRuntime.
|
|
17
|
+
*/
|
|
18
|
+
ExpoModulesHostObject::~ExpoModulesHostObject() {
|
|
19
|
+
installer->runtimeHolder.reset();
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
|
|
16
23
|
auto cName = name.utf8(runtime);
|
|
17
24
|
auto module = installer->getModule(cName);
|
|
@@ -20,6 +20,8 @@ class ExpoModulesHostObject : public jsi::HostObject {
|
|
|
20
20
|
public:
|
|
21
21
|
ExpoModulesHostObject(JSIInteropModuleRegistry *installer);
|
|
22
22
|
|
|
23
|
+
~ExpoModulesHostObject() override;
|
|
24
|
+
|
|
23
25
|
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
|
24
26
|
|
|
25
27
|
void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
|
|
@@ -59,7 +59,7 @@ void JSIInteropModuleRegistry::installJSI(
|
|
|
59
59
|
|
|
60
60
|
void JSIInteropModuleRegistry::installJSIForTests() {
|
|
61
61
|
#if !UNIT_TEST
|
|
62
|
-
throw std::logic_error("The function is only
|
|
62
|
+
throw std::logic_error("The function is only available when UNIT_TEST is defined.");
|
|
63
63
|
#else
|
|
64
64
|
runtimeHolder = std::make_shared<JavaScriptRuntime>();
|
|
65
65
|
jsi::Runtime &jsiRuntime = *runtimeHolder->get();
|
|
@@ -137,6 +137,18 @@ void JavaScriptModuleObject::registerProperty(
|
|
|
137
137
|
JavaScriptModuleObject::HostObject::HostObject(
|
|
138
138
|
JavaScriptModuleObject *jsModule) : jsModule(jsModule) {}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Clears all the JSI references held by the `JavaScriptModuleObject`.
|
|
142
|
+
*/
|
|
143
|
+
JavaScriptModuleObject::HostObject::~HostObject() {
|
|
144
|
+
if (jsModule->jsiObject != nullptr) {
|
|
145
|
+
jsModule->jsiObject.reset();
|
|
146
|
+
}
|
|
147
|
+
jsModule->methodsMetadata.clear();
|
|
148
|
+
jsModule->constants.clear();
|
|
149
|
+
jsModule->properties.clear();
|
|
150
|
+
}
|
|
151
|
+
|
|
140
152
|
jsi::Value JavaScriptModuleObject::HostObject::get(jsi::Runtime &runtime,
|
|
141
153
|
const jsi::PropNameID &name) {
|
|
142
154
|
auto cName = name.utf8(runtime);
|
|
@@ -103,6 +103,8 @@ public:
|
|
|
103
103
|
public:
|
|
104
104
|
HostObject(JavaScriptModuleObject *);
|
|
105
105
|
|
|
106
|
+
~HostObject() override;
|
|
107
|
+
|
|
106
108
|
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
|
107
109
|
|
|
108
110
|
void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
package expo.modules.adapters.react;
|
|
2
2
|
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
import androidx.annotation.Nullable;
|
|
5
|
+
|
|
3
6
|
import com.facebook.react.ReactPackage;
|
|
4
7
|
import com.facebook.react.bridge.NativeModule;
|
|
5
8
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
@@ -46,7 +49,8 @@ public class ModuleRegistryAdapter implements ReactPackage {
|
|
|
46
49
|
|
|
47
50
|
@Override
|
|
48
51
|
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
49
|
-
|
|
52
|
+
NativeModulesProxy proxy = getOrCreateNativeModulesProxy(reactContext, null);
|
|
53
|
+
ModuleRegistry moduleRegistry = proxy.getModuleRegistry();
|
|
50
54
|
|
|
51
55
|
for (InternalModule internalModule : mReactAdapterPackage.createInternalModules(reactContext)) {
|
|
52
56
|
moduleRegistry.registerInternalModule(internalModule);
|
|
@@ -54,7 +58,7 @@ public class ModuleRegistryAdapter implements ReactPackage {
|
|
|
54
58
|
|
|
55
59
|
List<NativeModule> nativeModules = getNativeModulesFromModuleRegistry(reactContext, moduleRegistry);
|
|
56
60
|
if (mWrapperDelegateHolders != null) {
|
|
57
|
-
KotlinInteropModuleRegistry kotlinInteropModuleRegistry =
|
|
61
|
+
KotlinInteropModuleRegistry kotlinInteropModuleRegistry = proxy.getKotlinInteropModuleRegistry();
|
|
58
62
|
kotlinInteropModuleRegistry.updateModuleHoldersInViewManagers(mWrapperDelegateHolders);
|
|
59
63
|
}
|
|
60
64
|
|
|
@@ -64,7 +68,7 @@ public class ModuleRegistryAdapter implements ReactPackage {
|
|
|
64
68
|
protected List<NativeModule> getNativeModulesFromModuleRegistry(ReactApplicationContext reactContext, ModuleRegistry moduleRegistry) {
|
|
65
69
|
List<NativeModule> nativeModulesList = new ArrayList<>(2);
|
|
66
70
|
|
|
67
|
-
nativeModulesList.add(getOrCreateNativeModulesProxy(reactContext));
|
|
71
|
+
nativeModulesList.add(getOrCreateNativeModulesProxy(reactContext, moduleRegistry));
|
|
68
72
|
|
|
69
73
|
// Add listener that will notify expo.modules.core.ModuleRegistry when all modules are ready
|
|
70
74
|
nativeModulesList.add(new ModuleRegistryReadyNotifier(moduleRegistry));
|
|
@@ -93,7 +97,7 @@ public class ModuleRegistryAdapter implements ReactPackage {
|
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
NativeModulesProxy modulesProxy = Objects.requireNonNull(getOrCreateNativeModulesProxy(reactContext));
|
|
100
|
+
NativeModulesProxy modulesProxy = Objects.requireNonNull(getOrCreateNativeModulesProxy(reactContext, null));
|
|
97
101
|
KotlinInteropModuleRegistry kotlinInteropModuleRegistry = modulesProxy.getKotlinInteropModuleRegistry();
|
|
98
102
|
List<ViewManager<?, ?>> kViewManager = kotlinInteropModuleRegistry.exportViewManagers();
|
|
99
103
|
// Saves all holders that needs to be in sync with module registry
|
|
@@ -103,15 +107,27 @@ public class ModuleRegistryAdapter implements ReactPackage {
|
|
|
103
107
|
return viewManagerList;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
private NativeModulesProxy getOrCreateNativeModulesProxy(
|
|
110
|
+
private synchronized NativeModulesProxy getOrCreateNativeModulesProxy(
|
|
111
|
+
ReactApplicationContext reactContext,
|
|
112
|
+
@Nullable ModuleRegistry moduleRegistry
|
|
113
|
+
) {
|
|
114
|
+
if (mModulesProxy != null && mModulesProxy.getReactContext() != reactContext) {
|
|
115
|
+
mModulesProxy = null;
|
|
116
|
+
mWrapperDelegateHolders = null;
|
|
117
|
+
}
|
|
107
118
|
if (mModulesProxy == null) {
|
|
108
|
-
ModuleRegistry
|
|
119
|
+
ModuleRegistry registry = moduleRegistry != null ? moduleRegistry : mModuleRegistryProvider.get(reactContext);
|
|
109
120
|
if (mModulesProvider != null) {
|
|
110
|
-
mModulesProxy = new NativeModulesProxy(reactContext,
|
|
121
|
+
mModulesProxy = new NativeModulesProxy(reactContext, registry, mModulesProvider);
|
|
111
122
|
} else {
|
|
112
|
-
mModulesProxy = new NativeModulesProxy(reactContext,
|
|
123
|
+
mModulesProxy = new NativeModulesProxy(reactContext, registry);
|
|
113
124
|
}
|
|
114
125
|
}
|
|
126
|
+
|
|
127
|
+
if (moduleRegistry != null && moduleRegistry != mModulesProxy.getModuleRegistry()) {
|
|
128
|
+
Log.e("expo-modules-core", "NativeModuleProxy was configured with a different instance of the modules registry.");
|
|
129
|
+
}
|
|
130
|
+
|
|
115
131
|
return mModulesProxy;
|
|
116
132
|
}
|
|
117
133
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.adapters.react;
|
|
2
2
|
|
|
3
|
+
import android.util.Log;
|
|
3
4
|
import android.util.SparseArray;
|
|
4
5
|
|
|
5
6
|
import com.facebook.react.bridge.Dynamic;
|
|
@@ -127,6 +128,9 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
|
|
|
127
128
|
constants.put(MODULES_CONSTANTS_KEY, modulesConstants);
|
|
128
129
|
constants.put(EXPORTED_METHODS_KEY, exportedMethodsMap);
|
|
129
130
|
constants.put(VIEW_MANAGERS_METADATA_KEY, viewManagersMetadata);
|
|
131
|
+
|
|
132
|
+
Log.i("ExpoModulesCore", "✅ Constants was exported");
|
|
133
|
+
|
|
130
134
|
return constants;
|
|
131
135
|
}
|
|
132
136
|
|
|
@@ -247,4 +251,12 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
|
|
|
247
251
|
mModuleRegistry.onDestroy();
|
|
248
252
|
mKotlinInteropModuleRegistry.onDestroy();
|
|
249
253
|
}
|
|
254
|
+
|
|
255
|
+
ModuleRegistry getModuleRegistry() {
|
|
256
|
+
return mModuleRegistry;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* package */ ReactApplicationContext getReactContext() {
|
|
260
|
+
return getReactApplicationContext();
|
|
261
|
+
}
|
|
250
262
|
}
|
|
@@ -5,12 +5,14 @@ package expo.modules.kotlin
|
|
|
5
5
|
import android.app.Activity
|
|
6
6
|
import android.content.Context
|
|
7
7
|
import android.content.Intent
|
|
8
|
+
import android.util.Log
|
|
8
9
|
import androidx.annotation.MainThread
|
|
9
10
|
import androidx.appcompat.app.AppCompatActivity
|
|
10
11
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
11
12
|
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
|
12
13
|
import expo.modules.core.errors.ContextDestroyedException
|
|
13
14
|
import expo.modules.core.interfaces.ActivityProvider
|
|
15
|
+
import expo.modules.core.interfaces.JavaScriptContextProvider
|
|
14
16
|
import expo.modules.interfaces.barcodescanner.BarCodeScannerInterface
|
|
15
17
|
import expo.modules.interfaces.camera.CameraViewInterface
|
|
16
18
|
import expo.modules.interfaces.constants.ConstantsInterface
|
|
@@ -86,18 +88,25 @@ class AppContext(
|
|
|
86
88
|
* Initializes a JSI part of the module registry.
|
|
87
89
|
* It will be a NOOP if the remote debugging was activated.
|
|
88
90
|
*/
|
|
89
|
-
fun installJSIInterop() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
fun installJSIInterop() = synchronized<Unit>(this) {
|
|
92
|
+
try {
|
|
93
|
+
jsiInterop = JSIInteropModuleRegistry(this)
|
|
94
|
+
val reactContext = reactContextHolder.get() ?: return
|
|
95
|
+
val jsContextHolder = legacyModule<JavaScriptContextProvider>()?.javaScriptContextRef
|
|
96
|
+
val catalystInstance = reactContext.catalystInstance ?: return
|
|
97
|
+
jsContextHolder
|
|
98
|
+
?.takeIf { it != 0L }
|
|
99
|
+
?.let {
|
|
100
|
+
jsiInterop.installJSI(
|
|
101
|
+
it,
|
|
102
|
+
catalystInstance.jsCallInvokerHolder as CallInvokerHolderImpl,
|
|
103
|
+
catalystInstance.nativeCallInvokerHolder as CallInvokerHolderImpl
|
|
104
|
+
)
|
|
105
|
+
Log.i("ExpoModulesCore", "✅ JSI interop was installed")
|
|
106
|
+
}
|
|
107
|
+
} catch (e: Throwable) {
|
|
108
|
+
Log.e("ExpoModulesCore", "Cannot install JSI interop: $e", e)
|
|
109
|
+
}
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
/**
|
|
@@ -223,11 +232,9 @@ class AppContext(
|
|
|
223
232
|
}
|
|
224
233
|
|
|
225
234
|
fun onHostDestroy() {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
)
|
|
235
|
+
currentActivity?.let {
|
|
236
|
+
activityResultsManager.onHostDestroy(it)
|
|
237
|
+
}
|
|
231
238
|
registry.post(EventName.ACTIVITY_DESTROYS)
|
|
232
239
|
}
|
|
233
240
|
|
|
@@ -90,9 +90,13 @@ static dispatch_once_t onceToken;
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
|
|
94
|
+
if (subcontractorsLeft == 0) {
|
|
95
|
+
completionHandler(fetchResult);
|
|
96
|
+
} else {
|
|
97
|
+
for (id<UIApplicationDelegate> subcontractor in subcontractorsArray) {
|
|
98
|
+
[subcontractor application:application performFetchWithCompletionHandler:handler];
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -201,9 +205,13 @@ static dispatch_once_t onceToken;
|
|
|
201
205
|
}
|
|
202
206
|
}
|
|
203
207
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
|
|
209
|
+
if (subcontractorsLeft == 0) {
|
|
210
|
+
completionHandler(fetchResult);
|
|
211
|
+
} else {
|
|
212
|
+
for (id<UIApplicationDelegate> subcontractor in subcontractorsArray) {
|
|
213
|
+
[subcontractor application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:handler];
|
|
214
|
+
}
|
|
207
215
|
}
|
|
208
216
|
}
|
|
209
217
|
|
|
@@ -92,8 +92,12 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
subs.
|
|
96
|
-
|
|
95
|
+
if subs.isEmpty {
|
|
96
|
+
completionHandler()
|
|
97
|
+
} else {
|
|
98
|
+
subs.forEach {
|
|
99
|
+
$0.application?(application, handleEventsForBackgroundURLSession: identifier, completionHandler: handler)
|
|
100
|
+
}
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
|
|
@@ -141,8 +145,12 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
141
145
|
}
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
subs.
|
|
145
|
-
|
|
148
|
+
if subs.isEmpty {
|
|
149
|
+
completionHandler(.noData)
|
|
150
|
+
} else {
|
|
151
|
+
subs.forEach { subscriber in
|
|
152
|
+
subscriber.application?(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: handler)
|
|
153
|
+
}
|
|
146
154
|
}
|
|
147
155
|
}
|
|
148
156
|
|
|
@@ -212,8 +220,12 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
212
220
|
}
|
|
213
221
|
}
|
|
214
222
|
|
|
215
|
-
subs.
|
|
216
|
-
|
|
223
|
+
if subs.isEmpty {
|
|
224
|
+
completionHandler(result)
|
|
225
|
+
} else {
|
|
226
|
+
subs.forEach { subscriber in
|
|
227
|
+
subscriber.application?(application, performActionFor: shortcutItem, completionHandler: handler)
|
|
228
|
+
}
|
|
217
229
|
}
|
|
218
230
|
}
|
|
219
231
|
|
|
@@ -249,8 +261,12 @@ open class ExpoAppDelegate: UIResponder, UIApplicationDelegate {
|
|
|
249
261
|
}
|
|
250
262
|
}
|
|
251
263
|
|
|
252
|
-
subs.
|
|
253
|
-
|
|
264
|
+
if subs.isEmpty {
|
|
265
|
+
completionHandler(.noData)
|
|
266
|
+
} else {
|
|
267
|
+
subs.forEach { subscriber in
|
|
268
|
+
subscriber.application?(application, performFetchWithCompletionHandler: handler)
|
|
269
|
+
}
|
|
254
270
|
}
|
|
255
271
|
}
|
|
256
272
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"@testing-library/react-hooks": "^7.0.1",
|
|
43
43
|
"expo-module-scripts": "^2.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "da2b9d2bb73100781b31906967669fe521d55e8a"
|
|
46
46
|
}
|