UNPKG

3.9 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var internal = require('../internal');
6
7/**
8 * Creates a `Readable` store that allows reading by subscription.
9 * @param value initial value
10 * @param {StartStopNotifier}start start and stop notifications for subscriptions
11 */
12function readable(value, start) {
13 return {
14 subscribe: writable(value, start).subscribe,
15 };
16}
17/**
18 * Create a `Writable` store that allows both updating and reading by subscription.
19 * @param {*=}value initial value
20 * @param {StartStopNotifier=}start start and stop notifications for subscriptions
21 */
22function writable(value, start = internal.noop) {
23 let stop;
24 const subscribers = [];
25 function set(new_value) {
26 if (internal.safe_not_equal(value, new_value)) {
27 value = new_value;
28 if (!stop) {
29 return; // not ready
30 }
31 subscribers.forEach((s) => s[1]());
32 subscribers.forEach((s) => s[0](value));
33 }
34 }
35 function update(fn) {
36 set(fn(value));
37 }
38 function subscribe(run, invalidate = internal.noop) {
39 const subscriber = [run, invalidate];
40 subscribers.push(subscriber);
41 if (subscribers.length === 1) {
42 stop = start(set) || internal.noop;
43 }
44 run(value);
45 return () => {
46 const index = subscribers.indexOf(subscriber);
47 if (index !== -1) {
48 subscribers.splice(index, 1);
49 }
50 if (subscribers.length === 0) {
51 stop();
52 stop = null;
53 }
54 };
55 }
56 return { set, update, subscribe };
57}
58/**
59 * Derived value store by synchronizing one or more readable stores and
60 * applying an aggregation function over its input values.
61 * @param {Stores} stores input stores
62 * @param {function(Stores=, function(*)=):*}fn function callback that aggregates the values
63 * @param {*=}initial_value when used asynchronously
64 */
65function 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 const invalidators = [];
72 const store = readable(initial_value, (set) => {
73 let inited = false;
74 const values = [];
75 let pending = 0;
76 let cleanup = internal.noop;
77 const sync = () => {
78 if (pending) {
79 return;
80 }
81 cleanup();
82 const result = fn(single ? values[0] : values, set);
83 if (auto) {
84 set(result);
85 }
86 else {
87 cleanup = internal.is_function(result) ? result : internal.noop;
88 }
89 };
90 const unsubscribers = stores_array.map((store, i) => store.subscribe((value) => {
91 values[i] = value;
92 pending &= ~(1 << i);
93 if (inited) {
94 sync();
95 }
96 }, () => {
97 internal.run_all(invalidators);
98 pending |= (1 << i);
99 }));
100 inited = true;
101 sync();
102 return function stop() {
103 internal.run_all(unsubscribers);
104 cleanup();
105 };
106 });
107 return {
108 subscribe(run, invalidate = internal.noop) {
109 invalidators.push(invalidate);
110 const unsubscribe = store.subscribe(run, invalidate);
111 return () => {
112 const index = invalidators.indexOf(invalidate);
113 if (index !== -1) {
114 invalidators.splice(index, 1);
115 }
116 unsubscribe();
117 };
118 }
119 };
120}
121
122Object.defineProperty(exports, 'get', {
123 enumerable: true,
124 get: function () {
125 return internal.get_store_value;
126 }
127});
128exports.derived = derived;
129exports.readable = readable;
130exports.writable = writable;