feat(server): emit query events with questions, answered status, response time and timestamp

This commit is contained in:
2026-02-20 15:18:30 +00:00
parent ca36d3be0a
commit 4581a6a1e0
3 changed files with 31 additions and 3 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## 2026-02-20 - 7.9.0 - feat(server)
emit query events with questions, answered status, response time and timestamp
- Added IDnsQueryCompletedEvent interface with questions, answered, responseTimeMs and timestamp fields
- DnsServer now extends EventEmitter and calls super() in constructor
- DnsServer emits a 'query' event on incoming dnsQuery from Rust bridge, providing answers and timing
- Imported IIpcDnsQuestion and used TypeScript 'satisfies' for the emitted event object
## 2026-02-12 - 7.8.1 - fix(server) ## 2026-02-12 - 7.8.1 - fix(server)
Require Rust bridge for DNS packet processing; remove synchronous TypeScript fallback; change handler API to accept IDnsQuestion and adjust query API Require Rust bridge for DNS packet processing; remove synchronous TypeScript fallback; change handler API to accept IDnsQuestion and adjust query API

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartdns', name: '@push.rocks/smartdns',
version: '7.8.1', version: '7.9.0',
description: 'A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.' description: 'A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.'
} }

View File

@@ -1,5 +1,5 @@
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
import { RustDnsBridge, type IDnsQueryEvent, type IIpcDnsAnswer, type IRustDnsConfig } from './classes.rustdnsbridge.js'; import { RustDnsBridge, type IDnsQueryEvent, type IIpcDnsAnswer, type IIpcDnsQuestion, type IRustDnsConfig } from './classes.rustdnsbridge.js';
export interface IDnsServerOptions { export interface IDnsServerOptions {
httpsKey: string; httpsKey: string;
@@ -45,7 +45,18 @@ interface LetsEncryptOptions {
certDir?: string; certDir?: string;
} }
export class DnsServer { export interface IDnsQueryCompletedEvent {
/** The original questions from the query */
questions: IIpcDnsQuestion[];
/** Whether any handler answered the query */
answered: boolean;
/** How long handler resolution took (ms) */
responseTimeMs: number;
/** Timestamp of the query */
timestamp: number;
}
export class DnsServer extends plugins.events.EventEmitter {
private bridge: RustDnsBridge; private bridge: RustDnsBridge;
private handlers: IDnsHandler[] = []; private handlers: IDnsHandler[] = [];
@@ -57,12 +68,21 @@ export class DnsServer {
private udpServer: any = null; private udpServer: any = null;
constructor(private options: IDnsServerOptions) { constructor(private options: IDnsServerOptions) {
super();
this.bridge = new RustDnsBridge(); this.bridge = new RustDnsBridge();
// Wire up the dnsQuery event to run TypeScript handlers // Wire up the dnsQuery event to run TypeScript handlers
this.bridge.on('dnsQuery', async (event: IDnsQueryEvent) => { this.bridge.on('dnsQuery', async (event: IDnsQueryEvent) => {
try { try {
const startTime = Date.now();
const answers = this.resolveQuery(event); const answers = this.resolveQuery(event);
const responseTimeMs = Date.now() - startTime;
this.emit('query', {
questions: event.questions,
answered: answers.answered,
responseTimeMs,
timestamp: startTime,
} satisfies IDnsQueryCompletedEvent);
await this.bridge.sendQueryResult( await this.bridge.sendQueryResult(
event.correlationId, event.correlationId,
answers.answers, answers.answers,