@synnaxlabs/x 0.43.0 → 0.44.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.
Files changed (288) hide show
  1. package/.turbo/turbo-build.log +105 -93
  2. package/dist/base-BAM2mqCy.cjs +1 -0
  3. package/dist/base-DFq0vvGn.js +38 -0
  4. package/dist/binary.cjs +1 -1
  5. package/dist/binary.js +1 -1
  6. package/dist/bounds-D6e9xoHt.cjs +1 -0
  7. package/dist/bounds-Dj9nG39I.js +174 -0
  8. package/dist/bounds.cjs +1 -1
  9. package/dist/bounds.js +2 -2
  10. package/dist/box-CO_2_DGG.js +209 -0
  11. package/dist/box-Cxki783Y.cjs +1 -0
  12. package/dist/box.cjs +1 -1
  13. package/dist/box.js +1 -1
  14. package/dist/caseconv.cjs +1 -1
  15. package/dist/caseconv.js +2 -2
  16. package/dist/change-C-YELKx6.cjs +1 -0
  17. package/dist/change-DLl6DccR.js +12 -0
  18. package/dist/change.cjs +1 -1
  19. package/dist/change.js +2 -10
  20. package/dist/compare.cjs +1 -1
  21. package/dist/compare.js +1 -1
  22. package/dist/deep.cjs +1 -1
  23. package/dist/deep.js +95 -96
  24. package/dist/dimensions-CRgergMS.js +43 -0
  25. package/dist/dimensions-D2QGoNXO.cjs +1 -0
  26. package/dist/dimensions.cjs +1 -1
  27. package/dist/dimensions.js +2 -41
  28. package/dist/direction-386XDm2w.cjs +1 -0
  29. package/dist/{index-DxU1zwsd.js → direction-8etxfKaR.js} +4 -3
  30. package/dist/direction.cjs +1 -1
  31. package/dist/direction.js +1 -1
  32. package/dist/external-B9AAGv50.cjs +1 -0
  33. package/dist/external-BFgJjMcS.js +23 -0
  34. package/dist/external-BPgtxa8d.js +29 -0
  35. package/dist/external-BYuXBYJh.js +40 -0
  36. package/dist/external-mffsMzJx.cjs +1 -0
  37. package/dist/external-uXk0Avrg.cjs +1 -0
  38. package/dist/index-B1m2qvBT.cjs +1 -0
  39. package/dist/{index-4GlOgZuh.js → index-B5l_quQn.js} +35 -42
  40. package/dist/index-BQe8OIgm.cjs +3 -0
  41. package/dist/index-D2xcvEO5.js +46 -0
  42. package/dist/index-DdhM_E4k.cjs +1 -0
  43. package/dist/index-PNh31WTW.js +125 -0
  44. package/dist/index.cjs +3 -5
  45. package/dist/index.js +685 -5363
  46. package/dist/kv.cjs +1 -1
  47. package/dist/kv.js +2 -45
  48. package/dist/{index-D6V-8SKw.js → location-Ar5y2DX2.js} +26 -26
  49. package/dist/location-DZi8ftXp.cjs +1 -0
  50. package/dist/location.cjs +1 -1
  51. package/dist/location.js +1 -1
  52. package/dist/observe.cjs +1 -1
  53. package/dist/observe.js +16 -20
  54. package/dist/path-BXdMenka.js +101 -0
  55. package/dist/path-st_E5-LJ.cjs +1 -0
  56. package/dist/position-DSy2hONH.cjs +1 -0
  57. package/dist/position-PQ6op54I.js +85 -0
  58. package/dist/position.cjs +1 -1
  59. package/dist/position.js +2 -83
  60. package/dist/record-CAcQ5PNX.js +14 -0
  61. package/dist/record-YvCh7bzB.cjs +1 -0
  62. package/dist/record.cjs +1 -1
  63. package/dist/record.js +2 -8
  64. package/dist/runtime.cjs +1 -1
  65. package/dist/runtime.js +2 -27
  66. package/dist/scale-C6qKDbRb.cjs +1 -0
  67. package/dist/{index-BUa-NXAX.js → scale-EWNUk-bn.js} +55 -59
  68. package/dist/scale.cjs +1 -1
  69. package/dist/scale.js +1 -1
  70. package/dist/{index-DBGAIs_7.js → series-Bn5y1tD1.js} +835 -759
  71. package/dist/series-CYAhDD6B.cjs +6 -0
  72. package/dist/spatial-BSWPzMkK.js +11 -0
  73. package/dist/spatial-DGpZ2sO3.cjs +1 -0
  74. package/dist/spatial.cjs +1 -1
  75. package/dist/spatial.js +18 -25
  76. package/dist/src/binary/codec.d.ts +1 -1
  77. package/dist/src/binary/codec.d.ts.map +1 -1
  78. package/dist/src/breaker/breaker.d.ts +2 -2
  79. package/dist/src/breaker/breaker.d.ts.map +1 -1
  80. package/dist/src/caseconv/caseconv.d.ts +0 -1
  81. package/dist/src/caseconv/caseconv.d.ts.map +1 -1
  82. package/dist/src/change/change.d.ts +1 -1
  83. package/dist/src/change/change.d.ts.map +1 -1
  84. package/dist/src/color/color.d.ts +2 -2
  85. package/dist/src/color/color.d.ts.map +1 -1
  86. package/dist/src/color/gradient.d.ts +1 -1
  87. package/dist/src/color/gradient.d.ts.map +1 -1
  88. package/dist/src/color/palette.d.ts +3 -3
  89. package/dist/src/color/palette.d.ts.map +1 -1
  90. package/dist/src/compare/compare.d.ts +4 -4
  91. package/dist/src/compare/compare.d.ts.map +1 -1
  92. package/dist/src/control/control.d.ts +9 -9
  93. package/dist/src/control/control.d.ts.map +1 -1
  94. package/dist/src/deep/merge.d.ts +1 -1
  95. package/dist/src/deep/merge.d.ts.map +1 -1
  96. package/dist/src/deep/path.d.ts +6 -6
  97. package/dist/src/deep/path.d.ts.map +1 -1
  98. package/dist/src/destructor.d.ts +6 -2
  99. package/dist/src/destructor.d.ts.map +1 -1
  100. package/dist/src/errors/errors.d.ts +5 -1
  101. package/dist/src/errors/errors.d.ts.map +1 -1
  102. package/dist/src/flush.d.ts +11 -0
  103. package/dist/src/flush.d.ts.map +1 -0
  104. package/dist/src/id/id.d.ts +1 -0
  105. package/dist/src/id/id.d.ts.map +1 -1
  106. package/dist/src/identity.d.ts +2 -2
  107. package/dist/src/identity.d.ts.map +1 -1
  108. package/dist/src/index.d.ts +3 -1
  109. package/dist/src/index.d.ts.map +1 -1
  110. package/dist/src/jsonrpc/jsonrpc.d.ts +1 -1
  111. package/dist/src/jsonrpc/jsonrpc.d.ts.map +1 -1
  112. package/dist/src/kv/types.d.ts +1 -1
  113. package/dist/src/kv/types.d.ts.map +1 -1
  114. package/dist/src/map/index.d.ts +2 -0
  115. package/dist/src/map/index.d.ts.map +1 -0
  116. package/dist/src/map/map.d.ts +2 -0
  117. package/dist/src/map/map.d.ts.map +1 -0
  118. package/dist/src/map/map.spec.d.ts +2 -0
  119. package/dist/src/map/map.spec.d.ts.map +1 -0
  120. package/dist/src/math/math.d.ts +2 -4
  121. package/dist/src/math/math.d.ts.map +1 -1
  122. package/dist/src/migrate/migrate.d.ts +1 -1
  123. package/dist/src/migrate/migrate.d.ts.map +1 -1
  124. package/dist/src/notation/notation.d.ts +1 -1
  125. package/dist/src/notation/notation.d.ts.map +1 -1
  126. package/dist/src/optional.d.ts +0 -3
  127. package/dist/src/optional.d.ts.map +1 -1
  128. package/dist/src/record/index.d.ts +2 -0
  129. package/dist/src/record/index.d.ts.map +1 -0
  130. package/dist/src/record/record.d.ts +90 -0
  131. package/dist/src/record/record.d.ts.map +1 -0
  132. package/dist/src/record/record.spec.d.ts.map +1 -0
  133. package/dist/src/runtime/os.d.ts +1 -1
  134. package/dist/src/runtime/os.d.ts.map +1 -1
  135. package/dist/src/spatial/base.d.ts +1 -1
  136. package/dist/src/spatial/base.d.ts.map +1 -1
  137. package/dist/src/spatial/box/box.d.ts +2 -1
  138. package/dist/src/spatial/box/box.d.ts.map +1 -1
  139. package/dist/src/spatial/dimensions/dimensions.d.ts +1 -1
  140. package/dist/src/spatial/dimensions/dimensions.d.ts.map +1 -1
  141. package/dist/src/spatial/direction/direction.d.ts +3 -3
  142. package/dist/src/spatial/direction/direction.d.ts.map +1 -1
  143. package/dist/src/spatial/location/location.d.ts +1 -1
  144. package/dist/src/spatial/location/location.d.ts.map +1 -1
  145. package/dist/src/spatial/scale/scale.d.ts +1 -1
  146. package/dist/src/spatial/scale/scale.d.ts.map +1 -1
  147. package/dist/src/spatial/xy/xy.d.ts +2 -1
  148. package/dist/src/spatial/xy/xy.d.ts.map +1 -1
  149. package/dist/src/status/index.d.ts +1 -1
  150. package/dist/src/status/index.d.ts.map +1 -1
  151. package/dist/src/status/status.d.ts +42 -0
  152. package/dist/src/status/status.d.ts.map +1 -0
  153. package/dist/src/status/status.spec.d.ts +2 -0
  154. package/dist/src/status/status.spec.d.ts.map +1 -0
  155. package/dist/src/strings/strings.d.ts +16 -0
  156. package/dist/src/strings/strings.d.ts.map +1 -1
  157. package/dist/src/telem/gl.d.ts +1 -1
  158. package/dist/src/telem/gl.d.ts.map +1 -1
  159. package/dist/src/telem/series.d.ts +17 -16
  160. package/dist/src/telem/series.d.ts.map +1 -1
  161. package/dist/src/telem/telem.d.ts +42 -19
  162. package/dist/src/telem/telem.d.ts.map +1 -1
  163. package/dist/src/testutil/testutil.d.ts +1 -0
  164. package/dist/src/testutil/testutil.d.ts.map +1 -1
  165. package/dist/src/testutil/testutil.spec.d.ts +2 -0
  166. package/dist/src/testutil/testutil.spec.d.ts.map +1 -0
  167. package/dist/src/zod/external.d.ts +1 -0
  168. package/dist/src/zod/external.d.ts.map +1 -1
  169. package/dist/src/zod/nullToUndefined.d.ts +1 -1
  170. package/dist/src/zod/nullToUndefined.d.ts.map +1 -1
  171. package/dist/src/zod/toArray.d.ts +3 -0
  172. package/dist/src/zod/toArray.d.ts.map +1 -0
  173. package/dist/src/zod/toArray.spec.d.ts +2 -0
  174. package/dist/src/zod/toArray.spec.d.ts.map +1 -0
  175. package/dist/src/zod/util.d.ts +1 -1
  176. package/dist/src/zod/util.d.ts.map +1 -1
  177. package/dist/telem.cjs +1 -1
  178. package/dist/telem.js +10 -11
  179. package/dist/url.cjs +1 -1
  180. package/dist/url.js +16 -19
  181. package/dist/worker.cjs +1 -1
  182. package/dist/worker.js +18 -22
  183. package/dist/xy-CUE3QDNn.cjs +1 -0
  184. package/dist/{index-C-qYOegc.js → xy-C_-hb3Q2.js} +67 -62
  185. package/dist/xy.cjs +1 -1
  186. package/dist/xy.js +1 -1
  187. package/dist/zod.cjs +1 -1
  188. package/dist/zod.js +2 -19
  189. package/package.json +13 -18
  190. package/src/binary/codec.spec.ts +1 -1
  191. package/src/binary/codec.ts +1 -1
  192. package/src/breaker/breaker.ts +1 -1
  193. package/src/caseconv/caseconv.ts +10 -12
  194. package/src/change/change.ts +1 -1
  195. package/src/color/color.ts +1 -1
  196. package/src/color/gradient.ts +1 -1
  197. package/src/color/palette.ts +1 -1
  198. package/src/compare/compare.ts +5 -5
  199. package/src/control/control.ts +2 -2
  200. package/src/deep/merge.spec.ts +2 -15
  201. package/src/deep/merge.ts +1 -1
  202. package/src/deep/path.spec.ts +41 -0
  203. package/src/deep/path.ts +48 -17
  204. package/src/destructor.ts +6 -2
  205. package/src/errors/errors.spec.ts +20 -20
  206. package/src/errors/errors.ts +4 -1
  207. package/src/flush.ts +21 -0
  208. package/src/id/id.spec.ts +1 -1
  209. package/src/id/id.ts +3 -1
  210. package/src/identity.ts +2 -2
  211. package/src/index.ts +3 -1
  212. package/src/instance/matcher.spec.ts +7 -7
  213. package/src/jsonrpc/jsonrpc.ts +1 -1
  214. package/src/kv/types.ts +1 -1
  215. package/src/map/index.ts +10 -0
  216. package/src/map/map.spec.ts +132 -0
  217. package/src/map/map.ts +17 -0
  218. package/src/math/math.ts +19 -27
  219. package/src/migrate/migrate.spec.ts +2 -2
  220. package/src/migrate/migrate.ts +2 -2
  221. package/src/notation/notation.ts +1 -1
  222. package/src/optional.ts +0 -4
  223. package/src/primitive/primitive.spec.ts +1 -1
  224. package/src/record/index.ts +10 -0
  225. package/src/record/record.spec.ts +319 -0
  226. package/src/record/record.ts +118 -0
  227. package/src/runtime/os.ts +1 -1
  228. package/src/spatial/base.ts +1 -1
  229. package/src/spatial/box/box.ts +6 -1
  230. package/src/spatial/dimensions/dimensions.ts +1 -1
  231. package/src/spatial/direction/direction.ts +1 -1
  232. package/src/spatial/location/location.ts +1 -1
  233. package/src/spatial/scale/scale.ts +1 -1
  234. package/src/spatial/xy/xy.ts +6 -1
  235. package/src/status/index.ts +1 -1
  236. package/src/status/status.spec.ts +25 -0
  237. package/src/status/status.ts +91 -0
  238. package/src/strings/strings.spec.ts +51 -13
  239. package/src/strings/strings.ts +20 -0
  240. package/src/telem/gl.ts +1 -1
  241. package/src/telem/series.spec.ts +193 -53
  242. package/src/telem/series.ts +53 -18
  243. package/src/telem/telem.spec.ts +202 -83
  244. package/src/telem/telem.ts +53 -35
  245. package/src/testutil/testutil.spec.ts +161 -0
  246. package/src/testutil/testutil.ts +12 -0
  247. package/src/zod/external.ts +1 -0
  248. package/src/zod/nullToUndefined.spec.ts +1 -1
  249. package/src/zod/nullToUndefined.ts +1 -1
  250. package/src/zod/toArray.spec.ts +182 -0
  251. package/src/{status/types.ts → zod/toArray.ts} +3 -12
  252. package/src/zod/util.spec.ts +2 -2
  253. package/src/zod/util.ts +3 -3
  254. package/tsconfig.tsbuildinfo +1 -1
  255. package/vite.config.ts +1 -2
  256. package/dist/base-B5lQIJKc.js +0 -38
  257. package/dist/base-CTq-lhpU.cjs +0 -1
  258. package/dist/index-B58dnYRu.cjs +0 -1
  259. package/dist/index-BMGaoK93.cjs +0 -1
  260. package/dist/index-BTet04Hd.cjs +0 -6
  261. package/dist/index-C07SBJhr.js +0 -128
  262. package/dist/index-C9EdKeu1.js +0 -174
  263. package/dist/index-CM8ZDZ6s.cjs +0 -1
  264. package/dist/index-CV2JaHfw.cjs +0 -1
  265. package/dist/index-CeBvOwG8.cjs +0 -3
  266. package/dist/index-ClrGyGDp.js +0 -205
  267. package/dist/index-CqQXXeCI.cjs +0 -1
  268. package/dist/index-DEdq2tza.cjs +0 -1
  269. package/dist/index-DKMnHBGR.cjs +0 -1
  270. package/dist/index-Dql5FMcH.js +0 -47
  271. package/dist/index-WwMnwoLy.cjs +0 -1
  272. package/dist/path-1tZLZ4AN.cjs +0 -1
  273. package/dist/path-DD6ytXzr.js +0 -76
  274. package/dist/schemas-55Usj0Fg.js +0 -3998
  275. package/dist/schemas-DbXuI2Qr.cjs +0 -27
  276. package/dist/search.cjs +0 -1
  277. package/dist/search.js +0 -14
  278. package/dist/src/record.d.ts +0 -18
  279. package/dist/src/record.d.ts.map +0 -1
  280. package/dist/src/record.spec.d.ts.map +0 -1
  281. package/dist/src/search.d.ts +0 -18
  282. package/dist/src/search.d.ts.map +0 -1
  283. package/dist/src/status/types.d.ts +0 -11
  284. package/dist/src/status/types.d.ts.map +0 -1
  285. package/src/record.spec.ts +0 -38
  286. package/src/record.ts +0 -45
  287. package/src/search.ts +0 -42
  288. /package/dist/src/{record.spec.d.ts → record/record.spec.d.ts} +0 -0
@@ -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/v4";
10
+ import { z } from "zod";
11
11
 
12
12
  import { math } from "@/math";
13
13
  import { primitive } from "@/primitive";
@@ -28,6 +28,12 @@ export type TimeStampStringFormat =
28
28
  | "shortDate"
29
29
  | "dateTime";
30
30
 
31
+ const dateComponentsZ = z.union([
32
+ z.tuple([z.int()]),
33
+ z.tuple([z.int(), z.int().min(1).max(12)]),
34
+ z.tuple([z.int(), z.int().min(1).max(12), z.int().min(1).max(31)]),
35
+ ]);
36
+
31
37
  /**
32
38
  * A triple of numbers representing a date.
33
39
  *
@@ -35,7 +41,7 @@ export type TimeStampStringFormat =
35
41
  * @param month - The month.
36
42
  * @param day - The day.
37
43
  */
38
- export type DateComponents = [number?, number?, number?];
44
+ export type DateComponents = z.infer<typeof dateComponentsZ>;
39
45
 
40
46
  const remainder = <T extends TimeStamp | TimeSpan>(
41
47
  value: T,
@@ -93,7 +99,7 @@ export class TimeStamp
93
99
  super(TimeStamp.parseDateTimeString(value, tzInfo).valueOf());
94
100
  else if (Array.isArray(value)) super(TimeStamp.parseDate(value));
95
101
  else {
96
- let offset: bigint = BigInt(0);
102
+ let offset = 0n;
97
103
  if (value instanceof Number) value = value.valueOf();
98
104
  if (tzInfo === "local") offset = TimeStamp.utcOffset.valueOf();
99
105
  if (typeof value === "number")
@@ -265,7 +271,7 @@ export class TimeStamp
265
271
  * @returns True if the TimeStamp represents the unix epoch, false otherwise.
266
272
  */
267
273
  get isZero(): boolean {
268
- return this.valueOf() === BigInt(0);
274
+ return this.valueOf() === 0n;
269
275
  }
270
276
 
271
277
  /**
@@ -644,12 +650,27 @@ export class TimeStamp
644
650
 
645
651
  /** A zod schema for validating timestamps */
646
652
  static readonly z = z.union([
653
+ z.instanceof(TimeStamp),
647
654
  z.object({ value: z.bigint() }).transform((v) => new TimeStamp(v.value)),
648
655
  z.string().transform((n) => new TimeStamp(BigInt(n))),
649
- z.instanceof(Number).transform((n) => new TimeStamp(n)),
650
656
  z.number().transform((n) => new TimeStamp(n)),
651
- z.instanceof(TimeStamp),
657
+ z.bigint().transform((n) => new TimeStamp(n)),
658
+ z.date().transform((d) => new TimeStamp(d)),
659
+ z.custom<TimeSpan>((v) => v instanceof TimeSpan).transform((v) => new TimeStamp(v)),
660
+ dateComponentsZ.transform((v) => new TimeStamp(v)),
652
661
  ]);
662
+
663
+ /**
664
+ * Sorts two timestamps.
665
+ *
666
+ * @param a - The first timestamp.
667
+ * @param b - The second timestamp.
668
+ * @returns A number indicating the order of the two timestamps (positive if a is
669
+ * greater than b, negative if a is less than b, and 0 if they are equal).
670
+ */
671
+ static sort(a: TimeStamp, b: TimeStamp): number {
672
+ return Number(a.valueOf() - b.valueOf());
673
+ }
653
674
  }
654
675
 
655
676
  /** TimeSpan represents a nanosecond precision duration. */
@@ -843,7 +864,7 @@ export class TimeSpan
843
864
  * @returns True if the TimeSpan represents a zero duration, false otherwise.
844
865
  */
845
866
  get isZero(): boolean {
846
- return this.valueOf() === BigInt(0);
867
+ return this.valueOf() === 0n;
847
868
  }
848
869
 
849
870
  /**
@@ -977,7 +998,6 @@ export class TimeSpan
977
998
  static readonly z = z.union([
978
999
  z.object({ value: z.bigint() }).transform((v) => new TimeSpan(v.value)),
979
1000
  z.string().transform((n) => new TimeSpan(BigInt(n))),
980
- z.instanceof(Number).transform((n) => new TimeSpan(n)),
981
1001
  z.number().transform((n) => new TimeSpan(n)),
982
1002
  z.instanceof(TimeSpan),
983
1003
  ]);
@@ -1076,7 +1096,6 @@ export class Rate
1076
1096
  /** A zod schema for validating and transforming rates */
1077
1097
  static readonly z = z.union([
1078
1098
  z.number().transform((n) => new Rate(n)),
1079
- z.instanceof(Number).transform((n) => new Rate(n)),
1080
1099
  z.instanceof(Rate),
1081
1100
  ]);
1082
1101
  }
@@ -1133,7 +1152,6 @@ export class Density
1133
1152
  /** A zod schema for validating and transforming densities */
1134
1153
  static readonly z = z.union([
1135
1154
  z.number().transform((n) => new Density(n)),
1136
- z.instanceof(Number).transform((n) => new Density(n)),
1137
1155
  z.instanceof(Density),
1138
1156
  ]);
1139
1157
  }
@@ -1374,15 +1392,22 @@ export class TimeRange implements primitive.Stringer {
1374
1392
  .transform((v) => new TimeRange(v.start, v.end)),
1375
1393
  z.instanceof(TimeRange),
1376
1394
  ]);
1377
- }
1378
1395
 
1379
- export const sortTimeRange = (a: TimeRange, b: TimeRange): -1 | 0 | 1 => {
1380
- if (a.start.before(b.start)) return -1;
1381
- if (a.start.after(b.start)) return 1;
1382
- if (a.end.before(b.end)) return -1;
1383
- if (a.end.after(b.end)) return 1;
1384
- return 0;
1385
- };
1396
+ /**
1397
+ * Sorts two time ranges. The range with the earlier start time is considered less than
1398
+ * the range with the later start time. If the start times are equal, the range with the
1399
+ * earlier end time is considered less than the range with the later end time.
1400
+ *
1401
+ * @param a - The first time range.
1402
+ * @param b - The second time range.
1403
+ * @returns A number indicating the order of the two time ranges. This number is
1404
+ * positive if a is earlier than b, negative if a is later than b, and 0 if they are
1405
+ * equal.
1406
+ */
1407
+ static sort(a: TimeRange, b: TimeRange): number {
1408
+ return TimeStamp.sort(a.start, b.start) || TimeStamp.sort(a.end, b.end);
1409
+ }
1410
+ }
1386
1411
 
1387
1412
  /** DataType is a string that represents a data type. */
1388
1413
  export class DataType
@@ -1664,7 +1689,9 @@ export class DataType
1664
1689
  ]);
1665
1690
  }
1666
1691
 
1667
- /** The size of an element in bytes. */
1692
+ /**
1693
+ * The Size of an element in bytes.
1694
+ */
1668
1695
  export class Size
1669
1696
  extends primitive.ValueExtension<number>
1670
1697
  implements primitive.Stringer
@@ -1826,31 +1853,22 @@ export class Size
1826
1853
 
1827
1854
  export type CrudeTimeStamp =
1828
1855
  | bigint
1829
- | BigInt
1830
1856
  | TimeStamp
1831
1857
  | TimeSpan
1832
1858
  | number
1833
1859
  | Date
1834
1860
  | string
1835
- | DateComponents
1836
- | Number;
1861
+ | DateComponents;
1837
1862
  export type TimeStampT = number;
1838
- export type CrudeTimeSpan =
1839
- | bigint
1840
- | BigInt
1841
- | TimeSpan
1842
- | TimeStamp
1843
- | number
1844
- | Number
1845
- | Rate;
1863
+ export type CrudeTimeSpan = bigint | TimeSpan | TimeStamp | number | Rate;
1846
1864
  export type TimeSpanT = number;
1847
- export type CrudeRate = Rate | number | Number;
1865
+ export type CrudeRate = Rate | number;
1848
1866
  export type RateT = number;
1849
- export type CrudeDensity = Density | number | Number;
1867
+ export type CrudeDensity = Density | number;
1850
1868
  export type DensityT = number;
1851
1869
  export type CrudeDataType = DataType | string | TypedArray;
1852
1870
  export type DataTypeT = string;
1853
- export type CrudeSize = Size | number | Number;
1871
+ export type CrudeSize = Size | number;
1854
1872
  export type SizeT = number;
1855
1873
  export interface CrudeTimeRange {
1856
1874
  start: CrudeTimeStamp;
@@ -1919,11 +1937,11 @@ export const convertDataType = (
1919
1937
  target: DataType,
1920
1938
  value: math.Numeric,
1921
1939
  offset: math.Numeric = 0,
1922
- ): math.PrimitiveNumeric => {
1940
+ ): math.Numeric => {
1923
1941
  if (source.usesBigInt && !target.usesBigInt) return Number(value) - Number(offset);
1924
1942
  if (!source.usesBigInt && target.usesBigInt)
1925
1943
  return BigInt(value.valueOf()) - BigInt(offset.valueOf());
1926
- return addSamples(value, -offset).valueOf();
1944
+ return addSamples(value, -offset);
1927
1945
  };
1928
1946
 
1929
1947
  export const addSamples = (a: math.Numeric, b: math.Numeric): math.Numeric => {
@@ -0,0 +1,161 @@
1
+ // Copyright 2025 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { describe, expect, it, vi } from "vitest";
11
+
12
+ import { testutil } from "@/testutil";
13
+
14
+ describe("testutil", () => {
15
+ describe("toString", () => {
16
+ it("should stringify regular values normally", () => {
17
+ expect(testutil.toString("hello")).toBe('"hello"');
18
+ expect(testutil.toString(123)).toBe("123");
19
+ expect(testutil.toString(true)).toBe("true");
20
+ expect(testutil.toString(null)).toBe("null");
21
+ expect(testutil.toString(undefined)).toBe(undefined);
22
+ });
23
+
24
+ it("should handle arrays", () => {
25
+ expect(testutil.toString([1, 2, 3])).toBe("[1,2,3]");
26
+ expect(testutil.toString(["a", "b", "c"])).toBe('["a","b","c"]');
27
+ expect(testutil.toString([])).toBe("[]");
28
+ });
29
+
30
+ it("should handle objects", () => {
31
+ expect(testutil.toString({ a: 1, b: 2 })).toBe('{"a":1,"b":2}');
32
+ expect(testutil.toString({ nested: { value: 42 } })).toBe(
33
+ '{"nested":{"value":42}}',
34
+ );
35
+ expect(testutil.toString({})).toBe("{}");
36
+ });
37
+
38
+ it("should convert bigint to string", () => {
39
+ const bigIntValue = BigInt(123456789012345678901234567890n);
40
+ expect(testutil.toString(bigIntValue)).toBe('"123456789012345678901234567890"');
41
+ });
42
+
43
+ it("should handle objects with bigint values", () => {
44
+ const obj = {
45
+ regular: 123,
46
+ big: BigInt(999999999999999999999n),
47
+ nested: {
48
+ value: BigInt(111111111111111111111n),
49
+ },
50
+ };
51
+ expect(testutil.toString(obj)).toBe(
52
+ '{"regular":123,"big":"999999999999999999999","nested":{"value":"111111111111111111111"}}',
53
+ );
54
+ });
55
+
56
+ it("should handle arrays with bigint values", () => {
57
+ const arr = [BigInt(1n), BigInt(2n), 3, BigInt(4n)];
58
+ expect(testutil.toString(arr)).toBe('["1","2",3,"4"]');
59
+ });
60
+
61
+ it("should handle mixed complex structures", () => {
62
+ const complex = {
63
+ id: BigInt(123n),
64
+ data: [1, BigInt(456n), { value: BigInt(789n) }],
65
+ metadata: {
66
+ count: 42,
67
+ total: BigInt(999999n),
68
+ },
69
+ };
70
+ expect(testutil.toString(complex)).toBe(
71
+ '{"id":"123","data":[1,"456",{"value":"789"}],"metadata":{"count":42,"total":"999999"}}',
72
+ );
73
+ });
74
+ });
75
+
76
+ describe("testutil.expectAlways", () => {
77
+ it("should call function multiple times over duration", async () => {
78
+ const fn = vi.fn();
79
+ await testutil.expectAlways(fn, 100, 20);
80
+ expect(fn).toHaveBeenCalledTimes(5);
81
+ });
82
+
83
+ it("should handle async functions", async () => {
84
+ let counter = 0;
85
+ const asyncFn = vi.fn(async () => {
86
+ counter++;
87
+ await new Promise((resolve) => setTimeout(resolve, 5));
88
+ });
89
+
90
+ await testutil.expectAlways(asyncFn, 60, 20);
91
+ expect(asyncFn).toHaveBeenCalled();
92
+ expect(counter).toBeGreaterThan(0);
93
+ });
94
+
95
+ it("should propagate errors from the function", async () => {
96
+ const errorFn = vi.fn(() => {
97
+ throw new Error("Test error");
98
+ });
99
+
100
+ await expect(testutil.expectAlways(errorFn, 50, 20)).rejects.toThrow(
101
+ "Test error",
102
+ );
103
+ expect(errorFn).toHaveBeenCalledTimes(1);
104
+ });
105
+
106
+ it("should propagate errors from async functions", async () => {
107
+ const asyncErrorFn = vi.fn(async () => {
108
+ throw new Error("Async test error");
109
+ });
110
+
111
+ await expect(testutil.expectAlways(asyncErrorFn, 50, 20)).rejects.toThrow(
112
+ "Async test error",
113
+ );
114
+ expect(asyncErrorFn).toHaveBeenCalledTimes(1);
115
+ });
116
+
117
+ it("should use default values when not provided", async () => {
118
+ const fn = vi.fn();
119
+ await testutil.expectAlways(fn);
120
+ expect(fn.mock.calls.length).toBeGreaterThanOrEqual(10);
121
+ });
122
+
123
+ it("should respect custom interval", async () => {
124
+ const fn = vi.fn();
125
+ const start = Date.now();
126
+ await testutil.expectAlways(fn, 100, 30);
127
+ const elapsed = Date.now() - start;
128
+ expect(elapsed).toBeGreaterThanOrEqual(90);
129
+ expect(elapsed).toBeLessThan(150);
130
+ expect(fn).toHaveBeenCalledTimes(4);
131
+ });
132
+
133
+ it("should handle functions that pass after initial failures", async () => {
134
+ let callCount = 0;
135
+ const fn = vi.fn(() => {
136
+ callCount++;
137
+ if (callCount < 3) throw new Error("Not ready yet");
138
+ });
139
+
140
+ await expect(testutil.expectAlways(fn, 80, 20)).rejects.toThrow("Not ready yet");
141
+ expect(fn).toHaveBeenCalledTimes(1);
142
+ });
143
+
144
+ it("should work with expectations inside the function", async () => {
145
+ let value = 0;
146
+ const incrementer = setInterval(() => value++, 10);
147
+
148
+ try {
149
+ await testutil.expectAlways(
150
+ () => {
151
+ expect(value).toBeGreaterThanOrEqual(0);
152
+ },
153
+ 50,
154
+ 10,
155
+ );
156
+ } finally {
157
+ clearInterval(incrementer);
158
+ }
159
+ });
160
+ });
161
+ });
@@ -12,3 +12,15 @@ export const toString = (value: unknown): string =>
12
12
  if (typeof value === "bigint") return value.toString();
13
13
  return value;
14
14
  });
15
+
16
+ export const expectAlways = async (
17
+ fn: () => void | Promise<void>,
18
+ duration: number = 200,
19
+ interval: number = 20,
20
+ ) => {
21
+ const start = Date.now();
22
+ while (Date.now() - start < duration) {
23
+ await fn();
24
+ await new Promise((resolve) => setTimeout(resolve, interval));
25
+ }
26
+ };
@@ -8,4 +8,5 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  export * from "@/zod/nullToUndefined";
11
+ export * from "@/zod/toArray";
11
12
  export * from "@/zod/util";
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { describe, expect, it } from "vitest";
11
- import { z } from "zod/v4";
11
+ import { z } from "zod";
12
12
 
13
13
  import { zod } from "@/zod";
14
14
 
@@ -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 { type z } from "zod/v4";
10
+ import { type z } from "zod";
11
11
 
12
12
  export const nullToUndefined = <Input, Output>(
13
13
  schema: z.ZodType<Input, Output>,
@@ -0,0 +1,182 @@
1
+ // Copyright 2025 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { describe, expect, it } from "vitest";
11
+ import { z } from "zod";
12
+
13
+ import { toArray } from "@/zod/toArray";
14
+
15
+ describe("toArray", () => {
16
+ describe("with string schema", () => {
17
+ const schema = toArray(z.string());
18
+
19
+ it("should accept an array of strings", () => {
20
+ const result = schema.parse(["hello", "world"]);
21
+ expect(result).toEqual(["hello", "world"]);
22
+ });
23
+
24
+ it("should convert a single string to an array", () => {
25
+ const result = schema.parse("hello");
26
+ expect(result).toEqual(["hello"]);
27
+ });
28
+
29
+ it("should accept an empty array", () => {
30
+ const result = schema.parse([]);
31
+ expect(result).toEqual([]);
32
+ });
33
+
34
+ it("should throw for invalid types in array", () => {
35
+ expect(() => schema.parse([123, 456])).toThrow(z.ZodError);
36
+ });
37
+
38
+ it("should throw for invalid single value", () => {
39
+ expect(() => schema.parse(123)).toThrow(z.ZodError);
40
+ });
41
+ });
42
+
43
+ describe("with number schema", () => {
44
+ const schema = toArray(z.number());
45
+
46
+ it("should accept an array of numbers", () => {
47
+ const result = schema.parse([1, 2, 3]);
48
+ expect(result).toEqual([1, 2, 3]);
49
+ });
50
+
51
+ it("should convert a single number to an array", () => {
52
+ const result = schema.parse(42);
53
+ expect(result).toEqual([42]);
54
+ });
55
+
56
+ it("should handle zero", () => {
57
+ const result = schema.parse(0);
58
+ expect(result).toEqual([0]);
59
+ });
60
+
61
+ it("should handle negative numbers", () => {
62
+ const result = schema.parse(-5);
63
+ expect(result).toEqual([-5]);
64
+ });
65
+ });
66
+
67
+ describe("with object schema", () => {
68
+ const objSchema = z.object({
69
+ name: z.string(),
70
+ age: z.number(),
71
+ });
72
+ const schema = toArray(objSchema);
73
+
74
+ it("should accept an array of objects", () => {
75
+ const input = [
76
+ { name: "Alice", age: 30 },
77
+ { name: "Bob", age: 25 },
78
+ ];
79
+ const result = schema.parse(input);
80
+ expect(result).toEqual(input);
81
+ });
82
+
83
+ it("should convert a single object to an array", () => {
84
+ const input = { name: "Charlie", age: 35 };
85
+ const result = schema.parse(input);
86
+ expect(result).toEqual([input]);
87
+ });
88
+
89
+ it("should validate object properties", () => {
90
+ expect(() => schema.parse([{ name: "Dave", age: "invalid" }])).toThrow(
91
+ z.ZodError,
92
+ );
93
+ });
94
+ });
95
+
96
+ describe("with optional schema", () => {
97
+ const schema = toArray(z.string().optional());
98
+
99
+ it("should handle undefined in array", () => {
100
+ const result = schema.parse([undefined, "hello", undefined]);
101
+ expect(result).toEqual([undefined, "hello", undefined]);
102
+ });
103
+
104
+ it("should convert undefined to array with undefined", () => {
105
+ const result = schema.parse(undefined);
106
+ expect(result).toEqual([undefined]);
107
+ });
108
+ });
109
+
110
+ describe("with union schema", () => {
111
+ const schema = toArray(z.union([z.string(), z.number()]));
112
+
113
+ it("should accept mixed types in array", () => {
114
+ const result = schema.parse(["hello", 42, "world", 123]);
115
+ expect(result).toEqual(["hello", 42, "world", 123]);
116
+ });
117
+
118
+ it("should convert single string to array", () => {
119
+ const result = schema.parse("test");
120
+ expect(result).toEqual(["test"]);
121
+ });
122
+
123
+ it("should convert single number to array", () => {
124
+ const result = schema.parse(999);
125
+ expect(result).toEqual([999]);
126
+ });
127
+
128
+ it("should throw for invalid type", () => {
129
+ expect(() => schema.parse(true)).toThrow(z.ZodError);
130
+ });
131
+ });
132
+
133
+ describe("with nullable schema", () => {
134
+ const schema = toArray(z.string().nullable());
135
+
136
+ it("should handle null in array", () => {
137
+ const result = schema.parse([null, "hello", null]);
138
+ expect(result).toEqual([null, "hello", null]);
139
+ });
140
+
141
+ it("should convert null to array with null", () => {
142
+ const result = schema.parse(null);
143
+ expect(result).toEqual([null]);
144
+ });
145
+ });
146
+
147
+ describe("with transformed schema", () => {
148
+ const baseSchema = z.string().transform((val) => val.toUpperCase());
149
+ const schema = toArray(baseSchema);
150
+
151
+ it("should apply transformation to array elements", () => {
152
+ const result = schema.parse(["hello", "world"]);
153
+ expect(result).toEqual(["HELLO", "WORLD"]);
154
+ });
155
+
156
+ it("should apply transformation to single value", () => {
157
+ const result = schema.parse("hello");
158
+ expect(result).toEqual(["HELLO"]);
159
+ });
160
+ });
161
+
162
+ describe("edge cases", () => {
163
+ it("should handle deeply nested arrays", () => {
164
+ const schema = toArray(toArray(z.number()));
165
+ const result = schema.parse([[1, 2], [3, 4]]);
166
+ expect(result).toEqual([[1, 2], [3, 4]]);
167
+ });
168
+
169
+ it("should convert single value to nested array", () => {
170
+ const schema = toArray(toArray(z.number()));
171
+ const result = schema.parse(5);
172
+ expect(result).toEqual([[5]]);
173
+ });
174
+
175
+ it("should return equal array when input is already an array", () => {
176
+ const schema = toArray(z.string());
177
+ const input = ["test"];
178
+ const result = schema.parse(input);
179
+ expect(result).toEqual(input);
180
+ });
181
+ });
182
+ });
@@ -7,16 +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/v4";
10
+ import z from "zod";
11
11
 
12
- export const variantZ = z.enum([
13
- "success",
14
- "info",
15
- "warning",
16
- "error",
17
- "loading",
18
- "disabled",
19
- ]);
20
-
21
- // Represents one of the possible variants of a status message.
22
- export type Variant = z.infer<typeof variantZ>;
12
+ export const toArray = <T extends z.ZodType>(schema: T) =>
13
+ z.array(schema).or(schema.transform((v) => [v]));
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { describe, expect, it, test } from "vitest";
11
- import { z } from "zod/v4";
11
+ import { z } from "zod";
12
12
 
13
13
  import { zod } from "@/zod";
14
14
 
@@ -110,7 +110,7 @@ describe("zod", () => {
110
110
  });
111
111
  const v = zod.getFieldSchema(schema, "name");
112
112
  expect(v).toBeInstanceOf(z.ZodString);
113
- expect(v.isOptional()).toBe(false);
113
+ expect(v.safeParse(undefined).success).toBe(false);
114
114
  });
115
115
  });
116
116
  });
package/src/zod/util.ts CHANGED
@@ -7,10 +7,10 @@
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 { type z } from "zod/v4";
10
+ import { type z } from "zod";
11
11
 
12
12
  import { deep } from "@/deep";
13
- import { type UnknownRecord } from "@/record";
13
+ import { type record } from "@/record";
14
14
 
15
15
  export const getFieldSchemaPath = (path: string): string =>
16
16
  deep.transformPath(path, (part, index, parts) => {
@@ -29,7 +29,7 @@ const sourceTypeGetter = (obj: unknown, key: string): z.ZodAny | null => {
29
29
  const sourceType = (
30
30
  obj as { sourceType: () => z.ZodObject<z.ZodRawShape> }
31
31
  ).sourceType();
32
- return (sourceType as unknown as UnknownRecord)[key] as z.ZodAny | null;
32
+ return (sourceType as unknown as record.Unknown)[key] as z.ZodAny | null;
33
33
  }
34
34
  return v;
35
35
  };