Skip to content

Commit

Permalink
Merge pull request #405 from poap-xyz/stream-remote
Browse files Browse the repository at this point in the history
Stream
  • Loading branch information
jm42 authored Nov 24, 2024
2 parents cdd5650 + d048f71 commit bd1af3a
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 72 deletions.
63 changes: 42 additions & 21 deletions src/hooks/useEventInCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import { useCallback, useEffect, useState } from 'react'
import { AbortedError } from 'models/error'
import { Drop } from 'models/drop'
import { POAP } from 'models/poap'
import { Progress } from 'models/http'
import { CountProgress, DownloadProgress } from 'models/http'
import { InCommon } from 'models/api'
import { filterInCommon } from 'models/in-common'
import { getInCommonEventsWithProgress } from 'loaders/api'
import { getInCommonEventsWithEvents, getInCommonEventsWithProgress } from 'loaders/api'
import { scanAddress } from 'loaders/poap'

function useEventInCommon(
eventId: number,
owners: string[],
force: boolean = false,
local: boolean = false,
stream: boolean = false,
): {
completedEventInCommon: boolean
loadingEventInCommon: boolean
loadedInCommonProgress: { progress: number; estimated: number | null; rate: number | null } | null
loadedInCommon: CountProgress | null
loadedInCommonDownload: DownloadProgress | null
loadedOwners: number
ownersErrors: Array<{ address: string; error: Error }>
inCommon: InCommon
Expand All @@ -27,7 +29,8 @@ function useEventInCommon(
} {
const [completed, setCompleted] = useState<boolean>(false)
const [loading, setLoading] = useState<boolean>(false)
const [loadedProgress, setLoadedProgress] = useState<Progress | null>(null)
const [loadedInCommon, setLoadedInCommon] = useState<CountProgress | null>(null)
const [loadedProgress, setLoadedProgress] = useState<DownloadProgress | null>(null)
const [loadedOwners, setLoadedOwners] = useState<number>(0)
const [errors, setErrors] = useState<Array<{ address: string; error: Error }>>([])
const [inCommon, setInCommon] = useState<InCommon>({})
Expand Down Expand Up @@ -144,24 +147,39 @@ function useEventInCommon(
} else {
setLoading(true)
setLoadedOwners(0)
setLoadedInCommon(null)
setLoadedProgress(null)
getInCommonEventsWithProgress(
eventId,
/*abortSignal*/undefined,
/*onProgress*/({ progress, estimated, rate }) => {
if (progress != null) {
setLoadedProgress({
progress,
estimated: estimated ?? null,
rate: rate ?? null,
})
} else {
setLoadedProgress(null)
}
},
/*refresh*/force
;(
stream
? getInCommonEventsWithEvents(
eventId,
/*refresh*/force,
/*onProgress*/(received, total) => {
setLoadedInCommon({
count: received,
total,
})
},
)
: getInCommonEventsWithProgress(
eventId,
/*abortSignal*/undefined,
/*onProgress*/({ progress, estimated, rate }) => {
if (progress != null) {
setLoadedProgress({
progress,
estimated: estimated ?? null,
rate: rate ?? null,
})
} else {
setLoadedProgress(null)
}
},
/*refresh*/force
)
).then(
(result) => {
setLoadedInCommon(null)
setLoadedProgress(null)
if (!result) {
return fetchOwnersInCommon(controllers)
Expand All @@ -175,6 +193,7 @@ function useEventInCommon(
setCachedTs(result.ts)
},
(err) => {
setLoadedInCommon(null)
setLoadedProgress(null)
console.error(err)
return fetchOwnersInCommon(controllers)
Expand All @@ -189,13 +208,14 @@ function useEventInCommon(
}
setCompleted(false)
setLoading(false)
setLoadedInCommon(null)
setLoadedProgress(null)
setLoadedOwners(0)
setErrors([])
setInCommon({})
}
},
[eventId, owners, force, local, fetchOwnersInCommon]
[eventId, owners, force, local, stream, fetchOwnersInCommon]
)

function retryAddress(address: string): () => void {
Expand All @@ -212,7 +232,8 @@ function useEventInCommon(
return {
completedEventInCommon: completed,
loadingEventInCommon: loading,
loadedInCommonProgress: loadedProgress,
loadedInCommon,
loadedInCommonDownload: loadedProgress,
loadedOwners,
ownersErrors: errors,
inCommon,
Expand Down
85 changes: 65 additions & 20 deletions src/hooks/useEventsInCommon.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useCallback, useEffect, useState } from 'react'
import { getInCommonEventsWithProgress } from 'loaders/api'
import { getInCommonEventsWithEvents, getInCommonEventsWithProgress } from 'loaders/api'
import { scanAddress } from 'loaders/poap'
import { AbortedError } from 'models/error'
import { POAP } from 'models/poap'
import { Drop } from 'models/drop'
import { Progress } from 'models/http'
import { CountProgress, DownloadProgress } from 'models/http'
import { EventsInCommon, InCommon } from 'models/api'
import { filterInCommon } from 'models/in-common'

Expand All @@ -14,12 +14,14 @@ function useEventsInCommon(
all: boolean = false,
force: boolean = false,
local: boolean = false,
stream: boolean = false,
): {
completedEventsInCommon: boolean
completedInCommonEvents: Record<number, boolean>
loadingInCommonEvents: Record<number, boolean>
eventsInCommonErrors: Record<number, Record<string, Error>>
loadedEventsProgress: Record<number, Progress>
loadedEventsInCommon: Record<number, CountProgress>
loadedEventsProgress: Record<number, DownloadProgress>
loadedEventsOwners: Record<number, number>
eventsInCommon: Record<number, EventsInCommon>
fetchEventsInCommon: () => () => void
Expand All @@ -28,7 +30,8 @@ function useEventsInCommon(
const [completed, setCompleted] = useState<Record<number, boolean>>({})
const [loading, setLoading] = useState<Record<number, boolean>>({})
const [errors, setErrors] = useState<Record<number, Record<string, Error>>>({})
const [loadedProgress, setLoadedProgress] = useState<Record<number, Progress>>({})
const [loadedInCommon, setLoadedInCommon] = useState<Record<number, CountProgress>>({})
const [loadedProgress, setLoadedProgress] = useState<Record<number, DownloadProgress>>({})
const [loadedOwners, setLoadedOwners] = useState<Record<number, number>>({})
const [inCommon, setInCommon] = useState<Record<number, EventsInCommon>>({})

Expand Down Expand Up @@ -141,6 +144,31 @@ function useEventsInCommon(
})
}

function updateLoadedInCommon(
eventId: number,
{ count, total }: CountProgress,
) {
setLoadedInCommon((prevLoadedInCommon) => ({
...(prevLoadedInCommon ?? {}),
[eventId]: { count, total },
}))
}

function removeLoadedInCommon(eventId: number): void {
setLoadedInCommon((prevLoadedInCommon) => {
if (prevLoadedInCommon == null) {
return {}
}
const newProgress: Record<number, CountProgress> = {}
for (const [loadingEventId, progress] of Object.entries(prevLoadedInCommon)) {
if (String(eventId) !== String(loadingEventId)) {
newProgress[loadingEventId] = progress
}
}
return newProgress
})
}

function addLoadedProgress(eventId: number): void {
setLoadedProgress((alsoProgress) => ({
...alsoProgress,
Expand All @@ -154,7 +182,7 @@ function useEventsInCommon(

function updateLoadedProgress(
eventId: number,
{ progress, estimated, rate }: Progress,
{ progress, estimated, rate }: DownloadProgress,
): void {
setLoadedProgress((alsoProgress) => {
if (alsoProgress[eventId] != null) {
Expand All @@ -176,7 +204,7 @@ function useEventsInCommon(
if (alsoProgress == null) {
return {}
}
const newProgress: Record<number, Progress> = {}
const newProgress: Record<number, DownloadProgress> = {}
for (const [loadingEventId, progress] of Object.entries(alsoProgress)) {
if (String(eventId) !== String(loadingEventId)) {
newProgress[loadingEventId] = progress
Expand Down Expand Up @@ -383,22 +411,35 @@ function useEventsInCommon(
} else {
removeCompleted(eventId)
addLoading(eventId)
addLoadedProgress(eventId)
let result: EventsInCommon | null = null
try {
result = await getInCommonEventsWithProgress(
eventId,
controller.signal,
/*onProgress*/({ progress, estimated, rate }) => {
if (progress != null) {
updateLoadedProgress(eventId, { progress, estimated, rate })
} else {
removeLoadedProgress(eventId)
}
},
/*refresh*/force
)
if (stream) {
result = await getInCommonEventsWithEvents(
eventId,
/*refresh*/force,
/*onProgress*/(received, total) => {
updateLoadedInCommon(eventId, { count: received, total })
},
)
removeLoadedInCommon(eventId)
} else {
addLoadedProgress(eventId)
result = await getInCommonEventsWithProgress(
eventId,
controller.signal,
/*onProgress*/({ progress, estimated, rate }) => {
if (progress != null) {
updateLoadedProgress(eventId, { progress, estimated, rate })
} else {
removeLoadedProgress(eventId)
}
},
/*refresh*/force
)
removeLoadedProgress(eventId)
}
} catch (err: unknown) {
removeLoadedInCommon(eventId)
removeLoadedProgress(eventId)
if (!(err instanceof AbortedError)) {
console.error(err)
Expand All @@ -408,6 +449,7 @@ function useEventsInCommon(
}
return
}
removeLoadedInCommon(eventId)
removeLoadedProgress(eventId)
if (result == null) {
await processEvent(eventId, addresses, controllers)
Expand All @@ -421,7 +463,7 @@ function useEventsInCommon(
}
}
},
[force, local, processEvent]
[force, local, stream, processEvent]
)

const fetchEventsInCommon = useCallback(
Expand All @@ -430,6 +472,7 @@ function useEventsInCommon(
setCompleted({})
setLoading({})
setErrors({})
setLoadedInCommon({})
setLoadedProgress({})
setLoadedOwners({})
setInCommon({})
Expand Down Expand Up @@ -469,6 +512,7 @@ function useEventsInCommon(
setCompleted({})
setLoading({})
setErrors({})
setLoadedInCommon({})
setLoadedProgress({})
setLoadedOwners({})
setInCommon({})
Expand Down Expand Up @@ -497,6 +541,7 @@ function useEventsInCommon(
completedInCommonEvents: completed,
loadingInCommonEvents: loading,
eventsInCommonErrors: errors,
loadedEventsInCommon: loadedInCommon,
loadedEventsProgress: loadedProgress,
loadedEventsOwners: loadedOwners,
eventsInCommon: inCommon,
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useEventsOwnersAndMetrics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useState } from 'react'
import { filterInvalidOwners } from 'models/address'
import { AbortedError } from 'models/error'
import { InCommon } from 'models/api'
import { EventAndOwners, InCommon } from 'models/api'
import { fetchPOAPs } from 'loaders/poap'
import {
getEventAndOwners,
Expand Down Expand Up @@ -117,7 +117,7 @@ function useEventsOwnersAndMetrics(eventIds: number[], expiryDates: Record<numbe
async (eventId: number, abortSignal: AbortSignal) => {
removeError(eventId)
addLoading(eventId)
let eventAndOwners
let eventAndOwners: EventAndOwners | null = null
try {
eventAndOwners = await getEventAndOwners(
eventId,
Expand Down
Loading

0 comments on commit bd1af3a

Please sign in to comment.