"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.visibleNodesAndEdgeLines = exports.userIsPanning = exports.treeRequestParametersToAbort = exports.treeParametersToFetch = exports.translation = exports.totalRelatedEventCountForNode = exports.timeRangeFilters = exports.statsTotalForNode = exports.selectedNode = exports.selectAnalyzerById = exports.selectAnalyzer = exports.scalingFactor = exports.scale = exports.resolverTreeSourceAndSchema = exports.resolverTreeHasNodes = exports.resolverComponentInstanceID = exports.relativeHref = exports.relatedEventTotalCount = exports.relatedEventCountOfTypeForNode = exports.projectionMatrix = exports.panelViewAndParameters = exports.originID = exports.nodeStats = exports.nodeEventsInCategory = exports.nodeDataStatus = exports.nodeDataForID = exports.newIDsToRequest = exports.layout = exports.lastRelatedEventResponseContainsCursor = exports.isTreeLoading = exports.isLoadingNodeEventsInCategory = exports.isLoadingMoreNodeEventsInCategory = exports.isCurrentRelatedEventLoading = exports.isAnimating = exports.inverseProjectionMatrix = exports.hasMoreGenerations = exports.hasMoreChildren = exports.hasMoreAncestors = exports.hadErrorLoadingTree = exports.hadErrorLoadingNodeEventsInCategory = exports.graphNodeForID = exports.eventIndices = exports.detectedBounds = exports.currentRelatedEventData = exports.ariaLevel = exports.ariaFlowtoNodeID = exports.ariaActiveDescendant = exports.analyzerByIdSelector = void 0; var _reselect = require("reselect"); var cameraSelectors = _interopRequireWildcard(require("./camera/selectors")); var dataSelectors = _interopRequireWildcard(require("./data/selectors")); var uiSelectors = _interopRequireWildcard(require("./ui/selectors")); var nodeModel = _interopRequireWildcard(require("../../../common/endpoint/models/node")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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; you may not use this file except in compliance with the Elastic License * 2.0. */ const selectAnalyzer = state => state.analyzer; exports.selectAnalyzer = selectAnalyzer; const selectAnalyzerById = (state, id) => state.analyzer[id]; exports.selectAnalyzerById = selectAnalyzerById; const analyzerByIdSelector = (0, _reselect.createSelector)(selectAnalyzer, analyzer => analyzer); /** * A matrix that when applied to a Vector2 will convert it from world coordinates to screen coordinates. * See https://en.wikipedia.org/wiki/Orthographic_projection */ exports.analyzerByIdSelector = analyzerByIdSelector; const projectionMatrix = composeSelectors(cameraStateSelector, cameraSelectors.projectionMatrix); exports.projectionMatrix = projectionMatrix; const translation = composeSelectors(cameraStateSelector, cameraSelectors.translation); exports.translation = translation; const detectedBounds = composeSelectors(dataStateSelector, dataSelectors.detectedBounds); /** * A matrix that when applied to a Vector2 converts it from screen coordinates to world coordinates. * See https://en.wikipedia.org/wiki/Orthographic_projection */ exports.detectedBounds = detectedBounds; const inverseProjectionMatrix = composeSelectors(cameraStateSelector, cameraSelectors.inverseProjectionMatrix); /** * The scale by which world values are scaled when rendered. */ exports.inverseProjectionMatrix = inverseProjectionMatrix; const scale = composeSelectors(cameraStateSelector, cameraSelectors.scale); /** * Scales the coordinate system, used for zooming. Should always be between 0 and 1 */ exports.scale = scale; const scalingFactor = composeSelectors(cameraStateSelector, cameraSelectors.scalingFactor); /** * Whether or not the user is current panning the map. */ exports.scalingFactor = scalingFactor; const userIsPanning = composeSelectors(cameraStateSelector, cameraSelectors.userIsPanning); /** * Whether or not the camera is animating, at a given time. */ exports.userIsPanning = userIsPanning; const isAnimating = composeSelectors(cameraStateSelector, cameraSelectors.isAnimating); exports.isAnimating = isAnimating; const resolverTreeHasNodes = composeSelectors(dataStateSelector, dataSelectors.resolverTreeHasNodes); /** * The position of nodes and edges. */ exports.resolverTreeHasNodes = resolverTreeHasNodes; const layout = composeSelectors(dataStateSelector, dataSelectors.layout); /** * If we need to fetch, this is the entity ID to fetch. */ exports.layout = layout; const treeParametersToFetch = composeSelectors(dataStateSelector, dataSelectors.treeParametersToFetch); exports.treeParametersToFetch = treeParametersToFetch; const treeRequestParametersToAbort = composeSelectors(dataStateSelector, dataSelectors.treeRequestParametersToAbort); /** * An array of indices to use for resolver panel requests. */ exports.treeRequestParametersToAbort = treeRequestParametersToAbort; const eventIndices = composeSelectors(dataStateSelector, dataSelectors.eventIndices); exports.eventIndices = eventIndices; const resolverComponentInstanceID = composeSelectors(dataStateSelector, dataSelectors.resolverComponentInstanceID); /** * This returns a map of nodeIDs to the associated stats provided by the datasource. */ exports.resolverComponentInstanceID = resolverComponentInstanceID; const nodeStats = composeSelectors(dataStateSelector, dataSelectors.nodeStats); /** * This returns the "aggregate total" for related events, tallied as the sum * of their individual `event.category`s. E.g. a [DNS, Network] would count as two * towards the aggregate total. */ exports.nodeStats = nodeStats; const relatedEventTotalCount = composeSelectors(dataStateSelector, dataSelectors.relatedEventTotalCount); /** * the loading state of the current related event data for the `event_detail` view */ exports.relatedEventTotalCount = relatedEventTotalCount; const isCurrentRelatedEventLoading = composeSelectors(dataStateSelector, dataSelectors.isCurrentRelatedEventLoading); /** * the current related event data for the `event_detail` view */ exports.isCurrentRelatedEventLoading = isCurrentRelatedEventLoading; const currentRelatedEventData = composeSelectors(dataStateSelector, dataSelectors.currentRelatedEventData); exports.currentRelatedEventData = currentRelatedEventData; const timeRangeFilters = composeSelectors(dataStateSelector, dataSelectors.timeRangeFilters); /** * Returns the id of the "current" tree node (fake-focused) */ exports.timeRangeFilters = timeRangeFilters; const ariaActiveDescendant = composeSelectors(uiStateSelector, uiSelectors.ariaActiveDescendant); /** * Returns the nodeID of the selected node */ exports.ariaActiveDescendant = ariaActiveDescendant; const selectedNode = composeSelectors(uiStateSelector, uiSelectors.selectedNode); /** * Returns the camera state from within ResolverState */ exports.selectedNode = selectedNode; function cameraStateSelector(state) { return state.camera; } /** * Returns the data state from within ResolverState */ function dataStateSelector(state) { return state.data; } /** * Returns the ui state from within ResolverState */ function uiStateSelector(state) { return state.ui; } /** * Whether or not the resolver is pending fetching data */ const isTreeLoading = composeSelectors(dataStateSelector, dataSelectors.isTreeLoading); /** * Whether or not the resolver encountered an error while fetching data */ exports.isTreeLoading = isTreeLoading; const hadErrorLoadingTree = composeSelectors(dataStateSelector, dataSelectors.hadErrorLoadingTree); /** * True there might be more descendants to retrieve in the resolver graph. */ exports.hadErrorLoadingTree = hadErrorLoadingTree; const hasMoreChildren = composeSelectors(dataStateSelector, dataSelectors.hasMoreChildren); /** * True if there might be more ancestors to retrieve in the resolver graph. */ exports.hasMoreChildren = hasMoreChildren; const hasMoreAncestors = composeSelectors(dataStateSelector, dataSelectors.hasMoreAncestors); /** * True if there might be more generations to retrieve in the resolver graph. */ exports.hasMoreAncestors = hasMoreAncestors; const hasMoreGenerations = composeSelectors(dataStateSelector, dataSelectors.hasMoreGenerations); exports.hasMoreGenerations = hasMoreGenerations; const boundingBox = composeSelectors(cameraStateSelector, cameraSelectors.viewableBoundingBox); const nodesAndEdgelines = composeSelectors(dataStateSelector, dataSelectors.nodesAndEdgelines); /** * Total count of related events for a process. * @deprecated */ const statsTotalForNode = composeSelectors(dataStateSelector, dataSelectors.statsTotalForNode); /** * Return the visible edge lines and process nodes based on the camera position at `time`. * The bounding box represents what the camera can see. The camera position is a function of time because it can be * animated. So in order to get the currently visible entities, we need to pass in time. */ exports.statsTotalForNode = statsTotalForNode; const visibleNodesAndEdgeLines = (0, _reselect.createSelector)(nodesAndEdgelines, boundingBox, function (nodesAndEdgelinesFn, boundingBoxFn) { // `boundingBox` and `nodesAndEdgelines` are each memoized. return time => nodesAndEdgelinesFn(boundingBoxFn(time)); }); /** * Takes a nodeID (aka entity_id) and returns the associated aria level as a number or null if the node ID isn't in the tree. */ exports.visibleNodesAndEdgeLines = visibleNodesAndEdgeLines; const ariaLevel = composeSelectors(dataStateSelector, dataSelectors.ariaLevel); /** * the node ID of the node representing the databaseDocumentID */ exports.ariaLevel = ariaLevel; const originID = composeSelectors(dataStateSelector, dataSelectors.originID); /** * Takes a nodeID (aka entity_id) and returns the node ID of the node that aria should 'flowto' or null * If the node has a flowto candidate that is currently visible, that will be returned, otherwise null. */ exports.originID = originID; const ariaFlowtoNodeID = (0, _reselect.createSelector)(visibleNodesAndEdgeLines, composeSelectors(dataStateSelector, dataSelectors.ariaFlowtoCandidate), function (visibleNodesAndEdgeLinesAtTime, ariaFlowtoCandidate) { return (0, _reselect.defaultMemoize)(time => { // get the visible nodes at `time` const { processNodePositions } = visibleNodesAndEdgeLinesAtTime(time); // get a `Set` containing their node IDs const nodesVisibleAtTime = new Set(); // NB: in practice, any event that has been graphed is guaranteed to have an entity_id for (const visibleNode of processNodePositions.keys()) { const nodeID = nodeModel.nodeID(visibleNode); if (nodeID !== undefined) { nodesVisibleAtTime.add(nodeID); } } // return the ID of `nodeID`'s following sibling, if it is visible return nodeID => { const flowtoNode = ariaFlowtoCandidate(nodeID); return flowtoNode === null || nodesVisibleAtTime.has(flowtoNode) === false ? null : flowtoNode; }; }); }); exports.ariaFlowtoNodeID = ariaFlowtoNodeID; const panelViewAndParameters = composeSelectors(uiStateSelector, uiSelectors.panelViewAndParameters); exports.panelViewAndParameters = panelViewAndParameters; const relativeHref = composeSelectors(uiStateSelector, uiSelectors.relativeHref); /** * Total count of events related to `nodeID`. * Based on `ResolverNodeStats` */ exports.relativeHref = relativeHref; const totalRelatedEventCountForNode = composeSelectors(dataStateSelector, dataSelectors.totalRelatedEventCountForNode); /** * Count of events with `category` related to `nodeID`. * Based on `ResolverNodeStats` * Used to populate the breadcrumbs in the `nodeEventsInCategory` panel. */ exports.totalRelatedEventCountForNode = totalRelatedEventCountForNode; const relatedEventCountOfTypeForNode = composeSelectors(dataStateSelector, dataSelectors.relatedEventCountOfTypeForNode); /** * Events related to the panel node that are in the panel category. * Used to populate the breadcrumbs in the `nodeEventsInCategory` panel. * NB: This cannot tell the view loading information. For example, this does not tell the view if data has been request or if data failed to load. */ exports.relatedEventCountOfTypeForNode = relatedEventCountOfTypeForNode; const nodeEventsInCategory = composeSelectors(dataStateSelector, dataSelectors.nodeEventsInCategory); /** * Flag used to show a Load More Data button in the nodeEventsOfType panel view. */ exports.nodeEventsInCategory = nodeEventsInCategory; const lastRelatedEventResponseContainsCursor = composeSelectors(dataStateSelector, dataSelectors.lastRelatedEventResponseContainsCursor); /** * Flag to show an error message when loading more related events. */ exports.lastRelatedEventResponseContainsCursor = lastRelatedEventResponseContainsCursor; const hadErrorLoadingNodeEventsInCategory = composeSelectors(dataStateSelector, dataSelectors.hadErrorLoadingNodeEventsInCategory); /** * Flag used to show a loading view for the initial loading of related events. */ exports.hadErrorLoadingNodeEventsInCategory = hadErrorLoadingNodeEventsInCategory; const isLoadingNodeEventsInCategory = composeSelectors(dataStateSelector, dataSelectors.isLoadingNodeEventsInCategory); /** * Flag used to show a loading state for any additional related events. */ exports.isLoadingNodeEventsInCategory = isLoadingNodeEventsInCategory; const isLoadingMoreNodeEventsInCategory = composeSelectors(dataStateSelector, dataSelectors.isLoadingMoreNodeEventsInCategory); /** * Returns the state of the node, loading, running, or terminated. */ exports.isLoadingMoreNodeEventsInCategory = isLoadingMoreNodeEventsInCategory; const nodeDataStatus = composeSelectors(dataStateSelector, dataSelectors.nodeDataStatus); /** * Returns the node data object for a specific node ID. */ exports.nodeDataStatus = nodeDataStatus; const nodeDataForID = composeSelectors(dataStateSelector, dataSelectors.nodeDataForID); /** * Returns the graph node for a given ID */ exports.nodeDataForID = nodeDataForID; const graphNodeForID = composeSelectors(dataStateSelector, dataSelectors.graphNodeForID); /** * Returns a Set of node IDs representing the visible nodes in the view that we do no have node data for already. */ exports.graphNodeForID = graphNodeForID; const newIDsToRequest = (0, _reselect.createSelector)(composeSelectors(dataStateSelector, dataState => dataState.nodeData), visibleNodesAndEdgeLines, function (nodeData, visibleNodesAndEdgeLinesAtTime) { return (0, _reselect.defaultMemoize)(time => { const { processNodePositions: nodesInView } = visibleNodesAndEdgeLinesAtTime(time); const nodes = new Set(); // loop through the nodes in view and see if any of them are new aka we don't have node data for them already for (const node of nodesInView.keys()) { const id = nodeModel.nodeID(node); // if the node has a valid ID field, and we either don't have any node data currently, or // the map doesn't have info for this particular node, then add it to the set so it'll be requested // by the middleware if (id !== undefined && (!nodeData || !nodeData.has(id))) { nodes.add(id); } } return nodes; }); }); /** * Returns the schema for the current resolver tree. Currently, only used in the graph controls panel. */ exports.newIDsToRequest = newIDsToRequest; const resolverTreeSourceAndSchema = composeSelectors(dataStateSelector, dataSelectors.resolverTreeSourceAndSchema); /** * Calls the `secondSelector` with the result of the `selector`. Use this when re-exporting a * concern-specific selector. `selector` should return the concern-specific state. */ exports.resolverTreeSourceAndSchema = resolverTreeSourceAndSchema; function composeSelectors(selector, secondSelector) { return state => secondSelector(selector(state)); }