ui: Small EventSource additions (#5978)
1. EventSources now pass themselves thorugh to the run function as a second argument. This enables the use of arrow functions along with the EventSources API `(configuration, source) => source.close()`. Order of arguments could potentially be switched at a later date. 2. BlockingEventSources now let you pass an 'event' through at instantation time. If you do this, the event will immediately be dispatched once the EventSource is opened. The usecase for this is for 'unfreezing' cached BlockingEvents. This makes it easier to provide a cache for BlockingEventSources by caching its data rather than the entire BlockingEventSource itself. ``` new BlockingEventSource( (config, source) => { /* something */ }, { cursor: 1024, // this would also come from a cache currentEvent: getFromSomeSortOfCache(eventSourceId) //this is the new bit } ); // more realistically new BlockingEventSource( (config, source) => { return data.findSomething(slug, config) }, getFromSomeSortOfCache(eventSourceId) ); ```
This commit is contained in:
parent
011fb8a559
commit
f7e2bb0712
|
@ -70,10 +70,11 @@ export default function(EventSource, backoff = create5xxBackoff()) {
|
|||
*/
|
||||
return class extends EventSource {
|
||||
constructor(source, configuration = {}) {
|
||||
const { currentEvent, ...config } = configuration;
|
||||
super(configuration => {
|
||||
const { createEvent, ...superConfiguration } = configuration;
|
||||
return source
|
||||
.apply(this, [superConfiguration])
|
||||
.apply(this, [superConfiguration, this])
|
||||
.catch(backoff)
|
||||
.then(result => {
|
||||
if (result instanceof Error) {
|
||||
|
@ -103,7 +104,19 @@ export default function(EventSource, backoff = create5xxBackoff()) {
|
|||
this.previousEvent = this.currentEvent;
|
||||
return throttledResolve(result);
|
||||
});
|
||||
}, configuration);
|
||||
}, config);
|
||||
if (typeof currentEvent !== 'undefined') {
|
||||
this.currentEvent = currentEvent;
|
||||
}
|
||||
// only on initialization
|
||||
// if we already have an currentEvent set via configuration
|
||||
// dispatch the event so things are populated immediately
|
||||
this.addEventListener('open', e => {
|
||||
const currentEvent = e.target.getCurrentEvent();
|
||||
if (typeof currentEvent !== 'undefined') {
|
||||
this.dispatchEvent(currentEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
// if we are having these props, at least make getters
|
||||
getCurrentEvent() {
|
||||
|
|
|
@ -5,7 +5,7 @@ export const defaultRunner = function(target, configuration, isClosed) {
|
|||
}
|
||||
// TODO Consider wrapping this is a promise for none thenable returns
|
||||
return target.source
|
||||
.bind(target)(configuration)
|
||||
.bind(target)(configuration, target)
|
||||
.then(function(res) {
|
||||
return defaultRunner(target, configuration, isClosed);
|
||||
});
|
||||
|
@ -36,7 +36,7 @@ export default function(
|
|||
this.readyState = 2;
|
||||
this.source =
|
||||
typeof source !== 'function'
|
||||
? function(configuration) {
|
||||
? function(configuration, target) {
|
||||
this.close();
|
||||
return P.resolve();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ export default function(
|
|||
P.resolve()
|
||||
.then(() => {
|
||||
// if we are already closed, don't do anything
|
||||
if (this.readyState !== 0) {
|
||||
if (this.readyState > 1) {
|
||||
return;
|
||||
}
|
||||
this.readyState = 1; // open
|
||||
|
@ -68,13 +68,14 @@ export default function(
|
|||
close() {
|
||||
// additional readyState 3 = CLOSING
|
||||
switch (this.readyState) {
|
||||
case 0: // CONNECTING
|
||||
case 2: // CLOSED
|
||||
this.readyState = 2; // CLOSED
|
||||
// it's already CLOSED , do nothing
|
||||
break;
|
||||
default:
|
||||
this.readyState = 3; // CLOSING
|
||||
}
|
||||
// non-standard
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue