@synnaxlabs/client 0.38.1 → 0.40.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 (257) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/dist/access/payload.d.ts +6 -6
  3. package/dist/access/payload.d.ts.map +1 -1
  4. package/dist/access/policy/client.d.ts +5 -3
  5. package/dist/access/policy/client.d.ts.map +1 -1
  6. package/dist/access/policy/external.d.ts +1 -0
  7. package/dist/access/policy/external.d.ts.map +1 -1
  8. package/dist/access/policy/ontology.d.ts +5 -0
  9. package/dist/access/policy/ontology.d.ts.map +1 -0
  10. package/dist/access/policy/payload.d.ts +86 -89
  11. package/dist/access/policy/payload.d.ts.map +1 -1
  12. package/dist/access/policy/retriever.d.ts +7 -6
  13. package/dist/access/policy/retriever.d.ts.map +1 -1
  14. package/dist/access/policy/writer.d.ts +2 -2
  15. package/dist/access/policy/writer.d.ts.map +1 -1
  16. package/dist/auth/auth.d.ts +2 -1
  17. package/dist/auth/auth.d.ts.map +1 -1
  18. package/dist/channel/client.d.ts +6 -5
  19. package/dist/channel/client.d.ts.map +1 -1
  20. package/dist/channel/payload.d.ts +13 -11
  21. package/dist/channel/payload.d.ts.map +1 -1
  22. package/dist/channel/retriever.d.ts +9 -6
  23. package/dist/channel/retriever.d.ts.map +1 -1
  24. package/dist/channel/writer.d.ts +6 -4
  25. package/dist/channel/writer.d.ts.map +1 -1
  26. package/dist/client.cjs +30 -30
  27. package/dist/client.d.ts +4 -2
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +3387 -3433
  30. package/dist/connection/checker.d.ts +5 -4
  31. package/dist/connection/checker.d.ts.map +1 -1
  32. package/dist/control/state.d.ts +10 -8
  33. package/dist/control/state.d.ts.map +1 -1
  34. package/dist/errors.d.ts +5 -0
  35. package/dist/errors.d.ts.map +1 -1
  36. package/dist/framer/adapter.d.ts +14 -15
  37. package/dist/framer/adapter.d.ts.map +1 -1
  38. package/dist/framer/client.d.ts +13 -15
  39. package/dist/framer/client.d.ts.map +1 -1
  40. package/dist/framer/deleter.d.ts +3 -2
  41. package/dist/framer/deleter.d.ts.map +1 -1
  42. package/dist/framer/frame.d.ts +31 -27
  43. package/dist/framer/frame.d.ts.map +1 -1
  44. package/dist/framer/iterator.d.ts +4 -5
  45. package/dist/framer/iterator.d.ts.map +1 -1
  46. package/dist/framer/streamer.d.ts +5 -6
  47. package/dist/framer/streamer.d.ts.map +1 -1
  48. package/dist/framer/writer.d.ts +42 -39
  49. package/dist/framer/writer.d.ts.map +1 -1
  50. package/dist/hardware/device/client.d.ts +20 -12
  51. package/dist/hardware/device/client.d.ts.map +1 -1
  52. package/dist/hardware/device/payload.d.ts +19 -16
  53. package/dist/hardware/device/payload.d.ts.map +1 -1
  54. package/dist/hardware/rack/client.d.ts +15 -15
  55. package/dist/hardware/rack/client.d.ts.map +1 -1
  56. package/dist/hardware/rack/payload.d.ts +9 -8
  57. package/dist/hardware/rack/payload.d.ts.map +1 -1
  58. package/dist/hardware/task/client.d.ts +38 -29
  59. package/dist/hardware/task/client.d.ts.map +1 -1
  60. package/dist/hardware/task/payload.d.ts +58 -53
  61. package/dist/hardware/task/payload.d.ts.map +1 -1
  62. package/dist/label/client.d.ts +4 -3
  63. package/dist/label/client.d.ts.map +1 -1
  64. package/dist/label/payload.d.ts +4 -4
  65. package/dist/label/payload.d.ts.map +1 -1
  66. package/dist/label/retriever.d.ts.map +1 -1
  67. package/dist/label/writer.d.ts +13 -10
  68. package/dist/label/writer.d.ts.map +1 -1
  69. package/dist/ontology/client.d.ts +12 -10
  70. package/dist/ontology/client.d.ts.map +1 -1
  71. package/dist/ontology/group/client.d.ts +5 -4
  72. package/dist/ontology/group/client.d.ts.map +1 -1
  73. package/dist/ontology/group/group.d.ts +7 -5
  74. package/dist/ontology/group/group.d.ts.map +1 -1
  75. package/dist/ontology/group/payload.d.ts +6 -5
  76. package/dist/ontology/group/payload.d.ts.map +1 -1
  77. package/dist/ontology/group/writer.d.ts +8 -8
  78. package/dist/ontology/group/writer.d.ts.map +1 -1
  79. package/dist/ontology/payload.d.ts +72 -62
  80. package/dist/ontology/payload.d.ts.map +1 -1
  81. package/dist/ontology/writer.d.ts.map +1 -1
  82. package/dist/ranger/alias.d.ts +9 -10
  83. package/dist/ranger/alias.d.ts.map +1 -1
  84. package/dist/ranger/client.d.ts +18 -18
  85. package/dist/ranger/client.d.ts.map +1 -1
  86. package/dist/ranger/external.d.ts +1 -1
  87. package/dist/ranger/external.d.ts.map +1 -1
  88. package/dist/ranger/kv.d.ts +18 -14
  89. package/dist/ranger/kv.d.ts.map +1 -1
  90. package/dist/ranger/payload.d.ts +13 -13
  91. package/dist/ranger/payload.d.ts.map +1 -1
  92. package/dist/ranger/writer.d.ts +14 -14
  93. package/dist/ranger/writer.d.ts.map +1 -1
  94. package/dist/setupspecs.d.ts.map +1 -1
  95. package/dist/signals/observable.d.ts +3 -1
  96. package/dist/signals/observable.d.ts.map +1 -1
  97. package/dist/user/client.d.ts +5 -3
  98. package/dist/user/client.d.ts.map +1 -1
  99. package/dist/user/payload.d.ts +7 -6
  100. package/dist/user/payload.d.ts.map +1 -1
  101. package/dist/user/retriever.d.ts +2 -1
  102. package/dist/user/retriever.d.ts.map +1 -1
  103. package/dist/user/writer.d.ts +2 -2
  104. package/dist/user/writer.d.ts.map +1 -1
  105. package/dist/util/decodeJSONString.d.ts +3 -0
  106. package/dist/util/decodeJSONString.d.ts.map +1 -0
  107. package/dist/util/parseWithoutKeyConversion.d.ts +3 -0
  108. package/dist/util/parseWithoutKeyConversion.d.ts.map +1 -0
  109. package/dist/util/retrieve.d.ts +1 -1
  110. package/dist/util/retrieve.d.ts.map +1 -1
  111. package/dist/util/telem.d.ts.map +1 -1
  112. package/dist/util/zod.d.ts.map +1 -1
  113. package/dist/workspace/client.d.ts +6 -60
  114. package/dist/workspace/client.d.ts.map +1 -1
  115. package/dist/workspace/external.d.ts +3 -0
  116. package/dist/workspace/external.d.ts.map +1 -0
  117. package/dist/workspace/index.d.ts +1 -1
  118. package/dist/workspace/index.d.ts.map +1 -1
  119. package/dist/workspace/lineplot/client.d.ts +5 -44
  120. package/dist/workspace/lineplot/client.d.ts.map +1 -1
  121. package/dist/workspace/lineplot/external.d.ts +3 -0
  122. package/dist/workspace/lineplot/external.d.ts.map +1 -0
  123. package/dist/workspace/lineplot/index.d.ts +1 -1
  124. package/dist/workspace/lineplot/index.d.ts.map +1 -1
  125. package/dist/workspace/lineplot/payload.d.ts +45 -0
  126. package/dist/workspace/lineplot/payload.d.ts.map +1 -0
  127. package/dist/workspace/log/client.d.ts +5 -44
  128. package/dist/workspace/log/client.d.ts.map +1 -1
  129. package/dist/workspace/log/external.d.ts +3 -0
  130. package/dist/workspace/log/external.d.ts.map +1 -0
  131. package/dist/workspace/log/index.d.ts +1 -1
  132. package/dist/workspace/log/index.d.ts.map +1 -1
  133. package/dist/workspace/log/payload.d.ts +45 -0
  134. package/dist/workspace/log/payload.d.ts.map +1 -0
  135. package/dist/workspace/payload.d.ts +60 -0
  136. package/dist/workspace/payload.d.ts.map +1 -0
  137. package/dist/workspace/schematic/client.d.ts +5 -68
  138. package/dist/workspace/schematic/client.d.ts.map +1 -1
  139. package/dist/workspace/schematic/external.d.ts +3 -0
  140. package/dist/workspace/schematic/external.d.ts.map +1 -0
  141. package/dist/workspace/schematic/index.d.ts +1 -1
  142. package/dist/workspace/schematic/index.d.ts.map +1 -1
  143. package/dist/workspace/schematic/payload.d.ts +71 -0
  144. package/dist/workspace/schematic/payload.d.ts.map +1 -0
  145. package/dist/workspace/table/client.d.ts +5 -57
  146. package/dist/workspace/table/client.d.ts.map +1 -1
  147. package/dist/workspace/table/external.d.ts +3 -0
  148. package/dist/workspace/table/external.d.ts.map +1 -0
  149. package/dist/workspace/table/index.d.ts +1 -1
  150. package/dist/workspace/table/index.d.ts.map +1 -1
  151. package/dist/workspace/table/payload.d.ts +60 -0
  152. package/dist/workspace/table/payload.d.ts.map +1 -0
  153. package/examples/node/basicReadWrite.js +26 -26
  154. package/examples/node/liveStream.js +15 -15
  155. package/examples/node/seriesAndFrames.js +38 -38
  156. package/examples/node/streamWrite.js +47 -45
  157. package/package.json +15 -13
  158. package/src/access/payload.ts +12 -12
  159. package/src/access/policy/client.ts +13 -12
  160. package/src/access/policy/external.ts +1 -0
  161. package/src/access/policy/ontology.ts +17 -0
  162. package/src/access/policy/payload.ts +7 -19
  163. package/src/access/policy/policy.spec.ts +16 -16
  164. package/src/access/policy/retriever.ts +2 -1
  165. package/src/access/policy/writer.ts +4 -4
  166. package/src/auth/auth.spec.ts +27 -23
  167. package/src/auth/auth.ts +7 -11
  168. package/src/channel/batchRetriever.spec.ts +25 -22
  169. package/src/channel/client.ts +19 -21
  170. package/src/channel/payload.ts +16 -20
  171. package/src/channel/retriever.ts +20 -21
  172. package/src/channel/writer.ts +11 -13
  173. package/src/client.ts +6 -16
  174. package/src/connection/checker.ts +9 -11
  175. package/src/connection/connection.spec.ts +17 -5
  176. package/src/control/state.ts +8 -9
  177. package/src/errors.spec.ts +1 -1
  178. package/src/errors.ts +8 -0
  179. package/src/framer/adapter.spec.ts +28 -23
  180. package/src/framer/adapter.ts +37 -41
  181. package/src/framer/client.spec.ts +5 -11
  182. package/src/framer/client.ts +34 -38
  183. package/src/framer/deleter.ts +5 -6
  184. package/src/framer/frame.ts +62 -50
  185. package/src/framer/iterator.ts +11 -16
  186. package/src/framer/streamer.spec.ts +2 -10
  187. package/src/framer/streamer.ts +15 -19
  188. package/src/framer/writer.spec.ts +48 -7
  189. package/src/framer/writer.ts +39 -31
  190. package/src/hardware/device/client.ts +67 -39
  191. package/src/hardware/device/device.spec.ts +91 -33
  192. package/src/hardware/device/payload.ts +29 -28
  193. package/src/hardware/rack/client.ts +52 -65
  194. package/src/hardware/rack/payload.ts +9 -18
  195. package/src/hardware/rack/rack.spec.ts +12 -0
  196. package/src/hardware/task/client.ts +160 -131
  197. package/src/hardware/task/payload.ts +49 -68
  198. package/src/hardware/task/task.spec.ts +98 -81
  199. package/src/label/client.ts +12 -15
  200. package/src/label/payload.ts +3 -9
  201. package/src/label/retriever.ts +3 -7
  202. package/src/label/writer.ts +8 -15
  203. package/src/ontology/client.ts +17 -22
  204. package/src/ontology/group/client.ts +5 -5
  205. package/src/ontology/group/group.spec.ts +4 -4
  206. package/src/ontology/group/group.ts +10 -7
  207. package/src/ontology/group/payload.ts +11 -35
  208. package/src/ontology/group/writer.ts +22 -26
  209. package/src/ontology/ontology.spec.ts +15 -15
  210. package/src/ontology/payload.ts +67 -43
  211. package/src/ontology/writer.ts +16 -23
  212. package/src/ranger/alias.ts +25 -42
  213. package/src/ranger/client.ts +29 -38
  214. package/src/ranger/external.ts +1 -1
  215. package/src/ranger/kv.ts +9 -32
  216. package/src/ranger/payload.ts +14 -36
  217. package/src/ranger/ranger.spec.ts +1 -2
  218. package/src/ranger/writer.ts +8 -26
  219. package/src/signals/observable.ts +3 -4
  220. package/src/user/client.ts +8 -4
  221. package/src/user/payload.ts +5 -9
  222. package/src/user/retriever.ts +1 -1
  223. package/src/user/user.spec.ts +17 -15
  224. package/src/user/writer.ts +3 -10
  225. package/src/util/decodeJSONString.ts +13 -0
  226. package/src/util/parseWithoutKeyConversion.ts +19 -0
  227. package/src/util/retrieve.spec.ts +3 -13
  228. package/src/util/retrieve.ts +2 -12
  229. package/src/util/telem.ts +1 -1
  230. package/src/vite-env.d.ts +1 -0
  231. package/src/workspace/client.ts +30 -57
  232. package/src/workspace/external.ts +11 -0
  233. package/src/workspace/index.ts +1 -1
  234. package/src/workspace/lineplot/client.ts +22 -36
  235. package/src/workspace/lineplot/external.ts +11 -0
  236. package/src/workspace/lineplot/index.ts +1 -1
  237. package/src/workspace/lineplot/linePlot.spec.ts +1 -2
  238. package/src/workspace/lineplot/payload.ts +32 -0
  239. package/src/workspace/log/client.ts +25 -39
  240. package/src/workspace/log/external.ts +11 -0
  241. package/src/workspace/log/index.ts +1 -1
  242. package/src/workspace/log/log.spec.ts +5 -18
  243. package/src/workspace/log/payload.ts +32 -0
  244. package/src/workspace/payload.ts +36 -0
  245. package/src/workspace/schematic/client.ts +30 -56
  246. package/src/workspace/schematic/external.ts +11 -0
  247. package/src/workspace/schematic/index.ts +1 -1
  248. package/src/workspace/schematic/payload.ts +37 -0
  249. package/src/workspace/schematic/schematic.spec.ts +15 -6
  250. package/src/workspace/table/client.ts +27 -50
  251. package/src/workspace/table/external.ts +11 -0
  252. package/src/workspace/table/index.ts +1 -1
  253. package/src/workspace/table/payload.ts +36 -0
  254. package/src/workspace/workspace.spec.ts +1 -2
  255. package/dist/channel/creator.d.ts +0 -9
  256. package/dist/channel/creator.d.ts.map +0 -1
  257. package/src/channel/creator.ts +0 -37
@@ -14,25 +14,23 @@ import { type Series } from "@synnaxlabs/x/telem";
14
14
  import { toArray } from "@synnaxlabs/x/toArray";
15
15
  import { z } from "zod";
16
16
 
17
- import { type Key as ChannelKey } from "@/channel/payload";
18
- import { type Retriever as ChannelRetriever } from "@/channel/retriever";
17
+ import { type channel } from "@/channel";
19
18
  import { MultipleFoundError, NotFoundError, QueryError } from "@/errors";
20
19
  import { type framer } from "@/framer";
21
20
  import { type label } from "@/label";
22
- import { type Label } from "@/label/payload";
23
- import { type ontology } from "@/ontology";
24
- import { type Resource } from "@/ontology/payload";
21
+ import { ontology } from "@/ontology";
25
22
  import { type Alias, Aliaser } from "@/ranger/alias";
26
23
  import { KV } from "@/ranger/kv";
27
24
  import {
25
+ ALIAS_ONTOLOGY_TYPE,
28
26
  analyzeParams,
29
27
  type Key,
30
28
  type Keys,
31
29
  keyZ,
32
30
  type Name,
33
31
  type Names,
34
- type NewPayload,
35
- ontologyID,
32
+ type New,
33
+ ONTOLOGY_TYPE,
36
34
  type Params,
37
35
  type Payload,
38
36
  payloadZ,
@@ -47,7 +45,7 @@ export class Range {
47
45
  readonly kv: KV;
48
46
  readonly timeRange: TimeRange;
49
47
  readonly color: string | undefined;
50
- readonly channels: ChannelRetriever;
48
+ readonly channels: channel.Retriever;
51
49
  private readonly aliaser: Aliaser;
52
50
  private readonly frameClient: framer.Client;
53
51
  private readonly labelClient: label.Client;
@@ -62,7 +60,7 @@ export class Range {
62
60
  _frameClient: framer.Client,
63
61
  _kv: KV,
64
62
  _aliaser: Aliaser,
65
- _channels: ChannelRetriever,
63
+ _channels: channel.Retriever,
66
64
  _labelClient: label.Client,
67
65
  _ontologyClient: ontology.Client,
68
66
  _rangeClient: Client,
@@ -93,22 +91,21 @@ export class Range {
93
91
  };
94
92
  }
95
93
 
96
- async setAlias(channel: ChannelKey | Name, alias: string): Promise<void> {
94
+ async setAlias(channel: channel.Key | Name, alias: string): Promise<void> {
97
95
  const ch = await this.channels.retrieve(channel);
98
96
  if (ch.length === 0) throw new QueryError(`Channel ${channel} does not exist`);
99
-
100
97
  await this.aliaser.set({ [ch[0].key]: alias });
101
98
  }
102
99
 
103
- async deleteAlias(...channels: ChannelKey[]): Promise<void> {
100
+ async deleteAlias(...channels: channel.Key[]): Promise<void> {
104
101
  await this.aliaser.delete(channels);
105
102
  }
106
103
 
107
- async listAliases(): Promise<Record<ChannelKey, string>> {
104
+ async listAliases(): Promise<Record<channel.Key, string>> {
108
105
  return await this.aliaser.list();
109
106
  }
110
107
 
111
- async resolveAlias(alias: string): Promise<ChannelKey> {
108
+ async resolveAlias(alias: string): Promise<channel.Key> {
112
109
  return await this.aliaser.resolve(alias);
113
110
  }
114
111
 
@@ -131,14 +128,12 @@ export class Range {
131
128
  }
132
129
 
133
130
  async read(channel: Key | Name): Promise<Series>;
134
-
135
131
  async read(channels: Params): Promise<framer.Frame>;
136
-
137
132
  async read(channels: Params): Promise<Series | framer.Frame> {
138
133
  return await this.frameClient.read(this.timeRange, channels);
139
134
  }
140
135
 
141
- async labels(): Promise<Label[]> {
136
+ async labels(): Promise<label.Label[]> {
142
137
  return await this.labelClient.retrieveFor(ontologyID(this.key));
143
138
  }
144
139
 
@@ -161,7 +156,7 @@ export class Range {
161
156
  dependents: initial,
162
157
  resourceType: "range",
163
158
  });
164
- base.onChange((r: Resource[]) =>
159
+ base.onChange((r: ontology.Resource[]) =>
165
160
  wrapper.notify(this.rangeClient.resourcesToRanges(r)),
166
161
  );
167
162
  wrapper.setCloser(async () => await base.close());
@@ -179,7 +174,7 @@ export class Range {
179
174
  dependents: [resourceP],
180
175
  relationshipDirection: "to",
181
176
  });
182
- base.onChange((resources: Resource[]) => {
177
+ base.onChange((resources: ontology.Resource[]) => {
183
178
  const ranges = this.rangeClient.resourcesToRanges(resources);
184
179
  if (ranges.length === 0) return;
185
180
  const p = ranges[0];
@@ -202,20 +197,18 @@ const retrieveReqZ = z.object({
202
197
  offset: z.number().int().optional(),
203
198
  });
204
199
 
205
- export type RetrieveRequest = z.infer<typeof retrieveReqZ>;
200
+ export interface RetrieveRequest extends z.infer<typeof retrieveReqZ> {}
206
201
 
207
202
  const RETRIEVE_ENDPOINT = "/range/retrieve";
208
203
 
209
- const retrieveResZ = z.object({
210
- ranges: nullableArrayZ(payloadZ),
211
- });
204
+ const retrieveResZ = z.object({ ranges: nullableArrayZ(payloadZ) });
212
205
 
213
206
  export class Client implements AsyncTermSearcher<string, Key, Range> {
214
207
  readonly type: string = "range";
215
208
  private readonly frameClient: framer.Client;
216
209
  private readonly writer: Writer;
217
210
  private readonly unaryClient: UnaryClient;
218
- private readonly channels: ChannelRetriever;
211
+ private readonly channels: channel.Retriever;
219
212
  private readonly labelClient: label.Client;
220
213
  private readonly ontologyClient: ontology.Client;
221
214
 
@@ -223,7 +216,7 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
223
216
  frameClient: framer.Client,
224
217
  writer: Writer,
225
218
  unary: UnaryClient,
226
- channels: ChannelRetriever,
219
+ channels: channel.Retriever,
227
220
  labelClient: label.Client,
228
221
  ontologyClient: ontology.Client,
229
222
  ) {
@@ -235,14 +228,9 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
235
228
  this.ontologyClient = ontologyClient;
236
229
  }
237
230
 
238
- async create(range: NewPayload, options?: CreateOptions): Promise<Range>;
239
-
240
- async create(ranges: NewPayload[], options?: CreateOptions): Promise<Range[]>;
241
-
242
- async create(
243
- ranges: NewPayload | NewPayload[],
244
- options?: CreateOptions,
245
- ): Promise<Range | Range[]> {
231
+ async create(range: New, options?: CreateOptions): Promise<Range>;
232
+ async create(ranges: New[], options?: CreateOptions): Promise<Range[]>;
233
+ async create(ranges: New | New[], options?: CreateOptions): Promise<Range | Range[]> {
246
234
  const single = !Array.isArray(ranges);
247
235
  const res = this.sugarMany(await this.writer.create(toArray(ranges), options));
248
236
  return single ? res[0] : res;
@@ -265,11 +253,8 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
265
253
  }
266
254
 
267
255
  async retrieve(range: CrudeTimeRange): Promise<Range[]>;
268
-
269
256
  async retrieve(range: Key | Name): Promise<Range>;
270
-
271
257
  async retrieve(range: Keys | Names): Promise<Range[]>;
272
-
273
258
  async retrieve(ranges: Params | CrudeTimeRange): Promise<Range | Range[]> {
274
259
  if (typeof ranges === "object" && "start" in ranges)
275
260
  return await this.execRetrieve({ overlapsWith: new TimeRange(ranges) });
@@ -343,11 +328,11 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
343
328
  );
344
329
  }
345
330
 
346
- resourcesToRanges(resources: Resource[]): Range[] {
331
+ resourcesToRanges(resources: ontology.Resource[]): Range[] {
347
332
  return resources.map((r) => this.resourceToRange(r));
348
333
  }
349
334
 
350
- resourceToRange(resource: Resource): Range {
335
+ resourceToRange(resource: ontology.Resource): Range {
351
336
  return this.sugarOne({
352
337
  key: resource.id.key,
353
338
  name: resource.data?.name as string,
@@ -356,3 +341,9 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
356
341
  });
357
342
  }
358
343
  }
344
+
345
+ export const ontologyID = (key: Key): ontology.ID =>
346
+ new ontology.ID({ type: ONTOLOGY_TYPE, key });
347
+
348
+ export const aliasOntologyID = (key: Key): ontology.ID =>
349
+ new ontology.ID({ type: ALIAS_ONTOLOGY_TYPE, 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
- export type { Alias, AliasChange } from "@/ranger/alias";
10
+ export { type Alias, type AliasChange } from "@/ranger/alias";
11
11
  export * from "@/ranger/client";
12
12
  export * from "@/ranger/kv";
13
13
  export * from "@/ranger/payload";
package/src/ranger/kv.ts CHANGED
@@ -17,38 +17,19 @@ import { type Key, keyZ } from "@/ranger/payload";
17
17
  import { signals } from "@/signals";
18
18
  import { nullableArrayZ } from "@/util/zod";
19
19
 
20
- const getReqZ = z.object({
21
- range: keyZ,
22
- keys: z.string().array(),
23
- });
20
+ const kvPairZ = z.object({ range: keyZ, key: z.string(), value: z.string() });
21
+ export interface KVPair extends z.infer<typeof kvPairZ> {}
24
22
 
25
- const kvPairZ = z.object({
26
- range: keyZ,
27
- key: z.string(),
28
- value: z.string(),
29
- });
23
+ const getReqZ = z.object({ range: keyZ, keys: z.string().array() });
24
+ export interface GetRequest extends z.infer<typeof getReqZ> {}
30
25
 
31
- const getResZ = z.object({
32
- pairs: nullableArrayZ(kvPairZ),
33
- });
26
+ const getResZ = z.object({ pairs: nullableArrayZ(kvPairZ) });
34
27
 
35
- export type GetRequest = z.infer<typeof getReqZ>;
28
+ const setReqZ = z.object({ range: keyZ, pairs: kvPairZ.array() });
29
+ export interface SetRequest extends z.infer<typeof setReqZ> {}
36
30
 
37
- const setReqZ = z.object({
38
- range: keyZ,
39
- pairs: kvPairZ.array(),
40
- });
41
-
42
- export type SetRequest = z.infer<typeof setReqZ>;
43
-
44
- const deleteReqZ = z.object({
45
- range: keyZ,
46
- keys: z.string().array(),
47
- });
48
-
49
- export type DeleteRequest = z.infer<typeof deleteReqZ>;
50
-
51
- export type KVPair = z.infer<typeof kvPairZ>;
31
+ const deleteReqZ = z.object({ range: keyZ, keys: z.string().array() });
32
+ export interface DeleteRequest extends z.infer<typeof deleteReqZ> {}
52
33
 
53
34
  export class KV {
54
35
  private static readonly GET_ENDPOINT = "/range/kv/get";
@@ -65,9 +46,7 @@ export class KV {
65
46
  }
66
47
 
67
48
  async get(key: string): Promise<string>;
68
-
69
49
  async get(keys: string[]): Promise<Record<string, string>>;
70
-
71
50
  async get(keys: string | string[]): Promise<string | Record<string, string>> {
72
51
  const res = await sendRequired(
73
52
  this.client,
@@ -85,9 +64,7 @@ export class KV {
85
64
  }
86
65
 
87
66
  async set(key: string, value: string): Promise<void>;
88
-
89
67
  async set(kv: Record<string, string>): Promise<void>;
90
-
91
68
  async set(key: string | Record<string, string>, value: string = ""): Promise<void> {
92
69
  let pairs: KVPair[];
93
70
  if (isObject(key))
@@ -11,48 +11,29 @@ import { TimeRange } from "@synnaxlabs/x/telem";
11
11
  import { toArray } from "@synnaxlabs/x/toArray";
12
12
  import { z } from "zod";
13
13
 
14
- import { ontology } from "@/ontology";
15
-
16
14
  export const keyZ = z.string().uuid();
17
15
  export type Key = z.infer<typeof keyZ>;
18
- export type Name = string;
16
+ export const nameZ = z.string().min(1);
17
+ export type Name = z.infer<typeof nameZ>;
19
18
  export type Keys = Key[];
20
19
  export type Names = Name[];
21
20
  export type Params = Key | Name | Keys | Names;
22
21
 
23
22
  export const payloadZ = z.object({
24
23
  key: keyZ,
25
- name: z.string().min(1),
24
+ name: nameZ,
26
25
  timeRange: TimeRange.z,
27
26
  color: z.string().optional(),
28
27
  });
29
- export type Payload = z.infer<typeof payloadZ>;
28
+ export interface Payload extends z.infer<typeof payloadZ> {}
30
29
 
31
- export const newPayloadZ = payloadZ.extend({ key: z.string().uuid().optional() });
32
- export type NewPayload = z.input<typeof newPayloadZ>;
30
+ export const newZ = payloadZ.partial({ key: true });
31
+ export interface New extends z.input<typeof newZ> {}
33
32
 
34
33
  export type ParamAnalysisResult =
35
- | {
36
- single: true;
37
- variant: "keys";
38
- normalized: Keys;
39
- actual: Key;
40
- empty: never;
41
- }
42
- | {
43
- single: true;
44
- variant: "names";
45
- normalized: Names;
46
- actual: Name;
47
- empty: never;
48
- }
49
- | {
50
- single: false;
51
- variant: "keys";
52
- normalized: Keys;
53
- actual: Keys;
54
- empty: boolean;
55
- }
34
+ | { single: true; variant: "keys"; normalized: Keys; actual: Key; empty: never }
35
+ | { single: true; variant: "names"; normalized: Names; actual: Name; empty: never }
36
+ | { single: false; variant: "keys"; normalized: Keys; actual: Keys; empty: boolean }
56
37
  | {
57
38
  single: false;
58
39
  variant: "names";
@@ -72,14 +53,11 @@ export const analyzeParams = (ranges: Params): ParamAnalysisResult => {
72
53
  normalized: normal,
73
54
  actual: ranges,
74
55
  empty,
75
- } as const as ParamAnalysisResult;
56
+ } as ParamAnalysisResult;
76
57
  };
77
58
 
78
- export const ONTOLOGY_TYPE: ontology.ResourceType = "range";
79
- export const ALIAS_ONTOLOGY_TYPE: ontology.ResourceType = "range-alias";
80
-
81
- export const ontologyID = (key: Key): ontology.ID =>
82
- new ontology.ID({ type: ONTOLOGY_TYPE, key });
59
+ export const ONTOLOGY_TYPE = "range";
60
+ export type OntologyType = typeof ONTOLOGY_TYPE;
83
61
 
84
- export const aliasOntologyID = (key: Key): ontology.ID =>
85
- new ontology.ID({ type: ALIAS_ONTOLOGY_TYPE, key });
62
+ export const ALIAS_ONTOLOGY_TYPE = "range-alias";
63
+ export type AliasOntologyType = typeof ALIAS_ONTOLOGY_TYPE;
@@ -13,7 +13,6 @@ import { describe, expect, it } from "vitest";
13
13
 
14
14
  import { QueryError } from "@/errors";
15
15
  import { type ranger } from "@/ranger";
16
- import { type NewPayload } from "@/ranger/payload";
17
16
  import { newClient } from "@/setupspecs";
18
17
 
19
18
  const client = newClient();
@@ -32,7 +31,7 @@ describe("Ranger", () => {
32
31
  expect(range.color).toEqual("#E774D0");
33
32
  });
34
33
  it("should create multiple ranges", async () => {
35
- const ranges: NewPayload[] = [
34
+ const ranges: ranger.New[] = [
36
35
  {
37
36
  name: "My New One Second Range",
38
37
  timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
@@ -11,37 +11,19 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { z } from "zod";
12
12
 
13
13
  import { ontology } from "@/ontology";
14
- import {
15
- keyZ,
16
- type NewPayload,
17
- newPayloadZ,
18
- type Payload,
19
- payloadZ,
20
- } from "@/ranger/payload";
14
+ import { keyZ, nameZ, type New, newZ, type Payload, payloadZ } from "@/ranger/payload";
21
15
 
22
- const createResZ = z.object({
23
- ranges: payloadZ.array(),
24
- });
16
+ const createResZ = z.object({ ranges: payloadZ.array() });
25
17
 
26
- const createReqZ = z.object({
27
- parent: ontology.idZ.optional(),
28
- ranges: newPayloadZ.array(),
29
- });
18
+ const createReqZ = z.object({ parent: ontology.idZ.optional(), ranges: newZ.array() });
30
19
 
31
- type CreateRequest = z.infer<typeof createReqZ>;
32
- export type CreateOptions = Pick<CreateRequest, "parent">;
33
-
34
- const deleteReqZ = z.object({
35
- keys: keyZ.array(),
36
- });
20
+ interface CreateRequest extends z.infer<typeof createReqZ> {}
21
+ export interface CreateOptions extends Pick<CreateRequest, "parent"> {}
37
22
 
23
+ const deleteReqZ = z.object({ keys: keyZ.array() });
38
24
  const deleteResZ = z.object({});
39
25
 
40
- const renameReqZ = z.object({
41
- key: keyZ,
42
- name: z.string(),
43
- });
44
-
26
+ const renameReqZ = z.object({ key: keyZ, name: nameZ });
45
27
  const renameResZ = z.object({});
46
28
 
47
29
  const CREATE_ENDPOINT = "/range/create";
@@ -65,7 +47,7 @@ export class Writer {
65
47
  );
66
48
  }
67
49
 
68
- async create(ranges: NewPayload[], options?: CreateOptions): Promise<Payload[]> {
50
+ async create(ranges: New[], options?: CreateOptions): Promise<Payload[]> {
69
51
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
70
52
  this.client,
71
53
  CREATE_ENDPOINT,
@@ -14,10 +14,9 @@ import { type Series } from "@synnaxlabs/x/telem";
14
14
  import { type channel } from "@/channel";
15
15
  import { framer } from "@/framer";
16
16
 
17
- export type Decoder<K, V> = (
18
- variant: change.Variant,
19
- data: Series,
20
- ) => Array<change.Change<K, V>>;
17
+ export interface Decoder<K, V> {
18
+ (variant: change.Variant, data: Series): Array<change.Change<K, V>>;
19
+ }
21
20
 
22
21
  export interface Observable<K, V>
23
22
  extends observe.ObservableAsyncCloseable<Array<change.Change<K, V>>> {}
@@ -11,7 +11,8 @@ import { type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { toArray } from "@synnaxlabs/x";
12
12
 
13
13
  import { MultipleFoundError, NotFoundError } from "@/errors";
14
- import { type Key, type NewUser, type User } from "@/user/payload";
14
+ import { ontology } from "@/ontology";
15
+ import { type Key, type New, ONTOLOGY_TYPE, type User } from "@/user/payload";
15
16
  import { Retriever } from "@/user/retriever";
16
17
  import { Writer } from "@/user/writer";
17
18
 
@@ -24,11 +25,11 @@ export class Client {
24
25
  this.reader = new Retriever(client);
25
26
  }
26
27
 
27
- async create(user: NewUser): Promise<User>;
28
+ async create(user: New): Promise<User>;
28
29
 
29
- async create(users: NewUser[]): Promise<User[]>;
30
+ async create(users: New[]): Promise<User[]>;
30
31
 
31
- async create(users: NewUser | NewUser[]): Promise<User | User[]> {
32
+ async create(users: New | New[]): Promise<User | User[]> {
32
33
  const isMany = Array.isArray(users);
33
34
  const res = await this.writer.create(users);
34
35
  return isMany ? res : res[0];
@@ -79,3 +80,6 @@ export class Client {
79
80
  await this.writer.delete(keys);
80
81
  }
81
82
  }
83
+
84
+ export const ontologyID = (key: Key): ontology.ID =>
85
+ new ontology.ID({ type: ONTOLOGY_TYPE, key });
@@ -9,8 +9,6 @@
9
9
 
10
10
  import { z } from "zod";
11
11
 
12
- import { ontology } from "@/ontology";
13
-
14
12
  export const keyZ = z.string().uuid();
15
13
  export type Key = z.infer<typeof keyZ>;
16
14
 
@@ -24,15 +22,13 @@ export const userZ = z.object({
24
22
  lastName: z.string().default(""),
25
23
  rootUser: z.boolean().default(true),
26
24
  });
27
- export type User = z.infer<typeof userZ>;
25
+ export interface User extends z.infer<typeof userZ> {}
28
26
 
29
- export const newUserZ = userZ
27
+ export const newZ = userZ
30
28
  .partial({ key: true, firstName: true, lastName: true })
31
29
  .omit({ rootUser: true })
32
30
  .extend({ password: z.string().min(1) });
33
- export type NewUser = z.infer<typeof newUserZ>;
34
-
35
- export const ONTOLOGY_TYPE: ontology.ResourceType = "user";
31
+ export interface New extends z.infer<typeof newZ> {}
36
32
 
37
- export const ontologyID = (key: Key): ontology.ID =>
38
- new ontology.ID({ type: ONTOLOGY_TYPE, key });
33
+ export const ONTOLOGY_TYPE = "user";
34
+ export type OntologyType = typeof ONTOLOGY_TYPE;
@@ -17,7 +17,7 @@ const reqZ = z.object({
17
17
  keys: keyZ.array().optional(),
18
18
  usernames: z.string().array().optional(),
19
19
  });
20
- type Request = z.infer<typeof reqZ>;
20
+ interface Request extends z.infer<typeof reqZ> {}
21
21
  const resZ = z.object({ users: nullableArrayZ(userZ) });
22
22
  const ENDPOINT = "/user/retrieve";
23
23
 
@@ -14,31 +14,33 @@ import { AuthError, NotFoundError } from "@/errors";
14
14
  import { newClient } from "@/setupspecs";
15
15
  import { type user } from "@/user";
16
16
 
17
- type SortType = { username: string };
17
+ interface SortType {
18
+ username: string;
19
+ }
18
20
 
19
21
  const sort = (a: SortType, b: SortType) => a.username.localeCompare(b.username);
20
22
 
21
23
  const client = newClient();
22
24
 
23
- const userOne: user.NewUser = {
24
- username: id.id(),
25
+ const userOne: user.New = {
26
+ username: id.create(),
25
27
  password: "test",
26
28
  firstName: "George",
27
29
  lastName: "Washington",
28
30
  };
29
31
 
30
- const userTwo: user.NewUser = { username: id.id(), password: "test" };
32
+ const userTwo: user.New = { username: id.create(), password: "test" };
31
33
 
32
- const userThree: user.NewUser = {
33
- username: id.id(),
34
+ const userThree: user.New = {
35
+ username: id.create(),
34
36
  password: "test",
35
37
  firstName: "John",
36
38
  lastName: "Adams",
37
39
  };
38
40
 
39
- const userArray: user.NewUser[] = [
40
- { username: id.id(), password: "secondTest", firstName: "Steve" },
41
- { username: id.id(), password: "testArray" },
41
+ const userArray: user.New[] = [
42
+ { username: id.create(), password: "secondTest", firstName: "Steve" },
43
+ { username: id.create(), password: "testArray" },
42
44
  ].sort(sort);
43
45
 
44
46
  describe("User", () => {
@@ -107,7 +109,7 @@ describe("User", () => {
107
109
  expect(res.lastName).toEqual(userOne.lastName);
108
110
  });
109
111
  test("not found", async () =>
110
- await expect(client.user.retrieveByName(id.id())).rejects.toThrow(
112
+ await expect(client.user.retrieveByName(id.create())).rejects.toThrow(
111
113
  NotFoundError,
112
114
  ));
113
115
  });
@@ -125,13 +127,13 @@ describe("User", () => {
125
127
  });
126
128
  });
127
129
  test("not found", async () => {
128
- const res = await client.user.retrieveByName([id.id()]);
130
+ const res = await client.user.retrieveByName([id.create()]);
129
131
  expect(res).toEqual([]);
130
132
  });
131
133
  test("extra names getting deleted", async () => {
132
134
  const res = await client.user.retrieveByName([
133
135
  ...userArray.map((u) => u.username),
134
- id.id(),
136
+ id.create(),
135
137
  ]);
136
138
  expect(res.sort(sort)).toHaveLength(2);
137
139
  res.forEach((u, i) => {
@@ -205,7 +207,7 @@ describe("User", () => {
205
207
  });
206
208
  describe("Change Username", () => {
207
209
  test("Successful", async () => {
208
- const newUsername = id.id();
210
+ const newUsername = id.create();
209
211
  await expect(
210
212
  client.user.changeUsername(userOne.key as string, newUsername),
211
213
  ).resolves.toBeUndefined();
@@ -221,12 +223,12 @@ describe("User", () => {
221
223
  client.user.changeUsername(userTwo.key as string, userOne.username),
222
224
  ).rejects.toThrow(AuthError));
223
225
  test("Repeated usernames fail", async () => {
224
- const oldUsername = id.id();
226
+ const oldUsername = id.create();
225
227
  const user = await client.user.create({
226
228
  username: oldUsername,
227
229
  password: "test",
228
230
  });
229
- const newUsername = id.id();
231
+ const newUsername = id.create();
230
232
  await client.user.changeUsername(user.key, newUsername);
231
233
  await expect(
232
234
  client.user.create({ username: newUsername, password: "test" }),
@@ -11,16 +11,9 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { toArray } from "@synnaxlabs/x/toArray";
12
12
  import { z } from "zod";
13
13
 
14
- import {
15
- type Key,
16
- keyZ,
17
- type NewUser,
18
- newUserZ,
19
- type User,
20
- userZ,
21
- } from "@/user/payload";
14
+ import { type Key, keyZ, type New, newZ, type User, userZ } from "@/user/payload";
22
15
 
23
- const createReqZ = z.object({ users: newUserZ.array() });
16
+ const createReqZ = z.object({ users: newZ.array() });
24
17
  const createResZ = z.object({ users: userZ.array() });
25
18
 
26
19
  const changeUsernameReqZ = z.object({ key: keyZ, username: z.string().min(1) });
@@ -48,7 +41,7 @@ export class Writer {
48
41
  this.client = client;
49
42
  }
50
43
 
51
- async create(users: NewUser | NewUser[]): Promise<User[]> {
44
+ async create(users: New | New[]): Promise<User[]> {
52
45
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
53
46
  this.client,
54
47
  CREATE_ENDPOINT,
@@ -0,0 +1,13 @@
1
+ // Copyright 2025 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 { binary, type UnknownRecord } from "@synnaxlabs/x";
11
+
12
+ export const decodeJSONString = (s: string): UnknownRecord =>
13
+ s ? binary.JSON_CODEC.decodeString(s) : {};
@@ -0,0 +1,19 @@
1
+ // Copyright 2025 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 { type UnknownRecord } from "@synnaxlabs/x/record";
11
+
12
+ // --- VERY IMPORTANT ---
13
+ // Synnax's encoders (in the binary package inside x) automatically convert the case of
14
+ // keys in objects to snake_case and back to camelCase when encoding and decoding
15
+ // respectively. This is done to ensure that the keys are consistent across all
16
+ // languages and platforms. Sometimes items have keys that are uuids, which have dashes,
17
+ // and those get messed up. So we just use regular JSON for these items.
18
+ export const parseWithoutKeyConversion = (s: string): UnknownRecord =>
19
+ s ? JSON.parse(s) : {};