From 514eec8bcffee67e876e8029c82a8ce5325ca36d Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Tue, 17 May 2022 15:38:07 +0200 Subject: [PATCH 1/4] docs: fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b044b5..dabe9fe 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@ When the `close` event is triggered, the plugin will check if the [`AbortSignal` Is guaranteed that one and just one `AbortController` and `AbortSignal` will be made per request. -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`. +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`. If the request aborted, the same hook will be used for cleaning resources. -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. +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. ## Setup From 427eaadaa5178804904ebab6900833e3687a78df Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Tue, 17 May 2022 15:56:45 +0200 Subject: [PATCH 2/4] feat: add proper types --- index.d.ts | 33 ++++++ test/index.test-d.ts | 243 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 253 insertions(+), 23 deletions(-) diff --git a/index.d.ts b/index.d.ts index 7e3a61c..af079e3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1 +1,34 @@ /// +import { FastifyPluginCallback } from 'fastify' +import { FastifyError } from '@fastify/error' + +export interface FastifyRacingSignal extends AbortSignal { + then: ( + onFulfilled?: (value: AbortEvent) => void | PromiseLike, + onRejected?: (reason: Error | FastifyError) => void | PromiseLike + ) => void | Promise +} + +export interface AbortEvent { + type: 'abort' | string + reason?: FastifyError | Error +} + +export interface FastifyRacingOptions { + handleError?: boolean + onRequestClosed?: ((evt: AbortEvent) => void) | null +} + +declare module 'fastify' { + interface FastifyRequest { + race(cb: FastifyRacingOptions['onRequestClosed']): void + race(opts: Omit): FastifyRacingSignal + race(opts: Omit): Promise + race(): FastifyRacingSignal + race(): Promise + } +} + +declare const FastifyRacing: FastifyPluginCallback + +export default FastifyRacing diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 37faede..140c7f4 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -1,26 +1,223 @@ -/// -import { FastifyPluginCallback } from 'fastify'; -import { FastifyError } from '@fastify/error'; - - -interface AbortEvent { - type: 'abort' | string; - reason?: FastifyError | Error -} - -interface FastifyRacing { - handleError?: boolean; - onRequestClosed?: (evt: AbortEvent) => void; -} - -declare module 'fastify' { - interface FastifyInstance { - race(cb: FastifyRacing['onRequestClosed']): void - race(opts: Omit): Promise - race(): Promise +import { expectType } from 'tsd' + +import fastify from 'fastify' +import plugin, { AbortEvent, FastifyRacingSignal } from '..' + +const serverHttp = fastify() + +serverHttp.register(plugin) + +serverHttp.register(plugin, { + handleError: true, + onRequestClosed: null +}) + +serverHttp.get( + '/', + { + preHandler: async (request, _reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + }, + async (request, reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } +) + +// -> Second level +serverHttp.register( + function (fastifyInstance, opts, done) { + fastifyInstance.register(plugin) + + fastifyInstance.get( + '/', + { + preHandler: async (request, _reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + }, + async (request, reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + ) + + done() + }, + { prefix: '/api' } +) + +const serverHttp2 = fastify({ http2: true }) + +serverHttp2.register(plugin, { + handleError: true, + onRequestClosed: null +}) + +serverHttp2.get( + '/', + { + preHandler: async (request, _reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + }, + async (request, reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) } -} +) + +// -> First plugin +serverHttp2.register( + function (fastifyInstance, opts, done) { + fastifyInstance.register(plugin) + + fastifyInstance.get( + '/', + { + preHandler: async (request, _reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) + + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + }, + async (request, reply) => { + const signal = request.race() + const signal2 = request.race({ + handleError: true + }) + const event = await request.race() + const event2 = await request.race({ + handleError: true + }) + + const asVoid = request.race(evt => { + expectType(evt) + }) -declare const FastifyRacing: FastifyPluginCallback; + expectType(asVoid) + expectType(signal) + expectType(event) + expectType(signal2) + expectType(event2) + } + ) -export default FastifyRacing; \ No newline at end of file + done() + }, + { prefix: '/api' } +) From a7b18622692540c202af4c71268362129b4d528e Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Tue, 17 May 2022 16:05:37 +0200 Subject: [PATCH 3/4] test: husky From 8c9339faa2fbbea5083bb8133219874af54f3864 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Tue, 17 May 2022 16:08:13 +0200 Subject: [PATCH 4/4] chore: add husky pre-push hook --- .husky/pre-commit | 2 +- .husky/pre-push | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100755 .husky/pre-push diff --git a/.husky/pre-commit b/.husky/pre-commit index 1dc4645..d1096ab 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npm run test:ci +npm run test diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..1dc4645 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run test:ci