@daisugi/kado
Version:
Kado is a minimal and unobtrusive inversion of control container.
416 lines (277 loc) β’ 7.5 kB
Markdown
# @daisugi/kado
[](https://www.npmjs.com/package/@daisugi/kado)

[](https://bundlephobia.com/result?p=@daisugi/kado)
This project is part of the [@daisugi](https://github.com/daisugiland/daisugi) monorepo.
**Kado** is a minimal and unobtrusive inversion of control (IoC) container.
## π Features
- π‘ Minimal size overhead ([see details](https://bundlephobia.com/result?p=@daisugi/kado))
- β‘οΈ Written in TypeScript
- π¦ Uses only trusted dependencies
- π¨ Powerful and agnostic to your code
- π§ͺ Well-tested
- π€ Used in production
- π Supports both ES Modules and CommonJS
## π¦ Installation
Using npm:
```sh
npm install @daisugi/kado
```
Using pnpm:
```sh
pnpm install @daisugi/kado
```
[:top: Back to top](#-table-of-contents)
## π Usage
```js
import { Kado } from '@daisugi/kado';
const { container } = new Kado();
class Foo {
constructor(bar) {
this.bar = bar;
}
}
class Bar {}
container.register([
{ token: 'Foo', useClass: Foo, params: ['Bar'] },
{ token: 'Bar', useClass: Bar }
]);
const foo = await container.resolve('Foo');
```
[:top: Back to top](#-table-of-contents)
## π Table of Contents
- [@daisugi/kado](#daisugikado)
- [π Features](#-features)
- [π¦ Installation](#-installation)
- [π Usage](#-usage)
- [π Table of Contents](#-table-of-contents)
- [π― Motivation](#-motivation)
- [β
Key Requirements](#-key-requirements)
- [π API](#-api)
- [`#register(manifestItems)`](#registermanifestitems)
- [Example:](#example)
- [`#resolve(token)`](#resolvetoken)
- [Example:](#example-1)
- [`#get(token)`](#gettoken)
- [Example:](#example-2)
- [`token`](#token)
- [`useClass`](#useclass)
- [Example:](#example-3)
- [`useValue`](#usevalue)
- [Example:](#example-4)
- [`useFnByContainer`](#usefnbycontainer)
- [Example:](#example-5)
- [`useFn`](#usefn)
- [Example:](#example-6)
- [`scope`](#scope)
- [Example:](#example-7)
- [`meta`](#meta)
- [Example:](#example-8)
- [`params`](#params)
- [Example:](#example-9)
- [`#list()`](#list)
- [Example:](#example-10)
- [`Kado.value`](#kadovalue)
- [Example:](#example-11)
- [`Kado.map`](#kadomap)
- [Example:](#example-12)
- [`Kado.flatMap`](#kadoflatmap)
- [Example:](#example-13)
- [π· TypeScript Support](#-typescript-support)
- [Example:](#example-14)
- [π― Goal](#-goal)
- [πΈ Etymology](#-etymology)
- [π Other Projects](#-other-projects)
- [π License](#-license)
[:top: Back to top](#-table-of-contents)
## π― Motivation
Kado was created to address limitations found in other IoC libraries. If these requirements align with your needs, Kado may be a good fit. Otherwise, alternatives like [di-ninja](https://github.com/di-ninja/di-ninja) or [tsyringe](https://github.com/microsoft/tsyringe) might be worth exploring.
### β
Key Requirements
- Allows multiple container instances without global state.
- Decouples dependency injection (DI) configuration from base code.
- Supports easy dependency decoration (useful for telemetry, debugging, etc.).
- Avoids annotation-based decorators ([see style guide](https://github.com/daisugiland/javascript-style-guide)).
- Works with pure JavaScript (does not require TypeScript).
- Keeps the API simple yet powerful.
[:top: Back to top](#-table-of-contents)
## π API
### `#register(manifestItems)`
Registers dependencies in the container.
#### Example:
```js
container.register([{ token: 'Foo' }]);
```
### `#resolve(token)`
Resolves a registered dependency.
#### Example:
```js
const foo = await container.resolve('Foo');
```
### `#get(token)`
Retrieves a registered manifest item by token.
#### Example:
```js
const manifestItem = container.get('Foo');
```
### `token`
A unique identifier for registered dependencies.
### `useClass`
Defines a class as a dependency.
#### Example:
```js
container.register([
{ token: 'Foo', useClass: Foo, params: ['Bar'] },
{ token: 'Bar', useClass: Bar }
]);
```
### `useValue`
Registers a constant value.
#### Example:
```js
container.register([{ token: 'foo', useValue: 'text' }]);
```
### `useFnByContainer`
Passes the container to a factory function.
#### Example:
```js
function bar(c) {
return c.resolve('Foo');
}
container.register([
{ token: 'Foo', useClass: Foo },
{ token: 'bar', useFnByContainer: bar }
]);
```
### `useFn`
Passes specified parameters to a factory function.
#### Example:
```js
function bar(foo) {
return foo;
}
container.register([
{ token: 'Foo', useClass: Foo },
{ token: 'bar', useFn: bar, params: ['Foo'] }
]);
```
### `scope`
Defines the lifecycle of dependencies.
- **`Singleton`** (default) - Reuses the same instance.
- **`Transient`** - Creates a new instance each time.
#### Example:
```js
container.register([
{ token: 'Foo', useClass: Foo, scope: 'Transient' }
]);
```
### `meta`
Stores arbitrary metadata.
#### Example:
```js
container.register([{ token: 'Foo', meta: { isFoo: true } }]);
```
### `params`
Specifies constructor arguments.
#### Example:
```js
container.register([
{ token: 'Foo', useClass: Foo, params: [{ useValue: 'text' }] }
]);
```
### `#list()`
Returns a list of registered dependencies.
#### Example:
```js
const manifestItems = container.list();
```
### `Kado.value`
Helper for injecting values.
#### Example:
```js
container.register([
{ token: 'Foo', useClass: Foo, params: [Kado.value('text')] }
]);
```
### `Kado.map`
Helper for resolving arrays.
#### Example:
```js
container.register([
{ token: 'bar', useValue: 'text' },
{ token: 'Foo', useClass: Foo, params: [Kado.map(['bar'])] }
]);
```
### `Kado.flatMap`
Similar to `Kado.map`, but flattens the result.
#### Example:
```js
container.register([
{ token: 'bar', useValue: ['text'] },
{ token: 'Foo', useClass: Foo, params: [Kado.flatMap(['bar'])] }
]);
```
[:top: Back to top](#-table-of-contents)
## π· TypeScript Support
Kado is fully written in TypeScript.
#### Example:
```ts
import {
Kado,
type KadoManifestItem,
type KadoContainer,
type KadoToken,
type KadoScope,
} from '@daisugi/kado';
const { container } = new Kado();
class Foo {}
const myContainer: KadoContainer = container;
const token: KadoToken = 'Foo';
const scope: KadoScope = Kado.scope.Transient;
const manifestItems: KadoManifestItem[] = [
{
token,
useClass: Foo,
scope,
}
];
myContainer.register(manifestItems);
const foo = await myContainer.resolve<Foo>('Foo');
```
[:top: Back to top](#-table-of-contents)
## π― Goal
Kado aims to provide a simple yet effective IoC solution with minimal overhead.
[:top: Back to top](#-table-of-contents)
## πΈ Etymology
*Kado* (θ―ι) is the Japanese art of flower arrangement, emphasizing form, lines, and balanceβsimilar to how Kado structures dependencies.
[:top: Back to top](#-table-of-contents)
## π Other Projects
Explore the [@daisugi](../../README.md) ecosystem.
[:top: Back to top](#-table-of-contents)
## π License
[MIT](../../LICENSE)
[:top: Back to top](#-table-of-contents)