react-native-worklets 0.3.0 → 0.4.0-bundle-mode-preview-1
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/NativeModules/JSIWorkletsModuleProxy.cpp +532 -0
- package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h +88 -0
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +40 -122
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +16 -40
- package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +2 -1
- package/Common/cpp/worklets/Resources/ValueUnpacker.cpp +1 -1
- package/Common/cpp/worklets/SharedItems/Shareables.cpp +200 -24
- package/Common/cpp/worklets/SharedItems/Shareables.h +108 -7
- package/Common/cpp/worklets/Tools/JSLogger.cpp +56 -4
- package/Common/cpp/worklets/Tools/JSLogger.h +17 -0
- package/Common/cpp/worklets/Tools/JSScheduler.cpp +12 -0
- package/Common/cpp/worklets/Tools/JSScheduler.h +10 -2
- package/Common/cpp/worklets/Tools/SingleInstanceChecker.h +3 -1
- package/Common/cpp/worklets/Tools/WorkletsJSIUtils.cpp +19 -1
- package/Common/cpp/worklets/Tools/WorkletsJSIUtils.h +12 -3
- package/Common/cpp/worklets/Tools/WorkletsSystraceSection.h +136 -0
- package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +4 -4
- package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +1 -1
- package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.cpp +85 -0
- package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.h +55 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.h +8 -4
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +70 -24
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +24 -4
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +53 -1
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +2 -1
- package/RNWorklets.podspec +9 -4
- package/android/CMakeLists.txt +14 -36
- package/android/build.gradle +16 -33
- package/android/src/experimentalBundling/com/swmansion/worklets/WorkletsModule.java +149 -0
- package/android/src/{main/java → legacyBundling}/com/swmansion/worklets/WorkletsModule.java +17 -2
- package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +49 -8
- package/android/src/main/cpp/worklets/android/WorkletsModule.h +17 -2
- package/android/src/main/java/com/swmansion/worklets/WorkletsPackage.java +1 -1
- package/apple/worklets/apple/WorkletsMessageThread.mm +4 -0
- package/apple/worklets/apple/WorkletsModule.h +16 -1
- package/apple/worklets/apple/WorkletsModule.mm +29 -2
- package/bundleMode/index.d.ts +3 -0
- package/bundleMode/index.js +55 -0
- package/lib/module/PlatformChecker/PlatformChecker.js +8 -0
- package/lib/module/PlatformChecker/PlatformChecker.js.map +1 -0
- package/lib/module/PlatformChecker/index.js +17 -0
- package/lib/module/PlatformChecker/index.js.map +1 -0
- package/lib/module/WorkletsError.js +2 -1
- package/lib/module/WorkletsError.js.map +1 -1
- package/lib/module/WorkletsModule/JSWorklets.js +36 -4
- package/lib/module/WorkletsModule/JSWorklets.js.map +1 -1
- package/lib/module/WorkletsModule/NativeWorklets.js +35 -15
- package/lib/module/WorkletsModule/NativeWorklets.js.map +1 -1
- package/lib/module/WorkletsModule/workletsModuleInstance.js +2 -2
- package/lib/module/WorkletsModule/workletsModuleInstance.js.map +1 -1
- package/lib/module/bundleUnpacker.js +47 -0
- package/lib/module/bundleUnpacker.js.map +1 -0
- package/lib/module/callGuard.js +30 -0
- package/lib/module/callGuard.js.map +1 -0
- package/lib/module/errors.js +30 -11
- package/lib/module/errors.js.map +1 -1
- package/lib/module/index.js +10 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/initializers.js +123 -103
- package/lib/module/initializers.js.map +1 -1
- package/lib/module/logger.js +15 -0
- package/lib/module/logger.js.map +1 -0
- package/lib/module/privateGlobals.d.js +0 -1
- package/lib/module/privateGlobals.d.js.map +1 -1
- package/lib/module/publicGlobals.js +5 -0
- package/lib/module/publicGlobals.js.map +1 -0
- package/lib/module/runLoop/mockedRequestAnimationFrame.js.map +1 -0
- package/lib/module/runLoop/requestAnimationFrame.js +50 -0
- package/lib/module/runLoop/requestAnimationFrame.js.map +1 -0
- package/lib/module/runLoop/setImmediatePolyfill.js +15 -0
- package/lib/module/runLoop/setImmediatePolyfill.js.map +1 -0
- package/lib/module/runLoop/setIntervalPolyfill.js +26 -0
- package/lib/module/runLoop/setIntervalPolyfill.js.map +1 -0
- package/lib/module/runLoop/setTimeoutPolyfill.js +32 -0
- package/lib/module/runLoop/setTimeoutPolyfill.js.map +1 -0
- package/lib/module/runtimes.js +6 -10
- package/lib/module/runtimes.js.map +1 -1
- package/lib/module/shareableMappingCache.js +1 -3
- package/lib/module/shareableMappingCache.js.map +1 -1
- package/lib/module/shareables.js +116 -34
- package/lib/module/shareables.js.map +1 -1
- package/lib/module/specs/index.js +2 -2
- package/lib/module/specs/index.js.map +1 -1
- package/lib/module/threads.js +49 -54
- package/lib/module/threads.js.map +1 -1
- package/lib/module/valueUnpacker.js +3 -3
- package/lib/module/valueUnpacker.js.map +1 -1
- package/lib/module/workletRuntimeEntry.js +30 -0
- package/lib/module/workletRuntimeEntry.js.map +1 -0
- package/lib/typescript/PlatformChecker/PlatformChecker.d.ts +5 -0
- package/lib/typescript/PlatformChecker/PlatformChecker.d.ts.map +1 -0
- package/lib/typescript/PlatformChecker/index.d.ts +10 -0
- package/lib/typescript/PlatformChecker/index.d.ts.map +1 -0
- package/lib/typescript/WorkletsError.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/JSWorklets.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/NativeWorklets.d.ts +1 -3
- package/lib/typescript/WorkletsModule/NativeWorklets.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +12 -2
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
- package/lib/typescript/bundleUnpacker.d.ts +7 -0
- package/lib/typescript/bundleUnpacker.d.ts.map +1 -0
- package/lib/typescript/callGuard.d.ts +4 -0
- package/lib/typescript/callGuard.d.ts.map +1 -0
- package/lib/typescript/errors.d.ts +13 -5
- package/lib/typescript/errors.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/initializers.d.ts +16 -5
- package/lib/typescript/initializers.d.ts.map +1 -1
- package/lib/typescript/logger.d.ts +5 -0
- package/lib/typescript/logger.d.ts.map +1 -0
- package/lib/typescript/publicGlobals.d.ts +22 -0
- package/lib/typescript/publicGlobals.d.ts.map +1 -0
- package/lib/typescript/runLoop/mockedRequestAnimationFrame.d.ts.map +1 -0
- package/lib/typescript/runLoop/requestAnimationFrame.d.ts.map +1 -0
- package/lib/typescript/runLoop/setImmediatePolyfill.d.ts +2 -0
- package/lib/typescript/runLoop/setImmediatePolyfill.d.ts.map +1 -0
- package/lib/typescript/runLoop/setIntervalPolyfill.d.ts +2 -0
- package/lib/typescript/runLoop/setIntervalPolyfill.d.ts.map +1 -0
- package/lib/typescript/runLoop/setTimeoutPolyfill.d.ts +2 -0
- package/lib/typescript/runLoop/setTimeoutPolyfill.d.ts.map +1 -0
- package/lib/typescript/runtimes.d.ts.map +1 -1
- package/lib/typescript/shareableMappingCache.d.ts.map +1 -1
- package/lib/typescript/shareables.d.ts +3 -2
- package/lib/typescript/shareables.d.ts.map +1 -1
- package/lib/typescript/specs/NativeWorkletsModule.d.ts +1 -1
- package/lib/typescript/specs/NativeWorkletsModule.d.ts.map +1 -1
- package/lib/typescript/specs/index.d.ts +2 -2
- package/lib/typescript/specs/index.d.ts.map +1 -1
- package/lib/typescript/threads.d.ts.map +1 -1
- package/lib/typescript/workletRuntimeEntry.d.ts +14 -0
- package/lib/typescript/workletRuntimeEntry.d.ts.map +1 -0
- package/lib/typescript/workletTypes.d.ts +14 -3
- package/lib/typescript/workletTypes.d.ts.map +1 -1
- package/package.json +17 -8
- package/plugin/index.js +145 -52
- package/scripts/worklets_utils.rb +9 -0
- package/src/PlatformChecker/PlatformChecker.ts +7 -0
- package/src/PlatformChecker/index.ts +29 -0
- package/src/WorkletsError.ts +2 -1
- package/src/WorkletsModule/JSWorklets.ts +71 -4
- package/src/WorkletsModule/NativeWorklets.ts +83 -21
- package/src/WorkletsModule/workletsModuleInstance.ts +2 -2
- package/src/WorkletsModule/workletsModuleProxy.ts +49 -1
- package/src/bundleUnpacker.ts +75 -0
- package/src/callGuard.ts +33 -0
- package/src/errors.ts +35 -18
- package/src/index.ts +12 -12
- package/src/initializers.ts +143 -113
- package/src/logger.ts +16 -0
- package/src/privateGlobals.d.ts +22 -6
- package/src/publicGlobals.ts +26 -0
- package/src/runLoop/requestAnimationFrame.ts +67 -0
- package/src/runLoop/setImmediatePolyfill.ts +20 -0
- package/src/runLoop/setIntervalPolyfill.ts +38 -0
- package/src/runLoop/setTimeoutPolyfill.ts +40 -0
- package/src/runtimes.ts +6 -11
- package/src/shareableMappingCache.ts +1 -3
- package/src/shareables.ts +179 -65
- package/src/specs/NativeWorkletsModule.ts +1 -1
- package/src/specs/index.ts +5 -2
- package/src/threads.ts +75 -65
- package/src/valueUnpacker.ts +3 -3
- package/src/workletRuntimeEntry.ts +30 -0
- package/src/workletTypes.ts +22 -5
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +0 -139
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +0 -61
- package/android/src/paper/com/swmansion/worklets/NativeWorkletsModuleSpec.java +0 -26
- package/lib/module/PlatformChecker.js +0 -26
- package/lib/module/PlatformChecker.js.map +0 -1
- package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js.map +0 -1
- package/lib/module/animationFrameQueue/requestAnimationFrame.js +0 -36
- package/lib/module/animationFrameQueue/requestAnimationFrame.js.map +0 -1
- package/lib/module/logger/LogBox.js +0 -15
- package/lib/module/logger/LogBox.js.map +0 -1
- package/lib/module/logger/index.js +0 -5
- package/lib/module/logger/index.js.map +0 -1
- package/lib/module/logger/logger.js +0 -137
- package/lib/module/logger/logger.js.map +0 -1
- package/lib/typescript/PlatformChecker.d.ts +0 -6
- package/lib/typescript/PlatformChecker.d.ts.map +0 -1
- package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts.map +0 -1
- package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts.map +0 -1
- package/lib/typescript/logger/LogBox.d.ts +0 -32
- package/lib/typescript/logger/LogBox.d.ts.map +0 -1
- package/lib/typescript/logger/index.d.ts +0 -3
- package/lib/typescript/logger/index.d.ts.map +0 -1
- package/lib/typescript/logger/logger.d.ts +0 -52
- package/lib/typescript/logger/logger.d.ts.map +0 -1
- package/src/PlatformChecker.ts +0 -30
- package/src/animationFrameQueue/requestAnimationFrame.ts +0 -41
- package/src/logger/LogBox.ts +0 -55
- package/src/logger/index.ts +0 -3
- package/src/logger/logger.ts +0 -155
- /package/lib/module/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.js +0 -0
- /package/lib/typescript/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.d.ts +0 -0
- /package/lib/typescript/{animationFrameQueue → runLoop}/requestAnimationFrame.d.ts +0 -0
- /package/src/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.ts +0 -0
package/src/initializers.ts
CHANGED
|
@@ -1,93 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from './
|
|
12
|
-
import { isJest, isWeb, shouldBeUseWeb } from './PlatformChecker';
|
|
3
|
+
import { bundleValueUnpacker } from './bundleUnpacker';
|
|
4
|
+
import { setupCallGuard } from './callGuard';
|
|
5
|
+
import { registerReportFatalRemoteError } from './errors';
|
|
6
|
+
import { IS_JEST, SHOULD_BE_USE_WEB } from './PlatformChecker';
|
|
7
|
+
import { mockedRequestAnimationFrame } from './runLoop/mockedRequestAnimationFrame';
|
|
8
|
+
import { setupRequestAnimationFrame } from './runLoop/requestAnimationFrame';
|
|
9
|
+
import { setupSetImmediate } from './runLoop/setImmediatePolyfill';
|
|
10
|
+
import { setupSetInterval } from './runLoop/setIntervalPolyfill';
|
|
11
|
+
import { setupSetTimeout } from './runLoop/setTimeoutPolyfill';
|
|
13
12
|
import { executeOnUIRuntimeSync, runOnJS, setupMicrotasks } from './threads';
|
|
14
13
|
import { isWorkletFunction } from './workletFunction';
|
|
15
14
|
import { registerWorkletsError, WorkletsError } from './WorkletsError';
|
|
16
|
-
import
|
|
15
|
+
import { WorkletsModule } from './WorkletsModule';
|
|
16
|
+
import type { ValueUnpacker } from './workletTypes';
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
|
|
20
|
-
|
|
21
|
-
// Override the logFunction implementation with the one that adds logs
|
|
22
|
-
// with better stack traces to the LogBox (need to override it after `runOnJS`
|
|
23
|
-
// is defined).
|
|
24
|
-
function overrideLogFunctionImplementation() {
|
|
25
|
-
'worklet';
|
|
26
|
-
replaceLoggerImplementation((data) => {
|
|
27
|
-
'worklet';
|
|
28
|
-
runOnJS(logToLogBoxAndConsole)(data);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Register logger config and replace the log function implementation in
|
|
33
|
-
// the React runtime global scope
|
|
34
|
-
registerLoggerConfig(DEFAULT_LOGGER_CONFIG);
|
|
35
|
-
overrideLogFunctionImplementation();
|
|
36
|
-
|
|
37
|
-
// this is for web implementation
|
|
38
|
-
if (SHOULD_BE_USE_WEB) {
|
|
39
|
-
global._WORKLET = false;
|
|
40
|
-
global._log = console.log;
|
|
41
|
-
global._getAnimationTimestamp = () => performance.now();
|
|
42
|
-
} else {
|
|
43
|
-
if (__DEV__) {
|
|
44
|
-
const testWorklet = () => {
|
|
45
|
-
'worklet';
|
|
46
|
-
};
|
|
47
|
-
if (!isWorkletFunction(testWorklet)) {
|
|
48
|
-
throw new WorkletsError(
|
|
49
|
-
`Failed to create a worklet. See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#failed-to-create-a-worklet for more details.`
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Register WorkletsError and logger config in the UI runtime global scope.
|
|
54
|
-
// (we are using `executeOnUIRuntimeSync` here to make sure that the changes
|
|
55
|
-
// are applied before any async operations are executed on the UI runtime)
|
|
56
|
-
executeOnUIRuntimeSync(registerWorkletsError)();
|
|
57
|
-
executeOnUIRuntimeSync(registerLoggerConfig)(DEFAULT_LOGGER_CONFIG);
|
|
58
|
-
executeOnUIRuntimeSync(overrideLogFunctionImplementation)();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// callGuard is only used with debug builds
|
|
62
|
-
export function callGuardDEV<Args extends unknown[], ReturnValue>(
|
|
63
|
-
fn: (...args: Args) => ReturnValue,
|
|
64
|
-
...args: Args
|
|
65
|
-
): ReturnValue | void {
|
|
66
|
-
'worklet';
|
|
67
|
-
try {
|
|
68
|
-
return fn(...args);
|
|
69
|
-
} catch (e) {
|
|
70
|
-
if (global.__ErrorUtils) {
|
|
71
|
-
global.__ErrorUtils.reportFatalError(e as Error);
|
|
72
|
-
} else {
|
|
73
|
-
throw e;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function setupCallGuard() {
|
|
79
|
-
'worklet';
|
|
80
|
-
global.__callGuardDEV = callGuardDEV;
|
|
81
|
-
global.__ErrorUtils = {
|
|
82
|
-
reportFatalError: (error: Error) => {
|
|
83
|
-
runOnJS(reportFatalErrorOnJS)({
|
|
84
|
-
message: error.message,
|
|
85
|
-
moduleName: 'Worklets',
|
|
86
|
-
stack: error.stack,
|
|
87
|
-
});
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
18
|
+
let capturableConsole: typeof console;
|
|
91
19
|
|
|
92
20
|
/**
|
|
93
21
|
* Currently there seems to be a bug in the JSI layer which causes a crash when
|
|
@@ -102,7 +30,11 @@ export function setupCallGuard() {
|
|
|
102
30
|
* we don't copy the methods as they are in the original console object, we copy
|
|
103
31
|
* JavaScript wrappers instead.
|
|
104
32
|
*/
|
|
105
|
-
function
|
|
33
|
+
export function getMemorySafeCapturableConsole(): typeof console {
|
|
34
|
+
if (capturableConsole) {
|
|
35
|
+
return capturableConsole;
|
|
36
|
+
}
|
|
37
|
+
|
|
106
38
|
const consoleCopy = Object.fromEntries(
|
|
107
39
|
Object.entries(console).map(([methodName, method]) => {
|
|
108
40
|
const methodWrapper = function methodWrapper(...args: unknown[]) {
|
|
@@ -125,37 +57,101 @@ function createMemorySafeCapturableConsole(): typeof console {
|
|
|
125
57
|
})
|
|
126
58
|
);
|
|
127
59
|
|
|
60
|
+
capturableConsole = consoleCopy as unknown as typeof console;
|
|
61
|
+
|
|
128
62
|
return consoleCopy as unknown as typeof console;
|
|
129
63
|
}
|
|
130
64
|
|
|
131
|
-
|
|
132
|
-
// this object makes it not configurable
|
|
133
|
-
const capturableConsole = createMemorySafeCapturableConsole();
|
|
134
|
-
|
|
135
|
-
export function setupConsole() {
|
|
65
|
+
export function setupConsole(boundCapturableConsole: typeof console) {
|
|
136
66
|
'worklet';
|
|
137
67
|
// @ts-ignore TypeScript doesn't like that there are missing methods in console object, but we don't provide all the methods for the UI runtime console version
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
info: runOnJS(capturableConsole.info),
|
|
146
|
-
/* eslint-enable @typescript-eslint/unbound-method */
|
|
68
|
+
globalThis.console = {
|
|
69
|
+
assert: runOnJS(boundCapturableConsole.assert),
|
|
70
|
+
debug: runOnJS(boundCapturableConsole.debug),
|
|
71
|
+
log: runOnJS(boundCapturableConsole.log),
|
|
72
|
+
warn: runOnJS(boundCapturableConsole.warn),
|
|
73
|
+
error: runOnJS(boundCapturableConsole.error),
|
|
74
|
+
info: runOnJS(boundCapturableConsole.info),
|
|
147
75
|
};
|
|
148
76
|
}
|
|
149
77
|
|
|
150
|
-
|
|
151
|
-
|
|
78
|
+
let initialized = false;
|
|
79
|
+
|
|
80
|
+
export function init() {
|
|
81
|
+
if (initialized) {
|
|
152
82
|
return;
|
|
153
83
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
84
|
+
initialized = true;
|
|
85
|
+
|
|
86
|
+
initializeRuntime();
|
|
87
|
+
|
|
88
|
+
if (SHOULD_BE_USE_WEB) {
|
|
89
|
+
initializeRuntimeOnWeb();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (globalThis._WORKLET) {
|
|
93
|
+
initializeWorkletRuntime();
|
|
94
|
+
} else {
|
|
95
|
+
initializeRNRuntime();
|
|
96
|
+
if (!SHOULD_BE_USE_WEB) {
|
|
97
|
+
installRNBindingsOnUIRuntime();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** A function that should be run on any kind of runtime. */
|
|
103
|
+
function initializeRuntime() {
|
|
104
|
+
if (globalThis._WORKLETS_BUNDLE_MODE) {
|
|
105
|
+
globalThis.__valueUnpacker = bundleValueUnpacker as ValueUnpacker;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A function that should be run only on React Native runtime. */
|
|
110
|
+
function initializeRNRuntime() {
|
|
111
|
+
if (__DEV__) {
|
|
112
|
+
const testWorklet = () => {
|
|
113
|
+
'worklet';
|
|
114
|
+
};
|
|
115
|
+
if (!isWorkletFunction(testWorklet)) {
|
|
116
|
+
throw new WorkletsError(
|
|
117
|
+
`Failed to create a worklet. See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#failed-to-create-a-worklet for more details.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
registerReportFatalRemoteError();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** A function that should be run only on Worklet runtimes. */
|
|
126
|
+
function initializeWorkletRuntime() {
|
|
127
|
+
if (globalThis._WORKLETS_BUNDLE_MODE) {
|
|
128
|
+
setupCallGuard();
|
|
129
|
+
|
|
130
|
+
if (__DEV__) {
|
|
131
|
+
/**
|
|
132
|
+
* Temporary workaround for Metro bundler. We must implement a dummy
|
|
133
|
+
* Refresh module to prevent Metro from throwing irrelevant errors.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
const Refresh = new Proxy(
|
|
137
|
+
{},
|
|
138
|
+
{
|
|
139
|
+
get() {
|
|
140
|
+
return () => {};
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
globalThis.__r.Refresh = Refresh;
|
|
146
|
+
}
|
|
158
147
|
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** A function that should be run only on RN Runtime in web implementation. */
|
|
151
|
+
function initializeRuntimeOnWeb() {
|
|
152
|
+
globalThis._WORKLET = false;
|
|
153
|
+
globalThis._log = console.log;
|
|
154
|
+
globalThis._getAnimationTimestamp = () => performance.now();
|
|
159
155
|
if (IS_JEST) {
|
|
160
156
|
// requestAnimationFrame react-native jest's setup is incorrect as it polyfills
|
|
161
157
|
// the method directly using setTimeout, therefore the callback doesn't get the
|
|
@@ -165,14 +161,48 @@ export function initializeUIRuntime(WorkletsModule: IWorkletsModule) {
|
|
|
165
161
|
// @ts-ignore TypeScript uses Node definition for rAF, setTimeout, etc which returns a Timeout object rather than a number
|
|
166
162
|
globalThis.requestAnimationFrame = mockedRequestAnimationFrame;
|
|
167
163
|
}
|
|
164
|
+
}
|
|
168
165
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
166
|
+
/**
|
|
167
|
+
* A function that should be run on the RN Runtime to configure the UI Runtime
|
|
168
|
+
* with callback bindings.
|
|
169
|
+
*/
|
|
170
|
+
function installRNBindingsOnUIRuntime() {
|
|
171
|
+
if (!WorkletsModule) {
|
|
172
|
+
throw new WorkletsError(
|
|
173
|
+
'Worklets are trying to initialize the UI runtime without a valid WorkletsModule'
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const runtimeBoundCapturableConsole = getMemorySafeCapturableConsole();
|
|
178
|
+
|
|
179
|
+
if (!globalThis._WORKLETS_BUNDLE_MODE) {
|
|
180
|
+
/** In bundle mode Runtimes setup their callGuard themselves. */
|
|
181
|
+
executeOnUIRuntimeSync(setupCallGuard)();
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Register WorkletsError in the UI runtime global scope. (we are using
|
|
185
|
+
* `executeOnUIRuntimeSync` here to make sure that the changes are applied
|
|
186
|
+
* before any async operations are executed on the UI runtime).
|
|
187
|
+
*
|
|
188
|
+
* There's no need to register the error in bundle mode.
|
|
189
|
+
*/
|
|
190
|
+
executeOnUIRuntimeSync(registerWorkletsError)();
|
|
177
191
|
}
|
|
192
|
+
|
|
193
|
+
executeOnUIRuntimeSync(() => {
|
|
194
|
+
'worklet';
|
|
195
|
+
|
|
196
|
+
setupConsole(runtimeBoundCapturableConsole);
|
|
197
|
+
/**
|
|
198
|
+
* TODO: Move `setupMicrotasks` and `setupRequestAnimationFrame` to a
|
|
199
|
+
* separate function once we have a better way to distinguish between
|
|
200
|
+
* Worklet Runtimes.
|
|
201
|
+
*/
|
|
202
|
+
setupMicrotasks();
|
|
203
|
+
setupRequestAnimationFrame();
|
|
204
|
+
setupSetTimeout();
|
|
205
|
+
setupSetImmediate();
|
|
206
|
+
setupSetInterval();
|
|
207
|
+
})();
|
|
178
208
|
}
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PREFIX = '[Worklets]';
|
|
4
|
+
|
|
5
|
+
function formatMessage(message: string) {
|
|
6
|
+
return `${PREFIX} ${message}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const logger = {
|
|
10
|
+
warn(message: string) {
|
|
11
|
+
console.warn(formatMessage(message));
|
|
12
|
+
},
|
|
13
|
+
error(message: string) {
|
|
14
|
+
console.error(formatMessage(message));
|
|
15
|
+
},
|
|
16
|
+
};
|
package/src/privateGlobals.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/* eslint-disable reanimated/use-global-this */
|
|
2
|
-
/* eslint-disable no-var */
|
|
3
2
|
'use strict';
|
|
4
3
|
|
|
5
4
|
// This file works by accident - currently Builder Bob doesn't move `.d.ts` files to output types.
|
|
6
5
|
// If it ever breaks, we should address it so we'd not pollute the user's global namespace.
|
|
7
|
-
import type { callGuardDEV } from './
|
|
6
|
+
import type { callGuardDEV } from './callGuard';
|
|
7
|
+
import type { reportFatalRemoteError } from './errors';
|
|
8
8
|
import type { IWorkletsErrorConstructor } from './WorkletsError';
|
|
9
9
|
import type { WorkletsModuleProxy } from './WorkletsModule';
|
|
10
10
|
import type { ValueUnpacker } from './workletTypes';
|
|
11
11
|
|
|
12
12
|
declare global {
|
|
13
|
+
/** The only runtime-available require method is `__r` defined by Metro. */
|
|
14
|
+
var __r: ((moduleId: number) => Record<string, unknown>) &
|
|
15
|
+
Record<string, unknown>;
|
|
13
16
|
var __workletsCache: Map<number, () => unknown>;
|
|
14
17
|
var __handleCache: WeakMap<object, unknown>;
|
|
15
18
|
var evalWithSourceMap:
|
|
@@ -21,6 +24,7 @@ declare global {
|
|
|
21
24
|
var _toString: (value: unknown) => string;
|
|
22
25
|
var __workletsModuleProxy: WorkletsModuleProxy | undefined;
|
|
23
26
|
var _WORKLET: boolean | undefined;
|
|
27
|
+
var _WORKLETS_BUNDLE_MODE: boolean | undefined;
|
|
24
28
|
var _makeShareableClone: <T>(
|
|
25
29
|
value: T,
|
|
26
30
|
nativeStateSource?: object
|
|
@@ -31,17 +35,29 @@ declare global {
|
|
|
31
35
|
var _makeShareableBigInt: (value: bigint) => FlatShareableRef<bigint>;
|
|
32
36
|
var _makeShareableUndefined: () => FlatShareableRef<undefined>;
|
|
33
37
|
var _makeShareableNull: () => FlatShareableRef<null>;
|
|
38
|
+
var _makeShareableObject: <T extends object>(
|
|
39
|
+
value: T,
|
|
40
|
+
shouldRetainRemote: boolean,
|
|
41
|
+
nativeStateSource?: object
|
|
42
|
+
) => FlatShareableRef<T>;
|
|
43
|
+
var _makeShareableHostObject: <T extends object>(
|
|
44
|
+
value: T
|
|
45
|
+
) => FlatShareableRef<T>;
|
|
46
|
+
var _makeShareableWorklet: (
|
|
47
|
+
value: object,
|
|
48
|
+
shouldPersistRemote: boolean
|
|
49
|
+
) => FlatShareableRef<object>;
|
|
50
|
+
var _makeShareableArray: (value: unknown[]) => FlatShareableRef<unknown[]>;
|
|
51
|
+
var _makeShareableInitializer: (value: object) => FlatShareableRef<object>;
|
|
34
52
|
var __callMicrotasks: () => void;
|
|
35
53
|
var _scheduleHostFunctionOnJS: (fun: (...args: A) => R, args?: A) => void;
|
|
36
54
|
var _scheduleRemoteFunctionOnJS: (fun: (...args: A) => R, args?: A) => void;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
55
|
+
/** Available only on RN Runtime */
|
|
56
|
+
var __reportFatalRemoteError: typeof reportFatalRemoteError | undefined;
|
|
40
57
|
var __valueUnpacker: ValueUnpacker;
|
|
41
58
|
var __callGuardDEV: typeof callGuardDEV | undefined;
|
|
42
59
|
var __flushAnimationFrame: (timestamp: number) => void;
|
|
43
60
|
var __frameTimestamp: number | undefined;
|
|
44
|
-
var __workletsLoggerConfig: LoggerConfigInternal;
|
|
45
61
|
var _log: (value: unknown) => void;
|
|
46
62
|
var _getAnimationTimestamp: () => number;
|
|
47
63
|
var _scheduleOnRuntime: (
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/* eslint-disable reanimated/use-global-this */
|
|
3
|
+
export {};
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
/**
|
|
7
|
+
* This global variable is a diagnostic/development tool.
|
|
8
|
+
*
|
|
9
|
+
* It is `true` on the UI thread and `false` on the JS thread.
|
|
10
|
+
*
|
|
11
|
+
* It used to be necessary in the past for some of the functionalities of
|
|
12
|
+
* react-native-reanimated to work properly but it's no longer the case. Your
|
|
13
|
+
* code shouldn't depend on it, we keep it here mainly for backward
|
|
14
|
+
* compatibility for our users.
|
|
15
|
+
*/
|
|
16
|
+
var _WORKLET: boolean | undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This ArrayBuffer contains the memory address of `jsi::Runtime` which is the
|
|
20
|
+
* Reanimated UI runtime.
|
|
21
|
+
*/
|
|
22
|
+
var _WORKLET_RUNTIME: ArrayBuffer;
|
|
23
|
+
|
|
24
|
+
/** @deprecated Don't use. */
|
|
25
|
+
var _IS_FABRIC: boolean | undefined;
|
|
26
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import { callMicrotasks } from '../threads';
|
|
4
|
+
|
|
5
|
+
export function setupRequestAnimationFrame() {
|
|
6
|
+
'worklet';
|
|
7
|
+
const nativeRequestAnimationFrame = globalThis.requestAnimationFrame;
|
|
8
|
+
|
|
9
|
+
let animationFrameCallbacks: ((timestamp: number) => void)[] = [];
|
|
10
|
+
let callbacksBegin = 0;
|
|
11
|
+
let callbacksEnd = 0;
|
|
12
|
+
|
|
13
|
+
let flushedCallbacks = animationFrameCallbacks;
|
|
14
|
+
let flushedCallbacksBegin = 0;
|
|
15
|
+
let flushedCallbacksEnd = 0;
|
|
16
|
+
|
|
17
|
+
let flushRequested = false;
|
|
18
|
+
|
|
19
|
+
globalThis.__flushAnimationFrame = (timestamp: number) => {
|
|
20
|
+
globalThis.__frameTimestamp = timestamp;
|
|
21
|
+
|
|
22
|
+
flushedCallbacks = animationFrameCallbacks;
|
|
23
|
+
animationFrameCallbacks = [];
|
|
24
|
+
|
|
25
|
+
flushedCallbacksBegin = callbacksBegin;
|
|
26
|
+
flushedCallbacksEnd = callbacksEnd;
|
|
27
|
+
callbacksBegin = callbacksEnd;
|
|
28
|
+
|
|
29
|
+
flushRequested = false;
|
|
30
|
+
|
|
31
|
+
for (const callback of flushedCallbacks) {
|
|
32
|
+
callback(timestamp);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
flushedCallbacksBegin = callbacksEnd;
|
|
36
|
+
|
|
37
|
+
callMicrotasks();
|
|
38
|
+
|
|
39
|
+
globalThis.__frameTimestamp = undefined;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
globalThis.requestAnimationFrame = (
|
|
43
|
+
callback: (timestamp: number) => void
|
|
44
|
+
): number => {
|
|
45
|
+
const handle = callbacksEnd++;
|
|
46
|
+
|
|
47
|
+
animationFrameCallbacks.push(callback);
|
|
48
|
+
if (!flushRequested) {
|
|
49
|
+
flushRequested = true;
|
|
50
|
+
|
|
51
|
+
nativeRequestAnimationFrame(globalThis.__flushAnimationFrame);
|
|
52
|
+
}
|
|
53
|
+
return handle;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
globalThis.cancelAnimationFrame = (handle: number) => {
|
|
57
|
+
if (handle < flushedCallbacksBegin || handle >= callbacksEnd) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (handle < flushedCallbacksEnd) {
|
|
62
|
+
flushedCallbacks[handle - flushedCallbacksBegin] = () => {};
|
|
63
|
+
} else {
|
|
64
|
+
animationFrameCallbacks[handle - callbacksBegin] = () => {};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
export function setupSetImmediate() {
|
|
4
|
+
'worklet';
|
|
5
|
+
|
|
6
|
+
const setImmediatePolyfill = (
|
|
7
|
+
callback: (...args: unknown[]) => void,
|
|
8
|
+
...args: unknown[]
|
|
9
|
+
) => {
|
|
10
|
+
return setTimeout(callback, 0, ...args);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const clearImmediatePolyfill = (immediateHandle: number) => {
|
|
14
|
+
clearTimeout(immediateHandle);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
globalThis.setImmediate =
|
|
18
|
+
setImmediatePolyfill as unknown as typeof setImmediate;
|
|
19
|
+
globalThis.clearImmediate = clearImmediatePolyfill as typeof clearImmediate;
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
export function setupSetInterval() {
|
|
4
|
+
'worklet';
|
|
5
|
+
|
|
6
|
+
const intervalHandleToTimeoutHandle: Map<number, number> = new Map();
|
|
7
|
+
|
|
8
|
+
const setIntervalPolyfill = (
|
|
9
|
+
callback: (...args: unknown[]) => void,
|
|
10
|
+
delay: number = 0,
|
|
11
|
+
...args: unknown[]
|
|
12
|
+
) => {
|
|
13
|
+
let intervalHandle = 0;
|
|
14
|
+
|
|
15
|
+
const repeatingCallback = () => {
|
|
16
|
+
const timeoutHandle = setTimeout(
|
|
17
|
+
repeatingCallback,
|
|
18
|
+
delay
|
|
19
|
+
) as unknown as number;
|
|
20
|
+
intervalHandleToTimeoutHandle.set(intervalHandle, timeoutHandle);
|
|
21
|
+
callback(...args);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
intervalHandle = setTimeout(repeatingCallback, delay) as unknown as number;
|
|
25
|
+
intervalHandleToTimeoutHandle.set(intervalHandle, intervalHandle);
|
|
26
|
+
|
|
27
|
+
return intervalHandle;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const clearIntervalPolyfill = (intervalHandle: number) => {
|
|
31
|
+
const timeoutHandle = intervalHandleToTimeoutHandle.get(intervalHandle);
|
|
32
|
+
clearTimeout(timeoutHandle);
|
|
33
|
+
intervalHandleToTimeoutHandle.delete(intervalHandle);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
globalThis.setInterval = setIntervalPolyfill as typeof setInterval;
|
|
37
|
+
globalThis.clearInterval = clearIntervalPolyfill as typeof clearInterval;
|
|
38
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
export function setupSetTimeout() {
|
|
4
|
+
'worklet';
|
|
5
|
+
|
|
6
|
+
const timeoutHandleToRafHandle: Map<number, number> = new Map();
|
|
7
|
+
|
|
8
|
+
const setTimeoutPolyfill = (
|
|
9
|
+
callback: (...args: unknown[]) => void,
|
|
10
|
+
delay: number = 1,
|
|
11
|
+
...args: unknown[]
|
|
12
|
+
) => {
|
|
13
|
+
const start = performance.now();
|
|
14
|
+
let timeoutHandle = 0;
|
|
15
|
+
|
|
16
|
+
const rafCallback = () => {
|
|
17
|
+
const now = performance.now();
|
|
18
|
+
if (now - start >= delay) {
|
|
19
|
+
callback(...args);
|
|
20
|
+
timeoutHandleToRafHandle.delete(timeoutHandle);
|
|
21
|
+
} else {
|
|
22
|
+
const rafHandle = requestAnimationFrame(rafCallback);
|
|
23
|
+
timeoutHandleToRafHandle.set(timeoutHandle, rafHandle);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
timeoutHandle = requestAnimationFrame(rafCallback);
|
|
28
|
+
timeoutHandleToRafHandle.set(timeoutHandle, timeoutHandle);
|
|
29
|
+
return timeoutHandle;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const clearTimeoutPolyfill = (timeoutHandle: number) => {
|
|
33
|
+
const rafHandle = timeoutHandleToRafHandle.get(timeoutHandle);
|
|
34
|
+
timeoutHandleToRafHandle.delete(timeoutHandle);
|
|
35
|
+
cancelAnimationFrame(rafHandle!);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
globalThis.setTimeout = setTimeoutPolyfill as typeof setTimeout;
|
|
39
|
+
globalThis.clearTimeout = clearTimeoutPolyfill as typeof clearTimeout;
|
|
40
|
+
}
|
package/src/runtimes.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import { setupCallGuard
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { setupCallGuard } from './callGuard';
|
|
4
|
+
import { getMemorySafeCapturableConsole, setupConsole } from './initializers';
|
|
5
|
+
import { SHOULD_BE_USE_WEB } from './PlatformChecker';
|
|
6
6
|
import {
|
|
7
7
|
makeShareableCloneOnUIRecursive,
|
|
8
8
|
makeShareableCloneRecursive,
|
|
@@ -12,8 +12,6 @@ import { registerWorkletsError, WorkletsError } from './WorkletsError';
|
|
|
12
12
|
import { WorkletsModule } from './WorkletsModule';
|
|
13
13
|
import type { WorkletFunction, WorkletRuntime } from './workletTypes';
|
|
14
14
|
|
|
15
|
-
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
|
|
16
|
-
|
|
17
15
|
/**
|
|
18
16
|
* Lets you create a new JS runtime which can be used to run worklets possibly
|
|
19
17
|
* on different threads than JS or UI thread.
|
|
@@ -36,17 +34,14 @@ export function createWorkletRuntime(
|
|
|
36
34
|
name: string,
|
|
37
35
|
initializer?: WorkletFunction<[], void>
|
|
38
36
|
): WorkletRuntime {
|
|
39
|
-
|
|
40
|
-
// identifier in the Worklet runtime.
|
|
41
|
-
const config = __workletsLoggerConfig;
|
|
37
|
+
const runtimeBoundCapturableConsole = getMemorySafeCapturableConsole();
|
|
42
38
|
return WorkletsModule.createWorkletRuntime(
|
|
43
39
|
name,
|
|
44
40
|
makeShareableCloneRecursive(() => {
|
|
45
41
|
'worklet';
|
|
46
|
-
registerWorkletsError();
|
|
47
|
-
registerLoggerConfig(config);
|
|
48
42
|
setupCallGuard();
|
|
49
|
-
|
|
43
|
+
registerWorkletsError();
|
|
44
|
+
setupConsole(runtimeBoundCapturableConsole);
|
|
50
45
|
initializer?.();
|
|
51
46
|
})
|
|
52
47
|
);
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import {
|
|
2
|
+
import { SHOULD_BE_USE_WEB } from './PlatformChecker';
|
|
3
3
|
import type { ShareableRef } from './workletTypes';
|
|
4
4
|
|
|
5
|
-
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
|
|
6
|
-
|
|
7
5
|
/**
|
|
8
6
|
* This symbol is used to represent a mapping from the value to itself.
|
|
9
7
|
*
|