{"version":3,"sources":["../../../packages/core/base/data-store/data-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;GAMG;AACH,8BAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,CAAE,YAAW,UAAU;IAErE;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAElD;;OAEG;IACH,SAAS,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAE5C;;OAEG;IACH,SAAgB,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,kBAAkB,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE7C;;OAEG;IACH,SAAgB,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,SAAS,CAAC,kBAAkB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC;IAErD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC;IAE/D;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC;IAEhD;;OAEG;;IAWH;;;;;;;OAOG;IACH,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,QAAyB,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,GAAE,MAA2B,GAAG,OAAO,CAAC,GAAG,CAAC;IASjI;;OAEG;IACI,OAAO,IAAI,IAAI;IAItB;;OAEG;IACI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC;IAM/B;;OAEG;IACI,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC;IASzC;;OAEG;IACI,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC;IAQhC;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,GAAG,WAAW;IAIpD;;OAEG;IACH,SAAS,CAAC,kBAAkB,CAAC,UAAU,EAAE,WAAW,GAAG,KAAK;CAG/D","file":"data-store.d.ts","sourcesContent":["import { Observable, Subject } from 'rxjs';\r\nimport { map, tap } from 'rxjs/operators';\r\nimport { Disposable } from '../../data/disposable';\r\nimport { LogLevel } from '../../diagnostics/log-level';\r\nimport { Logging } from '../../diagnostics/logging';\r\nimport { RxjsLifetimeManager } from '../rxjs-lifetime-manager';\r\n\r\n/**\r\n * Defines a base class for interchangeable single value data stores\r\n * This class is intended to be an abstraction from getting, setting, and clearing a value from a data source.\r\n * Unlike a \"database\" the idea here is that the store is concerned with a single value from an underlying storage mechanism.\r\n * This mechanism could a database, a REST API, browser storage, even a variable in memory. The point is to abstract the storage\r\n * implementation away from the management of the value\r\n */\r\nexport abstract class DataStore<TData, TStoredData> implements Disposable {\r\n\r\n    /**\r\n     * The source name to use for logging\r\n     */\r\n    protected abstract readonly logSourceName: string;\r\n\r\n    /**\r\n     * Container for active subscriptions that should be cleaned up in the OnDestroy call.\r\n     */\r\n    protected rxjsLifetime: RxjsLifetimeManager;\r\n\r\n    /**\r\n     * Observable that emits whenever the data has changed\r\n     */\r\n    public readonly dataChanged: Observable<TData>;\r\n\r\n    /**\r\n     * Backing subject for dataChanged property\r\n     */\r\n    protected dataChangedSubject: Subject<TData>;\r\n\r\n    /**\r\n     * Observable that emits whenever the data has been cleared\r\n     */\r\n    public readonly dataCleared: Observable<void>;\r\n\r\n    /**\r\n     * Backing subject for dataCleared property\r\n     */\r\n    protected dataClearedSubject: Subject<void>;\r\n\r\n    /**\r\n     * Implementation to get the stored data\r\n     * Called when the consumer wants to retrieve a value from the store.\r\n     * The result of this method will be processed through the transformFromStore\r\n     * method before giving the value to the consumer\r\n     */\r\n    protected abstract getData(): Observable<TStoredData>;\r\n\r\n    /**\r\n     * Implementation to set the stored data\r\n     * Called when the consumer wants to assign a value to the store.\r\n     * It is called after processing the value through the transformToStore method\r\n     */\r\n    protected abstract setData(data: TStoredData): Observable<void>;\r\n\r\n    /**\r\n     * Implementation to clear the stored data.\r\n     * Called when the consumer wants to remove or destroy the data.\r\n     * This may have slightly different meaning in different contexts,\r\n     * but is generally different than simply setting the value to null (although that may be effectively the same in some scenarios)\r\n     * dataCleared will be emitted immediately after this method is executed\r\n     */\r\n    protected abstract clearData(): Observable<void>;\r\n\r\n    /**\r\n     * Initializes a new instance of DataStore<T>\r\n     */\r\n    constructor() {\r\n        this.dataChangedSubject = new Subject<TData>();\r\n        this.dataChanged = this.dataChangedSubject.asObservable();\r\n        this.dataClearedSubject = new Subject<void>();\r\n        this.dataCleared = this.dataClearedSubject.asObservable();\r\n\r\n        this.rxjsLifetime = new RxjsLifetimeManager();\r\n        this.rxjsLifetime.addSubjects(this.dataChangedSubject, this.dataClearedSubject);\r\n    }\r\n\r\n    /**\r\n     * Shortcut to log a record. The source name is automatically picked up from the class instance\r\n     * @param message the message of the log record\r\n     * @param level (optional) the log level (defaults to Debug)\r\n     * @param params (optional) the parameters to log\r\n     * @param source (optional) the source of the log message. Defaults to the name of the constructor that instantiated this instance\r\n     * @return Promise<any> settle to resolve if buffered.\r\n     */\r\n    protected log(message: string, level: LogLevel = LogLevel.Debug, params?: any, source: string = this.logSourceName): Promise<any> {\r\n        return Logging.log({\r\n            level: level,\r\n            message: message,\r\n            localParams: params,\r\n            source: source\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Disposes this data store, freeing any resources consumed by this instance\r\n     */\r\n    public dispose(): void {\r\n        this.rxjsLifetime.dispose();\r\n    }\r\n\r\n    /**\r\n     * Gets the data value from the data store\r\n     */\r\n    public get(): Observable<TData> {\r\n        return this.getData().pipe(\r\n            map(storedData => this.transformFromStore(storedData))\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Sets the data value in the data store\r\n     */\r\n    public set(data: TData): Observable<void> {\r\n        const storedData = this.transformToStore(data);\r\n        return this.setData(storedData).pipe(\r\n            tap(() => {\r\n                this.dataChangedSubject.next(data);\r\n            })\r\n        );\r\n    }\r\n\r\n    /**\r\n     * clears the data value, effectively removing the value from the backing storage mechanism\r\n     */\r\n    public clear(): Observable<void> {\r\n        return this.clearData().pipe(\r\n            tap(() => {\r\n                this.dataClearedSubject.next();\r\n            })\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Transforms data in preparation for storage. Default behavior is no operation\r\n     */\r\n    protected transformToStore(data: TData): TStoredData {\r\n        return <any>data;\r\n    }\r\n\r\n    /**\r\n     * Transforms data in preparation for usage. Default behavior is no operation\r\n     */\r\n    protected transformFromStore(storedData: TStoredData): TData {\r\n        return <any>storedData;\r\n    }\r\n}\r\n"]}