@synnaxlabs/x 0.42.3 → 0.43.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/.turbo/turbo-build.log +93 -105
- package/.vscode/settings.json +4 -6
- package/README.md +1 -7
- package/dist/array.cjs +1 -0
- package/dist/array.js +7 -0
- package/dist/base-B5lQIJKc.js +38 -0
- package/dist/base-CTq-lhpU.cjs +1 -0
- package/dist/binary.cjs +1 -1
- package/dist/binary.js +1 -1
- package/dist/bounds.cjs +1 -1
- package/dist/bounds.js +2 -2
- package/dist/box.cjs +1 -1
- package/dist/box.js +1 -1
- package/dist/caseconv.cjs +1 -1
- package/dist/caseconv.js +2 -2
- package/dist/change.cjs +1 -1
- package/dist/change.js +10 -2
- package/dist/compare.cjs +1 -1
- package/dist/compare.js +1 -1
- package/dist/deep.cjs +1 -1
- package/dist/deep.js +92 -79
- package/dist/dimensions.cjs +1 -1
- package/dist/dimensions.js +41 -2
- package/dist/direction.cjs +1 -1
- package/dist/direction.js +1 -1
- package/dist/index-4GlOgZuh.js +99 -0
- package/dist/{direction-C-b6XTeU.cjs → index-B58dnYRu.cjs} +1 -1
- package/dist/index-BMGaoK93.cjs +1 -0
- package/dist/index-BTet04Hd.cjs +6 -0
- package/dist/{scale-DfJe9755.js → index-BUa-NXAX.js} +46 -46
- package/dist/{xy-D_LqxaGt.js → index-C-qYOegc.js} +62 -62
- package/dist/index-C07SBJhr.js +128 -0
- package/dist/{bounds-Bn5_l4Z3.js → index-C9EdKeu1.js} +77 -76
- package/dist/index-CM8ZDZ6s.cjs +1 -0
- package/dist/index-CV2JaHfw.cjs +1 -0
- package/dist/index-CeBvOwG8.cjs +3 -0
- package/dist/index-ClrGyGDp.js +205 -0
- package/dist/index-CqQXXeCI.cjs +1 -0
- package/dist/{location-C3aeu046.js → index-D6V-8SKw.js} +26 -26
- package/dist/index-DBGAIs_7.js +2492 -0
- package/dist/index-DEdq2tza.cjs +1 -0
- package/dist/index-DKMnHBGR.cjs +1 -0
- package/dist/index-Dql5FMcH.js +47 -0
- package/dist/{direction-BL0PhD1k.js → index-DxU1zwsd.js} +1 -1
- package/dist/index-WwMnwoLy.cjs +1 -0
- package/dist/index.cjs +5 -3
- package/dist/index.js +5372 -650
- package/dist/kv.cjs +1 -1
- package/dist/kv.js +45 -2
- package/dist/location.cjs +1 -1
- package/dist/location.js +1 -1
- package/dist/position.cjs +1 -1
- package/dist/position.js +83 -2
- package/dist/record.cjs +1 -1
- package/dist/record.js +8 -10
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +27 -2
- package/dist/scale.cjs +1 -1
- package/dist/scale.js +1 -1
- package/dist/schemas-55Usj0Fg.js +3998 -0
- package/dist/schemas-DbXuI2Qr.cjs +27 -0
- package/dist/spatial.cjs +1 -1
- package/dist/spatial.js +25 -18
- package/dist/src/array/index.d.ts +2 -0
- package/dist/src/array/index.d.ts.map +1 -0
- package/dist/src/array/toArray.d.ts +19 -0
- package/dist/src/array/toArray.d.ts.map +1 -0
- package/dist/src/array/toArray.spec.d.ts +2 -0
- package/dist/src/array/toArray.spec.d.ts.map +1 -0
- package/dist/src/binary/codec.d.ts +8 -16
- package/dist/src/binary/codec.d.ts.map +1 -1
- package/dist/src/breaker/breaker.d.ts +6 -6
- package/dist/src/breaker/breaker.d.ts.map +1 -1
- package/dist/src/caseconv/caseconv.d.ts +1 -1
- package/dist/src/caseconv/caseconv.d.ts.map +1 -1
- package/dist/src/change/change.d.ts +3 -3
- package/dist/src/change/change.d.ts.map +1 -1
- package/dist/src/color/color.d.ts +61 -37
- package/dist/src/color/color.d.ts.map +1 -1
- package/dist/src/color/external.d.ts +0 -1
- package/dist/src/color/external.d.ts.map +1 -1
- package/dist/src/color/gradient.d.ts +7 -7
- package/dist/src/color/gradient.d.ts.map +1 -1
- package/dist/src/color/palette.d.ts +10 -10
- package/dist/src/color/palette.d.ts.map +1 -1
- package/dist/src/compare/compare.d.ts +4 -4
- package/dist/src/compare/compare.d.ts.map +1 -1
- package/dist/src/control/control.d.ts +32 -32
- package/dist/src/control/control.d.ts.map +1 -1
- package/dist/src/debounce/debounce.d.ts +1 -1
- package/dist/src/debounce/debounce.d.ts.map +1 -1
- package/dist/src/deep/delete.d.ts +1 -1
- package/dist/src/deep/delete.d.ts.map +1 -1
- package/dist/src/deep/difference.d.ts.map +1 -1
- package/dist/src/deep/equal.d.ts +4 -4
- package/dist/src/deep/equal.d.ts.map +1 -1
- package/dist/src/deep/merge.d.ts +1 -1
- package/dist/src/deep/merge.d.ts.map +1 -1
- package/dist/src/errors/errors.d.ts +62 -36
- package/dist/src/errors/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/instance/index.d.ts +2 -0
- package/dist/src/instance/index.d.ts.map +1 -0
- package/dist/src/instance/matcher.d.ts +79 -0
- package/dist/src/instance/matcher.d.ts.map +1 -0
- package/dist/src/instance/matcher.spec.d.ts +2 -0
- package/dist/src/instance/matcher.spec.d.ts.map +1 -0
- package/dist/src/jsonrpc/jsonrpc.d.ts +40 -9
- package/dist/src/jsonrpc/jsonrpc.d.ts.map +1 -1
- package/dist/src/kv/types.d.ts +2 -2
- package/dist/src/kv/types.d.ts.map +1 -1
- package/dist/src/migrate/migrate.d.ts +5 -5
- package/dist/src/migrate/migrate.d.ts.map +1 -1
- package/dist/src/notation/notation.d.ts +1 -1
- package/dist/src/notation/notation.d.ts.map +1 -1
- package/dist/src/primitive/index.d.ts +2 -0
- package/dist/src/primitive/index.d.ts.map +1 -0
- package/dist/src/primitive/primitive.d.ts +39 -0
- package/dist/src/primitive/primitive.d.ts.map +1 -0
- package/dist/src/primitive/primitive.spec.d.ts +2 -0
- package/dist/src/primitive/primitive.spec.d.ts.map +1 -0
- package/dist/src/record.d.ts +2 -2
- package/dist/src/record.d.ts.map +1 -1
- package/dist/src/renderable.d.ts +1 -1
- package/dist/src/renderable.d.ts.map +1 -1
- package/dist/src/replace.d.ts.map +1 -1
- package/dist/src/runtime/detect.d.ts.map +1 -1
- package/dist/src/runtime/os.d.ts +1 -1
- package/dist/src/runtime/os.d.ts.map +1 -1
- package/dist/src/spatial/base.d.ts +10 -10
- package/dist/src/spatial/base.d.ts.map +1 -1
- package/dist/src/spatial/bounds/bounds.d.ts +82 -16
- package/dist/src/spatial/bounds/bounds.d.ts.map +1 -1
- package/dist/src/spatial/box/box.d.ts +7 -7
- package/dist/src/spatial/box/box.d.ts.map +1 -1
- package/dist/src/spatial/dimensions/dimensions.d.ts +5 -5
- package/dist/src/spatial/dimensions/dimensions.d.ts.map +1 -1
- package/dist/src/spatial/direction/direction.d.ts +1 -1
- package/dist/src/spatial/location/location.d.ts +4 -4
- package/dist/src/spatial/location/location.d.ts.map +1 -1
- package/dist/src/spatial/scale/scale.d.ts +11 -11
- package/dist/src/spatial/scale/scale.d.ts.map +1 -1
- package/dist/src/spatial/xy/xy.d.ts +5 -5
- package/dist/src/spatial/xy/xy.d.ts.map +1 -1
- package/dist/src/status/index.d.ts +2 -0
- package/dist/src/status/index.d.ts.map +1 -0
- package/dist/src/status/types.d.ts +11 -0
- package/dist/src/status/types.d.ts.map +1 -0
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/mutex.d.ts +0 -1
- package/dist/src/sync/mutex.d.ts.map +1 -1
- package/dist/src/telem/gl.d.ts +1 -1
- package/dist/src/telem/gl.d.ts.map +1 -1
- package/dist/src/telem/series.d.ts +468 -62
- package/dist/src/telem/series.d.ts.map +1 -1
- package/dist/src/telem/telem.d.ts +243 -53
- package/dist/src/telem/telem.d.ts.map +1 -1
- package/dist/src/uuid/index.d.ts +2 -0
- package/dist/src/uuid/index.d.ts.map +1 -0
- package/dist/src/uuid/uuid.d.ts +35 -0
- package/dist/src/uuid/uuid.d.ts.map +1 -0
- package/dist/src/uuid/uuid.spec.d.ts +2 -0
- package/dist/src/uuid/uuid.spec.d.ts.map +1 -0
- package/dist/src/zod/external.d.ts +1 -1
- package/dist/src/zod/external.d.ts.map +1 -1
- package/dist/src/zod/nullToUndefined.d.ts +3 -0
- package/dist/src/zod/nullToUndefined.d.ts.map +1 -0
- package/dist/src/zod/nullToUndefined.spec.d.ts +2 -0
- package/dist/src/zod/nullToUndefined.spec.d.ts.map +1 -0
- package/dist/src/zod/util.d.ts +2 -2
- package/dist/src/zod/util.d.ts.map +1 -1
- package/dist/telem.cjs +1 -1
- package/dist/telem.js +1 -1
- package/dist/xy.cjs +1 -1
- package/dist/xy.js +1 -1
- package/dist/zod.cjs +1 -1
- package/dist/zod.js +19 -2
- package/eslint.config.js +1 -1
- package/package.json +17 -15
- package/src/{toArray.ts → array/index.ts} +1 -5
- package/src/array/toArray.spec.ts +56 -0
- package/src/array/toArray.ts +28 -0
- package/src/binary/codec.spec.ts +201 -278
- package/src/binary/codec.ts +20 -76
- package/src/breaker/breaker.ts +3 -3
- package/src/caseconv/caseconv.ts +6 -4
- package/src/change/change.ts +2 -2
- package/src/color/color.spec.ts +113 -2
- package/src/color/color.ts +89 -59
- package/src/color/external.ts +0 -1
- package/src/color/gradient.ts +20 -28
- package/src/color/palette.ts +1 -1
- package/src/compare/compare.ts +5 -5
- package/src/control/control.ts +22 -19
- package/src/debounce/debounce.ts +1 -1
- package/src/deep/delete.ts +5 -4
- package/src/deep/difference.ts +6 -2
- package/src/deep/equal.spec.ts +1 -1
- package/src/deep/equal.ts +5 -5
- package/src/deep/merge.spec.ts +13 -1
- package/src/deep/merge.ts +16 -7
- package/src/deep/path.ts +1 -1
- package/src/errors/errors.ts +65 -44
- package/src/index.ts +4 -1
- package/src/instance/index.ts +10 -0
- package/src/instance/matcher.spec.ts +78 -0
- package/src/instance/matcher.ts +98 -0
- package/src/jsonrpc/jsonrpc.spec.ts +2 -1
- package/src/jsonrpc/jsonrpc.ts +36 -7
- package/src/kv/types.ts +1 -1
- package/src/migrate/migrate.spec.ts +1 -1
- package/src/migrate/migrate.ts +7 -7
- package/src/notation/notation.ts +1 -1
- package/src/primitive/index.ts +10 -0
- package/src/primitive/primitive.spec.ts +126 -0
- package/src/primitive/primitive.ts +82 -0
- package/src/record.ts +3 -5
- package/src/renderable.ts +1 -1
- package/src/replace.ts +9 -0
- package/src/runtime/detect.ts +0 -2
- package/src/runtime/os.ts +1 -1
- package/src/spatial/base.ts +1 -1
- package/src/spatial/bounds/bounds.spec.ts +20 -0
- package/src/spatial/bounds/bounds.ts +101 -18
- package/src/spatial/box/box.ts +1 -1
- package/src/spatial/dimensions/dimensions.ts +3 -3
- package/src/spatial/location/location.ts +1 -1
- package/src/spatial/scale/scale.ts +1 -1
- package/src/spatial/xy/xy.ts +1 -1
- package/src/status/index.ts +10 -0
- package/src/status/types.ts +22 -0
- package/src/sync/index.ts +9 -0
- package/src/sync/mutex.ts +9 -4
- package/src/telem/gl.ts +1 -1
- package/src/telem/series.spec.ts +735 -68
- package/src/telem/series.ts +536 -195
- package/src/telem/telem.spec.ts +60 -7
- package/src/telem/telem.ts +287 -95
- package/src/uuid/index.ts +10 -0
- package/src/uuid/uuid.spec.ts +82 -0
- package/src/uuid/uuid.ts +48 -0
- package/src/zod/external.ts +1 -1
- package/src/zod/nullToUndefined.spec.ts +31 -0
- package/src/zod/nullToUndefined.ts +23 -0
- package/src/zod/util.spec.ts +1 -1
- package/src/zod/util.ts +6 -6
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +1 -1
- package/dist/base-BAM2mqCy.cjs +0 -1
- package/dist/base-DFq0vvGn.js +0 -38
- package/dist/bounds-BQo7rvs9.cjs +0 -1
- package/dist/box-0YrQibkB.cjs +0 -1
- package/dist/box-Cc8IzcNo.js +0 -205
- package/dist/change-C-YELKx6.cjs +0 -1
- package/dist/change-DLl6DccR.js +0 -12
- package/dist/dimensions-CRgergMS.js +0 -43
- package/dist/dimensions-D2QGoNXO.cjs +0 -1
- package/dist/external-BPgtxa8d.js +0 -29
- package/dist/external-C-dNgNQw.cjs +0 -1
- package/dist/external-C8TFju8Q.js +0 -29
- package/dist/external-DWQITF5_.cjs +0 -1
- package/dist/external-DqPrWKvU.js +0 -47
- package/dist/external-uXk0Avrg.cjs +0 -1
- package/dist/index-BywOGO8U.js +0 -1074
- package/dist/index-CYYjI7Uf.cjs +0 -1
- package/dist/index-C_6NXBlg.cjs +0 -3
- package/dist/index-Dd8DLyMx.cjs +0 -1
- package/dist/index-DizUWH6z.js +0 -47
- package/dist/index-QGplUHuy.js +0 -98
- package/dist/location-BGl5Ddds.cjs +0 -1
- package/dist/position-Cai5-wi1.cjs +0 -1
- package/dist/position-DIglP1l2.js +0 -85
- package/dist/scale-BtZINJ-A.cjs +0 -1
- package/dist/series-B9JERcqi.js +0 -1977
- package/dist/series-DqJ6f97G.cjs +0 -11
- package/dist/spatial-BSWPzMkK.js +0 -11
- package/dist/spatial-DGpZ2sO3.cjs +0 -1
- package/dist/src/color/transformColorsToHex.d.ts +0 -6
- package/dist/src/color/transformColorsToHex.d.ts.map +0 -1
- package/dist/src/primitive.d.ts +0 -9
- package/dist/src/primitive.d.ts.map +0 -1
- package/dist/src/toArray.d.ts +0 -3
- package/dist/src/toArray.d.ts.map +0 -1
- package/dist/src/zod/integer.d.ts +0 -10
- package/dist/src/zod/integer.d.ts.map +0 -1
- package/dist/src/zod/integer.spec.d.ts +0 -2
- package/dist/src/zod/integer.spec.d.ts.map +0 -1
- package/dist/toArray.cjs +0 -1
- package/dist/toArray.js +0 -5
- package/dist/xy-B7065J2S.cjs +0 -1
- package/src/color/transformColorsToHex.ts +0 -30
- package/src/primitive.ts +0 -46
- package/src/zod/integer.spec.ts +0 -148
- package/src/zod/integer.ts +0 -38
package/src/binary/codec.ts
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import { type z } from "zod";
|
|
10
|
+
import { type z } from "zod/v4";
|
|
12
11
|
|
|
13
12
|
import { caseconv } from "@/caseconv";
|
|
14
13
|
import { isObject } from "@/identity";
|
|
@@ -35,10 +34,10 @@ export interface Codec {
|
|
|
35
34
|
* @param data - The data to decode.
|
|
36
35
|
* @param schema - The schema to decode the data with.
|
|
37
36
|
*/
|
|
38
|
-
decode: <P extends z.
|
|
37
|
+
decode: <P extends z.ZodType>(
|
|
39
38
|
data: Uint8Array | ArrayBuffer,
|
|
40
39
|
schema?: P,
|
|
41
|
-
) => z.
|
|
40
|
+
) => z.infer<P>;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
/** JSONCodec is a JSON implementation of Codec. */
|
|
@@ -56,33 +55,24 @@ export class JSONCodec implements Codec {
|
|
|
56
55
|
return this.encoder.encode(this.encodeString(payload));
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
decode<P extends z.
|
|
60
|
-
data: Uint8Array | ArrayBuffer,
|
|
61
|
-
schema?: P,
|
|
62
|
-
): z.output<P> {
|
|
58
|
+
decode<P extends z.ZodType>(data: Uint8Array | ArrayBuffer, schema?: P): z.infer<P> {
|
|
63
59
|
return this.decodeString(this.decoder.decode(data), schema);
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
decodeString<P extends z.
|
|
62
|
+
decodeString<P extends z.ZodType>(data: string, schema?: P): z.infer<P> {
|
|
67
63
|
const parsed = JSON.parse(data);
|
|
68
64
|
const unpacked = caseconv.snakeToCamel(parsed);
|
|
69
|
-
return schema != null ? schema.parse(unpacked) : (unpacked as z.
|
|
65
|
+
return schema != null ? schema.parse(unpacked) : (unpacked as z.infer<P>);
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
encodeString(payload: unknown): string {
|
|
73
69
|
const caseConverted = caseconv.camelToSnake(payload);
|
|
74
70
|
return JSON.stringify(caseConverted, (_, v) => {
|
|
75
71
|
if (ArrayBuffer.isView(v)) return Array.from(v as Uint8Array);
|
|
76
|
-
if (isObject(v) && "encode_value" in v) {
|
|
77
|
-
if (typeof v.value === "bigint") return v.value.toString();
|
|
78
|
-
return v.value;
|
|
79
|
-
}
|
|
80
72
|
if (typeof v === "bigint") return v.toString();
|
|
81
73
|
return v;
|
|
82
74
|
});
|
|
83
75
|
}
|
|
84
|
-
|
|
85
|
-
static registerCustomType(): void {}
|
|
86
76
|
}
|
|
87
77
|
|
|
88
78
|
/**
|
|
@@ -96,10 +86,7 @@ export class CSVCodec implements Codec {
|
|
|
96
86
|
return new TextEncoder().encode(csvString);
|
|
97
87
|
}
|
|
98
88
|
|
|
99
|
-
decode<P extends z.
|
|
100
|
-
data: Uint8Array | ArrayBuffer,
|
|
101
|
-
schema?: P,
|
|
102
|
-
): z.output<P> {
|
|
89
|
+
decode<P extends z.ZodType>(data: Uint8Array | ArrayBuffer, schema?: P): z.infer<P> {
|
|
103
90
|
const csvString = new TextDecoder().decode(data);
|
|
104
91
|
return this.decodeString(csvString, schema);
|
|
105
92
|
}
|
|
@@ -111,7 +98,7 @@ export class CSVCodec implements Codec {
|
|
|
111
98
|
const keys = Object.keys(payload[0]);
|
|
112
99
|
const csvRows = [keys.join(",")];
|
|
113
100
|
|
|
114
|
-
payload.forEach((item
|
|
101
|
+
payload.forEach((item) => {
|
|
115
102
|
const values = keys.map((key) => JSON.stringify(item[key] ?? ""));
|
|
116
103
|
csvRows.push(values.join(","));
|
|
117
104
|
});
|
|
@@ -119,15 +106,15 @@ export class CSVCodec implements Codec {
|
|
|
119
106
|
return csvRows.join("\n");
|
|
120
107
|
}
|
|
121
108
|
|
|
122
|
-
decodeString<P extends z.
|
|
109
|
+
decodeString<P extends z.ZodType>(data: string, schema?: P): z.infer<P> {
|
|
123
110
|
const [headerLine, ...lines] = data
|
|
124
111
|
.trim()
|
|
125
112
|
.split("\n")
|
|
126
113
|
.map((line) => line.trim());
|
|
127
114
|
if (headerLine.length === 0)
|
|
128
|
-
return schema != null ? schema.parse({}) : ({} as z.
|
|
115
|
+
return schema != null ? schema.parse({}) : ({} as z.infer<P>);
|
|
129
116
|
const headers = headerLine.split(",").map((header) => header.trim());
|
|
130
|
-
const result: { [key: string]:
|
|
117
|
+
const result: { [key: string]: unknown[] } = {};
|
|
131
118
|
|
|
132
119
|
headers.forEach((header) => {
|
|
133
120
|
result[header] = [];
|
|
@@ -142,78 +129,35 @@ export class CSVCodec implements Codec {
|
|
|
142
129
|
});
|
|
143
130
|
});
|
|
144
131
|
|
|
145
|
-
return schema != null ? schema.parse(result) : (result as z.
|
|
132
|
+
return schema != null ? schema.parse(result) : (result as z.infer<P>);
|
|
146
133
|
}
|
|
147
134
|
|
|
148
|
-
private parseValue(value?: string):
|
|
135
|
+
private parseValue(value?: string): unknown {
|
|
149
136
|
if (value == null || value.length === 0) return null;
|
|
150
137
|
const num = Number(value);
|
|
151
138
|
if (!isNaN(num)) return num;
|
|
152
139
|
if (value.startsWith('"') && value.endsWith('"')) return value.slice(1, -1);
|
|
153
140
|
return value;
|
|
154
141
|
}
|
|
155
|
-
|
|
156
|
-
static registerCustomType(): void {}
|
|
157
142
|
}
|
|
158
143
|
|
|
159
144
|
export class TextCodec implements Codec {
|
|
160
145
|
contentType = "text/plain";
|
|
161
146
|
|
|
162
147
|
encode(payload: unknown): Uint8Array {
|
|
163
|
-
|
|
148
|
+
if (typeof payload !== "string")
|
|
149
|
+
throw new Error("TextCodec.encode payload must be a string");
|
|
150
|
+
return new TextEncoder().encode(payload);
|
|
164
151
|
}
|
|
165
152
|
|
|
166
|
-
decode<P extends z.
|
|
167
|
-
data: Uint8Array | ArrayBuffer,
|
|
168
|
-
schema?: P,
|
|
169
|
-
): z.output<P> {
|
|
153
|
+
decode<P extends z.ZodType>(data: Uint8Array | ArrayBuffer, schema?: P): z.infer<P> {
|
|
170
154
|
const text = new TextDecoder().decode(data);
|
|
171
|
-
return schema != null ? schema.parse(text) : (text as z.
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const extensionCodec = new ExtensionCodec();
|
|
176
|
-
|
|
177
|
-
extensionCodec.register({
|
|
178
|
-
type: 0,
|
|
179
|
-
encode: (value: unknown): Uint8Array | null => {
|
|
180
|
-
if (ArrayBuffer.isView(value)) {
|
|
181
|
-
const array = Array.from(value as Uint8Array);
|
|
182
|
-
return encode(array, { extensionCodec });
|
|
183
|
-
}
|
|
184
|
-
if (isObject(value) && "encode_value" in value) {
|
|
185
|
-
if (typeof value.value === "bigint")
|
|
186
|
-
return encode(value.value.toString(), { extensionCodec });
|
|
187
|
-
return encode(value.value, { extensionCodec });
|
|
188
|
-
}
|
|
189
|
-
if (typeof value === "bigint") return encode(value.toString(), { extensionCodec });
|
|
190
|
-
return null;
|
|
191
|
-
},
|
|
192
|
-
decode: (data: Uint8Array) => decode(data, { extensionCodec }),
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
export class MsgPackCodec implements Codec {
|
|
196
|
-
contentType = "application/msgpack";
|
|
197
|
-
|
|
198
|
-
encode(payload: unknown): Uint8Array {
|
|
199
|
-
const caseConverted = caseconv.camelToSnake(payload);
|
|
200
|
-
const d = encode(caseConverted, { extensionCodec });
|
|
201
|
-
return d.slice();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
decode<P extends z.ZodTypeAny>(
|
|
205
|
-
data: Uint8Array | ArrayBuffer,
|
|
206
|
-
schema?: P,
|
|
207
|
-
): z.output<P> {
|
|
208
|
-
const decoded = decode(data, { extensionCodec });
|
|
209
|
-
const unpacked = caseconv.snakeToCamel(decoded);
|
|
210
|
-
return schema != null ? schema.parse(unpacked) : (unpacked as z.output<P>);
|
|
155
|
+
return schema != null ? schema.parse(text) : (text as z.infer<P>);
|
|
211
156
|
}
|
|
212
|
-
|
|
213
|
-
static registerCustomType(): void {}
|
|
214
157
|
}
|
|
215
158
|
|
|
216
159
|
export const JSON_CODEC = new JSONCodec();
|
|
217
160
|
export const CSV_CODEC = new CSVCodec();
|
|
218
161
|
export const TEXT_CODEC = new TextCodec();
|
|
219
|
-
|
|
162
|
+
|
|
163
|
+
export const ENCODERS: Codec[] = [JSON_CODEC];
|
package/src/breaker/breaker.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { z } from "zod";
|
|
10
|
+
import { z } from "zod/v4";
|
|
11
11
|
|
|
12
12
|
import { sleep } from "@/sleep";
|
|
13
13
|
import { type CrudeTimeSpan, TimeSpan } from "@/telem";
|
|
@@ -45,13 +45,13 @@ export class Breaker {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export const
|
|
48
|
+
export const breakerConfigZ = z.object({
|
|
49
49
|
baseInterval: TimeSpan.z.optional(),
|
|
50
50
|
maxRetries: z.number().optional(),
|
|
51
51
|
scale: z.number().optional(),
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
export interface Config extends Omit<z.infer<typeof
|
|
54
|
+
export interface Config extends Omit<z.infer<typeof breakerConfigZ>, "baseInterval"> {
|
|
55
55
|
baseInterval?: CrudeTimeSpan;
|
|
56
56
|
maxRetries?: number;
|
|
57
57
|
scale?: number;
|
package/src/caseconv/caseconv.ts
CHANGED
|
@@ -33,6 +33,8 @@ const createConverter = (
|
|
|
33
33
|
opt = validateOptions(opt);
|
|
34
34
|
const res: UnknownRecord = {};
|
|
35
35
|
const anyObj = obj as UnknownRecord;
|
|
36
|
+
if ("toJSON" in anyObj && typeof anyObj.toJSON === "function")
|
|
37
|
+
return converter(anyObj.toJSON(), opt);
|
|
36
38
|
Object.keys(anyObj).forEach((key) => {
|
|
37
39
|
let value = anyObj[key];
|
|
38
40
|
const nkey = f(key);
|
|
@@ -115,7 +117,7 @@ export const capitalize = (str: string): string => {
|
|
|
115
117
|
export interface Options {
|
|
116
118
|
recursive: boolean;
|
|
117
119
|
recursiveInArray?: boolean;
|
|
118
|
-
keepTypesOnRecursion?:
|
|
120
|
+
keepTypesOnRecursion?: Function[];
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
/**
|
|
@@ -133,12 +135,12 @@ const validateOptions = (opt: Options = defaultOptions): Options => {
|
|
|
133
135
|
return opt;
|
|
134
136
|
};
|
|
135
137
|
|
|
136
|
-
const isArrayObject = (obj:
|
|
138
|
+
const isArrayObject = (obj: unknown): boolean => obj != null && Array.isArray(obj);
|
|
137
139
|
|
|
138
|
-
const isValidObject = (obj:
|
|
140
|
+
const isValidObject = (obj: unknown): boolean =>
|
|
139
141
|
obj != null && typeof obj === "object" && !Array.isArray(obj);
|
|
140
142
|
|
|
141
|
-
const belongToTypes = (obj:
|
|
143
|
+
const belongToTypes = (obj: unknown, types?: Function[]): boolean =>
|
|
142
144
|
(types || []).some((Type) => obj instanceof Type);
|
|
143
145
|
|
|
144
146
|
/**
|
package/src/change/change.ts
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { z } from "zod";
|
|
10
|
+
import { z } from "zod/v4";
|
|
11
11
|
|
|
12
12
|
export type Variant = "set" | "delete";
|
|
13
13
|
|
|
14
|
-
export const Z = <V extends z.
|
|
14
|
+
export const Z = <V extends z.ZodType>(value: V) =>
|
|
15
15
|
z.object({
|
|
16
16
|
variant: z.enum(["set", "delete"]),
|
|
17
17
|
key: z.string(),
|
package/src/color/color.spec.ts
CHANGED
|
@@ -149,6 +149,84 @@ describe("color.Color", () => {
|
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
+
describe("isDark", () => {
|
|
153
|
+
test("black is dark", () => {
|
|
154
|
+
expect(color.isDark("#000000")).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("white is not dark", () => {
|
|
158
|
+
expect(color.isDark("#ffffff")).toBe(false);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("mid gray is not dark", () => {
|
|
162
|
+
expect(color.isDark("#808080")).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test("dark red is dark", () => {
|
|
166
|
+
expect(color.isDark("#800000")).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("light blue is not dark", () => {
|
|
170
|
+
expect(color.isDark("#add8e6")).toBe(false);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("handles RGB array input", () => {
|
|
174
|
+
expect(color.isDark([0, 0, 0])).toBe(true);
|
|
175
|
+
expect(color.isDark([255, 255, 255])).toBe(false);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("handles RGBA array input", () => {
|
|
179
|
+
expect(color.isDark([0, 0, 0, 0.5])).toBe(true);
|
|
180
|
+
expect(color.isDark([255, 255, 255, 0.5])).toBe(false);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("handles Color object input", () => {
|
|
184
|
+
const darkColor = color.construct("#000000");
|
|
185
|
+
const lightColor = color.construct("#ffffff");
|
|
186
|
+
expect(color.isDark(darkColor)).toBe(true);
|
|
187
|
+
expect(color.isDark(lightColor)).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("isLight", () => {
|
|
192
|
+
test("white is light", () => {
|
|
193
|
+
expect(color.isLight("#ffffff")).toBe(true);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("black is not light", () => {
|
|
197
|
+
expect(color.isLight("#000000")).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test("mid gray is not light", () => {
|
|
201
|
+
expect(color.isLight("#808080")).toBe(false);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("dark red is not light", () => {
|
|
205
|
+
expect(color.isLight("#800000")).toBe(false);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("light blue is light", () => {
|
|
209
|
+
expect(color.isLight("#add8e6")).toBe(true);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test("handles RGB array input", () => {
|
|
213
|
+
expect(color.isLight([255, 255, 255])).toBe(true);
|
|
214
|
+
expect(color.isLight([0, 0, 0])).toBe(false);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test("handles RGBA array input", () => {
|
|
218
|
+
expect(color.isLight([255, 255, 255, 0.5])).toBe(true);
|
|
219
|
+
expect(color.isLight([0, 0, 0, 0.5])).toBe(false);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("handles Color object input", () => {
|
|
223
|
+
const lightColor = color.construct("#ffffff");
|
|
224
|
+
const darkColor = color.construct("#000000");
|
|
225
|
+
expect(color.isLight(lightColor)).toBe(true);
|
|
226
|
+
expect(color.isLight(darkColor)).toBe(false);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
152
230
|
describe("grayness", () => {
|
|
153
231
|
const tests: Array<[string, number]> = [
|
|
154
232
|
["#000000", 1],
|
|
@@ -509,11 +587,11 @@ describe("color.Color", () => {
|
|
|
509
587
|
expect(color.equals(c1, c2)).toBe(true);
|
|
510
588
|
});
|
|
511
589
|
|
|
512
|
-
test("
|
|
590
|
+
test("comparing to undefined", () => {
|
|
513
591
|
const c1: color.RGB = [255, 0, 0];
|
|
514
592
|
expect(color.equals(c1, undefined)).toBe(false);
|
|
515
593
|
expect(color.equals(undefined, c1)).toBe(false);
|
|
516
|
-
expect(color.equals(undefined, undefined)).toBe(
|
|
594
|
+
expect(color.equals(undefined, undefined)).toBe(true);
|
|
517
595
|
});
|
|
518
596
|
|
|
519
597
|
test("comparing color with itself returns true", () => {
|
|
@@ -678,4 +756,37 @@ describe("color.Color", () => {
|
|
|
678
756
|
expect(color.isColor([0, 0, 0, 1.1])).toBe(false);
|
|
679
757
|
});
|
|
680
758
|
});
|
|
759
|
+
|
|
760
|
+
describe("isZero", () => {
|
|
761
|
+
test("returns true for zero color", () => {
|
|
762
|
+
expect(color.isZero([0, 0, 0, 0])).toBe(true);
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
test("returns false for non-zero RGB values", () => {
|
|
766
|
+
expect(color.isZero([1, 0, 0, 0])).toBe(false);
|
|
767
|
+
expect(color.isZero([0, 1, 0, 0])).toBe(false);
|
|
768
|
+
expect(color.isZero([0, 0, 1, 0])).toBe(false);
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
test("returns false for non-zero alpha", () => {
|
|
772
|
+
expect(color.isZero([0, 0, 0, 0.1])).toBe(false);
|
|
773
|
+
expect(color.isZero([0, 0, 0, 1])).toBe(false);
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
test("returns false for undefined input", () => {
|
|
777
|
+
expect(color.isZero(undefined)).toBe(false);
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
test("returns false for null input", () => {
|
|
781
|
+
expect(color.isZero(null as any)).toBe(false);
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
test("returns false for hex color", () => {
|
|
785
|
+
expect(color.isZero("#000000")).toBe(false);
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
test("returns false for constructed color", () => {
|
|
789
|
+
expect(color.isZero(color.construct("#000000"))).toBe(false);
|
|
790
|
+
});
|
|
791
|
+
});
|
|
681
792
|
});
|
package/src/color/color.ts
CHANGED
|
@@ -7,29 +7,61 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { z } from "zod";
|
|
10
|
+
import { z } from "zod/v4";
|
|
11
11
|
|
|
12
|
+
/** A regex to match hex colors. */
|
|
12
13
|
const hexRegex = /^#?([0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
14
|
+
|
|
15
|
+
/** A zod schema for a hex color. */
|
|
13
16
|
const hexZ = z.string().regex(hexRegex);
|
|
17
|
+
/** A zod schema for an RGB value. */
|
|
14
18
|
const rgbValueZ = z.number().min(0).max(255);
|
|
19
|
+
/** A zod schema for an alpha value between 0 and 1. */
|
|
15
20
|
const alphaZ = z.number().min(0).max(1);
|
|
21
|
+
/** A zod schema for an RGBA color. */
|
|
16
22
|
const rgbaZ = z.tuple([rgbValueZ, rgbValueZ, rgbValueZ, alphaZ]);
|
|
23
|
+
/** A zod schema for an RGB color. */
|
|
17
24
|
const rgbZ = z.tuple([rgbValueZ, rgbValueZ, rgbValueZ]);
|
|
25
|
+
/** A zod schema for a legacy color object. */
|
|
18
26
|
const legacyObjectZ = z.object({ rgba255: rgbaZ });
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
/** A zod schema for a hue value between 0 and 360. */
|
|
28
|
+
const hueZ = z.number().min(0).max(360);
|
|
29
|
+
/** A zod schema for a saturation value between 0 and 100. */
|
|
30
|
+
const saturationZ = z.number().min(0).max(100);
|
|
31
|
+
/** A zod schema for a lightness value between 0 and 100. */
|
|
32
|
+
const lightnessZ = z.number().min(0).max(100);
|
|
33
|
+
/** A zod schema for an HSLA color. */
|
|
34
|
+
const hslaZ = z.tuple([hueZ, saturationZ, lightnessZ, alphaZ]);
|
|
35
|
+
|
|
36
|
+
/** A color in RGBA format. See https://en.wikipedia.org/wiki/RGBA_color_model */
|
|
37
|
+
export type RGBA = z.infer<typeof rgbaZ>;
|
|
38
|
+
/** A color in HSLA format. See https://en.wikipedia.org/wiki/HSL_and_HSV */
|
|
39
|
+
export type HSLA = z.infer<typeof hslaZ>;
|
|
40
|
+
/** A color in RGB format. See https://en.wikipedia.org/wiki/RGB_color_model */
|
|
41
|
+
export type RGB = z.infer<typeof rgbZ>;
|
|
42
|
+
/** A color in hex format. See https://en.wikipedia.org/wiki/Web_colors */
|
|
27
43
|
export type Hex = z.infer<typeof hexZ>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/** A legacy color object. */
|
|
44
|
+
|
|
45
|
+
/** A legacy color object. Used for backwards compatibility. */
|
|
31
46
|
type LegacyObject = z.infer<typeof legacyObjectZ>;
|
|
32
47
|
|
|
48
|
+
/** A zod schema for a crude color representation. */
|
|
49
|
+
export const crudeZ = z.union([hexZ, rgbZ, rgbaZ, hslaZ, legacyObjectZ]);
|
|
50
|
+
/**
|
|
51
|
+
* An unparsed representation of a color i.e. a value that can be converted into
|
|
52
|
+
* a Color object.
|
|
53
|
+
*/
|
|
54
|
+
export type Crude = Hex | RGBA | Color | RGB | LegacyObject;
|
|
55
|
+
|
|
56
|
+
/** A zod schema to parse color values from various crude representations. */
|
|
57
|
+
export const colorZ = crudeZ.transform((v) => construct(v));
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A color in RGBA format. Used as the standard representation of a color in this package.
|
|
61
|
+
* See https://en.wikipedia.org/wiki/RGBA_color_model
|
|
62
|
+
*/
|
|
63
|
+
export type Color = RGBA;
|
|
64
|
+
|
|
33
65
|
/** @returns true if the given color can be parsed into a valid color object. */
|
|
34
66
|
export const isCrude = (color: unknown): color is Crude =>
|
|
35
67
|
colorZ.safeParse(color).success;
|
|
@@ -38,12 +70,6 @@ export const isCrude = (color: unknown): color is Crude =>
|
|
|
38
70
|
export const isColor = (color: unknown): color is Color =>
|
|
39
71
|
rgbaZ.safeParse(color).success;
|
|
40
72
|
|
|
41
|
-
/**
|
|
42
|
-
* An unparsed representation of a color i.e. a value that can be converted into
|
|
43
|
-
* a Color object.
|
|
44
|
-
*/
|
|
45
|
-
export type Crude = Hex | RGBA | Color | string | RGB | LegacyObject;
|
|
46
|
-
|
|
47
73
|
/**
|
|
48
74
|
* Converts a crude color to its most meaningful CSS format.
|
|
49
75
|
* @returns undefined if the color is undefined.
|
|
@@ -51,13 +77,18 @@ export type Crude = Hex | RGBA | Color | string | RGB | LegacyObject;
|
|
|
51
77
|
* @returns the color directly if it is a css variable.
|
|
52
78
|
* @throws if the color does not match any of the preceding conditions.
|
|
53
79
|
*/
|
|
54
|
-
export
|
|
80
|
+
export interface CSSString {
|
|
81
|
+
(color: Crude): string;
|
|
82
|
+
(color?: Crude): string | undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const cssString = ((color?: Crude): string | undefined => {
|
|
55
86
|
if (color == null) return undefined;
|
|
56
87
|
const res = colorZ.safeParse(color);
|
|
57
88
|
if (res.success) return rgbaCSS(res.data);
|
|
58
89
|
if (typeof color === "string") return color;
|
|
59
90
|
throw res.error;
|
|
60
|
-
};
|
|
91
|
+
}) as CSSString;
|
|
61
92
|
|
|
62
93
|
/**
|
|
63
94
|
* @constructor Creates a new color from the given color value. The color value can be
|
|
@@ -74,15 +105,15 @@ export const cssString = (color?: Crude): string | undefined => {
|
|
|
74
105
|
* alpha value, this value will be ignored. Defaults to 1.
|
|
75
106
|
*/
|
|
76
107
|
export const construct = (color: Crude, alpha: number = 1): Color => {
|
|
108
|
+
color = crudeZ.parse(color);
|
|
77
109
|
if (typeof color === "string") return fromHex(color, alpha);
|
|
78
110
|
if (Array.isArray(color)) {
|
|
79
111
|
if (color.length < 3 || color.length > 4)
|
|
80
112
|
throw new Error(`Invalid color: [${color.join(", ")}]`);
|
|
81
|
-
if (color.length === 3) return [...color, alpha]
|
|
113
|
+
if (color.length === 3) return [...color, alpha];
|
|
82
114
|
return color;
|
|
83
115
|
}
|
|
84
|
-
|
|
85
|
-
throw new Error(`Invalid color: ${JSON.stringify(color)}`);
|
|
116
|
+
return color.rgba255;
|
|
86
117
|
};
|
|
87
118
|
|
|
88
119
|
/**
|
|
@@ -90,7 +121,7 @@ export const construct = (color: Crude, alpha: number = 1): Color => {
|
|
|
90
121
|
* representations of the same color are considered equal (e.g. hex and rgba).
|
|
91
122
|
*/
|
|
92
123
|
export const equals = (a?: Crude, b?: Crude): boolean => {
|
|
93
|
-
if (a == null || b == null) return
|
|
124
|
+
if (a == null || b == null) return a == b;
|
|
94
125
|
const a_ = construct(a);
|
|
95
126
|
const b_ = construct(b);
|
|
96
127
|
return a_.every((v, i) => v === b_[i]);
|
|
@@ -174,10 +205,12 @@ export const setAlpha = (color: Crude, alpha: number): Color => {
|
|
|
174
205
|
if (alpha > 100)
|
|
175
206
|
throw new Error(`Color opacity must be between 0 and 100, got ${alpha}`);
|
|
176
207
|
if (alpha > 1) alpha /= 100;
|
|
177
|
-
return [r, g, b, alpha]
|
|
208
|
+
return [r, g, b, alpha];
|
|
178
209
|
};
|
|
179
|
-
|
|
180
|
-
|
|
210
|
+
/**
|
|
211
|
+
* @returns the luminance of the color, between 0 and 1.
|
|
212
|
+
* @see https://en.wikipedia.org/wiki/Relative_luminance for more information.
|
|
213
|
+
*/
|
|
181
214
|
export const luminance = (color: Crude): number => {
|
|
182
215
|
const [r, g, b] = rgb1(color).map((v) =>
|
|
183
216
|
v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4,
|
|
@@ -185,7 +218,10 @@ export const luminance = (color: Crude): number => {
|
|
|
185
218
|
return Number((0.2126 * r + 0.7152 * g + 0.0722 * b).toFixed(3));
|
|
186
219
|
};
|
|
187
220
|
|
|
188
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* @returns an approximation of the colors 'grayness' from 0 to 1 by measuring the
|
|
223
|
+
* deviation between the RGB values of the color.
|
|
224
|
+
*/
|
|
189
225
|
export const grayness = (color: Crude): number => {
|
|
190
226
|
const [r, g, b] = rgb1(color);
|
|
191
227
|
const deviation = Math.max(r, g, b) - Math.min(r, g, b);
|
|
@@ -196,8 +232,11 @@ export const grayness = (color: Crude): number => {
|
|
|
196
232
|
* @returns the contrast ratio between this color and the given color. The contrast
|
|
197
233
|
* ratio is a number between 1 and 21, where 1 is the lowest contrast and 21 is the
|
|
198
234
|
* highest.
|
|
199
|
-
* @param
|
|
200
|
-
* @
|
|
235
|
+
* @param a - The first color to compare.
|
|
236
|
+
* @param b - The second color to compare.
|
|
237
|
+
* @returns The contrast ratio between the two colors.
|
|
238
|
+
*
|
|
239
|
+
* @see https://www.accessibility-developer-guide.com/knowledge/colours-and-contrast/how-to-calculate/
|
|
201
240
|
*/
|
|
202
241
|
export const contrast = (a: Crude, b: Crude): number => {
|
|
203
242
|
const a_ = construct(a);
|
|
@@ -214,33 +253,25 @@ export const pickByContrast = (source: Crude, ...colors: Crude[]): Color => {
|
|
|
214
253
|
if (colors.length === 0)
|
|
215
254
|
throw new Error("[Color.pickByContrast] - must provide at least one color");
|
|
216
255
|
const source_ = construct(source);
|
|
217
|
-
const [best] = colors
|
|
218
|
-
|
|
219
|
-
.sort((a, b) => contrast(source_, b) - contrast(source_, a));
|
|
220
|
-
return best;
|
|
256
|
+
const [best] = colors.sort((a, b) => contrast(source_, b) - contrast(source_, a));
|
|
257
|
+
return construct(best);
|
|
221
258
|
};
|
|
222
259
|
|
|
223
260
|
/** @returns true if the color is dark i.e. it has a luminance less than 0.5. */
|
|
224
261
|
export const isDark = (color: Crude): boolean => luminance(color) < 0.5;
|
|
225
262
|
|
|
226
|
-
/** @returns true if the color is light i.e. the luminance is greater than
|
|
227
|
-
export const isLight = (color: Crude): boolean =>
|
|
228
|
-
|
|
229
|
-
/** A zod schema to parse color values from various crude representations. */
|
|
230
|
-
export const colorZ = z
|
|
231
|
-
.union([hexZ, rgbaZ, rgbZ, legacyObjectZ])
|
|
232
|
-
.transform((v) => construct(v));
|
|
263
|
+
/** @returns true if the color is light i.e. the luminance is greater than 0.5. */
|
|
264
|
+
export const isLight = (color: Crude): boolean => luminance(color) > 0.5;
|
|
233
265
|
|
|
234
266
|
/** @returns a color parsed from a hex string with an alpha value. */
|
|
235
|
-
const fromHex = (
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
hex_ = stripHash(hex_);
|
|
267
|
+
const fromHex = (hex: string, alpha: number = 1): RGBA => {
|
|
268
|
+
hex = hexZ.parse(hex);
|
|
269
|
+
hex = stripHash(hex);
|
|
239
270
|
return [
|
|
240
|
-
hexToRgba(
|
|
241
|
-
hexToRgba(
|
|
242
|
-
hexToRgba(
|
|
243
|
-
|
|
271
|
+
hexToRgba(hex, 0),
|
|
272
|
+
hexToRgba(hex, 2),
|
|
273
|
+
hexToRgba(hex, 4),
|
|
274
|
+
hex.length === 8 ? hexToRgba(hex, 6) / 255 : alpha,
|
|
244
275
|
];
|
|
245
276
|
};
|
|
246
277
|
|
|
@@ -251,8 +282,9 @@ const rgbaToHex = (n: number): string => Math.floor(n).toString(16).padStart(2,
|
|
|
251
282
|
const hexToRgba = (s: string, n: number): number => parseInt(s.slice(n, n + 2), 16);
|
|
252
283
|
const stripHash = (hex: string): string => (hex.startsWith("#") ? hex.slice(1) : hex);
|
|
253
284
|
|
|
254
|
-
/** @returns a color
|
|
255
|
-
export const fromHSLA = (hsla:
|
|
285
|
+
/** @returns parse a color from an HSLA tuple. */
|
|
286
|
+
export const fromHSLA = (hsla: HSLA): RGBA => {
|
|
287
|
+
hsla = hslaZ.parse(hsla);
|
|
256
288
|
let [h, s, l] = hsla;
|
|
257
289
|
const a = hsla[3];
|
|
258
290
|
h /= 360;
|
|
@@ -265,15 +297,15 @@ export const fromHSLA = (hsla: RGBA): RGBA => {
|
|
|
265
297
|
else {
|
|
266
298
|
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
267
299
|
const p = 2 * l - q;
|
|
268
|
-
r =
|
|
269
|
-
g =
|
|
270
|
-
b =
|
|
300
|
+
r = hueToRGB(p, q, h + 1 / 3);
|
|
301
|
+
g = hueToRGB(p, q, h);
|
|
302
|
+
b = hueToRGB(p, q, h - 1 / 3);
|
|
271
303
|
}
|
|
272
304
|
|
|
273
305
|
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
|
|
274
306
|
};
|
|
275
307
|
|
|
276
|
-
const
|
|
308
|
+
const hueToRGB = (p: number, q: number, t: number): number => {
|
|
277
309
|
if (t < 0) t += 1;
|
|
278
310
|
if (t > 1) t -= 1;
|
|
279
311
|
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
|
@@ -283,6 +315,7 @@ const hueToRgb = (p: number, q: number, t: number): number => {
|
|
|
283
315
|
};
|
|
284
316
|
|
|
285
317
|
const rgbaToHSLA = (rgba: RGBA): HSLA => {
|
|
318
|
+
rgba = rgbaZ.parse(rgba);
|
|
286
319
|
let [r, g, b] = rgba;
|
|
287
320
|
const a = rgba[3];
|
|
288
321
|
r /= 255;
|
|
@@ -293,7 +326,7 @@ const rgbaToHSLA = (rgba: RGBA): HSLA => {
|
|
|
293
326
|
const min = Math.min(r, g, b);
|
|
294
327
|
let h: number;
|
|
295
328
|
let s: number;
|
|
296
|
-
let l
|
|
329
|
+
let l = (max + min) / 2;
|
|
297
330
|
|
|
298
331
|
if (max === min)
|
|
299
332
|
h = s = 0; // achromatic
|
|
@@ -314,9 +347,6 @@ const rgbaToHSLA = (rgba: RGBA): HSLA => {
|
|
|
314
347
|
return [Math.round(h), Math.round(s), Math.round(l), a];
|
|
315
348
|
};
|
|
316
349
|
|
|
317
|
-
/** A zod schema for a crude color representation. */
|
|
318
|
-
export const crudeZ = z.union([hexZ, rgbaZ, z.string(), rgbZ, legacyObjectZ]);
|
|
319
|
-
|
|
320
350
|
/** The color black. */
|
|
321
351
|
export const BLACK = construct("#000000");
|
|
322
352
|
/** The color white. */
|
package/src/color/external.ts
CHANGED