import {Milliseconds, Nanoseconds} from './constants';
import {millisAsNanos, nanosAsJsDate, nanosAsMillis} from './util';
export interface TimeMeasurement {
asMilliseconds(truncate: boolean): Milliseconds;
asNanoseconds(): bigint;
}
export class NanoTimeMeasurement implements TimeMeasurement {
constructor(private readonly _nanos: Nanoseconds) {
}
asMilliseconds(truncate = false): Milliseconds {
return nanosAsMillis(this._nanos, truncate);
}
asNanoseconds(): Nanoseconds {
return this._nanos;
}
static fromNanoseconds(nanos: Nanoseconds): TimeMeasurement {
return new NanoTimeMeasurement(nanos);
}
static fromMillis(millis: number): TimeMeasurement {
return new NanoTimeMeasurement(millisAsNanos(millis));
}
}
export class Instant extends NanoTimeMeasurement {
asJsDate(): Date {
return nanosAsJsDate(this.asNanoseconds());
}
}
export interface Duration {
readonly elapsed: TimeMeasurement;
asMilliseconds(truncate: boolean): Milliseconds;
asNanoseconds(): bigint;
}
export class EagerDuration extends NanoTimeMeasurement implements Duration {
constructor(start: Nanoseconds, end: Nanoseconds) {
super(end - start);
}
get elapsed(): TimeMeasurement {
return this;
}
}
export class LazyDuration implements Duration {
private _elapsed: TimeMeasurement | undefined;
constructor(readonly start: Nanoseconds, readonly end: Nanoseconds) {
}
get elapsed(): TimeMeasurement {
if (!this._elapsed) {
this._elapsed = NanoTimeMeasurement.fromNanoseconds(this.end - this.start);
}
return this._elapsed;
}
asMilliseconds(truncate = false): Milliseconds {
return this.elapsed.asMilliseconds(truncate);
}
asNanoseconds(): bigint {
return this.elapsed.asNanoseconds();
}
}
export interface Period extends Duration {
readonly from: Instant;
readonly to: Instant;
}
export class EagerPeriod extends EagerDuration implements Period {
constructor(readonly from: Instant, readonly to: Instant) {
super(from.asNanoseconds(), to.asNanoseconds());
}
}
export class LazyPeriod extends LazyDuration implements Period {
constructor(readonly from: Instant, readonly to: Instant) {
super(from.asNanoseconds(), to.asNanoseconds());
}
}
|