{"_id":"@alphanull/publisher","_rev":"4-1e9cd73bf6f3739c4a9af386f032e01e","name":"@alphanull/publisher","dist-tags":{"latest":"1.6.2"},"versions":{"1.5.1":{"name":"@alphanull/publisher","version":"1.5.1","keywords":["publisher","publish","subscribe","publish/subscribe","pubsub","observer","custom","events"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/publisher@1.5.1","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/publisher#readme","bugs":{"url":"https://github.com/alphanull/publisher/issues"},"dist":{"shasum":"73d0e5a5efac1625b3e40c5d645c9e9dd280ee19","tarball":"https://registry.npmjs.org/@alphanull/publisher/-/publisher-1.5.1.tgz","fileCount":5,"integrity":"sha512-WfDKhwLYs4whMOFA1bgKyTB/dnsw5QRbookbH0I1SHfusCZDpWFRuLb+gmfXRKPvpeo3BwYTS0NXwB3NCuW5sw==","signatures":[{"sig":"MEYCIQCRxRXN96eAEoeni+xBo2hmRa5ZBe+IEDxBm5uMOaD72AIhAO2jSD6b6B1mabqJ+ygADtjJZZkP3W+r4gqACcIJtQOn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20348},"main":"./dist/publisher.min.cjs","type":"module","module":"./dist/publisher.min.js","engines":{"node":">=16.0.0"},"exports":{"import":"./dist/publisher.min.js","require":"./dist/publisher.min.cjs"},"gitHead":"f9e35f5062757e93e4815306e3d8630247a06db2","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/publisher.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/publisher.git","type":"git"},"_npmVersion":"11.3.0","description":"Publisher is a JavaScript publish/subscribe library with many features, including: topic hierarchies, sync/async, priority, conditions, wildcards, persistent messages & more.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","eslint":"^9.22.0","rollup":"^4.39.0","globals":"^15.15.0","@eslint/js":"^9.22.0","jsdoc-to-markdown":"^9.1.1","eslint-plugin-jsdoc":"^50.6.9","rollup-plugin-delete":"^3.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^4.2.0","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/publisher_1.5.1_1745785000170_0.3659102363112434","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@alphanull/publisher","version":"1.6.0","keywords":["publisher","publish","subscribe","publish/subscribe","pubsub","observer","custom","events"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/publisher@1.6.0","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/publisher#readme","bugs":{"url":"https://github.com/alphanull/publisher/issues"},"dist":{"shasum":"390526290e269292ecbaf0f971784359c8b16c03","tarball":"https://registry.npmjs.org/@alphanull/publisher/-/publisher-1.6.0.tgz","fileCount":5,"integrity":"sha512-O1BQhDomg0XTvTbX9Y8RCkP+PGrlaQY30h0IDs68fgUJSn5tjOPaho1YLC5RvJLXdQs60S8HfpWpi78tANnP1w==","signatures":[{"sig":"MEUCIQDNrbAi6GIOQt1YjX/mUYKl/BlrnBOQhyZnbLOp4I286AIgAl0IZ5hCX3sxYQAPY6Znld/MF3LfmjlWmzO78zChvHk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20489},"main":"./dist/publisher.min.cjs","type":"module","module":"./dist/publisher.min.js","engines":{"node":">=16.0.0"},"exports":{"import":"./dist/publisher.min.js","require":"./dist/publisher.min.cjs"},"gitHead":"3cf82723c8434b57707f3d8d058baca2462631ca","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/publisher.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","actor":{"name":"alphanull","type":"user","email":"kudermann@alphanull.de"},"email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/publisher.git","type":"git"},"_npmVersion":"11.4.1","description":"Publisher is a JavaScript publish/subscribe library with many features, including: topic hierarchies, sync/async, priority, conditions, wildcards, persistent messages & more.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","eslint":"^9.22.0","rollup":"^4.39.0","globals":"^15.15.0","@eslint/js":"^9.22.0","jsdoc-to-markdown":"^9.1.1","eslint-plugin-jsdoc":"^50.6.9","rollup-plugin-delete":"^3.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^4.2.0","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/publisher_1.6.0_1751069600255_0.45544619897246585","host":"s3://npm-registry-packages-npm-production"}},"1.6.1":{"name":"@alphanull/publisher","version":"1.6.1","keywords":["publisher","publish","subscribe","publish/subscribe","pubsub","observer","custom","events"],"author":{"url":"https://alphanull.de","name":"Frank Kudermann","email":"kudermann@alphanull.de"},"license":"MIT","_id":"@alphanull/publisher@1.6.1","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"homepage":"https://github.com/alphanull/publisher#readme","bugs":{"url":"https://github.com/alphanull/publisher/issues"},"dist":{"shasum":"ccbc1f36adc66f4881e5a3ba1c899c579cbec7fa","tarball":"https://registry.npmjs.org/@alphanull/publisher/-/publisher-1.6.1.tgz","fileCount":5,"integrity":"sha512-2g7mLHYM8yE2H7DiO+Jc2S2YZWT8EIrnERjEO1JmtqopWnSj+rMMJUJWHkkrEPYN0OX/LJE4TXcIOm0mVT5k5A==","signatures":[{"sig":"MEQCIDGDcxdaF/hGxiv5zvKrq0E3nq2B+7VU4dM7/ma8Z6MrAiBBHxAvi54bYZ499YALTiaNLOFo/QN4oL8WXuCgeBoPdg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21255},"main":"./dist/publisher.min.cjs","type":"module","module":"./dist/publisher.min.js","engines":{"node":">=16.0.0"},"exports":{"import":"./dist/publisher.min.js","require":"./dist/publisher.min.cjs"},"gitHead":"7320ef92972bd3b28baf53370dc5047898d91918","scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/publisher.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_npmUser":{"name":"alphanull","actor":{"name":"alphanull","type":"user","email":"kudermann@alphanull.de"},"email":"kudermann@alphanull.de"},"repository":{"url":"git+https://github.com/alphanull/publisher.git","type":"git"},"_npmVersion":"11.4.1","description":"Publisher is a JavaScript publish/subscribe library with many features, including: topic hierarchies, sync/async, priority, conditions, wildcards, persistent messages & more.","directories":{},"sideEffects":false,"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^4.0.4","eslint":"^9.22.0","rollup":"^4.39.0","globals":"^15.15.0","@eslint/js":"^9.22.0","jsdoc-to-markdown":"^9.1.1","eslint-plugin-jsdoc":"^50.6.9","rollup-plugin-delete":"^3.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^4.2.0","@rollup/plugin-node-resolve":"^16.0.1"},"_npmOperationalInternal":{"tmp":"tmp/publisher_1.6.1_1751069902231_0.8575988593005908","host":"s3://npm-registry-packages-npm-production"}},"1.6.2":{"name":"@alphanull/publisher","license":"MIT","version":"1.6.2","description":"Publisher is a JavaScript publish/subscribe library with many features, including: topic hierarchies, sync/async, priority, conditions, wildcards, persistent messages & more.","keywords":["publisher","publish","subscribe","publish/subscribe","pubsub","observer","custom","events"],"author":{"name":"Frank Kudermann","email":"kudermann@alphanull.de","url":"https://alphanull.de"},"repository":{"type":"git","url":"git+https://github.com/alphanull/publisher.git"},"homepage":"https://github.com/alphanull/publisher#readme","bugs":{"url":"https://github.com/alphanull/publisher/issues"},"type":"module","main":"./dist/publisher.min.cjs","module":"./dist/publisher.min.js","exports":{"import":"./dist/publisher.min.js","require":"./dist/publisher.min.cjs"},"publishConfig":{"access":"public"},"sideEffects":false,"engines":{"node":">=16.0.0"},"devDependencies":{"@eslint/js":"^9.22.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^4.2.0","eslint":"^9.22.0","eslint-plugin-jsdoc":"^50.6.9","globals":"^15.15.0","jsdoc":"^4.0.4","jsdoc-to-markdown":"^9.1.1","rollup":"^4.39.0","rollup-plugin-delete":"^3.0.1"},"scripts":{"doc":"jsdoc2md --private --separators --template ./scripts/docTemplate.hbs --files ./src/*.js > ./docs/publisher.md","lint":"echo 'Running ESLint...' && eslint src/ --max-warnings=0","build":"npm run lint && rollup -c ./scripts/rollup.config.js"},"_id":"@alphanull/publisher@1.6.2","gitHead":"8e6003bcafca3c4bf9601380c261a11b34376de4","_nodeVersion":"22.13.1","_npmVersion":"11.4.1","dist":{"integrity":"sha512-0Lx/jdInhUk6uiY0Ygiu67iC8FK3F21+MbfnoRzUxQT0knbBXyZb72SUxjw8h+uX8GtQwAV5GW4UjtjMTRfqlw==","shasum":"6de2867078367fd934459118b51227e5cb8b51d1","tarball":"https://registry.npmjs.org/@alphanull/publisher/-/publisher-1.6.2.tgz","fileCount":5,"unpackedSize":21005,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDPoLYP+5G68H0x4r9nW/326MS0RZR/DpvpmKUbTTMu6AIgWZvG6HJ0vDg/BckfhLZpyVxJEDQe9Y0m2bKvP5CipXE="}]},"_npmUser":{"name":"alphanull","email":"kudermann@alphanull.de","actor":{"name":"alphanull","email":"kudermann@alphanull.de","type":"user"}},"directories":{},"maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/publisher_1.6.2_1751070408048_0.939629486813538"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-27T20:16:40.061Z","modified":"2025-06-28T00:26:48.453Z","1.5.1":"2025-04-27T20:16:40.353Z","1.6.0":"2025-06-28T00:13:20.430Z","1.6.1":"2025-06-28T00:18:22.420Z","1.6.2":"2025-06-28T00:26:48.263Z"},"bugs":{"url":"https://github.com/alphanull/publisher/issues"},"author":{"name":"Frank Kudermann","email":"kudermann@alphanull.de","url":"https://alphanull.de"},"license":"MIT","homepage":"https://github.com/alphanull/publisher#readme","keywords":["publisher","publish","subscribe","publish/subscribe","pubsub","observer","custom","events"],"repository":{"type":"git","url":"git+https://github.com/alphanull/publisher.git"},"description":"Publisher is a JavaScript publish/subscribe library with many features, including: topic hierarchies, sync/async, priority, conditions, wildcards, persistent messages & more.","maintainers":[{"name":"alphanull","email":"kudermann@alphanull.de"}],"readme":"![License](https://img.shields.io/github/license/alphanull/publisher)\n![Version](https://img.shields.io/npm/v/@alphanull/publisher)\n[![JSDoc](https://img.shields.io/badge/docs-JSDoc-blue)](./docs/publisher.md)\n![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/@alphanull/publisher)\n\n# @alphanull/publisher\n\nPublisher is a JavaScript Publish/Subscribe (Pub/Sub) library crafted to handle event-driven communication. Provides pub/sub functionality with extensive wildcard support, async/sync publishing, priority and invocation options, content based filtering & more.\n\nThe heart of Publisher lies in its uniquely optimized hierarchical data structure, providing fast subscriber matching even with extensive subscription sets. Unlike traditional flat Pub/Sub systems, Publisher allows you to easily organize events into structured topics and leverage wildcard subscriptions for additional flexibility.\n\nWhether you're building scalable web applications or complex front-end architectures, Publisher ensures your events and notifications are handled gracefully and reliably, delivering ease of use combined with powerful features.\n\n## Features\n\n- **Topic Hierarchy & Wildcards**: Manage event complexity with a structured hierarchy and wildcard topic matching.\n- **Persisted Messages**: Ensure subscribers never miss critical events, delivering persistent messages immediately upon subscribing.\n- **Priority & Invocations**: Gain fine-grained control over execution order and limit subscription triggers, improving predictability and efficiency.\n- **Async & Exception Handling**: Dispatch events asynchronously or synchronously with built-in exception handling.\n- **Conditional Execution**: Execute subscriptions only when specific conditions are met.\n- **Global Configuration**: Configure default behavior globally for asynchronous dispatch, error handling, and unsubscribing behavior.\n\n## Installation\n\n### via NPM\n\n```bash\nnpm install @alphanull/publisher\n```\n\n### via CDN\n\n[Download latest version](https://cdn.jsdelivr.net/npm/@alphanull/publisher@1/dist/publisher.min.js) from jsDelivr\n[Download latest version](https://unpkg.com/@alphanull/publisher@1/dist/publisher.min.js) from unpkg\n\n### via GitHub\n\n[Download release](https://github.com/alphanull/publisher/releases) from GitHub\n\n## Usage\n\n### 1. Initialization\n\npublisher can be used as ES6 module (recommended) but also via `require` in NodeJS or with direct access to a global variable:\n\n#### ES6\n\n```javascript\nimport { publish, subscribe, unsubscribe } from '@alphanull/publisher';\n```\n\n#### CommonJS\n\n```javascript\nconst { publish, subscribe, unsubscribe } = require('@alphanull/publisher');\n```\n\n#### Global Variable\n\n```html\n<script src=\"path/to/publisher.min.cjs\"></script>\n```\n\n```javascript\nconst { publish, subscribe, unsubscribe } = publisher;\n```\n\n### 2. Basic Usage\n\nQuickly set up a simple Pub/Sub interaction:\n\n```javascript\nimport { publish, subscribe, unsubscribe } from '@alphanull/publisher';\n\nconst handler = data => {\n      console.log(`User logged in: ${data.username}`);\n}\n\n// Receiver: subscribe to a specific topic\nconst token = subscribe('login', handler);\n\n// Sender: publish an event\npublish('login', { username: 'Alice' });\n\n// Receiver: unsubscribe using the token (recommended)\nunsubscribe(token);\n\n// Receiver: alternatively, unsubscribe using topic and handler\nunsubscribe('login', handler);\n```\n\n### 3. Hierarchy and Wildcards\n\nBy utilizing topic hierarchies and wildcards, you can subscribe to multiple events. A hierachy is created by using the `/` delimiter to create topic segments, while a `*` is used to match any topic segment:\n\n```javascript\n// Subscribe to ALL topics\nsubscribe('*', (data, topic) => {\n    console.log(`Event ${topic} received:`, data);\n});\n\n// Subscribe to all \"user\"-related topics, INCLUDING \"user\"\nsubscribe('user', (data, topic) => {\n    console.log(`Event ${topic} received:`, data);\n});\n\n// Subscribe to all \"user\"-related topics, EXCLUDING \"user\"\nsubscribe('user/*', (data, topic) => {\n    console.log(`Event ${topic} received:`, data);\n});\n\n// Matching multiple topics with wildcards\nsubscribe('app/*/update', (data, topic) => {\n    console.log(`Update from ${topic}:`, data);\n});\n\npublish('user/logout', { username: 'Bob' }); // triggers first, second & third subscriber\npublish('app/profile/update', { username: 'Charlie' }); // triggers first and fourth subscribers\npublish('app/settings/update', { theme: 'dark' }); // triggers first and fourth subscribers\n```\n\n### 4. Advanced Unsubscribe: Multiple Tokens, Lenient Unsubscribe\n\nYou can also use an array of tokens to quickly unsubscribe multiple handlers. In addition, adding `true` to the second argument (or the third, in case you use topic/handler for unsubscribe) does not fail with an error if the matching token was not found.\n\n```javascript\nconst tokens = [\n    subscribe('topic/1', handler),\n    subscribe('topic/2', handler)\n];\n\n// Batch unsubscribe\nunsubscribe(tokens);\n\n// Lenient unsubscribe, silently ignores non-existing tokens\nunsubscribe(9999, true);\n```\n\n### 5. Async and Sync Usage, Cancellation\n\nBy default, all events are sent asynchronously. You can override this behavior globally (see 10.) or with individual `publish` actions by using `async: false` as an option. In addition, when using synchronous `publish`, any subscriber is able to cancel an event, so that subsequent subscribers are not notified anymore. So basically, this works similar to the cancellation of DOM Events.\n\n```javascript\n// return false in a handler cancels the chain\nsubscribe('sync/event', () => false); \n\n// Synchronous event publishing can be canceled \npublish('sync/event', {}, { async: false, cancelable: true });\n```\n\n### 6. Priority\n\nUsually, subscribers are notifed in the order they subscribed, i.e. the first subscriber is receiving the first message. You can change this behavior adding a `priority` option, where higher numbers are executed first, with `0` being the default. \n\n```javascript\n// Control subscriber order with priorities\nsubscribe('priority/event', () => console.log('second'), { priority: 1 });\nsubscribe('priority/event', () => console.log('first'), { priority: 2 });\n\npublish('priority/event');\n```\n\n### 7. Invocations\n\nIt is also possible to limit the number of handler invocations by adding the `invocations` option, this being a positive number counting down when the handler is called. Once the counter reaches `0` the handler is automatically unsubscribed. For example, the following code executes the handler only on the first `publish` occurence:\n\n```javascript\n// Limit subscription invocations\nsubscribe('limited/event', () => console.log('I only execute once'), { invocations: 1 });\n\npublish('limited/event'); // triggers handler\npublish('limited/event'); // not triggered anymore, handler was unsubscribed\n```\n\n### 8. Conditional Execution\n\nRun subscriptions based on conditional logic, so that the handler is only invoked if the function specified by the `condition` option returns true:\n\n```javascript\nsubscribe('data/event', data => {\n    console.log('Condition met:', data);\n}, {\n    condition: data => data.status === 'success'\n});\n\npublish('data/event', { status: 'success' }); // triggers subscriber\npublish('data/event', { status: 'error' }); // ignored\n```\n\n### 9. Persistency\n\nEnsure certain messages are received even when the subscription is done after the actual message was already sent. For this to happen, _both_ `publish` and `subscribe` have to use the `persist: true` option. It is also possible to remove a perssitent message later on using `removePersistentMessage`.\n\n```javascript\nimport { publish, subscribe, removePersistentMessage } from './publisher.js';\n\n// make message persistent\npublish('app/ready', { status: 'ready' }, { persist: true });\n\n// Subscribers immediately receive persistent messages upon subscription\nsubscribe('app/ready', data => console.log('Persistently received:', data), { persist: true });\n\n// after removing, later subscriber don't receive the event anymore\nremovePersistentMessage('app/ready');\n```\n\n### 10. Error Handling\n\nBy default, if a handler throws an Error, it is caught by the publisher so that subsequent subscribers are still being executed. Instead the error is output to the console (if possible). This behavior can be changed globally, or per `publish` so that exceptions are not caught anymore.\n\n```javascript\nsubscribe('error/event', () => {\n    throw new Error('Subscriber error!');\n});\n\nsubscribe('error/event', () => {\n    console.log('I still might be executed');\n});\n\n// Errors caught internally, other subscribers remain unaffected\npublish('error/event', data , { handleExceptions: true });\n\n// Throws an error, publishing is halted\npublish('error/event', data , { handleExceptions: false });\n```\n\n### 11. Global Configuration\n\nConfigure Publisher.js globally to tailor its behavior. All subsequent actions will use the newly set option(s), unless locally overidden.\n\n```javascript\nimport { configure } from './publisher.js';\n\n// Equivalent to the default configuration\nconfigure({\n    async: true,                  // Global async dispatch\n    handleExceptions: true,       // Global error handling\n    lenientUnsubscribe: true      // No errors on unsubscribing non-existent subscribers\n});\n```\n\n## Docs\n\nFor more detailed docs, see [JSDoc Documentation](docs/publisher.md)\n\n## License\n\n[MIT License](https://opensource.org/license/MIT)\n\nCopyright © 2015–present Frank Kudermann @ [alphanull.de](https://alphanull.de)","readmeFilename":"README.md"}