react-native-reanimated 3.0.0-rc.2 → 3.0.0-rc.4

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 (154) hide show
  1. package/Common/cpp/AnimatedSensor/AnimatedSensorModule.cpp +3 -0
  2. package/Common/cpp/{headers/AnimatedSensor → AnimatedSensor}/AnimatedSensorModule.h +0 -0
  3. package/Common/cpp/Fabric/FabricUtils.cpp +1 -1
  4. package/Common/cpp/{headers/Fabric → Fabric}/FabricUtils.h +0 -0
  5. package/Common/cpp/Fabric/ReanimatedUIManagerBinding.cpp +2 -0
  6. package/Common/cpp/{headers/Fabric → Fabric}/ReanimatedUIManagerBinding.h +0 -0
  7. package/Common/cpp/{headers/Fabric → Fabric}/ShadowTreeCloner.h +1 -1
  8. package/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp +2 -0
  9. package/Common/cpp/{headers/LayoutAnimations → LayoutAnimations}/LayoutAnimationsProxy.h +0 -0
  10. package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +6 -1
  11. package/Common/cpp/{headers/NativeModules → NativeModules}/NativeReanimatedModule.h +5 -0
  12. package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +2 -0
  13. package/Common/cpp/{headers/NativeModules → NativeModules}/NativeReanimatedModuleSpec.h +1 -1
  14. package/Common/cpp/ReanimatedRuntime/ReanimatedHermesRuntime.cpp +93 -0
  15. package/Common/cpp/ReanimatedRuntime/ReanimatedHermesRuntime.h +125 -0
  16. package/Common/cpp/ReanimatedRuntime/ReanimatedRuntime.cpp +50 -0
  17. package/Common/cpp/ReanimatedRuntime/ReanimatedRuntime.h +27 -0
  18. package/Common/cpp/ReanimatedRuntime/RuntimeInitialization.md +194 -0
  19. package/Common/cpp/{headers/Registries → Registries}/EventHandlerRegistry.h +0 -0
  20. package/Common/cpp/Registries/MapperRegistry.cpp +3 -1
  21. package/Common/cpp/{headers/Registries → Registries}/MapperRegistry.h +0 -0
  22. package/Common/cpp/{headers/Registries → Registries}/NewestShadowNodesRegistry.h +0 -0
  23. package/Common/cpp/Registries/WorkletsCache.cpp +8 -1
  24. package/Common/cpp/{headers/Registries → Registries}/WorkletsCache.h +0 -0
  25. package/Common/cpp/{headers/SharedItems → SharedItems}/FrozenObject.h +0 -0
  26. package/Common/cpp/{headers/SharedItems → SharedItems}/HostFunctionHandler.h +0 -0
  27. package/Common/cpp/SharedItems/MutableValue.cpp +2 -0
  28. package/Common/cpp/{headers/SharedItems → SharedItems}/MutableValue.h +0 -0
  29. package/Common/cpp/{headers/SharedItems → SharedItems}/MutableValueSetterProxy.h +0 -0
  30. package/Common/cpp/{headers/SharedItems → SharedItems}/RemoteObject.h +0 -0
  31. package/Common/cpp/{headers/SharedItems → SharedItems}/RuntimeManager.h +0 -0
  32. package/Common/cpp/SharedItems/ShareableValue.cpp +6 -2
  33. package/Common/cpp/{headers/SharedItems → SharedItems}/ShareableValue.h +0 -0
  34. package/Common/cpp/{headers/SharedItems → SharedItems}/SharedParent.h +0 -0
  35. package/Common/cpp/{headers/SharedItems → SharedItems}/ValueWrapper.h +0 -0
  36. package/Common/cpp/{headers/SpecTools → SpecTools}/ErrorHandler.h +0 -0
  37. package/Common/cpp/{headers/Tools → Tools}/FeaturesConfig.h +0 -0
  38. package/Common/cpp/Tools/JSIStoreValueUser.cpp +2 -2
  39. package/Common/cpp/{headers/Tools → Tools}/JSIStoreValueUser.h +0 -0
  40. package/Common/cpp/{headers/Tools → Tools}/Mapper.h +0 -0
  41. package/Common/cpp/{headers/Tools → Tools}/PlatformDepMethodsHolder.h +0 -0
  42. package/Common/cpp/{headers/Tools → Tools}/ReanimatedHiddenHeaders.h +1 -1
  43. package/Common/cpp/{headers/Tools → Tools}/RuntimeDecorator.h +0 -0
  44. package/Common/cpp/{headers/Tools → Tools}/Scheduler.h +0 -0
  45. package/Common/cpp/Tools/SingleInstanceChecker.h +58 -0
  46. package/Common/cpp/{headers/Tools → Tools}/WorkletEventHandler.h +0 -0
  47. package/RNReanimated.podspec +21 -85
  48. package/android/CMakeLists.txt +62 -58
  49. package/android/build.gradle +421 -114
  50. package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  51. package/android/src/fabric/java/com/swmansion/reanimated/NativeProxy.java +10 -8
  52. package/android/src/main/cpp/AndroidErrorHandler.cpp +3 -4
  53. package/android/src/main/cpp/{headers/AndroidErrorHandler.h → AndroidErrorHandler.h} +1 -4
  54. package/android/src/main/cpp/AndroidLogger.cpp +4 -1
  55. package/android/src/main/cpp/{headers/AndroidLogger.h → AndroidLogger.h} +0 -0
  56. package/android/src/main/cpp/{headers/AndroidScheduler.h → AndroidScheduler.h} +0 -0
  57. package/android/src/main/cpp/{headers/JNIHelper.h → JNIHelper.h} +0 -0
  58. package/android/src/main/cpp/{headers/LayoutAnimations.h → LayoutAnimations.h} +0 -0
  59. package/android/src/main/cpp/NativeProxy.cpp +12 -28
  60. package/android/src/main/cpp/{headers/NativeProxy.h → NativeProxy.h} +3 -1
  61. package/android/src/main/cpp/{headers/TurboModule.h → TurboModule.h} +0 -0
  62. package/android/src/main/java/com/swmansion/reanimated/ReanimatedMessageQueueThreadBase.java +72 -0
  63. package/android/src/main/java/com/swmansion/reanimated/keyboardObserver/ReanimatedKeyboardEventListener.java +2 -1
  64. package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ReanimatedUIManager.java +1 -1
  65. package/android/src/paper/java/com/swmansion/reanimated/NativeProxy.java +7 -7
  66. package/android/{rnVersionPatch/62 → src/reactNativeVersionPatch/UIImplementation/64/com/swmansion/reanimated}/layoutReanimation/ReanimatedUIImplementation.java +0 -0
  67. package/android/src/{main/java → reactNativeVersionPatch/UIImplementation/latest}/com/swmansion/reanimated/layoutReanimation/ReanimatedUIImplementation.java +0 -0
  68. package/android/src/reactNativeVersionPatch/messageQueueThread/67/com/swmansion/reanimated/ReanimatedMessageQueueThread.java +12 -0
  69. package/android/src/reactNativeVersionPatch/messageQueueThread/latest/com/swmansion/reanimated/ReanimatedMessageQueueThread.java +12 -0
  70. package/android/{rnVersionPatch/62 → src/reactNativeVersionPatch/nativeHierarchyManager/62/com/swmansion/reanimated}/layoutReanimation/ReanimatedNativeHierarchyManager.java +0 -0
  71. package/android/src/{main/java → reactNativeVersionPatch/nativeHierarchyManager/latest}/com/swmansion/reanimated/layoutReanimation/ReanimatedNativeHierarchyManager.java +0 -0
  72. package/ios/REAModule.mm +29 -0
  73. package/ios/keyboardObserver/REAKeyboardEventObserver.m +1 -1
  74. package/ios/native/NativeProxy.mm +12 -19
  75. package/ios/native/REAInitializer.h +2 -2
  76. package/ios/native/REAInitializer.mm +2 -2
  77. package/ios/native/REAMessageThread.h +22 -0
  78. package/ios/native/REAMessageThread.mm +38 -0
  79. package/ios/native/UIResponder+Reanimated.mm +1 -1
  80. package/lib/commonjs/createAnimatedComponent.js +2 -5
  81. package/lib/commonjs/createAnimatedComponent.js.map +1 -1
  82. package/lib/commonjs/reanimated2/NativeMethods.js +67 -31
  83. package/lib/commonjs/reanimated2/NativeMethods.js.map +1 -1
  84. package/lib/commonjs/reanimated2/animation/delay.js +0 -12
  85. package/lib/commonjs/reanimated2/animation/delay.js.map +1 -1
  86. package/lib/commonjs/reanimated2/animation/repeat.js +0 -24
  87. package/lib/commonjs/reanimated2/animation/repeat.js.map +1 -1
  88. package/lib/commonjs/reanimated2/animation/sequence.js +0 -12
  89. package/lib/commonjs/reanimated2/animation/sequence.js.map +1 -1
  90. package/lib/commonjs/reanimated2/commonTypes.js.map +1 -1
  91. package/lib/commonjs/reanimated2/frameCallback/FrameCallbackRegistryJS.js +4 -4
  92. package/lib/commonjs/reanimated2/frameCallback/FrameCallbackRegistryJS.js.map +1 -1
  93. package/lib/commonjs/reanimated2/frameCallback/FrameCallbackRegistryUI.js +51 -19
  94. package/lib/commonjs/reanimated2/frameCallback/FrameCallbackRegistryUI.js.map +1 -1
  95. package/lib/commonjs/reanimated2/globals.d.js.map +1 -1
  96. package/lib/commonjs/reanimated2/hook/index.js +8 -0
  97. package/lib/commonjs/reanimated2/hook/index.js.map +1 -1
  98. package/lib/commonjs/reanimated2/hook/useAnimatedScrollHandler.js.map +1 -1
  99. package/lib/commonjs/reanimated2/hook/useFrameCallback.js.map +1 -1
  100. package/lib/commonjs/reanimated2/hook/useScrollViewOffset.js +33 -0
  101. package/lib/commonjs/reanimated2/hook/useScrollViewOffset.js.map +1 -0
  102. package/lib/commonjs/reanimated2/utils.js +12 -3
  103. package/lib/commonjs/reanimated2/utils.js.map +1 -1
  104. package/lib/module/createAnimatedComponent.js +2 -5
  105. package/lib/module/createAnimatedComponent.js.map +1 -1
  106. package/lib/module/reanimated2/NativeMethods.js +68 -30
  107. package/lib/module/reanimated2/NativeMethods.js.map +1 -1
  108. package/lib/module/reanimated2/animation/delay.js +0 -10
  109. package/lib/module/reanimated2/animation/delay.js.map +1 -1
  110. package/lib/module/reanimated2/animation/repeat.js +0 -20
  111. package/lib/module/reanimated2/animation/repeat.js.map +1 -1
  112. package/lib/module/reanimated2/animation/sequence.js +0 -10
  113. package/lib/module/reanimated2/animation/sequence.js.map +1 -1
  114. package/lib/module/reanimated2/commonTypes.js.map +1 -1
  115. package/lib/module/reanimated2/frameCallback/FrameCallbackRegistryJS.js +4 -4
  116. package/lib/module/reanimated2/frameCallback/FrameCallbackRegistryJS.js.map +1 -1
  117. package/lib/module/reanimated2/frameCallback/FrameCallbackRegistryUI.js +51 -19
  118. package/lib/module/reanimated2/frameCallback/FrameCallbackRegistryUI.js.map +1 -1
  119. package/lib/module/reanimated2/globals.d.js.map +1 -1
  120. package/lib/module/reanimated2/hook/index.js +1 -0
  121. package/lib/module/reanimated2/hook/index.js.map +1 -1
  122. package/lib/module/reanimated2/hook/useAnimatedScrollHandler.js.map +1 -1
  123. package/lib/module/reanimated2/hook/useFrameCallback.js.map +1 -1
  124. package/lib/module/reanimated2/hook/useScrollViewOffset.js +21 -0
  125. package/lib/module/reanimated2/hook/useScrollViewOffset.js.map +1 -0
  126. package/lib/module/reanimated2/utils.js +13 -3
  127. package/lib/module/reanimated2/utils.js.map +1 -1
  128. package/package.json +10 -6
  129. package/plugin.js +105 -47
  130. package/react-native-reanimated.d.ts +13 -9
  131. package/scripts/reanimated_utils.rb +77 -0
  132. package/src/createAnimatedComponent.tsx +2 -3
  133. package/src/reanimated2/NativeMethods.ts +91 -44
  134. package/src/reanimated2/animation/delay.ts +0 -12
  135. package/src/reanimated2/animation/repeat.ts +0 -25
  136. package/src/reanimated2/animation/sequence.ts +0 -13
  137. package/src/reanimated2/commonTypes.ts +9 -0
  138. package/src/reanimated2/frameCallback/FrameCallbackRegistryJS.ts +6 -9
  139. package/src/reanimated2/frameCallback/FrameCallbackRegistryUI.ts +78 -27
  140. package/src/reanimated2/globals.d.ts +56 -14
  141. package/src/reanimated2/hook/index.ts +1 -0
  142. package/src/reanimated2/hook/useAnimatedScrollHandler.ts +3 -1
  143. package/src/reanimated2/hook/useFrameCallback.ts +2 -1
  144. package/src/reanimated2/hook/useScrollViewOffset.ts +37 -0
  145. package/src/reanimated2/utils.ts +12 -5
  146. package/android/rnVersionPatch/63/layoutReanimation/ReanimatedUIImplementation.java +0 -68
  147. package/android/rnVersionPatch/64/layoutReanimation/ReanimatedUIImplementation.java +0 -68
  148. package/android/rnVersionPatch/65/.gitkeep +0 -0
  149. package/android/rnVersionPatch/66/.gitkeep +0 -0
  150. package/android/rnVersionPatch/67/.gitkeep +0 -0
  151. package/android/rnVersionPatch/68/.gitkeep +0 -0
  152. package/android/rnVersionPatch/backup/.gitkeep +0 -0
  153. package/android/src/main/java/com/swmansion/reanimated/AndroidErrorHandler.java +0 -8
  154. package/android/src/main/java/com/swmansion/reanimated/ReanimatedJSIModulePackage.java +0 -29
package/plugin.js CHANGED
@@ -3,6 +3,7 @@ const generate = require('@babel/generator').default;
3
3
  const hash = require('string-hash-64');
4
4
  const traverse = require('@babel/traverse').default;
5
5
  const { transformSync } = require('@babel/core');
6
+ const fs = require('fs');
6
7
  /**
7
8
  * holds a map of function names as keys and array of argument indexes as values which should be automatically workletized(they have to be functions)(starting from 0)
8
9
  */
@@ -277,49 +278,105 @@ class ClosureGenerator {
277
278
  }
278
279
  }
279
280
 
280
- function buildWorkletString(t, fun, closureVariables, name) {
281
- function prependClosureVariablesIfNecessary(closureVariables, body) {
282
- if (closureVariables.length === 0) {
283
- return body;
284
- }
281
+ function isRelease() {
282
+ return ['production', 'release'].includes(process.env.BABEL_ENV);
283
+ }
285
284
 
286
- return t.blockStatement([
287
- t.variableDeclaration('const', [
288
- t.variableDeclarator(
289
- t.objectPattern(
290
- closureVariables.map((variable) =>
291
- t.objectProperty(
292
- t.identifier(variable.name),
293
- t.identifier(variable.name),
294
- false,
295
- true
296
- )
285
+ function shouldGenerateSourceMap() {
286
+ if (isRelease()) {
287
+ return false;
288
+ }
289
+
290
+ if (process.env.REANIMATED_PLUGIN_TESTS === 'jest') {
291
+ // We want to detect this, so we can disable source maps (because they break
292
+ // snapshot tests with jest).
293
+ return false;
294
+ }
295
+
296
+ return true;
297
+ }
298
+
299
+ function buildWorkletString(t, fun, closureVariables, name, inputMap) {
300
+ function prependClosureVariablesIfNecessary() {
301
+ const closureDeclaration = t.variableDeclaration('const', [
302
+ t.variableDeclarator(
303
+ t.objectPattern(
304
+ closureVariables.map((variable) =>
305
+ t.objectProperty(
306
+ t.identifier(variable.name),
307
+ t.identifier(variable.name),
308
+ false,
309
+ true
297
310
  )
298
- ),
299
- t.memberExpression(t.identifier('jsThis'), t.identifier('_closure'))
311
+ )
300
312
  ),
301
- ]),
302
- body,
313
+ t.memberExpression(t.identifier('jsThis'), t.identifier('_closure'))
314
+ ),
303
315
  ]);
304
- }
305
316
 
306
- traverse(fun, {
307
- enter(path) {
308
- t.removeComments(path.node);
309
- },
310
- });
317
+ function prependClosure(path) {
318
+ if (closureVariables.length === 0 || path.parent.type !== 'Program') {
319
+ return;
320
+ }
321
+
322
+ path.node.body.body.unshift(closureDeclaration);
323
+ }
324
+
325
+ return {
326
+ visitor: {
327
+ FunctionDeclaration(path) {
328
+ prependClosure(path);
329
+ },
330
+ FunctionExpression(path) {
331
+ prependClosure(path);
332
+ },
333
+ ArrowFunctionExpression(path) {
334
+ prependClosure(path);
335
+ },
336
+ ObjectMethod(path) {
337
+ prependClosure(path);
338
+ },
339
+ },
340
+ };
341
+ }
311
342
 
312
- const expression = fun.program.body.find(
313
- ({ type }) => type === 'ExpressionStatement'
314
- ).expression;
343
+ const expression =
344
+ fun.program.body.find(({ type }) => type === 'FunctionDeclaration') ||
345
+ fun.program.body.find(({ type }) => type === 'ExpressionStatement')
346
+ .expression;
315
347
 
316
348
  const workletFunction = t.functionExpression(
317
349
  t.identifier(name),
318
350
  expression.params,
319
- prependClosureVariablesIfNecessary(closureVariables, expression.body)
351
+ expression.body
320
352
  );
321
353
 
322
- return generate(workletFunction, { compact: true }).code;
354
+ const code = generate(workletFunction).code;
355
+
356
+ if (shouldGenerateSourceMap()) {
357
+ // Clear contents array (should be empty anyways)
358
+ inputMap.sourcesContent = [];
359
+ // Include source contents in source map, because Flipper/iframe is not
360
+ // allowed to read files from disk.
361
+ for (const sourceFile of inputMap.sources) {
362
+ inputMap.sourcesContent.push(
363
+ fs.readFileSync(sourceFile).toString('utf-8')
364
+ );
365
+ }
366
+ }
367
+
368
+ const transformed = transformSync(code, {
369
+ plugins: [prependClosureVariablesIfNecessary()],
370
+ compact: !shouldGenerateSourceMap(),
371
+ sourceMaps: shouldGenerateSourceMap() ? 'inline' : false,
372
+ inputSourceMap: inputMap,
373
+ ast: false,
374
+ babelrc: false,
375
+ configFile: false,
376
+ comments: false,
377
+ });
378
+
379
+ return transformed.code;
323
380
  }
324
381
 
325
382
  function makeWorkletName(t, fun) {
@@ -342,11 +399,10 @@ function makeWorklet(t, fun, state) {
342
399
  const functionName = makeWorkletName(t, fun);
343
400
 
344
401
  const closure = new Map();
345
- const outputs = new Set();
346
402
  const closureGenerator = new ClosureGenerator();
347
403
  const options = {};
348
404
 
349
- // remove 'worklet'; directive before calling .toString()
405
+ // remove 'worklet'; directive before generating string
350
406
  fun.traverse({
351
407
  DirectiveLiteral(path) {
352
408
  if (path.node.value === 'worklet' && path.getFunctionParent() === fun) {
@@ -358,8 +414,17 @@ function makeWorklet(t, fun, state) {
358
414
  // We use copy because some of the plugins don't update bindings and
359
415
  // some even break them
360
416
 
417
+ const codeObject = generate(fun.node, {
418
+ sourceMaps: true,
419
+ sourceFileName: state.file.opts.filename,
420
+ });
421
+
422
+ // We need to add a newline at the end, because there could potentially be a
423
+ // comment after the function that gets included here, and then the closing
424
+ // bracket would become part of the comment thus resulting in an error, since
425
+ // there is a missing closing bracket.
361
426
  const code =
362
- '\n(' + (t.isObjectMethod(fun) ? 'function ' : '') + fun.toString() + '\n)';
427
+ '(' + (t.isObjectMethod(fun) ? 'function ' : '') + codeObject.code + '\n)';
363
428
 
364
429
  const transformed = transformSync(code, {
365
430
  filename: state.file.opts.filename,
@@ -374,7 +439,9 @@ function makeWorklet(t, fun, state) {
374
439
  ast: true,
375
440
  babelrc: false,
376
441
  configFile: false,
442
+ inputSourceMap: codeObject.map,
377
443
  });
444
+
378
445
  if (
379
446
  fun.parent &&
380
447
  fun.parent.callee &&
@@ -418,17 +485,6 @@ function makeWorklet(t, fun, state) {
418
485
  closure.set(name, path.node);
419
486
  closureGenerator.addPath(name, path);
420
487
  },
421
- AssignmentExpression(path) {
422
- // test for <something>.value = <something> expressions
423
- const left = path.node.left;
424
- if (
425
- t.isMemberExpression(left) &&
426
- t.isIdentifier(left.object) &&
427
- t.isIdentifier(left.property, { name: 'value' })
428
- ) {
429
- outputs.add(left.object.name);
430
- }
431
- },
432
488
  });
433
489
 
434
490
  const variables = Array.from(closure.values());
@@ -441,16 +497,18 @@ function makeWorklet(t, fun, state) {
441
497
  } else {
442
498
  funExpression = clone;
443
499
  }
500
+
444
501
  const funString = buildWorkletString(
445
502
  t,
446
503
  transformed.ast,
447
504
  variables,
448
- functionName
505
+ functionName,
506
+ transformed.map
449
507
  );
450
508
  const workletHash = hash(funString);
451
509
 
452
510
  let location = state.file.opts.filename;
453
- if (state.opts.relativeSourceLocation) {
511
+ if (state.opts && state.opts.relativeSourceLocation) {
454
512
  const path = require('path');
455
513
  location = path.relative(state.cwd, location);
456
514
  }
@@ -54,6 +54,8 @@ declare module 'react-native-reanimated' {
54
54
  import('./lib/types/lib/reanimated2/animation/index').StyleLayoutAnimation;
55
55
  export type Animation<T> =
56
56
  import('./lib/types/lib/reanimated2/commonTypes').Animation<T>;
57
+ export type MeasuredDimensions =
58
+ import('./lib/types/lib/reanimated2/commonTypes').MeasuredDimensions;
57
59
 
58
60
  namespace Animated {
59
61
  type Nullable<T> = T | null | undefined;
@@ -543,8 +545,13 @@ declare module 'react-native-reanimated' {
543
545
  isActive: boolean;
544
546
  callbackId: number;
545
547
  };
548
+ export type FrameInfo = {
549
+ timestamp: number;
550
+ timeSincePreviousFrame: number | null;
551
+ timeSinceFirstFrame: number;
552
+ };
546
553
  export function useFrameCallback(
547
- callback: () => void,
554
+ callback: (frameInfo: FrameInfo) => void,
548
555
  autostart?: boolean
549
556
  ): FrameCallback;
550
557
 
@@ -561,6 +568,10 @@ declare module 'react-native-reanimated' {
561
568
  };
562
569
  export function useAnimatedKeyboard(): AnimatedKeyboardInfo;
563
570
 
571
+ export function useScrollViewOffset(
572
+ aref: RefObject<Animated.ScrollView>
573
+ ): SharedValue<number>;
574
+
564
575
  export interface ExitAnimationsValues {
565
576
  currentOriginX: number;
566
577
  currentOriginY: number;
@@ -805,14 +816,7 @@ declare module 'react-native-reanimated' {
805
816
  export function defineAnimation<T>(starting: any, factory: () => T): number;
806
817
  export function measure<T extends Component>(
807
818
  ref: RefObject<T>
808
- ): {
809
- width: number;
810
- height: number;
811
- x: number;
812
- y: number;
813
- pageX: number;
814
- pageY: number;
815
- };
819
+ ): MeasuredDimensions | null;
816
820
 
817
821
  export function getRelativeCoords(
818
822
  ref: RefObject<Component>,
@@ -0,0 +1,77 @@
1
+ def try_to_parse_react_native_package_json(node_modules_dir)
2
+ react_native_package_json_path = File.join(node_modules_dir, 'react-native/package.json')
3
+ if !File.exists?(react_native_package_json_path)
4
+ return nil
5
+ end
6
+ return JSON.parse(File.read(react_native_package_json_path))
7
+ end
8
+
9
+ def find_config()
10
+ result = {
11
+ :is_reanimated_example_app => nil,
12
+ :react_native_version => nil,
13
+ :react_native_minor_version => nil,
14
+ :is_tvos_target => nil,
15
+ :react_native_node_modules_dir => nil,
16
+ :reanimated_node_modules_dir => nil,
17
+ :react_native_common_dir => nil,
18
+ }
19
+
20
+ react_native_node_modules_dir = File.join(File.dirname(`cd #{Pod::Config.instance.installation_root.to_s} && node --print "require.resolve('react-native/package.json')"`), '..')
21
+ react_native_json = try_to_parse_react_native_package_json(react_native_node_modules_dir)
22
+
23
+ if react_native_json == nil
24
+ # user configuration, just in case
25
+ node_modules_dir = ENV["REACT_NATIVE_NODE_MODULES_DIR"]
26
+ react_native_json = try_to_parse_react_native_package_json(node_modules_dir)
27
+ end
28
+
29
+ if react_native_json == nil
30
+ raise '[RNReanimated] Unable to recognize your `react-native` version! Please set environmental variable with `react-native` locations: `export REACT_NATIVE_NODE_MODULES_DIR="<path to react-native>" && pod install'
31
+ end
32
+
33
+ result[:is_reanimated_example_app] = ENV["REANIMATED_EXAMPLE_APP_NAME"] != nil
34
+ result[:is_tvos_target] = react_native_json['name'] == 'react-native-tvos'
35
+ result[:react_native_version] = react_native_json['version']
36
+ result[:react_native_minor_version] = react_native_json['version'].split('.')[1].to_i
37
+ result[:react_native_node_modules_dir] = File.expand_path(react_native_node_modules_dir)
38
+ result[:reanimated_node_modules_dir] = File.expand_path(File.join(__dir__, '..', '..'))
39
+
40
+ pods_root = Pod::Config.instance.project_pods_root
41
+ react_native_common_dir_absolute = File.join(react_native_node_modules_dir, 'react-native', 'ReactCommon')
42
+ react_native_common_dir_relative = Pathname.new(react_native_common_dir_absolute).relative_path_from(pods_root).to_s
43
+ result[:react_native_common_dir] = react_native_common_dir_relative
44
+
45
+ return result
46
+ end
47
+
48
+ def assert_no_multiple_instances(react_native_info)
49
+ if react_native_info[:is_reanimated_example_app]
50
+ return
51
+ end
52
+
53
+ lib_instances_in_react_native_node_modules = %x[find #{react_native_info[:react_native_node_modules_dir]} -name "package.json" | grep "/react-native-reanimated/package.json"]
54
+ lib_instances_in_react_native_node_modules_array = lib_instances_in_react_native_node_modules.split("\n")
55
+ reanimated_instances = lib_instances_in_react_native_node_modules_array.length()
56
+ if react_native_info[:react_native_node_modules_dir] != react_native_info[:reanimated_node_modules_dir]
57
+ lib_instances_in_reanimated_node_modules = %x[find #{react_native_info[:reanimated_node_modules_dir]} -name "package.json" | grep "/react-native-reanimated/package.json"]
58
+ lib_instances_in_reanimated_node_modules_array = lib_instances_in_reanimated_node_modules.split("\n")
59
+ reanimated_instances += lib_instances_in_reanimated_node_modules_array.length()
60
+ end
61
+ if reanimated_instances > 1
62
+ parsed_location = ''
63
+ for location in lib_instances_in_react_native_node_modules_array + lib_instances_in_reanimated_node_modules_array
64
+ location['/package.json'] = ''
65
+ parsed_location += "- " + location + "\n"
66
+ end
67
+ raise "[react-native-reanimated] Multiple versions of Reanimated were detected. Only one instance of react-native-reanimated can be installed in a project. You need to resolve the conflict manually. Check out the documentation: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/troubleshooting#multiple-versions-of-reanimated-were-detected \n\nConflict between: \n" + parsed_location
68
+ end
69
+ end
70
+
71
+ def assert_no_reanimated2_with_new_architecture(reanimated_package_json)
72
+ reanimated_major_version = reanimated_package_json['version'].split('.')[0].to_i
73
+ fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
74
+ if fabric_enabled && reanimated_major_version == 2
75
+ raise "[react-native-reanimated] Reanimated 2.x does not support Fabric. Please upgrade to 3.x to use Reanimated with the New Architecture. For details, see https://blog.swmansion.com/announcing-reanimated-3-16167428c5f7"
76
+ end
77
+ end
@@ -400,12 +400,11 @@ export default function createAnimatedComponent(
400
400
  // TODO update config
401
401
  const tag = findNodeHandle(ref);
402
402
  if (
403
+ !shouldBeUseWeb() &&
403
404
  (this.props.layout || this.props.entering || this.props.exiting) &&
404
405
  tag != null
405
406
  ) {
406
- if (!shouldBeUseWeb()) {
407
- enableLayoutAnimations(true, false);
408
- }
407
+ enableLayoutAnimations(true, false);
409
408
  let layout = this.props.layout ? this.props.layout : DefaultLayout;
410
409
  let entering = this.props.entering
411
410
  ? this.props.entering
@@ -1,10 +1,9 @@
1
1
  /* global _WORKLET _measure _scrollTo _dispatchCommand _setGestureState */
2
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
- // @ts-nocheck
4
2
  import { Component } from 'react';
5
3
  import { findNodeHandle } from 'react-native';
6
- import { RefObjectFunction } from './commonTypes';
7
- import { shouldBeUseWeb } from './PlatformChecker';
4
+ import { MeasuredDimensions } from './commonTypes';
5
+ import { RefObjectFunction } from './hook/commonTypes';
6
+ import { isChromeDebugger, isWeb, shouldBeUseWeb } from './PlatformChecker';
8
7
 
9
8
  export function getTag(
10
9
  view: null | number | React.Component<any, any> | React.ComponentClass<any>
@@ -12,45 +11,73 @@ export function getTag(
12
11
  return findNodeHandle(view);
13
12
  }
14
13
 
15
- export interface MeasuredDimensions {
16
- x: number;
17
- y: number;
18
- width: number;
19
- height: number;
20
- pageX: number;
21
- pageY: number;
22
- }
23
-
24
- const isNativeIndefined = shouldBeUseWeb();
14
+ const isNative = !shouldBeUseWeb();
25
15
 
26
- export function measure(
16
+ export let measure: (
27
17
  animatedRef: RefObjectFunction<Component>
28
- ): MeasuredDimensions {
29
- 'worklet';
30
- if (!_WORKLET || isNativeIndefined) {
31
- console.warn(
32
- '[reanimated.measure] method cannot be used for web or Chrome Debugger'
33
- );
18
+ ) => MeasuredDimensions | null;
19
+
20
+ if (isWeb()) {
21
+ measure = (animatedRef: RefObjectFunction<Component>) => {
22
+ const element = animatedRef() as unknown as HTMLElement; // TODO: fix typing of animated refs on web
23
+ const viewportOffset = element.getBoundingClientRect();
34
24
  return {
35
- x: NaN,
36
- y: NaN,
37
- width: NaN,
38
- height: NaN,
39
- pageX: NaN,
40
- pageY: NaN,
25
+ width: element.offsetWidth,
26
+ height: element.offsetHeight,
27
+ x: element.offsetLeft,
28
+ y: element.offsetTop,
29
+ pageX: viewportOffset.left,
30
+ pageY: viewportOffset.top,
41
31
  };
42
- }
43
- const viewTag = animatedRef();
44
- const result = _measure(viewTag);
45
- if (result.x === -1234567) {
46
- throw new Error(`The view with tag ${viewTag} could not be measured`);
47
- }
48
- if (isNaN(result.x)) {
49
- console.warn(
50
- 'Trying to measure a component which gets view-flattened on Android. To disable view-flattening, set `collapsable={false}` on this component.'
51
- );
52
- }
53
- return result;
32
+ };
33
+ } else if (isChromeDebugger()) {
34
+ measure = (_animatedRef: RefObjectFunction<Component>) => {
35
+ console.warn('[Reanimated] measure() cannot be used with Chrome Debugger.');
36
+ return null;
37
+ };
38
+ } else {
39
+ measure = (animatedRef: RefObjectFunction<Component>) => {
40
+ 'worklet';
41
+ if (!_WORKLET) {
42
+ console.warn(
43
+ '[Reanimated] measure() was called from the main JS context. Measure is ' +
44
+ 'only available in the UI runtime. This may also happen if measure() ' +
45
+ 'was called by a worklet in the useAnimatedStyle hook, because useAnimatedStyle ' +
46
+ 'calls the given worklet on the JS runtime during render. If you want to ' +
47
+ 'prevent this warning then wrap the call with `if (_WORKLET)`. Then it will ' +
48
+ 'only be called on the UI runtime after the render has been completed.'
49
+ );
50
+ return null;
51
+ }
52
+
53
+ const viewTag = animatedRef();
54
+ if (viewTag === -1) {
55
+ console.warn(
56
+ `[Reanimated] The view with tag ${viewTag} is not a valid argument for measure(). This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
57
+ );
58
+ return null;
59
+ }
60
+
61
+ const measured = _measure(viewTag);
62
+ if (measured === null) {
63
+ console.warn(
64
+ `[Reanimated] The view with tag ${viewTag} has some undefined, not-yet-computed or meaningless value of \`LayoutMetrics\` type. This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
65
+ );
66
+ return null;
67
+ } else if (measured.x === -1234567) {
68
+ console.warn(
69
+ `[Reanimated] The view with tag ${viewTag} returned an invalid measurement response.`
70
+ );
71
+ return null;
72
+ } else if (isNaN(measured.x)) {
73
+ console.warn(
74
+ `[Reanimated] The view with tag ${viewTag} gets view-flattened on Android. To disable view-flattening, set \`collapsable={false}\` on this component.`
75
+ );
76
+ return null;
77
+ } else {
78
+ return measured;
79
+ }
80
+ };
54
81
  }
55
82
 
56
83
  export function dispatchCommand(
@@ -59,7 +86,7 @@ export function dispatchCommand(
59
86
  args: Array<unknown>
60
87
  ): void {
61
88
  'worklet';
62
- if (!_WORKLET || isNativeIndefined) {
89
+ if (!_WORKLET || !isNative) {
63
90
  return;
64
91
  }
65
92
  const shadowNodeWrapper = animatedRef();
@@ -73,7 +100,19 @@ export let scrollTo: (
73
100
  animated: boolean
74
101
  ) => void;
75
102
 
76
- if (global._IS_FABRIC) {
103
+ if (isWeb()) {
104
+ scrollTo = (
105
+ animatedRef: RefObjectFunction<Component>,
106
+ x: number,
107
+ y: number,
108
+ animated: boolean
109
+ ) => {
110
+ 'worklet';
111
+ const element = animatedRef() as unknown as HTMLElement;
112
+ // @ts-ignore same call as in react-native-web
113
+ element.scrollTo({ x, y, animated });
114
+ };
115
+ } else if (isNative && global._IS_FABRIC) {
77
116
  scrollTo = (
78
117
  animatedRef: RefObjectFunction<Component>,
79
118
  x: number,
@@ -83,7 +122,7 @@ if (global._IS_FABRIC) {
83
122
  'worklet';
84
123
  dispatchCommand(animatedRef, 'scrollTo', [x, y, animated]);
85
124
  };
86
- } else {
125
+ } else if (isNative) {
87
126
  scrollTo = (
88
127
  animatedRef: RefObjectFunction<Component>,
89
128
  x: number,
@@ -91,17 +130,25 @@ if (global._IS_FABRIC) {
91
130
  animated: boolean
92
131
  ) => {
93
132
  'worklet';
94
- if (!_WORKLET || isNativeIndefined) {
133
+ if (!_WORKLET) {
95
134
  return;
96
135
  }
97
136
  const viewTag = animatedRef();
98
137
  _scrollTo(viewTag, x, y, animated);
99
138
  };
139
+ } else {
140
+ scrollTo = (
141
+ _animatedRef: RefObjectFunction<Component>,
142
+ _x: number,
143
+ _y: number
144
+ ) => {
145
+ // no-op
146
+ };
100
147
  }
101
148
 
102
149
  export function setGestureState(handlerTag: number, newState: number): void {
103
150
  'worklet';
104
- if (!_WORKLET || isNativeIndefined) {
151
+ if (!_WORKLET || !isNative) {
105
152
  console.warn(
106
153
  '[Reanimated] You can not use setGestureState in non-worklet function.'
107
154
  );
@@ -75,15 +75,3 @@ export function withDelay(
75
75
  };
76
76
  });
77
77
  }
78
-
79
- /**
80
- * @deprecated Kept for backward compatibility. Will be removed soon.
81
- */
82
- export function delay(
83
- delayMs: number,
84
- _nextAnimation: NextAnimation<DelayAnimation>
85
- ): Animation<DelayAnimation> {
86
- 'worklet';
87
- console.warn('Method `delay` is deprecated. Please use `withDelay` instead');
88
- return withDelay(delayMs, _nextAnimation);
89
- }
@@ -91,28 +91,3 @@ export function withRepeat(
91
91
  } as RepeatAnimation;
92
92
  });
93
93
  }
94
-
95
- /**
96
- * @deprecated Kept for backward compatibility. Will be removed soon.
97
- */
98
- export function repeat(
99
- _nextAnimation: NextAnimation<RepeatAnimation>,
100
- numberOfReps = 2,
101
- reverse = false,
102
- callback?: AnimationCallback
103
- ): Animation<RepeatAnimation> {
104
- 'worklet';
105
- console.warn(
106
- 'Method `repeat` is deprecated. Please use `withRepeat` instead'
107
- );
108
- return withRepeat(_nextAnimation, numberOfReps, reverse, callback);
109
- }
110
-
111
- export function loop(
112
- nextAnimation: NextAnimation<RepeatAnimation>,
113
- numberOfLoops = 1
114
- ): Animation<RepeatAnimation> {
115
- 'worklet';
116
- console.warn('Method `loop` is deprecated. Please use `withRepeat` instead');
117
- return repeat(nextAnimation, Math.round(numberOfLoops * 2), true);
118
- }
@@ -83,16 +83,3 @@ export function withSequence(
83
83
  }
84
84
  );
85
85
  }
86
-
87
- /**
88
- * @deprecated Kept for backward compatibility. Will be removed soon.
89
- */
90
- export function sequence(
91
- ..._animations: NextAnimation<SequenceAnimation>[]
92
- ): Animation<SequenceAnimation> {
93
- 'worklet';
94
- console.warn(
95
- 'Method `sequence` is deprecated. Please use `withSequence` instead'
96
- );
97
- return withSequence(..._animations);
98
- }
@@ -161,3 +161,12 @@ export type AnimatedKeyboardInfo = {
161
161
  height: SharedValue<number>;
162
162
  state: SharedValue<KeyboardState>;
163
163
  };
164
+
165
+ export interface MeasuredDimensions {
166
+ x: number;
167
+ y: number;
168
+ width: number;
169
+ height: number;
170
+ pageX: number;
171
+ pageY: number;
172
+ }
@@ -1,5 +1,5 @@
1
1
  import { runOnUI } from '../core';
2
- import { prepareUIRegistry } from './FrameCallbackRegistryUI';
2
+ import { FrameInfo, prepareUIRegistry } from './FrameCallbackRegistryUI';
3
3
 
4
4
  export default class FrameCallbackRegistryJS {
5
5
  private nextCallbackId = 0;
@@ -8,7 +8,7 @@ export default class FrameCallbackRegistryJS {
8
8
  prepareUIRegistry();
9
9
  }
10
10
 
11
- registerFrameCallback(callback: () => void): number {
11
+ registerFrameCallback(callback: (frameInfo: FrameInfo) => void): number {
12
12
  if (!callback) {
13
13
  return -1;
14
14
  }
@@ -24,20 +24,17 @@ export default class FrameCallbackRegistryJS {
24
24
  return callbackId;
25
25
  }
26
26
 
27
- unregisterFrameCallback(frameCallbackId: number): void {
27
+ unregisterFrameCallback(callbackId: number): void {
28
28
  runOnUI(() => {
29
29
  'worklet';
30
- global._frameCallbackRegistry.unregisterFrameCallback(frameCallbackId);
30
+ global._frameCallbackRegistry.unregisterFrameCallback(callbackId);
31
31
  })();
32
32
  }
33
33
 
34
- manageStateFrameCallback(frameCallbackId: number, state: boolean): void {
34
+ manageStateFrameCallback(callbackId: number, state: boolean): void {
35
35
  runOnUI(() => {
36
36
  'worklet';
37
- global._frameCallbackRegistry.manageStateFrameCallback(
38
- frameCallbackId,
39
- state
40
- );
37
+ global._frameCallbackRegistry.manageStateFrameCallback(callbackId, state);
41
38
  })();
42
39
  }
43
40
  }