@synnaxlabs/x 0.55.0 → 0.56.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/.turbo/turbo-build.log +10 -13
- package/dist/src/array/nullable.d.ts +1 -1
- package/dist/src/array/nullable.d.ts.map +1 -1
- package/dist/src/caseconv/caseconv.d.ts.map +1 -1
- package/dist/src/compare/compare.d.ts +14 -0
- package/dist/src/compare/compare.d.ts.map +1 -1
- package/dist/src/debounce/debounce.d.ts +7 -2
- package/dist/src/debounce/debounce.d.ts.map +1 -1
- package/dist/src/deep/merge.d.ts.map +1 -1
- package/dist/src/deep/set.d.ts.map +1 -1
- package/dist/src/destructor/destructor.d.ts +1 -0
- package/dist/src/destructor/destructor.d.ts.map +1 -1
- package/dist/src/errors/errors.d.ts +18 -10
- 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/migrate/migrate.d.ts.map +1 -1
- package/dist/src/notation/external.d.ts +3 -0
- package/dist/src/notation/external.d.ts.map +1 -0
- package/dist/src/notation/index.d.ts +1 -1
- package/dist/src/notation/notation.d.ts +5 -9
- package/dist/src/notation/notation.d.ts.map +1 -1
- package/dist/src/notation/types.gen.d.ts +9 -0
- package/dist/src/notation/types.gen.d.ts.map +1 -0
- package/dist/src/primitive/primitive.d.ts +16 -0
- package/dist/src/primitive/primitive.d.ts.map +1 -1
- package/dist/src/record/record.d.ts +8 -1
- package/dist/src/record/record.d.ts.map +1 -1
- package/dist/src/require/index.d.ts +2 -0
- package/dist/src/require/index.d.ts.map +1 -0
- package/dist/src/require/require.d.ts +2 -0
- package/dist/src/require/require.d.ts.map +1 -0
- package/dist/src/spatial/base.d.ts +1 -103
- package/dist/src/spatial/base.d.ts.map +1 -1
- package/dist/src/spatial/bounds/bounds.d.ts +3 -3
- package/dist/src/spatial/bounds/bounds.d.ts.map +1 -1
- package/dist/src/spatial/box/box.d.ts +7 -13
- package/dist/src/spatial/box/box.d.ts.map +1 -1
- package/dist/src/spatial/direction/direction.d.ts +17 -16
- package/dist/src/spatial/direction/direction.d.ts.map +1 -1
- package/dist/src/spatial/external.d.ts +1 -2
- package/dist/src/spatial/external.d.ts.map +1 -1
- package/dist/src/spatial/location/location.d.ts +28 -28
- package/dist/src/spatial/location/location.d.ts.map +1 -1
- package/dist/src/spatial/scale/scale.d.ts +2 -2
- package/dist/src/spatial/scale/scale.d.ts.map +1 -1
- package/dist/src/spatial/sticky/sticky.d.ts +15 -15
- package/dist/src/spatial/sticky/sticky.d.ts.map +1 -1
- package/dist/src/spatial/types.gen.d.ts +179 -2
- package/dist/src/spatial/types.gen.d.ts.map +1 -1
- package/dist/src/spatial/xy/xy.d.ts +4 -4
- package/dist/src/spatial/xy/xy.d.ts.map +1 -1
- package/dist/src/status/status.d.ts +11 -0
- package/dist/src/status/status.d.ts.map +1 -1
- package/dist/src/telem/external.d.ts +1 -0
- package/dist/src/telem/external.d.ts.map +1 -1
- package/dist/src/telem/series.d.ts +5 -2
- package/dist/src/telem/series.d.ts.map +1 -1
- package/dist/src/telem/telem.d.ts +42 -34
- package/dist/src/telem/telem.d.ts.map +1 -1
- package/dist/src/telem/types.gen.d.ts +19 -0
- package/dist/src/telem/types.gen.d.ts.map +1 -0
- package/dist/src/text/external.d.ts +3 -0
- package/dist/src/text/external.d.ts.map +1 -0
- package/dist/src/text/index.d.ts +2 -0
- package/dist/src/text/index.d.ts.map +1 -0
- package/dist/src/text/types.d.ts +21 -0
- package/dist/src/text/types.d.ts.map +1 -0
- package/dist/src/text/types.gen.d.ts +13 -0
- package/dist/src/text/types.gen.d.ts.map +1 -0
- package/dist/src/throttle/index.d.ts +2 -0
- package/dist/src/throttle/index.d.ts.map +1 -0
- package/dist/src/throttle/throttle.d.ts +3 -0
- package/dist/src/throttle/throttle.d.ts.map +1 -0
- package/dist/src/throttle/throttle.spec.d.ts +2 -0
- package/dist/src/throttle/throttle.spec.d.ts.map +1 -0
- package/dist/src/zod/parse.d.ts.map +1 -1
- package/dist/x.cjs +10 -10
- package/dist/x.js +1497 -1365
- package/package.json +11 -11
- package/src/array/nullable.ts +1 -4
- package/src/caseconv/caseconv.spec.ts +71 -0
- package/src/caseconv/caseconv.ts +15 -2
- package/src/compare/compare.spec.ts +115 -0
- package/src/compare/compare.ts +29 -0
- package/src/debounce/debounce.spec.ts +258 -24
- package/src/debounce/debounce.ts +49 -30
- package/src/deep/copy.spec.ts +13 -0
- package/src/deep/difference.ts +1 -1
- package/src/deep/merge.ts +2 -1
- package/src/deep/set.ts +2 -1
- package/src/destructor/destructor.ts +2 -0
- package/src/errors/errors.spec.ts +122 -0
- package/src/errors/errors.ts +51 -17
- package/src/index.ts +4 -1
- package/src/migrate/migrate.ts +2 -1
- package/src/notation/external.ts +11 -0
- package/src/notation/index.ts +1 -1
- package/src/notation/notation.spec.ts +260 -2
- package/src/notation/notation.ts +25 -7
- package/src/notation/types.gen.ts +16 -0
- package/src/primitive/primitive.spec.ts +58 -5
- package/src/primitive/primitive.ts +22 -0
- package/src/record/record.spec.ts +26 -0
- package/src/record/record.ts +20 -5
- package/src/require/index.ts +10 -0
- package/src/require/require.ts +10 -0
- package/src/spatial/base.ts +1 -93
- package/src/spatial/bounds/bounds.ts +10 -10
- package/src/spatial/box/box.ts +5 -5
- package/src/spatial/direction/direction.ts +16 -17
- package/src/spatial/external.ts +1 -2
- package/src/spatial/location/location.ts +19 -17
- package/src/spatial/scale/scale.ts +2 -2
- package/src/spatial/sticky/sticky.spec.ts +2 -2
- package/src/spatial/sticky/sticky.ts +6 -13
- package/src/spatial/types.gen.ts +140 -0
- package/src/spatial/xy/xy.ts +7 -7
- package/src/status/status.spec.ts +82 -2
- package/src/status/status.ts +35 -9
- package/src/telem/external.ts +8 -0
- package/src/telem/series.spec.ts +183 -0
- package/src/telem/series.ts +54 -16
- package/src/telem/telem.spec.ts +128 -9
- package/src/telem/telem.ts +91 -79
- package/src/telem/types.gen.ts +28 -0
- package/src/text/external.ts +11 -0
- package/src/text/index.ts +10 -0
- package/src/text/types.gen.ts +16 -0
- package/src/text/types.ts +37 -0
- package/src/{worker → throttle}/index.ts +1 -1
- package/src/throttle/throttle.spec.ts +147 -0
- package/src/throttle/throttle.ts +44 -0
- package/src/zod/parse.ts +2 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/src/spatial/spatial.d.ts +0 -3
- package/dist/src/spatial/spatial.d.ts.map +0 -1
- package/dist/src/worker/index.d.ts +0 -2
- package/dist/src/worker/index.d.ts.map +0 -1
- package/dist/src/worker/worker.d.ts +0 -33
- package/dist/src/worker/worker.d.ts.map +0 -1
- package/dist/src/worker/worker.spec.d.ts +0 -2
- package/dist/src/worker/worker.spec.d.ts.map +0 -1
- package/src/spatial/spatial.ts +0 -44
- package/src/worker/worker.spec.ts +0 -41
- package/src/worker/worker.ts +0 -86
package/src/spatial/base.ts
CHANGED
|
@@ -9,99 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
export * from "@/spatial/types.gen";
|
|
13
13
|
|
|
14
14
|
export const numberCouple = z.tuple([z.number(), z.number()]);
|
|
15
15
|
export type NumberCouple<T extends number | bigint = number> = [T, T];
|
|
16
|
-
|
|
17
|
-
// Direction
|
|
18
|
-
|
|
19
|
-
export const DIRECTIONS = ["x", "y"] as const;
|
|
20
|
-
export const directionZ = z.enum(DIRECTIONS);
|
|
21
|
-
export type Direction = z.infer<typeof directionZ>;
|
|
22
|
-
|
|
23
|
-
// Location
|
|
24
|
-
|
|
25
|
-
export const OUTER_LOCATIONS = ["top", "right", "bottom", "left"] as const;
|
|
26
|
-
export const outerLocationZ = z.enum(OUTER_LOCATIONS);
|
|
27
|
-
export type OuterLocation = z.infer<typeof outerLocationZ>;
|
|
28
|
-
|
|
29
|
-
export const X_LOCATIONS = ["left", "right"] as const;
|
|
30
|
-
export const xLocationZ = z.enum(X_LOCATIONS);
|
|
31
|
-
export type XLocation = z.infer<typeof xLocationZ>;
|
|
32
|
-
|
|
33
|
-
export const Y_LOCATIONS = ["top", "bottom"] as const;
|
|
34
|
-
export const yLocationZ = z.enum(Y_LOCATIONS);
|
|
35
|
-
export type YLocation = z.infer<typeof yLocationZ>;
|
|
36
|
-
|
|
37
|
-
export const CENTER_LOCATIONS = ["center"] as const;
|
|
38
|
-
export const centerLocationZ = z.enum(CENTER_LOCATIONS);
|
|
39
|
-
export type CenterLocation = z.infer<typeof centerLocationZ>;
|
|
40
|
-
|
|
41
|
-
export const LOCATIONS = ["top", "right", "bottom", "left", "center"] as const;
|
|
42
|
-
export const locationZ = z.enum(LOCATIONS);
|
|
43
|
-
export type Location = z.infer<typeof locationZ>;
|
|
44
|
-
|
|
45
|
-
// Alignment
|
|
46
|
-
|
|
47
|
-
export const ALIGNMENTS = ["start", "center", "end"] as const;
|
|
48
|
-
export const alignmentZ = z.enum(ALIGNMENTS);
|
|
49
|
-
export type Alignment = z.infer<typeof alignmentZ>;
|
|
50
|
-
|
|
51
|
-
// Order
|
|
52
|
-
|
|
53
|
-
export const ORDERS = ["first", "last"] as const;
|
|
54
|
-
export const orderZ = z.enum(ORDERS);
|
|
55
|
-
export type Order = z.infer<typeof orderZ>;
|
|
56
|
-
|
|
57
|
-
// XY
|
|
58
|
-
|
|
59
|
-
export const clientXyZ = z.object({ clientX: z.number(), clientY: z.number() });
|
|
60
|
-
export type ClientXY = z.infer<typeof clientXyZ>;
|
|
61
|
-
|
|
62
|
-
// Dimensions
|
|
63
|
-
|
|
64
|
-
export const dimensionsZ = z.object({ width: z.number(), height: z.number() });
|
|
65
|
-
export type Dimensions = z.infer<typeof dimensionsZ>;
|
|
66
|
-
|
|
67
|
-
export const signedDimensionsZ = z.object({
|
|
68
|
-
signedWidth: z.number(),
|
|
69
|
-
signedHeight: z.number(),
|
|
70
|
-
});
|
|
71
|
-
export type SignedDimensions = z.infer<typeof signedDimensionsZ>;
|
|
72
|
-
|
|
73
|
-
export type Dimension = "width" | "height";
|
|
74
|
-
export type SignedDimension = "signedWidth" | "signedHeight";
|
|
75
|
-
|
|
76
|
-
// Bounds
|
|
77
|
-
|
|
78
|
-
export const boundsZ = z.object({ lower: z.number(), upper: z.number() });
|
|
79
|
-
|
|
80
|
-
// Generic bounds interface (supports bigint)
|
|
81
|
-
export interface Bounds<T extends number | bigint = number> {
|
|
82
|
-
lower: T;
|
|
83
|
-
upper: T;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export type CrudeBounds<T extends number | bigint = number> =
|
|
87
|
-
| Bounds<T>
|
|
88
|
-
| NumberCouple<T>;
|
|
89
|
-
|
|
90
|
-
// Derived/complex types
|
|
91
|
-
|
|
92
|
-
export const crudeDirection = z.enum([
|
|
93
|
-
"x",
|
|
94
|
-
"y",
|
|
95
|
-
...OUTER_LOCATIONS,
|
|
96
|
-
...CENTER_LOCATIONS,
|
|
97
|
-
]);
|
|
98
|
-
export type CrudeDirection = z.infer<typeof crudeDirection>;
|
|
99
|
-
export type CrudeXDirection = "x" | "left" | "right";
|
|
100
|
-
export type CrudeYDirection = "y" | "top" | "bottom";
|
|
101
|
-
export type AngularDirection = "clockwise" | "counterclockwise";
|
|
102
|
-
export const crudeLocation = z.union([
|
|
103
|
-
directionZ,
|
|
104
|
-
z.enum([...OUTER_LOCATIONS, ...CENTER_LOCATIONS]),
|
|
105
|
-
z.instanceof(String),
|
|
106
|
-
]);
|
|
107
|
-
export type CrudeLocation = z.infer<typeof crudeLocation>;
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import { abs, add, equal as mathEqual, min as mathMin, sub } from "@/math/math";
|
|
11
11
|
import { type numeric } from "@/numeric";
|
|
12
|
-
import { type Bounds, boundsZ, type
|
|
12
|
+
import { type Bounds, boundsZ, type NumberCouple } from "@/spatial/base";
|
|
13
13
|
|
|
14
14
|
export { type Bounds, boundsZ };
|
|
15
15
|
|
|
16
|
-
export type Crude<T extends numeric.Value = number> =
|
|
16
|
+
export type Crude<T extends numeric.Value = number> = Bounds<T> | NumberCouple<T>;
|
|
17
17
|
|
|
18
18
|
/** Options for the `construct` function. */
|
|
19
19
|
interface ConstructOptions {
|
|
@@ -209,7 +209,7 @@ export const clamp = <T extends numeric.Value>(bounds: Crude<T>, target: T): T =
|
|
|
209
209
|
*/
|
|
210
210
|
export const contains = <T extends numeric.Value>(
|
|
211
211
|
bounds: Crude<T>,
|
|
212
|
-
target: T |
|
|
212
|
+
target: T | Crude<T>,
|
|
213
213
|
): boolean => {
|
|
214
214
|
const _bounds = construct(bounds);
|
|
215
215
|
if (typeof target === "number" || typeof target === "bigint")
|
|
@@ -594,7 +594,7 @@ export const traverse = <T extends numeric.Value = number>(
|
|
|
594
594
|
if (dir === 0) return start;
|
|
595
595
|
|
|
596
596
|
let remainingDist = dist;
|
|
597
|
-
let currentPosition = start
|
|
597
|
+
let currentPosition = start;
|
|
598
598
|
|
|
599
599
|
while (mathEqual(remainingDist, 0) === false) {
|
|
600
600
|
// Find the bound we're currently in or adjacent to
|
|
@@ -607,15 +607,15 @@ export const traverse = <T extends numeric.Value = number>(
|
|
|
607
607
|
const b = _bounds[index];
|
|
608
608
|
let distanceInBound: T;
|
|
609
609
|
if (dir > 0) distanceInBound = sub(b.upper, currentPosition);
|
|
610
|
-
else distanceInBound = sub(currentPosition, b.lower)
|
|
610
|
+
else distanceInBound = sub(currentPosition, b.lower);
|
|
611
611
|
|
|
612
612
|
if (distanceInBound > (0 as T)) {
|
|
613
613
|
const moveDist = mathMin(abs(remainingDist), distanceInBound);
|
|
614
|
-
currentPosition = add(currentPosition, dir > 0 ? moveDist : -moveDist)
|
|
614
|
+
currentPosition = add(currentPosition, dir > 0 ? moveDist : -moveDist);
|
|
615
615
|
remainingDist = sub<T>(remainingDist, dir > 0 ? moveDist : -moveDist);
|
|
616
616
|
|
|
617
617
|
// If we've exhausted the distance, return the current position
|
|
618
|
-
if (mathEqual(remainingDist, 0)) return currentPosition
|
|
618
|
+
if (mathEqual(remainingDist, 0)) return currentPosition;
|
|
619
619
|
continue;
|
|
620
620
|
}
|
|
621
621
|
}
|
|
@@ -626,17 +626,17 @@ export const traverse = <T extends numeric.Value = number>(
|
|
|
626
626
|
const nextBounds = _bounds.filter((b) => b.lower > currentPosition);
|
|
627
627
|
if (nextBounds.length > 0) currentPosition = nextBounds[0].lower;
|
|
628
628
|
// No more bounds in this direction
|
|
629
|
-
else return currentPosition
|
|
629
|
+
else return currentPosition;
|
|
630
630
|
} else {
|
|
631
631
|
// Move to the previous bound's upper value
|
|
632
632
|
const prevBounds = _bounds.filter((b) => b.upper < currentPosition);
|
|
633
633
|
if (prevBounds.length > 0)
|
|
634
634
|
currentPosition = prevBounds[prevBounds.length - 1].upper;
|
|
635
635
|
// No more bounds in this direction
|
|
636
|
-
else return currentPosition
|
|
636
|
+
else return currentPosition;
|
|
637
637
|
}
|
|
638
638
|
}
|
|
639
|
-
return currentPosition
|
|
639
|
+
return currentPosition;
|
|
640
640
|
};
|
|
641
641
|
|
|
642
642
|
/**
|
package/src/spatial/box/box.ts
CHANGED
|
@@ -32,7 +32,7 @@ export const domRect = z.object({
|
|
|
32
32
|
export const box = z.object({
|
|
33
33
|
one: xy.xyZ,
|
|
34
34
|
two: xy.xyZ,
|
|
35
|
-
root: location.
|
|
35
|
+
root: location.cornerZ,
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
export type Box = z.infer<typeof box>;
|
|
@@ -50,7 +50,7 @@ export const ZERO = { one: xy.ZERO, two: xy.ZERO, root: location.TOP_LEFT };
|
|
|
50
50
|
*/
|
|
51
51
|
export const DECIMAL = { one: xy.ZERO, two: xy.ONE, root: location.BOTTOM_LEFT };
|
|
52
52
|
|
|
53
|
-
export const copy = (b: Box, root?: location.
|
|
53
|
+
export const copy = (b: Box, root?: location.Corner): Box => ({
|
|
54
54
|
one: b.one,
|
|
55
55
|
two: b.two,
|
|
56
56
|
root: root ?? b.root,
|
|
@@ -71,7 +71,7 @@ export const construct = (
|
|
|
71
71
|
second?: number | xy.XY | dimensions.Dimensions | dimensions.Signed,
|
|
72
72
|
width: number = 0,
|
|
73
73
|
height: number = 0,
|
|
74
|
-
coordinateRoot?: location.
|
|
74
|
+
coordinateRoot?: location.Corner,
|
|
75
75
|
): Box => {
|
|
76
76
|
const b: Box = {
|
|
77
77
|
one: { ...xy.ZERO },
|
|
@@ -339,7 +339,7 @@ export const yBounds = (b: Crude): bounds.Bounds => {
|
|
|
339
339
|
return { lower: b_.one.y, upper: b_.two.y };
|
|
340
340
|
};
|
|
341
341
|
|
|
342
|
-
export const reRoot = (b: Box, corner: location.
|
|
342
|
+
export const reRoot = (b: Box, corner: location.Corner): Box => copy(b, corner);
|
|
343
343
|
|
|
344
344
|
export const edgePoints = (b: Crude, loc: location.Location): [xy.XY, xy.XY] => {
|
|
345
345
|
const b_ = construct(b);
|
|
@@ -461,7 +461,7 @@ export const constructWithAlternateRoot = (
|
|
|
461
461
|
width: number,
|
|
462
462
|
height: number,
|
|
463
463
|
currRoot: location.XY,
|
|
464
|
-
newRoot: location.
|
|
464
|
+
newRoot: location.Corner,
|
|
465
465
|
): Box => {
|
|
466
466
|
const first = { x, y };
|
|
467
467
|
const second = { x: x + width, y: y + height };
|
|
@@ -7,30 +7,29 @@
|
|
|
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";
|
|
11
|
+
|
|
10
12
|
import {
|
|
11
13
|
type AngularDirection,
|
|
12
|
-
|
|
13
|
-
crudeDirection,
|
|
14
|
-
type CrudeXDirection,
|
|
15
|
-
type CrudeYDirection,
|
|
14
|
+
CENTER_LOCATIONS,
|
|
16
15
|
type Dimension,
|
|
17
16
|
type Direction,
|
|
18
17
|
DIRECTIONS,
|
|
19
18
|
directionZ,
|
|
20
19
|
type Location,
|
|
20
|
+
OUTER_LOCATIONS,
|
|
21
21
|
type SignedDimension,
|
|
22
22
|
Y_LOCATIONS,
|
|
23
23
|
type YLocation,
|
|
24
|
-
} from "@/spatial/
|
|
24
|
+
} from "@/spatial/types.gen";
|
|
25
25
|
|
|
26
26
|
export { type Direction, DIRECTIONS, directionZ };
|
|
27
27
|
|
|
28
|
-
export const crude = crudeDirection;
|
|
29
|
-
|
|
30
|
-
export type Crude = CrudeDirection;
|
|
31
|
-
export type CrudeX = CrudeXDirection;
|
|
32
|
-
export type CrudeY = CrudeYDirection;
|
|
33
28
|
export type Angular = AngularDirection;
|
|
29
|
+
export const crudeZ = z.enum(["x", "y", ...OUTER_LOCATIONS, ...CENTER_LOCATIONS]);
|
|
30
|
+
export type Crude = z.infer<typeof crudeZ>;
|
|
31
|
+
export type CrudeX = "x" | "left" | "right";
|
|
32
|
+
export type CrudeY = "y" | "top" | "bottom";
|
|
34
33
|
|
|
35
34
|
export const construct = (c: Crude): Direction => {
|
|
36
35
|
if (DIRECTIONS.includes(c as Direction)) return c as Direction;
|
|
@@ -38,24 +37,24 @@ export const construct = (c: Crude): Direction => {
|
|
|
38
37
|
return "x";
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
export const swap = (direction:
|
|
40
|
+
export const swap = (direction: Crude): Direction =>
|
|
42
41
|
construct(direction) === "x" ? "y" : "x";
|
|
43
42
|
|
|
44
|
-
export const dimension = (direction:
|
|
43
|
+
export const dimension = (direction: Crude): Dimension =>
|
|
45
44
|
construct(direction) === "x" ? "width" : "height";
|
|
46
45
|
|
|
47
|
-
export const location = (direction:
|
|
46
|
+
export const location = (direction: Crude): Location =>
|
|
48
47
|
construct(direction) === "x" ? "left" : "top";
|
|
49
48
|
|
|
50
|
-
export const isDirection = (c: unknown): c is Direction =>
|
|
49
|
+
export const isDirection = (c: unknown): c is Direction => crudeZ.safeParse(c).success;
|
|
51
50
|
|
|
52
|
-
export const signedDimension = (direction:
|
|
51
|
+
export const signedDimension = (direction: Crude): SignedDimension =>
|
|
53
52
|
construct(direction) === "x" ? "signedWidth" : "signedHeight";
|
|
54
53
|
|
|
55
|
-
export const isX = (direction:
|
|
54
|
+
export const isX = (direction: Crude): direction is CrudeX => {
|
|
56
55
|
if (direction === "center") return false;
|
|
57
56
|
return construct(direction) === "x";
|
|
58
57
|
};
|
|
59
58
|
|
|
60
|
-
export const isY = (direction:
|
|
59
|
+
export const isY = (direction: Crude): direction is CrudeY =>
|
|
61
60
|
construct(direction) === "y";
|
package/src/spatial/external.ts
CHANGED
|
@@ -13,7 +13,6 @@ export * from "@/spatial/dimensions";
|
|
|
13
13
|
export * from "@/spatial/direction";
|
|
14
14
|
export * from "@/spatial/location";
|
|
15
15
|
export * from "@/spatial/scale";
|
|
16
|
-
export * as spatial from "@/spatial/spatial";
|
|
17
16
|
export * from "@/spatial/sticky";
|
|
18
|
-
export * from "@/spatial/types.gen";
|
|
17
|
+
export * as spatial from "@/spatial/types.gen";
|
|
19
18
|
export * from "@/spatial/xy";
|
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
CENTER_LOCATIONS,
|
|
16
16
|
type CenterLocation,
|
|
17
17
|
centerLocationZ,
|
|
18
|
-
type
|
|
19
|
-
|
|
18
|
+
type CornerLocation,
|
|
19
|
+
cornerLocationZ,
|
|
20
20
|
type Direction,
|
|
21
21
|
DIRECTIONS,
|
|
22
|
+
directionZ,
|
|
22
23
|
type Location,
|
|
23
24
|
LOCATIONS,
|
|
24
25
|
locationZ,
|
|
@@ -43,15 +44,18 @@ export {
|
|
|
43
44
|
Y_LOCATIONS,
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
export const
|
|
47
|
-
export const
|
|
48
|
-
export const
|
|
47
|
+
export const xZ = xLocationZ;
|
|
48
|
+
export const yZ = yLocationZ;
|
|
49
|
+
export const centerZ = centerLocationZ;
|
|
49
50
|
export const outerZ = outerLocationZ;
|
|
51
|
+
export const cornerZ = cornerLocationZ;
|
|
50
52
|
|
|
51
53
|
export type X = XLocation;
|
|
52
54
|
export type Y = YLocation;
|
|
53
55
|
export type Outer = OuterLocation;
|
|
54
56
|
export type Center = CenterLocation;
|
|
57
|
+
export type Corner = CornerLocation;
|
|
58
|
+
export type CornerString = "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
|
|
55
59
|
|
|
56
60
|
const SWAPPED: Record<Location, Location> = {
|
|
57
61
|
top: "bottom",
|
|
@@ -67,10 +71,12 @@ const ROTATIONS: Record<Outer, Record<AngularDirection, Outer>> = {
|
|
|
67
71
|
bottom: { clockwise: "right", counterclockwise: "left" },
|
|
68
72
|
left: { clockwise: "bottom", counterclockwise: "top" },
|
|
69
73
|
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
export const crudeZ = z.union([
|
|
75
|
+
directionZ,
|
|
76
|
+
z.enum([...OUTER_LOCATIONS, ...CENTER_LOCATIONS]),
|
|
77
|
+
z.instanceof(String),
|
|
78
|
+
]);
|
|
79
|
+
export type Crude = z.infer<typeof crudeZ>;
|
|
74
80
|
|
|
75
81
|
export const construct = (cl: Crude): Location => {
|
|
76
82
|
if (cl instanceof String) return cl as Location;
|
|
@@ -93,16 +99,12 @@ export const xy = z.object({
|
|
|
93
99
|
x: xLocationZ.or(centerLocationZ),
|
|
94
100
|
y: yLocationZ.or(centerLocationZ),
|
|
95
101
|
});
|
|
96
|
-
export const corner = z.object({ x: xLocationZ, y: yLocationZ });
|
|
97
|
-
|
|
98
102
|
export type XY = z.infer<typeof xy>;
|
|
99
|
-
export type CornerXY = z.infer<typeof corner>;
|
|
100
|
-
export type CornerXYString = "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
|
|
101
103
|
|
|
102
|
-
export const TOP_LEFT:
|
|
103
|
-
export const TOP_RIGHT:
|
|
104
|
-
export const BOTTOM_LEFT:
|
|
105
|
-
export const BOTTOM_RIGHT:
|
|
104
|
+
export const TOP_LEFT: Corner = Object.freeze({ x: "left", y: "top" });
|
|
105
|
+
export const TOP_RIGHT: Corner = Object.freeze({ x: "right", y: "top" });
|
|
106
|
+
export const BOTTOM_LEFT: Corner = Object.freeze({ x: "left", y: "bottom" });
|
|
107
|
+
export const BOTTOM_RIGHT: Corner = Object.freeze({ x: "right", y: "bottom" });
|
|
106
108
|
export const CENTER: XY = Object.freeze({ x: "center", y: "center" });
|
|
107
109
|
export const TOP_CENTER: XY = Object.freeze({ x: "center", y: "top" });
|
|
108
110
|
export const BOTTOM_CENTER: XY = Object.freeze({ x: "center", y: "bottom" });
|
|
@@ -417,12 +417,12 @@ export class Scale<T extends numeric.Value = number> {
|
|
|
417
417
|
export class XY {
|
|
418
418
|
x: Scale<number>;
|
|
419
419
|
y: Scale<number>;
|
|
420
|
-
currRoot: location.
|
|
420
|
+
currRoot: location.Corner | null;
|
|
421
421
|
|
|
422
422
|
constructor(
|
|
423
423
|
x: Scale<number> = new Scale<number>(),
|
|
424
424
|
y: Scale<number> = new Scale<number>(),
|
|
425
|
-
root: location.
|
|
425
|
+
root: location.Corner | null = null,
|
|
426
426
|
) {
|
|
427
427
|
this.x = x;
|
|
428
428
|
this.y = y;
|
|
@@ -134,7 +134,7 @@ describe("sticky", () => {
|
|
|
134
134
|
];
|
|
135
135
|
SPECS.forEach(({ value, valid }, i) => {
|
|
136
136
|
test(`xy schema ${i}`, () => {
|
|
137
|
-
const result = sticky.
|
|
137
|
+
const result = sticky.xyZ.safeParse(value);
|
|
138
138
|
expect(result.success).toBe(valid);
|
|
139
139
|
});
|
|
140
140
|
});
|
|
@@ -196,7 +196,7 @@ describe("sticky", () => {
|
|
|
196
196
|
];
|
|
197
197
|
SPECS.forEach(({ value, valid }, i) => {
|
|
198
198
|
test(`completeXY schema ${i}`, () => {
|
|
199
|
-
const result = sticky.
|
|
199
|
+
const result = sticky.completeXYZ.safeParse(value);
|
|
200
200
|
expect(result.success).toBe(valid);
|
|
201
201
|
});
|
|
202
202
|
});
|
|
@@ -7,25 +7,18 @@
|
|
|
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 type z from "zod";
|
|
11
11
|
|
|
12
12
|
import { box } from "@/spatial/box";
|
|
13
13
|
import { location } from "@/spatial/location";
|
|
14
|
+
import { type StickyXY, stickyXYZ } from "@/spatial/types.gen";
|
|
14
15
|
import { xy as base } from "@/spatial/xy";
|
|
15
16
|
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
units: z.object({
|
|
19
|
-
x: z.enum(["px", "decimal"]),
|
|
20
|
-
y: z.enum(["px", "decimal"]),
|
|
21
|
-
}),
|
|
22
|
-
});
|
|
17
|
+
export const xyZ = stickyXYZ;
|
|
18
|
+
export type XY = StickyXY;
|
|
23
19
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
export const xy = completeXY.partial({ root: true, units: true });
|
|
27
|
-
|
|
28
|
-
export interface XY extends z.infer<typeof xy> {}
|
|
20
|
+
export const completeXYZ = stickyXYZ.required({ root: true, units: true });
|
|
21
|
+
export type CompleteXY = z.infer<typeof completeXYZ>;
|
|
29
22
|
|
|
30
23
|
interface ToCSSReturn extends Partial<Record<location.Outer, string>> {}
|
|
31
24
|
|
package/src/spatial/types.gen.ts
CHANGED
|
@@ -11,10 +11,56 @@
|
|
|
11
11
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
+
import { type numeric } from "@/numeric";
|
|
15
|
+
|
|
16
|
+
export const X_LOCATIONS = ["left", "right"] as const;
|
|
17
|
+
export const xLocationZ = z.enum(X_LOCATIONS);
|
|
18
|
+
export type XLocation = z.infer<typeof xLocationZ>;
|
|
19
|
+
|
|
20
|
+
export const Y_LOCATIONS = ["top", "bottom"] as const;
|
|
21
|
+
export const yLocationZ = z.enum(Y_LOCATIONS);
|
|
22
|
+
export type YLocation = z.infer<typeof yLocationZ>;
|
|
23
|
+
|
|
24
|
+
export const STICKY_UNITS = ["px", "decimal"] as const;
|
|
25
|
+
export const stickyUnitZ = z.enum(STICKY_UNITS);
|
|
26
|
+
export type StickyUnit = z.infer<typeof stickyUnitZ>;
|
|
27
|
+
|
|
14
28
|
export const OUTER_LOCATIONS = ["top", "right", "bottom", "left"] as const;
|
|
15
29
|
export const outerLocationZ = z.enum(OUTER_LOCATIONS);
|
|
16
30
|
export type OuterLocation = z.infer<typeof outerLocationZ>;
|
|
17
31
|
|
|
32
|
+
export const DIRECTIONS = ["x", "y"] as const;
|
|
33
|
+
export const directionZ = z.enum(DIRECTIONS);
|
|
34
|
+
export type Direction = z.infer<typeof directionZ>;
|
|
35
|
+
|
|
36
|
+
export const ANGULAR_DIRECTIONS = ["clockwise", "counterclockwise"] as const;
|
|
37
|
+
export const angularDirectionZ = z.enum(ANGULAR_DIRECTIONS);
|
|
38
|
+
export type AngularDirection = z.infer<typeof angularDirectionZ>;
|
|
39
|
+
|
|
40
|
+
export const CENTER_LOCATIONS = ["center"] as const;
|
|
41
|
+
export const centerLocationZ = z.enum(CENTER_LOCATIONS);
|
|
42
|
+
export type CenterLocation = z.infer<typeof centerLocationZ>;
|
|
43
|
+
|
|
44
|
+
export const LOCATIONS = ["top", "right", "bottom", "left", "center"] as const;
|
|
45
|
+
export const locationZ = z.enum(LOCATIONS);
|
|
46
|
+
export type Location = z.infer<typeof locationZ>;
|
|
47
|
+
|
|
48
|
+
export const ALIGNMENTS = ["start", "center", "end"] as const;
|
|
49
|
+
export const alignmentZ = z.enum(ALIGNMENTS);
|
|
50
|
+
export type Alignment = z.infer<typeof alignmentZ>;
|
|
51
|
+
|
|
52
|
+
export const ORDERS = ["first", "last"] as const;
|
|
53
|
+
export const orderZ = z.enum(ORDERS);
|
|
54
|
+
export type Order = z.infer<typeof orderZ>;
|
|
55
|
+
|
|
56
|
+
export const DIMENSIONS = ["width", "height"] as const;
|
|
57
|
+
export const dimensionZ = z.enum(DIMENSIONS);
|
|
58
|
+
export type Dimension = z.infer<typeof dimensionZ>;
|
|
59
|
+
|
|
60
|
+
export const SIGNED_DIMENSIONS = ["signedWidth", "signedHeight"] as const;
|
|
61
|
+
export const signedDimensionZ = z.enum(SIGNED_DIMENSIONS);
|
|
62
|
+
export type SignedDimension = z.infer<typeof signedDimensionZ>;
|
|
63
|
+
|
|
18
64
|
/**
|
|
19
65
|
* XY is a 2D coordinate point with x and y values. Used for positioning
|
|
20
66
|
* elements in two-dimensional space.
|
|
@@ -26,3 +72,97 @@ export const xyZ = z.object({
|
|
|
26
72
|
y: z.number(),
|
|
27
73
|
});
|
|
28
74
|
export interface XY extends z.infer<typeof xyZ> {}
|
|
75
|
+
|
|
76
|
+
/** CornerLocation is an anchor corner for positioning. */
|
|
77
|
+
export const cornerLocationZ = z.object({
|
|
78
|
+
/** x is the horizontal anchor. */
|
|
79
|
+
x: xLocationZ,
|
|
80
|
+
/** y is the vertical anchor. */
|
|
81
|
+
y: yLocationZ,
|
|
82
|
+
});
|
|
83
|
+
export interface CornerLocation extends z.infer<typeof cornerLocationZ> {}
|
|
84
|
+
|
|
85
|
+
/** StickyUnits specifies the measurement units for sticky positioning. */
|
|
86
|
+
export const stickyUnitsZ = z.object({
|
|
87
|
+
/** x is the horizontal unit. */
|
|
88
|
+
x: stickyUnitZ,
|
|
89
|
+
/** y is the vertical unit. */
|
|
90
|
+
y: stickyUnitZ,
|
|
91
|
+
});
|
|
92
|
+
export interface StickyUnits extends z.infer<typeof stickyUnitsZ> {}
|
|
93
|
+
|
|
94
|
+
/** Dimensions is a 2D size with width and height values. */
|
|
95
|
+
export const dimensionsZ = z.object({
|
|
96
|
+
/** width is the width in pixels. */
|
|
97
|
+
width: z.number(),
|
|
98
|
+
/** height is the height in pixels. */
|
|
99
|
+
height: z.number(),
|
|
100
|
+
});
|
|
101
|
+
export interface Dimensions extends z.infer<typeof dimensionsZ> {}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* SignedDimensions is a 2D size whose width and height components carry sign, allowing
|
|
105
|
+
* negative values to express direction.
|
|
106
|
+
*/
|
|
107
|
+
export const signedDimensionsZ = z.object({
|
|
108
|
+
/** signedWidth is the signed width. */
|
|
109
|
+
signedWidth: z.number(),
|
|
110
|
+
/** signedHeight is the signed height. */
|
|
111
|
+
signedHeight: z.number(),
|
|
112
|
+
});
|
|
113
|
+
export interface SignedDimensions extends z.infer<typeof signedDimensionsZ> {}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* ClientXY is a 2D coordinate point expressed in client (viewport) space, matching
|
|
117
|
+
* the shape of DOM mouse events.
|
|
118
|
+
*/
|
|
119
|
+
export const clientXYZ = z.object({
|
|
120
|
+
/** clientX is the horizontal coordinate in client (viewport) space. */
|
|
121
|
+
clientX: z.number(),
|
|
122
|
+
/** clientY is the vertical coordinate in client (viewport) space. */
|
|
123
|
+
clientY: z.number(),
|
|
124
|
+
});
|
|
125
|
+
export interface ClientXY extends z.infer<typeof clientXYZ> {}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Bounds is a closed-open interval [lower, upper) over an ordered numeric value
|
|
129
|
+
* space. The TypeScript binding is generic over T so callers can express
|
|
130
|
+
* bounds over either number or bigint values; other languages emit a
|
|
131
|
+
* concrete float64-based type.
|
|
132
|
+
*/
|
|
133
|
+
export const boundsZ = <T extends numeric.Value = number>(t?: z.ZodType<T>) =>
|
|
134
|
+
z.object({
|
|
135
|
+
/** lower is the inclusive lower bound. */
|
|
136
|
+
lower: t ?? z.number(),
|
|
137
|
+
/** upper is the exclusive upper bound. */
|
|
138
|
+
upper: t ?? z.number(),
|
|
139
|
+
});
|
|
140
|
+
export interface Bounds<T extends numeric.Value = number> {
|
|
141
|
+
lower: T;
|
|
142
|
+
upper: T;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Viewport is the camera state of a viewport. */
|
|
146
|
+
export const viewportZ = z.object({
|
|
147
|
+
/** zoom is the zoom level where 1.0 equals 100%. */
|
|
148
|
+
zoom: z.number().default(1),
|
|
149
|
+
/** position is the (x, y) pan offset of the viewport. */
|
|
150
|
+
position: xyZ,
|
|
151
|
+
});
|
|
152
|
+
export interface Viewport extends z.infer<typeof viewportZ> {}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* StickyXY is a position that can be anchored to different corners of a
|
|
156
|
+
* container with configurable units (pixels or decimal fractions).
|
|
157
|
+
*/
|
|
158
|
+
export const stickyXYZ = z.object({
|
|
159
|
+
/** x is the horizontal coordinate. */
|
|
160
|
+
x: z.number(),
|
|
161
|
+
/** y is the vertical coordinate. */
|
|
162
|
+
y: z.number(),
|
|
163
|
+
/** root is the optional anchor corner for the position. */
|
|
164
|
+
root: cornerLocationZ.optional(),
|
|
165
|
+
/** units is the optional unit specification for the coordinates. */
|
|
166
|
+
units: stickyUnitsZ.optional(),
|
|
167
|
+
});
|
|
168
|
+
export interface StickyXY extends z.infer<typeof stickyXYZ> {}
|
package/src/spatial/xy/xy.ts
CHANGED
|
@@ -12,19 +12,19 @@ import { z } from "zod";
|
|
|
12
12
|
import {
|
|
13
13
|
type AngularDirection,
|
|
14
14
|
type ClientXY,
|
|
15
|
-
|
|
16
|
-
type CrudeDirection,
|
|
15
|
+
clientXYZ,
|
|
17
16
|
dimensionsZ,
|
|
18
17
|
type Direction,
|
|
19
18
|
type NumberCouple,
|
|
20
19
|
numberCouple,
|
|
21
20
|
signedDimensionsZ,
|
|
21
|
+
type XY,
|
|
22
|
+
xyZ,
|
|
22
23
|
} from "@/spatial/base";
|
|
23
|
-
import { direction as dir } from "@/spatial/direction";
|
|
24
|
+
import { direction as dir, type direction } from "@/spatial/direction";
|
|
24
25
|
import { type location } from "@/spatial/location";
|
|
25
|
-
import { type XY, xyZ } from "@/spatial/types.gen";
|
|
26
26
|
|
|
27
|
-
export { type ClientXY as Client,
|
|
27
|
+
export { type ClientXY as Client, clientXYZ, type XY, xyZ };
|
|
28
28
|
|
|
29
29
|
/** A crude representation of a {@link XY} coordinate as a zod schema. */
|
|
30
30
|
export const crudeZ = z.union([
|
|
@@ -33,7 +33,7 @@ export const crudeZ = z.union([
|
|
|
33
33
|
numberCouple,
|
|
34
34
|
dimensionsZ,
|
|
35
35
|
signedDimensionsZ,
|
|
36
|
-
|
|
36
|
+
clientXYZ,
|
|
37
37
|
]);
|
|
38
38
|
|
|
39
39
|
/** A crude representation of a {@link XY} coordinate. */
|
|
@@ -141,7 +141,7 @@ export const translate: Translate = (a, b, v, ...cb): XY => {
|
|
|
141
141
|
* @returns the given coordinate the given direction set to the given value.
|
|
142
142
|
* @example set({ x: 1, y: 2 }, "x", 3) // { x: 3, y: 2 }
|
|
143
143
|
*/
|
|
144
|
-
export const set = (c: Crude, direction:
|
|
144
|
+
export const set = (c: Crude, direction: direction.Crude, value: number): XY => {
|
|
145
145
|
const xy = construct(c);
|
|
146
146
|
const d = dir.construct(direction);
|
|
147
147
|
if (d === "x") return { x: value, y: xy.y };
|