Quick reference for coding conventions used throughout the codebase.
Actions collocated with state, supporting both direct values and updater functions:
const useAppStore = create<AppStore>((set, get) => ({
activeMode: 'view',
setGeoJson: (geoJsonOrFn) => {
if (typeof geoJsonOrFn === 'function') {
set({ geoJson: geoJsonOrFn(get().geoJson) });
} else {
set({ geoJson: geoJsonOrFn });
}
},
}));Use getState() to avoid stale closures:
function handleClick() {
const { activeMode } = useAppStore.getState(); // Always fresh
}| Pattern | Rule |
|---|---|
| Functional only | No class components |
| Store consumption | Direct store access for complex state; props for testable sub-components |
| Inline styles | TypeScript-checked via styles.ts constants |
| Conditional render | Early return: if (!isOpen) return null; |
- All hooks exported via barrel (
hooks/index.ts) - Complex return types in
hooks/types.ts - Always return cleanup functions from effects
- Use refs for non-rendering state updates
Deck.gl layers built via pure factory function in layers/buildLayers.ts:
- Pure function = testable + memoizable
- All layer config in one place
- Zoned layer data (walls, borders, ceilings) computed separately in
zonedLayerData.ts
| Level | Approach |
|---|---|
| React sections | ErrorBoundary / PanelErrorBoundary |
| User-facing | Toast system via useToast() |
| Internal | Structured logging with log.info/error |
import typefor type-only imports- Discriminated unions via
featureTypeproperty - Type guards for geometry narrowing (
isPolygonLike)
| Strategy | Use Case |
|---|---|
| Geometry hash (djb2) | Detect GeoJSON coordinate changes |
| TTL cache (30s) | Terrain elevation results |
- Barrel exports via
index.tsin each folder - Named exports preserve tree-shaking
- Group by domain:
hooks/map/,hooks/routes/,hooks/vehicles/