| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- const IDLESS_INPUT_WAIT = Symbol('idless-input-wait');
- const INPUT_WAIT_ASK_EVENTS = {
- 'permission.asked': 'permission',
- 'question.asked': 'question',
- } as const;
- const INPUT_WAIT_RESOLUTION_EVENTS = {
- 'permission.replied': 'permission',
- 'question.replied': 'question',
- 'question.rejected': 'question',
- } as const;
- function isInputWaitAskEvent(
- type: string,
- ): type is keyof typeof INPUT_WAIT_ASK_EVENTS {
- return Object.hasOwn(INPUT_WAIT_ASK_EVENTS, type);
- }
- function isInputWaitResolutionEvent(
- type: string,
- ): type is keyof typeof INPUT_WAIT_RESOLUTION_EVENTS {
- return Object.hasOwn(INPUT_WAIT_RESOLUTION_EVENTS, type);
- }
- function inputWaitKey(kind: 'permission' | 'question', requestID: string) {
- return `${kind}:${requestID}`;
- }
- export function createInputWaitTracker(options: {
- shouldManageSession: (sessionID: string) => boolean;
- invalidateContinuation: (sessionID: string) => void;
- }) {
- const inputWaitsByParent = new Map<string, Set<string | symbol>>();
- function hasInputWait(sessionID: string): boolean {
- return (inputWaitsByParent.get(sessionID)?.size ?? 0) > 0;
- }
- function clearInputWaits(sessionID: string): void {
- inputWaitsByParent.delete(sessionID);
- }
- function trackInputWait(event: {
- type: string;
- properties?: { id?: string; requestID?: string; sessionID?: string };
- }): void {
- const sessionID = event.properties?.sessionID;
- if (!sessionID || !options.shouldManageSession(sessionID)) {
- return;
- }
- if (isInputWaitAskEvent(event.type)) {
- const requestID = event.properties?.id;
- const waits =
- inputWaitsByParent.get(sessionID) ?? new Set<string | symbol>();
- if (!requestID) {
- waits.add(IDLESS_INPUT_WAIT);
- inputWaitsByParent.set(sessionID, waits);
- options.invalidateContinuation(sessionID);
- return;
- }
- const key = inputWaitKey(INPUT_WAIT_ASK_EVENTS[event.type], requestID);
- waits.add(key);
- inputWaitsByParent.set(sessionID, waits);
- options.invalidateContinuation(sessionID);
- return;
- }
- if (!isInputWaitResolutionEvent(event.type)) return;
- const requestID = event.properties?.requestID;
- if (!requestID) return;
- const key = inputWaitKey(
- INPUT_WAIT_RESOLUTION_EVENTS[event.type],
- requestID,
- );
- const waits = inputWaitsByParent.get(sessionID);
- if (!waits) return;
- waits.delete(key);
- if (waits.size === 0) clearInputWaits(sessionID);
- }
- return {
- trackInputWait,
- hasInputWait,
- clearInputWaits,
- // Exposed for consumers not yet migrated (disposed handler, etc.)
- waitsByParent: inputWaitsByParent,
- };
- }
|