From f820cba57a674bf2b1abf4673b4583ae7410a9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBelawski?= <40713406+tjzel@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:48:08 +0100 Subject: [PATCH] chore: Add noop typescript worklets module (#6650) ## Summary Preparing for #6539 ## Test plan This PR has no real runtime impact --- .../src/ReanimatedModule/NativeReanimated.ts | 61 +++------------ .../src/ReanimatedModule/index.ts | 8 +- .../js-reanimated/JSReanimated.ts | 9 ++- .../reanimatedModuleInstance.ts | 9 +++ .../reanimatedModuleInstance.web.ts | 5 ++ .../ReanimatedModule/reanimatedModuleProxy.ts | 74 +++++++++++++++++++ .../src/commonTypes.ts | 2 + .../src/privateGlobals.d.ts | 2 +- .../src/worklets/WorkletsModule/JSWorklets.ts | 9 +++ .../worklets/WorkletsModule/NativeWorklets.ts | 9 +++ .../src/worklets/WorkletsModule/index.ts | 3 + .../WorkletsModule/workletsModuleInstance.ts | 9 +++ .../workletsModuleInstance.web.ts | 5 ++ .../src/worklets/index.ts | 3 + 14 files changed, 149 insertions(+), 59 deletions(-) create mode 100644 packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.ts create mode 100644 packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.web.ts create mode 100644 packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleProxy.ts create mode 100644 packages/react-native-reanimated/src/worklets/WorkletsModule/JSWorklets.ts create mode 100644 packages/react-native-reanimated/src/worklets/WorkletsModule/NativeWorklets.ts create mode 100644 packages/react-native-reanimated/src/worklets/WorkletsModule/index.ts create mode 100644 packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.ts create mode 100644 packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.web.ts create mode 100644 packages/react-native-reanimated/src/worklets/index.ts diff --git a/packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts b/packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts index 9303264ec10..5c8eb576d50 100644 --- a/packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts +++ b/packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts @@ -1,11 +1,11 @@ 'use strict'; import type { - ShadowNodeWrapper, Value3D, ValueRotation, ShareableRef, LayoutAnimationBatchItem, IReanimatedModule, + IWorkletsModule, } from '../commonTypes'; import { checkCppVersion } from '../platform-specific/checkCppVersion'; import { jsVersion } from '../platform-specific/jsVersion'; @@ -16,60 +16,13 @@ import type React from 'react'; import { getShadowNodeWrapperFromRef } from '../fabricUtils'; import { ReanimatedTurboModule } from '../specs'; import { ReanimatedError } from '../errors'; +import { WorkletsModule } from '../worklets'; +import type { ReanimatedModuleProxy } from './reanimatedModuleProxy'; -export function createNativeReanimatedModule() { +export function createNativeReanimatedModule(): IReanimatedModule { return new NativeReanimatedModule(); } -// this is the type of `__reanimatedModuleProxy` which is injected using JSI -export interface ReanimatedModuleProxy { - makeShareableClone( - value: T, - shouldPersistRemote: boolean, - nativeStateSource?: object - ): ShareableRef; - scheduleOnUI(shareable: ShareableRef): void; - executeOnUIRuntimeSync(shareable: ShareableRef): R; - createWorkletRuntime( - name: string, - initializer: ShareableRef<() => void> - ): WorkletRuntime; - scheduleOnRuntime( - workletRuntime: WorkletRuntime, - worklet: ShareableRef - ): void; - registerEventHandler( - eventHandler: ShareableRef, - eventName: string, - emitterReactTag: number - ): number; - unregisterEventHandler(id: number): void; - getViewProp( - viewTagOrShadowNodeWrapper: number | ShadowNodeWrapper, - propName: string, - callback?: (result: T) => void - ): Promise; - enableLayoutAnimations(flag: boolean): void; - registerSensor( - sensorType: number, - interval: number, - iosReferenceFrame: number, - handler: ShareableRef<(data: Value3D | ValueRotation) => void> - ): number; - unregisterSensor(sensorId: number): void; - configureProps(uiProps: string[], nativeProps: string[]): void; - subscribeForKeyboardEvents( - handler: ShareableRef, - isStatusBarTranslucent: boolean, - isNavigationBarTranslucent: boolean - ): number; - unsubscribeFromKeyboardEvents(listenerId: number): void; - configureLayoutAnimationBatch( - layoutAnimationsBatch: LayoutAnimationBatchItem[] - ): void; - setShouldAnimateExitingForTag(viewTag: number, shouldAnimate: boolean): void; -} - function assertSingleReanimatedInstance() { if ( global._REANIMATED_VERSION_JS !== undefined && @@ -83,9 +36,15 @@ See \`https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshoo } class NativeReanimatedModule implements IReanimatedModule { + /** + * We keep the instance of `WorkletsModule` here to keep correct coupling of + * the modules and initialization order. + */ + #workletsModule: IWorkletsModule; #reanimatedModuleProxy: ReanimatedModuleProxy; constructor() { + this.#workletsModule = WorkletsModule; // These checks have to split since version checking depend on the execution order if (__DEV__) { assertSingleReanimatedInstance(); diff --git a/packages/react-native-reanimated/src/ReanimatedModule/index.ts b/packages/react-native-reanimated/src/ReanimatedModule/index.ts index 594d30d50fe..0a49b2efc7e 100644 --- a/packages/react-native-reanimated/src/ReanimatedModule/index.ts +++ b/packages/react-native-reanimated/src/ReanimatedModule/index.ts @@ -1,8 +1,4 @@ 'use strict'; -import { createJSReanimatedModule } from './js-reanimated'; -import { shouldBeUseWeb } from '../PlatformChecker'; -import { createNativeReanimatedModule } from './NativeReanimated'; -export const ReanimatedModule = shouldBeUseWeb() - ? createJSReanimatedModule() - : createNativeReanimatedModule(); +export { ReanimatedModule } from './reanimatedModuleInstance'; +export type { ReanimatedModuleProxy } from './reanimatedModuleProxy'; diff --git a/packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts b/packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts index fa14b539273..05c04c97e74 100644 --- a/packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts +++ b/packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts @@ -8,6 +8,7 @@ import { import { SensorType } from '../../commonTypes'; import type { IReanimatedModule, + IWorkletsModule, ShareableRef, Value3D, ValueRotation, @@ -17,8 +18,9 @@ import { mockedRequestAnimationFrame } from '../../mockedRequestAnimationFrame'; import type { WorkletRuntime } from '../../runtimes'; import { logger } from '../../logger'; import { ReanimatedError } from '../../errors'; +import { WorkletsModule } from '../../worklets'; -export function createJSReanimatedModule() { +export function createJSReanimatedModule(): IReanimatedModule { return new JSReanimated(); } @@ -31,6 +33,11 @@ const requestAnimationFrameImpl = : globalThis.requestAnimationFrame; class JSReanimated implements IReanimatedModule { + /** + * We keep the instance of `WorkletsModule` here to keep correct coupling of + * the modules and initialization order. + */ + #workletsModule: IWorkletsModule = WorkletsModule; nextSensorId = 0; sensors = new Map(); platform?: Platform = undefined; diff --git a/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.ts b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.ts new file mode 100644 index 00000000000..134c73d4af6 --- /dev/null +++ b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.ts @@ -0,0 +1,9 @@ +'use strict'; + +import { createJSReanimatedModule } from './js-reanimated'; +import { shouldBeUseWeb } from '../PlatformChecker'; +import { createNativeReanimatedModule } from './NativeReanimated'; + +export const ReanimatedModule = shouldBeUseWeb() + ? createJSReanimatedModule() + : createNativeReanimatedModule(); diff --git a/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.web.ts b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.web.ts new file mode 100644 index 00000000000..c38452e8f72 --- /dev/null +++ b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.web.ts @@ -0,0 +1,5 @@ +'use strict'; + +import { createJSReanimatedModule } from './js-reanimated'; + +export const ReanimatedModule = createJSReanimatedModule(); diff --git a/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleProxy.ts b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleProxy.ts new file mode 100644 index 00000000000..70fc5c7f0c2 --- /dev/null +++ b/packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleProxy.ts @@ -0,0 +1,74 @@ +'use strict'; + +import type { + ShareableRef, + ShadowNodeWrapper, + Value3D, + ValueRotation, + LayoutAnimationBatchItem, +} from '../commonTypes'; +import type { WorkletRuntime } from '../runtimes'; + +/** Type of `__reanimatedModuleProxy` injected with JSI. */ +export interface ReanimatedModuleProxy { + makeShareableClone( + value: T, + shouldPersistRemote: boolean, + nativeStateSource?: object + ): ShareableRef; + + scheduleOnUI(shareable: ShareableRef): void; + + executeOnUIRuntimeSync(shareable: ShareableRef): R; + + createWorkletRuntime( + name: string, + initializer: ShareableRef<() => void> + ): WorkletRuntime; + + scheduleOnRuntime( + workletRuntime: WorkletRuntime, + worklet: ShareableRef + ): void; + + registerEventHandler( + eventHandler: ShareableRef, + eventName: string, + emitterReactTag: number + ): number; + + unregisterEventHandler(id: number): void; + + getViewProp( + viewTagOrShadowNodeWrapper: number | ShadowNodeWrapper, + propName: string, + callback?: (result: T) => void + ): Promise; + + enableLayoutAnimations(flag: boolean): void; + + registerSensor( + sensorType: number, + interval: number, + iosReferenceFrame: number, + handler: ShareableRef<(data: Value3D | ValueRotation) => void> + ): number; + + unregisterSensor(sensorId: number): void; + + configureProps(uiProps: string[], nativeProps: string[]): void; + + subscribeForKeyboardEvents( + handler: ShareableRef, + isStatusBarTranslucent: boolean, + isNavigationBarTranslucent: boolean + ): number; + + unsubscribeFromKeyboardEvents(listenerId: number): void; + + configureLayoutAnimationBatch( + layoutAnimationsBatch: LayoutAnimationBatchItem[] + ): void; + + setShouldAnimateExitingForTag(viewTag: number, shouldAnimate: boolean): void; +} diff --git a/packages/react-native-reanimated/src/commonTypes.ts b/packages/react-native-reanimated/src/commonTypes.ts index fd9082ef420..924650b8903 100644 --- a/packages/react-native-reanimated/src/commonTypes.ts +++ b/packages/react-native-reanimated/src/commonTypes.ts @@ -7,6 +7,8 @@ import type { } from 'react-native'; import type { WorkletRuntime } from './runtimes'; +export interface IWorkletsModule {} + export interface IReanimatedModule { registerSensor( sensorType: number, diff --git a/packages/react-native-reanimated/src/privateGlobals.d.ts b/packages/react-native-reanimated/src/privateGlobals.d.ts index 3a295a54b80..6b201f4300a 100644 --- a/packages/react-native-reanimated/src/privateGlobals.d.ts +++ b/packages/react-native-reanimated/src/privateGlobals.d.ts @@ -15,7 +15,7 @@ import type { } from './commonTypes'; import type { AnimatedStyle } from './helperTypes'; import type { FrameCallbackRegistryUI } from './frameCallback/FrameCallbackRegistryUI'; -import type { ReanimatedModuleProxy } from './ReanimatedModule/NativeReanimated'; +import type { ReanimatedModuleProxy } from './ReanimatedModule'; import type { SensorContainer } from './SensorContainer'; import type { LayoutAnimationsManager } from './layoutReanimation/animationsManager'; import type { ProgressTransitionRegister } from './layoutReanimation/sharedTransitions'; diff --git a/packages/react-native-reanimated/src/worklets/WorkletsModule/JSWorklets.ts b/packages/react-native-reanimated/src/worklets/WorkletsModule/JSWorklets.ts new file mode 100644 index 00000000000..95b0978d214 --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/WorkletsModule/JSWorklets.ts @@ -0,0 +1,9 @@ +'use strict'; + +import type { IWorkletsModule } from '../../commonTypes'; + +export function createJSWorkletsModule(): IWorkletsModule { + return new JSWorklets(); +} + +class JSWorklets implements IWorkletsModule {} diff --git a/packages/react-native-reanimated/src/worklets/WorkletsModule/NativeWorklets.ts b/packages/react-native-reanimated/src/worklets/WorkletsModule/NativeWorklets.ts new file mode 100644 index 00000000000..b0d5675ebf8 --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/WorkletsModule/NativeWorklets.ts @@ -0,0 +1,9 @@ +'use strict'; + +import type { IWorkletsModule } from '../../commonTypes'; + +export function createNativeWorkletsModule(): IWorkletsModule { + return new NativeWorklets(); +} + +class NativeWorklets {} diff --git a/packages/react-native-reanimated/src/worklets/WorkletsModule/index.ts b/packages/react-native-reanimated/src/worklets/WorkletsModule/index.ts new file mode 100644 index 00000000000..76e617320c5 --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/WorkletsModule/index.ts @@ -0,0 +1,3 @@ +'use strict'; + +export { WorkletsModule } from './workletsModuleInstance'; diff --git a/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.ts b/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.ts new file mode 100644 index 00000000000..483059436a0 --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.ts @@ -0,0 +1,9 @@ +'use strict'; + +import { createNativeWorkletsModule } from './NativeWorklets'; +import { shouldBeUseWeb } from '../../PlatformChecker'; +import { createJSWorkletsModule } from './JSWorklets'; + +export const WorkletsModule = shouldBeUseWeb() + ? createJSWorkletsModule() + : createNativeWorkletsModule(); diff --git a/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.web.ts b/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.web.ts new file mode 100644 index 00000000000..93c11d4d1d1 --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/WorkletsModule/workletsModuleInstance.web.ts @@ -0,0 +1,5 @@ +'use strict'; + +import { createJSWorkletsModule } from './JSWorklets'; + +export const WorkletsModule = createJSWorkletsModule(); diff --git a/packages/react-native-reanimated/src/worklets/index.ts b/packages/react-native-reanimated/src/worklets/index.ts new file mode 100644 index 00000000000..5d2e021f26a --- /dev/null +++ b/packages/react-native-reanimated/src/worklets/index.ts @@ -0,0 +1,3 @@ +'use strict'; + +export { WorkletsModule } from './WorkletsModule';