"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.sessionPureTransitions = exports.sessionPureSelectors = exports.createSessionStateContainer = exports.TrackedSearchState = exports.SearchSessionState = void 0; var _uuid = require("uuid"); var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal")); var _operators = require("rxjs/operators"); var _public = require("@kbn/kibana-utils-plugin/public"); /* * 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. */ /** * Possible state that current session can be in * * @public */ let SearchSessionState; /** * State of the tracked search */ exports.SearchSessionState = SearchSessionState; (function (SearchSessionState) { SearchSessionState["None"] = "none"; SearchSessionState["Loading"] = "loading"; SearchSessionState["Completed"] = "completed"; SearchSessionState["BackgroundLoading"] = "backgroundLoading"; SearchSessionState["BackgroundCompleted"] = "backgroundCompleted"; SearchSessionState["Restored"] = "restored"; SearchSessionState["Canceled"] = "canceled"; })(SearchSessionState || (exports.SearchSessionState = SearchSessionState = {})); let TrackedSearchState; exports.TrackedSearchState = TrackedSearchState; (function (TrackedSearchState) { TrackedSearchState["InProgress"] = "inProgress"; TrackedSearchState["Completed"] = "completed"; TrackedSearchState["Errored"] = "errored"; })(TrackedSearchState || (exports.TrackedSearchState = TrackedSearchState = {})); const createSessionDefaultState = () => ({ sessionId: undefined, appName: undefined, isStored: false, isRestore: false, isCanceled: false, isContinued: false, isStarted: false, trackedSearches: [] }); const sessionPureTransitions = { start: state => ({ appName }) => ({ ...createSessionDefaultState(), sessionId: (0, _uuid.v4)(), startTime: new Date(), appName }), restore: state => sessionId => ({ ...createSessionDefaultState(), sessionId, isRestore: true, isStored: true }), clear: state => () => createSessionDefaultState(), store: state => searchSessionSavedObject => { if (!state.sessionId) throw new Error("Can't store session. Missing sessionId"); if (state.isStored || state.isRestore) throw new Error('Can\'t store because current session is already stored"'); return { ...state, isStored: true, searchSessionSavedObject }; }, trackSearch: state => (search, meta = {}) => { if (!state.sessionId) throw new Error("Can't track search. Missing sessionId"); return { ...state, isStarted: true, trackedSearches: state.trackedSearches.concat({ state: TrackedSearchState.InProgress, searchDescriptor: search, searchMeta: meta }), completedTime: undefined }; }, removeSearch: state => search => { const trackedSearches = state.trackedSearches.filter(s => s.searchDescriptor !== search); return { ...state, trackedSearches, completedTime: trackedSearches.filter(s => s.state !== TrackedSearchState.InProgress).length === 0 ? new Date() : state.completedTime }; }, completeSearch: state => search => { return { ...state, trackedSearches: state.trackedSearches.map(s => { if (s.searchDescriptor === search) { return { ...s, state: TrackedSearchState.Completed }; } return s; }) }; }, errorSearch: state => search => { return { ...state, trackedSearches: state.trackedSearches.map(s => { if (s.searchDescriptor === search) { return { ...s, state: TrackedSearchState.Errored }; } return s; }) }; }, updateSearchMeta: state => (search, meta) => { return { ...state, trackedSearches: state.trackedSearches.map(s => { if (s.searchDescriptor === search) { return { ...s, searchMeta: { ...s.searchMeta, ...meta } }; } return s; }) }; }, cancel: state => () => { if (!state.sessionId) throw new Error("Can't cancel searches. Missing sessionId"); if (state.isRestore) throw new Error("Can't cancel searches when restoring older searches"); return { ...state, pendingSearches: [], isCanceled: true, canceledTime: new Date(), isStored: false, searchSessionSavedObject: undefined }; }, setSearchSessionSavedObject: state => searchSessionSavedObject => { if (!state.sessionId) throw new Error("Can't add search session saved object session into the state. Missing sessionId"); if (state.sessionId !== searchSessionSavedObject.attributes.sessionId) throw new Error("Can't add search session saved object session into the state. SessionIds don't match."); return { ...state, searchSessionSavedObject }; } }; /** * Consolidate meta info about current seach session * Contains both deferred properties and plain properties from state */ exports.sessionPureTransitions = sessionPureTransitions; const sessionPureSelectors = { getState: state => () => { if (!state.sessionId) return SearchSessionState.None; if (!state.isStarted) return SearchSessionState.None; if (state.isCanceled) return SearchSessionState.Canceled; const pendingSearches = state.trackedSearches.filter(s => s.state === TrackedSearchState.InProgress); switch (true) { case state.isRestore: return pendingSearches.length > 0 ? SearchSessionState.BackgroundLoading : SearchSessionState.Restored; case state.isStored: return pendingSearches.length > 0 ? SearchSessionState.BackgroundLoading : SearchSessionState.BackgroundCompleted; default: return pendingSearches.length > 0 ? SearchSessionState.Loading : SearchSessionState.Completed; } return SearchSessionState.None; }, getMeta(state) { const sessionState = this.getState(state)(); return () => { var _state$searchSessionS, _state$searchSessionS2, _state$searchSessionS3; return { state: sessionState, name: (_state$searchSessionS = state.searchSessionSavedObject) === null || _state$searchSessionS === void 0 ? void 0 : _state$searchSessionS.attributes.name, startTime: (_state$searchSessionS2 = state.searchSessionSavedObject) !== null && _state$searchSessionS2 !== void 0 && _state$searchSessionS2.attributes.created ? new Date((_state$searchSessionS3 = state.searchSessionSavedObject) === null || _state$searchSessionS3 === void 0 ? void 0 : _state$searchSessionS3.attributes.created) : state.startTime, completedTime: state.completedTime, canceledTime: state.canceledTime, isContinued: state.isContinued }; }; }, getSearch(state) { return search => { var _state$trackedSearche; return (_state$trackedSearche = state.trackedSearches.find(s => s.searchDescriptor === search)) !== null && _state$trackedSearche !== void 0 ? _state$trackedSearche : null; }; } }; exports.sessionPureSelectors = sessionPureSelectors; const createSessionStateContainer = ({ freeze = true } = { freeze: true }) => { const stateContainer = (0, _public.createStateContainer)(createSessionDefaultState(), sessionPureTransitions, sessionPureSelectors, freeze ? undefined : { freeze: s => s }); const sessionMeta$ = stateContainer.state$.pipe((0, _operators.map)(() => stateContainer.selectors.getMeta()), (0, _operators.distinctUntilChanged)(_fastDeepEqual.default), (0, _operators.shareReplay)(1)); const sessionState$ = sessionMeta$.pipe((0, _operators.map)(meta => meta.state), (0, _operators.distinctUntilChanged)()); return { stateContainer, sessionState$, sessionMeta$ }; }; exports.createSessionStateContainer = createSessionStateContainer;