feat: NFT GraphQL Feature Flag (#4969)
* add nft graphQl feature flag * connect flag to env provider * attempting metadata relay env switch * working config Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
This commit is contained in:
parent
5f431a1e26
commit
a21bbfd5a7
@ -1,5 +1,6 @@
|
|||||||
import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags'
|
import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags'
|
||||||
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
|
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
|
||||||
|
import { NftGraphQlVariant, useNftGraphQlFlag } from 'featureFlags/flags/nftGraphQl'
|
||||||
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
|
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
|
||||||
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
|
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
|
||||||
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
|
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
|
||||||
@ -204,6 +205,12 @@ export default function FeatureFlagModal() {
|
|||||||
</Header>
|
</Header>
|
||||||
<FeatureFlagGroup name="Phase 1">
|
<FeatureFlagGroup name="Phase 1">
|
||||||
<FeatureFlagOption variant={NftVariant} value={useNftFlag()} featureFlag={FeatureFlag.nft} label="NFTs" />
|
<FeatureFlagOption variant={NftVariant} value={useNftFlag()} featureFlag={FeatureFlag.nft} label="NFTs" />
|
||||||
|
<FeatureFlagOption
|
||||||
|
variant={NftGraphQlVariant}
|
||||||
|
value={useNftGraphQlFlag()}
|
||||||
|
featureFlag={FeatureFlag.nftGraphQl}
|
||||||
|
label="NFT GraphQL Endpoints"
|
||||||
|
/>
|
||||||
</FeatureFlagGroup>
|
</FeatureFlagGroup>
|
||||||
<FeatureFlagGroup name="Debug">
|
<FeatureFlagGroup name="Debug">
|
||||||
<FeatureFlagOption
|
<FeatureFlagOption
|
||||||
|
@ -3,4 +3,5 @@ export enum FeatureFlag {
|
|||||||
nft = 'nfts',
|
nft = 'nfts',
|
||||||
traceJsonRpc = 'traceJsonRpc',
|
traceJsonRpc = 'traceJsonRpc',
|
||||||
multiNetworkBalances = 'multiNetworkBalances',
|
multiNetworkBalances = 'multiNetworkBalances',
|
||||||
|
nftGraphQl = 'nftGraphQl',
|
||||||
}
|
}
|
||||||
|
7
src/featureFlags/flags/nftGraphQl.ts
Normal file
7
src/featureFlags/flags/nftGraphQl.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
|
||||||
|
|
||||||
|
export function useNftGraphQlFlag(): BaseVariant {
|
||||||
|
return useBaseFlag(FeatureFlag.nftGraphQl)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { BaseVariant as NftGraphQlVariant }
|
@ -1,41 +1,40 @@
|
|||||||
import ms from 'ms.macro'
|
import ms from 'ms.macro'
|
||||||
import { Variables } from 'react-relay'
|
import { Variables } from 'react-relay'
|
||||||
import { Environment, Network, RecordSource, RequestParameters, Store } from 'relay-runtime'
|
import { CacheConfig, Environment, Network, RecordSource, RequestParameters, Store } from 'relay-runtime'
|
||||||
import RelayQueryResponseCache from 'relay-runtime/lib/network/RelayQueryResponseCache'
|
import RelayQueryResponseCache from 'relay-runtime/lib/network/RelayQueryResponseCache'
|
||||||
|
|
||||||
import fetchGraphQL from './fetchGraphQL'
|
import fetchGraphQL from './fetchGraphQL'
|
||||||
|
|
||||||
// max number of request in cache, least-recently updated entries purged first
|
// max number of request in cache, least-recently updated entries purged first
|
||||||
const size = 250
|
const size = 250
|
||||||
// number in milliseconds, how long records stay valid in cache
|
// number in milliseconds, how long records stay valid in cache
|
||||||
const ttl = ms`5m`
|
const ttl = ms`5m`
|
||||||
export const cache = new RelayQueryResponseCache({ size, ttl })
|
export const cache = new RelayQueryResponseCache({ size, ttl })
|
||||||
|
|
||||||
const fetchQuery = async function wrappedFetchQuery(params: RequestParameters, variables: Variables) {
|
const fetchQuery = async function wrappedFetchQuery(
|
||||||
|
params: RequestParameters,
|
||||||
|
variables: Variables,
|
||||||
|
cacheConfig: CacheConfig
|
||||||
|
) {
|
||||||
const queryID = params.name
|
const queryID = params.name
|
||||||
const cachedData = cache.get(queryID, variables)
|
const cachedData = cache.get(queryID, variables)
|
||||||
|
|
||||||
if (cachedData !== null) return cachedData
|
if (cachedData !== null) return cachedData
|
||||||
|
|
||||||
return fetchGraphQL(params, variables).then((data) => {
|
return fetchGraphQL(params, variables, cacheConfig).then((data) => {
|
||||||
if (params.operationKind !== 'mutation') {
|
if (params.operationKind !== 'mutation') {
|
||||||
cache.set(queryID, variables, data)
|
cache.set(queryID, variables, data)
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This property tells Relay to not immediately clear its cache when the user
|
// This property tells Relay to not immediately clear its cache when the user
|
||||||
// navigates around the app. Relay will hold onto the specified number of
|
// navigates around the app. Relay will hold onto the specified number of
|
||||||
// query results, allowing the user to return to recently visited pages
|
// query results, allowing the user to return to recently visited pages
|
||||||
// and reusing cached data if its available/fresh.
|
// and reusing cached data if its available/fresh.
|
||||||
const gcReleaseBufferSize = 10
|
const gcReleaseBufferSize = 10
|
||||||
|
|
||||||
const queryCacheExpirationTime = ms`1m`
|
const queryCacheExpirationTime = ms`1m`
|
||||||
|
|
||||||
const store = new Store(new RecordSource(), { gcReleaseBufferSize, queryCacheExpirationTime })
|
const store = new Store(new RecordSource(), { gcReleaseBufferSize, queryCacheExpirationTime })
|
||||||
const network = Network.create(fetchQuery)
|
const network = Network.create(fetchQuery)
|
||||||
|
|
||||||
// Export a singleton instance of Relay Environment configured with our network function:
|
// Export a singleton instance of Relay Environment configured with our network function:
|
||||||
export default new Environment({
|
export default new Environment({
|
||||||
network,
|
network,
|
||||||
|
@ -1,22 +1,35 @@
|
|||||||
import { Variables } from 'react-relay'
|
import { Variables } from 'react-relay'
|
||||||
import { GraphQLResponse, RequestParameters } from 'relay-runtime'
|
import { CacheConfig, GraphQLResponse, RequestParameters } from 'relay-runtime'
|
||||||
|
|
||||||
const URL = process.env.REACT_APP_AWS_API_ENDPOINT
|
const URL = process.env.REACT_APP_AWS_API_ENDPOINT
|
||||||
|
const NFT_URL = process.env.REACT_APP_NFT_AWS_API_ENDPOINT ?? ''
|
||||||
|
|
||||||
if (!URL) {
|
if (!URL) {
|
||||||
throw new Error('AWS URL MISSING FROM ENVIRONMENT')
|
throw new Error('AWS URL MISSING FROM ENVIRONMENT')
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = {
|
const baseHeaders = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
}
|
}
|
||||||
const fetchQuery = (params: RequestParameters, variables: Variables): Promise<GraphQLResponse> => {
|
const nftHeaders = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-api-key': process.env.REACT_APP_NFT_AWS_X_API_KEY ?? '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchQuery = (
|
||||||
|
params: RequestParameters,
|
||||||
|
variables: Variables,
|
||||||
|
cacheConfig: CacheConfig
|
||||||
|
): Promise<GraphQLResponse> => {
|
||||||
|
const { metadata: { isNFT } = { isNFT: false } } = cacheConfig
|
||||||
const body = JSON.stringify({
|
const body = JSON.stringify({
|
||||||
query: params.text, // GraphQL text from input
|
query: params.text, // GraphQL text from input
|
||||||
variables,
|
variables,
|
||||||
})
|
})
|
||||||
|
const url = isNFT ? NFT_URL : URL
|
||||||
|
const headers = isNFT ? nftHeaders : baseHeaders
|
||||||
|
|
||||||
return fetch(URL, { method: 'POST', body, headers })
|
return fetch(url, { method: 'POST', body, headers })
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
Loading…
Reference in New Issue
Block a user