function isPlainObject(x) {
    if (x === null || typeof x !== "object") {
        return false;
    }
    if (Array.isArray(x)) {
        return false;
    }
    const proto = Object.getPrototypeOf(x);
    return proto === Object.prototype || proto === null;
}
function isImageRef(x) {
    if (!isPlainObject(x)) {
        return false;
    }
    return x.type === "image" && x.data === "" && typeof x.imageId === "string" && x.imageId.length > 0;
}
export class PeerImageCache {
    byId = new Map();
    store(payload) {
        this.byId.set(payload.imageId, { ...payload });
    }
    get(imageId) {
        return this.byId.get(imageId);
    }
    hydrate(value) {
        return this.hydrateValue(value);
    }
    collectMissingImageIds(value) {
        const seen = new Set();
        const out = [];
        const visit = (v) => {
            if (v === null || typeof v !== "object") {
                return;
            }
            if (Array.isArray(v)) {
                for (const el of v) {
                    visit(el);
                }
                return;
            }
            if (isImageRef(v) && !this.byId.has(v.imageId) && !seen.has(v.imageId)) {
                seen.add(v.imageId);
                out.push(v.imageId);
                return;
            }
            if (isPlainObject(v) && v.type === "image") {
                return;
            }
            if (isPlainObject(v)) {
                for (const k of Object.keys(v)) {
                    visit(v[k]);
                }
            }
        };
        visit(value);
        return out;
    }
    hydrateValue(value) {
        if (value === null || typeof value !== "object") {
            return value;
        }
        if (Array.isArray(value)) {
            return this.hydrateArray(value);
        }
        if (isImageRef(value)) {
            const hit = this.byId.get(value.imageId);
            if (hit) {
                return { ...value, data: hit.data, mimeType: hit.mimeType, imageId: hit.imageId };
            }
            return value;
        }
        if (isPlainObject(value)) {
            return this.hydratePlainObject(value);
        }
        return value;
    }
    hydrateArray(value) {
        let changed = false;
        const out = new Array(value.length);
        for (let i = 0; i < value.length; i++) {
            const el = value[i];
            const next = this.hydrateValue(el);
            if (next !== el) {
                changed = true;
            }
            out[i] = next;
        }
        return changed ? out : value;
    }
    hydratePlainObject(x) {
        let changed = false;
        const result = {};
        for (const k of Object.keys(x)) {
            const el = x[k];
            const next = this.hydrateValue(el);
            if (next !== el) {
                changed = true;
            }
            result[k] = next;
        }
        return changed ? result : x;
    }
}
//# sourceMappingURL=peer-image-cache.js.map