refactor(plugins): give host-service resolution its own home - #1023
Merged
Conversation
The loader carried five private resolvers — MessageService, SessionService, ConversationMappingService, PluginInstanceService, SearchProviderRegistry — each a lazy require plus a non-strict ModuleRef.get. Both halves exist to dodge a documented cycle, and that reasoning was spelled out three times in a file that has nothing else to do with module-load order. PluginHostServices now owns the pair and the explanation. The loader keeps the ModuleRef parameter and builds the locator in its constructor body, so the constructor SIGNATURE is untouched: all 33 positional constructions across six spec files, and the three spec subclasses overriding createSandboxHost, compile and pass unchanged. The loader also stops naming the five services. Four type-only imports go with the bodies; MessageService stays because dispatchConversationMedia still takes it as a parameter type. Two tests moved rather than being kept working by a delegate. They reached getSearchRegistry through a private cast on the loader and needed twenty lines of config/storage/HookManager scaffolding to do it; against PluginHostServices the same two assertions need one line. Suite total is unchanged at 4011. A note for whoever picks up the next step: the plan this came from justified an earlier prep commit rewriting those 33 constructions to Test.createTestingModule, on the grounds that field moves would force a spec rewrite. That was not needed here and was skipped. The constructor already absorbs new dependencies through @optional, as its own comment records; only reordering or removing a parameter would force the churn.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second step on
plugin-loader.service.ts, after the config-defaults seeder.Why
The loader carried five private resolvers —
MessageService,SessionService,ConversationMappingService,PluginInstanceService,SearchProviderRegistry— each a lazyrequireplus a non-strict
ModuleRef.get. Both halves are load-bearing and neither is about loading plugins:plugin-loader → message → session → engine.factory → core/plugins barrel → plugin-loader, whichcorrupts
MessageService's constructor paramtype metadata at boot;ModuleRefinstead of constructor injection avoids the provider cyclePluginLoaderService → SessionService → EngineFactory → PluginLoaderService.That reasoning was spelled out three times inside a file that otherwise has nothing to do with
module-load order.
What changes
PluginHostServicesowns the pair and the explanation. The loader keeps itsModuleRefparameter andbuilds the locator in the constructor body, so the constructor signature is untouched — all 33
positional constructions across six spec files, and the three spec subclasses overriding
createSandboxHost, compile and pass unchanged.The loader also stops naming the five services: four type-only imports leave with the bodies.
MessageServicestays, becausedispatchConversationMediastill takes it as a parameter type.Two tests moved
getSearchRegistry's own tests reached it through a private cast on the loader(
(loader as unknown as { getSearchRegistry })) and needed twenty lines of config/storage/HookManagerscaffolding. Against
PluginHostServicesthe same two assertions need one line. They were moved ratherthan kept alive by a delegate on the loader, which would have preserved the reach-in that made them
brittle.
Suite total is unchanged at 4011 — nothing added, two tests relocated. Suite count 249 → 250 for the
new file.
On the plan this came from
The earlier plan justified a prep commit rewriting those 33 constructions to
Test.createTestingModule,on the grounds that moving fields would force a spec rewrite. Checked at source, that was not needed
here and was skipped: the constructor already absorbs new dependencies through
@Optional— its owncomment records exactly that — so only reordering or removing a parameter forces the churn. The same
plan also called this step a prerequisite for breaking a
plugin-loader↔plugin-storagerequirecycle; that cycle does not exist today either.
Verification
Backend lint,
prettier --check,tsc --noEmitover the full project including specs, build, 4011 unittests, 137 e2e tests, and the dashboard build all pass on Node 22.