svelte-streamable
Version:
Super tiny, simple to use SvelteJS store for real-time updates from server via SSE.
272 lines (213 loc) • 7.05 kB
JavaScript
var streamable = (function (exports) {
'use strict';
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 _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function noop$1() {}
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$1) {
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$1) {
const subscriber = [run, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set) || noop$1;
}
run(value);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0) {
stop();
stop = null;
}
};
}
return {
set,
update,
subscribe
};
}
var _excluded = ["url", "event", "format"];
var esx = {};
function streamable(_ref, callback, defaultValue) {
var url = _ref.url,
_ref$event = _ref.event,
event = _ref$event === void 0 ? 'message' : _ref$event,
_ref$format = _ref.format,
format = _ref$format === void 0 ? 'json' : _ref$format,
options = _objectWithoutProperties(_ref, _excluded);
var auto = !callback || callback.length < 2;
var initial = defaultValue ? Promise.resolve(defaultValue) : new Promise(noop);
return readable(initial, function (set) {
var cleanup = noop;
function resolve(value) {
set(typeof value !== 'undefined' ? Promise.resolve(value) : initial);
}
function update(e) {
cleanup(false);
var data;
if (e && e.data) {
if (format === 'json') {
data = JSON.parse(e.data);
} else if (format === 'base64') {
data = atob(e.data);
} else if (format === 'urlencoded') {
data = Object.fromEntries(new URLSearchParams(e.data));
} else {
data = e.data;
}
}
var result = callback ? callback(data, resolve) : data;
if (auto) {
resolve(result);
} else {
cleanup = typeof result === 'function' ? result : noop;
}
}
function error(e) {
set(Promise.reject(e));
}
var keypath = Object.entries(options).sort().reduce(function (k, _ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
v = _ref3[1];
return "".concat(k, "/").concat(v);
}, url);
var es = esx[keypath];
if (!es) {
es = new EventSource(url, options);
es.subscribers = 0;
esx[keypath] = es;
}
es.addEventListener('error', error);
es.addEventListener(event, update);
callback && setTimeout(update);
es.subscribers++;
return function () {
es.removeEventListener('error', error);
es.removeEventListener(event, update);
if (! --es.subscribers) {
es.close();
delete esx[keypath];
}
cleanup(true);
};
});
}
function noop() {}
exports.streamable = streamable;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
}({}));