'use strict'; import { checkCppVersion } from '../debug/checkCppVersion'; import { jsVersion } from '../debug/jsVersion'; import { WorkletsError } from '../debug/WorkletsError'; import type { SerializableRef, SynchronizableRef } from '../memory/types'; import { RuntimeKind } from '../runtimeKind'; import { WorkletsTurboModule } from '../specs'; import type { WorkletRuntime } from '../types'; import type { IWorkletsModule, WorkletsModuleProxy, } from './workletsModuleProxy'; class NativeWorklets implements IWorkletsModule { #workletsModuleProxy: WorkletsModuleProxy; #serializableUndefined: SerializableRef; #serializableNull: SerializableRef; #serializableTrue: SerializableRef; #serializableFalse: SerializableRef; constructor() { const bundleModeEnabled = globalThis._WORKLETS_BUNDLE_MODE_ENABLED ?? false; globalThis._WORKLETS_VERSION_JS = jsVersion; if ( global.__workletsModuleProxy === undefined && globalThis.__RUNTIME_KIND === RuntimeKind.ReactNative ) { WorkletsTurboModule?.installTurboModule(bundleModeEnabled); if (__DEV__ && bundleModeEnabled) { console.log( '[Worklets] Bundle mode initialization: Downloaded the bundle for Worklet Runtimes.' ); } } if (global.__workletsModuleProxy === undefined) { throw new WorkletsError( `Native part of Worklets doesn't seem to be initialized. See https://docs.swmansion.com/react-native-worklets/docs/guides/troubleshooting#native-part-of-worklets-doesnt-seem-to-be-initialized for more details.` ); } if (__DEV__ && globalThis.__RUNTIME_KIND === RuntimeKind.ReactNative) { checkCppVersion(); } this.#workletsModuleProxy = global.__workletsModuleProxy; this.#serializableNull = this.#workletsModuleProxy.createSerializableNull(); this.#serializableUndefined = this.#workletsModuleProxy.createSerializableUndefined(); this.#serializableTrue = this.#workletsModuleProxy.createSerializableBoolean(true); this.#serializableFalse = this.#workletsModuleProxy.createSerializableBoolean(false); } createSerializable( value: TValue, shouldPersistRemote: boolean, nativeStateSource?: object ) { return this.#workletsModuleProxy.createSerializable( value, shouldPersistRemote, nativeStateSource ); } createSerializableImport( from: string, to: string ): SerializableRef { return this.#workletsModuleProxy.createSerializableImport(from, to); } createSerializableString(str: string) { return this.#workletsModuleProxy.createSerializableString(str); } createSerializableNumber(num: number) { return this.#workletsModuleProxy.createSerializableNumber(num); } createSerializableBoolean(bool: boolean) { return bool ? this.#serializableTrue : this.#serializableFalse; } createSerializableBigInt(bigInt: bigint) { return this.#workletsModuleProxy.createSerializableBigInt(bigInt); } createSerializableUndefined() { return this.#serializableUndefined; } createSerializableNull() { return this.#serializableNull; } createSerializableTurboModuleLike< TProps extends object, TProto extends object, >(props: TProps, proto: TProto): SerializableRef { return this.#workletsModuleProxy.createSerializableTurboModuleLike( props, proto ); } createSerializableObject( obj: T, shouldRetainRemote: boolean, nativeStateSource?: object ): SerializableRef { return this.#workletsModuleProxy.createSerializableObject( obj, shouldRetainRemote, nativeStateSource ); } createSerializableHostObject(obj: T) { return this.#workletsModuleProxy.createSerializableHostObject(obj); } createSerializableArray(array: unknown[], shouldRetainRemote: boolean) { return this.#workletsModuleProxy.createSerializableArray( array, shouldRetainRemote ); } createSerializableMap( keys: TKey[], values: TValue[] ): SerializableRef> { return this.#workletsModuleProxy.createSerializableMap(keys, values); } createSerializableSet( values: TValues[] ): SerializableRef> { return this.#workletsModuleProxy.createSerializableSet(values); } createSerializableInitializer(obj: object) { return this.#workletsModuleProxy.createSerializableInitializer(obj); } createSerializableFunction( func: (...args: TArgs) => TReturn ) { return this.#workletsModuleProxy.createSerializableFunction(func); } createSerializableWorklet(worklet: object, shouldPersistRemote: boolean) { return this.#workletsModuleProxy.createSerializableWorklet( worklet, shouldPersistRemote ); } createCustomSerializable( data: SerializableRef, typeId: number ): SerializableRef { return this.#workletsModuleProxy.createCustomSerializable(data, typeId); } registerCustomSerializable( determine: SerializableRef, pack: SerializableRef, unpack: SerializableRef, typeId: number ): void { this.#workletsModuleProxy.registerCustomSerializable( determine, pack, unpack, typeId ); } createShareable( hostRuntimeId: number, initial: SerializableRef, initSynchronously: boolean, decorateHost: SerializableRef, decorateRef: SerializableRef ): SerializableRef { return this.#workletsModuleProxy.createShareable( hostRuntimeId, initial, initSynchronously, decorateHost, decorateRef ); } scheduleOnUI(serializable: SerializableRef) { return this.#workletsModuleProxy.scheduleOnUI(serializable); } runOnUISync(worklet: SerializableRef): TReturn { return this.#workletsModuleProxy.runOnUISync(worklet); } createWorkletRuntime( name: string, initializer: SerializableRef<() => void>, useDefaultQueue: boolean, customQueue: object | undefined, enableEventLoop: boolean ) { return this.#workletsModuleProxy.createWorkletRuntime( name, initializer, useDefaultQueue, customQueue, enableEventLoop ); } scheduleOnRuntime( workletRuntime: WorkletRuntime, serializableWorklet: SerializableRef ) { return this.#workletsModuleProxy.scheduleOnRuntime( workletRuntime, serializableWorklet ); } scheduleOnRuntimeWithId( runtimeId: number, worklet: SerializableRef ) { return this.#workletsModuleProxy.scheduleOnRuntimeWithId( runtimeId, worklet ); } runOnRuntimeSync( workletRuntime: WorkletRuntime, worklet: SerializableRef ): TReturn { return this.#workletsModuleProxy.runOnRuntimeSync(workletRuntime, worklet); } runOnRuntimeSyncWithId( runtimeId: number, worklet: SerializableRef ): TReturn { return this.#workletsModuleProxy.runOnRuntimeSyncWithId(runtimeId, worklet); } createSynchronizable(value: TValue): SynchronizableRef { return this.#workletsModuleProxy.createSynchronizable(value); } synchronizableGetDirty( synchronizableRef: SynchronizableRef ): TValue { return this.#workletsModuleProxy.synchronizableGetDirty(synchronizableRef); } synchronizableGetBlocking( synchronizableRef: SynchronizableRef ): TValue { return this.#workletsModuleProxy.synchronizableGetBlocking( synchronizableRef ); } synchronizableSetBlocking( synchronizableRef: SynchronizableRef, value: SerializableRef ) { return this.#workletsModuleProxy.synchronizableSetBlocking( synchronizableRef, value ); } synchronizableLock( synchronizableRef: SynchronizableRef ): void { return this.#workletsModuleProxy.synchronizableLock(synchronizableRef); } synchronizableUnlock( synchronizableRef: SynchronizableRef ): void { return this.#workletsModuleProxy.synchronizableUnlock(synchronizableRef); } reportFatalErrorOnJS( message: string, stack: string, name: string, jsEngine: string ) { return this.#workletsModuleProxy.reportFatalErrorOnJS( message, stack, name, jsEngine ); } getStaticFeatureFlag(name: string): boolean { return this.#workletsModuleProxy.getStaticFeatureFlag(name); } setDynamicFeatureFlag(name: string, value: boolean) { this.#workletsModuleProxy.setDynamicFeatureFlag(name, value); } getUIRuntimeHolder(): object { return this.#workletsModuleProxy.getUIRuntimeHolder(); } getUISchedulerHolder(): object { return this.#workletsModuleProxy.getUISchedulerHolder(); } } export const WorkletsModule: IWorkletsModule = new NativeWorklets();