diff --git a/packages/router/.size-snapshot.json b/packages/router/.size-snapshot.json index 776d7c4dc..4e3d2f16d 100644 --- a/packages/router/.size-snapshot.json +++ b/packages/router/.size-snapshot.json @@ -1,8 +1,8 @@ { "dist/curi-router.es.js": { - "bundled": 17615, - "minified": 6201, - "gzipped": 2572, + "bundled": 18977, + "minified": 6574, + "gzipped": 2652, "treeshaked": { "rollup": { "code": 23, @@ -14,18 +14,18 @@ } }, "dist/curi-router.js": { - "bundled": 17848, - "minified": 6383, - "gzipped": 2646 + "bundled": 19210, + "minified": 6756, + "gzipped": 2724 }, "dist/curi-router.umd.js": { - "bundled": 30803, - "minified": 8933, - "gzipped": 3763 + "bundled": 32305, + "minified": 9306, + "gzipped": 3839 }, "dist/curi-router.min.js": { - "bundled": 30660, - "minified": 8847, - "gzipped": 3717 + "bundled": 32162, + "minified": 9220, + "gzipped": 3793 } } diff --git a/packages/router/src/curi.ts b/packages/router/src/curi.ts index a95a38528..6fe5dfdd5 100644 --- a/packages/router/src/curi.ts +++ b/packages/router/src/curi.ts @@ -174,7 +174,7 @@ export default function createRouter( activeNavigation = undefined; - callOneTimersAndSideEffects({ response, navigation, router }); + callSideEffects({ response, navigation, router }); }; } @@ -183,14 +183,14 @@ export default function createRouter( finishCallback = undefined; } - function callObservers(emitted: Emitted) { - observers.forEach(fn => { + function callObserversAndOneTimers(emitted: Emitted) { + [...observers, ...oneTimers.splice(0)].forEach(fn => { fn(emitted); }); } - function callOneTimersAndSideEffects(emitted: Emitted) { - [...oneTimers.splice(0), ...sideEffects].forEach(fn => { + function callSideEffects(emitted: Emitted) { + sideEffects.forEach(fn => { fn(emitted); }); } @@ -206,8 +206,8 @@ export default function createRouter( mostRecent.response = response; mostRecent.navigation = navigation; - callObservers({ response, navigation, router }); - callOneTimersAndSideEffects({ response, navigation, router }); + callObserversAndOneTimers({ response, navigation, router }); + callSideEffects({ response, navigation, router }); } if (response.redirectTo !== undefined) { @@ -221,7 +221,7 @@ export default function createRouter( mostRecent.response = response; mostRecent.navigation = navigation; - callObservers({ response, navigation, router }); + callObserversAndOneTimers({ response, navigation, router }); } if (response.redirectTo !== undefined) { diff --git a/packages/router/tests/curi.spec.ts b/packages/router/tests/curi.spec.ts index b8a508a39..80645f6e0 100644 --- a/packages/router/tests/curi.spec.ts +++ b/packages/router/tests/curi.spec.ts @@ -795,6 +795,44 @@ describe("curi", () => { router.observe(check); }); + describe("suspend", () => { + it("calls function before navigation is finished", done => { + const routes = [ + { name: "Home", path: "" }, + { name: "About", path: "about" }, + { + name: "Contact", + path: "contact", + children: [ + { + name: "How", + path: ":method", + resolve: { + test: () => Promise.resolve() + } + } + ] + } + ]; + const history = InMemory({ locations: ["/"] }); + const router = curi(history, routes, { + suspend: true + }); + // Register an observer function, but don't call it immediately + // so that we can compare its received location to the history's + // current location. + router.observe( + ({ response }) => { + expect(response.location.pathname).toBe("/contact/phone"); + expect(history.location.pathname).toBe("/"); + done(); + }, + { initial: false } + ); + history.navigate("/contact/phone"); + }); + }); + it("does not emit responses for cancelled navigation", done => { const routes = [ { name: "Home", path: "" }, @@ -1037,6 +1075,48 @@ describe("curi", () => { router.once(check); }); + describe("suspend", () => { + it("calls function before navigation is finished", done => { + const routes = [ + { name: "Home", path: "" }, + { name: "About", path: "about" }, + { + name: "Contact", + path: "contact", + children: [ + { + name: "How", + path: ":method", + resolve: { + test: () => Promise.resolve() + } + } + ] + } + ]; + const history = InMemory({ locations: ["/"] }); + const router = curi(history, routes, { + suspend: true + }); + // Register a one timer function, but don't call it immediately + // so that we can compare its received location to the history's + // current location. + // While router.once() is typically used with the initial location, + // the easiest way to verify that a one time function is called before + // finishing navigation is to verify that its location is the new one, + // while the history's is the old one. + router.once( + ({ response }) => { + expect(response.location.pathname).toBe("/contact/phone"); + expect(history.location.pathname).toBe("/"); + done(); + }, + { initial: false } + ); + history.navigate("/contact/phone"); + }); + }); + it("does not emit responses for cancelled navigation", done => { const routes = [ { name: "Home", path: "" },