@skillsmith/core 0.1.2 → 0.2.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/analysis/CodebaseAnalyzer.d.ts +4 -134
- package/dist/src/analysis/CodebaseAnalyzer.d.ts.map +1 -1
- package/dist/src/analysis/CodebaseAnalyzer.js +7 -315
- package/dist/src/analysis/CodebaseAnalyzer.js.map +1 -1
- package/dist/src/analysis/framework-detector.d.ts +47 -0
- package/dist/src/analysis/framework-detector.d.ts.map +1 -0
- package/dist/src/analysis/framework-detector.js +151 -0
- package/dist/src/analysis/framework-detector.js.map +1 -0
- package/dist/src/analysis/index.d.ts +6 -1
- package/dist/src/analysis/index.d.ts.map +1 -1
- package/dist/src/analysis/index.js +10 -1
- package/dist/src/analysis/index.js.map +1 -1
- package/dist/src/analysis/parsers.d.ts +43 -0
- package/dist/src/analysis/parsers.d.ts.map +1 -0
- package/dist/src/analysis/parsers.js +219 -0
- package/dist/src/analysis/parsers.js.map +1 -0
- package/dist/src/analysis/types.d.ts +138 -0
- package/dist/src/analysis/types.d.ts.map +1 -0
- package/dist/src/analysis/types.js +25 -0
- package/dist/src/analysis/types.js.map +1 -0
- package/dist/src/analytics/AnalyticsRepository.d.ts.map +1 -1
- package/dist/src/analytics/AnalyticsRepository.js +4 -4
- package/dist/src/analytics/AnalyticsRepository.js.map +1 -1
- package/dist/src/api/cache.d.ts +108 -0
- package/dist/src/api/cache.d.ts.map +1 -0
- package/dist/src/api/cache.js +216 -0
- package/dist/src/api/cache.js.map +1 -0
- package/dist/src/api/client.d.ts +152 -0
- package/dist/src/api/client.d.ts.map +1 -0
- package/dist/src/api/client.js +221 -0
- package/dist/src/api/client.js.map +1 -0
- package/dist/src/api/index.d.ts +10 -0
- package/dist/src/api/index.d.ts.map +1 -0
- package/dist/src/api/index.js +10 -0
- package/dist/src/api/index.js.map +1 -0
- package/dist/src/benchmarks/BenchmarkRunner.d.ts +6 -175
- package/dist/src/benchmarks/BenchmarkRunner.d.ts.map +1 -1
- package/dist/src/benchmarks/BenchmarkRunner.js +6 -123
- package/dist/src/benchmarks/BenchmarkRunner.js.map +1 -1
- package/dist/src/benchmarks/MemoryProfiler.d.ts +4 -262
- package/dist/src/benchmarks/MemoryProfiler.d.ts.map +1 -1
- package/dist/src/benchmarks/MemoryProfiler.js +4 -400
- package/dist/src/benchmarks/MemoryProfiler.js.map +1 -1
- package/dist/src/benchmarks/comparator.d.ts +38 -0
- package/dist/src/benchmarks/comparator.d.ts.map +1 -0
- package/dist/src/benchmarks/comparator.js +81 -0
- package/dist/src/benchmarks/comparator.js.map +1 -0
- package/dist/src/benchmarks/formatters.d.ts +30 -0
- package/dist/src/benchmarks/formatters.d.ts.map +1 -0
- package/dist/src/benchmarks/formatters.js +88 -0
- package/dist/src/benchmarks/formatters.js.map +1 -0
- package/dist/src/benchmarks/index.d.ts +5 -1
- package/dist/src/benchmarks/index.d.ts.map +1 -1
- package/dist/src/benchmarks/index.js +9 -2
- package/dist/src/benchmarks/index.js.map +1 -1
- package/dist/src/benchmarks/memory/MemoryProfiler.d.ts +165 -0
- package/dist/src/benchmarks/memory/MemoryProfiler.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/MemoryProfiler.js +312 -0
- package/dist/src/benchmarks/memory/MemoryProfiler.js.map +1 -0
- package/dist/src/benchmarks/memory/baseline-manager.d.ts +64 -0
- package/dist/src/benchmarks/memory/baseline-manager.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/baseline-manager.js +95 -0
- package/dist/src/benchmarks/memory/baseline-manager.js.map +1 -0
- package/dist/src/benchmarks/memory/index.d.ts +12 -0
- package/dist/src/benchmarks/memory/index.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/index.js +12 -0
- package/dist/src/benchmarks/memory/index.js.map +1 -0
- package/dist/src/benchmarks/memory/leak-detector.d.ts +23 -0
- package/dist/src/benchmarks/memory/leak-detector.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/leak-detector.js +46 -0
- package/dist/src/benchmarks/memory/leak-detector.js.map +1 -0
- package/dist/src/benchmarks/memory/regression-detector.d.ts +17 -0
- package/dist/src/benchmarks/memory/regression-detector.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/regression-detector.js +56 -0
- package/dist/src/benchmarks/memory/regression-detector.js.map +1 -0
- package/dist/src/benchmarks/memory/types.d.ts +111 -0
- package/dist/src/benchmarks/memory/types.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/types.js +7 -0
- package/dist/src/benchmarks/memory/types.js.map +1 -0
- package/dist/src/benchmarks/memory/utils.d.ts +17 -0
- package/dist/src/benchmarks/memory/utils.d.ts.map +1 -0
- package/dist/src/benchmarks/memory/utils.js +29 -0
- package/dist/src/benchmarks/memory/utils.js.map +1 -0
- package/dist/src/benchmarks/types.d.ts +175 -0
- package/dist/src/benchmarks/types.d.ts.map +1 -0
- package/dist/src/benchmarks/types.js +20 -0
- package/dist/src/benchmarks/types.js.map +1 -0
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/repositories/QuarantineRepository.d.ts +4 -251
- package/dist/src/repositories/QuarantineRepository.d.ts.map +1 -1
- package/dist/src/repositories/QuarantineRepository.js +4 -441
- package/dist/src/repositories/QuarantineRepository.js.map +1 -1
- package/dist/src/repositories/quarantine/QuarantineRepository.d.ts +168 -0
- package/dist/src/repositories/quarantine/QuarantineRepository.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/QuarantineRepository.js +341 -0
- package/dist/src/repositories/quarantine/QuarantineRepository.js.map +1 -0
- package/dist/src/repositories/quarantine/index.d.ts +10 -0
- package/dist/src/repositories/quarantine/index.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/index.js +10 -0
- package/dist/src/repositories/quarantine/index.js.map +1 -0
- package/dist/src/repositories/quarantine/queries.d.ts +58 -0
- package/dist/src/repositories/quarantine/queries.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/queries.js +88 -0
- package/dist/src/repositories/quarantine/queries.js.map +1 -0
- package/dist/src/repositories/quarantine/query-builder.d.ts +44 -0
- package/dist/src/repositories/quarantine/query-builder.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/query-builder.js +87 -0
- package/dist/src/repositories/quarantine/query-builder.js.map +1 -0
- package/dist/src/repositories/quarantine/types.d.ts +155 -0
- package/dist/src/repositories/quarantine/types.d.ts.map +1 -0
- package/dist/src/repositories/quarantine/types.js +13 -0
- package/dist/src/repositories/quarantine/types.js.map +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.d.ts +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.d.ts.map +1 -1
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js +7 -43
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
- package/dist/src/scripts/github-import/checkpoint.d.ts +21 -0
- package/dist/src/scripts/github-import/checkpoint.d.ts.map +1 -0
- package/dist/src/scripts/github-import/checkpoint.js +52 -0
- package/dist/src/scripts/github-import/checkpoint.js.map +1 -0
- package/dist/src/scripts/github-import/deduplication.d.ts +15 -0
- package/dist/src/scripts/github-import/deduplication.d.ts.map +1 -0
- package/dist/src/scripts/github-import/deduplication.js +33 -0
- package/dist/src/scripts/github-import/deduplication.js.map +1 -0
- package/dist/src/scripts/github-import/github-client.d.ts +29 -0
- package/dist/src/scripts/github-import/github-client.d.ts.map +1 -0
- package/dist/src/scripts/github-import/github-client.js +184 -0
- package/dist/src/scripts/github-import/github-client.js.map +1 -0
- package/dist/src/scripts/github-import/index.d.ts +29 -0
- package/dist/src/scripts/github-import/index.d.ts.map +1 -0
- package/dist/src/scripts/github-import/index.js +198 -0
- package/dist/src/scripts/github-import/index.js.map +1 -0
- package/dist/src/scripts/github-import/output.d.ts +12 -0
- package/dist/src/scripts/github-import/output.d.ts.map +1 -0
- package/dist/src/scripts/github-import/output.js +34 -0
- package/dist/src/scripts/github-import/output.js.map +1 -0
- package/dist/src/scripts/github-import/types.d.ts +108 -0
- package/dist/src/scripts/github-import/types.d.ts.map +1 -0
- package/dist/src/scripts/github-import/types.js +44 -0
- package/dist/src/scripts/github-import/types.js.map +1 -0
- package/dist/src/scripts/github-import/utils.d.ts +13 -0
- package/dist/src/scripts/github-import/utils.d.ts.map +1 -0
- package/dist/src/scripts/github-import/utils.js +28 -0
- package/dist/src/scripts/github-import/utils.js.map +1 -0
- package/dist/src/scripts/import-github-skills.d.ts +3 -12
- package/dist/src/scripts/import-github-skills.d.ts.map +1 -1
- package/dist/src/scripts/import-github-skills.js +18 -398
- package/dist/src/scripts/import-github-skills.js.map +1 -1
- package/dist/src/scripts/scan-imported-skills.d.ts +7 -7
- package/dist/src/scripts/scan-imported-skills.d.ts.map +1 -1
- package/dist/src/scripts/scan-imported-skills.js +8 -397
- package/dist/src/scripts/scan-imported-skills.js.map +1 -1
- package/dist/src/scripts/skill-scanner/categorizer.d.ts +43 -0
- package/dist/src/scripts/skill-scanner/categorizer.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/categorizer.js +61 -0
- package/dist/src/scripts/skill-scanner/categorizer.js.map +1 -0
- package/dist/src/scripts/skill-scanner/file-scanner.d.ts +43 -0
- package/dist/src/scripts/skill-scanner/file-scanner.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/file-scanner.js +90 -0
- package/dist/src/scripts/skill-scanner/file-scanner.js.map +1 -0
- package/dist/src/scripts/skill-scanner/index.d.ts +22 -0
- package/dist/src/scripts/skill-scanner/index.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/index.js +43 -0
- package/dist/src/scripts/skill-scanner/index.js.map +1 -0
- package/dist/src/scripts/skill-scanner/logger.d.ts +59 -0
- package/dist/src/scripts/skill-scanner/logger.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/logger.js +104 -0
- package/dist/src/scripts/skill-scanner/logger.js.map +1 -0
- package/dist/src/scripts/skill-scanner/reporter.d.ts +56 -0
- package/dist/src/scripts/skill-scanner/reporter.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/reporter.js +166 -0
- package/dist/src/scripts/skill-scanner/reporter.js.map +1 -0
- package/dist/src/scripts/skill-scanner/scanner.d.ts +44 -0
- package/dist/src/scripts/skill-scanner/scanner.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/scanner.js +140 -0
- package/dist/src/scripts/skill-scanner/scanner.js.map +1 -0
- package/dist/src/scripts/skill-scanner/trust-scorer.d.ts +59 -0
- package/dist/src/scripts/skill-scanner/trust-scorer.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/trust-scorer.js +62 -0
- package/dist/src/scripts/skill-scanner/trust-scorer.js.map +1 -0
- package/dist/src/scripts/skill-scanner/types.d.ts +98 -0
- package/dist/src/scripts/skill-scanner/types.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/types.js +7 -0
- package/dist/src/scripts/skill-scanner/types.js.map +1 -0
- package/dist/src/scripts/validate-skills.d.ts +3 -172
- package/dist/src/scripts/validate-skills.d.ts.map +1 -1
- package/dist/src/scripts/validate-skills.js +6 -519
- package/dist/src/scripts/validate-skills.js.map +1 -1
- package/dist/src/scripts/validation/deduplication.d.ts +23 -0
- package/dist/src/scripts/validation/deduplication.d.ts.map +1 -0
- package/dist/src/scripts/validation/deduplication.js +127 -0
- package/dist/src/scripts/validation/deduplication.js.map +1 -0
- package/dist/src/scripts/validation/field-validators.d.ts +9 -0
- package/dist/src/scripts/validation/field-validators.d.ts.map +1 -0
- package/dist/src/scripts/validation/field-validators.js +135 -0
- package/dist/src/scripts/validation/field-validators.js.map +1 -0
- package/dist/src/scripts/validation/index.d.ts +29 -0
- package/dist/src/scripts/validation/index.d.ts.map +1 -0
- package/dist/src/scripts/validation/index.js +84 -0
- package/dist/src/scripts/validation/index.js.map +1 -0
- package/dist/src/scripts/validation/normalizers.d.ts +29 -0
- package/dist/src/scripts/validation/normalizers.d.ts.map +1 -0
- package/dist/src/scripts/validation/normalizers.js +79 -0
- package/dist/src/scripts/validation/normalizers.js.map +1 -0
- package/dist/src/scripts/validation/pipeline.d.ts +13 -0
- package/dist/src/scripts/validation/pipeline.d.ts.map +1 -0
- package/dist/src/scripts/validation/pipeline.js +126 -0
- package/dist/src/scripts/validation/pipeline.js.map +1 -0
- package/dist/src/scripts/validation/types.d.ts +128 -0
- package/dist/src/scripts/validation/types.d.ts.map +1 -0
- package/dist/src/scripts/validation/types.js +43 -0
- package/dist/src/scripts/validation/types.js.map +1 -0
- package/dist/src/security/index.d.ts +5 -4
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +8 -2
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/rate-limiter/RateLimiter.d.ts +86 -0
- package/dist/src/security/rate-limiter/RateLimiter.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/RateLimiter.js +260 -0
- package/dist/src/security/rate-limiter/RateLimiter.js.map +1 -0
- package/dist/src/security/rate-limiter/constants.d.ts +15 -0
- package/dist/src/security/rate-limiter/constants.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/constants.js +15 -0
- package/dist/src/security/rate-limiter/constants.js.map +1 -0
- package/dist/src/security/rate-limiter/errors.d.ts +22 -0
- package/dist/src/security/rate-limiter/errors.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/errors.js +32 -0
- package/dist/src/security/rate-limiter/errors.js.map +1 -0
- package/dist/src/security/rate-limiter/index.d.ts +12 -0
- package/dist/src/security/rate-limiter/index.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/index.js +16 -0
- package/dist/src/security/rate-limiter/index.js.map +1 -0
- package/dist/src/security/rate-limiter/metrics-manager.d.ts +55 -0
- package/dist/src/security/rate-limiter/metrics-manager.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/metrics-manager.js +144 -0
- package/dist/src/security/rate-limiter/metrics-manager.js.map +1 -0
- package/dist/src/security/rate-limiter/presets.d.ts +52 -0
- package/dist/src/security/rate-limiter/presets.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/presets.js +53 -0
- package/dist/src/security/rate-limiter/presets.js.map +1 -0
- package/dist/src/security/rate-limiter/queue-manager.d.ts +59 -0
- package/dist/src/security/rate-limiter/queue-manager.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/queue-manager.js +189 -0
- package/dist/src/security/rate-limiter/queue-manager.js.map +1 -0
- package/dist/src/security/rate-limiter/storage.d.ts +34 -0
- package/dist/src/security/rate-limiter/storage.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/storage.js +80 -0
- package/dist/src/security/rate-limiter/storage.js.map +1 -0
- package/dist/src/security/rate-limiter/token-bucket.d.ts +44 -0
- package/dist/src/security/rate-limiter/token-bucket.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/token-bucket.js +99 -0
- package/dist/src/security/rate-limiter/token-bucket.js.map +1 -0
- package/dist/src/security/rate-limiter/types.d.ts +104 -0
- package/dist/src/security/rate-limiter/types.d.ts.map +1 -0
- package/dist/src/security/rate-limiter/types.js +7 -0
- package/dist/src/security/rate-limiter/types.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts +94 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.js +403 -0
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -0
- package/dist/src/security/scanner/index.d.ts +11 -0
- package/dist/src/security/scanner/index.d.ts.map +1 -0
- package/dist/src/security/scanner/index.js +14 -0
- package/dist/src/security/scanner/index.js.map +1 -0
- package/dist/src/security/scanner/patterns.d.ts +14 -0
- package/dist/src/security/scanner/patterns.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.js +147 -0
- package/dist/src/security/scanner/patterns.js.map +1 -0
- package/dist/src/security/scanner/regex-utils.d.ts +33 -0
- package/dist/src/security/scanner/regex-utils.d.ts.map +1 -0
- package/dist/src/security/scanner/regex-utils.js +41 -0
- package/dist/src/security/scanner/regex-utils.js.map +1 -0
- package/dist/src/security/scanner/types.d.ts +63 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -0
- package/dist/src/security/scanner/types.js +7 -0
- package/dist/src/security/scanner/types.js.map +1 -0
- package/dist/src/security/scanner/weights.d.ts +15 -0
- package/dist/src/security/scanner/weights.d.ts.map +1 -0
- package/dist/src/security/scanner/weights.js +28 -0
- package/dist/src/security/scanner/weights.js.map +1 -0
- package/dist/src/session/SessionHealthMonitor.d.ts +5 -168
- package/dist/src/session/SessionHealthMonitor.d.ts.map +1 -1
- package/dist/src/session/SessionHealthMonitor.js +22 -91
- package/dist/src/session/SessionHealthMonitor.js.map +1 -1
- package/dist/src/session/health-checks.d.ts +37 -0
- package/dist/src/session/health-checks.d.ts.map +1 -0
- package/dist/src/session/health-checks.js +64 -0
- package/dist/src/session/health-checks.js.map +1 -0
- package/dist/src/session/health-types.d.ts +78 -0
- package/dist/src/session/health-types.d.ts.map +1 -0
- package/dist/src/session/health-types.js +16 -0
- package/dist/src/session/health-types.js.map +1 -0
- package/dist/src/session/index.d.ts +5 -1
- package/dist/src/session/index.d.ts.map +1 -1
- package/dist/src/session/index.js +9 -0
- package/dist/src/session/index.js.map +1 -1
- package/dist/src/session/metrics-collector.d.ts +23 -0
- package/dist/src/session/metrics-collector.d.ts.map +1 -0
- package/dist/src/session/metrics-collector.js +44 -0
- package/dist/src/session/metrics-collector.js.map +1 -0
- package/dist/src/session/typed-event-emitter.d.ts +70 -0
- package/dist/src/session/typed-event-emitter.d.ts.map +1 -0
- package/dist/src/session/typed-event-emitter.js +79 -0
- package/dist/src/session/typed-event-emitter.js.map +1 -0
- package/dist/src/sources/BaseSourceAdapter.d.ts +1 -1
- package/dist/src/sources/BaseSourceAdapter.d.ts.map +1 -1
- package/dist/src/sources/BaseSourceAdapter.js +2 -2
- package/dist/src/sources/BaseSourceAdapter.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +1 -0
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +2 -0
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/posthog.d.ts +125 -0
- package/dist/src/telemetry/posthog.d.ts.map +1 -0
- package/dist/src/telemetry/posthog.js +198 -0
- package/dist/src/telemetry/posthog.js.map +1 -0
- package/dist/tests/RateLimiter.test.js +4 -4
- package/dist/tests/RateLimiter.test.js.map +1 -1
- package/dist/tests/e2e/security/security.e2e.test.js +3 -3
- package/dist/tests/e2e/security/security.e2e.test.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skillsmith API Client
|
|
3
|
+
* @module api/client
|
|
4
|
+
*
|
|
5
|
+
* SMI-1244: API client for fetching skills from live Supabase endpoints
|
|
6
|
+
*
|
|
7
|
+
* Provides methods to interact with the Skillsmith API:
|
|
8
|
+
* - search: Search skills with filters
|
|
9
|
+
* - getSkill: Get skill by ID
|
|
10
|
+
* - getRecommendations: Get skill recommendations based on tech stack
|
|
11
|
+
* - recordEvent: Record telemetry event
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_BASE_URL = 'https://vrcnzpmndtroqxxoqkzy.supabase.co/functions/v1';
|
|
14
|
+
/**
|
|
15
|
+
* Calculate delay with exponential backoff and jitter
|
|
16
|
+
*/
|
|
17
|
+
function calculateBackoff(attempt, baseDelay = 1000) {
|
|
18
|
+
const exponentialDelay = baseDelay * Math.pow(2, attempt);
|
|
19
|
+
const jitter = Math.random() * 0.3 * exponentialDelay;
|
|
20
|
+
return Math.min(exponentialDelay + jitter, 30000); // Max 30s
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate anonymous ID for telemetry
|
|
24
|
+
*/
|
|
25
|
+
export function generateAnonymousId() {
|
|
26
|
+
const chars = 'abcdef0123456789';
|
|
27
|
+
let id = '';
|
|
28
|
+
for (let i = 0; i < 32; i++) {
|
|
29
|
+
id += chars[Math.floor(Math.random() * chars.length)];
|
|
30
|
+
}
|
|
31
|
+
return id;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Skillsmith API Client
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const client = new SkillsmithApiClient({
|
|
39
|
+
* anonKey: process.env.SUPABASE_ANON_KEY,
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* const results = await client.search({ query: 'testing' });
|
|
43
|
+
* console.log(results.data);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class SkillsmithApiClient {
|
|
47
|
+
baseUrl;
|
|
48
|
+
anonKey;
|
|
49
|
+
timeout;
|
|
50
|
+
maxRetries;
|
|
51
|
+
debug;
|
|
52
|
+
constructor(config = {}) {
|
|
53
|
+
this.baseUrl = config.baseUrl || process.env.SKILLSMITH_API_URL || DEFAULT_BASE_URL;
|
|
54
|
+
this.anonKey = config.anonKey || process.env.SUPABASE_ANON_KEY;
|
|
55
|
+
this.timeout = config.timeout ?? 30000;
|
|
56
|
+
this.maxRetries = config.maxRetries ?? 3;
|
|
57
|
+
this.debug = config.debug ?? false;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Log debug message
|
|
61
|
+
*/
|
|
62
|
+
log(message, data) {
|
|
63
|
+
if (this.debug) {
|
|
64
|
+
console.log(`[SkillsmithApiClient] ${message}`, data ?? '');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build request headers
|
|
69
|
+
*/
|
|
70
|
+
buildHeaders() {
|
|
71
|
+
const headers = {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'x-request-id': `client-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
74
|
+
};
|
|
75
|
+
if (this.anonKey) {
|
|
76
|
+
headers['Authorization'] = `Bearer ${this.anonKey}`;
|
|
77
|
+
headers['apikey'] = this.anonKey;
|
|
78
|
+
}
|
|
79
|
+
return headers;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Make API request with retry logic
|
|
83
|
+
*/
|
|
84
|
+
async request(endpoint, options = {}) {
|
|
85
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
86
|
+
let lastError;
|
|
87
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
88
|
+
try {
|
|
89
|
+
this.log(`Request attempt ${attempt + 1}:`, { url, method: options.method || 'GET' });
|
|
90
|
+
const controller = new AbortController();
|
|
91
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
92
|
+
const response = await fetch(url, {
|
|
93
|
+
...options,
|
|
94
|
+
headers: {
|
|
95
|
+
...this.buildHeaders(),
|
|
96
|
+
...options.headers,
|
|
97
|
+
},
|
|
98
|
+
signal: controller.signal,
|
|
99
|
+
});
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const errorBody = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
103
|
+
// Don't retry on client errors (4xx)
|
|
104
|
+
if (response.status >= 400 && response.status < 500) {
|
|
105
|
+
throw new Error(errorBody.error || `API error: ${response.status}`);
|
|
106
|
+
}
|
|
107
|
+
// Retry on server errors (5xx) and rate limits (429)
|
|
108
|
+
if (response.status === 429 || response.status >= 500) {
|
|
109
|
+
throw new Error(`Server error: ${response.status}`);
|
|
110
|
+
}
|
|
111
|
+
throw new Error(errorBody.error || `API error: ${response.status}`);
|
|
112
|
+
}
|
|
113
|
+
const data = await response.json();
|
|
114
|
+
this.log('Response received:', { status: response.status });
|
|
115
|
+
return data;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
119
|
+
this.log(`Attempt ${attempt + 1} failed:`, lastError.message);
|
|
120
|
+
// Don't retry on abort or client errors
|
|
121
|
+
if (lastError.name === 'AbortError' || lastError.message.includes('API error')) {
|
|
122
|
+
throw lastError;
|
|
123
|
+
}
|
|
124
|
+
if (attempt < this.maxRetries) {
|
|
125
|
+
const delay = calculateBackoff(attempt);
|
|
126
|
+
this.log(`Retrying in ${delay}ms...`);
|
|
127
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
throw lastError || new Error('Request failed after retries');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Search for skills
|
|
135
|
+
*
|
|
136
|
+
* @param options - Search options
|
|
137
|
+
* @returns Search results
|
|
138
|
+
*/
|
|
139
|
+
async search(options) {
|
|
140
|
+
const params = new URLSearchParams();
|
|
141
|
+
params.set('query', options.query);
|
|
142
|
+
if (options.limit)
|
|
143
|
+
params.set('limit', String(options.limit));
|
|
144
|
+
if (options.offset)
|
|
145
|
+
params.set('offset', String(options.offset));
|
|
146
|
+
if (options.trustTier)
|
|
147
|
+
params.set('trust_tier', options.trustTier);
|
|
148
|
+
if (options.minQualityScore !== undefined)
|
|
149
|
+
params.set('min_score', String(options.minQualityScore));
|
|
150
|
+
if (options.category)
|
|
151
|
+
params.set('category', options.category);
|
|
152
|
+
return this.request(`/skills-search?${params.toString()}`);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get skill by ID
|
|
156
|
+
*
|
|
157
|
+
* @param id - Skill ID (UUID or author/name format)
|
|
158
|
+
* @returns Skill details
|
|
159
|
+
*/
|
|
160
|
+
async getSkill(id) {
|
|
161
|
+
const encodedId = encodeURIComponent(id);
|
|
162
|
+
return this.request(`/skills-get?id=${encodedId}`);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get skill recommendations based on tech stack
|
|
166
|
+
*
|
|
167
|
+
* @param request - Recommendation request
|
|
168
|
+
* @returns Recommended skills
|
|
169
|
+
*/
|
|
170
|
+
async getRecommendations(request) {
|
|
171
|
+
return this.request('/skills-recommend', {
|
|
172
|
+
method: 'POST',
|
|
173
|
+
body: JSON.stringify(request),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Record telemetry event
|
|
178
|
+
*
|
|
179
|
+
* @param event - Telemetry event
|
|
180
|
+
* @returns Success response
|
|
181
|
+
*/
|
|
182
|
+
async recordEvent(event) {
|
|
183
|
+
try {
|
|
184
|
+
const response = await this.request('/events', {
|
|
185
|
+
method: 'POST',
|
|
186
|
+
body: JSON.stringify(event),
|
|
187
|
+
});
|
|
188
|
+
return response.data;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Telemetry should not throw - fail silently
|
|
192
|
+
this.log('Telemetry event failed (non-blocking)');
|
|
193
|
+
return { ok: false };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Convert API result to Skill type
|
|
198
|
+
*/
|
|
199
|
+
static toSkill(result) {
|
|
200
|
+
return {
|
|
201
|
+
id: result.id,
|
|
202
|
+
name: result.name,
|
|
203
|
+
description: result.description,
|
|
204
|
+
author: result.author,
|
|
205
|
+
repoUrl: result.repo_url,
|
|
206
|
+
qualityScore: result.quality_score,
|
|
207
|
+
trustTier: result.trust_tier,
|
|
208
|
+
tags: result.tags || [],
|
|
209
|
+
createdAt: result.created_at,
|
|
210
|
+
updatedAt: result.updated_at,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Create a default API client instance
|
|
216
|
+
*/
|
|
217
|
+
export function createApiClient(config) {
|
|
218
|
+
return new SkillsmithApiClient(config);
|
|
219
|
+
}
|
|
220
|
+
export default SkillsmithApiClient;
|
|
221
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API module exports
|
|
3
|
+
* @module api
|
|
4
|
+
*
|
|
5
|
+
* SMI-1244: API client for Skillsmith
|
|
6
|
+
* SMI-1245: API response caching
|
|
7
|
+
*/
|
|
8
|
+
export { SkillsmithApiClient, createApiClient, generateAnonymousId, type ApiClientConfig, type ApiResponse, type ApiErrorResponse, type ApiSearchResult, type RecommendationRequest, type TelemetryEvent, } from './client.js';
|
|
9
|
+
export { ApiCache, createCache, getGlobalCache, DEFAULT_TTL, type CacheConfig, type CacheStats, } from './cache.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API module exports
|
|
3
|
+
* @module api
|
|
4
|
+
*
|
|
5
|
+
* SMI-1244: API client for Skillsmith
|
|
6
|
+
* SMI-1245: API response caching
|
|
7
|
+
*/
|
|
8
|
+
export { SkillsmithApiClient, createApiClient, generateAnonymousId, } from './client.js';
|
|
9
|
+
export { ApiCache, createCache, getGlobalCache, DEFAULT_TTL, } from './cache.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GAOpB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,YAAY,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SMI-632: BenchmarkRunner - Performance benchmark infrastructure
|
|
3
3
|
* SMI-689: Enhanced with MemoryProfiler integration
|
|
4
|
+
* SMI-1189: Refactored to use extracted modules
|
|
4
5
|
*
|
|
5
6
|
* Features:
|
|
6
7
|
* - Run benchmark suites
|
|
@@ -10,143 +11,11 @@
|
|
|
10
11
|
* - Warm-up runs before measurement
|
|
11
12
|
* - Statistical analysis (mean, stddev)
|
|
12
13
|
*/
|
|
13
|
-
import { MemoryProfiler, type MemoryBaseline
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export
|
|
18
|
-
/** Number of warm-up iterations before measurement */
|
|
19
|
-
warmupIterations?: number;
|
|
20
|
-
/** Number of measured iterations */
|
|
21
|
-
iterations?: number;
|
|
22
|
-
/** Enable memory profiling */
|
|
23
|
-
measureMemory?: boolean;
|
|
24
|
-
/** Suite name for grouping */
|
|
25
|
-
suiteName?: string;
|
|
26
|
-
/** Enable detailed memory profiling with MemoryProfiler (SMI-689) */
|
|
27
|
-
enableMemoryProfiler?: boolean;
|
|
28
|
-
/** Memory regression threshold percentage (SMI-689, default: 10) */
|
|
29
|
-
memoryRegressionThreshold?: number;
|
|
30
|
-
/** Memory baselines for regression comparison (SMI-689) */
|
|
31
|
-
memoryBaselines?: Record<string, MemoryBaseline>;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Single benchmark result
|
|
35
|
-
*/
|
|
36
|
-
export interface BenchmarkResult {
|
|
37
|
-
name: string;
|
|
38
|
-
iterations: number;
|
|
39
|
-
latencies: number[];
|
|
40
|
-
memoryUsage?: MemoryStats;
|
|
41
|
-
/** Number of errors encountered during benchmark execution */
|
|
42
|
-
errors: number;
|
|
43
|
-
/** Error messages (capped at 10 to prevent memory issues) */
|
|
44
|
-
errorMessages: string[];
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Memory usage statistics
|
|
48
|
-
*/
|
|
49
|
-
export interface MemoryStats {
|
|
50
|
-
heapUsedBefore: number;
|
|
51
|
-
heapUsedAfter: number;
|
|
52
|
-
heapUsedPeak: number;
|
|
53
|
-
externalBefore: number;
|
|
54
|
-
externalAfter: number;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Statistical summary of benchmark results
|
|
58
|
-
*/
|
|
59
|
-
export interface BenchmarkStats {
|
|
60
|
-
name: string;
|
|
61
|
-
iterations: number;
|
|
62
|
-
p50_ms: number;
|
|
63
|
-
p95_ms: number;
|
|
64
|
-
p99_ms: number;
|
|
65
|
-
mean_ms: number;
|
|
66
|
-
stddev_ms: number;
|
|
67
|
-
min_ms: number;
|
|
68
|
-
max_ms: number;
|
|
69
|
-
memoryPeak_mb?: number;
|
|
70
|
-
/** Number of errors encountered during benchmark execution */
|
|
71
|
-
errors?: number;
|
|
72
|
-
/** Error messages (capped at 10) */
|
|
73
|
-
errorMessages?: string[];
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Detailed memory profiling stats (SMI-689)
|
|
77
|
-
*/
|
|
78
|
-
export interface DetailedMemoryStats {
|
|
79
|
-
/** Start heap size in bytes */
|
|
80
|
-
startHeapSize: number;
|
|
81
|
-
/** End heap size in bytes */
|
|
82
|
-
endHeapSize: number;
|
|
83
|
-
/** Peak heap size in bytes */
|
|
84
|
-
peakHeapSize: number;
|
|
85
|
-
/** Heap growth in bytes */
|
|
86
|
-
heapGrowth: number;
|
|
87
|
-
/** Heap growth as percentage */
|
|
88
|
-
heapGrowthPercent: number;
|
|
89
|
-
/** Duration of profiling in ms */
|
|
90
|
-
profilingDuration: number;
|
|
91
|
-
/** Number of samples collected */
|
|
92
|
-
sampleCount: number;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Memory regression info (SMI-689)
|
|
96
|
-
*/
|
|
97
|
-
export interface MemoryRegressionInfo {
|
|
98
|
-
/** Whether any regressions were detected */
|
|
99
|
-
hasRegressions: boolean;
|
|
100
|
-
/** Threshold used for detection */
|
|
101
|
-
threshold: number;
|
|
102
|
-
/** Details per benchmark */
|
|
103
|
-
regressions: MemoryRegressionResult[];
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Complete benchmark report
|
|
107
|
-
*/
|
|
108
|
-
export interface BenchmarkReport {
|
|
109
|
-
suite: string;
|
|
110
|
-
timestamp: string;
|
|
111
|
-
environment: EnvironmentInfo;
|
|
112
|
-
results: Record<string, BenchmarkStats>;
|
|
113
|
-
summary: {
|
|
114
|
-
totalBenchmarks: number;
|
|
115
|
-
totalIterations: number;
|
|
116
|
-
totalDuration_ms: number;
|
|
117
|
-
};
|
|
118
|
-
/** Detailed memory profiling data (SMI-689) */
|
|
119
|
-
memoryProfile?: Record<string, DetailedMemoryStats>;
|
|
120
|
-
/** Memory regression info (SMI-689) */
|
|
121
|
-
memoryRegression?: MemoryRegressionInfo;
|
|
122
|
-
/** Memory baselines for future comparison (SMI-689) */
|
|
123
|
-
memoryBaselines?: Record<string, MemoryBaseline>;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Environment information for reproducibility
|
|
127
|
-
*/
|
|
128
|
-
export interface EnvironmentInfo {
|
|
129
|
-
node: string;
|
|
130
|
-
platform: string;
|
|
131
|
-
arch: string;
|
|
132
|
-
docker: boolean;
|
|
133
|
-
database: string;
|
|
134
|
-
cpuCount: number;
|
|
135
|
-
memoryTotal_mb: number;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Benchmark function type
|
|
139
|
-
*/
|
|
140
|
-
export type BenchmarkFn = () => void | Promise<void>;
|
|
141
|
-
/**
|
|
142
|
-
* Benchmark definition
|
|
143
|
-
*/
|
|
144
|
-
export interface BenchmarkDefinition {
|
|
145
|
-
name: string;
|
|
146
|
-
fn: BenchmarkFn;
|
|
147
|
-
setup?: () => void | Promise<void>;
|
|
148
|
-
teardown?: () => void | Promise<void>;
|
|
149
|
-
}
|
|
14
|
+
import { MemoryProfiler, type MemoryBaseline } from './MemoryProfiler.js';
|
|
15
|
+
import { type BenchmarkConfig, type BenchmarkResult, type BenchmarkReport, type BenchmarkDefinition } from './types.js';
|
|
16
|
+
export type { BenchmarkConfig, BenchmarkResult, BenchmarkStats, BenchmarkReport, BenchmarkDefinition, BenchmarkFn, EnvironmentInfo, MemoryStats, DetailedMemoryStats, MemoryRegressionInfo, ComparisonResult, MetricComparison, } from './types.js';
|
|
17
|
+
export { formatReportAsJson, formatReportAsText, formatBytes } from './formatters.js';
|
|
18
|
+
export { compareReports, hasRegressions, getRegressedBenchmarks, getImprovedBenchmarks, } from './comparator.js';
|
|
150
19
|
/**
|
|
151
20
|
* Core benchmark runner for performance testing
|
|
152
21
|
*/
|
|
@@ -217,42 +86,4 @@ export declare class BenchmarkRunner {
|
|
|
217
86
|
*/
|
|
218
87
|
getMemoryReport(): string;
|
|
219
88
|
}
|
|
220
|
-
/**
|
|
221
|
-
* Format a benchmark report as JSON for CI integration
|
|
222
|
-
*/
|
|
223
|
-
export declare function formatReportAsJson(report: BenchmarkReport): string;
|
|
224
|
-
/**
|
|
225
|
-
* Format a benchmark report as human-readable text
|
|
226
|
-
*/
|
|
227
|
-
export declare function formatReportAsText(report: BenchmarkReport): string;
|
|
228
|
-
/**
|
|
229
|
-
* Compare two benchmark reports
|
|
230
|
-
*/
|
|
231
|
-
export declare function compareReports(baseline: BenchmarkReport, current: BenchmarkReport): ComparisonResult;
|
|
232
|
-
/**
|
|
233
|
-
* Comparison result between two reports
|
|
234
|
-
*/
|
|
235
|
-
export interface ComparisonResult {
|
|
236
|
-
baseline: string;
|
|
237
|
-
current: string;
|
|
238
|
-
comparisons: Record<string, MetricComparison>;
|
|
239
|
-
summary: {
|
|
240
|
-
totalComparisons: number;
|
|
241
|
-
regressions: number;
|
|
242
|
-
improvements: number;
|
|
243
|
-
unchanged: number;
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Single metric comparison
|
|
248
|
-
*/
|
|
249
|
-
export interface MetricComparison {
|
|
250
|
-
baseline: BenchmarkStats;
|
|
251
|
-
current: BenchmarkStats;
|
|
252
|
-
p50ChangePercent: number;
|
|
253
|
-
p95ChangePercent: number;
|
|
254
|
-
p99ChangePercent: number;
|
|
255
|
-
isRegression: boolean;
|
|
256
|
-
isImprovement: boolean;
|
|
257
|
-
}
|
|
258
89
|
//# sourceMappingURL=BenchmarkRunner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BenchmarkRunner.d.ts","sourceRoot":"","sources":["../../../src/benchmarks/BenchmarkRunner.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"BenchmarkRunner.d.ts","sourceRoot":"","sources":["../../../src/benchmarks/BenchmarkRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EACL,cAAc,EACd,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAIzB,MAAM,YAAY,CAAA;AAGnB,YAAY,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACrF,OAAO,EACL,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AAExB;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,OAAO,CAAwB;IACvC,wCAAwC;IACxC,OAAO,CAAC,cAAc,CAA8B;gBAExC,MAAM,GAAE,eAAoB;IAYxC;;OAEG;IACH,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACH,GAAG,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI;IAK1C;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC;IA4BrC;;OAEG;YACW,YAAY;IAgF1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAiEtB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA4CtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAchB;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;OAEG;IACH,UAAU,IAAI,eAAe,EAAE;IAI/B;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI;IAQtE;;OAEG;IACH,eAAe,IAAI,MAAM;CAM1B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SMI-632: BenchmarkRunner - Performance benchmark infrastructure
|
|
3
3
|
* SMI-689: Enhanced with MemoryProfiler integration
|
|
4
|
+
* SMI-1189: Refactored to use extracted modules
|
|
4
5
|
*
|
|
5
6
|
* Features:
|
|
6
7
|
* - Run benchmark suites
|
|
@@ -14,15 +15,10 @@ import * as os from 'os';
|
|
|
14
15
|
import * as fs from 'fs';
|
|
15
16
|
import { percentile, sampleStddev, mean } from './stats.js';
|
|
16
17
|
import { MemoryProfiler, } from './MemoryProfiler.js';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
suiteName: 'default',
|
|
22
|
-
enableMemoryProfiler: false,
|
|
23
|
-
memoryRegressionThreshold: 10,
|
|
24
|
-
memoryBaselines: {},
|
|
25
|
-
};
|
|
18
|
+
import { DEFAULT_CONFIG, } from './types.js';
|
|
19
|
+
// Re-export formatters and comparator for backwards compatibility
|
|
20
|
+
export { formatReportAsJson, formatReportAsText, formatBytes } from './formatters.js';
|
|
21
|
+
export { compareReports, hasRegressions, getRegressedBenchmarks, getImprovedBenchmarks, } from './comparator.js';
|
|
26
22
|
/**
|
|
27
23
|
* Core benchmark runner for performance testing
|
|
28
24
|
*/
|
|
@@ -98,7 +94,7 @@ export class BenchmarkRunner {
|
|
|
98
94
|
try {
|
|
99
95
|
await definition.fn();
|
|
100
96
|
}
|
|
101
|
-
catch (
|
|
97
|
+
catch (_err) {
|
|
102
98
|
// Ignore warmup errors, just continue
|
|
103
99
|
}
|
|
104
100
|
}
|
|
@@ -337,117 +333,4 @@ export class BenchmarkRunner {
|
|
|
337
333
|
return this.memoryProfiler.formatMemoryReport();
|
|
338
334
|
}
|
|
339
335
|
}
|
|
340
|
-
/**
|
|
341
|
-
* Format a benchmark report as JSON for CI integration
|
|
342
|
-
*/
|
|
343
|
-
export function formatReportAsJson(report) {
|
|
344
|
-
return JSON.stringify(report, null, 2);
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Format a benchmark report as human-readable text
|
|
348
|
-
*/
|
|
349
|
-
export function formatReportAsText(report) {
|
|
350
|
-
const lines = [
|
|
351
|
-
`Benchmark Report: ${report.suite}`,
|
|
352
|
-
`Timestamp: ${report.timestamp}`,
|
|
353
|
-
`Environment: Node ${report.environment.node} on ${report.environment.platform}/${report.environment.arch}`,
|
|
354
|
-
`Docker: ${report.environment.docker ? 'Yes' : 'No'}`,
|
|
355
|
-
'',
|
|
356
|
-
'Results:',
|
|
357
|
-
'-'.repeat(80),
|
|
358
|
-
];
|
|
359
|
-
for (const [name, stats] of Object.entries(report.results)) {
|
|
360
|
-
lines.push(` ${name}:`);
|
|
361
|
-
lines.push(` Iterations: ${stats.iterations}`);
|
|
362
|
-
lines.push(` p50: ${stats.p50_ms}ms, p95: ${stats.p95_ms}ms, p99: ${stats.p99_ms}ms`);
|
|
363
|
-
lines.push(` Mean: ${stats.mean_ms}ms, StdDev: ${stats.stddev_ms}ms`);
|
|
364
|
-
lines.push(` Min: ${stats.min_ms}ms, Max: ${stats.max_ms}ms`);
|
|
365
|
-
if (stats.memoryPeak_mb !== undefined) {
|
|
366
|
-
lines.push(` Memory Peak: ${stats.memoryPeak_mb}MB`);
|
|
367
|
-
}
|
|
368
|
-
// SMI-689: Add detailed memory profile if available
|
|
369
|
-
if (report.memoryProfile?.[name]) {
|
|
370
|
-
const mp = report.memoryProfile[name];
|
|
371
|
-
lines.push(` Memory Profile:`);
|
|
372
|
-
lines.push(` Heap Growth: ${formatBytes(mp.heapGrowth)} (${mp.heapGrowthPercent.toFixed(1)}%)`);
|
|
373
|
-
lines.push(` Peak Heap: ${formatBytes(mp.peakHeapSize)}`);
|
|
374
|
-
lines.push(` Samples: ${mp.sampleCount}`);
|
|
375
|
-
}
|
|
376
|
-
lines.push('');
|
|
377
|
-
}
|
|
378
|
-
lines.push('-'.repeat(80));
|
|
379
|
-
lines.push(`Summary:`);
|
|
380
|
-
lines.push(` Total Benchmarks: ${report.summary.totalBenchmarks}`);
|
|
381
|
-
lines.push(` Total Iterations: ${report.summary.totalIterations}`);
|
|
382
|
-
lines.push(` Total Duration: ${report.summary.totalDuration_ms}ms`);
|
|
383
|
-
// SMI-689: Add memory regression summary
|
|
384
|
-
if (report.memoryRegression) {
|
|
385
|
-
lines.push('');
|
|
386
|
-
lines.push('Memory Regression Check:');
|
|
387
|
-
if (report.memoryRegression.hasRegressions) {
|
|
388
|
-
lines.push(` WARNING: ${report.memoryRegression.regressions.length} regression(s) detected (threshold: ${report.memoryRegression.threshold}%)`);
|
|
389
|
-
for (const reg of report.memoryRegression.regressions) {
|
|
390
|
-
lines.push(` - ${reg.label}: ${reg.changePercent.toFixed(1)}% increase`);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
lines.push(` No memory regressions detected (threshold: ${report.memoryRegression.threshold}%)`);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
return lines.join('\n');
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Format bytes to human-readable string (internal helper)
|
|
401
|
-
*/
|
|
402
|
-
function formatBytes(bytes) {
|
|
403
|
-
if (bytes === 0)
|
|
404
|
-
return '0 B';
|
|
405
|
-
const k = 1024;
|
|
406
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
407
|
-
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));
|
|
408
|
-
const value = bytes / Math.pow(k, i);
|
|
409
|
-
return `${value.toFixed(1)} ${sizes[i]}`;
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Compare two benchmark reports
|
|
413
|
-
*/
|
|
414
|
-
export function compareReports(baseline, current) {
|
|
415
|
-
const comparisons = {};
|
|
416
|
-
let regressions = 0;
|
|
417
|
-
let improvements = 0;
|
|
418
|
-
for (const [name, currentStats] of Object.entries(current.results)) {
|
|
419
|
-
const baselineStats = baseline.results[name];
|
|
420
|
-
if (!baselineStats)
|
|
421
|
-
continue;
|
|
422
|
-
const p50Change = ((currentStats.p50_ms - baselineStats.p50_ms) / baselineStats.p50_ms) * 100;
|
|
423
|
-
const p95Change = ((currentStats.p95_ms - baselineStats.p95_ms) / baselineStats.p95_ms) * 100;
|
|
424
|
-
const p99Change = ((currentStats.p99_ms - baselineStats.p99_ms) / baselineStats.p99_ms) * 100;
|
|
425
|
-
const isRegression = p95Change > 10; // 10% threshold
|
|
426
|
-
const isImprovement = p95Change < -10;
|
|
427
|
-
if (isRegression)
|
|
428
|
-
regressions++;
|
|
429
|
-
if (isImprovement)
|
|
430
|
-
improvements++;
|
|
431
|
-
comparisons[name] = {
|
|
432
|
-
baseline: baselineStats,
|
|
433
|
-
current: currentStats,
|
|
434
|
-
p50ChangePercent: Math.round(p50Change * 100) / 100,
|
|
435
|
-
p95ChangePercent: Math.round(p95Change * 100) / 100,
|
|
436
|
-
p99ChangePercent: Math.round(p99Change * 100) / 100,
|
|
437
|
-
isRegression,
|
|
438
|
-
isImprovement,
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
return {
|
|
442
|
-
baseline: baseline.timestamp,
|
|
443
|
-
current: current.timestamp,
|
|
444
|
-
comparisons,
|
|
445
|
-
summary: {
|
|
446
|
-
totalComparisons: Object.keys(comparisons).length,
|
|
447
|
-
regressions,
|
|
448
|
-
improvements,
|
|
449
|
-
unchanged: Object.keys(comparisons).length - regressions - improvements,
|
|
450
|
-
},
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
336
|
//# sourceMappingURL=BenchmarkRunner.js.map
|