2019-03-09 22:22:22 +01:00
|
|
|
import { run_all, noop, get_store_value, safe_not_equal } from './internal';
|
2017-11-24 18:50:12 +01:00
|
|
|
|
2019-03-25 13:18:13 +01:00
|
|
|
export function readable(value, start) {
|
|
|
|
return {
|
|
|
|
subscribe: writable(value, start).subscribe
|
|
|
|
};
|
2018-12-16 01:18:03 +01:00
|
|
|
}
|
2017-11-25 18:07:28 +01:00
|
|
|
|
2019-02-17 18:20:11 +01:00
|
|
|
export function writable(value, start = noop) {
|
|
|
|
let stop;
|
2018-12-16 01:18:03 +01:00
|
|
|
const subscribers = [];
|
2017-11-25 19:55:20 +01:00
|
|
|
|
2019-03-09 22:22:22 +01:00
|
|
|
function set(new_value) {
|
|
|
|
if (safe_not_equal(value, new_value)) {
|
|
|
|
value = new_value;
|
2019-03-09 22:34:30 +01:00
|
|
|
if (!stop) return; // not ready
|
2019-03-09 22:22:22 +01:00
|
|
|
subscribers.forEach(s => s[1]());
|
|
|
|
subscribers.forEach(s => s[0](value));
|
|
|
|
}
|
2018-12-16 01:18:03 +01:00
|
|
|
}
|
2018-05-03 03:31:38 +02:00
|
|
|
|
2018-12-16 01:18:03 +01:00
|
|
|
function update(fn) {
|
|
|
|
set(fn(value));
|
|
|
|
}
|
2017-11-25 18:07:28 +01:00
|
|
|
|
2018-12-17 01:49:42 +01:00
|
|
|
function subscribe(run, invalidate = noop) {
|
|
|
|
const subscriber = [run, invalidate];
|
|
|
|
subscribers.push(subscriber);
|
2019-03-25 13:18:13 +01:00
|
|
|
if (subscribers.length === 1) stop = start(set) || noop;
|
2018-12-17 01:49:42 +01:00
|
|
|
run(value);
|
2018-04-15 19:09:59 +02:00
|
|
|
|
2018-12-16 01:18:03 +01:00
|
|
|
return () => {
|
2018-12-17 01:49:42 +01:00
|
|
|
const index = subscribers.indexOf(subscriber);
|
2018-12-16 01:18:03 +01:00
|
|
|
if (index !== -1) subscribers.splice(index, 1);
|
2019-02-17 18:20:11 +01:00
|
|
|
if (subscribers.length === 0) stop();
|
2018-12-16 01:18:03 +01:00
|
|
|
};
|
|
|
|
}
|
2017-11-25 20:09:41 +01:00
|
|
|
|
2018-12-16 01:18:03 +01:00
|
|
|
return { set, update, subscribe };
|
|
|
|
}
|
2018-02-23 14:47:49 +01:00
|
|
|
|
2019-04-11 21:26:42 +02:00
|
|
|
export function derived(stores, fn, initial_value) {
|
2018-12-16 01:18:03 +01:00
|
|
|
const single = !Array.isArray(stores);
|
|
|
|
if (single) stores = [stores];
|
2017-11-24 18:50:12 +01:00
|
|
|
|
2019-02-05 23:12:14 +01:00
|
|
|
const auto = fn.length < 2;
|
2018-12-17 01:49:42 +01:00
|
|
|
let value = {};
|
2018-12-16 01:18:03 +01:00
|
|
|
|
2019-04-11 21:26:42 +02:00
|
|
|
return readable(initial_value, set => {
|
2018-12-16 01:18:03 +01:00
|
|
|
let inited = false;
|
|
|
|
const values = [];
|
|
|
|
|
2018-12-17 01:49:42 +01:00
|
|
|
let pending = 0;
|
|
|
|
|
2018-12-16 01:18:03 +01:00
|
|
|
const sync = () => {
|
2018-12-17 01:49:42 +01:00
|
|
|
if (pending) return;
|
2018-12-16 01:18:03 +01:00
|
|
|
const result = fn(single ? values[0] : values, set);
|
2019-05-06 12:26:38 +02:00
|
|
|
if (auto) set(result);
|
2019-04-11 21:26:42 +02:00
|
|
|
};
|
2017-11-24 18:50:12 +01:00
|
|
|
|
2018-12-17 01:49:42 +01:00
|
|
|
const unsubscribers = stores.map((store, i) => store.subscribe(
|
|
|
|
value => {
|
|
|
|
values[i] = value;
|
|
|
|
pending &= ~(1 << i);
|
|
|
|
if (inited) sync();
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
pending |= (1 << i);
|
|
|
|
})
|
|
|
|
);
|
2017-11-24 18:50:12 +01:00
|
|
|
|
2018-12-16 01:18:03 +01:00
|
|
|
inited = true;
|
|
|
|
sync();
|
|
|
|
|
|
|
|
return function stop() {
|
|
|
|
run_all(unsubscribers);
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2019-03-01 04:07:48 +01:00
|
|
|
|
|
|
|
export { get_store_value as get };
|