tsoa
This commit is contained in:
10
node_modules/@hapi/podium/LICENSE.md
generated
vendored
Executable file
10
node_modules/@hapi/podium/LICENSE.md
generated
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
Copyright (c) 2016-2022, Project contributors
|
||||
Copyright (c) 2016-2020, Sideway Inc
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* The names of any contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS OFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
17
node_modules/@hapi/podium/README.md
generated
vendored
Executable file
17
node_modules/@hapi/podium/README.md
generated
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
<a href="https://hapi.dev"><img src="https://raw.githubusercontent.com/hapijs/assets/master/images/family.png" width="180px" align="right" /></a>
|
||||
|
||||
# @hapi/podium
|
||||
|
||||
#### Event emitter with async features.
|
||||
|
||||
**podium** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) – they work even better together.
|
||||
|
||||
### Visit the [hapi.dev](https://hapi.dev) Developer Portal for tutorials, documentation, and support
|
||||
|
||||
## Useful resources
|
||||
|
||||
- [Documentation and API](https://hapi.dev/family/podium/)
|
||||
- [Version status](https://hapi.dev/resources/status/#podium) (builds, dependencies, node versions, licenses, eol)
|
||||
- [Changelog](https://hapi.dev/family/podium/changelog/)
|
||||
- [Project policies](https://hapi.dev/policies/)
|
||||
- [Free and commercial support options](https://hapi.dev/support/)
|
||||
332
node_modules/@hapi/podium/lib/index.d.ts
generated
vendored
Normal file
332
node_modules/@hapi/podium/lib/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
|
||||
type IfUndefinedElse<T, If, Else> = T extends undefined ? If : Else;
|
||||
|
||||
type EventNames<Events> = IfUndefinedElse<Events, string, keyof Events>;
|
||||
|
||||
type EventListenerParameters<Events> = Events[keyof Events] extends (...args: any) => any
|
||||
? Parameters<Events[keyof Events]>
|
||||
: never
|
||||
;
|
||||
|
||||
type EmitData<Events> = IfUndefinedElse<Events, any, EventListenerParameters<Events>>;
|
||||
|
||||
type EventListener<Events, TArgs extends unknown[], TContext extends object> = Podium.Listener<
|
||||
TContext,
|
||||
IfUndefinedElse<Events, TArgs, EventListenerParameters<Events>>
|
||||
>;
|
||||
|
||||
type WithRequiredProperty<Type, Key extends keyof Type> = Type & {
|
||||
[Property in Key]-?: Type[Property];
|
||||
};
|
||||
|
||||
/**
|
||||
* Node (semi) compatible event emitter with extra features.
|
||||
*/
|
||||
export class Podium<Events = undefined> {
|
||||
/**
|
||||
* Creates a new podium emitter.
|
||||
*
|
||||
* @param events - If present, the value is passed to podium.registerEvent().
|
||||
* @param options - optional configuration options passed to podium.registerEvent().
|
||||
*/
|
||||
constructor(events?: Podium.Event<EventNames<Events>> | Podium.Event<EventNames<Events>>[], options?: Podium.EventSettings);
|
||||
|
||||
/**
|
||||
* Register the specified events and their optional configuration. Events must be registered
|
||||
* before they can be emitted or subscribed to. This is done to detect event name mispelling
|
||||
* and invalid event activities.
|
||||
*
|
||||
* @param events - The event(s) to register.
|
||||
* @param options - optional configuration options.
|
||||
*/
|
||||
registerEvent(events: Podium.Event<EventNames<Events>> | Podium.Event<EventNames<Events>>[], options?: Podium.EventSettings): void;
|
||||
|
||||
/**
|
||||
* Emits an event update to all the subscribed listeners.
|
||||
|
||||
* @param criteria - The event update criteria.
|
||||
* @param data - The value emitted to the subscribers.
|
||||
*/
|
||||
emit(criteria: Podium.EmitCriteria<EventNames<Events>>, data?: EmitData<Events>): void;
|
||||
|
||||
/**
|
||||
* Emits an event update to all the subscribed listeners and resolves an array of their results.
|
||||
|
||||
* @param criteria - The event update criteria.
|
||||
* @param data - The value emitted to the subscribers.
|
||||
*/
|
||||
gauge<T = unknown>(criteria: Podium.EmitCriteria<EventNames<Events>>, data?: EmitData<Events>): Promise<PromiseSettledResult<T>[]>;
|
||||
|
||||
/**
|
||||
* Subscribe a handler to an event.
|
||||
*
|
||||
* @param criteria - The subscription criteria.
|
||||
* @param listener - The handler method set to receive event updates. The function signature
|
||||
* depends on the block, spread, and tags options.
|
||||
* @param context - Optional object that binds to the listener handler.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
on<TArgs extends any[] = unknown[], Tcontext extends object = this>
|
||||
(criteria: Podium.Criteria<EventNames<Events>>, listener: EventListener<Events, TArgs, Tcontext>, context?: Tcontext): this
|
||||
|
||||
/**
|
||||
* Subscribe a handler to an event. Same as podium.on().
|
||||
*
|
||||
* @param criteria - The subscription criteria.
|
||||
* @param listener - The handler method set to receive event updates. The function signature
|
||||
* depends on the block, spread, and tags options.
|
||||
* @param context - Optional object that binds to the listener handler.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
addListener<TArgs extends any[] = unknown[], Tcontext extends object = this>
|
||||
(criteria: Podium.Criteria<EventNames<Events>>, listener: EventListener<Events, TArgs, Tcontext>, context?: Tcontext): this;
|
||||
|
||||
/**
|
||||
* Same as podium.on() with the count option set to 1.
|
||||
*
|
||||
* Can also be called without an listener to wait for a single event.
|
||||
*
|
||||
* @param criteria - The subscription criteria.
|
||||
* @param listener - The handler method set to receive event updates. The function signature
|
||||
* depends on the block, spread, and tags options.
|
||||
* @param context - Optional object that binds to the listener handler.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
once<TArgs extends any[] = unknown[], Tcontext extends object = this>
|
||||
(criteria: Podium.OnceCriteria<EventNames<Events>>, listener: EventListener<Events, TArgs, Tcontext>, context?: Tcontext): this;
|
||||
|
||||
/**
|
||||
* Subscribes to an event by returning a promise that resolves when the event is emitted.
|
||||
*
|
||||
* @param criteria - The subscription criteria.
|
||||
*
|
||||
* @returns Promise with array of emitted parameters.
|
||||
*/
|
||||
once<TArgs extends any[] = unknown[], Tcontext extends object = this>(criteria: Podium.OnceCriteria<EventNames<Events>>): Promise<TArgs>;
|
||||
|
||||
/**
|
||||
* Subscribes to an event by returning a promise that resolves when the event is emitted `count` times.
|
||||
*
|
||||
* @param criteria - The subscription criteria.
|
||||
*
|
||||
* @returns Promise with array where each item is an array of emitted arguments.
|
||||
*/
|
||||
few<TArgs extends any[] = unknown[], Tcontext extends object = this>(criteria: Podium.FewCriteria<EventNames<Events>>): Promise<TArgs>;
|
||||
|
||||
/**
|
||||
* Removes all listeners subscribed to a given event name matching the provided listener method.
|
||||
*
|
||||
* @param name - The event name string.
|
||||
* @param listener - The function reference provided when subscribed.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
off(name: string, listener: Podium.Listener): this;
|
||||
|
||||
/**
|
||||
* Removes all listeners subscribed to a given event name matching the provided listener method.
|
||||
*
|
||||
* @param name - The event name string.
|
||||
* @param listener - The function reference provided when subscribed.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
removeListener(name: string, listener: Podium.Listener): this;
|
||||
|
||||
/**
|
||||
* Removes all listeners subscribed to a given event name.
|
||||
*
|
||||
* @param name - The event name string.
|
||||
*
|
||||
* @returns A reference to the current emitter.
|
||||
*/
|
||||
removeAllListeners(name: string): this;
|
||||
|
||||
/**
|
||||
* Returns whether an event has any listeners subscribed.
|
||||
*
|
||||
* @param name the event name string.
|
||||
*
|
||||
* @returns true if the event name has any listeners, otherwise false.
|
||||
*/
|
||||
hasListeners(name: string): boolean;
|
||||
}
|
||||
|
||||
declare namespace Podium {
|
||||
|
||||
type EventName = string | number | symbol
|
||||
|
||||
interface EmitCriteriaInterface<TName extends EventName> {
|
||||
|
||||
/**
|
||||
* Event name.
|
||||
*/
|
||||
readonly name: TName;
|
||||
|
||||
/**
|
||||
* Channel name.
|
||||
*/
|
||||
readonly channel?: string | undefined;
|
||||
|
||||
/**
|
||||
* The tags to apply.
|
||||
*/
|
||||
readonly tags?: string | string[] | { [tag: string]: boolean } | undefined;
|
||||
}
|
||||
|
||||
export type EmitCriteria<TName extends EventName> = EmitCriteriaInterface<TName> | TName
|
||||
|
||||
interface EventOptionsInterface<TName extends EventName> {
|
||||
|
||||
/**
|
||||
* Event name.
|
||||
*/
|
||||
readonly name: TName;
|
||||
|
||||
/**
|
||||
* A string or array of strings specifying the event channels available.
|
||||
*
|
||||
* Defaults to no channel restrictions - Event updates can specify a channel or not.
|
||||
*/
|
||||
readonly channels?: string | string[] | undefined;
|
||||
|
||||
/**
|
||||
* Set to make podium.emit() clone the data object passed to it, before it is passed to the
|
||||
* listeners (unless an override specified by each listener).
|
||||
*
|
||||
* Defaults to false - Data is passed as-is.
|
||||
*/
|
||||
readonly clone?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Set to require the data object passed to podium.emit() to be an array, and make the
|
||||
* listener method called with each array element passed as a separate argument (unless an
|
||||
* override specified by each listener).
|
||||
*
|
||||
* This should only be used when the emitted data structure is known and predictable.
|
||||
*
|
||||
* Defaults to false - Data is emitted as a single argument regardless of its type.
|
||||
*/
|
||||
readonly spread?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Set to make any tags in the critieria object passed to podium.emit() map to an object
|
||||
* (where each tag string is the key and the value is true) which is appended to the emitted
|
||||
* arguments list at the end.
|
||||
*
|
||||
* A configuration override can be set by each listener.
|
||||
*
|
||||
* Defaults to false.
|
||||
*/
|
||||
readonly tags?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Set to allow the same event name to be registered multiple times, ignoring all but the
|
||||
* first.
|
||||
*
|
||||
* Note that if the registration config is changed between registrations, only the first
|
||||
* configuration is used.
|
||||
*
|
||||
* Defaults to false - A duplicate registration will throw an error.
|
||||
*/
|
||||
readonly shared?: boolean | undefined;
|
||||
}
|
||||
|
||||
type EventOptions<TName extends EventName> = EventOptionsInterface<TName> | TName
|
||||
|
||||
type Event<TName extends EventName> = TName | EventOptions<TName>;
|
||||
|
||||
export interface EventSettings {
|
||||
|
||||
/**
|
||||
* If false, events are not validated. This is only allowed when the events
|
||||
* value is returned from Podium.validate().
|
||||
*
|
||||
* Defaults to true
|
||||
*/
|
||||
readonly validate?: boolean | undefined;
|
||||
}
|
||||
|
||||
type Listener<TContext extends object = any, TArgs extends any[] = any[]> =
|
||||
(this: TContext, ...args: TArgs) => unknown;
|
||||
|
||||
interface CriteriaFilterOptionsObject {
|
||||
|
||||
/**
|
||||
* A tag string or array of tag strings.
|
||||
*/
|
||||
readonly tags?: string | string[] | undefined;
|
||||
|
||||
/**
|
||||
* Require all tags to be present for the event update to match the subscription.
|
||||
*
|
||||
* Default false - Require at least one matching tag.
|
||||
*/
|
||||
readonly all?: boolean | undefined;
|
||||
}
|
||||
|
||||
interface CriteriaInterface<TName extends EventName> {
|
||||
|
||||
/**
|
||||
* Event name.
|
||||
*/
|
||||
readonly name: TName;
|
||||
|
||||
/**
|
||||
* The event channels to subscribe to.
|
||||
*
|
||||
* If the event registration specified a list of allowed channels, the channels array must
|
||||
* match the allowed channels. If channels are specified, event updates without any channel
|
||||
* designation will not be included in the subscription.
|
||||
*
|
||||
* Defaults to no channels filter.
|
||||
*/
|
||||
readonly channels?: string | string[] | undefined;
|
||||
|
||||
/**
|
||||
* Set to clone the data object passed to podium.emit() before it is passed to the listener
|
||||
* method.
|
||||
*
|
||||
* Defaults to the event registration option (which defaults to false).
|
||||
*/
|
||||
readonly clone?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* A positive non-zero integer indicating the number of times the listener can be called
|
||||
* after which the subscription is automatically removed.
|
||||
*
|
||||
* Does nothing when calling once(), where it will use the value 1.
|
||||
*
|
||||
* Defaults to no limit.
|
||||
*/
|
||||
readonly count?: number | undefined;
|
||||
|
||||
/**
|
||||
* The event tags (if present) to subscribe to.
|
||||
*/
|
||||
readonly filter?: string | string[] | CriteriaFilterOptionsObject | undefined;
|
||||
|
||||
/**
|
||||
* Override the value of spread from the event registraiont when the listener is called.
|
||||
*
|
||||
* This should only be used when the emitted data structure is known and predictable.
|
||||
*
|
||||
* Defaults to the event registration option (which defaults to false).
|
||||
*/
|
||||
readonly spread?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Override the value of tags from the event registraiont when the listener is called.
|
||||
*
|
||||
* Defaults to the event registration option (which defaults to false).
|
||||
*/
|
||||
readonly tags?: boolean | undefined;
|
||||
}
|
||||
|
||||
export type Criteria<TName extends EventName = string> = CriteriaInterface<TName> | TName
|
||||
export type OnceCriteria<TName extends EventName = string> = Omit<CriteriaInterface<TName>, 'count'> | TName
|
||||
export type FewCriteria<TName extends EventName = string> = WithRequiredProperty<CriteriaInterface<TName>, 'count'>
|
||||
}
|
||||
330
node_modules/@hapi/podium/lib/index.js
generated
vendored
Executable file
330
node_modules/@hapi/podium/lib/index.js
generated
vendored
Executable file
@@ -0,0 +1,330 @@
|
||||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
const Teamwork = require('@hapi/teamwork');
|
||||
const Validate = require('@hapi/validate');
|
||||
|
||||
|
||||
const internals = {
|
||||
schema: {
|
||||
base: Validate.object({
|
||||
name: Validate.string().required(),
|
||||
clone: Validate.boolean(),
|
||||
tags: Validate.boolean(),
|
||||
spread: Validate.boolean(),
|
||||
channels: Validate.array().items(Validate.string()).single().unique().min(1).cast('set')
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.schema.event = internals.schema.base.keys({
|
||||
shared: Validate.boolean()
|
||||
});
|
||||
|
||||
|
||||
internals.schema.listener = internals.schema.base.keys({
|
||||
listener: Validate.func().required(),
|
||||
context: Validate.object(),
|
||||
count: Validate.number().integer().min(1),
|
||||
filter: {
|
||||
tags: Validate.array().items(Validate.string()).single().unique().min(1).required(),
|
||||
all: Validate.boolean()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
exports.validate = function (events) {
|
||||
|
||||
const normalized = [];
|
||||
events = [].concat(events);
|
||||
for (let event of events) {
|
||||
if (typeof event === 'string') {
|
||||
event = { name: event };
|
||||
}
|
||||
|
||||
normalized.push(Validate.attempt(event, internals.schema.event, 'Invalid event options'));
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
|
||||
exports.Podium = class {
|
||||
|
||||
/** @type {Map<string,internals.EventListener>} */
|
||||
#listeners = new Map();
|
||||
|
||||
constructor(events, options) {
|
||||
|
||||
if (events) {
|
||||
this.registerEvent(events, options);
|
||||
}
|
||||
}
|
||||
|
||||
registerEvent(events, options) {
|
||||
|
||||
events = [].concat(events);
|
||||
for (let event of events) {
|
||||
if (typeof event === 'string') {
|
||||
event = { name: event };
|
||||
}
|
||||
|
||||
if (options?.validate !== false) { // Defaults to true
|
||||
event = Validate.attempt(event, internals.schema.event, 'Invalid event options');
|
||||
}
|
||||
|
||||
const name = event.name;
|
||||
if (this.#listeners.has(name)) {
|
||||
Hoek.assert(event.shared, `Event ${name} exists`);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.#listeners.set(name, new internals.EventListener(event));
|
||||
}
|
||||
}
|
||||
|
||||
emit(criteria, data) {
|
||||
|
||||
let thrownErr;
|
||||
|
||||
this.#emitToEachListener(criteria, data, ([err]) => {
|
||||
|
||||
thrownErr = thrownErr ?? err;
|
||||
});
|
||||
|
||||
if (thrownErr) {
|
||||
throw thrownErr;
|
||||
}
|
||||
}
|
||||
|
||||
async gauge(criteria, data) {
|
||||
|
||||
const promises = [];
|
||||
|
||||
this.#emitToEachListener(criteria, data, ([err, result]) => {
|
||||
|
||||
promises.push(err ? Promise.reject(err) : result);
|
||||
});
|
||||
|
||||
return await Promise.allSettled(promises);
|
||||
}
|
||||
|
||||
#emitToEachListener(criteria, data, fn) {
|
||||
|
||||
criteria = internals.criteria(criteria);
|
||||
|
||||
const name = criteria.name;
|
||||
Hoek.assert(name, 'Criteria missing event name');
|
||||
|
||||
const event = this.#listeners.get(name);
|
||||
Hoek.assert(event, `Unknown event ${name}`);
|
||||
|
||||
if (!event.handlers) {
|
||||
return;
|
||||
}
|
||||
|
||||
Hoek.assert(!criteria.channel || typeof criteria.channel === 'string', 'Invalid channel name');
|
||||
Hoek.assert(!criteria.channel || !event.flags.channels || event.flags.channels.has(criteria.channel), `Unknown ${criteria.channel} channel`);
|
||||
Hoek.assert(!event.flags.spread || Array.isArray(data) || typeof data === 'function', 'Data must be an array for spread event');
|
||||
|
||||
if (typeof criteria.tags === 'string') {
|
||||
criteria = { ...criteria };
|
||||
criteria.tags = { [criteria.tags]: true };
|
||||
}
|
||||
|
||||
if (criteria.tags &&
|
||||
Array.isArray(criteria.tags)) {
|
||||
|
||||
// Map array to object
|
||||
|
||||
const tags = {};
|
||||
for (const tag of criteria.tags) {
|
||||
tags[tag] = true;
|
||||
}
|
||||
|
||||
criteria = { ...criteria };
|
||||
criteria.tags = tags;
|
||||
}
|
||||
|
||||
let generated = false;
|
||||
|
||||
for (const handler of event.handlers) {
|
||||
if (handler.channels &&
|
||||
!(criteria.channel && handler.channels.has(criteria.channel))) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handler.filter) {
|
||||
if (!criteria.tags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const match = Hoek.intersect(criteria.tags, handler.filter.tags, { first: !handler.filter.all });
|
||||
if (!match ||
|
||||
handler.filter.all && match.length !== handler.filter.tags.length) {
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Found a listener, now prepare to call it
|
||||
|
||||
if (handler.count) {
|
||||
--handler.count;
|
||||
if (handler.count < 1) {
|
||||
event.removeListener(handler.listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (!generated &&
|
||||
typeof data === 'function') {
|
||||
|
||||
data = data();
|
||||
generated = true;
|
||||
}
|
||||
|
||||
const update = event.flagged('clone', handler) ? Hoek.clone(data) : data;
|
||||
const args = event.flagged('spread', handler) && Array.isArray(update) ? update.slice(0) : [update];
|
||||
|
||||
if (event.flagged('tags', handler) &&
|
||||
criteria.tags) {
|
||||
|
||||
args.push(criteria.tags);
|
||||
}
|
||||
|
||||
// Call the listener
|
||||
|
||||
try {
|
||||
if (handler.context) {
|
||||
fn([null, handler.listener.apply(handler.context, args)]);
|
||||
}
|
||||
else {
|
||||
fn([null, handler.listener(...args)]);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
fn([err, null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addListener(criteria, listener, context) {
|
||||
|
||||
criteria = internals.criteria(criteria);
|
||||
criteria.listener = listener;
|
||||
criteria.context = context;
|
||||
|
||||
if (criteria.filter &&
|
||||
(typeof criteria.filter === 'string' || Array.isArray(criteria.filter))) {
|
||||
|
||||
criteria = { ...criteria };
|
||||
criteria.filter = { tags: criteria.filter };
|
||||
}
|
||||
|
||||
criteria = Validate.attempt(criteria, internals.schema.listener, 'Invalid event listener options');
|
||||
|
||||
const name = criteria.name;
|
||||
const event = this.#listeners.get(name);
|
||||
Hoek.assert(event, `Unknown event ${name}`);
|
||||
|
||||
event.addHandler(criteria);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
on(criteria, listener, context) {
|
||||
|
||||
return this.addListener(criteria, listener, context);
|
||||
}
|
||||
|
||||
once(criteria, listener, context) {
|
||||
|
||||
criteria = { ...internals.criteria(criteria), count: 1 };
|
||||
|
||||
if (listener) {
|
||||
return this.addListener(criteria, listener, context);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
||||
this.addListener(criteria, (...args) => resolve(args));
|
||||
});
|
||||
}
|
||||
|
||||
few(criteria) {
|
||||
|
||||
Hoek.assert(typeof criteria === 'object', 'Criteria must be an object');
|
||||
Hoek.assert(criteria.count, 'Criteria must include a count limit');
|
||||
|
||||
const team = new Teamwork.Team({ meetings: criteria.count });
|
||||
this.addListener(criteria, (...args) => team.attend(args));
|
||||
return team.work;
|
||||
}
|
||||
|
||||
removeListener(name, listener) {
|
||||
|
||||
Hoek.assert(this.#listeners.has(name), `Unknown event ${name}`);
|
||||
Hoek.assert(typeof listener === 'function', 'Listener must be a function');
|
||||
|
||||
this.#listeners.get(name).removeListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
off(name, listener) {
|
||||
|
||||
return this.removeListener(name, listener);
|
||||
}
|
||||
|
||||
removeAllListeners(name) {
|
||||
|
||||
Hoek.assert(this.#listeners.has(name), `Unknown event ${name}`);
|
||||
this.#listeners.get(name).handlers = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
hasListeners(name) {
|
||||
|
||||
Hoek.assert(this.#listeners.has(name), `Unknown event ${name}`);
|
||||
return !!this.#listeners.get(name).handlers;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.EventListener = class {
|
||||
|
||||
constructor(flags) {
|
||||
|
||||
this.flags = flags;
|
||||
this.handlers = null;
|
||||
}
|
||||
|
||||
addHandler(handler) {
|
||||
|
||||
Hoek.assert(!handler.channels || !this.flags.channels || Hoek.intersect(this.flags.channels, handler.channels).length === handler.channels.size, `Unknown event channels ${handler.channels && [...handler.channels].join(', ')}`);
|
||||
|
||||
this.handlers = this.handlers ? [...this.handlers, handler] : [handler]; // Don't mutate
|
||||
}
|
||||
|
||||
removeListener(listener) {
|
||||
|
||||
const filtered = this.handlers?.filter((item) => item.listener !== listener);
|
||||
this.handlers = filtered?.length ? filtered : null;
|
||||
}
|
||||
|
||||
flagged(name, handler) {
|
||||
|
||||
return handler[name] ?? this.flags[name] ?? false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.criteria = function (criteria) {
|
||||
|
||||
if (typeof criteria === 'string') {
|
||||
return { name: criteria };
|
||||
}
|
||||
|
||||
return criteria;
|
||||
};
|
||||
37
node_modules/@hapi/podium/package.json
generated
vendored
Executable file
37
node_modules/@hapi/podium/package.json
generated
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@hapi/podium",
|
||||
"description": "Node compatible event emitter with extra features",
|
||||
"version": "5.0.2",
|
||||
"repository": "git://github.com/hapijs/podium",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"emitter",
|
||||
"event"
|
||||
],
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"plugin:@hapi/module"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^11.0.2",
|
||||
"@hapi/teamwork": "^6.0.0",
|
||||
"@hapi/validate": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hapi/code": "^9.0.3",
|
||||
"@hapi/eslint-plugin": "^6.0.0",
|
||||
"@hapi/lab": "^25.1.2",
|
||||
"@types/node": "^17.0.31",
|
||||
"typescript": "~4.6.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "lab -a @hapi/code -t 100 -L -Y",
|
||||
"test-cov-html": "lab -r html -o coverage.html -a @hapi/code -L"
|
||||
},
|
||||
"license": "BSD-3-Clause"
|
||||
}
|
||||
Reference in New Issue
Block a user