# All files / src _savepoint.ts

100% Statements 6/6
100% Branches 2/2
100% Functions 1/1
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    1x
    41x
    41x
    41x
    41x
    41x
     /**
     * Savepoint-name generator. Shared between `client.ts` (which
     * uses `pgrls_actor_` for the `asRole` scope) and
     * `assertions.ts` (which uses `pgrls_check_` for the
     * `assertRejected` scope).
     *
     * Centralizing avoids drift between the two random schemes —
     * the next time we want to tweak the suffix length or the
     * random source, there's one place to do it.
     *
     * 4-byte random suffix → 8 hex chars → 4 billion options.
     * Collisions in the same transaction are astronomically
     * unlikely.
     *
     * Mirrors Python's `secrets.token_hex(4)` call sites.
     */

    /**
     * Build a savepoint name with the given prefix and a 4-byte
     * cryptographically-random hex suffix.
     *
     * Uses `globalThis.crypto.getRandomValues` (WHATWG standard;
     * available in Node ≥18, so well within our `engines.node`
     * floor). Reaching via globalThis avoids needing a
     * `node:crypto` import or an ambient `crypto` global decl.
     */
    export function newSavepointName(prefix: string): string {
      const bytes = new Uint8Array(4);
      globalThis.crypto.getRandomValues(bytes);
      const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
      return `${prefix}_${hex}`;
    }