// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
import { call, createCallableFunction } from "./function.js";
-import {
- floor,
- isIntegralNumber,
- isNan,
- max,
- MAXIMUM_SAFE_INTEGRAL_NUMBER,
- min,
-} from "./numeric.js";
-import { sameValue, type } from "./value.js";
+import { isConcatSpreadableObject } from "./object.js";
+import { toIndex, type } from "./value.js";
const { prototype: arrayPrototype } = Array;
from: toArray,
} = Array;
-/**
- * Returns −0 if the provided argument is "-0"; returns a number
- * representing the index if the provided argument is a canonical
- * numeric index string; otherwise, returns undefined.
- *
- * There is no clamping of the numeric index, but note that numbers
- * above 2^53 − 1 are not safe nor valid integer indices.
- */
-export const canonicalNumericIndexString = ($) => {
- if (typeof $ !== "string") {
- return undefined;
- } else if ($ === "-0") {
- return -0;
- } else {
- const n = +$;
- return $ === `${n}` ? n : undefined;
- }
-};
-
/**
* Returns the result of catenating the provided arraylikes into a new
* collection according to the algorithm of `Array::concat`.
"indices",
);
-/** Returns whether the provided value is an array index string. */
-export const isArrayIndexString = ($) => {
- const value = canonicalNumericIndexString($);
- if (value !== undefined) {
- // The provided value is a canonical numeric index string.
- return sameValue(value, 0) || value > 0 && value < -1 >>> 0 &&
- value === toLength(value);
- } else {
- // The provided value is not a canonical numeric index string.
- return false;
- }
-};
-
-/** Returns whether the provided value is arraylike. */
-export const isArraylikeObject = ($) => {
- if (type($) !== "object") {
- return false;
- } else {
- try {
- lengthOfArraylike($); // throws if not arraylike
- return true;
- } catch {
- return false;
- }
- }
-};
-
/**
* Returns whether the provided object is a collection.
*
} else {
try {
toIndex($.length); // will throw if `length` is not an index
- return isConcatSpreadable($);
+ return isConcatSpreadableObject($);
} catch {
return false;
}
}
};
-/**
- * Returns whether the provided value is spreadable during array
- * concatenation.
- *
- * This is also used to determine which things should be treated as
- * collections.
- */
-export const isConcatSpreadable = ($) => {
- if (type($) !== "object") {
- // The provided value is not an object.
- return false;
- } else {
- // The provided value is an object.
- const spreadable = $[Symbol.isConcatSpreadable];
- return spreadable !== undefined ? !!spreadable : isArray($);
- }
-};
-
-/** Returns whether the provided value is an integer index string. */
-export const isIntegerIndexString = ($) => {
- const value = canonicalNumericIndexString($);
- if (value !== undefined && isIntegralNumber(value)) {
- // The provided value is a canonical numeric index string.
- return sameValue(value, 0) ||
- value > 0 && value <= MAXIMUM_SAFE_INTEGRAL_NUMBER &&
- value === toLength(value);
- } else {
- // The provided value is not a canonical numeric index string.
- return false;
- }
-};
-
/**
* Returns an iterator over the items in the provided value according
* to the algorithm of `Array::values`.
"items",
);
-/**
- * Returns the length of the provided arraylike object.
- *
- * Will throw if the provided object is not arraylike.
- *
- * This can produce larger lengths than can actually be stored in
- * arrays, because no such restrictions exist on arraylike methods.
- */
-export const lengthOfArraylike = ({ length }) => toLength(length);
-
/**
* Returns the result of mapping the provided value with the provided
* callback according to the algorithm of `Array::map`.
*/
export const splice = createCallableFunction(arrayPrototype.splice);
-/**
- * Returns the result of converting the provided value to an array
- * index, or throws an error if it is out of range.
- */
-export const toIndex = ($) => {
- const integer = floor($);
- if (isNan(integer) || integer == 0) {
- // The value is zero·like.
- return 0;
- } else {
- // The value is not zero·like.
- const clamped = toLength(integer);
- if (clamped !== integer) {
- // Clamping the value changes it.
- throw new RangeError(`Piscēs: Index out of range: ${$}.`);
- } else {
- // The value is within appropriate bounds.
- return integer;
- }
- }
-};
-
-/** Returns the result of converting the provided value to a length. */
-export const toLength = ($) => {
- const len = floor($);
- return isNan(len) || len == 0
- ? 0
- : max(min(len, MAXIMUM_SAFE_INTEGRAL_NUMBER), 0);
-};
-
/**
* Unshifts the provided value according to the algorithm of
* `Array::unshift`.