npm package: @iasd/kit-di
Description: <p align="center">     <img src="https://repository-images.githubusercontent.com/1047452352/3655e653-07d7-4fbd-b0fb-a590c59635ca" alt="logo"/> </p>
Latest version: 1.0.0

# KitDi

<p align="center">
    <img src="https://repository-images.githubusercontent.com/1047452352/3655e653-07d7-4fbd-b0fb-a590c59635ca" alt="logo"/>
</p>

A lightweight, dependency free, open source,  dependency injection container for **SvelteKit** with support for **global** and **request-scoped** providers.

- ⚡ Global & Request scopes
- 🧩 Discoverable `Module` files
- 🔄 Class, value, factory & async factory providers
- ✅ Synchronous `inject()` with TypeScript support

## Installation

```bash
# Install via npm, bun, ...etc
bun add @iasd/kit-di
```

## Quick Start

### 1) Define a module

```ts
    // src/feature/feature.module.ts
    import { Module, provide, InjectionToken } from "kit-di";

    export const Env = new InjectionToken<{ nodeEnv: string }>("Env");

    export class FeatureService {}

    export default new Module({
      providers: [
        // Global value
        provide({ provide: Env, useValue: { nodeEnv: process.env.NODE_ENV ?? "development" } }),

        // Global class
        provide({ provide: FeatureService, useClass: FeatureService }),

        // Request-scoped factory (new per request)
        provide({
          scope: "REQUEST",
          provide: new InjectionToken<Date>("RequestStart"),
          useFactory: () => new Date(),
        }),
      ],
    });
```

### 2) Wire it into SvelteKit

```ts
    // src/hooks.server.ts
    import type { Handle } from "@sveltejs/kit";
    import { KitDi } from "kit-di";

    const modules = await KitDi.discover();
    await modules.register();          // resolve GLOBAL providers once at startup

    export const handle: Handle = modules.handle(); // per-request DI context
```

> Using more handlers? Wrap with `sequence(modules.handle(), yourOtherHandle)`.

### 3) Inject dependencies where you need them

```ts
    // src/routes/+page.server.ts
    import { inject } from "kit-di";
    import { FeatureService, Env } from "../feature/feature.module";

    export const load = async () => {
      const svc = inject(FeatureService);  // class instance
      const env = inject(Env);             // token-bound value
      return { env, id: svc.id };
    };
```

## Defining Providers

Providers can be created with `provide(...)`:

- **Value**  
  Bind a concrete value to an `InjectionToken`.

- **Class**  
  The injector constructs the class (lazy by default, or eager with `eager: true`).

- **Factory (sync)**  
  A function returning a value (lazy by default).

- **Factory (async)**  
  A function returning a Promise — **must use** `eager: true` so it resolves during startup/request.  
  This keeps `inject()` strictly synchronous.

Scope options:

- `"GLOBAL"` (default): singleton for the whole app
- `"REQUEST"`: new instance per request (only available during the request lifecycle)

## Contributing

If you would like to contribute, take a look at the [contribution guide](./contributing.md).

## License

KitDi is licensed under the [MIT License](https://opensource.org/licenses/MIT).