diff options
| -rw-r--r-- | .editorconfig | 1 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 41 | ||||
| -rw-r--r-- | package.json | 35 | ||||
| -rw-r--r-- | src/index.ts | 28 | ||||
| -rw-r--r-- | test/index_test.ts (renamed from test/index.js) | 6 | ||||
| -rw-r--r-- | test/test-types-compilation.ts | 43 | ||||
| -rw-r--r-- | test/types.ts | 20 | ||||
| -rw-r--r-- | tsconfig.json | 8 |
9 files changed, 111 insertions, 72 deletions
diff --git a/.editorconfig b/.editorconfig index ac0adb7..04d7ef9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,7 @@ insert_final_newline = true [{package.json,.*rc,*.yml}] indent_style = space indent_size = 2 +insert_final_newline = false [*.md] trim_trailing_whitespace = false @@ -2,6 +2,7 @@ /test-reports /node_modules /npm-debug.log +/index.d.ts package-lock.json .DS_Store .idea @@ -102,38 +102,23 @@ const emitter: mitt.Emitter = mitt(); #### Table of Contents - [mitt](#mitt) -- [emit](#emit) - - [Properties](#properties) -- [emit](#emit-1) - - [Parameters](#parameters) +- [all](#all) - [on](#on) - - [Parameters](#parameters-1) + - [Parameters](#parameters) - [off](#off) + - [Parameters](#parameters-1) +- [emit](#emit) - [Parameters](#parameters-2) ### mitt Mitt: Tiny (~200b) functional event emitter / pubsub. -Returns **Mitt** - -### emit - -#### Properties - -- `all` **EventHandlerMap** Contains all registered event handlers. - -### emit - -Invoke all handlers for the given type. -If present, `"*"` handlers are invoked after type-matched handlers. - -Note: Manually firing "\*" handlers is not supported. +Returns **Mitt** -#### Parameters +### all -- `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** The event type to invoke -- `evt` **Any?** Any value (object is recommended and powerful), passed to each handler +A Map of event names to registered handler functions. ### on @@ -153,6 +138,18 @@ Remove an event handler for the given type. - `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** Type of event to unregister `handler` from, or `"*"` - `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** Handler function to remove +### emit + +Invoke all handlers for the given type. +If present, `"*"` handlers are invoked after type-matched handlers. + +Note: Manually firing "\*" handlers is not supported. + +#### Parameters + +- `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** The event type to invoke +- `evt` **Any?** Any value (object is recommended and powerful), passed to each handler + ## Contribute First off, thanks for taking the time to contribute! diff --git a/package.json b/package.json index 90b7b74..a2c2b58 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,13 @@ "esmodules": "dist/mitt.modern.js", "main": "dist/mitt.js", "umd:main": "dist/mitt.umd.js", - "typings": "dist/index.d.ts", + "typings": "index.d.ts", "scripts": { - "test": "npm-run-all --silent typecheck lint testonly", - "testonly": "mocha --require esm test/**/*.js", + "test": "npm-run-all --silent typecheck lint mocha test-types", + "mocha": "mocha test", + "test-types": "tsc test/test-types-compilation.ts --noEmit", "lint": "eslint src test --ext ts --ext js", - "typecheck": "tsc **/*.ts --noEmit", + "typecheck": "tsc --noEmit", "bundle": "microbundle", "build": "npm-run-all --silent clean -p bundle -s docs", "clean": "rimraf dist", @@ -34,8 +35,21 @@ "license": "MIT", "files": [ "src", - "dist" + "dist", + "index.d.ts" ], + "mocha": { + "extension": [ + "ts" + ], + "require": [ + "ts-node/register", + "esm" + ], + "spec": [ + "test/*_test.ts" + ] + }, "eslintConfig": { "extends": [ "developit", @@ -68,7 +82,8 @@ } }, "eslintIgnore": [ - "dist" + "dist", + "index.d.ts" ], "devDependencies": { "@types/chai": "^4.2.11", @@ -82,13 +97,13 @@ "eslint": "^7.1.0", "eslint-config-developit": "^1.2.0", "esm": "^3.2.25", - "microbundle": "^0.12.0", - "mocha": "^7.2.0", + "microbundle": "^0.12.3", + "mocha": "^8.0.1", "npm-run-all": "^4.1.5", "rimraf": "^3.0.2", "sinon": "^9.0.2", "sinon-chai": "^3.5.0", - "ts-node": "^8.10.1", + "ts-node": "^8.10.2", "typescript": "^3.9.3" } -} +}
\ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 0350868..ae85607 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,8 @@ export type EventType = string | symbol; // An event handler can take an optional event argument // and should not return a value -export type Handler = (event?: any) => void; -export type WildcardHandler = (type: EventType, event?: any) => void +export type Handler<T = any> = (event?: T) => void; +export type WildcardHandler = (type: EventType, event?: any) => void; // An array of all currently registered event handlers for a type export type EventHandlerList = Array<Handler>; @@ -15,28 +15,29 @@ export type EventHandlerMap = Map<EventType, EventHandlerList | WildCardEventHan export interface Emitter { all: EventHandlerMap; - on(type: EventType, handler: Handler): void; + on<T = any>(type: EventType, handler: Handler<T>): void; on(type: '*', handler: WildcardHandler): void; - off(type: EventType, handler: Handler): void; + off<T = any>(type: EventType, handler: Handler<T>): void; off(type: '*', handler: WildcardHandler): void; emit<T = any>(type: EventType, event?: T): void; emit(type: '*', event?: any): void; } -/** Mitt: Tiny (~200b) functional event emitter / pubsub. - * @name mitt - * @returns {Mitt} +/** + * Mitt: Tiny (~200b) functional event emitter / pubsub. + * @name mitt + * @returns {Mitt} */ export default function mitt(all?: EventHandlerMap): Emitter { all = all || new Map(); - /** - * @property {EventHandlerMap} all Contains all registered event handlers. - */ return { + /** + * A Map of event names to registered handler functions. + */ all, /** @@ -45,7 +46,7 @@ export default function mitt(all?: EventHandlerMap): Emitter { * @param {Function} handler Function to call in response to given event * @memberOf mitt */ - on(type: EventType, handler: Handler) { + on<T = any>(type: EventType, handler: Handler<T>) { const handlers = all.get(type); const added = handlers && handlers.push(handler); if (!added) { @@ -55,12 +56,11 @@ export default function mitt(all?: EventHandlerMap): Emitter { /** * Remove an event handler for the given type. - * * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` * @param {Function} handler Handler function to remove * @memberOf mitt */ - off(type: EventType, handler: Handler) { + off<T = any>(type: EventType, handler: Handler<T>) { const handlers = all.get(type); if (handlers) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); @@ -77,7 +77,7 @@ export default function mitt(all?: EventHandlerMap): Emitter { * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ - emit(type: EventType, evt: any) { + emit<T = any>(type: EventType, evt: T) { ((all.get(type) || []) as EventHandlerList).slice().map((handler) => { handler(evt); }); ((all.get('*') || []) as WildCardEventHandlerList).slice().map((handler) => { handler(type, evt); }); } diff --git a/test/index.js b/test/index_test.ts index 473e92e..5c25b55 100644 --- a/test/index.js +++ b/test/index_test.ts @@ -1,4 +1,4 @@ -import mitt from '..'; +import mitt, { Emitter } from '..'; import chai, { expect } from 'chai'; import { spy } from 'sinon'; import sinonChai from 'sinon-chai'; @@ -23,7 +23,7 @@ describe('mitt', () => { }); describe('mitt#', () => { - let events, inst; + let events, inst: Emitter; beforeEach( () => { events = new Map(); @@ -151,7 +151,7 @@ describe('mitt#', () => { it('should invoke handler for type', () => { const event = { a: 'b' }; - inst.on('foo', (one, two) => { + inst.on('foo', (one, two?) => { expect(one).to.deep.equal(event); expect(two).to.be.an('undefined'); }); diff --git a/test/test-types-compilation.ts b/test/test-types-compilation.ts new file mode 100644 index 0000000..00510da --- /dev/null +++ b/test/test-types-compilation.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-unused-vars */ + +import mitt from '..'; + +const emitter = mitt(); + +/* + * Check that if on is provided a generic, it only accepts handlers of that type + */ +{ + const badHandler = (x: number) => {}; + const goodHandler = (x: string) => {}; + + // @ts-expect-error + emitter.on<string>('foo', badHandler); + emitter.on<string>('foo', goodHandler); +} + +/* + * Check that if off is provided a generic, it only accepts handlers of that type + */ +{ + const badHandler = (x: number) => {}; + const goodHandler = (x: string) => {}; + + // @ts-expect-error + emitter.off<string>('foo', badHandler); + emitter.off<string>('foo', goodHandler); +} + + +/* + * Check that if emitt is provided a generic, it only accepts event data of that type + */ +{ + interface SomeEventData { + name: string; + } + // @ts-expect-error + emitter.emit<SomeEventData>('foo', 'NOT VALID'); + emitter.emit<SomeEventData>('foo', { name: 'jack' }); +} + diff --git a/test/types.ts b/test/types.ts deleted file mode 100644 index 23334bb..0000000 --- a/test/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import mitt, { EventHandlerList, EventHandlerMap } from '..'; - -const events = mitt(); -function foo() {} -events.on('foo', foo); -events.emit('foo', 'hello'); - -// handler return type should be ignored: -events.on('foo', async e => e * 42); - -// event map type -const map = new Map<string, EventHandlerList>([ - ['foo', [foo]] -]); -const events2 = mitt(map); -events2.emit('foo', 'hello'); - -// event map type & iterables -const map2 : EventHandlerMap = new Map(Object.entries(({ foo: [foo] }))); -mitt(map2); diff --git a/tsconfig.json b/tsconfig.json index 2610831..acab4f5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,9 +3,11 @@ "compilerOptions": { "noEmit": true, "declaration": true, - "moduleResolution": "node" + "moduleResolution": "node", + "esModuleInterop": true }, - "exclude": [ - "test" + "include": [ + "src/*.ts", + "test/*.ts", ] } |
