UNPKG

svelte-statusable

Version:

Super tiny, simple to use SvelteJS store to control your application status.

317 lines (255 loc) 8.16 kB
var statusable = (function (exports) { 'use strict'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function noop() {} function safe_not_equal(a, b) { return a != a ? b == b : a !== b || a && typeof a === 'object' || typeof a === 'function'; } Promise.resolve(); const subscriber_queue = []; /** * Creates a `Readable` store that allows reading by subscription. * @param value initial value * @param {StartStopNotifier}start start and stop notifications for subscriptions */ function readable(value, start) { return { subscribe: writable(value, start).subscribe }; } /** * Create a `Writable` store that allows both updating and reading by subscription. * @param {*=}value initial value * @param {StartStopNotifier=}start start and stop notifications for subscriptions */ function writable(value, start = noop) { let stop; const subscribers = new Set(); function set(new_value) { if (safe_not_equal(value, new_value)) { value = new_value; if (stop) { // store is ready const run_queue = !subscriber_queue.length; for (const subscriber of subscribers) { subscriber[1](); subscriber_queue.push(subscriber, value); } if (run_queue) { for (let i = 0; i < subscriber_queue.length; i += 2) { subscriber_queue[i][0](subscriber_queue[i + 1]); } subscriber_queue.length = 0; } } } } function update(fn) { set(fn(value)); } function subscribe(run, invalidate = noop) { const subscriber = [run, invalidate]; subscribers.add(subscriber); if (subscribers.size === 1) { stop = start(set) || noop; } run(value); return () => { subscribers.delete(subscriber); if (subscribers.size === 0) { stop(); stop = null; } }; } return { set, update, subscribe }; } var _excluded = ["url", "abort", "payload", "retry"]; var hasWindow = typeof window !== 'undefined'; var hasNavigator = typeof navigator !== 'undefined'; var hasDocument = typeof document !== 'undefined'; var hasEventSource = typeof EventSource !== 'undefined'; var hasAbortController = typeof AbortController !== 'undefined'; var defaultRetry = 10000; function setIntervalImmediately(func, interval) { func(); return setInterval(func, interval); } function heartbeat(_ref) { var url = _ref.url, _ref$abort = _ref.abort, abort = _ref$abort === void 0 ? 0 : _ref$abort, _ref$payload = _ref.payload, payload = _ref$payload === void 0 ? false : _ref$payload; _ref.retry; var options = _objectWithoutProperties(_ref, _excluded); /*eslint no-unused-vars: "off"*/ if (abort && hasAbortController) { var ac = new AbortController(); options.signal = ac.signal; setTimeout(function () { return ac.abort(); }, abort); } return fetch(url, options).then(function (res) { return payload ? res.json() : res.type === 'opaque' || res.ok; }).catch(function () { return false; }); } function statusable(_ref2) { var ping = _ref2.ping, sse = _ref2.sse; var value = { online: hasNavigator ? navigator.onLine : true, hidden: hasDocument ? document.hidden : false, heartbeat: !hasWindow, // for SSR stream: !hasWindow }; if (typeof ping === 'string') { ping = { url: ping, method: 'HEAD', cache: 'no-cache', credentials: 'omit', referrerPolicy: 'no-referrer' }; } if (typeof sse === 'string') { sse = { url: sse, withCredentials: false }; } return readable(value, function (set) { if (!hasWindow || !hasNavigator || !hasDocument) return; var es; var interval; function assign(key, val) { if (value[key] === val) return; set(value = _objectSpread2(_objectSpread2({}, value), {}, _defineProperty({}, key, val))); } function online() { assign('online', navigator.onLine); } function visibility() { assign('hidden', document.hidden); } function stream(e) { assign('stream', e.target.readyState === EventSource.OPEN); } if (sse && hasEventSource) { es = new EventSource(sse.url, { withCredentials: sse.withCredentials }); es.addEventListener('open', stream); es.addEventListener('error', stream); if (sse.event) { es.addEventListener(sse.event, stream); } assign('stream', es.readyState === EventSource.OPEN); } if (ping) { interval = setIntervalImmediately(function () { if (document.hidden || !navigator.onLine) return; heartbeat(ping).then(function (heartbeat) { return assign('heartbeat', heartbeat); }); }, ping.retry || defaultRetry); } window.addEventListener('online', online); window.addEventListener('offline', online); window.addEventListener('visibilitychange', visibility); return function () { window.removeEventListener('online', online); window.removeEventListener('offline', online); window.removeEventListener('visibilitychange', visibility); if (es) { es.removeEventListener('open', stream); es.removeEventListener('error', stream); if (sse.event) { es.removeEventListener(sse.event, stream); } } clearInterval(interval); }; }); } exports.statusable = statusable; Object.defineProperty(exports, '__esModule', { value: true }); return exports; })({});