onAppStart
Registers startup work inside a generator-based craftService.
Import
import { onAppStart } from '@craft-ng/core';Overview
onAppStart(...) is used inside a craftService(..., function* () {}) generator to declare logic that should run when the application starts.
Important constraints:
- the owning service must be declared with
appStart: true - a service can declare
yield* onAppStart(...)only once - the callback can be a plain function or a generator function
- nested
onAppStart(...)calls inside the callback are not supported
craftAppConfig(...) runs registered app-start services during Angular application initialization.
Signature
function onAppStart(
run: () => Observable<unknown> | Promise<unknown> | void,
): Generator<unknown, void, unknown>;
function onAppStart<Yielded>(
run: () => Generator<
Yielded,
Observable<unknown> | Promise<unknown> | void,
unknown
>,
): Generator<unknown, void, unknown>;Plain Callback
Use a plain callback when startup logic does not need to yield* crafted dependencies.
import { craftService, onAppStart } from '@craft-ng/core';
export const { injectStartupFlag } = craftService(
{
name: 'StartupFlag',
scope: 'global',
appStart: true,
},
function* () {
yield* onAppStart(() => {
console.log('app started');
return Promise.resolve();
});
return true;
},
);Generator Callback
Use a generator callback when startup logic needs to yield* crafted dependencies.
import { Console, craftService, onAppStart } from '@craft-ng/core';
export const { injectAppStartLog } = craftService(
{
name: 'AppStartLog',
scope: 'toProvide',
appStart: true,
},
function* () {
yield* onAppStart(function* () {
yield* Console.log('This is a log from the appStart callback');
return new Promise((resolve) => setTimeout(resolve, 1000));
});
return 1;
},
);The callback generator supports the same dependency-yield semantics as a normal crafted generator for:
yield* XToYield(...)yield*exposure tokens returned by derivation callbacks- browser boundaries such as
yield* Console.log(...)
Dependencies used only inside this callback are merged into the parent service dependency graph.
Dependency Tracking
Generator callbacks are type-visible.
If the callback only uses Console, the owning service dependency graph includes ConsoleService as a normal dependency node, with browserBoundary: true.
This means startup-only dependencies are still visible to:
GetInjectedServiceDependencies<typeof injectX>- route/app DI checks built on top of service metadata
- test helpers that inspect crafted dependency graphs
Runtime Behavior
onAppStart(...) does not run when the service instance is created.
It registers a startup hook that is executed when the application initializer runs that service, typically through craftAppConfig(...).
If the callback returns:
void: startup continues immediatelyPromise: startup waits for the promise to resolveObservable: startup waits through Angular's initializer handling
Generator callbacks preserve the same waiting behavior. The generator itself resolves first, then its returned Promise / Observable / void is used as the startup result.
Common Errors
Missing appStart: true
yield* onAppStart(() => undefined);This throws at runtime if the owning service was not declared with appStart: true.
Nested onAppStart(...)
yield* onAppStart(function* () {
yield* onAppStart(() => undefined); // unsupported
return undefined;
});Nested declarations are rejected at runtime.