EYHN
2024-03-22 16:43:26 +00:00
parent 05c44db5a9
commit 34703a3b7d
85 changed files with 3248 additions and 2286 deletions
@@ -1 +1,2 @@
export * from './kv';
export * from './memento';
+85
View File
@@ -0,0 +1,85 @@
import { AsyncLock } from '../utils';
export interface ByteKV extends ByteKVBehavior {
transaction<T>(cb: (transaction: ByteKVBehavior) => Promise<T>): Promise<T>;
}
export interface ByteKVBehavior {
get(key: string): Promise<Uint8Array | null> | Uint8Array | null;
set(key: string, value: Uint8Array): Promise<void> | void;
del(key: string): Promise<void> | void;
keys(): Promise<string[]> | string[];
clear(): Promise<void> | void;
}
export class MemoryByteKV implements ByteKV {
readonly lock = new AsyncLock();
constructor(readonly db = new Map<string, Uint8Array>()) {}
async transaction<T>(cb: (transaction: ByteKVBehavior) => Promise<T>) {
using _lock = await this.lock.acquire();
return await cb({
get: async key => {
return this.db.get(key) ?? null;
},
set: async (key, value) => {
this.db.set(key, value);
},
keys: async () => {
return Array.from(this.db.keys());
},
del: async key => {
this.db.delete(key);
},
clear: async () => {
this.db.clear();
},
});
}
get(key: string) {
return this.transaction(async tx => tx.get(key));
}
set(key: string, value: Uint8Array) {
return this.transaction(async tx => tx.set(key, value));
}
keys() {
return this.transaction(async tx => tx.keys());
}
clear() {
return this.transaction(async tx => tx.clear());
}
del(key: string) {
return this.transaction(async tx => tx.del(key));
}
}
export class ReadonlyByteKV extends MemoryByteKV implements ByteKV {
override transaction<T>(
cb: (transaction: ByteKVBehavior) => Promise<T>
): Promise<T> {
return super.transaction(tx => {
return cb({
...tx,
set() {
return Promise.resolve();
},
del() {
return Promise.resolve();
},
clear() {
return Promise.resolve();
},
});
});
}
override set(_key: string, _value: Uint8Array): Promise<void> {
return Promise.resolve();
}
override del(_key: string): Promise<void> {
return Promise.resolve();
}
override clear(): Promise<void> {
return Promise.resolve();
}
}
@@ -10,6 +10,9 @@ export interface Memento {
get<T>(key: string): T | null;
watch<T>(key: string): Observable<T | null>;
set<T>(key: string, value: T | null): void;
del(key: string): void;
clear(): void;
keys(): string[];
}
/**
@@ -54,4 +57,43 @@ export class MemoryMemento implements Memento {
set<T>(key: string, value: T | null): void {
this.getLiveData(key).next(value);
}
keys(): string[] {
return Array.from(this.data.keys());
}
clear(): void {
this.data.clear();
}
del(key: string): void {
this.data.delete(key);
}
}
export function wrapMemento(memento: Memento, prefix: string): Memento {
return {
get<T>(key: string): T | null {
return memento.get(prefix + key);
},
watch(key: string) {
return memento.watch(prefix + key);
},
set<T>(key: string, value: T | null): void {
memento.set(prefix + key, value);
},
keys(): string[] {
return memento
.keys()
.filter(k => k.startsWith(prefix))
.map(k => k.slice(prefix.length));
},
clear() {
memento.keys().forEach(k => {
if (k.startsWith(prefix)) {
memento.del(k);
}
});
},
del(key: string): void {
memento.del(prefix + key);
},
};
}