graphql: Add datasources

Add a simple wrapper datasources around web/lib/firebase
This commit is contained in:
joy_void_joy 2022-07-20 17:28:13 +02:00
parent efab3de172
commit 35a811ceee
6 changed files with 136 additions and 0 deletions

View 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))
}
}

View 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

View File

@ -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,
})

View File

@ -0,0 +1,8 @@
import type { FirebaseAPI } from './datasources/firebaseAPI'
/* Context type */
export type contextType = {
dataSources: {
firebaseAPI: FirebaseAPI
}
}

View File

@ -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",

View File

@ -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"