amazon-connect / amazon-connect-chat-interface

Amazon Connect Chat Interface - a browser-based customer chat widget for your website integrating with Amazon Connect ChatJS
https://docs.aws.amazon.com/connect/latest/adminguide/what-is-amazon-connect.html
MIT No Attribution
33 stars 35 forks source link

Modifying EventBus to handle duplicate handlers #114

Closed mliao95 closed 1 year ago

mliao95 commented 1 year ago

Issue #, if available:

Description:

What are the changes? Why are we making them?

This CR modifies the EventBus class to handle duplicate handler assignments. We see the issue that ChatContainer repeatedly registers a handler for initChat upon creation of the chat UI. For cases where amazon-connect-chat-interface.js is imported on the html level, the singleton instance persists through chat sessions which cause that initChat handler to be registered repeatedly.

By checking whether the handler has already been registered under an event, we can prevent handlers from being registered multiple times.

Old EventBus._eventMap structure:

// struct: Object
this._eventMap = {
  "initChat": [initHandlerFunc1, initHandlerFunc2, ...],
  "endChat": [endHandlerFunc1, endHandlerFunc2, ...]
}

New EventBus._eventMap structure:

In the new structure, we use another Map to store the handlers under each event category with the type Map <number, function>. The number here is a hash based off of the function. In general, we will stringify the function and then create a hash for that string to act as the identifying hash. If the hash already exists, we overwrite that hash's function.

In the case where bound handlers are passed into EventBus.on(...) (i.e. EventBus.on(myFunction.bind(this)), we cannot simply use the stringified version of the function since it will default to "myFunction() { [native code] }". In this case, we take the name of the function which will be "bound myFunction"and hash it based off the function name. The limitation here is the edge case where two bound functions with the exact same name cannot be registered under the same event.

// struct: Map<string, Map <number, function>>
this._eventMap = {
  "initChat": {
    {385832932: initHandlerFunc1},
    {341395234: initHandlerFunc2} 
  },
  "endChat": {
    {431932436: endHandlerFunc1},
    {483917294: endHandlerFunc2} 
  },
}

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.