2023-05-10 14:56:30 +00:00
|
|
|
import http from 'http'
|
|
|
|
import events from 'events'
|
|
|
|
import express from 'express'
|
2023-05-11 04:20:44 +00:00
|
|
|
import { DidResolver, MemoryCache } from '@atproto/did-resolver'
|
2023-05-10 14:56:30 +00:00
|
|
|
import { createServer } from './lexicon'
|
|
|
|
import feedGeneration from './feed-generation'
|
2023-05-11 04:00:44 +00:00
|
|
|
import { createDb, Database, migrateToLatest } from './db'
|
2023-05-10 14:56:30 +00:00
|
|
|
import { FirehoseSubscription } from './subscription'
|
2023-05-11 04:20:44 +00:00
|
|
|
import { AppContext, Config } from './config'
|
2023-05-10 14:56:30 +00:00
|
|
|
|
|
|
|
export class FeedGenerator {
|
|
|
|
public app: express.Application
|
|
|
|
public server?: http.Server
|
|
|
|
public db: Database
|
|
|
|
public firehose: FirehoseSubscription
|
|
|
|
public cfg: Config
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
app: express.Application,
|
|
|
|
db: Database,
|
|
|
|
firehose: FirehoseSubscription,
|
|
|
|
cfg: Config,
|
|
|
|
) {
|
|
|
|
this.app = app
|
|
|
|
this.db = db
|
|
|
|
this.firehose = firehose
|
|
|
|
this.cfg = cfg
|
|
|
|
}
|
|
|
|
|
|
|
|
static create(config?: Partial<Config>) {
|
2023-05-11 04:00:44 +00:00
|
|
|
const cfg: Config = {
|
2023-05-10 14:56:30 +00:00
|
|
|
port: config?.port ?? 3000,
|
2023-05-11 17:06:34 +00:00
|
|
|
sqliteLocation: config?.sqliteLocation ?? ':memory:',
|
2023-05-11 03:59:50 +00:00
|
|
|
subscriptionEndpoint: config?.subscriptionEndpoint ?? 'wss://bsky.social',
|
2023-05-11 04:20:44 +00:00
|
|
|
serviceDid: config?.serviceDid ?? 'did:example:test',
|
2023-05-10 14:56:30 +00:00
|
|
|
}
|
|
|
|
const app = express()
|
|
|
|
const db = createDb(cfg.sqliteLocation)
|
|
|
|
const firehose = new FirehoseSubscription(db, cfg.subscriptionEndpoint)
|
|
|
|
|
2023-05-11 04:20:44 +00:00
|
|
|
const didCache = new MemoryCache()
|
|
|
|
const didResolver = new DidResolver(
|
|
|
|
{ plcUrl: 'https://plc.directory' },
|
|
|
|
didCache,
|
|
|
|
)
|
|
|
|
|
2023-05-10 14:56:30 +00:00
|
|
|
const server = createServer({
|
|
|
|
validateResponse: true,
|
|
|
|
payload: {
|
|
|
|
jsonLimit: 100 * 1024, // 100kb
|
|
|
|
textLimit: 100 * 1024, // 100kb
|
|
|
|
blobLimit: 5 * 1024 * 1024, // 5mb
|
|
|
|
},
|
|
|
|
})
|
2023-05-11 04:20:44 +00:00
|
|
|
const ctx: AppContext = {
|
|
|
|
db,
|
|
|
|
didResolver,
|
|
|
|
cfg,
|
|
|
|
}
|
|
|
|
feedGeneration(server, ctx)
|
2023-05-10 14:56:30 +00:00
|
|
|
app.use(server.xrpc.router)
|
|
|
|
|
|
|
|
return new FeedGenerator(app, db, firehose, cfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
async start(): Promise<http.Server> {
|
2023-05-11 04:00:44 +00:00
|
|
|
await migrateToLatest(this.db)
|
|
|
|
this.firehose.run()
|
|
|
|
this.server = this.app.listen(this.cfg.port)
|
|
|
|
await events.once(this.server, 'listening')
|
|
|
|
return this.server
|
2023-05-10 14:56:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default FeedGenerator
|