import type { HashId } from "./types.js"; /** * Generates cryptographically strong lock ID (22-char base64url from 16 CSPRNG bytes). * @returns 22-character base64url encoded lock identifier */ export declare function generateLockId(): string; /** * Canonical 96-bit hash for user keys (NFC normalized, 24 hex chars). * * @remarks **Non-cryptographic hash for observability only.** * Uses a fast triple-hash algorithm suitable for sanitization, telemetry, * and UI display. Effective 96-bit space provides low collision probability * for typical workloads. Do NOT use for security-sensitive purposes. * * @param value - User-provided key string * @returns 24-character hex hash identifier */ export declare function hashKey(value: string): HashId; /** * Formats fence token as 15-digit zero-padded string for lexicographic ordering. * Internal helper - backends use this for consistent fence formatting. * 15-digit format guarantees full safety within Lua's 53-bit precision limit * (2^53-1 ≈ 9.007e15) while providing 10^15 capacity (~31.7 years at 1M locks/sec). * @param value - Fence counter (bigint or integer number) * @returns 15-digit string (e.g., "000000000000001") * @throws {LockError} "InvalidArgument" if value is not a finite non-negative integer */ export declare function formatFence(value: bigint | number): string; /** * Canonical storage key generation algorithm (NORMATIVE). * NORMATIVE: All backends MUST use this algorithm (or a byte-for-byte equivalent). * * This is the single source of truth for storage key generation across all backends. * All backends MUST use this function; custom implementations are FORBIDDEN. * * **Requirements:** * - Measures byte length (UTF-8), not string length, for accurate backend limit checks * - Reserves bytes for backend suffixes (e.g., ":id:" + 22-char lockId ≈ 26 bytes) to prevent derived key overflows * - Hashes the FULL prefixed key when truncation is required to preserve namespace boundaries and avoid collisions * - Uses base64url encoding for hashed output compactness (128 bits → 22 chars vs. 32 hex chars) * - Normalizes key to Unicode NFC form for canonical hashing * - Fails fast if prefix + reserve makes valid keys impossible * - Uses fixed 128-bit hash truncation for strong collision resistance (~2.8e-39 prob at 10^9 keys) * - Synchronous implementation for Node.js/Bun (no async overhead) * - O(1) performance: Negligible for small keys (TextEncoder/hash/loop are fast) * * **Two-Step Fence Key Pattern**: When generating fence keys, backends MUST: * 1. Compute base storage key: `baseKey = makeStorageKey(prefix, userKey, limit, reserve)` * 2. Derive fence key from base: `fenceKey = makeStorageKey(prefix, "fence:${baseKey}", limit, reserve)` * * This ensures 1:1 mapping between user keys and fence counters when hash truncation occurs. * * @param prefix - Backend-specific prefix (e.g., "syncguard"); can be empty * @param key - User-provided key; MUST NOT be empty (validated upstream) * @param backendLimitBytes - Backend-specific byte limit (e.g., 1500 for Firestore, 1000 for Redis) * @param reserveBytes - Bytes reserved for suffixes in derived keys (e.g., Redis index/fence keys) * @returns Storage key, truncated/hashed if necessary * @throws {LockError} "InvalidArgument" if prefix + reserve exceeds limit, or if even hashed form exceeds limit * @see docs/specs/interface.md#storage-key-generation - Normative specification * @see docs/specs/interface.md#fence-key-derivation - Two-step fence key pattern * @see docs/adr/006-mandatory-key-truncation.md - Mandatory uniform key truncation rationale */ export declare function makeStorageKey(prefix: string, key: string, backendLimitBytes: number, reserveBytes: number): string;