# ProxyDI Developer Documentation

## For AI agents: Before You Start

**MANDATORY reading before working on this project:**

1. **Read the entire [README.md](../README.md)** — understand what the library does and how users interact with it
2. **Read all source files** in `src/` — understand implementation
3. **Read all tests** in `src/__tests__/` — understand expected behavior and edge cases

I want it because I want you have all library and use cases in your context, it's not too big, so just do it. But don't read any others content like other documentation documents.

**This must be done RIGHT AFTER YOU reads this document.** ProxyDI is a production library used in other projects. Changes have real impact. So you must have full picture.

### Running Tests

Always use `npm run test:ci` when running tests during refactoring.

After code changes, run `npm run coverage`. Maintain 100% coverage for all code branches.

### Updating CHANGELOG

After making changes, update CHANGELOG.md with the appropriate version and changes.

## Documentation Structure

**[Library Users Documentation](../README.md):** for developers using ProxyDI in their projects.

**[Library Developers Documentation](./proxydi.md):** files in this folder (`documentation/`) for contributors working on ProxyDI itself.

## Key Resources

- [How to Write User Documentation](./writing-user-documentation.md) — style guide for user documentation
- [How to Write Developer Documentation](./writing-developer-documentation.md) — style guide for developer project documentation``
- [Roadmap](./roadmap.md) — planned improvements and features
- [Bundler Examples TODO](./bundler-examples-todo.md) — tasks for creating bundler configuration examples

## Feature Documentation

- [@injectAll and ResolveScope](./injectAll.md) — dependency arrays and scope control

## Architecture Overview

```mermaid
graph TB
    User[Using ProxyDI] --> Register[Register dependencies]
    User --> Resolve[Resolve dependencies]

    Register --> Container[ProxyDiContainer.ts]
    Resolve --> Container

    Container --> Injectable["@injectable
    auto-injectable classes"]
    Container --> Inject["@inject
    field injections"]
    Container --> InjectAll["@injectAll
    array injections"]

    Injectable --> AutoResolve[Auto-resolve on first use]
    AutoResolve --> DirectInstance[Direct instance]

    Inject --> InjectionProxy["makeInjectionProxy.ts
    Auto-bake after first use"]

    InjectAll --> InjectAllProxy["makeInjectAllProxy.ts
    Dynamic array (permanent)"]

    Container --> Hierarchy[Container hierarchy]
    Hierarchy --> CheckOrigin{"Instance from
    different container?"}
    CheckOrigin -->|No - same container| DirectInstance
    CheckOrigin -->|Yes - parent container| ResolveContext{resolveInContainerContext?}
    ResolveContext -->|false| DirectInstance
    ResolveContext -->|true| DependencyProxy["makeDependencyProxy.ts
    Permanent Proxy"]

    Container --> Middleware[Middleware system]
    Middleware --> MiddlewareDecorator["@middleware"]
    Middleware --> MiddlewareManager[MiddlewaresManager.ts]

    style InjectionProxy fill:#51cf66,stroke:#2f9e44,color:#000
    style InjectAllProxy fill:#ff6b6b,stroke:#c92a2a,color:#000
    style DependencyProxy fill:#ff6b6b,stroke:#c92a2a,color:#000
    style DirectInstance fill:#51cf66,stroke:#2f9e44,color:#000
```

- 🔴 Slow - Permanent Proxy (~100x slower)
- 🟢 Fast - Auto-baked or direct access

## Source Files Overview

**Core:**

- `ProxyDiContainer.ts` — main container implementation
- `types.ts` — TypeScript types and symbols

**Decorators:**

- `inject.decorator.ts` — `@inject` field decorator
- `injectable.decorator.ts` — `@injectable` class decorator
- `injectAll.decorator.ts` — `@injectAll` field decorator for dependency arrays

**Proxy Implementation:**

- `makeInjectionProxy.ts` — Proxy for `@inject` fields (auto-bakes after first use)
- `makeDependencyProxy.ts` — Proxy for `resolveInContainerContext` (permanent)
- `makeInjectAllProxy.ts` — Proxy for `@injectAll` arrays (permanent, dynamic)

**Middleware:**

- `middleware/middleware.decorator.ts` — `@middleware` decorator
- `middleware/MiddlewaresManager.ts` — middleware lifecycle management
- `middleware/middleware.api.ts` — middleware interfaces

**Utilities:**

- `resolveAll.ts` — wrapper for `container.resolveAll()`
- `presets.ts` — default container settings

## Test Files

All tests in `src/__tests__/`:

- `ProxyDiContainer.test.ts` — main container behavior (comprehensive coverage)
- `inject.test.ts` — `@inject` decorator tests
- `injectable.test.ts` — `@injectable` decorator tests
- `readme.test.ts` — examples from README (ensures docs stay correct)

## Architecture Decisions

### Why Proxy?

Enables circular dependency resolution without manual intervention. Different Proxy types have different lifecycle:

- Field injections (`@inject`) — auto-bake after first use (see `makeInjectionProxy.ts:30-32`)
- Context resolution — permanent Proxy (see `makeDependencyProxy.ts`)

### Why `resolveInContainerContext` is disabled by default?

Creates additional permanent Proxy for each parent dependency resolved from child. ~100x slower property access. See `ProxyDiContainer.ts:268-278`.

### Why `register(instance, Class)` is forbidden?

TypeScript overloads distinguish class constructors from instances. Conditional type `T extends new (...args: any[]) => any ? never : T` prevents ambiguity. See `ProxyDiContainer.ts:120-127`.

## Performance Characteristics

| Feature                       | Proxy Type      | Baking                 | Performance Impact |
| ----------------------------- | --------------- | ---------------------- | ------------------ |
| `@inject` fields (default)    | InjectionProxy  | Auto-bake on first use | Minimal (one-time) |
| `@inject` fields (rewritable) | InjectionProxy  | Never                  | ~100x slower       |
| `resolveInContainerContext`   | DependencyProxy | Never                  | ~100x slower       |

See performance tests in `ProxyDiContainer.test.ts:962-994` (commented out).

## Related Projects

- [@proxydi/react](https://github.com/proxy-di/proxydi-react) — React wrapper
- [node-babel-examples](https://github.com/proxy-di/node-babel-examples) — Babel configuration examples
- [node-ts-examples](https://github.com/proxy-di/node-ts-examples) — TypeScript examples

## Contributing

Before making changes:

1. Read this document
2. Read [How to Write Documentation](./writing-documentation.md)
3. Check [README Improvement Proposals](./documentation-improvement-proposals.md) for planned changes
4. Ensure all tests pass
5. Update documentation if behavior changes
6. Add tests for new features

This is a production library. Be careful.
