@synnaxlabs/x 0.44.2 → 0.44.4

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.
Files changed (131) hide show
  1. package/.turbo/turbo-build.log +35 -39
  2. package/dist/base-BLNViP3D.cjs +1 -0
  3. package/dist/{base-DFq0vvGn.js → base-BORMP3mH.js} +14 -11
  4. package/dist/bounds-BQqppNFf.js +186 -0
  5. package/dist/bounds-BXbqBINt.cjs +1 -0
  6. package/dist/bounds.cjs +1 -1
  7. package/dist/bounds.js +1 -1
  8. package/dist/{box-CO_2_DGG.js → box-DRH5SOaY.js} +67 -73
  9. package/dist/box-qgxWXNhm.cjs +1 -0
  10. package/dist/box.cjs +1 -1
  11. package/dist/box.js +1 -1
  12. package/dist/deep.cjs +1 -1
  13. package/dist/deep.js +1 -1
  14. package/dist/{dimensions-CRgergMS.js → dimensions-RaRkesPq.js} +1 -1
  15. package/dist/{dimensions-D2QGoNXO.cjs → dimensions-qY12pyfC.cjs} +1 -1
  16. package/dist/dimensions.cjs +1 -1
  17. package/dist/dimensions.js +1 -1
  18. package/dist/direction-DKdfJwj7.js +19 -0
  19. package/dist/direction-XCdrc4is.cjs +1 -0
  20. package/dist/direction.cjs +1 -1
  21. package/dist/direction.js +1 -1
  22. package/dist/{external-Birv9jaY.js → external-BM_NS5yM.js} +6 -6
  23. package/dist/external-E3ErJeeM.cjs +1 -0
  24. package/dist/index.cjs +3 -3
  25. package/dist/index.js +244 -240
  26. package/dist/{location-Ar5y2DX2.js → location-CGLioInQ.js} +16 -21
  27. package/dist/location-DJ_K4SlP.cjs +1 -0
  28. package/dist/location.cjs +1 -1
  29. package/dist/location.js +1 -1
  30. package/dist/{path-DVFrKaNI.js → path-Blh4wJuA.js} +24 -21
  31. package/dist/path-CPSfCjde.cjs +1 -0
  32. package/dist/record-BwjIgrpU.cjs +1 -0
  33. package/dist/record-tSFQKmdG.js +19 -0
  34. package/dist/record.cjs +1 -1
  35. package/dist/record.js +1 -1
  36. package/dist/{scale-C6qKDbRb.cjs → scale-76Azh2EE.cjs} +1 -1
  37. package/dist/{scale-EWNUk-bn.js → scale-BhIvACdB.js} +4 -4
  38. package/dist/scale.cjs +1 -1
  39. package/dist/scale.js +1 -1
  40. package/dist/{series-EA1uaEDj.js → series-kgnLXSDr.js} +622 -489
  41. package/dist/series-tAhThbnz.cjs +6 -0
  42. package/dist/{spatial-DGpZ2sO3.cjs → spatial-BsGadoUr.cjs} +1 -1
  43. package/dist/{spatial-BSWPzMkK.js → spatial-QY891r0E.js} +1 -1
  44. package/dist/spatial.cjs +1 -1
  45. package/dist/spatial.js +14 -16
  46. package/dist/src/breaker/breaker.d.ts +2 -1
  47. package/dist/src/breaker/breaker.d.ts.map +1 -1
  48. package/dist/src/deep/path.d.ts.map +1 -1
  49. package/dist/src/id/id.d.ts +3 -1
  50. package/dist/src/id/id.d.ts.map +1 -1
  51. package/dist/src/math/math.d.ts +2 -1
  52. package/dist/src/math/math.d.ts.map +1 -1
  53. package/dist/src/record/record.d.ts +18 -0
  54. package/dist/src/record/record.d.ts.map +1 -1
  55. package/dist/src/spatial/base.d.ts +12 -0
  56. package/dist/src/spatial/base.d.ts.map +1 -1
  57. package/dist/src/spatial/direction/direction.d.ts +5 -1
  58. package/dist/src/spatial/direction/direction.d.ts.map +1 -1
  59. package/dist/src/spatial/external.d.ts +0 -1
  60. package/dist/src/spatial/external.d.ts.map +1 -1
  61. package/dist/src/spatial/xy/xy.d.ts +3 -0
  62. package/dist/src/spatial/xy/xy.d.ts.map +1 -1
  63. package/dist/src/status/status.d.ts +1 -0
  64. package/dist/src/status/status.d.ts.map +1 -1
  65. package/dist/src/strings/strings.d.ts +1 -1
  66. package/dist/src/strings/strings.d.ts.map +1 -1
  67. package/dist/src/telem/series.d.ts +7 -0
  68. package/dist/src/telem/series.d.ts.map +1 -1
  69. package/dist/src/telem/telem.d.ts +86 -1
  70. package/dist/src/telem/telem.d.ts.map +1 -1
  71. package/dist/src/zod/util.d.ts.map +1 -1
  72. package/dist/telem.cjs +1 -1
  73. package/dist/telem.js +1 -1
  74. package/dist/xy-BKIJiLu_.cjs +1 -0
  75. package/dist/{xy-C_-hb3Q2.js → xy-CBuhMaIo.js} +41 -31
  76. package/dist/xy.cjs +1 -1
  77. package/dist/xy.js +1 -1
  78. package/dist/zod.cjs +1 -1
  79. package/dist/zod.js +1 -1
  80. package/package.json +3 -8
  81. package/src/breaker/breaker.ts +4 -0
  82. package/src/deep/path.spec.ts +14 -0
  83. package/src/deep/path.ts +9 -2
  84. package/src/id/id.ts +8 -4
  85. package/src/math/math.spec.ts +20 -0
  86. package/src/math/math.ts +32 -29
  87. package/src/record/record.spec.ts +31 -0
  88. package/src/record/record.ts +23 -0
  89. package/src/spatial/base.ts +4 -0
  90. package/src/spatial/bounds/bounds.ts +1 -1
  91. package/src/spatial/direction/direction.spec.ts +35 -1
  92. package/src/spatial/direction/direction.ts +12 -0
  93. package/src/spatial/external.ts +0 -1
  94. package/src/spatial/xy/xy.spec.ts +124 -7
  95. package/src/spatial/xy/xy.ts +15 -2
  96. package/src/status/status.ts +11 -0
  97. package/src/strings/strings.spec.ts +3 -0
  98. package/src/strings/strings.ts +2 -1
  99. package/src/telem/series.spec.ts +543 -2
  100. package/src/telem/series.ts +28 -9
  101. package/src/telem/telem.spec.ts +606 -0
  102. package/src/telem/telem.ts +143 -5
  103. package/src/zod/util.ts +5 -3
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/vite.config.ts +0 -1
  106. package/dist/base-BAM2mqCy.cjs +0 -1
  107. package/dist/bounds-D6e9xoHt.cjs +0 -1
  108. package/dist/bounds-Dj9nG39I.js +0 -174
  109. package/dist/box-Cxki783Y.cjs +0 -1
  110. package/dist/direction-386XDm2w.cjs +0 -1
  111. package/dist/direction-8etxfKaR.js +0 -17
  112. package/dist/external-DsmsSN1Y.cjs +0 -1
  113. package/dist/location-DZi8ftXp.cjs +0 -1
  114. package/dist/path-BeMr8xWN.cjs +0 -1
  115. package/dist/position-DSy2hONH.cjs +0 -1
  116. package/dist/position-PQ6op54I.js +0 -85
  117. package/dist/position.cjs +0 -1
  118. package/dist/position.js +0 -4
  119. package/dist/record-CAcQ5PNX.js +0 -14
  120. package/dist/record-YvCh7bzB.cjs +0 -1
  121. package/dist/series-CcA_WjbJ.cjs +0 -6
  122. package/dist/src/spatial/position/index.d.ts +0 -2
  123. package/dist/src/spatial/position/index.d.ts.map +0 -1
  124. package/dist/src/spatial/position/position.d.ts +0 -20
  125. package/dist/src/spatial/position/position.d.ts.map +0 -1
  126. package/dist/src/spatial/position/position.spec.d.ts +0 -2
  127. package/dist/src/spatial/position/position.spec.d.ts.map +0 -1
  128. package/dist/xy-CUE3QDNn.cjs +0 -1
  129. package/src/spatial/position/index.ts +0 -10
  130. package/src/spatial/position/position.spec.ts +0 -211
  131. package/src/spatial/position/position.ts +0 -157
@@ -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 { describe, expect, test } from "vitest";
10
+ import { describe, expect, it, test } from "vitest";
11
11
 
12
12
  import * as direction from "@/spatial/direction/direction";
13
13
 
@@ -22,4 +22,38 @@ describe("Direction", () => {
22
22
  test(name, () => expect(direction.construct(arg)).toEqual("y")),
23
23
  );
24
24
  });
25
+
26
+ describe("isX", () => {
27
+ const TESTS: [direction.Crude, boolean][] = [
28
+ ["x", true],
29
+ ["y", false],
30
+ ["left", true],
31
+ ["right", true],
32
+ ["top", false],
33
+ ["bottom", false],
34
+ ["center", false],
35
+ ];
36
+ TESTS.forEach(([arg, expected]) => {
37
+ it(`should return ${expected} for ${arg}`, () => {
38
+ expect(direction.isX(arg)).toBe(expected);
39
+ });
40
+ });
41
+ });
42
+
43
+ describe("isY", () => {
44
+ const TESTS: [direction.Crude, boolean][] = [
45
+ ["x", false],
46
+ ["y", true],
47
+ ["left", false],
48
+ ["right", false],
49
+ ["top", true],
50
+ ["bottom", true],
51
+ ["center", false],
52
+ ];
53
+ TESTS.forEach(([arg, expected]) => {
54
+ it(`should return ${expected} for ${arg}`, () => {
55
+ expect(direction.isY(arg)).toBe(expected);
56
+ });
57
+ });
58
+ });
25
59
  });
@@ -10,6 +10,8 @@
10
10
  import {
11
11
  type CrudeDirection,
12
12
  crudeDirection,
13
+ type CrudeXDirection,
14
+ type CrudeYDirection,
13
15
  type Dimension,
14
16
  type Direction,
15
17
  direction,
@@ -25,6 +27,8 @@ export { Direction, direction, DIRECTIONS };
25
27
  export const crude = crudeDirection;
26
28
 
27
29
  export type Crude = CrudeDirection;
30
+ export type CrudeX = CrudeXDirection;
31
+ export type CrudeY = CrudeYDirection;
28
32
 
29
33
  export const construct = (c: Crude): Direction => {
30
34
  if (DIRECTIONS.includes(c as Direction)) return c as Direction;
@@ -45,3 +49,11 @@ export const isDirection = (c: unknown): c is Direction => crude.safeParse(c).su
45
49
 
46
50
  export const signedDimension = (direction: CrudeDirection): SignedDimension =>
47
51
  construct(direction) === "x" ? "signedWidth" : "signedHeight";
52
+
53
+ export const isX = (direction: CrudeDirection): direction is CrudeXDirection => {
54
+ if (direction === "center") return false;
55
+ return construct(direction) === "x";
56
+ };
57
+
58
+ export const isY = (direction: CrudeDirection): direction is CrudeYDirection =>
59
+ construct(direction) === "y";
@@ -12,7 +12,6 @@ export { box } from "@/spatial/box";
12
12
  export * from "@/spatial/dimensions";
13
13
  export * from "@/spatial/direction";
14
14
  export * from "@/spatial/location";
15
- export * from "@/spatial/position";
16
15
  export * from "@/spatial/scale";
17
16
  export * as spatial from "@/spatial/spatial";
18
17
  export * from "@/spatial/xy";
@@ -9,7 +9,8 @@
9
9
 
10
10
  import { describe, expect, it, test } from "vitest";
11
11
 
12
- import * as xy from "@/spatial/xy/xy";
12
+ import { location } from "@/spatial/location";
13
+ import { xy } from "@/spatial/xy";
13
14
 
14
15
  describe("XY", () => {
15
16
  describe("construction", () => {
@@ -63,6 +64,44 @@ describe("XY", () => {
63
64
  expect(p.y).toEqual(9);
64
65
  });
65
66
 
67
+ describe("translate with Direction", () => {
68
+ it("should translate in the x direction", () => {
69
+ const p = xy.construct([1, 2]);
70
+ const result = xy.translate(p, "x", 5);
71
+ expect(result.x).toEqual(6);
72
+ expect(result.y).toEqual(2);
73
+ });
74
+
75
+ it("should translate in the y direction", () => {
76
+ const p = xy.construct([1, 2]);
77
+ const result = xy.translate(p, "y", 3);
78
+ expect(result.x).toEqual(1);
79
+ expect(result.y).toEqual(5);
80
+ });
81
+
82
+ it("should translate negative values in x direction", () => {
83
+ const p = xy.construct([10, 20]);
84
+ const result = xy.translate(p, "x", -7);
85
+ expect(result.x).toEqual(3);
86
+ expect(result.y).toEqual(20);
87
+ });
88
+
89
+ it("should translate negative values in y direction", () => {
90
+ const p = xy.construct([10, 20]);
91
+ const result = xy.translate(p, "y", -15);
92
+ expect(result.x).toEqual(10);
93
+ expect(result.y).toEqual(5);
94
+ });
95
+
96
+ it("should work with different input formats", () => {
97
+ const couple = xy.translate([5, 5], "x", 10);
98
+ expect(couple).toEqual({ x: 15, y: 5 });
99
+
100
+ const dims = xy.translate({ width: 3, height: 4 }, "y", 6);
101
+ expect(dims).toEqual({ x: 3, y: 10 });
102
+ });
103
+ });
104
+
66
105
  describe("equals", () => {
67
106
  const TESTS: Array<[xy.Crude, xy.Crude, boolean]> = [
68
107
  [[1, 1], { x: 1, y: 1 }, true],
@@ -80,7 +119,7 @@ describe("XY", () => {
80
119
  });
81
120
  it("should retrun true if the two points are within the given threshold", () => {
82
121
  const p = xy.construct([1, 1]);
83
- expect(xy.equals(p, [1.1, 1.1], 0.15)).toBe(true);
122
+ expect(xy.equals(p, [1.1, 1.1], 0.15)).toBeTruthy();
84
123
  });
85
124
  });
86
125
  test("couple", () => {
@@ -89,15 +128,15 @@ describe("XY", () => {
89
128
  });
90
129
  describe("isNan", () => {
91
130
  it("should return true if x or y is NaN", () => {
92
- expect(xy.isNan(xy.construct([1, NaN]))).toBe(true);
93
- expect(xy.isNan(xy.construct([NaN, 1]))).toBe(true);
131
+ expect(xy.isNan(xy.construct([1, NaN]))).toBeTruthy();
132
+ expect(xy.isNan(xy.construct([NaN, 1]))).toBeTruthy();
94
133
  });
95
134
  });
96
135
  describe("isFinite", () => {
97
136
  it("should return true if x or y is finite", () => {
98
- expect(xy.isFinite(xy.construct([1, 2]))).toBe(true);
99
- expect(xy.isFinite(xy.construct([Infinity, 2]))).toBe(false);
100
- expect(xy.isFinite(xy.construct([1, Infinity]))).toBe(false);
137
+ expect(xy.isFinite(xy.construct([1, 2]))).toBeTruthy();
138
+ expect(xy.isFinite(xy.construct([Infinity, 2]))).toBeFalsy();
139
+ expect(xy.isFinite(xy.construct([1, Infinity]))).toBeFalsy();
101
140
  });
102
141
  });
103
142
  describe("distance", () => {
@@ -151,4 +190,82 @@ describe("XY", () => {
151
190
  expect(xy.swap({ width: 5, height: 6 })).toEqual({ x: 6, y: 5 });
152
191
  });
153
192
  });
193
+
194
+ describe("translate with location.XY", () => {
195
+ it("should translate with top-left location", () => {
196
+ const p = xy.construct([10, 10]);
197
+ const result = xy.translate(p, location.TOP_LEFT, [5, 5]);
198
+ expect(result).toEqual({ x: 5, y: 5 });
199
+ });
200
+
201
+ it("should translate with top-right location", () => {
202
+ const p = xy.construct([10, 10]);
203
+ const result = xy.translate(p, location.TOP_RIGHT, [5, 5]);
204
+ expect(result).toEqual({ x: 15, y: 5 });
205
+ });
206
+
207
+ it("should translate with bottom-left location", () => {
208
+ const p = xy.construct([10, 10]);
209
+ const result = xy.translate(p, location.BOTTOM_LEFT, [5, 5]);
210
+ expect(result).toEqual({ x: 5, y: 15 });
211
+ });
212
+
213
+ it("should translate with bottom-right location", () => {
214
+ const p = xy.construct([10, 10]);
215
+ const result = xy.translate(p, location.BOTTOM_RIGHT, [5, 5]);
216
+ expect(result).toEqual({ x: 15, y: 15 });
217
+ });
218
+
219
+ it("should handle center x locations", () => {
220
+ const p = xy.construct([10, 10]);
221
+ const result = xy.translate(p, location.TOP_CENTER, [5, 5]);
222
+ expect(result).toEqual({ x: 10, y: 5 });
223
+
224
+ const result2 = xy.translate(p, location.BOTTOM_CENTER, [5, 5]);
225
+ expect(result2).toEqual({ x: 10, y: 15 });
226
+ });
227
+
228
+ it("should handle center y locations", () => {
229
+ const p = xy.construct([10, 10]);
230
+ const result = xy.translate(p, location.CENTER_LEFT, [5, 5]);
231
+ expect(result).toEqual({ x: 5, y: 10 });
232
+
233
+ const result2 = xy.translate(p, location.CENTER_RIGHT, [5, 5]);
234
+ expect(result2).toEqual({ x: 15, y: 10 });
235
+ });
236
+
237
+ it("should handle center-center location", () => {
238
+ const p = xy.construct([10, 10]);
239
+ const result = xy.translate(p, location.CENTER, [5, 5]);
240
+ expect(result).toEqual({ x: 10, y: 10 });
241
+ });
242
+
243
+ it("should work with different coordinate input formats", () => {
244
+ const result1 = xy.translate([10, 10], { x: "left", y: "top" }, [5, 5]);
245
+ expect(result1).toEqual({ x: 5, y: 5 });
246
+
247
+ const result2 = xy.translate(
248
+ { width: 10, height: 10 },
249
+ { x: "right", y: "bottom" },
250
+ { width: 5, height: 5 },
251
+ );
252
+ expect(result2).toEqual({ x: 15, y: 15 });
253
+ });
254
+
255
+ it("should handle negative translations correctly", () => {
256
+ const p = xy.construct([10, 10]);
257
+ const result = xy.translate(p, location.TOP_LEFT, [-5, -5]);
258
+ expect(result).toEqual({ x: 15, y: 15 });
259
+
260
+ const result2 = xy.translate(p, location.BOTTOM_RIGHT, [-5, -5]);
261
+ expect(result2).toEqual({ x: 5, y: 5 });
262
+ });
263
+
264
+ it("should work with custom location objects", () => {
265
+ const p = xy.construct([10, 10]);
266
+ const customLocation: location.XY = { x: "left", y: "bottom" };
267
+ const result = xy.translate(p, customLocation, [3, 7]);
268
+ expect(result).toEqual({ x: 7, y: 17 });
269
+ });
270
+ });
154
271
  });
@@ -20,6 +20,7 @@ import {
20
20
  type XY,
21
21
  xy,
22
22
  } from "@/spatial/base";
23
+ import { type location } from "@/spatial/location";
23
24
 
24
25
  export { type ClientXY as Client, clientXY, type XY, xy };
25
26
 
@@ -109,15 +110,27 @@ interface Translate {
109
110
  (a: Crude, b: Crude, ...cb: Crude[]): XY;
110
111
  /** @returns the coordinates translated in the given direction by the given value. */
111
112
  (a: Crude, direction: Direction, value: number): XY;
113
+ /** @returns the coordinates translated by the given amount. */
114
+ (a: Crude, direction: location.XY, xy: Crude): XY;
112
115
  }
113
116
 
114
117
  export const translate: Translate = (a, b, v, ...cb): XY => {
115
- if (typeof b === "string" && typeof v === "number") {
118
+ if (typeof b === "string") {
119
+ if (typeof v !== "number") throw new Error("The value must be a number.");
116
120
  if (b === "x") return translateX(a, v);
117
121
  return translateY(a, v);
118
122
  }
123
+ if (typeof b === "object" && "x" in b && typeof b.x === "string") {
124
+ const amnt = construct(v);
125
+ const root = construct(a);
126
+ if (b.x === "left") amnt.x = -amnt.x;
127
+ else if (b.x === "center") amnt.x = 0;
128
+ if (b.y === "top") amnt.y = -amnt.y;
129
+ else if (b.y === "center") amnt.y = 0;
130
+ return { x: root.x + amnt.x, y: root.y + amnt.y };
131
+ }
119
132
  return [a, b, v ?? ZERO, ...cb].reduce((p: XY, c) => {
120
- const xy = construct(c as Crude);
133
+ const xy = construct(c);
121
134
  return { x: p.x + xy.x, y: p.y + xy.y };
122
135
  }, ZERO);
123
136
  };
@@ -89,3 +89,14 @@ export const create = <D = undefined, V extends Variant = Variant>(
89
89
  time: TimeStamp.now(),
90
90
  ...spec,
91
91
  }) as unknown as Status<D, V>;
92
+
93
+ export const filterVariant = (
94
+ variant: Variant,
95
+ only: Variant | Variant[] = [],
96
+ ): Variant | undefined => {
97
+ if (Array.isArray(only)) {
98
+ if (only.includes(variant)) return variant;
99
+ return undefined;
100
+ }
101
+ return only === variant ? variant : undefined;
102
+ };
@@ -15,6 +15,9 @@ describe("naturalLanguageJoin", () => {
15
15
  it("should return an empty string for an empty array", () =>
16
16
  expect(strings.naturalLanguageJoin([])).toBe(""));
17
17
 
18
+ it("should return the string for a single string", () =>
19
+ expect(strings.naturalLanguageJoin("apple")).toBe("apple"));
20
+
18
21
  it("should return the zeroLength string for an empty array if provided", () =>
19
22
  expect(strings.naturalLanguageJoin([], "No items")).toBe("No items"));
20
23
 
@@ -24,9 +24,10 @@
24
24
  * ```
25
25
  */
26
26
  export const naturalLanguageJoin = (
27
- strings: string[],
27
+ strings: string | string[],
28
28
  zeroLength: string = "",
29
29
  ): string => {
30
+ if (typeof strings === "string") return strings;
30
31
  const length = strings.length;
31
32
  if (length === 0) return zeroLength;
32
33
  if (length === 1) return strings[0];