@mnemonica/tactica 0.4.0 → 0.4.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 CHANGED
@@ -253,7 +253,7 @@ These usage shapes are recognized and attributed within the existing output cont
253
253
  - **`call(entity, Ctor, ...)` / `apply(entity, Ctor, args)`** — the mnemonica construction exports (import-aware: only actual `'mnemonica'` imports or members of a tracked module-object alias match; userland `call`/`apply` never do). The Ctor argument (arg 1) records an `instantiation`, and the result variable binds to the Ctor's type (runtime `InstanceResult<Merge<E, T>>` approximated by T). **Decorated classes resolve as the Ctor** through the same graph tiers — `@decorate() class C` is a known type, so `call(parent, C)` records and binds; an undecorated plain class has no graph entry, so the call binds nothing and records no usage (never a bare name). The free-call `decorate(Class)` form is not tracked (tactica recognizes the `@decorate` decorator syntax only).
254
254
  - **`bind(entity, Ctor)`** — records no usage (it constructs nothing); the bound variable binds to the Ctor's type. Invoking the bound function later (`f(...)`, including `await f(...)`) is not followed.
255
255
 
256
- Two boundaries stay deliberate: bindings surface only for references lexically AFTER the binding statement (a binding made inside a constructor body is not yet visible to that same handler's property extraction), and the mechanism distinction (`new` vs fork vs call) is not carried in the outputs — fork/clone/merge record as plain `instantiation` entries, byte-indistinguishable from `new`, until the deferred mechanism-kind contract revision lands. Consumers counting constructions should expect fork sites among them.
256
+ Three boundaries stay deliberate: bindings surface only for references lexically AFTER the binding statement (a binding made inside a constructor body is not yet visible to that same handler's property extraction); a construction nested inside a class or function body of the initializer does not bind the outer variable (`const X = define('X', class { m = new Map() })` binds X to the defined type, never to `Map` — scope boundaries are not crossed); and the mechanism distinction (`new` vs fork vs call) is not carried in the outputs — fork/clone/merge record as plain `instantiation` entries, byte-indistinguishable from `new`, until the deferred mechanism-kind contract revision lands. Consumers counting constructions should expect fork sites among them.
257
257
 
258
258
  ### Builder pattern on the imported module object
259
259
 
@@ -909,7 +909,7 @@ Deliberate approximations (name-based, no type checker): namespace imports count
909
909
  1. **Parse** — load `tsconfig.json`, build a `ts.Program`, walk each source file's AST.
910
910
  2. **Detect** — find `define()` and `@decorate()` calls, plus `lookup` lookups, `new` expressions, and EDS / flow patterns.
911
911
  3. **Graph** — build a Trie of types in `TypeGraphImpl`, with parent links via the chain of `.define()` calls and `@decorate(Parent)` references.
912
- 4. **Generate** — emit `types.ts`, `registry.ts`, `index.ts` (default mode) or `index.d.ts` (legacy mode), plus `definitions.json`, `usages.json` (with `holderScopeId`), `flow.json`, `instrumentation.json`, `modules.json`, `scopes.json`, `hierarchy.json`/`hierarchy.txt`, and optionally `eds.json`.
912
+ 4. **Generate** — emit `types.ts`, `registry.ts`, `index.ts` (default mode) or `index.d.ts` (legacy mode), plus `definitions.json`, `usages.json` (with `holderScopeId`), `flow.json`, `instrumentation.json`, `modules.json`, `scopes.json`, `hierarchy.json`/`hierarchy.txt`, `collections.json`, and optionally `eds.json`.
913
913
  5. **Write** — files land in the output directory (default `.tactica/`).
914
914
 
915
915
  ```
package/lib/analyzer.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as ts from 'typescript';
2
- import { AnalyzeResult, DefinitionInfo, UsageInfo, EDSInfo, FlowInfo, InstrumentationPoint, ResolutionError } from './types';
2
+ import { AnalyzeResult, DefinitionInfo, UsageInfo, EDSInfo, FlowInfo, InstrumentationPoint, ResolutionError, CollectionManifestEntry } from './types';
3
3
  import { TypeGraphImpl } from './graph';
4
4
  import { TacticaPlugin } from './plugins';
5
5
  /**
@@ -73,6 +73,14 @@ export declare class MnemonicaAnalyzer {
73
73
  * Get collected definitions
74
74
  */
75
75
  getDefinitions(): Map<string, DefinitionInfo>;
76
+ /**
77
+ * The collections.json manifest: one entry per minted collection, in
78
+ * minting order, preceded by the default-collection entry whenever
79
+ * default-collection types exist. The default entry has no id/location
80
+ * (there is no call site — unprefixed fullPaths are its identity) and
81
+ * its registry interface is the global TypeRegistry.
82
+ */
83
+ getCollectionsManifest(): CollectionManifestEntry[];
76
84
  /**
77
85
  * Get collected usages
78
86
  */
@@ -251,6 +259,14 @@ export declare class MnemonicaAnalyzer {
251
259
  */
252
260
  private expandReferencedTypeDeclaration;
253
261
  private expandReferencedTypeDeclarationInner;
262
+ /**
263
+ * Emitted instance-type alias for a graph node — the name types.ts /
264
+ * registry.ts actually declare. Option B collection types carry their
265
+ * registry interface prefix; collection types WITHOUT a registry
266
+ * interface are never emitted, so no valid alias exists for them
267
+ * (undefined — callers degrade to `unknown`, never a bare name).
268
+ */
269
+ private getEmittedInstanceTypeName;
254
270
  /**
255
271
  * Resolve a simple (non-qualified) type reference: import-aware
256
272
  * declaration expansion first, then the InstanceType<typeof X> pattern,
@@ -403,9 +419,14 @@ export declare class MnemonicaAnalyzer {
403
419
  */
404
420
  private extractRegistryInterfaceName;
405
421
  /**
406
- * Get the registry interface name for a collection id.
422
+ * Stamp a node with its collection's emission info: the Option B registry
423
+ * interface name and the collection's home file — the module the generated
424
+ * augmentation must target (the interface is confirmed declared there).
425
+ * A type's own sourceFile is NOT the target: multi-file collections define
426
+ * types across many modules while the interface lives at the
427
+ * createTypesCollection() call site.
407
428
  */
408
- private getRegistryInterfaceName;
429
+ private applyCollectionEmissionInfo;
409
430
  /**
410
431
  * Check if an expression is a createTypesCollection() call.
411
432
  * Handles:
@@ -904,6 +925,11 @@ export declare class MnemonicaAnalyzer {
904
925
  * Get type name from expression (identifier or property access)
905
926
  */
906
927
  private getTypeNameFromExpression;
928
+ /**
929
+ * The one candidate whose parent type is defined in `fileName`, or
930
+ * undefined when none or several qualify.
931
+ */
932
+ private subtypeOwnedByFile;
907
933
  /**
908
934
  * Resolve full type path from property access
909
935
  */