Skip to content

Side Effect Isolation

The signal and lifecycle APIs can cause side effects such as tracking a signal access or registering a teardown hook.

The isolate function can be used to run arbitrary code in isolation from signal access tracking and the current lifecycle.

import { isolate } from "rvx";

isolate(() => {
    // Some code with side effects...
});
import { isolate } from "./rvx.js";

isolate(() => {
    // Some code with side effects...
});

Lifecycle

Teardown hooks are leaked as if teardown was called outside of any context:

import { capture, teardown, isolate } from "rvx";

capture(() => {
    // This will be captured:
    teardown(() => {});

    isolate(() => {
        // This will leak:
        teardown(() => {});
    });
});
import { capture, teardown, isolate } from "./rvx.js";

capture(() => {
    // This will be captured:
    teardown(() => {});

    isolate(() => {
        // This will leak:
        teardown(() => {});
    });
});

Signals

Signal accesses are not tracked as if the signal was accessed outside of any observer.

import { isolate, watch } from "rvx";

watch(() => {
    // This is tracked:
    signalA.access();

    isolate(() => {
        // This is ignored:
        signalB.access();
    });
});
import { isolate, watch } from "./rvx.js";

watch(() => {
    // This is tracked:
    signalA.access();

    isolate(() => {
        // This is ignored:
        signalB.access();
    });
});

To only isolate signal accesses, use untrack instead.

Non Isolated APIs

Batches are not isolated as this could lead to inconsistent signal access tracking:

import { batch, isolate } from "rvx";

batch(() => {
    // This is part of the batch:
    a.value++;

    isolate(() => {
        // This is also part of the batch:
        b.value++;
    });
});

The isolate function is transparent to all contexts for performance reasons:

import { Context, isolate } from "rvx";

const EXAMPLE = new Context(42);

EXAMPLE.provide(77, () => {
    isolate(() => {
        EXAMPLE.value; // 77
    });
});
import { Context, isolate } from "./rvx.js";

const EXAMPLE = new Context(42);

EXAMPLE.provide(77, () => {
    isolate(() => {
        EXAMPLE.value; // 77
    });
});

In case you also need to isolate all contexts, isolate can be combined with Context.isolate:

import { Context, isolate } from "rvx";

isolate(Context.isolate, [], () => {
    // ...
});
import { Context, isolate } from "./rvx.js";

isolate(Context.isolate, [], () => {
    // ...
});