mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 23:59:59 -05:00
fix: make WHATWG streams more compliant (#10967)
This commit is contained in:
parent
1eac527adb
commit
4cbc4a7eb3
6 changed files with 868 additions and 437 deletions
File diff suppressed because it is too large
Load diff
6
extensions/web/06_streams_types.d.ts
vendored
6
extensions/web/06_streams_types.d.ts
vendored
|
@ -40,6 +40,12 @@ interface VoidFunction {
|
|||
(): void;
|
||||
}
|
||||
|
||||
interface ReadableStreamGenericReader<T> {
|
||||
readonly closed: Promise<void>;
|
||||
// deno-lint-ignore no-explicit-any
|
||||
cancel(reason?: any): Promise<void>;
|
||||
}
|
||||
|
||||
// ** Ambient Definitions and Interfaces not provided by fetch **
|
||||
|
||||
declare function queueMicrotask(callback: VoidFunction): void;
|
||||
|
|
|
@ -566,6 +566,7 @@
|
|||
converters["sequence<double>"] = createSequenceConverter(
|
||||
converters["double"],
|
||||
);
|
||||
converters["Promise<undefined>"] = createPromiseConverter(() => undefined);
|
||||
|
||||
function requiredArguments(length, required, opts = {}) {
|
||||
if (length < required) {
|
||||
|
@ -578,11 +579,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function isEmptyObject(V) {
|
||||
for (const _ in V) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function createDictionaryConverter(name, ...dictionaries) {
|
||||
let hasRequiredKey = false;
|
||||
const allMembers = [];
|
||||
|
@ -642,10 +638,8 @@
|
|||
|
||||
const idlDict = { ...defaultValues };
|
||||
|
||||
// NOTE: fast path Null and Undefined and empty objects.
|
||||
if (
|
||||
(V === undefined || V === null || isEmptyObject(V)) && !hasRequiredKey
|
||||
) {
|
||||
// NOTE: fast path Null and Undefined.
|
||||
if ((V === undefined || V === null) && !hasRequiredKey) {
|
||||
return idlDict;
|
||||
}
|
||||
|
||||
|
@ -774,6 +768,31 @@
|
|||
};
|
||||
}
|
||||
|
||||
function createPromiseConverter(converter) {
|
||||
return (V, opts) => Promise.resolve(V).then((V) => converter(V, opts));
|
||||
}
|
||||
|
||||
function invokeCallbackFunction(
|
||||
callable,
|
||||
args,
|
||||
thisArg,
|
||||
returnValueConverter,
|
||||
opts,
|
||||
) {
|
||||
try {
|
||||
const rv = Reflect.apply(callable, thisArg, args);
|
||||
return returnValueConverter(rv, {
|
||||
prefix: opts.prefix,
|
||||
context: "return value",
|
||||
});
|
||||
} catch (err) {
|
||||
if (opts.returnsPromise === true) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const brand = Symbol("[[webidl.brand]]");
|
||||
|
||||
function createInterfaceConverter(name, prototype) {
|
||||
|
@ -927,6 +946,8 @@
|
|||
createNullableConverter,
|
||||
createSequenceConverter,
|
||||
createRecordConverter,
|
||||
createPromiseConverter,
|
||||
invokeCallbackFunction,
|
||||
createInterfaceConverter,
|
||||
brand,
|
||||
createBranded,
|
||||
|
|
18
extensions/webidl/internal.d.ts
vendored
18
extensions/webidl/internal.d.ts
vendored
|
@ -248,6 +248,24 @@ declare namespace globalThis {
|
|||
converter: (v: any, opts: ValueConverterOpts) => T,
|
||||
): (v: any, opts: ValueConverterOpts) => T[];
|
||||
|
||||
/**
|
||||
* Create a converter that converts a Promise of the inner type.
|
||||
*/
|
||||
declare function createPromiseConverter<T>(
|
||||
converter: (v: any, opts: ValueConverterOpts) => T,
|
||||
): (v: any, opts: ValueConverterOpts) => Promise<T>;
|
||||
|
||||
/**
|
||||
* Invoke a callback function.
|
||||
*/
|
||||
declare function invokeCallbackFunction<T>(
|
||||
callable: (...args: any) => any,
|
||||
args: any[],
|
||||
thisArg: any,
|
||||
returnValueConverter: (v: any, opts: ValueConverterOpts) => T,
|
||||
opts: ConverterOpts & { returnsPromise?: boolean },
|
||||
): T;
|
||||
|
||||
/**
|
||||
* Throw an illegal constructor error.
|
||||
*/
|
||||
|
|
|
@ -304,9 +304,15 @@ delete Object.prototype.__proto__;
|
|||
WritableStreamDefaultWriter: util.nonEnumerable(
|
||||
streams.WritableStreamDefaultWriter,
|
||||
),
|
||||
WritableStreamDefaultController: util.nonEnumerable(
|
||||
streams.WritableStreamDefaultController,
|
||||
),
|
||||
ReadableByteStreamController: util.nonEnumerable(
|
||||
streams.ReadableByteStreamController,
|
||||
),
|
||||
ReadableStreamDefaultController: util.nonEnumerable(
|
||||
streams.ReadableStreamDefaultController,
|
||||
),
|
||||
TransformStreamDefaultController: util.nonEnumerable(
|
||||
streams.TransformStreamDefaultController,
|
||||
),
|
||||
|
|
|
@ -256,23 +256,6 @@
|
|||
},
|
||||
"streams": {
|
||||
"idlharness.any.html": [
|
||||
"ReadableStream interface object length",
|
||||
"ReadableStream interface: attribute locked",
|
||||
"ReadableStream interface: operation cancel(optional any)",
|
||||
"ReadableStream interface: operation getReader(optional ReadableStreamGetReaderOptions)",
|
||||
"ReadableStream interface: operation pipeThrough(ReadableWritablePair, optional StreamPipeOptions)",
|
||||
"ReadableStream interface: operation pipeTo(WritableStream, optional StreamPipeOptions)",
|
||||
"ReadableStream interface: operation tee()",
|
||||
"ReadableStream interface: async iterable<any>",
|
||||
"Stringification of new ReadableStream()",
|
||||
"ReadableStream interface: calling pipeTo(WritableStream, optional StreamPipeOptions) on new ReadableStream() with too few arguments must throw TypeError",
|
||||
"ReadableStreamDefaultReader interface: existence and properties of interface object",
|
||||
"ReadableStreamDefaultReader interface: existence and properties of interface prototype object",
|
||||
"ReadableStreamDefaultReader interface: operation read()",
|
||||
"ReadableStreamDefaultReader interface: operation releaseLock()",
|
||||
"ReadableStreamDefaultReader interface: attribute closed",
|
||||
"ReadableStreamDefaultReader interface: operation cancel(optional any)",
|
||||
"Stringification of (new ReadableStream()).getReader()",
|
||||
"ReadableStreamBYOBReader interface: existence and properties of interface object",
|
||||
"ReadableStreamBYOBReader interface object length",
|
||||
"ReadableStreamBYOBReader interface object name",
|
||||
|
@ -291,25 +274,6 @@
|
|||
"ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property \"closed\" with the proper type",
|
||||
"ReadableStreamBYOBReader interface: (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) must inherit property \"cancel(optional any)\" with the proper type",
|
||||
"ReadableStreamBYOBReader interface: calling cancel(optional any) on (new ReadableStream({ type: 'bytes' })).getReader({ mode: 'byob' }) with too few arguments must throw TypeError",
|
||||
"ReadableStreamDefaultController interface: existence and properties of interface object",
|
||||
"ReadableStreamDefaultController interface object length",
|
||||
"ReadableStreamDefaultController interface object name",
|
||||
"ReadableStreamDefaultController interface: existence and properties of interface prototype object",
|
||||
"ReadableStreamDefaultController interface: existence and properties of interface prototype object's \"constructor\" property",
|
||||
"ReadableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property",
|
||||
"ReadableStreamDefaultController interface: attribute desiredSize",
|
||||
"ReadableStreamDefaultController interface: operation close()",
|
||||
"ReadableStreamDefaultController interface: operation enqueue(optional any)",
|
||||
"ReadableStreamDefaultController interface: operation error(optional any)",
|
||||
"ReadableStreamDefaultController must be primary interface of self.readableStreamDefaultController",
|
||||
"Stringification of self.readableStreamDefaultController",
|
||||
"ReadableByteStreamController interface: existence and properties of interface object",
|
||||
"ReadableByteStreamController interface: attribute byobRequest",
|
||||
"ReadableByteStreamController interface: attribute desiredSize",
|
||||
"ReadableByteStreamController interface: operation close()",
|
||||
"ReadableByteStreamController interface: operation enqueue(ArrayBufferView)",
|
||||
"ReadableByteStreamController interface: operation error(optional any)",
|
||||
"Stringification of self.readableByteStreamController",
|
||||
"ReadableByteStreamController interface: self.readableByteStreamController must inherit property \"byobRequest\" with the proper type",
|
||||
"ReadableStreamBYOBRequest interface: existence and properties of interface object",
|
||||
"ReadableStreamBYOBRequest interface object length",
|
||||
|
@ -326,109 +290,20 @@
|
|||
"ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property \"respond(unsigned long long)\" with the proper type",
|
||||
"ReadableStreamBYOBRequest interface: calling respond(unsigned long long) on self.readableStreamByobRequest with too few arguments must throw TypeError",
|
||||
"ReadableStreamBYOBRequest interface: self.readableStreamByobRequest must inherit property \"respondWithNewView(ArrayBufferView)\" with the proper type",
|
||||
"ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError",
|
||||
"WritableStream interface: attribute locked",
|
||||
"WritableStream interface: operation abort(optional any)",
|
||||
"WritableStream interface: operation close()",
|
||||
"WritableStream interface: operation getWriter()",
|
||||
"Stringification of new WritableStream()",
|
||||
"WritableStreamDefaultWriter interface: attribute closed",
|
||||
"WritableStreamDefaultWriter interface: attribute desiredSize",
|
||||
"WritableStreamDefaultWriter interface: attribute ready",
|
||||
"WritableStreamDefaultWriter interface: operation abort(optional any)",
|
||||
"WritableStreamDefaultWriter interface: operation close()",
|
||||
"WritableStreamDefaultWriter interface: operation releaseLock()",
|
||||
"WritableStreamDefaultWriter interface: operation write(optional any)",
|
||||
"Stringification of (new WritableStream()).getWriter()",
|
||||
"WritableStreamDefaultController interface: existence and properties of interface object",
|
||||
"WritableStreamDefaultController interface object length",
|
||||
"WritableStreamDefaultController interface object name",
|
||||
"WritableStreamDefaultController interface: existence and properties of interface prototype object",
|
||||
"WritableStreamDefaultController interface: existence and properties of interface prototype object's \"constructor\" property",
|
||||
"WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property",
|
||||
"WritableStreamDefaultController interface: operation error(optional any)",
|
||||
"WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController",
|
||||
"Stringification of self.writableStreamDefaultController",
|
||||
"TransformStream interface: attribute readable",
|
||||
"TransformStream interface: attribute writable",
|
||||
"Stringification of new TransformStream()",
|
||||
"TransformStreamDefaultController interface: existence and properties of interface object",
|
||||
"TransformStreamDefaultController interface: attribute desiredSize",
|
||||
"TransformStreamDefaultController interface: operation enqueue(optional any)",
|
||||
"TransformStreamDefaultController interface: operation error(optional any)",
|
||||
"TransformStreamDefaultController interface: operation terminate()",
|
||||
"Stringification of self.transformStreamDefaultController",
|
||||
"ByteLengthQueuingStrategy interface: attribute highWaterMark",
|
||||
"ByteLengthQueuingStrategy interface: attribute size",
|
||||
"Stringification of new ByteLengthQueuingStrategy({ highWaterMark: 5 })",
|
||||
"ByteLengthQueuingStrategy interface: new ByteLengthQueuingStrategy({ highWaterMark: 5 }) must inherit property \"highWaterMark\" with the proper type",
|
||||
"CountQueuingStrategy interface: attribute highWaterMark",
|
||||
"CountQueuingStrategy interface: attribute size",
|
||||
"Stringification of new CountQueuingStrategy({ highWaterMark: 5 })",
|
||||
"CountQueuingStrategy interface: new CountQueuingStrategy({ highWaterMark: 5 }) must inherit property \"highWaterMark\" with the proper type"
|
||||
"ReadableStreamBYOBRequest interface: calling respondWithNewView(ArrayBufferView) on self.readableStreamByobRequest with too few arguments must throw TypeError"
|
||||
],
|
||||
"piping": {
|
||||
"abort.any.html": [
|
||||
"a signal argument 'null' should cause pipeTo() to reject",
|
||||
"a signal argument 'AbortSignal' should cause pipeTo() to reject",
|
||||
"a signal argument 'true' should cause pipeTo() to reject",
|
||||
"a signal argument '-1' should cause pipeTo() to reject",
|
||||
"a signal argument '[object AbortSignal]' should cause pipeTo() to reject"
|
||||
],
|
||||
"close-propagation-backward.any.html": [
|
||||
"Closing must be propagated backward: starts closed; preventCancel = null (falsy); fulfilled cancel promise",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = 0 (falsy); fulfilled cancel promise",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = -0 (falsy); fulfilled cancel promise",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = NaN (falsy); fulfilled cancel promise",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = (falsy); fulfilled cancel promise",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = a (truthy)",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = 1 (truthy)",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = Symbol() (truthy)",
|
||||
"Closing must be propagated backward: starts closed; preventCancel = [object Object] (truthy)"
|
||||
],
|
||||
"close-propagation-forward.any.html": [
|
||||
"Closing must be propagated forward: starts closed; preventClose = null (falsy); fulfilled close promise",
|
||||
"Closing must be propagated forward: starts closed; preventClose = 0 (falsy); fulfilled close promise",
|
||||
"Closing must be propagated forward: starts closed; preventClose = -0 (falsy); fulfilled close promise",
|
||||
"Closing must be propagated forward: starts closed; preventClose = NaN (falsy); fulfilled close promise",
|
||||
"Closing must be propagated forward: starts closed; preventClose = (falsy); fulfilled close promise",
|
||||
"Closing must be propagated forward: starts closed; preventClose = a (truthy)",
|
||||
"Closing must be propagated forward: starts closed; preventClose = 1 (truthy)",
|
||||
"Closing must be propagated forward: starts closed; preventClose = Symbol() (truthy)",
|
||||
"Closing must be propagated forward: starts closed; preventClose = [object Object] (truthy)"
|
||||
],
|
||||
"error-propagation-backward.any.html": [
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = null (falsy); fulfilled cancel promise",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 0 (falsy); fulfilled cancel promise",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = -0 (falsy); fulfilled cancel promise",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = NaN (falsy); fulfilled cancel promise",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = (falsy); fulfilled cancel promise",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = a (truthy)",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = 1 (truthy)",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = Symbol() (truthy)",
|
||||
"Errors must be propagated backward: becomes errored before piping due to write; preventCancel = [object Object] (truthy)"
|
||||
],
|
||||
"error-propagation-forward.any.html": [
|
||||
"Errors must be propagated forward: starts errored; preventAbort = null (falsy); fulfilled abort promise",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = 0 (falsy); fulfilled abort promise",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = -0 (falsy); fulfilled abort promise",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = NaN (falsy); fulfilled abort promise",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = (falsy); fulfilled abort promise",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = a (truthy)",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = 1 (truthy)",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = Symbol() (truthy)",
|
||||
"Errors must be propagated forward: starts errored; preventAbort = [object Object] (truthy)"
|
||||
],
|
||||
"abort.any.html": true,
|
||||
"close-propagation-backward.any.html": true,
|
||||
"close-propagation-forward.any.html": true,
|
||||
"error-propagation-backward.any.html": true,
|
||||
"error-propagation-forward.any.html": true,
|
||||
"flow-control.any.html": true,
|
||||
"general.any.html": [
|
||||
"pipeTo must check the brand of its ReadableStream this value",
|
||||
"pipeTo must check the brand of its WritableStream argument",
|
||||
"pipeTo() promise should resolve if null is passed"
|
||||
],
|
||||
"general.any.html": true,
|
||||
"multiple-propagation.any.html": true,
|
||||
"pipe-through.any.html": true,
|
||||
"then-interception.any.html": true,
|
||||
"throwing-options.any.html": false,
|
||||
"throwing-options.any.html": true,
|
||||
"transform-streams.any.html": true
|
||||
},
|
||||
"queuing-strategies.any.html": true,
|
||||
|
@ -515,32 +390,20 @@
|
|||
"ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view (in the readable state)",
|
||||
"ReadableStream with byte source: respondWithNewView() with a transferred zero-length view (in the closed state)"
|
||||
],
|
||||
"non-transferable-buffers.any.html": false
|
||||
"non-transferable-buffers.any.html": false,
|
||||
"enqueue-with-detached-buffer.window.html": false
|
||||
},
|
||||
"readable-streams": {
|
||||
"async-iterator.any.html": [
|
||||
"Async iterator instances should have the correct list of properties",
|
||||
"values() throws if there's already a lock",
|
||||
"return() should unlock the stream synchronously when preventCancel = false",
|
||||
"return() should unlock the stream synchronously when preventCancel = true",
|
||||
"Async-iterating a pull source manually",
|
||||
"Cancellation behavior when throwing inside loop body; preventCancel = false",
|
||||
"Cancellation behavior when throwing inside loop body; preventCancel = true",
|
||||
"Cancellation behavior when breaking inside loop body; preventCancel = false",
|
||||
"Cancellation behavior when breaking inside loop body; preventCancel = true",
|
||||
"Cancellation behavior when returning inside loop body; preventCancel = false",
|
||||
"Cancellation behavior when returning inside loop body; preventCancel = true",
|
||||
"Cancellation behavior when manually calling return(); preventCancel = false",
|
||||
"Cancellation behavior when manually calling return(); preventCancel = true",
|
||||
"next() rejects if the stream errors",
|
||||
"return() does not rejects if the stream has not errored yet",
|
||||
"return() rejects if the stream has errored",
|
||||
"next() that succeeds; next() that reports an error; next()"
|
||||
],
|
||||
"bad-strategies.any.html": true,
|
||||
"bad-underlying-sources.any.html": true,
|
||||
"cancel.any.html": false,
|
||||
"constructor.any.html": false,
|
||||
"constructor.any.html": true,
|
||||
"count-queuing-strategy-integration.any.html": true,
|
||||
"default-reader.any.html": true,
|
||||
"floating-point-total-queue-size.any.html": true,
|
||||
|
@ -573,19 +436,11 @@
|
|||
},
|
||||
"writable-streams": {
|
||||
"aborting.any.html": false,
|
||||
"bad-strategies.any.html": [
|
||||
"reject any non-function value for strategy.size",
|
||||
"Writable stream: invalid size beats invalid highWaterMark"
|
||||
],
|
||||
"bad-strategies.any.html": true,
|
||||
"bad-underlying-sinks.any.html": true,
|
||||
"byte-length-queuing-strategy.any.html": true,
|
||||
"close.any.html": false,
|
||||
"constructor.any.html": [
|
||||
"underlyingSink argument should be converted after queuingStrategy argument",
|
||||
"WritableStreamDefaultController constructor should throw",
|
||||
"WritableStreamDefaultController constructor should throw when passed an initialised WritableStream",
|
||||
"WritableStreamDefaultWriter should throw unless passed a WritableStream"
|
||||
],
|
||||
"constructor.any.html": true,
|
||||
"count-queuing-strategy.any.html": true,
|
||||
"error.any.html": true,
|
||||
"floating-point-total-queue-size.any.html": true,
|
||||
|
@ -594,6 +449,10 @@
|
|||
"reentrant-strategy.any.html": true,
|
||||
"start.any.html": true,
|
||||
"write.any.html": true
|
||||
},
|
||||
"queuing-strategies-size-function-per-global.window.html": false,
|
||||
"transferable": {
|
||||
"deserialize-error.window.html": false
|
||||
}
|
||||
},
|
||||
"user-timing": {
|
||||
|
@ -951,6 +810,7 @@
|
|||
"stream-safe-creation.any.html": [
|
||||
"throwing Object.prototype.start accessor should not affect stream creation by 'fetch'",
|
||||
"Object.prototype.start accessor returning invalid value should not affect stream creation by 'fetch'",
|
||||
"throwing Object.prototype.type accessor should not affect stream creation by 'fetch'",
|
||||
"throwing Object.prototype.size accessor should not affect stream creation by 'fetch'",
|
||||
"Object.prototype.size accessor returning invalid value should not affect stream creation by 'fetch'",
|
||||
"throwing Object.prototype.highWaterMark accessor should not affect stream creation by 'fetch'",
|
||||
|
|
Loading…
Reference in a new issue