export const SYNCULAR_DIAGNOSTIC_RING_LIMIT = 100;
export const SYNCULAR_SYNC_TIMINGS_RING_LIMIT = 20;
export function appendSyncularDiagnosticEvent(events, event) {
    events.push(event);
    trimRing(events, SYNCULAR_DIAGNOSTIC_RING_LIMIT);
}
export function appendSyncularSyncTimings(timings, timing) {
    timings.push(timing);
    trimRing(timings, SYNCULAR_SYNC_TIMINGS_RING_LIMIT);
}
export function summarizeSyncularDiagnosticSubscriptions(subscriptions, bootstrap) {
    const bootstrapById = new Map((bootstrap?.subscriptions ?? []).map((entry) => [entry.id, entry]));
    return subscriptions.map((subscription) => {
        const bootstrapped = bootstrapById.get(subscription.id);
        return {
            id: subscription.id,
            table: subscription.table,
            scopeKeys: Object.keys(subscription.scopes).sort(),
            scopeValueCount: countRedactedValues(subscription.scopes),
            paramsKeys: Object.keys(subscription.params ?? {}).sort(),
            paramsValueCount: countRedactedValues(subscription.params ?? {}),
            status: bootstrapped?.status ?? null,
            ready: bootstrapped?.ready ?? false,
            phase: bootstrapped?.phase ?? 'pending',
            progressPercent: bootstrapped?.progressPercent ?? 0,
            cursor: bootstrapped?.cursor ?? null,
            bootstrapPhase: bootstrapped?.bootstrapPhase ?? subscription.bootstrapPhase ?? 0,
            bootstrapState: bootstrapped?.bootstrapState ?? null,
        };
    });
}
export function createSyncularSyncAttempt() {
    const traceId = randomHex(16);
    const spanId = randomHex(8);
    return {
        syncAttemptId: traceId,
        traceId,
        spanId,
        traceparent: `00-${traceId}-${spanId}-01`,
    };
}
export function syncularSyncAttemptHeaders(attempt) {
    return {
        traceparent: attempt.traceparent,
        'sentry-trace': `${attempt.traceId}-${attempt.spanId}-1`,
        'x-syncular-sync-attempt-id': attempt.syncAttemptId,
    };
}
export function syncularDiagnosticAttemptFields(attempt) {
    return attempt
        ? {
            syncAttemptId: attempt.syncAttemptId,
            traceId: attempt.traceId,
            spanId: attempt.spanId,
        }
        : {};
}
function countRedactedValues(values) {
    let count = 0;
    for (const value of Object.values(values)) {
        count += Array.isArray(value) ? value.length : 1;
    }
    return count;
}
function trimRing(items, limit) {
    if (items.length <= limit)
        return;
    items.splice(0, items.length - limit);
}
function randomHex(byteLength) {
    const bytes = new Uint8Array(byteLength);
    const cryptoSource = globalThis.crypto;
    if (cryptoSource?.getRandomValues) {
        cryptoSource.getRandomValues(bytes);
    }
    else {
        for (let index = 0; index < bytes.length; index += 1) {
            bytes[index] = Math.floor(Math.random() * 256);
        }
    }
    return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
}
//# sourceMappingURL=diagnostics.js.map