@adcp/sdk API Reference - v14.3.0
    Preparing search index...

    Interface IdempotencyStore

    interface IdempotencyStore {
        check(
            params: {
                principal: string;
                key: string;
                payload: unknown;
                extraScope?: string;
            },
        ): Promise<IdempotencyCheckResult>;
        renew(
            params: {
                principal: string;
                key: string;
                claimToken: string;
                extraScope?: string;
            },
        ): Promise<void>;
        save(
            params: {
                principal: string;
                key: string;
                payloadHash: string;
                claimToken: string;
                response: unknown;
                extraScope?: string;
            },
        ): Promise<void>;
        release(
            params: {
                principal: string;
                key: string;
                claimToken: string;
                extraScope?: string;
            },
        ): Promise<void>;
        saveTransientError?(
            params: {
                principal: string;
                key: string;
                payloadHash: string;
                claimToken: string;
                response: unknown;
                extraScope?: string;
            },
        ): Promise<void>;
        probe?(): Promise<void>;
        capability(): { replay_ttl_seconds: number };
        ttlSeconds: number;
        close(): Promise<void>;
        clearAll?(): Promise<void>;
    }
    Index
    ttlSeconds: number

    The replay window in seconds (already bounds-checked at construction).

    • Check the store for (principal, key, payload) and return whether the caller should replay, reject, or execute fresh.

      On miss, the store writes an in-flight placeholder atomically via the backend's putIfAbsent. Only the caller that wins the claim gets miss; parallel callers with the same key see in-flight and should retry the check after a brief delay. The returned payloadHash MUST be passed back to save() to avoid double-hashing.

      Parameters

      • params: { principal: string; key: string; payload: unknown; extraScope?: string }

      Returns Promise<IdempotencyCheckResult>

    • Extend an in-flight request claim while its handler is still running. The implementation MUST compare against claimToken atomically and throw IdempotencyClaimOwnershipError if that owner no longer holds the claim. Servers call this periodically until the response is saved or the claim is released.

      Parameters

      • params: { principal: string; key: string; claimToken: string; extraScope?: string }

      Returns Promise<void>

    • Save a successful execution's response to the cache, replacing the in-flight placeholder written at check time.

      Parameters

      • params: {
            principal: string;
            key: string;
            payloadHash: string;
            claimToken: string;
            response: unknown;
            extraScope?: string;
        }
        • principal: string
        • key: string
        • payloadHash: string
        • claimToken: string

          Owner fence returned by the matching check() miss.

        • response: unknown
        • OptionalextraScope?: string

      Returns Promise<void>

    • Release the in-flight claim written at check time — used by the middleware when the handler fails. The built-in store atomically replaces ownership with a retryable marker, preserving the original payload binding while allowing an exact retry to re-execute.

      Parameters

      • params: { principal: string; key: string; claimToken: string; extraScope?: string }

      Returns Promise<void>

    • Short-TTL cache for an error envelope that the handler is guaranteed to reproduce on re-execution (currently: strict-mode response VALIDATION_ERROR driven by handler drift).

      Optional on the interface so custom store implementations aren't forced to migrate — when absent, the dispatcher falls back to release() (the pre-#758 behavior). Stores backed by createIdempotencyStore always include it.

      Retry-storm guard, not a spec replay. Without it, a drifted handler under strict validation + a retrying buyer produces unbounded re-execution (release-on-error lets every retry hit the handler again with the same drift). The logical cache TTL is TRANSIENT_ERROR_TTL_SECONDS (10s). As with every idempotency result, peers continue replaying it through the configured clockSkewSeconds safety window rather than risking a fresh execution while clocks may disagree, so the default effective suppression window is up to 70s.

      Operational note — DoS primitive. A drifted handler reachable by a hostile buyer is a cache-fill vector: every fresh idempotency_key writes a new 10s-TTL entry, cheap because the handler fails fast. Alert on sustained VALIDATION_ERROR rates per principal — they indicate either a broken handler (deploy regression) or a buyer probing for drift. Steady-state VALIDATION_ERROR should be zero.

      Dev-experience note — TTL opacity. After deploying a handler fix, same-key retries within the logical 10s TTL plus the configured clock-skew safety window still replay the cached error before the fix takes effect. Iterative handler authors should use a fresh idempotency_key to bypass the cache during development.

      Parameters

      • params: {
            principal: string;
            key: string;
            payloadHash: string;
            claimToken: string;
            response: unknown;
            extraScope?: string;
        }
        • principal: string
        • key: string
        • payloadHash: string
        • claimToken: string

          Owner fence returned by the matching check() miss.

        • response: unknown
        • OptionalextraScope?: string

      Returns Promise<void>

    • Probe the backend at server startup. Delegates to backend.probe() if the backend implements it; otherwise resolves immediately. Wire into serve() via readinessCheck: () => store.probe() so the server never accepts traffic with a broken pool.

      Returns Promise<void>

    • Capability fragment describing this store's replay window. Servers created by createAdcpServer derive the wire capability directly from the wired store; adopters do not need to pass this value separately.

      Returns { replay_ttl_seconds: number }

    • Drop every cached entry without releasing backend resources. Present only when the configured backend supports it (e.g., memoryBackend). Production-leaning backends leave this undefined so an accidental production call can't flush the cache.

      Only invoked from AdcpServer.compliance.reset() — do not call from production code paths.

      Returns Promise<void>