UNPKG

datastore-core

Version:
142 lines 4.38 kB
import { DeleteFailedError, NotFoundError, PutFailedError } from 'interface-store'; import filter from 'it-filter'; import merge from 'it-merge'; import sort from 'it-sort'; import take from 'it-take'; import { BaseDatastore } from './base.js'; /** * A datastore that can combine multiple stores inside various * key prefixes */ export class MountDatastore extends BaseDatastore { mounts; constructor(mounts) { super(); this.mounts = mounts.slice(); } /** * Lookup the matching datastore for the given key */ _lookup(key) { for (const mount of this.mounts) { if (mount.prefix.toString() === key.toString() || mount.prefix.isAncestorOf(key)) { return { datastore: mount.datastore, mountpoint: mount.prefix }; } } } async put(key, value, options) { const match = this._lookup(key); if (match == null) { throw new PutFailedError('No datastore mounted for this key'); } await match.datastore.put(key, value, options); return key; } /** * @param {Key} key * @param {Options} [options] */ async get(key, options = {}) { const match = this._lookup(key); if (match == null) { throw new NotFoundError('No datastore mounted for this key'); } return match.datastore.get(key, options); } async has(key, options) { const match = this._lookup(key); if (match == null) { return Promise.resolve(false); } return match.datastore.has(key, options); } async delete(key, options) { const match = this._lookup(key); if (match == null) { throw new DeleteFailedError('No datastore mounted for this key'); } await match.datastore.delete(key, options); } batch() { const batchMounts = {}; const lookup = (key) => { const match = this._lookup(key); if (match == null) { throw new Error('No datastore mounted for this key'); } const m = match.mountpoint.toString(); if (batchMounts[m] == null) { batchMounts[m] = match.datastore.batch(); } return { batch: batchMounts[m] }; }; return { put: (key, value) => { const match = lookup(key); match.batch.put(key, value); }, delete: (key) => { const match = lookup(key); match.batch.delete(key); }, commit: async (options) => { await Promise.all(Object.keys(batchMounts).map(async (p) => { await batchMounts[p].commit(options); })); } }; } query(q, options) { const qs = this.mounts.map(m => { return m.datastore.query({ prefix: q.prefix, filters: q.filters }, options); }); let it = merge(...qs); if (q.filters != null) { q.filters.forEach(f => { it = filter(it, f); }); } if (q.orders != null) { q.orders.forEach(o => { it = sort(it, o); }); } if (q.offset != null) { let i = 0; const offset = q.offset; it = filter(it, () => i++ >= offset); } if (q.limit != null) { it = take(it, q.limit); } return it; } queryKeys(q, options) { const qs = this.mounts.map(m => { return m.datastore.queryKeys({ prefix: q.prefix, filters: q.filters }, options); }); /** @type AsyncIterable<Key> */ let it = merge(...qs); if (q.filters != null) { q.filters.forEach(f => { it = filter(it, f); }); } if (q.orders != null) { q.orders.forEach(o => { it = sort(it, o); }); } if (q.offset != null) { let i = 0; const offset = q.offset; it = filter(it, () => i++ >= offset); } if (q.limit != null) { it = take(it, q.limit); } return it; } } //# sourceMappingURL=mount.js.map