nstdlib-nightly
Version:
Node.js standard library converted to runtime-agnostic ES modules.
317 lines (274 loc) • 8.61 kB
JavaScript
// Source: https://github.com/nodejs/node/blob/65eff1eb/lib/internal/webstreams/util.js
import { codes as __codes__ } from "nstdlib/lib/internal/errors";
import {
copyArrayBuffer,
detachArrayBuffer,
} from "nstdlib/stub/binding/buffer";
import { inspect } from "nstdlib/lib/util";
import {
constants as __constants__,
getPromiseDetails,
} from "nstdlib/stub/binding/util";
import * as assert from "nstdlib/lib/internal/assert";
import { isArrayBufferDetached } from "nstdlib/lib/internal/util";
import { validateFunction } from "nstdlib/lib/internal/validators";
import * as __hoisted_internal_webstreams_transfer__ from "nstdlib/lib/internal/webstreams/transfer";
const {
ERR_ARG_NOT_ITERABLE,
ERR_INVALID_ARG_VALUE,
ERR_INVALID_STATE,
ERR_OPERATION_FAILED,
} = __codes__;
const { kPending } = __constants__;
const kState = Symbol("kState");
const kType = Symbol("kType");
const AsyncIterator = {
__proto__: AsyncIteratorPrototype,
next: undefined,
return: undefined,
};
function extractHighWaterMark(value, defaultHWM) {
if (value === undefined) return defaultHWM;
value = +value;
if (typeof value !== "number" || Number.isNaN(value) || value < 0)
throw new ERR_INVALID_ARG_VALUE.RangeError("strategy.highWaterMark", value);
return value;
}
function extractSizeAlgorithm(size) {
if (size === undefined) return () => 1;
validateFunction(size, "strategy.size");
return size;
}
function customInspect(depth, options, name, data) {
if (depth < 0) return this;
const opts = {
...options,
depth: options.depth == null ? null : options.depth - 1,
};
return `${name} ${inspect(data, opts)}`;
}
// These are defensive to work around the possibility that
// the buffer, byteLength, and byteOffset properties on
// ArrayBuffer and ArrayBufferView's may have been tampered with.
function ArrayBufferViewGetBuffer(view) {
return ReflectGet(view.constructor.prototype, "buffer", view);
}
function ArrayBufferViewGetByteLength(view) {
return ReflectGet(view.constructor.prototype, "byteLength", view);
}
function ArrayBufferViewGetByteOffset(view) {
return ReflectGet(view.constructor.prototype, "byteOffset", view);
}
function cloneAsUint8Array(view) {
const buffer = Object.getOwnPropertyDescriptor(
ArrayBufferView.prototype,
"buffer",
).get(view);
const byteOffset = Object.getOwnPropertyDescriptor(
ArrayBufferView.prototype,
"byteOffset",
).get(view);
const byteLength = Object.getOwnPropertyDescriptor(
ArrayBufferView.prototype,
"byteLength",
).get(view);
return new Uint8Array(
ArrayBuffer.prototype.slice.call(
buffer,
byteOffset,
byteOffset + byteLength,
),
);
}
function isBrandCheck(brand) {
return (value) => {
return (
value != null && value[kState] !== undefined && value[kType] === brand
);
};
}
function transferArrayBuffer(buffer) {
const res = detachArrayBuffer(buffer);
if (res === undefined) {
throw new ERR_OPERATION_FAILED.TypeError(
"The ArrayBuffer could not be transferred",
);
}
return res;
}
function isViewedArrayBufferDetached(view) {
return (
Object.getOwnPropertyDescriptor(
ArrayBufferView.prototype,
"byteLength",
).get(view) === 0 &&
isArrayBufferDetached(
Object.getOwnPropertyDescriptor(ArrayBufferView.prototype, "buffer").get(
view,
),
)
);
}
function dequeueValue(controller) {
assert(controller[kState].queue !== undefined);
assert(controller[kState].queueTotalSize !== undefined);
assert(controller[kState].queue.length);
const { value, size } = Array.prototype.shift.call(controller[kState].queue);
controller[kState].queueTotalSize = Math.max(
0,
controller[kState].queueTotalSize - size,
);
return value;
}
function resetQueue(controller) {
assert(controller[kState].queue !== undefined);
assert(controller[kState].queueTotalSize !== undefined);
controller[kState].queue = [];
controller[kState].queueTotalSize = 0;
}
function peekQueueValue(controller) {
assert(controller[kState].queue !== undefined);
assert(controller[kState].queueTotalSize !== undefined);
assert(controller[kState].queue.length);
return controller[kState].queue[0].value;
}
function enqueueValueWithSize(controller, value, size) {
assert(controller[kState].queue !== undefined);
assert(controller[kState].queueTotalSize !== undefined);
size = +size;
if (
typeof size !== "number" ||
size < 0 ||
Number.isNaN(size) ||
size === Infinity
) {
throw new ERR_INVALID_ARG_VALUE.RangeError("size", size);
}
Array.prototype.push.call(controller[kState].queue, { value, size });
controller[kState].queueTotalSize += size;
}
// This implements "invoke a callback function type" for callback functions that return a promise.
// See https://webidl.spec.whatwg.org/#es-invoking-callback-functions
async function invokePromiseCallback(fn, thisArg, ...args) {
return Function.prototype.call.call(fn, thisArg, ...args);
}
function createPromiseCallback(name, fn, thisArg) {
validateFunction(fn, name);
return (...args) => invokePromiseCallback(fn, thisArg, ...args);
}
function isPromisePending(promise) {
if (promise === undefined) return false;
const details = getPromiseDetails(promise);
return details?.[0] === kPending;
}
function setPromiseHandled(promise) {
// Alternatively, we could use the native API
// MarkAsHandled, but this avoids the extra boundary cross
// and is hopefully faster at the cost of an extra Promise
// allocation.
Promise.prototype.then.call(
promise,
() => {},
() => {},
);
}
async function nonOpFlush() {}
function nonOpStart() {}
async function nonOpPull() {}
async function nonOpCancel() {}
async function nonOpWrite() {}
let transfer;
function lazyTransfer() {
if (transfer === undefined)
transfer = __hoisted_internal_webstreams_transfer__;
return transfer;
}
function createAsyncFromSyncIterator(syncIteratorRecord) {
const syncIterable = {
[Symbol.iterator]: () => syncIteratorRecord.iterator,
};
const asyncIterator = (async function* () {
return yield* syncIterable;
})();
const nextMethod = asyncIterator.next;
return { iterator: asyncIterator, nextMethod, done: false };
}
function getIterator(obj, kind = "sync", method) {
if (method === undefined) {
if (kind === "async") {
method = obj[SymbolAsyncIterator];
if (method === undefined) {
const syncMethod = obj[Symbol.iterator];
if (syncMethod === undefined) {
throw new ERR_ARG_NOT_ITERABLE(obj);
}
const syncIteratorRecord = getIterator(obj, "sync", syncMethod);
return createAsyncFromSyncIterator(syncIteratorRecord);
}
} else {
method = obj[Symbol.iterator];
}
}
if (method === undefined) {
throw new ERR_ARG_NOT_ITERABLE(obj);
}
const iterator = Function.prototype.call.call(method, obj);
if (typeof iterator !== "object" || iterator === null) {
throw new ERR_INVALID_STATE.TypeError(
"The iterator method must return an object",
);
}
const nextMethod = iterator.next;
return { iterator, nextMethod, done: false };
}
function iteratorNext(iteratorRecord, value) {
let result;
if (value === undefined) {
result = Function.prototype.call.call(
iteratorRecord.nextMethod,
iteratorRecord.iterator,
);
} else {
result = Function.prototype.call.call(
iteratorRecord.nextMethod,
iteratorRecord.iterator,
[value],
);
}
if (typeof result !== "object" || result === null) {
throw new ERR_INVALID_STATE.TypeError(
"The iterator.next() method must return an object",
);
}
return result;
}
export { ArrayBufferViewGetBuffer };
export { ArrayBufferViewGetByteLength };
export { ArrayBufferViewGetByteOffset };
export { AsyncIterator };
export { createPromiseCallback };
export { cloneAsUint8Array };
export { copyArrayBuffer };
export { customInspect };
export { dequeueValue };
export { enqueueValueWithSize };
export { extractHighWaterMark };
export { extractSizeAlgorithm };
export { lazyTransfer };
export { invokePromiseCallback };
export { isBrandCheck };
export { isPromisePending };
export { isViewedArrayBufferDetached };
export { peekQueueValue };
export { resetQueue };
export { setPromiseHandled };
export { transferArrayBuffer };
export { nonOpCancel };
export { nonOpFlush };
export { nonOpPull };
export { nonOpStart };
export { nonOpWrite };
export { getIterator };
export { iteratorNext };
export { kType };
export { kState };