@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 {
13
13
  type ClientXY,
@@ -293,3 +293,8 @@ export const swap = (a: Crude): XY => {
293
293
  const xy = construct(a);
294
294
  return { x: xy.y, y: xy.x };
295
295
  };
296
+
297
+ export const round = (a: Crude): XY => {
298
+ const xy = construct(a);
299
+ return { x: Math.round(xy.x), y: Math.round(xy.y) };
300
+ };
@@ -7,4 +7,4 @@
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
- export * as status from "@/status/types";
10
+ export * as status from "@/status/status";
@@ -0,0 +1,25 @@
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 { id } from "@/id";
13
+ import { status } from "@/status";
14
+ import { TimeStamp } from "@/telem";
15
+
16
+ describe("status", () => {
17
+ describe("create", () => {
18
+ it("should create a status", () => {
19
+ const s = status.create({ variant: "success", message: "test" });
20
+ expect(s.key).toHaveLength(id.LENGTH);
21
+ expect(s.time).toBeInstanceOf(TimeStamp);
22
+ expect(s.time.beforeEq(TimeStamp.now())).toBe(true);
23
+ });
24
+ });
25
+ });
@@ -0,0 +1,91 @@
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
+ import { id } from "@/id";
13
+ import { type Optional } from "@/optional";
14
+ import { TimeStamp } from "@/telem";
15
+
16
+ export const variantZ = z.enum([
17
+ "success",
18
+ "info",
19
+ "warning",
20
+ "error",
21
+ "loading",
22
+ "disabled",
23
+ ]);
24
+
25
+ // Represents one of the possible variants of a status message.
26
+ export type Variant = z.infer<typeof variantZ>;
27
+
28
+ type StatusZodObject<D extends z.ZodType> = z.ZodObject<{
29
+ key: z.ZodString;
30
+ variant: typeof variantZ;
31
+ message: z.ZodString;
32
+ description: z.ZodOptional<z.ZodString>;
33
+ time: typeof TimeStamp.z;
34
+ details: D;
35
+ }>;
36
+
37
+ interface StatusZFunction {
38
+ (): StatusZodObject<z.ZodOptional<z.ZodUnknown>>;
39
+ <D extends z.ZodType>(details: D): StatusZodObject<D>;
40
+ }
41
+
42
+ export const statusZ: StatusZFunction = <D extends z.ZodType>(details?: D) =>
43
+ z.object({
44
+ key: z.string(),
45
+ variant: variantZ,
46
+ message: z.string(),
47
+ description: z.string().optional(),
48
+ time: TimeStamp.z,
49
+ details: details ?? z.unknown().optional(),
50
+ });
51
+
52
+ export type Status<D = undefined, V extends Variant = Variant> = {
53
+ key: string;
54
+ variant: V;
55
+ message: string;
56
+ description?: string;
57
+ time: TimeStamp;
58
+ } & (D extends undefined ? {} : { details: D });
59
+
60
+ export type Crude<D = undefined, V extends Variant = Variant> = Optional<
61
+ Status<D, V>,
62
+ "time" | "key"
63
+ >;
64
+
65
+ export interface ExceptionDetails {
66
+ stack: string;
67
+ }
68
+
69
+ export const fromException = (
70
+ exc: unknown,
71
+ message?: string,
72
+ ): Status<ExceptionDetails, "error"> => {
73
+ if (!(exc instanceof Error)) throw exc;
74
+ return create<ExceptionDetails, "error">({
75
+ variant: "error",
76
+ message: message ?? exc.message,
77
+ description: message != null ? exc.message : undefined,
78
+ details: {
79
+ stack: exc.stack ?? "",
80
+ },
81
+ });
82
+ };
83
+
84
+ export const create = <D = undefined, V extends Variant = Variant>(
85
+ spec: Crude<D, V>,
86
+ ): Status<D, V> =>
87
+ ({
88
+ key: id.create(),
89
+ time: TimeStamp.now(),
90
+ ...spec,
91
+ }) as unknown as Status<D, V>;
@@ -9,56 +9,94 @@
9
9
 
10
10
  import { describe, expect, it } from "vitest";
11
11
 
12
- import { createShortIdentifiers, naturalLanguageJoin } from "@/strings/strings";
12
+ import { strings } from "@/strings";
13
13
 
14
14
  describe("naturalLanguageJoin", () => {
15
15
  it("should return an empty string for an empty array", () =>
16
- expect(naturalLanguageJoin([])).toBe(""));
16
+ expect(strings.naturalLanguageJoin([])).toBe(""));
17
17
 
18
18
  it("should return the zeroLength string for an empty array if provided", () =>
19
- expect(naturalLanguageJoin([], "No items")).toBe("No items"));
19
+ expect(strings.naturalLanguageJoin([], "No items")).toBe("No items"));
20
20
 
21
21
  it("should return the single element for an array with one element", () =>
22
- expect(naturalLanguageJoin(["apple"])).toBe("apple"));
22
+ expect(strings.naturalLanguageJoin(["apple"])).toBe("apple"));
23
23
 
24
24
  it('should join two elements with "and"', () =>
25
- expect(naturalLanguageJoin(["apple", "banana"])).toBe("apple and banana"));
25
+ expect(strings.naturalLanguageJoin(["apple", "banana"])).toBe("apple and banana"));
26
26
 
27
27
  it('should join multiple elements with commas and "and"', () =>
28
- expect(naturalLanguageJoin(["apple", "banana", "cherry"])).toBe(
28
+ expect(strings.naturalLanguageJoin(["apple", "banana", "cherry"])).toBe(
29
29
  "apple, banana, and cherry",
30
30
  ));
31
31
 
32
32
  it("should handle an array with more than three elements correctly", () =>
33
- expect(naturalLanguageJoin(["apple", "banana", "cherry", "date"])).toBe(
33
+ expect(strings.naturalLanguageJoin(["apple", "banana", "cherry", "date"])).toBe(
34
34
  "apple, banana, cherry, and date",
35
35
  ));
36
36
  });
37
37
 
38
38
  describe("createShortIdentifiers", () => {
39
39
  it("should create identifiers for a single word", () =>
40
- expect(createShortIdentifiers("Bob")).toEqual(expect.arrayContaining(["bob"])));
40
+ expect(strings.createShortIdentifiers("Bob")).toEqual(
41
+ expect.arrayContaining(["bob"]),
42
+ ));
41
43
 
42
44
  it("should create identifiers for multiple words", () =>
43
- expect(createShortIdentifiers("John Doe")).toEqual(
45
+ expect(strings.createShortIdentifiers("John Doe")).toEqual(
44
46
  expect.arrayContaining(["jd", "j_d", "johdoe", "joh_doe"]),
45
47
  ));
46
48
 
47
49
  it("should create identifiers for words containing numbers", () =>
48
- expect(createShortIdentifiers("Alice 123")).toEqual(
50
+ expect(strings.createShortIdentifiers("Alice 123")).toEqual(
49
51
  expect.arrayContaining(["a1", "a_1", "ali123", "ali_123"]),
50
52
  ));
51
53
 
52
54
  it("should create identifiers for words longer than three characters", () =>
53
- expect(createShortIdentifiers("Jonathan")).toEqual(
55
+ expect(strings.createShortIdentifiers("Jonathan")).toEqual(
54
56
  expect.arrayContaining(["jon"]),
55
57
  ));
56
58
 
57
59
  it("should create identifiers for words shorter than three characters", () =>
58
- expect(createShortIdentifiers("Al")).toEqual(expect.arrayContaining(["al"])));
60
+ expect(strings.createShortIdentifiers("Al")).toEqual(
61
+ expect.arrayContaining(["al"]),
62
+ ));
59
63
 
60
64
  it("should create identifiers for mixed cases", () =>
61
- expect(createShortIdentifiers("Alice Bob")).toEqual(
65
+ expect(strings.createShortIdentifiers("Alice Bob")).toEqual(
62
66
  expect.arrayContaining(["ab", "a_b", "alibob", "ali_bob"]),
63
67
  ));
64
68
  });
69
+
70
+ describe("trimPrefix", () => {
71
+ it("should remove a prefix when it exists", () =>
72
+ expect(strings.trimPrefix("hello world", "hello ")).toBe("world"));
73
+
74
+ it("should return the original string when prefix does not exist", () =>
75
+ expect(strings.trimPrefix("hello world", "goodbye ")).toBe("hello world"));
76
+
77
+ it("should return the original string when prefix is empty", () =>
78
+ expect(strings.trimPrefix("hello world", "")).toBe("hello world"));
79
+
80
+ it("should return empty string when prefix equals the entire string", () =>
81
+ expect(strings.trimPrefix("hello world", "hello world")).toBe(""));
82
+
83
+ it("should handle case-sensitive matching", () =>
84
+ expect(strings.trimPrefix("Hello World", "hello ")).toBe("Hello World"));
85
+
86
+ it("should handle partial prefix matches", () =>
87
+ expect(strings.trimPrefix("hello world", "hello")).toBe(" world"));
88
+
89
+ it("should handle prefix longer than string", () =>
90
+ expect(strings.trimPrefix("hello", "hello world")).toBe("hello"));
91
+
92
+ it("should handle special characters in prefix", () =>
93
+ expect(strings.trimPrefix("file:///path/to/file", "file://")).toBe(
94
+ "/path/to/file",
95
+ ));
96
+
97
+ it("should handle unicode characters", () =>
98
+ expect(strings.trimPrefix("café au lait", "café ")).toBe("au lait"));
99
+
100
+ it("should handle numbers in prefix", () =>
101
+ expect(strings.trimPrefix("123abc", "123")).toBe("abc"));
102
+ });
@@ -87,3 +87,23 @@ export const createShortIdentifiers = (name: string): string[] => {
87
87
 
88
88
  return filteredIdentifiers;
89
89
  };
90
+
91
+ /**
92
+ * Removes a prefix from a string if it exists.
93
+ *
94
+ * @param str - The string to remove the prefix from.
95
+ * @param prefix - The prefix to remove.
96
+ * @returns The string with the prefix removed if it was present, otherwise the original string.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * trimPrefix("hello world", "hello "); // "world"
101
+ * trimPrefix("hello world", "goodbye "); // "hello world"
102
+ * trimPrefix("hello world", ""); // "hello world"
103
+ * trimPrefix("hello world", "hello world"); // ""
104
+ * ```
105
+ */
106
+ export const trimPrefix = (str: string, prefix: string): string => {
107
+ if (str.startsWith(prefix)) return str.slice(prefix.length);
108
+ return str;
109
+ };
package/src/telem/gl.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 interface GLBufferController {
13
13
  createBuffer: () => WebGLBuffer | null;