<commit_before>import { Dictionary } from '@ngrx/entity/src/models'
import { createFeatureSelector, createSelector } from '@ngrx/store'

import { SensorsData } from '../../shared/models/sensors-data.model'
import { SourceData } from '../../shared/models/source-data.model'
import * as fromSensorsData from './sensors-data/sensors-data.reducer'
import * as fromSourceTypes from './source-types/source-types.reducer'
import * as fromSources from './sources/sources.reducer'

export interface State {
  sources: fromSources.State
  sensorsData: fromSensorsData.State
  sourceTypes: fromSourceTypes.State
}

export const reducers = {
  sources: fromSources.reducer,
  sensorsData: fromSensorsData.reducer,
  sourceTypes: fromSourceTypes.reducer
}

export const getSubjectFeatureState = createFeatureSelector<State>('subject')

// Sources Selectors
export const getSourcesState = createSelector(
  getSubjectFeatureState,
  state => state.sources
)
export const {
  selectIds: getSourcesIds,
  selectEntities: getSourcesEntities,
  selectAll: getSources
} = fromSources.adapter.getSelectors(getSourcesState)

export const getSourcesData = createSelector(getSources, sources => {
  return sources.length && sources[0].sourceData
    ? sources.reduce((acc, source) => [...acc, ...source.sourceData], [])
    : null
})

export const getSourcesDataEntities = createSelector(
  getSourcesData,
  sourcesData => {
    return sourcesData && sourcesData.length
      ? sourcesData.reduce((acc, sourceData) => {
          return sourceData !== null
            ? { ...acc, [sourceData.uid]: sourceData }
            : { ...acc }
        }, {})
      : null
  }
)

export const getSourcesLoaded = createSelector(
  getSourcesState,
  fromSources.getIsLoaded
)

export const getSourcesSubject = createSelector(
  getSourcesState,
  fromSources.getSubject
)

// SourceTypes Selectors
export const getSourceTypesState = createSelector(
  getSubjectFeatureState,
  state => state.sourceTypes
)

export const {
  selectIds: getSourceTypesIds,
  selectEntities: getSourceTypesEntities,
  selectAll: getSourceTypesAll,
  selectTotal: getSourceTypesTotal
} = fromSourceTypes.adapter.getSelectors(getSourceTypesState)

// SensorsData Selectors
export const getSensorsDataState = createSelector(
  getSubjectFeatureState,
  state => state.sensorsData
)
export const {
  selectIds: getSensorsDataIds,
  selectEntities: getSensorsDataEntities,
  selectAll: getSensorsData
} = fromSensorsData.adapter.getSelectors(getSensorsDataState)

export const getSensorsDataLoaded = createSelector(
  getSensorsDataState,
  fromSensorsData.getIsDataLoaded
)

export const getSensorsDataDates = createSelector(
  getSensorsDataState,
  fromSensorsData.getDates
)

export const getSensorsDataTooltipDate = createSelector(
  getSensorsDataState,
  fromSensorsData.getTooltipDate
)

export const getSensorsDataTimeFrame = createSelector(
  getSensorsDataState,
  fromSensorsData.getTimeFrame
)

export const getSensorsDataTimeInterval = createSelector(
  getSensorsDataState,
  fromSensorsData.getTimeInterval
)

export const getSensorsDataDescriptiveStatistic = createSelector(
  getSensorsDataState,
  fromSensorsData.getDescriptiveStatistic
)

export const getSensorsDataTooltipValues = createSelector(
  getSensorsDataIds,
  getSensorsDataEntities,
  getSourcesDataEntities,
  getSensorsDataTooltipDate,
  (
    ids: string[],
    sensorsDataEntities: Dictionary<SensorsData>,
    sourcesDataEntities: Dictionary<SourceData>,
    date
  ) => {
    if (!date) {
      return []
    }

    return ids
      .filter(
        d =>
          sourcesDataEntities &&
          sourcesDataEntities[d] &&
          sourcesDataEntities[d].visible
      )
      .reduce((acc, id) => {
        const sensorData = sensorsDataEntities[id] || null

        if (sensorData === null) {
          return [...acc]
        }

        const index =
          sensorData.data &&
          sensorData.data.findIndex(d => d.date.getTime() === date.getTime())

        const value =
          sensorData.data && index > -1 ? sensorData.data[index].value : null

        return [
          ...acc,
          {
            id: id,
            label: sourcesDataEntities[id].label,
            dataType: sourcesDataEntities[id].chart.dataType,
            keys: sourcesDataEntities[id].keys || null,
            value
          }
        ]
      }, [])
  }
)<commit_msg>Optimize getSensorsDataTooltipValues selector<commit_after>import { Dictionary } from '@ngrx/entity/src/models'
import { createFeatureSelector, createSelector } from '@ngrx/store'

import { SensorsData } from '../../shared/models/sensors-data.model'
import { SourceData } from '../../shared/models/source-data.model'
import * as fromSensorsData from './sensors-data/sensors-data.reducer'
import * as fromSourceTypes from './source-types/source-types.reducer'
import * as fromSources from './sources/sources.reducer'

export interface State {
  sources: fromSources.State
  sensorsData: fromSensorsData.State
  sourceTypes: fromSourceTypes.State
}

export const reducers = {
  sources: fromSources.reducer,
  sensorsData: fromSensorsData.reducer,
  sourceTypes: fromSourceTypes.reducer
}

export const getSubjectFeatureState = createFeatureSelector<State>('subject')

// Sources Selectors
export const getSourcesState = createSelector(
  getSubjectFeatureState,
  state => state.sources
)
export const {
  selectIds: getSourcesIds,
  selectEntities: getSourcesEntities,
  selectAll: getSources
} = fromSources.adapter.getSelectors(getSourcesState)

export const getSourcesData = createSelector(getSources, sources => {
  return sources.length && sources[0].sourceData
    ? sources.reduce((acc, source) => [...acc, ...source.sourceData], [])
    : null
})

export const getSourcesDataEntities = createSelector(
  getSourcesData,
  sourcesData => {
    return sourcesData && sourcesData.length
      ? sourcesData.reduce((acc, sourceData) => {
          return sourceData !== null
            ? { ...acc, [sourceData.uid]: sourceData }
            : { ...acc }
        }, {})
      : null
  }
)

export const getSourcesLoaded = createSelector(
  getSourcesState,
  fromSources.getIsLoaded
)

export const getSourcesSubject = createSelector(
  getSourcesState,
  fromSources.getSubject
)

// SourceTypes Selectors
export const getSourceTypesState = createSelector(
  getSubjectFeatureState,
  state => state.sourceTypes
)

export const {
  selectIds: getSourceTypesIds,
  selectEntities: getSourceTypesEntities,
  selectAll: getSourceTypesAll,
  selectTotal: getSourceTypesTotal
} = fromSourceTypes.adapter.getSelectors(getSourceTypesState)

// SensorsData Selectors
export const getSensorsDataState = createSelector(
  getSubjectFeatureState,
  state => state.sensorsData
)
export const {
  selectIds: getSensorsDataIds,
  selectEntities: getSensorsDataEntities,
  selectAll: getSensorsData
} = fromSensorsData.adapter.getSelectors(getSensorsDataState)

export const getSensorsDataLoaded = createSelector(
  getSensorsDataState,
  fromSensorsData.getIsDataLoaded
)

export const getSensorsDataDates = createSelector(
  getSensorsDataState,
  fromSensorsData.getDates
)

export const getSensorsDataTooltipDate = createSelector(
  getSensorsDataState,
  fromSensorsData.getTooltipDate
)

export const getSensorsDataTimeFrame = createSelector(
  getSensorsDataState,
  fromSensorsData.getTimeFrame
)

export const getSensorsDataTimeInterval = createSelector(
  getSensorsDataState,
  fromSensorsData.getTimeInterval
)

export const getSensorsDataDescriptiveStatistic = createSelector(
  getSensorsDataState,
  fromSensorsData.getDescriptiveStatistic
)

export const getSensorsDataTooltipValues = createSelector(
  getSensorsDataIds,
  getSensorsDataEntities,
  getSourcesDataEntities,
  getSensorsDataTooltipDate,
  (
    ids: string[],
    sensorsDataEntities: Dictionary<SensorsData>,
    sourcesDataEntities: Dictionary<SourceData>,
    date
  ) => {
    if (!date) {
      return []
    }

    return ids
      .filter(
        id =>
          sensorsDataEntities[id] &&
          sensorsDataEntities[id].data &&
          sensorsDataEntities[id].chart &&
          sourcesDataEntities[id] &&
          sourcesDataEntities[id].visible
      )
      .reduce((acc, id) => {
        const sensorData = sensorsDataEntities[id] || null
        const index = sensorData.data.findIndex(
          d => d.date.getTime() === date.getTime()
        )
        const value = index > -1 ? sensorData.data[index].value : null

        return [
          ...acc,
          {
            id: id,
            label: sensorData.label || null,
            dataType: sensorData.chart.dataType || null,
            keys: sensorData.keys || null,
            value
          }
        ]
      }, [])
  }
)
{'fraction_non_alphanumeric': 0.09493454752418896, 'fraction_numerical': 0.0004553215708594195, 'mean_word_length': 3.6808737346830047, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4415912', 'n_tokens_mistral': 2495, 'n_tokens_neox': 2530, 'n_words': 502}