Is there a way to cancel/ignore/interrupt a stream based on the output of another stream?
The use case is that I have 3 streams:
- loginStream - user enters login creds and clicks submit. Emits login creds.
- authorizeStream- system tries to authorize user. Emits a token.
- logoutStream - users presses the logout button
The common case is---the user logs in, the system tries to authorize, at some point in the future the user logs out. This is pretty standard FRP.
Common case
loginStream: -------------------o---->
authorizeStream: ---------------a-------->
logoutStream: ---------l-------------->
The edge case is---user logs in but immediately logs out before he's authorized.
Edge case
loginStream: -------------------o---->
authorizeStream: --------a---------------> //ignore/cancel/interrupt this event
logoutStream: -------------l---------->
To keep the system from going to a weird state, I need to ignore the authorize stream in this particular case. The only thing I can think of is to (1) merge the three streams, (2) track state via a scan, (3) logout sets the state to logout
, login sets the state to login
. Filter out an authorize event when not in login
.
merge([loginStream, authorizeStream, logoutStream])
.scan((state, event) => event.type !== 'auth' ? {state: event.type, event} : {state, event}, {})
.filter(event => !(event.state !== 'login' && event.event.type === 'auth'))
The above approach should work but I'm wondering if there's a cleaner, "more FRP" way of ignoring the authorizationStream.