/** * HTTP/API CAS adapter — ETag (If-Match) token discipline over host-injected I/O. * * Uses executeIfUnchanged (conditional-write.ts). Does not invent a parallel outcome shape. * Token format is opaque to the guard (string equality only). * * Token encoding (this adapter only; not interpreted by the core): * api:v1: * Missing / empty ETag → API_ABSENT_TOKEN. * * HONESTY: this adapter does NOT perform HTTP. The host callback MUST send If-Match (or * equivalent) itself. The adapter only normalizes tokens and maps the host-reported * {committed|precondition_failed} onto ExecuteIfUnchangedOutcome. Same class as * conditional_write_is_host_asserted_not_cas_verified — the package never claims it sent * the header. * * No fetch/undici — all I/O is host-injected. */ import { tokensEqual, type ExecuteIfUnchangedOutcome, type VersionToken } from '../conditional-write.js'; /** Prefix for this adapter's opaque tokens (equality-only outside this module). */ export declare const API_VERSION_TOKEN_PREFIX = "api:v1:"; /** * Token used when the resource has no ETag / version header yet (or host reported null). * Hosts that measured absence should pass this as expected_token for create-if-absent CAS. */ export declare const API_ABSENT_TOKEN: VersionToken; /** * Build a VersionToken from a host-supplied ETag or version-header value. * null / undefined / empty / whitespace-only → API_ABSENT_TOKEN. * Surrounding weak/strong quote marks are stripped once for stable equality. */ export declare function createApiVersionToken(etag: string | null | undefined): VersionToken; /** Raw value embedded in an api:v1: token (for host If-Match headers). Absent → null. */ export declare function apiTokenRaw(token: VersionToken | null | undefined): string | null; /** * Host report after attempting a conditional write. * The host is responsible for sending If-Match / If-None-Match / equivalent. */ export type ApiHostWriteReport = { status: 'committed'; /** New ETag after write when the server returned one; null/omit when unknown. */ new_etag?: string | null; result?: T; } | { status: 'precondition_failed'; /** Current ETag if the host observed one (e.g. from 412 body / re-GET); omit → null. */ current_etag?: string | null; }; export type WriteApiIfUnchangedArgs = { /** Token measured before the host decided to write (from createApiVersionToken). */ expected_token: VersionToken; /** * Re-read the resource ETag (or equivalent version header). * Called by executeIfUnchanged before write and again after write when detect is on. */ current_etag: () => string | null | Promise; /** * Host performs the conditional HTTP write. * `if_match` is the raw expected ETag for the If-Match header (null when ABSENT). * Adapter does not send the request — host must. */ write: (ctx: { if_match: string | null; expected_token: VersionToken; }) => ApiHostWriteReport | Promise>; /** * Opt-in post-commit detection (default false — byte-identical when off). * Requires a meaningful intended post-ETag: when the host omits new_etag on success, * detection is a no-op (cannot know intended post state without inventing tokens). */ detect_stale_during_commit?: boolean; }; export type ApiWriteResult = { new_etag: string | null; result: T | undefined; }; /** * Conditional API write: re-read ETag; if token matches expected → host write with If-Match context. * * Mapping (host report → ExecuteIfUnchangedOutcome): * committed (+ optional new_etag) → committed (version_token = expected; result carries new_etag) * precondition_failed (412 class) → refused / stale_version_token * current_token from current_etag when host supplied it, * else null (no invented token) * * Missing new_etag on success: stored as null on result; detect_stale_during_commit is a no-op * unless new_etag is a non-empty string (honest — no ABSENT fabrication as "expected after"). * * Wired through executeIfUnchanged — not a parallel path. */ export declare function writeApiIfUnchanged(args: WriteApiIfUnchangedArgs): Promise>>; /** Re-export equality helper for hosts comparing tokens without importing core module. */ export { tokensEqual }; //# sourceMappingURL=api.d.ts.map