@aws-amplify/core
Advanced tools
Comparing version 1.0.24-unstable.0 to 1.0.24-unstable.1
@@ -6,2 +6,13 @@ # Change Log | ||
<a name="1.0.24-unstable.1"></a> | ||
## [1.0.24-unstable.1](https://github.com/aws/aws-amplify/compare/@aws-amplify/core@1.0.24-unstable.0...@aws-amplify/core@1.0.24-unstable.1) (2019-03-28) | ||
### Features | ||
* **core:** Hub refactor and tests ([7ac5bcf](https://github.com/aws/aws-amplify/commit/7ac5bcf)) | ||
<a name="1.0.24-unstable.0"></a> | ||
@@ -8,0 +19,0 @@ ## [1.0.24-unstable.0](https://github.com/aws/aws-amplify/compare/@aws-amplify/core@1.0.23...@aws-amplify/core@1.0.24-unstable.0) (2019-03-22) |
@@ -0,13 +1,36 @@ | ||
interface IPattern { | ||
pattern: RegExp; | ||
callback: HubCallback; | ||
} | ||
interface IListener { | ||
name: string; | ||
callback: HubCallback; | ||
} | ||
export declare type HubCapsule = { | ||
channel: string; | ||
payload: HubPayload; | ||
source: string; | ||
patternInfo?: string[]; | ||
}; | ||
export declare type HubPayload = { | ||
event: string; | ||
data?: any; | ||
message?: string; | ||
}; | ||
export declare type HubCallback = (capsule: HubCapsule) => void; | ||
export declare type LegacyCallback = { | ||
onHubCapsule: HubCallback; | ||
}; | ||
export declare class HubClass { | ||
name: any; | ||
bus: any[]; | ||
listeners: {}; | ||
constructor(name: any); | ||
static createHub(name: any): HubClass; | ||
dispatch(channel: any, payload: any, source?: string): void; | ||
listen(channel: any, listener: any, listenerName?: string): void; | ||
remove(channel: any, listener: any, listenerName?: string): void; | ||
toListeners(capsule: any): void; | ||
name: string; | ||
listeners: IListener[]; | ||
patterns: IPattern[]; | ||
protectedChannels: string[]; | ||
constructor(name: string); | ||
remove(channel: string | RegExp, listener: HubCallback): void; | ||
dispatch(channel: string, payload: HubPayload, source?: string, ampSymbol?: Symbol): void; | ||
listen(channel: string | RegExp, callback?: HubCallback | LegacyCallback, listenerName?: string): void; | ||
private _toListeners; | ||
} | ||
declare const Hub: HubClass; | ||
export default Hub; |
154
lib/Hub.js
@@ -14,68 +14,135 @@ "use strict"; | ||
*/ | ||
var __assign = (this && this.__assign) || Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Logger_1 = require("./Logger"); | ||
var logger = new Logger_1.ConsoleLogger('Hub'); | ||
function isLegacyCallback(callback) { | ||
return callback.onHubCapsule !== undefined; | ||
} | ||
var HubClass = /** @class */ (function () { | ||
function HubClass(name) { | ||
this.bus = []; | ||
this.listeners = {}; | ||
this.listeners = []; | ||
this.patterns = []; | ||
this.protectedChannels = ['core', 'auth', 'api', 'analytics', 'interactions', 'pubsub', 'storage', 'xr']; | ||
this.name = name; | ||
} | ||
HubClass.createHub = function (name) { | ||
return new HubClass(name); | ||
// Note - Need to pass channel as a reference for removal to work and not anonymous function | ||
HubClass.prototype.remove = function (channel, listener) { | ||
if (channel instanceof RegExp) { | ||
var pattern_1 = this.patterns.find(function (_a) { | ||
var pattern = _a.pattern; | ||
return pattern.source === channel.source; | ||
}); | ||
if (!pattern_1) { | ||
logger.warn("No listeners for " + channel); | ||
return; | ||
} | ||
this.patterns = this.patterns.filter(function (x) { return x !== pattern_1; }).slice(); | ||
} | ||
else { | ||
var holder = this.listeners[channel]; | ||
if (!holder) { | ||
logger.warn("No listeners for " + channel); | ||
return; | ||
} | ||
this.listeners[channel] = holder.filter(function (_a) { | ||
var callback = _a.callback; | ||
return callback !== listener; | ||
}).slice(); | ||
} | ||
}; | ||
HubClass.prototype.dispatch = function (channel, payload, source) { | ||
HubClass.prototype.dispatch = function (channel, payload, source, ampSymbol) { | ||
if (source === void 0) { source = ''; } | ||
if (this.protectedChannels.indexOf(channel) > -1) { | ||
var hasAccess = ampSymbol === Symbol.for('amplify_default'); | ||
if (!hasAccess) { | ||
logger.warn("WARNING: " + channel + " is protected and dispatching on it can have unintended consequences"); | ||
} | ||
} | ||
var capsule = { | ||
'channel': channel, | ||
'payload': Object.assign({}, payload), | ||
'source': source | ||
channel: channel, | ||
payload: __assign({}, payload), | ||
source: source, | ||
patternInfo: [] | ||
}; | ||
try { | ||
this.bus.push(capsule); | ||
this.toListeners(capsule); | ||
this._toListeners(capsule); | ||
} | ||
catch (e) { | ||
logger.warn('Hub dispatch error', e); | ||
logger.error(e); | ||
} | ||
}; | ||
HubClass.prototype.listen = function (channel, listener, listenerName) { | ||
HubClass.prototype.listen = function (channel, callback, listenerName) { | ||
if (listenerName === void 0) { listenerName = 'noname'; } | ||
logger.debug(listenerName + ' listening ' + channel); | ||
var holder = this.listeners[channel]; | ||
if (!holder) { | ||
holder = []; | ||
this.listeners[channel] = holder; | ||
var cb; | ||
// Check for legacy onHubCapsule callback for backwards compatability | ||
if (isLegacyCallback(callback)) { | ||
logger.warn("WARNING onHubCapsule is Deprecated. Please pass in a callback."); | ||
cb = callback.onHubCapsule; | ||
} | ||
holder.push({ | ||
'name': listenerName, | ||
'listener': listener | ||
}); | ||
else if (typeof callback !== 'function') { | ||
throw new Error('No callback supplied to Hub'); | ||
} | ||
else { | ||
cb = callback; | ||
} | ||
if (channel instanceof RegExp) { | ||
this.patterns.push({ | ||
pattern: channel, | ||
callback: cb | ||
}); | ||
} | ||
else { | ||
var holder = this.listeners[channel]; | ||
if (!holder) { | ||
holder = []; | ||
this.listeners[channel] = holder; | ||
} | ||
holder.push({ | ||
name: listenerName, | ||
callback: cb | ||
}); | ||
} | ||
}; | ||
HubClass.prototype.remove = function (channel, listener, listenerName) { | ||
if (listenerName === void 0) { listenerName = 'noname'; } | ||
logger.debug(listenerName + ' removing listener ' + channel); | ||
HubClass.prototype._toListeners = function (capsule) { | ||
var channel = capsule.channel, payload = capsule.payload; | ||
var holder = this.listeners[channel]; | ||
if (holder) { | ||
holder = holder.filter(function (_listener) { | ||
return !(listener === _listener.listener && listenerName === _listener.name); | ||
holder.forEach(function (listener) { | ||
logger.debug("Dispatching to " + channel + " with ", payload); | ||
try { | ||
listener.callback(capsule); | ||
} | ||
catch (e) { | ||
logger.error(e); | ||
} | ||
}); | ||
this.listeners[channel] = holder; | ||
} | ||
}; | ||
HubClass.prototype.toListeners = function (capsule) { | ||
var channel = capsule.channel, payload = capsule.payload, source = capsule.source; | ||
var holder = this.listeners[channel]; | ||
if (!holder) { | ||
return; | ||
if (this.patterns.length > 0) { | ||
if (!payload.message) { | ||
logger.warn("Cannot perform pattern matching without a message key"); | ||
return; | ||
} | ||
var payloadStr_1 = payload.message; | ||
this.patterns.forEach(function (pattern) { | ||
var match = payloadStr_1.match(pattern.pattern); | ||
if (match) { | ||
var groups = match.slice(1); | ||
var dispatchingCapsule = __assign({}, capsule, { patternInfo: groups }); | ||
try { | ||
pattern.callback(dispatchingCapsule); | ||
} | ||
catch (e) { | ||
logger.error(e); | ||
} | ||
} | ||
}); | ||
} | ||
holder.forEach(function (listener) { | ||
try { | ||
listener.listener.onHubCapsule(capsule); | ||
} | ||
catch (e) { | ||
logger.warn("error happend when dispatching " + channel + " event to " + listener.name + ": " + e); | ||
} | ||
}); | ||
this.bus.pop(); | ||
}; | ||
@@ -85,4 +152,7 @@ return HubClass; | ||
exports.HubClass = HubClass; | ||
/*We export a __default__ instance of HubClass to use it as a | ||
psuedo Singleton for the main messaging bus, however you can still create | ||
your own instance of HubClass() for a separate "private bus" of events.*/ | ||
var Hub = new HubClass('__default__'); | ||
exports.default = Hub; | ||
//# sourceMappingURL=Hub.js.map |
{ | ||
"name": "@aws-amplify/core", | ||
"version": "1.0.24-unstable.0", | ||
"version": "1.0.24-unstable.1", | ||
"description": "Core category of aws-amplify", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
175
src/Hub.ts
@@ -18,75 +18,158 @@ /* | ||
interface IPattern { | ||
pattern: RegExp, | ||
callback: HubCallback | ||
} | ||
interface IListener { | ||
name: string, | ||
callback: HubCallback | ||
} | ||
export type HubCapsule = { | ||
channel: string, | ||
payload: HubPayload, | ||
source: string, | ||
patternInfo?: string[] | ||
}; | ||
export type HubPayload = { | ||
event: string, | ||
data?: any, | ||
message?: string | ||
}; | ||
export type HubCallback = (capsule: HubCapsule) => void; | ||
export type LegacyCallback = { onHubCapsule: HubCallback }; | ||
function isLegacyCallback(callback: any): callback is LegacyCallback { | ||
return (<LegacyCallback>callback).onHubCapsule !== undefined; | ||
} | ||
export class HubClass { | ||
name; | ||
bus = []; | ||
listeners = {}; | ||
name: string; | ||
listeners: IListener[] = []; | ||
patterns: IPattern[] = []; | ||
constructor(name) { | ||
protectedChannels = ['core', 'auth', 'api', 'analytics', 'interactions', 'pubsub', 'storage', 'xr']; | ||
constructor(name: string) { | ||
this.name = name; | ||
} | ||
static createHub(name) { | ||
return new HubClass(name); | ||
// Note - Need to pass channel as a reference for removal to work and not anonymous function | ||
remove(channel: string | RegExp, listener: HubCallback) { | ||
if (channel instanceof RegExp) { | ||
const pattern = this.patterns.find(({ pattern }) => pattern.source === channel.source); | ||
if (!pattern) { | ||
logger.warn(`No listeners for ${channel}`); | ||
return; | ||
} | ||
this.patterns = [...this.patterns.filter(x => x !== pattern)]; | ||
} else { | ||
const holder = this.listeners[channel]; | ||
if (!holder) { | ||
logger.warn(`No listeners for ${channel}`); | ||
return; | ||
} | ||
this.listeners[channel] = [...holder.filter(({ callback }) => callback !== listener)]; | ||
} | ||
} | ||
dispatch(channel, payload, source='') { | ||
const capsule = { | ||
'channel': channel, | ||
'payload': Object.assign({}, payload), | ||
'source': source | ||
dispatch(channel: string, payload: HubPayload, source: string = '', ampSymbol?: Symbol) { | ||
if (this.protectedChannels.indexOf(channel) > -1) { | ||
const hasAccess = ampSymbol === Symbol.for('amplify_default'); | ||
if (!hasAccess) { | ||
logger.warn(`WARNING: ${channel} is protected and dispatching on it can have unintended consequences`); | ||
} | ||
} | ||
const capsule: HubCapsule = { | ||
channel, | ||
payload: { ...payload }, | ||
source, | ||
patternInfo: [] | ||
}; | ||
try { | ||
this.bus.push(capsule); | ||
this.toListeners(capsule); | ||
} catch (e) { | ||
logger.warn('Hub dispatch error', e); | ||
} | ||
this._toListeners(capsule); | ||
} catch (e) { logger.error(e); } | ||
} | ||
listen(channel, listener, listenerName='noname') { | ||
logger.debug(listenerName + ' listening ' + channel); | ||
listen(channel: string | RegExp, callback?: HubCallback | LegacyCallback, listenerName = 'noname') { | ||
let cb: HubCallback; | ||
// Check for legacy onHubCapsule callback for backwards compatability | ||
if (isLegacyCallback(callback)) { | ||
logger.warn(`WARNING onHubCapsule is Deprecated. Please pass in a callback.`); | ||
cb = callback.onHubCapsule; | ||
} else if (typeof callback !== 'function') { | ||
throw new Error('No callback supplied to Hub'); | ||
} else { | ||
cb = callback; | ||
} | ||
let holder = this.listeners[channel]; | ||
if (!holder) { | ||
holder = []; | ||
this.listeners[channel] = holder; | ||
if (channel instanceof RegExp) { | ||
this.patterns.push({ | ||
pattern: channel, | ||
callback: cb | ||
}); | ||
} else { | ||
let holder = this.listeners[channel]; | ||
if (!holder) { | ||
holder = []; | ||
this.listeners[channel] = holder; | ||
} | ||
holder.push({ | ||
name: listenerName, | ||
callback: cb | ||
}); | ||
} | ||
holder.push({ | ||
'name': listenerName, | ||
'listener': listener | ||
}); | ||
} | ||
remove(channel, listener, listenerName='noname') { | ||
logger.debug(listenerName + ' removing listener ' + channel); | ||
private _toListeners(capsule: HubCapsule) { | ||
const { channel, payload } = capsule; | ||
const holder = this.listeners[channel]; | ||
let holder = this.listeners[channel]; | ||
if (holder) { | ||
holder = holder.filter(_listener => | ||
!(listener === _listener.listener && listenerName === _listener.name) | ||
); | ||
this.listeners[channel] = holder; | ||
holder.forEach(listener => { | ||
logger.debug(`Dispatching to ${channel} with `, payload); | ||
try { | ||
listener.callback(capsule); | ||
} catch (e) { logger.error(e); } | ||
}); | ||
} | ||
} | ||
toListeners(capsule) { | ||
const { channel, payload, source } = capsule; | ||
const holder = this.listeners[channel]; | ||
if (!holder) { return; } | ||
holder.forEach(listener => { | ||
try { | ||
listener.listener.onHubCapsule(capsule); | ||
} catch (e) { | ||
logger.warn(`error happend when dispatching ${channel} event to ${listener.name}: ${e}`); | ||
if (this.patterns.length > 0) { | ||
if (!payload.message) { | ||
logger.warn(`Cannot perform pattern matching without a message key`); | ||
return; | ||
} | ||
}); | ||
this.bus.pop(); | ||
const payloadStr = payload.message; | ||
this.patterns.forEach(pattern => { | ||
const match = payloadStr.match(pattern.pattern); | ||
if (match){ | ||
const [, ...groups] = match; | ||
const dispatchingCapsule:HubCapsule = {...capsule, patternInfo:groups}; | ||
try { | ||
pattern.callback(dispatchingCapsule); | ||
} catch (e) { logger.error(e); } | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
/*We export a __default__ instance of HubClass to use it as a | ||
psuedo Singleton for the main messaging bus, however you can still create | ||
your own instance of HubClass() for a separate "private bus" of events.*/ | ||
const Hub = new HubClass('__default__'); | ||
export default Hub; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
4104849
33441