@synnaxlabs/client 0.20.0 → 0.22.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 (262) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.vscode/settings.json +3 -0
  3. package/README.md +13 -0
  4. package/dist/auth/auth.d.ts +7 -6
  5. package/dist/auth/auth.d.ts.map +1 -1
  6. package/dist/channel/client.d.ts +14 -11
  7. package/dist/channel/client.d.ts.map +1 -1
  8. package/dist/channel/creator.d.ts +10 -0
  9. package/dist/channel/creator.d.ts.map +1 -0
  10. package/dist/channel/payload.d.ts +6 -2
  11. package/dist/channel/payload.d.ts.map +1 -1
  12. package/dist/channel/retriever.d.ts +65 -35
  13. package/dist/channel/retriever.d.ts.map +1 -1
  14. package/dist/channel/writer.d.ts +4 -3
  15. package/dist/client.cjs +19 -22
  16. package/dist/client.cjs.map +1 -1
  17. package/dist/client.d.ts +12 -10
  18. package/dist/client.d.ts.map +1 -1
  19. package/dist/client.js +6781 -6675
  20. package/dist/client.js.map +1 -1
  21. package/dist/connection/checker.d.ts +4 -3
  22. package/dist/connection/checker.d.ts.map +1 -1
  23. package/dist/control/authority.d.ts +2 -1
  24. package/dist/control/state.d.ts +6 -4
  25. package/dist/control/state.d.ts.map +1 -1
  26. package/dist/errors.d.ts +24 -20
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/framer/adapter.d.ts +5 -4
  29. package/dist/framer/adapter.d.ts.map +1 -1
  30. package/dist/framer/client.d.ts +12 -12
  31. package/dist/framer/client.d.ts.map +1 -1
  32. package/dist/framer/frame.d.ts +13 -12
  33. package/dist/framer/frame.d.ts.map +1 -1
  34. package/dist/framer/iterator.d.ts +5 -4
  35. package/dist/framer/iterator.d.ts.map +1 -1
  36. package/dist/framer/streamProxy.d.ts +3 -2
  37. package/dist/framer/streamProxy.d.ts.map +1 -1
  38. package/dist/framer/streamer.d.ts +13 -4
  39. package/dist/framer/streamer.d.ts.map +1 -1
  40. package/dist/framer/writer.d.ts +67 -33
  41. package/dist/framer/writer.d.ts.map +1 -1
  42. package/dist/hardware/client.d.ts +4 -3
  43. package/dist/hardware/device/client.d.ts +107 -14
  44. package/dist/hardware/device/client.d.ts.map +1 -1
  45. package/dist/hardware/device/external.d.ts +0 -2
  46. package/dist/hardware/device/external.d.ts.map +1 -1
  47. package/dist/hardware/device/index.d.ts +1 -1
  48. package/dist/hardware/device/index.d.ts.map +1 -1
  49. package/dist/hardware/rack/client.d.ts +43 -20
  50. package/dist/hardware/rack/client.d.ts.map +1 -1
  51. package/dist/hardware/rack/external.d.ts +0 -2
  52. package/dist/hardware/rack/external.d.ts.map +1 -1
  53. package/dist/hardware/task/client.d.ts +197 -14
  54. package/dist/hardware/task/client.d.ts.map +1 -1
  55. package/dist/hardware/task/index.d.ts +1 -1
  56. package/dist/hardware/task/index.d.ts.map +1 -1
  57. package/dist/index.d.ts +4 -3
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/label/client.d.ts +8 -6
  60. package/dist/label/client.d.ts.map +1 -1
  61. package/dist/label/payload.d.ts +2 -1
  62. package/dist/label/retriever.d.ts +3 -2
  63. package/dist/label/writer.d.ts +4 -3
  64. package/dist/ontology/client.d.ts +82 -14
  65. package/dist/ontology/client.d.ts.map +1 -1
  66. package/dist/ontology/external.d.ts +0 -1
  67. package/dist/ontology/external.d.ts.map +1 -1
  68. package/dist/ontology/group/client.d.ts +3 -2
  69. package/dist/ontology/group/client.d.ts.map +1 -1
  70. package/dist/ontology/group/group.d.ts +1 -0
  71. package/dist/ontology/group/payload.d.ts +2 -1
  72. package/dist/ontology/group/writer.d.ts +4 -3
  73. package/dist/ontology/payload.d.ts +71 -60
  74. package/dist/ontology/payload.d.ts.map +1 -1
  75. package/dist/ontology/writer.d.ts +3 -2
  76. package/dist/ranger/active.d.ts +3 -2
  77. package/dist/ranger/alias.d.ts +7 -6
  78. package/dist/ranger/alias.d.ts.map +1 -1
  79. package/dist/ranger/client.d.ts +162 -11
  80. package/dist/ranger/client.d.ts.map +1 -1
  81. package/dist/ranger/external.d.ts +0 -1
  82. package/dist/ranger/external.d.ts.map +1 -1
  83. package/dist/ranger/kv.d.ts +5 -3
  84. package/dist/ranger/kv.d.ts.map +1 -1
  85. package/dist/ranger/payload.d.ts +57 -50
  86. package/dist/ranger/payload.d.ts.map +1 -1
  87. package/dist/ranger/range.d.ts +12 -10
  88. package/dist/ranger/range.d.ts.map +1 -1
  89. package/dist/ranger/writer.d.ts +3 -2
  90. package/dist/setupspecs.d.ts +2 -1
  91. package/dist/signals/observable.d.ts +8 -15
  92. package/dist/signals/observable.d.ts.map +1 -1
  93. package/dist/transport.d.ts +3 -2
  94. package/dist/transport.d.ts.map +1 -1
  95. package/dist/user/payload.d.ts +2 -1
  96. package/dist/util/retrieve.d.ts +24 -0
  97. package/dist/util/retrieve.d.ts.map +1 -0
  98. package/dist/util/retrieve.spec.d.ts +2 -0
  99. package/dist/util/retrieve.spec.d.ts.map +1 -0
  100. package/dist/util/telem.d.ts +2 -1
  101. package/dist/util/telem.d.ts.map +1 -1
  102. package/dist/util/zod.d.ts +4 -0
  103. package/dist/util/zod.d.ts.map +1 -0
  104. package/dist/workspace/client.d.ts +9 -6
  105. package/dist/workspace/client.d.ts.map +1 -1
  106. package/dist/workspace/lineplot/client.d.ts +6 -5
  107. package/dist/workspace/lineplot/client.d.ts.map +1 -1
  108. package/dist/workspace/lineplot/payload.d.ts +3 -2
  109. package/dist/workspace/lineplot/payload.d.ts.map +1 -1
  110. package/dist/workspace/lineplot/retriever.d.ts +3 -2
  111. package/dist/workspace/lineplot/retriever.d.ts.map +1 -1
  112. package/dist/workspace/lineplot/writer.d.ts +7 -6
  113. package/dist/workspace/lineplot/writer.d.ts.map +1 -1
  114. package/dist/workspace/payload.d.ts +3 -2
  115. package/dist/workspace/payload.d.ts.map +1 -1
  116. package/dist/workspace/retriever.d.ts +3 -2
  117. package/dist/workspace/schematic/client.d.ts +18 -0
  118. package/dist/workspace/schematic/client.d.ts.map +1 -0
  119. package/dist/workspace/schematic/external.d.ts.map +1 -0
  120. package/dist/workspace/schematic/index.d.ts +2 -0
  121. package/dist/workspace/schematic/index.d.ts.map +1 -0
  122. package/dist/workspace/{pid → schematic}/payload.d.ts +6 -5
  123. package/dist/workspace/schematic/payload.d.ts.map +1 -0
  124. package/dist/workspace/schematic/retriever.d.ts +10 -0
  125. package/dist/workspace/schematic/retriever.d.ts.map +1 -0
  126. package/dist/workspace/schematic/schematic.spec.d.ts +2 -0
  127. package/dist/workspace/schematic/schematic.spec.d.ts.map +1 -0
  128. package/dist/workspace/{pid → schematic}/writer.d.ts +11 -10
  129. package/dist/workspace/schematic/writer.d.ts.map +1 -0
  130. package/dist/workspace/writer.d.ts +5 -4
  131. package/dist/workspace/writer.d.ts.map +1 -1
  132. package/examples/node/package-lock.json +29 -12
  133. package/examples/node/package.json +2 -2
  134. package/examples/node/streamWrite.js +8 -11
  135. package/package.json +10 -9
  136. package/src/auth/auth.spec.ts +55 -15
  137. package/src/auth/auth.ts +41 -42
  138. package/src/channel/batchRetriever.spec.ts +37 -40
  139. package/src/channel/channel.spec.ts +4 -4
  140. package/src/channel/client.ts +42 -49
  141. package/src/channel/creator.ts +37 -0
  142. package/src/channel/payload.ts +2 -1
  143. package/src/channel/retriever.ts +55 -71
  144. package/src/client.ts +23 -20
  145. package/src/connection/checker.ts +1 -1
  146. package/src/connection/connection.spec.ts +1 -6
  147. package/src/control/state.ts +3 -1
  148. package/src/errors.ts +71 -67
  149. package/src/framer/adapter.spec.ts +33 -1
  150. package/src/framer/adapter.ts +10 -6
  151. package/src/framer/client.ts +13 -12
  152. package/src/framer/frame.spec.ts +1 -1
  153. package/src/framer/frame.ts +9 -6
  154. package/src/framer/iterator.spec.ts +1 -1
  155. package/src/framer/iterator.ts +1 -1
  156. package/src/framer/streamProxy.ts +12 -13
  157. package/src/framer/streamer.spec.ts +1 -1
  158. package/src/framer/streamer.ts +25 -1
  159. package/src/framer/writer.spec.ts +49 -2
  160. package/src/framer/writer.ts +27 -2
  161. package/src/hardware/device/client.ts +155 -28
  162. package/src/hardware/device/device.spec.ts +2 -2
  163. package/src/hardware/device/external.ts +0 -2
  164. package/src/hardware/device/index.ts +2 -2
  165. package/src/hardware/rack/client.ts +139 -56
  166. package/src/hardware/rack/external.ts +0 -2
  167. package/src/hardware/rack/rack.spec.ts +20 -1
  168. package/src/hardware/task/client.ts +324 -31
  169. package/src/hardware/task/index.ts +1 -1
  170. package/src/hardware/task/task.spec.ts +41 -0
  171. package/src/index.ts +3 -4
  172. package/src/label/client.ts +3 -2
  173. package/src/label/retriever.ts +1 -1
  174. package/src/label/writer.ts +1 -1
  175. package/src/ontology/client.ts +195 -41
  176. package/src/ontology/external.ts +0 -1
  177. package/src/ontology/group/client.ts +1 -2
  178. package/src/ontology/group/payload.ts +1 -1
  179. package/src/ontology/ontology.spec.ts +16 -0
  180. package/src/ontology/payload.ts +22 -13
  181. package/src/ranger/active.ts +5 -5
  182. package/src/ranger/alias.ts +2 -2
  183. package/src/ranger/client.ts +68 -17
  184. package/src/ranger/external.ts +0 -1
  185. package/src/ranger/kv.ts +6 -1
  186. package/src/ranger/payload.ts +6 -4
  187. package/src/ranger/range.ts +4 -1
  188. package/src/ranger/ranger.spec.ts +24 -2
  189. package/src/signals/observable.ts +24 -63
  190. package/src/transport.ts +2 -1
  191. package/src/util/retrieve.spec.ts +56 -0
  192. package/src/util/retrieve.ts +103 -0
  193. package/src/util/telem.ts +1 -1
  194. package/src/util/zod.ts +4 -0
  195. package/src/workspace/client.ts +6 -4
  196. package/src/workspace/lineplot/client.ts +3 -3
  197. package/src/workspace/lineplot/linePlot.spec.ts +11 -11
  198. package/src/workspace/lineplot/payload.ts +1 -1
  199. package/src/workspace/lineplot/retriever.ts +5 -13
  200. package/src/workspace/lineplot/writer.ts +8 -7
  201. package/src/workspace/payload.ts +6 -3
  202. package/src/workspace/retriever.ts +1 -1
  203. package/src/workspace/{pid → schematic}/client.ts +10 -10
  204. package/src/workspace/{pid → schematic}/external.ts +2 -2
  205. package/src/workspace/{pid → schematic}/index.ts +1 -1
  206. package/src/workspace/{pid → schematic}/payload.ts +4 -4
  207. package/src/workspace/{pid → schematic}/retriever.ts +10 -10
  208. package/src/workspace/{pid/pid.spec.ts → schematic/schematic.spec.ts} +35 -35
  209. package/src/workspace/{pid → schematic}/writer.ts +26 -25
  210. package/src/workspace/workspace.spec.ts +7 -7
  211. package/src/workspace/writer.ts +8 -2
  212. package/dist/hardware/device/payload.d.ts +0 -30
  213. package/dist/hardware/device/payload.d.ts.map +0 -1
  214. package/dist/hardware/device/retriever.d.ts +0 -10
  215. package/dist/hardware/device/retriever.d.ts.map +0 -1
  216. package/dist/hardware/device/writer.d.ts +0 -9
  217. package/dist/hardware/device/writer.d.ts.map +0 -1
  218. package/dist/hardware/rack/payload.d.ts +0 -26
  219. package/dist/hardware/rack/payload.d.ts.map +0 -1
  220. package/dist/hardware/rack/retriever.d.ts +0 -10
  221. package/dist/hardware/rack/retriever.d.ts.map +0 -1
  222. package/dist/hardware/rack/writer.d.ts +0 -9
  223. package/dist/hardware/rack/writer.d.ts.map +0 -1
  224. package/dist/hardware/task/external.d.ts +0 -4
  225. package/dist/hardware/task/external.d.ts.map +0 -1
  226. package/dist/hardware/task/payload.d.ts +0 -42
  227. package/dist/hardware/task/payload.d.ts.map +0 -1
  228. package/dist/hardware/task/retriever.d.ts +0 -29
  229. package/dist/hardware/task/retriever.d.ts.map +0 -1
  230. package/dist/hardware/task/writer.d.ts +0 -9
  231. package/dist/hardware/task/writer.d.ts.map +0 -1
  232. package/dist/ontology/retriever.d.ts +0 -13
  233. package/dist/ontology/retriever.d.ts.map +0 -1
  234. package/dist/ontology/signals.d.ts +0 -30
  235. package/dist/ontology/signals.d.ts.map +0 -1
  236. package/dist/ranger/retriever.d.ts +0 -11
  237. package/dist/ranger/retriever.d.ts.map +0 -1
  238. package/dist/workspace/pid/client.d.ts +0 -17
  239. package/dist/workspace/pid/client.d.ts.map +0 -1
  240. package/dist/workspace/pid/external.d.ts.map +0 -1
  241. package/dist/workspace/pid/index.d.ts +0 -2
  242. package/dist/workspace/pid/index.d.ts.map +0 -1
  243. package/dist/workspace/pid/payload.d.ts.map +0 -1
  244. package/dist/workspace/pid/pid.spec.d.ts +0 -2
  245. package/dist/workspace/pid/pid.spec.d.ts.map +0 -1
  246. package/dist/workspace/pid/retriever.d.ts +0 -9
  247. package/dist/workspace/pid/retriever.d.ts.map +0 -1
  248. package/dist/workspace/pid/writer.d.ts.map +0 -1
  249. package/src/hardware/device/payload.ts +0 -27
  250. package/src/hardware/device/retriever.ts +0 -60
  251. package/src/hardware/device/writer.ts +0 -59
  252. package/src/hardware/rack/payload.ts +0 -26
  253. package/src/hardware/rack/retriever.ts +0 -68
  254. package/src/hardware/rack/writer.ts +0 -59
  255. package/src/hardware/task/external.ts +0 -12
  256. package/src/hardware/task/payload.ts +0 -40
  257. package/src/hardware/task/retriever.ts +0 -70
  258. package/src/hardware/task/writer.ts +0 -65
  259. package/src/ontology/retriever.ts +0 -91
  260. package/src/ontology/signals.ts +0 -139
  261. package/src/ranger/retriever.ts +0 -50
  262. /package/dist/workspace/{pid → schematic}/external.d.ts +0 -0
package/src/client.ts CHANGED
@@ -7,7 +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 { TimeSpan, TimeStamp, URL } from "@synnaxlabs/x";
10
+ import { TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
11
+ import { URL } from "@synnaxlabs/x/url";
11
12
  import { z } from "zod";
12
13
 
13
14
  import { auth } from "@/auth";
@@ -26,8 +27,20 @@ import { Transport } from "@/transport";
26
27
  import { workspace } from "@/workspace";
27
28
 
28
29
  export const synnaxPropsZ = z.object({
29
- host: z.string().min(1),
30
- port: z.number().or(z.string()),
30
+ host: z
31
+ .string({
32
+ required_error: "Host is required",
33
+ })
34
+ .min(1, "Host is required"),
35
+ port: z
36
+ .number({
37
+ required_error: "Port is required",
38
+ })
39
+ .or(
40
+ z.string({
41
+ required_error: "Port is required",
42
+ }),
43
+ ),
31
44
  username: z.string().optional(),
32
45
  password: z.string().optional(),
33
46
  connectivityPollFrequency: TimeSpan.z.default(TimeSpan.seconds(30)),
@@ -105,36 +118,26 @@ export default class Synnax extends framer.Client {
105
118
  props.name,
106
119
  );
107
120
  this.ontology = new ontology.Client(transport.unary, this);
108
- const rangeRetriever = new ranger.Retriever(transport.unary);
109
121
  const rangeWriter = new ranger.Writer(this.transport.unary);
110
122
  this.labels = new label.Client(this.transport.unary, this);
111
123
  this.ranges = new ranger.Client(
112
124
  this,
113
- rangeRetriever,
114
125
  rangeWriter,
115
126
  this.transport.unary,
116
127
  chRetriever,
117
128
  this.labels,
118
129
  );
119
130
  this.workspaces = new workspace.Client(this.transport.unary);
120
- const devices = new device.Client(
121
- new device.Retriever(this.transport.unary),
122
- new device.Writer(this.transport.unary),
123
- this,
124
- );
125
- const taskRetriever = new task.Retriever(this.transport.unary);
126
- const taskWriter = new task.Writer(this.transport.unary);
127
- const tasks = new task.Client(taskRetriever, taskWriter);
128
- const racks = new rack.Client(
129
- new rack.Retriever(this.transport.unary),
130
- new rack.Writer(this.transport.unary),
131
- this,
132
- taskWriter,
133
- taskRetriever,
134
- );
131
+ const devices = new device.Client(this.transport.unary, this);
132
+ const tasks = new task.Client(this.transport.unary, this);
133
+ const racks = new rack.Client(this.transport.unary, this, tasks);
135
134
  this.hardware = new hardware.Client(tasks, racks, devices);
136
135
  }
137
136
 
137
+ get key(): string {
138
+ return this.createdAt.valueOf().toString();
139
+ }
140
+
138
141
  close(): void {
139
142
  this.connectivity.stopChecking();
140
143
  }
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import type { UnaryClient } from "@synnaxlabs/freighter";
11
- import { TimeSpan } from "@synnaxlabs/x";
11
+ import { TimeSpan } from "@synnaxlabs/x/telem";
12
12
  import { z } from "zod";
13
13
 
14
14
  const STATUSES = ["disconnected", "connecting", "connected", "failed"] as const;
@@ -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 { URL } from "@synnaxlabs/x";
10
+ import { URL } from "@synnaxlabs/x/url";
11
11
  import { describe, expect, it } from "vitest";
12
12
 
13
13
  import { auth } from "@/auth";
@@ -22,13 +22,8 @@ describe("connectivity", () => {
22
22
  username: "synnax",
23
23
  password: "seldon",
24
24
  });
25
- await client.authenticating;
26
- expect(client.authenticated).toBeTruthy();
27
-
28
25
  transport.use(client.middleware());
29
-
30
26
  const connectivity = new Checker(transport.unary);
31
-
32
27
  await connectivity.check();
33
28
  expect(connectivity.state.status).toEqual("connected");
34
29
  });
@@ -7,7 +7,9 @@
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 Destructor, binary, observe } from "@synnaxlabs/x";
10
+ import { binary } from "@synnaxlabs/x/binary";
11
+ import { type Destructor } from "@synnaxlabs/x/destructor";
12
+ import { observe } from "@synnaxlabs/x/observe";
11
13
  import { z } from "zod";
12
14
 
13
15
  import { type Key as ChannelKey } from "@/channel/payload";
package/src/errors.ts CHANGED
@@ -8,77 +8,58 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import {
11
- BaseTypedError,
12
11
  type Middleware,
13
12
  registerError,
14
13
  Unreachable,
15
14
  type ErrorPayload,
16
15
  } from "@synnaxlabs/freighter";
17
16
 
18
- const _FREIGHTER_EXCEPTION_PREFIX = "sy.api.";
19
-
20
- enum APIErrorType {
21
- General = _FREIGHTER_EXCEPTION_PREFIX + "general",
22
- Parse = _FREIGHTER_EXCEPTION_PREFIX + "parse",
23
- Auth = _FREIGHTER_EXCEPTION_PREFIX + "auth",
24
- Unexpected = _FREIGHTER_EXCEPTION_PREFIX + "unexpected",
25
- Validation = _FREIGHTER_EXCEPTION_PREFIX + "validation",
26
- Query = _FREIGHTER_EXCEPTION_PREFIX + "query",
27
- Route = _FREIGHTER_EXCEPTION_PREFIX + "route",
28
- }
17
+ const _FREIGHTER_EXCEPTION_PREFIX = "sy.";
29
18
 
30
19
  export interface Field {
31
20
  field: string;
32
21
  message: string;
33
22
  }
34
23
 
35
- class BaseError extends BaseTypedError {
36
- constructor(message: string) {
37
- super(message, _FREIGHTER_EXCEPTION_PREFIX);
38
- }
39
- }
40
-
41
24
  /**
42
25
  * Raised when a validation error occurs.
43
26
  */
44
- export class ValidationError extends BaseError {
45
- fields: Field[];
46
-
47
- constructor(fieldsOrMessage: string | Field[] | Field) {
48
- if (typeof fieldsOrMessage === "string") {
49
- super(fieldsOrMessage);
50
- this.fields = [];
51
- } else if (Array.isArray(fieldsOrMessage)) {
52
- super(
53
- fieldsOrMessage.map((field) => `${field.field}: ${field.message}`).join("\n"),
54
- );
55
- this.fields = fieldsOrMessage;
56
- } else {
57
- super(`${fieldsOrMessage.field}: ${fieldsOrMessage.message}`);
58
- this.fields = [fieldsOrMessage];
59
- }
60
- }
27
+ export class ValidationError extends Error {
28
+ static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "validation";
61
29
  }
62
30
 
63
- /**
64
- * GeneralError is raised when a general error occurs.
65
- */
66
- export class GeneralError extends BaseError {}
31
+ export class FieldError extends ValidationError {
32
+ static readonly TYPE = ValidationError.TYPE + ".field";
33
+ readonly field: string;
34
+ readonly message: string;
35
+
36
+ constructor(field: string, message: string) {
37
+ super(field + ": " + message);
38
+ this.field = field;
39
+ this.message = message;
40
+ }
41
+ }
67
42
 
68
43
  /**
69
- * ParseError is raised when a parse error occurs.
44
+ * AuthError is raised when an authentication error occurs.
70
45
  */
71
- export class ParseError extends BaseError {}
46
+ export class AuthError extends Error {
47
+ static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "auth";
48
+ }
72
49
 
73
50
  /**
74
- * AuthError is raised when an authentication error occurs.
51
+ * InvalidTokenError is raised when an authentication token is invalid.
75
52
  */
76
- export class AuthError extends BaseError {}
53
+ export class InvalidTokenError extends AuthError {
54
+ static readonly TYPE = AuthError.TYPE + ".invalid-token";
55
+ }
77
56
 
78
57
  /**
79
58
  * UnexpectedError is raised when an unexpected error occurs.
80
59
  */
81
- export class UnexpectedError extends BaseError {
60
+ export class UnexpectedError extends Error {
61
+ static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "unexpected";
62
+
82
63
  constructor(message: string) {
83
64
  super(`
84
65
  Unexpected error encountered:
@@ -93,16 +74,23 @@ export class UnexpectedError extends BaseError {
93
74
  /**
94
75
  * QueryError is raised when a query error occurs.
95
76
  */
96
- export class QueryError extends BaseError {}
77
+ export class QueryError extends Error {
78
+ static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "query";
79
+ }
97
80
 
98
- export class NotFoundError extends QueryError {}
81
+ export class NotFoundError extends QueryError {
82
+ static readonly TYPE = QueryError.TYPE + ".not_found";
83
+ }
99
84
 
100
- export class MultipleFoundError extends QueryError {}
85
+ export class MultipleFoundError extends QueryError {
86
+ static readonly TYPE = QueryError.TYPE + ".multiple_results";
87
+ }
101
88
 
102
89
  /**
103
90
  * RouteError is raised when a routing error occurs.
104
91
  */
105
- export class RouteError extends BaseError {
92
+ export class RouteError extends Error {
93
+ static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "route";
106
94
  path: string;
107
95
 
108
96
  constructor(message: string, path: string) {
@@ -114,28 +102,44 @@ export class RouteError extends BaseError {
114
102
  /**
115
103
  * Raised when time-series data is not contiguous.
116
104
  */
117
- export class ContiguityError extends BaseError {}
105
+ export class ContiguityError extends Error {}
118
106
 
119
107
  const decode = (payload: ErrorPayload): Error | null => {
120
108
  if (!payload.type.startsWith(_FREIGHTER_EXCEPTION_PREFIX)) return null;
121
- switch (payload.type) {
122
- case APIErrorType.General:
123
- return new GeneralError(payload.data);
124
- case APIErrorType.Parse:
125
- return new ParseError(payload.data);
126
- case APIErrorType.Auth:
127
- return new AuthError(payload.data);
128
- case APIErrorType.Unexpected:
129
- return new UnexpectedError(payload.data);
130
- case APIErrorType.Validation:
131
- return new ValidationError(payload.data);
132
- case APIErrorType.Query:
133
- return new QueryError(payload.data);
134
- case APIErrorType.Route:
135
- return new RouteError(payload.data, payload.data);
136
- default:
137
- return new UnexpectedError(payload.data);
109
+ if (payload.type.startsWith(ValidationError.TYPE)) {
110
+ if (payload.type === FieldError.TYPE) {
111
+ const values = payload.data.split(": ");
112
+ if (values.length < 2) {
113
+ return new ValidationError(payload.data);
114
+ }
115
+ return new FieldError(values[0], values[1]);
116
+ }
117
+ return new ValidationError(payload.data);
118
+ }
119
+
120
+ if (payload.type.startsWith(AuthError.TYPE)) {
121
+ if (payload.type.startsWith(InvalidTokenError.TYPE))
122
+ return new InvalidTokenError(payload.data);
123
+ return new AuthError(payload.data);
138
124
  }
125
+
126
+ if (payload.type.startsWith(UnexpectedError.TYPE)) {
127
+ return new UnexpectedError(payload.data);
128
+ }
129
+
130
+ if (payload.type.startsWith(QueryError.TYPE)) {
131
+ if (payload.type.startsWith(NotFoundError.TYPE))
132
+ return new NotFoundError(payload.data);
133
+ if (payload.type.startsWith(MultipleFoundError.TYPE))
134
+ return new MultipleFoundError(payload.data);
135
+ return new QueryError(payload.data);
136
+ }
137
+
138
+ if (payload.type.startsWith(RouteError.TYPE)) {
139
+ return new RouteError(payload.data, payload.data);
140
+ }
141
+
142
+ return new UnexpectedError(payload.data);
139
143
  };
140
144
 
141
145
  const encode = (): ErrorPayload => {
@@ -149,7 +153,7 @@ export const validateFieldNotNull = (
149
153
  value: unknown,
150
154
  message: string = "must be provided",
151
155
  ): void => {
152
- if (value == null) throw new ValidationError({ field: key, message });
156
+ if (value == null) throw new FieldError(key, message);
153
157
  };
154
158
 
155
159
  export const errorsMiddleware: Middleware = async (ctx, next) => {
@@ -1,4 +1,4 @@
1
- import { DataType, Series, TimeStamp } from "@synnaxlabs/x";
1
+ import { DataType, Series, TimeStamp } from "@synnaxlabs/x/telem";
2
2
  import { beforeAll, describe, expect, it } from "vitest";
3
3
 
4
4
  import { type channel } from "@/channel";
@@ -115,4 +115,36 @@ describe("WriteFrameAdapter", () => {
115
115
  expect(res.get(timeCh.key)).toHaveLength(1);
116
116
  expect(res.get(timeCh.key).at(0)).toEqual(ts);
117
117
  });
118
+
119
+ it("should correctly adapt a name and JSON value", async () => {
120
+ const jsonChannel = await client.channels.create({
121
+ name: `json-${Math.random()}-${TimeStamp.now().toString()}`,
122
+ dataType: DataType.JSON,
123
+ virtual: true,
124
+ });
125
+ const adapter = await WriteFrameAdapter.open(client.channels.retriever, [
126
+ jsonChannel.key,
127
+ ]);
128
+ const res = await adapter.adapt(jsonChannel.name, [{ dog: "blue" }]);
129
+ expect(res.columns).toHaveLength(1);
130
+ expect(res.series).toHaveLength(1);
131
+ expect(res.get(jsonChannel.key)).toHaveLength(1);
132
+ expect(res.get(jsonChannel.key).at(0)).toEqual({ dog: "blue" });
133
+ });
134
+
135
+ it("should correctly adapt a name and a json typed series", async () => {
136
+ const jsonChannel = await client.channels.create({
137
+ name: `json-${Math.random()}-${TimeStamp.now().toString()}`,
138
+ dataType: DataType.JSON,
139
+ virtual: true,
140
+ });
141
+ const adapter = await WriteFrameAdapter.open(client.channels.retriever, [
142
+ jsonChannel.key,
143
+ ]);
144
+ const res = await adapter.adapt(jsonChannel.name, new Series([{ dog: "blue" }]));
145
+ expect(res.columns).toHaveLength(1);
146
+ expect(res.series).toHaveLength(1);
147
+ expect(res.get(jsonChannel.key)).toHaveLength(1);
148
+ expect(res.get(jsonChannel.key).at(0)).toEqual({ dog: "blue" });
149
+ });
118
150
  });
@@ -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 { type CrudeSeries, Series } from "@synnaxlabs/x";
10
+ import { type CrudeSeries, Series } from "@synnaxlabs/x/telem";
11
11
 
12
12
  import {
13
13
  type Key,
@@ -16,7 +16,11 @@ import {
16
16
  type KeyOrName,
17
17
  type Payload,
18
18
  } from "@/channel/payload";
19
- import { type Retriever, analyzeParams, retrieveRequired } from "@/channel/retriever";
19
+ import {
20
+ type Retriever,
21
+ analyzeChannelParams,
22
+ retrieveRequired,
23
+ } from "@/channel/retriever";
20
24
  import { ValidationError } from "@/errors";
21
25
  import { type CrudeFrame, Frame } from "@/framer/frame";
22
26
 
@@ -38,10 +42,10 @@ export class ReadFrameAdapter {
38
42
  }
39
43
 
40
44
  async update(channels: Params): Promise<void> {
41
- const { variant, normalized } = analyzeParams(channels);
45
+ const { variant, normalized } = analyzeChannelParams(channels);
42
46
  if (variant === "keys") {
43
47
  this.adapter = null;
44
- this.keys = normalized;
48
+ this.keys = normalized as Key[];
45
49
  return;
46
50
  }
47
51
  const fetched = await this.retriever.retrieve(normalized);
@@ -111,12 +115,12 @@ export class WriteFrameAdapter {
111
115
  Received a single channel name or key but no series.
112
116
  `);
113
117
  if (Array.isArray(series)) {
114
- if (series.length > 1) {
118
+ if (series.some((s) => s instanceof Series || Array.isArray(s))) {
115
119
  throw new ValidationError(`
116
120
  Received a single channel name or key but multiple series.
117
121
  `);
118
122
  }
119
- series = series[0] as CrudeSeries;
123
+ series = series as CrudeSeries;
120
124
  }
121
125
  const pld = await this.fetchChannel(columnsOrData);
122
126
  const s = new Series({ data: series as CrudeSeries, dataType: pld.dataType });
@@ -13,10 +13,10 @@ import {
13
13
  type CrudeSeries,
14
14
  type CrudeTimeRange,
15
15
  type MultiSeries,
16
- } from "@synnaxlabs/x";
16
+ } from "@synnaxlabs/x/telem";
17
17
 
18
- import { type KeysOrNames, type KeyOrName, type Params } from "@/channel/payload";
19
- import { type Retriever, analyzeParams } from "@/channel/retriever";
18
+ import { KeysOrNames, type KeyOrName, type Params } from "@/channel/payload";
19
+ import { type Retriever, analyzeChannelParams } from "@/channel/retriever";
20
20
  import { Frame } from "@/framer/frame";
21
21
  import { Iterator } from "@/framer/iterator";
22
22
  import { Streamer, type StreamerConfig } from "@/framer/streamer";
@@ -45,12 +45,13 @@ export class Client {
45
45
  /**
46
46
  * Opens a new writer on the given channels.
47
47
  *
48
- * @param keys - The keys of the channels to write to. A writer cannot write to
49
- * a channel that is not in this list. See the {@link RecordWriter} documentation
50
- * for more information.
48
+ * @param config - The configuration for the created writer, see documentation for
49
+ * writerConfig for more detail.
51
50
  * @returns a new {@link RecordWriter}.
52
51
  */
53
- async openWriter(config: WriterConfig): Promise<Writer> {
52
+ async openWriter(config: WriterConfig | Params): Promise<Writer> {
53
+ if (Array.isArray(config) || typeof config !== "object")
54
+ config = { channels: config as Params };
54
55
  return await Writer._open(this.retriever, this.stream, config);
55
56
  }
56
57
 
@@ -76,12 +77,12 @@ export class Client {
76
77
  * and then will start reading new values.
77
78
  *
78
79
  */
79
- async openStreamer(config: StreamerConfig): Promise<Streamer>;
80
+ async openStreamer(config: StreamerConfig | Params): Promise<Streamer>;
80
81
 
81
82
  async openStreamer(config: StreamerConfig | Params): Promise<Streamer> {
82
- const isObject = typeof config === "object";
83
- if (Array.isArray(config) || !isObject) config = { channels: config as Params };
84
- return await Streamer._open(this.retriever, this.stream, config as StreamerConfig);
83
+ if (Array.isArray(config) || typeof config !== "object")
84
+ config = { channels: config as Params };
85
+ return await Streamer._open(this.retriever, this.stream, config);
85
86
  }
86
87
 
87
88
  async write(
@@ -148,7 +149,7 @@ export class Client {
148
149
  async read(tr: CrudeTimeRange, channels: Params): Promise<Frame>;
149
150
 
150
151
  async read(tr: CrudeTimeRange, channels: Params): Promise<MultiSeries | Frame> {
151
- const { single } = analyzeParams(channels);
152
+ const { single } = analyzeChannelParams(channels);
152
153
  const fr = await this.readFrame(tr, channels);
153
154
  if (single) return fr.get(channels as KeyOrName);
154
155
  return fr;
@@ -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 { DataType, Series, TimeRange } from "@synnaxlabs/x";
10
+ import { DataType, Series, TimeRange } from "@synnaxlabs/x/telem";
11
11
  import { describe, expect, it, test } from "vitest";
12
12
 
13
13
  import { framer } from "@/framer";
@@ -11,13 +11,13 @@ import {
11
11
  Size,
12
12
  Series,
13
13
  TimeRange,
14
- toArray,
15
14
  DataType,
16
- unique,
17
15
  TimeStamp,
18
16
  type TelemValue,
19
17
  MultiSeries,
20
- } from "@synnaxlabs/x";
18
+ } from "@synnaxlabs/x/telem";
19
+ import { toArray } from "@synnaxlabs/x/toArray";
20
+ import { unique } from "@synnaxlabs/x/unique";
21
21
  import { z } from "zod";
22
22
 
23
23
  import {
@@ -142,8 +142,8 @@ export class Frame {
142
142
  }
143
143
 
144
144
  throw new ValidationError(
145
- `[Frame] - invalid frame construction parameters. data parameter ust be a frame
146
- payload, a list of lazy arrays, a lazy array, a map, or a record keyed by channel
145
+ `[Frame] - invalid frame construction parameters. data parameter ust be a frame
146
+ payload, a list of lazy arrays, a lazy array, a map, or a record keyed by channel
147
147
  name. keys parameter must be a set of channel keys or channel names.`,
148
148
  );
149
149
  }
@@ -398,7 +398,10 @@ export class Frame {
398
398
 
399
399
  export const series = z.object({
400
400
  timeRange: TimeRange.z.optional(),
401
- alignment: z.number().optional(),
401
+ alignment: z
402
+ .bigint()
403
+ .or(z.string().transform((s) => BigInt(s)))
404
+ .optional(),
402
405
  dataType: DataType.z,
403
406
  data: z.string().transform(
404
407
  (s) =>
@@ -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 { DataType, Rate, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x";
10
+ import { DataType, Rate, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
11
11
  import { describe, test, expect } from "vitest";
12
12
 
13
13
  import { type channel } from "@/channel";
@@ -15,7 +15,7 @@ import {
15
15
  TimeSpan,
16
16
  TimeStamp,
17
17
  type CrudeTimeRange,
18
- } from "@synnaxlabs/x";
18
+ } from "@synnaxlabs/x/telem";
19
19
  import { z } from "zod";
20
20
 
21
21
  import { type Params } from "@/channel/payload";
@@ -33,19 +33,18 @@ export class StreamProxy<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny> {
33
33
 
34
34
  async closeAndAck(): Promise<void> {
35
35
  this.stream.closeSend();
36
- const [res, err] = await this.stream.receive();
37
- if (res != null)
38
- throw new UnexpectedError(
39
- `${this.name} received unexpected response on closure.
40
- Please report this error to the Synnax team.`,
41
- );
42
- if (err == null)
43
- throw new UnexpectedError(
44
- `${this.name} received unexpected null error on closure.
45
- Please report this error to Synnax team.
46
- `,
47
- );
48
- if (!(err instanceof EOF)) throw err;
36
+ while (true) {
37
+ const [res, err] = await this.stream.receive();
38
+ if (res != null)
39
+ console.warn(
40
+ `${this.name} received unexpected response on closure.
41
+ Please report this error to the Synnax team. ${JSON.stringify(res)}`,
42
+ );
43
+ if (err != null) {
44
+ if (err instanceof EOF) return;
45
+ throw err;
46
+ }
47
+ }
49
48
  }
50
49
 
51
50
  closeSend(): void {
@@ -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 { DataType, Rate, TimeStamp } from "@synnaxlabs/x";
11
10
  import { describe, test, expect, it } from "vitest";
11
+ import { DataType, Rate, TimeStamp } from "@synnaxlabs/x/telem";
12
12
 
13
13
  import { type channel } from "@/channel";
14
14
  import { newClient } from "@/setupspecs";
@@ -8,7 +8,8 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { errorZ, type Stream, type StreamClient } from "@synnaxlabs/freighter";
11
- import { TimeStamp, type CrudeTimeStamp } from "@synnaxlabs/x";
11
+ import { observe } from "@synnaxlabs/x";
12
+ import { TimeStamp, type CrudeTimeStamp } from "@synnaxlabs/x/telem";
12
13
  import { z } from "zod";
13
14
 
14
15
  import { type Key, type Params } from "@/channel/payload";
@@ -88,3 +89,26 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
88
89
  return this;
89
90
  }
90
91
  }
92
+
93
+ export class ObservableStreamer<V = Frame>
94
+ extends observe.Observer<Frame, V>
95
+ implements observe.ObservableAsyncCloseable<V>
96
+ {
97
+ private readonly streamer: Streamer;
98
+ private readonly closePromise: Promise<void>;
99
+
100
+ constructor(streamer: Streamer, transform?: observe.Transform<Frame, V>) {
101
+ super(transform);
102
+ this.streamer = streamer;
103
+ this.closePromise = this.stream();
104
+ }
105
+
106
+ async close(): Promise<void> {
107
+ this.streamer.close();
108
+ await this.closePromise;
109
+ }
110
+
111
+ private async stream(): Promise<void> {
112
+ for await (const frame of this.streamer) this.notify(frame);
113
+ }
114
+ }