JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdn.jsdelivr.net/kefir/3.1.0/kefir.js"></script>
<p>This is a solution for challenge from "<a href="http://www.jayway.com/2014/09/16/comparing-core-async-and-rx-by-example/" target="_blank">Comparing Core Async and Rx by Example</a>" blog post by Johan Haleby.</p>
<hr/>
<button id="a">A</button>
<button id="b">B</button>
<span id="status">
JavaScript
var SECRET = 'ABBABA';
var TIME_LIMIT = 5 * 1000;
// Base sources
var aClciks = Kefir.fromEvents(document.querySelector('#a'), 'click');
var bClciks = Kefir.fromEvents(document.querySelector('#b'), 'click');
// Compose base sources to create the desirable observables
var letters = Kefir.merge([
aClciks.map(function() {return 'A'}),
bClciks.map(function() {return 'B'})
]);
var withTime = letters.map(function(letter) {
return {
time: Date.now(),
letter: letter
};
});
var lastCombination = withTime
.slidingWindow(SECRET.length)
.map(function(comb) {
return {
timeSpend: comb[comb.length - 1].time - comb[0].time,
letters: comb.map(function(x) {return x.letter}).join('')
}
});
var statusText = lastCombination.map(function(comb) {
return comb.letters + ' (within ' + Math.ceil(comb.timeSpend / 1000) + ' sec.)';
});
var success = lastCombination.filter(function(comb) {
return comb.timeSpend < TIME_LIMIT && comb.letters === SECRET;
});
// Side effects
var statusEl = document.querySelector('#status');
statusText.onValue(function(text) {
statusEl.innerHTML = text;
});
success.onValue(function() {
alert('Combination unlocked!');
});