npm package: @on-the-ground/effect-dependency
Description: > 🥉 **Dynamically route effectful calls to matching dependencies — at runtime, with role-based duck typing.**\ > This is not your typical DI. This is actor-style delegation.
Latest version: 0.0.3

# `@on-the-ground/effect-dependency`

> 🥉 **Dynamically route effectful calls to matching dependencies — at runtime, with role-based duck typing.**\
> This is not your typical DI. This is actor-style delegation.

---

## ✨ Features

- 🔀 **Message-based delegation** of effectful function calls
- 🥆 **Duck-typed role matching** via [quackquack](https://www.npmjs.com/package/@on-the-ground/quackquack)
- 🔗 **Fallback delegation chain** for unhandled messages
- 🎭 No need to wire static interfaces or inject services — just declare a role and call it

---

## 🚀 Quick Example

```ts
import {
  withDependencyEffectHandler,
  dependencyEffect,
} from "@on-the-ground/effect-dependency";

import { quackable } from "@on-the-ground/quackquack";
import { withSignal, emptyContext } from "@on-the-ground/effect";

const greeter = {
  greet: quackable("(name: string) => string")((name) => `Hello, ${name}!`),
};

const pctx = withSignal(new AbortController().signal, emptyContext);

await withDependencyEffectHandler(pctx, [greeter], async (ctx) => {
  const result = await dependencyEffect(ctx, {
    role: { greet: "(name: string) => string" },
    call: { name: "greet", args: ["Juno"] },
  });

  console.log(result); // => "Hello, Juno!"
});
```

---

## 🧠 Concept

This is not a DI container.\
This is a **message-routing system based on duck-typed roles**.

It answers the question:

> “Whoever can handle this message — please do.”

### The Delegation Chain

1. You describe the **role** you're trying to call:

   ```ts
   role: {
     greet: "(name: string) => string";
   }
   ```

2. You issue a **call** into the effect system:

   ```ts
   call: { name: "greet", args: ["Alice"] }
   ```

3. Any dependency that matches the **shape** and **name** will be called.

4. If no match is found locally, the message **bubbles up** to the parent context (if available).

---

## 🧪 Testing Example

```ts
it("delegates to matching dependency", async () => {
  const greeter = {
    greet: quackable("(name: string) => string")((n) => `Hi ${n}`),
  };

  const pctx = withSignal(new AbortController().signal, emptyContext);

  await withDependencyEffectHandler(pctx, [greeter], async (ctx) => {
    const result = await dependencyEffect(ctx, {
      role: { greet: "(name: string) => string" },
      call: { name: "greet", args: ["Jo"] },
    });

    expect(result).toBe("Hi Jo");
  });
});
```

---

## 🏗️ When to Use This

✅ You want **flexible message passing** instead of tight coupling\
✅ You want **actor-style delegation** across contexts\
✅ You want **role-based resolution** rather than static DI graphs\
✅ You want to support **plugin-like dependency injection** with fallback chaining

---

## 📦 Installation

```bash
yarn add @on-the-ground/effect-dependency
```

This package depends on:

- `@on-the-ground/effect`
- `@on-the-ground/quackquack`

Make sure they're installed if you're using raw effect contexts.

---

## 💬 Philosophy

Most dependency injection systems are about wiring **who** to call.\
This system is about describing **what kind of role** should be fulfilled — and letting the system **find someone who can**.

Think of it like **actor delegation** or **post office routing**:

> If you match the signature, you get the message.

---

## 🛠️ API

### `withDependencyEffectHandler(ctx, dependencies, thunk)`

Wraps a context with a handler that intercepts dependencyEffect calls and tries to match them to the given dependencies.

### `dependencyEffect(ctx, payload)`

Performs a role-based message call.\
Returns the result of the matched method, or `null` if not handled.

```ts
type Payload<Messages extends string = string> = {
  role: { [K in Messages]: QuackDSL };
  call: {
    name: Messages;
    args: unknown[];
  };
};
```

---

## 📁 Related Packages

- [`@on-the-ground/effect`](https://www.npmjs.com/package/@on-the-ground/effect): Core effect handling system
- [`@on-the-ground/quackquack`](https://www.npmjs.com/package/@on-the-ground/quackquack): Structural type matcher for duck-typed roles

---

## 🧰 Designed for the effect-ive-\* ecosystem

This package is part of the **effect-ive programming** family — a new way to write real-world code with effects, not mocks.