Skip to content

feat(runtime): add resolver-bound interface facades - #12

Closed
Upd4ting wants to merge 9 commits into
mainfrom
feat/bind-module-context
Closed

feat(runtime): add resolver-bound interface facades#12
Upd4ting wants to merge 9 commits into
mainfrom
feat/bind-module-context

Conversation

@Upd4ting

@Upd4ting Upd4ting commented Aug 21, 2026

Copy link
Copy Markdown
Member

Summary

  • replace callback-context restoration with resolver-bound interface facades
  • bind exported InterfaceFunction, proxy, and nested namespace declarations to the provider selected for one consumer generation
  • keep classes, symbols, metadata, constants, and the underlying proxy state canonical
  • expose BuildInterfaceFacade for the limited case where a derived helper or cold decorator closes over a declaration
  • preserve original lifecycle, provider, HTTP, and business callback identities
  • invalidate stale facades and clean registrations by exact module generation
  • remove the public RunWithModuleContext provider-selection API; provider selection now belongs exclusively to the resolver/facade path

Application contract

Application imports and call syntax do not change. Core supplies the correct facade before evaluating each module, using that module's provider selection and importOverrides.

import { ValidateRaw } from "@antelopejs/interface-auth";

const user = await ValidateRaw(token);

Direct InterfaceFunction exports need no interface-specific integration. BuildInterfaceFacade is only needed for derived APIs such as Auth helpers or cold decorators such as API route registration. It is never a request wrapper.

Runtime boundary

  • providers and interface declarations remain canonical singletons
  • consumers receive one cached CommonJS facade per owner generation and interface entry/subpath
  • provider selection is captured in bound imports, not looked up from an HTTP callback context
  • provider implementations attach unchanged and call imports already bound for their own module
  • stale-generation calls reject with ModuleContextInvalidatedError
  • BindToCurrentModuleContext and public RunWithModuleContext are removed
  • GetModuleContext remains an ownership diagnostic, not a provider selector
  • the private ownership engine used by RunWithResponsibleModule remains for its existing stack-attribution compatibility; Core does not install it around lifecycle, HTTP, or business callbacks

Compatibility note

@antelopejs/interface-core 0.0.11 already exports RunWithModuleContext from /modules. Removing it is therefore a source-level breaking change for custom infrastructure that imports that function directly. Ordinary application modules, providers using ImplementInterface, and direct interface consumers do not use it and keep identical syntax. The release version/range strategy must be decided before publishing this PR.

Causal validation

  • historical single-provider Auth still passes
  • exact old API, Auth, Database, database-decorators, Data API, CMS automation, and CMS-SaaS cases reproduce AmbiguousProviderError with two providers
  • exact Core base routes a self-implementing provider B to provider A when the self-provider resolver selection is removed; restoring only that selection routes to B
  • candidate API/Auth/Database/downstream scenarios route A and B correctly without ambient callback context
  • registered API callbacks and CMS-SaaS invoice resolvers remain strict-equal to the original functions

Package validation

  • pnpm lint
  • TypeScript build
  • 86 passing interface-core tests
  • packed package-consumer install and runtime test, including /facades exports and the absence of public RunWithModuleContext
  • git diff --check

Cross-repository validation

The candidate Core/API/Auth/Database/CMS/CMS-SaaS/Mongo stack completed two construct/start/stop/destroy cycles after the public API removal: 396 fresh routes per cycle, HTTP GET 200 and PUT 401, exact replay/unregister cleanup, zero reporter/unhandled errors, immediate SIGTERM, and exit 0.

Qualifying log SHA-256: 5c82c4cb34f57208b4e8eafa0a63c8e1b498687763a7aed31d7cc95f23b8666b.

Performance

The rejected callback-wrapper design measured roughly 8% to 14% slower because it restored context in the request path.

The full-resolver A/B gate used Node 24.19.0, 1,000 routes, 100 connections, 5-second warmups, 30-second samples, and 10 alternating repetitions:

  • baseline median: 37,741.205 req/s
  • full resolver median: 37,871.87 req/s
  • paired median difference: -0.063677%
  • p99 latency: unchanged at 4-5 ms
  • paired dispersion: about -5.55% to +4.75%

The paired median is noise, with no stable measurable regression. Result JSON SHA-256: 6fe775e130b2b4739d5e5f28527bb37e474874005d970eed8903158122b12dfd. The public export removal does not touch proxies.ts, facades.ts, Core resolution, or any request-path source, so this benchmark remains the relevant hot-path gate.

Release ordering

This remains the first release gate, but do not publish it until the compatibility/version decision above is explicit. Downstream dependency ranges must target the chosen interface-core release before Core and composed interfaces are published.

Copy link
Copy Markdown
Member Author

@greptile review

Comment thread src/modules.ts Outdated

Copy link
Copy Markdown
Member Author

@greptile review

Base automatically changed from fix/export-core-declarations to main August 24, 2026 18:41
ampagent and others added 2 commits August 24, 2026 23:52
Co-authored-by: Upd4ting <upd4ting@gmail.com>
Co-authored-by: Upd4ting <upd4ting@gmail.com>
@Upd4ting Upd4ting changed the title feat(runtime): bind callbacks to module context feat(runtime): add resolver-bound interface facades Aug 25, 2026
ampagent and others added 3 commits August 25, 2026 23:28
Route interface calls and registrations through resolver-selected providers without wrapping stored callbacks. Preserve provider ownership and invalidate only the destroyed module generation.

Co-authored-by: Upd4ting <upd4ting@gmail.com>
Co-authored-by: Upd4ting <upd4ting@gmail.com>
Co-authored-by: Upd4ting <upd4ting@gmail.com>

Copy link
Copy Markdown
Member Author

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.

@Upd4ting Upd4ting closed this Aug 27, 2026
@Upd4ting
Upd4ting deleted the feat/bind-module-context branch August 27, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants