'use strict' ; import type DataEventEmitter from '../DataEventEmitter' ; import type JSON from '../../Core/JSON' ; import type StoreType from './StoreType' ; import DataParser from '../Parsers/DataParser.js' ; import DataTable from '../DataTable.js' ; import U from '../../Core/Utilities.js' ; const { addEvent , fireEvent , merge , pick } = U ; private abstract class DataStore < TEventObject extends DataStore . Event > implements DataEventEmitter < TEventObject > { /**
     * Registry as a record object with store names and their class.
     */ private static readonly registry = { } as Record < string , StoreType > ; /**
     * Regular expression to extract the store name (group 1) from the
     * stringified class type.
     */ private static readonly nameRegExp = ( /^function\s+(\w*?)(?:DataStore)?\s*\(/ ) ; param { DataStore } dataStore return { boolean } public static addStore ( dataStore ) { const name = DataStore . getName ( dataStore ) , registry = DataStore . registry ; if ( typeof name === 'undefined' || registry [ name ] ) { return false ; } registry [ name ] = dataStore ; return true ; } return { Array < string > } public static getAllStoreNames ( ) { return Object . keys ( DataStore . registry ) ; } return { Record < string , DataStoreRegistryType > } public static getAllStores ( ) { return merge ( DataStore . registry ) ; } param { DataStore } dataStore return { string } private static getName ( dataStore ) { return ( dataStore . toString ( ) . match ( DataStore . nameRegExp ) || [ '' , '' ] ) [ 1 ] ; } param { string } name return { DataStoreRegistryType | undefined } public static getStore ( name ) { return DataStore . registry [ name ] ; } param { DataTable } table param { DataStore . Metadata } metadata public constructor ( table = new DataTable ( ) , metadata = { columns : { } } ) { this . table = table ; this . metadata = metadata ; } /**
     * The DataParser responsible for handling converting the provided data to
     * a DataStore.
     */ public abstract readonly parser : DataParser < DataParser . Event > ; /**
     * Metadata to describe the store and the content of columns.
     */ public metadata : DataStore . Metadata ; /**
     * Table managed by this DataStore instance.
     */ public table : DataTable ; param { string } name param { DataStore . MetaColumn } columnMeta public describeColumn ( name , columnMeta ) { const store = this , columns = store . metadata . columns ; columns [ name ] = merge ( columns [ name ] || { } , columnMeta ) ; } param { Record < string , DataStore . MetaColumn > } columns public describeColumns ( columns ) { const store = this , columnNames = Object . keys ( columns ) ; let columnName ; while ( typeof ( columnName = columnNames . pop ( ) ) === 'string' ) { store . describeColumn ( columnName , columns [ columnName ] ) ; } } param { DataStore . Event } e public emit ( e ) { fireEvent ( this , e . type , e ) ; } param { boolean } usePresentationState return { Array < string > } public getColumnOrder ( usePresentationState ? ) { const store = this , metadata = store . metadata , columns = metadata . columns , columnNames = Object . keys ( columns ) , columnOrder = [ ] ; let columnName ; for ( let i = 0 , iEnd = columnNames . length ; i < iEnd ; ++ i ) { columnName = columnNames [ i ] ; columnOrder [ pick ( columns [ columnName ] . index , i ) ] = columnName ; } return columnOrder ; } param { boolean } usePresentationOrder return { { } } protected getColumnsForExport ( usePresentationOrder ? ) { const table = this . table , columnsRecord = table . getColumns ( ) , columnNames = table . getColumnNames ( ) ; const columnOrder = this . getColumnOrder ( usePresentationOrder ) ; if ( columnOrder . length ) { columnNames . sort ( ( a , b ) : number => { if ( columnOrder . indexOf ( a ) < columnOrder . indexOf ( b ) ) { return 1 ; } if ( columnOrder . indexOf ( a ) > columnOrder . indexOf ( b ) ) { return - 1 ; } return 0 ; } ) ; } return ( { columnNames , columnValues : columnNames . map ( ( name ) : DataTable . Column => columnsRecord [ name ] ) } ) ; } emits public load ( ) { fireEvent ( this , 'afterLoad' , { table : this . table } ) ; } param { string } type param { DataEventEmitter . EventCallback } callback return { Function } public on ( type , callback ) { return addEvent ( this , type , callback ) ; } param { Array < string > } columnNames public setColumnOrder ( columnNames ) { const store = this ; for ( let i = 0 , iEnd = columnNames . length ; i < iEnd ; ++ i ) { store . describeColumn ( columnNames [ i ] , { index : i } ) ; } } param { string } name return { DataStore . MetaColumn | undefined } public whatIs ( name ) { return this . metadata . columns [ name ] ; } } namespace DataStore { /**
     * The default event object for a datastore
     */ export interface Event extends DataEventEmitter . Event { readonly table : DataTable ; } /**
     * Object with columns for object.
     */ export interface ColumnsForExportObject { columnNames : Array < string > ; columnValues : Array < DataTable . Column > ; columnHeaderFormatter ? : Function ; } /**
     * Metadata entry containing the name of the column
     * and a metadata object
     */ export interface MetaColumn extends JSON . Object { dataType ? : string ; defaultValue ? : JSON . Primitive ; index ? : number ; title ? : string ; } /**
     * Metadata
     */ export interface Metadata extends JSON . Object { columns : Record < string , MetaColumn > ; } } declare module './StoreType' { interface StoreTypeRegistry { '' : typeof DataStore ; } } export default DataStore ;