@synnaxlabs/client 0.17.2 → 0.17.4
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 +5 -5
- package/README.md +1 -1
- package/dist/channel/client.d.ts +3 -3
- package/dist/channel/retriever.d.ts +1 -0
- package/dist/client.cjs +26 -10
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +4225 -4103
- package/dist/client.js.map +1 -1
- package/dist/framer/adapter.d.ts +10 -8
- package/dist/framer/adapter.spec.d.ts +1 -0
- package/dist/framer/client.d.ts +2 -2
- package/dist/framer/frame.d.ts +1 -1
- package/dist/framer/writer.d.ts +4 -3
- package/dist/index.d.ts +1 -1
- package/dist/util/telem.d.ts +2 -2
- package/examples/node/liveStream.js +41 -0
- package/examples/node/package-lock.json +4 -4
- package/examples/node/package.json +1 -1
- package/examples/node/streamWrite.js +0 -1
- package/package.json +4 -3
- package/src/channel/client.ts +7 -4
- package/src/channel/retriever.ts +35 -8
- package/src/framer/adapter.spec.ts +118 -0
- package/src/framer/adapter.ts +104 -45
- package/src/framer/client.ts +2 -6
- package/src/framer/frame.ts +12 -4
- package/src/framer/iterator.ts +4 -4
- package/src/framer/streamer.ts +4 -4
- package/src/framer/writer.spec.ts +1 -1
- package/src/framer/writer.ts +19 -16
- package/src/index.ts +1 -1
- package/src/util/telem.ts +2 -2
package/src/framer/client.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { type StreamClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import {
|
|
12
|
-
type
|
|
12
|
+
type TypedArray,
|
|
13
13
|
type Series,
|
|
14
14
|
type TimeRange,
|
|
15
15
|
type CrudeTimeStamp,
|
|
@@ -84,11 +84,7 @@ export class Client {
|
|
|
84
84
|
* data type as the channel.
|
|
85
85
|
* @throws if the channel does not exist.
|
|
86
86
|
*/
|
|
87
|
-
async write(
|
|
88
|
-
to: KeyOrName,
|
|
89
|
-
start: CrudeTimeStamp,
|
|
90
|
-
data: NativeTypedArray,
|
|
91
|
-
): Promise<void> {
|
|
87
|
+
async write(to: KeyOrName, start: CrudeTimeStamp, data: TypedArray): Promise<void> {
|
|
92
88
|
const w = await this.newWriter({
|
|
93
89
|
start,
|
|
94
90
|
channels: to,
|
package/src/framer/frame.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
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
Size,
|
|
12
|
+
Series,
|
|
13
|
+
TimeRange,
|
|
14
|
+
toArray,
|
|
15
|
+
DataType,
|
|
16
|
+
unique,
|
|
17
|
+
TimeStamp,
|
|
18
|
+
} from "@synnaxlabs/x";
|
|
11
19
|
import { z } from "zod";
|
|
12
20
|
|
|
13
21
|
import {
|
|
@@ -59,7 +67,7 @@ export type CrudeFrame =
|
|
|
59
67
|
*
|
|
60
68
|
* - A frame is weakly aligned if it meets the time range occupied by all arrays of a
|
|
61
69
|
* particular channel is the same for all channels in the frame. This means that the
|
|
62
|
-
* arrays for a particular channel can have gaps
|
|
70
|
+
* arrays for a particular channel can have gaps between them.
|
|
63
71
|
*
|
|
64
72
|
* - A strongly aligned frame means that all channels share the same rate/index and
|
|
65
73
|
* there are no gaps in time between arrays. Strongly aligned frames are natural
|
|
@@ -113,7 +121,7 @@ export class Frame {
|
|
|
113
121
|
Object.entries(columnsOrData).forEach(([k, v]) => {
|
|
114
122
|
const key = parseInt(k);
|
|
115
123
|
if (!isNaN(key)) return this.push(key, ...toArray(v));
|
|
116
|
-
else this.push(k, ...toArray(v))
|
|
124
|
+
else this.push(k, ...toArray(v));
|
|
117
125
|
});
|
|
118
126
|
return;
|
|
119
127
|
}
|
|
@@ -403,7 +411,7 @@ export type FramePayload = z.infer<typeof frameZ>;
|
|
|
403
411
|
|
|
404
412
|
export const seriesFromPayload = (series: SeriesPayload): Series => {
|
|
405
413
|
const { dataType, data, timeRange, alignment } = series;
|
|
406
|
-
return new Series({data, dataType, timeRange, glBufferUsage: "static", alignment});
|
|
414
|
+
return new Series({ data, dataType, timeRange, glBufferUsage: "static", alignment });
|
|
407
415
|
};
|
|
408
416
|
|
|
409
417
|
export const seriesToPayload = (series: Series): SeriesPayload => {
|
package/src/framer/iterator.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { z } from "zod";
|
|
|
19
19
|
|
|
20
20
|
import { type Params } from "@/channel/payload";
|
|
21
21
|
import { type Retriever } from "@/channel/retriever";
|
|
22
|
-
import {
|
|
22
|
+
import { ReadFrameAdapter } from "@/framer/adapter";
|
|
23
23
|
import { Frame, frameZ } from "@/framer/frame";
|
|
24
24
|
import { StreamProxy } from "@/framer/streamProxy";
|
|
25
25
|
|
|
@@ -72,12 +72,12 @@ const resZ = z.object({
|
|
|
72
72
|
export class Iterator {
|
|
73
73
|
private static readonly ENDPOINT = "/frame/iterate";
|
|
74
74
|
private readonly stream: StreamProxy<typeof reqZ, typeof resZ>;
|
|
75
|
-
private readonly adapter:
|
|
75
|
+
private readonly adapter: ReadFrameAdapter;
|
|
76
76
|
value: Frame;
|
|
77
77
|
|
|
78
78
|
private constructor(
|
|
79
79
|
stream: Stream<typeof reqZ, typeof resZ>,
|
|
80
|
-
adapter:
|
|
80
|
+
adapter: ReadFrameAdapter,
|
|
81
81
|
) {
|
|
82
82
|
this.stream = new StreamProxy("Iterator", stream);
|
|
83
83
|
this.value = new Frame();
|
|
@@ -97,7 +97,7 @@ export class Iterator {
|
|
|
97
97
|
retriever: Retriever,
|
|
98
98
|
client: StreamClient,
|
|
99
99
|
): Promise<Iterator> {
|
|
100
|
-
const adapter = await
|
|
100
|
+
const adapter = await ReadFrameAdapter.open(retriever, channels);
|
|
101
101
|
const stream = await client.stream(Iterator.ENDPOINT, reqZ, resZ);
|
|
102
102
|
const iter = new Iterator(stream, adapter);
|
|
103
103
|
await iter.execute({ command: Command.Open, keys: adapter.keys, bounds: tr });
|
package/src/framer/streamer.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { z } from "zod";
|
|
|
13
13
|
|
|
14
14
|
import { type Key, type Params } from "@/channel/payload";
|
|
15
15
|
import { type Retriever } from "@/channel/retriever";
|
|
16
|
-
import {
|
|
16
|
+
import { ReadFrameAdapter } from "@/framer/adapter";
|
|
17
17
|
import { Frame, frameZ } from "@/framer/frame";
|
|
18
18
|
import { StreamProxy } from "@/framer/streamProxy";
|
|
19
19
|
|
|
@@ -31,11 +31,11 @@ const ENDPOINT = "/frame/stream";
|
|
|
31
31
|
|
|
32
32
|
export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
|
|
33
33
|
private readonly stream: StreamProxy<typeof reqZ, typeof resZ>;
|
|
34
|
-
private readonly adapter:
|
|
34
|
+
private readonly adapter: ReadFrameAdapter;
|
|
35
35
|
|
|
36
36
|
private constructor(
|
|
37
37
|
stream: Stream<typeof reqZ, typeof resZ>,
|
|
38
|
-
adapter:
|
|
38
|
+
adapter: ReadFrameAdapter,
|
|
39
39
|
) {
|
|
40
40
|
this.stream = new StreamProxy("Streamer", stream);
|
|
41
41
|
this.adapter = adapter;
|
|
@@ -51,7 +51,7 @@ export class Streamer implements AsyncIterator<Frame>, AsyncIterable<Frame> {
|
|
|
51
51
|
retriever: Retriever,
|
|
52
52
|
client: StreamClient,
|
|
53
53
|
): Promise<Streamer> {
|
|
54
|
-
const adapter = await
|
|
54
|
+
const adapter = await ReadFrameAdapter.open(retriever, channels);
|
|
55
55
|
const stream = await client.stream(ENDPOINT, reqZ, resZ);
|
|
56
56
|
const streamer = new Streamer(stream, adapter);
|
|
57
57
|
stream.send({ start: new TimeStamp(start), keys: adapter.keys });
|
|
@@ -43,7 +43,7 @@ describe("Writer", () => {
|
|
|
43
43
|
const writer = await client.telem.newWriter({ start: 0, channels: ch.key });
|
|
44
44
|
await expect(
|
|
45
45
|
writer.write("billy bob", randomSeries(10, DataType.FLOAT64)),
|
|
46
|
-
).rejects.toThrow("Channel billy bob
|
|
46
|
+
).rejects.toThrow("Channel billy bob not found");
|
|
47
47
|
await writer.close();
|
|
48
48
|
});
|
|
49
49
|
test("stream when mode is set ot persist only", async () => {
|
package/src/framer/writer.ts
CHANGED
|
@@ -11,23 +11,27 @@
|
|
|
11
11
|
import type { Stream, StreamClient } from "@synnaxlabs/freighter";
|
|
12
12
|
import { decodeError, errorZ } from "@synnaxlabs/freighter";
|
|
13
13
|
import {
|
|
14
|
-
type NativeTypedArray,
|
|
15
|
-
Series,
|
|
16
14
|
TimeStamp,
|
|
17
15
|
type CrudeTimeStamp,
|
|
18
16
|
toArray,
|
|
17
|
+
type CrudeSeries,
|
|
19
18
|
} from "@synnaxlabs/x";
|
|
20
19
|
import { z } from "zod";
|
|
21
20
|
|
|
22
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
type KeysOrNames,
|
|
23
|
+
type Key,
|
|
24
|
+
type KeyOrName,
|
|
25
|
+
type Params,
|
|
26
|
+
} from "@/channel/payload";
|
|
23
27
|
import { type Retriever } from "@/channel/retriever";
|
|
24
28
|
import { Authority } from "@/control/authority";
|
|
25
29
|
import {
|
|
26
30
|
subjectZ as controlSubjectZ,
|
|
27
31
|
type Subject as ControlSubject,
|
|
28
32
|
} from "@/control/state";
|
|
29
|
-
import {
|
|
30
|
-
import { type CrudeFrame
|
|
33
|
+
import { WriteFrameAdapter } from "@/framer/adapter";
|
|
34
|
+
import { frameZ, type CrudeFrame } from "@/framer/frame";
|
|
31
35
|
import { StreamProxy } from "@/framer/streamProxy";
|
|
32
36
|
|
|
33
37
|
enum Command {
|
|
@@ -118,11 +122,11 @@ export interface WriterConfig {
|
|
|
118
122
|
export class Writer {
|
|
119
123
|
private static readonly ENDPOINT = "/frame/write";
|
|
120
124
|
private readonly stream: StreamProxy<typeof reqZ, typeof resZ>;
|
|
121
|
-
private readonly adapter:
|
|
125
|
+
private readonly adapter: WriteFrameAdapter;
|
|
122
126
|
|
|
123
127
|
private constructor(
|
|
124
128
|
stream: Stream<typeof reqZ, typeof resZ>,
|
|
125
|
-
adapter:
|
|
129
|
+
adapter: WriteFrameAdapter,
|
|
126
130
|
) {
|
|
127
131
|
this.stream = new StreamProxy("Writer", stream);
|
|
128
132
|
this.adapter = adapter;
|
|
@@ -139,7 +143,7 @@ export class Writer {
|
|
|
139
143
|
mode,
|
|
140
144
|
}: WriterConfig,
|
|
141
145
|
): Promise<Writer> {
|
|
142
|
-
const adapter = await
|
|
146
|
+
const adapter = await WriteFrameAdapter.open(retriever, channels);
|
|
143
147
|
const stream = await client.stream(Writer.ENDPOINT, reqZ, resZ);
|
|
144
148
|
const writer = new Writer(stream, adapter);
|
|
145
149
|
await writer.execute({
|
|
@@ -155,7 +159,9 @@ export class Writer {
|
|
|
155
159
|
return writer;
|
|
156
160
|
}
|
|
157
161
|
|
|
158
|
-
async write(channel: KeyOrName, data:
|
|
162
|
+
async write(channel: KeyOrName, data: CrudeSeries): Promise<boolean>;
|
|
163
|
+
|
|
164
|
+
async write(channel: KeysOrNames, data: CrudeSeries[]): Promise<boolean>;
|
|
159
165
|
|
|
160
166
|
async write(frame: CrudeFrame): Promise<boolean>;
|
|
161
167
|
|
|
@@ -174,14 +180,11 @@ export class Writer {
|
|
|
174
180
|
* should acknowledge the error by calling the error method or closing the writer.
|
|
175
181
|
*/
|
|
176
182
|
async write(
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
channelsOrData: Params | Record<KeyOrName, CrudeSeries> | CrudeFrame,
|
|
184
|
+
series?: CrudeSeries | CrudeSeries[],
|
|
179
185
|
): Promise<boolean> {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
frame = new Frame(frame, new Series({ data: data as NativeTypedArray }));
|
|
183
|
-
frame = this.adapter.adapt(new Frame(frame));
|
|
184
|
-
// @ts-expect-error
|
|
186
|
+
const frame = await this.adapter.adapt(channelsOrData, series);
|
|
187
|
+
// @ts-expect-error - zod issues
|
|
185
188
|
this.stream.send({ command: Command.Write, frame: frame.toPayload() });
|
|
186
189
|
return true;
|
|
187
190
|
}
|
package/src/index.ts
CHANGED
package/src/util/telem.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { DataType,
|
|
10
|
+
import { type DataType, type TypedArray } from "@synnaxlabs/x";
|
|
11
11
|
|
|
12
|
-
export const randomSeries = (length: number, dataType: DataType):
|
|
12
|
+
export const randomSeries = (length: number, dataType: DataType): TypedArray => {
|
|
13
13
|
// generate random bytes of the correct length
|
|
14
14
|
const bytes = new Uint8Array(length * dataType.density.valueOf());
|
|
15
15
|
for (let i = 0; i < bytes.byteLength; i++) {
|