Bluesky app fork with some witchin' additions ๐Ÿ’ซ

[๐Ÿด] Simplify message passing, cleanup (#3952)

* Simplify message passing

* Setup/teardown events

authored by

Eric Bailey and committed by
GitHub
f84a2def ab21aafc

+85 -87
+36 -6
src/state/messages/convo/agent.ts
··· 107 107 } else { 108 108 DEBUG_ACTIVE_CHAT = this.convoId 109 109 } 110 - 111 - this.events.trailConvo(this.convoId, events => { 112 - this.ingestFirehose(events) 113 - }) 114 - this.events.onConnect(this.onFirehoseConnect) 115 - this.events.onError(this.onFirehoseError) 116 110 } 117 111 118 112 private commit() { ··· 211 205 case ConvoDispatchEvent.Init: { 212 206 this.status = ConvoStatus.Initializing 213 207 this.setup() 208 + this.setupFirehose() 214 209 this.requestPollInterval(ACTIVE_POLL_INTERVAL) 215 210 break 216 211 } ··· 232 227 } 233 228 case ConvoDispatchEvent.Suspend: { 234 229 this.status = ConvoStatus.Suspended 230 + this.cleanupFirehoseConnection?.() 235 231 this.withdrawRequestedPollInterval() 236 232 break 237 233 } 238 234 case ConvoDispatchEvent.Error: { 239 235 this.status = ConvoStatus.Error 240 236 this.error = action.payload 237 + this.cleanupFirehoseConnection?.() 241 238 this.withdrawRequestedPollInterval() 242 239 break 243 240 } ··· 258 255 } 259 256 case ConvoDispatchEvent.Suspend: { 260 257 this.status = ConvoStatus.Suspended 258 + this.cleanupFirehoseConnection?.() 261 259 this.withdrawRequestedPollInterval() 262 260 break 263 261 } 264 262 case ConvoDispatchEvent.Error: { 265 263 this.status = ConvoStatus.Error 266 264 this.error = action.payload 265 + this.cleanupFirehoseConnection?.() 267 266 this.withdrawRequestedPollInterval() 268 267 break 269 268 } ··· 286 285 } 287 286 case ConvoDispatchEvent.Suspend: { 288 287 this.status = ConvoStatus.Suspended 288 + this.cleanupFirehoseConnection?.() 289 289 this.withdrawRequestedPollInterval() 290 290 break 291 291 } 292 292 case ConvoDispatchEvent.Error: { 293 293 this.status = ConvoStatus.Error 294 294 this.error = action.payload 295 + this.cleanupFirehoseConnection?.() 295 296 this.withdrawRequestedPollInterval() 296 297 break 297 298 } ··· 601 602 } 602 603 } 603 604 605 + private cleanupFirehoseConnection: (() => void) | undefined 606 + private setupFirehose() { 607 + // remove old listeners, if exist 608 + this.cleanupFirehoseConnection?.() 609 + 610 + // reconnect 611 + this.cleanupFirehoseConnection = this.events.on( 612 + event => { 613 + switch (event.type) { 614 + case 'connect': { 615 + this.onFirehoseConnect() 616 + break 617 + } 618 + case 'error': { 619 + this.onFirehoseError(event.error) 620 + break 621 + } 622 + case 'logs': { 623 + this.ingestFirehose(event.logs) 624 + break 625 + } 626 + } 627 + }, 628 + {convoId: this.convoId}, 629 + ) 630 + } 631 + 604 632 onFirehoseConnect() { 605 633 this.footerItems.delete(ConvoItemError.FirehoseFailed) 606 634 this.commit() ··· 709 737 id: tempId, 710 738 message, 711 739 }) 740 + // remove on each send, it might go through now without user having to click 741 + this.footerItems.delete(ConvoItemError.PendingFailed) 712 742 this.commit() 713 743 714 744 if (!this.isProcessingPendingMessages) {
+37 -66
src/state/messages/events/agent.ts
··· 8 8 import { 9 9 MessagesEventBusDispatch, 10 10 MessagesEventBusDispatchEvent, 11 - MessagesEventBusError, 12 11 MessagesEventBusErrorCode, 13 - MessagesEventBusEvents, 12 + MessagesEventBusEvent, 14 13 MessagesEventBusParams, 15 14 MessagesEventBusStatus, 16 15 } from '#/state/messages/events/types' ··· 22 21 23 22 private agent: BskyAgent 24 23 private __tempFromUserDid: string 25 - private emitter = new EventEmitter<MessagesEventBusEvents>() 24 + private emitter = new EventEmitter<{event: [MessagesEventBusEvent]}>() 26 25 27 26 private status: MessagesEventBusStatus = MessagesEventBusStatus.Initializing 28 - private error: MessagesEventBusError | undefined 29 27 private latestRev: string | undefined = undefined 30 28 private pollInterval = DEFAULT_POLL_INTERVAL 31 29 private requestedPollIntervals: Map<string, number> = new Map() ··· 52 50 } 53 51 } 54 52 55 - trail(handler: (events: ChatBskyConvoGetLog.OutputSchema['logs']) => void) { 56 - this.emitter.on('events', handler) 57 - return () => { 58 - this.emitter.off('events', handler) 59 - } 53 + getLatestRev() { 54 + return this.latestRev 60 55 } 61 56 62 - trailConvo( 63 - convoId: string, 64 - handler: (events: ChatBskyConvoGetLog.OutputSchema['logs']) => void, 57 + on( 58 + handler: (event: MessagesEventBusEvent) => void, 59 + options: { 60 + convoId?: string 61 + }, 65 62 ) { 66 - const handle = (events: ChatBskyConvoGetLog.OutputSchema['logs']) => { 67 - const convoEvents = events.filter(ev => { 68 - if (typeof ev.convoId === 'string' && ev.convoId === convoId) { 69 - return ev.convoId === convoId 70 - } 71 - return false 72 - }) 63 + const handle = (event: MessagesEventBusEvent) => { 64 + if (event.type === 'logs' && options.convoId) { 65 + const filteredLogs = event.logs.filter(log => { 66 + if ( 67 + typeof log.convoId === 'string' && 68 + log.convoId === options.convoId 69 + ) { 70 + return log.convoId === options.convoId 71 + } 72 + return false 73 + }) 73 74 74 - if (convoEvents.length > 0) { 75 - handler(convoEvents) 75 + if (filteredLogs.length > 0) { 76 + handler({ 77 + ...event, 78 + logs: filteredLogs, 79 + }) 80 + } 81 + } else { 82 + handler(event) 76 83 } 77 84 } 78 85 79 - this.emitter.on('events', handle) 80 - return () => { 81 - this.emitter.off('events', handle) 82 - } 83 - } 84 - 85 - getLatestRev() { 86 - return this.latestRev 87 - } 88 - 89 - onConnect(handler: () => void) { 90 - this.emitter.on('connect', handler) 91 - 92 - if ( 93 - this.status === MessagesEventBusStatus.Ready || 94 - this.status === MessagesEventBusStatus.Backgrounded || 95 - this.status === MessagesEventBusStatus.Suspended 96 - ) { 97 - handler() 98 - } 86 + this.emitter.on('event', handle) 99 87 100 88 return () => { 101 - this.emitter.off('connect', handler) 102 - } 103 - } 104 - 105 - onError(handler: (payload?: MessagesEventBusError) => void) { 106 - this.emitter.on('error', handler) 107 - 108 - if (this.status === MessagesEventBusStatus.Error) { 109 - handler(this.error) 110 - } 111 - 112 - return () => { 113 - this.emitter.off('error', handler) 89 + this.emitter.off('event', handle) 114 90 } 115 91 } 116 92 ··· 138 114 case MessagesEventBusDispatchEvent.Ready: { 139 115 this.status = MessagesEventBusStatus.Ready 140 116 this.resetPoll() 141 - this.emitter.emit('connect') 117 + this.emitter.emit('event', {type: 'connect'}) 142 118 break 143 119 } 144 120 case MessagesEventBusDispatchEvent.Background: { 145 121 this.status = MessagesEventBusStatus.Backgrounded 146 122 this.resetPoll() 147 - this.emitter.emit('connect') 123 + this.emitter.emit('event', {type: 'connect'}) 148 124 break 149 125 } 150 126 case MessagesEventBusDispatchEvent.Suspend: { ··· 153 129 } 154 130 case MessagesEventBusDispatchEvent.Error: { 155 131 this.status = MessagesEventBusStatus.Error 156 - this.error = action.payload 157 - this.emitter.emit('error', action.payload) 132 + this.emitter.emit('event', {type: 'error', error: action.payload}) 158 133 break 159 134 } 160 135 } ··· 174 149 } 175 150 case MessagesEventBusDispatchEvent.Error: { 176 151 this.status = MessagesEventBusStatus.Error 177 - this.error = action.payload 178 152 this.stopPoll() 179 - this.emitter.emit('error', action.payload) 153 + this.emitter.emit('event', {type: 'error', error: action.payload}) 180 154 break 181 155 } 182 156 case MessagesEventBusDispatchEvent.UpdatePoll: { ··· 200 174 } 201 175 case MessagesEventBusDispatchEvent.Error: { 202 176 this.status = MessagesEventBusStatus.Error 203 - this.error = action.payload 204 177 this.stopPoll() 205 - this.emitter.emit('error', action.payload) 178 + this.emitter.emit('event', {type: 'error', error: action.payload}) 206 179 break 207 180 } 208 181 case MessagesEventBusDispatchEvent.UpdatePoll: { ··· 226 199 } 227 200 case MessagesEventBusDispatchEvent.Error: { 228 201 this.status = MessagesEventBusStatus.Error 229 - this.error = action.payload 230 202 this.stopPoll() 231 - this.emitter.emit('error', action.payload) 203 + this.emitter.emit('event', {type: 'error', error: action.payload}) 232 204 break 233 205 } 234 206 } ··· 239 211 case MessagesEventBusDispatchEvent.Resume: { 240 212 // basically reset 241 213 this.status = MessagesEventBusStatus.Initializing 242 - this.error = undefined 243 214 this.latestRev = undefined 244 215 this.init() 245 216 break ··· 403 374 404 375 if (needsEmit) { 405 376 try { 406 - this.emitter.emit('events', batch) 377 + this.emitter.emit('event', {type: 'logs', logs: batch}) 407 378 } catch (e: any) { 408 379 logger.error(e, { 409 380 context: `${LOGGER_CONTEXT}: process latest events`,
+12 -15
src/state/messages/events/types.ts
··· 55 55 event: MessagesEventBusDispatchEvent.UpdatePoll 56 56 } 57 57 58 - export type TrailHandler = ( 59 - events: ChatBskyConvoGetLog.OutputSchema['logs'], 60 - ) => void 61 - 62 - export type RequestPollIntervalHandler = (interval: number) => () => void 63 - export type OnConnectHandler = (handler: () => void) => () => void 64 - export type OnDisconnectHandler = ( 65 - handler: (error?: MessagesEventBusError) => void, 66 - ) => () => void 67 - 68 - export type MessagesEventBusEvents = { 69 - events: [ChatBskyConvoGetLog.OutputSchema['logs']] 70 - connect: undefined 71 - error: [MessagesEventBusError] | undefined 72 - } 58 + export type MessagesEventBusEvent = 59 + | { 60 + type: 'connect' 61 + } 62 + | { 63 + type: 'error' 64 + error: MessagesEventBusError 65 + } 66 + | { 67 + type: 'logs' 68 + logs: ChatBskyConvoGetLog.OutputSchema['logs'] 69 + }