Skip to content

Commit

Permalink
fix(web): Implement retainUntilConsumed on notifyListeners (#7127)
Browse files Browse the repository at this point in the history
Co-authored-by: jcesarmobile <[email protected]>
Co-authored-by: Dan Giralté <[email protected]>
  • Loading branch information
3 people authored Jan 2, 2024
1 parent b8c2a92 commit 526292e
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
35 changes: 35 additions & 0 deletions core/src/tests/web-plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ class MockPlugin extends WebPlugin {
});
}

triggerRetained() {
this.notifyListeners(
'testRetained',
{
value: 'Test Retained Value 1',
},
true,
);

this.notifyListeners(
'testRetained',
{
value: 'Test Retained Value 2',
},
true,
);
}

getListeners() {
return this.listeners;
}
Expand Down Expand Up @@ -101,6 +119,23 @@ describe('Web Plugin', () => {
handle.remove();
});

it('Should submit retained events on event registration', async () => {
const lf = jest.fn();
plugin.triggerRetained();

const handle = await plugin.addListener('testRetained', lf);

expect(lf.mock.calls.length).toEqual(2);
expect(lf.mock.calls[0][0]).toEqual({
value: 'Test Retained Value 1',
});
expect(lf.mock.calls[1][0]).toEqual({
value: 'Test Retained Value 2',
});

handle.remove();
});

it('Should register and remove window listeners', async () => {
const pluginAddWindowListener = jest.spyOn(
MockPlugin.prototype as any,
Expand Down
44 changes: 41 additions & 3 deletions core/src/web-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class WebPlugin implements Plugin {
config?: WebPluginConfig;

protected listeners: { [eventName: string]: ListenerCallback[] } = {};
protected retainedEventArguments: { [eventName: string]: any[] } = {};
protected windowListeners: { [eventName: string]: WindowListenerHandle } = {};

constructor(config?: WebPluginConfig) {
Expand All @@ -29,9 +30,12 @@ export class WebPlugin implements Plugin {
eventName: string,
listenerFunc: ListenerCallback,
): Promise<PluginListenerHandle> {
let firstListener = false;

const listeners = this.listeners[eventName];
if (!listeners) {
this.listeners[eventName] = [];
firstListener = true;
}

this.listeners[eventName].push(listenerFunc);
Expand All @@ -43,6 +47,10 @@ export class WebPlugin implements Plugin {
this.addWindowListener(windowListener);
}

if (firstListener) {
this.sendRetainedArgumentsForEvent(eventName);
}

const remove = async () => this.removeListener(eventName, listenerFunc);

const p: any = Promise.resolve({ remove });
Expand All @@ -58,11 +66,28 @@ export class WebPlugin implements Plugin {
this.windowListeners = {};
}

protected notifyListeners(eventName: string, data: any): void {
protected notifyListeners(
eventName: string,
data: any,
retainUntilConsumed?: boolean,
): void {
const listeners = this.listeners[eventName];
if (listeners) {
listeners.forEach(listener => listener(data));
if (!listeners) {
if (retainUntilConsumed) {
let args = this.retainedEventArguments[eventName];
if (!args) {
args = [];
}

args.push(data);

this.retainedEventArguments[eventName] = args;
}

return;
}

listeners.forEach(listener => listener(data));
}

protected hasListeners(eventName: string): boolean {
Expand Down Expand Up @@ -123,6 +148,19 @@ export class WebPlugin implements Plugin {
window.removeEventListener(handle.windowEventName, handle.handler);
handle.registered = false;
}

private sendRetainedArgumentsForEvent(eventName: string): void {
const args = this.retainedEventArguments[eventName];
if (!args) {
return;
}

delete this.retainedEventArguments[eventName];

args.forEach(arg => {
this.notifyListeners(eventName, arg);
});
}
}

export type ListenerCallback = (err: any, ...args: any[]) => void;
Expand Down

0 comments on commit 526292e

Please sign in to comment.