Compare commits
2
Commits
10f01a9346
...
5a974bac8f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a974bac8f | ||
|
|
98380a06b9 |
@@ -1,8 +1,6 @@
|
|||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {getAccessToken} from "@/auth/token";
|
import {activityApi} from "@/mammon";
|
||||||
import {mammonUrl, refreshAccessToken} from "@/mammon";
|
|
||||||
|
|
||||||
const STREAM_URL = mammonUrl + "activities/processed";
|
|
||||||
const RECONNECT_DELAY_MILLIS = 3_000;
|
const RECONNECT_DELAY_MILLIS = 3_000;
|
||||||
const FRAME_SEPARATOR = "\n\n";
|
const FRAME_SEPARATOR = "\n\n";
|
||||||
const PROCESSED_EVENT = "event:processed";
|
const PROCESSED_EVENT = "event:processed";
|
||||||
@@ -48,33 +46,20 @@ const consume = async (body: ReadableStream<Uint8Array>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const connect = async (retried = false): Promise<void> => {
|
const connect = async (): Promise<void> => {
|
||||||
if (listeners.size === 0) {
|
if (listeners.size === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const signal = controller?.signal;
|
const signal = controller?.signal;
|
||||||
const token = getAccessToken();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(STREAM_URL, {
|
const response = await activityApi.streamProcessing({
|
||||||
headers: {
|
responseType: "stream",
|
||||||
Accept: "text/event-stream",
|
adapter: "fetch",
|
||||||
...(token ? {Authorization: `Bearer ${token}`} : {}),
|
|
||||||
},
|
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 401) {
|
await consume(response.data as unknown as ReadableStream<Uint8Array>);
|
||||||
if (!retried && await refreshAccessToken() && listeners.size > 0) {
|
|
||||||
return connect(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!response.ok || !response.body) {
|
|
||||||
throw new Error(`Activity processing SSE stream failed with ${response.status}`);
|
|
||||||
}
|
|
||||||
await consume(response.body);
|
|
||||||
scheduleReconnect();
|
scheduleReconnect();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (listeners.size === 0 || signal?.aborted) {
|
if (listeners.size === 0 || signal?.aborted) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {getMarketTypes, MarketTypePrice, useAppraisalStore} from "@/market";
|
import {getMarketTypes, MarketTypePrice, useAppraisalStore} from "@/market";
|
||||||
import {ref, watch} from 'vue';
|
import {ref, watch} from 'vue';
|
||||||
|
import {ArrowPathIcon} from '@heroicons/vue/24/outline';
|
||||||
|
import {useAutoRefresh} from '@/composables';
|
||||||
import {AcquiredType} from './AcquiredType';
|
import {AcquiredType} from './AcquiredType';
|
||||||
import {RawAcquiredType} from './acquisition';
|
import {RawAcquiredType} from './acquisition';
|
||||||
import AcquisitionResultTable from './AcquisitionResultTable.vue';
|
import AcquisitionResultTable from './AcquisitionResultTable.vue';
|
||||||
@@ -44,10 +46,18 @@ const refresh = async (itms: RawAcquiredType[] = props.items) => {
|
|||||||
|
|
||||||
watch(() => props.items, refresh, {immediate: true});
|
watch(() => props.items, refresh, {immediate: true});
|
||||||
|
|
||||||
defineExpose({refresh});
|
const {active: autoRefresh, toggle: toggleAutoRefresh} = useAutoRefresh(() => refresh(), 5 * 60 * 1000);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="flex">
|
||||||
|
<div class="ms-auto flex">
|
||||||
|
<button class="rounded-e-none" @click="refresh()">Refresh</button>
|
||||||
|
<button class="rounded-s-none border-s-0 flex items-center" :class="{ 'bg-slate-700': autoRefresh }" title="Auto refresh" @click="toggleAutoRefresh">
|
||||||
|
<ArrowPathIcon class="w-5 h-5" :class="{ 'animate-spin': autoRefresh }" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<template v-if="enriched.length > 0">
|
<template v-if="enriched.length > 0">
|
||||||
<AcquisitionResultTable :items="enriched" :ignoredColumns="ignoredColumns" @buy="(types, price, buy, sell) => buyModal?.open(types[0].type, { 'Price': price, 'Buy': buy, 'Sell': sell }, props.ledgerId)" @sell="types => sellModal?.open(types, props.ledgerId)" />
|
<AcquisitionResultTable :items="enriched" :ignoredColumns="ignoredColumns" @buy="(types, price, buy, sell) => buyModal?.open(types[0].type, { 'Price': price, 'Buy': buy, 'Sell': sell }, props.ledgerId)" @sell="types => sellModal?.open(types, props.ledgerId)" />
|
||||||
<BuyModal ref="buyModal" />
|
<BuyModal ref="buyModal" />
|
||||||
|
|||||||
@@ -1,29 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {AcquisitionsPanel, useAcquiredTypesStore} from '@/market/acquisition';
|
import {AcquisitionsPanel, useAcquiredTypesStore} from '@/market/acquisition';
|
||||||
import {ArrowPathIcon} from '@heroicons/vue/24/outline';
|
|
||||||
import {useAutoRefresh} from '@/composables';
|
|
||||||
import {ref} from 'vue';
|
|
||||||
|
|
||||||
const acquiredTypesStore = useAcquiredTypesStore();
|
const acquiredTypesStore = useAcquiredTypesStore();
|
||||||
const panel = ref<InstanceType<typeof AcquisitionsPanel>>();
|
|
||||||
|
|
||||||
const refresh = async () => {
|
|
||||||
await panel.value?.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
const {active: autoRefresh, toggle: toggleAutoRefresh} = useAutoRefresh(refresh, 5 * 60 * 1000);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<div class="flex">
|
<AcquisitionsPanel :items="acquiredTypesStore.acquiredTypes" ignoredColumns="date" />
|
||||||
<div class="ms-auto flex">
|
|
||||||
<button class="rounded-e-none" @click="refresh">Refresh</button>
|
|
||||||
<button class="rounded-s-none border-s-0 flex items-center" :class="{ 'bg-slate-700': autoRefresh }" title="Auto refresh" @click="toggleAutoRefresh">
|
|
||||||
<ArrowPathIcon class="w-5 h-5" :class="{ 'animate-spin': autoRefresh }" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<AcquisitionsPanel ref="panel" :items="acquiredTypesStore.acquiredTypes" ignoredColumns="date" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
Reference in New Issue
Block a user