{"id":18601827,"url":"https://github.com/yyued/flowhub","last_synced_at":"2025-10-11T06:39:17.687Z","repository":{"id":42736387,"uuid":"102583602","full_name":"yyued/flowhub","owner":"yyued","description":"Through a simple way to deal with the event flow.","archived":false,"fork":false,"pushed_at":"2023-01-06T12:32:25.000Z","size":678,"stargazers_count":111,"open_issues_count":7,"forks_count":17,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-09-23T22:40:17.060Z","etag":null,"topics":["javascript"],"latest_commit_sha":null,"homepage":"https://hub.js.org/","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/yyued.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":"2017-09-06T08:29:54.000Z","updated_at":"2025-05-30T03:43:18.000Z","dependencies_parsed_at":"2023-02-06T02:16:19.500Z","dependency_job_id":null,"html_url":"https://github.com/yyued/flowhub","commit_stats":null,"previous_names":["yyued/hub.js"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yyued/flowhub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yyued%2Fflowhub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yyued%2Fflowhub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yyued%2Fflowhub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yyued%2Fflowhub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yyued","download_url":"https://codeload.github.com/yyued/flowhub/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yyued%2Fflowhub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006451,"owners_count":26084107,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["javascript"],"created_at":"2024-11-07T02:09:28.757Z","updated_at":"2025-10-11T06:39:17.669Z","avatar_url":"https://github.com/yyued.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e Flow Hub \u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.org/package/flowhub\"\u003e\n    \u003cimg alt=\"NPM\" src=\"http://img.shields.io/npm/v/flowhub\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"\"\u003e\n    \u003cimg alt=\"Size\" src=\"https://img.shields.io/badge/size-6kb-green.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Why\n\nflowhub is more simpler and lightweight (gzip 2kb). It satisfies most of the situation event-driven situation, suitable for dealing with a variety of  event streams.\n\nFor frameworks of component systems, such as React, Vue.js, etc., communication between non parent and child components is a bothering thing, but it can be made easy by using flowhub.\n\n[简体中文](./README.zh-CN.md)\n\n## Installing\n\n```sh\nnpm i flowhub --save\n```\n\nor\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/flowhub/dist/flowhub.min.js\"\u003e\u003c/script\u003e\n```\n\n## Simple Usage\n\n```js\nimport $hub from 'flowhub';\n\n// register an event listener\n$hub.on('test', data =\u003e console.log('test', data))\n\nsetInterval(() =\u003e {\n  // send the 'test' event\n  $hub.emit('test', { code: 1 })\n}, 1000)\n```\n\n## More\n\n### Remove listener\n\n```js\nconst listener = $hub.on('test', data =\u003e console.log(data))\n\n$hub.emit('test', { code: 1 })\n\nlistener.off()\n// or\n// $hub.off('test', listener)\n\n$hub.emit('test', { code: 2 })\n```\n\n### once\n\n```js\nconst listener = $hub.once('test', data =\u003e console.log(data))\n\n$hub.emit('test', { code: 1 })\n\n$hub.emit('test', { code: 2 })\n```\n\n### Multiple\n\n```js\nconst listener = $hub.on(['test', 'test-1', 'test-2'], data =\u003e console.log(data))\n\n\n$hub.emit(['test', 'test-1', 'test-2'], { code: 1 })\n\nlistener.off()\n// or\n// $hub.off([ 'test', 'test-1' ], listener)\n\n$hub.emit(['test', 'test-1', 'test-2'], { code: 2 })\n```\n\nNote that, the listener receives each time the adapted event source occurs. For example, the above example will produce three logs.\n\n\n### Proxy Store\n\n```js\n// set store value\n$hub.store.code = 1\n\n// listen store  value\n// if this value already has a \"current value,\" the listener immediately returns the \"current value,\" just as Rx.BehaviorSubject\n$hub.on('@store/code', data =\u003e console.log('store code', data)\n\nsetInterval(() =\u003e {\n  ++$hub.store.code\n  // or\n  // $hub.emit('@store/code', 1)\n}, 1000)\n```\n\n### DOM Element\n\n```js\nconst dispatcher = $hub.DOM('button')\n                        .from('click')\n                        .emit('dom-click-event')\n                        .from('mousedown')\n                        .emit('dom-mousedown-event')\n\n$hub.on('dom-click-event', event =\u003e console.log('button click', event))\n$hub.on('dom-mousedown-event', event =\u003e console.log('button mousedown', event))\nsetTimeout(dispatcher.off, 10000)\n```\n\n### Fetch\n\n```js\nconst dispatcher = $hub.Fetch('https://xxxxx')\n                        .emit('fetch-event1')\n                        .emit('fetch-event2')\n\nsetTimeout(dispatcher.reload, 2000)\n\n$hub.on('fetch-event1', result =\u003e console.log('fetch1', result))\n$hub.on('fetch-event2', result =\u003e console.log('fetch2', result))\n```\n\n### WebSocket\n\n```js\nconst dispatcher = $hub.WS('ws://xxxxx')\n                        .emit('ws-event1')\n                        .emit('ws-event2')\n\n$hub.on('ws-event1', result =\u003e console.log('ws1: ', result))\n$hub.on('ws-event2', result =\u003e console.log('ws2: ', result))\n\nsetTimeout(dispatcher.off, 3000)\n```\n\n### socket.io\n\n```html\n\u003cscript src=\"./lib/socket.io.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\nconst dispatcher = $hub.IO('http://xxxxx')\n                        .from('mock')\n                        .emit('io-event')\n\ndispatcher.socket.emit('mock', { key: 'xxxxx' })\n\n$hub.on('io-event', result =\u003e console.log('io:', result))\n\nsetTimeout(dispatcher.off, 3000)\n\u003c/script\u003e\n```\n\n### Chain Pipe\n\n```js\n$hub.chain('test')\n        .pipe(\n          d =\u003e new Promise(resolve =\u003e setTimeout(() =\u003e resolve(d + 1), 2000)),\n          d =\u003e d + 2,\n          d =\u003e d + 3\n        )\n        .pipe(d =\u003e d + 3)\n\n$hub.on('@chain/test', d =\u003e console.log(d))\n\n$hub.emit('@chain/test', 1) // 10\n```\n\n### Chaining \u0026 Converter\n\n```js\n// register converter\n$hub.converter.DOMEventFormat1 = function (event) {\n  return [e.type, e.target]\n}\n$hub.converter.DOMEventFormat2 = function (event) {\n  return [e.target, e.type]\n}\n\n// you can control the convection by free combination of chaining, so as to get the effect you want.\nconst dispatcher = $hub.DOM('button')\n                        .from('click')\n                        .convert('DOMEventFormat1')\n                        .emit('dom-click-event')\n                        .from('mousedown')\n                        .convert('DOMEventFormat1')\n                        .emit('dom-mousedown-event')\n// or\n// $hub.DOM('button').from('click').convert('DOMEventFormat1').emit('dom-click-event1').emit('dom-click-event2')\n// $hub.DOM('button').from('click').convert('DOMEventFormat1').convert('DOMEventFormat2').emit('dom-click-event1')\n\n// other\n// $hub.Fetch('https://xxx').emit('e1').convert('converter').emit('e2')\n// $hub.WS('ws://xxx').emit('e1').convert('converter').emit('e2')\n// $hub.IO('https://xxx').from('x1').convert('converter').emit('e1').from('x2').emit('e1')\n\n$hub.on('dom-click-event', event =\u003e console.log('button click', event))\n\n$hub.on('dom-mousedown-event', event =\u003e console.log('button mousedown', event))\n\nsetTimeout(dispatcher.off, 10000)\n```\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyyued%2Fflowhub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyyued%2Fflowhub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyyued%2Fflowhub/lists"}