Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import { randomBytes, randomUUID } from "node:crypto";
|
|
|
|
const REQUEST_ID = /^[\w.:-]{1,128}$/;
|
|
const TRACEPARENT = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
|
|
const ZERO_TRACE = "0".repeat(32);
|
|
const ZERO_SPAN = "0".repeat(16);
|
|
|
|
export function generateRequestId(): string {
|
|
return randomUUID();
|
|
}
|
|
|
|
export function generateTraceId(): string {
|
|
return randomBytes(16).toString("hex");
|
|
}
|
|
|
|
export function generateSpanId(): string {
|
|
return randomBytes(8).toString("hex");
|
|
}
|
|
|
|
export function isValidRequestId(value: string | undefined): value is string {
|
|
return Boolean(value && REQUEST_ID.test(value));
|
|
}
|
|
|
|
export interface TraceParent {
|
|
traceId: string;
|
|
spanId: string;
|
|
flags: string;
|
|
}
|
|
|
|
export function parseTraceparent(value: string | undefined): TraceParent | undefined {
|
|
if (!value) return undefined;
|
|
const match = TRACEPARENT.exec(value.trim());
|
|
if (!match) return undefined;
|
|
const traceId = match[1]!;
|
|
const spanId = match[2]!;
|
|
const flags = match[3]!;
|
|
if (traceId === ZERO_TRACE || spanId === ZERO_SPAN) return undefined;
|
|
return { traceId, spanId, flags };
|
|
}
|
|
|
|
export function formatTraceparent(traceId: string, spanId: string, flags = "01"): string {
|
|
return `00-${traceId}-${spanId}-${flags}`;
|
|
}
|