katagami 3.0.3 → 4.0.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.
Files changed (44) hide show
  1. package/README.md +9 -7
  2. package/dist/chunk-R66WOZUM.js +71 -0
  3. package/dist/container/index.d.cts +142 -35
  4. package/dist/container/index.d.ts +142 -35
  5. package/dist/container/policy.d.cts +36 -0
  6. package/dist/container/policy.d.ts +36 -0
  7. package/dist/disposable/index.cjs +27 -5
  8. package/dist/disposable/index.d.cts +17 -7
  9. package/dist/disposable/index.d.ts +17 -7
  10. package/dist/disposable/index.js +2 -41
  11. package/dist/entrypoint/index.d.cts +20 -0
  12. package/dist/entrypoint/index.d.ts +20 -0
  13. package/dist/index.cjs +551 -149
  14. package/dist/index.d.cts +8 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.js +495 -150
  17. package/dist/internal.d.cts +65 -0
  18. package/dist/internal.d.ts +65 -0
  19. package/dist/metadata/index.d.cts +67 -0
  20. package/dist/metadata/index.d.ts +67 -0
  21. package/dist/resolver/index.d.cts +5 -0
  22. package/dist/resolver/index.d.ts +5 -0
  23. package/dist/scope/index.d.cts +49 -24
  24. package/dist/scope/index.d.ts +49 -24
  25. package/dist/scope/operations.d.cts +22 -0
  26. package/dist/scope/operations.d.ts +22 -0
  27. package/docs/README.de.md +3 -2
  28. package/docs/README.es.md +3 -2
  29. package/docs/README.fr.md +3 -2
  30. package/docs/README.ja.md +7 -6
  31. package/docs/README.ko.md +3 -2
  32. package/docs/README.zh-CN.md +3 -2
  33. package/docs/README.zh-TW.md +3 -2
  34. package/docs/ai-coding-agents.md +3 -3
  35. package/docs/articles/ai-coding-agents.md +1 -1
  36. package/docs/articles/request-scope.md +2 -1
  37. package/docs/choosing-di.md +7 -6
  38. package/docs/guide.md +35 -4
  39. package/docs/registration-policies.ja.md +261 -0
  40. package/docs/registration-policies.md +435 -0
  41. package/docs/type-safety.md +13 -4
  42. package/llms.txt +1 -0
  43. package/package.json +1 -1
  44. package/dist/chunk-J2NYR3SH.js +0 -6
package/docs/README.es.md CHANGED
@@ -29,11 +29,11 @@ console.log(greeting);
29
29
 
30
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
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).
32
+ **Revisado el 2026-09-11**, con versiones estables de npm y fuentes oficiales. Los datos de Katagami describen esta versión (4.0.0). 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
33
 
34
34
  | Biblioteca / versión | Tipos y comprobación de registros | Política de ámbitos |
35
35
  | --- | --- | --- |
36
- | **Katagami 3.0.3** | **Acumula tokens literales/unique symbol; rechaza tokens requeridos sin registrar** | **Excluye tokens Scoped del resolver de factorías Singleton/Transient** |
36
+ | **Katagami 4.0.0** | **Acumula tokens literales/unique symbol; rechaza tokens requeridos sin registrar** | **Excluye tokens Scoped del resolver de factorías Singleton/Transient** |
37
37
  | InversifyJS 8.2.3 | Bindings tipados; existencia comprobada en ejecución | Ciclo de vida configurado por binding |
38
38
  | tsyringe 4.10.0 | Tipos de clase/genéricos; registros comprobados en ejecución | Ciclos de vida y contenedores hijos |
39
39
  | TypeDI 0.10.0 | Clases y `Token<T>`; registros comprobados en ejecución | Servicios compartidos/Transient y contenedores con nombre |
@@ -74,6 +74,7 @@ Incluye ciclos de vida Singleton, Transient y Scoped, composición con use(), f
74
74
  - [Guía para agentes de IA (inglés)](./ai-coding-agents.md)
75
75
  - [Garantías de tipos (inglés)](./type-safety.md)
76
76
  - [Guía de uso y API (inglés)](./guide.md)
77
+ - [Políticas de registro y operaciones (inglés)](./registration-policies.md)
77
78
  - [Ejemplo de ámbitos por petición (inglés)](../examples/request-scope/README.md)
78
79
  - [Cómo elegir DI (inglés)](./choosing-di.md)
79
80
 
package/docs/README.fr.md CHANGED
@@ -29,11 +29,11 @@ console.log(greeting);
29
29
 
30
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
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).
32
+ **Vérifié le 2026-09-11**, à partir des versions stables npm et des sources officielles. Les données de Katagami décrivent cette version (4.0.0). 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
33
 
34
34
  | Bibliothèque / version | Types et vérification des enregistrements | Politique de portée |
35
35
  | --- | --- | --- |
36
- | **Katagami 3.0.3** | **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** |
36
+ | **Katagami 4.0.0** | **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
37
  | InversifyJS 8.2.3 | Bindings typés ; existence vérifiée à l'exécution | Durée de vie configurée par binding |
38
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
39
  | TypeDI 0.10.0 | Classes et `Token<T>` ; enregistrements vérifiés à l'exécution | Services partagés/Transient, conteneurs nommés |
@@ -74,6 +74,7 @@ Prend en charge Singleton, Transient et Scoped, la composition avec use(), les f
74
74
  - [Guide pour agents IA (anglais)](./ai-coding-agents.md)
75
75
  - [Garanties de types (anglais)](./type-safety.md)
76
76
  - [Guide et API (anglais)](./guide.md)
77
+ - [Politiques d'enregistrement et opérations (anglais)](./registration-policies.md)
77
78
  - [Exemple de portée par requête (anglais)](../examples/request-scope/README.md)
78
79
  - [Choisir une approche DI (anglais)](./choosing-di.md)
79
80
 
package/docs/README.ja.md CHANGED
@@ -36,13 +36,13 @@ Katagamiの強みは、**登録からの型推論・コンパイル時のスコ
36
36
 
37
37
  ### 他ライブラリとの比較
38
38
 
39
- **8ライブラリ・27項目の比較。2026-09-11確認。** 表中のnpm `latest`安定版と公式資料をもとにしています。[対象バージョン・出典・詳細な注記](./choosing-di.md#comparison-sources)。
39
+ **8ライブラリ・27項目の比較。2026-09-11確認。** 表中のnpm `latest`安定版と公式資料をもとにしています。Katagamiの列は、このリリース(4.0.0)の内容です。[対象バージョン・出典・詳細な注記](./choosing-di.md#comparison-sources)。
40
40
 
41
41
  **✅ 標準で対応 · ⚠️ 条件付き・異なるモデル・利用側での合成 · ➖ その機能の標準対応なし。** 各セルに具体的なAPIや条件を添えています。
42
42
 
43
43
  #### 型安全性・導入設定
44
44
 
45
- | 比較項目 | **Katagami**<br>**3.0.3** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
45
+ | 比較項目 | **Katagami**<br>**4.0.0** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
46
46
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
47
47
  | **ランタイム要件** | **✅ 通常のTypeScript** | ⚠️ クラスDIにReflectメタデータ | ⚠️ クラスDIにReflectメタデータ | ⚠️ Reflectメタデータ設定 | ✅ DIメタデータ不要 | ⚠️ Nestモジュール・メタデータ | ✅ Effect・Layer API | ✅ 通常のTypeScript |
48
48
  | **注入方式** | **明示的なファクトリ・コンストラクタ** | コンストラクタ・プロパティ・ファクトリ | コンストラクタ・ファクトリ | コンストラクタ・プロパティ・ファクトリ | Proxy・Classic・ファクトリ | コンストラクタ・プロパティ・ファクトリ | 関数型サービス・Layer | コンストラクタ・ファクトリ+`inject` |
@@ -56,7 +56,7 @@ Katagamiの強みは、**登録からの型推論・コンパイル時のスコ
56
56
 
57
57
  #### ライフタイム・非同期・リソース破棄
58
58
 
59
- | 比較項目 | **Katagami**<br>**3.0.3** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
59
+ | 比較項目 | **Katagami**<br>**4.0.0** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
60
60
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
61
61
  | **ライフタイム** | **✅ Singleton・Transient・Scoped** | ✅ Singleton・Transient・Request | ✅ Singleton・Transient・Resolution・Container | ✅ 共有・Transient | ✅ Singleton・Transient・Scoped | ✅ Singleton・Transient・Request | ⚠️ メモ化/fresh Layer+Scope | ✅ Singleton・Transient |
62
62
  | **リクエスト/Scopedライフタイム³** | **✅ リクエストごとに明示的なScope** | ⚠️ 1回の解決グラフ | ✅ Container/Resolution単位 | ⚠️ 名前付きコンテナ | ✅ リクエストごとに明示的なScope | ✅ HTTPリクエスト単位 | ⚠️ リソースScope | ⚠️ 子injector。Scoped登録なし |
@@ -69,7 +69,7 @@ Katagamiの強みは、**登録からの型推論・コンパイル時のスコ
69
69
 
70
70
  #### 合成・拡張機能
71
71
 
72
- | 比較項目 | **Katagami**<br>**3.0.3** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
72
+ | 比較項目 | **Katagami**<br>**4.0.0** | InversifyJS<br>8.2.3 | tsyringe<br>4.10.0 | TypeDI<br>0.10.0 | Awilix<br>13.0.5 | NestJS<br>12.0.1 | Effect<br>3.22.2 | typed-inject<br>5.0.0 |
73
73
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
74
74
  | **オプショナル解決** | **✅ `tryResolve`・`tryResolveAll`** | ✅ オプショナルget・inject | ✅ オプショナル注入 | ⚠️ `has`で確認して`get` | ✅ `allowUnregistered` | ✅ オプショナル注入 | ✅ `serviceOption` | ⚠️ オプショナル値を合成 |
75
75
  | **複数登録・一括解決** | **✅ `resolveAll`** | ✅ `getAll`・`getAllAsync` | ✅ `injectAll`・`resolveAll` | ✅ `getMany` | ⚠️ コレクション値を登録 | ⚠️ 配列provider | ⚠️ コレクション値を登録 | ⚠️ コレクション値を登録 |
@@ -78,7 +78,7 @@ Katagamiの強みは、**登録からの型推論・コンパイル時のスコ
78
78
  | **自動ロード/検出⁶** | **➖ 明示的な`use()`** | ⚠️ クラスの自動binding | ➖ 明示的な登録 | ➖ 明示的なimport | ✅ `loadModules`(Node) | ⚠️ `DiscoveryService` | ➖ 明示的なLayer | ➖ 明示的なprovider |
79
79
  | **モジュールシステム・合成** | **✅ `use()`** | ✅ コンテナモジュール | ✅ `@registry` | ⚠️ 登録をまとめる | ✅ `loadModules`・`register` | ✅ モジュール・動的モジュール | ✅ Layerの合成 | ⚠️ providerチェーンの合成 |
80
80
  | **循環依存の検出⁷** | **✅ 実行時に循環経路を表示** | ✅ 実行時に検出 | ⚠️ コンストラクタのエラー・`delay` | ⚠️ 型の遅延参照 | ✅ 実行時に循環経路を表示 | ⚠️ 循環エラー・`forwardRef` | ⚠️ Layerの要求型 | ⚠️ 登録順で依存を制限 |
81
- | **ミドルウェア/インターセプタ⁶** | **⚠️ 高階ファクトリで合成** | ✅ activation・deactivationフック | ✅ 解決前後のフック | ⚠️ ファクトリをラップ | ⚠️ ファクトリをラップ | ⚠️ Request用。DIフックとは異なる | ⚠️ Effectを合成 | ⚠️ providerの装飾 |
81
+ | **ミドルウェア/インターセプタ⁶** | **⚠️ `beforeResolve`の検査・高階ファクトリで合成** | ✅ activation・deactivationフック | ✅ 解決前後のフック | ⚠️ ファクトリをラップ | ⚠️ ファクトリをラップ | ⚠️ Request用。DIフックとは異なる | ⚠️ Effectを合成 | ⚠️ providerの装飾 |
82
82
  | **スナップショット/復元⁶** | **➖** | ✅ `snapshot`・`restore` | ➖ | ➖ | ➖ | ➖ | ➖ | ➖ |
83
83
  | **テスト用の差し替え・分離** | **✅ 新しいScope・コンテナ+`use()`** | ✅ 再binding・スナップショット | ✅ 子コンテナで上書き | ✅ 名前付きコンテナ・reset | ✅ 子Scopeで上書き | ✅ `overrideProvider` | ✅ テスト用Layerに差し替え | ✅ 子injectorで上書き |
84
84
 
@@ -92,7 +92,7 @@ Katagamiの強みは、**登録からの型推論・コンパイル時のスコ
92
92
  3. **スコープ:** InversifyJSのRequestは1回の解決グラフで、HTTPリクエストとは異なります。名前付きコンテナ・モジュールのコンテキスト・子injector・EffectのリソースScopeも、それぞれ異なる管理方式です。
93
93
  4. **非同期:** Promiseを返せることと、注入前に依存の完了を自動的に待つことは別です。KatagamiはPromiseを型に残し、`await`を明示します。
94
94
  5. **破棄:** Katagamiは追加の`disposable()`で`Symbol.dispose`・`Symbol.asyncDispose`・`await using`に連携します。所有権と破棄対象はライブラリごとに異なり、InversifyJSのdeactivationはSingleton、Awilixのdisposerはキャッシュした値が対象です。NestのフックはRequestスコープのクラスには適用されません。
95
- 6. **合成と専用API:** サービスの遅延Proxy・型参照の遅延・モジュールの遅延ロードは別の機能です。自動binding・検出も、ファイルの自動ロードとは異なります。Katagamiの`use()`は登録をコピーし、コンテナ自体は変更可能です。ファクトリのラップは専用インターセプタではなく、新しいコンテナでの分離はスナップショットではありません。[合成機能の詳細](./choosing-di.md#composition-and-tooling)。
95
+ 6. **合成と専用API:** サービスの遅延Proxy・型参照の遅延・モジュールの遅延ロードは別の機能です。自動binding・検出も、ファイルの自動ロードとは異なります。Katagamiの`use()`は登録をコピーし、コンテナ自体は変更可能です。ファクトリのラップは専用インターセプタではありません。`beforeResolve`は解決を拒否できますが、結果を置き換えることはできません。新しいコンテナでの分離はスナップショットではありません。[合成機能の詳細](./choosing-di.md#composition-and-tooling)。
96
96
  7. **循環依存:** 実行時の循環検出・参照の遅延・依存の型検査は異なる仕組みです。⚠️は汎用的な循環検出器の存在を意味しません。また、実行時の検出が、あらゆる非同期デッドロックの検出を保証するわけではありません。
97
97
 
98
98
  </details>
@@ -127,6 +127,7 @@ Singleton・Transient・Scoped、use()によるモジュール合成、非同期
127
127
  - [AIコーディングガイド(英語)](./ai-coding-agents.md)
128
128
  - [型の保証範囲(英語)](./type-safety.md)
129
129
  - [API・利用ガイド(英語)](./guide.md)
130
+ - [登録の属性と公開操作(英語)](./registration-policies.md)、[日本語版](./registration-policies.ja.md)
130
131
  - [リクエストスコープのスターター(英語)](../examples/request-scope/README.md)
131
132
  - [DIの選び方(英語)](./choosing-di.md)
132
133
  - [AIと型に関する日本語記事](./articles/ai-coding-agents.ja.md)
package/docs/README.ko.md CHANGED
@@ -29,11 +29,11 @@ console.log(greeting);
29
29
 
30
30
  **등록에서 추론한 타입, 컴파일 시점의 스코프 제한, 런타임 의존성 없음**을 일반 TypeScript 팩터리에서 함께 사용할 수 있습니다. 데코레이터나 메타데이터 설정이 필요 없으며, 리소스 정리와 지연 해석은 별도 진입점으로 가져옵니다.
31
31
 
32
- **2026-09-11 확인.** npm의 안정 버전과 공식 자료를 비교했습니다. [버전과 출처](./choosing-di.md#comparison-sources), [비동기·정리 기능까지 포함한 전체 비교](../README.md#library-comparison)를 참고하세요.
32
+ **2026-09-11 확인.** npm의 안정 버전과 공식 자료를 비교했습니다. Katagami 항목은 이번 릴리스(4.0.0) 기준입니다. [버전과 출처](./choosing-di.md#comparison-sources), [비동기·정리 기능까지 포함한 전체 비교](../README.md#library-comparison)를 참고하세요.
33
33
 
34
34
  | 라이브러리 / 버전 | 의존성 타입과 등록 확인 | 스코프 정책 |
35
35
  | --- | --- | --- |
36
- | **Katagami 3.0.3** | **리터럴·unique symbol 등록을 누적하고 미등록 필수 토큰 거부** | **Singleton·Transient 팩터리에서 Scoped 토큰을 타입으로 제외** |
36
+ | **Katagami 4.0.0** | **리터럴·unique symbol 등록을 누적하고 미등록 필수 토큰 거부** | **Singleton·Transient 팩터리에서 Scoped 토큰을 타입으로 제외** |
37
37
  | InversifyJS 8.2.3 | 타입이 있는 binding, 등록 여부는 런타임 확인 | binding의 라이프타임 설정 |
38
38
  | tsyringe 4.10.0 | 클래스·제네릭 타입, 등록 여부는 런타임 확인 | 라이프타임 설정과 자식 컨테이너 |
39
39
  | TypeDI 0.10.0 | 클래스·`Token<T>`, 등록 여부는 런타임 확인 | 공유·Transient 서비스와 이름 있는 컨테이너 |
@@ -74,6 +74,7 @@ Singleton, Transient, Scoped 수명, use() 모듈 합성, 비동기 팩터리,
74
74
  - [AI 코딩 가이드 (영어)](./ai-coding-agents.md)
75
75
  - [타입 보장 범위 (영어)](./type-safety.md)
76
76
  - [API와 사용 가이드 (영어)](./guide.md)
77
+ - [등록 정책과 공개 작업 (영어)](./registration-policies.md)
77
78
  - [요청 스코프 스타터 (영어)](../examples/request-scope/README.md)
78
79
  - [DI 선택 가이드 (영어)](./choosing-di.md)
79
80
 
@@ -29,11 +29,11 @@ console.log(greeting);
29
29
 
30
30
  Katagami 在普通 TypeScript 工厂中结合了**从注册推导类型、编译时作用域限制、零运行时依赖**。无需装饰器或元数据配置,资源清理和延迟解析可通过独立入口按需导入。
31
31
 
32
- **核查日期:2026-09-11。** 对照 npm 稳定版和官方资料;参见[版本与来源](./choosing-di.md#comparison-sources)及[包含异步和清理功能的完整对比](../README.md#library-comparison)。
32
+ **核查日期:2026-09-11。** 对照 npm 稳定版和官方资料;Katagami 一栏描述本次发布(4.0.0);参见[版本与来源](./choosing-di.md#comparison-sources)及[包含异步和清理功能的完整对比](../README.md#library-comparison)。
33
33
 
34
34
  | 库/版本 | 依赖类型与注册检查 | 作用域策略 |
35
35
  | --- | --- | --- |
36
- | **Katagami 3.0.3** | **累积字面量、unique symbol 的注册类型,拒绝未注册的必需 token** | **从 Singleton、Transient 工厂的 resolver 类型中排除 Scoped token** |
36
+ | **Katagami 4.0.0** | **累积字面量、unique symbol 的注册类型,拒绝未注册的必需 token** | **从 Singleton、Transient 工厂的 resolver 类型中排除 Scoped token** |
37
37
  | InversifyJS 8.2.3 | 有类型的 binding;运行时检查是否已绑定 | binding 的生命周期设置 |
38
38
  | tsyringe 4.10.0 | 类与泛型类型;运行时检查注册 | 生命周期设置与子容器 |
39
39
  | TypeDI 0.10.0 | 类与 `Token<T>`;运行时检查注册 | 共享、Transient 服务与命名容器 |
@@ -74,6 +74,7 @@ createContainer()
74
74
  - [AI 编程指南(英语)](./ai-coding-agents.md)
75
75
  - [类型保证范围(英语)](./type-safety.md)
76
76
  - [API 与使用指南(英语)](./guide.md)
77
+ - [注册策略与公开操作(英语)](./registration-policies.md)
77
78
  - [请求作用域入门示例(英语)](../examples/request-scope/README.md)
78
79
  - [DI 选型指南(英语)](./choosing-di.md)
79
80
 
@@ -29,11 +29,11 @@ console.log(greeting);
29
29
 
30
30
  Katagami 在一般 TypeScript 工廠中結合了**從註冊推導型別、編譯時作用域限制、零執行期依賴**。不需要裝飾器或中繼資料設定,資源清理與延遲解析可透過獨立入口按需匯入。
31
31
 
32
- **查核日期:2026-09-11。** 對照 npm 穩定版與官方資料;請參閱[版本與來源](./choosing-di.md#comparison-sources)及[包含非同步與清理功能的完整比較](../README.md#library-comparison)。
32
+ **查核日期:2026-09-11。** 對照 npm 穩定版與官方資料;Katagami 一欄描述本次發布(4.0.0);請參閱[版本與來源](./choosing-di.md#comparison-sources)及[包含非同步與清理功能的完整比較](../README.md#library-comparison)。
33
33
 
34
34
  | 函式庫/版本 | 依賴型別與註冊檢查 | 作用域策略 |
35
35
  | --- | --- | --- |
36
- | **Katagami 3.0.3** | **累積字面值、unique symbol 的註冊型別,拒絕未註冊的必要 token** | **從 Singleton、Transient 工廠的 resolver 型別中排除 Scoped token** |
36
+ | **Katagami 4.0.0** | **累積字面值、unique symbol 的註冊型別,拒絕未註冊的必要 token** | **從 Singleton、Transient 工廠的 resolver 型別中排除 Scoped token** |
37
37
  | InversifyJS 8.2.3 | 具型別的 binding;執行時檢查是否已綁定 | binding 的生命週期設定 |
38
38
  | tsyringe 4.10.0 | 類別與泛型型別;執行時檢查註冊 | 生命週期設定與子容器 |
39
39
  | TypeDI 0.10.0 | 類別與 `Token<T>`;執行時檢查註冊 | 共用、Transient 服務與具名容器 |
@@ -74,6 +74,7 @@ createContainer()
74
74
  - [AI 程式設計指南(英文)](./ai-coding-agents.md)
75
75
  - [型別保證範圍(英文)](./type-safety.md)
76
76
  - [API 與使用指南(英文)](./guide.md)
77
+ - [註冊策略與公開操作(英文)](./registration-policies.md)
77
78
  - [請求範圍入門範例(英文)](../examples/request-scope/README.md)
78
79
  - [DI 選型指南(英文)](./choosing-di.md)
79
80
 
@@ -1,7 +1,7 @@
1
1
  # TypeScript dependency injection with AI coding agents
2
2
 
3
3
  Use Katagami's accumulated registration types as feedback while an agent edits dependency wiring.
4
- This guide describes the v3 API. Check the installed package version before editing an existing app.
4
+ This guide describes the v4 API. Check the installed package version before editing an existing app.
5
5
 
6
6
  ## A repeatable workflow
7
7
 
@@ -42,7 +42,7 @@ concurrent calls and replacement of infrastructure with a fake.
42
42
  | `No overload matches this call` at `resolve`, often mentioning `never` | Is this exact token registered and visible here? | Register it earlier, correct its spelling, or compose the module first |
43
43
  | The same error inside a singleton/transient factory after a scoped registration | Does the factory capture request state? | Make the consumer scoped, or pass request data into a method without storing it |
44
44
  | A service method does not exist on `Promise<...>` | Is the dependency factory async? | Await the resolution; make the consuming factory async if needed |
45
- | `resolve` does not exist on `Container` | v3 separates registration from resolution | Call `createScope(container).resolve(token)` |
45
+ | `resolve` does not exist on `Container` | Katagami separates registration from resolution | Call `createScope(container).resolve(token)` |
46
46
  | `lazy` rejects a token | Is it an async or PropertyKey token? | Use direct resolution; `lazy` accepts synchronous class tokens |
47
47
  | Runtime `Token ... is not registered` despite a passing type check | Predeclared map, compatible class, widened key or assertion? | Register the actual token and review the type-safety guide |
48
48
 
@@ -52,7 +52,7 @@ expression and the resolver's visible registrations; do not match an error strin
52
52
  ## Project instruction you can copy
53
53
 
54
54
  ```text
55
- Use the installed Katagami v3 API for dependency wiring. Read
55
+ Use the installed Katagami v4 API for dependency wiring. Read
56
56
  node_modules/katagami/docs/ai-coding-agents.md and
57
57
  node_modules/katagami/docs/type-safety.md first.
58
58
  Preserve inferred registration chains and narrow literal/unique-symbol tokens.
@@ -45,7 +45,7 @@ In application code, change the wiring, run `npx tsc --noEmit`, then run behavio
45
45
 
46
46
  ## Make the workflow usable
47
47
 
48
- Give the agent the [v3 usage guide](../ai-coding-agents.md), the application's composition root and
48
+ Give the agent the [v4 usage guide](../ai-coding-agents.md), the application's composition root and
49
49
  its verification command. Have it use the supplied factory resolver, preserve inferred registration
50
50
  types and run the checker after changes. A [runnable request-scope starter](../../examples/request-scope/README.md)
51
51
  shows fake injection, concurrent calls and cleanup on both success and failure.
@@ -41,7 +41,8 @@ stays shared, and resources are cleaned on rejection as well as success. The
41
41
 
42
42
  The compile-time example uses accumulated literal keys. A broad type annotation, predeclared map,
43
43
  compatible class token, assertion or captured external resolver can change what is checked.
44
- The runtime captive-dependency guard also has limits around work resumed after an `await`.
44
+ The runtime captive-dependency guard follows the factory's resolver, including after an `await`, but not
45
+ a scope captured from elsewhere.
45
46
  The [type-safety guide](../type-safety.md) explains the exact scope of the guarantee.
46
47
 
47
48
  Katagami provides Singleton, Transient and Scoped lifetimes without decorator metadata.
@@ -37,12 +37,12 @@ typing, mutable aliases and predeclared-map boundaries.
37
37
  Reviewed **2026-09-11**. Competitor versions are the npm `latest` dist-tag versions observed on that date,
38
38
  not prerelease versions or unreleased features from repository default branches. TypeDI refers to
39
39
  the `typedi` package maintained under TypeStack, not similarly named forks. NestJS's version is
40
- the version of `@nestjs/core`. The comparison uses Effect **3** documentation explicitly. Katagami 3.0.3 is this documentation
41
- release; its runtime and public APIs are unchanged from the reviewed 3.0.1 package.
40
+ the version of `@nestjs/core`. The comparison uses Effect **3** documentation explicitly. Katagami entries describe
41
+ this release, 4.0.0.
42
42
 
43
43
  | Package | Reviewed version and registry metadata | Primary documentation / shipped API |
44
44
  | --- | --- | --- |
45
- | Katagami | [3.0.1](https://registry.npmjs.org/katagami/3.0.1) | [Type guarantees](./type-safety.md), [API guide](./guide.md) |
45
+ | Katagami | [4.0.0](https://registry.npmjs.org/katagami/4.0.0) | [Type guarantees](./type-safety.md), [API guide](./guide.md), [registration policies](./registration-policies.md) |
46
46
  | InversifyJS | [8.2.3](https://registry.npmjs.org/inversify/8.2.3) | [8.x setup](https://inversify.io/docs/introduction/getting-started/), [bindings](https://inversify.io/docs/fundamentals/binding/), [container API](https://inversify.io/docs/api/container/) |
47
47
  | tsyringe | [4.10.0](https://registry.npmjs.org/tsyringe/4.10.0) | [Release README](https://github.com/microsoft/tsyringe/blob/e033769d97cfb6cc4a8569e2b50eb32015453302/README.md), [container types](https://github.com/microsoft/tsyringe/blob/e033769d97cfb6cc4a8569e2b50eb32015453302/src/types/dependency-container.ts) |
48
48
  | TypeDI | [0.10.0](https://registry.npmjs.org/typedi/0.10.0) | [Release source](https://github.com/typestack/typedi/tree/v0.10.0), [container implementation](https://github.com/typestack/typedi/blob/v0.10.0/src/container-instance.class.ts) |
@@ -55,7 +55,7 @@ Versioned npm tarballs were also inspected. A focused TypeScript 5.9.3 check con
55
55
  Awilix 13.0.5 infers registered cradle properties and rejects an unknown cradle property, while
56
56
  `resolve('missing')` still compiles through its broad overload. The same check confirmed that
57
57
  typed-inject 5.0.0 and Katagami 3.0.1 reject an unknown literal token, and that Awilix and
58
- typed-inject infer a Promise returned by a factory. This is a type check, not a performance benchmark
58
+ typed-inject infer a Promise returned by a factory. Katagami 4.0.0 keeps that rejection in its type tests. This is a type check, not a performance benchmark
59
59
  or an exhaustive runtime compatibility test.
60
60
 
61
61
  ## Reading the comparison
@@ -115,7 +115,7 @@ application code can implement the pattern; it does not claim a dedicated contai
115
115
 
116
116
  | Library | Optional / multiple resolution | Composition, discovery and extension |
117
117
  | --- | --- | --- |
118
- | Katagami | `tryResolve`, `resolveAll`, `tryResolveAll` | `use()` copies registrations; opt-in `lazy()`; ordinary higher-order factories |
118
+ | Katagami | `tryResolve`, `resolveAll`, `tryResolveAll` | `use()` copies registrations; opt-in `lazy()`; `beforeResolve` checks; ordinary higher-order factories |
119
119
  | InversifyJS | Optional get/inject, `getAll`, `getAllAsync` | Container modules/hierarchy, autobinding, contextual constraints, activation/deactivation, snapshot/restore |
120
120
  | tsyringe | Optional inject, `injectAll`, `resolveAll` | `@registry`, child containers, before/after resolution interceptors, `delay()`, `predicateAwareClassFactory` |
121
121
  | TypeDI | `has` before `get`; `getMany` with multiple registrations | Named containers, factory configuration and service decorators |
@@ -126,7 +126,8 @@ application code can implement the pattern; it does not claim a dedicated contai
126
126
 
127
127
  Katagami does not implement filesystem auto-discovery or snapshot/restore, and its runtime
128
128
  containers are mutable. `use()` and fresh test containers provide explicit composition and test
129
- substitution. Factory wrappers are an application pattern, not a middleware/interceptor API.
129
+ substitution. Factory wrappers are an application pattern, not a middleware/interceptor API, and
130
+ `beforeResolve` can reject a resolution but does not replace or wrap its result.
130
131
  Similarly, a lazy module loader is not the same feature as a proxy that constructs one service on
131
132
  first property access, and a resolution graph scope is not an HTTP request scope.
132
133
 
package/docs/guide.md CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  Katagami publishes ESM, CommonJS and TypeScript declarations, with no runtime dependencies.
6
6
  The CI consumer checks run on Node.js 22 and 24; runtime tests and examples also run with Bun.
7
- Type examples use TypeScript 5.9, `strict: true`, and the `ES2022` and `ESNext.Disposable` libraries.
7
+ The published declarations require TypeScript 5.0 or later. Type examples use TypeScript 5.9,
8
+ `strict: true`, and the `ES2022` and `ESNext.Disposable` libraries.
8
9
  Browser APIs in examples, such as `crypto.randomUUID`, additionally need the `DOM` library.
9
10
 
10
11
  Core DI does not require decorator compiler flags, metadata emission or polyfills.
@@ -57,7 +58,10 @@ service.list();
57
58
 
58
59
  Class return types are inferred from constructors. Classes follow TypeScript's structural typing;
59
60
  see [token identity](./type-safety.md#class-tokens-use-structural-typing).
60
- Async factories produce Promise-typed resolutions. Await them explicitly.
61
+ Async factories produce Promise-typed resolutions. Await them explicitly. A resolution returns the end
62
+ of katagami's own bookkeeping chain, not the promise the factory returned. Katagami's bookkeeping and
63
+ disposal attach no listener to what it hands out, so a rejected resolution you drop surfaces as an
64
+ unhandled rejection, unless a later resolution waits on the same cached promise.
61
65
 
62
66
  ## Composition and test substitution
63
67
 
@@ -126,8 +130,10 @@ and retains its registered token types.
126
130
 
127
131
  Scope disposal cleans its cached scoped instances; container disposal cleans its singleton cache.
128
132
  Instances are processed in reverse cache insertion order, asynchronous results are awaited, and
129
- cleanup errors are combined in an `AggregateError`. Disposal is idempotent. Transient instances
130
- are not cached or automatically owned: arrange their cleanup explicitly.
133
+ cleanup errors are combined in an `AggregateError`. A cached asynchronous creation that rejected
134
+ yields no resolved value to close: disposal awaits it, skips it, continues with the remaining
135
+ instances, and leaves that failure to the caller that resolved the token. Disposal is idempotent.
136
+ Transient instances are not cached or automatically owned: arrange their cleanup explicitly.
131
137
 
132
138
  ## Lazy resolution
133
139
 
@@ -176,6 +182,17 @@ Default accumulated registration provides the registration-order checks describe
176
182
  | `registerScoped(token, factory)` | Register a factory cached per scope |
177
183
  | `use(source)` | Copy another container's registrations, replacing matching token entries |
178
184
  | `createScope(source)` | Create a scope from a container, scope or disposable view |
185
+ | `createContainer({ policy })` | Share a policy's settings and observed origins among containers given the same policy object |
186
+ | `ContainerPolicy` (type export) | Check a policy with `satisfies` while keeping its hook and required-key types |
187
+ | `policy.requiredMetadata` | Require metadata keys on every registration and in `.use()` |
188
+ | `createMetadataKey<T>()(name)` | Define a typed metadata key |
189
+ | `{ metadata: [KEY(value)] }` (third registration argument) | Declare registration metadata next to the factory |
190
+ | `container.getMetadata(token)` | Read the last registration's metadata without creating the service |
191
+ | `entrypoint(factory)` | Mark a factory that returns a function as a public operation |
192
+ | `beforeResolve(event)` (scope option) | Check a registration synchronously just before it is resolved, including cache hits |
193
+ | `policy.beforeReturn({ registrations })` | Synchronously check the observed origins of values returned by top-level resolution and of operations' direct results; resolutions requested by factories are not checked |
194
+ | `createScope(source, { access: 'operations' })` | Create a new scope whose `get(token)` returns public operations and whose disposal waits for running calls |
195
+ | `operations.get(token)(...args)` | Create nothing on `get`; resolve, run and check the operation on each call. The result is always a Promise |
179
196
  | `scope.resolve(token)` | Resolve the last registration; fail if missing |
180
197
  | `scope.resolveAll(token)` | Resolve every registration for a token |
181
198
  | `scope.tryResolve(token)` | Resolve the last registration or return `undefined` |
@@ -184,3 +201,17 @@ Default accumulated registration provides the registration-order checks describe
184
201
  | `lazy(scope, classToken)` from `katagami/lazy` | Defer synchronous resolution until first access |
185
202
  | `ContainerError` | Runtime error for missing registrations, cycles and invalid scope operations |
186
203
  | `Resolver` (type export) | Factory resolver type; retain inferred generics when extracting factories |
204
+
205
+ ## Registration policies and operations
206
+
207
+ See [registration policies and operations](./registration-policies.md) for the shared `policy`, required
208
+ metadata, `beforeResolve`, `beforeReturn`, `entrypoint` and operations scopes. Get a public operation
209
+ with `createScope(container, { access: 'operations' }).get(name)`; the function it returns resolves its
210
+ dependencies when called and always returns a Promise. Pass the same `policy` object to every module
211
+ that follows the policy, and assemble them with ordinary lifetimes and `.use()`. A value the policy
212
+ forbids does not leave through top-level resolution or an operation result, as long as it is an object
213
+ or function whose origin can be tracked.
214
+
215
+ `beforeResolve` checks resolutions in the scope that owns the resolver. It does not rebind a shared
216
+ singleton's resolver to its caller, and it does not re-check values that were already obtained. Use
217
+ scoped registrations for work that depends on the request or its permissions.