"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ContextService = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _rxjs = require("rxjs"); var _validation = require("../schema/validation"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ class ContextService { constructor(context$, isDevMode, logger) { (0, _defineProperty2.default)(this, "contextProvidersRegistry", new Map()); (0, _defineProperty2.default)(this, "contextProvidersSubscriptions", new Map()); this.context$ = context$; this.isDevMode = isDevMode; this.logger = logger; } /** * Registers a context provider, and subscribes to any updates from it. * @param contextProviderOpts The options to register the context provider {@link ContextProviderOpts} */ registerContextProvider({ name, context$, schema }) { if (this.contextProvidersSubscriptions.has(name)) { throw new Error(`Context provider with name '${name}' already registered`); } // Declare the validator only in dev-mode const validator = this.isDevMode ? (0, _validation.schemaToIoTs)(schema) : undefined; const subscription = context$.pipe((0, _rxjs.filter)(context => { if (validator) { try { (0, _validation.validateSchema)(`Context Provider '${name}'`, validator, context); } catch (validationError) { this.logger.error(validationError); return false; } } return true; })).subscribe(context => { // We store each context linked to the context provider so they can increase and reduce // the number of fields they report without having left-overs in the global context. this.contextProvidersRegistry.set(name, context); // For every context change, we rebuild the global context. // It's better to do it here than to rebuild it for every reportEvent. this.updateGlobalContext(); }); this.contextProvidersSubscriptions.set(name, subscription); } /** * Removes the context provider from the registry, unsubscribes from it, and rebuilds the global context. * @param name The name of the context provider to remove. */ removeContextProvider(name) { var _this$contextProvider; (_this$contextProvider = this.contextProvidersSubscriptions.get(name)) === null || _this$contextProvider === void 0 ? void 0 : _this$contextProvider.unsubscribe(); this.contextProvidersRegistry.delete(name); this.updateGlobalContext(); } /** * Loops through all the context providers and sets the global context * @private */ updateGlobalContext() { this.context$.next([...this.contextProvidersRegistry.values()].reduce((acc, context) => { return { ...acc, ...this.removeEmptyValues(context) }; }, {})); } removeEmptyValues(context) { if (!context) { return {}; } return Object.keys(context).reduce((acc, key) => { if (context[key] !== undefined) { acc[key] = context[key]; } return acc; }, {}); } } exports.ContextService = ContextService;