@ooopsstudio/performance 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/budget-engine-KDA4FRYU.js +160 -0
  4. package/dist/budget-engine-KDA4FRYU.js.map +1 -0
  5. package/dist/chunk-2XXIOHOO.js +58 -0
  6. package/dist/chunk-2XXIOHOO.js.map +1 -0
  7. package/dist/chunk-3GMKPRQP.js +197 -0
  8. package/dist/chunk-3GMKPRQP.js.map +1 -0
  9. package/dist/chunk-J6KBSLYO.js +118 -0
  10. package/dist/chunk-J6KBSLYO.js.map +1 -0
  11. package/dist/chunk-MMO5UEUU.js +20 -0
  12. package/dist/chunk-MMO5UEUU.js.map +1 -0
  13. package/dist/chunk-RL2752FW.js +31 -0
  14. package/dist/chunk-RL2752FW.js.map +1 -0
  15. package/dist/chunk-RY65GERM.js +159 -0
  16. package/dist/chunk-RY65GERM.js.map +1 -0
  17. package/dist/chunk-W72QW2AD.js +29 -0
  18. package/dist/chunk-W72QW2AD.js.map +1 -0
  19. package/dist/chunk-ZAXGEDZW.js +1184 -0
  20. package/dist/chunk-ZAXGEDZW.js.map +1 -0
  21. package/dist/custom/exporters/http.d.ts +11 -0
  22. package/dist/custom/exporters/http.js +364 -0
  23. package/dist/custom/exporters/http.js.map +1 -0
  24. package/dist/custom/exporters/raw.d.ts +8 -0
  25. package/dist/custom/exporters/raw.js +6 -0
  26. package/dist/custom/exporters/raw.js.map +1 -0
  27. package/dist/custom.d.ts +58 -0
  28. package/dist/custom.js +299 -0
  29. package/dist/custom.js.map +1 -0
  30. package/dist/development.d.ts +19 -0
  31. package/dist/development.js +55 -0
  32. package/dist/development.js.map +1 -0
  33. package/dist/event-export-manager-DEB64LWZ.js +632 -0
  34. package/dist/event-export-manager-DEB64LWZ.js.map +1 -0
  35. package/dist/index.d.ts +26 -0
  36. package/dist/index.js +205 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/monitors-VNNUIKAK.js +753 -0
  39. package/dist/monitors-VNNUIKAK.js.map +1 -0
  40. package/dist/n1-detector-6IQ2DINP.js +247 -0
  41. package/dist/n1-detector-6IQ2DINP.js.map +1 -0
  42. package/dist/observability.d.ts +32 -0
  43. package/dist/observability.js +76 -0
  44. package/dist/observability.js.map +1 -0
  45. package/dist/ports-DwUYdKj-.d.ts +23 -0
  46. package/dist/production.d.ts +19 -0
  47. package/dist/production.js +42 -0
  48. package/dist/production.js.map +1 -0
  49. package/dist/public/types.d.ts +11 -0
  50. package/dist/public/types.js +3 -0
  51. package/dist/public/types.js.map +1 -0
  52. package/package.json +74 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/performance/features/core/event-loop-monitor.ts","../src/performance/features/core/gc-monitor.ts","../src/performance/features/core/resource-load-average.ts","../src/performance/features/core/resource-monitor.ts","../src/performance/utils/error-boundary.ts","../src/performance/core/runtime/monitors.ts"],"names":[],"mappings":"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","file":"monitors-VNNUIKAK.js","sourcesContent":["/**\n * @file Event loop lag monitor.\n * Measures event loop delay using setImmediate or microtask benchmarks.\n */\n\nimport type {PerfEvent, SaturationAlert} from '@ooopsstudio/core/contracts/performance'\n\nimport type {HighResClock} from '../../core/clock'\nimport {nsToMs} from '../../core/clock'\n\n/**\n * Event loop lag statistics\n */\nexport interface EventLoopStats {\n\n\t/** Mean lag in milliseconds */\n\tmean: number\n\t/** 95th percentile lag */\n\tp95: number\n\t/** 99th percentile lag */\n\tp99: number\n\t/** Maximum lag observed */\n\tmax: number\n\t/** Number of samples */\n\tsampleCount: number\n}\n\n/**\n * Event loop monitor for tracking event loop lag\n */\nexport interface EventLoopMonitor {\n\n\t/** Start monitoring */\n\tstart(): void\n\n\t/** Stop monitoring */\n\tstop(): void\n\n\t/** Get current statistics */\n\tgetStats(): EventLoopStats | null\n\n\t/** Get the most recent lag measurement */\n\tgetCurrentLag(): number | null\n}\n\n/**\n * Options for creating an event loop monitor\n */\nexport interface EventLoopMonitorOptions {\n\n\t/** High-resolution clock */\n\tclock: HighResClock\n\n\t/** Monitoring interval in milliseconds */\n\tintervalMs?: number\n\n\t/** Callback for saturation alerts */\n\tonSaturationAlert?: (alert: SaturationAlert) => void\n\n\t/** Callback for perf events */\n\tonPerfEvent?: (event: PerfEvent) => void\n\n\t/** Thresholds for saturation alerts */\n\tthresholds?: {\n\t\tinfo?: number\n\t\twarn?: number\n\t\tcritical?: number\n\t}\n}\n\n/**\n * Create an event loop lag monitor.\n * Uses setImmediate to measure the delay between scheduling and execution.\n *\n * @param options - Monitor options\n * @returns Event loop monitor instance\n */\nexport function createEventLoopMonitor(options: EventLoopMonitorOptions): EventLoopMonitor {\n\n\tconst {\n\t\tclock,\n\t\tintervalMs = 1000,\n\t\tonSaturationAlert,\n\t\tonPerfEvent,\n\t\tthresholds = {}\n\t} = options\n\n\tif (!Number.isSafeInteger(intervalMs) || intervalMs <= 0 || intervalMs > 2_147_483_647) {\n\t\tthrow new Error('Event loop intervalMs must be between 1 and 2147483647')\n\t}\n\tconst configuredThresholds = [thresholds.info, thresholds.warn, thresholds.critical]\n\t\t.filter((value): value is number => value !== undefined)\n\tif (!configuredThresholds.every((value) => Number.isFinite(value) && value >= 0)) {\n\t\tthrow new Error('Event loop monitor thresholds must be non-negative finite numbers')\n\t}\n\tif (\n\t\t(thresholds.info !== undefined && thresholds.warn !== undefined && thresholds.info > thresholds.warn) ||\n\t\t(thresholds.warn !== undefined && thresholds.critical !== undefined && thresholds.warn > thresholds.critical) ||\n\t\t(thresholds.info !== undefined && thresholds.critical !== undefined && thresholds.info > thresholds.critical)\n\t) {\n\t\tthrow new Error('Event loop monitor thresholds must satisfy info <= warn <= critical')\n\t}\n\t// Derive missing levels around explicit values so partial overrides preserve\n\t// their existing meaning while the effective thresholds remain ordered.\n\tconst criticalThreshold = thresholds.critical ?? Math.max(100, thresholds.warn ?? thresholds.info ?? 0)\n\tconst warnThreshold = thresholds.warn ?? Math.min(Math.max(50, thresholds.info ?? 0), criticalThreshold)\n\tconst infoThreshold = thresholds.info ?? Math.min(20, warnThreshold)\n\n\tlet timeoutId: ReturnType<typeof setTimeout> | null = null\n\tlet immediateId: ReturnType<typeof setImmediate> | null = null\n\tlet running = false\n\tconst lagSamples: number[] = []\n\tlet currentLag: number | null = null\n\tconst scheduleNext = (): void => {\n\t\tif (!running) return\n\t\trunning = false\n\t\ttry {\n\t\t\ttimeoutId = setTimeout(scheduleMeasurement, intervalMs)\n\t\t\trunning = true\n\t\t\ttimeoutId.unref?.()\n\t\t} catch { /* only timer acquisition failure leaves the monitor stopped */ }\n\t}\n\n\t/**\n\t * Measure event loop lag using setImmediate\n\t */\n\tfunction measureLag(): void {\n\n\t\tlet scheduled: bigint\n\t\ttry { scheduled = clock.nowHr() } catch {\n\t\t\tscheduleNext()\n\t\t\treturn\n\t\t}\n\t\ttry { immediateId = setImmediate(() => {\n\t\t\timmediateId = null\n\t\t\tif (!running) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlet executed: bigint\n\t\t\ttry { executed = clock.nowHr() } catch {\n\t\t\t\tscheduleNext()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst lagMs = nsToMs(executed - scheduled)\n\t\t\tif (!Number.isFinite(lagMs) || lagMs < 0) {\n\t\t\t\t// A malformed/custom high-resolution clock must not poison all\n\t\t\t\t// subsequent percentiles. Keep monitoring and wait for a valid sample.\n\t\t\t\tscheduleNext()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcurrentLag = lagMs\n\n\t\t\t// Add to samples (keep only last maxSamples)\n\t\t\tlagSamples.push(lagMs)\n\t\t\tif (lagSamples.length > 100) {\n\t\t\t\tlagSamples.shift()\n\t\t\t}\n\n\t\t\t// Emit perf event\n\t\t\tif (onPerfEvent) {\n\t\t\t\ttry {\n\t\t\t\t\tconst end = clock.now()\n\t\t\t\t\tonPerfEvent({\n\t\t\t\t\t\tname: 'event_loop_lag',\n\t\t\t\t\t\tduration: lagMs,\n\t\t\t\t\t\tstart: end - lagMs,\n\t\t\t\t\t\tend,\n\t\t\t\t\t\tsource: 'runtime'\n\t\t\t\t\t})\n\t\t\t\t} catch {\n\t\t\t\t\t// Callback failures must not stop monitoring.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check saturation thresholds\n\t\t\tif (onSaturationAlert) {\n\t\t\t\tlet severity: 'info' | 'warn' | 'critical' | null = null\n\t\t\t\tlet threshold = 0\n\n\t\t\t\tif (lagMs >= criticalThreshold) {\n\t\t\t\t\tseverity = 'critical'\n\t\t\t\t\tthreshold = criticalThreshold\n\t\t\t\t} else if (lagMs >= warnThreshold) {\n\t\t\t\t\tseverity = 'warn'\n\t\t\t\t\tthreshold = warnThreshold\n\t\t\t\t} else if (lagMs >= infoThreshold) {\n\t\t\t\t\tseverity = 'info'\n\t\t\t\t\tthreshold = infoThreshold\n\t\t\t\t}\n\n\t\t\t\tif (severity) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tonSaturationAlert({\n\t\t\t\t\t\t\treason: 'event_loop_lag',\n\t\t\t\t\t\t\tseverity,\n\t\t\t\t\t\t\tvalue: lagMs,\n\t\t\t\t\t\t\tthreshold\n\t\t\t\t\t\t})\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Callback failures must not stop monitoring.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A callback may synchronously stop the monitor. Do not leave a stray\n\t\t\t// interval timer behind after that re-entrant shutdown.\n\t\t\tscheduleNext()\n\t\t}) } catch { running = false }\n\t}\n\n\t/**\n\t * Periodic measurement\n\t */\n\tfunction scheduleMeasurement(): void {\n\n\t\tif (!running) {\n\t\t\treturn\n\t\t}\n\t\tmeasureLag()\n\t}\n\n\t/**\n\t * Calculate percentiles from samples\n\t */\n\tfunction calculatePercentiles(sorted: number[], percentile: number): number {\n\n\t\tif (sorted.length === 0) {\n\t\t\treturn 0\n\t\t}\n\n\t\tconst index = Math.ceil((percentile / 100) * sorted.length) - 1\n\t\treturn sorted[Math.max(0, index)] ?? 0\n\t}\n\n\treturn {\n\t\tstart(): void {\n\n\t\t\tif (running) {\n\t\t\t\treturn // Already started\n\t\t\t}\n\n\t\t\trunning = true\n\t\t\tscheduleMeasurement()\n\t\t},\n\t\tstop(): void {\n\n\t\t\trunning = false\n\t\t\tif (timeoutId !== null) {\n\t\t\t\tclearTimeout(timeoutId)\n\t\t\t\ttimeoutId = null\n\t\t\t}\n\t\t\tif (immediateId !== null) {\n\t\t\t\tclearImmediate(immediateId)\n\t\t\t\timmediateId = null\n\t\t\t}\n\t\t},\n\t\tgetStats(): EventLoopStats | null {\n\n\t\t\tif (lagSamples.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst sorted = [...lagSamples].sort((a, b) => a - b)\n\t\t\tconst mean = sorted.reduce((sum, val) => sum + val, 0) / sorted.length\n\n\t\t\treturn {\n\t\t\t\tmean,\n\t\t\t\tp95: calculatePercentiles(sorted, 95),\n\t\t\t\tp99: calculatePercentiles(sorted, 99),\n\t\t\t\tmax: sorted[sorted.length - 1] ?? 0,\n\t\t\t\tsampleCount: sorted.length\n\t\t\t}\n\t\t},\n\t\tgetCurrentLag(): number | null {\n\n\t\t\treturn currentLag\n\t\t}\n\t}\n}\n","/**\n * @file GC monitor for tracking garbage collection events.\n * Uses Node.js perf_hooks if available (requires --expose-gc or perf hooks).\n */\n\nimport {createPerformanceOnError} from '../../utils/on-error'\n\nimport type {\n\tGCMonitor,\n\tGCMonitorOptions,\n\tGCStats,\n\tPerformanceEntryList,\n\tPerformanceObserverConstructor,\n\tPerformanceObserverInterface,\n\tPerfHooksModule,\n\tPerfHooksModuleType\n} from './gc-monitor-types'\n\nexport type {GCMonitor, GCMonitorOptions, GCStats} from './gc-monitor-types'\n\n// Module-level cache for perf_hooks module\nlet perfHooksModuleCache: PerfHooksModuleType | null = null\nlet perfHooksLoadingPromise: Promise<void> | null = null\nconst MAX_GC_ENTRIES_PER_CALLBACK = 256\n\n/**\n * Create a GC monitor.\n * Requires Node.js with perf_hooks support (--expose-gc or perf hooks enabled).\n * Falls back to no-op if not available.\n *\n * @param options - Monitor options\n * @returns GC monitor instance\n */\nexport function createGCMonitor(options: GCMonitorOptions): GCMonitor {\n\n\tconst {\n\t\tclock,\n\t\terrors,\n\t\tonSaturationAlert,\n\t\tonPerfEvent,\n\t\tthresholds = {}\n\t} = options\n\n\tconst onError = createPerformanceOnError(errors, {\n\t\toperation: 'module-load',\n\t\tmonitor: 'gc-monitor'\n\t})\n\n\t// Check if perf_hooks is available\n\tlet perfHooks: PerfHooksModule | null = null\n\n\t// Use cached module if available\n\tif (perfHooksModuleCache && perfHooksModuleCache.PerformanceObserver) {\n\t\tconst Observer = perfHooksModuleCache.PerformanceObserver as PerformanceObserverConstructor\n\t\tperfHooks = {\n\t\t\tPerformanceObserver: Observer\n\t\t}\n\t} else {\n\t\t// Try to load perf_hooks module asynchronously (for future calls)\n\t\tif (!perfHooksLoadingPromise) {\n\t\t\tperfHooksLoadingPromise = import('perf_hooks')\n\t\t\t\t.then((module) => {\n\t\t\t\t\tperfHooksModuleCache = module\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tperfHooksModuleCache = null\n\t\t\t\t\tperfHooksLoadingPromise = null\n\t\t\t\t\tonError(error, {module: 'perf_hooks'})\n\t\t\t\t})\n\t\t}\n\t\t// For now, perfHooks will be null (no-op monitor)\n\t\t// Future calls will use the cached module\n\t}\n\n\tconst pauseTimeThresholds = {...(thresholds.pauseTime ?? {})}\n\tconst heapUsageThresholds = {...(thresholds.heapUsage ?? {})}\n\tvalidatePair(pauseTimeThresholds, 'GC pause-time')\n\tvalidatePair(heapUsageThresholds, 'GC heap-usage', 1)\n\n\tlet majorCount = 0\n\tlet minorCount = 0\n\tconst pauseTimes: number[] = []\n\tlet observer: PerformanceObserverInterface | null = null\n\tlet heapCheckIntervalId: ReturnType<typeof setInterval> | null = null\n\tlet running = false\n\n\tfunction startObserver(): void {\n\t\tif (!perfHooks || observer || !running) {\n\t\t\treturn\n\t\t}\n\t\tlet candidate: PerformanceObserverInterface | null = null\n\t\ttry {\n\t\t\tcandidate = new perfHooks.PerformanceObserver((list: PerformanceEntryList) => {\n\t\t\t\ttry {\n\t\t\t\t\tlet processed = 0\n\t\t\t\t\tfor (const entry of list.getEntries()) {\n\t\t\t\t\t\tif (processed >= MAX_GC_ENTRIES_PER_CALLBACK) {\n\t\t\t\t\t\t\tonError(new Error('GC observer callback entry limit exceeded'), {\n\t\t\t\t\t\t\t\toperation: 'gc-monitor.entry-limit'\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprocessed += 1\n\t\t\t\t\t\tif (entry.entryType === 'gc') {\n\t\t\t\t\t\t\t// Node 22+ exposes GC kind through detail; the legacy kind accessor is deprecated.\n\t\t\t\t\t\t\thandleGCEvent(entry.detail?.kind ?? 2, entry.duration)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch(error) {\n\t\t\t\t\tonError(error, {operation: 'gc-monitor.observer'})\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tcandidate.observe({entryTypes: ['gc']})\n\t\t\tobserver = candidate\n\t\t\theapCheckIntervalId = setInterval(safeCheckHeapUsage, 5000)\n\t\t\theapCheckIntervalId.unref?.()\n\t\t} catch(error) {\n\t\t\tconst partialObserver = candidate\n\t\t\tcandidate = null\n\t\t\tobserver = null\n\t\t\tif (heapCheckIntervalId !== null) {\n\t\t\t\tclearInterval(heapCheckIntervalId)\n\t\t\t\theapCheckIntervalId = null\n\t\t\t}\n\t\t\ttry { partialObserver?.disconnect() } catch(cleanupError) {\n\t\t\t\tonError(cleanupError, {operation: 'gc-monitor.start-cleanup'})\n\t\t\t}\n\t\t\trunning = false\n\t\t\tonError(error, {operation: 'gc-monitor.start'})\n\t\t}\n\t}\n\n\tif (!perfHooks && perfHooksLoadingPromise) {\n\t\tvoid perfHooksLoadingPromise.then(() => {\n\t\t\tif (!perfHooksModuleCache?.PerformanceObserver) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tperfHooks = {PerformanceObserver: perfHooksModuleCache.PerformanceObserver as PerformanceObserverConstructor}\n\t\t\tstartObserver()\n\t\t})\n\t}\n\n\t/**\n\t * Handle GC event\n\t */\n\tfunction handleGCEvent(kind: number, pauseTimeMs: number): void {\n\n\t\tif (!running) {\n\t\t\treturn\n\t\t}\n\t\tif (!Number.isFinite(pauseTimeMs) || pauseTimeMs < 0) {\n\t\t\tonError(new Error('GC pause duration must be a non-negative finite number'), {\n\t\t\t\toperation: 'gc-monitor.invalid-entry'\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\t// V8 exposes minor as 1; major and incremental collections are treated as major.\n\t\tif (kind === 1) {\n\t\t\tminorCount++\n\t\t} else {\n\t\t\tmajorCount++\n\t\t}\n\n\t\tpauseTimes.push(pauseTimeMs)\n\n\t\t// Keep only last 100 pause times\n\t\tif (pauseTimes.length > 100) {\n\t\t\tpauseTimes.shift()\n\t\t}\n\n\t\t// Emit perf event\n\t\tif (onPerfEvent) {\n\t\t\ttry {\n\t\t\t\tconst end = clock.now()\n\t\t\t\tonPerfEvent({\n\t\t\t\t\tname: `gc_${kind === 1 ? 'minor' : 'major'}`,\n\t\t\t\t\tduration: pauseTimeMs,\n\t\t\t\t\tstart: end - pauseTimeMs,\n\t\t\t\t\tend,\n\t\t\t\t\tlabels: {\n\t\t\t\t\t\tkind: kind === 1 ? 'minor' : 'major'\n\t\t\t\t\t},\n\t\t\t\t\tsource: 'runtime'\n\t\t\t\t})\n\t\t\t} catch(error) {\n\t\t\t\tonError(error, {operation: 'gc-monitor.perf-event'})\n\t\t\t}\n\t\t}\n\n\t\t// Check saturation thresholds\n\t\tif (onSaturationAlert) {\n\t\t\tlet severity: 'warn' | 'critical' | null = null\n\t\t\tlet threshold = 0\n\n\t\t\tif (pauseTimeThresholds.critical !== undefined && pauseTimeMs >= pauseTimeThresholds.critical) {\n\t\t\t\tseverity = 'critical'\n\t\t\t\tthreshold = pauseTimeThresholds.critical\n\t\t\t} else if (pauseTimeThresholds.warn !== undefined && pauseTimeMs >= pauseTimeThresholds.warn) {\n\t\t\t\tseverity = 'warn'\n\t\t\t\tthreshold = pauseTimeThresholds.warn\n\t\t\t}\n\n\t\t\tif (severity) {\n\t\t\t\ttry {\n\t\t\t\t\tonSaturationAlert({\n\t\t\t\t\t\treason: `gc_pause_${kind === 1 ? 'minor' : 'major'}`,\n\t\t\t\t\t\tseverity,\n\t\t\t\t\t\tvalue: pauseTimeMs,\n\t\t\t\t\t\tthreshold\n\t\t\t\t\t})\n\t\t\t\t} catch(error) {\n\t\t\t\t\tonError(error, {operation: 'gc-monitor.saturation-alert'})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check heap usage and emit alerts if needed\n\t */\n\tfunction checkHeapUsage(): void {\n\n\t\tif (!running) {\n\t\t\treturn\n\t\t}\n\t\tif (!onSaturationAlert) {\n\t\t\treturn\n\t\t}\n\n\t\tconst usage = process.memoryUsage()\n\t\tconst heapLimit = (usage as {heapLimit?: number}).heapLimit ?? usage.heapTotal\n\t\tconst heapUsed = usage.heapUsed\n\n\t\tif (heapLimit > 0) {\n\t\t\tconst utilization = heapUsed / heapLimit\n\t\t\tlet severity: 'warn' | 'critical' | null = null\n\t\t\tlet threshold = 0\n\n\t\t\tif (heapUsageThresholds.critical !== undefined && utilization >= heapUsageThresholds.critical) {\n\t\t\t\tseverity = 'critical'\n\t\t\t\tthreshold = heapUsageThresholds.critical\n\t\t\t} else if (heapUsageThresholds.warn !== undefined && utilization >= heapUsageThresholds.warn) {\n\t\t\t\tseverity = 'warn'\n\t\t\t\tthreshold = heapUsageThresholds.warn\n\t\t\t}\n\n\t\t\tif (severity) {\n\t\t\t\ttry {\n\t\t\t\t\tonSaturationAlert({\n\t\t\t\t\t\treason: 'heap_usage',\n\t\t\t\t\t\tseverity,\n\t\t\t\t\t\tvalue: utilization,\n\t\t\t\t\t\tthreshold\n\t\t\t\t\t})\n\t\t\t\t} catch(error) {\n\t\t\t\t\tonError(error, {operation: 'gc-monitor.saturation-alert'})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction safeCheckHeapUsage(): void {\n\t\ttry {\n\t\t\tcheckHeapUsage()\n\t\t} catch(error) {\n\t\t\tonError(error, {operation: 'gc-monitor.heap-check'})\n\t\t}\n\t}\n\n\treturn {\n\t\tstart(): void {\n\n\t\t\tif (running) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\trunning = true\n\t\t\t\tstartObserver()\n\t\t\t} catch(error) {\n\t\t\t\trunning = false\n\t\t\t\tonError(error, {operation: 'gc-monitor.start'})\n\t\t\t\t// Observer creation failed, continue as no-op\n\t\t\t}\n\t\t},\n\t\tstop(): void {\n\n\t\t\trunning = false\n\t\t\tconst activeObserver = observer\n\t\t\tobserver = null\n\t\t\ttry {\n\t\t\t\tactiveObserver?.disconnect()\n\t\t\t} catch(error) {\n\t\t\t\tonError(error, {operation: 'gc-monitor.stop'})\n\t\t\t}\n\t\t\tconst activeHeapCheckInterval = heapCheckIntervalId\n\t\t\theapCheckIntervalId = null\n\t\t\tif (activeHeapCheckInterval !== null) {\n\t\t\t\tclearInterval(activeHeapCheckInterval)\n\t\t\t}\n\t\t},\n\t\tgetStats(): GCStats {\n\n\t\t\tconst totalPauseTimeMs = pauseTimes.reduce((sum, val) => sum + val, 0)\n\t\t\tconst avgPauseTimeMs = pauseTimes.length > 0 ? totalPauseTimeMs / pauseTimes.length : 0\n\t\t\tconst maxPauseTimeMs = pauseTimes.length > 0 ? Math.max(...pauseTimes) : 0\n\n\t\t\treturn {\n\t\t\t\tmajorCount,\n\t\t\t\tminorCount,\n\t\t\t\ttotalPauseTimeMs,\n\t\t\t\tavgPauseTimeMs,\n\t\t\t\tmaxPauseTimeMs\n\t\t\t}\n\t\t},\n\t\tgetHeapUsage(): {\n\t\t\theapUsed: number\n\t\t\theapTotal: number\n\t\t\theapLimit?: number\n\t\t} | null {\n\n\t\t\tif (typeof process === 'undefined' || !process.memoryUsage) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst usage = process.memoryUsage()\n\t\t\tconst result: {\n\t\t\t\theapUsed: number\n\t\t\t\theapTotal: number\n\t\t\t\theapLimit?: number\n\t\t\t} = {\n\t\t\t\theapUsed: usage.heapUsed,\n\t\t\t\theapTotal: usage.heapTotal\n\t\t\t}\n\t\t\tconst heapLimit = (usage as {heapLimit?: number}).heapLimit\n\t\t\tif (heapLimit !== undefined) {\n\t\t\t\tresult.heapLimit = heapLimit\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t}\n}\n\nfunction validatePair(\n\tthresholds: {warn?: number; critical?: number},\n\tname: string,\n\tmax = Number.POSITIVE_INFINITY\n): void {\n\tconst values = [thresholds.warn, thresholds.critical]\n\t\t.filter((value): value is number => value !== undefined)\n\tif (!values.every((value) => Number.isFinite(value) && value >= 0 && value <= max)) {\n\t\tthrow new Error(`${name} thresholds must be finite numbers between 0 and ${max}`)\n\t}\n\tif (thresholds.warn !== undefined && thresholds.critical !== undefined && thresholds.warn > thresholds.critical) {\n\t\tthrow new Error(`${name} thresholds must satisfy warn <= critical`)\n\t}\n}\n","type OsModule = {loadavg: () => [number, number, number]}\n\nlet osModuleCache: OsModule | null = null\nlet osModuleLoadingPromise: Promise<void> | null = null\n\n/** Returns the cached Node load average and starts a safe lazy import when needed. */\nexport function getResourceLoadAverage(\n\tonError: (error: unknown, details?: Record<string, string>) => void\n): [number, number, number] | undefined {\n\tif (typeof process === 'undefined' || process.platform === 'win32') return undefined\n\ttry {\n\t\tif (osModuleCache) {\n\t\t\treturn osModuleCache.loadavg()\n\t\t}\n\t\tif (osModuleLoadingPromise === null) {\n\t\t\tosModuleLoadingPromise = import('os')\n\t\t\t\t.then((module) => { osModuleCache = {loadavg: () => {\n\t\t\t\t\tconst load = module.loadavg()\n\t\t\t\t\treturn [load[0] ?? 0, load[1] ?? 0, load[2] ?? 0]\n\t\t\t\t}} })\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tosModuleCache = null\n\t\t\t\t\tosModuleLoadingPromise = null\n\t\t\t\t\tonError(error, {module: 'os'})\n\t\t\t\t})\n\t\t}\n\t} catch {\n\t\t// Load average is optional outside Node and must not affect monitoring.\n\t}\n\treturn undefined\n}\n","/**\n * @file CPU and memory resource monitor.\n * Tracks CPU usage, memory usage, and load averages at configurable intervals.\n */\n\nimport {createPerformanceOnError} from '../../utils/on-error'\n\nimport {getResourceLoadAverage} from './resource-load-average'\nimport type {CPUStats, MemoryStats, ResourceMonitor, ResourceMonitorOptions, ResourceStats} from './resource-monitor-types'\n\nexport type {CPUStats, MemoryStats, ResourceMonitor, ResourceMonitorOptions, ResourceStats} from './resource-monitor-types'\n\n/**\n * Create a resource monitor.\n * Tracks CPU and memory usage at configurable intervals.\n *\n * @param options - Monitor options\n * @returns Resource monitor instance\n */\nexport function createResourceMonitor(options: ResourceMonitorOptions): ResourceMonitor {\n\n\tconst {\n\t\tclock,\n\t\terrors,\n\t\tintervalMs = 5000,\n\t\tonSaturationAlert,\n\t\tonPerfEvent,\n\t\tthresholds = {}\n\t} = options\n\n\tconst onError = createPerformanceOnError(errors, {\n\t\toperation: 'module-load',\n\t\tmonitor: 'resource-monitor'\n\t})\n\tif (!Number.isSafeInteger(intervalMs) || intervalMs <= 0 || intervalMs > 2_147_483_647) {\n\t\tthrow new Error('Resource monitor intervalMs must be between 1 and 2147483647')\n\t}\n\n\tconst cpuThresholds = {...(thresholds.cpu ?? {})}\n\tconst memoryThresholds = {...(thresholds.memory ?? {})}\n\tvalidateThresholds(cpuThresholds, 'CPU')\n\tvalidateThresholds(memoryThresholds, 'memory', 1)\n\n\tlet intervalId: ReturnType<typeof setInterval> | null = null\n\tlet lastCPUUsage: {user: number; system: number} | null = null\n\tlet lastCPUCollectedAt: number | null = null\n\tlet running = false\n\n\tfunction safeCollectStats(): void {\n\t\tif (!running) {\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tcollectStats()\n\t\t} catch(error) {\n\t\t\tonError(error, {operation: 'resource-monitor.tick'})\n\t\t}\n\t}\n\n\t/**\n\t * Collect and emit resource statistics\n\t */\n\tfunction collectStats(): void {\n\n\t\tif (\n\t\t\ttypeof process === 'undefined' ||\n\t\t\ttypeof process.cpuUsage !== 'function' ||\n\t\t\ttypeof process.memoryUsage !== 'function'\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst now = clock.now()\n\n\t\t// CPU usage\n\t\tconst cpuUsage = process.cpuUsage()\n\n\t\tif (lastCPUUsage) {\n\t\t\tconst elapsedMs = lastCPUCollectedAt !== null && now > lastCPUCollectedAt\n\t\t\t\t? now - lastCPUCollectedAt\n\t\t\t\t: intervalMs\n\t\t\tconst userDelta = Math.max(0, cpuUsage.user - lastCPUUsage.user)\n\t\t\tconst systemDelta = Math.max(0, cpuUsage.system - lastCPUUsage.system)\n\t\t\tconst totalDelta = userDelta + systemDelta\n\n\t\t\t// Emit CPU perf event (convert microseconds to milliseconds)\n\t\t\tif (onPerfEvent) {\n\t\t\t\ttry {\n\t\t\t\t\tonPerfEvent({\n\t\t\t\t\t\tname: 'cpu_usage',\n\t\t\t\t\t\tduration: totalDelta / 1000, // Convert to ms\n\t\t\t\t\t\tstart: now - elapsedMs,\n\t\t\t\t\t\tend: now,\n\t\t\t\t\t\tlabels: {\n\t\t\t\t\t\t\tuser: String(userDelta / 1000),\n\t\t\t\t\t\t\tsystem: String(systemDelta / 1000),\n\t\t\t\t\t\t\tutilization: String(totalDelta / (elapsedMs * 1000))\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsource: 'runtime'\n\t\t\t\t\t})\n\t\t\t\t} catch(error) {\n\t\t\t\t\tonError(error, {operation: 'resource-monitor.perf-event'})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check CPU saturation (approximate: total CPU time / interval)\n\t\t\t// This is a rough approximation\n\t\t\tconst cpuUtilization = totalDelta / (elapsedMs * 1000) // Convert to ratio\n\t\t\tif (onSaturationAlert) {\n\t\t\t\tlet severity: 'info' | 'warn' | 'critical' | null = null\n\t\t\t\tlet threshold = 0\n\n\t\t\t\tif (cpuThresholds.critical !== undefined && cpuUtilization >= cpuThresholds.critical) {\n\t\t\t\t\tseverity = 'critical'\n\t\t\t\t\tthreshold = cpuThresholds.critical\n\t\t\t\t} else if (cpuThresholds.warn !== undefined && cpuUtilization >= cpuThresholds.warn) {\n\t\t\t\t\tseverity = 'warn'\n\t\t\t\t\tthreshold = cpuThresholds.warn\n\t\t\t\t} else if (cpuThresholds.info !== undefined && cpuUtilization >= cpuThresholds.info) {\n\t\t\t\t\tseverity = 'info'\n\t\t\t\t\tthreshold = cpuThresholds.info\n\t\t\t\t}\n\n\t\t\t\tif (severity) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tonSaturationAlert({\n\t\t\t\t\t\t\treason: 'cpu_saturation',\n\t\t\t\t\t\t\tseverity,\n\t\t\t\t\t\t\tvalue: cpuUtilization,\n\t\t\t\t\t\t\tthreshold\n\t\t\t\t\t\t})\n\t\t\t\t\t} catch(error) {\n\t\t\t\t\t\tonError(error, {operation: 'resource-monitor.saturation-alert'})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlastCPUUsage = cpuUsage\n\t\tlastCPUCollectedAt = now\n\n\t\t// Memory usage\n\t\tconst memoryUsage = process.memoryUsage()\n\t\tconst memoryStats: MemoryStats = {\n\t\t\trss: memoryUsage.rss,\n\t\t\theapUsed: memoryUsage.heapUsed,\n\t\t\theapTotal: memoryUsage.heapTotal,\n\t\t\texternal: memoryUsage.external\n\t\t}\n\n\t\t// Emit memory perf event\n\t\tif (onPerfEvent) {\n\t\t\ttry {\n\t\t\t\tonPerfEvent({\n\t\t\t\t\tname: 'memory_usage',\n\t\t\t\t\tduration: 0, // Memory is a snapshot, not a duration\n\t\t\t\t\tstart: now,\n\t\t\t\t\tend: now,\n\t\t\t\t\tlabels: {\n\t\t\t\t\t\trss: String(memoryStats.rss),\n\t\t\t\t\t\theapUsed: String(memoryStats.heapUsed),\n\t\t\t\t\t\theapTotal: String(memoryStats.heapTotal),\n\t\t\t\t\t\texternal: String(memoryStats.external)\n\t\t\t\t\t},\n\t\t\t\t\tsource: 'runtime'\n\t\t\t\t})\n\t\t\t} catch(error) {\n\t\t\t\tonError(error, {operation: 'resource-monitor.perf-event'})\n\t\t\t}\n\t\t}\n\n\t\t// Check memory saturation (heap used / heap total)\n\t\tif (memoryStats.heapTotal > 0 && onSaturationAlert) {\n\t\t\tconst memoryUtilization = memoryStats.heapUsed / memoryStats.heapTotal\n\t\t\tlet severity: 'info' | 'warn' | 'critical' | null = null\n\t\t\tlet threshold = 0\n\n\t\t\tif (memoryThresholds.critical !== undefined && memoryUtilization >= memoryThresholds.critical) {\n\t\t\t\tseverity = 'critical'\n\t\t\t\tthreshold = memoryThresholds.critical\n\t\t\t} else if (memoryThresholds.warn !== undefined && memoryUtilization >= memoryThresholds.warn) {\n\t\t\t\tseverity = 'warn'\n\t\t\t\tthreshold = memoryThresholds.warn\n\t\t\t} else if (memoryThresholds.info !== undefined && memoryUtilization >= memoryThresholds.info) {\n\t\t\t\tseverity = 'info'\n\t\t\t\tthreshold = memoryThresholds.info\n\t\t\t}\n\n\t\t\tif (severity) {\n\t\t\t\ttry {\n\t\t\t\t\tonSaturationAlert({\n\t\t\t\t\t\treason: 'memory_pressure',\n\t\t\t\t\t\tseverity,\n\t\t\t\t\t\tvalue: memoryUtilization,\n\t\t\t\t\t\tthreshold\n\t\t\t\t\t})\n\t\t\t\t} catch(error) {\n\t\t\t\t\tonError(error, {operation: 'resource-monitor.saturation-alert'})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tstart(): void {\n\n\t\t\tif (intervalId !== null) {\n\t\t\t\treturn // Already started\n\t\t\t}\n\n\t\t\t// Initialize CPU usage baseline\n\t\t\tif (typeof process !== 'undefined' && typeof process.cpuUsage === 'function') {\n\t\t\t\tlastCPUUsage = process.cpuUsage()\n\t\t\t\tlastCPUCollectedAt = clock.now()\n\t\t\t}\n\n\t\t\trunning = true\n\t\t\t// Start periodic collection\n\t\t\tintervalId = setInterval(safeCollectStats, intervalMs)\n\t\t\tintervalId.unref?.()\n\t\t},\n\t\tstop(): void {\n\n\t\t\trunning = false\n\t\t\tif (intervalId !== null) {\n\t\t\t\tclearInterval(intervalId)\n\t\t\t\tintervalId = null\n\t\t\t}\n\n\t\t\tlastCPUUsage = null\n\t\t\tlastCPUCollectedAt = null\n\t\t},\n\t\tgetStats(): ResourceStats | null {\n\n\t\t\tif (\n\t\t\t\ttypeof process === 'undefined' ||\n\t\t\t\ttypeof process.cpuUsage !== 'function' ||\n\t\t\t\ttypeof process.memoryUsage !== 'function'\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst cpuUsage = process.cpuUsage()\n\t\t\tconst memoryUsage = process.memoryUsage()\n\n\t\t\tconst cpu: CPUStats = {\n\t\t\t\tuser: cpuUsage.user,\n\t\t\t\tsystem: cpuUsage.system,\n\t\t\t\ttotal: cpuUsage.user + cpuUsage.system\n\t\t\t}\n\n\t\t\tconst memory: MemoryStats = {\n\t\t\t\trss: memoryUsage.rss,\n\t\t\t\theapUsed: memoryUsage.heapUsed,\n\t\t\t\theapTotal: memoryUsage.heapTotal,\n\t\t\t\texternal: memoryUsage.external\n\t\t\t}\n\n\t\t\tconst loadAverage = getResourceLoadAverage(onError)\n\n\t\t\tconst stats: ResourceStats = {\n\t\t\t\tcpu,\n\t\t\t\tmemory\n\t\t\t}\n\t\t\tif (loadAverage) {\n\t\t\t\tstats.loadAverage = loadAverage\n\t\t\t}\n\t\t\treturn stats\n\t\t}\n\t}\n}\n\nfunction validateThresholds(\n\tthresholds: {info?: number; warn?: number; critical?: number},\n\tname: string,\n\tmax = Number.POSITIVE_INFINITY\n): void {\n\tconst ordered = [thresholds.info, thresholds.warn, thresholds.critical]\n\t\t.filter((value): value is number => value !== undefined)\n\tif (!ordered.every((value) => Number.isFinite(value) && value >= 0 && value <= max)) {\n\t\tthrow new Error(`${name} thresholds must be finite numbers between 0 and ${max}`)\n\t}\n\tif (\n\t\t(thresholds.info !== undefined && thresholds.warn !== undefined && thresholds.info > thresholds.warn) ||\n\t\t(thresholds.warn !== undefined && thresholds.critical !== undefined && thresholds.warn > thresholds.critical) ||\n\t\t(thresholds.info !== undefined && thresholds.critical !== undefined && thresholds.info > thresholds.critical)\n\t) {\n\t\tthrow new Error(`${name} thresholds must satisfy info <= warn <= critical`)\n\t}\n}\n","/**\n * @file Error boundary for performance monitoring operations.\n * Wraps monitor operations to prevent crashes.\n * Uses engines' error boundary utilities for consistency.\n */\n\nimport type {Errors} from '@ooopsstudio/core/ports/errors'\n\nimport {createPerformanceOnError} from './on-error'\nimport {isRuntimePromise} from './safe-object'\n\n/**\n * Wrap a function with error boundary.\n * Catches errors and reports them without throwing.\n *\n * @param fn - Function to wrap\n * @param errors - Optional error handler\n * @param context - Optional context for error reporting\n * @returns Wrapped function\n */\nexport function withErrorBoundary<T extends (...args: unknown[]) => unknown>(\n\tfn: T,\n\terrors?: Errors,\n\tcontext?: Record<string, string>\n): T {\n\n\tconst onError = createPerformanceOnError(errors, {\n\t\tstage: 'monitor',\n\t\t...(context ? {step: Object.values(context)[0]} : {})\n\t})\n\n\treturn ((...args: Parameters<T>) => {\n\t\ttry {\n\t\t\treturn fn(...args)\n\t\t} catch(error) {\n\t\t\tonError(error)\n\t\t\t// Return undefined instead of throwing\n\t\t\treturn undefined as ReturnType<T>\n\t\t}\n\t}) as T\n}\n\n/**\n * Wrap an async function with error boundary.\n *\n * @param fn - Async function to wrap\n * @param errors - Optional error handler\n * @param context - Optional context for error reporting\n * @returns Wrapped async function\n */\nexport function withAsyncErrorBoundary<T extends (...args: unknown[]) => Promise<unknown>>(\n\tfn: T,\n\terrors?: Errors,\n\tcontext?: Record<string, string>\n): T {\n\n\tconst onError = createPerformanceOnError(errors, {\n\t\tstage: 'monitor',\n\t\t...(context ? {step: Object.values(context)[0]} : {})\n\t})\n\n\treturn ((...args: Parameters<T>) => {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tconst result = fn(...args)\n\t\t\tif (!isRuntimePromise(result)) throw new TypeError('Performance async boundary requires a native Promise')\n\t\t\treturn result\n\t\t}).catch((error) => {\n\t\t\tonError(error)\n\t\t\treturn undefined\n\t\t}) as Promise<Awaited<ReturnType<T>> | undefined>\n\t}) as T\n}\n","import type {PerfEvent, SaturationAlert} from '@ooopsstudio/core/contracts/performance'\nimport type {Errors} from '@ooopsstudio/core/ports/errors'\n\nimport {createEventLoopMonitor, type EventLoopMonitor} from '../../features/core/event-loop-monitor'\nimport {createGCMonitor, type GCMonitor} from '../../features/core/gc-monitor'\nimport {createResourceMonitor, type ResourceMonitor} from '../../features/core/resource-monitor'\nimport {withErrorBoundary} from '../../utils/error-boundary'\nimport type {HighResClock} from '../clock'\n\nexport interface Monitors {\n\teventLoopMonitor?: EventLoopMonitor\n\tgcMonitor?: GCMonitor\n\tresourceMonitor?: ResourceMonitor\n}\n\nexport interface MonitorsOptions {\n\tclock: HighResClock\n\tonPerfEvent: (event: PerfEvent) => void\n\tonSaturationAlert?: (alert: SaturationAlert) => void\n\terrors?: Errors\n\tenableEventLoopMonitor: boolean\n\tenableGCMonitor: boolean\n\tenableResourceMonitor: boolean\n}\n\nexport function createMonitors(options: MonitorsOptions): Monitors {\n\tconst monitors: Monitors = {}\n\tconst safelyEmitEvent = (event: PerfEvent) => {\n\t\ttry { options.onPerfEvent(event) } catch { /* monitors never break the host */ }\n\t}\n\tconst safelyEmitAlert = (alert: SaturationAlert) => {\n\t\ttry { options.onSaturationAlert?.(alert) } catch { /* observers are isolated */ }\n\t}\n\ttry {\n\t\tif (options.enableEventLoopMonitor) {\n\t\t\tmonitors.eventLoopMonitor = createEventLoopMonitor({\n\t\t\t\tclock: options.clock,\n\t\t\t\tonPerfEvent: safelyEmitEvent,\n\t\t\t\tonSaturationAlert: safelyEmitAlert\n\t\t\t})\n\t\t\twithErrorBoundary(() => monitors.eventLoopMonitor?.start(), options.errors, {operation: 'eventLoopMonitor.start'})()\n\t\t}\n\t\tif (options.enableGCMonitor) {\n\t\t\tmonitors.gcMonitor = createGCMonitor({\n\t\t\t\tclock: options.clock,\n\t\t\t\t...(options.errors ? {errors: options.errors} : {}),\n\t\t\t\tonPerfEvent: safelyEmitEvent,\n\t\t\t\tonSaturationAlert: safelyEmitAlert\n\t\t\t})\n\t\t\twithErrorBoundary(() => monitors.gcMonitor?.start(), options.errors, {operation: 'gcMonitor.start'})()\n\t\t}\n\t\tif (options.enableResourceMonitor) {\n\t\t\tmonitors.resourceMonitor = createResourceMonitor({\n\t\t\t\tclock: options.clock,\n\t\t\t\t...(options.errors ? {errors: options.errors} : {}),\n\t\t\t\tonPerfEvent: safelyEmitEvent,\n\t\t\t\tonSaturationAlert: safelyEmitAlert\n\t\t\t})\n\t\t\twithErrorBoundary(() => monitors.resourceMonitor?.start(), options.errors, {operation: 'resourceMonitor.start'})()\n\t\t}\n\t} catch(error) {\n\t\tstopAllMonitors(monitors)\n\t\tthrow error\n\t}\n\treturn monitors\n}\n\nexport function stopAllMonitors(monitors: Monitors): void {\n\ttry { monitors.eventLoopMonitor?.stop() } catch { /* cleanup continues */ }\n\ttry { monitors.gcMonitor?.stop() } catch { /* cleanup continues */ }\n\ttry { monitors.resourceMonitor?.stop() } catch { /* cleanup continues */ }\n}\n"]}
@@ -0,0 +1,247 @@
1
+ // src/performance/features/db/n1-patterns.ts
2
+ var firstString = (...values) => values.find((value) => typeof value === "string");
3
+ var queryCollection = (event) => firstString(event.dbMetadata?.collection, event.dbMetadata?.table, event.labels?.collection);
4
+ var queryMethod = (event) => firstString(event.dbMetadata?.method, event.dbMetadata?.operation, event.labels?.method);
5
+ var normalizeQuerySignature = (event) => {
6
+ const parts = [event.name];
7
+ const collection = queryCollection(event);
8
+ const method = queryMethod(event);
9
+ if (collection) parts.push(`collection:${collection}`);
10
+ if (method) parts.push(`method:${method}`);
11
+ if (typeof event.dbMetadata?.queryHash === "string") parts.push(`query_hash:${event.dbMetadata.queryHash}`);
12
+ if (event.labels?.filter_type) parts.push(`filter_type:${event.labels.filter_type}`);
13
+ return parts.sort().join("|");
14
+ };
15
+ var cloneN1Event = (event) => {
16
+ const bounded = (value) => value?.slice(0, 128);
17
+ return {
18
+ name: event.name,
19
+ duration: event.duration,
20
+ start: event.start,
21
+ end: event.end,
22
+ source: event.source,
23
+ dbMetadata: {
24
+ collection: bounded(queryCollection(event)),
25
+ operation: bounded(queryMethod(event)),
26
+ queryHash: bounded(event.dbMetadata?.queryHash)
27
+ },
28
+ labels: { filter_type: bounded(event.labels?.filter_type) ?? "" }
29
+ };
30
+ };
31
+ var cloneN1Pattern = (pattern) => ({
32
+ type: pattern.type,
33
+ duplicateCount: pattern.duplicateCount,
34
+ querySignature: pattern.querySignature,
35
+ ...pattern.collection ? { collection: pattern.collection } : {},
36
+ ...pattern.method ? { method: pattern.method } : {},
37
+ timeWindow: pattern.timeWindow,
38
+ ...pattern.suggestion ? { suggestion: pattern.suggestion } : {}
39
+ });
40
+ var groupBySignature = (events) => {
41
+ const signatures = /* @__PURE__ */ new Map();
42
+ for (const event of events) {
43
+ if (!event.name.startsWith("db.")) continue;
44
+ const signature = normalizeQuerySignature(event);
45
+ const matchingEvents = signatures.get(signature) ?? [];
46
+ matchingEvents.push(event);
47
+ signatures.set(signature, matchingEvents);
48
+ }
49
+ return signatures;
50
+ };
51
+ var detectSignaturePatterns = (events, options, type, knownFingerprints) => {
52
+ const patterns = [];
53
+ const maximumWindow = options.timeWindow * (type === "identical-queries" ? 1 : 10);
54
+ for (const [signature, matchingEvents] of groupBySignature(events)) {
55
+ if (matchingEvents.length < options.minDuplicates) continue;
56
+ if (knownFingerprints?.has(`${type}:${signature}`)) continue;
57
+ const sortedEvents = [...matchingEvents].sort((a, b) => a.start - b.start);
58
+ const firstEvent = sortedEvents[0];
59
+ const lastEvent = sortedEvents.at(-1);
60
+ if (!firstEvent || !lastEvent) continue;
61
+ const eventWindow = lastEvent.end - firstEvent.start;
62
+ if (eventWindow > maximumWindow) continue;
63
+ if (type === "repeated-queries" && eventWindow <= options.timeWindow) continue;
64
+ const collection = queryCollection(firstEvent);
65
+ const method = queryMethod(firstEvent);
66
+ patterns.push({
67
+ type,
68
+ duplicateCount: matchingEvents.length,
69
+ querySignature: signature,
70
+ ...collection ? { collection } : {},
71
+ ...method ? { method } : {},
72
+ timeWindow: eventWindow,
73
+ events: matchingEvents,
74
+ suggestion: type === "identical-queries" ? `Consider batching ${matchingEvents.length} identical queries into a single request` : `Consider caching results for ${matchingEvents.length} repeated queries`
75
+ });
76
+ }
77
+ return patterns;
78
+ };
79
+ var detectQueryWaterfall = (events, options, knownFingerprints) => {
80
+ const dbEvents = events.filter((event) => event.name.startsWith("db.")).sort((a, b) => a.start - b.start);
81
+ if (dbEvents.length < options.minDuplicates) return [];
82
+ const collections = dbEvents.map(queryCollection);
83
+ const methods = dbEvents.map(queryMethod);
84
+ const sequentialBreaks = new Array(dbEvents.length).fill(0);
85
+ for (let index = 1; index < dbEvents.length; index += 1) {
86
+ sequentialBreaks[index] = sequentialBreaks[index - 1] + (dbEvents[index].start < dbEvents[index - 1].end ? 1 : 0);
87
+ }
88
+ const collectionCounts = /* @__PURE__ */ new Map();
89
+ const methodCounts = /* @__PURE__ */ new Map();
90
+ const adjust = (counts, value, delta) => {
91
+ if (!value) return;
92
+ const next = (counts.get(value) ?? 0) + delta;
93
+ if (next === 0) counts.delete(value);
94
+ else counts.set(value, next);
95
+ };
96
+ for (let index = 0; index < options.minDuplicates; index += 1) {
97
+ adjust(collectionCounts, collections[index], 1);
98
+ adjust(methodCounts, methods[index], 1);
99
+ }
100
+ for (let index = 0; index <= dbEvents.length - options.minDuplicates; index += 1) {
101
+ const endIndex = index + options.minDuplicates - 1;
102
+ const firstEvent = dbEvents[index];
103
+ const lastEvent = dbEvents[endIndex];
104
+ if (!firstEvent || !lastEvent) continue;
105
+ const sequentialBreakCount = sequentialBreaks[endIndex] - sequentialBreaks[index];
106
+ const windowDuration = lastEvent.end - firstEvent.start;
107
+ if (sequentialBreakCount === 0 && windowDuration <= options.timeWindow * 2 && collectionCounts.size === 1 && methodCounts.size === 1) {
108
+ const collection = queryCollection(firstEvent);
109
+ const method = queryMethod(firstEvent);
110
+ const signature = `${collection ?? "unknown"}:${method ?? "unknown"}`;
111
+ if (!knownFingerprints?.has(`query-waterfall:${signature}`)) {
112
+ return [{
113
+ type: "query-waterfall",
114
+ duplicateCount: options.minDuplicates,
115
+ querySignature: signature,
116
+ ...collection ? { collection } : {},
117
+ ...method ? { method } : {},
118
+ timeWindow: windowDuration,
119
+ events: dbEvents.slice(index, endIndex + 1),
120
+ suggestion: `Consider batching ${options.minDuplicates} sequential queries into a single request with filters`
121
+ }];
122
+ }
123
+ }
124
+ adjust(collectionCounts, collections[index], -1);
125
+ adjust(methodCounts, methods[index], -1);
126
+ adjust(collectionCounts, collections[endIndex + 1], 1);
127
+ adjust(methodCounts, methods[endIndex + 1], 1);
128
+ }
129
+ return [];
130
+ };
131
+ var detectOverFetching = (events, options, knownFingerprints) => {
132
+ const collections = /* @__PURE__ */ new Map();
133
+ for (const event of events) {
134
+ const collection = queryCollection(event);
135
+ if (!event.name.startsWith("db.") || !collection) continue;
136
+ const matchingEvents = collections.get(collection) ?? [];
137
+ matchingEvents.push(event);
138
+ collections.set(collection, matchingEvents);
139
+ }
140
+ const patterns = [];
141
+ for (const [collection, matchingEvents] of collections) {
142
+ if (matchingEvents.length < options.minDuplicates) continue;
143
+ if (knownFingerprints?.has(`over-fetching:collection:${collection}`)) continue;
144
+ const sortedEvents = [...matchingEvents].sort((a, b) => a.start - b.start);
145
+ const firstEvent = sortedEvents[0];
146
+ const lastEvent = sortedEvents.at(-1);
147
+ if (!firstEvent || !lastEvent) continue;
148
+ const eventWindow = lastEvent.end - firstEvent.start;
149
+ if (eventWindow > options.timeWindow) continue;
150
+ patterns.push({
151
+ type: "over-fetching",
152
+ duplicateCount: matchingEvents.length,
153
+ querySignature: `collection:${collection}`,
154
+ collection,
155
+ timeWindow: eventWindow,
156
+ events: matchingEvents,
157
+ suggestion: `Consider consolidating ${matchingEvents.length} queries to collection "${collection}"`
158
+ });
159
+ }
160
+ return patterns;
161
+ };
162
+ var detectN1Patterns = (events, options, knownFingerprints) => [
163
+ ...detectSignaturePatterns(events, options, "identical-queries", knownFingerprints),
164
+ ...detectSignaturePatterns(events, options, "repeated-queries", knownFingerprints),
165
+ ...detectQueryWaterfall(events, options, knownFingerprints),
166
+ ...detectOverFetching(events, options, knownFingerprints)
167
+ ];
168
+
169
+ // src/performance/features/db/n1-detector.ts
170
+ var MAX_PATTERNS = 10;
171
+ function createN1Detector(options) {
172
+ const {
173
+ timeWindowMs = 1e3,
174
+ minDuplicates = 3,
175
+ maxTrackedTraces = 100,
176
+ maxEventsPerTrace = 100,
177
+ enabled
178
+ } = options;
179
+ if (enabled !== true) throw new Error("N+1 detection requires enabled: true");
180
+ if (!Number.isFinite(timeWindowMs) || timeWindowMs <= 0) {
181
+ throw new Error("timeWindowMs must be a positive finite number");
182
+ }
183
+ if (!Number.isInteger(minDuplicates) || minDuplicates < 2) {
184
+ throw new Error("minDuplicates must be an integer of at least 2");
185
+ }
186
+ if (!Number.isInteger(maxTrackedTraces) || maxTrackedTraces <= 0 || maxTrackedTraces > 1e3) {
187
+ throw new Error("maxTrackedTraces must be 1..1000");
188
+ }
189
+ if (!Number.isInteger(maxEventsPerTrace) || maxEventsPerTrace < minDuplicates || maxEventsPerTrace > 256) {
190
+ throw new Error("maxEventsPerTrace must be minDuplicates..256");
191
+ }
192
+ if (maxTrackedTraces * maxEventsPerTrace > 1e4) {
193
+ throw new Error("N+1 detection supports at most 10000 retained events");
194
+ }
195
+ const traces = /* @__PURE__ */ new Map();
196
+ const detectionOptions = { timeWindow: timeWindowMs, minDuplicates };
197
+ const cleanupIntervalMs = Math.max(1e3, Math.min(timeWindowMs * 10, 6e4));
198
+ let nextCleanupAt = Number.NEGATIVE_INFINITY;
199
+ const validTraceId = (value) => typeof value === "string" && /^[0-9a-f]{32}$/i.test(value) && !/^0{32}$/.test(value);
200
+ const prune = (timestamp) => {
201
+ if (timestamp >= nextCleanupAt) {
202
+ for (const [traceId, state] of traces) {
203
+ if (timestamp - state.lastSeen > timeWindowMs * 10) traces.delete(traceId);
204
+ }
205
+ nextCleanupAt = timestamp + cleanupIntervalMs;
206
+ }
207
+ };
208
+ return {
209
+ check(event) {
210
+ if (!enabled || !event.name.startsWith("db.") || !validTraceId(event.traceId)) return [];
211
+ prune(event.end);
212
+ let state = traces.get(event.traceId);
213
+ if (!state) {
214
+ while (traces.size >= maxTrackedTraces) {
215
+ const oldest = traces.keys().next().value;
216
+ if (!oldest) break;
217
+ traces.delete(oldest);
218
+ }
219
+ state = { events: [], fingerprints: /* @__PURE__ */ new Set(), lastSeen: event.end };
220
+ traces.set(event.traceId, state);
221
+ }
222
+ state.lastSeen = Math.max(state.lastSeen, event.end);
223
+ state.events.push(cloneN1Event(event));
224
+ if (state.events.length > maxEventsPerTrace) state.events.shift();
225
+ const fresh = [];
226
+ for (const pattern of detectN1Patterns(state.events, detectionOptions, state.fingerprints)) {
227
+ const fingerprint = `${pattern.type}:${pattern.querySignature}`;
228
+ if (state.fingerprints.has(fingerprint)) continue;
229
+ if (state.fingerprints.size >= MAX_PATTERNS) break;
230
+ state.fingerprints.add(fingerprint);
231
+ fresh.push(cloneN1Pattern(pattern));
232
+ }
233
+ return fresh;
234
+ },
235
+ detectPatterns(events) {
236
+ return detectN1Patterns(events, detectionOptions).map(cloneN1Pattern);
237
+ },
238
+ reset() {
239
+ traces.clear();
240
+ nextCleanupAt = Number.NEGATIVE_INFINITY;
241
+ }
242
+ };
243
+ }
244
+
245
+ export { createN1Detector };
246
+ //# sourceMappingURL=n1-detector-6IQ2DINP.js.map
247
+ //# sourceMappingURL=n1-detector-6IQ2DINP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/performance/features/db/n1-patterns.ts","../src/performance/features/db/n1-detector.ts"],"names":[],"mappings":"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","file":"n1-detector-6IQ2DINP.js","sourcesContent":["import type {N1Pattern, PerfEvent} from '@ooopsstudio/core/contracts/performance'\n\nexport interface N1PatternDetectionOptions {\n\ttimeWindow: number\n\tminDuplicates: number\n}\n\ntype DetectedN1Pattern = N1Pattern & {events: readonly PerfEvent[]}\n\nconst firstString = (...values: unknown[]): string | undefined =>\n\tvalues.find((value): value is string => typeof value === 'string')\n\nconst queryCollection = (event: PerfEvent): string | undefined =>\n\tfirstString(event.dbMetadata?.collection, event.dbMetadata?.table, event.labels?.collection)\n\nconst queryMethod = (event: PerfEvent): string | undefined =>\n\tfirstString(event.dbMetadata?.method, event.dbMetadata?.operation, event.labels?.method)\n\nconst normalizeQuerySignature = (event: PerfEvent): string => {\n\tconst parts: string[] = [event.name]\n\tconst collection = queryCollection(event)\n\tconst method = queryMethod(event)\n\tif (collection) parts.push(`collection:${collection}`)\n\tif (method) parts.push(`method:${method}`)\n\tif (typeof event.dbMetadata?.queryHash === 'string') parts.push(`query_hash:${event.dbMetadata.queryHash}`)\n\tif (event.labels?.filter_type) parts.push(`filter_type:${event.labels.filter_type}`)\n\treturn parts.sort().join('|')\n}\n\nexport const cloneN1Event = (event: PerfEvent): PerfEvent => {\n\tconst bounded = (value: string | undefined) => value?.slice(0, 128)\n\treturn {\n\t\tname: event.name,\n\t\tduration: event.duration,\n\t\tstart: event.start,\n\t\tend: event.end,\n\t\tsource: event.source,\n\t\tdbMetadata: {\n\t\t\tcollection: bounded(queryCollection(event)),\n\t\t\toperation: bounded(queryMethod(event)),\n\t\t\tqueryHash: bounded(event.dbMetadata?.queryHash)\n\t\t},\n\t\tlabels: {filter_type: bounded(event.labels?.filter_type) ?? ''}\n\t}\n}\n\nexport const cloneN1Pattern = (pattern: DetectedN1Pattern): N1Pattern => ({\n\ttype: pattern.type,\n\tduplicateCount: pattern.duplicateCount,\n\tquerySignature: pattern.querySignature,\n\t...(pattern.collection ? {collection: pattern.collection} : {}),\n\t...(pattern.method ? {method: pattern.method} : {}),\n\ttimeWindow: pattern.timeWindow,\n\t...(pattern.suggestion ? {suggestion: pattern.suggestion} : {})\n})\n\nconst groupBySignature = (events: readonly PerfEvent[]) => {\n\tconst signatures = new Map<string, PerfEvent[]>()\n\tfor (const event of events) {\n\t\tif (!event.name.startsWith('db.')) continue\n\t\tconst signature = normalizeQuerySignature(event)\n\t\tconst matchingEvents = signatures.get(signature) ?? []\n\t\tmatchingEvents.push(event)\n\t\tsignatures.set(signature, matchingEvents)\n\t}\n\treturn signatures\n}\n\nconst detectSignaturePatterns = (\n\tevents: readonly PerfEvent[],\n\toptions: N1PatternDetectionOptions,\n\ttype: Extract<N1Pattern['type'], 'identical-queries' | 'repeated-queries'>,\n\tknownFingerprints?: ReadonlySet<string>\n): DetectedN1Pattern[] => {\n\tconst patterns: DetectedN1Pattern[] = []\n\tconst maximumWindow = options.timeWindow * (type === 'identical-queries' ? 1 : 10)\n\tfor (const [signature, matchingEvents] of groupBySignature(events)) {\n\t\tif (matchingEvents.length < options.minDuplicates) continue\n\t\tif (knownFingerprints?.has(`${type}:${signature}`)) continue\n\t\tconst sortedEvents = [...matchingEvents].sort((a, b) => a.start - b.start)\n\t\tconst firstEvent = sortedEvents[0]\n\t\tconst lastEvent = sortedEvents.at(-1)\n\t\tif (!firstEvent || !lastEvent) continue\n\t\tconst eventWindow = lastEvent.end - firstEvent.start\n\t\tif (eventWindow > maximumWindow) continue\n\t\tif (type === 'repeated-queries' && eventWindow <= options.timeWindow) continue\n\t\tconst collection = queryCollection(firstEvent)\n\t\tconst method = queryMethod(firstEvent)\n\t\tpatterns.push({\n\t\t\ttype,\n\t\t\tduplicateCount: matchingEvents.length,\n\t\t\tquerySignature: signature,\n\t\t\t...(collection ? {collection} : {}),\n\t\t\t...(method ? {method} : {}),\n\t\t\ttimeWindow: eventWindow,\n\t\t\tevents: matchingEvents,\n\t\t\tsuggestion: type === 'identical-queries'\n\t\t\t\t? `Consider batching ${matchingEvents.length} identical queries into a single request`\n\t\t\t\t: `Consider caching results for ${matchingEvents.length} repeated queries`\n\t\t})\n\t}\n\treturn patterns\n}\n\nconst detectQueryWaterfall = (\n\tevents: readonly PerfEvent[],\n\toptions: N1PatternDetectionOptions,\n\tknownFingerprints?: ReadonlySet<string>\n): DetectedN1Pattern[] => {\n\tconst dbEvents = events.filter((event) => event.name.startsWith('db.')).sort((a, b) => a.start - b.start)\n\tif (dbEvents.length < options.minDuplicates) return []\n\tconst collections = dbEvents.map(queryCollection)\n\tconst methods = dbEvents.map(queryMethod)\n\tconst sequentialBreaks = new Array<number>(dbEvents.length).fill(0)\n\tfor (let index = 1; index < dbEvents.length; index += 1) {\n\t\tsequentialBreaks[index] = sequentialBreaks[index - 1]!\n\t\t\t+ (dbEvents[index]!.start < dbEvents[index - 1]!.end ? 1 : 0)\n\t}\n\tconst collectionCounts = new Map<string, number>()\n\tconst methodCounts = new Map<string, number>()\n\tconst adjust = (counts: Map<string, number>, value: string | undefined, delta: 1 | -1) => {\n\t\tif (!value) return\n\t\tconst next = (counts.get(value) ?? 0) + delta\n\t\tif (next === 0) counts.delete(value)\n\t\telse counts.set(value, next)\n\t}\n\tfor (let index = 0; index < options.minDuplicates; index += 1) {\n\t\tadjust(collectionCounts, collections[index], 1)\n\t\tadjust(methodCounts, methods[index], 1)\n\t}\n\tfor (let index = 0; index <= dbEvents.length - options.minDuplicates; index += 1) {\n\t\tconst endIndex = index + options.minDuplicates - 1\n\t\tconst firstEvent = dbEvents[index]\n\t\tconst lastEvent = dbEvents[endIndex]\n\t\tif (!firstEvent || !lastEvent) continue\n\t\tconst sequentialBreakCount = sequentialBreaks[endIndex]! - sequentialBreaks[index]!\n\t\tconst windowDuration = lastEvent.end - firstEvent.start\n\t\tif (sequentialBreakCount === 0 && windowDuration <= options.timeWindow * 2\n\t\t\t&& collectionCounts.size === 1 && methodCounts.size === 1) {\n\t\t\tconst collection = queryCollection(firstEvent)\n\t\t\tconst method = queryMethod(firstEvent)\n\t\t\tconst signature = `${collection ?? 'unknown'}:${method ?? 'unknown'}`\n\t\t\tif (!knownFingerprints?.has(`query-waterfall:${signature}`)) {\n\t\t\t\treturn [{\n\t\t\t\t\ttype: 'query-waterfall',\n\t\t\t\t\tduplicateCount: options.minDuplicates,\n\t\t\t\t\tquerySignature: signature,\n\t\t\t\t\t...(collection ? {collection} : {}),\n\t\t\t\t\t...(method ? {method} : {}),\n\t\t\t\t\ttimeWindow: windowDuration,\n\t\t\t\t\tevents: dbEvents.slice(index, endIndex + 1),\n\t\t\t\t\tsuggestion: `Consider batching ${options.minDuplicates} sequential queries into a single request with filters`\n\t\t\t\t}]\n\t\t\t}\n\t\t}\n\t\tadjust(collectionCounts, collections[index], -1)\n\t\tadjust(methodCounts, methods[index], -1)\n\t\tadjust(collectionCounts, collections[endIndex + 1], 1)\n\t\tadjust(methodCounts, methods[endIndex + 1], 1)\n\t}\n\treturn []\n}\n\nconst detectOverFetching = (\n\tevents: readonly PerfEvent[],\n\toptions: N1PatternDetectionOptions,\n\tknownFingerprints?: ReadonlySet<string>\n): DetectedN1Pattern[] => {\n\tconst collections = new Map<string, PerfEvent[]>()\n\tfor (const event of events) {\n\t\tconst collection = queryCollection(event)\n\t\tif (!event.name.startsWith('db.') || !collection) continue\n\t\tconst matchingEvents = collections.get(collection) ?? []\n\t\tmatchingEvents.push(event)\n\t\tcollections.set(collection, matchingEvents)\n\t}\n\tconst patterns: DetectedN1Pattern[] = []\n\tfor (const [collection, matchingEvents] of collections) {\n\t\tif (matchingEvents.length < options.minDuplicates) continue\n\t\tif (knownFingerprints?.has(`over-fetching:collection:${collection}`)) continue\n\t\tconst sortedEvents = [...matchingEvents].sort((a, b) => a.start - b.start)\n\t\tconst firstEvent = sortedEvents[0]\n\t\tconst lastEvent = sortedEvents.at(-1)\n\t\tif (!firstEvent || !lastEvent) continue\n\t\tconst eventWindow = lastEvent.end - firstEvent.start\n\t\tif (eventWindow > options.timeWindow) continue\n\t\tpatterns.push({\n\t\t\ttype: 'over-fetching',\n\t\t\tduplicateCount: matchingEvents.length,\n\t\t\tquerySignature: `collection:${collection}`,\n\t\t\tcollection,\n\t\t\ttimeWindow: eventWindow,\n\t\t\tevents: matchingEvents,\n\t\t\tsuggestion: `Consider consolidating ${matchingEvents.length} queries to collection \"${collection}\"`\n\t\t})\n\t}\n\treturn patterns\n}\n\nexport const detectN1Patterns = (\n\tevents: readonly PerfEvent[],\n\toptions: N1PatternDetectionOptions,\n\tknownFingerprints?: ReadonlySet<string>\n): DetectedN1Pattern[] => [\n\t...detectSignaturePatterns(events, options, 'identical-queries', knownFingerprints),\n\t...detectSignaturePatterns(events, options, 'repeated-queries', knownFingerprints),\n\t...detectQueryWaterfall(events, options, knownFingerprints),\n\t...detectOverFetching(events, options, knownFingerprints)\n]\n","import type {N1Pattern, PerfEvent} from '@ooopsstudio/core/contracts/performance'\n\nimport {cloneN1Event, cloneN1Pattern, detectN1Patterns} from './n1-patterns'\n\nexport interface N1DetectorOptions {\n\ttimeWindowMs?: number\n\tminDuplicates?: number\n\tmaxTrackedTraces?: number\n\tmaxEventsPerTrace?: number\n\tenabled: true\n}\n\nexport interface N1Detector {\n\tcheck(event: PerfEvent): N1Pattern[]\n\tdetectPatterns(events: PerfEvent[]): N1Pattern[]\n\treset(): void\n}\n\nconst MAX_PATTERNS = 10\n\nexport function createN1Detector(options: N1DetectorOptions): N1Detector {\n\tconst {\n\t\ttimeWindowMs = 1_000,\n\t\tminDuplicates = 3,\n\t\tmaxTrackedTraces = 100,\n\t\tmaxEventsPerTrace = 100,\n\t\tenabled\n\t} = options\n\tif (enabled !== true) throw new Error('N+1 detection requires enabled: true')\n\tif (!Number.isFinite(timeWindowMs) || timeWindowMs <= 0) {\n\t\tthrow new Error('timeWindowMs must be a positive finite number')\n\t}\n\tif (!Number.isInteger(minDuplicates) || minDuplicates < 2) {\n\t\tthrow new Error('minDuplicates must be an integer of at least 2')\n\t}\n\tif (!Number.isInteger(maxTrackedTraces) || maxTrackedTraces <= 0 || maxTrackedTraces > 1_000) {\n\t\tthrow new Error('maxTrackedTraces must be 1..1000')\n\t}\n\tif (!Number.isInteger(maxEventsPerTrace) || maxEventsPerTrace < minDuplicates || maxEventsPerTrace > 256) {\n\t\tthrow new Error('maxEventsPerTrace must be minDuplicates..256')\n\t}\n\tif (maxTrackedTraces * maxEventsPerTrace > 10_000) {\n\t\tthrow new Error('N+1 detection supports at most 10000 retained events')\n\t}\n\n\tconst traces = new Map<string, {events: PerfEvent[]; fingerprints: Set<string>; lastSeen: number}>()\n\tconst detectionOptions = {timeWindow: timeWindowMs, minDuplicates}\n\tconst cleanupIntervalMs = Math.max(1_000, Math.min(timeWindowMs * 10, 60_000))\n\tlet nextCleanupAt = Number.NEGATIVE_INFINITY\n\tconst validTraceId = (value: unknown): value is string =>\n\t\ttypeof value === 'string' && /^[0-9a-f]{32}$/i.test(value) && !/^0{32}$/.test(value)\n\tconst prune = (timestamp: number) => {\n\t\tif (timestamp >= nextCleanupAt) {\n\t\t\tfor (const [traceId, state] of traces) {\n\t\t\t\tif (timestamp - state.lastSeen > timeWindowMs * 10) traces.delete(traceId)\n\t\t\t}\n\t\t\tnextCleanupAt = timestamp + cleanupIntervalMs\n\t\t}\n\t}\n\n\treturn {\n\t\tcheck(event) {\n\t\t\tif (!enabled || !event.name.startsWith('db.') || !validTraceId(event.traceId)) return []\n\t\t\tprune(event.end)\n\t\t\tlet state = traces.get(event.traceId)\n\t\t\tif (!state) {\n\t\t\t\twhile (traces.size >= maxTrackedTraces) {\n\t\t\t\t\tconst oldest = traces.keys().next().value as string | undefined\n\t\t\t\t\tif (!oldest) break\n\t\t\t\t\ttraces.delete(oldest)\n\t\t\t\t}\n\t\t\t\tstate = {events: [], fingerprints: new Set(), lastSeen: event.end}\n\t\t\t\ttraces.set(event.traceId, state)\n\t\t\t}\n\t\t\tstate.lastSeen = Math.max(state.lastSeen, event.end)\n\t\t\tstate.events.push(cloneN1Event(event))\n\t\t\tif (state.events.length > maxEventsPerTrace) state.events.shift()\n\t\t\tconst fresh: N1Pattern[] = []\n\t\t\tfor (const pattern of detectN1Patterns(state.events, detectionOptions, state.fingerprints)) {\n\t\t\t\tconst fingerprint = `${pattern.type}:${pattern.querySignature}`\n\t\t\t\tif (state.fingerprints.has(fingerprint)) continue\n\t\t\t\tif (state.fingerprints.size >= MAX_PATTERNS) break\n\t\t\t\tstate.fingerprints.add(fingerprint)\n\t\t\t\tfresh.push(cloneN1Pattern(pattern))\n\t\t\t}\n\t\t\treturn fresh\n\t\t},\n\t\tdetectPatterns(events) {\n\t\t\treturn detectN1Patterns(events, detectionOptions).map(cloneN1Pattern)\n\t\t},\n\t\treset() {\n\t\t\ttraces.clear()\n\t\t\tnextCleanupAt = Number.NEGATIVE_INFINITY\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { BudgetViolation, SaturationAlert, N1Pattern, PerfEvent } from '@ooopsstudio/core/contracts/performance';
2
+ import { M as ManagedPerformance } from './ports-DwUYdKj-.js';
3
+ import '@ooopsstudio/core/ports/performance';
4
+
5
+ type PerformanceObservabilityEvent = {
6
+ readonly kind: 'budget_violation';
7
+ readonly violation: Readonly<BudgetViolation>;
8
+ } | {
9
+ readonly kind: 'saturation_alert';
10
+ readonly alert: Readonly<SaturationAlert>;
11
+ } | {
12
+ readonly kind: 'dimension_explosion' | 'dimension_drop';
13
+ readonly metricName: string;
14
+ readonly reason: string;
15
+ } | {
16
+ readonly kind: 'n1_pattern';
17
+ readonly pattern: Readonly<N1Pattern>;
18
+ } | {
19
+ readonly kind: 'performance_event';
20
+ readonly event: Readonly<PerfEvent>;
21
+ } | {
22
+ readonly kind: 'self_metric';
23
+ readonly name: string;
24
+ readonly value: number;
25
+ readonly labels?: Readonly<Record<string, string>>;
26
+ };
27
+ type PerformanceObservabilityAttachment = () => void;
28
+ type PerformanceObservabilityListener = (event: PerformanceObservabilityEvent) => void;
29
+ /** Attach one fail-open, bounded listener without exposing runtime internals. */
30
+ declare function attachPerformanceObservability(performance: ManagedPerformance, listener: PerformanceObservabilityListener): PerformanceObservabilityAttachment;
31
+
32
+ export { type PerformanceObservabilityAttachment, type PerformanceObservabilityEvent, type PerformanceObservabilityListener, attachPerformanceObservability };
@@ -0,0 +1,76 @@
1
+ import { attachPerformanceTelemetry } from './chunk-MMO5UEUU.js';
2
+ import { isRuntimePromise } from './chunk-RL2752FW.js';
3
+
4
+ // src/performance/public/observability.ts
5
+ var attachments = /* @__PURE__ */ new WeakSet();
6
+ var emissions = /* @__PURE__ */ new WeakMap();
7
+ var OBSERVABILITY_LISTENER_TIMEOUT_MS = 5e3;
8
+ function attachPerformanceObservability(performance, listener) {
9
+ if (typeof listener !== "function") throw new TypeError("performance_invalid_observability");
10
+ if (attachments.has(performance)) throw new Error("PERFORMANCE_OBSERVABILITY_ATTACHED");
11
+ let listenerDisabled = false;
12
+ const emit = (event) => {
13
+ if (listenerDisabled || emissions.has(performance)) return void 0;
14
+ const emission = {};
15
+ emissions.set(performance, emission);
16
+ let listenerTimeout;
17
+ const release = () => {
18
+ if (emissions.get(performance) === emission) emissions.delete(performance);
19
+ if (listenerTimeout !== void 0) {
20
+ try {
21
+ clearTimeout(listenerTimeout);
22
+ } catch {
23
+ }
24
+ listenerTimeout = void 0;
25
+ }
26
+ };
27
+ try {
28
+ const result = listener(Object.freeze(event));
29
+ if (isRuntimePromise(result)) {
30
+ try {
31
+ listenerTimeout = setTimeout(() => {
32
+ listenerDisabled = true;
33
+ release();
34
+ }, OBSERVABILITY_LISTENER_TIMEOUT_MS);
35
+ try {
36
+ listenerTimeout.unref?.();
37
+ } catch {
38
+ }
39
+ } catch {
40
+ listenerDisabled = true;
41
+ release();
42
+ }
43
+ try {
44
+ void Reflect.apply(Promise.prototype.then, result, [release, release]);
45
+ } catch {
46
+ release();
47
+ }
48
+ } else release();
49
+ return result;
50
+ } catch {
51
+ release();
52
+ return void 0;
53
+ }
54
+ };
55
+ const detachTelemetry = attachPerformanceTelemetry(performance, {
56
+ onBudgetViolation: (violation) => emit({ kind: "budget_violation", violation }),
57
+ onSaturationAlert: (alert) => emit({ kind: "saturation_alert", alert }),
58
+ onDimensionExplosion: (metricName, reason) => emit({ kind: "dimension_explosion", metricName, reason }),
59
+ onDimensionDrop: (metricName, reason) => emit({ kind: "dimension_drop", metricName, reason }),
60
+ onN1Pattern: (pattern) => emit({ kind: "n1_pattern", pattern }),
61
+ onPerfEvent: (event) => emit({ kind: "performance_event", event }),
62
+ onSelfMetric: (name, value, labels) => emit({ kind: "self_metric", name, value, ...labels ? { labels } : {} })
63
+ });
64
+ attachments.add(performance);
65
+ let active = true;
66
+ return () => {
67
+ if (!active) return;
68
+ active = false;
69
+ attachments.delete(performance);
70
+ detachTelemetry();
71
+ };
72
+ }
73
+
74
+ export { attachPerformanceObservability };
75
+ //# sourceMappingURL=observability.js.map
76
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/performance/public/observability.ts"],"names":[],"mappings":"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","file":"observability.js","sourcesContent":["import type {BudgetViolation, N1Pattern, PerfEvent, SaturationAlert} from '@ooopsstudio/core/contracts/performance'\n\nimport {attachPerformanceTelemetry} from '../core/runtime-capabilities'\nimport type {ManagedPerformance} from '../types/ports'\nimport {isRuntimePromise} from '../utils/safe-object'\n\nexport type PerformanceObservabilityEvent =\n\t| {readonly kind: 'budget_violation'; readonly violation: Readonly<BudgetViolation>}\n\t| {readonly kind: 'saturation_alert'; readonly alert: Readonly<SaturationAlert>}\n\t| {readonly kind: 'dimension_explosion' | 'dimension_drop'; readonly metricName: string; readonly reason: string}\n\t| {readonly kind: 'n1_pattern'; readonly pattern: Readonly<N1Pattern>}\n\t| {readonly kind: 'performance_event'; readonly event: Readonly<PerfEvent>}\n\t| {readonly kind: 'self_metric'; readonly name: string; readonly value: number; readonly labels?: Readonly<Record<string, string>>}\n\nexport type PerformanceObservabilityAttachment = () => void\nexport type PerformanceObservabilityListener = (event: PerformanceObservabilityEvent) => void\n\nconst attachments = new WeakSet<ManagedPerformance>()\nconst emissions = new WeakMap<ManagedPerformance, object>()\nconst OBSERVABILITY_LISTENER_TIMEOUT_MS = 5_000\n\n/** Attach one fail-open, bounded listener without exposing runtime internals. */\nexport function attachPerformanceObservability(\n\tperformance: ManagedPerformance,\n\tlistener: PerformanceObservabilityListener\n): PerformanceObservabilityAttachment {\n\tif (typeof listener !== 'function') throw new TypeError('performance_invalid_observability')\n\tif (attachments.has(performance)) throw new Error('PERFORMANCE_OBSERVABILITY_ATTACHED')\n\tlet listenerDisabled = false\n\tconst emit = (event: PerformanceObservabilityEvent): unknown => {\n\t\tif (listenerDisabled || emissions.has(performance)) return undefined\n\t\tconst emission = {}\n\t\temissions.set(performance, emission)\n\t\tlet listenerTimeout: ReturnType<typeof setTimeout> | undefined\n\t\tconst release = () => {\n\t\t\tif (emissions.get(performance) === emission) emissions.delete(performance)\n\t\t\tif (listenerTimeout !== undefined) {\n\t\t\t\ttry { clearTimeout(listenerTimeout) } catch { /* listener settlement remains authoritative */ }\n\t\t\t\tlistenerTimeout = undefined\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tconst result: unknown = listener(Object.freeze(event))\n\t\t\tif (isRuntimePromise(result)) {\n\t\t\t\ttry {\n\t\t\t\t\tlistenerTimeout = setTimeout(() => {\n\t\t\t\t\t\tlistenerDisabled = true\n\t\t\t\t\t\trelease()\n\t\t\t\t\t}, OBSERVABILITY_LISTENER_TIMEOUT_MS)\n\t\t\t\t\ttry { listenerTimeout.unref?.() } catch { /* optional process-lifetime optimization */ }\n\t\t\t\t} catch {\n\t\t\t\t\tlistenerDisabled = true\n\t\t\t\t\trelease()\n\t\t\t\t}\n\t\t\t\ttry { void Reflect.apply(Promise.prototype.then, result, [release, release]) } catch { release() }\n\t\t\t} else release()\n\t\t\treturn result\n\t\t} catch { release(); return undefined }\n\t}\n\tconst detachTelemetry = attachPerformanceTelemetry(performance, {\n\t\tonBudgetViolation: (violation) => emit({kind: 'budget_violation', violation}),\n\t\tonSaturationAlert: (alert) => emit({kind: 'saturation_alert', alert}),\n\t\tonDimensionExplosion: (metricName, reason) => emit({kind: 'dimension_explosion', metricName, reason}),\n\t\tonDimensionDrop: (metricName, reason) => emit({kind: 'dimension_drop', metricName, reason}),\n\t\tonN1Pattern: (pattern) => emit({kind: 'n1_pattern', pattern}),\n\t\tonPerfEvent: (event) => emit({kind: 'performance_event', event}),\n\t\tonSelfMetric: (name, value, labels) => emit({kind: 'self_metric', name, value, ...(labels ? {labels} : {})})\n\t})\n\tattachments.add(performance)\n\tlet active = true\n\treturn () => {\n\t\tif (!active) return\n\t\tactive = false\n\t\tattachments.delete(performance)\n\t\tdetachTelemetry()\n\t}\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { BudgetStatus } from '@ooopsstudio/core/contracts/performance';
2
+ import { PerformancePort } from '@ooopsstudio/core/ports/performance';
3
+
4
+ type PerformanceRuntimeState = 'running' | 'draining' | 'closed';
5
+ type PerformanceSinkState = 'healthy' | 'degraded' | 'unhealthy' | 'closed';
6
+ interface PerformanceStatus {
7
+ readonly state: PerformanceRuntimeState;
8
+ readonly activeMeasurements: number;
9
+ readonly queueSize: number;
10
+ readonly droppedTotal: number;
11
+ readonly retriedTotal: number;
12
+ readonly sinkState: PerformanceSinkState;
13
+ readonly lastFailureCode?: string;
14
+ }
15
+ interface ManagedPerformance extends Required<PerformancePort> {
16
+ getBudgetStatus(name: string): Readonly<BudgetStatus> | undefined;
17
+ getStatus(): PerformanceStatus;
18
+ flush(): Promise<void>;
19
+ shutdown(): Promise<void>;
20
+ }
21
+ type PerformanceHandlerPort = ManagedPerformance;
22
+
23
+ export type { ManagedPerformance as M, PerformanceHandlerPort as P, PerformanceRuntimeState as a, PerformanceSinkState as b, PerformanceStatus as c };
@@ -0,0 +1,19 @@
1
+ import { Clock } from '@ooopsstudio/core/contracts/clock';
2
+ import { ObservabilityResource } from '@ooopsstudio/core/contracts/observability-shared';
3
+ import { Errors } from '@ooopsstudio/core/ports/errors';
4
+ import { LifecyclePort } from '@ooopsstudio/core/ports/lifecycle';
5
+ import { Tracing } from '@ooopsstudio/core/ports/tracing';
6
+ import { M as ManagedPerformance } from './ports-DwUYdKj-.js';
7
+ import '@ooopsstudio/core/contracts/performance';
8
+ import '@ooopsstudio/core/ports/performance';
9
+
10
+ interface ProductionPerformanceOptions {
11
+ clock?: Clock;
12
+ resource?: ObservabilityResource;
13
+ errors?: Errors;
14
+ tracer?: Tracing;
15
+ lifecycle?: LifecyclePort;
16
+ }
17
+ declare function createProductionPerformance(options?: ProductionPerformanceOptions): Promise<ManagedPerformance>;
18
+
19
+ export { type ProductionPerformanceOptions, createProductionPerformance };