amazon-connect-streams
Version:
Amazon Connect Streams Library
1,318 lines (1,262 loc) • 1.28 MB
JavaScript
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 256:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
AmazonConnectStreamsSite: () => (/* reexport */ AmazonConnectStreamsSite)
});
;// ./node_modules/@amazon-connect/core/lib-esm/provider/global-provider.js
let _provider;
function setGlobalProvider(provider) {
if (_provider)
throw new Error("Global Provider is already set");
_provider = provider;
}
function resetGlobalProvider(provider) {
_provider = provider;
}
function global_provider_getGlobalProvider(notSetMessage) {
if (!_provider) {
throw new Error(notSetMessage !== null && notSetMessage !== void 0 ? notSetMessage : "Attempted to get Global AmazonConnectProvider that has not been set.");
}
return _provider;
}
//# sourceMappingURL=global-provider.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/error/connect-error.js
class ConnectError extends Error {
constructor({ reason, namespace, errorKey, details, }) {
super(`ConnectError with error key "${errorKey}"`);
this.errorType = ConnectError.ErrorType;
this.namespace = namespace;
this.errorKey = errorKey;
this.reason = reason;
this.details = details !== null && details !== void 0 ? details : {};
}
}
ConnectError.ErrorType = "ConnectError";
function isConnectError(error) {
return Boolean(error instanceof ConnectError ||
(error &&
typeof error === "object" &&
"errorType" in error &&
error.errorType === ConnectError.ErrorType));
}
//# sourceMappingURL=connect-error.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/error/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/emitter/emitter-base.js
class emitter_base_EmitterBase {
constructor({ provider, loggerKey }) {
this.events = new Map();
this.logger = new connect_logger_ConnectLogger({
provider,
source: "emitter",
mixin: () => ({
emitterLoggerKey: loggerKey,
}),
});
}
on(parameter, handler) {
const set = this.events.get(parameter);
if (set)
set.add(handler);
else
this.events.set(parameter, new Set([handler]));
}
off(parameter, handler) {
const set = this.events.get(parameter);
if (set) {
set.delete(handler);
if (set.size < 1)
this.events.delete(parameter);
}
}
getHandlers(parameter) {
var _a;
return Array.from((_a = this.events.get(parameter)) !== null && _a !== void 0 ? _a : []);
}
}
//# sourceMappingURL=emitter-base.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/emitter/async-event-emitter.js
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
class AsyncEventEmitter extends emitter_base_EmitterBase {
emit(parameter, event) {
return __awaiter(this, void 0, void 0, function* () {
const handlers = this.getHandlers(parameter);
yield Promise.allSettled(handlers.map((handler) => __awaiter(this, void 0, void 0, function* () {
try {
yield handler(event);
}
catch (error) {
this.logger.error("An error occurred when invoking event handler", {
error,
parameter,
});
}
})));
});
}
}
//# sourceMappingURL=async-event-emitter.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/emitter/emitter.js
class Emitter extends (/* unused pure expression or super */ null && (EmitterBase)) {
emit(parameter) {
for (const handler of this.getHandlers(parameter)) {
try {
handler();
}
catch (error) {
this.logger.error("An error occurred when invoking handler", {
error,
parameter,
});
}
}
}
}
//# sourceMappingURL=emitter.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/emitter/event-emitter.js
class EventEmitter extends (/* unused pure expression or super */ null && (EmitterBase)) {
emit(parameter, event) {
const handlers = this.getHandlers(parameter);
for (const handler of handlers) {
try {
handler(event);
}
catch (error) {
this.logger.error("An error occurred when invoking event handler", {
error,
parameter,
});
}
}
}
}
//# sourceMappingURL=event-emitter.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/emitter/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/id-generator.js
function generateStringId(length) {
const a = new Uint8Array(Math.ceil(length / 2));
crypto.getRandomValues(a);
return Array.from(a, (d) => d.toString(16).padStart(2, "0"))
.join("")
.substring(0, length);
}
function generateUUID() {
if ("randomUUID" in crypto) {
return crypto.randomUUID();
}
else {
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
const d = parseInt(c);
return (d ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (d / 4)))).toString(16);
});
}
}
//# sourceMappingURL=id-generator.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/location-helpers.js
function getOriginAndPath() {
var _a, _b, _c, _d;
return {
origin: (_b = (_a = document === null || document === void 0 ? void 0 : document.location) === null || _a === void 0 ? void 0 : _a.origin) !== null && _b !== void 0 ? _b : "unknown",
path: (_d = (_c = document === null || document === void 0 ? void 0 : document.location) === null || _c === void 0 ? void 0 : _c.pathname) !== null && _d !== void 0 ? _d : "unknown",
};
}
//# sourceMappingURL=location-helpers.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/subscription/subscription-handler-id-map.js
class SubscriptionHandlerIdMap {
constructor() {
this.idsByHandler = new Map();
this.handlersById = new Map();
}
add(handler) {
const existingId = this.idsByHandler.get(handler);
if (existingId) {
return { handlerId: existingId };
}
const handlerId = generateUUID();
this.idsByHandler.set(handler, handlerId);
this.handlersById.set(handlerId, handler);
return { handlerId };
}
getIdByHandler(handler) {
var _a;
return (_a = this.idsByHandler.get(handler)) !== null && _a !== void 0 ? _a : null;
}
getHandlerById(id) {
var _a;
return (_a = this.handlersById.get(id)) !== null && _a !== void 0 ? _a : null;
}
get() {
return [...this.idsByHandler.entries()].map(([handler, handlerId]) => ({
handler,
handlerId,
}));
}
delete(handler) {
const handlerId = this.idsByHandler.get(handler);
if (handlerId)
this.handlersById.delete(handlerId);
this.idsByHandler.delete(handler);
return { isEmpty: this.idsByHandler.size < 1 };
}
size() {
return this.idsByHandler.size;
}
}
//# sourceMappingURL=subscription-handler-id-map.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/subscription/subscription-map.js
class SubscriptionMap {
constructor() {
this.simpleSubscriptions = new Map();
this.paramSubscriptions = new Map();
}
add({ namespace, key, parameter: param }, value) {
var _a, _b, _c, _d, _e;
if (param) {
if (!this.paramSubscriptions.has(namespace)) {
this.paramSubscriptions.set(namespace, new Map([[key, new Map([[param, value]])]]));
return;
}
if (!((_a = this.paramSubscriptions.get(namespace)) === null || _a === void 0 ? void 0 : _a.has(key))) {
(_b = this.paramSubscriptions
.get(namespace)) === null || _b === void 0 ? void 0 : _b.set(key, new Map([[param, value]]));
return;
}
(_d = (_c = this.paramSubscriptions.get(namespace)) === null || _c === void 0 ? void 0 : _c.get(key)) === null || _d === void 0 ? void 0 : _d.set(param, value);
}
else {
if (!this.simpleSubscriptions.has(namespace)) {
this.simpleSubscriptions.set(namespace, new Map([[key, value]]));
return;
}
else
(_e = this.simpleSubscriptions.get(namespace)) === null || _e === void 0 ? void 0 : _e.set(key, value);
}
}
delete({ namespace, key, parameter: param }) {
var _a, _b, _c, _d;
if (param) {
if ((_b = (_a = this.paramSubscriptions.get(namespace)) === null || _a === void 0 ? void 0 : _a.get(key)) === null || _b === void 0 ? void 0 : _b.delete(param)) {
if (this.paramSubscriptions.get(namespace).get(key).size < 1) {
(_c = this.paramSubscriptions.get(namespace)) === null || _c === void 0 ? void 0 : _c.delete(key);
if (this.paramSubscriptions.get(namespace).size < 1) {
this.paramSubscriptions.delete(namespace);
}
}
}
}
else {
if ((_d = this.simpleSubscriptions.get(namespace)) === null || _d === void 0 ? void 0 : _d.delete(key)) {
if (this.simpleSubscriptions.get(namespace).size < 1) {
this.simpleSubscriptions.delete(namespace);
}
}
}
}
get({ namespace, key, parameter: param }) {
var _a, _b, _c;
if (!param) {
return (_a = this.simpleSubscriptions.get(namespace)) === null || _a === void 0 ? void 0 : _a.get(key);
}
else {
return (_c = (_b = this.paramSubscriptions.get(namespace)) === null || _b === void 0 ? void 0 : _b.get(key)) === null || _c === void 0 ? void 0 : _c.get(param);
}
}
getOrAdd(topic, addFactory) {
let value = this.get(topic);
if (!value) {
value = addFactory();
this.add(topic, value);
}
return value;
}
addOrUpdate(topic, addFactory, updateAction) {
let value = this.get(topic);
if (value) {
value = updateAction(value);
}
else {
value = addFactory();
}
this.add(topic, value);
return value;
}
getAllSubscriptions() {
const noParam = Array.from(this.simpleSubscriptions.keys()).flatMap((namespace) => Array.from(this.simpleSubscriptions.get(namespace).keys()).flatMap((key) => ({
namespace,
key,
})));
const withParam = Array.from(this.paramSubscriptions.keys()).flatMap((namespace) => Array.from(this.paramSubscriptions.get(namespace).keys()).flatMap((key) => Array.from(this.paramSubscriptions.get(namespace).get(key).keys()).flatMap((parameter) => ({
namespace,
key,
parameter,
}))));
return [...noParam, ...withParam];
}
}
//# sourceMappingURL=subscription-map.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/subscription/subscription-manager.js
class SubscriptionManager {
constructor() {
this.subscriptions = new SubscriptionMap();
}
add(topic, handler) {
return this.subscriptions
.getOrAdd(topic, () => new SubscriptionHandlerIdMap())
.add(handler);
}
get(topic) {
var _a, _b;
return (_b = (_a = this.subscriptions.get(topic)) === null || _a === void 0 ? void 0 : _a.get()) !== null && _b !== void 0 ? _b : [];
}
getById(topic, handlerId) {
var _a, _b;
return (_b = (_a = this.subscriptions.get(topic)) === null || _a === void 0 ? void 0 : _a.getHandlerById(handlerId)) !== null && _b !== void 0 ? _b : null;
}
delete(topic, handler) {
var _a, _b;
if ((_b = (_a = this.subscriptions.get(topic)) === null || _a === void 0 ? void 0 : _a.delete(handler).isEmpty) !== null && _b !== void 0 ? _b : false) {
this.subscriptions.delete(topic);
}
}
size(topic) {
var _a, _b;
return (_b = (_a = this.subscriptions.get(topic)) === null || _a === void 0 ? void 0 : _a.size()) !== null && _b !== void 0 ? _b : 0;
}
isEmpty(topic) {
return this.size(topic) === 0;
}
getAllSubscriptions() {
return this.subscriptions.getAllSubscriptions();
}
getAllSubscriptionHandlerIds() {
return this.subscriptions
.getAllSubscriptions()
.reduce((acc, topic) => acc.concat(this.get(topic).map(({ handlerId }) => ({
topic,
handlerId,
}))), []);
}
}
//# sourceMappingURL=subscription-manager.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/subscription/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/metric/connect-metric-recorder.js
/**
* @classdesc ConnectMetricRecorder class provides APIs to emit metrics based on users' need
*/
class connect_metric_recorder_ConnectMetricRecorder {
/**
* Constructor for ConnectMetricRecorder
* @param {ConnectRecorderMetricParams} params - The namespace and provider(optional)
*/
constructor(params) {
this._proxy = null;
this.namespace = params.namespace;
if (params.provider && typeof params.provider === "function")
this.providerFactory = params.provider;
else
this.provider = params.provider;
}
/**
* Emit a metric that counts success
* @param {string} metricName - The name of the metric
* @param {Record<string, string>} dimensions - The dimensions of a metric with keys and values (optional)
* @param {Record<string, string>} optionalDimensions - The optional dimensions of a metric with keys and values (optional)
*/
recordSuccess(metricName, metricOptions) {
var _a;
const processedDimensions = Object.assign({}, ((_a = metricOptions === null || metricOptions === void 0 ? void 0 : metricOptions.dimensions) !== null && _a !== void 0 ? _a : {}));
const processedMetricOptions = Object.assign(Object.assign({}, metricOptions), { dimensions: processedDimensions });
this.recordCount(metricName, 0, processedMetricOptions);
}
/**
* Emit a metric that counts error. Add default dimension { name: "Metric", value: "Error" } to the metric if not added
* @param {string} metricName - The name of the metric
* @param {Record<string, string>} dimensions - The dimensions of a metric with keys and values (optional)
* @param {Record<string, string>} optionalDimensions - The optional dimensions of a metric with keys and values (optional)
*/
recordError(metricName, metricOptions) {
var _a;
const processedDimensions = Object.assign({}, ((_a = metricOptions === null || metricOptions === void 0 ? void 0 : metricOptions.dimensions) !== null && _a !== void 0 ? _a : {}));
const processedMetricOptions = Object.assign(Object.assign({}, metricOptions), { dimensions: processedDimensions });
this.recordCount(metricName, 1, processedMetricOptions);
}
/**
* Emit a counting metric
* @param {string} metricName - The name of the metric
* @param {number} count - The count of the metric
* @param {Record<string, string>} dimensions - The dimensions of a metric with keys and values (optional)
* @param {Record<string, string>} optionalDimensions - The optional dimensions of a metric with keys and values (optional)
*/
recordCount(metricName, count, metricOptions) {
this.sendMetric({
metricName,
unit: "Count",
value: count,
dimensions: metricOptions === null || metricOptions === void 0 ? void 0 : metricOptions.dimensions,
optionalDimensions: metricOptions === null || metricOptions === void 0 ? void 0 : metricOptions.optionalDimensions,
});
}
/**
* Start a duration metric
* @param {string} metricName - The name of the metric
* @param {Record<string, string>} dimensions - The dimensions of a metric with keys and values (optional)
* @param {Record<string, string>} optionalDimensions - The optional dimensions of a metric with keys and values (optional)
* @returns {DurationMetricRecorder} - The DurationMetricRecorder object being created
*/
startDurationCounter(metricName, metricOptions) {
return new DurationMetricRecorder({
sendMetric: this.sendMetric.bind(this),
metricName,
metricOptions,
});
}
/**
* Emit metric
* @param {string} metricName - The name of the metric
* @param {unit} unit - The unit of the metric
* @param {number} value - The value of the metric
* @param {Record<string, string>} dimensions - The dimensions of a metric with keys and values (optional)
* @param {Record<string, string>} optionalDimensions - The optional dimensions of a metric with keys and values (optional)
*/
sendMetric({ metricName, unit, value, dimensions, optionalDimensions, }) {
if (dimensions) {
checkDimensionLength(dimensions, optionalDimensions);
}
const metricData = {
metricName,
unit,
value,
dimensions,
optionalDimensions,
};
const time = new Date();
this.getProxy().sendMetric({
metricData,
time,
namespace: this.namespace,
});
}
/**
* Get the provider of the ConnectMetricRecorder instance
*/
getProvider() {
if (!this.provider) {
this.provider = this.providerFactory
? this.providerFactory()
: getGlobalProvider();
}
return this.provider;
}
/**
* Get the proxy of the ConnectMetricRecorder instance
*/
getProxy() {
if (!this._proxy) {
this._proxy = this.getProvider().getProxy();
}
return this._proxy;
}
}
//# sourceMappingURL=connect-metric-recorder.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/metric/metric-helpers.js
const MAX_METRIC_DIMENSIONS = 30;
/**
* Check if the the sum of the length of dimensions and optional dimentions is exceeding maximum dimension length acceptable by back-end
* @param {Record<string, string>} dimensions - The dimensions of the duration metric with keys and values
* @param {Record<string, string>} optionalDimensions -The optional dimensions of the duration metric with keys and values
*/
function metric_helpers_checkDimensionLength(dimensions, optionalDimensions) {
if (Object.keys(dimensions).length +
Object.keys(optionalDimensions !== null && optionalDimensions !== void 0 ? optionalDimensions : {}).length >
MAX_METRIC_DIMENSIONS) {
throw new Error("Cannot add more than 30 dimensions to a metric");
}
}
/**
* Transform the metric message into the format acceptable by back-end
* @param {MetricData} metricData - The metric data
* @param {string} timestamp - The timestamp of the metric
* @param {string} namespace - The namespace of the metric
* @param {UpstreamMessageOrigin} messageOrigin - The origin of the metric message
* @return {MetricMessage} - Return a MetricMessage object
*/
function createMetricMessage({ metricData, time, namespace }, messageOrigin) {
var _a, _b;
return {
type: "metric",
namespace: namespace,
metricName: metricData.metricName,
unit: metricData.unit,
value: metricData.value,
time: time,
dimensions: (_a = metricData.dimensions) !== null && _a !== void 0 ? _a : {},
optionalDimensions: (_b = metricData.optionalDimensions) !== null && _b !== void 0 ? _b : {},
messageOrigin,
};
}
//# sourceMappingURL=metric-helpers.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/metric/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/request/client-timeout-error.js
const clientTimeoutResponseErrorKey = "clientTimeout";
function formatClientTimeoutError(request, timeoutMs) {
const { namespace, command, data: requestData } = request;
return {
namespace,
reason: "Client Timeout",
details: {
command,
requestData,
timeoutMs,
},
errorKey: clientTimeoutResponseErrorKey,
};
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isClientTimeoutResponseError(err) {
return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
typeof err === "object" && err.errorKey === clientTimeoutResponseErrorKey);
}
//# sourceMappingURL=client-timeout-error.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/request/request-handler-factory.js
const DEFAULT_TIMEOUT_MS = 30 * 1000;
function createRequestHandler(request, onStart, onTimeout, timeoutMs) {
const adjustedTimeoutMs = Math.max(1, timeoutMs !== null && timeoutMs !== void 0 ? timeoutMs : DEFAULT_TIMEOUT_MS);
return new Promise((resolve, reject) => {
let isTimedOut = false;
const timeout = setTimeout(() => {
onTimeout({ timeoutMs: adjustedTimeoutMs, request });
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject(formatClientTimeoutError(request, adjustedTimeoutMs));
isTimedOut = true;
}, adjustedTimeoutMs);
const handler = (msg) => {
clearTimeout(timeout);
if (!isTimedOut) {
if (msg.isError) {
reject(new ConnectError(msg));
}
else {
resolve(msg.data);
}
}
};
onStart(handler);
});
}
//# sourceMappingURL=request-handler-factory.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/request/request-manager.js
class RequestManager {
constructor(provider) {
this.requestMap = new Map();
this.logger = new connect_logger_ConnectLogger({
provider,
source: "core.requestManager",
});
}
processRequest(request) {
const { requestId } = request;
return createRequestHandler(request, (handler) => this.requestMap.set(requestId, handler), ({ request, timeoutMs }) => this.handleTimeout(request, timeoutMs));
}
processResponse(response) {
const { requestId } = response;
const handler = this.requestMap.get(requestId);
if (!handler) {
// The proxy is implemented such that this should never happen
this.logger.error("Returned a response message with no handler", {
message: response,
});
return;
}
handler(response);
this.requestMap.delete(requestId);
}
handleTimeout(request, timeoutMs) {
const { requestId, namespace, command } = request;
this.requestMap.delete(requestId);
this.logger.error("Client request timeout", {
requestId,
namespace,
command,
timeoutMs,
});
}
}
//# sourceMappingURL=request-manager.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/request/request-message-factory.js
function createRequestMessage(namespace, command, data, messageOrigin) {
const requestId = generateUUID();
return {
type: "request",
namespace,
command,
requestId,
data,
messageOrigin,
};
}
//# sourceMappingURL=request-message-factory.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/request/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/downstream-message-sanitizer.js
var __rest = (undefined && undefined.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
function sanitizeDownstreamMessage(message) {
try {
switch (message.type) {
case "acknowledge":
case "error":
case "childConnectionClose":
return message;
case "childDownstreamMessage":
return Object.assign(Object.assign({}, message), { message: sanitizeDownstreamMessage(message.message) });
case "publish": {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { data } = message, other = __rest(message, ["data"]);
return Object.assign({}, other);
}
case "response": {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
if (message.isError)
return Object.assign(Object.assign({}, message), { details: { command: message.details.command } });
else {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { data } = message, other = __rest(message, ["data"]);
return Object.assign({}, other);
}
}
default:
return message;
}
}
catch (error) {
return {
messageDetails: "error when sanitizing downstream message",
message,
error,
};
}
}
//# sourceMappingURL=downstream-message-sanitizer.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/messaging/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/channel-manager.js
class ChannelManager {
constructor(provider, relayChildUpstreamMessage) {
this.provider = provider;
this.relayChildUpstreamMessage = relayChildUpstreamMessage;
this.messagePorts = new Map();
this.logger = new connect_logger_ConnectLogger({
provider,
source: "childConnectionManager",
});
}
addChannel(params) {
const { connectionId } = params;
if (this.messagePorts.has(connectionId)) {
this.logger.error("Attempted to add child connection that already exists. No action", {
connectionId,
});
return;
}
this.setupPort(params);
this.logger.debug("Child port added", { connectionId });
}
updateChannelPort(params) {
var _a;
const { connectionId } = params;
const originalPort = (_a = this.messagePorts.get(connectionId)) === null || _a === void 0 ? void 0 : _a.port;
if (!originalPort) {
this.logger.error("Attempted to update child connection that does not exist No action", {
connectionId,
});
return;
}
originalPort.onmessage = null;
originalPort.close();
this.setupPort(params);
this.logger.info("Updated child port", { connectionId });
}
setupPort({ connectionId, port, providerId, }) {
const handler = this.createMessageHandler(connectionId, providerId);
port.addEventListener("message", handler);
port.start();
this.messagePorts.set(connectionId, { port, handler, providerId });
this.relayChildUpstreamMessage({
type: "childUpstream",
connectionId,
sourceProviderId: providerId,
parentProviderId: this.provider.id,
message: {
type: "childConnectionReady",
},
});
}
handleDownstreamMessage({ connectionId, message, targetProviderId, }) {
const messagePortData = this.messagePorts.get(connectionId);
if (!messagePortData) {
this.logger.warn("Attempted to route downstream message to child message port that does not exist", { connectionId, message: sanitizeDownstreamMessage(message) });
return;
}
const { port, providerId } = messagePortData;
// Older versions of the SDK do not provide a provider id. This
// check is ignored for versions without a providerId.
if (providerId && providerId !== targetProviderId) {
this.logger.error("Downstream target message did not match target provider id. Not sending message.", {
connectionId,
targetProviderId,
actualProviderId: providerId,
message: sanitizeDownstreamMessage(message),
});
return;
}
port.postMessage(message);
}
handleCloseMessage({ connectionId }) {
const messagePortData = this.messagePorts.get(connectionId);
if (!messagePortData) {
this.logger.warn("Attempted to close child message port that was not found", { connectionId });
return;
}
const { port, handler } = messagePortData;
port.removeEventListener("message", handler);
port.close();
this.messagePorts.delete(connectionId);
this.logger.debug("Removed child message channel", { connectionId });
}
createMessageHandler(connectionId, providerId) {
return (message) => this.relayChildUpstreamMessage({
type: "childUpstream",
sourceProviderId: providerId,
parentProviderId: this.provider.id,
connectionId,
message: message.data,
});
}
}
//# sourceMappingURL=channel-manager.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/error/error-service.js
class ErrorService {
constructor(provider) {
this.errorHandlers = new Set();
this.logger = new connect_logger_ConnectLogger({
provider,
source: "core.proxy.error",
});
}
invoke(error) {
const { message, key, details, isFatal, connectionStatus } = error;
this.logger.error(message, {
key,
details,
isFatal,
connectionStatus,
}, { duplicateMessageToConsole: true, remoteIgnore: true });
[...this.errorHandlers].forEach((handler) => {
try {
handler(error);
}
catch (handlerError) {
this.logger.error("An error occurred within a AmazonConnectErrorHandler", {
handlerError,
originalError: error,
});
}
});
}
onError(handler) {
this.errorHandlers.add(handler);
}
offError(handler) {
this.errorHandlers.delete(handler);
}
}
//# sourceMappingURL=error-service.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/error/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/health-check/health-check-manager.js
class HealthCheckManager {
constructor({ provider, sendHealthCheck, getUpstreamMessageOrigin, }) {
this.connectionId = null;
this.healthCheckInterval = null;
this.healthCheckTimeout = null;
this.sendHealthCheck = sendHealthCheck;
this.getUpstreamMessageOrigin = getUpstreamMessageOrigin;
this.sendHealthCheckInterval = null;
this.lastHealthCheckResponse = null;
this._status = "unknown";
this.logger = new connect_logger_ConnectLogger({
source: "core.proxy.health-check",
provider: provider,
mixin: () => ({
connectionId: this.connectionId,
}),
});
this.events = new AsyncEventEmitter({
provider,
loggerKey: "core.proxy.health-check",
});
}
get status() {
return this._status;
}
get isRunning() {
return this.sendHealthCheckInterval !== null;
}
get lastCheckCounter() {
var _a, _b;
return (_b = (_a = this.lastHealthCheckResponse) === null || _a === void 0 ? void 0 : _a.counter) !== null && _b !== void 0 ? _b : null;
}
get lastCheckTime() {
var _a, _b;
return (_b = (_a = this.lastHealthCheckResponse) === null || _a === void 0 ? void 0 : _a.time) !== null && _b !== void 0 ? _b : null;
}
start({ healthCheckInterval: interval, connectionId, }) {
this.connectionId = connectionId;
this.healthCheckInterval = interval;
this.clearInterval();
if (interval <= 0) {
this.logger.debug("Health check disabled");
return;
}
if (interval < 1000) {
this.logger.error("Health check interval is less than 1 second. Not running", { interval });
return;
}
this.sendHealthCheckMessage();
this.sendHealthCheckInterval = setInterval(() => this.sendHealthCheckMessage(), interval);
this.startTimeout();
}
stop() {
this.clearInterval();
this.clearTimeout();
}
handleResponse(message) {
this.setHealthy({
time: message.time,
counter: message.counter,
});
}
sendHealthCheckMessage() {
this.sendHealthCheck({
type: "healthCheck",
messageOrigin: this.getUpstreamMessageOrigin(),
});
}
startTimeout() {
if (!this.healthCheckInterval) {
this.logger.error("Health check interval not set. Cannot start timeout");
return;
}
// Cancels a preexisting timeout to be replaced with new timeout
this.clearTimeout();
this.healthCheckTimeout = setTimeout(() => {
this.setUnhealthy();
}, this.healthCheckInterval * 3);
}
clearInterval() {
if (this.sendHealthCheckInterval) {
clearInterval(this.sendHealthCheckInterval);
this.sendHealthCheckInterval = null;
}
}
clearTimeout() {
if (this.healthCheckTimeout) {
clearTimeout(this.healthCheckTimeout);
this.healthCheckTimeout = null;
}
}
setUnhealthy() {
if (this._status !== "unhealthy") {
const previousStatus = this._status;
this.logger.info("Connection unhealthy", {
previousStatus,
});
this._status = "unhealthy";
this.emitStatusChanged("unhealthy", previousStatus);
}
}
setHealthy(result) {
this.lastHealthCheckResponse = Object.assign({}, result);
if (this._status !== "healthy") {
const previousStatus = this._status;
this.logger.debug("Connection healthy", {
previousStatus,
});
this._status = "healthy";
this.emitStatusChanged("healthy", previousStatus);
}
this.startTimeout();
}
emitStatusChanged(status, previousStatus) {
var _a, _b, _c, _d;
void this.events.emit(HealthCheckManager.statusChangedKey, {
status,
previousStatus,
lastCheckTime: (_b = (_a = this.lastHealthCheckResponse) === null || _a === void 0 ? void 0 : _a.time) !== null && _b !== void 0 ? _b : null,
lastCheckCounter: (_d = (_c = this.lastHealthCheckResponse) === null || _c === void 0 ? void 0 : _c.counter) !== null && _d !== void 0 ? _d : null,
});
}
onStatusChanged(handler) {
this.events.on(HealthCheckManager.statusChangedKey, handler);
}
offStatusChanged(handler) {
this.events.off(HealthCheckManager.statusChangedKey, handler);
}
}
HealthCheckManager.statusChangedKey = "statusChanged";
//# sourceMappingURL=health-check-manager.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/health-check/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/proxy-connection/proxy-connection-status-manager.js
class ProxyConnectionStatusManager {
constructor(provider) {
this.status = "notConnected";
this.changeHandlers = new Set();
this.logger = new connect_logger_ConnectLogger({
source: "core.proxy.connection-status-manager",
provider,
mixin: () => ({ status: this.status }),
});
}
getStatus() {
return this.status;
}
update(evt) {
this.status = evt.status;
this.logger.trace("Proxy Connection Status Changed", {
status: evt.status,
});
[...this.changeHandlers].forEach((handler) => {
try {
handler(evt);
}
catch (error) {
this.logger.error("An error occurred within a ProxyConnectionChangedHandler", { error });
}
});
}
onChange(handler) {
this.changeHandlers.add(handler);
}
offChange(handler) {
this.changeHandlers.delete(handler);
}
}
//# sourceMappingURL=proxy-connection-status-manager.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/proxy-connection/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/proxy.js
var proxy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var proxy_rest = (undefined && undefined.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
class Proxy {
constructor(provider) {
this.provider = provider;
this.logger = new connect_logger_ConnectLogger({
source: "core.proxy",
provider,
mixin: () => ({
proxyType: this.proxyType,
connectionId: this.connectionId,
}),
});
this.requestManager = new RequestManager(provider);
this.status = new ProxyConnectionStatusManager(provider);
this.errorService = new ErrorService(provider);
this.upstreamMessageQueue = [];
this.connectionEstablished = false;
this.isInitialized = false;
this.subscriptions = new SubscriptionManager();
this.connectionId = null;
this.channelManager = new ChannelManager(provider, this.sendOrQueueMessageToSubject.bind(this));
this.healthCheck = new HealthCheckManager({
provider,
sendHealthCheck: this.sendOrQueueMessageToSubject.bind(this),
getUpstreamMessageOrigin: this.getUpstreamMessageOrigin.bind(this),
});
}
init() {
if (this.isInitialized)
throw new Error("Proxy already initialized");
this.isInitialized = true;
this.initProxy();
}
request(namespace, command, data, origin) {
const msg = createRequestMessage(namespace, command, data, origin !== null && origin !== void 0 ? origin : this.getUpstreamMessageOrigin());
const resp = this.requestManager.processRequest(msg);
this.sendOrQueueMessageToSubject(msg);
return resp;
}
subscribe(topic, handler, origin) {
const { handlerId } = this.subscriptions.add(topic, handler);
const msg = {
type: "subscribe",
topic,
messageOrigin: origin !== null && origin !== void 0 ? origin : this.getUpstreamMessageOrigin(),
handlerId,
};
this.sendOrQueueMessageToSubject(msg);
}
unsubscribe(topic, handler, origin) {
this.subscriptions.delete(topic, handler);
if (this.subscriptions.isEmpty(topic)) {
const msg = {
type: "unsubscribe",
topic,
messageOrigin: origin !== null && origin !== void 0 ? origin : this.getUpstreamMessageOrigin(),
};
this.sendOrQueueMessageToSubject(msg);
}
}
log(logData) {
const logMsg = createLogMessage(logData, this.addContextToLogger(), this.getUpstreamMessageOrigin());
this.sendOrQueueMessageToSubject(logMsg);
}
sendLogMessage(message) {
if (message.type !== "log") {
this.logger.error("Attempted to send invalid log message", {
message,
});
return;
}
message.context = Object.assign(Object.assign({}, message.context), this.addContextToLogger());
this.sendOrQueueMessageToSubject(message);
}
sendMetric({ metricData, time, namespace }) {
const metricMessage = createMetricMessage({
metricData,
time,
namespace,
}, this.getUpstreamMessageOrigin());
this.sendOrQueueMessageToSubject(metricMessage);
}
sendMetricMessage(metricMessage) {
if (metricMessage.type !== "metric") {
this.logger.error("Attempted to send invalid metric message", {
metricMessage,
});
return;
}
this.sendOrQueueMessageToSubject(metricMessage);
}
sendOrQueueMessageToSubject(message) {
if (this.connectionEstablished) {
this.sendMessageToSubject(message);
}
else {
this.upstreamMessageQueue.push(message);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
consumerMessageHandler(evt) {
if (!this.isInitialized) {
this.logger.error("Attempted to process message from subject prior to proxy being initializing. Message not processed", { originalMessageEventData: evt.data });
return;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { data } = evt;
if (!("type" in data)) {
// TODO Clean this up... probably safe to ignore without logging
this.logger.warn("Unknown inbound message", {
originalMessageEventData: data,
});
return;
}
// Naming of type confusing because outbound to worker is inbound to client
const msg = data;
this.handleMessageFromSubject(msg);
}
handleMessageFromSubject(msg) {
this.handleDefaultMessageFromSubject(msg);
}
handleDefaultMessageFromSubject(msg) {
switch (msg.type) {
case "acknowledge":
this.handleConnectionAcknowledge(msg);
break;
case "response":
this.handleResponse(msg);
break;
case "publish":
this.handlePublish(msg);
break;
case "error":
this.handleError(msg);
break;
case "childDownstreamMessage":
this.channelManager.handleDownstreamMessage(msg);
break;
case "childConnectionClose":
this.channelManager.handleCloseMessage(msg);
break;
case "healthCheckResponse":
this.healthCheck.handleResponse(msg);
break;
default:
this.logger.error("Unknown inbound message", {
originalMessageEventData: msg,
});
return;
}
}
handleConnectionAcknowledge(msg) {
this.connectionId = msg.connectionId;
this.status.update({
status: "ready",
connectionId: msg.connectionId,
});
this.connectionEstablished = true;
// Sends any messages in queue
while (this.upstreamMessageQueue.length) {
const msg = this.upstreamMessageQueue.shift();
this.sendMessageToSubject(msg);
}
this.healthCheck.start(msg);
}
handleResponse(msg) {
this.requestManager.processResponse(msg);
}
handlePublish(msg) {
const { handlerId, topic } = msg;
if (handlerId) {
const handler = this.subscriptions.getById(topic, handlerId);
if (handler) {
void this.handleAsyncSubscriptionHandlerInvoke({ handler, handlerId }, msg);
}
}
else {
this.subscriptions
.get(topic)
.map((handlerIdMapping) => void this.handleAsyncSubscriptionHandlerInvoke(handlerIdMapping, msg));
}
}
handleError(msg) {
if (msg.isFatal) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { message: reason, type: _ } = msg, details = proxy_rest(msg, ["message", "type"]);
this.status.update({ status: "error", reason: reason, details });
}
this.publishError({
message: msg.message,
key: msg.key,
details: msg.details,
isFatal: msg.isFatal,
proxyStatus: msg.status,
});
}
publishError(error) {
const fullError = Object.assign(Object.assign({}, error), { connectionStatus: this.connectionStatus });
this.errorService.invoke(fullError);
}
handleAsyncSubscriptionHandlerInvoke(_a, _b) {
return proxy_awaiter(this, arguments, void 0, function* ({ handler, handlerId }, { topic, data }) {
try {
yield handler(data);
}
catch (error) {
this.logger.error("An error occurred when handling subscription", {
topic,
error,
handlerId,
});
}
});
}
get connectionStatus() {
return this.status.getStatus();
}
onError(handler) {
this.errorService.onError(handler);
}
offError(handler) {
this.errorService.offError(handler);
}
onConnectionStatusChange(handler) {
this.status.onChange(handler);
}
offConnectionStatusChange(handler) {
this.status.offChange(handler);
}
onHealthCheckStatusChanged(handler) {
this.healthCheck.onStatusChanged(handler);
}
offHealthCheckStatusChanged(handler) {
this.healthCheck.offStatusChanged(handler);
}
addChildChannel(params) {
this.channelManager.addChannel(params);
}
updateChildChannelPort(params) {
this.channelManager.updateChannelPort(params);
}
resetConnection(reason) {
var _a;
this.connectionEstablished = false;
this.status.update({
status: "reset",
reason,
});
const subscriptionHandlerIds = this.subscriptions.getAllSubscriptionHandlerIds();
this.logger.info("Resetting proxy", {
reason,
subscriptionHandlerCount: (_a = subscriptionHandlerIds === null || subscriptionHandlerIds === void 0 ? void 0 : subscriptionHandlerIds.length) !== null && _a !== void 0 ? _a : -1,
});
// Restore all subscriptions
subscriptionHandlerIds === null || subscriptionHandlerIds === void 0 ? void 0 : subscriptionHandlerIds.map(({ topic, handlerId }) => ({
type: "subscribe",
topic,
messageOrigin: this.getUpstreamMessageOrigin(),
handlerId,
})).forEach((msg) => this.sendOrQueueMessageToSubject(msg));
// TODO Notify Connection has repaired
}
}
//# sourceMappingURL=proxy.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/proxy/index.js
//# sourceMappingURL=index.js.map
;// ./node_modules/@amazon-connect/core/lib-esm/utility/subsc