backgroundFn and runOnBackground

Lets main-thread code call a function on the background thread, where background-only APIs live. import { backgroundFn } from '@blotch/angular-lynx';

Info

Template handlers such as (bindtap) already run on the main thread. Main-thread scripts explains when you need this API instead.

Usage

src/app/app.ts
import { Component } from '@angular/core';
import {
  backgroundFn,
  LYNX_ELEMENTS,
  LynxMainThreadEvent,
  mainThreadFn,
  type MainThread,
} from '@blotch/angular-lynx';

let lastColor = '';

// Registered on the background thread.
const rememberColor = backgroundFn((color: string) => {
  lastColor = color;
});

const paint = mainThreadFn((event: MainThread.TouchEvent) => {
  event.currentTarget.setStyleProperty('background-color', '#ff5722');
  void runOnBackground(rememberColor, '#ff5722');
});

@Component({
  selector: 'app-root',
  imports: [LYNX_ELEMENTS, LynxMainThreadEvent],
  template: `
    <view [mainThreadBindtap]="paint"><text>Tap to paint</text></view>
  `,
})
export class App {
  readonly paint = paint;
}

runOnBackground is a global, so it needs no import. Its type comes with @blotch/angular-lynx.

API

backgroundFn(fn)

function backgroundFn<TArgs extends unknown[], TReturn>(
  fn: (...args: TArgs) => TReturn,
): BackgroundFnHandle<TArgs, TReturn>;
  • fn: the function to run on the background thread.
  • Returns a handle to pass to runOnBackground().

runOnBackground(handle, ...args)

// A global on the main thread.
function runOnBackground(
  handle: { _wkltId: string },
  ...args: unknown[]
): Promise<unknown>;
  • handle: a handle from backgroundFn().
  • args: its arguments. They aren't type-checked against the function.
  • Returns a promise of the function's return value, typed unknown. If the function throws, it rejects with an Error whose message is the thrown value as a string.

You can call it from a main-thread function or from a template event handler, since both run on the main thread.

Constraints

  • runOnBackground exists only on the main thread. Code in a constructor or ngOnInit also runs on the background thread, where calling it throws.
  • Define backgroundFn at module scope. The call finds the function by an ID, which matches on both threads only for module-level functions.
  • Arguments and the return value are copied as JSON.
  • The function must return synchronously. A returned promise isn't awaited: the caller receives {}, so an async function's result is lost.
  • Signals it changes don't reach the screen. It runs in the background copy of your app, which isn't shown. Return a value and set the signal on the main thread instead.

Types

// An opaque handle. Its fields are internal.
type BackgroundFnHandle<
  TArgs extends unknown[] = unknown[],
  TReturn = unknown,
> = {
  /* internal */
};