fastpod 0.0.1 → 0.0.3
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 +31 -3
- package/benchmark.js +156 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,7 +16,33 @@ npx fastpod
|
|
|
16
16
|
# That's it! Your Solid pod is running at http://localhost:5444
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
## ⚡
|
|
19
|
+
## ⚡ Performance
|
|
20
|
+
|
|
21
|
+
fastpod lives up to its name. Here are real benchmark results:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
🏁 Benchmark Results
|
|
25
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
26
|
+
Startup Time: ~3 seconds
|
|
27
|
+
First Response: 3ms
|
|
28
|
+
|
|
29
|
+
Average Response Times:
|
|
30
|
+
GET: 0.63ms
|
|
31
|
+
PUT: 0.84ms
|
|
32
|
+
POST: 0.64ms
|
|
33
|
+
DELETE: 0.44ms
|
|
34
|
+
|
|
35
|
+
Throughput: 1,569 requests/sec
|
|
36
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**What this means:**
|
|
40
|
+
- 🚀 Server starts in ~3 seconds from `npx fastpod`
|
|
41
|
+
- ⚡ Sub-millisecond response times for all operations
|
|
42
|
+
- 💪 Handles 1,500+ requests per second
|
|
43
|
+
- 🎯 Production-ready performance out of the box
|
|
44
|
+
|
|
45
|
+
## ✨ Features
|
|
20
46
|
|
|
21
47
|
- ✅ **Zero configuration** - Just works
|
|
22
48
|
- ✅ **Lightning fast** - Server starts in seconds
|
|
@@ -92,8 +118,10 @@ npx fastpod
|
|
|
92
118
|
|
|
93
119
|
## 🎯 Why fastpod?
|
|
94
120
|
|
|
95
|
-
- **Fast to type**: Just 7 characters
|
|
96
|
-
- **Fast to start**: Server
|
|
121
|
+
- **Fast to type**: Just 7 characters (`fastpod`)
|
|
122
|
+
- **Fast to start**: Server ready in 3 seconds
|
|
123
|
+
- **Fast to respond**: Sub-millisecond response times (0.44-0.84ms)
|
|
124
|
+
- **Fast to scale**: 1,500+ requests/second throughput
|
|
97
125
|
- **Fast to learn**: Zero configuration needed
|
|
98
126
|
- **Fast to deploy**: One command and you're live
|
|
99
127
|
|
package/benchmark.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Benchmark script for fastpod
|
|
5
|
+
* Tests startup time, response time, and throughput
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { setTimeout as sleep } from 'timers/promises';
|
|
10
|
+
|
|
11
|
+
const BENCHMARK_PORT = 5555;
|
|
12
|
+
const BASE_URL = `http://localhost:${BENCHMARK_PORT}`;
|
|
13
|
+
const TEST_ITERATIONS = 100;
|
|
14
|
+
|
|
15
|
+
console.log('🏁 fastpod Benchmark Suite\n');
|
|
16
|
+
|
|
17
|
+
// Track metrics
|
|
18
|
+
const metrics = {
|
|
19
|
+
startupTime: 0,
|
|
20
|
+
firstResponseTime: 0,
|
|
21
|
+
getRequests: [],
|
|
22
|
+
putRequests: [],
|
|
23
|
+
postRequests: [],
|
|
24
|
+
deleteRequests: []
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Start the server
|
|
28
|
+
console.log('Starting fastpod server...');
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
|
|
31
|
+
const server = spawn('node', ['node_modules/.bin/jspod', '--port', BENCHMARK_PORT, '--no-auth', '--root', './bench-data'], {
|
|
32
|
+
stdio: 'pipe',
|
|
33
|
+
env: { ...process.env }
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Wait for server to be ready
|
|
37
|
+
async function waitForServer() {
|
|
38
|
+
const maxAttempts = 30;
|
|
39
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(BASE_URL);
|
|
42
|
+
if (response.ok || response.status === 404) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
await sleep(500);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error('Server failed to start');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
await waitForServer();
|
|
54
|
+
metrics.startupTime = Date.now() - startTime;
|
|
55
|
+
console.log(`✓ Server started in ${metrics.startupTime}ms\n`);
|
|
56
|
+
|
|
57
|
+
// Test first response time
|
|
58
|
+
console.log('Testing first response time...');
|
|
59
|
+
const firstReqStart = Date.now();
|
|
60
|
+
await fetch(BASE_URL);
|
|
61
|
+
metrics.firstResponseTime = Date.now() - firstReqStart;
|
|
62
|
+
console.log(`✓ First response: ${metrics.firstResponseTime}ms\n`);
|
|
63
|
+
|
|
64
|
+
// Benchmark GET requests
|
|
65
|
+
console.log(`Benchmarking GET requests (${TEST_ITERATIONS} iterations)...`);
|
|
66
|
+
for (let i = 0; i < TEST_ITERATIONS; i++) {
|
|
67
|
+
const start = Date.now();
|
|
68
|
+
await fetch(BASE_URL);
|
|
69
|
+
metrics.getRequests.push(Date.now() - start);
|
|
70
|
+
}
|
|
71
|
+
const avgGet = (metrics.getRequests.reduce((a, b) => a + b, 0) / metrics.getRequests.length).toFixed(2);
|
|
72
|
+
const minGet = Math.min(...metrics.getRequests);
|
|
73
|
+
const maxGet = Math.max(...metrics.getRequests);
|
|
74
|
+
console.log(`✓ GET avg: ${avgGet}ms, min: ${minGet}ms, max: ${maxGet}ms`);
|
|
75
|
+
|
|
76
|
+
// Benchmark PUT requests
|
|
77
|
+
console.log(`\nBenchmarking PUT requests (${TEST_ITERATIONS} iterations)...`);
|
|
78
|
+
for (let i = 0; i < TEST_ITERATIONS; i++) {
|
|
79
|
+
const start = Date.now();
|
|
80
|
+
await fetch(`${BASE_URL}/test-${i}.txt`, {
|
|
81
|
+
method: 'PUT',
|
|
82
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
83
|
+
body: `Test data ${i}`
|
|
84
|
+
});
|
|
85
|
+
metrics.putRequests.push(Date.now() - start);
|
|
86
|
+
}
|
|
87
|
+
const avgPut = (metrics.putRequests.reduce((a, b) => a + b, 0) / metrics.putRequests.length).toFixed(2);
|
|
88
|
+
const minPut = Math.min(...metrics.putRequests);
|
|
89
|
+
const maxPut = Math.max(...metrics.putRequests);
|
|
90
|
+
console.log(`✓ PUT avg: ${avgPut}ms, min: ${minPut}ms, max: ${maxPut}ms`);
|
|
91
|
+
|
|
92
|
+
// Benchmark POST requests
|
|
93
|
+
console.log(`\nBenchmarking POST requests (${TEST_ITERATIONS} iterations)...`);
|
|
94
|
+
for (let i = 0; i < TEST_ITERATIONS; i++) {
|
|
95
|
+
const start = Date.now();
|
|
96
|
+
await fetch(BASE_URL, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'text/plain',
|
|
100
|
+
'Slug': `post-${i}.txt`
|
|
101
|
+
},
|
|
102
|
+
body: `Posted data ${i}`
|
|
103
|
+
});
|
|
104
|
+
metrics.postRequests.push(Date.now() - start);
|
|
105
|
+
}
|
|
106
|
+
const avgPost = (metrics.postRequests.reduce((a, b) => a + b, 0) / metrics.postRequests.length).toFixed(2);
|
|
107
|
+
const minPost = Math.min(...metrics.postRequests);
|
|
108
|
+
const maxPost = Math.max(...metrics.postRequests);
|
|
109
|
+
console.log(`✓ POST avg: ${avgPost}ms, min: ${minPost}ms, max: ${maxPost}ms`);
|
|
110
|
+
|
|
111
|
+
// Benchmark DELETE requests
|
|
112
|
+
console.log(`\nBenchmarking DELETE requests (${TEST_ITERATIONS} iterations)...`);
|
|
113
|
+
for (let i = 0; i < TEST_ITERATIONS; i++) {
|
|
114
|
+
const start = Date.now();
|
|
115
|
+
await fetch(`${BASE_URL}/test-${i}.txt`, {
|
|
116
|
+
method: 'DELETE'
|
|
117
|
+
});
|
|
118
|
+
metrics.deleteRequests.push(Date.now() - start);
|
|
119
|
+
}
|
|
120
|
+
const avgDelete = (metrics.deleteRequests.reduce((a, b) => a + b, 0) / metrics.deleteRequests.length).toFixed(2);
|
|
121
|
+
const minDelete = Math.min(...metrics.deleteRequests);
|
|
122
|
+
const maxDelete = Math.max(...metrics.deleteRequests);
|
|
123
|
+
console.log(`✓ DELETE avg: ${avgDelete}ms, min: ${minDelete}ms, max: ${maxDelete}ms`);
|
|
124
|
+
|
|
125
|
+
// Calculate throughput
|
|
126
|
+
const totalRequests = TEST_ITERATIONS * 4; // GET, PUT, POST, DELETE
|
|
127
|
+
const totalTime = metrics.getRequests.reduce((a, b) => a + b, 0) +
|
|
128
|
+
metrics.putRequests.reduce((a, b) => a + b, 0) +
|
|
129
|
+
metrics.postRequests.reduce((a, b) => a + b, 0) +
|
|
130
|
+
metrics.deleteRequests.reduce((a, b) => a + b, 0);
|
|
131
|
+
const throughput = (totalRequests / (totalTime / 1000)).toFixed(2);
|
|
132
|
+
|
|
133
|
+
// Display summary
|
|
134
|
+
console.log('\n' + '='.repeat(60));
|
|
135
|
+
console.log('📊 Benchmark Results Summary');
|
|
136
|
+
console.log('='.repeat(60));
|
|
137
|
+
console.log(`Startup Time: ${metrics.startupTime}ms`);
|
|
138
|
+
console.log(`First Response: ${metrics.firstResponseTime}ms`);
|
|
139
|
+
console.log(`\nAverage Response Times:`);
|
|
140
|
+
console.log(` GET: ${avgGet}ms`);
|
|
141
|
+
console.log(` PUT: ${avgPut}ms`);
|
|
142
|
+
console.log(` POST: ${avgPost}ms`);
|
|
143
|
+
console.log(` DELETE: ${avgDelete}ms`);
|
|
144
|
+
console.log(`\nThroughput: ${throughput} req/sec`);
|
|
145
|
+
console.log(`Total Requests: ${totalRequests}`);
|
|
146
|
+
console.log('='.repeat(60));
|
|
147
|
+
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error('Benchmark failed:', error.message);
|
|
150
|
+
} finally {
|
|
151
|
+
// Cleanup
|
|
152
|
+
console.log('\nCleaning up...');
|
|
153
|
+
server.kill('SIGTERM');
|
|
154
|
+
await sleep(1000);
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastpod",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Fast Solid Pod - The fastest way to run a Solid pod",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"node": ">=18.0.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"jspod": "^0.0.
|
|
39
|
+
"jspod": "^0.0.4"
|
|
40
40
|
}
|
|
41
41
|
}
|