# How DataLayerManager Orchestrates Data Layers in God's Eye View

> Discover how DataLayerManager orchestrates real-time data overlays in God's Eye View using a deterministic control plane for centralized lifecycle management.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: internals
- Published: 2026-09-11

---

**The `DataLayerManager` class in [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js) provides a deterministic, serializable control plane that registers, enables, disables, and refreshes real-time data overlays on the CesiumJS globe through an intent-based epoch system and centralized lifecycle management.**

In the **bilawalsidhu/gods-eye-view** repository, the `DataLayerManager` serves as the central nervous system for all geospatial visualizations. This singleton orchestrator manages every real-time data overlay—from traffic patterns to satellite positions—ensuring deterministic state transitions even under rapid user interaction. Understanding how the DataLayerManager orchestrates different data layers reveals a sophisticated architecture built around intent epochs, lifecycle contracts, and fault-tolerant refresh loops.

## Core Architecture and State Management

The manager initializes with a CesiumJS `viewer` reference and maintains an internal `Map` of layer entries. This registry tracks each layer’s enabled state, refresh timers, and lifecycle metadata according to the source code in [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js).

### Layer Registration and Finalization

The `register(layerModule)` method stores layer modules that must expose a stable string `id`. Duplicate IDs trigger immediate errors, and the registration window seals permanently after invoking `finalizeRegistrations(serializationRegistry)`. This finalization step validates that every layer declares a serialization disposition (e.g., `'enabled-only'`), preventing runtime registration bugs in production builds.

For QA environments, constructing the manager with `{allowQaRegistration: true}` enables the `registerForQa(layerModule)` pathway. These synthetic layers have their IDs tracked in the internal `_qaLayerIds` set, allowing clean removal before production deployment.

## Intent-Based Visibility Control

### The Visibility Intent Epoch Pattern

Rather than mutating state directly, the manager implements an **intent epoch** system via `_setEnabledWithIntent`. Each absolute enable or disable request increments a `visibilityIntentEpoch` counter and stores an intent record with the requested state and origin metadata. When processing completes, the manager discards stale intents that were superseded by newer requests, guaranteeing deterministic final states even when rapid toggles occur.

### Toggle vs. Absolute Enable Operations

The `toggle(layerId, options)` method delegates to `_setEnabledWithIntent` with the negated current state and supports a `notifyWillChangeBeforeEffective` flag. This fires a `visibility-will-change` event before the transition commits, allowing UI components to display loading states. Conversely, `setEnabled(layerId, shouldEnable, options)` provides absolute control, triggering the full lifecycle sequence: optional `init`, `enable`, immediate `update`, and then periodic refreshes.

## Lifecycle Management and Periodic Updates

### State Transitions and Presentation

The manager maintains explicit `lifecycleState` values—`'enabled'`, `'disabled'`, `'enabling'`, `'disabling'`—and propagates these through `_syncModuleLifecyclePresentation` to any module implementing `setLifecyclePresentation`. This synchronization ensures UI toggles reflect underlying async initialization states rather than just boolean flags.

### Automated Refresh Loops

When a layer defines a `refreshInterval` or `updateInterval` greater than zero, `_armUpdateLoop` schedules a `setInterval` that invokes `_runPeriodicUpdate`. These loops respect the layer’s current enabled state and abort signals, automatically cancelling when the layer disables or destroys to prevent memory leaks and unnecessary API polling.

## Event Broadcasting and Fault Tolerance

All state changes flow through `_notifyListeners`, broadcasting granular events—including `visibility`, `refresh`, `error`, and lifecycle transitions—to subscribers registered via `manager.subscribe(callback)`. After successful updates, the manager triggers `governorRequestRender` and marks detection sources as changed, ensuring the Cesium scene reflects the latest data.

If lifecycle steps throw exceptions, the manager captures errors and may place the layer into an **uncertain** state to avoid unintentionally hiding critical information. This fault-tolerant design keeps the globe informative even when individual data sources fail.

## Implementation Examples

### Basic Setup and Registration

```javascript
import { DataLayerManager } from './data/manager.js';
import trafficLayer from './data/traffic.js';
import satellitesLayer from './data/satellites.js';

// Create the manager with the Cesium viewer instance.
const manager = new DataLayerManager(viewer);

// Register production layers.
manager.register(trafficLayer);
manager.register(satellitesLayer);

// Finalize registrations with serialization dispositions.
manager.finalizeRegistrations([
  { id: trafficLayer.id, disposition: 'enabled+options' },
  { id: satellitesLayer.id, disposition: 'enabled+mirrored-options' },
]);

```

### Controlling Layer Visibility

```javascript
// Absolute enable with origin tracking for analytics
await manager.setEnabled('traffic', true, { origin: 'user' });

// Relative toggle for checkbox interactions
await manager.toggle('satellites');

```

### Subscribing to State Changes

```javascript
const unsubscribe = manager.subscribe(change => {
  console.log('Layer change:', change.layerId, change.type);
});

// Cleanup subscription on component unmount
unsubscribe();

```

### QA and Development Workflows

```javascript
// Enable synthetic test layers during development
const qaManager = new DataLayerManager(viewer, { allowQaRegistration: true });
qaManager.registerForQa(syntheticTrafficLayer);

```

## Summary

- **Centralized orchestration**: `DataLayerManager` in [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js) maintains a `Map` of registered layers, handling construction through `register()` and sealing via `finalizeRegistrations()`.
- **Intent-based control**: The `visibilityIntentEpoch` system in `_setEnabledWithIntent` guarantees deterministic ordering of rapid visibility changes through absolute and toggle APIs.
- **Lifecycle automation**: Full state management—including `'enabling'` and `'disabling'` transitions synced via `_syncModuleLifecyclePresentation`—ensures UI consistency during async operations.
- **Resilient refresh loops**: `_armUpdateLoop` and `_runPeriodicUpdate` manage periodic data fetching with automatic cleanup on disable or destroy.
- **Observable state**: The `_listeners` pattern via `subscribe()` broadcasts granular events while supporting fault tolerance through uncertain states and error capture.

## Frequently Asked Questions

### What is the difference between `setEnabled` and `toggle` in DataLayerManager?

`setEnabled(layerId, shouldEnable)` provides absolute control by invoking `_setEnabledWithIntent` with a specific boolean, executing the full initialization, enable, and update lifecycle. `toggle(layerId)` retrieves the current effective state, negates it, and delegates to the same intent system, making it ideal for checkbox or button interactions that simply flip visibility regardless of current state.

### How does DataLayerManager handle rapid successive visibility changes?

The manager implements an **intent epoch** counter (`visibilityIntentEpoch`) in `_setEnabledWithIntent`. Each request increments the epoch and stores a timestamped intent record. When processing completes, the manager validates that no newer intent has superseded the current operation, ensuring that only the most recent user or programmatic request determines the final visible state.

### What happens if a layer fails to initialize or update?

Errors during `init`, `enable`, or `update` are captured within the lifecycle flow. Rather than silently disabling the layer, the manager may place it into an **uncertain** state to prevent unintentional data hiding. Errors propagate through the `_notifyListeners` system, allowing UI components to display warning indicators while the manager continues operating other layers.

### Can I add layers after calling `finalizeRegistrations`?

No. The `finalizeRegistrations(serializationRegistry)` method seals the registration set to prevent accidental additions in production environments. However, when constructing the manager with `{allowQaRegistration: true}`, developers may use `registerForQa()` to inject synthetic test layers after finalization, with IDs tracked in `_qaLayerIds` for later removal.