expo-modules-core 56.0.7 → 56.0.9
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 +14 -0
- package/android/build.gradle +2 -2
- package/android/src/compose/expo/modules/kotlin/views/ExpoComposeView.kt +4 -6
- package/android/src/main/cpp/JSIContext.h +0 -9
- package/android/src/main/cpp/JavaCallback.cpp +78 -47
- package/android/src/main/cpp/JavaCallback.h +1 -11
- package/android/src/main/cpp/JavaScriptValue.h +0 -1
- package/android/src/main/cpp/decorators/JSDecoratorsBridgingObject.cpp +10 -0
- package/android/src/main/cpp/decorators/JSDecoratorsBridgingObject.h +9 -9
- package/android/src/main/cpp/decorators/JSPropertiesDecorator.h +2 -0
- package/android/src/main/cpp/fabric/AndroidExpoViewState.h +2 -0
- package/android/src/main/cpp/fabric/ExpoComponentDescriptorFactory.cpp +31 -0
- package/android/src/main/cpp/fabric/ExpoComponentDescriptorFactory.h +23 -0
- package/android/src/main/cpp/fabric/FabricComponentsRegistry.cpp +3 -25
- package/android/src/main/cpp/fabric/FabricComponentsRegistry.h +0 -17
- package/android/src/main/cpp/fabric/NativeStatePropsGetter.cpp +1 -0
- package/android/src/main/cpp/fabric/NativeStatePropsGetter.h +0 -1
- package/android/src/main/java/expo/modules/kotlin/devtools/cdp/CdpNetworkTypes.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +26 -4
- package/android/src/main/java/expo/modules/kotlin/views/OnAttachAfterDetachmentListener.kt +41 -0
- package/build/polyfill/CoreModule.d.ts.map +1 -1
- package/build/ts-declarations/SharedRef.d.ts.map +1 -1
- package/ios/Core/ExpoModulesMacros.swift +64 -5
- package/ios/Core/ModuleHolder.swift +19 -1
- package/ios/Core/Modules/ModuleDefinition.swift +7 -0
- package/ios/Core/Protocols/AnyModule.swift +12 -0
- package/ios/Core/SharedObjects/SharedObject.swift +64 -43
- package/ios/DevTools/CdpNetworkTypes.swift +1 -1
- package/package.json +4 -4
- package/prebuilds/output/debug/xcframeworks/ExpoModulesCore.tar.gz +0 -0
- package/prebuilds/output/debug/xcframeworks/ExpoModulesWorklets.tar.gz +0 -0
- package/prebuilds/output/release/xcframeworks/ExpoModulesCore.tar.gz +0 -0
- package/prebuilds/output/release/xcframeworks/ExpoModulesWorklets.tar.gz +0 -0
- package/src/polyfill/CoreModule.ts +3 -3
- package/src/ts-declarations/SharedRef.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,19 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 56.0.9 — 2026-05-15
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Added single-payload overloads for `SharedObject.emit` on iOS and Android. The iOS API also accepts an already-converted `JavaScriptValue` payload to skip the native-to-JS conversion step. ([#45596](https://github.com/expo/expo/pull/45596) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
|
|
19
|
+
## 56.0.8 — 2026-05-13
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- [Android] Avoid remounting Jetpack Compose views during same-frame React Native reparenting. ([#45711](https://github.com/expo/expo/pull/45711) by [@mvincentong](https://github.com/mvincentong))
|
|
24
|
+
- [Android] Fixed `associatedCookies` in `Network.requestWillBeSentExtraInfo` CDP events serializing as a JSON object instead of an array. ([#45720](https://github.com/expo/expo/pull/45720) by [@huntie](https://github.com/huntie))
|
|
25
|
+
|
|
13
26
|
## 56.0.7 — 2026-05-13
|
|
14
27
|
|
|
15
28
|
### 🐛 Bug fixes
|
|
@@ -21,6 +34,7 @@
|
|
|
21
34
|
### 💡 Others
|
|
22
35
|
|
|
23
36
|
- [iOS] `AppContext.setRuntime` now takes the native React `RuntimeScheduler` pointer and a dispatch trampoline alongside the runtime pointer. ([#45636](https://github.com/expo/expo/pull/45636) by [@tsapeta](https://github.com/tsapeta))
|
|
37
|
+
- Deprecated `SharedObject.emit(event:arguments:)` (iOS) and the `vararg` `emit` (Android) in favor of the new single-payload overloads. Existing single-argument call sites keep working unchanged. ([#45596](https://github.com/expo/expo/pull/45596) by [@tsapeta](https://github.com/tsapeta))
|
|
24
38
|
|
|
25
39
|
## 56.0.5 — 2026-05-08
|
|
26
40
|
|
package/android/build.gradle
CHANGED
|
@@ -27,7 +27,7 @@ if (shouldIncludeCompose) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
group = 'host.exp.exponent'
|
|
30
|
-
version = '56.0.
|
|
30
|
+
version = '56.0.9'
|
|
31
31
|
|
|
32
32
|
def isExpoModulesCoreTests = {
|
|
33
33
|
Gradle gradle = getGradle()
|
|
@@ -94,7 +94,7 @@ android {
|
|
|
94
94
|
defaultConfig {
|
|
95
95
|
consumerProguardFiles 'proguard-rules.pro'
|
|
96
96
|
versionCode 1
|
|
97
|
-
versionName "56.0.
|
|
97
|
+
versionName "56.0.9"
|
|
98
98
|
buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
|
|
99
99
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
|
|
100
100
|
|
|
@@ -193,13 +193,11 @@ abstract class ExpoComposeView<T : ComposeProps>(
|
|
|
193
193
|
Content()
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
it.addOnAttachStateChangeListener(
|
|
197
|
-
|
|
196
|
+
it.addOnAttachStateChangeListener(
|
|
197
|
+
OnAttachAfterDetachmentListener(onAttachAfterDetachment = {
|
|
198
198
|
it.disposeComposition()
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
override fun onViewDetachedFromWindow(v: View) = Unit
|
|
202
|
-
})
|
|
199
|
+
})
|
|
200
|
+
)
|
|
203
201
|
}
|
|
204
202
|
addView(composeView)
|
|
205
203
|
}
|
|
@@ -7,22 +7,13 @@
|
|
|
7
7
|
#include "JavaScriptModuleObject.h"
|
|
8
8
|
#include "JavaScriptValue.h"
|
|
9
9
|
#include "JavaScriptObject.h"
|
|
10
|
-
#include "JavaReferencesCache.h"
|
|
11
10
|
#include "JSReferencesCache.h"
|
|
12
11
|
#include "JNIDeallocator.h"
|
|
13
12
|
#include "ThreadSafeJNIGlobalRef.h"
|
|
14
13
|
#include "javaclasses/JSRunnable.h"
|
|
15
14
|
|
|
16
|
-
#include <ReactCommon/CallInvokerHolder.h>
|
|
17
15
|
#include <ReactCommon/CallInvoker.h>
|
|
18
16
|
|
|
19
|
-
#if IS_NEW_ARCHITECTURE_ENABLED
|
|
20
|
-
|
|
21
|
-
#include <ReactCommon/RuntimeExecutor.h>
|
|
22
|
-
#include <react/jni/JRuntimeExecutor.h>
|
|
23
|
-
|
|
24
|
-
#endif
|
|
25
|
-
|
|
26
17
|
namespace jni = facebook::jni;
|
|
27
18
|
namespace jsi = facebook::jsi;
|
|
28
19
|
namespace react = facebook::react;
|
|
@@ -60,10 +60,8 @@ jni::local_ref<JavaCallback::javaobject> JavaCallback::newInstance(
|
|
|
60
60
|
return object;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
void
|
|
65
|
-
ArgsConverter<typename std::remove_const<T>::type> argsConverter,
|
|
66
|
-
T arg
|
|
63
|
+
void JavaCallback::invokeWithResolver(
|
|
64
|
+
std::function<void(jsi::Runtime &rt, jsi::Function &jsFunction)> resolver
|
|
67
65
|
) {
|
|
68
66
|
const auto strongCallbackContext = this->callbackContext.lock();
|
|
69
67
|
// The context were deallocated before the callback was invoked.
|
|
@@ -80,8 +78,7 @@ void JavaCallback::invokeJSFunction(
|
|
|
80
78
|
jsInvoker->invokeAsync(
|
|
81
79
|
[
|
|
82
80
|
context = callbackContext,
|
|
83
|
-
|
|
84
|
-
arg = std::move(arg)
|
|
81
|
+
resolver = std::move(resolver)
|
|
85
82
|
]() -> void {
|
|
86
83
|
auto strongContext = context.lock();
|
|
87
84
|
// The context were deallocated before the callback was invoked.
|
|
@@ -98,25 +95,11 @@ void JavaCallback::invokeJSFunction(
|
|
|
98
95
|
jsi::Function &jsFunction = strongContext->resolveHolder.value();
|
|
99
96
|
jsi::Runtime &rt = strongContext->rt;
|
|
100
97
|
|
|
101
|
-
|
|
98
|
+
resolver(rt, jsFunction);
|
|
102
99
|
strongContext->invalidate();
|
|
103
100
|
});
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
template<class T>
|
|
107
|
-
void JavaCallback::invokeJSFunction(T arg) {
|
|
108
|
-
invokeJSFunction<T>(
|
|
109
|
-
[](
|
|
110
|
-
jsi::Runtime &rt,
|
|
111
|
-
jsi::Function &jsFunction,
|
|
112
|
-
T arg
|
|
113
|
-
) {
|
|
114
|
-
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::forward<T>(arg)));
|
|
115
|
-
},
|
|
116
|
-
arg
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
103
|
template<class T>
|
|
121
104
|
void JavaCallback::invokeJSFunctionForArray(T &arg) {
|
|
122
105
|
size_t size = arg->size();
|
|
@@ -125,38 +108,51 @@ void JavaCallback::invokeJSFunctionForArray(T &arg) {
|
|
|
125
108
|
rawArray.size = size;
|
|
126
109
|
rawArray.data = std::move(region);
|
|
127
110
|
|
|
128
|
-
|
|
129
|
-
std::move(rawArray)
|
|
111
|
+
invokeWithResolver(
|
|
112
|
+
[rawArray = std::move(rawArray)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
113
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(rawArray)));
|
|
114
|
+
}
|
|
130
115
|
);
|
|
131
116
|
}
|
|
132
117
|
|
|
133
118
|
void JavaCallback::invoke() {
|
|
134
|
-
|
|
135
|
-
[](
|
|
136
|
-
jsi::Runtime &rt,
|
|
137
|
-
jsi::Function &jsFunction,
|
|
138
|
-
nullptr_t arg
|
|
139
|
-
) {
|
|
119
|
+
invokeWithResolver(
|
|
120
|
+
[](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
140
121
|
jsFunction.call(rt, {jsi::Value::null()});
|
|
141
|
-
}
|
|
142
|
-
nullptr
|
|
122
|
+
}
|
|
143
123
|
);
|
|
144
124
|
}
|
|
145
125
|
|
|
146
126
|
void JavaCallback::invokeBool(bool result) {
|
|
147
|
-
|
|
127
|
+
invokeWithResolver(
|
|
128
|
+
[result](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
129
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, result));
|
|
130
|
+
}
|
|
131
|
+
);
|
|
148
132
|
}
|
|
149
133
|
|
|
150
134
|
void JavaCallback::invokeInt(int result) {
|
|
151
|
-
|
|
135
|
+
invokeWithResolver(
|
|
136
|
+
[result](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
137
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, result));
|
|
138
|
+
}
|
|
139
|
+
);
|
|
152
140
|
}
|
|
153
141
|
|
|
154
142
|
void JavaCallback::invokeDouble(double result) {
|
|
155
|
-
|
|
143
|
+
invokeWithResolver(
|
|
144
|
+
[result](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
145
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, result));
|
|
146
|
+
}
|
|
147
|
+
);
|
|
156
148
|
}
|
|
157
149
|
|
|
158
150
|
void JavaCallback::invokeFloat(float result) {
|
|
159
|
-
|
|
151
|
+
invokeWithResolver(
|
|
152
|
+
[result](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
153
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, result));
|
|
154
|
+
}
|
|
155
|
+
);
|
|
160
156
|
}
|
|
161
157
|
|
|
162
158
|
void JavaCallback::invokeString(jni::alias_ref<jstring> result) {
|
|
@@ -164,41 +160,76 @@ void JavaCallback::invokeString(jni::alias_ref<jstring> result) {
|
|
|
164
160
|
const char *rawValue = env->GetStringUTFChars(result.get(), nullptr);
|
|
165
161
|
std::string parsedResult = rawValue;
|
|
166
162
|
env->ReleaseStringUTFChars(result.get(), rawValue);
|
|
167
|
-
|
|
163
|
+
invokeWithResolver(
|
|
164
|
+
[parsedResult = std::move(parsedResult)](jsi::Runtime &rt, jsi::Function &jsFunction) {
|
|
165
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, parsedResult));
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
void JavaCallback::invokeCollection(jni::alias_ref<jni::JCollection<jobject>> result) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
jni::global_ref<jni::JCollection<jobject>> globalResult = jni::make_global(result);
|
|
172
|
+
invokeWithResolver(
|
|
173
|
+
[globalResult = std::move(globalResult)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
174
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(globalResult)));
|
|
175
|
+
}
|
|
176
|
+
);
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
void JavaCallback::invokeMap(jni::alias_ref<jni::JMap<jstring, jobject>> result) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
jni::global_ref<jni::JMap<jstring, jobject>> globalResult = jni::make_global(result);
|
|
181
|
+
invokeWithResolver(
|
|
182
|
+
[globalResult = std::move(globalResult)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
183
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(globalResult)));
|
|
184
|
+
}
|
|
185
|
+
);
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
void
|
|
183
189
|
JavaCallback::invokeWritableArray(jni::alias_ref<react::WritableNativeArray::javaobject> result) {
|
|
184
|
-
|
|
190
|
+
auto consumed = result->cthis()->consume();
|
|
191
|
+
invokeWithResolver(
|
|
192
|
+
[consumed = std::move(consumed)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
193
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(consumed)));
|
|
194
|
+
}
|
|
195
|
+
);
|
|
185
196
|
}
|
|
186
197
|
|
|
187
198
|
void JavaCallback::invokeWritableMap(jni::alias_ref<react::WritableNativeMap::javaobject> result) {
|
|
188
|
-
|
|
199
|
+
auto consumed = result->cthis()->consume();
|
|
200
|
+
invokeWithResolver(
|
|
201
|
+
[consumed = std::move(consumed)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
202
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(consumed)));
|
|
203
|
+
}
|
|
204
|
+
);
|
|
189
205
|
}
|
|
190
206
|
|
|
191
207
|
void JavaCallback::invokeSharedObject(jni::alias_ref<JSharedObject::javaobject> result) {
|
|
192
|
-
|
|
208
|
+
auto globalResult = jni::make_global(result);
|
|
209
|
+
invokeWithResolver(
|
|
210
|
+
[globalResult = std::move(globalResult)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
211
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(globalResult)));
|
|
212
|
+
}
|
|
213
|
+
);
|
|
193
214
|
}
|
|
194
215
|
|
|
195
216
|
void JavaCallback::invokeJavaScriptArrayBuffer(
|
|
196
217
|
jni::alias_ref<JavaScriptArrayBuffer::javaobject> result) {
|
|
197
|
-
|
|
218
|
+
auto globalResult = jni::make_global(result);
|
|
219
|
+
invokeWithResolver(
|
|
220
|
+
[globalResult = std::move(globalResult)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
221
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(globalResult)));
|
|
222
|
+
}
|
|
223
|
+
);
|
|
198
224
|
}
|
|
199
225
|
|
|
200
226
|
void JavaCallback::invokeNativeArrayBuffer(jni::alias_ref<NativeArrayBuffer::javaobject> result) {
|
|
201
|
-
|
|
227
|
+
auto globalResult = jni::make_global(result);
|
|
228
|
+
invokeWithResolver(
|
|
229
|
+
[globalResult = std::move(globalResult)](jsi::Runtime &rt, jsi::Function &jsFunction) mutable {
|
|
230
|
+
jsFunction.call(rt, convertToJS(jni::Environment::current(), rt, std::move(globalResult)));
|
|
231
|
+
}
|
|
232
|
+
);
|
|
202
233
|
}
|
|
203
234
|
|
|
204
235
|
void JavaCallback::invokeIntArray(jni::alias_ref<jni::JArrayInt> result) {
|
|
@@ -90,19 +90,9 @@ private:
|
|
|
90
90
|
void invokeDoubleArray(jni::alias_ref<jni::JArrayDouble> result);
|
|
91
91
|
void invokeFloatArray(jni::alias_ref<jni::JArrayFloat> result);
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
using ArgsConverter = std::function<void(jsi::Runtime &rt, jsi::Function &jsFunction, T arg)>;
|
|
95
|
-
|
|
96
|
-
template<class T>
|
|
97
|
-
inline void invokeJSFunction(
|
|
98
|
-
ArgsConverter<typename std::remove_const<T>::type> argsConverter,
|
|
99
|
-
T arg
|
|
100
|
-
);
|
|
93
|
+
void invokeWithResolver(std::function<void(jsi::Runtime &rt, jsi::Function &jsFunction)> resolver);
|
|
101
94
|
|
|
102
95
|
template<class T>
|
|
103
96
|
void invokeJSFunctionForArray(T &arg);
|
|
104
|
-
|
|
105
|
-
template<class T>
|
|
106
|
-
inline void invokeJSFunction(T arg);
|
|
107
97
|
};
|
|
108
98
|
} // namespace expo
|
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
#include "JSDecoratorsBridgingObject.h"
|
|
4
4
|
|
|
5
|
+
#include "JSFunctionsDecorator.h"
|
|
6
|
+
#include "JSPropertiesDecorator.h"
|
|
7
|
+
#include "JSConstantsDecorator.h"
|
|
8
|
+
#include "JSObjectDecorator.h"
|
|
5
9
|
#include "JSClassesDecorator.h"
|
|
6
10
|
#include "../types/ReturnType.h"
|
|
7
11
|
|
|
8
12
|
namespace expo {
|
|
9
13
|
|
|
14
|
+
JSDecoratorsBridgingObject::~JSDecoratorsBridgingObject() = default;
|
|
15
|
+
|
|
16
|
+
JSClassesDecorator* JSDecoratorsBridgingObject::getClassDecorator() const {
|
|
17
|
+
return classDecorator.get();
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
jni::local_ref<jni::HybridClass<JSDecoratorsBridgingObject>::jhybriddata>
|
|
11
21
|
JSDecoratorsBridgingObject::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
|
12
22
|
return makeCxxInstance();
|
|
@@ -8,18 +8,20 @@
|
|
|
8
8
|
#include "../JNIFunctionBody.h"
|
|
9
9
|
#include "../types/ExpectedType.h"
|
|
10
10
|
|
|
11
|
-
#include "JSFunctionsDecorator.h"
|
|
12
|
-
#include "JSPropertiesDecorator.h"
|
|
13
|
-
#include "JSConstantsDecorator.h"
|
|
14
|
-
#include "JSObjectDecorator.h"
|
|
15
|
-
#include "JSClassesDecorator.h"
|
|
16
|
-
|
|
17
11
|
namespace jni = facebook::jni;
|
|
18
12
|
|
|
19
13
|
namespace expo {
|
|
20
14
|
|
|
15
|
+
class JSFunctionsDecorator;
|
|
16
|
+
class JSPropertiesDecorator;
|
|
17
|
+
class JSConstantsDecorator;
|
|
18
|
+
class JSObjectDecorator;
|
|
19
|
+
class JSClassesDecorator;
|
|
20
|
+
|
|
21
21
|
class JSDecoratorsBridgingObject : public jni::HybridClass<JSDecoratorsBridgingObject> {
|
|
22
22
|
public:
|
|
23
|
+
~JSDecoratorsBridgingObject();
|
|
24
|
+
|
|
23
25
|
static auto constexpr
|
|
24
26
|
kJavaDescriptor = "Lexpo/modules/kotlin/jni/decorators/JSDecoratorsBridgingObject;";
|
|
25
27
|
static auto constexpr TAG = "JSDecoratorsBridgingObject";
|
|
@@ -87,9 +89,7 @@ public:
|
|
|
87
89
|
/**
|
|
88
90
|
* Returns the class decorator, or nullptr if none was registered.
|
|
89
91
|
*/
|
|
90
|
-
JSClassesDecorator* getClassDecorator() const
|
|
91
|
-
return classDecorator.get();
|
|
92
|
-
}
|
|
92
|
+
JSClassesDecorator* getClassDecorator() const;
|
|
93
93
|
|
|
94
94
|
private:
|
|
95
95
|
friend HybridBase;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include "ExpoComponentDescriptorFactory.h"
|
|
4
|
+
#include "AndroidExpoViewComponentDescriptor.h"
|
|
5
|
+
|
|
6
|
+
namespace react = facebook::react;
|
|
7
|
+
|
|
8
|
+
namespace expo {
|
|
9
|
+
|
|
10
|
+
StatePropMapType statePropMap = {};
|
|
11
|
+
|
|
12
|
+
react::ComponentDescriptor::Unique concreteExpoComponentDescriptorConstructor(
|
|
13
|
+
const react::ComponentDescriptorParameters ¶meters
|
|
14
|
+
) {
|
|
15
|
+
auto descriptor = std::make_unique<AndroidExpoViewComponentDescriptor>(
|
|
16
|
+
parameters,
|
|
17
|
+
react::RawPropsParser(/*useRawPropsJsiValue=*/true)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (statePropMap.contains(std::static_pointer_cast<std::string const>(parameters.flavor))) {
|
|
21
|
+
descriptor->setStateProps(
|
|
22
|
+
statePropMap.at(
|
|
23
|
+
std::static_pointer_cast<std::string const>(parameters.flavor)
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return descriptor;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace expo
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <react/renderer/core/ComponentDescriptor.h>
|
|
6
|
+
#include "../types/FrontendConverter.h"
|
|
7
|
+
|
|
8
|
+
namespace react = facebook::react;
|
|
9
|
+
|
|
10
|
+
namespace expo {
|
|
11
|
+
|
|
12
|
+
using StatePropMapType = std::unordered_map<
|
|
13
|
+
react::ComponentDescriptor::Flavor,
|
|
14
|
+
std::unordered_map<std::string, std::shared_ptr<FrontendConverter>>
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
extern StatePropMapType statePropMap;
|
|
18
|
+
|
|
19
|
+
react::ComponentDescriptor::Unique concreteExpoComponentDescriptorConstructor(
|
|
20
|
+
const react::ComponentDescriptorParameters ¶meters
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
} // namespace expo
|
|
@@ -1,38 +1,16 @@
|
|
|
1
1
|
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
#include "FabricComponentsRegistry.h"
|
|
4
|
+
#include "ExpoComponentDescriptorFactory.h"
|
|
4
5
|
#include "../types/FrontendConverterProvider.h"
|
|
6
|
+
#include <CoreComponentsRegistry.h>
|
|
7
|
+
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
|
|
5
8
|
|
|
6
9
|
namespace jni = facebook::jni;
|
|
7
10
|
namespace react = facebook::react;
|
|
8
11
|
|
|
9
12
|
namespace expo {
|
|
10
13
|
|
|
11
|
-
#pragma clang diagnostic push
|
|
12
|
-
#pragma clang diagnostic ignored "-Wextern-initializer"
|
|
13
|
-
// Clang think that we don't need to initialize the extern variable here, but we do.
|
|
14
|
-
extern StatePropMapType statePropMap = {};
|
|
15
|
-
#pragma clang diagnostic pop
|
|
16
|
-
|
|
17
|
-
AndroidExpoViewComponentDescriptor::Unique concreteExpoComponentDescriptorConstructor(
|
|
18
|
-
const react::ComponentDescriptorParameters ¶meters
|
|
19
|
-
) {
|
|
20
|
-
auto descriptor = std::make_unique<AndroidExpoViewComponentDescriptor>(
|
|
21
|
-
parameters,
|
|
22
|
-
react::RawPropsParser(/*useRawPropsJsiValue=*/true)
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
if (statePropMap.contains(std::static_pointer_cast<std::string const>(parameters.flavor))) {
|
|
26
|
-
descriptor->setStateProps(
|
|
27
|
-
statePropMap.at(
|
|
28
|
-
std::static_pointer_cast<std::string const>(parameters.flavor)
|
|
29
|
-
)
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return descriptor;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
14
|
// static
|
|
37
15
|
void FabricComponentsRegistry::registerNatives() {
|
|
38
16
|
registerHybrid({
|
|
@@ -3,29 +3,12 @@
|
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
5
|
#include "../ExpoHeader.pch"
|
|
6
|
-
#include <CoreComponentsRegistry.h>
|
|
7
|
-
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
|
|
8
|
-
|
|
9
6
|
#include "../types/ExpectedType.h"
|
|
10
|
-
#include "../types/FrontendConverter.h"
|
|
11
|
-
#include "AndroidExpoViewComponentDescriptor.h"
|
|
12
7
|
|
|
13
8
|
namespace jni = facebook::jni;
|
|
14
|
-
namespace react = facebook::react;
|
|
15
9
|
|
|
16
10
|
namespace expo {
|
|
17
11
|
|
|
18
|
-
typedef std::unordered_map<
|
|
19
|
-
AndroidExpoViewComponentDescriptor::Flavor,
|
|
20
|
-
std::unordered_map<std::string, std::shared_ptr<FrontendConverter>>
|
|
21
|
-
> StatePropMapType;
|
|
22
|
-
|
|
23
|
-
extern StatePropMapType statePropMap;
|
|
24
|
-
|
|
25
|
-
AndroidExpoViewComponentDescriptor::Unique concreteExpoComponentDescriptorConstructor(
|
|
26
|
-
const react::ComponentDescriptorParameters ¶meters
|
|
27
|
-
);
|
|
28
|
-
|
|
29
12
|
class FabricComponentsRegistry : public jni::HybridClass<FabricComponentsRegistry> {
|
|
30
13
|
public:
|
|
31
14
|
static auto constexpr
|
|
@@ -5,6 +5,7 @@ package expo.modules.kotlin.devtools.cdp
|
|
|
5
5
|
import expo.modules.kotlin.devtools.ExpoNetworkInspectOkHttpNetworkInterceptor
|
|
6
6
|
import expo.modules.kotlin.devtools.toSingleMap
|
|
7
7
|
import okio.Buffer
|
|
8
|
+
import org.json.JSONArray
|
|
8
9
|
import org.json.JSONObject
|
|
9
10
|
import java.math.BigDecimal
|
|
10
11
|
|
|
@@ -155,7 +156,7 @@ data class RequestWillBeSentParams(
|
|
|
155
156
|
|
|
156
157
|
data class RequestWillBeSentExtraInfoParams(
|
|
157
158
|
val requestId: RequestId,
|
|
158
|
-
val associatedCookies:
|
|
159
|
+
val associatedCookies: List<Any> = emptyList(),
|
|
159
160
|
val headers: Headers,
|
|
160
161
|
val connectTiming: ConnectTiming
|
|
161
162
|
) : JsonSerializable {
|
|
@@ -168,7 +169,7 @@ data class RequestWillBeSentExtraInfoParams(
|
|
|
168
169
|
override fun toJSONObject(): JSONObject {
|
|
169
170
|
return JSONObject().apply {
|
|
170
171
|
put("requestId", requestId)
|
|
171
|
-
put("associatedCookies",
|
|
172
|
+
put("associatedCookies", JSONArray(associatedCookies))
|
|
172
173
|
put("headers", JSONObject(headers))
|
|
173
174
|
put("connectTiming", connectTiming.toJSONObject())
|
|
174
175
|
}
|
|
@@ -41,20 +41,42 @@ open class SharedObject(runtime: Runtime? = null) {
|
|
|
41
41
|
)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Emits an event with no payload to the associated JavaScript object.
|
|
46
|
+
*/
|
|
47
|
+
fun emit(event: String) {
|
|
48
|
+
emitInternal(event, emptyArray())
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Emits an event with a single payload to the associated JavaScript object.
|
|
53
|
+
*/
|
|
54
|
+
fun emit(event: String, payload: Any?) {
|
|
55
|
+
emitInternal(event, arrayOf(payload))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Deprecated(
|
|
59
|
+
"Multi-argument event emission is deprecated. Use `emit(event)` or `emit(event, payload)` and pass a single payload (typically a Map/Bundle) instead.",
|
|
60
|
+
ReplaceWith("emit(event, args)")
|
|
61
|
+
)
|
|
62
|
+
fun emit(event: String, vararg args: Any?) {
|
|
63
|
+
emitInternal(event, args)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private fun emitInternal(event: String, payload: Array<out Any?>) {
|
|
45
67
|
val jsObject = getJavaScriptObject() ?: return
|
|
46
68
|
val jniInterop = runtime?.jsiContext ?: return
|
|
47
69
|
try {
|
|
48
70
|
JNIUtils.emitEvent(
|
|
49
71
|
jsObject,
|
|
50
72
|
jniInterop,
|
|
51
|
-
|
|
52
|
-
|
|
73
|
+
event,
|
|
74
|
+
payload
|
|
53
75
|
.map { JSTypeConverterProvider.convertToJSValue(it, useExperimentalConverter = true) }
|
|
54
76
|
.toTypedArray()
|
|
55
77
|
)
|
|
56
78
|
} catch (e: Throwable) {
|
|
57
|
-
logger.error("Unable to send event '$
|
|
79
|
+
logger.error("Unable to send event '$event' by shared object of type ${this::class.java.simpleName}", e)
|
|
58
80
|
}
|
|
59
81
|
}
|
|
60
82
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package expo.modules.kotlin.views
|
|
2
|
+
|
|
3
|
+
import android.os.Handler
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.view.View
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Runs a callback only when a view is attached after staying detached through one main-loop turn.
|
|
9
|
+
* React Native can synchronously detach and reattach native children during view reparenting, and
|
|
10
|
+
* those moves should not be treated like a full detach.
|
|
11
|
+
*/
|
|
12
|
+
internal class OnAttachAfterDetachmentListener(
|
|
13
|
+
private val onAttachAfterDetachment: () -> Unit,
|
|
14
|
+
private val post: (Runnable) -> Unit = { runnable ->
|
|
15
|
+
Handler(Looper.getMainLooper()).post(runnable)
|
|
16
|
+
}
|
|
17
|
+
) : View.OnAttachStateChangeListener {
|
|
18
|
+
private var shouldRunOnAttach = false
|
|
19
|
+
private var detachGeneration = 0
|
|
20
|
+
|
|
21
|
+
override fun onViewAttachedToWindow(v: View) {
|
|
22
|
+
detachGeneration += 1
|
|
23
|
+
|
|
24
|
+
if (shouldRunOnAttach) {
|
|
25
|
+
shouldRunOnAttach = false
|
|
26
|
+
onAttachAfterDetachment()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun onViewDetachedFromWindow(v: View) {
|
|
31
|
+
val generation = ++detachGeneration
|
|
32
|
+
|
|
33
|
+
post(
|
|
34
|
+
Runnable {
|
|
35
|
+
if (detachGeneration == generation && !v.isAttachedToWindow) {
|
|
36
|
+
shouldRunOnAttach = true
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoreModule.d.ts","sourceRoot":"","sources":["../../src/polyfill/CoreModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,IAAI,gBAAgB,EAChC,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE/E,qBAAa,YAAY,CAAC,UAAU,SAAS,SAAS,CAAE,YAAW,gBAAgB;IACjF,OAAO,CAAC,SAAS,CAAC,CAAuC;IAEzD,WAAW,CAAC,SAAS,SAAS,MAAM,UAAU,EAC5C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,GAC9B,iBAAiB;IAuBpB,cAAc,CAAC,SAAS,SAAS,MAAM,UAAU,EAC/C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,GAC9B,IAAI;IAOP,kBAAkB,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAQlF,IAAI,CAAC,SAAS,SAAS,MAAM,UAAU,EACrC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GACzC,IAAI;IAeP,aAAa,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM;IAI/E,cAAc,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAE9E,aAAa,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;CAC9E;AAED,qBAAa,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/D,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,gBAAgB;IAE3B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/D,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,gBAAgB;IAE3B,OAAO,IAAI,IAAI;CAGhB;AAED,qBAAa,SAAS,
|
|
1
|
+
{"version":3,"file":"CoreModule.d.ts","sourceRoot":"","sources":["../../src/polyfill/CoreModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,IAAI,gBAAgB,EAChC,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE/E,qBAAa,YAAY,CAAC,UAAU,SAAS,SAAS,CAAE,YAAW,gBAAgB;IACjF,OAAO,CAAC,SAAS,CAAC,CAAuC;IAEzD,WAAW,CAAC,SAAS,SAAS,MAAM,UAAU,EAC5C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,GAC9B,iBAAiB;IAuBpB,cAAc,CAAC,SAAS,SAAS,MAAM,UAAU,EAC/C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,GAC9B,IAAI;IAOP,kBAAkB,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAQlF,IAAI,CAAC,SAAS,SAAS,MAAM,UAAU,EACrC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GACzC,IAAI;IAeP,aAAa,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM;IAI/E,cAAc,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAE9E,aAAa,CAAC,SAAS,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;CAC9E;AAED,qBAAa,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/D,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,gBAAgB;IAE3B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/D,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,gBAAgB;IAE3B,OAAO,IAAI,IAAI;CAGhB;AAED,qBAAa,SAAS,CACpB,cAAc,SAAS,MAAM,GAAG,SAAS,EACzC,UAAU,SAAS,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAEnD,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,aAAa,CAAC,cAAc,CAAC;IAExC,aAAa,EAAE,MAAM,CAAa;CACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedRef.d.ts","sourceRoot":"","sources":["../../src/ts-declarations/SharedRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,SAAS,
|
|
1
|
+
{"version":3,"file":"SharedRef.d.ts","sourceRoot":"","sources":["../../src/ts-declarations/SharedRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,SAAS,CAC5B,cAAc,SAAS,MAAM,GAAG,SAAS,EACzC,UAAU,SAAS,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAEnD,SAAQ,YAAY,CAAC,UAAU,CAC/B,YAAW,YAAY,CAAC,UAAU,CAAC;IAEnC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,cAAc,CAAC;IAE7C;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Keep in sync with `@expo/expo-modules-macros-plugin/apple/Sources/ExpoModulesOptimized/ExpoModulesOptimized.swift`.
|
|
5
|
-
*/
|
|
1
|
+
// Declares macro signatures whose implementations are provided by the `ExpoModulesMacros` compiler
|
|
2
|
+
// plugin shipped in the `@expo/expo-modules-macros-plugin` package. Keep the `#externalMacro`
|
|
3
|
+
// module/type names below in sync with the macro implementations in that package.
|
|
6
4
|
|
|
7
5
|
// MARK: - Macro declarations
|
|
8
6
|
|
|
@@ -25,3 +23,64 @@
|
|
|
25
23
|
@attached(peer, names: arbitrary)
|
|
26
24
|
public macro OptimizedFunction() =
|
|
27
25
|
#externalMacro(module: "ExpoModulesMacros", type: "OptimizedFunctionAttachedMacro")
|
|
26
|
+
|
|
27
|
+
/// Marker macro applied to module / shared-object members that should be exposed to JavaScript.
|
|
28
|
+
/// The accompanying `@ExpoModule` and `@SharedObject` macros discover `@JS`-marked declarations
|
|
29
|
+
/// and generate the matching `Function` / `AsyncFunction` / `Property` / `Constructor` registrations.
|
|
30
|
+
///
|
|
31
|
+
/// Usage:
|
|
32
|
+
///
|
|
33
|
+
/// @JS
|
|
34
|
+
/// func greet(name: String) -> String { ... }
|
|
35
|
+
///
|
|
36
|
+
/// @JS("doWork")
|
|
37
|
+
/// func performWork() async throws { ... }
|
|
38
|
+
///
|
|
39
|
+
/// @JS
|
|
40
|
+
/// var status: String { "ok" }
|
|
41
|
+
@attached(peer)
|
|
42
|
+
public macro JS(_ jsName: String? = nil) =
|
|
43
|
+
#externalMacro(module: "ExpoModulesMacros", type: "JSMacro")
|
|
44
|
+
|
|
45
|
+
/// Member macro applied to a `Module` subclass. Scans the class body for declarations
|
|
46
|
+
/// marked with `@JS` and synthesizes a framework-internal `_exposedDefinition()` method.
|
|
47
|
+
/// `expo-modules-core` calls it automatically and merges the result into the module's
|
|
48
|
+
/// definition, so the user doesn't have to reference it from `definition()`.
|
|
49
|
+
///
|
|
50
|
+
/// Usage:
|
|
51
|
+
///
|
|
52
|
+
/// @ExpoModule
|
|
53
|
+
/// public final class MyModule: Module {
|
|
54
|
+
/// public func definition() -> ModuleDefinition {
|
|
55
|
+
/// Name("MyModule")
|
|
56
|
+
/// }
|
|
57
|
+
///
|
|
58
|
+
/// @JS
|
|
59
|
+
/// func greet(name: String) -> String { "Hi, \(name)" }
|
|
60
|
+
/// }
|
|
61
|
+
@attached(member, names: named(_exposedDefinition), named(appContext), named(init))
|
|
62
|
+
public macro ExpoModule(_ name: String? = nil, classes: [Any.Type] = []) =
|
|
63
|
+
#externalMacro(module: "ExpoModulesMacros", type: "ExpoModuleMacro")
|
|
64
|
+
|
|
65
|
+
/// Member macro applied to a `SharedObject` subclass. Scans the class body for declarations
|
|
66
|
+
/// marked with `@JS` (including a single `@JS init(...)` for the JS constructor) and
|
|
67
|
+
/// synthesizes a `_exposedClassDefinition()` static method returning a `ClassDefinition`.
|
|
68
|
+
/// The companion `@ExpoModule(classes: [Foo.self])` wires the class into the module's
|
|
69
|
+
/// exposed surface.
|
|
70
|
+
///
|
|
71
|
+
/// Usage:
|
|
72
|
+
///
|
|
73
|
+
/// @SharedObject
|
|
74
|
+
/// final class Cache: SharedObject {
|
|
75
|
+
/// @JS
|
|
76
|
+
/// init(name: String) { self.name = name }
|
|
77
|
+
///
|
|
78
|
+
/// @JS
|
|
79
|
+
/// func get(_ key: String) -> String? { ... }
|
|
80
|
+
///
|
|
81
|
+
/// @JS
|
|
82
|
+
/// var size: Int { 42 }
|
|
83
|
+
/// }
|
|
84
|
+
@attached(member, names: named(_exposedClassDefinition))
|
|
85
|
+
public macro SharedObject(_ name: String? = nil) =
|
|
86
|
+
#externalMacro(module: "ExpoModulesMacros", type: "SharedObjectMacro")
|
|
@@ -46,10 +46,28 @@ public final class ModuleHolder {
|
|
|
46
46
|
self.appContext = appContext
|
|
47
47
|
self._name = name
|
|
48
48
|
self.module = module
|
|
49
|
-
self.definition =
|
|
49
|
+
self.definition = ModuleHolder.buildDefinition(for: module)
|
|
50
50
|
post(event: .moduleCreate)
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/// Combines the user-authored definition with the entries synthesized by the
|
|
54
|
+
/// `@ExpoModule` macro on this module's class (if any). The macro emits a
|
|
55
|
+
/// `_exposedDefinition()` method returning an `[AnyDefinition]` array of the
|
|
56
|
+
/// `Function` / `Property` / `Constructor` entries it generated from `@JS`
|
|
57
|
+
/// members. Those entries are prepended to the user's definitions and the
|
|
58
|
+
/// whole list is fed back through `ModuleDefinition.init` so the merged
|
|
59
|
+
/// result is rebucketed (into `functions`, `properties`, etc.) just like a
|
|
60
|
+
/// hand-written definition. Modules that don't use the macro fall through
|
|
61
|
+
/// the empty-exposed fast path and return the user's definition unchanged.
|
|
62
|
+
private static func buildDefinition(for module: AnyModule) -> ModuleDefinition {
|
|
63
|
+
let userDefinition = module.definition()
|
|
64
|
+
let exposed = module._exposedDefinition()
|
|
65
|
+
if exposed.isEmpty {
|
|
66
|
+
return userDefinition
|
|
67
|
+
}
|
|
68
|
+
return ModuleDefinition(definitions: exposed + userDefinition.rawDefinitions)
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
// MARK: Constants
|
|
54
72
|
|
|
55
73
|
/**
|
|
@@ -29,10 +29,17 @@ public final class ModuleDefinition: ObjectDefinition {
|
|
|
29
29
|
|
|
30
30
|
let eventObservers: [AnyEventObservingDefinition]
|
|
31
31
|
|
|
32
|
+
/// The raw list of definitions used to construct this module. Retained so
|
|
33
|
+
/// that `ModuleHolder` can merge in the entries synthesized by the
|
|
34
|
+
/// `@ExpoModule` macro without losing the user-authored ones.
|
|
35
|
+
let rawDefinitions: [AnyDefinition]
|
|
36
|
+
|
|
32
37
|
/**
|
|
33
38
|
Initializer that is called by the `ModuleDefinitionBuilder` results builder.
|
|
34
39
|
*/
|
|
35
40
|
override init(definitions: [AnyDefinition]) {
|
|
41
|
+
self.rawDefinitions = definitions
|
|
42
|
+
|
|
36
43
|
self.name = definitions
|
|
37
44
|
.compactMap { $0 as? ModuleNameDefinition }
|
|
38
45
|
.last?
|
|
@@ -14,4 +14,16 @@ public protocol AnyModule: AnyObject, AnyArgument {
|
|
|
14
14
|
*/
|
|
15
15
|
@ModuleDefinitionBuilder
|
|
16
16
|
func definition() -> ModuleDefinition
|
|
17
|
+
|
|
18
|
+
/// Returns definitions synthesized from `@JS`-annotated members by the `@ExpoModule` macro.
|
|
19
|
+
/// Framework-internal: the leading underscore signals this is not part of the public API and
|
|
20
|
+
/// should only be called by `expo-modules-core` itself. Modules that don't use the macro fall
|
|
21
|
+
/// back to the default empty implementation.
|
|
22
|
+
func _exposedDefinition() -> [AnyDefinition]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public extension AnyModule {
|
|
26
|
+
func _exposedDefinition() -> [AnyDefinition] {
|
|
27
|
+
return []
|
|
28
|
+
}
|
|
17
29
|
}
|
|
@@ -66,66 +66,87 @@ open class SharedObject: AnySharedObject {
|
|
|
66
66
|
public func getJavaScriptObject() -> JavaScriptObject? {
|
|
67
67
|
return appContext?.sharedObjectRegistry.toJavaScriptObject(self)
|
|
68
68
|
}
|
|
69
|
-
}
|
|
70
69
|
|
|
71
|
-
// Unfortunately the `emit` function needs to be defined in the extension.
|
|
72
|
-
// When put in the class, pack expansion is crashing with `EXC_BAD_ACCESS` code.
|
|
73
|
-
// See https://github.com/apple/swift/issues/72381 for more details.
|
|
74
|
-
public extension SharedObject { // swiftlint:disable:this no_grouping_extension
|
|
75
|
-
// Parameter packs feature requires Swift 5.9 (Xcode 15.0), but some CIs and EAS images may still use older versions.
|
|
76
|
-
// As of April 29, all submissions must be made with Xcode 15, so hopefully we can remove this condition soon.
|
|
77
|
-
// No one should use <15.0 these days.
|
|
78
|
-
#if swift(>=5.9)
|
|
79
70
|
/**
|
|
80
|
-
Schedules an event with the given name and
|
|
71
|
+
Schedules an event with the given name and a pre-converted JavaScript payload to be emitted
|
|
72
|
+
to the associated JavaScript object. This is the lowest-level emit overload — use it when the
|
|
73
|
+
value is already a `JavaScriptValue` to skip the native-to-JS conversion step.
|
|
81
74
|
*/
|
|
82
|
-
func emit
|
|
75
|
+
public func emit(event: String, payload: JavaScriptValue) {
|
|
83
76
|
guard let appContext, let runtime = try? appContext.runtime else {
|
|
84
77
|
log.warn("Trying to send event '\(event)' to \(type(of: self)), but the JS runtime has been lost")
|
|
85
78
|
return
|
|
86
79
|
}
|
|
80
|
+
guard let jsValue = getJavaScriptValue() else {
|
|
81
|
+
log.warn("Trying to send event '\(event)' to JS, but the JS object is no longer associated with the native instance")
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
runtime.schedule {
|
|
85
|
+
dispatch(event: event, payload: payload, to: jsValue, in: runtime)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
/**
|
|
90
|
+
Schedules an event with the given name to be emitted to the associated JavaScript object.
|
|
91
|
+
*/
|
|
92
|
+
public func emit(event: String) {
|
|
93
|
+
emit(event: event, payload: .undefined)
|
|
94
|
+
}
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
/**
|
|
97
|
+
Schedules an event with the given name and payload to be emitted to the associated JavaScript object.
|
|
98
|
+
*/
|
|
99
|
+
public func emit<P: AnyArgument>(event: String, payload: sending P) {
|
|
100
|
+
guard let appContext, let runtime = try? appContext.runtime else {
|
|
101
|
+
log.warn("Trying to send event '\(event)' to \(type(of: self)), but the JS runtime has been lost")
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
guard let jsValue = getJavaScriptValue() else {
|
|
105
|
+
log.warn("Trying to send event '\(event)' to JS, but the JS object is no longer associated with the native instance")
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
runtime.schedule { [weak appContext] in
|
|
109
|
+
guard let appContext else {
|
|
96
110
|
return
|
|
97
111
|
}
|
|
98
|
-
|
|
99
|
-
// Convert native arguments to JS, just like function results
|
|
100
|
-
let jsArguments: [JavaScriptValue]
|
|
101
112
|
do {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
113
|
+
let jsPayload = try (~P.self).castToJS(payload, appContext: appContext, in: runtime)
|
|
114
|
+
dispatch(event: event, payload: jsPayload, to: jsValue, in: runtime)
|
|
105
115
|
} catch {
|
|
106
|
-
log.warn("Failed to convert
|
|
116
|
+
log.warn("Failed to convert payload for event '\(event)' on \(P.self); the event will not be emitted: \(error)")
|
|
107
117
|
return
|
|
108
118
|
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
/**
|
|
123
|
+
Backwards-compatible overload that forwards to `emit(event:payload:)`. Existing single-argument
|
|
124
|
+
call sites keep working unchanged; the parameter has been renamed to `payload` to make the
|
|
125
|
+
single-payload semantics explicit, so callers should migrate the label.
|
|
126
|
+
*/
|
|
127
|
+
@available(*, deprecated, renamed: "emit(event:payload:)", message: "Use `emit(event:payload:)` and pass a single value (typically a dictionary). Multi-argument event emission is no longer supported.")
|
|
128
|
+
public func emit<P: AnyArgument>(event: String, arguments: sending P) {
|
|
129
|
+
emit(event: event, payload: arguments)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
Sends a pre-converted event payload to the given JavaScript object via the JSI emitter helper.
|
|
135
|
+
Must run on the JS thread; the public `emit` overloads schedule onto the runtime before calling in.
|
|
136
|
+
*/
|
|
137
|
+
@JavaScriptActor
|
|
138
|
+
private func dispatch(event: String, payload: JavaScriptValue, to value: JavaScriptValue, in runtime: JavaScriptRuntime) {
|
|
139
|
+
runtime.withUnsafePointee { runtimePtr in
|
|
140
|
+
value.withUnsafePointee { objectPtr in
|
|
141
|
+
payload.withUnsafePointee { payloadPtr in
|
|
142
|
+
JSUtils.emitEvent(
|
|
143
|
+
event,
|
|
144
|
+
runtimePointer: runtimePtr,
|
|
145
|
+
objectPointer: objectPtr,
|
|
146
|
+
argumentsPointer: payloadPtr,
|
|
147
|
+
argumentCount: 1
|
|
148
|
+
)
|
|
122
149
|
}
|
|
123
150
|
}
|
|
124
151
|
}
|
|
125
|
-
#else // swift(>=5.9)
|
|
126
|
-
@available(*, unavailable, message: "Unavailable in Xcode <15.0")
|
|
127
|
-
public func emit(event: String, arguments: AnyArgument...) {
|
|
128
|
-
fatalError("Emitting events to JS requires at least Xcode 15.0")
|
|
129
|
-
}
|
|
130
|
-
#endif // swift(<5.9)
|
|
131
152
|
}
|
|
@@ -110,7 +110,7 @@ struct CdpNetwork {
|
|
|
110
110
|
|
|
111
111
|
struct RequestWillBeSentExtraInfoParams: EventParams {
|
|
112
112
|
let requestId: RequestId
|
|
113
|
-
var associatedCookies = [String
|
|
113
|
+
var associatedCookies = [String]()
|
|
114
114
|
let headers: Headers
|
|
115
115
|
let connectTiming: ConnectTiming
|
|
116
116
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "56.0.
|
|
3
|
+
"version": "56.0.9",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"preset": "expo-module-scripts"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@expo/expo-modules-macros-plugin": "~0.0.
|
|
50
|
-
"expo-modules-jsi": "~56.0.
|
|
49
|
+
"@expo/expo-modules-macros-plugin": "~0.0.9",
|
|
50
|
+
"expo-modules-jsi": "~56.0.5",
|
|
51
51
|
"invariant": "^2.2.4"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@types/invariant": "^2.2.33",
|
|
67
67
|
"expo-module-scripts": "56.0.2"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "f26be3dd9396bf7c399a1d607865d0fabdbc0d64",
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "expo-module build",
|
|
72
72
|
"clean": "expo-module clean",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -100,9 +100,9 @@ export class SharedObject<TEventsMap extends Record<never, never>>
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export class SharedRef<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
TNativeRefType extends string = 'unknown',
|
|
104
|
+
TEventsMap extends EventsMap = Record<never, never>,
|
|
105
|
+
>
|
|
106
106
|
extends SharedObject<TEventsMap>
|
|
107
107
|
implements SharedRefType<TNativeRefType>
|
|
108
108
|
{
|
|
@@ -11,9 +11,9 @@ import type { SharedObject } from './SharedObject';
|
|
|
11
11
|
* directly to the image view from `expo-image` without any additional writes and reads from the file system.
|
|
12
12
|
*/
|
|
13
13
|
export declare class SharedRef<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
TNativeRefType extends string = 'unknown',
|
|
15
|
+
TEventsMap extends EventsMap = Record<never, never>,
|
|
16
|
+
>
|
|
17
17
|
extends SharedObject<TEventsMap>
|
|
18
18
|
implements SharedObject<TEventsMap>
|
|
19
19
|
{
|