@evolu/common 8.9.0 → 8.10.0
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/dist/src/Bytes.d.ts +647 -0
- package/dist/src/Bytes.d.ts.map +1 -0
- package/dist/src/{Binary.js → Bytes.js} +266 -16
- package/dist/src/Config.d.ts +142 -0
- package/dist/src/Config.d.ts.map +1 -0
- package/dist/src/Config.js +181 -0
- package/dist/src/Fs.d.ts +302 -0
- package/dist/src/Fs.d.ts.map +1 -0
- package/dist/src/Fs.js +111 -0
- package/dist/src/Number.d.ts +50 -7
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +47 -8
- package/dist/src/Object.d.ts +32 -0
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +41 -0
- package/dist/src/Sqlite.js +1 -1
- package/dist/src/Time.d.ts +74 -12
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +40 -2
- package/dist/src/Type.d.ts +1451 -79
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +1303 -96
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/_en.d.ts +24 -1
- package/dist/src/intl/_en.d.ts.map +1 -1
- package/dist/src/intl/_en.js +20 -0
- package/dist/src/intl/ar.d.ts +24 -1
- package/dist/src/intl/ar.d.ts.map +1 -1
- package/dist/src/intl/ar.js +20 -0
- package/dist/src/intl/bn.d.ts +24 -1
- package/dist/src/intl/bn.d.ts.map +1 -1
- package/dist/src/intl/bn.js +20 -0
- package/dist/src/intl/ca.d.ts +24 -1
- package/dist/src/intl/ca.d.ts.map +1 -1
- package/dist/src/intl/ca.js +20 -0
- package/dist/src/intl/cs.d.ts +24 -1
- package/dist/src/intl/cs.d.ts.map +1 -1
- package/dist/src/intl/cs.js +20 -0
- package/dist/src/intl/da.d.ts +24 -1
- package/dist/src/intl/da.d.ts.map +1 -1
- package/dist/src/intl/da.js +20 -0
- package/dist/src/intl/de.d.ts +24 -1
- package/dist/src/intl/de.d.ts.map +1 -1
- package/dist/src/intl/de.js +20 -0
- package/dist/src/intl/el.d.ts +24 -1
- package/dist/src/intl/el.d.ts.map +1 -1
- package/dist/src/intl/el.js +20 -0
- package/dist/src/intl/es.d.ts +24 -1
- package/dist/src/intl/es.d.ts.map +1 -1
- package/dist/src/intl/es.js +20 -0
- package/dist/src/intl/fa.d.ts +24 -1
- package/dist/src/intl/fa.d.ts.map +1 -1
- package/dist/src/intl/fa.js +20 -0
- package/dist/src/intl/fi.d.ts +24 -1
- package/dist/src/intl/fi.d.ts.map +1 -1
- package/dist/src/intl/fi.js +20 -0
- package/dist/src/intl/fil.d.ts +24 -1
- package/dist/src/intl/fil.d.ts.map +1 -1
- package/dist/src/intl/fil.js +20 -0
- package/dist/src/intl/fr.d.ts +24 -1
- package/dist/src/intl/fr.d.ts.map +1 -1
- package/dist/src/intl/fr.js +20 -0
- package/dist/src/intl/he.d.ts +24 -1
- package/dist/src/intl/he.d.ts.map +1 -1
- package/dist/src/intl/he.js +20 -0
- package/dist/src/intl/hi.d.ts +24 -1
- package/dist/src/intl/hi.d.ts.map +1 -1
- package/dist/src/intl/hi.js +20 -0
- package/dist/src/intl/hr.d.ts +24 -1
- package/dist/src/intl/hr.d.ts.map +1 -1
- package/dist/src/intl/hr.js +20 -0
- package/dist/src/intl/hu.d.ts +22 -1
- package/dist/src/intl/hu.d.ts.map +1 -1
- package/dist/src/intl/hu.js +18 -0
- package/dist/src/intl/id.d.ts +24 -1
- package/dist/src/intl/id.d.ts.map +1 -1
- package/dist/src/intl/id.js +20 -0
- package/dist/src/intl/it.d.ts +24 -1
- package/dist/src/intl/it.d.ts.map +1 -1
- package/dist/src/intl/it.js +20 -0
- package/dist/src/intl/ja.d.ts +24 -1
- package/dist/src/intl/ja.d.ts.map +1 -1
- package/dist/src/intl/ja.js +20 -0
- package/dist/src/intl/ko.d.ts +24 -1
- package/dist/src/intl/ko.d.ts.map +1 -1
- package/dist/src/intl/ko.js +20 -0
- package/dist/src/intl/ml.d.ts +24 -1
- package/dist/src/intl/ml.d.ts.map +1 -1
- package/dist/src/intl/ml.js +20 -0
- package/dist/src/intl/mr.d.ts +24 -1
- package/dist/src/intl/mr.d.ts.map +1 -1
- package/dist/src/intl/mr.js +20 -0
- package/dist/src/intl/ms.d.ts +24 -1
- package/dist/src/intl/ms.d.ts.map +1 -1
- package/dist/src/intl/ms.js +20 -0
- package/dist/src/intl/nb.d.ts +22 -1
- package/dist/src/intl/nb.d.ts.map +1 -1
- package/dist/src/intl/nb.js +18 -0
- package/dist/src/intl/nl.d.ts +24 -1
- package/dist/src/intl/nl.d.ts.map +1 -1
- package/dist/src/intl/nl.js +20 -0
- package/dist/src/intl/pa.d.ts +24 -1
- package/dist/src/intl/pa.d.ts.map +1 -1
- package/dist/src/intl/pa.js +20 -0
- package/dist/src/intl/pl.d.ts +23 -0
- package/dist/src/intl/pl.d.ts.map +1 -1
- package/dist/src/intl/pl.js +20 -0
- package/dist/src/intl/pt-BR.d.ts +24 -1
- package/dist/src/intl/pt-BR.d.ts.map +1 -1
- package/dist/src/intl/pt-BR.js +20 -0
- package/dist/src/intl/pt.d.ts +24 -1
- package/dist/src/intl/pt.d.ts.map +1 -1
- package/dist/src/intl/pt.js +20 -0
- package/dist/src/intl/ro.d.ts +24 -1
- package/dist/src/intl/ro.d.ts.map +1 -1
- package/dist/src/intl/ro.js +20 -0
- package/dist/src/intl/sk.d.ts +24 -1
- package/dist/src/intl/sk.d.ts.map +1 -1
- package/dist/src/intl/sk.js +20 -0
- package/dist/src/intl/sl.d.ts +24 -1
- package/dist/src/intl/sl.d.ts.map +1 -1
- package/dist/src/intl/sl.js +20 -0
- package/dist/src/intl/sv.d.ts +24 -1
- package/dist/src/intl/sv.d.ts.map +1 -1
- package/dist/src/intl/sv.js +20 -0
- package/dist/src/intl/sw.d.ts +21 -0
- package/dist/src/intl/sw.d.ts.map +1 -1
- package/dist/src/intl/sw.js +18 -0
- package/dist/src/intl/ta.d.ts +24 -1
- package/dist/src/intl/ta.d.ts.map +1 -1
- package/dist/src/intl/ta.js +20 -0
- package/dist/src/intl/te.d.ts +24 -1
- package/dist/src/intl/te.d.ts.map +1 -1
- package/dist/src/intl/te.js +20 -0
- package/dist/src/intl/th.d.ts +24 -1
- package/dist/src/intl/th.d.ts.map +1 -1
- package/dist/src/intl/th.js +20 -0
- package/dist/src/intl/tr.d.ts +24 -1
- package/dist/src/intl/tr.d.ts.map +1 -1
- package/dist/src/intl/tr.js +20 -0
- package/dist/src/intl/uk.d.ts +80 -57
- package/dist/src/intl/uk.d.ts.map +1 -1
- package/dist/src/intl/uk.js +174 -149
- package/dist/src/intl/ur.d.ts +24 -1
- package/dist/src/intl/ur.d.ts.map +1 -1
- package/dist/src/intl/ur.js +20 -0
- package/dist/src/intl/vi.d.ts +24 -1
- package/dist/src/intl/vi.d.ts.map +1 -1
- package/dist/src/intl/vi.js +20 -0
- package/dist/src/intl/zh-CN.d.ts +24 -1
- package/dist/src/intl/zh-CN.d.ts.map +1 -1
- package/dist/src/intl/zh-CN.js +20 -0
- package/dist/src/intl/zh-TW.d.ts +24 -1
- package/dist/src/intl/zh-TW.d.ts.map +1 -1
- package/dist/src/intl/zh-TW.js +20 -0
- package/dist/src/local-first/Protocol.d.ts +1 -1
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +1 -1
- package/dist/src/local-first/Schema.d.ts +10 -0
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +1 -1
- package/dist/src/local-first/Timestamp.js +1 -1
- package/package.json +1 -1
- package/src/{Binary.test.ts → Bytes.test.ts} +286 -1
- package/src/{Binary.ts → Bytes.ts} +652 -21
- package/src/Config.test.ts +672 -0
- package/src/Config.ts +410 -0
- package/src/Fs.test.ts +105 -0
- package/src/Fs.ts +414 -0
- package/src/Number.test.ts +82 -18
- package/src/Number.ts +76 -8
- package/src/Object.test.ts +115 -1
- package/src/Object.ts +44 -0
- package/src/Sqlite.ts +1 -1
- package/src/Time.test.ts +82 -11
- package/src/Time.ts +141 -16
- package/src/Type.test.ts +3114 -157
- package/src/Type.ts +2553 -196
- package/src/index.ts +3 -1
- package/src/intl/_en.ts +70 -0
- package/src/intl/ar.ts +71 -0
- package/src/intl/bn.ts +70 -0
- package/src/intl/ca.ts +70 -0
- package/src/intl/cs.ts +70 -0
- package/src/intl/da.ts +70 -0
- package/src/intl/de.ts +70 -0
- package/src/intl/el.ts +70 -0
- package/src/intl/es.ts +70 -0
- package/src/intl/fa.ts +70 -0
- package/src/intl/fi.ts +70 -0
- package/src/intl/fil.ts +70 -0
- package/src/intl/fr.ts +70 -0
- package/src/intl/he.ts +70 -0
- package/src/intl/hi.ts +70 -0
- package/src/intl/hr.ts +70 -0
- package/src/intl/hu.ts +69 -0
- package/src/intl/id.ts +70 -0
- package/src/intl/intl.test.ts +819 -1
- package/src/intl/it.ts +70 -0
- package/src/intl/ja.ts +70 -0
- package/src/intl/ko.ts +68 -0
- package/src/intl/ml.ts +70 -0
- package/src/intl/mr.ts +70 -0
- package/src/intl/ms.ts +71 -0
- package/src/intl/nb.ts +69 -0
- package/src/intl/nl.ts +70 -0
- package/src/intl/pa.ts +70 -0
- package/src/intl/pl.ts +63 -0
- package/src/intl/pt-BR.ts +70 -0
- package/src/intl/pt.ts +71 -0
- package/src/intl/ro.ts +70 -0
- package/src/intl/sk.ts +71 -0
- package/src/intl/sl.ts +70 -0
- package/src/intl/sv.ts +70 -0
- package/src/intl/sw.ts +62 -0
- package/src/intl/ta.ts +70 -0
- package/src/intl/te.ts +70 -0
- package/src/intl/th.ts +68 -0
- package/src/intl/tr.ts +70 -0
- package/src/intl/uk.ts +228 -155
- package/src/intl/ur.ts +70 -0
- package/src/intl/vi.ts +70 -0
- package/src/intl/zh-CN.ts +68 -0
- package/src/intl/zh-TW.ts +68 -0
- package/src/local-first/Protocol.test.ts +1 -1
- package/src/local-first/Protocol.ts +1 -1
- package/src/local-first/Schema.ts +11 -0
- package/src/local-first/Storage.ts +1 -1
- package/src/local-first/Timestamp.ts +1 -1
- package/dist/src/Binary.d.ts +0 -254
- package/dist/src/Binary.d.ts.map +0 -1
|
@@ -1,23 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Bytes: `Uint8Array` helpers, the {@link Buffer} codec, and byte sizes.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Sizes follow the same pattern as durations in Time.ts:
|
|
5
|
+
*
|
|
6
|
+
* - {@link ByteLength} is the canonical unit, a validated number of bytes.
|
|
7
|
+
* - {@link ByteSizeLiteral} is the human-readable form, such as `"10MiB"`,
|
|
8
|
+
* validated at compile time and runtime.
|
|
9
|
+
* - {@link ByteSize} is what APIs accept: `ByteSizeLiteral | ByteLength`.
|
|
10
|
+
* - {@link byteSizeToByteLength} normalizes a `ByteSize` to a `ByteLength`.
|
|
11
|
+
* - {@link ByteLengthFromString} parses either form from text.
|
|
12
|
+
*
|
|
13
|
+
* Buffer-based decoding functions throw instead of returning {@link Result}.
|
|
14
|
+
* Result is not slow, but every successful decode would allocate one, and a
|
|
15
|
+
* protocol message decodes many values. Throwing is the safe bet for that hot
|
|
16
|
+
* path until benchmarks cover the alternatives. Callers convert a thrown error
|
|
17
|
+
* into a Result once, at the boundary, as `parseProtocolHeader` in Protocol.ts
|
|
18
|
+
* does.
|
|
10
19
|
*
|
|
11
20
|
* @module
|
|
12
21
|
*/
|
|
13
22
|
|
|
14
23
|
import { bytesToUtf8, utf8ToBytes } from "@noble/ciphers/utils.js";
|
|
15
|
-
import
|
|
16
|
-
import type
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
import { assert } from "./Assert.ts";
|
|
25
|
+
import { err, ok, type Result } from "./Result.ts";
|
|
26
|
+
import { safelyStringifyUnknownValue } from "./String.ts";
|
|
27
|
+
import {
|
|
28
|
+
brand,
|
|
29
|
+
createTypeWithError,
|
|
30
|
+
Digit,
|
|
31
|
+
Digit1To9,
|
|
32
|
+
type FiniteNumber,
|
|
33
|
+
type JsonValue,
|
|
19
34
|
NonNegativeInt,
|
|
20
|
-
PositiveInt,
|
|
35
|
+
type PositiveInt,
|
|
36
|
+
String,
|
|
37
|
+
templateLiteral,
|
|
38
|
+
type TemplateLiteralType,
|
|
39
|
+
type LiteralType,
|
|
40
|
+
type UnionType,
|
|
41
|
+
transform,
|
|
42
|
+
type Type,
|
|
43
|
+
type TypeError,
|
|
44
|
+
union,
|
|
45
|
+
type UnionError,
|
|
21
46
|
} from "./Type.ts";
|
|
22
47
|
export { bytesToHex, concatBytes, hexToBytes } from "@noble/ciphers/utils.js";
|
|
23
48
|
export { bytesToUtf8, utf8ToBytes };
|
|
@@ -143,7 +168,7 @@ export const createBuffer = (
|
|
|
143
168
|
arrayLike?: Uint8Array | ArrayLike<number>,
|
|
144
169
|
): Buffer => {
|
|
145
170
|
const initialLength = arrayLike?.length ?? 0;
|
|
146
|
-
|
|
171
|
+
assertBufferNonNegativeInt(initialLength, "arrayLike.length");
|
|
147
172
|
|
|
148
173
|
let value = arrayLike ? new Uint8Array(arrayLike) : new Uint8Array(512);
|
|
149
174
|
let length = initialLength;
|
|
@@ -155,10 +180,10 @@ export const createBuffer = (
|
|
|
155
180
|
|
|
156
181
|
extend: (arg) => {
|
|
157
182
|
const argLength = arg.length;
|
|
158
|
-
|
|
183
|
+
assertBufferNonNegativeInt(argLength, "arg.length");
|
|
159
184
|
|
|
160
185
|
const targetSize = length + argLength;
|
|
161
|
-
|
|
186
|
+
assertBufferNonNegativeInt(targetSize, "Buffer length");
|
|
162
187
|
|
|
163
188
|
if (value.length < targetSize) {
|
|
164
189
|
const oldValue = value;
|
|
@@ -341,7 +366,7 @@ export const decodeNonNegativeInt = (buffer: Buffer): NonNegativeInt => {
|
|
|
341
366
|
}
|
|
342
367
|
|
|
343
368
|
const value = Number(result);
|
|
344
|
-
|
|
369
|
+
assertBufferNonNegativeInt(value, "Decoded integer");
|
|
345
370
|
return value;
|
|
346
371
|
};
|
|
347
372
|
|
|
@@ -350,7 +375,7 @@ export const encodeLength = (
|
|
|
350
375
|
buffer: Buffer,
|
|
351
376
|
value: ArrayLike<unknown>,
|
|
352
377
|
): void => {
|
|
353
|
-
|
|
378
|
+
assertBufferNonNegativeInt(value.length, "Array-like length");
|
|
354
379
|
encodeNonNegativeInt(buffer, value.length);
|
|
355
380
|
};
|
|
356
381
|
|
|
@@ -489,7 +514,7 @@ let jsonDecoderSource: Uint8Array = emptyJsonDecoderSource;
|
|
|
489
514
|
let jsonDecoderView: DataView = emptyJsonDecoderView;
|
|
490
515
|
let jsonDecoderPosition = 0;
|
|
491
516
|
let jsonDecoderDepth = 0;
|
|
492
|
-
const jsonStringFromCharCode = String.fromCharCode;
|
|
517
|
+
const jsonStringFromCharCode = globalThis.String.fromCharCode;
|
|
493
518
|
// Cache only short keys and use a fixed table to bound retained memory.
|
|
494
519
|
const jsonKeyCache: Array<JsonKeyCacheEntry | undefined> = Array.from(
|
|
495
520
|
{ length: jsonKeyCacheSize },
|
|
@@ -816,12 +841,12 @@ const writeJsonEncoderByte = (value: number): void => {
|
|
|
816
841
|
|
|
817
842
|
const ensureJsonEncoderCapacity = (additionalLength: number): void => {
|
|
818
843
|
const requiredLength = jsonEncoderPosition + additionalLength;
|
|
819
|
-
|
|
844
|
+
assertBufferNonNegativeInt(requiredLength, "Encoded JSON value length");
|
|
820
845
|
|
|
821
846
|
if (requiredLength <= jsonEncoderTarget.length) return;
|
|
822
847
|
|
|
823
848
|
const newCapacity = Math.max(jsonEncoderTarget.length * 2, requiredLength);
|
|
824
|
-
|
|
849
|
+
assertBufferNonNegativeInt(newCapacity, "JSON encoder capacity");
|
|
825
850
|
|
|
826
851
|
const oldTarget = jsonEncoderTarget;
|
|
827
852
|
jsonEncoderTarget = new Uint8Array(newCapacity);
|
|
@@ -1358,7 +1383,7 @@ const assertJsonDecoderHasRemainingBytes = (requiredBytes: number): void => {
|
|
|
1358
1383
|
}
|
|
1359
1384
|
};
|
|
1360
1385
|
|
|
1361
|
-
const
|
|
1386
|
+
const assertBufferNonNegativeInt: (
|
|
1362
1387
|
value: number,
|
|
1363
1388
|
name: string,
|
|
1364
1389
|
) => asserts value is NonNegativeInt = (value, name) => {
|
|
@@ -1375,3 +1400,609 @@ const assertBufferHasRemainingBytes = (
|
|
|
1375
1400
|
throw new BufferError("Buffer parse ended prematurely");
|
|
1376
1401
|
}
|
|
1377
1402
|
};
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* Non-negative safe integer number of bytes.
|
|
1406
|
+
*
|
|
1407
|
+
* The canonical unit for sizes, as milliseconds are for time. APIs accept
|
|
1408
|
+
* {@link ByteSize} and normalize it with {@link byteSizeToByteLength}. Parse text
|
|
1409
|
+
* such as an environment variable with {@link ByteLengthFromString}. Negative
|
|
1410
|
+
* zero is rejected so zero has one canonical representation.
|
|
1411
|
+
*
|
|
1412
|
+
* ### Example
|
|
1413
|
+
*
|
|
1414
|
+
* ```ts
|
|
1415
|
+
* import { assertErr, assertOk, ByteLength } from "@evolu/common";
|
|
1416
|
+
*
|
|
1417
|
+
* assertOk(ByteLength.fromUnknown(0), 0);
|
|
1418
|
+
* assertOk(ByteLength.fromUnknown(1024), 1024);
|
|
1419
|
+
* assertErr(ByteLength.fromUnknown(-0));
|
|
1420
|
+
* assertErr(ByteLength.fromUnknown(-1));
|
|
1421
|
+
* assertErr(ByteLength.fromUnknown(1.5));
|
|
1422
|
+
* ```
|
|
1423
|
+
*/
|
|
1424
|
+
export const ByteLength = /*#__PURE__*/ brand(
|
|
1425
|
+
"ByteLength",
|
|
1426
|
+
NonNegativeInt,
|
|
1427
|
+
(value) =>
|
|
1428
|
+
Object.is(value, -0)
|
|
1429
|
+
? err<ByteLengthError>({ type: "ByteLength", value })
|
|
1430
|
+
: ok(),
|
|
1431
|
+
() => "The value -0 is not a byte length. Use 0 instead.",
|
|
1432
|
+
);
|
|
1433
|
+
export type ByteLength = typeof ByteLength.Output;
|
|
1434
|
+
|
|
1435
|
+
/** Error returned when {@link ByteLength} rejects negative zero. */
|
|
1436
|
+
export interface ByteLengthError extends TypeError<"ByteLength"> {
|
|
1437
|
+
readonly value: number;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
const Digit0To1 = /*#__PURE__*/ union("0", "1");
|
|
1441
|
+
const Digit0To3 = /*#__PURE__*/ union("0", "1", "2", "3");
|
|
1442
|
+
|
|
1443
|
+
// Keep these annotations concrete. Generic unit wrappers add thousands of
|
|
1444
|
+
// compiler instantiations to pnpm bench:type.
|
|
1445
|
+
/** Bytes: `"0B"` to `"1023B"`. See {@link ByteSizeLiteral}. */
|
|
1446
|
+
export const ByteSizeLiteralBytes: UnionType<
|
|
1447
|
+
readonly [
|
|
1448
|
+
TemplateLiteralType<readonly [typeof Digit, "B"]>,
|
|
1449
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "B"]>,
|
|
1450
|
+
TemplateLiteralType<
|
|
1451
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, "B"]
|
|
1452
|
+
>,
|
|
1453
|
+
TemplateLiteralType<
|
|
1454
|
+
readonly [
|
|
1455
|
+
"10",
|
|
1456
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1457
|
+
typeof Digit,
|
|
1458
|
+
"B",
|
|
1459
|
+
]
|
|
1460
|
+
>,
|
|
1461
|
+
TemplateLiteralType<
|
|
1462
|
+
readonly [
|
|
1463
|
+
"102",
|
|
1464
|
+
UnionType<
|
|
1465
|
+
readonly [
|
|
1466
|
+
LiteralType<"0">,
|
|
1467
|
+
LiteralType<"1">,
|
|
1468
|
+
LiteralType<"2">,
|
|
1469
|
+
LiteralType<"3">,
|
|
1470
|
+
]
|
|
1471
|
+
>,
|
|
1472
|
+
"B",
|
|
1473
|
+
]
|
|
1474
|
+
>,
|
|
1475
|
+
]
|
|
1476
|
+
> = /*#__PURE__*/ union(
|
|
1477
|
+
/*#__PURE__*/ templateLiteral(Digit, "B"),
|
|
1478
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, "B"),
|
|
1479
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "B"),
|
|
1480
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, "B"),
|
|
1481
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, "B"),
|
|
1482
|
+
);
|
|
1483
|
+
export type ByteSizeLiteralBytes = typeof ByteSizeLiteralBytes.Output;
|
|
1484
|
+
|
|
1485
|
+
/**
|
|
1486
|
+
* KiB: `"1KiB"` to `"1023KiB"` or `"1.5KiB"` to `"1023.5KiB"`. See
|
|
1487
|
+
* {@link ByteSizeLiteral}.
|
|
1488
|
+
*/
|
|
1489
|
+
export const ByteSizeLiteralKiB: UnionType<
|
|
1490
|
+
readonly [
|
|
1491
|
+
TemplateLiteralType<readonly [typeof Digit1To9, "KiB"]>,
|
|
1492
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "KiB"]>,
|
|
1493
|
+
TemplateLiteralType<
|
|
1494
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, "KiB"]
|
|
1495
|
+
>,
|
|
1496
|
+
TemplateLiteralType<
|
|
1497
|
+
readonly [
|
|
1498
|
+
"10",
|
|
1499
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1500
|
+
typeof Digit,
|
|
1501
|
+
"KiB",
|
|
1502
|
+
]
|
|
1503
|
+
>,
|
|
1504
|
+
TemplateLiteralType<
|
|
1505
|
+
readonly [
|
|
1506
|
+
"102",
|
|
1507
|
+
UnionType<
|
|
1508
|
+
readonly [
|
|
1509
|
+
LiteralType<"0">,
|
|
1510
|
+
LiteralType<"1">,
|
|
1511
|
+
LiteralType<"2">,
|
|
1512
|
+
LiteralType<"3">,
|
|
1513
|
+
]
|
|
1514
|
+
>,
|
|
1515
|
+
"KiB",
|
|
1516
|
+
]
|
|
1517
|
+
>,
|
|
1518
|
+
TemplateLiteralType<readonly [typeof Digit1To9, ".5KiB"]>,
|
|
1519
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, ".5KiB"]>,
|
|
1520
|
+
TemplateLiteralType<
|
|
1521
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, ".5KiB"]
|
|
1522
|
+
>,
|
|
1523
|
+
TemplateLiteralType<
|
|
1524
|
+
readonly [
|
|
1525
|
+
"10",
|
|
1526
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1527
|
+
typeof Digit,
|
|
1528
|
+
".5KiB",
|
|
1529
|
+
]
|
|
1530
|
+
>,
|
|
1531
|
+
TemplateLiteralType<
|
|
1532
|
+
readonly [
|
|
1533
|
+
"102",
|
|
1534
|
+
UnionType<
|
|
1535
|
+
readonly [
|
|
1536
|
+
LiteralType<"0">,
|
|
1537
|
+
LiteralType<"1">,
|
|
1538
|
+
LiteralType<"2">,
|
|
1539
|
+
LiteralType<"3">,
|
|
1540
|
+
]
|
|
1541
|
+
>,
|
|
1542
|
+
".5KiB",
|
|
1543
|
+
]
|
|
1544
|
+
>,
|
|
1545
|
+
]
|
|
1546
|
+
> = /*#__PURE__*/ union(
|
|
1547
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, "KiB"),
|
|
1548
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, "KiB"),
|
|
1549
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "KiB"),
|
|
1550
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, "KiB"),
|
|
1551
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, "KiB"),
|
|
1552
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, ".5KiB"),
|
|
1553
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, ".5KiB"),
|
|
1554
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, ".5KiB"),
|
|
1555
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, ".5KiB"),
|
|
1556
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, ".5KiB"),
|
|
1557
|
+
);
|
|
1558
|
+
export type ByteSizeLiteralKiB = typeof ByteSizeLiteralKiB.Output;
|
|
1559
|
+
|
|
1560
|
+
/**
|
|
1561
|
+
* MiB: `"1MiB"` to `"1023MiB"` or `"1.5MiB"` to `"1023.5MiB"`. See
|
|
1562
|
+
* {@link ByteSizeLiteral}.
|
|
1563
|
+
*/
|
|
1564
|
+
export const ByteSizeLiteralMiB: UnionType<
|
|
1565
|
+
readonly [
|
|
1566
|
+
TemplateLiteralType<readonly [typeof Digit1To9, "MiB"]>,
|
|
1567
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "MiB"]>,
|
|
1568
|
+
TemplateLiteralType<
|
|
1569
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, "MiB"]
|
|
1570
|
+
>,
|
|
1571
|
+
TemplateLiteralType<
|
|
1572
|
+
readonly [
|
|
1573
|
+
"10",
|
|
1574
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1575
|
+
typeof Digit,
|
|
1576
|
+
"MiB",
|
|
1577
|
+
]
|
|
1578
|
+
>,
|
|
1579
|
+
TemplateLiteralType<
|
|
1580
|
+
readonly [
|
|
1581
|
+
"102",
|
|
1582
|
+
UnionType<
|
|
1583
|
+
readonly [
|
|
1584
|
+
LiteralType<"0">,
|
|
1585
|
+
LiteralType<"1">,
|
|
1586
|
+
LiteralType<"2">,
|
|
1587
|
+
LiteralType<"3">,
|
|
1588
|
+
]
|
|
1589
|
+
>,
|
|
1590
|
+
"MiB",
|
|
1591
|
+
]
|
|
1592
|
+
>,
|
|
1593
|
+
TemplateLiteralType<readonly [typeof Digit1To9, ".5MiB"]>,
|
|
1594
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, ".5MiB"]>,
|
|
1595
|
+
TemplateLiteralType<
|
|
1596
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, ".5MiB"]
|
|
1597
|
+
>,
|
|
1598
|
+
TemplateLiteralType<
|
|
1599
|
+
readonly [
|
|
1600
|
+
"10",
|
|
1601
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1602
|
+
typeof Digit,
|
|
1603
|
+
".5MiB",
|
|
1604
|
+
]
|
|
1605
|
+
>,
|
|
1606
|
+
TemplateLiteralType<
|
|
1607
|
+
readonly [
|
|
1608
|
+
"102",
|
|
1609
|
+
UnionType<
|
|
1610
|
+
readonly [
|
|
1611
|
+
LiteralType<"0">,
|
|
1612
|
+
LiteralType<"1">,
|
|
1613
|
+
LiteralType<"2">,
|
|
1614
|
+
LiteralType<"3">,
|
|
1615
|
+
]
|
|
1616
|
+
>,
|
|
1617
|
+
".5MiB",
|
|
1618
|
+
]
|
|
1619
|
+
>,
|
|
1620
|
+
]
|
|
1621
|
+
> = /*#__PURE__*/ union(
|
|
1622
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, "MiB"),
|
|
1623
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, "MiB"),
|
|
1624
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "MiB"),
|
|
1625
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, "MiB"),
|
|
1626
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, "MiB"),
|
|
1627
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, ".5MiB"),
|
|
1628
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, ".5MiB"),
|
|
1629
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, ".5MiB"),
|
|
1630
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, ".5MiB"),
|
|
1631
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, ".5MiB"),
|
|
1632
|
+
);
|
|
1633
|
+
export type ByteSizeLiteralMiB = typeof ByteSizeLiteralMiB.Output;
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* GiB: `"1GiB"` to `"1023GiB"` or `"1.5GiB"` to `"1023.5GiB"`. See
|
|
1637
|
+
* {@link ByteSizeLiteral}.
|
|
1638
|
+
*/
|
|
1639
|
+
export const ByteSizeLiteralGiB: UnionType<
|
|
1640
|
+
readonly [
|
|
1641
|
+
TemplateLiteralType<readonly [typeof Digit1To9, "GiB"]>,
|
|
1642
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "GiB"]>,
|
|
1643
|
+
TemplateLiteralType<
|
|
1644
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, "GiB"]
|
|
1645
|
+
>,
|
|
1646
|
+
TemplateLiteralType<
|
|
1647
|
+
readonly [
|
|
1648
|
+
"10",
|
|
1649
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1650
|
+
typeof Digit,
|
|
1651
|
+
"GiB",
|
|
1652
|
+
]
|
|
1653
|
+
>,
|
|
1654
|
+
TemplateLiteralType<
|
|
1655
|
+
readonly [
|
|
1656
|
+
"102",
|
|
1657
|
+
UnionType<
|
|
1658
|
+
readonly [
|
|
1659
|
+
LiteralType<"0">,
|
|
1660
|
+
LiteralType<"1">,
|
|
1661
|
+
LiteralType<"2">,
|
|
1662
|
+
LiteralType<"3">,
|
|
1663
|
+
]
|
|
1664
|
+
>,
|
|
1665
|
+
"GiB",
|
|
1666
|
+
]
|
|
1667
|
+
>,
|
|
1668
|
+
TemplateLiteralType<readonly [typeof Digit1To9, ".5GiB"]>,
|
|
1669
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, ".5GiB"]>,
|
|
1670
|
+
TemplateLiteralType<
|
|
1671
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, ".5GiB"]
|
|
1672
|
+
>,
|
|
1673
|
+
TemplateLiteralType<
|
|
1674
|
+
readonly [
|
|
1675
|
+
"10",
|
|
1676
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1677
|
+
typeof Digit,
|
|
1678
|
+
".5GiB",
|
|
1679
|
+
]
|
|
1680
|
+
>,
|
|
1681
|
+
TemplateLiteralType<
|
|
1682
|
+
readonly [
|
|
1683
|
+
"102",
|
|
1684
|
+
UnionType<
|
|
1685
|
+
readonly [
|
|
1686
|
+
LiteralType<"0">,
|
|
1687
|
+
LiteralType<"1">,
|
|
1688
|
+
LiteralType<"2">,
|
|
1689
|
+
LiteralType<"3">,
|
|
1690
|
+
]
|
|
1691
|
+
>,
|
|
1692
|
+
".5GiB",
|
|
1693
|
+
]
|
|
1694
|
+
>,
|
|
1695
|
+
]
|
|
1696
|
+
> = /*#__PURE__*/ union(
|
|
1697
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, "GiB"),
|
|
1698
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, "GiB"),
|
|
1699
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "GiB"),
|
|
1700
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, "GiB"),
|
|
1701
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, "GiB"),
|
|
1702
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, ".5GiB"),
|
|
1703
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, ".5GiB"),
|
|
1704
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, ".5GiB"),
|
|
1705
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, ".5GiB"),
|
|
1706
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, ".5GiB"),
|
|
1707
|
+
);
|
|
1708
|
+
export type ByteSizeLiteralGiB = typeof ByteSizeLiteralGiB.Output;
|
|
1709
|
+
|
|
1710
|
+
/**
|
|
1711
|
+
* TiB: `"1TiB"` to `"1023TiB"` or `"1.5TiB"` to `"1023.5TiB"`. See
|
|
1712
|
+
* {@link ByteSizeLiteral}.
|
|
1713
|
+
*/
|
|
1714
|
+
export const ByteSizeLiteralTiB: UnionType<
|
|
1715
|
+
readonly [
|
|
1716
|
+
TemplateLiteralType<readonly [typeof Digit1To9, "TiB"]>,
|
|
1717
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, "TiB"]>,
|
|
1718
|
+
TemplateLiteralType<
|
|
1719
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, "TiB"]
|
|
1720
|
+
>,
|
|
1721
|
+
TemplateLiteralType<
|
|
1722
|
+
readonly [
|
|
1723
|
+
"10",
|
|
1724
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1725
|
+
typeof Digit,
|
|
1726
|
+
"TiB",
|
|
1727
|
+
]
|
|
1728
|
+
>,
|
|
1729
|
+
TemplateLiteralType<
|
|
1730
|
+
readonly [
|
|
1731
|
+
"102",
|
|
1732
|
+
UnionType<
|
|
1733
|
+
readonly [
|
|
1734
|
+
LiteralType<"0">,
|
|
1735
|
+
LiteralType<"1">,
|
|
1736
|
+
LiteralType<"2">,
|
|
1737
|
+
LiteralType<"3">,
|
|
1738
|
+
]
|
|
1739
|
+
>,
|
|
1740
|
+
"TiB",
|
|
1741
|
+
]
|
|
1742
|
+
>,
|
|
1743
|
+
TemplateLiteralType<readonly [typeof Digit1To9, ".5TiB"]>,
|
|
1744
|
+
TemplateLiteralType<readonly [typeof Digit1To9, typeof Digit, ".5TiB"]>,
|
|
1745
|
+
TemplateLiteralType<
|
|
1746
|
+
readonly [typeof Digit1To9, typeof Digit, typeof Digit, ".5TiB"]
|
|
1747
|
+
>,
|
|
1748
|
+
TemplateLiteralType<
|
|
1749
|
+
readonly [
|
|
1750
|
+
"10",
|
|
1751
|
+
UnionType<readonly [LiteralType<"0">, LiteralType<"1">]>,
|
|
1752
|
+
typeof Digit,
|
|
1753
|
+
".5TiB",
|
|
1754
|
+
]
|
|
1755
|
+
>,
|
|
1756
|
+
TemplateLiteralType<
|
|
1757
|
+
readonly [
|
|
1758
|
+
"102",
|
|
1759
|
+
UnionType<
|
|
1760
|
+
readonly [
|
|
1761
|
+
LiteralType<"0">,
|
|
1762
|
+
LiteralType<"1">,
|
|
1763
|
+
LiteralType<"2">,
|
|
1764
|
+
LiteralType<"3">,
|
|
1765
|
+
]
|
|
1766
|
+
>,
|
|
1767
|
+
".5TiB",
|
|
1768
|
+
]
|
|
1769
|
+
>,
|
|
1770
|
+
]
|
|
1771
|
+
> = /*#__PURE__*/ union(
|
|
1772
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, "TiB"),
|
|
1773
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, "TiB"),
|
|
1774
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, "TiB"),
|
|
1775
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, "TiB"),
|
|
1776
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, "TiB"),
|
|
1777
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, ".5TiB"),
|
|
1778
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, ".5TiB"),
|
|
1779
|
+
/*#__PURE__*/ templateLiteral(Digit1To9, Digit, Digit, ".5TiB"),
|
|
1780
|
+
/*#__PURE__*/ templateLiteral("10", Digit0To1, Digit, ".5TiB"),
|
|
1781
|
+
/*#__PURE__*/ templateLiteral("102", Digit0To3, ".5TiB"),
|
|
1782
|
+
);
|
|
1783
|
+
export type ByteSizeLiteralTiB = typeof ByteSizeLiteralTiB.Output;
|
|
1784
|
+
|
|
1785
|
+
export type ByteSizeLiteral =
|
|
1786
|
+
| ByteSizeLiteralBytes
|
|
1787
|
+
| ByteSizeLiteralKiB
|
|
1788
|
+
| ByteSizeLiteralMiB
|
|
1789
|
+
| ByteSizeLiteralGiB
|
|
1790
|
+
| ByteSizeLiteralTiB;
|
|
1791
|
+
|
|
1792
|
+
const byteSizeLiteralSyntax = /*#__PURE__*/ union(
|
|
1793
|
+
ByteSizeLiteralBytes,
|
|
1794
|
+
ByteSizeLiteralKiB,
|
|
1795
|
+
ByteSizeLiteralMiB,
|
|
1796
|
+
ByteSizeLiteralGiB,
|
|
1797
|
+
ByteSizeLiteralTiB,
|
|
1798
|
+
);
|
|
1799
|
+
|
|
1800
|
+
/**
|
|
1801
|
+
* Byte length literal Type with compile-time and runtime validation.
|
|
1802
|
+
*
|
|
1803
|
+
* Supported formats:
|
|
1804
|
+
*
|
|
1805
|
+
* - Bytes: `0B` to `1023B`
|
|
1806
|
+
* - KiB: `1KiB` to `1023KiB` or `1.5KiB` to `1023.5KiB`
|
|
1807
|
+
* - MiB: `1MiB` to `1023MiB` or `1.5MiB` to `1023.5MiB`
|
|
1808
|
+
* - GiB: `1GiB` to `1023GiB` or `1.5GiB` to `1023.5GiB`
|
|
1809
|
+
* - TiB: `1TiB` to `1023TiB` or `1.5TiB` to `1023.5TiB`
|
|
1810
|
+
*
|
|
1811
|
+
* Units are the binary ones defined by IEC, named kibibyte (`KiB`, 1024 bytes),
|
|
1812
|
+
* mebibyte (`MiB`), gibibyte (`GiB`), and tebibyte (`TiB`), each 1024 times the
|
|
1813
|
+
* previous. Memory, storage quotas, and caches are measured in them. The
|
|
1814
|
+
* familiar `MB` is ambiguous: SI defines it as a million bytes, storage vendors
|
|
1815
|
+
* use that meaning, and most software uses 1048576 instead, which is why a "1
|
|
1816
|
+
* TB" drive shows as 931 "GB". `MiB` has only one meaning, so a literal never
|
|
1817
|
+
* depends on a convention.
|
|
1818
|
+
*
|
|
1819
|
+
* Each unit is bounded below 1024, so equivalent representations are avoided:
|
|
1820
|
+
* `1024KiB` must be written as `"1MiB"`. A half is the only decimal allowed,
|
|
1821
|
+
* because it is the only single decimal digit that is exact in every binary
|
|
1822
|
+
* unit; `1.1KiB` would be 1126.4 bytes. For other exact values, use
|
|
1823
|
+
* {@link ByteLength} directly.
|
|
1824
|
+
*
|
|
1825
|
+
* See {@link ByteSize} for a type that also accepts {@link ByteLength}. Use
|
|
1826
|
+
* {@link byteSizeToByteLength} to convert.
|
|
1827
|
+
*
|
|
1828
|
+
* Invalid values produce a {@link ByteSizeLiteralError}.
|
|
1829
|
+
*
|
|
1830
|
+
* ### Example
|
|
1831
|
+
*
|
|
1832
|
+
* ```ts
|
|
1833
|
+
* import {
|
|
1834
|
+
* assertEqual,
|
|
1835
|
+
* assertErr,
|
|
1836
|
+
* assertFalse,
|
|
1837
|
+
* assertOk,
|
|
1838
|
+
* assertType,
|
|
1839
|
+
* ByteSizeLiteral,
|
|
1840
|
+
* } from "@evolu/common";
|
|
1841
|
+
*
|
|
1842
|
+
* // The TypeScript type accepts valid spellings and rejects the rest.
|
|
1843
|
+
* const literal: ByteSizeLiteral = "1023MiB";
|
|
1844
|
+
* assertType<
|
|
1845
|
+
* Extract<ByteSizeLiteral, "1024KiB" | "1.1KiB" | "1MB">,
|
|
1846
|
+
* never
|
|
1847
|
+
* >();
|
|
1848
|
+
*
|
|
1849
|
+
* // The runtime Type validates the same grammar.
|
|
1850
|
+
* assertOk(ByteSizeLiteral.fromUnknown(literal), "1023MiB");
|
|
1851
|
+
* assertFalse(ByteSizeLiteral.is("1024KiB"));
|
|
1852
|
+
*
|
|
1853
|
+
* const invalid = ByteSizeLiteral.fromUnknown("1MB");
|
|
1854
|
+
* assertErr(invalid);
|
|
1855
|
+
* assertEqual(invalid.error.type, "ByteSizeLiteral");
|
|
1856
|
+
* assertEqual(
|
|
1857
|
+
* ByteSizeLiteral.formatError(invalid.error),
|
|
1858
|
+
* 'The value "1MB" is not a byte-size literal. Use a value such as "512KiB" or "1MiB".',
|
|
1859
|
+
* );
|
|
1860
|
+
* ```
|
|
1861
|
+
*/
|
|
1862
|
+
export const ByteSizeLiteral: Type<
|
|
1863
|
+
"ByteSizeLiteral",
|
|
1864
|
+
ByteSizeLiteral,
|
|
1865
|
+
ByteSizeLiteral,
|
|
1866
|
+
ByteSizeLiteralError
|
|
1867
|
+
> = /*#__PURE__*/ createTypeWithError(
|
|
1868
|
+
"ByteSizeLiteral",
|
|
1869
|
+
byteSizeLiteralSyntax,
|
|
1870
|
+
(cause, value): ByteSizeLiteralError => ({
|
|
1871
|
+
type: "ByteSizeLiteral",
|
|
1872
|
+
value,
|
|
1873
|
+
cause,
|
|
1874
|
+
}),
|
|
1875
|
+
(error) =>
|
|
1876
|
+
`The value ${safelyStringifyUnknownValue(error.value)} is not a byte-size literal. Use a value such as "512KiB" or "1MiB".`,
|
|
1877
|
+
);
|
|
1878
|
+
|
|
1879
|
+
/** Error returned when {@link ByteSizeLiteral} rejects a value. */
|
|
1880
|
+
export interface ByteSizeLiteralError extends TypeError<"ByteSizeLiteral"> {
|
|
1881
|
+
readonly value: unknown;
|
|
1882
|
+
/**
|
|
1883
|
+
* The underlying union failure, retained for diagnostics.
|
|
1884
|
+
*
|
|
1885
|
+
* With `{ errors: "all" }`, includes every failed alternative.
|
|
1886
|
+
*/
|
|
1887
|
+
readonly cause: UnionError;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
/**
|
|
1891
|
+
* {@link ByteSizeLiteral} or {@link ByteLength}.
|
|
1892
|
+
*
|
|
1893
|
+
* Convenience input accepting a human-readable {@link ByteSizeLiteral} or a
|
|
1894
|
+
* validated {@link ByteLength} for values that no literal expresses. APIs
|
|
1895
|
+
* normalize it with {@link byteSizeToByteLength}.
|
|
1896
|
+
*
|
|
1897
|
+
* ### Example
|
|
1898
|
+
*
|
|
1899
|
+
* ```ts
|
|
1900
|
+
* import {
|
|
1901
|
+
* assertEqual,
|
|
1902
|
+
* ByteLength,
|
|
1903
|
+
* byteSizeToByteLength,
|
|
1904
|
+
* type ByteSize,
|
|
1905
|
+
* } from "@evolu/common";
|
|
1906
|
+
*
|
|
1907
|
+
* const literal: ByteSize = "1MiB";
|
|
1908
|
+
* const validated: ByteSize = ByteLength.orThrow(1000000);
|
|
1909
|
+
*
|
|
1910
|
+
* assertEqual(byteSizeToByteLength(literal), 1048576);
|
|
1911
|
+
* assertEqual(byteSizeToByteLength(validated), 1000000);
|
|
1912
|
+
* ```
|
|
1913
|
+
*/
|
|
1914
|
+
export type ByteSize = ByteSizeLiteral | ByteLength;
|
|
1915
|
+
|
|
1916
|
+
const bytesByByteLengthUnit = {
|
|
1917
|
+
B: 1,
|
|
1918
|
+
KiB: 1024,
|
|
1919
|
+
MiB: 1024 ** 2,
|
|
1920
|
+
GiB: 1024 ** 3,
|
|
1921
|
+
TiB: 1024 ** 4,
|
|
1922
|
+
};
|
|
1923
|
+
|
|
1924
|
+
/**
|
|
1925
|
+
* Converts a {@link ByteSize} to a {@link ByteLength}. A {@link ByteLength} is
|
|
1926
|
+
* returned unchanged.
|
|
1927
|
+
*
|
|
1928
|
+
* ### Example
|
|
1929
|
+
*
|
|
1930
|
+
* ```ts
|
|
1931
|
+
* import { assertEqual, byteSizeToByteLength } from "@evolu/common";
|
|
1932
|
+
*
|
|
1933
|
+
* assertEqual(byteSizeToByteLength("0B"), 0);
|
|
1934
|
+
* assertEqual(byteSizeToByteLength("2KiB"), 2048);
|
|
1935
|
+
* assertEqual(byteSizeToByteLength("1GiB"), 1073741824);
|
|
1936
|
+
* ```
|
|
1937
|
+
*/
|
|
1938
|
+
export const byteSizeToByteLength = (value: ByteSize): ByteLength => {
|
|
1939
|
+
if (typeof value === "number") return value;
|
|
1940
|
+
|
|
1941
|
+
const unit = value.endsWith("iB") ? value.slice(-3) : "B";
|
|
1942
|
+
assert(unit in bytesByByteLengthUnit, `Unknown byte length unit: ${unit}`);
|
|
1943
|
+
|
|
1944
|
+
return ByteLength.orThrow(
|
|
1945
|
+
Number.parseFloat(value) *
|
|
1946
|
+
bytesByByteLengthUnit[unit as keyof typeof bytesByByteLengthUnit],
|
|
1947
|
+
);
|
|
1948
|
+
};
|
|
1949
|
+
|
|
1950
|
+
/**
|
|
1951
|
+
* Error returned when a string is neither a number of bytes nor a
|
|
1952
|
+
* {@link ByteSizeLiteral}.
|
|
1953
|
+
*/
|
|
1954
|
+
export interface ByteLengthFromStringError extends TypeError<"ByteLengthFromString"> {
|
|
1955
|
+
readonly value: string;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
/**
|
|
1959
|
+
* Transforms a number of bytes or a {@link ByteSizeLiteral} in text into a
|
|
1960
|
+
* {@link ByteLength}.
|
|
1961
|
+
*
|
|
1962
|
+
* This is useful for inputs that carry sizes as text, such as environment
|
|
1963
|
+
* variables and configuration files, where `"10MiB"` reads better than
|
|
1964
|
+
* `"10485760"`. Encoding produces the number of bytes.
|
|
1965
|
+
*
|
|
1966
|
+
* ### Example
|
|
1967
|
+
*
|
|
1968
|
+
* ```ts
|
|
1969
|
+
* import {
|
|
1970
|
+
* assertEqual,
|
|
1971
|
+
* assertErr,
|
|
1972
|
+
* assertOk,
|
|
1973
|
+
* ByteLengthFromString,
|
|
1974
|
+
* } from "@evolu/common";
|
|
1975
|
+
*
|
|
1976
|
+
* assertOk(ByteLengthFromString.fromUnknown("10MiB"), 10485760);
|
|
1977
|
+
* assertOk(ByteLengthFromString.fromUnknown("1048576"), 1048576);
|
|
1978
|
+
* assertEqual(
|
|
1979
|
+
* ByteLengthFromString.to(ByteLengthFromString.orThrow("1KiB")),
|
|
1980
|
+
* "1024",
|
|
1981
|
+
* );
|
|
1982
|
+
*
|
|
1983
|
+
* const invalid = ByteLengthFromString.fromUnknown("10MB");
|
|
1984
|
+
* assertErr(invalid, { type: "ByteLengthFromString", value: "10MB" });
|
|
1985
|
+
* assertEqual(
|
|
1986
|
+
* ByteLengthFromString.formatError(invalid.error),
|
|
1987
|
+
* 'The value "10MB" is not a byte length. Use a number of bytes or a literal such as 10MiB.',
|
|
1988
|
+
* );
|
|
1989
|
+
* ```
|
|
1990
|
+
*/
|
|
1991
|
+
export const ByteLengthFromString = /*#__PURE__*/ transform(
|
|
1992
|
+
"ByteLengthFromString",
|
|
1993
|
+
String,
|
|
1994
|
+
ByteLength,
|
|
1995
|
+
{
|
|
1996
|
+
from: (value): Result<number, ByteLengthFromStringError> => {
|
|
1997
|
+
if (ByteSizeLiteral.is(value)) return ok(byteSizeToByteLength(value));
|
|
1998
|
+
if (/^\d+$/u.test(value)) {
|
|
1999
|
+
const number = Number(value);
|
|
2000
|
+
if (Number.isSafeInteger(number)) return ok(number);
|
|
2001
|
+
}
|
|
2002
|
+
return err({ type: "ByteLengthFromString", value });
|
|
2003
|
+
},
|
|
2004
|
+
to: (value) => globalThis.String(value),
|
|
2005
|
+
},
|
|
2006
|
+
(error) =>
|
|
2007
|
+
`The value ${safelyStringifyUnknownValue(error.value)} is not a byte length. Use a number of bytes or a literal such as 10MiB.`,
|
|
2008
|
+
);
|