{"_id":"@alexmacarthur/power-plant","_rev":"7-c7cbea85716dbec870e76ca89bebdb23","name":"@alexmacarthur/power-plant","dist-tags":{"latest":"0.0.7"},"versions":{"0.0.0":{"name":"@alexmacarthur/power-plant","version":"0.0.0","keywords":[],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.0","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"dist":{"shasum":"6243a3fecb2f7bc9414051113cd37044160320d1","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.0.tgz","fileCount":2,"integrity":"sha512-IdnKAT+FibZE7SMXFdSM2O7xm7ouYwXCtcXjLYcQ14ZmerC7h3Jn2gVTlaqcVRvfOXBAI9oJU5negMZGQz1E3Q==","signatures":[{"sig":"MEQCIG/jZ/k0pLa8dy5awI72ydZem5g6p8+ZUih9+FJ76X0DAiBMeOxgtlBUdMNzoqttK3C4X3A1etWE2Y2K30AtO+fXqg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":254},"main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.0_1722566101773_0.92441016080942","host":"s3://npm-registry-packages"}},"0.0.1":{"name":"@alexmacarthur/power-plant","version":"0.0.1","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.1","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"7b6dbbcddab57ad8794e09d9837f582df6103fdb","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.1.tgz","fileCount":23,"integrity":"sha512-IgR6J7eL0I9rr3AK1vIdUmmXvv680GXQffnwUBzSDczhFRI2FloCMthgXORVuNtmrsb+LEDRFVl5qjUiDQ3JRw==","signatures":[{"sig":"MEUCIHwyeC38GvS4LyNOCjeibmU+hl1D8+s2BqKurwrQpDvjAiEA6YWB5aG5nllPuh8mqfPEioLB1ZyaMZtRg9ml3BhMCqo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":9986},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"70362ddb6f4cc3c7fd13a3c1c6711364d9185be5","scripts":{"test":"vitest run src","build":"rm -rf dist && mkdir dist && tsc","start":"tsx examples/first.ts","format":"prettier --write .","coverage":"vitest run src --coverage"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"_A dependency injection framework built on native decorators._","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.1_1722748276196_0.27881158169307896","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@alexmacarthur/power-plant","version":"0.0.2","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.2","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"d5ffc2b122807a22ed0dedc9ec4dcbe82a9226d1","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.2.tgz","fileCount":23,"integrity":"sha512-BfmCEJgPM8BN9GlB38KnGJ5xb+8QrSCCqQ+x1W56JWZYAUMfGFrUxl3W4TJt2sSYp6wLt2n3xJnBBjm1NjaKSA==","signatures":[{"sig":"MEYCIQCPB9j584uS/buBCsDYHtcmJaYcRZ1VV5A7fpnLQQNpSQIhALLJG4dU9zuROhfwG9ioxS4bqIDUcwBCfdDZ5Zate/ae","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":10866},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"522a8ee947f237c32e3100dfdd7a390d4138d030","scripts":{"test":"vitest run src","build":"rm -rf dist && mkdir dist && tsc","format":"prettier --write .","coverage":"vitest run src --coverage","demo:local":"tsx examples/local.ts","demo:remote":"tsx examples/remote.ts"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"A dependency injection framework built on native decorators.","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.2_1722810808118_0.8075375056642757","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"@alexmacarthur/power-plant","version":"0.0.3","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.3","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"ff2e68013ee984517cb645477d75f35184430796","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.3.tgz","fileCount":23,"integrity":"sha512-rZQegEpRJqZGxPrq6tnyxsspCJWqYl32iGMkQy5fv11aOntdtBkeLb0b7aO4aOmlpI/CYYh4I0R2qiukeXNqFA==","signatures":[{"sig":"MEQCIBRus3tw1Tsnb2xB3S8C0+Y6ZP9zBBJp3n1mUeg4U/1xAiA8vjloJVxn/v9Q/ki6lrrb4C5lpa6Q27wKcloOW8Al1w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":10812},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"522a8ee947f237c32e3100dfdd7a390d4138d030","scripts":{"test":"vitest run src","build":"rm -rf dist && mkdir dist && tsc","format":"prettier --write .","coverage":"vitest run src --coverage","demo:local":"tsx examples/local.ts","demo:remote":"tsx examples/remote.ts"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"A dependency injection framework built on native decorators.","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.3_1722811119781_0.9363291575503336","host":"s3://npm-registry-packages"}},"0.0.4":{"name":"@alexmacarthur/power-plant","version":"0.0.4","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.4","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"0e30522498c39e75efef0ec7ec18bdf6eb98f287","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.4.tgz","fileCount":21,"integrity":"sha512-QdKolXZFVBEqStnxyD4GT40Dh7vknBOhtDSFHBvRanfTi0AEP2tKuBYFGcFvJ9aqXksWKAVd/HhH2n/UfBt6uQ==","signatures":[{"sig":"MEQCIFplJiwEo3LzWjLwFtcE0DP2Y8eL1JlILnKqifyWoQfmAiBuecNc0EdwpyiA+HaiSDcXVWVlye41QfJzcnGPJP002w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":10629},"main":"dist/index.es.js","type":"module","types":"dist/index.d.ts","gitHead":"522a8ee947f237c32e3100dfdd7a390d4138d030","scripts":{"test":"vitest run src","build":"rm -rf dist && mkdir dist && vite build && tsc","format":"prettier --write .","coverage":"vitest run src --coverage","demo:local":"tsx examples/local.ts","demo:remote":"tsx examples/remote.ts"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"A dependency injection framework built on native decorators.","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.4_1722820233972_0.8403822745878611","host":"s3://npm-registry-packages"}},"0.0.5":{"name":"@alexmacarthur/power-plant","version":"0.0.5","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.5","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"b1d99b359767eb86713f9cd23f0c950df85e0125","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.5.tgz","fileCount":23,"integrity":"sha512-+1z8MdWcbQN1VLY2s7dvZ5muOrCNHIwLKT+dt3XlLhpz9MCOveajOpam7Mj1e28/1G24kQHkVparO4aaqpR/Cw==","signatures":[{"sig":"MEUCIQD6d42QpH8IuiFqPud5DZNO57BDEObDETEje8tdrixh1QIgEMEVT2lKmDbcZ66Pr0d473L43COfPXYy8diEy00P9mg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":14887},"main":"dist/index.es.js","type":"module","types":"dist/index.d.ts","gitHead":"93422bef70a4168d4cd1a8cbbac35dac95793e8e","scripts":{"demo":"tsx examples/local.ts","test":"vitest run src","build":"rm -rf dist && mkdir dist && vite build && tsc","format":"prettier --write .","coverage":"vitest run src --coverage"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"A dependency injection framework built on native decorators.","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.5_1722884370663_0.13027448982771328","host":"s3://npm-registry-packages"}},"0.0.6":{"name":"@alexmacarthur/power-plant","version":"0.0.6","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"author":{"name":"Alex MacArthur"},"license":"MIT","_id":"@alexmacarthur/power-plant@0.0.6","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"homepage":"https://github.com/alexmacarthur/power-plant","dist":{"shasum":"60f66c2d338ce3df4bfb75a86e3ef92ea23eae53","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.6.tgz","fileCount":24,"integrity":"sha512-B0tC4yA8jcJSBIauAyVXUOg5QR1cbZqcVonzyEIZ4HZqPmLBXnFrtoZ9QhMeXdyFElYwM5QCiqniyoN+LoQ/cw==","signatures":[{"sig":"MEQCIGjw+4n+9ZUQpW6bZFf7mfQ1otOZxpULsXEn2K32m09OAiBJU8C+H+SripMvV6OPAg9RCYSGKaZuJhf4jsA3c47Usg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":16431},"main":"dist/index.es.js","type":"module","types":"dist/index.d.ts","gitHead":"fd57ea471bf5382c5210f75aefa90dd84c72ad7a","scripts":{"demo":"tsx examples/local.ts","test":"vitest run src","build":"rm -rf dist && mkdir dist && vite build && tsc","format":"prettier --write .","coverage":"vitest run src --coverage"},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"_npmVersion":"9.6.7","description":"A dependency injection framework built on native decorators.","directories":{},"_nodeVersion":"20.3.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.16.5","vitest":"^2.0.5","ts-node":"^10.9.2","prettier":"^3.3.3","typescript":"^5.5.4","@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5"},"_npmOperationalInternal":{"tmp":"tmp/power-plant_0.0.6_1722911221129_0.12214771746867337","host":"s3://npm-registry-packages"}},"0.0.7":{"name":"@alexmacarthur/power-plant","description":"A dependency injection framework built on native decorators.","author":{"name":"Alex MacArthur"},"license":"MIT","version":"0.0.7","homepage":"https://github.com/alexmacarthur/power-plant","type":"module","types":"dist/index.d.ts","main":"dist/index.es.js","scripts":{"build":"rm -rf dist && mkdir dist && vite build && tsc","test":"vitest run src","coverage":"vitest run src --coverage","format":"prettier --write .","demo":"tsx examples/local.ts"},"keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"devDependencies":{"@types/node":"^22.1.0","@vitest/coverage-v8":"^2.0.5","prettier":"^3.3.3","ts-node":"^10.9.2","tsx":"^4.16.5","typescript":"^5.5.4","vitest":"^2.0.5"},"gitHead":"c10d773352257987e73d1cf58043907666ceccac","_id":"@alexmacarthur/power-plant@0.0.7","_nodeVersion":"20.3.0","_npmVersion":"9.6.7","dist":{"integrity":"sha512-1BZLF3GAXNB2Z6KyjAVLXB5zRUSAlRcew9y7M0MKr46PmBHQnfLtw7nEAZT6JI0drDMd8MuAZD0gTB9rykELuw==","shasum":"591b89251f298c94b240121313c111c243be30c7","tarball":"https://registry.npmjs.org/@alexmacarthur/power-plant/-/power-plant-0.0.7.tgz","fileCount":24,"unpackedSize":16500,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE1uI3ZkQv/6QJov9f5VSgO/G1C3mUvEAurNmnZrFD+tAiA0mhhpvNrTNLDsom4fnF5W0iRyAkLVTl4MOOYPzBYCYg=="}]},"_npmUser":{"name":"alexmacarthur","email":"alex@macarthur.me"},"directories":{},"maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/power-plant_0.0.7_1722911547711_0.34252448939983116"},"_hasShrinkwrap":false}},"time":{"created":"2024-08-02T02:35:01.582Z","modified":"2024-08-06T02:32:28.046Z","0.0.0":"2024-08-02T02:35:02.043Z","0.0.1":"2024-08-04T05:11:16.381Z","0.0.2":"2024-08-04T22:33:28.284Z","0.0.3":"2024-08-04T22:38:40.004Z","0.0.4":"2024-08-05T01:10:34.181Z","0.0.5":"2024-08-05T18:59:30.860Z","0.0.6":"2024-08-06T02:27:01.315Z","0.0.7":"2024-08-06T02:32:27.850Z"},"author":{"name":"Alex MacArthur"},"license":"MIT","homepage":"https://github.com/alexmacarthur/power-plant","keywords":["di","ioc","decorator","inversion-of-control","dependency-injection"],"description":"A dependency injection framework built on native decorators.","maintainers":[{"name":"alexmacarthur","email":"alex@macarthur.me"}],"readme":"# Power Plant\n\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40alexmacarthur%2Fpower-plant)\n\n_A dependency injection framework built on native decorators._\n\n## Why?\n\n[Native class decorators](https://github.com/tc39/proposal-decorators) will inevitably be made available in ECMAScript, providing a simple API for enhancing classes, their fields, methods, and accessors.\n\nAmongst the many use cases is container-managed dependency injection, an approach used by frameworks such as Laravel, Spring Boot, and Nest.js. This library offers a similar feature using native JavaScript decorators.\n\nIt's purpose is to help maintain clear inversion of control, remove instantiation responsibilty from your application, and enable simpler testing of your application code.\n\n## Installation\n\n`npm install @alexmacarthur/power-plant`\n\n## Usage\n\nThere are two decorators available for using this library.\n\n### (Optionally) Register Classes w/ Constructor Parameters\n\nBy default, no class registration is necessary (they will be lazily instantiated when injected). However, if you'd like to customize the parameters passed to a class constructor, use the `@register` decorator to define them as an array:\n\n```ts\n@register([\"arg1\", \"arg2\", \"arg3\"])\nclass MyService {}\n```\n\nWhen the class is later instantiated, that array will be provided as distinct parameters:\n\n```ts\nnew class MyService(\"arg1\", \"arg2\", \"arg3\");\n```\n\nIf, for whatever reason, you'd like to add or remove registered classes manually, you can import the `registry` Map directly:\n\n```ts\nimport { registry } from \"@alexmacarthur/power-plant\";\n\n// Register with constructor parameters.\nregistry.set(MyService, [\"arg1\", \"arg2\", \"arg3\"]);\n\n// Unregister classes.\nregistry.delete(MyService);\n```\n\n### Injecting Classes\n\nThe `@inject()` decorator is needed to construct and assign instances to class fields.\n\n```ts\nclass MyClass {\n  @inject(MyService);\n  myService: MyService;\n\n  constructor() {\n    console.log(this.myService); // instance of MyService\n  }\n}\n```\n\nIf needed, you can manipulate the container of instantiated classes directly:\n\n```ts\nimport { container } from \"@alexmacarthur/power-plant\";\n\n// Set instances.\nconst myServiceInstance = new MyService();\ncontainer.set(MyService, myServiceInstance);\n\n// Remove instances.\ncontainer.delete(MyService);\n```\n\n## Testing with Injected Dependencies\n\nTo mock an injected class during a test, you can use the aforementioned `container` to point the `@inject` decorator to a mock instance. For example:\n\n```typescript\nit(\"Can mock instances.\", () => {\n  class MyTestApp {\n    @inject(EmailService)\n    emailService;\n\n    go() {\n      this.emailService.send(\"my message!\");\n    }\n  }\n\n  const mockEmailServiceInstance = {\n    send: vi.fn(),\n  };\n\n  // Replace actual implementation with a mock.\n  container.set(EmailService, mockEmailServiceInstance);\n\n  new MyTestApp().go();\n\n  // Make assertions on that mock.\n  expect(mockEmailServiceInstance.send).toHaveBeenCalledTimes(1);\n  expect(mockEmailServiceInstance.send).toHaveBeenCalledWith(\"my message!\");\n});\n```\n\n## FAQ\n\n### What makes this special?\n\nThis library is built entirely on the offiial ECMAScript decorators proposal. It differs from most other libraries out there, which are built on a [legacy decorator specification](https://github.com/tc39/proposal-decorators?tab=readme-ov-file#comparison-with-babel-legacy-decorators).\n\n### In what runtimes is this supported?\n\nCurrently, Deno appears to be the only major runtime that supports native ECMAScript decorators, and even [it has a bug](https://github.com/denoland/deno/issues/22253) that'll prevent this library from working correctly.\n\nSo, in order to use this, you'll need to compile your code with [TypeScript > v5.0](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#decorators) or with [Babel's @babel/plugin-proposal-decorators](https://babeljs.io/docs/babel-plugin-proposal-decorators) plugin.\n\n### Can I use this across modules in the same application?\n\nYes. The same registry and container are used throughout an application, so you can safely inject dependencies without worring about classes being unnecessarily instantiated multiple times. Here's a more fleshed out, contrived example:\n\n```typescript\n// my-dependency-class.ts\n\nexport class MyDependencyClass {}\n```\n\n```typescript\n// my-class.ts\n\nimport { inject } from \"@alexmacarthur/power-plant\";\nimport { MyDependencyClass } from \"./my-dependency-class\";\n\nexport class MyClass {\n  @inject(MyDependencyClass)\n  dependencyClass: MyDependencyClass;\n\n  constructor() {}\n\n  run() {}\n}\n```\n\n```typescript\n// my-other-class.ts\n\nimport { inject } from \"@alexmacarthur/power-plant\";\nimport { MyDependencyClass } from \"./my-dependency-class\";\n\nexport class MyOtherClass {\n  @inject(MyDependencyClass)\n  dependencyClass: MyDependencyClass;\n\n  constructor() {}\n\n  run() {}\n}\n```\n\n```typescript\n// index.ts\n\nimport { register } from \"@alexmacarthur/power-plant\";\nimport { MyDependencyClass } from \"./my-dependency-class\";\nimport { MyClass } from \"./my-class\";\nimport { MyOtherClass } from \"./my-other-class\";\n\nregister(MyDependencyClass);\n\nnew MyClass().run();\nnew MyOtherClass().run();\n\n// MyDependencyClass was instantiated _once_.\n```\n\n## Feedback or Contributions?\n\nMake an issue or [find me on X](https://twitter.com/amacarthur).\n","readmeFilename":"README.md"}