SPB Git forge

spb/market-atlas

Public
12commits 1branches 0releases
1.1 MBsize
maindefault branch
10 days agolast push
TypeScript 96.7% SQL 1.6% CSS 0.8% JavaScript 0.5%
1.7 KB · 49 lines typescript
Raw Blame History
1import { createHash } from "node:crypto";23export function sha256(input: string | Buffer): string {4  return createHash("sha256").update(input).digest("hex");5}67export function shortHash(input: string, len = 16): string {8  return sha256(input).slice(0, len);9}1011/**12 * Structural fingerprint of a payload: the sorted set of key paths with primitive types,13 * ignoring values and array indexes. Used to detect schema drift on public endpoints.14 */15export function schemaFingerprint(payload: unknown, maxDepth = 6): string {16  const paths = new Set<string>();17  const walk = (v: unknown, path: string, depth: number) => {18    if (depth > maxDepth) return;19    if (Array.isArray(v)) {20      if (v.length === 0) paths.add(`${path}[]`);21      // Sample first 3 elements — enough to capture the shape.22      for (const item of v.slice(0, 3)) walk(item, `${path}[]`, depth + 1);23      return;24    }25    if (v && typeof v === "object") {26      for (const [k, val] of Object.entries(v as Record<string, unknown>)) walk(val, path ? `${path}.${k}` : k, depth + 1);27      return;28    }29    paths.add(`${path}:${v === null ? "null" : typeof v}`);30  };31  walk(payload, "", 0);32  return shortHash([...paths].sort().join("|"), 20);33}3435/** Deterministic fingerprint for deduplicating observations replayed after a reconnect. */36export function observationFingerprint(parts: {37  sourceId: string;38  instrumentId: string;39  field: string;40  value: number;41  sourceTimestamp: number | null;42  sequence?: number | string | null;43}): string {44  return shortHash(45    `${parts.sourceId}|${parts.instrumentId}|${parts.field}|${parts.value}|${parts.sourceTimestamp ?? ""}|${parts.sequence ?? ""}`,46    24,47  );48}49