@depup/react-native-worklets 0.11.4-depup.0 → 0.12.2-depup.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/Common/cpp/worklets/AnimationFrameQueue/AnimationFrameBatchinator.cpp +6 -3
- package/Common/cpp/worklets/Compat/StableApi.cpp +4 -0
- package/Common/cpp/worklets/Compat/StableApi.h +3 -1
- package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp +26 -43
- package/Common/cpp/worklets/RunLoop/EventLoop.cpp +16 -7
- package/Common/cpp/worklets/RunLoop/EventLoop.h +4 -2
- package/Common/cpp/worklets/SharedItems/MemoryManager.cpp +2 -2
- package/Common/cpp/worklets/SharedItems/Serializable.cpp +17 -1
- package/Common/cpp/worklets/SharedItems/Serializable.h +14 -16
- package/Common/cpp/worklets/Tools/UIScheduler.cpp +10 -0
- package/Common/cpp/worklets/Tools/UIScheduler.h +3 -0
- package/Common/cpp/worklets/Tools/WorkletsJSIUtils.h +23 -0
- package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.cpp +7 -4
- package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.h +2 -1
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +60 -88
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +335 -122
- package/README.md +7 -7
- package/android/build.gradle.kts +20 -6
- package/android/src/main/cpp/worklets/android/AndroidUIScheduler.cpp +10 -8
- package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.cpp +2 -11
- package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.h +1 -4
- package/android/src/main/java/com/swmansion/worklets/AndroidUIScheduler.kt +3 -0
- package/android/src/main/java/com/swmansion/worklets/ScriptBufferWrapper.kt +87 -43
- package/android/src/main/java/com/swmansion/worklets/runloop/AnimationFrameQueue.kt +37 -5
- package/android/src/networking/com/swmansion/worklets/WorkletsModule.kt +2 -3
- package/android/src/no-networking/com/swmansion/worklets/WorkletsModule.kt +2 -3
- package/apple/worklets/apple/IOSUIScheduler.h +3 -0
- package/apple/worklets/apple/IOSUIScheduler.mm +6 -1
- package/apple/worklets/apple/ScriptLoader.h +11 -0
- package/apple/worklets/apple/ScriptLoader.mm +124 -0
- package/apple/worklets/apple/WorkletsModule.h +1 -16
- package/apple/worklets/apple/WorkletsModule.mm +4 -16
- package/changes.json +6 -6
- package/compatibility.json +4 -1
- package/lib/module/WorkletsModule/NativeWorklets.native.js +2 -2
- package/lib/module/WorkletsModule/NativeWorklets.native.js.map +1 -1
- package/lib/module/debug/jsVersion.js +1 -1
- package/lib/module/memory/serializable.native.js +61 -23
- package/lib/module/memory/serializable.native.js.map +1 -1
- package/lib/module/memory/synchronizableUnpacker.native.js +16 -8
- package/lib/module/memory/synchronizableUnpacker.native.js.map +1 -1
- package/lib/module/mock.js +58 -17
- package/lib/module/mock.js.map +1 -1
- package/lib/module/runLoop/uiRuntime/requestAnimationFrame.js +1 -2
- package/lib/module/runLoop/uiRuntime/requestAnimationFrame.js.map +1 -1
- package/lib/module/runLoop/workletRuntime/taskQueue.js +0 -1
- package/lib/module/runLoop/workletRuntime/taskQueue.js.map +1 -1
- package/lib/module/runtimes.native.js +7 -8
- package/lib/module/runtimes.native.js.map +1 -1
- package/lib/module/threads.js +35 -24
- package/lib/module/threads.js.map +1 -1
- package/lib/typescript/WorkletsModule/NativeWorklets.native.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
- package/lib/typescript/debug/jsVersion.d.ts +1 -1
- package/lib/typescript/memory/serializable.native.d.ts.map +1 -1
- package/lib/typescript/memory/synchronizableUnpacker.native.d.ts.map +1 -1
- package/lib/typescript/runLoop/uiRuntime/requestAnimationFrame.d.ts.map +1 -1
- package/lib/typescript/runLoop/workletRuntime/taskQueue.d.ts.map +1 -1
- package/lib/typescript/runtimes.native.d.ts.map +1 -1
- package/lib/typescript/specs/NativeWorkletsModule.d.ts +1 -1
- package/lib/typescript/threads.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +38 -8
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +24 -25
- package/plugin/index.js +1625 -1572
- package/src/WorkletsModule/NativeWorklets.native.ts +4 -2
- package/src/WorkletsModule/workletsModuleProxy.ts +2 -1
- package/src/debug/jsVersion.ts +1 -1
- package/src/memory/serializable.native.ts +108 -38
- package/src/memory/synchronizableUnpacker.native.ts +16 -10
- package/src/mock.ts +85 -23
- package/src/runLoop/uiRuntime/requestAnimationFrame.ts +1 -2
- package/src/runLoop/workletRuntime/taskQueue.ts +0 -1
- package/src/runtimes.native.ts +12 -8
- package/src/threads.ts +38 -26
- package/src/types.ts +42 -8
- package/Common/cpp/worklets/Registries/EventHandlerRegistry.cpp +0 -95
- package/Common/cpp/worklets/Registries/EventHandlerRegistry.h +0 -44
- package/Common/cpp/worklets/Tools/WorkletEventHandler.cpp +0 -34
- package/Common/cpp/worklets/Tools/WorkletEventHandler.h +0 -44
- package/jest/pluginTestUtils.ts +0 -16
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
#include <worklets/Tools/JSLogger.h>
|
|
11
11
|
#include <worklets/Tools/JSScheduler.h>
|
|
12
12
|
#include <worklets/Tools/ScriptBuffer.h>
|
|
13
|
+
#include <worklets/Tools/WorkletsJSIUtils.h>
|
|
13
14
|
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
|
14
15
|
#include <worklets/WorkletRuntime/RuntimeData.h>
|
|
15
16
|
|
|
17
|
+
#include <cstdint>
|
|
16
18
|
#include <memory>
|
|
19
|
+
#include <mutex>
|
|
17
20
|
#include <optional>
|
|
18
21
|
#include <string>
|
|
19
22
|
#include <type_traits>
|
|
@@ -26,13 +29,16 @@ using namespace facebook;
|
|
|
26
29
|
using namespace react;
|
|
27
30
|
|
|
28
31
|
template <typename TCallable>
|
|
29
|
-
concept
|
|
30
|
-
std::
|
|
32
|
+
concept RuntimeCallable = std::is_same_v<std::remove_cvref_t<TCallable>, jsi::Function> ||
|
|
33
|
+
std::is_same_v<std::remove_cvref_t<TCallable>, std::shared_ptr<SerializableWorklet>>;
|
|
31
34
|
|
|
32
|
-
template <typename
|
|
33
|
-
concept
|
|
34
|
-
{
|
|
35
|
-
}
|
|
35
|
+
template <typename TJob>
|
|
36
|
+
concept RuntimeJob = !RuntimeCallable<TJob> && requires(TJob &&job, jsi::Runtime &rt) {
|
|
37
|
+
{ job(rt) };
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
template <typename TResult>
|
|
41
|
+
concept SyncCallResult = std::is_same_v<TResult, jsi::Value> || std::is_same_v<TResult, std::shared_ptr<Serializable>>;
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* Forward declaration to avoid circular dependencies.
|
|
@@ -41,105 +47,174 @@ class JSIWorkletsModuleProxy;
|
|
|
41
47
|
|
|
42
48
|
class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_this<WorkletRuntime> {
|
|
43
49
|
public:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
void schedule(std::function<void()> job) const;
|
|
50
|
+
/**
|
|
51
|
+
* Schedules a std::function to run asynchronously.
|
|
52
|
+
*
|
|
53
|
+
* Runs a single microtask checkpoint on completion.
|
|
54
|
+
*/
|
|
50
55
|
void schedule(std::function<void(jsi::Runtime &)> job) const;
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Schedules a jsi::Function to run asynchronously.
|
|
59
|
+
*
|
|
60
|
+
* The jsi::Function has to originate from this runtime, otherwise it will
|
|
61
|
+
crash.
|
|
62
|
+
*
|
|
63
|
+
* Runs a single microtask checkpoint on completion.
|
|
64
|
+
*/
|
|
65
|
+
void schedule(jsi::Function &&function) const;
|
|
53
66
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Schedules a serialized worklet to run asynchronously.
|
|
69
|
+
*
|
|
70
|
+
* Runs a single microtask checkpoint on completion.
|
|
71
|
+
*/
|
|
72
|
+
void schedule(std::shared_ptr<SerializableWorklet> worklet) const;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Schedules a batch of serialized worklets to run asynchronously.
|
|
76
|
+
*
|
|
77
|
+
* Runs a single microtask checkpoint on completion of the batch.
|
|
78
|
+
*/
|
|
79
|
+
void schedule(std::vector<std::shared_ptr<SerializableWorklet>> worklets) const;
|
|
66
80
|
#ifndef NDEBUG
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Schedules a serialized worklet to run asynchronously on the worklet runtime,
|
|
83
|
+
* remembering the call site that scheduled it for error reporting.
|
|
84
|
+
*
|
|
85
|
+
* Runs a single microtask checkpoint on completion.
|
|
86
|
+
*/
|
|
87
|
+
void scheduleWithStack(std::shared_ptr<SerializableWorklet> worklet, std::optional<std::string> scheduleStack) const;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Schedules a batch of serialized worklets to run asynchronously on the
|
|
91
|
+
* worklet runtime, remembering their scheduling call sites for error
|
|
92
|
+
* reporting.
|
|
93
|
+
*
|
|
94
|
+
* Runs a single microtask checkpoint on completion of the batch.
|
|
95
|
+
*/
|
|
96
|
+
void scheduleWithStack(
|
|
97
|
+
std::vector<std::shared_ptr<SerializableWorklet>> worklets,
|
|
98
|
+
std::vector<std::optional<std::string>> scheduleStacks) const;
|
|
72
99
|
#endif // NDEBUG
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Runs a RuntimeJob synchronously and returns its result.
|
|
103
|
+
*
|
|
104
|
+
* Does not run a microtask checkpoint.
|
|
105
|
+
*/
|
|
106
|
+
template <RuntimeJob TJob>
|
|
107
|
+
auto runSync(TJob &&job) const -> std::invoke_result_t<TJob, jsi::Runtime &> {
|
|
108
|
+
auto lock = acquireRuntimeLock();
|
|
109
|
+
return runSyncImpl(std::forward<TJob>(job));
|
|
73
110
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
template <RuntimeCallable TCallable>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return job(rt);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Runs a jsi::Function or SerializableWorklet synchronously and returns a
|
|
114
|
+
* jsi::Value result.
|
|
115
|
+
*
|
|
116
|
+
* The returned jsi::Value originates from this runtime and cannot be used on
|
|
117
|
+
* another runtime unless it is a primitive value. Use runSyncSerialized to
|
|
118
|
+
* transfer the result to another runtime.
|
|
119
|
+
*
|
|
120
|
+
* Does not run a microtask checkpoint.
|
|
121
|
+
*/
|
|
122
|
+
template <RuntimeCallable TCallable, typename... TArgs>
|
|
123
|
+
auto runSync(const TCallable &callable, TArgs &&...args) const -> jsi::Value {
|
|
124
|
+
auto lock = acquireRuntimeLock();
|
|
125
|
+
return runSyncImpl(callable, std::forward<TArgs>(args)...);
|
|
90
126
|
}
|
|
91
127
|
|
|
92
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Runs a jsi::Function or SerializableWorklet synchronously and returns its
|
|
130
|
+
* serialized result.
|
|
131
|
+
*
|
|
132
|
+
* Does not run a microtask checkpoint.
|
|
133
|
+
*/
|
|
134
|
+
template <RuntimeCallable TCallable, typename... TArgs>
|
|
135
|
+
auto runSyncSerialized(const TCallable &callable, TArgs &&...args) const -> std::shared_ptr<Serializable> {
|
|
136
|
+
auto lock = acquireRuntimeLock();
|
|
137
|
+
return runSyncImpl<MicrotaskCheckpoint::Skip, std::shared_ptr<Serializable>>(
|
|
138
|
+
callable, std::forward<TArgs>(args)...);
|
|
139
|
+
}
|
|
93
140
|
|
|
94
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Runs a jsi::Function or SerializableWorklet synchronously and returns its
|
|
143
|
+
* serialized result.
|
|
144
|
+
*
|
|
145
|
+
* Runs a single microtask checkpoint on completion.
|
|
146
|
+
*/
|
|
147
|
+
template <RuntimeJob TJob>
|
|
148
|
+
auto runSyncAndDrainMicrotasks(TJob &&job) const -> std::invoke_result_t<TJob, jsi::Runtime &> {
|
|
149
|
+
auto lock = acquireRuntimeLock();
|
|
150
|
+
return runSyncImpl<MicrotaskCheckpoint::Run>(std::forward<TJob>(job));
|
|
151
|
+
}
|
|
95
152
|
|
|
96
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Runs a jsi::Function or SerializableWorklet synchronously and returns a
|
|
155
|
+
* jsi::Value result.
|
|
156
|
+
*
|
|
157
|
+
* The returned jsi::Value originates from this runtime and cannot be used on
|
|
158
|
+
* another runtime unless it is a primitive value. Use
|
|
159
|
+
* runSyncAndDrainMicrotasksSerialized to transfer the result to another
|
|
160
|
+
* runtime.
|
|
161
|
+
*
|
|
162
|
+
* Runs a single microtask checkpoint on completion.
|
|
163
|
+
*/
|
|
164
|
+
template <RuntimeCallable TCallable, typename... TArgs>
|
|
165
|
+
auto runSyncAndDrainMicrotasks(const TCallable &callable, TArgs &&...args) const -> jsi::Value {
|
|
166
|
+
auto lock = acquireRuntimeLock();
|
|
167
|
+
return runSyncImpl<MicrotaskCheckpoint::Run>(callable, std::forward<TArgs>(args)...);
|
|
168
|
+
}
|
|
97
169
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
"must return a value serialized with `createSerializable`.");
|
|
110
|
-
return serializableResult;
|
|
170
|
+
/**
|
|
171
|
+
* Runs a jsi::Function or SerializableWorklet synchronously and returns its
|
|
172
|
+
* serialized result.
|
|
173
|
+
*
|
|
174
|
+
* Runs a single microtask checkpoint on completion.
|
|
175
|
+
*/
|
|
176
|
+
template <RuntimeCallable TCallable, typename... TArgs>
|
|
177
|
+
auto runSyncAndDrainMicrotasksSerialized(const TCallable &callable, TArgs &&...args) const
|
|
178
|
+
-> std::shared_ptr<Serializable> {
|
|
179
|
+
auto lock = acquireRuntimeLock();
|
|
180
|
+
return runSyncImpl<MicrotaskCheckpoint::Run, std::shared_ptr<Serializable>>(callable, std::forward<TArgs>(args)...);
|
|
111
181
|
}
|
|
182
|
+
|
|
112
183
|
#ifndef NDEBUG
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Synchronously invokes a jsi::Function or SerializableWorklet on the worklet
|
|
186
|
+
* runtime and returns TResult, remembering the call site that scheduled it
|
|
187
|
+
* for error reporting.
|
|
188
|
+
*
|
|
189
|
+
* TResult must be either jsi::Value or std::shared_ptr<Serializable>.
|
|
190
|
+
*
|
|
191
|
+
* Does not run a microtask checkpoint.
|
|
192
|
+
*/
|
|
193
|
+
template <SyncCallResult TResult, RuntimeCallable TCallable, typename... TArgs>
|
|
194
|
+
auto runSyncWithStack(const TCallable &callable, const std::optional<std::string> &scheduleStack, TArgs &&...args)
|
|
195
|
+
const -> TResult {
|
|
196
|
+
auto lock = acquireRuntimeLock();
|
|
197
|
+
return runSyncImpl<MicrotaskCheckpoint::Skip, TResult, ScheduleStack::Requested>(
|
|
198
|
+
callable, scheduleStack, std::forward<TArgs>(args)...);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Synchronously invokes a jsi::Function or SerializableWorklet on the worklet
|
|
203
|
+
* runtime, runs any microtasks it queued, and returns TResult, remembering the
|
|
204
|
+
* call site that scheduled it for error reporting.
|
|
205
|
+
*
|
|
206
|
+
* TResult must be either jsi::Value or std::shared_ptr<Serializable>.
|
|
207
|
+
*/
|
|
208
|
+
template <SyncCallResult TResult, RuntimeCallable TCallable, typename... TArgs>
|
|
209
|
+
auto runSyncWithStackAndDrainMicrotasks(
|
|
210
|
+
const TCallable &callable,
|
|
116
211
|
const std::optional<std::string> &scheduleStack,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
auto serializableResult = extractSerializableOrThrow(
|
|
122
|
-
rt,
|
|
123
|
-
result,
|
|
124
|
-
"[Worklets] Worklet passed to `runSyncSerialized`"
|
|
125
|
-
"must return a value serialized with `createSerializable`.");
|
|
126
|
-
return serializableResult;
|
|
212
|
+
TArgs &&...args) const -> TResult {
|
|
213
|
+
auto lock = acquireRuntimeLock();
|
|
214
|
+
return runSyncImpl<MicrotaskCheckpoint::Run, TResult, ScheduleStack::Requested>(
|
|
215
|
+
callable, scheduleStack, std::forward<TArgs>(args)...);
|
|
127
216
|
}
|
|
128
217
|
#endif // NDEBUG
|
|
129
|
-
template <typename... Args>
|
|
130
|
-
std::shared_ptr<Serializable> runSyncSerialized(const std::shared_ptr<SerializableWorklet> &worklet, Args &&...args)
|
|
131
|
-
const {
|
|
132
|
-
jsi::Runtime &rt = getJSIRuntime();
|
|
133
|
-
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
|
134
|
-
auto result = runSync(worklet, std::forward<Args>(args)...);
|
|
135
|
-
auto serializableResult = extractSerializableOrThrow(
|
|
136
|
-
rt,
|
|
137
|
-
result,
|
|
138
|
-
"[Worklets] Worklet passed to `runSyncSerialized`"
|
|
139
|
-
"must return a value serialized with `createSerializable`.");
|
|
140
|
-
return serializableResult;
|
|
141
|
-
}
|
|
142
|
-
/* #endregion */
|
|
143
218
|
|
|
144
219
|
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override;
|
|
145
220
|
|
|
@@ -161,63 +236,192 @@ class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_th
|
|
|
161
236
|
return name_;
|
|
162
237
|
}
|
|
163
238
|
|
|
239
|
+
[[nodiscard]] bool isLockingEnabled() const noexcept {
|
|
240
|
+
return enableLocking_;
|
|
241
|
+
}
|
|
242
|
+
|
|
164
243
|
explicit WorkletRuntime(
|
|
165
244
|
RuntimeData::RuntimeId runtimeId,
|
|
166
245
|
RuntimeData::RuntimeKind runtimeKind,
|
|
167
246
|
const std::string &name,
|
|
168
247
|
const std::shared_ptr<AsyncQueue> &queue = nullptr,
|
|
169
|
-
bool enableEventLoop = true
|
|
248
|
+
bool enableEventLoop = true,
|
|
249
|
+
bool enableLocking = true);
|
|
170
250
|
|
|
171
251
|
void init(const std::shared_ptr<JSIWorkletsModuleProxy> &jsiWorkletsModuleProxy);
|
|
172
252
|
|
|
173
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Retrieves a weak reference to the WorkletRuntime associated with the
|
|
255
|
+
* provided jsi::Runtime.
|
|
256
|
+
*
|
|
257
|
+
* Throws when invoked with a non-worklet runtime.
|
|
258
|
+
*/
|
|
259
|
+
static std::weak_ptr<WorkletRuntime> getWeakRuntimeFromJSIRuntime(jsi::Runtime &rt);
|
|
174
260
|
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Runs the worklet runtime's pending microtasks.
|
|
263
|
+
*
|
|
264
|
+
* The runtime lock is held until the microtask checkpoint completes.
|
|
265
|
+
*/
|
|
266
|
+
void drainMicrotasks() const {
|
|
267
|
+
auto lock = acquireRuntimeLock();
|
|
268
|
+
drainMicrotasksImpl();
|
|
179
269
|
}
|
|
180
270
|
|
|
181
|
-
|
|
182
|
-
|
|
271
|
+
private:
|
|
272
|
+
enum class MicrotaskCheckpoint : std::uint8_t {
|
|
273
|
+
Skip,
|
|
274
|
+
Run,
|
|
275
|
+
};
|
|
183
276
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
jsi::Value executeSync(const std::function<jsi::Value(jsi::Runtime &)> &job) const;
|
|
277
|
+
enum class ScheduleStack : std::uint8_t {
|
|
278
|
+
NotRequested,
|
|
279
|
+
#ifndef NDEBUG
|
|
280
|
+
Requested,
|
|
281
|
+
#endif // NDEBUG
|
|
282
|
+
};
|
|
191
283
|
|
|
192
|
-
|
|
284
|
+
struct NoScheduleStack {};
|
|
285
|
+
|
|
286
|
+
#ifndef NDEBUG
|
|
287
|
+
struct RequestedScheduleStack {
|
|
288
|
+
const std::optional<std::string> &value;
|
|
289
|
+
};
|
|
290
|
+
#endif // NDEBUG
|
|
291
|
+
|
|
292
|
+
using ScheduledJob = std::function<void(const WorkletRuntime &)>;
|
|
193
293
|
|
|
194
294
|
/**
|
|
195
|
-
*
|
|
196
|
-
* provided jsi::Runtime.
|
|
197
|
-
*
|
|
198
|
-
* Throws when invoked with a non-worklet runtime.
|
|
295
|
+
* Queues a job and acquires the runtime lock immediately before invoking it.
|
|
199
296
|
*
|
|
200
|
-
*
|
|
297
|
+
* Scheduled jobs must use the unlocked implementation methods.
|
|
201
298
|
*/
|
|
202
|
-
|
|
299
|
+
void scheduleImpl(ScheduledJob job) const;
|
|
203
300
|
|
|
204
|
-
|
|
301
|
+
/**
|
|
302
|
+
* Assumes the caller acquired the runtime lock.
|
|
303
|
+
*/
|
|
304
|
+
template <
|
|
305
|
+
MicrotaskCheckpoint TCheckpoint = MicrotaskCheckpoint::Skip,
|
|
306
|
+
SyncCallResult TResult = jsi::Value,
|
|
307
|
+
ScheduleStack TScheduleStack = ScheduleStack::NotRequested,
|
|
308
|
+
typename TCallable,
|
|
309
|
+
typename... TArgs>
|
|
310
|
+
requires RuntimeJob<TCallable> || RuntimeCallable<TCallable>
|
|
311
|
+
auto runSyncImpl(TCallable &&callable, TArgs &&...args) const -> decltype(auto) {
|
|
312
|
+
jsi::Runtime &rt = getJSIRuntime();
|
|
313
|
+
if constexpr (std::is_same_v<std::remove_cvref_t<TCallable>, std::shared_ptr<SerializableWorklet>>) {
|
|
314
|
+
auto function = callable->toJSValue(rt).getObject(rt).getFunction(rt);
|
|
315
|
+
return runSyncImpl<TCheckpoint, TResult, TScheduleStack>(function, std::forward<TArgs>(args)...);
|
|
316
|
+
} else {
|
|
317
|
+
auto stackPolicyInvocation = [&]<typename TScheduleStackContext, typename... TCallArgs>(
|
|
318
|
+
TScheduleStackContext &&scheduleStackContext,
|
|
319
|
+
TCallArgs &&...callArgs) -> decltype(auto) {
|
|
320
|
+
auto microtaskPolicyInvocation = [&]() -> decltype(auto) {
|
|
321
|
+
if constexpr (RuntimeJob<TCallable>) {
|
|
322
|
+
return std::forward<TCallable>(callable)(rt);
|
|
323
|
+
} else {
|
|
324
|
+
auto result = this->invoke(
|
|
325
|
+
rt,
|
|
326
|
+
callable,
|
|
327
|
+
std::forward<TScheduleStackContext>(scheduleStackContext),
|
|
328
|
+
std::forward<TCallArgs>(callArgs)...);
|
|
329
|
+
if constexpr (std::is_same_v<TResult, std::shared_ptr<Serializable>>) {
|
|
330
|
+
return extractSerializableOrThrow(rt, result);
|
|
331
|
+
} else {
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
return invokeWithMicrotaskCheckpointPolicyImpl<TCheckpoint>(std::move(microtaskPolicyInvocation));
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return invokeWithStackPolicyImpl<TScheduleStack, TCallable>(
|
|
341
|
+
std::move(stackPolicyInvocation), std::forward<TArgs>(args)...);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Assumes the caller acquired the runtime lock.
|
|
347
|
+
*/
|
|
348
|
+
template <ScheduleStack TScheduleStack, typename TCallable, typename TInvoker, typename... TArgs>
|
|
349
|
+
static auto invokeWithStackPolicyImpl(TInvoker &&invoke, TArgs &&...args) -> decltype(auto) {
|
|
350
|
+
#ifndef NDEBUG
|
|
351
|
+
if constexpr (TScheduleStack == ScheduleStack::Requested) {
|
|
352
|
+
static_assert(RuntimeCallable<TCallable>, "[Worklets] Scheduling stacks can be used only with worklet calls.");
|
|
353
|
+
static_assert(sizeof...(TArgs) > 0, "[Worklets] A scheduling stack argument is required.");
|
|
354
|
+
return [&]<typename TScheduleStackArg, typename... TCallArgs>(
|
|
355
|
+
TScheduleStackArg &&scheduleStack, TCallArgs &&...callArgs) -> decltype(auto) {
|
|
356
|
+
static_assert(
|
|
357
|
+
std::is_same_v<std::remove_cvref_t<TScheduleStackArg>, std::optional<std::string>>,
|
|
358
|
+
"[Worklets] The first argument must be an optional scheduling stack.");
|
|
359
|
+
return std::forward<TInvoker>(invoke)(
|
|
360
|
+
RequestedScheduleStack{std::forward<TScheduleStackArg>(scheduleStack)},
|
|
361
|
+
std::forward<TCallArgs>(callArgs)...);
|
|
362
|
+
}(std::forward<TArgs>(args)...);
|
|
363
|
+
} else
|
|
364
|
+
#endif // NDEBUG
|
|
365
|
+
{
|
|
366
|
+
return std::forward<TInvoker>(invoke)(NoScheduleStack{}, std::forward<TArgs>(args)...);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Assumes the caller acquired the runtime lock.
|
|
372
|
+
*/
|
|
373
|
+
template <MicrotaskCheckpoint TCheckpoint, typename TInvoker>
|
|
374
|
+
auto invokeWithMicrotaskCheckpointPolicyImpl(TInvoker &&invoke) const -> std::invoke_result_t<TInvoker> {
|
|
375
|
+
using Result = std::invoke_result_t<TInvoker>;
|
|
376
|
+
const auto checkpoint = [&]() {
|
|
377
|
+
if constexpr (TCheckpoint == MicrotaskCheckpoint::Run) {
|
|
378
|
+
drainMicrotasksImpl();
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
if constexpr (std::is_void_v<Result>) {
|
|
382
|
+
std::forward<TInvoker>(invoke)();
|
|
383
|
+
checkpoint();
|
|
384
|
+
} else {
|
|
385
|
+
Result result = std::forward<TInvoker>(invoke)();
|
|
386
|
+
checkpoint();
|
|
387
|
+
return std::forward<Result>(result);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Assumes the caller acquired the runtime lock.
|
|
393
|
+
*/
|
|
394
|
+
void drainMicrotasksImpl() const {
|
|
395
|
+
if (microtaskQueueEnabled_) {
|
|
396
|
+
jsi_utils::drainMicrotasks(getJSIRuntime());
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Invokes the provided function, reporting any exception with the scheduling
|
|
402
|
+
* stack carried by the provided stack context in debug builds.
|
|
403
|
+
*/
|
|
404
|
+
template <typename TScheduleStackContext, typename... TArgs>
|
|
405
|
+
jsi::Value invoke(
|
|
406
|
+
jsi::Runtime &rt,
|
|
407
|
+
const jsi::Function &function,
|
|
408
|
+
const TScheduleStackContext &scheduleStackContext,
|
|
409
|
+
TArgs &&...args) const {
|
|
205
410
|
#ifndef NDEBUG
|
|
206
|
-
// Wraps the provided function in a try/catch so an exception thrown on the
|
|
207
|
-
// worklet runtime can be reported on the RN Runtime LogBox with a
|
|
208
|
-
// stack pointing back to the JS call site that scheduled the worklet.
|
|
209
|
-
template <typename... Args>
|
|
210
|
-
jsi::Value callGuarded(const jsi::Function &function, const std::optional<std::string> &scheduleStack, Args &&...args)
|
|
211
|
-
const {
|
|
212
|
-
auto &rt = *runtime_;
|
|
213
411
|
try {
|
|
214
|
-
return function.call(rt, args...);
|
|
412
|
+
return function.call(rt, std::forward<TArgs>(args)...);
|
|
215
413
|
} catch (jsi::JSError &e) {
|
|
216
|
-
|
|
414
|
+
if constexpr (std::is_same_v<TScheduleStackContext, RequestedScheduleStack>) {
|
|
415
|
+
JSLogger::handleJSError(jsScheduler_, rt, name_, e, scheduleStackContext.value);
|
|
416
|
+
} else {
|
|
417
|
+
JSLogger::handleJSError(jsScheduler_, rt, name_, e, std::nullopt);
|
|
418
|
+
}
|
|
217
419
|
return jsi::Value::undefined();
|
|
218
420
|
}
|
|
219
|
-
|
|
421
|
+
#else
|
|
422
|
+
return function.call(rt, std::forward<TArgs>(args)...);
|
|
220
423
|
#endif // NDEBUG
|
|
424
|
+
}
|
|
221
425
|
|
|
222
426
|
void bundleModeInit(
|
|
223
427
|
const std::shared_ptr<JSScheduler> &jsScheduler,
|
|
@@ -227,8 +431,17 @@ class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_th
|
|
|
227
431
|
|
|
228
432
|
void legacyModeInit(const std::shared_ptr<UnpackerLoader> &unpackerLoader);
|
|
229
433
|
|
|
434
|
+
[[nodiscard]] std::unique_lock<std::recursive_mutex> acquireRuntimeLock() const {
|
|
435
|
+
if (enableLocking_) {
|
|
436
|
+
return std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
|
437
|
+
}
|
|
438
|
+
return {};
|
|
439
|
+
}
|
|
440
|
+
|
|
230
441
|
const RuntimeData::RuntimeId runtimeId_;
|
|
442
|
+
const bool enableLocking_;
|
|
231
443
|
const std::shared_ptr<std::recursive_mutex> runtimeMutex_;
|
|
444
|
+
const bool microtaskQueueEnabled_;
|
|
232
445
|
const std::shared_ptr<jsi::Runtime> runtime_;
|
|
233
446
|
std::shared_ptr<JSScheduler> jsScheduler_;
|
|
234
447
|
const RuntimeData::RuntimeKind runtimeKind_;
|
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/react-native-worklets
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [react-native-worklets](https://www.npmjs.com/package/react-native-worklets) @ 0.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [react-native-worklets](https://www.npmjs.com/package/react-native-worklets) @ 0.12.2 |
|
|
17
|
+
| Processed | 2026-09-13 |
|
|
18
18
|
| Smoke test | failed |
|
|
19
19
|
| Deps updated | 13 |
|
|
20
20
|
|
|
@@ -22,18 +22,18 @@ npm install @depup/react-native-worklets
|
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
|
-
| @babel/generator | ^7.27.1 | ^8.0.
|
|
25
|
+
| @babel/generator | ^7.27.1 | ^8.0.5 |
|
|
26
26
|
| @babel/plugin-transform-arrow-functions | ^7.27.1 | ^8.0.1 |
|
|
27
27
|
| @babel/plugin-transform-class-properties | ^7.28.6 | ^8.0.1 |
|
|
28
|
-
| @babel/plugin-transform-classes | ^7.28.6 | ^8.0.
|
|
28
|
+
| @babel/plugin-transform-classes | ^7.28.6 | ^8.0.5 |
|
|
29
29
|
| @babel/plugin-transform-nullish-coalescing-operator | ^7.28.6 | ^8.0.1 |
|
|
30
|
-
| @babel/plugin-transform-optional-chaining | ^7.28.6 | ^8.0.
|
|
30
|
+
| @babel/plugin-transform-optional-chaining | ^7.28.6 | ^8.0.5 |
|
|
31
31
|
| @babel/plugin-transform-shorthand-properties | ^7.27.1 | ^8.0.1 |
|
|
32
32
|
| @babel/plugin-transform-template-literals | ^7.27.1 | ^8.0.1 |
|
|
33
33
|
| @babel/plugin-transform-unicode-regex | ^7.27.1 | ^8.0.1 |
|
|
34
34
|
| @babel/preset-typescript | ^7.28.5 | ^8.0.1 |
|
|
35
|
-
| @babel/traverse | ^7.27.1 | ^8.0.
|
|
36
|
-
| @babel/types | ^7.27.1 | ^8.0.
|
|
35
|
+
| @babel/traverse | ^7.27.1 | ^8.0.5 |
|
|
36
|
+
| @babel/types | ^7.27.1 | ^8.0.5 |
|
|
37
37
|
| semver | ^7.7.4 | ^7.8.5 |
|
|
38
38
|
|
|
39
39
|
---
|
package/android/build.gradle.kts
CHANGED
|
@@ -8,7 +8,21 @@ plugins {
|
|
|
8
8
|
id("com.android.library")
|
|
9
9
|
id("maven-publish")
|
|
10
10
|
id("com.diffplug.spotless") version "8.1.0"
|
|
11
|
-
id("org.jetbrains.kotlin.android")
|
|
11
|
+
id("org.jetbrains.kotlin.android") apply false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fun shouldApplyKotlinAndroidPlugin(): Boolean {
|
|
15
|
+
val agpMajorVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.substringBefore('.').toInt()
|
|
16
|
+
if (agpMajorVersion <= 8) {
|
|
17
|
+
return true
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
val builtInKotlin = providers.gradleProperty("android.builtInKotlin").orNull?.toBoolean() ?: true
|
|
21
|
+
return !builtInKotlin
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (shouldApplyKotlinAndroidPlugin()) {
|
|
25
|
+
apply(plugin = "org.jetbrains.kotlin.android")
|
|
12
26
|
}
|
|
13
27
|
|
|
14
28
|
fun safeExtGet(prop: String, fallback: Any?): Any? =
|
|
@@ -159,7 +173,7 @@ apply(from = "./fix-prefab.gradle.kts")
|
|
|
159
173
|
apply(from = "./generate-stub-pch.gradle.kts")
|
|
160
174
|
|
|
161
175
|
android {
|
|
162
|
-
compileSdk = safeExtGet("compileSdkVersion",
|
|
176
|
+
compileSdk = safeExtGet("compileSdkVersion", 37) as Int
|
|
163
177
|
|
|
164
178
|
namespace = "com.swmansion.worklets"
|
|
165
179
|
|
|
@@ -274,11 +288,11 @@ android {
|
|
|
274
288
|
|
|
275
289
|
sourceSets {
|
|
276
290
|
getByName("main") {
|
|
277
|
-
|
|
291
|
+
kotlin {
|
|
278
292
|
if (FETCH_PREVIEW_ENABLED) {
|
|
279
|
-
|
|
293
|
+
directories.add("src/networking")
|
|
280
294
|
} else {
|
|
281
|
-
|
|
295
|
+
directories.add("src/no-networking")
|
|
282
296
|
}
|
|
283
297
|
}
|
|
284
298
|
}
|
|
@@ -290,7 +304,7 @@ android {
|
|
|
290
304
|
}
|
|
291
305
|
|
|
292
306
|
if (project != rootProject) {
|
|
293
|
-
kotlin {
|
|
307
|
+
extensions.configure<org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension> {
|
|
294
308
|
compilerOptions {
|
|
295
309
|
jvmTarget = JvmTarget.fromTarget("17")
|
|
296
310
|
}
|
|
@@ -7,18 +7,25 @@ namespace worklets {
|
|
|
7
7
|
using namespace facebook;
|
|
8
8
|
using namespace react;
|
|
9
9
|
|
|
10
|
-
static thread_local bool tls_isOnUIThread = false;
|
|
11
|
-
|
|
12
10
|
class UISchedulerWrapper : public UIScheduler {
|
|
13
11
|
private:
|
|
14
12
|
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler_;
|
|
15
13
|
|
|
14
|
+
bool queryIsOnUIThread() const override {
|
|
15
|
+
static const auto method = androidUiScheduler_->getClass()->getMethod<jboolean()>("isOnUIThread");
|
|
16
|
+
return method(androidUiScheduler_);
|
|
17
|
+
}
|
|
18
|
+
|
|
16
19
|
public:
|
|
17
20
|
explicit UISchedulerWrapper(jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
|
|
18
21
|
: androidUiScheduler_(std::move(androidUiScheduler)) {}
|
|
19
22
|
|
|
23
|
+
void triggerUI() override {
|
|
24
|
+
UIScheduler::triggerUI();
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
void scheduleOnUI(std::function<void()> job) override {
|
|
21
|
-
if (
|
|
28
|
+
if (isOnUIThread()) {
|
|
22
29
|
job();
|
|
23
30
|
return;
|
|
24
31
|
}
|
|
@@ -29,11 +36,6 @@ class UISchedulerWrapper : public UIScheduler {
|
|
|
29
36
|
method(androidUiScheduler_);
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
|
-
|
|
33
|
-
void triggerUI() override {
|
|
34
|
-
tls_isOnUIThread = true;
|
|
35
|
-
UIScheduler::triggerUI();
|
|
36
|
-
}
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
AndroidUIScheduler::AndroidUIScheduler(const jni::alias_ref<AndroidUIScheduler::jhybridobject> &jThis)
|