Named defer on serverless and Convex
Await durable acceptance with config-only ambient mode or a strict host boundary.
Named defer stages Runtime work and resolves after durable acceptance.
Config-only ambient mode
On an ambient-capable platform, configure Runtime and retention once:
import { config } from "@use-crux/core";
import { serverless } from "@use-crux/core/runtime";
import { vercel } from "@use-crux/vercel";
export default config({
host: vercel(),
runtime: serverless({ store, wake }),
});Then await acceptance at the call site:
import { defer } from "@use-crux/core";
import { durableTask } from "@use-crux/core/runtime";
const postProcess = durableTask("post-process", {
run: async (input: { jobId: string }) => input.jobId,
});
export async function POST(request: Request) {
const { jobId } = await request.json();
const ref = await defer(postProcess, { jobId });
return Response.json({ accepted: true, workId: ref.workId });
}The user's await is the acceptance barrier. Each ambient call owns an
ephemeral root; it does not classify the enclosing handler or provide a strict
response commit barrier.
Strict serverless boundary
Use withServerlessDefer when handler outcome and response commitment belong
to one real invocation:
import { withServerlessDefer } from "@use-crux/core/defer/serverless";
export const handler = withServerlessDefer(appHandler, { binding });Lambda-class hosts without a retention port should use
withNamedOnlyDefer. Inline callbacks then fail explicitly with
DEFER_CAPABILITY_MISSING; named Runtime work remains available:
export const handler = withNamedOnlyDefer(
async (event: { jobId: string }) => {
const ref = await defer(postProcess, { jobId: event.jobId });
return { accepted: true, workId: ref.workId };
},
{ host: "lambda", durableFinalization: true },
);If staging or strict finalization fails, the wrapper reports
DEFER_COMMIT_FAILED and must not commit a successful response.
Convex
Configure runtime: convex() and execute through
createCruxConvex().run(). The bridge installs its named-only execution scope;
await named work and keep targets JSON-safe and exported for wake.