Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable to add listeners for clearStore #4082

Merged
Merged
24 changes: 19 additions & 5 deletions packages/apollo-client/src/ApolloClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default class ApolloClient<TCacheShape> implements DataProxy {
private proxy: ApolloCache<TCacheShape> | undefined;
private ssrMode: boolean;
private resetStoreCallbacks: Array<() => Promise<any>> = [];
private clearStoreCallbacks: Array<() => Promise<any>> = [];

/**
* Constructs an instance of {@link ApolloClient}.
Expand Down Expand Up @@ -114,7 +115,7 @@ export default class ApolloClient<TCacheShape> implements DataProxy {
const supportedDirectives = new ApolloLink(
(operation: Operation, forward: NextLink) => {
let result = supportedCache.get(operation.query);
if (! result) {
if (!result) {
result = removeConnectionDirectiveFromDocument(operation.query);
supportedCache.set(operation.query, result);
supportedCache.set(result, result);
Expand Down Expand Up @@ -460,23 +461,36 @@ export default class ApolloClient<TCacheShape> implements DataProxy {
*/
public clearStore(): Promise<void | null> {
const { queryManager } = this;
return Promise.resolve().then(
() => (queryManager ? queryManager.clearStore() : Promise.resolve(null)),
);
return Promise.resolve()
.then(() => Promise.all(this.clearStoreCallbacks.map(fn => fn())))
.then(
() =>
queryManager ? queryManager.clearStore() : Promise.resolve(null),
);
}

/**
* Allows callbacks to be registered that are executed with the store is reset.
* onResetStore returns an unsubscribe function for removing your registered callbacks.
*/

public onResetStore(cb: () => Promise<any>): () => void {
this.resetStoreCallbacks.push(cb);
return () => {
this.resetStoreCallbacks = this.resetStoreCallbacks.filter(c => c !== cb);
};
}

/**
* Allows callbacks to be registered that are executed with the store is cleared.
* onClearStore returns an unsubscribe function for removing your registered callbacks.
*/
public onClearStore(cb: () => Promise<any>): () => void {
this.clearStoreCallbacks.push(cb);
return () => {
this.clearStoreCallbacks = this.clearStoreCallbacks.filter(c => c !== cb);
};
}

/**
* Refetches all of your active queries.
*
Expand Down
42 changes: 42 additions & 0 deletions packages/apollo-client/src/__tests__/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,48 @@ describe('client', () => {
});
});

it('has a clearStore method which calls QueryManager', done => {
const client = new ApolloClient({
link: ApolloLink.empty(),
cache: new InMemoryCache(),
});
client.queryManager = {
clearStore: () => {
done();
},
} as QueryManager;
client.clearStore();
});

it('has an onClearStore method which takes a callback to be called after clearStore', async () => {
const client = new ApolloClient({
link: ApolloLink.empty(),
cache: new InMemoryCache(),
});

const onClearStore = jest.fn();
client.onClearStore(onClearStore);

await client.clearStore();

expect(onClearStore).toHaveBeenCalled();
});

it('onClearStore returns a method that unsubscribes the callback', async () => {
const client = new ApolloClient({
link: ApolloLink.empty(),
cache: new InMemoryCache(),
});

const onClearStore = jest.fn();
const unsubscribe = client.onClearStore(onClearStore);

unsubscribe();

await client.clearStore();
expect(onClearStore).not.toHaveBeenCalled();
});

it('has a resetStore method which calls QueryManager', done => {
const client = new ApolloClient({
link: ApolloLink.empty(),
Expand Down