svelte-asyncable
Version:
Super tiny, declarative, optimistic, async store for SvelteJS.
413 lines (403 loc) • 13.3 kB
JavaScript
var asyncable = (function (exports) {
'use strict';
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
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 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 _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
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 _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function noop() {}
function run(fn) {
return fn();
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || a && typeof a === 'object' || typeof a === 'function';
}
function subscribe(store, ...callbacks) {
if (store == null) {
return noop;
}
const unsub = store.subscribe(...callbacks);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function get_store_value(store) {
let value;
subscribe(store, _ => value = _)();
return value;
}
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
};
}
function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
const stores_array = single ? [stores] : stores;
const auto = fn.length < 2;
return readable(initial_value, set => {
let inited = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
}
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) {
set(result);
} else {
cleanup = is_function(result) ? result : noop;
}
};
const unsubscribers = stores_array.map((store, i) => subscribe(store, value => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
sync();
}
}, () => {
pending |= 1 << i;
}));
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
function asyncable(getter) {
var setter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
var stores = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var resolve;
var initial = new Promise(function (res) {
return resolve = res;
});
var derived$ = derived(stores, function (values) {
return values;
});
var store$ = writable(initial, function (set) {
return derived$.subscribe( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var values,
value,
_args = arguments;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
values = _args.length > 0 && _args[0] !== undefined ? _args[0] : [];
value = getter.apply(void 0, _toConsumableArray(values));
if (!(value === undefined)) {
_context.next = 4;
break;
}
return _context.abrupt("return");
case 4:
value = Promise.resolve(value);
set(value);
resolve(value);
case 7:
case "end":
return _context.stop();
}
}
}, _callee);
})));
});
function _set2(_x, _x2) {
return _set.apply(this, arguments);
}
function _set() {
_set = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(newValue, oldValue) {
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
if (!(newValue === oldValue)) {
_context4.next = 2;
break;
}
return _context4.abrupt("return");
case 2:
store$.set(Promise.resolve(newValue));
_context4.prev = 3;
_context4.next = 6;
return setter(newValue, oldValue);
case 6:
_context4.next = 12;
break;
case 8:
_context4.prev = 8;
_context4.t0 = _context4["catch"](3);
store$.set(Promise.resolve(oldValue));
throw _context4.t0;
case 12:
case "end":
return _context4.stop();
}
}
}, _callee4, null, [[3, 8]]);
}));
return _set.apply(this, arguments);
}
return {
subscribe: store$.subscribe,
update: function update(reducer) {
return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
var oldValue, newValue;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (setter) {
_context2.next = 2;
break;
}
return _context2.abrupt("return");
case 2:
_context2.prev = 2;
_context2.next = 5;
return get_store_value(store$);
case 5:
oldValue = _context2.sent;
_context2.next = 8;
return reducer(shallowCopy(oldValue));
case 8:
newValue = _context2.sent;
case 9:
_context2.prev = 9;
_context2.next = 12;
return _set2(newValue, oldValue);
case 12:
return _context2.finish(9);
case 13:
case "end":
return _context2.stop();
}
}
}, _callee2, null, [[2,, 9, 13]]);
}))();
},
set: function set(newValue) {
return _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
var oldValue;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
if (setter) {
_context3.next = 2;
break;
}
return _context3.abrupt("return");
case 2:
_context3.prev = 2;
_context3.next = 5;
return get_store_value(store$);
case 5:
oldValue = _context3.sent;
_context3.next = 8;
return newValue;
case 8:
newValue = _context3.sent;
case 9:
_context3.prev = 9;
_context3.next = 12;
return _set2(newValue, oldValue);
case 12:
return _context3.finish(9);
case 13:
case "end":
return _context3.stop();
}
}
}, _callee3, null, [[2,, 9, 13]]);
}))();
},
get: function get() {
return get_store_value(store$);
}
};
}
function syncable(stores, initialValue) {
return derived(stores, function ($values, set) {
return (Array.isArray(stores) ? Promise.allSettled : Promise.resolve).call(Promise, $values).then(set);
}, initialValue);
}
function shallowCopy(value) {
if (_typeof(value) !== 'object' || value === null) return value;
return Array.isArray(value) ? _toConsumableArray(value) : _objectSpread2({}, value);
}
exports.asyncable = asyncable;
exports.syncable = syncable;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
}({}));