• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / roku-debug / #2022

pending completion
#2022

push

web-flow
Merge 2bf3908ce into 4961675eb

1897 of 2750 branches covered (68.98%)

Branch coverage included in aggregate %.

17 of 17 new or added lines in 3 files covered. (100.0%)

3450 of 4594 relevant lines covered (75.1%)

27.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.05
/src/debugProtocol/PluginInterface.ts
1
// inspiration: https://github.com/andywer/typed-emitter/blob/master/index.d.ts
2
export type Arguments<T> = [T] extends [(...args: infer U) => any]
3
    ? U
4
    : [T] extends [void] ? [] : [T];
5

6
export default class PluginInterface<TPlugin> {
1✔
7
    constructor(
8
        plugins = [] as TPlugin[]
128✔
9
    ) {
10
        for (const plugin of plugins ?? []) {
128!
11
            this.add(plugin);
×
12
        }
13
    }
14

15
    private plugins: Array<PluginContainer<TPlugin>> = [];
128✔
16

17
    /**
18
     * Call `event` on plugins
19
     */
20
    public async emit<K extends keyof TPlugin & string>(eventName: K, event: Arguments<TPlugin[K]>[0]) {
21
        for (let { plugin } of this.plugins) {
1,492✔
22
            if ((plugin as any)[eventName]) {
1,505✔
23
                await Promise.resolve((plugin as any)[eventName](event));
439✔
24
            }
25
        }
26
        return event;
1,492✔
27
    }
28

29
    /**
30
     * Add a plugin to the end of the list of plugins
31
     * @param plugin the plugin
32
     * @param priority the priority for the plugin. Lower number means higher priority. (ex: 1 executes before 5)
33
     */
34
    public add<T extends TPlugin = TPlugin>(plugin: T, priority = 1) {
64✔
35
        const container = {
129✔
36
            plugin: plugin,
37
            priority: priority
38
        };
39
        this.plugins.push(container);
129✔
40

41
        //sort the plugins by priority
42
        this.plugins.sort((a, b) => {
129✔
43
            return a.priority - b.priority;
2✔
44
        });
45

46
        return plugin;
129✔
47
    }
48

49
    /**
50
     * Adds a temporary plugin with a single event hook, and resolve a promise with the event from the next occurance of that event.
51
     * Once the event fires for the first time, the plugin is unregistered.
52
     * @param eventName the name of the event to subscribe to
53
     * @param priority the priority for this event. Lower number means higher priority. (ex: 1 executes before 5)
54
     */
55
    public once<TEventType>(eventName: keyof TPlugin, priority = 1): Promise<TEventType> {
×
56
        return this.onceIf(eventName, () => true, priority);
×
57
    }
58

59
    /**
60
     * Adds a temporary plugin with a single event hook, and resolve a promise with the event from the next occurance of that event.
61
     * Once the event fires for the first time and the matcher evaluates to true, the plugin is unregistered.
62
     * @param eventName the name of the event to subscribe to
63
     * @param matcher a function to call that, when true, will deregister this hander and return the event
64
     * @param priority the priority for this event. Lower number means higher priority. (ex: 1 executes before 5)
65
     */
66
    public onceIf<TEventType>(eventName: keyof TPlugin, matcher: (TEventType) => boolean, priority = 1): Promise<TEventType> {
×
67
        return new Promise((resolve) => {
1✔
68
            const tempPlugin = {} as any;
1✔
69
            tempPlugin[eventName] = (event) => {
1✔
70
                if (matcher(event)) {
1!
71
                    //remove the temp plugin
72
                    this.remove(tempPlugin);
1✔
73
                    //resolve the promise with this event
74
                    resolve(event);
1✔
75
                }
76
            };
77
            this.add(tempPlugin, priority);
1✔
78
        }) as any;
79
    }
80

81
    /**
82
     * Remove the specified plugin
83
     */
84
    public remove<T extends TPlugin = TPlugin>(plugin: T) {
85
        for (let i = this.plugins.length - 1; i >= 0; i--) {
1✔
86
            if (this.plugins[i].plugin === plugin) {
2✔
87
                this.plugins.splice(i, 1);
1✔
88
            }
89
        }
90
    }
91

92
    /**
93
     * Remove all plugins
94
     */
95
    public clear() {
96
        this.plugins = [];
×
97
    }
98
}
99

100
interface PluginContainer<TPlugin> {
101
    plugin: TPlugin;
102
    priority: number;
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc