var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/**
 * Computes a deterministic, collision-resistant identifier for a {@link SyncScope}.
 *
 * The ID is `base64url(SHA-256(canonicalJSON))` where `canonicalJSON` is the
 * scope object with keys sorted alphabetically and array values sorted
 * lexicographically.
 *
 * Used as part of the LevelDB key for the replication ledger:
 * `{tenantDid}^{remoteEndpoint}^{scopeId}`.
 */
export function computeScopeId(scope) {
    return __awaiter(this, void 0, void 0, function* () {
        const canonical = { kind: scope.kind };
        if (scope.kind === 'protocol') {
            canonical.protocol = scope.protocol;
            if (scope.protocolPathPrefixes !== undefined) {
                canonical.protocolPathPrefixes = [...new Set(scope.protocolPathPrefixes)].sort((a, b) => a.localeCompare(b));
            }
            if (scope.contextIdPrefixes !== undefined) {
                canonical.contextIdPrefixes = [...new Set(scope.contextIdPrefixes)].sort((a, b) => a.localeCompare(b));
            }
        }
        // Stable JSON: keys sorted by construction order (kind < protocol < protocolPathPrefixes).
        const json = JSON.stringify(canonical);
        const bytes = new TextEncoder().encode(json);
        const hashBuffer = yield crypto.subtle.digest('SHA-256', bytes);
        const hashArray = new Uint8Array(hashBuffer);
        // base64url encode (no padding).
        let base64 = '';
        for (const b of hashArray) {
            base64 += String.fromCharCode(b);
        }
        const result = btoa(base64).replaceAll('+', '-').replaceAll('/', '_');
        // Strip trailing '=' padding without regex quantifiers (avoids ReDoS scanners).
        let end = result.length;
        while (end > 0 && result.codePointAt(end - 1) === 61) {
            end--;
        } // 61 === '='
        return end === result.length ? result : result.slice(0, end);
    });
}
// ---------------------------------------------------------------------------
// Replication checkpoint types
// ---------------------------------------------------------------------------
/**
 * Maximum number of in-flight deliveries (runtime ordinals) a link may
 * accumulate before transitioning to `repairing`. This is the overflow
 * threshold for the engine's in-memory delivery tracker, not for durable
 * checkpoint state. Normative per the sync redesign RFC.
 */
export const MAX_PENDING_TOKENS = 100;
//# sourceMappingURL=sync.js.map