react-native-worklets 0.7.2 → 0.8.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 +32 -28
- package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h +13 -5
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +7 -5
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +5 -4
- package/Common/cpp/worklets/Resources/SynchronizableUnpacker.cpp +5 -5
- package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.cpp +42 -19
- package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h +2 -0
- package/Common/cpp/worklets/Tools/Defs.h +2 -2
- package/Common/cpp/worklets/Tools/ScriptBuffer.h +34 -0
- package/Common/cpp/worklets/WorkletRuntime/RuntimeBindings.h +24 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +11 -6
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +82 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +12 -0
- package/RNWorklets.podspec +15 -14
- package/android/CMakeLists.txt +8 -2
- package/android/build.gradle +92 -56
- package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.cpp +67 -0
- package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.h +48 -0
- package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.cpp +52 -0
- package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.h +43 -0
- package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +115 -19
- package/android/src/main/cpp/worklets/android/WorkletsModule.h +11 -13
- package/android/src/main/cpp/worklets/android/WorkletsOnLoad.cpp +6 -0
- package/android/src/main/java/com/swmansion/worklets/ScriptBufferWrapper.java +88 -0
- package/android/src/networking/com/swmansion/worklets/WorkletRuntimeWrapper.kt +23 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsHeaderUtil.kt +30 -0
- package/android/src/{legacyBundling → networking}/com/swmansion/worklets/WorkletsModule.java +52 -2
- package/android/src/networking/com/swmansion/worklets/WorkletsNetworkEventUtil.kt +268 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsNetworking.kt +1084 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsOkHttpCallUtil.kt +37 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsProgressListener.kt +9 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsProgressRequestBody.kt +98 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsProgressResponseBody.kt +57 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsProgressiveStringDecoder.kt +82 -0
- package/android/src/networking/com/swmansion/worklets/WorkletsRequestBodyUtil.kt +177 -0
- package/android/src/{experimentalBundling → no-networking}/com/swmansion/worklets/WorkletsModule.java +10 -15
- package/apple/worklets/apple/Networking/WorkletsNetworking.h +22 -0
- package/apple/worklets/apple/Networking/WorkletsNetworking.mm +706 -0
- package/apple/worklets/apple/WorkletsModule.mm +56 -17
- package/bundleMode/index.js +2 -6
- package/compatibility.json +4 -1
- package/lib/module/WorkletsModule/NativeWorklets.native.js +8 -2
- package/lib/module/WorkletsModule/NativeWorklets.native.js.map +1 -1
- package/lib/module/bundleMode/metroOverrides.native.js +115 -0
- package/lib/module/bundleMode/metroOverrides.native.js.map +1 -0
- package/lib/module/bundleMode/network.native.js +41 -0
- package/lib/module/bundleMode/network.native.js.map +1 -0
- package/lib/module/debug/jsVersion.js +1 -1
- package/lib/module/debug/jsVersion.js.map +1 -1
- package/lib/module/featureFlags/staticFlags.json +2 -0
- package/lib/module/featureFlags/types.js +3 -1
- package/lib/module/featureFlags/types.js.map +1 -1
- package/lib/module/index.js +4 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/initializers/initializers.native.js +24 -50
- package/lib/module/initializers/initializers.native.js.map +1 -1
- package/lib/module/initializers/workletRuntimeEntry.native.js +3 -3
- package/lib/module/initializers/workletRuntimeEntry.native.js.map +1 -1
- package/lib/module/memory/bundleUnpacker.native.js +2 -2
- package/lib/module/memory/bundleUnpacker.native.js.map +1 -1
- package/lib/module/memory/serializable.native.js +3 -3
- package/lib/module/memory/serializable.native.js.map +1 -1
- package/lib/module/memory/synchronizableUnpacker.native.js +3 -3
- package/lib/module/memory/synchronizableUnpacker.native.js.map +1 -1
- package/lib/module/platformChecker.js +2 -2
- package/lib/module/platformChecker.js.map +1 -1
- package/lib/module/runtimeKind.js +51 -0
- package/lib/module/runtimeKind.js.map +1 -1
- package/lib/module/runtimes.js +3 -0
- package/lib/module/runtimes.js.map +1 -1
- package/lib/module/runtimes.native.js +34 -3
- package/lib/module/runtimes.native.js.map +1 -1
- package/lib/module/threads.native.js +2 -2
- package/lib/module/threads.native.js.map +1 -1
- package/lib/typescript/WorkletsModule/NativeWorklets.native.d.ts.map +1 -1
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +2 -1
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
- package/lib/typescript/bundleMode/metroOverrides.native.d.ts +28 -0
- package/lib/typescript/bundleMode/metroOverrides.native.d.ts.map +1 -0
- package/lib/typescript/bundleMode/network.native.d.ts +7 -0
- package/lib/typescript/bundleMode/network.native.d.ts.map +1 -0
- package/lib/typescript/debug/jsVersion.d.ts +1 -1
- package/lib/typescript/debug/jsVersion.d.ts.map +1 -1
- package/lib/typescript/featureFlags/types.d.ts +3 -1
- package/lib/typescript/featureFlags/types.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/initializers/initializers.native.d.ts +1 -0
- package/lib/typescript/initializers/initializers.native.d.ts.map +1 -1
- package/lib/typescript/initializers/workletRuntimeEntry.native.d.ts +1 -1
- package/lib/typescript/memory/bundleUnpacker.native.d.ts.map +1 -1
- package/lib/typescript/memory/synchronizableUnpacker.native.d.ts.map +1 -1
- package/lib/typescript/platformChecker.d.ts.map +1 -1
- package/lib/typescript/runtimeKind.d.ts +31 -0
- package/lib/typescript/runtimeKind.d.ts.map +1 -1
- package/lib/typescript/runtimes.d.ts +1 -0
- package/lib/typescript/runtimes.d.ts.map +1 -1
- package/lib/typescript/runtimes.native.d.ts +20 -2
- package/lib/typescript/runtimes.native.d.ts.map +1 -1
- package/lib/typescript/threads.native.d.ts +1 -1
- package/package.json +8 -6
- package/plugin/index.d.ts +109 -0
- package/plugin/index.js +59 -9
- package/scripts/worklets_utils.rb +21 -5
- package/src/WorkletsModule/NativeWorklets.native.ts +14 -4
- package/src/WorkletsModule/workletsModuleProxy.ts +6 -3
- package/src/bundleMode/metroOverrides.native.ts +151 -0
- package/src/bundleMode/network.native.ts +59 -0
- package/src/debug/jsVersion.ts +1 -1
- package/src/featureFlags/staticFlags.json +2 -0
- package/src/featureFlags/types.ts +3 -1
- package/src/index.ts +10 -1
- package/src/initializers/initializers.native.ts +29 -70
- package/src/initializers/workletRuntimeEntry.native.ts +3 -3
- package/src/memory/bundleUnpacker.native.ts +2 -4
- package/src/memory/serializable.native.ts +3 -3
- package/src/memory/synchronizableUnpacker.native.ts +6 -12
- package/src/platformChecker.ts +3 -2
- package/src/privateGlobals.d.ts +7 -2
- package/src/runtimeKind.ts +47 -0
- package/src/runtimes.native.ts +43 -2
- package/src/runtimes.ts +10 -0
- package/src/threads.native.ts +2 -2
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import { WorkletsError } from '../debug/WorkletsError';
|
|
4
|
+
import { isWorkletRuntime } from '../runtimeKind';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Evaluating HMR updates on Worklet Runtimes leads to verbose warnings which
|
|
8
|
+
* don't affect runtime. This function silences those warnings by providing a
|
|
9
|
+
* dummy Refresh module to the global scope.
|
|
10
|
+
*
|
|
11
|
+
* Use only in dev builds.
|
|
12
|
+
*/
|
|
13
|
+
export function silenceHMRWarnings() {
|
|
14
|
+
assertWorkletRuntime('silenceHMRWarnings');
|
|
15
|
+
|
|
16
|
+
const Refresh = new Proxy(
|
|
17
|
+
{},
|
|
18
|
+
{
|
|
19
|
+
get() {
|
|
20
|
+
return () => {};
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
globalThis.__r.Refresh = Refresh;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Importing `react-native` on Worklet Runtimes will result in a crash due to
|
|
30
|
+
* the fact that React Native will try to set itself up as on the React Native
|
|
31
|
+
* runtime. To provide better developer experience we override the main React
|
|
32
|
+
* Native module with a proxy that puts an actionable warning.
|
|
33
|
+
*
|
|
34
|
+
* Note that this doesn't affect deep imports.
|
|
35
|
+
*
|
|
36
|
+
* Use only in dev builds.
|
|
37
|
+
*/
|
|
38
|
+
export function disallowRNImports() {
|
|
39
|
+
assertWorkletRuntime('disallowRNImports');
|
|
40
|
+
|
|
41
|
+
const modules = require.getModules();
|
|
42
|
+
const ReactNativeModuleId = require.resolveWeak('react-native');
|
|
43
|
+
|
|
44
|
+
const moduleFactory = makeModuleFactory((module) => {
|
|
45
|
+
module.exports = new Proxy(
|
|
46
|
+
{},
|
|
47
|
+
{
|
|
48
|
+
get: function get(_target, prop) {
|
|
49
|
+
globalThis.console.warn(
|
|
50
|
+
`You tried to import '${String(
|
|
51
|
+
prop
|
|
52
|
+
)}' from 'react-native' module on a Worklet Runtime. Using 'react-native' module on a Worklet Runtime is not allowed.`,
|
|
53
|
+
// eslint-disable-next-line reanimated/use-worklets-error
|
|
54
|
+
new Error().stack
|
|
55
|
+
);
|
|
56
|
+
return {
|
|
57
|
+
get() {
|
|
58
|
+
return undefined;
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const mockModule = {
|
|
67
|
+
dependencyMap: [],
|
|
68
|
+
moduleFactory,
|
|
69
|
+
hasError: false,
|
|
70
|
+
importedAll: {},
|
|
71
|
+
importedDefault: {},
|
|
72
|
+
isInitialized: false,
|
|
73
|
+
publicModule: {
|
|
74
|
+
exports: {},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
modules.set(ReactNativeModuleId, mockModule);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* To use code from React Native that obtains TurboModules we need to mock the
|
|
83
|
+
* registry even if the TurboModules aren't actually used.
|
|
84
|
+
*
|
|
85
|
+
* This is needed for example for the XHR setup code that is imported from React
|
|
86
|
+
* Native.
|
|
87
|
+
*/
|
|
88
|
+
export function mockTurboModuleRegistry() {
|
|
89
|
+
const modules = require.getModules();
|
|
90
|
+
|
|
91
|
+
const TurboModuleRegistryId = require.resolveWeak(
|
|
92
|
+
'react-native/Libraries/TurboModule/TurboModuleRegistry'
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const TurboModules = new Map<string, unknown>();
|
|
96
|
+
|
|
97
|
+
TurboModules.set('Networking', {});
|
|
98
|
+
|
|
99
|
+
globalThis.TurboModules = TurboModules;
|
|
100
|
+
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
|
+
const moduleFactory = makeModuleFactory((module: any) => {
|
|
103
|
+
function get(name: string) {
|
|
104
|
+
return globalThis.TurboModules.get(name);
|
|
105
|
+
}
|
|
106
|
+
function getEnforcing(name: string) {
|
|
107
|
+
return globalThis.TurboModules.get(name);
|
|
108
|
+
}
|
|
109
|
+
module.exports.get = get;
|
|
110
|
+
module.exports.getEnforcing = getEnforcing;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const metroModule = {
|
|
114
|
+
dependencyMap: [],
|
|
115
|
+
factory: moduleFactory,
|
|
116
|
+
hasError: false,
|
|
117
|
+
importedAll: {},
|
|
118
|
+
importedDefault: {},
|
|
119
|
+
isInitialized: false,
|
|
120
|
+
publicModule: {
|
|
121
|
+
exports: {},
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
modules.set(TurboModuleRegistryId, metroModule);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function assertWorkletRuntime(functionName: string) {
|
|
129
|
+
if (!isWorkletRuntime()) {
|
|
130
|
+
throw new WorkletsError(
|
|
131
|
+
`${functionName} can be used only on Worklet Runtimes.`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Module factory mimicking the one used by Metro bundler. */
|
|
137
|
+
function makeModuleFactory(
|
|
138
|
+
moduleImpl: (moduleExports: Record<string, unknown>) => void
|
|
139
|
+
) {
|
|
140
|
+
return function (
|
|
141
|
+
_global: unknown,
|
|
142
|
+
_require: unknown,
|
|
143
|
+
_importDefault: unknown,
|
|
144
|
+
_importAll: unknown,
|
|
145
|
+
module: Record<string, unknown>,
|
|
146
|
+
_exports: unknown,
|
|
147
|
+
_dependencyMap: unknown
|
|
148
|
+
) {
|
|
149
|
+
moduleImpl(module);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import { WorkletsError } from '../debug/WorkletsError';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Mocks necessary networking TurboModules on Worklet Runtimes to prevent
|
|
7
|
+
* crashes when code running on Worklet Runtimes tries to use networking APIs.
|
|
8
|
+
* The NetworkingModule itself is injected via C++.
|
|
9
|
+
*/
|
|
10
|
+
export function initializeNetworking() {
|
|
11
|
+
const TurboModules = globalThis.TurboModules;
|
|
12
|
+
|
|
13
|
+
TurboModules.set('FileReaderModule', makeMockTurboModule('FileReaderModule'));
|
|
14
|
+
TurboModules.set(
|
|
15
|
+
'PlatformConstants',
|
|
16
|
+
makeMockTurboModule('PlatformConstants')
|
|
17
|
+
);
|
|
18
|
+
TurboModules.set('WebSocketModule', makeMockTurboModule('WebSocketModule'));
|
|
19
|
+
TurboModules.set(
|
|
20
|
+
'BlobModule',
|
|
21
|
+
makeMockTurboModule('BlobModule', ['addNetworkingHandler'])
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This require statement below is the key part of the implementation here. It
|
|
26
|
+
* pulls all the code that properly sets up XHR on a Runtime, using underlying
|
|
27
|
+
* C++ NetworkingModule. Thanks to that we can have the same JavaScript
|
|
28
|
+
* implementation for fetch on all runtimes in the app and we don't have to
|
|
29
|
+
* write the code ourselves.
|
|
30
|
+
*/
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
require('react-native/Libraries/Core/setUpXHR');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const noopMethods = ['getConstants'];
|
|
36
|
+
|
|
37
|
+
function makeMockTurboModule(name: string, extraNoopMethods?: string[]) {
|
|
38
|
+
const proxy = new Proxy(
|
|
39
|
+
{},
|
|
40
|
+
{
|
|
41
|
+
get: function get(_target, prop) {
|
|
42
|
+
if (
|
|
43
|
+
[...noopMethods, ...(extraNoopMethods ?? [])].includes(prop as string)
|
|
44
|
+
) {
|
|
45
|
+
return () => {
|
|
46
|
+
return () => {};
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
throw new WorkletsError(
|
|
50
|
+
`You tried to call method '${String(
|
|
51
|
+
prop
|
|
52
|
+
)}' from '${name}' TurboModule on a Worklet Runtime. Using '${name}' TurboModule on a Worklet Runtime is not allowed.`
|
|
53
|
+
);
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return proxy;
|
|
59
|
+
}
|
package/src/debug/jsVersion.ts
CHANGED
|
@@ -21,7 +21,9 @@ export type DynamicFlagName = keyof Omit<
|
|
|
21
21
|
*/
|
|
22
22
|
export const DefaultStaticFeatureFlags = {
|
|
23
23
|
RUNTIME_TEST_FLAG: false,
|
|
24
|
-
|
|
24
|
+
BUNDLE_MODE_ENABLED: false,
|
|
25
|
+
FETCH_PREVIEW_ENABLED: false,
|
|
26
|
+
IOS_DYNAMIC_FRAMERATE_ENABLED: true,
|
|
25
27
|
} as const satisfies typeof StaticFeatureFlagsJSON;
|
|
26
28
|
|
|
27
29
|
export type StaticFeatureFlagsSchema = {
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { init } from './initializers/initializers';
|
|
4
4
|
import { bundleModeInit } from './initializers/workletRuntimeEntry';
|
|
5
5
|
|
|
6
|
+
// is-tree-shakable-suppress
|
|
6
7
|
init();
|
|
7
8
|
|
|
8
9
|
// @ts-expect-error We must trick the bundler to include
|
|
@@ -40,10 +41,18 @@ export type {
|
|
|
40
41
|
Synchronizable,
|
|
41
42
|
SynchronizableRef,
|
|
42
43
|
} from './memory/types';
|
|
43
|
-
export {
|
|
44
|
+
export {
|
|
45
|
+
getRuntimeKind,
|
|
46
|
+
isRNRuntime,
|
|
47
|
+
isUIRuntime,
|
|
48
|
+
isWorkerRuntime,
|
|
49
|
+
isWorkletRuntime,
|
|
50
|
+
RuntimeKind,
|
|
51
|
+
} from './runtimeKind';
|
|
44
52
|
export {
|
|
45
53
|
createWorkletRuntime,
|
|
46
54
|
runOnRuntime,
|
|
55
|
+
runOnRuntimeSync,
|
|
47
56
|
scheduleOnRuntime,
|
|
48
57
|
} from './runtimes';
|
|
49
58
|
export {
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
disallowRNImports,
|
|
5
|
+
mockTurboModuleRegistry,
|
|
6
|
+
silenceHMRWarnings,
|
|
7
|
+
} from '../bundleMode/metroOverrides';
|
|
8
|
+
import { initializeNetworking } from '../bundleMode/network';
|
|
3
9
|
import { setupCallGuard } from '../callGuard';
|
|
4
10
|
import { registerReportFatalRemoteError } from '../debug/errors';
|
|
5
11
|
import { registerWorkletsError, WorkletsError } from '../debug/WorkletsError';
|
|
12
|
+
import { getStaticFeatureFlag } from '../featureFlags/featureFlags';
|
|
6
13
|
import { bundleValueUnpacker } from '../memory/bundleUnpacker';
|
|
7
14
|
import { __installUnpacker as installCustomSerializableUnpacker } from '../memory/customSerializableUnpacker';
|
|
15
|
+
import { makeShareableCloneOnUIRecursive } from '../memory/serializable';
|
|
8
16
|
import { __installUnpacker as installSynchronizableUnpacker } from '../memory/synchronizableUnpacker';
|
|
9
17
|
import { setupSetImmediate } from '../runLoop/common/setImmediatePolyfill';
|
|
10
18
|
import { setupSetInterval } from '../runLoop/common/setIntervalPolyfill';
|
|
@@ -82,6 +90,11 @@ export function setupConsole(boundCapturableConsole: typeof console) {
|
|
|
82
90
|
};
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
export function setupSerializer() {
|
|
94
|
+
'worklet';
|
|
95
|
+
globalThis.__serializer = makeShareableCloneOnUIRecursive;
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
let initialized = false;
|
|
86
99
|
|
|
87
100
|
export function init() {
|
|
@@ -102,7 +115,7 @@ export function init() {
|
|
|
102
115
|
|
|
103
116
|
/** A function that should be run on any kind of runtime. */
|
|
104
117
|
function initializeRuntime() {
|
|
105
|
-
if (globalThis.
|
|
118
|
+
if (globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
|
|
106
119
|
globalThis.__valueUnpacker = bundleValueUnpacker as ValueUnpacker;
|
|
107
120
|
}
|
|
108
121
|
installSynchronizableUnpacker();
|
|
@@ -127,68 +140,17 @@ function initializeRNRuntime() {
|
|
|
127
140
|
|
|
128
141
|
/** A function that should be run only on Worklet runtimes. */
|
|
129
142
|
function initializeWorkletRuntime() {
|
|
130
|
-
if (globalThis.
|
|
143
|
+
if (globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
|
|
131
144
|
setupCallGuard();
|
|
132
145
|
|
|
133
146
|
if (__DEV__) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
*/
|
|
138
|
-
const Refresh = new Proxy(
|
|
139
|
-
{},
|
|
140
|
-
{
|
|
141
|
-
get() {
|
|
142
|
-
return () => {};
|
|
143
|
-
},
|
|
144
|
-
}
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
globalThis.__r.Refresh = Refresh;
|
|
148
|
-
|
|
149
|
-
/* Gracefully handle unwanted imports from React Native. */
|
|
150
|
-
const modules = require.getModules();
|
|
151
|
-
const ReactNativeModuleId = require.resolveWeak('react-native');
|
|
152
|
-
|
|
153
|
-
const factory = function (
|
|
154
|
-
_global: unknown,
|
|
155
|
-
_require: unknown,
|
|
156
|
-
_importDefault: unknown,
|
|
157
|
-
_importAll: unknown,
|
|
158
|
-
module: Record<string, unknown>,
|
|
159
|
-
_exports: unknown,
|
|
160
|
-
_dependencyMap: unknown
|
|
161
|
-
) {
|
|
162
|
-
module.exports = new Proxy(
|
|
163
|
-
{},
|
|
164
|
-
{
|
|
165
|
-
get: function get(_target, prop) {
|
|
166
|
-
globalThis.console.warn(
|
|
167
|
-
`You tried to import '${String(prop)}' from 'react-native' module on a Worklet Runtime. Using 'react-native' module on a Worklet Runtime is not allowed.`
|
|
168
|
-
);
|
|
169
|
-
return {
|
|
170
|
-
get() {
|
|
171
|
-
return undefined;
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
},
|
|
175
|
-
}
|
|
176
|
-
);
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const mod = {
|
|
180
|
-
dependencyMap: [],
|
|
181
|
-
factory,
|
|
182
|
-
hasError: false,
|
|
183
|
-
importedAll: {},
|
|
184
|
-
importedDefault: {},
|
|
185
|
-
isInitialized: false,
|
|
186
|
-
publicModule: {
|
|
187
|
-
exports: {},
|
|
188
|
-
},
|
|
189
|
-
};
|
|
147
|
+
silenceHMRWarnings();
|
|
148
|
+
disallowRNImports();
|
|
149
|
+
}
|
|
190
150
|
|
|
191
|
-
|
|
151
|
+
if (getStaticFeatureFlag('FETCH_PREVIEW_ENABLED')) {
|
|
152
|
+
mockTurboModuleRegistry();
|
|
153
|
+
initializeNetworking();
|
|
192
154
|
}
|
|
193
155
|
}
|
|
194
156
|
}
|
|
@@ -204,22 +166,19 @@ function installRNBindingsOnUIRuntime() {
|
|
|
204
166
|
);
|
|
205
167
|
}
|
|
206
168
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (!globalThis._WORKLETS_BUNDLE_MODE) {
|
|
210
|
-
/** In bundle mode Runtimes setup their callGuard themselves. */
|
|
169
|
+
if (!globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
|
|
170
|
+
/** In Bundle Mode Runtimes setup their callGuard themselves. */
|
|
211
171
|
runOnUISync(setupCallGuard);
|
|
212
172
|
|
|
213
|
-
/**
|
|
214
|
-
* Register WorkletsError in the UI runtime global scope. (we are using
|
|
215
|
-
* `executeOnUIRuntimeSync` here to make sure that the changes are applied
|
|
216
|
-
* before any async operations are executed on the UI runtime).
|
|
217
|
-
*
|
|
218
|
-
* There's no need to register the error in bundle mode.
|
|
219
|
-
*/
|
|
173
|
+
/** In Bundle Mode the error is taken from the bundle. */
|
|
220
174
|
runOnUISync(registerWorkletsError);
|
|
175
|
+
|
|
176
|
+
/** In Bundle Mode the serializer is taken from the bundle. */
|
|
177
|
+
runOnUISync(setupSerializer);
|
|
221
178
|
}
|
|
222
179
|
|
|
180
|
+
const runtimeBoundCapturableConsole = getMemorySafeCapturableConsole();
|
|
181
|
+
|
|
223
182
|
runOnUISync(() => {
|
|
224
183
|
'worklet';
|
|
225
184
|
|
|
@@ -14,14 +14,14 @@ import { init } from './initializers';
|
|
|
14
14
|
* error is caught in C++ code.
|
|
15
15
|
*
|
|
16
16
|
* This function has no effect on the RN Runtime beside setting the
|
|
17
|
-
* `
|
|
17
|
+
* `_WORKLETS_BUNDLE_MODE_ENABLED` flag.
|
|
18
18
|
*/
|
|
19
19
|
export function bundleModeInit() {
|
|
20
20
|
// Worklets Babel Plugin replaces `false` with `true` here
|
|
21
21
|
// when Bundle Mode is enabled.
|
|
22
|
-
globalThis.
|
|
22
|
+
globalThis._WORKLETS_BUNDLE_MODE_ENABLED = false;
|
|
23
23
|
|
|
24
|
-
if (!globalThis.
|
|
24
|
+
if (!globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -48,11 +48,9 @@ function getWorklet(
|
|
|
48
48
|
if (__DEV__) {
|
|
49
49
|
try {
|
|
50
50
|
worklet = getWorkletFromMetroRequire(workletHash, closureVariables);
|
|
51
|
-
} catch (
|
|
51
|
+
} catch (e) {
|
|
52
52
|
logger.error(
|
|
53
|
-
|
|
54
|
-
workletHash +
|
|
55
|
-
'. Try reloading the app.'
|
|
53
|
+
`Unable to resolve worklet with hash ${workletHash}. Try reloading the app. Original error: ${(e as Error).message}`
|
|
56
54
|
);
|
|
57
55
|
}
|
|
58
56
|
} else {
|
|
@@ -174,7 +174,7 @@ export function createSerializable<TValue>(
|
|
|
174
174
|
return cloneArray(value, shouldPersistRemote, depth);
|
|
175
175
|
}
|
|
176
176
|
if (
|
|
177
|
-
globalThis.
|
|
177
|
+
globalThis._WORKLETS_BUNDLE_MODE_ENABLED &&
|
|
178
178
|
isFunction &&
|
|
179
179
|
(value as WorkletImport).__bundleData
|
|
180
180
|
) {
|
|
@@ -238,7 +238,7 @@ export function createSerializable<TValue>(
|
|
|
238
238
|
return inaccessibleObject(value);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
if (globalThis.
|
|
241
|
+
if (globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
|
|
242
242
|
// TODO: Do it programmatically.
|
|
243
243
|
createSerializable.__bundleData = {
|
|
244
244
|
imported: 'createSerializable',
|
|
@@ -870,7 +870,7 @@ function makeShareableCloneOnUIRecursiveLEGACY<TValue>(
|
|
|
870
870
|
|
|
871
871
|
/** @deprecated This function is no longer supported. */
|
|
872
872
|
export const makeShareableCloneOnUIRecursive = (
|
|
873
|
-
globalThis.
|
|
873
|
+
globalThis._WORKLETS_BUNDLE_MODE_ENABLED
|
|
874
874
|
? createSerializable
|
|
875
875
|
: makeShareableCloneOnUIRecursiveLEGACY
|
|
876
876
|
) as typeof makeShareableCloneOnUIRecursiveLEGACY;
|
|
@@ -6,16 +6,16 @@ import { type Synchronizable, type SynchronizableRef } from './types';
|
|
|
6
6
|
export function __installUnpacker() {
|
|
7
7
|
// TODO: Add cache for synchronizables.
|
|
8
8
|
const serializer =
|
|
9
|
-
!globalThis._WORKLET || globalThis.
|
|
10
|
-
?
|
|
11
|
-
: globalThis.
|
|
9
|
+
!globalThis._WORKLET || globalThis._WORKLETS_BUNDLE_MODE_ENABLED
|
|
10
|
+
? createSerializable
|
|
11
|
+
: (value: unknown) => globalThis.__serializer(value);
|
|
12
12
|
|
|
13
13
|
function synchronizableUnpacker<TValue>(
|
|
14
14
|
synchronizableRef: SynchronizableRef<TValue>
|
|
15
15
|
): Synchronizable<TValue> {
|
|
16
16
|
const synchronizable =
|
|
17
17
|
synchronizableRef as unknown as Synchronizable<TValue>;
|
|
18
|
-
const proxy = globalThis.__workletsModuleProxy
|
|
18
|
+
const proxy = globalThis.__workletsModuleProxy;
|
|
19
19
|
|
|
20
20
|
synchronizable.__synchronizableRef = true;
|
|
21
21
|
synchronizable.getDirty = () => {
|
|
@@ -34,19 +34,13 @@ export function __installUnpacker() {
|
|
|
34
34
|
const prev = synchronizable.getBlocking();
|
|
35
35
|
newValue = func(prev);
|
|
36
36
|
|
|
37
|
-
proxy.synchronizableSetBlocking(
|
|
38
|
-
synchronizable,
|
|
39
|
-
serializer(newValue, undefined)
|
|
40
|
-
);
|
|
37
|
+
proxy.synchronizableSetBlocking(synchronizable, serializer(newValue));
|
|
41
38
|
|
|
42
39
|
synchronizable.unlock();
|
|
43
40
|
} else {
|
|
44
41
|
const value = valueOrFunction;
|
|
45
42
|
newValue = value;
|
|
46
|
-
proxy.synchronizableSetBlocking(
|
|
47
|
-
synchronizable,
|
|
48
|
-
serializer(newValue, undefined)
|
|
49
|
-
);
|
|
43
|
+
proxy.synchronizableSetBlocking(synchronizable, serializer(newValue));
|
|
50
44
|
}
|
|
51
45
|
};
|
|
52
46
|
synchronizable.lock = () => {
|
package/src/platformChecker.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
|
|
5
5
|
export const IS_JEST: boolean = !!process.env.JEST_WORKER_ID;
|
|
6
|
-
export const IS_WEB: boolean = Platform.OS === 'web';
|
|
7
|
-
export const IS_WINDOWS: boolean =
|
|
6
|
+
export const IS_WEB: boolean = /* @__PURE__ */ (() => Platform.OS === 'web')();
|
|
7
|
+
export const IS_WINDOWS: boolean = /* @__PURE__ */ (() =>
|
|
8
|
+
Platform.OS === 'windows')();
|
|
8
9
|
export const SHOULD_BE_USE_WEB: boolean = IS_JEST || IS_WEB || IS_WINDOWS;
|
package/src/privateGlobals.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { callGuardDEV } from './callGuard';
|
|
6
6
|
import type { reportFatalRemoteError } from './debug/errors';
|
|
7
7
|
import type { CustomSerializableUnpacker } from './memory/customSerializableUnpacker';
|
|
8
|
+
import type { makeShareableCloneOnUIRecursive } from './memory/serializable';
|
|
8
9
|
import type { SynchronizableUnpacker } from './memory/synchronizableUnpacker';
|
|
9
10
|
import type { CustomSerializationRegistry } from './memory/types';
|
|
10
11
|
import type { Queue } from './runLoop/workletRuntime/taskQueue';
|
|
@@ -17,8 +18,8 @@ declare global {
|
|
|
17
18
|
Record<string, unknown>;
|
|
18
19
|
|
|
19
20
|
var _toString: (value: unknown) => string;
|
|
20
|
-
var __workletsModuleProxy: WorkletsModuleProxy
|
|
21
|
-
var
|
|
21
|
+
var __workletsModuleProxy: WorkletsModuleProxy;
|
|
22
|
+
var _WORKLETS_BUNDLE_MODE_ENABLED: boolean | undefined;
|
|
22
23
|
var _WORKLETS_VERSION_CPP: string | undefined;
|
|
23
24
|
var _WORKLETS_VERSION_JS: string | undefined;
|
|
24
25
|
var _createSerializable: <T>(
|
|
@@ -54,6 +55,8 @@ declare global {
|
|
|
54
55
|
var _createSerializableSynchronizable: (
|
|
55
56
|
value: object
|
|
56
57
|
) => FlatShareableRef<object>;
|
|
58
|
+
/** Only outside of Bundle Mode on Worklet Runtimes. */
|
|
59
|
+
var __serializer: typeof makeShareableCloneOnUIRecursive;
|
|
57
60
|
var __callMicrotasks: () => void;
|
|
58
61
|
var _scheduleHostFunctionOnJS: (fun: (...args: A) => R, args?: A) => void;
|
|
59
62
|
var _scheduleRemoteFunctionOnJS: (fun: (...args: A) => R, args?: A) => void;
|
|
@@ -81,6 +84,8 @@ declare global {
|
|
|
81
84
|
var __hasNativeState: (value: object) => boolean;
|
|
82
85
|
/** Only in Debug builds. */
|
|
83
86
|
var __isHostObject: (value: object) => boolean;
|
|
87
|
+
/** Only in Bundle Mode on Worklet Runtimes. */
|
|
88
|
+
var TurboModules: Map<string, unknown>;
|
|
84
89
|
interface NodeRequire {
|
|
85
90
|
resolveWeak(id: string): number;
|
|
86
91
|
getModules(): Map<number, unknown>;
|
package/src/runtimeKind.ts
CHANGED
|
@@ -29,6 +29,53 @@ export function getRuntimeKind(): RuntimeKind {
|
|
|
29
29
|
return globalThis.__RUNTIME_KIND;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the current runtime is the [React Native
|
|
34
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds/#rn-runtime).
|
|
35
|
+
*
|
|
36
|
+
* @returns `true` if the current runtime is the React Native Runtime, `false`
|
|
37
|
+
* otherwise.
|
|
38
|
+
*/
|
|
39
|
+
export function isRNRuntime(): boolean {
|
|
40
|
+
'worklet';
|
|
41
|
+
return globalThis.__RUNTIME_KIND === 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Checks if the current runtime is a [Worklet
|
|
46
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds/#worklet-runtime).
|
|
47
|
+
*
|
|
48
|
+
* @returns `true` if the current runtime is a Worklet Runtime, `false`
|
|
49
|
+
* otherwise.
|
|
50
|
+
*/
|
|
51
|
+
export function isWorkletRuntime(): boolean {
|
|
52
|
+
'worklet';
|
|
53
|
+
return globalThis.__RUNTIME_KIND !== 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Checks if the current runtime is the [UI
|
|
58
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds/#ui-runtime).
|
|
59
|
+
*
|
|
60
|
+
* @returns `true` if the current runtime is the UI Runtime, `false` otherwise.
|
|
61
|
+
*/
|
|
62
|
+
export function isUIRuntime(): boolean {
|
|
63
|
+
'worklet';
|
|
64
|
+
return globalThis.__RUNTIME_KIND === 2;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks if the current runtime is a [Worker
|
|
69
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds/#worker-runtime).
|
|
70
|
+
*
|
|
71
|
+
* @returns `true` if the current runtime is a Worker Runtime, `false`
|
|
72
|
+
* otherwise.
|
|
73
|
+
*/
|
|
74
|
+
export function isWorkerRuntime(): boolean {
|
|
75
|
+
'worklet';
|
|
76
|
+
return globalThis.__RUNTIME_KIND === 3;
|
|
77
|
+
}
|
|
78
|
+
|
|
32
79
|
if (globalThis.__RUNTIME_KIND === undefined) {
|
|
33
80
|
// In Jest environments eager imports make this file to evaluate before
|
|
34
81
|
// `initializers.ts` file, therefore we have to set the RuntimeKind here,
|
package/src/runtimes.native.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { registerWorkletsError, WorkletsError } from './debug/WorkletsError';
|
|
|
5
5
|
import {
|
|
6
6
|
getMemorySafeCapturableConsole,
|
|
7
7
|
setupConsole,
|
|
8
|
+
setupSerializer,
|
|
8
9
|
} from './initializers/initializers';
|
|
9
10
|
import {
|
|
10
11
|
createSerializable,
|
|
@@ -91,6 +92,7 @@ export function createWorkletRuntime(
|
|
|
91
92
|
createSerializable(() => {
|
|
92
93
|
'worklet';
|
|
93
94
|
setupCallGuard();
|
|
95
|
+
setupSerializer();
|
|
94
96
|
registerWorkletsError();
|
|
95
97
|
setupConsole(runtimeBoundCapturableConsole);
|
|
96
98
|
if (enableEventLoop) {
|
|
@@ -121,8 +123,8 @@ export function createWorkletRuntime(
|
|
|
121
123
|
* or another [Worker
|
|
122
124
|
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds#worker-runtime),
|
|
123
125
|
* unless the [Bundle
|
|
124
|
-
* Mode](https://docs.swmansion.com/react-native-worklets/docs/
|
|
125
|
-
*
|
|
126
|
+
* Mode](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/) is
|
|
127
|
+
* enabled.
|
|
126
128
|
*
|
|
127
129
|
* @param workletRuntime - The runtime to schedule the worklet on.
|
|
128
130
|
* @param worklet - The worklet to schedule.
|
|
@@ -196,3 +198,42 @@ export function runOnRuntime<Args extends unknown[], ReturnValue>(
|
|
|
196
198
|
type WorkletRuntimeConfigInternal = WorkletRuntimeConfig & {
|
|
197
199
|
initializer?: WorkletFunction<[], void>;
|
|
198
200
|
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Lets you run a function synchronously on a [Worker
|
|
204
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds#worker-runtime).
|
|
205
|
+
*
|
|
206
|
+
* - This function cannot be called from the [UI
|
|
207
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds#ui-runtime).
|
|
208
|
+
* or another [Worker
|
|
209
|
+
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds#worker-runtime),
|
|
210
|
+
* unless the [Bundle
|
|
211
|
+
* Mode](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/) is
|
|
212
|
+
* enabled.
|
|
213
|
+
*
|
|
214
|
+
* @param workletRuntime - The runtime to run the worklet on.
|
|
215
|
+
* @param worklet - The worklet to run.
|
|
216
|
+
* @param args - The arguments to pass to the worklet.
|
|
217
|
+
* @returns The return value of the worklet.
|
|
218
|
+
*/
|
|
219
|
+
export function runOnRuntimeSync<Args extends unknown[], ReturnValue>(
|
|
220
|
+
workletRuntime: WorkletRuntime,
|
|
221
|
+
worklet: (...args: Args) => ReturnValue,
|
|
222
|
+
...args: Args
|
|
223
|
+
): ReturnValue {
|
|
224
|
+
'worklet';
|
|
225
|
+
if (__DEV__ && !isWorkletFunction(worklet)) {
|
|
226
|
+
throw new WorkletsError(
|
|
227
|
+
'The function passed to `runOnRuntimeSync` is not a worklet.'
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return WorkletsModule.runOnRuntimeSync(
|
|
232
|
+
workletRuntime,
|
|
233
|
+
createSerializable(() => {
|
|
234
|
+
'worklet';
|
|
235
|
+
const result = worklet(...args);
|
|
236
|
+
return makeShareableCloneOnUIRecursive(result);
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
}
|