{"id":23413654,"url":"https://github.com/rmdm/message-network","last_synced_at":"2025-04-09T05:15:40.231Z","repository":{"id":57295224,"uuid":"72669748","full_name":"rmdm/message-network","owner":"rmdm","description":"Highly scalable, modular, flexible, lightweight and performant solution for evented interactions.","archived":false,"fork":false,"pushed_at":"2016-12-09T20:41:10.000Z","size":95,"stargazers_count":0,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T02:34:18.060Z","etag":null,"topics":["fbp","message","network"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/rmdm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-02T18:33:42.000Z","updated_at":"2016-12-13T10:36:15.000Z","dependencies_parsed_at":"2022-08-31T03:01:46.334Z","dependency_job_id":null,"html_url":"https://github.com/rmdm/message-network","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/rmdm%2Fmessage-network","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmdm%2Fmessage-network/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmdm%2Fmessage-network/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmdm%2Fmessage-network/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmdm","download_url":"https://codeload.github.com/rmdm/message-network/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980844,"owners_count":21027809,"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":["fbp","message","network"],"created_at":"2024-12-22T19:53:56.240Z","updated_at":"2025-04-09T05:15:40.180Z","avatar_url":"https://github.com/rmdm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"message-network [![Build Status](https://travis-ci.org/rmdm/message-network.svg?branch=master)](https://travis-ci.org/rmdm/message-network) [![Coverage Status](https://coveralls.io/repos/github/rmdm/message-network/badge.svg?branch=master)](https://coveralls.io/github/rmdm/message-network?branch=master)\n===\n\nHighly scalable, modular, flexible, lightweight and performant solution for\nevented interactions.\n\nDescription\n===\n\n**message-network** allows you to build a network of nodes that can interact by\nsending messages to each other. **message-network** provides three models of\ninteraction:\n\n* notification,\n* request-response,\n* chat,\n\nwhere _notification_ is fire-and-forget interaction, no response is expected or\nwaited for, _request-response_, as its name implies, allows one node to ask\nanother one for response and _chat_ is much like _request-response_ with\nmultiple roundtrips.\n\nFor an interaction to occur both sides of the interaction have to declare theirs\nparticipation. By default no nodes is listening on messages (though some nodes\nmay emit messages by default). Hence no interaction occurs by default. A message\ncan be sent to one (unicast message), many (multicast message) or all (broadcast\nmessage) nodes of a network.\n\nMessage networks can be combined by using _gates_. A gate is a special kind of\na network node. This nodes, when receive messages, pass them to gate nodes of\nanother networks which in turn send the messages into destination network.\nNetworks by itself does not have names but by using (always) named gates they\ncan refer to other networks (including itself) by that names. It is possible to\ntransparently connect networks residing on different devices which makes\n**message-network** a good basement for distributed architectures also.\n\nInstallation\n===\n\n```\nnpm install message-network\n```\n\nAPI\n===\n\n* [Net ()](#net)\n  * [connect (name, node [, options])](#connect-name-node--options---net)\n  * [disconnect (name)](#disconnect-name---net)\n  * [reconnect (name, node [, options])](#reconnect-name-node--options---net)\n  * [listen (params)](#listen-params---net)\n  * [send (params)](#send-params---net)\n  * [unlisten (params)](#unlisten-params---net)\n  * [node (name)](#node-name---node)\n  * [names (node)](#names-node---string)\n* [Node ([properties])](#node-properties)\n  * [listen (params)](#listen-params---node)\n  * [send (params)](#send-params---node)\n  * [unlisten (params)](#unlisten-params---node)\n* [Gate ([options])](#gate-options)\n  * [listen (params)](#listen-params---gate)\n  * [_transfer (data)](#_transfer-data--throws)\n  * [transfer (date)](#transfer-data)\n  * [receive (data)](#receive-data)\n* [MemoryGate ([options])](#memorygate-options)\n  * [link (memorygate)](#link-memorygate---memorygate)\n  * [unlink ()](#unlink----memorygate)\n* [BaseError (message [, data])](#baseerror-message-data)\n  * [data](#data)\n* [TimeoutError (message [, data])](#timeouterror-message-data)\n  * [data.timeout](#datatimeout)\n* [DisconnectedError (message [, data])](#disconnectederror-message-data)\n  * [data.remote](#dataremote)\n* [Handler function](#handler-function)\n  * [Context](#context)\n\n### ```Net()```\n\n#### ```.connect (name, node [, options]) -\u003e Net```\n\nConnects a **node** to the network under specified **name**. A network cannot\nhave more than one connected **node** under the same **name**. A **node** can be\nconnected to multiple message networks. A **node** can be connected to the\nsame network under different names.\n\nAn instance of one of the following classes can be passed in place of **node**:\n\n* **Node**\n* **Net**\n* **EventEmitter**\n* **Object**\n\nInstances of **Node** is used as is. Passing an instance of **Net** is\nan implicit way to create a **MemoryGate** node under specified **name** in the\ncurrent network that is linked to another **MemoryGate** node in the passed\nnetwork under name defined by **options.remoteGateName** option, which is\nrequired in this case. If an **EventEmitter** is passed, an implicit Node is\ncreated which listens on events specified by **options.events** option and\nresends messages of the same topic name into the network. Passing an **Object**\ninstance is a shortcut of connecting a **Node** instance initialized with that\nobject.\n\n#### ```.disconnect (name) -\u003e Net```\n\nDisconnects a node under specified **name** from the network.\n\n#### ```.reconnect (name, node [, options]) -\u003e Net```\n\nShorthand for calling [```.disconnect```](#disconnect-name---net) and\n[```.connect```](#connect-name-node--options---net) sequentially.\n\n#### ```.listen (params) -\u003e Net```\n\nRegisters new handlers on messages sent from nodes specified by **params**.\n\n**params** are:\n\n* **as** - name of the node listening.\n* **to** - names of nodes to listen to. Setting to **'*'** listens to all\n  nodes.\n  * **to.node** - names of nodes to listen to. Setting to **'*'** listens to all\n  nodes.\n  * **to.gate** - names of gates to listen to, **to.node** is required if\n  **to.gate** is set. Setting to **'*'** listens to all gates.\n* **topic** - names of topics of messages to listen on. Setting to **'*'**\n  listens on all topics.\n* **success** - a [handler](#handler-function) to execute on a message.\n* **error** - optional default error [handler](#handler-function) to execute on\nreply error.\n\n_Not used directly normally, but [through nodes](#listen-params---node)._\n\n#### ```.send (params) -\u003e Net```\n\nSend a message to nodes specified by **params**.\n\n**params** are:\n\n* **as** - name of the node sending.\n* **to** - names of nodes to send to. Setting to **'*'** sends to all\n  nodes.\n  * **to.node** - names of nodes to send to. Setting to **'*'** sends to all\n  nodes.\n  * **to.gate** - names of gate to send to, **to.node** is required if\n  **to.gate** is set. Setting to **'*'** sends to all gates.\n* **topic** - a name of a topic to send the message of.\n* \u003ca name=\"payload\"\u003e\u003c/a\u003e**data** - optional message payload.\n* **success** - optional success [handler](#handler-function). Called when receiving node\n  handler calls its [context's](#context) **reply** method.\n* **error** - optional error [handler](#handler-function). Called when receiving node handler\n  calls its [context's](#context) **refuse** method. Its first argument is always\n  an instance of **BaseError** class.\n* **options**\n  * **options.timeout** - optional timeout in which response is expected. If\n  timeout is expired, **error** handler is called with a **TimeoutError**.\n\n_Not used directly normally, but [through nodes](#send-params---node)._\n\n#### ```.unlisten (params) -\u003e Net```\n\nRemoves handlers on messages sent from nodes specified by **params**.\n\n**params** are:\n\n* **as** - name of the node listening.\n* **to** - names of nodes to stop listen to. Setting to **'*'** stops\n  listening to all nodes.\n  * **to.node** - names of nodes to stop listen to. Setting to **'*'** stops\n  listening to all nodes.\n  * **to.gate** - names of gates to stop listen to, note that **to.node** is\n  optional here, unlike in [```.listen```](#listen-params---net). Setting to\n  **'*'** stops listening to all gates.\n* **topic** - names of topics of messages to stop listen on. Setting to **'*'**\n  stops listening on all topics.\n* **success** - [handlers](#handler-function) to stop execute on message.\n\n_Not used directly normally, but [through nodes](#unlisten-params---node)._\n\n#### ```.node (name) -\u003e Node```\n\nReturns a node under specified **name**.\n\n#### ```.names (node) -\u003e String[]```\n\nReturns a **node** names under which it is registered in the network.\n\n### ```Node (properties)```\n\nWhen **properties** object is passed its properties are set on newly created\n**Node** instance.\n\n#### ```.listen (params) -\u003e Node```\n\nPasses **params** to a network's [```.listen```](#listen-params---net) method\nwith **params.as** param set to **name** under which node is registered in the\nnetwork.\n\n#### ```.send (params) -\u003e Node```\n\nPasses **params** to a network's [```.send```](#send-params---net) method with\n**params.as** param set to **name** under which node is registered in the\nnetwork.\n\n#### ```.unlisten (params) -\u003e Node```\n\nPasses **params** to a network's [```.unlisten```](#unlisten-params---net)\nmethod with **params.as** param set to **name** under which node is registered\nin the network.\n\n### ```Gate (options)```\n\nExtends **Node** class. Includes specific implementation for inter-network\nevent passing. Unlike **Node** constructor, accepts **options** object, not\n**properties** one. Used as base class for actual **Gate** classes. Subclasses\nmust implement [```._transfer```](#_transfer-data--throws) method.\n\n**options** are:\n\n* **MAX_HELD_CB_COUNT** - Number of callbacks to hold, wating for possible call\ntriggered by other network. Defaults to 1000.\n\n#### ```.listen (params) -\u003e Gate```\n\nOverrides **Node** [```.listen```](#listen-params---node) method. Ignores\npassed **params.success** param.\n\n#### ```._transfer (data) * throws```\n\nAlways throws. Method to override for subclasses. Its single responsibility is\nto pass **data** to other gate which in turn must call its\n[```.receive```](#receive-data) method on receive.\n\n#### ````.transfer (data)````\n\nShould not be used directly. This method is used as\n[```.listen```](#listen-params---gate) method **params.success** param.\n\n#### ````.receive (data)````\n\nShould be used only within **Gate**'s subclass implementation. Receives **data**\n[transfered](#_transfer-data--throws) by other gate.\n\n### ```MemoryGate ([options])```\n\nExtends **Gate** class. Accepts all the same options as **Gate** class does.\nIncludes specific implementation for inter-network event passing for the\nnetworks in the same memory.\n\n#### ```.link (memorygate) -\u003e MemoryGate```\n\nSets link to other **MemoryGate** node connected to other network to pass inter-\nnetwork messages to.\n\n#### ```.unlink () -\u003e MemoryGate```\n\nUnsets linked **MemoryGate** node.\n\n### ```BaseError (message, data)```\n\nBase error class.\n\n#### ```.data```\n\nProperty set on an error instance passed on constructor\n\n### ```TimeoutError (message, data)```\n\nThrown when a request is not respond within timeout.\n\n#### ```data.timeout```\n\nValue of expired timeout.\n\n### ```DisconnectedError (message, data)```\n\nThrown when either sender or receiver is disconnected from the network.\n\n#### ```data.remote```\n\nFlag showing whether receiving or sending node is disconnected.\n\n### ```Handler function```\n\nA function of the following signature: ```function (data, context)```.\n\nFunction accepts message [payload](#payload) as its first param and message\n[context](#context) as its second param.\n\n#### ```Context```\n\nAn object with the following properties:\n\n* **sender** - name of the sender.\n  * **sender.node** - name of the sender node.\n  * **sender.gate** - name of the sender gate.\n* **topic** - name of the message topic.\n* **reply** - function accepting as its first argument **data** to send back to\n  calling node success handler, and **options** as its second argument.\n* **refuse** - function accepting as its first argument **error** to send back\nto calling node error handler, and **options** as its second argument.\n\n**options** of both context functions are similar to those of the **Node's**\n[send](#send-params---node) method and are the following:\n\n* **success** - optional success [handler](#handler-function). Called when receiving node\n  handler calls its [context's](#context) **reply** method.\n* **error** - optional error [handler](#handler-function). Called when receiving node handler\n  calls its [context's](#context) **refuse** method. Its first argument is always\n  an instance of **BaseError** class.\n* **options**\n  * **options.timeout** - optional timeout in which response is expected. If\n  timeout is expired, **error** handler is called with a **TimeoutError**.\n\nExamples\n===\n\n### Ping-pong\n\n```javascript\nimport {Net, Node} from 'message-network'\n\nfunction Player (name, skill) {\n\n  return Node({\n\n    name: name,\n\n    skill: skill,\n\n    takeTurn: function (data, context) {\n      const fault = Math.random() \u003e this.skill\n      if (fault) {\n        console.log(this.name, 'out!')\n        context.refuse()\n      } else {\n        console.log(this.name, 'in!')\n        context.reply()\n      }\n    },\n\n    callReferee: function (data, context) {\n      const loser = context.sender.node\n      this.send({\n        to: 'referee',\n        topic: 'out',\n        data: loser,\n      })\n    },\n\n  })\n\n}\n\nconst match = Net()\n\nconst ping = Player('ping', 0.8)\nconst pong = Player('pong', 0.75)\nconst referee = Node()\n\nmatch\n  .connect('ping', ping)\n  .connect('pong', pong)\n  .connect('referee', referee)\n\nping.listen({\n  to: 'pong',\n  topic: 'turn',\n  success: function (data, context) {\n    this.takeTurn(data, context)\n  },\n  error: function (data, context) {\n    this.callReferee(data, context)\n  },\n})\n\npong.send({\n  to: 'ping',\n  topic: 'turn',\n  success: function (data, context) {\n    this.takeTurn(data, context)\n  },\n  error: function (data, context) {\n    this.callReferee(data, context)\n  },\n})\n\nreferee.listen({\n  to: ['ping', 'pong'],\n  topic: 'out',\n  success: function (loser, context) {\n    const winner = context.sender.node\n    console.log('referee!', loser, 'has lost!')\n    console.log('referee!', winner, 'has won!')\n  }\n})\n\n// ping in!\n// pong in!\n// ping out!\n// referee! ping has lost!\n// referee! pong has won!\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmdm%2Fmessage-network","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmdm%2Fmessage-network","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmdm%2Fmessage-network/lists"}