flareperf 0.1.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/README.md +43 -0
- package/bin/flareperf.js +40 -0
- package/install.js +78 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# flareperf
|
|
2
|
+
|
|
3
|
+
> **Unified Cloudflare Edge Performance & Budget Guardian**
|
|
4
|
+
> Enforce Worker bundle size budgets, analyze V8 isolate cold-start latency, verify 50-subrequest limits, and eliminate D1 SQLite N+1 query bottlenecks.
|
|
5
|
+
|
|
6
|
+
## 🚀 Quickstart
|
|
7
|
+
|
|
8
|
+
Run via `npx` (no installation required):
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# Run comprehensive check
|
|
12
|
+
npx flareperf check .
|
|
13
|
+
|
|
14
|
+
# Check bundle size against Cloudflare tier budgets (free, paid, ai)
|
|
15
|
+
npx flareperf bundle dist/_worker.js --budget free
|
|
16
|
+
|
|
17
|
+
# Check V8 isolate cold-start complexity
|
|
18
|
+
npx flareperf isolate src/index.ts
|
|
19
|
+
|
|
20
|
+
# Check for 50-subrequest limit violations
|
|
21
|
+
npx flareperf subrequests src/
|
|
22
|
+
|
|
23
|
+
# Check for D1 N+1 query loops
|
|
24
|
+
npx flareperf d1 src/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or install globally:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g flareperf
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 📦 Rust Crate
|
|
34
|
+
|
|
35
|
+
Also available on [crates.io](https://crates.io/crates/flareperf):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cargo install flareperf
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 📄 License
|
|
42
|
+
|
|
43
|
+
MIT © [Brandon Hubbard](https://brandonhubbard.com)
|
package/bin/flareperf.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
|
|
8
|
+
const platform = os.platform();
|
|
9
|
+
const binName = platform === 'win32' ? 'flareperf.exe' : 'flareperf';
|
|
10
|
+
const localBinPath = path.join(__dirname, binName);
|
|
11
|
+
|
|
12
|
+
let targetBin = localBinPath;
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(localBinPath)) {
|
|
15
|
+
// Check if available globally in PATH
|
|
16
|
+
try {
|
|
17
|
+
const check = spawnSync(binName, ['--version'], { stdio: 'ignore' });
|
|
18
|
+
if (check.status === 0) {
|
|
19
|
+
targetBin = binName;
|
|
20
|
+
} else {
|
|
21
|
+
console.error(`Error: Could not find flareperf binary at ${localBinPath}`);
|
|
22
|
+
console.error('Run npm rebuild flareperf or install via cargo: cargo install flareperf');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
} catch (_e) {
|
|
26
|
+
console.error(`Error: Could not find flareperf binary at ${localBinPath}`);
|
|
27
|
+
console.error('Run npm rebuild flareperf or install via cargo: cargo install flareperf');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const args = process.argv.slice(2);
|
|
33
|
+
const result = spawnSync(targetBin, args, { stdio: 'inherit' });
|
|
34
|
+
|
|
35
|
+
if (result.error) {
|
|
36
|
+
console.error('Failed to execute flareperf:', result.error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process.exit(result.status ?? 0);
|
package/install.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const platform = os.platform();
|
|
8
|
+
const arch = os.arch();
|
|
9
|
+
|
|
10
|
+
const REPO = 'bhubbard/flareperf';
|
|
11
|
+
const VERSION = require('./package.json').version;
|
|
12
|
+
|
|
13
|
+
let assetName = 'flareperf';
|
|
14
|
+
|
|
15
|
+
if (platform === 'win32') {
|
|
16
|
+
if (arch !== 'x64') throw new Error('Unsupported architecture on Windows: ' + arch);
|
|
17
|
+
assetName = 'flareperf-win32-x64.exe';
|
|
18
|
+
} else if (platform === 'darwin') {
|
|
19
|
+
if (arch === 'x64') assetName = 'flareperf-darwin-x64';
|
|
20
|
+
else if (arch === 'arm64') assetName = 'flareperf-darwin-arm64';
|
|
21
|
+
else throw new Error('Unsupported architecture on macOS: ' + arch);
|
|
22
|
+
} else if (platform === 'linux') {
|
|
23
|
+
if (arch !== 'x64') throw new Error('Unsupported architecture on Linux: ' + arch);
|
|
24
|
+
assetName = 'flareperf-linux-x64';
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error('Unsupported platform: ' + platform);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${assetName}`;
|
|
30
|
+
|
|
31
|
+
const binDir = path.join(__dirname, 'bin');
|
|
32
|
+
const binaryPath = path.join(binDir, platform === 'win32' ? 'flareperf.exe' : 'flareperf');
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(binDir)) {
|
|
35
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// If binary is already present, skip download
|
|
39
|
+
if (fs.existsSync(binaryPath)) {
|
|
40
|
+
console.log(`flareperf binary already present at ${binaryPath}`);
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log(`Downloading flareperf v${VERSION} for ${platform} ${arch}...`);
|
|
45
|
+
console.log(`URL: ${url}`);
|
|
46
|
+
|
|
47
|
+
function download(downloadUrl, dest) {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const file = fs.createWriteStream(dest);
|
|
50
|
+
https.get(downloadUrl, (response) => {
|
|
51
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
52
|
+
download(response.headers.location, dest).then(resolve).catch(reject);
|
|
53
|
+
} else if (response.statusCode === 200) {
|
|
54
|
+
response.pipe(file);
|
|
55
|
+
file.on('finish', () => {
|
|
56
|
+
file.close();
|
|
57
|
+
resolve();
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
|
|
61
|
+
}
|
|
62
|
+
}).on('error', (err) => {
|
|
63
|
+
fs.unlink(dest, () => reject(err));
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
download(url, binaryPath)
|
|
69
|
+
.then(() => {
|
|
70
|
+
if (platform !== 'win32') {
|
|
71
|
+
execSync(`chmod +x "${binaryPath}"`);
|
|
72
|
+
}
|
|
73
|
+
console.log('Successfully installed flareperf binary.');
|
|
74
|
+
})
|
|
75
|
+
.catch((err) => {
|
|
76
|
+
console.warn('Notice: Could not automatically download prebuilt binary:', err.message);
|
|
77
|
+
console.warn('You can build flareperf from source with: cargo install flareperf');
|
|
78
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flareperf",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unified Cloudflare Edge Performance & Budget Guardian — Bundle size budgets, V8 isolate cold-start analysis, 50-subrequest limits, and D1 batching.",
|
|
5
|
+
"main": "bin/flareperf.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"flareperf": "bin/flareperf.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node install.js"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/bhubbard/flareperf.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"cloudflare",
|
|
18
|
+
"workers",
|
|
19
|
+
"performance",
|
|
20
|
+
"pages",
|
|
21
|
+
"budgets",
|
|
22
|
+
"cli",
|
|
23
|
+
"linter",
|
|
24
|
+
"cold-start",
|
|
25
|
+
"d1",
|
|
26
|
+
"subrequests"
|
|
27
|
+
],
|
|
28
|
+
"author": "Brandon Hubbard <bhubbard@users.noreply.github.com>",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/bhubbard/flareperf/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://bhubbard.github.io/flareperf",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"bin/flareperf.js",
|
|
39
|
+
"install.js",
|
|
40
|
+
"README.md"
|
|
41
|
+
]
|
|
42
|
+
}
|