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.
Files changed (123) hide show
  1. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp +32 -28
  2. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h +13 -5
  3. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +7 -5
  4. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +5 -4
  5. package/Common/cpp/worklets/Resources/SynchronizableUnpacker.cpp +5 -5
  6. package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.cpp +42 -19
  7. package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h +2 -0
  8. package/Common/cpp/worklets/Tools/Defs.h +2 -2
  9. package/Common/cpp/worklets/Tools/ScriptBuffer.h +34 -0
  10. package/Common/cpp/worklets/WorkletRuntime/RuntimeBindings.h +24 -0
  11. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +11 -6
  12. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +82 -0
  13. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +12 -0
  14. package/RNWorklets.podspec +15 -14
  15. package/android/CMakeLists.txt +8 -2
  16. package/android/build.gradle +92 -56
  17. package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.cpp +67 -0
  18. package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.h +48 -0
  19. package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.cpp +52 -0
  20. package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.h +43 -0
  21. package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +115 -19
  22. package/android/src/main/cpp/worklets/android/WorkletsModule.h +11 -13
  23. package/android/src/main/cpp/worklets/android/WorkletsOnLoad.cpp +6 -0
  24. package/android/src/main/java/com/swmansion/worklets/ScriptBufferWrapper.java +88 -0
  25. package/android/src/networking/com/swmansion/worklets/WorkletRuntimeWrapper.kt +23 -0
  26. package/android/src/networking/com/swmansion/worklets/WorkletsHeaderUtil.kt +30 -0
  27. package/android/src/{legacyBundling → networking}/com/swmansion/worklets/WorkletsModule.java +52 -2
  28. package/android/src/networking/com/swmansion/worklets/WorkletsNetworkEventUtil.kt +268 -0
  29. package/android/src/networking/com/swmansion/worklets/WorkletsNetworking.kt +1084 -0
  30. package/android/src/networking/com/swmansion/worklets/WorkletsOkHttpCallUtil.kt +37 -0
  31. package/android/src/networking/com/swmansion/worklets/WorkletsProgressListener.kt +9 -0
  32. package/android/src/networking/com/swmansion/worklets/WorkletsProgressRequestBody.kt +98 -0
  33. package/android/src/networking/com/swmansion/worklets/WorkletsProgressResponseBody.kt +57 -0
  34. package/android/src/networking/com/swmansion/worklets/WorkletsProgressiveStringDecoder.kt +82 -0
  35. package/android/src/networking/com/swmansion/worklets/WorkletsRequestBodyUtil.kt +177 -0
  36. package/android/src/{experimentalBundling → no-networking}/com/swmansion/worklets/WorkletsModule.java +10 -15
  37. package/apple/worklets/apple/Networking/WorkletsNetworking.h +22 -0
  38. package/apple/worklets/apple/Networking/WorkletsNetworking.mm +706 -0
  39. package/apple/worklets/apple/WorkletsModule.mm +56 -17
  40. package/bundleMode/index.js +2 -6
  41. package/compatibility.json +4 -1
  42. package/lib/module/WorkletsModule/NativeWorklets.native.js +8 -2
  43. package/lib/module/WorkletsModule/NativeWorklets.native.js.map +1 -1
  44. package/lib/module/bundleMode/metroOverrides.native.js +115 -0
  45. package/lib/module/bundleMode/metroOverrides.native.js.map +1 -0
  46. package/lib/module/bundleMode/network.native.js +41 -0
  47. package/lib/module/bundleMode/network.native.js.map +1 -0
  48. package/lib/module/debug/jsVersion.js +1 -1
  49. package/lib/module/debug/jsVersion.js.map +1 -1
  50. package/lib/module/featureFlags/staticFlags.json +2 -0
  51. package/lib/module/featureFlags/types.js +3 -1
  52. package/lib/module/featureFlags/types.js.map +1 -1
  53. package/lib/module/index.js +4 -2
  54. package/lib/module/index.js.map +1 -1
  55. package/lib/module/initializers/initializers.native.js +24 -50
  56. package/lib/module/initializers/initializers.native.js.map +1 -1
  57. package/lib/module/initializers/workletRuntimeEntry.native.js +3 -3
  58. package/lib/module/initializers/workletRuntimeEntry.native.js.map +1 -1
  59. package/lib/module/memory/bundleUnpacker.native.js +2 -2
  60. package/lib/module/memory/bundleUnpacker.native.js.map +1 -1
  61. package/lib/module/memory/serializable.native.js +3 -3
  62. package/lib/module/memory/serializable.native.js.map +1 -1
  63. package/lib/module/memory/synchronizableUnpacker.native.js +3 -3
  64. package/lib/module/memory/synchronizableUnpacker.native.js.map +1 -1
  65. package/lib/module/platformChecker.js +2 -2
  66. package/lib/module/platformChecker.js.map +1 -1
  67. package/lib/module/runtimeKind.js +51 -0
  68. package/lib/module/runtimeKind.js.map +1 -1
  69. package/lib/module/runtimes.js +3 -0
  70. package/lib/module/runtimes.js.map +1 -1
  71. package/lib/module/runtimes.native.js +34 -3
  72. package/lib/module/runtimes.native.js.map +1 -1
  73. package/lib/module/threads.native.js +2 -2
  74. package/lib/module/threads.native.js.map +1 -1
  75. package/lib/typescript/WorkletsModule/NativeWorklets.native.d.ts.map +1 -1
  76. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +2 -1
  77. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
  78. package/lib/typescript/bundleMode/metroOverrides.native.d.ts +28 -0
  79. package/lib/typescript/bundleMode/metroOverrides.native.d.ts.map +1 -0
  80. package/lib/typescript/bundleMode/network.native.d.ts +7 -0
  81. package/lib/typescript/bundleMode/network.native.d.ts.map +1 -0
  82. package/lib/typescript/debug/jsVersion.d.ts +1 -1
  83. package/lib/typescript/debug/jsVersion.d.ts.map +1 -1
  84. package/lib/typescript/featureFlags/types.d.ts +3 -1
  85. package/lib/typescript/featureFlags/types.d.ts.map +1 -1
  86. package/lib/typescript/index.d.ts +2 -2
  87. package/lib/typescript/index.d.ts.map +1 -1
  88. package/lib/typescript/initializers/initializers.native.d.ts +1 -0
  89. package/lib/typescript/initializers/initializers.native.d.ts.map +1 -1
  90. package/lib/typescript/initializers/workletRuntimeEntry.native.d.ts +1 -1
  91. package/lib/typescript/memory/bundleUnpacker.native.d.ts.map +1 -1
  92. package/lib/typescript/memory/synchronizableUnpacker.native.d.ts.map +1 -1
  93. package/lib/typescript/platformChecker.d.ts.map +1 -1
  94. package/lib/typescript/runtimeKind.d.ts +31 -0
  95. package/lib/typescript/runtimeKind.d.ts.map +1 -1
  96. package/lib/typescript/runtimes.d.ts +1 -0
  97. package/lib/typescript/runtimes.d.ts.map +1 -1
  98. package/lib/typescript/runtimes.native.d.ts +20 -2
  99. package/lib/typescript/runtimes.native.d.ts.map +1 -1
  100. package/lib/typescript/threads.native.d.ts +1 -1
  101. package/package.json +8 -6
  102. package/plugin/index.d.ts +109 -0
  103. package/plugin/index.js +59 -9
  104. package/scripts/worklets_utils.rb +21 -5
  105. package/src/WorkletsModule/NativeWorklets.native.ts +14 -4
  106. package/src/WorkletsModule/workletsModuleProxy.ts +6 -3
  107. package/src/bundleMode/metroOverrides.native.ts +151 -0
  108. package/src/bundleMode/network.native.ts +59 -0
  109. package/src/debug/jsVersion.ts +1 -1
  110. package/src/featureFlags/staticFlags.json +2 -0
  111. package/src/featureFlags/types.ts +3 -1
  112. package/src/index.ts +10 -1
  113. package/src/initializers/initializers.native.ts +29 -70
  114. package/src/initializers/workletRuntimeEntry.native.ts +3 -3
  115. package/src/memory/bundleUnpacker.native.ts +2 -4
  116. package/src/memory/serializable.native.ts +3 -3
  117. package/src/memory/synchronizableUnpacker.native.ts +6 -12
  118. package/src/platformChecker.ts +3 -2
  119. package/src/privateGlobals.d.ts +7 -2
  120. package/src/runtimeKind.ts +47 -0
  121. package/src/runtimes.native.ts +43 -2
  122. package/src/runtimes.ts +10 -0
  123. 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
+ }
@@ -5,4 +5,4 @@
5
5
  * version used to build the native part of the library in runtime. Remember to
6
6
  * keep this in sync with the version declared in `package.json`
7
7
  */
8
- export const jsVersion = '0.7.2';
8
+ export const jsVersion = '0.8.0-bundle-mode-preview-1';
@@ -1,4 +1,6 @@
1
1
  {
2
2
  "RUNTIME_TEST_FLAG": false,
3
+ "BUNDLE_MODE_ENABLED": false,
4
+ "FETCH_PREVIEW_ENABLED": false,
3
5
  "IOS_DYNAMIC_FRAMERATE_ENABLED": true
4
6
  }
@@ -21,7 +21,9 @@ export type DynamicFlagName = keyof Omit<
21
21
  */
22
22
  export const DefaultStaticFeatureFlags = {
23
23
  RUNTIME_TEST_FLAG: false,
24
- IOS_DYNAMIC_FRAMERATE_ENABLED: false,
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 { getRuntimeKind, RuntimeKind } from './runtimeKind';
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._WORKLETS_BUNDLE_MODE) {
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._WORKLETS_BUNDLE_MODE) {
143
+ if (globalThis._WORKLETS_BUNDLE_MODE_ENABLED) {
131
144
  setupCallGuard();
132
145
 
133
146
  if (__DEV__) {
134
- /*
135
- * Temporary workaround for Metro bundler. We must implement a dummy
136
- * Refresh module to prevent Metro from throwing irrelevant errors.
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
- modules.set(ReactNativeModuleId, mod);
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
- const runtimeBoundCapturableConsole = getMemorySafeCapturableConsole();
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
- * `_WORKLETS_BUNDLE_MODE` flag.
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._WORKLETS_BUNDLE_MODE = false;
22
+ globalThis._WORKLETS_BUNDLE_MODE_ENABLED = false;
23
23
 
24
- if (!globalThis._WORKLETS_BUNDLE_MODE) {
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 (_e) {
51
+ } catch (e) {
52
52
  logger.error(
53
- 'Unable to resolve worklet with hash ' +
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._WORKLETS_BUNDLE_MODE &&
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._WORKLETS_BUNDLE_MODE) {
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._WORKLETS_BUNDLE_MODE
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._WORKLETS_BUNDLE_MODE
10
- ? (value: unknown, _: unknown) => createSerializable(value)
11
- : globalThis._createSerializable;
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 = () => {
@@ -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 = Platform.OS === 'windows';
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;
@@ -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 | undefined;
21
- var _WORKLETS_BUNDLE_MODE: boolean | undefined;
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>;
@@ -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,
@@ -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/experimental/bundleMode)
125
- * is enabled.
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
+ }