@synnaxlabs/client 0.2.1 → 0.13.6
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/.eslintrc.cjs +18 -0
- package/.pytest_cache/README.md +8 -0
- package/.turbo/turbo-build.log +16 -0
- package/LICENSE +4 -21
- package/{build/module/lib → dist/auth}/auth.d.ts +16 -19
- package/dist/auth/index.d.ts +1 -0
- package/dist/cdc/external.d.ts +1 -0
- package/dist/cdc/index.d.ts +1 -0
- package/dist/cdc/observable.d.ts +17 -0
- package/dist/channel/client.d.ts +58 -0
- package/dist/channel/creator.d.ts +8 -0
- package/dist/channel/external.d.ts +4 -0
- package/dist/channel/index.d.ts +1 -0
- package/dist/channel/payload.d.ts +63 -0
- package/dist/channel/retriever.d.ts +49 -0
- package/dist/client.cjs.js +23050 -0
- package/dist/client.cjs.js.map +1 -0
- package/dist/client.d.ts +73 -0
- package/dist/client.es.js +23050 -0
- package/dist/client.es.js.map +1 -0
- package/dist/connection/checker.d.ts +66 -0
- package/dist/connection/index.d.ts +1 -0
- package/dist/control/authority.d.ts +6 -0
- package/dist/control/external.d.ts +2 -0
- package/dist/control/index.d.ts +1 -0
- package/dist/control/state.d.ts +81 -0
- package/{build/main/lib → dist}/errors.d.ts +6 -3
- package/dist/framer/adapter.d.ts +21 -0
- package/dist/framer/client.d.ts +44 -0
- package/dist/framer/external.d.ts +5 -0
- package/dist/framer/frame.d.ts +251 -0
- package/dist/framer/index.d.ts +1 -0
- package/{build/module/lib/segment → dist/framer}/iterator.d.ts +32 -64
- package/dist/framer/streamProxy.d.ts +12 -0
- package/dist/framer/streamer.d.ts +17 -0
- package/dist/framer/writer.d.ts +257 -0
- package/dist/index.d.ts +16 -0
- package/dist/label/client.d.ts +25 -0
- package/dist/label/external.d.ts +4 -0
- package/dist/label/index.d.ts +1 -0
- package/dist/label/payload.d.ts +20 -0
- package/dist/label/retriever.d.ts +13 -0
- package/dist/label/writer.d.ts +26 -0
- package/dist/ontology/cdc.d.ts +25 -0
- package/dist/ontology/client.d.ts +25 -0
- package/dist/ontology/external.d.ts +3 -0
- package/dist/ontology/group/client.d.ts +11 -0
- package/dist/ontology/group/external.d.ts +2 -0
- package/dist/ontology/group/group.d.ts +7 -0
- package/dist/ontology/group/index.d.ts +1 -0
- package/dist/ontology/group/payload.d.ts +40 -0
- package/dist/ontology/group/writer.d.ts +13 -0
- package/dist/ontology/index.d.ts +1 -0
- package/dist/ontology/ontology.spec.d.ts +1 -0
- package/dist/ontology/payload.d.ts +235 -0
- package/dist/ontology/retriever.d.ts +12 -0
- package/dist/ontology/signals.d.ts +25 -0
- package/dist/ontology/writer.d.ts +9 -0
- package/dist/ranger/active.d.ts +9 -0
- package/dist/ranger/alias.d.ts +32 -0
- package/dist/ranger/client.d.ts +31 -0
- package/dist/ranger/external.d.ts +6 -0
- package/dist/ranger/index.d.ts +1 -0
- package/dist/ranger/kv.d.ts +50 -0
- package/dist/ranger/payload.d.ts +94 -0
- package/dist/ranger/range.d.ts +29 -0
- package/dist/ranger/ranger.spec.d.ts +1 -0
- package/dist/ranger/retriever.d.ts +10 -0
- package/dist/ranger/writer.d.ts +9 -0
- package/{build/main → dist}/setupspecs.d.ts +2 -2
- package/dist/signals/external.d.ts +1 -0
- package/dist/signals/index.d.ts +1 -0
- package/dist/signals/observable.d.ts +17 -0
- package/dist/transport.d.ts +10 -0
- package/dist/user/index.d.ts +1 -0
- package/{build/main/lib → dist}/user/payload.d.ts +3 -3
- package/dist/util/telem.d.ts +2 -0
- package/dist/workspace/client.d.ts +22 -0
- package/dist/workspace/external.d.ts +2 -0
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/lineplot/client.d.ts +15 -0
- package/dist/workspace/lineplot/external.d.ts +2 -0
- package/dist/workspace/lineplot/index.d.ts +1 -0
- package/dist/workspace/lineplot/linePlot.spec.d.ts +1 -0
- package/dist/workspace/lineplot/payload.d.ts +31 -0
- package/dist/workspace/lineplot/retriever.d.ts +9 -0
- package/dist/workspace/lineplot/writer.d.ts +39 -0
- package/dist/workspace/payload.d.ts +31 -0
- package/dist/workspace/pid/client.d.ts +16 -0
- package/dist/workspace/pid/external.d.ts +2 -0
- package/dist/workspace/pid/index.d.ts +1 -0
- package/dist/workspace/pid/payload.d.ts +37 -0
- package/dist/workspace/pid/pid.spec.d.ts +1 -0
- package/dist/workspace/pid/retriever.d.ts +9 -0
- package/dist/workspace/pid/writer.d.ts +46 -0
- package/dist/workspace/retriever.d.ts +12 -0
- package/dist/workspace/workspace.spec.d.ts +1 -0
- package/dist/workspace/writer.d.ts +55 -0
- package/package.json +27 -98
- package/src/auth/auth.spec.ts +46 -0
- package/src/auth/auth.ts +83 -0
- package/src/auth/index.ts +10 -0
- package/src/channel/channel.spec.ts +82 -0
- package/src/channel/client.ts +209 -0
- package/src/channel/creator.ts +43 -0
- package/src/channel/external.ts +13 -0
- package/src/channel/index.ts +10 -0
- package/src/channel/payload.ts +52 -0
- package/src/channel/retriever.ts +160 -0
- package/src/client.ts +116 -0
- package/src/connection/checker.ts +104 -0
- package/src/connection/connection.spec.ts +35 -0
- package/src/connection/index.ts +10 -0
- package/src/control/authority.ts +26 -0
- package/src/control/external.ts +11 -0
- package/src/control/index.ts +10 -0
- package/src/control/state.spec.ts +24 -0
- package/src/control/state.ts +133 -0
- package/src/errors.ts +163 -0
- package/src/framer/adapter.ts +116 -0
- package/src/framer/client.ts +116 -0
- package/src/framer/external.ts +14 -0
- package/src/framer/frame.spec.ts +317 -0
- package/src/framer/frame.ts +412 -0
- package/src/framer/index.ts +10 -0
- package/src/framer/iterator.spec.ts +62 -0
- package/src/framer/iterator.ts +240 -0
- package/src/framer/streamProxy.ts +59 -0
- package/src/framer/streamer.spec.ts +42 -0
- package/src/framer/streamer.ts +86 -0
- package/src/framer/writer.spec.ts +52 -0
- package/src/framer/writer.ts +236 -0
- package/src/index.ts +53 -0
- package/src/label/client.ts +103 -0
- package/src/label/external.ts +13 -0
- package/src/label/index.ts +10 -0
- package/src/label/label.spec.ts +51 -0
- package/src/label/payload.ts +29 -0
- package/src/label/retriever.ts +65 -0
- package/src/label/writer.ts +90 -0
- package/src/ontology/client.ts +104 -0
- package/src/ontology/external.ts +12 -0
- package/src/ontology/group/client.ts +40 -0
- package/src/ontology/group/external.ts +11 -0
- package/src/ontology/group/group.spec.ts +46 -0
- package/src/ontology/group/group.ts +27 -0
- package/src/ontology/group/index.ts +10 -0
- package/src/ontology/group/payload.ts +65 -0
- package/src/ontology/group/writer.ts +48 -0
- package/src/ontology/index.ts +10 -0
- package/src/ontology/ontology.spec.ts +114 -0
- package/src/ontology/payload.ts +118 -0
- package/src/ontology/retriever.ts +91 -0
- package/src/ontology/signals.ts +135 -0
- package/src/ontology/writer.ts +49 -0
- package/src/ranger/active.ts +56 -0
- package/src/ranger/alias.ts +183 -0
- package/src/ranger/client.ts +129 -0
- package/src/ranger/external.ts +15 -0
- package/src/ranger/index.ts +10 -0
- package/src/ranger/kv.ts +91 -0
- package/src/ranger/payload.ts +70 -0
- package/src/ranger/range.ts +95 -0
- package/src/ranger/ranger.spec.ts +201 -0
- package/src/ranger/retriever.ts +50 -0
- package/src/ranger/writer.ts +80 -0
- package/src/setupspecs.ts +25 -0
- package/src/signals/external.ts +10 -0
- package/src/signals/index.ts +10 -0
- package/src/signals/observable.ts +80 -0
- package/src/transport.ts +39 -0
- package/src/user/index.ts +10 -0
- package/src/user/payload.ts +17 -0
- package/src/util/telem.ts +19 -0
- package/src/vite-env.d.ts +11 -0
- package/src/workspace/client.ts +75 -0
- package/src/workspace/external.ts +11 -0
- package/src/workspace/index.ts +10 -0
- package/src/workspace/lineplot/client.ts +51 -0
- package/src/workspace/lineplot/external.ts +11 -0
- package/src/workspace/lineplot/index.ts +10 -0
- package/src/workspace/lineplot/linePlot.spec.ts +78 -0
- package/src/workspace/lineplot/payload.ts +29 -0
- package/src/workspace/lineplot/retriever.ts +49 -0
- package/src/workspace/lineplot/writer.ts +109 -0
- package/src/workspace/payload.ts +29 -0
- package/src/workspace/pid/client.ts +55 -0
- package/src/workspace/pid/external.ts +11 -0
- package/src/workspace/pid/index.ts +10 -0
- package/src/workspace/pid/payload.ts +31 -0
- package/src/workspace/pid/pid.spec.ts +111 -0
- package/src/workspace/pid/retriever.ts +45 -0
- package/src/workspace/pid/writer.ts +130 -0
- package/src/workspace/retriever.ts +66 -0
- package/src/workspace/workspace.spec.ts +62 -0
- package/src/workspace/writer.ts +103 -0
- package/tsconfig.json +7 -0
- package/tsconfig.vite.json +4 -0
- package/vite.config.ts +25 -0
- package/CHANGELOG.md +0 -5
- package/build/main/index.d.ts +0 -4
- package/build/main/index.js +0 -35
- package/build/main/lib/auth.d.ts +0 -54
- package/build/main/lib/auth.js +0 -62
- package/build/main/lib/auth.spec.js +0 -39
- package/build/main/lib/channel/channel.spec.js +0 -49
- package/build/main/lib/channel/client.d.ts +0 -94
- package/build/main/lib/channel/client.js +0 -134
- package/build/main/lib/channel/creator.d.ts +0 -19
- package/build/main/lib/channel/creator.js +0 -44
- package/build/main/lib/channel/payload.d.ts +0 -25
- package/build/main/lib/channel/payload.js +0 -18
- package/build/main/lib/channel/registry.d.ts +0 -9
- package/build/main/lib/channel/registry.js +0 -37
- package/build/main/lib/channel/retriever.d.ts +0 -11
- package/build/main/lib/channel/retriever.js +0 -39
- package/build/main/lib/client.d.ts +0 -30
- package/build/main/lib/client.js +0 -46
- package/build/main/lib/errors.js +0 -122
- package/build/main/lib/segment/client.d.ts +0 -62
- package/build/main/lib/segment/client.js +0 -95
- package/build/main/lib/segment/iterator.d.ts +0 -134
- package/build/main/lib/segment/iterator.js +0 -253
- package/build/main/lib/segment/iterator.spec.js +0 -73
- package/build/main/lib/segment/payload.d.ts +0 -16
- package/build/main/lib/segment/payload.js +0 -13
- package/build/main/lib/segment/splitter.d.ts +0 -7
- package/build/main/lib/segment/splitter.js +0 -25
- package/build/main/lib/segment/typed.d.ts +0 -15
- package/build/main/lib/segment/typed.js +0 -49
- package/build/main/lib/segment/validator.d.ts +0 -22
- package/build/main/lib/segment/validator.js +0 -64
- package/build/main/lib/segment/writer.d.ts +0 -98
- package/build/main/lib/segment/writer.js +0 -183
- package/build/main/lib/segment/writer.spec.js +0 -90
- package/build/main/lib/telem.d.ts +0 -395
- package/build/main/lib/telem.js +0 -553
- package/build/main/lib/telem.spec.js +0 -152
- package/build/main/lib/transport.d.ts +0 -10
- package/build/main/lib/transport.js +0 -22
- package/build/main/lib/user/payload.js +0 -9
- package/build/main/lib/util/telem.d.ts +0 -2
- package/build/main/lib/util/telem.js +0 -13
- package/build/main/setupspecs.js +0 -17
- package/build/module/index.d.ts +0 -4
- package/build/module/index.js +0 -5
- package/build/module/lib/auth.js +0 -63
- package/build/module/lib/auth.spec.js +0 -34
- package/build/module/lib/channel/channel.spec.js +0 -44
- package/build/module/lib/channel/client.d.ts +0 -94
- package/build/module/lib/channel/client.js +0 -134
- package/build/module/lib/channel/creator.d.ts +0 -19
- package/build/module/lib/channel/creator.js +0 -42
- package/build/module/lib/channel/payload.d.ts +0 -25
- package/build/module/lib/channel/payload.js +0 -15
- package/build/module/lib/channel/registry.d.ts +0 -9
- package/build/module/lib/channel/registry.js +0 -36
- package/build/module/lib/channel/retriever.d.ts +0 -11
- package/build/module/lib/channel/retriever.js +0 -37
- package/build/module/lib/client.d.ts +0 -30
- package/build/module/lib/client.js +0 -44
- package/build/module/lib/errors.d.ts +0 -53
- package/build/module/lib/errors.js +0 -113
- package/build/module/lib/segment/client.d.ts +0 -62
- package/build/module/lib/segment/client.js +0 -94
- package/build/module/lib/segment/iterator.js +0 -248
- package/build/module/lib/segment/iterator.spec.js +0 -68
- package/build/module/lib/segment/payload.d.ts +0 -16
- package/build/module/lib/segment/payload.js +0 -10
- package/build/module/lib/segment/splitter.d.ts +0 -7
- package/build/module/lib/segment/splitter.js +0 -26
- package/build/module/lib/segment/typed.d.ts +0 -15
- package/build/module/lib/segment/typed.js +0 -49
- package/build/module/lib/segment/validator.d.ts +0 -22
- package/build/module/lib/segment/validator.js +0 -60
- package/build/module/lib/segment/writer.d.ts +0 -98
- package/build/module/lib/segment/writer.js +0 -183
- package/build/module/lib/segment/writer.spec.js +0 -85
- package/build/module/lib/telem.d.ts +0 -395
- package/build/module/lib/telem.js +0 -545
- package/build/module/lib/telem.spec.js +0 -147
- package/build/module/lib/transport.d.ts +0 -10
- package/build/module/lib/transport.js +0 -22
- package/build/module/lib/user/payload.d.ts +0 -12
- package/build/module/lib/user/payload.js +0 -6
- package/build/module/lib/util/telem.d.ts +0 -2
- package/build/module/lib/util/telem.js +0 -9
- package/build/module/setupspecs.d.ts +0 -4
- package/build/module/setupspecs.js +0 -16
- /package/{build/main/lib → dist/auth}/auth.spec.d.ts +0 -0
- /package/{build/main/lib → dist}/channel/channel.spec.d.ts +0 -0
- /package/{build/main/lib/segment/iterator.spec.d.ts → dist/connection/connection.spec.d.ts} +0 -0
- /package/{build/main/lib/segment/writer.spec.d.ts → dist/control/state.spec.d.ts} +0 -0
- /package/{build/main/lib/telem.spec.d.ts → dist/framer/frame.spec.d.ts} +0 -0
- /package/{build/module/lib/segment → dist/framer}/iterator.spec.d.ts +0 -0
- /package/{build/module/lib/auth.spec.d.ts → dist/framer/streamer.spec.d.ts} +0 -0
- /package/{build/module/lib/segment → dist/framer}/writer.spec.d.ts +0 -0
- /package/{build/module/lib/channel/channel.spec.d.ts → dist/label/label.spec.d.ts} +0 -0
- /package/{build/module/lib/telem.spec.d.ts → dist/ontology/group/group.spec.d.ts} +0 -0
package/src/ranger/kv.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { type UnaryClient, sendRequired } from "@synnaxlabs/freighter";
|
|
11
|
+
import { isObject, toArray } from "@synnaxlabs/x";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
import { type Key, keyZ } from "@/ranger/payload";
|
|
15
|
+
|
|
16
|
+
const getReqZ = z.object({
|
|
17
|
+
range: keyZ,
|
|
18
|
+
keys: z.string().array(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const getResZ = z.object({
|
|
22
|
+
pairs: z.record(z.string(), z.string()),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export type GetRequest = z.infer<typeof getReqZ>;
|
|
26
|
+
|
|
27
|
+
const setReqZ = z.object({
|
|
28
|
+
range: keyZ,
|
|
29
|
+
pairs: z.record(z.string(), z.string()),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export type SetRequest = z.infer<typeof setReqZ>;
|
|
33
|
+
|
|
34
|
+
const deleteReqZ = z.object({
|
|
35
|
+
range: keyZ,
|
|
36
|
+
keys: z.string().array(),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export type DeleteRequest = z.infer<typeof deleteReqZ>;
|
|
40
|
+
|
|
41
|
+
export class KV {
|
|
42
|
+
private static readonly GET_ENDPOINT = "/range/kv/get";
|
|
43
|
+
private static readonly SET_ENDPOINT = "/range/kv/set";
|
|
44
|
+
private static readonly DELETE_ENDPOINT = "/range/kv/delete";
|
|
45
|
+
private readonly rangeKey: Key;
|
|
46
|
+
private readonly client: UnaryClient;
|
|
47
|
+
|
|
48
|
+
constructor(rng: Key, client: UnaryClient) {
|
|
49
|
+
this.rangeKey = rng;
|
|
50
|
+
this.client = client;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async get(key: string): Promise<string>;
|
|
54
|
+
|
|
55
|
+
async get(keys: string[]): Promise<Record<string, string>>;
|
|
56
|
+
|
|
57
|
+
async get(keys: string | string[]): Promise<string | Record<string, string>> {
|
|
58
|
+
const [res, err] = await this.client.send(
|
|
59
|
+
KV.GET_ENDPOINT,
|
|
60
|
+
{ range: this.rangeKey, keys: toArray(keys) },
|
|
61
|
+
getResZ,
|
|
62
|
+
);
|
|
63
|
+
if (err != null) throw err;
|
|
64
|
+
return Array.isArray(keys) ? res.pairs : res.pairs[keys];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async set(key: string, value: string): Promise<void>;
|
|
68
|
+
|
|
69
|
+
async set(kv: Record<string, string>): Promise<void>;
|
|
70
|
+
|
|
71
|
+
async set(key: string | Record<string, string>, value?: string): Promise<void> {
|
|
72
|
+
await sendRequired(
|
|
73
|
+
this.client,
|
|
74
|
+
KV.SET_ENDPOINT,
|
|
75
|
+
{
|
|
76
|
+
range: this.rangeKey,
|
|
77
|
+
pairs: isObject(key) ? key : { [key]: value },
|
|
78
|
+
},
|
|
79
|
+
z.unknown(),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async delete(key: string | string[]): Promise<void> {
|
|
84
|
+
await sendRequired(
|
|
85
|
+
this.client,
|
|
86
|
+
KV.DELETE_ENDPOINT,
|
|
87
|
+
{ range: this.rangeKey, keys: toArray(key) },
|
|
88
|
+
z.unknown(),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright 2023 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 { TimeRange, toArray } from "@synnaxlabs/x";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
export const keyZ = z.string().uuid();
|
|
14
|
+
export type Key = z.infer<typeof keyZ>;
|
|
15
|
+
export type Name = string;
|
|
16
|
+
export type Keys = Key[];
|
|
17
|
+
export type Names = Name[];
|
|
18
|
+
export type Params = Key | Name | Keys | Names;
|
|
19
|
+
|
|
20
|
+
export const payloadZ = z.object({
|
|
21
|
+
key: keyZ,
|
|
22
|
+
name: z.string().min(1),
|
|
23
|
+
timeRange: TimeRange.z,
|
|
24
|
+
});
|
|
25
|
+
export type Payload = z.infer<typeof payloadZ>;
|
|
26
|
+
|
|
27
|
+
export const newPayloadZ = payloadZ.extend({
|
|
28
|
+
key: z.string().uuid().optional(),
|
|
29
|
+
});
|
|
30
|
+
export type NewPayload = z.infer<typeof newPayloadZ>;
|
|
31
|
+
|
|
32
|
+
export type ParamAnalsysisResult =
|
|
33
|
+
| {
|
|
34
|
+
single: true;
|
|
35
|
+
variant: "keys";
|
|
36
|
+
normalized: Keys;
|
|
37
|
+
actual: Key;
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
single: true;
|
|
41
|
+
variant: "names";
|
|
42
|
+
normalized: Names;
|
|
43
|
+
actual: Name;
|
|
44
|
+
}
|
|
45
|
+
| {
|
|
46
|
+
single: false;
|
|
47
|
+
variant: "keys";
|
|
48
|
+
normalized: Keys;
|
|
49
|
+
actual: Keys;
|
|
50
|
+
}
|
|
51
|
+
| {
|
|
52
|
+
single: false;
|
|
53
|
+
variant: "names";
|
|
54
|
+
normalized: Names;
|
|
55
|
+
actual: Names;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const analyzeParams = (params: Params): ParamAnalsysisResult => {
|
|
59
|
+
const normal = toArray(params) as Keys | Names;
|
|
60
|
+
if (normal.length === 0) {
|
|
61
|
+
throw new Error("Range params must not be empty");
|
|
62
|
+
}
|
|
63
|
+
const isKey = keyZ.safeParse(normal[0]).success;
|
|
64
|
+
return {
|
|
65
|
+
single: !Array.isArray(params),
|
|
66
|
+
variant: isKey ? "keys" : "names",
|
|
67
|
+
normalized: normal,
|
|
68
|
+
actual: params,
|
|
69
|
+
} as const as ParamAnalsysisResult;
|
|
70
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Copyright 2023 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 Series, TimeRange } from "@synnaxlabs/x";
|
|
11
|
+
|
|
12
|
+
import { type Key, type Params, type Name } from "@/channel/payload";
|
|
13
|
+
import { type Retriever as ChannelRetriever } from "@/channel/retriever";
|
|
14
|
+
import { QueryError } from "@/errors";
|
|
15
|
+
import { type framer } from "@/framer";
|
|
16
|
+
import { type label } from "@/label";
|
|
17
|
+
import { type Label } from "@/label/payload";
|
|
18
|
+
import { ontology } from "@/ontology";
|
|
19
|
+
import { type Alias, type Aliaser } from "@/ranger/alias";
|
|
20
|
+
import { type KV } from "@/ranger/kv";
|
|
21
|
+
import { type signals } from "@/signals";
|
|
22
|
+
|
|
23
|
+
const ontologyID = (key: string): ontology.ID =>
|
|
24
|
+
new ontology.ID({ type: "range", key });
|
|
25
|
+
|
|
26
|
+
export class Range {
|
|
27
|
+
key: string;
|
|
28
|
+
name: string;
|
|
29
|
+
readonly kv: KV;
|
|
30
|
+
readonly timeRange: TimeRange;
|
|
31
|
+
readonly channels: ChannelRetriever;
|
|
32
|
+
private readonly aliaser: Aliaser;
|
|
33
|
+
private readonly frameClient: framer.Client;
|
|
34
|
+
private readonly labelClient: label.Client;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
name: string,
|
|
38
|
+
timeRange: TimeRange = TimeRange.ZERO,
|
|
39
|
+
key: string,
|
|
40
|
+
_frameClient: framer.Client,
|
|
41
|
+
_kv: KV,
|
|
42
|
+
_aliaser: Aliaser,
|
|
43
|
+
_channels: ChannelRetriever,
|
|
44
|
+
_labelClient: label.Client,
|
|
45
|
+
) {
|
|
46
|
+
this.key = key;
|
|
47
|
+
this.name = name;
|
|
48
|
+
this.timeRange = timeRange;
|
|
49
|
+
this.frameClient = _frameClient;
|
|
50
|
+
this.kv = _kv;
|
|
51
|
+
this.aliaser = _aliaser;
|
|
52
|
+
this.channels = _channels;
|
|
53
|
+
this.labelClient = _labelClient;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async setAlias(channel: Key | Name, alias: string): Promise<void> {
|
|
57
|
+
const ch = await this.channels.retrieve(channel);
|
|
58
|
+
if (ch.length === 0) {
|
|
59
|
+
throw new QueryError(`Channel ${channel} does not exist`);
|
|
60
|
+
}
|
|
61
|
+
await this.aliaser.set({ [ch[0].key]: alias });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async deleteAlias(...channels: Key[]): Promise<void> {
|
|
65
|
+
await this.aliaser.delete(channels);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async listAliases(): Promise<Record<Key, string>> {
|
|
69
|
+
return await this.aliaser.list();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async openAliasTracker(): Promise<signals.Observable<string, Alias>> {
|
|
73
|
+
return await this.aliaser.openChangeTracker();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async read(channel: Key | Name): Promise<Series>;
|
|
77
|
+
|
|
78
|
+
async read(channels: Params): Promise<framer.Frame>;
|
|
79
|
+
|
|
80
|
+
async read(channels: Params): Promise<Series | framer.Frame> {
|
|
81
|
+
return await this.frameClient.read(this.timeRange, channels);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async labels(): Promise<Label[]> {
|
|
85
|
+
return await this.labelClient.retrieveFor(ontologyID(this.key));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async addLabel(...labels: label.Key[]): Promise<void> {
|
|
89
|
+
await this.labelClient.label(ontologyID(this.key), labels);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async removeLabel(...labels: label.Key[]): Promise<void> {
|
|
93
|
+
await this.labelClient.removeLabels(ontologyID(this.key), labels);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Copyright 2023 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, TimeSpan, TimeStamp } from "@synnaxlabs/x";
|
|
11
|
+
import { describe, expect, it } from "vitest";
|
|
12
|
+
|
|
13
|
+
import { QueryError } from "@/errors";
|
|
14
|
+
import { type NewPayload } from "@/ranger/payload";
|
|
15
|
+
import { newClient } from "@/setupspecs";
|
|
16
|
+
|
|
17
|
+
const client = newClient();
|
|
18
|
+
|
|
19
|
+
describe("Ranger", () => {
|
|
20
|
+
describe("create", () => {
|
|
21
|
+
it("should create a single range", async () => {
|
|
22
|
+
const timeRange = TimeStamp.now().spanRange(TimeSpan.seconds(1));
|
|
23
|
+
const range = await client.ranges.create({
|
|
24
|
+
name: "My New One Second Range",
|
|
25
|
+
timeRange,
|
|
26
|
+
});
|
|
27
|
+
expect(range.key).not.toHaveLength(0);
|
|
28
|
+
expect(timeRange).toEqual(range.timeRange);
|
|
29
|
+
});
|
|
30
|
+
it("should create multiple ranges", async () => {
|
|
31
|
+
const ranges: NewPayload[] = [
|
|
32
|
+
{
|
|
33
|
+
name: "My New One Second Range",
|
|
34
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "My New Two Second Range",
|
|
38
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(2)),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
const createdRanges = await client.ranges.create(ranges);
|
|
42
|
+
expect(createdRanges).toHaveLength(2);
|
|
43
|
+
expect(createdRanges[0].key).not.toHaveLength(0);
|
|
44
|
+
expect(createdRanges[1].key).not.toHaveLength(0);
|
|
45
|
+
expect(createdRanges[0].timeRange).toEqual(ranges[0].timeRange);
|
|
46
|
+
expect(createdRanges[1].timeRange).toEqual(ranges[1].timeRange);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("delete", () => {
|
|
51
|
+
it("should delete a single range", async () => {
|
|
52
|
+
const timeRange = TimeStamp.now().spanRange(TimeSpan.seconds(1));
|
|
53
|
+
const range = await client.ranges.create({
|
|
54
|
+
name: "My New One Second Range",
|
|
55
|
+
timeRange,
|
|
56
|
+
});
|
|
57
|
+
await client.ranges.delete(range.key);
|
|
58
|
+
await expect(async () => await client.ranges.retrieve(range.key)).rejects.toThrow(
|
|
59
|
+
QueryError,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("rename", () => {
|
|
65
|
+
it("should rename a single range", async () => {
|
|
66
|
+
const timeRange = TimeStamp.now().spanRange(TimeSpan.seconds(1));
|
|
67
|
+
const range = await client.ranges.create({
|
|
68
|
+
name: "My New One Second Range",
|
|
69
|
+
timeRange,
|
|
70
|
+
});
|
|
71
|
+
await client.ranges.rename(range.key, "My New One Second Range Renamed");
|
|
72
|
+
const renamed = await client.ranges.retrieve(range.key);
|
|
73
|
+
expect(renamed.name).toEqual("My New One Second Range Renamed");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("retrieve", () => {
|
|
78
|
+
it("should retrieve a range by key", async () => {
|
|
79
|
+
const timeRange = TimeStamp.now().spanRange(TimeSpan.seconds(1));
|
|
80
|
+
const range = await client.ranges.create({
|
|
81
|
+
name: "My New One Second Range",
|
|
82
|
+
timeRange,
|
|
83
|
+
});
|
|
84
|
+
const retrieved = await client.ranges.retrieve(range.key);
|
|
85
|
+
expect(retrieved.key).toEqual(range.key);
|
|
86
|
+
expect(retrieved.timeRange).toEqual(range.timeRange);
|
|
87
|
+
});
|
|
88
|
+
it("should retrieve a range by name", async () => {
|
|
89
|
+
const timeRange = TimeStamp.now().spanRange(TimeSpan.seconds(1));
|
|
90
|
+
const range = await client.ranges.create({
|
|
91
|
+
name: "My New Three Second Range",
|
|
92
|
+
timeRange,
|
|
93
|
+
});
|
|
94
|
+
const retrieved = await client.ranges.retrieve([range.name]);
|
|
95
|
+
expect(retrieved.length).toBeGreaterThan(0);
|
|
96
|
+
expect(retrieved[0].name).toEqual(range.name);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("KV", () => {
|
|
101
|
+
it("should set, get, and delete a single key", async () => {
|
|
102
|
+
const rng = await client.ranges.create({
|
|
103
|
+
name: "My New One Second Range",
|
|
104
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
105
|
+
});
|
|
106
|
+
await rng.kv.set("foo", "bar");
|
|
107
|
+
const val = await rng.kv.get("foo");
|
|
108
|
+
expect(val).toEqual("bar");
|
|
109
|
+
await rng.kv.delete("foo");
|
|
110
|
+
await expect(async () => await rng.kv.get("foo")).rejects.toThrow(QueryError);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("should set and get multiple keys", async () => {
|
|
114
|
+
const rng = await client.ranges.create({
|
|
115
|
+
name: "My New One Second Range",
|
|
116
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
117
|
+
});
|
|
118
|
+
await rng.kv.set({ foo: "bar", baz: "qux" });
|
|
119
|
+
const res = await rng.kv.get(["foo", "baz"]);
|
|
120
|
+
expect(res).toEqual({ foo: "bar", baz: "qux" });
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe("Alias", () => {
|
|
125
|
+
describe("list", () => {
|
|
126
|
+
it("should list the aliases for the range", async () => {
|
|
127
|
+
const ch = await client.channels.create({
|
|
128
|
+
name: "My New Channel",
|
|
129
|
+
dataType: DataType.FLOAT32,
|
|
130
|
+
rate: Rate.hz(1),
|
|
131
|
+
});
|
|
132
|
+
const rng = await client.ranges.create({
|
|
133
|
+
name: "My New One Second Range",
|
|
134
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
135
|
+
});
|
|
136
|
+
await rng.setAlias(ch.key, "myalias");
|
|
137
|
+
const aliases = await rng.listAliases();
|
|
138
|
+
expect(aliases).toEqual({ [ch.key]: "myalias" });
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("Active", () => {
|
|
144
|
+
describe("setActive", () => {
|
|
145
|
+
it("should create and set a range as active", async () => {
|
|
146
|
+
const rng = await client.ranges.create({
|
|
147
|
+
name: "My New One Second Range",
|
|
148
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
149
|
+
});
|
|
150
|
+
await client.ranges.setActive(rng.key);
|
|
151
|
+
const retrieved = await client.ranges.retrieveActive();
|
|
152
|
+
expect(retrieved).not.toBeNull();
|
|
153
|
+
expect(retrieved?.key).toEqual(rng.key);
|
|
154
|
+
});
|
|
155
|
+
it("should clear the active range", async () => {
|
|
156
|
+
const rng = await client.ranges.create({
|
|
157
|
+
name: "My New One Second Range",
|
|
158
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
159
|
+
});
|
|
160
|
+
await client.ranges.setActive(rng.key);
|
|
161
|
+
await client.ranges.clearActive(rng.key);
|
|
162
|
+
const retrieved = await client.ranges.retrieveActive();
|
|
163
|
+
expect(retrieved).toBeNull();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("Labels", () => {
|
|
169
|
+
describe("set", () => {
|
|
170
|
+
it("should set a label on a range", async () => {
|
|
171
|
+
const rng = await client.ranges.create({
|
|
172
|
+
name: "My New One Second Range",
|
|
173
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
174
|
+
});
|
|
175
|
+
const lbl = await client.labels.create({
|
|
176
|
+
name: "My New Label",
|
|
177
|
+
color: "#E774D0",
|
|
178
|
+
});
|
|
179
|
+
await rng.addLabel(lbl.key);
|
|
180
|
+
const retrieved = await rng.labels();
|
|
181
|
+
expect(retrieved).toEqual([lbl]);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe("remove", () => {
|
|
185
|
+
it("should remove a label from a range", async () => {
|
|
186
|
+
const rng = await client.ranges.create({
|
|
187
|
+
name: "My New One Second Range",
|
|
188
|
+
timeRange: TimeStamp.now().spanRange(TimeSpan.seconds(1)),
|
|
189
|
+
});
|
|
190
|
+
const lbl = await client.labels.create({
|
|
191
|
+
name: "My New Label",
|
|
192
|
+
color: "#E774D0",
|
|
193
|
+
});
|
|
194
|
+
await rng.addLabel(lbl.key);
|
|
195
|
+
await rng.removeLabel(lbl.key);
|
|
196
|
+
const retrieved = await rng.labels();
|
|
197
|
+
expect(retrieved).toEqual([]);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
import { type Params, type Payload, analyzeParams, keyZ, payloadZ } from "./payload";
|
|
14
|
+
|
|
15
|
+
const reqZ = z.object({
|
|
16
|
+
keys: keyZ.array().optional(),
|
|
17
|
+
names: z.array(z.string()).optional(),
|
|
18
|
+
term: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
type Request = z.infer<typeof reqZ>;
|
|
22
|
+
|
|
23
|
+
const resZ = z.object({
|
|
24
|
+
ranges: z.array(payloadZ),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export class Retriever {
|
|
28
|
+
private readonly ENDPOINT = "/range/retrieve";
|
|
29
|
+
private readonly client: UnaryClient;
|
|
30
|
+
|
|
31
|
+
constructor(client: UnaryClient) {
|
|
32
|
+
this.client = client;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async retrieve(params: Params): Promise<Payload[]> {
|
|
36
|
+
const { normalized, variant } = analyzeParams(params);
|
|
37
|
+
const res = await this.execute({ [variant]: normalized });
|
|
38
|
+
return res;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async search(term: string): Promise<Payload[]> {
|
|
42
|
+
return await this.execute({ term });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private async execute(request: Request): Promise<Payload[]> {
|
|
46
|
+
const [res, err] = await this.client.send(this.ENDPOINT, request, resZ);
|
|
47
|
+
if (err != null) throw err;
|
|
48
|
+
return res.ranges;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
type NewPayload,
|
|
15
|
+
type Payload,
|
|
16
|
+
payloadZ,
|
|
17
|
+
keyZ,
|
|
18
|
+
newPayloadZ,
|
|
19
|
+
} from "@/ranger/payload";
|
|
20
|
+
|
|
21
|
+
const createResZ = z.object({
|
|
22
|
+
ranges: payloadZ.array(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const createReqZ = z.object({
|
|
26
|
+
ranges: newPayloadZ.array(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const deleteReqZ = z.object({
|
|
30
|
+
keys: keyZ.array(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const deleteResZ = z.object({});
|
|
34
|
+
|
|
35
|
+
const renameReqZ = z.object({
|
|
36
|
+
key: keyZ,
|
|
37
|
+
name: z.string(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const renameResZ = z.object({});
|
|
41
|
+
|
|
42
|
+
const CREATE_ENDPOINT = "/range/create";
|
|
43
|
+
const DELETE_ENDPOINT = "/range/delete";
|
|
44
|
+
const RENAME_ENDPOINT = "/range/rename";
|
|
45
|
+
|
|
46
|
+
export class Writer {
|
|
47
|
+
client: UnaryClient;
|
|
48
|
+
|
|
49
|
+
constructor(client: UnaryClient) {
|
|
50
|
+
this.client = client;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async rename(key: string, name: string): Promise<void> {
|
|
54
|
+
await sendRequired<typeof renameReqZ, typeof renameResZ>(
|
|
55
|
+
this.client,
|
|
56
|
+
RENAME_ENDPOINT,
|
|
57
|
+
{ key, name },
|
|
58
|
+
renameResZ,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async create(ranges: NewPayload[]): Promise<Payload[]> {
|
|
63
|
+
const res = await sendRequired<typeof createReqZ, typeof createResZ>(
|
|
64
|
+
this.client,
|
|
65
|
+
CREATE_ENDPOINT,
|
|
66
|
+
{ ranges },
|
|
67
|
+
createResZ,
|
|
68
|
+
);
|
|
69
|
+
return res.ranges;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async delete(keys: string[]): Promise<void> {
|
|
73
|
+
await sendRequired<typeof deleteReqZ, typeof deleteResZ>(
|
|
74
|
+
this.client,
|
|
75
|
+
DELETE_ENDPOINT,
|
|
76
|
+
{ keys },
|
|
77
|
+
deleteResZ,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2023 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 Synnax, { type SynnaxProps } from "@/client";
|
|
11
|
+
|
|
12
|
+
export const HOST = "localhost";
|
|
13
|
+
export const PORT = 9090;
|
|
14
|
+
|
|
15
|
+
export const newClient = (...props: SynnaxProps[]): Synnax => {
|
|
16
|
+
let _props = {};
|
|
17
|
+
if (props.length > 0) _props = props[0];
|
|
18
|
+
return new Synnax({
|
|
19
|
+
host: HOST,
|
|
20
|
+
port: PORT,
|
|
21
|
+
username: "synnax",
|
|
22
|
+
password: "seldon",
|
|
23
|
+
..._props,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
export * from "@/signals/observable";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
export * as signals from "@/signals/external";
|