Skip to content

Commit

Permalink
feat(esl-event-listener): add a group key to process batch subscrip…
Browse files Browse the repository at this point in the history
…tion operations

Closes: #2381
  • Loading branch information
ala-n committed May 7, 2024
1 parent 35f968c commit 3d1ece0
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/modules/esl-event-listener/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ All active subscriptions are stored in a hidden property of the `host` object.
- `capture` - marker to use the capture phase of the DOM event life-cycle;
- `passive` - marker to use passive (non-blocking) subscription of the native event (if supported);
- `once` - marker to destroy the subscription after the first event catch.
- `group` - auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.

All of the `ESLEventListener` instance fields are read-only; the subscription can't be changed once created.

Expand Down Expand Up @@ -170,6 +171,19 @@ Here is the list of supported keys of `ESLEventDesriptor`:
<u>Default Value:</u> `false`
<u>Description:</u> marker to unsubscribe the listener after the first successful handling of the event.


- #### `group` key
<u>Type:</u> `string`
<u>Description:</u> auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.

E.g.:
```typescript
ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler1);
ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler2);
// ...
ESLEventUtils.unsubscribe(host, {group: 'group'}); // Unsubscribes all subscriptions with the 'group' key
```

- #### `auto` key (for `ESLEventDesriptorFn` declaration only)
<u>Type:</u> `boolean`
<u>Default Value:</u> `false` for `ESLEventUtils.initDescriptor`, `true` for `@listen` decorator
Expand All @@ -180,6 +194,7 @@ Here is the list of supported keys of `ESLEventDesriptor`:
Allows to inherit `ESLEventDesriptor` data from the `ESLEventDesriptorFn` from the prototype chain.
See [`initDescriptor`](#-esleventutilsinitdescriptor) usages example.


### <a name="automatic-collectable-descriptors">Automatic (collectable) descriptors</a>

Auto-collectable (or auto-subscribable) descriptors can be subscribed at once during the initialization of the `host` object.
Expand Down
2 changes: 2 additions & 0 deletions src/modules/esl-event-listener/core/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export class ESLEventListener implements ESLListenerDefinition, EventListenerObj
public readonly auto?: boolean;
public readonly passive?: boolean;

public readonly group?: string;

protected constructor(
public readonly host: object,
public readonly event: string,
Expand Down
3 changes: 3 additions & 0 deletions src/modules/esl-event-listener/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export type ESLListenerDescriptor<EType extends keyof ESLListenerEventMap = stri
auto?: boolean;
/** A boolean value indicating that the listener should be invoked at most once after being added */
once?: boolean;

/** Auxiliary group name to group listeners. Used for a batch un/re-subscribe */
group?: string;
};

/** Resolved descriptor (definition) to create {@link ESLEventListener} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ describe('ESLEventUtils:unsubscribe successfully removes listener', () => {
const div = document.createElement('div');

beforeEach(() => {
ESLEventUtils.subscribe(div, {event: 'click'}, handle);
ESLEventUtils.subscribe(div, {event: 'event'}, handle);
ESLEventUtils.subscribe(div, {event: 'click', group: 'test'}, handle);
ESLEventUtils.subscribe(div, {event: 'event', group: 'test'}, handle);
});

test('all', () => {
Expand Down Expand Up @@ -39,6 +39,11 @@ describe('ESLEventUtils:unsubscribe successfully removes listener', () => {
expect(ESLEventUtils.listeners(div).length).toBe(0);
});

test('by group', () => {
ESLEventUtils.unsubscribe(div, {group: 'test'});
expect(ESLEventUtils.listeners(div).length).toBe(0);
});

test('with multiple criteria', () => {
ESLEventUtils.unsubscribe(div, handle, {event: 'key'});
expect(ESLEventUtils.listeners(div).length).toBe(2);
Expand Down

0 comments on commit 3d1ece0

Please sign in to comment.