@poppinss/hooks
Advanced tools
Comparing version 7.1.1-4 to 7.1.1-5
@@ -0,1 +1,9 @@ | ||
/* | ||
* @poppinss/hooks | ||
* | ||
* (c) Poppinss | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
export { Hooks as default } from './src/hooks.js'; |
import { Runner } from './runner.js'; | ||
import { HookHandler, HookHandlerProvider } from './types.js'; | ||
/** | ||
* Quite simple implementation register lifecycle hooks around specific events. | ||
* | ||
* ```ts | ||
* const hooks = new Hooks() | ||
* | ||
* hooks.add('saving', function hashPassword(entity) { | ||
* }) | ||
* ``` | ||
*/ | ||
export declare class Hooks<Events extends Record<string, [any[], any[]]>> { | ||
#private; | ||
/** | ||
* Get access to all the registered hooks. The return value is | ||
* a map of the event name and a set of handlers. | ||
*/ | ||
all(): { [Event_1 in keyof Events]: Map<Event_1, Set<HookHandler<Events[Event_1][0], Events[Event_1][1]> | HookHandlerProvider<Events[Event_1][0], Events[Event_1][1]>>>; }[keyof Events]; | ||
/** | ||
* Find if a handler for a given event exists. | ||
*/ | ||
has<Event extends keyof Events>(event: Event, handler: HookHandler<Events[Event][0], Events[Event][1]> | HookHandlerProvider<Events[Event][0], Events[Event][1]>): boolean; | ||
/** | ||
* Add a hook handler for a given event. Adding the same handler twice will | ||
* result in a noop. | ||
*/ | ||
add<Event extends keyof Events>(event: Event, handler: HookHandler<Events[Event][0], Events[Event][1]> | HookHandlerProvider<Events[Event][0], Events[Event][1]>): this; | ||
/** | ||
* Remove hook handler for a given event. | ||
*/ | ||
remove<Event extends keyof Events>(event: Event, handler: HookHandler<Events[Event][0], Events[Event][1]> | HookHandlerProvider<Events[Event][0], Events[Event][1]>): boolean; | ||
/** | ||
* Clear all the hooks for a specific event or all the | ||
* events. | ||
*/ | ||
clear(event?: keyof Events): void; | ||
/** | ||
* Merge hooks from an existing hooks instance. | ||
*/ | ||
merge(hooks: Hooks<Events>): void; | ||
/** | ||
* Returns an instance of the runner to run hooks | ||
*/ | ||
runner<Event extends Extract<keyof Events, string>>(action: Event): Runner<Events[Event][0], Events[Event][1]>; | ||
} |
@@ -0,7 +1,35 @@ | ||
/* | ||
* @poppinss/hooks | ||
* | ||
* (c) Poppinss | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import { Runner } from './runner.js'; | ||
/** | ||
* Quite simple implementation register lifecycle hooks around specific events. | ||
* | ||
* ```ts | ||
* const hooks = new Hooks() | ||
* | ||
* hooks.add('saving', function hashPassword(entity) { | ||
* }) | ||
* ``` | ||
*/ | ||
export class Hooks { | ||
/** | ||
* A collection of registered hooks | ||
*/ | ||
#hooks = new Map(); | ||
/** | ||
* Get access to all the registered hooks. The return value is | ||
* a map of the event name and a set of handlers. | ||
*/ | ||
all() { | ||
return this.#hooks; | ||
} | ||
/** | ||
* Find if a handler for a given event exists. | ||
*/ | ||
has(event, handler) { | ||
@@ -14,4 +42,11 @@ const handlers = this.#hooks.get(event); | ||
} | ||
/** | ||
* Add a hook handler for a given event. Adding the same handler twice will | ||
* result in a noop. | ||
*/ | ||
add(event, handler) { | ||
const handlers = this.#hooks.get(event); | ||
/** | ||
* Instantiate handlers | ||
*/ | ||
if (!handlers) { | ||
@@ -23,2 +58,5 @@ this.#hooks.set(event, new Set()); | ||
} | ||
/** | ||
* Remove hook handler for a given event. | ||
*/ | ||
remove(event, handler) { | ||
@@ -31,2 +69,6 @@ const handlers = this.#hooks.get(event); | ||
} | ||
/** | ||
* Clear all the hooks for a specific event or all the | ||
* events. | ||
*/ | ||
clear(event) { | ||
@@ -39,2 +81,5 @@ if (!event) { | ||
} | ||
/** | ||
* Merge hooks from an existing hooks instance. | ||
*/ | ||
merge(hooks) { | ||
@@ -47,2 +92,5 @@ hooks.all().forEach((actionHooks, action) => { | ||
} | ||
/** | ||
* Returns an instance of the runner to run hooks | ||
*/ | ||
runner(action) { | ||
@@ -49,0 +97,0 @@ return new Runner(action, this.#hooks.get(action)); |
import { HookHandler, HookHandlerProvider } from './types.js'; | ||
/** | ||
* Runner allows running a set of specific hook handlers for a given | ||
* event. You can grab the instance of the runner using the "hook.runner" method. | ||
* | ||
* ```ts | ||
* const hooks = new Hooks() | ||
* | ||
* await hooks.runner('saving').run() | ||
* ``` | ||
*/ | ||
export declare class Runner<HookArgs extends any[], CleanUpArgs extends any[]> { | ||
#private; | ||
action: string; | ||
/** | ||
* Find if cleanup is pending or not | ||
*/ | ||
get isCleanupPending(): boolean; | ||
constructor(action: string, hookHandlers?: Set<HookHandler<HookArgs, CleanUpArgs> | HookHandlerProvider<HookArgs, CleanUpArgs>>); | ||
/** | ||
* Ignore specific or all hook handlers. Calling this | ||
* method multiple times will result in overwriting | ||
* the existing state. | ||
*/ | ||
without(handlersToIgnore?: string[]): this; | ||
/** | ||
* Execute handlers | ||
*/ | ||
run(...data: HookArgs): Promise<void>; | ||
/** | ||
* Execute cleanup actions | ||
*/ | ||
cleanup(...data: CleanUpArgs): Promise<void>; | ||
} |
@@ -0,8 +1,46 @@ | ||
/* | ||
* @poppinss/hooks | ||
* | ||
* (c) Poppinss | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
/** | ||
* Runner allows running a set of specific hook handlers for a given | ||
* event. You can grab the instance of the runner using the "hook.runner" method. | ||
* | ||
* ```ts | ||
* const hooks = new Hooks() | ||
* | ||
* await hooks.runner('saving').run() | ||
* ``` | ||
*/ | ||
export class Runner { | ||
action; | ||
/** | ||
* A collection of registered hook handlers | ||
*/ | ||
#hookHandlers; | ||
/** | ||
* Cleanup handlers should always be an array of functions. Using a set will | ||
* discard duplicates and it is very much possible for two hooks to return | ||
* a shared cleanup handler. | ||
*/ | ||
#cleanupHandlers = []; | ||
/** | ||
* State to perform the cleanup | ||
*/ | ||
#state = 'idle'; | ||
/** | ||
* A collection of handlers to ignore when executed them | ||
*/ | ||
#handlersToIgnore = []; | ||
/** | ||
* Whether or not to skip all the hooks | ||
*/ | ||
#skipAllHooks = false; | ||
/** | ||
* Find if cleanup is pending or not | ||
*/ | ||
get isCleanupPending() { | ||
@@ -15,5 +53,13 @@ return this.#state === 'cleanup_pending'; | ||
} | ||
/** | ||
* Filter to check if we should run the handler | ||
*/ | ||
#filter(handlerName) { | ||
return !this.#handlersToIgnore.includes(handlerName); | ||
} | ||
/** | ||
* Ignore specific or all hook handlers. Calling this | ||
* method multiple times will result in overwriting | ||
* the existing state. | ||
*/ | ||
without(handlersToIgnore) { | ||
@@ -29,2 +75,5 @@ if (!handlersToIgnore) { | ||
} | ||
/** | ||
* Execute handlers | ||
*/ | ||
async run(...data) { | ||
@@ -38,2 +87,5 @@ if (this.#state !== 'idle') { | ||
} | ||
/** | ||
* Execute handlers | ||
*/ | ||
for (let handler of this.#hookHandlers) { | ||
@@ -50,2 +102,5 @@ if (this.#filter(handler.name)) { | ||
} | ||
/** | ||
* Execute cleanup actions | ||
*/ | ||
async cleanup(...data) { | ||
@@ -52,0 +107,0 @@ if (!this.isCleanupPending) { |
import type { Runner } from './runner.js'; | ||
/** | ||
* Exporting hooks runner as a type | ||
*/ | ||
export { Runner }; | ||
/** | ||
* Shape of the cleanup handler | ||
*/ | ||
export type CleanupHandler<Args extends any[]> = (...args: Args) => void | Promise<void>; | ||
/** | ||
* Shape of the hook handler | ||
*/ | ||
export type HookHandler<Args extends any[], CleanUpArgs extends any[]> = (...args: Args) => void | CleanupHandler<CleanUpArgs> | Promise<void> | Promise<CleanupHandler<CleanUpArgs>>; | ||
/** | ||
* Extracts args from a hook handler type | ||
*/ | ||
export type ExtractHookHandlerArgs<Handler> = Handler extends HookHandler<infer A, infer B> ? [A, B] : never; | ||
/** | ||
* Hook represented as an object with handle method | ||
*/ | ||
export type HookHandlerProvider<Args extends any[], CleanUpArgs extends any[]> = { | ||
@@ -7,0 +22,0 @@ name: string; |
@@ -0,1 +1,9 @@ | ||
/* | ||
* @poppinss/hooks | ||
* | ||
* (c) Poppinss | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
export {}; |
{ | ||
"name": "@poppinss/hooks", | ||
"version": "7.1.1-4", | ||
"version": "7.1.1-5", | ||
"description": "A no brainer hooks module for execute before/after lifecycle hooks", | ||
@@ -41,21 +41,21 @@ "main": "build/index.js", | ||
"devDependencies": { | ||
"@adonisjs/eslint-config": "^1.1.6", | ||
"@adonisjs/prettier-config": "^1.1.6", | ||
"@adonisjs/tsconfig": "^1.1.6", | ||
"@commitlint/cli": "^17.6.6", | ||
"@commitlint/config-conventional": "^17.6.6", | ||
"@adonisjs/eslint-config": "^1.1.8", | ||
"@adonisjs/prettier-config": "^1.1.8", | ||
"@adonisjs/tsconfig": "^1.1.8", | ||
"@commitlint/cli": "^17.7.1", | ||
"@commitlint/config-conventional": "^17.7.0", | ||
"@japa/assert": "^2.0.0-1", | ||
"@japa/expect-type": "^2.0.0-0", | ||
"@japa/runner": "^3.0.0-2", | ||
"@swc/core": "^1.3.67", | ||
"@types/node": "^20.3.2", | ||
"c8": "^8.0.0", | ||
"del-cli": "^5.0.0", | ||
"eslint": "^8.43.0", | ||
"@swc/core": "1.3.82", | ||
"@types/node": "^20.6.3", | ||
"c8": "^8.0.1", | ||
"del-cli": "^5.1.0", | ||
"eslint": "^8.50.0", | ||
"github-label-sync": "^2.3.1", | ||
"husky": "^8.0.3", | ||
"np": "^8.0.4", | ||
"prettier": "^2.8.8", | ||
"prettier": "^3.0.3", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.1.6" | ||
"typescript": "^5.2.2" | ||
}, | ||
@@ -62,0 +62,0 @@ "repository": { |
@@ -5,3 +5,3 @@ # @poppinss/hooks | ||
[![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url] [![synk-image]][synk-url] | ||
[![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url] | ||
@@ -172,11 +172,12 @@ This package is a zero-dependency implementation for running lifecycle hooks around an event. Following are some of the notable features. | ||
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/poppinss/hooks/test.yml?style=for-the-badge | ||
[gh-workflow-url]: https://github.com/poppinss/hooks/actions/workflows/test.yml 'Github action' | ||
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/poppinss/hooks/checks.yml?style=for-the-badge | ||
[gh-workflow-url]: https://github.com/poppinss/hooks/actions/workflows/checks.yml 'Github action' | ||
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript | ||
[typescript-url]: "typescript" | ||
[npm-image]: https://img.shields.io/npm/v/@poppinss/hooks.svg?style=for-the-badge&logo=npm | ||
[npm-url]: https://npmjs.org/package/@poppinss/hooks 'npm' | ||
[license-image]: https://img.shields.io/npm/l/@poppinss/hooks?color=blueviolet&style=for-the-badge | ||
[license-url]: LICENSE.md 'license.' | ||
[synk-image]: https://img.shields.io/snyk/vulnerabilities/github/poppinss/hooks?label=Synk%20Vulnerabilities&style=for-the-badge | ||
[synk-url]: https://snyk.io/test/github/poppinss/hooks?targetFile=package.json 'synk' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18357
331
182