This commit is contained in:
ahaas25
2025-02-23 23:35:15 -05:00
commit 5b64ef9207
1796 changed files with 186622 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
'use strict';
var $TypeError = require('es-errors/type');
var callBound = require('call-bind/callBound');
var $push = callBound('Array.prototype.push');
var SameValue = require('./SameValue');
var IsArray = require('../helpers/IsArray');
var every = require('../helpers/every');
var forEach = require('../helpers/forEach');
var hasOwn = require('hasown');
var isKeyedGroup = function (group) {
return hasOwn(group, '[[Key]]')
&& hasOwn(group, '[[Elements]]')
&& IsArray(group['[[Elements]]']);
};
// https://262.ecma-international.org/15.0/#sec-add-value-to-keyed-group
module.exports = function AddValueToKeyedGroup(groups, key, value) {
if (!IsArray(groups) || (groups.length > 0 && !every(groups, isKeyedGroup))) {
throw new $TypeError('Assertion failed: `groups` must be a List of Records with [[Key]] and [[Elements]]');
}
var matched = 0;
forEach(groups, function (g) { // step 1
if (SameValue(g['[[Key]]'], key)) { // step 2
matched += 1;
if (matched > 1) {
throw new $TypeError('Assertion failed: Exactly one element of groups meets this criterion'); // step 2.a
}
$push(g['[[Elements]]'], value); // step 2.b
}
});
if (matched === 0) {
var group = { '[[Key]]': key, '[[Elements]]': [value] }; // step 2
$push(groups, group); // step 3
}
};
+38
View File
@@ -0,0 +1,38 @@
'use strict';
var $TypeError = require('es-errors/type');
// https://262.ecma-international.org/15.0/#sec-arraybufferbytelength
var IsDetachedBuffer = require('./IsDetachedBuffer');
var isArrayBuffer = require('is-array-buffer');
var isSharedArrayBuffer = require('is-shared-array-buffer');
var arrayBufferByteLength = require('array-buffer-byte-length');
var isGrowable = false; // TODO: support this
module.exports = function ArrayBufferByteLength(arrayBuffer, order) {
var isSAB = isSharedArrayBuffer(arrayBuffer);
if (!isArrayBuffer(arrayBuffer) && !isSAB) {
throw new $TypeError('Assertion failed: `arrayBuffer` must be an ArrayBuffer or a SharedArrayBuffer');
}
if (order !== 'SEQ-CST' && order !== 'UNORDERED') {
throw new $TypeError('Assertion failed: `order` must be ~SEQ-CST~ or ~UNORDERED~');
}
// 1. If IsSharedArrayBuffer(arrayBuffer) is true and arrayBuffer has an [[ArrayBufferByteLengthData]] internal slot, then
// TODO: see if IsFixedLengthArrayBuffer can be used here in the spec instead
if (isSAB && isGrowable) { // step 1
// a. Let bufferByteLengthBlock be arrayBuffer.[[ArrayBufferByteLengthData]].
// b. Let rawLength be GetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, BIGUINT64, true, order).
// c. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
// d. Return (RawBytesToNumeric(BIGUINT64, rawLength, isLittleEndian)).
}
if (IsDetachedBuffer(arrayBuffer)) {
throw new $TypeError('Assertion failed: `arrayBuffer` must not be detached'); // step 2
}
return arrayBufferByteLength(arrayBuffer);
};
+70
View File
@@ -0,0 +1,70 @@
'use strict';
var GetIntrinsic = require('get-intrinsic');
var $SyntaxError = require('es-errors/syntax');
var $TypeError = require('es-errors/type');
var $Promise = GetIntrinsic('%Promise%', true);
var Call = require('./Call');
var CompletionRecord = require('./CompletionRecord');
var GetMethod = require('./GetMethod');
var Type = require('./Type');
var isIteratorRecord = require('../helpers/records/iterator-record');
var callBound = require('call-bind/callBound');
var $then = callBound('Promise.prototype.then', true);
// https://262.ecma-international.org/15.0/#sec-asynciteratorclose
module.exports = function AsyncIteratorClose(iteratorRecord, completion) {
if (!isIteratorRecord(iteratorRecord)) {
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
}
if (!(completion instanceof CompletionRecord)) {
throw new $TypeError('Assertion failed: completion is not a Completion Record instance'); // step 2
}
if (!$then) {
throw new $SyntaxError('This environment does not support Promises.');
}
var iterator = iteratorRecord['[[Iterator]]']; // step 3
return $then(
$then(
$then(
new $Promise(function (resolve) {
resolve(GetMethod(iterator, 'return')); // step 4
// resolve(Call(ret, iterator, [])); // step 6
}),
function (returnV) { // step 5.a
if (typeof returnV === 'undefined') {
return completion; // step 5.b
}
return Call(returnV, iterator); // step 5.c, 5.d.
}
),
null,
function (e) {
if (completion.type() === 'throw') {
completion['?'](); // step 6
} else {
throw e; // step 7
}
}
),
function (innerResult) { // step 8
if (completion.type() === 'throw') {
completion['?'](); // step 6
}
if (Type(innerResult) !== 'Object') {
throw new $TypeError('`innerResult` must be an Object'); // step 10
}
return completion;
}
);
};
+137
View File
@@ -0,0 +1,137 @@
'use strict';
var GetIntrinsic = require('get-intrinsic');
var $SyntaxError = require('es-errors/syntax');
var $TypeError = require('es-errors/type');
var $Promise = GetIntrinsic('%Promise%', true);
var AsyncFromSyncIteratorContinuation = require('./AsyncFromSyncIteratorContinuation');
var Call = require('./Call');
var CreateIterResultObject = require('./CreateIterResultObject');
var Get = require('./Get');
var GetMethod = require('./GetMethod');
var IteratorNext = require('./IteratorNext');
var OrdinaryObjectCreate = require('./OrdinaryObjectCreate');
var Type = require('./Type');
var SLOT = require('internal-slot');
var isIteratorRecord = require('../helpers/records/iterator-record');
var $AsyncFromSyncIteratorPrototype = GetIntrinsic('%AsyncFromSyncIteratorPrototype%', true) || {
next: function next(value) {
if (!$Promise) {
throw new $SyntaxError('This environment does not support Promises.');
}
var O = this; // step 1
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
var argsLength = arguments.length;
return new $Promise(function (resolve) { // step 3
var syncIteratorRecord = SLOT.get(O, '[[SyncIteratorRecord]]'); // step 4
var result;
if (argsLength > 0) {
result = IteratorNext(syncIteratorRecord, value); // step 5.a
} else { // step 6
result = IteratorNext(syncIteratorRecord);// step 6.a
}
resolve(AsyncFromSyncIteratorContinuation(result)); // step 8
});
},
'return': function () {
if (!$Promise) {
throw new $SyntaxError('This environment does not support Promises.');
}
var O = this; // step 1
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
var valueIsPresent = arguments.length > 0;
var value = valueIsPresent ? arguments[0] : void undefined;
return new $Promise(function (resolve, reject) { // step 3
var syncIterator = SLOT.get(O, '[[SyncIteratorRecord]]')['[[Iterator]]']; // step 4
var iteratorReturn = GetMethod(syncIterator, 'return'); // step 5
if (typeof iteratorReturn === 'undefined') { // step 7
var iterResult = CreateIterResultObject(value, true); // step 7.a
Call(resolve, undefined, [iterResult]); // step 7.b
return;
}
var result;
if (valueIsPresent) { // step 8
result = Call(iteratorReturn, syncIterator, [value]); // step 8.a
} else { // step 9
result = Call(iteratorReturn, syncIterator); // step 9.a
}
if (Type(result) !== 'Object') { // step 11
Call(reject, undefined, [new $TypeError('Iterator `return` method returned a non-object value.')]); // step 11.a
return;
}
resolve(AsyncFromSyncIteratorContinuation(result)); // step 12
});
},
'throw': function () {
if (!$Promise) {
throw new $SyntaxError('This environment does not support Promises.');
}
var O = this; // step 1
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
var valueIsPresent = arguments.length > 0;
var value = valueIsPresent ? arguments[0] : void undefined;
return new $Promise(function (resolve, reject) { // step 3
var syncIterator = SLOT.get(O, '[[SyncIteratorRecord]]')['[[Iterator]]']; // step 4
var throwMethod = GetMethod(syncIterator, 'throw'); // step 5
if (typeof throwMethod === 'undefined') { // step 7
Call(reject, undefined, [value]); // step 7.a
return;
}
var result;
if (valueIsPresent) { // step 8
result = Call(throwMethod, syncIterator, [value]); // step 8.a
} else { // step 9
result = Call(throwMethod, syncIterator); // step 9.a
}
if (Type(result) !== 'Object') { // step 11
Call(reject, undefined, [new $TypeError('Iterator `throw` method returned a non-object value.')]); // step 11.a
return;
}
resolve(AsyncFromSyncIteratorContinuation(result/* , promiseCapability */)); // step 12
});
}
};
// https://262.ecma-international.org/15.0/#sec-createasyncfromsynciterator
module.exports = function CreateAsyncFromSyncIterator(syncIteratorRecord) {
if (!isIteratorRecord(syncIteratorRecord)) {
throw new $TypeError('Assertion failed: `syncIteratorRecord` must be an Iterator Record');
}
// var asyncIterator = OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »); // step 1
var asyncIterator = OrdinaryObjectCreate($AsyncFromSyncIteratorPrototype);
SLOT.set(asyncIterator, '[[SyncIteratorRecord]]', syncIteratorRecord); // step 2
var nextMethod = Get(asyncIterator, 'next'); // step 3
return { // steps 3-4
'[[Iterator]]': asyncIterator,
'[[NextMethod]]': nextMethod,
'[[Done]]': false
};
};
+21
View File
@@ -0,0 +1,21 @@
'use strict';
var Get = require('./Get');
var ToIndex = require('./ToIndex');
var Type = require('./Type');
// https://262.ecma-international.org/15.0/#sec-getarraybuffermaxbytelengthoption
module.exports = function GetArrayBufferMaxByteLengthOption(options) {
if (Type(options) !== 'Object') {
return 'EMPTY'; // step 1
}
var maxByteLength = Get(options, 'maxByteLength'); // step 2
if (typeof maxByteLength === 'undefined') {
return 'EMPTY'; // step 3
}
return ToIndex(maxByteLength); // step 4
};
+77
View File
@@ -0,0 +1,77 @@
'use strict';
var $TypeError = require('es-errors/type');
var AddValueToKeyedGroup = require('./AddValueToKeyedGroup');
var Call = require('./Call');
var GetIterator = require('./GetIterator');
var IsCallable = require('./IsCallable');
var IteratorClose = require('./IteratorClose');
var IteratorStep = require('./IteratorStep');
var IteratorValue = require('./IteratorValue');
var RequireObjectCoercible = require('./RequireObjectCoercible');
var ThrowCompletion = require('./ThrowCompletion');
var ToPropertyKey = require('./ToPropertyKey');
var isNegativeZero = require('../helpers/isNegativeZero');
var maxSafeInteger = require('../helpers/maxSafeInteger');
// https://262.ecma-international.org/15.0/#sec-groupby
module.exports = function GroupBy(items, callbackfn, keyCoercion) {
if (keyCoercion !== 'PROPERTY' && keyCoercion !== 'ZERO') {
throw new $TypeError('Assertion failed: `keyCoercion` must be `"PROPERTY"` or `"ZERO"`');
}
RequireObjectCoercible(items); // step 1
if (!IsCallable(callbackfn)) {
throw new $TypeError('callbackfn must be callable'); // step 2
}
var groups = []; // step 3
var iteratorRecord = GetIterator(items, 'SYNC'); // step 4
var k = 0; // step 5
// eslint-disable-next-line no-constant-condition
while (true) { // step 6
if (k >= maxSafeInteger) { // step 6.a
var error = ThrowCompletion(new $TypeError('k must be less than 2 ** 53 - 1')); // step 6.a.i
return IteratorClose(iteratorRecord, error); // step 6.a.ii
}
var next = IteratorStep(iteratorRecord); // step 6.b
if (!next) { // step 6.c
return groups; // step 6.c.i
}
var value = IteratorValue(next); // step 6.dv
var key;
try {
key = Call(callbackfn, undefined, [value, k]); // step 6.e
} catch (e) {
return IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.f
}
if (keyCoercion === 'PROPERTY') { // step 6.g
try {
key = ToPropertyKey(key); // step 6.g.i
} catch (e) {
return IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.g.ii
}
} else { // step 6.h
if (keyCoercion !== 'ZERO') {
throw new $TypeError('keyCoercion must be ~PROPERTY~ or ~ZERO~'); // step 6.h.i
}
if (isNegativeZero(key)) {
key = +0; // step 6.h.ii
}
}
AddValueToKeyedGroup(groups, key, value); // step 6.i
k += 1; // step 6.j
}
};
+54
View File
@@ -0,0 +1,54 @@
'use strict';
var $TypeError = require('es-errors/type');
var IsDetachedBuffer = require('./IsDetachedBuffer');
var TypedArrayElementSize = require('./TypedArrayElementSize');
var isTypedArrayWithBufferWitnessRecord = require('../helpers/records/typed-array-with-buffer-witness-record');
var typedArrayBuffer = require('typed-array-buffer');
var typedArrayByteOffset = require('typed-array-byte-offset');
var typedArrayLength = require('typed-array-length');
// https://262.ecma-international.org/15.0/#sec-istypedarrayoutofbounds
module.exports = function IsTypedArrayOutOfBounds(taRecord) {
if (!isTypedArrayWithBufferWitnessRecord(taRecord)) {
throw new $TypeError('Assertion failed: `taRecord` must be a TypedArray With Buffer Witness Record');
}
var O = taRecord['[[Object]]']; // step 1
var bufferByteLength = taRecord['[[CachedBufferByteLength]]']; // step 2
if (IsDetachedBuffer(typedArrayBuffer(O)) && bufferByteLength !== 'DETACHED') {
throw new $TypeError('Assertion failed: typed array is detached only if the byte length is ~DETACHED~'); // step 3
}
if (bufferByteLength === 'DETACHED') {
return true; // step 4
}
var byteOffsetStart = typedArrayByteOffset(O); // step 5
var byteOffsetEnd;
var length = typedArrayLength(O);
// TODO: probably use package for array length
// seems to apply when TA is backed by a resizable/growable AB
if (length === 'AUTO') { // step 6
byteOffsetEnd = bufferByteLength; // step 6.a
} else {
var elementSize = TypedArrayElementSize(O); // step 7.a
byteOffsetEnd = byteOffsetStart + (length * elementSize); // step 7.b
}
if (byteOffsetStart > bufferByteLength || byteOffsetEnd > bufferByteLength) {
return true; // step 8
}
// 9. NOTE: 0-length TypedArrays are not considered out-of-bounds.
return false; // step 10
};
+62
View File
@@ -0,0 +1,62 @@
'use strict';
var $TypeError = require('es-errors/type');
var Call = require('./Call');
var CompletionRecord = require('./CompletionRecord');
var GetMethod = require('./GetMethod');
var IsCallable = require('./IsCallable');
var Type = require('./Type');
var isIteratorRecord = require('../helpers/records/iterator-record');
// https://262.ecma-international.org/15.0/#sec-iteratorclose
module.exports = function IteratorClose(iteratorRecord, completion) {
if (!isIteratorRecord(iteratorRecord)) {
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
}
if (Type(iteratorRecord['[[Iterator]]']) !== 'Object') {
throw new $TypeError('Assertion failed: iteratorRecord.[[Iterator]] must be an Object'); // step 1
}
if (!IsCallable(completion) && !(completion instanceof CompletionRecord)) { // step 2
throw new $TypeError('Assertion failed: completion is not a thunk representing a Completion Record, nor a Completion Record instance');
}
var completionThunk = completion instanceof CompletionRecord ? function () { return completion['?'](); } : completion;
var iterator = iteratorRecord['[[Iterator]]']; // step 3
var iteratorReturn;
try {
iteratorReturn = GetMethod(iterator, 'return'); // step 4
} catch (e) {
completionThunk(); // throws if `completion` is a throw completion // step 6
completionThunk = null; // ensure it's not called twice.
throw e; // step 7
}
if (typeof iteratorReturn === 'undefined') {
return completionThunk(); // step 5.a - 5.b
}
var innerResult;
try {
innerResult = Call(iteratorReturn, iterator, []);
} catch (e) {
// if we hit here, then "e" is the innerResult completion that needs re-throwing
completionThunk(); // throws if `completion` is a throw completion // step 6
completionThunk = null; // ensure it's not called twice.
// if not, then return the innerResult completion
throw e; // step 7
}
var completionRecord = completionThunk(); // if innerResult worked, then throw if the completion does
completionThunk = null; // ensure it's not called twice.
if (Type(innerResult) !== 'Object') {
throw new $TypeError('iterator .return must return an object');
}
return completionRecord;
};
+28
View File
@@ -0,0 +1,28 @@
'use strict';
var $TypeError = require('es-errors/type');
var Call = require('./Call');
var Type = require('./Type');
var isIteratorRecord = require('../helpers/records/iterator-record');
// https://262.ecma-international.org/15.0/#sec-iteratornext
module.exports = function IteratorNext(iteratorRecord) {
if (!isIteratorRecord(iteratorRecord)) {
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
}
var result;
if (arguments.length < 2) { // step 1
result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]']); // step 1.a
} else { // step 2
result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]'], [arguments[1]]); // step 2.a
}
if (Type(result) !== 'Object') {
throw new $TypeError('iterator next must return an object'); // step 3
}
return result; // step 4
};
+21
View File
@@ -0,0 +1,21 @@
'use strict';
var $TypeError = require('es-errors/type');
var IteratorComplete = require('./IteratorComplete');
var IteratorNext = require('./IteratorNext');
var isIteratorRecord = require('../helpers/records/iterator-record');
// https://262.ecma-international.org/15.0/#sec-iteratorstep
module.exports = function IteratorStep(iteratorRecord) {
if (!isIteratorRecord(iteratorRecord)) {
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
}
var result = IteratorNext(iteratorRecord); // step 1
var done = IteratorComplete(result); // step 2
return done === true ? false : result; // steps 3-4
};
+31
View File
@@ -0,0 +1,31 @@
'use strict';
var $TypeError = require('es-errors/type');
var callBound = require('call-bind/callBound');
var $arrayPush = callBound('Array.prototype.push');
var IteratorStep = require('./IteratorStep');
var IteratorValue = require('./IteratorValue');
var isIteratorRecord = require('../helpers/records/iterator-record');
// https://262.ecma-international.org/15.0/#sec-iteratortolist
module.exports = function IteratorToList(iteratorRecord) {
if (!isIteratorRecord(iteratorRecord)) {
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
}
var values = []; // step 1
var next = true; // step 2
while (next) { // step 3
next = IteratorStep(iteratorRecord); // step 3.a
if (next) {
var nextValue = IteratorValue(next); // step 3.b.i
$arrayPush(values, nextValue); // step 3.b.ii
}
}
return values; // step 4
};
+26
View File
@@ -0,0 +1,26 @@
'use strict';
var $TypeError = require('es-errors/type');
var ArrayBufferByteLength = require('./ArrayBufferByteLength');
var IsDetachedBuffer = require('./IsDetachedBuffer');
var isTypedArray = require('is-typed-array');
var typedArrayBuffer = require('typed-array-buffer');
// https://262.ecma-international.org/15.0/#sec-maketypedarraywithbufferwitnessrecord
module.exports = function MakeTypedArrayWithBufferWitnessRecord(obj, order) {
if (!isTypedArray(obj)) {
throw new $TypeError('Assertion failed: `obj` must be a Typed Array');
}
if (order !== 'SEQ-CST' && order !== 'UNORDERED') {
throw new $TypeError('Assertion failed: `order` must be ~SEQ-CST~ or ~UNORDERED~');
}
var buffer = typedArrayBuffer(obj); // step 1
var byteLength = IsDetachedBuffer(buffer) ? 'DETACHED' : ArrayBufferByteLength(buffer, order); // steps 2 - 3
return { '[[Object]]': obj, '[[CachedBufferByteLength]]': byteLength }; // step 4
};
+39
View File
@@ -0,0 +1,39 @@
'use strict';
var $TypeError = require('es-errors/type');
var IsTypedArrayOutOfBounds = require('./IsTypedArrayOutOfBounds');
var TypedArrayElementSize = require('./TypedArrayElementSize');
var TypedArrayLength = require('./TypedArrayLength');
var isTypedArrayWithBufferWitnessRecord = require('../helpers/records/typed-array-with-buffer-witness-record');
var typedArrayByteLength = require('typed-array-byte-length');
// https://262.ecma-international.org/15.0/#sec-typedarraybytelength
module.exports = function TypedArrayByteLength(taRecord) {
if (!isTypedArrayWithBufferWitnessRecord(taRecord)) {
throw new $TypeError('Assertion failed: `taRecord` must be a TypedArray With Buffer Witness Record');
}
if (IsTypedArrayOutOfBounds(taRecord)) {
return 0; // step 1
}
var length = TypedArrayLength(taRecord); // step 2
if (length === 0) {
return 0; // step 3
}
var O = taRecord['[[Object]]']; // step 4
var byteLength = typedArrayByteLength(O);
if (byteLength !== 'AUTO') {
return byteLength; // step 5
}
var elementSize = TypedArrayElementSize(O); // step 6
return length * elementSize; // step 7
};