UNPKG

@waylaidwanderer/fetch-event-source

Version:

A better API for making Event Source requests, with all the features of fetch()

95 lines 4.33 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchEventSource = exports.EventStreamContentType = void 0; const parse_js_1 = require("./parse.cjs"); exports.EventStreamContentType = 'text/event-stream'; const DefaultRetryInterval = 1000; const LastEventId = 'last-event-id'; function fetchEventSource(input, _a) { var { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, fetch: inputFetch } = _a, rest = __rest(_a, ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden", "fetch"]); return new Promise((resolve, reject) => { const headers = Object.assign({}, inputHeaders); if (!headers.accept) { headers.accept = exports.EventStreamContentType; } let curRequestController; function onVisibilityChange() { curRequestController.abort(); if (!document.hidden) { create(); } } if (typeof document !== 'undefined' && !openWhenHidden) { document.addEventListener('visibilitychange', onVisibilityChange); } let retryInterval = DefaultRetryInterval; let retryTimer = 0; function dispose() { if (typeof document !== 'undefined' && !openWhenHidden) { document.removeEventListener('visibilitychange', onVisibilityChange); } clearTimeout(retryTimer); curRequestController.abort(); } inputSignal === null || inputSignal === void 0 ? void 0 : inputSignal.addEventListener('abort', () => { dispose(); resolve(); }); const fetchFn = inputFetch !== null && inputFetch !== void 0 ? inputFetch : fetch; const onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen; async function create() { var _a; curRequestController = new AbortController(); try { const response = await fetchFn(input, Object.assign(Object.assign({}, rest), { headers, signal: curRequestController.signal })); await onopen(response); await (0, parse_js_1.getBytes)(response.body, (0, parse_js_1.getLines)((0, parse_js_1.getMessages)(onmessage, id => { if (id) { headers[LastEventId] = id; } else { delete headers[LastEventId]; } }, retry => { retryInterval = retry; }))); onclose === null || onclose === void 0 ? void 0 : onclose(); dispose(); resolve(); } catch (err) { if (!curRequestController.signal.aborted) { try { const interval = (_a = onerror === null || onerror === void 0 ? void 0 : onerror(err)) !== null && _a !== void 0 ? _a : retryInterval; clearTimeout(retryTimer); retryTimer = setTimeout(create, interval); } catch (innerErr) { dispose(); reject(innerErr); } } } } create(); }); } exports.fetchEventSource = fetchEventSource; function defaultOnOpen(response) { const contentType = response.headers.get('content-type'); if (!(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(exports.EventStreamContentType))) { throw new Error(`Expected content-type to be ${exports.EventStreamContentType}, Actual: ${contentType}`); } } //# sourceMappingURL=fetch.cjs.map