@techiev2/vajra 1.5.0 → 1.5.1

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 CHANGED
@@ -22,6 +22,12 @@ Like the Vajra, this server delivers maximum power in minimal form.
22
22
 
23
23
  ## Changelog
24
24
 
25
+ ### 1.5.1 (2026-01-04)
26
+ - Adds a pre-allocated buffer based body reader for improvement.
27
+
28
+ ### 1.5.0 (2026-01-03)
29
+ - Adds support for res.sendFile.
30
+
25
31
  ### 1.4.3 (2026-01-02)
26
32
  - Adds guardrails for unsafe operations with template paths.
27
33
 
package/README.md CHANGED
@@ -22,6 +22,9 @@ Like the Vajra, this server delivers maximum power in minimal form.
22
22
 
23
23
  ## Changelog
24
24
 
25
+ ### 1.5.1 (2026-01-04)
26
+ - Adds a pre-allocated buffer based body reader for improvement.
27
+
25
28
  ### 1.5.0 (2026-01-03)
26
29
  - Adds support for res.sendFile.
27
30
 
package/benchmark.sh CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- set -euo pipefail
2
+ set -eox pipefail
3
3
  declare -A portMap=(
4
4
  ["elysia"]=4000
5
5
  ["express"]=4001
@@ -15,23 +15,28 @@ declare -A runnerMap=(
15
15
  ["hono"]="index.js"
16
16
  ["vajra"]="examples/api.js"
17
17
  )
18
- frameworks=$(ls -d */ | sed 's|/$||' | grep -v auth | grep vajra)
18
+ frameworks=$(ls -d */ | sed 's|/$||' | grep -v auth)
19
+ if [ -z "$1" ]; then
20
+ frameworks=$(echo $frameworks | grep "$1")
21
+ fi
22
+
19
23
 
20
24
  LOOPS=5
21
25
 
22
26
  runWrk() {
23
27
  port=$1
24
- sync && echo 3 > tee /proc/sys/vm/drop_caches
25
- wrk -t16 -c600 -d10s \
26
- -H "Content-Type: multipart/form-data; boundary=BOUNDARY123456" \
27
- "http://localhost:${port}/upload" < ../test_upload_2mb.txt
28
+ sync && echo 3 > /proc/sys/vm/drop_caches
29
+ wrk -t16 -c600 -d10s -H "Content-Type: multipart/form-data; boundary=BOUNDARY123456" "http://localhost:${port}/upload" < ../test_upload_2mb.txt
28
30
  }
29
31
  main() {
30
- echo "" > report.txt
32
+ mkdir -p reports
33
+ runtime=$(date '+%Y-%m-%d_%H:%M:%S')
34
+ reportFile="./reports/report_${runtime}.txt"
35
+ echo "" > $reportFile
31
36
  for framework in ${frameworks[@]}; do
32
37
  cd $framework
33
38
  mkdir -p benchmarks
34
- echo "" > benchmarks/report.txt
39
+ echo "" > benchmarks/report_${runtime}.txt
35
40
  port=${portMap[$framework]}
36
41
  runner=${runnerMap[$framework]}
37
42
  for i in $(seq 1 $LOOPS); do
@@ -40,18 +45,18 @@ main() {
40
45
  runningPID=$(lsof | grep -P ":$port" | head -n1 | awk '{print $2}')
41
46
  echo "$framework running at $runningPID"
42
47
  sleep 2
43
- runWrk $port >> benchmarks/report.txt
48
+ runWrk $port >> benchmarks/report_${runtime}.txt
44
49
  sleep 2
45
50
  echo "Killing $framework running at $runningPID"
46
51
  kill -9 $runningPID
47
52
  done
48
- avg_rps=$(grep "Requests/sec:" benchmarks/report.txt | awk -F' ' '{print $2}' | awk '{x+=$1; n++} END { print x/n}')
49
- avg_tps=$(grep "Transfer/sec:" benchmarks/report.txt | awk -F' ' '{print $2}' | awk '{x+=$1; n++} END { print x/n}')
53
+ avg_rps=$(grep "Requests/sec:" benchmarks/report_${runtime}.txt | awk -F' ' '{print $2}' | awk '{x+=$1; n++} END { print x/n}')
54
+ avg_tps=$(grep "Transfer/sec:" benchmarks/report_${runtime}.txt | awk -F' ' '{print $2}' | awk '{x+=$1; n++} END { print x/n}')
50
55
  echo "${framework}
51
56
  Average RPS: ${avg_rps}/s
52
57
  Average TPS: ${avg_tps}MB/s
53
58
 
54
- " >> "../report.txt"
59
+ " >> $reportFile
55
60
  cd ..
56
61
  done
57
62
  }
package/index.js CHANGED
@@ -62,13 +62,14 @@ export default class Vajra {
62
62
  if (req.method === 'GET' || req.method === 'HEAD') { return runMiddlwares() }
63
63
  async function runMiddlwares() { let idx = 0; const next = async () => { if (idx >= Vajra.#middlewares.length) { return setImmediate(handleRoute) } const fn = Vajra.#middlewares[idx]; idx++; try { await fn(req, res, next); } catch (err) { return default_500({ url: req.url, method: req.method }, res, err); } }; await next(); }
64
64
  setImmediate(() => {
65
- req.body = {}; req.rawData = ''; req.formData = {}; let dataSize = 0
66
- req.on('data', (chunk) => { dataSize += chunk.length; if (dataSize > Vajra.#MAX_FILE_SIZE) { return default_413(res) }; req.rawData+=chunk })
65
+ req.body = {}; req.rawData = ''; req.formData = {}; let totalSize = 0; let chunks = []
66
+ req.on('data', (chunk) => { if (totalSize + chunk.length > Vajra.#MAX_FILE_SIZE) { return default_413(res) }; chunks.push(chunk); totalSize += chunk.length; })
67
67
  const formDataMatcher = /Content-Disposition: form-data; name=['"](?<name>[^"']+)['"]\s+(?<value>.*?)$/smi;
68
68
  let boundaryMatch = (req.headers['Content-Type'] || '').match(/boundary=(.*)/); const boundary = boundaryMatch ? '--' + boundaryMatch[1] : null; const fileDataMatcher = /^Content-Disposition:.*?name=["'](?<field>[^"']+)["'].*?filename=["'](?<fileName>[^"']+)["'].*?Content-Type:\s*(?<contentType>[^\r\n]*)\r?\n\r?\n(?<content>[\s\S]*)$/ims
69
69
  req.on('end', async () => {
70
- req.files = []; if (boundary) {
71
- req.rawData.split(boundary).filter(Boolean).map((line) => {
70
+ const buffer = Buffer.allocUnsafe(totalSize); let offset = 0;
71
+ for (const chunk of chunks) { chunk.copy(buffer, offset); offset += chunk.length; }
72
+ req.rawData = buffer.toString(); req.files = []; if (boundary) { req.rawData.split(boundary).filter(Boolean).map((line) => {
72
73
  let key, value; if (line.includes('filename')) { req.files.push(fileDataMatcher.exec(line)?.groups || {}); return }
73
74
  [key, value] = Object.values(line.match(formDataMatcher)?.groups || {}); (key && value) && Object.assign(req.formData, { [key]: value }); return
74
75
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techiev2/vajra",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Blazing-fast, zero-dependency Node.js server with routing, middleware, multipart uploads, and templating. 111 lines · ~95k req/s · ~52 MB idle.",
5
5
  "keywords": [
6
6
  "http-server",