composeSequentialCallback
composeSequentialCallback<
TResult>(db,callback):Operation<TResult> &object
Defined in: packages/db/src/compose.ts:333
Sequential compose variant that accepts a callback for ad-hoc workflows where
later operations depend on the results of earlier ones (e.g. inserting a child
row that references the inserted parent’s id).
Permissions are still collected ahead-of-time: the callback is run twice. The
first pass uses a tracking proxy that records every operation’s permission
descriptors and returns sentinel values from .run() (so card.id and similar
accesses don’t crash). The second pass runs the callback against the real Db
to actually execute the queries.
Because the callback runs twice, it must be free of side effects outside of
db.* calls (no fetch, no console.log you care about, no global state
mutation). All control flow that depends on db results should use the sentinel-
tolerant property accesses.
The dry-run pass is asynchronous, so op.permissions is empty until the dry-run
resolves. Consumers that need to inspect permissions before calling .run() (e.g.
the @cfast/actions permission UI) should await op.permissionsAsync() instead.
Calling op.run() always awaits the dry-run internally, so permissions are
guaranteed to be populated by the time the real callback runs.
Type Parameters
Section titled “Type Parameters”TResult
Section titled “TResult”TResult
The return type of the callback.
Parameters
Section titled “Parameters”The real Db that will execute the operations on the second pass.
callback
Section titled “callback”(db) => Promise<TResult>
A function that receives a Db and returns a value.
Returns
Section titled “Returns”Operation<TResult> & object
A single Operation whose .permissions is the union of every
operation discovered during the dry-run pass and whose .run() re-executes
the callback against the real Db. The returned object also exposes
permissionsAsync() for guaranteed permission retrieval.
Example
Section titled “Example”import { composeSequentialCallback } from "@cfast/db";
const op = composeSequentialCallback(db, async (tx) => { const card = await tx.insert(cards).values({ title: "New" }).returning().run(); await tx.insert(activityLog).values({ cardId: (card as { id: string }).id, action: "card_created", }).run(); return card;});
await op.permissionsAsync(); // [{ create, cards }, { create, activityLog }]await op.run();