From 5bf562442e616651f2d9e358bf4ec6778d2aef85 Mon Sep 17 00:00:00 2001 From: chad Date: Thu, 12 Jan 2023 19:44:25 -0500 Subject: [PATCH 01/12] docs: added aegir doc-check command to compile Typescript in documentation (#1128) --- .github/workflows/main.yml | 1 + .gitignore | 3 +++ doc/tsconfig.json | 17 +++++++++++++++++ package.json | 3 ++- 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 doc/tsconfig.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 85e4c003c8..0514a04eba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,6 +19,7 @@ jobs: - uses: ipfs/aegir/actions/cache-node-modules@master - run: npm run --if-present lint - run: npm run --if-present dep-check + - run: npm run --if-present doc-check test-node: needs: check diff --git a/.gitignore b/.gitignore index 1531bdf9de..4b0879218d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ dist .coverage package-lock.json yarn.lock + +# IDE +.DS_STORE diff --git a/doc/tsconfig.json b/doc/tsconfig.json new file mode 100644 index 0000000000..a2bbf9bb2f --- /dev/null +++ b/doc/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + /* Language and Environment */ + "target": "ES2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + /* Modules */ + "module": "ESNext" /* Specify what module code is generated. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + /* Completeness */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */, + "noImplicitAny": false, + "isolatedModules": false + } +} diff --git a/package.json b/package.json index e1bc116d88..2c93a23ff7 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "clean": "aegir clean", "lint": "aegir lint", "dep-check": "aegir dep-check", + "doc-check": "aegir doc-check --inputFiles doc/*.md --tsConfigPath doc/", "prepublishOnly": "node scripts/update-version.js", "build": "aegir build", "docs": "aegir docs", @@ -187,7 +188,7 @@ "@types/p-fifo": "^1.0.0", "@types/varint": "^6.0.0", "@types/xsalsa20": "^1.1.0", - "aegir": "^37.5.6", + "aegir": "^38.1.0", "cborg": "^1.8.1", "delay": "^5.0.0", "execa": "^6.1.0", From a35195443b44d61d680c0ada4a337974347f4617 Mon Sep 17 00:00:00 2001 From: chad Date: Thu, 12 Jan 2023 20:10:58 -0500 Subject: [PATCH 02/12] doc: updated limits doc according to ts doc verifier errors (wip) --- doc/LIMITS.md | 141 ++++++++++++++++++++++++++-------------------- doc/tsconfig.json | 4 +- 2 files changed, 83 insertions(+), 62 deletions(-) diff --git a/doc/LIMITS.md b/doc/LIMITS.md index 6173b413a7..c08a039912 100644 --- a/doc/LIMITS.md +++ b/doc/LIMITS.md @@ -23,7 +23,7 @@ This is important for [DoS](https://en.wikipedia.org/wiki/Denial-of-service_atta It's possible to limit the total amount of connections a node is able to make (combining incoming and outgoing). When this limit is reached and an attempt to open a new connection is made, existing connections may be closed to make room for the new connection (see [Closing connections][#closing-connections]). -* Note: there currently isn't a way to specify different limits for incoming vs. outgoing. Connection limits are applied across both incoming and outgoing connections combined. There is a backlog item for this [here](https://github.com/libp2p/js-libp2p/issues/1508). +- Note: there currently isn't a way to specify different limits for incoming vs. outgoing. Connection limits are applied across both incoming and outgoing connections combined. There is a backlog item for this [here](https://github.com/libp2p/js-libp2p/issues/1508). We can also limit the number of connections in a "pending" state. These connections have been opened by a remote peer but peer IDs have yet to be exchanged and/or connection encryption and multiplexing negotiated. Once this limit is hit further connections will be closed unless the remote peer has an address in the [allow list](#allowdeny-lists). @@ -35,32 +35,36 @@ const node = await createLibp2pNode({ /** * The total number of connections allowed to be open at one time */ - maxConnections: number + maxConnections: number, /** * If the number of open connections goes below this number, the node * will try to connect to randomly selected peers from the peer store */ - minConnections: number + minConnections: number, /** * How many connections can be open but not yet upgraded */ - maxIncomingPendingConnections: number - } -}) + maxIncomingPendingConnections: number, + }, +}); + +export {}; ``` ## Closing connections When choosing connections to close the connection manager sorts the list of connections by the value derived from the tags given to each peer. The values of all tags are summed and connections with lower valued peers are eligible for closing first. If there are tags with equal values, the shortest-lived connection will be closed first. -```js +```ts // tag a peer -await libp2p.peerStore.tagPeer(peerId, 'my-tag', { +await libp2p.peerStore.tagPeer(peerId, "my-tag", { value: 50, // 0-100 is the typical value range - ttl: 1000 // optional field, this tag will be deleted after this many ms -}) + ttl: 1000, // optional field, this tag will be deleted after this many ms +}); + +export {}; ``` ## Inbound connection threshold @@ -76,9 +80,11 @@ const node = await createLibp2pNode({ * A remote peer may attempt to open up to this many connections per second, * any more than that will be automatically rejected */ - inboundConnectionThreshold: number - } -}) + inboundConnectionThreshold: number, + }, +}); + +export {}; ``` ## Data transfer and Event Loop limits @@ -92,7 +98,7 @@ All fields are optional. The default values are defined in [src/connection-manag ```ts const node = await createLibp2pNode({ metrics: { - enabled: true + enabled: true, }, connectionManager: { /** @@ -102,7 +108,7 @@ const node = await createLibp2pNode({ * * It is bytes per second. */ - maxData: number + maxData: number, /** * If the node sends more than this amount of data in bytes/second @@ -111,7 +117,7 @@ const node = await createLibp2pNode({ * * It is bytes per second. */ - maxSentData: number + maxSentData: number, /** * If the node receives more than this amount of data in bytes/second @@ -120,7 +126,7 @@ const node = await createLibp2pNode({ * * It is bytes per second. */ - maxReceivedData: number + maxReceivedData: number, /** * If the event loop takes longer than this many ms to run, connections @@ -128,9 +134,10 @@ const node = await createLibp2pNode({ * * It is milliseconds. */ - maxEventLoopDelay: number - } -}) + maxEventLoopDelay: number, + }, +}); +export {}; ``` ## Stream limits @@ -152,31 +159,32 @@ const node = await createLibp2pNode({ /** * The total number of inbound protocol streams that can be opened on a given connection */ - maxInboundStreams: number + maxInboundStreams: number, /** * The total number of outbound protocol streams that can be opened on a given connection */ - maxOutboundStreams: number + maxOutboundStreams: number, /** * How much incoming data in bytes to buffer while attempting to parse messages - peers sending many small messages in batches may cause this buffer to grow */ - maxUnprocessedMessageQueueSize: number + maxUnprocessedMessageQueueSize: number, /** * How much message data in bytes to buffer after parsing - slow stream consumers may cause this buffer to grow */ - maxStreamBufferSize: number + maxStreamBufferSize: number, /** * Mplex does not support backpressure so to protect ourselves, if `maxInboundStreams` is * hit and the remote opens more than this many streams per second, close the connection */ - disconnectThreshold: number - }) - ] -}) + disconnectThreshold: number, + }), + ], +}); +export {}; ``` ### Yamux @@ -194,17 +202,19 @@ const node = await createLibp2pNode({ * * This field is optional, the default value is shown */ - maxInboundStreams: number + maxInboundStreams: number, /** * The total number of outbound protocol streams that can be opened on a given connection * * This field is optional, the default value is shown */ - maxOutboundStreams: number - }) - ] -}) + maxOutboundStreams: number, + }), + ], +}); + +export {}; ``` ### Protocol limits @@ -218,12 +228,19 @@ Since incoming stream data is buffered until it is consumed, you should attempt All fields are optional. The default values are defined in [src/registrar.ts](https://github.com/libp2p/js-libp2p/blob/master/src/registrar.ts) - please see that file for the current values. ```ts -libp2p.handle('/my-protocol/1.0.0', (streamData) => { - // ..handle stream -}, { - maxInboundStreams: number - maxOutboundStreams: number -}) +const node = await createLibp2pNode({}); + +node.handle( + "/my-protocol/1.0.0", + (streamData) => { + // ..handle stream + }, + { + maxInboundStreams: number, + maxOutboundStreams: number, + } +); +export {}; ``` ## Transport specific limits @@ -245,29 +262,31 @@ const node = await createLibp2pNode({ /** * Inbound connections with no activity in this time frame (ms) will be closed */ - inboundSocketInactivityTimeout: number + inboundSocketInactivityTimeout: number, /** * Outbound connections with no activity in this time frame (ms) will be closed */ - outboundSocketInactivityTimeout: number + outboundSocketInactivityTimeout: number, /** * Once this many connections are open on this listener any further connections * will be rejected - this will have no effect if it is larger than the value * configured for the ConnectionManager maxConnections parameter */ - maxConnections: number - }) - ] -}) + maxConnections: number, + }), + ], +}); + +export {}; ``` ## Allow/deny lists It is possible to configure some hosts to always accept connections from and some to always reject connections from. -```js +```ts const node = await createLibp2pNode({ connectionManager: { /** @@ -276,9 +295,9 @@ const node = await createLibp2pNode({ * all connection limits */ allow: [ - '/ip4/43.123.5.23/tcp/3984', - '/ip4/234.243.64.2', - '/ip4/52.55', + "/ip4/43.123.5.23/tcp/3984", + "/ip4/234.243.64.2", + "/ip4/52.55", // etc ], @@ -286,14 +305,16 @@ const node = await createLibp2pNode({ * Any connection with a `remoteAddress` property that has any of these * addresses as a prefix will be immediately rejected */ - deny: [ - '/ip4/132.14.52.64/tcp/3984', - '/ip4/234.243.64.2', - '/ip4/34.42', + deny: [ + "/ip4/132.14.52.64/tcp/3984", + "/ip4/234.243.64.2", + "/ip4/34.42", // etc - ] - } -}) + ], + }, +}); + +export {}; ``` ## How much memory will be used for buffering? @@ -302,10 +323,10 @@ There is no a single config value to control the amount of memory js-libp2p uses Important details for ascertaining this are: -* Each connection has a multiplexer -* Each multiplexer has a buffer for raw incoming data (`muxer.maxUnprocessedMessageQueueSize`) -* The incoming data is parsed into messages for each stream and queued (`muxer.maxStreamBufferSize`) -* Each multiplexer has a stream limit for number of streams (`muxer.maxInboundStreams`, `muxer.maxOutboundStreams`). +- Each connection has a multiplexer +- Each multiplexer has a buffer for raw incoming data (`muxer.maxUnprocessedMessageQueueSize`) +- The incoming data is parsed into messages for each stream and queued (`muxer.maxStreamBufferSize`) +- Each multiplexer has a stream limit for number of streams (`muxer.maxInboundStreams`, `muxer.maxOutboundStreams`). As a result, the max amount of memory buffered by libp2p is approximately: diff --git a/doc/tsconfig.json b/doc/tsconfig.json index a2bbf9bb2f..bb2d226e32 100644 --- a/doc/tsconfig.json +++ b/doc/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { /* Language and Environment */ - "target": "ES2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, /* Modules */ - "module": "ESNext" /* Specify what module code is generated. */, + "module": "esnext" /* Specify what module code is generated. */, "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, From 0ad13234cbc9ab18050d4f1577639aa45fb0917e Mon Sep 17 00:00:00 2001 From: chad Date: Fri, 21 Apr 2023 13:14:00 -0500 Subject: [PATCH 03/12] docs: updated linting for ts on docs (#1228) --- doc/LIMITS.md | 90 +++++++++++++++--------- doc/METRICS.md | 176 +--------------------------------------------- doc/tsconfig.json | 4 +- 3 files changed, 60 insertions(+), 210 deletions(-) diff --git a/doc/LIMITS.md b/doc/LIMITS.md index d826a1e95d..2f910c0bf3 100644 --- a/doc/LIMITS.md +++ b/doc/LIMITS.md @@ -29,27 +29,28 @@ We can also limit the number of connections in a "pending" state. These connecti All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values. ```ts -const node = await createLibp2pNode({ +import { createLibp2p } from 'libp2p' + +const node = await createLibp2p({ connectionManager: { /** * The total number of connections allowed to be open at one time */ - maxConnections: number, + maxConnections: 100, /** * If the number of open connections goes below this number, the node * will try to connect to randomly selected peers from the peer store */ - minConnections: number, + minConnections: 50, /** * How many connections can be open but not yet upgraded */ - maxIncomingPendingConnections: number, + maxIncomingPendingConnections: 100, }, }); -export {}; ``` ## Closing connections @@ -57,13 +58,21 @@ export {}; When choosing connections to close the connection manager sorts the list of connections by the value derived from the tags given to each peer. The values of all tags are summed and connections with lower valued peers are eligible for closing first. If there are tags with equal values, the shortest-lived connection will be closed first. ```ts +import { createLibp2p } from 'libp2p' +import { createEd25519PeerId } from '@libp2p/peer-id-factory' + + +const libp2p = await createLibp2p({}) + +const peerId = await createEd25519PeerId() + // tag a peer await libp2p.peerStore.tagPeer(peerId, "my-tag", { value: 50, // 0-100 is the typical value range ttl: 1000, // optional field, this tag will be deleted after this many ms }); -export {}; + ``` ## Inbound connection threshold @@ -73,17 +82,19 @@ To prevent individual peers from opening multiple connections to a node, an `inb All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values. ```ts -const node = await createLibp2pNode({ +import { createLibp2p } from 'libp2p' + +const node = await createLibp2p({ connectionManager: { /** * A remote peer may attempt to open up to this many connections per second, * any more than that will be automatically rejected */ - inboundConnectionThreshold: number, + inboundConnectionThreshold: 100, }, }); -export {}; + ``` ## Stream limits @@ -99,38 +110,41 @@ These settings are done on a per-muxer basis, please see the README of the relev All fields are optional. The default values are defined in [@libp2p/mplex/src/mplex.ts](https://github.com/libp2p/js-libp2p-mplex/blob/master/src/mplex.ts) - please see that file for the current values. ```ts -const node = await createLibp2pNode({ - muxers: [ +import { createLibp2p } from 'libp2p' +import { mplex } from '@libp2p/mplex' + +const node = await createLibp2p({ + streamMuxers: [ mplex({ /** * The total number of inbound protocol streams that can be opened on a given connection */ - maxInboundStreams: number, + maxInboundStreams: 100, /** * The total number of outbound protocol streams that can be opened on a given connection */ - maxOutboundStreams: number, + maxOutboundStreams: 100, /** * How much incoming data in bytes to buffer while attempting to parse messages - peers sending many small messages in batches may cause this buffer to grow */ - maxUnprocessedMessageQueueSize: number, + maxUnprocessedMessageQueueSize: 50, /** * How much message data in bytes to buffer after parsing - slow stream consumers may cause this buffer to grow */ - maxStreamBufferSize: number, + maxStreamBufferSize: 20, /** * Mplex does not support backpressure so to protect ourselves, if `maxInboundStreams` is * hit and the remote opens more than this many streams per second, close the connection */ - disconnectThreshold: number, + disconnectThreshold: 20, }), ], }); -export {}; + ``` ### Yamux @@ -140,27 +154,30 @@ export {}; All fields are optional. The default values are defined in [@chainsafe/libp2p-yamux/src/config.ts](https://github.com/ChainSafe/js-libp2p-yamux/blob/master/src/config.ts) - please see that file for the current values. ```ts -const node = await createLibp2pNode({ - muxers: [ +import { createLibp2p } from 'libp2p' +import { yamux } from '@chainsafe/libp2p-yamux' + +const node = await createLibp2p({ + streamMuxers: [ yamux({ /** * The total number of inbound protocol streams that can be opened on a given connection * * This field is optional, the default value is shown */ - maxInboundStreams: number, + maxInboundStreams: 100, /** * The total number of outbound protocol streams that can be opened on a given connection * * This field is optional, the default value is shown */ - maxOutboundStreams: number, + maxOutboundStreams: 100, }), ], }); -export {}; + ``` ### Protocol limits @@ -174,7 +191,9 @@ Since incoming stream data is buffered until it is consumed, you should attempt All fields are optional. The default values are defined in [src/registrar.ts](https://github.com/libp2p/js-libp2p/blob/master/src/registrar.ts) - please see that file for the current values. ```ts -const node = await createLibp2pNode({}); +import { createLibp2p } from "libp2p"; + +const node = await createLibp2p({}); node.handle( "/my-protocol/1.0.0", @@ -182,11 +201,11 @@ node.handle( // ..handle stream }, { - maxInboundStreams: number, - maxOutboundStreams: number, + maxInboundStreams: 100, + maxOutboundStreams: 100, } ); -export {}; + ``` ## Transport specific limits @@ -202,30 +221,33 @@ The [@libp2p/tcp](https://github.com/libp2p/js-libp2p-tcp) transport allows addi All fields are optional. The full list of options is defined in [@libp2p/tcp/src/index.ts](https://github.com/libp2p/js-libp2p-tcp/blob/master/src/index.ts) - please see that file for more details. ```ts -const node = await createLibp2pNode({ +import { createLibp2p } from 'libp2p' +import {tcp } from '@libp2p/tcp' + +const node = await createLibp2p({ transports: [ tcp({ /** * Inbound connections with no activity in this time frame (ms) will be closed */ - inboundSocketInactivityTimeout: number, + inboundSocketInactivityTimeout: 20, /** * Outbound connections with no activity in this time frame (ms) will be closed */ - outboundSocketInactivityTimeout: number, + outboundSocketInactivityTimeout: 20, /** * Once this many connections are open on this listener any further connections * will be rejected - this will have no effect if it is larger than the value * configured for the ConnectionManager maxConnections parameter */ - maxConnections: number, + maxConnections: 50, }), ], }); -export {}; + ``` ## Allow/deny lists @@ -233,7 +255,9 @@ export {}; It is possible to configure some hosts to always accept connections from and some to always reject connections from. ```ts -const node = await createLibp2pNode({ +import { createLibp2p } from 'libp2p' + +const node = await createLibp2p({ connectionManager: { /** * A list of multiaddrs, any connection with a `remoteAddress` property @@ -260,7 +284,7 @@ const node = await createLibp2pNode({ }, }); -export {}; + ``` ## How much memory will be used for buffering? diff --git a/doc/METRICS.md b/doc/METRICS.md index 72ea0785bd..5e1ce88299 100644 --- a/doc/METRICS.md +++ b/doc/METRICS.md @@ -1,177 +1,3 @@ # Libp2p Metrics -Metrics allow you to gather run time statistics on your libp2p node. - -## Table of Contents - -- [Overview](#overview) -- [Tracking](#tracking) - - [Enable metrics](#enable-metrics) - - [Stream Metrics](#stream-metrics) - - [Component Metrics](#component-metrics) -- [Extracting metrics](#extracting-metrics) - -## Overview - -- Metrics gathering is optional, as there is a performance hit to using it -- See the [API](./API.md) for Metrics usage. Metrics in libp2p do not emit events, as such applications wishing to read Metrics will need to do so actively. This ensures that the system is not unnecessarily firing update notifications. -- For large installations you may wish to combine the statistics with a visualizer such as [Graphana](https://grafana.com/) - -There are two types of metrics [`StreamMetrics`](https://github.com/libp2p/js-libp2p-interfaces/blob/master/packages/interface-metrics/src/index.ts#L66-L115) and [`ComponentMetrics`](https://github.com/libp2p/js-libp2p-interfaces/blob/master/packages/interface-metrics/src/index.ts#L183-L193). `StreamMetrics` track data in and out of streams, `ComponentMetrics` allow system components to record metrics that are of interest to the observer. - -Although designed to primarily integrate with tools such as [Prometheus](https://prometheus.io/) it does not introduce any dependencies that require you to use any particular tool to store or graph metrics. - -## Tracking - -- When a transport hands off a connection for upgrading, Metrics are hooked up if enabled. -- When a stream is created, Metrics will be tracked on that stream and associated to that streams protocol. -- Tracked Metrics are associated to a specific peer, and count towards global bandwidth Metrics. - -### Enable metrics - -First enable metrics tracking by supplying a [Metrics](https://www.npmjs.com/package/@libp2p/interface-metrics) implementation: - -```js -import { createLibp2pNode } from 'libp2p' -import { prometheusMetrics } from '@libp2p/prometheus-metrics' - -const node = await createLibp2pNode({ - metrics: prometheusMetrics() - //... other config -}) -``` - -### Stream Metrics - -- The main Metrics object consists of individual `Stats` objects -- The following categories are tracked: - - Global stats; every byte in and out - - Peer stats; every byte in and out, per peer - - Protocol stats; every byte in and out, per protocol -- When a message goes through Metrics: - - It is added to the global stat - - It is added to the stats for the remote peer - - It is added to the protocol stats if there is one -- When data is pushed onto a `Stat` it is added to a queue - - The queue is processed at the earliest of either (configurable): - - every 2 seconds after the last item was added to the queue - - or once 1000 items have been queued - - When the queue is processed: - - The data length is added to either the `in` or `out` stat - - The moving averages is calculated since the last queue processing (based on most recently processed item timestamp) - -### Component Metrics - -To define component metrics first get a reference to the metrics object: - -```ts -import type { Metrics } from '@libp2p/interface-metrics' - -interface MyClassComponents { - metrics: Metrics -} - -class MyClass { - private readonly components: MyClassComponents - - constructor (components: MyClassComponents) { - this.components = components - } - - myMethod () { - // here we will set metrics - } -} -``` - -A tracked metric can be created by calling either `registerMetric` on the metrics object: - -```ts -const metric = metrics.registerMetric('my_metric', { - // an optional label - label: 'label', - // optional help text - help: 'help' -}) - -// set a value -metric.update(5) - -// increment by one, optionally pass a number to increment by -metric.increment() - -// decrement by one, optionally pass a number to increment by -metric.decrement() - -// reset to the default value -metric.reset() - -// use the metric to time something -const stopTimer = metric.timer() -// later -stopTimer() -``` - -A metric that is expensive to calculate can be created by passing a `calculate` function that will only be invoked when metrics are being scraped: - -```ts -metrics.registerMetric('my_metric', { - async calculate () { - return 5 - } -}) -``` - -If several metrics should be grouped together (e.g. for graphing purposes) `registerMetricGroup` can be used instead: - -```ts -const metric = metrics.registerMetricGroup('my_metric', { - // an optional label - label: 'label', - // optional help text - help: 'help' -}) - -metric.update({ - key1: 1, - key2: 1 -}) - -// increment one or more keys in the group -metric.increment({ - key1: true -}) - -// increment one or more keys by passed value -metric.increment({ - key1: 5 -}) - -// reset to the default value -metric.reset() - -// use the metric to time something as one of the keys -const stopTimer = metric.timer('key1') -// later -stopTimer() -``` - -## Extracting metrics - -Metrics implementations will allow extracting the values for presentation in an external system. For example here is how to use the metrics implementation from `@libp2p/prometheus-metrics` to enable scraping stats to display in [Prometheus](https://prometheus.io/) or a [Graphana](https://grafana.com/) dashboard: - -```ts -import { prometheusMetrics } from '@libp2p/prometheus-metrics' -import client from 'prom-client' - -const libp2p = createLibp2pNode({ - metrics: prometheusMetrics() - //... other config -}) - -// A handler invoked by express/hapi or your http framework of choice -export default async function metricsEndpoint (req, res) { - // prom-client metrics are global so extract them from the client - res.send(await client.register.metrics()) -} -``` +The documentation here has moved to https://libp2p.github.io/js-libp2p-prometheus-metrics/ - please update your bookmarks! \ No newline at end of file diff --git a/doc/tsconfig.json b/doc/tsconfig.json index bb2d226e32..359f5d14ec 100644 --- a/doc/tsconfig.json +++ b/doc/tsconfig.json @@ -11,7 +11,7 @@ "strict": true /* Enable all strict type-checking options. */, /* Completeness */ "skipLibCheck": true /* Skip type checking all .d.ts files. */, - "noImplicitAny": false, - "isolatedModules": false + "noImplicitAny": true, + "isolatedModules": true } } From 8a4b3099c45308b3b1cf313d74ea1d499900f046 Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 3 May 2023 11:44:40 -0500 Subject: [PATCH 04/12] docs: update metrics documentation (#1228) --- doc/METRICS.md | 195 ++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/doc/METRICS.md b/doc/METRICS.md index d43789816f..93764e08ed 100644 --- a/doc/METRICS.md +++ b/doc/METRICS.md @@ -1,3 +1,196 @@ # Libp2p Metrics -The documentation here has moved to https://libp2p.github.io/js-libp2p-prometheus-metrics/ - please update your bookmarks! +Metrics allow you to gather run time statistics on your libp2p node. +## Table of Contents + +- [Overview](#overview) +- [Tracking](#tracking) + - [Enable metrics](#enable-metrics) + - [Stream Metrics](#stream-metrics) + - [Component Metrics](#component-metrics) +- [Extracting metrics](#extracting-metrics) + +## Overview + +- Metrics gathering is optional, as there is a performance hit to using it +- See the [API](./API.md) for Metrics usage. Metrics in libp2p do not emit events, as such applications wishing to read Metrics will need to do so actively. This ensures that the system is not unnecessarily firing update notifications. +- For large installations you may wish to combine the statistics with a visualizer such as [Graphana](https://grafana.com/) + +There are two types of metrics [`StreamMetrics`](https://github.com/libp2p/js-libp2p-interfaces/blob/master/packages/interface-metrics/src/index.ts#L66-L115) and [`ComponentMetrics`](https://github.com/libp2p/js-libp2p-interfaces/blob/master/packages/interface-metrics/src/index.ts#L183-L193). `StreamMetrics` track data in and out of streams, `ComponentMetrics` allow system components to record metrics that are of interest to the observer. + +Although designed to primarily integrate with tools such as [Prometheus](https://prometheus.io/) it does not introduce any dependencies that require you to use any particular tool to store or graph metrics. + +## Tracking + +- When a transport hands off a connection for upgrading, Metrics are hooked up if enabled. +- When a stream is created, Metrics will be tracked on that stream and associated to that streams protocol. +- Tracked Metrics are associated to a specific peer, and count towards global bandwidth Metrics. + +### Enable metrics + +First enable metrics tracking by supplying a [Metrics](https://www.npmjs.com/package/@libp2p/interface-metrics) implementation: + +```ts +import { createLibp2p } from 'libp2p' +import { prometheusMetrics } from '@libp2p/prometheus-metrics' + +const node = await createLibp2p({ + metrics: prometheusMetrics() + //... other config +}) +``` + +### Stream Metrics + +- The main Metrics object consists of individual `Stats` objects +- The following categories are tracked: + - Global stats; every byte in and out + - Peer stats; every byte in and out, per peer + - Protocol stats; every byte in and out, per protocol +- When a message goes through Metrics: + - It is added to the global stat + - It is added to the stats for the remote peer + - It is added to the protocol stats if there is one +- When data is pushed onto a `Stat` it is added to a queue + - The queue is processed at the earliest of either (configurable): + - every 2 seconds after the last item was added to the queue + - or once 1000 items have been queued + - When the queue is processed: + - The data length is added to either the `in` or `out` stat + - The moving averages is calculated since the last queue processing (based on most recently processed item timestamp) + +### Component Metrics + +To define component metrics first get a reference to the metrics object: + +```ts +import type { Metrics } from '@libp2p/interface-metrics' + +interface MyClassComponents { + metrics: Metrics +} + +class MyClass { + private readonly components: MyClassComponents + + constructor (components: MyClassComponents) { + this.components = components + } + + myMethod () { + // here we will set metrics + } +} +``` + +A tracked metric can be created by calling either `registerMetric` on the metrics object: + +```ts +import type { Metrics } from '@libp2p/interface-metrics' +import { prometheusMetrics } from '@libp2p/prometheus-metrics' + +const metrics: Metrics = prometheusMetrics()() + +const metric = metrics.registerMetric('my_metric', { + // an optional label + label: 'label', + // optional help text + help: 'help' +}) + +// set a value +metric.update(5) + +// increment by one, optionally pass a number to increment by +metric.increment() + +// decrement by one, optionally pass a number to increment by +metric.decrement() + +// reset to the default value +metric.reset() + +// use the metric to time something +const stopTimer = metric.timer() +// later +stopTimer() +``` + +A metric that is expensive to calculate can be created by passing a `calculate` function that will only be invoked when metrics are being scraped: + +```ts +import type { Metrics } from '@libp2p/interface-metrics' +import { prometheusMetrics } from '@libp2p/prometheus-metrics' + +const metrics: Metrics = prometheusMetrics()() + +metrics.registerMetric('my_metric', { + async calculate () { + return 5 + } +}) +``` + +If several metrics should be grouped together (e.g. for graphing purposes) `registerMetricGroup` can be used instead: + +```ts +import type { Metrics } from '@libp2p/interface-metrics' +import { prometheusMetrics } from '@libp2p/prometheus-metrics' + +const metrics: Metrics = prometheusMetrics()() + +const metric = metrics.registerMetricGroup('my_metric', { + // an optional label + label: 'label', + // optional help text + help: 'help' +}) + +metric.update({ + key1: 1, + key2: 1 +}) + +// increment one or more keys in the group +metric.increment({ + key1: true +}) + +// increment one or more keys by passed value +metric.increment({ + key1: 5 +}) + +// reset to the default value +metric.reset() + +// use the metric to time something as one of the keys +const stopTimer = metric.timer('key1') +// later +stopTimer() +``` + +## Extracting metrics + +Metrics implementations will allow extracting the values for presentation in an external system. For example here is how to use the metrics implementation from `@libp2p/prometheus-metrics` to enable scraping stats to display in [Prometheus](https://prometheus.io/) or a [Graphana](https://grafana.com/) dashboard. For more information, you can view our [docs](https://libp2p.github.io/js-libp2p-prometheus-metrics/) + + +```ts +import { prometheusMetrics } from '@libp2p/prometheus-metrics' +import { createLibp2p } from 'libp2p' + +import client from 'prom-client' +import { createServer } from 'http' + + +const libp2p = createLibp2p({ + metrics: prometheusMetrics() + //... other config +}) + +createServer(async (req, res) => { + res.write(await client.register.metrics()); + res.end(); + }) + .listen(3000) +``` diff --git a/package.json b/package.json index 01fad8483a..30e55f326a 100644 --- a/package.json +++ b/package.json @@ -204,6 +204,7 @@ "@libp2p/kad-dht": "^9.1.0", "@libp2p/mdns": "^7.0.0", "@libp2p/mplex": "^8.0.1", + "@libp2p/prometheus-metrics": "^1.1.3", "@libp2p/pubsub": "^7.0.1", "@libp2p/tcp": "^7.0.1", "@libp2p/websockets": "^6.0.1", From 924e95ce4931d2648f71bc50aaa770b4809025d8 Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 3 May 2023 14:04:34 -0500 Subject: [PATCH 05/12] doc: linting fixes (#1228) --- doc/LIMITS.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/LIMITS.md b/doc/LIMITS.md index 208ea4fd91..459dadd4f9 100644 --- a/doc/LIMITS.md +++ b/doc/LIMITS.md @@ -24,7 +24,7 @@ It's possible to limit the total amount of connections a node is able to make (c - Note: there currently isn't a way to specify different limits for incoming vs. outgoing. Connection limits are applied across both incoming and outgoing connections combined. There is a backlog item for this [here](https://github.com/libp2p/js-libp2p/issues/1508). -We can also limit the number of connections in a "pending" state. These connections have been opened by a remote peer but peer IDs have yet to be exchanged and/or connection encryption and multiplexing negotiated. Once this limit is hit further connections will be closed unless the remote peer has an address in the [allow list](#allowdeny-lists). +We can also limit the number of connections in a 'pending' state. These connections have been opened by a remote peer but peer IDs have yet to be exchanged and/or connection encryption and multiplexing negotiated. Once this limit is hit further connections will be closed unless the remote peer has an address in the [allow list](#allowdeny-lists). All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values. @@ -69,7 +69,7 @@ const peerId = await createEd25519PeerId() // tag a peer await libp2p.peerStore.merge(peerId, { tags: { - "my-tag": { + 'my-tag': { value: 50, // 0-100 is the typical value range ttl: 1000, // optional field, this tag will be deleted after this many ms } @@ -195,12 +195,12 @@ Since incoming stream data is buffered until it is consumed, you should attempt All fields are optional. The default values are defined in [src/registrar.ts](https://github.com/libp2p/js-libp2p/blob/master/src/registrar.ts) - please see that file for the current values. ```ts -import { createLibp2p } from "libp2p"; +import { createLibp2p } from 'libp2p'; const node = await createLibp2p({}); node.handle( - "/my-protocol/1.0.0", + '/my-protocol/1.0.0', (streamData) => { // ..handle stream }, @@ -269,9 +269,9 @@ const node = await createLibp2p({ * all connection limits */ allow: [ - "/ip4/43.123.5.23/tcp/3984", - "/ip4/234.243.64.2", - "/ip4/52.55", + '/ip4/43.123.5.23/tcp/3984', + '/ip4/234.243.64.2', + '/ip4/52.55', // etc ], @@ -280,9 +280,9 @@ const node = await createLibp2p({ * addresses as a prefix will be immediately rejected */ deny: [ - "/ip4/132.14.52.64/tcp/3984", - "/ip4/234.243.64.2", - "/ip4/34.42", + '/ip4/132.14.52.64/tcp/3984', + '/ip4/234.243.64.2', + '/ip4/34.42', // etc ], }, From 999575a26d7f2d075c2238414035e8c818cad24d Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 3 May 2023 16:12:49 -0500 Subject: [PATCH 06/12] docs: move config to aegir repo (#1228) --- doc/tsconfig.json | 17 ----------------- package.json | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 doc/tsconfig.json diff --git a/doc/tsconfig.json b/doc/tsconfig.json deleted file mode 100644 index 359f5d14ec..0000000000 --- a/doc/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Language and Environment */ - "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - /* Modules */ - "module": "esnext" /* Specify what module code is generated. */, - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - /* Completeness */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */, - "noImplicitAny": true, - "isolatedModules": true - } -} diff --git a/package.json b/package.json index 30e55f326a..f04f5e414f 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "scripts": { "clean": "aegir clean", "lint": "aegir lint", - "doc-check": "aegir doc-check --inputFiles doc/*.md --tsConfigPath doc/", + "doc-check": "aegir doc-check --inputFiles doc/*.md", "dep-check": "aegir dep-check -i protons", "prepublishOnly": "node scripts/update-version.js", "build": "aegir build", From f4859900fe3b256cfc3751e13fab1c59ebcb4ee0 Mon Sep 17 00:00:00 2001 From: chad Date: Mon, 29 May 2023 12:20:20 -0500 Subject: [PATCH 07/12] deps: upgraded aegir to 39.0.9 to use latest doc-check (#1228) --- package.json | 2 +- tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7143b1b016..3da4236fd2 100644 --- a/package.json +++ b/package.json @@ -207,7 +207,7 @@ "@libp2p/websockets": "^6.0.1", "@types/varint": "^6.0.0", "@types/xsalsa20": "^1.1.0", - "aegir": "^39.0.5", + "aegir": "^39.0.9", "cborg": "^1.8.1", "delay": "^6.0.0", "execa": "^7.0.0", diff --git a/tsconfig.json b/tsconfig.json index 21473ad0ec..13a3599639 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,5 +6,5 @@ "include": [ "src", "test" - ], + ] } From f9a584096c48318c5c61e3e641069111c8dee0fc Mon Sep 17 00:00:00 2001 From: chad Date: Mon, 29 May 2023 12:25:43 -0500 Subject: [PATCH 08/12] docs: ignore metrics dependency as it is needed for docs (#1228) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3da4236fd2..d1371fa340 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "clean": "aegir clean", "lint": "aegir lint", "doc-check": "aegir doc-check --inputFiles doc/*.md", - "dep-check": "aegir dep-check -i protons", + "dep-check": "aegir dep-check -i protons @libp2p/prometheus-metrics", "prepublishOnly": "node scripts/update-version.js && npm run build", "build": "aegir build", "docs": "aegir docs", From 2b4233136e509392ec4317cb1a186b5dc7c7403c Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 21 Jun 2023 15:55:17 -0500 Subject: [PATCH 09/12] docs: added doc check script (#1228) --- doc/CONFIGURATION.md | 12 ++++++------ package.json | 1 - packages/libp2p/package.json | 9 ++++++++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index 025e9fa0fa..5e1fb06773 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -4,7 +4,6 @@ - [Modules](#modules) - [Transport](#transport) - [Stream Multiplexing](#stream-multiplexing) - - [Muxer Selection](#muxer-selection) - [Connection Encryption](#connection-encryption) - [Peer Discovery](#peer-discovery) - [Content Routing](#content-routing) @@ -585,12 +584,12 @@ const node = await createLibp2p({ Libp2p allows you to setup a secure keychain to manage your keys. The keychain configuration object should have the following properties: -| Name | Type | Description | -| --------- | -------- | -------------------------------------------------------------------------------------- | -| pass | `string` | Passphrase to use in the keychain (minimum of 20 characters). | -| dek | `DEKConfig` | the default options for generating the derived encryption key, which, along with the passphrase are input to the PBKDF2 function. For more info see: https://github.com/libp2p/js-libp2p-keychain | +| Name | Type | Description | +| ---- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| pass | `string` | Passphrase to use in the keychain (minimum of 20 characters). | +| dek | `DEKConfig` | the default options for generating the derived encryption key, which, along with the passphrase are input to the PBKDF2 function. For more info see: https://github.com/libp2p/js-libp2p-keychain | -The keychain will store keys encrypted in the datastore which default is an in memory datastore. If you want to store the keys on disc you need to initialize libp2p with a suitable datastore implementation. +The keychain will store keys encrypted in the datastore which default is an in memory datastore. If you want to store the keys on disc you need to initialize libp2p with a suitable datastore implementation. ```js import { createLibp2p } from 'libp2p' @@ -982,6 +981,7 @@ const node = await createLibp2p({ }) } }) +``` #### Configuring UPnP NAT Traversal diff --git a/package.json b/package.json index db12d779e4..c64333fee8 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "build": "aegir run build", "clean": "aegir run clean", "lint": "aegir run lint", - "dep-check": "aegir run dep-check", "release": "run-s build npm:release", "npm:release": "aegir exec npm -- publish || true", "release:rc": "aegir release-rc", diff --git a/packages/libp2p/package.json b/packages/libp2p/package.json index 2ceeebe910..7f26c9d9e2 100644 --- a/packages/libp2p/package.json +++ b/packages/libp2p/package.json @@ -95,7 +95,8 @@ "scripts": { "clean": "aegir clean", "lint": "aegir lint", - "dep-check": "aegir dep-check", + "doc-check": "aegir doc-check --inputFiles ../../doc/*.md", + "dep-check": "aegir dep-check -i protons @libp2p/prometheus-metrics", "prepublishOnly": "node scripts/update-version.js && npm run build", "build": "aegir build", "generate": "run-s generate:proto:*", @@ -168,15 +169,21 @@ "@libp2p/daemon-server": "^5.0.2", "@libp2p/floodsub": "^7.0.1", "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-mocks": "^12.0.1", + "@libp2p/interface-peer-id": "^2.0.2", + "@libp2p/interface-pubsub": "^4.0.1", + "@libp2p/interfaces": "^3.3.2", "@libp2p/interop": "^8.0.0", "@libp2p/kad-dht": "^9.0.0", "@libp2p/mdns": "^8.0.0", "@libp2p/mplex": "^8.0.0", + "@libp2p/pubsub": "^7.0.1", "@libp2p/tcp": "^7.0.0", "@libp2p/websockets": "^6.0.0", "@types/varint": "^6.0.0", "@types/xsalsa20": "^1.1.0", "aegir": "^39.0.10", + "cborg": "^2.0.1", "delay": "^6.0.0", "execa": "^7.0.0", "go-libp2p": "^1.1.1", From ef3e5693a1c87cd586660033c1b973dd310639cc Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 28 Jun 2023 16:48:24 -0500 Subject: [PATCH 10/12] docs: added doc-check to doc workspace (#1228) --- doc/LIMITS.md | 4 ++-- doc/package.json | 43 ++++++++++++++++++++++++++++++++++++ doc/tsconfig.json | 6 +++++ package.json | 3 ++- packages/libp2p/package.json | 9 +------- 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 doc/package.json create mode 100644 doc/tsconfig.json diff --git a/doc/LIMITS.md b/doc/LIMITS.md index 459dadd4f9..84d8c0bfbc 100644 --- a/doc/LIMITS.md +++ b/doc/LIMITS.md @@ -177,8 +177,8 @@ const node = await createLibp2p({ * This field is optional, the default value is shown */ maxOutboundStreams: 100, - }), - ], + }) + ] }); diff --git a/doc/package.json b/doc/package.json new file mode 100644 index 0000000000..4a55707b2f --- /dev/null +++ b/doc/package.json @@ -0,0 +1,43 @@ +{ + "name": "@libp2p/docs", + "version": "1.0.0", + "description": "Docs for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-internal#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "type": "module", + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "build": "aegir build", + "doc-check": "aegir doc-check" + }, + "dependencies": { + "@chainsafe/libp2p-yamux": "^4.0.2", + "@libp2p/interface-metrics": "^4.0.8", + "@libp2p/mplex": "^8.0.4", + "@libp2p/prometheus-metrics": "^1.1.5", + "@libp2p/tcp": "^7.0.3", + "aegir": "^39.0.13", + "libp2p": "^0.45.9", + "prom-client": "^14.2.0" + } +} diff --git a/doc/tsconfig.json b/doc/tsconfig.json new file mode 100644 index 0000000000..db3eb63fca --- /dev/null +++ b/doc/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + } +} \ No newline at end of file diff --git a/package.json b/package.json index 0f2e7be576..66d7e44438 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "workspaces": [ "packages/*", "interop", - "examples/*" + "examples/*", + "doc/*" ] } diff --git a/packages/libp2p/package.json b/packages/libp2p/package.json index d051c7995f..ce64a297a6 100644 --- a/packages/libp2p/package.json +++ b/packages/libp2p/package.json @@ -95,8 +95,7 @@ "scripts": { "clean": "aegir clean", "lint": "aegir lint", - "doc-check": "aegir doc-check --inputFiles ../../doc/*.md", - "dep-check": "aegir dep-check -i protons @libp2p/prometheus-metrics", + "dep-check": "aegir dep-check", "prepublishOnly": "node scripts/update-version.js && npm run build", "build": "aegir build", "generate": "run-s generate:proto:*", @@ -169,21 +168,15 @@ "@libp2p/daemon-server": "^5.0.2", "@libp2p/floodsub": "^7.0.0", "@libp2p/interface-compliance-tests": "^3.0.0", - "@libp2p/interface-mocks": "^12.0.1", - "@libp2p/interface-peer-id": "^2.0.2", - "@libp2p/interface-pubsub": "^4.0.1", - "@libp2p/interfaces": "^3.3.2", "@libp2p/interop": "^8.0.0", "@libp2p/kad-dht": "^9.0.0", "@libp2p/mdns": "^8.0.0", "@libp2p/mplex": "^8.0.0", - "@libp2p/pubsub": "^7.0.1", "@libp2p/tcp": "^7.0.0", "@libp2p/websockets": "^6.0.0", "@types/varint": "^6.0.0", "@types/xsalsa20": "^1.1.0", "aegir": "^39.0.10", - "cborg": "^2.0.1", "delay": "^6.0.0", "execa": "^7.1.1", "go-libp2p": "^1.1.1", From 0948c94de058420a8b64567b9ae6bddd66f54847 Mon Sep 17 00:00:00 2001 From: chad Date: Wed, 28 Jun 2023 16:48:24 -0500 Subject: [PATCH 11/12] docs: added doc-check to doc workspace (#1228) --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 66d7e44438..ab7ca812b3 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "build": "aegir run build", "clean": "aegir run clean", "lint": "aegir run lint", + "dep-check": "aegir run dep-check", "release": "run-s build npm:release", "npm:release": "aegir exec npm -- publish || true", "release:rc": "aegir release-rc", From ec3ed567e2ed4ee7d367f64c8cabc2e350849f3b Mon Sep 17 00:00:00 2001 From: Chad Nehemiah Date: Tue, 4 Jul 2023 10:12:17 -0500 Subject: [PATCH 12/12] Add private flag to avoid publishing to npm Co-authored-by: Alex Potsides --- doc/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/package.json b/doc/package.json index 4a55707b2f..ff989310b1 100644 --- a/doc/package.json +++ b/doc/package.json @@ -39,5 +39,6 @@ "aegir": "^39.0.13", "libp2p": "^0.45.9", "prom-client": "^14.2.0" - } + }, + "private": true }