@synnaxlabs/client 0.30.0 → 0.31.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 (115) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/api/client.api.md +615 -261
  3. package/dist/access/client.d.ts +2 -7
  4. package/dist/access/client.d.ts.map +1 -1
  5. package/dist/access/payload.d.ts +7 -102
  6. package/dist/access/payload.d.ts.map +1 -1
  7. package/dist/access/policy/client.d.ts +17 -0
  8. package/dist/access/policy/client.d.ts.map +1 -0
  9. package/dist/access/policy/external.d.ts +3 -0
  10. package/dist/access/policy/external.d.ts.map +1 -0
  11. package/dist/access/policy/index.d.ts +2 -0
  12. package/dist/access/policy/index.d.ts.map +1 -0
  13. package/dist/access/policy/payload.d.ts +163 -0
  14. package/dist/access/policy/payload.d.ts.map +1 -0
  15. package/dist/access/policy/policy.spec.d.ts +2 -0
  16. package/dist/access/policy/policy.spec.d.ts.map +1 -0
  17. package/dist/access/policy/retriever.d.ts +36 -0
  18. package/dist/access/policy/retriever.d.ts.map +1 -0
  19. package/dist/access/policy/writer.d.ts +9 -0
  20. package/dist/access/policy/writer.d.ts.map +1 -0
  21. package/dist/auth/auth.d.ts +6 -30
  22. package/dist/auth/auth.d.ts.map +1 -1
  23. package/dist/channel/payload.d.ts +17 -17
  24. package/dist/channel/payload.d.ts.map +1 -1
  25. package/dist/channel/retriever.d.ts +8 -8
  26. package/dist/client.cjs +31 -21
  27. package/dist/client.js +2962 -2233
  28. package/dist/framer/client.d.ts +4 -1
  29. package/dist/framer/client.d.ts.map +1 -1
  30. package/dist/framer/frame.d.ts +27 -80
  31. package/dist/framer/frame.d.ts.map +1 -1
  32. package/dist/framer/streamer.d.ts +3 -1
  33. package/dist/framer/streamer.d.ts.map +1 -1
  34. package/dist/framer/writer.d.ts +24 -16
  35. package/dist/framer/writer.d.ts.map +1 -1
  36. package/dist/hardware/device/client.d.ts +2 -2
  37. package/dist/hardware/device/payload.d.ts +1 -1
  38. package/dist/hardware/device/payload.d.ts.map +1 -1
  39. package/dist/hardware/rack/payload.d.ts +1 -1
  40. package/dist/hardware/rack/payload.d.ts.map +1 -1
  41. package/dist/hardware/task/client.d.ts +2 -2
  42. package/dist/hardware/task/ni/types.d.ts +16 -16
  43. package/dist/hardware/task/payload.d.ts +13 -13
  44. package/dist/hardware/task/payload.d.ts.map +1 -1
  45. package/dist/index.d.ts +6 -2
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/label/payload.d.ts +1 -1
  48. package/dist/label/payload.d.ts.map +1 -1
  49. package/dist/label/writer.d.ts +5 -5
  50. package/dist/ontology/client.d.ts +32 -30
  51. package/dist/ontology/client.d.ts.map +1 -1
  52. package/dist/ontology/payload.d.ts +62 -63
  53. package/dist/ontology/payload.d.ts.map +1 -1
  54. package/dist/ranger/payload.d.ts +2 -2
  55. package/dist/ranger/payload.d.ts.map +1 -1
  56. package/dist/ranger/writer.d.ts +5 -5
  57. package/dist/user/client.d.ts +13 -3
  58. package/dist/user/client.d.ts.map +1 -1
  59. package/dist/user/payload.d.ts +34 -3
  60. package/dist/user/payload.d.ts.map +1 -1
  61. package/dist/user/retriever.d.ts +21 -0
  62. package/dist/user/retriever.d.ts.map +1 -0
  63. package/dist/user/user.spec.d.ts +2 -0
  64. package/dist/user/user.spec.d.ts.map +1 -0
  65. package/dist/user/writer.d.ts +11 -0
  66. package/dist/user/writer.d.ts.map +1 -0
  67. package/dist/workspace/lineplot/payload.d.ts +1 -1
  68. package/dist/workspace/lineplot/payload.d.ts.map +1 -1
  69. package/dist/workspace/payload.d.ts +1 -1
  70. package/dist/workspace/payload.d.ts.map +1 -1
  71. package/dist/workspace/schematic/client.d.ts.map +1 -1
  72. package/dist/workspace/schematic/payload.d.ts +1 -1
  73. package/dist/workspace/schematic/payload.d.ts.map +1 -1
  74. package/examples/node/package-lock.json +963 -134
  75. package/examples/node/package.json +1 -1
  76. package/package.json +3 -3
  77. package/src/access/client.ts +4 -70
  78. package/src/access/payload.ts +14 -24
  79. package/src/access/policy/client.ts +65 -0
  80. package/src/access/policy/external.ts +11 -0
  81. package/src/access/policy/index.ts +10 -0
  82. package/src/access/policy/payload.ts +45 -0
  83. package/src/access/policy/policy.spec.ts +331 -0
  84. package/src/access/policy/retriever.ts +43 -0
  85. package/src/access/policy/writer.ts +65 -0
  86. package/src/auth/auth.ts +32 -10
  87. package/src/channel/payload.ts +2 -2
  88. package/src/framer/client.ts +7 -1
  89. package/src/framer/frame.spec.ts +21 -12
  90. package/src/framer/frame.ts +9 -24
  91. package/src/framer/streamer.spec.ts +48 -0
  92. package/src/framer/streamer.ts +7 -4
  93. package/src/framer/writer.ts +0 -2
  94. package/src/hardware/device/payload.ts +2 -2
  95. package/src/hardware/rack/payload.ts +2 -2
  96. package/src/hardware/task/payload.ts +2 -2
  97. package/src/index.ts +16 -13
  98. package/src/label/payload.ts +2 -2
  99. package/src/ontology/client.ts +35 -34
  100. package/src/ontology/payload.ts +28 -35
  101. package/src/ranger/payload.ts +5 -7
  102. package/src/setupspecs.ts +2 -2
  103. package/src/user/client.ts +63 -19
  104. package/src/user/payload.ts +14 -7
  105. package/src/user/retriever.ts +41 -0
  106. package/src/user/user.spec.ts +289 -0
  107. package/src/user/writer.ts +91 -0
  108. package/src/workspace/lineplot/payload.ts +2 -2
  109. package/src/workspace/payload.ts +2 -2
  110. package/src/workspace/schematic/client.ts +1 -1
  111. package/src/workspace/schematic/payload.ts +2 -2
  112. package/src/workspace/workspace.spec.ts +1 -1
  113. package/dist/access/access.spec.d.ts +0 -2
  114. package/dist/access/access.spec.d.ts.map +0 -1
  115. package/src/access/access.spec.ts +0 -276
@@ -0,0 +1,65 @@
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 { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
+ import { toArray } from "@synnaxlabs/x";
12
+ import { z } from "zod";
13
+
14
+ import {
15
+ type Key,
16
+ keyZ,
17
+ type NewPolicy,
18
+ newPolicyZ,
19
+ type Policy,
20
+ policyZ,
21
+ } from "@/access/policy/payload";
22
+
23
+ const createReqZ = z.object({ policies: policyZ.partial({ key: true }).array() });
24
+ const createResZ = z.object({ policies: policyZ.array() });
25
+
26
+ const deleteReqZ = z.object({ keys: keyZ.array() });
27
+ const deleteResZ = z.object({});
28
+
29
+ const CREATE_ENDPOINT = "/access/policy/create";
30
+ const DELETE_ENDPOINT = "/access/policy/delete";
31
+
32
+ export class Writer {
33
+ private readonly client: UnaryClient;
34
+
35
+ constructor(client: UnaryClient) {
36
+ this.client = client;
37
+ }
38
+
39
+ async create(policies: NewPolicy | NewPolicy[]): Promise<Policy[]> {
40
+ const parsedPolicies = newPolicyZ.array().parse(toArray(policies));
41
+ const req = parsedPolicies.map((policy) => ({
42
+ objects: toArray(policy.objects),
43
+ actions: toArray(policy.actions),
44
+ subjects: toArray(policy.subjects),
45
+ }));
46
+ const res = await sendRequired<typeof createReqZ, typeof createResZ>(
47
+ this.client,
48
+ CREATE_ENDPOINT,
49
+ { policies: req },
50
+ createReqZ,
51
+ createResZ,
52
+ );
53
+ return res.policies;
54
+ }
55
+
56
+ async delete(keys: Key | Key[]): Promise<void> {
57
+ await sendRequired<typeof deleteReqZ, typeof deleteResZ>(
58
+ this.client,
59
+ DELETE_ENDPOINT,
60
+ { keys: toArray(keys) },
61
+ deleteReqZ,
62
+ deleteResZ,
63
+ );
64
+ }
65
+ }
package/src/auth/auth.ts CHANGED
@@ -7,36 +7,43 @@
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 Middleware, type UnaryClient } from "@synnaxlabs/freighter";
10
+ import { type Middleware, sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { z } from "zod";
12
12
 
13
13
  import { InvalidTokenError } from "@/errors";
14
14
  import { user } from "@/user";
15
15
 
16
- export const insecureCredentialsZ = z.object({
16
+ const insecureCredentialsZ = z.object({
17
17
  username: z.string(),
18
18
  password: z.string(),
19
19
  });
20
- export type InsecureCredentials = z.infer<typeof insecureCredentialsZ>;
20
+ type InsecureCredentials = z.infer<typeof insecureCredentialsZ>;
21
21
 
22
- export const tokenResponseZ = z.object({
22
+ const tokenResponseZ = z.object({
23
23
  token: z.string(),
24
- user: user.payloadZ,
24
+ user: user.userZ,
25
25
  });
26
26
 
27
- export type TokenResponse = z.infer<typeof tokenResponseZ>;
28
-
29
27
  const LOGIN_ENDPOINT = "/auth/login";
30
28
 
31
29
  const MAX_RETRIES = 3;
32
30
 
31
+ const CHANGE_PASSWORD_ENDPOINT = "/auth/change-password";
32
+
33
+ const changePasswordReqZ = z.object({
34
+ username: z.string(),
35
+ password: z.string(),
36
+ newPassword: z.string().min(1),
37
+ });
38
+ const changePasswordResZ = z.object({});
39
+
33
40
  export class Client {
34
41
  token: string | undefined;
35
42
  private readonly client: UnaryClient;
36
43
  private readonly credentials: InsecureCredentials;
37
- private authenticating: Promise<Error | null> | undefined;
44
+ authenticating: Promise<Error | null> | undefined;
38
45
  authenticated: boolean;
39
- user: user.Payload | undefined;
46
+ user: user.User | undefined;
40
47
  private retryCount: number;
41
48
 
42
49
  constructor(client: UnaryClient, credentials: InsecureCredentials) {
@@ -46,6 +53,22 @@ export class Client {
46
53
  this.retryCount = 0;
47
54
  }
48
55
 
56
+ async changePassword(newPassword: string): Promise<void> {
57
+ if (!this.authenticated) throw new Error("Not authenticated");
58
+ await sendRequired<typeof changePasswordReqZ, typeof changePasswordResZ>(
59
+ this.client,
60
+ CHANGE_PASSWORD_ENDPOINT,
61
+ {
62
+ username: this.credentials.username,
63
+ password: this.credentials.password,
64
+ newPassword,
65
+ },
66
+ changePasswordReqZ,
67
+ changePasswordResZ,
68
+ );
69
+ this.credentials.password = newPassword;
70
+ }
71
+
49
72
  middleware(): Middleware {
50
73
  const mw: Middleware = async (reqCtx, next) => {
51
74
  if (!this.authenticated && !reqCtx.target.endsWith(LOGIN_ENDPOINT)) {
@@ -54,7 +77,6 @@ export class Client {
54
77
  this.client
55
78
  .send(
56
79
  LOGIN_ENDPOINT,
57
-
58
80
  this.credentials,
59
81
  insecureCredentialsZ,
60
82
  tokenResponseZ,
@@ -48,7 +48,7 @@ export const newPayload = payload.extend({
48
48
 
49
49
  export type NewPayload = z.input<typeof newPayload>;
50
50
 
51
- export const ChannelOntologyType = "channel" as ontology.ResourceType;
51
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "channel";
52
52
 
53
53
  export const ontologyID = (key: Key): ontology.ID =>
54
- new ontology.ID({ type: ChannelOntologyType, key: key.toString() });
54
+ new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
@@ -24,6 +24,12 @@ import { Frame } from "@/framer/frame";
24
24
  import { Iterator, IteratorConfig } from "@/framer/iterator";
25
25
  import { Streamer, type StreamerConfig } from "@/framer/streamer";
26
26
  import { Writer, type WriterConfig, WriterMode } from "@/framer/writer";
27
+ import { ontology } from "@/ontology";
28
+
29
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "framer";
30
+
31
+ export const ontologyID = (key: Key): ontology.ID =>
32
+ new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
27
33
 
28
34
  export class Client {
29
35
  private readonly streamClient: StreamClient;
@@ -93,7 +99,7 @@ export class Client {
93
99
 
94
100
  async openStreamer(config: StreamerConfig | Params): Promise<Streamer> {
95
101
  if (Array.isArray(config) || typeof config !== "object")
96
- config = { channels: config as Params };
102
+ config = { channels: config as Params, downsampleFactor: 1 };
97
103
  return await Streamer._open(this.retriever, this.streamClient, config);
98
104
  }
99
105
 
@@ -75,19 +75,28 @@ describe("framer.Frame", () => {
75
75
  expect(f.colType).toEqual("name");
76
76
  });
77
77
 
78
- test("from payload", () => {
79
- const f = new framer.Frame({
80
- keys: [12],
81
- series: [
82
- {
83
- dataType: new DataType("float32"),
84
- data: new SharedArrayBuffer(12),
85
- },
86
- ],
78
+ describe("payload parsing", () => {
79
+ it("should correctly parse a series payload", () => {
80
+ const f = new framer.Frame({
81
+ keys: [12],
82
+ series: [
83
+ { dataType: new DataType("float32"), data: new SharedArrayBuffer(12) },
84
+ ],
85
+ });
86
+ expect(f.length.valueOf()).toEqual(3);
87
+ expect(f.columns.length).toEqual(1);
88
+ expect(f.series.length).toEqual(1);
89
+ });
90
+
91
+ it("should correctly parse a series with null data", () => {
92
+ const f = new framer.Frame({
93
+ keys: [12],
94
+ series: [{ dataType: "float32", data: null }],
95
+ });
96
+ expect(f.length.valueOf()).toEqual(0);
97
+ expect(f.columns.length).toEqual(1);
98
+ expect(f.series.length).toEqual(1);
87
99
  });
88
- expect(f.length.valueOf()).toEqual(3);
89
- expect(f.columns.length).toEqual(1);
90
- expect(f.series.length).toEqual(1);
91
100
  });
92
101
 
93
102
  test("from record", () => {
@@ -8,9 +8,9 @@
8
8
  // included in the file licenses/APL.txt.
9
9
 
10
10
  import {
11
- DataType,
12
11
  MultiSeries,
13
12
  Series,
13
+ SeriesPayload,
14
14
  Size,
15
15
  type TelemValue,
16
16
  TimeRange,
@@ -55,7 +55,7 @@ const validateMatchedColsAndSeries = (columns: Params, series: Series[]): void =
55
55
 
56
56
  export type CrudeFrame =
57
57
  | Frame
58
- | FramePayload
58
+ | CrudeFramePayload
59
59
  | Map<KeyOrName, Series[] | Series>
60
60
  | Record<KeyOrName, Series[] | Series>;
61
61
 
@@ -117,6 +117,8 @@ export class Frame {
117
117
  if (isObject) {
118
118
  if ("keys" in columnsOrData && "series" in columnsOrData) {
119
119
  const data_ = columnsOrData as FramePayload;
120
+ data_.series ??= [];
121
+ data_.keys ??= [];
120
122
  const series = data_.series.map((a) => seriesFromPayload(a));
121
123
  validateMatchedColsAndSeries(data_.keys, series);
122
124
  data_.keys.forEach((key, i) => this.push(key, series[i]));
@@ -396,37 +398,20 @@ export class Frame {
396
398
  }
397
399
  }
398
400
 
399
- export const series = z.object({
400
- timeRange: TimeRange.z.optional(),
401
- alignment: z
402
- .bigint()
403
- .or(z.string().transform((s) => BigInt(s)))
404
- .optional(),
405
- dataType: DataType.z,
406
- data: z.string().transform(
407
- (s) =>
408
- new Uint8Array(
409
- atob(s)
410
- .split("")
411
- .map((c) => c.charCodeAt(0)),
412
- ).buffer,
413
- ),
414
- });
415
-
416
- export type SeriesPayload = z.infer<typeof series>;
417
-
418
401
  export const frameZ = z.object({
419
402
  keys: z.union([
420
403
  z.null().transform(() => [] as number[]),
421
404
  z.number().array().optional().default([]),
422
405
  ]),
423
406
  series: z.union([
424
- z.null().transform(() => [] as Array<z.infer<typeof series>>),
425
- series.array().optional().default([]),
407
+ z.null().transform(() => [] as Array<z.infer<typeof Series.crudeZ>>),
408
+ Series.crudeZ.array().optional().default([]),
426
409
  ]),
427
410
  });
428
411
 
429
- export type FramePayload = z.infer<typeof frameZ>;
412
+ export type FramePayload = z.output<typeof frameZ>;
413
+
414
+ export type CrudeFramePayload = z.input<typeof frameZ>;
430
415
 
431
416
  export const seriesFromPayload = (series: SeriesPayload): Series => {
432
417
  const { dataType, data, timeRange, alignment } = series;
@@ -50,4 +50,52 @@ describe("Streamer", () => {
50
50
  it("should throw an error when the streamer is opened with a channel that does not exist", async () => {
51
51
  await expect(client.openStreamer([5678])).rejects.toThrow("not found");
52
52
  });
53
+ test("downsample factor of 1", async () => {
54
+ const ch = await newChannel();
55
+ const streamer = await client.openStreamer({channels: ch.key, downsampleFactor: 1});
56
+ await new Promise((resolve) => setTimeout(resolve, 100));
57
+ const writer = await client.openWriter({
58
+ start: TimeStamp.now(),
59
+ channels: ch.key,
60
+ });
61
+ try {
62
+ await writer.write(ch.key, new Float64Array([1, 2, 3, 4, 5]));
63
+ } finally {
64
+ await writer.close();
65
+ }
66
+ const d = await streamer.read();
67
+ expect(Array.from(d.get(ch.key))).toEqual([1, 2, 3, 4, 5]);
68
+ });
69
+ test("downsample factor of 2", async () => {
70
+ const ch = await newChannel();
71
+ const streamer = await client.openStreamer({channels: ch.key, downsampleFactor: 2});
72
+ await new Promise((resolve) => setTimeout(resolve, 100));
73
+ const writer = await client.openWriter({
74
+ start: TimeStamp.now(),
75
+ channels: ch.key,
76
+ });
77
+ try {
78
+ await writer.write(ch.key, new Float64Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));
79
+ } finally {
80
+ await writer.close();
81
+ }
82
+ const d = await streamer.read();
83
+ expect(Array.from(d.get(ch.key))).toEqual([1, 3, 5, 7, 9]);
84
+ });
85
+ test("downsample factor of 10", async () => {
86
+ const ch = await newChannel();
87
+ const streamer = await client.openStreamer({channels: ch.key, downsampleFactor: 10});
88
+ await new Promise((resolve) => setTimeout(resolve, 100));
89
+ const writer = await client.openWriter({
90
+ start: TimeStamp.now(),
91
+ channels: ch.key,
92
+ });
93
+ try {
94
+ await writer.write(ch.key, new Float64Array([1, 2, 3, 4, 5, 6,7,8,9,10]));
95
+ } finally {
96
+ await writer.close();
97
+ }
98
+ const d = await streamer.read();
99
+ expect(Array.from(d.get(ch.key))).toEqual([1]);
100
+ });
53
101
  });
@@ -17,7 +17,7 @@ import { ReadFrameAdapter } from "@/framer/adapter";
17
17
  import { Frame, frameZ } from "@/framer/frame";
18
18
  import { StreamProxy } from "@/framer/streamProxy";
19
19
 
20
- const reqZ = z.object({ keys: z.number().array() });
20
+ const reqZ = z.object({ keys: z.number().array() , downsampleFactor: z.number() });
21
21
 
22
22
  const resZ = z.object({
23
23
  frame: frameZ,
@@ -28,11 +28,13 @@ const ENDPOINT = "/frame/stream";
28
28
 
29
29
  export interface StreamerConfig {
30
30
  channels: Params;
31
+ downsampleFactor?: number;
31
32
  }
32
33
 
33
34
  export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
34
35
  private readonly stream: StreamProxy<typeof reqZ, typeof resZ>;
35
36
  private readonly adapter: ReadFrameAdapter;
37
+ private readonly downsampleFactor: number;
36
38
 
37
39
  private constructor(
38
40
  stream: Stream<typeof reqZ, typeof resZ>,
@@ -40,6 +42,7 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
40
42
  ) {
41
43
  this.stream = new StreamProxy("Streamer", stream);
42
44
  this.adapter = adapter;
45
+ this.downsampleFactor = 1;
43
46
  }
44
47
 
45
48
  get keys(): Key[] {
@@ -49,12 +52,12 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
49
52
  static async _open(
50
53
  retriever: Retriever,
51
54
  client: StreamClient,
52
- { channels }: StreamerConfig,
55
+ { channels, downsampleFactor }: StreamerConfig,
53
56
  ): Promise<Streamer> {
54
57
  const adapter = await ReadFrameAdapter.open(retriever, channels);
55
58
  const stream = await client.stream(ENDPOINT, reqZ, resZ);
56
59
  const streamer = new Streamer(stream, adapter);
57
- stream.send({ keys: adapter.keys });
60
+ stream.send({ keys: adapter.keys, downsampleFactor: downsampleFactor ?? 1 });
58
61
  const [, err] = await stream.receive();
59
62
  if (err != null) throw err;
60
63
  return streamer;
@@ -76,7 +79,7 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
76
79
 
77
80
  async update(channels: Params): Promise<void> {
78
81
  await this.adapter.update(channels);
79
- this.stream.send({ keys: this.adapter.keys });
82
+ this.stream.send({ keys: this.adapter.keys, downsampleFactor: this.downsampleFactor });
80
83
  }
81
84
 
82
85
  close(): void {
@@ -231,7 +231,6 @@ export class Writer {
231
231
  series?: CrudeSeries | CrudeSeries[],
232
232
  ): Promise<boolean> {
233
233
  const frame = await this.adapter.adapt(channelsOrData, series);
234
- // @ts-expect-error - zod issues
235
234
  this.stream.send({ command: Command.Write, frame: frame.toPayload() });
236
235
  return true;
237
236
  }
@@ -298,7 +297,6 @@ export class Writer {
298
297
  }
299
298
 
300
299
  async execute(req: Request): Promise<Response> {
301
- // @ts-expect-error - frame payload adjustments
302
300
  this.stream.send(req);
303
301
  while (true) {
304
302
  const res = await this.stream.receive();
@@ -47,7 +47,7 @@ export type NewDevice<P extends UnknownRecord = UnknownRecord> = Omit<
47
47
  "properties"
48
48
  > & { properties: P };
49
49
 
50
- export const DeviceOntologyType = "device" as ontology.ResourceType;
50
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "device";
51
51
 
52
52
  export const ontologyID = (key: DeviceKey): ontology.ID =>
53
- new ontology.ID({ type: DeviceOntologyType, key: key.toString() });
53
+ new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
@@ -26,7 +26,7 @@ export const newRackZ = rackZ.partial({ key: true });
26
26
 
27
27
  export type NewRack = z.input<typeof newRackZ>;
28
28
 
29
- export const RackOntologyType = "rack" as ontology.ResourceType;
29
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "rack";
30
30
 
31
31
  export const ontologyID = (key: RackKey): ontology.ID =>
32
- new ontology.ID({ type: RackOntologyType, key: key.toString() });
32
+ new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
@@ -96,7 +96,7 @@ export const commandZ = z.object({
96
96
  export type StateObservable<D extends UnknownRecord = UnknownRecord> =
97
97
  observe.ObservableAsyncCloseable<State<D>>;
98
98
 
99
- export const DeviceOntologyType = "task" as ontology.ResourceType;
99
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "task";
100
100
 
101
101
  export const ontologyID = (key: TaskKey): ontology.ID =>
102
- new ontology.ID({ type: DeviceOntologyType, key: key.toString() });
102
+ new ontology.ID({ type: ONTOLOGY_TYPE, key: key.toString() });
package/src/index.ts CHANGED
@@ -7,6 +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
+ export { access } from "@/access";
11
+ export { policy } from "@/access/policy";
10
12
  export * from "@/channel";
11
13
  export { Channel } from "@/channel/client";
12
14
  export { default as Synnax, type SynnaxProps, synnaxPropsZ } from "@/client";
@@ -32,29 +34,30 @@ export { label } from "@/label";
32
34
  export { ontology } from "@/ontology";
33
35
  export { ranger } from "@/ranger";
34
36
  export { signals } from "@/signals";
37
+ export { user } from "@/user";
35
38
  export { workspace } from "@/workspace";
36
- export type {
37
- CrudeDataType,
38
- CrudeDensity,
39
- CrudeRate,
40
- CrudeSize,
41
- CrudeTimeSpan,
42
- CrudeTimeStamp,
43
- NumericTelemValue,
44
- TelemValue,
45
- TimeStampStringFormat,
46
- TypedArray,
47
- TZInfo,
48
- } from "@synnaxlabs/x/telem";
39
+ export { linePlot } from "@/workspace/lineplot";
40
+ export { schematic } from "@/workspace/schematic";
49
41
  export {
42
+ type CrudeDataType,
43
+ type CrudeDensity,
44
+ type CrudeRate,
45
+ type CrudeSize,
46
+ type CrudeTimeSpan,
47
+ type CrudeTimeStamp,
50
48
  DataType,
51
49
  Density,
52
50
  MultiSeries,
51
+ type NumericTelemValue,
53
52
  Rate,
54
53
  Series,
54
+ type TelemValue,
55
55
  TimeRange,
56
56
  TimeSpan,
57
57
  TimeStamp,
58
+ type TimeStampStringFormat,
59
+ type TypedArray,
60
+ type TZInfo,
58
61
  } from "@synnaxlabs/x/telem";
59
62
  import { control } from "@synnaxlabs/x";
60
63
  export const Authority = control.Authority;
@@ -25,7 +25,7 @@ export const labelZ = z.object({
25
25
 
26
26
  export type Label = z.infer<typeof labelZ>;
27
27
 
28
- export const LabelOntologyType = "label" as ontology.ResourceType;
28
+ export const ONTOLOGY_TYPE: ontology.ResourceType = "label";
29
29
 
30
30
  export const ontologyID = (key: Key): ontology.ID =>
31
- new ontology.ID({ type: LabelOntologyType, key });
31
+ new ontology.ID({ type: ONTOLOGY_TYPE, key });
@@ -13,19 +13,18 @@ import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
13
13
  import { z } from "zod";
14
14
 
15
15
  import { QueryError } from "@/errors";
16
- import { framer } from "@/framer";
17
- import { Frame } from "@/framer/frame";
16
+ import { type framer } from "@/framer";
18
17
  import { group } from "@/ontology/group";
19
18
  import {
20
- CrudeID,
19
+ type CrudeID,
21
20
  ID,
22
- IDPayload,
21
+ type IDPayload,
23
22
  idZ,
24
23
  parseRelationship,
25
- RelationshipChange,
26
- RelationshipDirection,
24
+ type RelationshipChange,
25
+ type RelationshipDirection,
27
26
  type Resource,
28
- ResourceChange,
27
+ type ResourceChange,
29
28
  resourceSchemaZ,
30
29
  resourceTypeZ,
31
30
  } from "@/ontology/payload";
@@ -92,12 +91,12 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
92
91
 
93
92
  /**
94
93
  * Retrieves the resource in the ontology with the given ID.
95
- * @param id The ID of the resource to retrieve.
96
- * @param options Additional options for the retrieval.
97
- * @param options.includeSchema Whether to include the schema of the resource in the
94
+ * @param id - The ID of the resource to retrieve.
95
+ * @param options - Additional options for the retrieval.
96
+ * @param options.includeSchema - Whether to include the schema of the resource in the
98
97
  * results.
99
- * @param options.excludeFieldData Whether to exclude the field data of the resource in
100
- * the results.
98
+ * @param options.excludeFieldData - Whether to exclude the field data of the resource
99
+ * in the results.
101
100
  * @returns The resource with the given ID.
102
101
  * @throws {QueryError} If no resource is found with the given ID.
103
102
  */
@@ -105,12 +104,13 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
105
104
 
106
105
  /**
107
106
  * Retrieves the resources in the ontology with the given IDs.
108
- * @param ids The IDs of the resources to retrieve.
109
- * @param options Additional options for the retrieval.
110
- * @param options.includeSchema Whether to include the schema of the resources in the
111
- * results.
112
- * @param options.excludeFieldData Whether to exclude the field data of the resources in
107
+ *
108
+ * @param ids - The IDs of the resources to retrieve.
109
+ * @param options - Additional options for the retrieval.
110
+ * @param options.includeSchema - Whether to include the schema of the resources in
113
111
  * the results.
112
+ * @param options.excludeFieldData - Whether to exclude the field data of the
113
+ * resources in the results.
114
114
  * @returns The resources with the given IDs.
115
115
  * @throws {QueryError} If no resource is found with any of the given IDs.
116
116
  */
@@ -164,10 +164,12 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
164
164
  /**
165
165
  * Retrieves the parents of the resources with the given IDs.
166
166
  *
167
- * @param ids the IDs of the resources whose parents to retrieve
168
- * @param options additional options for the retrieval
169
- * @param options.includeSchema whether to include the schema of the parents in the results
170
- * @param options.excludeFieldData whether to exclude the field data of the parents in the results
167
+ * @param ids - the IDs of the resources whose parents to retrieve
168
+ * @param options - additional options for the retrieval
169
+ * @param options.includeSchema - whether to include the schema of the parents in the
170
+ * results
171
+ * @param options.excludeFieldData - whether to exclude the field data of the parents
172
+ * in the results
171
173
  * @returns the parents of the resources with the given IDs
172
174
  */
173
175
  async retrieveParents(
@@ -179,8 +181,8 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
179
181
 
180
182
  /**
181
183
  * Adds children to a resource in the ontology.
182
- * @param id The ID of the resource to add children to.
183
- * @param children The IDs of the children to add.
184
+ * @param id - The ID of the resource to add children to.
185
+ * @param children - The IDs of the children to add.
184
186
  */
185
187
  async addChildren(id: CrudeID, ...children: CrudeID[]): Promise<void> {
186
188
  return await this.writer.addChildren(id, ...children);
@@ -188,9 +190,8 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
188
190
 
189
191
  /**
190
192
  * Removes children from a resource in the ontology.
191
- * @param id The ID of the resource to remove children from.
192
- * @param children The IDs of the children
193
- * to remove.
193
+ * @param id - The ID of the resource to remove children from.
194
+ * @param children - The IDs of the children to remove.
194
195
  */
195
196
  async removeChildren(id: CrudeID, ...children: CrudeID[]): Promise<void> {
196
197
  return await this.writer.removeChildren(id, ...children);
@@ -198,9 +199,9 @@ export class Client implements AsyncTermSearcher<string, string, Resource> {
198
199
 
199
200
  /**
200
201
  * Moves children from one resource to another in the ontology.
201
- * @param from The ID of the resource to move children from.
202
- * @param to The ID of the resource to move children to.
203
- * @param children The IDs of the children to move.
202
+ * @param from - The ID of the resource to move children from.
203
+ * @param to - The ID of the resource to move children to.
204
+ * @param children - The IDs of the children to move.
204
205
  */
205
206
  async moveChildren(
206
207
  from: CrudeID,
@@ -294,7 +295,7 @@ export class ChangeTracker {
294
295
  }
295
296
  }
296
297
 
297
- private async update(frame: Frame): Promise<void> {
298
+ private async update(frame: framer.Frame): Promise<void> {
298
299
  const resSets = await this.parseResourceSets(frame);
299
300
  const resDeletes = this.parseResourceDeletes(frame);
300
301
  const allResources = resSets.concat(resDeletes);
@@ -306,7 +307,7 @@ export class ChangeTracker {
306
307
  this.relationshipObs.notify(relSets.concat(relDeletes));
307
308
  }
308
309
 
309
- private parseRelationshipSets(frame: Frame): RelationshipChange[] {
310
+ private parseRelationshipSets(frame: framer.Frame): RelationshipChange[] {
310
311
  const relationships = frame.get(RELATIONSHIP_SET_NAME);
311
312
  if (relationships.length === 0) return [];
312
313
  return Array.from(relationships.as("string")).map((rel) => ({
@@ -316,7 +317,7 @@ export class ChangeTracker {
316
317
  }));
317
318
  }
318
319
 
319
- private parseRelationshipDeletes(frame: Frame): RelationshipChange[] {
320
+ private parseRelationshipDeletes(frame: framer.Frame): RelationshipChange[] {
320
321
  const relationships = frame.get(RELATIONSHIP_DELETE_NAME);
321
322
  if (relationships.length === 0) return [];
322
323
  return Array.from(relationships.as("string")).map((rel) => ({
@@ -325,7 +326,7 @@ export class ChangeTracker {
325
326
  }));
326
327
  }
327
328
 
328
- private async parseResourceSets(frame: Frame): Promise<ResourceChange[]> {
329
+ private async parseResourceSets(frame: framer.Frame): Promise<ResourceChange[]> {
329
330
  const sets = frame.get(RESOURCE_SET_NAME);
330
331
  if (sets.length === 0) return [];
331
332
  // We should only ever get one series of sets
@@ -343,7 +344,7 @@ export class ChangeTracker {
343
344
  }
344
345
  }
345
346
 
346
- private parseResourceDeletes(frame: Frame): ResourceChange[] {
347
+ private parseResourceDeletes(frame: framer.Frame): ResourceChange[] {
347
348
  const deletes = frame.get(RESOURCE_DELETE_NAME);
348
349
  if (deletes.length === 0) return [];
349
350
  // We should only ever get one series of deletes