Skip to content

Commit

Permalink
Merge pull request #191 from rainlanguage/2024-02-07-gui-refactor-stores
Browse files Browse the repository at this point in the history
2024 02 07 gui refactor stores
  • Loading branch information
thedavidmeister authored Feb 8, 2024
2 parents d0bc28b + 5e964ce commit 800b3c8
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 104 deletions.
31 changes: 3 additions & 28 deletions tauri-app/src/lib/stores/orderDetail.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
import { get, writable } from 'svelte/store';
import { get } from 'svelte/store';
import type { Order } from '$lib/typeshare/orderDetail';
import { invoke } from '@tauri-apps/api';
import { subgraphUrl } from '$lib/stores/settings';
import { detailStore } from '$lib/storesGeneric/detailStore';

function useOrderDetailStore() {
const STORAGE_KEY = "orders.orderDetail";

const { subscribe, update } = writable<{[id: string]: Order}>(localStorage.getItem(STORAGE_KEY) ? JSON.parse(localStorage.getItem(STORAGE_KEY) as string) : {});

subscribe(value => {
if(value) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(value));
} else {
localStorage.setItem(STORAGE_KEY, JSON.stringify({}));
}
});

async function refetch(id: string) {
const res: Order = await invoke("order_detail", {id, subgraphArgs: { url: get(subgraphUrl)} });
update((value) => {
return {... value, [id]: res};
});
}

return {
subscribe,
refetch
}
}

export const orderDetail = useOrderDetailStore();
export const orderDetail = detailStore<Order>("orders.orderDetail", (id: string) => invoke("order_detail", {id, subgraphArgs: { url: get(subgraphUrl)} }));
4 changes: 2 additions & 2 deletions tauri-app/src/lib/stores/ordersList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { get } from 'svelte/store';
import type { Order } from '$lib/typeshare/ordersList';
import { invoke } from '@tauri-apps/api';
import { subgraphUrl } from '$lib/stores/settings';
import { usePaginatedCachedStore } from '$lib/stores/paginatedStore';
import { listStore } from '$lib/storesGeneric/listStore';

export const ordersList = usePaginatedCachedStore<Order>(
export const ordersList = listStore<Order>(
'ordersList',
(page) => invoke("orders_list", {subgraphArgs: { url: get(subgraphUrl)}, paginationArgs: { page, page_size: 10 } }),
(path) => invoke("orders_list_write_csv", { path, subgraphArgs: { url: get(subgraphUrl)}, paginationArgs: { page: 1, page_size: 1000 } })
Expand Down
42 changes: 12 additions & 30 deletions tauri-app/src/lib/stores/settings.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
import { isUrlValid } from '$lib/utils/url';
import { writable, derived } from 'svelte/store';
import { derived } from 'svelte/store';
import every from 'lodash/every';
import { isAddress } from 'viem';
import { updateChainId } from '$lib/stores/chain';
import { cachedWritableInt, cachedWritableString } from '$lib/storesGeneric/cachedWritableStore';

export const rpcUrl = writable(localStorage.getItem("settings.rpcUrl") || '');
export const subgraphUrl = writable(localStorage.getItem("settings.subgraphUrl") || '');
export const orderbookAddress = writable(localStorage.getItem("settings.orderbookAddress") || '');
export const walletAddress = writable(localStorage.getItem("settings.walletAddress") || '');
export const walletDerivationIndex = writable(parseInt(localStorage.getItem("settings.walletDerivationIndex") || '0'));
export const forkBlockNumber = writable(parseInt(localStorage.getItem("settings.forkBlockNumber") || '45122616'));
export const rpcUrl = cachedWritableString("settings.rpcUrl", '');
export const subgraphUrl = cachedWritableString("settings.subgraphUrl", '');
export const orderbookAddress = cachedWritableString("settings.orderbookAddress", '');
export const walletAddress = cachedWritableString("settings.walletAddress", '');
export const walletDerivationIndex = cachedWritableInt("settings.walletDerivationIndex", 0);
export const forkBlockNumber = cachedWritableInt("settings.forkBlockNumber", 53247376);

rpcUrl.subscribe(value => {
localStorage.setItem("settings.rpcUrl", value || '');
});
subgraphUrl.subscribe(value => {
localStorage.setItem("settings.subgraphUrl", value || '');
});
orderbookAddress.subscribe(value => {
localStorage.setItem("settings.orderbookAddress", value || '');
});
walletAddress.subscribe(value => {
localStorage.setItem("settings.walletAddress", value || '');
});
walletDerivationIndex.subscribe(value => {
localStorage.setItem("settings.walletDerivationIndex", (value || 0).toString());
});
forkBlockNumber.subscribe(value => {
localStorage.setItem("settings.forkBlockNumber", (value || 45122616).toString());
});

export const isRpcUrlValid = derived(rpcUrl, (val) => isUrlValid(val));
export const isSubgraphUrlValid = derived(subgraphUrl, (val) => isUrlValid(val));
export const isOrderbookAddressValid = derived(orderbookAddress, (val) => isAddress(val));
export const isWalletAddressValid = derived(walletAddress, (val) => isAddress(val));
export const isRpcUrlValid = derived(rpcUrl, (val) => val && isUrlValid(val));
export const isSubgraphUrlValid = derived(subgraphUrl, (val) => val && isUrlValid(val));
export const isOrderbookAddressValid = derived(orderbookAddress, (val) => val && isAddress(val));
export const isWalletAddressValid = derived(walletAddress, (val) => val && isAddress(val));

isRpcUrlValid.subscribe(value => {
if(value) {
Expand Down
31 changes: 3 additions & 28 deletions tauri-app/src/lib/stores/vaultDetail.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
import { get, writable } from 'svelte/store';
import type { TokenVault } from '$lib/typeshare/vaultDetail';
import { get } from 'svelte/store';
import { invoke } from '@tauri-apps/api';
import { subgraphUrl } from '$lib/stores/settings';
import { detailStore } from '$lib/storesGeneric/detailStore';

function useVaultDetailStore() {
const STORAGE_KEY = "vaults.vaultsDetail";

const { subscribe, update } = writable<{[id: string]: TokenVault}>(localStorage.getItem(STORAGE_KEY) ? JSON.parse(localStorage.getItem(STORAGE_KEY) as string) : {});

subscribe(value => {
if(value) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(value));
} else {
localStorage.setItem(STORAGE_KEY, JSON.stringify({}));
}
});

async function refetch(id: string) {
const res: TokenVault = await invoke("vault_detail", {id, subgraphArgs: { url: get(subgraphUrl)} });
update((value) => {
return {... value, [id]: res};
});
}

return {
subscribe,
refetch
}
}

export const vaultDetail = useVaultDetailStore();
export const vaultDetail = detailStore<TokenVault>("vaults.vaultsDetail", (id: string) => invoke("vault_detail", {id, subgraphArgs: { url: get(subgraphUrl)} }));
5 changes: 2 additions & 3 deletions tauri-app/src/lib/stores/vaultListBalanceChanges.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { get } from 'svelte/store';
import { invoke } from '@tauri-apps/api';
import { subgraphUrl } from '$lib/stores/settings';
import { usePaginatedCachedStore } from './paginatedStore';
import { listStore } from '$lib/storesGeneric/listStore';
import type { VaultBalanceChange } from '$lib/typeshare/vaultListBalanceChanges';


export const useVaultListBalanceChanges = (id: string) => usePaginatedCachedStore<VaultBalanceChange>(
export const useVaultListBalanceChanges = (id: string) => listStore<VaultBalanceChange>(
`vaultListBalanceChanges-${id}`,
(page) => invoke("vault_list_balance_changes", {subgraphArgs: { url: get(subgraphUrl)}, id, paginationArgs: { page, page_size: 10 } }),
(path) => invoke("vault_list_balance_changes_write_csv", {path, subgraphArgs: { url: get(subgraphUrl)}, id, paginationArgs: { page: 1, page_size: 1000 } })
Expand Down
4 changes: 2 additions & 2 deletions tauri-app/src/lib/stores/vaultsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { get } from 'svelte/store';
import type { TokenVault } from '$lib/typeshare/vaultsList';
import { invoke } from '@tauri-apps/api';
import { subgraphUrl } from '$lib/stores/settings';
import { usePaginatedCachedStore } from './paginatedStore';
import { listStore } from '$lib/storesGeneric/listStore';


export const vaultsList = usePaginatedCachedStore<TokenVault>(
export const vaultsList = listStore<TokenVault>(
'vaultsList',
(page) => invoke("vaults_list", {subgraphArgs: { url: get(subgraphUrl)}, paginationArgs: { page, page_size: 10 } }),
(path) => invoke("vaults_list_write_csv", {path, subgraphArgs: { url: get(subgraphUrl)}, paginationArgs: { page: 1, page_size: 1000 } })
Expand Down
41 changes: 41 additions & 0 deletions tauri-app/src/lib/storesGeneric/cachedWritableStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { writable } from "svelte/store";

export function cachedWritableStore<T>(
key: string,
defaultValue: T,
serialize: (value: T) => string,
deserialize: (serialized: string) => T
) {
const getCache = () => {
const cached = localStorage.getItem(key);
return cached ? deserialize(cached) : defaultValue;
}
const setCache = (value?: T) => {
if(value !== undefined) {
localStorage.setItem(key, serialize(value));
} else {
localStorage.removeItem(key);
}
}

const data = writable<T>(getCache());

data.subscribe((value) => {
setCache(value);
})

return data;
}

export const cachedWritableString = (key: string, defaultValue = '') => cachedWritableStore<string>(key, defaultValue, (v) => v, (v) => v);
export const cachedWritableInt = (key: string, defaultValue = 0) => cachedWritableStore<number>(key, defaultValue, (v) => v.toString(), (v) => parseInt(v));


export const cachedWritableOptionalStore = <T>(
key: string,
defaultValue: T | undefined = undefined,
serialize: (value: T) => string,
deserialize: (serialized: string) => T
) => cachedWritableStore<T | undefined>(key, defaultValue, (v) => v ? serialize(v) : '', (v) => v ? deserialize(v) : undefined);

export const cachedWritableIntOptional = (key: string, defaultValue = undefined) => cachedWritableOptionalStore<number>(key, defaultValue, (v) => v.toString(), (v) => parseInt(v));
25 changes: 25 additions & 0 deletions tauri-app/src/lib/storesGeneric/detailStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { cachedWritableStore } from '$lib/storesGeneric/cachedWritableStore';

export function detailStore<T>(key: string, fetchById: (id: string) => Promise<T>) {
const {subscribe, update} = cachedWritableStore<{[id: string]: T}>(key, {}, (value) => JSON.stringify(value), (value) => JSON.parse(value));

subscribe(value => {
if(value) {
localStorage.setItem(key, JSON.stringify(value));
} else {
localStorage.setItem(key, JSON.stringify({}));
}
});

async function refetch(id: string) {
const res: T = await fetchById(id);
update((value) => {
return {... value, [id]: res};
});
}

return {
subscribe,
refetch
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { derived, get, writable, type Invalidator, type Subscriber } from 'svelte/store';
import { toasts } from './toasts';
import { toasts } from '../stores/toasts';
import { save } from '@tauri-apps/api/dialog';
import dayjs from 'dayjs';
import { ToastMessageType } from '$lib/typeshare/toast';
import { cachedWritableStore } from '$lib/storesGeneric/cachedWritableStore';

type Unsubscriber = () => void;

Expand All @@ -26,20 +27,15 @@ export interface AllPages<T> {
[pageIndex: number]: Array<T>
}

export function usePaginatedCachedStore<T>(key: string, fetchPageHandler: (page: number) => Promise<Array<T>>, writeCsvHandler: (path: string) => Promise<void>) {
const allPages = writable<AllPages<T>>(localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : []);

const cachedWritablePages = <T>(key: string) => cachedWritableStore<AllPages<T>>(key, [], (value) => JSON.stringify(value), (value) => JSON.parse(value));

export function listStore<T>(key: string, fetchPageHandler: (page: number) => Promise<Array<T>>, writeCsvHandler: (path: string) => Promise<void>) {
const allPages = cachedWritablePages<T>(key);
const pageIndex = writable(1);
const isFetching = writable(false);
const isExporting = writable(false);

allPages.subscribe(value => {
if(value) {
localStorage.setItem(key, JSON.stringify(value));
} else {
localStorage.setItem(key, JSON.stringify([]));
}
});

const page = derived(allPages, $allPages => (page: number) => $allPages[page] || []);

const { subscribe } = derived([page, pageIndex, isFetching, isExporting], ([$page, $pageIndex, $isFetching, $isExporting]) => ({
Expand Down

0 comments on commit 800b3c8

Please sign in to comment.