@synnaxlabs/client 0.42.3 → 0.43.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 (180) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.vscode/settings.json +2 -2
  3. package/CONTRIBUTING.md +6 -5
  4. package/README.md +7 -8
  5. package/dist/access/payload.d.ts +1 -1
  6. package/dist/access/payload.d.ts.map +1 -1
  7. package/dist/access/policy/payload.d.ts +9 -9
  8. package/dist/access/policy/payload.d.ts.map +1 -1
  9. package/dist/access/policy/retriever.d.ts +3 -3
  10. package/dist/access/policy/retriever.d.ts.map +1 -1
  11. package/dist/auth/auth.d.ts +2 -2
  12. package/dist/auth/auth.d.ts.map +1 -1
  13. package/dist/channel/client.d.ts +1 -0
  14. package/dist/channel/client.d.ts.map +1 -1
  15. package/dist/channel/payload.d.ts +21 -8
  16. package/dist/channel/payload.d.ts.map +1 -1
  17. package/dist/channel/retriever.d.ts +5 -5
  18. package/dist/channel/retriever.d.ts.map +1 -1
  19. package/dist/channel/writer.d.ts +3 -3
  20. package/dist/channel/writer.d.ts.map +1 -1
  21. package/dist/client.cjs +135 -39
  22. package/dist/client.d.ts +8 -8
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +28505 -9345
  25. package/dist/connection/checker.d.ts +5 -5
  26. package/dist/connection/checker.d.ts.map +1 -1
  27. package/dist/control/state.d.ts +46 -3
  28. package/dist/control/state.d.ts.map +1 -1
  29. package/dist/framer/adapter.d.ts +2 -2
  30. package/dist/framer/adapter.d.ts.map +1 -1
  31. package/dist/framer/client.d.ts +2 -0
  32. package/dist/framer/client.d.ts.map +1 -1
  33. package/dist/framer/codec.d.ts +3 -3
  34. package/dist/framer/codec.d.ts.map +1 -1
  35. package/dist/framer/deleter.d.ts +8 -8
  36. package/dist/framer/deleter.d.ts.map +1 -1
  37. package/dist/framer/frame.d.ts +17 -17
  38. package/dist/framer/frame.d.ts.map +1 -1
  39. package/dist/framer/streamProxy.d.ts +3 -3
  40. package/dist/framer/streamProxy.d.ts.map +1 -1
  41. package/dist/framer/streamer.d.ts +103 -22
  42. package/dist/framer/streamer.d.ts.map +1 -1
  43. package/dist/framer/writer.d.ts +25 -25
  44. package/dist/framer/writer.d.ts.map +1 -1
  45. package/dist/hardware/device/client.d.ts +3 -3
  46. package/dist/hardware/device/client.d.ts.map +1 -1
  47. package/dist/hardware/device/payload.d.ts +65 -18
  48. package/dist/hardware/device/payload.d.ts.map +1 -1
  49. package/dist/hardware/rack/client.d.ts.map +1 -1
  50. package/dist/hardware/rack/payload.d.ts +87 -30
  51. package/dist/hardware/rack/payload.d.ts.map +1 -1
  52. package/dist/hardware/task/client.d.ts +3 -3
  53. package/dist/hardware/task/client.d.ts.map +1 -1
  54. package/dist/hardware/task/payload.d.ts +14 -15
  55. package/dist/hardware/task/payload.d.ts.map +1 -1
  56. package/dist/label/payload.d.ts +2 -2
  57. package/dist/label/payload.d.ts.map +1 -1
  58. package/dist/label/writer.d.ts +4 -4
  59. package/dist/label/writer.d.ts.map +1 -1
  60. package/dist/ontology/client.d.ts +3 -3
  61. package/dist/ontology/client.d.ts.map +1 -1
  62. package/dist/ontology/group/payload.d.ts +2 -2
  63. package/dist/ontology/group/payload.d.ts.map +1 -1
  64. package/dist/ontology/payload.d.ts +25 -25
  65. package/dist/ontology/payload.d.ts.map +1 -1
  66. package/dist/ranger/client.d.ts +8 -8
  67. package/dist/ranger/client.d.ts.map +1 -1
  68. package/dist/ranger/kv.d.ts +6 -6
  69. package/dist/ranger/kv.d.ts.map +1 -1
  70. package/dist/ranger/payload.d.ts +15 -15
  71. package/dist/ranger/payload.d.ts.map +1 -1
  72. package/dist/ranger/writer.d.ts +10 -10
  73. package/dist/ranger/writer.d.ts.map +1 -1
  74. package/dist/testutil/{indexedPair.d.ts → channels.d.ts} +1 -1
  75. package/dist/testutil/channels.d.ts.map +1 -0
  76. package/dist/user/payload.d.ts +3 -3
  77. package/dist/user/payload.d.ts.map +1 -1
  78. package/dist/user/retriever.d.ts +2 -2
  79. package/dist/user/retriever.d.ts.map +1 -1
  80. package/dist/util/retrieve.d.ts +6 -6
  81. package/dist/util/retrieve.d.ts.map +1 -1
  82. package/dist/util/zod.d.ts +2 -2
  83. package/dist/util/zod.d.ts.map +1 -1
  84. package/dist/workspace/client.d.ts.map +1 -1
  85. package/dist/workspace/lineplot/client.d.ts.map +1 -1
  86. package/dist/workspace/lineplot/lineplot.spec.d.ts +2 -0
  87. package/dist/workspace/lineplot/lineplot.spec.d.ts.map +1 -0
  88. package/dist/workspace/lineplot/payload.d.ts +5 -5
  89. package/dist/workspace/lineplot/payload.d.ts.map +1 -1
  90. package/dist/workspace/log/client.d.ts.map +1 -1
  91. package/dist/workspace/log/payload.d.ts +5 -5
  92. package/dist/workspace/log/payload.d.ts.map +1 -1
  93. package/dist/workspace/payload.d.ts +6 -6
  94. package/dist/workspace/payload.d.ts.map +1 -1
  95. package/dist/workspace/schematic/client.d.ts.map +1 -1
  96. package/dist/workspace/schematic/payload.d.ts +7 -7
  97. package/dist/workspace/schematic/payload.d.ts.map +1 -1
  98. package/dist/workspace/table/client.d.ts.map +1 -1
  99. package/dist/workspace/table/payload.d.ts +6 -6
  100. package/dist/workspace/table/payload.d.ts.map +1 -1
  101. package/package.json +11 -12
  102. package/src/access/payload.ts +1 -1
  103. package/src/access/policy/client.ts +3 -3
  104. package/src/access/policy/payload.ts +1 -1
  105. package/src/access/policy/retriever.ts +1 -1
  106. package/src/access/policy/writer.ts +7 -7
  107. package/src/auth/auth.ts +1 -1
  108. package/src/channel/client.ts +6 -4
  109. package/src/channel/payload.ts +10 -18
  110. package/src/channel/retriever.ts +2 -2
  111. package/src/channel/writer.ts +11 -2
  112. package/src/client.ts +3 -3
  113. package/src/connection/checker.ts +1 -1
  114. package/src/connection/connection.spec.ts +1 -1
  115. package/src/control/client.ts +1 -1
  116. package/src/control/state.ts +4 -5
  117. package/src/errors.spec.ts +2 -3
  118. package/src/errors.ts +2 -2
  119. package/src/framer/adapter.ts +2 -2
  120. package/src/framer/client.ts +4 -3
  121. package/src/framer/codec.spec.ts +2 -2
  122. package/src/framer/codec.ts +5 -9
  123. package/src/framer/deleter.spec.ts +1 -1
  124. package/src/framer/deleter.ts +1 -1
  125. package/src/framer/frame.ts +15 -15
  126. package/src/framer/iterator.spec.ts +1 -1
  127. package/src/framer/iterator.ts +1 -1
  128. package/src/framer/streamProxy.ts +4 -4
  129. package/src/framer/streamer.spec.ts +420 -215
  130. package/src/framer/streamer.ts +119 -21
  131. package/src/framer/writer.spec.ts +1 -1
  132. package/src/framer/writer.ts +15 -8
  133. package/src/hardware/device/client.ts +5 -5
  134. package/src/hardware/device/device.spec.ts +28 -30
  135. package/src/hardware/device/payload.ts +5 -5
  136. package/src/hardware/rack/client.ts +4 -4
  137. package/src/hardware/rack/payload.ts +6 -6
  138. package/src/hardware/rack/rack.spec.ts +1 -1
  139. package/src/hardware/task/client.ts +21 -19
  140. package/src/hardware/task/payload.ts +8 -6
  141. package/src/label/payload.ts +1 -1
  142. package/src/label/retriever.ts +3 -3
  143. package/src/label/writer.ts +4 -4
  144. package/src/ontology/client.ts +4 -4
  145. package/src/ontology/group/payload.ts +3 -3
  146. package/src/ontology/group/writer.ts +1 -1
  147. package/src/ontology/payload.ts +2 -2
  148. package/src/ontology/writer.ts +1 -1
  149. package/src/ranger/alias.ts +1 -1
  150. package/src/ranger/client.ts +6 -4
  151. package/src/ranger/kv.ts +4 -4
  152. package/src/ranger/payload.ts +3 -3
  153. package/src/ranger/writer.ts +1 -1
  154. package/src/user/client.ts +3 -3
  155. package/src/user/payload.ts +1 -1
  156. package/src/user/retriever.ts +1 -1
  157. package/src/user/writer.ts +4 -4
  158. package/src/util/retrieve.spec.ts +7 -4
  159. package/src/util/retrieve.ts +10 -10
  160. package/src/util/zod.ts +3 -3
  161. package/src/workspace/client.ts +5 -5
  162. package/src/workspace/lineplot/client.ts +5 -5
  163. package/src/workspace/lineplot/{linePlot.spec.ts → lineplot.spec.ts} +2 -2
  164. package/src/workspace/lineplot/payload.ts +1 -1
  165. package/src/workspace/log/client.ts +5 -5
  166. package/src/workspace/log/log.spec.ts +2 -2
  167. package/src/workspace/log/payload.ts +1 -1
  168. package/src/workspace/payload.ts +1 -1
  169. package/src/workspace/schematic/client.ts +5 -5
  170. package/src/workspace/schematic/payload.ts +1 -1
  171. package/src/workspace/schematic/schematic.spec.ts +3 -3
  172. package/src/workspace/table/client.ts +5 -5
  173. package/src/workspace/table/payload.ts +1 -1
  174. package/src/workspace/table/table.spec.ts +2 -2
  175. package/src/workspace/workspace.spec.ts +2 -2
  176. package/tsconfig.json +3 -5
  177. package/dist/testutil/indexedPair.d.ts.map +0 -1
  178. package/dist/workspace/lineplot/linePlot.spec.d.ts +0 -2
  179. package/dist/workspace/lineplot/linePlot.spec.d.ts.map +0 -1
  180. /package/src/testutil/{indexedPair.ts → channels.ts} +0 -0
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";
13
+ import { z } from "zod/v4";
14
14
 
15
15
  import { access } from "@/access";
16
16
  import { auth } from "@/auth";
@@ -40,11 +40,11 @@ export const synnaxPropsZ = z.object({
40
40
  connectivityPollFrequency: TimeSpan.z.default(TimeSpan.seconds(30)),
41
41
  secure: z.boolean().optional().default(false),
42
42
  name: z.string().optional(),
43
- retry: breaker.breakerConfig.optional(),
43
+ retry: breaker.breakerConfigZ.optional(),
44
44
  });
45
45
 
46
46
  export interface SynnaxProps extends z.input<typeof synnaxPropsZ> {}
47
- export interface ParsedSynnaxProps extends z.output<typeof synnaxPropsZ> {}
47
+ export interface ParsedSynnaxProps extends z.infer<typeof synnaxPropsZ> {}
48
48
 
49
49
  /**
50
50
  * Client to perform operations against a Synnax cluster.
@@ -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";
13
+ import { z } from "zod/v4";
14
14
 
15
15
  export const statusZ = z.enum(["disconnected", "connecting", "connected", "failed"]);
16
16
  export type Status = z.infer<typeof statusZ>;
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { URL } from "@synnaxlabs/x/url";
11
11
  import { describe, expect, it } from "vitest";
12
- import { z } from "zod";
12
+ import { z } from "zod/v4";
13
13
 
14
14
  import { auth } from "@/auth";
15
15
  import { connection } from "@/connection";
@@ -21,7 +21,7 @@ export class Client {
21
21
 
22
22
  async openStateTracker(): Promise<StateTracker> {
23
23
  const stream = await framer.HardenedStreamer.open(
24
- async () => await this.framer.openStreamer(CONTROL_STATE_KEY),
24
+ async (p) => await this.framer.openStreamer(p),
25
25
  CONTROL_STATE_KEY,
26
26
  );
27
27
  return new StateTracker(stream);
@@ -10,9 +10,10 @@
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";
13
+ import { z } from "zod/v4";
14
14
 
15
15
  import { type channel } from "@/channel";
16
+ import { keyZ } from "@/channel/payload";
16
17
  import { framer } from "@/framer";
17
18
 
18
19
  export type Authority = control.Authority;
@@ -35,12 +36,10 @@ export const transferString = (t: Transfer): string => {
35
36
  };
36
37
 
37
38
  const updateZ = z.object({
38
- transfers: z.array(control.transferZ),
39
+ transfers: z.array(control.transferZ(keyZ)),
39
40
  });
40
41
 
41
- interface Update {
42
- transfers: control.Transfer<channel.Key>[];
43
- }
42
+ export interface Update extends z.infer<typeof updateZ> {}
44
43
 
45
44
  export class StateTracker
46
45
  extends framer.ObservableStreamer<Transfer[]>
@@ -7,8 +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 { type errors, id } from "@synnaxlabs/x";
11
- import { v4 as uuid } from "uuid";
10
+ import { type errors, id, uuid } from "@synnaxlabs/x";
12
11
  import { describe, expect, test } from "vitest";
13
12
 
14
13
  import {
@@ -61,7 +60,7 @@ test("client", async () => {
61
60
  expect(NotFoundError.matches(e)).toBe(true);
62
61
  }
63
62
  try {
64
- await client.workspaces.schematic.retrieve(uuid());
63
+ await client.workspaces.schematic.retrieve(uuid.create());
65
64
  } catch (e) {
66
65
  expect(NotFoundError.matches(e)).toBe(true);
67
66
  }
package/src/errors.ts CHANGED
@@ -36,9 +36,9 @@ export class AuthError extends SynnaxError.sub("auth") {}
36
36
  /**
37
37
  * InvalidTokenError is raised when an authentication token is invalid.
38
38
  */
39
- export class InvalidTokenError extends AuthError.sub("invalid-token") {}
39
+ export class InvalidTokenError extends AuthError.sub("invalid_token") {}
40
40
 
41
- export class ExpiredTokenError extends AuthError.sub("expired-token") {}
41
+ export class ExpiredTokenError extends AuthError.sub("expired_token") {}
42
42
 
43
43
  /**
44
44
  * UnexpectedError is raised when an unexpected error occurs.
@@ -12,7 +12,7 @@ import { type CrudeSeries, Series } from "@synnaxlabs/x/telem";
12
12
  import { channel } from "@/channel";
13
13
  import { ValidationError } from "@/errors";
14
14
  import { Codec } from "@/framer/codec";
15
- import { type Crude, Frame } from "@/framer/frame";
15
+ import { type CrudeFrame, Frame } from "@/framer/frame";
16
16
 
17
17
  export class ReadAdapter {
18
18
  private adapter: Map<channel.Key, channel.Name> | null;
@@ -133,7 +133,7 @@ export class WriteAdapter {
133
133
  }
134
134
 
135
135
  async adapt(
136
- columnsOrData: channel.Params | Record<channel.KeyOrName, CrudeSeries> | Crude,
136
+ columnsOrData: channel.Params | Record<channel.KeyOrName, CrudeSeries> | CrudeFrame,
137
137
  series?: CrudeSeries | CrudeSeries[],
138
138
  ): Promise<Frame> {
139
139
  if (typeof columnsOrData === "string" || typeof columnsOrData === "number") {
@@ -108,6 +108,9 @@ export class Client {
108
108
  * and then will start reading new values.
109
109
  *
110
110
  */
111
+ async openStreamer(config: StreamerConfig): Promise<Streamer>;
112
+
113
+ /** Overload to provide interface compatibility with @see StreamOpener */
111
114
  async openStreamer(config: StreamerConfig | channel.Params): Promise<Streamer>;
112
115
 
113
116
  async openStreamer(config: StreamerConfig | channel.Params): Promise<Streamer> {
@@ -160,9 +163,7 @@ export class Client {
160
163
  autoIndexPersistInterval: TimeSpan.MAX,
161
164
  });
162
165
  await w.write(data_);
163
- await w.commit();
164
- await w.close();
165
- return;
166
+ return await w.close();
166
167
  }
167
168
  const w = await this.openWriter({
168
169
  start,
@@ -269,7 +269,7 @@ describe("encoder", () => {
269
269
  });
270
270
 
271
271
  describe("websocket writer codec", () => {
272
- it("should correctly e + d a websocket write request", () => {
272
+ it("should correctly encode and decode a websocket write request", () => {
273
273
  const baseCodec = new Codec([1], [DataType.INT32]);
274
274
  const fr = new framer.Frame([1], [new Series(new Int32Array([1, 2, 3]))]);
275
275
  const writeReq: WriteRequest = {
@@ -280,7 +280,7 @@ describe("encoder", () => {
280
280
  const codec = new WSWriterCodec(baseCodec);
281
281
  const encoded = codec.encode(msg);
282
282
  expect(encoded[0]).toEqual(HIGH_PERF_SPECIAL_CHAR);
283
- const decoded = codec.decode<WebsocketMessage<WriteRequest>>(encoded);
283
+ const decoded = codec.decode(encoded) as WebsocketMessage<WriteRequest>;
284
284
  expect(decoded.payload?.command).toEqual(WriterCommand.Write);
285
285
  const decodedFr = new Frame(decoded.payload?.frame);
286
286
  expect(decodedFr.series[0].data).toEqual(fr.series[0].data);
@@ -15,7 +15,7 @@ import {
15
15
  TimeRange,
16
16
  TimeStamp,
17
17
  } from "@synnaxlabs/x";
18
- import { type ZodSchema } from "zod";
18
+ import { type z } from "zod/v4";
19
19
 
20
20
  import { type channel } from "@/channel";
21
21
  import { ValidationError } from "@/errors";
@@ -23,10 +23,6 @@ import { type Frame, type Payload } from "@/framer/frame";
23
23
  import { type StreamerResponse } from "@/framer/streamer";
24
24
  import { WriterCommand, type WriteRequest } from "@/framer/writer";
25
25
 
26
- // For detailed information about the specifications,
27
- // please refer to the official RFC 0016 document.
28
- // Document here: docs/tech/rfc/0016-231001-frame-flight-protocol.md
29
-
30
26
  const seriesPldLength = (series: SeriesPayload): number =>
31
27
  series.data.byteLength / series.dataType.density.valueOf();
32
28
 
@@ -356,7 +352,7 @@ export class WSWriterCodec implements binary.Codec {
356
352
  return data;
357
353
  }
358
354
 
359
- decode<P>(data: Uint8Array | ArrayBuffer, schema?: ZodSchema<P>): P {
355
+ decode<P extends z.ZodType>(data: Uint8Array | ArrayBuffer, schema?: P): z.infer<P> {
360
356
  const dv = new DataView(data instanceof Uint8Array ? data.buffer : data);
361
357
  const codec = dv.getUint8(0);
362
358
  if (codec === LOW_PER_SPECIAL_CHAR)
@@ -364,7 +360,7 @@ export class WSWriterCodec implements binary.Codec {
364
360
  const v: WebsocketMessage<WriteRequest> = { type: "data" };
365
361
  const frame = this.base.decode(data, 1);
366
362
  v.payload = { command: WriterCommand.Write, frame };
367
- return v as P;
363
+ return v as z.infer<P>;
368
364
  }
369
365
  }
370
366
 
@@ -382,7 +378,7 @@ export class WSStreamerCodec implements binary.Codec {
382
378
  return this.lowPerfCodec.encode(payload);
383
379
  }
384
380
 
385
- decode<P>(data: Uint8Array | ArrayBuffer, schema?: ZodSchema<P>): P {
381
+ decode<P extends z.ZodType>(data: Uint8Array | ArrayBuffer, schema?: P): z.infer<P> {
386
382
  const dv = new DataView(data instanceof Uint8Array ? data.buffer : data);
387
383
  const codec = dv.getUint8(0);
388
384
  if (codec === LOW_PER_SPECIAL_CHAR)
@@ -391,6 +387,6 @@ export class WSStreamerCodec implements binary.Codec {
391
387
  type: "data",
392
388
  payload: { frame: this.base.decode(data, 1) },
393
389
  };
394
- return v as P;
390
+ return v as z.infer<P>;
395
391
  }
396
392
  }
@@ -12,7 +12,7 @@ import { describe, expect, test } from "vitest";
12
12
 
13
13
  import { NotFoundError, UnauthorizedError } from "@/errors";
14
14
  import { newClient } from "@/setupspecs";
15
- import { newIndexedPair } from "@/testutil/indexedPair";
15
+ import { newIndexedPair } from "@/testutil/channels";
16
16
  import { secondsLinspace } from "@/testutil/telem";
17
17
  import { randomSeries } from "@/util/telem";
18
18
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { TimeRange } from "@synnaxlabs/x";
12
- import { z } from "zod";
12
+ import { z } from "zod/v4";
13
13
 
14
14
  import { channel } from "@/channel";
15
15
 
@@ -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 { toArray, unique } from "@synnaxlabs/x";
10
+ import { array, unique } from "@synnaxlabs/x";
11
11
  import {
12
12
  MultiSeries,
13
13
  Series,
@@ -18,7 +18,7 @@ import {
18
18
  TimeRange,
19
19
  TimeStamp,
20
20
  } from "@synnaxlabs/x/telem";
21
- import { z } from "zod";
21
+ import { z } from "zod/v4";
22
22
 
23
23
  import { type channel } from "@/channel";
24
24
  import { UnexpectedError, ValidationError } from "@/errors";
@@ -31,7 +31,7 @@ type ColumnType = "key" | "name" | null;
31
31
  export interface Digest extends Record<channel.KeyOrName, SeriesDigest[]> {}
32
32
 
33
33
  const columnType = (columns: channel.PrimitiveParams): ColumnType => {
34
- const arrKeys = toArray(columns);
34
+ const arrKeys = array.toArray(columns);
35
35
  if (arrKeys.length === 0) return null;
36
36
  if (typeof arrKeys[0] === "number") return "key";
37
37
  if (!isNaN(parseInt(arrKeys[0]))) return "key";
@@ -42,7 +42,7 @@ const validateMatchedColsAndSeries = (
42
42
  columns: channel.PrimitiveParams,
43
43
  series: Series[],
44
44
  ): void => {
45
- const colsArr = toArray(columns);
45
+ const colsArr = array.toArray(columns);
46
46
  if (colsArr.length === series.length) return;
47
47
  const colType = columnType(columns);
48
48
  if (columnType === null)
@@ -55,7 +55,7 @@ const validateMatchedColsAndSeries = (
55
55
  );
56
56
  };
57
57
 
58
- export type Crude =
58
+ export type CrudeFrame =
59
59
  | Frame
60
60
  | CrudePayload
61
61
  | Map<channel.KeyOrName, Series[] | Series>
@@ -101,7 +101,7 @@ export class Frame {
101
101
  readonly series: Series[] = [];
102
102
 
103
103
  constructor(
104
- columnsOrData: channel.PrimitiveParams | Crude = [],
104
+ columnsOrData: channel.PrimitiveParams | CrudeFrame = [],
105
105
  series: Series | Series[] = [],
106
106
  ) {
107
107
  if (columnsOrData instanceof Frame) {
@@ -112,7 +112,7 @@ export class Frame {
112
112
 
113
113
  // Construction from a map.
114
114
  if (columnsOrData instanceof Map) {
115
- columnsOrData.forEach((v, k) => this.push(k, ...toArray(v)));
115
+ columnsOrData.forEach((v, k) => this.push(k, ...array.toArray(v)));
116
116
  return;
117
117
  }
118
118
 
@@ -130,8 +130,8 @@ export class Frame {
130
130
  } else
131
131
  Object.entries(columnsOrData).forEach(([k, v]) => {
132
132
  const key = parseInt(k);
133
- if (!isNaN(key)) return this.push(key, ...toArray(v));
134
- this.push(k, ...toArray(v));
133
+ if (!isNaN(key)) return this.push(key, ...array.toArray(v));
134
+ this.push(k, ...array.toArray(v));
135
135
  });
136
136
  return;
137
137
  }
@@ -141,8 +141,8 @@ export class Frame {
141
141
  Array.isArray(columnsOrData) ||
142
142
  ["string", "number"].includes(typeof columnsOrData)
143
143
  ) {
144
- const data_ = toArray(series);
145
- const cols = toArray(columnsOrData) as channel.Keys | channel.Names;
144
+ const data_ = array.toArray(series);
145
+ const cols = array.toArray(columnsOrData) as channel.Keys | channel.Names;
146
146
  validateMatchedColsAndSeries(cols, data_);
147
147
  data_.forEach((d, i) => this.push(cols[i], d));
148
148
  return;
@@ -429,7 +429,7 @@ export class Frame {
429
429
  let str = `Frame{\n`;
430
430
  this.uniqueColumns.forEach((c) => {
431
431
  str += ` ${c}: ${this.get(c)
432
- .series.map((c) => c.toString())
432
+ .series.map((s) => s.toString())
433
433
  .join(",")}\n`;
434
434
  });
435
435
  str += "}";
@@ -439,16 +439,16 @@ export class Frame {
439
439
 
440
440
  export const frameZ = z.object({
441
441
  keys: z.union([
442
- z.null().transform(() => [] as number[]),
442
+ z.null().transform<number[]>(() => []),
443
443
  z.number().array().optional().default([]),
444
444
  ]),
445
445
  series: z.union([
446
- z.null().transform(() => [] as Array<z.infer<typeof Series.crudeZ>>),
446
+ z.null().transform<z.infer<typeof Series.crudeZ>[]>(() => []),
447
447
  Series.crudeZ.array().optional().default([]),
448
448
  ]),
449
449
  });
450
450
 
451
- export interface Payload extends z.output<typeof frameZ> {}
451
+ export interface Payload extends z.infer<typeof frameZ> {}
452
452
 
453
453
  export interface CrudePayload extends z.input<typeof frameZ> {}
454
454
 
@@ -12,7 +12,7 @@ import { describe, expect, test } from "vitest";
12
12
 
13
13
  import { AUTO_SPAN } from "@/framer/iterator";
14
14
  import { newClient } from "@/setupspecs";
15
- import { newIndexedPair } from "@/testutil/indexedPair";
15
+ import { newIndexedPair } from "@/testutil/channels";
16
16
  import { secondsLinspace } from "@/testutil/telem";
17
17
  import { randomSeries } from "@/util/telem";
18
18
 
@@ -17,7 +17,7 @@ import {
17
17
  TimeSpan,
18
18
  TimeStamp,
19
19
  } from "@synnaxlabs/x/telem";
20
- import { z } from "zod";
20
+ import { z } from "zod/v4";
21
21
 
22
22
  import { channel } from "@/channel";
23
23
  import { ReadAdapter } from "@/framer/adapter";
@@ -8,9 +8,9 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { EOF, type Stream } from "@synnaxlabs/freighter";
11
- import { type z } from "zod";
11
+ import { type z } from "zod/v4";
12
12
 
13
- export class StreamProxy<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny> {
13
+ export class StreamProxy<RQ extends z.ZodType, RS extends z.ZodType> {
14
14
  readonly name: string;
15
15
  private readonly stream: Stream<RQ, RS>;
16
16
 
@@ -19,7 +19,7 @@ export class StreamProxy<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny> {
19
19
  this.name = name;
20
20
  }
21
21
 
22
- async receive(): Promise<z.output<RS>> {
22
+ async receive(): Promise<z.infer<RS>> {
23
23
  const [res, err] = await this.stream.receive();
24
24
  if (err != null) throw err;
25
25
  return res;
@@ -35,7 +35,7 @@ export class StreamProxy<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny> {
35
35
  const [res, err] = await this.stream.receive();
36
36
  if (res != null)
37
37
  console.warn(
38
- `${this.name} received unexpected response on closure.
38
+ `${this.name} received unexpected response on ${JSON.stringify(res)} closure.
39
39
  Please report this error to the Synnax team.`,
40
40
  );
41
41
  if (err != null) {