1- import type { Channel , Event , StreamChat } from 'stream-chat' ;
1+ import type {
2+ Channel ,
3+ ChannelMemberResponse ,
4+ Event ,
5+ MessageResponseBase ,
6+ ReactionResponse ,
7+ StreamChat ,
8+ UserResponse ,
9+ } from 'stream-chat' ;
210
311import {
412 type SupportedWebsocketEventType ,
@@ -7,7 +15,17 @@ import {
715} from './websocketEventTemplates' ;
816import type { SimulationState , SimulationUser } from './types' ;
917
10- type JsonObject = Record < string , unknown > ;
18+ type UnknownRecord = Record < string , unknown > ;
19+ type EventPayload = Omit <
20+ Partial < Event > ,
21+ 'channel' | 'member' | 'message' | 'reaction' | 'user'
22+ > & {
23+ channel ?: Partial < WebSocketEventTemplateContext [ 'channel' ] > ;
24+ member ?: ChannelMemberResponse ;
25+ message ?: Partial < MessageResponseBase > ;
26+ reaction ?: ReactionResponse ;
27+ user ?: UserResponse ;
28+ } ;
1129
1230const messageTextFragments = [
1331 'debug event payload' ,
@@ -19,12 +37,12 @@ const messageTextFragments = [
1937
2038const reactionTypes = [ 'love' , 'haha' , 'wow' , 'like' , 'sad' ] as const ;
2139
22- const asJsonObject = ( value : unknown ) : JsonObject | undefined => {
40+ const asJsonObject = ( value : unknown ) : UnknownRecord | undefined => {
2341 if ( ! value || typeof value !== 'object' || Array . isArray ( value ) ) {
2442 return undefined ;
2543 }
2644
27- return value as JsonObject ;
45+ return value as UnknownRecord ;
2846} ;
2947
3048const getId = ( value : unknown ) => {
@@ -44,10 +62,33 @@ const getMessageUser = (message: unknown) => asJsonObject(asJsonObject(message)?
4462const getMessageMember = ( message : unknown ) =>
4563 asJsonObject ( asJsonObject ( message ) ?. member ) ;
4664
65+ const asUserResponse = ( value : unknown ) : UserResponse | undefined => {
66+ const user = asJsonObject ( value ) ;
67+
68+ return typeof user ?. id === 'string' ? ( user as unknown as UserResponse ) : undefined ;
69+ } ;
70+
71+ const asChannelMemberResponse = ( value : unknown ) : ChannelMemberResponse | undefined => {
72+ const member = asJsonObject ( value ) ;
73+
74+ if ( ! member ) return undefined ;
75+
76+ const userId = getId ( member . user_id ) ?? getUserId ( member . user ) ;
77+
78+ return userId ? ( member as unknown as ChannelMemberResponse ) : undefined ;
79+ } ;
80+
4781const buildRandomMessageText = ( sequence : number ) =>
4882 `${ messageTextFragments [ sequence % messageTextFragments . length ] } #${ sequence } ` ;
4983
50- const buildReactionState = ( { reaction } : { reaction : JsonObject } ) : JsonObject => {
84+ const buildReactionState = ( {
85+ reaction,
86+ } : {
87+ reaction : ReactionResponse ;
88+ } ) : Pick <
89+ MessageResponseBase ,
90+ 'latest_reactions' | 'reaction_counts' | 'reaction_groups' | 'reaction_scores'
91+ > => {
5192 const reactionType = getId ( reaction . type ) ?? 'love' ;
5293 const reactionScore =
5394 typeof reaction . score === 'number' && Number . isFinite ( reaction . score )
@@ -99,7 +140,7 @@ const getChannelMembersForCid = (
99140 cid : string ,
100141 simulationState : SimulationState ,
101142 templateContext : WebSocketEventTemplateContext ,
102- ) => {
143+ ) : ChannelMemberResponse [ ] => {
103144 const knownMembers = Object . values ( simulationState . membersByCid [ cid ] ?? { } ) ;
104145
105146 if ( knownMembers . length > 0 ) {
@@ -121,7 +162,7 @@ const buildFreshContext = (
121162 templateContext ,
122163 ) ;
123164 const memberCount = channelMembers . length || templateContext . memberCount ;
124- const baseChannel = asJsonObject ( templateContext . channel ) ?? { } ;
165+ const baseChannel = templateContext . channel ;
125166
126167 return {
127168 ...templateContext ,
@@ -211,9 +252,9 @@ const registerUserAndMember = ({
211252 user,
212253} : {
213254 cid : string ;
214- member ?: JsonObject ;
255+ member ?: ChannelMemberResponse ;
215256 simulationState : SimulationState ;
216- user ?: JsonObject ;
257+ user ?: UserResponse ;
217258} ) => {
218259 if ( user ) {
219260 const userId = getUserId ( user ) ;
@@ -265,9 +306,9 @@ export const createInitialSimulationState = ({
265306
266307 registerUserAndMember ( {
267308 cid,
268- member : templateContext . actorMember ,
309+ member : templateContext . actorMember as ChannelMemberResponse ,
269310 simulationState : state ,
270- user : templateContext . actor ,
311+ user : templateContext . actor as UserResponse ,
271312 } ) ;
272313 registerUserAndMember ( {
273314 cid,
@@ -283,9 +324,9 @@ export const createInitialSimulationState = ({
283324
284325 registerUserAndMember ( {
285326 cid,
286- member : memberObject ,
327+ member : asChannelMemberResponse ( memberObject ) ,
287328 simulationState : state ,
288- user : userObject ,
329+ user : asUserResponse ( userObject ) ,
289330 } ) ;
290331 } ) ;
291332
@@ -304,9 +345,9 @@ export const createInitialSimulationState = ({
304345
305346 registerUserAndMember ( {
306347 cid,
307- member : getMessageMember ( messageObject ) ,
348+ member : asChannelMemberResponse ( getMessageMember ( messageObject ) ) ,
308349 simulationState : state ,
309- user : getMessageUser ( messageObject ) ,
350+ user : asUserResponse ( getMessageUser ( messageObject ) ) ,
310351 } ) ;
311352 } ) ;
312353
@@ -321,11 +362,11 @@ export const buildFreshWebSocketEventPayload = ({
321362 eventType : SupportedWebsocketEventType ;
322363 simulationState : SimulationState ;
323364 templateContext : WebSocketEventTemplateContext ;
324- } ) : JsonObject => {
365+ } ) : EventPayload => {
325366 const freshContext = buildFreshContext ( templateContext , simulationState ) ;
326367 const basePayload = websocketEventTemplateDefinitions [ eventType ] . buildDefault (
327368 freshContext ,
328- ) as JsonObject ;
369+ ) as EventPayload ;
329370
330371 switch ( eventType ) {
331372 case 'message.new' :
@@ -470,15 +511,15 @@ export const trackSimulationStateFromPayload = ({
470511
471512 registerUserAndMember ( {
472513 cid,
473- member : asJsonObject ( payload . member ) ,
514+ member : asChannelMemberResponse ( payload . member ) ,
474515 simulationState,
475- user : asJsonObject ( payload . user ) ,
516+ user : asUserResponse ( payload . user ) ,
476517 } ) ;
477518 registerUserAndMember ( {
478519 cid,
479- member : getMessageMember ( message ) ,
520+ member : asChannelMemberResponse ( getMessageMember ( message ) ) ,
480521 simulationState,
481- user : getMessageUser ( message ) ,
522+ user : asUserResponse ( getMessageUser ( message ) ) ,
482523 } ) ;
483524
484525 const channelObject = asJsonObject ( payload . channel ) ;
@@ -493,9 +534,9 @@ export const trackSimulationStateFromPayload = ({
493534
494535 registerUserAndMember ( {
495536 cid,
496- member,
537+ member : asChannelMemberResponse ( member ) ,
497538 simulationState,
498- user : asJsonObject ( member . user ) ,
539+ user : asUserResponse ( member . user ) ,
499540 } ) ;
500541 } ) ;
501542 }
@@ -510,14 +551,14 @@ export const emitWebSocketEventPayload = ({
510551} : {
511552 client : StreamChat ;
512553 eventType : SupportedWebsocketEventType ;
513- payload : Event ;
554+ payload : EventPayload ;
514555 simulationState : SimulationState ;
515556 templateContext : WebSocketEventTemplateContext ;
516557} ) => {
517- const emittedPayload : Event = {
558+ const emittedPayload = {
518559 ...payload ,
519560 type : eventType ,
520- } ;
561+ } as Event ;
521562
522563 client . dispatchEvent ( emittedPayload ) ;
523564
0 commit comments