From a87f4147908910ea9805b12c9805c5217ac42618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Wed, 27 Aug 2025 13:12:33 +0300 Subject: [PATCH 1/6] Add event system with metrics and typings Introduces Event.js implementing a publish/subscribe event system with Prometheus metrics tracking, and Event.d.ts for TypeScript definitions. Updates package.json exports to use the new event files. --- package.json | 6 +- src/Event.d.ts | 43 ++++++++++ src/Event.js | 214 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 src/Event.d.ts create mode 100644 src/Event.js diff --git a/package.json b/package.json index 122d71a..9a96247 100644 --- a/package.json +++ b/package.json @@ -44,9 +44,9 @@ }, "exports": { ".": { - "import": "./src/Event.ts", - "require": "./src/Event.ts", - "types": "./src/Event.ts" + "import": "./src/Event.js", + "require": "./src/Event.js", + "types": "./src/Event.d.ts" }, "./client": { "import": "./client/Event.js", diff --git a/src/Event.d.ts b/src/Event.d.ts new file mode 100644 index 0000000..9863c72 --- /dev/null +++ b/src/Event.d.ts @@ -0,0 +1,43 @@ +import * as client from "prom-client"; + +export interface EventRegistry { + id: string; + type: string; + callback: (...args: any[]) => void; + unsubscribe: () => void; +} + +export type EventCallback = (...args: any[]) => void; + +/** + * Subscribe to events with a callback function + * @param args - Event type parts followed by a callback function + * @returns Event registry object with unsubscribe method + */ +export declare function subscribe( + ...args: [...string[], EventCallback] +): EventRegistry; + +/** + * Publish an event with a payload + * @param args - Event type parts followed by the payload + */ +export declare function publish(...args: [...string[], any]): void; + +/** + * Map containing the last message for each event type + */ +export declare const messages: Map; + +/** + * Get the last published message for a given event type + * @param type - The event type + * @param init - Default value if no message exists + * @returns The last message or the init value + */ +export declare function last(type: string, init?: any): any; + +/** + * Prometheus client for metrics + */ +export declare const client: typeof import("prom-client"); diff --git a/src/Event.js b/src/Event.js new file mode 100644 index 0000000..a4b1b01 --- /dev/null +++ b/src/Event.js @@ -0,0 +1,214 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.client = + exports.last = + exports.messages = + exports.publish = + exports.subscribe = + void 0; + +const client = require("prom-client"); +const { v4: uuid } = require("uuid"); + +const subscriptions = {}; +const messages = new Map(); + +const eventPublishCounter = new client.Counter({ + name: "events_published_total", + help: "Total number of events published", + labelNames: ["event_type"], +}); + +const eventSubscriptionGauge = new client.Gauge({ + name: "active_event_subscriptions", + help: "Number of active event subscriptions", + labelNames: ["event_type"], +}); + +const eventPublishDuration = new client.Histogram({ + name: "event_publish_duration_seconds", + help: "Time taken to publish events", + labelNames: ["event_type"], + buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], +}); + +// Track payload size for analysis +const eventPayloadSize = new client.Histogram({ + name: "event_payload_size_bytes", + help: "Size of event payloads in bytes", + labelNames: ["event_type"], + buckets: [10, 100, 1000, 10000, 100000, 1000000], +}); + +// Track error rates +const eventPublishErrors = new client.Counter({ + name: "event_publish_errors_total", + help: "Total number of event publish errors", + labelNames: ["event_type", "error_type"], +}); + +// Track callback processing duration +const callbackProcessingDuration = new client.Histogram({ + name: "event_callback_duration_seconds", + help: "Time taken to process event callbacks", + labelNames: ["event_type"], + buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], +}); + +// Track subscription rates +const subscriptionRate = new client.Counter({ + name: "event_subscriptions_total", + help: "Total number of event subscriptions created", + labelNames: ["event_type"], +}); + +// Track unsubscription rates +const unsubscriptionRate = new client.Counter({ + name: "event_unsubscriptions_total", + help: "Total number of event unsubscriptions", + labelNames: ["event_type"], +}); + +// Track throughput (events processed per second) +const eventThroughput = new client.Counter({ + name: "event_callbacks_processed_total", + help: "Total number of event callbacks processed successfully", + labelNames: ["event_type"], +}); + +const colors = [ + "red", + "green", + "yellow", + "blue", + "magenta", + "cyan", + "white", + "gray", +]; + +function typeColor(type) { + const hash = (str) => { + let hash = 0; + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; + } + return Math.abs(hash); + }; + + const colorIndex = hash(type) % colors.length; + return colors[colorIndex]; +} + +const subscribe = (...args) => { + if (args.length < 2) { + throw new Error("subscribe requires at least 2 arguments"); + } + + const callback = args.pop(); + const type = args.join("."); + const id = uuid(); + + console.debug("node-event", "subscribe", type, id); + + if (type === "__proto__" || type === "constructor" || type === "prototype") { + throw new Error("Invalid subscription type"); + } + if (!subscriptions[type]) { + subscriptions[type] = {}; + } + + const registry = { + id, + type, + callback, + unsubscribe: () => { + console.debug("node-event", "unsubscribe", type, id); + delete subscriptions[type][id]; + + // Track unsubscription + unsubscriptionRate.labels(type).inc(); + + if (Object.keys(subscriptions[type]).length === 0) { + delete subscriptions[type]; + eventSubscriptionGauge.labels(type).set(0); + } else { + eventSubscriptionGauge + .labels(type) + .set(Object.keys(subscriptions[type]).length); + } + }, + }; + + subscriptions[type][id] = registry; + + // Update subscription metrics + subscriptionRate.labels(type).inc(); + eventSubscriptionGauge + .labels(type) + .set(Object.keys(subscriptions[type]).length); + + return registry; +}; + +const publish = (...args) => { + if (args.length < 2) { + throw new Error("publish requires at least 2 arguments"); + } + + const payload = args.pop(); + const type = args.join("."); + + console.log("node-event", "publish", type, payload); + messages.set(type, payload); + + if (type === "__proto__" || type === "constructor" || type === "prototype") { + throw new Error("Invalid publish type"); + } + + // Track metrics for event publishing + const endTimer = eventPublishDuration.labels(type).startTimer(); + eventPublishCounter.labels(type).inc(); + + // Track payload size + const payloadSize = JSON.stringify(payload).length; + eventPayloadSize.labels(type).observe(payloadSize); + + Object.keys(subscriptions[type] || {}).forEach((key) => { + const registry = subscriptions[type][key]; + + setTimeout(() => { + const callbackTimer = callbackProcessingDuration + .labels(type) + .startTimer(); + try { + registry.callback(payload, registry); + eventThroughput.labels(type).inc(); + } catch (err) { + console.error("node-event", "error", type, err); + const errorName = err instanceof Error ? err.name : "UnknownError"; + eventPublishErrors.labels(type, errorName).inc(); + } finally { + callbackTimer(); + } + }, 0); + }); + + endTimer(); +}; + +function last(type, init) { + if (messages.has(type)) { + return messages.get(type); + } else { + return init; + } +} + +exports.subscribe = subscribe; +exports.publish = publish; +exports.messages = messages; +exports.last = last; +exports.client = client; From 67cc09a8a8ea3f8263594b613e924a9a123a326f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Thu, 28 Aug 2025 09:58:08 +0300 Subject: [PATCH 2/6] Remove redundant comments from Event module Eliminated unnecessary inline comments from Event.js, Event.ts, and Event.d.ts to improve code readability and maintain consistency. No functional changes were made. --- src/Event.d.ts | 21 --------------------- src/Event.js | 6 ------ src/Event.ts | 9 --------- 3 files changed, 36 deletions(-) diff --git a/src/Event.d.ts b/src/Event.d.ts index 9863c72..d6c0c17 100644 --- a/src/Event.d.ts +++ b/src/Event.d.ts @@ -9,35 +9,14 @@ export interface EventRegistry { export type EventCallback = (...args: any[]) => void; -/** - * Subscribe to events with a callback function - * @param args - Event type parts followed by a callback function - * @returns Event registry object with unsubscribe method - */ export declare function subscribe( ...args: [...string[], EventCallback] ): EventRegistry; -/** - * Publish an event with a payload - * @param args - Event type parts followed by the payload - */ export declare function publish(...args: [...string[], any]): void; -/** - * Map containing the last message for each event type - */ export declare const messages: Map; -/** - * Get the last published message for a given event type - * @param type - The event type - * @param init - Default value if no message exists - * @returns The last message or the init value - */ export declare function last(type: string, init?: any): any; -/** - * Prometheus client for metrics - */ export declare const client: typeof import("prom-client"); diff --git a/src/Event.js b/src/Event.js index a4b1b01..a5cae9c 100644 --- a/src/Event.js +++ b/src/Event.js @@ -32,7 +32,6 @@ const eventPublishDuration = new client.Histogram({ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], }); -// Track payload size for analysis const eventPayloadSize = new client.Histogram({ name: "event_payload_size_bytes", help: "Size of event payloads in bytes", @@ -40,14 +39,12 @@ const eventPayloadSize = new client.Histogram({ buckets: [10, 100, 1000, 10000, 100000, 1000000], }); -// Track error rates const eventPublishErrors = new client.Counter({ name: "event_publish_errors_total", help: "Total number of event publish errors", labelNames: ["event_type", "error_type"], }); -// Track callback processing duration const callbackProcessingDuration = new client.Histogram({ name: "event_callback_duration_seconds", help: "Time taken to process event callbacks", @@ -55,21 +52,18 @@ const callbackProcessingDuration = new client.Histogram({ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], }); -// Track subscription rates const subscriptionRate = new client.Counter({ name: "event_subscriptions_total", help: "Total number of event subscriptions created", labelNames: ["event_type"], }); -// Track unsubscription rates const unsubscriptionRate = new client.Counter({ name: "event_unsubscriptions_total", help: "Total number of event unsubscriptions", labelNames: ["event_type"], }); -// Track throughput (events processed per second) const eventThroughput = new client.Counter({ name: "event_callbacks_processed_total", help: "Total number of event callbacks processed successfully", diff --git a/src/Event.ts b/src/Event.ts index f43ae26..7d87162 100644 --- a/src/Event.ts +++ b/src/Event.ts @@ -23,7 +23,6 @@ const eventPublishDuration = new client.Histogram({ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], }); -// Track payload size for analysis const eventPayloadSize = new client.Histogram({ name: "event_payload_size_bytes", help: "Size of event payloads in bytes", @@ -31,14 +30,12 @@ const eventPayloadSize = new client.Histogram({ buckets: [10, 100, 1000, 10000, 100000, 1000000], }); -// Track error rates const eventPublishErrors = new client.Counter({ name: "event_publish_errors_total", help: "Total number of event publish errors", labelNames: ["event_type", "error_type"], }); -// Track callback processing duration const callbackProcessingDuration = new client.Histogram({ name: "event_callback_duration_seconds", help: "Time taken to process event callbacks", @@ -46,21 +43,18 @@ const callbackProcessingDuration = new client.Histogram({ buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], }); -// Track subscription rates const subscriptionRate = new client.Counter({ name: "event_subscriptions_total", help: "Total number of event subscriptions created", labelNames: ["event_type"], }); -// Track unsubscription rates const unsubscriptionRate = new client.Counter({ name: "event_unsubscriptions_total", help: "Total number of event unsubscriptions", labelNames: ["event_type"], }); -// Track throughput (events processed per second) const eventThroughput = new client.Counter({ name: "event_callbacks_processed_total", help: "Total number of event callbacks processed successfully", @@ -135,7 +129,6 @@ const subscribe = (...args) => { subscriptions[type][id] = registry; - // Update subscription metrics subscriptionRate.labels(type).inc(); eventSubscriptionGauge .labels(type) @@ -159,11 +152,9 @@ const publish = (...args) => { throw new Error("Invalid publish type"); } - // Track metrics for event publishing const endTimer = eventPublishDuration.labels(type).startTimer(); eventPublishCounter.labels(type).inc(); - // Track payload size const payloadSize = JSON.stringify(payload).length; eventPayloadSize.labels(type).observe(payloadSize); From 9fa45ae8b0036c3a2762890aff310035efacf73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Thu, 28 Aug 2025 10:01:42 +0300 Subject: [PATCH 3/6] Replace console.debug with console.log in Event.js Changed logging from console.debug to console.log for subscription and unsubscription events. Also removed some redundant comments to clean up the code. --- src/Event.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Event.js b/src/Event.js index a5cae9c..a1500a7 100644 --- a/src/Event.js +++ b/src/Event.js @@ -105,7 +105,7 @@ const subscribe = (...args) => { const type = args.join("."); const id = uuid(); - console.debug("node-event", "subscribe", type, id); + console.log("node-event", "subscribe", type, id); if (type === "__proto__" || type === "constructor" || type === "prototype") { throw new Error("Invalid subscription type"); @@ -119,10 +119,9 @@ const subscribe = (...args) => { type, callback, unsubscribe: () => { - console.debug("node-event", "unsubscribe", type, id); + console.log("node-event", "unsubscribe", type, id); delete subscriptions[type][id]; - // Track unsubscription unsubscriptionRate.labels(type).inc(); if (Object.keys(subscriptions[type]).length === 0) { @@ -138,7 +137,6 @@ const subscribe = (...args) => { subscriptions[type][id] = registry; - // Update subscription metrics subscriptionRate.labels(type).inc(); eventSubscriptionGauge .labels(type) @@ -162,11 +160,9 @@ const publish = (...args) => { throw new Error("Invalid publish type"); } - // Track metrics for event publishing const endTimer = eventPublishDuration.labels(type).startTimer(); eventPublishCounter.labels(type).inc(); - // Track payload size const payloadSize = JSON.stringify(payload).length; eventPayloadSize.labels(type).observe(payloadSize); From e98ed70894a8f0f1ba0c46a9d1c855cf8610d842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Thu, 28 Aug 2025 10:13:20 +0300 Subject: [PATCH 4/6] Handle JSON.stringify errors in publish function Adds error handling for JSON.stringify when calculating payload size in the publish function. If stringification fails, logs the error, increments an error metric, and sets payload size to 0 to prevent crashes. --- server/server.js | 0 src/Event.js | 11 ++++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) mode change 100644 => 100755 server/server.js diff --git a/server/server.js b/server/server.js old mode 100644 new mode 100755 diff --git a/src/Event.js b/src/Event.js index a1500a7..28f0b15 100644 --- a/src/Event.js +++ b/src/Event.js @@ -163,7 +163,16 @@ const publish = (...args) => { const endTimer = eventPublishDuration.labels(type).startTimer(); eventPublishCounter.labels(type).inc(); - const payloadSize = JSON.stringify(payload).length; + let payloadSize = 0; + try { + payloadSize = JSON.stringify(payload).length; + } catch (err) { + console.error("node-event", "error stringifying payload", type, err); + const errorName = err instanceof Error ? err.name : "UnknownError"; + eventPublishErrors.labels(type, errorName).inc(); + payloadSize = 0; + } + eventPayloadSize.labels(type).observe(payloadSize); Object.keys(subscriptions[type] || {}).forEach((key) => { From 6529f9ac0924e6da6cf84d67343475c531f4899c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Thu, 28 Aug 2025 10:23:54 +0300 Subject: [PATCH 5/6] Remove redundant comment in subscribe function Deleted an unnecessary comment related to tracking unsubscription in the subscribe function for improved code clarity. --- src/Event.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Event.ts b/src/Event.ts index 7d87162..465651f 100644 --- a/src/Event.ts +++ b/src/Event.ts @@ -113,7 +113,6 @@ const subscribe = (...args) => { console.debug("node-event", "unsubscribe", type, id); delete subscriptions[type][id]; - // Track unsubscription unsubscriptionRate.labels(type).inc(); if (Object.keys(subscriptions[type]).length === 0) { From 16e938420f2f9f7801e25bf0d421034445c99b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebubekir=20Y=C4=B1lmaz?= Date: Thu, 28 Aug 2025 12:23:15 +0300 Subject: [PATCH 6/6] Refactor Event module to TypeScript Removed src/Event.js and src/Event.d.ts, consolidating all event logic into src/Event.ts. Updated package.json build script to compile src/Event.ts. This change improves type safety and maintainability by using TypeScript directly for the Event module. --- package.json | 2 +- src/Event.d.ts | 22 ----- src/Event.js | 213 ------------------------------------------------- src/Event.ts | 3 +- 4 files changed, 3 insertions(+), 237 deletions(-) delete mode 100644 src/Event.d.ts delete mode 100644 src/Event.js diff --git a/package.json b/package.json index 9a96247..fe27b38 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "test": "jest src", "start": "node sample/publisher/index.js && node sample/subscriber/index.js && npx nuc-node-event-test/server", - "build": "npx tsc client/Event.ts --outDir client --declaration" + "build": "npx tsc client/Event.ts --outDir client --declaration && npx tsc src/Event.ts --outDir src --declaration" }, "dependencies": { "chalk": "^4.1.2", diff --git a/src/Event.d.ts b/src/Event.d.ts deleted file mode 100644 index d6c0c17..0000000 --- a/src/Event.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as client from "prom-client"; - -export interface EventRegistry { - id: string; - type: string; - callback: (...args: any[]) => void; - unsubscribe: () => void; -} - -export type EventCallback = (...args: any[]) => void; - -export declare function subscribe( - ...args: [...string[], EventCallback] -): EventRegistry; - -export declare function publish(...args: [...string[], any]): void; - -export declare const messages: Map; - -export declare function last(type: string, init?: any): any; - -export declare const client: typeof import("prom-client"); diff --git a/src/Event.js b/src/Event.js deleted file mode 100644 index 28f0b15..0000000 --- a/src/Event.js +++ /dev/null @@ -1,213 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.client = - exports.last = - exports.messages = - exports.publish = - exports.subscribe = - void 0; - -const client = require("prom-client"); -const { v4: uuid } = require("uuid"); - -const subscriptions = {}; -const messages = new Map(); - -const eventPublishCounter = new client.Counter({ - name: "events_published_total", - help: "Total number of events published", - labelNames: ["event_type"], -}); - -const eventSubscriptionGauge = new client.Gauge({ - name: "active_event_subscriptions", - help: "Number of active event subscriptions", - labelNames: ["event_type"], -}); - -const eventPublishDuration = new client.Histogram({ - name: "event_publish_duration_seconds", - help: "Time taken to publish events", - labelNames: ["event_type"], - buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], -}); - -const eventPayloadSize = new client.Histogram({ - name: "event_payload_size_bytes", - help: "Size of event payloads in bytes", - labelNames: ["event_type"], - buckets: [10, 100, 1000, 10000, 100000, 1000000], -}); - -const eventPublishErrors = new client.Counter({ - name: "event_publish_errors_total", - help: "Total number of event publish errors", - labelNames: ["event_type", "error_type"], -}); - -const callbackProcessingDuration = new client.Histogram({ - name: "event_callback_duration_seconds", - help: "Time taken to process event callbacks", - labelNames: ["event_type"], - buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], -}); - -const subscriptionRate = new client.Counter({ - name: "event_subscriptions_total", - help: "Total number of event subscriptions created", - labelNames: ["event_type"], -}); - -const unsubscriptionRate = new client.Counter({ - name: "event_unsubscriptions_total", - help: "Total number of event unsubscriptions", - labelNames: ["event_type"], -}); - -const eventThroughput = new client.Counter({ - name: "event_callbacks_processed_total", - help: "Total number of event callbacks processed successfully", - labelNames: ["event_type"], -}); - -const colors = [ - "red", - "green", - "yellow", - "blue", - "magenta", - "cyan", - "white", - "gray", -]; - -function typeColor(type) { - const hash = (str) => { - let hash = 0; - for (let i = 0; i < str.length; i++) { - const char = str.charCodeAt(i); - hash = (hash << 5) - hash + char; - hash = hash & hash; - } - return Math.abs(hash); - }; - - const colorIndex = hash(type) % colors.length; - return colors[colorIndex]; -} - -const subscribe = (...args) => { - if (args.length < 2) { - throw new Error("subscribe requires at least 2 arguments"); - } - - const callback = args.pop(); - const type = args.join("."); - const id = uuid(); - - console.log("node-event", "subscribe", type, id); - - if (type === "__proto__" || type === "constructor" || type === "prototype") { - throw new Error("Invalid subscription type"); - } - if (!subscriptions[type]) { - subscriptions[type] = {}; - } - - const registry = { - id, - type, - callback, - unsubscribe: () => { - console.log("node-event", "unsubscribe", type, id); - delete subscriptions[type][id]; - - unsubscriptionRate.labels(type).inc(); - - if (Object.keys(subscriptions[type]).length === 0) { - delete subscriptions[type]; - eventSubscriptionGauge.labels(type).set(0); - } else { - eventSubscriptionGauge - .labels(type) - .set(Object.keys(subscriptions[type]).length); - } - }, - }; - - subscriptions[type][id] = registry; - - subscriptionRate.labels(type).inc(); - eventSubscriptionGauge - .labels(type) - .set(Object.keys(subscriptions[type]).length); - - return registry; -}; - -const publish = (...args) => { - if (args.length < 2) { - throw new Error("publish requires at least 2 arguments"); - } - - const payload = args.pop(); - const type = args.join("."); - - console.log("node-event", "publish", type, payload); - messages.set(type, payload); - - if (type === "__proto__" || type === "constructor" || type === "prototype") { - throw new Error("Invalid publish type"); - } - - const endTimer = eventPublishDuration.labels(type).startTimer(); - eventPublishCounter.labels(type).inc(); - - let payloadSize = 0; - try { - payloadSize = JSON.stringify(payload).length; - } catch (err) { - console.error("node-event", "error stringifying payload", type, err); - const errorName = err instanceof Error ? err.name : "UnknownError"; - eventPublishErrors.labels(type, errorName).inc(); - payloadSize = 0; - } - - eventPayloadSize.labels(type).observe(payloadSize); - - Object.keys(subscriptions[type] || {}).forEach((key) => { - const registry = subscriptions[type][key]; - - setTimeout(() => { - const callbackTimer = callbackProcessingDuration - .labels(type) - .startTimer(); - try { - registry.callback(payload, registry); - eventThroughput.labels(type).inc(); - } catch (err) { - console.error("node-event", "error", type, err); - const errorName = err instanceof Error ? err.name : "UnknownError"; - eventPublishErrors.labels(type, errorName).inc(); - } finally { - callbackTimer(); - } - }, 0); - }); - - endTimer(); -}; - -function last(type, init) { - if (messages.has(type)) { - return messages.get(type); - } else { - return init; - } -} - -exports.subscribe = subscribe; -exports.publish = publish; -exports.messages = messages; -exports.last = last; -exports.client = client; diff --git a/src/Event.ts b/src/Event.ts index 465651f..1d8ed16 100644 --- a/src/Event.ts +++ b/src/Event.ts @@ -1,4 +1,5 @@ -import client from "prom-client"; +import * as client from "prom-client"; + import { v4 as uuid } from "uuid"; const subscriptions = {};