{"_id":"typestately","_rev":"30-7b3d15697942ee2f8585e212b4ccef9a","name":"typestately","dist-tags":{"latest":"5.1.1","next":"5.0.0"},"versions":{"1.0.1":{"name":"typestately","version":"1.0.1","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","test":"jest"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","shallowequal":"^1.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"b6a7a59d406b9f27ac36c086364a2734d96c118b","_id":"typestately@1.0.1","_npmVersion":"5.6.0","_nodeVersion":"8.11.2","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-08xXQPkQ1T9ClVIFXk0V4bgZYJhxrH2ZK57WccxnnwHL3s+e8PQ3V/S0x9+3Onr+B2e2/sfqIwSiNBKVNoKmUg==","shasum":"1247539ed80b94bbc82e075c6e2af3696116ed21","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.0.1.tgz","fileCount":76,"unpackedSize":212885,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbTaUZCRA9TVsSAnZWagAAW1UQAIwJ1Rl2lJr5THhCWlpR\n5Psz4B63oSIOY7ZIRKIjwdZmwNCZm5qeCbpSGg8Egr6rmPEcm9hGA5y1rs6a\na747ahFoc5LXgEk9Co8mfh4PC+HAor4DbTrCZLBEZ/sK6IZu6SiZmrkLKD92\nQdYHcXGH8NkHGCHQrE4+urE/QsAnkYJJkxDSyv3K+Wz8C9a4TKt13K0akNF2\n9mQtSWTRQwnOgn4SV20qKIKF+FYFvQRBMkMJnYPtSuqWcBbCLWWmwZAz/G2e\n0+CPCYvRxFFbpq1j+H+BKbQDu9uBLwn7WYcBe9en5Bq47dF+rhrCubCle5ey\nXdUGLUIINkzmy5NLwr0ly8292H76/qXqHPThJDQlbLz3e503NdKaTgZOLu5k\nmodSp5wHzfVbNN7h5yiUa3VYg/hhZgydWuYbZOPnlvnPCWlIiqVHRsuIbktO\ns84etceHT7CGKvsBLPk+Tcm1CvL1j8SMQKPTgcLCZbi4zTZ2TLaLq+bgRf/X\nCwsgs2DWrqTn8Oc8hvoA/X6HW5zt26LdXLOTpRC/+B0117C37J2DKwRhgxVM\niLM1FaizVOFOUX8zcyB7x8nh5cpiWxdDUlJ+0oVUa3VkP2fhfyl6F7c8ug9b\nRqPbLJTnyEbT/Gd5wrulrP1wT3hmTA1KOSVIYFV5dsVydZfE1J+eXAboM3A3\nZKaQ\r\n=Ovuk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDdReDkNsSw4j3dILm83zPcTI/T+4D/KeM0iar3cHGbsQIhAJ1CxsGRNlkcrW71upVHV4NFa+B6Png9HPc+P2kT5gXq"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.0.1_1531815193432_0.9170446334302871"},"_hasShrinkwrap":false},"1.0.2":{"name":"typestately","version":"1.0.2","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","test":"jest"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","shallowequal":"^1.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"980a558fd2b6b1a5df02a14369b1a1975a144345","_id":"typestately@1.0.2","_npmVersion":"5.6.0","_nodeVersion":"8.11.2","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-b/hy8pJF8Zz6wGRhxTAs6j95GqJekSfs0cta2a84qRlhIVxdaWov2M5GbnSZjnpg3UI2XCKZjAYGUHZSTjAKnQ==","shasum":"6d59d9692870d6cda79a08b4eb96b18182e5ec3d","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.0.2.tgz","fileCount":77,"unpackedSize":212910,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbTai/CRA9TVsSAnZWagAA8x4P/0Ho47bE+1YESmZbnyrV\nl+oL78Fs1LxbeFHPW7DFzjdKR6axWs1rWGrJ8mS/xkzabN0EmVeCF/9TRsl5\nrJT8vESxgpZtDfWH9xkA8QEd+BPf7GInYuWfeksaG0I4/SzZA82odPUTmXjA\nImwchavj7IR2Q125zU/z728o7GBtGivNbqQ9eQaVxgxnajqjbY9LDLmtBLlt\nBY+lH92v0Rgf/sq0801VW3PVTmjkHxZoe2+8dCuzi/LuJPqEzO/sOWNohAZY\ndoRATAfvPgRYBs2Ks4fEkDue+b/TV8epMXs754LwrVfQq80GVqox9ii27J7s\nUVbupkelQLOIEBt7a7v4mo4R38ra5WgrT3nfz8k6qqQaVY9yNS54eZhrw3Rj\n+npnXsR15ox/Jgg2z6ulXzCmbZ4FgQ9bFvmMyH1MAvQ2mqFP2ncNE4Cil6R5\nwOQaL1qv/UAkHwJ0Xzp28xOz6KGWX9AvHCfTuDL2COPmFGPpHd6BYjTVXmh5\nX/IIGxevX5xAW0+AalHJbAGpUeSr8H9Z4GcE81V9nwL5F1IT2PeKPPIqJd27\n8cqFvP/bx8wFXifE/Cr/Odn+wp2bQLhCY2ZXLgFz6CV45FrvGzbGtg7h/bYU\nb8tLS6SwwH14rPJ7yAjOSWXrWI+PgyMiT9JhgkkA2B0m5phAe2sORbOpcD90\n83v/\r\n=pWrT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF9Q3B6I5H+Dc934f3ayustThuJDVntYs4R/lvFq43zTAiBNB6SP6W4vwdsSmfgSxYtmW72qUDEOOXMT5mS4ajOXZw=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.0.2_1531816127429_0.27104107270403954"},"_hasShrinkwrap":false},"1.0.3":{"name":"typestately","version":"1.0.3","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","test":"jest"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","shallowequal":"^1.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"aefa452b9ddaaa98891aa1020cc15c74efdf7efd","_id":"typestately@1.0.3","_npmVersion":"5.6.0","_nodeVersion":"8.11.2","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-ptWFQRVflFr78X0+8nWxycgL+GdCLE6Wy0AP2nhW0OMamDSoshnDdXgsZ4CTHzN+YatVPCSwA5qS4wfpe37peQ==","shasum":"5f830e89db5cda8791c7bf0c8ee8230651d4baaa","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.0.3.tgz","fileCount":77,"unpackedSize":212666,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbTdFSCRA9TVsSAnZWagAA0SIQAJtolnRTLtqQ7zku4yZ1\nJBa8i3bMPQdkC6ZPfRJhtMLmIycXtege2xOhw0ZFCncV/lUP2c5jScCblFNj\ntmzh8Cwo4Y1iHr0ekRtrtzij5KxSxJlw3OoDIUn6EAzsj0HQ09RvFrAC2PYm\n/0Zo0g1v+GPWqcGyJcPCQgVOVCNOjLqNZnQwvsfZ75oiu5crHda3Cx7PKmm9\nPit11jHh5WX6XCW6rUh/5NzbXbKUq4yHCw0eHHrh9B3LdsVLhMKVUPhdR/WA\n1S7/Rk6It17TCa5boM0MaMVaooXvCAwvtqNayvO3I/FS5nulq8C6UNnxqQks\nT0gKMx+EVFNB91y+qj3qUqzDILxqB1agl5gijN9ghaBOWO1b6e6vEaXoG+V1\nsi+JwyzgAhcb9HBlWiZcr8kNxpL70QiEICEtuKB7qk7S/9WD+dj9g0WQEDnv\nosp0IBCYOfLgfjyD+i2XGE8MJxE3CBvfLNL+1ei1CnNq6YmJsssysyRATnuz\nS51ydgPP3Wa17dmYiyizpCK7DBxvSqi+FJ63T4KUDVT7GEKGcAfKwGbE9zAt\nqOkKA00GjLYM7hZ2yuMr0ydAdI40ZtSPIWcxCrxLo/KJn7MA0lJMIQHZFGHq\nzgwljQkjq0QaG2knEeASn4Fd+I1Ypze+YDew1S2YVhiXnWxaHG8p5IBSX92b\nOmQb\r\n=NIHi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDAWpk/uHVRUGK/ASI8JGy9LNZ5zw9F2QAmmnB6iLw4BAiATlR/GW/L9OKW2ReO28xjYKtazQFOBc4d6ltLnCdZhkw=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.0.3_1531826514754_0.8247031845259427"},"_hasShrinkwrap":false},"1.1.0":{"name":"typestately","version":"1.1.0","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --watch","test":"jest"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","shallowequal":"^1.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"872c4847d03c98ae0fa9541e602664bcb9d13a07","_id":"typestately@1.1.0","_npmVersion":"5.6.0","_nodeVersion":"8.11.2","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-LK+2ebmDddSrg/YcmT7qOoQtHE4qDU32dln2iKwagZQMNvQhXRNapkz6fjwicIvLuQ49UZxQ1ew4dowjfcVGwA==","shasum":"50bc6d78c3bf803584ac21b89548d58dd0868dc9","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.1.0.tgz","fileCount":81,"unpackedSize":216550,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbVMJtCRA9TVsSAnZWagAAT3AP/2/PyZ5IiC9rwWRubgsy\n5qHSWYpUlAdd3+y6hfNfqL0SGhTXM5YSDoQdfBoIHKlLNPh1gz1NdjHiXYUK\ng8ldYW9vDgLwZi0/fwBEw2LUB2HeZH/bOaP1PdCVyEs6Bobi+Lpz/sge4GoE\nVTilE/0ljl/6FiexI/LJBQUCNTGUYUjNCYj8bFfsoFgJVuoVTIRxDmsjV5XC\n9a/3TOqKvadOU5928uqZNav8whxVYIDzXWllxh+ib84rC1J6R/sl0oRg8yJp\nMBUPpkyeb6nesKfDUUOJY4oHB9MEAv6un+a/xEz5Y55BYkzL2rpIXyAT9ucS\nmACShYuEChWK6KDRRFvqynjhxPnf+j9icHtc+/fnxugV8aefz16j3GRJrKxy\nSLdciadbBQ/F8ZSKuaG93yOKXa7J34AqmkIhtqI8eagA3d8AEzhuMK2lIICF\nDgtK/5NyTzX1MLlap29PVJgZ6cLIGbxvVaLQk/zHVd1bwpFyKmmMMUZsbKGb\n8kSebmAh1lkCG//AecgWBuqeb4/twDrlxTM7tMecdUcv0hs1DO4/mQBppxTg\ndrZrQWqRDhbF5LWEZ0sL3mFZQ6rPG64RswHzzEDRPyYRt9kOOsMXm2xIzmiJ\nxmpYfchYmdEK4p4QuiuzMo3c3HeQj2fRHYXKjzHJP1JD9puLbOhSwRByHYki\nOziG\r\n=1tvS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCDnoxqKaugjWdMAkox9cVz+i3ssZBpirX84j7J2NoDawIhAOX8bHvJHvWOYF5vDcxcdsTRUFLVtEjOUjsBCZ/A++Hc"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.1.0_1532281453024_0.987409525511048"},"_hasShrinkwrap":false},"1.2.0":{"name":"typestately","version":"1.2.0","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","shallowequal":"^1.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"2170509b4c99b633f13a7552192f5ec287fc97d4","_id":"typestately@1.2.0","_npmVersion":"5.3.0","_nodeVersion":"8.3.0","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-RP3RAqxyLml3ouZcGQ/e0f+sngIc8LLc5DME/61gOpBrhw1i/b2J9AwFCc3BiycQkgfZgxjioExOZfLId+IxCg==","shasum":"830356de6bb2ec94ddca3fcc17bbe2cf79383edd","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.2.0.tgz","fileCount":82,"unpackedSize":220941,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbW1qhCRA9TVsSAnZWagAAxd8P/13RC3UvEjd2ErDHxdNz\nGQdYCVm9denbD7HUCzc0rQG78fN0jAYGZ6uOpLxu5nMyvTtGFZDsqQyTwvOo\n1Fn3wUtLefgUFCvORT0EgA+mwdXLzHruGpMKuXDbcpYzI/p92p8nEIW+sDtE\nra2IJEJ2P+oB9PPYFS//48+N3Id1DXvqn6uAWo4FxIK+Fq22bTATf0ofCj+2\nhf/fyVzaVfDK57PPIrB885ku9BmGa5BYStpYphEJoOtpwQXqq0ixtBuiMw8W\nxP9+5vWPRD4eHa/HsenA+LEUa9ug8+hKKzqmj/zFgUfxV8QnwxuOqM/m2W2Q\nsoWFk2aoiI57LRwyL0v3HShEE/yw05wca9KtcF6bdR1mHdvwwIuAYqINzxav\nhbOj7dh/e0YzGEAOJPEipEl1Jr/D/sgbIu1t4qL5f72XZSHPVzbxEqZq97y8\nWNBJ1ebTv1HGUzFRg0bf3cXuo8a6swCX1QHT9bxTjC/jdDCGEOtXwuPkhyUT\nrNDdbgF+RUCOITSaPV3hlo4NU6HL0Io/ouKTU8Ztr+aXFLV1SqND2SkX6h49\nMemarhoPBrN/l0u6mqy9tnoDC4vIW8oYW9uRInONllKBVzNNjWn5Qt8pvmiN\n44W2Og3eSi00wpXJSl/C/pVZcmgDSjumamoSOMhUASDagidVDPPeKfsI7iTM\ngU9s\r\n=28zM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLoMN1gxvaqw6KakDke6F5y5vnMrTn/ySpihTQ+IUpjAIhAIE0QqRIIEySXdxBDJmlIXRtgGyYk4jDn0692J+mvRci"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.2.0_1532713633028_0.2979762834141366"},"_hasShrinkwrap":false},"1.2.1":{"name":"typestately","version":"1.2.1","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"9dc20e0a42bce414cbc62efcc7ff997a57a2fa67","_id":"typestately@1.2.1","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-eaTJF7KwM54jAPkHHMj6CAq5U4H8hv7BaeaMC1ry8HevnMImX2v2w3xOpdCYqQa9Gt04vXhUnhbOZrbHgZ/6wQ==","shasum":"aa59ca3170336ac7bb73d1357fa8445cddb8445c","tarball":"https://registry.npmjs.org/typestately/-/typestately-1.2.1.tgz","fileCount":81,"unpackedSize":220642,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbgCAbCRA9TVsSAnZWagAAl3MP/i/bd/mKKcHjYkL1kqVu\nt3NHDF7M78NAnEA6l4yu4zJ0NNWN3T6G9M6L5ImjCkR+ylBmoEMqCuz9B3q9\nh1LUmN0xOUnohA3gkuxpIBtHdfWeGQVCa6mrbdXV3o8KUVKYET2moBPrmTnm\n1ksraIw3M5HbwFYthdrB17KwC4uMOixFjLUeIXTIl1nyK48CYWHaaL2Fh28O\n+ZbuR7CO2kk16ep0/S88i6eckykt0Zi7nNalSSAVCX7+s7E0kTs3JBvNvQLT\n8xEovHQoMuOFGqSpA0IJpzq4QkT0nRmNbl1Nb9NvP6YSyhX92aUuMem3OS2m\nA4eAcEXiWnDFtPybdyu5TG1h04WiWGbI1ISjKhmSOOTxXejyZrw85XNH4Auv\nAVkOFW4Em/wISIDyrtKjOuGFenxw4NAaPWvTivd+y4IZ4O/wo3UWZ/nZhbnu\nz/e+MupCI+m/IF96NxsXHkEMWQdOy1aVD3Z5nl1jD7a44ON6Jt22hCU04NIR\nk0HlC7oSWyoO+s53UhZakFZYm7zbhZZkMg7KcDNWEYhQ+GyiEEKD4p+mNti3\nA07VulNH1oZptMgcjyvoh9AgCXVf0sTnsqHt72JQwU6qP7sdMOlFzvV02AuK\n4ZkLMKSs0ss28uBOJLSi3VuhjMbkgFO1UbDNMw9VD+Pe7h1cvlGyLKo3pjwA\n2aKc\r\n=nX5U\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEB7qcQbkb+LGk6pnqgpsddEWvZsUecJsJrCmFLRjYgCAiBNEb/YvrXjHDlRicRUMYObfgqPU5IqNIvZ2adGUSY/gg=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_1.2.1_1535123482933_0.05657864426377546"},"_hasShrinkwrap":false},"2.0.0":{"name":"typestately","version":"2.0.0","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","gitHead":"db0072727778b9767d85b157d9166a664e357dd2","_id":"typestately@2.0.0","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-BoSduMELP6Q3cfefYHL90hdL2Idjj0yoIGmqjskuIc6zXXsraSQXHrb47f8MZMgQW7ktH8gQttSSP+GD6kCFtw==","shasum":"05b6b499ee05480518b62d7245ab759ea2c4ac00","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.0.0.tgz","fileCount":85,"unpackedSize":221528,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbgpWPCRA9TVsSAnZWagAA7YoP/R3dsrkXOcUypJ5bZh/u\nO5eTLMygmNueyJFDW4PoJeGpGZIeW6ZaKfg7C9Lk7sM85NNqvwaG1WobJq+0\n9MD358d/QBtR1wemVfDavyOFSsNE9TZqYAPn8yJb6lju5eOXbNv9mN18CQGF\nprWpVVG5iR4UZrsJme7XESH2BNGndJJf+dMrK9c1O5bFBFExxRh/jgeQHPS9\nh2P4rcbCZ8VhmH+DYO+CMvQJW3s0xGlkfDbqg/fP8vN2FmHIud1JMfXFu7OS\ncoWdiZg78JLzzsgYQ6yuw0XWH/iD8SblS4EKtu7fjAsAjFwv+I1iH4pmPr0I\n9MrDrdKb604kSgQGJ/DGwc4oT5/cnYX8nSz5ia5QzTPefLRfKjEipgq48piZ\nVN+ozypgqAxIWm4FiRIFtGjnhWDn1CBAylUtE9DZr2TTy5iVa7AVJLCAxh5m\nnCoNtv+YvRiumWwg1FbL9QwmYW0M+QoBJ2+NChlRlVZVcAyNti85ETqI0Vhf\nAu3kH+oKMxpXMP5kf59Sck4aygLn9ixhw/jF/V/JbgSSxNpdM8S9sH5FKQNW\n7/238ufK+DhznCAaWmYpX3IO4SIN6QzCMJ5li5TaL5kj7Zs5lzd3zNrbm/1z\nC0i3Bdkz5mdql8y+/Ij9mt47CCk9K3JG5nZ8GTzra66wqHLT4Qwc12SCE4pG\nT0sg\r\n=RTD0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAWAGtJ68rZjTwQPzHsmCR8totrPt4Az12FzNkzFEq+aAiEAwP5B1vfzViVdkUtSncOj+BBBJTbEmnylViqCf02gH+Y="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.0.0_1535284622409_0.04953599157416355"},"_hasShrinkwrap":false},"2.0.1":{"name":"typestately","version":"2.0.1","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"4f260965787e9855ecff48d17ba5fea746ca0f08","readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","_id":"typestately@2.0.1","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-JQ2ZGbwPP+SeIXIv5vCheCjFm2kUw9cAZZ/3OPrn2Sp3k4/mjUjn/hDEpeyzj/hF2fAsFC4bXba8fm0qmn9uDw==","shasum":"4fb44bac761456c16b7fd168c2849d3e03eb997e","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.0.1.tgz","fileCount":85,"unpackedSize":221685,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbh5CYCRA9TVsSAnZWagAABOIQAI3l/yH9+NsTBfNmKK1D\n6HiFbzuzCqlbvIKxwy4qM6fXNzDbILCDcFYu9TiFvSbZ0xlKNxD08sC5WTam\nFrYaH3d3gsKKtePvqTArtlvZ+EXtGT1hw/YSJtz0QJxtuYVAIVkmOtAzUIXp\nNY1LSzAkIeS+O7Qgfsay+UXvXEB1oEqJ1B5CRW4lucQfa5dd8XeTGdUFvg85\nMAaHyTEqIm6e0FNdwZovinXpOlejHGX3VmdaNLZOZuwvcgplfB1ck9XCsQBK\nwBGTXgdS8cpfma/+RH2X+dSjnZN8clXKe8A9LqtNa6kh8BfuOGLHHaWRZbJJ\nEMLf/VzHT9bmTI9H9jKyfaZawOwbEowNukB8iF9rQHgKa7gm4iBszGGE+FUU\nExuNIl2UpWLr1fxziuCCV0u8sBi3vwF6VVl3PQQAb4/o+DRfNrtRO88B8URV\nZ1JnOhPbIyMVvbshjrnbPifek0X5GP0MtEZwzlLuANNIth0DyDfGiJlueVHt\nubHadnOmasrYNP5QFFWBk1ZhDSEzeeR7jNWNigQ86QeBAzitrecSSJUOCepx\nm4rh10h4EKikLVhqPwZlPP1XMSkjulTq3Fxk/JKlzqWm/102VEB0MlaHA11d\nTYlhQlC88cYqmiQ2cFtI8iTJVa6T8O3MAbI8GrBuvPzJG1ecJchnvvQaUOZI\nDSrg\r\n=irtw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDy+gMGM18cRiVlrBf9/ylV/lexwNxF2lZQmIgctT+YiAIhAPPe0BnOxm8v2zmz2t0Q3o+vc4uYF2BiNsFEZkw2MLkU"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.0.1_1535611031948_0.03569765140775716"},"_hasShrinkwrap":false},"2.0.2":{"name":"typestately","version":"2.0.2","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","gitHead":"d9e11d4c59effeb9e6d33c8d0f7927a555b4d5be","_id":"typestately@2.0.2","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-Y3TMf8ZBua1SZ/D/EUZk9thYAxVjQFSLxfymbOHsndF5y34kzuk89YN9RBRDBx/QonI9Lgoh+rJiA83fJaiGeg==","shasum":"13d53a768db582172092630ee77cb0e1eb5863ec","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.0.2.tgz","fileCount":85,"unpackedSize":221696,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbpQyTCRA9TVsSAnZWagAA5gIP+wZjqG3RIDqIA3Sou/PY\nsir2RSZdWnMUuWiQs47ula+qucaC8t2MLMaJQOjIqO69V7QRzEnKMnqXvphW\n0QKUuXdm4aS4fOyMWbzt2rgoGtsSvN/f6KJMZM/UZgNDISTXm4B8Z+1bx8ut\nZQPL13H9u2CpjVqbG7BC8ewnOOnnk2GrbJhf803h9eb/bXQQvjGvPd8iCKk1\nF6jLbiC3gS6Li9voWqLRFBe1a3PULtRmeUzSSOAPukuf1IU2hOTySCtg6lH+\nTCce31qgLBDyTwUKTvyw4fCGyuVYYw+c1YCQqaanvgFGFvKrpQBXDHcgQ5Tj\nXQ7kl/yPFR5IB1pm5LQmU6F6k6WDk4WGBcoEp05GzYf/pN/B1h/c9L+e6SW+\n9S5qU+eGujygiBFBc4wEFYchPP2XoNNACeC6ynUlu95t9j9676vKFchgCiqs\nFERVTMaWwHSyGqcB4wMTwLX+/r4ePEB42b4hWzKw80lyipgHrSXZOzlQFCpT\nrNuxTcWSXQ8WmhDpTjPPtsODLhL3rWmcdVVT8n+S34zirUDKw7dqMbxx7w/6\nAF2rZJF82LSloxCaUnOFzI07VmW4MnuLeGEiS51MB/ebM9pBpoK8v67/rtID\nmLAouurFzD6oAD1EyJDil/kxCJbomoZp+keudjFjOu+RbS/Qr7G/h07C2bat\nm2Ma\r\n=SR1/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHb0nF/SFS+LfbfdrD/mgbvof8kQeX+ao2HlG9nrMuwfAiB4UDTTGitmAi7DrbkuGFYwT/ZQixrLN0NwZcnyiLnVkg=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.0.2_1537543314914_0.5884311746769622"},"_hasShrinkwrap":false},"2.0.3":{"name":"typestately","version":"2.0.3","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","gitHead":"01c630523221876e42559a20fd01af25f2340785","_id":"typestately@2.0.3","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-VUco5cYWXrzJuk7Htm8mfNtVmMaJBi8YciM/v4di9Ky8YKtFy6TwMfns3ytv8Eui+7Vj2Wl70fLZ3jfGLchDpg==","shasum":"af967d3b5fca155ee11f7d8d7f6e84bf4cd156ff","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.0.3.tgz","fileCount":85,"unpackedSize":221778,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbpQ/CCRA9TVsSAnZWagAAV/wP/RaakJr+C+cqJkyRc3Z3\nLBFd3VowidGR9QwrdaXS3SiwXkq4TSf95GNvEvtjm8/SSYeRZVCf7Nx88xt/\n4s5IWQ786esPLKg/gKtoKH+l+rtw4sYTtttx+7A1ZFWoapR/Sjbk83rIPxav\nHCJ0cHsFXFSiP3dcywwTqUR8h8WrdDOgoku0/Kv2IJmOd4WCQkO3fD+vKpR0\nNNatIC9IBDa5DVWov1juz9ARAygiN/YIf6FgOxfv6+6n6auUxHMwa/7vkXV2\ngVXnnMuz5JjNlfEHhBbmvVoePcjldCf4vierypQPEssVo3OYqcbrW7JFH9Hm\n/tlEMx++PyfEwQ0QJZz91e0OKg3A1bKQ2JO6EOz6oQ679WsXcEhKrMGRodI7\nYxZGbR1QD9pDYB+xYlow5JSP6tiVo4FL1rHjAw+q/o5O7rHgkImqWJlT4+tF\njTuOTFgSPn2Ui/yXzG5Nhyh3zc/b5/ZKEAdDK6FWJmibgBhef6f+DAjD/CaC\n2Sv9pwmD65iCRI0lEkaNrAYjtEyI4RGS83hbsffTBrTauwZf2jt+VZUAz6UD\ntnHRCWTca+biH1tdqU2fT7nag6JQ2edIsVEPJ6OqGycPHKzbe1mrXEVtDdYc\n0QmBqnjUYq7fc709P2HUNEORqvhK0ApmFr7++GLgk3VEQehewQWxf2L3jAqO\n5K6F\r\n=SD4a\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSqKA388IH7nEfdLgGFKwKt1Ka8E7yyZO3Vj4jQGQG5QIgdOnFN6UOPy2yN9ndVf9RigSbzi4DPWpHXNUkWnfYLzo="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.0.3_1537544129230_0.5929349930347374"},"_hasShrinkwrap":false},"2.1.0":{"name":"typestately","version":"2.1.0","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","rxjs":"^6.3.3","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"gitHead":"dba0de8d9b86a3b6acaa3663c643bec8fe70542d","readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","_id":"typestately@2.1.0","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-zr/MbiQ+wMyUsHA0FL+ZfY3xvsDlij6dw9Nt72nGQ9qIjmPyf2dMTa+fpjpivCoIoALZPDeuforV1Mmj6YZiJA==","shasum":"a10ad2979fe82ce5b28f939b702144964bd43ae5","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.1.0.tgz","fileCount":70,"unpackedSize":337999,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcD7/QCRA9TVsSAnZWagAAzqQQAI0eAcZZg8K7rxDk4HdB\nWTQSYKPIv0pyKH3bHVW6OB5OPuD6ug8uPOR5ByccC7Gil155Ooe4JOWfRsKh\ntSMPMOZBevE8fkE31Hae+4lAmyxqkEqZjCbRX36YcBNSrYS3BdZ1tN5ZWr0q\nyL1GIjU+eeYINypjFc56vroomMurDud8CWhOJ+fIPbDkK3Lut1btXvTBNx5G\nanKKFE4GKANJFpQc4zvDBXoELmp3hSdqT2ctB44MAbCBcSwE2k2rtaEZw5pO\nk1hLx+KLS5AGw8OV838D+MiuQIvZ7hDOgKBhcnXLepov7T7rjSTe0DTAB+I2\nIebCmpQFWsN3Qi8B+69SSnRxAdf9Pey762TsB4jnykfoJ1FPDg5RHpFudMb7\n5jQFx2QdP+QnYvawU4+P1JWFLEzENoJPw1wwr13GgsbsIV9S/bFOFCloTVdz\nMoupwQdOottywbHwg2oO7vEhDKppaZjGrGVkAYAbPYDnKPZ6qmbZV41TtGjs\nH+skz3aFcc8NhIuyA2diZ5OX8sHh+t2vtpCP2Tn/9myPU6ddXiiyWwEMN4tX\nRjIiSkqH2P2y/H2vbLw/B4jrWAtZg1h9h8LPnt6G6kijO0XkvCq3Xe0TXVlZ\nXWYDjNbCtxynnps/DRFn1aL3GVxPE0nT9lNOULyl6vDQJnw8chVXbjUPcQKT\nio/a\r\n=vSwq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDDrGV268n9yegz+/ajAq7XqghehiePsTmtd1tIysSAvgIgbJDGd2oa4KfJ0fBt4vlAOAJ8gd7qCToacfj2z8UzqOc="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.1.0_1544536015975_0.27639565529476817"},"_hasShrinkwrap":false},"2.1.1":{"name":"typestately","version":"2.1.1","description":"Recomposed approach of using redux with TypeScript in a react app","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{},"devDependencies":{"@types/jest":"^22.2.3","@types/react":"^16.3.13","@types/shallowequal":"^0.2.2","jest":"22.1.4","react":"^16.3.2","redux":"4.0.0","rimraf":"^2.6.2","rxjs":"^6.3.3","shallowequal":"^1.0.2","ts-jest":"^22.4.6","tslint":"^5.7.0","tslint-react":"^3.2.0","typescript":"^2.8.3"},"readme":"typestately\r\n===========\r\nRecomposed approach of using redux with TypeScript in a react app. An idea showing how you can deal with state management using redux.  \r\n## Some goals\r\n* Reduce needed type annotation by making use of type inference\r\n* Reduce boilerplate code \r\n* Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n* Easy way to plug new parts of global state in and out\r\n* Support code-splitting\r\n* Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup, registered and tracked by id.\r\n\r\n_StoreIds.ts_\r\n```tsx\r\nimport { setupMainStore } from \"./StoreSetups\";\r\n\r\nconst storeIds = {\r\n    Main: setupMainStore()\r\n};\r\n\r\nexport default storeIds;\r\n```\r\n\r\n_StoreSetup.ts_\r\n```tsx\r\nexport function setupMainStore() {\r\n    const store = createStore((state) => state);\r\n\r\n    return CoreRegistry.registerStore(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n```tsx\r\nexport default interface State {\r\n    value: number;\r\n    clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n    value: 0,\r\n    clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n```tsx\r\nexport enum ActionType {\r\n    Increment = \"INCREMENT\",\r\n    Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends ReduxAction<ActionType> {\r\n    type: ActionType;\r\n    clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n```tsx\r\n@DecoratedStateHandler\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n\r\n    constructor() {\r\n        super(\"counter\", defaultState);\r\n    }\r\n\r\n    public dispatchIncrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Increment,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public dispatchDecrement(clicked: Date) {\r\n        this.dispatch<ChangeAction>({\r\n            type: ActionType.Decrement,\r\n            clicked\r\n        });\r\n    }\r\n\r\n    public incrementAsync(clicked: Date) {\r\n        return new Promise<void>((resolve) => {\r\n            window.setTimeout(\r\n                () => {\r\n                    this.dispatchIncrement(clicked);\r\n                    resolve();\r\n                },\r\n                2000\r\n            );\r\n        });\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Increment)\r\n    protected increment(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value + 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n\r\n    @Reducer<State, ActionType>(ActionType.Decrement)\r\n    protected decrement(state: State, action: ChangeAction) {\r\n        return {\r\n            value: state.value - 1,\r\n            clicked: action.clicked\r\n        };\r\n    }\r\n}\r\n\r\nconst counterStateHandler = new CounterStateHandler();\r\n\r\nregisterOnStore(storeIds.Main, counterStateHandler);\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n```tsx\r\nexport interface Props {\r\n    value: number;\r\n    clicked: Date;\r\n    onIncrement: (clicked: Date) => void;\r\n    onIncrementAsync: (clicked: Date) => Promise<void>;\r\n    onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.increment = this.increment.bind(this);\r\n        this.incrementAsync = this.incrementAsync.bind(this);\r\n        this.decrement = this.decrement.bind(this);\r\n    }\r\n\r\n    public render() {\r\n        return (\r\n            <div>\r\n                <p>Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})</p>\r\n                <p>\r\n                    <button onClick={this.increment}> + </button>\r\n                    <button onClick={this.decrement}> - </button>\r\n                </p>\r\n                <p>\r\n                    <button onClick={this.incrementAsync}> + (async) </button>\r\n                </p>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    private increment() {\r\n        this.props.onIncrement(new Date());\r\n    }\r\n\r\n    private incrementAsync() {\r\n        this.props\r\n            .onIncrementAsync(new Date())\r\n            .then(() => {\r\n                console.log(\"async done!\")\r\n            });\r\n    }\r\n\r\n    private decrement() {\r\n        this.props.onDecrement(new Date());\r\n    }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n```tsx\r\nexport default withStateToProps<State, Props>(\r\n    counterStateHandler.stateProvider,\r\n    (counterState) => {\r\n        return {\r\n            value: counterState.value,\r\n            clicked: counterState.clicked,\r\n            onIncrement: (clicked: Date) => counterStateHandler.dispatchIncrement(clicked),\r\n            onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n            onDecrement: (clicked: Date) => counterStateHandler.dispatchDecrement(clicked)\r\n        };\r\n    }\r\n)(Counter);\r\n```","readmeFilename":"README.md","gitHead":"424fa5196f674d7385a9cc7fb4cac4ef1b4da412","_id":"typestately@2.1.1","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-y44xwcjqj+3kSIAjaDtilvQCFh2G/mhJ/okaI2RhtjNEeEheGnHXOSJjud7hLhVn6wjcmrPpNEvwUSglDcadWw==","shasum":"d28631f4fbc5d756f691f1bd97f049997a9d19c2","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.1.1.tgz","fileCount":66,"unpackedSize":336784,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcEAcoCRA9TVsSAnZWagAACpUP/jpwqvNA6xFMchH0H2Df\n8WsDI+d21AIo27qg/o0BMozcs29rPSf0+obQSIEstiPZF3SZZOEYbOpXDzcI\nOpE0qIEPwTwoeUpZUE09xrmI6KkMAAqFS8Y5ngxMkRjVmuQEeiDimiemgGv8\npBtYC65U9bS9/s3TvgkWptWYISE9oCVNOa9gge3H6diPPrTqxVQykjOzq42f\nfw/02dugN85lraNjEyZQUN1HjBSWNIQ+NJ5a3SRHayf5JJvjNQ538iMMj6Ey\nbr8vk0eGylWiq2ZDqAzIIjjgBAQQ6TNDQmpBgkegdHfatPWcoIJEkdJLc65S\nthjkTPuBYrjKmSggDvoP5lscnAeWPw8XlQHhVY8btVH1J6MM+Nd2EoDcNHKo\nBzB13d+pV7uRunAb5V51+Z+UVefO68zARulr/az1jYEYhTfllcDhMho0zTGY\nAmNfp8p6+yop4KVAWBVpevHKKxP0C6NfFOT5JPFIVrF1qA9fRdvICWH9PWnt\nHicRbNOexnWeVqguAMAldtQAfk7j039+C03ScGkTfdg/sr46qqesDQxqZ1bC\nLyCiD43Mwy9b9dAtt/nVYMJNOX32qBXMVAHrXpyqIi5dnfO9q3+qm/dOlpre\ngWdJIGoxShSJez1RDRtkUcMDIBvA3OjNrLU45HjWPOYkcmz7tIEEFn8Er+6Z\npjGm\r\n=jSaw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqk8nBOZOTU16DXRHZG/4XeLAjzOk4/jayLJbtbFggsAiBv6p5AhFrDbqfZ5HNvmkDhWjKL4fuxip4HJtDhmaIhCA=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.1.1_1544554279257_0.3363261411631895"},"_hasShrinkwrap":false},"2.2.0":{"name":"typestately","version":"2.2.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","shallowequal":"^1.1.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"3a935eb23b78058950dfe401f4032a57d9bb505f","_id":"typestately@2.2.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-LGc4bdinqnTz6jcIrAeudfgkVAfD7vPeGndKrUMmsGL0zy3xBWRyCGECQWiTNG3QhTp0FE/wW6RBYpShH+dlzw==","shasum":"d1de5bcd7b7a1cd84fcdb1a856416db0b19e498e","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.2.0.tgz","fileCount":66,"unpackedSize":246734,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc3l/LCRA9TVsSAnZWagAAtq8P/jmhhvXILpl2yN3ZR3+M\ni4b7YAM22Fx9s5L9OH4IoQW3+gHdw3kJnPm24Sqgs0lIFgsEVybNz56COOHE\nR7aUQ637tUuI1D3p8NIKprpSulEMLB/JIpf0Q3rtqMg/VYd+5EdR1SYsnC5F\n/De34XXo+xLJkB1lHF5fRq4wa+TMewDC03HJJx7seoZYU+3H611wExtMV+KP\n+xZiFPwPx0KDdKgsUtt9ylK1XxuvyILM46RwHxVoVOr+s/dl2if2E0QiEC6T\nxIdyS+xt/i3ufbYVG4nMmUWDWOwWkvvRpE327qsrQDj/R6ITiqENseFbCnpb\noQeAr/tniCyhfRhT3Z/yi9irGZNzwIuJ3jIv2dXq5lVXilGHSL95XWxzslSx\n0teSjIAAi0r1nio1uUCBCylOm8MkMPpMF3V+z8yzDp2UzajlVHaROWBQmUJp\n/1x5jjPvp48Bz8ZkhA4mH+t1qBRq0SZOrkzXLNnI23be+mTV5VKhu3uCE8dm\nvQ3vY1B0AQx3sBPVkxPyfDlUVncWIGTF9Kfe60e+OZ68klw7r5QJyJZY8Maj\ny5Qn/I/rkM3Npw/AhTOS5g4vPFF7j0wKFWqFLyb57s2M6f7JwL8MGq/ScGC+\not2ObMGbLgiiG3IAPG6HqY+H72NFqp7yCey8m308BpC5fv3iTY5vVbZ0uSVB\nV7BP\r\n=ZpSQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCRW+eir2YooUuIpkDEM3LrG35iwUmW421jzCJNqFL3kAIgKGwqlZJpKJ/87DFTWAYnHTTy4j/2DCkAT9aRuKMJrsA="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.2.0_1558077387189_0.0015908865059168775"},"_hasShrinkwrap":false},"2.2.1":{"name":"typestately","version":"2.2.1","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","shallowequal":"^1.1.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"53179f3f25539b465dd38bd4ff63008154c32f14","_id":"typestately@2.2.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-soV1SERMJS8eI9aoVhv65bUPsPK0Qh0CKtPabrV6STZQQeb9E9vUMRTM35ezpEg6tm2qLmZKJQbds1hPNftiwg==","shasum":"b80f197b498326f602b3cce752608c11ab64626c","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.2.1.tgz","fileCount":66,"unpackedSize":246898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc3mDzCRA9TVsSAnZWagAAArsP/iSYX7Xxvb7e9iW86sgq\nLvhkSYuNQrnzEZW0++CZ8tDhN/YnSsk0D5gi+B4qEPEuzfhBF8pK2y24nlf7\na/8mcSXH56Tq+sjZ8ZlaY4IkEphMeQy4uyvQSvoh1ctgh3yjX3WOlmiCbmIM\n776UuzvlTVT3Ydioj8hC92uekx1V3jo+dEC6C0wcrauK5gBltuDW/NtnIYD/\n6aOAwKdftmDVrXk7HFsrr0idvDAnSYEZvhGl5PWgiPL9kM9sXxwpRZ5GfkGt\nUYcxzQ8z++FtSeAVBEQbFZ82emBt8WQ3Zq133hsUya3kj+yT6KNSNQ70fq+k\nbtHrKTGQbfVqeoIFE2dxxjoTgM2Jsy8bklBTAITO5G+n8DGjRj0ssPD2p4qN\noXgAP2/iGt484izNMg8EykKMIENT1KekHWR9QzYYuCtfGrggSX1OLfu15FPN\nZGw7cIbZv2DFW3oqE6snuhZLawwlTNEBRhF8t319lHAjY3uCOocdJvAC4+ah\nPS+63ifiGjevUZamC7JeW8m2HgywXlubS+1NCNvmUAodq3xJx1Z375JmeclN\n6XKmO2WUPcpNcv2FfS8Di3kpfPZKau4s3Sj898DK9EqUrOP/ZCG51xR3ct/3\nSJI2fAmEUquoTuuK3smvOgWthNVQtBcubtjVAv0jnQvCNVw1jzZd/ZevfdL9\nuOiD\r\n=7Vxs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE1wGxc2qD842jtKIMBcQEyB5Cn6yU24Dua0UxtA3EnAAiAdwiJNVguRQAZHRKv0e5HFYXfTyhzASpx1DAFYn4f2hA=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.2.1_1558077682881_0.005067830136950446"},"_hasShrinkwrap":false},"2.2.2":{"name":"typestately","version":"2.2.2","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"48cb3adaabe9e43f16cb97fe49aebd481e9b0e42","_id":"typestately@2.2.2","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-dVxIe88C+VxMFY7BWz0LpjbtWJRZgOw+RES5OuILhJBqzxAc8QTI8QDdsCvjQ3n0lEWf0QReQknWHACPu+QqMg==","shasum":"15355a2af937ee6382bae475e38a8c06431384cd","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.2.2.tgz","fileCount":66,"unpackedSize":246900,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc3mxzCRA9TVsSAnZWagAAzEwP/3PzW4RysxlgQ72/jxC+\nzIEDS3/vzQJ7hRwaVpSmUX85K9Anj4oD/1jjAqvfZLZBxUbDpGosgg4Wptrg\nFb/LPA9nHO2ZyrEhB4LrZbqevBTa87JJDQNViU1ngMoqUzoUCeTE3JNWSTW3\nMA+0R9IWBRBCtOXWjpPUtsEk9oPhY6/9TLx5OxBNPuwGuiZzWOMsFspenskA\neqaQHXBps0vSHmG3KfKA0f89u4ym8N1WcgDzBaYo01+GKlrmLEDvHT9TKhW1\n+d2xd0iaaLgx8ySQc1coz+B5YhtiI75tr7PMqZFT8Mz0BHd8rttZ79a5YK3+\nJwKeYgyumfWk60X80lTWV+0A4Kue3BzAmPNaZxxzE4ygjZUhyMjPvc6DgdN0\n454fbtPy36DFyhrIp7Uba+EnOkRq+bt8CvgvjfEyqhQiGAJ0NMV4HLVy0UTo\nWoulmgwpdNgU9xOpq489Tun9Qxboh8MU/y41svaVYr0qFHktWwkIQT8eB+vU\nfiaR0xT72Sd2xWT4yy22++ku42jIxZ5CQIqRntqvbJy4eVjZuUnVQlOjul+9\nSv8dF4Ad1NL5hBhTnygEA3p45FkOXwzhtOe/im4HgH78ETLwOXP/DDed8RyV\nW7oWoCzmlCANanpwXt6Y4iksf+Z8PwG6uECkZ7+tZS0PmtsjxEaLuKgbkyf3\nyXZJ\r\n=iW+/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCA66ZGOMoj+PpkyIYDh/241yP2fUg0U8AHQsS0O4PI1wIgTLz15fd8NdsJrH1Bq0BHLIncX+7v9IFgPS/R5XMaYF8="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.2.2_1558080626993_0.6910253563947442"},"_hasShrinkwrap":false},"2.2.3":{"name":"typestately","version":"2.2.3","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"bda78b4a5af9c3525e211fc6424e8d6f9e28e4dc","_id":"typestately@2.2.3","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-JmcmgL+zy4gJ/Qsh1CM+Ykycx3w/Ye9S3u7ggYxSepCAUUgXBMEQy6BwdpACq/g8bb/hI9PtapirgUHEZ76mew==","shasum":"06267a3e5c5945c544404f62e6ba6da25909a1ee","tarball":"https://registry.npmjs.org/typestately/-/typestately-2.2.3.tgz","fileCount":66,"unpackedSize":246820,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc3prdCRA9TVsSAnZWagAAyZoP/RCo8FMIf6FY6BP2iMDW\nYwmZGBQyTq/8bEibpjsg4Ct9EpCKC5GV4dNPDobFEO31Lpb34pA01mC+ysd2\nKocscZiysYKQ5kM9PvcyB7KDU0iHZCjBed+4kgiFZsUBupGy5E2PSUexcJ7h\nnHOwW4rMxRcUCNQTRZtXe0oeBu2UDq6mA4SYEmAz83NJKFFxW9LX+ZO2Y3q+\nkiIVqRi+me0xNC8vEN5QitubE+wMXQeObIrweb3spR5YcgABLrmL3AxGFsXi\n0NwC/TywYZ2cGcz+mVePFcsxW6Yvieok7Fr1czt9bhTlziTyNiX7+5Q5J6OV\nYzgCMsNKtx9cjbgFEOYfkvq1zkb/NAe5jqtaV7wB1LjsjkjIxf7efwiNJrfm\nm5jL+VYJew5NRdR9AhO0IirWh4gSWCYG74s/1i5vHZ5Kqp2oziC3O/QokFfO\nsVHdMhUHbB8D/ckww2WclDAehcIu4JtLW7bTCR/L7qAFjmm6HnzvjjSJl9lG\nNRiWFCED/hyfFHFjcsbZFzbEKLKE8ygeLnznMV5vxVhJxq0YOXTuJsZm3Yfn\nZfeDxlSQ5eLRp7uRe7935gPOc4TIdpvdm1020+Sy3bdTwkvQUYYwm4TLqG2v\nRF/6ukwfW9YnBrtBXBwPdRFlvezz88e47Ft9/Tn4No76P0a+0HN7ItMf74/Q\nE3H4\r\n=blAM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAHlBbJQ3ZLT70SsPhS/v1ZqNRuTxcVPFdLeBfOWJwE7AiBWwP469TZpJYEF+3DgGhAFy0efMF8lvT2XOs0sU6WWSg=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_2.2.3_1558092509225_0.5769520256362246"},"_hasShrinkwrap":false},"3.0.0":{"name":"typestately","version":"3.0.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler.state,\r\n  counterStateHandler.state$,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","gitHead":"637341743ac05b4d48bd559e4e1e763f4473b249","_id":"typestately@3.0.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-nLdPk4kbYhUa6ZS2oAB0R8tE20YqhfQlFLduyERCtECvq5TPyRtuRs2WQSk9cWiLmKURIANGtgBJRNSNgvKqkQ==","shasum":"d6543731973bd5acfdaa3cf42780e1a379dee46b","tarball":"https://registry.npmjs.org/typestately/-/typestately-3.0.0.tgz","fileCount":66,"unpackedSize":247030,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc5To5CRA9TVsSAnZWagAAghMP/RwPpAer/h8w+qlypmqJ\n4xv1tRN+7Fsxo42BV41Vn3eANZHoyQ1NKuP3SvcYpuk/+JER/zHRNxa2KbXf\n1dqPyClSt9chsN2GZy17bvnuAKGHCI7/BrCQddz4ad0CRREuX+oWo0yAlysf\nRaekCcw8LJJCKtBDx8EmTt5n3DS/cj5Jwcl1oG3U/EvLWxghDNFvFcQgNo3v\n10EL5VlxLdh5i+9R8Qn4LjxpB7oVWvqcrgaPkiyIOa1IFhhoaoltuOxMKm6q\ngC4+D0ZseKA7SJPNLJFR5TX2b/vAe7frNfdjV7R011YnTVqxEtFqDEuv0SGr\nO3VOUmWuYIzjgOBLPeV7WbiEUz6ITjBScNwN2j0mg8R+udJ34wiLm/QwRaXG\nGO26Ed6RaizC5XQDNMJ5FSgTT0JzZgO8gFAJ+2IfmvPIsYrPqjN1kOTZVJmO\nhUJ+fa3TGvdUeBYBM8rLB+YJIxXmnKWgKUvHpuJjoi5ME+zvFW9D8kkkpTfL\nRjAojYjSONUEFAolyjMlwATg1p0XHBKoJn+c7VRFc/XM9TLNSKgrRsR0VgRi\nluGwKdqOKyvWYhvxuNJqFPkqKSZ/XXocGd01v+H1OPEqLWGnX1WGMtve63TI\n0K34z54ftj6HXeazqS4dFztXVPvh78ZP/pHiMOcQCW3xluTXJKiCinoDMbGM\n4B6f\r\n=ly57\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiaLeB5QCxD/uANBcEnd9VeqS83IW6CGC8PzCSGdAhXwIgJsEj0N8nfhILEk4YcsDTWmQ+ZcwbVoabpxJzEnghlvA="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_3.0.0_1558526520831_0.38035887036767235"},"_hasShrinkwrap":false},"3.1.0":{"name":"typestately","version":"3.1.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"66f173cf9f2017d5b4fbffdaec47bec5a41d605f","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler.state,\r\n  counterStateHandler.state$,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@3.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-GLKtJ22xj/oY2xsLG86t05chm0hQkHB6dm9HjPcmgv4QmKJEeT7GEQ16hux8h3NaVAOUhTTj+P/LqEg7OBZSrQ==","shasum":"0182e577b30f6a88d8f338ef0ce7de46a2893d24","tarball":"https://registry.npmjs.org/typestately/-/typestately-3.1.0.tgz","fileCount":66,"unpackedSize":248348,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc69EnCRA9TVsSAnZWagAAjzsP/2qBurYWVkGVruUuX+33\nKwtCzdT9x6OYpolGMvdTxxVZjHsgU+eWzSJ+AdzQGrbSrcIR1zW4uqTekD7h\nrCXQaI7YawTOIORO6TdjWJKrkt1aJJQ8xHrzy+Q7zGI4H+s4jaY1YyAunRC2\n229DbGenb/XtDpKly96DsX6aMM9ejQd7jwDnRtmkSYAlpggsUUtQD1qnOX+/\nwCFaqoZeVrrFVOuSRO9U+IHaWsF3Y+BYLhjoodH7MVxQ4yKGentyLiDV24Tu\n/NSvTXKjH8H+Yhag0kXTgnUqV4Oh6chX8ncfibB75zoVedhy5hT/wElWzDJq\nsNlsH9sJNUyCUf06XVFzFEip8MsuTKiwpVWMHenqZ5TUiFlet+4/94yqmAkE\nZ86UKDEM8wX7b48wFfwFp6o9sEsskla+JluBll4cnNT8LE3Uj51oYXrHgMN7\nB1XxVABMm060bfcW7tO4BFkCHIO/+6vhvJnSzdB738CscbqAaULDkTvMO8vm\nT4uPIJy0WMOv9eN9ltz3lUTDHy7QIwj5vSYM6EqPSp+LlmMRGO55belGE0TD\ngMCEpFvfjv2IQ/p8jObc78r+MrNkVSvi3SqN44fDW2z7spEy4lZotdodA83O\nCBxw7iXPSVgfQR6AohbrI2c3nLC3POKi96SAYaX+h0tbrS31xVnvOpGGqUzx\nsML4\r\n=Whu1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCFDoeJpKpb5oLXgr9g/w5j9sv3EtU/H2r2PhgeFBdKYgIgSKjFEa8VdmqpuBHU2k0nPHh6fQx7KOnVFWMR1ViP6pE="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_3.1.0_1558958375315_0.8477024900656902"},"_hasShrinkwrap":false},"3.2.0":{"name":"typestately","version":"3.2.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"00f0712edcd8d2d1c9540473e448a30e1ec36bdc","_id":"typestately@3.2.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-j0VAYmLerqozbx9O8BUfkU00xFaHEU9VkKGrv1joEtv8sR9zfcozY7U8q3XXi94WqwAQmh8UhXANfDwmiJMRrQ==","shasum":"5f49958cd27c835081b6486ec3fb9a6f4b6d7c5d","tarball":"https://registry.npmjs.org/typestately/-/typestately-3.2.0.tgz","fileCount":70,"unpackedSize":260300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc/UbdCRA9TVsSAnZWagAAVPYQAKRToXsx+QwyKVxa/nOy\ntIyvZ4WBqZ/QxPjamAMMtsyQ9vekqhsRHGY7se7euLV0EC/opow6GMea5Trc\n+GmOwJqygG8TD9aODUWG5p63Pc0dDusdO+C2HA9GnZLBRExwWHBSSD3aLXEF\nRI+MsbpapVHPHwJ4k1RwD7/y6XLAoxEeKTLV1wBpAcjQHrZSTCwDPkBzx4Df\nQA+jdczYeuXOLsdJgzpksnuYfjL2usEFC9h3qoiywn4MS6YMc+bWMXdRIy37\ndn8ko8B7l5ev/KgNbr0uItgbhwGjVFPgVJq56wsIDeCrfY0hV3xInwE6gXnD\np/gcnAbXiBD5WkUYWI9UkpL60i9k0BI1uytS0s+kZmYNQsOi8d3gFj5TEXUV\nmhqSgcSkRiVz/e+/f0ZsS1+EPmwRl0YebdafBn4f7RYV523zOXkF/P4eCE3K\nqalM1k5BV8uwin6Uzjn0FuFy8UYzIyH8QUnlwSu7rxgFnekmmb3Z3lIHPgKq\n6J4Z3Jz0z0XappRq7uE2PJsginnYsQa7blXS+/G4lFL+nrX08GbVjJ12cUd4\nCr3FgV55EzTn11QqdtW09ku42rpAaQwhHtc25YINPrJm7LUbnmnK6AZlQswK\n/6pLQkHn7sJVp/X18jwfpSS7zcisXaYfDQuu9eyNsk6eAnss0z4Ct5fJ2vIS\nduQs\r\n=QVre\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCEB5hA3nisJpv3QO+vZvPvD6uK+vIKpFDW+sy7O1aKBgIgASwwy1CN4c4jq9bzvqGFKJ2/UzKwbMevkLm8qAF5F+M="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_3.2.0_1560102619850_0.10404744940680621"},"_hasShrinkwrap":false},"3.3.0":{"name":"typestately","version":"3.3.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"fe1d2fc20b6b6b29b64f935e3581f0aa28767693","_id":"typestately@3.3.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-251TOLLYzT1mPq21q9nZLvnmVapuQNM1pvQ0YsijctrUpjXPUKe+9OasQbl7hBKaXekZzR7RRJQ0luQIIj+3Gg==","shasum":"d012d398fed13d07b41bf53f056d39220071a2c3","tarball":"https://registry.npmjs.org/typestately/-/typestately-3.3.0.tgz","fileCount":70,"unpackedSize":260334,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdFdqDCRA9TVsSAnZWagAAssgQAJ0HSHw8pb8oK784K92J\n3xKR3Hcr1d2T4akw+vo1351VBtv9+OUnjCVTFFOS94Nm9x2KreXTlDltgbgf\nMce3FbhjN/GMpONJKzTwnoLxLWTR4179IjP/i5/eWmBM8xwTCtbgsQBvoGtv\nfj5zjhofsbTV/tiEFT84XIuHgoq2I0GtPv+UoWK2hb05FCKtiuBd6s2gQfck\nfh0Y1Cv9eOLfM/halRFdRE0mLPO6CuhOVmZhQ5fXynuG9u3mnV//305qaAI3\nOpgYFVePB1AeBLb4BMNf+oIej+8mmVpLOjvG2pC9IpJGq1hNtWHwMf7Kl5AE\nUcN+TUuH+mxh/VDmZ0B5/iCAl8k9SAqt/SESrZgtwSO/7jiu46n2ZpAVQmAZ\nnig+TFbuUJT/wK29X+frZl7BvHV+QPjv0cUdBYzgbY0N3fVo2baYyNHPXx2T\nbCIfiBvLcGQGBDZ1WkridLy2xHdFBR1q8lCcBVSCPydYG++gLo3On9Vtdn79\nOQmQL+TyDGHnf7ZODreaHrRE0rMg6WPPn2AZBsf/aiLOo5ez5pe52WXcfQxS\nRMrhLBBr9DQZOoXCFSZVyA72P10k0x0PekuzBYGxOe7rJkbrbryUl/B5qzlk\nrg3JsjZTiS1DoyfP7ZCxBoAgHA/ptAi4uC+ZUFAIuP5OkZ9uTiYytMpTFHTa\n6RE+\r\n=OWmY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZFR5giXgckYYsgYu4bzI2P5Z/cc0/8Zuv4SjWU688owIgdLRzJTyZdMLaTmnMEdc9sDXvA5Sw/VA67/BEWKHDFrE="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_3.3.0_1561713282868_0.31744466976480656"},"_hasShrinkwrap":false},"4.0.0":{"name":"typestately","version":"4.0.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"77bd8030a2ab1938c20c6999cf997b407154b5b1","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.0.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-ygs+naoAeENiRHdtaB85sX2rf/6WucmYGv1lkpwfPOvVLTm4Jz+ZecYeiwQ1/xPw3q+/7d64WQ0hJFxDgwP4jw==","shasum":"e00b454bb25f0ca96c681cb6eaf2ec41876ec296","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.0.tgz","fileCount":74,"unpackedSize":284024,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJde5UhCRA9TVsSAnZWagAAabIP/izfgx2Axf7lFzAP2kGZ\nNpoq5iXYURpmsOW7t1sZuabQADZCaGV+5KDJXG2MhbAW4U351Vq7BO5Dhw3N\n6uyx1Z8rbYpQ1ZpW6sXiZEzgmZk6lJUogOqkny2tWD7XT/r68wdHYgp8U3WG\nLvK8gyUyZRffAP55B8nzoJk1qpghnJYbcEWnRkSk9FISZruqNiKxhhZDf5MB\nvZCxLlWQXs/WHeXV4YuoUiyM+fDLCTSmp+pK4QJR9xHYwAC6xNVAE/8D96vA\nk4sEOGoCkkOtUliOacKsCd1dMq8cmo3f9I+IjkaUP8VfFt+4OQPWqwWHG5/r\npQM6uLx5KJ/HigGZf5MiEkUD/0uYMec3x9Jwqc9zKIOYx8lfqBclqiv3j6CI\nwDG3txP+sLRrV8UvUifm0hqQQgd9+kwDw2eA6fJtUeLgSat6zz8mSAoIHiIb\nZI/vcSIN3rxJD4j+kGrpAvK7oq/QFk4jXLuCFXukzL5xQ9EpzktmfdQ4ZFuK\nDm2NsBuNkl76f6Bu1uA9sJsOIUYQp/fq0hyx6nOv1En9ttC0WxjdcaRjSJ8a\n1DcxiWo2YFhpe5lUZoGP7a7VkS2cHDG4vAfrEZtsEVRhNe/xgWb/CtUDBAnU\nOrPkaQWjaZqrHDEtOELOB7+szd4LL39hrZ/VuWNyYwVN1qFYc37+Biho+rKA\n3YAj\r\n=i+WE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDsr5i9VCDMd5YmgQcd6p0j7sIPyG/hvJ5ZSnGwIBtpXAiEA3CU8P8PvIF1dyLapJ7WOD44sPFSGMdWYTocxZFuTuQE="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.0_1568380193061_0.6810690567346585"},"_hasShrinkwrap":false},"4.0.1":{"name":"typestately","version":"4.0.1","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"982de5b9617435fc8cf4f9b9120233b12be68e2b","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.0.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-q71xmmk/sRPkEFJodQOkpLO4/ZpHdaXoZio27uSkqbWcIz3k2jh8FpGgLwgNslnF1+O94WPFaws5IK/qxfF9Sw==","shasum":"2587bde0411b52fffd7d57c78992d490a20215a8","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.1.tgz","fileCount":74,"unpackedSize":284026,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJde7C4CRA9TVsSAnZWagAAZwsQAIGZGCk2bJ8034rA3+B7\nIQsInXeRycBpIfZo2QFwr0Fp5ZXsrmoj2rkVEtqkt4uRqeF85ANbtppcf49q\nXWh0R3eklJ0rtkOo/XVQiRNpX1WOqWhvNunrN4B3Bqbj7lOTxkvdQdsOR8J2\ndU2FSguqO3yVSSsEyqAQrSdU++pko66zCzWMpXF48rLFQrg9HSsrdxomY2lP\n61JwdZ0R1j6XkJykRR7kjMkyhA02Nv6cTnkaqR7zo+h4lb7dJkeiEdRNryWt\nirLlfJ1yTSOvsMtt39k42jtJTJcQkqfthH7xmGUpxCP8B4Ta6kLbPu0TInwK\n0vGWH/KTkPoM8BvdpYetXtepbudfdrcupbUq27TZb10Zb30GTLfEHcDn0FOv\naWFS3vpu+Vn/y6kiXwlyQMDfKYQyZqTYG7uhkI3MO6gKaIbIM4NS2jFbH7L+\niy427PhMKVUg7KaWnXzfDMpu5REZBu46tuDYv3Yx8/3S58Z4yJhhltAEJ3dS\nBrzNlca9K1NIvpQgX3+Jcgtspacn8hPC4qo6DwGxOmFnZ0qKcjGov3QR/uf/\nKi/gmkK62Cu05QNwOgMszQdck4sBx8dDD4F+rZ6iA8w9yIR67RLe5+1FYtod\no2O0+zLIOnM20eLZ+QIda4czGezUrYxGwP+EwNVIeMEzF6wOPGaexfjFFl1b\nNL+H\r\n=jwMo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB0BLKuDlCldq+YduUDy/XvF3Zg3BYWZlE2ERGXTmlfgAiEA/EscqIkClKjAhtFocfYRDP/q6woqpLsz5nL2R5Bxlb8="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.1_1568387255744_0.34958217718300677"},"_hasShrinkwrap":false},"4.0.2":{"name":"typestately","version":"4.0.2","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"f202f42629c3b981c785df47815e59706d3fae3f","_id":"typestately@4.0.2","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-S/+8XmFi5KrAaauhiSrAb1/zp7izuvWAczJJfhgWNis5WxWWXZvk4nd4m3pQpUOSpyZFuwmNNZhIeHCt9Lo20w==","shasum":"575fb120072a9845263972a08912f6c18f3dc031","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.2.tgz","fileCount":74,"unpackedSize":284118,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgIoRCRA9TVsSAnZWagAAZJsP/0kxIII1D8Y/9nCnBy7r\nAnXCYOZI1eiFm76whthR3Hn+g/8YP/VAMYUf2NCxcrtSvs9KR7r5Pc98htuZ\nWwv0wq/E2QazRxZJmZohC+xQKIxDJpuh5wAMk0w5TSGpmOWBaVQ6wBB/f0bg\nM1IFGiSwudDJ0F2fYr/n0CqUDm++nrXOl8Q7rOGaGAi33Gmvwyn2YAvaELLr\nOZq0rrWjBYEI9136cf9v9Pnd8Z1A4M5fmgMB2s2XOIUMwYvTQzws6+qNXB+F\nfneTnsKFA6wLWMH6Wu/xGO6uDFhnZueKrv00SIIzaOfREsxVfBBQ/7LxioSJ\nuA0TzRzVx3ICZmW2p15LpaIWsgrdiGaofKjeaRJl+v3vC1Bc8srCTmH17Cmv\nRBQ1mbIuyyxkTvkHPDbNLzoqsc89RKibVJ858GxZIek1Cl2r5mCvVwonNS4e\nWo9UhAQpU/9pmkoo3bZQjABoaB82Nop59SpycsfA9ilQXz2683FT2mDY6KAb\n3eOyGj1Tpnyv81xJkIPaU4VnaGF37IBS70+JeTsE5c7S9v64vV2j5bL3+kZu\nchLCaBle93++FxRGt5S3Sx2FhpSTRx6gRueK14O87zrRpr2HJqN76dGdLl9C\nJzvpqTjgSarE9AA+v16hazZapbEwoeAM11WQ/GrY4iAhF4KwxiG98xM9qIRc\nv6h6\r\n=eMEZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCBUu2DPhIhduXgSVY3Isslof27/0XX0NBNcZDahhMnPgIhAIcazYtsV+bVtQ65hR03/7kSfGqNaKpmKfZWmez7huCg"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.2_1568705040371_0.13009334294953545"},"_hasShrinkwrap":false},"4.0.3":{"name":"typestately","version":"4.0.3","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"276a7ad733c8d92fa80e58af9bdc83e2d85c488b","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.0.3","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-NdqSnDlV2EhhFinCjy7uHp+ix+4JvEK2/AzNIzKPT8iE8eeBUw8MpZxHDLco++oNcUBvcdP4RO5m5E7qmPWjLA==","shasum":"b578c4ba3b800bef1ab4690cd390e89a25ff9aea","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.3.tgz","fileCount":74,"unpackedSize":283857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgMhvCRA9TVsSAnZWagAAKNkP/2Fj62VDvJqm435cpLP/\n6BjM73JF6vgy9mniZ85AUnVWnrojI+WhGAlc/XZGu8TLi1BHTFCUM0uAABvu\nR+xfEYSiUlUyyLXKNN7PZHiVs+lZnaR1Et0nXHz5FDkIKPRheUt0cbqk2CJ2\nvZr0lUEezYIyDHi8+eXax9fXTO/gVITqseB5uAGZlNmbHRv00fO6LW8uIOKt\nVnXJFiyF3YRL8EvW9EFagL1BJjNH1Q9zIAcwpI3mUL3Rp47GcNCCT3AX9BkQ\nlVVC5JhGo3kg5xgmcL51anE70zYjC8pOx9ekDMRNzcPOgS/bCLlSxqdMrMCi\noRRbHOxs3oBrjrLNBm9/46qd15F+RIkkiTLYw7BEWymHLoZQ3YGx6v02M/Nj\nPe1OUaFRwQM78Kvyda/uJS125jEKgp2JfbnwBVuHVuZjE8kF8MpusvqL+6SB\n7ck9cLF41SFSM4CaswP0fM74jHFxwHjz0/9j5t0kZpPDGpOTqzRE5Z1be3q3\n4FLIcPtmjTGb+eSEDynI2UTt1Qep1+kIMQ7sX+8djcRGLkWzJkTnMfABABYw\nZnuQpxgO7SjqpSHC2pDNr7hhlfVnOXq7T1rm9VziBxZDorF59YjJA1Ow2om6\nR1oEkU3UGCFT1fRoCGu31NeBuzAsA8D822pjW3sYTKGbLF0WXaOedFXTHShf\nanef\r\n=4Bp2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFCq4jah3w6Zw8RtLMR7V3gLSE4HjNhRRedqFB1ccwHJAiEA5Fa5xA0ig9TiCD1qZ7sLJTXgDnzZEfF5ApAsyIE9zsE="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.3_1568721006537_0.3287568922034243"},"_hasShrinkwrap":false},"4.0.4":{"name":"typestately","version":"4.0.4","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"b4e51c9f0557bd7affaa3697c697469e7250bc9b","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.0.4","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-i6z0Oqf3TPU8DdmKKvn0ci2CSztcTsGChX7Z2WcNWdqhvz8Df1+1GUS4RWWu5OTQEaQAmjeM/d+Ulxe0qDEV6Q==","shasum":"0a5b93ff6b26ce97ef77b9f7942cc1706c8dc301","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.4.tgz","fileCount":74,"unpackedSize":284022,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgN3XCRA9TVsSAnZWagAADgsP+wXiGFsB1K81DWBsJpky\nZqo78lcRe4xFJu7m6UzMRYsdkQewpF9CtSccb9llho4WfvQz90BbxgJ4WP1C\nDrDCrKEKra5X4AE79HJdmfhZXg47UaHk0Ip2/UURkWnv0JlvQrw+Mof7/j5t\nXe6ekBgNrlkwRQsEL00DIrmF0PjyzfLXqePRpW3AqvYWG3mJfGd7196lPRiz\nPEoNnKRkohK+BxejZNoS9iPspCsQUwI4K8CmhUfIgLFl2xNnEAl4uFXGB7os\nQ2PJWJu4Lf815s2+F+UWfSqKZLqgsgzj8S3FdWe4QkiNttrKtMVdM0RKLi9F\nh0sph2GjY/md/qZmvx/9jy60yMZ82mZ1MmGJBppinDNXq2GIJFxx0/1AJVwY\nkr4VT0DLEpiu53GbcuxR++wuKYdAvsXnWSfadlFXaEDtSfQ/wm0tufhcvctJ\nromrH0x38cAqbBWiaDdfKrzplecsaNHNpb3VTLiueEs7WD+5Jutzu3p/BIXr\neHxpJqb+lv2FWb8gAVaHNS5k1/6KMB3DYXP3w6AQR+Bj9JcCl7wZZDdDiRlp\n1fGHnW3jw/8wzZvau3x4uomMh+s13pPwYRHQCk0gYIKOVzjpfmX48ZLt8Owd\n7qVlUm/Ia88K9CBl/BKA9tsSNmVYBplwOPbuy0YcrbiQ41wT5oGenkxg1xsk\noLTP\r\n=xDwp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBjykmzgi7Lzu2OJBnRVaLXs1YPBbJ2vokKkXHdC+F1oAiEA8TW470SrNq5XHVJcoNeXyS+pyrAEFmVkTjwaeSwgqgs="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.4_1568726487003_0.3577800558987694"},"_hasShrinkwrap":false},"4.0.5":{"name":"typestately","version":"4.0.5","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.11","@types/react":"^16.8.3","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.8.2","redux":"4.0.1","rimraf":"^2.6.3","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.12.1","tslint-config-prettier":"^1.18.0","tslint-react":"^3.6.0","typescript":"^3.4.5"},"gitHead":"39d681ccb932e98465406caefeeed8dab56b13fb","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.0.5","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-PEIl9DenFBj2vGddUo2n1tKnI0WY11IYw2+KvpwSe0bl4pBsYjOaEw5DUHkNhzNRLX3R/Z/5rDrPTU7/sQouJw==","shasum":"ccf1c6ba71d09d141c555c1ef17ed9c4f33921d9","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.0.5.tgz","fileCount":74,"unpackedSize":284032,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgOIbCRA9TVsSAnZWagAABM0P/Ar39M6bcEawNoSeNaXy\nsN+LMmmpit92ge7kPp3/peO2MIwvsSYOGKl47YoVxbWpoIX/blBqopF+2ohU\nKdu7oFBOOIsGRPzy1MMWmqVHuXMG9G/EiajqYVbQDaAQ/iRbLjhSmNO2ISR8\nOptv7NZLhyUzdIo2azM8ch1xuD6wF0o2GeUpJdNlVvV87PkxWagdr+qihfS4\nz7JnzdIpL24/CC0AhOcg00pK5wHRZD3XTMhSKXcS9wllOP1y5Jvm3lZXJa2j\nNhQ8G8g9QC4wyCRW5/HOpgf9G3t92f9/AiB5IfLw6vjxgT35Dsky3S73tc2T\nGUklEwIS3uTAUzoY5SOoXjTy/wlODYPcnW1kIWHV8W44YOrgFfQ3Uy3ltBKN\n4hZ1lbkYJSMlpTgsjqUtx0DPoimdE7C3NZbkpSqikamzX12HJOl7iGafAn4l\nKunCyeXw3hTk+f/cc3r0IXpPeuaYU9xCGuA1LkDa8FBvNLsF3mdT8GPz2orb\n8cs5oUpUhyRIRJx7PIZ5MWW6R6xa6wZrd7VnGK9tzt9qqYSsocbZtmLIz6CW\nzpsZhQEwRi5hjRj7xbaTJZIWE6TRDkUoQ042yysDPxA5UzWBtIK4837rPrE/\nLIgK8jjEXet14oEdp7zx4WDAI21c8ms4gcOAUFNYqT7A2ErJ+gHtdHRj3LNO\nwfxP\r\n=Er1B\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwpBs19EG5Zz4qz8Dl7SDYjKkduOEWTHg1kg2LpDAIYwIhANmAMkHGYpd3hadpzNr5CDcfCJyuX9+7wK+yqTjV+FcZ"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.0.5_1568727579359_0.20663435928243"},"_hasShrinkwrap":false},"4.1.0":{"name":"typestately","version":"4.1.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","tslint":"tslint --project .","build":"npm run clean && npm run tslint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.0.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.23","@types/react":"^16.9.11","@types/shallowequal":"^1.1.1","jest":"^24.5.0","react":"^16.12.0","redux":"4.0.4","rimraf":"^3.0.0","rxjs":"^6.4.0","ts-jest":"^24.0.0","tslint":"^5.20.1","tslint-config-prettier":"^1.18.0","tslint-react":"^4.1.0","typescript":"^3.7.2"},"gitHead":"181bd3f9af68249c04dee988e0718224b2a511ed","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@4.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-+5LdQ9w7vN+zC8GJfsatH65wxHFkWocu1O4ZuwVA4cRioLyWLfVCP5Y0ybKmt9ki4gbsGyp+tZRumiao8yR/OQ==","shasum":"30afd0fb3e723597b591812a2c7e86ae59fe2bfc","tarball":"https://registry.npmjs.org/typestately/-/typestately-4.1.0.tgz","fileCount":82,"unpackedSize":287796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd0sxsCRA9TVsSAnZWagAAUbwP/0RTUcOYGFmNrcRkZTh7\n3Z6cFVDsQ6y85Sj4cEBK0VkD+R5LePJ9cFDXFXbuA7D8fB4qqozZsJ3GfXvg\nbSDNsLOCutGsyUFjvLt1Zo/edXfwLPfwxw+MBXha1fzUhWcvqB3lJuAPa1xH\n04DUvjA1jJXyP88va1Ns3ft5dJBNzhoU4loyHjgz5CidxnHNro3XviNm8NTb\nst/38KFq8w4SDP6UepmMnaBrhmXYCB10DInyGfm3bJNPvOBJgJsmPxi6eNYC\nnDa5y6P/MTXAtnxWqxA82DKjVXX3JWBN1I3ezKKG0XZvPw85Tg4fxnUYi+uU\nZr/QuEljCeXMg3G8CGtimS4nqd1thr4xqLDlR8l2Ph0D/Dl+9KU6zx6olBm1\nLwolgGn6+8r+06KJUcWW+kj5kFTAajKo2qlL1M9H3ipEmrMvZB42WXNdj8k3\nMsmIvu/YokT1MuuWWrHvTYY+SiItkHoomI2IiKCYEz+NI6Wg0YlxsI0JNhzR\nltJkMvCj6jRvtL+1r9+RohW+4FxbjGyeVn91lslwdLu5Kcp+rP3Jy8MIRs2I\nnjiRZz1iNzP+VOShOrthbD2CnXjv6yMGe4vfFXCkRcjOkO0PmTMN5WWZMdjB\n+BiE9EMBkhdo6GuuchvKBrvsecSq041qUhG9yJapz9g3c5P2afCe0YAeDMl2\nY0xl\r\n=/k2Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDUt4Xn4fahvuJxOhCxyv8AB9KqeJDr3ntbqdcHgAe+TAiEAgmIY7CHUk6qFeDwc4IzxA2NPXjFzQrBq15d5a9eTfyk="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_4.1.0_1574095980056_0.3274007911177983"},"_hasShrinkwrap":false},"5.0.0":{"name":"typestately","version":"5.0.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","lint":"eslint --ext=ts,tsx src","build":"yarn clean && yarn lint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.8.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.23","@types/react":"^16.9.11","@types/shallowequal":"^1.1.1","@typescript-eslint/eslint-plugin":"^2.9.0","@typescript-eslint/parser":"^2.9.0","babel-eslint":"^10.0.3","eslint":"^6.7.1","eslint-config-prettier":"^6.7.0","eslint-config-react-app":"^5.0.2","eslint-plugin-flowtype":"^4.5.2","eslint-plugin-import":"^2.18.2","eslint-plugin-jsx-a11y":"^6.2.3","eslint-plugin-prettier":"^3.1.1","eslint-plugin-react":"^7.16.0","eslint-plugin-react-hooks":"^2.3.0","jest":"^24.5.0","prettier":"^1.19.1","react":"^16.12.0","redux":"4.0.4","rimraf":"^3.0.0","rxjs":"^6.4.0","ts-jest":"^24.0.0","typescript":"^3.7.2"},"gitHead":"885cdd5dcdc0aaaebb922f061f33bb94886a4d87","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers (class) and an alternative usage with state contexts (objects & functions).\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nimport { Action } from \"redux\";\r\n\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nimport { StateHandler } from \"typestately\";\r\nimport Status from \"components/Loader/State/Status\";\r\nimport LoaderStateHandler from \"components/Loader/State/LoaderStateHandler\";\r\nimport { ChangeAction, ActionType } from \"./CounterActions\";\r\nimport State, { defaultState } from \"./CounterState\";\r\n\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nimport * as React from \"react\";\r\n\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n","readmeFilename":"README.md","_id":"typestately@5.0.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-TzYltUx5/jtrzAXc/n2s/7yTXLAXczVAmLmXUqAo6Xy7bj2wqYQ+HPEf8XtvC/N0rOSuVp7XtvfT67vulc4mVg==","shasum":"9bae89893b6baa15171a760b5b465835dca19aa7","tarball":"https://registry.npmjs.org/typestately/-/typestately-5.0.0.tgz","fileCount":82,"unpackedSize":1620484,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd9QuRCRA9TVsSAnZWagAAH6QP/2T+A/DA/BPgY7fbParJ\nzJQn5NC2//4rWn7PaS2GjiYZ91sjOtUvhrKkaf8sEhdPqv6DTQzKz3ISFxlX\nS1h7CSlGUYE8vzpBpY7ouv87gtpvWvtXmmatVfx6CIWCLQEUL1NiTucF9jsG\n8+DQsecXJna1v0lTDFS6LmFxKx1OcKne7GX2I945GAdkyaIN8vJgzP4sqc3b\nwGJoNgmYafNxHGQhCEBQxQohd2AkkKKusDmyilD2jE6SzgpoyNU7Y8J0McGU\n6g+FVchvf6pbAwhgCSVw3ON9A4Lm72sM08gUm4WtcD4/o+EtAtm2zB263zeZ\na0gKKQMW8h22tYuvAhgE1tCg9N98jcb5UvaRdsSTqiQI+g5G/k/U20TG4PLf\n1fTsp8kt717EHuZ98aMShUyuGV3ALi8jVEgZZcGXLtEdN7Y9x7cK/b5gIrFE\nRfkc5xS2IzAuNwNapZI+G6JugW9LIuouDkoH/oa838RXxatQvlPpGHB33g19\njGu819uq6n2DBvsFlt95hDrBAlTbC09A41DvoxSIpFb1wL8LJCC8iG0WaRoL\nG2bTTUL0J3PTMlNpAO0OlvFMdKZDX+PCp/GK4VN5aDiVWC0/pTaiNKwxQn7v\nAqQL/agZXX6BOKwb8t8d26ults0logRkw8q2UjWJ5W4W3YltUf8DgWNKWQPi\nwv3R\r\n=MM9l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEer5qw7/taOTFfpPcERS9ZK4J/LNwGXjGCKJdVDI17gAiAkBCVAXSk4gskgT8LrP61U6R4FmSMThsaYzCNKAFvTsQ=="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_5.0.0_1576340369450_0.3763356694783093"},"_hasShrinkwrap":false},"5.1.0":{"name":"typestately","version":"5.1.0","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","lint":"eslint --ext=ts,tsx src","build":"yarn clean && yarn lint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.8.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.23","@types/react":"^16.9.11","@types/shallowequal":"^1.1.1","@typescript-eslint/eslint-plugin":"^2.9.0","@typescript-eslint/parser":"^2.9.0","babel-eslint":"^10.0.3","eslint":"^6.7.1","eslint-config-prettier":"^6.7.0","eslint-config-react-app":"^5.0.2","eslint-plugin-flowtype":"^4.5.2","eslint-plugin-import":"^2.18.2","eslint-plugin-jsx-a11y":"^6.2.3","eslint-plugin-prettier":"^3.1.1","eslint-plugin-react":"^7.16.0","eslint-plugin-react-hooks":"^2.3.0","jest":"^24.5.0","prettier":"^1.19.1","react":"^16.12.0","redux":"4.0.4","rimraf":"^3.0.0","rxjs":"^6.4.0","ts-jest":"^24.0.0","typescript":"^3.7.2"},"gitHead":"56a6080b7a28fc7dc82c6b81357d4959dd31387e","_id":"typestately@5.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-pV1AYqHAU/RBvM8oeB0Ffl8a3gcrOYDqoXzESy8n8++dc8bLrAuJCd/s8mKAj4mJk//wu6FTpXMzOz7cs7QXOw==","shasum":"b2b1844ff79ed0df2fc4d371973a71a0dc6fdf1d","tarball":"https://registry.npmjs.org/typestately/-/typestately-5.1.0.tgz","fileCount":82,"unpackedSize":1624005,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd93mICRA9TVsSAnZWagAABhQP/04Bl9NM5Ya2+XSoHEdc\na2mpSNW9f6y5dGISDCY6QoGoBYrilP/sQa/04VRP0qKRWy1PqQWbzZQk9Wqm\nWu1J3025XSGOlcMe5Nbix+9RrVOo830TUIK0/jiTwhemTv6TILy68PoABcz/\n6q70hEeJrqvUe1Za7H4eZjYCBv7k45AosEsLafnWUh2tfn0BmLOeztKQQaXc\n8dSmt3L6ShUqKSof4bEYugiCR9KfElrAKgQIBBNP8g2uPAj7PkelHeV6n95B\noVEzig155elCNJqLDlM7bILBCa4grGbY/plZtPcQRr7C8dP3CS7AOkvW4DIF\n1eZyOVOA6ERfxnfJSdYhnp5H1HkdkC3eyYy+7iN3Z8wCoBotfWyZJPCBJKvY\nKUKmDYPcV6+PKmvubZrm6f0GeJ3mlaVTr30a9RzaEI7Jh530I4o/23BGIARm\nlrp1VrWNokdFieM0dO1B/IStOessTLoSCRMbAciZTAVPLiHxOrXtbtPzj87s\ns2EHGHsKM/2nJx93dX5z8KCAdihvdLiVvdHXtq6/x6xI3seVplfKNUAPcz1T\nVBn2UVJaujHjAEfGomoKJWF9+v2s411K7Nf9aOfHD74CMBmaLJohwHqEz3ia\n7y16w/KAmyExlaqCnWnZ0ACWMwC612V9Zl1g0I48AiPeWsYmNua1F+9cQgJQ\naIOp\r\n=Vq/+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYkZMNxHL70U3P2lpKF95Kgmn3g+c/u5ffdN/WhMWS8wIhAM6bQVJHpOHNBVWAkbqvmJ4GS6hPCpH5FMCiXKOyFDnQ"}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_5.1.0_1576499592129_0.5709374730928283"},"_hasShrinkwrap":false},"5.1.1":{"name":"typestately","version":"5.1.1","description":"Recomposed approach of using redux with TypeScript","main":"index.js","repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"keywords":["redux","react","typescript"],"author":{"name":"Heinrich Muralt"},"license":"MIT","bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"homepage":"https://github.com/hmuralt/typestately#readme","scripts":{"clean":"rimraf dist","lint":"eslint --ext=ts,tsx src","build":"yarn clean && yarn lint && tsc","tdd":"jest --env=node --watch","test":"jest --env=node"},"peerDependencies":{"react":"^16.8.0-0","redux":"^4.0.0-0","rxjs":"^6.0.0"},"dependencies":{"shallowequal":"^1.1.0"},"devDependencies":{"@types/jest":"^24.0.23","@types/react":"^16.9.11","@types/shallowequal":"^1.1.1","@typescript-eslint/eslint-plugin":"^2.9.0","@typescript-eslint/parser":"^2.9.0","babel-eslint":"^10.0.3","eslint":"^6.7.1","eslint-config-prettier":"^6.7.0","eslint-config-react-app":"^5.0.2","eslint-plugin-flowtype":"^4.5.2","eslint-plugin-import":"^2.18.2","eslint-plugin-jsx-a11y":"^6.2.3","eslint-plugin-prettier":"^3.1.1","eslint-plugin-react":"^7.16.0","eslint-plugin-react-hooks":"^2.3.0","jest":"^24.5.0","prettier":"^1.19.1","react":"^16.12.0","redux":"4.0.4","rimraf":"^3.0.0","rxjs":"^6.4.0","ts-jest":"^24.0.0","typescript":"^3.7.2"},"gitHead":"fdc88316c4de6cfb2458757a25db80564bc415cc","_id":"typestately@5.1.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"hmuralt","email":"h_muralt@bluewin.ch"},"dist":{"integrity":"sha512-mqShy+MUtB5qexGYXD/kivItj/m4f5G3i6sQ6yBAuLI10NCUoLX8SOy82QvcCVDD54GoA3uL97SSIXTmjJwfmA==","shasum":"35e604601ed6a9e3704c2f866da48c9c07563b7e","tarball":"https://registry.npmjs.org/typestately/-/typestately-5.1.1.tgz","fileCount":82,"unpackedSize":334513,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeA91MCRA9TVsSAnZWagAAkjcP/2foHjL+Z0CeAfY0pgz7\nfTPi6mbLeJCbYg6HJCUvLkUtUVxnvrIdE7CwKrtA6uPNJe8jSlXAIM9+7BQy\nYHjm9m57BTTqd87kb3CBn1PmmTvdY/DsW/E3cC5nSEL58nrCwPhuw4hPeaWI\n0dPo69vLKwmepw13c+rI0630L5k22dL/KVo8TdErfFzu5x4B6W+4r1dCEP18\n7nhplS2T7TJH3ZTadehmKeOP59P4XvzWHjZ5GIq2GeSsfOZztASgw2FoE79h\n6Q0H4BEfhyI/Bx5f2Tp4piOH69dkfxYM+2mGFfArMx47WfvapVXS82I97nd3\niK+EueN3h8NMZlEAXW9EF81S3AJFdQdo9erhe+W9fQ6o0TTndTFtKVmfP3gm\nnmoOTWcu63ue7u0pN3iB9EzvvvDGDUkYuu0nEsjVNi3EURvFRQXx1Ap8tvP7\nLsYNHjXGe0RqbxVreKBH1tCLqgc8hdL6pULgCJMzY67JCnpqRfkUOXezNvFm\n/xFjUBWMe8y0FT2tXfKq2LEEq4guw4F6aUpzgY30ozrUCnOVS3AFECsXhBtH\n+a1EKbtyfq4HU8Hyk9PuQN0hl3mBEAppe4LEFoqaFAyM+5ipB9RAajOBvE3s\nmXgno8K461hLRCRG2XzWUwjfh8o9yJy4fCukqAMYwwxhAcN1M4fZR1pblQiF\nsFlK\r\n=Q1Kd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCpuni26j2p9vtSXWDJyIzELn39AxQX3UTwhMoohJ9bRgIgamk6mqZoz/FMzoKSGDE0EHLFKrj5gS/3QVErt2udGPw="}]},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typestately_5.1.1_1577311563512_0.5387234072617657"},"_hasShrinkwrap":false}},"time":{"created":"2018-07-17T08:13:13.431Z","1.0.1":"2018-07-17T08:13:13.543Z","modified":"2022-05-22T14:03:55.984Z","1.0.2":"2018-07-17T08:28:47.524Z","1.0.3":"2018-07-17T11:21:54.844Z","1.1.0":"2018-07-22T17:44:13.176Z","1.2.0":"2018-07-27T17:47:13.131Z","1.2.1":"2018-08-24T15:11:23.046Z","2.0.0":"2018-08-26T11:57:02.547Z","2.0.1":"2018-08-30T06:37:12.083Z","2.0.2":"2018-09-21T15:21:55.133Z","2.0.3":"2018-09-21T15:35:29.418Z","2.1.0":"2018-12-11T13:46:56.301Z","2.1.1":"2018-12-11T18:51:19.497Z","2.2.0":"2019-05-17T07:16:27.321Z","2.2.1":"2019-05-17T07:21:23.108Z","2.2.2":"2019-05-17T08:10:27.194Z","2.2.3":"2019-05-17T11:28:29.329Z","3.0.0":"2019-05-22T12:02:00.948Z","3.1.0":"2019-05-27T11:59:35.492Z","3.2.0":"2019-06-09T17:50:20.040Z","3.3.0":"2019-06-28T09:14:42.999Z","4.0.0":"2019-09-13T13:09:53.197Z","4.0.1":"2019-09-13T15:07:35.856Z","4.0.2":"2019-09-17T07:24:00.519Z","4.0.3":"2019-09-17T11:50:06.720Z","4.0.4":"2019-09-17T13:21:27.120Z","4.0.5":"2019-09-17T13:39:39.481Z","4.1.0":"2019-11-18T16:53:00.200Z","5.0.0":"2019-12-14T16:19:29.611Z","5.1.0":"2019-12-16T12:33:12.374Z","5.1.1":"2019-12-25T22:06:03.624Z"},"maintainers":[{"name":"hmuralt","email":"h_muralt@bluewin.ch"}],"description":"Recomposed approach of using redux with TypeScript","homepage":"https://github.com/hmuralt/typestately#readme","keywords":["redux","react","typescript"],"repository":{"type":"git","url":"git+ssh://git@github.com/hmuralt/typestately.git"},"author":{"name":"Heinrich Muralt"},"bugs":{"url":"https://github.com/hmuralt/typestately/issues"},"license":"MIT","readme":"# typestately\r\n\r\nRecomposed approach of using redux with TypeScript. An idea showing how you can deal with state management using redux.\r\n\r\n[![build status](https://img.shields.io/travis/hmuralt/typestately/master.svg?style=flat-square)](https://travis-ci.org/hmuralt/typestately)\r\n[![npm version](https://img.shields.io/npm/v/typestately.svg?style=flat-square)](https://www.npmjs.com/package/typestately)\r\n\r\n## Some goals\r\n\r\n- Reduce needed type annotation by making use of type inference\r\n- Reduce boilerplate code\r\n- Encapsulate state details/concerns (e.g. key used for a reducer in the stores state object) in one place\r\n- Easy way to plug new parts of global state in and out\r\n- Support code-splitting\r\n- Support multiple stores\r\n\r\n## Examples/HowTo\r\n\r\nA complete example can be found here: https://github.com/hmuralt/typestately-example\r\n\r\nIt shows the usage with state handlers implemented as classes and an alternative usage with plain objects & functions.\r\n\r\n### Store\r\n\r\nThis is an example of how stores could be setup and registered.\r\n\r\n_StoreContexts.ts_\r\n\r\n```tsx\r\nimport { setupMainStoreContext } from \"./StoreContextSetups\";\r\n\r\nconst storeContexts = {\r\n  Main: setupMainStoreContext()\r\n};\r\n\r\nexport default storeContexts;\r\n```\r\n\r\n_StoreContextSetups.ts_\r\n\r\n```tsx\r\nimport { createStore } from \"redux\";\r\nimport { createStoreContext } from \"typestately\";\r\n\r\nexport function setupMainStoreContext() {\r\n  const store = createStore((state) => state || {});\r\n\r\n  return createStoreContext(store, {});\r\n}\r\n```\r\n\r\n### Counter example with state handler classes\r\n\r\n#### State\r\n\r\n_CounterState.ts_\r\n\r\n```tsx\r\nexport default interface State {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultState: State = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### State handler\r\n\r\n_CounterStateHandler.ts_\r\n\r\n```tsx\r\nclass CounterStateHandler extends StateHandler<State, ActionType> {\r\n  @StateHandler.nested\r\n  public readonly loaderStateHandler: LoaderStateHandler;\r\n\r\n  constructor(loaderStateHandler: LoaderStateHandler) {\r\n    super(\"counter\", defaultState);\r\n\r\n    this.loaderStateHandler = loaderStateHandler;\r\n  }\r\n\r\n  public increment(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Increment,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public decrement(clicked: Date) {\r\n    this.dispatch<ChangeAction>({\r\n      type: ActionType.Decrement,\r\n      clicked\r\n    });\r\n  }\r\n\r\n  public incrementAsync(clicked: Date) {\r\n    this.loaderStateHandler.setStatus(Status.Updating);\r\n    window.setTimeout(() => {\r\n      this.increment(clicked);\r\n      this.loaderStateHandler.setStatus(Status.Done);\r\n    }, 2000);\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Increment)\r\n  protected reduceIncrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value + 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n\r\n  @StateHandler.reducer<State, ActionType>(ActionType.Decrement)\r\n  protected reduceDecrement(state: State, action: ChangeAction) {\r\n    return {\r\n      value: state.value - 1,\r\n      clicked: action.clicked\r\n    };\r\n  }\r\n}\r\n// Ideally managed by IOC container...\r\nconst counterStateHandler = new CounterStateHandler(new LoaderStateHandler());\r\n\r\nexport default counterStateHandler;\r\n```\r\n\r\n#### Component\r\n\r\n_Counter.tsx_\r\n\r\n```tsx\r\nexport interface Props {\r\n  value: number;\r\n  clicked: Date;\r\n  onIncrement: (clicked: Date) => void;\r\n  onIncrementAsync: (clicked: Date) => void;\r\n  onDecrement: (clicked: Date) => void;\r\n}\r\n\r\nexport default class Counter extends React.Component<Props> {\r\n  constructor(props: Props) {\r\n    super(props);\r\n\r\n    this.increment = this.increment.bind(this);\r\n    this.incrementAsync = this.incrementAsync.bind(this);\r\n    this.decrement = this.decrement.bind(this);\r\n  }\r\n\r\n  public render() {\r\n    return (\r\n      <div>\r\n        <p>\r\n          Value: {this.props.value} (clicked: {this.props.clicked.toLocaleString()})\r\n        </p>\r\n        <p>\r\n          <button onClick={this.decrement}>-</button>\r\n          <button onClick={this.increment}>+</button>\r\n        </p>\r\n        <p>\r\n          <button onClick={this.incrementAsync}>+ (async)</button>\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  private increment() {\r\n    this.props.onIncrement(new Date());\r\n  }\r\n\r\n  private incrementAsync() {\r\n    this.props.onIncrementAsync(new Date());\r\n  }\r\n\r\n  private decrement() {\r\n    this.props.onDecrement(new Date());\r\n  }\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n_Counter.ts_\r\n\r\n```tsx\r\ncounterStateHandler.attachTo(storeContexts.Main.hub);\r\n\r\nexport default withStateToProps(\r\n  counterStateHandler,\r\n  (counterState): Props => {\r\n    return {\r\n      value: counterState.value,\r\n      clicked: counterState.clicked,\r\n      onIncrement: (clicked: Date) => counterStateHandler.increment(clicked),\r\n      onIncrementAsync: (clicked: Date) => counterStateHandler.incrementAsync(clicked),\r\n      onDecrement: (clicked: Date) => counterStateHandler.decrement(clicked)\r\n    };\r\n  }\r\n)(Counter);\r\n```\r\n\r\n### Counter example with state handler functions (alternative to classes)\r\n\r\n#### State\r\n\r\n```tsx\r\nexport default interface CounterState {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nexport const defaultCounterState: CounterState = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n```\r\n\r\n#### Actions\r\n\r\n_CounterActions.ts_\r\n\r\n```tsx\r\nexport enum ActionType {\r\n  Increment = \"INCREMENT\",\r\n  Decrement = \"DECREMENT\"\r\n}\r\n\r\nexport interface ChangeAction extends Action<ActionType> {\r\n  type: ActionType;\r\n  clicked: Date;\r\n}\r\n```\r\n\r\n#### Reducer\r\n\r\n```tsx\r\nfunction increment(state: CounterState, action: ChangeAction) {\r\n  return {\r\n    value: state.value + 1,\r\n    clicked: action.clicked\r\n  };\r\n}\r\n\r\nfunction decrement(state: CounterState, action: ChangeAction) {\r\n  return {\r\n    value: state.value - 1,\r\n    clicked: action.clicked\r\n  };\r\n}\r\n\r\nconst counterReducer = createExtensibleReducer<CounterState, ActionType>()\r\n  .handling(ActionType.Increment, increment)\r\n  .handling(ActionType.Decrement, decrement);\r\n\r\nexport default counterReducer;\r\n```\r\n\r\n#### State handler\r\n\r\n```tsx\r\nconst counterStateDefinition = defineState(defaultCounterState)\r\n  .makeStorableUsingKey(\"counter\")\r\n  .setReducer(() => counterReducer)\r\n  .setActionDispatchers({\r\n    increment(dispatch: Dispatch<ActionType>, clicked: Date) {\r\n      dispatch<ChangeAction>({\r\n        type: ActionType.Increment,\r\n        clicked\r\n      });\r\n    },\r\n    decrement(dispatch: Dispatch<ActionType>, clicked: Date) {\r\n      dispatch<ChangeAction>({\r\n        type: ActionType.Decrement,\r\n        clicked\r\n      });\r\n    }\r\n  });\r\n\r\nexport function createCounterStateHandler(hub: Hub) {\r\n  const counterStateHandler = counterStateDefinition.createStateHandler(hub);\r\n  const loaderStateHandler = createLoaderStateHandler(hub, counterStateHandler.contextId);\r\n  const extensions = {\r\n    incrementAsync(clicked: Date) {\r\n      loaderStateHandler.setStatus(Status.Updating);\r\n\r\n      window.setTimeout(() => {\r\n        counterStateHandler.increment(clicked);\r\n\r\n        loaderStateHandler.setStatus(Status.Done);\r\n      }, 2000);\r\n    }\r\n  };\r\n\r\n  return Object.assign(counterStateHandler, extensions, {\r\n    loaderStateProvider: withStateProvider(loaderStateHandler)({})\r\n  });\r\n}\r\n```\r\n\r\n#### Container\r\n\r\n```tsx\r\nconst CounterContainer: React.FC = () => {\r\n  const counterStateHandler = React.useMemo(() => createCounterStateHandler(storeContexts.FunctionsExample.hub), []);\r\n  const counterState = useStateProvider(counterStateHandler);\r\n\r\n  return (\r\n    <Counter\r\n      value={counterState.value}\r\n      clicked={counterState.clicked}\r\n      onIncrement={counterStateHandler.increment}\r\n      onIncrementAsync={counterStateHandler.incrementAsync}\r\n      onDecrement={counterStateHandler.decrement}\r\n    />\r\n  );\r\n};\r\n```\r\n\r\n### State without using redux\r\n\r\nYou can also create a standalone state handler which isn't attached to the redux store and has it's own standalone state.\r\n\r\n```tsx\r\ninterface CounterState {\r\n  value: number;\r\n  clicked: Date;\r\n}\r\n\r\nconst defaultCounterState: CounterState = {\r\n  value: 0,\r\n  clicked: new Date()\r\n};\r\n\r\nfunction increment(state: CounterState, clicked: Date) {\r\n  return {\r\n    value: state.value + 1,\r\n    clicked\r\n  };\r\n}\r\n\r\nfunction decrement(state: CounterState, clicked: Date) {\r\n  return {\r\n    value: state.value - 1,\r\n    clicked\r\n  };\r\n}\r\n\r\nconst counterStateDefinition = defineState(defaultCounterState, { increment, decrement });\r\n\r\nconst counterStateHandler = counterStateDefinition.createStandaloneStateHandler();\r\ncounterStateHandler.increment(new Date());\r\n```\r\n\r\nAnd, you can extend the existing an state definition with Redux if needed.\r\n\r\n```tsx\r\ncounterStateDefinition\r\n  .makeStorableUsingKey(\"counter\")\r\n  .setReducer((stateOperations) => ...) // stateOperations = { increment, decrement } object from defineState call.\r\n  ...\r\n```\r\n","readmeFilename":"README.md"}