@dudousxd/nestjs-telescope
Version:
Laravel Telescope-style observability console for NestJS — core: watchers, recorder, correlation, SQLite store, headless API.
91 lines • 4.16 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 ScheduleManagerRegistry_1;
// packages/core/src/schedule/schedule-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';
function errorMessage(error) {
return error instanceof Error ? error.message : String(error);
}
/**
* Duck-types the `ScheduleManager` SPI (see {@link ScheduleManager}) against a
* `watchers` entry so `ScheduleWatcher`-style classes that implement BOTH
* `Watcher` and `ScheduleManager` (e.g. the `@nestjs/schedule` watcher) don't
* need to also be listed in `scheduleManagers` — forgetting one of the two
* arrays used to leave `/schedules/live` silently empty.
*
* Matches the FULL required SPI shape (every non-optional member — currently
* just `listTasks`) to avoid false-positiving on an unrelated watcher that
* happens to expose an unrelated `listTasks` method. `init` is optional on the
* SPI so it is intentionally not part of the check.
*/
function isScheduleManager(watcher) {
return typeof watcher.listTasks === 'function';
}
let ScheduleManagerRegistry = ScheduleManagerRegistry_1 = class ScheduleManagerRegistry {
options;
config;
moduleRef;
logger = new Logger(ScheduleManagerRegistry_1.name);
managers = [];
constructor(options, config, moduleRef) {
this.options = options;
this.config = config;
this.moduleRef = moduleRef;
}
/** Build the shared context handed to managers (init + list). */
context() {
return { moduleRef: this.moduleRef, config: this.config };
}
/**
* Explicit `scheduleManagers` plus any `watchers` entry that structurally
* implements the `ScheduleManager` SPI (see {@link isScheduleManager}),
* deduped by identity — a watcher instance listed in BOTH `watchers` and
* `scheduleManagers` is only inited/registered once.
*/
candidates() {
const explicit = this.options.scheduleManagers ?? [];
const seen = new Set(explicit);
const fromWatchers = (this.options.watchers ?? []).filter((watcher) => isScheduleManager(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.push(manager);
}
catch (error) {
this.logger.error(`ScheduleManager failed to init: ${errorMessage(error)}`);
}
}
if (this.managers.length > 0) {
this.logger.log(`Telescope schedule managers: ${this.managers.length}`);
}
}
all() {
return [...this.managers];
}
};
ScheduleManagerRegistry = ScheduleManagerRegistry_1 = __decorate([
Injectable(),
__param(0, Inject(TELESCOPE_OPTIONS)),
__param(1, Inject(TELESCOPE_CONFIG)),
__metadata("design:paramtypes", [Object, Object, ModuleRef])
], ScheduleManagerRegistry);
export { ScheduleManagerRegistry };
//# sourceMappingURL=schedule-manager.registry.js.map