brumate

Reactive logic in modules

A .brm.ts module holds state and logic that several components share. Its functions use $signal, $memo and the other compile-time functions, and a component calls one at the top level of its script.

Edit the code to run it again

The sample runs when it comes into view.

How it works

The compiler copies the body of the function into the component, in place of the call. Its signals and memos become values of the component, as if the component declared them itself.

Write a module function

The module can import other modules and declare constants. The function can read them, and the component imports them for it. A constant that the function reads must be exported, because the component imports it from the module.

Call it from a component

Destructure the call at the top level of a <script>:

<script>
  import { counter } from './counter.brm.ts';

  const { count, increment } = counter(1);
</script>

Pass a signal in

An argument that is a name, such as a signal or a prop, stays reactive inside the function. Any other argument is computed once, when the component renders.

Edit the code to run it again

The sample runs when it comes into view.

Here area follows size, because the memo reads the component's signal. With scaled(2), it would stay at 4.

Effects and other compile-time functions

A module function can use $effect, $client, $produce, $untrack and the rest. They behave as in the component that calls the function.

A function that gives a handler with $handler is compiled into each component that calls it, rather than shared, because its handler is a part of that component.

Edit the code to run it again

The sample runs when it comes into view.

Errors and types

A module function runs only as a copy in a component. Called anywhere else, such as from a .ts file, its compile-time functions throw, because nothing compiles them.