1- /* eslint-disable @typescript-eslint/ban-types */
2- import {
3- attributeNotExists ,
4- equals ,
5- ConditionExpression ,
6- } from '@aws/dynamodb-expressions'
71import { parse , execute } from 'graphql'
8- import { MessageType } from 'graphql-ws'
9- import { Subscription } from '../model/Subscription'
10- import { ServerClosure } from '../types'
2+ import { MessageType , NextMessage } from 'graphql-ws'
3+ import { PubSubEvent , ServerClosure } from '../types'
114import { sendMessage } from '../utils/aws'
125import { constructContext } from '../utils/graphql'
6+ import { getFilteredSubs } from './getFilteredSubs'
137
14- type PubSubEvent = {
15- topic : string
16- payload : any
17- }
18-
19- export const publish = ( c : ServerClosure ) => async ( event : PubSubEvent ) => {
8+ export const publish = ( c : ServerClosure ) => async ( event : PubSubEvent ) : Promise < void > => {
209 const subscriptions = await getFilteredSubs ( c ) ( event )
2110 const iters = subscriptions . map ( async ( sub ) => {
2211 const payload = await execute (
@@ -29,86 +18,16 @@ export const publish = (c: ServerClosure) => async (event: PubSubEvent) => {
2918 undefined ,
3019 )
3120
21+ const message : NextMessage = {
22+ id : sub . subscriptionId ,
23+ type : MessageType . Next ,
24+ payload,
25+ }
26+
3227 await sendMessage ( c ) ( {
3328 ...sub . requestContext ,
34- message : {
35- id : sub . subscriptionId ,
36- type : MessageType . Next ,
37- payload,
38- } ,
29+ message,
3930 } )
4031 } )
41- return await Promise . all ( iters )
32+ await Promise . all ( iters )
4233}
43-
44- const getFilteredSubs =
45- ( c : Omit < ServerClosure , 'gateway' > ) =>
46- async ( event : PubSubEvent ) : Promise < Subscription [ ] > => {
47- const flattenPayload = flatten ( event . payload )
48- const iterator = c . mapper . query (
49- c . model . Subscription ,
50- { topic : equals ( event . topic ) } ,
51- {
52- filter : {
53- type : 'And' ,
54- conditions : Object . entries ( flattenPayload ) . reduce (
55- ( p , [ key , value ] ) => [
56- ...p ,
57- {
58- type : 'Or' ,
59- conditions : [
60- {
61- ...attributeNotExists ( ) ,
62- subject : `filter.${ key } ` ,
63- } ,
64- {
65- ...equals ( value ) ,
66- subject : `filter.${ key } ` ,
67- } ,
68- ] ,
69- } ,
70- ] ,
71- [ ] as ConditionExpression [ ] ,
72- ) ,
73- } ,
74- indexName : 'TopicIndex' ,
75- } ,
76- )
77-
78- // Aggregate all targets
79- const subs : Subscription [ ] = [ ]
80- for await ( const sub of iterator ) {
81- subs . push ( sub )
82- }
83-
84- return subs
85- }
86-
87- export const flatten = (
88- obj : object ,
89- ) : Record < string , number | string | boolean > =>
90- Object . entries ( obj ) . reduce ( ( p , [ k1 , v1 ] ) => {
91- if ( v1 && typeof v1 === 'object' ) {
92- const next = Object . entries ( v1 ) . reduce (
93- ( prev , [ k2 , v2 ] ) => ( {
94- ...prev ,
95- [ `${ k1 } .${ k2 } ` ] : v2 ,
96- } ) ,
97- { } ,
98- )
99- return {
100- ...p ,
101- ...flatten ( next ) ,
102- }
103- }
104-
105- if (
106- typeof v1 === 'string' ||
107- typeof v1 === 'number' ||
108- typeof v1 === 'boolean'
109- ) {
110- return { ...p , [ k1 ] : v1 }
111- }
112-
113- return p
114- } , { } )
0 commit comments