mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
Draft: Setup subsriptions for backend+frontend
Please clean up this commit and squash it later on.
This commit is contained in:
parent
1a93fcc023
commit
3be5dee08b
@ -96,6 +96,7 @@
|
||||
"request": "~2.88.0",
|
||||
"sanitize-html": "~1.21.1",
|
||||
"slug": "~2.1.0",
|
||||
"subscriptions-transport-ws": "^0.9.16",
|
||||
"trunc-html": "~1.1.2",
|
||||
"uuid": "~3.4.0",
|
||||
"validator": "^12.1.0",
|
||||
|
||||
@ -49,6 +49,7 @@ export const serverConfigs = {
|
||||
CLIENT_URI,
|
||||
GRAPHQL_URI,
|
||||
PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION === 'true',
|
||||
SUBSCRIPTIONS_PATH: '/subscriptions',
|
||||
}
|
||||
|
||||
export const developmentConfigs = {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import createServer from './server'
|
||||
import CONFIG from './config'
|
||||
|
||||
const { app } = createServer()
|
||||
const { app, server, httpServer } = createServer()
|
||||
const url = new URL(CONFIG.GRAPHQL_URI)
|
||||
app.listen({ port: url.port }, () => {
|
||||
httpServer.listen({ port: url.port }, () => {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.log(`GraphQLServer ready at ${CONFIG.GRAPHQL_URI} 🚀`)
|
||||
console.log(`🚀 Server ready at http://localhost:${url.port}${server.graphqlPath}`)
|
||||
console.log(`🚀 Subscriptions ready at ws://localhost:${url.port}${server.subscriptionsPath}`)
|
||||
})
|
||||
|
||||
@ -5,6 +5,11 @@ import { UserInputError } from 'apollo-server'
|
||||
import fileUpload from './fileUpload'
|
||||
import Resolver from './helpers/Resolver'
|
||||
import { filterForMutedUsers } from './helpers/filterForMutedUsers'
|
||||
import { PubSub } from 'apollo-server'
|
||||
|
||||
const pubsub = new PubSub();
|
||||
const POST_ADDED = 'POST_ADDED';
|
||||
|
||||
|
||||
const maintainPinnedPosts = params => {
|
||||
const pinnedPostFilter = { pinned: true }
|
||||
@ -17,6 +22,12 @@ const maintainPinnedPosts = params => {
|
||||
}
|
||||
|
||||
export default {
|
||||
Subscription: {
|
||||
postAdded: {
|
||||
// Additional event labels can be passed to asyncIterator creation
|
||||
subscribe: () => pubsub.asyncIterator([POST_ADDED]),
|
||||
},
|
||||
},
|
||||
Query: {
|
||||
Post: async (object, params, context, resolveInfo) => {
|
||||
params = await filterForMutedUsers(params, context)
|
||||
@ -102,6 +113,7 @@ export default {
|
||||
})
|
||||
try {
|
||||
const [post] = await writeTxResultPromise
|
||||
pubsub.publish(POST_ADDED, { postAdded: post });
|
||||
return post
|
||||
} catch (e) {
|
||||
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
type Subscription {
|
||||
postAdded: Post
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
# Get a JWT Token for the given Email and password
|
||||
login(email: String!, password: String!): String!
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import express from 'express'
|
||||
import http from 'http'
|
||||
import helmet from 'helmet'
|
||||
import { ApolloServer } from 'apollo-server-express'
|
||||
|
||||
|
||||
import CONFIG from './config'
|
||||
import middleware from './middleware'
|
||||
import { getNeode, getDriver } from './db/neo4j'
|
||||
@ -8,19 +11,28 @@ import decode from './jwt/decode'
|
||||
import schema from './schema'
|
||||
import webfinger from './activitypub/routes/webfinger'
|
||||
|
||||
|
||||
const driver = getDriver()
|
||||
const neode = getNeode()
|
||||
|
||||
export const context = async ({ req }) => {
|
||||
const user = await decode(driver, req.headers.authorization)
|
||||
return {
|
||||
driver,
|
||||
neode,
|
||||
user,
|
||||
req,
|
||||
cypherParams: {
|
||||
currentUserId: user ? user.id : null,
|
||||
},
|
||||
const getContext = async (req) => {
|
||||
const user = await decode(driver, req.headers.authorization)
|
||||
return {
|
||||
driver,
|
||||
neode,
|
||||
user,
|
||||
req,
|
||||
cypherParams: {
|
||||
currentUserId: user ? user.id : null,
|
||||
},
|
||||
}
|
||||
}
|
||||
export const context = async (options) => {
|
||||
const { connection, req } = options
|
||||
if (connection) {
|
||||
return connection.context
|
||||
} else {
|
||||
return getContext(req)
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +40,12 @@ const createServer = options => {
|
||||
const defaults = {
|
||||
context,
|
||||
schema: middleware(schema),
|
||||
subscriptions: {
|
||||
onConnect: (connectionParams, webSocket) => {
|
||||
console.log('connectionParams', connectionParams)
|
||||
return getContext(connectionParams)
|
||||
},
|
||||
},
|
||||
debug: !!CONFIG.DEBUG,
|
||||
tracing: !!CONFIG.DEBUG,
|
||||
formatError: error => {
|
||||
@ -46,8 +64,11 @@ const createServer = options => {
|
||||
app.use('/.well-known/', webfinger())
|
||||
app.use(express.static('public'))
|
||||
server.applyMiddleware({ app, path: '/' })
|
||||
const httpServer = http.createServer(app);
|
||||
server.installSubscriptionHandlers(httpServer);
|
||||
|
||||
return { server, app }
|
||||
|
||||
return { server, httpServer, app }
|
||||
}
|
||||
|
||||
export default createServer
|
||||
|
||||
@ -1175,7 +1175,7 @@
|
||||
url-regex "~4.1.1"
|
||||
video-extensions "~1.1.0"
|
||||
|
||||
"@metascraper/helpers@^5.10.5", "@metascraper/helpers@^5.10.6":
|
||||
"@metascraper/helpers@^5.10.6":
|
||||
version "5.10.6"
|
||||
resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.10.6.tgz#0b786607212925a577926fd0cd0313a49de3499c"
|
||||
integrity sha512-/jvhlM3RKGYMoUK8D8S1r3tN03/EYizCqWF7zDx0aBMC8Ihp33DRGs9oNdsgkgwzVF7O/YpDm55l9K+qVJlsyQ==
|
||||
@ -7918,6 +7918,11 @@ serve-static@1.14.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
|
||||
integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
|
||||
dependencies:
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
parseurl "~1.3.3"
|
||||
send "0.17.1"
|
||||
|
||||
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
||||
version "2.0.0"
|
||||
|
||||
@ -74,6 +74,16 @@ import { mapGetters, mapMutations } from 'vuex'
|
||||
import { filterPosts } from '~/graphql/PostQuery.js'
|
||||
import PostMutations from '~/graphql/PostMutations'
|
||||
import UpdateQuery from '~/components/utils/UpdateQuery'
|
||||
import gql from 'graphql-tag'
|
||||
import {
|
||||
userFragment,
|
||||
postFragment,
|
||||
commentFragment,
|
||||
postCountsFragment,
|
||||
userCountsFragment,
|
||||
locationAndBadgesFragment,
|
||||
tagsCategoriesAndPinnedFragment,
|
||||
} from '~/graphql/Fragments'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -213,6 +223,36 @@ export default {
|
||||
this.posts = Post
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
subscribeToMore: {
|
||||
document: gql`
|
||||
${userFragment}
|
||||
${userCountsFragment}
|
||||
${locationAndBadgesFragment('EN')}
|
||||
${postFragment}
|
||||
${postCountsFragment}
|
||||
${tagsCategoriesAndPinnedFragment}
|
||||
|
||||
subscription Post {
|
||||
postAdded {
|
||||
...post
|
||||
...postCounts
|
||||
...tagsCategoriesAndPinned
|
||||
author {
|
||||
...user
|
||||
...userCounts
|
||||
...locationAndBadges
|
||||
}
|
||||
}
|
||||
}`,
|
||||
// Mutate the previous result
|
||||
updateQuery: (previousResult, { subscriptionData }) => {
|
||||
console.log('previousResult', previousResult)
|
||||
console.log('subscriptionData', subscriptionData)
|
||||
const { data: { postAdded: newPost } } = subscriptionData
|
||||
return { Post: [newPost, ...previousResult.Post] }
|
||||
// Here, return the new result from the previous with the new data
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ export default ({ app }) => {
|
||||
const backendUrl = process.env.GRAPHQL_URI || 'http://localhost:4000'
|
||||
|
||||
return {
|
||||
wsEndpoint: 'ws://localhost:4000/graphql', // optional
|
||||
httpEndpoint: process.server ? backendUrl : '/api',
|
||||
httpLinkOptions: {
|
||||
credentials: 'same-origin',
|
||||
@ -16,7 +17,7 @@ export default ({ app }) => {
|
||||
credentials: true,
|
||||
tokenName: 'human-connection-token',
|
||||
persisting: false,
|
||||
websocketsOnly: false,
|
||||
websocketsOnly: true,
|
||||
cache: new InMemoryCache({ fragmentMatcher }),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user