@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
package/src/channel/payload.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.
|
|
@@ -27,6 +27,7 @@ export const payload = z.object({
|
|
|
27
27
|
leaseholder: z.number(),
|
|
28
28
|
index: z.number(),
|
|
29
29
|
isIndex: z.boolean(),
|
|
30
|
+
internal: z.boolean(),
|
|
30
31
|
alias: z.string().optional(),
|
|
31
32
|
});
|
|
32
33
|
|
|
@@ -38,6 +39,7 @@ export const newPayload = payload.extend({
|
|
|
38
39
|
index: z.number().optional(),
|
|
39
40
|
rate: Rate.z.optional().default(0),
|
|
40
41
|
isIndex: z.boolean().optional(),
|
|
42
|
+
internal: z.boolean().optional().default(false),
|
|
41
43
|
virtual: z.boolean().optional().default(false),
|
|
42
44
|
});
|
|
43
45
|
|
package/src/channel/retriever.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.
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
payload,
|
|
23
23
|
} from "@/channel/payload";
|
|
24
24
|
import { QueryError } from "@/errors";
|
|
25
|
-
import { type ParamAnalysisResult
|
|
25
|
+
import { analyzeParams, type ParamAnalysisResult } from "@/util/retrieve";
|
|
26
26
|
import { nullableArrayZ } from "@/util/zod";
|
|
27
27
|
|
|
28
28
|
const reqZ = z.object({
|
|
@@ -76,7 +76,9 @@ export class ClusterRetriever implements Retriever {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async retrieve(channels: Params, options?: RetrieveOptions): Promise<Payload[]> {
|
|
79
|
-
|
|
79
|
+
const res = analyzeChannelParams(channels);
|
|
80
|
+
const { variant } = res;
|
|
81
|
+
let { normalized } = res;
|
|
80
82
|
if (variant === "keys" && (normalized as Key[]).indexOf(0) !== -1)
|
|
81
83
|
normalized = (normalized as Key[]).filter((k) => k !== 0);
|
|
82
84
|
if (normalized.length === 0) return [];
|
|
@@ -185,7 +187,7 @@ export class DebouncedBatchRetriever implements Retriever {
|
|
|
185
187
|
const { normalized, variant } = analyzeChannelParams(channels);
|
|
186
188
|
// Bypass on name fetches for now.
|
|
187
189
|
if (variant === "names") return await this.wrapped.retrieve(normalized);
|
|
188
|
-
|
|
190
|
+
|
|
189
191
|
const a = new Promise<Payload[]>((resolve, reject) => {
|
|
190
192
|
void this.mu.runExclusive(() => {
|
|
191
193
|
this.requests.set(normalized as Key[], { resolve, reject });
|
package/src/channel/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.
|
|
@@ -11,11 +11,12 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
|
+
Key,
|
|
15
|
+
keyZ,
|
|
16
|
+
type NewPayload,
|
|
17
|
+
newPayload,
|
|
14
18
|
type Payload,
|
|
15
19
|
payload,
|
|
16
|
-
newPayload,
|
|
17
|
-
type NewPayload,
|
|
18
|
-
keyZ,
|
|
19
20
|
} from "@/channel/payload";
|
|
20
21
|
|
|
21
22
|
const createReqZ = z.object({ channels: newPayload.array() });
|
|
@@ -27,10 +28,18 @@ const deleteReqZ = z.object({
|
|
|
27
28
|
});
|
|
28
29
|
const deleteResZ = z.object({});
|
|
29
30
|
|
|
31
|
+
const renameReqZ = z.object({
|
|
32
|
+
keys: keyZ.array(),
|
|
33
|
+
names: z.string().array(),
|
|
34
|
+
});
|
|
35
|
+
const renameResZ = z.object({});
|
|
36
|
+
|
|
30
37
|
const CREATE_ENDPOINT = "/channel/create";
|
|
31
38
|
const DELETE_ENDPOINT = "/channel/delete";
|
|
39
|
+
const RENAME_ENDPOINT = "/channel/rename";
|
|
32
40
|
|
|
33
41
|
export type DeleteProps = z.input<typeof deleteReqZ>;
|
|
42
|
+
export type RenameProps = z.input<typeof renameReqZ>;
|
|
34
43
|
|
|
35
44
|
export class Writer {
|
|
36
45
|
private readonly client: UnaryClient;
|
|
@@ -60,4 +69,14 @@ export class Writer {
|
|
|
60
69
|
deleteResZ,
|
|
61
70
|
);
|
|
62
71
|
}
|
|
72
|
+
|
|
73
|
+
async rename(keys: Key[], names: string[]): Promise<void> {
|
|
74
|
+
await sendRequired<typeof renameReqZ, typeof renameResZ>(
|
|
75
|
+
this.client,
|
|
76
|
+
RENAME_ENDPOINT,
|
|
77
|
+
{ keys, names },
|
|
78
|
+
renameReqZ,
|
|
79
|
+
renameResZ,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
63
82
|
}
|
package/src/client.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.
|
|
@@ -14,6 +14,7 @@ import { z } from "zod";
|
|
|
14
14
|
import { auth } from "@/auth";
|
|
15
15
|
import { channel } from "@/channel";
|
|
16
16
|
import { connection } from "@/connection";
|
|
17
|
+
import { control } from "@/control";
|
|
17
18
|
import { errorsMiddleware } from "@/errors";
|
|
18
19
|
import { framer } from "@/framer";
|
|
19
20
|
import { hardware } from "@/hardware";
|
|
@@ -59,7 +60,6 @@ export type ParsedSynnaxProps = z.output<typeof synnaxPropsZ>;
|
|
|
59
60
|
* @property connectivity - Client for retrieving connectivity information.
|
|
60
61
|
* @property ontology - Client for querying the cluster's ontology.
|
|
61
62
|
*/
|
|
62
|
-
// eslint-disable-next-line import/no-default-export
|
|
63
63
|
export default class Synnax extends framer.Client {
|
|
64
64
|
readonly createdAt: TimeStamp;
|
|
65
65
|
readonly props: ParsedSynnaxProps;
|
|
@@ -71,6 +71,7 @@ export default class Synnax extends framer.Client {
|
|
|
71
71
|
readonly workspaces: workspace.Client;
|
|
72
72
|
readonly labels: label.Client;
|
|
73
73
|
readonly hardware: hardware.Client;
|
|
74
|
+
readonly control: control.Client;
|
|
74
75
|
static readonly connectivity = connection.Checker;
|
|
75
76
|
private readonly transport: Transport;
|
|
76
77
|
|
|
@@ -106,7 +107,7 @@ export default class Synnax extends framer.Client {
|
|
|
106
107
|
new channel.ClusterRetriever(transport.unary),
|
|
107
108
|
);
|
|
108
109
|
const chCreator = new channel.Writer(transport.unary);
|
|
109
|
-
super(transport.stream, chRetriever);
|
|
110
|
+
super(transport.stream, transport.unary, chRetriever);
|
|
110
111
|
this.createdAt = TimeStamp.now();
|
|
111
112
|
this.props = props;
|
|
112
113
|
this.auth = auth_;
|
|
@@ -117,6 +118,7 @@ export default class Synnax extends framer.Client {
|
|
|
117
118
|
connectivityPollFrequency,
|
|
118
119
|
props.name,
|
|
119
120
|
);
|
|
121
|
+
this.control = new control.Client(this);
|
|
120
122
|
this.ontology = new ontology.Client(transport.unary, this);
|
|
121
123
|
const rangeWriter = new ranger.Writer(this.transport.unary);
|
|
122
124
|
this.labels = new label.Client(this.transport.unary, this);
|
package/src/connection/index.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StateTracker } from "@/control/state";
|
|
2
|
+
import { framer } from "@/framer";
|
|
3
|
+
|
|
4
|
+
const CONTROL_STATE_KEY = "sy_node_1_control";
|
|
5
|
+
|
|
6
|
+
export class Client {
|
|
7
|
+
private readonly framer: framer.Client;
|
|
8
|
+
|
|
9
|
+
constructor(framer: framer.Client) {
|
|
10
|
+
this.framer = framer;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async openStateTracker(): Promise<StateTracker> {
|
|
14
|
+
const stream = await this.framer.openStreamer(CONTROL_STATE_KEY);
|
|
15
|
+
return new StateTracker(stream);
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/control/external.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,5 +7,5 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
export * from "@/control/
|
|
10
|
+
export * from "@/control/client";
|
|
11
11
|
export * from "@/control/state";
|
package/src/control/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.
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, expect, it } from "vitest";
|
|
11
11
|
|
|
12
|
-
import { control } from "@/control";
|
|
13
12
|
import { newClient } from "@/setupspecs";
|
|
14
13
|
|
|
15
14
|
const client = newClient();
|
|
16
15
|
|
|
17
16
|
describe("state", () => {
|
|
18
17
|
it("should receive the initial control state from the cluster", async () => {
|
|
19
|
-
const s = await control.
|
|
18
|
+
const s = await client.control.openStateTracker();
|
|
20
19
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
21
20
|
expect(s.states.size).toBeGreaterThan(0);
|
|
22
21
|
await s.close();
|
package/src/control/state.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,65 +7,21 @@
|
|
|
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 { control } from "@synnaxlabs/x";
|
|
10
11
|
import { binary } from "@synnaxlabs/x/binary";
|
|
11
|
-
import { type Destructor } from "@synnaxlabs/x/destructor";
|
|
12
12
|
import { observe } from "@synnaxlabs/x/observe";
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
15
|
import { type Key as ChannelKey } from "@/channel/payload";
|
|
16
|
-
import {
|
|
17
|
-
import { type Client as FrameClient } from "@/framer/client";
|
|
16
|
+
import { framer } from "@/framer";
|
|
18
17
|
import { type Streamer as FrameStreamer } from "@/framer/streamer";
|
|
19
18
|
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export
|
|
26
|
-
name: string;
|
|
27
|
-
key: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const stateZ = z.object({
|
|
31
|
-
subject: subjectZ,
|
|
32
|
-
resource: z.number(),
|
|
33
|
-
authority: Authority.z,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export interface State {
|
|
37
|
-
subject: Subject;
|
|
38
|
-
resource: ChannelKey;
|
|
39
|
-
authority: Authority;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const filterTransfersByChannelKey =
|
|
43
|
-
(...resources: ChannelKey[]) =>
|
|
44
|
-
(transfers: Transfer[]): Transfer[] =>
|
|
45
|
-
transfers.filter((t) => {
|
|
46
|
-
let ok = false;
|
|
47
|
-
if (t.to != null) ok = resources.includes(t.to.resource);
|
|
48
|
-
if (t.from != null && !ok) ok = resources.includes(t.from.resource);
|
|
49
|
-
return ok;
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
interface Release {
|
|
53
|
-
from: State;
|
|
54
|
-
to?: null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
interface Acquire {
|
|
58
|
-
from?: null;
|
|
59
|
-
to: State;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export type Transfer =
|
|
63
|
-
| {
|
|
64
|
-
from: State;
|
|
65
|
-
to: State;
|
|
66
|
-
}
|
|
67
|
-
| Release
|
|
68
|
-
| Acquire;
|
|
19
|
+
export type Authority = control.Authority;
|
|
20
|
+
export const Authority = control.Authority;
|
|
21
|
+
export type Transfer = control.Transfer<ChannelKey>;
|
|
22
|
+
export type State = control.State<ChannelKey>;
|
|
23
|
+
export type Subject = control.Subject;
|
|
24
|
+
export const stateZ = control.stateZ(z.number());
|
|
69
25
|
|
|
70
26
|
export const transferString = (t: Transfer): string => {
|
|
71
27
|
if (t.to == null) return `${t.from?.resource} - ${t.from?.subject.name} -> released`;
|
|
@@ -79,22 +35,24 @@ export const transferString = (t: Transfer): string => {
|
|
|
79
35
|
};
|
|
80
36
|
|
|
81
37
|
interface Update {
|
|
82
|
-
transfers: Transfer[];
|
|
38
|
+
transfers: control.Transfer<ChannelKey>[];
|
|
83
39
|
}
|
|
84
40
|
|
|
85
|
-
export class StateTracker
|
|
41
|
+
export class StateTracker
|
|
42
|
+
extends framer.ObservableStreamer<Transfer[]>
|
|
43
|
+
implements observe.ObservableAsyncCloseable<Transfer[]>
|
|
44
|
+
{
|
|
86
45
|
readonly states: Map<ChannelKey, State>;
|
|
87
|
-
private readonly streamer: FrameStreamer;
|
|
88
46
|
private readonly ecd: binary.EncoderDecoder;
|
|
89
|
-
private readonly observer: observe.Observer<Transfer[]>;
|
|
90
|
-
private readonly closePromise: Promise<void>;
|
|
91
47
|
|
|
92
|
-
|
|
48
|
+
constructor(streamer: FrameStreamer) {
|
|
49
|
+
super(streamer, (frame) => {
|
|
50
|
+
const update: Update = this.ecd.decode(frame.series[0].buffer);
|
|
51
|
+
this.merge(update);
|
|
52
|
+
return [update.transfers, true];
|
|
53
|
+
});
|
|
93
54
|
this.states = new Map();
|
|
94
55
|
this.ecd = new binary.JSONEncoderDecoder();
|
|
95
|
-
this.observer = new observe.Observer<Transfer[]>();
|
|
96
|
-
this.streamer = streamer;
|
|
97
|
-
this.closePromise = this.stream();
|
|
98
56
|
}
|
|
99
57
|
|
|
100
58
|
subjects(): Subject[] {
|
|
@@ -103,28 +61,6 @@ export class StateTracker implements observe.Observable<Transfer[]> {
|
|
|
103
61
|
return Array.from(subjects.values());
|
|
104
62
|
}
|
|
105
63
|
|
|
106
|
-
onChange(handler: observe.Handler<Transfer[]>): Destructor {
|
|
107
|
-
return this.observer.onChange(handler);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async close(): Promise<void> {
|
|
111
|
-
this.streamer.close();
|
|
112
|
-
await this.closePromise;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
static async open(client: FrameClient): Promise<StateTracker> {
|
|
116
|
-
const streamer = await client.openStreamer("sy_node_1_control");
|
|
117
|
-
return new StateTracker(streamer);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private async stream(): Promise<void> {
|
|
121
|
-
for await (const frame of this.streamer) {
|
|
122
|
-
const update: Update = this.ecd.decode(frame.series[0].buffer);
|
|
123
|
-
this.merge(update);
|
|
124
|
-
this.observer.notify(update.transfers);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
64
|
private merge(update: Update): void {
|
|
129
65
|
update.transfers.forEach((t) => {
|
|
130
66
|
if (t.from == null && t.to == null) console.warn("Invalid transfer: ", t);
|
package/src/errors.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,10 +8,10 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
+
type ErrorPayload,
|
|
11
12
|
type Middleware,
|
|
12
13
|
registerError,
|
|
13
14
|
Unreachable,
|
|
14
|
-
type ErrorPayload,
|
|
15
15
|
} from "@synnaxlabs/freighter";
|
|
16
16
|
|
|
17
17
|
const _FREIGHTER_EXCEPTION_PREFIX = "sy.";
|
|
@@ -99,6 +99,14 @@ export class RouteError extends Error {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export class ControlError extends Error {
|
|
103
|
+
static readonly TYPE = _FREIGHTER_EXCEPTION_PREFIX + "control";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export class UnauthorizedError extends ControlError {
|
|
107
|
+
static readonly TYPE = ControlError.TYPE + ".unauthorized";
|
|
108
|
+
}
|
|
109
|
+
|
|
102
110
|
/**
|
|
103
111
|
* Raised when time-series data is not contiguous.
|
|
104
112
|
*/
|
|
@@ -109,9 +117,7 @@ const decode = (payload: ErrorPayload): Error | null => {
|
|
|
109
117
|
if (payload.type.startsWith(ValidationError.TYPE)) {
|
|
110
118
|
if (payload.type === FieldError.TYPE) {
|
|
111
119
|
const values = payload.data.split(": ");
|
|
112
|
-
if (values.length < 2)
|
|
113
|
-
return new ValidationError(payload.data);
|
|
114
|
-
}
|
|
120
|
+
if (values.length < 2) return new ValidationError(payload.data);
|
|
115
121
|
return new FieldError(values[0], values[1]);
|
|
116
122
|
}
|
|
117
123
|
return new ValidationError(payload.data);
|
|
@@ -135,10 +141,15 @@ const decode = (payload: ErrorPayload): Error | null => {
|
|
|
135
141
|
return new QueryError(payload.data);
|
|
136
142
|
}
|
|
137
143
|
|
|
138
|
-
if (payload.type.startsWith(
|
|
139
|
-
|
|
144
|
+
if (payload.type.startsWith(ControlError.TYPE)) {
|
|
145
|
+
if (payload.type.startsWith(UnauthorizedError.TYPE))
|
|
146
|
+
return new UnauthorizedError(payload.data);
|
|
147
|
+
return new ControlError(payload.data);
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
if (payload.type.startsWith(RouteError.TYPE))
|
|
151
|
+
return new RouteError(payload.data, payload.data);
|
|
152
|
+
|
|
142
153
|
return new UnexpectedError(payload.data);
|
|
143
154
|
};
|
|
144
155
|
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
import { DataType, Series, TimeStamp } from "@synnaxlabs/x/telem";
|
|
2
11
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
3
12
|
|
package/src/framer/adapter.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.
|
|
@@ -11,14 +11,14 @@ import { type CrudeSeries, Series } from "@synnaxlabs/x/telem";
|
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
type Key,
|
|
14
|
+
type KeyOrName,
|
|
14
15
|
type Name,
|
|
15
16
|
type Params,
|
|
16
|
-
type KeyOrName,
|
|
17
17
|
type Payload,
|
|
18
18
|
} from "@/channel/payload";
|
|
19
19
|
import {
|
|
20
|
-
type Retriever,
|
|
21
20
|
analyzeChannelParams,
|
|
21
|
+
type Retriever,
|
|
22
22
|
retrieveRequired,
|
|
23
23
|
} from "@/channel/retriever";
|
|
24
24
|
import { ValidationError } from "@/errors";
|
package/src/framer/client.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,28 +7,35 @@
|
|
|
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 {
|
|
10
|
+
import {type StreamClient, UnaryClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import {
|
|
12
|
-
type CrudeTimeStamp,
|
|
13
12
|
type CrudeSeries,
|
|
14
13
|
type CrudeTimeRange,
|
|
14
|
+
type CrudeTimeStamp,
|
|
15
15
|
type MultiSeries,
|
|
16
|
-
|
|
16
|
+
TimeRange,
|
|
17
|
+
TimeSpan,
|
|
18
|
+
} from "@synnaxlabs/x";
|
|
17
19
|
|
|
18
|
-
import {
|
|
19
|
-
import { type Retriever
|
|
20
|
+
import { type Key, type KeyOrName, KeysOrNames, type Params} from "@/channel/payload";
|
|
21
|
+
import { analyzeChannelParams,type Retriever } from "@/channel/retriever";
|
|
20
22
|
import { Frame } from "@/framer/frame";
|
|
21
23
|
import { Iterator } from "@/framer/iterator";
|
|
22
24
|
import { Streamer, type StreamerConfig } from "@/framer/streamer";
|
|
23
|
-
import { Writer,
|
|
25
|
+
import { Writer, type WriterConfig,WriterMode } from "@/framer/writer";
|
|
26
|
+
import { Deleter } from "@/framer/deleter";
|
|
24
27
|
|
|
25
28
|
export class Client {
|
|
26
|
-
private readonly
|
|
29
|
+
private readonly streamClient: StreamClient;
|
|
30
|
+
// private readonly unaryClient: UnaryClient;
|
|
27
31
|
private readonly retriever: Retriever;
|
|
32
|
+
private readonly deleter: Deleter;
|
|
28
33
|
|
|
29
|
-
constructor(stream: StreamClient, retriever: Retriever) {
|
|
30
|
-
this.
|
|
34
|
+
constructor(stream: StreamClient, unary: UnaryClient, retriever: Retriever) {
|
|
35
|
+
this.streamClient = stream;
|
|
36
|
+
// this.unaryClient = unary;
|
|
31
37
|
this.retriever = retriever;
|
|
38
|
+
this.deleter = new Deleter(unary);
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
/**
|
|
@@ -39,7 +46,7 @@ export class Client {
|
|
|
39
46
|
* @returns a new {@link TypedIterator}.
|
|
40
47
|
*/
|
|
41
48
|
async openIterator(tr: CrudeTimeRange, channels: Params): Promise<Iterator> {
|
|
42
|
-
return await Iterator._open(tr, channels, this.retriever, this.
|
|
49
|
+
return await Iterator._open(tr, channels, this.retriever, this.streamClient);
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
/**
|
|
@@ -52,7 +59,7 @@ export class Client {
|
|
|
52
59
|
async openWriter(config: WriterConfig | Params): Promise<Writer> {
|
|
53
60
|
if (Array.isArray(config) || typeof config !== "object")
|
|
54
61
|
config = { channels: config as Params };
|
|
55
|
-
return await Writer._open(this.retriever, this.
|
|
62
|
+
return await Writer._open(this.retriever, this.streamClient, config);
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
/***
|
|
@@ -82,7 +89,7 @@ export class Client {
|
|
|
82
89
|
async openStreamer(config: StreamerConfig | Params): Promise<Streamer> {
|
|
83
90
|
if (Array.isArray(config) || typeof config !== "object")
|
|
84
91
|
config = { channels: config as Params };
|
|
85
|
-
return await Streamer._open(this.retriever, this.
|
|
92
|
+
return await Streamer._open(this.retriever, this.streamClient, config);
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
async write(
|
|
@@ -135,10 +142,12 @@ export class Client {
|
|
|
135
142
|
start,
|
|
136
143
|
channels: channels as Params,
|
|
137
144
|
mode: WriterMode.PersistOnly,
|
|
145
|
+
errOnUnauthorized: true,
|
|
146
|
+
enableAutoCommit: true,
|
|
147
|
+
autoIndexPersistInterval: TimeSpan.MAX,
|
|
138
148
|
});
|
|
139
149
|
try {
|
|
140
150
|
await w.write(channels as Params, data);
|
|
141
|
-
await w.commit();
|
|
142
151
|
} finally {
|
|
143
152
|
await w.close();
|
|
144
153
|
}
|
|
@@ -165,4 +174,15 @@ export class Client {
|
|
|
165
174
|
}
|
|
166
175
|
return frame;
|
|
167
176
|
}
|
|
177
|
+
|
|
178
|
+
async delete(
|
|
179
|
+
channels: Params,
|
|
180
|
+
timeRange : TimeRange,
|
|
181
|
+
): Promise<void> {
|
|
182
|
+
|
|
183
|
+
const { normalized, variant } = analyzeChannelParams(channels);
|
|
184
|
+
if (variant === "keys")
|
|
185
|
+
return await this.deleter.delete({ keys: normalized as Key[], bounds: timeRange });
|
|
186
|
+
return await this.deleter.delete({ names: normalized as string[], bounds: timeRange });
|
|
187
|
+
}
|
|
168
188
|
}
|