@expofp/wayfinding
Framework-neutral wayfinding for the ExpoFP SDK: a routing/snapping engine, an
imperative runtime orchestrator, and a scene renderer — with no coupling to
efp stores or MobX. core and runtime are environment-agnostic; the scene
renderer assumes a browser-like environment (requestAnimationFrame, document),
so the package is not suitable for Node/SSR as-is. All three layers sit behind a
single entry point, createWayfinding.
Install
pnpm add @expofp/wayfinding @expofp/renderer
@expofp/renderer is a peer dependency and must be installed by the consumer:
the package's public types (e.g. RenderableDef on Wayfinding/RendererPort)
reference it, so its types must resolve for @expofp/wayfinding's .d.ts to compile.
Layers
core | Graph build + A* pathfinding, route geometry, snapping, transition points. Pure functions. |
runtime | Imperative orchestrator (setRoute / setPosition / notifyFloorChanged) over the engine. |
renderer | Scene mutator (icons, trails, route lines) against an injected RendererPort. |
These layers are internal. The package exports only the createWayfinding
facade, the port interfaces the host implements, the boundary data types, the
CURRENT_POSITION_POINT_ID protocol sentinel, and the optimizeWaypointOrder
helper.
Ports (host implements)
The package knows nothing concrete about the host renderer, graph data, or app
state. The host supplies four ports via WayfindingConfig:
dataSource (GraphDataSource) — graph lines + line ends for pathfinding.
renderer (RendererPort) — def factories, current scale, scene layers, commit.
iconProvider (IconProvider) — canvases for icon names.
floorContext (FloorContext) — active floor / visibility predicates.
@expofp/renderer is a type-only peer (its types appear in the public API; the
concrete renderer is injected through RendererPort). @expofp/geometry is a regular
runtime dependency (Rect, Box, geometry helpers).
Usage
import { createWayfinding } from '@expofp/wayfinding';
const wayfinding = createWayfinding({
dataSource,
renderer,
iconProvider,
floorContext,
layers,
gpsConfig,
onTransitionClick: (point) => {
},
onRouteUpdate: (lines, bounds) => {
},
onRouteDistance: (distance) => {
},
});
wayfinding.setRoute({ from, to, accessible: false });
wayfinding.setPosition(position);
wayfinding.notifyFloorChanged();
wayfinding.applyScale(scale);
wayfinding.applyRoll(angle);
wayfinding.handleClick(pickedDefs);
wayfinding.destroy();
optimizeWaypointOrder is exported separately to order booth waypoints before a
createWayfinding instance exists (it backs the SDK's getOptimizedRoutes).