@synnaxlabs/client 0.43.1 → 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 (245) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/dist/access/payload.d.ts +1 -1
  3. package/dist/access/payload.d.ts.map +1 -1
  4. package/dist/access/policy/client.d.ts +263 -6
  5. package/dist/access/policy/client.d.ts.map +1 -1
  6. package/dist/access/policy/external.d.ts +0 -1
  7. package/dist/access/policy/external.d.ts.map +1 -1
  8. package/dist/access/policy/payload.d.ts +105 -93
  9. package/dist/access/policy/payload.d.ts.map +1 -1
  10. package/dist/auth/auth.d.ts +1 -1
  11. package/dist/auth/auth.d.ts.map +1 -1
  12. package/dist/channel/client.d.ts +12 -13
  13. package/dist/channel/client.d.ts.map +1 -1
  14. package/dist/channel/payload.d.ts +77 -19
  15. package/dist/channel/payload.d.ts.map +1 -1
  16. package/dist/channel/retriever.d.ts +9 -16
  17. package/dist/channel/retriever.d.ts.map +1 -1
  18. package/dist/channel/writer.d.ts +1 -1
  19. package/dist/channel/writer.d.ts.map +1 -1
  20. package/dist/client.cjs +27 -135
  21. package/dist/client.d.ts +3 -3
  22. package/dist/client.d.ts.map +1 -1
  23. package/dist/client.js +8612 -28957
  24. package/dist/connection/checker.d.ts +1 -1
  25. package/dist/connection/checker.d.ts.map +1 -1
  26. package/dist/control/client.d.ts +1 -0
  27. package/dist/control/client.d.ts.map +1 -1
  28. package/dist/control/state.d.ts +6 -6
  29. package/dist/control/state.d.ts.map +1 -1
  30. package/dist/errors.d.ts +18 -5
  31. package/dist/errors.d.ts.map +1 -1
  32. package/dist/framer/adapter.d.ts +3 -3
  33. package/dist/framer/adapter.d.ts.map +1 -1
  34. package/dist/framer/client.d.ts +4 -13
  35. package/dist/framer/client.d.ts.map +1 -1
  36. package/dist/framer/codec.d.ts +1 -1
  37. package/dist/framer/codec.d.ts.map +1 -1
  38. package/dist/framer/deleter.d.ts +5 -5
  39. package/dist/framer/deleter.d.ts.map +1 -1
  40. package/dist/framer/frame.d.ts +5 -7
  41. package/dist/framer/frame.d.ts.map +1 -1
  42. package/dist/framer/streamProxy.d.ts +1 -1
  43. package/dist/framer/streamProxy.d.ts.map +1 -1
  44. package/dist/framer/streamer.d.ts +139 -20
  45. package/dist/framer/streamer.d.ts.map +1 -1
  46. package/dist/framer/writer.d.ts +222 -33
  47. package/dist/framer/writer.d.ts.map +1 -1
  48. package/dist/hardware/device/client.d.ts +49 -28
  49. package/dist/hardware/device/client.d.ts.map +1 -1
  50. package/dist/hardware/device/payload.d.ts +126 -46
  51. package/dist/hardware/device/payload.d.ts.map +1 -1
  52. package/dist/hardware/rack/client.d.ts +78 -22
  53. package/dist/hardware/rack/client.d.ts.map +1 -1
  54. package/dist/hardware/rack/payload.d.ts +99 -56
  55. package/dist/hardware/rack/payload.d.ts.map +1 -1
  56. package/dist/hardware/task/client.d.ts +100 -41
  57. package/dist/hardware/task/client.d.ts.map +1 -1
  58. package/dist/hardware/task/payload.d.ts +83 -61
  59. package/dist/hardware/task/payload.d.ts.map +1 -1
  60. package/dist/index.d.ts +2 -2
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/label/client.d.ts +138 -20
  63. package/dist/label/client.d.ts.map +1 -1
  64. package/dist/label/external.d.ts +0 -2
  65. package/dist/label/external.d.ts.map +1 -1
  66. package/dist/label/payload.d.ts +4 -5
  67. package/dist/label/payload.d.ts.map +1 -1
  68. package/dist/ontology/client.d.ts +45 -135
  69. package/dist/ontology/client.d.ts.map +1 -1
  70. package/dist/ontology/group/group.d.ts +3 -3
  71. package/dist/ontology/group/group.d.ts.map +1 -1
  72. package/dist/ontology/group/payload.d.ts +3 -27
  73. package/dist/ontology/group/payload.d.ts.map +1 -1
  74. package/dist/ontology/payload.d.ts +113 -243
  75. package/dist/ontology/payload.d.ts.map +1 -1
  76. package/dist/ontology/writer.d.ts +4 -4
  77. package/dist/ontology/writer.d.ts.map +1 -1
  78. package/dist/ranger/alias.d.ts +11 -5
  79. package/dist/ranger/alias.d.ts.map +1 -1
  80. package/dist/ranger/client.d.ts +87 -30
  81. package/dist/ranger/client.d.ts.map +1 -1
  82. package/dist/ranger/external.d.ts +1 -1
  83. package/dist/ranger/external.d.ts.map +1 -1
  84. package/dist/ranger/kv.d.ts +10 -12
  85. package/dist/ranger/kv.d.ts.map +1 -1
  86. package/dist/ranger/payload.d.ts +23 -44
  87. package/dist/ranger/payload.d.ts.map +1 -1
  88. package/dist/ranger/writer.d.ts +22 -19
  89. package/dist/ranger/writer.d.ts.map +1 -1
  90. package/dist/testutil/client.d.ts +4 -0
  91. package/dist/testutil/client.d.ts.map +1 -0
  92. package/dist/user/client.d.ts +59 -6
  93. package/dist/user/client.d.ts.map +1 -1
  94. package/dist/user/payload.d.ts +4 -6
  95. package/dist/user/payload.d.ts.map +1 -1
  96. package/dist/user/retriever.d.ts +2 -2
  97. package/dist/user/retriever.d.ts.map +1 -1
  98. package/dist/util/decodeJSONString.d.ts +2 -2
  99. package/dist/util/decodeJSONString.d.ts.map +1 -1
  100. package/dist/util/parseWithoutKeyConversion.d.ts +2 -2
  101. package/dist/util/parseWithoutKeyConversion.d.ts.map +1 -1
  102. package/dist/util/retrieve.d.ts +1 -1
  103. package/dist/util/retrieve.d.ts.map +1 -1
  104. package/dist/util/zod.d.ts +1 -1
  105. package/dist/util/zod.d.ts.map +1 -1
  106. package/dist/workspace/client.d.ts +17 -6
  107. package/dist/workspace/client.d.ts.map +1 -1
  108. package/dist/workspace/lineplot/client.d.ts +2 -2
  109. package/dist/workspace/lineplot/client.d.ts.map +1 -1
  110. package/dist/workspace/lineplot/payload.d.ts +8 -9
  111. package/dist/workspace/lineplot/payload.d.ts.map +1 -1
  112. package/dist/workspace/log/client.d.ts +2 -2
  113. package/dist/workspace/log/client.d.ts.map +1 -1
  114. package/dist/workspace/log/payload.d.ts +8 -9
  115. package/dist/workspace/log/payload.d.ts.map +1 -1
  116. package/dist/workspace/payload.d.ts +10 -11
  117. package/dist/workspace/payload.d.ts.map +1 -1
  118. package/dist/workspace/schematic/client.d.ts +2 -2
  119. package/dist/workspace/schematic/client.d.ts.map +1 -1
  120. package/dist/workspace/schematic/payload.d.ts +10 -11
  121. package/dist/workspace/schematic/payload.d.ts.map +1 -1
  122. package/dist/workspace/table/client.d.ts +2 -2
  123. package/dist/workspace/table/client.d.ts.map +1 -1
  124. package/dist/workspace/table/payload.d.ts +10 -11
  125. package/dist/workspace/table/payload.d.ts.map +1 -1
  126. package/examples/node/package-lock.json +47 -39
  127. package/examples/node/package.json +2 -1
  128. package/examples/node/streamWrite.js +5 -11
  129. package/package.json +14 -13
  130. package/src/access/payload.ts +1 -1
  131. package/src/access/policy/client.ts +87 -32
  132. package/src/access/policy/external.ts +0 -1
  133. package/src/access/policy/payload.ts +4 -4
  134. package/src/access/policy/policy.spec.ts +86 -83
  135. package/src/auth/auth.spec.ts +29 -18
  136. package/src/auth/auth.ts +1 -1
  137. package/src/channel/batchRetriever.spec.ts +4 -9
  138. package/src/channel/channel.spec.ts +24 -6
  139. package/src/channel/client.ts +31 -46
  140. package/src/channel/payload.ts +13 -14
  141. package/src/channel/retriever.ts +26 -41
  142. package/src/channel/writer.ts +3 -3
  143. package/src/client.ts +4 -4
  144. package/src/connection/checker.ts +1 -1
  145. package/src/connection/connection.spec.ts +31 -23
  146. package/src/control/client.ts +2 -2
  147. package/src/control/state.spec.ts +3 -3
  148. package/src/control/state.ts +1 -1
  149. package/src/errors.spec.ts +9 -5
  150. package/src/errors.ts +28 -15
  151. package/src/framer/adapter.spec.ts +118 -9
  152. package/src/framer/adapter.ts +24 -11
  153. package/src/framer/client.spec.ts +125 -2
  154. package/src/framer/client.ts +41 -47
  155. package/src/framer/codec.ts +1 -1
  156. package/src/framer/deleter.spec.ts +2 -2
  157. package/src/framer/deleter.ts +1 -1
  158. package/src/framer/frame.ts +1 -4
  159. package/src/framer/iterator.spec.ts +8 -8
  160. package/src/framer/iterator.ts +1 -1
  161. package/src/framer/streamProxy.ts +1 -1
  162. package/src/framer/streamer.spec.ts +185 -36
  163. package/src/framer/streamer.ts +28 -36
  164. package/src/framer/writer.spec.ts +6 -6
  165. package/src/framer/writer.ts +97 -111
  166. package/src/hardware/device/client.ts +45 -131
  167. package/src/hardware/device/device.spec.ts +163 -52
  168. package/src/hardware/device/payload.ts +10 -21
  169. package/src/hardware/rack/client.ts +87 -105
  170. package/src/hardware/rack/payload.ts +4 -13
  171. package/src/hardware/rack/rack.spec.ts +28 -35
  172. package/src/hardware/task/client.ts +335 -291
  173. package/src/hardware/task/payload.ts +86 -62
  174. package/src/hardware/task/task.spec.ts +208 -32
  175. package/src/index.ts +2 -1
  176. package/src/label/client.ts +100 -95
  177. package/src/label/external.ts +0 -2
  178. package/src/label/label.spec.ts +8 -6
  179. package/src/label/payload.ts +3 -4
  180. package/src/ontology/client.ts +41 -324
  181. package/src/ontology/group/group.spec.ts +2 -2
  182. package/src/ontology/group/group.ts +4 -5
  183. package/src/ontology/group/payload.ts +2 -25
  184. package/src/ontology/group/writer.ts +1 -1
  185. package/src/ontology/ontology.spec.ts +355 -41
  186. package/src/ontology/payload.ts +74 -112
  187. package/src/ontology/writer.ts +8 -17
  188. package/src/ranger/alias.ts +19 -37
  189. package/src/ranger/client.ts +118 -150
  190. package/src/ranger/external.ts +9 -1
  191. package/src/ranger/kv.ts +6 -27
  192. package/src/ranger/payload.ts +21 -37
  193. package/src/ranger/ranger.spec.ts +37 -56
  194. package/src/ranger/writer.ts +1 -1
  195. package/src/{signals/index.ts → testutil/client.ts} +11 -1
  196. package/src/user/client.ts +122 -47
  197. package/src/user/payload.ts +2 -5
  198. package/src/user/retriever.ts +1 -1
  199. package/src/user/user.spec.ts +31 -31
  200. package/src/user/writer.ts +1 -1
  201. package/src/util/decodeJSONString.ts +3 -3
  202. package/src/util/parseWithoutKeyConversion.ts +2 -2
  203. package/src/util/retrieve.ts +1 -1
  204. package/src/util/zod.ts +1 -1
  205. package/src/workspace/client.ts +20 -36
  206. package/src/workspace/lineplot/client.ts +5 -7
  207. package/src/workspace/lineplot/lineplot.spec.ts +2 -2
  208. package/src/workspace/lineplot/payload.ts +4 -7
  209. package/src/workspace/log/client.ts +5 -7
  210. package/src/workspace/log/log.spec.ts +2 -2
  211. package/src/workspace/log/payload.ts +4 -7
  212. package/src/workspace/payload.ts +4 -7
  213. package/src/workspace/schematic/client.ts +5 -7
  214. package/src/workspace/schematic/payload.ts +4 -7
  215. package/src/workspace/schematic/schematic.spec.ts +2 -2
  216. package/src/workspace/table/client.ts +5 -7
  217. package/src/workspace/table/payload.ts +4 -7
  218. package/src/workspace/table/table.spec.ts +2 -2
  219. package/src/workspace/workspace.spec.ts +2 -2
  220. package/dist/access/policy/ontology.d.ts +0 -5
  221. package/dist/access/policy/ontology.d.ts.map +0 -1
  222. package/dist/access/policy/retriever.d.ts +0 -40
  223. package/dist/access/policy/retriever.d.ts.map +0 -1
  224. package/dist/access/policy/writer.d.ts +0 -9
  225. package/dist/access/policy/writer.d.ts.map +0 -1
  226. package/dist/label/retriever.d.ts +0 -14
  227. package/dist/label/retriever.d.ts.map +0 -1
  228. package/dist/label/writer.d.ts +0 -54
  229. package/dist/label/writer.d.ts.map +0 -1
  230. package/dist/setupspecs.d.ts +0 -5
  231. package/dist/setupspecs.d.ts.map +0 -1
  232. package/dist/signals/external.d.ts +0 -2
  233. package/dist/signals/external.d.ts.map +0 -1
  234. package/dist/signals/index.d.ts +0 -2
  235. package/dist/signals/index.d.ts.map +0 -1
  236. package/dist/signals/observable.d.ts +0 -12
  237. package/dist/signals/observable.d.ts.map +0 -1
  238. package/src/access/policy/ontology.ts +0 -17
  239. package/src/access/policy/retriever.ts +0 -44
  240. package/src/access/policy/writer.ts +0 -65
  241. package/src/label/retriever.ts +0 -63
  242. package/src/label/writer.ts +0 -95
  243. package/src/setupspecs.ts +0 -27
  244. package/src/signals/external.ts +0 -10
  245. package/src/signals/observable.ts +0 -42
@@ -9,7 +9,6 @@
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { array } from "@synnaxlabs/x";
12
- import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
13
12
  import {
14
13
  type CrudeDensity,
15
14
  type CrudeTimeStamp,
@@ -18,17 +17,16 @@ import {
18
17
  type TimeRange,
19
18
  type TypedArray,
20
19
  } from "@synnaxlabs/x/telem";
21
- import { z } from "zod/v4";
20
+ import { z } from "zod";
22
21
 
23
22
  import {
24
- channelZ,
25
23
  type Key,
26
24
  type KeyOrName,
27
25
  type Name,
28
26
  type New,
29
- ONTOLOGY_TYPE,
30
27
  type Params,
31
28
  type Payload,
29
+ payloadZ,
32
30
  } from "@/channel/payload";
33
31
  import {
34
32
  analyzeParams,
@@ -37,11 +35,12 @@ import {
37
35
  DebouncedBatchRetriever,
38
36
  type RetrieveOptions,
39
37
  type Retriever,
38
+ type RetrieveRequest,
40
39
  } from "@/channel/retriever";
41
40
  import { type Writer } from "@/channel/writer";
42
41
  import { ValidationError } from "@/errors";
43
42
  import { type framer } from "@/framer";
44
- import { ontology } from "@/ontology";
43
+ import { type ontology } from "@/ontology";
45
44
  import { group } from "@/ontology/group";
46
45
  import { checkForMultipleOrNoResults } from "@/util/retrieve";
47
46
 
@@ -49,6 +48,9 @@ interface CreateOptions {
49
48
  retrieveIfNameExists?: boolean;
50
49
  }
51
50
 
51
+ export const SET_CHANNEL_NAME = "sy_channel_set";
52
+ export const DELETE_CHANNEL_NAME = "sy_channel_delete";
53
+
52
54
  /**
53
55
  * Represents a Channel in a Synnax database. Typically, channels should not be
54
56
  * instantiated directly, but instead created via the `.channels.create` or retrieved
@@ -153,7 +155,7 @@ export class Channel {
153
155
  * network transportation, but also provided to you as a convenience.
154
156
  */
155
157
  get payload(): Payload {
156
- return channelZ.parse({
158
+ return payloadZ.parse({
157
159
  key: this.key,
158
160
  name: this.name,
159
161
  dataType: this.dataType.valueOf(),
@@ -200,7 +202,7 @@ export class Channel {
200
202
  }
201
203
  }
202
204
 
203
- export const CALCULATION_STATE_CHANNEL_NAME = "sy_calculation_state";
205
+ export const CALCULATION_STATUS_CHANNEL_NAME = "sy_calculation_status";
204
206
 
205
207
  const RETRIEVE_GROUP_ENDPOINT = "/channel/retrieve-group";
206
208
 
@@ -213,8 +215,8 @@ const retrieveGroupResZ = z.object({ group: group.groupZ });
213
215
  * cluster. This class should not be instantiated directly, and instead should be used
214
216
  * through the `channels` property of an {@link Synnax} client.
215
217
  */
216
- export class Client implements AsyncTermSearcher<string, Key, Channel> {
217
- readonly type = ONTOLOGY_TYPE;
218
+ export class Client {
219
+ readonly type = "channel";
218
220
  private readonly frameClient: framer.Client;
219
221
  private readonly client: UnaryClient;
220
222
  readonly retriever: Retriever;
@@ -315,7 +317,7 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
315
317
  /**
316
318
  * Retrieves a channel from the database using the given key or name.
317
319
  *
318
- * @param channel - The key or name of the channel to retrieve.
320
+ * @param params - The key or name of the channel to retrieve.
319
321
  * @param options - Optional parameters to control the retrieval process.
320
322
  * @param options.dataTypes - Limits the query to only channels with the specified data
321
323
  * type.
@@ -334,13 +336,13 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
334
336
  * const channel = await client.channels.retrieve(1);
335
337
  * ```
336
338
  */
337
- async retrieve(channel: KeyOrName, options?: RetrieveOptions): Promise<Channel>;
339
+ async retrieve(params: KeyOrName, options?: RetrieveOptions): Promise<Channel>;
338
340
 
339
341
  /**
340
342
  * Retrieves multiple channels from the database using the provided keys or the
341
343
  * provided names.
342
344
  *
343
- * @param channels - The keys or the names of the channels to retrieve. Note that
345
+ * @param params - The keys or the names of the channels to retrieve. Note that
344
346
  * this method does not support mixing keys and names in the same call.
345
347
  * @param options - Optional parameters to control the retrieval process.
346
348
  * @param options.dataTypes - Limits the query to only channels with the specified data
@@ -348,7 +350,9 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
348
350
  * @param options.notDataTypes - Limits the query to only channels without the specified
349
351
  *
350
352
  */
351
- async retrieve(channels: Params, options?: RetrieveOptions): Promise<Channel[]>;
353
+ async retrieve(params: Params, options?: RetrieveOptions): Promise<Channel[]>;
354
+
355
+ async retrieve(params: RetrieveRequest): Promise<Channel[]>;
352
356
 
353
357
  /**
354
358
  * Retrieves a channel from the database using the given parameters.
@@ -358,25 +362,24 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
358
362
  * @raises {QueryError} If the channel does not exist or if multiple results are returned.
359
363
  */
360
364
  async retrieve(
361
- channels: Params,
365
+ params: Params | RetrieveRequest,
362
366
  options?: RetrieveOptions,
363
367
  ): Promise<Channel | Channel[]> {
364
- const isSingle = !Array.isArray(channels);
365
- const res = this.sugar(await this.retriever.retrieve(channels, options));
366
- checkForMultipleOrNoResults("channel", channels, res, isSingle);
367
- return isSingle ? res[0] : res;
368
- }
368
+ if (typeof params === "object" && !Array.isArray(params))
369
+ return this.sugar(await this.retriever.retrieve(params));
369
370
 
370
- async search(term: string, options?: RetrieveOptions): Promise<Channel[]> {
371
- return this.sugar(await this.retriever.search(term, options));
371
+ const isSingle = !Array.isArray(params);
372
+ const res = this.sugar(await this.retriever.retrieve(params, options));
373
+ checkForMultipleOrNoResults<Params, Channel>("channel", params, res, isSingle);
374
+ return isSingle ? res[0] : res;
372
375
  }
373
376
 
374
377
  /***
375
378
  * Deletes channels from the database using the given keys or names.
376
- * @param channels - The keys or names of the channels to delete.
379
+ * @param params - The keys or names of the channels to delete.
377
380
  */
378
- async delete(channels: Params): Promise<void> {
379
- const { normalized, variant } = analyzeParams(channels);
381
+ async delete(params: Params): Promise<void> {
382
+ const { normalized, variant } = analyzeParams(params);
380
383
  if (variant === "keys")
381
384
  return await this.writer.delete({ keys: normalized as Key[] });
382
385
  return await this.writer.delete({ names: normalized as string[] });
@@ -388,26 +391,6 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
388
391
  return await this.writer.rename(array.toArray(keys), array.toArray(names));
389
392
  }
390
393
 
391
- newSearcherWithOptions(
392
- options: RetrieveOptions,
393
- ): AsyncTermSearcher<string, Key, Channel> {
394
- return {
395
- type: this.type,
396
- search: async (term: string) => await this.search(term, options),
397
- retrieve: async (keys: Key[]) => await this.retrieve(keys, options),
398
- page: async (offset: number, limit: number) =>
399
- await this.page(offset, limit, options),
400
- };
401
- }
402
-
403
- async page(
404
- offset: number,
405
- limit: number,
406
- options?: Omit<RetrieveOptions, "limit" | "offset">,
407
- ): Promise<Channel[]> {
408
- return this.sugar(await this.retriever.page(offset, limit, options));
409
- }
410
-
411
394
  createDebouncedBatchRetriever(deb: number = 10): Retriever {
412
395
  return new CacheRetriever(
413
396
  new DebouncedBatchRetriever(new ClusterRetriever(this.client), deb),
@@ -455,5 +438,7 @@ export const resolveCalculatedIndex = async (
455
438
  return null;
456
439
  };
457
440
 
458
- export const ontologyID = (key: Key): ontology.ID =>
459
- new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
441
+ export const ontologyID = (key: Key): ontology.ID => ({
442
+ type: "channel",
443
+ key: key.toString(),
444
+ });
@@ -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 CrudeDataType, DataType, status } from "@synnaxlabs/x";
11
- import { z } from "zod/v4";
10
+ import { type CrudeDataType, DataType, status, zod } from "@synnaxlabs/x";
11
+ import { z } from "zod";
12
12
 
13
13
  import { nullableArrayZ } from "@/util/zod";
14
14
 
@@ -21,9 +21,8 @@ export type Names = Name[];
21
21
  export type KeyOrName = Key | Name;
22
22
  export type KeysOrNames = Keys | Names;
23
23
  export type PrimitiveParams = Key | Name | Keys | Names;
24
- export type Params = Key | Name | Keys | Names | Payload | Payload[];
25
24
 
26
- export const channelZ = z.object({
25
+ export const payloadZ = z.object({
27
26
  name: nameZ,
28
27
  key: keyZ,
29
28
  dataType: DataType.z,
@@ -36,9 +35,9 @@ export const channelZ = z.object({
36
35
  expression: z.string().default(""),
37
36
  requires: nullableArrayZ(keyZ),
38
37
  });
39
- export interface Payload extends z.infer<typeof channelZ> {}
38
+ export interface Payload extends z.infer<typeof payloadZ> {}
40
39
 
41
- export const newZ = channelZ.extend({
40
+ export const newZ = payloadZ.extend({
42
41
  key: keyZ.optional(),
43
42
  leaseholder: z.number().optional(),
44
43
  index: keyZ.optional(),
@@ -53,12 +52,12 @@ export interface New extends Omit<z.input<typeof newZ>, "dataType"> {
53
52
  dataType: CrudeDataType;
54
53
  }
55
54
 
56
- export const ONTOLOGY_TYPE = "channel";
57
- export type OntologyType = typeof ONTOLOGY_TYPE;
55
+ export const calculationStatusZ = status.statusZ();
56
+ export type CalculationStatus = z.infer<typeof calculationStatusZ>;
58
57
 
59
- export const calculationStateZ = z.object({
60
- key: keyZ,
61
- variant: status.variantZ,
62
- message: z.string(),
63
- });
64
- export interface CalculationState extends z.infer<typeof calculationStateZ> {}
58
+ export const paramsZ = z.union([
59
+ zod.toArray(keyZ),
60
+ zod.toArray(nameZ),
61
+ zod.toArray(payloadZ).transform((p) => p.map((c) => c.key)),
62
+ ]);
63
+ export type Params = Key | Name | Keys | Names | Payload | Payload[];
@@ -11,10 +11,9 @@ import { type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { debounce } from "@synnaxlabs/x/debounce";
12
12
  import { DataType } from "@synnaxlabs/x/telem";
13
13
  import { Mutex } from "async-mutex";
14
- import { z } from "zod/v4";
14
+ import { z } from "zod";
15
15
 
16
16
  import {
17
- channelZ,
18
17
  type Key,
19
18
  type KeyOrName,
20
19
  type Keys,
@@ -24,6 +23,7 @@ import {
24
23
  type Names,
25
24
  type Params,
26
25
  type Payload,
26
+ payloadZ,
27
27
  } from "@/channel/payload";
28
28
  import { QueryError } from "@/errors";
29
29
  import {
@@ -36,7 +36,7 @@ const reqZ = z.object({
36
36
  leaseholder: z.number().optional(),
37
37
  keys: keyZ.array().optional(),
38
38
  names: z.string().array().optional(),
39
- search: z.string().optional(),
39
+ searchTerm: z.string().optional(),
40
40
  rangeKey: z.string().optional(),
41
41
  limit: z.number().optional(),
42
42
  offset: z.number().optional(),
@@ -45,13 +45,15 @@ const reqZ = z.object({
45
45
  virtual: z.boolean().optional(),
46
46
  isIndex: z.boolean().optional(),
47
47
  internal: z.boolean().optional(),
48
+ calculated: z.boolean().optional(),
48
49
  });
49
- interface Request extends z.input<typeof reqZ> {}
50
+ export interface RetrieveRequest extends z.input<typeof reqZ> {}
50
51
 
51
- export interface RetrieveOptions extends Omit<Request, "keys" | "names" | "search"> {}
52
+ export interface RetrieveOptions
53
+ extends Omit<RetrieveRequest, "keys" | "names" | "search"> {}
52
54
  export interface PageOptions extends Omit<RetrieveOptions, "offset" | "limit"> {}
53
55
 
54
- const resZ = z.object({ channels: nullableArrayZ(channelZ) });
56
+ const resZ = z.object({ channels: nullableArrayZ(payloadZ) });
55
57
 
56
58
  export const analyzeParams = (
57
59
  channels: Params,
@@ -66,9 +68,8 @@ export const analyzeParams = (
66
68
  };
67
69
 
68
70
  export interface Retriever {
69
- retrieve: (channels: Params, opts?: RetrieveOptions) => Promise<Payload[]>;
70
- search: (term: string, opts?: RetrieveOptions) => Promise<Payload[]>;
71
- page: (offset: number, limit: number, opts?: PageOptions) => Promise<Payload[]>;
71
+ retrieve: ((channels: Params, opts?: RetrieveOptions) => Promise<Payload[]>) &
72
+ ((request: RetrieveRequest) => Promise<Payload[]>);
72
73
  }
73
74
 
74
75
  export class ClusterRetriever implements Retriever {
@@ -79,11 +80,12 @@ export class ClusterRetriever implements Retriever {
79
80
  this.client = client;
80
81
  }
81
82
 
82
- async search(term: string, options?: RetrieveOptions): Promise<Payload[]> {
83
- return await this.execute({ search: term, ...options });
84
- }
85
-
86
- async retrieve(channels: Params, options?: RetrieveOptions): Promise<Payload[]> {
83
+ async retrieve(
84
+ channels: Params | RetrieveRequest,
85
+ options?: RetrieveOptions,
86
+ ): Promise<Payload[]> {
87
+ if (!Array.isArray(channels) && typeof channels === "object")
88
+ return await this.execute(channels);
87
89
  const res = analyzeParams(channels);
88
90
  const { variant } = res;
89
91
  let { normalized } = res;
@@ -93,11 +95,7 @@ export class ClusterRetriever implements Retriever {
93
95
  return await this.execute({ [variant]: normalized, ...options });
94
96
  }
95
97
 
96
- async page(offset: number, limit: number, options?: PageOptions): Promise<Payload[]> {
97
- return await this.execute({ offset, limit, ...options });
98
- }
99
-
100
- private async execute(request: Request): Promise<Payload[]> {
98
+ private async execute(request: RetrieveRequest): Promise<Payload[]> {
101
99
  const [res, err] = await this.client.send(
102
100
  ClusterRetriever.ENDPOINT,
103
101
  request,
@@ -120,15 +118,12 @@ export class CacheRetriever implements Retriever {
120
118
  this.wrapped = wrapped;
121
119
  }
122
120
 
123
- async search(term: string, options?: RetrieveOptions): Promise<Payload[]> {
124
- return await this.wrapped.search(term, options);
125
- }
126
-
127
- async page(offset: number, limit: number, options?: PageOptions): Promise<Payload[]> {
128
- return await this.wrapped.page(offset, limit, options);
129
- }
130
-
131
- async retrieve(channels: Params, options?: RetrieveOptions): Promise<Payload[]> {
121
+ async retrieve(
122
+ channels: Params | RetrieveRequest,
123
+ options?: RetrieveOptions,
124
+ ): Promise<Payload[]> {
125
+ if (!Array.isArray(channels) && typeof channels === "object")
126
+ return await this.wrapped.retrieve(channels);
132
127
  const { normalized } = analyzeParams(channels);
133
128
  const results: Payload[] = [];
134
129
  const toFetch: KeysOrNames = [];
@@ -226,19 +221,9 @@ export class DebouncedBatchRetriever implements Retriever {
226
221
  }, deb);
227
222
  }
228
223
 
229
- async search(term: string, options?: RetrieveOptions): Promise<Payload[]> {
230
- return await this.wrapped.search(term, options);
231
- }
232
-
233
- async page(
234
- offset: number,
235
- limit: number,
236
- options?: RetrieveOptions,
237
- ): Promise<Payload[]> {
238
- return await this.wrapped.page(offset, limit, options);
239
- }
240
-
241
- async retrieve(channels: Params): Promise<Payload[]> {
224
+ async retrieve(channels: Params | RetrieveRequest): Promise<Payload[]> {
225
+ if (!Array.isArray(channels) && typeof channels === "object")
226
+ return await this.wrapped.retrieve(channels);
242
227
  const { normalized, variant } = analyzeParams(channels);
243
228
  // Bypass on name fetches for now.
244
229
  if (variant === "names") return await this.wrapped.retrieve(normalized);
@@ -9,21 +9,21 @@
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { type DataType } from "@synnaxlabs/x";
12
- import { z } from "zod/v4";
12
+ import { z } from "zod";
13
13
 
14
14
  import {
15
- channelZ,
16
15
  type Key,
17
16
  keyZ,
18
17
  nameZ,
19
18
  type New,
20
19
  newZ,
21
20
  type Payload,
21
+ payloadZ,
22
22
  } from "@/channel/payload";
23
23
  import { type CacheRetriever } from "@/channel/retriever";
24
24
 
25
25
  const createReqZ = z.object({ channels: newZ.array() });
26
- const createResZ = z.object({ channels: channelZ.array() });
26
+ const createResZ = z.object({ channels: payloadZ.array() });
27
27
 
28
28
  const deleteReqZ = z.object({
29
29
  keys: keyZ.array().optional(),
package/src/client.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  import { breaker } from "@synnaxlabs/x";
11
11
  import { TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
12
12
  import { URL } from "@synnaxlabs/x/url";
13
- import { z } from "zod/v4";
13
+ import { z } from "zod";
14
14
 
15
15
  import { access } from "@/access";
16
16
  import { auth } from "@/auth";
@@ -132,7 +132,7 @@ export default class Synnax extends framer.Client {
132
132
  this.control = new control.Client(this);
133
133
  this.ontology = new ontology.Client(transport.unary, this);
134
134
  const rangeWriter = new ranger.Writer(this.transport.unary);
135
- this.labels = new label.Client(this.transport.unary, this, this.ontology);
135
+ this.labels = new label.Client(this.transport.unary);
136
136
  this.ranges = new ranger.Client(
137
137
  this,
138
138
  rangeWriter,
@@ -144,14 +144,14 @@ export default class Synnax extends framer.Client {
144
144
  this.access = new access.Client(this.transport.unary);
145
145
  this.user = new user.Client(this.transport.unary);
146
146
  this.workspaces = new workspace.Client(this.transport.unary);
147
- const devices = new device.Client(this.transport.unary, this);
147
+ const devices = new device.Client(this.transport.unary);
148
148
  const tasks = new task.Client(
149
149
  this.transport.unary,
150
150
  this,
151
151
  this.ontology,
152
152
  this.ranges,
153
153
  );
154
- const racks = new rack.Client(this.transport.unary, tasks, this);
154
+ const racks = new rack.Client(this.transport.unary, tasks);
155
155
  this.hardware = new hardware.Client(tasks, racks, devices);
156
156
  }
157
157
 
@@ -10,7 +10,7 @@
10
10
  import type { UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { migrate } from "@synnaxlabs/x";
12
12
  import { TimeSpan } from "@synnaxlabs/x/telem";
13
- import { z } from "zod/v4";
13
+ import { z } from "zod";
14
14
 
15
15
  export const statusZ = z.enum(["disconnected", "connecting", "connected", "failed"]);
16
16
  export type Status = z.infer<typeof statusZ>;
@@ -9,20 +9,22 @@
9
9
 
10
10
  import { URL } from "@synnaxlabs/x/url";
11
11
  import { describe, expect, it } from "vitest";
12
- import { z } from "zod/v4";
12
+ import { z } from "zod";
13
13
 
14
14
  import { auth } from "@/auth";
15
15
  import { connection } from "@/connection";
16
- import { HOST, PORT } from "@/setupspecs";
16
+ import { TEST_CLIENT_PROPS } from "@/testutil/client";
17
17
  import { Transport } from "@/transport";
18
18
 
19
19
  describe("connectivity", () => {
20
20
  it("should connect to the server", async () => {
21
- const transport = new Transport(new URL({ host: HOST, port: PORT }));
22
- const client = new auth.Client(transport.unary, {
23
- username: "synnax",
24
- password: "seldon",
25
- });
21
+ const transport = new Transport(
22
+ new URL({
23
+ host: TEST_CLIENT_PROPS.host,
24
+ port: Number(TEST_CLIENT_PROPS.port),
25
+ }),
26
+ );
27
+ const client = new auth.Client(transport.unary, TEST_CLIENT_PROPS);
26
28
  transport.use(client.middleware());
27
29
  const connectivity = new connection.Checker(
28
30
  transport.unary,
@@ -31,15 +33,17 @@ describe("connectivity", () => {
31
33
  );
32
34
  const state = await connectivity.check();
33
35
  expect(state.status).toEqual("connected");
34
- expect(z.string().uuid().safeParse(state.clusterKey).success).toBe(true);
36
+ expect(z.uuid().safeParse(state.clusterKey).success).toBe(true);
35
37
  });
36
38
  describe("version compatibility", () => {
37
39
  it("should pull the server and client versions", async () => {
38
- const transport = new Transport(new URL({ host: HOST, port: PORT }));
39
- const client = new auth.Client(transport.unary, {
40
- username: "synnax",
41
- password: "seldon",
42
- });
40
+ const transport = new Transport(
41
+ new URL({
42
+ host: TEST_CLIENT_PROPS.host,
43
+ port: Number(TEST_CLIENT_PROPS.port),
44
+ }),
45
+ );
46
+ const client = new auth.Client(transport.unary, TEST_CLIENT_PROPS);
43
47
  transport.use(client.middleware());
44
48
  const connectivity = new connection.Checker(
45
49
  transport.unary,
@@ -51,11 +55,13 @@ describe("connectivity", () => {
51
55
  expect(state.clientVersion).toBe(__VERSION__);
52
56
  });
53
57
  it("should adjust state if the server is too old", async () => {
54
- const transport = new Transport(new URL({ host: HOST, port: PORT }));
55
- const client = new auth.Client(transport.unary, {
56
- username: "synnax",
57
- password: "seldon",
58
- });
58
+ const transport = new Transport(
59
+ new URL({
60
+ host: TEST_CLIENT_PROPS.host,
61
+ port: Number(TEST_CLIENT_PROPS.port),
62
+ }),
63
+ );
64
+ const client = new auth.Client(transport.unary, TEST_CLIENT_PROPS);
59
65
  transport.use(client.middleware());
60
66
  const connectivity = new connection.Checker(
61
67
  transport.unary,
@@ -67,11 +73,13 @@ describe("connectivity", () => {
67
73
  expect(state.clientVersion).toBe("50000.0.0");
68
74
  });
69
75
  it("should adjust state if the server is too new", async () => {
70
- const transport = new Transport(new URL({ host: HOST, port: PORT }));
71
- const client = new auth.Client(transport.unary, {
72
- username: "synnax",
73
- password: "seldon",
74
- });
76
+ const transport = new Transport(
77
+ new URL({
78
+ host: TEST_CLIENT_PROPS.host,
79
+ port: Number(TEST_CLIENT_PROPS.port),
80
+ }),
81
+ );
82
+ const client = new auth.Client(transport.unary, TEST_CLIENT_PROPS);
75
83
  transport.use(client.middleware());
76
84
  const connectivity = new connection.Checker(transport.unary, undefined, "0.0.0");
77
85
  const state = await connectivity.check();
@@ -10,7 +10,7 @@
10
10
  import { StateTracker } from "@/control/state";
11
11
  import { framer } from "@/framer";
12
12
 
13
- const CONTROL_STATE_KEY = "sy_node_1_control";
13
+ export const CONTROL_STATE_CHANNEL_NAME = "sy_node_1_control";
14
14
 
15
15
  export class Client {
16
16
  private readonly framer: framer.Client;
@@ -22,7 +22,7 @@ export class Client {
22
22
  async openStateTracker(): Promise<StateTracker> {
23
23
  const stream = await framer.HardenedStreamer.open(
24
24
  async (p) => await this.framer.openStreamer(p),
25
- CONTROL_STATE_KEY,
25
+ CONTROL_STATE_CHANNEL_NAME,
26
26
  );
27
27
  return new StateTracker(stream);
28
28
  }
@@ -9,14 +9,14 @@
9
9
 
10
10
  import { describe, expect, it } from "vitest";
11
11
 
12
- import { newClient } from "@/setupspecs";
12
+ import { newTestClient } from "@/testutil/client";
13
13
 
14
- const client = newClient();
14
+ const client = newTestClient();
15
15
 
16
16
  describe("state", () => {
17
17
  it("should receive the initial control state from the cluster", async () => {
18
18
  const s = await client.control.openStateTracker();
19
- await expect.poll(() => s.states.size > 0).toBeTruthy();
19
+ await expect.poll(() => s.states.size > 0).toBe(true);
20
20
  await s.close();
21
21
  });
22
22
  });
@@ -10,7 +10,7 @@
10
10
  import { control } from "@synnaxlabs/x";
11
11
  import { binary } from "@synnaxlabs/x/binary";
12
12
  import { type observe } from "@synnaxlabs/x/observe";
13
- import { z } from "zod/v4";
13
+ import { z } from "zod";
14
14
 
15
15
  import { type channel } from "@/channel";
16
16
  import { keyZ } from "@/channel/payload";
@@ -14,23 +14,27 @@ import {
14
14
  AuthError,
15
15
  ContiguityError,
16
16
  ControlError,
17
- FieldError,
18
17
  InvalidTokenError,
19
18
  MultipleFoundError,
20
19
  NotFoundError,
20
+ PathError,
21
21
  QueryError,
22
22
  RouteError,
23
23
  UnauthorizedError,
24
24
  UnexpectedError,
25
25
  ValidationError,
26
26
  } from "@/errors";
27
- import { newClient } from "@/setupspecs";
27
+ import { newTestClient } from "@/testutil/client";
28
28
 
29
29
  describe("error", () => {
30
30
  describe("type matching", () => {
31
31
  const ERRORS: [string, Error, errors.Matchable][] = [
32
32
  [ValidationError.TYPE, new ValidationError(), ValidationError],
33
- [FieldError.TYPE, new FieldError("field", "message"), FieldError],
33
+ [
34
+ PathError.TYPE,
35
+ new PathError("field", new ValidationError("message")),
36
+ PathError,
37
+ ],
34
38
  [AuthError.TYPE, new AuthError(), AuthError],
35
39
  [InvalidTokenError.TYPE, new InvalidTokenError(), InvalidTokenError],
36
40
  [UnexpectedError.TYPE, new UnexpectedError("message"), UnexpectedError],
@@ -44,13 +48,13 @@ describe("error", () => {
44
48
  ];
45
49
  ERRORS.forEach(([typeName, error, type]) =>
46
50
  test(`matches ${typeName}`, () => {
47
- expect(type.matches(error)).toBeTruthy();
51
+ expect(type.matches(error)).toBe(true);
48
52
  }),
49
53
  );
50
54
  });
51
55
  });
52
56
 
53
- const client = newClient();
57
+ const client = newTestClient();
54
58
 
55
59
  test("client", async () => {
56
60
  expect.assertions(2);