- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.4k
 
          feat(Worklets): runOnRuntimeSync
          #8224
        
          New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
a1daa99
              88e28d9
              e15fb9c
              4b1adb2
              61f294a
              3a80161
              8ebbf2e
              c5f563e
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { | ||
| createSynchronizable, | ||
| createWorkletRuntime, | ||
| runOnJS, | ||
| runOnRuntimeSync, | ||
| scheduleOnRuntime, | ||
| } from 'react-native-worklets'; | ||
| import { describe, expect, test, notify, waitForNotification } from '../../ReJest/RuntimeTestsApi'; | ||
| import { ComparisonMode } from '../../ReJest/types'; | ||
| 
     | 
||
| const NOTIFICATION_NAME = 'NOTIFICATION_NAME'; | ||
| 
     | 
||
| describe('runOnRuntimeSync', () => { | ||
| test('use runOnRuntimeSync to run a function on the Worker Runtime from RN Runtime', () => { | ||
| // Arrange | ||
| const workletRuntime = createWorkletRuntime({ name: 'test' }); | ||
| 
     | 
||
| // Act | ||
| const result = runOnRuntimeSync(workletRuntime, () => { | ||
| 'worklet'; | ||
| return 100; | ||
| }); | ||
| 
     | 
||
| // Assert | ||
| expect(result).toBe(100, ComparisonMode.NUMBER); | ||
| }); | ||
| 
     | 
||
| test('keep the correct order of execution runOnRuntimeSync and scheduleOnRuntime', async () => { | ||
| // Arrange | ||
| const workletRuntime = createWorkletRuntime({ name: 'test' }); | ||
| const synchronizable = createSynchronizable(0); | ||
| 
     | 
||
| const onJSCallback = () => { | ||
| notify(NOTIFICATION_NAME); | ||
| }; | ||
| 
     | 
||
| // Act | ||
| scheduleOnRuntime(workletRuntime, () => { | ||
| 'worklet'; | ||
| // heavy computation | ||
| new Array(50_000_000).map((_v, i) => i ** 2); | ||
| synchronizable.setBlocking(100); | ||
| runOnJS(onJSCallback)(); | ||
                
      
                  skusnierz marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| }); | ||
                
      
                  skusnierz marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| const result = runOnRuntimeSync(workletRuntime, () => { | ||
| 'worklet'; | ||
| return 100; | ||
| }); | ||
| 
     | 
||
| // Assert | ||
| expect(result).toBe(100, ComparisonMode.NUMBER); | ||
| await waitForNotification(NOTIFICATION_NAME); | ||
| expect(synchronizable.getBlocking()).toBe(100, ComparisonMode.NUMBER); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| --- | ||
| sidebar_position: 13 | ||
| --- | ||
| 
     | 
||
| # runOnRuntimeSync | ||
| 
     | 
||
| `runOnRuntimeSync` lets you run a [workletized](/docs/fundamentals/glossary#to-workletize) function synchronously on a [Worker Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime). | ||
| 
     | 
||
| ## Reference | ||
| 
     | 
||
| ```javascript | ||
| import { runOnRuntimeSync, createWorkletRuntime } from 'react-native-worklets'; | ||
| 
     | 
||
| const workletRuntime = createWorkletRuntime({ name: 'background' }); | ||
| 
     | 
||
| const result = runOnRuntimeSync(workletRuntime, () => { | ||
| 'worklet'; | ||
| return 2+2; | ||
| }); | ||
| 
     | 
||
| console.log(result); // 4 | ||
| ``` | ||
| 
     | 
||
| 
     | 
||
| <details> | ||
| <summary>Type definitions</summary> | ||
| 
     | 
||
| ```typescript | ||
| function runOnRuntimeSync<Args extends unknown[], ReturnValue>( | ||
| workletRuntime: WorkletRuntime, | ||
| worklet: (...args: Args) => ReturnValue, | ||
| ...args: Args | ||
| ): ReturnValue | ||
| ``` | ||
| 
     | 
||
| </details> | ||
| 
     | 
||
| ## Arguments | ||
| 
     | 
||
| ### workletRuntime | ||
| 
     | 
||
| The worklet runtime to run the worklet on. | ||
| 
     | 
||
| ### worklet | ||
| 
     | 
||
| A reference to a function you want to execute on the [Worklet Runtime](/docs/fundamentals/glossary#worklet-runtime). | ||
| 
     | 
||
| ### args | ||
| 
     | 
||
| Arguments to the function you want to execute on the [Worklet Runtime](/docs/fundamentals/glossary#worklet-runtime). | ||
| 
     | 
||
| ## Remarks | ||
                
      
                  tjzel marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| - The worklet cannot be run on the Worker Runtime from [UI | ||
| Runtime](/docs/fundamentals/glossary#ui-runtime) or another [Worker | ||
| Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime), unless the [Bundle Mode](/docs/experimental/bundleMode) is enabled. | ||
                
      
                  skusnierz marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| ```javascript | ||
| import { createWorkletRuntime, runOnRuntimeSync } from 'react-native-worklets'; | ||
| const workletRuntime = createWorkletRuntime({ name: 'background' }); | ||
| runOnUI(() => { | ||
| runOnRuntimeSync(workletRuntime, (greeting: string) => { | ||
| console.log(`${greeting} from the background Worklet Runtime`); | ||
| }, 'Hello'); // This will throw an error outside of Bundle Mode 🚨 | ||
| }); | ||
| ``` | ||
| 
     | 
||
| ```javascript | ||
| import { createWorkletRuntime, scheduleOnRuntime } from 'react-native-worklets'; | ||
| const workletRuntime = createWorkletRuntime({ name: 'background' }); | ||
| const anotherWorkletRuntime = createWorkletRuntime({ name: 'anotherBackground' }); | ||
| runOnRuntimeSync(anotherWorkletRuntime, () => { | ||
| runOnRuntimeSync(workletRuntime, (greeting: string) => { | ||
| console.log(`${greeting} from the background Worklet Runtime`); | ||
| }, 'Hello'); // This will throw an error outside of Bundle Mode 🚨 | ||
| }); | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /* eslint-disable @typescript-eslint/no-unused-vars */ | ||
| import { createWorkletRuntime, runOnRuntimeSync, runOnUISync } from '..'; | ||
| 
     | 
||
| function runOnRuntimeSyncTypeTests() { | ||
| const workletRuntime = createWorkletRuntime({ name: 'test' }); | ||
| // Correct usage - correct usage | ||
| runOnRuntimeSync( | ||
| workletRuntime, | ||
| (num: number): number => { | ||
| return num + 1; | ||
| }, | ||
| 0 | ||
| ); | ||
| 
     | 
||
| // @ts-expect-error - expected no args, but arg is provided | ||
| runOnRuntimeSync(workletRuntime, (): void => {}, 0); | ||
| 
     | 
||
| // Wrong args type | ||
| runOnRuntimeSync( | ||
| workletRuntime, | ||
| (num: number): number => { | ||
| return num + 1; | ||
| }, | ||
| // @ts-expect-error - wrong args type | ||
| 'tets' | ||
| ); | ||
| 
     | 
||
| // Wrong return type | ||
| runOnRuntimeSync( | ||
| workletRuntime, | ||
| (num: number): string => { | ||
| // @ts-expect-error - wrong return type | ||
| return num + 1; | ||
| }, | ||
| 0 | ||
| ); | ||
| 
     | 
||
| // @ts-expect-error - wrong return type | ||
| const result: string = runOnRuntimeSync( | ||
| workletRuntime, | ||
| (num: number): number => { | ||
| return num + 1; | ||
| }, | ||
| 0 | ||
| ); | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -170,6 +170,56 @@ export function scheduleOnRuntime<Args extends unknown[], ReturnValue>( | |
| runOnRuntime(workletRuntime, worklet)(...args); | ||
| } | ||
| 
     | 
||
| /** | ||
| * Lets you run a function synchronously on the [Worker | ||
| * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime). | ||
| * | ||
| * - This function cannot be called from the [UI | ||
| * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime). | ||
| * or another [Worker | ||
| * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime), | ||
| * unless the [Bundle | ||
| * Mode](https://docs.swmansion.com/react-native-worklets/docs/experimental/bundleMode) | ||
| * is enabled. | ||
| * | ||
| * @param workletRuntime - The runtime to run the worklet on. | ||
| * @param worklet - The worklet to run. | ||
| * @param args - The arguments to pass to the worklet. | ||
| * @returns The return value of the worklet. | ||
| */ | ||
| export function runOnRuntimeSync<Args extends unknown[], ReturnValue>( | ||
| workletRuntime: WorkletRuntime, | ||
| worklet: (...args: Args) => ReturnValue, | ||
| ...args: Args | ||
| ): ReturnValue { | ||
| 'worklet'; | ||
| if (__DEV__ && !SHOULD_BE_USE_WEB && !isWorkletFunction(worklet)) { | ||
| throw new WorkletsError( | ||
| 'The function passed to `runOnRuntimeSync` is not a worklet.' | ||
| ); | ||
| } | ||
| 
     | 
||
| if (globalThis.__RUNTIME_KIND !== RuntimeKind.ReactNative) { | ||
| return WorkletsModule.runOnRuntimeSync( | ||
| workletRuntime, | ||
| makeShareableCloneOnUIRecursive(() => { | ||
                
       | 
||
| 'worklet'; | ||
| const result = worklet(...args); | ||
| return createSerializable(result); | ||
| }) | ||
| ); | ||
| } | ||
                
      
                  skusnierz marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| return WorkletsModule.runOnRuntimeSync( | ||
| workletRuntime, | ||
| createSerializable(() => { | ||
| 'worklet'; | ||
| const result = worklet(...args); | ||
| return makeShareableCloneOnUIRecursive(result); | ||
| }) | ||
| ); | ||
| } | ||
| 
     | 
||
| /** Configuration object for creating a worklet runtime. */ | ||
| export type WorkletRuntimeConfig = { | ||
| /** The name of the worklet runtime. */ | ||
| 
          
            
          
           | 
    ||
Uh oh!
There was an error while loading. Please reload this page.