@mcptoolshop/registry-stats 0.3.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.
@@ -0,0 +1,130 @@
1
+ import * as node_http from 'node:http';
2
+ import { IncomingMessage, ServerResponse } from 'node:http';
3
+
4
+ type RegistryName = 'npm' | 'pypi' | 'nuget' | 'vscode' | 'docker';
5
+ interface PackageStats {
6
+ registry: RegistryName;
7
+ package: string;
8
+ downloads: {
9
+ total?: number;
10
+ lastDay?: number;
11
+ lastWeek?: number;
12
+ lastMonth?: number;
13
+ };
14
+ extra?: Record<string, unknown>;
15
+ fetchedAt: string;
16
+ }
17
+ interface DailyDownloads {
18
+ date: string;
19
+ downloads: number;
20
+ }
21
+ interface RateLimitConfig {
22
+ /** Max requests per window */
23
+ maxRequests: number;
24
+ /** Window duration in seconds */
25
+ windowSeconds: number;
26
+ /** Whether auth raises the limit */
27
+ authRaisesLimit: boolean;
28
+ }
29
+ interface RegistryProvider {
30
+ name: string;
31
+ getStats(pkg: string, options?: StatsOptions): Promise<PackageStats | null>;
32
+ getRange?(pkg: string, start: string, end: string): Promise<DailyDownloads[]>;
33
+ rateLimit?: RateLimitConfig;
34
+ }
35
+ interface StatsCache {
36
+ get(key: string): PackageStats | DailyDownloads[] | undefined;
37
+ set(key: string, value: PackageStats | DailyDownloads[], ttlMs: number): void;
38
+ }
39
+ interface StatsOptions {
40
+ dockerToken?: string;
41
+ /** Max concurrent requests for bulk operations (default: 5) */
42
+ concurrency?: number;
43
+ /** Cache instance — use createCache() for built-in TTL cache */
44
+ cache?: StatsCache;
45
+ /** Cache TTL in milliseconds (default: 300000 = 5 min) */
46
+ cacheTtlMs?: number;
47
+ }
48
+ interface PackageConfig {
49
+ /** Registry-specific package identifiers */
50
+ [registry: string]: string;
51
+ }
52
+ interface Config {
53
+ /** Default registries to query when none specified */
54
+ registries?: string[];
55
+ /** Tracked packages — key is display name, value maps registries to package IDs */
56
+ packages?: Record<string, PackageConfig>;
57
+ /** Enable caching (default: true) */
58
+ cache?: boolean;
59
+ /** Cache TTL in milliseconds (default: 300000 = 5 min) */
60
+ cacheTtlMs?: number;
61
+ /** Max concurrent requests (default: 5) */
62
+ concurrency?: number;
63
+ /** Docker Hub auth token */
64
+ dockerToken?: string;
65
+ }
66
+ interface ComparisonResult {
67
+ package: string;
68
+ registries: Record<string, PackageStats>;
69
+ fetchedAt: string;
70
+ }
71
+ interface ChartData {
72
+ labels: string[];
73
+ datasets: {
74
+ label: string;
75
+ data: number[];
76
+ }[];
77
+ }
78
+ declare class RegistryError extends Error {
79
+ registry: RegistryName;
80
+ statusCode: number;
81
+ retryAfter?: number | undefined;
82
+ constructor(registry: RegistryName, statusCode: number, message: string, retryAfter?: number | undefined);
83
+ }
84
+
85
+ declare const calc: {
86
+ total(records: DailyDownloads[]): number;
87
+ avg(records: DailyDownloads[]): number;
88
+ group(records: DailyDownloads[], fn: (r: DailyDownloads) => string): Record<string, DailyDownloads[]>;
89
+ monthly(records: DailyDownloads[]): Record<string, DailyDownloads[]>;
90
+ yearly(records: DailyDownloads[]): Record<string, DailyDownloads[]>;
91
+ groupTotals(grouped: Record<string, DailyDownloads[]>): Record<string, number>;
92
+ groupAvgs(grouped: Record<string, DailyDownloads[]>): Record<string, number>;
93
+ trend(records: DailyDownloads[], windowDays?: number): {
94
+ slope: number;
95
+ direction: "up" | "down" | "flat";
96
+ changePercent: number;
97
+ };
98
+ movingAvg(records: DailyDownloads[], windowDays?: number): DailyDownloads[];
99
+ popularity(records: DailyDownloads[]): number;
100
+ toCSV(records: DailyDownloads[]): string;
101
+ toChartData(records: DailyDownloads[], label?: string): ChartData;
102
+ };
103
+
104
+ declare function loadConfig(startDir?: string): Config | null;
105
+ declare function defaultConfig(): Config;
106
+ declare function starterConfig(): string;
107
+
108
+ interface ServerOptions {
109
+ port?: number;
110
+ cache?: boolean;
111
+ corsOrigin?: string;
112
+ }
113
+ type Handler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
114
+ /** Creates a request handler suitable for Node http.createServer or serverless adapters. */
115
+ declare function createHandler(opts?: StatsOptions): Handler;
116
+ /** Starts an HTTP server. Returns the server instance. */
117
+ declare function serve(opts?: ServerOptions): node_http.Server<typeof IncomingMessage, typeof ServerResponse>;
118
+
119
+ declare function createCache(): StatsCache;
120
+
121
+ declare function registerProvider(provider: RegistryProvider): void;
122
+ declare function stats(registry: string, pkg: string, options?: StatsOptions): Promise<PackageStats | null>;
123
+ declare namespace stats {
124
+ var all: (pkg: string, options?: StatsOptions) => Promise<PackageStats[]>;
125
+ var bulk: (registry: string, packages: string[], options?: StatsOptions) => Promise<(PackageStats | null)[]>;
126
+ var range: (registry: string, pkg: string, start: string, end: string, options?: StatsOptions) => Promise<DailyDownloads[]>;
127
+ var compare: (pkg: string, registries?: string[], options?: StatsOptions) => Promise<ComparisonResult>;
128
+ }
129
+
130
+ export { type ChartData, type ComparisonResult, type Config, type DailyDownloads, type PackageConfig, type PackageStats, type RateLimitConfig, RegistryError, type RegistryName, type RegistryProvider, type ServerOptions, type StatsCache, type StatsOptions, calc, createCache, createHandler, defaultConfig, loadConfig, registerProvider, serve, starterConfig, stats };
@@ -0,0 +1,130 @@
1
+ import * as node_http from 'node:http';
2
+ import { IncomingMessage, ServerResponse } from 'node:http';
3
+
4
+ type RegistryName = 'npm' | 'pypi' | 'nuget' | 'vscode' | 'docker';
5
+ interface PackageStats {
6
+ registry: RegistryName;
7
+ package: string;
8
+ downloads: {
9
+ total?: number;
10
+ lastDay?: number;
11
+ lastWeek?: number;
12
+ lastMonth?: number;
13
+ };
14
+ extra?: Record<string, unknown>;
15
+ fetchedAt: string;
16
+ }
17
+ interface DailyDownloads {
18
+ date: string;
19
+ downloads: number;
20
+ }
21
+ interface RateLimitConfig {
22
+ /** Max requests per window */
23
+ maxRequests: number;
24
+ /** Window duration in seconds */
25
+ windowSeconds: number;
26
+ /** Whether auth raises the limit */
27
+ authRaisesLimit: boolean;
28
+ }
29
+ interface RegistryProvider {
30
+ name: string;
31
+ getStats(pkg: string, options?: StatsOptions): Promise<PackageStats | null>;
32
+ getRange?(pkg: string, start: string, end: string): Promise<DailyDownloads[]>;
33
+ rateLimit?: RateLimitConfig;
34
+ }
35
+ interface StatsCache {
36
+ get(key: string): PackageStats | DailyDownloads[] | undefined;
37
+ set(key: string, value: PackageStats | DailyDownloads[], ttlMs: number): void;
38
+ }
39
+ interface StatsOptions {
40
+ dockerToken?: string;
41
+ /** Max concurrent requests for bulk operations (default: 5) */
42
+ concurrency?: number;
43
+ /** Cache instance — use createCache() for built-in TTL cache */
44
+ cache?: StatsCache;
45
+ /** Cache TTL in milliseconds (default: 300000 = 5 min) */
46
+ cacheTtlMs?: number;
47
+ }
48
+ interface PackageConfig {
49
+ /** Registry-specific package identifiers */
50
+ [registry: string]: string;
51
+ }
52
+ interface Config {
53
+ /** Default registries to query when none specified */
54
+ registries?: string[];
55
+ /** Tracked packages — key is display name, value maps registries to package IDs */
56
+ packages?: Record<string, PackageConfig>;
57
+ /** Enable caching (default: true) */
58
+ cache?: boolean;
59
+ /** Cache TTL in milliseconds (default: 300000 = 5 min) */
60
+ cacheTtlMs?: number;
61
+ /** Max concurrent requests (default: 5) */
62
+ concurrency?: number;
63
+ /** Docker Hub auth token */
64
+ dockerToken?: string;
65
+ }
66
+ interface ComparisonResult {
67
+ package: string;
68
+ registries: Record<string, PackageStats>;
69
+ fetchedAt: string;
70
+ }
71
+ interface ChartData {
72
+ labels: string[];
73
+ datasets: {
74
+ label: string;
75
+ data: number[];
76
+ }[];
77
+ }
78
+ declare class RegistryError extends Error {
79
+ registry: RegistryName;
80
+ statusCode: number;
81
+ retryAfter?: number | undefined;
82
+ constructor(registry: RegistryName, statusCode: number, message: string, retryAfter?: number | undefined);
83
+ }
84
+
85
+ declare const calc: {
86
+ total(records: DailyDownloads[]): number;
87
+ avg(records: DailyDownloads[]): number;
88
+ group(records: DailyDownloads[], fn: (r: DailyDownloads) => string): Record<string, DailyDownloads[]>;
89
+ monthly(records: DailyDownloads[]): Record<string, DailyDownloads[]>;
90
+ yearly(records: DailyDownloads[]): Record<string, DailyDownloads[]>;
91
+ groupTotals(grouped: Record<string, DailyDownloads[]>): Record<string, number>;
92
+ groupAvgs(grouped: Record<string, DailyDownloads[]>): Record<string, number>;
93
+ trend(records: DailyDownloads[], windowDays?: number): {
94
+ slope: number;
95
+ direction: "up" | "down" | "flat";
96
+ changePercent: number;
97
+ };
98
+ movingAvg(records: DailyDownloads[], windowDays?: number): DailyDownloads[];
99
+ popularity(records: DailyDownloads[]): number;
100
+ toCSV(records: DailyDownloads[]): string;
101
+ toChartData(records: DailyDownloads[], label?: string): ChartData;
102
+ };
103
+
104
+ declare function loadConfig(startDir?: string): Config | null;
105
+ declare function defaultConfig(): Config;
106
+ declare function starterConfig(): string;
107
+
108
+ interface ServerOptions {
109
+ port?: number;
110
+ cache?: boolean;
111
+ corsOrigin?: string;
112
+ }
113
+ type Handler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
114
+ /** Creates a request handler suitable for Node http.createServer or serverless adapters. */
115
+ declare function createHandler(opts?: StatsOptions): Handler;
116
+ /** Starts an HTTP server. Returns the server instance. */
117
+ declare function serve(opts?: ServerOptions): node_http.Server<typeof IncomingMessage, typeof ServerResponse>;
118
+
119
+ declare function createCache(): StatsCache;
120
+
121
+ declare function registerProvider(provider: RegistryProvider): void;
122
+ declare function stats(registry: string, pkg: string, options?: StatsOptions): Promise<PackageStats | null>;
123
+ declare namespace stats {
124
+ var all: (pkg: string, options?: StatsOptions) => Promise<PackageStats[]>;
125
+ var bulk: (registry: string, packages: string[], options?: StatsOptions) => Promise<(PackageStats | null)[]>;
126
+ var range: (registry: string, pkg: string, start: string, end: string, options?: StatsOptions) => Promise<DailyDownloads[]>;
127
+ var compare: (pkg: string, registries?: string[], options?: StatsOptions) => Promise<ComparisonResult>;
128
+ }
129
+
130
+ export { type ChartData, type ComparisonResult, type Config, type DailyDownloads, type PackageConfig, type PackageStats, type RateLimitConfig, RegistryError, type RegistryName, type RegistryProvider, type ServerOptions, type StatsCache, type StatsOptions, calc, createCache, createHandler, defaultConfig, loadConfig, registerProvider, serve, starterConfig, stats };