Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152import * as CID from '@atcute/cid';import type { Cid } from '@atcute/lexicons';
/** A project's files by path. The SDK speaks in these; the app adapts them to the kernel's filesystem. */export type FileTree = Map<string, Uint8Array>;
/** Changes on top of a base tree. A null value deletes the base's path. */export type Overlay<T> = Map<string, T | null>;
/** The raw-codec CID a PDS assigns to these bytes as a blob. */export async function blobCid(bytes: Uint8Array): Promise<Cid> { return CID.toString(await CID.create(CID.CODEC_RAW, bytes));}
export async function hashTree(tree: ReadonlyMap<string, Uint8Array>): Promise<Map<string, Cid>> { const entries = await Promise.all([...tree].map(async ([path, bytes]) => [path, await blobCid(bytes)] as const)); return new Map(entries);}
/** * The overlay that turns `base` into `current`, sorted by path. * Without a base the overlay is the whole tree; with one it holds only changed and added paths, plus a null for each removed path. */export function diffAgainstBase( base: ReadonlyMap<string, Cid> | undefined, current: ReadonlyMap<string, Cid>,): Overlay<Cid> { const overlay: Overlay<Cid> = new Map(); for (const [path, cid] of current) { if (base?.get(path) !== cid) overlay.set(path, cid); } if (base) { for (const path of base.keys()) { if (!current.has(path)) overlay.set(path, null); } } return sortByPath(overlay);}
export function applyOverlay<T>(base: ReadonlyMap<string, T>, overlay: ReadonlyMap<string, T | null>): Map<string, T> { const tree = new Map(base); for (const [path, value] of overlay) { if (value === null) tree.delete(path); else tree.set(path, value); } return sortByPath(tree);}
function sortByPath<T>(map: Map<string, T>): Map<string, T> { return new Map([...map].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));}