1
- import { unstable_cache } from "next/cache" ;
2
1
import { cache } from 'react' ;
3
- import superjson from "superjson" ;
4
- import { z } from "zod" ;
2
+ import type { z } from 'zod' ;
5
3
6
- // Your imports
7
4
import { Cluster , clients , priceFeedsSchema } from "../services/pyth" ;
5
+ import { createChunkedCacheFetcher , fetchAllChunks } from '../utils/cache' ;
8
6
9
7
const getDataCached = cache ( async ( cluster : Cluster ) => {
10
8
return clients [ cluster ] . getData ( ) ;
11
9
} ) ;
12
- const MAX_CACHE_SIZE_STRING = 2 * 1024 * 1024 - 510_000 ; // is the buffer for the returned object and the metadata from next
13
10
14
- const getPublishersForFeed = unstable_cache ( async ( cluster : Cluster , chunk ?: number ) => {
11
+ const fetchFeeds = createChunkedCacheFetcher ( async ( cluster : Cluster ) => {
12
+ const unfilteredData = await getDataCached ( cluster ) ;
13
+ const filteredData = unfilteredData . symbols
14
+ . filter (
15
+ ( symbol ) =>
16
+ unfilteredData . productFromSymbol . get ( symbol ) ?. display_symbol !== undefined
17
+ )
18
+ . map ( ( symbol ) => ( {
19
+ symbol,
20
+ product : unfilteredData . productFromSymbol . get ( symbol ) ,
21
+ price : {
22
+ ...unfilteredData . productPrice . get ( symbol ) ,
23
+ priceComponents :
24
+ unfilteredData . productPrice
25
+ . get ( symbol )
26
+ ?. priceComponents . map ( ( { publisher } ) => ( {
27
+ publisher : publisher . toBase58 ( ) ,
28
+ } ) ) ?? [ ] ,
29
+ } ,
30
+ } ) ) ;
31
+ const parsedData = priceFeedsSchema . parse ( filteredData ) ;
32
+ return parsedData ;
33
+ } , 'getfeeds' ) ;
34
+
35
+
36
+ const fetchPublishers = createChunkedCacheFetcher ( async ( cluster : Cluster ) => {
15
37
const data = await getDataCached ( cluster ) ;
16
38
const result : Record < string , string [ ] > = { } ;
17
39
for ( const key of data . productPrice . keys ( ) ) {
18
40
const price = data . productPrice . get ( key ) ;
19
41
result [ key ] = price ?. priceComponents . map ( ( { publisher } ) => publisher . toBase58 ( ) ) ?? [ ] ;
20
42
}
21
- const stringifiedResult = superjson . stringify ( result ) ;
22
-
23
- const chunksNumber = Math . ceil ( stringifiedResult . length / MAX_CACHE_SIZE_STRING ) ;
24
- const chunks = [ ] ;
25
- for ( let i = 0 ; i < chunksNumber ; i ++ ) {
26
- chunks . push ( stringifiedResult . slice ( i * MAX_CACHE_SIZE_STRING , ( i + 1 ) * MAX_CACHE_SIZE_STRING ) ) ;
27
- }
28
- return {
29
- chunk : chunks [ chunk ?? 0 ] ,
30
- chunksNumber,
31
- } ;
32
- } , [ ] , { revalidate : false } ) ;
33
-
34
- const _getFeeds = unstable_cache ( async ( cluster : Cluster , chunk ?: number ) => {
35
- // eslint-disable-next-line no-console
36
- console . log ( 'getFeeds' , cluster , chunk ) ;
37
- const data = await getDataCached ( cluster ) ;
38
- const parsedData = priceFeedsSchema . parse (
39
- data . symbols
40
- . filter (
41
- ( symbol ) =>
42
- data . productFromSymbol . get ( symbol ) ?. display_symbol !== undefined
43
- )
44
- . map ( ( symbol ) => ( {
45
- symbol,
46
- product : data . productFromSymbol . get ( symbol ) ,
47
- price : {
48
- ...data . productPrice . get ( symbol ) ,
49
- priceComponents :
50
- data . productPrice
51
- . get ( symbol )
52
- ?. priceComponents . map ( ( { publisher } ) => ( {
53
- publisher : publisher . toBase58 ( ) ,
54
- } ) ) ?? [ ] ,
55
- } ,
56
- } ) )
57
- )
58
- const result = superjson . stringify (
59
- parsedData
60
- ) ;
61
- const chunksNumber = Math . ceil ( result . length / MAX_CACHE_SIZE_STRING ) ;
62
- const chunks = [ ] ;
63
- for ( let i = 0 ; i < chunksNumber ; i ++ ) {
64
- chunks . push ( result . slice ( i * MAX_CACHE_SIZE_STRING , ( i + 1 ) * MAX_CACHE_SIZE_STRING ) ) ;
65
- }
66
- return {
67
- chunk : chunks [ chunk ?? 0 ] ,
68
- chunksNumber,
69
- } ;
70
- } , [ ] , { revalidate : false } ) ;
43
+ return result ;
44
+ } , 'getpublishers' ) ;
71
45
72
46
export const getFeedsCached = async ( cluster : Cluster ) => {
73
- const start = performance . now ( ) ;
74
- const { chunk, chunksNumber } = await _getFeeds ( cluster ) ; // uses cache
75
- const rawResults = await Promise . all ( Array . from ( { length : chunksNumber - 1 } , ( _ , i ) => _getFeeds ( cluster , i + 1 ) ) ) ;
76
- const rawJson = [ chunk , ...rawResults . map ( ( { chunk } ) => chunk ) ] . join ( '' ) ;
77
- const data = superjson . parse < z . infer < typeof priceFeedsSchema > > ( rawJson ) ;
78
- const end = performance . now ( ) ;
79
- // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions
80
- console . log ( `getFeedsCached: ${ end - start } ms` ) ;
81
- return data ;
47
+ return fetchAllChunks < z . infer < typeof priceFeedsSchema > , [ Cluster ] > ( fetchFeeds , cluster )
82
48
} ;
83
49
84
50
export const getPublishersForFeedCached = async ( cluster : Cluster , symbol : string ) => {
85
- const start = performance . now ( ) ;
86
- const { chunk, chunksNumber } = await getPublishersForFeed ( cluster ) ; // uses cache
87
- const rawResults = await Promise . all ( Array . from ( { length : chunksNumber - 1 } , ( _ , i ) => getPublishersForFeed ( cluster , i + 1 ) ) ) ;
88
- const rawJson = [ chunk , ...rawResults . map ( ( { chunk } ) => chunk ) ] . join ( '' ) ;
89
- const data = superjson . parse < Record < string , string [ ] > > ( rawJson ) ;
90
- const end = performance . now ( ) ;
91
- // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions
92
- console . log ( `getPublishersForFeedCached: ${ end - start } ms` ) ;
93
- return data [ symbol ] ;
51
+ const data = await fetchAllChunks < Record < string , string [ ] > , [ Cluster ] > ( fetchPublishers , cluster ) ;
52
+ return data [ symbol ]
94
53
} ;
95
54
96
55
export const getFeedsForPublisherCached = async (
97
56
cluster : Cluster ,
98
57
publisher : string
99
58
) => {
100
- const start = performance . now ( ) ;
101
- const data = await getFeedsCached ( cluster ) ; // uses cache
102
- const end = performance . now ( ) ;
103
- // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions
104
- console . log ( `getFeedsForPublisherCached: ${ end - start } ms.` ) ;
59
+ const data = await getFeedsCached ( cluster ) ;
105
60
return priceFeedsSchema . parse (
106
61
data . filter ( ( { price } ) =>
107
62
price . priceComponents . some (
108
63
( component ) => component . publisher . toString ( ) === publisher
109
64
)
110
65
)
111
66
) ;
112
- } ;
67
+ } ;
0 commit comments