p2p-media-loader-core
Version:
P2P Media Loader core functionality
120 lines (119 loc) • 4.95 kB
TypeScript
import { BandwidthCalculators, Playback } from "../internal-types.js";
import { CoreEventMap, RequestError, RequestAbortErrorType, RequestErrorType, SegmentWithStream, Segment } from "../types.js";
import * as StreamUtils from "../utils/stream.js";
import { EventTarget } from "../utils/event-target.js";
export type LoadProgress = {
startTimestamp: number;
lastLoadedChunkTimestamp?: number;
startFromByte?: number;
loadedBytes: number;
};
type HttpRequestAttempt = {
downloadSource: "http";
error?: RequestError;
};
type P2PRequestAttempt = {
downloadSource: "p2p";
peerId: string;
error?: RequestError;
};
export type RequestAttempt = HttpRequestAttempt | P2PRequestAttempt;
export type RequestControls = Readonly<{
firstBytesReceived: Request["firstBytesReceived"];
addLoadedChunk: Request["addLoadedChunk"];
completeOnSuccess: Request["completeOnSuccess"];
failWithError: Request["failWithError"];
}>;
type OmitEncapsulated<T extends RequestAttempt> = Omit<T, "error" | "errorTimestamp">;
type StartRequestParameters = OmitEncapsulated<HttpRequestAttempt> | OmitEncapsulated<P2PRequestAttempt>;
export type RequestStatus = "not-started" | "loading" | "succeed" | "failed" | "aborted";
export declare class Request {
readonly segment: SegmentWithStream;
private readonly requestProcessQueueCallback;
private readonly bandwidthCalculators;
private readonly playback;
private readonly playbackConfig;
readonly infoHash: string;
private currentAttempt?;
private _failedAttempts;
private finalData?;
private bytes;
private _loadedBytes;
private _totalBytes?;
private _status;
private progress?;
private notReceivingBytesTimeout;
private _onAbortCallback?;
private notReceivingBytesTimeoutMs?;
private readonly _logger;
private _isHandledByProcessQueue;
private readonly onSegmentError;
private readonly onSegmentAbort;
private readonly onSegmentStart;
private readonly onSegmentLoaded;
constructor(segment: SegmentWithStream, requestProcessQueueCallback: () => void, bandwidthCalculators: BandwidthCalculators, playback: Playback, playbackConfig: StreamUtils.PlaybackTimeWindowsConfig, eventTarget: EventTarget<CoreEventMap>, infoHash: string);
clearLoadedBytes(): void;
get status(): RequestStatus;
private setStatus;
get downloadSource(): "http" | "p2p" | undefined;
get loadedBytes(): number;
get totalBytes(): number | undefined;
get data(): ArrayBuffer;
get failedAttempts(): FailedRequestAttempts;
get isHandledByProcessQueue(): boolean;
markHandledByProcessQueue(): void;
setTotalBytes(value: number): void;
/**
* Checks if all bytes are already loaded and, if so, starts, validates,
* and completes the request without making a network request.
*
* Handles three cases:
* - loadedBytes === totalBytes: start → validate → complete (returns true)
* - loadedBytes > totalBytes: corrupted state → clearLoadedBytes (returns false)
* - otherwise: no-op (returns false)
*
* The request is started synchronously so that processQueue sees
* it as "loading" immediately. Validation runs as fire-and-forget.
*
* @returns true if the request was started and is being handled,
* false if caller should proceed with a normal download.
*/
tryCompleteByLoadedBytes(requestData: StartRequestParameters, controls: {
notReceivingBytesTimeoutMs?: number;
onAbort: (errorType: RequestError<RequestAbortErrorType>) => void;
}, validate: ((url: string, byteRange: Segment["byteRange"], data: ArrayBuffer) => Promise<boolean>) | undefined, validationErrorType: RequestErrorType): boolean;
validateData(validate?: (url: string, byteRange: Segment["byteRange"], data: ArrayBuffer) => Promise<boolean>): Promise<boolean>;
private validateAndComplete;
start(requestData: StartRequestParameters, controls: {
notReceivingBytesTimeoutMs?: number;
onAbort: (errorType: RequestError<RequestAbortErrorType>) => void;
}): RequestControls;
cancel(): void;
private abortOnTimeout;
private failWithError;
private handleFailure;
private completeOnSuccess;
private addLoadedChunk;
private firstBytesReceived;
private throwErrorIfNotLoadingStatus;
private logger;
private manageBandwidthCalculatorsState;
}
declare class FailedRequestAttempts {
private attempts;
add(attempt: Required<RequestAttempt>): void;
get httpAttemptsCount(): number;
get p2pAttemptsCount(): number;
get lastAttempt(): Readonly<Required<RequestAttempt>> | undefined;
clear(): void;
}
export declare class Timeout {
private readonly action;
private timeoutId?;
private ms?;
constructor(action: () => void);
start(ms: number): void;
restart(ms?: number): void;
clear(): void;
}
export {};