UNPKG

@aws-amplify/core

Version:
121 lines (118 loc) 3.77 kB
import { ConsoleLogger } from '../Logger/ConsoleLogger.mjs'; import { NO_HUBCALLBACK_PROVIDED_EXCEPTION } from '../constants.mjs'; import { AmplifyError } from '../errors/AmplifyError.mjs'; import '../types/errors.mjs'; import '../errors/errorHelpers.mjs'; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 const AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' ? Symbol('amplify_default') : '@@amplify_default'); const logger = new ConsoleLogger('Hub'); class HubClass { constructor(name) { this.listeners = new Map(); this.protectedChannels = [ 'core', 'auth', 'api', 'analytics', 'interactions', 'pubsub', 'storage', 'ui', 'xr', ]; this.name = name; } /** * Used internally to remove a Hub listener. * * @remarks * This private method is for internal use only. Instead of calling Hub.remove, call the result of Hub.listen. */ _remove(channel, listener) { const holder = this.listeners.get(channel); if (!holder) { logger.warn(`No listeners for ${channel}`); return; } this.listeners.set(channel, [ ...holder.filter(({ callback }) => callback !== listener), ]); } dispatch(channel, payload, source, ampSymbol) { if (typeof channel === 'string' && this.protectedChannels.indexOf(channel) > -1) { const hasAccess = ampSymbol === AMPLIFY_SYMBOL; if (!hasAccess) { logger.warn(`WARNING: ${channel} is protected and dispatching on it can have unintended consequences`); } } const capsule = { channel, payload: { ...payload }, source, patternInfo: [], }; try { this._toListeners(capsule); } catch (e) { logger.error(e); } } listen(channel, callback, listenerName = 'noname') { let cb; if (typeof callback !== 'function') { throw new AmplifyError({ name: NO_HUBCALLBACK_PROVIDED_EXCEPTION, message: 'No callback supplied to Hub', }); } else { // Needs to be casted as a more generic type cb = callback; } let holder = this.listeners.get(channel); if (!holder) { holder = []; this.listeners.set(channel, holder); } holder.push({ name: listenerName, callback: cb, }); return () => { this._remove(channel, cb); }; } _toListeners(capsule) { const { channel, payload } = capsule; const holder = this.listeners.get(channel); if (holder) { holder.forEach(listener => { logger.debug(`Dispatching to ${channel} with `, payload); try { listener.callback(capsule); } catch (e) { logger.error(e); } }); } } } /* We export a __default__ instance of HubClass to use it as a pseudo 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__'); /** * @internal * * Internal hub used for core Amplify functionality. Not intended for use outside of Amplify. * */ const HubInternal = new HubClass('internal-hub'); export { AMPLIFY_SYMBOL, Hub, HubClass, HubInternal }; //# sourceMappingURL=index.mjs.map