cf-workers-idbkv
Version:
IndexedDB (IDB) backed Cloudflare workers KV store for testing.
93 lines • 2.17 kB
JavaScript
import { KV } from 'cf-workers-kv';
// @ts-ignore
import IdbKvStore from 'idb-kv-store';
import Fifo from 'p-fifo';
class IDBBackend {
constructor(name) {
this.idb = new IdbKvStore(name);
}
clear() {
return this.idb.clear();
}
delete(key) {
return this.idb.remove(key);
}
async forEach(callbackfn, thisArg) {
for await (const [k, v] of toIterable(this.idb)) {
// @ts-ignore
callbackfn.call(thisArg, v, k, this);
}
}
get(key) {
return this.idb.get(key);
}
async has(key) {
const v = await this.idb.get(key);
return v !== undefined;
}
async set(key, value) {
await this.idb.set(key, value);
return this;
}
get size() {
return this.idb.count();
}
async *entries() {
for await (const entry of toIterable(this.idb)) {
yield entry;
}
}
async *keys() {
for await (const entry of toIterable(this.idb)) {
yield entry[0];
}
}
async *values() {
for await (const entry of toIterable(this.idb)) {
yield entry[1];
}
}
close() {
return this.idb.close();
}
}
async function* toIterable(idb) {
let done = false;
const q = new Fifo();
const txn = idb.iterator(async (err, cursor) => {
if (err || !cursor) {
done = true;
return q.push(err || done);
}
await q.push([cursor.key, cursor.value]);
cursor.continue();
});
try {
while (true) {
const val = await q.shift();
if (val instanceof Error)
throw val;
if (val === true)
return;
yield val;
}
}
finally {
if (!done)
txn.abort();
}
}
export class IDBKV extends KV {
constructor(name) {
const be = new IDBBackend(name);
super(be);
this.backend = be;
}
clear() {
return this.backend.clear();
}
close() {
return this.backend.close();
}
}
//# sourceMappingURL=IDBKV.js.map