This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+108
View File
@@ -0,0 +1,108 @@
/// <reference path="../../adonis-typings/events.d.ts" />
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
import { AnyHandler, EventsList, TrapHandler, EventHandler, DataForEvent, ErrorHandler, TrapAllHandler, EmitterContract, EmitterTransportContract } from '@ioc:Adonis/Core/Event';
import { FakeEmitter } from '../FakeEmitter';
/**
* Emitter class exposes the API for async event emitter built on top of
* Emittery. It also exposes an API to pre-define the Typescript types
* for different events.
*/
export declare class Emitter implements EmitterContract {
transport: EmitterTransportContract;
private iocResolver?;
/**
* Error handler to report emitter errors
*/
private errorHandler?;
/**
* Deprecated properties to manage trapping events
*/
private trappingEvents;
private traps;
private trapAllHandler?;
/**
* Fakes
*/
private eventsToFake;
private fakeEmitter;
constructor(app?: ApplicationContract);
/**
* Returns reference to the IoC resolver. Do not call this method until
* handler is not a string
*/
private getResolver;
/**
* Define a custom error handler
*/
onError(handler: ErrorHandler): this;
/**
* Define event handler for a given event
*/
on<K extends keyof EventsList | string>(event: K, handler: EventHandler<DataForEvent<K>> | string): this;
/**
* Define event handler for a given event and to be called
* only once.
*/
once<K extends keyof EventsList | string>(event: K, handler: EventHandler<DataForEvent<K>> | string): this;
/**
* Define catch all event handler to listen for all events.
*/
onAny(handler: AnyHandler | string): this;
/**
* Emit event
*/
emit<K extends keyof EventsList | string>(event: K, data: DataForEvent<K>): Promise<any>;
/**
* Remove existing event listener
*/
off<K extends keyof EventsList>(event: K | string, handler: EventHandler | string): void;
/**
* Remove existing event listener for catch all handler
*/
offAny(handler: AnyHandler | string): void;
/**
* Remove existing event listener.
* @alias off
*/
clearListener<K extends keyof EventsList | string>(event: K, handler: EventHandler | string): void;
/**
* Clear all listeners for a given event
*/
clearListeners<K extends keyof EventsList | string>(event: K): void;
/**
* Clear all listeners for all events
*/
clearAllListeners(): void;
/**
* Returns count of listeners for a given event or all
* events.
*/
listenerCount<K extends keyof EventsList | string>(event?: K): number;
/**
* Returns a boolean telling if listeners count for a given
* event or all events is greater than 0 or not.
*/
hasListeners<K extends keyof EventsList | string>(event?: K): boolean;
/**
* Define custom namespace for event listeners. It is set to `App/Listeners`
* by default.
*/
namespace(namespace: string): this;
/**
* Trap event instead of emitting it
*/
trap<K extends keyof EventsList | string>(event: K, handler: TrapHandler<DataForEvent<K>>): this;
/**
* Trap all events instead of emitting them
*/
trapAll(handler: TrapAllHandler): this;
/**
* Fake event emitter to collect events in-memory vs
* emitting them
*/
fake(events?: any[]): FakeEmitter;
/**
* Restore fakes
*/
restore(): void;
}
+250
View File
@@ -0,0 +1,250 @@
"use strict";
/*
* @adonisjs/events
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Emitter = void 0;
/// <reference path="../../adonis-typings/events.ts" />
const emittery_1 = __importDefault(require("emittery"));
const FakeEmitter_1 = require("../FakeEmitter");
const IocResolver_1 = require("../IocResolver");
/**
* Emitter class exposes the API for async event emitter built on top of
* Emittery. It also exposes an API to pre-define the Typescript types
* for different events.
*/
class Emitter {
constructor(app) {
this.transport = new emittery_1.default();
/**
* Deprecated properties to manage trapping events
*/
this.trappingEvents = false;
this.traps = new Map();
/**
* Fakes
*/
this.eventsToFake = new Set();
this.fakeEmitter = new FakeEmitter_1.FakeEmitter();
if (app) {
this.iocResolver = new IocResolver_1.IocResolver(app);
}
}
/**
* Returns reference to the IoC resolver. Do not call this method until
* handler is not a string
*/
getResolver(handler) {
if (!this.iocResolver) {
throw new Error(`Cannot resolve string based event handler "${handler}". IoC container is not provided to the event emitter`);
}
return this.iocResolver;
}
/**
* Define a custom error handler
*/
onError(handler) {
this.errorHandler = handler;
return this;
}
/**
* Define event handler for a given event
*/
on(event, handler) {
if (typeof handler === 'string') {
handler = this.getResolver(handler).getEventHandler(event, handler);
}
this.transport.on(event, handler);
return this;
}
/**
* Define event handler for a given event and to be called
* only once.
*/
once(event, handler) {
this.transport.once(event).then((data) => {
if (typeof handler === 'string') {
this.getResolver(handler).getEventHandler(event, handler)(data);
this.getResolver(handler).removeEventHandler(event, handler);
}
else {
handler(data);
}
});
return this;
}
/**
* Define catch all event handler to listen for all events.
*/
onAny(handler) {
if (typeof handler === 'string') {
handler = this.getResolver(handler).getAnyHandler(handler);
}
this.transport.onAny(handler);
return this;
}
/**
* Emit event
*/
async emit(event, data) {
try {
let shouldEmitEvent = true;
/**
* Register event with the fake emitter
*/
if (this.eventsToFake.has('*') || this.eventsToFake.has(event)) {
shouldEmitEvent = false;
this.fakeEmitter.events.push({ name: event, data });
}
if (this.trappingEvents) {
/**
* Give preference to the handler for a specific event
*/
if (this.traps.has(event)) {
shouldEmitEvent = false;
await this.traps.get(event)(data);
}
else if (this.trapAllHandler) {
shouldEmitEvent = false;
await this.trapAllHandler(event, data);
}
}
if (shouldEmitEvent) {
return await this.transport.emit(event, data);
}
}
catch (error) {
if (this.errorHandler) {
return this.errorHandler(event, error, data);
}
throw error;
}
}
/**
* Remove existing event listener
*/
off(event, handler) {
if (typeof handler === 'string') {
const offHandler = this.getResolver(handler).removeEventHandler(event, handler);
if (offHandler) {
this.transport.off(event, offHandler);
}
return;
}
this.transport.off(event, handler);
}
/**
* Remove existing event listener for catch all handler
*/
offAny(handler) {
if (typeof handler === 'string') {
const offHandler = this.getResolver(handler).removeAnyHandler(handler);
if (offHandler) {
this.transport.offAny(offHandler);
}
return;
}
this.transport.offAny(handler);
}
/**
* Remove existing event listener.
* @alias off
*/
clearListener(event, handler) {
this.off(event, handler);
}
/**
* Clear all listeners for a given event
*/
clearListeners(event) {
this.transport.clearListeners(event);
}
/**
* Clear all listeners for all events
*/
clearAllListeners() {
this.transport.clearListeners();
}
/**
* Returns count of listeners for a given event or all
* events.
*/
listenerCount(event) {
return this.transport.listenerCount(event ? event : undefined);
}
/**
* Returns a boolean telling if listeners count for a given
* event or all events is greater than 0 or not.
*/
hasListeners(event) {
return this.listenerCount(event) > 0;
}
/**
* Define custom namespace for event listeners. It is set to `App/Listeners`
* by default.
*/
namespace(namespace) {
if (this.iocResolver) {
this.iocResolver.namespace(namespace);
}
return this;
}
/**
* Trap event instead of emitting it
*/
trap(event, handler) {
process.emitWarning('DeprecationWarning', '"Event.trap" is deprecated. Instead use "Event.fake" method');
this.trappingEvents = true;
this.traps.set(event, handler);
return this;
}
/**
* Trap all events instead of emitting them
*/
trapAll(handler) {
process.emitWarning('DeprecationWarning', '"Event.trapAll" is deprecated. Instead use "Event.fake" method');
this.trappingEvents = true;
this.trapAllHandler = handler;
return this;
}
/**
* Fake event emitter to collect events in-memory vs
* emitting them
*/
fake(events) {
/**
* If no events have been mentioned, then fake
* all the events
*/
if (!events) {
this.eventsToFake.add('*');
return this.fakeEmitter;
}
/**
* Only track event names when wildcard is not added
*/
if (!this.eventsToFake.has('*')) {
events.forEach((event) => this.eventsToFake.add(event));
}
return this.fakeEmitter;
}
/**
* Restore fakes
*/
restore() {
this.trappingEvents = false;
this.trapAllHandler = undefined;
this.traps.clear();
this.eventsToFake.clear();
this.fakeEmitter.restore();
}
}
exports.Emitter = Emitter;
+44
View File
@@ -0,0 +1,44 @@
import { FakeEmitterContract } from '@ioc:Adonis/Core/Event';
/**
* Fake emitter to be used for finding and asserting
* faked events
*/
export declare class FakeEmitter implements FakeEmitterContract {
events: {
name: string;
data: any;
}[];
/**
* Get all the emitted events
*/
all(): {
name: string;
data: any;
}[];
/**
* Returns the size of captured events
*/
size(): number;
/**
* Find if the event has emitted
*/
exists(eventOrCallback: string | ((event: {
name: string;
data: any;
}) => boolean)): boolean;
/**
* Get selected events
*/
filter(eventOrCallback: string | ((event: {
name: string;
data: any;
}) => boolean)): any[];
/**
* Find a specific event
*/
find(eventOrCallback: string | ((event: {
name: string;
data: any;
}) => boolean)): any;
restore(): void;
}
+60
View File
@@ -0,0 +1,60 @@
"use strict";
/*
* @adonisjs/events
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FakeEmitter = void 0;
/**
* Fake emitter to be used for finding and asserting
* faked events
*/
class FakeEmitter {
constructor() {
this.events = [];
}
/**
* Get all the emitted events
*/
all() {
return this.events;
}
/**
* Returns the size of captured events
*/
size() {
return this.events.length;
}
/**
* Find if the event has emitted
*/
exists(eventOrCallback) {
return !!this.find(eventOrCallback);
}
/**
* Get selected events
*/
filter(eventOrCallback) {
if (typeof eventOrCallback === 'function') {
return this.events.filter(eventOrCallback);
}
return this.events.filter((event) => event.name === eventOrCallback);
}
/**
* Find a specific event
*/
find(eventOrCallback) {
if (typeof eventOrCallback === 'function') {
return this.events.find(eventOrCallback);
}
return this.events.find((event) => event.name === eventOrCallback);
}
restore() {
this.events = [];
}
}
exports.FakeEmitter = FakeEmitter;
+65
View File
@@ -0,0 +1,65 @@
/// <reference path="../../adonis-typings/events.d.ts" />
import { ApplicationContract } from '@ioc:Adonis/Core/Application';
import { AnyHandler, EventHandler } from '@ioc:Adonis/Core/Event';
/**
* Resolves string based event listeners from the IoC container. Also this method wraps
* the IoC container bindings in a closure. That closure is later used to remove
* the event listeners properly.
*/
export declare class IocResolver {
/**
* A reference to the event handlers resolved from the IoC container and
* cached. It is a map of
*
* [event, [namespace, resolvedHandler]]
*/
private eventHandlers;
/**
* A reference to the catch all event handlers. It is a map of
*
* [namespace, resolvedHandler]
*/
private anyHandlers;
/**
* Reference to AdonisJS IoC container resolver. It looks for listeners inside the
* `App/Listeners` namespace or the namespace defined inside `eventListeners`
* property
*/
private containerResolver;
/**
* A custom base namespace defined directly on the event class.
*/
private listenersBaseNamespace?;
constructor(app: ApplicationContract);
/**
* Returns the listener by resolving the namespace from the IoC container
*/
private getReferenceListener;
/**
* Returns all handlers for a given event.
*/
private getHandlersFor;
/**
* Define custom namespace for Event listeners
*/
namespace(namespace: string): void;
/**
* Returns event handler callback for an IoC container string reference.
* Adding same handler for the same event is noop.
*/
getEventHandler(event: string, handler: string): EventHandler;
/**
* Removes the event handler from the tracked list and also returns
* it back.
*/
removeEventHandler(event: string, handler: string): EventHandler | null;
/**
* Returns Event handler for wildcard events. Adding the same
* handler for multiple times is a noop.
*/
getAnyHandler(handler: string): AnyHandler;
/**
* Removes and returns the handler for a string reference.
*/
removeAnyHandler(handler: string): AnyHandler | null;
}
+118
View File
@@ -0,0 +1,118 @@
"use strict";
/*
* @adonisjs/events
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IocResolver = void 0;
/**
* Resolves string based event listeners from the IoC container. Also this method wraps
* the IoC container bindings in a closure. That closure is later used to remove
* the event listeners properly.
*/
class IocResolver {
constructor(app) {
/**
* A reference to the event handlers resolved from the IoC container and
* cached. It is a map of
*
* [event, [namespace, resolvedHandler]]
*/
this.eventHandlers = new Map();
/**
* A reference to the catch all event handlers. It is a map of
*
* [namespace, resolvedHandler]
*/
this.anyHandlers = new Map();
this.containerResolver = app.container.getResolver(undefined, 'eventListeners', 'App/Listeners');
}
/**
* Returns the listener by resolving the namespace from the IoC container
*/
getReferenceListener(handler) {
return (...args) => {
return this.containerResolver.call(handler, this.listenersBaseNamespace, args);
};
}
/**
* Returns all handlers for a given event.
*/
getHandlersFor(event) {
if (!this.eventHandlers.has(event)) {
this.eventHandlers.set(event, new Map());
}
return this.eventHandlers.get(event);
}
/**
* Define custom namespace for Event listeners
*/
namespace(namespace) {
this.listenersBaseNamespace = namespace;
}
/**
* Returns event handler callback for an IoC container string reference.
* Adding same handler for the same event is noop.
*/
getEventHandler(event, handler) {
const handlers = this.getHandlersFor(event);
/**
* Return the existing handler when same handler for the
* same event already exists.
*
* Emittery will also re-use the same handler. So it is a noop
* everywhere.
*/
if (handlers.has(handler)) {
return handlers.get(handler);
}
const eventHandler = this.getReferenceListener(handler);
/**
* Store reference to the handler, so that we can clean it off
* later.
*/
handlers.set(handler, eventHandler);
return eventHandler;
}
/**
* Removes the event handler from the tracked list and also returns
* it back.
*/
removeEventHandler(event, handler) {
const handlers = this.getHandlersFor(event);
const eventHandler = handlers.get(handler);
if (eventHandler) {
handlers.delete(handler);
return eventHandler;
}
return null;
}
/**
* Returns Event handler for wildcard events. Adding the same
* handler for multiple times is a noop.
*/
getAnyHandler(handler) {
if (this.anyHandlers.has(handler)) {
return this.anyHandlers.get(handler);
}
const eventHandler = this.getReferenceListener(handler);
this.anyHandlers.set(handler, eventHandler);
return eventHandler;
}
/**
* Removes and returns the handler for a string reference.
*/
removeAnyHandler(handler) {
const anyHandler = this.anyHandlers.get(handler);
if (anyHandler) {
this.anyHandlers.delete(handler);
return anyHandler;
}
return null;
}
}
exports.IocResolver = IocResolver;