This page documents the 0.4 release candidates of @nexusdi/core. The newest on npm is 0.4.0-rc.1. The documentation for 0.3.2, the current release, is at nexus.js.org. Try the release candidate.
NEXUS_MISSING_PROVIDER
NEXUS_MISSING_PROVIDER means a provider depends on a token that no module visible to it provides. Nexus.create reports it inside NEXUS_BLUEPRINT_INVALID before any constructor runs, and so does validate(). get() and resolve() throw it directly for a token that no module in the graph provides. A token that some module provides but the lookup cannot see raises NEXUS_NOT_VISIBLE instead.
Reproduce NEXUS_MISSING_PROVIDER
The region provides NavCharts in Tactical and never exports it, so ShipComputer in Engineering cannot see it. Without a plugin, core prints a one-line message that starts with the code and ends with the address of this page. With errors() from @nexusdi/errors registered (npm install @nexusdi/errors@next), the same error carries the full text and its fix. The full text also names where the token exists: errors() searches the graph for near misses.
import { Nexus, Token, defineModule, isNexusError } from '@nexusdi/core';
import { provide } from '@nexusdi/core';
import { errors } from '@nexusdi/errors';
interface INavCharts {
plot(to: string): string;
}
interface IShipComputer {
course(to: string): string;
}
const NAV_CHARTS = new Token<INavCharts>('NavCharts');
const COMPUTER = new Token<IShipComputer>('ShipComputer');
class StarCharts implements INavCharts {
plot(to: string) {
return `course to ${to}`;
}
}
class QuantumComputer implements IShipComputer {
static deps = [NAV_CHARTS] as const;
constructor(private readonly charts: INavCharts) {}
course(to: string) {
return this.charts.plot(to);
}
}
const Tactical = defineModule({
name: 'Tactical',
providers: [provide(NAV_CHARTS, { useClass: StarCharts })],
});
const Engineering = defineModule({
name: 'Engineering',
providers: [provide(COMPUTER, { useClass: QuantumComputer })],
});
const Meridian = defineModule({
name: 'Meridian',
imports: [Engineering, Tactical],
});
const thin = await Nexus.create(Meridian).catch((error: unknown) => error);
if (!isNexusError(thin, 'NEXUS_BLUEPRINT_INVALID')) throw thin;
const line = thin.errors[0]?.message; // -> '[NEXUS_MISSING_PROVIDER] token=NavCharts requester=ShipComputer module=Engineering. https://nexus.js.org/errors/NEXUS_MISSING_PROVIDER'
console.log(line);
const full = await Nexus.create(Meridian, { plugins: [errors()] }).catch(
(error: unknown) => error,
);
if (!isNexusError(full, 'NEXUS_BLUEPRINT_INVALID')) throw full;
const text = full.errors[0]?.message.split('\n'); // -> ['[NEXUS_MISSING_PROVIDER] ShipComputer (module Engineering) depends on NavCharts, but no provider of NavCharts is visible in Engineering.', ' NavCharts is provided in Tactical, which does not export it.', " Fix: add NavCharts to Tactical's exports and import Tactical into Engineering."]
console.log(text);Try it: save the region as error.ts and run npx tsx error.ts. It prints the one-line message, then the full text. The second line of the full text says that Tactical provides NavCharts and does not export it. Then save the fix region below as fixed.ts and run npx tsx fixed.ts. It prints course to Kepler-442b.
Fix NEXUS_MISSING_PROVIDER
NEXUS_MISSING_PROVIDER is fixed by making a provider of the token visible to the module that asks for it: provide the token in that module, or export it from a module and import that module. Here Tactical exports NAV_CHARTS and Engineering imports Tactical.
import { Nexus, Token, defineModule, provide } from '@nexusdi/core';
interface INavCharts {
plot(to: string): string;
}
interface IShipComputer {
course(to: string): string;
}
const NAV_CHARTS = new Token<INavCharts>('NavCharts');
const COMPUTER = new Token<IShipComputer>('ShipComputer');
class StarCharts implements INavCharts {
plot(to: string) {
return `course to ${to}`;
}
}
class QuantumComputer implements IShipComputer {
static deps = [NAV_CHARTS] as const;
constructor(private readonly charts: INavCharts) {}
course(to: string) {
return this.charts.plot(to);
}
}
const Tactical = defineModule({
name: 'Tactical',
providers: [provide(NAV_CHARTS, { useClass: StarCharts })],
exports: [NAV_CHARTS],
});
const Engineering = defineModule({
name: 'Engineering',
imports: [Tactical],
providers: [provide(COMPUTER, { useClass: QuantumComputer })],
exports: [COMPUTER],
});
const Meridian = defineModule({ name: 'Meridian', imports: [Engineering] });
await using ship = await Nexus.create(Meridian);
const course = ship.get(COMPUTER).course('Kepler-442b'); // -> 'course to Kepler-442b'
console.log(course);Try it: delete the exports: [NAV_CHARTS], line from Tactical in fixed.ts and run it again. Nexus.create rejects with a BlueprintError that holds one NEXUS_MISSING_PROVIDER error for NavCharts, because Engineering imports Tactical and sees nothing of it. Put the line back and the program prints course to Kepler-442b again.
Fields of MissingProviderError
MissingProviderError carries these fields:
token: the display name of the token nobody provides.requester: the provider whose deps named the token, ornullfor a lookup fromget(),resolve()orvalidate().module: the module the lookup ran in.entry: the deps entry ofresolve()orvalidate()this error is about, ornull.nearMisses: the places the token exists that the module cannot see. Each has amoduleand akind:not-exportedfor a module that keeps the token private, andnot-importedorsame-descriptionfor the other places the search looks. The list is empty unlesserrors()is registered, because the search lives in@nexusdi/errors.