@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
package/src/math/math.ts CHANGED
@@ -7,27 +7,20 @@
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
- /** A primitive numeric value is either a number or a bigint. */
11
- export type PrimitiveNumeric = number | bigint;
12
-
13
- /** An extension of {@link PrimitiveNumeric} that includes the {@link BigInt} and {@link Number} classes. */
14
- export type Numeric = PrimitiveNumeric | Number | BigInt;
15
-
16
- const isBigInt = (n: Numeric): n is bigint | BigInt =>
17
- typeof n === "bigint" || n instanceof BigInt;
10
+ /** A numeric value is either a a number, or a bigint. */
11
+ export type Numeric = number | bigint;
18
12
 
19
13
  /**
20
14
  * @returns the product of a and b, coercing b to the type of a if necessary. */
21
15
  export const sub = <V extends Numeric>(a: V, b: Numeric): V => {
22
- if (isBigInt(a)) return (a.valueOf() - BigInt(b.valueOf().valueOf())) as V;
23
- return (a.valueOf() - Number(b.valueOf())) as V;
16
+ if (typeof a === "bigint") return (a - BigInt(b)) as V;
17
+ return (a - Number(b)) as V;
24
18
  };
25
19
 
26
20
  /** @returns the sum of a and b, coercing b to the type of a if necessary. */
27
21
  export const add = <V extends Numeric>(a: V, b: Numeric): V => {
28
- if (isBigInt(a)) return (a.valueOf() + BigInt(b.valueOf().valueOf())) as V;
29
- // @ts-expect-error - a is a number but typescript doesn't recognize that.
30
- return (a + Number(b.valueOf())) as V;
22
+ if (typeof a === "bigint") return (a + BigInt(b)) as V;
23
+ return ((a as unknown as number) + Number(b)) as V;
31
24
  };
32
25
 
33
26
  /** @returns true if a is close to b within epsilon. */
@@ -36,8 +29,8 @@ export const closeTo = (a: number, b: number, epsilon = 0.0001): boolean =>
36
29
 
37
30
  /** @returns true if a is equal to b, coercing b to the type of a if necessary. */
38
31
  export const equal = <V extends Numeric>(a: V, b: Numeric): boolean => {
39
- if (isBigInt(a)) return a === BigInt(b.valueOf().valueOf());
40
- return a === Number(b.valueOf());
32
+ if (typeof a === "bigint") return a === BigInt(b);
33
+ return a === Number(b);
41
34
  };
42
35
 
43
36
  /**
@@ -53,32 +46,31 @@ export const roundToNearestMagnitude = (num: number): number => {
53
46
 
54
47
  /** @returns the minimum of a and b, coercing b to the type of a if necessary. */
55
48
  export const min = <V extends Numeric>(a: V, b: Numeric): V => {
56
- if (isBigInt(a))
57
- return (a.valueOf() < BigInt(b.valueOf()) ? a : BigInt(b.valueOf())) as V;
58
- return (a.valueOf() < Number(b.valueOf()) ? a : Number(b.valueOf())) as V;
49
+ if (a <= b) return a;
50
+ if (typeof a === "bigint") return (a <= b ? a : BigInt(b)) as V;
51
+ return (a <= b ? a : Number(b)) as V;
59
52
  };
60
53
 
61
54
  /** @returns the maximum of a and b, coercing b to the type of a if necessary. */
62
55
  export const max = <V extends Numeric>(a: V, b: Numeric): V => {
63
- if (isBigInt(a))
64
- return (a.valueOf() > BigInt(b.valueOf()) ? a : BigInt(b.valueOf())) as V;
65
- return (a.valueOf() > Number(b.valueOf()) ? a : Number(b.valueOf())) as V;
56
+ if (typeof a === "bigint") return (a >= b ? a : BigInt(b)) as V;
57
+ return (a >= b ? a : Number(b)) as V;
66
58
  };
67
59
 
68
60
  /** @returns the absolute value of a. */
69
61
  export const abs = <V extends Numeric>(a: V): V => {
70
- if (isBigInt(a) || a instanceof BigInt) return (a.valueOf() < 0n ? -a : a) as V;
71
- return (a.valueOf() < 0 ? -a : a) as V;
62
+ if (a < 0) return -a as V;
63
+ return a;
72
64
  };
73
65
 
74
66
  /** @returns the multiplication of a and b, coercing b to the type of a if necessary. */
75
67
  export const mult = <V extends Numeric>(a: V, b: Numeric): V => {
76
- if (isBigInt(a)) return (a.valueOf() * BigInt(b.valueOf())) as V;
77
- return (a.valueOf() * Number(b.valueOf())) as V;
68
+ if (typeof a === "bigint") return (a * BigInt(b)) as V;
69
+ return (a * Number(b)) as V;
78
70
  };
79
71
 
80
72
  /** @returns the division of a and b, coercing b to the type of a if necessary. */
81
73
  export const div = <V extends Numeric>(a: V, b: Numeric): V => {
82
- if (isBigInt(a)) return (a.valueOf() / BigInt(b.valueOf())) as V;
83
- return (a.valueOf() / Number(b.valueOf())) as V;
74
+ if (typeof a === "bigint") return (a / BigInt(b)) as V;
75
+ return (a / Number(b)) as V;
84
76
  };
@@ -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 { migrate } from "@/migrate";
14
14
 
@@ -59,7 +59,7 @@ const migrations: migrate.Migrations = {
59
59
  describe("compareSemVer", () => {
60
60
  it("should return true when the major version is higher", () => {
61
61
  expect(migrate.compareSemVer("1.0.0", "0.0.0")).toBeGreaterThan(0);
62
- expect(migrate.semVerNewer("3.0.0", "0.3.0")).toBeTruthy();
62
+ expect(migrate.semVerNewer("3.0.0", "0.3.0")).toBe(true);
63
63
  });
64
64
  describe("only check major", () => {
65
65
  it("should return equal when the major versions are equal but the minor and patch are different", () => {
@@ -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 { compare } from "@/compare";
13
13
  import { type Optional } from "@/optional";
@@ -70,7 +70,7 @@ export const compareSemVer = ((
70
70
  if (aPatch > bPatch) return compare.GREATER_THAN;
71
71
  }
72
72
  return compare.EQUAL;
73
- }) satisfies compare.CompareF<SemVer>;
73
+ }) satisfies compare.Comparator<SemVer>;
74
74
 
75
75
  /**
76
76
  * @returns true if the two semantic versions are equal.
@@ -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
  export const NOTATIONS = ["standard", "scientific", "engineering"] as const;
13
13
  export const notationZ = z.enum(NOTATIONS);
package/src/optional.ts CHANGED
@@ -8,7 +8,3 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
11
-
12
- export type Required<T> = {
13
- [P in keyof T]-?: T[P];
14
- };
@@ -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 { binary } from "@/binary";
14
14
  import { primitive } from "@/primitive";
@@ -0,0 +1,10 @@
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
+ export * as record from "@/record/record";
@@ -0,0 +1,319 @@
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
+
12
+ import { record } from "@/record";
13
+
14
+ describe("record", () => {
15
+ describe("types", () => {
16
+ it("should allow string and number keys", () => {
17
+ // Test Key type
18
+ const stringKey: record.Key = "test";
19
+ const numberKey: record.Key = 123;
20
+
21
+ expect(typeof stringKey).toBe("string");
22
+ expect(typeof numberKey).toBe("number");
23
+ });
24
+
25
+ it("should allow unknown values", () => {
26
+ // Test Unknown type
27
+ const unknown: record.Unknown = {
28
+ string: "value",
29
+ number: 42,
30
+ boolean: true,
31
+ object: { nested: "value" },
32
+ array: [1, 2, 3],
33
+ null: null,
34
+ undefined,
35
+ };
36
+
37
+ expect(unknown.string).toBe("value");
38
+ expect(unknown.number).toBe(42);
39
+ expect(unknown.boolean).toBe(true);
40
+ });
41
+
42
+ it("should support Keyed interface", () => {
43
+ // Test Keyed interface
44
+ const keyedString: record.Keyed<string> = { key: "test" };
45
+ const keyedNumber: record.Keyed<number> = { key: 123 };
46
+
47
+ expect(keyedString.key).toBe("test");
48
+ expect(keyedNumber.key).toBe(123);
49
+ });
50
+
51
+ it("should support KeyedNamed interface", () => {
52
+ // Test KeyedNamed interface
53
+ const keyedNamed: record.KeyedNamed = { key: "test", name: "Test Item" };
54
+ const keyedNamedNumber: record.KeyedNamed<number> = {
55
+ key: 123,
56
+ name: "Number Item",
57
+ };
58
+
59
+ expect(keyedNamed.key).toBe("test");
60
+ expect(keyedNamed.name).toBe("Test Item");
61
+ expect(keyedNamedNumber.key).toBe(123);
62
+ expect(keyedNamedNumber.name).toBe("Number Item");
63
+ });
64
+ });
65
+
66
+ describe("unknownZ", () => {
67
+ it("should validate valid records", () => {
68
+ const validRecord = {
69
+ string: "value",
70
+ number: 42,
71
+ symbol: Symbol("test"),
72
+ nested: { key: "value" },
73
+ array: [1, 2, 3],
74
+ };
75
+
76
+ const result = record.unknownZ.safeParse(validRecord);
77
+ expect(result.success).toBe(true);
78
+ });
79
+
80
+ it("should not reject invalid keys", () => {
81
+ const invalidRecord = {
82
+ [Symbol("test")]: "value", // Symbol keys are not allowed in the schema
83
+ };
84
+
85
+ const result = record.unknownZ.safeParse(invalidRecord);
86
+ expect(result.success).toBe(true);
87
+ });
88
+
89
+ it("should accept empty objects", () => {
90
+ const emptyRecord = {};
91
+ const result = record.unknownZ.safeParse(emptyRecord);
92
+ expect(result.success).toBe(true);
93
+ });
94
+
95
+ it("should accept null and undefined values", () => {
96
+ const recordWithNulls = {
97
+ null: null,
98
+ undefined,
99
+ string: "value",
100
+ };
101
+
102
+ const result = record.unknownZ.safeParse(recordWithNulls);
103
+ expect(result.success).toBe(true);
104
+ });
105
+ });
106
+
107
+ describe("entries", () => {
108
+ it("should return entries for a simple object", () => {
109
+ const obj = { a: 1, b: "test", c: true };
110
+ const result = record.entries(obj);
111
+
112
+ expect(result).toEqual([
113
+ ["a", 1],
114
+ ["b", "test"],
115
+ ["c", true],
116
+ ]);
117
+ });
118
+
119
+ it("should return entries for an object with number keys", () => {
120
+ const obj = { 1: "one", 2: "two", 3: "three" };
121
+ const result = record.entries(obj);
122
+
123
+ expect(result).toEqual([
124
+ ["1", "one"],
125
+ ["2", "two"],
126
+ ["3", "three"],
127
+ ]);
128
+ });
129
+
130
+ it("should return empty array for empty object", () => {
131
+ const obj = {};
132
+ const result = record.entries(obj);
133
+
134
+ expect(result).toEqual([]);
135
+ });
136
+
137
+ it("should preserve order of entries", () => {
138
+ const obj = { first: 1, second: 2, third: 3 };
139
+ const result = record.entries(obj);
140
+
141
+ expect(result[0]).toEqual(["first", 1]);
142
+ expect(result[1]).toEqual(["second", 2]);
143
+ expect(result[2]).toEqual(["third", 3]);
144
+ });
145
+
146
+ it("should handle objects with null and undefined values", () => {
147
+ const obj = { a: null, b: undefined, c: "value" };
148
+ const result = record.entries(obj);
149
+
150
+ expect(result).toEqual([
151
+ ["a", null],
152
+ ["b", undefined],
153
+ ["c", "value"],
154
+ ]);
155
+ });
156
+ });
157
+
158
+ describe("map", () => {
159
+ it("should map values using the provided function", () => {
160
+ const obj = { a: 1, b: 2, c: 3 };
161
+ const result = record.map(obj, (value) => value * 2);
162
+
163
+ expect(result).toEqual({ a: 2, b: 4, c: 6 });
164
+ });
165
+
166
+ it("should pass both value and key to the mapping function", () => {
167
+ const obj = { a: 1, b: 2, c: 3 };
168
+ const result = record.map(obj, (value, key) => `${key}:${value}`);
169
+
170
+ expect(result).toEqual({ a: "a:1", b: "b:2", c: "c:3" });
171
+ });
172
+
173
+ it("should handle different return types", () => {
174
+ const obj = { a: 1, b: 2, c: 3 };
175
+ const result = record.map(obj, (value) => value > 2);
176
+
177
+ expect(result).toEqual({ a: false, b: false, c: true });
178
+ });
179
+
180
+ it("should return empty object for empty input", () => {
181
+ const obj = {};
182
+ const result = record.map(obj, (value) => value);
183
+
184
+ expect(result).toEqual({});
185
+ });
186
+
187
+ it("should handle objects with mixed value types", () => {
188
+ const obj = { a: 1, b: "test", c: true, d: null };
189
+ const result = record.map(obj, (value) => typeof value);
190
+
191
+ expect(result).toEqual({
192
+ a: "number",
193
+ b: "string",
194
+ c: "boolean",
195
+ d: "object",
196
+ });
197
+ });
198
+
199
+ it("should preserve key types", () => {
200
+ const obj = { 1: "one", 2: "two" };
201
+ const result = record.map(obj, (value) => value.toUpperCase());
202
+
203
+ expect(result).toEqual({ 1: "ONE", 2: "TWO" });
204
+ });
205
+ });
206
+
207
+ describe("purgeUndefined", () => {
208
+ it("should remove undefined values", () => {
209
+ const obj = { a: 1, b: undefined, c: "test", d: undefined };
210
+ const result = record.purgeUndefined(obj);
211
+
212
+ expect(result).toEqual({ a: 1, c: "test" });
213
+ });
214
+
215
+ it("should not remove null values", () => {
216
+ const obj = { a: 1, b: null, c: "test", d: null };
217
+ const result = record.purgeUndefined(obj);
218
+
219
+ expect(result).toEqual({ a: 1, b: null, c: "test", d: null });
220
+ });
221
+
222
+ it("should preserve other falsy values", () => {
223
+ const obj = { a: 0, b: false, c: "", d: undefined, e: null };
224
+ const result = record.purgeUndefined(obj);
225
+
226
+ expect(result).toEqual({ a: 0, b: false, c: "", e: null });
227
+ });
228
+
229
+ it("should return empty object when all values are undefined", () => {
230
+ const obj = { a: undefined, b: undefined, c: undefined };
231
+ const result = record.purgeUndefined(obj);
232
+
233
+ expect(result).toEqual({});
234
+ });
235
+
236
+ it("should return same object when no null/undefined values", () => {
237
+ const obj = { a: 1, b: "test", c: true, d: 0, e: false };
238
+ const result = record.purgeUndefined(obj);
239
+
240
+ expect(result).toEqual(obj);
241
+ });
242
+
243
+ it("should handle empty object", () => {
244
+ const obj = {};
245
+ const result = record.purgeUndefined(obj);
246
+
247
+ expect(result).toEqual({});
248
+ });
249
+
250
+ it("should not purge undefined values in nested objects and arrays", () => {
251
+ const obj = {
252
+ a: 1,
253
+ b: undefined,
254
+ c: { nested: "value" },
255
+ d: null,
256
+ e: [1, 2, 3],
257
+ };
258
+ const result = record.purgeUndefined(obj);
259
+
260
+ expect(result).toEqual({
261
+ a: 1,
262
+ c: { nested: "value" },
263
+ e: [1, 2, 3],
264
+ d: null,
265
+ });
266
+ });
267
+
268
+ it("should create a copy of the object", () => {
269
+ const obj = { a: 1, b: "test" };
270
+ const result = record.purgeUndefined(obj);
271
+ expect(result).not.toBe(obj);
272
+ });
273
+ });
274
+
275
+ describe("integration", () => {
276
+ it("should work together: entries -> map -> deleteUndefined", () => {
277
+ const original = { a: 1, b: undefined, c: 3, d: null };
278
+
279
+ // Get entries
280
+ const entries = record.entries(original);
281
+ expect(entries).toEqual([
282
+ ["a", 1],
283
+ ["b", undefined],
284
+ ["c", 3],
285
+ ["d", null],
286
+ ]);
287
+
288
+ // Map to double values (keeping undefined/null)
289
+ const mapped = record.map(original, (value) =>
290
+ typeof value === "number" ? value * 2 : value,
291
+ );
292
+ expect(mapped).toEqual({ a: 2, b: undefined, c: 6, d: null });
293
+
294
+ // Remove undefined/null
295
+ const cleaned = record.purgeUndefined(mapped);
296
+ expect(cleaned).toEqual({ a: 2, c: 6, d: null });
297
+ });
298
+
299
+ it("should not purge undefined values in complex nested structures", () => {
300
+ const complex = {
301
+ id: 1,
302
+ name: "test",
303
+ metadata: undefined,
304
+ tags: null,
305
+ config: { enabled: true, timeout: undefined },
306
+ items: [1, 2, 3],
307
+ };
308
+
309
+ const result = record.purgeUndefined(complex);
310
+ expect(result).toEqual({
311
+ id: 1,
312
+ name: "test",
313
+ config: { enabled: true, timeout: undefined },
314
+ items: [1, 2, 3],
315
+ tags: null,
316
+ });
317
+ });
318
+ });
319
+ });
@@ -0,0 +1,118 @@
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 { z } from "zod";
11
+
12
+ /**
13
+ * Represents valid key types for record objects.
14
+ * Can be either a string or number.
15
+ */
16
+ export type Key = string | number;
17
+
18
+ /**
19
+ * Represents a record with unknown values and string/number keys.
20
+ * This is a generic type for objects where the value types are not known.
21
+ */
22
+ export type Unknown = Record<Key, unknown>;
23
+
24
+ /**
25
+ * Interface for objects that have a key property.
26
+ * @template K - The type of the key (must extend Key)
27
+ */
28
+ export interface Keyed<K extends Key = Key> {
29
+ /** The key identifier for this object */
30
+ key: K;
31
+ }
32
+
33
+ /**
34
+ * Interface for objects that have both a key and a name property.
35
+ * @template K - The type of the key (defaults to string)
36
+ */
37
+ export interface KeyedNamed<K extends Key = string> {
38
+ /** The key identifier for this object */
39
+ key: K;
40
+ /** The display name for this object */
41
+ name: string;
42
+ }
43
+
44
+ /**
45
+ * Zod schema for validating unknown records.
46
+ * Accepts objects with string, number, or symbol keys and unknown values.
47
+ */
48
+ export const unknownZ = z.record(
49
+ z.union([z.number(), z.string(), z.symbol()]),
50
+ z.unknown(),
51
+ );
52
+
53
+ /**
54
+ * Type representing the entries of a record as an array of key-value tuples.
55
+ * @template T - The record type
56
+ */
57
+ export type Entries<T> = Array<
58
+ {
59
+ [K in keyof T]: [K, T[K]];
60
+ }[keyof T]
61
+ >;
62
+
63
+ /**
64
+ * Converts a record object into an array of key-value tuples.
65
+ * This is a type-safe wrapper around Object.entries().
66
+ *
67
+ * @template T - The type of the input record
68
+ * @param obj - The record object to convert to entries
69
+ * @returns An array of [key, value] tuples
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * const obj = { a: 1, b: "hello" };
74
+ * const entries = record.entries(obj);
75
+ * // Result: [["a", 1], ["b", "hello"]]
76
+ * ```
77
+ */
78
+ export const entries = <T extends Record<Key, unknown>>(obj: T): Entries<T> =>
79
+ Object.entries(obj) as Entries<T>;
80
+
81
+ /**
82
+ * Maps over the entries of a record, applying a transformation function to each value.
83
+ *
84
+ * @template T - The type of the input record
85
+ * @template U - The type of the output values
86
+ * @param obj - The record object to map over
87
+ * @param fn - A function that transforms each value. Receives the value and key as parameters.
88
+ * @returns A new record with the same keys but transformed values
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const obj = { a: 1, b: 2, c: 3 };
93
+ * const doubled = record.map(obj, (value, key) => value * 2);
94
+ * // Result: { a: 2, b: 4, c: 6 }
95
+ * ```
96
+ */
97
+ export const map = <T extends Record<Key, unknown>, U>(
98
+ obj: T,
99
+ fn: (value: T[keyof T], key: keyof T) => U,
100
+ ): Record<Key, U> =>
101
+ Object.fromEntries(entries(obj).map(([key, value]) => [key, fn(value, key)]));
102
+
103
+ /**
104
+ * Removes all properties with undefined or null values from a record.
105
+ *
106
+ * @template T - The type of the input record
107
+ * @param obj - The record object to purge
108
+ * @returns A new record with undefined/null values removed
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const obj = { a: 1, b: undefined, c: null, d: "hello" };
113
+ * const purged = record.purgeUndefined(obj);
114
+ * // Result: { a: 1, d: "hello" }
115
+ * ```
116
+ */
117
+ export const purgeUndefined = <T extends Record<Key, unknown>>(obj: T): T =>
118
+ Object.fromEntries(entries(obj).filter(([_, value]) => value !== undefined)) as T;
package/src/runtime/os.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/v4";
10
+ import { z } from "zod";
11
11
 
12
12
  export const OPERATING_SYSTEMS = ["macOS", "Windows", "Linux"] as const;
13
13
  const LOWERCASE_OPERATING_SYSTEMS = ["macos", "windows", "linux"] as const;
@@ -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
  export const numberCouple = z.tuple([z.number(), z.number()]);
13
13
  export const bigNumberCouple = z.tuple([z.bigint(), z.bigint()]);
@@ -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 type * as bounds from "@/spatial/bounds/bounds";
13
13
  import type * as dimensions from "@/spatial/dimensions/dimensions";
@@ -484,3 +484,8 @@ export const constructWithAlternateRoot = (
484
484
  }
485
485
  return construct(first, second, undefined, undefined, newRoot);
486
486
  };
487
+
488
+ export const round = (b: Crude): Box => {
489
+ const b_ = construct(b);
490
+ return construct(xy.round(b_.one), xy.round(b_.two), undefined, undefined, b_.root);
491
+ };
@@ -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 { type Dimensions, dimensions, numberCouple, xy } from "@/spatial/base";
13
13
 
@@ -20,7 +20,7 @@ import {
20
20
  type YLocation,
21
21
  } from "@/spatial/base";
22
22
 
23
- export { Direction, direction };
23
+ export { Direction, direction, DIRECTIONS };
24
24
 
25
25
  export const crude = crudeDirection;
26
26
 
@@ -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 { caseconv } from "@/caseconv";
13
13
  import {
@@ -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 { clamp } from "@/clamp/clamp";
13
13
  import { type numeric } from "@/numeric";