feat(loader): resolve interface facades per consumer - #104
Conversation
|
@greptileai review current HEAD 90cc407. Verify runtime optional RegisteringProxy stubs remain providerless, explicit TestModule stubs attach route-aware no-op handlers only for stubbed interfaces, provider-consumer registrations replay and unload cleanly, and AsyncProxy behavior remains unchanged. |
|
@greptileai review current HEAD 3edd84a. Verify TestModule explicit RegisteringProxy stub leases remain route-aware through owned-entry unregister, are detached during manager teardown, cannot accept a same-route registration in a later manager/process phase, and report no teardown errors. Also verify runtime optional RegisteringProxy remains providerless, replay/ownership/unload semantics remain intact, unrelated RegisteringProxy still fails, and AsyncProxy stubs still reject. |
Resolve self-implemented interface proxies through a dedicated declaration-only package entry so graph preparation cannot evaluate application lifecycle side effects outside module ownership.
|
@greptileai review current HEAD 4ef985b. Verify self-implemented interface graph discovery resolves only the canonical ./interface-declarations subpath and never evaluates the application main during addModules; external declaration-only interface packages retain root fallback; the declaration path cannot escape its canonical package; provider-route identities cover canonical public subpath proxies; side-effectful registrations load under lifecycle generation ownership, nested callbacks retain provider context, generation destroy leaves zero stale replay; early RegisteringProxy registrations replay and unregister on the exact future provider without consumer-route fallback; no DEFAULT_PROVIDER fallback, selectProvider weakening, or unregisterModule cleanup was introduced. Review the declaration-closure documentation and the deterministic RED/GREEN regressions. Ignore the expected CI install 404 for unpublished @antelopejs/interface-core@0.0.13. |
|
@greptile review |
Co-authored-by: Upd4ting <upd4ting@gmail.com>
|
Closed at Upd4ting's request: the Core 1.5 / multi-provider train is deferred and will be restarted manually later. This PR contains only work for that train; no independent fix is being retained. Do not merge or publish artifacts from this branch. Any future implementation should start from the then-current main branches and released package graph. |
Summary
Resolver behavior
The resolver already owns the mapping from a consumer to its selected providers. It now applies that mapping when Node resolves the consumer's interface import.
Application syntax stays unchanged. Providers still receive canonical declarations for
ImplementInterface; classes, symbols, metadata, proxies, and callbacks preserve strict identity.Bug reproduced
With two Auth providers, the old resolver returned the same canonical Auth module to both consumers. Direct calls could work while a lifecycle context was active, but
Authentication()stored a parameter provider that ran later under API's provider context. That laterValidateRaw()call had no consumer provider route and failed withAmbiguousProviderError.The integration regression builds two real consumer modules with different Auth
importOverrides, registers real Auth and API decorators, waits across an async boundary, invokes both deferred parameter providers outside the consumers' lifecycle contexts, and proves results route toauth-provider-aandauth-provider-b. The registered HTTP callbacks remain strict-equal to the controller methods.The self-implemented interface regression also imports
./interface-declarationsthrough a consumer facade and proves delayed nested calls, reconstruction, HMR, and declaration identity.Validation
pnpm lint(exit 0; two pre-existing warnings and one informational finding outside this diff)pnpm buildgit diff --checkPerformance
The resolver performs facade construction only during module resolution. Implementing provider modules stay canonical, request callbacks are not wrapped, and the historical
AsyncProxy.call()attached-provider path is unchanged.An isolated A/B HTTP gate (Node 24.19.0, pinned server CPU, 8 repetitions, 8-second samples) measured +1.15% JSON c100, +2.46% dynamic routes, +1.68% POST echo, and -0.36% on the last of 1,000 routes. This shows no attributable steady-state regression; the rejected callback-wrapper branch measured roughly -8% to -14%.
CI and release ordering
The stock Ubuntu install remains expected to fail until unpublished
@antelopejs/interface-core@0.0.13(or its final next release version) exists in the registry. Do not work around that provenance gate in the lockfile.Merge/release order starts with interface-core #12, then this Core PR, then interface-api #17 and interface-auth. No package is published by this PR.