{"id":28857095,"url":"https://github.com/rubaxa/gizmo-di","last_synced_at":"2026-03-02T18:03:29.078Z","repository":{"id":245114979,"uuid":"817285016","full_name":"RubaXa/gizmo-di","owner":"RubaXa","description":"Gizmo is a lightweight TypeScript DI container for flexible and maintainable dependency management in large applications","archived":false,"fork":false,"pushed_at":"2025-05-18T14:44:47.000Z","size":118,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-17T14:59:20.099Z","etag":null,"topics":["container","dependency","dependency-injection","di","inject","injection","ioc"],"latest_commit_sha":null,"homepage":"","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/RubaXa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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}},"created_at":"2024-06-19T11:46:35.000Z","updated_at":"2025-05-10T18:22:05.000Z","dependencies_parsed_at":"2024-06-19T22:52:00.274Z","dependency_job_id":"7f3d1984-d8aa-40f4-911a-8652ed328293","html_url":"https://github.com/RubaXa/gizmo-di","commit_stats":null,"previous_names":["rubaxa/gizmo-di"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RubaXa/gizmo-di","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubaXa%2Fgizmo-di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubaXa%2Fgizmo-di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubaXa%2Fgizmo-di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubaXa%2Fgizmo-di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RubaXa","download_url":"https://codeload.github.com/RubaXa/gizmo-di/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubaXa%2Fgizmo-di/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260857453,"owners_count":23073444,"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","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":["container","dependency","dependency-injection","di","inject","injection","ioc"],"created_at":"2025-06-20T01:12:59.946Z","updated_at":"2026-03-02T18:03:29.073Z","avatar_url":"https://github.com/RubaXa.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Gizmo 🕋\n--------\nGizmo is a lightweight dependency injection (DI) container designed to simplify dependency management in your TypeScript projects. It is particularly useful for managing and injecting dependencies in large applications, ensuring that components are easily testable and maintainable.\n\n```sh\nnpm i --save gizmo-di\n```\n\n---\n\n### Features\n\n- 🏷️ **Token-Based Dependency Resolution**: Uses tokens to identify and resolve dependencies, providing flexibility and type safety.\n- 📦 **Sub-Containers**: Allows creation of sub-containers for hierarchical dependency management.\n- 💉 **Dependency Injection**: Based on active containers.\n- ⚙️ **Supports `singleton`, `scoped`, and `transient`** modes for controlling dependency lifecycles.\n- 🔄 **Lifecycle Hooks**: `onCreated` and `onDeleted` for managing dependency lifecycle events.\n- ✨ **Lazy**: Asynchronously loads dependencies to enhance performance by created modules only when they are required.\n- 🛡️ **Reliability**: Type Inference \u0026 Checking, Cyclic Dependency Detection and Error Tolerance\n\n---\n\n### Examples\n\n1. [**Logger**](./EXAMPLES.md#logger)\n1. [**Inject**](./EXAMPLES.md#inject)\n\n---\n\n### API\n\n#### `Gizmo.token\u003cType\u003e([description[, factory]])`\n\nCreates a new Gizmo token.\n\n**Parameters**:\n- **description**: `string` — A string description for the token. (optional, but very recommended)\n- **factory**: `() =\u003e Type` — A factory function to create the token's default value.\n\n**Returns**: A `GizmoToken\u003cType\u003e` instance.\n\n```ts\n/** Config token with description \u0026 default */\nconst CONFIG_TOKEN = Gizmo.token(`Config`, () =\u003e ({\n\tdebug: false,\n\thost: '127.0.0.1',\n}))\n```\n\n---\n\n#### `Gizmo.provide\u003cDep\u003e(dep, ...args)`\n\nProvides a dependency using the active Gizmo container.\n\n**Parameters**\n- **dep**: `Dep` — a function or class to be used as the dependency.\n- **args**: `DepTokenArgs\u003cDep\u003e` — the arguments to be passed to the dependency.\n\n**Returns**: `() =\u003e DepType\u003cDep\u003e` — a function that provides the dependency.\n\n**Throws**: Error if the call outside of container.\n\n```ts\nconst LOGGER_TOKEN = Gizmo.token('Logger', Gizmo.provide(\n\t({ debug }: InferGizmoToken\u003ctypeof CONFIG_TOKEN\u003e) =\u003e (debug\n\t\t? console.info\n\t\t: (...args: any[]) =\u003e {}\n\t),\n\tCONFIG_TOKEN,\n))\n```\n\n---\n\n#### `Gizmo.lazy\u003cType\u003e(factory)`\n\nCreates a lazy-loaded factory for a token.\n\n**Parameters**:\n- **factory**: `() =\u003e Promise\u003cType\u003e | Promise\u003cType\u003e` — A function or promise that resolves to the token's value.\n\n**Returns**: A function that returns a promise resolving to the token's value.\n\n```ts\n// on demand\nglobalGizmo.set(LAZY_MODULE_TOKEN, Gizmo.lazy(() =\u003e import('@some/module')))\n\n// and promise based\nglobalGizmo.set(PROMISE_TOKEN, Gizmo.lazy(import('@some/module')))\n```\n\n---\n\n### `Gizmo` instance methods\n\n#### `set\u003cType\u003e(token, factory, [options])`\n\nSet a factory for a given token and store the factory method and options.\n\n**Parameters**\n- **token**: `GizmoToken\u003cType\u003e` — the token to associate with the factory.\n- **factory**: `() =\u003e Type` — the factory function to create the token's value.\n- **options**: `GizmoSetOptions\u003cType\u003e` (optional)\n  - **mode**: `singleton | scoped | transient` (optional).\n  - **onCreated**: `(value: Type) =\u003e void` (optional) — a hook called when a token's value is created.\n  - **onDeleted**: `(value: Type) =\u003e void` (optional) — a hook called when a token's value is deleted.\n\n**Returns**: `() =\u003e Type` — function to resolve the token.\n\n```ts\n// Singleton\ncontainer.set(CONFIG_TOKEN, () =\u003e ({ debug: true }), {\n\tonCreated: (config) =\u003e console.log('Config created:', config),\n})\n\n// Transient\ncontainer.set(HTTP_CLIENT, () =\u003e new HttpClient(), { mode: 'transient' })\n```\n\n---\n\n#### `has(token)`\n\nCheck if a token is present in the container.\n\n**Parameters**\n- **token**: `GizmoToken\u003cany\u003e` — the token to check.\n\n**Returns**: `boolean` — `true` if the token is present, otherwise `false`.\n\n```ts\nconst exists = container.has(CONFIG_TOKEN)\n```\n\n---\n\n#### `get\u003cType\u003e(token)`\n\nGet the value associated with a token. If not cached, it resolves the value using the factory.\n\n**Parameters**\n- **token**: `GizmoToken\u003cType\u003e` — the token to get the value for.\n\n**Returns**: `Type | undefined` — the resolved value or `undefined` if not found and no default is provided.\n\n```ts\nconst config = container.get(CONFIG_TOKEN)\n```\n\n---\n\n#### `resolve\u003cType\u003e(token)`\n\nGet the value associated with a token, throws an error if not found.\n\n**Parameters**\n- **token**: `GizmoToken\u003cType\u003e` — the token to resolve.\n\n**Returns**: `Type` — the resolved value.\n\n**Throws**: Error if the token cannot be resolved.\n\n```ts\nconst config = container.resolve(CONFIG_TOKEN)\n```\n\n---\n\n#### `sub()`\n\nCreates a sub-container.\n\n**Returns**: `Gizmo` instance\n\n```ts\nconst projectGizmo = globalGizmo.sub()\n```\n\n---\n\n#### `delete\u003cType\u003e(token)`\n\nRemove a token and its value from the container.\n\n**Parameters**\n- **token**: GizmoToken\u003cType\u003e — the token to delete.\n\n**Returns**: `void`\n\n```ts\ncontainer.delete(CONFIG_TOKEN)\n```\n\n#### `clear()`\n\nClear all tokens and values from the container.\n\n**Returns**: `void`\n\n```ts\ncontainer.clear()\n```\n\n---\n\n### Types / Utils\n\n### `GizmoToken`\n\n#### `inject(): Type`\n\nInjects a dependency based on the active Gizmo container.\n\n**Returns**: `Type` — the resolved dependency instance.\n\n```ts\nconst HTTP_CLIENT_TOKEN = Gizmo.token\u003cHttpClient\u003e('HttpClient')\nconst HTTP_CLIENT_CONFIG_TOKEN = Gizmo.token('HttpClientConfig', () =\u003e ({ apiBaseUrl: 'http://127.0.0.1/api/v1' }))\n\nclass HttpClient {\n\tprivate config = HTTP_CLIENT_CONFIG_TOKEN.inject()\n}\n\ncontainer.set(HTTP_CLIENT_TOKEN, () =\u003e new HttpClient())\n```\n\n---\n\n#### `map\u003cTOut\u003e(fn)`\n\nTransforms a token into a subordinate token for injectable (`Gizmo#provide`).\n\n**Parameters**\n- **fn**: `(value: Type, gizmo: Gizmo) =\u003e TOut` — A function that defines the transformation. It receives the resolved value of the parent token and the current Gizmo instance.\n\n**Returns**: `GizmoTokenSub\u003cTOut\u003e` — Subordinate token type\n\n```ts\ncontainer.set(LOGGER_TOKEN, Gizmo.provide(\n\t(debug: boolean) =\u003e debug ? console.info : (...args: any[]) =\u003e {},\n\tCONFIG_TOKEN.map(({ debug }) =\u003e debug),\n))\n```\n\n---\n\n### `InferGizmoToken\u003cToken\u003e`\n\nUtility type to infer the type from a `GizmoToken\u003cType\u003e`.\n\n---\n\n### `GizmoTokenMode`\n\nRepresents token modes.\n\n**Values**\n- `singleton`\n- `scoped`\n- `transient`\n\n```ts\n/* eslint no-self-compare:\"off\" */\nconst randomValue = () =\u003e ({ value: Math.random() })\nconst RANDOM_TOKEN = Gizmo.token\u003c{ value: number }\u003e('random')\n\nconst first = new Gizmo()\nconst second = first.sub()\nconst third = second.sub()\nconst four = third.sub()\n\n// Singleton\nfirst.set(RANDOM_TOKEN, randomValue)\nsecond.set(RANDOM_TOKEN, randomValue)\n\n// Scoped\nthird.set(RANDOM_TOKEN, randomValue, { mode: 'scoped' })\n\n// Transient\nfour.set(RANDOM_TOKEN, randomValue, { mode: 'transient' })\n\n// TESTS: Transient\nfour.resolve(RANDOM_TOKEN).value !== four.resolve(RANDOM_TOKEN).value // \"four\" not equal \"four\"\n\n// TESTS: Scoped\nthird.resolve(RANDOM_TOKEN).value !== four.resolve(RANDOM_TOKEN).value // \"third\" not equal \"four\"\nthird.resolve(RANDOM_TOKEN).value === third.resolve(RANDOM_TOKEN).value // \"third\" equal \"third\"\n\n// TESTS: Singleton\nsecond.resolve(RANDOM_TOKEN).value === first.resolve(RANDOM_TOKEN).value // \"second\" equal \"first\"\nsecond.resolve(RANDOM_TOKEN).value !== third.resolve(RANDOM_TOKEN).value // \"second\" not equal \"third\"\n```\n\n---\n\n### Conclusion\n\nGizmo provides a structured and efficient way to manage dependencies in your TypeScript projects. By leveraging tokens and different dependency scopes, you can create scalable and maintainable applications. Integrate Gizmo into your project to simplify dependency management and improve code testability.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubaxa%2Fgizmo-di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubaxa%2Fgizmo-di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubaxa%2Fgizmo-di/lists"}