Last active
November 8, 2021 01:28
-
-
Save qwtel/8f1ab50722b928af8d4ccb71fde2c484 to your computer and use it in GitHub Desktop.
kv-storage implementation for Cloudflare Workers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Base64Encoder, Base64Decoder } from 'base64-encoding'; | |
const PREFIX = 'data:application/octet-stream;base64,'; | |
const b64e = new Base64Encoder(); | |
const b64d = new Base64Decoder(); | |
const encodeKey = (key: string | BufferSource) => typeof key !== 'string' ? PREFIX + b64e.encode(key) : key; | |
const decodeKey = (key: string) => key.startsWith(PREFIX) ? b64d.decode(key.substr(PREFIX.length)) : key; | |
async function* __paginationHelper(db: KVNamespace) { | |
let keys: { name: string; expiration?: number; metadata?: unknown }[]; | |
let done: boolean; | |
let cursor: string; | |
do { | |
({ keys, list_complete: done, cursor } = await db.list({ ...cursor ? { cursor } : {} })); | |
for (const { name } of keys) yield name; | |
} while (!done); | |
} | |
export class StorageArea { | |
db: KVNamespace; | |
constructor(name: string) { | |
this.db = Reflect.get(self, name); | |
} | |
async get(key: string | BufferSource) { | |
return this.db.get(encodeKey(key)); | |
} | |
async set(key: string | BufferSource, value: string): Promise<void> { | |
this.db.put(encodeKey(key), value); | |
} | |
async delete(key: string | BufferSource) { | |
return this.db.delete(encodeKey(key)); | |
} | |
async clear() { | |
for await (const key of __paginationHelper(this.db)) { | |
await this.db.delete(key) | |
} | |
} | |
async *keys(): AsyncGenerator<string | BufferSource> { | |
for await (let key of __paginationHelper(this.db)) { | |
yield decodeKey(key); | |
} | |
} | |
async *values(): AsyncGenerator<string> { | |
for await (let key of __paginationHelper(this.db)) { | |
yield this.db.get(key); | |
} | |
} | |
async *entries(): AsyncGenerator<[string | BufferSource, string]> { | |
for await (let key of __paginationHelper(this.db)) { | |
yield [decodeKey(key), await this.db.get(key)]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Update:
A better implementation is now available as a standalone module here: https://github.com/worker-utils/cloudflare-kv-storage