katagami 3.0.0 → 3.0.2
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 +140 -584
- package/dist/chunk-J2NYR3SH.js +6 -0
- package/dist/container/index.d.cts +108 -0
- package/dist/container/index.d.ts +2 -2
- package/dist/disposable/index.cjs +16 -25
- package/dist/disposable/index.d.cts +69 -0
- package/dist/disposable/index.d.ts +13 -5
- package/dist/disposable/index.js +1 -1
- package/dist/error/index.d.cts +11 -0
- package/dist/index.cjs +91 -55
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +76 -31
- package/dist/internal.d.cts +29 -0
- package/dist/internal.d.ts +3 -1
- package/dist/lazy/index.cjs +16 -25
- package/dist/lazy/index.d.cts +33 -0
- package/dist/lazy/index.d.ts +3 -3
- package/dist/lazy/index.js +1 -1
- package/dist/resolver/index.d.cts +93 -0
- package/dist/scope/index.d.cts +120 -0
- package/dist/scope/index.d.ts +4 -4
- package/docs/README.de.md +84 -0
- package/docs/README.es.md +84 -0
- package/docs/README.fr.md +84 -0
- package/docs/README.ja.md +105 -0
- package/docs/README.ko.md +84 -0
- package/docs/README.zh-CN.md +84 -0
- package/docs/README.zh-TW.md +84 -0
- package/docs/ai-coding-agents.md +78 -0
- package/docs/articles/ai-coding-agents.ja.md +83 -0
- package/docs/articles/ai-coding-agents.md +70 -0
- package/docs/articles/request-scope.md +48 -0
- package/docs/articles/without-decorators.md +54 -0
- package/docs/choosing-di.md +143 -0
- package/docs/growth/baseline-2026-09-11.json +68 -0
- package/docs/growth/github-metadata.json +13 -0
- package/docs/growth/rollout.md +77 -0
- package/docs/guide.md +186 -0
- package/docs/type-safety.md +126 -0
- package/examples/request-scope/README.md +37 -0
- package/examples/request-scope/app.ts +31 -0
- package/examples/request-scope/demo.ts +10 -0
- package/examples/request-scope/tsconfig.json +11 -0
- package/llms.txt +16 -0
- package/package.json +56 -23
- package/dist/index-jx8b52m0.js +0 -4
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**Typsichere Dependency Injection für TypeScript.**
|
|
6
|
+
|
|
7
|
+
Mache Abhängigkeiten explizit und prüfbar, auch wenn KI-Coding-Agenten den Code schreiben. Katagami sammelt Typen mit jeder Registrierung, prüft die in einer Factory verfügbaren Tokens und verfolgt asynchrone Rückgaben. Ohne Decorators, reflect-metadata oder Laufzeitabhängigkeiten.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Schnellstart
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Warum Katagami? Bibliotheksvergleich
|
|
29
|
+
|
|
30
|
+
Katagami verbindet **aus Registrierungen abgeleitete Typen, Scope-Prüfungen zur Compile-Zeit und keine Laufzeitabhängigkeiten** mit gewöhnlichen TypeScript-Factories. Decorators und Metadaten sind nicht nötig. Ressourcenfreigabe und Lazy Resolution haben eigene Einstiegspunkte.
|
|
31
|
+
|
|
32
|
+
**Geprüft am 2026-09-11**, anhand stabiler npm-Versionen und offizieller Quellen. Siehe [Versionen und Quellen](./choosing-di.md#comparison-sources) sowie den [vollständigen Vergleich mit Async-Verhalten und Ressourcenfreigabe](../README.md#library-comparison).
|
|
33
|
+
|
|
34
|
+
| Bibliothek / Version | Abhängigkeitstypen und Registrierungsprüfung | Scope-Verhalten |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **Sammelt Literal-/unique-symbol-Tokens; fehlende erforderliche Tokens sind Typfehler** | **Scoped-Tokens im Resolver von Singleton-/Transient-Factories ausgeschlossen** |
|
|
37
|
+
| InversifyJS 8.2.3 | Typisierte Bindings; Existenzprüfung zur Laufzeit | Konfigurierte Binding-Lebensdauer |
|
|
38
|
+
| tsyringe 4.10.0 | Klassen-/generische Typen; Registrierungsprüfung zur Laufzeit | Lebensdauer und Kindcontainer |
|
|
39
|
+
| TypeDI 0.10.0 | Klassen und `Token<T>`; Registrierungsprüfung zur Laufzeit | Geteilte/Transient-Services, benannte Container |
|
|
40
|
+
| Awilix 13.0.5 | Abgeleitete Cradle-Typen; breites `resolve` akzeptiert unbekannte Namen | Laufzeitprüfung von Lebensdauern mit `strict: true` |
|
|
41
|
+
| NestJS 12.0.1 | Typisierte Provider; Abhängigkeitsgraph zur Laufzeit | Request-Scope überträgt sich auf abhängige Provider |
|
|
42
|
+
| Effect 3.22.2 | Service-Anforderungen in `Effect`-/`Layer`-Typen | Typisierter `Scope` und Finalizer |
|
|
43
|
+
| typed-inject 5.0.0 | Gesammelte String-Tokens, geprüfte `inject`-Tupel | Singleton, Transient, Kindinjectoren |
|
|
44
|
+
|
|
45
|
+
Auch Awilix, Effect und typed-inject bieten Typprüfungen. Katagami kombiniert Registrierungs- und Scope-Prüfungen mit direkten `r.resolve(token)`-Aufrufen. Die [Grenzen für Tokentypen, Klassen und veränderliche Referenzen](./type-safety.md) gelten weiterhin.
|
|
46
|
+
|
|
47
|
+
## Mit KI-Coding-Agenten arbeiten
|
|
48
|
+
|
|
49
|
+
Der Agent ändert die Abhängigkeiten, führt den TypeScript-Checker aus und korrigiert den Code anhand der Diagnosen. Explizite Factories zeigen Abhängigkeiten als gewöhnlichen TypeScript-Code.
|
|
50
|
+
|
|
51
|
+
Wenn eine Singleton-Factory auf Scoped-Zustand einer Anfrage zugreift, entsteht beispielsweise ein Typfehler.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Registriere handler in diesem Beispiel mit registerScoped. @ts-expect-error prüft das fehlerhafte Beispiel in CI. Korrigiere im Anwendungscode die Lebensdauer und führe npx tsc --noEmit aus, statt den Fehler zu unterdrücken.
|
|
63
|
+
|
|
64
|
+
## Gesammelte Typen und Garantien
|
|
65
|
+
|
|
66
|
+
createContainer() sammelt Typen aus Registrierungen. Solange Literalschlüssel und unique-symbol-Typen erhalten bleiben, werden Tokens außerhalb der sichtbaren Registrierungen abgelehnt. Eine manuelle Service-Typzuordnung ist nicht nötig.
|
|
67
|
+
|
|
68
|
+
Klassentokens folgen struktureller Typisierung: Eine andere kompatible Klasse kann akzeptiert werden. Ein in createContainer<Services>() deklarierter Schlüssel ist ebenfalls im Typ sichtbar, auch ohne tatsächliche Registrierung.
|
|
69
|
+
|
|
70
|
+
Unterstützt Singleton, Transient und Scoped, Modulkomposition mit use(), asynchrone Factories, optionale und mehrfache Auflösung, Ressourcenfreigabe und verzögerte Auflösung. Bei wenigen Abhängigkeiten reichen oft normale Parameter.
|
|
71
|
+
|
|
72
|
+
## Anleitungen und ausführbares Beispiel
|
|
73
|
+
|
|
74
|
+
- [Anleitung für KI-Agenten (Englisch)](./ai-coding-agents.md)
|
|
75
|
+
- [Typgarantien (Englisch)](./type-safety.md)
|
|
76
|
+
- [API und Anwendung (Englisch)](./guide.md)
|
|
77
|
+
- [Starter für Anfrage-Scopes (Englisch)](../examples/request-scope/README.md)
|
|
78
|
+
- [DI auswählen (Englisch)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
CI prüft Typbeispiele und Laufzeittests. Verbesserungen der Reparaturquote von Agenten oder Token-Einsparungen wurden noch nicht gemessen.
|
|
81
|
+
|
|
82
|
+
Der Name stammt von 型紙, den Papierschablonen der traditionellen japanischen Färberei. Typen sammeln sich wie übereinandergelegte Schablonen.
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**Inyección de dependencias con seguridad de tipos para TypeScript.**
|
|
6
|
+
|
|
7
|
+
Haz explícitas y verificables las dependencias, incluso cuando el código lo escriben agentes de IA. Katagami acumula tipos con cada registro, comprueba los tokens accesibles en cada fábrica y conserva los resultados asíncronos. Sin decoradores, reflect-metadata ni dependencias en tiempo de ejecución.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Inicio rápido
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Por qué elegir Katagami: comparación
|
|
29
|
+
|
|
30
|
+
Katagami combina **tipos derivados del registro, restricciones de ámbito en compilación y cero dependencias de ejecución** en factorías de TypeScript normales. No requiere decoradores ni metadatos. La liberación de recursos y la resolución diferida tienen puntos de entrada separados.
|
|
31
|
+
|
|
32
|
+
**Revisado el 2026-09-11**, con versiones estables de npm y fuentes oficiales. Consulta las [versiones y fuentes](./choosing-di.md#comparison-sources) y la [comparación completa de asincronía y liberación de recursos](../README.md#library-comparison).
|
|
33
|
+
|
|
34
|
+
| Biblioteca / versión | Tipos y comprobación de registros | Política de ámbitos |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **Acumula tokens literales/unique symbol; rechaza tokens requeridos sin registrar** | **Excluye tokens Scoped del resolver de factorías Singleton/Transient** |
|
|
37
|
+
| InversifyJS 8.2.3 | Bindings tipados; existencia comprobada en ejecución | Ciclo de vida configurado por binding |
|
|
38
|
+
| tsyringe 4.10.0 | Tipos de clase/genéricos; registros comprobados en ejecución | Ciclos de vida y contenedores hijos |
|
|
39
|
+
| TypeDI 0.10.0 | Clases y `Token<T>`; registros comprobados en ejecución | Servicios compartidos/Transient y contenedores con nombre |
|
|
40
|
+
| Awilix 13.0.5 | Infiere el cradle del registro; el `resolve` amplio acepta nombres desconocidos | `strict: true` comprueba fugas de ciclo de vida en ejecución |
|
|
41
|
+
| NestJS 12.0.1 | Providers tipados; grafo resuelto en ejecución | Request se propaga a los providers dependientes |
|
|
42
|
+
| Effect 3.22.2 | Requisitos de servicios en los tipos `Effect`/`Layer` | `Scope` tipado y finalizadores |
|
|
43
|
+
| typed-inject 5.0.0 | Acumula tokens de cadena y comprueba tuplas `inject` | Singleton, Transient e injectores hijos |
|
|
44
|
+
|
|
45
|
+
Awilix, Effect y typed-inject también ofrecen comprobaciones de tipos. Katagami combina las de registro y ámbito con llamadas directas a `r.resolve(token)`. Se aplican los [límites de tokens, clases y referencias mutables](./type-safety.md).
|
|
46
|
+
|
|
47
|
+
## Uso con agentes de programación de IA
|
|
48
|
+
|
|
49
|
+
El agente modifica las dependencias, ejecuta el comprobador de TypeScript y corrige el código a partir de los diagnósticos. Las fábricas explícitas muestran las dependencias en código TypeScript normal.
|
|
50
|
+
|
|
51
|
+
Por ejemplo, acceder a un estado Scoped desde una fábrica Singleton produce un error de tipos.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
En este ejemplo, registra handler con registerScoped. @ts-expect-error verifica el ejemplo incorrecto en CI; en la aplicación, corrige el ciclo de vida y ejecuta npx tsc --noEmit sin suprimir el error.
|
|
63
|
+
|
|
64
|
+
## Tipos acumulados y garantías
|
|
65
|
+
|
|
66
|
+
createContainer() acumula los tipos de los registros. Si se conservan las claves literales y los tipos unique symbol, se rechazan los tokens fuera del conjunto visible de registros. No hace falta un mapa manual de servicios.
|
|
67
|
+
|
|
68
|
+
Los tokens de clase siguen el tipado estructural: otra clase compatible puede ser aceptada. Una clave declarada en createContainer<Services>() también puede estar disponible en los tipos sin tener un registro real.
|
|
69
|
+
|
|
70
|
+
Incluye ciclos de vida Singleton, Transient y Scoped, composición con use(), fábricas asíncronas, resolución opcional y múltiple, limpieza de recursos y resolución diferida. Para pocas dependencias, los parámetros normales pueden ser suficientes.
|
|
71
|
+
|
|
72
|
+
## Guías y ejemplo ejecutable
|
|
73
|
+
|
|
74
|
+
- [Guía para agentes de IA (inglés)](./ai-coding-agents.md)
|
|
75
|
+
- [Garantías de tipos (inglés)](./type-safety.md)
|
|
76
|
+
- [Guía de uso y API (inglés)](./guide.md)
|
|
77
|
+
- [Ejemplo de ámbitos por petición (inglés)](../examples/request-scope/README.md)
|
|
78
|
+
- [Cómo elegir DI (inglés)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
CI comprueba los ejemplos de tipos y las pruebas de ejecución. No se han medido mejoras en la tasa de reparación de agentes ni ahorro de tokens.
|
|
81
|
+
|
|
82
|
+
El nombre viene de 型紙, las plantillas de papel de la tintura tradicional japonesa. Los tipos se acumulan como capas de plantillas.
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**Injection de dépendances avec sûreté des types pour TypeScript.**
|
|
6
|
+
|
|
7
|
+
Rendez les dépendances explicites et vérifiables, même quand des agents de programmation IA écrivent le code. Katagami accumule les types à chaque enregistrement, vérifie les jetons accessibles aux fabriques et suit les retours asynchrones. Sans décorateurs, reflect-metadata ni dépendances à l’exécution.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Démarrage rapide
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Pourquoi choisir Katagami ? Comparaison
|
|
29
|
+
|
|
30
|
+
Katagami associe **types déduits des enregistrements, restrictions de portée à la compilation et aucune dépendance d'exécution** dans des fabriques TypeScript ordinaires. Aucun décorateur ni métadonnée n'est nécessaire. La libération des ressources et la résolution différée ont des points d'entrée distincts.
|
|
31
|
+
|
|
32
|
+
**Vérifié le 2026-09-11**, à partir des versions stables npm et des sources officielles. Consultez les [versions et sources](./choosing-di.md#comparison-sources) et le [comparatif complet sur l'asynchronisme et la libération des ressources](../README.md#library-comparison).
|
|
33
|
+
|
|
34
|
+
| Bibliothèque / version | Types et vérification des enregistrements | Politique de portée |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **Accumule les tokens littéraux/unique symbol ; rejette les tokens requis non enregistrés** | **Exclut les tokens Scoped du résolveur des fabriques Singleton/Transient** |
|
|
37
|
+
| InversifyJS 8.2.3 | Bindings typés ; existence vérifiée à l'exécution | Durée de vie configurée par binding |
|
|
38
|
+
| tsyringe 4.10.0 | Types de classe/génériques ; enregistrements vérifiés à l'exécution | Durées de vie et conteneurs enfants |
|
|
39
|
+
| TypeDI 0.10.0 | Classes et `Token<T>` ; enregistrements vérifiés à l'exécution | Services partagés/Transient, conteneurs nommés |
|
|
40
|
+
| Awilix 13.0.5 | Cradle déduit des enregistrements ; `resolve` accepte aussi des noms inconnus | `strict: true` vérifie les fuites de durée de vie à l'exécution |
|
|
41
|
+
| NestJS 12.0.1 | Providers typés ; graphe résolu à l'exécution | La portée Request se propage aux providers dépendants |
|
|
42
|
+
| Effect 3.22.2 | Services requis suivis dans les types `Effect`/`Layer` | `Scope` typé et finaliseurs |
|
|
43
|
+
| typed-inject 5.0.0 | Tokens chaînes accumulés et tuples `inject` vérifiés | Singleton, Transient, injecteurs enfants |
|
|
44
|
+
|
|
45
|
+
Awilix, Effect et typed-inject proposent aussi des vérifications de types. Katagami associe celles des enregistrements et des portées avec des appels directs à `r.resolve(token)`. Les [limites des tokens, classes et références mutables](./type-safety.md) s'appliquent.
|
|
46
|
+
|
|
47
|
+
## Travailler avec des agents de programmation IA
|
|
48
|
+
|
|
49
|
+
L’agent modifie les dépendances, exécute le vérificateur TypeScript, puis corrige le code à partir des diagnostics. Les fabriques explicites rendent les dépendances visibles dans du code TypeScript ordinaire.
|
|
50
|
+
|
|
51
|
+
Par exemple, accéder à un état Scoped depuis une fabrique Singleton produit une erreur de type.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Dans cet exemple, enregistrez handler avec registerScoped. @ts-expect-error sert à vérifier l’exemple incorrect en CI. Dans l’application, corrigez la durée de vie et lancez npx tsc --noEmit sans masquer l’erreur.
|
|
63
|
+
|
|
64
|
+
## Types accumulés et garanties
|
|
65
|
+
|
|
66
|
+
createContainer() accumule les types des enregistrements. En conservant les clés littérales et les types unique symbol, les jetons absents de l’ensemble visible sont rejetés. Aucune table manuelle des types de services n’est nécessaire.
|
|
67
|
+
|
|
68
|
+
Les jetons de classe suivent le typage structurel : une autre classe compatible peut être acceptée. Une clé déclarée dans createContainer<Services>() peut aussi être visible dans les types sans enregistrement réel.
|
|
69
|
+
|
|
70
|
+
Prend en charge Singleton, Transient et Scoped, la composition avec use(), les fabriques asynchrones, la résolution optionnelle et multiple, la libération des ressources et la résolution différée. Pour peu de dépendances, des paramètres ordinaires peuvent suffire.
|
|
71
|
+
|
|
72
|
+
## Guides et exemple exécutable
|
|
73
|
+
|
|
74
|
+
- [Guide pour agents IA (anglais)](./ai-coding-agents.md)
|
|
75
|
+
- [Garanties de types (anglais)](./type-safety.md)
|
|
76
|
+
- [Guide et API (anglais)](./guide.md)
|
|
77
|
+
- [Exemple de portée par requête (anglais)](../examples/request-scope/README.md)
|
|
78
|
+
- [Choisir une approche DI (anglais)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
Les exemples de types et les tests d’exécution sont vérifiés en CI. Les gains de réussite des agents ou de consommation de tokens n’ont pas encore été mesurés.
|
|
81
|
+
|
|
82
|
+
Le nom vient de 型紙, les pochoirs de papier de la teinture traditionnelle japonaise. Les types s’accumulent comme des couches de pochoirs.
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**TypeScriptの型安全な依存性注入(DI)コンテナ。**
|
|
6
|
+
|
|
7
|
+
AIエージェントが書くコードでも、依存関係の配線を明示し、型で検証できます。Katagamiは登録するたびに型が自動的に積み上がり、ファクトリから参照できる依存と非同期の戻り値を追跡します。デコレータ・reflect-metadata・ランタイム依存パッケージは不要です。
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## クイックスタート
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Katagamiを選ぶ理由
|
|
29
|
+
|
|
30
|
+
Katagamiの強みは、**登録からの型推論・コンパイル時のスコープ制約・ランタイム依存ゼロ**を、通常のTypeScriptファクトリで組み合わせられることです。
|
|
31
|
+
|
|
32
|
+
- **登録した型がそのまま使える。** リテラルキーやunique symbolの型を保てば、登録集合にない必須トークンは型エラーになります。
|
|
33
|
+
- **リクエストの状態を型で分離できる。** Singleton・Transientのファクトリに渡されるresolverからは、Scopedのトークンを解決できません。
|
|
34
|
+
- **デコレータ設定が不要。** DIのための`experimentalDecorators`・`emitDecoratorMetadata`・Reflectポリフィルを追加する必要がありません。
|
|
35
|
+
- **必要な機能だけ取り込める。** コア・`katagami/disposable`・`katagami/lazy`を別々にインポートできます。ESMと`sideEffects: false`でツリーシェイキングに対応し、破棄はホストのdisposalシンボルと`await using`に連携します。
|
|
36
|
+
|
|
37
|
+
### 他ライブラリとの比較
|
|
38
|
+
|
|
39
|
+
**2026-09-11確認。** npmの`latest`安定版と公式資料をもとに、標準APIの動作を比較しています。[対象バージョン・出典・詳細な注記](./choosing-di.md#comparison-sources)も参照してください。
|
|
40
|
+
|
|
41
|
+
| ライブラリ/確認した版 | 依存の型付けと登録漏れ | スコープの扱い | DIの導入設定 |
|
|
42
|
+
| --- | --- | --- | --- |
|
|
43
|
+
| **Katagami 3.0.2** | **リテラル・unique symbolの登録型を蓄積し、未登録の必須トークンを拒否** | **Singleton・TransientのresolverからScopedを型で除外** | **デコレータ・メタデータ不要、ランタイム依存ゼロ** |
|
|
44
|
+
| InversifyJS 8.2.3 | 型付きの識別子・binding。登録の有無は実行時に確認 | bindingのスコープ指定。resolverの型では分離しない | クラス注入はメタデータ方式。明示的な値・ファクトリbindingも可能 |
|
|
45
|
+
| tsyringe 4.10.0 | クラス・ジェネリックの型を利用。登録の有無は実行時に確認 | 実行時のライフタイム設定。ファクトリにはコンテナを渡す | クラス注入にデコレータとReflectメタデータのポリフィル |
|
|
46
|
+
| TypeDI 0.10.0 | クラス・`Token<T>`の型を利用。登録の有無は実行時に確認 | 共有・Transientと名前付きコンテナ | TypeScriptの導入手順はデコレータと`reflect-metadata`を使用 |
|
|
47
|
+
| Awilix 13.0.5 | 登録からcradleの型を推論。`resolve`の広いオーバーロードは未登録名も許可 | `strict: true`でライフタイム漏れを実行時に検出 | デコレータ・メタデータ不要 |
|
|
48
|
+
| NestJS 12.0.1 | 型付きprovider。モジュールとproviderの依存グラフは実行時に解決 | Requestスコープが依存元へ伝播 | フレームワークのモジュールとメタデータ方式のクラス注入 |
|
|
49
|
+
| Effect 3.22.2 | `Effect`・`Layer`の型で必要なサービスを追跡 | 型付き`Scope`とfinalizer。DIコンテナとは異なるライフタイムモデル | デコレータ・メタデータ不要。Effectのサービス・Layerを使用 |
|
|
50
|
+
| typed-inject 5.0.0 | 文字列トークンを蓄積し、`inject`タプルも検査 | Singleton・Transientと子injector。独立したScoped登録はない | デコレータ・メタデータ不要、ランタイム依存ゼロ |
|
|
51
|
+
|
|
52
|
+
Awilixのcradle推論、typed-injectの登録検査、Effectのサービス要求の型検査も、それぞれコンパイル時の機能です。Katagamiは、**登録集合とスコープ制約を、直接`r.resolve(token)`を呼べるファクトリAPIで組み合わせられる**点を重視しています。[型の保証範囲](./type-safety.md)にあるクラストークン・事前宣言・変更可能な参照の条件も適用されます。
|
|
53
|
+
|
|
54
|
+
| ライブラリ | ライフタイム/スコープ | 非同期サービス | リソース破棄 |
|
|
55
|
+
| --- | --- | --- | --- |
|
|
56
|
+
| **Katagami** | **Singleton・Transient・Scoped、ネストしたスコープ** | **`Promise<T>`を推論。依存は明示的にawait** | **`disposable()`でdisposalシンボルと`await using`に連携** |
|
|
57
|
+
| InversifyJS | Singleton・Transient・Request(1回の解決グラフ)、コンテナ階層 | `getAsync`・`getAllAsync`が依存の完了を待機 | Singletonのdeactivation handler |
|
|
58
|
+
| tsyringe | Singleton・Transient・ResolutionScoped・ContainerScoped | Promiseを返すファクトリを登録可能。利用側で処理 | 構築したDisposableを`container.dispose()`で破棄 |
|
|
59
|
+
| TypeDI | 共有・Transient、名前付きコンテナ | Promiseをサービス値として扱い、利用側で処理 | reset・削除時に`destroy()`を呼べるが、戻り値のPromiseは待機しない |
|
|
60
|
+
| Awilix | Singleton・Transient・Scoped | Promiseを返すファクトリを登録可能。利用側で処理 | キャッシュしたSingleton・Scopedに登録済みdisposerを適用 |
|
|
61
|
+
| NestJS | Singleton・Transient・HTTPリクエスト、スコープ伝播 | 依存providerの非同期初期化を待ってから構築 | アプリのライフサイクルフック。Requestスコープのクラスは対象外 |
|
|
62
|
+
| Effect | メモ化されたLayerと明示的なリソーススコープ | 非同期処理を含むEffectによる取得 | Scopeのfinalizerと`acquireRelease` |
|
|
63
|
+
| typed-inject | Singleton・Transient、破棄可能な子injector | ファクトリが返すPromiseの型も推論 | 所有するインスタンスの`dispose()`をawait |
|
|
64
|
+
|
|
65
|
+
InversifyJSのRequestは1回の解決グラフであり、HTTPリクエストとは異なります。また、Promiseを値として返せることと、依存のPromiseを自動的に待って注入することは別の機能です。[モジュール合成・複数解決・拡張機能の比較](./choosing-di.md#composition-and-tooling)も掲載しています。
|
|
66
|
+
|
|
67
|
+
## AIエージェントによるコーディングで役立つ理由
|
|
68
|
+
|
|
69
|
+
エージェントが依存関係を変更し、TypeScriptの型チェックを実行し、診断をもとに修正する。この手順に、登録漏れやライフタイムの誤用を検出する具体的なチェックを組み込めます。依存関係は通常のTypeScriptのファクトリとして記述します。
|
|
70
|
+
|
|
71
|
+
例えば、リクエスト固有の状態をSingletonのファクトリから解決しようとすると、型エラーになります。
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createContainer } from 'katagami';
|
|
75
|
+
|
|
76
|
+
createContainer()
|
|
77
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
78
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
79
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
この例では、handlerもregisterScopedで登録すると解決できます。@ts-expect-errorは失敗例をCIで検証するための注記です。実際のアプリではエラーを抑制せず、ライフタイムを修正してnpx tsc --noEmitを実行します。
|
|
83
|
+
|
|
84
|
+
## 型の蓄積方式と保証範囲
|
|
85
|
+
|
|
86
|
+
デフォルトのcreateContainer()では、登録から型が積み上がります。リテラルキーやunique symbolの型を保てば、見えている登録集合に含まれないトークンは型エラーになります。事前にサービスの型マップを書く必要はありません。
|
|
87
|
+
|
|
88
|
+
クラストークンにはTypeScriptの構造的型付けが適用されるため、同じ構造の別クラスを区別できない場合があります。また、createContainer<Services>()で事前宣言したキーは、未登録でも型として見えるようになります。この2つは蓄積方式の通常の登録チェックとは分けて説明しています。
|
|
89
|
+
|
|
90
|
+
Singleton・Transient・Scoped、use()によるモジュール合成、非同期ファクトリ、複数・オプショナル解決、リソース破棄、遅延解決をサポートします。依存が少ない場合は、通常の引数やコンストラクタによる受け渡しでも十分です。
|
|
91
|
+
|
|
92
|
+
## ガイドと実行可能な例
|
|
93
|
+
|
|
94
|
+
- [AIコーディングガイド(英語)](./ai-coding-agents.md)
|
|
95
|
+
- [型の保証範囲(英語)](./type-safety.md)
|
|
96
|
+
- [API・利用ガイド(英語)](./guide.md)
|
|
97
|
+
- [リクエストスコープのスターター(英語)](../examples/request-scope/README.md)
|
|
98
|
+
- [DIの選び方(英語)](./choosing-di.md)
|
|
99
|
+
- [AIと型に関する日本語記事](./articles/ai-coding-agents.ja.md)
|
|
100
|
+
|
|
101
|
+
サンプルの型チェックと実行テストはCIで検証します。AIの修正成功率やトークン削減効果は未測定であり、性能向上の数値は主張していません。
|
|
102
|
+
|
|
103
|
+
名前の由来は、伝統的な染色で模様を写す「型紙」です。型紙を重ねるように、登録ごとに型が積み上がります。
|
|
104
|
+
|
|
105
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**TypeScript를 위한 타입 안전한 의존성 주입(DI) 컨테이너.**
|
|
6
|
+
|
|
7
|
+
AI 코딩 에이전트가 작성한 코드에서도 의존 관계를 명시하고 타입으로 검사하세요. Katagami는 등록할 때마다 타입을 누적하고, 팩터리에서 접근 가능한 토큰과 비동기 반환값을 추적합니다. 데코레이터, reflect-metadata, 런타임 의존 패키지가 필요하지 않습니다.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 빠른 시작
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Katagami를 선택하는 이유와 라이브러리 비교
|
|
29
|
+
|
|
30
|
+
**등록에서 추론한 타입, 컴파일 시점의 스코프 제한, 런타임 의존성 없음**을 일반 TypeScript 팩터리에서 함께 사용할 수 있습니다. 데코레이터나 메타데이터 설정이 필요 없으며, 리소스 정리와 지연 해석은 별도 진입점으로 가져옵니다.
|
|
31
|
+
|
|
32
|
+
**2026-09-11 확인.** npm의 안정 버전과 공식 자료를 비교했습니다. [버전과 출처](./choosing-di.md#comparison-sources), [비동기·정리 기능까지 포함한 전체 비교](../README.md#library-comparison)를 참고하세요.
|
|
33
|
+
|
|
34
|
+
| 라이브러리 / 버전 | 의존성 타입과 등록 확인 | 스코프 정책 |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **리터럴·unique symbol 등록을 누적하고 미등록 필수 토큰 거부** | **Singleton·Transient 팩터리에서 Scoped 토큰을 타입으로 제외** |
|
|
37
|
+
| InversifyJS 8.2.3 | 타입이 있는 binding, 등록 여부는 런타임 확인 | binding의 라이프타임 설정 |
|
|
38
|
+
| tsyringe 4.10.0 | 클래스·제네릭 타입, 등록 여부는 런타임 확인 | 라이프타임 설정과 자식 컨테이너 |
|
|
39
|
+
| TypeDI 0.10.0 | 클래스·`Token<T>`, 등록 여부는 런타임 확인 | 공유·Transient 서비스와 이름 있는 컨테이너 |
|
|
40
|
+
| Awilix 13.0.5 | 등록에서 cradle 추론. 넓은 `resolve`는 미등록 이름도 허용 | `strict: true`로 런타임 라이프타임 검사 |
|
|
41
|
+
| NestJS 12.0.1 | 타입이 있는 provider, 런타임 의존성 그래프 | Request 스코프가 의존하는 쪽으로 전파 |
|
|
42
|
+
| Effect 3.22.2 | `Effect`·`Layer` 타입으로 필요한 서비스 추적 | 타입이 있는 `Scope`와 finalizer |
|
|
43
|
+
| typed-inject 5.0.0 | 문자열 토큰 누적과 `inject` 튜플 검사 | Singleton·Transient, 자식 injector |
|
|
44
|
+
|
|
45
|
+
Awilix, Effect, typed-inject에도 컴파일 시점 기능이 있습니다. Katagami는 등록 확인과 스코프 제한을 직접 `r.resolve(token)`을 호출하는 API로 결합합니다. [토큰 타입·클래스·변경 가능한 참조의 조건](./type-safety.md)이 적용됩니다.
|
|
46
|
+
|
|
47
|
+
## AI 코딩 에이전트와 함께 사용하기
|
|
48
|
+
|
|
49
|
+
에이전트가 의존 관계를 수정하고 TypeScript 검사기를 실행한 뒤 진단에 따라 수정하는 흐름을 만듭니다. 팩터리에 의존 관계가 일반 TypeScript 코드로 드러납니다.
|
|
50
|
+
|
|
51
|
+
예를 들어 Singleton 팩터리에서 요청별 Scoped 상태를 참조하면 타입 오류가 발생합니다.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
handler를 registerScoped로 등록하면 이 오류를 해결할 수 있습니다. @ts-expect-error는 실패 예제를 검증하기 위한 것입니다. 앱에서는 오류를 억제하지 말고 수명을 수정한 뒤 npx tsc --noEmit을 실행하세요.
|
|
63
|
+
|
|
64
|
+
## 누적 타입과 보장 범위
|
|
65
|
+
|
|
66
|
+
기본 createContainer()는 등록에서 타입을 누적합니다. 리터럴 키와 unique symbol 타입을 유지하면, 현재 보이는 등록 집합에 없는 토큰은 거부됩니다. 별도의 서비스 타입 맵은 필요하지 않습니다.
|
|
67
|
+
|
|
68
|
+
클래스 토큰은 구조적 타이핑을 따르므로 구조가 같은 다른 클래스가 허용될 수 있습니다. createContainer<Services>()에 미리 선언한 키 역시 실제 등록이 없어도 타입에 나타납니다.
|
|
69
|
+
|
|
70
|
+
Singleton, Transient, Scoped 수명, use() 모듈 합성, 비동기 팩터리, 선택적·다중 해석, 리소스 정리 및 지연 해석을 지원합니다. 의존성이 적다면 일반 함수나 생성자 매개변수로 충분할 수 있습니다.
|
|
71
|
+
|
|
72
|
+
## 가이드와 실행 가능한 예제
|
|
73
|
+
|
|
74
|
+
- [AI 코딩 가이드 (영어)](./ai-coding-agents.md)
|
|
75
|
+
- [타입 보장 범위 (영어)](./type-safety.md)
|
|
76
|
+
- [API와 사용 가이드 (영어)](./guide.md)
|
|
77
|
+
- [요청 스코프 스타터 (영어)](../examples/request-scope/README.md)
|
|
78
|
+
- [DI 선택 가이드 (영어)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
타입 예제와 실행 테스트는 CI에서 검사합니다. AI 수정 성공률이나 토큰 절감 효과는 아직 측정하지 않았습니다.
|
|
81
|
+
|
|
82
|
+
이름은 일본 전통 염색의 형지인 型紙에서 왔습니다. 형지를 겹치듯 등록마다 타입이 누적됩니다.
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**适用于 TypeScript 的类型安全依赖注入(DI)容器。**
|
|
6
|
+
|
|
7
|
+
即使代码由 AI 编程智能体编写,也能显式描述依赖关系并进行类型检查。Katagami 随注册逐步累积类型,检查工厂可访问的依赖,并追踪异步返回值。无需装饰器、reflect-metadata 或运行时依赖包。
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 为什么选择 Katagami:库对比
|
|
29
|
+
|
|
30
|
+
Katagami 在普通 TypeScript 工厂中结合了**从注册推导类型、编译时作用域限制、零运行时依赖**。无需装饰器或元数据配置,资源清理和延迟解析可通过独立入口按需导入。
|
|
31
|
+
|
|
32
|
+
**核查日期:2026-09-11。** 对照 npm 稳定版和官方资料;参见[版本与来源](./choosing-di.md#comparison-sources)及[包含异步和清理功能的完整对比](../README.md#library-comparison)。
|
|
33
|
+
|
|
34
|
+
| 库/版本 | 依赖类型与注册检查 | 作用域策略 |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **累积字面量、unique symbol 的注册类型,拒绝未注册的必需 token** | **从 Singleton、Transient 工厂的 resolver 类型中排除 Scoped token** |
|
|
37
|
+
| InversifyJS 8.2.3 | 有类型的 binding;运行时检查是否已绑定 | binding 的生命周期设置 |
|
|
38
|
+
| tsyringe 4.10.0 | 类与泛型类型;运行时检查注册 | 生命周期设置与子容器 |
|
|
39
|
+
| TypeDI 0.10.0 | 类与 `Token<T>`;运行时检查注册 | 共享、Transient 服务与命名容器 |
|
|
40
|
+
| Awilix 13.0.5 | 从注册推导 cradle;宽泛的 `resolve` 仍接受未知名称 | `strict: true` 在运行时检查生命周期泄漏 |
|
|
41
|
+
| NestJS 12.0.1 | 有类型的 provider;运行时解析依赖图 | Request 作用域向依赖方传播 |
|
|
42
|
+
| Effect 3.22.2 | 通过 `Effect`、`Layer` 类型追踪所需服务 | 有类型的 `Scope` 与 finalizer |
|
|
43
|
+
| typed-inject 5.0.0 | 累积字符串 token,检查 `inject` 元组 | Singleton、Transient 与子 injector |
|
|
44
|
+
|
|
45
|
+
Awilix、Effect、typed-inject 也有编译时检查能力。Katagami 的特点是通过直接调用 `r.resolve(token)` 的 API 结合注册检查与作用域限制。[窄 token 类型、类和可变引用的边界](./type-safety.md)仍然适用。
|
|
46
|
+
|
|
47
|
+
## 配合 AI 编程智能体使用
|
|
48
|
+
|
|
49
|
+
让智能体修改依赖关系,运行 TypeScript 检查,再根据诊断修复。显式工厂让依赖关系直接体现在普通 TypeScript 代码中。
|
|
50
|
+
|
|
51
|
+
例如,Singleton 工厂访问请求级 Scoped 状态时,会出现类型错误。
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
将 handler 改为 registerScoped 即可修正此例。@ts-expect-error 用于在 CI 中验证失败示例。在应用中应修正生命周期,而非抑制错误,然后运行 npx tsc --noEmit。
|
|
63
|
+
|
|
64
|
+
## 类型累积与保证范围
|
|
65
|
+
|
|
66
|
+
默认的 createContainer() 从注册中累积类型。保留字面量键或 unique symbol 类型时,当前可见注册集合之外的令牌会被拒绝,无需手写服务类型映射。
|
|
67
|
+
|
|
68
|
+
类令牌遵循结构类型规则,因此可能接受结构相同的另一个类。通过 createContainer<Services>() 预先声明的键,即使没有实际注册,也会出现在类型中。
|
|
69
|
+
|
|
70
|
+
支持 Singleton、Transient、Scoped 生命周期、use() 模块组合、异步工厂、可选及多重解析、资源清理和延迟解析。依赖较少时,普通函数或构造函数参数可能已经足够。
|
|
71
|
+
|
|
72
|
+
## 指南与可运行示例
|
|
73
|
+
|
|
74
|
+
- [AI 编程指南(英语)](./ai-coding-agents.md)
|
|
75
|
+
- [类型保证范围(英语)](./type-safety.md)
|
|
76
|
+
- [API 与使用指南(英语)](./guide.md)
|
|
77
|
+
- [请求作用域入门示例(英语)](../examples/request-scope/README.md)
|
|
78
|
+
- [DI 选型指南(英语)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
类型示例及运行测试由 CI 验证。尚未测量 AI 修复成功率或令牌节省效果。
|
|
81
|
+
|
|
82
|
+
名称来自日本传统染色中使用的“型纸”。如同叠加型纸,类型也随注册逐步累积。
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[English](../README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-TW.md) | [简体中文](./README.zh-CN.md) | [Español](./README.es.md) | [Deutsch](./README.de.md) | [Français](./README.fr.md)
|
|
2
|
+
|
|
3
|
+
# Katagami
|
|
4
|
+
|
|
5
|
+
**適用於 TypeScript 的型別安全依賴注入(DI)容器。**
|
|
6
|
+
|
|
7
|
+
即使程式碼由 AI 程式設計代理撰寫,也能明確描述依賴關係並進行型別檢查。Katagami 隨註冊逐步累積型別,檢查工廠可存取的依賴,並追蹤非同步回傳值。不需要裝飾器、reflect-metadata 或執行階段依賴套件。
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/katagami)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install katagami
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 快速開始
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createContainer, createScope } from 'katagami';
|
|
19
|
+
|
|
20
|
+
const container = createContainer()
|
|
21
|
+
.registerSingleton('name', () => 'Ada')
|
|
22
|
+
.registerScoped('greeting', r => `Hello, ${r.resolve('name')}!`);
|
|
23
|
+
|
|
24
|
+
const greeting: string = createScope(container).resolve('greeting');
|
|
25
|
+
console.log(greeting);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 為什麼選擇 Katagami:函式庫比較
|
|
29
|
+
|
|
30
|
+
Katagami 在一般 TypeScript 工廠中結合了**從註冊推導型別、編譯時作用域限制、零執行期依賴**。不需要裝飾器或中繼資料設定,資源清理與延遲解析可透過獨立入口按需匯入。
|
|
31
|
+
|
|
32
|
+
**查核日期:2026-09-11。** 對照 npm 穩定版與官方資料;請參閱[版本與來源](./choosing-di.md#comparison-sources)及[包含非同步與清理功能的完整比較](../README.md#library-comparison)。
|
|
33
|
+
|
|
34
|
+
| 函式庫/版本 | 依賴型別與註冊檢查 | 作用域策略 |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Katagami 3.0.2** | **累積字面值、unique symbol 的註冊型別,拒絕未註冊的必要 token** | **從 Singleton、Transient 工廠的 resolver 型別中排除 Scoped token** |
|
|
37
|
+
| InversifyJS 8.2.3 | 具型別的 binding;執行時檢查是否已綁定 | binding 的生命週期設定 |
|
|
38
|
+
| tsyringe 4.10.0 | 類別與泛型型別;執行時檢查註冊 | 生命週期設定與子容器 |
|
|
39
|
+
| TypeDI 0.10.0 | 類別與 `Token<T>`;執行時檢查註冊 | 共用、Transient 服務與具名容器 |
|
|
40
|
+
| Awilix 13.0.5 | 從註冊推導 cradle;寬泛的 `resolve` 仍接受未知名稱 | `strict: true` 在執行時檢查生命週期洩漏 |
|
|
41
|
+
| NestJS 12.0.1 | 具型別的 provider;執行時解析依賴圖 | Request 作用域向依賴方傳播 |
|
|
42
|
+
| Effect 3.22.2 | 透過 `Effect`、`Layer` 型別追蹤所需服務 | 具型別的 `Scope` 與 finalizer |
|
|
43
|
+
| typed-inject 5.0.0 | 累積字串 token,檢查 `inject` 元組 | Singleton、Transient 與子 injector |
|
|
44
|
+
|
|
45
|
+
Awilix、Effect、typed-inject 也有編譯時檢查能力。Katagami 的特色是透過直接呼叫 `r.resolve(token)` 的 API 結合註冊檢查與作用域限制。[窄 token 型別、類別與可變參照的邊界](./type-safety.md)仍然適用。
|
|
46
|
+
|
|
47
|
+
## 與 AI 程式設計代理搭配使用
|
|
48
|
+
|
|
49
|
+
讓代理修改依賴關係,執行 TypeScript 檢查,再根據診斷修正。明確的工廠讓依賴關係直接呈現在一般 TypeScript 程式碼中。
|
|
50
|
+
|
|
51
|
+
例如,Singleton 工廠存取請求層級的 Scoped 狀態時,會出現型別錯誤。
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createContainer } from 'katagami';
|
|
55
|
+
|
|
56
|
+
createContainer()
|
|
57
|
+
.registerScoped('request', () => ({ id: crypto.randomUUID() }))
|
|
58
|
+
// @ts-expect-error — singleton factories cannot access scoped tokens
|
|
59
|
+
.registerSingleton('handler', r => r.resolve('request'));
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
將 handler 改為 registerScoped 即可修正此例。@ts-expect-error 用於在 CI 中驗證失敗範例。在應用程式中應修正生命週期,而非抑制錯誤,再執行 npx tsc --noEmit。
|
|
63
|
+
|
|
64
|
+
## 型別累積與保證範圍
|
|
65
|
+
|
|
66
|
+
預設的 createContainer() 從註冊中累積型別。保留字面值鍵或 unique symbol 型別時,目前可見註冊集合以外的權杖會被拒絕,不需要手寫服務型別映射。
|
|
67
|
+
|
|
68
|
+
類別權杖遵循結構型別規則,因此可能接受結構相同的另一個類別。透過 createContainer<Services>() 預先宣告的鍵,即使沒有實際註冊,也會出現在型別中。
|
|
69
|
+
|
|
70
|
+
支援 Singleton、Transient、Scoped 生命週期、use() 模組組合、非同步工廠、可選及多重解析、資源清理與延遲解析。依賴較少時,一般函式或建構子參數可能已經足夠。
|
|
71
|
+
|
|
72
|
+
## 指南與可執行範例
|
|
73
|
+
|
|
74
|
+
- [AI 程式設計指南(英文)](./ai-coding-agents.md)
|
|
75
|
+
- [型別保證範圍(英文)](./type-safety.md)
|
|
76
|
+
- [API 與使用指南(英文)](./guide.md)
|
|
77
|
+
- [請求範圍入門範例(英文)](../examples/request-scope/README.md)
|
|
78
|
+
- [DI 選型指南(英文)](./choosing-di.md)
|
|
79
|
+
|
|
80
|
+
型別範例與執行測試由 CI 驗證。尚未測量 AI 修正成功率或 token 節省效果。
|
|
81
|
+
|
|
82
|
+
名稱來自日本傳統染色使用的「型紙」。如同疊加型紙,型別也隨註冊逐步累積。
|
|
83
|
+
|
|
84
|
+
MIT
|