Skip to content

Commit 593ec09

Browse files
committed
feat: initial release of 🍊 tangerine
0 parents  commit 593ec09

27 files changed

+3392
-0
lines changed

.commitlintrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
extends: ['@commitlint/config-conventional']
3+
};

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!.*.js

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

.github/workflows/ci.yml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CI
2+
on:
3+
- push
4+
- pull_request
5+
jobs:
6+
build:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
os:
11+
- ubuntu-latest
12+
node_version:
13+
- 16
14+
- 18
15+
name: Node ${{ matrix.node_version }} on ${{ matrix.os }}
16+
steps:
17+
- uses: actions/checkout@v3
18+
- name: Setup node
19+
uses: actions/setup-node@v3
20+
with:
21+
node-version: ${{ matrix.node_version }}
22+
- name: Install dependencies
23+
run: npm install
24+
- name: Run tests
25+
run: npm run test
26+
- name: Run benchmarks
27+
run: npm run benchmarks

.gitignore

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.DS_Store
2+
*.log
3+
.idea
4+
node_modules
5+
coverage
6+
.nyc_output
7+
locales/
8+
package-lock.json
9+
yarn.lock
10+
11+
Thumbs.db
12+
tmp/
13+
temp/
14+
*.lcov
15+
.env

.lintstagedrc.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
"*.md": filenames => filenames.map(filename => `remark ${filename} -qfo`),
3+
'package.json': 'fixpack',
4+
'*.js': 'xo --fix'
5+
};

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

.prettierrc.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
singleQuote: true,
3+
bracketSpacing: true,
4+
trailingComma: 'none'
5+
};

.remarkrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
plugins: ['preset-github']
3+
};

.xo-config.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
prettier: true,
3+
space: true,
4+
extends: ['xo-lass']
5+
};

CNAME

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tangeri.ne

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Forward Email (https://forwardemail.net)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+576
Large diffs are not rendered by default.

ava.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
files: ['test/*.js', 'test/**/*.js']
3+
};

benchmarks/http.js

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
const http = require('node:http');
2+
const process = require('node:process');
3+
4+
const Benchmark = require('benchmark');
5+
const axios = require('axios');
6+
const fetch = require('node-fetch');
7+
const fetchMock = require('fetch-mock');
8+
const got = require('got');
9+
const nock = require('nock');
10+
const phin = require('phin');
11+
const request = require('request');
12+
const superagent = require('superagent');
13+
const undici = require('undici');
14+
15+
const PROTOCOL = process.env.BENCHMARK_PROTOCOL || 'http';
16+
const HOST = process.env.BENCHMARK_HOST || 'test';
17+
const PORT = process.env.BENCHMARK_PORT
18+
? Number.parseInt(process.env.BENCHMARK_PORT, 10)
19+
: 80;
20+
const PATH = process.env.BENCHMARK_PATH || '/test';
21+
const URL = `${PROTOCOL}://${HOST}:${PORT}${PATH}`;
22+
23+
const suite = new Benchmark.Suite();
24+
25+
axios.defaults.baseURL = `http://${HOST}`;
26+
27+
if (HOST === 'test') {
28+
const mockAgent = new undici.MockAgent();
29+
30+
mockAgent
31+
.get(axios.defaults.baseURL)
32+
.intercept({ path: PATH })
33+
.reply(200, 'ok');
34+
35+
undici.setGlobalDispatcher(mockAgent);
36+
37+
nock(axios.defaults.baseURL)
38+
.persist()
39+
.post(PATH)
40+
.reply(200, 'ok')
41+
.get(PATH)
42+
.reply(200, 'ok');
43+
44+
fetchMock.mock(URL, 200);
45+
}
46+
47+
suite.add('http.request POST request', {
48+
defer: true,
49+
fn(defer) {
50+
const req = http.request(
51+
{ host: HOST, port: PORT, path: PATH, method: 'POST' },
52+
(res) => {
53+
res.resume().on('end', () => defer.resolve());
54+
}
55+
);
56+
req.write('');
57+
req.end();
58+
}
59+
});
60+
61+
suite.add('http.request GET request', {
62+
defer: true,
63+
fn(defer) {
64+
http
65+
.request({ path: PATH, host: HOST, port: PORT }, (res) => {
66+
res.resume().on('end', () => defer.resolve());
67+
})
68+
.end();
69+
}
70+
});
71+
72+
suite.add('undici GET request', {
73+
defer: true,
74+
fn(defer) {
75+
undici
76+
.request(URL)
77+
.then(() => defer.resolve())
78+
.catch(() => defer.resolve());
79+
}
80+
});
81+
82+
suite.add('undici POST request', {
83+
defer: true,
84+
fn(defer) {
85+
undici
86+
.request(URL, { method: 'POST' })
87+
.then(() => defer.resolve())
88+
.catch(() => defer.resolve());
89+
}
90+
});
91+
92+
suite.add('axios GET request', {
93+
defer: true,
94+
fn(defer) {
95+
axios
96+
.get(PATH)
97+
.then(() => defer.resolve())
98+
.catch(() => defer.resolve());
99+
}
100+
});
101+
102+
suite.add('axios POST request', {
103+
defer: true,
104+
fn(defer) {
105+
axios
106+
.post(PATH)
107+
.then(() => defer.resolve())
108+
.catch(() => defer.resolve());
109+
}
110+
});
111+
112+
suite.add('got GET request', {
113+
defer: true,
114+
fn(defer) {
115+
got
116+
.get(URL, { throwHttpErrors: false, retry: 0 })
117+
.then(() => defer.resolve())
118+
.catch(() => defer.resolve());
119+
}
120+
});
121+
122+
suite.add('got POST request', {
123+
defer: true,
124+
fn(defer) {
125+
got
126+
.post(URL, { throwHttpErrors: false })
127+
.then(() => defer.resolve())
128+
.catch(() => defer.resolve());
129+
}
130+
});
131+
132+
suite.add('fetch GET request', {
133+
defer: true,
134+
fn(defer) {
135+
fetch(URL).then(() => defer.resolve());
136+
}
137+
});
138+
139+
suite.add('fetch POST request', {
140+
defer: true,
141+
fn(defer) {
142+
fetch(URL, { method: 'POST' })
143+
.then(() => defer.resolve())
144+
.catch(() => defer.resolve());
145+
}
146+
});
147+
148+
suite.add('request GET request', {
149+
defer: true,
150+
fn(defer) {
151+
request(URL, () => defer.resolve());
152+
}
153+
});
154+
155+
suite.add('request POST request', {
156+
defer: true,
157+
fn(defer) {
158+
request.post({ url: URL }, () => defer.resolve());
159+
}
160+
});
161+
162+
suite.add('superagent GET request', {
163+
defer: true,
164+
fn(defer) {
165+
superagent.get(URL).end(() => defer.resolve());
166+
}
167+
});
168+
169+
suite.add('superagent POST request', {
170+
defer: true,
171+
fn(defer) {
172+
superagent
173+
.post(URL)
174+
.send()
175+
.end(() => defer.resolve());
176+
}
177+
});
178+
179+
suite.add('phin GET request', {
180+
defer: true,
181+
fn(defer) {
182+
phin(URL).then(() => defer.resolve());
183+
}
184+
});
185+
186+
suite.add('phin POST request', {
187+
defer: true,
188+
fn(defer) {
189+
phin({ url: URL, method: 'POST' }).then(() => defer.resolve());
190+
}
191+
});
192+
193+
suite.on('complete', function () {
194+
console.log('Fastest is ' + this.filter('fastest').map('name'));
195+
});
196+
197+
suite.on('cycle', function (event) {
198+
console.log(String(event.target));
199+
});
200+
201+
suite.run();

0 commit comments

Comments
 (0)