Create Type File for Typescript compatibility
fieldju opened this issue · 5 comments
I think it would be cool to have an official type file either included with this project or available via
npn install @types/measured
I have made the following in my project which is probably almost everything that is needed
/**
* Everything in this file is sourced from the [measured readme]{@link https://github.com/felixge/node-measured}
*/
declare module 'measured' {
/**
* Values that can be read instantly.
*
* Gauges take a function as parameter which needs to return their current value.
*/
export class Gauge {
constructor(callBack: () => number)
/**
* Gauges directly return their currently value.
*/
public toJSON(): JSON
}
/**
* Things that increment or decrement.
*/
export class Counter implements IMetric {
/**
* @param {CounterProperties} properties
*/
constructor(properties?: CounterProperties)
/**
* Increment the counter by n. Defaults to 1.
* @param {number} n
*/
public inc(n?: number): void
/**
* Decrement the counter by n. Defaults to 1.
* @param {number} n
*/
public dec(n?: number): void
/**
* Resets the counter back to count Defaults to 0.
* @param {number} count
*/
public reset(count?: number): void
/**
* Counters directly return their currently value.
*/
public toJSON(): JSON
}
/**
* Properties to create a [Counter]{@see Counter} with.
*/
export class CounterProperties {
/**
* count An initial count for the counter. Defaults to 0.
*/
public count: number
}
/**
* Things that are measured as events / interval. Example:
*/
export class Meter implements IMetric {
/**
* rateUnit The rate unit. Defaults to 1000 (1 sec).
* tickInterval The interval in which the averages are updated. Defaults to 5000 (5 sec).
* @param {MeterProperties} properties
*/
constructor(properties?: MeterProperties)
/**
* Register n events as having just occured. Defaults to 1.
* @param {number} n
*/
public mark(n: number)
/**
* Resets all values. Meters initialized with custom options will be reset to the default settings (patch welcome).
*/
public reset(): void
/**
* Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent.
*/
public unref(): void
/**
* Refs the backing timer again. Idempotent.
*/
public ref(): void
/**
* toJSON Output
*
* <li> mean: The average rate since the meter was started.
* <li> count: The total of all values added to the meter.
* <li> currentRate: The rate of the meter since the last toJSON() call.
* <li> 1MinuteRate: The rate of the meter biased towards the last 1 minute.
* <li> 5MinuteRate: The rate of the meter biased towards the last 5 minutes.
* <li> 15MinuteRate: The rate of the meter biased towards the last 15 minutes.
*
* @return {JSON}
*/
public toJSON(): JSON
}
/**
* Properties to create a [Meter]{@see Meter} with.
*/
export class MeterProperties {
/**
* The rate unit. Defaults to 1000 (1 sec).
*/
public rateUnit: number
/**
* The interval in which the averages are updated. Defaults to 5000 (5 sec).
*/
public tickInterval: number
}
/**
* Keeps a resevoir of statistically relevant values biased towards the last 5 minutes to explore their distribution.
*
* {@link https://github.com/felixge/node-measured#histogram}
*/
export class Histogram implements IMetric {
/**
* @param {HistogramProperties} properties
*/
constructor(properties?: HistogramProperties)
/**
* Pushes value into the sample. timestamp defaults to Date.now().
* @param {number} value
* @param {Date} timestamp
*/
public update(value: number, timestamp?: Date): void
/**
* Whether the histogram contains values.
* @return {boolean}
*/
public hasValues(): boolean
/**
* Resets all values. Histograms initialized with custom options will be reset to the default settings (patch welcome).
*/
public reset(): void
/**
* toJSON output:
*
* <li> min: The lowest observed value.
* <li> max: The highest observed value.
* <li> sum: The sum of all observed values.
* <li> variance: The variance of all observed values.
* <li> mean: The average of all observed values.
* <li> stddev: The stddev of all observed values.
* <li> count: The number of observed values.
* <li> median: 50% of all values in the resevoir are at or below this value.
* <li> p75: See median, 75% percentile.
* <li> p95: See median, 95% percentile.
* <li> p99: See median, 99% percentile.
* <li> p999: See median, 99.9% percentile.
*
* @return {JSON}
*/
public toJSON(): JSON
}
/**
* Properties to create a [Histogram]{@see Histogram} with.
*/
export class HistogramProperties {
/**
* The sample resevoir to use. Defaults to an ExponentiallyDecayingSample.
*/
public sample: object
}
/**
* Timers are a combination of Meters and Histograms. They measure the rate as well as distribution of scalar events.
* Since they are frequently used for tracking how long certain things take, they expose an API for that:
*
* {@see https://github.com/felixge/node-measured#timers}
*/
export class Timer implements IMetric {
/**
* @param {TimerProperties} properties
*/
constructor(properties?: TimerProperties)
/**
* @return {StopWatch} Returns a Stopwatch that has been started.
*/
public start(): StopWatch
/**
* Updates the internal histogram with value and marks one event on the internal meter.
* @param {number} value
*/
public update(value: number)
/**
* Resets all values. Timers initialized with custom options will be reset to the default settings.
*/
public reset(): void
/**
* Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent.
*/
public unref(): void
/**
* Refs the backing timer again. Idempotent.
*/
public ref(): void
/**
* toJSON output:
*
* <li> meter: {@see Meter} toJSON output docs above.
* <li> histogram: {@see Histogram} toJSON output docs above.
*
* @return {JSON}
*/
public toJSON(): JSON
}
/**
* Properties to create a [Timer]{@see Timer} with.
*/
export class TimerProperties {
/**
* The internal meter to use. Defaults to a new Meter.
* {@see Meter}
*/
public meter: Meter
/**
* The internal histogram to use. Defaults to a new Histogram.
* {@see Histogram}
*/
public histogram: Histogram
}
/**
* Created by the Timer Metric when start() is called
*/
export class StopWatch {
/**
* Called to mark the end of the timer task
* @return {number} the total execution time
*/
public end(): number
}
/**
* Creates a collection that can create and keep track of metrics
*/
export const createCollection: (name?: string) => Collection
/**
* Collection class that keeps track of Metrics that it has created
*
* @param {string} name Optional name to use for the collection
*/
export class Collection {
constructor(name: string)
/**
* {@see https://github.com/felixge/node-measured/blob/master/lib/Collection.js}
* @return {JSON} JSON object with all the metrics in the collection
*/
public toJSON(): JSON
/**
* Iterates through the metrics in the collection and
* calls end() in the metric, if the metric has an end() method.
*/
public end(): void
/**
* Creates a new Gauge and registers it with the metrics collection
*
* {@see Gauge}
*
* @param {() => number} callBack
* @return {Gauge}
*/
public guage(callBack: () => number): Gauge
/**
* Creates a new Counter and registers it with the metrics collection
*
* {@see Counter}
*
* @param {CounterProperties} properties optional counter properties.
* @return {Counter}
*/
public counter(properties?: CounterProperties): Counter
/**
* Creates a new Meter and registers it with the metrics collection
*
* {@see Meter}
*
* @param {MeterProperties} properties
* @return {Meter}
*/
public meter(properties?: MeterProperties): Meter
/**
* Creates a new Histogram and registers it with the metrics collection
*
* {@see Histogram}
*
* @param {HistogramProperties} properties
* @return {Histogram}
*/
public histogram(properties?: HistogramProperties): Histogram
/**
* Creates a new Timer and registers it with the metrics collection
*
* {@see Timer}
*
* @param {TimerProperties} properties
* @return {Timer}
*/
public timer(properties?: TimerProperties): Timer
}
/**
* All metrics implement toJSON()
*/
export interface IMetric {
/**
* See the toJSON metric of the implementing classes
* @return {JSON}
*/
toJSON(): JSON
}
}
I think a modified version of the above could be included with index.js
Checkout what AWS is doing with their Node SDK
https://github.com/aws/aws-sdk-js
If this is something you are open to I could make a PR.
I think this would benefit all users regardless if they use typescript, as it will add java docs and return types to their IDEs
Not particularly, I added bunch of js doc annotations throughout the code base which gives you intelisense and IDE type warnings when using Javascript.
This was enough to meet my needs, since I had been developing this lib for people that don't use typescript.
Although I do have a project in the pipeline that will be typescript and use this lib, so maybe I'll revisit this soon.
Feel free to make a PR or reopen.
That project that was in the pipeline is here, I will probably do this soon (tm).
I last commented on this June 6th, 💯
Update: I am planning on using this library in https://github.com/Nike-Inc/Referee and I will be needed the types for that project and will get it done then. That work is likely to start in the next couple of weeks.
FWIW, i updated OPs to be measured-core and added actual toJSON return types, and a couple other things
/**
* Everything in this file is sourced from the [measured readme]{@link https://github.com/felixge/node-measured}
*/
declare module 'measured-core' {
/**
* Values that can be read instantly.
*
* Gauges take a function as parameter which needs to return their current value.
*/
export class Gauge implements IMetric {
getType(): 'Gauge';
constructor(callback: () => number)
/**
* Gauges directly return their currently value.
*/
public toJSON(): number
}
/**
* Things that increment or decrement.
*/
export class Counter implements IMetric {
getType(): 'Counter';
/**
* @param properties
*/
constructor(properties?: CounterProperties)
/**
* Increment the counter by n. Defaults to 1.
* @param n
*/
public inc(n?: number): void
/**
* Decrement the counter by n. Defaults to 1.
* @param n
*/
public dec(n?: number): void
/**
* Resets the counter back to count Defaults to 0.
* @param count
*/
public reset(count?: number): void
/**
* Counters directly return their currently value.
*/
public toJSON(): number
}
/**
* Properties to create a [Counter]{@see Counter} with.
*/
export class CounterProperties {
/**
* count An initial count for the counter. Defaults to 0.
*/
public count: number
}
/**
* Things that are measured as events / interval. Example:
*/
export class Meter implements IMetric {
getType(): 'Meter';
/**
* rateUnit The rate unit. Defaults to 1000 (1 sec).
* tickInterval The interval in which the averages are updated. Defaults to 5000 (5 sec).
* @param properties
*/
constructor(properties?: MeterProperties)
/**
* Register n events as having just occured. Defaults to 1.
* @param n
*/
public mark(n: number): void
/**
* Resets all values. Meters initialized with custom options will be reset to the default settings (patch welcome).
*/
public reset(): void
/**
* Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent.
*/
public unref(): void
/**
* Refs the backing timer again. Idempotent.
*/
public ref(): void
/**
* toJSON Output
*
* <li> mean: The average rate since the meter was started.
* <li> count: The total of all values added to the meter.
* <li> currentRate: The rate of the meter since the last toJSON() call.
* <li> 1MinuteRate: The rate of the meter biased towards the last 1 minute.
* <li> 5MinuteRate: The rate of the meter biased towards the last 5 minutes.
* <li> 15MinuteRate: The rate of the meter biased towards the last 15 minutes.
*
* @return
*/
public toJSON(): MeterData
}
export interface MeterData {
/**
* The average rate since the meter was started.
*/
mean: number;
/**
* The total of all values added to the meter.
*/
count: number;
/**
* The rate of the meter since the last toJSON() call.
*/
currentRate: number;
/**
* The rate of the meter biased towards the last 1 minute.
*/
'1MinuteRate': number;
/**
* The rate of the meter biased towards the last 5 minutes.
*/
'5MinuteRate': number;
/**
* The rate of the meter biased towards the last 15 minutes.
*/
'15MinuteRate': number;
}
/**
* Properties to create a [Meter]{@see Meter} with.
*/
export class MeterProperties {
/**
* The rate unit. Defaults to 1000 (1 sec).
*/
public rateUnit: number
/**
* The interval in which the averages are updated. Defaults to 5000 (5 sec).
*/
public tickInterval: number
}
/**
* Keeps a resevoir of statistically relevant values biased towards the last 5 minutes to explore their distribution.
*
* {@link https://github.com/felixge/node-measured#histogram}
*/
export class Histogram implements IMetric {
getType(): 'Histogram';
/**
* @param properties
*/
constructor(properties?: HistogramProperties)
/**
* Pushes value into the sample. timestamp defaults to Date.now().
* @param value
* @param timestamp
*/
public update(value: number, timestamp?: Date): void
/**
* Whether the histogram contains values.
* @return
*/
public hasValues(): boolean
/**
* Resets all values. Histograms initialized with custom options will be reset to the default settings (patch welcome).
*/
public reset(): void
/**
* toJSON output:
*
* <li> min: The lowest observed value.
* <li> max: The highest observed value.
* <li> sum: The sum of all observed values.
* <li> variance: The variance of all observed values.
* <li> mean: The average of all observed values.
* <li> stddev: The stddev of all observed values.
* <li> count: The number of observed values.
* <li> median: 50% of all values in the resevoir are at or below this value.
* <li> p75: See median, 75% percentile.
* <li> p95: See median, 95% percentile.
* <li> p99: See median, 99% percentile.
* <li> p999: See median, 99.9% percentile.
*
* @return
*/
public toJSON(): HistogramData
}
export interface HistogramData {
/**
* The lowest observed value.
*/
min: number | null;
/**
* The highest observed value.
*/
max: number | null;
/**
* The sum of all observed values.
*/
sum: number | null;
/**
* The variance of all observed values.
*/
variance: number | null;
/**
* The average of all observed values.
*/
mean: number | null;
/**
* The stddev of all observed values.
*/
stddev: number | null;
/**
* The number of observed values.
*/
count: number;
/**
* 50% of all values in the resevoir are at or below this value.
*/
median: number;
/**
* See median, 75% percentile.
*/
p75: number;
/**
* See median, 95% percentile.
*/
p95: number;
/**
* See median, 99% percentile.
*/
p99: number;
/**
* See median, 99.9% percentile.
*/
p999: number;
}
/**
* Properties to create a [Histogram]{@see Histogram} with.
*/
export class HistogramProperties {
/**
* The sample resevoir to use. Defaults to an ExponentiallyDecayingSample.
*/
public sample: object
}
/**
* Timers are a combination of Meters and Histograms. They measure the rate as well as distribution of scalar events.
* Since they are frequently used for tracking how long certain things take, they expose an API for that:
*
* {@see https://github.com/felixge/node-measured#timers}
*/
export class Timer implements IMetric {
getType(): 'Timer';
/**
* @param properties
*/
constructor(properties?: TimerProperties)
/**
* @return Returns a Stopwatch that has been started.
*/
public start(): StopWatch
/**
* Updates the internal histogram with value and marks one event on the internal meter.
* @param value
*/
public update(value: number): void
/**
* Resets all values. Timers initialized with custom options will be reset to the default settings.
*/
public reset(): void
/**
* Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent.
*/
public unref(): void
/**
* Refs the backing timer again. Idempotent.
*/
public ref(): void
/**
* toJSON output:
*
* <li> meter: {@see Meter} toJSON output docs above.
* <li> histogram: {@see Histogram} toJSON output docs above.
*
* @return
*/
public toJSON(): { meter: MeterData; histogram: HistogramData; }
}
/**
* Properties to create a [Timer]{@see Timer} with.
*/
export class TimerProperties {
/**
* The internal meter to use. Defaults to a new Meter.
* {@see Meter}
*/
public meter: Meter
/**
* The internal histogram to use. Defaults to a new Histogram.
* {@see Histogram}
*/
public histogram: Histogram
}
/**
* Created by the Timer Metric when start() is called
*/
export class StopWatch {
/**
* Called to mark the end of the timer task
* @return the total execution time
*/
public end(): number
}
/**
* Creates a collection that can create and keep track of metrics
*/
export const createCollection: (name?: string) => Collection
/**
* Collection class that keeps track of Metrics that it has created
*
* @param name Optional name to use for the collection
*/
export class Collection<TName extends undefined | string = undefined> {
public name: TName;
/**
* Note: This is technically private but you may prefer to use this vs toJSON to iterate metrics. From my reading of the code, I see no reason not to
*/
public _metrics: Record<string, IMetric>;
constructor(name?: TName)
/**
* {@see https://github.com/felixge/node-measured/blob/master/lib/Collection.js}
* @return JSON object with all the metrics in the collection
*/
public toJSON(): TName extends string ? { [key in TName]: Record<string, unknown> } : Record<string, unknown>
/**
* Iterates through the metrics in the collection and
* calls end() in the metric, if the metric has an end() method.
*/
public end(): void
/**
* Creates a new Gauge and registers it with the metrics collection
*
* {@see Gauge}
*
* @param callback
* @return
*/
public guage(callback: () => number): Gauge
/**
* Creates a new Counter and registers it with the metrics collection
*
* {@see Counter}
*
* @param properties optional counter properties.
* @return
*/
public counter(properties?: CounterProperties): Counter
/**
* Creates a new Meter and registers it with the metrics collection
*
* {@see Meter}
*
* @param properties
* @return
*/
public meter(properties?: MeterProperties): Meter
/**
* Creates a new Histogram and registers it with the metrics collection
*
* {@see Histogram}
*
* @param properties
* @return
*/
public histogram(properties?: HistogramProperties): Histogram
/**
* Creates a new Timer and registers it with the metrics collection
*
* {@see Timer}
*
* @param properties
* @return
*/
public timer(properties?: TimerProperties): Timer
/**
* register a metric that was created outside the provided convenience methods of this collection
* @param name The metric name
* @param metric The {@link IMetric} implementation
* @example
* var { Collection, Gauge } = require('measured');
* const collection = new Collection('node-process-metrics');
* const gauge = new Gauge(() => {
* return process.memoryUsage().heapUsed;
* });
* collection.register('node.process.heap_used', gauge);
*/
public register(name: string, metric: IMetric): void;
}
/**
* All metrics implement toJSON()
*/
export interface IMetric {
getType(): string;
/**
* See the toJSON metric of the implementing classes
* @return
*/
toJSON(): unknown
}
}