How to Check Module and Package Boundaries in God's Eye View: A Complete Guide
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) 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:
layers.set('flights', { name: 'flights', module: flightsModule });
To check if a module is properly registered and accessible, query the map using the layer identifier:
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 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 for the registration call:
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:
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:
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:
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:
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— The core DataManager that registers and retrieves layer modules via thelayersMap. -
src/layers/*/index.js(e.g.,src/layers/flights/index.js) — Defines the layer module and its public API through explicit exports. -
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— Example of a cross-layer overlay that respects module boundaries by only consuming public APIs. -
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) 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 inspectObject.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) 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 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →