From 82f9c304c8945e593f23f4c309013151dd61ba56 Mon Sep 17 00:00:00 2001 From: Cristian Necula Date: Fri, 27 Oct 2023 15:04:24 +0300 Subject: [PATCH] feat(useAbortSignal): new hook to help cleanup event listeners and requests --- src/hooks/use-abort-signal.ts | 13 +++++++++++++ test/use-abort-signal.test.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/hooks/use-abort-signal.ts create mode 100644 test/use-abort-signal.test.js diff --git a/src/hooks/use-abort-signal.ts b/src/hooks/use-abort-signal.ts new file mode 100644 index 0000000..9b5dec0 --- /dev/null +++ b/src/hooks/use-abort-signal.ts @@ -0,0 +1,13 @@ +import { useEffect, useMemo } from 'haunted'; + +export const useAbortSignal = () => { + const { controller, signal } = useMemo(() => { + const controller = new AbortController(), + signal = controller.signal; + return { controller, signal }; + }, []); + + useEffect(() => () => controller.abort(), []); + + return signal; +}; diff --git a/test/use-abort-signal.test.js b/test/use-abort-signal.test.js new file mode 100644 index 0000000..a8d9d0b --- /dev/null +++ b/test/use-abort-signal.test.js @@ -0,0 +1,34 @@ +import { useAbortSignal } from '../src/hooks/use-abort-signal'; +import { component } from 'haunted'; +import { assert, html, fixture } from '@open-wc/testing'; +import { spy } from 'sinon'; + +customElements.define( + 'use-abort-signal', + component((host) => { + host.current = useAbortSignal(); + }), +); + +suite('useAbortSignal', () => { + test('creates an abort signal', async () => { + const result = await fixture(html``); + + assert.isOk(result.current); + assert.instanceOf(result.current, AbortSignal); + }); + + test('signal aborts when the component is destroyed', async () => { + const result = await fixture(html``); + const abortSignal = result.current; + const abortSpy = spy(); + + abortSignal.addEventListener('abort', abortSpy); + + assert.isFalse(abortSignal.aborted); + assert.isFalse(abortSpy.called); + result.parentNode.removeChild(result); + assert.isTrue(abortSignal.aborted); + assert.isTrue(abortSpy.calledOnce); + }); +});