1 import type { AbstractUIService
} from
'../ui-server/ui-services/AbstractUIService.js'
4 type BroadcastChannelResponse
,
5 type BroadcastChannelResponsePayload
,
9 } from
'../../types/index.js'
10 import { logger
} from
'../../utils/index.js'
11 import { WorkerBroadcastChannel
} from
'./WorkerBroadcastChannel.js'
13 const moduleName
= 'UIServiceWorkerBroadcastChannel'
16 responses
: BroadcastChannelResponsePayload
[]
17 responsesExpected
: number
18 responsesReceived
: number
21 export class UIServiceWorkerBroadcastChannel
extends WorkerBroadcastChannel
{
22 private readonly responses
: Map
<string, Responses
>
23 private readonly uiService
: AbstractUIService
25 constructor (uiService
: AbstractUIService
) {
27 this.uiService
= uiService
28 this.onmessage
= this.responseHandler
.bind(this) as (message
: unknown
) => void
29 this.onmessageerror
= this.messageErrorHandler
.bind(this) as (message
: unknown
) => void
30 this.responses
= new Map
<string, Responses
>()
33 private buildResponsePayload (uuid
: string): ResponsePayload
{
34 const responsesStatus
=
37 ?.responses
.every(({ status }) => status === ResponseStatus
.SUCCESS
) === true
38 ? ResponseStatus
.SUCCESS
39 : ResponseStatus
.FAILURE
41 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
42 hashIdsSucceeded
: this.responses
44 ?.responses
.map(({ hashId
, status }) => {
45 if (hashId
!= null && status === ResponseStatus
.SUCCESS
) {
50 .filter(hashId
=> hashId
!= null)!,
51 status: responsesStatus
,
52 ...(responsesStatus
=== ResponseStatus
.FAILURE
&& {
53 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
54 hashIdsFailed
: this.responses
56 ?.responses
.map(({ hashId
, status }) => {
57 if (hashId
!= null && status === ResponseStatus
.FAILURE
) {
62 .filter(hashId
=> hashId
!= null)!,
64 ...(responsesStatus
=== ResponseStatus
.FAILURE
&& {
65 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
66 responsesFailed
: this.responses
68 ?.responses
.map(response
=> {
69 if (response
.status === ResponseStatus
.FAILURE
) {
74 .filter(response
=> response
!= null)!,
79 private messageErrorHandler (messageEvent
: MessageEvent
): void {
81 `${this.uiService.logPrefix(moduleName, 'messageErrorHandler')} Error at handling message:`,
86 private responseHandler (messageEvent
: MessageEvent
): void {
87 const validatedMessageEvent
= this.validateMessageEvent(messageEvent
)
88 if (validatedMessageEvent
=== false) {
91 if (this.isRequest(validatedMessageEvent
.data
)) {
94 const [uuid
, responsePayload
] = validatedMessageEvent
.data
as BroadcastChannelResponse
95 if (!this.responses
.has(uuid
)) {
96 this.responses
.set(uuid
, {
97 responses
: [responsePayload
],
98 responsesExpected
: this.uiService
.getBroadcastChannelExpectedResponses(uuid
),
102 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
103 this.responses
.get(uuid
)!.responsesReceived
<= this.responses
.get(uuid
)!.responsesExpected
105 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
106 ++this.responses
.get(uuid
)!.responsesReceived
107 this.responses
.get(uuid
)?.responses
.push(responsePayload
)
110 this.responses
.get(uuid
)?.responsesReceived
=== this.responses
.get(uuid
)?.responsesExpected
112 this.uiService
.sendResponse(uuid
, this.buildResponsePayload(uuid
))
113 this.responses
.delete(uuid
)
114 this.uiService
.deleteBroadcastChannelRequest(uuid
)