{"_id":"@brandwatch/remimi","_rev":"1-23c57c7f07541bd10cac8b91b3575050","name":"@brandwatch/remimi","dist-tags":{"latest":"3.0.0"},"versions":{"3.0.0":{"name":"@brandwatch/remimi","version":"3.0.0","description":"Redux Mixpanel Middleware","main":"dist/index.js","scripts":{"build":"rm -rf dist && mkdir dist && babel src --out-dir dist","test":"mocha","lint":"eslint src/**","ci":"npm run test && npm run lint","prepublish":"npm run test && npm run lint && npm run build"},"repository":{"type":"git","url":"git+https://github.com/BrandwatchLtd/remimi.git"},"keywords":["Redux.","Middleware","Mixpanel"],"author":{"name":"Brandwatch Engineering"},"license":"MIT","private":false,"bugs":{"url":"https://github.com/BrandwatchLtd/remimi/issues"},"homepage":"https://github.com/BrandwatchLtd/remimi#readme","devDependencies":{"babel-cli":"6.11.4","babel-core":"6.11.4","babel-plugin-transform-object-rest-spread":"6.8.0","babel-preset-es2015":"6.9.0","chai":"3.5.0","eslint":"3.1.1","jsdom":"9.4.1","jsdom-global":"2.0.0","mocha":"^6.2.0","sinon":"^7.4.2"},"dependencies":{"mixpanel-browser":"^2.29.1"},"gitHead":"e1eb3c8e40272d6d6b316ac1673bf4743384ae03","_id":"@brandwatch/remimi@3.0.0","_nodeVersion":"10.10.0","_npmVersion":"6.11.3","dist":{"integrity":"sha512-olwGyk/Qn7M959WL6p4c1GRFPNTzf/1kq3nfNuhKjRQKiKtzYujNKFYVwOa/1VtqguFHimgRJsh5E48uS0KTpQ==","shasum":"542b96c3d6fa02fd9c48c015240e08ef1993c160","tarball":"https://registry.npmjs.org/@brandwatch/remimi/-/remimi-3.0.0.tgz","fileCount":9,"unpackedSize":12732,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdiNdyCRA9TVsSAnZWagAAGwYQAJBCU2RMXvpiPMB3bc7S\nNEvAsooroDkCRCx9ia8qP202S3zBbYHLlw551V9FD5qvlt2Tp8Xl/Rr51wPr\n39jfVXkTUPK/zmfGtlvxfZ6j1eOpve3+JmgYtKK4CMPtnB5j6rBXw9mZq9lr\n4iWlCQAR4giUverukyIxKWVLcMtrom1XoMXo73KCXIbDNbPDSaZB2N+9VCCs\ngW89rkXs6fHLFGoGZ3a01/BIfj5vgpiFfbCxRZnwyHiWJhOBf8mZkSH7kYxh\nw9VPYRmUUoKrpizU8oybzwvGvyeh2CGR1FhzeNx9CbUfuH0CQP1RykPv+db3\n294ASw1U8vSqL3W8W4Xy4P+8r/tvm49NWP4kVwoaTXOcdye+J5I3oePe2S8v\ndKz0Ag2Rf5c4ZbgcYp8Xyj530LZAEILf5BqzPV0zb8MB7GgfETAgYcRuPT2t\n7xeQ4QYJk9dsGfcIF6rak0ZBlouB+ODpIeP4oKFzOgBkU6g2dNYMexJJmJvd\nadVBfKUVDZ0p4DZTqR8WwB1IQ+7IffgQCnOxBH60MzbbNflbKhOGIBfTjGIK\n83cpm8tNSgd8xYNx7NOFEM7cyk7x/B06dQVYz76ly0vjzjz8cXsJd9joayEf\nqnSVN7Q7/XnqcOE4hladFJqg41Lb7AI+aUS6OxBCPfGEsNbwqMGJYLtJOBne\nYBC6\r\n=AZ5j\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDy0xUDy+EBtjjbWJoken4RZ+KfIGdXMhf8XkZKv3pAGAiAfd+Ex2XOiPYF2ASYUFOb42MZ6DElQ0uwpWxFwt/VobQ=="}]},"maintainers":[{"name":"brandwatch","email":"opensource@brandwatch.com"}],"_npmUser":{"name":"brandwatch","email":"opensource@brandwatch.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/remimi_3.0.0_1569249136358_0.4647222751144682"},"_hasShrinkwrap":false}},"time":{"created":"2019-09-23T14:32:16.114Z","3.0.0":"2019-09-23T14:32:17.722Z","modified":"2022-04-04T20:26:45.404Z"},"maintainers":[{"name":"brandwatch","email":"opensource@brandwatch.com"}],"description":"Redux Mixpanel Middleware","homepage":"https://github.com/BrandwatchLtd/remimi#readme","keywords":["Redux.","Middleware","Mixpanel"],"repository":{"type":"git","url":"git+https://github.com/BrandwatchLtd/remimi.git"},"author":{"name":"Brandwatch Engineering"},"bugs":{"url":"https://github.com/BrandwatchLtd/remimi/issues"},"license":"MIT","readme":"# remimi - Redux Mixpanel Middleware\n\n[![Build Status](https://travis-ci.org/BrandwatchLtd/remimi.svg?branch=master)](https://travis-ci.org/BrandwatchLtd/remimi)\n\nAdvanced Client Redux Mixpanel Middleware.\n\n# Installation\n\n`npm install --save remimi`\n\n# Basic Configuration\n\n```js\nimport { createStore } from 'redux';\nimport mixpanelMiddleware from 'remimi';\n\nimport reducer from './your-reducers';\n\nlet store = createStore(reducer, ['Initial State'], mixpanelMiddleware(token, /*options*/));\n```\n\nThis is very basic usage. You want to setup the Profiles for application in production.\n\n# Advanced configuration - Profile\n\n> Mixpanel allows you to tie data to a specific user, creating a profile. This is where you store things like their email address, where they came from, or their age.\n\nhttps://mixpanel.com/help/reference/creating-a-profile\n\nFunction (optional) provided as second argument to middleware should be selector returning flat object for given state, see some examples below.\nMiddlewares requires unique identifier of an user, which is just standard id. Provide function to get the id from state.\n\n```js\nconst uniqueIdSelector = state => state.me.id; // unique identifier\nconst personSelector = state => state.me; // data passed down to mixpanel\nlet store = createStore(\n  reducer,\n  ['Initial State'],\n  mixpanelMiddleware(token, {\n    personSelector: personSelector,\n    uniqueIdSelector: uniqueIdSelectorm\n  })\n);\n```\n\n## Example example\n\n```js\nfunction getPerson(state) {\n    const {\n        auth: {\n            user: {\n                id,\n                username,\n                firstName,\n                lastName,\n                client: {\n                    id: clientId,\n                    name: clientName,\n                } = {},\n            } = {},\n        },\n    } = state;\n\n    const person = {\n        clientId: clientId,\n        clientName: clientName,\n        $first_name: firstName,\n        $last_name: lastName,\n        $email: username,\n    };\n}\n```\n\n## Notes\n> Special properties have a leading \"$\". You shouldn't make up your own property names beginning with \"$\".\n\nList of special properties\nhttps://mixpanel.com/help/questions/articles/special-or-reserved-properties\n\n# Use human-friendly names\n\n> Developers implementing Mixpanel are sometimes tempted to use camel case, underscores, or obscure function names. We recommend choosing names that are easy to understand yet also convey the precise meaning for your Events. So for the example above, instead of calling the signup Event something like “newuser_su_done,” simply call it “Sign up complete” - that way, anyone looking at your project understand what action triggers that Event.\n\nMixpanel recommmend to use human names for action types and properties. You can pass formatter functions to library for humanizing names. I recommend to use existing package for humanizing the names e.g. https://www.npmjs.com/package/humanize-string\n\n## Action Types\n\n```\nmixpanelMiddleware(token, {actionTypeFormatter: actionType => `---${actionType}---`}); // event will look like '---Action---'\n```\n\n## Properties and Increment name\n\n```\nmixpanelMiddleware(token, {propertyFormatter: property => `---${property}---`}); // mixpanel custom properties will look like '---Property---'\n```\n\n## Values\n```\nmixpanelMiddleware(token, {valueFormatter: value => `---${value}---`}); // mixpanel custom properties will look like '---Value---'\n```\n\n\n# Redux Actions\n\n## Event\n\n```js\n\nconst action = {\n    type: 'Login',\n    meta: {\n        mixpanel: {\n            eventName: 'Some event',\n            props: {\n                source: 'website',\n            },\n        },\n    },\n}\n```\n\n## Override Redux Action Type\nYou can use this option in case the action type is not descriptive enough, or you are moving tracking across actions but already collected some data.\n\n```js\nconst action = {\n    type: 'Login',\n    meta: {\n        mixpanel: {\n            eventName: 'Some event',\n            type: 'Login via API' // !!! this will take precedence over the Redux type\n            props: {\n                source: 'website',\n            },\n        },\n    },\n}\n\n```\n\n## Increment\n\n> You can use mixpanel.people.increment to change the current value of numeric properties. This is useful when you want to keep a running tally of things, such as games played, messages sent, or points earned.\n\n```js\n// counting logins\nconst action = {\n   type: 'Login',\n   meta: {\n     mixpanel: {\n         eventName: 'Some event',\n         increment: ['login', 1], // or\n         increment: {'login': 1, 'logout': 2}, // or\n         increment: 'login'\n     },\n   },\n}\n```\n\nYou can combine standard `events` with `increments`\n\n# Warning\nThis is **client side mixpanel** middleware, it should be possible to make universal and support server side rendering.\n\nUntil then, you need to wrap in condition. Mixpanel-browser package requires `window` to be set, otherwise it crashes.\n\n```js\n  const middlewares = [];\n  if (__CLIENT__) {\n    middlewares.push(require('remimi').default(token, { personSelector, idSelector }));\n  }\n```\n\n\nLibrary mixpanel-node https://github.com/mixpanel/mixpanel-node could be used to make middleware universal.\n\n# Development\n\n`npm test`\n\n## Contributions\n\nContributions are very appreciated and welcome. We promise you a prompt response. Feel free to drop message to [kamil](https://twitter.com/kkamilio) if you have any questions.\n\n# Credits\nThanks to [Harry](https://twitter.com/hogg_io) and [Andy](https://twitter.com/andrew_polhill) for implementing the middleware! Kudos to them.\n\n:heart: :heart:  :heart: [Brandwatch](https://www.brandwatch.com/careers/) is looking for talented engineers in Brighton, Berlin and __Stuttgart__. :heart: :heart: :heart:\n","readmeFilename":"README.md"}