37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
export interface SessionRecord {
|
|
value: Record<string, unknown>;
|
|
expires: number;
|
|
}
|
|
|
|
export interface SessionStore {
|
|
get(key: string): Promise<SessionRecord | undefined>;
|
|
set(key: string, record: SessionRecord): Promise<void>;
|
|
delete(key: string): Promise<void>;
|
|
/** Atomically removes and returns a transaction, preventing callback replay. */
|
|
consume(key: string): Promise<SessionRecord | undefined>;
|
|
}
|
|
|
|
export class MemorySessionStore implements SessionStore {
|
|
private readonly records = new Map<string, SessionRecord>();
|
|
async get(key: string): Promise<SessionRecord | undefined> {
|
|
const record = this.records.get(key);
|
|
if (!record || record.expires <= Date.now()) {
|
|
this.records.delete(key);
|
|
return undefined;
|
|
}
|
|
return structuredClone(record);
|
|
}
|
|
async set(key: string, record: SessionRecord): Promise<void> {
|
|
this.records.set(key, structuredClone(record));
|
|
}
|
|
async delete(key: string): Promise<void> {
|
|
this.records.delete(key);
|
|
}
|
|
async consume(key: string): Promise<SessionRecord | undefined> {
|
|
const record = this.records.get(key);
|
|
this.records.delete(key);
|
|
return record && record.expires > Date.now()
|
|
? structuredClone(record)
|
|
: undefined;
|
|
}
|
|
}
|