@dharmax/state-router 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,14 +7,17 @@ export type ApplicationState = {
7
7
  route: RegExp;
8
8
  mode?: string | string[];
9
9
  };
10
+ export type ChangeAuthority = (state: ApplicationState) => Promise<boolean>;
10
11
  export declare class StateManager {
11
12
  private allStates;
12
13
  private appState;
13
14
  private previousState;
14
15
  private stateContext;
15
- static dispatcher: import("@dharmax/pubsub").Pubsub;
16
+ static dispatcher: import("@dharmax/pubsub").PubSub;
17
+ private changeAuthorities;
16
18
  constructor(mode?: RoutingMode);
17
19
  onChange(handler: (event: PubSubEvent, data: any) => void): IPubSubHandle;
20
+ registerChangeAuthority(authorityCallback: (targetState: ApplicationState) => Promise<boolean>): void;
18
21
  getState(): ApplicationState;
19
22
  get previous(): ApplicationState;
20
23
  get context(): ApplicationState;
@@ -23,14 +26,14 @@ export declare class StateManager {
23
26
  * @param state can be either just a state or a state and context (which can be sub-state, or anything else)
24
27
  */
25
28
  set state(state: ApplicationStateName | [ApplicationStateName, any]);
26
- /** attempts to restore state from current url */
29
+ /** attempts to restore state from current url. Currently, works only in hash mode */
27
30
  restoreState(defaultState: ApplicationStateName): void;
28
31
  /**
29
32
  *
30
33
  * @param stateName state
31
34
  * @param context extra context (e.g. sub-state)
32
35
  */
33
- setState(stateName: ApplicationStateName, context?: any): boolean;
36
+ setState(stateName: ApplicationStateName, context?: any): Promise<boolean>;
34
37
  /**
35
38
  * Define an application state
36
39
  * @param name
@@ -6,6 +6,7 @@ export class StateManager {
6
6
  previousState;
7
7
  stateContext;
8
8
  static dispatcher = dispatcher;
9
+ changeAuthorities = [];
9
10
  constructor(mode = 'hash') {
10
11
  router.mode = mode;
11
12
  router.listen();
@@ -13,6 +14,14 @@ export class StateManager {
13
14
  onChange(handler) {
14
15
  return StateManager.dispatcher.on('state:changed', handler);
15
16
  }
17
+ /*
18
+ Add a hook which enable conditional approval of state change. It can be more than one; when a state
19
+ change is requested, all the registered authorities must return true (asynchronously) otherwise the change
20
+ requested doesn't happen.
21
+ **/
22
+ registerChangeAuthority(authorityCallback) {
23
+ this.changeAuthorities.push(authorityCallback);
24
+ }
16
25
  getState() {
17
26
  return this.appState || {};
18
27
  }
@@ -32,7 +41,7 @@ export class StateManager {
32
41
  else
33
42
  this.setState(state);
34
43
  }
35
- /** attempts to restore state from current url */
44
+ /** attempts to restore state from current url. Currently, works only in hash mode */
36
45
  restoreState(defaultState) {
37
46
  let dest = window.location.hash;
38
47
  if (dest == '#login' || dest == '')
@@ -44,12 +53,17 @@ export class StateManager {
44
53
  * @param stateName state
45
54
  * @param context extra context (e.g. sub-state)
46
55
  */
47
- setState(stateName, context) {
56
+ async setState(stateName, context) {
48
57
  const newState = this.allStates[stateName];
49
58
  if (!newState) {
50
59
  alert(`Undefined app state ${stateName}`);
51
60
  return false;
52
61
  }
62
+ // check if the state change was declined by any change authority and if so - don't do it and return false
63
+ const changeConfirmations = await Promise.all(this.changeAuthorities.map(authority => authority(newState)));
64
+ if (changeConfirmations.includes(false))
65
+ return false;
66
+ // perform the change
53
67
  this.previousState = this.appState;
54
68
  this.stateContext = context;
55
69
  this.appState = newState;
@@ -79,8 +93,8 @@ export class StateManager {
79
93
  }
80
94
  registerStateByState(state) {
81
95
  this.allStates[state.name] = state;
82
- router.add(state.route, (context) => {
83
- if (this.setState(state.name, context)) {
96
+ router.add(state.route, async (context) => {
97
+ if (await this.setState(state.name, context)) {
84
98
  // @ts-ignore
85
99
  if (window.ga) {
86
100
  // @ts-ignore
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@dharmax/state-router",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "A cute and tight router and application state controller",
5
- "main": "dist/router.js",
6
- "types": "dist/router.d.ts",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+
7
8
  "scripts": {
8
9
  "test": "echo \"Error: no test specified\" && exit 1",
9
10
  "build": "npx tsc",
@@ -27,6 +28,6 @@
27
28
  "typescript": "^4.9.5"
28
29
  },
29
30
  "dependencies": {
30
- "@dharmax/pubsub": "^1.0.1"
31
+ "@dharmax/pubsub": "^1.1.0"
31
32
  }
32
33
  }