@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
@@ -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 Series, TimeRange } from "@synnaxlabs/x";
10
+ import { type Series, TimeRange } from "@synnaxlabs/x/telem";
11
11
 
12
12
  import { type Key, type Params, type Name } from "@/channel/payload";
13
13
  import { type Retriever as ChannelRetriever } from "@/channel/retriever";
@@ -28,6 +28,7 @@ export class Range {
28
28
  name: string;
29
29
  readonly kv: KV;
30
30
  readonly timeRange: TimeRange;
31
+ readonly color: string | undefined;
31
32
  readonly channels: ChannelRetriever;
32
33
  private readonly aliaser: Aliaser;
33
34
  private readonly frameClient: framer.Client;
@@ -37,6 +38,7 @@ export class Range {
37
38
  name: string,
38
39
  timeRange: TimeRange = TimeRange.ZERO,
39
40
  key: string,
41
+ color: string | undefined,
40
42
  _frameClient: framer.Client,
41
43
  _kv: KV,
42
44
  _aliaser: Aliaser,
@@ -47,6 +49,7 @@ export class Range {
47
49
  this.name = name;
48
50
  this.timeRange = timeRange;
49
51
  this.frameClient = _frameClient;
52
+ this.color = color;
50
53
  this.kv = _kv;
51
54
  this.aliaser = _aliaser;
52
55
  this.channels = _channels;
@@ -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, TimeSpan, TimeStamp } from "@synnaxlabs/x";
10
+ import { DataType, Rate, TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
11
11
  import { describe, expect, it } from "vitest";
12
12
 
13
13
  import { QueryError } from "@/errors";
@@ -23,9 +23,11 @@ describe("Ranger", () => {
23
23
  const range = await client.ranges.create({
24
24
  name: "My New One Second Range",
25
25
  timeRange,
26
+ color: "#E774D0",
26
27
  });
27
28
  expect(range.key).not.toHaveLength(0);
28
29
  expect(timeRange).toEqual(range.timeRange);
30
+ expect(range.color).toEqual("#E774D0");
29
31
  });
30
32
  it("should create multiple ranges", async () => {
31
33
  const ranges: NewPayload[] = [
@@ -95,6 +97,16 @@ describe("Ranger", () => {
95
97
  expect(retrieved.length).toBeGreaterThan(0);
96
98
  expect(retrieved[0].name).toEqual(range.name);
97
99
  });
100
+ it("should retrieve ranges that overlap with the given time range", async () => {
101
+ const timeRange = TimeStamp.hours(500).spanRange(TimeSpan.seconds(1));
102
+ const range = await client.ranges.create({
103
+ name: "My New One Second Range",
104
+ timeRange,
105
+ });
106
+ const retrieved = await client.ranges.retrieve(timeRange);
107
+ expect(retrieved.length).toBeGreaterThan(0);
108
+ expect(retrieved.map((r) => r.key)).toContain(range.key);
109
+ });
98
110
  });
99
111
 
100
112
  describe("KV", () => {
@@ -116,7 +128,17 @@ describe("Ranger", () => {
116
128
  timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
117
129
  });
118
130
  await rng.kv.set({ foo: "bar", baz: "qux" });
119
- const res = await rng.kv.get(["foo", "baz"]);
131
+ const res = await rng.kv.list();
132
+ expect(res).toEqual({ foo: "bar", baz: "qux" });
133
+ });
134
+
135
+ it("should list all keys", async () => {
136
+ const rng = await client.ranges.create({
137
+ name: "My New One Second Range",
138
+ timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
139
+ });
140
+ await rng.kv.set({ foo: "bar", baz: "qux" });
141
+ const res = await rng.kv.list();
120
142
  expect(res).toEqual({ foo: "bar", baz: "qux" });
121
143
  });
122
144
  });
@@ -7,74 +7,35 @@
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 { observe, type Destructor, type change, type Series } from "@synnaxlabs/x";
10
+ import { type change } from "@synnaxlabs/x/change";
11
+ import { type observe } from "@synnaxlabs/x/observe";
12
+ import { type Series } from "@synnaxlabs/x/telem";
11
13
 
12
14
  import { type channel } from "@/channel";
13
- import { type framer } from "@/framer";
15
+ import { framer } from "@/framer";
14
16
 
15
17
  export type Decoder<K, V> = (
16
18
  variant: change.Variant,
17
19
  data: Series,
18
20
  ) => Array<change.Change<K, V>>;
19
21
 
20
- export class Observable<K, V>
21
- implements observe.Observable<Array<change.Change<K, V>>>
22
- {
23
- private readonly streamer: framer.Streamer;
24
- private readonly decoder: Decoder<K, V>;
25
- private readonly base: observe.Observer<Array<change.Change<K, V>>>;
26
- private readonly closePromise: Promise<void>;
27
- private readonly deleteChannel?: channel.Key | channel.Name;
28
- private readonly setChannel?: channel.Key | channel.Name;
29
-
30
- private constructor(
31
- streamer: framer.Streamer,
32
- ecd: Decoder<K, V>,
33
- setChannel?: channel.Key | channel.Name,
34
- deleteChannel?: channel.Key | channel.Name,
35
- ) {
36
- this.streamer = streamer;
37
- this.decoder = ecd;
38
- this.base = new observe.Observer<Array<change.Change<K, V>>>();
39
- this.closePromise = this.stream();
40
- this.deleteChannel = deleteChannel;
41
- this.setChannel = setChannel;
42
- }
43
-
44
- onChange(handler: observe.Handler<Array<change.Change<K, V>>>): Destructor {
45
- return this.base.onChange(handler);
46
- }
47
-
48
- async close(): Promise<void> {
49
- this.streamer.close();
50
- return await this.closePromise;
51
- }
52
-
53
- async stream(): Promise<void> {
54
- for await (const frame of this.streamer) {
55
- const changes: Array<change.Change<K, V>> = [];
56
- if (this.deleteChannel != null) {
57
- const deletes = frame.get(this.deleteChannel);
58
- changes.push(...deletes.series.flatMap((s) => this.decoder("delete", s)));
59
- }
60
- if (this.setChannel != null) {
61
- const sets = frame.get(this.setChannel);
62
- changes.push(...sets.series.flatMap((s) => this.decoder("set", s)));
63
- }
64
- this.base.notify(changes);
65
- }
66
- }
67
-
68
- static async open<K, V>(
69
- client: framer.Client,
70
- setChannel: channel.Key | channel.Name,
71
- deleteChannel: channel.Key | channel.Name,
72
- ecd: Decoder<K, V>,
73
- ): Promise<Observable<K, V>> {
74
- const stream = await client.openStreamer([
75
- setChannel,
76
- deleteChannel,
77
- ] as channel.Keys);
78
- return new Observable(stream, ecd, setChannel, deleteChannel);
79
- }
80
- }
22
+ export interface Observable<K, V>
23
+ extends observe.ObservableAsyncCloseable<Array<change.Change<K, V>>> {}
24
+
25
+ export const openObservable = async <K, V>(
26
+ client: framer.Client,
27
+ setChannel: channel.Key | channel.Name,
28
+ deleteChannel: channel.Key | channel.Name,
29
+ ecd: Decoder<K, V>,
30
+ ): Promise<Observable<K, V>> => {
31
+ const stream = await client.openStreamer([setChannel, deleteChannel] as channel.Keys);
32
+ const transform = (frame: framer.Frame): [Array<change.Change<K, V>>, boolean] => {
33
+ const changes: Array<change.Change<K, V>> = [];
34
+ if (deleteChannel != null)
35
+ changes.push(...frame.get(deleteChannel).series.flatMap((s) => ecd("delete", s)));
36
+ if (setChannel != null)
37
+ changes.push(...frame.get(setChannel).series.flatMap((s) => ecd("set", s)));
38
+ return [changes, changes.length > 0];
39
+ };
40
+ return new framer.ObservableStreamer<Array<change.Change<K, V>>>(stream, transform);
41
+ };
package/src/transport.ts CHANGED
@@ -14,7 +14,8 @@ import {
14
14
  type StreamClient,
15
15
  type UnaryClient,
16
16
  } from "@synnaxlabs/freighter";
17
- import { binary, type URL } from "@synnaxlabs/x";
17
+ import { binary } from "@synnaxlabs/x/binary";
18
+ import { type URL } from "@synnaxlabs/x/url";
18
19
 
19
20
  const baseAPIEndpoint = "/api/v1/";
20
21
 
@@ -0,0 +1,56 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { it, describe, expect } from "vitest";
11
+ import { type Primitive } from "zod";
12
+
13
+ import {
14
+ analyzeParams,
15
+ type ParamAnalysisResult,
16
+ type PartialTypeNameRecord,
17
+ } from "@/util/retrieve";
18
+
19
+ describe("retrieve utils", () => {
20
+ describe("analyze params", () => {
21
+ interface Spec {
22
+ args: Primitive extends any ? any : never;
23
+ variantMap: PartialTypeNameRecord<Primitive>;
24
+ expected: ParamAnalysisResult<Primitive, PartialTypeNameRecord<Primitive>>;
25
+ }
26
+
27
+ const SPECS: Spec[] = [
28
+ {
29
+ args: "abc",
30
+ variantMap: { string: "name" },
31
+ expected: {
32
+ single: true,
33
+ variant: "name",
34
+ normalized: ["abc"],
35
+ actual: "abc",
36
+ },
37
+ },
38
+ {
39
+ args: 123,
40
+ variantMap: { number: "id" },
41
+ expected: {
42
+ single: true,
43
+ variant: "id",
44
+ normalized: [123],
45
+ actual: 123,
46
+ },
47
+ },
48
+ ];
49
+
50
+ SPECS.forEach(({ args, variantMap, expected }) => {
51
+ it(`should analyze ${JSON.stringify(args)} with ${JSON.stringify(variantMap)}`, () => {
52
+ expect(analyzeParams(args, variantMap)).toEqual(expected);
53
+ });
54
+ });
55
+ });
56
+ });
@@ -0,0 +1,103 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
10
+ import { toArray, type Primitive } from "@synnaxlabs/x";
11
+
12
+ import { MultipleFoundError, NotFoundError } from "@/errors";
13
+
14
+ export type SingleParamAnalysisResult<
15
+ T extends Primitive,
16
+ K extends PartialTypeNameRecord<T>,
17
+ > = T extends any
18
+ ? {
19
+ single: true;
20
+ variant: K[keyof K];
21
+ normalized: T[];
22
+ actual: T;
23
+ }
24
+ : never;
25
+
26
+ export type MultiParamAnalysisResult<
27
+ T extends Primitive,
28
+ K extends PartialTypeNameRecord<T>,
29
+ > = T extends any
30
+ ? {
31
+ single: false;
32
+ variant: K[keyof K];
33
+ normalized: T[];
34
+ actual: T[];
35
+ }
36
+ : never;
37
+
38
+ type TypeName<T> = T extends string
39
+ ? "string"
40
+ : T extends number
41
+ ? "number"
42
+ : T extends boolean
43
+ ? "boolean"
44
+ : T extends undefined
45
+ ? "undefined"
46
+ : T extends Function
47
+ ? "function"
48
+ : "object";
49
+
50
+ export type PartialTypeNameRecord<T extends Primitive> = Partial<
51
+ Record<TypeName<T>, string>
52
+ >;
53
+
54
+ export type ParamAnalysisResult<
55
+ T extends Primitive,
56
+ K extends PartialTypeNameRecord<T> = PartialTypeNameRecord<T>,
57
+ > = SingleParamAnalysisResult<T, K> | MultiParamAnalysisResult<T, K>;
58
+
59
+ export interface AnalyzeParamsOptions {
60
+ convertNumericStrings?: boolean;
61
+ }
62
+
63
+ export const analyzeParams = <
64
+ T extends Primitive = Primitive,
65
+ K extends PartialTypeNameRecord<T> = PartialTypeNameRecord<T>,
66
+ >(
67
+ args: T extends any ? T | T[] : never,
68
+ variantMap: K,
69
+ { convertNumericStrings = true }: AnalyzeParamsOptions = {},
70
+ ): ParamAnalysisResult<T, K> => {
71
+ const isSingle = !Array.isArray(args);
72
+ let normal = toArray(args);
73
+ const first = normal[0];
74
+ const t = typeof first;
75
+ let variant: K[keyof K];
76
+ if (t === "string" && convertNumericStrings)
77
+ if (!isNaN(parseInt(first as string)) && "number" in variantMap) {
78
+ variant = variantMap.number as K[keyof K];
79
+ normal = normal.map((n) => parseInt(n as string));
80
+ } else variant = variantMap[t as TypeName<T>];
81
+ else variant = variantMap[t as TypeName<T>];
82
+ return {
83
+ single: isSingle,
84
+ variant,
85
+ normalized: normal,
86
+ actual: args,
87
+ } as unknown as ParamAnalysisResult<T, K>;
88
+ };
89
+
90
+ export const checkForMultipleOrNoResults = <T, R>(
91
+ name: string,
92
+ params: T | T[],
93
+ results: R[],
94
+ isSingle: boolean,
95
+ ): void => {
96
+ if (!isSingle) return;
97
+ if (results.length === 0)
98
+ throw new NotFoundError(`${name} not found matching ${JSON.stringify(params)}`);
99
+ if (results.length > 1)
100
+ throw new MultipleFoundError(
101
+ `Expected one ${name} matching ${JSON.stringify(params)}, but found ${results.length}`,
102
+ );
103
+ };
package/src/util/telem.ts CHANGED
@@ -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 DataType, type TypedArray } from "@synnaxlabs/x";
10
+ import { type DataType, type TypedArray } from "@synnaxlabs/x/telem";
11
11
 
12
12
  export const randomSeries = (length: number, dataType: DataType): TypedArray => {
13
13
  // generate random bytes of the correct length
@@ -0,0 +1,4 @@
1
+ import { z } from "zod";
2
+
3
+
4
+ export const nullableArrayZ = <Z extends z.ZodTypeAny>(item: Z) => z.union([z.null().transform(() => []), item.array()]);
@@ -8,22 +8,24 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { type UnaryClient } from "@synnaxlabs/freighter";
11
- import { type UnknownRecord, type AsyncTermSearcher } from "@synnaxlabs/x";
11
+ import { type UnknownRecord } from "@synnaxlabs/x/record";
12
+ import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
12
13
 
13
14
  import { linePlot } from "@/workspace/lineplot";
14
15
  import { type Key, type Workspace } from "@/workspace/payload";
15
- import { pid } from "@/workspace/pid";
16
+ import { schematic } from "@/workspace/schematic";
16
17
  import { Retriever } from "@/workspace/retriever";
17
18
  import { type NewWorkspace, Writer } from "@/workspace/writer";
18
19
 
19
20
  export class Client implements AsyncTermSearcher<string, Key, Workspace> {
20
- readonly pid: pid.Client;
21
+ readonly type = "workspace";
22
+ readonly schematic: schematic.Client;
21
23
  readonly linePlot: linePlot.Client;
22
24
  private readonly retriever: Retriever;
23
25
  private readonly writer: Writer;
24
26
 
25
27
  constructor(client: UnaryClient) {
26
- this.pid = new pid.Client(client);
28
+ this.schematic = new schematic.Client(client);
27
29
  this.linePlot = new linePlot.Client(client);
28
30
  this.retriever = new Retriever(client);
29
31
  this.writer = new Writer(client);
@@ -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 { type UnknownRecord } from "@synnaxlabs/x";
11
+ import { type UnknownRecord } from "@synnaxlabs/x/record";
12
12
 
13
13
  import { type LinePlot, type Key, type Params } from "@/workspace/lineplot/payload";
14
14
  import { Retriever } from "@/workspace/lineplot/retriever";
@@ -23,8 +23,8 @@ export class Client {
23
23
  this.retriever = new Retriever(client);
24
24
  }
25
25
 
26
- async create(workspace: string, pid: NewLinePlot): Promise<LinePlot> {
27
- return await this.writer.create(workspace, pid);
26
+ async create(workspace: string, schematic: NewLinePlot): Promise<LinePlot> {
27
+ return await this.writer.create(workspace, schematic);
28
28
  }
29
29
 
30
30
  async rename(key: Key, name: string): Promise<void> {
@@ -19,14 +19,14 @@ describe("LinePlot", () => {
19
19
  describe("create", () => {
20
20
  test("create one", async () => {
21
21
  const ws = await client.workspaces.create({
22
- name: "PID",
22
+ name: "Schematic",
23
23
  layout: { one: 1 },
24
24
  });
25
25
  const linePlot = await client.workspaces.linePlot.create(ws.key, {
26
- name: "PID",
26
+ name: "Schematic",
27
27
  data: { one: 1 },
28
28
  });
29
- expect(linePlot.name).toEqual("PID");
29
+ expect(linePlot.name).toEqual("Schematic");
30
30
  expect(linePlot.key).not.toEqual(ZERO_UUID);
31
31
  expect(linePlot.data.one).toEqual(1);
32
32
  });
@@ -34,26 +34,26 @@ describe("LinePlot", () => {
34
34
  describe("rename", () => {
35
35
  test("rename one", async () => {
36
36
  const ws = await client.workspaces.create({
37
- name: "PID",
37
+ name: "Schematic",
38
38
  layout: { one: 1 },
39
39
  });
40
40
  const linePlot = await client.workspaces.linePlot.create(ws.key, {
41
- name: "PID",
41
+ name: "Schematic",
42
42
  data: { one: 1 },
43
43
  });
44
- await client.workspaces.linePlot.rename(linePlot.key, "PID2");
44
+ await client.workspaces.linePlot.rename(linePlot.key, "Schematic2");
45
45
  const res = await client.workspaces.linePlot.retrieve(linePlot.key);
46
- expect(res.name).toEqual("PID2");
46
+ expect(res.name).toEqual("Schematic2");
47
47
  });
48
48
  });
49
49
  describe("setData", () => {
50
50
  test("set data", async () => {
51
51
  const ws = await client.workspaces.create({
52
- name: "PID",
52
+ name: "Schematic",
53
53
  layout: { one: 1 },
54
54
  });
55
55
  const linePlot = await client.workspaces.linePlot.create(ws.key, {
56
- name: "PID",
56
+ name: "Schematic",
57
57
  data: { one: 1 },
58
58
  });
59
59
  await client.workspaces.linePlot.setData(linePlot.key, { two: 2 });
@@ -64,11 +64,11 @@ describe("LinePlot", () => {
64
64
  describe("delete", () => {
65
65
  test("delete one", async () => {
66
66
  const ws = await client.workspaces.create({
67
- name: "PID",
67
+ name: "Schematic",
68
68
  layout: { one: 1 },
69
69
  });
70
70
  const linePlot = await client.workspaces.linePlot.create(ws.key, {
71
- name: "PID",
71
+ name: "Schematic",
72
72
  data: { one: 1 },
73
73
  });
74
74
  await client.workspaces.linePlot.delete(linePlot.key);
@@ -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 UnknownRecord, unknownRecordZ } from "@synnaxlabs/x";
10
+ import { type UnknownRecord, unknownRecordZ } from "@synnaxlabs/x/record";
11
11
  import { z } from "zod";
12
12
 
13
13
  export const keyZ = z.string().uuid();
@@ -8,14 +8,10 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
- import { toArray } from "@synnaxlabs/x";
11
+ import { toArray } from "@synnaxlabs/x/toArray";
12
12
  import { z } from "zod";
13
13
 
14
- import {
15
- type LinePlot,
16
- type Params,
17
- linePlotZ,
18
- } from "@/workspace/lineplot/payload";
14
+ import { type LinePlot, type Params, linePlotZ } from "@/workspace/lineplot/payload";
19
15
 
20
16
  const reqZ = z.object({
21
17
  keys: z.string().array(),
@@ -37,12 +33,8 @@ export class Retriever {
37
33
 
38
34
  async retrieve(params: Params): Promise<LinePlot[]> {
39
35
  const normalized = toArray(params);
40
- return (await sendRequired(
41
- this.client,
42
- this.ENDPOINT,
43
- { keys: normalized },
44
- reqZ,
45
- resZ
46
- )).linePlots;
36
+ return (
37
+ await sendRequired(this.client, this.ENDPOINT, { keys: normalized }, reqZ, resZ)
38
+ ).linePlots;
47
39
  }
48
40
  }
@@ -8,7 +8,8 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
- import { toArray, type UnknownRecord } from "@synnaxlabs/x";
11
+ import { type UnknownRecord } from "@synnaxlabs/x/record";
12
+ import { toArray } from "@synnaxlabs/x/toArray";
12
13
  import { z } from "zod";
13
14
 
14
15
  import {
@@ -69,11 +70,11 @@ export class Writer {
69
70
  }
70
71
 
71
72
  async create(workspace: string, plot: NewLinePlot): Promise<LinePlot> {
72
- const pid_ = { ...plot, data: JSON.stringify(plot.data) };
73
+ const schematic_ = { ...plot, data: JSON.stringify(plot.data) };
73
74
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
74
75
  this.client,
75
76
  CREATE_ENDPOINT,
76
- { workspace, linePlots: [pid_] },
77
+ { workspace, linePlots: [schematic_] },
77
78
  createReqZ,
78
79
  createResZ,
79
80
  );
@@ -92,21 +93,21 @@ export class Writer {
92
93
  );
93
94
  }
94
95
 
95
- async rename(pid: Key, name: string): Promise<void> {
96
+ async rename(schematic: Key, name: string): Promise<void> {
96
97
  await sendRequired<typeof renameReqZ, typeof renameResZ>(
97
98
  this.client,
98
99
  RENAME_ENDPOINT,
99
- { key: pid, name },
100
+ { key: schematic, name },
100
101
  renameReqZ,
101
102
  renameResZ,
102
103
  );
103
104
  }
104
105
 
105
- async setData(pid: Key, data: UnknownRecord): Promise<void> {
106
+ async setData(schematic: Key, data: UnknownRecord): Promise<void> {
106
107
  await sendRequired<typeof setDataReqZ, typeof setDataResZ>(
107
108
  this.client,
108
109
  SET_DATA_ENDPOINT,
109
- { key: pid, data: JSON.stringify(data) },
110
+ { key: schematic, data: JSON.stringify(data) },
110
111
  setDataReqZ,
111
112
  setDataResZ,
112
113
  );
@@ -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 { type UnknownRecord, unknownRecordZ } from "@synnaxlabs/x";
10
+ import { binary } from "@synnaxlabs/x/binary";
11
+ import { type UnknownRecord, unknownRecordZ } from "@synnaxlabs/x/record";
11
12
  import { z } from "zod";
12
13
 
13
14
  export const keyZ = z.string().uuid();
@@ -19,11 +20,13 @@ export type Params = Key | Key[];
19
20
  export const workspaceZ = z.object({
20
21
  name: z.string(),
21
22
  key: keyZ,
22
- layout: unknownRecordZ.or(z.string().transform((s) => JSON.parse(s) as UnknownRecord)),
23
+ layout: unknownRecordZ.or(
24
+ z.string().transform((s) => binary.JSON_ECD.decodeString(s) as UnknownRecord),
25
+ ),
23
26
  });
24
27
 
25
28
  export const workspaceRemoteZ = workspaceZ.omit({ layout: true }).extend({
26
- layout: z.string().transform((s) => JSON.parse(s) as UnknownRecord),
29
+ layout: z.string().transform((s) => binary.JSON_ECD.decodeString(s) as UnknownRecord),
27
30
  });
28
31
 
29
32
  export type Workspace = z.infer<typeof workspaceZ>;
@@ -8,7 +8,7 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
- import { toArray } from "@synnaxlabs/x";
11
+ import { toArray } from "@synnaxlabs/x/toArray";
12
12
  import { z } from "zod";
13
13
 
14
14
  import {
@@ -8,11 +8,11 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import { type UnaryClient } from "@synnaxlabs/freighter";
11
- import { type UnknownRecord } from "@synnaxlabs/x";
11
+ import { type UnknownRecord } from "@synnaxlabs/x/record";
12
12
 
13
- import { type Key, type Params, type PID } from "@/workspace/pid/payload";
14
- import { Retriever } from "@/workspace/pid/retriever";
15
- import { Writer, type NewPID } from "@/workspace/pid/writer";
13
+ import { type Key, type Params, type Schematic } from "@/workspace/schematic/payload";
14
+ import { Retriever } from "@/workspace/schematic/retriever";
15
+ import { Writer, type NewSchematic } from "@/workspace/schematic/writer";
16
16
 
17
17
  export class Client {
18
18
  private readonly writer: Writer;
@@ -23,8 +23,8 @@ export class Client {
23
23
  this.retriever = new Retriever(client);
24
24
  }
25
25
 
26
- async create(workspace: string, pid: NewPID): Promise<PID> {
27
- return await this.writer.create(workspace, pid);
26
+ async create(workspace: string, schematic: NewSchematic): Promise<Schematic> {
27
+ return await this.writer.create(workspace, schematic);
28
28
  }
29
29
 
30
30
  async rename(key: Key, name: string): Promise<void> {
@@ -35,11 +35,11 @@ export class Client {
35
35
  await this.writer.setData(key, data);
36
36
  }
37
37
 
38
- async retrieve(key: Key): Promise<PID>;
38
+ async retrieve(key: Key): Promise<Schematic>;
39
39
 
40
- async retrieve(keys: Key[]): Promise<PID[]>;
40
+ async retrieve(keys: Key[]): Promise<Schematic[]>;
41
41
 
42
- async retrieve(keys: Params): Promise<PID | PID[]> {
42
+ async retrieve(keys: Params): Promise<Schematic | Schematic[]> {
43
43
  const isMany = Array.isArray(keys);
44
44
  const res = await this.retriever.retrieve(keys);
45
45
  return isMany ? res : res[0];
@@ -49,7 +49,7 @@ export class Client {
49
49
  await this.writer.delete(keys);
50
50
  }
51
51
 
52
- async copy(key: Key, name: string, snapshot: boolean): Promise<PID> {
52
+ async copy(key: Key, name: string, snapshot: boolean): Promise<Schematic> {
53
53
  return await this.writer.copy(key, name, snapshot);
54
54
  }
55
55
  }