Skip to content
AbloAblo Docs
Esc
navigateopen⌘Jpreview
On this page

Basic Usage

Read one task row by id, list matching rows, create and update state, and coordinate work when needed.

Assume the configured client from Installation is exported from ./ablo/client.

Read rows

import { ablo } from './ablo/client';

const task = await ablo.tasks.get({ id: taskId });
if (!task) throw new Error('task not found');

const open = await ablo.tasks.list({ where: { status: 'open' } });

get observes one current row. Use read instead only when a later Ablo write must be rejected if that exact premise changes.

Write rows

const created = await ablo.tasks.create({
  data: { title: 'Review return', status: 'open' },
});

await ablo.tasks.update({
  id: created.id,
  data: { status: 'done' },
});

Writes return after Ablo confirms the authoritative result. Your PostgreSQL constraints and schema remain in force.

Coordinate slow work

When the target is an Ablo model row, claim it before the expensive step and pass the claim to the final write.

await using claim = await ablo.tasks.claim({ id: taskId });

const result = await performExpensiveWork(claim.data);

await ablo.tasks.update({
  id: claim.data.id,
  data: { title: result.title, status: 'done' },
  claim,
});

A contender follows the chosen wait, skip, or fail policy. Disposal releases the claim, and expiry lets another participant recover when the owner disappears.

Preserve an existing write

The claimed target does not have to be an Ablo row. Claim a stable business id and keep the final transaction in the application that already owns it.

await using lease = await ablo.taskRuns.claim(taskId, {
  contention: { mode: 'skip' },
});
if (!lease) return;

const prepared = await performExpensiveWork(taskId);
return existingTaskService.commitPrepared(taskId, prepared);

That transaction must still re-read, validate, and commit authoritatively. An Ablo claim does not join a transaction in another process.

Add stronger guarantees when required

Was this page helpful?