mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-25 10:58:19 +01:00
Rename files
This commit is contained in:
105
ts/util/getStreamWithTimeout.node.ts
Normal file
105
ts/util/getStreamWithTimeout.node.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { Transform } from 'node:stream';
|
||||
import type { Readable } from 'node:stream';
|
||||
|
||||
import * as Bytes from '../Bytes.std.js';
|
||||
import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary.std.js';
|
||||
import { explodePromise } from './explodePromise.std.js';
|
||||
|
||||
export type OptionsType = Readonly<{
|
||||
name: string;
|
||||
timeout: number;
|
||||
abortController: { abort(): void };
|
||||
}>;
|
||||
|
||||
export class StreamTimeoutError extends Error {}
|
||||
|
||||
export function getStreamWithTimeout(
|
||||
stream: Readable,
|
||||
{ name, timeout, abortController }: OptionsType
|
||||
): Promise<Uint8Array> {
|
||||
const { promise, resolve, reject } = explodePromise<Uint8Array>();
|
||||
|
||||
const chunks = new Array<Uint8Array>();
|
||||
|
||||
let timer: NodeJS.Timeout | undefined;
|
||||
|
||||
const clearTimer = () => {
|
||||
clearTimeoutIfNecessary(timer);
|
||||
timer = undefined;
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
clearTimer();
|
||||
|
||||
timer = setTimeout(() => {
|
||||
abortController.abort();
|
||||
reject(new StreamTimeoutError(`getStreamWithTimeout(${name}) timed out`));
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
stream.on('data', chunk => {
|
||||
reset();
|
||||
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
clearTimer();
|
||||
resolve(Bytes.concatenate(chunks));
|
||||
});
|
||||
|
||||
stream.on('error', error => {
|
||||
clearTimer();
|
||||
reject(error);
|
||||
});
|
||||
|
||||
reset();
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
export function getTimeoutStream({
|
||||
name,
|
||||
timeout,
|
||||
abortController,
|
||||
}: OptionsType): Transform {
|
||||
const timeoutStream = new Transform();
|
||||
|
||||
let timer: NodeJS.Timeout | undefined;
|
||||
const clearTimer = () => {
|
||||
clearTimeoutIfNecessary(timer);
|
||||
timer = undefined;
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
clearTimer();
|
||||
|
||||
timer = setTimeout(() => {
|
||||
abortController.abort();
|
||||
timeoutStream.emit(
|
||||
'error',
|
||||
new StreamTimeoutError(`getStreamWithTimeout(${name}) timed out`)
|
||||
);
|
||||
clearTimer();
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
timeoutStream._transform = function transform(chunk, _encoding, done) {
|
||||
try {
|
||||
reset();
|
||||
} catch (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
this.push(chunk);
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
reset();
|
||||
|
||||
return timeoutStream;
|
||||
}
|
||||
Reference in New Issue
Block a user