114 lines
3.8 KiB
Plaintext
114 lines
3.8 KiB
Plaintext
'use strict';
|
|
|
|
var forEach = require('for-each');
|
|
var availableTypedArrays = require('available-typed-arrays');
|
|
var callBind = require('call-bind');
|
|
var callBound = require('call-bind/callBound');
|
|
var gOPD = require('gopd');
|
|
|
|
var $toString = callBound('Object.prototype.toString');
|
|
var hasToStringTag = require('has-tostringtag/shams')();
|
|
|
|
var g = typeof globalThis === 'undefined' ? global : globalThis;
|
|
var typedArrays = availableTypedArrays();
|
|
|
|
var $slice = callBound('String.prototype.slice');
|
|
var getPrototypeOf = Object.getPrototypeOf; // require('getprototypeof');
|
|
|
|
var $indexOf = callBound('Array.prototype.indexOf', true) || /** @type {(array: readonly unknown[], value: unknown) => keyof array} */ function indexOf(array, value) {
|
|
for (var i = 0; i < array.length; i += 1) {
|
|
if (array[i] === value) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
/** @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array} TypedArray */
|
|
/** @typedef {'Int8Array' | 'Uint8Array' | 'Uint8ClampedArray' | 'Int16Array' | 'Uint16Array' | 'Int32Array' | 'Uint32Array' | 'Float32Array' | 'Float64Array' | 'BigInt64Array' | 'BigUint64Array'} TypedArrayName */
|
|
/** @type {{ [k in `\$${TypedArrayName}`]?: (receiver: TypedArray) => string | typeof Uint8Array.prototype.slice.call | typeof Uint8Array.prototype.set.call } & { __proto__: null }} */
|
|
var cache = { __proto__: null };
|
|
if (hasToStringTag && gOPD && getPrototypeOf) {
|
|
forEach(typedArrays, function (typedArray) {
|
|
var arr = new g[typedArray]();
|
|
if (Symbol.toStringTag in arr) {
|
|
var proto = getPrototypeOf(arr);
|
|
// @ts-expect-error TS won't narrow inside a closure
|
|
var descriptor = gOPD(proto, Symbol.toStringTag);
|
|
if (!descriptor) {
|
|
var superProto = getPrototypeOf(proto);
|
|
// @ts-expect-error TS won't narrow inside a closure
|
|
descriptor = gOPD(superProto, Symbol.toStringTag);
|
|
}
|
|
// @ts-expect-error TODO: fix
|
|
cache['$' + typedArray] = callBind(descriptor.get);
|
|
}
|
|
});
|
|
} else {
|
|
forEach(typedArrays, function (typedArray) {
|
|
var arr = new g[typedArray]();
|
|
var fn = arr.slice || arr.set;
|
|
if (fn) {
|
|
// @ts-expect-error TODO: fix
|
|
cache['$' + typedArray] = callBind(fn);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** @type {import('.')} */
|
|
var tryTypedArrays = function tryAllTypedArrays(value) {
|
|
/** @type {ReturnType<tryAllTypedArrays>} */ var found = false;
|
|
forEach(
|
|
// eslint-disable-next-line no-extra-parens
|
|
/** @type {Record<`\$${TypedArrayName}`, typeof cache>} */ /** @type {any} */ (cache),
|
|
/** @type {(getter: typeof cache, name: `\$${TypedArrayName}`) => void} */ function (getter, typedArray) {
|
|
if (!found) {
|
|
try {
|
|
// @ts-expect-error TODO: fix
|
|
if ('$' + getter(value) === typedArray) {
|
|
found = $slice(typedArray, 1);
|
|
}
|
|
} catch (e) { /**/ }
|
|
}
|
|
}
|
|
);
|
|
return found;
|
|
};
|
|
|
|
/** @type {import('.')} */
|
|
var trySlices = function tryAllSlices(value) {
|
|
/** @type {ReturnType<tryAllSlices>} */ var found = false;
|
|
forEach(
|
|
// eslint-disable-next-line no-extra-parens
|
|
/** @type {any} */ (cache),
|
|
/** @type {(getter: typeof cache, name: `\$${TypedArrayName}`) => void} */ function (getter, name) {
|
|
if (!found) {
|
|
try {
|
|
// @ts-expect-error TODO: fix
|
|
getter(value);
|
|
found = $slice(name, 1);
|
|
} catch (e) { /**/ }
|
|
}
|
|
}
|
|
);
|
|
return found;
|
|
};
|
|
|
|
/** @type {import('.')} */
|
|
module.exports = function whichTypedArray(value) {
|
|
if (!value || typeof value !== 'object') { return false; }
|
|
if (!hasToStringTag) {
|
|
var tag = $slice($toString(value), 8, -1);
|
|
if ($indexOf(typedArrays, tag) > -1) {
|
|
return tag;
|
|
}
|
|
if (tag !== 'Object') {
|
|
return false;
|
|
}
|
|
// node < 0.6 hits here on real Typed Arrays
|
|
return trySlices(value);
|
|
}
|
|
if (!gOPD) { return null; } // unknown engine
|
|
return tryTypedArrays(value);
|
|
};
|