recker 1.0.15 → 1.0.16
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/README.md +86 -97
- package/dist/ai/providers/anthropic.d.ts.map +1 -1
- package/dist/ai/providers/anthropic.js +4 -1
- package/dist/ai/providers/base.d.ts.map +1 -1
- package/dist/ai/providers/base.js +7 -2
- package/dist/ai/rate-limiter.d.ts.map +1 -1
- package/dist/ai/rate-limiter.js +4 -1
- package/dist/bench/generator.d.ts.map +1 -1
- package/dist/bench/generator.js +8 -3
- package/dist/bench/stats.d.ts +15 -1
- package/dist/bench/stats.d.ts.map +1 -1
- package/dist/bench/stats.js +117 -5
- package/dist/cache/memory-storage.d.ts.map +1 -1
- package/dist/cache/memory-storage.js +3 -2
- package/dist/cli/handler.js +14 -14
- package/dist/cli/index.js +602 -48
- package/dist/cli/presets.js +5 -5
- package/dist/cli/tui/ai-chat.js +10 -10
- package/dist/cli/tui/load-dashboard.d.ts.map +1 -1
- package/dist/cli/tui/load-dashboard.js +127 -32
- package/dist/cli/tui/scroll-buffer.d.ts +43 -0
- package/dist/cli/tui/scroll-buffer.d.ts.map +1 -0
- package/dist/cli/tui/scroll-buffer.js +162 -0
- package/dist/cli/tui/search-panel.d.ts +41 -0
- package/dist/cli/tui/search-panel.d.ts.map +1 -0
- package/dist/cli/tui/search-panel.js +419 -0
- package/dist/cli/tui/shell.d.ts +14 -0
- package/dist/cli/tui/shell.d.ts.map +1 -1
- package/dist/cli/tui/shell.js +424 -46
- package/dist/cli/tui/websocket.js +17 -17
- package/dist/contract/index.js +3 -2
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +18 -26
- package/dist/core/errors.d.ts +109 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +214 -1
- package/dist/core/request-promise.d.ts.map +1 -1
- package/dist/core/request-promise.js +5 -6
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +5 -6
- package/dist/dns/index.d.ts +1 -0
- package/dist/dns/index.d.ts.map +1 -1
- package/dist/dns/index.js +1 -0
- package/dist/dns/propagation.d.ts +21 -0
- package/dist/dns/propagation.d.ts.map +1 -0
- package/dist/dns/propagation.js +169 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +10 -11
- package/dist/mcp/embeddings-loader.d.ts +18 -0
- package/dist/mcp/embeddings-loader.d.ts.map +1 -0
- package/dist/mcp/embeddings-loader.js +162 -0
- package/dist/mcp/geoip-loader.d.ts +11 -0
- package/dist/mcp/geoip-loader.d.ts.map +1 -0
- package/dist/mcp/geoip-loader.js +107 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/ip-intel.d.ts +28 -0
- package/dist/mcp/ip-intel.d.ts.map +1 -0
- package/dist/mcp/ip-intel.js +209 -0
- package/dist/mcp/search/hybrid-search.d.ts.map +1 -1
- package/dist/mcp/search/hybrid-search.js +12 -22
- package/dist/mcp/search/math.d.ts.map +1 -1
- package/dist/mcp/search/math.js +5 -1
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +122 -2
- package/dist/plugins/compression.js +4 -2
- package/dist/plugins/har-player.d.ts.map +1 -1
- package/dist/plugins/har-player.js +8 -11
- package/dist/plugins/odata.d.ts.map +1 -1
- package/dist/plugins/odata.js +5 -2
- package/dist/protocols/ftp.d.ts.map +1 -1
- package/dist/protocols/ftp.js +69 -16
- package/dist/protocols/sftp.d.ts.map +1 -1
- package/dist/protocols/sftp.js +13 -3
- package/dist/protocols/telnet.d.ts.map +1 -1
- package/dist/protocols/telnet.js +25 -6
- package/dist/recker.d.ts +47 -0
- package/dist/recker.d.ts.map +1 -0
- package/dist/recker.js +99 -0
- package/dist/transport/base-udp.d.ts.map +1 -1
- package/dist/transport/base-udp.js +7 -4
- package/dist/transport/udp-response.d.ts.map +1 -1
- package/dist/transport/udp-response.js +10 -3
- package/dist/transport/udp.d.ts.map +1 -1
- package/dist/transport/udp.js +5 -1
- package/dist/transport/undici.d.ts.map +1 -1
- package/dist/transport/undici.js +75 -63
- package/dist/utils/agent-manager.d.ts +1 -0
- package/dist/utils/agent-manager.d.ts.map +1 -1
- package/dist/utils/agent-manager.js +11 -0
- package/dist/utils/client-pool.d.ts.map +1 -1
- package/dist/utils/client-pool.js +4 -1
- package/dist/utils/colors.d.ts +16 -0
- package/dist/utils/colors.d.ts.map +1 -1
- package/dist/utils/colors.js +16 -0
- package/dist/utils/dns-toolkit.d.ts +88 -1
- package/dist/utils/dns-toolkit.d.ts.map +1 -1
- package/dist/utils/dns-toolkit.js +704 -6
- package/dist/utils/doh.d.ts.map +1 -1
- package/dist/utils/doh.js +13 -16
- package/dist/utils/download.d.ts.map +1 -1
- package/dist/utils/download.js +10 -11
- package/dist/utils/rdap.d.ts +9 -0
- package/dist/utils/rdap.d.ts.map +1 -1
- package/dist/utils/rdap.js +78 -9
- package/dist/utils/security-grader.d.ts +47 -0
- package/dist/utils/security-grader.d.ts.map +1 -0
- package/dist/utils/security-grader.js +637 -0
- package/dist/utils/sparkline.d.ts +18 -0
- package/dist/utils/sparkline.d.ts.map +1 -0
- package/dist/utils/sparkline.js +55 -0
- package/dist/utils/sse.d.ts.map +1 -1
- package/dist/utils/sse.js +5 -6
- package/dist/utils/system-metrics.d.ts +26 -0
- package/dist/utils/system-metrics.d.ts.map +1 -0
- package/dist/utils/system-metrics.js +81 -0
- package/dist/utils/tls-inspector.d.ts +6 -0
- package/dist/utils/tls-inspector.d.ts.map +1 -1
- package/dist/utils/tls-inspector.js +35 -1
- package/dist/webrtc/index.d.ts.map +1 -1
- package/dist/webrtc/index.js +21 -7
- package/dist/websocket/client.d.ts.map +1 -1
- package/dist/websocket/client.js +13 -16
- package/package.json +4 -3
- package/dist/mcp/data/embeddings.json +0 -1
package/README.md
CHANGED
|
@@ -2,155 +2,144 @@
|
|
|
2
2
|
|
|
3
3
|
# ⚡ Recker
|
|
4
4
|
|
|
5
|
-
### The
|
|
5
|
+
### The Network SDK for the AI Era
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Zero-config HTTP. Multi-protocol support. AI-native streaming. Observable to the millisecond.**
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/recker)
|
|
10
10
|
[](https://www.npmjs.com/package/recker)
|
|
11
11
|
[](https://www.typescriptlang.org/)
|
|
12
12
|
[](https://nodejs.org/)
|
|
13
|
-
[](https://github.com/forattini-dev/recker)
|
|
14
14
|
[](https://github.com/forattini-dev/recker/blob/main/LICENSE)
|
|
15
15
|
|
|
16
|
-
[Documentation](https://forattini-dev.github.io/recker) · [
|
|
16
|
+
[Documentation](https://forattini-dev.github.io/recker) · [API Reference](./docs/reference/01-api.md) · [Examples](./docs/examples/README.md)
|
|
17
17
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Install
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
npm install recker
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Quick Start
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import {
|
|
31
|
+
import { get, post, whois, dns } from 'recker';
|
|
32
|
+
import { rdap, supportsRDAP } from 'recker/utils/rdap';
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
// HTTP - zero config
|
|
35
|
+
const users = await get('https://api.example.com/users').json();
|
|
36
|
+
await post('https://api.example.com/users', { json: { name: 'John' } });
|
|
34
37
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
38
|
+
// WHOIS
|
|
39
|
+
const info = await whois('github.com');
|
|
37
40
|
|
|
38
|
-
//
|
|
39
|
-
|
|
41
|
+
// RDAP (modern WHOIS)
|
|
42
|
+
if (supportsRDAP('com')) {
|
|
43
|
+
const data = await rdap(client, 'google.com');
|
|
44
|
+
console.log(data.status, data.events);
|
|
45
|
+
}
|
|
40
46
|
|
|
41
|
-
//
|
|
42
|
-
|
|
47
|
+
// DNS
|
|
48
|
+
const ips = await dns('google.com');
|
|
43
49
|
```
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
### Unified Namespace
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { recker } from 'recker';
|
|
55
|
+
|
|
56
|
+
// Everything in one place
|
|
57
|
+
await recker.get('https://api.example.com/users').json();
|
|
58
|
+
await recker.whois('github.com');
|
|
59
|
+
await recker.dns('google.com');
|
|
60
|
+
await recker.ai.chat('Hello!');
|
|
61
|
+
|
|
62
|
+
const socket = recker.ws('wss://api.example.com/ws');
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### With Configuration
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { createClient } from 'recker';
|
|
69
|
+
|
|
70
|
+
const api = createClient({
|
|
71
|
+
baseUrl: 'https://api.example.com',
|
|
72
|
+
headers: { 'Authorization': 'Bearer token' },
|
|
73
|
+
timeout: 10000,
|
|
74
|
+
retry: { maxAttempts: 3 }
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const user = await api.get('/users/:id', { params: { id: '123' } }).json();
|
|
78
|
+
```
|
|
46
79
|
|
|
47
|
-
|
|
80
|
+
## Features
|
|
48
81
|
|
|
49
82
|
| Feature | Description |
|
|
50
83
|
|:---|:---|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
84
|
+
| **Zero Config** | Direct functions work out of the box. No setup required. |
|
|
85
|
+
| **Multi-Protocol** | HTTP, WebSocket, DNS, WHOIS, RDAP, FTP, SFTP, Telnet in one SDK. |
|
|
86
|
+
| **AI-Native** | SSE streaming, token counting, provider abstraction. |
|
|
87
|
+
| **Type-Safe** | Full TypeScript with Zod schema validation. |
|
|
88
|
+
| **Observable** | DNS/TCP/TLS/TTFB timing breakdown per request. |
|
|
89
|
+
| **Resilient** | Retry, circuit breaker, rate limiting, deduplication. |
|
|
90
|
+
| **GeoIP (Offline)** | MaxMind GeoLite2 database with bogon detection. |
|
|
91
|
+
| **RDAP Support** | Modern WHOIS with IANA Bootstrap and TLD detection. |
|
|
57
92
|
|
|
58
|
-
##
|
|
93
|
+
## Highlights
|
|
59
94
|
|
|
60
|
-
###
|
|
61
|
-
Handle LLM streams effortlessly with the `.sse()` iterator.
|
|
95
|
+
### AI Streaming
|
|
62
96
|
|
|
63
97
|
```typescript
|
|
64
|
-
for await (const event of
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
98
|
+
for await (const event of recker.ai.stream({
|
|
99
|
+
model: 'gpt-4',
|
|
100
|
+
messages: [{ role: 'user', content: 'Hello!' }]
|
|
101
|
+
})) {
|
|
102
|
+
process.stdout.write(event.choices[0]?.delta?.content || '');
|
|
68
103
|
}
|
|
69
104
|
```
|
|
70
105
|
|
|
71
|
-
###
|
|
72
|
-
|
|
106
|
+
### Request Timing
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const response = await get('https://api.example.com/data');
|
|
110
|
+
console.log(response.timings);
|
|
111
|
+
// { dns: 12, tcp: 8, tls: 45, firstByte: 23, total: 156 }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Scraping
|
|
73
115
|
|
|
74
116
|
```typescript
|
|
75
117
|
const doc = await client.scrape('https://example.com');
|
|
76
118
|
const titles = doc.selectAll('h1').map(el => el.text());
|
|
77
119
|
```
|
|
78
120
|
|
|
79
|
-
###
|
|
80
|
-
Configure advanced retry policies in declarative style.
|
|
121
|
+
### Circuit Breaker
|
|
81
122
|
|
|
82
123
|
```typescript
|
|
124
|
+
import { createClient, circuitBreaker } from 'recker';
|
|
125
|
+
|
|
83
126
|
const client = createClient({
|
|
127
|
+
baseUrl: 'https://api.example.com',
|
|
84
128
|
plugins: [
|
|
85
|
-
|
|
129
|
+
circuitBreaker({ threshold: 5, resetTimeout: 30000 })
|
|
86
130
|
]
|
|
87
131
|
});
|
|
88
132
|
```
|
|
89
133
|
|
|
90
|
-
|
|
91
|
-
Know exactly where your latency comes from.
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
const { timings } = await client.get('/api/data');
|
|
95
|
-
console.log(timings);
|
|
96
|
-
// { dns: 12ms, tcp: 8ms, tls: 45ms, firstByte: 23ms, total: 156ms }
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## 📚 Documentation
|
|
100
|
-
|
|
101
|
-
**Getting Started**
|
|
102
|
-
- [Installation](./docs/getting-started/installation.md)
|
|
103
|
-
- [Quick Start](./docs/http/01-quickstart.md)
|
|
104
|
-
- [Client Configuration](./docs/http/05-configuration.md)
|
|
105
|
-
|
|
106
|
-
**Core Features**
|
|
107
|
-
- [HTTP Fundamentals](./docs/http/02-fundamentals.md)
|
|
108
|
-
- [Streaming & SSE](./docs/ai/02-streaming.md)
|
|
109
|
-
- [Retry & Resilience](./docs/http/07-resilience.md)
|
|
110
|
-
- [Caching](./docs/http/09-cache.md)
|
|
111
|
-
- [Concurrency](./docs/http/08-concurrency.md)
|
|
112
|
-
|
|
113
|
-
**Integrations**
|
|
114
|
-
- [GraphQL](./docs/http/13-graphql.md)
|
|
115
|
-
- [Scraping](./docs/http/14-scraping.md)
|
|
116
|
-
- [Plugins](./docs/http/10-plugins.md)
|
|
117
|
-
|
|
118
|
-
**Reference**
|
|
119
|
-
- [API Reference](./docs/reference/01-api.md)
|
|
120
|
-
- [Troubleshooting](./docs/reference/05-troubleshooting.md)
|
|
121
|
-
- [Examples](./docs/examples/README.md)
|
|
122
|
-
|
|
123
|
-
## ❤️ Acknowledgements
|
|
124
|
-
|
|
125
|
-
At Recker, we are passionate about these incredible open-source technologies. We are here to celebrate the past achievements that shaped the internet as we know it today, and to prepare ourselves for the future of web development.
|
|
126
|
-
|
|
127
|
-
Recker stands on the shoulders of giants. We extend our deepest gratitude to these projects:
|
|
128
|
-
|
|
129
|
-
<div align="center">
|
|
130
|
-
|
|
131
|
-
| | | |
|
|
132
|
-
|:---|:---|:---|
|
|
133
|
-
| **[Apollo Client](https://github.com/apollographql/apollo-client)** | **[Axios](https://github.com/axios/axios)** | **[Cheerio](https://github.com/cheeriojs/cheerio)** |
|
|
134
|
-
| **[Cookie](https://github.com/jshttp/cookie)** | **[Got](https://github.com/sindresorhus/got)** | **[GraphQL.js](https://github.com/graphql/graphql-js)** |
|
|
135
|
-
| **[Ky](https://github.com/sindresorhus/ky)** | **[Needle](https://github.com/tomas/needle)** | **[Node-libcurl](https://github.com/JCMais/node-libcurl)** |
|
|
136
|
-
| **[SuperAgent](https://github.com/ladjs/superagent)** | **[Undici](https://github.com/nodejs/undici)** | **[WS](https://github.com/websockets/ws)** |
|
|
137
|
-
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
## 🤝 Contributing
|
|
134
|
+
## Documentation
|
|
141
135
|
|
|
142
|
-
|
|
136
|
+
- **[Quick Start](./docs/http/01-quickstart.md)** - Get running in 2 minutes
|
|
137
|
+
- **[API Reference](./docs/reference/01-api.md)** - Complete API documentation
|
|
138
|
+
- **[Configuration](./docs/http/05-configuration.md)** - Client options
|
|
139
|
+
- **[Plugins](./docs/http/10-plugins.md)** - Extend functionality
|
|
140
|
+
- **[AI Integration](./docs/ai/01-overview.md)** - OpenAI, Anthropic, and more
|
|
141
|
+
- **[Protocols](./docs/protocols/01-websocket.md)** - WebSocket, DNS, WHOIS
|
|
143
142
|
|
|
144
|
-
##
|
|
143
|
+
## License
|
|
145
144
|
|
|
146
145
|
MIT © [Forattini](https://github.com/forattini-dev)
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
<div align="center">
|
|
151
|
-
|
|
152
|
-
**Built for the AI era.**
|
|
153
|
-
|
|
154
|
-
[Documentation](https://forattini-dev.github.io/recker) · [GitHub](https://github.com/forattini-dev/recker) · [npm](https://www.npmjs.com/package/recker)
|
|
155
|
-
|
|
156
|
-
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/anthropic.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EAIf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,sBAAsB,EAMvB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/anthropic.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EAIf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,cAAc,EACd,sBAAsB,EAMvB,MAAM,WAAW,CAAC;AAMnB,MAAM,WAAW,eAAgB,SAAQ,cAAc;IAErD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAAC;CAC1C;AAED,KAAK,oBAAoB,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAclE,UAAU,mBAAmB;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,UAAU,GAAG,YAAY,GAAG,eAAe,GAAG,UAAU,CAAC;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAkBD,qBAAa,iBAAkB,SAAQ,cAAc;IACnD,OAAO,CAAC,eAAe,CAAkB;gBAE7B,MAAM,GAAE,eAAoB;IAKxC,SAAS,CAAC,YAAY,IAAI,MAAM,GAAG,SAAS;IAI5C,SAAS,CAAC,UAAU,IAAI,MAAM;IAI9B,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAShD,SAAS,CAAC,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE;IA0BxE,OAAO,CAAC,gBAAgB;IAuDxB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,eAAe;IAYjB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAa/C,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAY/C,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAW3D,OAAO,CAAC,aAAa;YAmCP,WAAW;YAsBX,WAAW;IA8BzB,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,sBAAsB,GAAG,UAAU;IAiD/F,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,WAAW,GAAG,IAAI;YAKjF,oBAAoB;CA2HpC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseAIProvider, AIError, RateLimitError, ContextLengthError, OverloadedError, AuthenticationError, } from './base.js';
|
|
2
|
+
import { StreamError } from '../../core/errors.js';
|
|
2
3
|
export class AnthropicProvider extends BaseAIProvider {
|
|
3
4
|
anthropicConfig;
|
|
4
5
|
constructor(config = {}) {
|
|
@@ -256,7 +257,9 @@ export class AnthropicProvider extends BaseAIProvider {
|
|
|
256
257
|
async *parseAnthropicStream(response, context) {
|
|
257
258
|
const reader = response.body?.getReader();
|
|
258
259
|
if (!reader) {
|
|
259
|
-
throw new
|
|
260
|
+
throw new StreamError('Response body is not readable', {
|
|
261
|
+
streamType: 'anthropic-sse',
|
|
262
|
+
});
|
|
260
263
|
}
|
|
261
264
|
const decoder = new TextDecoder();
|
|
262
265
|
let buffer = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/base.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACT,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/base.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IAExD,IAAI,EAAE,UAAU,CAAC;CAClB;AAKD,8BAAsB,cAAc;IAClC,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC;gBAEzB,MAAM,EAAE,kBAAkB;IAOtC,IAAI,IAAI,IAAI,UAAU,CAErB;IAKD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAKxD,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKxD,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAK7D,SAAS,CAAC,SAAS,IAAI,MAAM;IAa7B,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,MAAM,GAAG,SAAS;IAKrD,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,MAAM;IAKvC,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUhD,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE;IAKxE,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,GAAG,UAAU;IAKhG,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,WAAW,GAAG,IAAI;IAKvG,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS;IAgBtE,SAAS,CAAC,UAAU,IAAI,UAAU;cAWjB,cAAc,CAC7B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,sBAAsB,GAC9B,QAAQ;IA+DX,SAAS,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE;CAY9D;AAKD,qBAAa,OAAQ,SAAQ,KAAK;aAGd,QAAQ,EAAE,UAAU;aACpB,IAAI,CAAC,EAAE,MAAM;aACb,MAAM,CAAC,EAAE,MAAM;aACf,SAAS,EAAE,OAAO;gBAJlC,OAAO,EAAE,MAAM,EACC,QAAQ,EAAE,UAAU,EACpB,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,SAAS,GAAE,OAAe;CAK7C;AAED,qBAAa,cAAe,SAAQ,OAAO;aAGvB,UAAU,CAAC,EAAE,MAAM;gBADnC,QAAQ,EAAE,UAAU,EACJ,UAAU,CAAC,EAAE,MAAM,YAAA;CAKtC;AAED,qBAAa,kBAAmB,SAAQ,OAAO;gBACjC,QAAQ,EAAE,UAAU;CAIjC;AAED,qBAAa,eAAgB,SAAQ,OAAO;gBAC9B,QAAQ,EAAE,UAAU;CAIjC;AAED,qBAAa,mBAAoB,SAAQ,OAAO;gBAClC,QAAQ,EAAE,UAAU;CAIjC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ConfigurationError, StreamError } from '../../core/errors.js';
|
|
1
2
|
export class BaseAIProvider {
|
|
2
3
|
config;
|
|
3
4
|
constructor(config) {
|
|
@@ -9,7 +10,9 @@ export class BaseAIProvider {
|
|
|
9
10
|
getApiKey() {
|
|
10
11
|
const key = this.config.apiKey || this.getEnvApiKey();
|
|
11
12
|
if (!key) {
|
|
12
|
-
throw new
|
|
13
|
+
throw new ConfigurationError(`API key not configured for provider: ${this.config.name}`, {
|
|
14
|
+
configKey: `${this.config.name}.apiKey`,
|
|
15
|
+
});
|
|
13
16
|
}
|
|
14
17
|
return key;
|
|
15
18
|
}
|
|
@@ -40,7 +43,9 @@ export class BaseAIProvider {
|
|
|
40
43
|
async *parseSSEStream(response, context) {
|
|
41
44
|
const reader = response.body?.getReader();
|
|
42
45
|
if (!reader) {
|
|
43
|
-
throw new
|
|
46
|
+
throw new StreamError('Response body is not readable', {
|
|
47
|
+
streamType: 'sse',
|
|
48
|
+
});
|
|
44
49
|
}
|
|
45
50
|
const decoder = new TextDecoder();
|
|
46
51
|
let buffer = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/ai/rate-limiter.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/ai/rate-limiter.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA0FxE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,GAAE,oBAAyB;IAYvC,OAAO,CAAC,CAAC,EACb,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;KAAE,GAC3E,OAAO,CAAC,CAAC,CAAC;IA4BP,WAAW,CAAC,CAAC,EACjB,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;IAUb,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAchE,QAAQ,IAAI;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB;IAeD,UAAU,IAAI,IAAI;IAYlB,KAAK,IAAI,IAAI;IAYb,OAAO,CAAC,UAAU;YAYJ,UAAU;IAUxB,OAAO,CAAC,OAAO;YAmCD,YAAY;IAkC1B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,KAAK;CAGd;AAKD,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CAI/C;AAKD,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAa9E,CAAC;AAKF,wBAAgB,iBAAiB,CAC/B,YAAY,CAAC,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACxC,gBAAgB,CAGlB;AAKD,eAAO,MAAM,eAAe;6BAjVD,MAAM,GAAG,MAAM;gCAQZ,WAAW,GAAG,MAAM;CAyUH,CAAC"}
|
package/dist/ai/rate-limiter.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { QueueCancelledError } from '../core/errors.js';
|
|
1
2
|
const DEFAULT_LIMITS = {
|
|
2
3
|
tokensPerMinute: 90000,
|
|
3
4
|
requestsPerMinute: 500,
|
|
@@ -94,7 +95,9 @@ export class TokenRateLimiter {
|
|
|
94
95
|
}
|
|
95
96
|
clearQueue() {
|
|
96
97
|
for (const req of this.queue) {
|
|
97
|
-
req.reject(new
|
|
98
|
+
req.reject(new QueueCancelledError('Queue cleared', {
|
|
99
|
+
queueName: 'ai-rate-limiter',
|
|
100
|
+
}));
|
|
98
101
|
}
|
|
99
102
|
this.queue = [];
|
|
100
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/bench/generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAa;IACpB,KAAK,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,UAAU;IAKxB,KAAK;
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/bench/generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAa;IACpB,KAAK,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,UAAU;IAKxB,KAAK;IA8GX,IAAI;CAGL"}
|
package/dist/bench/generator.js
CHANGED
|
@@ -11,6 +11,8 @@ export class LoadGenerator {
|
|
|
11
11
|
async start() {
|
|
12
12
|
this.running = true;
|
|
13
13
|
const startTime = Date.now();
|
|
14
|
+
const connections = Math.min(Math.ceil(this.config.users / 10), 100);
|
|
15
|
+
const pipelining = this.config.mode === 'stress' ? 1 : 10;
|
|
14
16
|
const client = createClient({
|
|
15
17
|
baseUrl: new URL(this.config.url).origin,
|
|
16
18
|
observability: false,
|
|
@@ -20,9 +22,11 @@ export class LoadGenerator {
|
|
|
20
22
|
requestsPerInterval: Infinity,
|
|
21
23
|
interval: 1000,
|
|
22
24
|
agent: {
|
|
23
|
-
connections
|
|
24
|
-
pipelining
|
|
25
|
-
keepAlive:
|
|
25
|
+
connections,
|
|
26
|
+
pipelining,
|
|
27
|
+
keepAlive: true,
|
|
28
|
+
keepAliveTimeout: 30000,
|
|
29
|
+
connectTimeout: 5000,
|
|
26
30
|
}
|
|
27
31
|
},
|
|
28
32
|
retry: {
|
|
@@ -41,6 +45,7 @@ export class LoadGenerator {
|
|
|
41
45
|
await new Promise(r => setTimeout(r, 50 + Math.random() * 450));
|
|
42
46
|
}
|
|
43
47
|
const res = await client.get(path, { signal: controller.signal });
|
|
48
|
+
await res.text();
|
|
44
49
|
const duration = performance.now() - start;
|
|
45
50
|
const bytes = Number(res.headers.get('content-length') || 0);
|
|
46
51
|
this.stats.addResult(duration, res.status, bytes);
|
package/dist/bench/stats.d.ts
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
|
+
export interface ErrorEntry {
|
|
2
|
+
status: number;
|
|
3
|
+
message: string;
|
|
4
|
+
count: number;
|
|
5
|
+
lastSeen: number;
|
|
6
|
+
}
|
|
1
7
|
export declare class LoadStats {
|
|
2
8
|
totalRequests: number;
|
|
3
9
|
successful: number;
|
|
4
10
|
failed: number;
|
|
5
11
|
bytesTransferred: number;
|
|
6
12
|
statusCodes: Record<number, number>;
|
|
7
|
-
|
|
13
|
+
private errorMap;
|
|
14
|
+
private recentErrors;
|
|
15
|
+
private readonly maxRecentErrors;
|
|
8
16
|
latencies: number[];
|
|
9
17
|
private lastSnapshotTime;
|
|
10
18
|
private lastSnapshotRequests;
|
|
11
19
|
activeUsers: number;
|
|
12
20
|
addResult(durationMs: number, status: number, bytes: number, error?: Error): void;
|
|
21
|
+
private trackError;
|
|
22
|
+
private formatErrorMessage;
|
|
23
|
+
private getStatusText;
|
|
24
|
+
getErrors(): ErrorEntry[];
|
|
25
|
+
getRecentErrors(): ErrorEntry[];
|
|
26
|
+
get errors(): Record<string, number>;
|
|
13
27
|
getSnapshot(): {
|
|
14
28
|
rps: number;
|
|
15
29
|
p95: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/bench/stats.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/bench/stats.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACpB,aAAa,SAAK;IAClB,UAAU,SAAK;IACf,MAAM,SAAK;IACX,gBAAgB,SAAK;IAErB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAKzC,OAAO,CAAC,QAAQ,CAAiC;IAKjD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAM;IAGtC,SAAS,EAAE,MAAM,EAAE,CAAM;IAGzB,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,oBAAoB,CAAK;IAGjC,WAAW,SAAK;IAEhB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;IAoB1E,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,aAAa;IAiDrB,SAAS,IAAI,UAAU,EAAE;IAQzB,eAAe,IAAI,UAAU,EAAE;IAO/B,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOnC;IAED,WAAW;;;;;IAmBX,UAAU;;;;;;;;;;;;;;;;CAmBX"}
|
package/dist/bench/stats.js
CHANGED
|
@@ -4,7 +4,9 @@ export class LoadStats {
|
|
|
4
4
|
failed = 0;
|
|
5
5
|
bytesTransferred = 0;
|
|
6
6
|
statusCodes = {};
|
|
7
|
-
|
|
7
|
+
errorMap = new Map();
|
|
8
|
+
recentErrors = [];
|
|
9
|
+
maxRecentErrors = 10;
|
|
8
10
|
latencies = [];
|
|
9
11
|
lastSnapshotTime = Date.now();
|
|
10
12
|
lastSnapshotRequests = 0;
|
|
@@ -15,10 +17,7 @@ export class LoadStats {
|
|
|
15
17
|
this.latencies.push(durationMs);
|
|
16
18
|
if (error || status >= 400) {
|
|
17
19
|
this.failed++;
|
|
18
|
-
|
|
19
|
-
const msg = error.message || 'Unknown Error';
|
|
20
|
-
this.errors[msg] = (this.errors[msg] || 0) + 1;
|
|
21
|
-
}
|
|
20
|
+
this.trackError(status, error);
|
|
22
21
|
}
|
|
23
22
|
else {
|
|
24
23
|
this.successful++;
|
|
@@ -27,6 +26,119 @@ export class LoadStats {
|
|
|
27
26
|
this.statusCodes[status] = (this.statusCodes[status] || 0) + 1;
|
|
28
27
|
}
|
|
29
28
|
}
|
|
29
|
+
trackError(status, error) {
|
|
30
|
+
const message = this.formatErrorMessage(status, error);
|
|
31
|
+
const key = `${status}:${message}`;
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
const existing = this.errorMap.get(key);
|
|
34
|
+
if (existing) {
|
|
35
|
+
existing.count++;
|
|
36
|
+
existing.lastSeen = now;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const entry = { status, message, count: 1, lastSeen: now };
|
|
40
|
+
this.errorMap.set(key, entry);
|
|
41
|
+
this.recentErrors.push(entry);
|
|
42
|
+
if (this.recentErrors.length > this.maxRecentErrors) {
|
|
43
|
+
this.recentErrors.shift();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
formatErrorMessage(status, error) {
|
|
48
|
+
if (error) {
|
|
49
|
+
let msg = error.message || 'Unknown Error';
|
|
50
|
+
if (msg.includes('ECONNREFUSED'))
|
|
51
|
+
return 'Connection refused';
|
|
52
|
+
if (msg.includes('ECONNRESET'))
|
|
53
|
+
return 'Connection reset';
|
|
54
|
+
if (msg.includes('ETIMEDOUT'))
|
|
55
|
+
return 'Connection timeout';
|
|
56
|
+
if (msg.includes('ENOTFOUND'))
|
|
57
|
+
return 'DNS lookup failed';
|
|
58
|
+
if (msg.includes('UND_ERR_SOCKET'))
|
|
59
|
+
return 'Socket error';
|
|
60
|
+
if (msg.includes('UND_ERR_HEADERS_TIMEOUT'))
|
|
61
|
+
return 'Headers timeout';
|
|
62
|
+
if (msg.includes('UND_ERR_BODY_TIMEOUT'))
|
|
63
|
+
return 'Body timeout';
|
|
64
|
+
if (msg.includes('UND_ERR_CONNECT_TIMEOUT'))
|
|
65
|
+
return 'Connect timeout';
|
|
66
|
+
if (msg.includes('AbortError') || msg.includes('aborted'))
|
|
67
|
+
return 'Request aborted';
|
|
68
|
+
if (msg.includes('expression evaluated to a falsy value'))
|
|
69
|
+
return 'Connection pool exhausted';
|
|
70
|
+
if (msg.includes('AssertionError'))
|
|
71
|
+
return 'Internal assertion failed';
|
|
72
|
+
if (msg.length > 50) {
|
|
73
|
+
msg = msg.substring(0, 47) + '...';
|
|
74
|
+
}
|
|
75
|
+
return msg;
|
|
76
|
+
}
|
|
77
|
+
if (status >= 400) {
|
|
78
|
+
return this.getStatusText(status);
|
|
79
|
+
}
|
|
80
|
+
return 'Unknown Error';
|
|
81
|
+
}
|
|
82
|
+
getStatusText(status) {
|
|
83
|
+
const texts = {
|
|
84
|
+
400: 'BadRequest',
|
|
85
|
+
401: 'Unauthorized',
|
|
86
|
+
402: 'PaymentRequired',
|
|
87
|
+
403: 'Forbidden',
|
|
88
|
+
404: 'NotFound',
|
|
89
|
+
405: 'MethodNotAllowed',
|
|
90
|
+
406: 'NotAcceptable',
|
|
91
|
+
407: 'ProxyAuthRequired',
|
|
92
|
+
408: 'RequestTimeout',
|
|
93
|
+
409: 'Conflict',
|
|
94
|
+
410: 'Gone',
|
|
95
|
+
411: 'LengthRequired',
|
|
96
|
+
412: 'PreconditionFailed',
|
|
97
|
+
413: 'PayloadTooLarge',
|
|
98
|
+
414: 'URITooLong',
|
|
99
|
+
415: 'UnsupportedMediaType',
|
|
100
|
+
416: 'RangeNotSatisfiable',
|
|
101
|
+
417: 'ExpectationFailed',
|
|
102
|
+
418: 'Teapot',
|
|
103
|
+
421: 'MisdirectedRequest',
|
|
104
|
+
422: 'UnprocessableEntity',
|
|
105
|
+
423: 'Locked',
|
|
106
|
+
424: 'FailedDependency',
|
|
107
|
+
425: 'TooEarly',
|
|
108
|
+
426: 'UpgradeRequired',
|
|
109
|
+
428: 'PreconditionRequired',
|
|
110
|
+
429: 'TooManyRequests',
|
|
111
|
+
431: 'HeaderFieldsTooLarge',
|
|
112
|
+
451: 'UnavailableForLegalReasons',
|
|
113
|
+
500: 'InternalServerError',
|
|
114
|
+
501: 'NotImplemented',
|
|
115
|
+
502: 'BadGateway',
|
|
116
|
+
503: 'ServiceUnavailable',
|
|
117
|
+
504: 'GatewayTimeout',
|
|
118
|
+
505: 'HTTPVersionNotSupported',
|
|
119
|
+
506: 'VariantAlsoNegotiates',
|
|
120
|
+
507: 'InsufficientStorage',
|
|
121
|
+
508: 'LoopDetected',
|
|
122
|
+
510: 'NotExtended',
|
|
123
|
+
511: 'NetworkAuthRequired',
|
|
124
|
+
};
|
|
125
|
+
return texts[status] || `HTTP${status}`;
|
|
126
|
+
}
|
|
127
|
+
getErrors() {
|
|
128
|
+
return Array.from(this.errorMap.values())
|
|
129
|
+
.sort((a, b) => b.count - a.count);
|
|
130
|
+
}
|
|
131
|
+
getRecentErrors() {
|
|
132
|
+
return [...this.recentErrors];
|
|
133
|
+
}
|
|
134
|
+
get errors() {
|
|
135
|
+
const result = {};
|
|
136
|
+
for (const entry of this.errorMap.values()) {
|
|
137
|
+
const key = entry.status > 0 ? `[${entry.status}] ${entry.message}` : entry.message;
|
|
138
|
+
result[key] = entry.count;
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
30
142
|
getSnapshot() {
|
|
31
143
|
const now = Date.now();
|
|
32
144
|
const timeDiff = (now - this.lastSnapshotTime) / 1000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-storage.d.ts","sourceRoot":"","sources":["../../src/cache/memory-storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-storage.d.ts","sourceRoot":"","sources":["../../src/cache/memory-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ConfigurationError } from '../core/errors.js';
|
|
1
2
|
import zlib from 'node:zlib';
|
|
2
3
|
import os from 'node:os';
|
|
3
4
|
import { getEffectiveTotalMemoryBytes, resolveCacheMemoryLimit, formatBytes, getHeapStats, } from './memory-limits.js';
|
|
@@ -38,11 +39,11 @@ export class MemoryStorage {
|
|
|
38
39
|
options.maxMemoryBytes > 0 &&
|
|
39
40
|
options.maxMemoryPercent &&
|
|
40
41
|
options.maxMemoryPercent > 0) {
|
|
41
|
-
throw new
|
|
42
|
+
throw new ConfigurationError('[MemoryStorage] Cannot use both maxMemoryBytes and maxMemoryPercent', { configKey: 'maxMemoryBytes|maxMemoryPercent' });
|
|
42
43
|
}
|
|
43
44
|
if (options.maxMemoryPercent !== undefined &&
|
|
44
45
|
(options.maxMemoryPercent < 0 || options.maxMemoryPercent > 1)) {
|
|
45
|
-
throw new
|
|
46
|
+
throw new ConfigurationError('[MemoryStorage] maxMemoryPercent must be between 0 and 1', { configKey: 'maxMemoryPercent' });
|
|
46
47
|
}
|
|
47
48
|
this.maxSize = options.maxSize ?? 1000;
|
|
48
49
|
this.defaultTtl = options.ttl ?? 300000;
|