{"id":16758189,"url":"https://github.com/foo123/publishsubscribe","last_synced_at":"2025-07-13T04:31:15.241Z","repository":{"id":19343874,"uuid":"22583004","full_name":"foo123/PublishSubscribe","owner":"foo123","description":"A simple and flexible publish-subscribe pattern implementation for PHP, Python, JavaScript","archived":false,"fork":false,"pushed_at":"2022-09-24T15:23:47.000Z","size":131,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-20T09:15:51.237Z","etag":null,"topics":["event-emitter","events","node-js","php","publish-subscribe","python"],"latest_commit_sha":null,"homepage":"https://foo123.github.io/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foo123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-03T20:31:27.000Z","updated_at":"2024-07-24T12:23:12.000Z","dependencies_parsed_at":"2023-01-11T20:25:53.422Z","dependency_job_id":null,"html_url":"https://github.com/foo123/PublishSubscribe","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foo123%2FPublishSubscribe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foo123%2FPublishSubscribe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foo123%2FPublishSubscribe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foo123%2FPublishSubscribe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foo123","download_url":"https://codeload.github.com/foo123/PublishSubscribe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225855966,"owners_count":17534966,"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","events","node-js","php","publish-subscribe","python"],"created_at":"2024-10-13T04:04:26.115Z","updated_at":"2024-11-22T07:06:53.629Z","avatar_url":"https://github.com/foo123.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"PublishSubscribe\n================\n\nA simple and flexible publish-subscribe pattern implementation for PHP, Python, Node/XPCOM/JS\n\n\n![PublishSubscribe](/publishsubscribe.jpg)\n\n\nSupports *nested* topics, *tagged* topics and *namespaced* topics.\n\n\n* `PublishSubscribe` is also a `XPCOM JavaScript Component` (Firefox) (e.g to be used in firefox browser addons/plugins)\n\n\n[PublishSubscribe.js](https://raw.githubusercontent.com/foo123/PublishSubscribe/master/src/js/PublishSubscribe.js),  [PublishSubscribe.min.js](https://raw.githubusercontent.com/foo123/PublishSubscribe/master/src/js/PublishSubscribe.min.js)\n\n\n**see also:**\n\n* [ModelView](https://github.com/foo123/modelview.js) a simple, fast, powerful and flexible MVVM framework for JavaScript\n* [tico](https://github.com/foo123/tico) a tiny, super-simple MVC framework for PHP\n* [LoginManager](https://github.com/foo123/LoginManager) a simple, barebones agnostic login manager for PHP, JavaScript, Python\n* [SimpleCaptcha](https://github.com/foo123/simple-captcha) a simple, image-based, mathematical captcha with increasing levels of difficulty for PHP, JavaScript, Python\n* [Dromeo](https://github.com/foo123/Dromeo) a flexible, and powerful agnostic router for PHP, JavaScript, Python\n* [PublishSubscribe](https://github.com/foo123/PublishSubscribe) a simple and flexible publish-subscribe pattern implementation for PHP, JavaScript, Python\n* [Importer](https://github.com/foo123/Importer) simple class \u0026amp; dependency manager and loader for PHP, JavaScript, Python\n* [Contemplate](https://github.com/foo123/Contemplate) a fast and versatile isomorphic template engine for PHP, JavaScript, Python\n* [HtmlWidget](https://github.com/foo123/HtmlWidget) html widgets, made as simple as possible, both client and server, both desktop and mobile, can be used as (template) plugins and/or standalone for PHP, JavaScript, Python (can be used as [plugins for Contemplate](https://github.com/foo123/Contemplate/blob/master/src/js/plugins/plugins.txt))\n* [Paginator](https://github.com/foo123/Paginator)  simple and flexible pagination controls generator for PHP, JavaScript, Python\n* [Formal](https://github.com/foo123/Formal) a simple and versatile (Form) Data validation framework based on Rules for PHP, JavaScript, Python\n* [Dialect](https://github.com/foo123/Dialect) a cross-vendor \u0026amp; cross-platform SQL Query Builder, based on [GrammarTemplate](https://github.com/foo123/GrammarTemplate), for PHP, JavaScript, Python\n* [DialectORM](https://github.com/foo123/DialectORM) an Object-Relational-Mapper (ORM) and Object-Document-Mapper (ODM), based on [Dialect](https://github.com/foo123/Dialect), for PHP, JavaScript, Python\n* [Unicache](https://github.com/foo123/Unicache) a simple and flexible agnostic caching framework, supporting various platforms, for PHP, JavaScript, Python\n* [Xpresion](https://github.com/foo123/Xpresion) a simple and flexible eXpression parser engine (with custom functions and variables support), based on [GrammarTemplate](https://github.com/foo123/GrammarTemplate), for PHP, JavaScript, Python\n* [Regex Analyzer/Composer](https://github.com/foo123/RegexAnalyzer) Regular Expression Analyzer and Composer for PHP, JavaScript, Python\n\n\n**Topic/Event structure:**\n\n```text\n[Topic1[/SubTopic11/SubTopic111 ...]][#Tag1[#Tag2 ...]][@NAMESPACE1[@NAMESPACE2 ...]]\n```\n\n* A topic can be **nested** with one or more levels, all matching levels will be notified (in order of specific to general)\n* A topic can (also) be **tagged** with one or more tags, only matching levels whose registered tags are matched will be notified\n* A topic can (also) be **namespaced** with one or more namespaces, all matching levels will be notified if no namespace given when event triggered, else only the levels whose namespace(s) are matched (this is similar to tags above)\n* All/Any of the above can be used simultaneously, at least one topic OR tag OR namespace should be given for an event to be triggered\n\nNamespaces work similarly to (for example) jQuery namespaces (so handlers can be un-binded based on namespaces etc..).\n\nThe difference between tags and namespaces is that when just a topic is triggered (without tags and namespaces), \nhandlers which match the topic **will** be called regardless if they have namespaces or not, \nwhile handlers that match the topic but also have tags **will not** be called.\n\nAll topic separators (i.e \"/\", \"#\", \"@\") are configurable per instance.\n\nDuring the publishing process, an event can be stopped and/or cancell the bubble propagation.\n\n\n\n**Methods (javascript)**\n\n```javascript\nvar pb = new PublishSubscribe( );\n\n// set topic/tag/namespace separators for this pb instance\n// defaults are:\n// Topic separator = \"/\"\n// Tag separator = \"#\"\n// Namespace separator = \"@\"\npb.setSeparators([\"/\", \"#\", \"@\"]);\n\n// add/subscribe a handler for a topic with (optional) tags and (optional) namespaces\npb.on( topic_with_tags_namespaces, handlerFunc );\n\n// add/subscribe a handler only once for a topic with (optional) tags and (optional) namespaces\n// handler automatically is unsubscribed after it is called once\npb.one( topic_with_tags_namespaces, handlerFunc );\n\n// add/subscribe a handler on top (first) for a topic with (optional) tags and (optional) namespaces\npb.on1( topic_with_tags_namespaces, handlerFunc );\n\n// add/subscribe a handler only once on top (first) for a topic with (optional) tags and (optional) namespaces\n// handler automatically is unsubscribed after it is called once\npb.one1( topic_with_tags_namespaces, handlerFunc );\n\n// remove/unsubscribe a specific handler or all handlers matching topic with (optional) tags and (optional) namespaces\npb.off( topic_with_tags_namespaces [, handlerFunc=null ] );\n\n// trigger/publish a topic with (optional) tags and (optional) namespaces and pass any data as well\npb.trigger( topic_with_tags_namespaces, data );\n\n// pipeline allows to call subscribers (of given topic/message) asynchronously via a pipeline\n// each subscriber calls next subscriber via the (passed) event's .next() method\n// pipeline can be aborted via the (passed) event's .abort() method\n// optional finish_callback will be called when the pipeline finishes the chain or event is aborted\npb.pipeline( topic_with_tags_namespaces, data [, abort_callback [, finish_callback]] );\n\n// dispose PublishSubscribe instance\npb.disposePubSub( );\n\n```\n\n\n**example (javascript)**\n\n```javascript\n\nvar PublishSubscribe = require('../src/js/PublishSubscribe.js');\n\nconsole.log('PublishSubscribe.VERSION = ' + PublishSubscribe.VERSION);\n\nfunction _log(evt)\n{\n    console.log({topic: evt.topic, originalTopic: evt.originalTopic, tags: evt.tags, namespaces: evt.namespaces, timestamp: evt.timestamp});\n    console.log(evt.data);\n}\n\nvar handler1 = function(evt){\n    console.log('Handler1');\n    _log(evt);\n    // event abort\n    //evt.abort( );\n    // stop bubble propagation\n    //evt.propagate( false );\n    // stop propagation on same event\n    //evt.stop( );\n    //return false;\n};\nvar handler2 = function(evt){\n    console.log('Handler2');\n    _log(evt);\n};\nvar handler3 = function(evt){\n    console.log('Handler3');\n    _log(evt);\n};\nvar handler4 = function(evt){\n    console.log('Handler4');\n    _log(evt);\n};\n\nvar pb = new PublishSubscribe( )\n\n    .on('Topic1/SubTopic11#Tag1#Tag2', handler1)\n    .on1('Topic1/SubTopic11#Tag1#Tag2@NS1', handler2)\n    .on('Topic1/SubTopic11#Tag1#Tag2@NS1@NS2', handler3)\n    .off('@NS1@NS2')\n    .trigger('Topic1/SubTopic11#Tag2#Tag1', {key1: 'value1'})\n    .trigger('Topic1/SubTopic11#Tag2#Tag1@NS1', {key1: 'value1'})\n;\n\n```\n\n\n**output**\n```text\n\nPublishSubscribe.VERSION = 1.0.0\nHandler2\n{ topic: [ 'Topic1', 'SubTopic11' ],\n  originalTopic: [ 'Topic1', 'SubTopic11' ],\n  tags: [ 'Tag1', 'Tag2' ],\n  namespaces: [],\n  timestamp: 1413370469838 }\n{ key1: 'value1' }\nHandler1\n{ topic: [ 'Topic1', 'SubTopic11' ],\n  originalTopic: [ 'Topic1', 'SubTopic11' ],\n  tags: [ 'Tag1', 'Tag2' ],\n  namespaces: [],\n  timestamp: 1413370469838 }\n{ key1: 'value1' }\nHandler2\n{ topic: [ 'Topic1', 'SubTopic11' ],\n  originalTopic: [ 'Topic1', 'SubTopic11' ],\n  tags: [ 'Tag1', 'Tag2' ],\n  namespaces: [ 'NS1' ],\n  timestamp: 1413370469840 }\n{ key1: 'value1' }\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoo123%2Fpublishsubscribe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoo123%2Fpublishsubscribe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoo123%2Fpublishsubscribe/lists"}