@synnaxlabs/client 0.47.0 → 0.49.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 -7
- package/dist/client.cjs +35 -35
- package/dist/client.js +6264 -5984
- package/dist/eslint.config.d.ts +3 -2
- package/dist/eslint.config.d.ts.map +1 -1
- package/dist/src/access/client.d.ts +3 -1
- package/dist/src/access/client.d.ts.map +1 -1
- package/dist/src/access/enforce.d.ts +35 -0
- package/dist/src/access/enforce.d.ts.map +1 -0
- package/dist/src/access/enforce.spec.d.ts +2 -0
- package/dist/src/access/enforce.spec.d.ts.map +1 -0
- package/dist/src/access/external.d.ts +3 -0
- package/dist/src/access/external.d.ts.map +1 -1
- package/dist/src/access/payload.d.ts +0 -6
- package/dist/src/access/payload.d.ts.map +1 -1
- package/dist/src/access/policy/access.spec.d.ts +2 -0
- package/dist/src/access/policy/access.spec.d.ts.map +1 -0
- package/dist/src/access/policy/client.d.ts +485 -31
- package/dist/src/access/policy/client.d.ts.map +1 -1
- package/dist/src/access/policy/payload.d.ts +36 -113
- package/dist/src/access/policy/payload.d.ts.map +1 -1
- package/dist/src/access/role/client.d.ts +135 -0
- package/dist/src/access/role/client.d.ts.map +1 -0
- package/dist/src/access/role/external.d.ts.map +1 -0
- package/dist/src/access/role/index.d.ts +2 -0
- package/dist/src/access/role/index.d.ts.map +1 -0
- package/dist/src/access/role/payload.d.ts +27 -0
- package/dist/src/access/role/payload.d.ts.map +1 -0
- package/dist/src/access/role/role.spec.d.ts +2 -0
- package/dist/src/access/role/role.spec.d.ts.map +1 -0
- package/dist/src/arc/access.spec.d.ts +2 -0
- package/dist/src/arc/access.spec.d.ts.map +1 -0
- package/dist/src/arc/client.d.ts +5 -14
- package/dist/src/arc/client.d.ts.map +1 -1
- package/dist/src/arc/payload.d.ts +11 -2
- package/dist/src/arc/payload.d.ts.map +1 -1
- package/dist/src/auth/auth.d.ts +5 -3
- package/dist/src/auth/auth.d.ts.map +1 -1
- package/dist/src/channel/access.spec.d.ts +2 -0
- package/dist/src/channel/access.spec.d.ts.map +1 -0
- package/dist/src/channel/client.d.ts +0 -1
- package/dist/src/channel/client.d.ts.map +1 -1
- package/dist/src/channel/payload.d.ts +19 -8
- package/dist/src/channel/payload.d.ts.map +1 -1
- package/dist/src/channel/payload.spec.d.ts +2 -0
- package/dist/src/channel/payload.spec.d.ts.map +1 -0
- package/dist/src/channel/retriever.d.ts +4 -6
- package/dist/src/channel/retriever.d.ts.map +1 -1
- package/dist/src/channel/writer.d.ts.map +1 -1
- package/dist/src/client.d.ts +18 -10
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/connection/checker.d.ts +2 -3
- package/dist/src/connection/checker.d.ts.map +1 -1
- package/dist/src/connection.spec.d.ts +2 -0
- package/dist/src/connection.spec.d.ts.map +1 -0
- package/dist/src/device/access.spec.d.ts +2 -0
- package/dist/src/device/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/device → device}/client.d.ts +14 -7
- package/dist/src/device/client.d.ts.map +1 -0
- package/dist/src/device/device.spec.d.ts.map +1 -0
- package/dist/src/device/external.d.ts.map +1 -0
- package/dist/src/device/index.d.ts.map +1 -0
- package/dist/src/{hardware/device → device}/payload.d.ts +1 -1
- package/dist/src/device/payload.d.ts.map +1 -0
- package/dist/src/errors.d.ts +3 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/framer/adapter.d.ts +2 -2
- package/dist/src/framer/adapter.d.ts.map +1 -1
- package/dist/src/framer/client.d.ts +8 -1
- package/dist/src/framer/client.d.ts.map +1 -1
- package/dist/src/framer/frame.d.ts +11 -5
- package/dist/src/framer/frame.d.ts.map +1 -1
- package/dist/src/framer/iterator.d.ts +3 -3
- package/dist/src/framer/streamer.d.ts +24 -21
- package/dist/src/framer/streamer.d.ts.map +1 -1
- package/dist/src/framer/writer.d.ts +13 -13
- package/dist/src/index.d.ts +6 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/label/access.spec.d.ts +2 -0
- package/dist/src/label/access.spec.d.ts.map +1 -0
- package/dist/src/label/client.d.ts +20 -11
- package/dist/src/label/client.d.ts.map +1 -1
- package/dist/src/ontology/client.d.ts +6 -6
- package/dist/src/ontology/client.d.ts.map +1 -1
- package/dist/src/ontology/group/access.spec.d.ts +2 -0
- package/dist/src/ontology/group/access.spec.d.ts.map +1 -0
- package/dist/src/ontology/group/client.d.ts +2 -2
- package/dist/src/ontology/group/client.d.ts.map +1 -1
- package/dist/src/ontology/group/payload.d.ts +1 -2
- package/dist/src/ontology/group/payload.d.ts.map +1 -1
- package/dist/src/ontology/payload.d.ts +23 -17
- package/dist/src/ontology/payload.d.ts.map +1 -1
- package/dist/src/ontology/writer.d.ts +10 -10
- package/dist/src/ontology/writer.d.ts.map +1 -1
- package/dist/src/rack/access.spec.d.ts +2 -0
- package/dist/src/rack/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/rack → rack}/client.d.ts +15 -8
- package/dist/src/rack/client.d.ts.map +1 -0
- package/dist/src/rack/external.d.ts.map +1 -0
- package/dist/src/rack/index.d.ts.map +1 -0
- package/dist/src/{hardware/rack → rack}/payload.d.ts +1 -1
- package/dist/src/rack/payload.d.ts.map +1 -0
- package/dist/src/rack/rack.spec.d.ts.map +1 -0
- package/dist/src/ranger/access.spec.d.ts +2 -0
- package/dist/src/ranger/access.spec.d.ts.map +1 -0
- package/dist/src/ranger/alias.d.ts +1 -8
- package/dist/src/ranger/alias.d.ts.map +1 -1
- package/dist/src/ranger/client.d.ts +12 -5
- package/dist/src/ranger/client.d.ts.map +1 -1
- package/dist/src/ranger/kv.d.ts +0 -3
- package/dist/src/ranger/kv.d.ts.map +1 -1
- package/dist/src/ranger/writer.d.ts +2 -2
- package/dist/src/ranger/writer.d.ts.map +1 -1
- package/dist/src/status/access.spec.d.ts +2 -0
- package/dist/src/status/access.spec.d.ts.map +1 -0
- package/dist/src/status/client.d.ts +4 -4
- package/dist/src/status/client.d.ts.map +1 -1
- package/dist/src/status/payload.d.ts +9 -2
- package/dist/src/status/payload.d.ts.map +1 -1
- package/dist/src/task/access.spec.d.ts +2 -0
- package/dist/src/task/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/task → task}/client.d.ts +26 -15
- package/dist/src/task/client.d.ts.map +1 -0
- package/dist/src/task/external.d.ts +3 -0
- package/dist/src/task/external.d.ts.map +1 -0
- package/dist/src/task/index.d.ts.map +1 -0
- package/dist/src/{hardware/task → task}/payload.d.ts +45 -6
- package/dist/src/task/payload.d.ts.map +1 -0
- package/dist/src/task/task.spec.d.ts.map +1 -0
- package/dist/src/testutil/access.d.ts +4 -0
- package/dist/src/testutil/access.d.ts.map +1 -0
- package/dist/src/testutil/client.d.ts +3 -3
- package/dist/src/testutil/client.d.ts.map +1 -1
- package/dist/src/transport.d.ts.map +1 -1
- package/dist/src/user/access.spec.d.ts +2 -0
- package/dist/src/user/access.spec.d.ts.map +1 -0
- package/dist/src/user/client.d.ts +10 -1
- package/dist/src/user/client.d.ts.map +1 -1
- package/dist/src/user/external.d.ts +1 -1
- package/dist/src/user/external.d.ts.map +1 -1
- package/dist/src/user/payload.d.ts.map +1 -1
- package/dist/src/workspace/access.spec.d.ts +2 -0
- package/dist/src/workspace/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/client.d.ts +10 -5
- package/dist/src/workspace/client.d.ts.map +1 -1
- package/dist/src/workspace/lineplot/access.spec.d.ts +2 -0
- package/dist/src/workspace/lineplot/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/lineplot/client.d.ts +8 -1
- package/dist/src/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/src/workspace/log/access.spec.d.ts +2 -0
- package/dist/src/workspace/log/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/log/client.d.ts +8 -1
- package/dist/src/workspace/log/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/access.spec.d.ts +2 -0
- package/dist/src/workspace/schematic/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/schematic/client.d.ts +8 -1
- package/dist/src/workspace/schematic/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/symbol/access.spec.d.ts +2 -0
- package/dist/src/workspace/schematic/symbol/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/schematic/symbol/client.d.ts +1 -5
- package/dist/src/workspace/schematic/symbol/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/symbol/payload.d.ts +2 -2
- package/dist/src/workspace/table/access.spec.d.ts +2 -0
- package/dist/src/workspace/table/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/table/client.d.ts +8 -1
- package/dist/src/workspace/table/client.d.ts.map +1 -1
- package/eslint.config.ts +3 -1
- package/package.json +8 -8
- package/src/access/client.ts +5 -2
- package/src/access/enforce.spec.ts +189 -0
- package/src/access/enforce.ts +84 -0
- package/src/access/external.ts +3 -0
- package/src/access/payload.ts +1 -13
- package/src/access/policy/access.spec.ts +147 -0
- package/src/access/policy/client.ts +21 -25
- package/src/access/policy/payload.ts +9 -5
- package/src/access/role/client.ts +135 -0
- package/src/access/role/external.ts +11 -0
- package/src/{hardware → access/role}/index.ts +1 -1
- package/src/access/role/payload.ts +32 -0
- package/src/access/role/role.spec.ts +95 -0
- package/src/arc/access.spec.ts +143 -0
- package/src/arc/client.ts +7 -31
- package/src/arc/payload.ts +4 -0
- package/src/auth/auth.spec.ts +13 -13
- package/src/auth/auth.ts +33 -11
- package/src/channel/access.spec.ts +116 -0
- package/src/channel/channel.spec.ts +63 -73
- package/src/channel/client.ts +2 -8
- package/src/channel/payload.spec.ts +171 -0
- package/src/channel/payload.ts +37 -8
- package/src/channel/retriever.ts +10 -11
- package/src/channel/writer.ts +3 -7
- package/src/client.ts +38 -28
- package/src/connection/checker.ts +10 -10
- package/src/connection/connection.spec.ts +13 -13
- package/src/connection.spec.ts +145 -0
- package/src/device/access.spec.ts +159 -0
- package/src/{hardware/device → device}/client.ts +12 -21
- package/src/{hardware/device → device}/device.spec.ts +70 -34
- package/src/device/external.ts +11 -0
- package/src/{hardware/rack → device}/index.ts +1 -1
- package/src/{hardware/device → device}/payload.ts +3 -3
- package/src/errors.ts +2 -0
- package/src/framer/adapter.spec.ts +351 -13
- package/src/framer/adapter.ts +23 -13
- package/src/framer/client.spec.ts +14 -20
- package/src/framer/client.ts +3 -5
- package/src/framer/deleter.spec.ts +1 -1
- package/src/framer/frame.spec.ts +427 -0
- package/src/framer/frame.ts +30 -3
- package/src/framer/iterator.ts +4 -4
- package/src/framer/streamer.spec.ts +155 -10
- package/src/framer/streamer.ts +35 -12
- package/src/framer/writer.spec.ts +5 -5
- package/src/index.ts +13 -7
- package/src/label/access.spec.ts +109 -0
- package/src/label/client.ts +10 -14
- package/src/ontology/client.ts +4 -6
- package/src/ontology/group/access.spec.ts +77 -0
- package/src/ontology/group/client.ts +3 -7
- package/src/ontology/group/group.spec.ts +18 -0
- package/src/ontology/group/payload.ts +2 -2
- package/src/ontology/ontology.spec.ts +2 -0
- package/src/ontology/payload.ts +18 -2
- package/src/ontology/writer.ts +3 -7
- package/src/rack/access.spec.ts +102 -0
- package/src/{hardware/rack → rack}/client.ts +14 -19
- package/src/{hardware/device/index.ts → rack/external.ts} +2 -1
- package/src/{hardware/external.ts → rack/index.ts} +1 -1
- package/src/{hardware/rack → rack}/payload.ts +2 -2
- package/src/{hardware/rack → rack}/rack.spec.ts +43 -17
- package/src/ranger/access.spec.ts +115 -0
- package/src/ranger/alias.ts +6 -14
- package/src/ranger/client.ts +13 -14
- package/src/ranger/kv.ts +7 -9
- package/src/ranger/ranger.spec.ts +4 -4
- package/src/ranger/writer.ts +3 -7
- package/src/status/access.spec.ts +129 -0
- package/src/status/client.ts +5 -9
- package/src/status/payload.ts +3 -2
- package/src/task/access.spec.ts +131 -0
- package/src/{hardware/task → task}/client.ts +50 -25
- package/src/task/external.ts +11 -0
- package/src/{hardware/task → task}/index.ts +1 -1
- package/src/{hardware/task → task}/payload.ts +22 -3
- package/src/{hardware/task → task}/task.spec.ts +197 -34
- package/src/testutil/access.ts +34 -0
- package/src/testutil/channels.ts +3 -3
- package/src/testutil/client.ts +4 -4
- package/src/transport.ts +1 -3
- package/src/user/access.spec.ts +107 -0
- package/src/user/client.ts +10 -12
- package/src/user/external.ts +12 -1
- package/src/user/payload.ts +3 -5
- package/src/workspace/access.spec.ts +108 -0
- package/src/workspace/client.ts +11 -27
- package/src/workspace/lineplot/access.spec.ts +134 -0
- package/src/workspace/lineplot/client.ts +8 -13
- package/src/workspace/log/access.spec.ts +134 -0
- package/src/workspace/log/client.ts +8 -13
- package/src/workspace/schematic/access.spec.ts +134 -0
- package/src/workspace/schematic/client.ts +9 -18
- package/src/workspace/schematic/symbol/access.spec.ts +172 -0
- package/src/workspace/schematic/symbol/client.ts +6 -17
- package/src/workspace/schematic/symbol/payload.ts +1 -1
- package/src/workspace/table/access.spec.ts +134 -0
- package/src/workspace/table/client.ts +8 -13
- package/dist/src/access/policy/policy.spec.d.ts +0 -2
- package/dist/src/access/policy/policy.spec.d.ts.map +0 -1
- package/dist/src/hardware/client.d.ts +0 -10
- package/dist/src/hardware/client.d.ts.map +0 -1
- package/dist/src/hardware/device/client.d.ts.map +0 -1
- package/dist/src/hardware/device/device.spec.d.ts.map +0 -1
- package/dist/src/hardware/device/external.d.ts.map +0 -1
- package/dist/src/hardware/device/index.d.ts.map +0 -1
- package/dist/src/hardware/device/payload.d.ts.map +0 -1
- package/dist/src/hardware/external.d.ts +0 -2
- package/dist/src/hardware/external.d.ts.map +0 -1
- package/dist/src/hardware/index.d.ts +0 -2
- package/dist/src/hardware/index.d.ts.map +0 -1
- package/dist/src/hardware/rack/client.d.ts.map +0 -1
- package/dist/src/hardware/rack/external.d.ts.map +0 -1
- package/dist/src/hardware/rack/index.d.ts.map +0 -1
- package/dist/src/hardware/rack/payload.d.ts.map +0 -1
- package/dist/src/hardware/rack/rack.spec.d.ts.map +0 -1
- package/dist/src/hardware/task/client.d.ts.map +0 -1
- package/dist/src/hardware/task/external.d.ts.map +0 -1
- package/dist/src/hardware/task/index.d.ts.map +0 -1
- package/dist/src/hardware/task/payload.d.ts.map +0 -1
- package/dist/src/hardware/task/task.spec.d.ts.map +0 -1
- package/dist/src/user/retriever.d.ts +0 -16
- package/dist/src/user/retriever.d.ts.map +0 -1
- package/dist/src/user/writer.d.ts +0 -11
- package/dist/src/user/writer.d.ts.map +0 -1
- package/src/access/policy/policy.spec.ts +0 -329
- package/src/hardware/client.ts +0 -24
- package/src/hardware/device/external.ts +0 -11
- package/src/hardware/rack/external.ts +0 -11
- package/src/hardware/task/external.ts +0 -11
- package/src/user/retriever.ts +0 -41
- package/src/user/writer.ts +0 -84
- /package/dist/src/{hardware/device → access/role}/external.d.ts +0 -0
- /package/dist/src/{hardware/device → device}/device.spec.d.ts +0 -0
- /package/dist/src/{hardware/rack → device}/external.d.ts +0 -0
- /package/dist/src/{hardware/device → device}/index.d.ts +0 -0
- /package/dist/src/{hardware/task → rack}/external.d.ts +0 -0
- /package/dist/src/{hardware/rack → rack}/index.d.ts +0 -0
- /package/dist/src/{hardware/rack → rack}/rack.spec.d.ts +0 -0
- /package/dist/src/{hardware/task → task}/index.d.ts +0 -0
- /package/dist/src/{hardware/task → task}/task.spec.d.ts +0 -0
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { EOF, Unreachable } from "@synnaxlabs/freighter";
|
|
11
|
-
import { id, sleep } from "@synnaxlabs/x";
|
|
12
|
-
import { DataType, Series, TimeSpan, TimeStamp } from "@synnaxlabs/x/telem";
|
|
11
|
+
import { DataType, id, Rate, Series, sleep, TimeSpan, TimeStamp } from "@synnaxlabs/x";
|
|
13
12
|
import { describe, expect, it, test, vi } from "vitest";
|
|
14
13
|
|
|
15
14
|
import { type channel } from "@/channel";
|
|
@@ -114,11 +113,98 @@ describe("Streamer", () => {
|
|
|
114
113
|
});
|
|
115
114
|
});
|
|
116
115
|
|
|
116
|
+
describe("throttling", () => {
|
|
117
|
+
test("throttle at 60Hz", async () => {
|
|
118
|
+
const ch = await newVirtualChannel(client);
|
|
119
|
+
const streamer = await client.openStreamer({
|
|
120
|
+
channels: ch.key,
|
|
121
|
+
throttleRate: 60,
|
|
122
|
+
});
|
|
123
|
+
const writer = await client.openWriter({
|
|
124
|
+
start: TimeStamp.now(),
|
|
125
|
+
channels: ch.key,
|
|
126
|
+
});
|
|
127
|
+
try {
|
|
128
|
+
const startTime = Date.now();
|
|
129
|
+
// Write data rapidly
|
|
130
|
+
for (let i = 0; i < 10; i++) {
|
|
131
|
+
await writer.write(ch.key, new Float64Array([i]));
|
|
132
|
+
await sleep.sleep(TimeSpan.milliseconds(5));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Read frames - should be throttled
|
|
136
|
+
const receivedFrames: Frame[] = [];
|
|
137
|
+
const timeout = Date.now() + 500;
|
|
138
|
+
while (Date.now() < timeout)
|
|
139
|
+
try {
|
|
140
|
+
const frame = await Promise.race([
|
|
141
|
+
streamer.read(),
|
|
142
|
+
sleep.sleep(TimeSpan.milliseconds(100)).then(() => null),
|
|
143
|
+
]);
|
|
144
|
+
if (frame) receivedFrames.push(frame);
|
|
145
|
+
else break;
|
|
146
|
+
} catch {
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
expect(receivedFrames.length).toBeGreaterThan(0);
|
|
151
|
+
const elapsed = Date.now() - startTime;
|
|
152
|
+
// Should take at least the throttle period
|
|
153
|
+
expect(elapsed).toBeGreaterThanOrEqual(16); // ~1/60Hz
|
|
154
|
+
} finally {
|
|
155
|
+
await writer.close();
|
|
156
|
+
streamer.close();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("no throttling with rate of 0", async () => {
|
|
161
|
+
const ch = await newVirtualChannel(client);
|
|
162
|
+
const streamer = await client.openStreamer({
|
|
163
|
+
channels: ch.key,
|
|
164
|
+
throttleRate: 0,
|
|
165
|
+
});
|
|
166
|
+
const writer = await client.openWriter({
|
|
167
|
+
start: TimeStamp.now(),
|
|
168
|
+
channels: ch.key,
|
|
169
|
+
});
|
|
170
|
+
try {
|
|
171
|
+
await writer.write(ch.key, new Float64Array([1, 2, 3]));
|
|
172
|
+
const d = await streamer.read();
|
|
173
|
+
expect(Array.from(d.get(ch.key))).toEqual([1, 2, 3]);
|
|
174
|
+
} finally {
|
|
175
|
+
await writer.close();
|
|
176
|
+
streamer.close();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("combine throttling and downsampling", async () => {
|
|
181
|
+
const ch = await newVirtualChannel(client);
|
|
182
|
+
const streamer = await client.openStreamer({
|
|
183
|
+
channels: ch.key,
|
|
184
|
+
downsampleFactor: 2,
|
|
185
|
+
throttleRate: 10,
|
|
186
|
+
});
|
|
187
|
+
const writer = await client.openWriter({
|
|
188
|
+
start: TimeStamp.now(),
|
|
189
|
+
channels: ch.key,
|
|
190
|
+
});
|
|
191
|
+
try {
|
|
192
|
+
await writer.write(ch.key, new Float64Array([1, 2, 3, 4, 5, 6]));
|
|
193
|
+
const d = await streamer.read();
|
|
194
|
+
// Should be downsampled to [1, 3, 5] and throttled
|
|
195
|
+
expect(Array.from(d.get(ch.key))).toEqual([1, 3, 5]);
|
|
196
|
+
} finally {
|
|
197
|
+
await writer.close();
|
|
198
|
+
streamer.close();
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
117
203
|
describe("calculations", () => {
|
|
118
204
|
test("basic calculated channel streaming", async () => {
|
|
119
205
|
// Create a timestamp index channel
|
|
120
206
|
const timeChannel = await client.channels.create({
|
|
121
|
-
name:
|
|
207
|
+
name: id.create(),
|
|
122
208
|
isIndex: true,
|
|
123
209
|
dataType: DataType.TIMESTAMP,
|
|
124
210
|
});
|
|
@@ -139,7 +225,7 @@ describe("Streamer", () => {
|
|
|
139
225
|
|
|
140
226
|
// Create calculated channel that adds the two source channels
|
|
141
227
|
const calcChannel = await client.channels.create({
|
|
142
|
-
name:
|
|
228
|
+
name: id.create(),
|
|
143
229
|
dataType: DataType.FLOAT64,
|
|
144
230
|
virtual: true,
|
|
145
231
|
expression: `return ${channelA.name} + ${channelB.name}`,
|
|
@@ -175,6 +261,7 @@ describe("Streamer", () => {
|
|
|
175
261
|
streamer.close();
|
|
176
262
|
}
|
|
177
263
|
});
|
|
264
|
+
|
|
178
265
|
test("calculated channel with constant", async () => {
|
|
179
266
|
// Create an index channel for timestamps
|
|
180
267
|
const timeChannel = await client.channels.create({
|
|
@@ -192,7 +279,7 @@ describe("Streamer", () => {
|
|
|
192
279
|
|
|
193
280
|
// Create calculated channel that adds 5
|
|
194
281
|
const calcChannel = await client.channels.create({
|
|
195
|
-
name:
|
|
282
|
+
name: id.create(),
|
|
196
283
|
dataType: DataType.FLOAT64,
|
|
197
284
|
virtual: true,
|
|
198
285
|
expression: `return ${baseChannel.name} + 5`,
|
|
@@ -231,23 +318,24 @@ describe("Streamer", () => {
|
|
|
231
318
|
test("calculated channel with multiple operations", async () => {
|
|
232
319
|
// Create timestamp channel
|
|
233
320
|
const timeChannel = await client.channels.create({
|
|
234
|
-
name:
|
|
321
|
+
name: id.create(),
|
|
235
322
|
isIndex: true,
|
|
236
323
|
dataType: DataType.TIMESTAMP,
|
|
237
324
|
});
|
|
238
325
|
|
|
239
326
|
// Create source channels
|
|
327
|
+
const names = [id.create(), id.create()];
|
|
240
328
|
const [channelA, channelB] = await client.channels.create([
|
|
241
|
-
{ name:
|
|
242
|
-
{ name:
|
|
329
|
+
{ name: names[0], dataType: DataType.FLOAT64, index: timeChannel.key },
|
|
330
|
+
{ name: names[1], dataType: DataType.FLOAT64, index: timeChannel.key },
|
|
243
331
|
]);
|
|
244
332
|
|
|
245
333
|
// Create calculated channel with multiple operations
|
|
246
334
|
const calcChannel = await client.channels.create({
|
|
247
|
-
name:
|
|
335
|
+
name: id.create(),
|
|
248
336
|
dataType: DataType.FLOAT64,
|
|
249
337
|
virtual: true,
|
|
250
|
-
expression:
|
|
338
|
+
expression: `return (${names[0]} * 2) + (${names[1]} / 2)`,
|
|
251
339
|
});
|
|
252
340
|
|
|
253
341
|
const streamer = await client.openStreamer(calcChannel.key);
|
|
@@ -274,6 +362,62 @@ describe("Streamer", () => {
|
|
|
274
362
|
streamer.close();
|
|
275
363
|
}
|
|
276
364
|
});
|
|
365
|
+
|
|
366
|
+
describe("legacy calculations", async () => {
|
|
367
|
+
it("should correctly execute a calculation with a requires field", async () => {
|
|
368
|
+
const timeChannel = await client.channels.create({
|
|
369
|
+
name: id.create(),
|
|
370
|
+
isIndex: true,
|
|
371
|
+
dataType: DataType.TIMESTAMP,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
const [channelA, channelB] = await client.channels.create([
|
|
375
|
+
{
|
|
376
|
+
name: id.create(),
|
|
377
|
+
dataType: DataType.FLOAT64,
|
|
378
|
+
index: timeChannel.key,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: id.create(),
|
|
382
|
+
dataType: DataType.FLOAT64,
|
|
383
|
+
index: timeChannel.key,
|
|
384
|
+
},
|
|
385
|
+
]);
|
|
386
|
+
|
|
387
|
+
const calcChannel = await client.channels.create({
|
|
388
|
+
name: id.create(),
|
|
389
|
+
dataType: DataType.FLOAT64,
|
|
390
|
+
virtual: true,
|
|
391
|
+
expression: `return ${channelA.name} + ${channelB.name}`,
|
|
392
|
+
requires: [channelA.key, channelB.key],
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const streamer = await client.openStreamer(calcChannel.key);
|
|
396
|
+
await sleep.sleep(TimeSpan.milliseconds(10));
|
|
397
|
+
|
|
398
|
+
const startTime = TimeStamp.now();
|
|
399
|
+
const writer = await client.openWriter({
|
|
400
|
+
start: startTime,
|
|
401
|
+
channels: [timeChannel.key, channelA.key, channelB.key],
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
await writer.write({
|
|
406
|
+
[timeChannel.key]: [startTime],
|
|
407
|
+
[channelA.key]: new Float64Array([2.5]),
|
|
408
|
+
[channelB.key]: new Float64Array([2.5]),
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const frame = await streamer.read();
|
|
412
|
+
|
|
413
|
+
const calcData = Array.from(frame.get(calcChannel.key));
|
|
414
|
+
expect(calcData).toEqual([5.0]);
|
|
415
|
+
} finally {
|
|
416
|
+
await writer.close();
|
|
417
|
+
streamer.close();
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
});
|
|
277
421
|
});
|
|
278
422
|
});
|
|
279
423
|
|
|
@@ -341,6 +485,7 @@ describe("Streamer", () => {
|
|
|
341
485
|
expect(openMock).toHaveBeenCalledWith({
|
|
342
486
|
...config,
|
|
343
487
|
downsampleFactor: 1,
|
|
488
|
+
throttleRate: new Rate(0),
|
|
344
489
|
});
|
|
345
490
|
await hardened.update([1, 2, 3]);
|
|
346
491
|
expect(streamer.updateMock).toHaveBeenCalledWith([1, 2, 3]);
|
package/src/framer/streamer.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { EOF, type Stream, type WebSocketClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { breaker, observe, TimeSpan } from "@synnaxlabs/x";
|
|
11
|
+
import { breaker, observe, Rate, TimeSpan } from "@synnaxlabs/x";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
14
|
import { type channel } from "@/channel";
|
|
@@ -18,7 +18,11 @@ import { WSStreamerCodec } from "@/framer/codec";
|
|
|
18
18
|
import { Frame, frameZ } from "@/framer/frame";
|
|
19
19
|
import { StreamProxy } from "@/framer/streamProxy";
|
|
20
20
|
|
|
21
|
-
const reqZ = z.object({
|
|
21
|
+
const reqZ = z.object({
|
|
22
|
+
keys: z.number().array(),
|
|
23
|
+
downsampleFactor: z.int(),
|
|
24
|
+
throttleRate: Rate.z.optional(),
|
|
25
|
+
});
|
|
22
26
|
|
|
23
27
|
/**
|
|
24
28
|
* Request interface for streaming frames from a Synnax cluster.
|
|
@@ -38,10 +42,12 @@ const intermediateStreamerConfigZ = z.object({
|
|
|
38
42
|
/** The channels to stream data from. Can be channel keys, names, or payloads. */
|
|
39
43
|
channels: paramsZ,
|
|
40
44
|
/** Optional factor to downsample the data by. Defaults to 1 (no downsampling). */
|
|
41
|
-
downsampleFactor: z.
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
useHighPerformanceCodec
|
|
45
|
+
downsampleFactor: z.int().default(1),
|
|
46
|
+
/** Optional throttle rate in Hz to limit the rate of frames sent to the client. Defaults to 0 (no throttling). */
|
|
47
|
+
throttleRate: Rate.z.default(new Rate(0)),
|
|
48
|
+
/** useHighPerformanceCodec sets whether the writer will use the Synnax frame encoder
|
|
49
|
+
as opposed to the standard JSON encoding mechanisms for frames. */
|
|
50
|
+
useHighPerformanceCodec: z.boolean().default(true),
|
|
45
51
|
});
|
|
46
52
|
|
|
47
53
|
export const streamerConfigZ = intermediateStreamerConfigZ.or(
|
|
@@ -105,8 +111,17 @@ export const createStreamOpener =
|
|
|
105
111
|
if (cfg.useHighPerformanceCodec)
|
|
106
112
|
client = client.withCodec(new WSStreamerCodec(adapter.codec));
|
|
107
113
|
const stream = await client.stream("/frame/stream", reqZ, resZ);
|
|
108
|
-
const streamer = new CoreStreamer(
|
|
109
|
-
|
|
114
|
+
const streamer = new CoreStreamer(
|
|
115
|
+
stream,
|
|
116
|
+
adapter,
|
|
117
|
+
cfg.downsampleFactor,
|
|
118
|
+
cfg.throttleRate,
|
|
119
|
+
);
|
|
120
|
+
stream.send({
|
|
121
|
+
keys: Array.from(adapter.keys),
|
|
122
|
+
downsampleFactor: cfg.downsampleFactor,
|
|
123
|
+
throttleRate: cfg.throttleRate,
|
|
124
|
+
});
|
|
110
125
|
const [, err] = await stream.receive();
|
|
111
126
|
if (err != null) throw err;
|
|
112
127
|
return streamer;
|
|
@@ -129,15 +144,22 @@ class CoreStreamer implements Streamer {
|
|
|
129
144
|
private readonly stream: StreamProxy<typeof reqZ, typeof resZ>;
|
|
130
145
|
private readonly adapter: ReadAdapter;
|
|
131
146
|
private readonly downsampleFactor: number;
|
|
147
|
+
private readonly throttleRate: Rate;
|
|
132
148
|
|
|
133
|
-
constructor(
|
|
149
|
+
constructor(
|
|
150
|
+
stream: Stream<typeof reqZ, typeof resZ>,
|
|
151
|
+
adapter: ReadAdapter,
|
|
152
|
+
downsampleFactor: number = 1,
|
|
153
|
+
throttleRate: Rate = new Rate(0),
|
|
154
|
+
) {
|
|
134
155
|
this.stream = new StreamProxy("Streamer", stream);
|
|
135
156
|
this.adapter = adapter;
|
|
136
|
-
this.downsampleFactor =
|
|
157
|
+
this.downsampleFactor = downsampleFactor;
|
|
158
|
+
this.throttleRate = throttleRate;
|
|
137
159
|
}
|
|
138
160
|
|
|
139
161
|
get keys(): channel.Key[] {
|
|
140
|
-
return this.adapter.keys;
|
|
162
|
+
return Array.from(this.adapter.keys);
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
async next(): Promise<IteratorResult<Frame, any>> {
|
|
@@ -158,8 +180,9 @@ class CoreStreamer implements Streamer {
|
|
|
158
180
|
const hasChanged = await this.adapter.update(channels);
|
|
159
181
|
if (!hasChanged) return;
|
|
160
182
|
this.stream.send({
|
|
161
|
-
keys: this.adapter.keys,
|
|
183
|
+
keys: Array.from(this.adapter.keys),
|
|
162
184
|
downsampleFactor: this.downsampleFactor,
|
|
185
|
+
throttleRate: this.throttleRate,
|
|
163
186
|
});
|
|
164
187
|
}
|
|
165
188
|
|
|
@@ -7,7 +7,7 @@
|
|
|
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 { DataType, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x";
|
|
10
|
+
import { DataType, id, TimeRange, TimeSpan, TimeStamp } from "@synnaxlabs/x";
|
|
11
11
|
import { describe, expect, it, test } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { UnauthorizedError, ValidationError } from "@/errors";
|
|
@@ -42,8 +42,8 @@ describe("Writer", () => {
|
|
|
42
42
|
const channels = await newIndexedPair(client);
|
|
43
43
|
const writer = await client.openWriter({ start: TimeStamp.now(), channels });
|
|
44
44
|
await expect(
|
|
45
|
-
writer.write("
|
|
46
|
-
).rejects.toThrow('Channel "
|
|
45
|
+
writer.write("nonexistent_channel", randomSeries(10, DataType.FLOAT64)),
|
|
46
|
+
).rejects.toThrow('Channel "nonexistent_channel" not found');
|
|
47
47
|
await writer.close();
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -152,13 +152,13 @@ describe("Writer", () => {
|
|
|
152
152
|
|
|
153
153
|
test("write with out of order timestamp", async () => {
|
|
154
154
|
const indexCh = await client.channels.create({
|
|
155
|
-
name:
|
|
155
|
+
name: id.create(),
|
|
156
156
|
dataType: DataType.TIMESTAMP,
|
|
157
157
|
isIndex: true,
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
const dataCh = await client.channels.create({
|
|
161
|
-
name:
|
|
161
|
+
name: id.create(),
|
|
162
162
|
dataType: DataType.FLOAT64,
|
|
163
163
|
index: indexCh.key,
|
|
164
164
|
});
|
package/src/index.ts
CHANGED
|
@@ -8,13 +8,20 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
export { access } from "@/access";
|
|
11
|
-
export { policy } from "@/access/policy";
|
|
12
11
|
export { arc } from "@/arc";
|
|
13
12
|
export { channel } from "@/channel";
|
|
14
13
|
export { Channel, isCalculated } from "@/channel/client";
|
|
15
|
-
export {
|
|
14
|
+
export {
|
|
15
|
+
checkConnection,
|
|
16
|
+
type CheckConnectionParams,
|
|
17
|
+
newConnectionChecker,
|
|
18
|
+
default as Synnax,
|
|
19
|
+
type SynnaxParams,
|
|
20
|
+
synnaxParamsZ,
|
|
21
|
+
} from "@/client";
|
|
16
22
|
export * from "@/connection";
|
|
17
23
|
export { control } from "@/control";
|
|
24
|
+
export { device } from "@/device";
|
|
18
25
|
export {
|
|
19
26
|
AuthError,
|
|
20
27
|
ContiguityError,
|
|
@@ -28,16 +35,15 @@ export {
|
|
|
28
35
|
} from "@/errors";
|
|
29
36
|
export { framer } from "@/framer";
|
|
30
37
|
export { Frame } from "@/framer/frame";
|
|
31
|
-
export { hardware } from "@/hardware";
|
|
32
|
-
export { device } from "@/hardware/device";
|
|
33
|
-
export { rack } from "@/hardware/rack";
|
|
34
|
-
export { task } from "@/hardware/task";
|
|
35
38
|
export { label } from "@/label";
|
|
36
39
|
export { ontology } from "@/ontology";
|
|
37
40
|
export { group } from "@/ontology/group";
|
|
41
|
+
export { rack } from "@/rack";
|
|
38
42
|
export { ranger } from "@/ranger";
|
|
39
43
|
export { status } from "@/status";
|
|
40
|
-
export {
|
|
44
|
+
export { task } from "@/task";
|
|
45
|
+
export { createTestClientWithPolicy } from "@/testutil/access";
|
|
46
|
+
export { createTestClient, TEST_CLIENT_PARAMS } from "@/testutil/client";
|
|
41
47
|
export { user } from "@/user";
|
|
42
48
|
export { workspace } from "@/workspace";
|
|
43
49
|
export { lineplot } from "@/workspace/lineplot";
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright 2025 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 { describe, expect, it } from "vitest";
|
|
11
|
+
|
|
12
|
+
import { AuthError, NotFoundError } from "@/errors";
|
|
13
|
+
import { label } from "@/label";
|
|
14
|
+
import { createTestClientWithPolicy } from "@/testutil/access";
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
|
+
|
|
17
|
+
const client = createTestClient();
|
|
18
|
+
|
|
19
|
+
describe("label", () => {
|
|
20
|
+
describe("access control", () => {
|
|
21
|
+
it("should deny access when no retrieve policy exists", async () => {
|
|
22
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
23
|
+
name: "test",
|
|
24
|
+
objects: [],
|
|
25
|
+
actions: [],
|
|
26
|
+
});
|
|
27
|
+
const randomLabel = await client.labels.create({
|
|
28
|
+
name: "test",
|
|
29
|
+
color: "#E774D0",
|
|
30
|
+
});
|
|
31
|
+
await expect(
|
|
32
|
+
userClient.labels.retrieve({ key: randomLabel.key }),
|
|
33
|
+
).rejects.toThrow(AuthError);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should allow the caller to retrieve labels with the correct policy", async () => {
|
|
37
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
38
|
+
name: "test",
|
|
39
|
+
objects: [label.ontologyID("")],
|
|
40
|
+
actions: ["retrieve"],
|
|
41
|
+
});
|
|
42
|
+
const randomLabel = await client.labels.create({
|
|
43
|
+
name: "test",
|
|
44
|
+
color: "#E774D0",
|
|
45
|
+
});
|
|
46
|
+
const retrieved = await userClient.labels.retrieve({ key: randomLabel.key });
|
|
47
|
+
expect(retrieved.key).toBe(randomLabel.key);
|
|
48
|
+
expect(retrieved.name).toBe(randomLabel.name);
|
|
49
|
+
expect(retrieved.color).toBe(randomLabel.color);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should allow the caller to create labels with the correct policy", async () => {
|
|
53
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
54
|
+
name: "test",
|
|
55
|
+
objects: [label.ontologyID("")],
|
|
56
|
+
actions: ["create"],
|
|
57
|
+
});
|
|
58
|
+
await userClient.labels.create({
|
|
59
|
+
name: "test",
|
|
60
|
+
color: "#E774D0",
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should deny access when no create policy exists", async () => {
|
|
65
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
66
|
+
name: "test",
|
|
67
|
+
objects: [label.ontologyID("")],
|
|
68
|
+
actions: [],
|
|
69
|
+
});
|
|
70
|
+
await expect(
|
|
71
|
+
userClient.labels.create({
|
|
72
|
+
name: "test",
|
|
73
|
+
color: "#E774D0",
|
|
74
|
+
}),
|
|
75
|
+
).rejects.toThrow(AuthError);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should allow the caller to delete labels with the correct policy", async () => {
|
|
79
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
80
|
+
name: "test",
|
|
81
|
+
objects: [label.ontologyID("")],
|
|
82
|
+
actions: ["delete"],
|
|
83
|
+
});
|
|
84
|
+
const randomLabel = await client.labels.create({
|
|
85
|
+
name: "test",
|
|
86
|
+
color: "#E774D0",
|
|
87
|
+
});
|
|
88
|
+
await userClient.labels.delete(randomLabel.key);
|
|
89
|
+
await expect(
|
|
90
|
+
userClient.labels.retrieve({ key: randomLabel.key }),
|
|
91
|
+
).rejects.toThrow(NotFoundError);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should deny access when no delete policy exists", async () => {
|
|
95
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
96
|
+
name: "test",
|
|
97
|
+
objects: [label.ontologyID("")],
|
|
98
|
+
actions: [],
|
|
99
|
+
});
|
|
100
|
+
const randomLabel = await client.labels.create({
|
|
101
|
+
name: "test",
|
|
102
|
+
color: "#E774D0",
|
|
103
|
+
});
|
|
104
|
+
await expect(userClient.labels.delete(randomLabel.key)).rejects.toThrow(
|
|
105
|
+
AuthError,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
});
|
package/src/label/client.ts
CHANGED
|
@@ -36,18 +36,13 @@ export interface SetOptions extends Pick<SetReq, "replace"> {}
|
|
|
36
36
|
const removeReqZ = setReqZ.omit({ replace: true });
|
|
37
37
|
const emptyResZ = z.object({});
|
|
38
38
|
|
|
39
|
-
const CREATE_ENDPOINT = "/label/create";
|
|
40
|
-
const DELETE_ENDPOINT = "/label/delete";
|
|
41
|
-
const SET_ENDPOINT = "/label/set";
|
|
42
|
-
const REMOVE_ENDPOINT = "/label/remove";
|
|
43
|
-
const RETRIEVE_ENDPOINT = "/label/retrieve";
|
|
44
|
-
|
|
45
39
|
const retrieveRequestZ = z.object({
|
|
46
40
|
keys: keyZ.array().optional(),
|
|
41
|
+
names: z.string().array().optional(),
|
|
47
42
|
for: ontology.idZ.optional(),
|
|
48
43
|
searchTerm: z.string().optional(),
|
|
49
|
-
offset: z.
|
|
50
|
-
limit: z.
|
|
44
|
+
offset: z.int().optional(),
|
|
45
|
+
limit: z.int().optional(),
|
|
51
46
|
});
|
|
52
47
|
|
|
53
48
|
const singleRetrieveArgsZ = z
|
|
@@ -76,7 +71,7 @@ export class Client {
|
|
|
76
71
|
const isSingle = "key" in args;
|
|
77
72
|
const res = await sendRequired(
|
|
78
73
|
this.client,
|
|
79
|
-
|
|
74
|
+
"/label/retrieve",
|
|
80
75
|
args,
|
|
81
76
|
retrieveArgsZ,
|
|
82
77
|
retrieveResponseZ,
|
|
@@ -88,7 +83,7 @@ export class Client {
|
|
|
88
83
|
async label(id: ontology.ID, labels: Key[], opts: SetOptions = {}): Promise<void> {
|
|
89
84
|
await sendRequired<typeof setReqZ, typeof emptyResZ>(
|
|
90
85
|
this.client,
|
|
91
|
-
|
|
86
|
+
"/label/set",
|
|
92
87
|
{ id, labels, replace: opts.replace },
|
|
93
88
|
setReqZ,
|
|
94
89
|
emptyResZ,
|
|
@@ -98,7 +93,7 @@ export class Client {
|
|
|
98
93
|
async remove(id: ontology.ID, labels: Key[]): Promise<void> {
|
|
99
94
|
await sendRequired<typeof removeReqZ, typeof emptyResZ>(
|
|
100
95
|
this.client,
|
|
101
|
-
|
|
96
|
+
"/label/remove",
|
|
102
97
|
{ id, labels },
|
|
103
98
|
removeReqZ,
|
|
104
99
|
emptyResZ,
|
|
@@ -111,7 +106,7 @@ export class Client {
|
|
|
111
106
|
const isMany = Array.isArray(labels);
|
|
112
107
|
const res = await sendRequired<typeof createReqZ, typeof createResZ>(
|
|
113
108
|
this.client,
|
|
114
|
-
|
|
109
|
+
"/label/create",
|
|
115
110
|
{ labels: array.toArray(labels) },
|
|
116
111
|
createReqZ,
|
|
117
112
|
createResZ,
|
|
@@ -122,7 +117,7 @@ export class Client {
|
|
|
122
117
|
async delete(keys: Key | Key[]): Promise<void> {
|
|
123
118
|
await sendRequired<typeof deleteReqZ, typeof emptyResZ>(
|
|
124
119
|
this.client,
|
|
125
|
-
|
|
120
|
+
"/label/delete",
|
|
126
121
|
{ keys: array.toArray(keys) },
|
|
127
122
|
deleteReqZ,
|
|
128
123
|
emptyResZ,
|
|
@@ -130,4 +125,5 @@ export class Client {
|
|
|
130
125
|
}
|
|
131
126
|
}
|
|
132
127
|
|
|
133
|
-
export const ontologyID =
|
|
128
|
+
export const ontologyID = ontology.createIDFactory<Key>("label");
|
|
129
|
+
export const TYPE_ONTOLOGY_ID = ontologyID("");
|
package/src/ontology/client.ts
CHANGED
|
@@ -25,17 +25,15 @@ import {
|
|
|
25
25
|
} from "@/ontology/payload";
|
|
26
26
|
import { Writer } from "@/ontology/writer";
|
|
27
27
|
|
|
28
|
-
const RETRIEVE_ENDPOINT = "/ontology/retrieve";
|
|
29
|
-
|
|
30
28
|
const retrieveReqZ = z.object({
|
|
31
29
|
ids: idZ.array().optional(),
|
|
32
30
|
children: z.boolean().optional(),
|
|
33
31
|
parents: z.boolean().optional(),
|
|
34
32
|
excludeFieldData: z.boolean().optional(),
|
|
35
|
-
searchTerm: z.string().optional(),
|
|
36
|
-
limit: z.number().optional(),
|
|
37
|
-
offset: z.number().optional(),
|
|
38
33
|
types: resourceTypeZ.array().optional(),
|
|
34
|
+
searchTerm: z.string().optional(),
|
|
35
|
+
limit: z.int().optional(),
|
|
36
|
+
offset: z.int().optional(),
|
|
39
37
|
});
|
|
40
38
|
export interface RetrieveRequest extends z.infer<typeof retrieveReqZ> {}
|
|
41
39
|
|
|
@@ -174,7 +172,7 @@ export class Client {
|
|
|
174
172
|
private async execRetrieve(request: RetrieveRequest): Promise<Resource[]> {
|
|
175
173
|
const { resources } = await sendRequired(
|
|
176
174
|
this.client,
|
|
177
|
-
|
|
175
|
+
"/ontology/retrieve",
|
|
178
176
|
request,
|
|
179
177
|
retrieveReqZ,
|
|
180
178
|
retrieveResZ,
|