Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
134 lines (122 loc) · 3.69 KB
/
Copy pathindex.js
File metadata and controls
134 lines (122 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
'use strict';
var forEach = require('for-each');
var availableTypedArrays = require('available-typed-arrays');
var callBind = require('call-bind');
var callBound = require('call-bound');
var gOPD = require('gopd');
var getProto = require('get-proto');
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');
/** @import { BoundSet, BoundSlice, Cache, Getter } from './types' */
/** @import { TypedArrayName } from '.' */
/** @type {<T = unknown>(array: readonly T[], value: unknown) => number} */
var $indexOf = callBound('Array.prototype.indexOf', true) || function indexOf(array, value) {
for (var i = 0; i < array.length; i += 1) {
if (array[i] === value) {
return i;
}
}
return -1;
};
/** @type {Cache} */
var cache = { __proto__: null };
if (hasToStringTag && gOPD && getProto) {
forEach(typedArrays, function (typedArray) {
var arr = new g[typedArray]();
if (Symbol.toStringTag in arr && getProto) {
var proto = getProto(arr);
// @ts-expect-error TS won't narrow inside a closure
var descriptor = gOPD(proto, Symbol.toStringTag);
if (!descriptor && proto) {
var superProto = getProto(proto);
// @ts-expect-error TS won't narrow inside a closure
descriptor = gOPD(superProto, Symbol.toStringTag);
}
if (descriptor && descriptor.get) {
var bound = callBind(descriptor.get);
cache[
/** @type {`$${TypedArrayName}`} */
('$' + typedArray)
] = bound;
}
}
});
} else {
forEach(typedArrays, function (typedArray) {
var arr = new g[typedArray]();
var fn = arr.slice || arr.set;
if (fn) {
var bound = /** @type {typeof BoundSlice | typeof BoundSet} */ (
// @ts-expect-error TODO FIXME
callBind(fn)
);
cache[
/** @type {`$${TypedArrayName}`} */
('$' + typedArray)
] = bound;
}
});
}
/** @type {(value: object) => false | TypedArrayName} */
function tryTypedArrays(value) {
/** @type {ReturnType<typeof tryTypedArrays>} */ var found = false;
forEach(
/** @type {Record<`$${TypedArrayName}`, Getter>} */ (cache),
/** @param {Getter} getter @param {`$${TypedArrayName}`} typedArray */
function (getter, typedArray) {
if (!found) {
try {
// @ts-expect-error a throw is fine here
if ('$' + getter(value) === typedArray) {
found = /** @type {TypedArrayName} */ ($slice(typedArray, 1));
}
} catch (e) { /**/ }
}
}
);
return found;
}
/** @type {(value: object) => false | TypedArrayName} */
function trySlices(value) {
/** @type {ReturnType<typeof trySlices>} */ var found = false;
forEach(
/** @type {Record<`$${TypedArrayName}`, Getter>} */(cache),
/** @param {Getter} getter @param {`$${TypedArrayName}`} name */ function (getter, name) {
if (!found) {
try {
// @ts-expect-error a throw is fine here
getter(value);
found = /** @type {TypedArrayName} */ ($slice(name, 1));
} catch (e) { /**/ }
}
}
);
return found;
}
/** @type {(tag: unknown) => tag is typeof typedArrays[number]} */
function isTATag(tag) {
return $indexOf(typedArrays, tag) > -1;
}
/** @type {(value: unknown) => ReturnType<typeof import('.')>} */
function whichTypedArray(value) {
if (!value || typeof value !== 'object') {
return false;
}
if (!hasToStringTag) {
var tag = $slice($toString(value), 8, -1);
if (isTATag(tag)) {
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);
}
module.exports = whichTypedArray;