LCOV - code coverage report
Current view: top level - dashql-app/src/query - query_result_cache_key.ts Coverage Total Hit
Test: DashQL 915828b Lines: 100.0 % 25 25
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : /// Computes the content hash that keys a query result in the file-based query result cache.
       2              : ///
       3              : /// A result is cached as a pure function of `(connection params signature, script AST signature)`.
       4              : /// Post-processing (analyze) runs after the cache load, so it deliberately does NOT
       5              : /// participate in the key.
       6              : 
       7              : /// Deterministically serialize a value to JSON with object keys sorted at every level.
       8              : ///
       9              : /// `createConnectionParamsSignature` already sorts its arrays, but `JSON.stringify` preserves object
      10              : /// *key insertion order*, which is not guaranteed stable across constructions. The whole cache's
      11              : /// correctness rests on a byte-stable canonical form, so we sort keys explicitly here.
      12            1 : function stableStringify(value: unknown): string {
      13            1 :     return JSON.stringify(value, (_key, val) => {
      14            1 :         if (val && typeof val === 'object' && !Array.isArray(val)) {
      15            1 :             const sorted: Record<string, unknown> = {};
      16            1 :             for (const k of Object.keys(val as Record<string, unknown>).sort()) {
      17            1 :                 sorted[k] = (val as Record<string, unknown>)[k];
      18              :             }
      19            1 :             return sorted;
      20            1 :         }
      21            1 :         return val;
      22            1 :     });
      23            1 : }
      24              : 
      25              : /// Hex-encode a byte buffer (lowercase).
      26            1 : function toHex(buffer: ArrayBuffer): string {
      27            1 :     const bytes = new Uint8Array(buffer);
      28            1 :     let hex = '';
      29            1 :     for (let i = 0; i < bytes.length; ++i) {
      30            1 :         hex += bytes[i].toString(16).padStart(2, '0');
      31              :     }
      32            1 :     return hex;
      33            1 : }
      34              : 
      35              : /// Compute the lowercase SHA-256 hex digest of the canonical connection signature plus the
      36              : /// versioned semantic signature emitted by dashql-core.
      37            1 : export async function computeQueryResultCacheKey(paramsSignature: unknown, scriptSignature: string): Promise<string> {
      38            1 :     const connectionSignature = stableStringify(paramsSignature);
      39            1 :     const input = `dashql-query-cache-v3\n${connectionSignature.length}:${connectionSignature}${scriptSignature.length}:${scriptSignature}`;
      40            1 :     const encoded = new TextEncoder().encode(input);
      41            1 :     const digest = await crypto.subtle.digest('SHA-256', encoded);
      42            1 :     return toHex(digest);
      43            1 : }
        

Generated by: LCOV version 2.0-1