@@ -30,67 +30,88 @@ export class Signal<TParam> {
3030 }
3131 }
3232
33- static combine < TParam > ( signals : Signal < TParam > [ ] ) : Signal < TParam > {
34- const { signal, emit } = Signal . controlled < TParam > ( )
35-
36- for ( const parentSignal of signals ) {
37- parentSignal . watch ( emit )
38- }
39-
40- return signal
41- }
42-
4333 get emitted ( ) {
4434 return this . #emitted
4535 }
4636
37+ get watched ( ) {
38+ return this . #listeners. length > 0
39+ }
40+
4741 watch ( listener : ( param : TParam ) => void ) {
48- if ( this . #once && this . #emitted ) {
49- return
42+ if ( this . #active ) {
43+ this . #listeners . push ( listener )
5044 }
45+ }
5146
52- this . #listeners. push ( listener )
47+ cancel ( listener : ( param : TParam ) => void ) {
48+ const index = this . #listeners. indexOf ( listener )
49+ if ( index >= 0 ) {
50+ this . #listeners. splice ( index , 1 )
51+ }
5352 }
5453
5554 watchUntil ( cancelSignal : Signal < any > , listener : ( param : TParam ) => void ) {
56- if ( ( cancelSignal . #once && cancelSignal . #emitted ) || ( this . #once && this . #emitted ) ) {
55+ if ( ! this . #active || ! cancelSignal . #active ) {
5756 return
5857 }
5958
59+ const cancel = ( ) => {
60+ this . cancel ( listener )
61+ cancelSignal . cancel ( cancel )
62+ }
63+
6064 this . watch ( listener )
61- cancelSignal . watch ( ( ) => this . cancel ( listener ) )
65+ cancelSignal . watch ( cancel )
6266 }
6367
64- chain ( signal : SignalController < TParam > ) {
65- this . watch ( param => signal . emit ( param ) )
66- }
68+ toggle < TUndoParam > (
69+ undoSignal : Signal < TUndoParam > ,
70+ applyListener : ( param : TParam ) => void ,
71+ undoListener : ( param : TUndoParam ) => void ,
72+ ) {
73+ if ( ! this . #active || ! undoSignal . #active) {
74+ return
75+ }
6776
68- cancel ( listener : ( param : TParam ) => void ) {
69- const index = this . #listeners. indexOf ( listener )
70- if ( index >= 0 ) {
71- this . #listeners. splice ( index , 1 )
77+ const apply = ( param : TParam ) => {
78+ this . cancel ( apply )
79+ if ( undoSignal . #active) {
80+ applyListener ( param )
81+ undoSignal . watch ( undo )
82+ }
83+ }
84+
85+ const undo = ( param : TUndoParam ) => {
86+ undoSignal . cancel ( undo )
87+ undoListener ( param )
88+ if ( this . #active) {
89+ this . watch ( apply )
90+ }
7291 }
92+
93+ this . watch ( apply )
94+ }
95+
96+ get #active( ) {
97+ return ! ( this . #once && this . #emitted)
7398 }
7499
75100 #cancelAll( ) {
76101 this . #listeners. length = 0
77102 }
78103
79104 #emit( param : TParam ) {
80- if ( this . #once && this . #emitted ) {
105+ if ( ! this . #active ) {
81106 return
82107 }
83108
84109 this . #emitted = true
85110
86- if ( this . #reverseOrder) {
87- for ( let index = this . #listeners. length - 1 ; index >= 0 ; index -- ) {
88- this . #listeners[ index ] ?.( param )
89- }
90- } else {
91- for ( const listener of this . #listeners) {
92- listener ( param )
93- }
111+ const listeners = this . #reverseOrder ? this . #listeners. toReversed ( ) : this . #listeners. slice ( )
112+
113+ for ( const listener of listeners ) {
114+ listener ( param )
94115 }
95116
96117 if ( this . #once) {
0 commit comments