mirror of
https://github.com/ItzCrazyKns/Perplexica.git
synced 2025-12-25 04:58:15 +00:00
106 lines
2.6 KiB
TypeScript
106 lines
2.6 KiB
TypeScript
import { EventEmitter } from 'stream';
|
|
import { applyPatch } from 'rfc6902';
|
|
import { Block } from './types';
|
|
|
|
const sessions =
|
|
(global as any)._sessionManagerSessions || new Map<string, SessionManager>();
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
(global as any)._sessionManagerSessions = sessions;
|
|
}
|
|
|
|
class SessionManager {
|
|
private static sessions: Map<string, SessionManager> = sessions;
|
|
readonly id: string;
|
|
private blocks = new Map<string, Block>();
|
|
private events: { event: string; data: any }[] = [];
|
|
private emitter = new EventEmitter();
|
|
private TTL_MS = 30 * 60 * 1000;
|
|
|
|
constructor(id?: string) {
|
|
this.id = id ?? crypto.randomUUID();
|
|
|
|
setTimeout(() => {
|
|
SessionManager.sessions.delete(this.id);
|
|
}, this.TTL_MS);
|
|
}
|
|
|
|
static getSession(id: string): SessionManager | undefined {
|
|
return this.sessions.get(id);
|
|
}
|
|
|
|
static getAllSessions(): SessionManager[] {
|
|
return Array.from(this.sessions.values());
|
|
}
|
|
|
|
static createSession(): SessionManager {
|
|
const session = new SessionManager();
|
|
this.sessions.set(session.id, session);
|
|
return session;
|
|
}
|
|
|
|
removeAllListeners() {
|
|
this.emitter.removeAllListeners();
|
|
}
|
|
|
|
emit(event: string, data: any) {
|
|
this.emitter.emit(event, data);
|
|
this.events.push({ event, data });
|
|
}
|
|
|
|
emitBlock(block: Block) {
|
|
this.blocks.set(block.id, block);
|
|
this.emit('data', {
|
|
type: 'block',
|
|
block: block,
|
|
});
|
|
}
|
|
|
|
getBlock(blockId: string): Block | undefined {
|
|
return this.blocks.get(blockId);
|
|
}
|
|
|
|
updateBlock(blockId: string, patch: any[]) {
|
|
const block = this.blocks.get(blockId);
|
|
|
|
if (block) {
|
|
applyPatch(block, patch);
|
|
this.blocks.set(blockId, block);
|
|
this.emit('data', {
|
|
type: 'updateBlock',
|
|
blockId: blockId,
|
|
patch: patch,
|
|
});
|
|
}
|
|
}
|
|
|
|
getAllBlocks() {
|
|
return Array.from(this.blocks.values());
|
|
}
|
|
|
|
subscribe(listener: (event: string, data: any) => void): () => void {
|
|
const currentEventsLength = this.events.length;
|
|
|
|
const handler = (event: string) => (data: any) => listener(event, data);
|
|
const dataHandler = handler('data');
|
|
const endHandler = handler('end');
|
|
const errorHandler = handler('error');
|
|
|
|
this.emitter.on('data', dataHandler);
|
|
this.emitter.on('end', endHandler);
|
|
this.emitter.on('error', errorHandler);
|
|
|
|
for (let i = 0; i < currentEventsLength; i++) {
|
|
const { event, data } = this.events[i];
|
|
listener(event, data);
|
|
}
|
|
|
|
return () => {
|
|
this.emitter.off('data', dataHandler);
|
|
this.emitter.off('end', endHandler);
|
|
this.emitter.off('error', errorHandler);
|
|
};
|
|
}
|
|
}
|
|
|
|
export default SessionManager;
|