From 01d1b3c1396ad233456f42c4053c6643f17efeac Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 20 Jun 2019 10:23:36 +0100 Subject: [PATCH] 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) ); ``` --- ui-v2/app/utils/dom/event-source/blocking.js | 17 +++++++++++++++-- ui-v2/app/utils/dom/event-source/callable.js | 11 ++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ui-v2/app/utils/dom/event-source/blocking.js b/ui-v2/app/utils/dom/event-source/blocking.js index afc315896f..54adb99fc9 100644 --- a/ui-v2/app/utils/dom/event-source/blocking.js +++ b/ui-v2/app/utils/dom/event-source/blocking.js @@ -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() { diff --git a/ui-v2/app/utils/dom/event-source/callable.js b/ui-v2/app/utils/dom/event-source/callable.js index 7f5fe9fe24..17e0e0b0ba 100644 --- a/ui-v2/app/utils/dom/event-source/callable.js +++ b/ui-v2/app/utils/dom/event-source/callable.js @@ -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; } }; }