@synnaxlabs/x 0.7.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/.eslintrc.cjs +18 -0
- package/.turbo/turbo-build.log +16 -0
- package/.vscode/settings.json +3 -0
- package/LICENSE +4 -0
- package/README.md +44 -0
- package/dist/binary/encoder.d.ts +59 -0
- package/dist/binary/encoder.spec.d.ts +1 -0
- package/dist/binary/index.d.ts +1 -0
- package/dist/case.d.ts +5 -0
- package/dist/change/change.d.ts +32 -0
- package/dist/change/index.d.ts +1 -0
- package/dist/clamp.d.ts +1 -0
- package/dist/compare/compare.d.ts +39 -0
- package/dist/compare/index.d.ts +1 -0
- package/dist/debounce.d.ts +2 -0
- package/dist/deep/copy.d.ts +1 -0
- package/dist/deep/delete.d.ts +2 -0
- package/dist/deep/delete.spec.d.ts +1 -0
- package/dist/deep/equal.d.ts +8 -0
- package/dist/deep/equal.spec.d.ts +1 -0
- package/dist/deep/external.d.ts +7 -0
- package/dist/deep/index.d.ts +1 -0
- package/dist/deep/key.d.ts +30 -0
- package/dist/deep/memo.d.ts +1 -0
- package/dist/deep/merge.d.ts +2 -0
- package/dist/deep/merge.spec.d.ts +1 -0
- package/dist/deep/partial.d.ts +3 -0
- package/dist/destructor.d.ts +1 -0
- package/dist/identity.d.ts +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/join.d.ts +1 -0
- package/dist/kv/index.d.ts +1 -0
- package/dist/kv/types.d.ts +32 -0
- package/dist/mock/MockGLBufferController.d.ts +20 -0
- package/dist/mock/index.d.ts +1 -0
- package/dist/observe/index.d.ts +1 -0
- package/dist/observe/observe.d.ts +11 -0
- package/dist/optional.d.ts +1 -0
- package/dist/primitive.d.ts +8 -0
- package/dist/record.d.ts +14 -0
- package/dist/renderable.d.ts +4 -0
- package/dist/runtime/detect.d.ts +9 -0
- package/dist/runtime/external.d.ts +2 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/os.d.ts +9 -0
- package/dist/search.d.ts +15 -0
- package/dist/spatial/base.d.ts +102 -0
- package/dist/spatial/bounds.d.ts +31 -0
- package/dist/spatial/bounds.spec.d.ts +1 -0
- package/dist/spatial/box.d.ts +265 -0
- package/dist/spatial/box.spec.d.ts +1 -0
- package/dist/spatial/dimensions.d.ts +59 -0
- package/dist/spatial/dimensions.spec.d.ts +1 -0
- package/dist/spatial/direction.d.ts +10 -0
- package/dist/spatial/direction.spec.d.ts +1 -0
- package/dist/spatial/external.d.ts +8 -0
- package/dist/spatial/index.d.ts +1 -0
- package/dist/spatial/location.d.ts +52 -0
- package/dist/spatial/location.spec.d.ts +1 -0
- package/dist/spatial/position.d.ts +2 -0
- package/dist/spatial/scale.d.ts +241 -0
- package/dist/spatial/scale.spec.d.ts +1 -0
- package/dist/spatial/spatial.d.ts +1 -0
- package/dist/spatial/xy.d.ts +116 -0
- package/dist/spatial/xy.spec.d.ts +1 -0
- package/dist/telem/encode.d.ts +1 -0
- package/dist/telem/generate.d.ts +2 -0
- package/dist/telem/gl.d.ts +11 -0
- package/dist/telem/index.d.ts +3 -0
- package/dist/telem/series.d.ts +104 -0
- package/dist/telem/series.spec.d.ts +1 -0
- package/dist/telem/telem.d.ts +633 -0
- package/dist/telem/telem.spec.d.ts +1 -0
- package/dist/toArray.d.ts +1 -0
- package/dist/transform.d.ts +1 -0
- package/dist/unique.d.ts +1 -0
- package/dist/url/index.d.ts +1 -0
- package/dist/url/url.d.ts +46 -0
- package/dist/url/url.spec.d.ts +1 -0
- package/dist/worker/worker.d.ts +32 -0
- package/dist/worker/worker.spec.d.ts +1 -0
- package/dist/x.cjs.js +9046 -0
- package/dist/x.cjs.js.map +1 -0
- package/dist/x.es.js +9047 -0
- package/dist/x.es.js.map +1 -0
- package/package.json +42 -0
- package/src/binary/encoder.spec.ts +31 -0
- package/src/binary/encoder.ts +118 -0
- package/src/binary/index.ts +10 -0
- package/src/case.ts +31 -0
- package/src/change/change.ts +31 -0
- package/src/change/index.ts +10 -0
- package/src/clamp.ts +14 -0
- package/src/compare/compare.ts +116 -0
- package/src/compare/index.ts +10 -0
- package/src/debounce.ts +45 -0
- package/src/deep/copy.ts +13 -0
- package/src/deep/delete.spec.ts +36 -0
- package/src/deep/delete.ts +27 -0
- package/src/deep/equal.spec.ts +82 -0
- package/src/deep/equal.ts +65 -0
- package/src/deep/external.ts +15 -0
- package/src/deep/index.ts +10 -0
- package/src/deep/key.ts +46 -0
- package/src/deep/merge.spec.ts +63 -0
- package/src/deep/merge.ts +41 -0
- package/src/deep/partial.ts +14 -0
- package/src/destructor.ts +10 -0
- package/src/identity.ts +14 -0
- package/src/index.ts +34 -0
- package/src/join.ts +14 -0
- package/src/kv/index.ts +10 -0
- package/src/kv/types.ts +52 -0
- package/src/mock/MockGLBufferController.ts +70 -0
- package/src/mock/index.ts +10 -0
- package/src/observe/index.ts +10 -0
- package/src/observe/observe.ts +33 -0
- package/src/optional.ts +10 -0
- package/src/primitive.ts +46 -0
- package/src/record.ts +45 -0
- package/src/renderable.ts +20 -0
- package/src/runtime/detect.ts +34 -0
- package/src/runtime/external.ts +11 -0
- package/src/runtime/index.ts +10 -0
- package/src/runtime/os.ts +38 -0
- package/src/search.ts +40 -0
- package/src/spatial/base.ts +80 -0
- package/src/spatial/bounds.spec.ts +99 -0
- package/src/spatial/bounds.ts +80 -0
- package/src/spatial/box.spec.ts +137 -0
- package/src/spatial/box.ts +326 -0
- package/src/spatial/dimensions.spec.ts +47 -0
- package/src/spatial/dimensions.ts +64 -0
- package/src/spatial/direction.spec.ts +25 -0
- package/src/spatial/direction.ts +47 -0
- package/src/spatial/external.ts +17 -0
- package/src/spatial/index.ts +10 -0
- package/src/spatial/location.spec.ts +24 -0
- package/src/spatial/location.ts +124 -0
- package/src/spatial/position.ts +26 -0
- package/src/spatial/scale.spec.ts +74 -0
- package/src/spatial/scale.ts +351 -0
- package/src/spatial/spatial.ts +17 -0
- package/src/spatial/xy.spec.ts +68 -0
- package/src/spatial/xy.ts +164 -0
- package/src/telem/encode.ts +22 -0
- package/src/telem/generate.ts +19 -0
- package/src/telem/gl.ts +22 -0
- package/src/telem/index.ts +12 -0
- package/src/telem/series.spec.ts +289 -0
- package/src/telem/series.ts +449 -0
- package/src/telem/telem.spec.ts +302 -0
- package/src/telem/telem.ts +1237 -0
- package/src/toArray.ts +11 -0
- package/src/transform.ts +10 -0
- package/src/unique.ts +10 -0
- package/src/url/index.ts +10 -0
- package/src/url/url.spec.ts +47 -0
- package/src/url/url.ts +113 -0
- package/src/worker/worker.spec.ts +41 -0
- package/src/worker/worker.ts +86 -0
- package/tsconfig.json +7 -0
- package/tsconfig.vite.json +4 -0
- package/vite.config.ts +23 -0
|
@@ -0,0 +1,1237 @@
|
|
|
1
|
+
// Copyright 2023 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
import { type Stringer } from "@/primitive";
|
|
13
|
+
import { addSamples } from "@/telem/series";
|
|
14
|
+
|
|
15
|
+
export type TZInfo = "UTC" | "local";
|
|
16
|
+
|
|
17
|
+
export type TimeStampStringFormat =
|
|
18
|
+
| "ISO"
|
|
19
|
+
| "ISODate"
|
|
20
|
+
| "ISOTime"
|
|
21
|
+
| "time"
|
|
22
|
+
| "preciseTime"
|
|
23
|
+
| "date"
|
|
24
|
+
| "preciseDate"
|
|
25
|
+
| "shortDate"
|
|
26
|
+
| "dateTime";
|
|
27
|
+
|
|
28
|
+
export type DateComponents = [number?, number?, number?];
|
|
29
|
+
|
|
30
|
+
const remainder = <T extends TimeStamp | TimeSpan>(
|
|
31
|
+
value: T,
|
|
32
|
+
divisor: TimeSpan | TimeStamp,
|
|
33
|
+
): T => {
|
|
34
|
+
const ts = new TimeStamp(divisor);
|
|
35
|
+
if (
|
|
36
|
+
![
|
|
37
|
+
TimeSpan.DAY,
|
|
38
|
+
TimeSpan.HOUR,
|
|
39
|
+
TimeSpan.MINUTE,
|
|
40
|
+
TimeSpan.SECOND,
|
|
41
|
+
TimeSpan.MILLISECOND,
|
|
42
|
+
TimeSpan.MICROSECOND,
|
|
43
|
+
TimeSpan.NANOSECOND,
|
|
44
|
+
].some((s) => s.equals(ts))
|
|
45
|
+
) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"Invalid argument for remainder. Must be an even TimeSpan or Timestamp",
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const v = value.valueOf() % ts.valueOf();
|
|
51
|
+
return (value instanceof TimeStamp ? new TimeStamp(v) : new TimeSpan(v)) as T;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Represents a UTC timestamp. Synnax uses a nanosecond precision int64 timestamp.
|
|
56
|
+
*
|
|
57
|
+
* DISCLAIMER: JavaScript stores all numbers as 64-bit floating point numbers, so we expect a
|
|
58
|
+
* expect a precision drop from nanoseconds to quarter microseconds when communicating
|
|
59
|
+
* with the server. If this is a problem, please file an issue with the Synnax team.
|
|
60
|
+
* Caveat emptor.
|
|
61
|
+
*
|
|
62
|
+
* @param value - The timestamp value to parse. This can be any of the following:
|
|
63
|
+
*
|
|
64
|
+
* 1. A number representing the number of milliseconds since the Unix epoch.
|
|
65
|
+
* 2. A javascript Date object.
|
|
66
|
+
* 3. An array of numbers satisfying the DateComponents type, where the first element is the
|
|
67
|
+
* year, the second is the month, and the third is the day. To increaase resolution
|
|
68
|
+
* when using this method, use the add method. It's important to note that this initializes
|
|
69
|
+
* a timestamp at midnight UTC, regardless of the timezone specified.
|
|
70
|
+
* 4. An ISO compliant date or date time string. The time zone component is ignored.
|
|
71
|
+
*
|
|
72
|
+
* @param tzInfo - The timezone to use when parsing the timestamp. This can be either "UTC" or
|
|
73
|
+
* "local". This parameter is ignored if the value is a Date object or a DateComponents array.
|
|
74
|
+
*
|
|
75
|
+
* @example ts = new TimeStamp(1 * TimeSpan.HOUR) // 1 hour after the Unix epoch
|
|
76
|
+
* @example ts = new TimeStamp([2021, 1, 1]) // 1/1/2021 at midnight UTC
|
|
77
|
+
* @example ts = new TimeStamp([2021, 1, 1]).add(1 * TimeSpan.HOUR) // 1/1/2021 at 1am UTC
|
|
78
|
+
* @example ts = new TimeStamp("2021-01-01T12:30:00Z") // 1/1/2021 at 12:30pm UTC
|
|
79
|
+
*/
|
|
80
|
+
export class TimeStamp extends Number implements Stringer {
|
|
81
|
+
constructor(value?: CrudeTimeStamp, tzInfo: TZInfo = "UTC") {
|
|
82
|
+
if (value == null) return TimeStamp.now();
|
|
83
|
+
else if (value instanceof Date)
|
|
84
|
+
super(value.getTime() * TimeStamp.MILLISECOND.valueOf());
|
|
85
|
+
else if (typeof value === "string")
|
|
86
|
+
super(TimeStamp.parseDateTimeString(value, tzInfo).valueOf());
|
|
87
|
+
else if (Array.isArray(value)) super(TimeStamp.parseDate(value));
|
|
88
|
+
else {
|
|
89
|
+
let offset = 0;
|
|
90
|
+
if (value instanceof Number) value = value.valueOf();
|
|
91
|
+
if (tzInfo === "local") offset = TimeStamp.utcOffset.valueOf();
|
|
92
|
+
super(value.valueOf() + offset);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private static parseDate([year = 1970, month = 1, day = 1]: DateComponents): number {
|
|
97
|
+
const date = new Date(year, month - 1, day, 0, 0, 0, 0);
|
|
98
|
+
// We truncate here to only get the date component regardless of the time zone.
|
|
99
|
+
return new TimeStamp(date.getTime() * TimeStamp.MILLISECOND.valueOf())
|
|
100
|
+
.truncate(TimeStamp.DAY)
|
|
101
|
+
.valueOf();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private static parseTimeString(time: string, tzInfo: TZInfo = "UTC"): number {
|
|
105
|
+
const [hours, minutes, mbeSeconds] = time.split(":");
|
|
106
|
+
let seconds = "00";
|
|
107
|
+
let milliseconds: string | undefined = "00";
|
|
108
|
+
if (mbeSeconds != null) [seconds, milliseconds] = mbeSeconds.split(".");
|
|
109
|
+
let base = TimeStamp.hours(parseInt(hours ?? "00", 10))
|
|
110
|
+
.add(TimeStamp.minutes(parseInt(minutes ?? "00", 10)))
|
|
111
|
+
.add(TimeStamp.seconds(parseInt(seconds ?? "00", 10)))
|
|
112
|
+
.add(TimeStamp.milliseconds(parseInt(milliseconds ?? "00", 10)));
|
|
113
|
+
if (tzInfo === "local") base = base.add(TimeStamp.utcOffset);
|
|
114
|
+
return base.valueOf();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private static parseDateTimeString(str: string, tzInfo: TZInfo = "UTC"): number {
|
|
118
|
+
if (!str.includes("/") && !str.includes("-"))
|
|
119
|
+
return TimeStamp.parseTimeString(str, tzInfo);
|
|
120
|
+
const d = new Date(str);
|
|
121
|
+
// Essentialy to note that this makes the date midnight in UTC! Not local!
|
|
122
|
+
// As a result, we need to add the tzInfo offset back in.
|
|
123
|
+
if (!str.includes(":")) d.setUTCHours(0, 0, 0, 0);
|
|
124
|
+
return new TimeStamp(
|
|
125
|
+
d.getTime() * TimeStamp.MILLISECOND.valueOf(),
|
|
126
|
+
tzInfo,
|
|
127
|
+
).valueOf();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fString(format: TimeStampStringFormat = "ISO", tzInfo: TZInfo = "UTC"): string {
|
|
131
|
+
switch (format) {
|
|
132
|
+
case "ISODate":
|
|
133
|
+
return this.toISOString(tzInfo).slice(0, 10);
|
|
134
|
+
case "ISOTime":
|
|
135
|
+
return this.toISOString(tzInfo).slice(11, 23);
|
|
136
|
+
case "time":
|
|
137
|
+
return this.timeString(false, tzInfo);
|
|
138
|
+
case "preciseTime":
|
|
139
|
+
return this.timeString(true, tzInfo);
|
|
140
|
+
case "date":
|
|
141
|
+
return this.dateString(tzInfo);
|
|
142
|
+
case "preciseDate":
|
|
143
|
+
return `${this.dateString(tzInfo)} ${this.timeString(true, tzInfo)}`;
|
|
144
|
+
case "dateTime":
|
|
145
|
+
return `${this.dateString(tzInfo)} ${this.timeString(false, tzInfo)}`;
|
|
146
|
+
default:
|
|
147
|
+
return this.toISOString(tzInfo);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private toISOString(tzInfo: TZInfo = "UTC"): string {
|
|
152
|
+
if (tzInfo === "UTC") return this.date().toISOString();
|
|
153
|
+
return this.sub(TimeStamp.utcOffset).date().toISOString();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private timeString(milliseconds: boolean = false, tzInfo: TZInfo = "UTC"): string {
|
|
157
|
+
const iso = this.toISOString(tzInfo);
|
|
158
|
+
return milliseconds ? iso.slice(11, 23) : iso.slice(11, 19);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private dateString(tzInfo: TZInfo = "UTC"): string {
|
|
162
|
+
const date = this.date();
|
|
163
|
+
const month = date.toLocaleString("default", { month: "short" });
|
|
164
|
+
const day = date.toLocaleString("default", { day: "numeric" });
|
|
165
|
+
return `${month} ${day}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static get utcOffset(): TimeSpan {
|
|
169
|
+
return new TimeSpan(new Date().getTimezoneOffset() * TimeStamp.MINUTE.valueOf());
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @returns a TimeSpan representing the amount time elapsed since
|
|
174
|
+
* the other timestamp.
|
|
175
|
+
* @param other - The other timestamp.
|
|
176
|
+
*/
|
|
177
|
+
static since(other: TimeStamp): TimeSpan {
|
|
178
|
+
return new TimeStamp().span(other);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** @returns A JavaScript Date object representing the TimeStamp. */
|
|
182
|
+
date(): Date {
|
|
183
|
+
return new Date(this.milliseconds());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Checks if the TimeStamp is equal to another TimeStamp.
|
|
188
|
+
*
|
|
189
|
+
* @param other - The other TimeStamp to compare to.
|
|
190
|
+
* @returns True if the TimeStamps are equal, false otherwise.
|
|
191
|
+
*/
|
|
192
|
+
equals(other: CrudeTimeStamp): boolean {
|
|
193
|
+
return this.valueOf() === new TimeStamp(other).valueOf();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Creates a TimeSpan representing the duration between the two timestamps.
|
|
198
|
+
*
|
|
199
|
+
* @param other - The other TimeStamp to compare to.
|
|
200
|
+
* @returns A TimeSpan representing the duration between the two timestamps.
|
|
201
|
+
* The span is guaranteed to be positive.
|
|
202
|
+
*/
|
|
203
|
+
span(other: CrudeTimeStamp): TimeSpan {
|
|
204
|
+
return this.range(other).span;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Creates a TimeRange spanning the given TimeStamp.
|
|
209
|
+
*
|
|
210
|
+
* @param other - The other TimeStamp to compare to.
|
|
211
|
+
* @returns A TimeRange spanning the given TimeStamp that is guaranteed to be
|
|
212
|
+
* valid, regardless of the TimeStamp order.
|
|
213
|
+
*/
|
|
214
|
+
range(other: CrudeTimeStamp): TimeRange {
|
|
215
|
+
return new TimeRange(this, other).makeValid();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Creates a TimeRange starting at the TimeStamp and spanning the given
|
|
220
|
+
* TimeSpan.
|
|
221
|
+
*
|
|
222
|
+
* @param other - The TimeSpan to span.
|
|
223
|
+
* @returns A TimeRange starting at the TimeStamp and spanning the given
|
|
224
|
+
* TimeSpan. The TimeRange is guaranteed to be valid.
|
|
225
|
+
*/
|
|
226
|
+
spanRange(other: CrudeTimeSpan): TimeRange {
|
|
227
|
+
return this.range(this.add(other)).makeValid();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Checks if the TimeStamp represents the unix epoch.
|
|
232
|
+
*
|
|
233
|
+
* @returns True if the TimeStamp represents the unix epoch, false otherwise.
|
|
234
|
+
*/
|
|
235
|
+
get isZero(): boolean {
|
|
236
|
+
return this.valueOf() === 0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Checks if the TimeStamp is after the given TimeStamp.
|
|
241
|
+
*
|
|
242
|
+
* @param other - The other TimeStamp to compare to.
|
|
243
|
+
* @returns True if the TimeStamp is after the given TimeStamp, false
|
|
244
|
+
* otherwise.
|
|
245
|
+
*/
|
|
246
|
+
after(other: CrudeTimeStamp): boolean {
|
|
247
|
+
return this.valueOf() > new TimeStamp(other).valueOf();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Checks if the TimeStamp is after or equal to the given TimeStamp.
|
|
252
|
+
*
|
|
253
|
+
* @param other - The other TimeStamp to compare to.
|
|
254
|
+
* @returns True if the TimeStamp is after or equal to the given TimeStamp,
|
|
255
|
+
* false otherwise.
|
|
256
|
+
*/
|
|
257
|
+
afterEq(other: CrudeTimeStamp): boolean {
|
|
258
|
+
return this.valueOf() >= new TimeStamp(other).valueOf();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Checks if the TimeStamp is before the given TimeStamp.
|
|
263
|
+
*
|
|
264
|
+
* @param other - The other TimeStamp to compare to.
|
|
265
|
+
* @returns True if the TimeStamp is before the given TimeStamp, false
|
|
266
|
+
* otherwise.
|
|
267
|
+
*/
|
|
268
|
+
before(other: CrudeTimeStamp): boolean {
|
|
269
|
+
return this.valueOf() < new TimeStamp(other).valueOf();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Checks if TimeStamp is before or equal to the current timestamp.
|
|
274
|
+
*
|
|
275
|
+
* @param other - The other TimeStamp to compare to.
|
|
276
|
+
* @returns True if TimeStamp is before or equal to the current timestamp,
|
|
277
|
+
* false otherwise.
|
|
278
|
+
*/
|
|
279
|
+
beforeEq(other: CrudeTimeStamp): boolean {
|
|
280
|
+
return this.valueOf() <= new TimeStamp(other).valueOf();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Adds a TimeSpan to the TimeStamp.
|
|
285
|
+
*
|
|
286
|
+
* @param span - The TimeSpan to add.
|
|
287
|
+
* @returns A new TimeStamp representing the sum of the TimeStamp and
|
|
288
|
+
* TimeSpan.
|
|
289
|
+
*/
|
|
290
|
+
add(span: CrudeTimeSpan): TimeStamp {
|
|
291
|
+
return new TimeStamp(this.valueOf() + span.valueOf());
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Subtracts a TimeSpan from the TimeStamp.
|
|
296
|
+
*
|
|
297
|
+
* @param span - The TimeSpan to subtract.
|
|
298
|
+
* @returns A new TimeStamp representing the difference of the TimeStamp and
|
|
299
|
+
* TimeSpan.
|
|
300
|
+
*/
|
|
301
|
+
sub(span: CrudeTimeSpan): TimeStamp {
|
|
302
|
+
return new TimeStamp(this.valueOf() - span.valueOf());
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @returns The number of milliseconds since the unix epoch.
|
|
307
|
+
*/
|
|
308
|
+
milliseconds(): number {
|
|
309
|
+
return this.valueOf() / TimeStamp.MILLISECOND.valueOf();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
toString(): string {
|
|
313
|
+
return this.date().toISOString();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @returns A new TimeStamp that is the remainder of the TimeStamp divided by the
|
|
318
|
+
* given span. This is useful in cases where you want only part of a TimeStamp's value
|
|
319
|
+
* i.e. the hours, minutes, seconds, milliseconds, microseconds, and nanoseconds but
|
|
320
|
+
* not the days, years, etc.
|
|
321
|
+
*
|
|
322
|
+
* @param divisor - The TimeSpan to divide by. Must be an even TimeSpan or TimeStamp. Even
|
|
323
|
+
* means it must be a day, hour, minute, second, millisecond, or microsecond, etc.
|
|
324
|
+
*
|
|
325
|
+
* @example TimeStamp.now().remainder(TimeStamp.DAY) // => TimeStamp representing the current day
|
|
326
|
+
*/
|
|
327
|
+
remainder(divisor: TimeSpan | TimeStamp): TimeStamp {
|
|
328
|
+
return remainder(this, divisor);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
truncate(span: TimeSpan | TimeStamp): TimeStamp {
|
|
332
|
+
return this.sub(this.remainder(span));
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* @returns A new TimeStamp representing the current time in UTC. It's important to
|
|
337
|
+
* note that this TimeStamp is only accurate to the millisecond level (that's the best
|
|
338
|
+
* JavaScript can do).
|
|
339
|
+
*/
|
|
340
|
+
static now(): TimeStamp {
|
|
341
|
+
return new TimeStamp(new Date());
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** @returns a new TimeStamp n nanoseconds after the unix epoch */
|
|
345
|
+
static nanoseconds(value: number): TimeStamp {
|
|
346
|
+
return new TimeStamp(value);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* One nanosecond after the unix epoch */
|
|
350
|
+
static readonly NANOSECOND = TimeStamp.nanoseconds(1);
|
|
351
|
+
|
|
352
|
+
/** @returns a new TimeStamp n microseconds after the unix epoch */
|
|
353
|
+
static microseconds(value: number): TimeStamp {
|
|
354
|
+
return TimeStamp.nanoseconds(value * 1000);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** One microsecond after the unix epoch */
|
|
358
|
+
static readonly MICROSECOND = TimeStamp.microseconds(1);
|
|
359
|
+
|
|
360
|
+
/** @returns a new TimeStamp n milliseconds after the unix epoch */
|
|
361
|
+
static milliseconds(value: number): TimeStamp {
|
|
362
|
+
return TimeStamp.microseconds(value * 1000);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** One millisecond after the unix epoch */
|
|
366
|
+
static readonly MILLISECOND = TimeStamp.milliseconds(1);
|
|
367
|
+
|
|
368
|
+
/** @returns a new TimeStamp n seconds after the unix epoch */
|
|
369
|
+
static seconds(value: number): TimeStamp {
|
|
370
|
+
return TimeStamp.milliseconds(value * 1000);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/** One second after the unix epoch */
|
|
374
|
+
static readonly SECOND = TimeStamp.seconds(1);
|
|
375
|
+
|
|
376
|
+
/** @returns a new TimeStamp n minutes after the unix epoch */
|
|
377
|
+
static minutes(value: number): TimeStamp {
|
|
378
|
+
return TimeStamp.seconds(value * 60);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** One minute after the unix epoch */
|
|
382
|
+
static readonly MINUTE = TimeStamp.minutes(1);
|
|
383
|
+
|
|
384
|
+
/** @returns a new TimeStamp n hours after the unix epoch */
|
|
385
|
+
static hours(value: number): TimeStamp {
|
|
386
|
+
return TimeStamp.minutes(value * 60);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/** One hour after the unix epoch */
|
|
390
|
+
static readonly HOUR = TimeStamp.hours(1);
|
|
391
|
+
|
|
392
|
+
/** @returns a new TimeStamp n days after the unix epoch */
|
|
393
|
+
static days(value: number): TimeStamp {
|
|
394
|
+
return TimeStamp.hours(value * 24);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/** One day after the unix epoch */
|
|
398
|
+
static readonly DAY = TimeStamp.days(1);
|
|
399
|
+
|
|
400
|
+
/** The maximum possible value for a timestamp */
|
|
401
|
+
static readonly MAX = new TimeStamp(9122272036554776000);
|
|
402
|
+
|
|
403
|
+
/** The minimum possible value for a timestamp */
|
|
404
|
+
static readonly MIN = new TimeStamp(0);
|
|
405
|
+
|
|
406
|
+
/** The unix epoch */
|
|
407
|
+
static readonly ZERO = new TimeStamp(0);
|
|
408
|
+
|
|
409
|
+
/** A zod schema for validating timestamps */
|
|
410
|
+
static readonly z = z.union([
|
|
411
|
+
z.instanceof(Number).transform((n) => new TimeStamp(n)),
|
|
412
|
+
z.number().transform((n) => new TimeStamp(n)),
|
|
413
|
+
z.instanceof(TimeStamp),
|
|
414
|
+
]);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/** TimeSpan represents a nanosecond precision duration. */
|
|
418
|
+
export class TimeSpan extends Number implements Stringer {
|
|
419
|
+
constructor(value: CrudeTimeSpan) {
|
|
420
|
+
if (value instanceof Number) super(value.valueOf());
|
|
421
|
+
else super(value);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
remainder(divisor: TimeSpan): TimeSpan {
|
|
425
|
+
return remainder(this, divisor);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
truncate(span: TimeSpan): TimeSpan {
|
|
429
|
+
return new TimeSpan(Math.trunc(this.valueOf() / span.valueOf()) * span.valueOf());
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
toString(): string {
|
|
433
|
+
const totalDays = this.truncate(TimeSpan.DAY);
|
|
434
|
+
const totalHours = this.truncate(TimeSpan.HOUR);
|
|
435
|
+
const totalMinutes = this.truncate(TimeSpan.MINUTE);
|
|
436
|
+
const totalSeconds = this.truncate(TimeSpan.SECOND);
|
|
437
|
+
const totalMilliseconds = this.truncate(TimeSpan.MILLISECOND);
|
|
438
|
+
const totalMicroseconds = this.truncate(TimeSpan.MICROSECOND);
|
|
439
|
+
const totalNanoseconds = this.truncate(TimeSpan.NANOSECOND);
|
|
440
|
+
const days = totalDays;
|
|
441
|
+
const hours = totalHours.sub(totalDays);
|
|
442
|
+
const minutes = totalMinutes.sub(totalHours);
|
|
443
|
+
const seconds = totalSeconds.sub(totalMinutes);
|
|
444
|
+
const milliseconds = totalMilliseconds.sub(totalSeconds);
|
|
445
|
+
const microseconds = totalMicroseconds.sub(totalMilliseconds);
|
|
446
|
+
const nanoseconds = totalNanoseconds.sub(totalMicroseconds);
|
|
447
|
+
|
|
448
|
+
let str = "";
|
|
449
|
+
if (!days.isZero) str += `${days.days}d `;
|
|
450
|
+
if (!hours.isZero) str += `${hours.hours}h `;
|
|
451
|
+
if (!minutes.isZero) str += `${minutes.minutes}m `;
|
|
452
|
+
if (!seconds.isZero) str += `${seconds.seconds}s `;
|
|
453
|
+
if (!milliseconds.isZero) str += `${milliseconds.milliseconds}ms `;
|
|
454
|
+
if (!microseconds.isZero) str += `${microseconds.microseconds}µs `;
|
|
455
|
+
if (!nanoseconds.isZero) str += `${nanoseconds.nanoseconds}ns`;
|
|
456
|
+
return str.trim();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** @returns the decimal number of days in the timespan */
|
|
460
|
+
get days(): number {
|
|
461
|
+
return this.valueOf() / TimeSpan.DAY.valueOf();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** @returns the decimal number of hours in the timespan */
|
|
465
|
+
get hours(): number {
|
|
466
|
+
return this.valueOf() / TimeSpan.HOUR.valueOf();
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** @returns the decimal number of minutes in the timespan */
|
|
470
|
+
get minutes(): number {
|
|
471
|
+
return this.valueOf() / TimeSpan.MINUTE.valueOf();
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/** @returns The number of seconds in the TimeSpan. */
|
|
475
|
+
get seconds(): number {
|
|
476
|
+
return this.valueOf() / TimeSpan.SECOND.valueOf();
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/** @returns The number of milliseconds in the TimeSpan. */
|
|
480
|
+
get milliseconds(): number {
|
|
481
|
+
return this.valueOf() / TimeSpan.MILLISECOND.valueOf();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
get microseconds(): number {
|
|
485
|
+
return this.valueOf() / TimeSpan.MICROSECOND.valueOf();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
get nanoseconds(): number {
|
|
489
|
+
return this.valueOf();
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Checks if the TimeSpan represents a zero duration.
|
|
494
|
+
*
|
|
495
|
+
* @returns True if the TimeSpan represents a zero duration, false otherwise.
|
|
496
|
+
*/
|
|
497
|
+
get isZero(): boolean {
|
|
498
|
+
return this.valueOf() === 0;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Checks if the TimeSpan is equal to another TimeSpan.
|
|
503
|
+
*
|
|
504
|
+
* @returns True if the TimeSpans are equal, false otherwise.
|
|
505
|
+
*/
|
|
506
|
+
equals(other: CrudeTimeSpan): boolean {
|
|
507
|
+
return this.valueOf() === new TimeSpan(other).valueOf();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Adds a TimeSpan to the TimeSpan.
|
|
512
|
+
*
|
|
513
|
+
* @returns A new TimeSpan representing the sum of the two TimeSpans.
|
|
514
|
+
*/
|
|
515
|
+
add(other: CrudeTimeSpan): TimeSpan {
|
|
516
|
+
return new TimeSpan(this.valueOf() + new TimeSpan(other).valueOf());
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Creates a TimeSpan representing the duration between the two timestamps.
|
|
521
|
+
*
|
|
522
|
+
* @param other
|
|
523
|
+
*/
|
|
524
|
+
sub(other: CrudeTimeSpan): TimeSpan {
|
|
525
|
+
return new TimeSpan(this.valueOf() - new TimeSpan(other).valueOf());
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Creates a TimeSpan representing the given number of nanoseconds.
|
|
530
|
+
*
|
|
531
|
+
* @param value - The number of nanoseconds.
|
|
532
|
+
* @returns A TimeSpan representing the given number of nanoseconds.
|
|
533
|
+
*/
|
|
534
|
+
static nanoseconds(value: number = 1): TimeSpan {
|
|
535
|
+
return new TimeSpan(value);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/** A nanosecond. */
|
|
539
|
+
static readonly NANOSECOND = TimeSpan.nanoseconds(1);
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Creates a TimeSpan representing the given number of microseconds.
|
|
543
|
+
*
|
|
544
|
+
* @param value - The number of microseconds.
|
|
545
|
+
* @returns A TimeSpan representing the given number of microseconds.
|
|
546
|
+
*/
|
|
547
|
+
static microseconds(value: number = 1): TimeSpan {
|
|
548
|
+
return TimeSpan.nanoseconds(value * 1000);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/** A microsecond. */
|
|
552
|
+
static readonly MICROSECOND = TimeSpan.microseconds(1);
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Creates a TimeSpan representing the given number of milliseconds.
|
|
556
|
+
*
|
|
557
|
+
* @param value - The number of milliseconds.
|
|
558
|
+
* @returns A TimeSpan representing the given number of milliseconds.
|
|
559
|
+
*/
|
|
560
|
+
static milliseconds(value: number = 1): TimeSpan {
|
|
561
|
+
return TimeSpan.microseconds(value * 1000);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/** A millisecond. */
|
|
565
|
+
static readonly MILLISECOND = TimeSpan.milliseconds(1);
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Creates a TimeSpan representing the given number of seconds.
|
|
569
|
+
*
|
|
570
|
+
* @param value - The number of seconds.
|
|
571
|
+
* @returns A TimeSpan representing the given number of seconds.
|
|
572
|
+
*/
|
|
573
|
+
static seconds(value: number = 1): TimeSpan {
|
|
574
|
+
return TimeSpan.milliseconds(value * 1000);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** A second. */
|
|
578
|
+
static readonly SECOND = TimeSpan.seconds(1);
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Creates a TimeSpan representing the given number of minutes.
|
|
582
|
+
*
|
|
583
|
+
* @param value - The number of minutes.
|
|
584
|
+
* @returns A TimeSpan representing the given number of minutes.
|
|
585
|
+
*/
|
|
586
|
+
static minutes(value: number): TimeSpan {
|
|
587
|
+
return TimeSpan.seconds(value.valueOf() * 60);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/** A minute. */
|
|
591
|
+
static readonly MINUTE = TimeSpan.minutes(1);
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Creates a TimeSpan representing the given number of hours.
|
|
595
|
+
*
|
|
596
|
+
* @param value - The number of hours.
|
|
597
|
+
* @returns A TimeSpan representing the given number of hours.
|
|
598
|
+
*/
|
|
599
|
+
static hours(value: number): TimeSpan {
|
|
600
|
+
return TimeSpan.minutes(value * 60);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** Represents an hour. */
|
|
604
|
+
static readonly HOUR = TimeSpan.hours(1);
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Creates a TimeSpan representing the given number of days.
|
|
608
|
+
*
|
|
609
|
+
* @param value - The number of days.
|
|
610
|
+
* @returns A TimeSpan representing the given number of days.
|
|
611
|
+
*/
|
|
612
|
+
static days(value: number): TimeSpan {
|
|
613
|
+
return TimeSpan.hours(value * 24);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/** Represents a day. */
|
|
617
|
+
static readonly DAY = TimeSpan.days(1);
|
|
618
|
+
|
|
619
|
+
/** The maximum possible value for a TimeSpan. */
|
|
620
|
+
static readonly MAX = new TimeSpan(this.MAX_SAFE_INTEGER);
|
|
621
|
+
|
|
622
|
+
/** The minimum possible value for a TimeSpan. */
|
|
623
|
+
static readonly MIN = new TimeSpan(-this.MAX_SAFE_INTEGER);
|
|
624
|
+
|
|
625
|
+
/** The zero value for a TimeSpan. */
|
|
626
|
+
static readonly ZERO = new TimeSpan(0);
|
|
627
|
+
|
|
628
|
+
/** A zod schema for validating and transforming timespans */
|
|
629
|
+
static readonly z = z.union([
|
|
630
|
+
z.instanceof(Number).transform((n) => new TimeSpan(n)),
|
|
631
|
+
z.number().transform((n) => new TimeSpan(n)),
|
|
632
|
+
z.instanceof(TimeSpan),
|
|
633
|
+
]);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/** Rate represents a data rate in Hz. */
|
|
637
|
+
export class Rate extends Number implements Stringer {
|
|
638
|
+
constructor(value: CrudeRate) {
|
|
639
|
+
if (value instanceof Number) super(value.valueOf());
|
|
640
|
+
else super(value);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** @returns a pretty string representation of the rate in the format "X Hz". */
|
|
644
|
+
toString(): string {
|
|
645
|
+
return `${this.valueOf()} Hz`;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/** @returns The number of seconds in the Rate. */
|
|
649
|
+
equals(other: CrudeRate): boolean {
|
|
650
|
+
return this.valueOf() === new Rate(other).valueOf();
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Calculates the period of the Rate as a TimeSpan.
|
|
655
|
+
*
|
|
656
|
+
* @returns A TimeSpan representing the period of the Rate.
|
|
657
|
+
*/
|
|
658
|
+
get period(): TimeSpan {
|
|
659
|
+
return TimeSpan.seconds(1 / this.valueOf());
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Calculates the number of samples in the given TimeSpan at this rate.
|
|
664
|
+
*
|
|
665
|
+
* @param duration - The duration to calculate the sample count from.
|
|
666
|
+
* @returns The number of samples in the given TimeSpan at this rate.
|
|
667
|
+
*/
|
|
668
|
+
sampleCount(duration: CrudeTimeSpan): number {
|
|
669
|
+
return new TimeSpan(duration).seconds * this.valueOf();
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Calculates the number of bytes in the given TimeSpan at this rate.
|
|
674
|
+
*
|
|
675
|
+
* @param span - The duration to calculate the byte count from.
|
|
676
|
+
* @param density - The density of the data in bytes per sample.
|
|
677
|
+
* @returns The number of bytes in the given TimeSpan at this rate.
|
|
678
|
+
*/
|
|
679
|
+
byteCount(span: CrudeTimeSpan, density: CrudeDensity): number {
|
|
680
|
+
return this.sampleCount(span) * new Density(density).valueOf();
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Calculates a TimeSpan given the number of samples at this rate.
|
|
685
|
+
*
|
|
686
|
+
* @param sampleCount - The number of samples in the span.
|
|
687
|
+
* @returns A TimeSpan that corresponds to the given number of samples.
|
|
688
|
+
*/
|
|
689
|
+
span(sampleCount: number): TimeSpan {
|
|
690
|
+
return TimeSpan.seconds(sampleCount / this.valueOf());
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Calculates a TimeSpan given the number of bytes at this rate.
|
|
695
|
+
*
|
|
696
|
+
* @param size - The number of bytes in the span.
|
|
697
|
+
* @param density - The density of the data in bytes per sample.
|
|
698
|
+
* @returns A TimeSpan that corresponds to the given number of bytes.
|
|
699
|
+
*/
|
|
700
|
+
byteSpan(size: Size, density: CrudeDensity): TimeSpan {
|
|
701
|
+
return this.span(size.valueOf() / density.valueOf());
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Creates a Rate representing the given number of Hz.
|
|
706
|
+
*
|
|
707
|
+
* @param value - The number of Hz.
|
|
708
|
+
* @returns A Rate representing the given number of Hz.
|
|
709
|
+
*/
|
|
710
|
+
static hz(value: number): Rate {
|
|
711
|
+
return new Rate(value);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Creates a Rate representing the given number of kHz.
|
|
716
|
+
*
|
|
717
|
+
* @param value - The number of kHz.
|
|
718
|
+
* @returns A Rate representing the given number of kHz.
|
|
719
|
+
*/
|
|
720
|
+
static khz(value: number): Rate {
|
|
721
|
+
return Rate.hz(value * 1000);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/** A zod schema for validating and transforming rates */
|
|
725
|
+
static readonly z = z.union([
|
|
726
|
+
z.number().transform((n) => new Rate(n)),
|
|
727
|
+
z.instanceof(Number).transform((n) => new Rate(n)),
|
|
728
|
+
z.instanceof(Rate),
|
|
729
|
+
]);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/** Density represents the number of bytes in a value. */
|
|
733
|
+
export class Density extends Number implements Stringer {
|
|
734
|
+
/**
|
|
735
|
+
* Creates a Density representing the given number of bytes per value.
|
|
736
|
+
*
|
|
737
|
+
* @class
|
|
738
|
+
* @param value - The number of bytes per value.
|
|
739
|
+
* @returns A Density representing the given number of bytes per value.
|
|
740
|
+
*/
|
|
741
|
+
constructor(value: CrudeDensity) {
|
|
742
|
+
if (value instanceof Number) super(value.valueOf());
|
|
743
|
+
else super(value);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
length(size: Size): number {
|
|
747
|
+
return size.valueOf() / this.valueOf();
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
size(sampleCount: number): Size {
|
|
751
|
+
return new Size(sampleCount * this.valueOf());
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/** Unknown/Invalid Density. */
|
|
755
|
+
static readonly UNKNOWN = new Density(0);
|
|
756
|
+
/** 128 bits per value. */
|
|
757
|
+
static readonly BIT128 = new Density(16);
|
|
758
|
+
/** 64 bits per value. */
|
|
759
|
+
static readonly BIT64 = new Density(8);
|
|
760
|
+
/** 32 bits per value. */
|
|
761
|
+
static readonly BIT32 = new Density(4);
|
|
762
|
+
/** 16 bits per value. */
|
|
763
|
+
static readonly BIT16 = new Density(2);
|
|
764
|
+
/** 8 bits per value. */
|
|
765
|
+
static readonly BIT8 = new Density(1);
|
|
766
|
+
|
|
767
|
+
/** A zod schema for validating and transforming densities */
|
|
768
|
+
static readonly z = z.union([
|
|
769
|
+
z.number().transform((n) => new Density(n)),
|
|
770
|
+
z.instanceof(Number).transform((n) => new Density(n)),
|
|
771
|
+
z.instanceof(Density),
|
|
772
|
+
]);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* TimeRange is a range of time marked by a start and end timestamp. A TimeRange
|
|
777
|
+
* is start inclusive and end exclusive.
|
|
778
|
+
*
|
|
779
|
+
* @property start - A TimeStamp representing the start of the range.
|
|
780
|
+
* @property end - A Timestamp representing the end of the range.
|
|
781
|
+
*/
|
|
782
|
+
export class TimeRange implements Stringer {
|
|
783
|
+
/**
|
|
784
|
+
* The starting TimeStamp of the TimeRange.
|
|
785
|
+
*
|
|
786
|
+
* Note that this value is not guaranteed to be before or equal to the ending value.
|
|
787
|
+
* To ensure that this is the case, call TimeRange.make_valid().
|
|
788
|
+
*
|
|
789
|
+
* In most cases, operations should treat start as inclusive.
|
|
790
|
+
*/
|
|
791
|
+
start: TimeStamp;
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* The starting TimeStamp of the TimeRange.
|
|
795
|
+
*
|
|
796
|
+
* Note that this value is not guaranteed to be before or equal to the ending value.
|
|
797
|
+
* To ensure that this is the case, call TimeRange.make_valid().
|
|
798
|
+
*
|
|
799
|
+
* In most cases, operations should treat end as exclusive.
|
|
800
|
+
*/
|
|
801
|
+
end: TimeStamp;
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* Creates a TimeRange from the given start and end TimeStamps.
|
|
805
|
+
*
|
|
806
|
+
* @param start - A TimeStamp representing the start of the range.
|
|
807
|
+
* @param end - A TimeStamp representing the end of the range.
|
|
808
|
+
*/
|
|
809
|
+
constructor(start: CrudeTimeStamp, end: CrudeTimeStamp) {
|
|
810
|
+
this.start = new TimeStamp(start);
|
|
811
|
+
this.end = new TimeStamp(end);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/** @returns The TimeSpan occupied by the TimeRange. */
|
|
815
|
+
get span(): TimeSpan {
|
|
816
|
+
return new TimeSpan(this.end.valueOf() - this.start.valueOf());
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Checks if the timestamp is valid i.e. the start is before the end.
|
|
821
|
+
*
|
|
822
|
+
* @returns True if the TimeRange is valid.
|
|
823
|
+
*/
|
|
824
|
+
get isValid(): boolean {
|
|
825
|
+
return this.start.valueOf() <= this.end.valueOf();
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Makes sure the TimeRange is valid i.e. the start is before the end.
|
|
830
|
+
*
|
|
831
|
+
* @returns A TimeRange that is valid.
|
|
832
|
+
*/
|
|
833
|
+
makeValid(): TimeRange {
|
|
834
|
+
return this.isValid ? this : this.swap();
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Checks if the TimeRange has a zero span.
|
|
839
|
+
*
|
|
840
|
+
* @returns True if the TimeRange has a zero span.
|
|
841
|
+
*/
|
|
842
|
+
get isZero(): boolean {
|
|
843
|
+
return this.span.isZero;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Creates a new TimeRange with the start and end swapped.
|
|
848
|
+
*
|
|
849
|
+
* @returns A TimeRange with the start and end swapped.
|
|
850
|
+
*/
|
|
851
|
+
swap(): TimeRange {
|
|
852
|
+
return new TimeRange(this.end, this.start);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Checks if the TimeRange is equal to the given TimeRange.
|
|
857
|
+
*
|
|
858
|
+
* @param other - The TimeRange to compare to.
|
|
859
|
+
* @returns True if the TimeRange is equal to the given TimeRange.
|
|
860
|
+
*/
|
|
861
|
+
equals(other: TimeRange): boolean {
|
|
862
|
+
return this.start.equals(other.start) && this.end.equals(other.end);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
toString(): string {
|
|
866
|
+
return `${this.start.toString()} - ${this.end.toString()}`;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
toPrettyString(): string {
|
|
870
|
+
return `${this.start.fString("preciseDate")} - ${this.span.toString()}`;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
overlapsWith(other: TimeRange): boolean {
|
|
874
|
+
other = other.makeValid();
|
|
875
|
+
const rng = this.makeValid();
|
|
876
|
+
if (other.start.equals(rng.start)) return true;
|
|
877
|
+
if (other.end.equals(this.start) || other.start.equals(this.end)) return false;
|
|
878
|
+
return (
|
|
879
|
+
this.contains(other.end) ||
|
|
880
|
+
this.contains(other.start) ||
|
|
881
|
+
other.contains(this.start) ||
|
|
882
|
+
other.contains(this.end)
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
contains(other: TimeRange): boolean;
|
|
887
|
+
|
|
888
|
+
contains(ts: CrudeTimeStamp): boolean;
|
|
889
|
+
|
|
890
|
+
contains(other: TimeRange | CrudeTimeStamp): boolean {
|
|
891
|
+
if (other instanceof TimeRange)
|
|
892
|
+
return this.contains(other.start) && this.contains(other.end);
|
|
893
|
+
return this.start.beforeEq(other) && this.end.after(other);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/** The maximum possible time range. */
|
|
897
|
+
static readonly MAX = new TimeRange(TimeStamp.MIN, TimeStamp.MAX);
|
|
898
|
+
|
|
899
|
+
/** The minimum possible time range. */
|
|
900
|
+
static readonly MIN = new TimeRange(TimeStamp.MAX, TimeStamp.MIN);
|
|
901
|
+
|
|
902
|
+
/** A zero time range. */
|
|
903
|
+
static readonly ZERO = new TimeRange(TimeStamp.ZERO, TimeStamp.ZERO);
|
|
904
|
+
|
|
905
|
+
/** A zod schema for validating and transforming time ranges */
|
|
906
|
+
static readonly z = z.union([
|
|
907
|
+
z
|
|
908
|
+
.object({ start: TimeStamp.z, end: TimeStamp.z })
|
|
909
|
+
.transform((v) => new TimeRange(v.start, v.end)),
|
|
910
|
+
z.instanceof(TimeRange),
|
|
911
|
+
]);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/** DataType is a string that represents a data type. */
|
|
915
|
+
export class DataType extends String implements Stringer {
|
|
916
|
+
constructor(value: CrudeDataType) {
|
|
917
|
+
if (
|
|
918
|
+
value instanceof DataType ||
|
|
919
|
+
typeof value === "string" ||
|
|
920
|
+
typeof value.valueOf() === "string"
|
|
921
|
+
) {
|
|
922
|
+
super(value.valueOf());
|
|
923
|
+
return;
|
|
924
|
+
} else {
|
|
925
|
+
const t = DataType.ARRAY_CONSTRUCTOR_DATA_TYPES.get(value.constructor.name);
|
|
926
|
+
if (t != null) {
|
|
927
|
+
super(t.valueOf());
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
super(DataType.UNKNOWN.valueOf());
|
|
932
|
+
throw new Error(`unable to find data type for ${value.toString()}`);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* @returns the TypedArray constructor for the DataType.
|
|
937
|
+
*/
|
|
938
|
+
get Array(): NativeTypedArrayConstructor {
|
|
939
|
+
const v = DataType.ARRAY_CONSTRUCTORS.get(this.toString());
|
|
940
|
+
if (v == null)
|
|
941
|
+
throw new Error(`unable to find array constructor for ${this.valueOf()}`);
|
|
942
|
+
return v;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
equals(other: DataType): boolean {
|
|
946
|
+
return this.valueOf() === other.valueOf();
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/** @returns a string representation of the DataType. */
|
|
950
|
+
toString(): string {
|
|
951
|
+
return this.valueOf();
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
get density(): Density {
|
|
955
|
+
const v = DataType.DENSITIES.get(this.toString());
|
|
956
|
+
if (v == null) throw new Error(`unable to find density for ${this.valueOf()}`);
|
|
957
|
+
return v;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Checks whether the given TypedArray is of the same type as the DataType.
|
|
962
|
+
*
|
|
963
|
+
* @param array - The TypedArray to check.
|
|
964
|
+
* @returns True if the TypedArray is of the same type as the DataType.
|
|
965
|
+
*/
|
|
966
|
+
checkArray(array: NativeTypedArray): boolean {
|
|
967
|
+
return array.constructor === this.Array;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
toJSON(): string {
|
|
971
|
+
return this.toString();
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
get usesBigInt(): boolean {
|
|
975
|
+
return DataType.BIG_INT_TYPES.some((t) => t.equals(this));
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/** Represents an Unknown/Invalid DataType. */
|
|
979
|
+
static readonly UNKNOWN = new DataType("unknown");
|
|
980
|
+
/** Represents a 64-bit floating point value. */
|
|
981
|
+
static readonly FLOAT64 = new DataType("float64");
|
|
982
|
+
/** Represents a 32-bit floating point value. */
|
|
983
|
+
static readonly FLOAT32 = new DataType("float32");
|
|
984
|
+
/** Represents a 64-bit signed integer value. */
|
|
985
|
+
static readonly INT64 = new DataType("int64");
|
|
986
|
+
/** Represents a 32-bit signed integer value. */
|
|
987
|
+
static readonly INT32 = new DataType("int32");
|
|
988
|
+
/** Represents a 16-bit signed integer value. */
|
|
989
|
+
static readonly INT16 = new DataType("int16");
|
|
990
|
+
/** Represents a 8-bit signed integer value. */
|
|
991
|
+
static readonly INT8 = new DataType("int8");
|
|
992
|
+
/** Represents a 64-bit unsigned integer value. */
|
|
993
|
+
static readonly UINT64 = new DataType("uint64");
|
|
994
|
+
/** Represents a 32-bit unsigned integer value. */
|
|
995
|
+
static readonly UINT32 = new DataType("uint32");
|
|
996
|
+
/** Represents a 16-bit unsigned integer value. */
|
|
997
|
+
static readonly UINT16 = new DataType("uint16");
|
|
998
|
+
/** Represents a 8-bit unsigned integer value. */
|
|
999
|
+
static readonly UINT8 = new DataType("uint8");
|
|
1000
|
+
/** Represents a 64-bit unix epoch. */
|
|
1001
|
+
static readonly TIMESTAMP = new DataType("timestamp");
|
|
1002
|
+
/** Represents a UUID data type */
|
|
1003
|
+
static readonly UUID = new DataType("uuid");
|
|
1004
|
+
/** Represents a string data type. Strings have an unknown density, and are separate
|
|
1005
|
+
* by a newline character. */
|
|
1006
|
+
static readonly STRING = new DataType("string");
|
|
1007
|
+
/** Represents a JSON data type. JSON has an unknown density, and is separated by a
|
|
1008
|
+
* newline character. */
|
|
1009
|
+
static readonly JSON = new DataType("json");
|
|
1010
|
+
|
|
1011
|
+
static readonly ARRAY_CONSTRUCTORS: Map<string, NativeTypedArrayConstructor> =
|
|
1012
|
+
new Map<string, NativeTypedArrayConstructor>([
|
|
1013
|
+
[DataType.UINT8.toString(), Uint8Array],
|
|
1014
|
+
[DataType.UINT16.toString(), Uint16Array],
|
|
1015
|
+
[DataType.UINT32.toString(), Uint32Array],
|
|
1016
|
+
[DataType.UINT64.toString(), BigUint64Array],
|
|
1017
|
+
[DataType.FLOAT32.toString(), Float32Array],
|
|
1018
|
+
[DataType.FLOAT64.toString(), Float64Array],
|
|
1019
|
+
[DataType.INT8.toString(), Int8Array],
|
|
1020
|
+
[DataType.INT16.toString(), Int16Array],
|
|
1021
|
+
[DataType.INT32.toString(), Int32Array],
|
|
1022
|
+
[DataType.INT64.toString(), BigInt64Array],
|
|
1023
|
+
[DataType.TIMESTAMP.toString(), BigInt64Array],
|
|
1024
|
+
[DataType.STRING.toString(), Uint8Array],
|
|
1025
|
+
[DataType.JSON.toString(), Uint8Array],
|
|
1026
|
+
[DataType.UUID.toString(), Uint8Array],
|
|
1027
|
+
]);
|
|
1028
|
+
|
|
1029
|
+
static readonly ARRAY_CONSTRUCTOR_DATA_TYPES: Map<string, DataType> = new Map<
|
|
1030
|
+
string,
|
|
1031
|
+
DataType
|
|
1032
|
+
>([
|
|
1033
|
+
[Uint8Array.name, DataType.UINT8],
|
|
1034
|
+
[Uint16Array.name, DataType.UINT16],
|
|
1035
|
+
[Uint32Array.name, DataType.UINT32],
|
|
1036
|
+
[BigUint64Array.name, DataType.UINT64],
|
|
1037
|
+
[Float32Array.name, DataType.FLOAT32],
|
|
1038
|
+
[Float64Array.name, DataType.FLOAT64],
|
|
1039
|
+
[Int8Array.name, DataType.INT8],
|
|
1040
|
+
[Int16Array.name, DataType.INT16],
|
|
1041
|
+
[Int32Array.name, DataType.INT32],
|
|
1042
|
+
[BigInt64Array.name, DataType.INT64],
|
|
1043
|
+
]);
|
|
1044
|
+
|
|
1045
|
+
static readonly DENSITIES = new Map<string, Density>([
|
|
1046
|
+
[DataType.UINT8.toString(), Density.BIT8],
|
|
1047
|
+
[DataType.UINT16.toString(), Density.BIT16],
|
|
1048
|
+
[DataType.UINT32.toString(), Density.BIT32],
|
|
1049
|
+
[DataType.UINT64.toString(), Density.BIT64],
|
|
1050
|
+
[DataType.FLOAT32.toString(), Density.BIT32],
|
|
1051
|
+
[DataType.FLOAT64.toString(), Density.BIT64],
|
|
1052
|
+
[DataType.INT8.toString(), Density.BIT8],
|
|
1053
|
+
[DataType.INT16.toString(), Density.BIT16],
|
|
1054
|
+
[DataType.INT32.toString(), Density.BIT32],
|
|
1055
|
+
[DataType.INT64.toString(), Density.BIT64],
|
|
1056
|
+
[DataType.TIMESTAMP.toString(), Density.BIT64],
|
|
1057
|
+
[DataType.STRING.toString(), Density.UNKNOWN],
|
|
1058
|
+
[DataType.JSON.toString(), Density.UNKNOWN],
|
|
1059
|
+
[DataType.UUID.toString(), Density.BIT128],
|
|
1060
|
+
]);
|
|
1061
|
+
|
|
1062
|
+
static readonly BIG_INT_TYPES = [DataType.INT64, DataType.UINT64, DataType.TIMESTAMP];
|
|
1063
|
+
|
|
1064
|
+
/** A zod schema for a DataType. */
|
|
1065
|
+
static readonly z = z.union([
|
|
1066
|
+
z.string().transform((v) => new DataType(v)),
|
|
1067
|
+
z.instanceof(DataType),
|
|
1068
|
+
]);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* The Size of an elementy in bytes.
|
|
1073
|
+
*/
|
|
1074
|
+
export class Size extends Number implements Stringer {
|
|
1075
|
+
constructor(value: CrudeSize) {
|
|
1076
|
+
super(value.valueOf());
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/** @returns true if the Size is larger than the other size. */
|
|
1080
|
+
largerThan(other: CrudeSize): boolean {
|
|
1081
|
+
return this.valueOf() > other.valueOf();
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
/** @returns true if the Size is smaller than the other sisze. */
|
|
1085
|
+
smallerThan(other: CrudeSize): boolean {
|
|
1086
|
+
return this.valueOf() < other.valueOf();
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
add(other: CrudeSize): Size {
|
|
1090
|
+
return Size.bytes(this.valueOf() + other.valueOf());
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
sub(other: CrudeSize): Size {
|
|
1094
|
+
return Size.bytes(this.valueOf() - other.valueOf());
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* Creates a Size from the given number of bytes.
|
|
1099
|
+
*
|
|
1100
|
+
* @param value - The number of bytes.
|
|
1101
|
+
* @returns A Size representing the given number of bytes.
|
|
1102
|
+
*/
|
|
1103
|
+
static bytes(value: CrudeSize = 1): Size {
|
|
1104
|
+
return new Size(value);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/** A single byte */
|
|
1108
|
+
static readonly BYTE = new Size(1);
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Creates a Size from the given number if kilobytes.
|
|
1112
|
+
*
|
|
1113
|
+
* @param value - The number of kilobytes.
|
|
1114
|
+
* @returns A Size representing the given number of kilobytes.
|
|
1115
|
+
*/
|
|
1116
|
+
static kilobytes(value: CrudeSize = 1): Size {
|
|
1117
|
+
return Size.bytes(value.valueOf() * 1e3);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/** A kilobyte */
|
|
1121
|
+
static readonly KILOBYTE = Size.kilobytes(1);
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* Creates a Size from the given number of megabytes.
|
|
1125
|
+
*
|
|
1126
|
+
* @param value - The number of megabytes.
|
|
1127
|
+
* @returns A Size representing the given number of megabytes.
|
|
1128
|
+
*/
|
|
1129
|
+
static megabytes(value: CrudeSize = 1): Size {
|
|
1130
|
+
return Size.kilobytes(value.valueOf() * 1e3);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/** A megabyte */
|
|
1134
|
+
static readonly MEGABYTE = Size.megabytes(1);
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* Creates a Size from the given number of gigabytes.
|
|
1138
|
+
*
|
|
1139
|
+
* @param value - The number of gigabytes.
|
|
1140
|
+
* @returns A Size representing the given number of gigabytes.
|
|
1141
|
+
*/
|
|
1142
|
+
static gigabytes(value: CrudeSize = 1): Size {
|
|
1143
|
+
return Size.megabytes(value.valueOf() * 1e3);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/** A gigabyte */
|
|
1147
|
+
static readonly GIGABYTE = Size.gigabytes(1);
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* Creates a Size from the given number of terabytes.
|
|
1151
|
+
*
|
|
1152
|
+
* @param value - The number of terabytes.
|
|
1153
|
+
* @returns A Size representing the given number of terabytes.
|
|
1154
|
+
*/
|
|
1155
|
+
static terabytes(value: CrudeSize): Size {
|
|
1156
|
+
return Size.gigabytes(value.valueOf() * 1e3);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/** A terabyte. */
|
|
1160
|
+
static readonly TERABYTE = Size.terabytes(1);
|
|
1161
|
+
|
|
1162
|
+
/** The zero value for Size */
|
|
1163
|
+
static readonly ZERO = new Size(0);
|
|
1164
|
+
|
|
1165
|
+
/** A zod schema for a Size. */
|
|
1166
|
+
static readonly z = z.union([
|
|
1167
|
+
z.number().transform((v) => new Size(v)),
|
|
1168
|
+
z.instanceof(Size),
|
|
1169
|
+
]);
|
|
1170
|
+
|
|
1171
|
+
isZero(): boolean {
|
|
1172
|
+
return this.valueOf() === 0;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
export type CrudeTimeStamp =
|
|
1177
|
+
| TimeStamp
|
|
1178
|
+
| TimeSpan
|
|
1179
|
+
| number
|
|
1180
|
+
| Date
|
|
1181
|
+
| string
|
|
1182
|
+
| DateComponents
|
|
1183
|
+
| Number;
|
|
1184
|
+
export type TimeStampT = number;
|
|
1185
|
+
export type CrudeTimeSpan = TimeSpan | TimeStamp | number | Number;
|
|
1186
|
+
export type TimeSpanT = number;
|
|
1187
|
+
export type CrudeRate = Rate | number | Number;
|
|
1188
|
+
export type RateT = number;
|
|
1189
|
+
export type CrudeDensity = Density | number | Number;
|
|
1190
|
+
export type DensityT = number;
|
|
1191
|
+
export type CrudeDataType = DataType | string | NativeTypedArray;
|
|
1192
|
+
export type DataTypeT = string;
|
|
1193
|
+
export type CrudeSize = Size | number | Number;
|
|
1194
|
+
export type SizeT = number;
|
|
1195
|
+
export interface CrudeTimeRange {
|
|
1196
|
+
start: TimeStampT;
|
|
1197
|
+
end: TimeStampT;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
export const nativeTypedArray = z.union([
|
|
1201
|
+
z.instanceof(Uint8Array),
|
|
1202
|
+
z.instanceof(Uint16Array),
|
|
1203
|
+
z.instanceof(Uint32Array),
|
|
1204
|
+
z.instanceof(BigUint64Array),
|
|
1205
|
+
z.instanceof(Float32Array),
|
|
1206
|
+
z.instanceof(Float64Array),
|
|
1207
|
+
z.instanceof(Int8Array),
|
|
1208
|
+
z.instanceof(Int16Array),
|
|
1209
|
+
z.instanceof(Int32Array),
|
|
1210
|
+
z.instanceof(BigInt64Array),
|
|
1211
|
+
]);
|
|
1212
|
+
|
|
1213
|
+
export type NativeTypedArray = z.infer<typeof nativeTypedArray>;
|
|
1214
|
+
|
|
1215
|
+
type NativeTypedArrayConstructor =
|
|
1216
|
+
| Uint8ArrayConstructor
|
|
1217
|
+
| Uint16ArrayConstructor
|
|
1218
|
+
| Uint32ArrayConstructor
|
|
1219
|
+
| BigUint64ArrayConstructor
|
|
1220
|
+
| Float32ArrayConstructor
|
|
1221
|
+
| Float64ArrayConstructor
|
|
1222
|
+
| Int8ArrayConstructor
|
|
1223
|
+
| Int16ArrayConstructor
|
|
1224
|
+
| Int32ArrayConstructor
|
|
1225
|
+
| BigInt64ArrayConstructor;
|
|
1226
|
+
type TelemValue = number | bigint;
|
|
1227
|
+
|
|
1228
|
+
export const convertDataType = (
|
|
1229
|
+
source: DataType,
|
|
1230
|
+
target: DataType,
|
|
1231
|
+
value: TelemValue,
|
|
1232
|
+
offset: number | bigint = 0,
|
|
1233
|
+
): TelemValue => {
|
|
1234
|
+
if (source.usesBigInt && !target.usesBigInt) return Number(value) - Number(offset);
|
|
1235
|
+
if (!source.usesBigInt && target.usesBigInt) return BigInt(value) - BigInt(offset);
|
|
1236
|
+
return addSamples(value, -offset);
|
|
1237
|
+
};
|