expo-modules-core 55.0.3 → 55.0.5
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 +10 -0
- package/android/build.gradle +2 -2
- package/android/src/main/cpp/JSIContext.cpp +14 -2
- package/android/src/main/cpp/JSIContext.h +5 -14
- package/android/src/main/cpp/JavaScriptFunction.cpp +4 -12
- package/android/src/main/cpp/JavaScriptFunction.h +1 -1
- package/android/src/main/cpp/JavaScriptRuntime.cpp +1 -5
- package/android/src/main/cpp/JavaScriptRuntime.h +7 -1
- package/android/src/main/cpp/types/JNIToJSIConverter.h +18 -0
- package/android/src/main/cpp/worklets/Worklet.cpp +59 -2
- package/android/src/main/cpp/worklets/Worklet.h +14 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -4
- package/android/src/main/java/expo/modules/kotlin/jni/PromiseImpl.kt +5 -5
- package/android/src/main/java/expo/modules/kotlin/jni/worklets/Worklet.kt +33 -0
- package/ios/Core/Objects/ConstantDefinition.swift +9 -0
- package/ios/DevTools/ModuleDefinitionEncoder.swift +11 -14
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 55.0.5 — 2026-01-27
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
17
|
+
## 55.0.4 — 2026-01-26
|
|
18
|
+
|
|
19
|
+
### 🐛 Bug fixes
|
|
20
|
+
|
|
21
|
+
- [Android] Added missing checks in the promise implementation. ([#42467](https://github.com/expo/expo/pull/42467) by [@lukmccall](https://github.com/lukmccall))
|
|
22
|
+
|
|
13
23
|
## 55.0.3 — 2026-01-22
|
|
14
24
|
|
|
15
25
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -29,7 +29,7 @@ if (shouldIncludeCompose) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
group = 'host.exp.exponent'
|
|
32
|
-
version = '55.0.
|
|
32
|
+
version = '55.0.5'
|
|
33
33
|
|
|
34
34
|
def isExpoModulesCoreTests = {
|
|
35
35
|
Gradle gradle = getGradle()
|
|
@@ -96,7 +96,7 @@ android {
|
|
|
96
96
|
defaultConfig {
|
|
97
97
|
consumerProguardFiles 'proguard-rules.pro'
|
|
98
98
|
versionCode 1
|
|
99
|
-
versionName "55.0.
|
|
99
|
+
versionName "55.0.5"
|
|
100
100
|
buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
|
|
101
101
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
|
|
102
102
|
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
#include <fbjni/fbjni.h>
|
|
14
14
|
|
|
15
15
|
#include <memory>
|
|
16
|
+
#include <shared_mutex>
|
|
16
17
|
|
|
17
18
|
namespace jni = facebook::jni;
|
|
18
19
|
namespace jsi = facebook::jsi;
|
|
19
20
|
|
|
20
21
|
namespace expo {
|
|
21
22
|
|
|
22
|
-
|
|
23
23
|
void JSIContext::registerNatives() {
|
|
24
24
|
registerHybrid({
|
|
25
25
|
makeNativeMethod("evaluateScript", JSIContext::evaluateScript),
|
|
@@ -263,14 +263,26 @@ bool JSIContext::wasDeallocated() const noexcept {
|
|
|
263
263
|
return wasDeallocated_;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
std::unordered_map<uintptr_t, JSIContext *> jsiContexts;
|
|
266
|
+
static std::unordered_map<uintptr_t, JSIContext *> jsiContexts;
|
|
267
|
+
static std::shared_mutex jsiContextsMutex;
|
|
267
268
|
|
|
268
269
|
void bindJSIContext(const jsi::Runtime &runtime, JSIContext *jsiContext) {
|
|
270
|
+
std::unique_lock lock(jsiContextsMutex);
|
|
269
271
|
jsiContexts[reinterpret_cast<uintptr_t>(&runtime)] = jsiContext;
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
void unbindJSIContext(const jsi::Runtime &runtime) {
|
|
275
|
+
std::unique_lock lock(jsiContextsMutex);
|
|
273
276
|
jsiContexts.erase(reinterpret_cast<uintptr_t>(&runtime));
|
|
274
277
|
}
|
|
275
278
|
|
|
279
|
+
JSIContext *getJSIContext(const jsi::Runtime &runtime) {
|
|
280
|
+
std::shared_lock lock(jsiContextsMutex);
|
|
281
|
+
const auto iterator = jsiContexts.find(reinterpret_cast<uintptr_t>(&runtime));
|
|
282
|
+
if (iterator == jsiContexts.end()) {
|
|
283
|
+
throw std::invalid_argument("JSIContext for the given runtime doesn't exist");
|
|
284
|
+
}
|
|
285
|
+
return iterator->second;
|
|
286
|
+
}
|
|
287
|
+
|
|
276
288
|
} // namespace expo
|
|
@@ -167,14 +167,9 @@ private:
|
|
|
167
167
|
) noexcept;
|
|
168
168
|
};
|
|
169
169
|
|
|
170
|
-
/**
|
|
171
|
-
* We are binding the JSIContext to the runtime using a thread-local map.
|
|
172
|
-
* This is a simplification of how we're accessing the JSIContext from different places.
|
|
173
|
-
*/
|
|
174
|
-
extern std::unordered_map<uintptr_t, JSIContext *> jsiContexts;
|
|
175
|
-
|
|
176
170
|
/**
|
|
177
171
|
* Binds the JSIContext to the runtime.
|
|
172
|
+
* Thread-safe: uses exclusive lock.
|
|
178
173
|
* @param runtime
|
|
179
174
|
* @param jsiContext
|
|
180
175
|
*/
|
|
@@ -182,22 +177,18 @@ void bindJSIContext(const jsi::Runtime &runtime, JSIContext *jsiContext);
|
|
|
182
177
|
|
|
183
178
|
/**
|
|
184
179
|
* Unbinds the JSIContext from the runtime.
|
|
180
|
+
* Thread-safe: uses exclusive lock.
|
|
185
181
|
* @param runtime
|
|
186
182
|
*/
|
|
187
183
|
void unbindJSIContext(const jsi::Runtime &runtime);
|
|
188
184
|
|
|
189
185
|
/**
|
|
190
186
|
* Gets the JSIContext for the given runtime.
|
|
187
|
+
* Thread-safe: uses exclusive lock.
|
|
191
188
|
* @param runtime
|
|
192
189
|
* @return JSIContext * - it should never be stored when received from this function.
|
|
193
|
-
*
|
|
190
|
+
* @throws std::invalid_argument if the JSIContext for the given runtime doesn't exist.
|
|
194
191
|
*/
|
|
195
|
-
|
|
196
|
-
const auto iterator = jsiContexts.find(reinterpret_cast<uintptr_t>(&runtime));
|
|
197
|
-
if (iterator == jsiContexts.end()) {
|
|
198
|
-
throw std::invalid_argument("JSIContext for the given runtime doesn't exist");
|
|
199
|
-
}
|
|
200
|
-
return iterator->second;
|
|
201
|
-
}
|
|
192
|
+
JSIContext *getJSIContext(const jsi::Runtime &runtime);
|
|
202
193
|
|
|
203
194
|
} // namespace expo
|
|
@@ -27,7 +27,7 @@ std::shared_ptr<jsi::Function> JavaScriptFunction::get() {
|
|
|
27
27
|
|
|
28
28
|
jobject JavaScriptFunction::invoke(
|
|
29
29
|
jni::alias_ref<JavaScriptObject::javaobject> jsThis,
|
|
30
|
-
jni::alias_ref<jni::JArrayClass<
|
|
30
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args,
|
|
31
31
|
jni::alias_ref<ExpectedType::javaobject> expectedReturnType
|
|
32
32
|
) {
|
|
33
33
|
auto runtime = runtimeHolder.lock();
|
|
@@ -35,28 +35,20 @@ jobject JavaScriptFunction::invoke(
|
|
|
35
35
|
auto &rawRuntime = runtime->get();
|
|
36
36
|
|
|
37
37
|
JNIEnv *env = jni::Environment::current();
|
|
38
|
-
|
|
39
|
-
size_t size = args->size();
|
|
40
|
-
std::vector<jsi::Value> convertedArgs;
|
|
41
|
-
convertedArgs.reserve(size);
|
|
42
|
-
|
|
43
|
-
for (size_t i = 0; i < size; i++) {
|
|
44
|
-
jni::local_ref<jobject> arg = args->getElement(i);
|
|
45
|
-
convertedArgs.push_back(convert(env, rawRuntime, arg));
|
|
46
|
-
}
|
|
38
|
+
std::vector<jsi::Value> convertedArgs = convertArray(env, rawRuntime, args);
|
|
47
39
|
|
|
48
40
|
// TODO(@lukmccall): add better error handling
|
|
49
41
|
jsi::Value result = jsThis == nullptr ?
|
|
50
42
|
jsFunction->call(
|
|
51
43
|
rawRuntime,
|
|
52
44
|
(const jsi::Value *) convertedArgs.data(),
|
|
53
|
-
size
|
|
45
|
+
convertedArgs.size()
|
|
54
46
|
) :
|
|
55
47
|
jsFunction->callWithThis(
|
|
56
48
|
rawRuntime,
|
|
57
49
|
*(jsThis->cthis()->get()),
|
|
58
50
|
(const jsi::Value *) convertedArgs.data(),
|
|
59
|
-
size
|
|
51
|
+
convertedArgs.size()
|
|
60
52
|
);
|
|
61
53
|
|
|
62
54
|
auto converter = AnyType(jni::make_local(expectedReturnType)).converter;
|
|
@@ -49,7 +49,7 @@ private:
|
|
|
49
49
|
|
|
50
50
|
jobject invoke(
|
|
51
51
|
jni::alias_ref<jni::HybridClass<JavaScriptObject, Destructible>::javaobject> jsThis,
|
|
52
|
-
jni::alias_ref<jni::JArrayClass<
|
|
52
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args,
|
|
53
53
|
jni::alias_ref<ExpectedType::javaobject> expectedReturnType
|
|
54
54
|
);
|
|
55
55
|
};
|
|
@@ -14,11 +14,7 @@ namespace expo {
|
|
|
14
14
|
JavaScriptRuntime::JavaScriptRuntime(
|
|
15
15
|
jsi::Runtime *runtime,
|
|
16
16
|
std::shared_ptr<react::CallInvoker> jsInvoker
|
|
17
|
-
) : jsInvoker(std::move(jsInvoker)) {
|
|
18
|
-
// Creating a shared pointer that points to the runtime but doesn't own it, thus doesn't release it.
|
|
19
|
-
// In this code flow, the runtime should be owned by something else like the CatalystInstance.
|
|
20
|
-
// See explanation for constructor (8): https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
|
|
21
|
-
this->runtime = std::shared_ptr<jsi::Runtime>(std::shared_ptr<jsi::Runtime>(), runtime);
|
|
17
|
+
) : jsInvoker(std::move(jsInvoker)), runtime(runtime) {
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
jsi::Runtime &JavaScriptRuntime::get() const noexcept {
|
|
@@ -76,6 +76,12 @@ public:
|
|
|
76
76
|
std::shared_ptr<react::CallInvoker> jsInvoker;
|
|
77
77
|
|
|
78
78
|
private:
|
|
79
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Raw pointer to the runtime. We do not own this - it's managed by React Native.
|
|
81
|
+
* The runtime's lifetime is guaranteed to exceed JavaScriptRuntime's lifetime,
|
|
82
|
+
* as JSIContext::prepareForDeallocation() invalidates all weak references before
|
|
83
|
+
* the runtime is deallocated.
|
|
84
|
+
*/
|
|
85
|
+
jsi::Runtime *runtime;
|
|
80
86
|
};
|
|
81
87
|
} // namespace expo
|
|
@@ -32,6 +32,24 @@ jsi::Value convert(
|
|
|
32
32
|
const jni::local_ref<jobject> &value
|
|
33
33
|
);
|
|
34
34
|
|
|
35
|
+
template<typename RefType>
|
|
36
|
+
std::vector<jsi::Value> convertArray(
|
|
37
|
+
JNIEnv *env,
|
|
38
|
+
jsi::Runtime &rt,
|
|
39
|
+
RefType &values
|
|
40
|
+
) {
|
|
41
|
+
size_t size = values->size();
|
|
42
|
+
std::vector<jsi::Value> convertedValues;
|
|
43
|
+
convertedValues.reserve(size);
|
|
44
|
+
|
|
45
|
+
for (size_t i = 0; i < size; i++) {
|
|
46
|
+
jni::local_ref<jobject> value = values->getElement(i);
|
|
47
|
+
convertedValues.push_back(convert(env, rt, value));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return convertedValues;
|
|
51
|
+
}
|
|
52
|
+
|
|
35
53
|
/**
|
|
36
54
|
* Convert a string with FollyDynamicExtensionConverter support.
|
|
37
55
|
*/
|
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
#if WORKLETS_ENABLED
|
|
4
4
|
|
|
5
|
+
#include "../types/JNIToJSIConverter.h"
|
|
6
|
+
|
|
5
7
|
namespace expo {
|
|
6
8
|
|
|
7
9
|
void Worklet::registerNatives() {
|
|
8
10
|
javaClassLocal()->registerNatives({
|
|
9
11
|
makeNativeMethod("schedule", Worklet::schedule),
|
|
12
|
+
makeNativeMethod("schedule", Worklet::scheduleWithArgs),
|
|
10
13
|
makeNativeMethod("execute", Worklet::execute),
|
|
14
|
+
makeNativeMethod("execute", Worklet::executeWithArgs),
|
|
11
15
|
});
|
|
12
16
|
}
|
|
13
17
|
|
|
@@ -17,7 +21,10 @@ void Worklet::schedule(
|
|
|
17
21
|
jni::alias_ref<Serializable::javaobject> synchronizable
|
|
18
22
|
) {
|
|
19
23
|
auto workletRuntime = workletRuntimeHolder->cthis()->workletRuntime.lock();
|
|
20
|
-
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
24
|
+
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
25
|
+
synchronizable->cthis()->getSerializable()
|
|
26
|
+
);
|
|
27
|
+
|
|
21
28
|
workletRuntime->schedule(std::move(worklet));
|
|
22
29
|
}
|
|
23
30
|
|
|
@@ -27,11 +34,61 @@ void Worklet::execute(
|
|
|
27
34
|
jni::alias_ref<Serializable::javaobject> synchronizable
|
|
28
35
|
) {
|
|
29
36
|
auto workletRuntime = workletRuntimeHolder->cthis()->workletRuntime.lock();
|
|
30
|
-
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
37
|
+
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
38
|
+
synchronizable->cthis()->getSerializable()
|
|
39
|
+
);
|
|
31
40
|
|
|
32
41
|
workletRuntime->runSync(worklet);
|
|
33
42
|
}
|
|
34
43
|
|
|
44
|
+
void Worklet::scheduleWithArgs(
|
|
45
|
+
jni::alias_ref<Worklet::javaobject> self,
|
|
46
|
+
jni::alias_ref<WorkletNativeRuntime::javaobject> workletRuntimeHolder,
|
|
47
|
+
jni::alias_ref<Serializable::javaobject> synchronizable,
|
|
48
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args
|
|
49
|
+
) {
|
|
50
|
+
auto workletRuntime = workletRuntimeHolder->cthis()->workletRuntime.lock();
|
|
51
|
+
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
52
|
+
synchronizable->cthis()->getSerializable()
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
workletRuntime->schedule([&worklet, globalArgs = jni::make_global(args)](jsi::Runtime &rt) mutable {
|
|
56
|
+
JNIEnv *env = jni::Environment::current();
|
|
57
|
+
std::vector<jsi::Value> convertedArgs = convertArray(env, rt, globalArgs);
|
|
58
|
+
|
|
59
|
+
auto func = worklet->toJSValue(rt).asObject(rt).asFunction(rt);
|
|
60
|
+
func.call(
|
|
61
|
+
rt,
|
|
62
|
+
(const jsi::Value *) convertedArgs.data(),
|
|
63
|
+
convertedArgs.size()
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void Worklet::executeWithArgs(
|
|
69
|
+
jni::alias_ref<Worklet::javaobject> self,
|
|
70
|
+
jni::alias_ref<WorkletNativeRuntime::javaobject> workletRuntimeHolder,
|
|
71
|
+
jni::alias_ref<Serializable::javaobject> synchronizable,
|
|
72
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args
|
|
73
|
+
) {
|
|
74
|
+
auto workletRuntime = workletRuntimeHolder->cthis()->workletRuntime.lock();
|
|
75
|
+
auto worklet = std::dynamic_pointer_cast<worklets::SerializableWorklet>(
|
|
76
|
+
synchronizable->cthis()->getSerializable()
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
workletRuntime->runSync([&args, &worklet](jsi::Runtime &rt) {
|
|
80
|
+
JNIEnv *env = jni::Environment::current();
|
|
81
|
+
std::vector<jsi::Value> convertedArgs = convertArray(env, rt, args);
|
|
82
|
+
|
|
83
|
+
auto func = worklet->toJSValue(rt).asObject(rt).asFunction(rt);
|
|
84
|
+
func.call(
|
|
85
|
+
rt,
|
|
86
|
+
(const jsi::Value *) convertedArgs.data(),
|
|
87
|
+
convertedArgs.size()
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
35
92
|
} // namespace expo
|
|
36
93
|
|
|
37
94
|
#endif
|
|
@@ -33,6 +33,20 @@ public:
|
|
|
33
33
|
jni::alias_ref<WorkletNativeRuntime::javaobject> workletRuntimeHolder,
|
|
34
34
|
jni::alias_ref<Serializable::javaobject> synchronizable
|
|
35
35
|
);
|
|
36
|
+
|
|
37
|
+
static void scheduleWithArgs(
|
|
38
|
+
jni::alias_ref<Worklet::javaobject> self,
|
|
39
|
+
jni::alias_ref<WorkletNativeRuntime::javaobject> workletRuntimeHolder,
|
|
40
|
+
jni::alias_ref<Serializable::javaobject> synchronizable,
|
|
41
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
static void executeWithArgs(
|
|
45
|
+
jni::alias_ref<Worklet::javaobject> self,
|
|
46
|
+
jni::alias_ref<WorkletNativeRuntime::javaobject> workletRuntimeHolder,
|
|
47
|
+
jni::alias_ref<Serializable::javaobject> synchronizable,
|
|
48
|
+
jni::alias_ref<jni::JArrayClass<jobject>> args
|
|
49
|
+
);
|
|
36
50
|
};
|
|
37
51
|
|
|
38
52
|
} // namespace expo
|
|
@@ -264,16 +264,25 @@ class AppContext(
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
internal fun onDestroy() = trace("AppContext.onDestroy") {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
runtime.reactContext?.run {
|
|
268
|
+
removeLifecycleEventListener(reactLifecycleDelegate)
|
|
269
|
+
removeActivityEventListener(reactLifecycleDelegate)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
with(registry) {
|
|
273
|
+
post(EventName.MODULE_DESTROY)
|
|
274
|
+
cleanUp()
|
|
275
|
+
}
|
|
276
|
+
|
|
270
277
|
modulesQueue.cancel(ContextDestroyedException())
|
|
271
278
|
mainQueue.cancel(ContextDestroyedException())
|
|
272
279
|
backgroundCoroutineScope.cancel(ContextDestroyedException())
|
|
273
|
-
|
|
280
|
+
|
|
281
|
+
runtime.deallocate()
|
|
274
282
|
if (uiRuntimeHolder.isInitialized()) {
|
|
275
283
|
uiRuntime.deallocate()
|
|
276
284
|
}
|
|
285
|
+
|
|
277
286
|
logger.info("✅ AppContext was destroyed")
|
|
278
287
|
}
|
|
279
288
|
|
|
@@ -45,11 +45,11 @@ class PromiseImpl @DoNotStrip internal constructor(
|
|
|
45
45
|
callback.invoke(result)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
override fun resolve(result: Collection<Any?>) {
|
|
48
|
+
override fun resolve(result: Collection<Any?>) = checkIfWasSettled {
|
|
49
49
|
callback.invoke(result)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
override fun resolve(result: Map<String, Any?>) {
|
|
52
|
+
override fun resolve(result: Map<String, Any?>) = checkIfWasSettled {
|
|
53
53
|
callback.invoke(result)
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -62,11 +62,11 @@ class PromiseImpl @DoNotStrip internal constructor(
|
|
|
62
62
|
private inline fun checkIfWasSettled(body: () -> Unit) {
|
|
63
63
|
if (wasSettled) {
|
|
64
64
|
val exception = PromiseAlreadySettledException(fullFunctionName ?: "unknown")
|
|
65
|
-
val
|
|
65
|
+
val jsLogger = appContextHolder?.get()?.jsLogger
|
|
66
66
|
// We want to report that a promise was settled twice in the development build.
|
|
67
67
|
// However, in production, the app should crash.
|
|
68
|
-
if (BuildConfig.DEBUG &&
|
|
69
|
-
|
|
68
|
+
if (BuildConfig.DEBUG && jsLogger != null) {
|
|
69
|
+
jsLogger.error("Trying to resolve promise that was already settled", exception)
|
|
70
70
|
logger.error("Trying to resolve promise that was already settled", exception)
|
|
71
71
|
return
|
|
72
72
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.kotlin.jni.worklets
|
|
2
2
|
|
|
3
3
|
import expo.modules.kotlin.runtime.WorkletRuntime
|
|
4
|
+
import expo.modules.kotlin.types.JSTypeConverter
|
|
4
5
|
|
|
5
6
|
class Worklet internal constructor(
|
|
6
7
|
private val serializable: Serializable
|
|
@@ -19,13 +20,45 @@ class Worklet internal constructor(
|
|
|
19
20
|
execute(runtimeHolder, serializable)
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
fun schedule(runtime: WorkletRuntime, vararg arguments: Any?) {
|
|
24
|
+
val runtimeHolder = runtime.enforceHolder
|
|
25
|
+
|
|
26
|
+
val convertedArgs = arguments.map {
|
|
27
|
+
JSTypeConverter.convertToJSValue(it, useExperimentalConverter = true)
|
|
28
|
+
}.toTypedArray()
|
|
29
|
+
|
|
30
|
+
schedule(runtimeHolder, serializable, convertedArgs)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fun execute(runtime: WorkletRuntime, vararg arguments: Any?) {
|
|
34
|
+
val runtimeHolder = runtime.enforceHolder
|
|
35
|
+
|
|
36
|
+
val convertedArgs = arguments.map {
|
|
37
|
+
JSTypeConverter.convertToJSValue(it, useExperimentalConverter = true)
|
|
38
|
+
}.toTypedArray()
|
|
39
|
+
|
|
40
|
+
execute(runtimeHolder, serializable, convertedArgs)
|
|
41
|
+
}
|
|
42
|
+
|
|
22
43
|
private external fun schedule(
|
|
23
44
|
workletNativeRuntime: WorkletNativeRuntime,
|
|
24
45
|
serializable: Serializable
|
|
25
46
|
)
|
|
26
47
|
|
|
48
|
+
private external fun schedule(
|
|
49
|
+
workletNativeRuntime: WorkletNativeRuntime,
|
|
50
|
+
serializable: Serializable,
|
|
51
|
+
args: Array<Any?>
|
|
52
|
+
)
|
|
53
|
+
|
|
27
54
|
private external fun execute(
|
|
28
55
|
workletNativeRuntime: WorkletNativeRuntime,
|
|
29
56
|
serializable: Serializable
|
|
30
57
|
)
|
|
58
|
+
|
|
59
|
+
private external fun execute(
|
|
60
|
+
workletNativeRuntime: WorkletNativeRuntime,
|
|
61
|
+
serializable: Serializable,
|
|
62
|
+
args: Array<Any?>
|
|
63
|
+
)
|
|
31
64
|
}
|
|
@@ -10,6 +10,11 @@ protocol AnyConstantDefinition {
|
|
|
10
10
|
Creates the JavaScript object representing the constant property descriptor.
|
|
11
11
|
*/
|
|
12
12
|
func buildDescriptor(appContext: AppContext) throws -> JavaScriptObject
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
Returns the raw value of the constant for encoding purposes.
|
|
16
|
+
*/
|
|
17
|
+
func getRawValue() -> Any?
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
public final class ConstantDefinition<ReturnType>: AnyDefinition, AnyConstantDefinition {
|
|
@@ -59,6 +64,10 @@ public final class ConstantDefinition<ReturnType>: AnyDefinition, AnyConstantDef
|
|
|
59
64
|
return try getter?()
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
internal func getRawValue() -> Any? {
|
|
68
|
+
return try? getter?()
|
|
69
|
+
}
|
|
70
|
+
|
|
62
71
|
/**
|
|
63
72
|
Creates the JavaScript function that will be used as a getter of the constant.
|
|
64
73
|
*/
|
|
@@ -16,7 +16,12 @@ class ModuleDefinitionEncoder: Encodable {
|
|
|
16
16
|
func encode(to encoder: Encoder) throws {
|
|
17
17
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
18
18
|
try container.encode(definition.name, forKey: .name)
|
|
19
|
-
|
|
19
|
+
var allConstants: [[ConstantEncoder]] = []
|
|
20
|
+
allConstants.append(contentsOf: definition.legacyConstants.map({ LegacyConstantsDefinitionEncoder($0).getEncoders() }))
|
|
21
|
+
if !definition.constants.isEmpty {
|
|
22
|
+
allConstants.append(definition.constants.values.map({ ConstantEncoder($0.name, value: $0.getRawValue()) }))
|
|
23
|
+
}
|
|
24
|
+
try container.encode(allConstants, forKey: .constants)
|
|
20
25
|
try container.encode(definition.properties.values.map({ PropertyDefinitionEncoder($0) }), forKey: .properties)
|
|
21
26
|
try container.encode(definition.functions.values.map({ FunctionDefinitionEncoder($0) }), forKey: .functions)
|
|
22
27
|
try container.encode(definition.views.values.map({ ViewDefinitionEncoder($0) }), forKey: .views)
|
|
@@ -130,10 +135,10 @@ class ConstantEncoder: Encodable {
|
|
|
130
135
|
case nil:
|
|
131
136
|
try container.encodeNil(forKey: .value)
|
|
132
137
|
try container.encode("null", forKey: .type)
|
|
133
|
-
case
|
|
138
|
+
case _ as [String: Any]:
|
|
134
139
|
try container.encodeNil(forKey: .value)
|
|
135
140
|
try container.encode("object", forKey: .type)
|
|
136
|
-
case
|
|
141
|
+
case _ as [Any]:
|
|
137
142
|
try container.encodeNil(forKey: .value)
|
|
138
143
|
try container.encode("array", forKey: .type)
|
|
139
144
|
default:
|
|
@@ -143,24 +148,16 @@ class ConstantEncoder: Encodable {
|
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
|
|
146
|
-
class LegacyConstantsDefinitionEncoder
|
|
151
|
+
class LegacyConstantsDefinitionEncoder {
|
|
147
152
|
private let definition: ConstantsDefinition
|
|
148
153
|
|
|
149
154
|
init(_ definition: ConstantsDefinition) {
|
|
150
155
|
self.definition = definition
|
|
151
156
|
}
|
|
152
157
|
|
|
153
|
-
|
|
154
|
-
case name
|
|
155
|
-
case value
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
func encode(to encoder: Encoder) throws {
|
|
159
|
-
var container = encoder.unkeyedContainer()
|
|
158
|
+
func getEncoders() -> [ConstantEncoder] {
|
|
160
159
|
let constants = definition.body()
|
|
161
|
-
|
|
162
|
-
try container.encode(ConstantEncoder(key, value: value))
|
|
163
|
-
}
|
|
160
|
+
return constants.map { (key, value) in ConstantEncoder(key, value: value) }
|
|
164
161
|
}
|
|
165
162
|
}
|
|
166
163
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "55.0.
|
|
3
|
+
"version": "55.0.5",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@testing-library/react-native": "^13.2.0",
|
|
67
|
-
"expo-module-scripts": "^55.0.
|
|
67
|
+
"expo-module-scripts": "^55.0.2"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "220594d473a3100248087151004ae4acb7282d5f"
|
|
70
70
|
}
|