Skip to content

Commit e8bc95f

Browse files
author
Robert Jackson
committed
Simplify TransitionState resolution system.
1 parent bb16c56 commit e8bc95f

File tree

5 files changed

+47
-62
lines changed

5 files changed

+47
-62
lines changed

lib/router/route-info.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface Route {
4040
buildRouteInfoMetadata?(): unknown;
4141
}
4242

43-
export type Continuation = () => PromiseLike<boolean> | boolean;
43+
export type Continuation = () => boolean;
4444

4545
export interface RouteInfo {
4646
readonly name: string;
@@ -376,11 +376,9 @@ export default class InternalRouteInfo<T extends Route> {
376376
}
377377

378378
private checkForAbort<T>(shouldContinue: Continuation, value: T) {
379-
return Promise.resolve(shouldContinue()).then(function () {
380-
// We don't care about shouldContinue's resolve value;
381-
// pass along the original value passed to this fn.
382-
return value;
383-
}, null);
379+
shouldContinue();
380+
381+
return value;
384382
}
385383

386384
private stashResolvedModel(transition: InternalTransition<T>, resolvedModel: Dict<unknown>) {

lib/router/transition-state.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Promise } from 'rsvp';
22
import { Dict } from './core';
3-
import InternalRouteInfo, { Continuation, Route } from './route-info';
3+
import InternalRouteInfo, { Continuation, Route, ResolvedRouteInfo } from './route-info';
44
import Transition from './transition';
55
import { forEach, promiseLabel } from './utils';
66

@@ -42,40 +42,41 @@ export default class TransitionState<T extends Route> {
4242
// The prelude RSVP.resolve() asyncs us into the promise land.
4343
return Promise.resolve(null, this.promiseLabel('Start transition'))
4444
.then(resolveOneRouteInfo, null, this.promiseLabel('Resolve route'))
45-
.catch(handleError, this.promiseLabel('Handle error'));
45+
.catch(handleError, this.promiseLabel('Handle error'))
46+
.then(() => {
47+
return currentState;
48+
});
4649

4750
function innerShouldContinue() {
48-
return Promise.resolve(
49-
shouldContinue(),
50-
currentState.promiseLabel('Check if should continue')
51-
).catch(function (reason) {
51+
if (shouldContinue()) {
52+
return true;
53+
} else {
5254
// We distinguish between errors that occurred
5355
// during resolution (e.g. before"Model/model/afterModel),
5456
// and aborts due to a rejecting promise from shouldContinue().
5557
wasAborted = true;
56-
return Promise.reject(reason);
57-
}, currentState.promiseLabel('Handle abort'));
58+
throw new Error('Transition aborted');
59+
}
5860
}
5961

60-
function handleError(error: Error) {
62+
function handleError(error: Error): never {
6163
// This is the only possible
6264
// reject value of TransitionState#resolve
6365
let routeInfos = currentState.routeInfos;
6466
let errorHandlerIndex =
6567
transition.resolveIndex >= routeInfos.length
6668
? routeInfos.length - 1
6769
: transition.resolveIndex;
68-
return Promise.reject(
69-
new TransitionError(
70-
error,
71-
currentState.routeInfos[errorHandlerIndex].route!,
72-
wasAborted,
73-
currentState
74-
)
70+
71+
throw new TransitionError(
72+
error,
73+
currentState.routeInfos[errorHandlerIndex].route!,
74+
wasAborted,
75+
currentState
7576
);
7677
}
7778

78-
function proceed(resolvedRouteInfo: InternalRouteInfo<T>): Promise<InternalRouteInfo<T>> {
79+
function proceed(resolvedRouteInfo: ResolvedRouteInfo<T>): void | Promise<void> {
7980
let wasAlreadyResolved = currentState.routeInfos[transition.resolveIndex].isResolved;
8081

8182
// Swap the previously unresolved routeInfo with
@@ -97,18 +98,16 @@ export default class TransitionState<T extends Route> {
9798

9899
// Proceed after ensuring that the redirect hook
99100
// didn't abort this transition by transitioning elsewhere.
100-
return innerShouldContinue().then(
101-
resolveOneRouteInfo,
102-
null,
103-
currentState.promiseLabel('Resolve route')
104-
);
101+
if (innerShouldContinue()) {
102+
return resolveOneRouteInfo();
103+
}
105104
}
106105

107-
function resolveOneRouteInfo(): TransitionState<T> | Promise<any> {
106+
function resolveOneRouteInfo(): void | Promise<void> {
108107
if (transition.resolveIndex === currentState.routeInfos.length) {
109108
// This is is the only possible
110109
// fulfill value of TransitionState#resolve
111-
return currentState;
110+
return;
112111
}
113112

114113
let routeInfo = currentState.routeInfos[transition.resolveIndex];

lib/router/transition.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,7 @@ export default class Transition<T extends Route> implements Partial<Promise<T>>
170170

171171
this.sequence = router.currentSequence++;
172172
this.promise = state
173-
.resolve(() => {
174-
if (this.isAborted) {
175-
return Promise.reject(false, promiseLabel('Transition aborted - reject'));
176-
}
177-
178-
return Promise.resolve(true);
179-
}, this)
173+
.resolve(() => !this.isAborted, this)
180174
.catch((result: TransitionError) => {
181175
return Promise.reject(this.router.transitionDidError(result, this));
182176
}, promiseLabel('Handle Abort'));

tests/route_info_test.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@ import RouteInfo, {
99
} from 'router/route-info';
1010
import InternalTransition from 'router/transition';
1111
import URLTransitionIntent from 'router/transition-intent/url-transition-intent';
12-
import { reject, resolve } from 'rsvp';
12+
import { resolve } from 'rsvp';
1313
import { createHandler, createHandlerInfo, module, test, TestRouter } from './test_helpers';
1414

15-
function noop() {
16-
return resolve(true);
17-
}
18-
1915
module('RouteInfo');
2016

2117
test('ResolvedRouteInfo resolve to themselves', function (assert) {
@@ -43,9 +39,10 @@ test('RouteInfo can be aborted mid-resolve', function (assert) {
4339

4440
let routeInfo = createHandlerInfo('stub');
4541

46-
function abortResolve() {
42+
function abortResolve(): boolean {
4743
assert.ok(true, 'abort was called');
48-
return reject('LOL');
44+
45+
throw new Error('foo');
4946
}
5047

5148
routeInfo.resolve(abortResolve, {} as Transition).catch(function (error: Error) {
@@ -81,7 +78,7 @@ test('RouteInfo#resolve runs beforeModel hook on handler', function (assert) {
8178
}),
8279
});
8380

84-
routeInfo.resolve(noop, transition as Transition);
81+
routeInfo.resolve(() => true, transition as Transition);
8582
});
8683

8784
test('RouteInfo#resolve runs getModel hook', function (assert) {
@@ -95,7 +92,7 @@ test('RouteInfo#resolve runs getModel hook', function (assert) {
9592
},
9693
});
9794

98-
routeInfo.resolve(noop, transition as Transition);
95+
routeInfo.resolve(() => true, transition as Transition);
9996
});
10097

10198
test('RouteInfo#resolve runs afterModel hook on handler', function (assert) {
@@ -118,7 +115,7 @@ test('RouteInfo#resolve runs afterModel hook on handler', function (assert) {
118115
});
119116

120117
routeInfo
121-
.resolve(noop, transition as Transition)
118+
.resolve(() => true, transition as Transition)
122119
.then(function (resolvedRouteInfo: RouteInfo<Route>) {
123120
assert.equal(resolvedRouteInfo.context, model, 'RouteInfo resolved with correct model');
124121
});
@@ -146,7 +143,7 @@ test('UnresolvedRouteInfoByParam gets its model hook called', function (assert)
146143
})
147144
);
148145

149-
routeInfo.resolve(noop, transition as Transition);
146+
routeInfo.resolve(() => true, transition as Transition);
150147
});
151148

152149
test('UnresolvedRouteInfoByObject does NOT get its model hook called', function (assert) {
@@ -166,10 +163,12 @@ test('UnresolvedRouteInfoByObject does NOT get its model hook called', function
166163
resolve({ name: 'dorkletons' })
167164
);
168165

169-
routeInfo.resolve(noop, {} as Transition).then(function (resolvedRouteInfo: RouteInfo<Route>) {
170-
// @ts-ignore
171-
assert.equal(resolvedRouteInfo.context!.name, 'dorkletons');
172-
});
166+
routeInfo
167+
.resolve(() => true, {} as Transition)
168+
.then(function (resolvedRouteInfo: RouteInfo<Route>) {
169+
// @ts-ignore
170+
assert.equal(resolvedRouteInfo.context!.name, 'dorkletons');
171+
});
173172
});
174173

175174
test('RouteInfo.find', function (assert) {

tests/transition_state_test.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
UnresolvedRouteInfoByParam,
88
} from 'router/route-info';
99
import TransitionState, { TransitionError } from 'router/transition-state';
10-
import { Promise, reject, resolve } from 'rsvp';
10+
import { Promise, resolve } from 'rsvp';
1111
import {
1212
createHandler,
1313
createHandlerInfo,
@@ -54,7 +54,7 @@ test("#resolve delegates to handleInfo objects' resolve()", function (assert) {
5454

5555
function keepGoing() {
5656
assert.ok(true, 'continuation function was called');
57-
return Promise.resolve(false);
57+
return true;
5858
}
5959

6060
state.resolve(keepGoing, {} as Transition).then(function (result: TransitionState<Route>) {
@@ -63,7 +63,7 @@ test("#resolve delegates to handleInfo objects' resolve()", function (assert) {
6363
});
6464

6565
test('State resolution can be halted', function (assert) {
66-
assert.expect(2);
66+
assert.expect(1);
6767

6868
let state = new TransitionState();
6969

@@ -81,11 +81,10 @@ test('State resolution can be halted', function (assert) {
8181
];
8282

8383
function keepGoing() {
84-
return reject('NOPE');
84+
return false;
8585
}
8686

8787
state.resolve(keepGoing, {} as Transition).catch(function (reason: TransitionError) {
88-
assert.equal(reason.error, 'NOPE');
8988
assert.ok(reason.wasAborted, 'state resolution was correctly marked as aborted');
9089
});
9190

@@ -118,12 +117,8 @@ test('Integration w/ HandlerInfos', function (assert) {
118117
new UnresolvedRouteInfoByObject(router, 'bar', ['bar_id'], resolve(barModel)),
119118
];
120119

121-
function noop() {
122-
return Promise.resolve(false);
123-
}
124-
125120
state
126-
.resolve(noop, transition as Transition)
121+
.resolve(() => true, transition as Transition)
127122
.then(function (result: TransitionState<Route>) {
128123
let models = [];
129124
for (let i = 0; i < result.routeInfos.length; i++) {

0 commit comments

Comments
 (0)