@synnaxlabs/x 0.42.1 → 0.43.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 +93 -105
- package/.vscode/settings.json +4 -6
- package/README.md +1 -7
- package/dist/array.cjs +1 -0
- package/dist/array.js +7 -0
- package/dist/base-B5lQIJKc.js +38 -0
- package/dist/base-CTq-lhpU.cjs +1 -0
- package/dist/binary.cjs +1 -1
- package/dist/binary.js +1 -1
- package/dist/bounds.cjs +1 -1
- package/dist/bounds.js +2 -2
- package/dist/box.cjs +1 -1
- package/dist/box.js +1 -1
- package/dist/caseconv.cjs +1 -1
- package/dist/caseconv.js +2 -2
- package/dist/change.cjs +1 -1
- package/dist/change.js +10 -2
- package/dist/compare.cjs +1 -1
- package/dist/compare.js +1 -1
- package/dist/deep.cjs +1 -1
- package/dist/deep.js +92 -79
- package/dist/dimensions.cjs +1 -1
- package/dist/dimensions.js +41 -2
- package/dist/direction.cjs +1 -1
- package/dist/direction.js +1 -1
- package/dist/index-4GlOgZuh.js +99 -0
- package/dist/{direction-C-b6XTeU.cjs → index-B58dnYRu.cjs} +1 -1
- package/dist/index-BMGaoK93.cjs +1 -0
- package/dist/index-BTet04Hd.cjs +6 -0
- package/dist/{scale-DfJe9755.js → index-BUa-NXAX.js} +46 -46
- package/dist/{xy-D_LqxaGt.js → index-C-qYOegc.js} +62 -62
- package/dist/index-C07SBJhr.js +128 -0
- package/dist/{bounds-Bn5_l4Z3.js → index-C9EdKeu1.js} +77 -76
- package/dist/index-CM8ZDZ6s.cjs +1 -0
- package/dist/index-CV2JaHfw.cjs +1 -0
- package/dist/index-CeBvOwG8.cjs +3 -0
- package/dist/index-ClrGyGDp.js +205 -0
- package/dist/index-CqQXXeCI.cjs +1 -0
- package/dist/{location-C3aeu046.js → index-D6V-8SKw.js} +26 -26
- package/dist/index-DBGAIs_7.js +2492 -0
- package/dist/index-DEdq2tza.cjs +1 -0
- package/dist/index-DKMnHBGR.cjs +1 -0
- package/dist/index-Dql5FMcH.js +47 -0
- package/dist/{direction-BL0PhD1k.js → index-DxU1zwsd.js} +1 -1
- package/dist/index-WwMnwoLy.cjs +1 -0
- package/dist/index.cjs +5 -3
- package/dist/index.js +5372 -649
- package/dist/kv.cjs +1 -1
- package/dist/kv.js +45 -2
- package/dist/location.cjs +1 -1
- package/dist/location.js +1 -1
- package/dist/position.cjs +1 -1
- package/dist/position.js +83 -2
- package/dist/record.cjs +1 -1
- package/dist/record.js +8 -10
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +27 -2
- package/dist/scale.cjs +1 -1
- package/dist/scale.js +1 -1
- package/dist/schemas-55Usj0Fg.js +3998 -0
- package/dist/schemas-DbXuI2Qr.cjs +27 -0
- package/dist/spatial.cjs +1 -1
- package/dist/spatial.js +25 -18
- package/dist/src/array/index.d.ts +2 -0
- package/dist/src/array/index.d.ts.map +1 -0
- package/dist/src/array/toArray.d.ts +19 -0
- package/dist/src/array/toArray.d.ts.map +1 -0
- package/dist/src/array/toArray.spec.d.ts +2 -0
- package/dist/src/array/toArray.spec.d.ts.map +1 -0
- package/dist/src/binary/codec.d.ts +8 -16
- package/dist/src/binary/codec.d.ts.map +1 -1
- package/dist/src/breaker/breaker.d.ts +6 -6
- package/dist/src/breaker/breaker.d.ts.map +1 -1
- package/dist/src/caseconv/caseconv.d.ts +1 -1
- package/dist/src/caseconv/caseconv.d.ts.map +1 -1
- package/dist/src/change/change.d.ts +3 -3
- package/dist/src/change/change.d.ts.map +1 -1
- package/dist/src/color/color.d.ts +63 -28
- package/dist/src/color/color.d.ts.map +1 -1
- package/dist/src/color/external.d.ts +0 -1
- package/dist/src/color/external.d.ts.map +1 -1
- package/dist/src/color/gradient.d.ts +9 -5
- package/dist/src/color/gradient.d.ts.map +1 -1
- package/dist/src/color/palette.d.ts +14 -6
- package/dist/src/color/palette.d.ts.map +1 -1
- package/dist/src/compare/compare.d.ts +4 -4
- package/dist/src/compare/compare.d.ts.map +1 -1
- package/dist/src/control/control.d.ts +32 -32
- package/dist/src/control/control.d.ts.map +1 -1
- package/dist/src/debounce/debounce.d.ts +1 -1
- package/dist/src/debounce/debounce.d.ts.map +1 -1
- package/dist/src/deep/delete.d.ts +1 -1
- package/dist/src/deep/delete.d.ts.map +1 -1
- package/dist/src/deep/difference.d.ts.map +1 -1
- package/dist/src/deep/equal.d.ts +4 -4
- package/dist/src/deep/equal.d.ts.map +1 -1
- package/dist/src/deep/merge.d.ts +1 -1
- package/dist/src/deep/merge.d.ts.map +1 -1
- package/dist/src/errors/errors.d.ts +62 -36
- package/dist/src/errors/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/instance/index.d.ts +2 -0
- package/dist/src/instance/index.d.ts.map +1 -0
- package/dist/src/instance/matcher.d.ts +79 -0
- package/dist/src/instance/matcher.d.ts.map +1 -0
- package/dist/src/instance/matcher.spec.d.ts +2 -0
- package/dist/src/instance/matcher.spec.d.ts.map +1 -0
- package/dist/src/jsonrpc/jsonrpc.d.ts +40 -9
- package/dist/src/jsonrpc/jsonrpc.d.ts.map +1 -1
- package/dist/src/kv/types.d.ts +2 -2
- package/dist/src/kv/types.d.ts.map +1 -1
- package/dist/src/migrate/migrate.d.ts +5 -5
- package/dist/src/migrate/migrate.d.ts.map +1 -1
- package/dist/src/notation/notation.d.ts +1 -1
- package/dist/src/notation/notation.d.ts.map +1 -1
- package/dist/src/primitive/index.d.ts +2 -0
- package/dist/src/primitive/index.d.ts.map +1 -0
- package/dist/src/primitive/primitive.d.ts +39 -0
- package/dist/src/primitive/primitive.d.ts.map +1 -0
- package/dist/src/primitive/primitive.spec.d.ts +2 -0
- package/dist/src/primitive/primitive.spec.d.ts.map +1 -0
- package/dist/src/record.d.ts +2 -2
- package/dist/src/record.d.ts.map +1 -1
- package/dist/src/renderable.d.ts +1 -1
- package/dist/src/renderable.d.ts.map +1 -1
- package/dist/src/replace.d.ts.map +1 -1
- package/dist/src/runtime/detect.d.ts.map +1 -1
- package/dist/src/runtime/os.d.ts +1 -1
- package/dist/src/runtime/os.d.ts.map +1 -1
- package/dist/src/spatial/base.d.ts +10 -10
- package/dist/src/spatial/base.d.ts.map +1 -1
- package/dist/src/spatial/bounds/bounds.d.ts +82 -16
- package/dist/src/spatial/bounds/bounds.d.ts.map +1 -1
- package/dist/src/spatial/box/box.d.ts +7 -7
- package/dist/src/spatial/box/box.d.ts.map +1 -1
- package/dist/src/spatial/dimensions/dimensions.d.ts +5 -5
- package/dist/src/spatial/dimensions/dimensions.d.ts.map +1 -1
- package/dist/src/spatial/direction/direction.d.ts +1 -1
- package/dist/src/spatial/location/location.d.ts +4 -4
- package/dist/src/spatial/location/location.d.ts.map +1 -1
- package/dist/src/spatial/scale/scale.d.ts +11 -11
- package/dist/src/spatial/scale/scale.d.ts.map +1 -1
- package/dist/src/spatial/xy/xy.d.ts +5 -5
- package/dist/src/spatial/xy/xy.d.ts.map +1 -1
- package/dist/src/status/index.d.ts +2 -0
- package/dist/src/status/index.d.ts.map +1 -0
- package/dist/src/status/types.d.ts +11 -0
- package/dist/src/status/types.d.ts.map +1 -0
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/mutex.d.ts +0 -1
- package/dist/src/sync/mutex.d.ts.map +1 -1
- package/dist/src/telem/gl.d.ts +1 -1
- package/dist/src/telem/gl.d.ts.map +1 -1
- package/dist/src/telem/series.d.ts +468 -62
- package/dist/src/telem/series.d.ts.map +1 -1
- package/dist/src/telem/telem.d.ts +243 -53
- package/dist/src/telem/telem.d.ts.map +1 -1
- package/dist/src/uuid/index.d.ts +2 -0
- package/dist/src/uuid/index.d.ts.map +1 -0
- package/dist/src/uuid/uuid.d.ts +35 -0
- package/dist/src/uuid/uuid.d.ts.map +1 -0
- package/dist/src/uuid/uuid.spec.d.ts +2 -0
- package/dist/src/uuid/uuid.spec.d.ts.map +1 -0
- package/dist/src/zod/external.d.ts +1 -1
- package/dist/src/zod/external.d.ts.map +1 -1
- package/dist/src/zod/nullToUndefined.d.ts +3 -0
- package/dist/src/zod/nullToUndefined.d.ts.map +1 -0
- package/dist/src/zod/nullToUndefined.spec.d.ts +2 -0
- package/dist/src/zod/nullToUndefined.spec.d.ts.map +1 -0
- package/dist/src/zod/util.d.ts +2 -2
- package/dist/src/zod/util.d.ts.map +1 -1
- package/dist/telem.cjs +1 -1
- package/dist/telem.js +1 -1
- package/dist/xy.cjs +1 -1
- package/dist/xy.js +1 -1
- package/dist/zod.cjs +1 -1
- package/dist/zod.js +19 -2
- package/eslint.config.js +1 -1
- package/package.json +16 -14
- package/src/{toArray.ts → array/index.ts} +1 -5
- package/src/array/toArray.spec.ts +56 -0
- package/src/array/toArray.ts +28 -0
- package/src/binary/codec.spec.ts +201 -278
- package/src/binary/codec.ts +20 -76
- package/src/breaker/breaker.ts +3 -3
- package/src/caseconv/caseconv.ts +6 -4
- package/src/change/change.ts +2 -2
- package/src/color/color.spec.ts +121 -2
- package/src/color/color.ts +90 -54
- package/src/color/external.ts +0 -1
- package/src/color/gradient.ts +20 -28
- package/src/color/palette.ts +1 -1
- package/src/compare/compare.ts +5 -5
- package/src/control/control.ts +22 -19
- package/src/debounce/debounce.ts +1 -1
- package/src/deep/delete.ts +5 -4
- package/src/deep/difference.ts +6 -2
- package/src/deep/equal.spec.ts +1 -1
- package/src/deep/equal.ts +5 -5
- package/src/deep/merge.spec.ts +13 -1
- package/src/deep/merge.ts +16 -7
- package/src/deep/path.ts +1 -1
- package/src/errors/errors.ts +65 -44
- package/src/index.ts +4 -1
- package/src/instance/index.ts +10 -0
- package/src/instance/matcher.spec.ts +78 -0
- package/src/instance/matcher.ts +98 -0
- package/src/jsonrpc/jsonrpc.spec.ts +2 -1
- package/src/jsonrpc/jsonrpc.ts +36 -7
- package/src/kv/types.ts +1 -1
- package/src/migrate/migrate.spec.ts +1 -1
- package/src/migrate/migrate.ts +7 -7
- package/src/notation/notation.ts +1 -1
- package/src/primitive/index.ts +10 -0
- package/src/primitive/primitive.spec.ts +126 -0
- package/src/primitive/primitive.ts +82 -0
- package/src/record.ts +3 -5
- package/src/renderable.ts +1 -1
- package/src/replace.ts +9 -0
- package/src/runtime/detect.ts +0 -2
- package/src/runtime/os.ts +1 -1
- package/src/spatial/base.ts +1 -1
- package/src/spatial/bounds/bounds.spec.ts +20 -0
- package/src/spatial/bounds/bounds.ts +101 -18
- package/src/spatial/box/box.ts +1 -1
- package/src/spatial/dimensions/dimensions.ts +3 -3
- package/src/spatial/location/location.ts +1 -1
- package/src/spatial/scale/scale.ts +1 -1
- package/src/spatial/xy/xy.ts +1 -1
- package/src/status/index.ts +10 -0
- package/src/status/types.ts +22 -0
- package/src/sync/index.ts +9 -0
- package/src/sync/mutex.ts +9 -4
- package/src/telem/gl.ts +1 -1
- package/src/telem/series.spec.ts +735 -68
- package/src/telem/series.ts +536 -195
- package/src/telem/telem.spec.ts +60 -7
- package/src/telem/telem.ts +287 -95
- package/src/uuid/index.ts +10 -0
- package/src/uuid/uuid.spec.ts +82 -0
- package/src/uuid/uuid.ts +48 -0
- package/src/zod/external.ts +1 -1
- package/src/zod/nullToUndefined.spec.ts +31 -0
- package/src/zod/nullToUndefined.ts +23 -0
- package/src/zod/util.spec.ts +1 -1
- package/src/zod/util.ts +6 -6
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +1 -1
- package/dist/base-BAM2mqCy.cjs +0 -1
- package/dist/base-DFq0vvGn.js +0 -38
- package/dist/bounds-BQo7rvs9.cjs +0 -1
- package/dist/box-0YrQibkB.cjs +0 -1
- package/dist/box-Cc8IzcNo.js +0 -205
- package/dist/change-C-YELKx6.cjs +0 -1
- package/dist/change-DLl6DccR.js +0 -12
- package/dist/dimensions-CRgergMS.js +0 -43
- package/dist/dimensions-D2QGoNXO.cjs +0 -1
- package/dist/external-BPgtxa8d.js +0 -29
- package/dist/external-C-dNgNQw.cjs +0 -1
- package/dist/external-C8TFju8Q.js +0 -29
- package/dist/external-DWQITF5_.cjs +0 -1
- package/dist/external-DqPrWKvU.js +0 -47
- package/dist/external-uXk0Avrg.cjs +0 -1
- package/dist/index-BywOGO8U.js +0 -1074
- package/dist/index-CYYjI7Uf.cjs +0 -1
- package/dist/index-C_6NXBlg.cjs +0 -3
- package/dist/index-Dd8DLyMx.cjs +0 -1
- package/dist/index-DizUWH6z.js +0 -47
- package/dist/index-QGplUHuy.js +0 -98
- package/dist/location-BGl5Ddds.cjs +0 -1
- package/dist/position-Cai5-wi1.cjs +0 -1
- package/dist/position-DIglP1l2.js +0 -85
- package/dist/scale-BtZINJ-A.cjs +0 -1
- package/dist/series-B9JERcqi.js +0 -1977
- package/dist/series-DqJ6f97G.cjs +0 -11
- package/dist/spatial-BSWPzMkK.js +0 -11
- package/dist/spatial-DGpZ2sO3.cjs +0 -1
- package/dist/src/color/transformColorsToHex.d.ts +0 -6
- package/dist/src/color/transformColorsToHex.d.ts.map +0 -1
- package/dist/src/primitive.d.ts +0 -9
- package/dist/src/primitive.d.ts.map +0 -1
- package/dist/src/toArray.d.ts +0 -3
- package/dist/src/toArray.d.ts.map +0 -1
- package/dist/src/zod/integer.d.ts +0 -10
- package/dist/src/zod/integer.d.ts.map +0 -1
- package/dist/src/zod/integer.spec.d.ts +0 -2
- package/dist/src/zod/integer.spec.d.ts.map +0 -1
- package/dist/toArray.cjs +0 -1
- package/dist/toArray.js +0 -5
- package/dist/xy-B7065J2S.cjs +0 -1
- package/src/color/transformColorsToHex.ts +0 -30
- package/src/primitive.ts +0 -46
- package/src/zod/integer.spec.ts +0 -148
- package/src/zod/integer.ts +0 -38
package/src/telem/series.spec.ts
CHANGED
|
@@ -8,11 +8,18 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { describe, expect, it, test } from "vitest";
|
|
11
|
-
import { z } from "zod";
|
|
11
|
+
import { z } from "zod/v4";
|
|
12
12
|
|
|
13
13
|
import { MockGLBufferController } from "@/mock/MockGLBufferController";
|
|
14
|
-
import { isCrudeSeries, MultiSeries, Series } from "@/telem/series";
|
|
15
|
-
import {
|
|
14
|
+
import { type CrudeSeries, isCrudeSeries, MultiSeries, Series } from "@/telem/series";
|
|
15
|
+
import {
|
|
16
|
+
type CrudeDataType,
|
|
17
|
+
DataType,
|
|
18
|
+
Size,
|
|
19
|
+
TimeRange,
|
|
20
|
+
TimeSpan,
|
|
21
|
+
TimeStamp,
|
|
22
|
+
} from "@/telem/telem";
|
|
16
23
|
|
|
17
24
|
describe("Series", () => {
|
|
18
25
|
describe("construction", () => {
|
|
@@ -201,6 +208,22 @@ describe("Series", () => {
|
|
|
201
208
|
expect(strContent).toBe('{"a_b":1,"b_c":"apple"}\n');
|
|
202
209
|
});
|
|
203
210
|
|
|
211
|
+
it("should throw an error when an empty JS array is provided and no data type is provided", () => {
|
|
212
|
+
expect(() => {
|
|
213
|
+
new Series({ data: [] });
|
|
214
|
+
}).toThrow(
|
|
215
|
+
"cannot infer data type from a zero length JS array when constructing a Series. Please provide a data type.",
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("should throw an error when constructing a series from a symbol", () => {
|
|
220
|
+
expect(() => {
|
|
221
|
+
new Series({ data: [Symbol("123")] });
|
|
222
|
+
}).toThrow(
|
|
223
|
+
"cannot infer data type of symbol when constructing a Series from a JS array",
|
|
224
|
+
);
|
|
225
|
+
});
|
|
226
|
+
|
|
204
227
|
it("should decode keys from snake_case to camelCase", () => {
|
|
205
228
|
const a = new Series({
|
|
206
229
|
data: [{ a_b: 1, b_c: "apple" }],
|
|
@@ -353,23 +376,47 @@ describe("Series", () => {
|
|
|
353
376
|
});
|
|
354
377
|
|
|
355
378
|
describe("min and max", () => {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
379
|
+
describe("numbers", () => {
|
|
380
|
+
it("should return a min and max of zero on an allocated array", () => {
|
|
381
|
+
const series = Series.alloc({ capacity: 10, dataType: DataType.FLOAT32 });
|
|
382
|
+
expect(series.max).toEqual(-Infinity);
|
|
383
|
+
expect(series.min).toEqual(Infinity);
|
|
384
|
+
});
|
|
385
|
+
it("should correctly calculate the min and max of a lazy array", () => {
|
|
386
|
+
const series = new Series({
|
|
387
|
+
data: new Float32Array([1, 2, 3]),
|
|
388
|
+
dataType: DataType.FLOAT32,
|
|
389
|
+
});
|
|
390
|
+
expect(series.max).toEqual(3);
|
|
391
|
+
expect(series.min).toEqual(1);
|
|
392
|
+
});
|
|
360
393
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
394
|
+
describe("bigints", () => {
|
|
395
|
+
it("should return a min and max of zero on an allocated array", () => {
|
|
396
|
+
const series = Series.alloc({ capacity: 10, dataType: DataType.INT64 });
|
|
397
|
+
expect(series.max).toEqual(-Infinity);
|
|
398
|
+
expect(series.min).toEqual(Infinity);
|
|
399
|
+
});
|
|
400
|
+
it("should correctly calculate the min and max of a lazy array", () => {
|
|
401
|
+
const series = new Series({
|
|
402
|
+
data: new BigInt64Array([1n, 2n, 3n]),
|
|
403
|
+
dataType: DataType.INT64,
|
|
404
|
+
});
|
|
405
|
+
expect(series.max).toEqual(3n);
|
|
406
|
+
expect(series.min).toEqual(1n);
|
|
365
407
|
});
|
|
366
|
-
expect(series.max).toEqual(3);
|
|
367
|
-
expect(series.min).toEqual(1);
|
|
368
408
|
});
|
|
369
409
|
it("should throw an error if that data type is not numeric", () => {
|
|
370
|
-
const series = new Series({
|
|
371
|
-
|
|
372
|
-
|
|
410
|
+
const series = new Series({
|
|
411
|
+
data: ["a", "b", "c"],
|
|
412
|
+
dataType: DataType.STRING,
|
|
413
|
+
});
|
|
414
|
+
expect(() => series.min).toThrow(
|
|
415
|
+
"cannot calculate minimum on a variable length data type",
|
|
416
|
+
);
|
|
417
|
+
expect(() => series.max).toThrow(
|
|
418
|
+
"cannot calculate maximum on a variable length data type",
|
|
419
|
+
);
|
|
373
420
|
});
|
|
374
421
|
});
|
|
375
422
|
|
|
@@ -404,7 +451,7 @@ describe("Series", () => {
|
|
|
404
451
|
});
|
|
405
452
|
});
|
|
406
453
|
|
|
407
|
-
describe("
|
|
454
|
+
describe("write", () => {
|
|
408
455
|
it("should correctly write to an allocated lazy array", () => {
|
|
409
456
|
const series = Series.alloc({ capacity: 10, dataType: DataType.FLOAT32 });
|
|
410
457
|
expect(series.byteCapacity).toEqual(Size.bytes(40));
|
|
@@ -419,11 +466,27 @@ describe("Series", () => {
|
|
|
419
466
|
|
|
420
467
|
it("should recompute cached max and min correctly", () => {
|
|
421
468
|
const series = Series.alloc({ capacity: 10, dataType: DataType.FLOAT32 });
|
|
422
|
-
series.
|
|
423
|
-
|
|
424
|
-
|
|
469
|
+
expect(series.max).toEqual(-Infinity);
|
|
470
|
+
expect(series.min).toEqual(Infinity);
|
|
471
|
+
const writeOne = new Series({ data: new Float32Array([2, 3]) });
|
|
472
|
+
series.write(writeOne);
|
|
425
473
|
expect(series.max).toEqual(3);
|
|
426
474
|
expect(series.min).toEqual(2);
|
|
475
|
+
const writeTwo = new Series({ data: new Float32Array([4, 5]) });
|
|
476
|
+
series.write(writeTwo);
|
|
477
|
+
expect(series.max).toEqual(5);
|
|
478
|
+
expect(series.min).toEqual(2);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("should recompute the length of a variable density array", () => {
|
|
482
|
+
const series = Series.alloc({ capacity: 12, dataType: DataType.STRING });
|
|
483
|
+
expect(series.length).toEqual(0);
|
|
484
|
+
const writeOne = new Series({ data: ["apple"] });
|
|
485
|
+
expect(series.write(writeOne)).toEqual(1);
|
|
486
|
+
expect(series.length).toEqual(1);
|
|
487
|
+
const writeTwo = new Series({ data: ["apple"] });
|
|
488
|
+
expect(series.write(writeTwo)).toEqual(1);
|
|
489
|
+
expect(series.length).toEqual(2);
|
|
427
490
|
});
|
|
428
491
|
|
|
429
492
|
it("should correctly adjust the sample offset of a written array", () => {
|
|
@@ -448,27 +511,6 @@ describe("Series", () => {
|
|
|
448
511
|
});
|
|
449
512
|
});
|
|
450
513
|
|
|
451
|
-
describe("createTimeStamps", () => {
|
|
452
|
-
it("should correctly create timestamps", () => {
|
|
453
|
-
const ts = Series.createTimestamps(5, Rate.hz(1), TimeStamp.seconds(1));
|
|
454
|
-
expect(ts.timeRange).toEqual(
|
|
455
|
-
new TimeRange(TimeStamp.seconds(1), TimeStamp.seconds(6)),
|
|
456
|
-
);
|
|
457
|
-
expect(ts.capacity).toEqual(5);
|
|
458
|
-
expect(ts.length).toEqual(5);
|
|
459
|
-
expect(ts.dataType.toString()).toEqual(DataType.TIMESTAMP.toString());
|
|
460
|
-
expect(ts.data).toEqual(
|
|
461
|
-
new BigInt64Array([
|
|
462
|
-
BigInt(TimeStamp.seconds(1).valueOf()),
|
|
463
|
-
BigInt(TimeStamp.seconds(2).valueOf()),
|
|
464
|
-
BigInt(TimeStamp.seconds(3).valueOf()),
|
|
465
|
-
BigInt(TimeStamp.seconds(4).valueOf()),
|
|
466
|
-
BigInt(TimeStamp.seconds(5).valueOf()),
|
|
467
|
-
]),
|
|
468
|
-
);
|
|
469
|
-
});
|
|
470
|
-
});
|
|
471
|
-
|
|
472
514
|
describe("webgl buffering", () => {
|
|
473
515
|
it("should correctly buffer a new lazy array", () => {
|
|
474
516
|
const series = new Series({
|
|
@@ -486,6 +528,7 @@ describe("Series", () => {
|
|
|
486
528
|
expect(buf.byteLength).toEqual(12);
|
|
487
529
|
expect(buf).toEqual(new Float32Array([1, 2, 3]).buffer);
|
|
488
530
|
});
|
|
531
|
+
|
|
489
532
|
it("should correctly update a buffer when writing to an allocated array", () => {
|
|
490
533
|
const series = Series.alloc({ capacity: 10, dataType: DataType.FLOAT32 });
|
|
491
534
|
const controller = new MockGLBufferController();
|
|
@@ -560,35 +603,12 @@ describe("Series", () => {
|
|
|
560
603
|
|
|
561
604
|
describe("string series", () => {
|
|
562
605
|
it("should correctly encode and decode a string series", () => {
|
|
563
|
-
const s = Series
|
|
606
|
+
const s = new Series(["apple", "banana", "carrot"]);
|
|
564
607
|
expect(s.dataType.toString()).toEqual(DataType.STRING.toString());
|
|
565
608
|
const outStrings = s.toStrings();
|
|
566
609
|
expect(outStrings).toEqual(["apple", "banana", "carrot"]);
|
|
567
610
|
});
|
|
568
611
|
|
|
569
|
-
it("should throw an error if the series is not of type string", () => {
|
|
570
|
-
const s = new Series({ data: new Float32Array([1, 2, 3]) });
|
|
571
|
-
expect(() => {
|
|
572
|
-
s.toStrings();
|
|
573
|
-
}).toThrow();
|
|
574
|
-
});
|
|
575
|
-
|
|
576
|
-
it("should not throw an error if the series is of type UUID", () => {
|
|
577
|
-
const s = new Series({
|
|
578
|
-
data: new Uint8Array([1, 2, 3]),
|
|
579
|
-
dataType: DataType.UUID,
|
|
580
|
-
});
|
|
581
|
-
expect(() => {
|
|
582
|
-
s.toStrings();
|
|
583
|
-
}).not.toThrow();
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
it("should return an array of length 0 if the series is empty", () => {
|
|
587
|
-
const s = new Series({ data: new Float32Array([]), dataType: DataType.STRING });
|
|
588
|
-
const outStrings = s.toStrings();
|
|
589
|
-
expect(outStrings).toEqual([]);
|
|
590
|
-
});
|
|
591
|
-
|
|
592
612
|
it("should allow allocation of a particular byte capacity", () => {
|
|
593
613
|
const s = Series.alloc({ capacity: 10, dataType: DataType.STRING });
|
|
594
614
|
expect(s.byteCapacity).toEqual(Size.bytes(10));
|
|
@@ -634,7 +654,7 @@ describe("Series", () => {
|
|
|
634
654
|
a: z.number(),
|
|
635
655
|
b: z.string(),
|
|
636
656
|
});
|
|
637
|
-
const s = Series
|
|
657
|
+
const s = new Series([
|
|
638
658
|
{ a: 1, b: "apple" },
|
|
639
659
|
{ a: 2, b: "banana" },
|
|
640
660
|
{ a: 3, b: "carrot" },
|
|
@@ -737,6 +757,106 @@ describe("Series", () => {
|
|
|
737
757
|
});
|
|
738
758
|
});
|
|
739
759
|
|
|
760
|
+
describe("toStrings", () => {
|
|
761
|
+
interface Spec {
|
|
762
|
+
name: string;
|
|
763
|
+
values: CrudeSeries;
|
|
764
|
+
expected: string[];
|
|
765
|
+
dataType?: CrudeDataType;
|
|
766
|
+
}
|
|
767
|
+
const SPECS: Spec[] = [
|
|
768
|
+
{
|
|
769
|
+
name: "string",
|
|
770
|
+
values: ["apple", "banana", "carrot"],
|
|
771
|
+
expected: ["apple", "banana", "carrot"],
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
name: "json",
|
|
775
|
+
values: [
|
|
776
|
+
{ a: 1, b: "apple" },
|
|
777
|
+
{ a: 2, b: "banana" },
|
|
778
|
+
{ a: 3, b: "carrot" },
|
|
779
|
+
],
|
|
780
|
+
expected: [
|
|
781
|
+
'{"a":1,"b":"apple"}',
|
|
782
|
+
'{"a":2,"b":"banana"}',
|
|
783
|
+
'{"a":3,"b":"carrot"}',
|
|
784
|
+
],
|
|
785
|
+
dataType: "json",
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
name: "number",
|
|
789
|
+
values: [1, 2, 3],
|
|
790
|
+
expected: ["1", "2", "3"],
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
name: "bigint",
|
|
794
|
+
values: [BigInt(1), BigInt(2), BigInt(3)],
|
|
795
|
+
expected: ["1", "2", "3"],
|
|
796
|
+
},
|
|
797
|
+
];
|
|
798
|
+
SPECS.forEach(({ name, values, expected }) => {
|
|
799
|
+
it(`should correctly convert a ${name} series to strings`, () => {
|
|
800
|
+
const s = new Series({ data: values });
|
|
801
|
+
expect(s.toStrings()).toEqual(expected);
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it("should return an series of length 0 if the series is empty", () => {
|
|
806
|
+
const s = new Series({ data: new Float32Array([]), dataType: DataType.STRING });
|
|
807
|
+
const outStrings = s.toStrings();
|
|
808
|
+
expect(outStrings).toEqual([]);
|
|
809
|
+
});
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
describe("toUUIDs", () => {
|
|
813
|
+
it("should convert a UUID series to an array of UUID strings", () => {
|
|
814
|
+
// Valid UUID v4 bytes (version 4, variant 1)
|
|
815
|
+
const bytes = new Uint8Array([
|
|
816
|
+
// First UUID: 123e4567-e89b-4xxx-yxxx-426614174000 (version 4, variant 1)
|
|
817
|
+
0x12, 0x3e, 0x45, 0x67, 0xe8, 0x9b, 0x40, 0xd3, 0x80, 0x56, 0x42, 0x66, 0x14,
|
|
818
|
+
0x17, 0x40, 0x00,
|
|
819
|
+
// Second UUID: 7f3e4567-e89b-4xxx-yxxx-426614174000 (version 4, variant 1)
|
|
820
|
+
0x7f, 0x3e, 0x45, 0x67, 0xe8, 0x9b, 0x40, 0xd3, 0x80, 0x56, 0x42, 0x66, 0x14,
|
|
821
|
+
0x17, 0x40, 0x00,
|
|
822
|
+
]);
|
|
823
|
+
const series = new Series({ data: bytes, dataType: DataType.UUID });
|
|
824
|
+
const uuids = series.toUUIDs();
|
|
825
|
+
expect(uuids).toHaveLength(2);
|
|
826
|
+
expect(uuids[0]).toBe("123e4567-e89b-40d3-8056-426614174000");
|
|
827
|
+
expect(uuids[1]).toBe("7f3e4567-e89b-40d3-8056-426614174000");
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it("should throw an error when converting non-UUID series", () => {
|
|
831
|
+
const series = new Series({ data: [1, 2, 3], dataType: DataType.INT32 });
|
|
832
|
+
expect(() => series.toUUIDs()).toThrow("cannot convert non-uuid series to uuids");
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it("should handle empty UUID series", () => {
|
|
836
|
+
const series = new Series({ data: new Uint8Array(), dataType: DataType.UUID });
|
|
837
|
+
const uuids = series.toUUIDs();
|
|
838
|
+
expect(uuids).toHaveLength(0);
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it("should handle series with nil UUID", () => {
|
|
842
|
+
// Nil UUID: 00000000-0000-0000-0000-000000000000
|
|
843
|
+
const bytes = new Uint8Array(16).fill(0);
|
|
844
|
+
const series = new Series({ data: bytes, dataType: DataType.UUID });
|
|
845
|
+
const uuids = series.toUUIDs();
|
|
846
|
+
expect(uuids).toHaveLength(1);
|
|
847
|
+
expect(uuids[0]).toBe("00000000-0000-0000-0000-000000000000");
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
it("should handle series with max UUID", () => {
|
|
851
|
+
// Max UUID: ffffffff-ffff-ffff-ffff-ffffffffffff
|
|
852
|
+
const bytes = new Uint8Array(16).fill(0xff);
|
|
853
|
+
const series = new Series({ data: bytes, dataType: DataType.UUID });
|
|
854
|
+
const uuids = series.toUUIDs();
|
|
855
|
+
expect(uuids).toHaveLength(1);
|
|
856
|
+
expect(uuids[0]).toBe("ffffffff-ffff-ffff-ffff-ffffffffffff");
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
|
|
740
860
|
describe("digest", () => {
|
|
741
861
|
it("should return a digest of information about the series", () => {
|
|
742
862
|
const digest = new Series({
|
|
@@ -777,14 +897,14 @@ describe("Series", () => {
|
|
|
777
897
|
const SPECS: Spec[] = [
|
|
778
898
|
{
|
|
779
899
|
series: new Series({ data: [1, 2, 3, 4], dataType: "float64" }),
|
|
780
|
-
expected: "float64 4 [1,2,3,4]",
|
|
900
|
+
expected: "Series(float64 4 [1,2,3,4])",
|
|
781
901
|
},
|
|
782
902
|
{
|
|
783
903
|
series: new Series({
|
|
784
904
|
data: Array.from({ length: 100 }, (_, i) => i),
|
|
785
905
|
dataType: "float32",
|
|
786
906
|
}),
|
|
787
|
-
expected: "float32 100 [0,1,2,3,4
|
|
907
|
+
expected: "Series(float32 100 [0,1,2,3,4,...,95,96,97,98,99])",
|
|
788
908
|
},
|
|
789
909
|
];
|
|
790
910
|
SPECS.forEach(({ series, expected }) => {
|
|
@@ -837,6 +957,122 @@ describe("Series", () => {
|
|
|
837
957
|
expect(iter.next().done).toBeTruthy();
|
|
838
958
|
});
|
|
839
959
|
});
|
|
960
|
+
|
|
961
|
+
describe("bounds", () => {
|
|
962
|
+
it("should return the bounds of the series", () => {
|
|
963
|
+
const series = new Series({
|
|
964
|
+
data: new Float32Array([1, 2, 3]),
|
|
965
|
+
dataType: DataType.FLOAT32,
|
|
966
|
+
});
|
|
967
|
+
expect(series.bounds).toEqual({ lower: 1, upper: 3 });
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
it("should handle negative numbers", () => {
|
|
971
|
+
const series = new Series({
|
|
972
|
+
data: new Float32Array([-3, -2, -1]),
|
|
973
|
+
dataType: DataType.FLOAT32,
|
|
974
|
+
});
|
|
975
|
+
expect(series.bounds).toEqual({ lower: -3, upper: -1 });
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
it("should handle empty series", () => {
|
|
979
|
+
const series = new Series({
|
|
980
|
+
data: new Float32Array([]),
|
|
981
|
+
dataType: DataType.FLOAT32,
|
|
982
|
+
});
|
|
983
|
+
expect(series.bounds).toEqual({ lower: Infinity, upper: -Infinity });
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
describe("reAlign", () => {
|
|
988
|
+
it("should create a new series with the specified alignment", () => {
|
|
989
|
+
const original = new Series({
|
|
990
|
+
data: new Float32Array([1, 2, 3]),
|
|
991
|
+
dataType: DataType.FLOAT32,
|
|
992
|
+
alignment: 0n,
|
|
993
|
+
});
|
|
994
|
+
const realigned = original.reAlign(10n);
|
|
995
|
+
expect(realigned.alignment).toBe(10n);
|
|
996
|
+
expect(realigned.alignmentBounds).toEqual({ lower: 10n, upper: 13n });
|
|
997
|
+
expect(realigned.data).toEqual(original.data);
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
it("should preserve data when realigning", () => {
|
|
1001
|
+
const original = new Series({
|
|
1002
|
+
data: new Float32Array([1, 2, 3]),
|
|
1003
|
+
dataType: DataType.FLOAT32,
|
|
1004
|
+
alignment: 0n,
|
|
1005
|
+
});
|
|
1006
|
+
const realigned = original.reAlign(10n);
|
|
1007
|
+
expect(realigned.at(0)).toBe(1);
|
|
1008
|
+
expect(realigned.at(1)).toBe(2);
|
|
1009
|
+
expect(realigned.at(2)).toBe(3);
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
it("should update alignment bounds correctly", () => {
|
|
1013
|
+
const original = new Series({
|
|
1014
|
+
data: new Float32Array([1, 2, 3]),
|
|
1015
|
+
dataType: DataType.FLOAT32,
|
|
1016
|
+
alignment: 0n,
|
|
1017
|
+
});
|
|
1018
|
+
const realigned = original.reAlign(10n);
|
|
1019
|
+
expect(realigned.alignmentBounds).toEqual({ lower: 10n, upper: 13n });
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
it("should handle atAlignment with new alignment", () => {
|
|
1023
|
+
const original = new Series({
|
|
1024
|
+
data: new Float32Array([1, 2, 3]),
|
|
1025
|
+
dataType: DataType.FLOAT32,
|
|
1026
|
+
alignment: 0n,
|
|
1027
|
+
});
|
|
1028
|
+
const realigned = original.reAlign(10n);
|
|
1029
|
+
expect(realigned.atAlignment(10n)).toBe(1);
|
|
1030
|
+
expect(realigned.atAlignment(11n)).toBe(2);
|
|
1031
|
+
expect(realigned.atAlignment(12n)).toBe(3);
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
it("should handle bigint series", () => {
|
|
1035
|
+
const original = new Series({
|
|
1036
|
+
data: new BigInt64Array([1n, 2n, 3n]),
|
|
1037
|
+
dataType: DataType.INT64,
|
|
1038
|
+
alignment: 0n,
|
|
1039
|
+
});
|
|
1040
|
+
const realigned = original.reAlign(10n);
|
|
1041
|
+
expect(realigned.alignment).toBe(10n);
|
|
1042
|
+
expect(realigned.alignmentBounds).toEqual({ lower: 10n, upper: 13n });
|
|
1043
|
+
expect(realigned.at(0)).toBe(1n);
|
|
1044
|
+
expect(realigned.at(1)).toBe(2n);
|
|
1045
|
+
expect(realigned.at(2)).toBe(3n);
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
it("should handle variable length data types", () => {
|
|
1049
|
+
const original = new Series({
|
|
1050
|
+
data: ["a", "b", "c"],
|
|
1051
|
+
dataType: DataType.STRING,
|
|
1052
|
+
alignment: 0n,
|
|
1053
|
+
});
|
|
1054
|
+
const realigned = original.reAlign(10n);
|
|
1055
|
+
expect(realigned.alignment).toBe(10n);
|
|
1056
|
+
expect(realigned.alignmentBounds).toEqual({ lower: 10n, upper: 13n });
|
|
1057
|
+
expect(realigned.at(0)).toBe("a");
|
|
1058
|
+
expect(realigned.at(1)).toBe("b");
|
|
1059
|
+
expect(realigned.at(2)).toBe("c");
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
it("should preserve sample offset", () => {
|
|
1063
|
+
const original = new Series({
|
|
1064
|
+
data: new Float32Array([1, 2, 3]),
|
|
1065
|
+
dataType: DataType.FLOAT32,
|
|
1066
|
+
alignment: 0n,
|
|
1067
|
+
sampleOffset: 10,
|
|
1068
|
+
});
|
|
1069
|
+
const realigned = original.reAlign(10n);
|
|
1070
|
+
expect(realigned.sampleOffset).toBe(10);
|
|
1071
|
+
expect(realigned.at(0)).toBe(11);
|
|
1072
|
+
expect(realigned.at(1)).toBe(12);
|
|
1073
|
+
expect(realigned.at(2)).toBe(13);
|
|
1074
|
+
});
|
|
1075
|
+
});
|
|
840
1076
|
});
|
|
841
1077
|
|
|
842
1078
|
describe("MultiSeries", () => {
|
|
@@ -872,6 +1108,20 @@ describe("MultiSeries", () => {
|
|
|
872
1108
|
expect(multi.at(-5)).toEqual(2);
|
|
873
1109
|
expect(multi.at(-6)).toEqual(1);
|
|
874
1110
|
});
|
|
1111
|
+
|
|
1112
|
+
it("should return undefined if the index is not found", () => {
|
|
1113
|
+
const a = new Series(new Float32Array([1, 2, 3]));
|
|
1114
|
+
const b = new Series(new Float32Array([4, 5, 6]));
|
|
1115
|
+
const multi = new MultiSeries([a, b]);
|
|
1116
|
+
expect(multi.at(10)).toBeUndefined();
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
it("should throw an error if the index is not found and required is true", () => {
|
|
1120
|
+
const a = new Series(new Float32Array([1, 2, 3]));
|
|
1121
|
+
const b = new Series(new Float32Array([4, 5, 6]));
|
|
1122
|
+
const multi = new MultiSeries([a, b]);
|
|
1123
|
+
expect(() => multi.at(10, true)).toThrow();
|
|
1124
|
+
});
|
|
875
1125
|
});
|
|
876
1126
|
|
|
877
1127
|
describe("atAlignment", () => {
|
|
@@ -892,6 +1142,24 @@ describe("MultiSeries", () => {
|
|
|
892
1142
|
expect(multi.atAlignment(6n)).toEqual(5);
|
|
893
1143
|
expect(multi.atAlignment(7n)).toEqual(6);
|
|
894
1144
|
});
|
|
1145
|
+
|
|
1146
|
+
it("should return undefined if the alignment is not found", () => {
|
|
1147
|
+
const a = new Series({
|
|
1148
|
+
data: new Float32Array([1, 2, 3]),
|
|
1149
|
+
alignment: 1n,
|
|
1150
|
+
});
|
|
1151
|
+
const multi = new MultiSeries([a]);
|
|
1152
|
+
expect(multi.atAlignment(45n)).toBeUndefined();
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
it("should throw if the alignment is not found and required is true", () => {
|
|
1156
|
+
const a = new Series({
|
|
1157
|
+
data: new Float32Array([1, 2, 3]),
|
|
1158
|
+
alignment: 1n,
|
|
1159
|
+
});
|
|
1160
|
+
const multi = new MultiSeries([a]);
|
|
1161
|
+
expect(() => multi.atAlignment(45n, true)).toThrow();
|
|
1162
|
+
});
|
|
895
1163
|
});
|
|
896
1164
|
|
|
897
1165
|
describe("subIterator", () => {
|
|
@@ -1135,4 +1403,403 @@ describe("MultiSeries", () => {
|
|
|
1135
1403
|
expect(() => multi.as("string")).toThrow();
|
|
1136
1404
|
});
|
|
1137
1405
|
});
|
|
1406
|
+
|
|
1407
|
+
describe("bounds", () => {
|
|
1408
|
+
it("should return bounds of [Infinity, -Infinity] for an empty MultiSeries", () => {
|
|
1409
|
+
const multiSeries = new MultiSeries();
|
|
1410
|
+
expect(multiSeries.bounds).toEqual({ lower: Infinity, upper: -Infinity });
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
it("should correctly calculate bounds across multiple series", () => {
|
|
1414
|
+
const series1 = new Series({
|
|
1415
|
+
data: new Float32Array([1, 2, 3]),
|
|
1416
|
+
dataType: DataType.FLOAT32,
|
|
1417
|
+
});
|
|
1418
|
+
const series2 = new Series({
|
|
1419
|
+
data: new Float32Array([4, 5, 6]),
|
|
1420
|
+
dataType: DataType.FLOAT32,
|
|
1421
|
+
});
|
|
1422
|
+
const multiSeries = new MultiSeries([series1, series2]);
|
|
1423
|
+
expect(multiSeries.bounds).toEqual({ lower: 1, upper: 6 });
|
|
1424
|
+
});
|
|
1425
|
+
|
|
1426
|
+
it("should handle negative numbers across series", () => {
|
|
1427
|
+
const series1 = new Series({
|
|
1428
|
+
data: new Float32Array([-5, -3, -1]),
|
|
1429
|
+
dataType: DataType.FLOAT32,
|
|
1430
|
+
});
|
|
1431
|
+
const series2 = new Series({
|
|
1432
|
+
data: new Float32Array([0, 2, 4]),
|
|
1433
|
+
dataType: DataType.FLOAT32,
|
|
1434
|
+
});
|
|
1435
|
+
const multiSeries = new MultiSeries([series1, series2]);
|
|
1436
|
+
expect(multiSeries.bounds).toEqual({ lower: -5, upper: 4 });
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
it("should handle sample offsets across series", () => {
|
|
1440
|
+
const series1 = new Series({
|
|
1441
|
+
data: new Float32Array([1, 2, 3]),
|
|
1442
|
+
dataType: DataType.FLOAT32,
|
|
1443
|
+
sampleOffset: 10,
|
|
1444
|
+
});
|
|
1445
|
+
const series2 = new Series({
|
|
1446
|
+
data: new Float32Array([4, 5, 6]),
|
|
1447
|
+
dataType: DataType.FLOAT32,
|
|
1448
|
+
sampleOffset: 20,
|
|
1449
|
+
});
|
|
1450
|
+
const multiSeries = new MultiSeries([series1, series2]);
|
|
1451
|
+
expect(multiSeries.bounds).toEqual({ lower: 11, upper: 26 });
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
it("should handle bigint series", () => {
|
|
1455
|
+
const series1 = new Series({
|
|
1456
|
+
data: new BigInt64Array([1n, 2n, 3n]),
|
|
1457
|
+
dataType: DataType.INT64,
|
|
1458
|
+
});
|
|
1459
|
+
const series2 = new Series({
|
|
1460
|
+
data: new BigInt64Array([4n, 5n, 6n]),
|
|
1461
|
+
dataType: DataType.INT64,
|
|
1462
|
+
});
|
|
1463
|
+
const multiSeries = new MultiSeries([series1, series2]);
|
|
1464
|
+
expect(multiSeries.bounds).toEqual({ lower: 1, upper: 6 });
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
it("should throw an error for non-numeric data types", () => {
|
|
1468
|
+
const series1 = new Series({
|
|
1469
|
+
data: ["a", "b", "c"],
|
|
1470
|
+
dataType: DataType.STRING,
|
|
1471
|
+
});
|
|
1472
|
+
const series2 = new Series({
|
|
1473
|
+
data: ["d", "e", "f"],
|
|
1474
|
+
dataType: DataType.STRING,
|
|
1475
|
+
});
|
|
1476
|
+
const multiSeries = new MultiSeries([series1, series2]);
|
|
1477
|
+
expect(() => multiSeries.bounds).toThrow(
|
|
1478
|
+
"cannot calculate minimum on a variable length data type",
|
|
1479
|
+
);
|
|
1480
|
+
});
|
|
1481
|
+
});
|
|
1482
|
+
|
|
1483
|
+
describe("subAlignmentSpanIterator", () => {
|
|
1484
|
+
it("should return an empty iterator when start is beyond bounds", () => {
|
|
1485
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1486
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 3n });
|
|
1487
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1488
|
+
const iter = ms.subAlignmentSpanIterator(10n, 5);
|
|
1489
|
+
expect(Array.from(iter)).toEqual([]);
|
|
1490
|
+
});
|
|
1491
|
+
|
|
1492
|
+
it("should return an empty iterator when start is at upper bound", () => {
|
|
1493
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1494
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 3n });
|
|
1495
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1496
|
+
const iter = ms.subAlignmentSpanIterator(6n, 5);
|
|
1497
|
+
expect(Array.from(iter)).toEqual([]);
|
|
1498
|
+
});
|
|
1499
|
+
|
|
1500
|
+
it("should iterate over samples within a single series", () => {
|
|
1501
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1502
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 3n });
|
|
1503
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1504
|
+
const iter = ms.subAlignmentSpanIterator(1n, 2);
|
|
1505
|
+
expect(Array.from(iter)).toEqual([2, 3]);
|
|
1506
|
+
});
|
|
1507
|
+
|
|
1508
|
+
it("should iterate over samples across multiple series", () => {
|
|
1509
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1510
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 3n });
|
|
1511
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1512
|
+
const iter = ms.subAlignmentSpanIterator(2n, 3);
|
|
1513
|
+
expect(Array.from(iter)).toEqual([3, 4, 5]);
|
|
1514
|
+
});
|
|
1515
|
+
|
|
1516
|
+
it("should handle span that exceeds available data", () => {
|
|
1517
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1518
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 3n });
|
|
1519
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1520
|
+
const iter = ms.subAlignmentSpanIterator(4n, 10);
|
|
1521
|
+
expect(Array.from(iter)).toEqual([5, 6]);
|
|
1522
|
+
});
|
|
1523
|
+
|
|
1524
|
+
it("should handle span that exceeds available data with non-continuous spans", () => {
|
|
1525
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 0n });
|
|
1526
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 500000000n });
|
|
1527
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1528
|
+
const iter = ms.subAlignmentSpanIterator(4n, 10000000000);
|
|
1529
|
+
expect(Array.from(iter)).toEqual([4, 5, 6]);
|
|
1530
|
+
});
|
|
1531
|
+
|
|
1532
|
+
it("should handle empty series", () => {
|
|
1533
|
+
const ms = new MultiSeries();
|
|
1534
|
+
const iter = ms.subAlignmentSpanIterator(0n, 5);
|
|
1535
|
+
expect(Array.from(iter)).toEqual([]);
|
|
1536
|
+
});
|
|
1537
|
+
|
|
1538
|
+
it("should handle start alignment before first series", () => {
|
|
1539
|
+
const s1 = new Series({ data: [1, 2, 3], alignment: 2n });
|
|
1540
|
+
const s2 = new Series({ data: [4, 5, 6], alignment: 5n });
|
|
1541
|
+
const ms = new MultiSeries([s1, s2]);
|
|
1542
|
+
const iter = ms.subAlignmentSpanIterator(0n, 4);
|
|
1543
|
+
expect(Array.from(iter)).toEqual([1, 2, 3, 4]);
|
|
1544
|
+
});
|
|
1545
|
+
});
|
|
1546
|
+
|
|
1547
|
+
describe("traverseAlignment", () => {
|
|
1548
|
+
it("should traverse alignment across multiple series", () => {
|
|
1549
|
+
const a = new Series({
|
|
1550
|
+
data: new Float32Array([1, 2, 3]),
|
|
1551
|
+
alignment: 1n,
|
|
1552
|
+
});
|
|
1553
|
+
const b = new Series({
|
|
1554
|
+
data: new Float32Array([5, 6, 7]),
|
|
1555
|
+
alignment: 5n,
|
|
1556
|
+
});
|
|
1557
|
+
const multi = new MultiSeries([a, b]);
|
|
1558
|
+
expect(multi.traverseAlignment(1n, 2n)).toEqual(3n);
|
|
1559
|
+
expect(multi.traverseAlignment(2n, 4n)).toEqual(7n);
|
|
1560
|
+
expect(multi.traverseAlignment(5n, 2n)).toEqual(7n);
|
|
1561
|
+
});
|
|
1562
|
+
|
|
1563
|
+
it("should handle empty multi-series", () => {
|
|
1564
|
+
const multi = new MultiSeries();
|
|
1565
|
+
expect(multi.traverseAlignment(1n, 2n)).toEqual(1n);
|
|
1566
|
+
});
|
|
1567
|
+
});
|
|
1568
|
+
|
|
1569
|
+
describe("acquire and release", () => {
|
|
1570
|
+
it("should acquire and release all series in the multi-series", () => {
|
|
1571
|
+
const a = new Series({
|
|
1572
|
+
data: new Float32Array([1, 2, 3]),
|
|
1573
|
+
dataType: DataType.FLOAT32,
|
|
1574
|
+
});
|
|
1575
|
+
const b = new Series({
|
|
1576
|
+
data: new Float32Array([4, 5, 6]),
|
|
1577
|
+
dataType: DataType.FLOAT32,
|
|
1578
|
+
});
|
|
1579
|
+
const multi = new MultiSeries([a, b]);
|
|
1580
|
+
const controller = new MockGLBufferController();
|
|
1581
|
+
|
|
1582
|
+
multi.acquire(controller);
|
|
1583
|
+
expect(a.refCount).toEqual(1);
|
|
1584
|
+
expect(b.refCount).toEqual(1);
|
|
1585
|
+
expect(controller.createBufferMock).toHaveBeenCalledTimes(2);
|
|
1586
|
+
|
|
1587
|
+
multi.release();
|
|
1588
|
+
expect(a.refCount).toEqual(0);
|
|
1589
|
+
expect(b.refCount).toEqual(0);
|
|
1590
|
+
expect(controller.deleteBufferMock).toHaveBeenCalledTimes(2);
|
|
1591
|
+
});
|
|
1592
|
+
|
|
1593
|
+
it("should handle empty multi-series", () => {
|
|
1594
|
+
const multi = new MultiSeries();
|
|
1595
|
+
const controller = new MockGLBufferController();
|
|
1596
|
+
multi.acquire(controller);
|
|
1597
|
+
multi.release();
|
|
1598
|
+
});
|
|
1599
|
+
});
|
|
1600
|
+
|
|
1601
|
+
describe("distance", () => {
|
|
1602
|
+
it("should calculate distance between alignments across multiple series", () => {
|
|
1603
|
+
const a = new Series({
|
|
1604
|
+
data: new Float32Array([1, 2, 3]),
|
|
1605
|
+
alignment: 1n,
|
|
1606
|
+
});
|
|
1607
|
+
const b = new Series({
|
|
1608
|
+
data: new Float32Array([5, 6, 7]),
|
|
1609
|
+
alignment: 5n,
|
|
1610
|
+
});
|
|
1611
|
+
const multi = new MultiSeries([a, b]);
|
|
1612
|
+
|
|
1613
|
+
expect(multi.distance(1n, 3n)).toEqual(2n);
|
|
1614
|
+
expect(multi.distance(2n, 6n)).toEqual(3n);
|
|
1615
|
+
expect(multi.distance(5n, 7n)).toEqual(2n);
|
|
1616
|
+
});
|
|
1617
|
+
|
|
1618
|
+
it("should handle empty multi-series", () => {
|
|
1619
|
+
const multi = new MultiSeries();
|
|
1620
|
+
expect(multi.distance(1n, 2n)).toEqual(0n);
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
it("should handle zero distance", () => {
|
|
1624
|
+
const a = new Series({
|
|
1625
|
+
data: new Float32Array([1, 2, 3]),
|
|
1626
|
+
alignment: 1n,
|
|
1627
|
+
});
|
|
1628
|
+
const multi = new MultiSeries([a]);
|
|
1629
|
+
expect(multi.distance(1n, 1n)).toEqual(0n);
|
|
1630
|
+
});
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
describe("byteLength", () => {
|
|
1634
|
+
it("should return the sum of byte lengths of all series", () => {
|
|
1635
|
+
const a = new Series({
|
|
1636
|
+
data: new Float32Array([1, 2, 3]),
|
|
1637
|
+
dataType: DataType.FLOAT32,
|
|
1638
|
+
});
|
|
1639
|
+
const b = new Series({
|
|
1640
|
+
data: new Float32Array([4, 5, 6]),
|
|
1641
|
+
dataType: DataType.FLOAT32,
|
|
1642
|
+
});
|
|
1643
|
+
const multi = new MultiSeries([a, b]);
|
|
1644
|
+
expect(multi.byteLength).toEqual(Size.bytes(24)); // 12 bytes per series (3 * 4 bytes)
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
it("should return 0 for empty multi-series", () => {
|
|
1648
|
+
const multi = new MultiSeries();
|
|
1649
|
+
expect(multi.byteLength).toEqual(Size.bytes(0));
|
|
1650
|
+
});
|
|
1651
|
+
});
|
|
1652
|
+
|
|
1653
|
+
describe("updateGLBuffer", () => {
|
|
1654
|
+
it("should update GL buffers for all series", () => {
|
|
1655
|
+
const a = new Series({
|
|
1656
|
+
data: new Float32Array([1, 2, 3]),
|
|
1657
|
+
dataType: DataType.FLOAT32,
|
|
1658
|
+
});
|
|
1659
|
+
const b = new Series({
|
|
1660
|
+
data: new Float32Array([4, 5, 6]),
|
|
1661
|
+
dataType: DataType.FLOAT32,
|
|
1662
|
+
});
|
|
1663
|
+
const multi = new MultiSeries([a, b]);
|
|
1664
|
+
const controller = new MockGLBufferController();
|
|
1665
|
+
|
|
1666
|
+
multi.updateGLBuffer(controller);
|
|
1667
|
+
|
|
1668
|
+
expect(controller.createBufferMock).toHaveBeenCalledTimes(2);
|
|
1669
|
+
expect(controller.bindBufferMock).toHaveBeenCalledTimes(2);
|
|
1670
|
+
expect(controller.bufferDataMock).toHaveBeenCalledTimes(2);
|
|
1671
|
+
});
|
|
1672
|
+
|
|
1673
|
+
it("should handle empty multi-series", () => {
|
|
1674
|
+
const multi = new MultiSeries();
|
|
1675
|
+
const controller = new MockGLBufferController();
|
|
1676
|
+
|
|
1677
|
+
multi.updateGLBuffer(controller);
|
|
1678
|
+
|
|
1679
|
+
expect(controller.createBufferMock).not.toHaveBeenCalled();
|
|
1680
|
+
expect(controller.bindBufferMock).not.toHaveBeenCalled();
|
|
1681
|
+
expect(controller.bufferDataMock).not.toHaveBeenCalled();
|
|
1682
|
+
});
|
|
1683
|
+
|
|
1684
|
+
it("should throw error for non-FLOAT32/UINT8 series", () => {
|
|
1685
|
+
const a = new Series({
|
|
1686
|
+
data: new BigInt64Array([BigInt(1), BigInt(2)]),
|
|
1687
|
+
dataType: DataType.INT64,
|
|
1688
|
+
});
|
|
1689
|
+
const multi = new MultiSeries([a]);
|
|
1690
|
+
const controller = new MockGLBufferController();
|
|
1691
|
+
|
|
1692
|
+
expect(() => multi.updateGLBuffer(controller)).toThrow(
|
|
1693
|
+
"Only FLOAT32 and UINT8 arrays can be used in WebGL",
|
|
1694
|
+
);
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1697
|
+
it("should handle series with different buffer states", () => {
|
|
1698
|
+
const a = new Series({
|
|
1699
|
+
data: new Float32Array([1, 2, 3]),
|
|
1700
|
+
dataType: DataType.FLOAT32,
|
|
1701
|
+
});
|
|
1702
|
+
const b = Series.alloc({ capacity: 10, dataType: DataType.FLOAT32 });
|
|
1703
|
+
const multi = new MultiSeries([a, b]);
|
|
1704
|
+
const controller = new MockGLBufferController();
|
|
1705
|
+
|
|
1706
|
+
multi.updateGLBuffer(controller);
|
|
1707
|
+
|
|
1708
|
+
expect(controller.createBufferMock).toHaveBeenCalledTimes(2);
|
|
1709
|
+
expect(controller.bindBufferMock).toHaveBeenCalledTimes(1);
|
|
1710
|
+
expect(controller.bufferDataMock).toHaveBeenCalledTimes(1);
|
|
1711
|
+
});
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1714
|
+
describe("push", () => {
|
|
1715
|
+
it("should push a single Series to an empty MultiSeries", () => {
|
|
1716
|
+
const series = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1717
|
+
const multiSeries = new MultiSeries();
|
|
1718
|
+
multiSeries.push(series);
|
|
1719
|
+
expect(multiSeries.series.length).toBe(1);
|
|
1720
|
+
expect(multiSeries.series[0]).toBe(series);
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
it("should push a single Series to a non-empty MultiSeries", () => {
|
|
1724
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1725
|
+
const series2 = new Series({ data: [4, 5, 6], dataType: DataType.FLOAT32 });
|
|
1726
|
+
const multiSeries = new MultiSeries([series1]);
|
|
1727
|
+
multiSeries.push(series2);
|
|
1728
|
+
expect(multiSeries.series.length).toBe(2);
|
|
1729
|
+
expect(multiSeries.series[0]).toBe(series1);
|
|
1730
|
+
expect(multiSeries.series[1]).toBe(series2);
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1733
|
+
it("should push a MultiSeries to another MultiSeries", () => {
|
|
1734
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1735
|
+
const series2 = new Series({ data: [4, 5, 6], dataType: DataType.FLOAT32 });
|
|
1736
|
+
const multiSeries1 = new MultiSeries([series1]);
|
|
1737
|
+
const multiSeries2 = new MultiSeries([series2]);
|
|
1738
|
+
multiSeries1.push(multiSeries2);
|
|
1739
|
+
expect(multiSeries1.series.length).toBe(2);
|
|
1740
|
+
expect(multiSeries1.series[0]).toBe(series1);
|
|
1741
|
+
expect(multiSeries1.series[1]).toBe(series2);
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
it("should maintain data type consistency when pushing series", () => {
|
|
1745
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1746
|
+
const series2 = new Series({ data: [4, 5, 6], dataType: DataType.FLOAT32 });
|
|
1747
|
+
const multiSeries = new MultiSeries([series1]);
|
|
1748
|
+
multiSeries.push(series2);
|
|
1749
|
+
expect(multiSeries.dataType).toEqual(DataType.FLOAT32);
|
|
1750
|
+
});
|
|
1751
|
+
|
|
1752
|
+
it("should push an empty MultiSeries to a non-empty MultiSeries", () => {
|
|
1753
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1754
|
+
const multiSeries1 = new MultiSeries([series1]);
|
|
1755
|
+
const multiSeries2 = new MultiSeries();
|
|
1756
|
+
multiSeries1.push(multiSeries2);
|
|
1757
|
+
expect(multiSeries1.series.length).toBe(1);
|
|
1758
|
+
});
|
|
1759
|
+
|
|
1760
|
+
it("should push an empty MultiSeries to an empty MultiSeries", () => {
|
|
1761
|
+
const multiSeries1 = new MultiSeries();
|
|
1762
|
+
const multiSeries2 = new MultiSeries();
|
|
1763
|
+
multiSeries1.push(multiSeries2);
|
|
1764
|
+
expect(multiSeries1.series.length).toBe(0);
|
|
1765
|
+
});
|
|
1766
|
+
|
|
1767
|
+
it("should update time range when pushing series", () => {
|
|
1768
|
+
const timeRange1 = new TimeRange(1, 2);
|
|
1769
|
+
const timeRange2 = new TimeRange(2, 3);
|
|
1770
|
+
const series1 = new Series({
|
|
1771
|
+
data: [1, 2, 3],
|
|
1772
|
+
dataType: DataType.FLOAT32,
|
|
1773
|
+
timeRange: timeRange1,
|
|
1774
|
+
});
|
|
1775
|
+
const series2 = new Series({
|
|
1776
|
+
data: [4, 5, 6],
|
|
1777
|
+
dataType: DataType.FLOAT32,
|
|
1778
|
+
timeRange: timeRange2,
|
|
1779
|
+
});
|
|
1780
|
+
const multiSeries = new MultiSeries([series1]);
|
|
1781
|
+
multiSeries.push(series2);
|
|
1782
|
+
expect(multiSeries.timeRange.start.valueOf()).toBe(1n);
|
|
1783
|
+
expect(multiSeries.timeRange.end.valueOf()).toBe(3n);
|
|
1784
|
+
});
|
|
1785
|
+
|
|
1786
|
+
it("should throw an error when pushing a series with a different data type", () => {
|
|
1787
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1788
|
+
const series2 = new Series({ data: [4, 5, 6], dataType: DataType.INT64 });
|
|
1789
|
+
const multiSeries = new MultiSeries([series1]);
|
|
1790
|
+
expect(() => multiSeries.push(series2)).toThrow(
|
|
1791
|
+
"cannot push a int64 series to a float32 multi-series",
|
|
1792
|
+
);
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
it("should throw an error when pushing a multi-series with a different data type", () => {
|
|
1796
|
+
const series1 = new Series({ data: [1, 2, 3], dataType: DataType.FLOAT32 });
|
|
1797
|
+
const series2 = new Series({ data: [4, 5, 6], dataType: DataType.INT64 });
|
|
1798
|
+
const multiSeries1 = new MultiSeries([series1]);
|
|
1799
|
+
const multiSeries2 = new MultiSeries([series2]);
|
|
1800
|
+
expect(() => multiSeries1.push(multiSeries2)).toThrow(
|
|
1801
|
+
"cannot push a int64 series to a float32 multi-series",
|
|
1802
|
+
);
|
|
1803
|
+
});
|
|
1804
|
+
});
|
|
1138
1805
|
});
|