@synnaxlabs/client 0.34.0 → 0.36.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.
- package/.turbo/turbo-build.log +7 -7
- package/dist/access/policy/payload.d.ts +40 -40
- package/dist/access/policy/retriever.d.ts +5 -5
- package/dist/client.cjs +28 -28
- package/dist/client.d.ts +35 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3092 -2820
- package/dist/control/state.d.ts.map +1 -1
- package/dist/framer/deleter.d.ts.map +1 -1
- package/dist/framer/frame.d.ts +14 -7
- package/dist/framer/frame.d.ts.map +1 -1
- package/dist/framer/writer.d.ts +8 -8
- package/dist/framer/writer.d.ts.map +1 -1
- package/dist/hardware/device/client.d.ts +2 -2
- package/dist/hardware/device/client.d.ts.map +1 -1
- package/dist/hardware/device/payload.d.ts +2 -2
- package/dist/hardware/device/payload.d.ts.map +1 -1
- package/dist/hardware/task/client.d.ts +4 -2
- package/dist/hardware/task/client.d.ts.map +1 -1
- package/dist/hardware/task/payload.d.ts +9 -5
- package/dist/hardware/task/payload.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/label/writer.d.ts +5 -5
- package/dist/ontology/client.d.ts +8 -8
- package/dist/ontology/group/payload.d.ts +3 -0
- package/dist/ontology/group/payload.d.ts.map +1 -1
- package/dist/ontology/payload.d.ts +43 -43
- package/dist/ontology/payload.d.ts.map +1 -1
- package/dist/ranger/client.d.ts +1 -0
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts +5 -5
- package/dist/ranger/writer.d.ts.map +1 -1
- package/dist/transport.d.ts +2 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/workspace/client.d.ts +70 -11
- package/dist/workspace/client.d.ts.map +1 -1
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/lineplot/client.d.ts +48 -6
- package/dist/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/index.d.ts +1 -1
- package/dist/workspace/lineplot/index.d.ts.map +1 -1
- package/dist/workspace/log/client.d.ts +48 -6
- package/dist/workspace/log/client.d.ts.map +1 -1
- package/dist/workspace/log/index.d.ts +1 -1
- package/dist/workspace/log/index.d.ts.map +1 -1
- package/dist/workspace/schematic/client.d.ts +72 -6
- package/dist/workspace/schematic/client.d.ts.map +1 -1
- package/dist/workspace/schematic/index.d.ts +1 -1
- package/dist/workspace/schematic/index.d.ts.map +1 -1
- package/dist/workspace/table/client.d.ts +71 -0
- package/dist/workspace/table/client.d.ts.map +1 -0
- package/dist/workspace/table/index.d.ts +2 -0
- package/dist/workspace/table/index.d.ts.map +1 -0
- package/dist/workspace/table/table.spec.d.ts +2 -0
- package/dist/workspace/table/table.spec.d.ts.map +1 -0
- package/package.json +10 -10
- package/src/client.ts +16 -2
- package/src/control/state.ts +1 -1
- package/src/framer/frame.spec.ts +32 -3
- package/src/framer/frame.ts +17 -0
- package/src/hardware/device/client.ts +10 -4
- package/src/hardware/task/client.ts +51 -3
- package/src/hardware/task/payload.ts +21 -6
- package/src/index.ts +2 -0
- package/src/ontology/group/payload.ts +8 -7
- package/src/ontology/payload.ts +1 -0
- package/src/ranger/client.ts +4 -1
- package/src/transport.ts +8 -3
- package/src/workspace/client.ts +151 -47
- package/src/workspace/index.ts +1 -1
- package/src/workspace/lineplot/client.ts +96 -28
- package/src/workspace/lineplot/index.ts +1 -1
- package/src/workspace/log/client.ts +93 -28
- package/src/workspace/log/index.ts +1 -1
- package/src/workspace/schematic/client.ts +121 -29
- package/src/workspace/schematic/index.ts +1 -1
- package/src/workspace/table/client.ts +125 -0
- package/src/workspace/{external.ts → table/index.ts} +1 -2
- package/src/workspace/table/table.spec.ts +65 -0
- package/dist/workspace/external.d.ts +0 -3
- package/dist/workspace/external.d.ts.map +0 -1
- package/dist/workspace/lineplot/external.d.ts +0 -3
- package/dist/workspace/lineplot/external.d.ts.map +0 -1
- package/dist/workspace/lineplot/retriever.d.ts +0 -9
- package/dist/workspace/lineplot/retriever.d.ts.map +0 -1
- package/dist/workspace/lineplot/writer.d.ts +0 -35
- package/dist/workspace/lineplot/writer.d.ts.map +0 -1
- package/dist/workspace/log/external.d.ts +0 -3
- package/dist/workspace/log/external.d.ts.map +0 -1
- package/dist/workspace/log/payload.d.ts +0 -36
- package/dist/workspace/log/payload.d.ts.map +0 -1
- package/dist/workspace/log/retriever.d.ts +0 -9
- package/dist/workspace/log/retriever.d.ts.map +0 -1
- package/dist/workspace/log/writer.d.ts +0 -35
- package/dist/workspace/log/writer.d.ts.map +0 -1
- package/dist/workspace/payload.d.ts +0 -38
- package/dist/workspace/payload.d.ts.map +0 -1
- package/dist/workspace/retriever.d.ts +0 -13
- package/dist/workspace/retriever.d.ts.map +0 -1
- package/dist/workspace/schematic/external.d.ts +0 -3
- package/dist/workspace/schematic/external.d.ts.map +0 -1
- package/dist/workspace/schematic/payload.d.ts +0 -42
- package/dist/workspace/schematic/payload.d.ts.map +0 -1
- package/dist/workspace/schematic/retriever.d.ts +0 -9
- package/dist/workspace/schematic/retriever.d.ts.map +0 -1
- package/dist/workspace/schematic/writer.d.ts +0 -41
- package/dist/workspace/schematic/writer.d.ts.map +0 -1
- package/dist/workspace/writer.d.ts +0 -66
- package/dist/workspace/writer.d.ts.map +0 -1
- package/src/workspace/lineplot/external.ts +0 -11
- package/src/workspace/lineplot/retriever.ts +0 -34
- package/src/workspace/lineplot/writer.ts +0 -115
- package/src/workspace/log/external.ts +0 -11
- package/src/workspace/log/payload.ts +0 -36
- package/src/workspace/log/retriever.ts +0 -38
- package/src/workspace/log/writer.ts +0 -116
- package/src/workspace/payload.ts +0 -44
- package/src/workspace/retriever.ts +0 -70
- package/src/workspace/schematic/external.ts +0 -11
- package/src/workspace/schematic/payload.ts +0 -38
- package/src/workspace/schematic/retriever.ts +0 -42
- package/src/workspace/schematic/writer.ts +0 -140
- package/src/workspace/writer.ts +0 -111
|
@@ -19,6 +19,9 @@ import { framer } from "@/framer";
|
|
|
19
19
|
import { type Frame } from "@/framer/frame";
|
|
20
20
|
import { rack } from "@/hardware/rack";
|
|
21
21
|
import {
|
|
22
|
+
type Command,
|
|
23
|
+
type CommandObservable,
|
|
24
|
+
commandZ,
|
|
22
25
|
type NewTask,
|
|
23
26
|
newTaskZ,
|
|
24
27
|
type Payload,
|
|
@@ -46,7 +49,7 @@ export class Task<
|
|
|
46
49
|
T extends string = string,
|
|
47
50
|
> {
|
|
48
51
|
readonly key: TaskKey;
|
|
49
|
-
|
|
52
|
+
name: string;
|
|
50
53
|
readonly internal: boolean;
|
|
51
54
|
readonly type: T;
|
|
52
55
|
config: C;
|
|
@@ -139,7 +142,10 @@ export class Task<
|
|
|
139
142
|
const s = frame.get(TASK_STATE_CHANNEL);
|
|
140
143
|
if (s.length === 0) return [null, false];
|
|
141
144
|
const parse = stateZ.safeParse(s.at(-1));
|
|
142
|
-
if (!parse.success)
|
|
145
|
+
if (!parse.success) {
|
|
146
|
+
console.error(parse.error);
|
|
147
|
+
return [null, false];
|
|
148
|
+
}
|
|
143
149
|
const state = parse.data as State<D>;
|
|
144
150
|
if (state.task !== this.key) return [null, false];
|
|
145
151
|
return [state, true];
|
|
@@ -147,6 +153,27 @@ export class Task<
|
|
|
147
153
|
);
|
|
148
154
|
}
|
|
149
155
|
|
|
156
|
+
async openCommandObserver<A extends UnknownRecord = UnknownRecord>(): Promise<
|
|
157
|
+
CommandObservable<A>
|
|
158
|
+
> {
|
|
159
|
+
if (this.frameClient == null) throw TASK_NOT_CREATED;
|
|
160
|
+
return new framer.ObservableStreamer<Command<A>>(
|
|
161
|
+
await this.frameClient.openStreamer(TASK_CMD_CHANNEL),
|
|
162
|
+
(frame) => {
|
|
163
|
+
const s = frame.get(TASK_CMD_CHANNEL);
|
|
164
|
+
if (s.length === 0) return [null, false];
|
|
165
|
+
const parse = commandZ.safeParse(s.at(-1));
|
|
166
|
+
if (!parse.success) {
|
|
167
|
+
console.error(parse.error);
|
|
168
|
+
return [null, false];
|
|
169
|
+
}
|
|
170
|
+
const cmd = parse.data as Command<A>;
|
|
171
|
+
if (cmd.task !== this.key) return [null, false];
|
|
172
|
+
return [cmd, true];
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
150
177
|
async snapshottedTo(): Promise<ontology.Resource | null> {
|
|
151
178
|
if (this.ontologyClient == null || this.rangeClient == null) throw TASK_NOT_CREATED;
|
|
152
179
|
if (!this.snapshot) return null;
|
|
@@ -376,9 +403,30 @@ export class Client implements AsyncTermSearcher<string, TaskKey, Payload> {
|
|
|
376
403
|
const s = frame.get(TASK_STATE_CHANNEL);
|
|
377
404
|
if (s.length === 0) return [null, false];
|
|
378
405
|
const parse = stateZ.safeParse(s.at(-1));
|
|
379
|
-
if (!parse.success)
|
|
406
|
+
if (!parse.success) {
|
|
407
|
+
console.error(parse.error);
|
|
408
|
+
return [null, false];
|
|
409
|
+
}
|
|
380
410
|
return [parse.data as State<D>, true];
|
|
381
411
|
},
|
|
382
412
|
);
|
|
383
413
|
}
|
|
414
|
+
|
|
415
|
+
async openCommandObserver<A extends UnknownRecord = UnknownRecord>(): Promise<
|
|
416
|
+
CommandObservable<A>
|
|
417
|
+
> {
|
|
418
|
+
return new framer.ObservableStreamer<Command<A>>(
|
|
419
|
+
await this.frameClient.openStreamer(TASK_CMD_CHANNEL),
|
|
420
|
+
(frame) => {
|
|
421
|
+
const s = frame.get(TASK_CMD_CHANNEL);
|
|
422
|
+
if (s.length === 0) return [null, false];
|
|
423
|
+
const parse = commandZ.safeParse(s.at(-1));
|
|
424
|
+
if (!parse.success) {
|
|
425
|
+
console.error(parse.error);
|
|
426
|
+
return [null, false];
|
|
427
|
+
}
|
|
428
|
+
return [parse.data as Command<A>, true];
|
|
429
|
+
},
|
|
430
|
+
);
|
|
431
|
+
}
|
|
384
432
|
}
|
|
@@ -85,17 +85,32 @@ export const commandZ = z.object({
|
|
|
85
85
|
task: taskKeyZ,
|
|
86
86
|
type: z.string(),
|
|
87
87
|
key: z.string(),
|
|
88
|
-
args: z
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
args: z
|
|
89
|
+
.record(z.unknown())
|
|
90
|
+
.or(
|
|
91
|
+
z.string().transform((c) => {
|
|
92
|
+
if (c === "") return {};
|
|
93
|
+
return JSON.parse(c);
|
|
94
|
+
}),
|
|
95
|
+
)
|
|
96
|
+
.or(z.array(z.unknown()))
|
|
97
|
+
.or(z.null())
|
|
98
|
+
.optional() as z.ZodOptional<z.ZodType<UnknownRecord>>,
|
|
94
99
|
});
|
|
95
100
|
|
|
101
|
+
export type Command<A extends {} = UnknownRecord> = Omit<
|
|
102
|
+
z.infer<typeof commandZ>,
|
|
103
|
+
"args"
|
|
104
|
+
> & {
|
|
105
|
+
args?: A;
|
|
106
|
+
};
|
|
107
|
+
|
|
96
108
|
export type StateObservable<D extends UnknownRecord = UnknownRecord> =
|
|
97
109
|
observe.ObservableAsyncCloseable<State<D>>;
|
|
98
110
|
|
|
111
|
+
export type CommandObservable<A extends UnknownRecord = UnknownRecord> =
|
|
112
|
+
observe.ObservableAsyncCloseable<Command<A>>;
|
|
113
|
+
|
|
99
114
|
export const ONTOLOGY_TYPE: ontology.ResourceType = "task";
|
|
100
115
|
|
|
101
116
|
export const ontologyID = (key: TaskKey): ontology.ID =>
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ export { rack } from "@/hardware/rack";
|
|
|
32
32
|
export { task } from "@/hardware/task";
|
|
33
33
|
export { label } from "@/label";
|
|
34
34
|
export { ontology } from "@/ontology";
|
|
35
|
+
export { group } from "@/ontology/group";
|
|
35
36
|
export { ranger } from "@/ranger";
|
|
36
37
|
export { signals } from "@/signals";
|
|
37
38
|
export { user } from "@/user";
|
|
@@ -39,6 +40,7 @@ export { workspace } from "@/workspace";
|
|
|
39
40
|
export { linePlot } from "@/workspace/lineplot";
|
|
40
41
|
export { log } from "@/workspace/log";
|
|
41
42
|
export { schematic } from "@/workspace/schematic";
|
|
43
|
+
export { table } from "@/workspace/table";
|
|
42
44
|
export {
|
|
43
45
|
type CrudeDataType,
|
|
44
46
|
type CrudeDensity,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
+
import { ontology } from "@/ontology";
|
|
12
13
|
|
|
13
14
|
export const keyZ = z.string().uuid();
|
|
14
15
|
export type Key = z.infer<typeof keyZ>;
|
|
@@ -17,10 +18,7 @@ export type Keys = Key[];
|
|
|
17
18
|
export type Names = Name[];
|
|
18
19
|
export type Params = Key | Name | Keys | Names;
|
|
19
20
|
|
|
20
|
-
export const groupZ = z.object({
|
|
21
|
-
key: keyZ,
|
|
22
|
-
name: z.string(),
|
|
23
|
-
});
|
|
21
|
+
export const groupZ = z.object({ key: keyZ, name: z.string() });
|
|
24
22
|
|
|
25
23
|
export type Payload = z.infer<typeof groupZ>;
|
|
26
24
|
|
|
@@ -52,9 +50,7 @@ export type ParamAnalysisResult =
|
|
|
52
50
|
|
|
53
51
|
export const analyzeParams = (groups: Params): ParamAnalysisResult => {
|
|
54
52
|
const normal = toArray(groups) as Keys | Names;
|
|
55
|
-
if (normal.length === 0)
|
|
56
|
-
throw new Error("No groups specified");
|
|
57
|
-
|
|
53
|
+
if (normal.length === 0) throw new Error("No groups specified");
|
|
58
54
|
const isKey = keyZ.safeParse(normal[0]).success;
|
|
59
55
|
return {
|
|
60
56
|
single: !Array.isArray(groups),
|
|
@@ -63,3 +59,8 @@ export const analyzeParams = (groups: Params): ParamAnalysisResult => {
|
|
|
63
59
|
actual: groups,
|
|
64
60
|
} as const as ParamAnalysisResult;
|
|
65
61
|
};
|
|
62
|
+
|
|
63
|
+
export const ONTOLOGY_TYPE: ontology.ResourceType = "group";
|
|
64
|
+
|
|
65
|
+
export const ontologyID = (key: Key): ontology.ID =>
|
|
66
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
package/src/ontology/payload.ts
CHANGED
package/src/ranger/client.ts
CHANGED
|
@@ -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 { type CrudeTimeRange, observe, TimeRange } from "@synnaxlabs/x";
|
|
11
|
+
import { type CrudeTimeRange, observe, sortTimeRange, TimeRange } from "@synnaxlabs/x";
|
|
12
12
|
import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
13
13
|
import { type Series } from "@synnaxlabs/x/telem";
|
|
14
14
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
@@ -192,6 +192,9 @@ export class Range {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
export const sort = (a: Range, b: Range): -1 | 0 | 1 =>
|
|
196
|
+
sortTimeRange(a.timeRange, b.timeRange);
|
|
197
|
+
|
|
195
198
|
const retrieveReqZ = z.object({
|
|
196
199
|
keys: keyZ.array().optional(),
|
|
197
200
|
names: z.array(z.string()).optional(),
|
package/src/transport.ts
CHANGED
|
@@ -12,8 +12,10 @@ import {
|
|
|
12
12
|
type Middleware,
|
|
13
13
|
type StreamClient,
|
|
14
14
|
type UnaryClient,
|
|
15
|
+
unaryWithBreaker,
|
|
15
16
|
WebSocketClient,
|
|
16
17
|
} from "@synnaxlabs/freighter";
|
|
18
|
+
import { breaker } from "@synnaxlabs/x";
|
|
17
19
|
import { binary } from "@synnaxlabs/x/binary";
|
|
18
20
|
import { type URL } from "@synnaxlabs/x/url";
|
|
19
21
|
|
|
@@ -25,12 +27,15 @@ export class Transport {
|
|
|
25
27
|
readonly stream: StreamClient;
|
|
26
28
|
readonly secure: boolean;
|
|
27
29
|
|
|
28
|
-
constructor(url: URL, secure: boolean = false) {
|
|
30
|
+
constructor(url: URL, breakerCfg: breaker.Config = {}, secure: boolean = false) {
|
|
29
31
|
this.secure = secure;
|
|
30
32
|
this.url = url.child(baseAPIEndpoint);
|
|
31
33
|
const codec = new binary.JSONCodec();
|
|
32
|
-
this.unary =
|
|
33
|
-
|
|
34
|
+
(this.unary = unaryWithBreaker(
|
|
35
|
+
new HTTPClient(this.url, codec, this.secure),
|
|
36
|
+
breakerCfg,
|
|
37
|
+
)),
|
|
38
|
+
(this.stream = new WebSocketClient(this.url, codec, this.secure));
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
use(...middleware: Middleware[]): void {
|
package/src/workspace/client.ts
CHANGED
|
@@ -1,80 +1,184 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { type UnknownRecord } from "@synnaxlabs/x/record";
|
|
12
|
-
import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
13
|
-
|
|
1
|
+
import { ontology } from "@/ontology";
|
|
2
|
+
import { sendRequired, UnaryClient } from "@synnaxlabs/freighter";
|
|
3
|
+
import { toArray, UnknownRecord } from "@synnaxlabs/x";
|
|
4
|
+
import { unknownRecordZ } from "@synnaxlabs/x/record";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
14
7
|
import { linePlot } from "@/workspace/lineplot";
|
|
15
8
|
import { log } from "@/workspace/log";
|
|
16
|
-
import { type Key, type Workspace } from "@/workspace/payload";
|
|
17
|
-
import { Retriever } from "@/workspace/retriever";
|
|
18
9
|
import { schematic } from "@/workspace/schematic";
|
|
19
|
-
import {
|
|
10
|
+
import { table } from "@/workspace/table";
|
|
11
|
+
import { nullableArrayZ } from "@/util/zod";
|
|
12
|
+
|
|
13
|
+
export const keyZ = z.string().uuid();
|
|
14
|
+
export type Key = z.infer<typeof keyZ>;
|
|
15
|
+
export type Params = Key | Key[];
|
|
16
|
+
|
|
17
|
+
// --- VERY IMPORTANT ---
|
|
18
|
+
// Synnax's encoders (in the binary package inside x) automatically convert the case
|
|
19
|
+
// of keys in objects to snake_case and back to camelCase when encoding and decoding
|
|
20
|
+
// respectively. This is done to ensure that the keys are consistent across all
|
|
21
|
+
// languages and platforms. Sometimes workspaces have keys that are uuids, which have
|
|
22
|
+
// dashes, and those get messed up. So we just use regular JSON for workspaces.
|
|
23
|
+
const parse = (s: string): UnknownRecord => JSON.parse(s) as UnknownRecord;
|
|
24
|
+
|
|
25
|
+
export const workspaceZ = z.object({
|
|
26
|
+
key: z.string(),
|
|
27
|
+
name: z.string(),
|
|
28
|
+
layout: unknownRecordZ.or(z.string().transform((s) => parse(s) as UnknownRecord)),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type Workspace = z.infer<typeof workspaceZ>;
|
|
32
|
+
|
|
33
|
+
export const ONTOLOGY_TYPE: ontology.ResourceType = "workspace";
|
|
34
|
+
|
|
35
|
+
export const ontologyID = (key: Key): ontology.ID =>
|
|
36
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
37
|
+
|
|
38
|
+
const RETRIEVE_ENDPOINT = "/workspace/retrieve";
|
|
39
|
+
const CREATE_ENDPOINT = "/workspace/create";
|
|
40
|
+
const RENAME_ENDPOINT = "/workspace/rename";
|
|
41
|
+
const SET_LAYOUT_ENDPOINT = "/workspace/set-layout";
|
|
42
|
+
const DELETE_ENDPOINT = "/workspace/delete";
|
|
43
|
+
|
|
44
|
+
export const newWorkspaceZ = workspaceZ.partial({ key: true }).transform((p) => ({
|
|
45
|
+
...p,
|
|
46
|
+
layout: JSON.stringify(p.layout),
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
export const workspaceRemoteZ = workspaceZ.omit({ layout: true }).extend({
|
|
50
|
+
layout: z.string().transform((s) => parse(s) as UnknownRecord),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export type NewWorkspace = z.input<typeof newWorkspaceZ>;
|
|
54
|
+
|
|
55
|
+
const retrieveReqZ = z.object({
|
|
56
|
+
keys: z.string().array().optional(),
|
|
57
|
+
search: z.string().optional(),
|
|
58
|
+
author: z.string().uuid().optional(),
|
|
59
|
+
offset: z.number().optional(),
|
|
60
|
+
limit: z.number().optional(),
|
|
61
|
+
});
|
|
62
|
+
const createReqZ = z.object({ workspaces: newWorkspaceZ.array() });
|
|
63
|
+
const renameReqZ = z.object({ key: z.string(), name: z.string() });
|
|
64
|
+
const setLayoutReqZ = z.object({ key: z.string(), layout: z.string() });
|
|
65
|
+
const deleteReqZ = z.object({ keys: z.string().array() });
|
|
66
|
+
|
|
67
|
+
const retrieveResZ = z.object({ workspaces: nullableArrayZ(workspaceZ) });
|
|
68
|
+
const createResZ = z.object({ workspaces: workspaceRemoteZ.array() });
|
|
69
|
+
const emptyResZ = z.object({});
|
|
20
70
|
|
|
21
71
|
export class Client implements AsyncTermSearcher<string, Key, Workspace> {
|
|
22
72
|
readonly type = "workspace";
|
|
23
73
|
readonly schematic: schematic.Client;
|
|
24
74
|
readonly linePlot: linePlot.Client;
|
|
25
75
|
readonly log: log.Client;
|
|
26
|
-
|
|
27
|
-
private readonly
|
|
76
|
+
readonly table: table.Client;
|
|
77
|
+
private readonly client: UnaryClient;
|
|
28
78
|
|
|
29
79
|
constructor(client: UnaryClient) {
|
|
80
|
+
this.client = client;
|
|
30
81
|
this.schematic = new schematic.Client(client);
|
|
31
82
|
this.linePlot = new linePlot.Client(client);
|
|
32
|
-
this.retriever = new Retriever(client);
|
|
33
83
|
this.log = new log.Client(client);
|
|
34
|
-
this.
|
|
84
|
+
this.table = new table.Client(client);
|
|
35
85
|
}
|
|
36
86
|
|
|
37
|
-
async
|
|
38
|
-
|
|
87
|
+
async create(workspace: NewWorkspace): Promise<Workspace>;
|
|
88
|
+
async create(workspaces: NewWorkspace[]): Promise<Workspace[]>;
|
|
89
|
+
async create(
|
|
90
|
+
workspaces: NewWorkspace | NewWorkspace[],
|
|
91
|
+
): Promise<Workspace | Workspace[]> {
|
|
92
|
+
const isMany = Array.isArray(workspaces);
|
|
93
|
+
const normalized = toArray(workspaces);
|
|
94
|
+
const res = await sendRequired(
|
|
95
|
+
this.client,
|
|
96
|
+
CREATE_ENDPOINT,
|
|
97
|
+
{ workspaces: normalized },
|
|
98
|
+
createReqZ,
|
|
99
|
+
createResZ,
|
|
100
|
+
);
|
|
101
|
+
return isMany ? res.workspaces : res.workspaces[0];
|
|
39
102
|
}
|
|
40
103
|
|
|
41
|
-
async
|
|
42
|
-
|
|
104
|
+
async rename(key: Key, name: string): Promise<void> {
|
|
105
|
+
await sendRequired(
|
|
106
|
+
this.client,
|
|
107
|
+
RENAME_ENDPOINT,
|
|
108
|
+
{ key, name },
|
|
109
|
+
renameReqZ,
|
|
110
|
+
emptyResZ,
|
|
111
|
+
);
|
|
43
112
|
}
|
|
44
113
|
|
|
45
|
-
async
|
|
114
|
+
async setLayout(key: Key, layout: UnknownRecord): Promise<void> {
|
|
115
|
+
await sendRequired(
|
|
116
|
+
this.client,
|
|
117
|
+
SET_LAYOUT_ENDPOINT,
|
|
118
|
+
{ key, layout: JSON.stringify(layout) },
|
|
119
|
+
setLayoutReqZ,
|
|
120
|
+
emptyResZ,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
46
123
|
|
|
124
|
+
async retrieve(key: Key): Promise<Workspace>;
|
|
47
125
|
async retrieve(keys: Key[]): Promise<Workspace[]>;
|
|
48
|
-
|
|
49
|
-
async retrieve(keys: Key | Key[]): Promise<Workspace | Workspace[]> {
|
|
126
|
+
async retrieve(keys: Params): Promise<Workspace | Workspace[]> {
|
|
50
127
|
const isMany = Array.isArray(keys);
|
|
51
|
-
const
|
|
52
|
-
|
|
128
|
+
const normalized = toArray(keys);
|
|
129
|
+
const res = await sendRequired(
|
|
130
|
+
this.client,
|
|
131
|
+
RETRIEVE_ENDPOINT,
|
|
132
|
+
{ keys: normalized },
|
|
133
|
+
retrieveReqZ,
|
|
134
|
+
retrieveResZ,
|
|
135
|
+
);
|
|
136
|
+
return isMany ? res.workspaces : res.workspaces[0];
|
|
53
137
|
}
|
|
54
138
|
|
|
55
|
-
async
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const isMany = Array.isArray(workspaces);
|
|
65
|
-
const res = await this.writer.create(workspaces);
|
|
66
|
-
return isMany ? res : res[0];
|
|
139
|
+
async retrieveByAuthor(author: string): Promise<Workspace[]> {
|
|
140
|
+
const res = await sendRequired(
|
|
141
|
+
this.client,
|
|
142
|
+
RETRIEVE_ENDPOINT,
|
|
143
|
+
{ author },
|
|
144
|
+
retrieveReqZ,
|
|
145
|
+
retrieveResZ,
|
|
146
|
+
);
|
|
147
|
+
return res.workspaces;
|
|
67
148
|
}
|
|
68
149
|
|
|
69
|
-
async
|
|
70
|
-
await
|
|
150
|
+
async search(term: string): Promise<Workspace[]> {
|
|
151
|
+
const res = await sendRequired(
|
|
152
|
+
this.client,
|
|
153
|
+
RETRIEVE_ENDPOINT,
|
|
154
|
+
{ search: term },
|
|
155
|
+
retrieveReqZ,
|
|
156
|
+
retrieveResZ,
|
|
157
|
+
);
|
|
158
|
+
return res.workspaces;
|
|
71
159
|
}
|
|
72
160
|
|
|
73
|
-
async
|
|
74
|
-
await
|
|
161
|
+
async page(offset: number, limit: number): Promise<Workspace[]> {
|
|
162
|
+
const res = await sendRequired(
|
|
163
|
+
this.client,
|
|
164
|
+
RETRIEVE_ENDPOINT,
|
|
165
|
+
{ offset, limit },
|
|
166
|
+
retrieveReqZ,
|
|
167
|
+
retrieveResZ,
|
|
168
|
+
);
|
|
169
|
+
return res.workspaces;
|
|
75
170
|
}
|
|
76
171
|
|
|
77
|
-
async delete(
|
|
78
|
-
|
|
172
|
+
async delete(key: Key): Promise<void>;
|
|
173
|
+
async delete(keys: Key[]): Promise<void>;
|
|
174
|
+
async delete(keys: Params): Promise<void> {
|
|
175
|
+
const normalized = toArray(keys);
|
|
176
|
+
await sendRequired(
|
|
177
|
+
this.client,
|
|
178
|
+
DELETE_ENDPOINT,
|
|
179
|
+
{ keys: normalized },
|
|
180
|
+
deleteReqZ,
|
|
181
|
+
emptyResZ,
|
|
182
|
+
);
|
|
79
183
|
}
|
|
80
184
|
}
|
package/src/workspace/index.ts
CHANGED
|
@@ -1,51 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { ontology } from "@/ontology";
|
|
2
|
+
import { nullableArrayZ } from "@/util/zod";
|
|
3
|
+
import { sendRequired, UnaryClient } from "@synnaxlabs/freighter";
|
|
4
|
+
import { breaker, TimeSpan, toArray, UnknownRecord } from "@synnaxlabs/x";
|
|
5
|
+
import { unknownRecordZ } from "@synnaxlabs/x/record";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
export const keyZ = z.string().uuid();
|
|
9
|
+
export type Key = z.infer<typeof keyZ>;
|
|
10
|
+
export type Params = Key | Key[];
|
|
11
|
+
|
|
12
|
+
export const linePlotZ = z.object({
|
|
13
|
+
key: z.string(),
|
|
14
|
+
name: z.string(),
|
|
15
|
+
data: unknownRecordZ.or(z.string().transform((s) => JSON.parse(s) as UnknownRecord)),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export type LinePlot = z.infer<typeof linePlotZ>;
|
|
19
|
+
|
|
20
|
+
export const ONTOLOGY_TYPE: ontology.ResourceType = "lineplot";
|
|
21
|
+
|
|
22
|
+
export const ontologyID = (key: Key): ontology.ID =>
|
|
23
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
24
|
+
|
|
25
|
+
const RETRIEVE_ENDPOINT = "/workspace/lineplot/retrieve";
|
|
26
|
+
const CREATE_ENDPOINT = "/workspace/lineplot/create";
|
|
27
|
+
const RENAME_ENDPOINT = "/workspace/lineplot/rename";
|
|
28
|
+
const SET_DATA_ENDPOINT = "/workspace/lineplot/set-data";
|
|
29
|
+
const DELETE_ENDPOINT = "/workspace/lineplot/delete";
|
|
30
|
+
|
|
31
|
+
export const newLinePlotZ = linePlotZ.partial({ key: true }).transform((p) => ({
|
|
32
|
+
...p,
|
|
33
|
+
data: JSON.stringify(p.data),
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
export type NewLinePlot = z.input<typeof newLinePlotZ>;
|
|
37
|
+
|
|
38
|
+
const retrieveReqZ = z.object({ keys: keyZ.array() });
|
|
39
|
+
const createReqZ = z.object({ workspace: z.string(), linePlots: newLinePlotZ.array() });
|
|
40
|
+
const renameReqZ = z.object({ key: keyZ, name: z.string() });
|
|
41
|
+
const setDataReqZ = z.object({ key: keyZ, data: z.string() });
|
|
42
|
+
const deleteReqZ = z.object({ keys: keyZ.array() });
|
|
43
|
+
const retrieveResZ = z.object({ linePlots: nullableArrayZ(linePlotZ) });
|
|
44
|
+
const createResZ = z.object({ linePlots: linePlotZ.array() });
|
|
45
|
+
const emptyResZ = z.object({});
|
|
16
46
|
|
|
17
47
|
export class Client {
|
|
18
|
-
private readonly
|
|
19
|
-
private readonly retriever: Retriever;
|
|
48
|
+
private readonly client: UnaryClient;
|
|
20
49
|
|
|
21
50
|
constructor(client: UnaryClient) {
|
|
22
|
-
this.
|
|
23
|
-
this.retriever = new Retriever(client);
|
|
51
|
+
this.client = client;
|
|
24
52
|
}
|
|
25
53
|
|
|
26
|
-
async create(workspace: string, linePlot: NewLinePlot): Promise<LinePlot
|
|
27
|
-
|
|
54
|
+
async create(workspace: string, linePlot: NewLinePlot): Promise<LinePlot>;
|
|
55
|
+
async create(workspace: string, linePlots: NewLinePlot[]): Promise<LinePlot[]>;
|
|
56
|
+
async create(
|
|
57
|
+
workspace: string,
|
|
58
|
+
linePlots: NewLinePlot | NewLinePlot[],
|
|
59
|
+
): Promise<LinePlot | LinePlot[]> {
|
|
60
|
+
const isMany = Array.isArray(linePlots);
|
|
61
|
+
const normalized = toArray(linePlots);
|
|
62
|
+
const res = await sendRequired(
|
|
63
|
+
this.client,
|
|
64
|
+
CREATE_ENDPOINT,
|
|
65
|
+
{ workspace, linePlots: normalized },
|
|
66
|
+
createReqZ,
|
|
67
|
+
createResZ,
|
|
68
|
+
);
|
|
69
|
+
return isMany ? res.linePlots : res.linePlots[0];
|
|
28
70
|
}
|
|
29
71
|
|
|
30
72
|
async rename(key: Key, name: string): Promise<void> {
|
|
31
|
-
await
|
|
73
|
+
await sendRequired(
|
|
74
|
+
this.client,
|
|
75
|
+
RENAME_ENDPOINT,
|
|
76
|
+
{ key, name },
|
|
77
|
+
renameReqZ,
|
|
78
|
+
emptyResZ,
|
|
79
|
+
);
|
|
32
80
|
}
|
|
33
81
|
|
|
34
82
|
async setData(key: Key, data: UnknownRecord): Promise<void> {
|
|
35
|
-
await
|
|
83
|
+
await sendRequired(
|
|
84
|
+
this.client,
|
|
85
|
+
SET_DATA_ENDPOINT,
|
|
86
|
+
{ key, data: JSON.stringify(data) },
|
|
87
|
+
setDataReqZ,
|
|
88
|
+
emptyResZ,
|
|
89
|
+
);
|
|
36
90
|
}
|
|
37
91
|
|
|
38
92
|
async retrieve(key: Key): Promise<LinePlot>;
|
|
39
|
-
|
|
40
93
|
async retrieve(keys: Key[]): Promise<LinePlot[]>;
|
|
41
|
-
|
|
42
94
|
async retrieve(keys: Params): Promise<LinePlot | LinePlot[]> {
|
|
43
95
|
const isMany = Array.isArray(keys);
|
|
44
|
-
const
|
|
45
|
-
|
|
96
|
+
const normalized = toArray(keys);
|
|
97
|
+
const res = await sendRequired(
|
|
98
|
+
this.client,
|
|
99
|
+
RETRIEVE_ENDPOINT,
|
|
100
|
+
{ keys: normalized },
|
|
101
|
+
retrieveReqZ,
|
|
102
|
+
retrieveResZ,
|
|
103
|
+
);
|
|
104
|
+
return isMany ? res.linePlots : res.linePlots[0];
|
|
46
105
|
}
|
|
47
106
|
|
|
107
|
+
async delete(key: Key): Promise<void>;
|
|
108
|
+
async delete(keys: Key[]): Promise<void>;
|
|
48
109
|
async delete(keys: Params): Promise<void> {
|
|
49
|
-
|
|
110
|
+
const normalized = toArray(keys);
|
|
111
|
+
await sendRequired(
|
|
112
|
+
this.client,
|
|
113
|
+
DELETE_ENDPOINT,
|
|
114
|
+
{ keys: normalized },
|
|
115
|
+
deleteReqZ,
|
|
116
|
+
emptyResZ,
|
|
117
|
+
);
|
|
50
118
|
}
|
|
51
119
|
}
|