Architecture
Module Hierarchy
graph TD
A[index.js] --> B[index_maps.js]
A --> C[index_indoor.js]
B --> D[Map]
B --> E[Marker / InfoWindow / OverlayView]
B --> F[Geometry — Polygon, Polyline, Circle, Rectangle]
B --> G[Data Layer — GeoJSON features]
B --> H[Services — Distance, Stores, Localities, etc.]
B --> I[Directions — Service + Renderer]
B --> J[Overlays — StoresOverlay, DatasetsOverlay]
B --> K[ImageMapType — Tile layers]
C --> L[IndoorRenderer]
C --> M[IndoorService]
D --> N[MVCObject]
E --> N
F --> N
G --> N
style A fill:#4051b5,color:#fff
style B fill:#4051b5,color:#fff
style C fill:#4051b5,color:#fff
Initialization Flow
sequenceDiagram
participant Browser
participant Config
participant Map
participant MapboxGL
participant Worker
Browser->>Config: Parse script tag params (key, language, libraries)
Browser->>Map: new Map(div, options)
Map->>MapboxGL: Initialize mbgl.Map with default style
MapboxGL->>Worker: Spawn tile processing web worker
Map->>Map: Apply gestureHandling overlay
Map->>Map: Bind Data layer
Map->>Map: Initialize MVCObject properties
Map-->>Browser: Fire 'tilesloaded' event
Map-->>Browser: Fire 'idle' event
Source Organization
src/
├── index.js # Main entry (Maps + Indoor)
├── index_maps.js # Maps-only exports
├── index_indoor.js # Indoor exports
├── index_services.js # Services-only entry
├── map.js # Map class
├── marker.js # Marker class
├── infowindow.js # InfoWindow class
├── overlay-view.js # OverlayView base class
├── latlng.js # LatLng, LatLngBounds
├── mvcobject.js # MVCObject (observable properties)
├── mvcarray.js # MVCArray (observable array)
├── config.js # Global config singleton
├── directions-service.js # DirectionsService
├── directions-renderer.js # DirectionsRenderer
├── stores-overlay.js # StoresOverlay
├── datasets-overlay.js # DatasetsOverlay
├── geometry/ # Polygon, Polyline, Circle, Rectangle
├── data/ # GeoJSON data layer, symbols, feature styling
├── services/ # API clients
│ ├── distance/
│ ├── stores/
│ ├── localities/
│ ├── datasets/
│ ├── transit/
│ └── query/
├── indoor/ # Indoor renderer and service
├── widgets/ # Preact UI components
│ ├── navigation/ # Navigation control
│ └── indoor/ # Indoor panel
├── drawing/ # Drawing tools (wraps mapbox-gl-draw)
├── map-style/ # MapStyleSpec processing
├── map-type/ # ImageMapType tile overlays
├── css/ # PostCSS source
└── utils/ # Network, caching, errors, image processing
MVCObject Pattern
MVCObject is the base class for most map objects. It implements a Key-Value Observer pattern inspired by Google Maps:
class MVCObject {
get(key) // Get property value
set(key, value) // Set property and notify listeners
addListener(event, handler) // Listen for property changes
bindTo(key, target, targetKey) // Bind property to another MVCObject
}
When a property changes, the object fires a {key}_changed event. Bound properties propagate changes bidirectionally.
Classes that extend MVCObject: Map, Marker, InfoWindow, OverlayView, Polygon, Polyline, Circle, Rectangle, Data, and more.
Global Namespace Assembly
The entry points assemble exports into window.woosmap.map:
graph LR
A[index_maps.js] -->|Object.assign| C[window.woosmap.map]
B[index_indoor.js] -->|Object.assign| C
C -->|alias| D[window.ninja.maps]
The services.js bundle exports a subset (services only) to the same namespace, allowing headless API usage without loading the map renderer.
Styling Pipeline
Map styling follows this flow:
- User calls
map.setMapStyle(styles: MapStyleSpec[]) - Styles are validated against the spec (feature types, element types, styler properties)
MapStyleiterates styles and applies transforms viaapplyStylers()- Transforms modify Mapbox GL layer paint properties (color, weight, visibility)
- A
style_updateevent fires when processing completes
Data Flow
graph LR
A[User Input] --> B[Map / Service API]
B --> C[Config — URL construction]
C --> D[REQUESTER — HTTP client]
D --> E[Woosmap API]
E --> D
D --> B
B --> F[MVCObject — property update]
F --> G[Event listeners / UI update]
Services use the REQUESTER utility for all HTTP communication. The Config singleton constructs API URLs based on the build environment and API key format.