@synnaxlabs/x 0.42.3 → 0.44.0

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 (337) hide show
  1. package/.turbo/turbo-build.log +78 -78
  2. package/.vscode/settings.json +4 -6
  3. package/README.md +1 -7
  4. package/dist/array.cjs +1 -0
  5. package/dist/array.js +7 -0
  6. package/dist/binary.cjs +1 -1
  7. package/dist/binary.js +1 -1
  8. package/dist/bounds-D6e9xoHt.cjs +1 -0
  9. package/dist/bounds-Dj9nG39I.js +174 -0
  10. package/dist/bounds.cjs +1 -1
  11. package/dist/bounds.js +1 -1
  12. package/dist/{box-0YrQibkB.cjs → box-BcGdqkt4.cjs} +1 -1
  13. package/dist/{box-Cc8IzcNo.js → box-D_qdUyEe.js} +2 -2
  14. package/dist/box.cjs +1 -1
  15. package/dist/box.js +1 -1
  16. package/dist/caseconv.cjs +1 -1
  17. package/dist/caseconv.js +1 -1
  18. package/dist/compare.cjs +1 -1
  19. package/dist/compare.js +1 -1
  20. package/dist/deep.cjs +1 -1
  21. package/dist/deep.js +100 -88
  22. package/dist/{direction-C-b6XTeU.cjs → direction-386XDm2w.cjs} +1 -1
  23. package/dist/{direction-BL0PhD1k.js → direction-8etxfKaR.js} +4 -3
  24. package/dist/direction.cjs +1 -1
  25. package/dist/direction.js +1 -1
  26. package/dist/external-B9AAGv50.cjs +1 -0
  27. package/dist/external-BFgJjMcS.js +23 -0
  28. package/dist/{external-DqPrWKvU.js → external-BYuXBYJh.js} +10 -17
  29. package/dist/external-mffsMzJx.cjs +1 -0
  30. package/dist/index-B1m2qvBT.cjs +1 -0
  31. package/dist/index-B5l_quQn.js +92 -0
  32. package/dist/index-BQe8OIgm.cjs +3 -0
  33. package/dist/index-D2xcvEO5.js +46 -0
  34. package/dist/index-DdhM_E4k.cjs +1 -0
  35. package/dist/{index-QGplUHuy.js → index-PNh31WTW.js} +64 -37
  36. package/dist/index.cjs +3 -3
  37. package/dist/index.js +472 -428
  38. package/dist/kv.cjs +1 -1
  39. package/dist/kv.js +1 -1
  40. package/dist/{location-C3aeu046.js → location-Ar5y2DX2.js} +1 -1
  41. package/dist/{location-BGl5Ddds.cjs → location-DZi8ftXp.cjs} +1 -1
  42. package/dist/location.cjs +1 -1
  43. package/dist/location.js +1 -1
  44. package/dist/observe.cjs +1 -1
  45. package/dist/observe.js +16 -20
  46. package/dist/path-BXdMenka.js +101 -0
  47. package/dist/path-st_E5-LJ.cjs +1 -0
  48. package/dist/position-DAL0Qqdf.cjs +1 -0
  49. package/dist/position-bA6pUwLn.js +85 -0
  50. package/dist/position.cjs +1 -1
  51. package/dist/position.js +1 -1
  52. package/dist/record-CAcQ5PNX.js +14 -0
  53. package/dist/record-YvCh7bzB.cjs +1 -0
  54. package/dist/record.cjs +1 -1
  55. package/dist/record.js +2 -10
  56. package/dist/scale-Bzn1Cl0r.cjs +1 -0
  57. package/dist/{scale-DfJe9755.js → scale-CdTNWu-d.js} +55 -59
  58. package/dist/scale.cjs +1 -1
  59. package/dist/scale.js +1 -1
  60. package/dist/series-BeJyqCoP.js +2568 -0
  61. package/dist/series-anlpaR_I.cjs +6 -0
  62. package/dist/spatial.cjs +1 -1
  63. package/dist/spatial.js +6 -6
  64. package/dist/src/array/index.d.ts +2 -0
  65. package/dist/src/array/index.d.ts.map +1 -0
  66. package/dist/src/array/toArray.d.ts +19 -0
  67. package/dist/src/array/toArray.d.ts.map +1 -0
  68. package/dist/src/array/toArray.spec.d.ts +2 -0
  69. package/dist/src/array/toArray.spec.d.ts.map +1 -0
  70. package/dist/src/binary/codec.d.ts +7 -15
  71. package/dist/src/binary/codec.d.ts.map +1 -1
  72. package/dist/src/breaker/breaker.d.ts +5 -5
  73. package/dist/src/breaker/breaker.d.ts.map +1 -1
  74. package/dist/src/caseconv/caseconv.d.ts +0 -1
  75. package/dist/src/caseconv/caseconv.d.ts.map +1 -1
  76. package/dist/src/change/change.d.ts +2 -2
  77. package/dist/src/change/change.d.ts.map +1 -1
  78. package/dist/src/color/color.d.ts +60 -36
  79. package/dist/src/color/color.d.ts.map +1 -1
  80. package/dist/src/color/external.d.ts +0 -1
  81. package/dist/src/color/external.d.ts.map +1 -1
  82. package/dist/src/color/gradient.d.ts +6 -6
  83. package/dist/src/color/gradient.d.ts.map +1 -1
  84. package/dist/src/color/palette.d.ts +9 -9
  85. package/dist/src/color/palette.d.ts.map +1 -1
  86. package/dist/src/compare/compare.d.ts +8 -8
  87. package/dist/src/compare/compare.d.ts.map +1 -1
  88. package/dist/src/control/control.d.ts +39 -39
  89. package/dist/src/control/control.d.ts.map +1 -1
  90. package/dist/src/debounce/debounce.d.ts +1 -1
  91. package/dist/src/debounce/debounce.d.ts.map +1 -1
  92. package/dist/src/deep/delete.d.ts +1 -1
  93. package/dist/src/deep/delete.d.ts.map +1 -1
  94. package/dist/src/deep/difference.d.ts.map +1 -1
  95. package/dist/src/deep/equal.d.ts +4 -4
  96. package/dist/src/deep/equal.d.ts.map +1 -1
  97. package/dist/src/deep/merge.d.ts.map +1 -1
  98. package/dist/src/deep/path.d.ts +6 -6
  99. package/dist/src/deep/path.d.ts.map +1 -1
  100. package/dist/src/destructor.d.ts +6 -2
  101. package/dist/src/destructor.d.ts.map +1 -1
  102. package/dist/src/errors/errors.d.ts +65 -35
  103. package/dist/src/errors/errors.d.ts.map +1 -1
  104. package/dist/src/flush.d.ts +11 -0
  105. package/dist/src/flush.d.ts.map +1 -0
  106. package/dist/src/id/id.d.ts +1 -0
  107. package/dist/src/id/id.d.ts.map +1 -1
  108. package/dist/src/identity.d.ts +2 -2
  109. package/dist/src/identity.d.ts.map +1 -1
  110. package/dist/src/index.d.ts +7 -2
  111. package/dist/src/index.d.ts.map +1 -1
  112. package/dist/src/instance/index.d.ts +2 -0
  113. package/dist/src/instance/index.d.ts.map +1 -0
  114. package/dist/src/instance/matcher.d.ts +79 -0
  115. package/dist/src/instance/matcher.d.ts.map +1 -0
  116. package/dist/src/instance/matcher.spec.d.ts +2 -0
  117. package/dist/src/instance/matcher.spec.d.ts.map +1 -0
  118. package/dist/src/jsonrpc/jsonrpc.d.ts +39 -8
  119. package/dist/src/jsonrpc/jsonrpc.d.ts.map +1 -1
  120. package/dist/src/kv/types.d.ts +1 -1
  121. package/dist/src/kv/types.d.ts.map +1 -1
  122. package/dist/src/map/index.d.ts +2 -0
  123. package/dist/src/map/index.d.ts.map +1 -0
  124. package/dist/src/map/map.d.ts +2 -0
  125. package/dist/src/map/map.d.ts.map +1 -0
  126. package/dist/src/map/map.spec.d.ts +2 -0
  127. package/dist/src/map/map.spec.d.ts.map +1 -0
  128. package/dist/src/math/math.d.ts +2 -4
  129. package/dist/src/math/math.d.ts.map +1 -1
  130. package/dist/src/migrate/migrate.d.ts +4 -4
  131. package/dist/src/migrate/migrate.d.ts.map +1 -1
  132. package/dist/src/optional.d.ts +0 -3
  133. package/dist/src/optional.d.ts.map +1 -1
  134. package/dist/src/primitive/index.d.ts +2 -0
  135. package/dist/src/primitive/index.d.ts.map +1 -0
  136. package/dist/src/primitive/primitive.d.ts +39 -0
  137. package/dist/src/primitive/primitive.d.ts.map +1 -0
  138. package/dist/src/primitive/primitive.spec.d.ts +2 -0
  139. package/dist/src/primitive/primitive.spec.d.ts.map +1 -0
  140. package/dist/src/record/index.d.ts +2 -0
  141. package/dist/src/record/index.d.ts.map +1 -0
  142. package/dist/src/record/record.d.ts +90 -0
  143. package/dist/src/record/record.d.ts.map +1 -0
  144. package/dist/src/record/record.spec.d.ts.map +1 -0
  145. package/dist/src/renderable.d.ts +1 -1
  146. package/dist/src/renderable.d.ts.map +1 -1
  147. package/dist/src/replace.d.ts.map +1 -1
  148. package/dist/src/runtime/detect.d.ts.map +1 -1
  149. package/dist/src/spatial/base.d.ts +9 -9
  150. package/dist/src/spatial/base.d.ts.map +1 -1
  151. package/dist/src/spatial/bounds/bounds.d.ts +82 -16
  152. package/dist/src/spatial/bounds/bounds.d.ts.map +1 -1
  153. package/dist/src/spatial/box/box.d.ts +6 -6
  154. package/dist/src/spatial/box/box.d.ts.map +1 -1
  155. package/dist/src/spatial/dimensions/dimensions.d.ts +4 -4
  156. package/dist/src/spatial/dimensions/dimensions.d.ts.map +1 -1
  157. package/dist/src/spatial/direction/direction.d.ts +2 -2
  158. package/dist/src/spatial/direction/direction.d.ts.map +1 -1
  159. package/dist/src/spatial/location/location.d.ts +3 -3
  160. package/dist/src/spatial/location/location.d.ts.map +1 -1
  161. package/dist/src/spatial/scale/scale.d.ts +10 -10
  162. package/dist/src/spatial/scale/scale.d.ts.map +1 -1
  163. package/dist/src/spatial/xy/xy.d.ts +4 -4
  164. package/dist/src/spatial/xy/xy.d.ts.map +1 -1
  165. package/dist/src/status/index.d.ts +2 -0
  166. package/dist/src/status/index.d.ts.map +1 -0
  167. package/dist/src/status/status.d.ts +42 -0
  168. package/dist/src/status/status.d.ts.map +1 -0
  169. package/dist/src/status/status.spec.d.ts +2 -0
  170. package/dist/src/status/status.spec.d.ts.map +1 -0
  171. package/dist/src/strings/strings.d.ts +16 -0
  172. package/dist/src/strings/strings.d.ts.map +1 -1
  173. package/dist/src/sync/index.d.ts.map +1 -1
  174. package/dist/src/sync/mutex.d.ts +0 -1
  175. package/dist/src/sync/mutex.d.ts.map +1 -1
  176. package/dist/src/telem/series.d.ts +473 -66
  177. package/dist/src/telem/series.d.ts.map +1 -1
  178. package/dist/src/telem/telem.d.ts +274 -61
  179. package/dist/src/telem/telem.d.ts.map +1 -1
  180. package/dist/src/testutil/testutil.d.ts +1 -0
  181. package/dist/src/testutil/testutil.d.ts.map +1 -1
  182. package/dist/src/testutil/testutil.spec.d.ts +2 -0
  183. package/dist/src/testutil/testutil.spec.d.ts.map +1 -0
  184. package/dist/src/uuid/index.d.ts +2 -0
  185. package/dist/src/uuid/index.d.ts.map +1 -0
  186. package/dist/src/uuid/uuid.d.ts +35 -0
  187. package/dist/src/uuid/uuid.d.ts.map +1 -0
  188. package/dist/src/uuid/uuid.spec.d.ts +2 -0
  189. package/dist/src/uuid/uuid.spec.d.ts.map +1 -0
  190. package/dist/src/zod/external.d.ts +2 -1
  191. package/dist/src/zod/external.d.ts.map +1 -1
  192. package/dist/src/zod/nullToUndefined.d.ts +3 -0
  193. package/dist/src/zod/nullToUndefined.d.ts.map +1 -0
  194. package/dist/src/zod/nullToUndefined.spec.d.ts +2 -0
  195. package/dist/src/zod/nullToUndefined.spec.d.ts.map +1 -0
  196. package/dist/src/zod/toArray.d.ts +3 -0
  197. package/dist/src/zod/toArray.d.ts.map +1 -0
  198. package/dist/src/zod/toArray.spec.d.ts +2 -0
  199. package/dist/src/zod/toArray.spec.d.ts.map +1 -0
  200. package/dist/src/zod/util.d.ts +1 -1
  201. package/dist/src/zod/util.d.ts.map +1 -1
  202. package/dist/telem.cjs +1 -1
  203. package/dist/telem.js +10 -11
  204. package/dist/url.cjs +1 -1
  205. package/dist/url.js +16 -19
  206. package/dist/worker.cjs +1 -1
  207. package/dist/worker.js +18 -22
  208. package/dist/zod.cjs +1 -1
  209. package/dist/zod.js +1 -1
  210. package/eslint.config.js +1 -1
  211. package/package.json +20 -23
  212. package/src/array/index.ts +10 -0
  213. package/src/array/toArray.spec.ts +56 -0
  214. package/src/array/toArray.ts +28 -0
  215. package/src/binary/codec.spec.ts +200 -277
  216. package/src/binary/codec.ts +19 -75
  217. package/src/breaker/breaker.ts +2 -2
  218. package/src/caseconv/caseconv.ts +14 -14
  219. package/src/change/change.ts +1 -1
  220. package/src/color/color.spec.ts +113 -2
  221. package/src/color/color.ts +88 -58
  222. package/src/color/external.ts +0 -1
  223. package/src/color/gradient.ts +19 -27
  224. package/src/compare/compare.ts +10 -10
  225. package/src/control/control.ts +22 -19
  226. package/src/debounce/debounce.ts +1 -1
  227. package/src/deep/delete.ts +5 -4
  228. package/src/deep/difference.ts +6 -2
  229. package/src/deep/equal.spec.ts +1 -1
  230. package/src/deep/equal.ts +5 -5
  231. package/src/deep/merge.spec.ts +1 -2
  232. package/src/deep/merge.ts +15 -6
  233. package/src/deep/path.spec.ts +41 -0
  234. package/src/deep/path.ts +48 -17
  235. package/src/destructor.ts +6 -2
  236. package/src/errors/errors.spec.ts +20 -20
  237. package/src/errors/errors.ts +67 -43
  238. package/src/flush.ts +21 -0
  239. package/src/id/id.spec.ts +1 -1
  240. package/src/id/id.ts +3 -1
  241. package/src/identity.ts +2 -2
  242. package/src/index.ts +7 -2
  243. package/src/instance/index.ts +10 -0
  244. package/src/instance/matcher.spec.ts +78 -0
  245. package/src/instance/matcher.ts +98 -0
  246. package/src/jsonrpc/jsonrpc.spec.ts +2 -1
  247. package/src/jsonrpc/jsonrpc.ts +35 -6
  248. package/src/map/index.ts +10 -0
  249. package/src/map/map.spec.ts +132 -0
  250. package/src/map/map.ts +17 -0
  251. package/src/math/math.ts +19 -27
  252. package/src/migrate/migrate.spec.ts +1 -1
  253. package/src/migrate/migrate.ts +7 -7
  254. package/src/optional.ts +0 -4
  255. package/src/primitive/index.ts +10 -0
  256. package/src/primitive/primitive.spec.ts +126 -0
  257. package/src/primitive/primitive.ts +82 -0
  258. package/src/record/index.ts +10 -0
  259. package/src/record/record.spec.ts +319 -0
  260. package/src/record/record.ts +118 -0
  261. package/src/renderable.ts +1 -1
  262. package/src/replace.ts +9 -0
  263. package/src/runtime/detect.ts +0 -2
  264. package/src/spatial/bounds/bounds.spec.ts +20 -0
  265. package/src/spatial/bounds/bounds.ts +101 -18
  266. package/src/spatial/dimensions/dimensions.ts +2 -2
  267. package/src/spatial/direction/direction.ts +1 -1
  268. package/src/status/index.ts +10 -0
  269. package/src/status/status.spec.ts +25 -0
  270. package/src/status/status.ts +91 -0
  271. package/src/strings/strings.spec.ts +51 -13
  272. package/src/strings/strings.ts +20 -0
  273. package/src/sync/index.ts +9 -0
  274. package/src/sync/mutex.ts +9 -4
  275. package/src/telem/series.spec.ts +912 -105
  276. package/src/telem/series.ts +577 -201
  277. package/src/telem/telem.spec.ts +262 -90
  278. package/src/telem/telem.ts +335 -125
  279. package/src/testutil/testutil.spec.ts +161 -0
  280. package/src/testutil/testutil.ts +12 -0
  281. package/src/uuid/index.ts +10 -0
  282. package/src/uuid/uuid.spec.ts +82 -0
  283. package/src/uuid/uuid.ts +48 -0
  284. package/src/zod/external.ts +2 -1
  285. package/src/zod/nullToUndefined.spec.ts +31 -0
  286. package/src/zod/nullToUndefined.ts +23 -0
  287. package/src/zod/toArray.spec.ts +182 -0
  288. package/src/{toArray.ts → zod/toArray.ts} +3 -4
  289. package/src/zod/util.spec.ts +1 -1
  290. package/src/zod/util.ts +7 -7
  291. package/tsconfig.json +1 -1
  292. package/tsconfig.tsbuildinfo +1 -1
  293. package/vite.config.ts +2 -3
  294. package/dist/bounds-BQo7rvs9.cjs +0 -1
  295. package/dist/bounds-Bn5_l4Z3.js +0 -173
  296. package/dist/external-C-dNgNQw.cjs +0 -1
  297. package/dist/external-C8TFju8Q.js +0 -29
  298. package/dist/external-DWQITF5_.cjs +0 -1
  299. package/dist/index-BywOGO8U.js +0 -1074
  300. package/dist/index-CYYjI7Uf.cjs +0 -1
  301. package/dist/index-C_6NXBlg.cjs +0 -3
  302. package/dist/index-Dd8DLyMx.cjs +0 -1
  303. package/dist/index-DizUWH6z.js +0 -47
  304. package/dist/path-1tZLZ4AN.cjs +0 -1
  305. package/dist/path-DD6ytXzr.js +0 -76
  306. package/dist/position-Cai5-wi1.cjs +0 -1
  307. package/dist/position-DIglP1l2.js +0 -85
  308. package/dist/scale-BtZINJ-A.cjs +0 -1
  309. package/dist/search.cjs +0 -1
  310. package/dist/search.js +0 -14
  311. package/dist/series-B9JERcqi.js +0 -1977
  312. package/dist/series-DqJ6f97G.cjs +0 -11
  313. package/dist/src/color/transformColorsToHex.d.ts +0 -6
  314. package/dist/src/color/transformColorsToHex.d.ts.map +0 -1
  315. package/dist/src/primitive.d.ts +0 -9
  316. package/dist/src/primitive.d.ts.map +0 -1
  317. package/dist/src/record.d.ts +0 -18
  318. package/dist/src/record.d.ts.map +0 -1
  319. package/dist/src/record.spec.d.ts.map +0 -1
  320. package/dist/src/search.d.ts +0 -18
  321. package/dist/src/search.d.ts.map +0 -1
  322. package/dist/src/toArray.d.ts +0 -3
  323. package/dist/src/toArray.d.ts.map +0 -1
  324. package/dist/src/zod/integer.d.ts +0 -10
  325. package/dist/src/zod/integer.d.ts.map +0 -1
  326. package/dist/src/zod/integer.spec.d.ts +0 -2
  327. package/dist/src/zod/integer.spec.d.ts.map +0 -1
  328. package/dist/toArray.cjs +0 -1
  329. package/dist/toArray.js +0 -5
  330. package/src/color/transformColorsToHex.ts +0 -30
  331. package/src/primitive.ts +0 -46
  332. package/src/record.spec.ts +0 -38
  333. package/src/record.ts +0 -47
  334. package/src/search.ts +0 -42
  335. package/src/zod/integer.spec.ts +0 -148
  336. package/src/zod/integer.ts +0 -38
  337. /package/dist/src/{record.spec.d.ts → record/record.spec.d.ts} +0 -0
@@ -10,6 +10,7 @@
10
10
  import { describe, expect, it } from "vitest";
11
11
 
12
12
  import { deep } from "@/deep";
13
+ import { type record } from "@/record";
13
14
 
14
15
  interface TestRecord {
15
16
  a: number;
@@ -72,8 +73,22 @@ describe("path", () => {
72
73
  }),
73
74
  ).toEqual(0);
74
75
  });
76
+
77
+ it("should get an array of keyed records", () => {
78
+ interface TestKeyedRecord {
79
+ values: record.KeyedNamed[];
80
+ }
81
+ const a: TestKeyedRecord = {
82
+ values: [
83
+ { key: "a", name: "a" },
84
+ { key: "b", name: "b" },
85
+ ],
86
+ };
87
+ expect(deep.get(a, "values.a.name")).toEqual("a");
88
+ });
75
89
  });
76
90
  });
91
+
77
92
  describe("set", () => {
78
93
  it("should set a key", () => {
79
94
  const a: TestRecord = {
@@ -111,6 +126,32 @@ describe("path", () => {
111
126
  deep.set(a, "c.1", 4);
112
127
  expect(a).toEqual(b);
113
128
  });
129
+
130
+ it("should set a value on a nested object in the array by key", () => {
131
+ const data = {
132
+ config: {
133
+ channels: [{ key: "tMnAnJeQmn6", type: "ai_voltage" }],
134
+ },
135
+ };
136
+ deep.set(data, "config.channels.tMnAnJeQmn6.type", "ai_force_bridge_table");
137
+ expect(data.config.channels[0].type).toEqual("ai_force_bridge_table");
138
+ });
139
+
140
+ it("should set an entire item in the array by its key", () => {
141
+ const data = {
142
+ config: {
143
+ channels: [{ key: "tMnAnJeQmn6", type: "ai_voltage" }],
144
+ },
145
+ };
146
+ deep.set(data, "config.channels.tMnAnJeQmn6", {
147
+ key: "tMnAnJeQmn6",
148
+ type: "ai_force_bridge_table",
149
+ });
150
+ expect(data.config.channels[0]).toEqual({
151
+ key: "tMnAnJeQmn6",
152
+ type: "ai_force_bridge_table",
153
+ });
154
+ });
114
155
  });
115
156
 
116
157
  describe("transformPath", () => {
package/src/deep/path.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { type Join } from "@/join";
11
- import { type UnknownRecord } from "@/record";
11
+ import { type record } from "@/record";
12
12
 
13
13
  type Prev = [
14
14
  never,
@@ -53,7 +53,7 @@ export type Key<T, D extends number = 5> = [D] extends [never]
53
53
  /** Options for the get function. */
54
54
  export interface GetOptions<O extends boolean | undefined = boolean | undefined> {
55
55
  optional: O;
56
- getter?: (obj: UnknownRecord, key: string) => unknown;
56
+ getter?: (obj: record.Unknown, key: string) => unknown;
57
57
  separator?: string;
58
58
  }
59
59
 
@@ -69,12 +69,12 @@ export interface GetOptions<O extends boolean | undefined = boolean | undefined>
69
69
  * @returns the value at the given path on the object.
70
70
  */
71
71
  export interface Get {
72
- <V = unknown, T = UnknownRecord>(
72
+ <V = record.Unknown, T = record.Unknown>(
73
73
  obj: T,
74
74
  path: string,
75
75
  options?: GetOptions<false>,
76
76
  ): V;
77
- <V = unknown, T = UnknownRecord>(
77
+ <V = record.Unknown, T = record.Unknown>(
78
78
  obj: T,
79
79
  path: string,
80
80
  options?: GetOptions<boolean | undefined>,
@@ -82,7 +82,7 @@ export interface Get {
82
82
  }
83
83
 
84
84
  /** A strongly typed version of the @link Get function. */
85
- export interface TypedGet<V = unknown, T = UnknownRecord> {
85
+ export interface TypedGet<V = record.Unknown, T = record.Unknown> {
86
86
  (obj: T, path: string, options?: GetOptions<false>): V;
87
87
  (obj: T, path: string, options?: GetOptions<boolean | undefined>): V | null;
88
88
  }
@@ -116,6 +116,16 @@ export const transformPath = (
116
116
  return result.join(separator);
117
117
  };
118
118
 
119
+ const defaultGetter = (obj: record.Unknown, key: string): unknown => {
120
+ if (!Array.isArray(obj)) return obj[key];
121
+ const res = obj[key];
122
+ if (res != null || obj.length == 0) return res;
123
+ const first = obj[0];
124
+ if (typeof first === "object" && "key" in first)
125
+ return obj.find((o) => o.key === key);
126
+ return undefined;
127
+ };
128
+
119
129
  /**
120
130
  * Gets the value at the given path on the object. If the path does not exist
121
131
  * and the optional flag is set to true, null will be returned. If the path does
@@ -127,23 +137,23 @@ export const transformPath = (
127
137
  * @param opts.getter a custom getter function to use on each part of the path.
128
138
  * @returns the value at the given path on the object.
129
139
  */
130
- export const get = (<V = unknown, T = UnknownRecord>(
140
+ export const get = (<V = record.Unknown, T = record.Unknown>(
131
141
  obj: T,
132
142
  path: string,
133
143
  opts: GetOptions = { optional: false, separator: "." },
134
144
  ): V | null => {
135
145
  opts.separator ??= ".";
136
- const { optional, getter = (obj, key) => (obj)[key] } = opts;
146
+ const { optional, getter = defaultGetter } = opts;
137
147
  const parts = path.split(opts.separator);
138
- if (parts.length === 1 && parts[0] === "") return obj as unknown as V;
139
- let result: UnknownRecord = obj as UnknownRecord;
148
+ if (parts.length === 1 && parts[0] === "") return obj as record.Unknown as V;
149
+ let result: record.Unknown = obj as record.Unknown;
140
150
  for (const part of parts) {
141
151
  const v = getter(result, part);
142
152
  if (v == null) {
143
153
  if (optional) return null;
144
154
  throw new Error(`Path ${path} does not exist. ${part} is null`);
145
155
  }
146
- result = v as UnknownRecord;
156
+ result = v as record.Unknown;
147
157
  }
148
158
  return result as V;
149
159
  }) as Get;
@@ -157,14 +167,32 @@ export const get = (<V = unknown, T = UnknownRecord>(
157
167
  */
158
168
  export const set = <V>(obj: V, path: string, value: unknown): void => {
159
169
  const parts = path.split(".");
160
- let result: UnknownRecord = obj as UnknownRecord;
170
+ let result: record.Unknown = obj as record.Unknown;
161
171
  for (let i = 0; i < parts.length - 1; i++) {
162
172
  const part = parts[i];
163
- result[part] ??= {};
164
- result = result[part] as UnknownRecord;
173
+ const v = defaultGetter(result, part);
174
+ if (v == null) throw new Error(`Path ${path} does not exist. ${part} is null`);
175
+ result = v as record.Unknown;
165
176
  }
166
177
  try {
167
- result[parts[parts.length - 1]] = value;
178
+ if (!Array.isArray(result)) {
179
+ result[parts[parts.length - 1]] = value;
180
+ return;
181
+ }
182
+ if (result.length === 0) return;
183
+ const index = parseInt(parts[parts.length - 1]);
184
+ if (isNaN(index)) {
185
+ const first = result[0];
186
+ if (typeof first === "object" && "key" in first) {
187
+ const objIndex = result.findIndex((o) => o.key === parts[parts.length - 1]);
188
+ if (objIndex !== -1) {
189
+ result[objIndex] = value;
190
+ return;
191
+ }
192
+ }
193
+ return;
194
+ }
195
+ result[index] = value;
168
196
  } catch (e) {
169
197
  console.error("failed to set value", value, "at path", path, "on object", obj);
170
198
  throw e;
@@ -179,11 +207,11 @@ export const set = <V>(obj: V, path: string, value: unknown): void => {
179
207
  */
180
208
  export const remove = <V>(obj: V, path: string): void => {
181
209
  const parts = path.split(".");
182
- let result: UnknownRecord = obj as UnknownRecord;
210
+ let result: record.Unknown = obj as record.Unknown;
183
211
  for (let i = 0; i < parts.length - 1; i++) {
184
212
  const part = parts[i];
185
213
  if (result[part] == null) return;
186
- result = result[part] as UnknownRecord;
214
+ result = result[part] as record.Unknown;
187
215
  }
188
216
  // if its an array, we need to splice it
189
217
  if (Array.isArray(result)) {
@@ -213,7 +241,10 @@ export const element = (path: string, index: number): string => {
213
241
  * @param path the path to check
214
242
  * @returns whether the path exists in the object
215
243
  */
216
- export const has = <V = unknown, T = UnknownRecord>(obj: T, path: string): boolean => {
244
+ export const has = <V = record.Unknown, T = record.Unknown>(
245
+ obj: T,
246
+ path: string,
247
+ ): boolean => {
217
248
  try {
218
249
  get<V, T>(obj, path);
219
250
  return true;
package/src/destructor.ts CHANGED
@@ -7,6 +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
- export type Destructor = () => void;
10
+ export interface Destructor {
11
+ (): void;
12
+ }
11
13
 
12
- export type AsyncDestructor = () => Promise<void>;
14
+ export interface AsyncDestructor {
15
+ (): Promise<void>;
16
+ }
@@ -30,14 +30,14 @@ describe("errors", () => {
30
30
  it("should return true if the error implements the TypedError interface", () => {
31
31
  const error = new ErrorOne("test");
32
32
  const fError = errors.isTyped(error);
33
- expect(fError).toBeTruthy();
33
+ expect(fError).toBe(true);
34
34
  expect(error.type).toEqual("one");
35
35
  });
36
36
 
37
37
  it("should return false if the error does not implement the TypedError interface", () => {
38
38
  const error = new Error("rando");
39
39
  const fError = errors.isTyped(error);
40
- expect(fError).toBeFalsy();
40
+ expect(fError).toBe(false);
41
41
  });
42
42
  });
43
43
 
@@ -50,7 +50,7 @@ describe("errors", () => {
50
50
  const error = new ErrorOne("test");
51
51
  const encoded = errors.encode(error);
52
52
  const decoded = errors.decode(encoded);
53
- expect(ErrorOne.matches(decoded)).toBeTruthy();
53
+ expect(ErrorOne.matches(decoded)).toBe(true);
54
54
  });
55
55
 
56
56
  test("should correctly encode/decode a null error", () => {
@@ -85,7 +85,7 @@ describe("errors", () => {
85
85
  expect(encoded.type).toEqual(errors.UNKNOWN);
86
86
  expect(encoded.data).toEqual("test");
87
87
  const decoded = errors.decode(encoded);
88
- expect(errors.Unknown.matches(decoded)).toBeTruthy();
88
+ expect(errors.Unknown.matches(decoded)).toBe(true);
89
89
  });
90
90
 
91
91
  it("should correctly encode/decode a random object", () => {
@@ -94,59 +94,59 @@ describe("errors", () => {
94
94
  expect(encoded.type).toEqual(errors.UNKNOWN);
95
95
  expect(encoded.data).toEqual(JSON.stringify(error));
96
96
  const decoded = errors.decode(encoded);
97
- expect(errors.Unknown.matches(decoded)).toBeTruthy();
97
+ expect(errors.Unknown.matches(decoded)).toBe(true);
98
98
  });
99
99
  });
100
100
 
101
101
  describe("matches", () => {
102
102
  it("should return true if the errors are exactly the same", () => {
103
103
  const v = new ErrorOne("test");
104
- expect(ErrorOne.matches(v)).toBeTruthy();
104
+ expect(ErrorOne.matches(v)).toBe(true);
105
105
  const v2 = new ErrorOne("test");
106
- expect(v2.matches(v)).toBeTruthy();
106
+ expect(v2.matches(v)).toBe(true);
107
107
  });
108
108
 
109
109
  it("should return false if the errors are typed and clearly different", () => {
110
110
  const e1 = new ErrorOne("test");
111
111
  const e2 = new ErrorTwo("test");
112
- expect(e1.matches(e2)).toBeFalsy();
113
- expect(ErrorOne.matches(e2)).toBeFalsy();
114
- expect(ErrorTwo.matches(e1)).toBeFalsy();
112
+ expect(e1.matches(e2)).toBe(false);
113
+ expect(ErrorOne.matches(e2)).toBe(false);
114
+ expect(ErrorTwo.matches(e1)).toBe(false);
115
115
  });
116
116
 
117
117
  it("should return false if the error is not typed", () => {
118
118
  const e1 = new ErrorOne("test");
119
119
  const e2 = new Error("rando");
120
- expect(e1.matches(e2)).toBeFalsy();
121
- expect(ErrorOne.matches(e2)).toBeFalsy();
120
+ expect(e1.matches(e2)).toBe(false);
121
+ expect(ErrorOne.matches(e2)).toBe(false);
122
122
  });
123
123
 
124
124
  it("should return false if the error is not actually an error", () => {
125
125
  const e1 = new ErrorOne("test");
126
126
  const e2 = "rando";
127
- expect(e1.matches(e2)).toBeFalsy();
128
- expect(ErrorOne.matches(e2)).toBeFalsy();
127
+ expect(e1.matches(e2)).toBe(false);
128
+ expect(ErrorOne.matches(e2)).toBe(false);
129
129
  });
130
130
 
131
131
  it("should return false if hte error is undefined", () => {
132
132
  const e1 = new ErrorOne("test");
133
133
  const e2 = undefined;
134
- expect(e1.matches(e2)).toBeFalsy();
135
- expect(ErrorOne.matches(e2)).toBeFalsy();
134
+ expect(e1.matches(e2)).toBe(false);
135
+ expect(ErrorOne.matches(e2)).toBe(false);
136
136
  });
137
137
 
138
138
  it("should return true if the the matching error is a parent", () => {
139
139
  const e1 = new ErrorOne("rando");
140
140
  const e2 = new SubError("rando");
141
- expect(e1.matches(e2)).toBeTruthy();
142
- expect(ErrorOne.matches(e1)).toBeTruthy();
141
+ expect(e1.matches(e2)).toBe(true);
142
+ expect(ErrorOne.matches(e1)).toBe(true);
143
143
  });
144
144
 
145
145
  it("should return false if the matching error is a sub-error", () => {
146
146
  const e1 = new ErrorOne("random");
147
147
  const e2 = new SubError("random");
148
- expect(e2.matches(e1)).toBeFalsy();
149
- expect(SubError.matches(e1)).toBeFalsy();
148
+ expect(e2.matches(e1)).toBe(false);
149
+ expect(SubError.matches(e1)).toBe(false);
150
150
  });
151
151
  });
152
152
  });
@@ -11,55 +11,56 @@ import { z } from "zod";
11
11
 
12
12
  import { singleton } from "@/singleton";
13
13
 
14
+ const ERROR_DISCRIMINATOR = "sy_x_error";
15
+
14
16
  /**
15
17
  * @returns general function that returns true if an error matches a set of
16
18
  * abstracted criteria
17
19
  */
18
- export type Matcher = (e: string | Error | unknown) => boolean;
20
+ export type Matcher = (e: unknown) => boolean;
19
21
 
20
- /** @description an error type that can match against other errors. */
22
+ /** an error type that can match against other errors. */
21
23
  export interface Matchable {
22
24
  /**
23
- * @returns a function that matches errors of the given type. Returns true if
24
- * the provided instance of Error or a string message contains the provided error type.
25
+ * @returns true if the provided error matches the matchable.
25
26
  */
26
27
  matches: Matcher;
27
28
  }
28
29
 
29
30
  /**
30
- * @description an error that has a network-portable type, allowing it to be encoded/
31
- * decoded by freighter. Also allows for simpler matching using @method matches instead
32
- * of using instanceof, which has a number of caveats.
31
+ * An error that has a network-portable type, allowing it to be encoded/decoded into
32
+ * a JSON representation. Also allows for simpler matching using @method matches instead of using
33
+ * instanceof, which has a number of caveats.
33
34
  */
34
35
  export interface Typed extends Error, Matchable {
35
- discriminator: "FreighterError";
36
+ discriminator: typeof ERROR_DISCRIMINATOR;
36
37
  /**
37
- * @description Returns a unique type identifier for the error. Freighter uses this to
38
- * determine the correct decoder to use on the other end of the freighter.
38
+ * Returns a unique type identifier for the error. The errors package uses this to
39
+ * determine the correct decoder to use when encoding/decoding errors.
39
40
  */
40
41
  type: string;
41
42
  }
42
43
 
43
44
  /**
44
- * @description a class that, when constructed, implements the TypedError interface.
45
- * Also provides utilities for matching and creating subclasses.
45
+ * a class that, when constructed, implements the TypedError interface. Also provides
46
+ * utilities for matching and creating subclasses.
46
47
  */
47
48
  export interface TypedClass extends Matchable {
48
49
  /**
49
- * @description constructs a new TypedError. Identical to the Error constructor.
50
+ * constructs a new TypedError. Identical to the Error constructor.
50
51
  * @param message - the error message.
51
52
  * @param options - the error options.
52
53
  * @returns a new TypedError.
53
54
  */
54
55
  new (message?: string, options?: ErrorOptions): Typed;
55
56
  /**
56
- * @description the type of the error.
57
+ * the type of the error.
57
58
  */
58
59
  TYPE: string;
59
60
  /**
60
- * @description creates a new subclass of the error that extends its type. So if
61
- * the type of this class is `dog` and subType is `labrador`, the type of the new
62
- * class will be `dog.labrador`.
61
+ * creates a new subclass of the error that extends its type. So if the type of this
62
+ * class is `dog` and subType is `labrador`, the type of the new class will be
63
+ * `dog.labrador`.
63
64
  * @param subType - the type of the new error.
64
65
  * @returns a new TypedErrorClass.
65
66
  */
@@ -92,7 +93,7 @@ const createTypeMatcher =
92
93
  */
93
94
  export const createTyped = (type: string): TypedClass =>
94
95
  class Internal extends Error implements Typed {
95
- static readonly discriminator = "FreighterError";
96
+ static readonly discriminator = ERROR_DISCRIMINATOR;
96
97
  readonly discriminator = Internal.discriminator;
97
98
 
98
99
  static readonly TYPE = type;
@@ -111,50 +112,67 @@ export const createTyped = (type: string): TypedClass =>
111
112
  };
112
113
 
113
114
  /**
114
- * @description Function that decodes an encoded error payload back into an error object
115
+ * Function that decodes an encoded error payload back into an error object
115
116
  * @param encoded - The encoded error payload to decode
116
- * @returns The decoded error object or null if the decoder cannot handle this error type
117
+ * @returns The decoded error object or null if the decoder cannot handle this error
118
+ * type
117
119
  */
118
120
  export type Decoder = (encoded: Payload) => Error | null;
119
121
 
120
122
  /**
121
- * @description Function that encodes a typed error into a network-portable payload
123
+ * Function that encodes a typed error into a network-portable payload
122
124
  * @param error - The typed error to encode
123
125
  * @returns The encoded error payload or null if the encoder cannot handle this error type
124
126
  */
125
127
  export type Encoder = (error: Typed) => Payload | null;
126
128
 
127
129
  /**
128
- * @description Checks if an unknown value is a TypedError
130
+ * Checks if an unknown value is a TypedError
129
131
  * @param error - The value to check
130
132
  * @returns True if the value is a TypedError, false otherwise
131
133
  */
132
134
  export const isTyped = (error: unknown): error is Typed => {
133
135
  if (error == null || typeof error !== "object") return false;
134
136
  const typedError = error as Typed;
135
- if (typedError.discriminator !== "FreighterError") return false;
137
+ if (typedError.discriminator !== ERROR_DISCRIMINATOR) return false;
136
138
  if (!("type" in typedError))
137
139
  throw new Error(
138
- `Freighter error is missing its type property: ${JSON.stringify(typedError)}`,
140
+ `X Error is missing its type property: ${JSON.stringify(typedError)}`,
139
141
  );
140
142
  return true;
141
143
  };
142
144
 
143
- /** @description Constant representing an unknown error type */
145
+ /** Constant representing an unknown error type */
144
146
  export const UNKNOWN = "unknown";
145
147
 
146
- /** @description Constant representing no error (null) */
148
+ /** Constant representing no error (null) */
147
149
  export const NONE = "nil";
148
150
 
149
- interface provider {
151
+ /**
152
+ * provides custom encoding/decoding mechanisms for specific error
153
+ * categories.
154
+ */
155
+ interface Provider {
156
+ /**
157
+ * Encodes an error into a primitive payload that can be sent over the network or stored
158
+ * on disk.
159
+ * @param error - The error to encode.
160
+ * @returns The encoded error.
161
+ */
150
162
  encode: Encoder;
163
+ /**
164
+ * Decodes an error from a primitive payload that can be sent over the network or stored
165
+ * on disk.
166
+ * @param payload - The encoded error.
167
+ * @returns The decoded error.
168
+ */
151
169
  decode: Decoder;
152
170
  }
153
171
 
154
172
  class Registry {
155
- private readonly providers: provider[] = [];
173
+ private readonly providers: Provider[] = [];
156
174
 
157
- register(provider: provider): void {
175
+ register(provider: Provider): void {
158
176
  this.providers.push(provider);
159
177
  }
160
178
 
@@ -195,17 +213,12 @@ const getRegistry = singleton.define("synnax-error-registry", () => new Registry
195
213
  * @param encode - A function that encodes the error into a string.
196
214
  * @param decode - A function that decodes the error from a string.
197
215
  */
198
- export const register = ({
199
- encode,
200
- decode,
201
- }: {
202
- encode: Encoder;
203
- decode: Decoder;
204
- }): void => getRegistry().register({ encode, decode });
216
+ export const register = ({ encode, decode }: Provider): void =>
217
+ getRegistry().register({ encode, decode });
205
218
 
206
219
  /**
207
- * Encodes an error into a payload that can be sent between a freighter server
208
- * and client.
220
+ * Encodes an error into a primitive payload that can be sent over the network or stored
221
+ * on disk.
209
222
  * @param error - The error to encode.
210
223
  * @returns The encoded error.
211
224
  */
@@ -225,17 +238,28 @@ export const decode = (payload?: Payload | null): Error | null => {
225
238
  };
226
239
 
227
240
  /**
228
- * @description Generic error for representing unknown errors
241
+ * Generic error for representing unknown errors
229
242
  */
230
243
  export class Unknown extends createTyped("unknown") {}
231
244
 
232
- /** @description Zod schema for validating error payloads */
245
+ /** Zod schema for validating error payloads */
233
246
  export const payloadZ = z.object({ type: z.string(), data: z.string() });
234
247
 
235
- /** @description Network-portable representation of an error */
248
+ /** Network-portable representation of an error */
236
249
  export type Payload = z.infer<typeof payloadZ>;
237
250
 
238
- /** @description Error for representing the cancellation of an operation */
251
+ /** Error for representing the cancellation of an operation */
239
252
  export class Canceled extends createTyped("canceled") {}
240
253
 
241
- export type Return<T> = [T, null] | [null, Error];
254
+ /** A payload representing a native JavaScript Error */
255
+ export interface NativePayload {
256
+ /** The name of the error */
257
+ name: string;
258
+ /** The message of the error */
259
+ message: string;
260
+ /** The stack trace of the error */
261
+ stack?: string;
262
+ }
263
+
264
+ /** Error for representing a method that is not implemented */
265
+ export class NotImplemented extends createTyped("not_implemented") {}
package/src/flush.ts ADDED
@@ -0,0 +1,21 @@
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
+ /**
11
+ * Flushes the microtask queue.
12
+ * @returns A promise that resolves when the microtask queue is flushed.
13
+ */
14
+ export const flushMicrotasks = (): Promise<void> => Promise.resolve();
15
+
16
+ /**
17
+ * Flushes the task queue.
18
+ * @returns A promise that resolves when the task queue is flushed.
19
+ */
20
+ export const flushTaskQueue = (): Promise<void> =>
21
+ new Promise((resolve) => setTimeout(resolve, 0));
package/src/id/id.spec.ts CHANGED
@@ -20,7 +20,7 @@ describe("id", () => {
20
20
 
21
21
  it("should create a string of length 11", () => {
22
22
  const newID = id.create();
23
- expect(newID.length).toBe(11);
23
+ expect(newID.length).toBe(id.LENGTH);
24
24
  });
25
25
 
26
26
  it("should only contain alphanumeric characters", () => {
package/src/id/id.ts CHANGED
@@ -11,7 +11,9 @@ import { customAlphabet } from "nanoid/non-secure";
11
11
 
12
12
  const ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
13
13
 
14
- const createInternal = customAlphabet(ALPHANUMERIC, 11);
14
+ export const LENGTH = 11;
15
+
16
+ const createInternal = customAlphabet(ALPHANUMERIC, LENGTH);
15
17
 
16
18
  /**
17
19
  * Creates a unique alphanumeric string of length 11.
package/src/identity.ts CHANGED
@@ -7,8 +7,8 @@
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 UnknownRecord } from "@/record";
10
+ import { type record } from "@/record";
11
11
 
12
- export const isObject = <T extends UnknownRecord = UnknownRecord>(
12
+ export const isObject = <T extends record.Unknown = record.Unknown>(
13
13
  item?: unknown,
14
14
  ): item is T => item != null && typeof item === "object" && !Array.isArray(item);
package/src/index.ts CHANGED
@@ -7,6 +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
+ export * from "@/array";
10
11
  export * from "@/binary";
11
12
  export * from "@/breaker";
12
13
  export * from "@/caseconv";
@@ -19,12 +20,15 @@ export * from "@/debounce/debounce";
19
20
  export * from "@/deep";
20
21
  export * from "@/destructor";
21
22
  export * from "@/errors";
23
+ export * from "@/flush";
22
24
  export * from "@/id";
23
25
  export * from "@/identity";
26
+ export * from "@/instance";
24
27
  export * from "@/invert";
25
28
  export * from "@/jsonrpc";
26
29
  export * from "@/kv";
27
30
  export * from "@/link";
31
+ export * from "@/map";
28
32
  export * from "@/math";
29
33
  export * from "@/migrate";
30
34
  export * from "@/notation";
@@ -36,16 +40,17 @@ export * from "@/renderable";
36
40
  export * from "@/replace";
37
41
  export * from "@/runtime";
38
42
  export * from "@/runtime";
39
- export * from "@/search";
40
43
  export * from "@/shallowCopy";
41
44
  export * from "@/sleep";
42
45
  export * from "@/spatial";
46
+ export * from "@/status";
43
47
  export * from "@/strings";
44
48
  export * from "@/sync";
45
49
  export * from "@/telem";
46
- export * from "@/toArray";
50
+ export * from "@/testutil";
47
51
  export * from "@/transform";
48
52
  export * from "@/unique";
49
53
  export * from "@/url";
54
+ export * from "@/uuid";
50
55
  export * from "@/worker";
51
56
  export * from "@/zod";
@@ -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 instance from "@/instance/matcher";