graphql: Add datasources
Add a simple wrapper datasources around web/lib/firebase
This commit is contained in:
parent
efab3de172
commit
35a811ceee
108
web/lib/api/graphql/datasources/firebaseAPI.ts
Normal file
108
web/lib/api/graphql/datasources/firebaseAPI.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
import type { Contract, BinaryContract } from 'common/contract'
|
||||
|
||||
import { getOutcomeProbability, getProbability } from 'common/calculate'
|
||||
import { listAllBets } from 'web/lib/firebase/bets'
|
||||
import {
|
||||
getContractFromId,
|
||||
getContractFromSlug,
|
||||
listAllContracts,
|
||||
} from 'web/lib/firebase/contracts'
|
||||
import { listAllComments } from 'web/lib/firebase/comments'
|
||||
import { getUser } from 'web/lib/firebase/users'
|
||||
|
||||
import { DataSource } from 'apollo-datasource'
|
||||
import { InMemoryLRUCache, KeyValueCache } from 'apollo-server-caching'
|
||||
|
||||
/* Simple wrapper around web/lib/firebase functions */
|
||||
export class FirebaseAPI extends DataSource {
|
||||
cache: KeyValueCache
|
||||
context?: any
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.cache = null as any
|
||||
}
|
||||
|
||||
initialize({
|
||||
context,
|
||||
cache,
|
||||
}: { context?: any; cache?: KeyValueCache } = {}) {
|
||||
this.context = context
|
||||
this.cache = cache || new InMemoryLRUCache()
|
||||
}
|
||||
|
||||
didEncounterError(error: any) {
|
||||
throw error
|
||||
}
|
||||
|
||||
cacheKey(id: string | undefined, type: string) {
|
||||
return `firebaseapi-${type}-${id}`
|
||||
}
|
||||
|
||||
async get<T>(
|
||||
id: string | undefined,
|
||||
type: string,
|
||||
func: () => Promise<T>,
|
||||
{ ttlInSeconds = 200 }: { ttlInSeconds?: number } = {}
|
||||
): Promise<T> {
|
||||
const cacheDoc = await this.cache.get(this.cacheKey(id, type))
|
||||
if (cacheDoc) {
|
||||
return JSON.parse(cacheDoc)
|
||||
}
|
||||
|
||||
const doc = await func()
|
||||
|
||||
if (ttlInSeconds) {
|
||||
this.cache.set(this.cacheKey(id, type), JSON.stringify(doc), {
|
||||
ttl: ttlInSeconds,
|
||||
})
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
|
||||
async listAllBets(id: string) {
|
||||
return this.get(id, 'listAllBets', () => listAllBets(id))
|
||||
}
|
||||
|
||||
async getContractFromSlug(id: string) {
|
||||
return this.get(id, 'getContractFromSlug', () => getContractFromSlug(id))
|
||||
}
|
||||
|
||||
async getContractFromID(id: string) {
|
||||
return this.get(id, 'market', () => getContractFromId(id))
|
||||
}
|
||||
|
||||
async getOutcomeProbability(contract: Contract, answerID: string) {
|
||||
return this.get(answerID, 'getOutcomeProbability', () =>
|
||||
(async () => getOutcomeProbability(contract, answerID))()
|
||||
)
|
||||
}
|
||||
|
||||
async getProbability(contract: BinaryContract) {
|
||||
return this.get(contract.id, 'getProbability', () =>
|
||||
(async () => getProbability(contract))()
|
||||
)
|
||||
}
|
||||
|
||||
async listAllCommentAnswers(commentId: string, contractID: string) {
|
||||
return this.get(commentId, 'listAllCommentAnswers', async () => {
|
||||
const allComments = await this.listAllComments(contractID)
|
||||
return allComments.filter((c) => c.replyToCommentId === commentId)
|
||||
})
|
||||
}
|
||||
|
||||
async listAllComments(id: string) {
|
||||
return this.get(id, 'listAllComments', () => listAllComments(id))
|
||||
}
|
||||
|
||||
async listAllContracts(limit = 1000, before?: string) {
|
||||
return this.get(before, 'listAllContracts', () =>
|
||||
listAllContracts(limit, before)
|
||||
)
|
||||
}
|
||||
|
||||
async getUser(id: string) {
|
||||
return this.get(id, 'user', () => getUser(id))
|
||||
}
|
||||
}
|
10
web/lib/api/graphql/datasources/index.ts
Normal file
10
web/lib/api/graphql/datasources/index.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import type { contextType } from '../types'
|
||||
|
||||
import { FirebaseAPI } from './firebaseAPI'
|
||||
|
||||
const dataSources = () =>
|
||||
({
|
||||
firebaseAPI: new FirebaseAPI(),
|
||||
} as contextType['dataSources'])
|
||||
|
||||
export default dataSources
|
|
@ -1,6 +1,7 @@
|
|||
import { ApolloServer } from 'apollo-server-micro'
|
||||
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core'
|
||||
|
||||
import dataSources from './datasources'
|
||||
import resolvers from './resolvers'
|
||||
import typeDefs from 'web/generated/schema.graphql'
|
||||
|
||||
|
@ -9,6 +10,7 @@ export const apolloServer = new ApolloServer({
|
|||
cache: 'bounded',
|
||||
plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
|
||||
|
||||
dataSources,
|
||||
resolvers,
|
||||
typeDefs,
|
||||
})
|
||||
|
|
8
web/lib/api/graphql/types.ts
Normal file
8
web/lib/api/graphql/types.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import type { FirebaseAPI } from './datasources/firebaseAPI'
|
||||
|
||||
/* Context type */
|
||||
export type contextType = {
|
||||
dataSources: {
|
||||
firebaseAPI: FirebaseAPI
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@
|
|||
"@tiptap/react": "2.0.0-beta.114",
|
||||
"@tiptap/starter-kit": "2.0.0-beta.190",
|
||||
"algoliasearch": "4.13.0",
|
||||
"apollo-server-caching": "3.3.0",
|
||||
"apollo-server-micro": "3.10.0",
|
||||
"clsx": "1.1.1",
|
||||
"cors": "2.8.5",
|
||||
|
|
|
@ -4858,6 +4858,13 @@ apollo-reporting-protobuf@^3.3.1, apollo-reporting-protobuf@^3.3.2:
|
|||
dependencies:
|
||||
"@apollo/protobufjs" "1.2.4"
|
||||
|
||||
apollo-server-caching@3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-3.3.0.tgz#f501cbeb820a4201d98c2b768c085f22848d9dc5"
|
||||
integrity sha512-Wgcb0ArjZ5DjQ7ID+tvxUcZ7Yxdbk5l1MxZL8D8gkyjooOkhPNzjRVQ7ubPoXqO54PrOMOTm1ejVhsF+AfIirQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
apollo-server-core@^3.10.0:
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-3.10.0.tgz#6680b4eb4699829ed50d8a592721ee5e5e11e041"
|
||||
|
|
Loading…
Reference in New Issue
Block a user