Something went wrong. Try again.
A collaborative coding-agent orchestrator for atproto radl.app
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117// Byte plumbing for the private path. Isomorphic by construction: no `node:buffer`, no `atob`, no// `Buffer` — the browser tab and the daemon have to produce identical bytes or they produce// different CIDs, and the surest way to guarantee that is for both to run this.
const BASE32_LOWER = 'abcdefghijklmnopqrstuvwxyz234567'const BASE64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
const ENCODER = new TextEncoder()const DECODER = new TextDecoder()
export const utf8 = (value: string): Uint8Array => ENCODER.encode(value)export const fromUtf8 = (bytes: Uint8Array): string => DECODER.decode(bytes)
export function concat(...parts: Uint8Array[]): Uint8Array { const total = parts.reduce((sum, part) => sum + part.length, 0) const out = new Uint8Array(total) let offset = 0 for (const part of parts) { out.set(part, offset) offset += part.length } return out}
export function equalBytes(left: Uint8Array, right: Uint8Array): boolean { if (left.length !== right.length) return false for (let index = 0; index < left.length; index += 1) { if (left[index] !== right[index]) return false } return true}
/** Bytewise comparison — the tie-break inside DAG-CBOR's length-first map key ordering. */export function compareBytes(left: Uint8Array, right: Uint8Array): number { const shared = Math.min(left.length, right.length) for (let index = 0; index < shared; index += 1) { const a = left[index] as number const b = right[index] as number if (a !== b) return a < b ? -1 : 1 } return left.length - right.length}
/** RFC 4648 base32, lowercase, unpadded — the multibase `b` alphabet CIDv1 is written in. */export function base32Encode(bytes: Uint8Array): string { let out = '' let buffer = 0 let bits = 0 for (const byte of bytes) { buffer = (buffer << 8) | byte bits += 8 while (bits >= 5) { out += BASE32_LOWER[(buffer >>> (bits - 5)) & 31] bits -= 5 } } if (bits > 0) out += BASE32_LOWER[(buffer << (5 - bits)) & 31] return out}
export function base32Decode(value: string): Uint8Array { const out: number[] = [] let buffer = 0 let bits = 0 for (const character of value) { const index = BASE32_LOWER.indexOf(character) if (index === -1) throw new TypeError(`not base32: ${value}`) buffer = (buffer << 5) | index bits += 5 if (bits >= 8) { out.push((buffer >>> (bits - 8)) & 0xff) bits -= 8 } } return new Uint8Array(out)}
/** Unpadded base64url — how a public key and a signature travel in a record or an envelope. */export function base64urlEncode(bytes: Uint8Array): string { let out = '' for (let index = 0; index < bytes.length; index += 3) { const a = bytes[index] as number const b = bytes[index + 1] const c = bytes[index + 2] out += BASE64URL[a >>> 2] out += BASE64URL[((a & 3) << 4) | ((b ?? 0) >>> 4)] if (b === undefined) break out += BASE64URL[((b & 15) << 2) | ((c ?? 0) >>> 6)] if (c === undefined) break out += BASE64URL[c & 63] } return out}
export function base64urlDecode(value: string): Uint8Array { const out: number[] = [] let buffer = 0 let bits = 0 for (const character of value) { const index = BASE64URL.indexOf(character) if (index === -1) throw new TypeError(`not base64url: ${value}`) buffer = (buffer << 6) | index bits += 6 if (bits >= 8) { out.push((buffer >>> (bits - 8)) & 0xff) bits -= 8 } } return new Uint8Array(out)}
export function hexEncode(bytes: Uint8Array): string { let out = '' for (const byte of bytes) out += byte.toString(16).padStart(2, '0') return out}