LynxMainThread

A service that calls one of your main-thread scripts from Angular code, and gives you its return value. import { LynxMainThread } 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, inject, signal } from '@angular/core';
import {
  createMainThreadRef,
  LYNX_ELEMENTS,
  LynxMainThread,
  LynxMainThreadEvent,
  mainThreadFn,
} from '@blotch/angular-lynx';

const taps = createMainThreadRef(0);
const countTap = mainThreadFn(() => {
  taps.current++;
});
const readTaps = mainThreadFn(() => taps.current);

@Component({
  selector: 'app-root',
  imports: [LYNX_ELEMENTS, LynxMainThreadEvent],
  template: `
    <view [mainThreadBindtap]="countTap">
      <text>Tap me</text>
    </view>
    <view (bindtap)="showTaps()">
      <text>Taps so far: {{ shown() }}</text>
    </view>
  `,
})
export class App {
  readonly #mainThread = inject(LynxMainThread);
  readonly countTap = countTap;
  readonly shown = signal(0);

  async showTaps(): Promise<void> {
    this.shown.set(await this.#mainThread.runOnMainThread(readTaps));
  }
}

LynxMainThread is provided in root, so inject() it anywhere.

API

runOnMainThread(handle, ...args)

runOnMainThread<TArgs extends unknown[], TReturn>(
  handle: MainThreadFnHandle<TArgs, TReturn>,
  ...args: TArgs
): Promise<TReturn>;
  • handle: a function from mainThreadFn().
  • args: its arguments, checked against its parameter types.
  • Returns a promise of the function's return value. It rejects if the function throws.

Where you call it changes what happens:

Called fromWhat happens
The main thread, such as a (bindtap) handlerRuns the function right away. Arguments aren't copied, and a returned promise is awaited
The background threadSends the call to the main thread. Arguments and the return value are copied as JSON

Constraints

  • Code that runs on both threads calls it twice. A constructor, ngOnInit or effect() runs in both copies of your app (see Threads), so the function runs once from each. Call it from an event handler instead.
  • From the background thread, define the function at module scope. The call finds the function by an ID, which matches on both threads only for module-level functions.
  • From the background thread, use JSON-safe arguments and return values. A development build throws on arguments that can't be serialized. A returned promise isn't awaited.