@dudousxd/nestjs-telescope
Version:
Laravel Telescope-style observability console for NestJS — core: watchers, recorder, correlation, SQLite store, headless API.
108 lines • 4.78 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var QueueManagerRegistry_1;
// packages/core/src/queue/queue-manager.registry.ts
import { Inject, Injectable, Logger } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { TELESCOPE_CONFIG, TELESCOPE_OPTIONS, } from '../nest/telescope.options.js';
import { redact } from '../redaction/redact.js';
function errorMessage(error) {
return error instanceof Error ? error.message : String(error);
}
/**
* Duck-types the `QueueManager` SPI (see {@link QueueManager}) against a
* `watchers` entry so a watcher class that ALSO implements `QueueManager`
* doesn't need to be listed in both `watchers` and `queueManagers` — mirrors
* the same footgun `ScheduleManagerRegistry` closes for `ScheduleManager`.
*
* Matches the FULL required SPI shape (every non-optional member: `driver`,
* `init`, `listQueues`, `counts`, `listJobs`, `getJob`) so an unrelated watcher
* that happens to expose e.g. its own `listQueues` doesn't false-positive. The
* Phase-2 action methods (`retry`/`remove`/`promote`/`retryAll`/`redrive`/
* `enqueue`) are optional on the SPI and intentionally not part of the check.
*/
function isQueueManager(watcher) {
const candidate = watcher;
return (typeof candidate.driver === 'string' &&
typeof candidate.init === 'function' &&
typeof candidate.listQueues === 'function' &&
typeof candidate.counts === 'function' &&
typeof candidate.listJobs === 'function' &&
typeof candidate.getJob === 'function');
}
let QueueManagerRegistry = QueueManagerRegistry_1 = class QueueManagerRegistry {
options;
config;
moduleRef;
logger = new Logger(QueueManagerRegistry_1.name);
managers = new Map();
constructor(options, config, moduleRef) {
this.options = options;
this.config = config;
this.moduleRef = moduleRef;
}
/** Build the shared context handed to managers (init + on-demand actions). */
context() {
return {
moduleRef: this.moduleRef,
config: this.config,
redact: (value) => redact(value, this.config.redact),
};
}
/**
* Explicit `queueManagers` plus any `watchers` entry that structurally
* implements the `QueueManager` SPI (see {@link isQueueManager}), deduped by
* identity — a watcher instance listed in BOTH `watchers` and
* `queueManagers` is only inited/registered once.
*/
candidates() {
const explicit = this.options.queueManagers ?? [];
const seen = new Set(explicit);
const fromWatchers = (this.options.watchers ?? []).filter((watcher) => isQueueManager(watcher) && !seen.has(watcher));
return [...explicit, ...fromWatchers];
}
async onApplicationBootstrap() {
if (!this.config.enabled)
return;
const ctx = this.context();
for (const manager of this.candidates()) {
try {
await manager.init(ctx);
this.managers.set(manager.driver, manager);
}
catch (error) {
this.logger.error(`QueueManager "${manager.driver}" failed to init: ${errorMessage(error)}`);
}
}
if (this.managers.size > 0) {
this.logger.log(`Telescope queue drivers: ${[...this.managers.keys()].join(', ')}`);
}
}
drivers() {
return [...this.managers.keys()];
}
get(driver) {
return this.managers.get(driver);
}
all() {
return [...this.managers.values()];
}
};
QueueManagerRegistry = QueueManagerRegistry_1 = __decorate([
Injectable(),
__param(0, Inject(TELESCOPE_OPTIONS)),
__param(1, Inject(TELESCOPE_CONFIG)),
__metadata("design:paramtypes", [Object, Object, ModuleRef])
], QueueManagerRegistry);
export { QueueManagerRegistry };
//# sourceMappingURL=queue-manager.registry.js.map