# How to Check Module and Package Boundaries in God's Eye View: A Complete Guide

> Learn how to check module and package boundaries in God's Eye View. Discover how the DataManager enforces strict API definitions for better code organization and maintainability.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: how-to-guide
- Published: 2026-09-13

---

**God's Eye View enforces strict module boundaries through a central DataManager that registers layer modules in a Map, where only exported methods on the module object constitute the public API and all other internals are considered private implementation details.**

God's Eye View, an open-source project by bilawalsidhu, implements a strict module-per-layer architecture to isolate features like flights, military, and CCTV. Understanding how to check module and package boundaries ensures you only interact with the intended public API and avoid tight coupling to internal implementation details. This guide walks you through the exact steps and code patterns used in the repository to verify these boundaries.

## Understanding the Module-Per-Layer Architecture

God's Eye View organizes code around a **module-per-layer** architecture. Each logical feature lives in its own layer module under `src/layers/<name>/`, encapsulating all related logic, state, and rendering. 

The boundary between packages is defined by the module's public API—specifically the functions, getters, and events exported from the layer's entry file. Everything else inside the folder is considered private implementation detail. Accessing anything beyond the exported surface will yield `undefined` or a runtime error, which serves as an intentional safeguard against coupling.

## Locating the Central DataManager Registry

The **DataManager** ([`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js)) acts as the single source of truth for module registration. It maintains a private `Map` called `layers` that stores every registered layer as a key-value pair:

```js
layers.set('flights', { name: 'flights', module: flightsModule });

```

To check if a module is properly registered and accessible, query the map using the layer identifier:

```js
const mod = dataManager.layers.get('flights')?.module;

```

If the module exists, `Object.keys(mod)` reveals the public surface area—any method not present in this list (such as internal helpers or private state) is out of bounds.

## Step-by-Step Guide to Verify Package Boundaries

### 1. Locate the Layer Source Folder

Navigate to `src/layers/<name>/` (for example, `src/layers/flights/` or `src/layers/cctv/`). This folder encapsulates an entire package. Files inside this directory should not be imported directly by other layers; instead, all interaction must flow through the module object registered in the DataManager.

### 2. Inspect the Module Exports

Open the module's entry file—usually [`index.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/index.js) or `<name>.js`—and examine the `export default` or `module.exports` block. This block explicitly lists the **public API**. Look for methods like `trackById`, `getNearby`, and `clearSelection`, which represent the contract the layer exposes to the rest of the application.

### 3. Verify DataManager Registration

Confirm the package is correctly wired to the system by searching [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js) for the registration call:

```js
layers.set('<name>', { name: '<name>', module: <name>Module });

```

If this line is missing, the layer exists in the filesystem but is not accessible to other parts of the application, indicating a broken package boundary.

### 4. Runtime Inspection of Public APIs

At runtime, fetch the module via `dataManager.layers.get('<name>')?.module` and inspect its keys. This guarantees you are only accessing declared members:

```js
const layer = dataManager.layers.get('flights');
const publicMethods = Object.keys(layer.module);
console.log(publicMethods); // ["trackById", "getNearby", "clearSelection"]

```

### 5. Enforce Boundaries with Automated Tests

Write tests that assert the existence of expected methods and fail when private internals are accessed. This prevents accidental coupling during refactoring.

## Practical Code Examples to Check Boundaries

### Listing the Public API of a Layer

Use this utility to dynamically inspect what a layer exposes:

```js
import { dataManager } from './data/manager.js';

function listLayerAPI(layerId) {
  const layer = dataManager.layers.get(layerId);
  if (!layer?.module) {
    console.warn(`No module found for layer "${layerId}"`);
    return;
  }
  console.log(`Public API of ${layerId}:`, Object.keys(layer.module));
}

// Usage
listLayerAPI('flights');   // → ["trackById","getNearby","clearSelection",…]

```

### Guarded Calls That Respect Package Boundaries

Defensively check for method existence before invocation to ensure you never cross into private implementation:

```js
function safeTrack(layerId, targetId) {
  const mod = dataManager.layers.get(layerId)?.module;
  if (typeof mod?.trackById !== 'function') {
    throw new Error(`Layer "${layerId}" does not expose a trackById method`);
  }
  return mod.trackById(targetId, { origin: 'ui' });
}

// Usage
try {
  safeTrack('cctv', '12345');
} catch (e) {
  console.error(e.message);
}

```

### Automated Tests for Boundary Contracts

Enforce architectural constraints in your test suite to prevent regression:

```js
import { dataManager } from './data/manager.js';
import { expect } from 'chai';

describe('Layer module boundaries', () => {
  const requiredMethods = ['trackById', 'clearSelection', 'getNearby'];
  for (const [id, entry] of dataManager.layers) {
    it(`"${id}" module exports required methods`, () => {
      const mod = entry.module;
      requiredMethods.forEach(fn => {
        expect(mod).to.have.property(fn).that.is.a('function');
      });
    });
  }
});

```

## Key Files That Define Module Boundaries

These files illustrate how God's Eye View separates concerns and maintains package integrity:

- **[`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js)** — The core **DataManager** that registers and retrieves layer modules via the `layers` Map.

- **`src/layers/*/index.js`** (e.g., [`src/layers/flights/index.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/layers/flights/index.js)) — Defines the **layer module** and its public API through explicit exports.

- **[`src/data/contextStore.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/contextStore.js)** — Holds shared state that modules may read but not mutate directly, enforcing unidirectional data flow across package boundaries.

- **[`src/overlays/worldOverlayTokens.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/overlays/worldOverlayTokens.js)** — Example of a *cross-layer* overlay that respects module boundaries by only consuming public APIs.

- **[`src/overlays/worldOverlayDraw.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/overlays/worldOverlayDraw.js)** — Rendering logic that strictly consumes the public surface of other modules without importing private internals.

## Summary

- **God's Eye View** uses a centralized `DataManager` ([`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js)) to register layer modules in a Map, establishing clear package boundaries.
- Each layer under `src/layers/<name>/` encapsulates its own logic; only exported members from the module's entry file constitute the public API.
- Verify boundaries by checking the `layers.set()` registration in the DataManager, then inspect `Object.keys(module)` at runtime.
- Use defensive programming patterns like `typeof mod?.trackById === 'function'` to ensure you only call declared public methods.
- Automated tests can enforce these contracts, failing builds when layers expose insufficient APIs or when code attempts to access private internals.

## Frequently Asked Questions

### How do I know if a method is part of the public API in God's Eye View?

A method is part of the public API only if it appears in the `export default` or `module.exports` block of the layer's entry file (e.g., [`src/layers/flights/index.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/layers/flights/index.js)) and is subsequently accessible via `dataManager.layers.get('flights')?.module`. If `Object.keys(module)` does not include the method name, it is a private internal and should not be called.

### What happens if I try to access private internals of a layer module?

Attempting to access properties or methods not exported by the layer module will yield `undefined` or throw a runtime error. This behavior is intentional—it acts as a safeguard preventing tight coupling to implementation details that may change without notice.

### Where is the layer registry defined in the codebase?

The layer registry is defined in [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js) as a private `Map` named `layers`. This registry is populated via `layers.set('<name>', { name: '<name>', module: <name>Module })` calls during application initialization, making it the authoritative source for which packages are available to the system.

### Can I add a new layer without modifying the DataManager?

No. To maintain proper package boundaries, every new layer must be explicitly imported and registered in [`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js) using the `layers.set()` API. Without this registration step, the module exists in the filesystem but remains isolated from the rest of the application, ensuring the architecture's integrity is preserved.