char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aleksander Grygierui: Linting & Formatting scripts (#26819)92d1bb0c9

char/aliceai-t5-moe
4.7 KiB173 linesraw
1/**
2 * Abort Signal Utilities
3 *
4 * Provides utilities for consistent AbortSignal propagation across the application.
5 * These utilities help ensure that async operations can be properly cancelled
6 * when needed (e.g., user stops generation, navigates away, etc.).
7 */
8
9// the standard DOMException name for a cancelled operation
10const ABORT_ERROR_NAME = 'AbortError';
11// browser specific TypeError messages emitted when a fetch reader is cut by page unload,
12// navigation, or a transient network drop. functionally aborts, not actionable errors
13const ABORT_LIKE_MESSAGE_PATTERNS = [
14	/input stream/i, // Firefox: stream cut at unload
15	/network connection was lost/i, // Safari: transient network drop
16	/load failed/i // Safari: page navigation during fetch
17];
18
19/**
20 * Throws an AbortError if the signal is aborted.
21 * Use this at the start of async operations to fail fast.
22 *
23 * @param signal - Optional AbortSignal to check
24 * @throws DOMException with name 'AbortError' if signal is aborted
25 *
26 * @example
27 * ```ts
28 * async function fetchData(signal?: AbortSignal) {
29 *   throwIfAborted(signal);
30 *   // ... proceed with operation
31 * }
32 * ```
33 */
34export function throwIfAborted(signal?: AbortSignal): void {
35	if (signal?.aborted) {
36		throw new DOMException('Operation was aborted', ABORT_ERROR_NAME);
37	}
38}
39
40/**
41 * Checks if an error is an AbortError.
42 * Use this to distinguish between user-initiated cancellation and actual errors.
43 *
44 * @param error - Error to check
45 * @returns true if the error is an AbortError
46 *
47 * @example
48 * ```ts
49 * try {
50 *   await fetchData(signal);
51 * } catch (error) {
52 *   if (isAbortError(error)) {
53 *     // User cancelled - no error dialog needed
54 *     return;
55 *   }
56 *   // Handle actual error
57 * }
58 * ```
59 */
60export function isAbortError(error: unknown): boolean {
61	if (error instanceof DOMException && error.name === ABORT_ERROR_NAME) {
62		return true;
63	}
64
65	if (error instanceof Error) {
66		if (error.name === ABORT_ERROR_NAME) {
67			return true;
68		}
69
70		// these patterns are functionally aborts, keep them out of the red console
71		if (error instanceof TypeError) {
72			const msg = error.message ?? '';
73
74			if (ABORT_LIKE_MESSAGE_PATTERNS.some((re) => re.test(msg))) return true;
75		}
76	}
77
78	return false;
79}
80
81/**
82 * Creates a new AbortController that is linked to one or more parent signals.
83 * When any parent signal aborts, the returned controller also aborts.
84 *
85 * Useful for creating child operations that should be cancelled when
86 * either the parent operation or their own timeout/condition triggers.
87 *
88 * @param signals - Parent signals to link to (undefined signals are ignored)
89 * @returns A new AbortController linked to all provided signals
90 *
91 * @example
92 * ```ts
93 * // Link to user's abort signal and add a timeout
94 * const linked = createLinkedController(userSignal, timeoutSignal);
95 * await fetch(url, { signal: linked.signal });
96 * ```
97 */
98export function createLinkedController(...signals: (AbortSignal | undefined)[]): AbortController {
99	const controller = new AbortController();
100
101	for (const signal of signals) {
102		if (!signal) continue;
103
104		// If already aborted, abort immediately
105		if (signal.aborted) {
106			controller.abort(signal.reason);
107
108			return controller;
109		}
110
111		// Link to parent signal
112		signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });
113	}
114
115	return controller;
116}
117
118/**
119 * Creates an AbortSignal that times out after the specified duration.
120 *
121 * @param ms - Timeout duration in milliseconds
122 * @returns AbortSignal that will abort after the timeout
123 *
124 * @example
125 * ```ts
126 * const signal = createTimeoutSignal(5000); // 5 second timeout
127 * await fetch(url, { signal });
128 * ```
129 */
130export function createTimeoutSignal(ms: number): AbortSignal {
131	return AbortSignal.timeout(ms);
132}
133
134/**
135 * Wraps a promise to reject if the signal is aborted.
136 * Useful for making non-abortable promises respect an AbortSignal.
137 *
138 * @param promise - Promise to wrap
139 * @param signal - AbortSignal to respect
140 * @returns Promise that rejects with AbortError if signal aborts
141 *
142 * @example
143 * ```ts
144 * // Make a non-abortable operation respect abort signal
145 * const result = await withAbortSignal(
146 *   someNonAbortableOperation(),
147 *   signal
148 * );
149 * ```
150 */
151export async function withAbortSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {
152	if (!signal) return promise;
153
154	throwIfAborted(signal);
155
156	return new Promise<T>((resolve, reject) => {
157		const abortHandler = () => {
158			reject(new DOMException('Operation was aborted', ABORT_ERROR_NAME));
159		};
160
161		signal.addEventListener('abort', abortHandler, { once: true });
162
163		promise
164			.then((value) => {
165				signal.removeEventListener('abort', abortHandler);
166				resolve(value);
167			})
168			.catch((error) => {
169				signal.removeEventListener('abort', abortHandler);
170				reject(error);
171			});
172	});
173}