wretch
Version:
A tiny wrapper built around fetch with an intuitive syntax.
1 lines • 5.37 kB
Source Map (JSON)
{"version":3,"file":"abort.min.mjs","names":[],"sources":["../../../src/addons/abort.ts"],"sourcesContent":["import type { Wretch, WretchAddon, WretchErrorCallback, WretchResponseChain } from \"../types.js\"\n\nexport interface AbortWretch {\n /**\n * Associates a custom controller with the request.\n *\n * Useful when you need to use\n * your own AbortController, otherwise wretch will create a new controller itself.\n *\n * ```js\n * const controller = new AbortController()\n *\n * // Associates the same controller with multiple requests\n * wretch(\"url1\")\n * .addon(AbortAddon())\n * .signal(controller)\n * .get()\n * .json()\n * wretch(\"url2\")\n * .addon(AbortAddon())\n * .signal(controller)\n * .get()\n * .json()\n *\n * // Aborts both requests\n * controller.abort()\n * ```\n *\n * @param controller - An instance of AbortController\n */\n signal: <T extends AbortWretch, C, R, E>(this: T & Wretch<T, C, R, E>, controller: AbortController) => this\n}\n\n/**\n * Options for the setTimeout method.\n */\nexport type SetTimeoutOptions = {\n /**\n * A custom AbortController to use for aborting the request.\n * If not provided, the controller associated with the request will be used.\n */\n controller?: AbortController\n}\n\nexport interface AbortResolver {\n /**\n * Aborts the request after a fixed time.\n *\n * If you use a custom AbortController associated with the request, pass it in the options object.\n *\n * ```js\n * // 1 second timeout\n * wretch(\"...\").addon(AbortAddon()).get().setTimeout(1000).json(_ =>\n * // will not be called if the request timeouts\n * )\n *\n * // With custom controller\n * wretch(\"...\").addon(AbortAddon()).get().setTimeout(1000, { controller }).json()\n * ```\n *\n * @param time - Time in milliseconds\n * @param options - Optional configuration object\n */\n setTimeout: <T, C extends AbortResolver, R, E>(this: C & WretchResponseChain<T, C, R, E>, time: number, options?: SetTimeoutOptions) => this\n /**\n * Returns the provided or generated AbortController plus the wretch response chain as a pair.\n *\n * ```js\n * // We need the controller outside the chain\n * const [c, w] = wretch(\"url\")\n * .addon(AbortAddon())\n * .get()\n * .controller()\n *\n * // Resume with the chain\n * w.onAbort(_ => console.log(\"ouch\")).json()\n *\n * // Later on…\n * c.abort()\n * ```\n */\n controller: <T, C extends AbortResolver, R, E>(this: C & WretchResponseChain<T, C, R, E>) => [any, this]\n /**\n * Catches an AbortError and performs a callback.\n */\n onAbort: <T, C extends AbortResolver, R, E>(this: C & WretchResponseChain<T, C, R, E>, cb: WretchErrorCallback<T, C, R, E>) => this\n}\n\n/**\n * Adds the ability to abort requests using AbortController and signals under the hood.\n *\n * ```js\n * import AbortAddon from \"wretch/addons/abort\"\n *\n * const [c, w] = wretch(\"...\")\n * .addon(AbortAddon())\n * .get()\n * .onAbort((_) => console.log(\"Aborted !\"))\n * .controller();\n *\n * w.text((_) => console.log(\"should never be called\"));\n * c.abort();\n *\n * // Or :\n *\n * const controller = new AbortController();\n *\n * wretch(\"...\")\n * .addon(AbortAddon())\n * .signal(controller)\n * .get()\n * .onAbort((_) => console.log(\"Aborted !\"))\n * .text((_) => console.log(\"should never be called\"));\n *\n * controller.abort();\n * ```\n */\nconst abort: () => WretchAddon<AbortWretch, AbortResolver> = () => {\n return {\n beforeRequest(wretch, options, state) {\n const fetchController = new AbortController()\n if (!options[\"signal\"]) {\n options[\"signal\"] = fetchController.signal\n }\n const timeout = {\n ref: null,\n clear() {\n if (timeout.ref) {\n clearTimeout(timeout.ref)\n timeout.ref = null\n }\n }\n }\n state.abort = {\n timeout,\n fetchController\n }\n return wretch\n },\n wretch: {\n signal(controller) {\n return { ...this, _options: { ...this._options, signal: controller.signal } }\n },\n },\n resolver: {\n setTimeout(time, options = {}) {\n const controller = options.controller ?? this._sharedState.abort.fetchController\n const { timeout } = this._sharedState.abort\n timeout.clear()\n timeout.ref = setTimeout(() => controller.abort(), time)\n return this\n },\n controller() { return [this._sharedState.abort.fetchController, this] },\n onAbort(cb) { return this.error(\"AbortError\", cb) }\n },\n }\n}\n\nexport default abort\n"],"mappings":"AAqHA,MAAM,OACG,CACL,cAAc,EAAQ,EAAS,EAAO,CACpC,IAAM,EAAkB,IAAI,gBAC5B,AACE,EAAQ,SAAY,EAAgB,OAEtC,IAAM,EAAU,CACd,IAAK,KACL,OAAQ,CACN,AAEE,EAAQ,OADR,aAAa,EAAQ,IAAI,CACX,OAGnB,CAKD,MAJA,GAAM,MAAQ,CACZ,UACA,kBACD,CACM,GAET,OAAQ,CACN,OAAO,EAAY,CACjB,MAAO,CAAE,GAAG,KAAM,SAAU,CAAE,GAAG,KAAK,SAAU,OAAQ,EAAW,OAAQ,CAAE,EAEhF,CACD,SAAU,CACR,WAAW,EAAM,EAAU,EAAE,CAAE,CAC7B,IAAM,EAAa,EAAQ,YAAc,KAAK,aAAa,MAAM,gBAC3D,CAAE,WAAY,KAAK,aAAa,MAGtC,OAFA,EAAQ,OAAO,CACf,EAAQ,IAAM,eAAiB,EAAW,OAAO,CAAE,EAAK,CACjD,MAET,YAAa,CAAE,MAAO,CAAC,KAAK,aAAa,MAAM,gBAAiB,KAAK,EACrE,QAAQ,EAAI,CAAE,OAAO,KAAK,MAAM,aAAc,EAAG,EAClD,CACF"}