Skip to content

Commit

Permalink
fix(history-service): navigation after reload (#175)
Browse files Browse the repository at this point in the history
fixes #171

Instead of using a memory history under the hood for the consumer history,
and storing the entries in session storage, we just compute the consumer
path from the root location, and store all consumer states in the root
history state.

This change also removes the memory history. We don't need a facade for
memory histories, since they don't affect the URL and browser history.
For server-side rendering we will provide a static history instead
(in a separate upcoming PR).
  • Loading branch information
unstubbable authored and clebert committed Dec 19, 2018
1 parent eb8f5eb commit b37eecf
Show file tree
Hide file tree
Showing 21 changed files with 1,157 additions and 1,185 deletions.
4 changes: 2 additions & 2 deletions packages/demos/src/history-service/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ describe('integration test: "history-service"', () => {
expect(await b.getPathname()).toBe('/b1');
});

test.skip('Scenario 7: Consumer A pushes a new pathname, B replaces their pathname, and then the user navigates back', async () => {
test('Scenario 7: Consumer A pushes a new pathname, B replaces their pathname, and then the user navigates back', async () => {
await browser.goto(url);

expect(await browser.getPath()).toBe('/');
Expand Down Expand Up @@ -184,7 +184,7 @@ describe('integration test: "history-service"', () => {
expect(await b.getPathname()).toBe('/b1');
});

test.skip('Scenario 9: Consumer A pushes a new pathname two times, then the user reloads the page, and navigates back', async () => {
test('Scenario 9: Consumer A pushes a new pathname two times, then the user reloads the page, and navigates back', async () => {
await browser.goto(url);
await a.push('/a1');
await a.push('/a2');
Expand Down
2 changes: 1 addition & 1 deletion packages/history-service/.size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
module.exports = [
{
path: 'lib/index.js',
limit: '2 KB'
limit: '3 KB'
}
];
71 changes: 65 additions & 6 deletions packages/history-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ page.
- [On the server:](#on-the-server)
- [As the Integrator](#as-the-integrator)
- [Writing a Custom Location Transformer](#writing-a-custom-location-transformer)
- [Caveats](#caveats)

## Getting started

Expand Down Expand Up @@ -136,11 +137,11 @@ export default {

create(env) {
const historyService = env.featureServices['s2:history'];
const memoryHistory = historyService.createMemoryHistory();
const staticHistory = historyService.createStaticHistory();

return {
render: () => (
<Router history={memoryHistory}>
<Router history={staticHistory}>
<App />
</Router>
)
Expand All @@ -149,8 +150,9 @@ export default {
};
```

For both the browser and the memory history, the service is API-compatible with
the history package. For further information reference
For both the browser and the static history, the service is API-compatible with
the history package. Note, however, that the `go`, `goBack`, `goForward` and
`block` methods are not supported. For further information, reference
[its documentation](https://www.npmjs.com/package/history).

### As the Integrator
Expand Down Expand Up @@ -241,16 +243,73 @@ const rootLocationTransformer = {
searchParams.delete(consumerId);
}

const {pathname, state} = rootLocation;

return {
...rootLocation,
search: searchParams.toString()
pathname,
search: searchParams.toString(),
state
};
}
};

// ...
```

## Caveats

### Replace & Pop

Since multiple consumers can push and replace location changes at any time onto
the browser history, special attention must be given when **replacing** consumer
locations. Imagine the following scenario with two history service consumers (A
and B):

- A and B are initially loaded with `/`.

| Browser History Stack | Current URL |
| --------------------- | ------------ |
| /?a=**/**&b=**/** | :arrow_left: |

* A pushes `/a1`, e.g. caused by user interaction.

| Browser History Stack | Current URL |
| --------------------- | ------------ |
| /?a=/&b=/ | |
| /?a=**/a1**&b=/ | :arrow_left: |

* B decides it needs to replace `/` with `/b1`, e.g. because it received some
outdated data.

| Browser History Stack | Current URL |
| --------------------- | ------------ |
| /?a=/&b=/ | |
| /?a=/a1&b=**/b1** | :arrow_left: |

* The user navigates back.

| Browser History Stack | Current URL |
| --------------------- | ------------ |
| /?a=/&b=/ | :arrow_left: |
| /?a=/a1&b=/b1 | |

* ⚠️ Now it is B's responsibility, again, to replace its location with `/b1` on
the first browser history entry.

| Browser History Stack | Current URL |
| --------------------- | ------------ |
| /?a=/&b=**/b1** | :arrow_left: |
| /?a=/a1&b=/b1 | |

**Note:** The alternating background colors of the table rows don't have any
meaning.

### Push, Push & Pop

When a history service consumer pushes the same location multiple times in a row
and the user subsequently navigates back, no pop event is emitted for the
unchanged location of this consumer.

---

Copyright (c) 2018 SinnerSchrader Deutschland GmbH. Released under the terms of
Expand Down
3 changes: 2 additions & 1 deletion packages/history-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"typings": "lib/index.d.ts",
"dependencies": {
"@feature-hub/core": "^0.7.0",
"@feature-hub/server-renderer": "^0.7.0"
"@feature-hub/server-renderer": "^0.7.0",
"fast-deep-equal": "^2.0.1"
},
"devDependencies": {
"@types/history": "^4.7.2",
Expand Down
Loading

0 comments on commit b37eecf

Please sign in to comment.