1
- import { run_all } from './internal.js' ;
1
+ import { run_all , noop } from './internal.js' ;
2
2
3
3
export function readable ( start , value ) {
4
4
const subscribers = [ ] ;
@@ -7,20 +7,22 @@ export function readable(start, value) {
7
7
function set ( newValue ) {
8
8
if ( newValue === value ) return ;
9
9
value = newValue ;
10
- subscribers . forEach ( fn => fn ( value ) ) ;
10
+ subscribers . forEach ( s => s [ 1 ] ( ) ) ;
11
+ subscribers . forEach ( s => s [ 0 ] ( value ) ) ;
11
12
}
12
13
13
14
return {
14
- subscribe ( fn ) {
15
+ subscribe ( run , invalidate = noop ) {
15
16
if ( subscribers . length === 0 ) {
16
17
stop = start ( set ) ;
17
18
}
18
19
19
- subscribers . push ( fn ) ;
20
- fn ( value ) ;
20
+ const subscriber = [ run , invalidate ] ;
21
+ subscribers . push ( subscriber ) ;
22
+ run ( value ) ;
21
23
22
24
return function ( ) {
23
- const index = subscribers . indexOf ( fn ) ;
25
+ const index = subscribers . indexOf ( subscriber ) ;
24
26
if ( index !== - 1 ) subscribers . splice ( index , 1 ) ;
25
27
26
28
if ( subscribers . length === 0 ) {
@@ -38,19 +40,21 @@ export function writable(value) {
38
40
function set ( newValue ) {
39
41
if ( newValue === value ) return ;
40
42
value = newValue ;
41
- subscribers . forEach ( fn => fn ( value ) ) ;
43
+ subscribers . forEach ( s => s [ 1 ] ( ) ) ;
44
+ subscribers . forEach ( s => s [ 0 ] ( value ) ) ;
42
45
}
43
46
44
47
function update ( fn ) {
45
48
set ( fn ( value ) ) ;
46
49
}
47
50
48
- function subscribe ( fn ) {
49
- subscribers . push ( fn ) ;
50
- fn ( value ) ;
51
+ function subscribe ( run , invalidate = noop ) {
52
+ const subscriber = [ run , invalidate ] ;
53
+ subscribers . push ( subscriber ) ;
54
+ run ( value ) ;
51
55
52
56
return ( ) => {
53
- const index = subscribers . indexOf ( fn ) ;
57
+ const index = subscribers . indexOf ( subscriber ) ;
54
58
if ( index !== - 1 ) subscribers . splice ( index , 1 ) ;
55
59
} ;
56
60
}
@@ -63,20 +67,30 @@ export function derive(stores, fn) {
63
67
if ( single ) stores = [ stores ] ;
64
68
65
69
const auto = fn . length === 1 ;
70
+ let value = { } ;
66
71
67
72
return readable ( set => {
68
73
let inited = false ;
69
74
const values = [ ] ;
70
75
76
+ let pending = 0 ;
77
+
71
78
const sync = ( ) => {
79
+ if ( pending ) return ;
72
80
const result = fn ( single ? values [ 0 ] : values , set ) ;
73
- if ( auto ) set ( result ) ;
81
+ if ( auto && ( value !== ( value = result ) ) ) set ( result ) ;
74
82
}
75
83
76
- const unsubscribers = stores . map ( ( store , i ) => store . subscribe ( value => {
77
- values [ i ] = value ;
78
- if ( inited ) sync ( ) ;
79
- } ) ) ;
84
+ const unsubscribers = stores . map ( ( store , i ) => store . subscribe (
85
+ value => {
86
+ values [ i ] = value ;
87
+ pending &= ~ ( 1 << i ) ;
88
+ if ( inited ) sync ( ) ;
89
+ } ,
90
+ ( ) => {
91
+ pending |= ( 1 << i ) ;
92
+ } )
93
+ ) ;
80
94
81
95
inited = true ;
82
96
sync ( ) ;
0 commit comments