chore: refactor pub/sub iterator usage across schema files
- Updated pub/sub iterator methods from `asyncIterableIterator` to `asyncIterator` in multiple schema files for improved compatibility with the latest GraphQL subscriptions. - Refactored subscription logic in CollaborationSession, Document, Message, User, and other schema files to enhance readability and maintainability. - Adjusted imports in GraphQL builder to utilize RedisPubSub for better performance in subscription handling.
This commit is contained in:
@@ -324,7 +324,9 @@ export class CollaborationSessionSchema extends PothosSchema {
|
|||||||
if (!collaborationSession) {
|
if (!collaborationSession) {
|
||||||
throw new Error('Collaboration session not found')
|
throw new Error('Collaboration session not found')
|
||||||
}
|
}
|
||||||
return ctx.websocket.pubSub.asyncIterableIterator(`collaborationSessionUpdated:${collaborationSession.id}`)
|
return ctx.websocket.pubSub.asyncIterator([
|
||||||
|
`collaborationSessionUpdated:${collaborationSession.id}`,
|
||||||
|
]) as unknown as AsyncIterable<CollaborationSession>
|
||||||
},
|
},
|
||||||
resolve: async (payload: CollaborationSession) => payload,
|
resolve: async (payload: CollaborationSession) => payload,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -447,9 +447,6 @@ export class DocumentSchema extends PothosSchema {
|
|||||||
if (!ctx.isSubscription) {
|
if (!ctx.isSubscription) {
|
||||||
throw new Error('Not allowed')
|
throw new Error('Not allowed')
|
||||||
}
|
}
|
||||||
const {
|
|
||||||
websocket: { pubSub },
|
|
||||||
} = ctx
|
|
||||||
const documentId = args.documentId
|
const documentId = args.documentId
|
||||||
// check user permission
|
// check user permission
|
||||||
const document = await this.prisma.document.findUnique({
|
const document = await this.prisma.document.findUnique({
|
||||||
@@ -469,7 +466,7 @@ export class DocumentSchema extends PothosSchema {
|
|||||||
throw new Error('User is not owner or collaborator of document')
|
throw new Error('User is not owner or collaborator of document')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pubSub.asyncIterableIterator([
|
return ctx.websocket.pubSub.asyncIterator([
|
||||||
`${DocumentEvent.CHANGED}.${documentId}`,
|
`${DocumentEvent.CHANGED}.${documentId}`,
|
||||||
`${DocumentEvent.DELETED}.${documentId}`,
|
`${DocumentEvent.DELETED}.${documentId}`,
|
||||||
`${DocumentEvent.SAVED}.${documentId}`,
|
`${DocumentEvent.SAVED}.${documentId}`,
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import { User } from '@prisma/client'
|
|||||||
import { JsonValue } from '@prisma/client/runtime/library'
|
import { JsonValue } from '@prisma/client/runtime/library'
|
||||||
import { Request, Response } from 'express'
|
import { Request, Response } from 'express'
|
||||||
import { Kind, ValueNode } from 'graphql'
|
import { Kind, ValueNode } from 'graphql'
|
||||||
|
import { RedisPubSub } from 'graphql-redis-subscriptions'
|
||||||
import { JSONObjectResolver } from 'graphql-scalars'
|
import { JSONObjectResolver } from 'graphql-scalars'
|
||||||
import { PubSub } from 'graphql-subscriptions'
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'
|
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -30,7 +30,7 @@ export type SchemaContext =
|
|||||||
isSubscription: true
|
isSubscription: true
|
||||||
websocket: {
|
websocket: {
|
||||||
req: Request
|
req: Request
|
||||||
pubSub: PubSub
|
pubSub: RedisPubSub
|
||||||
sessionId: string
|
sessionId: string
|
||||||
me: User
|
me: User
|
||||||
generator: PrismaCrudGenerator<BuilderTypes>
|
generator: PrismaCrudGenerator<BuilderTypes>
|
||||||
@@ -42,7 +42,7 @@ export type SchemaContext =
|
|||||||
req: Request
|
req: Request
|
||||||
res: Response
|
res: Response
|
||||||
me: User | null
|
me: User | null
|
||||||
pubSub: PubSub
|
pubSub: RedisPubSub
|
||||||
invalidateCache: () => Promise<void>
|
invalidateCache: () => Promise<void>
|
||||||
generator: PrismaCrudGenerator<BuilderTypes>
|
generator: PrismaCrudGenerator<BuilderTypes>
|
||||||
}
|
}
|
||||||
@@ -101,8 +101,8 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
|
|||||||
debounceDelay: 1000,
|
debounceDelay: 1000,
|
||||||
...subscribeOptionsFromIterator((name, context) => {
|
...subscribeOptionsFromIterator((name, context) => {
|
||||||
return context.isSubscription
|
return context.isSubscription
|
||||||
? context.websocket.pubSub.asyncIterableIterator(name)
|
? context.websocket.pubSub.asyncIterator(name)
|
||||||
: context.http.pubSub.asyncIterableIterator(name)
|
: context.http.pubSub.asyncIterator(name)
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
zod: {
|
zod: {
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ import { GraphqlService } from './graphql.service'
|
|||||||
}
|
}
|
||||||
// @ts-expect-error: Request is not typed
|
// @ts-expect-error: Request is not typed
|
||||||
ctx.extra.request.headers['x-session-id'] = ctx.connectionParams['x-session-id']
|
ctx.extra.request.headers['x-session-id'] = ctx.connectionParams['x-session-id']
|
||||||
|
// @ts-expect-error: Request is not typed
|
||||||
|
Logger.log(ctx.extra.request.headers['x-session-id'], 'Session ID')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -197,10 +197,9 @@ export class MessageSchema extends PothosSchema {
|
|||||||
if (!ctx.isSubscription) {
|
if (!ctx.isSubscription) {
|
||||||
throw new Error('Not allowed')
|
throw new Error('Not allowed')
|
||||||
}
|
}
|
||||||
const {
|
return ctx.websocket.pubSub.asyncIterator([
|
||||||
websocket: { pubSub },
|
`${PubSubEvent.MESSAGE_SENT}.${args.chatRoomId}`,
|
||||||
} = ctx
|
]) as unknown as AsyncIterable<Message>
|
||||||
return pubSub.asyncIterableIterator([`${PubSubEvent.MESSAGE_SENT}.${args.chatRoomId}`])
|
|
||||||
},
|
},
|
||||||
resolve: (payload: Message) => payload,
|
resolve: (payload: Message) => payload,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { clerkClient } from '@clerk/express'
|
import { clerkClient } from '@clerk/express'
|
||||||
import { Inject, Injectable, Logger } from '@nestjs/common'
|
import { Inject, Injectable, Logger } from '@nestjs/common'
|
||||||
import { ChatRoom, Message, MessageContextType, MessageType, Role } from '@prisma/client'
|
import { Message, Role } from '@prisma/client'
|
||||||
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
|
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
|
||||||
import { ChatroomSchema } from '../ChatRoom/chatroom.schema'
|
import { ChatroomSchema } from '../ChatRoom/chatroom.schema'
|
||||||
import { Builder, SchemaContext } from '../Graphql/graphql.builder'
|
import { Builder, SchemaContext } from '../Graphql/graphql.builder'
|
||||||
@@ -547,17 +547,15 @@ export class UserSchema extends PothosSchema {
|
|||||||
this.builder.subscriptionFields((t) => ({
|
this.builder.subscriptionFields((t) => ({
|
||||||
userScopedMessage: t.field({
|
userScopedMessage: t.field({
|
||||||
type: this.messageSchema.message(),
|
type: this.messageSchema.message(),
|
||||||
subscribe: async (_, _args, ctx: SchemaContext) => {
|
subscribe: async (_, _args, ctx) => {
|
||||||
if (!ctx.isSubscription) {
|
if (!ctx.isSubscription) {
|
||||||
throw new Error('Not allowed')
|
throw new Error('Not allowed')
|
||||||
}
|
}
|
||||||
const {
|
|
||||||
websocket: { pubSub },
|
return ctx.websocket.pubSub.asyncIterator([
|
||||||
} = ctx
|
|
||||||
return pubSub.asyncIterableIterator([
|
|
||||||
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
|
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
|
||||||
`${PubSubEvent.NOTIFICATION}.${ctx.websocket.me?.id}`,
|
`${PubSubEvent.NOTIFICATION}.${ctx.websocket.me?.id}`,
|
||||||
])
|
]) as unknown as AsyncIterable<Message>
|
||||||
},
|
},
|
||||||
resolve: async (payload: Message) => payload,
|
resolve: async (payload: Message) => payload,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user