Skip to content

Commit

Permalink
fix(TransitionHook): Transition hooks no longer expose the internal S…
Browse files Browse the repository at this point in the history
…tateObject

BREAKING CHANGE: Transition hooks no longer expose the internal `State` object (now named `StateObject`)

- #### Before:

```js
import { State } from "ui-router-core";
const match = { to: (state: State) => state.data.auth };
transitionsvc.onEnter(match, (trans: Transition, state: State) => {
  // state is the internal State object
  if (state.includes["foo"]) { // internal ui-router API
    return false;
  }
}
```

- #### Now:

```js
import { StateDeclaration } from "ui-router-core";
const match = { to: (state: StateDeclaration) => state.data.auth };
transitionsvc.onEnter(match, (trans: Transition, state: StateDeclaration) => {
  // state === the state object you registered
  // Access internal ui-router API using $$state()
  if (state.$$state().includes["foo"]) {
    return false;
  }
}
```

- #### Motivation:

The `State` object (now named `StateObject`) is an internal API and should not be exposed via any public APIs.
If you depend on the internal APIs, you can still access the internal object by calling `state.$$state()`.

- #### BC Likelihood

How likely is this BC to affect me?

Medium: You will likely be affected you 1) have transition hooks, 2) are using typescript and/or 3) use the internal ui-router State API.

- #### BC Severity

How severe is this BC?

Low: Access to the internal api is still available using `$$state()`.
  • Loading branch information
christopherthielen committed Feb 23, 2017
1 parent 3a5d055 commit 2b0e48b
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 115 deletions.
4 changes: 2 additions & 2 deletions src/hooks/onEnterExitRetain.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @module hooks */ /** for typedoc */
import {TransitionStateHookFn} from "../transition/interface";
import {StateObject} from "../state/stateObject";
import {Transition} from "../transition/transition";
import {TransitionService} from "../transition/transitionService";
import { StateDeclaration } from '../state/interface';

/**
* A factory which creates an onEnter, onExit or onRetain transition hook function
Expand All @@ -13,7 +13,7 @@ import {TransitionService} from "../transition/transitionService";
* @hidden
*/
function makeEnterExitRetainHook(hookName: string): TransitionStateHookFn {
return (transition: Transition, state: StateObject) => {
return (transition: Transition, state: StateDeclaration) => {
let hookFn: TransitionStateHookFn = state[hookName];
return hookFn(transition, state);
}
Expand Down
21 changes: 11 additions & 10 deletions src/hooks/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/** @module hooks */ /** for typedoc */
import {noop} from "../common/common";
import {Transition} from "../transition/transition";
import {StateObject} from "../state/stateObject";
import {ResolveContext} from "../resolve/resolveContext";
import {TransitionStateHookFn, TransitionHookFn} from "../transition/interface";
import {TransitionService} from "../transition/transitionService";
import {val} from "../common/hof";
/** @module hooks */
/** for typedoc */
import { noop } from '../common/common';
import { Transition } from '../transition/transition';
import { ResolveContext } from '../resolve/resolveContext';
import { TransitionStateHookFn, TransitionHookFn } from '../transition/interface';
import { TransitionService } from '../transition/transitionService';
import { val } from '../common/hof';
import { StateDeclaration } from '../state/interface';

/**
* A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path
Expand Down Expand Up @@ -33,9 +34,9 @@ export const registerEagerResolvePath = (transitionService: TransitionService) =
*
* See [[StateDeclaration.resolve]]
*/
const lazyResolveState: TransitionStateHookFn = (trans: Transition, state: StateObject) =>
const lazyResolveState: TransitionStateHookFn = (trans: Transition, state: StateDeclaration) =>
new ResolveContext(trans.treeChanges().to)
.subContext(state)
.subContext(state.$$state())
.resolvePath("LAZY", trans)
.then(noop);

Expand Down
2 changes: 1 addition & 1 deletion src/transition/hookBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class HookBuilder {
traceData: { hookType: hookType.name, context: node }
}, baseHookOptions);

let state = hookType.criteriaMatchPath.scope === TransitionHookScope.STATE ? node.state : null;
let state = hookType.criteriaMatchPath.scope === TransitionHookScope.STATE ? node.state.self : null;
let transitionHook = new TransitionHook(transition, state, hook, _options);
return <HookTuple> { hook, node, transitionHook };
});
Expand Down
7 changes: 4 additions & 3 deletions src/transition/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export interface TransitionHookFn {
* - [[IHookRegistry.onEnter]]
*/
export interface TransitionStateHookFn {
(transition: Transition, state: StateObject) : HookResult
(transition: Transition, state: StateDeclaration) : HookResult
}

/**
Expand Down Expand Up @@ -700,8 +700,9 @@ export interface IHookRegistry {
_registeredHooks: { [key: string]: RegisteredHook[] }
}

/** A predicate type which takes a [[StateObject]] and returns a boolean */
export type IStateMatch = Predicate<StateObject>
/** A predicate type which tests if a [[StateDeclaration]] passes some test. Returns a boolean. */
export type IStateMatch = Predicate<StateDeclaration>

/**
* This object is used to configure whether or not a Transition Hook is invoked for a particular transition,
* based on the Transition's "to state" and "from state".
Expand Down
6 changes: 3 additions & 3 deletions src/transition/transitionHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { services } from '../common/coreservices';
import { Rejection } from './rejectFactory';
import { TargetState } from '../state/targetState';
import { Transition } from './transition';
import { StateObject } from '../state/stateObject';
import { TransitionEventType } from './transitionEventType';
import { RegisteredHook } from './hookRegistry'; // has or is using
import { RegisteredHook } from './hookRegistry';
import { StateDeclaration } from '../state/interface'; // has or is using

let defaultOptions: TransitionHookOptions = {
current: noop,
Expand All @@ -34,7 +34,7 @@ export type ErrorHandler = (error) => Promise<any>;
export class TransitionHook {
type: TransitionEventType;
constructor(private transition: Transition,
private stateContext: StateObject,
private stateContext: StateDeclaration,
private registeredHook: RegisteredHook,
private options: TransitionHookOptions) {
this.options = defaults(options, defaultOptions);
Expand Down
Loading

0 comments on commit 2b0e48b

Please sign in to comment.