import { CID } from 'multiformats';
import { NotFoundError } from 'interface-store';
import { collectBlockstoreBytes, deleteManyBlockstoreItems, getManyBlockstoreItems, putManyBlockstoreItems, yieldBlockstoreBytes, } from './blockstore-utils.js';
import { createLevelDatabase, LevelWrapper } from './level-wrapper.js';
// `level` works in Node.js 12+ and Electron 5+ on Linux, Mac OS, Windows and
// FreeBSD, including any future Node.js and Electron release thanks to Node-API, including ARM
// platforms like Raspberry Pi and Android, as well as in Chrome, Firefox, Edge, Safari, iOS Safari
//  and Chrome for Android.
/**
 * Blockstore implementation using LevelDB for storing the actual messages (in the case of MessageStore)
 * or the data associated with messages (in the case of a DataStore).
 */
export class BlockstoreLevel {
    config;
    db;
    constructor(config, db) {
        this.config = {
            createLevelDatabase,
            ...config
        };
        this.db = db ?? new LevelWrapper({ ...this.config, valueEncoding: 'binary' });
    }
    async open() {
        return this.db.open();
    }
    async close() {
        return this.db.close();
    }
    async partition(name) {
        const db = await this.db.partition(name);
        return new BlockstoreLevel({ ...this.config, location: '' }, db);
    }
    async put(key, val, options) {
        const bytes = await collectBlockstoreBytes(val);
        await this.db.put(String(key), bytes, options);
        return CID.parse(key.toString());
    }
    async *get(key, options) {
        const result = await this.db.get(String(key), options);
        if (result === undefined) {
            throw new NotFoundError();
        }
        yield result;
    }
    async has(key, options) {
        return this.db.has(String(key), options);
    }
    async delete(key, options) {
        return this.db.delete(String(key), options);
    }
    async isEmpty(options) {
        return this.db.isEmpty(options);
    }
    async *putMany(source, options) {
        yield* putManyBlockstoreItems(this, source, options);
    }
    async *getMany(source, options) {
        yield* getManyBlockstoreItems(this, source, options);
    }
    async *getAll(options) {
        const li = this.db.iterator({ keys: true }, options);
        for await (const [key, value] of li) {
            yield { cid: CID.parse(key), bytes: yieldBlockstoreBytes(value) };
        }
    }
    async *deleteMany(source, options) {
        yield* deleteManyBlockstoreItems(this, source, options);
    }
    /**
     * deletes all entries
     */
    async clear() {
        return this.db.clear();
    }
}
//# sourceMappingURL=blockstore-level.js.map