Skip to content

Commit b77c679

Browse files
committed
Add frontend cacheing for aggregates data
1 parent d0fee16 commit b77c679

File tree

6 files changed

+149
-34
lines changed

6 files changed

+149
-34
lines changed

src/components/Asset/Metadata.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ import TooltipMeta from "../../components/misc/TooltipMeta.vue";
8080
return val === 0
8181
? `no fractional units`
8282
: val > 1
83-
? `${val} decimal digits`
84-
: `${val} decimal digit`;
83+
? `${val} decimal digits`
84+
: `${val} decimal digit`;
8585
}
8686
}
8787

src/components/Home/TopInfo/MetaData.vue

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,15 @@
9191
</template>
9292
<script lang="ts">
9393
import "reflect-metadata";
94-
import { Vue, Component } from "vue-property-decorator";
94+
import { Vue, Component, Watch } from "vue-property-decorator";
9595
9696
import axios from "@/axios";
9797
import { stringToBig } from "@/helper";
9898
import TooltipHeading from "../../misc/TooltipHeading.vue";
9999
import TooltipMeta from "../TopInfo/TooltipMeta.vue";
100100
import { AVAX_ID } from "@/store/index";
101+
import { Asset } from '@/js/Asset';
102+
import Big from "big.js";
101103
102104
@Component({
103105
components: {
@@ -106,14 +108,77 @@ import { AVAX_ID } from "@/store/index";
106108
}
107109
})
108110
export default class MetaData extends Vue {
111+
volumeCache: Big = Big(0);
112+
totalTransactionsCache: number = 0;
113+
109114
get assetsLoaded(): boolean {
110115
return this.$store.state.assetsLoaded;
111116
}
112117
118+
get assetAggregatesLoaded(): boolean {
119+
return this.$store.state.assetAggregatesLoaded;
120+
}
121+
113122
get subnetsLoaded(): boolean {
114123
return this.$store.state.Platform.subnetsLoaded;
115124
}
116125
126+
@Watch("avaxVolume")
127+
onAvaxVolumeChanged(val: string) {
128+
console.log("CALLED FROM: @Watch(avaxVolume)")
129+
this.saveCacheAvax();
130+
}
131+
132+
@Watch("totalTransactions")
133+
ontotalTransactionsChanged(val: number) {
134+
console.log("CALLED FROM: @Watch(totalTransactions)")
135+
this.saveCacheTotalTransactions();
136+
}
137+
138+
created() {
139+
// Get 24h volume cache
140+
// TODO: remove when API is enhanced
141+
let volumeCacheJSON = localStorage.getItem('avaxCache');
142+
let volumeCache = Big(0);
143+
if (volumeCacheJSON) {
144+
let cache = JSON.parse(volumeCacheJSON);
145+
volumeCache = Big(cache.volume_day);
146+
}
147+
this.volumeCache = volumeCache;
148+
149+
// Get totalTransactions cache
150+
// TODO: remove when API is enhanced
151+
let totalTransactionsCacheJSON = localStorage.getItem('totalTransactions');
152+
let totalTransactionsCache = 0;
153+
if (totalTransactionsCacheJSON) {
154+
let cache = JSON.parse(totalTransactionsCacheJSON);
155+
totalTransactionsCache = cache;
156+
}
157+
this.totalTransactionsCache = totalTransactionsCache;
158+
}
159+
160+
saveCacheAvax() {
161+
let asset = this.avax;
162+
if (asset) {
163+
let volume_day = asset.volume_day.toString();
164+
let txCount_day = asset.txCount_day;
165+
let cache = {
166+
volume_day, // AVAX volume
167+
txCount_day, // AVAX count
168+
};
169+
localStorage.setItem('avaxCache', JSON.stringify(cache));
170+
}
171+
}
172+
173+
saveCacheTotalTransactions() {
174+
let totalTransactions = this.totalTransactions;
175+
let cache = {
176+
totalTransactions // count across all assets
177+
}
178+
localStorage.setItem('totalTransactions', JSON.stringify(totalTransactions));
179+
}
180+
181+
// Data from Ortelius
117182
get tpmText(): string {
118183
let day = 60 * 24;
119184
let avg = this.totalTransactions / day;
@@ -126,6 +191,30 @@ export default class MetaData extends Vue {
126191
return avg > 1 ? avg.toFixed(0) : avg.toFixed(2);
127192
}
128193
194+
get assets() {
195+
return this.$store.state.assets;
196+
}
197+
198+
get avax(): Asset | undefined {
199+
return this.assets[AVAX_ID];
200+
}
201+
202+
get avaxVolume(): string {
203+
if (!this.avax) {
204+
return parseInt(this.volumeCache.toFixed(0)).toLocaleString();
205+
}
206+
return this.avax.isHistoryUpdated
207+
? parseInt(this.avax.volume_day.toFixed(0)).toLocaleString()
208+
: parseInt(this.volumeCache.toFixed(0)).toLocaleString();
209+
}
210+
211+
get totalTransactions(): number {
212+
return this.$store.state.assetAggregatesLoaded
213+
? this.$store.getters.totalTransactions
214+
: this.totalTransactionsCache;
215+
}
216+
217+
// Data from Avalanche-Go
129218
get totalStake(): string {
130219
let res = this.$store.getters["Platform/totalStake"];
131220
res = stringToBig(res.toString(), 9).toFixed(0);
@@ -135,18 +224,6 @@ export default class MetaData extends Vue {
135224
get validatorCount(): number {
136225
return this.$store.getters["Platform/totalValidators"];
137226
}
138-
139-
get avaxVolume(): string {
140-
let assets = this.$store.state.assets;
141-
let avax = assets[AVAX_ID];
142-
return !avax
143-
? (0).toLocaleString()
144-
: parseInt(avax.volume_day.toFixed(0)).toLocaleString();
145-
}
146-
147-
get totalTransactions(): number {
148-
return this.$store.getters.totalTransactions;
149-
}
150227
}
151228
152229
</script>

src/components/Home/TopInfo/TopAssets.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
></TooltipHeading>
99
</h2>
1010
</div>
11-
<div v-if="!assetsLoaded">
11+
<div v-if="!assetAggregatesLoaded">
1212
<v-progress-circular :size="16" :width="2" color="#E84970" indeterminate key="1"></v-progress-circular>
1313
</div>
1414
<div v-else>
@@ -65,6 +65,10 @@ export default class TopAssets extends Vue {
6565
return res.slice(0, 5);
6666
}
6767
68+
get assetAggregatesLoaded(): boolean {
69+
return this.$store.state.assetAggregatesLoaded;
70+
}
71+
6872
get assetsLoaded(): boolean {
6973
return this.$store.state.assetsLoaded;
7074
}

src/js/Asset.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IAssetData_Ortelius } from "./IAsset";
33
import { profanities } from "@/js/Profanities";
44
import Big from "big.js";
55
import { stringToBig } from '@/helper';
6+
import store from '../store';
67

78
class Asset {
89
id: string;
@@ -12,8 +13,11 @@ class Asset {
1213
denomination: number;
1314
name: string;
1415
symbol: string;
16+
// aggregate data
1517
volume_day: Big;
1618
txCount_day: number;
19+
isHistoryUpdated: boolean;
20+
// FE metadata
1721
profane: boolean;
1822

1923
constructor(assetData: IAssetData_Ortelius, isUnknown: boolean) {
@@ -27,10 +31,13 @@ class Asset {
2731
this.symbol = assetData.symbol;
2832
this.volume_day = Big(0);
2933
this.txCount_day = 0;
30-
this.profane = false;
34+
// aggregate data
35+
this.isHistoryUpdated = false;
3136
if (!isUnknown) {
3237
this.updateVolumeHistory();
3338
}
39+
// FE metadata
40+
this.profane = false;
3441
this.checkForProfanities(this.name);
3542
this.checkForProfanities(this.symbol);
3643
}
@@ -49,6 +56,8 @@ class Asset {
4956
let txVolume = res.data.aggregates.transactionVolume || "0";
5057
parent.volume_day = stringToBig(txVolume, parent.denomination);
5158
parent.txCount_day = txCount;
59+
this.isHistoryUpdated = true;
60+
store.dispatch("checkAssetAggregatesLoaded");
5261
});
5362
}
5463

src/store/index.ts

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,43 @@ export default new Vuex.Store({
2525
state: {
2626
assets: {},
2727
assetsLoaded: false,
28+
assetAggregatesLoaded: false,
2829
known_addresses: AddressDict,
2930
chainId: "X",
3031
},
3132
actions: {
3233
async init(store) {
3334
// TODO: support service for multiple chain
34-
let start = -1;
35-
let offset = 0;
35+
36+
// Get list of all indexed assets
37+
let count = 0;
38+
let offset = 0;
3639
const limit = 500;
37-
let res = await api.get(`/x/assets?&offset=${offset}&limit=${limit}`);
38-
let assets = res.data.assets;
39-
assets.forEach((assetData: any) => {
40-
store.commit("addAsset", new Asset(assetData, false));
41-
});
4240

41+
// initial request
42+
let res = await api.get(`/x/assets?offset=${offset}&limit=${limit}`);
43+
let assets = res.data.assets;
44+
// count of indexed assets
45+
count = res.data.count;
46+
47+
// keep getting asset data as necessary
4348
async function checkForMoreAssets() {
44-
if (assets.length === limit) {
45-
start = start + limit // -1 + 499
46-
offset = start
47-
let res = await api.get(`/x/assets?&offset=${offset}&limit=${limit}`);
48-
let assets = res.data.assets;
49-
assets.forEach((assetData: any) => {
50-
store.commit("addAsset", new Asset(assetData, false));
51-
});
52-
}
49+
offset += limit;
50+
let res = await api.get(`/x/assets?offset=${offset}&limit=${limit}`);
51+
let moreAssets = res.data.assets;
52+
assets.push(...moreAssets);
5353
}
5454

55-
await checkForMoreAssets();
55+
while (offset < count) {
56+
await checkForMoreAssets();
57+
}
58+
59+
// once we get all the assets, instantiate assets and save them to the store
60+
// asset aggregate data is resolved asynchronously
61+
assets.forEach((assetData: any) => {
62+
store.commit("addAsset", new Asset(assetData, false));
63+
});
64+
5665
store.commit("finishLoading");
5766
},
5867

@@ -70,13 +79,28 @@ export default new Vuex.Store({
7079
};
7180
commit("addAsset", new Asset(newAssetData, true));
7281
},
82+
83+
// dispatched from Asset instance upon /aggregates response
84+
checkAssetAggregatesLoaded(store) {
85+
let assetsArray = store.getters["assetsArray"];
86+
let notLoaded = assetsArray.find((element: Asset) => element.isHistoryUpdated === false);
87+
if (!notLoaded) {
88+
store.commit("finishAggregatesLoading");
89+
console.log("ALL ASSET AGGREGATES LOADED")
90+
}
91+
}
92+
93+
// TODO - move cache here
7394
},
7495
mutations: {
7596
addAsset(state, asset) {
7697
Vue.set(state.assets, asset.id, asset);
7798
},
7899
finishLoading(state) {
79100
state.assetsLoaded = true;
101+
},
102+
finishAggregatesLoading(state) {
103+
state.assetAggregatesLoaded = true;
80104
}
81105
},
82106
getters: {

src/store/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export interface IRootState {
22
assets: any,
33
assetsLoaded: boolean,
4+
assetAggregatesLoaded: boolean;
45
chainId: string,
56
known_addresses: {
67
[key:string]: string

0 commit comments

Comments
 (0)