2020-05-03 15:10:52 -04:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
|
|
|
|
|
|
|
import {
|
|
|
|
Deferred,
|
|
|
|
getDeferred,
|
|
|
|
initializeTransformStream,
|
|
|
|
invokeOrNoop,
|
|
|
|
isTransformStream,
|
|
|
|
makeSizeAlgorithmFromSizeFunction,
|
|
|
|
setUpTransformStreamDefaultControllerFromTransformer,
|
|
|
|
validateAndNormalizeHighWaterMark,
|
|
|
|
} from "./internals.ts";
|
2020-07-08 05:26:39 -04:00
|
|
|
import type { ReadableStreamImpl } from "./readable_stream.ts";
|
2020-05-03 15:10:52 -04:00
|
|
|
import * as sym from "./symbols.ts";
|
2020-07-08 05:26:39 -04:00
|
|
|
import type { TransformStreamDefaultControllerImpl } from "./transform_stream_default_controller.ts";
|
|
|
|
import type { WritableStreamImpl } from "./writable_stream.ts";
|
2020-05-03 15:10:52 -04:00
|
|
|
import { customInspect, inspect } from "../console.ts";
|
2020-07-10 22:38:15 -04:00
|
|
|
import { setFunctionName } from "../util.ts";
|
2020-05-03 15:10:52 -04:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
export class TransformStreamImpl<I = any, O = any>
|
|
|
|
implements TransformStream<I, O> {
|
|
|
|
[sym.backpressure]?: boolean;
|
|
|
|
[sym.backpressureChangePromise]?: Deferred<void>;
|
|
|
|
[sym.readable]: ReadableStreamImpl<O>;
|
|
|
|
[sym.transformStreamController]: TransformStreamDefaultControllerImpl<I, O>;
|
|
|
|
[sym.writable]: WritableStreamImpl<I>;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
transformer: Transformer<I, O> = {},
|
|
|
|
writableStrategy: QueuingStrategy<I> = {},
|
2020-07-14 15:24:17 -04:00
|
|
|
readableStrategy: QueuingStrategy<O> = {},
|
2020-05-03 15:10:52 -04:00
|
|
|
) {
|
|
|
|
const writableSizeFunction = writableStrategy.size;
|
|
|
|
let writableHighWaterMark = writableStrategy.highWaterMark;
|
|
|
|
const readableSizeFunction = readableStrategy.size;
|
|
|
|
let readableHighWaterMark = readableStrategy.highWaterMark;
|
|
|
|
const writableType = transformer.writableType;
|
|
|
|
if (writableType !== undefined) {
|
|
|
|
throw new RangeError(
|
2020-07-14 15:24:17 -04:00
|
|
|
`Expected transformer writableType to be undefined, received "${
|
|
|
|
String(writableType)
|
|
|
|
}"`,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
const writableSizeAlgorithm = makeSizeAlgorithmFromSizeFunction(
|
2020-07-14 15:24:17 -04:00
|
|
|
writableSizeFunction,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
if (writableHighWaterMark === undefined) {
|
|
|
|
writableHighWaterMark = 1;
|
|
|
|
}
|
|
|
|
writableHighWaterMark = validateAndNormalizeHighWaterMark(
|
2020-07-14 15:24:17 -04:00
|
|
|
writableHighWaterMark,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
const readableType = transformer.readableType;
|
|
|
|
if (readableType !== undefined) {
|
|
|
|
throw new RangeError(
|
2020-07-14 15:24:17 -04:00
|
|
|
`Expected transformer readableType to be undefined, received "${
|
|
|
|
String(readableType)
|
|
|
|
}"`,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
const readableSizeAlgorithm = makeSizeAlgorithmFromSizeFunction(
|
2020-07-14 15:24:17 -04:00
|
|
|
readableSizeFunction,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
if (readableHighWaterMark === undefined) {
|
|
|
|
readableHighWaterMark = 1;
|
|
|
|
}
|
|
|
|
readableHighWaterMark = validateAndNormalizeHighWaterMark(
|
2020-07-14 15:24:17 -04:00
|
|
|
readableHighWaterMark,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
const startPromise = getDeferred<void>();
|
|
|
|
initializeTransformStream(
|
|
|
|
this,
|
|
|
|
startPromise.promise,
|
|
|
|
writableHighWaterMark,
|
|
|
|
writableSizeAlgorithm,
|
|
|
|
readableHighWaterMark,
|
2020-07-14 15:24:17 -04:00
|
|
|
readableSizeAlgorithm,
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
// the brand check expects this, and the brand check occurs in the following
|
|
|
|
// but the property hasn't been defined.
|
|
|
|
Object.defineProperty(this, sym.transformStreamController, {
|
|
|
|
value: undefined,
|
|
|
|
writable: true,
|
|
|
|
configurable: true,
|
|
|
|
});
|
|
|
|
setUpTransformStreamDefaultControllerFromTransformer(this, transformer);
|
|
|
|
const startResult: void | PromiseLike<void> = invokeOrNoop(
|
|
|
|
transformer,
|
|
|
|
"start",
|
2020-07-14 15:24:17 -04:00
|
|
|
this[sym.transformStreamController],
|
2020-05-03 15:10:52 -04:00
|
|
|
);
|
|
|
|
startPromise.resolve(startResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
get readable(): ReadableStream<O> {
|
|
|
|
if (!isTransformStream(this)) {
|
|
|
|
throw new TypeError("Invalid TransformStream.");
|
|
|
|
}
|
|
|
|
return this[sym.readable];
|
|
|
|
}
|
|
|
|
|
|
|
|
get writable(): WritableStream<I> {
|
|
|
|
if (!isTransformStream(this)) {
|
|
|
|
throw new TypeError("Invalid TransformStream.");
|
|
|
|
}
|
|
|
|
return this[sym.writable];
|
|
|
|
}
|
|
|
|
|
|
|
|
[customInspect](): string {
|
2020-07-14 15:24:17 -04:00
|
|
|
return `${this.constructor.name} {\n readable: ${
|
|
|
|
inspect(this.readable)
|
|
|
|
}\n writable: ${inspect(this.writable)}\n}`;
|
2020-05-03 15:10:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setFunctionName(TransformStreamImpl, "TransformStream");
|