Skip to content

Commit

Permalink
explorer: Add a reset method to data stores
Browse files Browse the repository at this point in the history
Resolves #1732
  • Loading branch information
ascartabelli committed May 14, 2024
1 parent a46fd0b commit a63624d
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,86 @@ describe("createDataStore", () => {
});
expect(dataPromise).resolves.toStrictEqual(get(dataStore));
});

it("should expose a `reset` method to reset the data to its initial state", async () => {
expect(get(dataStore)).toStrictEqual({
data: null,
error: null,
isLoading: false,
});

await dataStore.getData(...args);

expect(get(dataStore)).toStrictEqual({
data,
error: null,
isLoading: false,
});

dataStore.reset();

expect(get(dataStore)).toStrictEqual({
data: null,
error: null,
isLoading: false,
});

dataRetriever.mockRejectedValueOnce(error);

await dataStore.getData(...args);

expect(get(dataStore)).toStrictEqual({
data: null,
error,
isLoading: false,
});

dataStore.reset();

expect(get(dataStore)).toStrictEqual({
data: null,
error: null,
isLoading: false,
});
});

it("should ignore the pending promise when `reset` is called and have `getData` return the reset store", async () => {
const expectedInitialState = {
data: null,
error: null,
isLoading: false,
};

await dataStore.getData(...args);

let dataPromise = dataStore.getData(...args);

expect(get(dataStore)).toStrictEqual({
data,
error: null,
isLoading: true,
});

dataStore.reset();

expect(get(dataStore)).toStrictEqual(expectedInitialState);
expect(await dataPromise).toStrictEqual(expectedInitialState);

// dataStore.getData(...args);
await dataStore.getData(...args);

dataRetriever.mockRejectedValueOnce(error);
dataPromise = dataStore.getData(...args);

expect(get(dataStore)).toStrictEqual({
data,
error: null,
isLoading: true,
});

dataStore.reset();

expect(get(dataStore)).toStrictEqual(expectedInitialState);
expect(await dataPromise).toStrictEqual(expectedInitialState);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,68 @@ describe("createPollingDataStore", () => {

pollingDataStore.stop();
});

it("should expose a `reset` method that stops the polling and resets the store to its initial state", async () => {
const expectedInitialState = {
data: null,
error: null,
isLoading: false,
};

expect(get(pollingDataStore)).toStrictEqual(expectedInitialState);

dataRetriever.mockResolvedValueOnce(data1).mockResolvedValueOnce(data2);

pollingDataStore.start(...args);

await vi.advanceTimersByTimeAsync(fetchInterval - 1);

expect(get(pollingDataStore)).toStrictEqual({
data: data1,
error: null,
isLoading: false,
});

expect(dataRetriever).toHaveBeenCalledTimes(1);

pollingDataStore.reset();

expect(get(pollingDataStore)).toStrictEqual(expectedInitialState);

await vi.advanceTimersByTimeAsync(fetchInterval * 10);

expect(dataRetriever).toHaveBeenCalledTimes(1);
expect(get(pollingDataStore)).toStrictEqual(expectedInitialState);

dataRetriever.mockRejectedValueOnce(error).mockResolvedValueOnce(data1);

pollingDataStore.start(...args);

await vi.advanceTimersByTimeAsync(fetchInterval - 1);

expect(get(pollingDataStore)).toStrictEqual({
data: data2,
error: null,
isLoading: false,
});

await vi.advanceTimersByTimeAsync(fetchInterval - 1);

expect(get(pollingDataStore)).toStrictEqual({
data: null,
error,
isLoading: false,
});

expect(dataRetriever).toHaveBeenCalledTimes(3);

pollingDataStore.reset();

expect(get(pollingDataStore)).toStrictEqual(expectedInitialState);

await vi.advanceTimersByTimeAsync(fetchInterval * 10);

expect(dataRetriever).toHaveBeenCalledTimes(3);
expect(get(pollingDataStore)).toStrictEqual(expectedInitialState);
});
});
37 changes: 26 additions & 11 deletions explorer/src/lib/dusk/svelte-stores/createDataStore.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { writable } from "svelte/store";
import { get, writable } from "svelte/store";

import { getErrorFrom } from "$lib/dusk/error";

Expand Down Expand Up @@ -30,24 +30,32 @@ function createDataStore(dataRetriever) {

dataPromise = dataRetriever(...args)
.then((data) => {
const newStore = { data, error: null, isLoading: false };
if (dataPromise) {
const newStoreContent = { data, error: null, isLoading: false };

set(newStore);
set(newStoreContent);

return newStore;
return newStoreContent;
} else {
return get(dataStore);
}
})
.catch(
/** @param {any} error */
(error) => {
const newStore = {
data: null,
error: getErrorFrom(error),
isLoading: false,
};
if (dataPromise) {
const newStoreContent = {
data: null,
error: getErrorFrom(error),
isLoading: false,
};

set(newStore);
set(newStoreContent);

return newStore;
return newStoreContent;
} else {
return get(dataStore);
}
}
)
.finally(() => {
Expand All @@ -57,8 +65,15 @@ function createDataStore(dataRetriever) {
return dataPromise;
};

const reset = () => {
dataPromise = null;

set(initialState);
};

return {
getData,
reset,
subscribe,
};
}
Expand Down
6 changes: 6 additions & 0 deletions explorer/src/lib/dusk/svelte-stores/createPollingDataStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ const createPollingDataStore = (dataRetriever, fetchInterval) => {
}
};

const reset = () => {
stop();
dataStore.reset();
};

const stop = () => {
isPolling = false;
};
Expand All @@ -53,6 +58,7 @@ const createPollingDataStore = (dataRetriever, fetchInterval) => {
);

return {
reset,
start,
stop,
subscribe: pollingDataStore.subscribe,
Expand Down
2 changes: 2 additions & 0 deletions explorer/src/lib/dusk/svelte-stores/svelte-stores.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ type DataStoreContent = {

type DataStore = Readable<DataStoreContent> & {
getData: (...args: any) => Promise<DataStoreContent>;
reset: () => void;
};

type PollingDataStore = Readable<DataStoreContent> & {
reset: () => void;
start: (...args: any) => void;
stop: (...args: any) => void;
};

0 comments on commit a63624d

Please sign in to comment.