@fluojs/core 1.0.0-beta.4 → 1.0.0-beta.5

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.ko.md CHANGED
@@ -70,7 +70,7 @@ ensureMetadataSymbol();
70
70
 
71
71
  ### 명시적인 의존성 메타데이터
72
72
 
73
- `@Inject(...)`는 리플렉션 기반 추론 대신 코드 안에서 의존성 토큰을 직접 드러냅니다. 상속된 constructor 토큰을 명시적으로 비우려면 `@Inject()`를 사용하면 됩니다.
73
+ `@Inject(...)`는 리플렉션 기반 추론 대신 코드 안에서 의존성 토큰을 직접 드러냅니다. 이 데코레이터는 표준 클래스 데코레이터이므로 constructor parameter나 property가 아니라 생성자 토큰을 선언할 클래스 위에 붙입니다. 상속된 constructor 토큰을 명시적으로 비우려면 `@Inject()`를 사용하면 됩니다.
74
74
 
75
75
  ```ts
76
76
  const CONFIG_TOKEN = Symbol('CONFIG_TOKEN');
@@ -81,16 +81,16 @@ class UsesConfigValue {
81
81
  }
82
82
  ```
83
83
 
84
- 여러 constructor 토큰은 `@Inject(A, B)`처럼 variadic 호출로 지정하면 dependency metadata가 표준 데코레이터 사용 방식과 맞게 유지됩니다. `@Inject([A, B])` 배열 형태도 허용되지만, 새 코드는 variadic 형태를 사용하는 것이 좋습니다.
84
+ 여러 constructor 토큰은 `@Inject(A, B)`처럼 variadic 호출로 지정하면 dependency metadata가 표준 데코레이터 사용 방식과 맞게 유지됩니다. `@Inject([A, B])` 배열 형태도 허용되지만, 새 코드는 variadic 형태를 사용하는 것이 좋습니다. 데코레이션 시점에 아직 사용할 수 없는 토큰은 해당 토큰만 `forwardRef(...)`로 감싸고, 없어도 되는 의존성은 해당 토큰만 `optional(...)`로 감쌉니다.
85
85
 
86
86
  ### 형제 패키지를 위한 공용 메타데이터 헬퍼
87
87
 
88
- 내부 메타데이터 reader/writer는 `@fluojs/core/internal` 아래에 있으며, `@fluojs/di`, `@fluojs/http`, `@fluojs/runtime` 같은 패키지들이 같은 메타데이터 모델을 공유할 수 있게 합니다.
88
+ `getModuleMetadata()`는 테스트와 도구에서 read-only 모듈 inspection을 할 수 있도록 공개 루트 엔트리포인트에서 사용할 수 있습니다. 더 넓은 내부 메타데이터 reader/writer는 `@fluojs/core/internal` 아래에 있으며, `@fluojs/di`, `@fluojs/http`, `@fluojs/runtime` 같은 패키지들이 같은 메타데이터 모델을 공유할 수 있게 합니다.
89
89
 
90
- 애플리케이션 코드는 공개 데코레이터와 `ensureMetadataSymbol()`을 `@fluojs/core`에서 import해야 합니다. `@fluojs/core/internal` 서브패스는 메타데이터 레코드, 컨트롤러/라우트 헬퍼, injection/validation 헬퍼, clone 유틸리티가 필요한 fluo 패키지를 위한 경로입니다. 표준 metadata bag helper는 current/native `Symbol.metadata`와 fallback symbol이 섞인 lookup을 처리합니다. 어느 era에서 온 own metadata든 같은 key에 대해서는 어느 era에서 온 inherited metadata보다 우선하지만, child가 다른 key만 소유한 경우 parent constructor의 inherited key는 계속 보입니다. DI와 모듈 그래프 hot path의 allocation을 줄이기 위해 `getModuleMetadata()`, `getOwnClassDiMetadata()`, `getInheritedClassDiMetadata()`, `getClassDiMetadata()`는 frozen snapshot을 반환하며 write 사이에는 같은 reference를 재사용할 수 있습니다. 이 결과, collection 필드, module provider descriptor wrapper와 middleware route-config wrapper(그 안의 `routes` 배열 포함)는 immutable로 취급해야 합니다. `useValue` payload 객체와 runtime middleware/guard/interceptor instance는 mutable reference로 유지되며 이 snapshot 때문에 freeze되지 않습니다. 다른 metadata reader는 각 reader의 테스트가 stable-reference 재사용을 문서화하지 않는 한 기존 defensive-read 동작을 유지합니다.
90
+ 애플리케이션 코드는 공개 데코레이터, `ensureMetadataSymbol()`, read-only module metadata inspection을 `@fluojs/core`에서 import해야 합니다. `@fluojs/core/internal` 서브패스는 메타데이터 레코드, 컨트롤러/라우트 헬퍼, injection/validation 헬퍼, clone 유틸리티가 필요한 fluo 패키지를 위한 경로입니다. 표준 metadata bag helper는 current/native `Symbol.metadata`와 fallback symbol이 섞인 lookup을 처리합니다. 어느 era에서 온 own metadata든 같은 key에 대해서는 어느 era에서 온 inherited metadata보다 우선하지만, child가 다른 key만 소유한 경우 parent constructor의 inherited key는 계속 보입니다. DI와 모듈 그래프 hot path의 allocation을 줄이기 위해 `getModuleMetadata()`, `getOwnClassDiMetadata()`, `getInheritedClassDiMetadata()`, `getClassDiMetadata()`는 frozen snapshot을 반환하며 write 사이에는 같은 reference를 재사용할 수 있습니다. 이 결과, collection 필드, module provider descriptor wrapper와 middleware route-config wrapper(그 안의 `routes` 배열 포함)는 immutable로 취급해야 합니다. `useValue` payload 객체와 runtime middleware/guard/interceptor instance는 mutable reference로 유지되며 이 snapshot 때문에 freeze되지 않습니다. 다른 metadata reader는 각 reader의 테스트가 stable-reference 재사용을 문서화하지 않는 한 기존 defensive-read 동작을 유지합니다.
91
91
 
92
92
  ```ts
93
- import { getModuleMetadata } from '@fluojs/core/internal';
93
+ import { getModuleMetadata } from '@fluojs/core';
94
94
 
95
95
  const metadata = getModuleMetadata(AppModule);
96
96
  console.log(metadata.providers);
@@ -159,7 +159,7 @@ class Logger {}
159
159
 
160
160
  - **데코레이터**: `Module`, `Global`, `Inject`, `Scope`
161
161
  - **에러**: `FluoError`, `InvariantError`, `FluoCodeError`, `FluoErrorOptions`, `formatTokenName`
162
- - **메타데이터 런타임**: `ensureMetadataSymbol`
162
+ - **메타데이터 런타임**: `ensureMetadataSymbol`, `getModuleMetadata`
163
163
  - **타입**: `Constructor<T>`, `Token<T>`, `MaybePromise<T>`, `AsyncModuleOptions`, `MetadataPropertyKey`, `MetadataSource`
164
164
  - **내부 서브패스**: `@fluojs/core/internal`을 통한 메타데이터 헬퍼, 컨트롤러/라우트 헬퍼, injection 헬퍼, validation 헬퍼, clone 유틸리티
165
165
 
package/README.md CHANGED
@@ -72,7 +72,7 @@ ensureMetadataSymbol();
72
72
 
73
73
  ### Explicit dependency metadata
74
74
 
75
- `@Inject(...)` keeps dependency wiring visible in code instead of relying on emitted reflection metadata. Call `@Inject()` when you want to record an explicit empty override for inherited constructor tokens.
75
+ `@Inject(...)` keeps dependency wiring visible in code instead of relying on emitted reflection metadata. It is a standard class decorator: place it on the class whose constructor tokens you are declaring, not on constructor parameters or properties. Call `@Inject()` when you want to record an explicit empty override for inherited constructor tokens.
76
76
 
77
77
  ```ts
78
78
  const CONFIG_TOKEN = Symbol('CONFIG_TOKEN');
@@ -83,16 +83,16 @@ class UsesConfigValue {
83
83
  }
84
84
  ```
85
85
 
86
- Pass multiple constructor tokens as variadic arguments, such as `@Inject(A, B)`, so dependency metadata stays aligned with standard decorator usage. The array form `@Inject([A, B])` is also accepted, but new code should prefer the variadic form.
86
+ Pass multiple constructor tokens as variadic arguments, such as `@Inject(A, B)`, so dependency metadata stays aligned with standard decorator usage. The array form `@Inject([A, B])` is also accepted, but new code should prefer the variadic form. If a token is unavailable at decoration time, wrap that one token with `forwardRef(...)`; if a dependency may be absent, wrap that token with `optional(...)`.
87
87
 
88
88
  ### Shared metadata helpers for sibling packages
89
89
 
90
- Internal readers and writers live under `@fluojs/core/internal`, which is how packages like `@fluojs/di`, `@fluojs/http`, and `@fluojs/runtime` consume the same metadata model.
90
+ `getModuleMetadata()` is available from the public root entrypoint for read-only module inspection in tests and tooling. Broader internal readers and writers live under `@fluojs/core/internal`, which is how packages like `@fluojs/di`, `@fluojs/http`, and `@fluojs/runtime` consume the same metadata model.
91
91
 
92
- Application code should import public decorators and `ensureMetadataSymbol()` from `@fluojs/core`. The `@fluojs/core/internal` subpath is reserved for fluo packages that need metadata records, controller/route helpers, injection and validation helpers, or clone utilities. Standard metadata bag helpers handle mixed-era lookups across current/native `Symbol.metadata` and the fallback symbol: own metadata from either era overrides inherited metadata from either era for the same key, while inherited keys from parent constructors remain visible when the child owns a different key. To reduce DI and module-graph hot-path allocations, `getModuleMetadata()`, `getOwnClassDiMetadata()`, `getInheritedClassDiMetadata()`, and `getClassDiMetadata()` return frozen snapshots and may reuse the same reference between writes. Treat those results, their collection fields, module provider descriptor wrappers, and middleware route-config wrappers (including their `routes` arrays) as immutable. `useValue` payload objects and runtime middleware/guard/interceptor instances remain mutable references and are not frozen by these snapshots. Other metadata readers keep their existing defensive-read behavior unless their own tests document stable-reference reuse.
92
+ Application code should import public decorators, `ensureMetadataSymbol()`, and read-only module metadata inspection from `@fluojs/core`. The `@fluojs/core/internal` subpath is reserved for fluo packages that need metadata records, controller/route helpers, injection and validation helpers, or clone utilities. Standard metadata bag helpers handle mixed-era lookups across current/native `Symbol.metadata` and the fallback symbol: own metadata from either era overrides inherited metadata from either era for the same key, while inherited keys from parent constructors remain visible when the child owns a different key. To reduce DI and module-graph hot-path allocations, `getModuleMetadata()`, `getOwnClassDiMetadata()`, `getInheritedClassDiMetadata()`, and `getClassDiMetadata()` return frozen snapshots and may reuse the same reference between writes. Treat those results, their collection fields, module provider descriptor wrappers, and middleware route-config wrappers (including their `routes` arrays) as immutable. `useValue` payload objects and runtime middleware/guard/interceptor instances remain mutable references and are not frozen by these snapshots. Other metadata readers keep their existing defensive-read behavior unless their own tests document stable-reference reuse.
93
93
 
94
94
  ```ts
95
- import { getModuleMetadata } from '@fluojs/core/internal';
95
+ import { getModuleMetadata } from '@fluojs/core';
96
96
 
97
97
  const metadata = getModuleMetadata(AppModule);
98
98
  console.log(metadata.providers);
@@ -161,7 +161,7 @@ Standard decorators cannot automatically infer types for abstract classes or int
161
161
 
162
162
  - **Decorators**: `Module`, `Global`, `Inject`, `Scope`
163
163
  - **Errors**: `FluoError`, `InvariantError`, `FluoCodeError`, `FluoErrorOptions`, `formatTokenName`
164
- - **Metadata runtime**: `ensureMetadataSymbol`
164
+ - **Metadata runtime**: `ensureMetadataSymbol`, `getModuleMetadata`
165
165
  - **Types**: `Constructor<T>`, `Token<T>`, `MaybePromise<T>`, `AsyncModuleOptions`, `MetadataPropertyKey`, `MetadataSource`
166
166
  - **Internal subpath**: metadata helpers, controller/route helpers, injection helpers, validation helpers, and clone utilities via `@fluojs/core/internal`
167
167
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Global, Inject, Module, Scope } from './decorators.js';
2
2
  export { InvariantError, FluoCodeError, FluoError, formatTokenName, type FluoErrorOptions } from './errors.js';
3
- export { ensureMetadataSymbol } from './metadata.js';
3
+ export { ensureMetadataSymbol, getModuleMetadata } from './metadata.js';
4
4
  export type { AsyncModuleOptions, Constructor, MaybePromise, MetadataPropertyKey, MetadataSource, Token } from './types.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/G,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/G,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACxE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { Global, Inject, Module, Scope } from './decorators.js';
2
2
  export { InvariantError, FluoCodeError, FluoError, formatTokenName } from './errors.js';
3
- export { ensureMetadataSymbol } from './metadata.js';
3
+ export { ensureMetadataSymbol, getModuleMetadata } from './metadata.js';
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "types",
10
10
  "foundation"
11
11
  ],
12
- "version": "1.0.0-beta.4",
12
+ "version": "1.0.0-beta.5",
13
13
  "private": false,
14
14
  "license": "MIT",
15
15
  "repository": {