pingflux 1.0.0

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 (49) hide show
  1. package/dist/core/emitter.d.ts +44 -0
  2. package/dist/core/emitter.d.ts.map +1 -0
  3. package/dist/core/emitter.js +58 -0
  4. package/dist/core/emitter.js.map +1 -0
  5. package/dist/core/monitor.d.ts +47 -0
  6. package/dist/core/monitor.d.ts.map +1 -0
  7. package/dist/core/monitor.js +156 -0
  8. package/dist/core/monitor.js.map +1 -0
  9. package/dist/index.d.ts +63 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +79 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/interfaces/index.d.ts +92 -0
  14. package/dist/interfaces/index.d.ts.map +1 -0
  15. package/dist/interfaces/index.js +3 -0
  16. package/dist/interfaces/index.js.map +1 -0
  17. package/dist/probes/dns.d.ts +17 -0
  18. package/dist/probes/dns.d.ts.map +1 -0
  19. package/dist/probes/dns.js +86 -0
  20. package/dist/probes/dns.js.map +1 -0
  21. package/dist/probes/http.d.ts +17 -0
  22. package/dist/probes/http.d.ts.map +1 -0
  23. package/dist/probes/http.js +117 -0
  24. package/dist/probes/http.js.map +1 -0
  25. package/dist/probes/ping.d.ts +21 -0
  26. package/dist/probes/ping.d.ts.map +1 -0
  27. package/dist/probes/ping.js +37 -0
  28. package/dist/probes/ping.js.map +1 -0
  29. package/dist/probes/tcp.d.ts +14 -0
  30. package/dist/probes/tcp.d.ts.map +1 -0
  31. package/dist/probes/tcp.js +115 -0
  32. package/dist/probes/tcp.js.map +1 -0
  33. package/dist/probes/udp.d.ts +19 -0
  34. package/dist/probes/udp.d.ts.map +1 -0
  35. package/dist/probes/udp.js +135 -0
  36. package/dist/probes/udp.js.map +1 -0
  37. package/dist/utils/latency.d.ts +14 -0
  38. package/dist/utils/latency.d.ts.map +1 -0
  39. package/dist/utils/latency.js +19 -0
  40. package/dist/utils/latency.js.map +1 -0
  41. package/dist/utils/probes/ping.d.ts +24 -0
  42. package/dist/utils/probes/ping.d.ts.map +1 -0
  43. package/dist/utils/probes/ping.js +218 -0
  44. package/dist/utils/probes/ping.js.map +1 -0
  45. package/dist/utils/timer.d.ts +13 -0
  46. package/dist/utils/timer.d.ts.map +1 -0
  47. package/dist/utils/timer.js +19 -0
  48. package/dist/utils/timer.js.map +1 -0
  49. package/package.json +47 -0
@@ -0,0 +1,44 @@
1
+ import { EventEmitter } from "events";
2
+ import { PingfluxEvent } from "../interfaces";
3
+ export declare class PingfluxEmitter extends EventEmitter {
4
+ constructor();
5
+ /**
6
+ * Emit an "up" event — target is reachable and within the latency threshold.
7
+ *
8
+ * @param data - The probe result event payload.
9
+ *
10
+ * @example
11
+ * emitter.on("up", (e) => console.log(`${e.target} is up (${e.latency}ms)`));
12
+ */
13
+ emitUp(data: PingfluxEvent): void;
14
+ /**
15
+ * Emit a "down" event — target is unreachable with no specific error.
16
+ *
17
+ * @param data - The probe result event payload.
18
+ *
19
+ * @example
20
+ * emitter.on("down", (e) => console.log(`${e.target} is down`));
21
+ */
22
+ emitDown(data: PingfluxEvent): void;
23
+ /**
24
+ * Emit a "slow" event — target is reachable but latency exceeds the threshold.
25
+ *
26
+ * @param data - The probe result event payload.
27
+ *
28
+ * @example
29
+ * emitter.on("slow", (e) => console.log(`${e.target} is slow (${e.latency}ms)`));
30
+ */
31
+ emitSlow(data: PingfluxEvent): void;
32
+ /**
33
+ * Emit a "probe_error" event — probe failed with a specific error message.
34
+ * Uses a dedicated "probe_error" channel instead of Node's built-in "error"
35
+ * event to avoid conflicts with EventEmitter's crash-on-unhandled-error behavior.
36
+ *
37
+ * @param data - The probe result event payload. `data.error` contains the error message.
38
+ *
39
+ * @example
40
+ * emitter.on("probe_error", (e) => console.error(`${e.target} error: ${e.error}`));
41
+ */
42
+ emitError(data: PingfluxEvent): void;
43
+ }
44
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/core/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,qBAAa,eAAgB,SAAQ,YAAY;;IAM/C;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAIjC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAInC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAInC;;;;;;;;;OASG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;CAGrC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PingfluxEmitter = void 0;
4
+ const events_1 = require("events");
5
+ class PingfluxEmitter extends events_1.EventEmitter {
6
+ constructor() {
7
+ super();
8
+ this.on("error", () => { });
9
+ }
10
+ /**
11
+ * Emit an "up" event — target is reachable and within the latency threshold.
12
+ *
13
+ * @param data - The probe result event payload.
14
+ *
15
+ * @example
16
+ * emitter.on("up", (e) => console.log(`${e.target} is up (${e.latency}ms)`));
17
+ */
18
+ emitUp(data) {
19
+ this.emit("up", data);
20
+ }
21
+ /**
22
+ * Emit a "down" event — target is unreachable with no specific error.
23
+ *
24
+ * @param data - The probe result event payload.
25
+ *
26
+ * @example
27
+ * emitter.on("down", (e) => console.log(`${e.target} is down`));
28
+ */
29
+ emitDown(data) {
30
+ this.emit("down", data);
31
+ }
32
+ /**
33
+ * Emit a "slow" event — target is reachable but latency exceeds the threshold.
34
+ *
35
+ * @param data - The probe result event payload.
36
+ *
37
+ * @example
38
+ * emitter.on("slow", (e) => console.log(`${e.target} is slow (${e.latency}ms)`));
39
+ */
40
+ emitSlow(data) {
41
+ this.emit("slow", data);
42
+ }
43
+ /**
44
+ * Emit a "probe_error" event — probe failed with a specific error message.
45
+ * Uses a dedicated "probe_error" channel instead of Node's built-in "error"
46
+ * event to avoid conflicts with EventEmitter's crash-on-unhandled-error behavior.
47
+ *
48
+ * @param data - The probe result event payload. `data.error` contains the error message.
49
+ *
50
+ * @example
51
+ * emitter.on("probe_error", (e) => console.error(`${e.target} error: ${e.error}`));
52
+ */
53
+ emitError(data) {
54
+ this.emit("probe_error", data);
55
+ }
56
+ }
57
+ exports.PingfluxEmitter = PingfluxEmitter;
58
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/core/emitter.ts"],"names":[],"mappings":";;;AAAA,mCAAsC;AAGtC,MAAa,eAAgB,SAAQ,qBAAY;IAC/C;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,IAAmB;QACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAmB;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAmB;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,IAAmB;QAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;CACF;AAvDD,0CAuDC"}
@@ -0,0 +1,47 @@
1
+ import { PingfluxEmitter } from "./emitter";
2
+ import { Target, Protocol, PingfluxOptions } from "../interfaces";
3
+ export declare class Monitor {
4
+ private emitter;
5
+ private timers;
6
+ private running;
7
+ private globalOptions;
8
+ constructor(emitter: PingfluxEmitter, options?: PingfluxOptions);
9
+ private targetKey;
10
+ private runProbe;
11
+ private runWithRetry;
12
+ private handle;
13
+ /**
14
+ * Start monitoring a target.
15
+ * Runs the appropriate probe immediately and then on every `interval` ms.
16
+ * If the same target (same protocol + url) is already being watched, this call is a no-op.
17
+ *
18
+ * @param target - The target to monitor.
19
+ * @returns `true` if monitoring started, `false` if the target was already being watched.
20
+ *
21
+ * @example
22
+ * const added = monitor.watch({ protocol: "https", url: "example.com" });
23
+ * console.log(added); // true
24
+ * const duplicate = monitor.watch({ protocol: "https", url: "example.com" });
25
+ * console.log(duplicate); // false
26
+ */
27
+ watch(target: Target): boolean;
28
+ /**
29
+ * Stop monitoring a specific target by its exact protocol and url.
30
+ * If no matching target is found, the call is a no-op.
31
+ *
32
+ * @param protocol - The protocol of the target to stop.
33
+ * @param url - The url of the target to stop.
34
+ *
35
+ * @example
36
+ * monitor.stop("https", "example.com");
37
+ */
38
+ stop(protocol: Protocol, url: string): void;
39
+ /**
40
+ * Stop all active monitors and clear all internal state.
41
+ *
42
+ * @example
43
+ * monitor.stopAll();
44
+ */
45
+ stopAll(): void;
46
+ }
47
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/core/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAe,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAQ/E,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAAkB;gBAE3B,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,eAAe;IAO/D,OAAO,CAAC,SAAS;YAIH,QAAQ;YAyBR,YAAY;IAW1B,OAAO,CAAC,MAAM;IA0Bd;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IA0B9B;;;;;;;;;OASG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAU3C;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAWhB"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Monitor = void 0;
4
+ const http_1 = require("../probes/http");
5
+ const tcp_1 = require("../probes/tcp");
6
+ const udp_1 = require("../probes/udp");
7
+ const dns_1 = require("../probes/dns");
8
+ const ping_1 = require("../probes/ping");
9
+ const latency_1 = require("../utils/latency");
10
+ class Monitor {
11
+ constructor(emitter, options) {
12
+ this.emitter = emitter;
13
+ this.timers = new Map();
14
+ this.running = new Map();
15
+ this.globalOptions = options ?? {};
16
+ }
17
+ targetKey(target) {
18
+ return `${target.protocol}::${target.url}`;
19
+ }
20
+ async runProbe(target) {
21
+ switch (target.protocol) {
22
+ case "http":
23
+ case "https":
24
+ return (0, http_1.httpProbe)(target.url, target.protocol);
25
+ case "tcp":
26
+ return (0, tcp_1.tcpProbe)(target.url);
27
+ case "udp":
28
+ return (0, udp_1.udpProbe)(target.url);
29
+ case "dns":
30
+ return (0, dns_1.dnsProbe)(target.url);
31
+ case "ping":
32
+ return (0, ping_1.pingProbe)(target.url);
33
+ default:
34
+ return {
35
+ ok: false,
36
+ latency: null,
37
+ error: "Unknown protocol",
38
+ protocol: target.protocol,
39
+ target: target.url,
40
+ timestamp: Date.now(),
41
+ };
42
+ }
43
+ }
44
+ async runWithRetry(target, retries) {
45
+ let lastResult = null;
46
+ for (let i = 0; i <= retries; i++) {
47
+ const result = await this.runProbe(target);
48
+ if (result.ok)
49
+ return result;
50
+ lastResult = result;
51
+ if (i < retries)
52
+ await new Promise((r) => setTimeout(r, 500));
53
+ }
54
+ return lastResult;
55
+ }
56
+ handle(result, threshold) {
57
+ const event = {
58
+ target: result.target,
59
+ protocol: result.protocol,
60
+ latency: result.latency,
61
+ error: result.error,
62
+ timestamp: result.timestamp,
63
+ };
64
+ if (!result.ok) {
65
+ if (result.error) {
66
+ this.emitter.emitError(event);
67
+ }
68
+ else {
69
+ this.emitter.emitDown(event);
70
+ }
71
+ return;
72
+ }
73
+ if (result.latency !== null && (0, latency_1.isSlowLatency)(result.latency, threshold)) {
74
+ this.emitter.emitSlow(event);
75
+ return;
76
+ }
77
+ this.emitter.emitUp(event);
78
+ }
79
+ /**
80
+ * Start monitoring a target.
81
+ * Runs the appropriate probe immediately and then on every `interval` ms.
82
+ * If the same target (same protocol + url) is already being watched, this call is a no-op.
83
+ *
84
+ * @param target - The target to monitor.
85
+ * @returns `true` if monitoring started, `false` if the target was already being watched.
86
+ *
87
+ * @example
88
+ * const added = monitor.watch({ protocol: "https", url: "example.com" });
89
+ * console.log(added); // true
90
+ * const duplicate = monitor.watch({ protocol: "https", url: "example.com" });
91
+ * console.log(duplicate); // false
92
+ */
93
+ watch(target) {
94
+ const key = this.targetKey(target);
95
+ if (this.timers.has(key))
96
+ return false;
97
+ const interval = target.interval ?? 5000;
98
+ const threshold = target.threshold ?? this.globalOptions.threshold ?? 1000;
99
+ const retry = target.retry ?? this.globalOptions.retry ?? 1;
100
+ const run = async () => {
101
+ if (this.running.get(key))
102
+ return;
103
+ this.running.set(key, true);
104
+ try {
105
+ const result = await this.runWithRetry(target, retry);
106
+ this.handle(result, threshold);
107
+ }
108
+ finally {
109
+ this.running.set(key, false);
110
+ }
111
+ };
112
+ run();
113
+ const timer = setInterval(run, interval);
114
+ this.timers.set(key, timer);
115
+ this.running.set(key, false);
116
+ return true;
117
+ }
118
+ /**
119
+ * Stop monitoring a specific target by its exact protocol and url.
120
+ * If no matching target is found, the call is a no-op.
121
+ *
122
+ * @param protocol - The protocol of the target to stop.
123
+ * @param url - The url of the target to stop.
124
+ *
125
+ * @example
126
+ * monitor.stop("https", "example.com");
127
+ */
128
+ stop(protocol, url) {
129
+ const key = `${protocol}::${url}`;
130
+ const timer = this.timers.get(key);
131
+ if (timer !== undefined) {
132
+ clearInterval(timer);
133
+ this.timers.delete(key);
134
+ this.running.delete(key);
135
+ }
136
+ }
137
+ /**
138
+ * Stop all active monitors and clear all internal state.
139
+ *
140
+ * @example
141
+ * monitor.stopAll();
142
+ */
143
+ stopAll() {
144
+ const keys = Array.from(this.timers.keys());
145
+ for (const key of keys) {
146
+ const timer = this.timers.get(key);
147
+ if (timer !== undefined) {
148
+ clearInterval(timer);
149
+ this.timers.delete(key);
150
+ this.running.delete(key);
151
+ }
152
+ }
153
+ }
154
+ }
155
+ exports.Monitor = Monitor;
156
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/core/monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { Target, PingfluxEvent, EventType, PingfluxOptions, Protocol } from "./interfaces";
2
+ export declare class Pingflux {
3
+ private emitter;
4
+ private monitor;
5
+ constructor(options?: PingfluxOptions);
6
+ /**
7
+ * Start monitoring a target.
8
+ * Runs the probe immediately and then on every `target.interval` ms.
9
+ * If the same target (same protocol + url) is already being watched, this call is a no-op.
10
+ *
11
+ * @param target - The target to monitor.
12
+ * @returns `true` if monitoring started, `false` if already being watched.
13
+ *
14
+ * @example
15
+ * pf.watch({ protocol: "https", url: "example.com" });
16
+ * pf.watch({ protocol: "tcp", url: "example.com:443", interval: 10000, threshold: 500 });
17
+ */
18
+ watch(target: Target): boolean;
19
+ /**
20
+ * Register a listener for a probe event.
21
+ * Multiple listeners can be registered for the same event.
22
+ *
23
+ * @param event - One of `"up"`, `"down"`, `"slow"`, `"probe_error"`.
24
+ * @param callback - Function called with the probe result payload.
25
+ *
26
+ * @example
27
+ * pf.on("up", (e) => console.log(`${e.target} is up — ${e.latency}ms`));
28
+ * pf.on("probe_error", (e) => console.error(`${e.target} error: ${e.error}`));
29
+ */
30
+ on(event: EventType, callback: (data: PingfluxEvent) => void): void;
31
+ /**
32
+ * Remove a previously registered event listener.
33
+ *
34
+ * @param event - The event name the listener was registered on.
35
+ * @param callback - The exact function reference passed to `on()`.
36
+ *
37
+ * @example
38
+ * const handler = (e: PingfluxEvent) => console.log(e);
39
+ * pf.on("up", handler);
40
+ * pf.off("up", handler);
41
+ */
42
+ off(event: EventType, callback: (data: PingfluxEvent) => void): void;
43
+ /**
44
+ * Stop monitoring a specific target.
45
+ * If no matching target is found, the call is a no-op.
46
+ *
47
+ * @param protocol - The protocol of the target to stop.
48
+ * @param url - The url of the target to stop.
49
+ *
50
+ * @example
51
+ * pf.stop("https", "example.com");
52
+ * pf.stop("tcp", "example.com:443");
53
+ */
54
+ stop(protocol: Protocol, url: string): void;
55
+ /**
56
+ * Stop all active monitors and clear all internal state.
57
+ *
58
+ * @example
59
+ * pf.stopAll();
60
+ */
61
+ stopAll(): void;
62
+ }
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE3F,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,CAAC,EAAE,eAAe;IAKrC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;;;;;;;OAUG;IACH,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAInE;;;;;;;;;;OAUG;IACH,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAIpE;;;;;;;;;;OAUG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAI3C;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAGhB"}
package/dist/index.js ADDED
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Pingflux = void 0;
4
+ const monitor_1 = require("./core/monitor");
5
+ const emitter_1 = require("./core/emitter");
6
+ class Pingflux {
7
+ constructor(options) {
8
+ this.emitter = new emitter_1.PingfluxEmitter();
9
+ this.monitor = new monitor_1.Monitor(this.emitter, options);
10
+ }
11
+ /**
12
+ * Start monitoring a target.
13
+ * Runs the probe immediately and then on every `target.interval` ms.
14
+ * If the same target (same protocol + url) is already being watched, this call is a no-op.
15
+ *
16
+ * @param target - The target to monitor.
17
+ * @returns `true` if monitoring started, `false` if already being watched.
18
+ *
19
+ * @example
20
+ * pf.watch({ protocol: "https", url: "example.com" });
21
+ * pf.watch({ protocol: "tcp", url: "example.com:443", interval: 10000, threshold: 500 });
22
+ */
23
+ watch(target) {
24
+ return this.monitor.watch(target);
25
+ }
26
+ /**
27
+ * Register a listener for a probe event.
28
+ * Multiple listeners can be registered for the same event.
29
+ *
30
+ * @param event - One of `"up"`, `"down"`, `"slow"`, `"probe_error"`.
31
+ * @param callback - Function called with the probe result payload.
32
+ *
33
+ * @example
34
+ * pf.on("up", (e) => console.log(`${e.target} is up — ${e.latency}ms`));
35
+ * pf.on("probe_error", (e) => console.error(`${e.target} error: ${e.error}`));
36
+ */
37
+ on(event, callback) {
38
+ this.emitter.on(event, callback);
39
+ }
40
+ /**
41
+ * Remove a previously registered event listener.
42
+ *
43
+ * @param event - The event name the listener was registered on.
44
+ * @param callback - The exact function reference passed to `on()`.
45
+ *
46
+ * @example
47
+ * const handler = (e: PingfluxEvent) => console.log(e);
48
+ * pf.on("up", handler);
49
+ * pf.off("up", handler);
50
+ */
51
+ off(event, callback) {
52
+ this.emitter.off(event, callback);
53
+ }
54
+ /**
55
+ * Stop monitoring a specific target.
56
+ * If no matching target is found, the call is a no-op.
57
+ *
58
+ * @param protocol - The protocol of the target to stop.
59
+ * @param url - The url of the target to stop.
60
+ *
61
+ * @example
62
+ * pf.stop("https", "example.com");
63
+ * pf.stop("tcp", "example.com:443");
64
+ */
65
+ stop(protocol, url) {
66
+ this.monitor.stop(protocol, url);
67
+ }
68
+ /**
69
+ * Stop all active monitors and clear all internal state.
70
+ *
71
+ * @example
72
+ * pf.stopAll();
73
+ */
74
+ stopAll() {
75
+ this.monitor.stopAll();
76
+ }
77
+ }
78
+ exports.Pingflux = Pingflux;
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAAyC;AACzC,4CAAiD;AAGjD,MAAa,QAAQ;IAInB,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,yBAAe,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,MAAc;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;;;OAUG;IACH,EAAE,CAAC,KAAgB,EAAE,QAAuC;QAC1D,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;;;;OAUG;IACH,GAAG,CAAC,KAAgB,EAAE,QAAuC;QAC3D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI,CAAC,QAAkB,EAAE,GAAW;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF;AA/ED,4BA+EC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Supported probe protocols.
3
+ *
4
+ * - `http` / `https` — HTTP GET request; resolves ok if status < 400
5
+ * - `tcp` — TCP socket connect; resolves ok on successful connection
6
+ * - `udp` — UDP packet send/receive; resolves ok if a response is received
7
+ * - `dns` — DNS A/AAAA record lookup; resolves ok if at least one record found
8
+ * - `ping` — Raw ICMP echo request; requires root or CAP_NET_RAW on Linux
9
+ */
10
+ export type Protocol = "http" | "https" | "tcp" | "udp" | "dns" | "ping";
11
+ /**
12
+ * Event types emitted by Pingflux.
13
+ *
14
+ * - `up` — target is reachable and within latency threshold
15
+ * - `down` — target is unreachable with no specific error
16
+ * - `slow` — target is reachable but latency exceeds threshold
17
+ * - `probe_error` — probe failed with a specific error message
18
+ */
19
+ export type EventType = "up" | "down" | "slow" | "probe_error";
20
+ /**
21
+ * Internal result returned by each probe function.
22
+ * Not exposed directly to end users — use `PingfluxEvent` for listener callbacks.
23
+ */
24
+ export interface ProbeResult {
25
+ ok: boolean;
26
+ latency: number | null;
27
+ error?: string;
28
+ protocol: Protocol;
29
+ target: string;
30
+ timestamp: number;
31
+ }
32
+ /**
33
+ * A monitoring target.
34
+ *
35
+ * @example
36
+ * // HTTP target with custom interval and threshold
37
+ * { protocol: "https", url: "example.com", interval: 10000, threshold: 500 }
38
+ *
39
+ * @example
40
+ * // TCP target
41
+ * { protocol: "tcp", url: "example.com:443" }
42
+ *
43
+ * @example
44
+ * // ICMP ping — requires root or CAP_NET_RAW, url must be a plain IP address
45
+ * { protocol: "ping", url: "1.1.1.1" }
46
+ */
47
+ export interface Target {
48
+ /**
49
+ * For `http`/`https`: hostname or full URL (e.g. `"example.com"` or `"example.com/health"`).
50
+ * For `tcp`/`udp`: `"host:port"` format (e.g. `"example.com:443"`).
51
+ * For `dns`: hostname to resolve (e.g. `"example.com"`).
52
+ * For `ping`: plain IP address only — hostname resolution is not supported (e.g. `"1.1.1.1"`).
53
+ */
54
+ url: string;
55
+ protocol: Protocol;
56
+ /** Probe interval in milliseconds. Default: `5000` */
57
+ interval?: number;
58
+ /** Latency threshold in milliseconds above which a `slow` event is emitted. Default: `1000` */
59
+ threshold?: number;
60
+ /** Number of retries on failure before emitting a `down` or `probe_error` event. Default: `1` */
61
+ retry?: number;
62
+ }
63
+ /**
64
+ * Event payload passed to all event listeners.
65
+ *
66
+ * @example
67
+ * pingflux.on("up", (e: PingfluxEvent) => {
68
+ * console.log(`${e.protocol}://${e.target} — ${e.latency}ms`);
69
+ * });
70
+ */
71
+ export interface PingfluxEvent {
72
+ target: string;
73
+ protocol: Protocol;
74
+ latency: number | null;
75
+ /** Present only on `probe_error` events. */
76
+ error?: string;
77
+ timestamp: number;
78
+ }
79
+ /**
80
+ * Global options passed to the `Pingflux` constructor.
81
+ * These apply to all targets unless overridden per-target.
82
+ *
83
+ * @example
84
+ * const pf = new Pingflux({ threshold: 500, retry: 2 });
85
+ */
86
+ export interface PingfluxOptions {
87
+ /** Default latency threshold in ms. Default: `1000` */
88
+ threshold?: number;
89
+ /** Default retry count on failure. Default: `1` */
90
+ retry?: number;
91
+ }
92
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM;IACrB;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { ProbeResult } from "../interfaces";
2
+ /**
3
+ * Probe a host via DNS resolution.
4
+ * Attempts A record lookup first, then AAAA, then CNAME as a final fallback.
5
+ * Resolves `ok: true` if any record type is found.
6
+ *
7
+ * Note: only A, AAAA, and CNAME record types are checked.
8
+ * Hosts with exclusively MX, TXT, or other record types will resolve as `ok: false`.
9
+ *
10
+ * @param url - Hostname to resolve, optionally with a port suffix (e.g. `"example.com"` or `"example.com:53"`).
11
+ *
12
+ * @example
13
+ * const result = await dnsProbe("example.com");
14
+ * console.log(result.ok, result.latency);
15
+ */
16
+ export declare function dnsProbe(url: string): Promise<ProbeResult>;
17
+ //# sourceMappingURL=dns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns.d.ts","sourceRoot":"","sources":["../../src/probes/dns.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmC1D"}