@synnaxlabs/client 0.22.0 → 0.23.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 -6
- package/dist/auth/auth.d.ts.map +1 -1
- package/dist/channel/client.d.ts +14 -4
- package/dist/channel/client.d.ts.map +1 -1
- package/dist/channel/creator.d.ts +1 -1
- package/dist/channel/creator.d.ts.map +1 -1
- package/dist/channel/external.d.ts +1 -1
- package/dist/channel/external.d.ts.map +1 -1
- package/dist/channel/payload.d.ts +21 -8
- package/dist/channel/payload.d.ts.map +1 -1
- package/dist/channel/retriever.d.ts +6 -6
- package/dist/channel/retriever.d.ts.map +1 -1
- package/dist/channel/writer.d.ts +13 -1
- package/dist/channel/writer.d.ts.map +1 -1
- package/dist/client.cjs +17 -18
- package/dist/client.d.ts +4 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5487 -13607
- package/dist/connection/checker.d.ts +4 -4
- package/dist/control/client.d.ts +9 -0
- package/dist/control/client.d.ts.map +1 -0
- package/dist/control/external.d.ts +1 -1
- package/dist/control/external.d.ts.map +1 -1
- package/dist/control/state.d.ts +17 -52
- package/dist/control/state.d.ts.map +1 -1
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/framer/adapter.d.ts +1 -1
- package/dist/framer/adapter.d.ts.map +1 -1
- package/dist/framer/client.d.ts +7 -5
- package/dist/framer/client.d.ts.map +1 -1
- package/dist/framer/deleter.d.ts +68 -0
- package/dist/framer/deleter.d.ts.map +1 -0
- package/dist/framer/deleter.spec.d.ts +2 -0
- package/dist/framer/deleter.spec.d.ts.map +1 -0
- package/dist/framer/frame.d.ts +45 -241
- package/dist/framer/frame.d.ts.map +1 -1
- package/dist/framer/iterator.d.ts +1 -1
- package/dist/framer/iterator.d.ts.map +1 -1
- package/dist/framer/streamProxy.d.ts.map +1 -1
- package/dist/framer/streamer.d.ts.map +1 -1
- package/dist/framer/writer.d.ts +86 -231
- package/dist/framer/writer.d.ts.map +1 -1
- package/dist/hardware/device/client.d.ts +9 -7
- package/dist/hardware/device/client.d.ts.map +1 -1
- package/dist/hardware/task/client.d.ts +17 -14
- package/dist/hardware/task/client.d.ts.map +1 -1
- package/dist/index.d.ts +12 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/label/client.d.ts.map +1 -1
- package/dist/label/external.d.ts +2 -2
- package/dist/label/external.d.ts.map +1 -1
- package/dist/label/writer.d.ts +4 -2
- package/dist/label/writer.d.ts.map +1 -1
- package/dist/ontology/client.d.ts +8 -8
- package/dist/ontology/client.d.ts.map +1 -1
- package/dist/ontology/group/client.d.ts +1 -1
- package/dist/ontology/group/client.d.ts.map +1 -1
- package/dist/ontology/group/external.d.ts +1 -1
- package/dist/ontology/group/external.d.ts.map +1 -1
- package/dist/ontology/group/writer.d.ts +1 -1
- package/dist/ontology/group/writer.d.ts.map +1 -1
- package/dist/ontology/payload.d.ts +14 -26
- package/dist/ontology/payload.d.ts.map +1 -1
- package/dist/ontology/writer.d.ts.map +1 -1
- package/dist/ranger/active.d.ts +1 -1
- package/dist/ranger/active.d.ts.map +1 -1
- package/dist/ranger/alias.d.ts.map +1 -1
- package/dist/ranger/client.d.ts +16 -100
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/external.d.ts +2 -2
- package/dist/ranger/external.d.ts.map +1 -1
- package/dist/ranger/kv.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts +34 -270
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/range.d.ts +1 -1
- package/dist/ranger/range.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts.map +1 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/util/retrieve.d.ts.map +1 -1
- package/dist/util/zod.d.ts +1 -1
- package/dist/util/zod.d.ts.map +1 -1
- package/dist/workspace/client.d.ts.map +1 -1
- package/dist/workspace/external.d.ts +1 -1
- package/dist/workspace/external.d.ts.map +1 -1
- package/dist/workspace/lineplot/client.d.ts +1 -1
- package/dist/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/external.d.ts +1 -1
- package/dist/workspace/lineplot/external.d.ts.map +1 -1
- package/dist/workspace/lineplot/payload.d.ts +2 -2
- package/dist/workspace/lineplot/retriever.d.ts.map +1 -1
- package/dist/workspace/lineplot/writer.d.ts +4 -4
- package/dist/workspace/lineplot/writer.d.ts.map +1 -1
- package/dist/workspace/payload.d.ts +6 -4
- package/dist/workspace/payload.d.ts.map +1 -1
- package/dist/workspace/retriever.d.ts.map +1 -1
- package/dist/workspace/schematic/client.d.ts.map +1 -1
- package/dist/workspace/schematic/external.d.ts +1 -1
- package/dist/workspace/schematic/external.d.ts.map +1 -1
- package/dist/workspace/schematic/payload.d.ts +2 -2
- package/dist/workspace/schematic/retriever.d.ts +1 -1
- package/dist/workspace/schematic/retriever.d.ts.map +1 -1
- package/dist/workspace/schematic/writer.d.ts +4 -4
- package/dist/workspace/schematic/writer.d.ts.map +1 -1
- package/dist/workspace/writer.d.ts +7 -5
- package/dist/workspace/writer.d.ts.map +1 -1
- package/eslint.config.js +12 -0
- package/examples/node/basicReadWrite.js +11 -2
- package/examples/node/liveStream.js +13 -4
- package/examples/node/seriesAndFrames.js +12 -3
- package/examples/node/streamWrite.js +15 -6
- package/package.json +11 -8
- package/src/auth/auth.spec.ts +7 -6
- package/src/auth/auth.ts +17 -13
- package/src/auth/index.ts +1 -1
- package/src/channel/batchRetriever.spec.ts +16 -5
- package/src/channel/channel.spec.ts +42 -4
- package/src/channel/client.ts +26 -9
- package/src/channel/creator.ts +2 -2
- package/src/channel/external.ts +2 -2
- package/src/channel/index.ts +1 -1
- package/src/channel/payload.ts +3 -1
- package/src/channel/retriever.ts +6 -4
- package/src/channel/writer.ts +23 -4
- package/src/client.ts +5 -3
- package/src/connection/checker.ts +1 -1
- package/src/connection/connection.spec.ts +1 -1
- package/src/connection/index.ts +1 -1
- package/src/control/client.ts +17 -0
- package/src/control/external.ts +2 -2
- package/src/control/index.ts +1 -1
- package/src/control/state.spec.ts +2 -3
- package/src/control/state.ts +20 -84
- package/src/errors.ts +18 -7
- package/src/framer/adapter.spec.ts +9 -0
- package/src/framer/adapter.ts +3 -3
- package/src/framer/client.spec.ts +1 -1
- package/src/framer/client.ts +34 -14
- package/src/framer/deleter.spec.ts +129 -0
- package/src/framer/deleter.ts +49 -0
- package/src/framer/external.ts +1 -1
- package/src/framer/frame.spec.ts +1 -1
- package/src/framer/frame.ts +14 -14
- package/src/framer/index.ts +1 -1
- package/src/framer/iterator.spec.ts +2 -2
- package/src/framer/iterator.ts +2 -2
- package/src/framer/streamProxy.ts +2 -4
- package/src/framer/streamer.spec.ts +2 -2
- package/src/framer/streamer.ts +6 -5
- package/src/framer/writer.spec.ts +18 -1
- package/src/framer/writer.ts +19 -27
- package/src/hardware/device/client.ts +2 -2
- package/src/hardware/device/index.ts +1 -1
- package/src/hardware/external.ts +1 -1
- package/src/hardware/index.ts +1 -1
- package/src/hardware/rack/rack.spec.ts +1 -1
- package/src/hardware/task/client.ts +3 -3
- package/src/hardware/task/task.spec.ts +2 -2
- package/src/index.ts +26 -25
- package/src/label/client.ts +2 -2
- package/src/label/external.ts +3 -3
- package/src/label/index.ts +1 -1
- package/src/label/label.spec.ts +1 -1
- package/src/label/payload.ts +1 -1
- package/src/label/retriever.ts +1 -1
- package/src/label/writer.ts +1 -1
- package/src/ontology/client.ts +7 -7
- package/src/ontology/external.ts +1 -1
- package/src/ontology/group/client.ts +3 -3
- package/src/ontology/group/external.ts +2 -2
- package/src/ontology/group/group.spec.ts +2 -2
- package/src/ontology/group/group.ts +1 -1
- package/src/ontology/group/index.ts +1 -1
- package/src/ontology/group/payload.ts +1 -1
- package/src/ontology/group/writer.ts +22 -6
- package/src/ontology/index.ts +1 -1
- package/src/ontology/ontology.spec.ts +2 -2
- package/src/ontology/payload.ts +3 -3
- package/src/ontology/writer.ts +2 -2
- package/src/ranger/active.ts +2 -2
- package/src/ranger/alias.ts +2 -2
- package/src/ranger/client.ts +15 -16
- package/src/ranger/external.ts +3 -3
- package/src/ranger/index.ts +1 -1
- package/src/ranger/kv.ts +2 -2
- package/src/ranger/payload.ts +1 -1
- package/src/ranger/range.ts +2 -2
- package/src/ranger/ranger.spec.ts +1 -1
- package/src/ranger/writer.ts +3 -3
- package/src/setupspecs.ts +1 -1
- package/src/signals/external.ts +1 -1
- package/src/signals/index.ts +1 -1
- package/src/signals/observable.ts +1 -1
- package/src/transport.ts +2 -2
- package/src/user/index.ts +1 -1
- package/src/user/payload.ts +1 -1
- package/src/util/retrieve.spec.ts +1 -1
- package/src/util/retrieve.ts +1 -1
- package/src/util/telem.ts +1 -1
- package/src/util/zod.ts +11 -2
- package/src/vite-env.d.ts +2 -2
- package/src/workspace/client.ts +2 -2
- package/src/workspace/external.ts +2 -2
- package/src/workspace/index.ts +1 -1
- package/src/workspace/lineplot/client.ts +2 -2
- package/src/workspace/lineplot/external.ts +2 -2
- package/src/workspace/lineplot/index.ts +1 -1
- package/src/workspace/lineplot/linePlot.spec.ts +2 -2
- package/src/workspace/lineplot/payload.ts +1 -1
- package/src/workspace/lineplot/retriever.ts +4 -10
- package/src/workspace/lineplot/writer.ts +4 -4
- package/src/workspace/payload.ts +11 -6
- package/src/workspace/retriever.ts +12 -6
- package/src/workspace/schematic/client.ts +2 -2
- package/src/workspace/schematic/external.ts +2 -2
- package/src/workspace/schematic/index.ts +1 -1
- package/src/workspace/schematic/payload.ts +1 -1
- package/src/workspace/schematic/retriever.ts +17 -18
- package/src/workspace/schematic/schematic.spec.ts +2 -2
- package/src/workspace/schematic/writer.ts +5 -5
- package/src/workspace/workspace.spec.ts +2 -2
- package/src/workspace/writer.ts +3 -3
- package/vite.config.ts +3 -4
- package/.eslintrc.cjs +0 -18
- package/dist/client.cjs.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/control/authority.d.ts +0 -8
- package/dist/control/authority.d.ts.map +0 -1
- package/src/control/authority.ts +0 -26
|
@@ -0,0 +1,129 @@
|
|
|
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 { DataType, Rate, TimeRange, TimeStamp } from "@synnaxlabs/x/telem";
|
|
11
|
+
import { describe, expect, test } from "vitest";
|
|
12
|
+
import { NotFoundError, UnauthorizedError } from "@/errors"
|
|
13
|
+
|
|
14
|
+
import { type channel } from "@/channel";
|
|
15
|
+
import { newClient } from "@/setupspecs";
|
|
16
|
+
import { randomSeries } from "@/util/telem";
|
|
17
|
+
|
|
18
|
+
const client = newClient();
|
|
19
|
+
|
|
20
|
+
const newChannel = async (): Promise<channel.Channel> =>
|
|
21
|
+
await client.channels.create({
|
|
22
|
+
name: "test",
|
|
23
|
+
leaseholder: 1,
|
|
24
|
+
rate: Rate.hz(1),
|
|
25
|
+
dataType: DataType.FLOAT64,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const newIndexDataChannelPair = async (): Promise<channel.Channel[]> => {
|
|
29
|
+
const ind = await client.channels.create({
|
|
30
|
+
name: "index",
|
|
31
|
+
leaseholder: 1,
|
|
32
|
+
isIndex: true,
|
|
33
|
+
dataType: DataType.TIMESTAMP,
|
|
34
|
+
})
|
|
35
|
+
const data = await client.channels.create({
|
|
36
|
+
name: "data",
|
|
37
|
+
leaseholder: 1,
|
|
38
|
+
index: ind.key,
|
|
39
|
+
dataType: DataType.INT64,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return [ind, data]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe("Deleter", () => {
|
|
46
|
+
test("Client - basic delete", async () => {
|
|
47
|
+
const ch = await newChannel();
|
|
48
|
+
const data = randomSeries(10, ch.dataType);
|
|
49
|
+
await client.write(TimeStamp.seconds(0), ch.key, data);
|
|
50
|
+
|
|
51
|
+
await client.delete(ch.key, TimeStamp.seconds(2).range(TimeStamp.seconds(5)))
|
|
52
|
+
|
|
53
|
+
const res = await client.read(TimeRange.MAX, ch.key);
|
|
54
|
+
expect(res.length).toEqual(data.length - 3);
|
|
55
|
+
expect(res.data.slice(0, 2)).toEqual(data.slice(0, 2))
|
|
56
|
+
expect(res.data.slice(2)).toEqual(data.slice(5))
|
|
57
|
+
});
|
|
58
|
+
test("Client - basic delete by name", async () => {
|
|
59
|
+
const ch = await newChannel()
|
|
60
|
+
const data = randomSeries(10, ch.dataType);
|
|
61
|
+
await client.write(TimeStamp.seconds(0), ch.key, data);
|
|
62
|
+
|
|
63
|
+
await client.delete(ch.name, TimeStamp.seconds(2).range(TimeStamp.seconds(5)))
|
|
64
|
+
|
|
65
|
+
const res = await client.read(TimeRange.MAX, ch.key);
|
|
66
|
+
expect(res.length).toEqual(data.length - 3);
|
|
67
|
+
expect(res.data.slice(0, 2)).toEqual(data.slice(0, 2))
|
|
68
|
+
expect(res.data.slice(2)).toEqual(data.slice(5))
|
|
69
|
+
})
|
|
70
|
+
test("Client - delete name not found", async () => {
|
|
71
|
+
const ch = await newChannel();
|
|
72
|
+
const data = randomSeries(10, ch.dataType);
|
|
73
|
+
await client.write(TimeStamp.seconds(0), ch.key, data);
|
|
74
|
+
|
|
75
|
+
await expect(
|
|
76
|
+
client.delete(["billy bob", ch.name], TimeRange.MAX)
|
|
77
|
+
).rejects.toThrow(NotFoundError)
|
|
78
|
+
|
|
79
|
+
const res = await client.read(TimeRange.MAX, ch.key);
|
|
80
|
+
expect(res.data).toEqual(data);
|
|
81
|
+
})
|
|
82
|
+
test("Client - delete key not found", async () => {
|
|
83
|
+
const ch = await newChannel();
|
|
84
|
+
const data = randomSeries(10, ch.dataType);
|
|
85
|
+
await client.write(TimeStamp.seconds(0), ch.key, data);
|
|
86
|
+
|
|
87
|
+
await expect(
|
|
88
|
+
client.delete([ch.key, 1232], TimeRange.MAX)
|
|
89
|
+
).rejects.toThrow(NotFoundError)
|
|
90
|
+
|
|
91
|
+
const res = await client.read(TimeRange.MAX, ch.key);
|
|
92
|
+
expect(res.data).toEqual(data);
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test("Client - delete with writer", async () => {
|
|
96
|
+
const ch = await newChannel();
|
|
97
|
+
|
|
98
|
+
const writer = await client.openWriter({
|
|
99
|
+
start: TimeStamp.seconds(10),
|
|
100
|
+
channels: [ch.key],
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
await expect(
|
|
104
|
+
client.delete(
|
|
105
|
+
[ch.key], TimeStamp.seconds(12).range(TimeStamp.seconds(30)))
|
|
106
|
+
).rejects.toThrow(UnauthorizedError)
|
|
107
|
+
|
|
108
|
+
await writer.close()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test("Client - delete index channel alone", async () => {
|
|
112
|
+
const chs = await newIndexDataChannelPair()
|
|
113
|
+
const index = chs[0]
|
|
114
|
+
const dat = chs[1]
|
|
115
|
+
const data = randomSeries(10, dat.dataType)
|
|
116
|
+
|
|
117
|
+
const time = BigInt64Array.from({ length: 10 },
|
|
118
|
+
(_, i) => (TimeStamp.milliseconds(i)).valueOf());
|
|
119
|
+
|
|
120
|
+
await index.write(0, time)
|
|
121
|
+
await dat.write(0, data)
|
|
122
|
+
|
|
123
|
+
await expect(
|
|
124
|
+
client.delete(
|
|
125
|
+
[index.key], TimeStamp.milliseconds(2).range(TimeStamp.milliseconds(5))
|
|
126
|
+
)
|
|
127
|
+
).rejects.toThrow()
|
|
128
|
+
})
|
|
129
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
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, UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { TimeRange } from "@synnaxlabs/x";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
import { keyZ } from "@/channel/payload";
|
|
15
|
+
|
|
16
|
+
const reqZ = z.object({
|
|
17
|
+
keys: keyZ.array().optional(),
|
|
18
|
+
names: z.string().array().optional(),
|
|
19
|
+
bounds: TimeRange.z,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
type RequestProps = z.infer<typeof reqZ>;
|
|
23
|
+
|
|
24
|
+
const resZ = z.object({});
|
|
25
|
+
|
|
26
|
+
const ENDPOINT = "/frame/delete";
|
|
27
|
+
|
|
28
|
+
export class Deleter {
|
|
29
|
+
/*
|
|
30
|
+
Deleter is used to delete a time range of telemetry from the data engine.
|
|
31
|
+
*/
|
|
32
|
+
private readonly client: UnaryClient;
|
|
33
|
+
|
|
34
|
+
constructor(
|
|
35
|
+
client: UnaryClient,
|
|
36
|
+
) {
|
|
37
|
+
this.client = client;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async delete(props: RequestProps): Promise<void> {
|
|
41
|
+
await sendRequired<typeof reqZ, typeof resZ>(
|
|
42
|
+
this.client,
|
|
43
|
+
ENDPOINT,
|
|
44
|
+
props,
|
|
45
|
+
reqZ,
|
|
46
|
+
resZ,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/framer/external.ts
CHANGED
package/src/framer/frame.spec.ts
CHANGED
package/src/framer/frame.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
DataType,
|
|
12
|
+
MultiSeries,
|
|
12
13
|
Series,
|
|
14
|
+
Size,
|
|
15
|
+
type TelemValue,
|
|
13
16
|
TimeRange,
|
|
14
|
-
DataType,
|
|
15
17
|
TimeStamp,
|
|
16
|
-
type TelemValue,
|
|
17
|
-
MultiSeries,
|
|
18
18
|
} from "@synnaxlabs/x/telem";
|
|
19
19
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
20
20
|
import { unique } from "@synnaxlabs/x/unique";
|
|
@@ -60,7 +60,7 @@ export type CrudeFrame =
|
|
|
60
60
|
| Record<KeyOrName, Series[] | Series>;
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
* A frame is a collection of
|
|
63
|
+
* A frame is a collection of series mapped to a particular channel. Frames
|
|
64
64
|
* can be keyed by channel name or channel key, but not both.
|
|
65
65
|
*
|
|
66
66
|
* Frames have two important characteristics: alignment and orientation.
|
|
@@ -283,10 +283,10 @@ export class Frame {
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
/**
|
|
286
|
-
* Pushes a set of
|
|
286
|
+
* Pushes a set of series for the given channel onto the frame.
|
|
287
287
|
*
|
|
288
288
|
* @param key the channel key or name;
|
|
289
|
-
* @param v the
|
|
289
|
+
* @param v the series to push.
|
|
290
290
|
*/
|
|
291
291
|
push(key: KeyOrName, ...v: Series[]): void;
|
|
292
292
|
|
|
@@ -316,7 +316,7 @@ export class Frame {
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
/**
|
|
319
|
-
* @returns a shallow copy of this frame containing all
|
|
319
|
+
* @returns a shallow copy of this frame containing all series in the current frame and the
|
|
320
320
|
* provided frame.
|
|
321
321
|
*/
|
|
322
322
|
concat(frame: Frame): Frame {
|
|
@@ -338,7 +338,7 @@ export class Frame {
|
|
|
338
338
|
|
|
339
339
|
/**
|
|
340
340
|
* @returns a new frame containing the mapped output of the provided function.
|
|
341
|
-
* @param fn a function that takes a channel key and
|
|
341
|
+
* @param fn a function that takes a channel key and series and returns a
|
|
342
342
|
* boolean.
|
|
343
343
|
*/
|
|
344
344
|
map(fn: (k: KeyOrName, arr: Series, i: number) => [KeyOrName, Series]): Frame {
|
|
@@ -348,9 +348,9 @@ export class Frame {
|
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
/**
|
|
351
|
-
* Iterates over all
|
|
351
|
+
* Iterates over all series in the current frame.
|
|
352
352
|
*
|
|
353
|
-
* @param fn a function that takes a channel key and
|
|
353
|
+
* @param fn a function that takes a channel key and series.
|
|
354
354
|
*/
|
|
355
355
|
forEach(fn: (k: KeyOrName, arr: Series, i: number) => void): void {
|
|
356
356
|
this.columns.forEach((k, i) => {
|
|
@@ -372,9 +372,9 @@ export class Frame {
|
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
/**
|
|
375
|
-
* @returns a new frame containing all
|
|
375
|
+
* @returns a new frame containing all series in the current frame that pass
|
|
376
376
|
* the provided filter function.
|
|
377
|
-
* @param fn a function that takes a channel key and
|
|
377
|
+
* @param fn a function that takes a channel key and series and returns a boolean.
|
|
378
378
|
*/
|
|
379
379
|
filter(fn: (k: KeyOrName, arr: Series, i: number) => boolean): Frame {
|
|
380
380
|
const frame = new Frame();
|
package/src/framer/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { DataType, Rate, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
|
|
11
|
-
import { describe, test
|
|
11
|
+
import { describe, expect,test } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { type channel } from "@/channel";
|
|
14
14
|
import { newClient } from "@/setupspecs";
|
package/src/framer/iterator.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
import { errorZ, type Stream, type StreamClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import {
|
|
12
|
+
type CrudeTimeRange,
|
|
12
13
|
type CrudeTimeSpan,
|
|
13
14
|
type CrudeTimeStamp,
|
|
14
15
|
TimeRange,
|
|
15
16
|
TimeSpan,
|
|
16
17
|
TimeStamp,
|
|
17
|
-
type CrudeTimeRange,
|
|
18
18
|
} from "@synnaxlabs/x/telem";
|
|
19
19
|
import { z } from "zod";
|
|
20
20
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -7,11 +7,9 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { type Stream
|
|
10
|
+
import { EOF, type Stream } from "@synnaxlabs/freighter";
|
|
11
11
|
import { type z } from "zod";
|
|
12
12
|
|
|
13
|
-
import { UnexpectedError } from "@/errors";
|
|
14
|
-
|
|
15
13
|
export class StreamProxy<RQ extends z.ZodTypeAny, RS extends z.ZodTypeAny> {
|
|
16
14
|
readonly name: string;
|
|
17
15
|
private readonly stream: Stream<RQ, RS>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { describe, test, expect, it } from "vitest";
|
|
11
10
|
import { DataType, Rate, TimeStamp } from "@synnaxlabs/x/telem";
|
|
11
|
+
import { describe, expect, it,test } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { type channel } from "@/channel";
|
|
14
14
|
import { newClient } from "@/setupspecs";
|
package/src/framer/streamer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -7,9 +7,9 @@
|
|
|
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 { errorZ, type Stream, type StreamClient } from "@synnaxlabs/freighter";
|
|
10
|
+
import { EOF, errorZ, type Stream, type StreamClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import { observe } from "@synnaxlabs/x";
|
|
12
|
-
import {
|
|
12
|
+
import { type CrudeTimeStamp, TimeStamp } from "@synnaxlabs/x/telem";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
15
|
import { type Key, type Params } from "@/channel/payload";
|
|
@@ -67,8 +67,9 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
|
|
|
67
67
|
try {
|
|
68
68
|
const frame = await this.read();
|
|
69
69
|
return { done: false, value: frame };
|
|
70
|
-
} catch (
|
|
71
|
-
return { done: true, value: undefined };
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof EOF) return { done: true, value: undefined };
|
|
72
|
+
throw err;
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -11,6 +11,7 @@ import { DataType, Rate, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x/te
|
|
|
11
11
|
import { describe, expect, test } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { type channel } from "@/channel";
|
|
14
|
+
import { UnauthorizedError } from "@/errors";
|
|
14
15
|
import { ALWAYS_INDEX_PERSIST_ON_AUTO_COMMIT, WriterMode } from "@/framer/writer";
|
|
15
16
|
import { newClient } from "@/setupspecs";
|
|
16
17
|
import { randomSeries } from "@/util/telem";
|
|
@@ -113,6 +114,22 @@ describe("Writer", () => {
|
|
|
113
114
|
}
|
|
114
115
|
expect(true).toBeTruthy();
|
|
115
116
|
});
|
|
117
|
+
test("write with errOnUnauthorized", async () => {
|
|
118
|
+
const ch = await newChannel();
|
|
119
|
+
const w1 = await client.openWriter({
|
|
120
|
+
start: 0,
|
|
121
|
+
channels: ch.key,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
await expect(
|
|
125
|
+
client.openWriter({
|
|
126
|
+
start: 0,
|
|
127
|
+
channels: ch.key,
|
|
128
|
+
errOnUnauthorized: true,
|
|
129
|
+
}),
|
|
130
|
+
).rejects.toThrow(UnauthorizedError);
|
|
131
|
+
await w1.close();
|
|
132
|
+
});
|
|
116
133
|
});
|
|
117
134
|
describe("Client", () => {
|
|
118
135
|
test("Client - basic write", async () => {
|
package/src/framer/writer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2024 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -7,32 +7,27 @@
|
|
|
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
|
-
/* eslint-disable @typescript-eslint/no-throw-literal */
|
|
11
10
|
import type { Stream, StreamClient } from "@synnaxlabs/freighter";
|
|
12
11
|
import { decodeError, errorZ } from "@synnaxlabs/freighter";
|
|
12
|
+
import { control } from "@synnaxlabs/x";
|
|
13
13
|
import {
|
|
14
|
-
TimeStamp,
|
|
15
|
-
type CrudeTimeStamp,
|
|
16
14
|
type CrudeSeries,
|
|
15
|
+
type CrudeTimeStamp,
|
|
17
16
|
TimeSpan,
|
|
17
|
+
TimeStamp,
|
|
18
18
|
} from "@synnaxlabs/x/telem";
|
|
19
19
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
|
|
22
22
|
import {
|
|
23
|
-
type KeysOrNames,
|
|
24
23
|
type Key,
|
|
25
24
|
type KeyOrName,
|
|
25
|
+
type KeysOrNames,
|
|
26
26
|
type Params,
|
|
27
27
|
} from "@/channel/payload";
|
|
28
28
|
import { type Retriever } from "@/channel/retriever";
|
|
29
|
-
import { Authority } from "@/control/authority";
|
|
30
|
-
import {
|
|
31
|
-
subjectZ as controlSubjectZ,
|
|
32
|
-
type Subject as ControlSubject,
|
|
33
|
-
} from "@/control/state";
|
|
34
29
|
import { WriteFrameAdapter } from "@/framer/adapter";
|
|
35
|
-
import {
|
|
30
|
+
import { type CrudeFrame, frameZ } from "@/framer/frame";
|
|
36
31
|
import { StreamProxy } from "@/framer/streamProxy";
|
|
37
32
|
|
|
38
33
|
enum Command {
|
|
@@ -41,7 +36,6 @@ enum Command {
|
|
|
41
36
|
Commit = 2,
|
|
42
37
|
Error = 3,
|
|
43
38
|
SetAuthority = 4,
|
|
44
|
-
SetMode = 5,
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
export enum WriterMode {
|
|
@@ -54,10 +48,11 @@ export const ALWAYS_INDEX_PERSIST_ON_AUTO_COMMIT: TimeSpan = new TimeSpan(-1);
|
|
|
54
48
|
|
|
55
49
|
const netConfigZ = z.object({
|
|
56
50
|
start: TimeStamp.z.optional(),
|
|
57
|
-
controlSubject:
|
|
51
|
+
controlSubject: control.subjectZ.optional(),
|
|
58
52
|
keys: z.number().array().optional(),
|
|
59
|
-
authorities: Authority.z.array().optional(),
|
|
53
|
+
authorities: control.Authority.z.array().optional(),
|
|
60
54
|
mode: z.nativeEnum(WriterMode).optional(),
|
|
55
|
+
errOnUnauthorized: z.boolean().optional(),
|
|
61
56
|
enableAutoCommit: z.boolean().optional(),
|
|
62
57
|
autoIndexPersistInterval: TimeSpan.z.optional(),
|
|
63
58
|
});
|
|
@@ -84,14 +79,17 @@ export interface WriterConfig {
|
|
|
84
79
|
// start sets the starting timestamp for the first sample in the writer.
|
|
85
80
|
start?: CrudeTimeStamp;
|
|
86
81
|
// controlSubject sets the control subject of the writer.
|
|
87
|
-
controlSubject?:
|
|
82
|
+
controlSubject?: control.Subject;
|
|
88
83
|
// authorities set the control authority to set for each channel on the writer.
|
|
89
84
|
// Defaults to absolute authority. If not working with concurrent control,
|
|
90
85
|
// it's best to leave this as the default.
|
|
91
|
-
authorities?: Authority | Authority[];
|
|
86
|
+
authorities?: control.Authority | control.Authority[];
|
|
92
87
|
// mode sets the persistence and streaming mode of the writer. The default
|
|
93
88
|
// mode is WriterModePersistStream.
|
|
94
89
|
mode?: WriterMode;
|
|
90
|
+
// errOnUnauthorized sets whether the writer raises an error when it attempts to write
|
|
91
|
+
// to a channel without permission.
|
|
92
|
+
errOnUnauthorized?: boolean,
|
|
95
93
|
// enableAutoCommit determines whether the writer will automatically commit.
|
|
96
94
|
// If enableAutoCommit is true, then the writer will commit after each write, and
|
|
97
95
|
// will flush that commit to index after the specified autoIndexPersistInterval.
|
|
@@ -159,9 +157,10 @@ export class Writer {
|
|
|
159
157
|
{
|
|
160
158
|
channels,
|
|
161
159
|
start = TimeStamp.now(),
|
|
162
|
-
authorities = Authority.Absolute,
|
|
160
|
+
authorities = control.Authority.Absolute,
|
|
163
161
|
controlSubject: subject,
|
|
164
162
|
mode = WriterMode.PersistStream,
|
|
163
|
+
errOnUnauthorized = false,
|
|
165
164
|
enableAutoCommit = false,
|
|
166
165
|
autoIndexPersistInterval = TimeSpan.SECOND,
|
|
167
166
|
}: WriterConfig,
|
|
@@ -177,6 +176,7 @@ export class Writer {
|
|
|
177
176
|
controlSubject: subject,
|
|
178
177
|
authorities: toArray(authorities),
|
|
179
178
|
mode,
|
|
179
|
+
errOnUnauthorized,
|
|
180
180
|
enableAutoCommit,
|
|
181
181
|
autoIndexPersistInterval,
|
|
182
182
|
},
|
|
@@ -219,7 +219,7 @@ export class Writer {
|
|
|
219
219
|
return true;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
async setAuthority(value: Record<Key, Authority>): Promise<boolean> {
|
|
222
|
+
async setAuthority(value: Record<Key, control.Authority>): Promise<boolean> {
|
|
223
223
|
const res = await this.execute({
|
|
224
224
|
command: Command.SetAuthority,
|
|
225
225
|
config: {
|
|
@@ -230,14 +230,6 @@ export class Writer {
|
|
|
230
230
|
return res.ack;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
async setMode(mode: WriterMode): Promise<boolean> {
|
|
234
|
-
const res = await this.execute({
|
|
235
|
-
command: Command.SetMode,
|
|
236
|
-
config: { mode },
|
|
237
|
-
});
|
|
238
|
-
return res.ack;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
233
|
/**
|
|
242
234
|
* Commits the written frames to the database. Commit is synchronous, meaning that it
|
|
243
235
|
* will not return until all frames have been commited to the database.
|
|
@@ -272,7 +264,7 @@ export class Writer {
|
|
|
272
264
|
}
|
|
273
265
|
|
|
274
266
|
async execute(req: Request): Promise<Response> {
|
|
275
|
-
// @ts-expect-error
|
|
267
|
+
// @ts-expect-error - frame payload adjustments
|
|
276
268
|
this.stream.send(req);
|
|
277
269
|
while (true) {
|
|
278
270
|
const res = await this.stream.receive();
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { type UnaryClient
|
|
11
|
-
import { type UnknownRecord
|
|
10
|
+
import { sendRequired,type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { toArray,type UnknownRecord } from "@synnaxlabs/x";
|
|
12
12
|
import { binary } from "@synnaxlabs/x/binary";
|
|
13
13
|
import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
14
14
|
import { z } from "zod";
|
package/src/hardware/external.ts
CHANGED
package/src/hardware/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ describe("Rack", () => {
|
|
|
22
22
|
expect(r.key).toBeGreaterThan(0n);
|
|
23
23
|
});
|
|
24
24
|
it("should return an error if the rack doesn't have a name", async () => {
|
|
25
|
-
// @ts-expect-error
|
|
25
|
+
// @ts-expect-error - Testing for error
|
|
26
26
|
await expect(client.hardware.racks.create({})).rejects.toThrow(ZodError);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { type UnaryClient
|
|
10
|
+
import { sendRequired,type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import { binary, type observe } from "@synnaxlabs/x";
|
|
12
12
|
import { type UnknownRecord } from "@synnaxlabs/x/record";
|
|
13
13
|
import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
14
|
-
import {
|
|
14
|
+
import { type CrudeTimeSpan,TimeSpan } from "@synnaxlabs/x/telem";
|
|
15
15
|
import { toArray } from "@synnaxlabs/x/toArray";
|
|
16
16
|
import { nanoid } from "nanoid";
|
|
17
17
|
import { z } from "zod";
|
|
@@ -316,7 +316,7 @@ export class Client implements AsyncTermSearcher<string, TaskKey, Payload> {
|
|
|
316
316
|
{ number: "rack", string: "keys" },
|
|
317
317
|
{ convertNumericStrings: false },
|
|
318
318
|
);
|
|
319
|
-
|
|
319
|
+
const req: RetrieveRequest = { ...options };
|
|
320
320
|
if (variant === "rack") req.rack = rack as number;
|
|
321
321
|
else req.keys = normalized as string[];
|
|
322
322
|
const tasks = await this.execRetrieve(req);
|
|
@@ -7,11 +7,11 @@
|
|
|
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 { nanoid } from "nanoid";
|
|
10
11
|
import { describe, expect, it } from "vitest";
|
|
11
12
|
|
|
12
|
-
import { newClient } from "@/setupspecs";
|
|
13
13
|
import { task } from "@/hardware/task";
|
|
14
|
-
import {
|
|
14
|
+
import { newClient } from "@/setupspecs";
|
|
15
15
|
|
|
16
16
|
const client = newClient();
|
|
17
17
|
|