class ScalableDataModel extends Multisynq.Model {
init(options) {
super.init(options);
// Use Maps for O(1) lookups
this.users = new Map();
this.spatialIndex = new Map(); // Grid-based spatial indexing
// Track only essential data in main model
this.userSummaries = new Map(); // Lightweight user data
}
addUser(userData) {
const { id, x, y } = userData;
// Store full data
this.users.set(id, userData);
// Store lightweight summary
this.userSummaries.set(id, { id, x, y, lastUpdate: this.now() });
// Update spatial index
this.updateSpatialIndex(id, x, y);
// Only publish summary to reduce bandwidth
this.publish(this.sessionId, "userAdded", this.userSummaries.get(id));
}
updateSpatialIndex(userId, x, y) {
const gridX = Math.floor(x / 100); // 100-unit grid
const gridY = Math.floor(y / 100);
const gridKey = `${gridX},${gridY}`;
if (!this.spatialIndex.has(gridKey)) {
this.spatialIndex.set(gridKey, new Set());
}
this.spatialIndex.get(gridKey).add(userId);
}
getUsersInRegion(x, y, radius) {
const nearbyUsers = [];
const gridRadius = Math.ceil(radius / 100);
for (let dx = -gridRadius; dx <= gridRadius; dx++) {
for (let dy = -gridRadius; dy <= gridRadius; dy++) {
const gridKey = `${Math.floor(x/100) + dx},${Math.floor(y/100) + dy}`;
const gridUsers = this.spatialIndex.get(gridKey);
if (gridUsers) {
gridUsers.forEach(userId => {
const user = this.userSummaries.get(userId);
if (user && this.distance(x, y, user.x, user.y) <= radius) {
nearbyUsers.push(user);
}
});
}
}
}
return nearbyUsers;
}
}