pingflux 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +275 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ <p align="center">
2
+ <img src="https://skillicons.dev/icons?i=nodejs" width="80" alt="pingflux" />
3
+ </p>
4
+
5
+ <h1 align="center">pingflux</h1>
6
+
7
+ <p align="center">
8
+ network monitoring library for Node.js — probes hosts over HTTP, TCP, UDP, DNS, and ICMP, emits events, handles retries.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <img src="https://img.shields.io/npm/v/pingflux?style=flat-square" />
13
+ <img src="https://img.shields.io/badge/runtime-Node.js-339933?style=flat-square" />
14
+ <img src="https://img.shields.io/badge/language-TypeScript-3178c6?style=flat-square" />
15
+ </p>
16
+
17
+ ---
18
+
19
+ ## what it does
20
+
21
+ `pingflux` monitors network targets continuously. you point it at a host, pick a protocol, set an interval — it runs probes in the background and tells you when something is up, down, slow, or broken. no polling loops, no boilerplate. just events.
22
+
23
+ five protocols supported out of the box: `http`, `https`, `tcp`, `udp`, `dns`, and `ping` (raw ICMP). each probe returns latency, status, and an optional error message. slow responses get their own event so you can distinguish degraded service from total failure.
24
+
25
+ ---
26
+
27
+ ## install
28
+
29
+ ```bash
30
+ npm install pingflux
31
+ ```
32
+
33
+ ---
34
+
35
+ ## quick start
36
+
37
+ ```typescript
38
+ import { Pingflux } from "pingflux";
39
+
40
+ const pf = new Pingflux({ threshold: 500, retry: 2 });
41
+
42
+ pf.watch({ protocol: "https", url: "amirvoid12.ir" });
43
+ pf.watch({ protocol: "tcp", url: "amirvoid12.ir:443", interval: 10000 });
44
+
45
+ pf.on("up", (e) => console.log(`up ${e.target} — ${e.latency}ms`));
46
+ pf.on("down", (e) => console.log(`down ${e.target}`));
47
+ pf.on("slow", (e) => console.log(`slow ${e.target} — ${e.latency}ms`));
48
+ pf.on("probe_error", (e) => console.error(`err ${e.target}: ${e.error}`));
49
+ ```
50
+
51
+ ---
52
+
53
+ ## api
54
+
55
+ ### `new Pingflux(options?)`
56
+
57
+ creates a new instance. options are applied globally to all targets unless overridden per-target.
58
+
59
+ | option | type | default | description |
60
+ |---|---|---|---|
61
+ | `threshold` | `number` | `1000` | latency in ms above which a `slow` event fires |
62
+ | `retry` | `number` | `1` | retries on failure before emitting `down` or `probe_error` |
63
+
64
+ ---
65
+
66
+ ### `.watch(target)`
67
+
68
+ starts monitoring a target. runs the first probe immediately, then repeats on the given interval. if the same target (same protocol + url) is already being watched, this is a no-op and returns `false`.
69
+
70
+ ```typescript
71
+ pf.watch({
72
+ protocol: "https",
73
+ url: "amirvoid12.ir/",
74
+ interval: 5000,
75
+ threshold: 300,
76
+ retry: 3,
77
+ });
78
+ ```
79
+
80
+ | field | type | default | description |
81
+ |---|---|---|---|
82
+ | `protocol` | `Protocol` | required | one of `http`, `https`, `tcp`, `udp`, `dns`, `ping` |
83
+ | `url` | `string` | required | target address — format depends on protocol (see below) |
84
+ | `interval` | `number` | `5000` | ms between probes |
85
+ | `threshold` | `number` | global | overrides the global threshold for this target |
86
+ | `retry` | `number` | global | overrides the global retry count for this target |
87
+
88
+ returns `true` if monitoring started, `false` if already watching.
89
+
90
+ ---
91
+
92
+ ### `.on(event, callback)`
93
+
94
+ registers a listener for a probe event. multiple listeners can be registered for the same event.
95
+
96
+ ```typescript
97
+ pf.on("up", (e: PingfluxEvent) => {
98
+ console.log(e.target, e.protocol, e.latency, e.timestamp);
99
+ });
100
+ ```
101
+
102
+ ---
103
+
104
+ ### `.off(event, callback)`
105
+
106
+ removes a previously registered listener. must be the exact same function reference passed to `.on()`.
107
+
108
+ ---
109
+
110
+ ### `.stop(protocol, url)`
111
+
112
+ stops monitoring a specific target. no-op if the target isn't being watched.
113
+
114
+ ```typescript
115
+ pf.stop("https", "amirvoid12.ir");
116
+ pf.stop("tcp", "amirvoid12.ir:443");
117
+ ```
118
+
119
+ ---
120
+
121
+ ### `.stopAll()`
122
+
123
+ stops all active monitors and clears all internal state.
124
+
125
+ ---
126
+
127
+ ## events
128
+
129
+ four event types are emitted:
130
+
131
+ | event | when |
132
+ |---|---|
133
+ | `up` | target responded within the latency threshold |
134
+ | `down` | target is unreachable, no specific error |
135
+ | `slow` | target responded but latency exceeded the threshold |
136
+ | `probe_error` | probe failed with a specific error message |
137
+
138
+ every callback receives a `PingfluxEvent` object:
139
+
140
+ ```typescript
141
+ interface PingfluxEvent {
142
+ target: string;
143
+ protocol: Protocol;
144
+ latency: number | null; // null on failure
145
+ error?: string; // present on probe_error only
146
+ timestamp: number; // unix ms
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## protocols
153
+
154
+ ### `http` / `https`
155
+
156
+ sends a GET request. resolves `ok: true` if the status code is below 400. url can be a bare hostname, a path, or a full url — the protocol prefix is stripped automatically to avoid double-prefixing.
157
+
158
+ ```typescript
159
+ pf.watch({ protocol: "https", url: "amirvoid12.ir/" });
160
+ pf.watch({ protocol: "http", url: "192.168.1.1:8080/status" });
161
+ ```
162
+
163
+ ---
164
+
165
+ ### `tcp`
166
+
167
+ attempts a TCP socket connection. resolves `ok: true` on successful connect. the socket is immediately destroyed — no data is exchanged.
168
+
169
+ url must be in `host:port` format.
170
+
171
+ ```typescript
172
+ pf.watch({ protocol: "tcp", url: "amirvoid12.ir:443" });
173
+ pf.watch({ protocol: "tcp", url: "10.0.0.1:22" });
174
+ ```
175
+
176
+ ---
177
+
178
+ ### `udp`
179
+
180
+ sends a small packet and waits for any response. resolves `ok: true` only if a response is received within the timeout window.
181
+
182
+ ⚠️ most servers do not reply to arbitrary UDP packets. a timeout here does not necessarily mean the host is down — the server may have simply ignored the probe. this is most useful for services that explicitly echo UDP packets. for DNS specifically, use the `dns` protocol.
183
+
184
+ url must be in `host:port` format.
185
+
186
+ ```typescript
187
+ pf.watch({ protocol: "udp", url: "1.2.3.4:9000" });
188
+ ```
189
+
190
+ ---
191
+
192
+ ### `dns`
193
+
194
+ performs a DNS lookup for the given hostname. tries A records first, then AAAA, then CNAME as a fallback. resolves `ok: true` if any record type is found.
195
+
196
+ ⚠️ hosts with exclusively MX, TXT, or other record types will resolve as `ok: false`.
197
+
198
+ ```typescript
199
+ pf.watch({ protocol: "dns", url: "google.com" });
200
+ ```
201
+
202
+ ---
203
+
204
+ ### `ping`
205
+
206
+ sends a raw ICMP echo request and waits for a matching reply. the blocking `recvfrom` syscall runs inside a Worker thread to avoid blocking the event loop.
207
+
208
+ ⚠️ **requires elevated privileges:**
209
+ - Linux: root or `CAP_NET_RAW` (`sudo setcap cap_net_raw+ep $(which node)`)
210
+ - macOS: root
211
+ - Windows: Administrator
212
+
213
+ ⚠️ **url must be a plain IPv4 address.** hostname resolution is not performed — resolve the hostname before passing it in.
214
+
215
+ ```typescript
216
+ pf.watch({ protocol: "ping", url: "1.1.1.1" });
217
+ pf.watch({ protocol: "ping", url: "8.8.8.8", interval: 3000 });
218
+ ```
219
+
220
+ ---
221
+
222
+ ## url format by protocol
223
+
224
+ | protocol | format | example |
225
+ |---|---|---|
226
+ | `http` | hostname, path, or full url | `amirvoid12.ir/` |
227
+ | `https` | hostname, path, or full url | `amirvoid12.ir` |
228
+ | `tcp` | `host:port` | `amirvoid12.ir:443` |
229
+ | `udp` | `host:port` | `1.2.3.4:9000` |
230
+ | `dns` | hostname (port suffix ignored) | `google.com` |
231
+ | `ping` | plain IPv4 address | `1.1.1.1` |
232
+
233
+ ---
234
+
235
+ ## event listener management
236
+
237
+ ```typescript
238
+ const handler = (e: PingfluxEvent) => console.log(e);
239
+
240
+ // register
241
+ pf.on("up", handler);
242
+
243
+ // remove — must pass exact same reference
244
+ pf.off("up", handler);
245
+ ```
246
+
247
+ ---
248
+
249
+ ## duplicate watch protection
250
+
251
+ calling `.watch()` with the same protocol and url combination twice is a no-op. the return value tells you whether monitoring actually started:
252
+
253
+ ```typescript
254
+ pf.watch({ protocol: "https", url: "amirvoid12.ir" }); // true — started
255
+ pf.watch({ protocol: "https", url: "amirvoid12.ir" }); // false — already running
256
+ ```
257
+
258
+ ---
259
+
260
+ ## concurrent probe protection
261
+
262
+ if a probe takes longer than the interval, the next scheduled run is skipped. this prevents multiple concurrent probes from stacking up on slow or unreachable targets.
263
+
264
+ ---
265
+
266
+ ## built with
267
+
268
+ - **TypeScript** — fully typed, interfaces exported
269
+ - **Node.js built-ins** — `net`, `dgram`, `dns`, `http`, `https`, `worker_threads`
270
+ - **koffi** — FFI bindings for raw ICMP socket syscalls
271
+ - `process.hrtime.bigint()` for sub-millisecond latency measurement
272
+
273
+ ---
274
+
275
+ built by [AmirVoid12 (AmirDavodinia)](https://amirvoid12.ir)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pingflux",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "A lightweight, event-driven network diagnostics and observability SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",