diff --git a/observeable.js b/observeable.js deleted file mode 100644 index 337be57..0000000 --- a/observeable.js +++ /dev/null @@ -1,28 +0,0 @@ -export default class Observable { - constructor() { - this._observers = new Map(); - this._hasTriggered = false; - this._previousData = null; - } - - clear() { - this._observers.clear(); - } - - notify(data) { - this._observers.forEach(observer => observer(data)); - this._hasTriggered = true; - this._previousData = data; - } - - subscribe(observer, initialize) { - this._observers.set(observer, observer); - if (this._hasTriggered) { - initialize?.(this._previousData); - } - } - - unsubscribe(observer) { - this._observers.delete(observer); - } -} diff --git a/pub-sub.js b/pub-sub.js new file mode 100644 index 0000000..7938343 --- /dev/null +++ b/pub-sub.js @@ -0,0 +1,28 @@ +export default class PubSub { + constructor() { + this._listeners = new Map(); + this._hasTriggered = false; + this._previousData = null; + } + + clear() { + this._listeners.clear(); + } + + publish(data) { + this._listeners.forEach(listener => listener(data)); + this._hasTriggered = true; + this._previousData = data; + } + + subscribe(listener, initialize) { + this._listeners.set(listener, listener); + if (this._hasTriggered) { + initialize?.(this._previousData); + } + } + + unsubscribe(listener) { + this._listeners.delete(listener); + } +} diff --git a/router.js b/router.js index 5c8fe9d..a5cc7ff 100644 --- a/router.js +++ b/router.js @@ -1,4 +1,4 @@ -import Observable from './observeable.js'; +import PubSub from './pub-sub.js'; import page from 'page'; let activePage = page; @@ -15,7 +15,7 @@ export const _createReducedContext = pageContext => ({ options: {}, }); -const _routeChangeObservable = new Observable(); +const _routeChangePubSub = new PubSub(); const _handleRouteView = (context, r) => { if (r.view) { @@ -24,7 +24,7 @@ const _handleRouteView = (context, r) => { reducedContext.options = options || {}; return r.view.call(host, reducedContext); }; - _routeChangeObservable.notify(context); + _routeChangePubSub.publish(context); } }; @@ -106,25 +106,35 @@ export const redirect = path => { export class ContextReactor { constructor(host, callback, initialize) { this.host = host; - this.host.addController(this); + this.host?.addController(this); this._callback = callback; this._initialize = initialize; this._onRouteChange = this._onRouteChange.bind(this); + + if (!this.host) this.connect(); // Support for non-LitElement use cases + } + + connect() { + _routeChangePubSub.subscribe(this._onRouteChange, this._initialize); + } + + disconnect() { + _routeChangePubSub.unsubscribe(this._onRouteChange); } hostConnected() { - _routeChangeObservable.subscribe(this._onRouteChange, this._initialize); + this.connect(); } hostDisconnected() { - _routeChangeObservable.unsubscribe(this._onRouteChange); + this.disconnect(); } _onRouteChange(context) { this._callback?.(context); - this.host.requestUpdate(); + this.host?.requestUpdate(); } } @@ -133,7 +143,7 @@ export const RouterTesting = { activePage.stop(); activePage = page.create(); hasRegistered = false; - _routeChangeObservable.clear(); + _routeChangePubSub.clear(); }, restart: () => {