@synnaxlabs/x 0.32.0 → 0.34.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 +32 -32
- package/dist/binary.cjs +1 -1
- package/dist/binary.js +1 -1
- package/dist/bounds-CFI9wDXn.js +171 -0
- package/dist/bounds-DzCDHgdE.cjs +1 -0
- package/dist/bounds.cjs +1 -1
- package/dist/bounds.js +1 -1
- package/dist/box-DVCNGsJG.js +201 -0
- package/dist/box-Mf8E1Ypp.cjs +1 -0
- package/dist/box.cjs +1 -1
- package/dist/box.js +1 -1
- package/dist/caseconv.cjs +1 -1
- package/dist/caseconv.js +1 -1
- package/dist/compare.js +1 -1
- package/dist/deep.cjs +1 -1
- package/dist/deep.js +46 -48
- package/dist/{direction-DZbN47uL.cjs → direction-D7qoo_GJ.cjs} +1 -1
- package/dist/direction.cjs +1 -1
- package/dist/external-B3XSLDq5.cjs +1 -0
- package/dist/{external-CO221aaF.js → external-sVtvYJS6.js} +3 -3
- package/dist/{index-B5THJ1eb.js → index-BBa2mWG1.js} +1 -1
- package/dist/{index-DgaYJC35.cjs → index-CYxQwEdX.cjs} +1 -1
- package/dist/{index-B3BUDIdi.js → index-HQonyH7n.js} +1 -2
- package/dist/index-YsO0EMN8.cjs +1 -0
- package/dist/{index-Duv1uH08.js → index-eue4dSQX.js} +14 -10
- package/dist/index.cjs +2 -2
- package/dist/index.js +162 -145
- package/dist/{location-DjcaXEps.js → location-CI9x53qR.js} +8 -8
- package/dist/{location-gPB1RtfA.cjs → location-DetomF8Z.cjs} +1 -1
- package/dist/location.cjs +1 -1
- package/dist/location.js +1 -1
- package/dist/path-BBCx3K6k.cjs +1 -0
- package/dist/{path-B-1-i3qC.js → path-CmnoH3RC.js} +26 -26
- package/dist/{position-DkON65EZ.js → position-CFc9RsSn.js} +2 -2
- package/dist/{position-C71OiHiw.cjs → position-DKhPhvPh.cjs} +1 -1
- package/dist/position.cjs +1 -1
- package/dist/position.js +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +1 -1
- package/dist/{scale-COPgp55a.cjs → scale-CT61XD_X.cjs} +1 -1
- package/dist/{scale-qw6vRO4s.js → scale-DNQE1LMm.js} +25 -3
- package/dist/scale.cjs +1 -1
- package/dist/scale.js +1 -1
- package/dist/series-DWLXo7J6.cjs +11 -0
- package/dist/{series-B5eA90Ci.js → series-sjWkW8qe.js} +627 -466
- package/dist/spatial.cjs +1 -1
- package/dist/spatial.js +5 -5
- package/dist/src/binary/encoder.d.ts.map +1 -1
- package/dist/src/caseconv/caseconv.d.ts.map +1 -1
- package/dist/src/clamp/clamp.d.ts.map +1 -1
- package/dist/src/compare/compare.d.ts.map +1 -1
- package/dist/src/debounce/debounce.d.ts.map +1 -1
- package/dist/src/deep/difference.d.ts.map +1 -1
- package/dist/src/deep/merge.d.ts.map +1 -1
- package/dist/src/deep/path.d.ts +2 -2
- package/dist/src/deep/path.d.ts.map +1 -1
- package/dist/src/math/math.d.ts +26 -6
- package/dist/src/math/math.d.ts.map +1 -1
- package/dist/src/math/math.spec.d.ts +2 -0
- package/dist/src/math/math.spec.d.ts.map +1 -0
- package/dist/src/migrate/migrate.d.ts.map +1 -1
- package/dist/src/record.d.ts +4 -0
- package/dist/src/record.d.ts.map +1 -1
- package/dist/src/spatial/bounds/bounds.d.ts +208 -4
- package/dist/src/spatial/bounds/bounds.d.ts.map +1 -1
- package/dist/src/spatial/box/box.d.ts +4 -4
- package/dist/src/spatial/box/box.d.ts.map +1 -1
- package/dist/src/spatial/scale/scale.d.ts +177 -5
- package/dist/src/spatial/scale/scale.d.ts.map +1 -1
- package/dist/src/strings/strings.d.ts +14 -0
- package/dist/src/strings/strings.d.ts.map +1 -1
- package/dist/src/telem/generate.d.ts.map +1 -1
- package/dist/src/telem/series.d.ts +35 -10
- package/dist/src/telem/series.d.ts.map +1 -1
- package/dist/src/telem/telem.d.ts +12 -10
- package/dist/src/telem/telem.d.ts.map +1 -1
- package/dist/src/url/url.d.ts.map +1 -1
- package/dist/telem.cjs +1 -1
- package/dist/telem.js +1 -1
- package/dist/url.cjs +1 -1
- package/dist/url.js +1 -1
- package/dist/{zodutil-BWvwKcpb.cjs → zodutil-C6RYzvXd.cjs} +1 -1
- package/dist/{zodutil-qNM8aVYC.js → zodutil-Tmuc4CNq.js} +1 -1
- package/dist/zodutil.cjs +1 -1
- package/dist/zodutil.js +1 -1
- package/package.json +10 -9
- package/src/binary/encoder.ts +1 -2
- package/src/caseconv/caseconv.ts +8 -15
- package/src/clamp/clamp.ts +1 -1
- package/src/compare/compare.ts +1 -3
- package/src/debounce/debounce.ts +1 -2
- package/src/deep/difference.ts +3 -9
- package/src/deep/merge.ts +8 -15
- package/src/deep/path.spec.ts +1 -1
- package/src/deep/path.ts +4 -4
- package/src/math/math.spec.ts +149 -0
- package/src/math/math.ts +61 -10
- package/src/migrate/migrate.ts +4 -5
- package/src/record.ts +5 -0
- package/src/runtime/os.ts +2 -2
- package/src/spatial/bounds/bounds.spec.ts +135 -270
- package/src/spatial/bounds/bounds.ts +296 -29
- package/src/spatial/box/box.ts +13 -12
- package/src/spatial/direction/direction.ts +1 -1
- package/src/spatial/location/location.ts +5 -5
- package/src/spatial/scale/scale.ts +196 -12
- package/src/strings/strings.spec.ts +33 -1
- package/src/strings/strings.ts +52 -0
- package/src/telem/generate.ts +1 -3
- package/src/telem/series.spec.ts +235 -0
- package/src/telem/series.ts +310 -100
- package/src/telem/telem.spec.ts +27 -11
- package/src/telem/telem.ts +56 -36
- package/src/url/url.ts +9 -12
- package/src/zodutil/zodutil.spec.ts +5 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/bounds-CpboA0q6.js +0 -127
- package/dist/bounds-ZZc1c-_Z.cjs +0 -1
- package/dist/box-BQID-0jO.cjs +0 -1
- package/dist/box-xRqO6NvI.js +0 -202
- package/dist/external-B-DoBvh7.cjs +0 -1
- package/dist/index-xk130iQA.cjs +0 -1
- package/dist/path-577Fmn5N.cjs +0 -1
- package/dist/series-CJ65b1Uz.cjs +0 -11
package/src/telem/series.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { binary } from "@/binary";
|
|
|
13
13
|
import { caseconv } from "@/caseconv";
|
|
14
14
|
import { compare } from "@/compare";
|
|
15
15
|
import { id } from "@/id";
|
|
16
|
+
import { type math } from "@/math";
|
|
16
17
|
import { bounds } from "@/spatial";
|
|
17
18
|
import {
|
|
18
19
|
type GLBufferController,
|
|
@@ -25,7 +26,6 @@ import {
|
|
|
25
26
|
type CrudeTimeStamp,
|
|
26
27
|
DataType,
|
|
27
28
|
isTelemValue,
|
|
28
|
-
type NumericTelemValue,
|
|
29
29
|
type Rate,
|
|
30
30
|
Size,
|
|
31
31
|
type TelemValue,
|
|
@@ -43,10 +43,12 @@ interface GL {
|
|
|
43
43
|
bufferUsage: GLBufferUsage;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export interface IterableIterator<T> extends Iterator<T>, Iterable<T> {}
|
|
47
|
+
|
|
46
48
|
export interface SeriesDigest {
|
|
47
49
|
key: string;
|
|
48
50
|
dataType: string;
|
|
49
|
-
sampleOffset:
|
|
51
|
+
sampleOffset: math.Numeric;
|
|
50
52
|
alignment: bounds.Bounds<bigint>;
|
|
51
53
|
timeRange?: string;
|
|
52
54
|
length: number;
|
|
@@ -56,7 +58,7 @@ export interface SeriesDigest {
|
|
|
56
58
|
interface BaseSeriesProps {
|
|
57
59
|
dataType?: CrudeDataType;
|
|
58
60
|
timeRange?: TimeRange;
|
|
59
|
-
sampleOffset?:
|
|
61
|
+
sampleOffset?: math.Numeric;
|
|
60
62
|
glBufferUsage?: GLBufferUsage;
|
|
61
63
|
alignment?: bigint;
|
|
62
64
|
key?: string;
|
|
@@ -101,6 +103,11 @@ export interface SeriesMemInfo {
|
|
|
101
103
|
glBuffer: boolean;
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
const noopIterableIterator: IterableIterator<never> = {
|
|
107
|
+
[Symbol.iterator]: () => noopIterableIterator,
|
|
108
|
+
next: () => ({ done: true, value: undefined }),
|
|
109
|
+
};
|
|
110
|
+
|
|
104
111
|
const stringArrayZ = z.string().transform(
|
|
105
112
|
(s) =>
|
|
106
113
|
new Uint8Array(
|
|
@@ -114,6 +121,8 @@ const nullArrayZ = z
|
|
|
114
121
|
.union([z.null(), z.undefined()])
|
|
115
122
|
.transform(() => new Uint8Array().buffer as ArrayBuffer);
|
|
116
123
|
|
|
124
|
+
const NEW_LINE = 10;
|
|
125
|
+
|
|
117
126
|
/**
|
|
118
127
|
* Series is a strongly typed array of telemetry samples backed by an underlying binary
|
|
119
128
|
* buffer.
|
|
@@ -128,7 +137,7 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
128
137
|
* downwards. Typically used to convert arrays to lower precision while preserving
|
|
129
138
|
* the relative range of actual values.
|
|
130
139
|
*/
|
|
131
|
-
sampleOffset:
|
|
140
|
+
sampleOffset: math.Numeric;
|
|
132
141
|
/**
|
|
133
142
|
* Stores information about the buffer state of this array into a WebGL buffer.
|
|
134
143
|
*/
|
|
@@ -138,14 +147,17 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
138
147
|
readonly _timeRange?: TimeRange;
|
|
139
148
|
readonly alignment: bigint = 0n;
|
|
140
149
|
/** A cached minimum value. */
|
|
141
|
-
private _cachedMin?:
|
|
150
|
+
private _cachedMin?: math.Numeric;
|
|
142
151
|
/** A cached maximum value. */
|
|
143
|
-
private _cachedMax?:
|
|
152
|
+
private _cachedMax?: math.Numeric;
|
|
144
153
|
/** The write position of the buffer. */
|
|
145
154
|
private writePos: number = FULL_BUFFER;
|
|
146
155
|
/** Tracks the number of entities currently using this array. */
|
|
147
156
|
private _refCount: number = 0;
|
|
157
|
+
/** Caches the length of the array for variable length data types. */
|
|
148
158
|
private _cachedLength?: number;
|
|
159
|
+
/** Caches the indexes of the array for variable length data types. */
|
|
160
|
+
private _cachedIndexes?: number[];
|
|
149
161
|
|
|
150
162
|
static readonly crudeZ = z.object({
|
|
151
163
|
timeRange: TimeRange.z.optional(),
|
|
@@ -193,37 +205,35 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
193
205
|
const isArray = Array.isArray(data);
|
|
194
206
|
|
|
195
207
|
if (dataType != null) this.dataType = new DataType(dataType);
|
|
196
|
-
else
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (
|
|
204
|
-
if (data.length === 0)
|
|
205
|
-
throw new Error(
|
|
206
|
-
"cannot infer data type from a zero length JS array when constructing a Series. Please provide a data type.",
|
|
207
|
-
);
|
|
208
|
-
first = data[0];
|
|
209
|
-
}
|
|
210
|
-
if (typeof first === "string") this.dataType = DataType.STRING;
|
|
211
|
-
else if (typeof first === "number") this.dataType = DataType.FLOAT64;
|
|
212
|
-
else if (typeof first === "bigint") this.dataType = DataType.INT64;
|
|
213
|
-
else if (typeof first === "boolean") this.dataType = DataType.BOOLEAN;
|
|
214
|
-
else if (
|
|
215
|
-
first instanceof TimeStamp ||
|
|
216
|
-
first instanceof Date ||
|
|
217
|
-
first instanceof TimeStamp
|
|
218
|
-
)
|
|
219
|
-
this.dataType = DataType.TIMESTAMP;
|
|
220
|
-
else if (typeof first === "object") this.dataType = DataType.JSON;
|
|
221
|
-
else
|
|
208
|
+
else if (data instanceof ArrayBuffer)
|
|
209
|
+
throw new Error(
|
|
210
|
+
"cannot infer data type from an ArrayBuffer instance when constructing a Series. Please provide a data type.",
|
|
211
|
+
);
|
|
212
|
+
else if (isArray || isSingle) {
|
|
213
|
+
let first: TelemValue | unknown = data as TelemValue;
|
|
214
|
+
if (!isSingle) {
|
|
215
|
+
if (data.length === 0)
|
|
222
216
|
throw new Error(
|
|
223
|
-
|
|
217
|
+
"cannot infer data type from a zero length JS array when constructing a Series. Please provide a data type.",
|
|
224
218
|
);
|
|
225
|
-
|
|
226
|
-
|
|
219
|
+
first = data[0];
|
|
220
|
+
}
|
|
221
|
+
if (typeof first === "string") this.dataType = DataType.STRING;
|
|
222
|
+
else if (typeof first === "number") this.dataType = DataType.FLOAT64;
|
|
223
|
+
else if (typeof first === "bigint") this.dataType = DataType.INT64;
|
|
224
|
+
else if (typeof first === "boolean") this.dataType = DataType.BOOLEAN;
|
|
225
|
+
else if (
|
|
226
|
+
first instanceof TimeStamp ||
|
|
227
|
+
first instanceof Date ||
|
|
228
|
+
first instanceof TimeStamp
|
|
229
|
+
)
|
|
230
|
+
this.dataType = DataType.TIMESTAMP;
|
|
231
|
+
else if (typeof first === "object") this.dataType = DataType.JSON;
|
|
232
|
+
else
|
|
233
|
+
throw new Error(
|
|
234
|
+
`cannot infer data type of ${typeof first} when constructing a Series from a JS array`,
|
|
235
|
+
);
|
|
236
|
+
} else this.dataType = new DataType(data);
|
|
227
237
|
|
|
228
238
|
if (!isArray && !isSingle) this._data = data;
|
|
229
239
|
else {
|
|
@@ -237,11 +247,11 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
237
247
|
data_ = data_.map((v) => new TimeStamp(v as CrudeTimeStamp).valueOf());
|
|
238
248
|
if (this.dataType.equals(DataType.STRING)) {
|
|
239
249
|
this._cachedLength = data_.length;
|
|
240
|
-
this._data = new TextEncoder().encode(data_.join("\n")
|
|
250
|
+
this._data = new TextEncoder().encode(`${data_.join("\n")}\n`);
|
|
241
251
|
} else if (this.dataType.equals(DataType.JSON)) {
|
|
242
252
|
this._cachedLength = data_.length;
|
|
243
253
|
this._data = new TextEncoder().encode(
|
|
244
|
-
data_.map((d) => binary.JSON_CODEC.encodeString(d)).join("\n")
|
|
254
|
+
`${data_.map((d) => binary.JSON_CODEC.encodeString(d)).join("\n")}\n`,
|
|
245
255
|
);
|
|
246
256
|
} else this._data = new this.dataType.Array(data_ as number[] & bigint[]).buffer;
|
|
247
257
|
}
|
|
@@ -274,9 +284,8 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
274
284
|
static generateTimestamps(length: number, rate: Rate, start: TimeStamp): Series {
|
|
275
285
|
const timeRange = start.spanRange(rate.span(length));
|
|
276
286
|
const data = new BigInt64Array(length);
|
|
277
|
-
for (let i = 0; i < length; i++)
|
|
287
|
+
for (let i = 0; i < length; i++)
|
|
278
288
|
data[i] = BigInt(start.add(rate.span(i)).valueOf());
|
|
279
|
-
}
|
|
280
289
|
return new Series({ data, dataType: DataType.TIMESTAMP, timeRange });
|
|
281
290
|
}
|
|
282
291
|
|
|
@@ -285,13 +294,13 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
285
294
|
}
|
|
286
295
|
|
|
287
296
|
static fromStrings(data: string[], timeRange?: TimeRange): Series {
|
|
288
|
-
const buffer = new TextEncoder().encode(data.join("\n")
|
|
297
|
+
const buffer = new TextEncoder().encode(`${data.join("\n")}\n`);
|
|
289
298
|
return new Series({ data: buffer, dataType: DataType.STRING, timeRange });
|
|
290
299
|
}
|
|
291
300
|
|
|
292
301
|
static fromJSON<T>(data: T[], timeRange?: TimeRange): Series {
|
|
293
302
|
const buffer = new TextEncoder().encode(
|
|
294
|
-
data.map((d) => binary.JSON_CODEC.encodeString(d)).join("\n")
|
|
303
|
+
`${data.map((d) => binary.JSON_CODEC.encodeString(d)).join("\n")}\n`,
|
|
295
304
|
);
|
|
296
305
|
return new Series({ data: buffer, dataType: DataType.JSON, timeRange });
|
|
297
306
|
}
|
|
@@ -320,25 +329,46 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
320
329
|
write(other: Series): number {
|
|
321
330
|
if (!other.dataType.equals(this.dataType))
|
|
322
331
|
throw new Error("buffer must be of the same type as this array");
|
|
332
|
+
if (this.dataType.isVariable) return this.writeVariable(other);
|
|
333
|
+
return this.writeFixed(other);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private writeVariable(other: Series): number {
|
|
337
|
+
if (this.writePos === FULL_BUFFER) return 0;
|
|
338
|
+
const available = this.byteCapacity.valueOf() - this.writePos;
|
|
339
|
+
const toWrite = other.subBytes(0, available);
|
|
340
|
+
this.writeToUnderlyingData(toWrite);
|
|
341
|
+
this.writePos += toWrite.byteLength.valueOf();
|
|
342
|
+
if (this._cachedLength != null) {
|
|
343
|
+
this._cachedLength += toWrite.length;
|
|
344
|
+
this.calculateCachedLength();
|
|
345
|
+
}
|
|
346
|
+
return toWrite.length;
|
|
347
|
+
}
|
|
323
348
|
|
|
324
|
-
|
|
349
|
+
private writeFixed(other: Series): number {
|
|
325
350
|
if (this.writePos === FULL_BUFFER) return 0;
|
|
326
351
|
const available = this.capacity - this.writePos;
|
|
352
|
+
const toWrite = other.sub(0, available);
|
|
353
|
+
this.writeToUnderlyingData(toWrite);
|
|
354
|
+
this._cachedLength = undefined;
|
|
355
|
+
this.maybeRecomputeMinMax(toWrite);
|
|
356
|
+
this.writePos += toWrite.length;
|
|
357
|
+
return toWrite.length;
|
|
358
|
+
}
|
|
327
359
|
|
|
328
|
-
|
|
360
|
+
private writeToUnderlyingData(data: Series) {
|
|
329
361
|
this.underlyingData.set(
|
|
330
|
-
|
|
362
|
+
data.data as unknown as ArrayLike<bigint> & ArrayLike<number>,
|
|
331
363
|
this.writePos,
|
|
332
364
|
);
|
|
333
|
-
this.maybeRecomputeMinMax(toWrite);
|
|
334
|
-
this._cachedLength = undefined;
|
|
335
|
-
this.writePos += toWrite.length;
|
|
336
|
-
return toWrite.length;
|
|
337
365
|
}
|
|
338
366
|
|
|
339
367
|
/** @returns the underlying buffer backing this array. */
|
|
340
368
|
get buffer(): ArrayBufferLike {
|
|
341
|
-
|
|
369
|
+
if (this._data instanceof ArrayBuffer || this._data instanceof SharedArrayBuffer)
|
|
370
|
+
return this._data;
|
|
371
|
+
return (this._data as TypedArray).buffer;
|
|
342
372
|
}
|
|
343
373
|
|
|
344
374
|
private get underlyingData(): TypedArray {
|
|
@@ -354,7 +384,7 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
354
384
|
toStrings(): string[] {
|
|
355
385
|
if (!this.dataType.matches(DataType.STRING, DataType.UUID))
|
|
356
386
|
throw new Error("cannot convert non-string series to strings");
|
|
357
|
-
return new TextDecoder().decode(this.
|
|
387
|
+
return new TextDecoder().decode(this.underlyingData).split("\n").slice(0, -1);
|
|
358
388
|
}
|
|
359
389
|
|
|
360
390
|
toUUIDs(): string[] {
|
|
@@ -364,7 +394,7 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
364
394
|
const r = Array(this.length);
|
|
365
395
|
|
|
366
396
|
for (let i = 0; i < this.length; i++) {
|
|
367
|
-
const v = this.
|
|
397
|
+
const v = this.underlyingData.slice(i * den, (i + 1) * den);
|
|
368
398
|
const id = Array.from(new Uint8Array(v), (b) => b.toString(16).padStart(2, "0"))
|
|
369
399
|
.join("")
|
|
370
400
|
.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, "$1-$2-$3-$4-$5");
|
|
@@ -377,7 +407,7 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
377
407
|
if (!this.dataType.equals(DataType.JSON))
|
|
378
408
|
throw new Error("cannot convert non-string series to strings");
|
|
379
409
|
return new TextDecoder()
|
|
380
|
-
.decode(this.
|
|
410
|
+
.decode(this.underlyingData)
|
|
381
411
|
.split("\n")
|
|
382
412
|
.slice(0, -1)
|
|
383
413
|
.map((s) => schema.parse(binary.JSON_CODEC.decodeString(s)));
|
|
@@ -391,17 +421,19 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
391
421
|
|
|
392
422
|
/** @returns the capacity of the series in bytes. */
|
|
393
423
|
get byteCapacity(): Size {
|
|
394
|
-
return new Size(this.
|
|
424
|
+
return new Size(this.underlyingData.byteLength);
|
|
395
425
|
}
|
|
396
426
|
|
|
397
427
|
/** @returns the capacity of the series in samples. */
|
|
398
428
|
get capacity(): number {
|
|
429
|
+
if (this.dataType.isVariable) return this.byteCapacity.valueOf();
|
|
399
430
|
return this.dataType.density.length(this.byteCapacity);
|
|
400
431
|
}
|
|
401
432
|
|
|
402
433
|
/** @returns the length of the series in bytes. */
|
|
403
434
|
get byteLength(): Size {
|
|
404
435
|
if (this.writePos === FULL_BUFFER) return this.byteCapacity;
|
|
436
|
+
if (this.dataType.isVariable) return new Size(this.writePos);
|
|
405
437
|
return this.dataType.density.size(this.writePos);
|
|
406
438
|
}
|
|
407
439
|
|
|
@@ -417,9 +449,13 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
417
449
|
if (!this.dataType.isVariable)
|
|
418
450
|
throw new Error("cannot calculate length of a non-variable length data type");
|
|
419
451
|
let cl = 0;
|
|
420
|
-
|
|
421
|
-
|
|
452
|
+
const ci: number[] = [0];
|
|
453
|
+
this.data.forEach((v, i) => {
|
|
454
|
+
if (v !== NEW_LINE) return;
|
|
455
|
+
cl++;
|
|
456
|
+
ci.push(i + 1);
|
|
422
457
|
});
|
|
458
|
+
this._cachedIndexes = ci;
|
|
423
459
|
this._cachedLength = cl;
|
|
424
460
|
return cl;
|
|
425
461
|
}
|
|
@@ -433,12 +469,11 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
433
469
|
* WARNING: This method is expensive and copies the entire underlying array. There
|
|
434
470
|
* also may be untimely precision issues when converting between data types.
|
|
435
471
|
*/
|
|
436
|
-
convert(target: DataType, sampleOffset:
|
|
472
|
+
convert(target: DataType, sampleOffset: math.Numeric = 0): Series {
|
|
437
473
|
if (this.dataType.equals(target)) return this;
|
|
438
474
|
const data = new target.Array(this.length);
|
|
439
|
-
for (let i = 0; i < this.length; i++)
|
|
475
|
+
for (let i = 0; i < this.length; i++)
|
|
440
476
|
data[i] = convertDataType(this.dataType, target, this.data[i], sampleOffset);
|
|
441
|
-
}
|
|
442
477
|
return new Series({
|
|
443
478
|
data: data.buffer,
|
|
444
479
|
dataType: target,
|
|
@@ -449,11 +484,11 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
449
484
|
});
|
|
450
485
|
}
|
|
451
486
|
|
|
452
|
-
private calcRawMax():
|
|
487
|
+
private calcRawMax(): math.Numeric {
|
|
453
488
|
if (this.length === 0) return -Infinity;
|
|
454
|
-
if (this.dataType.equals(DataType.TIMESTAMP))
|
|
489
|
+
if (this.dataType.equals(DataType.TIMESTAMP))
|
|
455
490
|
this._cachedMax = this.data[this.data.length - 1];
|
|
456
|
-
|
|
491
|
+
else if (this.dataType.usesBigInt) {
|
|
457
492
|
const d = this.data as BigInt64Array;
|
|
458
493
|
this._cachedMax = d.reduce((a, b) => (a > b ? a : b));
|
|
459
494
|
} else {
|
|
@@ -464,19 +499,18 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
464
499
|
}
|
|
465
500
|
|
|
466
501
|
/** @returns the maximum value in the array */
|
|
467
|
-
get max():
|
|
502
|
+
get max(): math.Numeric {
|
|
468
503
|
if (this.dataType.isVariable)
|
|
469
504
|
throw new Error("cannot calculate maximum on a variable length data type");
|
|
470
505
|
if (this.writePos === 0) return -Infinity;
|
|
471
|
-
|
|
506
|
+
this._cachedMax ??= this.calcRawMax();
|
|
472
507
|
return addSamples(this._cachedMax, this.sampleOffset);
|
|
473
508
|
}
|
|
474
509
|
|
|
475
|
-
private calcRawMin():
|
|
510
|
+
private calcRawMin(): math.Numeric {
|
|
476
511
|
if (this.length === 0) return Infinity;
|
|
477
|
-
if (this.dataType.equals(DataType.TIMESTAMP))
|
|
478
|
-
|
|
479
|
-
} else if (this.dataType.usesBigInt) {
|
|
512
|
+
if (this.dataType.equals(DataType.TIMESTAMP)) this._cachedMin = this.data[0];
|
|
513
|
+
else if (this.dataType.usesBigInt) {
|
|
480
514
|
const d = this.data as BigInt64Array;
|
|
481
515
|
this._cachedMin = d.reduce((a, b) => (a < b ? a : b));
|
|
482
516
|
} else {
|
|
@@ -487,11 +521,11 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
487
521
|
}
|
|
488
522
|
|
|
489
523
|
/** @returns the minimum value in the array */
|
|
490
|
-
get min():
|
|
524
|
+
get min(): math.Numeric {
|
|
491
525
|
if (this.dataType.isVariable)
|
|
492
526
|
throw new Error("cannot calculate minimum on a variable length data type");
|
|
493
527
|
if (this.writePos === 0) return Infinity;
|
|
494
|
-
|
|
528
|
+
this._cachedMin ??= this.calcRawMin();
|
|
495
529
|
return addSamples(this._cachedMin, this.sampleOffset);
|
|
496
530
|
}
|
|
497
531
|
|
|
@@ -517,10 +551,23 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
517
551
|
_ = this.min;
|
|
518
552
|
}
|
|
519
553
|
|
|
520
|
-
get range():
|
|
554
|
+
get range(): math.Numeric {
|
|
521
555
|
return addSamples(this.max, -this.min);
|
|
522
556
|
}
|
|
523
557
|
|
|
558
|
+
atAlignment(alignment: bigint, required: true): T;
|
|
559
|
+
|
|
560
|
+
atAlignment(alignment: bigint, required?: false): T | undefined;
|
|
561
|
+
|
|
562
|
+
atAlignment(alignment: bigint, required?: boolean): T | undefined {
|
|
563
|
+
const index = Number(alignment - this.alignment);
|
|
564
|
+
if (index < 0 || index >= this.length) {
|
|
565
|
+
if (required === true) throw new Error(`[series] - no value at index ${index}`);
|
|
566
|
+
return undefined;
|
|
567
|
+
}
|
|
568
|
+
return this.at(index, required as true);
|
|
569
|
+
}
|
|
570
|
+
|
|
524
571
|
at(index: number, required: true): T;
|
|
525
572
|
|
|
526
573
|
at(index: number, required?: false): T | undefined;
|
|
@@ -537,24 +584,28 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
537
584
|
}
|
|
538
585
|
|
|
539
586
|
private atVariable(index: number, required: boolean): T | undefined {
|
|
540
|
-
if (index < 0) index = this.length + index;
|
|
541
587
|
let start = 0;
|
|
542
588
|
let end = 0;
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
589
|
+
if (this._cachedIndexes != null) {
|
|
590
|
+
start = this._cachedIndexes[index];
|
|
591
|
+
end = this._cachedIndexes[index + 1] - 1;
|
|
592
|
+
} else {
|
|
593
|
+
if (index < 0) index = this.length + index;
|
|
594
|
+
for (let i = 0; i < this.data.length; i++)
|
|
595
|
+
if (this.data[i] === NEW_LINE) {
|
|
596
|
+
if (index === 0) {
|
|
597
|
+
end = i;
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
start = i + 1;
|
|
601
|
+
index--;
|
|
548
602
|
}
|
|
549
|
-
|
|
550
|
-
|
|
603
|
+
if (end === 0) end = this.data.length;
|
|
604
|
+
if (start >= end || index > 0) {
|
|
605
|
+
if (required) throw new Error(`[series] - no value at index ${index}`);
|
|
606
|
+
return undefined;
|
|
551
607
|
}
|
|
552
608
|
}
|
|
553
|
-
if (end === 0) end = this.data.length;
|
|
554
|
-
if (start >= end || index > 0) {
|
|
555
|
-
if (required) throw new Error(`[series] - no value at index ${index}`);
|
|
556
|
-
return undefined;
|
|
557
|
-
}
|
|
558
609
|
const slice = this.data.slice(start, end);
|
|
559
610
|
if (this.dataType.equals(DataType.STRING))
|
|
560
611
|
return new TextDecoder().decode(slice) as unknown as T;
|
|
@@ -568,13 +619,13 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
568
619
|
* The underlying array must be sorted. If it is not, the behavior of this method is undefined.
|
|
569
620
|
* @param value the value to search for.
|
|
570
621
|
*/
|
|
571
|
-
binarySearch(value:
|
|
622
|
+
binarySearch(value: math.Numeric): number {
|
|
572
623
|
let left = 0;
|
|
573
624
|
let right = this.length - 1;
|
|
574
625
|
const cf = compare.newF(value);
|
|
575
626
|
while (left <= right) {
|
|
576
627
|
const mid = Math.floor((left + right) / 2);
|
|
577
|
-
const cmp = cf(this.at(mid, true) as
|
|
628
|
+
const cmp = cf(this.at(mid, true) as math.Numeric, value);
|
|
578
629
|
if (cmp === 0) return mid;
|
|
579
630
|
if (cmp < 0) left = mid + 1;
|
|
580
631
|
else right = mid - 1;
|
|
@@ -599,9 +650,8 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
599
650
|
|
|
600
651
|
// This means we only need to buffer part of the array.
|
|
601
652
|
if (this.writePos !== FULL_BUFFER) {
|
|
602
|
-
if (prevBuffer === 0)
|
|
653
|
+
if (prevBuffer === 0)
|
|
603
654
|
gl.bufferData(gl.ARRAY_BUFFER, this.byteCapacity.valueOf(), gl.STATIC_DRAW);
|
|
604
|
-
}
|
|
605
655
|
const byteOffset = this.dataType.density.size(prevBuffer).valueOf();
|
|
606
656
|
const slice = this.underlyingData.slice(this.gl.prevBuffer, this.writePos);
|
|
607
657
|
gl.bufferSubData(gl.ARRAY_BUFFER, byteOffset, slice.buffer);
|
|
@@ -610,7 +660,7 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
610
660
|
// This means we can buffer the entire array in a single go.
|
|
611
661
|
gl.bufferData(
|
|
612
662
|
gl.ARRAY_BUFFER,
|
|
613
|
-
this.
|
|
663
|
+
this.underlyingData,
|
|
614
664
|
bufferUsage === "static" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW,
|
|
615
665
|
);
|
|
616
666
|
this.gl.prevBuffer = FULL_BUFFER;
|
|
@@ -690,17 +740,51 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
690
740
|
[Symbol.iterator](): Iterator<T> {
|
|
691
741
|
if (this.dataType.isVariable) {
|
|
692
742
|
const s = new StringSeriesIterator(this);
|
|
693
|
-
if (this.dataType.equals(DataType.JSON))
|
|
743
|
+
if (this.dataType.equals(DataType.JSON))
|
|
694
744
|
return new JSONSeriesIterator(s) as Iterator<T>;
|
|
695
|
-
}
|
|
696
745
|
return s as Iterator<T>;
|
|
697
746
|
}
|
|
698
747
|
return new FixedSeriesIterator(this) as Iterator<T>;
|
|
699
748
|
}
|
|
700
749
|
|
|
701
750
|
slice(start: number, end?: number): Series {
|
|
751
|
+
return this.sliceSub(false, start, end);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
sub(start: number, end?: number): Series {
|
|
755
|
+
return this.sliceSub(true, start, end);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
subIterator(start: number, end?: number): IterableIterator<T> {
|
|
759
|
+
return new SubIterator(this, start, end ?? this.length);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
subAlignmentIterator(start: bigint, end: bigint): IterableIterator<T> {
|
|
763
|
+
return new SubIterator(
|
|
764
|
+
this,
|
|
765
|
+
Number(start - this.alignment),
|
|
766
|
+
Number(end - this.alignment),
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
private subBytes(start: number, end?: number): Series {
|
|
771
|
+
if (start >= 0 && (end == null || end >= this.byteLength.valueOf())) return this;
|
|
772
|
+
const data = this.data.subarray(start, end);
|
|
773
|
+
return new Series({
|
|
774
|
+
data,
|
|
775
|
+
dataType: this.dataType,
|
|
776
|
+
timeRange: this._timeRange,
|
|
777
|
+
sampleOffset: this.sampleOffset,
|
|
778
|
+
glBufferUsage: this.gl.bufferUsage,
|
|
779
|
+
alignment: this.alignment + BigInt(start),
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
private sliceSub(sub: boolean, start: number, end?: number): Series {
|
|
702
784
|
if (start <= 0 && (end == null || end >= this.length)) return this;
|
|
703
|
-
|
|
785
|
+
let data: TypedArray;
|
|
786
|
+
if (sub) data = this.data.subarray(start, end);
|
|
787
|
+
else data = this.data.slice(start, end);
|
|
704
788
|
return new Series({
|
|
705
789
|
data,
|
|
706
790
|
dataType: this.dataType,
|
|
@@ -723,6 +807,28 @@ export class Series<T extends TelemValue = TelemValue> {
|
|
|
723
807
|
}
|
|
724
808
|
}
|
|
725
809
|
|
|
810
|
+
class SubIterator<T> implements Iterator<T>, Iterable<T> {
|
|
811
|
+
private readonly series: Series;
|
|
812
|
+
private readonly end: number;
|
|
813
|
+
private index: number;
|
|
814
|
+
|
|
815
|
+
constructor(series: Series, start: number, end: number) {
|
|
816
|
+
this.series = series;
|
|
817
|
+
const b = bounds.construct(0, series.length);
|
|
818
|
+
this.end = bounds.clamp(b, end);
|
|
819
|
+
this.index = bounds.clamp(b, start);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
next(): IteratorResult<T> {
|
|
823
|
+
if (this.index >= this.end) return { done: true, value: undefined };
|
|
824
|
+
return { done: false, value: this.series.at(this.index++, true) as T };
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
[Symbol.iterator](): Iterator<T> {
|
|
828
|
+
return this;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
726
832
|
class StringSeriesIterator implements Iterator<string> {
|
|
727
833
|
private readonly series: Series;
|
|
728
834
|
private index: number;
|
|
@@ -741,7 +847,7 @@ class StringSeriesIterator implements Iterator<string> {
|
|
|
741
847
|
next(): IteratorResult<string> {
|
|
742
848
|
const start = this.index;
|
|
743
849
|
const data = this.series.data;
|
|
744
|
-
while (this.index < data.length && data[this.index] !==
|
|
850
|
+
while (this.index < data.length && data[this.index] !== NEW_LINE) this.index++;
|
|
745
851
|
const end = this.index;
|
|
746
852
|
if (start === end) return { done: true, value: undefined };
|
|
747
853
|
this.index++;
|
|
@@ -777,7 +883,7 @@ class JSONSeriesIterator implements Iterator<unknown> {
|
|
|
777
883
|
[Symbol.toStringTag] = "JSONSeriesIterator";
|
|
778
884
|
}
|
|
779
885
|
|
|
780
|
-
class FixedSeriesIterator implements Iterator<
|
|
886
|
+
class FixedSeriesIterator implements Iterator<math.Numeric> {
|
|
781
887
|
series: Series;
|
|
782
888
|
index: number;
|
|
783
889
|
constructor(series: Series) {
|
|
@@ -785,25 +891,22 @@ class FixedSeriesIterator implements Iterator<NumericTelemValue> {
|
|
|
785
891
|
this.index = 0;
|
|
786
892
|
}
|
|
787
893
|
|
|
788
|
-
next(): IteratorResult<
|
|
894
|
+
next(): IteratorResult<math.Numeric> {
|
|
789
895
|
if (this.index >= this.series.length) return { done: true, value: undefined };
|
|
790
896
|
return {
|
|
791
897
|
done: false,
|
|
792
|
-
value: this.series.at(this.index++, true) as
|
|
898
|
+
value: this.series.at(this.index++, true) as math.Numeric,
|
|
793
899
|
};
|
|
794
900
|
}
|
|
795
901
|
|
|
796
|
-
[Symbol.iterator](): Iterator<
|
|
902
|
+
[Symbol.iterator](): Iterator<math.Numeric> {
|
|
797
903
|
return this;
|
|
798
904
|
}
|
|
799
905
|
|
|
800
906
|
[Symbol.toStringTag] = "SeriesIterator";
|
|
801
907
|
}
|
|
802
908
|
|
|
803
|
-
export const addSamples = (
|
|
804
|
-
a: NumericTelemValue,
|
|
805
|
-
b: NumericTelemValue,
|
|
806
|
-
): NumericTelemValue => {
|
|
909
|
+
export const addSamples = (a: math.Numeric, b: math.Numeric): math.Numeric => {
|
|
807
910
|
if (typeof a === "bigint" && typeof b === "bigint") return a + b;
|
|
808
911
|
if (typeof a === "number" && typeof b === "number") return a + b;
|
|
809
912
|
if (b === 0) return a;
|
|
@@ -851,6 +954,19 @@ export class MultiSeries<T extends TelemValue = TelemValue> implements Iterable<
|
|
|
851
954
|
);
|
|
852
955
|
}
|
|
853
956
|
|
|
957
|
+
get alignment(): bigint {
|
|
958
|
+
if (this.series.length === 0) return 0n;
|
|
959
|
+
return this.series[0].alignment;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
get alignmentBounds(): bounds.Bounds<bigint> {
|
|
963
|
+
if (this.series.length === 0) return bounds.construct(0n, 0n);
|
|
964
|
+
return bounds.construct(
|
|
965
|
+
this.series[0].alignmentBounds.lower,
|
|
966
|
+
this.series[this.series.length - 1].alignmentBounds.upper,
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
|
|
854
970
|
push(series: Series<T>): void {
|
|
855
971
|
this.series.push(series);
|
|
856
972
|
}
|
|
@@ -859,6 +975,22 @@ export class MultiSeries<T extends TelemValue = TelemValue> implements Iterable<
|
|
|
859
975
|
return this.series.reduce((a, b) => a + b.length, 0);
|
|
860
976
|
}
|
|
861
977
|
|
|
978
|
+
atAlignment(alignment: bigint, required: true): T;
|
|
979
|
+
|
|
980
|
+
atAlignment(alignment: bigint, required?: false): T | undefined;
|
|
981
|
+
|
|
982
|
+
atAlignment(alignment: bigint, required?: boolean): T | undefined {
|
|
983
|
+
if (this.series.length === 0) {
|
|
984
|
+
if (required) throw new Error(`[series] - no value at alignment ${alignment}`);
|
|
985
|
+
return undefined;
|
|
986
|
+
}
|
|
987
|
+
for (const ser of this.series)
|
|
988
|
+
if (bounds.contains(ser.alignmentBounds, alignment))
|
|
989
|
+
return ser.atAlignment(alignment, required as true);
|
|
990
|
+
if (required) throw new Error(`[series] - no value at alignment ${alignment}`);
|
|
991
|
+
return undefined;
|
|
992
|
+
}
|
|
993
|
+
|
|
862
994
|
at(index: number, required: true): T;
|
|
863
995
|
|
|
864
996
|
at(index: number, required?: false): T | undefined;
|
|
@@ -873,6 +1005,51 @@ export class MultiSeries<T extends TelemValue = TelemValue> implements Iterable<
|
|
|
873
1005
|
return undefined;
|
|
874
1006
|
}
|
|
875
1007
|
|
|
1008
|
+
subIterator(start: number, end?: number): IterableIterator<T> {
|
|
1009
|
+
return new MultiSubIterator(this, start, end ?? this.length);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
subAlignmentIterator(start: bigint, end: bigint): IterableIterator<T> {
|
|
1013
|
+
if (start >= this.alignmentBounds.upper || end <= this.alignmentBounds.lower)
|
|
1014
|
+
return noopIterableIterator;
|
|
1015
|
+
let startIdx = 0;
|
|
1016
|
+
for (let i = 0; i < this.series.length; i++) {
|
|
1017
|
+
const ser = this.series[i];
|
|
1018
|
+
if (start < ser.alignment) break;
|
|
1019
|
+
else if (start >= ser.alignmentBounds.upper) startIdx += ser.length;
|
|
1020
|
+
else if (bounds.contains(ser.alignmentBounds, start)) {
|
|
1021
|
+
startIdx += Number(start - ser.alignment);
|
|
1022
|
+
break;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
let endIdx = 0;
|
|
1026
|
+
for (let i = 0; i < this.series.length; i++) {
|
|
1027
|
+
const ser = this.series[i];
|
|
1028
|
+
if (end < ser.alignment) break;
|
|
1029
|
+
else if (end >= ser.alignmentBounds.upper) endIdx += ser.length;
|
|
1030
|
+
else if (bounds.contains(ser.alignmentBounds, end)) {
|
|
1031
|
+
endIdx += Number(end - ser.alignment);
|
|
1032
|
+
break;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return new MultiSubIterator(this, startIdx, endIdx);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
subAlignmentSpanIterator(start: bigint, span: number): IterableIterator<T> {
|
|
1039
|
+
if (start >= this.alignmentBounds.upper) return noopIterableIterator;
|
|
1040
|
+
let startIdx = 0;
|
|
1041
|
+
for (let i = 0; i < this.series.length; i++) {
|
|
1042
|
+
const ser = this.series[i];
|
|
1043
|
+
if (start < ser.alignment) break;
|
|
1044
|
+
else if (start >= ser.alignmentBounds.upper) startIdx += ser.length;
|
|
1045
|
+
else if (bounds.contains(ser.alignmentBounds, start)) {
|
|
1046
|
+
startIdx += Number(start - ser.alignment);
|
|
1047
|
+
break;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return new MultiSubIterator(this, startIdx, startIdx + span);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
876
1053
|
get byteLength(): Size {
|
|
877
1054
|
return new Size(this.series.reduce((a, b) => a + b.byteLength.valueOf(), 0));
|
|
878
1055
|
}
|
|
@@ -887,6 +1064,16 @@ export class MultiSeries<T extends TelemValue = TelemValue> implements Iterable<
|
|
|
887
1064
|
return new this.dataType.Array(buf);
|
|
888
1065
|
}
|
|
889
1066
|
|
|
1067
|
+
traverseAlignment(start: bigint, dist: bigint): bigint {
|
|
1068
|
+
const b = this.series.map((s) => s.alignmentBounds);
|
|
1069
|
+
return bounds.traverse(b, start, dist);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
distance(start: bigint, end: bigint): bigint {
|
|
1073
|
+
const b = this.series.map((s) => s.alignmentBounds);
|
|
1074
|
+
return bounds.distance(b, start, end);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
890
1077
|
[Symbol.iterator](): Iterator<T> {
|
|
891
1078
|
if (this.series.length === 0)
|
|
892
1079
|
return {
|
|
@@ -925,4 +1112,27 @@ class MultiSeriesIterator<T extends TelemValue = TelemValue> implements Iterator
|
|
|
925
1112
|
[Symbol.toStringTag] = "MultiSeriesIterator";
|
|
926
1113
|
}
|
|
927
1114
|
|
|
1115
|
+
class MultiSubIterator<T extends TelemValue = TelemValue>
|
|
1116
|
+
implements IterableIterator<T>
|
|
1117
|
+
{
|
|
1118
|
+
private readonly series: MultiSeries<T>;
|
|
1119
|
+
private index: number;
|
|
1120
|
+
private end: number;
|
|
1121
|
+
|
|
1122
|
+
constructor(series: MultiSeries<T>, start: number, end: number) {
|
|
1123
|
+
this.series = series;
|
|
1124
|
+
this.end = end;
|
|
1125
|
+
this.index = start;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
next(): IteratorResult<T> {
|
|
1129
|
+
if (this.index >= this.end) return { done: true, value: undefined };
|
|
1130
|
+
return { done: false, value: this.series.at(this.index++, true) as T };
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
[Symbol.iterator](): Iterator<T> {
|
|
1134
|
+
return this;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
928
1138
|
export type SeriesPayload = z.infer<typeof Series.crudeZ>;
|