@synnaxlabs/client 0.43.0 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/dist/access/payload.d.ts +1 -1
- package/dist/access/payload.d.ts.map +1 -1
- package/dist/access/policy/client.d.ts +263 -6
- package/dist/access/policy/client.d.ts.map +1 -1
- package/dist/access/policy/external.d.ts +0 -1
- package/dist/access/policy/external.d.ts.map +1 -1
- package/dist/access/policy/payload.d.ts +105 -93
- package/dist/access/policy/payload.d.ts.map +1 -1
- package/dist/auth/auth.d.ts +1 -1
- package/dist/auth/auth.d.ts.map +1 -1
- package/dist/channel/client.d.ts +12 -13
- package/dist/channel/client.d.ts.map +1 -1
- package/dist/channel/payload.d.ts +77 -19
- package/dist/channel/payload.d.ts.map +1 -1
- package/dist/channel/retriever.d.ts +9 -16
- package/dist/channel/retriever.d.ts.map +1 -1
- package/dist/channel/writer.d.ts +1 -1
- package/dist/channel/writer.d.ts.map +1 -1
- package/dist/client.cjs +27 -135
- package/dist/client.d.ts +3 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8619 -28938
- package/dist/connection/checker.d.ts +1 -1
- package/dist/connection/checker.d.ts.map +1 -1
- package/dist/control/client.d.ts +1 -0
- package/dist/control/client.d.ts.map +1 -1
- package/dist/control/state.d.ts +6 -6
- package/dist/control/state.d.ts.map +1 -1
- package/dist/errors.d.ts +18 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/framer/adapter.d.ts +3 -3
- package/dist/framer/adapter.d.ts.map +1 -1
- package/dist/framer/client.d.ts +4 -13
- package/dist/framer/client.d.ts.map +1 -1
- package/dist/framer/codec.d.ts +1 -1
- package/dist/framer/codec.d.ts.map +1 -1
- package/dist/framer/deleter.d.ts +5 -5
- package/dist/framer/deleter.d.ts.map +1 -1
- package/dist/framer/frame.d.ts +5 -7
- package/dist/framer/frame.d.ts.map +1 -1
- package/dist/framer/streamProxy.d.ts +1 -1
- package/dist/framer/streamProxy.d.ts.map +1 -1
- package/dist/framer/streamer.d.ts +139 -20
- package/dist/framer/streamer.d.ts.map +1 -1
- package/dist/framer/writer.d.ts +222 -33
- package/dist/framer/writer.d.ts.map +1 -1
- package/dist/hardware/device/client.d.ts +49 -28
- package/dist/hardware/device/client.d.ts.map +1 -1
- package/dist/hardware/device/payload.d.ts +126 -46
- package/dist/hardware/device/payload.d.ts.map +1 -1
- package/dist/hardware/rack/client.d.ts +78 -22
- package/dist/hardware/rack/client.d.ts.map +1 -1
- package/dist/hardware/rack/payload.d.ts +99 -56
- package/dist/hardware/rack/payload.d.ts.map +1 -1
- package/dist/hardware/task/client.d.ts +100 -41
- package/dist/hardware/task/client.d.ts.map +1 -1
- package/dist/hardware/task/payload.d.ts +83 -61
- package/dist/hardware/task/payload.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/label/client.d.ts +138 -20
- package/dist/label/client.d.ts.map +1 -1
- package/dist/label/external.d.ts +0 -2
- package/dist/label/external.d.ts.map +1 -1
- package/dist/label/payload.d.ts +4 -5
- package/dist/label/payload.d.ts.map +1 -1
- package/dist/ontology/client.d.ts +45 -135
- package/dist/ontology/client.d.ts.map +1 -1
- package/dist/ontology/group/group.d.ts +3 -3
- package/dist/ontology/group/group.d.ts.map +1 -1
- package/dist/ontology/group/payload.d.ts +3 -27
- package/dist/ontology/group/payload.d.ts.map +1 -1
- package/dist/ontology/payload.d.ts +113 -243
- package/dist/ontology/payload.d.ts.map +1 -1
- package/dist/ontology/writer.d.ts +4 -4
- package/dist/ontology/writer.d.ts.map +1 -1
- package/dist/ranger/alias.d.ts +11 -5
- package/dist/ranger/alias.d.ts.map +1 -1
- package/dist/ranger/client.d.ts +87 -30
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/external.d.ts +1 -1
- package/dist/ranger/external.d.ts.map +1 -1
- package/dist/ranger/kv.d.ts +10 -12
- package/dist/ranger/kv.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts +23 -44
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts +22 -19
- package/dist/ranger/writer.d.ts.map +1 -1
- package/dist/testutil/client.d.ts +4 -0
- package/dist/testutil/client.d.ts.map +1 -0
- package/dist/user/client.d.ts +59 -6
- package/dist/user/client.d.ts.map +1 -1
- package/dist/user/payload.d.ts +4 -6
- package/dist/user/payload.d.ts.map +1 -1
- package/dist/user/retriever.d.ts +2 -2
- package/dist/user/retriever.d.ts.map +1 -1
- package/dist/util/decodeJSONString.d.ts +2 -2
- package/dist/util/decodeJSONString.d.ts.map +1 -1
- package/dist/util/parseWithoutKeyConversion.d.ts +2 -2
- package/dist/util/parseWithoutKeyConversion.d.ts.map +1 -1
- package/dist/util/retrieve.d.ts +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 +17 -6
- package/dist/workspace/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/client.d.ts +2 -2
- package/dist/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/payload.d.ts +8 -9
- package/dist/workspace/lineplot/payload.d.ts.map +1 -1
- package/dist/workspace/log/client.d.ts +2 -2
- package/dist/workspace/log/client.d.ts.map +1 -1
- package/dist/workspace/log/payload.d.ts +8 -9
- package/dist/workspace/log/payload.d.ts.map +1 -1
- package/dist/workspace/payload.d.ts +10 -11
- package/dist/workspace/payload.d.ts.map +1 -1
- package/dist/workspace/schematic/client.d.ts +2 -2
- package/dist/workspace/schematic/client.d.ts.map +1 -1
- package/dist/workspace/schematic/payload.d.ts +10 -11
- package/dist/workspace/schematic/payload.d.ts.map +1 -1
- package/dist/workspace/table/client.d.ts +2 -2
- package/dist/workspace/table/client.d.ts.map +1 -1
- package/dist/workspace/table/payload.d.ts +10 -11
- package/dist/workspace/table/payload.d.ts.map +1 -1
- package/examples/node/package-lock.json +47 -39
- package/examples/node/package.json +2 -1
- package/examples/node/streamWrite.js +5 -11
- package/package.json +14 -13
- package/src/access/payload.ts +1 -1
- package/src/access/policy/client.ts +87 -32
- package/src/access/policy/external.ts +0 -1
- package/src/access/policy/payload.ts +4 -4
- package/src/access/policy/policy.spec.ts +86 -83
- package/src/auth/auth.spec.ts +29 -18
- package/src/auth/auth.ts +1 -1
- package/src/channel/batchRetriever.spec.ts +4 -9
- package/src/channel/channel.spec.ts +24 -6
- package/src/channel/client.ts +31 -46
- package/src/channel/payload.ts +13 -14
- package/src/channel/retriever.ts +26 -41
- package/src/channel/writer.ts +3 -3
- package/src/client.ts +4 -4
- package/src/connection/checker.ts +1 -1
- package/src/connection/connection.spec.ts +31 -23
- package/src/control/client.ts +2 -2
- package/src/control/state.spec.ts +3 -3
- package/src/control/state.ts +1 -1
- package/src/errors.spec.ts +9 -5
- package/src/errors.ts +28 -15
- package/src/framer/adapter.spec.ts +118 -9
- package/src/framer/adapter.ts +24 -11
- package/src/framer/client.spec.ts +125 -2
- package/src/framer/client.ts +41 -47
- package/src/framer/codec.ts +1 -1
- package/src/framer/deleter.spec.ts +2 -2
- package/src/framer/deleter.ts +1 -1
- package/src/framer/frame.ts +1 -4
- package/src/framer/iterator.spec.ts +8 -8
- package/src/framer/iterator.ts +1 -1
- package/src/framer/streamProxy.ts +1 -1
- package/src/framer/streamer.spec.ts +185 -36
- package/src/framer/streamer.ts +28 -36
- package/src/framer/writer.spec.ts +6 -6
- package/src/framer/writer.ts +97 -111
- package/src/hardware/device/client.ts +45 -131
- package/src/hardware/device/device.spec.ts +163 -52
- package/src/hardware/device/payload.ts +10 -21
- package/src/hardware/rack/client.ts +87 -105
- package/src/hardware/rack/payload.ts +4 -13
- package/src/hardware/rack/rack.spec.ts +28 -35
- package/src/hardware/task/client.ts +335 -291
- package/src/hardware/task/payload.ts +86 -62
- package/src/hardware/task/task.spec.ts +208 -32
- package/src/index.ts +2 -1
- package/src/label/client.ts +100 -95
- package/src/label/external.ts +0 -2
- package/src/label/label.spec.ts +8 -6
- package/src/label/payload.ts +3 -4
- package/src/ontology/client.ts +41 -324
- package/src/ontology/group/group.spec.ts +2 -2
- package/src/ontology/group/group.ts +4 -5
- package/src/ontology/group/payload.ts +2 -25
- package/src/ontology/group/writer.ts +1 -1
- package/src/ontology/ontology.spec.ts +355 -41
- package/src/ontology/payload.ts +74 -112
- package/src/ontology/writer.ts +8 -17
- package/src/ranger/alias.ts +19 -37
- package/src/ranger/client.ts +118 -150
- package/src/ranger/external.ts +9 -1
- package/src/ranger/kv.ts +6 -27
- package/src/ranger/payload.ts +21 -37
- package/src/ranger/ranger.spec.ts +37 -56
- package/src/ranger/writer.ts +1 -1
- package/src/{signals/index.ts → testutil/client.ts} +11 -1
- package/src/user/client.ts +122 -47
- package/src/user/payload.ts +2 -5
- package/src/user/retriever.ts +1 -1
- package/src/user/user.spec.ts +31 -31
- package/src/user/writer.ts +1 -1
- package/src/util/decodeJSONString.ts +3 -3
- package/src/util/parseWithoutKeyConversion.ts +2 -2
- package/src/util/retrieve.ts +1 -1
- package/src/util/zod.ts +1 -1
- package/src/workspace/client.ts +20 -36
- package/src/workspace/lineplot/client.ts +5 -7
- package/src/workspace/lineplot/lineplot.spec.ts +2 -2
- package/src/workspace/lineplot/payload.ts +4 -7
- package/src/workspace/log/client.ts +5 -7
- package/src/workspace/log/log.spec.ts +2 -2
- package/src/workspace/log/payload.ts +4 -7
- package/src/workspace/payload.ts +4 -7
- package/src/workspace/schematic/client.ts +5 -7
- package/src/workspace/schematic/payload.ts +4 -7
- package/src/workspace/schematic/schematic.spec.ts +2 -2
- package/src/workspace/table/client.ts +5 -7
- package/src/workspace/table/payload.ts +4 -7
- package/src/workspace/table/table.spec.ts +2 -2
- package/src/workspace/workspace.spec.ts +2 -2
- package/dist/access/policy/ontology.d.ts +0 -5
- package/dist/access/policy/ontology.d.ts.map +0 -1
- package/dist/access/policy/retriever.d.ts +0 -40
- package/dist/access/policy/retriever.d.ts.map +0 -1
- package/dist/access/policy/writer.d.ts +0 -9
- package/dist/access/policy/writer.d.ts.map +0 -1
- package/dist/label/retriever.d.ts +0 -14
- package/dist/label/retriever.d.ts.map +0 -1
- package/dist/label/writer.d.ts +0 -54
- package/dist/label/writer.d.ts.map +0 -1
- package/dist/setupspecs.d.ts +0 -5
- package/dist/setupspecs.d.ts.map +0 -1
- package/dist/signals/external.d.ts +0 -2
- package/dist/signals/external.d.ts.map +0 -1
- package/dist/signals/index.d.ts +0 -2
- package/dist/signals/index.d.ts.map +0 -1
- package/dist/signals/observable.d.ts +0 -12
- package/dist/signals/observable.d.ts.map +0 -1
- package/src/access/policy/ontology.ts +0 -17
- package/src/access/policy/retriever.ts +0 -44
- package/src/access/policy/writer.ts +0 -65
- package/src/label/retriever.ts +0 -63
- package/src/label/writer.ts +0 -95
- package/src/setupspecs.ts +0 -27
- package/src/signals/external.ts +0 -10
- package/src/signals/observable.ts +0 -42
package/src/ontology/writer.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { z } from "zod
|
|
11
|
+
import { z } from "zod";
|
|
12
12
|
|
|
13
|
-
import { type
|
|
13
|
+
import { type ID, idZ } from "@/ontology/payload";
|
|
14
14
|
|
|
15
15
|
const ADD_CHILDREN_ENDPOINT = "/ontology/add-children";
|
|
16
16
|
const REMOVE_CHILDREN_ENDPOINT = "/ontology/remove-children";
|
|
@@ -29,40 +29,31 @@ export class Writer {
|
|
|
29
29
|
this.client = client;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async addChildren(id:
|
|
32
|
+
async addChildren(id: ID, ...children: ID[]): Promise<void> {
|
|
33
33
|
await sendRequired<typeof addRemoveChildrenReqZ, typeof emptyResZ>(
|
|
34
34
|
this.client,
|
|
35
35
|
ADD_CHILDREN_ENDPOINT,
|
|
36
|
-
{ id
|
|
36
|
+
{ id, children },
|
|
37
37
|
addRemoveChildrenReqZ,
|
|
38
38
|
emptyResZ,
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
async removeChildren(id:
|
|
42
|
+
async removeChildren(id: ID, ...children: ID[]): Promise<void> {
|
|
43
43
|
await sendRequired<typeof addRemoveChildrenReqZ, typeof emptyResZ>(
|
|
44
44
|
this.client,
|
|
45
45
|
REMOVE_CHILDREN_ENDPOINT,
|
|
46
|
-
{ id
|
|
46
|
+
{ id, children },
|
|
47
47
|
addRemoveChildrenReqZ,
|
|
48
48
|
emptyResZ,
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
async moveChildren(
|
|
53
|
-
from: CrudeID,
|
|
54
|
-
to: CrudeID,
|
|
55
|
-
...children: CrudeID[]
|
|
56
|
-
): Promise<void> {
|
|
57
|
-
const req = {
|
|
58
|
-
from: new ID(from).payload,
|
|
59
|
-
to: new ID(to).payload,
|
|
60
|
-
children: children.map((c) => new ID(c).payload),
|
|
61
|
-
};
|
|
52
|
+
async moveChildren(from: ID, to: ID, ...children: ID[]): Promise<void> {
|
|
62
53
|
await sendRequired<typeof moveChildrenReqZ, typeof emptyResZ>(
|
|
63
54
|
this.client,
|
|
64
55
|
MOVE_CHILDREN_ENDPOINT,
|
|
65
|
-
|
|
56
|
+
{ from, to, children },
|
|
66
57
|
moveChildrenReqZ,
|
|
67
58
|
emptyResZ,
|
|
68
59
|
);
|
package/src/ranger/alias.ts
CHANGED
|
@@ -9,12 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import { type change } from "@synnaxlabs/x/change";
|
|
12
|
-
import { z } from "zod
|
|
12
|
+
import { z } from "zod";
|
|
13
13
|
|
|
14
14
|
import { channel } from "@/channel";
|
|
15
15
|
import { type framer } from "@/framer";
|
|
16
16
|
import { type Key, keyZ } from "@/ranger/payload";
|
|
17
|
-
import { signals } from "@/signals";
|
|
18
17
|
|
|
19
18
|
export const SET_ALIAS_CHANNEL_NAME = "sy_range_alias_set";
|
|
20
19
|
export const DELETE_ALIAS_CHANNEL_NAME = "sy_range_alias_delete";
|
|
@@ -118,44 +117,27 @@ export class Aliaser {
|
|
|
118
117
|
deleteResZ,
|
|
119
118
|
);
|
|
120
119
|
}
|
|
121
|
-
|
|
122
|
-
async openChangeTracker(): Promise<signals.Observable<string, Alias>> {
|
|
123
|
-
return await signals.openObservable<string, Alias>(
|
|
124
|
-
this.frameClient,
|
|
125
|
-
SET_ALIAS_CHANNEL_NAME,
|
|
126
|
-
DELETE_ALIAS_CHANNEL_NAME,
|
|
127
|
-
decodeAliasChanges(this.rangeKey),
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
120
|
}
|
|
131
121
|
|
|
132
|
-
export
|
|
122
|
+
export const aliasZ = z.object({
|
|
123
|
+
alias: z.string(),
|
|
124
|
+
channel: channel.keyZ,
|
|
125
|
+
range: keyZ,
|
|
126
|
+
});
|
|
127
|
+
export interface Alias extends z.infer<typeof aliasZ> {}
|
|
128
|
+
|
|
129
|
+
export type AliasChange = change.Change<string, Alias>;
|
|
130
|
+
|
|
131
|
+
const SEPARATOR = "---";
|
|
132
|
+
|
|
133
|
+
export interface DecodedDeleteAliasChange {
|
|
133
134
|
range: Key;
|
|
134
135
|
channel: channel.Key;
|
|
135
|
-
alias: string;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
export
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const decodeAliasChanges =
|
|
145
|
-
(rangeKey: Key): signals.Decoder<string, Alias> =>
|
|
146
|
-
(variant, data) => {
|
|
147
|
-
if (variant === "delete")
|
|
148
|
-
return data
|
|
149
|
-
.toStrings()
|
|
150
|
-
.filter((k) => k.split(separator)[0] === rangeKey)
|
|
151
|
-
.map((alias) => ({
|
|
152
|
-
variant,
|
|
153
|
-
key: alias,
|
|
154
|
-
value: undefined,
|
|
155
|
-
}));
|
|
156
|
-
return data.parseJSON(aliasZ).map((alias) => ({
|
|
157
|
-
variant,
|
|
158
|
-
key: alias.alias,
|
|
159
|
-
value: alias,
|
|
160
|
-
}));
|
|
161
|
-
};
|
|
138
|
+
export const decodeDeleteAliasChange = (
|
|
139
|
+
deletedAlias: string,
|
|
140
|
+
): DecodedDeleteAliasChange => {
|
|
141
|
+
const [range, channel] = deletedAlias.split(SEPARATOR);
|
|
142
|
+
return { range, channel: Number(channel) };
|
|
143
|
+
};
|
package/src/ranger/client.ts
CHANGED
|
@@ -8,43 +8,53 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { type CrudeTimeRange,
|
|
12
|
-
import { array } from "@synnaxlabs/x/array";
|
|
13
|
-
import { type AsyncTermSearcher } from "@synnaxlabs/x/search";
|
|
11
|
+
import { array, type CrudeTimeRange, TimeRange } from "@synnaxlabs/x";
|
|
14
12
|
import { type Series } from "@synnaxlabs/x/telem";
|
|
15
|
-
import { z } from "zod
|
|
13
|
+
import { z } from "zod";
|
|
16
14
|
|
|
17
15
|
import { type channel } from "@/channel";
|
|
18
|
-
import {
|
|
16
|
+
import { QueryError } from "@/errors";
|
|
19
17
|
import { type framer } from "@/framer";
|
|
20
18
|
import { label } from "@/label";
|
|
21
|
-
import { ontology } from "@/ontology";
|
|
22
|
-
import {
|
|
19
|
+
import { type ontology } from "@/ontology";
|
|
20
|
+
import { Aliaser } from "@/ranger/alias";
|
|
23
21
|
import { KV } from "@/ranger/kv";
|
|
24
22
|
import {
|
|
25
|
-
ALIAS_ONTOLOGY_TYPE,
|
|
26
|
-
analyzeParams,
|
|
27
23
|
type Key,
|
|
28
24
|
type Keys,
|
|
29
25
|
keyZ,
|
|
30
26
|
type Name,
|
|
31
27
|
type Names,
|
|
32
28
|
type New,
|
|
33
|
-
ONTOLOGY_TYPE,
|
|
34
29
|
type Params,
|
|
35
30
|
type Payload,
|
|
36
31
|
payloadZ,
|
|
37
32
|
} from "@/ranger/payload";
|
|
38
33
|
import { type CreateOptions, type Writer } from "@/ranger/writer";
|
|
39
|
-
import {
|
|
34
|
+
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
40
35
|
import { nullableArrayZ } from "@/util/zod";
|
|
41
36
|
|
|
37
|
+
export const SET_CHANNEL_NAME = "sy_range_set";
|
|
38
|
+
export const DELETE_CHANNEL_NAME = "sy_range_delete";
|
|
39
|
+
|
|
40
|
+
interface RangeConstructionOptions {
|
|
41
|
+
frameClient: framer.Client;
|
|
42
|
+
kv: KV;
|
|
43
|
+
aliaser: Aliaser;
|
|
44
|
+
channels: channel.Retriever;
|
|
45
|
+
labelClient: label.Client;
|
|
46
|
+
ontologyClient: ontology.Client;
|
|
47
|
+
rangeClient: Client;
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
export class Range {
|
|
43
51
|
key: string;
|
|
44
52
|
name: string;
|
|
45
53
|
readonly kv: KV;
|
|
46
54
|
readonly timeRange: TimeRange;
|
|
47
55
|
readonly color: string | undefined;
|
|
56
|
+
readonly parent: Payload | null;
|
|
57
|
+
readonly labels: label.Label[];
|
|
48
58
|
readonly channels: channel.Retriever;
|
|
49
59
|
private readonly aliaser: Aliaser;
|
|
50
60
|
private readonly frameClient: framer.Client;
|
|
@@ -53,29 +63,30 @@ export class Range {
|
|
|
53
63
|
private readonly rangeClient: Client;
|
|
54
64
|
|
|
55
65
|
constructor(
|
|
56
|
-
name:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
_rangeClient: Client,
|
|
66
|
+
{ name, timeRange = TimeRange.ZERO, key, color, parent, labels = [] }: Payload,
|
|
67
|
+
{
|
|
68
|
+
frameClient,
|
|
69
|
+
kv,
|
|
70
|
+
aliaser,
|
|
71
|
+
channels,
|
|
72
|
+
labelClient,
|
|
73
|
+
ontologyClient,
|
|
74
|
+
rangeClient,
|
|
75
|
+
}: RangeConstructionOptions,
|
|
67
76
|
) {
|
|
68
77
|
this.key = key;
|
|
69
78
|
this.name = name;
|
|
70
79
|
this.timeRange = timeRange;
|
|
71
|
-
this.
|
|
80
|
+
this.parent = parent;
|
|
81
|
+
this.labels = labels;
|
|
82
|
+
this.frameClient = frameClient;
|
|
72
83
|
this.color = color;
|
|
73
|
-
this.kv =
|
|
74
|
-
this.aliaser =
|
|
75
|
-
this.channels =
|
|
76
|
-
this.labelClient =
|
|
77
|
-
this.ontologyClient =
|
|
78
|
-
this.rangeClient =
|
|
84
|
+
this.kv = kv;
|
|
85
|
+
this.aliaser = aliaser;
|
|
86
|
+
this.channels = channels;
|
|
87
|
+
this.labelClient = labelClient;
|
|
88
|
+
this.ontologyClient = ontologyClient;
|
|
89
|
+
this.rangeClient = rangeClient;
|
|
79
90
|
}
|
|
80
91
|
|
|
81
92
|
get ontologyID(): ontology.ID {
|
|
@@ -88,6 +99,8 @@ export class Range {
|
|
|
88
99
|
name: this.name,
|
|
89
100
|
timeRange: this.timeRange,
|
|
90
101
|
color: this.color,
|
|
102
|
+
labels: this.labels,
|
|
103
|
+
parent: this.parent,
|
|
91
104
|
};
|
|
92
105
|
}
|
|
93
106
|
|
|
@@ -109,10 +122,6 @@ export class Range {
|
|
|
109
122
|
return await this.aliaser.resolve(alias);
|
|
110
123
|
}
|
|
111
124
|
|
|
112
|
-
async openAliasTracker(): Promise<signals.Observable<string, Alias>> {
|
|
113
|
-
return await this.aliaser.openChangeTracker();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
125
|
async retrieveParent(): Promise<Range | null> {
|
|
117
126
|
return this.rangeClient.retrieveParent(this.key);
|
|
118
127
|
}
|
|
@@ -133,8 +142,8 @@ export class Range {
|
|
|
133
142
|
return await this.frameClient.read(this.timeRange, channels);
|
|
134
143
|
}
|
|
135
144
|
|
|
136
|
-
async
|
|
137
|
-
return await this.labelClient.
|
|
145
|
+
async retrieveLabels(): Promise<label.Label[]> {
|
|
146
|
+
return await this.labelClient.retrieve({ for: ontologyID(this.key) });
|
|
138
147
|
}
|
|
139
148
|
|
|
140
149
|
async addLabel(...labels: label.Key[]): Promise<void> {
|
|
@@ -142,69 +151,47 @@ export class Range {
|
|
|
142
151
|
}
|
|
143
152
|
|
|
144
153
|
async removeLabel(...labels: label.Key[]): Promise<void> {
|
|
145
|
-
await this.labelClient.
|
|
154
|
+
await this.labelClient.remove(ontologyID(this.key), labels);
|
|
146
155
|
}
|
|
147
156
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const initial: ontology.Resource[] = (await this.retrieveChildren()).map((r) => {
|
|
151
|
-
const id = ontologyID(r.key);
|
|
152
|
-
return { id, key: id.toString(), name: r.name, data: r.payload };
|
|
153
|
-
});
|
|
154
|
-
const base = await this.ontologyClient.openDependentTracker({
|
|
155
|
-
target: this.ontologyID,
|
|
156
|
-
dependents: initial,
|
|
157
|
-
resourceType: "range",
|
|
158
|
-
});
|
|
159
|
-
base.onChange((r: ontology.Resource[]) =>
|
|
160
|
-
wrapper.notify(this.rangeClient.resourcesToRanges(r)),
|
|
161
|
-
);
|
|
162
|
-
wrapper.setCloser(async () => await base.close());
|
|
163
|
-
return wrapper;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async openParentRangeTracker(): Promise<observe.ObservableAsyncCloseable<Range> | null> {
|
|
167
|
-
const wrapper = new observe.Observer<Range>();
|
|
168
|
-
const p = await this.retrieveParent();
|
|
169
|
-
if (p == null) return null;
|
|
170
|
-
const id = ontologyID(p.key);
|
|
171
|
-
const resourceP = { id, key: id.toString(), name: p.name, data: p.payload };
|
|
172
|
-
const base = await this.ontologyClient.openDependentTracker({
|
|
173
|
-
target: this.ontologyID,
|
|
174
|
-
dependents: [resourceP],
|
|
175
|
-
relationshipDirection: "to",
|
|
176
|
-
});
|
|
177
|
-
base.onChange((resources: ontology.Resource[]) => {
|
|
178
|
-
const ranges = this.rangeClient.resourcesToRanges(resources);
|
|
179
|
-
if (ranges.length === 0) return;
|
|
180
|
-
const p = ranges[0];
|
|
181
|
-
wrapper.notify(p);
|
|
182
|
-
});
|
|
183
|
-
wrapper.setCloser(async () => await base.close());
|
|
184
|
-
return wrapper;
|
|
157
|
+
static sort(a: Range, b: Range): number {
|
|
158
|
+
return TimeRange.sort(a.timeRange, b.timeRange);
|
|
185
159
|
}
|
|
186
160
|
}
|
|
187
161
|
|
|
188
|
-
|
|
189
|
-
sortTimeRange(a.timeRange, b.timeRange);
|
|
190
|
-
|
|
191
|
-
const retrieveReqZ = z.object({
|
|
162
|
+
const retrieveRequestZ = z.object({
|
|
192
163
|
keys: keyZ.array().optional(),
|
|
193
164
|
names: z.array(z.string()).optional(),
|
|
194
|
-
|
|
165
|
+
searchTerm: z.string().optional(),
|
|
195
166
|
overlapsWith: TimeRange.z.optional(),
|
|
196
167
|
limit: z.number().int().optional(),
|
|
197
168
|
offset: z.number().int().optional(),
|
|
198
169
|
hasLabels: label.keyZ.array().optional(),
|
|
170
|
+
includeLabels: z.boolean().optional(),
|
|
171
|
+
includeParent: z.boolean().optional(),
|
|
199
172
|
});
|
|
200
173
|
|
|
201
|
-
export
|
|
174
|
+
export type RetrieveRequest = z.infer<typeof retrieveRequestZ>;
|
|
175
|
+
|
|
176
|
+
const retrieveArgsZ = retrieveRequestZ
|
|
177
|
+
.or(keyZ.array().transform((keys) => ({ keys })))
|
|
178
|
+
.or(keyZ.transform((key) => ({ keys: [key] })))
|
|
179
|
+
.or(z.string().transform((name) => ({ names: [name] })))
|
|
180
|
+
.or(
|
|
181
|
+
z
|
|
182
|
+
.string()
|
|
183
|
+
.array()
|
|
184
|
+
.transform((names) => ({ names })),
|
|
185
|
+
)
|
|
186
|
+
.or(TimeRange.z.transform((timeRange) => ({ overlapsWith: timeRange })));
|
|
187
|
+
|
|
188
|
+
export type RetrieveArgs = z.input<typeof retrieveArgsZ>;
|
|
202
189
|
|
|
203
190
|
const RETRIEVE_ENDPOINT = "/range/retrieve";
|
|
204
191
|
|
|
205
192
|
const retrieveResZ = z.object({ ranges: nullableArrayZ(payloadZ) });
|
|
206
193
|
|
|
207
|
-
export class Client
|
|
194
|
+
export class Client {
|
|
208
195
|
readonly type: string = "range";
|
|
209
196
|
private readonly frameClient: framer.Client;
|
|
210
197
|
private readonly writer: Writer;
|
|
@@ -247,48 +234,28 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
|
|
|
247
234
|
await this.writer.delete(array.toArray(key));
|
|
248
235
|
}
|
|
249
236
|
|
|
250
|
-
async
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
async
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
async retrieve(range: CrudeTimeRange): Promise<Range[]>;
|
|
259
|
-
async retrieve(range: Key | Name): Promise<Range>;
|
|
260
|
-
async retrieve(range: Keys | Names): Promise<Range[]>;
|
|
261
|
-
async retrieve(ranges: Params | CrudeTimeRange): Promise<Range | Range[]> {
|
|
262
|
-
if (typeof ranges === "object" && "start" in ranges)
|
|
263
|
-
return await this.execRetrieve({ overlapsWith: new TimeRange(ranges) });
|
|
264
|
-
const { single, actual, variant, normalized, empty } = analyzeParams(ranges);
|
|
265
|
-
if (empty) return [];
|
|
266
|
-
const retrieved = await this.execRetrieve({ [variant]: normalized });
|
|
267
|
-
if (!single) return retrieved;
|
|
268
|
-
if (retrieved.length === 0)
|
|
269
|
-
throw new NotFoundError(`range matching ${actual as string} not found`);
|
|
270
|
-
if (retrieved.length > 1)
|
|
271
|
-
throw new MultipleFoundError(
|
|
272
|
-
`multiple ranges matching ${actual as string} found`,
|
|
273
|
-
);
|
|
274
|
-
return retrieved[0];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
getKV(range: Key): KV {
|
|
278
|
-
return new KV(range, this.unaryClient, this.frameClient);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
private async execRetrieve(req: RetrieveRequest): Promise<Range[]> {
|
|
282
|
-
const { ranges } = await sendRequired<typeof retrieveReqZ, typeof retrieveResZ>(
|
|
237
|
+
async retrieve(params: Key | Name): Promise<Range>;
|
|
238
|
+
async retrieve(params: Keys | Names): Promise<Range[]>;
|
|
239
|
+
async retrieve(params: TimeRange): Promise<Range[]>;
|
|
240
|
+
async retrieve(params: RetrieveRequest): Promise<Range[]>;
|
|
241
|
+
async retrieve(params: RetrieveArgs): Promise<Range | Range[]> {
|
|
242
|
+
const isSingle = typeof params === "string";
|
|
243
|
+
const { ranges } = await sendRequired(
|
|
283
244
|
this.unaryClient,
|
|
284
245
|
RETRIEVE_ENDPOINT,
|
|
285
|
-
|
|
286
|
-
|
|
246
|
+
params,
|
|
247
|
+
retrieveArgsZ,
|
|
287
248
|
retrieveResZ,
|
|
288
249
|
);
|
|
250
|
+
checkForMultipleOrNoResults("Range", params, ranges, isSingle);
|
|
251
|
+
if (isSingle) return this.sugarMany(ranges)[0];
|
|
289
252
|
return this.sugarMany(ranges);
|
|
290
253
|
}
|
|
291
254
|
|
|
255
|
+
getKV(range: Key): KV {
|
|
256
|
+
return new KV(range, this.unaryClient);
|
|
257
|
+
}
|
|
258
|
+
|
|
292
259
|
async retrieveParent(range: Key): Promise<Range | null> {
|
|
293
260
|
const res = await this.ontologyClient.retrieveParents(ontologyID(range));
|
|
294
261
|
if (res.length === 0) return null;
|
|
@@ -297,56 +264,57 @@ export class Client implements AsyncTermSearcher<string, Key, Range> {
|
|
|
297
264
|
return await this.retrieve(first.id.key);
|
|
298
265
|
}
|
|
299
266
|
|
|
267
|
+
sugarOntologyResource(resource: ontology.Resource): Range {
|
|
268
|
+
return this.sugarOne(convertOntologyResourceToPayload(resource));
|
|
269
|
+
}
|
|
270
|
+
|
|
300
271
|
sugarOne(payload: Payload): Range {
|
|
301
|
-
return new Range(
|
|
302
|
-
|
|
303
|
-
payload.
|
|
304
|
-
payload.key,
|
|
305
|
-
|
|
306
|
-
this.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
this.labelClient,
|
|
311
|
-
this.ontologyClient,
|
|
312
|
-
this,
|
|
313
|
-
);
|
|
272
|
+
return new Range(payload, {
|
|
273
|
+
frameClient: this.frameClient,
|
|
274
|
+
kv: new KV(payload.key, this.unaryClient),
|
|
275
|
+
aliaser: new Aliaser(payload.key, this.frameClient, this.unaryClient),
|
|
276
|
+
channels: this.channels,
|
|
277
|
+
labelClient: this.labelClient,
|
|
278
|
+
ontologyClient: this.ontologyClient,
|
|
279
|
+
rangeClient: this,
|
|
280
|
+
});
|
|
314
281
|
}
|
|
315
282
|
|
|
316
283
|
sugarMany(payloads: Payload[]): Range[] {
|
|
317
284
|
return payloads.map((payload) => this.sugarOne(payload));
|
|
318
285
|
}
|
|
319
286
|
|
|
320
|
-
async openTracker(): Promise<signals.Observable<string, Range>> {
|
|
321
|
-
return await signals.openObservable<string, Range>(
|
|
322
|
-
this.frameClient,
|
|
323
|
-
"sy_range_set",
|
|
324
|
-
"sy_range_delete",
|
|
325
|
-
(variant, data) => {
|
|
326
|
-
if (variant === "delete")
|
|
327
|
-
return data.toUUIDs().map((k) => ({ variant, key: k, value: undefined }));
|
|
328
|
-
const sugared = this.sugarMany(data.parseJSON(payloadZ));
|
|
329
|
-
return sugared.map((r) => ({ variant, key: r.key, value: r }));
|
|
330
|
-
},
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
resourcesToRanges(resources: ontology.Resource[]): Range[] {
|
|
335
|
-
return resources.map((r) => this.resourceToRange(r));
|
|
336
|
-
}
|
|
337
|
-
|
|
338
287
|
resourceToRange(resource: ontology.Resource): Range {
|
|
339
288
|
return this.sugarOne({
|
|
340
289
|
key: resource.id.key,
|
|
341
290
|
name: resource.data?.name as string,
|
|
342
291
|
timeRange: new TimeRange(resource.data?.timeRange as CrudeTimeRange),
|
|
343
292
|
color: resource.data?.color as string,
|
|
293
|
+
labels: [],
|
|
294
|
+
parent: null,
|
|
344
295
|
});
|
|
345
296
|
}
|
|
346
297
|
}
|
|
347
298
|
|
|
348
|
-
export const ontologyID = (key: Key): ontology.ID =>
|
|
349
|
-
|
|
299
|
+
export const ontologyID = (key: Key): ontology.ID => ({ type: "range", key });
|
|
300
|
+
|
|
301
|
+
export const aliasOntologyID = (key: Key): ontology.ID => ({
|
|
302
|
+
type: "range-alias",
|
|
303
|
+
key,
|
|
304
|
+
});
|
|
350
305
|
|
|
351
|
-
export const
|
|
352
|
-
|
|
306
|
+
export const convertOntologyResourceToPayload = ({
|
|
307
|
+
data,
|
|
308
|
+
id: { key },
|
|
309
|
+
name,
|
|
310
|
+
}: ontology.Resource): Payload => {
|
|
311
|
+
const timeRange = TimeRange.z.parse(data?.timeRange);
|
|
312
|
+
return {
|
|
313
|
+
key,
|
|
314
|
+
name,
|
|
315
|
+
timeRange,
|
|
316
|
+
color: typeof data?.color === "string" ? data.color : undefined,
|
|
317
|
+
labels: [],
|
|
318
|
+
parent: null,
|
|
319
|
+
};
|
|
320
|
+
};
|
package/src/ranger/external.ts
CHANGED
|
@@ -7,7 +7,15 @@
|
|
|
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 {
|
|
10
|
+
export {
|
|
11
|
+
type Alias,
|
|
12
|
+
type AliasChange,
|
|
13
|
+
aliasZ,
|
|
14
|
+
type DecodedDeleteAliasChange,
|
|
15
|
+
decodeDeleteAliasChange,
|
|
16
|
+
DELETE_ALIAS_CHANNEL_NAME,
|
|
17
|
+
SET_ALIAS_CHANNEL_NAME,
|
|
18
|
+
} from "@/ranger/alias";
|
|
11
19
|
export * from "@/ranger/client";
|
|
12
20
|
export * from "@/ranger/kv";
|
|
13
21
|
export * from "@/ranger/payload";
|
package/src/ranger/kv.ts
CHANGED
|
@@ -10,14 +10,15 @@
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import { array } from "@synnaxlabs/x/array";
|
|
12
12
|
import { isObject } from "@synnaxlabs/x/identity";
|
|
13
|
-
import { z } from "zod
|
|
13
|
+
import { z } from "zod";
|
|
14
14
|
|
|
15
|
-
import { type framer } from "@/framer";
|
|
16
15
|
import { type Key, keyZ } from "@/ranger/payload";
|
|
17
|
-
import { signals } from "@/signals";
|
|
18
16
|
import { nullableArrayZ } from "@/util/zod";
|
|
19
17
|
|
|
20
|
-
const
|
|
18
|
+
export const KV_SET_CHANNEL = "sy_range_kv_set";
|
|
19
|
+
export const KV_DELETE_CHANNEL = "sy_range_kv_delete";
|
|
20
|
+
|
|
21
|
+
export const kvPairZ = z.object({ range: keyZ, key: z.string(), value: z.string() });
|
|
21
22
|
export interface KVPair extends z.infer<typeof kvPairZ> {}
|
|
22
23
|
|
|
23
24
|
const getReqZ = z.object({ range: keyZ, keys: z.string().array() });
|
|
@@ -37,12 +38,10 @@ export class KV {
|
|
|
37
38
|
private static readonly DELETE_ENDPOINT = "/range/kv/delete";
|
|
38
39
|
private readonly rangeKey: Key;
|
|
39
40
|
private readonly client: UnaryClient;
|
|
40
|
-
private readonly frameClient: framer.Client;
|
|
41
41
|
|
|
42
|
-
constructor(rng: Key, client: UnaryClient
|
|
42
|
+
constructor(rng: Key, client: UnaryClient) {
|
|
43
43
|
this.rangeKey = rng;
|
|
44
44
|
this.client = client;
|
|
45
|
-
this.frameClient = frameClient;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
async get(key: string): Promise<string>;
|
|
@@ -92,24 +91,4 @@ export class KV {
|
|
|
92
91
|
z.unknown(),
|
|
93
92
|
);
|
|
94
93
|
}
|
|
95
|
-
|
|
96
|
-
async openTracker(): Promise<signals.Observable<string, KVPair>> {
|
|
97
|
-
return await signals.openObservable<string, KVPair>(
|
|
98
|
-
this.frameClient,
|
|
99
|
-
"sy_range_kv_set",
|
|
100
|
-
"sy_range_kv_delete",
|
|
101
|
-
(variant, data) => {
|
|
102
|
-
if (variant === "delete")
|
|
103
|
-
return data.toStrings().map((combinedKey) => {
|
|
104
|
-
const [range, key] = combinedKey.split("<--->", 2);
|
|
105
|
-
return { variant, key: combinedKey, value: { range, key, value: "" } };
|
|
106
|
-
});
|
|
107
|
-
return data.parseJSON(kvPairZ).map((pair) => ({
|
|
108
|
-
variant,
|
|
109
|
-
key: `${pair.range}${pair.key}`,
|
|
110
|
-
value: pair,
|
|
111
|
-
}));
|
|
112
|
-
},
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
94
|
}
|
package/src/ranger/payload.ts
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
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 { array } from "@synnaxlabs/x/array";
|
|
11
10
|
import { TimeRange } from "@synnaxlabs/x/telem";
|
|
12
|
-
import { z } from "zod
|
|
11
|
+
import { z } from "zod";
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
import { label } from "@/label";
|
|
14
|
+
import { nullableArrayZ } from "@/util/zod";
|
|
15
|
+
|
|
16
|
+
export const keyZ = z.uuid();
|
|
15
17
|
export type Key = z.infer<typeof keyZ>;
|
|
16
18
|
export const nameZ = z.string().min(1);
|
|
17
19
|
export type Name = z.infer<typeof nameZ>;
|
|
@@ -24,40 +26,22 @@ export const payloadZ = z.object({
|
|
|
24
26
|
name: nameZ,
|
|
25
27
|
timeRange: TimeRange.z,
|
|
26
28
|
color: z.string().optional(),
|
|
29
|
+
labels: nullableArrayZ(label.labelZ),
|
|
30
|
+
get parent(): z.ZodUnion<readonly [z.ZodNull, typeof payloadZ]> {
|
|
31
|
+
// Using as unknown is bad, but unfortunately resolving the output type of this
|
|
32
|
+
// transform is nearly impossible.
|
|
33
|
+
return payloadZ
|
|
34
|
+
.optional()
|
|
35
|
+
.nullable()
|
|
36
|
+
.transform((p) => (p === undefined ? null : p)) as unknown as z.ZodUnion<
|
|
37
|
+
readonly [z.ZodNull, typeof payloadZ]
|
|
38
|
+
>;
|
|
39
|
+
},
|
|
27
40
|
});
|
|
28
|
-
export interface Payload extends z.infer<typeof payloadZ> {}
|
|
29
|
-
|
|
30
|
-
export const newZ = payloadZ.partial({ key: true });
|
|
31
|
-
export interface New extends z.input<typeof newZ> {}
|
|
32
41
|
|
|
33
|
-
export type
|
|
34
|
-
| { single: true; variant: "keys"; normalized: Keys; actual: Key; empty: never }
|
|
35
|
-
| { single: true; variant: "names"; normalized: Names; actual: Name; empty: never }
|
|
36
|
-
| { single: false; variant: "keys"; normalized: Keys; actual: Keys; empty: boolean }
|
|
37
|
-
| {
|
|
38
|
-
single: false;
|
|
39
|
-
variant: "names";
|
|
40
|
-
normalized: Names;
|
|
41
|
-
actual: Names;
|
|
42
|
-
empty: boolean;
|
|
43
|
-
};
|
|
42
|
+
export type Payload = z.infer<typeof payloadZ>;
|
|
44
43
|
|
|
45
|
-
export const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (!empty) isKey = keyZ.safeParse(normal[0]).success;
|
|
50
|
-
return {
|
|
51
|
-
single: !Array.isArray(ranges),
|
|
52
|
-
variant: isKey ? "keys" : "names",
|
|
53
|
-
normalized: normal,
|
|
54
|
-
actual: ranges,
|
|
55
|
-
empty,
|
|
56
|
-
} as ParamAnalysisResult;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export const ONTOLOGY_TYPE = "range";
|
|
60
|
-
export type OntologyType = typeof ONTOLOGY_TYPE;
|
|
61
|
-
|
|
62
|
-
export const ALIAS_ONTOLOGY_TYPE = "range-alias";
|
|
63
|
-
export type AliasOntologyType = typeof ALIAS_ONTOLOGY_TYPE;
|
|
44
|
+
export const newZ = payloadZ
|
|
45
|
+
.omit({ parent: true, labels: true })
|
|
46
|
+
.partial({ key: true });
|
|
47
|
+
export interface New extends z.input<typeof newZ> {}
|