API reference@evolu/commonTask › unabortable

const unabortable: <T, E, D>(task: Task<T, E, D>) => Task<T, E, D>;

Defined in: packages/common/src/Task.ts:1541

Makes a Task unabortable.

Once started, an unabortable Task always completes — abort requests are ignored and signal.aborted remains false.

If the parent Run is already disposing or settled, run(task) short-circuits before task execution and returns err(AbortError) with runStoppedError as reason. So unabortable means “do not interrupt this Task once it has started”, not “remove AbortError from its type”.

When that pre-start abort would be a programmer error, assert it explicitly with assertNotAborted after awaiting the result.

Example

await using run = createRun();

const events: Array<string> = [];
const canComplete = Promise.withResolvers<void>();
let signalAbortedInAnalytics = true;

// Simulate async analytics API (abortable by default)
const sendToAnalytics =
  (event: number): Task<void, never> =>
  async ({ signal }) => {
    await canComplete.promise;
    signalAbortedInAnalytics = signal.aborted;
    events.push(`sent ${event}`);
    return ok();
  };

// Important events must be sent even if the user navigates away
const trackImportantEvent = (event: number) =>
  unabortable(sendToAnalytics(event));

// User clicks, we start tracking (Task runs until first await)
const fiber = run(trackImportantEvent(123));

// User navigates away (abort requested while task is running)
fiber.abort();
canComplete.resolve();

const result = await fiber;

expect(signalAbortedInAnalytics).toBe(false);
// Analytics was sent despite abort
expect(events).toEqual(["sent 123"]);
expect(result).toEqual(ok());