{"id":22656887,"url":"https://github.com/libreworks/container","last_synced_at":"2025-10-08T20:57:59.452Z","repository":{"id":192295963,"uuid":"686764122","full_name":"libreworks/container","owner":"libreworks","description":"A simple dependency injection container and event target","archived":false,"fork":false,"pushed_at":"2025-04-21T01:10:26.000Z","size":806,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-30T01:45:17.036Z","etag":null,"topics":["dependency-injection","eventtarget","service-locator"],"latest_commit_sha":null,"homepage":"https://libreworks.github.io/container/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/libreworks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-03T21:28:43.000Z","updated_at":"2025-04-21T01:09:53.000Z","dependencies_parsed_at":"2024-01-08T02:37:32.895Z","dependency_job_id":"47c43296-8a31-4e01-8d0e-895ffd163f57","html_url":"https://github.com/libreworks/container","commit_stats":null,"previous_names":["libreworks/container"],"tags_count":59,"template":false,"template_full_name":null,"purl":"pkg:github/libreworks/container","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcontainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcontainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcontainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcontainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libreworks","download_url":"https://codeload.github.com/libreworks/container/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcontainer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278561274,"owners_count":26006954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","eventtarget","service-locator"],"created_at":"2024-12-09T10:16:49.015Z","updated_at":"2025-10-08T20:57:59.438Z","avatar_url":"https://github.com/libreworks.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @libreworks/container\n\n[![MIT](https://img.shields.io/github/license/libreworks/container)](https://github.com/libreworks/container/blob/main/LICENSE)\n[![npm](https://img.shields.io/npm/v/@libreworks/container)](https://www.npmjs.com/package/@libreworks/container)\n[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/libreworks/container/release/main?label=release)](https://github.com/libreworks/container/actions/workflows/release.yml)\n[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/libreworks/container?sort=semver)](https://github.com/libreworks/container/releases)\n[![codecov](https://codecov.io/gh/libreworks/container/branch/main/graph/badge.svg?token=OHTRGNTSPO)](https://codecov.io/gh/libreworks/container)\n\nA simple asynchronous dependency injection container and event target.\n\n## Installation\n\n```shell\nnpm install @libreworks/container\n```\n\nThis library conforms to ECMAScript Modules (ESM). You can import this module using ESM or TypeScript syntax.\n\n```TypeScript\nimport { Builder, Container, Producer } from \"@libreworks/container\";\n```\n\nIf you're using CommonJS, you must use [dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) instead.\n\n## Usage\n\nYou can use this library to create a graph of objects with intertwined dependencies. These objects and values can even be produced asynchronously.\n\n### Container\n\nA container provides named values.\n\n```typescript\nimport { Foobar } from \"your-package-name-here\";\n\n// Assume we created a Container.\ndeclare const container: Container;\n// Retrieve a value by its name.\nconst myObject: Foobar = await container.get(\"MyObject\");\n// Retrieve multiple values by their names.\nconst allObjects: Foobar[] = await container.getAll([\"MyObject\", \"Another\"]);\n// Retrieve values by tag.\nconst taggedByMe: Foobar[] = await container.getAllTagged(\"my-tag\");\n```\n\n#### Events\n\nThe `Container` class extends the `EventTarget` class ([see MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget)).\n\n### Builder\n\nIn order to put together a `Container`, you can use the `Builder` class.\n\n```typescript\nconst builder = new Builder()\n  // Register a constant\n  .constant(\"ExampleValue\", \"Lorem ipsum dolor sit amet\")\n  // Register an array.\n  .constant(\"my.numbers\", [1, 2, 3, 5, 8, 13, 21])\n  // Register an object created synchronously.\n  .register(\"RandomName\", () =\u003e AnotherClass.doSomething())\n  // Register an object created asynchronously.\n  .register(\n    \"an-async-value\",\n    async (c) =\u003e {\n      const myNumbers = await c.get(\"my.numbers\");\n      return await createNewThingy(myNumbers);\n    },\n    [\"my-tag\", \"AnotherTag\", \"Yet another\"]\n  );\n\nconst container = await builder.build();\n\n// Use the get method's generic type if you prefer.\nconst anAsyncValue = await container.get\u003cMyClassName\u003e(\"an-async-value\");\n```\n\nYou provide a name and a \"factory\" function when you call the `register` method. The factory function needs to return the value you want to register; it can be asynchronous or return a `Promise` as well.\n\nOnce the container is built, a call to `get` using the same name will invoke the factory function. The container provides itself as the first argument. That way, you can recursively locate other dependencies immediately before constructing the return value.\n\nSince the container is an `EventTarget`, the factory function could broadcast an event, or the value returned by the factory function can register itself as an event listener. This feature allows objects inside the container to communicate in a loosely-coupled way.\n\nThe factory function will only ever be invoked once, no matter how many times `get` is invoked.\n\n#### Eager Creation\n\nNormally, values are lazy-loaded; they are created on-demand. However, you can provide the `@eager` tag when you call the `register` method to ensure your objects initialize themselves when the container is created.\n\n```typescript\nconst builder = new Builder().register(\"FooBar\", () =\u003e new Thingy(), [\n  \"@eager\",\n]);\nconst container = await builder.build();\n// Thingy has already been instantiated.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibreworks%2Fcontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibreworks%2Fcontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibreworks%2Fcontainer/lists"}