/** * Minimal collector plugin base (Phase 3 / EXTENDING.md). * * Subclasses implement `collect()` → sample batch, call `start()` to schedule. */ import { EventEmitter } from 'events' import { SAMPLE_INTERVAL_MS } from '../../../shared/metrics.js' export class CollectorPlugin extends EventEmitter { /** * @param {{ name: string, intervalMs?: number }} opts */ constructor(opts) { super() this.name = opts.name || 'plugin' this.intervalMs = opts.intervalMs || Number(process.env.PEARDATA_SAMPLE_MS) || SAMPLE_INTERVAL_MS this._timer = null } /** @returns {boolean} */ isEnabled() { return false } /** * @returns {Promise }>>|Array} */ async collect() { return [] } start() { if (this._timer || !this.isEnabled()) return const tick = async () => { try { const batch = await this.collect() if (batch?.length) this.emit('samples', batch) } catch (err) { this.emit('error', err) } } tick() this._timer = setInterval(tick, this.intervalMs) if (typeof this._timer.unref === 'function') this._timer.unref() } stop() { if (this._timer) { clearInterval(this._timer) this._timer = null } } }