Event System
Relevant source files
The following files were used as context for generating this wiki page:The consent-manager features a simple yet powerful event-driven system based on a publisher-subscriber pattern. This system allows different parts of the application to react to changes in user consent status without being tightly coupled to the core ConsentManager logic. When a user's consent preferences are updated, ConsentManager dispatches events that other modules, such as the DOMConnector and GrantsInterface, can listen for to update the UI or modify DOM attributes accordingly.
This decoupling is central to the library's modularity, enabling developers to create custom logic that responds to consent changes. The system supports registering and unregistering callback functions for specific event types.
Sources: src/modules/ConsentManager.ts:182-211, src/modules/DOMConnector.ts:4-6, src/modules/GrantsInterface.ts:110-114
Core Architecture
The event system is implemented within the ConsentManager class. It maintains a private property, eventListeners, which is an object that maps event names to an array of callback functions.
Sources: src/modules/ConsentManager.ts:80
Event Types
The system defines three distinct event types that are dispatched when consent grants are modified.
| Event Name | Description |
|---|---|
grant | Fired specifically when a consent category's status changes to true. |
revoke | Fired specifically when a consent category's status changes to false. |
update | Fired whenever a consent category's status changes, regardless of whether it was granted or revoked. |
Sources: src/modules/ConsentManager.ts:60, src/modules/ConsentManager.ts:173-175
Event Management Methods
The ConsentManager class provides public methods for managing event listeners.
| Method | Parameters | Description - on(eventName, callback) | eventName: update | grant | revokecallback: (id: G) => void | Registers a callback function to be executed when the specified event is dispatched. |
| off(eventName, callback) | eventName: update | grant | revokecallback: (id: G) => void | Removes a previously registered callback function. The exact same function reference must be passed. |
Sources: src/modules/ConsentManager.ts:182-202, README.md:128-145
Event Flow
The event lifecycle begins when a consent grant is changed via the setGrant method. This method is the sole trigger for dispatching events.
The following sequence diagram illustrates the process when a grant is changed.
This diagram shows how a call to setGrant triggers the dispatch method for both update and grant events, which in turn invokes the registered callbacks in modules like DOMConnector and GrantsInterface.
Sources: src/modules/ConsentManager.ts:153-180
Event Dispatching
The setGrant method is responsible for changing the status of a consent category. After updating the internal grants object, it determines the correct event type (grant or revoke) and dispatches it, along with the general update event.
// File: src/modules/ConsentManager.ts:172-175
// Dispatch events
const eventType = status ? 'grant' : 'revoke';
this.dispatch('update', id);
this.dispatch(eventType, id);
The private dispatch method then iterates over all registered listeners for that event and executes them with the category id as an argument.
// File: src/modules/ConsentManager.ts:204-211
private dispatch(eventName: EventNames, grant: G): void {
// Ignore if no listeners are registered for event
if (!(eventName in this.eventListeners)) {
return;
}
for (const callback of this.eventListeners[eventName]) {
callback(grant);
}
}
Sources: src/modules/ConsentManager.ts:153-180, src/modules/ConsentManager.ts:204-211
Event Consumers
The modularity of consent-manager is demonstrated by its event consumers, which operate independently of the core logic.
DOMConnector
The DOMConnector module listens for the update event to dynamically modify HTML elements based on the current consent grants. In its constructor, it registers a listener that calls its updateDOM method whenever a consent status changes.
// File: src/modules/DOMConnector.ts:4-6
constructor(private client: ConsentManager) {
this.updateDOM();
client.on('update', this.updateDOM.bind(this));
}
The updateDOM method then queries the document for all elements with the data-consent-manager attribute and updates them according to the new consent status.
Sources: src/modules/DOMConnector.ts:4-6, src/modules/DOMConnector.ts:28-47
GrantsInterface
The GrantsInterface module uses the event system to manage its UI components.
-
Hiding the Banner: It listens for the
updateevent to automatically hide the consent banner once the user has customized their preferences (isCustomizedbecomestrue).// File: src/modules/GrantsInterface.ts:110-114 this.client.on('update', () => { if (this.client.isCustomized) { this.hideBanner(); } }); -
Auto-updating Table: When generating the consent table with
autoUpdateset totrue, it registers anupdateevent listener for each category toggle. This ensures that if a grant is changed elsewhere (e.g., via "Accept All"), the corresponding checkbox in the modal is updated to reflect the new state.// File: src/modules/GrantsInterface.ts:182-186 if (autoUpdate) { this.client.on('update', (id) => { if (category.id === id) { checkbox.checked = this.client.grants[id]; } }); }
Sources: src/modules/GrantsInterface.ts:110-114, src/modules/GrantsInterface.ts:182-186
Usage Example
To use the event system, call the on method on a ConsentManager instance with the desired event name and a callback function.
The following example, adapted from the project's tests and documentation, demonstrates how to listen for an update event and how to remove the listener later.
// File: src/modules/ConsentManager.test.ts:113-128
const consentManager = new ConsentManager({
version: '1',
categories: [
{
id: 'test',
label: 'Test',
description: 'Test category',
required: false,
},
],
});
const callback = (id) => {
console.log(`Category ${id} was updated!`);
};
// Register the listener
consentManager.on('update', callback);
// This will trigger the callback and log "Category test was updated!"
consentManager.setGrant('test', true);
// Unregister the listener
consentManager.off('update', callback);
// This will not trigger the callback
consentManager.setGrant('test', false);
It is crucial to pass the exact same function reference to off that was used with on to successfully remove the listener.
Sources: src/modules/ConsentManager.test.ts:113-128, README.md:128-145