@synnaxlabs/client 0.16.3 → 0.17.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 (71) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/dist/auth/auth.d.ts +2 -2
  3. package/dist/client.cjs +11 -11
  4. package/dist/client.cjs.map +1 -1
  5. package/dist/client.d.ts +14 -4
  6. package/dist/client.js +5442 -5437
  7. package/dist/client.js.map +1 -1
  8. package/dist/framer/frame.d.ts +280 -24
  9. package/dist/framer/writer.d.ts +203 -15
  10. package/dist/hardware/rack/client.d.ts +1 -1
  11. package/dist/hardware/task/payload.d.ts +5 -5
  12. package/dist/ontology/retriever.d.ts +1 -1
  13. package/dist/ranger/active.d.ts +1 -1
  14. package/dist/ranger/payload.d.ts +308 -20
  15. package/dist/workspace/client.d.ts +2 -2
  16. package/dist/workspace/lineplot/client.d.ts +2 -2
  17. package/dist/workspace/lineplot/payload.d.ts +3 -16
  18. package/dist/workspace/lineplot/retriever.d.ts +0 -1
  19. package/dist/workspace/lineplot/writer.d.ts +9 -14
  20. package/dist/workspace/payload.d.ts +3 -3
  21. package/dist/workspace/pid/client.d.ts +2 -2
  22. package/dist/workspace/pid/payload.d.ts +3 -3
  23. package/dist/workspace/pid/retriever.d.ts +0 -1
  24. package/dist/workspace/pid/writer.d.ts +12 -18
  25. package/dist/workspace/writer.d.ts +14 -6
  26. package/examples/node/basicReadWriter.js +66 -0
  27. package/examples/node/package-lock.json +4961 -0
  28. package/examples/{package.json → node/package.json} +5 -5
  29. package/package.json +5 -5
  30. package/src/auth/auth.ts +5 -4
  31. package/src/channel/client.ts +0 -1
  32. package/src/channel/creator.ts +1 -0
  33. package/src/channel/retriever.ts +2 -2
  34. package/src/client.ts +2 -2
  35. package/src/connection/checker.ts +6 -2
  36. package/src/framer/client.ts +7 -3
  37. package/src/framer/frame.ts +4 -4
  38. package/src/hardware/device/retriever.ts +3 -3
  39. package/src/hardware/device/writer.ts +3 -1
  40. package/src/hardware/rack/client.ts +3 -4
  41. package/src/hardware/rack/retriever.ts +3 -0
  42. package/src/hardware/rack/writer.ts +2 -0
  43. package/src/hardware/task/payload.ts +5 -4
  44. package/src/hardware/task/retriever.ts +10 -7
  45. package/src/hardware/task/writer.ts +3 -1
  46. package/src/label/retriever.ts +1 -0
  47. package/src/label/writer.ts +4 -0
  48. package/src/ontology/group/writer.ts +18 -5
  49. package/src/ontology/retriever.ts +9 -9
  50. package/src/ontology/writer.ts +25 -11
  51. package/src/ranger/active.ts +26 -8
  52. package/src/ranger/alias.ts +9 -13
  53. package/src/ranger/client.ts +0 -1
  54. package/src/ranger/kv.ts +4 -1
  55. package/src/ranger/retriever.ts +1 -1
  56. package/src/ranger/writer.ts +3 -0
  57. package/src/workspace/client.ts +3 -3
  58. package/src/workspace/lineplot/client.ts +2 -2
  59. package/src/workspace/lineplot/payload.ts +1 -7
  60. package/src/workspace/lineplot/retriever.ts +10 -11
  61. package/src/workspace/lineplot/writer.ts +13 -8
  62. package/src/workspace/payload.ts +1 -1
  63. package/src/workspace/pid/client.ts +2 -2
  64. package/src/workspace/pid/payload.ts +1 -1
  65. package/src/workspace/pid/retriever.ts +8 -10
  66. package/src/workspace/pid/writer.ts +12 -5
  67. package/src/workspace/retriever.ts +2 -4
  68. package/src/workspace/workspace.spec.ts +4 -4
  69. package/src/workspace/writer.ts +12 -10
  70. package/.pytest_cache/README.md +0 -8
  71. package/examples/index.js +0 -1
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "examples",
3
- "type":"module",
3
+ "type": "module",
4
4
  "version": "1.0.0",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "scripts": {
8
8
  "main": "node index.js"
9
9
  },
10
- "dependencies": {
11
- "@synnaxlabs/client": "workspace:*"
12
- },
13
10
  "keywords": [],
14
11
  "author": "",
15
- "license": "ISC"
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "@synnaxlabs/client": "^0.16.4"
15
+ }
16
16
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@synnaxlabs/client",
3
3
  "private": false,
4
- "version": "0.16.3",
4
+ "version": "0.17.0",
5
5
  "type": "module",
6
6
  "description": "The Client Library for Synnax",
7
7
  "repository": "https://github.com/synnaxlabs/synnax/tree/main/client/ts",
@@ -18,8 +18,8 @@
18
18
  "dependencies": {
19
19
  "async-mutex": "^0.4.0",
20
20
  "zod": "3.22.4",
21
- "@synnaxlabs/freighter": "0.7.1",
22
- "@synnaxlabs/x": "0.12.0"
21
+ "@synnaxlabs/freighter": "0.9.1",
22
+ "@synnaxlabs/x": "0.14.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^20.10.5",
@@ -28,8 +28,8 @@
28
28
  "vite": "^5.1.2",
29
29
  "vitest": "^1.2.2",
30
30
  "@synnaxlabs/tsconfig": "0.0.2",
31
- "@synnaxlabs/vite-plugin": "0.0.1",
32
- "eslint-config-synnaxlabs": "0.0.1"
31
+ "eslint-config-synnaxlabs": "0.0.1",
32
+ "@synnaxlabs/vite-plugin": "0.0.1"
33
33
  },
34
34
  "main": "dist/client.cjs",
35
35
  "module": "dist/client.js",
package/src/auth/auth.ts CHANGED
@@ -47,18 +47,19 @@ export class Client {
47
47
  authenticated: boolean;
48
48
  user: user.Payload | undefined;
49
49
 
50
- constructor(client: UnaryClient, creds: InsecureCredentials) {
50
+ constructor(client: UnaryClient, credentials: InsecureCredentials) {
51
51
  this.client = client;
52
52
  this.authenticated = false;
53
- this.authenticate(creds);
53
+ this.authenticate(credentials);
54
54
  }
55
55
 
56
- authenticate(creds: InsecureCredentials): void {
56
+ authenticate(credentials: InsecureCredentials): void {
57
57
  this.authenticating = new Promise((resolve, reject) => {
58
58
  this.client
59
59
  .send<typeof insecureCredentialsZ, typeof tokenResponseZ>(
60
60
  LOGIN_ENDPOINT,
61
- creds,
61
+ credentials,
62
+ insecureCredentialsZ,
62
63
  tokenResponseZ,
63
64
  )
64
65
  .then(([res, err]) => {
@@ -244,7 +244,6 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
244
244
  async create(channels: NewPayload[]): Promise<Channel[]>;
245
245
 
246
246
  async create(channels: NewPayload | NewPayload[]): Promise<Channel | Channel[]> {
247
- console.log("ABC");
248
247
  const single = !Array.isArray(channels);
249
248
  const payloads = await this.creator.create(toArray(channels));
250
249
  const res = this.sugar(payloads);
@@ -35,6 +35,7 @@ export class Creator {
35
35
  const [res, err] = await this.client.send<typeof reqZ, typeof resZ>(
36
36
  Creator.ENDPOINT,
37
37
  req,
38
+ reqZ,
38
39
  resZ,
39
40
  );
40
41
  if (err != null) throw err;
@@ -33,7 +33,7 @@ const reqZ = z.object({
33
33
  offset: z.number().optional(),
34
34
  });
35
35
 
36
- type Request = z.infer<typeof reqZ>;
36
+ type Request = z.input<typeof reqZ>;
37
37
 
38
38
  const resZ = z.object({
39
39
  channels: payload.array(),
@@ -67,7 +67,7 @@ export class ClusterRetriever implements Retriever {
67
67
  }
68
68
 
69
69
  private async execute(request: Request): Promise<Payload[]> {
70
- const [res, err] = await this.client.send(ClusterRetriever.ENDPOINT, request, resZ);
70
+ const [res, err] = await this.client.send(ClusterRetriever.ENDPOINT, request, reqZ, resZ);
71
71
  if (err != null) throw err;
72
72
  return res.channels;
73
73
  }
package/src/client.ts CHANGED
@@ -48,19 +48,19 @@ export type ParsedSynnaxProps = z.output<typeof synnaxPropsZ>;
48
48
  */
49
49
  // eslint-disable-next-line import/no-default-export
50
50
  export default class Synnax {
51
- private readonly transport: Transport;
52
51
  readonly createdAt: TimeStamp;
52
+ readonly props: ParsedSynnaxProps;
53
53
  readonly telem: framer.Client;
54
54
  readonly ranges: ranger.Client;
55
55
  readonly channels: channel.Client;
56
56
  readonly auth: auth.Client | undefined;
57
57
  readonly connectivity: connection.Checker;
58
58
  readonly ontology: ontology.Client;
59
- readonly props: ParsedSynnaxProps;
60
59
  readonly workspaces: workspace.Client;
61
60
  readonly labels: label.Client;
62
61
  readonly hardware: hardware.Client;
63
62
  static readonly connectivity = connection.Checker;
63
+ private readonly transport: Transport;
64
64
 
65
65
  /**
66
66
  * @param props.host - Hostname of a node in the cluster.
@@ -52,7 +52,11 @@ export class Checker {
52
52
  * @param pollFreq - The frequency at which to poll the cluster for
53
53
  * connectivity information.
54
54
  */
55
- constructor(client: UnaryClient, pollFreq: TimeSpan = TimeSpan.seconds(30), name?: string) {
55
+ constructor(
56
+ client: UnaryClient,
57
+ pollFreq: TimeSpan = TimeSpan.seconds(30),
58
+ name?: string,
59
+ ) {
56
60
  this._state = { ...DEFAULT };
57
61
  this.client = client;
58
62
  this.pollFrequency = pollFreq;
@@ -73,7 +77,7 @@ export class Checker {
73
77
  async check(): Promise<State> {
74
78
  const prevStatus = this._state.status;
75
79
  try {
76
- const [res, err] = await this.client.send(Checker.ENDPOINT, null, responseZ);
80
+ const [res, err] = await this.client.send(Checker.ENDPOINT, {}, z.object({}), responseZ);
77
81
  if (err != null) throw err;
78
82
  this._state.status = "connected";
79
83
  this._state.message = `Connected to ${this.name ?? "cluster"}`;
@@ -96,8 +96,8 @@ export class Client {
96
96
  });
97
97
  try {
98
98
  await w.write(to, data);
99
- if (!(await w.commit())) throw (await w.error()) as Error;
100
- } catch {
99
+ await w.commit();
100
+ } finally {
101
101
  await w.close();
102
102
  }
103
103
  }
@@ -116,7 +116,11 @@ export class Client {
116
116
  private async readFrame(tr: TimeRange, params: Params): Promise<Frame> {
117
117
  const i = await this.newIterator(tr, params);
118
118
  const frame = new Frame();
119
- for await (const f of i) frame.push(f);
119
+ try {
120
+ for await (const f of i) frame.push(f);
121
+ } finally {
122
+ await i.close();
123
+ }
120
124
  return frame;
121
125
  }
122
126
  }
@@ -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 { Size, Series, TimeRange, toArray, DataType, unique } from "@synnaxlabs/x";
10
+ import { Size, Series, TimeRange, toArray, DataType, unique, TimeStamp } from "@synnaxlabs/x";
11
11
  import { z } from "zod";
12
12
 
13
13
  import {
@@ -222,7 +222,7 @@ export class Frame {
222
222
  * @returns true if the frame is weakly aligned. A frame is weakly aligned if it meets
223
223
  * the time range occupied by all arrays of a particular channel is the same for all
224
224
  * channels in the frame. This means that the arrays for a particular channel can have
225
- * gaps betwen them.
225
+ * gaps between them.
226
226
  */
227
227
  get isWeaklyAligned(): boolean {
228
228
  if (this.columns.length <= 1) return true;
@@ -233,8 +233,8 @@ export class Frame {
233
233
  timeRange(col?: KeyOrName): TimeRange {
234
234
  if (col == null) {
235
235
  if (this.columns.length === 0) return TimeRange.ZERO;
236
- const start = Math.min(...this.series.map((a) => a.timeRange.start.valueOf()));
237
- const end = Math.max(...this.series.map((a) => a.timeRange.end.valueOf()));
236
+ const start = TimeStamp.min(...this.series.map((a) => a.timeRange.start));
237
+ const end = TimeStamp.max(...this.series.map((a) => a.timeRange.end));
238
238
  return new TimeRange(start, end);
239
239
  }
240
240
  const group = this.get(col);
@@ -37,7 +37,7 @@ export class Retriever {
37
37
  const res = await sendRequired<
38
38
  typeof retrieveDeviceReqZ,
39
39
  typeof retrieveDeviceResZ
40
- >(this.client, RETRIEVE_ENDPOINT, { keys: [term] }, retrieveDeviceResZ);
40
+ >(this.client, RETRIEVE_ENDPOINT, { keys: [term] }, retrieveDeviceReqZ, retrieveDeviceResZ);
41
41
  return res.devices;
42
42
  }
43
43
 
@@ -45,7 +45,7 @@ export class Retriever {
45
45
  const res = await sendRequired<
46
46
  typeof retrieveDeviceReqZ,
47
47
  typeof retrieveDeviceResZ
48
- >(this.client, RETRIEVE_ENDPOINT, { offset, limit }, retrieveDeviceResZ);
48
+ >(this.client, RETRIEVE_ENDPOINT, { offset, limit }, retrieveDeviceReqZ, retrieveDeviceResZ);
49
49
  return res.devices;
50
50
  }
51
51
 
@@ -54,7 +54,7 @@ export class Retriever {
54
54
  const res = await sendRequired<
55
55
  typeof retrieveDeviceReqZ,
56
56
  typeof retrieveDeviceResZ
57
- >(this.client, RETRIEVE_ENDPOINT, { keys }, retrieveDeviceResZ);
57
+ >(this.client, RETRIEVE_ENDPOINT, { keys }, retrieveDeviceReqZ, retrieveDeviceResZ);
58
58
  return res.devices;
59
59
  }
60
60
  }
@@ -40,7 +40,8 @@ export class Writer {
40
40
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
41
41
  this.client,
42
42
  CREATE_ENDPOINT,
43
- createReqZ.parse({ devices }),
43
+ { devices },
44
+ createReqZ,
44
45
  createResZ,
45
46
  );
46
47
  return res.devices;
@@ -51,6 +52,7 @@ export class Writer {
51
52
  this.client,
52
53
  DELETE_ENDPOINT,
53
54
  { keys },
55
+ deleteReqZ,
54
56
  deleteResZ,
55
57
  );
56
58
  }
@@ -74,7 +74,7 @@ export class Rack {
74
74
  key: number;
75
75
  name: string;
76
76
  private readonly writer: TaskWriter;
77
- private readonly retriever: TaskRetriever;
77
+ private readonly tasks: TaskRetriever;
78
78
 
79
79
  constructor(
80
80
  key: number,
@@ -85,11 +85,11 @@ export class Rack {
85
85
  this.key = key;
86
86
  this.name = name;
87
87
  this.writer = _writer;
88
- this.retriever = _retriever;
88
+ this.tasks = _retriever;
89
89
  }
90
90
 
91
91
  async listTasks(): Promise<Task[]> {
92
- return await this.retriever.retrieve({ rack: this.key });
92
+ return await this.tasks.retrieve({ rack: this.key });
93
93
  }
94
94
 
95
95
  async retrieveTasks(): Promise<Task[]> {
@@ -97,7 +97,6 @@ export class Rack {
97
97
  }
98
98
 
99
99
  async createTask(task: NewTask): Promise<Task> {
100
- // @ts-expect-error
101
100
  task.key = (
102
101
  (BigInt(this.key) << 32n) +
103
102
  (BigInt(task.key ?? 0) & 0xffffffffn)
@@ -38,6 +38,7 @@ export class Retriever {
38
38
  this.client,
39
39
  RETRIEVE_ENDPOINT,
40
40
  { offset, limit },
41
+ retrieveRackReqZ,
41
42
  retrieveRackResZ,
42
43
  );
43
44
  return res.racks;
@@ -48,6 +49,7 @@ export class Retriever {
48
49
  this.client,
49
50
  RETRIEVE_ENDPOINT,
50
51
  { search: term },
52
+ retrieveRackReqZ,
51
53
  retrieveRackResZ,
52
54
  );
53
55
  return res.racks;
@@ -58,6 +60,7 @@ export class Retriever {
58
60
  this.client,
59
61
  RETRIEVE_ENDPOINT,
60
62
  { keys },
63
+ retrieveRackReqZ,
61
64
  retrieveRackResZ,
62
65
  );
63
66
  return res.racks;
@@ -40,6 +40,7 @@ export class Writer {
40
40
  this.client,
41
41
  CREATE_RACK_ENDPOINT,
42
42
  { racks },
43
+ createReqZ,
43
44
  createResZ,
44
45
  );
45
46
  return res.racks;
@@ -50,6 +51,7 @@ export class Writer {
50
51
  this.client,
51
52
  DELETE_RACK_ENDPOINT,
52
53
  { keys },
54
+ deleteReqZ,
53
55
  deleteResZ,
54
56
  );
55
57
  }
@@ -10,10 +10,11 @@
10
10
  import { type UnknownRecord } from "@synnaxlabs/x";
11
11
  import { z } from "zod";
12
12
 
13
- export const taskKeyZ = z
14
- .bigint()
15
- .or(z.number())
16
- .transform((k) => k.toString());
13
+ export const taskKeyZ = z.union([
14
+ z.string(),
15
+ z.bigint().transform((k) => k.toString()),
16
+ z.number().transform((k) => k.toString()),
17
+ ])
17
18
 
18
19
  export type TaskKey = z.infer<typeof taskKeyZ>;
19
20
 
@@ -20,7 +20,7 @@ const retrieveReqZ = z.object({
20
20
  limit: z.number().optional(),
21
21
  });
22
22
 
23
- const rerieveResS = z.object({
23
+ const retrieveResZ = z.object({
24
24
  tasks: z.union([taskZ.array(), z.null().transform(() => [])]),
25
25
  });
26
26
 
@@ -36,31 +36,34 @@ export class Retriever {
36
36
  }
37
37
 
38
38
  async retrieve(params: RetrieveRequest): Promise<Task[]> {
39
- const res = await sendRequired<typeof retrieveReqZ, typeof rerieveResS>(
39
+ const res = await sendRequired<typeof retrieveReqZ, typeof retrieveResZ>(
40
40
  this.client,
41
41
  RETRIEVE_ENDPOINT,
42
42
  params,
43
- rerieveResS,
43
+ retrieveReqZ,
44
+ retrieveResZ,
44
45
  );
45
46
  return res.tasks;
46
47
  }
47
48
 
48
49
  async search(term: string): Promise<Task[]> {
49
- const res = await sendRequired<typeof retrieveReqZ, typeof rerieveResS>(
50
+ const res = await sendRequired<typeof retrieveReqZ, typeof retrieveResZ>(
50
51
  this.client,
51
52
  RETRIEVE_ENDPOINT,
52
53
  { keys: [term] },
53
- rerieveResS,
54
+ retrieveReqZ,
55
+ retrieveResZ,
54
56
  );
55
57
  return res.tasks;
56
58
  }
57
59
 
58
60
  async page(offset: number, limit: number): Promise<Task[]> {
59
- const res = await sendRequired<typeof retrieveReqZ, typeof rerieveResS>(
61
+ const res = await sendRequired<typeof retrieveReqZ, typeof retrieveResZ>(
60
62
  this.client,
61
63
  RETRIEVE_ENDPOINT,
62
64
  { offset, limit },
63
- rerieveResS,
65
+ retrieveReqZ,
66
+ retrieveResZ,
64
67
  );
65
68
  return res.tasks;
66
69
  }
@@ -46,7 +46,8 @@ export class Writer {
46
46
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
47
47
  this.client,
48
48
  CREATE_ENDPOINT,
49
- { tasks: tasks.map((t) => ({ ...t, config: JSON.stringify(t.config) })) },
49
+ { tasks },
50
+ createReqZ,
50
51
  createResZ,
51
52
  );
52
53
  return res.tasks;
@@ -57,6 +58,7 @@ export class Writer {
57
58
  this.client,
58
59
  DELETE_ENDPOINT,
59
60
  { keys },
61
+ deleteReqZ,
60
62
  deleteResZ,
61
63
  );
62
64
  }
@@ -57,6 +57,7 @@ export class Retriever {
57
57
  const [res, err] = await this.client.send<typeof reqZ, typeof resZ>(
58
58
  Retriever.ENDPOINT,
59
59
  req,
60
+ reqZ,
60
61
  resZ,
61
62
  );
62
63
  if (err != null) throw err;
@@ -56,6 +56,7 @@ export class Writer {
56
56
  this.client,
57
57
  CREATE_ENDPOINT,
58
58
  { labels: toArray(labels) },
59
+ createReqZ,
59
60
  createResZ,
60
61
  );
61
62
  return res.labels;
@@ -66,6 +67,7 @@ export class Writer {
66
67
  this.client,
67
68
  DELETE_ENDPOINT,
68
69
  { keys: toArray(keys) },
70
+ deleteReqZ,
69
71
  emptyResZ,
70
72
  );
71
73
  }
@@ -75,6 +77,7 @@ export class Writer {
75
77
  this.client,
76
78
  SET_ENDPOINT,
77
79
  { id, labels },
80
+ setReqZ,
78
81
  emptyResZ,
79
82
  );
80
83
  }
@@ -84,6 +87,7 @@ export class Writer {
84
87
  this.client,
85
88
  REMOVE_ENDPOINT,
86
89
  { id, labels },
90
+ removeReqZ,
87
91
  emptyResZ,
88
92
  );
89
93
  }
@@ -11,12 +11,26 @@ import { type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { z } from "zod";
12
12
 
13
13
  import { type Payload, payloadZ } from "@/ontology/group/payload";
14
- import { type ID } from "@/ontology/payload";
14
+ import { idZ, type ID } from "@/ontology/payload";
15
15
 
16
16
  const resZ = z.object({
17
17
  group: payloadZ,
18
18
  });
19
19
 
20
+ const createReqZ = z.object({
21
+ parent: idZ,
22
+ name: z.string(),
23
+ });
24
+
25
+ const renameReqZ = z.object({
26
+ key: z.string(),
27
+ name: z.string(),
28
+ });
29
+
30
+ const deleteReqZ = z.object({
31
+ keys: z.array(z.string()),
32
+ });
33
+
20
34
  export class Writer {
21
35
  private static readonly ENDPOINT = "/ontology/create-group";
22
36
  private static readonly ENDPOINT_RENAME = "/ontology/rename-group";
@@ -28,21 +42,20 @@ export class Writer {
28
42
  }
29
43
 
30
44
  async create(parent: ID, name: string): Promise<Payload> {
31
- const req = { parent, name };
32
- const [res, err] = await this.client.send(Writer.ENDPOINT, req, resZ);
45
+ const [res, err] = await this.client.send(Writer.ENDPOINT, {parent, name},createReqZ, resZ);
33
46
  if (err != null) throw err;
34
47
  return res.group;
35
48
  }
36
49
 
37
50
  async rename(key: string, name: string): Promise<void> {
38
51
  const req = { key, name };
39
- const [, err] = await this.client.send(Writer.ENDPOINT_RENAME, req, z.object({}));
52
+ const [, err] = await this.client.send(Writer.ENDPOINT_RENAME, req, renameReqZ, z.object({}));
40
53
  if (err != null) throw err;
41
54
  }
42
55
 
43
56
  async delete(keys: string[]): Promise<void> {
44
57
  const req = { keys };
45
- const [, err] = await this.client.send(Writer.ENDPOINT_DELETE, req, z.object({}));
58
+ const [, err] = await this.client.send(Writer.ENDPOINT_DELETE, req, deleteReqZ, z.object({}));
46
59
  if (err != null) throw err;
47
60
  }
48
61
  }
@@ -7,13 +7,13 @@
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 { UnaryClient } from "@synnaxlabs/freighter";
10
+ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { toArray } from "@synnaxlabs/x";
12
12
  import { z } from "zod";
13
13
 
14
14
  import { ID, type Resource, idZ, resourceSchemaZ } from "@/ontology/payload";
15
15
 
16
- const requestSchema = z.object({
16
+ const reqZ = z.object({
17
17
  ids: idZ.array().optional(),
18
18
  children: z.boolean().optional(),
19
19
  parents: z.boolean().optional(),
@@ -22,9 +22,9 @@ const requestSchema = z.object({
22
22
  term: z.string().optional(),
23
23
  });
24
24
 
25
- type Request = z.infer<typeof requestSchema>;
25
+ type Request = z.infer<typeof reqZ>;
26
26
 
27
- const responseSchema = z.object({
27
+ const resZ = z.object({
28
28
  resources: resourceSchemaZ.array(),
29
29
  });
30
30
 
@@ -80,12 +80,12 @@ export class Retriever {
80
80
  }
81
81
 
82
82
  private async execute(request: Request): Promise<Resource[]> {
83
- const [res, err] = await this.client.send(
83
+ return (await sendRequired(
84
+ this.client,
84
85
  Retriever.ENDPOINT,
85
86
  request,
86
- responseSchema,
87
- );
88
- if (err != null) throw err;
89
- return res.resources;
87
+ reqZ,
88
+ resZ,
89
+ )).resources;
90
90
  }
91
91
  }
@@ -7,10 +7,10 @@
7
7
  // License, use of this software will be governed by the Apache License, Version 2.0,
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
- import { type UnaryClient } from "@synnaxlabs/freighter";
10
+ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { z } from "zod";
12
12
 
13
- import { type ID } from "@/ontology/payload";
13
+ import { idZ, type ID } from "@/ontology/payload";
14
14
 
15
15
  const ENDPOINTS = {
16
16
  ADD_CHILDREN: "/ontology/add-children",
@@ -18,6 +18,17 @@ const ENDPOINTS = {
18
18
  MOVE_CHILDREN: "/ontology/move-children",
19
19
  };
20
20
 
21
+ const addRemoveChildrenReqZ = z.object({
22
+ id: idZ,
23
+ children: idZ.array(),
24
+ });
25
+
26
+ const moveChildrenReqZ = z.object({
27
+ from: idZ,
28
+ to: idZ,
29
+ children: idZ.array(),
30
+ });
31
+
21
32
  export class Writer {
22
33
  client: UnaryClient;
23
34
 
@@ -26,24 +37,27 @@ export class Writer {
26
37
  }
27
38
 
28
39
  async addChildren(id: ID, ...children: ID[]): Promise<void> {
29
- const req = { id, children };
30
- const [, err] = await this.client.send(ENDPOINTS.ADD_CHILDREN, req, z.object({}));
31
- if (err != null) throw err;
40
+ await sendRequired<typeof addRemoveChildrenReqZ, z.ZodTypeAny>(
41
+ this.client,
42
+ ENDPOINTS.ADD_CHILDREN,
43
+ { id, children },
44
+ addRemoveChildrenReqZ,
45
+ z.object({})
46
+ );
32
47
  }
33
48
 
34
49
  async removeChildren(id: ID, ...children: ID[]): Promise<void> {
35
- const req = { id, children };
36
- const [, err] = await this.client.send(
50
+ await sendRequired<typeof addRemoveChildrenReqZ, z.ZodTypeAny>(
51
+ this.client,
37
52
  ENDPOINTS.REMOVE_CHILDREN,
38
- req,
53
+ { id, children },
54
+ addRemoveChildrenReqZ,
39
55
  z.object({}),
40
56
  );
41
- if (err != null) throw err;
42
57
  }
43
58
 
44
59
  async moveChildren(from: ID, to: ID, ...children: ID[]): Promise<void> {
45
60
  const req = { from, to, children };
46
- const [, err] = await this.client.send(ENDPOINTS.MOVE_CHILDREN, req, z.object({}));
47
- if (err != null) throw err;
61
+ await sendRequired(this.client, ENDPOINTS.MOVE_CHILDREN, req, moveChildrenReqZ, z.object({}));
48
62
  }
49
63
  }