orbital_router 0.1.1
orbital_router: ^0.1.1 copied to clipboard
Flutter router integration for Orbital modules, scopes and deep links.
orbital_router #
Flutter routing integration for Orbital modules, scopes, deep links and navigation guards.
Imports #
orbital_router exports the routing API plus the core contracts used by route
declarations.
If you want the default scope runtime, import orbital_injector as well:
import 'package:orbital_injector/orbital_injector.dart';
import 'package:orbital_router/orbital_router.dart';
If you prefer a single import surface, use package:orbital/orbital.dart.
What this package contains #
orbital_router connects the Orbital scope model to Flutter navigation:
OrbitalApp.router(...)OrbitalModule,OrbitalPageRouteandOrbitalModuleRouteOrbitalRouterDelegateOrbitalRouteContextOrbitalMiddlewareandOrbitalAsyncMiddlewareOrbitalRetentionPolicyOrbitalScopeFactoryOrbitalScopeProviderplusBuildContextextensions- router debug snapshots consumed by
orbital_devtools
Quick start #
MaterialApp.router(
routerConfig: OrbitalApp.router(
scopeFactory: const DefaultOrbitalScopeFactory(),
initialUri: Uri.parse('/'),
modules: [
OrbitalModule(
path: '/',
routes: [
OrbitalPageRoute(
path: '/home',
builder: (context, routeContext) => const HomePage(),
),
],
),
],
),
);
Route tree model #
Orbital composes navigation from modules and page routes.
Modules contribute:
- a base path
- module-scoped bindings
- module-scoped middlewares
- nested pages or submodules
Pages contribute:
- a page path
- page-scoped bindings
- page-scoped middlewares
- a widget builder
- optional retention semantics
- optional route and async page presentation overrides
Matching and module identity #
Route matching prefers more specific branches first. Static segments outrank parameterized segments; declaration order is only the final tiebreaker.
OrbitalModule.id is the semantic identity used for scope reuse across rebuilt
declarations. If you want a module scope to survive equivalent rebuilds, supply
an explicit id.
Without id, reuse falls back to the module declaration identity inside the
current delegate instance, which prevents unrelated modules that merely share
the same path from accidentally reusing each other's scope.
Async navigation #
A branch is treated as async when it contains async bindings or async middlewares.
Use:
asyncNavigationBuilderasyncNavigationPageFactorypageFactory
Precedence is:
- page
- nearest module
- app-level default
During async navigation, Orbital keeps the currently rendered route mounted under the async page by default. The fallback async page is non-opaque, so the active page remains visible unless a custom async page factory chooses a different presentation.
OrbitalAsyncNavigationState.background remains available for custom builders
that want to compose an explicit background widget.
Middleware #
OrbitalMiddleware can:
- continue navigation
- block navigation
- redirect to another URI
Hook points:
onBeforeRunonAfterRun
Middlewares that may await must implement OrbitalAsyncMiddleware.
Scope access and navigation helpers #
Pages can read route and scope state from:
OrbitalRouteContextcontext.orbitalRouteContextcontext.orbitalScopecontext.getOrbital<T>()context.pushNamed('/path')context.pushReplacementNamed('/path')
Orbital currently renders one active Flutter page at a time. Methods such as
pushNamed add entries to Orbital's logical history, not to a multi-page
Navigator.pages stack. Use pop() / popRoute() / popUntil(...) to walk
that logical history.
Retention and scope rules #
- page bindings require
createScope: true - persistent module and page scopes can be retained across navigations
- page retention keys default to
path + query + fragment persistentScopeKeyBuilderlets apps override page retention semanticsOrbitalRetentionPolicybounds retained module/page entries and evicts the oldest retained scope when capacity is exceeded
More detail #
See doc.md for lifecycle flow, middleware orchestration, logical history, async overlay behavior and error semantics.