{"_id":"@zuze/pubsub","_rev":"27-d73fc747aedc55fa5043646774ac5a78","name":"@zuze/pubsub","dist-tags":{"latest":"3.1.0"},"versions":{"1.0.0":{"name":"@zuze/pubsub","version":"1.0.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional"],"main":"build/index.js","module":"index.js","browser":"build/bundle.min.js","types":"index.d.ts","scripts":{"prepublishOnly":"yarn test && yarn test:typescript && yarn build","build":"rimraf build && babel index.js -d build && rollup -c ","lint":"eslint index.js","test:ci":"yarn test:typescript && jest --coverage --coverageReporters=text-lcov | coveralls","test":"jest  --testPathPattern=test.js","test:typescript":"jest --config jest.tsconfig.js --testPathPattern=test.ts"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/preset-env":"^7.10.2","@types/jest":"^25.2.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-terser":"^6.1.0","rollup-plugin-sourcemaps":"^0.6.2","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"3f419b2f2ab9097c75183a8833e894c6acfd1843","bugs":{"url":"https://github.com/zuze-lab/pubsub/issues"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@1.0.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-MQm+Gnvdq1haAFwThQjmtJjOLLGbhNBMQh7Z+5wgPX6MsmSr+q+YD0Om9b9Afx9s6xu1wwmwLxsk2EdeQYqPVw==","shasum":"acb4bc9537312c1fd437b9ea500dae11cf4294f7","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-1.0.0.tgz","fileCount":7,"unpackedSize":12876,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuKBfCRA9TVsSAnZWagAAENQP/3QK3VuFR+1uLnbjpQM+\nKxHzhrQ56hMIWC8cAHU0UTbPL4DlICRmQ+Av9xFb2Z9sm6Jxwy7a06LJr0V8\nXjpXIb4h0dpLpIIcI/E+5xhsk2m5nLnXhVLAUTbcPxsZ2rI8dhFvatD/PbT0\nAbwnPmhTRNTeynw5eCZvSdRqslIrt4t5y1lHV+2/EraVTf5npSJEN9iero5f\nnIwLJxWcuY7pVBF70e89Uwkzoxjvt627kepFSK44rBxEC57hQTMqkgdZZY7H\nSoFFQw70NFVg3HCuYBqJSO2iXrpFBHffvdC4c6zBTUzp68np3Zuaf48yDG6a\ngiaSDlI9vuPpYuHGK3Rezutgmyd11XKOAFbqoxKHR+sVXKmqGd9V6nP9ERVv\nH9/vZKfBvQJjXRGbFttAatGOKAQoyOmeaOu1OC5I2EjnULWak3uym+xSH+fx\nu/v6LGydLIgyNBO7c92evMP05RHbvVGmJZcCYbayou+1dFbiLon3gCI05sSM\nZYc+8W9kEyNIqGRWTyT2Yrd9mo7GQpj2NP++uADwvCMazD2qubMN8R0CX98C\nzKXxDEgdqb8KUgjYZwXVBwhoy/2CeG6NkNEbTGGUkg059ljL2/cnYdK+N8xP\n67y/4BMEZ5t1FwJIgQCNNtRbqDPW2HvB+eTfeG7U+ogiJMFnhsNo7DOIqhNl\nyGVO\r\n=VyBu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAC0Vf2e0FGIfHp90FJT6vkhc9UkDHLNuJqkItVgC1FZAiEA9KbjurQm7QJXnjyOBFsp35K8kGEBd+BTCOKBxrsS9uA="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_1.0.0_1605935199015_0.42956218680992064"},"_hasShrinkwrap":false},"2.0.0":{"name":"@zuze/pubsub","version":"2.0.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"build/index.js","module":"index.js","browser":"build/bundle.min.js","types":"index.d.ts","scripts":{"prepublishOnly":"yarn lint && yarn test && yarn test:typescript && yarn build","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","rollup":"rimraf build && rollup -c","test:ci":"yarn test:typescript && jest --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.js","test:typescript":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"d69265cb244d37538e5a0d2a13870174df05b801","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.0.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ZmR9pGTk/+qHrgfbxxPURMrCiYKIUbS6v6estAkVvuxBzxp5vOinY8VG6o7oFeR6S7YuzaWK87ISRi2UeDezcw==","shasum":"14e8cc45e7e45bf15884adf7e42b019d748c1aef","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.0.0.tgz","fileCount":57,"unpackedSize":55694,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuy46CRA9TVsSAnZWagAAhogP/j6MCXpaBzriFFCVo6/3\n2ZlypTFXCabTyZZ+TPxvZHTtjNVmJFhKQ+VWYOb+niAV7qynrLWdcjaKIs/k\nKDXGh+55vp7QfpYCqAnjjRG7umXxirBkEUM2QcwpGJrAnmKUQC5k3zpp79gj\ndWzZIDSTpdp7xUGGw5pjxcoRrD2bfjOAj4bccrqiQarzjLQshTfptT46ErbV\nM+dQ8DWNuu7gsMph8eMJ/N6DN2BiuCpTzAy+2tpgUJkkurViqJLUwk0EyjmK\nbL1qbhUbbRn/P6rheW8UGArFH8m7fHmkcWal8UWss8lo/q6UDA3S5h1OcOos\nmW00ZEsl+eQP7u9OQlVKM8egQCQ9Rz+A9OOEHmc2W9eXmm5eUgLTCwJgwZtR\n++u2b9UXbsfK9AIgAmPYProWW4OM3a020QR8wHxyfMNtfKZabj3hSU4HAg1G\nL+myvupRxKz9vZimYpgd8jCwxzGArpjMqJN4S+yW467LWfAHNVxzbUxwkh9w\nEyDg4AgzVTl44P42FHWRfuqmPpufNsSHkK9+bn2rdHHb1yvW0VtU6ZOVlyAw\nqz6jD3GHXfA3CQTldEoRZAA2m0c+Y3EHq5oma/jxtucEhudpsRv7GgfzlPBR\n8/hYGL+M5+1dmIHTCRHLCgbrflsx/AcR7iwORSLQ5dsbPJy9ZpaTxt8Afd9r\ng5pZ\r\n=xbnO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDb/vDX9WbcakrL0ULpW8nP9OjByGzURrSVnKsnV8YKbQIgSghRLifHB1Rhn5VqvBAgRRfs3UbhA42OlAiUbC8/FKE="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.0.0_1606102586035_0.08264972087521993"},"_hasShrinkwrap":false},"2.0.1":{"name":"@zuze/pubsub","version":"2.0.1","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"build/index.js","module":"index.js","browser":"build/bundle.min.js","types":"index.d.ts","scripts":{"prepublishOnly":"yarn lint && yarn test && yarn test:typescript && yarn build","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","rollup":"rimraf build && rollup -c","test:ci":"yarn test:typescript && jest --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.js","test:typescript":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"392e79261216f4279bae89e9856d648a78d90f49","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.0.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ThENrfwxC6a+PSDHi07QG/FFf4w82ea9Dze6ngaz7rE/Z2K9r1Y4bhYSQTBq0+hpRwTGuUbNc/oE24Nrrq8iDA==","shasum":"612a8e7c2a37595a66da6db16d16561490dfdadf","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.0.1.tgz","fileCount":57,"unpackedSize":51171,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfu87eCRA9TVsSAnZWagAA4MAP/0uP2DP0L8v6B1ag60IP\nHLahzVEcHuF7GjhRRfrkk93Ne+xTvogc0Wua9vaGrhpVGci/KZGR7omltCdw\nHGqk7wiWWYn6QHr9vyTxAR6OeW1o8XlG8V4C9AWnyVnuXOz/vRhiWAX6UDHn\nbuNOwp3o66aTfJfxdiUPDqOTrzE+jGVu1RJOWXuJyK4WCJsWX9l53A1u8AjD\n4OgjODtUWWRUDuMnT1bfGXWon26gOEHHMOLLAjkDu98u9N5Wy9nD3mjcGYl7\nyhNTydfrf7dyCbiGdTYwaKYCSgAKrEaWcQ3jH7n5l/hSIq4Tc7p05LWe6qP6\nn+1URmj6/SZWgwNwQy6f/l+USiLSAjt8OYGFEkJ1/Oa8+cbPLFutqmLE2HQU\nrlZygf6ZQB5OXxQnN7jsgiJczT6Bz/TKItdHJRrC40FA2QE6Aq6AqSGRcO2q\nkyFPJiATLu5tQWwdsqtP+tqJzcGMaawysXiwMCXnQTfqvVJiVA2QmRdb3Ei5\nSsi1jV12nJCtlwHHAy2upxuIfYxhiYBZo/0B9RU/zshOjy+kfG9O8sHZP7wv\nNwtDc9AQ65llVZqPK4kcASrwf75cvGIIKxm656eWFPYdZ91nfsQ054eILPuc\nP1xcVoXR8v3HDt9frETxK5yRhLvdu5Jx209g++wdJ2A2dPk1cifnBTNQccVS\nC6os\r\n=04lX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHhqhJJvf3CdeLGUbRp/cYBvNpY25Eag9GfP+W4PebvnAiEA7yRIWg/yZhhmwCh1NR+gv2jZ+2QxEp9fqNPkcXdqYw8="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.0.1_1606143710083_0.233788744735693"},"_hasShrinkwrap":false},"2.0.2":{"name":"@zuze/pubsub","version":"2.0.2","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"build","module":"index.js","browser":"browser.js","types":"index.d.ts","scripts":{"prepublishOnly":"yarn lint && yarn test && yarn test:typescript && yarn build","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","rollup":"rimraf build && rollup -c","test:ci":"yarn test:typescript && jest --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.js","test:typescript":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"9945238c7a81a1c5bf7bb9988cecb4651a3dad26","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.0.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-TPbV+DLBEZAPGnH1YcdHAToHLtV2C8Sq6gimQLRXXconCFBZXQhfwO72dQPlr3yzbX092SbI5+7dKFemfvl7UA==","shasum":"15f5acab8c8c1d6856b4a75f29f22e92128c3897","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.0.2.tgz","fileCount":57,"unpackedSize":51144,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvFpFCRA9TVsSAnZWagAA2tcP/2z4+a6mBiWulymfUwvx\ncRALw3vD6Zsn1w/qBpf4O+BAuWcmZlknQuq3KBz9/DrvSzx0SWdFUZNj3Gl4\n/YVlc6RtQha9OKp+IX+uI82SHlMf0ql/E6VrQ/6ldry6N7sT7n3p13NUm3u5\n21d8G94QjmbrvZ1epeKx1cpRIh5z/NT3joXq9mr28B6E+sH4e1BxYHWceIO1\n5wU+Ew9iU+/SMhJI1BVKAIweFbNwDVGl5/oIWKKNctfMYg9qMFmcWCEVlw7e\nN3x81S27LEx0yqVgiznCNY6qpRd9oh3JaXciYmyaTQIhDocXQdrhtRvvEi9Z\nRLDP9skPryyDNredjF0D5ISoFO6NMK7oIOXSBTHyTbECk1fiO0SIyFUN7BZZ\nVpPHfJnJXPEU4KN+grwkF3IR7/gBxpD5maTMoHIPcJE77NpWv3hk8BCJPBL5\nYsQkN69n7sp/d0h72c0iIbrwa1O1P7PMfoEDErefNtVGmX1xGjY2AubMGckM\nRwo5pZquUPezsCw5JTmCeOSPHwZw+McdyulN8pTXgMzqaGzOrukLl027r7L4\n2I5TyslUUe/Av0vvSF2GhHiiDeAe3OffXiS88oXyBrGF3+7C1OjRST3S8qtb\nPOQ2nZZAIrcWKrU+UjS/EpSkC9v22R5E8J4KvRIUFdkBafNh0gx3Oq+sZ6ih\nMS9u\r\n=aXO6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmeXu/LuGddfa7ZNdZFZ2DBs1aNK3dGI/E4BDrI2wEWgIhAMEH8HuG6gtkKPghkLMUeacLPza1k8Lh2fhmKAZEANcT"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.0.2_1606179396825_0.9757108281202125"},"_hasShrinkwrap":false},"2.0.3":{"name":"@zuze/pubsub","version":"2.0.3","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"build","module":"src","browser":"browser.js","types":"index.d.ts","scripts":{"prepublishOnly":"yarn lint && yarn test && yarn test:typescript && yarn build","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","rollup":"rimraf build && rollup -c","test:ci":"yarn test:typescript && jest --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.js","test:typescript":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"4da1607f2daa2c669a344f481f5052d4baec1197","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.0.3","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JurAUkbJwEyjfXwAN/MS188hsDL5UzM2NTLZXU5qbsi8NDJG05ph2LWCSAwlOe/DeT+/B3NEy7CXSjCrLpYtWQ==","shasum":"65f4e6fd4103293b4466ec73e6fb042c43b2129b","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.0.3.tgz","fileCount":57,"unpackedSize":51139,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvFsICRA9TVsSAnZWagAA+S4QAJ5a/vtgJoGNZkS73sDS\nQbIGj6he1sECcmGLI0xPct4d4zHB2tZmVTp9534XwF8q8u7AK5lTHvWb8VHv\nQtuc1oLi9a06WMYGXF/vYZ3CEWDSLcH+QBM6Rcyucmxq5LB0PpDyFEhqNF5+\ngMiRX5Tfrpkrov/ReYZXvi/DMhcpMJShjK6ZTXxq91O1Xa07EGAaEKXwDoaN\nB/DxpDRMjAg2ru97KZHG+CxWRojyHk1z2HxcYit62D9q7xVLjGLO6nFt69Gx\n8fML/w1a7+ezrklbLuyrsZK9rwpmz6idvQmma00UZsRupBbN4YVKLNV+JyEU\n1/Y0y1FSIGqm47aJNED+/GcQneUD/Jvl8I/gG8ghpFnx7PhQlCg3nGoq08HC\n5tL7SuH9FsTJx8P+9cFJ3KoL6TBzUOch6u0T9mC9WagWHnHFzpNClP0MI+zz\nJndtNVAlpMgh/fVDHKFekf5G7T9rskea2xkp1mybHmSdynfu7hxyt7wnHQxI\nWTssv9ChiRVuHE+/DXnD1IkoVq9osvfSx3hW8VWq5OXMtyG2/LnZlcM4siji\nfW4PvWMyW8KnQmBJUu9Muc4nf8XjIC6XNGQlM4329X/m74pAJqRmdJxJ/h9d\nj2ARrBFnZWXRl5jfs4XyVcz+Z7K0cga5RE+aGOzFmJQdUoDqzTSQR05ifzKX\nuebh\r\n=zIhB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICFpUHgPCVqcQhM0owNcNynUD9Luy2+6jDKeuEFHnWaxAiEA2FP9fs6Ls4OKkvXtV3yZ+b2NwbR+/SPr12ZOSKCmwGY="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.0.3_1606179591888_0.8087637716149274"},"_hasShrinkwrap":false},"2.1.0":{"name":"@zuze/pubsub","version":"2.1.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"build","module":"src","browser":"browser.js","scripts":{"prepublishOnly":"yarn lint && yarn test && yarn build","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","rollup":"rimraf build && rollup -c","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"gitHead":"5bed6ac484c0cc3cf566bb3ee2acf6d8fef43723","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-EtE3CQezMDCIAdagxM/zgt6PwMeA8PvGpN7bHbIRcCV4WNXcY/5ccI9LUjnplCXRuYyPtSzErkIUY2H0K8KuJQ==","shasum":"f3d0597ebf215ee5083872863facff71c1c42d2b","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.0.tgz","fileCount":59,"unpackedSize":56316,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvv73CRA9TVsSAnZWagAAzWMP/02zk5HV/PuC3WC0rVDw\nO72Adnk9mXVIZES3ELXUFocr+L0QQyJZZNKTub9V153YQgvpm6wx2kCw0wY0\nAw4lczjpbdMdcnrFLMdzThqcQ/FRNibaUcwpSRvCr98cWrjwEUkVdpiZzY06\nheNHmYZkXXL4YPvy/oMw8DQmo40MvWA4bjhVYLRwJuJoqWDuW48T+Vo41UK/\nj+Pqi+8yE7oOG9ZZKA3S19ZNf9amUbolPDMgtaF1ESCJ5e5MPBAE8mc1na68\nf09gm0Bq0b99x4lqWQNvdB/x3JeTS7PFRXUHnSyoZ9MxhVaY13i0OJ8QF7PC\nw6GR8z1WV+bQLKDeoEtOVSJhNT0gMU0sbwCAdQHbzensgW4qJ9Px8rRUqjFB\n319gs2gfburu03ZaPOxo2kvschsJVfO3LWCw/diAjRIviTTAeg+9ZxyI7bFX\nEEF2CbWa9YSwF3lhsBPr/WdfOd9vjWG9J1YYv2384kXrETTEp26p/kROVDTF\nmDIvrfI4eehClaGIDo2mCTcnrdkEiAtp7y2GI9+eIKDDoyjwadL98KIlp5oX\n0BeTURgNTNgtnbspDTYhKFlOfB2KKCJmruaPcMFGfgfppXDOZNg0cHgeTm46\noCIj4PQA25E8fBFSqBBP+apV34HE71smGZy/QNzC67POldLOkOezzTZxbLxw\nxIXb\r\n=xJ3O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQClDpJ12y3zpZLVg50dw3jORnifa3m3zR8SD/r8uR/GDgIhAIwlXXFSV6uarbLD7JSCZP6lpO0su2rY0Nmozclo89yR"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.0_1606352630733_0.893831536248761"},"_hasShrinkwrap":false},"2.1.1":{"name":"@zuze/pubsub","version":"2.1.1","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build/ && cd build && npm publish --ignore-scripts","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ftK1xjkJ16zqCZsNV/EDXZr3Dr8W44lu8p5QLkk+nsU7j1gQy2Ds2wFbPRKsnVZn5lr+IXN2+NgvFf/fxlAzNg==","shasum":"18b208777b58ff3013f1107b3a9becc44c98ddd7","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.1.tgz","fileCount":4,"unpackedSize":4525,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvwiACRA9TVsSAnZWagAAas4P/imvrK8q7eBATLIJl8Cw\nAkP6ffEekDcSvh8g2lQpnQiKzwF7M87li8jny3D+X2lenkgt1JaxGH42ykxK\nyjtFkYEOdCv0hl9INJ3y5SCWPLiL5OajWaJgX8TivLD7zlOCC7Zd8kcJmzJG\n5iofq1zrLT3MKgbrpztg1Bsb3nq4P67sIKpQNwp76eunVFOKe4Q3FUss/YZO\n2LGQYw9FZ+lMfBjJy8nquq/IvuUy2kiLe5lu7yEUu7sycqAU6gK41Pn07MzD\nK48671NTn7XMd5h+mrxx6KKFQ+OIzoFbsD/HXyv6lTafLgYidxNMVdsugX3/\nT39Plwkn8sx/sR5lJ3hTjTE/EGnJAi+WdXV8uTGyaC596Oas6lMMh7QbMbMR\nhqppGq+3mgSexlRrxinduzWne7HIiwAEhKX3CLkg1vBKIsqbvhHr58dqhk5h\nTzg+2UJ/I2RDIiR8x0CSAVLFilt4FvaBwV1ayJHg5AxNGwTtJnm/Vx2gftd4\nXNekKwCwI4CWcToX6Rks7p7OcYZwF1f7vP6OAG8yJ5axyu0SUe3+siP+pn8s\nmVshnLN1cbcU4gM2LC6Zsyg4g00UC+nu0eUZ9JjfzGhczGDQKvLwbxPmu4pC\niG+orRcyg9R7N5e9UhcUwrx/pxxs5twMCl34Qs49eYngx2K+c+Ezp/rWamvE\nBOCW\r\n=MsBj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGq/OcxYGfuDs85pStR4JYmIEmlVdJnQi2AuEx5dJVaSAiEA7hojnUq61bvcgsinVdb9QsiGTpxWn9A4jerWFNrCECE="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.1_1606355072432_0.24561052273974515"},"_hasShrinkwrap":false},"2.1.2":{"name":"@zuze/pubsub","version":"2.1.2","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build/ && cd build/ && npm publish --ignore-scripts","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-g0jmlrN/wk/imlzEikkmu1Ka8PqDDt1MElXOMZKOrPDSQLJNbmvKNK9Q9mNEDMVn1kPyql5PTanMs+FWgIw/Ew==","shasum":"6cecc080dd9d41aa82823aaadcfb8417e306014d","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.2.tgz","fileCount":11,"unpackedSize":25121,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvwlrCRA9TVsSAnZWagAACn0P/1bDocHd5QM/9kMfRktk\nUCYoibTezDFz0Kwj5mBZ+AL8UIWkp71eswhg8+QP2KQXu0jkyDmDQePI5KB1\nXg3DbzFU01XltfLYJ/BEb2pi9/iruHzayJca4ysKfpjoLrL2iKzAxuFcBQJI\n+bwo3DKLE49vcws5gbEfQrdXUgbMDGMtP7oVhOp+K95GhvuJaFXGNh4+vAa9\nnTf5ysn3FNNDMZddi3NPPnSFSxfwIe2TleQC5WXaF97HdUQXELK1K1EOJnPa\nYQLCD0PfrocSXTpe6oGM6XTN8mSxZRQMQg6RorBLzx1iF/eBUa1WFqDRPKMu\n/G923SY6M96uNGqwAB4QLx8pdYSrV0yjFKgZvgCyrX3MpxhmDJoA9KB23+Yi\nYr1d+6XerH+thxSY6dSbyQ4ToLehkBtNnyj0QTJzBxmNdaHn4qMvITXXFWOK\nkLb3j4mmMj1db/ez9PPpo//poIB8LDX0IEsAdtaCTTbfHGcT+ZaLTLzx0YZV\nYfAMOOknqX9ved2LAX6TJ33dZeB+SywN6bkX26/bLCHP6Qj55Fvwfoq9NIzA\nLpXLL2wLXgZayqp0ZaDAFW9+hiAV4OsP+rt0YKfWwjebRXLJiD4HCMfNeurH\nidQRHpCCNclkyRASGbzhDZejz/p9DVuxhdkmMgRcDIwjfLh8DMc4C4rMEgdZ\neXfP\r\n=toDD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDR52ucwLS+L8qN8z0Aw3ZBDDk0gie8DILbMYDk5ipJtAIhAJmlYjjtDgi2MLi7UmC1+D3b1lM3Vaqh9rwAo/vL+Opl"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.2_1606355306859_0.5181840151059787"},"_hasShrinkwrap":false},"2.1.3":{"name":"@zuze/pubsub","version":"2.1.3","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.3","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-EkRSoZcKFtODrIl/NdJyGXeyQKfvQcCtpy3iLenIYMyT0DiGR6neL5PgrOhlqNq+Dk+oD5d6Ll+MwG1NpcyNWA==","shasum":"0b37ca4858028ff7558a8368bdfe9750cc23c949","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.3.tgz","fileCount":11,"unpackedSize":25126,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvwwhCRA9TVsSAnZWagAAMrUP/RdKMOd7SUjGnBVIxmvh\nGivujoQZD8P99Ka34zx4/DgRbP3jmmIlQEV46XdTrJTwfub+dB/0N6ADe7ii\nlKt5+o6mSwCj31+2jtgNjfJOGrgI/M3iYJZ0MgtE5u5+ZDs7QEssPo1bgYKI\nI1NeMLqcs/7XViSNSOenClPVgxNHCvfGkDmU2/iCUR75AGwqnfN9SK2ML/Mv\nrSfgPFxTnatADsKgXMaPiJiLi+tW8YtbZ4V7pqSOVfBVJBmR4DmhGyQyESba\nKJpPYpzl9XJAVIipRvPxtdzi/htDiHop4knMrxPVJSILvCoFwJtW0sl1fdUm\nMT5yb2BCN/VWL1dPQVx8ohrdAO9yvPuGz266b/7xwBlktVexMnz1WT/GMV+g\nwKeOgnAQ2KnzxMrCHmZ9VtauFPN62v6OY7S4uObl2dFHHZpEM+383bln1ANf\nPisGQCYzxvRQ5hS92KyK4b4o/TB6Nn2g1c0UBycHnKJLkHSSeFK7mF+kZyV/\n2vwcXtkVSLd2vN0+Qd1bUAmNusmAHEpqGZvP2OP+Wenf1tG2yFEMIYHZYdso\neWOMZgEwaQBTLAjRzoKq5xYRMp9kaYm3ttcCf5USmWS1CN5RC7/h1sOuwjg0\nqJxHC0vwDCZJtRB9N6u5uVXEFvpXK348aa6nz83fiDd5ZhMr0N4gs1seIjMA\nAmPG\r\n=NWE9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICtGl66MCswPiecL2GAMye2y8qXodWBGLgkmqyn/kcNVAiEAo1SCZlrEW9PZPMNgMwsMuQTRypUfojl6Lm9p3QYjMyk="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.3_1606356001109_0.8624409158793209"},"_hasShrinkwrap":false},"2.1.4":{"name":"@zuze/pubsub","version":"2.1.4","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.4","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-7eOQU7Vvq0QkSW988nb6suZdMXnJF25MdT2vfoSPQ3Wdd2J/oSSIzZGNFywkHuzdYywxSb/Lv1FV/wSTHRI1Fg==","shasum":"468988956201dcec197c666f8351fb40efda6020","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.4.tgz","fileCount":13,"unpackedSize":26055,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvw18CRA9TVsSAnZWagAAzn4P/RJwsIWMvCMissyXhZGm\n0zczhYJ68r1+YgXt+SRzvQpmbNbPztHAtJifr3NI1GgHCzMop5yUtf81+Uub\nstjSyGrfRiVC6YVx87OgK9CBEvnrnwi1oReqtRkye5DFsz0YEV1oiD2O5IWD\nIsJ3uraP6v4fM7XSDVxCCVZWYrvltcpBXrGt4xVzlq6hLLth4Gp7XsjTClGB\nkijnInIN4l2M97z2G32M27luA6bYsrLHevtxrtJ1L5oxiy47N2tSf/GEy7TA\nVspeYF+FN4WLd6cU7XSYnE+V7Pt4zdvg9xCjy8gWK98X1WXHcTaDK21/SXBK\nfRM8A+CeKvQbvdcj9HBYltLc6ZBCo06uvvGDKKR35vzkvG7QnHBoNUIt7VLq\nfmLIqoN+vxShbGI7UNR+D5+ePv4LxjDarNUM9Rn9Bjcdi2U4oCSJE2r0B8P4\nx6G875Rp6XjNysnLKZN5ymcrNjtyvcMC/xJYtA4SS7JB6hVd7X1xijLWgmuy\nn+FZvSfhLvKuyUppoJ5FQ6zX1dd2dZSvMLt7SAhfZpuimzIY4v9N9fwvP2sA\nU0M5xQCDQ7kZNIjgy4g05uafTzfmLcaYWTiIZQaOoVgEZk0sYiXdAuSUI3nA\nRq14p/Mle5xaF1CJdutMKVDDb9SuN6UhsLY/X2bQSfFrhVjop2biOhbw8gQG\nNOXZ\r\n=IPcN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDy5FayvJWReU125XiX0JdvB9yw9lsmAjRcOcBO5GlS4AiEA8gW1Q+CnJiPGt+cNO4rgYz8Nut9cEetHYtzRb6LV3Gk="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.4_1606356348022_0.5018022563122824"},"_hasShrinkwrap":false},"2.1.5":{"name":"@zuze/pubsub","version":"2.1.5","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.5","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-3RFGCypGNTmCd5VgoLf+uzKOtqIXBT/KZYTBr1xe/bLT/b4d/RCiuMfBiBQjZGq5Y/J3YlPqFBp8K1fVIYOnlQ==","shasum":"06d322f6d4210add8a9aa8c79959c39771024210","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.5.tgz","fileCount":13,"unpackedSize":26071,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvxDMCRA9TVsSAnZWagAAoA0P/ApWaIincJsxmy86wvq/\nvg1ETM7UmSg65UopoxA/rWYedIyKma7r4I6+cYVFu0b9TEbK6fqkbpEQS/xx\n2N7oGOTxdxIGAfpXVV5tj3+uo+ylztlVs2OdDk1w3Er0DV7cCGtcjGi5fN5d\nG34r46SjG0LQmi8O/6u4+pRBC7L+rGyWulswW0piQVMZYM0V2aQcRQyEIWXL\nQvjnY0ZP21ytcbZjpWGjxmHOy6EQHB2VoEUJ39dXHcHPlP8gTkMHBsMGQkmw\nI9J8Tp7VjffIxKnicPjqH0CqvyLL3d9ZGxg92dx/rmfEUuR+Y5mLZyPWlquH\nkX3mrux1aZMcFd+olajRVfHWNLx5Ry9WhCYb+Fw2pbw+GYQTc2hrVrXhR+4P\nSqkxnVkirHn9HOJuasHpAAOykIJgoQ8x4iFj8qTgE3awCstqF+/wLGKSCAW7\n0bPPGH/Bfb5LNjHYayw1vytr/L6wWc0At2d7UFfsq02TuV5qvjrZMYv9VJdC\noam9nyRrLDnvyXA97+PczmPol6RY6iWEBSRZ7nEYQceHToEhBe2JG2+Ak80N\n0jna9C+dtOu/AcZIfex72quNVutgR40cLF1Ct/DvF2ZF2Y8apVcjA/m0pfe5\nsQwUgsjDoQ7xOSOrWvuFBSR44jaM0uBCnCJgLqSO/BleTsI0+1NtHmNrUJu9\nGko3\r\n=rny7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBo5N/kwR2wfa6//XWKbQwpleDVVUgppTXgqxT9gaok2AiEAklE5laQoPMLPyFNwcI865jWDNY6BMsEozqWziYFCLck="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.5_1606357196194_0.5007928007528966"},"_hasShrinkwrap":false},"2.1.6":{"name":"@zuze/pubsub","version":"2.1.6","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.6","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-5LEXkFmVllnKEmH1cOklyuAw1OFypcSiKYe00xCtvb9vpXm+zvvw6Dvw+HvzzbjM2lVbUdebcpJHLXYYLgoKvw==","shasum":"29cb6639f908dfb238380f1d3d5b118ab69d4f62","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.6.tgz","fileCount":13,"unpackedSize":26408,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwRv0CRA9TVsSAnZWagAA0iMP/078ySWU+XJQxTwRV+U6\n/JrjjHBKcxHBhcP3rSvAoSftBM8SS4fSEqRyK8hG9gC4VN9+oBmQvzEArSIk\nCGEhd63dZ3QnwIln51DINaczrb3AS0FhKYHQqGJwv0VqV8YcwiXW+K48jDU5\n1pUcqu+jKk4FQZ6P8Kxx9yDP8YEWcboEyfySbaSRXDzZYHPyYHFX5MntBCdl\nj22EKbrdl4PYHcjigIu9qWGj+AtAECMGf23Dl5lI+hLVEBAv839eCKcCaryH\ny06mtCfKzq1mKqcsaMWlv3v5yC0bYCsENJrN6kQSiZ1z72v1Sm5iv+8e02sG\nLaLcIvqHhqm/qIEoFySy+oxhD4AAB8O5NV+6QAHc8aXaNgG4H5f1dVgAsFQd\ndo4QKhlDVIFjc8xB0joVhmnIcfieHwKkcbFPmeVvhyIGyqXf2JlD3LFssluA\nkK44lbo2WpG3mV6QqeMYUwk2Ong5HVN8l80lErqeNa6agNdVKQ2ll7zMQ/2D\naFLaO6vmmdmVwTzWx1Y1MGdSyLYWcw/eyJ6thTS3arLW6W3azOlZopuxxWvi\nF2qDGNeFLNx+3wnM+jS6sCZpt/1N4Je5K3oJawYjYVorp5gKeZHjdu7XK9Lc\n0N4upG5c/ou2VzYexnGbRbonZZWpIE4Xc9zjXbLCGbimfPdmLo1Yt9Rgenea\nQ1k/\r\n=acWj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVxoiWezD4fZj/9i6gaHFEkZvXlJXTLh7pretw41u5vgIhAJVj6zFj0AieaytoqELObQ2R6TwJXp6+aoWhsIvQCEfx"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.6_1606491123814_0.546302802511389"},"_hasShrinkwrap":false},"2.1.7":{"name":"@zuze/pubsub","version":"2.1.7","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.7","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-y8htuex9vwJnDvVDUrRqdhaB8csUFqHMpNUiMkjq43rsLBMQa/dOiEDqKFa2Iq6YBwp2inov7wlMZdT/n4oxxg==","shasum":"f8e73953f21ff2815f366ab8df80166f75e121c8","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.7.tgz","fileCount":13,"unpackedSize":26856,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwSKKCRA9TVsSAnZWagAArOkP/15Jn/mjfMNIjMbFskGX\ndtBdCGOWKYHIpiOV5VeLMQ33SbsUbY+beOaIOaKySD02dMm1GxpipJjOwVcn\n3zz2MSp/CQO7DnTEkf2ZMqwsUlcC48LMTHxGB+RdVTw4SU4PurqDq7utQPE5\nPlxAgQ2FBrvBu0npyr4LiTIXnnzPFm9/lrmnen1+XdmYTF8wf8o6rUWCkEId\n+dvN/gFWY5Id1yhza980oc12KZM8/DtBXJxv9ugTZ71b5gEwi46PHVaQO4oT\nMAy7uxG2uf5yZ6xzTN+eQA0muk1+zPc59LTVMuW5HYt+76gyIJ7BsHUt68TV\nUEqXHouFWoZ8wxrJjT2fauFLlJaMJsONTak9UVVEKo6RC8uaulelTpaVU/rT\nyfLVRMbWi0tVDem1A2XQXPW2Q/usSeQjhPs9oDS+BkRV9BxiOJEoeycVg3Pg\nXweD9UDs6a9qhrlTL49uZjGf3G8fb1R7sh9K2IBRSvzZQfxAU3JWvf2K1eI0\nW14XcourvFwyW30j/TyDgJCYYdkZNlnszce0Aq76OJieLnL0eLvAvVDagvgg\nFNDuqSZukmlNNSRdV8qPY9AYLlfXQFW7B8yfFwplqyNG8XClvS7y6ai/Gvo0\ncVREyQkYFMAx0/9H3YN2kv3pEYt2kJyRGJi6pAlBrGWl9fZqLfyOyt895lxS\ngtlw\r\n=E0sQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBkeIHnctbiHTPvlxelXynNFPDLhIBM5dUCyXS9HY+c5AiAPtcFiZfuLx2d03R5nO8izUU9ou0TgEmkgDj7EJXuyXw=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.7_1606492810283_0.34176334079102166"},"_hasShrinkwrap":false},"2.1.8":{"name":"@zuze/pubsub","version":"2.1.8","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.1.8","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-SRa33jJaDJS4LX7JHNvvV+VHOrpOiUGJWG6Lxgz+Gc1x4sTa+pXgU5JbnTXJvRxnF378N823oyM60+64b+Eq3A==","shasum":"1f835d029c2ff5bb53022564c53eeb23143c4773","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.1.8.tgz","fileCount":13,"unpackedSize":27259,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwSqcCRA9TVsSAnZWagAAKWYP/A8adJG2wQvWbqMndbAr\nPNnmcgocIdTMVPg1zPZCrTRcII8ONMuyp/M3Q7IHCnXFJ5XkVQVu/k6TSEOX\nc4Hx4Wno01dBY3/eJb02T3LA6kGnBWm/I5khteSKCWnhw2Tq7KIfPX/UZwZT\nEmyS2BdcpqwxOqgWozmzIB3KpNtmVZB4c7LNqgSCtrddHQZtfveMjJWwRJja\nZGg/ibtRBVPFX5HoMTKe2RAodhJdZWlzi+zMUfusKNaE1rlSMm/+6JwKTP4b\nMi46V/AQAu0ipzjGau/OM1xDqcLRNUhlMdeOPSjW16Ga/T2HquliRLzuYAC4\n5q5MVtzMJg/Ja91IvQN8pL0BF+Cm8ndPt0a8p5G05aiJwyLSNY/ssEt7Jvz0\nmeIyu/jWaa9RGEBblRZTNe2nDV97Ndkb3nmUjz12d01E9W/QWZJBnLw4i5R5\nkzGe4618HLga1CPn3UHQh3z7GJiQPiz7St1+FkJ6mihXawGyuCD/525Ejx1f\n0C03vpCokzVwhvy0nQP18Q0a2xpNqgbnG7o1aIU+Xb8mEoPmaY9DjJb5ufVA\ndJNz1DaRiE9jw1oSSDYgbRJ0OwbHJzUk5sdkU5k7WaQCK3QTJc+G8AI+qwjt\nsP/yoKcu6AVmfLzw8P7nly0u+TG12MZENBtHz9aXSM+amo/qIkQ5M2RUcbk5\nrIWK\r\n=nCJF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCX2/H9ycZoFw67VRdyBGwqWdJue//U8AcEraQW4Ys8uQIgQLEvCJdEkkirCayOan4EJeM0yJDqfm1OYNYeaeBoh3s="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.1.8_1606494876157_0.7365782233611697"},"_hasShrinkwrap":false},"2.2.0":{"name":"@zuze/pubsub","version":"2.2.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.2.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-4v8aMHA51GEuOvxEWZdxiX8WPeCuXDwWT9DyXKnArdmfWr3eTSWYgPd3BhheEOCWwT1vN0deLUnV3pCXQtZ6Gw==","shasum":"c55f00561e04127afb791a30f5a2853eca61be35","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.2.0.tgz","fileCount":13,"unpackedSize":28489,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwbe9CRA9TVsSAnZWagAAIV0P+gMGVerScS8oCc209BBn\naMg2lfcuZTA8dFmV9qH+EKNxl+HFhpZYvbqme6Lj4HX1bPeZtm7M7VeKwIOT\nPx61/mT3hi5ps5hJRKh2JOJNGY/VZhPG/KlO80skAmqnXezsPvI9srbgsF6w\nFDPwepLfTCKoACOvHTwyfx8cXrujxCdp+6EPD4U7j/mWxyntnByRk7obGRRK\nR1lZN/AXfuOum5nscnRigGf0P3D27jRCRx0afZ+WbVbSDtTeCJC+ObOa+KRy\nzCgZ4n90oaVed9wkenScJDx1QVoYKDdsL/QqqGOb/olywtQisvFTeX8xWI0r\nL8fARqGF4QBBYVxU1/mHC6LAeOfoArN0/jS/JlGdyCFRRqR3uPKoQSLzmrvT\ngmxOxoacja0lfAxALQWNMvvMJtHVKOeS2hDeQTPMdg+hhYP9ElQVs0uVmXUE\nSJowYX+GjfKJ8DmzGcLaqYCKXjSvD2LHfTxbytnJL7dPOWsgTTXwJ3hABskX\nUrjQCfPDLv1BjiYQ5T13pBOnMWZXPrp14HWmNZkshkYxG5StK/KOtiHjQFBT\nMdlq0tYl3AvKplJDZxq21x5KvtCmtTLCB0NI+WJNwnyBX3/bwRahmUTvhGJG\nzLDSnGyMP+T1/sVvwdUCfZ42ZsXwmbAjD2daaTlFxtBa3ZzqEO9B8u9i6W22\nx7vj\r\n=8DES\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBFuXUc3vm9u+wmnEB+6lCgbfUaQpueKH9NzxwLld8dfAiABH8HSbRKQXuCjc0DqHly1izeFsDBPBscv72L4GFa62g=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.2.0_1606531004541_0.6125819856615726"},"_hasShrinkwrap":false},"2.2.1":{"name":"@zuze/pubsub","version":"2.2.1","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.2.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-mmyU8wUugg1MaLMJdl/Gy5RIrI1UstuWICrO01fHpkCpS6pvcakFH3D7svHvgLN12v4KncdyYa3CxoQRXxQGbQ==","shasum":"6db0eb499b93914af72dbb721629916bbd2ca4f0","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.2.1.tgz","fileCount":13,"unpackedSize":34030,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwbh0CRA9TVsSAnZWagAAGuQP/RUWgOhn37e3IcYsAJdo\nfGGeOCUmZphTCpUPL/6IbJCb2tFbnN1nDlZRQFO3d3hxdMfdr1ryphaTnm6m\nX1LBcPSxCpvMBoZz9Z1XCQsJyAtMKDX9/h7T3UBFiS+cmMPraALi1uoYBi1l\n8yGl3rAW6U3uFbWo7d/OwyBT0hM5xADoHR47ZXgQL1hkc59OpGLiKVKnLOGS\nwmCKzv8jIotkPB85Qxfve3wbg8251fGQ01D7RPkoIp2voT4pO8MBiHoj24aS\nKEZaVb6PlwdQ8G3/xCZAIFt5/Vu2+jx+ew4J/ygqx8zZ+vq804rkPK7ttp63\ndxzlQASLEuJ0DUwjLMZtVWtudDUleu3dJR4kYPZ1mjPy+vnrOnqdaTvT8Cys\nq7RKx6mETyGsIGBnV7Ou3jDfXjJFuF4vOR5A234rdORGKJxoKMjhha5pH0u7\nv3OXytbQEHlJM/C22srj24xBcZo5/d+4OeL0ldieDyWn9yM1J4MzWDQhZwVZ\nRGNhkjoebdX7irNOfP9ZeE0QeXDsow8uuzsvDoH+Bkj2wDr84gvRKnL+Ft4L\nqGiqiJCsVWneAtDc+0qrTc/DniWwbidvVQ0redJJvAzGoJ7bOzYiNvY9QbEh\nYklcvXdC6cORebF7+9/kzDmR/UEx91VRzrsXsGpQlAGju2S5amHn8cdXzL1W\nGor9\r\n=GxiZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDURXUatK0f+SINQ1nvv+vnwCnFnpvPSlaxCXUx4XdQ9QIhAKZ1LdKQGRlPf0wdP5LzXx7wT4956mEgzmPdoAA3Ta33"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.2.1_1606531187928_0.8947083806893714"},"_hasShrinkwrap":false},"3.0.0":{"name":"@zuze/pubsub","version":"3.0.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel:cjs && rollup -c","babel:cjs":"babel src -d build","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"ERROR: No README data found!","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@3.0.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JBB4uFBkZ1Xmmr6s2JPTSWesu2mFAmoYXQq23TChyBvALXxIg6p13YomNdHfW3Vkvvfr739yZC7RUj+cDZHRJA==","shasum":"0da3578560915895dfbe5a348aabdf34143d69c3","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.0.tgz","fileCount":38,"unpackedSize":43458,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0EGpCRA9TVsSAnZWagAAKkAQAKB3ymE+h7AcoQvvdNaF\n87/q2DxtKjaD9uPmiLoXI/2zcDj81Rlcr3CltedSQuYA5o+z5ToJOoGpq5TX\nfn5/QuTb9I5+2CT2MHtuehFO+E+wVDgEq5J1mJDQXIUVMIaIbGti26FAycVF\nDGV3mQTzTa7tYrDdpzmMub8TedqXFM0t0zIg4FXue57/Xk2gw8AhDxRz/m3J\nL48HYCRkDgHmWVYq3pfSqAd2nqot0sE58gsRj2AEQXF502OMjRZJ/ZSmY9ZQ\nI0n0fTbzfWAKCkwSvb3l7b2DD+NozCORw0EmZT1c5oC66IbhEgLvPHpFn3yk\nYgXlI9TLtbg6FzJHFvbnUcsFx6j8eeFYK2EMs3aYG87n6Yp2qCDVcuv38o9T\noGhKevyj1o3bj/7ZCsFSyC40NOBJhTTkhTLRTWPmRJcZqSZOIXd9TUZVlF7D\n42/2tWK/5T0ty+nLVlscK0TzeHLoHnaGf/LtBe7o4JWyZiSP9LeTx06wA0DJ\nFAzP7Kosi7x9LYf+DTjQSbaYSDUbwM1HLiy41XQAoc2ANzZsccoxx3jtVN6j\nGj+PWzE//ElRKAhSoiCmYQFrFbCw/8Q89vglJA3WYDgwHkxJNZhTjVtCnHct\nqRQ/qIjKyY4+GAxFwHH/bKQvUFKm4F+Or17Td0n6iMPmm9PuDt62/bD5pZhW\ntPP9\r\n=IWMA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCOBPDAdEUYRE6ZdcU8PQfm4b/txP7j7OzeckdBHsXCBAIhALh+rbCo5sYZecdB7mxq5ahjrW/wPsBWZKCqdHsqGBbM"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.0_1607483816536_0.8412676658051532"},"_hasShrinkwrap":false},"2.2.2":{"name":"@zuze/pubsub","version":"2.2.2","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && yarn pub","clean":"rimraf build","build":"yarn clean && rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.2.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-lG1h8xNUDYwR4VGB7Ida3kZS3GycFup6QAEnySTo4gNL0LeecOj6e4KO5EZ8QCFLk2dwfz5fKyfLRLknppC28Q==","shasum":"39bfa82f5a673f9e708781b0a9c3792c4dd9ba8a","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.2.2.tgz","fileCount":14,"unpackedSize":48455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0EJ+CRA9TVsSAnZWagAA3RcP/iWqWwrDiNtdn8B6TXRK\nrkTo4CMxWxXLTs+tmBoiq2+LAD+JkQ1fD1yaXCR3IE5Ap0ulTy+lOLFn/zVc\n6Y7MS50Tkit9YRJ1tEEXVakrdyuXfhsbwaU0wSA9RjeXcK9we3xoII/iGh3t\nBwZTSXC8pJ0gKijfoJCw8qgJgNUuysZsw85fxr8REQiq+vcv3h91qCBRAmy5\nKjgur8TyWoaMcAs2e3H003fJr8O9lStqwjonz2As5ADrCrdCWRQ+KaCuDlbr\ng2SOzhADYaryYnrFoztbVAwYOqCI7lqOkRDlL43V3q9VKtHp2Z0GsUTYegJm\n4jZqs+FwhQ33K2ck5xu6Cds91u/n/0OysSd/EW9V3wswgaLwe7w6tD3AasNx\n+mOV8IlmbArH9togJBMOtYl1YXQJu0wzOBPs3BpFS0ajWMw3bMH9p1kV+pSd\nM+rTNnWzJ81/zFdr2f5JkmMIGPx3B5+uBJ1J0bZF4/ht8z4TV1pyAiVOll9G\nwm/yXtydbow5eiOO+pPddckGdc9envl0zN18588m3n1LR8/BMPJWobRWMWsy\n5ZmXaJp7Jk/lPq9/76yE+M0axXgdoBlFL2MCu4LtEoJlKZeSAiq6vSabZb8z\njaC7I5/adqS6aRASYN95+m0zyPy2KiO9s8F7tAm45OmGnBxqDKwCfpCfXG+B\nd/2y\r\n=3B/E\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEA26SLUqKXR8Yx9BuZ0TbQDFpeJUfQ4w8ih99OT4BvbAiBM3r0yS+jvJ6lwAbsXx8muJRLh2d+JPCwLlDrCkK1wnw=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.2.2_1607484030361_0.08232755458001662"},"_hasShrinkwrap":false},"3.0.1":{"name":"@zuze/pubsub","version":"3.0.1","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel:cjs && rollup -c","babel:cjs":"babel src -d build","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"## @zuze/pubsub\n\n[![npm version](https://img.shields.io/npm/v/@zuze/pubsub.svg)](https://npmjs.org/package/@zuze/pubsub)\n[![Coverage Status](https://coveralls.io/repos/github/zuze-lab/pubsub/badge.svg)](https://coveralls.io/github/zuze-lab/pubsub)\n[![Build Status](https://travis-ci.com/zuze-lab/pubsub.svg)](https://travis-ci.com/zuze-lab/pubsub)\n[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/@zuze/pubsub)](https://bundlephobia.com/result?p=@zuze/pubsub)\n\n## What is this?\n\n[PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is one of the best known decoupling software architecture patterns - it allows different components to communicate with each other without knowing about each other.\n\n## What's special about this one?\n\nWell, we really like the RxJS inspired [operators](#subscribing-with-pipe-and-operators) and the [super small dependency free package size](https://bundlephobia.com/result?p=@zuze/pubsub).\n\n### Getting Started\n\nInstall it as a dependency in your JavaScript/Typescript project\n\n```bash\nnpm install @zuze/pubsub\n# or\nyarn add @zuze/pubsub\n```\n\nOr just pull it in from the browser:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { pubsub } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(console.log);\n    publish('it works!'); // logs it works! in the console\n</script>\n```\n\nThe core `pubsub` is extremely tiny and, to be honest, mostly useless. But it forms a core structure that can be extended with just a few lines to create other incredibly tiny and less-useless utilities, like a pubsub with topics:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { topic } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe('someEvent', console.log);\n    publish('someEvent', 'it works!'); // logs it works! in the console\n</script>\n```\n\nOr a super tiny state manager:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { state } = zuze;\n    const { getState, setState, subscribe } = state('joe');\n    console.log(getState()) // logs joe\n    const unsubscribe = subscribe(console.log) // logs joe\n    setState('jim'); // the above subscriber logs jim\n    unsubscribe();\n    setState('fred'); // nothing logged, we unsubscribed\n</script>\n```\n\nThe three utilities combined, built on top of each other, come in at a rather hefty (heh) **400 bytes**.\n\n\n### API\n\n- **`pubsub<T>(): EventBus<T>`**\n\nCreates an `EventBus` of type `T`\n\n```js\nimport pubsub from '@zuze/pubsub';\n\nconst { publish, subscribe } = pubsub<string>();\n\nconst unsub = subscribe(console.log);\npublish('joe'); // logs joe\nunsub();\npublish('fred'); // no log\n\n```\n\n- **`pubsub<T extends Topics>(): EventBus<T>`**\n\nCreate an `EventBus` of type T.\n\n```js\nimport pubsub from '@zuze/pubsub';\n\ntype Topics = {\n    user_event: {\n        first_name: string;\n        last_name: string;\n        user_id: number;\n    };\n    post: {\n        post_id: number;\n        content: string;\n    };\n    comment: {\n        comment_id: number;\n        content: string;\n        post_id: number;\n    };\n    nums: number;\n};\n\nconst { subscribe, publish } = pubsub<Topics>();\n```\n\n\n- **`publish: <R extends keyof T>(topic: R, data: T[R], sync?: boolean) => void`**\n\nBroadcasts an entity to all subscribers on a given topic:\n\n```js\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n```\n\nTake note of the optional third `sync` parameter. By default `@zuze/pubsub` broadcasts to all subscribers for a given topic **asynchronously** so as to prevent a single subscriber from potentially blocking any other subscriber. If you pass the third parameter as true, events will be broadcast **synchronously**.\n\n- **`subscribe: <R extends keyof T>(topic: R, subscriber: Subscriber<T[R]>) => Unsubscribe`**\n\nSubscribes to a topic and returns an unsubscribe function.\n\n```js\ne.g. \nconst { subscribe, publish } = pubsub<Topics>();\nconst unsub = subscribe('comment', comment => console.log('got comment',comment));\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n\n/*\noutput:\ngot comment\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n*/\n\nunsub(); // no further events will be logged\n```\n\n## Subscribing with `pipe` and Operators\n\nYou could stop here and have an great, incredibly small and flexible PubSub utility. But subscribing with a `pipe` and operators takes your functional PubSub and/or State management system to the next level. \n\n```js\nimport pubsub from '@zuze/pubsub';\nimport { pipe, filter, subscriber } from '@zuze/pubsub/operators';\n\nconst { subscribe, publish } = pubsub<Topics>();\n\nsubscribe(\n    'comment', \n    pipe(\n        filter(({ comment_id }) => comment_id === 10),\n        subscriber(({ content }) => console.log(content))\n    )\n);\n\npublish('comment', { comment_id: 9, content: 'some comment' }); // no log\npublish('comment', { comment_id: 10, content: 'bye' }); // logs 'bye'\n```\n\n### In the browser\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script src=\"https://unpkg.com/@zuze/pubsub/pipe\"></script>\n<script>\n    const { pubsub, map, subscriber, pipe } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(\n        'someEvent', \n        pipe(\n            map(r => `I said, ${r}`),\n            subscriber(output => console.log(output))\n        )\n    );\n\n    publish('someEvent','it works!'); // logs 'I said, it works!' in the console\n</script>\n```\n\nPerhaps counterintuitively, due to the way a pipe is constructed from operator functions, nothing ever \"comes out\" of it, then end result is always `undefined`. If you want to call some external function at any point in the pipe, use the [subscriber](#subscribertfn-e-t--void-t) operator (an alias of [tap](#taptfn-e-t--void-t))\n\n\n`pipe` and `operators` are ~~stolen from~~ inspired by the [RxJS](https://rxjs-dev.firebaseapp.com/guide/operators) operator API, but without the power, complexity, or sheer size (our operators and utilities weigh less than 1/10th the size) of schedulers or marble diagrams.\n\n### Using Operators\n\n### `pipe<T>(...operators: OperatorFn<T,any>[])`\n\n\nWhen using typescript, if you need to create a pipe separately from a subscription and want to stay type-safe, you can use `createPipe`:\n\n```ts\nimport { createPipe } from '@zuze/pubsub/operators';\n\n// creates a pipe whose operator functions act on SomeType\nconst pipe = createPipe<SomeType>();\nconst myPipe = pipe(...operatorFunctions);\n\n// and then later\nsomePubSub.subscribe(myPipe);\n```\n\nIf you're creating the pipe at subscription time, you can just use `pipe` directly and you'll stay typesafe\n\n```js\nimport { pipe } from '@zuze/pubsub/operators';\nsomePubSub.subscribe(pipe(...operatorFunctions))\n```\n\n\n### Creating Reusable Operators\n\nAn operator function accepts a single parameter - a [unary function](https://en.wikipedia.org/wiki/Unary_function) typically named `next` and returns a function that, after performing some operation, may or may not call `next` with a single argument.\n\nSo an operator creator is any function that returns an operator function.\n\nWhile this might sound complicated, in reality it's just a bunch of fat arrows. Let's create one:\n\n```js\nimport { log } from '@zuze/pubsub/operators';\n\n// greaterThan is an operator creator - a function that returns an operator.\n\ncreateOperator((...args) => event =>)\n\n// call next with the published event if it's greater than the user supplied number\nconst greaterThan = num => next => event => event > num && next(event);\n\n// use like\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe('nums', pipe( greaterThan(5), log() ));\n\npublish('nums', 4); // no log\npublish('nums', 8); // log's 8\n\nconst multiplyBy = num => next => event => next(event*num);\n\n// use like\nsubscribe('nums', pipe( multiplyBy(4), log() ));\n\npublish('nums',4); // logs 16\n\n// chain your custom operators!\nsubscribe('nums', pipe( multiplyBy(4), greaterThan(5), log() ));\n\npublish('nums', 1); // no log\npublish('nums', 2); // logs 8\n\n\n```\n\nAsync operators are trivial:\n\n```js\nimport { topic } from '@zuze/pubsub';\nimport { pipe, log } from '@zuze/pubsub/operators';\n\nconst { publish, subscribe } = topic();\n\n// call next with the published event IF it's greater than the user supplied number\nconst callApiOperator = apiCall => next => async event => next(await apiCall(event));\n\nsubscribe(\n    'user_ids',\n    pipe(\n        callApiOperator(\n            async id => (await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)).json()\n        ),\n        log()\n    )\n);\n\npublish('user_ids', 10);\n```\n\n\nYou can easily create operators that are simply a common reuse of other operators using `pipe` using `pipeable`. \nThis is handy if you find yourself consistently reusing operators together and is used internally to create operators as well:\n\nThe below code is taken directly from `bufferCount`:\n\n```js\nimport { pipeable, stack, filter, map } from '@zuze/pubsub/operators';\n\nconst bufferCount = (size, every) => pipeable(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n);\n```\n\nJust for fun, creating bufferCount without using `pipeable` would look like this:\n\n```js\nconst bufferCount = (size,every) => next => pipe(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n  () => next    \n);\n```\n\n### List of Operators\n\nWe tried to stay as close as possible to RxJS operating naming, considering we're not in an observable environment.\nWith that in mind, here's the list:\n\n#### `map<T,R>(mapper: (e: T) => R): R`\n\nTransforms the emitted event into a new value using a function before passing it to the next function:\n\n```js\nconst fn = pipe( map(e => e*2), log() ) )\nfn(3); // logs 6\n```\n\n#### `mapTo<R>(mapper: () => R): R`\n\nTransforms the emitted event into a new value before passing it to the next function\n\n```js\nconst fn = pipe( map('joe'), log() ) )\nfn(3); // logs 'joe'\n```\n\n#### `take<T>(num: number): T`\n\nStops calling the next function after `num`\n\n```js\nconst fn = pipe( take(2), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\nfn(3); // no log\n```\n\n#### `takeUntil<T>(promise: Promise<void>): T`\n\nCalls the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\n// 2 seconds pass\nfn(3); // no log\n```\n\n#### `startWith<T>(T | Promise<T> | () => (T | Promise<T>)): T`\n\nImmediately calls the next operator in the chain with the value:\n\n```js\n\nconst fn = pipe( filter(i => i > 2), startWith(7), log() ); // 7 is logged immediately\nfn(1); // no log\nfn(3); // logs 3\n\n\nconst fn = pipe ( filter(i => i > 2), startWith(() => new Promise(res => setTimeout(() => res(7))), log() );\n\n```\n\n#### `single<T>():T`\n\nAlias of `take(1)`\n\n#### `skip<T>(num: number): T`\n\nOnly starts calling the next function after `num` calls\n\n```js\nconst fn = pipe( skip(2), log() ) )\nfn(3); // no log\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `skipUntil<T>(promise: Promise<void>): T`\n\nPrevents calling the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // no log\nfn(3); // no log\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `tap<T>(fn: (e: T) => void): T`\n\nCalls it's function argument with the emitted event and continues calling the next function in the pipe:\n\n```js\nconst fn = pipe( tap(e => console.log(e*2)), log() ) )\nfn(3); // logs 6, then logs 3\n```\n\n#### `subscriber<T>(fn: (e: T) => void): T`\n\nAlias of `tap`\n\n#### `log<T>(): T`\n\nAlias of `tap(console.log)`\n\n#### `every<T>(num: number): T`\n\nOnly calls the subsequent function in the pipe when a modulo of `num` has been admitted.\n\n```js\nconst fn = pipe( every(2), log() ); // only proceed after every second event\nfn(3); // no log\nfn(3); // logs 3\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `count<T>(startAt?: number): [number,T]`\n\nAdds in the number of events that have been emitted when calling the next function in the chain:\n\n```js\nconst fn = pipe( count(), log() ); \nfn(3); // logs [0,3]\nfn(3); // logs [1,3]\nfn(3); // logs [2,3]\nfn(3); // logs [3,3]\n```\n\n#### `stack<T>(minSize?: number, maxSize?: number): T[]`\n\nCalls the next operator with an array of all previously emitted events. Will not call the next operator until the stack reaches `minSize` (defaults to 1). Will call the next operator with a maximum array length of `maxSize` (defaults to all).\n\n```js\nconst fn = pipe( stack(), log() ); \n\nfn(1); // logs [1]\nfn(2); // logs [1,2]\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\n\nconst fn = pipe( stack(3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\nconst fn = pipe( stack(3,2), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // logs [3,4]\nfn(5); // logs [4,5]\n\n```\n\n#### `bufferCount<T>(size?: number, every?: number): T[]`\n\nCalls the next operator when at least `size` events have been emitted with an array of `size`. If `every` is provided, will only call the next operator when the current call number%every is 0.\n\n```js\nconst fn = pipe( bufferCount(2,3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // no log\nfn(5); // no log\nfn(6); // logs [5,6]\nfn(7); // no log\n\n```\n\n#### `pairwise<T>(): T[]`\n\nCalls the next operator with an array containing the most recent emitted event (last element) and the event emitted previous to this. \n\nNote: This operator will NOT call the subsequent operator until at least 2 events have been emitted.\n\n#### `filter<T>(filterFn: (e: T) => boolean): T`\n\nThe provided filter function controls whether to calling the next operator in the pipe depending on if it returns true or false\n\n```js\nconst fn = pipe( filter(e => e > 2), log() )\nfn(1); // no log\nfn(3); // logs 3\n```\n\n#### `pluck<T,R>(...keys: string[]): R`\n\nPlucks value from the object the function was called with based on the given keys:\n\n```js\nconst fn = pipe ( pluck( 'comment', 'created_on' ), log() );\nfn({\n    comment: {\n        created_on: 1606101991,\n        content: 'hi'\n    }\n}) // logs 1606101991\n```\n\n#### `distinct<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value hasn't been previously emitted ever.\n  \n#### `distinctKey<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key hasn't been previously emitted ever.\n\n#### `distinctUntilChanged<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value is different than the previous value.\n\n#### `distinctUntilKeyChanged<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key is different than the previous value.\n\n#### `delay(by?: number)`\n\nDelays calling the next function in the pipe using `by` (milliseconds):\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `debounce(by?: number, leading?: boolean = false)`\n\nDebounces calls to the subsequent operator given using `by` (milliseconds).\nIf *leading* is true then the function will be called immediately on first invocation and subsequent calls within `by` will be ignored.\n\n#### `throttle(by?: number, leading?: boolean)`\n\nThrottles calls to the subsequent operator using `by` (milliseconds)\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `select(...selectorFunctions,resultFunc)`\n\nThis is similar, though not identical to [reselect] and really is just a combination of `map` + `distinctUntilChanged`\n\n```js\nimport { state } from '@zuze/pubsub';\nimport { pipe, select, tap } from '@zuze/pubsub/operators';\nconst { getState, setState, subscribe } = state({\n    first:3,\n    second:10\n});\n\nsubscribe(\n    pipe(\n        select(\n            ({ first }) => first,\n            ({ second }) => second,\n            ([ first, second ]) => first + second\n        ),\n        tap(console.log)\n    )\n); // logs 13\n\nsetState({third:9}); // doesn't log anything because arguments to the selector haven't changed\n```\n\n\n## Contributing\n\nPRs are welcome!\n\n## License\n\nMIT © [akmjenkins](https://github.com/akmjenkins)","readmeFilename":"README.md","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@3.0.1","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-9Nw9yJryuy4SPIOxnmTe1OxTYwW1/i2RPLp4FowAhqJgOaYQJhE+6sjoAertcbZiTaW9StilE7E8vmD3PG92aQ==","shasum":"719aed79a79e3aa3055c8ffca2a84fe9947a5616","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.1.tgz","fileCount":39,"unpackedSize":60055,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0EO9CRA9TVsSAnZWagAAkY4P/2LDzLj+2nlhv3ZuaYBD\nFl/RqsPT8kdkWwH8YaZdS+Y71zglgyMlOCYIYnww+ABVeENdzBFmFV3txMyh\nHp31xOeKnBQ/gIfzuX+DG1/xF/hFKNhqF7x94TF7MVKVlrSb7Ljgz2cLqM+W\n8bPKIFmX/y5QSe+QJFZA3ljgVqJJcrf8y4OSmCN2LQFraQTX9xKKGHO+C5q+\nzZQh1mMk6F5PfScSc7Qh4m4Sv1Gvw8BgKmGk8BM5QGd0MTM0UPL9CfqpFDN/\nFG4Hw6D3wlQ78fbt/bbXn77PYQj1W4/eewYG21kG45BHEtNlYYBW3tLRJ6V4\nvPlsI5ufbYPaF/+o76BUeUkbtSGd4fMFj4dKy91zH//Mp82qVHSFGT1oNDYy\nwdpz9x/2MmsdXJ+nmbhbjUGJIuqU73KoO9vErEy1JB7668+jny7K1uv8VlZl\nbHIPkQwNOIP1L7MRw0aCOr2/lqO0ULIOjqrg3schteL5tmQB8Q+3xNALCii4\nOLcmXPGPHALeFH1rB5j7UvRtdRz0qhXsJl+HUiJe2BqSkdyeaYtf+rUUcy74\nq7la3UO31EC2wbMSeHkpcDf2yrO+5TZKk7/esoRaKjJH+vZUtCDOi3OfCAEJ\nZWdVVlzhhar7MrCKG2z2Tini1v82YOs7lBVBF+IKIkWnxN00t+S/4aJjY3L6\nxjn+\r\n=3CO8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHcar2tLalHfUV15y93sQCfndXRMvHYi0o2KAp7dycUMAiAH8UAnYy0NUg9ATANdDc7rysXH7v8OzDawQTLiMir2Rg=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.1_1607484349259_0.30730626828662944"},"_hasShrinkwrap":false},"3.0.2":{"name":"@zuze/pubsub","version":"3.0.2","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel:cjs && rollup -c","babel:cjs":"babel src -d build","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"## @zuze/pubsub\n\n[![npm version](https://img.shields.io/npm/v/@zuze/pubsub.svg)](https://npmjs.org/package/@zuze/pubsub)\n[![Coverage Status](https://coveralls.io/repos/github/zuze-lab/pubsub/badge.svg)](https://coveralls.io/github/zuze-lab/pubsub)\n[![Build Status](https://travis-ci.com/zuze-lab/pubsub.svg)](https://travis-ci.com/zuze-lab/pubsub)\n[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/@zuze/pubsub)](https://bundlephobia.com/result?p=@zuze/pubsub)\n\n## What is this?\n\n[PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is one of the best known decoupling software architecture patterns - it allows different components to communicate with each other without knowing about each other.\n\n## What's special about this one?\n\nWell, we really like the RxJS inspired [operators](#subscribing-with-pipe-and-operators) and the [super small dependency free package size](https://bundlephobia.com/result?p=@zuze/pubsub).\n\n### Getting Started\n\nInstall it as a dependency in your JavaScript/Typescript project\n\n```bash\nnpm install @zuze/pubsub\n# or\nyarn add @zuze/pubsub\n```\n\nOr just pull it in from the browser:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { pubsub } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(console.log);\n    publish('it works!'); // logs it works! in the console\n</script>\n```\n\nThe core `pubsub` is extremely tiny and, to be honest, mostly useless. But it forms a core structure that can be extended with just a few lines to create other incredibly tiny and less-useless utilities, like a pubsub with topics:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { topic } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe('someEvent', console.log);\n    publish('someEvent', 'it works!'); // logs it works! in the console\n</script>\n```\n\nOr a super tiny state manager:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { state } = zuze;\n    const { getState, setState, subscribe } = state('joe');\n    console.log(getState()) // logs joe\n    const unsubscribe = subscribe(console.log) // logs joe\n    setState('jim'); // the above subscriber logs jim\n    unsubscribe();\n    setState('fred'); // nothing logged, we unsubscribed\n</script>\n```\n\nThe three utilities combined, built on top of each other, come in at a rather hefty (heh) **400 bytes**.\n\n\n### API\n\n- **`pubsub<T>(): EventBus<T>`**\n\nCreates an `EventBus` of type `T`\n\n```js\nimport pubsub from '@zuze/pubsub';\n\nconst { publish, subscribe } = pubsub<string>();\n\nconst unsub = subscribe(console.log);\npublish('joe'); // logs joe\nunsub();\npublish('fred'); // no log\n\n```\n\n- **`pubsub<T extends Topics>(): EventBus<T>`**\n\nCreate an `EventBus` of type T.\n\n```js\nimport pubsub from '@zuze/pubsub';\n\ntype Topics = {\n    user_event: {\n        first_name: string;\n        last_name: string;\n        user_id: number;\n    };\n    post: {\n        post_id: number;\n        content: string;\n    };\n    comment: {\n        comment_id: number;\n        content: string;\n        post_id: number;\n    };\n    nums: number;\n};\n\nconst { subscribe, publish } = pubsub<Topics>();\n```\n\n\n- **`publish: <R extends keyof T>(topic: R, data: T[R], sync?: boolean) => void`**\n\nBroadcasts an entity to all subscribers on a given topic:\n\n```js\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n```\n\nTake note of the optional third `sync` parameter. By default `@zuze/pubsub` broadcasts to all subscribers for a given topic **asynchronously** so as to prevent a single subscriber from potentially blocking any other subscriber. If you pass the third parameter as true, events will be broadcast **synchronously**.\n\n- **`subscribe: <R extends keyof T>(topic: R, subscriber: Subscriber<T[R]>) => Unsubscribe`**\n\nSubscribes to a topic and returns an unsubscribe function.\n\n```js\ne.g. \nconst { subscribe, publish } = pubsub<Topics>();\nconst unsub = subscribe('comment', comment => console.log('got comment',comment));\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n\n/*\noutput:\ngot comment\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n*/\n\nunsub(); // no further events will be logged\n```\n\n## Subscribing with `pipe` and Operators\n\nYou could stop here and have an great, incredibly small and flexible PubSub utility. But subscribing with a `pipe` and operators takes your functional PubSub and/or State management system to the next level. \n\n```js\nimport pubsub from '@zuze/pubsub';\nimport { pipe, filter, subscriber } from '@zuze/pubsub/operators';\n\nconst { subscribe, publish } = pubsub<Topics>();\n\nsubscribe(\n    'comment', \n    pipe(\n        filter(({ comment_id }) => comment_id === 10),\n        subscriber(({ content }) => console.log(content))\n    )\n);\n\npublish('comment', { comment_id: 9, content: 'some comment' }); // no log\npublish('comment', { comment_id: 10, content: 'bye' }); // logs 'bye'\n```\n\n### In the browser\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script src=\"https://unpkg.com/@zuze/pubsub/pipe\"></script>\n<script>\n    const { pubsub, map, subscriber, pipe } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(\n        'someEvent', \n        pipe(\n            map(r => `I said, ${r}`),\n            subscriber(output => console.log(output))\n        )\n    );\n\n    publish('someEvent','it works!'); // logs 'I said, it works!' in the console\n</script>\n```\n\nPerhaps counterintuitively, due to the way a pipe is constructed from operator functions, nothing ever \"comes out\" of it, then end result is always `undefined`. If you want to call some external function at any point in the pipe, use the [subscriber](#subscribertfn-e-t--void-t) operator (an alias of [tap](#taptfn-e-t--void-t))\n\n\n`pipe` and `operators` are ~~stolen from~~ inspired by the [RxJS](https://rxjs-dev.firebaseapp.com/guide/operators) operator API, but without the power, complexity, or sheer size (our operators and utilities weigh less than 1/10th the size) of schedulers or marble diagrams.\n\n### Using Operators\n\n### `pipe<T>(...operators: OperatorFn<T,any>[])`\n\n\nWhen using typescript, if you need to create a pipe separately from a subscription and want to stay type-safe, you can use `createPipe`:\n\n```ts\nimport { createPipe } from '@zuze/pubsub/operators';\n\n// creates a pipe whose operator functions act on SomeType\nconst pipe = createPipe<SomeType>();\nconst myPipe = pipe(...operatorFunctions);\n\n// and then later\nsomePubSub.subscribe(myPipe);\n```\n\nIf you're creating the pipe at subscription time, you can just use `pipe` directly and you'll stay typesafe\n\n```js\nimport { pipe } from '@zuze/pubsub/operators';\nsomePubSub.subscribe(pipe(...operatorFunctions))\n```\n\n\n### Creating Reusable Operators\n\nAn operator function accepts a single parameter - a [unary function](https://en.wikipedia.org/wiki/Unary_function) typically named `next` and returns a function that, after performing some operation, may or may not call `next` with a single argument.\n\nSo an operator creator is any function that returns an operator function.\n\nWhile this might sound complicated, in reality it's just a bunch of fat arrows. Let's create one:\n\n```js\nimport { log } from '@zuze/pubsub/operators';\n\n// greaterThan is an operator creator - a function that returns an operator.\n\ncreateOperator((...args) => event =>)\n\n// call next with the published event if it's greater than the user supplied number\nconst greaterThan = num => next => event => event > num && next(event);\n\n// use like\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe('nums', pipe( greaterThan(5), log() ));\n\npublish('nums', 4); // no log\npublish('nums', 8); // log's 8\n\nconst multiplyBy = num => next => event => next(event*num);\n\n// use like\nsubscribe('nums', pipe( multiplyBy(4), log() ));\n\npublish('nums',4); // logs 16\n\n// chain your custom operators!\nsubscribe('nums', pipe( multiplyBy(4), greaterThan(5), log() ));\n\npublish('nums', 1); // no log\npublish('nums', 2); // logs 8\n\n\n```\n\nAsync operators are trivial:\n\n```js\nimport { topic } from '@zuze/pubsub';\nimport { pipe, log } from '@zuze/pubsub/operators';\n\nconst { publish, subscribe } = topic();\n\n// call next with the published event IF it's greater than the user supplied number\nconst callApiOperator = apiCall => next => async event => next(await apiCall(event));\n\nsubscribe(\n    'user_ids',\n    pipe(\n        callApiOperator(\n            async id => (await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)).json()\n        ),\n        log()\n    )\n);\n\npublish('user_ids', 10);\n```\n\n\nYou can easily create operators that are simply a common reuse of other operators using `pipe` using `pipeable`. \nThis is handy if you find yourself consistently reusing operators together and is used internally to create operators as well:\n\nThe below code is taken directly from `bufferCount`:\n\n```js\nimport { pipeable, stack, filter, map } from '@zuze/pubsub/operators';\n\nconst bufferCount = (size, every) => pipeable(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n);\n```\n\nJust for fun, creating bufferCount without using `pipeable` would look like this:\n\n```js\nconst bufferCount = (size,every) => next => pipe(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n  () => next    \n);\n```\n\n### List of Operators\n\nWe tried to stay as close as possible to RxJS operating naming, considering we're not in an observable environment.\nWith that in mind, here's the list:\n\n#### `map<T,R>(mapper: (e: T) => R): R`\n\nTransforms the emitted event into a new value using a function before passing it to the next function:\n\n```js\nconst fn = pipe( map(e => e*2), log() ) )\nfn(3); // logs 6\n```\n\n#### `mapTo<R>(mapper: () => R): R`\n\nTransforms the emitted event into a new value before passing it to the next function\n\n```js\nconst fn = pipe( map('joe'), log() ) )\nfn(3); // logs 'joe'\n```\n\n#### `take<T>(num: number): T`\n\nStops calling the next function after `num`\n\n```js\nconst fn = pipe( take(2), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\nfn(3); // no log\n```\n\n#### `takeUntil<T>(promise: Promise<void>): T`\n\nCalls the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\n// 2 seconds pass\nfn(3); // no log\n```\n\n#### `startWith<T>(T | Promise<T> | () => (T | Promise<T>)): T`\n\nImmediately calls the next operator in the chain with the value:\n\n```js\n\nconst fn = pipe( filter(i => i > 2), startWith(7), log() ); // 7 is logged immediately\nfn(1); // no log\nfn(3); // logs 3\n\n\nconst fn = pipe ( filter(i => i > 2), startWith(() => new Promise(res => setTimeout(() => res(7))), log() );\n\n```\n\n#### `single<T>():T`\n\nAlias of `take(1)`\n\n#### `skip<T>(num: number): T`\n\nOnly starts calling the next function after `num` calls\n\n```js\nconst fn = pipe( skip(2), log() ) )\nfn(3); // no log\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `skipUntil<T>(promise: Promise<void>): T`\n\nPrevents calling the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // no log\nfn(3); // no log\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `tap<T>(fn: (e: T) => void): T`\n\nCalls it's function argument with the emitted event and continues calling the next function in the pipe:\n\n```js\nconst fn = pipe( tap(e => console.log(e*2)), log() ) )\nfn(3); // logs 6, then logs 3\n```\n\n#### `subscriber<T>(fn: (e: T) => void): T`\n\nAlias of `tap`\n\n#### `log<T>(): T`\n\nAlias of `tap(console.log)`\n\n#### `every<T>(num: number): T`\n\nOnly calls the subsequent function in the pipe when a modulo of `num` has been admitted.\n\n```js\nconst fn = pipe( every(2), log() ); // only proceed after every second event\nfn(3); // no log\nfn(3); // logs 3\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `count<T>(startAt?: number): [number,T]`\n\nAdds in the number of events that have been emitted when calling the next function in the chain:\n\n```js\nconst fn = pipe( count(), log() ); \nfn(3); // logs [0,3]\nfn(3); // logs [1,3]\nfn(3); // logs [2,3]\nfn(3); // logs [3,3]\n```\n\n#### `stack<T>(minSize?: number, maxSize?: number): T[]`\n\nCalls the next operator with an array of all previously emitted events. Will not call the next operator until the stack reaches `minSize` (defaults to 1). Will call the next operator with a maximum array length of `maxSize` (defaults to all).\n\n```js\nconst fn = pipe( stack(), log() ); \n\nfn(1); // logs [1]\nfn(2); // logs [1,2]\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\n\nconst fn = pipe( stack(3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\nconst fn = pipe( stack(3,2), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // logs [3,4]\nfn(5); // logs [4,5]\n\n```\n\n#### `bufferCount<T>(size?: number, every?: number): T[]`\n\nCalls the next operator when at least `size` events have been emitted with an array of `size`. If `every` is provided, will only call the next operator when the current call number%every is 0.\n\n```js\nconst fn = pipe( bufferCount(2,3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // no log\nfn(5); // no log\nfn(6); // logs [5,6]\nfn(7); // no log\n\n```\n\n#### `pairwise<T>(): T[]`\n\nCalls the next operator with an array containing the most recent emitted event (last element) and the event emitted previous to this. \n\nNote: This operator will NOT call the subsequent operator until at least 2 events have been emitted.\n\n#### `filter<T>(filterFn: (e: T) => boolean): T`\n\nThe provided filter function controls whether to calling the next operator in the pipe depending on if it returns true or false\n\n```js\nconst fn = pipe( filter(e => e > 2), log() )\nfn(1); // no log\nfn(3); // logs 3\n```\n\n#### `pluck<T,R>(...keys: string[]): R`\n\nPlucks value from the object the function was called with based on the given keys:\n\n```js\nconst fn = pipe ( pluck( 'comment', 'created_on' ), log() );\nfn({\n    comment: {\n        created_on: 1606101991,\n        content: 'hi'\n    }\n}) // logs 1606101991\n```\n\n#### `distinct<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value hasn't been previously emitted ever.\n  \n#### `distinctKey<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key hasn't been previously emitted ever.\n\n#### `distinctUntilChanged<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value is different than the previous value.\n\n#### `distinctUntilKeyChanged<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key is different than the previous value.\n\n#### `delay(by?: number)`\n\nDelays calling the next function in the pipe using `by` (milliseconds):\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `debounce(by?: number, leading?: boolean = false)`\n\nDebounces calls to the subsequent operator given using `by` (milliseconds).\nIf *leading* is true then the function will be called immediately on first invocation and subsequent calls within `by` will be ignored.\n\n#### `throttle(by?: number, leading?: boolean)`\n\nThrottles calls to the subsequent operator using `by` (milliseconds)\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `select(...selectorFunctions,resultFunc)`\n\nThis is similar, though not identical to [reselect] and really is just a combination of `map` + `distinctUntilChanged`\n\n```js\nimport { state } from '@zuze/pubsub';\nimport { pipe, select, tap } from '@zuze/pubsub/operators';\nconst { getState, setState, subscribe } = state({\n    first:3,\n    second:10\n});\n\nsubscribe(\n    pipe(\n        select(\n            ({ first }) => first,\n            ({ second }) => second,\n            ([ first, second ]) => first + second\n        ),\n        tap(console.log)\n    )\n); // logs 13\n\nsetState({third:9}); // doesn't log anything because arguments to the selector haven't changed\n```\n\n\n## Contributing\n\nPRs are welcome!\n\n## License\n\nMIT © [akmjenkins](https://github.com/akmjenkins)","readmeFilename":"README.md","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@3.0.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-j+47thq/h+ruuc9/NTkvQttneER4lhQlk+I1zey8+nAQieeQ1UJVq9vFouypw8M5UpCPeJoGaOa+s3wWMfODUA==","shasum":"c145a3a7bda3f3a69b1546d3f2bb6ceb49d7b440","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.2.tgz","fileCount":39,"unpackedSize":60054,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0EPwCRA9TVsSAnZWagAAH7gP/1jWoiJsvK0LSiQp6RVZ\n/lidwU2HYkeCDdCbefKw6GjwEQZzvS4iP0EFiFfty4HBX/oM2IuKp/kQ5KAD\nCy2zKwyOhsYES01xN5YJHG+03738GGfPJoXSE22J6wQxvcgFFeI4tDeop0MA\nSd1TJrgM8fEUNNxD6pjtWeYzfVfpX38HQ8st1DsTs6GYCx+x03gC2YbOJhIp\nRR7THtI1WJ/IWQtXUitjr08tUAlbfiDonQuSbv63vSbhUdYtxCr8KcaM/VYd\nlpg/p72zzgBXLgXWwsIcOH0x8tgMsUTeJ4Ov9DSCAA2jypFWfMuGmeGuqtup\nIJu4RojNpvnXaopzvSve10qbm+HpZoQuDGzRO0y56uxrg/bflnz43b52uozj\nq+tPndYkWxf6RmoQjkfwW1gupBxNPa788BNdEamKACqk6D4iicW+pTVqng5q\ngM/B9pTVRSm1V0NRWHWWO0DGvd9uKlYCCYYGAJ5nZDbXHOZzA+vRZ04ZZ37Q\n9w1/2HWGUw3Iyokox8Pd8OigdE64Ep7j17MQDcHJ1t3+C3oQ3juuE2LkT12l\nUpO6Bl/PVQOv4XRtU1RH3ZLpZ7ZNOyKflgL2Bf3v6qg0EbNOgRUdSQvl/G9/\nyaXzVxl5hiGB4UPiMzUedwgC/SbXqrigIXpyFNULPnGh5Nen4jaJ6Tw1NS9V\nuPPs\r\n=2jDl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFrcDX045QWnTPGIE+F4WD8UoYfVbwKnxOmzE7ByBFWaAiAFhtMeOyRas1pgnO+JERruSfahlPeaGUNMoDFGXoKYBQ=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.2_1607484399976_0.13675748335237414"},"_hasShrinkwrap":false},"3.0.3":{"name":"@zuze/pubsub","version":"3.0.3","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && cp -a .npmignore build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel:cjs && rollup -c","babel:cjs":"babel src -d build --copy-files --no-copy-ignored","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"## @zuze/pubsub\n\n[![npm version](https://img.shields.io/npm/v/@zuze/pubsub.svg)](https://npmjs.org/package/@zuze/pubsub)\n[![Coverage Status](https://coveralls.io/repos/github/zuze-lab/pubsub/badge.svg)](https://coveralls.io/github/zuze-lab/pubsub)\n[![Build Status](https://travis-ci.com/zuze-lab/pubsub.svg)](https://travis-ci.com/zuze-lab/pubsub)\n[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/@zuze/pubsub)](https://bundlephobia.com/result?p=@zuze/pubsub)\n\n## What is this?\n\n[PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is one of the best known decoupling software architecture patterns - it allows different components to communicate with each other without knowing about each other.\n\n## What's special about this one?\n\nWell, we really like the RxJS inspired [operators](#subscribing-with-pipe-and-operators) and the [super small dependency free package size](https://bundlephobia.com/result?p=@zuze/pubsub).\n\n### Getting Started\n\nInstall it as a dependency in your JavaScript/Typescript project\n\n```bash\nnpm install @zuze/pubsub\n# or\nyarn add @zuze/pubsub\n```\n\nOr just pull it in from the browser:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { pubsub } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(console.log);\n    publish('it works!'); // logs it works! in the console\n</script>\n```\n\nThe core `pubsub` is extremely tiny and, to be honest, mostly useless. But it forms a core structure that can be extended with just a few lines to create other incredibly tiny and less-useless utilities, like a pubsub with topics:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { topic } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe('someEvent', console.log);\n    publish('someEvent', 'it works!'); // logs it works! in the console\n</script>\n```\n\nOr a super tiny state manager:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { state } = zuze;\n    const { getState, setState, subscribe } = state('joe');\n    console.log(getState()) // logs joe\n    const unsubscribe = subscribe(console.log) // logs joe\n    setState('jim'); // the above subscriber logs jim\n    unsubscribe();\n    setState('fred'); // nothing logged, we unsubscribed\n</script>\n```\n\nThe three utilities combined, built on top of each other, come in at a rather hefty (heh) **400 bytes**.\n\n\n### API\n\n- **`pubsub<T>(): EventBus<T>`**\n\nCreates an `EventBus` of type `T`\n\n```js\nimport { pubsub } from '@zuze/pubsub';\n\nconst { publish, subscribe } = pubsub<string>();\n\nconst unsub = subscribe(console.log);\npublish('joe'); // logs joe\nunsub();\npublish('fred'); // no log\n\n```\n\n- **`pubsub<T extends Topics>(): EventBus<T>`**\n\nCreate an `EventBus` of type T.\n\n```js\nimport pubsub from '@zuze/pubsub';\n\ntype Topics = {\n    user_event: {\n        first_name: string;\n        last_name: string;\n        user_id: number;\n    };\n    post: {\n        post_id: number;\n        content: string;\n    };\n    comment: {\n        comment_id: number;\n        content: string;\n        post_id: number;\n    };\n    nums: number;\n};\n\nconst { subscribe, publish } = pubsub<Topics>();\n```\n\n\n- **`publish: <R extends keyof T>(topic: R, data: T[R], sync?: boolean) => void`**\n\nBroadcasts an entity to all subscribers on a given topic:\n\n```js\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n```\n\nTake note of the optional third `sync` parameter. By default `@zuze/pubsub` broadcasts to all subscribers for a given topic **asynchronously** so as to prevent a single subscriber from potentially blocking any other subscriber. If you pass the third parameter as true, events will be broadcast **synchronously**.\n\n- **`subscribe: <R extends keyof T>(topic: R, subscriber: Subscriber<T[R]>) => Unsubscribe`**\n\nSubscribes to a topic and returns an unsubscribe function.\n\n```js\ne.g. \nconst { subscribe, publish } = pubsub<Topics>();\nconst unsub = subscribe('comment', comment => console.log('got comment',comment));\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n\n/*\noutput:\ngot comment\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n*/\n\nunsub(); // no further events will be logged\n```\n\n## Subscribing with `pipe` and Operators\n\nYou could stop here and have an great, incredibly small and flexible PubSub utility. But subscribing with a `pipe` and operators takes your functional PubSub and/or State management system to the next level. \n\n```js\nimport pubsub from '@zuze/pubsub';\nimport { pipe, filter, subscriber } from '@zuze/pubsub/operators';\n\nconst { subscribe, publish } = pubsub<Topics>();\n\nsubscribe(\n    'comment', \n    pipe(\n        filter(({ comment_id }) => comment_id === 10),\n        subscriber(({ content }) => console.log(content))\n    )\n);\n\npublish('comment', { comment_id: 9, content: 'some comment' }); // no log\npublish('comment', { comment_id: 10, content: 'bye' }); // logs 'bye'\n```\n\n### In the browser\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script src=\"https://unpkg.com/@zuze/pubsub/pipe\"></script>\n<script>\n    const { pubsub, map, subscriber, pipe } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(\n        'someEvent', \n        pipe(\n            map(r => `I said, ${r}`),\n            subscriber(output => console.log(output))\n        )\n    );\n\n    publish('someEvent','it works!'); // logs 'I said, it works!' in the console\n</script>\n```\n\nPerhaps counterintuitively, due to the way a pipe is constructed from operator functions, nothing ever \"comes out\" of it, then end result is always `undefined`. If you want to call some external function at any point in the pipe, use the [subscriber](#subscribertfn-e-t--void-t) operator (an alias of [tap](#taptfn-e-t--void-t))\n\n\n`pipe` and `operators` are ~~stolen from~~ inspired by the [RxJS](https://rxjs-dev.firebaseapp.com/guide/operators) operator API, but without the power, complexity, or sheer size (our operators and utilities weigh less than 1/10th the size) of schedulers or marble diagrams.\n\n### Using Operators\n\n### `pipe<T>(...operators: OperatorFn<T,any>[])`\n\n\nWhen using typescript, if you need to create a pipe separately from a subscription and want to stay type-safe, you can use `createPipe`:\n\n```ts\nimport { createPipe } from '@zuze/pubsub/operators';\n\n// creates a pipe whose operator functions act on SomeType\nconst pipe = createPipe<SomeType>();\nconst myPipe = pipe(...operatorFunctions);\n\n// and then later\nsomePubSub.subscribe(myPipe);\n```\n\nIf you're creating the pipe at subscription time, you can just use `pipe` directly and you'll stay typesafe\n\n```js\nimport { pipe } from '@zuze/pubsub/operators';\nsomePubSub.subscribe(pipe(...operatorFunctions))\n```\n\n\n### Creating Reusable Operators\n\nAn operator function accepts a single parameter - a [unary function](https://en.wikipedia.org/wiki/Unary_function) typically named `next` and returns a function that, after performing some operation, may or may not call `next` with a single argument.\n\nSo an operator creator is any function that returns an operator function.\n\nWhile this might sound complicated, in reality it's just a bunch of fat arrows. Let's create one:\n\n```js\nimport { log } from '@zuze/pubsub/operators';\n\n// greaterThan is an operator creator - a function that returns an operator.\n\ncreateOperator((...args) => event =>)\n\n// call next with the published event if it's greater than the user supplied number\nconst greaterThan = num => next => event => event > num && next(event);\n\n// use like\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe('nums', pipe( greaterThan(5), log() ));\n\npublish('nums', 4); // no log\npublish('nums', 8); // log's 8\n\nconst multiplyBy = num => next => event => next(event*num);\n\n// use like\nsubscribe('nums', pipe( multiplyBy(4), log() ));\n\npublish('nums',4); // logs 16\n\n// chain your custom operators!\nsubscribe('nums', pipe( multiplyBy(4), greaterThan(5), log() ));\n\npublish('nums', 1); // no log\npublish('nums', 2); // logs 8\n\n\n```\n\nAsync operators are trivial:\n\n```js\nimport topic from '@zuze/pubsub/topic';\nimport { pipe, log } from '@zuze/pubsub/operators';\n\nconst { publish, subscribe } = topic();\n\n// call next with the published event IF it's greater than the user supplied number\nconst callApiOperator = apiCall => next => async event => next(await apiCall(event));\n\nsubscribe(\n    'user_ids',\n    pipe(\n        callApiOperator(\n            async id => (await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)).json()\n        ),\n        log()\n    )\n);\n\npublish('user_ids', 10);\n```\n\n\nYou can easily create operators that are simply a common reuse of other operators using `pipe` using `pipeable`. \nThis is handy if you find yourself consistently reusing operators together and is used internally to create operators as well:\n\nThe below code is taken directly from `bufferCount`:\n\n```js\nimport { pipeable, stack, filter, map } from '@zuze/pubsub/operators';\n\nconst bufferCount = (size, every) => pipeable(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n);\n```\n\nJust for fun, creating bufferCount without using `pipeable` would look like this:\n\n```js\nconst bufferCount = (size,every) => next => pipe(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n  () => next    \n);\n```\n\n### List of Operators\n\nWe tried to stay as close as possible to RxJS operating naming, considering we're not in an observable environment.\nWith that in mind, here's the list:\n\n#### `map<T,R>(mapper: (e: T) => R): R`\n\nTransforms the emitted event into a new value using a function before passing it to the next function:\n\n```js\nconst fn = pipe( map(e => e*2), log() ) )\nfn(3); // logs 6\n```\n\n#### `mapTo<R>(mapper: () => R): R`\n\nTransforms the emitted event into a new value before passing it to the next function\n\n```js\nconst fn = pipe( map('joe'), log() ) )\nfn(3); // logs 'joe'\n```\n\n#### `take<T>(num: number): T`\n\nStops calling the next function after `num`\n\n```js\nconst fn = pipe( take(2), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\nfn(3); // no log\n```\n\n#### `takeUntil<T>(promise: Promise<void>): T`\n\nCalls the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\n// 2 seconds pass\nfn(3); // no log\n```\n\n#### `startWith<T>(T | Promise<T> | () => (T | Promise<T>)): T`\n\nImmediately calls the next operator in the chain with the value:\n\n```js\n\nconst fn = pipe( filter(i => i > 2), startWith(7), log() ); // 7 is logged immediately\nfn(1); // no log\nfn(3); // logs 3\n\n\nconst fn = pipe ( filter(i => i > 2), startWith(() => new Promise(res => setTimeout(() => res(7))), log() );\n\n```\n\n#### `single<T>():T`\n\nAlias of `take(1)`\n\n#### `skip<T>(num: number): T`\n\nOnly starts calling the next function after `num` calls\n\n```js\nconst fn = pipe( skip(2), log() ) )\nfn(3); // no log\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `skipUntil<T>(promise: Promise<void>): T`\n\nPrevents calling the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // no log\nfn(3); // no log\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `tap<T>(fn: (e: T) => void): T`\n\nCalls it's function argument with the emitted event and continues calling the next function in the pipe:\n\n```js\nconst fn = pipe( tap(e => console.log(e*2)), log() ) )\nfn(3); // logs 6, then logs 3\n```\n\n#### `subscriber<T>(fn: (e: T) => void): T`\n\nAlias of `tap`\n\n#### `log<T>(): T`\n\nAlias of `tap(console.log)`\n\n#### `every<T>(num: number): T`\n\nOnly calls the subsequent function in the pipe when a modulo of `num` has been admitted.\n\n```js\nconst fn = pipe( every(2), log() ); // only proceed after every second event\nfn(3); // no log\nfn(3); // logs 3\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `count<T>(startAt?: number): [number,T]`\n\nAdds in the number of events that have been emitted when calling the next function in the chain:\n\n```js\nconst fn = pipe( count(), log() ); \nfn(3); // logs [0,3]\nfn(3); // logs [1,3]\nfn(3); // logs [2,3]\nfn(3); // logs [3,3]\n```\n\n#### `stack<T>(minSize?: number, maxSize?: number): T[]`\n\nCalls the next operator with an array of all previously emitted events. Will not call the next operator until the stack reaches `minSize` (defaults to 1). Will call the next operator with a maximum array length of `maxSize` (defaults to all).\n\n```js\nconst fn = pipe( stack(), log() ); \n\nfn(1); // logs [1]\nfn(2); // logs [1,2]\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\n\nconst fn = pipe( stack(3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\nconst fn = pipe( stack(3,2), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // logs [3,4]\nfn(5); // logs [4,5]\n\n```\n\n#### `bufferCount<T>(size?: number, every?: number): T[]`\n\nCalls the next operator when at least `size` events have been emitted with an array of `size`. If `every` is provided, will only call the next operator when the current call number%every is 0.\n\n```js\nconst fn = pipe( bufferCount(2,3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // no log\nfn(5); // no log\nfn(6); // logs [5,6]\nfn(7); // no log\n\n```\n\n#### `pairwise<T>(): T[]`\n\nCalls the next operator with an array containing the most recent emitted event (last element) and the event emitted previous to this. \n\nNote: This operator will NOT call the subsequent operator until at least 2 events have been emitted.\n\n#### `filter<T>(filterFn: (e: T) => boolean): T`\n\nThe provided filter function controls whether to calling the next operator in the pipe depending on if it returns true or false\n\n```js\nconst fn = pipe( filter(e => e > 2), log() )\nfn(1); // no log\nfn(3); // logs 3\n```\n\n#### `pluck<T,R>(...keys: string[]): R`\n\nPlucks value from the object the function was called with based on the given keys:\n\n```js\nconst fn = pipe ( pluck( 'comment', 'created_on' ), log() );\nfn({\n    comment: {\n        created_on: 1606101991,\n        content: 'hi'\n    }\n}) // logs 1606101991\n```\n\n#### `distinct<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value hasn't been previously emitted ever.\n  \n#### `distinctKey<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key hasn't been previously emitted ever.\n\n#### `distinctUntilChanged<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value is different than the previous value.\n\n#### `distinctUntilKeyChanged<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key is different than the previous value.\n\n#### `delay(by?: number)`\n\nDelays calling the next function in the pipe using `by` (milliseconds):\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `debounce(by?: number, leading?: boolean = false)`\n\nDebounces calls to the subsequent operator given using `by` (milliseconds).\nIf *leading* is true then the function will be called immediately on first invocation and subsequent calls within `by` will be ignored.\n\n#### `throttle(by?: number, leading?: boolean)`\n\nThrottles calls to the subsequent operator using `by` (milliseconds)\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `select(...selectorFunctions,resultFunc)`\n\nThis is similar, though not identical to [reselect] and really is just a combination of `map` + `distinctUntilChanged`\n\n```js\nimport state from '@zuze/pubsub/state';\nimport { pipe, select, tap } from '@zuze/pubsub/operators';\nconst { getState, setState, subscribe } = state({\n    first:3,\n    second:10\n});\n\nsubscribe(\n    pipe(\n        select(\n            ({ first }) => first,\n            ({ second }) => second,\n            ([ first, second ]) => first + second\n        ),\n        tap(console.log)\n    )\n); // logs 13\n\nsetState({third:9}); // doesn't log anything because arguments to the selector haven't changed\n```\n\n\n## Contributing\n\nPRs are welcome!\n\n## License\n\nMIT © [akmjenkins](https://github.com/akmjenkins)","readmeFilename":"README.md","homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@3.0.3","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-1HGRkCXN95q1kRfG0atWmDbYj5CJ4zEizF2s0lbw1IwUQrfxWEfv63XznTXiEMdQXTeQLy+lTa97+0b1OuDhUg==","shasum":"7a7878a8e0b1aa2abfae51d47b174304d61720f9","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.3.tgz","fileCount":44,"unpackedSize":68230,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0EdfCRA9TVsSAnZWagAAleYP/3P0nM/jKowWKIBKXGmR\n64Oo5dEq3kXVP2ScHPFMhksU4mQxMkHZlOGfHwXsrk+T0R3FCJToV77Rdh04\n1yxyZ46qiCecdXTX/pFUnU9Coolvz1J7/nVtMgFzgsuz4AwCJ92Fd87IOgSw\n9HxleWD+qGitQ0RiEEgsx0w70Y37r4b2l26IlRTGECPQT7EN8NjsXLIYhtb9\nDz1SvETIse3oIEgSCdNDND7JYiMDph5MBZ/L6oPNTMn2lY4XMAX0ZtQ75FHC\ngSDbjGiVC7BqDdAPzXF9OufgFsHPTeZYocbIc6hJT1220AUviWgyFpO8N3cs\nYmeftn7jyDZLR169SPOQ73SnQkaYTznMKhCxXgTtGvSs7srdgalFFfOUDzeM\nC223mCLzcvm9uZGqyAjm9JKqPKXLm7YFeKa3B0MlkShdrqAoKBaE1Ak/271A\n3zzqy2K/KmH4GucIYlzOsB44/qL5SRafO06/pATu45qzGOeOZJv8yRYo7cIm\nU9yzqlpTQ3b3uzGZRfxq6mXJj5wlo+1zK1nvf+zUxoR52Gks0QGKJahqPEMH\nWIdR3yFU9iQGijuKgFAH/+9HUzc8ea5q/bkUatCPMqsmKaXweWo6rLSQt6A0\nb2zFc37ihpGPJjGigT6x7DgqQSWE65oI4SpXPwaK0h1ymqHZE7BnzyLh/e45\nNzg0\r\n=bSHi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCje71WdlBBzFyqmqa09cJy4NcufIA9UY/fQI22HtFUlQIhAPgKQoEV5IasG5fMHZgq2nFMvzNyQMo9JMBYKwxKj3Li"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.3_1607485279244_0.15967576085181312"},"_hasShrinkwrap":false},"3.0.4":{"name":"@zuze/pubsub","version":"3.0.4","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"https://github.com/zuze-lab/pubsub/tree/next"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && cp -a .npmignore build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel && rollup -c","babel":"babel src -d build --copy-files --no-copy-ignored","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","babel-plugin-add-module-exports":"^1.0.4","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"_id":"@zuze/pubsub@3.0.4","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-nlROE/6+hYmhcJdRuCStLYWGHSR+WJKDRoHqzWRdtTWIr7FSMq2nrNNHplr84QCMexKfv1jLs0MkKs/99En/SQ==","shasum":"5f911fdf09378c503047a73853ce3535728685d8","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.4.tgz","fileCount":44,"unpackedSize":69260,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0MA8CRA9TVsSAnZWagAASTgP/1MvkzYqFAwbzapS3Sna\nBPB4FLFJiL+DMvlLCEg1GQfBi4ezDtXoD1/qOl1TimlUI4j0oa5OFhD1j1tv\nVWk4RFXtEN9STtqEO6kZPLTl3QYsCGSnHa6URHn4pqcSXCKypv2Yq78Tu0K/\n2w0AM1x9lQBAoU6yF1Nn021YW7k8xILolGkI1T+F9N6jP0D4NhE+Ys/wH1G0\ncHE9682j6kIWRecF8fQQM2Zpi3S7pziNCXMcAoe4SDPw94/e0UETU+RiDetA\nRSDz/Nea9D+YtjBk6NEhECGUDW63PqQTd/+6QFdG6a0JYSCi8CIx4vrFzMWo\n+Br+w9TAXVNApsLNMZYUqDIaf6M53ACeVzhFyx3VEYdWi01xGJh++Wm92fw3\nl4rqqVzDZ13yAQpg3D35wItq5uBAOX1mzGN/AENmj5z87dNDu13JroLK0LFv\nEdWxzgHPDgTrP728P0enPjLdj7NHgaucdAn0/McsitzkW2z52ZJmG8mrh3z9\nuWCX9xaBe/326gg8EETS2E2ctQTMz6Lc++0dhNo9JJtTnYBZir7XdQo0Th8b\nivwLPHyoAu6+03T2VNh9ewJ2Hb6hPBRFwaU9p8+EbeCHmAaQtPTnjqiMuXUx\n7MiKx4f0tk8d6IUcUyNimtkKNK3ygR/ClHZaYKS78/9Eyb5cC0I7JAlU+Sgz\n6y43\r\n=y8vA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCI7xBowHUmMJQH9yTUxpzoZiXC1NuKxSOcElCgL750QIhANROhSndEZKUBCklD816w8YZxrMVLTKRv61R1cXyXYJh"}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.4_1607516219450_0.11229855006844103"},"_hasShrinkwrap":false},"3.0.5":{"name":"@zuze/pubsub","version":"3.0.5","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"https://github.com/zuze-lab/pubsub/tree/next"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && cp -a .npmignore build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel && rollup -c","babel":"babel src -d build --copy-files --no-copy-ignored","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","babel-plugin-add-module-exports":"^1.0.4","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"## @zuze/pubsub\n\n[![npm version](https://img.shields.io/npm/v/@zuze/pubsub/next.svg)](https://npmjs.org/package/@zuze/pubsub/v/next)\n[![Coverage Status](https://coveralls.io/repos/github/zuze-lab/pubsub/badge.svg?branch=next)](https://coveralls.io/github/zuze-lab/pubsub?branch=next)\n[![Build Status](https://travis-ci.com/zuze-lab/pubsub.svg?branch=next)](https://travis-ci.com/zuze-lab/pubsub)\n[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/@zuze/pubsub@next)](https://bundlephobia.com/result?p=@zuze/pubsub@next)\n\n## What is this?\n\n[PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is one of the best known decoupling software architecture patterns - it allows different components to communicate with each other without knowing about each other.\n\n## What's special about this one?\n\nWell, we really like the RxJS inspired [operators](#subscribing-with-pipe-and-operators) and the [super small dependency free package size](https://bundlephobia.com/result?p=@zuze/pubsub).\n\n### Getting Started\n\nInstall it as a dependency in your JavaScript/Typescript project\n\n```bash\nnpm install @zuze/pubsub\n# or\nyarn add @zuze/pubsub\n```\n\nOr just pull it in from the browser:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { pubsub } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(console.log);\n    publish('it works!'); // logs it works! in the console\n</script>\n```\n\nThe core `pubsub` is extremely tiny and, to be honest, mostly useless. But it forms a core structure that can be extended with just a few lines to create other incredibly tiny and less-useless utilities, like a pubsub with topics:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { topic } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe('someEvent', console.log);\n    publish('someEvent', 'it works!'); // logs it works! in the console\n</script>\n```\n\nOr a super tiny state manager:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { state } = zuze;\n    const { getState, setState, subscribe } = state('joe');\n    console.log(getState()) // logs joe\n    const unsubscribe = subscribe(console.log) // logs joe\n    setState('jim'); // the above subscriber logs jim\n    unsubscribe();\n    setState('fred'); // nothing logged, we unsubscribed\n</script>\n```\n\nThe three utilities combined, built on top of each other, come in at a rather hefty (heh) **400 bytes**.\n\n\n### API\n\n- **`pubsub<T>(): EventBus<T>`**\n\nCreates an `EventBus` of type `T`\n\n```js\nimport { pubsub } from '@zuze/pubsub';\n\nconst { publish, subscribe } = pubsub<string>();\n\nconst unsub = subscribe(console.log);\npublish('joe'); // logs joe\nunsub();\npublish('fred'); // no log\n\n```\n\n- **`pubsub<T extends Topics>(): EventBus<T>`**\n\nCreate an `EventBus` of type T.\n\n```js\nimport pubsub from '@zuze/pubsub';\n\ntype Topics = {\n    user_event: {\n        first_name: string;\n        last_name: string;\n        user_id: number;\n    };\n    post: {\n        post_id: number;\n        content: string;\n    };\n    comment: {\n        comment_id: number;\n        content: string;\n        post_id: number;\n    };\n    nums: number;\n};\n\nconst { subscribe, publish } = pubsub<Topics>();\n```\n\n\n- **`publish: <R extends keyof T>(topic: R, data: T[R], sync?: boolean) => void`**\n\nBroadcasts an entity to all subscribers on a given topic:\n\n```js\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n```\n\nTake note of the optional third `sync` parameter. By default `@zuze/pubsub` broadcasts to all subscribers for a given topic **asynchronously** so as to prevent a single subscriber from potentially blocking any other subscriber. If you pass the third parameter as true, events will be broadcast **synchronously**.\n\n- **`subscribe: <R extends keyof T>(topic: R, subscriber: Subscriber<T[R]>) => Unsubscribe`**\n\nSubscribes to a topic and returns an unsubscribe function.\n\n```js\ne.g. \nconst { subscribe, publish } = pubsub<Topics>();\nconst unsub = subscribe('comment', comment => console.log('got comment',comment));\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n\n/*\noutput:\ngot comment\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n*/\n\nunsub(); // no further events will be logged\n```\n\n## Subscribing with `pipe` and Operators\n\nYou could stop here and have an great, incredibly small and flexible PubSub utility. But subscribing with a `pipe` and operators takes your functional PubSub and/or State management system to the next level. \n\n```js\nimport pubsub from '@zuze/pubsub';\nimport { pipe, filter, subscriber } from '@zuze/pubsub/operators';\n\nconst { subscribe, publish } = pubsub<Topics>();\n\nsubscribe(\n    'comment', \n    pipe(\n        filter(({ comment_id }) => comment_id === 10),\n        subscriber(({ content }) => console.log(content))\n    )\n);\n\npublish('comment', { comment_id: 9, content: 'some comment' }); // no log\npublish('comment', { comment_id: 10, content: 'bye' }); // logs 'bye'\n```\n\n### In the browser\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script src=\"https://unpkg.com/@zuze/pubsub/pipe\"></script>\n<script>\n    const { pubsub, map, subscriber, pipe } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(\n        'someEvent', \n        pipe(\n            map(r => `I said, ${r}`),\n            subscriber(output => console.log(output))\n        )\n    );\n\n    publish('someEvent','it works!'); // logs 'I said, it works!' in the console\n</script>\n```\n\nPerhaps counterintuitively, due to the way a pipe is constructed from operator functions, nothing ever \"comes out\" of it, then end result is always `undefined`. If you want to call some external function at any point in the pipe, use the [subscriber](#subscribertfn-e-t--void-t) operator (an alias of [tap](#taptfn-e-t--void-t))\n\n\n`pipe` and `operators` are ~~stolen from~~ inspired by the [RxJS](https://rxjs-dev.firebaseapp.com/guide/operators) operator API, but without the power, complexity, or sheer size (our operators and utilities weigh less than 1/10th the size) of schedulers or marble diagrams.\n\n### Using Operators\n\n### `pipe<T>(...operators: OperatorFn<T,any>[])`\n\n\nWhen using typescript, if you need to create a pipe separately from a subscription and want to stay type-safe, you can use `createPipe`:\n\n```ts\nimport { createPipe } from '@zuze/pubsub/operators';\n\n// creates a pipe whose operator functions act on SomeType\nconst pipe = createPipe<SomeType>();\nconst myPipe = pipe(...operatorFunctions);\n\n// and then later\nsomePubSub.subscribe(myPipe);\n```\n\nIf you're creating the pipe at subscription time, you can just use `pipe` directly and you'll stay typesafe\n\n```js\nimport { pipe } from '@zuze/pubsub/operators';\nsomePubSub.subscribe(pipe(...operatorFunctions))\n```\n\n\n### Creating Reusable Operators\n\nAn operator function accepts a single parameter - a [unary function](https://en.wikipedia.org/wiki/Unary_function) typically named `next` and returns a function that, after performing some operation, may or may not call `next` with a single argument.\n\nSo an operator creator is any function that returns an operator function.\n\nWhile this might sound complicated, in reality it's just a bunch of fat arrows. Let's create one:\n\n```js\nimport { log } from '@zuze/pubsub/operators';\n\n// greaterThan is an operator creator - a function that returns an operator.\n\ncreateOperator((...args) => event =>)\n\n// call next with the published event if it's greater than the user supplied number\nconst greaterThan = num => next => event => event > num && next(event);\n\n// use like\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe('nums', pipe( greaterThan(5), log() ));\n\npublish('nums', 4); // no log\npublish('nums', 8); // log's 8\n\nconst multiplyBy = num => next => event => next(event*num);\n\n// use like\nsubscribe('nums', pipe( multiplyBy(4), log() ));\n\npublish('nums',4); // logs 16\n\n// chain your custom operators!\nsubscribe('nums', pipe( multiplyBy(4), greaterThan(5), log() ));\n\npublish('nums', 1); // no log\npublish('nums', 2); // logs 8\n\n\n```\n\nAsync operators are trivial:\n\n```js\nimport topic from '@zuze/pubsub/topic';\nimport { pipe, log } from '@zuze/pubsub/operators';\n\nconst { publish, subscribe } = topic();\n\n// call next with the published event IF it's greater than the user supplied number\nconst callApiOperator = apiCall => next => async event => next(await apiCall(event));\n\nsubscribe(\n    'user_ids',\n    pipe(\n        callApiOperator(\n            async id => (await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)).json()\n        ),\n        log()\n    )\n);\n\npublish('user_ids', 10);\n```\n\n\nYou can easily create operators that are simply a common reuse of other operators using `pipe` using `pipeable`. \nThis is handy if you find yourself consistently reusing operators together and is used internally to create operators as well:\n\nThe below code is taken directly from `bufferCount`:\n\n```js\nimport { pipeable, stack, filter, map } from '@zuze/pubsub/operators';\n\nconst bufferCount = (size, every) => pipeable(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n);\n```\n\nJust for fun, creating bufferCount without using `pipeable` would look like this:\n\n```js\nconst bufferCount = (size,every) => next => pipe(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n  () => next    \n);\n```\n\n### List of Operators\n\nWe tried to stay as close as possible to RxJS operating naming, considering we're not in an observable environment.\nWith that in mind, here's the list:\n\n#### `map<T,R>(mapper: (e: T) => R): R`\n\nTransforms the emitted event into a new value using a function before passing it to the next function:\n\n```js\nconst fn = pipe( map(e => e*2), log() ) )\nfn(3); // logs 6\n```\n\n#### `mapTo<R>(mapper: () => R): R`\n\nTransforms the emitted event into a new value before passing it to the next function\n\n```js\nconst fn = pipe( map('joe'), log() ) )\nfn(3); // logs 'joe'\n```\n\n#### `take<T>(num: number): T`\n\nStops calling the next function after `num`\n\n```js\nconst fn = pipe( take(2), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\nfn(3); // no log\n```\n\n#### `takeUntil<T>(promise: Promise<void>): T`\n\nCalls the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\n// 2 seconds pass\nfn(3); // no log\n```\n\n#### `startWith<T>(T | Promise<T> | () => (T | Promise<T>)): T`\n\nImmediately calls the next operator in the chain with the value:\n\n```js\n\nconst fn = pipe( filter(i => i > 2), startWith(7), log() ); // 7 is logged immediately\nfn(1); // no log\nfn(3); // logs 3\n\n\nconst fn = pipe ( filter(i => i > 2), startWith(() => new Promise(res => setTimeout(() => res(7))), log() );\n\n```\n\n#### `single<T>():T`\n\nAlias of `take(1)`\n\n#### `skip<T>(num: number): T`\n\nOnly starts calling the next function after `num` calls\n\n```js\nconst fn = pipe( skip(2), log() ) )\nfn(3); // no log\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `skipUntil<T>(promise: Promise<void>): T`\n\nPrevents calling the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // no log\nfn(3); // no log\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `tap<T>(fn: (e: T) => void): T`\n\nCalls it's function argument with the emitted event and continues calling the next function in the pipe:\n\n```js\nconst fn = pipe( tap(e => console.log(e*2)), log() ) )\nfn(3); // logs 6, then logs 3\n```\n\n#### `subscriber<T>(fn: (e: T) => void): T`\n\nAlias of `tap`\n\n#### `log<T>(): T`\n\nAlias of `tap(console.log)`\n\n#### `every<T>(num: number): T`\n\nOnly calls the subsequent function in the pipe when a modulo of `num` has been admitted.\n\n```js\nconst fn = pipe( every(2), log() ); // only proceed after every second event\nfn(3); // no log\nfn(3); // logs 3\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `count<T>(startAt?: number): [number,T]`\n\nAdds in the number of events that have been emitted when calling the next function in the chain:\n\n```js\nconst fn = pipe( count(), log() ); \nfn(3); // logs [0,3]\nfn(3); // logs [1,3]\nfn(3); // logs [2,3]\nfn(3); // logs [3,3]\n```\n\n#### `stack<T>(minSize?: number, maxSize?: number): T[]`\n\nCalls the next operator with an array of all previously emitted events. Will not call the next operator until the stack reaches `minSize` (defaults to 1). Will call the next operator with a maximum array length of `maxSize` (defaults to all).\n\n```js\nconst fn = pipe( stack(), log() ); \n\nfn(1); // logs [1]\nfn(2); // logs [1,2]\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\n\nconst fn = pipe( stack(3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\nconst fn = pipe( stack(3,2), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // logs [3,4]\nfn(5); // logs [4,5]\n\n```\n\n#### `bufferCount<T>(size?: number, every?: number): T[]`\n\nCalls the next operator when at least `size` events have been emitted with an array of `size`. If `every` is provided, will only call the next operator when the current call number%every is 0.\n\n```js\nconst fn = pipe( bufferCount(2,3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // no log\nfn(5); // no log\nfn(6); // logs [5,6]\nfn(7); // no log\n\n```\n\n#### `pairwise<T>(): T[]`\n\nCalls the next operator with an array containing the most recent emitted event (last element) and the event emitted previous to this. \n\nNote: This operator will NOT call the subsequent operator until at least 2 events have been emitted.\n\n#### `filter<T>(filterFn: (e: T) => boolean): T`\n\nThe provided filter function controls whether to calling the next operator in the pipe depending on if it returns true or false\n\n```js\nconst fn = pipe( filter(e => e > 2), log() )\nfn(1); // no log\nfn(3); // logs 3\n```\n\n#### `pluck<T,R>(...keys: string[]): R`\n\nPlucks value from the object the function was called with based on the given keys:\n\n```js\nconst fn = pipe ( pluck( 'comment', 'created_on' ), log() );\nfn({\n    comment: {\n        created_on: 1606101991,\n        content: 'hi'\n    }\n}) // logs 1606101991\n```\n\n#### `distinct<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value hasn't been previously emitted ever.\n  \n#### `distinctKey<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key hasn't been previously emitted ever.\n\n#### `distinctUntilChanged<T>(comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value is different than the previous value.\n\n#### `distinctUntilKeyChanged<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n\nOnly calls subsequent operators if the value at the given key is different than the previous value.\n\n#### `delay(by?: number)`\n\nDelays calling the next function in the pipe using `by` (milliseconds):\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `debounce(by?: number, leading?: boolean = false)`\n\nDebounces calls to the subsequent operator given using `by` (milliseconds).\nIf *leading* is true then the function will be called immediately on first invocation and subsequent calls within `by` will be ignored.\n\n#### `throttle(by?: number, leading?: boolean)`\n\nThrottles calls to the subsequent operator using `by` (milliseconds)\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n#### `select(...selectorFunctions,resultFunc)`\n\nThis is similar, though not identical to [reselect] and really is just a combination of `map` + `distinctUntilChanged`\n\n```js\nimport state from '@zuze/pubsub/state';\nimport { pipe, select, tap } from '@zuze/pubsub/operators';\nconst { getState, setState, subscribe } = state({\n    first:3,\n    second:10\n});\n\nsubscribe(\n    pipe(\n        select(\n            ({ first }) => first,\n            ({ second }) => second,\n            ([ first, second ]) => first + second\n        ),\n        tap(console.log)\n    )\n); // logs 13\n\nsetState({third:9}); // doesn't log anything because arguments to the selector haven't changed\n```\n\n\n## Contributing\n\nPRs are welcome!\n\n## License\n\nMIT © [akmjenkins](https://github.com/akmjenkins)","readmeFilename":"README.md","_id":"@zuze/pubsub@3.0.5","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-jM4ZXAkMB4NmhUw9OuejOsclNn1CundXVHLYKx/iLy8FRAw31vBsOCX2fwSNum/OJG0hJJkwr+1lkrq2MPq2LQ==","shasum":"b0bddcfacdb44d6b1b2a65a0c8750f5f6b6c66bc","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.0.5.tgz","fileCount":44,"unpackedSize":69260,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0MCxCRA9TVsSAnZWagAAQSEP/iQOmNxGffoxaF1vF4eR\njLqDrsQPrvQo+roQ+YWcIMgLd7SQMv97UiQKPsjMruWkgGJJ26Awa155wbbR\ni74lfKPBT9/TgGW4aZ9T540zg+VCEO/ZpjThNcXgYwflPzTzURFZM5Tuj1QA\n1bmTEcPVLZ/kXEoAmWNhfctVja1rW80NfhUQ0ttFCD/k+Z9vrbf0sdT2OSY2\n40GJ/E0pjNiQW4kKv10aNDDdJbx4VTvA5K8kkLscJmiRKT2qBi2dWPFf2uLB\n4wBnZXoogQB7fMWhibfpadST1ehnLVsx+xWP1vTAmSRNp0hvRcWB+ak6XS9y\n/rubTilzwowOGr2AhJMXRBs4/xn0wWPPgsnDpxCMh+xKGugwhpt6ZidD/L9f\nYClBMuUrnFQ+XqdDPItq0kk7TU/DP9M/qrYZD49jf0HEVq6WUaYtlwP90CLv\n2piAQccbbzcEwGpjvK9pypTRSQrukEKYUev8ePUsiJ1QN7P8bAHrvFCfyEm6\nb04+woWdqgXC5x0JZW6jpoNG0icqqJt+b3mytEa0z94LaHU7sKu4OdIMVOFf\naN4157up+Tc0REN9MC4kLTR5U/NEtp9rKtsAuOluOS61PPbJgRW0Xlz96s1g\nB9ERyujpYVWnKo6xJi5kLbF3G7KVF8MaBjAX+srQBZ3T8Zp0dgTMjq7i0eLn\nu/SY\r\n=8bVR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICj7CoDuY5NxNPDja/+t0CAAXorxuib7DBY92UNvI8IRAiBywwh+COrDFtUC+rxTE4qSM6MCN7054QeLN7lE41IFhA=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.0.5_1607516336722_0.34859369698348686"},"_hasShrinkwrap":false},"2.2.3":{"name":"@zuze/pubsub","version":"2.2.3","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"esm/index.js","browser":"browser.min.js","scripts":{"dist":"yarn clean && yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && yarn pub","clean":"rimraf build","build":"rollup -c ","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"homepage":"https://github.com/zuze-lab/pubsub#readme","_id":"@zuze/pubsub@2.2.3","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-OjixuPBKGYnapbKgD4R+eofDyjWTtjemRTtNhhzwu9Ri+I2ycetfmdgfqfZYeMNFGEsI4tgeciSoe6xWgesuBA==","shasum":"2e2907bf9222a77056ef78ef17899157e405d8a9","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-2.2.3.tgz","fileCount":14,"unpackedSize":48480,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0MJRCRA9TVsSAnZWagAA38IQAJYESqwpTykITUiLKp7p\n6DssbUcL7Irmfyqiq25gkbnSStM1WV7i5n1S3lr4t/dsW2FCFR8AjYTd7K4W\nr1ywI509bodPRD7zNH3cgr0tBZqwhRcCd4T7fPaItGXDL50U1uaEQue1p9Ql\n8PG8CrJvYkfLCu5i9pcnYjPfOiCA+ST1hlgprJ0ffKnO1MgEeeFlsDSC76tk\nuuYSKUkvvxd/fdMOyEeqHNvAe1aO3QUHCCt2xHx3BccgqYrqpJsdxoGErswq\nd0CZEjIM3kUTTntEA66kN7H/7ufUxnJTmyenyETBG2q01bYY73C8Ot4KHbSa\nnfQUgeaZivzXPfrvqdJZX4/HGeRk1JZhBsirSuQ/X5ts+TDVlmpT8YMEDAmP\nmi4cF/zHw47bVC0eJLEGdglbb1EKFDg9/RNOgadJMKVZ71bKa6nWsK4bn5ye\n6eLj1U+GO4CNXZKD7gvbQTgBg0j3kCCryWYyiZsBucVvvUcZozKMqwzpxQ3K\nJ/mmZWZE4P4J876aUhHe4OwrgDNbf85WwvUq9c+Z3z7PP1Rn8tQTkjcI/zYB\nDYhP5tWCadnp/p4ehsbXEuIuw+ue/OVRINjAzl3pKtkbel4X5cPG1bbd1ex2\nc3y9rMSSkbFWFhjugi9GjEeSQGw+3Ck3WLtTeDa3t8I4puh0m2z6FW1456B6\nTjzl\r\n=ZxeJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAGEdrzxCCsfatkQ8WN1Pw9T/lqlgkvgOmXcU3gm4UE4AiB7QA+zGls0+AY6zdIrD1MckzVvdAaQAl5WASDrC7sHtw=="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_2.2.3_1607516753238_0.36748620841159485"},"_hasShrinkwrap":false},"3.1.0":{"name":"@zuze/pubsub","version":"3.1.0","author":{"name":"akmjenkins"},"license":"MIT","repository":{"type":"git","url":"https://github.com/zuze-lab/pubsub/tree/next"},"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"main":"index.js","module":"index.js","browser":"browser.min.js","scripts":{"dist":"yarn lint && yarn test && yarn build && cp -a package.json build && cp -a README.md build && cp -a .npmignore build && yarn pub","clean":"rimraf build","build":"yarn clean && yarn babel && rollup -c","babel":"babel src -d build --copy-files --no-copy-ignored","lint":"eslint src/","test:ci":"yarn test --coverage --coverageReporters=text-lcov | coveralls","test":"jest --testPathPattern=test.ts --config jest.tsconfig.js","pub":"cd build && npm publish"},"sideEffects":false,"devDependencies":{"@babel/cli":"^7.10.1","@babel/core":"^7.10.2","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.10.2","@rollup/plugin-babel":"^5.2.1","@rollup/plugin-node-resolve":"^10.0.0","@types/jest":"^25.2.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","babel-eslint":"^10.0.3","babel-jest":"^25.1.0","babel-plugin-add-module-exports":"^1.0.4","coveralls":"^3.0.9","eslint":"^6.4.0","eslint-config-prettier":"^6.3.0","eslint-plugin-import":"^2.21.1","eslint-plugin-jest":"^22.17.0","eslint-plugin-prettier":"^3.1.0","jest":"^25.1.0","prettier":"^1.18.2","reselect":"^4.0.0","rollup":"^2.15.0","rollup-plugin-bundle-size":"^1.0.3","rollup-plugin-copy":"^3.3.0","rollup-plugin-sourcemaps":"^0.6.2","rollup-plugin-terser":"^6.1.0","ts-jest":"^25.3.1","typescript":"^3.6.4"},"readme":"## @zuze/pubsub\n\n[![npm version](https://img.shields.io/npm/v/@zuze/pubsub/next.svg)](https://npmjs.org/package/@zuze/pubsub/v/next)\n[![Coverage Status](https://coveralls.io/repos/github/zuze-lab/pubsub/badge.svg?branch=next)](https://coveralls.io/github/zuze-lab/pubsub?branch=next)\n[![Build Status](https://travis-ci.com/zuze-lab/pubsub.svg?branch=next)](https://travis-ci.com/zuze-lab/pubsub)\n[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/@zuze/pubsub@next)](https://bundlephobia.com/result?p=@zuze/pubsub@next)\n\n## What is this?\n\n[PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is one of the best known decoupling software architecture patterns - it allows different components to communicate with each other without knowing about each other.\n\n## What's special about this one?\n\nWell, we really like the RxJS inspired [operators](#subscribing-with-pipe-and-operators) and the [super small dependency free package size](https://bundlephobia.com/result?p=@zuze/pubsub).\n\n### Getting Started\n\nInstall it as a dependency in your JavaScript/Typescript project\n\n```bash\nnpm install @zuze/pubsub\n# or\nyarn add @zuze/pubsub\n```\n\nOr just pull it in from the browser:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { pubsub } = zuze;\n    const { publish, subscribe } = pubsub();\n    subscribe(console.log);\n    publish('it works!'); // logs it works! in the console\n</script>\n```\n\nThe core `pubsub` is extremely tiny and, to be honest, mostly useless. But it forms a core structure that can be extended with just a few lines to create other incredibly tiny and less-useless utilities, like a pubsub with topics:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { topic } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe('someEvent', console.log);\n    publish('someEvent', 'it works!'); // logs it works! in the console\n</script>\n```\n\nOr a super tiny state manager:\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script>\n    const { state } = zuze;\n    const { getState, setState, subscribe } = state('joe');\n    console.log(getState()) // logs joe\n    const unsubscribe = subscribe(console.log) // logs joe\n    setState('jim'); // the above subscriber logs jim\n    unsubscribe();\n    setState('fred'); // nothing logged, we unsubscribed\n</script>\n```\n\nThe three utilities combined, built on top of each other, come in at a rather hefty (heh) **400 bytes**.\n\n\n### API\n\n- **`pubsub<T>(): EventBus<T>`**\n\nCreates an `EventBus` of type `T`\n\n```js\nimport { pubsub } from '@zuze/pubsub';\n\nconst { publish, subscribe } = pubsub<string>();\n\nconst unsub = subscribe(console.log);\npublish('joe'); // logs joe\nunsub();\npublish('fred'); // no log\n\n```\n\n- **`topic<T extends Topics>(): EventBus<T>`**\n\nCreate an `EventBus` of type T.\n\n```js\nimport { topic } from '@zuze/pubsub';\n\ntype Topics = {\n    user_event: {\n        first_name: string;\n        last_name: string;\n        user_id: number;\n    };\n    post: {\n        post_id: number;\n        content: string;\n    };\n    comment: {\n        comment_id: number;\n        content: string;\n        post_id: number;\n    };\n    nums: number;\n};\n\nconst { subscribe, publish } = topic<Topics>();\n\npublish( 'post', { post_id: 10, content: 'My Post!' } )\n```\n\nIn the case of `topic`, `publish` and `subscribe` are typechecked for safety:\n\n- **`publish: <R extends keyof T>(topic: R, data: T[R], sync?: boolean) => void`**\n\n\n```js\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n```\n\n- **`subscribe: <R extends keyof T>(topic: R, subscriber: Subscriber<T[R]>) => Unsubscribe`**\n\nSubscribes to a topic and returns an unsubscribe function.\n\ne.g.\n```js\nimport { topic } from '@zuze/pubsub';\nconst { subscribe, publish } = topic<Topics>();\nconst unsub = subscribe('comment', comment => console.log('got comment',comment));\npublish(\n    'comment',\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n);\n\n/*\noutput:\ngot comment\n    {\n        comment_id: 10,\n        content: 'some comment',\n        post_id: 27\n    }\n*/\n\nunsub(); // no further events will be logged\n```\n\n## Subscribing with `pipe` and Operators\n\nYou could stop here and have an great, incredibly small and flexible PubSub utility. But subscribing with a `pipe` and operators takes your functional PubSub and/or State management system to the next level. \n\n```js\nimport { topic } from '@zuze/pubsub';\nimport { pipe, filter, subscriber } from '@zuze/pubsub/operators';\n\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe(\n    'comment', \n    pipe(\n        filter(({ comment_id }) => comment_id === 10),\n        subscriber(({ content }) => console.log(content))\n    )\n);\n\npublish('comment', { comment_id: 9, content: 'some comment' }); // no log\npublish('comment', { comment_id: 10, content: 'bye' }); // logs 'bye'\n```\n\n### In the browser\n\n```html\n<script src=\"https://unpkg.com/@zuze/pubsub\"></script>\n<script src=\"https://unpkg.com/@zuze/pubsub/pipe\"></script>\n<script>\n    const { pubsub, map, subscriber, pipe } = zuze;\n    const { publish, subscribe } = topic();\n    subscribe(\n        'someEvent', \n        pipe(\n            map(r => `I said, ${r}`),\n            subscriber(output => console.log(output))\n        )\n    );\n\n    publish('someEvent','it works!'); // logs 'I said, it works!' in the console\n</script>\n```\n\nIt's worth mentioning that `pipe` and operators can be used with any of `pubsub`, `state`, or `topic` pubsub utilities.\n\n### Using Operators\n\nPerhaps counterintuitively, due to the way a pipe is constructed from operator functions, nothing ever \"comes out\" of it, then end result is always `undefined`. If you want to call some external function at any point in the pipe, use the [subscriber](#subscriber) operator (an alias of [tap](#tap))\n\n\n`pipe` and `operators` are ~~stolen from~~ inspired by the [RxJS](https://rxjs-dev.firebaseapp.com/guide/operators) operator API, but without the power, size (our operators and utilities weigh less than 1/10th the size) or complexity of things like schedulers and marble diagrams.\n\n\n### `pipe<T>(...operators: OperatorFn[])`\n\n\nWhen using typescript, if you need to create a pipe separately from a subscription and want to stay type-safe, you can use `createPipe`:\n\n```ts\nimport { createPipe } from '@zuze/pubsub/operators';\n\n// creates a pipe whose operator functions act on SomeType\nconst pipe = createPipe<SomeType>();\nconst myPipe = pipe(...operatorFunctions);\n\n// and then later\nsomePubSub.subscribe(myPipe);\n```\n\nIf you're creating the pipe at subscription time, you can just use `pipe` directly and you'll stay typesafe\n\n```js\nimport { pipe } from '@zuze/pubsub/operators';\nsomePubSub.subscribe(pipe(...operatorFunctions))\n```\n\n\n### Creating Reusable Operators\n\nAn operator function accepts a single parameter - a [unary function](https://en.wikipedia.org/wiki/Unary_function) typically named `next` and returns a function that, after performing some operation, may or may not call `next` with a single argument.\n\nSo an operator creator is any function that returns an operator function.\n\nWhile this might sound complicated, in reality it's just a bunch of fat arrows. Let's create one:\n\n```js\nimport { log } from '@zuze/pubsub/operators';\n\n// greaterThan is an operator creator - a function that returns an operator.\n\ncreateOperator((...args) => event =>)\n\n// call next with the published event if it's greater than the user supplied number\nconst greaterThan = num => next => event => event > num && next(event);\n\n// use like\nconst { subscribe, publish } = topic<Topics>();\n\nsubscribe('nums', pipe( greaterThan(5), log() ));\n\npublish('nums', 4); // no log\npublish('nums', 8); // log's 8\n\nconst multiplyBy = num => next => event => next(event*num);\n\n// use like\nsubscribe('nums', pipe( multiplyBy(4), log() ));\n\npublish('nums',4); // logs 16\n\n// chain your custom operators!\nsubscribe('nums', pipe( multiplyBy(4), greaterThan(5), log() ));\n\npublish('nums', 1); // no log\npublish('nums', 2); // logs 8\n\n\n```\n\nAsync operators are trivial:\n\n```js\nimport topic from '@zuze/pubsub/topic';\nimport { pipe, log } from '@zuze/pubsub/operators';\n\nconst { publish, subscribe } = topic();\n\n// call next with the published event IF it's greater than the user supplied number\nconst callApiOperator = apiCall => next => async event => next(await apiCall(event));\n\nsubscribe(\n    'user_ids',\n    pipe(\n        callApiOperator(\n            async id => (await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)).json()\n        ),\n        log()\n    )\n);\n\npublish('user_ids', 10);\n```\n\n\nYou can easily create operators that are simply a common reuse of other operators using `pipe` using `pipeable`. \nThis is handy if you find yourself consistently reusing operators together and is used internally to create operators as well:\n\nThe below code is taken directly from `bufferCount`:\n\n```js\nimport { pipeable, stack, filter, map } from '@zuze/pubsub/operators';\n\nconst bufferCount = (size, every) => pipeable(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n);\n```\n\nJust for fun, creating bufferCount without using `pipeable` would look like this:\n\n```js\nconst bufferCount = (size,every) => next => pipe(\n  stack(),\n  filter(\n    e => (!size || e.length >= size) && (!every || e.length % every === 0),\n  ),\n  map(e => e.slice(size * -1)),\n  () => next    \n);\n```\n\n### Testing Operators\n\nOne thing I find tricky about RxJS is testing. Again, `@zuze/pubsub` operators don't contain the power that comes with RxJS, but it also doesn't come the complexity. Testing pipe's and operators is usually easily achieved using a simple mock function:\n\n```js\nimport { pipe, tap, filter } from '@zuze/pubsub/operators';\n\ndescribe('my pipe test',() => {\n\n    it('should work',() => {\n        const spy = jest.fn();\n        const myPipe = pipe ( filter(e => e < 10), ...some more operators, tap(spy) );\n        myPipe(someValue); // call your pipe\n        expect(spy).toHaveBeenCalledWith(...); // check to see if your spy was called appropriately\n    })\n\n})\n```\n\n### List of Operators\n\nYou'll find these operators, where applicable, are mostly similar to [RxJS operators](https://rxjs-dev.firebaseapp.com/guide/operators)\n\n- [bufferCount](#bufferCount)\n- [count](#count)\n- [debounce](#debounce)\n- [delay](#api)\n- [distinct](#distinct)\n- [distinctKey](#distinctKey)\n- [distinctUntilChanged](#distinctUntilChanged)\n- [distinctUntilKeyChanged](#distinctUntilKeyChanged)\n- [every](#every)\n- [filter](#filter)\n- [log](#log)\n- [map](#map)\n- [mapTo](#mapTo)\n- [pairwise](#pairwise)\n- [pluck](#pluck)\n- [select](#select)\n- [single](#single)\n- [skip](#skip)\n- [skipUntil](#skipUntil)\n- [skipWhile](#skipWhile)\n- [stack](#stack)\n- [startWith](#startWith)\n- [subscriber](#subscriber)\n- [take](#take)\n- [takeUntil](#takeUntil)\n- [takeWhile](#takeWhile)\n- [tap](#tap)\n- [throttle](#throttle)\n\n#### `bufferCount<T>(size?: number, every?: number): T[]`\n<a name=\"bufferCount\"></a>\n\nCalls the next operator when at least `size` events have been emitted with an array of `size`. If `every` is provided, will only call the next operator when the current call number%every is 0.\n\n```js\nconst fn = pipe( bufferCount(2,3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // no log\nfn(5); // no log\nfn(6); // logs [5,6]\nfn(7); // no log\n\n```\n\n#### `count<T>(startAt?: number): [number,T]`\n<a name=\"count\"></a>\n\nAdds in the number of events that have been emitted when calling the next function in the chain:\n\n```js\nconst fn = pipe( count(), log() ); \nfn(3); // logs [0,3]\nfn(3); // logs [1,3]\nfn(3); // logs [2,3]\nfn(3); // logs [3,3]\n```\n\n#### `debounce(by?: number, leading?: boolean = false)`\n\nDebounces calls to the subsequent operator given using `by` (milliseconds).\nIf *leading* is true then the function will be called immediately on first invocation and subsequent calls within `by` will be ignored.\n\n```js\nconst fn = pipe( debounce(100), log() );\nfn(3); // after 100ms, logs 3\n\nfn(3);\nfn(3);\nfn(3);\nfn(3); // after 100ms, logs 3, just one time\n\n\n\nconst fn2 = pipe( debounce(100,true), log() )\nfn(3); // logs three immediately\nfn(3);\nfn(3);\nfn(3);  // doesn't log again\n```\n\n#### `delay(by?: number)`\n<a name=\"delay\"></a>\n\nDelays calling the next function in the pipe using `by` (milliseconds):\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3);\nfn(3);\nfn(3);\nfn(3);\n\n// logs \"3\" 4 times, 100ms after each invocation\n```\n\n#### `distinct<T>(comparator?: (a: T, b: T) => boolean): R`\n<a name=\"distinct\"></a>\n\nOnly calls subsequent operators if the value hasn't been previously emitted ever.\n\n```js\nconst fn = pipe (distinct(),log());\n\nfn(3); // logs 3\nfn(4); // logs 4\nfn(3); // doesn't log, 3 is not distinct\n```\n  \n#### `distinctKey<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n<a name=\"distinctKey\"></a>\n\nOnly calls subsequent operators if the value at the given key hasn't been previously emitted ever.\n\n```js\nconst fn = pipe (distinctKey('post_id'),log());\n\nfn({ post_id: 10 }); // logs { post_id: 10 }\nfn({ post_id: 9 }); // logs { post_id: 10 }\nfn({ post_id: 10 }); // doesn't log, value at post_id is not distinct\n```\n\n#### `distinctUntilChanged<T>(comparator?: (a: T, b: T) => boolean): R`\n<a name=\"distinctUntilChanged\"></a>\n\nOnly calls subsequent operators if the value is different than the previous value.\n\n```js\nconst fn = pipe (distinctUntilChanged(),log());\n\nfn(3); // logs 3\nfn(3); // doesn't log, 3 is same as previous\nfn(4); // logs 4\n```\n\n#### `distinctUntilKeyChanged<T>(key: string, comparator?: (a: T, b: T) => boolean): R`\n<a name=\"distinctUntilKeyChanged\"></a>\n\nOnly calls subsequent operators if the value at the given key is different than the previous value.\n\n```js\nconst fn = pipe (distinctUntilKeyChanged('post_id'),log());\n\nfn({ post_id: 10 }); // logs { post_id: 10 }\nfn({ post_id: 10 }); // logs { post_id: 10 }\nfn({ post_id: 9 }); // logs { post_id: 9}\n```\n\n#### `every<T>(num: number): T`\n<a name=\"every\"></a>\n\nOnly calls the subsequent function in the pipe when a modulo of `num` has been admitted.\n\n```js\nconst fn = pipe( every(2), log() ); // only proceed after every second event\nfn(3); // no log\nfn(3); // logs 3\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `filter<T>(filterFn: (e: T) => boolean): T`\n<a name=\"filter\"></a>\n\nThe provided filter function controls whether to calling the next operator in the pipe depending on if it returns true or false\nNote: This operator is used internally to create a lot of the other operators which provide filtering functionality\n\n```js\nconst fn = pipe( filter(e => e > 2), log() )\nfn(1); // no log\nfn(3); // logs 3\n```\n\n#### `log<T>(): T`\n<a name=\"log\"></a>\n\nAlias of [`tap(console.log)`](#tap)\n\n#### `map<T,R>(mapper: (e: T) => R): R`\n<a name=\"map\"></a>\n\nTransforms the emitted event into a new value **using a function** before passing it to the next function:\n\n```js\nconst fn = pipe( map(e => e*2), log() ) )\nfn(3); // logs 6\n```\n\nNote: If the function provided to `map` returns a promise it will wait for the promise to resulve return the resolved value of the promise to the next operator.\n\n#### `mapTo<R>(value: R): R`\n<a name=\"mapTo\"></a>\n\nTransforms the emitted event into a new value before passing it to the next function\n\n```js\nconst fn = pipe( map('joe'), log() ) )\nfn(3); // logs 'joe'\n```\n\n#### `pairwise<T>(): T[]`\n<a name=\"pairwise\"></a>\n\nCalls the next operator with an array containing the most recent emitted event (last element) and the event emitted previous to this. \n\nNote: This operator will NOT call the subsequent operator until at least 2 events have been emitted.\n\n```js\nconst fn = pipe( pairwise(), log() );\nfn(3); // no log\nfn(4); // logs [3,4]\n```\n\n#### `pluck<T,R>(...keys: string[]): R`\n<a name=\"pluck\"></a>\n\nPlucks value from the object the function was called with based on the given keys:\n\n```js\nconst fn = pipe ( pluck( 'comment', 'created_on' ), log() );\nfn({\n    comment: {\n        created_on: 1606101991,\n        content: 'hi'\n    }\n}) // logs 1606101991\n```\n\n#### `select(...selectorFunctions,resultFunc)`\n\nConvenience operator which is just a combination of [`map`](#map) + [`distinctUntilChanged`](#distinctUntilChanged)\nInspired by [`reselect`](https://github.com/reduxjs/reselect)\n\n```js\nimport state from '@zuze/pubsub/state';\nimport { pipe, select, tap } from '@zuze/pubsub/operators';\nconst { getState, setState, subscribe } = state({\n    first:3,\n    second:10\n});\n\nsubscribe(\n    pipe(\n        select(\n            ({ first }) => first,\n            ({ second }) => second,\n            ([ first, second ]) => first + second\n        ),\n        tap(console.log)\n    )\n); // logs 13\n\nsetState({third:9}); // doesn't log anything because arguments to the selector haven't changed\n```\n\n#### `single<T>():T`\n<a name=\"take\"></a>\n\nAlias of [`take(1)`](#take)\n\n#### `skip<T>(num: number): T`\n<a name=\"skip\"></a>\n\nOnly starts calling the next function after `num` calls\n\n```js\nconst fn = pipe( skip(2), log() ) )\nfn(3); // no log\nfn(3); // no log\nfn(3); // logs 3\n```\n\n#### `skipUntil<T>(promise: Promise<void>): T`\n<a name=\"skipUntil\"></a>\n\nPrevents calling the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( skipUntil(when), log() ) )\nfn(3); // no log\nfn(3); // no log\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `skipWhile<T>(getValue: () => boolean): T`\n<a name=\"skipWhile\"></a>\n\nPrevents calling the next function if the getter returns true.\n\n```js\nlet someValue = true;\nconst when = () => someValue;\nconst fn = pipe( skipWhile(when), log() ) )\nfn(3); // no log\nfn(3); // no log\nsomeValue = true;\n// 2 seconds pass\nfn(3); // logs 3\n```\n\n#### `stack<T>(minSize?: number, maxSize?: number): T[]`\n<a name=\"stack\"></a>\n\nCalls the next operator with an array of previously emitted events. Will not call the next operator until the stack reaches `minSize` (defaults to 1). Will call the next operator with a maximum array length of `maxSize` (defaults to all).\n\nRelated: [`bufferCount`](#bufferCount)\n\n```js\nconst fn = pipe( stack(), log() ); \n\nfn(1); // logs [1]\nfn(2); // logs [1,2]\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\n\nconst fn = pipe( stack(3), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [1,2,3]\nfn(4); // logs [1,2,3,4]\n\nconst fn = pipe( stack(3,2), log() ); \n\nfn(1); // no log\nfn(2); // no log\nfn(3); // logs [2,3]\nfn(4); // logs [3,4]\nfn(5); // logs [4,5]\n\n```\n\n#### `startWith<T>(T | Promise<T> | () => (T | Promise<T>)): T`\n<a name=\"startWith\"></a>\n\nImmediately calls the next operator in the chain with the value (or resolved value, in the case of a Promise)\n\n```js\n\nconst fn = pipe( filter(i => i > 2), startWith(7), log() ); // 7 is logged immediately\nfn(1); // no log\nfn(3); // logs 3\n\n\nconst fn = pipe ( filter(i => i > 2), startWith(() => new Promise(res => setTimeout(() => res(7))), log() );\n\n```\n\n#### `subscriber<T>(fn: (e: T) => void): T`\n<a name=\"subscriber\"></a>\n\nAlias of [`tap`](#tap)\n\n\n#### `take<T>(num: number): T`\n<a name=\"take\"></a>\n\nStops calling the next function after `num`\n\n```js\nconst fn = pipe( take(2), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\nfn(3); // no log\n```\n\n#### `takeUntil<T>(promise: Promise<void>): T`\n<a name=\"takeUntil\"></a>\n\nCalls the next function until the provided promise resolved\n\n```js\nconst when = new Promise(res => setTimeout(res,2000));\nconst fn = pipe( takeUntil(when), log() ) )\nfn(3); // logs 3\nfn(3); // logs 3\n// 2 seconds pass\nfn(3); // no log\n```\n\n#### `takeWhile<T>(getValue: () => boolean): T`\n<a name=\"takeWhile\"></a>\n\nPrevents calling the next function if the getter returns false.\n\n\n```js\nlet someValue = true;\nconst when = () => someValue;\nconst fn = pipe( skipWhile(when), log() ) )\nfn(3); // no log\nfn(3); // no log\nsomeValue = true;\n// 2 seconds pass\nfn(3); // logs 3\n```\n\nNote: A keen observer will notice that takeWhile is an alias for [filter](#filter).\n\n#### `tap<T>(fn: (e: T) => void): T`\n<a name=\"tap\"></a>\n\nCalls it's function argument with the emitted event and continues calling the next function in the pipe:\n\n```js\nconst fn = pipe( tap(e => console.log(e*2)), log() ) )\nfn(3); // logs 6, then logs 3\n```\n\n\n#### `throttle(by?: number, leading?: boolean)`\n<a name=\"throttle\"></a>\n\nThrottles calls to the subsequent operator using `by` (milliseconds)\n\n```js\nconst fn = pipe( delay(100), log() ); \nfn(3); // asynchronous logs 3, 100 ms after emitted\n```\n\n\n## Contributing\n\nPRs are welcome!\n\n## License\n\nMIT © [akmjenkins](https://github.com/akmjenkins)","readmeFilename":"README.md","_id":"@zuze/pubsub@3.1.0","_nodeVersion":"14.4.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Ckyrnr7agR6ekSisdtz8EuMnUnN0j7KpP4ZZc8aDeJZFPnw2BAquXe73M8HPTdtBq12kglR+P4qvD8sjQu+XDQ==","shasum":"92c675bda5be84d660dae6f9096aabd54297b3bf","tarball":"https://registry.npmjs.org/@zuze/pubsub/-/pubsub-3.1.0.tgz","fileCount":47,"unpackedSize":80336,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf14McCRA9TVsSAnZWagAAT14P/3YqYoH0Cz3N6V5CnZbL\nYwL7oNrhz8XU5xPRAplUyqk2g7L6EbVZ1PEPQmOLrXUiZhVgi9vz1N6hMTnF\n0BIhLiH/iOzAY5+Irq+MmCksXR20Pf2OyLEGecH/w5353kov7bmYpAzQoWEe\nBIZI4UWnWEzE19tKD7oh/HR69NXQRuEW6XK0D+5xuy5K29AP4qwlp+zZVIZ2\n6xBlUbMSw0G9IxtqAfpw6TMmG0qW9XDdqrXqRoKii89ymInkgy9Uxuij1i4S\nqPF2c1TEEANiPERtaYibBzMwsfZLKlnN0LLECGEgg/h4osz1vro/OHRhRi+L\nIw7u1njwAluvDi0tnEkdltperoOosQDNiVCShduAdYtdjvQiQXiI7K+xr9oJ\nCQ90HIQrTWDE/vzfGQbKmK+VI0db0gLPephuEAF8/7stDWArqxqEnQhJ40wl\nCNUdDj3YY3UCzRRkQY1iVvubkyyEkM5Csou6iE+SV8Nz5cwRZzFj9M/DtjEw\ntHgF2uI7csRDFavwwH8tDDp8M/SjPVbcOBPgkrN6NWejWxDiVpPAufGhtohS\nlZM7RseUUlSmnARguPnuiFspJvPF4m847EY5pCpRbCa0ATQufvTvXoO4rNSE\n5xMEz514BOeFfV0CubMDZgtgKNUhsQLDDb9X3vkQEGNIx5EpJi0KkOfmVfh0\nrk6m\r\n=YoaP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBGee66nHm8K7vftFsJGlmtwIALFYgp5Z22aCc4bpYEoAiEAy7q3Uyv0fGrGxjzHrVyKr0reTjv5f4qOXxbJvzzdOPc="}]},"_npmUser":{"name":"zuze","email":"akmjenkins+zuze@gmail.com"},"directories":{},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pubsub_3.1.0_1607959323967_0.19525429312730758"},"_hasShrinkwrap":false}},"time":{"created":"2020-11-21T05:06:38.976Z","1.0.0":"2020-11-21T05:06:39.214Z","modified":"2022-04-11T12:12:33.983Z","2.0.0":"2020-11-23T03:36:26.197Z","2.0.1":"2020-11-23T15:01:50.217Z","2.0.2":"2020-11-24T00:56:36.976Z","2.0.3":"2020-11-24T00:59:52.040Z","2.1.0":"2020-11-26T01:03:50.891Z","2.1.1":"2020-11-26T01:44:32.555Z","2.1.2":"2020-11-26T01:48:27.037Z","2.1.3":"2020-11-26T02:00:01.402Z","2.1.4":"2020-11-26T02:05:48.186Z","2.1.5":"2020-11-26T02:19:56.349Z","2.1.6":"2020-11-27T15:32:03.988Z","2.1.7":"2020-11-27T16:00:10.418Z","2.1.8":"2020-11-27T16:34:36.284Z","2.2.0":"2020-11-28T02:36:44.700Z","2.2.1":"2020-11-28T02:39:48.101Z","3.0.0":"2020-12-09T03:16:56.723Z","2.2.2":"2020-12-09T03:20:30.500Z","3.0.1":"2020-12-09T03:25:49.439Z","3.0.2":"2020-12-09T03:26:40.149Z","3.0.3":"2020-12-09T03:41:19.358Z","3.0.4":"2020-12-09T12:16:59.637Z","3.0.5":"2020-12-09T12:18:56.948Z","2.2.3":"2020-12-09T12:25:53.382Z","3.1.0":"2020-12-14T15:22:04.103Z"},"maintainers":[{"name":"zuze","email":"akmjenkins+zuze@gmail.com"}],"description":"A functional minimalist pubsub implementation with utilities","keywords":["event","eventbus","pubsub","eventemitter","publish/subscribe","functional","pipe","operators"],"repository":{"type":"git","url":"git+https://github.com/zuze-lab/pubsub.git"},"author":{"name":"akmjenkins"},"bugs":{"url":"https://github.com/zuze-lab/pubsub","email":"akmjenkins@gmail.com"},"license":"MIT","readme":"","readmeFilename":"","homepage":"https://github.com/zuze-lab/pubsub#readme"}