{"_id":"@benwiley4000/fair-analytics","_rev":"2-29c703e2386e273dbb99e7b6befeb971","name":"@benwiley4000/fair-analytics","dist-tags":{"latest":"1.2.2-urlencoded"},"versions":{"1.2.2":{"name":"@benwiley4000/fair-analytics","version":"1.2.2","description":"Fair Analytics","main":"lib/index.js","engines":{"node":">=6"},"bin":{"fair-analytics":"bin/index.js"},"scripts":{"dev":"nodemon --ignore stats.json bin/index.js -p 3000 -H localhost","start":"bin/index.js","bump":"standard-version","precommit":"lint-staged","testonly":"ava test/**/*.spec.js --tap | tap-spec","lint":"standard","test":"nyc npm run testonly","build":"npm run lint && npm run test","release":"npm run build && npm run bump && git push --follow-tags origin master && npm publish"},"repository":{"type":"git","url":"git+https://github.com/vesparny/fair-analytics.git"},"keywords":["privacy","fair","api","ga","google","analytics"],"homepage":"https://github.com/vesparny/fair-analytics","authors":["Alessandro Arnodo <alessandro@arnodo.net>"],"license":"MIT","dependencies":{"args":"^3.0.4","body-parser":"^1.17.2","brcast":"^3.0.1","cors":"^2.8.4","enqueue":"1.0.2","express":"^4.15.4","http-status-codes":"^1.2.0","hypercore":"^6.8.0","hyperdiscovery":"^6.0.4","lowdb":"^0.16.2","node-version":"^1.1.0","random-access-memory":"2.4.0","sse-channel":"2.0.6","update-notifier":"^2.2.0"},"devDependencies":{"ava":"^0.22.0","husky":"^0.14.3","lint-staged":"^4.0.4","nodemon":"^1.11.0","nyc":"^11.1.0","prettier":"^1.6.1","request":"^2.81.0","request-promise":"^4.2.0","standard":"^10.0.3","standard-version":"^4.2.0","tap-spec":"^4.1.1","test-listen":"^1.0.2","testdouble":"^3.2.4"},"lint-staged":{"*.js":["prettier --write --semi false --single-quote","standard --fix","git add"]},"nyc":{"include":["lib/**/*.js"],"exclude":["test/**/*.js"],"reporter":["lcov","text"],"all":true},"publishConfig":{"access":"public"},"gitHead":"da83af6b71c7ec8332a6eed9851c52d715df6608","bugs":{"url":"https://github.com/vesparny/fair-analytics/issues"},"_id":"@benwiley4000/fair-analytics@1.2.2","_nodeVersion":"8.10.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-vVlCpY/CbTFMQuj1IIrVmbTxUQVYlFaU10FtHb7HqP505/sAJ2DHvmcKi1spykWJxQcjJr0X8CNTV7jjQuTOMg==","shasum":"316b806499100014ba509c2958eab028527cfdc7","tarball":"https://registry.npmjs.org/@benwiley4000/fair-analytics/-/fair-analytics-1.2.2.tgz","fileCount":21,"unpackedSize":29441,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcoD8lCRA9TVsSAnZWagAArzsP/iCCtrhUWrB29tXgFv0M\nhFN5dHZBg9GaCovS7IOcqk9f8zmdQ/8txadVzj2s7J/Q9PvUT/C7CnWbPT1w\nAYIMH2wzm5dbQkn4CilLFhJap5/fnynWenYZUfjl1BLMpDTfQzXYFfIJFrj+\nn+SCuOcMiKB83HT+bkGvzIEK099ExoUscruoZdJ+F9Ger+UKLfJVYoWblsn/\nkhS2o1r2AVwcjMxrTGK1h3FmgGseXr5UtxoyPLvsoKWhbcArkbMeo/U7FqUK\nP12eSY2O6trOp1miil7DabYUWJY6qSNRPyzsWC+ES5KsrraCu8qvEU5meGxP\ng+s6cG4mIeKUigjGtpyI2QGep3zHbLNue1B+r+HIRhXC9Rns7DggbII4KfGo\nLiI1UPtyMX016JzDNVsmSYUAuvsLitQK4u5gKK5/7Fzf7rct4uowZt+ckE1s\nMPsMIPASrydurOijRBmyryZ1O27G2/w2WKNWKE/0swaLjUXWaHpS/LYT9NPy\nbYS5SA2bMJZZqegEwFCqls8HsZdOmw6+zkMWN2k9yWBFKFsHqU/9Tm1YuwjV\n0npMFoq0Y+HB13MH/9k2iyigjOT5VeqB6dPnNsvX4hdmcOi51vojpBeypgh0\nOtqojf5HLG8mCWhBvL7MIzv+Dhlpc5myalQtOj9LAyX1Y20PadI8/MqMEWRD\n1WtI\r\n=+57U\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEJ7sZezxsXbeJ+zvyCBfOAXUE8VTqaMvdFyU79M9zAQAiEAwm8ReNZzyk5JLcou3ukUB2ssbCZKegTzdIoCExt/ELE="}]},"maintainers":[{"name":"benwiley4000","email":"therealbenwiley@gmail.com"}],"_npmUser":{"name":"benwiley4000","email":"therealbenwiley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/fair-analytics_1.2.2_1554005796694_0.29303584826427276"},"_hasShrinkwrap":false},"1.2.2-urlencoded":{"name":"@benwiley4000/fair-analytics","version":"1.2.2-urlencoded","description":"Fair Analytics","main":"lib/index.js","engines":{"node":">=6"},"bin":{"fair-analytics":"bin/index.js"},"scripts":{"dev":"nodemon --ignore stats.json bin/index.js -p 3000 -H localhost","start":"bin/index.js","bump":"standard-version","precommit":"lint-staged","testonly":"ava test/**/*.spec.js --tap | tap-spec","lint":"standard","test":"nyc npm run testonly","build":"npm run lint && npm run test","release":"npm run build && npm run bump && git push --follow-tags origin master && npm publish"},"repository":{"type":"git","url":"git+https://github.com/vesparny/fair-analytics.git"},"keywords":["privacy","fair","api","ga","google","analytics"],"homepage":"https://github.com/vesparny/fair-analytics","authors":["Alessandro Arnodo <alessandro@arnodo.net>"],"license":"MIT","dependencies":{"args":"^3.0.4","body-parser":"^1.17.2","brcast":"^3.0.1","cors":"^2.8.4","enqueue":"1.0.2","express":"^4.15.4","http-status-codes":"^1.2.0","hypercore":"^6.8.0","hyperdiscovery":"^6.0.4","lowdb":"^0.16.2","node-version":"^1.1.0","random-access-memory":"2.4.0","sse-channel":"2.0.6","update-notifier":"^2.2.0"},"devDependencies":{"ava":"^0.22.0","husky":"^0.14.3","lint-staged":"^4.0.4","nodemon":"^1.11.0","nyc":"^11.1.0","prettier":"^1.6.1","request":"^2.81.0","request-promise":"^4.2.0","standard":"^10.0.3","standard-version":"^4.2.0","tap-spec":"^4.1.1","test-listen":"^1.0.2","testdouble":"^3.2.4"},"lint-staged":{"*.js":["prettier --write --semi false --single-quote","standard --fix","git add"]},"nyc":{"include":["lib/**/*.js"],"exclude":["test/**/*.js"],"reporter":["lcov","text"],"all":true},"publishConfig":{"access":"public"},"gitHead":"886cf6a1fc919b38cf7a402ef85b99809af90f06","bugs":{"url":"https://github.com/vesparny/fair-analytics/issues"},"_id":"@benwiley4000/fair-analytics@1.2.2-urlencoded","_nodeVersion":"8.10.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-vdd+Vg4snPULTKNp2fEbwjwvFetjrLjLmLQgLD7Win5VOJABZ5vjVUi8nLsB6mVzhkN91fSAsTggQ9MAXKCVfQ==","shasum":"99d584fafdc623a9ab9e022efc87eaf0d2033b96","tarball":"https://registry.npmjs.org/@benwiley4000/fair-analytics/-/fair-analytics-1.2.2-urlencoded.tgz","fileCount":21,"unpackedSize":29487,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcoYZCCRA9TVsSAnZWagAAM3wP/1zme6RZgGdhIHfSIQGg\nLAe1nqtMmwA9Kmtt+KjHiL5xrmM1mrWuENJ7pI6xYrTysPAj+mFdVkA94ozI\nNzboxs9vfeMqHF4gaBh8V6wGCYT/kQKXUtHBGGMxeke+mQK1zyy9NCtfAoMv\ntAztPLQw0ZvTOIXTSUkDP3gLl569/fqxLJRiJveQFt8eoYMlf8WTITk39yYl\nOckGyurWgdaWQzGfbBnA/x4VHiJFdCynnM7olxajO7jVNbJe6zC9QsVuuxpY\nCxodxFyUDi99QhmYHcVoPxUPkTZPNn4oxQoDq24zSCyDRbDLQF4yY8z+ep92\n1/yGa5CT3hrqugwtn/XQV8qR/0OVGY6IY+QfnvSsL7PuBfFhDPSSpP83OptY\n8g5m10nSitdpZzw/SNO99EmA0VG97oPU+rclCUEdXhT1fBJEOddCLqku/gPP\n7J7oH5tLlijBnaCkqShKN51HWrAZIemHw0pFCJHwzuLaRacO2nBjaTly25nV\nZ9CMsODM9bNX/7rDTjJxkWnhLW6FVBWrR2qadNqKkQI9oySG7CTqRTVHyWPb\no5X5VjEWSaz7fcNzUmLomF8aRAqfo7ZWsdI1nvRBZ/16NAzuoyNrEO6xjLLd\nKeTu4AxOp6ELeq1UKGSGuniXH8VT61RSpRM1DiGHLw6PEGCpw8Q+ZJkcYA0l\n2LAQ\r\n=3kGo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAh8KT2GtYIUvB0CrlAALcGbE1WQ9gSiT4X9KI9WLfrQAiB6vZB4N3n9rW0RNrdM1idI7sfjGEoZfvjdNYxvvu4ctw=="}]},"maintainers":[{"name":"benwiley4000","email":"therealbenwiley@gmail.com"}],"_npmUser":{"name":"benwiley4000","email":"therealbenwiley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/fair-analytics_1.2.2-urlencoded_1554089537521_0.36081910169942844"},"_hasShrinkwrap":false}},"time":{"created":"2019-03-31T04:16:36.501Z","1.2.2":"2019-03-31T04:16:36.910Z","modified":"2022-04-04T18:28:28.790Z","1.2.2-urlencoded":"2019-04-01T03:32:17.646Z"},"maintainers":[{"name":"benwiley4000","email":"therealbenwiley@gmail.com"}],"description":"Fair Analytics","homepage":"https://github.com/vesparny/fair-analytics","keywords":["privacy","fair","api","ga","google","analytics"],"repository":{"type":"git","url":"git+https://github.com/vesparny/fair-analytics.git"},"bugs":{"url":"https://github.com/vesparny/fair-analytics/issues"},"license":"MIT","readme":"# Fair Analytics\n\n> An analytics server that doesn't undermine user's privacy\n\n[![Travis](https://img.shields.io/travis/vesparny/fair-analytics.svg)](https://travis-ci.org/vesparny/fair-analytics)\n[![Code Coverage](https://img.shields.io/codecov/c/github/vesparny/fair-analytics.svg?style=flat-square)](https://codecov.io/github/vesparny/fair-analytics)\n[![David](https://img.shields.io/david/vesparny/fair-analytics.svg)](https://david-dm.org/vesparny/fair-analytics)\n[![npm](https://img.shields.io/npm/v/fair-analytics.svg)](https://www.npmjs.com/package/fair-analytics)\n[![npm](https://img.shields.io/npm/dm/fair-analytics.svg)](https://npm-stat.com/charts.html?package=fair-analytics&from=2017-04-01)\n[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n[![MIT License](https://img.shields.io/npm/l/fair-analytics.svg?style=flat-square)](https://github.com/vesparny/fair-analytics/blob/master/LICENSE)\n\n## Motivations?\n\nGoogle Analytics is the de-facto standard in the web and mobile analytics service world.\n\n* It's easy to setup and start tracking users behaviors\n* It provides advanced reporting features.\n\nBut it has several serious privacy implications:\n\n* Most of the time personal data is collected without the explicit consent of the user, hence it undermines user's privacy\n* It's closed-source\n* It does not embrace transparency at all\n* Users cannot access tracked data because data ownership is granted only to the website/app owner (and sadly to Google)\n* It targets specific users and data collected is not anonymous\n\nInspired by an [interesting article](https://staltz.com/open-analytics.html) from [@staltz](https://github.com/staltz), and from the awesome work done by the [micro-analytics](https://github.com/micro-analytics/micro-analytics-cli) team, I decided to start working on a Google Analytics alternative.\n\n## What is Fair Analytics\n\nFair Analytics is an open, transparent, distributed and fair Google Analytics alternative.\n\n## Key features\n\n* **Fair** - It's meant to provide lightweight and anonymous analytics about traffic and usage, not to track behaviors nor geographical locations of users\n* **Distributed** - Raw traffic data is written in an append-only, secure, and distributed log. It uses [hypercore](https://github.com/mafintosh/hypercore) under the hood\n* **Transparent** - Raw traffic data is accessible to anyone. This makes it auditable and gives back its ownership to the crowd\n* **Easy** - It's easy to setup\n* **Flexible** - Even though Fair Analytics only stores raw data, it's pretty easy to listen to incoming events, enabling the user to manipulate/aggregate raw data in order to provide graphs or charts. Get fancy if you want to.\n\n\n## Setup\n\nThere are 2 ways of running Fair Analytics\n\n### CLI\n\n```bash\nnpm install -g fair-analytics\n\nfair-analytics\n\n```\n\nThe command accepts some options:\n\n```bash\n$ fair-analytics --help\n\n  Usage: fair-analytics [options] [command]\n\n  Commands:\n\n    help  Display help\n\n  Options:\n\n    -h, --help                       Output usage information\n    -H, --host [value]               Host to listen on (defaults to \"0.0.0.0\")\n    -m, --memory                     Use in-memory storage (disabled by default)\n    -o, --origin [value]             Accepts POST requests only from a specified origin (defaults to \"*\")\n    -p, --port <n>                   Port to listen on (defaults to 3000)\n    -s, --storage-directory [value]  Storage directory (defaults to process.cwd())\n    -v, --version                    Output the version number\n```\n\nThe instance is now running at `http://localhost:3000`\n\n### Programmatically\n\nAdd fair-analytics as a dependency to your project\n\n```js\nconst path = require('path')\nconst fa = require('fair-analytics')\n\nconst server = fa({\n  storageDirectory: path.resolve(__dirname)\n})\nconst { feed } = server\n\nfeed.on('ready', () => {\n  server.listen(3000, '0.0.0.0')\n})\n```\n\nThe instance is now running at `http://localhost:3000`\n\n## Deploy\n\nTODO\n\n* nginx\n* docker\n\n\n## Usage\n\n### Track events\n\nThe quickest way to start tracking usage is to use [fair-analytics-client-api](https://github.com/vesparny/fair-analytics-client-api)\n\nExample usage:\n\n```js\nimport fairAnalytics from 'fair-analytics-client-api'\n\n// create a fa instance\nconst fa = fairAnalytics({\n  url: 'https://fa.yoursite.com' // the URL of your hosted Fair Analytics instance\n})\n\n// track events\nfa.send({\n  event: 'pageView', // event is mandatory and can be anything\n  pathname: window.location.pathname\n})\n.then(res => {\n  if (res.ok) {\n    console.log('success')\n  }\n})\n.catch(err => {\n  console.error(err.message)\n})\n```\n\nPlease refer to the [fair-analytics-client-api documentation](https://github.com/vesparny/fair-analytics-client-api/#readme) for further details\n\n### Endpoints\n\nFair Analytics responds to 3 endpoints:\n\n##### GET /\n\nResponds with a basic homepage, displaying the `feed.key`\n\n##### POST /\n\nUsed to POST tracked events.\nResponds with 204 in case of success (the body MUST be an object containing at least an `event` parameter)\n\n##### GET /_live\n\nGets realtime updates via [server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)\nUseful to create real-time dashboards\n\nConsuming real-time data is as easy as:\n\n```js\nif (window.EventSource) {\n  const source = new window.EventSource('https://fa.mysite.com/_live')\n\n  source.addEventListener('fair-analytics-event', (e) => {\n    console.log(e)\n  })\n\n  source.addEventListener('open', () => {\n    console.log('Connection was opened')\n  })\n\n  source.addEventListener('error', e => {\n    if (e.readyState === window.EventSource.CLOSED) {\n      console.log('Connection was closed')\n    }\n  })\n}\n```\n\n##### GET /_stats\n\nProvides an aggregated view of all the events stored, grouped by `event` and `pathname`\nIn this case data is persisted to a local JSON file using [lowdb](https://github.com/typicode/lowdb)\n\nHere is an example response:\n\n```json\n{  \n   \"pageView\":{  \n      \"/home\":{  \n         \"times\":640,\n         \"last\":\"2017-05-04T12:36:31.514Z\"\n      },\n      \"/about\":{  \n         \"times\":40,\n         \"last\":\"2017-05-04T12:36:31.514Z\"\n      }\n   }\n}\n```\n\n### Replicate raw data\n\nAs we said Fair Analytics is distributed.\nIt's easily possible to replicate raw data.\n\n```js\nconst hypercore = require('hypercore')\nconst swarm = require('hyperdiscovery')\nconst KEY = 'A FAIR ANALYTICS FEEED KEY'\nconst LOCALPATH = './replicated.dataset'\n\nconst feed = hypercore(LOCALPATH, KEY, {valueEncoding: 'json'})\nswarm(feed)\n\nfeed.on('ready', () => {\n  // this configuration will download all the feed\n  // and process new incoming data\n  // via the feed.on('data') callback\n  // in case you want to process all the feed (old and new)\n  // use only {tail: true, tail: true}\n\n  feed.createReadStream({\n    tail: true,\n    live: true,\n    start: feed.length,\n    snapshot: false\n  })\n  .on('data', console.log) // Use this callback to precess data as you like\n})\n```\n\n## Tests\n\n```sh\n$ npm test\n```\n\n## Change Log\n\nThis project adheres to [Semantic Versioning](http://semver.org/).  \nEvery release, along with the migration instructions, is documented in the [CHANGELOG.md](https://github.com/vesparny/fair-analytics/blob/master/CHANGELOG.md) file.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}