"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _exportNames = { browserJourneyReducer: true }; exports.browserJourneyReducer = void 0; var _toolkit = require("@reduxjs/toolkit"); var _runtime_types = require("../../../../../common/runtime_types"); var _actions = require("./actions"); Object.keys(_actions).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _actions[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _actions[key]; } }); }); var _api = require("./api"); Object.keys(_api).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _api[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _api[key]; } }); }); var _models = require("./models"); Object.keys(_models).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _models[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _models[key]; } }); }); var _effects = require("./effects"); Object.keys(_effects).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _effects[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _effects[key]; } }); }); var _selectors = require("./selectors"); Object.keys(_selectors).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _selectors[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _selectors[key]; } }); }); /* * 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 initialState = { blocks: {}, cacheSize: 0, hitCount: [], journeys: {}, journeysLoading: {} }; const browserJourneyReducer = (0, _toolkit.createReducer)(initialState, builder => { builder /** * When removing blocks from the cache, we receive an action with a number. * The number equates to the desired ceiling size of the cache. We then discard * blocks, ordered by the least-requested. We continue dropping blocks until * the newly-pruned size will be less than the ceiling supplied by the action. */.addCase(_actions.pruneCacheAction, (state, action) => { handlePruneAction(state, action.payload); }) /** * Keep track of the least- and most-requested blocks, so when it is time to * prune we keep the most commonly-used ones. */.addCase(_actions.updateHitCountsAction, (state, action) => { handleUpdateHitCountsAction(state, action.payload); }).addCase(_actions.putCacheSize, (state, action) => { state.cacheSize = state.cacheSize + action.payload; }).addCase(_actions.fetchBlocksAction, (state, action) => { state.blocks = { ...state.blocks, ...action.payload // there's no need to overwrite existing blocks because the key // is either storing a pending req or a cached result .filter(b => !state.blocks[b]) // convert the list of new hashes in the payload to an object that // will combine with with the existing blocks cache .reduce((acc, cur) => ({ ...acc, [cur]: { status: 'pending' } }), {}) }; }).addCase(_actions.setBlockLoadingAction, (state, action) => { state.blocks = { ...state.blocks, ...action.payload.reduce((acc, cur) => ({ ...acc, [cur]: { status: 'loading' } }), {}) }; }).addCase(_actions.putBlocksAction, (state, action) => { state.blocks = { ...state.blocks, ...action.payload.blocks.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {}) }; }).addCase(_actions.fetchJourneyAction.get, (state, action) => { state.journeysLoading[action.payload.checkGroup] = true; }).addCase(_actions.fetchJourneyAction.success, (state, action) => { state.journeysLoading[action.payload.checkGroup] = false; state.journeys[action.payload.checkGroup] = action.payload; }).addCase(_actions.fetchJourneyAction.fail, (state, action) => { if (action.payload.getPayload) { state.journeysLoading[action.payload.getPayload.checkGroup] = false; } }); }); exports.browserJourneyReducer = browserJourneyReducer; function handlePruneAction(state, pruneSize) { const { blocks, hitCount } = state; const hashesToPrune = []; let sizeToRemove = 0; let removeIndex = hitCount.length - 1; while (sizeToRemove < pruneSize && removeIndex >= 0) { const { hash } = hitCount[removeIndex]; removeIndex--; if (!blocks[hash]) continue; const block = blocks[hash]; if ((0, _runtime_types.isScreenshotBlockDoc)(block)) { sizeToRemove += block.synthetics.blob.length; hashesToPrune.push(hash); } } for (const hash of hashesToPrune) { delete blocks[hash]; } state.cacheSize = state.cacheSize - sizeToRemove; state.hitCount = hitCount.slice(0, removeIndex + 1); } function handleUpdateHitCountsAction(state, hashes) { const newHitCount = [...state.hitCount]; const hitTime = Date.now(); hashes.forEach(hash => { const countItem = newHitCount.find(item => item.hash === hash); if (!countItem) { newHitCount.push({ hash, hitTime }); } else { countItem.hitTime = hitTime; } }); // sorts in descending order newHitCount.sort((a, b) => b.hitTime - a.hitTime); state.hitCount = newHitCount; }