Class Architecture - Incomplete-Infinity/eve-companion GitHub Wiki
🧠 Class Architecture
The EVE Companion App follows a modular class-based design, where each major data structure (e.g., a character, type, or system) is represented by a single class in its own file. This approach ensures clarity, separation of concerns, and scalability.
🗂️ Directory Structure
All core logic classes are stored in:
src/js/main/
Each file contains one class that corresponds to a game object or logical entity.
Examples:
InventoryType.js
→ Represents an item type from ESICharacter.js
→ Represents a pilotSystem.js
→ Represents a solar systemCorporation.js
→ Represents a player corp
📚 Class Pattern
Each class:
- Accepts a minimal identifier in the constructor (e.g.,
typeId
,characterId
) - Retrieves data from the ESI Swagger client
- Enriches or reformats the data
- Exposes it via instance properties
- Optionally saves to local cache (Dexie)
export default class InventoryType {
constructor(typeId, token) {
this.typeId = typeId;
this.token = token;
this.name = null;
this.description = null;
this.groupId = null;
this.loaded = false;
}
async load() {
if (this.loaded) return;
const api = new UniverseApi(new Configuration({
accessToken: this.token,
basePath: 'https://esi.evetech.net/latest'
}));
const { data } = await api.getUniverseTypesTypeId({ typeId: this.typeId });
Object.assign(this, data);
this.loaded = true;
}
}
💡 Lazy Loading Strategy
To reduce API load and startup time:
- Instances are created with IDs only
.load()
or similar must be called to fetch details- Zustand and p-queue manage global request state and throttling
🔗 Connecting Classes
Many classes relate to each other. Example:
const type = new InventoryType(34, token);
await type.load();
const group = new InventoryGroup(type.groupId);
await group.load();
Future improvements will allow auto-linking via shared cache or context.
🌐 Frontend Integration
- These classes live in the main/worker context (Node/Electron)
- The renderer UI accesses data via messaging or shared IndexedDB
- Zustand stores track current selection (e.g.,
activeCharacter
,selectedFit
)
🔍 Naming Conventions
- Class names are PascalCase
- Files are named to match the class
- Methods like
.load()
,.toJSON()
,.save()
are standardized - Internal-only methods are prefixed with
_
(e.g.,_fetch()
)
⚡ Advanced Extensions (Planned)
- Auto-cache with Dexie
- Shared instance registry (Universe pattern)
- Class inheritance for shared logic (e.g.,
Character
←Contact
) - Relationship mapping (e.g.,
Character.corporation
as aCorporation
instance)
🔄 Summary
This class-based architecture is central to the app. It provides:
- Clean abstraction over ESI
- Consistent lazy-loading and caching
- A scalable structure for future features
Continue to:
- [ESI Integration](./ESI-Integration)
- [Electron Setup](./Electron-Setup)