session-lifecycle.ts 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. export class SessionLifecycle {
  2. #cleanupCallbacks: Array<(sessionId: string) => void> = [];
  3. #pendingSessionIds = new Set<string>();
  4. #log: (msg: string, meta?: Record<string, unknown>) => void;
  5. constructor(log: (msg: string, meta?: Record<string, unknown>) => void) {
  6. this.#log = log;
  7. }
  8. onSessionDeleted(callback: (sessionId: string) => void): void {
  9. this.#cleanupCallbacks.push(callback);
  10. }
  11. dispatchSessionDeleted(sessionId: string): void {
  12. for (const cb of this.#cleanupCallbacks) {
  13. try {
  14. cb(sessionId);
  15. } catch (error) {
  16. this.#log(
  17. `[session-lifecycle] cleanup callback failed for session ${sessionId}`,
  18. { error },
  19. );
  20. }
  21. }
  22. }
  23. markPending(sessionId: string): void {
  24. this.#pendingSessionIds.add(sessionId);
  25. }
  26. /** Atomic — only one caller gets true per markPending call. */
  27. consumePending(sessionId: string): boolean {
  28. const had = this.#pendingSessionIds.has(sessionId);
  29. this.#pendingSessionIds.delete(sessionId);
  30. return had;
  31. }
  32. clearSession(sessionId: string): void {
  33. this.#pendingSessionIds.delete(sessionId);
  34. }
  35. }