@synnaxlabs/client 0.13.6 → 0.14.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 +10 -10
- package/dist/auth/index.d.ts +1 -1
- package/dist/channel/client.d.ts +8 -7
- package/dist/channel/creator.d.ts +1 -1
- package/dist/channel/external.d.ts +4 -4
- package/dist/channel/index.d.ts +1 -1
- package/dist/channel/payload.d.ts +6 -0
- package/dist/channel/retriever.d.ts +7 -7
- package/dist/client.cjs.js +14 -23043
- package/dist/client.cjs.js.map +1 -1
- package/dist/client.d.ts +5 -0
- package/dist/client.es.js +11867 -17730
- package/dist/client.es.js.map +1 -1
- package/dist/connection/checker.d.ts +2 -1
- package/dist/connection/index.d.ts +1 -1
- package/dist/control/external.d.ts +2 -2
- package/dist/control/index.d.ts +1 -1
- package/dist/control/state.d.ts +1 -1
- package/dist/framer/adapter.d.ts +1 -1
- package/dist/framer/client.d.ts +4 -4
- package/dist/framer/external.d.ts +5 -5
- package/dist/framer/index.d.ts +1 -1
- package/dist/framer/iterator.d.ts +1 -1
- package/dist/framer/streamer.d.ts +1 -1
- package/dist/framer/writer.d.ts +1 -1
- package/dist/hardware/client.d.ts +9 -0
- package/dist/hardware/device/client.d.ts +16 -0
- package/dist/hardware/device/device.spec.d.ts +1 -0
- package/dist/hardware/device/external.d.ts +3 -0
- package/dist/hardware/device/index.d.ts +1 -0
- package/dist/hardware/device/payload.d.ts +29 -0
- package/dist/hardware/device/retriever.d.ts +7 -0
- package/dist/hardware/device/writer.d.ts +8 -0
- package/dist/hardware/external.d.ts +2 -0
- package/dist/hardware/index.d.ts +1 -0
- package/dist/hardware/rack/client.d.ts +29 -0
- package/dist/hardware/rack/external.d.ts +3 -0
- package/dist/hardware/rack/index.d.ts +1 -0
- package/dist/hardware/rack/payload.d.ts +25 -0
- package/dist/hardware/rack/rack.spec.d.ts +1 -0
- package/dist/hardware/rack/retriever.d.ts +7 -0
- package/dist/hardware/rack/writer.d.ts +8 -0
- package/dist/hardware/task/client.d.ts +12 -0
- package/dist/hardware/task/external.d.ts +3 -0
- package/dist/hardware/task/index.d.ts +1 -0
- package/dist/hardware/task/payload.d.ts +40 -0
- package/dist/hardware/task/retriever.d.ts +20 -0
- package/dist/hardware/task/task.spec.d.ts +1 -0
- package/dist/hardware/task/writer.d.ts +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/label/client.d.ts +2 -2
- package/dist/label/external.d.ts +4 -4
- package/dist/label/index.d.ts +1 -1
- package/dist/label/retriever.d.ts +1 -1
- package/dist/label/writer.d.ts +1 -1
- package/dist/ontology/client.d.ts +4 -4
- package/dist/ontology/external.d.ts +3 -3
- package/dist/ontology/group/client.d.ts +2 -2
- package/dist/ontology/group/external.d.ts +2 -2
- package/dist/ontology/group/group.d.ts +1 -1
- package/dist/ontology/group/index.d.ts +1 -1
- package/dist/ontology/group/writer.d.ts +2 -2
- package/dist/ontology/index.d.ts +1 -1
- package/dist/ontology/payload.d.ts +47 -47
- package/dist/ontology/retriever.d.ts +1 -1
- package/dist/ontology/signals.d.ts +6 -2
- package/dist/ontology/writer.d.ts +1 -1
- package/dist/ranger/alias.d.ts +1 -1
- package/dist/ranger/client.d.ts +4 -4
- package/dist/ranger/external.d.ts +6 -6
- package/dist/ranger/index.d.ts +1 -1
- package/dist/ranger/kv.d.ts +1 -1
- package/dist/ranger/range.d.ts +2 -2
- package/dist/ranger/writer.d.ts +1 -1
- package/dist/signals/external.d.ts +1 -1
- package/dist/signals/index.d.ts +1 -1
- package/dist/user/index.d.ts +1 -1
- package/dist/workspace/client.d.ts +4 -4
- package/dist/workspace/external.d.ts +2 -2
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/lineplot/client.d.ts +2 -2
- package/dist/workspace/lineplot/external.d.ts +2 -2
- package/dist/workspace/lineplot/index.d.ts +1 -1
- package/dist/workspace/lineplot/retriever.d.ts +1 -1
- package/dist/workspace/lineplot/writer.d.ts +1 -1
- package/dist/workspace/pid/client.d.ts +2 -2
- package/dist/workspace/pid/external.d.ts +2 -2
- package/dist/workspace/pid/index.d.ts +1 -1
- package/dist/workspace/pid/writer.d.ts +1 -1
- package/dist/workspace/retriever.d.ts +1 -1
- package/package.json +8 -8
- package/src/channel/client.ts +11 -9
- package/src/channel/payload.ts +1 -0
- package/src/channel/retriever.ts +13 -15
- package/src/client.ts +23 -0
- package/src/connection/checker.ts +4 -2
- package/src/framer/frame.spec.ts +67 -79
- package/src/framer/frame.ts +1 -1
- package/src/framer/writer.ts +1 -1
- package/src/hardware/client.ts +24 -0
- package/src/hardware/device/client.ts +54 -0
- package/src/hardware/device/device.spec.ts +45 -0
- package/src/hardware/device/external.ts +3 -0
- package/src/hardware/device/index.ts +1 -0
- package/src/hardware/device/payload.ts +18 -0
- package/src/hardware/device/retriever.ts +39 -0
- package/src/hardware/device/writer.ts +48 -0
- package/src/hardware/external.ts +11 -0
- package/src/hardware/index.ts +10 -0
- package/src/hardware/rack/client.ts +96 -0
- package/src/hardware/rack/external.ts +3 -0
- package/src/hardware/rack/index.ts +1 -0
- package/src/hardware/rack/payload.ts +17 -0
- package/src/hardware/rack/rack.spec.ts +29 -0
- package/src/hardware/rack/retriever.ts +32 -0
- package/src/hardware/rack/writer.ts +57 -0
- package/src/hardware/task/client.ts +47 -0
- package/src/hardware/task/external.ts +12 -0
- package/src/hardware/task/index.ts +10 -0
- package/src/hardware/task/payload.ts +37 -0
- package/src/hardware/task/retriever.ts +45 -0
- package/src/hardware/task/task.spec.ts +47 -0
- package/src/hardware/task/writer.ts +63 -0
- package/src/index.ts +1 -0
- package/src/label/writer.ts +1 -1
- package/src/ontology/client.ts +1 -1
- package/src/ontology/group/client.ts +3 -3
- package/src/ontology/payload.ts +1 -0
- package/src/ontology/signals.ts +4 -0
- package/vite.config.ts +1 -1
- package/.pytest_cache/README.md +0 -8
- package/dist/cdc/external.d.ts +0 -1
- package/dist/cdc/index.d.ts +0 -1
- package/dist/cdc/observable.d.ts +0 -17
- package/dist/ontology/cdc.d.ts +0 -25
package/src/channel/client.ts
CHANGED
|
@@ -45,6 +45,7 @@ export class Channel {
|
|
|
45
45
|
leaseholder: number;
|
|
46
46
|
index: Key;
|
|
47
47
|
isIndex: boolean;
|
|
48
|
+
alias: string | undefined;
|
|
48
49
|
|
|
49
50
|
constructor({
|
|
50
51
|
dataType,
|
|
@@ -52,10 +53,10 @@ export class Channel {
|
|
|
52
53
|
name,
|
|
53
54
|
leaseholder = 0,
|
|
54
55
|
key = 0,
|
|
55
|
-
density = 0,
|
|
56
56
|
isIndex = false,
|
|
57
57
|
index = 0,
|
|
58
58
|
frameClient,
|
|
59
|
+
alias,
|
|
59
60
|
}: NewPayload & {
|
|
60
61
|
frameClient?: framer.Client;
|
|
61
62
|
density?: CrudeDensity;
|
|
@@ -67,6 +68,7 @@ export class Channel {
|
|
|
67
68
|
this.leaseholder = leaseholder;
|
|
68
69
|
this.index = index;
|
|
69
70
|
this.isIndex = isIndex;
|
|
71
|
+
this.alias = alias;
|
|
70
72
|
this._frameClient = frameClient ?? null;
|
|
71
73
|
}
|
|
72
74
|
|
|
@@ -145,9 +147,9 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
|
|
|
145
147
|
return single ? res[0] : res;
|
|
146
148
|
}
|
|
147
149
|
|
|
148
|
-
async retrieve(channel: KeyOrName): Promise<Channel>;
|
|
150
|
+
async retrieve(channel: KeyOrName, rangeKey?: string): Promise<Channel>;
|
|
149
151
|
|
|
150
|
-
async retrieve(channels: Params): Promise<Channel[]>;
|
|
152
|
+
async retrieve(channels: Params, rangeKey?: string): Promise<Channel[]>;
|
|
151
153
|
|
|
152
154
|
/**
|
|
153
155
|
* Retrieves a channel from the database using the given parameters.
|
|
@@ -157,10 +159,10 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
|
|
|
157
159
|
* @returns The retrieved channel.
|
|
158
160
|
* @raises {QueryError} If the channel does not exist or if multiple results are returned.
|
|
159
161
|
*/
|
|
160
|
-
async retrieve(channels: Params): Promise<Channel | Channel[]> {
|
|
162
|
+
async retrieve(channels: Params, rangeKey?: string): Promise<Channel | Channel[]> {
|
|
161
163
|
const { single, actual, normalized } = analyzeParams(channels);
|
|
162
164
|
if (normalized.length === 0) return [];
|
|
163
|
-
const res = this.sugar(await this.retriever.retrieve(channels));
|
|
165
|
+
const res = this.sugar(await this.retriever.retrieve(channels, rangeKey));
|
|
164
166
|
if (!single) return res;
|
|
165
167
|
if (res.length === 0) throw new QueryError(`channel matching ${actual} not found`);
|
|
166
168
|
if (res.length > 1)
|
|
@@ -176,8 +178,8 @@ export class Client implements AsyncTermSearcher<string, Key, Channel> {
|
|
|
176
178
|
return new SearcherUnderRange(this, rangeKey);
|
|
177
179
|
}
|
|
178
180
|
|
|
179
|
-
async page(offset: number, limit: number): Promise<Channel[]> {
|
|
180
|
-
return this.sugar(await this.retriever.page(offset, limit));
|
|
181
|
+
async page(offset: number, limit: number, rangeKey?: string): Promise<Channel[]> {
|
|
182
|
+
return this.sugar(await this.retriever.page(offset, limit, rangeKey));
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
private sugar(payloads: Payload[]): Channel[] {
|
|
@@ -200,10 +202,10 @@ class SearcherUnderRange implements AsyncTermSearcher<string, Key, Channel> {
|
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
async page(offset: number, limit: number): Promise<Channel[]> {
|
|
203
|
-
return await this.client.page(offset, limit);
|
|
205
|
+
return await this.client.page(offset, limit, this.rangeKey);
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
async retrieve(channels: Key[]): Promise<Channel[]> {
|
|
207
|
-
return await this.client.retrieve(channels);
|
|
209
|
+
return await this.client.retrieve(channels, this.rangeKey);
|
|
208
210
|
}
|
|
209
211
|
}
|
package/src/channel/payload.ts
CHANGED
package/src/channel/retriever.ts
CHANGED
|
@@ -22,14 +22,13 @@ import {
|
|
|
22
22
|
type Payload,
|
|
23
23
|
payload,
|
|
24
24
|
} from "@/channel/payload";
|
|
25
|
-
import { QueryError } from "@/errors";
|
|
26
25
|
|
|
27
26
|
const reqZ = z.object({
|
|
28
27
|
leaseholder: z.number().optional(),
|
|
29
28
|
keys: z.number().array().optional(),
|
|
30
29
|
names: z.string().array().optional(),
|
|
31
30
|
search: z.string().optional(),
|
|
32
|
-
|
|
31
|
+
rangeKey: z.string().optional(),
|
|
33
32
|
limit: z.number().optional(),
|
|
34
33
|
offset: z.number().optional(),
|
|
35
34
|
});
|
|
@@ -41,9 +40,9 @@ const resZ = z.object({
|
|
|
41
40
|
});
|
|
42
41
|
|
|
43
42
|
export interface Retriever {
|
|
44
|
-
retrieve: (channels: Params) => Promise<Payload[]>;
|
|
43
|
+
retrieve: (channels: Params, rangeKey?: string) => Promise<Payload[]>;
|
|
45
44
|
search: (term: string, rangeKey?: string) => Promise<Payload[]>;
|
|
46
|
-
page: (offset: number, limit: number) => Promise<Payload[]>;
|
|
45
|
+
page: (offset: number, limit: number, rangeKey?: string) => Promise<Payload[]>;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
export class ClusterRetriever implements Retriever {
|
|
@@ -55,16 +54,16 @@ export class ClusterRetriever implements Retriever {
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
async search(term: string, rangeKey?: string): Promise<Payload[]> {
|
|
58
|
-
return await this.execute({ search: term,
|
|
57
|
+
return await this.execute({ search: term, rangeKey });
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
async retrieve(channels: Params): Promise<Payload[]> {
|
|
60
|
+
async retrieve(channels: Params, rangeKey?: string): Promise<Payload[]> {
|
|
62
61
|
const { variant, normalized } = analyzeParams(channels);
|
|
63
|
-
return await this.execute({ [variant]: normalized });
|
|
62
|
+
return await this.execute({ [variant]: normalized, rangeKey});
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
async page(offset: number, limit: number): Promise<Payload[]> {
|
|
67
|
-
return await this.execute({ offset, limit });
|
|
65
|
+
async page(offset: number, limit: number, rangeKey?: string): Promise<Payload[]> {
|
|
66
|
+
return await this.execute({ offset, limit, rangeKey});
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
private async execute(request: Request): Promise<Payload[]> {
|
|
@@ -85,12 +84,12 @@ export class CacheRetriever implements Retriever {
|
|
|
85
84
|
this.wrapped = wrapped;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
async search(term: string,
|
|
89
|
-
return await this.wrapped.search(term,
|
|
87
|
+
async search(term: string, rangeKey?: string): Promise<Payload[]> {
|
|
88
|
+
return await this.wrapped.search(term, rangeKey);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
async page(offset: number, limit: number): Promise<Payload[]> {
|
|
93
|
-
return await this.wrapped.page(offset, limit);
|
|
91
|
+
async page(offset: number, limit: number, rangeKey?: string): Promise<Payload[]> {
|
|
92
|
+
return await this.wrapped.page(offset, limit, rangeKey);
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
async retrieve(channels: Params): Promise<Payload[]> {
|
|
@@ -149,8 +148,7 @@ export type ParamAnalysisResult =
|
|
|
149
148
|
};
|
|
150
149
|
|
|
151
150
|
export const analyzeParams = (channels: Params): ParamAnalysisResult => {
|
|
152
|
-
const normal = toArray(channels) as KeysOrNames;
|
|
153
|
-
if (normal.length === 0) throw new QueryError("No channels provided");
|
|
151
|
+
const normal = (toArray(channels) as KeysOrNames).filter((c) => c != 0);
|
|
154
152
|
return {
|
|
155
153
|
single: !Array.isArray(channels),
|
|
156
154
|
variant: typeof normal[0] === "number" ? "keys" : "names",
|
package/src/client.ts
CHANGED
|
@@ -20,6 +20,10 @@ import { ontology } from "@/ontology";
|
|
|
20
20
|
import { ranger } from "@/ranger";
|
|
21
21
|
import { Transport } from "@/transport";
|
|
22
22
|
import { workspace } from "@/workspace";
|
|
23
|
+
import { hardware } from "./hardware";
|
|
24
|
+
import { device } from "./hardware/device";
|
|
25
|
+
import { rack } from "./hardware/rack";
|
|
26
|
+
import { task } from "./hardware/task";
|
|
23
27
|
|
|
24
28
|
export const synnaxPropsZ = z.object({
|
|
25
29
|
host: z.string().min(1),
|
|
@@ -28,6 +32,7 @@ export const synnaxPropsZ = z.object({
|
|
|
28
32
|
password: z.string().optional(),
|
|
29
33
|
connectivityPollFrequency: TimeSpan.z.default(TimeSpan.seconds(30)),
|
|
30
34
|
secure: z.boolean().optional().default(false),
|
|
35
|
+
name: z.string().optional(),
|
|
31
36
|
});
|
|
32
37
|
|
|
33
38
|
export type SynnaxProps = z.input<typeof synnaxPropsZ>;
|
|
@@ -54,6 +59,7 @@ export default class Synnax {
|
|
|
54
59
|
readonly props: ParsedSynnaxProps;
|
|
55
60
|
readonly workspaces: workspace.Client;
|
|
56
61
|
readonly labels: label.Client;
|
|
62
|
+
readonly hardware: hardware.Client;
|
|
57
63
|
static readonly connectivity = connection.Checker;
|
|
58
64
|
|
|
59
65
|
/**
|
|
@@ -94,6 +100,7 @@ export default class Synnax {
|
|
|
94
100
|
this.connectivity = new connection.Checker(
|
|
95
101
|
this.transport.unary,
|
|
96
102
|
connectivityPollFrequency,
|
|
103
|
+
props.name,
|
|
97
104
|
);
|
|
98
105
|
this.ontology = new ontology.Client(this.transport.unary, this.telem);
|
|
99
106
|
const rangeRetriever = new ranger.Retriever(this.transport.unary);
|
|
@@ -108,6 +115,22 @@ export default class Synnax {
|
|
|
108
115
|
this.labels,
|
|
109
116
|
);
|
|
110
117
|
this.workspaces = new workspace.Client(this.transport.unary);
|
|
118
|
+
const devices = new device.Client(
|
|
119
|
+
new device.Retriever(this.transport.unary),
|
|
120
|
+
new device.Writer(this.transport.unary),
|
|
121
|
+
this.telem,
|
|
122
|
+
);
|
|
123
|
+
const taskRetriever = new task.Retriever(this.transport.unary);
|
|
124
|
+
const taskWriter = new task.Writer(this.transport.unary);
|
|
125
|
+
const tasks = new task.Client(taskRetriever, taskWriter);
|
|
126
|
+
const racks = new rack.Client(
|
|
127
|
+
new rack.Retriever(this.transport.unary),
|
|
128
|
+
new rack.Writer(this.transport.unary),
|
|
129
|
+
this.telem,
|
|
130
|
+
taskWriter,
|
|
131
|
+
taskRetriever,
|
|
132
|
+
);
|
|
133
|
+
this.hardware = new hardware.Client(tasks, racks, devices);
|
|
111
134
|
}
|
|
112
135
|
|
|
113
136
|
close(): void {
|
|
@@ -42,6 +42,7 @@ export class Checker {
|
|
|
42
42
|
private readonly _state: State;
|
|
43
43
|
private readonly pollFrequency = TimeSpan.seconds(30);
|
|
44
44
|
private readonly client: UnaryClient;
|
|
45
|
+
private readonly name?: string;
|
|
45
46
|
private interval?: NodeJS.Timeout;
|
|
46
47
|
private readonly onChangeHandlers: Array<(state: State) => void> = [];
|
|
47
48
|
static readonly connectionStateZ = state;
|
|
@@ -51,10 +52,11 @@ export class Checker {
|
|
|
51
52
|
* @param pollFreq - The frequency at which to poll the cluster for
|
|
52
53
|
* connectivity information.
|
|
53
54
|
*/
|
|
54
|
-
constructor(client: UnaryClient, pollFreq: TimeSpan = TimeSpan.seconds(30)) {
|
|
55
|
+
constructor(client: UnaryClient, pollFreq: TimeSpan = TimeSpan.seconds(30), name?: string) {
|
|
55
56
|
this._state = { ...DEFAULT };
|
|
56
57
|
this.client = client;
|
|
57
58
|
this.pollFrequency = pollFreq;
|
|
59
|
+
this.name = name;
|
|
58
60
|
void this.check();
|
|
59
61
|
this.startChecking();
|
|
60
62
|
}
|
|
@@ -74,7 +76,7 @@ export class Checker {
|
|
|
74
76
|
const [res, err] = await this.client.send(Checker.ENDPOINT, null, responseZ);
|
|
75
77
|
if (err != null) throw err;
|
|
76
78
|
this._state.status = "connected";
|
|
77
|
-
this._state.message = `Connected to
|
|
79
|
+
this._state.message = `Connected to ${this.name ?? "cluster"}`;
|
|
78
80
|
this._state.clusterKey = res.clusterKey;
|
|
79
81
|
} catch (err) {
|
|
80
82
|
this._state.status = "failed";
|
package/src/framer/frame.spec.ts
CHANGED
|
@@ -19,9 +19,9 @@ describe("framer.Frame", () => {
|
|
|
19
19
|
const f = new framer.Frame(
|
|
20
20
|
["a", "b", "c"],
|
|
21
21
|
[
|
|
22
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
23
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
24
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
22
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
23
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
24
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
25
25
|
],
|
|
26
26
|
);
|
|
27
27
|
expect(f.length).toEqual(9);
|
|
@@ -32,9 +32,9 @@ describe("framer.Frame", () => {
|
|
|
32
32
|
const f = new framer.Frame(
|
|
33
33
|
[12, 13, 14],
|
|
34
34
|
[
|
|
35
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
36
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
37
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
35
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
36
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
37
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
38
38
|
],
|
|
39
39
|
);
|
|
40
40
|
expect(f.length).toEqual(9);
|
|
@@ -42,25 +42,25 @@ describe("framer.Frame", () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
test("from a single name and an array of arrays", () => {
|
|
45
|
-
const f = new framer.Frame("a", [new Series(new Float32Array([1, 2, 3]))]);
|
|
45
|
+
const f = new framer.Frame("a", [new Series({data: new Float32Array([1, 2, 3])})]);
|
|
46
46
|
expect(f.length).toEqual(3);
|
|
47
47
|
expect(f.colType).toEqual("name");
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
test("from a single key and an array of arrays", () => {
|
|
51
|
-
const f = new framer.Frame(12, [new Series(new Float32Array([1, 2, 3]))]);
|
|
51
|
+
const f = new framer.Frame(12, [new Series({data: new Float32Array([1, 2, 3])})]);
|
|
52
52
|
expect(f.length).toEqual(3);
|
|
53
53
|
expect(f.colType).toEqual("key");
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
test("from a single key and a single array", () => {
|
|
57
|
-
const f = new framer.Frame(12, new Series(new Float32Array([1, 2, 3])));
|
|
57
|
+
const f = new framer.Frame(12, new Series({data: new Float32Array([1, 2, 3])}));
|
|
58
58
|
expect(f.length).toEqual(3);
|
|
59
59
|
expect(f.colType).toEqual("key");
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
test("from a single name and a single array", () => {
|
|
63
|
-
const f = new framer.Frame("a", new Series(new Float32Array([1, 2, 3])));
|
|
63
|
+
const f = new framer.Frame("a", new Series({data: new Float32Array([1, 2, 3])}));
|
|
64
64
|
expect(f.length).toEqual(3);
|
|
65
65
|
expect(f.colType).toEqual("name");
|
|
66
66
|
});
|
|
@@ -82,7 +82,7 @@ describe("framer.Frame", () => {
|
|
|
82
82
|
|
|
83
83
|
test("from record", () => {
|
|
84
84
|
const f = new framer.Frame({
|
|
85
|
-
a: new Series(new Float32Array([1, 2, 3])),
|
|
85
|
+
a: new Series({data: new Float32Array([1, 2, 3])}),
|
|
86
86
|
});
|
|
87
87
|
expect(f.length.valueOf()).toEqual(3);
|
|
88
88
|
expect(f.columns.length).toEqual(1);
|
|
@@ -91,7 +91,7 @@ describe("framer.Frame", () => {
|
|
|
91
91
|
|
|
92
92
|
test("from map", () => {
|
|
93
93
|
const f = new framer.Frame(
|
|
94
|
-
new Map([[12, new Series(new Float32Array([1, 2, 3]))]]),
|
|
94
|
+
new Map([[12, new Series({data: new Float32Array([1, 2, 3])})]]),
|
|
95
95
|
);
|
|
96
96
|
expect(f.length).toEqual(3);
|
|
97
97
|
expect(f.columns.length).toEqual(1);
|
|
@@ -106,8 +106,8 @@ describe("framer.Frame", () => {
|
|
|
106
106
|
new framer.Frame(
|
|
107
107
|
["a", "b", "c"],
|
|
108
108
|
[
|
|
109
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
110
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
109
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
110
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
111
111
|
],
|
|
112
112
|
),
|
|
113
113
|
).toThrow();
|
|
@@ -119,12 +119,12 @@ describe("framer.Frame", () => {
|
|
|
119
119
|
it("should return false if a key has more than one array", () => {
|
|
120
120
|
const f = new framer.Frame(
|
|
121
121
|
new Map([
|
|
122
|
-
[12, [new Series(new Float32Array([1, 2, 3]))]],
|
|
122
|
+
[12, [new Series({data: new Float32Array([1, 2, 3])})]],
|
|
123
123
|
[
|
|
124
124
|
13,
|
|
125
125
|
[
|
|
126
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
127
|
-
new Series(new Float32Array([1, 2, 3])),
|
|
126
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
127
|
+
new Series({data: new Float32Array([1, 2, 3])}),
|
|
128
128
|
],
|
|
129
129
|
],
|
|
130
130
|
]),
|
|
@@ -137,8 +137,8 @@ describe("framer.Frame", () => {
|
|
|
137
137
|
it("should return false if there is more than one key", () => {
|
|
138
138
|
const f = new framer.Frame(
|
|
139
139
|
new Map([
|
|
140
|
-
[12, [new Series(new Float32Array([1, 2, 3]))]],
|
|
141
|
-
[13, [new Series(new Float32Array([1, 2, 3]))]],
|
|
140
|
+
[12, [new Series({data: new Float32Array([1, 2, 3])})]],
|
|
141
|
+
[13, [new Series({data: new Float32Array([1, 2, 3])})]],
|
|
142
142
|
]),
|
|
143
143
|
);
|
|
144
144
|
expect(f.isHorizontal).toEqual(false);
|
|
@@ -152,21 +152,19 @@ describe("framer.Frame", () => {
|
|
|
152
152
|
[
|
|
153
153
|
12,
|
|
154
154
|
[
|
|
155
|
-
new Series(
|
|
156
|
-
new Float32Array([1, 2, 3]),
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
),
|
|
155
|
+
new Series({
|
|
156
|
+
data: new Float32Array([1, 2, 3]),
|
|
157
|
+
timeRange: new TimeRange(500, 50000),
|
|
158
|
+
}),
|
|
160
159
|
],
|
|
161
160
|
],
|
|
162
161
|
[
|
|
163
162
|
13,
|
|
164
163
|
[
|
|
165
|
-
new Series(
|
|
166
|
-
new Float32Array([1, 2, 3]),
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
),
|
|
164
|
+
new Series({
|
|
165
|
+
data: new Float32Array([1, 2, 3]),
|
|
166
|
+
timeRange: new TimeRange(500, 50000),
|
|
167
|
+
}),
|
|
170
168
|
],
|
|
171
169
|
],
|
|
172
170
|
]),
|
|
@@ -180,21 +178,19 @@ describe("framer.Frame", () => {
|
|
|
180
178
|
[
|
|
181
179
|
12,
|
|
182
180
|
[
|
|
183
|
-
new Series(
|
|
184
|
-
new Float32Array([1, 2, 3]),
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
),
|
|
181
|
+
new Series({
|
|
182
|
+
data: new Float32Array([1, 2, 3]),
|
|
183
|
+
timeRange: new TimeRange(500, 50000),
|
|
184
|
+
}),
|
|
188
185
|
],
|
|
189
186
|
],
|
|
190
187
|
[
|
|
191
188
|
13,
|
|
192
189
|
[
|
|
193
|
-
new Series(
|
|
194
|
-
new Float32Array([1, 2, 3]),
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
),
|
|
190
|
+
new Series({
|
|
191
|
+
data: new Float32Array([1, 2, 3]),
|
|
192
|
+
timeRange: new TimeRange(500, 50001),
|
|
193
|
+
}),
|
|
198
194
|
],
|
|
199
195
|
],
|
|
200
196
|
]),
|
|
@@ -211,21 +207,19 @@ describe("framer.Frame", () => {
|
|
|
211
207
|
[
|
|
212
208
|
12,
|
|
213
209
|
[
|
|
214
|
-
new Series(
|
|
215
|
-
new Float32Array([1, 2, 3]),
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
),
|
|
210
|
+
new Series({
|
|
211
|
+
data: new Float32Array([1, 2, 3]),
|
|
212
|
+
timeRange: new TimeRange(40, 50000),
|
|
213
|
+
}),
|
|
219
214
|
],
|
|
220
215
|
],
|
|
221
216
|
[
|
|
222
217
|
13,
|
|
223
218
|
[
|
|
224
|
-
new Series(
|
|
225
|
-
new Float32Array([1, 2, 3]),
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
),
|
|
219
|
+
new Series({
|
|
220
|
+
data: new Float32Array([1, 2, 3]),
|
|
221
|
+
timeRange: new TimeRange(500, 50001),
|
|
222
|
+
}),
|
|
229
223
|
],
|
|
230
224
|
],
|
|
231
225
|
]),
|
|
@@ -237,16 +231,14 @@ describe("framer.Frame", () => {
|
|
|
237
231
|
describe("key provided", () => {
|
|
238
232
|
it("should return the time range of the key", () => {
|
|
239
233
|
const f = new framer.Frame({
|
|
240
|
-
a: new Series(
|
|
241
|
-
new Float32Array([1, 2, 3]),
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
new
|
|
247
|
-
|
|
248
|
-
new TimeRange(500, 50001),
|
|
249
|
-
),
|
|
234
|
+
a: new Series({
|
|
235
|
+
data: new Float32Array([1, 2, 3]),
|
|
236
|
+
timeRange: new TimeRange(40, 50000),
|
|
237
|
+
}),
|
|
238
|
+
b: new Series({
|
|
239
|
+
data: new Float32Array([1, 2, 3]),
|
|
240
|
+
timeRange: new TimeRange(500, 50001),
|
|
241
|
+
}),
|
|
250
242
|
});
|
|
251
243
|
expect(f.timeRange("a")).toEqual(new TimeRange(40, 50000));
|
|
252
244
|
});
|
|
@@ -259,21 +251,19 @@ describe("framer.Frame", () => {
|
|
|
259
251
|
[
|
|
260
252
|
12,
|
|
261
253
|
[
|
|
262
|
-
new Series(
|
|
263
|
-
new Float32Array([1, 2, 3]),
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
),
|
|
254
|
+
new Series({
|
|
255
|
+
data: new Float32Array([1, 2, 3]),
|
|
256
|
+
timeRange: new TimeRange(40, 50000),
|
|
257
|
+
}),
|
|
267
258
|
],
|
|
268
259
|
],
|
|
269
260
|
[
|
|
270
261
|
13,
|
|
271
262
|
[
|
|
272
|
-
new Series(
|
|
273
|
-
new Float32Array([1, 2, 3]),
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
),
|
|
263
|
+
new Series({
|
|
264
|
+
data: new Float32Array([1, 2, 3]),
|
|
265
|
+
timeRange: new TimeRange(500, 50001),
|
|
266
|
+
}),
|
|
277
267
|
],
|
|
278
268
|
],
|
|
279
269
|
]),
|
|
@@ -290,21 +280,19 @@ describe("framer.Frame", () => {
|
|
|
290
280
|
[
|
|
291
281
|
12,
|
|
292
282
|
[
|
|
293
|
-
new Series(
|
|
294
|
-
new Float32Array([1, 2, 3]),
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
),
|
|
283
|
+
new Series({
|
|
284
|
+
data: new Float32Array([1, 2, 3]),
|
|
285
|
+
timeRange: new TimeRange(40, 50000),
|
|
286
|
+
}),
|
|
298
287
|
],
|
|
299
288
|
],
|
|
300
289
|
[
|
|
301
290
|
13,
|
|
302
291
|
[
|
|
303
|
-
new Series(
|
|
304
|
-
new Float32Array([1, 2, 3]),
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
),
|
|
292
|
+
new Series({
|
|
293
|
+
data: new Float32Array([1, 2, 3]),
|
|
294
|
+
timeRange: new TimeRange(500, 50001),
|
|
295
|
+
}),
|
|
308
296
|
],
|
|
309
297
|
],
|
|
310
298
|
]),
|
package/src/framer/frame.ts
CHANGED
|
@@ -399,7 +399,7 @@ export type FramePayload = z.infer<typeof frameZ>;
|
|
|
399
399
|
|
|
400
400
|
export const seriesFromPayload = (series: SeriesPayload): Series => {
|
|
401
401
|
const { dataType, data, timeRange, alignment } = series;
|
|
402
|
-
return new Series(data, dataType, timeRange,
|
|
402
|
+
return new Series({data, dataType, timeRange, glBufferUsage: "static", alignment});
|
|
403
403
|
};
|
|
404
404
|
|
|
405
405
|
export const seriesToPayload = (series: Series): SeriesPayload => {
|
package/src/framer/writer.ts
CHANGED
|
@@ -168,7 +168,7 @@ export class Writer {
|
|
|
168
168
|
): Promise<boolean> {
|
|
169
169
|
const isKeyOrName = ["string", "number"].includes(typeof frame);
|
|
170
170
|
if (isKeyOrName) {
|
|
171
|
-
frame = new Frame(frame, new Series(data as NativeTypedArray));
|
|
171
|
+
frame = new Frame(frame, new Series({data: data as NativeTypedArray}));
|
|
172
172
|
}
|
|
173
173
|
frame = this.adapter.adapt(new Frame(frame));
|
|
174
174
|
// @ts-expect-error
|
|
@@ -0,0 +1,24 @@
|
|
|
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 device } from "@/hardware/device";
|
|
11
|
+
import { type rack } from "@/hardware/rack";
|
|
12
|
+
import { type task } from "@/hardware/task";
|
|
13
|
+
|
|
14
|
+
export class Client {
|
|
15
|
+
readonly tasks: task.Client;
|
|
16
|
+
readonly racks: rack.Client;
|
|
17
|
+
readonly devices: device.Client;
|
|
18
|
+
|
|
19
|
+
constructor(tasks: task.Client, racks: rack.Client, devices: device.Client) {
|
|
20
|
+
this.tasks = tasks;
|
|
21
|
+
this.racks = racks;
|
|
22
|
+
this.devices = devices;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { toArray } from "@synnaxlabs/x";
|
|
2
|
+
|
|
3
|
+
import { type framer } from "@/framer";
|
|
4
|
+
import { type Device, deviceZ } from "@/hardware/device/payload";
|
|
5
|
+
import { type Retriever } from "@/hardware/device/retriever";
|
|
6
|
+
import { type Writer } from "@/hardware/device/writer";
|
|
7
|
+
import { signals } from "@/signals";
|
|
8
|
+
|
|
9
|
+
const DEVICE_SET_NAME = "sy_device_set";
|
|
10
|
+
const DEVICE_DELETE_NAME = "sy_device_delete";
|
|
11
|
+
|
|
12
|
+
export class Client {
|
|
13
|
+
private readonly retriever: Retriever;
|
|
14
|
+
private readonly writer: Writer;
|
|
15
|
+
private readonly frameClient: framer.Client;
|
|
16
|
+
|
|
17
|
+
constructor(retriever: Retriever, writer: Writer, frameClient: framer.Client) {
|
|
18
|
+
this.retriever = retriever;
|
|
19
|
+
this.writer = writer;
|
|
20
|
+
this.frameClient = frameClient;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async create(device: Device): Promise<Device> {
|
|
24
|
+
const res = await this.writer.create([device]);
|
|
25
|
+
return res[0];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async retrieve(key: string): Promise<Device>;
|
|
29
|
+
async retrieve(keys: string[]): Promise<Device[]>;
|
|
30
|
+
|
|
31
|
+
async retrieve(keys: string | string[]): Promise<Device | Device[]> {
|
|
32
|
+
const res = await this.retriever.retrieve(toArray(keys));
|
|
33
|
+
return Array.isArray(keys) ? res : res[0];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async delete(keys: string[]): Promise<void> {
|
|
37
|
+
await this.writer.delete(keys);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async openDeviceTracker(): Promise<signals.Observable<string, Device>> {
|
|
41
|
+
return await signals.Observable.open<string, Device>(
|
|
42
|
+
this.frameClient,
|
|
43
|
+
DEVICE_SET_NAME,
|
|
44
|
+
DEVICE_DELETE_NAME,
|
|
45
|
+
decodeDeviceChanges,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const decodeDeviceChanges: signals.Decoder<string, Device> = (variant, data) => {
|
|
51
|
+
if (variant === "delete")
|
|
52
|
+
return data.toStrings().map((k) => ({ variant, key: k, value: undefined }));
|
|
53
|
+
return data.parseJSON(deviceZ).map((d) => ({ variant, key: d.key, value: d }));
|
|
54
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { newClient } from "@/setupspecs";
|
|
4
|
+
|
|
5
|
+
const client = newClient();
|
|
6
|
+
|
|
7
|
+
describe("Device", () => {
|
|
8
|
+
describe("Device", () => {
|
|
9
|
+
describe("create", () => {
|
|
10
|
+
it("should create a device on a rack", async () => {
|
|
11
|
+
const rack = await client.hardware.racks.create({ name: "test" });
|
|
12
|
+
const d = await client.hardware.devices.create({
|
|
13
|
+
rack: rack.key,
|
|
14
|
+
location: "Dev1",
|
|
15
|
+
key: "SN222",
|
|
16
|
+
name: "test",
|
|
17
|
+
make: "ni",
|
|
18
|
+
model: "dog",
|
|
19
|
+
properties: "dog",
|
|
20
|
+
});
|
|
21
|
+
expect(d.key).toEqual("SN222");
|
|
22
|
+
expect(d.name).toBe("test");
|
|
23
|
+
expect(d.make).toBe("ni");
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe("retrieve", () => {
|
|
27
|
+
it("should retrieve a device by its key", async () => {
|
|
28
|
+
const rack = await client.hardware.racks.create({ name: "test" });
|
|
29
|
+
const d = await client.hardware.devices.create({
|
|
30
|
+
key: "SN222",
|
|
31
|
+
rack: rack.key,
|
|
32
|
+
location: "Dev1",
|
|
33
|
+
name: "test",
|
|
34
|
+
make: "ni",
|
|
35
|
+
model: "dog",
|
|
36
|
+
properties: "dog",
|
|
37
|
+
});
|
|
38
|
+
const retrieved = await client.hardware.devices.retrieve(d.key);
|
|
39
|
+
expect(retrieved.key).toBe(d.key);
|
|
40
|
+
expect(retrieved.name).toBe("test");
|
|
41
|
+
expect(retrieved.make).toBe("ni");
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|