1
1
import { DEV } from 'esm-env' ;
2
2
import { source , set } from '../internal/client/reactivity/sources.js' ;
3
+ import { effect } from '../internal/client/reactivity/effects.js' ;
3
4
import { get } from '../internal/client/runtime.js' ;
4
5
import { map } from './utils.js' ;
5
6
@@ -13,7 +14,7 @@ var inited = false;
13
14
*/
14
15
export class ReactiveSet extends Set {
15
16
/** @type {Map<T, import('#client').Source<boolean>> } */
16
- #sources = new Map ( ) ;
17
+ #tracked = new Map ( ) ;
17
18
#version = source ( 0 ) ;
18
19
#size = source ( 0 ) ;
19
20
@@ -27,13 +28,11 @@ export class ReactiveSet extends Set {
27
28
if ( DEV ) new Set ( value ) ;
28
29
29
30
if ( value ) {
30
- var sources = this . #sources;
31
-
32
31
for ( var element of value ) {
33
- sources . set ( element , source ( true ) ) ;
32
+ super . add ( element ) ;
34
33
}
35
34
36
- this . #size. v = sources . size ;
35
+ this . #size. v = super . size ;
37
36
}
38
37
39
38
if ( ! inited ) this . #init( ) ;
@@ -73,65 +72,72 @@ export class ReactiveSet extends Set {
73
72
74
73
/** @param {T } value */
75
74
has ( value ) {
76
- var s = this . #sources. get ( value ) ;
75
+ var exists = super . has ( value ) ;
76
+ var s = this . #tracked. get ( value ) ;
77
77
78
78
if ( s === undefined ) {
79
- // We should always track the version in case
80
- // the Set ever gets this value in the future.
81
- get ( this . #version) ;
82
-
83
- return false ;
79
+ s = source ( exists ) ;
80
+ this . #tracked. set ( value , s ) ;
84
81
}
85
82
83
+ effect ( ( ) => ( ) => {
84
+ queueMicrotask ( ( ) => {
85
+ if ( s && ! s . reactions ) {
86
+ this . #tracked. delete ( value ) ;
87
+ }
88
+ } ) ;
89
+ } ) ;
90
+
86
91
return get ( s ) ;
87
92
}
88
93
89
94
/** @param {T } value */
90
95
add ( value ) {
91
- var sources = this . #sources;
92
-
93
- if ( ! sources . has ( value ) ) {
94
- sources . set ( value , source ( true ) ) ;
95
- set ( this . #size, sources . size ) ;
96
+ if ( ! super . has ( value ) ) {
97
+ super . add ( value ) ;
98
+ set ( this . #size, super . size ) ;
96
99
this . #increment_version( ) ;
100
+
101
+ var s = this . #tracked. get ( value ) ;
102
+ if ( s !== undefined ) {
103
+ set ( s , true ) ;
104
+ }
97
105
}
98
106
99
107
return this ;
100
108
}
101
109
102
110
/** @param {T } value */
103
111
delete ( value ) {
104
- var sources = this . #sources;
105
- var s = sources . get ( value ) ;
106
-
107
- if ( s !== undefined ) {
108
- var removed = sources . delete ( value ) ;
109
- set ( this . #size, sources . size ) ;
110
- set ( s , false ) ;
112
+ var removed = super . delete ( value ) ;
113
+ if ( removed ) {
114
+ set ( this . #size, super . size ) ;
111
115
this . #increment_version( ) ;
112
- return removed ;
116
+
117
+ var s = this . #tracked. get ( value ) ;
118
+ if ( s !== undefined ) {
119
+ set ( s , false ) ;
120
+ }
113
121
}
114
122
115
- return false ;
123
+ return removed ;
116
124
}
117
125
118
126
clear ( ) {
119
- var sources = this . #sources;
120
-
121
- if ( sources . size !== 0 ) {
127
+ if ( super . size !== 0 ) {
122
128
set ( this . #size, 0 ) ;
123
- for ( var s of sources . values ( ) ) {
129
+ for ( var s of this . #tracked . values ( ) ) {
124
130
set ( s , false ) ;
125
131
}
126
132
this . #increment_version( ) ;
127
133
}
128
134
129
- sources . clear ( ) ;
135
+ super . clear ( ) ;
130
136
}
131
137
132
138
keys ( ) {
133
139
get ( this . #version) ;
134
- return map ( this . #sources . keys ( ) , ( key ) => key , 'Set Iterator' ) ;
140
+ return map ( super . keys ( ) , ( key ) => key , 'Set Iterator' ) ;
135
141
}
136
142
137
143
values ( ) {
0 commit comments