examples/live-notes Public
// The part of an R2 bucket snapshots.ts uses (put, get and list with prefix, startAfter and// limit), in memory. Keys list in byte order, as they do in R2.type Stored = { text: string; uploaded: Date };export class MemoryBucket { objects = new Map<string, Stored>(); failNext = false; #clock: () => Date; constructor(clock: () => Date = () => new Date()) { this.#clock = clock; } async put(key: string, value: string): Promise<void> { if (this.failNext) { this.failNext = false; throw new Error("R2 put failed: 503 Service Unavailable"); } this.objects.set(key, { text: value, uploaded: this.#clock() }); } async get(key: string) { const o = this.objects.get(key); return o ? { text: async () => o.text } : null; } async list({ prefix = "", startAfter = "", limit = 1000 }: { prefix?: string; startAfter?: string; limit?: number }) { const keys = [...this.objects.keys()].filter((k) => k.startsWith(prefix) && k > startAfter).sort(); const objects = keys.slice(0, limit).map((key) => ({ key, size: new TextEncoder().encode(this.objects.get(key)!.text).length, uploaded: this.objects.get(key)!.uploaded })); return { objects, truncated: keys.length > limit }; }}export function memoryBucket(clock?: () => Date): MemoryBucket & R2Bucket { return new MemoryBucket(clock) as MemoryBucket & R2Bucket;}