orbital_core

Core contracts, debug primitives and lifecycle vocabulary for the Orbital ecosystem.

What this package contains

orbital_core is the framework-agnostic layer shared by every other Orbital package. It exports:

  • OrbitalBinding, OrbitalBindingType, OrbitalDependencyRef and OrbitalKey
  • OrbitalResolver and OrbitalScope
  • OrbitalLifecycle
  • OrbitalLogger, OrbitalLogEvent and logger presets/config
  • debug snapshots, OrbitalDebugBridge and service-extension contracts
  • deterministic runtime exceptions such as duplicate, missing, cycle and not-ready failures

This package contains no concrete dependency graph implementation and no Flutter routing runtime.

Binding model

Orbital supports six creation strategies:

  • singleton
  • singletonAsync
  • lazySingleton
  • lazySingletonAsync
  • factory
  • factoryAsync

Use async bindings only when that binding's own factory needs await.

Use dependsOn to describe readiness order, not constructor injection:

OrbitalBinding.singletonAsync<ApiClient>((resolver) async {
  return ApiClient.connect();
}),
OrbitalBinding.singleton<HomeController>(
  (resolver) => HomeController(
    resolver.get<ApiClient>(),
  ),
  dependsOn: [OrbitalDependencyRef.of<ApiClient>()],
),

The factory still reads values through OrbitalResolver.

Resolver, scope and lifecycle contracts

OrbitalResolver exposes:

  • get<T>()
  • getAsync<T>()
  • getOrNull<T>()
  • isRegistered<T>()
  • isReady<T>()

OrbitalScope extends that contract with:

  • createChild(...)
  • register(...)
  • initialize()
  • dispose()

OrbitalLifecycle is optional and gives framework-managed objects three hooks:

  • onInit()
  • onReady()
  • onDispose()

It also exposes addDisposer(action), which registers cleanup that runs automatically on disposal (in LIFO order) without overriding onDispose(). Disposer failures are reported rather than thrown, so one failing cleanup does not block the rest; a runRegisteredDisposers(onDisposerError:) reporter that itself throws is isolated so it cannot abort the remaining drain either.

After disposal has completed, isDisposed is true and addDisposer becomes a no-op: a cleanup registered after the run could never run, so it is dropped rather than leaked. The concrete runtime typically handles this for you — in orbital_injector, a listen on an already-disposed owner returns a cancelled handle instead of attaching a live subscription.

The execution order and recovery semantics are implemented by the concrete runtime, typically orbital_injector.

Logging and debug contracts

OrbitalLogger provides stable event names plus readable formatted output. orbital_core also owns the runtime debug model consumed by orbital_devtools:

  • scope snapshots
  • router snapshots
  • health summaries
  • service-extension names
  • OrbitalDebugBridge.enable(...)

OrbitalDebugBridge is a singleton. isEnabled reports whether one is active, and instance returns it so callers can reuse a bridge another component (e.g. OrbitalRouter's auto-enable) already created — the first enabler owns the singleton, and a later enable(...) with a different logger/appId throws rather than silently replacing it.

This split keeps runtime packages independent from the DevTools UI while still sharing one debug protocol.

Sensitive data in logs

The default logger preset is normal, which omits dependency read/register tracing. Verbose logging can include route URIs, query parameters, error messages and stack traces. Treat verbose output and debug snapshots as development diagnostics: do not forward them to remote logging services without reviewing or redacting application-specific secrets such as tokens, emails or customer identifiers.

For production telemetry, provide a custom OrbitalLoggerAdapter and redact event.details before export. Keep OrbitalLoggerConfig.minimal() or a category-limited custom config for environments where URLs or query strings may contain sensitive data.

More detail

See doc.md for binding semantics, readiness rules, lifecycle contracts, logger behavior and debug integration.

Libraries

orbital_core