{"_id":"@alexlafroscia/service-locator","_rev":"3-6864e506ae16c8cf7cf8866b524c3efc","name":"@alexlafroscia/service-locator","description":"Serice locator pattern for ES6 classes","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@alexlafroscia/service-locator","version":"1.0.0","description":"Serice locator pattern for ES6 classes","main":"dist/index.js","license":"MIT","module":"lib/index.js","files":["dist","lib"],"scripts":{"build":"rollup lib/index.js --o dist/index.js -f umd --name 'service-locator'","doc":"esdoc","doc:open":"open docs/index.html","lint":"eslint .","lint:fix":"eslint --fix .","pretest":"yarn build","test":"ava"},"devDependencies":{"ava":"^0.24.0","esdoc":"^1.0.4","esdoc-standard-plugin":"^1.0.0","eslint":"^4.13.1","eslint-config-prettier":"^2.9.0","eslint-plugin-prettier":"^2.3.1","faker":"^4.1.0","prettier":"^1.9.2","rollup":"^0.52.1"},"gitHead":"b86fc309ed9510335a1ad293a5fdad9a4b6c100d","_id":"@alexlafroscia/service-locator@1.0.0","_npmVersion":"5.5.1","_nodeVersion":"9.2.0","_npmUser":{"name":"alexlafroscia","email":"alex@lafroscia.com"},"dist":{"integrity":"sha512-bjl2y+yLCGR3czE1MwQMH98KBCV1GYhvDwxgbNFT0gYYLuRSVRognxlf/ewz6WrvhFWPmviCqBIogwP+kgY+Pw==","shasum":"b51741e07c514f59f4dbef25e7a73a94cf7ed5d9","tarball":"https://registry.npmjs.org/@alexlafroscia/service-locator/-/service-locator-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCpq7vJU7NBsyhiDLfsv7RokrALAYK9fZnwKplRSPuikgIgQLOJe7hdKfYVqNbVtV2apcRv0hU0E1OQSQXXAetL6Bg="}]},"maintainers":[{"name":"alexlafroscia","email":"alex@lafroscia.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/service-locator-1.0.0.tgz_1513216071842_0.5444920051377267"}},"1.1.0":{"name":"@alexlafroscia/service-locator","version":"1.1.0","description":"Serice locator pattern for ES6 classes","main":"dist/index.js","license":"MIT","module":"lib/index.js","files":["dist","lib"],"scripts":{"build":"rollup lib/index.js --o dist/index.js -f umd --name 'service-locator'","doc":"esdoc","doc:open":"open docs/index.html","lint":"eslint .","lint:fix":"eslint --fix .","prepublish":"yarn build","pretest":"yarn build","test":"ava"},"devDependencies":{"ava":"^0.24.0","esdoc":"^1.0.4","esdoc-standard-plugin":"^1.0.0","eslint":"^4.13.1","eslint-config-prettier":"^2.9.0","eslint-plugin-prettier":"^2.3.1","faker":"^4.1.0","prettier":"^1.9.2","rollup":"^0.52.1"},"gitHead":"b9b90df607555634ca64d3b3c65ac522e1c2c821","_id":"@alexlafroscia/service-locator@1.1.0","_npmVersion":"5.5.1","_nodeVersion":"9.2.0","_npmUser":{"name":"alexlafroscia","email":"alex@lafroscia.com"},"dist":{"integrity":"sha512-jMzlIUTce8ezK5+MBhr3fUT3KjUzYDk8fTEpmsFfGMQNC+P2dFc/cFtqQTKHFwhAwjvHurXy3ywzQYDhfePHHw==","shasum":"ed4d6b831a502426947f157357b1685459db4022","tarball":"https://registry.npmjs.org/@alexlafroscia/service-locator/-/service-locator-1.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC+WffkoS8TeWumjM6JEmZlZ3E38MpiCLm6yvmiFiiXGAIhAJCrlljG6T5yWXfmukPMgaQwmUKIoPUvGRThgO6z4H4K"}]},"maintainers":[{"name":"alexlafroscia","email":"alex@lafroscia.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/service-locator-1.1.0.tgz_1513287362349_0.2627602599095553"}},"1.2.0":{"name":"@alexlafroscia/service-locator","version":"1.2.0","description":"Serice locator pattern for ES6 classes","main":"dist/index.js","license":"MIT","module":"lib/index.js","files":["dist","lib"],"scripts":{"build":"rollup lib/index.js --o dist/index.js -f umd --name 'service-locator'","doc":"esdoc","doc:open":"open docs/index.html","lint":"eslint .","lint:fix":"eslint --fix .","prepublish":"yarn build","pretest":"yarn build","test":"ava"},"devDependencies":{"ava":"^0.24.0","babel-eslint":"^8.0.3","babel-plugin-transform-class-properties":"^6.24.1","babel-plugin-transform-decorators-legacy":"^1.3.4","esdoc":"^1.0.4","esdoc-ecmascript-proposal-plugin":"^1.0.0","esdoc-standard-plugin":"^1.0.0","eslint":"^4.13.1","eslint-config-prettier":"^2.9.0","eslint-plugin-prettier":"^2.3.1","faker":"^4.1.0","prettier":"^1.9.2","rollup":"^0.52.1"},"ava":{"babel":{"plugins":["transform-decorators-legacy","transform-class-properties"],"presets":["@ava/stage-4"]}},"gitHead":"8388864a9becb6c113f97dce81e2bf9b84dfc4cb","_id":"@alexlafroscia/service-locator@1.2.0","_npmVersion":"5.5.1","_nodeVersion":"9.2.0","_npmUser":{"name":"alexlafroscia","email":"alex@lafroscia.com"},"dist":{"integrity":"sha512-QQISDBoN8LyLjog+TXcD7OEVjH2h0CwIVdCYenq54i1eEAJERbmPYs215ppN6i2j3ibHYLcd1prWZCcUYkf1dA==","shasum":"0c1f4536962bfb8438a756c4fe008c9555cd6644","tarball":"https://registry.npmjs.org/@alexlafroscia/service-locator/-/service-locator-1.2.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDy2tRNAyjrVPd0+Dh+3iSmF+qNghENA7T/Sde5FGkhYAIhAK3FgynWSK5aEGl8n9yPYqAyflxq3ASyjp7/PHVrp1Ze"}]},"maintainers":[{"name":"alexlafroscia","email":"alex@lafroscia.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/service-locator-1.2.0.tgz_1513302380473_0.047829794231802225"}}},"readme":"# @alexlafroscia/service-locator\n\nA JS implementation of the [Service Locator pattern][service locator pattern] for ES6 classes.\n\n## Features\n\n- Store commonly-needed values in a single place, allowing easy access to shared state\n- Inject registry access into any ES6 class through a mixin, or extend the provided ES6 class\n- Easily provide stubs for objects in the registry to simplify testing\n\n## A quick example\n\nImagine we have a component that should check if the user is logged in and either prompt for login, or greet the user. We have two parts: fetching the user data, and the component itself.\n\nIf you were to use this package, here is how the code might be set up (note that I'm using a fake Component implementation that is something similar to React or Preact):\n\n```javascript\nimport { registry, RegistryAccess } from '@alexlafroscia/service-locator';\n\nclass UserService {\n  fetchUserInfo() {\n    return fetch('...').then(res => res.json());\n  }\n\n  async isLoggedIn() {\n    const { isLoggedIn } = await this.fetch('...');\n\n    return isLoggedin;\n  }\n};\n\nregistry.register('userService', new UserService());\n\nexport default class LoggedInComponent extends RegistryAccess.Mixin(Component) {\n  async getInitialState() {\n    const isLoggedIn = this.userService.isLoggedIn();\n    this.setState({ isLoggedIn });\n  }\n\n  render({ isLoggedIn }) {\n    return isLoggedIn ? 'Hello!' : 'Please log in!';\n  }\n}\n```\n\nWhat's the benefit here? For one, we've separated out the thing that fetches the data from the thing that displays it, which is always a good idea. Additionally, we made it easy to stub the data fetching in a test:\n\n```javascript\ntest('shows the right thing when the user is logged in', () => {\n  registry.stub('userService', {\n    async fetchUserInfo() {\n      return { isLoggedIn: true };\n    }\n  });\n\n  const result = render(<Component />);\n  expect(result).to.contain('Hello!');\n});\n\ntest('shows the right thing when the user is not logged in', () => {\n  registry.stub('userService', {\n    async fetch() {\n      return { isLoggedIn: false };\n    }\n  });\n\n  const result = render(<Component />);\n  expect(result).to.contain('Please log in!');\n});\n```\n\n## Could you make this easier?\n\nIn fact, you can. I _love_ the syntax that Ember provides for injecting services, and wanted to emulate that as closely as possible. Through the power of [decorators][decorators] I was able to do it. The downside is that you need a [Babel transform for it][decorators-babel-transform], but with that in place, we can clean up the implementation a whole lot. Rather than repeating an extended example, check out the examples in the tests.\n\n\n## Why?\n\nI've struggled with making a complex set of components using [Skate.js][skate] where all components needed access to some state. I didn't want to have pass the properties to every component explicitly, and wished I had an easy way of using service injection the way that I'm used to with [Ember.js][ember]. So, I started messing around with this.\n\n## Should I use this?\n\nMaybe. In reality, it's not that different than just accessing everything off the `window`, and we all know that's a bad idea (although this works in a Node environment where `window` isn't available, and is built for use with JavaScript modules where there isn't a shared global context).\n\n## Compatibility Notes\n\nThis package is meant to be consumed in an ES6 environment. It relies on [Proxy][proxy] and is built with ES6 classes in mind. Make sure your environment can handle this.\n\n## Prior Art\n\n- [Ember.js service injection][ember service injection]\n\n[service locator pattern]: https://martinfowler.com/articles/injection.html\n[skate]: https://github.com/skatejs/skatejs\n[ember]: https://www.emberjs.com/api/ember/2.17/classes/@ember%2Fservice/methods/inject?anchor=inject\n[ember service injection]: https://www.emberjs.com/api/ember/2.17/classes/@ember%2Fservice/methods/inject?anchor=inject\n[proxy]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy\n[decorators]: https://github.com/tc39/proposal-decorators\n[decorators-babel-transform]: https://www.npmjs.com/package/babel-plugin-transform-decorators-legacy\n","maintainers":[{"name":"alexlafroscia","email":"alex@lafroscia.com"}],"time":{"modified":"2022-04-04T12:41:04.323Z","created":"2017-12-14T01:47:51.903Z","1.0.0":"2017-12-14T01:47:51.903Z","1.1.0":"2017-12-14T21:36:02.574Z","1.2.0":"2017-12-15T01:46:20.652Z"},"license":"MIT","readmeFilename":"README.md"}