@@ -91,44 +91,40 @@ const sortObjectByKeys = <T extends Record<string, unknown>>(
91
91
) : Array < [ string , unknown ] > =>
92
92
Object . entries ( obj ) . sort ( ( [ a ] , [ b ] ) => a . localeCompare ( b ) ) ;
93
93
94
+ /**
95
+ * Helper function to transform object values
96
+ */
97
+ const mapValues = < T , U > (
98
+ obj : Record < string , T > ,
99
+ fn : ( value : T ) => U ,
100
+ ) : Record < string , U > =>
101
+ Object . fromEntries (
102
+ Object . entries ( obj ) . map ( ( [ key , value ] ) => [ key , fn ( value ) ] ) ,
103
+ ) ;
104
+
94
105
/**
95
106
* Sort configuration data for consistent output
96
107
*/
97
108
function sortData ( data : DownloadableConfig ) : DownloadableConfig {
98
- const sortedData : DownloadableConfig = { } ;
99
- const keys = Object . keys ( data ) . sort ( ) ;
100
- for ( const key of keys ) {
101
- const productData = data [ key ] ;
102
- const sortedKeyValues = sortObjectByKeys ( productData . metadata ) ;
103
-
104
- const sortedInnerData : DownloadableProduct = {
105
- address : productData . address ,
106
- metadata : Object . fromEntries ( sortedKeyValues ) as Omit <
107
- Product ,
108
- "price_account"
109
- > ,
110
- priceAccounts : [ ] ,
111
- } ;
112
-
113
- // Sort price accounts by address
114
- sortedInnerData . priceAccounts = [ ...productData . priceAccounts ]
115
- . sort ( ( a , b ) => a . address . localeCompare ( b . address ) )
116
- . map ( ( priceAccount ) => {
117
- const sortedPriceAccount : DownloadablePriceAccount = {
118
- address : priceAccount . address ,
119
- expo : priceAccount . expo ,
120
- minPub : priceAccount . minPub ,
121
- maxLatency : priceAccount . maxLatency ,
122
- publishers : [ ...priceAccount . publishers ] . sort ( ( a , b ) =>
123
- a . localeCompare ( b ) ,
124
- ) ,
125
- } ;
126
- return sortedPriceAccount ;
127
- } ) ;
128
-
129
- sortedData [ key ] = sortedInnerData ;
130
- }
131
- return sortedData ;
109
+ return mapValues ( data , ( productData : DownloadableProduct ) => ( {
110
+ address : productData . address ,
111
+ metadata : Object . fromEntries (
112
+ sortObjectByKeys ( productData . metadata ) ,
113
+ ) as Omit < Product , "price_account" > ,
114
+ priceAccounts : [ ...productData . priceAccounts ]
115
+ . sort ( ( a : DownloadablePriceAccount , b : DownloadablePriceAccount ) =>
116
+ a . address . localeCompare ( b . address ) ,
117
+ )
118
+ . map ( ( priceAccount : DownloadablePriceAccount ) => ( {
119
+ address : priceAccount . address ,
120
+ expo : priceAccount . expo ,
121
+ minPub : priceAccount . minPub ,
122
+ maxLatency : priceAccount . maxLatency ,
123
+ publishers : [ ...priceAccount . publishers ] . sort ( ( a : string , b : string ) =>
124
+ a . localeCompare ( b ) ,
125
+ ) ,
126
+ } ) ) ,
127
+ } ) ) ;
132
128
}
133
129
134
130
/**
@@ -149,73 +145,72 @@ export function getConfig(
149
145
) ;
150
146
151
147
// First pass: Extract price accounts
152
- const priceRawConfigs = Object . fromEntries (
153
- accounts
154
- . filter (
155
- ( account ) =>
156
- parsedBaseDataMap . get ( account . pubkey . toBase58 ( ) ) ?. type ===
157
- AccountType . Price ,
158
- )
159
- . map ( ( account ) => {
160
- const parsed = parsePriceData ( account . account . data ) ;
161
- return [
162
- account . pubkey . toBase58 ( ) ,
163
- {
164
- next : parsed . nextPriceAccountKey ,
165
- address : account . pubkey ,
166
- publishers : parsed . priceComponents
167
- . filter ( ( x ) => x . publisher !== null && x . publisher !== undefined )
168
- . map ( ( x ) => x . publisher ) ,
169
- expo : parsed . exponent ,
170
- minPub : parsed . minPublishers ,
171
- maxLatency : parsed . maxLatency ,
172
- } ,
173
- ] ;
174
- } ) ,
148
+ const priceAccounts = accounts . filter (
149
+ ( account ) =>
150
+ parsedBaseDataMap . get ( account . pubkey . toBase58 ( ) ) ?. type ===
151
+ AccountType . Price ,
152
+ ) ;
153
+
154
+ const priceRawConfigs = mapValues (
155
+ Object . fromEntries (
156
+ priceAccounts . map ( ( account ) => [ account . pubkey . toBase58 ( ) , account ] ) ,
157
+ ) ,
158
+ ( account ) => {
159
+ const parsed = parsePriceData ( account . account . data ) ;
160
+ return {
161
+ next : parsed . nextPriceAccountKey ,
162
+ address : account . pubkey ,
163
+ publishers : parsed . priceComponents
164
+ . filter ( ( x ) => x . publisher !== null && x . publisher !== undefined )
165
+ . map ( ( x ) => x . publisher ) ,
166
+ expo : parsed . exponent ,
167
+ minPub : parsed . minPublishers ,
168
+ maxLatency : parsed . maxLatency ,
169
+ } ;
170
+ } ,
175
171
) ;
176
172
177
173
// Second pass: Extract product accounts and link to price accounts
178
- const productRawConfigs = Object . fromEntries (
179
- accounts
180
- . filter (
181
- ( account ) =>
182
- parsedBaseDataMap . get ( account . pubkey . toBase58 ( ) ) ?. type ===
183
- AccountType . Product ,
184
- )
185
- . map ( ( account ) => {
186
- const parsed = parseProductData ( account . account . data ) ;
187
- const priceAccounts : PriceRawConfig [ ] = [ ] ;
188
-
189
- // Follow the linked list of price accounts
190
- if ( parsed . priceAccountKey ) {
191
- let priceAccountKey : string | undefined =
192
- parsed . priceAccountKey . toBase58 ( ) ;
193
- const processedPriceKeys = new Set < string > ( ) ;
194
-
195
- while (
196
- priceAccountKey &&
197
- ! processedPriceKeys . has ( priceAccountKey ) &&
198
- priceRawConfigs [ priceAccountKey ]
199
- ) {
200
- processedPriceKeys . add ( priceAccountKey ) ;
201
- const priceConfig : PriceRawConfig =
202
- priceRawConfigs [ priceAccountKey ] ;
203
- priceAccounts . push ( priceConfig ) ;
204
- priceAccountKey = priceConfig . next
205
- ? priceConfig . next . toBase58 ( )
206
- : undefined ;
207
- }
174
+ const productAccounts = accounts . filter (
175
+ ( account ) =>
176
+ parsedBaseDataMap . get ( account . pubkey . toBase58 ( ) ) ?. type ===
177
+ AccountType . Product ,
178
+ ) ;
179
+
180
+ const productRawConfigs = mapValues (
181
+ Object . fromEntries (
182
+ productAccounts . map ( ( account ) => [ account . pubkey . toBase58 ( ) , account ] ) ,
183
+ ) ,
184
+ ( account ) => {
185
+ const parsed = parseProductData ( account . account . data ) ;
186
+ const priceAccounts : PriceRawConfig [ ] = [ ] ;
187
+
188
+ // Follow the linked list of price accounts
189
+ if ( parsed . priceAccountKey ) {
190
+ let priceAccountKey : string | undefined =
191
+ parsed . priceAccountKey . toBase58 ( ) ;
192
+ const processedPriceKeys = new Set < string > ( ) ;
193
+
194
+ while (
195
+ priceAccountKey &&
196
+ ! processedPriceKeys . has ( priceAccountKey ) &&
197
+ priceRawConfigs [ priceAccountKey ]
198
+ ) {
199
+ processedPriceKeys . add ( priceAccountKey ) ;
200
+ const priceConfig : PriceRawConfig = priceRawConfigs [ priceAccountKey ] ;
201
+ priceAccounts . push ( priceConfig ) ;
202
+ priceAccountKey = priceConfig . next
203
+ ? priceConfig . next . toBase58 ( )
204
+ : undefined ;
208
205
}
206
+ }
209
207
210
- return [
211
- account . pubkey . toBase58 ( ) ,
212
- {
213
- priceAccounts,
214
- metadata : parsed . product ,
215
- address : account . pubkey ,
216
- } ,
217
- ] ;
218
- } ) ,
208
+ return {
209
+ priceAccounts,
210
+ metadata : parsed . product ,
211
+ address : account . pubkey ,
212
+ } ;
213
+ } ,
219
214
) ;
220
215
221
216
// Third pass: Extract mapping accounts and permission data
0 commit comments