1 | import { noop, safe_not_equal, subscribe, run_all, is_function } from '../internal/index.mjs';
|
2 | export { get_store_value as get } from '../internal/index.mjs';
|
3 |
|
4 | const subscriber_queue = [];
|
5 | /**
|
6 | * Creates a `Readable` store that allows reading by subscription.
|
7 | * @param value initial value
|
8 | * @param {StartStopNotifier}start start and stop notifications for subscriptions
|
9 | */
|
10 | function readable(value, start) {
|
11 | return {
|
12 | subscribe: writable(value, start).subscribe
|
13 | };
|
14 | }
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function writable(value, start = noop) {
|
21 | let stop;
|
22 | const subscribers = [];
|
23 | function set(new_value) {
|
24 | if (safe_not_equal(value, new_value)) {
|
25 | value = new_value;
|
26 | if (stop) {
|
27 | const run_queue = !subscriber_queue.length;
|
28 | for (let i = 0; i < subscribers.length; i += 1) {
|
29 | const s = subscribers[i];
|
30 | s[1]();
|
31 | subscriber_queue.push(s, value);
|
32 | }
|
33 | if (run_queue) {
|
34 | for (let i = 0; i < subscriber_queue.length; i += 2) {
|
35 | subscriber_queue[i][0](subscriber_queue[i + 1]);
|
36 | }
|
37 | subscriber_queue.length = 0;
|
38 | }
|
39 | }
|
40 | }
|
41 | }
|
42 | function update(fn) {
|
43 | set(fn(value));
|
44 | }
|
45 | function subscribe(run, invalidate = noop) {
|
46 | const subscriber = [run, invalidate];
|
47 | subscribers.push(subscriber);
|
48 | if (subscribers.length === 1) {
|
49 | stop = start(set) || noop;
|
50 | }
|
51 | run(value);
|
52 | return () => {
|
53 | const index = subscribers.indexOf(subscriber);
|
54 | if (index !== -1) {
|
55 | subscribers.splice(index, 1);
|
56 | }
|
57 | if (subscribers.length === 0) {
|
58 | stop();
|
59 | stop = null;
|
60 | }
|
61 | };
|
62 | }
|
63 | return { set, update, subscribe };
|
64 | }
|
65 | function derived(stores, fn, initial_value) {
|
66 | const single = !Array.isArray(stores);
|
67 | const stores_array = single
|
68 | ? [stores]
|
69 | : stores;
|
70 | const auto = fn.length < 2;
|
71 | return readable(initial_value, (set) => {
|
72 | let inited = false;
|
73 | const values = [];
|
74 | let pending = 0;
|
75 | let cleanup = noop;
|
76 | const sync = () => {
|
77 | if (pending) {
|
78 | return;
|
79 | }
|
80 | cleanup();
|
81 | const result = fn(single ? values[0] : values, set);
|
82 | if (auto) {
|
83 | set(result);
|
84 | }
|
85 | else {
|
86 | cleanup = is_function(result) ? result : noop;
|
87 | }
|
88 | };
|
89 | const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
|
90 | values[i] = value;
|
91 | pending &= ~(1 << i);
|
92 | if (inited) {
|
93 | sync();
|
94 | }
|
95 | }, () => {
|
96 | pending |= (1 << i);
|
97 | }));
|
98 | inited = true;
|
99 | sync();
|
100 | return function stop() {
|
101 | run_all(unsubscribers);
|
102 | cleanup();
|
103 | };
|
104 | });
|
105 | }
|
106 |
|
107 | export { derived, readable, writable };
|