expo-modules-core 1.5.11 → 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.
- package/CHANGELOG.md +26 -8
- package/android/CMakeLists.txt +1 -1
- package/android/build.gradle +32 -105
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +33 -2
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +18 -1
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +14 -13
- package/android/src/main/cpp/JavaScriptModuleObject.h +4 -1
- package/android/src/main/cpp/JavaScriptObject.cpp +12 -27
- package/android/src/main/cpp/JavaScriptObject.h +2 -8
- package/android/src/main/cpp/JavaScriptRuntime.cpp +48 -18
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -16
- package/android/src/main/cpp/MethodMetadata.cpp +12 -13
- package/android/src/main/cpp/types/FrontendConverter.cpp +20 -3
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +7 -8
- package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +25 -22
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +1 -11
- package/android/src/main/java/expo/modules/adapters/react/views/ViewManagerAdapterUtils.java +0 -54
- package/android/src/main/java/expo/modules/core/ModuleRegistry.java +0 -16
- package/android/src/main/java/expo/modules/core/ViewManager.java +3 -130
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +35 -4
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/Promise.kt +5 -1
- package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +1 -2
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +18 -1
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/CoreModule.kt +11 -0
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +12 -1
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +1 -5
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +20 -19
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +106 -13
- package/android/src/main/java/expo/modules/kotlin/functions/FunctionBuilder.kt +103 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +19 -6
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +9 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +10 -2
- package/android/src/main/java/expo/modules/kotlin/jni/PromiseImpl.kt +34 -7
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +32 -1
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +43 -20
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +11 -7
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +35 -3
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +12 -2
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +11 -3
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +0 -1
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +0 -2
- package/android/src/main/java/expo/modules/kotlin/types/ReadableArgumentsTypeConverter.kt +24 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/viewevent/ViewEventDelegate.kt +0 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +0 -1
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +3 -4
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerType.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +3 -3
- package/android/src/reactnative/expo/modules/kotlin/ReactNativeCompatibleHelper.kt +12 -0
- package/android/src/reactnative72/expo/modules/kotlin/ReactNativeCompatibleHelper.kt +12 -0
- package/android-annotation/build.gradle +6 -3
- package/android-annotation-processor/build.gradle +6 -3
- package/build/errors/UnavailabilityError.d.ts.map +1 -1
- package/build/errors/UnavailabilityError.js +1 -1
- package/build/errors/UnavailabilityError.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/sweet/setUpErrorManager.fx.js +5 -1
- package/build/sweet/setUpErrorManager.fx.js.map +1 -1
- package/build/uuid/index.d.ts +3 -0
- package/build/uuid/index.d.ts.map +1 -0
- package/build/uuid/index.js +3 -0
- package/build/uuid/index.js.map +1 -0
- package/build/uuid/lib/bytesToUuid.d.ts +3 -0
- package/build/uuid/lib/bytesToUuid.d.ts.map +1 -0
- package/build/uuid/lib/bytesToUuid.js +37 -0
- package/build/uuid/lib/bytesToUuid.js.map +1 -0
- package/build/uuid/lib/rng.d.ts +3 -0
- package/build/uuid/lib/rng.d.ts.map +1 -0
- package/build/uuid/lib/rng.js +35 -0
- package/build/uuid/lib/rng.js.map +1 -0
- package/build/uuid/lib/sha1.d.ts +3 -0
- package/build/uuid/lib/sha1.d.ts.map +1 -0
- package/build/uuid/lib/sha1.js +98 -0
- package/build/uuid/lib/sha1.js.map +1 -0
- package/build/uuid/lib/v35.d.ts +7 -0
- package/build/uuid/lib/v35.d.ts.map +1 -0
- package/build/uuid/lib/v35.js +51 -0
- package/build/uuid/lib/v35.js.map +1 -0
- package/build/uuid/types/uuid.types.d.ts +11 -0
- package/build/uuid/types/uuid.types.d.ts.map +1 -0
- package/build/uuid/types/uuid.types.js +2 -0
- package/build/uuid/types/uuid.types.js.map +1 -0
- package/build/uuid/v4.d.ts +6 -0
- package/build/uuid/v4.d.ts.map +1 -0
- package/build/uuid/v4.js +24 -0
- package/build/uuid/v4.js.map +1 -0
- package/build/uuid/v5.d.ts +11 -0
- package/build/uuid/v5.d.ts.map +1 -0
- package/build/uuid/v5.js +7 -0
- package/build/uuid/v5.js.map +1 -0
- package/common/cpp/JSIUtils.cpp +23 -2
- package/common/cpp/JSIUtils.h +12 -2
- package/common/cpp/LazyObject.cpp +1 -1
- package/common/cpp/ObjectDeallocator.cpp +21 -0
- package/common/cpp/ObjectDeallocator.h +37 -0
- package/ios/AppDelegates/EXLegacyAppDelegateWrapper.m +1 -0
- package/ios/JSI/EXJSIUtils.h +1 -12
- package/ios/JSI/EXJSIUtils.mm +5 -27
- package/ios/JSI/EXJavaScriptObject.mm +8 -21
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.h +1 -1
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -1
- package/ios/ModuleRegistryAdapter/EXModuleRegistryHolderReactModule.h +2 -2
- package/ios/ModuleRegistryAdapter/EXModuleRegistryHolderReactModule.m +4 -4
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.h +2 -1
- package/ios/Services/EXReactFontManager.m +31 -7
- package/ios/Swift/AppContext.swift +6 -0
- package/ios/Swift/ExpoBridgeModule.swift +6 -2
- package/ios/Swift/ModuleRegistry.swift +14 -4
- package/ios/Swift/Views/ViewModuleWrapper.swift +3 -1
- package/package.json +2 -2
- package/src/errors/UnavailabilityError.ts +1 -1
- package/src/index.ts +2 -0
- package/src/sweet/setUpErrorManager.fx.ts +6 -1
- package/src/uuid/index.ts +2 -0
- package/src/uuid/lib/bytesToUuid.ts +38 -0
- package/src/uuid/lib/rng.ts +42 -0
- package/src/uuid/lib/sha1.ts +110 -0
- package/src/uuid/lib/v35.ts +67 -0
- package/src/uuid/types/uuid.types.ts +12 -0
- package/src/uuid/v4.ts +40 -0
- package/src/uuid/v5.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/cpp/ObjectDeallocator.h +0 -25
- package/android/src/main/java/expo/modules/adapters/react/views/SimpleViewManagerAdapter.java +0 -62
- package/android/src/main/java/expo/modules/adapters/react/views/ViewGroupManagerAdapter.java +0 -62
- package/ios/JSI/EXObjectDeallocator.h +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -10,29 +10,47 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
-
## 1.
|
|
13
|
+
## 1.7.0 — 2023-09-04
|
|
14
14
|
|
|
15
|
-
###
|
|
16
|
-
|
|
17
|
-
- [Android] Fixed owner type of view functions. ([#24135](https://github.com/expo/expo/pull/24135) by [@lukmccall](https://github.com/lukmccall))
|
|
15
|
+
### 🎉 New features
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
- [Android] Surfaced errorManager to allow throwing errors and warnings from modules. ([#23848](https://github.com/expo/expo/pull/23848) by [@aleqsio](https://github.com/aleqsio))
|
|
18
|
+
- [Android] Enums can now be used to define events. ([#23875](https://github.com/expo/expo/pull/23875) by [@lukmccall](https://github.com/lukmccall))
|
|
19
|
+
- [Android] Promises can now be resolved without arguments. ([#23907](https://github.com/expo/expo/pull/23907) by [@lukmccall](https://github.com/lukmccall))
|
|
20
|
+
- Added support for React Native 0.73. ([#24018](https://github.com/expo/expo/pull/24018), [#24019](https://github.com/expo/expo/pull/24019) by [@kudo](https://github.com/kudo))
|
|
21
|
+
- [Android] `Property` component can now take the native shared object instance as the first argument. ([#24206](https://github.com/expo/expo/pull/24206) by [@lukmccall](https://github.com/lukmccall))
|
|
20
22
|
|
|
21
23
|
### 🐛 Bug fixes
|
|
22
24
|
|
|
25
|
+
- [Android] Refresh NativeModulesProxy if app bundle is reloaded. ([#23824](https://github.com/expo/expo/pull/23824) by [@douglowder](https://github.com/douglowder))
|
|
26
|
+
- [Android] Fix nullability of parameter type in `List` and `Map` when converting from JS to native. ([#23942](https://github.com/expo/expo/pull/23942) by [@lukmccall](https://github.com/lukmccall))
|
|
23
27
|
- Fixed Fabric setup error on iOS. ([#24004](https://github.com/expo/expo/pull/24004) by [@kudo](https://github.com/kudo))
|
|
28
|
+
- Fixed uuid v4 generation. ([#24123](https://github.com/expo/expo/pull/24123) by [@tsapeta](https://github.com/tsapeta))
|
|
29
|
+
- [Android] Fixed owner type of view functions. ([#24135](https://github.com/expo/expo/pull/24135) by [@lukmccall](https://github.com/lukmccall))
|
|
30
|
+
|
|
31
|
+
### 💡 Others
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
- [Android] Add type converter for the `ReadableArguments` class to allow backward compatibility with older modules. ([#24137](https://github.com/expo/expo/pull/24137) by [@lukmccall](https://github.com/lukmccall))
|
|
34
|
+
- [Android] `SharedObjectTypeConverter` now can work with the `Dynamic` class. ([#24207](https://github.com/expo/expo/pull/24207) by [@lukmccall](https://github.com/lukmccall))
|
|
35
|
+
- [Android] Expose a conversion between id and shared objects. ([#24220](https://github.com/expo/expo/pull/24220) by [@lukmccall](https://github.com/lukmccall))
|
|
36
|
+
|
|
37
|
+
## 1.6.0 — 2023-07-28
|
|
26
38
|
|
|
27
39
|
### 🐛 Bug fixes
|
|
28
40
|
|
|
41
|
+
- [iOS] Fixed custom fonts support on Fabric. ([#23666](https://github.com/expo/expo/pull/23666) by [@aleqsio](https://github.com/aleqsio))
|
|
29
42
|
- [Android] Fixed splash screen is missing when using the `getDelayLoadAppHandler()` from expo-updates. ([#23747](https://github.com/expo/expo/pull/23747) by [@kudo](https://github.com/kudo))
|
|
30
43
|
|
|
31
|
-
|
|
44
|
+
### 💡 Others
|
|
45
|
+
|
|
46
|
+
- Fork `uuid@3.4.0` and move into `expo-modules-core`. Remove the original dependency. ([#23249](https://github.com/expo/expo/pull/23249) by [@alanhughes](https://github.com/alanjhughes))
|
|
47
|
+
- Improved error handling when working with native promises on Android. ([#23571](https://github.com/expo/expo/pull/23571) by [@lukmccall](https://github.com/lukmccall))
|
|
48
|
+
- Added tracing to avoid slow app startup on Android. ([#23653](https://github.com/expo/expo/pull/23653) by [@lukmccall](https://github.com/lukmccall))
|
|
49
|
+
|
|
50
|
+
## 1.5.8 - 2023-07-23
|
|
32
51
|
|
|
33
52
|
### 🐛 Bug fixes
|
|
34
53
|
|
|
35
|
-
- Fork `uuid@3.4.0` and move into `expo-modules-core`. Remove the original dependency. ([#23249](https://github.com/expo/expo/pull/23249) by [@alanhughes](https://github.com/alanjhughes))
|
|
36
54
|
- Fixed the `ErrorViewGroup` cannot be cast to module view class exception on Android. ([#23651](https://github.com/expo/expo/pull/23651) by [@lukmccall](https://github.com/lukmccall))
|
|
37
55
|
- [iOS] Fix allowed orientations set in `Info.plist` being ignored when no delegates requested a different orientation. ([#23593](https://github.com/expo/expo/pull/23593) by [@behenate](https://github.com/behenate))
|
|
38
56
|
|
package/android/CMakeLists.txt
CHANGED
|
@@ -6,7 +6,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
|
6
6
|
set(CMAKE_CXX_STANDARD 17)
|
|
7
7
|
set(PACKAGE_NAME "expo-modules-core")
|
|
8
8
|
set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
|
|
9
|
-
set(ignoreMe "${PROJECT_BUILD_DIR} ${REACT_ANDROID_BUILD_DIR} ${REACT_ANDROID_DIR} ${
|
|
9
|
+
set(ignoreMe "${PROJECT_BUILD_DIR} ${REACT_ANDROID_BUILD_DIR} ${REACT_ANDROID_DIR} ${BOOST_VERSION}")
|
|
10
10
|
|
|
11
11
|
string(APPEND CMAKE_CXX_FLAGS " -DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}")
|
|
12
12
|
|
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 = '1.
|
|
9
|
+
version = '1.7.0'
|
|
10
10
|
|
|
11
11
|
buildscript {
|
|
12
12
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -64,7 +64,8 @@ def REACT_NATIVE_SO_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
|
|
|
64
64
|
def reactProperties = new Properties()
|
|
65
65
|
file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
// TODO: Remove react-native < 0.71 support
|
|
68
|
+
def BOOST_VERSION = reactProperties.getProperty("BOOST_VERSION") ?: "1_76_0"
|
|
68
69
|
def REACT_NATIVE_VERSION = System.getenv("REACT_NATIVE_OVERRIDE_VERSION") ?: reactProperties.getProperty("VERSION_NAME")
|
|
69
70
|
def REACT_NATIVE_TARGET_VERSION = REACT_NATIVE_VERSION.split("\\.")[1].toInteger()
|
|
70
71
|
|
|
@@ -76,20 +77,7 @@ def reactNativeArchitectures() {
|
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
// HERMES
|
|
79
|
-
def prebuiltHermesDir = findProperty("expo.prebuiltHermesDir") ?: file("${rootDir}/prebuiltHermes")
|
|
80
|
-
def prebuiltHermesVersion = file("${prebuiltHermesDir}/.hermesversion").exists() ? file("${prebuiltHermesDir}/.hermesversion").text : null
|
|
81
|
-
def currentHermesVersion = file("${REACT_NATIVE_DIR}/sdks/.hermesversion").exists() ? file("${REACT_NATIVE_DIR}/sdks/.hermesversion").text : null
|
|
82
|
-
def hasHermesProject = findProject(":packages:react-native:ReactAndroid:hermes-engine") != null
|
|
83
|
-
def prebuiltHermesCacheHit = hasHermesProject && currentHermesVersion == prebuiltHermesVersion
|
|
84
|
-
|
|
85
|
-
// By default we are going to download and unzip hermes inside the /sdks/hermes folder
|
|
86
|
-
// but you can provide an override for where the hermes source code is located.
|
|
87
|
-
def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: file("${REACT_NATIVE_DIR}/sdks/hermes")
|
|
88
|
-
|
|
89
80
|
def USE_HERMES = true
|
|
90
|
-
def NEED_DOWNLOAD_HERMES = false
|
|
91
|
-
def HERMES_HEADER_DIR = null
|
|
92
|
-
def HERMES_AAR = null
|
|
93
81
|
if (findProject(":app")) {
|
|
94
82
|
def appProject = project(":app")
|
|
95
83
|
USE_HERMES = appProject?.hermesEnabled?.toBoolean() || appProject?.ext?.react?.enableHermes?.toBoolean()
|
|
@@ -97,25 +85,6 @@ if (findProject(":app")) {
|
|
|
97
85
|
|
|
98
86
|
// Currently the needs for hermes/jsc are only for androidTest, so we turn on this flag only when `isExpoModulesCoreTests` is true
|
|
99
87
|
USE_HERMES = USE_HERMES && isExpoModulesCoreTests
|
|
100
|
-
|
|
101
|
-
if (USE_HERMES) {
|
|
102
|
-
if (prebuiltHermesCacheHit) {
|
|
103
|
-
HERMES_HEADER_DIR = file("${thirdPartyNdkDir}/hermes/prefab/modules/libhermes/include")
|
|
104
|
-
HERMES_AAR = file("${prebuiltHermesDir}/hermes-engine-debug.aar")
|
|
105
|
-
} else if (hasHermesProject) {
|
|
106
|
-
HERMES_HEADER_DIR = file("${thirdPartyNdkDir}/hermes/prefab/modules/libhermes/include")
|
|
107
|
-
HERMES_AAR = file("${REACT_NATIVE_DIR}/ReactAndroid/hermes-engine/build/outputs/aar/hermes-engine-debug.aar")
|
|
108
|
-
} else {
|
|
109
|
-
def prebuiltAAR = fileTree(REACT_NATIVE_DIR).matching { include "**/hermes-engine/**/hermes-engine-*-debug.aar" }
|
|
110
|
-
if (prebuiltAAR.any()) {
|
|
111
|
-
HERMES_AAR = prebuiltAAR.singleFile
|
|
112
|
-
} else {
|
|
113
|
-
HERMES_AAR = file("${hermesEngineDir}/android/hermes-debug.aar")
|
|
114
|
-
}
|
|
115
|
-
HERMES_HEADER_DIR = file("${hermesDir}")
|
|
116
|
-
NEED_DOWNLOAD_HERMES = true
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
88
|
// END HERMES
|
|
120
89
|
|
|
121
90
|
def isNewArchitectureEnabled = findProperty("newArchEnabled") == "true"
|
|
@@ -145,13 +114,16 @@ android {
|
|
|
145
114
|
ndkVersion rootProject.ext.ndkVersion
|
|
146
115
|
}
|
|
147
116
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
117
|
+
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
118
|
+
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
119
|
+
compileOptions {
|
|
120
|
+
sourceCompatibility JavaVersion.VERSION_11
|
|
121
|
+
targetCompatibility JavaVersion.VERSION_11
|
|
122
|
+
}
|
|
152
123
|
|
|
153
|
-
|
|
154
|
-
|
|
124
|
+
kotlinOptions {
|
|
125
|
+
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
126
|
+
}
|
|
155
127
|
}
|
|
156
128
|
|
|
157
129
|
namespace "expo.modules"
|
|
@@ -160,7 +132,7 @@ android {
|
|
|
160
132
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
161
133
|
consumerProguardFiles 'proguard-rules.pro'
|
|
162
134
|
versionCode 1
|
|
163
|
-
versionName "1.
|
|
135
|
+
versionName "1.7.0"
|
|
164
136
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
|
|
165
137
|
|
|
166
138
|
testInstrumentationRunner "expo.modules.TestRunner"
|
|
@@ -174,7 +146,6 @@ android {
|
|
|
174
146
|
"-DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}",
|
|
175
147
|
"-DBOOST_VERSION=${BOOST_VERSION}",
|
|
176
148
|
"-DUSE_HERMES=${USE_HERMES}",
|
|
177
|
-
"-DHERMES_HEADER_DIR=${HERMES_HEADER_DIR}",
|
|
178
149
|
"-DIS_NEW_ARCHITECTURE_ENABLED=${isNewArchitectureEnabled}",
|
|
179
150
|
"-DPROJECT_BUILD_DIR=$buildDir",
|
|
180
151
|
"-DREACT_ANDROID_DIR=${REACT_NATIVE_DIR}/ReactAndroid",
|
|
@@ -194,7 +165,20 @@ android {
|
|
|
194
165
|
}
|
|
195
166
|
}
|
|
196
167
|
|
|
168
|
+
sourceSets {
|
|
169
|
+
main {
|
|
170
|
+
java {
|
|
171
|
+
if (REACT_NATIVE_TARGET_VERSION >= 73) {
|
|
172
|
+
srcDirs += "src/reactnative"
|
|
173
|
+
} else {
|
|
174
|
+
srcDirs += "src/reactnative72"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
197
180
|
buildFeatures {
|
|
181
|
+
buildConfig true
|
|
198
182
|
prefab true
|
|
199
183
|
}
|
|
200
184
|
|
|
@@ -301,71 +285,20 @@ dependencies {
|
|
|
301
285
|
androidTestImplementation "com.google.truth:truth:1.1.2"
|
|
302
286
|
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
|
|
303
287
|
|
|
304
|
-
if (
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
288
|
+
if (isExpoModulesCoreTests) {
|
|
289
|
+
if (USE_HERMES) {
|
|
290
|
+
compileOnly "com.facebook.react:hermes-android"
|
|
291
|
+
} else {
|
|
292
|
+
compileOnly "org.webkit:android-jsc:+"
|
|
293
|
+
}
|
|
309
294
|
}
|
|
310
295
|
}
|
|
311
296
|
|
|
312
|
-
/**
|
|
313
|
-
* To make the users of annotations @OptIn and @RequiresOptIn aware of their experimental status,
|
|
314
|
-
* the compiler raises warnings when compiling the code with these annotations:
|
|
315
|
-
* This class can only be used with the compiler argument '-Xopt-in=kotlin.RequiresOptIn'
|
|
316
|
-
* To remove the warnings, we add the compiler argument -Xopt-in=kotlin.RequiresOptIn.
|
|
317
|
-
*/
|
|
318
|
-
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
|
319
|
-
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
|
320
|
-
}
|
|
321
|
-
|
|
322
297
|
def createNativeDepsDirectories = project.tasks.findByName('createNativeDepsDirectories') ?: project.tasks.register('createNativeDepsDirectories') {
|
|
323
298
|
downloadsDir.mkdirs()
|
|
324
299
|
thirdPartyNdkDir.mkdirs()
|
|
325
300
|
}
|
|
326
301
|
|
|
327
|
-
// TODO: Remove all these hermes code when we update our repo to react-native 0.71 by using prefab
|
|
328
|
-
task downloadHermes(type: Download) {
|
|
329
|
-
def hermesVersion = currentHermesVersion ?: "main"
|
|
330
|
-
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
|
|
331
|
-
onlyIfNewer(true)
|
|
332
|
-
overwrite(false)
|
|
333
|
-
dest(new File(downloadsDir, "hermes-${hermesVersion}.tar.gz"))
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
task unzipHermes(dependsOn: downloadHermes, type: Copy) {
|
|
337
|
-
from(tarTree(downloadHermes.dest)) {
|
|
338
|
-
eachFile { file ->
|
|
339
|
-
// We flatten the unzip as the tarball contains a `facebook-hermes-<SHA>`
|
|
340
|
-
// folder at the top level.
|
|
341
|
-
if (file.relativePath.segments.size() > 1) {
|
|
342
|
-
file.relativePath = new org.gradle.api.file.RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
into(hermesDir)
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
task prepareHermes() {
|
|
350
|
-
if (!USE_HERMES) {
|
|
351
|
-
return
|
|
352
|
-
}
|
|
353
|
-
dependsOn(createNativeDepsDirectories)
|
|
354
|
-
if (NEED_DOWNLOAD_HERMES) {
|
|
355
|
-
dependsOn(unzipHermes)
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
doLast {
|
|
359
|
-
def files = zipTree(HERMES_AAR).matching({ it.include "**/*.so", "prefab/modules/libhermes/include/**/*" })
|
|
360
|
-
|
|
361
|
-
copy {
|
|
362
|
-
from files
|
|
363
|
-
from "$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/first-party/hermes/Android.mk"
|
|
364
|
-
into "$thirdPartyNdkDir/hermes"
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
302
|
def downloadBoost = tasks.create('downloadBoost', Download) {
|
|
370
303
|
dependsOn(createNativeDepsDirectories)
|
|
371
304
|
def srcUrl = REACT_NATIVE_TARGET_VERSION >= 69
|
|
@@ -408,12 +341,6 @@ afterEvaluate {
|
|
|
408
341
|
if (REACT_NATIVE_TARGET_VERSION < 71) {
|
|
409
342
|
nativeBuildDependsOn(project, prepareBoost, null)
|
|
410
343
|
}
|
|
411
|
-
if (USE_HERMES) {
|
|
412
|
-
nativeBuildDependsOn(project, prepareHermes, null)
|
|
413
|
-
if (hasHermesProject && !prebuiltHermesCacheHit) {
|
|
414
|
-
prepareHermes.dependsOn(":packages:react-native:ReactAndroid:hermes-engine:assembleDebug")
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
344
|
}
|
|
418
345
|
|
|
419
346
|
if (REACT_NATIVE_TARGET_VERSION < 71) {
|
|
@@ -14,6 +14,23 @@ namespace jni = facebook::jni;
|
|
|
14
14
|
namespace jsi = facebook::jsi;
|
|
15
15
|
|
|
16
16
|
namespace expo {
|
|
17
|
+
|
|
18
|
+
namespace {
|
|
19
|
+
|
|
20
|
+
#if REACT_NATIVE_TARGET_VERSION >= 73
|
|
21
|
+
std::shared_ptr<NativeMethodCallInvokerCompatible> getNativeMethodCallInvokerHolderCompatible(
|
|
22
|
+
jni::alias_ref<NativeMethodCallInvokerHolderCompatible::javaobject> holder) {
|
|
23
|
+
return holder->cthis()->getNativeMethodCallInvoker();
|
|
24
|
+
}
|
|
25
|
+
#else
|
|
26
|
+
std::shared_ptr<NativeMethodCallInvokerCompatible> getNativeMethodCallInvokerHolderCompatible(
|
|
27
|
+
jni::alias_ref<NativeMethodCallInvokerHolderCompatible::javaobject> holder) {
|
|
28
|
+
return holder->cthis()->getCallInvoker();
|
|
29
|
+
}
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
} // namespace
|
|
33
|
+
|
|
17
34
|
jni::local_ref<JSIInteropModuleRegistry::jhybriddata>
|
|
18
35
|
JSIInteropModuleRegistry::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
|
19
36
|
return makeCxxInstance(jThis);
|
|
@@ -39,7 +56,7 @@ void JSIInteropModuleRegistry::installJSI(
|
|
|
39
56
|
jlong jsRuntimePointer,
|
|
40
57
|
jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator,
|
|
41
58
|
jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
|
|
42
|
-
jni::alias_ref<
|
|
59
|
+
jni::alias_ref<NativeMethodCallInvokerHolderCompatible::javaobject> nativeInvokerHolder
|
|
43
60
|
) {
|
|
44
61
|
this->jniDeallocator = jni::make_global(jniDeallocator);
|
|
45
62
|
|
|
@@ -51,7 +68,7 @@ void JSIInteropModuleRegistry::installJSI(
|
|
|
51
68
|
this,
|
|
52
69
|
runtime,
|
|
53
70
|
jsInvokerHolder->cthis()->getCallInvoker(),
|
|
54
|
-
nativeInvokerHolder
|
|
71
|
+
getNativeMethodCallInvokerHolderCompatible(nativeInvokerHolder)
|
|
55
72
|
);
|
|
56
73
|
|
|
57
74
|
auto expoModules = std::make_shared<ExpoModulesHostObject>(this);
|
|
@@ -113,6 +130,16 @@ JSIInteropModuleRegistry::callGetJavaScriptModuleObjectMethod(const std::string
|
|
|
113
130
|
return method(javaPart_, moduleName);
|
|
114
131
|
}
|
|
115
132
|
|
|
133
|
+
jni::local_ref<JavaScriptModuleObject::javaobject>
|
|
134
|
+
JSIInteropModuleRegistry::callGetCoreModuleObject() const {
|
|
135
|
+
const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
|
|
136
|
+
->getMethod<jni::local_ref<JavaScriptModuleObject::javaobject>()>(
|
|
137
|
+
"getCoreModuleObject"
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
return method(javaPart_);
|
|
141
|
+
}
|
|
142
|
+
|
|
116
143
|
jni::local_ref<jni::JArrayClass<jni::JString>>
|
|
117
144
|
JSIInteropModuleRegistry::callGetJavaScriptModulesNames() const {
|
|
118
145
|
const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
|
|
@@ -135,6 +162,10 @@ JSIInteropModuleRegistry::getModule(const std::string &moduleName) const {
|
|
|
135
162
|
return callGetJavaScriptModuleObjectMethod(moduleName);
|
|
136
163
|
}
|
|
137
164
|
|
|
165
|
+
jni::local_ref<JavaScriptModuleObject::javaobject> JSIInteropModuleRegistry::getCoreModule() const {
|
|
166
|
+
return callGetCoreModuleObject();
|
|
167
|
+
}
|
|
168
|
+
|
|
138
169
|
bool JSIInteropModuleRegistry::hasModule(const std::string &moduleName) const {
|
|
139
170
|
return callHasModule(moduleName);
|
|
140
171
|
}
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
#include <jsi/jsi.h>
|
|
15
15
|
#include <ReactCommon/CallInvokerHolder.h>
|
|
16
16
|
#include <ReactCommon/CallInvoker.h>
|
|
17
|
+
#if REACT_NATIVE_TARGET_VERSION >= 73
|
|
18
|
+
#include <ReactCommon/NativeMethodCallInvokerHolder.h>
|
|
19
|
+
#endif
|
|
17
20
|
|
|
18
21
|
#include <memory>
|
|
19
22
|
|
|
@@ -22,6 +25,13 @@ namespace jsi = facebook::jsi;
|
|
|
22
25
|
namespace react = facebook::react;
|
|
23
26
|
|
|
24
27
|
namespace expo {
|
|
28
|
+
|
|
29
|
+
#if REACT_NATIVE_TARGET_VERSION >= 73
|
|
30
|
+
using NativeMethodCallInvokerHolderCompatible = react::NativeMethodCallInvokerHolder;
|
|
31
|
+
#else
|
|
32
|
+
using NativeMethodCallInvokerHolderCompatible = react::CallInvokerHolder;
|
|
33
|
+
#endif
|
|
34
|
+
|
|
25
35
|
/**
|
|
26
36
|
* A JNI wrapper to initialize CPP part of modules and access all data from the module registry.
|
|
27
37
|
*/
|
|
@@ -42,7 +52,7 @@ public:
|
|
|
42
52
|
jlong jsRuntimePointer,
|
|
43
53
|
jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator,
|
|
44
54
|
jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
|
|
45
|
-
jni::alias_ref<
|
|
55
|
+
jni::alias_ref<NativeMethodCallInvokerHolderCompatible::javaobject> nativeInvokerHolder
|
|
46
56
|
);
|
|
47
57
|
|
|
48
58
|
/**
|
|
@@ -82,6 +92,11 @@ public:
|
|
|
82
92
|
*/
|
|
83
93
|
jni::local_ref<JavaScriptObject::javaobject> createObject();
|
|
84
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Gets a core module.
|
|
97
|
+
*/
|
|
98
|
+
jni::local_ref<JavaScriptModuleObject::javaobject> getCoreModule() const;
|
|
99
|
+
|
|
85
100
|
/**
|
|
86
101
|
* Adds a shared object to the internal registry
|
|
87
102
|
* @param native part of the shared object
|
|
@@ -113,6 +128,8 @@ private:
|
|
|
113
128
|
|
|
114
129
|
inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const;
|
|
115
130
|
|
|
131
|
+
inline jni::local_ref<JavaScriptModuleObject::javaobject> callGetCoreModuleObject() const;
|
|
132
|
+
|
|
116
133
|
inline bool callHasModule(const std::string &moduleName) const;
|
|
117
134
|
};
|
|
118
135
|
} // namespace expo
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include "JavaScriptModuleObject.h"
|
|
4
4
|
#include "JSIInteropModuleRegistry.h"
|
|
5
|
-
#include "
|
|
5
|
+
#include "JSIUtils.h"
|
|
6
6
|
|
|
7
7
|
#include <folly/dynamic.h>
|
|
8
8
|
#include <jsi/JSIDynamic.h>
|
|
@@ -61,7 +61,7 @@ void decorateObjectWithProperties(
|
|
|
61
61
|
jsi::Value(runtime, *setter.toJSFunction(runtime,
|
|
62
62
|
jsiInteropModuleRegistry))
|
|
63
63
|
);
|
|
64
|
-
|
|
64
|
+
common::definePropertyOnJSIObject(runtime, jsObject, name.c_str(), std::move(descriptor));
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -215,8 +215,8 @@ std::shared_ptr<jsi::Object> JavaScriptModuleObject::getJSIObject(jsi::Runtime &
|
|
|
215
215
|
auto descriptor = JavaScriptObject::preparePropertyDescriptor(runtime, 0);
|
|
216
216
|
descriptor.setProperty(runtime, "value", jsi::Value(runtime, nativeConstructor));
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
common::definePropertyOnJSIObject(runtime, &prototype, nativeConstructorKey.c_str(),
|
|
219
|
+
std::move(descriptor));
|
|
220
220
|
|
|
221
221
|
moduleObject->setProperty(
|
|
222
222
|
runtime,
|
|
@@ -321,29 +321,30 @@ void JavaScriptModuleObject::registerViewPrototype(
|
|
|
321
321
|
|
|
322
322
|
void JavaScriptModuleObject::registerProperty(
|
|
323
323
|
jni::alias_ref<jstring> name,
|
|
324
|
-
|
|
324
|
+
jboolean getterTakesOwner,
|
|
325
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> getterExpectedArgsTypes,
|
|
325
326
|
jni::alias_ref<JNIFunctionBody::javaobject> getter,
|
|
327
|
+
jboolean setterTakesOwner,
|
|
328
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> setterExpectedArgsTypes,
|
|
326
329
|
jni::alias_ref<JNIFunctionBody::javaobject> setter
|
|
327
330
|
) {
|
|
328
331
|
auto cName = name->toStdString();
|
|
329
332
|
|
|
330
333
|
auto getterMetadata = MethodMetadata(
|
|
331
334
|
cName,
|
|
335
|
+
getterTakesOwner,
|
|
336
|
+
getterExpectedArgsTypes->size(),
|
|
332
337
|
false,
|
|
333
|
-
|
|
334
|
-
false,
|
|
335
|
-
std::vector<std::unique_ptr<AnyType>>(),
|
|
338
|
+
jni::make_local(getterExpectedArgsTypes),
|
|
336
339
|
jni::make_global(getter)
|
|
337
340
|
);
|
|
338
341
|
|
|
339
|
-
auto types = std::vector<std::unique_ptr<AnyType>>();
|
|
340
|
-
types.push_back(std::make_unique<AnyType>(jni::make_local(expectedArgType)));
|
|
341
342
|
auto setterMetadata = MethodMetadata(
|
|
342
343
|
cName,
|
|
344
|
+
setterTakesOwner,
|
|
345
|
+
setterExpectedArgsTypes->size(),
|
|
343
346
|
false,
|
|
344
|
-
|
|
345
|
-
false,
|
|
346
|
-
std::move(types),
|
|
347
|
+
jni::make_local(setterExpectedArgsTypes),
|
|
347
348
|
jni::make_global(setter)
|
|
348
349
|
);
|
|
349
350
|
|
|
@@ -122,8 +122,11 @@ public:
|
|
|
122
122
|
*/
|
|
123
123
|
void registerProperty(
|
|
124
124
|
jni::alias_ref<jstring> name,
|
|
125
|
-
|
|
125
|
+
jboolean getterTakesOwner,
|
|
126
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> getterExpectedArgsTypes,
|
|
126
127
|
jni::alias_ref<JNIFunctionBody::javaobject> getter,
|
|
128
|
+
jboolean setterTakesOwner,
|
|
129
|
+
jni::alias_ref<jni::JArrayClass<ExpectedType>> setterExpectedArgsTypes,
|
|
127
130
|
jni::alias_ref<JNIFunctionBody::javaobject> setter
|
|
128
131
|
);
|
|
129
132
|
|
|
@@ -112,7 +112,11 @@ jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames(
|
|
|
112
112
|
jni::local_ref<JavaScriptFunction::javaobject> JavaScriptObject::jniAsFunction() {
|
|
113
113
|
auto &jsRuntime = runtimeHolder.getJSRuntime();
|
|
114
114
|
auto jsFuncion = std::make_shared<jsi::Function>(jsObject->asFunction(jsRuntime));
|
|
115
|
-
return JavaScriptFunction::newInstance(
|
|
115
|
+
return JavaScriptFunction::newInstance(
|
|
116
|
+
runtimeHolder.getModuleRegistry(),
|
|
117
|
+
runtimeHolder,
|
|
118
|
+
jsFuncion
|
|
119
|
+
);
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) {
|
|
@@ -143,27 +147,6 @@ jsi::Object JavaScriptObject::preparePropertyDescriptor(
|
|
|
143
147
|
return descriptor;
|
|
144
148
|
}
|
|
145
149
|
|
|
146
|
-
void JavaScriptObject::defineProperty(
|
|
147
|
-
jsi::Runtime &runtime,
|
|
148
|
-
jsi::Object *jsthis,
|
|
149
|
-
const std::string &name,
|
|
150
|
-
jsi::Object descriptor
|
|
151
|
-
) {
|
|
152
|
-
jsi::Object global = runtime.global();
|
|
153
|
-
jsi::Object objectClass = global.getPropertyAsObject(runtime, "Object");
|
|
154
|
-
jsi::Function definePropertyFunction = objectClass.getPropertyAsFunction(
|
|
155
|
-
runtime,
|
|
156
|
-
"defineProperty"
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
// This call is basically the same as `Object.defineProperty(object, name, descriptor)` in JS
|
|
160
|
-
definePropertyFunction.callWithThis(runtime, objectClass, {
|
|
161
|
-
jsi::Value(runtime, *jsthis),
|
|
162
|
-
jsi::String::createFromUtf8(runtime, name),
|
|
163
|
-
std::move(descriptor),
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
150
|
jni::local_ref<JavaScriptObject::javaobject> JavaScriptObject::newInstance(
|
|
168
151
|
JSIInteropModuleRegistry *jsiInteropModuleRegistry,
|
|
169
152
|
std::weak_ptr<JavaScriptRuntime> runtime,
|
|
@@ -179,7 +162,10 @@ void JavaScriptObject::defineNativeDeallocator(
|
|
|
179
162
|
) {
|
|
180
163
|
auto &rt = runtimeHolder.getJSRuntime();
|
|
181
164
|
jni::global_ref<JNIFunctionBody::javaobject> globalRef = jni::make_global(deallocator);
|
|
182
|
-
|
|
165
|
+
|
|
166
|
+
common::setDeallocator(
|
|
167
|
+
rt,
|
|
168
|
+
jsObject,
|
|
183
169
|
[globalRef = std::move(globalRef)]() mutable {
|
|
184
170
|
auto args = jni::Environment::current()->NewObjectArray(
|
|
185
171
|
0,
|
|
@@ -188,9 +174,8 @@ void JavaScriptObject::defineNativeDeallocator(
|
|
|
188
174
|
);
|
|
189
175
|
globalRef->invoke(args);
|
|
190
176
|
globalRef.reset();
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
jsObject->setProperty(rt, "__expo_shared_object_deallocator__", std::move(descriptor));
|
|
177
|
+
},
|
|
178
|
+
"__expo_shared_object_deallocator__"
|
|
179
|
+
);
|
|
195
180
|
}
|
|
196
181
|
} // namespace expo
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include "WeakRuntimeHolder.h"
|
|
9
9
|
#include "JNIFunctionBody.h"
|
|
10
10
|
#include "JNIDeallocator.h"
|
|
11
|
+
#include "JSIUtils.h"
|
|
11
12
|
|
|
12
13
|
#include <fbjni/fbjni.h>
|
|
13
14
|
#include <jsi/jsi.h>
|
|
@@ -71,13 +72,6 @@ public:
|
|
|
71
72
|
|
|
72
73
|
static jsi::Object preparePropertyDescriptor(jsi::Runtime &jsRuntime, int options);
|
|
73
74
|
|
|
74
|
-
static void defineProperty(
|
|
75
|
-
jsi::Runtime &runtime,
|
|
76
|
-
jsi::Object *jsthis,
|
|
77
|
-
const std::string &name,
|
|
78
|
-
jsi::Object descriptor
|
|
79
|
-
);
|
|
80
|
-
|
|
81
75
|
void defineNativeDeallocator(
|
|
82
76
|
jni::alias_ref<JNIFunctionBody::javaobject> deallocator
|
|
83
77
|
);
|
|
@@ -139,7 +133,7 @@ private:
|
|
|
139
133
|
auto cName = name->toStdString();
|
|
140
134
|
jsi::Object descriptor = preparePropertyDescriptor(jsRuntime, options);
|
|
141
135
|
descriptor.setProperty(jsRuntime, "value", jsi_type_converter<T>::convert(jsRuntime, value));
|
|
142
|
-
|
|
136
|
+
common::definePropertyOnJSIObject(jsRuntime, jsObject.get(), cName.c_str(), std::move(descriptor));
|
|
143
137
|
}
|
|
144
138
|
};
|
|
145
139
|
} // namespace expo
|