Create wt-odlux directory
[ccsdk/features.git] / sdnr / wt-odlux / odlux / framework / src / flux / store.ts
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 import { Event } from "../common/event"
19
20 import { Action } from './action';
21 import { IActionHandler } from './action';
22
23 const LogLevel = +(localStorage.getItem('log.odlux.framework.flux.store') || 0);
24
25 export interface Dispatch {
26   <TAction extends Action>(action: TAction): TAction;
27 }
28
29 export interface Enhancer<TStoreState> {
30   (store: Store<TStoreState>): Dispatch;
31 }
32
33 class InitializationAction extends Action { };
34 const initializationAction = new InitializationAction();
35
36 export class Store<TStoreState> {
37
38   constructor(actionHandler: IActionHandler<TStoreState>, enhancer?: Enhancer<TStoreState>)
39   constructor(actionHandler: IActionHandler<TStoreState>, initialState: TStoreState, enhancer?: Enhancer<TStoreState>)
40   constructor(actionHandler: IActionHandler<TStoreState>, initialState?: TStoreState | Enhancer<TStoreState>, enhancer?: Enhancer<TStoreState>) {
41     if (typeof initialState === 'function') {
42       enhancer = initialState as Enhancer<TStoreState>;
43       initialState = undefined;
44     }
45
46     this._isDispatching = false;
47      
48     this.changed = new Event<void>();
49
50     this._actionHandler = actionHandler;
51     
52     this._state = initialState as TStoreState;
53     if (enhancer) this._dispatch = enhancer(this);
54
55     this._dispatch(initializationAction);
56   }
57
58   public changed: Event<void>;
59
60   private _dispatch: Dispatch = <TAction extends Action>(payload: TAction): TAction => {
61     if (LogLevel > 2) {
62       console.log('Store::Dispatch - ', payload);
63     }
64     if (payload == null || !(payload instanceof Action)) {
65       throw new Error(
66         'Actions must inherit from type Action. ' +
67         'Use a custom middleware for async actions.'
68       );
69     }
70     
71     if (this._isDispatching) {
72       throw new Error('ActionHandler may not dispatch actions.');
73     }
74
75     const oldState = this._state;
76     try {
77       this._isDispatching = true;
78       this._state = this._actionHandler(oldState, payload);
79     } finally {
80       this._isDispatching = false;
81     }
82
83     if (this._state !== oldState) {
84       if (LogLevel > 3) {
85         console.log('Store::Dispatch - state has changed', this._state);
86       }
87       this.changed.invoke();
88     }
89
90     return payload;
91   }
92
93   public get dispatch(): Dispatch {
94     return this._dispatch;
95   }
96
97   public get state() {
98     return this._state
99   }
100
101   private _state: TStoreState;
102   private _isDispatching: boolean;
103   private _actionHandler: IActionHandler<TStoreState>;
104
105 }
106