boring-router
Advanced tools
Comparing version 0.3.0-alpha.9 to 0.3.0-alpha.10
@@ -5,1 +5,2 @@ import { Location } from 'history'; | ||
export declare function isLocationEqual(left: Location, right: Location): boolean; | ||
export declare function isShallowlyEqual(left: any, right: any): boolean; |
@@ -19,2 +19,15 @@ "use strict"; | ||
exports.isLocationEqual = isLocationEqual; | ||
function isShallowlyEqual(left, right) { | ||
if (left === right) { | ||
return true; | ||
} | ||
let keySet = new Set([...Object.keys(left), ...Object.keys(right)]); | ||
for (let key of keySet) { | ||
if (left[key] !== right[key]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
exports.isShallowlyEqual = isShallowlyEqual; | ||
//# sourceMappingURL=@utils.js.map |
@@ -10,4 +10,10 @@ import { History } from 'history'; | ||
*/ | ||
export declare type RouteBeforeEnter<TRouteMatch extends RouteMatch = RouteMatch> = (next: NextRouteMatchType<TRouteMatch>) => Promise<string | boolean | void> | string | boolean | void; | ||
export declare type RouteBeforeEnter<TRouteMatch extends RouteMatch = RouteMatch> = (next: NextRouteMatchType<TRouteMatch>) => Promise<boolean | void> | boolean | void; | ||
/** | ||
* Route before update callback. | ||
* @return Return `true` or `undefined` to do nothing; return `false` to revert | ||
* this history change; return full path to redirect. | ||
*/ | ||
export declare type RouteBeforeUpdate<TRouteMatch extends RouteMatch = RouteMatch> = (next: NextRouteMatchType<TRouteMatch>) => Promise<boolean | void> | boolean | void; | ||
/** | ||
* Route before leave callback. | ||
@@ -19,2 +25,3 @@ * @return Return `true` or `undefined` to do nothing; return `false` to revert | ||
export declare type RouteAfterEnter = () => Promise<void> | void; | ||
export declare type RouteAfterUpdate = () => Promise<void> | void; | ||
export declare type RouteAfterLeave = () => Promise<void> | void; | ||
@@ -25,2 +32,4 @@ export declare type RouteServiceFactory<TRouteMatch extends RouteMatch> = (match: TRouteMatch) => IRouteService<TRouteMatch> | Promise<IRouteService<TRouteMatch>>; | ||
afterEnter?: RouteAfterEnter; | ||
beforeUpdate?: RouteBeforeUpdate<TRouteMatch>; | ||
afterUpdate?: RouteAfterUpdate; | ||
beforeLeave?: RouteBeforeLeave; | ||
@@ -27,0 +36,0 @@ afterLeave?: RouteAfterLeave; |
@@ -156,2 +156,4 @@ "use strict"; | ||
/** @internal */ | ||
this._beforeUpdateCallbacks = []; | ||
/** @internal */ | ||
this._beforeLeaveCallbacks = []; | ||
@@ -161,2 +163,4 @@ /** @internal */ | ||
/** @internal */ | ||
this._afterUpdateCallbacks = []; | ||
/** @internal */ | ||
this._afterLeaveCallbacks = []; | ||
@@ -293,4 +297,4 @@ /** @internal */ | ||
let result = yield callback(next); | ||
if (typeof result === 'string' || result === false) { | ||
return result; | ||
if (result === false) { | ||
return false; | ||
} | ||
@@ -303,4 +307,4 @@ } | ||
let result = yield service.beforeEnter(next); | ||
if (typeof result === 'string' || result === false) { | ||
return result; | ||
if (result === false) { | ||
return false; | ||
} | ||
@@ -311,2 +315,23 @@ return true; | ||
/** @internal */ | ||
_beforeUpdate() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
let next = this._next; | ||
for (let callback of this._beforeUpdateCallbacks) { | ||
let result = yield callback(next); | ||
if (result === false) { | ||
return false; | ||
} | ||
} | ||
let service = yield this._getService(); | ||
if (!service || !service.beforeUpdate) { | ||
return true; | ||
} | ||
let result = yield service.beforeUpdate(next); | ||
if (result === false) { | ||
return false; | ||
} | ||
return true; | ||
}); | ||
} | ||
/** @internal */ | ||
_afterLeave() { | ||
@@ -342,2 +367,17 @@ return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
/** @internal */ | ||
_afterUpdate() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
for (let callback of this._afterUpdateCallbacks) { | ||
yield callback(); | ||
} | ||
let service = yield this._getService(); | ||
if (!service) { | ||
return; | ||
} | ||
if (service.afterUpdate) { | ||
yield service.afterUpdate(); | ||
} | ||
}); | ||
} | ||
/** @internal */ | ||
_update(matched, exactlyMatched) { | ||
@@ -344,0 +384,0 @@ this._matched = matched; |
@@ -26,2 +26,3 @@ "use strict"; | ||
this._onLocationChange = (location) => { | ||
this._nextLocation = location; | ||
this._changing = this._changing | ||
@@ -33,4 +34,6 @@ .then(() => this._asyncOnLocationChange(location)) | ||
this._asyncOnLocationChange = (nextLocation) => tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
if (this._isNextLocationOutDated(nextLocation)) { | ||
return; | ||
} | ||
let { pathname, search } = nextLocation; | ||
let history = this._history; | ||
let location = this._location; | ||
@@ -52,3 +55,4 @@ if (location && _utils_1.isLocationEqual(location, nextLocation)) { | ||
// Prepare previous/next match set | ||
let previousMatchSet = new Set(this._source.matchToMatchEntryMap.keys()); | ||
let previousMatchToMatchEntryMap = this._source.matchToMatchEntryMap; | ||
let previousMatchSet = new Set(previousMatchToMatchEntryMap.keys()); | ||
let nextMatchSet = new Set(matchToMatchEntryMap.keys()); | ||
@@ -60,5 +64,10 @@ let leavingMatchSet = new Set(previousMatchSet); | ||
let reversedLeavingMatches = Array.from(leavingMatchSet).reverse(); | ||
let enteringMatchSet = new Set(nextMatchSet); | ||
let enteringAndUpdatingMatchSet = new Set(nextMatchSet); | ||
for (let match of previousMatchSet) { | ||
enteringMatchSet.delete(match); | ||
if (!enteringAndUpdatingMatchSet.has(match)) { | ||
continue; | ||
} | ||
if (_utils_1.isShallowlyEqual(match._pathFragments, match._next._pathFragments)) { | ||
enteringAndUpdatingMatchSet.delete(match); | ||
} | ||
} | ||
@@ -68,2 +77,5 @@ // Process before hooks | ||
let result = yield match._beforeLeave(); | ||
if (this._isNextLocationOutDated(nextLocation)) { | ||
return; | ||
} | ||
if (!result) { | ||
@@ -74,6 +86,8 @@ this._revert(); | ||
} | ||
for (let match of enteringMatchSet) { | ||
let result = yield match._beforeEnter(); | ||
if (typeof result === 'string') { | ||
history.replace(result); | ||
for (let match of enteringAndUpdatingMatchSet) { | ||
let update = previousMatchSet.has(match); | ||
let result = update | ||
? yield match._beforeUpdate() | ||
: yield match._beforeEnter(); | ||
if (this._isNextLocationOutDated(nextLocation)) { | ||
return; | ||
@@ -100,4 +114,10 @@ } | ||
} | ||
for (let match of enteringMatchSet) { | ||
yield match._afterEnter(); | ||
for (let match of enteringAndUpdatingMatchSet) { | ||
let update = previousMatchSet.has(match); | ||
if (update) { | ||
yield match._afterUpdate(); | ||
} | ||
else { | ||
yield match._afterEnter(); | ||
} | ||
} | ||
@@ -116,2 +136,6 @@ }); | ||
/** @internal */ | ||
_isNextLocationOutDated(location) { | ||
return location !== this._nextLocation; | ||
} | ||
/** @internal */ | ||
_revert() { | ||
@@ -118,0 +142,0 @@ this._history.replace(this._location || this._default); |
{ | ||
"name": "boring-router", | ||
"version": "0.3.0-alpha.9", | ||
"version": "0.3.0-alpha.10", | ||
"description": "A light-weight, type-safe, yet reactive router service using MobX.", | ||
@@ -5,0 +5,0 @@ "repository": { |
50515
1035