Skip to content

Commit 035c117

Browse files
authored
feat: add types (#3)
1 parent a093f8a commit 035c117

File tree

5 files changed

+260
-26
lines changed

5 files changed

+260
-26
lines changed

Diff for: .husky/pre-commit

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
22
. "$(dirname "$0")/_/husky.sh"
33

4-
npm run test:ci
4+
npm run test

Diff for: .husky/pre-push

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npm run test:ci

Diff for: README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ When the `close` event is triggered, the plugin will check if the [`AbortSignal`
1616

1717
Is guaranteed that one and just one `AbortController` and `AbortSignal` will be made per request.
1818

19-
If the request was not aborted during its lifetime, the plugin will remove the `AbortController` and `AbortSignal` from the cache. This by scheduling a callback on the hook `onResponse`.
19+
If the request was not aborted during its lifetime, the plugin will remove the `AbortController` and `AbortSignal` from the cache. This by scheduling a hook-handler on the hook `onResponse`.
2020

2121
If the request aborted, the same hook will be used for cleaning resources.
2222

23-
A [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is used under the hood for caching, ensuring that the `AbortController` and `AbortSignal` instances can be unliked if not needed anymore, and for instance GC'ed.
23+
A [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is used under the hood for caching, ensuring that the `AbortController` and `AbortSignal` instances can be unlinked if not needed anymore, and for instance GC'ed.
2424

2525
## Setup
2626

Diff for: index.d.ts

+33
Original file line numberDiff line numberDiff line change
@@ -1 +1,34 @@
11
/// <reference types="node" />
2+
import { FastifyPluginCallback } from 'fastify'
3+
import { FastifyError } from '@fastify/error'
4+
5+
export interface FastifyRacingSignal extends AbortSignal {
6+
then: (
7+
onFulfilled?: (value: AbortEvent) => void | PromiseLike<unknown>,
8+
onRejected?: (reason: Error | FastifyError) => void | PromiseLike<unknown>
9+
) => void | Promise<unknown>
10+
}
11+
12+
export interface AbortEvent {
13+
type: 'abort' | string
14+
reason?: FastifyError | Error
15+
}
16+
17+
export interface FastifyRacingOptions {
18+
handleError?: boolean
19+
onRequestClosed?: ((evt: AbortEvent) => void) | null
20+
}
21+
22+
declare module 'fastify' {
23+
interface FastifyRequest {
24+
race(cb: FastifyRacingOptions['onRequestClosed']): void
25+
race(opts: Omit<FastifyRacingOptions, 'onRequestClosed'>): FastifyRacingSignal
26+
race(opts: Omit<FastifyRacingOptions, 'onRequestClosed'>): Promise<AbortEvent>
27+
race(): FastifyRacingSignal
28+
race(): Promise<AbortEvent>
29+
}
30+
}
31+
32+
declare const FastifyRacing: FastifyPluginCallback<FastifyRacingOptions>
33+
34+
export default FastifyRacing

Diff for: test/index.test-d.ts

+220-23
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,223 @@
1-
/// <reference types="node" />
2-
import { FastifyPluginCallback } from 'fastify';
3-
import { FastifyError } from '@fastify/error';
4-
5-
6-
interface AbortEvent {
7-
type: 'abort' | string;
8-
reason?: FastifyError | Error
9-
}
10-
11-
interface FastifyRacing {
12-
handleError?: boolean;
13-
onRequestClosed?: (evt: AbortEvent) => void;
14-
}
15-
16-
declare module 'fastify' {
17-
interface FastifyInstance {
18-
race(cb: FastifyRacing['onRequestClosed']): void
19-
race(opts: Omit<FastifyRacing, 'onRequestClosed'>): Promise<AbortEvent>
20-
race(): Promise<AbortEvent>
1+
import { expectType } from 'tsd'
2+
3+
import fastify from 'fastify'
4+
import plugin, { AbortEvent, FastifyRacingSignal } from '..'
5+
6+
const serverHttp = fastify()
7+
8+
serverHttp.register(plugin)
9+
10+
serverHttp.register(plugin, {
11+
handleError: true,
12+
onRequestClosed: null
13+
})
14+
15+
serverHttp.get(
16+
'/',
17+
{
18+
preHandler: async (request, _reply) => {
19+
const signal = request.race()
20+
const signal2 = request.race({
21+
handleError: true
22+
})
23+
const event = await request.race()
24+
const event2 = await request.race({
25+
handleError: true
26+
})
27+
28+
const asVoid = request.race(evt => {
29+
expectType<AbortEvent>(evt)
30+
})
31+
32+
expectType<void>(asVoid)
33+
expectType<FastifyRacingSignal>(signal)
34+
expectType<AbortEvent>(event)
35+
expectType<FastifyRacingSignal>(signal2)
36+
expectType<AbortEvent>(event2)
37+
}
38+
},
39+
async (request, reply) => {
40+
const signal = request.race()
41+
const signal2 = request.race({
42+
handleError: true
43+
})
44+
const event = await request.race()
45+
const event2 = await request.race({
46+
handleError: true
47+
})
48+
49+
const asVoid = request.race(evt => {
50+
expectType<AbortEvent>(evt)
51+
})
52+
53+
expectType<void>(asVoid)
54+
expectType<FastifyRacingSignal>(signal)
55+
expectType<AbortEvent>(event)
56+
expectType<FastifyRacingSignal>(signal2)
57+
expectType<AbortEvent>(event2)
58+
}
59+
)
60+
61+
// -> Second level
62+
serverHttp.register(
63+
function (fastifyInstance, opts, done) {
64+
fastifyInstance.register(plugin)
65+
66+
fastifyInstance.get(
67+
'/',
68+
{
69+
preHandler: async (request, _reply) => {
70+
const signal = request.race()
71+
const signal2 = request.race({
72+
handleError: true
73+
})
74+
const event = await request.race()
75+
const event2 = await request.race({
76+
handleError: true
77+
})
78+
const asVoid = request.race(evt => {
79+
expectType<AbortEvent>(evt)
80+
})
81+
82+
expectType<void>(asVoid)
83+
expectType<FastifyRacingSignal>(signal)
84+
expectType<AbortEvent>(event)
85+
expectType<FastifyRacingSignal>(signal2)
86+
expectType<AbortEvent>(event2)
87+
}
88+
},
89+
async (request, reply) => {
90+
const signal = request.race()
91+
const signal2 = request.race({
92+
handleError: true
93+
})
94+
const event = await request.race()
95+
const event2 = await request.race({
96+
handleError: true
97+
})
98+
99+
const asVoid = request.race(evt => {
100+
expectType<AbortEvent>(evt)
101+
})
102+
103+
expectType<void>(asVoid)
104+
expectType<FastifyRacingSignal>(signal)
105+
expectType<AbortEvent>(event)
106+
expectType<FastifyRacingSignal>(signal2)
107+
expectType<AbortEvent>(event2)
108+
}
109+
)
110+
111+
done()
112+
},
113+
{ prefix: '/api' }
114+
)
115+
116+
const serverHttp2 = fastify({ http2: true })
117+
118+
serverHttp2.register(plugin, {
119+
handleError: true,
120+
onRequestClosed: null
121+
})
122+
123+
serverHttp2.get(
124+
'/',
125+
{
126+
preHandler: async (request, _reply) => {
127+
const signal = request.race()
128+
const signal2 = request.race({
129+
handleError: true
130+
})
131+
const event = await request.race()
132+
const event2 = await request.race({
133+
handleError: true
134+
})
135+
136+
const asVoid = request.race(evt => {
137+
expectType<AbortEvent>(evt)
138+
})
139+
140+
expectType<void>(asVoid)
141+
expectType<FastifyRacingSignal>(signal)
142+
expectType<AbortEvent>(event)
143+
expectType<FastifyRacingSignal>(signal2)
144+
expectType<AbortEvent>(event2)
145+
}
146+
},
147+
async (request, reply) => {
148+
const signal = request.race()
149+
const signal2 = request.race({
150+
handleError: true
151+
})
152+
const event = await request.race()
153+
const event2 = await request.race({
154+
handleError: true
155+
})
156+
157+
const asVoid = request.race(evt => {
158+
expectType<AbortEvent>(evt)
159+
})
160+
161+
expectType<void>(asVoid)
162+
expectType<FastifyRacingSignal>(signal)
163+
expectType<AbortEvent>(event)
164+
expectType<FastifyRacingSignal>(signal2)
165+
expectType<AbortEvent>(event2)
21166
}
22-
}
167+
)
168+
169+
// -> First plugin
170+
serverHttp2.register(
171+
function (fastifyInstance, opts, done) {
172+
fastifyInstance.register(plugin)
173+
174+
fastifyInstance.get(
175+
'/',
176+
{
177+
preHandler: async (request, _reply) => {
178+
const signal = request.race()
179+
const signal2 = request.race({
180+
handleError: true
181+
})
182+
const event = await request.race()
183+
const event2 = await request.race({
184+
handleError: true
185+
})
186+
187+
const asVoid = request.race(evt => {
188+
expectType<AbortEvent>(evt)
189+
})
190+
191+
expectType<void>(asVoid)
192+
expectType<FastifyRacingSignal>(signal)
193+
expectType<AbortEvent>(event)
194+
expectType<FastifyRacingSignal>(signal2)
195+
expectType<AbortEvent>(event2)
196+
}
197+
},
198+
async (request, reply) => {
199+
const signal = request.race()
200+
const signal2 = request.race({
201+
handleError: true
202+
})
203+
const event = await request.race()
204+
const event2 = await request.race({
205+
handleError: true
206+
})
207+
208+
const asVoid = request.race(evt => {
209+
expectType<AbortEvent>(evt)
210+
})
23211

24-
declare const FastifyRacing: FastifyPluginCallback<FastifyRacing>;
212+
expectType<void>(asVoid)
213+
expectType<FastifyRacingSignal>(signal)
214+
expectType<AbortEvent>(event)
215+
expectType<FastifyRacingSignal>(signal2)
216+
expectType<AbortEvent>(event2)
217+
}
218+
)
25219

26-
export default FastifyRacing;
220+
done()
221+
},
222+
{ prefix: '/api' }
223+
)

0 commit comments

Comments
 (0)