{"id":15647905,"url":"https://github.com/slorber/micro-typed-events","last_synced_at":"2025-04-14T19:33:39.448Z","repository":{"id":34290478,"uuid":"174499540","full_name":"slorber/micro-typed-events","owner":"slorber","description":"The smallest, most convenient typesafe TS event emitter you'll ever need","archived":false,"fork":false,"pushed_at":"2022-12-09T15:05:36.000Z","size":989,"stargazers_count":42,"open_issues_count":16,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T07:51:13.993Z","etag":null,"topics":["event-emitter","event-listener","events","javascript","listener","pubsub","stream","typescript"],"latest_commit_sha":null,"homepage":"https://sebastienlorber.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slorber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-08T08:36:57.000Z","updated_at":"2023-08-14T13:37:35.000Z","dependencies_parsed_at":"2023-01-15T05:55:38.426Z","dependency_job_id":null,"html_url":"https://github.com/slorber/micro-typed-events","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slorber%2Fmicro-typed-events","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slorber%2Fmicro-typed-events/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slorber%2Fmicro-typed-events/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slorber%2Fmicro-typed-events/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slorber","download_url":"https://codeload.github.com/slorber/micro-typed-events/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248946139,"owners_count":21187459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["event-emitter","event-listener","events","javascript","listener","pubsub","stream","typescript"],"created_at":"2024-10-03T12:21:55.959Z","updated_at":"2025-04-14T19:33:39.426Z","avatar_url":"https://github.com/slorber.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# micro-typed-events\n\n[![NPM](https://img.shields.io/npm/dm/micro-typed-events.svg)](https://www.npmjs.com/package/micro-typed-events)\n[![Build Status](https://travis-ci.com/slorber/micro-typed-events.svg?branch=master)](https://travis-ci.com/slorber/micro-typed-events)\n\n```ts\nconst events = createEvents\u003cnumber\u003e();\nconst unsubscribe = events.subscribe(num =\u003e console.log(num));\nevents.emit(42);\nevents.emit(57);\nunsubscribe();\n\nevents.emit(99); // not logged\nevents.emit('hey'); // not compiling\n```\n\nThe smallest, most convenient, typesafe (with TS, but also works with normal JS), event emitter / pubsub system you'll ever need.\n\nUnlike other event emitters, it does not use `on/off/once` methods but only a single subscribe method and returns an unsubscribe handle, which makes it more tiny, easier to type, more convenient to use with arrow functions.\n\nThe most minimal code you need for a typesafe pub/sub system, and **feature complete**, making suitable to include as a dependency on other libraries.\n\n## Install\n\n```bash\nnpm install --save micro-typed-events\n// or\nyarn add micro-typed-events\n```\n\n## Usage\n\n**Simple typed events**\n\n```ts\nimport { createEvents } from 'micro-typed-events';\n\nconst events = createEvents\u003cnumber\u003e();\n\nconst unsubscribe = events.subscribe(num =\u003e console.log(num));\n\nevents.emit(42);\nevents.emit('hey'); // Does not compile\n\nunsubscribe();\n```\n\n---\n\n**Object typed events**\n\n```ts\nimport { createEvents } from 'micro-typed-events';\n\ntype EventType = { num: number; str: string };\nconst events = createEvents\u003cEventType\u003e();\n\nconst unsubscribe = events.subscribe(obj =\u003e console.log(obj));\n\nevents.emit({ num: 42, str: 'hello' });\nevents.emit({ num: 42, str: null }); // Does not compile\n\nunsubscribe();\n```\n\n---\n\n**Multiple-args typed events**\n\n```ts\nimport { createEvents } from 'micro-typed-events';\n\nconst events = createEvents\u003cnumber, string\u003e();\n\nconst unsubscribe = events.subscribe((num, str) =\u003e console.log(num, str));\n\nevents.emit(42, 'hello');\nevents.emit('hello', 42); // Does not compile\n\nunsubscribe();\n```\n\n---\n\n**Advanced typing, dynamic args...**\n\n```ts\nimport { createEvents } from 'micro-typed-events';\n\n// Listener type is any void function\ntype ListenerType = (str: string, num: number, ...args: any[]) =\u003e void;\n\nconst events = createEvents\u003cListenerType\u003e();\n\nconst unsubscribe = events.subscribe((str, num, ...args) =\u003e\n  console.log(str, num, ...args),\n);\n\nevents.emit('hey', 1, 'blaa', 'whatever', 'you', 'want', 1, 2, 3);\nevents.emit(1, 'hey', 'blaa', 'whatever', 'you', 'want', 1, 2, 3); // Does not compile\n\nunsubscribe();\n```\n\n---\n\n**Vanilla JS**\n\n```js\nimport { createEvents } from 'micro-typed-events';\n\nconst events = createEvents();\n\nconst unsubscribe = events.subscribe(num =\u003e console.log(num));\n\nevents.emit(42);\nevents.emit('hey'); // Does not fail, you should use typescript\n\nunsubscribe();\n```\n\n## FAQ\n\n**Should I create a single events object for all my events?**\n\nNo, you should rather create one per event-type. You could expose all your events as an object, like this:\n\n```ts\nexport const ApiEvents = {\n  requests: createEvents\u003cRequest\u003e(),\n  responses: createEvents\u003cResponse\u003e(),\n  errors: createEvents\u003cErrors\u003e(),\n};\n```\n\n**Can I unsubscribe directly inside a listener**\n\nYes, listeners are able to unsubscribe themselves (or other listeners) without messing things up.\n\n**Can I subscribe directly inside a listener**\n\nYes, but that listener will only be called on next emitted event.\n\n**Can I embed this library in my library?**\n\nYes, this lib is very tiny. It exports ES and CJS modules. Here's the CJS output, I'll let you judge yourself if you can write something shorter:\n\n```js\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction createEvents() {\n    var listeners = [];\n    return {\n        subscribe: function (listener) {\n            listeners.push(listener);\n            return function () {\n                var index = listeners.indexOf(listener);\n                if (index \u003e -1) {\n                    listeners.splice(index, 1);\n                }\n            };\n        },\n        emit: function () {\n            var args = [];\n            for (var _i = 0; _i \u003c arguments.length; _i++) {\n                args[_i] = arguments[_i];\n            }\n            // take care of user trying to unsub inside a listener\n            listeners.slice().forEach(function (listener) {\n                if (listeners.indexOf(listener) \u003e -1) {\n                    listener.apply(void 0, args);\n                }\n            });\n        },\n    };\n}\n\nexports.createEvents = createEvents;\n//# sourceMappingURL=index.js.map\n```\n\n## License\n\nMIT © [slorber](https://github.com/slorber)\n\n# Hire a freelance expert\n\nLooking for a React/ReactNative freelance expert with more than 5 years production experience?\nContact me from my [website](https://sebastienlorber.com/) or with [Twitter](https://twitter.com/sebastienlorber).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslorber%2Fmicro-typed-events","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslorber%2Fmicro-typed-events","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslorber%2Fmicro-typed-events/lists"}