npm package: @ortha/admin-platform-plugin-registry
Description: The foundational types and service factories for the Ortha admin plugin system. Every admin package depends on this — it defines the plugin contract, provides the plugin registry, routing and slot services, validation, and topological sort for dependency 
Latest version: 0.0.4

# @ortha/admin-platform-plugin-registry

The foundational types and service factories for the Ortha admin plugin system. Every admin package depends on this — it defines the plugin contract, provides the plugin registry, routing and slot services, validation, and topological sort for dependency resolution.

## Installation

Internal monorepo dependency — import directly:

```ts
import type {
    AdminPlugin,
    AdminPluginContext
} from '@ortha/admin-platform-plugin-registry';
import {
    pluginRegistry,
    routerService,
    slotService
} from '@ortha/admin-platform-plugin-registry';
```

## Usage

### Defining a plugin

```ts
import type { AdminPlugin } from '@ortha/admin-platform-plugin-registry';

const myPlugin = (): AdminPlugin =>
    Object.freeze({
        id: 'my-plugin',
        name: 'My Plugin',
        dependencies: ['core'],
        setup(ctx) {
            ctx.router.addRoute({
                path: '/my-page',
                component: MyPage
            });
            ctx.slots.fill(SLOT_TOPBAR_NAV_MAIN_ACTIONS, MyNavButton, {
                order: 10
            });
        }
    });
```

### Creating services

```ts
import {
    pluginRegistry,
    routerService,
    slotService,
    pluginContext
} from '@ortha/admin-platform-plugin-registry';

const registry = pluginRegistry();
const router = routerService();
const slots = slotService();

// Create a scoped context for a specific plugin
const ctx = pluginContext({
    pluginId: 'my-plugin',
    registry,
    router,
    slots,
    config: {}
});
```

### Validation and load ordering

```ts
import {
    validate,
    resolveLoadOrder
} from '@ortha/admin-platform-plugin-registry';

// Validate plugins before setup
validate(plugins);

// Resolve topological order based on dependencies
const sorted = resolveLoadOrder(plugins);
```

## API Reference

### Types

| Export                | Kind | Description                                                              |
| --------------------- | ---- | ------------------------------------------------------------------------ |
| `AdminPlugin`         | type | Contract every plugin must satisfy (`id`, `name`, `setup`)               |
| `AdminPluginContext`  | type | DI context passed to `setup()` — `registry`, `router`, `slots`, `config` |
| `AdminPluginRegistry` | type | Central registry — `register()`, `get()`, `getAll()`, `isRegistered()`   |
| `RouteDefinition`     | type | Route descriptor (`path`, `component`, `meta`)                           |
| `SlotDefinition`      | type | Slot fill descriptor (`key`, `component`, `order`)                       |
| `SlotFill`            | type | Resolved fill stored by `SlotService`                                    |
| `RouterService`       | type | Route collection — `addRoute()`, `getRoutes()`                           |
| `SlotService`         | type | Slot management — `fill()`, `getSlot()`, `getAll()`                      |
| `AdminConfig`         | type | Open config object (`basePath`, `debug`, extensible)                     |

### Factories

| Export             | Kind    | Description                                               |
| ------------------ | ------- | --------------------------------------------------------- |
| `pluginRegistry()` | factory | Creates a `Map`-backed plugin registry                    |
| `routerService()`  | factory | Creates a route collection service                        |
| `slotService()`    | factory | Creates a slot management service (auto-sorts by `order`) |
| `pluginContext()`  | factory | Creates a scoped context for a single plugin's `setup()`  |

### Utilities

| Export               | Kind | Description                                                  |
| -------------------- | ---- | ------------------------------------------------------------ |
| `validate()`         | util | Checks required fields, duplicate IDs, and resolvable deps   |
| `resolveLoadOrder()` | util | Topological sort via Kahn's algorithm; detects circular deps |

## Internal Structure

```
src/lib/
├── types/index.ts              # All shared type definitions
├── pluginRegistry/index.ts     # Map-backed registry factory
├── pluginContext/index.ts       # Scoped context builder
├── services/
│   ├── index.ts                # Barrel
│   ├── routerService/index.ts  # Route collection
│   └── slotService/index.ts    # Slot fill management
└── utils/
    ├── index.ts                # Barrel
    ├── validate/index.ts       # Plugin validation
    └── resolveLoadOrder/index.ts # Kahn's topological sort
```

## Key Patterns

- All factory return values are frozen with `Object.freeze()`.
- `validate()` runs before any services are instantiated — fail fast.
- `resolveLoadOrder()` uses Kahn's algorithm; throws on circular dependencies.
- `pluginContext()` wraps `SlotService.fill()` to auto-inject the calling plugin's ID.
- Plugins must never import each other directly — all cross-plugin communication goes through context services.

## Building

```bash
nx build admin-platform-plugin-registry
```