diff --git a/README.md b/README.md index b03fc08a..1d48a7ee 100644 --- a/README.md +++ b/README.md @@ -8,547 +8,33 @@ > Get usage and health data about your Node.js process. -`doc` is a small module that helps you collect health metrics about your Node.js process. -It does that by using only the API available on Node itself (no native dependencies). -It doesn't have any ties with an APM platform, so you are free to use anything you want for that purpose. -Its API lets you access both computed and raw values, where possible. +[Read the full documentation](https://dnlup.github.io/doc). - [Installation](#installation) - * [latest stable version](#latest-stable-version) - * [latest development version](#latest-development-version) - [Usage](#usage) - * [Importing with CommonJS](#importing-with-commonjs) - * [Importing with ESM](#importing-with-esm) - * [Note](#note) - - [Enable/disable metrics collection](#enabledisable-metrics-collection) - - [Garbage collection](#garbage-collection) - - [Active handles](#active-handles) - * [Examples](#examples) -- [API](#api) - * [`doc([options])`](#docoptions) - * [Class: `doc.Sampler`](#class-docsampler) - + [new `doc.Sampler([options])`](#new-docsampleroptions) - + [Event: '`sample`'](#event-sample) - + [`sampler.start()`](#samplerstart) - + [`sampler.stop()`](#samplerstop) - + [`sampler.cpu`](#samplercpu) - + [`sampler.resourceUsage`](#samplerresourceusage) - + [`sampler.eventLoopDelay`](#samplereventloopdelay) - + [`sampler.eventLoopUtilization`](#samplereventlooputilization) - + [`sampler.gc`](#samplergc) - + [`sampler.activeHandles`](#sampleractivehandles) - + [`sampler.memory`](#samplermemory) - * [Class: `CpuMetric`](#class-cpumetric) - + [`cpuMetric.usage`](#cpumetricusage) - + [`cpuMetric.raw`](#cpumetricraw) - * [Class: `ResourceUsageMetric`](#class-resourceusagemetric) - + [`resourceUsage.cpu`](#resourceusagecpu) - + [`resourceUsage.raw`](#resourceusageraw) - * [Class: `EventLoopDelayMetric`](#class-eventloopdelaymetric) - + [`eventLoopDelay.computed`](#eventloopdelaycomputed) - + [`eventLoopDelay.raw`](#eventloopdelayraw) - + [`eventLoopDelay.compute(raw)`](#eventloopdelaycomputeraw) - * [Class: `EventLoopUtilizationMetric`](#class-eventlooputilizationmetric) - + [`eventLoopUtilization.idle`](#eventlooputilizationidle) - + [`eventLoopUtilization.active`](#eventlooputilizationactive) - + [`eventLoopUtilization.utilization`](#eventlooputilizationutilization) - + [`eventLoopUtilization.raw`](#eventlooputilizationraw) - * [Class: `GCMetric`](#class-gcmetric) - + [`new GCMetric(options)`](#new-gcmetricoptions) - * [`gcMetric.pause`](#gcmetricpause) - + [`gcMetric.major`](#gcmetricmajor) - + [`gcMetric.minor`](#gcmetricminor) - + [`gcMetric.incremental`](#gcmetricincremental) - + [`gcMetric.weakCb`](#gcmetricweakcb) - * [Class: `GCEntry`](#class-gcentry) - + [`new GCEntry()`](#new-gcentry) - + [`gcEntry.totalDuration`](#gcentrytotalduration) - + [`gcEntry.totalCount`](#gcentrytotalcount) - + [`gcEntry.mean`](#gcentrymean) - + [`gcEntry.max`](#gcentrymax) - + [`gcEntry.min`](#gcentrymin) - + [`gcEntry.stdDeviation`](#gcentrystddeviation) - + [`gcEntry.summary`](#gcentrysummary) - + [`gcEntry.getPercentile(percentile)`](#gcentrygetpercentilepercentile) - * [Class: `GCAggregatedEntry`](#class-gcaggregatedentry) - + [`new GCAggregatedEntry()`](#new-gcaggregatedentry) - + [`gcAggregatedEntry.flags`](#gcaggregatedentryflags) - + [`gcAggregatedEntry.flags.no`](#gcaggregatedentryflagsno) - + [`gcAggregatedEntry.flags.constructRetained`](#gcaggregatedentryflagsconstructretained) - + [`gcAggregatedEntry.flags.forced`](#gcaggregatedentryflagsforced) - + [`gcAggregatedEntry.flags.synchronousPhantomProcessing`](#gcaggregatedentryflagssynchronousphantomprocessing) - + [`gcAggregatedEntry.flags.allAvailableGarbage`](#gcaggregatedentryflagsallavailablegarbage) - + [`gcAggregatedEntry.flags.allExternalMemory`](#gcaggregatedentryflagsallexternalmemory) - + [`gcAggregatedEntry.flags.scheduleIdle`](#gcaggregatedentryflagsscheduleidle) - * [`doc.eventLoopUtilizationSupported`](#doceventlooputilizationsupported) - * [`doc.resourceUsageSupported`](#docresourceusagesupported) - * [`doc.gcFlagsSupported`](#docgcflagssupported) - * [`doc.errors`](#docerrors) +- [Examples](#examples) +- [Contributing](#contributing) - [License](#license) ## Installation -###### latest stable version - -```bash -$ npm i @dnlup/doc -``` - -###### latest development version - -```bash -$ npm i @dnlup/doc@next -``` +See [here](https://dnlup.github.io/doc/#/?id=installation). ## Usage -You can import the module by using either CommonJS or ESM. - -By default `doc` returns a [`Sampler`](#class-docsampler) instance that collects metrics about cpu, memory usage, event loop delay and event loop utilization (only on Node versions that [support it](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2)). - -###### Importing with CommonJS - -```js -const doc = require('@dnlup/doc') - -const sampler = doc() // Use the default options - -sampler.on('sample', () => { - doStuffWithCpuUsage(sampler.cpu.usage) - doStuffWithMemoryUsage(sampler.memory) - doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) - doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it -}) -``` - -###### Importing with ESM - -```js -import doc from '@dnlup/doc' - -const sampler = doc() - -sampler.on('sample', () => { - doStuffWithCpuUsage(sampler.cpu.usage) - doStuffWithMemoryUsage(sampler.memory) - doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) - doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it -}) -``` - -###### Note - -A `Sampler` holds a snapshot of the metrics taken at the specified sample interval. -This behavior makes the instance stateful. On every tick, a new snapshot will overwrite the previous one. - -##### Enable/disable metrics collection - -You can disable the metrics that you don't need. - -```js -const doc = require('@dnlup/doc') - -// Collect only the event loop delay -const sampler = doc({ collect: { cpu: false, memory: false } }) - -sampler.on('sample', () => { - // `sampler.cpu` will be `undefined` - // `sampler.memory` will be `undefined` - doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) - doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it -}) -``` - -You can enable more metrics if you need them. - -##### Garbage collection - -```js -const doc = require('@dnlup/doc') - -const sampler = doc({ collect: { gc: true } }) -sampler.on('sample', () => { - doStuffWithCpuUsage(sampler.cpu.usage) - doStuffWithMemoryUsage(sampler.memory) - doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) - doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it - doStuffWithGarbageCollectionDuration(sampler.gc.pause) -}) -``` - -##### Active handles - -```js -const doc = require('@dnlup/doc') - -const sampler = doc({ collect: { activeHandles: true } }) - -sampler.on('sample', () => { - doStuffWithCpuUsage(sampler.cpu.usage) - doStuffWithMemoryUsage(sampler.memory) - doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) - doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it - doStuffWithActiveHandles(sampler.activeHandles) -}) -``` - -### Examples - -You can find more examples in the [`examples`](./examples) folder. - -## API - -### `doc([options])` - -It creates a metrics [`Sampler`](#class-docsampler) instance with the given options. - -* `options` ``: same as the `Sampler` [`options`](#new-docsampleroptions). -* Returns: [``](#class-docsampler) - -### Class: `doc.Sampler` - -* Extends [`EventEmitter`](https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_class_eventemitter). - -Metrics sampler. - -It collects the selected metrics at a regular interval. A `Sampler` instance is stateful so, on each tick, -only the values of the last sample are available. Each time the sampler emits the [`sample`](#event-sample) event, it will overwrite the previous one. - -#### new `doc.Sampler([options])` - -* `options` `` - * `sampleInterval` ``: sample interval (ms) to get a sample. On each `sampleInterval` ms a [`sample`](#event-sample) event is emitted. **Default:** `500` on Node < 11.10.0, `1000` otherwise. Under the hood the package uses [`monitorEventLoopDelay`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options) when available to track the event loop delay and this allows to increase the default `sampleInterval`. - * `autoStart` ``: start automatically to collect metrics. **Default:** `true`. - * `unref` ``: [unref](https://nodejs.org/dist/latest-v12.x/docs/api/timers.html#timers_timeout_unref) the timer used to schedule the sampling interval. **Default:** `true`. - * `gcOptions` ``: Garbage collection options - * `aggregate` ``: Track and aggregate statistics about each garbage collection operation (see https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_kind). **Default:** `false` - * `flags` ``: , Track statistics about the flags of each (aggregated) garbage collection operation (see https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_flags). `aggregate` has to be `true` to enable this option. **Default:** `true` on Node version `12.17.0` and newer. - * `eventLoopDelayOptions` ``: Options to setup [`monitorEventLoopDelay`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options). **Default:** `{ resolution: 10 }` - * `collect` ``: enable/disable the collection of specific metrics. - * `cpu` ``: enable cpu metric. **Default:** `true`. - * `resourceUsage` ``: enable [resourceUsage](https://nodejs.org/docs/latest-v12.x/api/process.html#process_process_resourceusage) metric. **Default:** `false`. - * `eventLoopDelay` ``: enable eventLoopDelay metric. **Default:** `true`. - * `eventLoopUtilization` ``: enable [eventLoopUtilization](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) metric. **Default:** `true` on Node version `12.19.0` and newer. - * `memory` ``: enable memory metric. **Default:** `true`. - * `gc` ``: enable garbage collection metric. **Default:** `false`. - * `activeHandles` ``: enable active handles collection metric. **Default:** `false`. - -If `options.collect.resourceUsage` is set to `true`, `options.collect.cpu` will be set to false because the cpu metric is already available in the [`resource usage metric`](#samplerresourceusage). - -#### Event: '`sample`' - -Emitted every `sampleInterval`, it signals that new data the sampler has collected new data. - -#### `sampler.start()` - -Start collecting metrics. - -#### `sampler.stop()` - -Stop collecting metrics. - -#### `sampler.cpu` - -* [``](#class-cpumetric) - -Resource usage metric instance. - -#### `sampler.resourceUsage` - -* [``](#class-resourceusagemetric) - -Resource usage metric instance. - -#### `sampler.eventLoopDelay` - -* [``](#class-eventloopdelaymetric) - -Event loop delay metric instance. - -#### `sampler.eventLoopUtilization` - -* [``](#class-eventlooputilizationmetric) - -Event loop utilization metric instance. - -#### `sampler.gc` - -* [``](#class-gcmetric) - -Garbage collector metric instance. - -#### `sampler.activeHandles` - -* `` - -Number of active handles returned by `process._getActiveHandles()`. - -#### `sampler.memory` - -* `` - -Object returned by [`process.memoryUsage()`](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_memoryusage). - -### Class: `CpuMetric` - -It exposes both computed and raw values of the cpu usage. - -#### `cpuMetric.usage` - -* `` - -Cpu usage in percentage. - -#### `cpuMetric.raw` - -* `` - -Raw value returned by [`process.cpuUsage()`](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_cpuusage_previousvalue). - -### Class: `ResourceUsageMetric` - -It exposes both computed and raw values of the process resource usage. - -#### `resourceUsage.cpu` - -* `` - -Cpu usage in percentage. - -#### `resourceUsage.raw` - -* `` - -Raw value returned by [`process.resourceUsage()`](https://nodejs.org/docs/latest-v12.x/api/process.html#process_process_resourceusage). - -### Class: `EventLoopDelayMetric` - -It exposes both computed and raw values about the event loop delay. - -#### `eventLoopDelay.computed` - -* `` - -Event loop delay in milliseconds. On Node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v13.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options), it computes this value using the `mean` of the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. Otherwise, it uses a simple timer to calculate it. - -#### `eventLoopDelay.raw` - -* `` | `` - -On Node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options) this exposes the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. Otherwise, it exposes the raw delay value in nanoseconds. - -#### `eventLoopDelay.compute(raw)` - -* `raw` `` The raw value obtained using the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) API. -* Returns `` The computed delay value. - -This function works only on node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options). It allows to get computed values of the event loop delay from statistics other than the `mean` of the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. - -### Class: `EventLoopUtilizationMetric` - -It exposes statistics about the event loop utilization. - -#### `eventLoopUtilization.idle` - -* `` - -The `idle` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. - -#### `eventLoopUtilization.active` - -* `` - -The `active` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. -#### `eventLoopUtilization.utilization` - -* `` - -The `utilization` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. - -#### `eventLoopUtilization.raw` - -* `` - -Raw value returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. - -### Class: `GCMetric` - -It exposes the garbage collector activity statistics in the specified `sampleInterval` using hdr histograms. - -#### `new GCMetric(options)` - -* `options` ``: Configuration options - * `aggregate` ``: See `gcOptions.aggregate` in the [Sampler options](#new-docsampleroptions). - * `flags` ``: See `gcOptions.flags` in the [Sampler options](#new-docsampleroptions). - -### `gcMetric.pause` - -* [``](#class-gcentry) - -It tracks the global activity of the garbage collector. - -#### `gcMetric.major` - -* [``](#class-gcentry) | [``](#class-gcaggregatedentry) - -The activity of the operation of type `major`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. - -See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). - -#### `gcMetric.minor` - -* [``](#class-gcentry) | [``](#class-gcaggregatedentry) - -The activity of the operation of type `minor`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. - -See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). - -#### `gcMetric.incremental` - -* [``](#class-gcentry) | [``](#class-gcaggregatedentry) - -The activity of the operation of type `incremental`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. - -See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). - -#### `gcMetric.weakCb` - -* [``](#class-gcentry) | [``](#class-gcaggregatedentry) - -The activity of the operation of type `weakCb`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. - -See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). - -### Class: `GCEntry` - -It contains garbage collection data, represented with an [hdr histogram](https://github.com/HdrHistogram/HdrHistogramJS). All timing values are expressed in nanoseconds. - -#### `new GCEntry()` - -The initialization doesn't require options. It is created internally by a [`GCMetric`](#class-gcmetric). - -#### `gcEntry.totalDuration` - -* `` - -It is the total time of the entry in nanoseconds. - -#### `gcEntry.totalCount` - -* `` - -It is the total number of operations counted. - -#### `gcEntry.mean` - -* `` - -It is the mean value of the entry in nanoseconds. -#### `gcEntry.max` - -* `` - -It is the maximum value of the entry in nanoseconds. -#### `gcEntry.min` - -* `` - -It is the minimum value of the entry in nanoseconds. - -#### `gcEntry.stdDeviation` - -* `` - -It is the standard deviation of the entry in nanoseconds. - -#### `gcEntry.summary` - -* `` - -The hdr histogram summary. See https://github.com/HdrHistogram/HdrHistogramJS#record-values-and-retrieve-metrics. - -#### `gcEntry.getPercentile(percentile)` - -* `percentile` ``: Get a percentile from the histogram. -* Returns `` The percentile - -See https://github.com/HdrHistogram/HdrHistogramJS#record-values-and-retrieve-metrics. - -### Class: `GCAggregatedEntry` - -It extends [`GCEntry`](#class-gcentry) and contains garbage collection data plus the flags associated with it (see https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_flags). - -#### `new GCAggregatedEntry()` - -The initialization doesn't require options. It is created internally by a [`GCMetric`](#class-gcmetric). - -#### `gcAggregatedEntry.flags` - -* `` - -This object contains the various hdr histograms of each flag. -#### `gcAggregatedEntry.flags.no` - -* [``](#class-gcentry) - -#### `gcAggregatedEntry.flags.constructRetained` - -* [``](#class-gcentry) - - -#### `gcAggregatedEntry.flags.forced` - -* [``](#class-gcentry) - - -#### `gcAggregatedEntry.flags.synchronousPhantomProcessing` - -* [``](#class-gcentry) - - -#### `gcAggregatedEntry.flags.allAvailableGarbage` - -* [``](#class-gcentry) - - -#### `gcAggregatedEntry.flags.allExternalMemory` - -* [``](#class-gcentry) - -#### `gcAggregatedEntry.flags.scheduleIdle` - -* [``](#class-gcentry) - -### `doc.eventLoopUtilizationSupported` - -* `` - -It tells if the Node.js version in use supports the [eventLoopUtilization metric](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2). - -### `doc.resourceUsageSupported` - -* `` - -It tells if the Node.js version in use supports the [resourceUsage metric](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_resourceusage). - -### `doc.gcFlagsSupported` - -* `` +See [here](https://dnlup.github.io/doc/#/?id=usage). -It tells if the Node.js version in use supports [GC flags](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_flags). +## Examples -### `doc.errors` +You can find more examples in the [`examples`](https://github.com/dnlup/doc/tree/HEAD/examples) folder. -In the `errors` object are exported all the custom errors used by the module. +## Contributing -| Error | Error Code | Description | -|-------|------------|-------------| -| `InvalidArgumentError` | `DOC_ERR_INVALID_ARG` | An invalid option or argument was used | -| `NotSupportedError` | `DOC_ERR_NOT_SUPPORTED` | A metric is not supported on the Node.js version used | +See [the contributing section](./CONTRIBUTING.md). ## License diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..735fa5a4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,124 @@ +# doc + +[![npm version](https://badge.fury.io/js/%40dnlup%2Fdoc.svg)](https://badge.fury.io/js/%40dnlup%2Fdoc) + +> Get usage and health data about your Node.js process. + +`doc` is a small module that helps you collect health metrics about your Node.js process. +It does that by using only the API available on Node itself (no native dependencies). +It doesn't have any ties with an APM platform, so you are free to use anything you want for that purpose. +Its API lets you access both computed and raw values, where possible. + +## Installation + +###### latest stable version + +```bash +npm i @dnlup/doc +``` + +###### latest development version + +```bash +npm i @dnlup/doc@next +``` + +## Usage + +You can import the module by using either CommonJS or ESM. + +By default `doc` returns a [`Sampler`](#class-docsampler) instance that collects metrics about cpu, memory usage, event loop delay and event loop utilization (only on Node versions that [support it](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2)). + +###### Importing with CommonJS + +```js +const doc = require('@dnlup/doc') + +const sampler = doc() // Use the default options + +sampler.on('sample', () => { + doStuffWithCpuUsage(sampler.cpu.usage) + doStuffWithMemoryUsage(sampler.memory) + doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) + doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it +}) +``` + +###### Importing with ESM + +```js +import doc from '@dnlup/doc' + +const sampler = doc() + +sampler.on('sample', () => { + doStuffWithCpuUsage(sampler.cpu.usage) + doStuffWithMemoryUsage(sampler.memory) + doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) + doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it +}) +``` + +###### Note + +A `Sampler` holds a snapshot of the metrics taken at the specified sample interval. +This behavior makes the instance stateful. On every tick, a new snapshot will overwrite the previous one. + +##### Enable/disable metrics collection + +You can disable the metrics that you don't need. + +```js +const doc = require('@dnlup/doc') + +// Collect only the event loop delay +const sampler = doc({ collect: { cpu: false, memory: false } }) + +sampler.on('sample', () => { + // `sampler.cpu` will be `undefined` + // `sampler.memory` will be `undefined` + doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) + doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it +}) +``` + +You can enable more metrics if you need them. + +##### Garbage collection + +```js +const doc = require('@dnlup/doc') + +const sampler = doc({ collect: { gc: true } }) +sampler.on('sample', () => { + doStuffWithCpuUsage(sampler.cpu.usage) + doStuffWithMemoryUsage(sampler.memory) + doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) + doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it + doStuffWithGarbageCollectionDuration(sampler.gc.pause) +}) +``` + +##### Active handles + +```js +const doc = require('@dnlup/doc') + +const sampler = doc({ collect: { activeHandles: true } }) + +sampler.on('sample', () => { + doStuffWithCpuUsage(sampler.cpu.usage) + doStuffWithMemoryUsage(sampler.memory) + doStuffWithEventLoopDelay(sampler.eventLoopDelay.computed) + doStuffWithEventLoopUtilization(sampler.eventLoopUtilization.utilization) // Available only on Node versions that support it + doStuffWithActiveHandles(sampler.activeHandles) +}) +``` + +### Examples + +You can find more examples in the [`examples`](https://github.com/dnlup/doc/tree/HEAD/examples) folder. + +## License + +[ISC](https://github.com/dnlup/doc/tree/HEAD/LICENSE) diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 00000000..f2ce297f --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,9 @@ +* [Home](/ "@dnlup/doc") +* API + * [doc](/api/doc.md) + * [Sampler](/api/sampler.md) + * [CPUMetric](/api/cpu.md) + * [EventLoopDelayMetric](/api/eventloopdelay.md) + * [EventLoopUtilizationMetric](/api/eventlooputilization.md) + * [GCMetric](/api/gc.md) + * [ResourceUsageMetric](/api/resourceusage.md) diff --git a/docs/api/cpu.md b/docs/api/cpu.md new file mode 100644 index 00000000..8167e433 --- /dev/null +++ b/docs/api/cpu.md @@ -0,0 +1,15 @@ +# Class: `CpuMetric` + +It exposes both computed and raw values of the cpu usage. + +## `cpuMetric.usage` + +* `` + +Cpu usage in percentage. + +## `cpuMetric.raw` + +* `` + +Raw value returned by [`process.cpuUsage()`](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_cpuusage_previousvalue). diff --git a/docs/api/doc.md b/docs/api/doc.md new file mode 100644 index 00000000..f5fec54c --- /dev/null +++ b/docs/api/doc.md @@ -0,0 +1,37 @@ +# `doc([options])` + +It creates a metrics [`Sampler`](#class-docsampler) instance with the given options. + +* `options` ``: same as the `Sampler` [`options`](/api/sampler.md#new-sampleroptions). +* Returns: [``](#class-docsampler) + +## `doc.Sampler` + +* [`Sampler`](/api/sampler.md) + +## `doc.eventLoopUtilizationSupported` + +* `` + +It tells if the Node.js version in use supports the [eventLoopUtilization metric](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2). + +## `doc.resourceUsageSupported` + +* `` + +It tells if the Node.js version in use supports the [resourceUsage metric](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_resourceusage). + +## `doc.gcFlagsSupported` + +* `` + +It tells if the Node.js version in use supports [GC flags](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_flags). + +## `doc.errors` + +In the `errors` object are exported all the custom errors used by the module. + +| Error | Error Code | Description | +|-------|------------|-------------| +| `InvalidArgumentError` | `DOC_ERR_INVALID_ARG` | An invalid option or argument was used | +| `NotSupportedError` | `DOC_ERR_NOT_SUPPORTED` | A metric is not supported on the Node.js version used | diff --git a/docs/api/eventloopdelay.md b/docs/api/eventloopdelay.md new file mode 100644 index 00000000..e14d2fee --- /dev/null +++ b/docs/api/eventloopdelay.md @@ -0,0 +1,23 @@ +# Class: `EventLoopDelayMetric` + +It exposes both computed and raw values about the event loop delay. + +## `eventLoopDelay.computed` + +* `` + +Event loop delay in milliseconds. On Node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v13.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options), it computes this value using the `mean` of the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. Otherwise, it uses a simple timer to calculate it. + +## `eventLoopDelay.raw` + +* [``](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) | `` + +On Node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options) this exposes the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. Otherwise, it exposes the raw delay value in nanoseconds. + +## `eventLoopDelay.compute(raw)` + +* `raw` `` The raw value obtained using the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) API. +* Returns `` The computed delay value. + +This function works only on node versions that support [`monitorEventLoopDelay`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options). It allows to get computed values of the event loop delay from statistics other than the `mean` of the [`Histogram`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_class_histogram) instance. + diff --git a/docs/api/eventlooputilization.md b/docs/api/eventlooputilization.md new file mode 100644 index 00000000..4c7163b0 --- /dev/null +++ b/docs/api/eventlooputilization.md @@ -0,0 +1,26 @@ +# Class: `EventLoopUtilizationMetric` + +It exposes statistics about the event loop utilization. + +#### `eventLoopUtilization.idle` + +* `` + +The `idle` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. + +## `eventLoopUtilization.active` + +* `` + +The `active` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. +## `eventLoopUtilization.utilization` + +* `` + +The `utilization` value in the object returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. + +## `eventLoopUtilization.raw` + +* `` + +Raw value returned by [`performance.eventLoopUtilization()`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) during the `sampleInterval` window. diff --git a/docs/api/gc.md b/docs/api/gc.md new file mode 100644 index 00000000..67230d83 --- /dev/null +++ b/docs/api/gc.md @@ -0,0 +1,150 @@ +# Class: `GCMetric` + +It exposes the garbage collector activity statistics in the specified `sampleInterval` using hdr histograms. + +## `new GCMetric(options)` + +* `options` ``: Configuration options + * `aggregate` ``: See `gcOptions.aggregate` in the [Sampler options](#new-docsampleroptions). + * `flags` ``: See `gcOptions.flags` in the [Sampler options](#new-docsampleroptions). + +## `gcMetric.pause` + +* [``](#class-gcentry) + +It tracks the global activity of the garbage collector. + +## `gcMetric.major` + +* [``](#class-gcentry) | [``](#class-gcaggregatedentry) + +The activity of the operation of type `major`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. + +See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). + +## `gcMetric.minor` + +* [``](#class-gcentry) | [``](#class-gcaggregatedentry) + +The activity of the operation of type `minor`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. + +See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). + +## `gcMetric.incremental` + +* [``](#class-gcentry) | [``](#class-gcaggregatedentry) + +The activity of the operation of type `incremental`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. + +See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). + +## `gcMetric.weakCb` + +* [``](#class-gcentry) | [``](#class-gcaggregatedentry) + +The activity of the operation of type `weakCb`. It's present only if `GCMetric` has been created with the option `aggregate` equal to `true`. + +See [`performanceEntry.kind`](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html#perf_hooks_performanceentry_kind). + +# Class: `GCEntry` + +It contains garbage collection data, represented with an [hdr histogram](https://github.com/HdrHistogram/HdrHistogramJS). All timing values are expressed in nanoseconds. + +## `new GCEntry()` + +The initialization doesn't require options. It is created internally by a [`GCMetric`](#class-gcmetric). + +## `gcEntry.totalDuration` + +* `` + +It is the total time of the entry in nanoseconds. + +## `gcEntry.totalCount` + +* `` + +It is the total number of operations counted. + +## `gcEntry.mean` + +* `` + +It is the mean value of the entry in nanoseconds. + +## `gcEntry.max` + +* `` + +It is the maximum value of the entry in nanoseconds. + +## `gcEntry.min` + +* `` + +It is the minimum value of the entry in nanoseconds. + +## `gcEntry.stdDeviation` + +* `` + +It is the standard deviation of the entry in nanoseconds. + +## `gcEntry.summary` + +* `` + +The hdr histogram summary. See https://github.com/HdrHistogram/HdrHistogramJS#record-values-and-retrieve-metrics. + +## `gcEntry.getPercentile(percentile)` + +* `percentile` ``: Get a percentile from the histogram. +* Returns `` The percentile + +See https://github.com/HdrHistogram/HdrHistogramJS#record-values-and-retrieve-metrics. + +# Class: `GCAggregatedEntry` + +It extends [`GCEntry`](#class-gcentry) and contains garbage collection data plus the flags associated with it (see https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_flags). + +## `new GCAggregatedEntry()` + +The initialization doesn't require options. It is created internally by a [`GCMetric`](#class-gcmetric). + +## `gcAggregatedEntry.flags` + +* `` + +This object contains the various hdr histograms of each flag. + +## `gcAggregatedEntry.flags.no` + +* [``](#class-gcentry) + +## `gcAggregatedEntry.flags.constructRetained` + +* [``](#class-gcentry) + + +## `gcAggregatedEntry.flags.forced` + +* [``](#class-gcentry) + + +## `gcAggregatedEntry.flags.synchronousPhantomProcessing` + +* [``](#class-gcentry) + + +## `gcAggregatedEntry.flags.allAvailableGarbage` + +* [``](#class-gcentry) + + +## `gcAggregatedEntry.flags.allExternalMemory` + +* [``](#class-gcentry) + +## `gcAggregatedEntry.flags.scheduleIdle` + +* [``](#class-gcentry) diff --git a/docs/api/resourceusage.md b/docs/api/resourceusage.md new file mode 100644 index 00000000..f877b495 --- /dev/null +++ b/docs/api/resourceusage.md @@ -0,0 +1,15 @@ +# Class: `ResourceUsageMetric` + +It exposes both computed and raw values of the process resource usage. + +## `resourceUsage.cpu` + +* `` + +Cpu usage in percentage. + +## `resourceUsage.raw` + +* `` + +Raw value returned by [`process.resourceUsage()`](https://nodejs.org/docs/latest-v12.x/api/process.html#process_process_resourceusage). diff --git a/docs/api/sampler.md b/docs/api/sampler.md new file mode 100644 index 00000000..63b77c86 --- /dev/null +++ b/docs/api/sampler.md @@ -0,0 +1,83 @@ +# Class: `Sampler` + +* Extends [`EventEmitter`](https://nodejs.org/dist/latest-v12.x/docs/api/events.html#events_class_eventemitter). + +Metrics sampler. + +It collects the selected metrics at a regular interval. A `Sampler` instance is stateful so, on each tick, +only the values of the last sample are available. Each time the sampler emits the [`sample`](#event-39sample39) event, it will overwrite the previous one. + +### new `Sampler([options])` + +* `options` `` + * `sampleInterval` ``: sample interval (ms) to get a sample. On each `sampleInterval` ms a [`sample`](#event-39sample39) event is emitted. **Default:** `500` on Node < 11.10.0, `1000` otherwise. Under the hood the package uses [`monitorEventLoopDelay`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options) when available to track the event loop delay and this allows to increase the default `sampleInterval`. + * `autoStart` ``: start automatically to collect metrics. **Default:** `true`. + * `unref` ``: [unref](https://nodejs.org/dist/latest-v12.x/docs/api/timers.html#timers_timeout_unref) the timer used to schedule the sampling interval. **Default:** `true`. + * `gcOptions` ``: Garbage collection options + * `aggregate` ``: Track and aggregate statistics about each garbage collection operation ([more info](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_kind)). **Default:** `false` + * `flags` ``: , Track statistics about the flags of each (aggregated) garbage collection operation ([more info](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performanceentry_flags)). `aggregate` has to be `true` to enable this option. **Default:** `true` on Node version `12.17.0` and newer. + * `eventLoopDelayOptions` ``: Options to setup [`monitorEventLoopDelay`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options). **Default:** `{ resolution: 10 }` + * `collect` ``: enable/disable the collection of specific metrics. + * `cpu` ``: enable cpu metric. **Default:** `true`. + * `resourceUsage` ``: enable [resourceUsage](https://nodejs.org/docs/latest-v12.x/api/process.html#process_process_resourceusage) metric. **Default:** `false`. + * `eventLoopDelay` ``: enable eventLoopDelay metric. **Default:** `true`. + * `eventLoopUtilization` ``: enable [eventLoopUtilization](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_performance_eventlooputilization_utilization1_utilization2) metric. **Default:** `true` on Node version `12.19.0` and newer. + * `memory` ``: enable memory metric. **Default:** `true`. + * `gc` ``: enable garbage collection metric. **Default:** `false`. + * `activeHandles` ``: enable active handles collection metric. **Default:** `false`. + +If `options.collect.resourceUsage` is set to `true`, `options.collect.cpu` will be set to false because the cpu metric is already available in the [`resource usage metric`](#samplerresourceusage). + +### Event: '`sample`' + +Emitted every `sampleInterval`, it signals that new data the sampler has collected new data. + +### `sampler.start()` + +Start collecting metrics. + +### `sampler.stop()` + +Stop collecting metrics. + +### `sampler.cpu` + +* [``](/api/cpu.md#class-cpumetric) + +Resource usage metric instance. + +### `sampler.resourceUsage` + +* [``](/api/resourceusage.md#class-resourceusagemetric) + +Resource usage metric instance. + +### `sampler.eventLoopDelay` + +* [``](/api/eventloopdelay.md#class-eventloopdelaymetric) + +Event loop delay metric instance. + +### `sampler.eventLoopUtilization` + +* [``](/api/eventlooputilization.md#class-eventlooputilizationmetric) + +Event loop utilization metric instance. + +### `sampler.gc` + +* [``](/api/gc.md#class-gcmetric) + +Garbage collector metric instance. + +### `sampler.activeHandles` + +* `` + +Number of active handles returned by `process._getActiveHandles()`. + +### `sampler.memory` + +* `` + +Object returned by [`process.memoryUsage()`](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_memoryusage). diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..0b6ac38e --- /dev/null +++ b/docs/index.html @@ -0,0 +1,26 @@ + + + + + @dnlup/doc + + + + + + +
+ + + + + diff --git a/package-lock.json b/package-lock.json index 760016de..7ce27fae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1128,6 +1128,18 @@ } } }, + "clipboard": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", + "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", + "dev": true, + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -1503,6 +1515,41 @@ "xdg-basedir": "^4.0.0" } }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "connect-livereload": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz", + "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", + "dev": true + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", @@ -2620,6 +2667,13 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "dev": true, + "optional": true + }, "deoptigate": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/deoptigate/-/deoptigate-0.5.0.tgz", @@ -2634,6 +2688,18 @@ "v8-tools-core": "~0.1.1" } }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, "detect-indent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", @@ -2673,6 +2739,216 @@ "path-type": "^4.0.0" } }, + "docsify": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.12.1.tgz", + "integrity": "sha512-7v4UlCYLTmb83leJLIlheQlQ8kDTbTxcpMttRg0Uf92Nl//m0AcKFHoLLo5HHS4UhnO0KhDV8SKCdTR279zI9A==", + "dev": true, + "requires": { + "dompurify": "^2.2.6", + "marked": "^1.2.9", + "medium-zoom": "^1.0.6", + "opencollective-postinstall": "^2.0.2", + "prismjs": "^1.23.0", + "strip-indent": "^3.0.0", + "tinydate": "^1.3.0", + "tweezer.js": "^1.4.0" + } + }, + "docsify-cli": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/docsify-cli/-/docsify-cli-4.4.3.tgz", + "integrity": "sha512-oI/cD04b+hklNd9yKiN9p9EqGx9UKL6p4D0J3fS9L5fpwOti1F8p2rshGJTyArxUlw6EeEBtaJd4rzPzBkK+Lw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "connect": "^3.6.0", + "connect-livereload": "^0.6.0", + "cp-file": "^7.0.0", + "docsify": "^4.12.1", + "docsify-server-renderer": ">=4.10.0", + "enquirer": "^2.3.6", + "fs-extra": "^8.1.0", + "get-port": "^5.0.0", + "livereload": "^0.9.1", + "lru-cache": "^5.1.1", + "open": "^6.4.0", + "serve-static": "^1.12.1", + "update-notifier": "^4.1.0", + "yargonaut": "^1.1.2", + "yargs": "^14.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "cp-file": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", + "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "nested-error-stacks": "^2.0.0", + "p-event": "^4.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "docsify-server-renderer": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/docsify-server-renderer/-/docsify-server-renderer-4.12.1.tgz", + "integrity": "sha512-IYakkc+UxPS89N/Mq8MF4SKTQ1gtxN5nDEFAnJPf5TvQO+1fuxszHgv/hMprG5z/ms7PJb1w4nMykUfRW36+/A==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "docsify": "^4.12.0", + "dompurify": "^2.2.6", + "node-fetch": "^2.6.0", + "resolve-pathname": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2682,6 +2958,12 @@ "esutils": "^2.0.2" } }, + "dompurify": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.7.tgz", + "integrity": "sha512-jdtDffdGNY+C76jvodNTu9jt5yYj59vuTUyx+wXdzcSwAGTYZDAQkQ7Iwx9zcGrA4ixC1syU4H3RZROqRxokxg==", + "dev": true + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -2761,12 +3043,24 @@ "safer-buffer": "^2.1.0" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -2842,6 +3136,12 @@ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "dev": true }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -3529,6 +3829,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "events-to-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", @@ -3681,6 +3987,12 @@ "reusify": "^1.0.4" } }, + "figlet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", + "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", + "dev": true + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -3725,6 +4037,38 @@ "to-regex-range": "^5.0.1" } }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -3911,6 +4255,12 @@ "mime-types": "^2.1.12" } }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, "fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", @@ -3926,6 +4276,17 @@ "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4146,6 +4507,12 @@ } } }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -4652,6 +5019,16 @@ } } }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "dev": true, + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -4745,6 +5122,23 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-async-hooks": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-async-hooks/-/has-async-hooks-1.0.0.tgz", @@ -4812,6 +5206,19 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, "http-parser-js": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", @@ -5412,6 +5819,15 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -5616,6 +6032,49 @@ } } }, + "livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "requires": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + }, + "dependencies": { + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } + } + }, + "livereload-js": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.2.tgz", + "integrity": "sha512-w677WnINxFkuixAoUEXOStewzLYGI76XVag+0JWMMEyjJQKs0ibWZMxkTlB96Lm3EjZ7IeOxVziBEbtxVQqQZA==", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5823,12 +6282,24 @@ "strip-color": "^0.1.0" } }, + "marked": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz", + "integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==", + "dev": true + }, "math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, + "medium-zoom": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.6.tgz", + "integrity": "sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg==", + "dev": true + }, "meow": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", @@ -5940,6 +6411,12 @@ "picomatch": "^2.0.5" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", @@ -6096,6 +6573,12 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + }, "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", @@ -6351,6 +6834,15 @@ "has": "^1.0.3" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, "on-net-listen": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/on-net-listen/-/on-net-listen-1.1.2.tgz", @@ -6375,6 +6867,21 @@ "mimic-fn": "^2.1.0" } }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true + }, "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -6404,6 +6911,12 @@ "word-wrap": "^1.2.3" } }, + "opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -6431,6 +6944,21 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", @@ -6458,6 +6986,15 @@ "aggregate-error": "^3.0.0" } }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -6518,6 +7055,12 @@ } } }, + "parent-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", + "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", + "dev": true + }, "parse-github-repo-url": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", @@ -6534,6 +7077,12 @@ "json-parse-better-errors": "^1.0.1" } }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6642,6 +7191,15 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, + "prismjs": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", + "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", + "dev": true, + "requires": { + "clipboard": "^2.0.0" + } + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -6757,6 +7315,12 @@ } } }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -7074,6 +7638,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, "responselike": { "version": "1.0.2", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/responselike/-/responselike-1.0.2.tgz", @@ -7141,6 +7711,13 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "dev": true, + "optional": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -7190,6 +7767,64 @@ } } }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -7205,6 +7840,12 @@ "to-object-path": "^0.3.0" } }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -7523,6 +8164,12 @@ } } }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -9036,6 +9683,19 @@ "integrity": "sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==", "dev": true }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true, + "optional": true + }, + "tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -9077,6 +9737,12 @@ "is-number": "^7.0.0" } }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, "toml": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", @@ -9248,6 +9914,12 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "tweezer.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", + "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9327,6 +9999,18 @@ "crypto-random-string": "^2.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", @@ -9399,6 +10083,12 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -9532,6 +10222,12 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", + "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", + "dev": true + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -9568,6 +10264,65 @@ "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true }, + "yargonaut": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", + "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "figlet": "^1.1.1", + "parent-require": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", diff --git a/package.json b/package.json index 8c488e3f..4623b65d 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "autocannon": "^7.0.0", "concurrently": "^6.0.0", "deoptigate": "^0.5.0", + "docsify-cli": "^4.4.3", "eslint": "^7.9.0", "eslint-config-standard": "^16.0.0", "eslint-plugin-import": "^2.22.0",