@frontmcp/di 1.9.6 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,58 +1,91 @@
1
1
  # @frontmcp/di
2
2
 
3
- Dependency injection container and registry utilities for FrontMCP.
3
+ The dependency injection container behind FrontMCP. This is an internal package: `@frontmcp/sdk` uses it to build providers and registries, and installs it for you. In a FrontMCP server, declare shared services with `@Provider` and read them with `this.get()` from `@frontmcp/sdk` instead. The container has no FrontMCP-specific code, so you can also use it on its own in any TypeScript project.
4
4
 
5
- [![NPM](https://img.shields.io/npm/v/@frontmcp/di.svg)](https://www.npmjs.com/package/@frontmcp/di)
6
-
7
- > **Internal package.** Used by `@frontmcp/sdk` — most users do not need to install this directly.
5
+ [![npm](https://img.shields.io/npm/v/@frontmcp/di.svg)](https://www.npmjs.com/package/@frontmcp/di) [![License](https://img.shields.io/npm/l/@frontmcp/di.svg)](https://github.com/agentfront/frontmcp/blob/main/LICENSE)
8
6
 
9
7
  ## Install
10
8
 
11
9
  ```bash
12
- npm install @frontmcp/di reflect-metadata zod
10
+ npm install @frontmcp/di @frontmcp/lazy-zod zod reflect-metadata
13
11
  ```
14
12
 
15
- ## Features
16
-
17
- - **Type-safe DI** — class tokens with configurable prefixes ([docs][docs-providers])
18
- - **Scoped providers** — GLOBAL and CONTEXT scopes
19
- - **Hierarchical registries** — parent/child container adoption
20
- - **Indexed lookups** — O(1) registry queries via `IndexedRegistry`
21
- - **Change events** — subscribe to registry mutations
22
- - **Token factory** — `createTokenFactory({ prefix })` for Symbol-based tokens
13
+ `@frontmcp/lazy-zod` (which needs `zod` 4) and `reflect-metadata` are peer dependencies. Import `reflect-metadata` once, before anything else. It needs Node.js 24 or later.
23
14
 
24
- ## Quick Example
15
+ ## Usage
25
16
 
26
17
  ```ts
27
18
  import 'reflect-metadata';
28
19
 
29
20
  import { createTokenFactory, DiContainer, ProviderScope } from '@frontmcp/di';
30
21
 
31
- const tokens = createTokenFactory({ prefix: 'MyApp' });
22
+ const tokens = createTokenFactory({ prefix: 'Desk' });
23
+ const DESK_URL = tokens.type('DeskUrl');
24
+
25
+ class TicketStore {
26
+ static metadata = { name: 'TicketStore', scope: ProviderScope.GLOBAL };
27
+ readonly tickets = new Map<string, string>();
28
+ }
32
29
 
33
- class DatabaseService {
34
- static metadata = { name: 'Database', scope: ProviderScope.GLOBAL };
30
+ class TicketClient {
31
+ constructor(
32
+ readonly store: TicketStore,
33
+ readonly baseUrl: string,
34
+ ) {}
35
35
  }
36
36
 
37
- const container = new DiContainer([DatabaseService]);
37
+ const container = new DiContainer([
38
+ TicketStore,
39
+ { provide: DESK_URL, useValue: 'https://desk.example.com' },
40
+ {
41
+ provide: TicketClient,
42
+ inject: () => [TicketStore, DESK_URL],
43
+ useFactory: (store: TicketStore, baseUrl: string) => new TicketClient(store, baseUrl),
44
+ },
45
+ ]);
46
+
38
47
  await container.ready;
39
- const db = container.get(DatabaseService);
48
+
49
+ const client = container.get(TicketClient);
40
50
  ```
41
51
 
52
+ ### Providers
53
+
54
+ | Form | How it's built |
55
+ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
56
+ | `MyClass` | With `new`. An optional `static metadata = { name, scope }` names it and sets its scope. Constructor parameters are injected when TypeScript records their types, which it does for a decorated class with `emitDecoratorMetadata` on. |
57
+ | `@AsyncWith(() => [DepA, DepB])` on a class | By calling its static `with(depA, depB)`, which may be async. |
58
+ | `{ provide, useValue }` | The value itself. |
59
+ | `{ provide, useFactory, inject }` | By calling `useFactory` with the providers `inject()` returns, in order. |
60
+ | `{ provide, useClass }` | Like a class, registered under `provide`. |
61
+
62
+ `provide` is a class, a symbol or a string. `createTokenFactory({ prefix })` makes symbols with `Symbol.for()`, so two copies of a package in one process share them: `tokens.type('DeskUrl')` is `Symbol.for('Desk:type:DeskUrl')`.
63
+
64
+ ### Scopes
65
+
66
+ - `ProviderScope.GLOBAL` (the default): one instance, built in dependency order when the container starts. `await container.ready`, then read it with `container.get(token)`, or `container.tryGet(token)`, which returns `undefined` instead of throwing.
67
+ - `ProviderScope.CONTEXT`: one instance per context, like a request or a session. Build a context with `const views = await container.buildViews(key)`, then read it with `container.getScoped(token, views)`.
68
+
69
+ A `GLOBAL` provider can't depend on a `CONTEXT` one, and the container throws on dependency cycles.
70
+
71
+ ### Hierarchy and registries
72
+
73
+ `new DiContainer(providers, parent)` looks up tokens it doesn't have in `parent`. The package also exports the registry base classes FrontMCP's own registries extend: `RegistryAbstract`, `SimpleRegistry`, and `IndexedRegistry`, which indexes entries by ID, name and owner, adopts child registries, and emits change events to `subscribe()` callbacks.
74
+
42
75
  ## Docs
43
76
 
44
- | Topic | Link |
45
- | -------------- | --------------------------- |
46
- | Providers & DI | [Providers][docs-providers] |
77
+ - [`@Provider`](https://frontmcp.dev/reference/sdk/provider): providers in a FrontMCP server, built on this container
78
+ - [Sharing state with providers](https://frontmcp.dev/learn/sharing-state-with-providers): a step-by-step guide
47
79
 
48
- ## Related Packages
80
+ ## Related packages
49
81
 
50
- - [`@frontmcp/sdk`](../sdk) — consumes DI for server-level injection
82
+ - [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk): the framework. Use its `@Provider` in a FrontMCP server.
83
+ - [`@frontmcp/lazy-zod`](https://www.npmjs.com/package/@frontmcp/lazy-zod): the Zod used for `providerMetadataSchema`.
51
84
 
52
- ## License
85
+ ## Contributing
53
86
 
54
- Apache-2.0 — see [LICENSE](../../LICENSE).
87
+ Source: [`libs/di`](https://github.com/agentfront/frontmcp/tree/main/libs/di). Issues and pull requests are welcome; see [CONTRIBUTING.md](https://github.com/agentfront/frontmcp/blob/main/CONTRIBUTING.md).
55
88
 
56
- <!-- links -->
89
+ ## License
57
90
 
58
- [docs-providers]: https://frontmcp.dev/reference/sdk/provider
91
+ Apache-2.0. See [LICENSE](https://github.com/agentfront/frontmcp/blob/main/LICENSE).
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/di",
3
- "version": "1.9.6",
3
+ "version": "1.10.0",
4
4
  "description": "Generic dependency injection container and registry utilities for TypeScript applications",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -13,7 +13,8 @@
13
13
  "typescript",
14
14
  "decorators",
15
15
  "reflect-metadata",
16
- "inversion-of-control"
16
+ "inversion-of-control",
17
+ "frontmcp"
17
18
  ],
18
19
  "repository": {
19
20
  "type": "git",
@@ -23,7 +24,7 @@
23
24
  "bugs": {
24
25
  "url": "https://github.com/agentfront/frontmcp/issues"
25
26
  },
26
- "homepage": "https://github.com/agentfront/frontmcp/blob/main/libs/di/README.md",
27
+ "homepage": "https://frontmcp.dev",
27
28
  "type": "module",
28
29
  "main": "../index.js",
29
30
  "module": "./index.mjs",
@@ -47,7 +48,7 @@
47
48
  "node": ">=24.0.0"
48
49
  },
49
50
  "peerDependencies": {
50
- "@frontmcp/lazy-zod": "1.9.6",
51
+ "@frontmcp/lazy-zod": "1.10.0",
51
52
  "reflect-metadata": "^0.2.0"
52
53
  },
53
54
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/di",
3
- "version": "1.9.6",
3
+ "version": "1.10.0",
4
4
  "description": "Generic dependency injection container and registry utilities for TypeScript applications",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -13,7 +13,8 @@
13
13
  "typescript",
14
14
  "decorators",
15
15
  "reflect-metadata",
16
- "inversion-of-control"
16
+ "inversion-of-control",
17
+ "frontmcp"
17
18
  ],
18
19
  "repository": {
19
20
  "type": "git",
@@ -23,7 +24,7 @@
23
24
  "bugs": {
24
25
  "url": "https://github.com/agentfront/frontmcp/issues"
25
26
  },
26
- "homepage": "https://github.com/agentfront/frontmcp/blob/main/libs/di/README.md",
27
+ "homepage": "https://frontmcp.dev",
27
28
  "type": "commonjs",
28
29
  "main": "./index.js",
29
30
  "module": "./esm/index.mjs",
@@ -47,7 +48,7 @@
47
48
  "node": ">=24.0.0"
48
49
  },
49
50
  "peerDependencies": {
50
- "@frontmcp/lazy-zod": "1.9.6",
51
+ "@frontmcp/lazy-zod": "1.10.0",
51
52
  "reflect-metadata": "^0.2.0"
52
53
  },
53
54
  "devDependencies": {