@keeex/utils 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +105 -0
- package/lib/array.d.ts +28 -0
- package/lib/array.js +36 -0
- package/lib/arraybuffer.d.ts +138 -0
- package/lib/arraybuffer.js +141 -0
- package/lib/async/asynctrigger.d.ts +50 -0
- package/lib/async/asynctrigger.js +108 -0
- package/lib/async/deferredpromise.d.ts +32 -0
- package/lib/async/deferredpromise.js +66 -0
- package/lib/async/keycache.d.ts +56 -0
- package/lib/async/keycache.js +103 -0
- package/lib/async/queues.d.ts +69 -0
- package/lib/async/queues.js +135 -0
- package/lib/async/timecache.d.ts +58 -0
- package/lib/async/timecache.js +118 -0
- package/lib/base58.d.ts +27 -0
- package/lib/base58.js +83 -0
- package/lib/base64.d.ts +51 -0
- package/lib/base64.js +126 -0
- package/lib/benchmark.d.ts +126 -0
- package/lib/benchmark.js +177 -0
- package/lib/bits/arraybuffer.d.ts +35 -0
- package/lib/bits/arraybuffer.js +64 -0
- package/lib/bits/base64.d.ts +35 -0
- package/lib/bits/base64.js +70 -0
- package/lib/bits/hex.d.ts +17 -0
- package/lib/bits/hex.js +30 -0
- package/lib/bits/uint8array.d.ts +28 -0
- package/lib/bits/uint8array.js +42 -0
- package/lib/bytebuffer.d.ts +27 -0
- package/lib/bytebuffer.js +29 -0
- package/lib/consts.d.ts +33 -0
- package/lib/consts.js +33 -0
- package/lib/cron/logger.d.ts +22 -0
- package/lib/cron/logger.js +31 -0
- package/lib/cron/scheduledtask.d.ts +71 -0
- package/lib/cron/scheduledtask.js +137 -0
- package/lib/cron/types.d.ts +53 -0
- package/lib/cron/types.js +31 -0
- package/lib/cron.d.ts +29 -0
- package/lib/cron.js +47 -0
- package/lib/dict.d.ts +56 -0
- package/lib/dict.js +74 -0
- package/lib/error.d.ts +25 -0
- package/lib/error.js +41 -0
- package/lib/global.d.ts +27 -0
- package/lib/global.js +53 -0
- package/lib/hex.d.ts +32 -0
- package/lib/hex.js +58 -0
- package/lib/idx.d.ts +51 -0
- package/lib/idx.js +81 -0
- package/lib/json.d.ts +57 -0
- package/lib/json.js +116 -0
- package/lib/marshalling/marshaller.d.ts +51 -0
- package/lib/marshalling/marshaller.js +155 -0
- package/lib/marshalling/unmarshaller.d.ts +53 -0
- package/lib/marshalling/unmarshaller.js +124 -0
- package/lib/marshalling/util.d.ts +25 -0
- package/lib/marshalling/util.js +25 -0
- package/lib/number.d.ts +17 -0
- package/lib/number.js +21 -0
- package/lib/path.d.ts +25 -0
- package/lib/path.js +29 -0
- package/lib/promise.d.ts +42 -0
- package/lib/promise.js +78 -0
- package/lib/starttime.d.ts +23 -0
- package/lib/starttime.js +29 -0
- package/lib/string.d.ts +65 -0
- package/lib/string.js +108 -0
- package/lib/types/array.d.ts +34 -0
- package/lib/types/array.js +64 -0
- package/lib/types/enum.d.ts +30 -0
- package/lib/types/enum.js +44 -0
- package/lib/types/predicateerror.d.ts +40 -0
- package/lib/types/predicateerror.js +107 -0
- package/lib/types/primitive.d.ts +23 -0
- package/lib/types/primitive.js +34 -0
- package/lib/types/record.d.ts +67 -0
- package/lib/types/record.js +235 -0
- package/lib/types/types.d.ts +64 -0
- package/lib/types/types.js +115 -0
- package/lib/types/utils.d.ts +18 -0
- package/lib/types/utils.js +67 -0
- package/lib/uint8array.d.ts +176 -0
- package/lib/uint8array.js +438 -0
- package/lib/units.d.ts +159 -0
- package/lib/units.js +290 -0
- package/lib/utils/buffer.d.ts +49 -0
- package/lib/utils/buffer.js +79 -0
- package/lib/utils/fourbytes.d.ts +29 -0
- package/lib/utils/fourbytes.js +45 -0
- package/package.json +1 -0
- package/web/array.d.ts +28 -0
- package/web/array.js +34 -0
- package/web/arraybuffer.d.ts +138 -0
- package/web/arraybuffer.js +141 -0
- package/web/async/asynctrigger.d.ts +50 -0
- package/web/async/asynctrigger.js +106 -0
- package/web/async/deferredpromise.d.ts +32 -0
- package/web/async/deferredpromise.js +65 -0
- package/web/async/keycache.d.ts +56 -0
- package/web/async/keycache.js +97 -0
- package/web/async/queues.d.ts +69 -0
- package/web/async/queues.js +131 -0
- package/web/async/timecache.d.ts +58 -0
- package/web/async/timecache.js +107 -0
- package/web/base58.d.ts +27 -0
- package/web/base58.js +78 -0
- package/web/base64.d.ts +51 -0
- package/web/base64.js +136 -0
- package/web/benchmark.d.ts +126 -0
- package/web/benchmark.js +183 -0
- package/web/bits/arraybuffer.d.ts +35 -0
- package/web/bits/arraybuffer.js +59 -0
- package/web/bits/base64.d.ts +35 -0
- package/web/bits/base64.js +67 -0
- package/web/bits/hex.d.ts +17 -0
- package/web/bits/hex.js +27 -0
- package/web/bits/uint8array.d.ts +28 -0
- package/web/bits/uint8array.js +41 -0
- package/web/bytebuffer.d.ts +27 -0
- package/web/bytebuffer.js +29 -0
- package/web/consts.d.ts +33 -0
- package/web/consts.js +33 -0
- package/web/cron/logger.d.ts +22 -0
- package/web/cron/logger.js +30 -0
- package/web/cron/scheduledtask.d.ts +71 -0
- package/web/cron/scheduledtask.js +136 -0
- package/web/cron/types.d.ts +53 -0
- package/web/cron/types.js +31 -0
- package/web/cron.d.ts +29 -0
- package/web/cron.js +47 -0
- package/web/dict.d.ts +56 -0
- package/web/dict.js +67 -0
- package/web/error.d.ts +25 -0
- package/web/error.js +39 -0
- package/web/global.d.ts +27 -0
- package/web/global.js +49 -0
- package/web/hex.d.ts +32 -0
- package/web/hex.js +52 -0
- package/web/idx.d.ts +51 -0
- package/web/idx.js +76 -0
- package/web/json.d.ts +57 -0
- package/web/json.js +98 -0
- package/web/marshalling/marshaller.d.ts +51 -0
- package/web/marshalling/marshaller.js +150 -0
- package/web/marshalling/unmarshaller.d.ts +53 -0
- package/web/marshalling/unmarshaller.js +115 -0
- package/web/marshalling/util.d.ts +25 -0
- package/web/marshalling/util.js +25 -0
- package/web/number.d.ts +17 -0
- package/web/number.js +21 -0
- package/web/path.d.ts +25 -0
- package/web/path.js +26 -0
- package/web/promise.d.ts +42 -0
- package/web/promise.js +74 -0
- package/web/starttime.d.ts +23 -0
- package/web/starttime.js +29 -0
- package/web/string.d.ts +65 -0
- package/web/string.js +101 -0
- package/web/types/array.d.ts +34 -0
- package/web/types/array.js +63 -0
- package/web/types/enum.d.ts +30 -0
- package/web/types/enum.js +40 -0
- package/web/types/predicateerror.d.ts +40 -0
- package/web/types/predicateerror.js +128 -0
- package/web/types/primitive.d.ts +23 -0
- package/web/types/primitive.js +33 -0
- package/web/types/record.d.ts +67 -0
- package/web/types/record.js +213 -0
- package/web/types/types.d.ts +64 -0
- package/web/types/types.js +123 -0
- package/web/types/utils.d.ts +18 -0
- package/web/types/utils.js +30 -0
- package/web/uint8array.d.ts +176 -0
- package/web/uint8array.js +412 -0
- package/web/units.d.ts +159 -0
- package/web/units.js +312 -0
- package/web/utils/buffer.d.ts +49 -0
- package/web/utils/buffer.js +76 -0
- package/web/utils/fourbytes.d.ts +29 -0
- package/web/utils/fourbytes.js +45 -0
package/web/base64.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
import { asArray } from "./array.js";
|
|
17
|
+
import { ab2b64, b642ab } from "./bits/arraybuffer.js";
|
|
18
|
+
import { b64Len as b64LenBits } from "./bits/base64.js";
|
|
19
|
+
import { getUint8Array } from "./bits/uint8array.js";
|
|
20
|
+
import { buf82b64 } from "./uint8array.js";
|
|
21
|
+
/** @public */
|
|
22
|
+
export const buf82B64 = buffer => buffer instanceof ArrayBuffer ? ab2b64(buffer) : buf82b64(buffer);
|
|
23
|
+
const headerBegin = "-----BEGIN ";
|
|
24
|
+
const headerEnd = "-----END ";
|
|
25
|
+
const headerSuffix = "-----";
|
|
26
|
+
const bagAttributesHeader = "Bag Attributes";
|
|
27
|
+
const singleInput2ArmorB64 = ({
|
|
28
|
+
buffer,
|
|
29
|
+
label,
|
|
30
|
+
bagAttributes
|
|
31
|
+
}, lineWidth) => {
|
|
32
|
+
const b64Data = buf82B64(buffer);
|
|
33
|
+
const splitB64Data = lineWidth >= b64Data.length ? b64Data : b64Data.match(new RegExp(`(.{1,${lineWidth}})`, "gu"))?.join("\n") ?? "";
|
|
34
|
+
const header = `${headerBegin}${label}${headerSuffix}\n`;
|
|
35
|
+
const footer = `\n${headerEnd}${label}${headerSuffix}\n`;
|
|
36
|
+
const bag = bagAttributes ? `${bagAttributesHeader}\n${bagAttributes}\n` : "";
|
|
37
|
+
return `${bag}${header}${splitB64Data}${footer}`;
|
|
38
|
+
};
|
|
39
|
+
const DEFAULT_WIDTH = 64;
|
|
40
|
+
/** @public */
|
|
41
|
+
export const buf82ArmorB64 = (bufferOrInput, labelOrLineWidth, lineWidth, bagAttributes) => {
|
|
42
|
+
if (bufferOrInput instanceof ArrayBuffer || bufferOrInput instanceof Uint8Array) {
|
|
43
|
+
const label = labelOrLineWidth ?? "DATA";
|
|
44
|
+
return singleInput2ArmorB64({
|
|
45
|
+
bagAttributes: bagAttributes,
|
|
46
|
+
buffer: bufferOrInput,
|
|
47
|
+
label: label
|
|
48
|
+
}, lineWidth ?? DEFAULT_WIDTH);
|
|
49
|
+
}
|
|
50
|
+
return asArray(bufferOrInput).map(input => singleInput2ArmorB64(input, labelOrLineWidth ?? DEFAULT_WIDTH)).join("");
|
|
51
|
+
};
|
|
52
|
+
const splitArmorB64 = armorB64 => {
|
|
53
|
+
const res = [];
|
|
54
|
+
const lines = armorB64.split("\n");
|
|
55
|
+
const bagAttributesLines = [];
|
|
56
|
+
let inBagAttributes = false;
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
58
|
+
let base64Begin;
|
|
59
|
+
for (let i = 0; i < lines.length; ++i) {
|
|
60
|
+
const line = lines[i];
|
|
61
|
+
if (base64Begin === undefined) {
|
|
62
|
+
if (line.startsWith(headerBegin) && line.endsWith(headerSuffix)) {
|
|
63
|
+
inBagAttributes = false;
|
|
64
|
+
base64Begin = i;
|
|
65
|
+
} else if (inBagAttributes) {
|
|
66
|
+
bagAttributesLines.push(line);
|
|
67
|
+
} else if (line.startsWith(bagAttributesHeader)) {
|
|
68
|
+
inBagAttributes = true;
|
|
69
|
+
}
|
|
70
|
+
} else if (line.startsWith(headerEnd) && line.endsWith(headerSuffix)) {
|
|
71
|
+
const bagAttributes = bagAttributesLines.length > 0 ? bagAttributesLines.join("\n") : undefined;
|
|
72
|
+
const headLine = lines[base64Begin];
|
|
73
|
+
const label = headLine.substring(headerBegin.length, headLine.length - headerSuffix.length);
|
|
74
|
+
const labelEnd = line.substring(headerEnd.length, line.length - headerSuffix.length);
|
|
75
|
+
if (label !== labelEnd) throw new Error("Invalid end marker");
|
|
76
|
+
res.push({
|
|
77
|
+
b64: lines.slice(base64Begin + 1, i).join(""),
|
|
78
|
+
bagAttributes,
|
|
79
|
+
label: headLine.substring(headerBegin.length, headLine.length - headerSuffix.length)
|
|
80
|
+
});
|
|
81
|
+
base64Begin = undefined;
|
|
82
|
+
bagAttributesLines.length = 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (res.length === 0) throw new Error("Not an armored base64 input");
|
|
86
|
+
return res;
|
|
87
|
+
};
|
|
88
|
+
/** @public */
|
|
89
|
+
export const armorB642Buf8 = armorB64 => {
|
|
90
|
+
const [{
|
|
91
|
+
label,
|
|
92
|
+
b64,
|
|
93
|
+
bagAttributes
|
|
94
|
+
}] = splitArmorB64(armorB64);
|
|
95
|
+
const arrayBuffer = b642ab(b64, false);
|
|
96
|
+
return {
|
|
97
|
+
arrayBuffer,
|
|
98
|
+
bagAttributes,
|
|
99
|
+
buf8: getUint8Array(arrayBuffer),
|
|
100
|
+
label
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/** @public */
|
|
104
|
+
export const multipleArmorB642Buf8 = armorB64 => {
|
|
105
|
+
const splitted = splitArmorB64(armorB64);
|
|
106
|
+
return splitted.map(({
|
|
107
|
+
b64,
|
|
108
|
+
label,
|
|
109
|
+
bagAttributes
|
|
110
|
+
}) => {
|
|
111
|
+
const arrayBuffer = b642ab(b64, false);
|
|
112
|
+
return {
|
|
113
|
+
arrayBuffer,
|
|
114
|
+
bagAttributes,
|
|
115
|
+
buf8: getUint8Array(arrayBuffer),
|
|
116
|
+
label
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Return the length of the data in a b64 string.
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export const b64Len = (data, strict) => b64LenBits(data, strict);
|
|
126
|
+
/**
|
|
127
|
+
* Return the length of the data in an armored b64 string.
|
|
128
|
+
*
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export const armorB64Len = armorB64 => {
|
|
132
|
+
const [{
|
|
133
|
+
b64
|
|
134
|
+
}] = splitArmorB64(armorB64);
|
|
135
|
+
return b64Len(b64, false);
|
|
136
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
import { Awaitable } from "./types/types.js";
|
|
17
|
+
export type BenchmarkFunction = (() => Promise<void>) | (() => void);
|
|
18
|
+
/**
|
|
19
|
+
* Run the provided function for given iterations and return the average runtime in ms.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export declare const benchmarkTime: (func: BenchmarkFunction, iterations: number) => Promise<number>;
|
|
24
|
+
interface DynamicBenchSettings {
|
|
25
|
+
/**
|
|
26
|
+
* Minimum number of run before we can stop.
|
|
27
|
+
*
|
|
28
|
+
* Defaults to 5.
|
|
29
|
+
*/
|
|
30
|
+
minRun?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of run after which we stop trying to get a stable value.
|
|
33
|
+
*
|
|
34
|
+
* When either this value or maxDuration is exceeded, the benchmark gives up.
|
|
35
|
+
*
|
|
36
|
+
* Defaults to 10000.
|
|
37
|
+
*/
|
|
38
|
+
maxRun?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum duration before the benchmark gives up on running new iterations.
|
|
41
|
+
*
|
|
42
|
+
* When either this value or maxDuration is exceeded, the benchmark gives up.
|
|
43
|
+
*
|
|
44
|
+
* Defaults to never.
|
|
45
|
+
*/
|
|
46
|
+
maxDurationMs?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Number of runs to keep to compute the average duration.
|
|
49
|
+
*
|
|
50
|
+
* Defaults to 5.
|
|
51
|
+
*/
|
|
52
|
+
averageWindowSize?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Number of consecutive run that must fit withing the margin of error.
|
|
55
|
+
*
|
|
56
|
+
* If the average of the last `stableRun` are closer than `maxDeltaMs` to the average duration,
|
|
57
|
+
* the benchmark completes.
|
|
58
|
+
*
|
|
59
|
+
* Defaults to 3.
|
|
60
|
+
*/
|
|
61
|
+
stableRun?: number;
|
|
62
|
+
/**
|
|
63
|
+
* Maximum delta between the fastest and slowest iteration in the last `stableRun` runs to accept.
|
|
64
|
+
*
|
|
65
|
+
* If the average of the last `stableRun` are closer than `maxDeltaMs` to the average duration,
|
|
66
|
+
* the benchmark completes.
|
|
67
|
+
*
|
|
68
|
+
* Defaults to 10 (ms).
|
|
69
|
+
*/
|
|
70
|
+
maxDeltaMs?: number;
|
|
71
|
+
/** Set to true to output debug on the console when running the benchmark */
|
|
72
|
+
debugLog?: boolean;
|
|
73
|
+
}
|
|
74
|
+
interface DynamicBenchSimple extends DynamicBenchSettings {
|
|
75
|
+
/**
|
|
76
|
+
* Function to benchmark.
|
|
77
|
+
*
|
|
78
|
+
* Make sure this function can be called multiple time without side effect and for roughly the
|
|
79
|
+
* same duration each time.
|
|
80
|
+
*/
|
|
81
|
+
func: BenchmarkFunction;
|
|
82
|
+
}
|
|
83
|
+
interface DynamicBenchAdvanced extends DynamicBenchSettings {
|
|
84
|
+
/**
|
|
85
|
+
* Function that return the adjusted function to benchmark.
|
|
86
|
+
*
|
|
87
|
+
* This function receive a multiplier as its single parameter, starting at 1.
|
|
88
|
+
* This value is increased until either the function duration is above the given threshold or it
|
|
89
|
+
* reaches a set maximum.
|
|
90
|
+
*/
|
|
91
|
+
getFunc: (multiplier: number) => Awaitable<BenchmarkFunction>;
|
|
92
|
+
/**
|
|
93
|
+
* Maximum value for the multiplier.
|
|
94
|
+
*
|
|
95
|
+
* Defaults to 1000.
|
|
96
|
+
*/
|
|
97
|
+
maxMultiplier?: number;
|
|
98
|
+
/**
|
|
99
|
+
* Minimum value for the function duration.
|
|
100
|
+
*
|
|
101
|
+
* Defaults to 10.
|
|
102
|
+
*/
|
|
103
|
+
minFuncDurationMs?: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Benchmark the duration of a function.
|
|
107
|
+
*
|
|
108
|
+
* This benchmark will run the function multiple time until it reaches a stable average.
|
|
109
|
+
*
|
|
110
|
+
* @public
|
|
111
|
+
*/
|
|
112
|
+
export declare const dynamicBenchmark: (dynamicBenchSetup: DynamicBenchSimple) => Promise<number>;
|
|
113
|
+
interface AdvancedBenchmarkResult {
|
|
114
|
+
multiplier: number;
|
|
115
|
+
durationMs: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Advanced dynamic benchmark where the length of the benchmark function can be adjusted.
|
|
119
|
+
*
|
|
120
|
+
* The `multiplier` property/parameter can be increased as needed until the benchmark function reach
|
|
121
|
+
* a given minimum duration, after which it is effectively benchmarked.
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export declare const advancedDynamicBenchmark: (dynamicBenchSetup: DynamicBenchAdvanced) => Promise<AdvancedBenchmarkResult>;
|
|
126
|
+
export {};
|
package/web/benchmark.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
import { createLogger } from "@keeex/log";
|
|
17
|
+
/** Return now() up to the best precision available */
|
|
18
|
+
const getNow = typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
19
|
+
/**
|
|
20
|
+
* Run the provided function for given iterations and return the average runtime in ms.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export const benchmarkTime = async (func, iterations) => {
|
|
25
|
+
const usePromises = func() instanceof Promise;
|
|
26
|
+
const start = getNow();
|
|
27
|
+
if (usePromises) {
|
|
28
|
+
// eslint-disable-next-line no-await-in-loop
|
|
29
|
+
for (let i = 0; i < iterations; ++i) await func();
|
|
30
|
+
} else {
|
|
31
|
+
// We checked that the function does not return a promise above
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
33
|
+
for (let i = 0; i < iterations; ++i) func();
|
|
34
|
+
}
|
|
35
|
+
const end = getNow();
|
|
36
|
+
const delta = end - start;
|
|
37
|
+
return delta / iterations;
|
|
38
|
+
};
|
|
39
|
+
/** Benchmark the function once */
|
|
40
|
+
const benchOneRun = async (usePromise, func) => {
|
|
41
|
+
if (usePromise) {
|
|
42
|
+
const before = getNow();
|
|
43
|
+
await func();
|
|
44
|
+
return getNow() - before;
|
|
45
|
+
}
|
|
46
|
+
const before = getNow();
|
|
47
|
+
func();
|
|
48
|
+
return getNow() - before;
|
|
49
|
+
};
|
|
50
|
+
const getBenchFuncInfo = async func => {
|
|
51
|
+
const before = getNow();
|
|
52
|
+
const testRun = func();
|
|
53
|
+
const isPromise = testRun instanceof Promise;
|
|
54
|
+
if (isPromise) await testRun;
|
|
55
|
+
const firstRunDurationMs = getNow() - before;
|
|
56
|
+
return {
|
|
57
|
+
isPromise,
|
|
58
|
+
firstRunDurationMs
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
/** Compute the average of an array, excluding the max and min value */
|
|
62
|
+
const computeAverage = values => {
|
|
63
|
+
const maxValue = Math.max(...values);
|
|
64
|
+
const minValue = Math.min(...values);
|
|
65
|
+
const filtered = [...values];
|
|
66
|
+
filtered.splice(filtered.indexOf(maxValue), 1);
|
|
67
|
+
filtered.splice(filtered.indexOf(minValue), 1);
|
|
68
|
+
return filtered.reduce((acc, cur) => acc + cur) / filtered.length;
|
|
69
|
+
};
|
|
70
|
+
const addToAverageWindow = (value, window, len) => {
|
|
71
|
+
while (window.length >= len) window.shift();
|
|
72
|
+
window.push(value);
|
|
73
|
+
};
|
|
74
|
+
let logger = null;
|
|
75
|
+
const getLogger = () => {
|
|
76
|
+
logger ??= createLogger({
|
|
77
|
+
tag: "@keeex/js-utils:benchmark"
|
|
78
|
+
});
|
|
79
|
+
return logger;
|
|
80
|
+
};
|
|
81
|
+
const getLog = printDebug => printDebug ? msg => {
|
|
82
|
+
getLogger().info(msg);
|
|
83
|
+
} :
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
85
|
+
() => {};
|
|
86
|
+
const defaultBenchConfig = {
|
|
87
|
+
averageWindowSize: 5,
|
|
88
|
+
debugLog: false,
|
|
89
|
+
maxDeltaMs: 10,
|
|
90
|
+
maxRun: 10000,
|
|
91
|
+
minRun: 5,
|
|
92
|
+
stableRun: 3
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Benchmark the duration of a function.
|
|
96
|
+
*
|
|
97
|
+
* This benchmark will run the function multiple time until it reaches a stable average.
|
|
98
|
+
*
|
|
99
|
+
* @public
|
|
100
|
+
*/
|
|
101
|
+
export const dynamicBenchmark = async dynamicBenchSetup => {
|
|
102
|
+
const cfg = {
|
|
103
|
+
...defaultBenchConfig,
|
|
104
|
+
...dynamicBenchSetup
|
|
105
|
+
};
|
|
106
|
+
const log = getLog(cfg.debugLog);
|
|
107
|
+
log("Getting benchmark function informations");
|
|
108
|
+
const funcInfo = await getBenchFuncInfo(cfg.func);
|
|
109
|
+
let runCounter = 1;
|
|
110
|
+
log(`First run: ${funcInfo.firstRunDurationMs}ms; use promises: ${funcInfo.isPromise ? "true" : "false"}`);
|
|
111
|
+
const averageWindow = [];
|
|
112
|
+
averageWindow.push(funcInfo.firstRunDurationMs);
|
|
113
|
+
log("Filling average window with initial runs");
|
|
114
|
+
while (averageWindow.length < cfg.averageWindowSize || runCounter < cfg.minRun) {
|
|
115
|
+
log(`Run ${runCounter + 1}`);
|
|
116
|
+
addToAverageWindow(
|
|
117
|
+
// eslint-disable-next-line no-await-in-loop
|
|
118
|
+
await benchOneRun(funcInfo.isPromise, cfg.func), averageWindow, cfg.averageWindowSize);
|
|
119
|
+
++runCounter;
|
|
120
|
+
}
|
|
121
|
+
let consecutiveSuccess = 0;
|
|
122
|
+
while (runCounter < cfg.maxRun) {
|
|
123
|
+
const currentAverage = computeAverage(averageWindow);
|
|
124
|
+
log(`Doing new run ${runCounter + 1}`);
|
|
125
|
+
// eslint-disable-next-line no-await-in-loop
|
|
126
|
+
const nextRun = await benchOneRun(funcInfo.isPromise, cfg.func);
|
|
127
|
+
++runCounter;
|
|
128
|
+
if (Math.abs(currentAverage - nextRun) <= cfg.maxDeltaMs) {
|
|
129
|
+
log(`Average run: ${currentAverage}ms, new run: ${nextRun}ms, under delta ${cfg.maxDeltaMs}`);
|
|
130
|
+
++consecutiveSuccess;
|
|
131
|
+
} else {
|
|
132
|
+
log(`Average run: ${currentAverage}ms, new run: ${nextRun}ms, over delta ${cfg.maxDeltaMs}`);
|
|
133
|
+
consecutiveSuccess = 0;
|
|
134
|
+
}
|
|
135
|
+
averageWindow.shift();
|
|
136
|
+
averageWindow.push(nextRun);
|
|
137
|
+
if (consecutiveSuccess >= cfg.stableRun) {
|
|
138
|
+
log(`Found ${consecutiveSuccess} successive run under delta, ending benchmark`);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (consecutiveSuccess < cfg.stableRun) log("Benchmark was inconclusive");
|
|
143
|
+
return computeAverage(averageWindow);
|
|
144
|
+
};
|
|
145
|
+
const advancedDefaults = {
|
|
146
|
+
maxMultiplier: 1000,
|
|
147
|
+
minFuncDurationMs: 10
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Advanced dynamic benchmark where the length of the benchmark function can be adjusted.
|
|
151
|
+
*
|
|
152
|
+
* The `multiplier` property/parameter can be increased as needed until the benchmark function reach
|
|
153
|
+
* a given minimum duration, after which it is effectively benchmarked.
|
|
154
|
+
*
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
export const advancedDynamicBenchmark = async dynamicBenchSetup => {
|
|
158
|
+
const cfg = {
|
|
159
|
+
...advancedDefaults,
|
|
160
|
+
...dynamicBenchSetup
|
|
161
|
+
};
|
|
162
|
+
const log = getLog(cfg.debugLog);
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
164
|
+
let durationMs;
|
|
165
|
+
let multiplier = 0;
|
|
166
|
+
while (durationMs === undefined || durationMs < cfg.minFuncDurationMs && multiplier <= cfg.maxMultiplier) {
|
|
167
|
+
log(`Advanced benchmark, multiplier: ${multiplier}`);
|
|
168
|
+
++multiplier;
|
|
169
|
+
// eslint-disable-next-line no-await-in-loop
|
|
170
|
+
const func = await cfg.getFunc(multiplier);
|
|
171
|
+
// eslint-disable-next-line no-await-in-loop
|
|
172
|
+
durationMs = await dynamicBenchmark({
|
|
173
|
+
...cfg,
|
|
174
|
+
func
|
|
175
|
+
});
|
|
176
|
+
log(`Duration: ${durationMs}ms, target: ${cfg.minFuncDurationMs}`);
|
|
177
|
+
}
|
|
178
|
+
log(`Final results: ${durationMs}ms with multiplier ${multiplier}`);
|
|
179
|
+
return {
|
|
180
|
+
multiplier,
|
|
181
|
+
durationMs
|
|
182
|
+
};
|
|
183
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Return an ArrayBuffer that match the provided Uint8Array
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
export declare const getArrayBuffer: (typedArray: ArrayBuffer | Uint8Array) => ArrayBuffer;
|
|
22
|
+
/**
|
|
23
|
+
* Convert an array buffer to a b64 string
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare const ab2b64: (data: ArrayBuffer) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Convert a b64 string to an array buffer
|
|
30
|
+
*
|
|
31
|
+
* @param strict - If enabled, prevent input from having extra data after the B64 string.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export declare const b642ab: (data: string, strict?: boolean) => ArrayBuffer;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
import { encode as encodeB64, decode as decodeB64 } from "base64-arraybuffer";
|
|
17
|
+
import { b64EffectiveData, B64_PAD2, B64_PAD1, B64_PAD0, B64_CHARBLOCK } from "./base64.js";
|
|
18
|
+
/**
|
|
19
|
+
* Return an ArrayBuffer that match the provided Uint8Array
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export const getArrayBuffer = typedArray => {
|
|
24
|
+
if (typedArray instanceof ArrayBuffer) return typedArray;
|
|
25
|
+
const ab = typedArray.buffer;
|
|
26
|
+
if (typedArray.byteOffset === 0 && typedArray.byteLength === ab.byteLength) return ab;
|
|
27
|
+
return ab.slice(typedArray.byteOffset, typedArray.byteOffset + typedArray.byteLength);
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Convert an array buffer to a b64 string
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export const ab2b64 = data => encodeB64(data);
|
|
35
|
+
/**
|
|
36
|
+
* Convert a b64 string to an array buffer
|
|
37
|
+
*
|
|
38
|
+
* @param strict - If enabled, prevent input from having extra data after the B64 string.
|
|
39
|
+
*
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
export const b642ab = (data, strict = false) => {
|
|
43
|
+
const effectiveData = b64EffectiveData(data, strict);
|
|
44
|
+
const result = decodeB64(effectiveData);
|
|
45
|
+
if (strict && effectiveData.length > 0) {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
47
|
+
let padding;
|
|
48
|
+
if (effectiveData.endsWith("==")) {
|
|
49
|
+
padding = B64_PAD2;
|
|
50
|
+
} else if (effectiveData.endsWith("=")) {
|
|
51
|
+
padding = B64_PAD1;
|
|
52
|
+
} else {
|
|
53
|
+
padding = B64_PAD0;
|
|
54
|
+
}
|
|
55
|
+
const outputLength = effectiveData.length / B64_CHARBLOCK * (B64_CHARBLOCK - 1) - padding;
|
|
56
|
+
if (result.byteLength !== outputLength) throw new Error("Invalid output length");
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
/** @internal */
|
|
17
|
+
export declare const B64_CHARBLOCK = 4;
|
|
18
|
+
/** @internal */
|
|
19
|
+
export declare const B64_PAD2 = 2;
|
|
20
|
+
/** @internal */
|
|
21
|
+
export declare const B64_PAD1 = 1;
|
|
22
|
+
/** @internal */
|
|
23
|
+
export declare const B64_PAD0 = 0;
|
|
24
|
+
/**
|
|
25
|
+
* Return the canonical data from a b64 string
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export declare const b64EffectiveData: (data: string, strict?: boolean) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Return the length of the data in a b64 string.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export declare const b64Len: (data: string, strict: boolean) => number;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
/** @internal */
|
|
17
|
+
export const B64_CHARBLOCK = 4;
|
|
18
|
+
const B64_PAD3 = 3;
|
|
19
|
+
/** @internal */
|
|
20
|
+
export const B64_PAD2 = 2;
|
|
21
|
+
/** @internal */
|
|
22
|
+
export const B64_PAD1 = 1;
|
|
23
|
+
/** @internal */
|
|
24
|
+
export const B64_PAD0 = 0;
|
|
25
|
+
/**
|
|
26
|
+
* Return the canonical data from a b64 string
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export const b64EffectiveData = (data, strict = false) => {
|
|
31
|
+
let effectiveData = data.indexOf("\n") === data.indexOf("\r") ? data : data.replace(/[\n\r]/gu, "");
|
|
32
|
+
if (effectiveData.length % B64_CHARBLOCK !== 0) {
|
|
33
|
+
if (strict) throw new Error("Invalid input length");
|
|
34
|
+
const extraSize = effectiveData.length % B64_CHARBLOCK;
|
|
35
|
+
switch (extraSize) {
|
|
36
|
+
case B64_PAD1:
|
|
37
|
+
effectiveData = effectiveData.substring(0, Math.floor(effectiveData.length / B64_CHARBLOCK) * B64_CHARBLOCK);
|
|
38
|
+
break;
|
|
39
|
+
case B64_PAD2:
|
|
40
|
+
effectiveData = `${effectiveData}==`;
|
|
41
|
+
break;
|
|
42
|
+
case B64_PAD3:
|
|
43
|
+
effectiveData = `${effectiveData}=`;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return effectiveData;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Return the length of the data in a b64 string.
|
|
51
|
+
*
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
export const b64Len = (data, strict) => {
|
|
55
|
+
const effectiveData = b64EffectiveData(data, strict);
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
57
|
+
let padding;
|
|
58
|
+
if (effectiveData.endsWith("==")) {
|
|
59
|
+
padding = B64_PAD2;
|
|
60
|
+
} else if (effectiveData.endsWith("=")) {
|
|
61
|
+
padding = B64_PAD1;
|
|
62
|
+
} else {
|
|
63
|
+
padding = B64_PAD0;
|
|
64
|
+
}
|
|
65
|
+
const outputLength = effectiveData.length / B64_CHARBLOCK * (B64_CHARBLOCK - 1) - padding;
|
|
66
|
+
return outputLength;
|
|
67
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* @preserve
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2023 KeeeX SAS
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
/** Clean an hex string input; make it even and remove 0x prefix if present */
|
|
17
|
+
export declare const clearHexInput: (input: string) => string;
|