-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
valueToKey.ts
72 lines (67 loc) · 2.07 KB
/
valueToKey.ts
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
import { DataError } from "./errors.js";
import { Key } from "./types.js";
// https://w3c.github.io/IndexedDB/#convert-value-to-key
const valueToKey = (input: any, seen?: Set<object>): Key | Key[] => {
if (typeof input === "number") {
if (isNaN(input)) {
throw new DataError();
}
return input;
} else if (input instanceof Date) {
const ms = input.valueOf();
if (isNaN(ms)) {
throw new DataError();
}
return new Date(ms);
} else if (typeof input === "string") {
return input;
} else if (
input instanceof ArrayBuffer ||
(typeof SharedArrayBuffer !== "undefined" &&
input instanceof SharedArrayBuffer) ||
(typeof ArrayBuffer !== "undefined" &&
ArrayBuffer.isView &&
ArrayBuffer.isView(input))
) {
let arrayBuffer;
let offset = 0;
let length = 0;
if (
input instanceof ArrayBuffer ||
(typeof SharedArrayBuffer !== "undefined" &&
input instanceof SharedArrayBuffer)
) {
arrayBuffer = input;
length = input.byteLength;
} else {
arrayBuffer = input.buffer;
offset = input.byteOffset;
length = input.byteLength;
}
if ((arrayBuffer as any).detached) {
return new ArrayBuffer(0);
}
return arrayBuffer.slice(offset, offset + length);
} else if (Array.isArray(input)) {
if (seen === undefined) {
seen = new Set();
} else if (seen.has(input)) {
throw new DataError();
}
seen.add(input);
const keys = [];
for (let i = 0; i < input.length; i++) {
const hop = Object.hasOwn(input, i);
if (!hop) {
throw new DataError();
}
const entry = input[i];
const key = valueToKey(entry, seen);
keys.push(key);
}
return keys;
} else {
throw new DataError();
}
};
export default valueToKey;