@synnaxlabs/client 0.33.0 → 0.35.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/auth/auth.d.ts.map +1 -1
- package/dist/channel/writer.d.ts.map +1 -1
- package/dist/client.cjs +29 -29
- package/dist/client.js +1880 -1686
- package/dist/control/client.d.ts.map +1 -1
- package/dist/control/state.d.ts.map +1 -1
- package/dist/errors.d.ts +3 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/framer/adapter.d.ts.map +1 -1
- package/dist/framer/client.d.ts.map +1 -1
- package/dist/framer/deleter.d.ts.map +1 -1
- package/dist/framer/frame.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/hardware/rack/client.d.ts.map +1 -1
- package/dist/hardware/task/client.d.ts +5 -3
- package/dist/hardware/task/client.d.ts.map +1 -1
- package/dist/hardware/task/ni/types.d.ts.map +1 -1
- package/dist/hardware/task/payload.d.ts +7 -3
- package/dist/hardware/task/payload.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/label/client.d.ts.map +1 -1
- package/dist/label/writer.d.ts +5 -5
- package/dist/ontology/client.d.ts +8 -8
- package/dist/ontology/client.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/alias.d.ts.map +1 -1
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/kv.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts +5 -5
- package/dist/util/telem.d.ts.map +1 -1
- package/dist/workspace/client.d.ts +2 -0
- package/dist/workspace/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/payload.d.ts.map +1 -1
- package/dist/workspace/log/payload.d.ts.map +1 -1
- package/dist/workspace/payload.d.ts.map +1 -1
- package/dist/workspace/schematic/payload.d.ts.map +1 -1
- package/dist/workspace/table/client.d.ts +16 -0
- package/dist/workspace/table/client.d.ts.map +1 -0
- package/dist/workspace/table/external.d.ts +3 -0
- package/dist/workspace/table/external.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/payload.d.ts +36 -0
- package/dist/workspace/table/payload.d.ts.map +1 -0
- package/dist/workspace/table/retriever.d.ts +8 -0
- package/dist/workspace/table/retriever.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/dist/workspace/table/writer.d.ts +35 -0
- package/dist/workspace/table/writer.d.ts.map +1 -0
- package/eslint.config.js +1 -1
- package/package.json +12 -12
- package/src/access/policy/policy.spec.ts +2 -4
- package/src/auth/auth.spec.ts +1 -1
- package/src/auth/auth.ts +17 -18
- package/src/channel/writer.ts +2 -2
- package/src/connection/checker.ts +1 -1
- package/src/control/client.ts +1 -1
- package/src/control/state.ts +1 -1
- package/src/errors.spec.ts +1 -1
- package/src/errors.ts +14 -15
- package/src/framer/adapter.ts +5 -6
- package/src/framer/client.ts +9 -4
- package/src/framer/deleter.ts +1 -1
- package/src/framer/frame.ts +9 -11
- package/src/framer/iterator.spec.ts +2 -3
- package/src/framer/writer.ts +1 -1
- package/src/hardware/device/client.ts +13 -7
- package/src/hardware/device/payload.ts +1 -1
- package/src/hardware/rack/client.ts +3 -3
- package/src/hardware/task/client.ts +64 -14
- package/src/hardware/task/ni/types.ts +1 -1
- package/src/hardware/task/payload.ts +22 -7
- package/src/hardware/task/task.spec.ts +1 -1
- package/src/index.ts +1 -0
- package/src/label/client.ts +1 -1
- package/src/ontology/client.ts +1 -3
- package/src/ontology/group/payload.ts +2 -2
- package/src/ontology/payload.ts +2 -1
- package/src/ranger/alias.ts +2 -3
- package/src/ranger/client.ts +7 -9
- package/src/ranger/kv.ts +2 -2
- package/src/ranger/payload.ts +2 -2
- package/src/ranger/ranger.spec.ts +2 -2
- package/src/user/user.spec.ts +1 -2
- package/src/util/telem.ts +1 -3
- package/src/workspace/client.ts +3 -0
- package/src/workspace/lineplot/payload.ts +1 -1
- package/src/workspace/log/payload.ts +1 -1
- package/src/workspace/payload.ts +1 -1
- package/src/workspace/schematic/payload.ts +1 -1
- package/src/workspace/table/client.ts +51 -0
- package/src/workspace/table/external.ts +11 -0
- package/src/workspace/table/index.ts +10 -0
- package/src/workspace/table/payload.ts +36 -0
- package/src/workspace/table/retriever.ts +33 -0
- package/src/workspace/table/table.spec.ts +65 -0
- package/src/workspace/table/writer.ts +102 -0
|
@@ -19,18 +19,21 @@ import { framer } from "@/framer";
|
|
|
19
19
|
import { type Frame } from "@/framer/frame";
|
|
20
20
|
import { rack } from "@/hardware/rack";
|
|
21
21
|
import {
|
|
22
|
-
|
|
22
|
+
type Command,
|
|
23
|
+
type CommandObservable,
|
|
24
|
+
commandZ,
|
|
25
|
+
type NewTask,
|
|
23
26
|
newTaskZ,
|
|
24
|
-
Payload,
|
|
25
|
-
State,
|
|
26
|
-
StateObservable,
|
|
27
|
+
type Payload,
|
|
28
|
+
type State,
|
|
29
|
+
type StateObservable,
|
|
27
30
|
stateZ,
|
|
28
|
-
TaskKey,
|
|
31
|
+
type TaskKey,
|
|
29
32
|
taskKeyZ,
|
|
30
33
|
taskZ,
|
|
31
34
|
} from "@/hardware/task/payload";
|
|
32
35
|
import { ontology } from "@/ontology";
|
|
33
|
-
import { ranger } from "@/ranger";
|
|
36
|
+
import { type ranger } from "@/ranger";
|
|
34
37
|
import { signals } from "@/signals";
|
|
35
38
|
import { analyzeParams, checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
36
39
|
import { nullableArrayZ } from "@/util/zod";
|
|
@@ -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;
|
|
@@ -123,9 +126,7 @@ export class Task<
|
|
|
123
126
|
if (parsed.success) {
|
|
124
127
|
res = parsed.data as State<D>;
|
|
125
128
|
if (res.key === cmdKey) break;
|
|
126
|
-
} else
|
|
127
|
-
console.error(parsed.error);
|
|
128
|
-
}
|
|
129
|
+
} else console.error(parsed.error);
|
|
129
130
|
}
|
|
130
131
|
streamer.close();
|
|
131
132
|
return res;
|
|
@@ -141,7 +142,10 @@ export class Task<
|
|
|
141
142
|
const s = frame.get(TASK_STATE_CHANNEL);
|
|
142
143
|
if (s.length === 0) return [null, false];
|
|
143
144
|
const parse = stateZ.safeParse(s.at(-1));
|
|
144
|
-
if (!parse.success)
|
|
145
|
+
if (!parse.success) {
|
|
146
|
+
console.error(parse.error);
|
|
147
|
+
return [null, false];
|
|
148
|
+
}
|
|
145
149
|
const state = parse.data as State<D>;
|
|
146
150
|
if (state.task !== this.key) return [null, false];
|
|
147
151
|
return [state, true];
|
|
@@ -149,6 +153,27 @@ export class Task<
|
|
|
149
153
|
);
|
|
150
154
|
}
|
|
151
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
|
+
|
|
152
177
|
async snapshottedTo(): Promise<ontology.Resource | null> {
|
|
153
178
|
if (this.ontologyClient == null || this.rangeClient == null) throw TASK_NOT_CREATED;
|
|
154
179
|
if (!this.snapshot) return null;
|
|
@@ -316,10 +341,14 @@ export class Client implements AsyncTermSearcher<string, TaskKey, Payload> {
|
|
|
316
341
|
return this.sugar([res.task])[0];
|
|
317
342
|
}
|
|
318
343
|
|
|
319
|
-
async retrieveByName
|
|
344
|
+
async retrieveByName<
|
|
345
|
+
C extends UnknownRecord = UnknownRecord,
|
|
346
|
+
D extends {} = UnknownRecord,
|
|
347
|
+
T extends string = string,
|
|
348
|
+
>(name: string, rack?: number): Promise<Task<C, D, T>> {
|
|
320
349
|
const tasks = await this.execRetrieve({ names: [name], rack });
|
|
321
350
|
checkForMultipleOrNoResults("Task", name, tasks, true);
|
|
322
|
-
return this.sugar(tasks)[0]
|
|
351
|
+
return this.sugar(tasks)[0] as Task<C, D, T>;
|
|
323
352
|
}
|
|
324
353
|
|
|
325
354
|
private async execRetrieve(req: RetrieveRequest): Promise<Payload[]> {
|
|
@@ -374,9 +403,30 @@ export class Client implements AsyncTermSearcher<string, TaskKey, Payload> {
|
|
|
374
403
|
const s = frame.get(TASK_STATE_CHANNEL);
|
|
375
404
|
if (s.length === 0) return [null, false];
|
|
376
405
|
const parse = stateZ.safeParse(s.at(-1));
|
|
377
|
-
if (!parse.success)
|
|
406
|
+
if (!parse.success) {
|
|
407
|
+
console.error(parse.error);
|
|
408
|
+
return [null, false];
|
|
409
|
+
}
|
|
378
410
|
return [parse.data as State<D>, true];
|
|
379
411
|
},
|
|
380
412
|
);
|
|
381
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
|
+
}
|
|
382
432
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
12
|
import { device } from "@/hardware/device";
|
|
13
|
-
import { task } from "@/hardware/task";
|
|
13
|
+
import { type task } from "@/hardware/task";
|
|
14
14
|
|
|
15
15
|
export const unitsVoltsZ = z.literal("Volts");
|
|
16
16
|
export type UnitsVolts = z.infer<typeof unitsVoltsZ>;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { binary, observe, UnknownRecord } from "@synnaxlabs/x";
|
|
10
|
+
import { binary, type observe, type UnknownRecord } from "@synnaxlabs/x";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
import { ontology } from "@/ontology";
|
|
@@ -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 =>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { id } from "@synnaxlabs/x";
|
|
11
11
|
import { describe, expect, it } from "vitest";
|
|
12
12
|
|
|
13
|
-
import { task } from "@/hardware/task";
|
|
13
|
+
import { type task } from "@/hardware/task";
|
|
14
14
|
import { newClient } from "@/setupspecs";
|
|
15
15
|
|
|
16
16
|
const client = newClient();
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export { workspace } from "@/workspace";
|
|
|
39
39
|
export { linePlot } from "@/workspace/lineplot";
|
|
40
40
|
export { log } from "@/workspace/log";
|
|
41
41
|
export { schematic } from "@/workspace/schematic";
|
|
42
|
+
export { table } from "@/workspace/table";
|
|
42
43
|
export {
|
|
43
44
|
type CrudeDataType,
|
|
44
45
|
type CrudeDensity,
|
package/src/label/client.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
|
14
14
|
import { type framer } from "@/framer";
|
|
15
15
|
import { type Key, type Label, labelZ } from "@/label/payload";
|
|
16
16
|
import { Retriever } from "@/label/retriever";
|
|
17
|
-
import { type NewLabelPayload, SetOptions, Writer } from "@/label/writer";
|
|
17
|
+
import { type NewLabelPayload, type SetOptions, Writer } from "@/label/writer";
|
|
18
18
|
import { ontology } from "@/ontology";
|
|
19
19
|
import { signals } from "@/signals";
|
|
20
20
|
|
package/src/ontology/client.ts
CHANGED
|
@@ -290,9 +290,7 @@ export class ChangeTracker {
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
private async start(): Promise<void> {
|
|
293
|
-
for await (const frame of this.streamer)
|
|
294
|
-
await this.update(frame);
|
|
295
|
-
}
|
|
293
|
+
for await (const frame of this.streamer) await this.update(frame);
|
|
296
294
|
}
|
|
297
295
|
|
|
298
296
|
private async update(frame: framer.Frame): Promise<void> {
|
|
@@ -52,9 +52,9 @@ export type ParamAnalysisResult =
|
|
|
52
52
|
|
|
53
53
|
export const analyzeParams = (groups: Params): ParamAnalysisResult => {
|
|
54
54
|
const normal = toArray(groups) as Keys | Names;
|
|
55
|
-
if (normal.length === 0)
|
|
55
|
+
if (normal.length === 0)
|
|
56
56
|
throw new Error("No groups specified");
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
const isKey = keyZ.safeParse(normal[0]).success;
|
|
59
59
|
return {
|
|
60
60
|
single: !Array.isArray(groups),
|
package/src/ontology/payload.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { change, UnknownRecord } from "@synnaxlabs/x";
|
|
10
|
+
import { type change, type UnknownRecord } from "@synnaxlabs/x";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
export type ResourceChange = change.Change<ID, Resource>;
|
|
@@ -37,6 +37,7 @@ export const resourceTypeZ = z.union([
|
|
|
37
37
|
z.literal("device"),
|
|
38
38
|
z.literal("task"),
|
|
39
39
|
z.literal("policy"),
|
|
40
|
+
z.literal("table"),
|
|
40
41
|
]);
|
|
41
42
|
export type ResourceType = z.infer<typeof resourceTypeZ>;
|
|
42
43
|
|
package/src/ranger/alias.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { type change } from "@synnaxlabs/x/change";
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
14
|
import { type channel } from "@/channel";
|
|
15
|
-
import { type Key as ChannelKey,keyZ as channelKeyZ } from "@/channel/payload";
|
|
15
|
+
import { type Key as ChannelKey, keyZ as channelKeyZ } from "@/channel/payload";
|
|
16
16
|
import { type Client as FrameClient } from "@/framer/client";
|
|
17
17
|
import { type Key, keyZ } from "@/ranger/payload";
|
|
18
18
|
import { signals } from "@/signals";
|
|
@@ -161,7 +161,7 @@ const aliasSeparator = "---";
|
|
|
161
161
|
const decodeAliasChanges =
|
|
162
162
|
(rangeKey: Key): signals.Decoder<string, Alias> =>
|
|
163
163
|
(variant, data) => {
|
|
164
|
-
if (variant === "delete")
|
|
164
|
+
if (variant === "delete")
|
|
165
165
|
return data
|
|
166
166
|
.toStrings()
|
|
167
167
|
.filter((k) => k.split(aliasSeparator)[0] === rangeKey)
|
|
@@ -170,7 +170,6 @@ const decodeAliasChanges =
|
|
|
170
170
|
key: alias,
|
|
171
171
|
value: undefined,
|
|
172
172
|
}));
|
|
173
|
-
}
|
|
174
173
|
return data.parseJSON(aliasZ).map((alias) => ({
|
|
175
174
|
variant,
|
|
176
175
|
key: alias.alias,
|
package/src/ranger/client.ts
CHANGED
|
@@ -8,21 +8,20 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { CrudeTimeRange, observe, TimeRange } from "@synnaxlabs/x";
|
|
11
|
+
import { type CrudeTimeRange, observe, 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";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
|
-
import { Key as ChannelKey } from "@/channel/payload";
|
|
17
|
+
import { type Key as ChannelKey } from "@/channel/payload";
|
|
18
18
|
import { type Retriever as ChannelRetriever } from "@/channel/retriever";
|
|
19
|
-
import { MultipleFoundError, NotFoundError } from "@/errors";
|
|
20
|
-
import { QueryError } from "@/errors";
|
|
19
|
+
import { MultipleFoundError, NotFoundError, QueryError } from "@/errors";
|
|
21
20
|
import { type framer } from "@/framer";
|
|
22
21
|
import { type label } from "@/label";
|
|
23
22
|
import { type Label } from "@/label/payload";
|
|
24
23
|
import { ontology } from "@/ontology";
|
|
25
|
-
import { Resource } from "@/ontology/payload";
|
|
24
|
+
import { type Resource } from "@/ontology/payload";
|
|
26
25
|
import { type Alias, Aliaser } from "@/ranger/alias";
|
|
27
26
|
import { KV } from "@/ranger/kv";
|
|
28
27
|
import {
|
|
@@ -37,7 +36,7 @@ import {
|
|
|
37
36
|
type Payload,
|
|
38
37
|
payloadZ,
|
|
39
38
|
} from "@/ranger/payload";
|
|
40
|
-
import { CreateOptions, type Writer } from "@/ranger/writer";
|
|
39
|
+
import { type CreateOptions, type Writer } from "@/ranger/writer";
|
|
41
40
|
import { signals } from "@/signals";
|
|
42
41
|
import { nullableArrayZ } from "@/util/zod";
|
|
43
42
|
|
|
@@ -98,9 +97,8 @@ export class Range {
|
|
|
98
97
|
|
|
99
98
|
async setAlias(channel: ChannelKey | Name, alias: string): Promise<void> {
|
|
100
99
|
const ch = await this.channels.retrieve(channel);
|
|
101
|
-
if (ch.length === 0) {
|
|
102
|
-
|
|
103
|
-
}
|
|
100
|
+
if (ch.length === 0) throw new QueryError(`Channel ${channel} does not exist`);
|
|
101
|
+
|
|
104
102
|
await this.aliaser.set({ [ch[0].key]: alias });
|
|
105
103
|
}
|
|
106
104
|
|
package/src/ranger/kv.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { isObject } from "@synnaxlabs/x/identity";
|
|
|
12
12
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
|
-
import { framer } from "@/framer";
|
|
15
|
+
import { type framer } from "@/framer";
|
|
16
16
|
import { type Key, keyZ } from "@/ranger/payload";
|
|
17
17
|
import { signals } from "@/signals";
|
|
18
18
|
import { nullableArrayZ } from "@/util/zod";
|
|
@@ -96,7 +96,7 @@ export class KV {
|
|
|
96
96
|
key: k,
|
|
97
97
|
value: v,
|
|
98
98
|
}));
|
|
99
|
-
else pairs = [{ range: this.rangeKey, key
|
|
99
|
+
else pairs = [{ range: this.rangeKey, key, value }];
|
|
100
100
|
await sendRequired(
|
|
101
101
|
this.client,
|
|
102
102
|
KV.SET_ENDPOINT,
|
package/src/ranger/payload.ts
CHANGED
|
@@ -79,7 +79,7 @@ export const ONTOLOGY_TYPE: ontology.ResourceType = "range";
|
|
|
79
79
|
export const ALIAS_ONTOLOGY_TYPE: ontology.ResourceType = "range-alias";
|
|
80
80
|
|
|
81
81
|
export const rangeOntologyID = (key: Key): ontology.ID =>
|
|
82
|
-
new ontology.ID({ type: ONTOLOGY_TYPE, key
|
|
82
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
83
83
|
|
|
84
84
|
export const rangeAliasOntologyID = (key: Key): ontology.ID =>
|
|
85
|
-
new ontology.ID({ type: ALIAS_ONTOLOGY_TYPE, key
|
|
85
|
+
new ontology.ID({ type: ALIAS_ONTOLOGY_TYPE, key });
|
|
@@ -7,12 +7,12 @@
|
|
|
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 { change } from "@synnaxlabs/x";
|
|
10
|
+
import { type change } from "@synnaxlabs/x";
|
|
11
11
|
import { DataType, Rate, TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
|
|
12
12
|
import { describe, expect, it } from "vitest";
|
|
13
13
|
|
|
14
14
|
import { QueryError } from "@/errors";
|
|
15
|
-
import { ranger } from "@/ranger";
|
|
15
|
+
import { type ranger } from "@/ranger";
|
|
16
16
|
import { type NewPayload } from "@/ranger/payload";
|
|
17
17
|
import { newClient } from "@/setupspecs";
|
|
18
18
|
|
package/src/user/user.spec.ts
CHANGED
|
@@ -183,9 +183,8 @@ describe("User", () => {
|
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
test("not found", async () => {
|
|
186
|
-
for (const u of userArray)
|
|
186
|
+
for (const u of userArray)
|
|
187
187
|
await expect(client.user.delete(u.key as string)).resolves.toBeUndefined();
|
|
188
|
-
}
|
|
189
188
|
await expect(
|
|
190
189
|
client.user.retrieve(userArray.map((u) => u.key as string)),
|
|
191
190
|
).rejects.toThrow(NotFoundError);
|
package/src/util/telem.ts
CHANGED
|
@@ -12,8 +12,6 @@ import { type DataType, type TypedArray } from "@synnaxlabs/x/telem";
|
|
|
12
12
|
export const randomSeries = (length: number, dataType: DataType): TypedArray => {
|
|
13
13
|
// generate random bytes of the correct length
|
|
14
14
|
const bytes = new Uint8Array(length * dataType.density.valueOf());
|
|
15
|
-
for (let i = 0; i < bytes.byteLength; i++)
|
|
16
|
-
bytes[i] = Math.floor(Math.random() * 256);
|
|
17
|
-
}
|
|
15
|
+
for (let i = 0; i < bytes.byteLength; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
18
16
|
return new dataType.Array(bytes.buffer);
|
|
19
17
|
};
|
package/src/workspace/client.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { log } from "@/workspace/log";
|
|
|
16
16
|
import { type Key, type Workspace } from "@/workspace/payload";
|
|
17
17
|
import { Retriever } from "@/workspace/retriever";
|
|
18
18
|
import { schematic } from "@/workspace/schematic";
|
|
19
|
+
import { table } from "@/workspace/table";
|
|
19
20
|
import { type NewWorkspace, Writer } from "@/workspace/writer";
|
|
20
21
|
|
|
21
22
|
export class Client implements AsyncTermSearcher<string, Key, Workspace> {
|
|
@@ -23,6 +24,7 @@ export class Client implements AsyncTermSearcher<string, Key, Workspace> {
|
|
|
23
24
|
readonly schematic: schematic.Client;
|
|
24
25
|
readonly linePlot: linePlot.Client;
|
|
25
26
|
readonly log: log.Client;
|
|
27
|
+
readonly table: table.Client;
|
|
26
28
|
private readonly retriever: Retriever;
|
|
27
29
|
private readonly writer: Writer;
|
|
28
30
|
|
|
@@ -32,6 +34,7 @@ export class Client implements AsyncTermSearcher<string, Key, Workspace> {
|
|
|
32
34
|
this.retriever = new Retriever(client);
|
|
33
35
|
this.log = new log.Client(client);
|
|
34
36
|
this.writer = new Writer(client);
|
|
37
|
+
this.table = new table.Client(client);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
async search(term: string): Promise<Workspace[]> {
|
|
@@ -27,4 +27,4 @@ export type LinePlot = z.infer<typeof linePlotZ>;
|
|
|
27
27
|
export const ONTOLOGY_TYPE: ontology.ResourceType = "lineplot";
|
|
28
28
|
|
|
29
29
|
export const ontologyID = (key: Key): ontology.ID =>
|
|
30
|
-
new ontology.ID({ type: ONTOLOGY_TYPE, key
|
|
30
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
package/src/workspace/payload.ts
CHANGED
|
@@ -41,4 +41,4 @@ export type Workspace = z.infer<typeof workspaceZ>;
|
|
|
41
41
|
export const ONTOLOGY_TYPE: ontology.ResourceType = "workspace";
|
|
42
42
|
|
|
43
43
|
export const ontologyID = (key: Key): ontology.ID =>
|
|
44
|
-
new ontology.ID({ type: ONTOLOGY_TYPE, key
|
|
44
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
@@ -35,4 +35,4 @@ export type Schematic = z.infer<typeof schematicZ>;
|
|
|
35
35
|
export const ONTOLOGY_TYPE: ontology.ResourceType = "schematic";
|
|
36
36
|
|
|
37
37
|
export const ontologyID = (key: Key): ontology.ID =>
|
|
38
|
-
new ontology.ID({ type: ONTOLOGY_TYPE, key
|
|
38
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
@@ -0,0 +1,51 @@
|
|
|
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 { type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { type UnknownRecord } from "@synnaxlabs/x/record";
|
|
12
|
+
|
|
13
|
+
import { type Key, type Params, type Table } from "@/workspace/table/payload";
|
|
14
|
+
import { Retriever } from "@/workspace/table/retriever";
|
|
15
|
+
import { type NewTable, Writer } from "@/workspace/table/writer";
|
|
16
|
+
|
|
17
|
+
export class Client {
|
|
18
|
+
private readonly writer: Writer;
|
|
19
|
+
private readonly retriever: Retriever;
|
|
20
|
+
|
|
21
|
+
constructor(client: UnaryClient) {
|
|
22
|
+
this.writer = new Writer(client);
|
|
23
|
+
this.retriever = new Retriever(client);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async create(workspace: string, table: NewTable): Promise<Table> {
|
|
27
|
+
return await this.writer.create(workspace, table);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async rename(key: Key, name: string): Promise<void> {
|
|
31
|
+
await this.writer.rename(key, name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async setData(key: Key, data: UnknownRecord): Promise<void> {
|
|
35
|
+
await this.writer.setData(key, data);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async retrieve(key: Key): Promise<Table>;
|
|
39
|
+
|
|
40
|
+
async retrieve(keys: Key[]): Promise<Table[]>;
|
|
41
|
+
|
|
42
|
+
async retrieve(keys: Params): Promise<Table | Table[]> {
|
|
43
|
+
const isMany = Array.isArray(keys);
|
|
44
|
+
const res = await this.retriever.retrieve(keys);
|
|
45
|
+
return isMany ? res : res[0];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async delete(keys: Params): Promise<void> {
|
|
49
|
+
await this.writer.delete(keys);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
export * from "@/workspace/table/client";
|
|
11
|
+
export * from "@/workspace/table/payload";
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
export * as table from "@/workspace/table/external";
|
|
@@ -0,0 +1,36 @@
|
|
|
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 { type UnknownRecord, unknownRecordZ } from "@synnaxlabs/x/record";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
import { ontology } from "@/ontology";
|
|
14
|
+
|
|
15
|
+
export const keyZ = z.string().uuid();
|
|
16
|
+
export type Key = z.infer<typeof keyZ>;
|
|
17
|
+
export type Params = Key | Key[];
|
|
18
|
+
|
|
19
|
+
export const tableZ = z.object({
|
|
20
|
+
key: z.string(),
|
|
21
|
+
name: z.string(),
|
|
22
|
+
data: unknownRecordZ.or(z.string().transform((s) => JSON.parse(s) as UnknownRecord)),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const tableRemoteZ = z.object({
|
|
26
|
+
key: z.string(),
|
|
27
|
+
name: z.string(),
|
|
28
|
+
data: z.string().transform((s) => JSON.parse(s) as UnknownRecord),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type Table = z.infer<typeof tableZ>;
|
|
32
|
+
|
|
33
|
+
export const ONTOLOGY_TYPE: ontology.ResourceType = "table";
|
|
34
|
+
|
|
35
|
+
export const ontologyID = (key: Key): ontology.ID =>
|
|
36
|
+
new ontology.ID({ type: ONTOLOGY_TYPE, key });
|
|
@@ -0,0 +1,33 @@
|
|
|
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/toArray";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
import { type Params, type Table, tableRemoteZ } from "@/workspace/table/payload";
|
|
15
|
+
|
|
16
|
+
const reqZ = z.object({ keys: z.string().array() });
|
|
17
|
+
const resZ = z.object({ tables: tableRemoteZ.array() });
|
|
18
|
+
|
|
19
|
+
const ENDPOINT = "/workspace/table/retrieve";
|
|
20
|
+
|
|
21
|
+
export class Retriever {
|
|
22
|
+
private readonly client: UnaryClient;
|
|
23
|
+
|
|
24
|
+
constructor(client: UnaryClient) {
|
|
25
|
+
this.client = client;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async retrieve(tables: Params): Promise<Table[]> {
|
|
29
|
+
return (
|
|
30
|
+
await sendRequired(this.client, ENDPOINT, { keys: toArray(tables) }, reqZ, resZ)
|
|
31
|
+
).tables;
|
|
32
|
+
}
|
|
33
|
+
}
|