Keep tracked-entity state in Core records instead of on Cesium entities

Flights, military, satellites, installations, local ADS-B and ALPR hung
gevTrackedId, gevDisplayPosition, gevVisualPosition, gevSelectionOrigin and
gevLabelModel on the Cesium entities they draw, and the tracked readout,
follow camera, cockpit, share links and awareness read them back. They now
live in src/data/entityRecords.js, a Core-owned record per entity: layers
write entityRecord(entity), readers use readEntityRecord(entity). Nothing
changes on screen. This is the first slice of the renderer plan's state
mirror (P1).

The module is exported as ./data/entity-records so hosted code can read the
same records, and window.__godsEyeView.entityRecords gives the QA scripts
the same access from the page.
This commit is contained in:
Sameh Khamis committed 2026-11-03 08:09:00 -08:00
1 parent ea69bb4ce2
commit 95c0070412
53 files changed
+408 -291

No files matched your search

+27 -11
View File
@@ -871,7 +871,8 @@
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
"src/ui/unitLabels.js",
"src/data/entityRecords.js"
],
"external": ["cesium"]
},
@@ -1124,7 +1125,8 @@
"src/ui/kit/UiBadge.vue",
"src/ui/stores/globeActions.js",
"src/ui/stores/recording.js",
"src/ui/i18n.js"
"src/ui/i18n.js",
"src/data/entityRecords.js"
],
"external": ["cesium", "vue", "pinia", "vue-i18n"]
},
@@ -1335,7 +1337,8 @@
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
"src/ui/unitLabels.js",
"src/data/entityRecords.js"
],
"external": ["cesium"]
},
@@ -1391,7 +1394,8 @@
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
"src/i18n/locales/zh-Hant.json",
"src/data/entityRecords.js"
],
"external": ["cesium"]
},
@@ -1576,7 +1580,8 @@
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
"src/ui/unitLabels.js",
"src/data/entityRecords.js"
],
"external": ["cesium", "satellite.js"]
},
@@ -1667,7 +1672,8 @@
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/layers/installations/classLabel.js"
"src/layers/installations/classLabel.js",
"src/data/entityRecords.js"
],
"external": ["cesium", "@mapbox/vector-tile", "pbf"]
},
@@ -1713,7 +1719,8 @@
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
"src/ui/unitLabels.js",
"src/data/entityRecords.js"
],
"external": ["cesium"]
},
@@ -1973,7 +1980,8 @@
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
"src/i18n/locales/zh-Hant.json",
"src/data/entityRecords.js"
],
"external": ["cesium", "@mapbox/vector-tile", "pbf"]
},
@@ -3184,7 +3192,8 @@
"src/data/placeBoundaries.js",
"src/data/placeNames.js",
"src/data/local_data/us_census_places/files.js",
"src/data/local_data/wof_neighborhoods/files.js"
"src/data/local_data/wof_neighborhoods/files.js",
"src/data/entityRecords.js"
],
"external": [
"hls.js",
@@ -3792,7 +3801,8 @@
"src/data/placeBoundaries.js",
"src/data/placeNames.js",
"src/data/local_data/us_census_places/files.js",
"src/data/local_data/wof_neighborhoods/files.js"
"src/data/local_data/wof_neighborhoods/files.js",
"src/data/entityRecords.js"
],
"external": [
"hls.js",
@@ -3890,6 +3900,11 @@
"mgrs"
]
},
"entity-records": {
"exports": ["./data/entity-records"],
"modules": ["src/data/entityRecords.js"],
"external": []
},
"layer-lifecycle": {
"exports": ["./data/lifecycle"],
"modules": ["src/data/lifecycle.js", "src/data/cameraArrival.js"],
@@ -3944,7 +3959,8 @@
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
"src/i18n/locales/zh-Hant.json",
"src/data/entityRecords.js"
],
"external": []
},
+2 -2
View File
@@ -763,7 +763,7 @@ try {
} : null,
navigation: snapshot?.navigation || null,
afterId: trackedInfo?.icao24 || null,
viewerTrackedId: viewer.trackedEntity?.gevTrackedId || null,
viewerTrackedId: window.__godsEyeView.entityRecords.read(viewer.trackedEntity)?.trackedId || null,
contextVisible: !document.getElementById('military-awareness-panel')?.hidden,
entryAvailableAfterSettlement: Boolean(entry && !entry.hidden),
blockerStillRegistered: dataManager.layers.has(blockerId),
@@ -1362,7 +1362,7 @@ try {
contextMode: styleManager._contextControls._contextMode,
contextChanging: styleManager._contextControls._contextModeChanging,
subject: context?.subject ? `${context.subject.layerId}:${context.subject.id}` : null,
tracked: tracker?.gevTrackedId || null,
tracked: window.__godsEyeView.entityRecords.read(tracker)?.trackedId || null,
density: styleManager.getDetectionState().densityPct,
detectionMode: styleManager.getDetectionState().detectionMode,
installations: dataManager.getLayerLifecycleState('military-installations'),
+6 -3
View File
@@ -360,7 +360,9 @@ async function contacts() {
entities: ds?.entities.values.length ?? 0,
created,
tracked:
window.__godsEyeView.viewer.trackedEntity?.gevTrackedId ?? null,
window.__godsEyeView.entityRecords.read(
window.__godsEyeView.viewer.trackedEntity,
)?.trackedId ?? null,
cockpit: document.body.classList.contains('cockpit-mode'),
});
if (samples.length > 5000) samples.splice(0, 1000);
@@ -375,8 +377,9 @@ async function contacts() {
await page
.waitForFunction(
() =>
window.__godsEyeView.viewer.trackedEntity?.gevTrackedId ===
'flights:aaa051',
window.__godsEyeView.entityRecords.read(
window.__godsEyeView.viewer.trackedEntity,
)?.trackedId === 'flights:aaa051',
{ timeout: 60_000 },
)
.catch(() => {});
+3 -3
View File
@@ -169,8 +169,8 @@ async function observeTrackedHostPaint(page, timeoutMs = 5000) {
const tracked = viewer?.trackedEntity;
const current = {
elapsedMs: Math.round(performance.now() - startedAt),
entryId: tracked?.gevTrackedId || null,
hasPresentationModel: Boolean(tracked?.gevLabelModel?.title),
entryId: window.__godsEyeView?.entityRecords?.read(tracked)?.trackedId || null,
hasPresentationModel: Boolean(window.__godsEyeView?.entityRecords?.read(tracked)?.labelModel?.title),
candidateCount: diagnostics.candidateCount || 0,
projectedCount: diagnostics.projectedCount || 0,
selectedCount: diagnostics.selectedCount || 0,
@@ -610,7 +610,7 @@ async function main() {
if (!pool.length) return null;
const ent = v.trackedEntity;
let tracked = null;
if (ent && typeof ent.gevDisplayPosition === 'function') tracked = ent.gevDisplayPosition();
if (ent && typeof window.__godsEyeView.entityRecords.read(ent)?.displayPosition === 'function') tracked = window.__godsEyeView.entityRecords.read(ent)?.displayPosition();
if (!tracked) return pool[0];
let best = null, bestD = Infinity;
for (const m of pool) {
+1 -1
View File
@@ -333,7 +333,7 @@ export async function checkInstallationSelection(
for (let y = 250; y < 650; y += 75)
for (let x = 400; x < 850; x += 75) {
const pick = g.viewer.scene.pick({ x, y });
if (!pick?.id?.installationId && !pick?.id?.gevTrackedId)
if (!pick?.id?.installationId && !window.__godsEyeView.entityRecords.read(pick?.id)?.trackedId)
return { x, y };
}
throw new Error('No empty map point');
+6 -6
View File
@@ -3817,7 +3817,7 @@ async function main() {
id: `qa:${ownerPrefix}:radio-camera-owner`,
position: viewer.camera.positionWC.clone(),
});
owner.gevTrackedId = `${ownerPrefix}:qa-radio-camera-owner`;
window.__godsEyeView.entityRecords.write(owner).trackedId = `${ownerPrefix}:qa-radio-camera-owner`;
viewer.trackedEntity = owner;
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
const beforeStationId = radio.getUIState().selected?.id || null;
@@ -3831,7 +3831,7 @@ async function main() {
afterStationId: radio.getUIState().selected?.id || null,
flyToDelta: window.__qaRadioFlyToCalls.length - beforeFlyToCalls,
trackedIdentityPreserved: viewer.trackedEntity === owner,
trackedId: viewer.trackedEntity?.gevTrackedId || null,
trackedId: window.__godsEyeView.entityRecords.read(viewer.trackedEntity)?.trackedId || null,
};
viewer.trackedEntity = undefined;
viewer.entities.remove(owner);
@@ -3867,11 +3867,11 @@ async function main() {
id: 'qa:flights:delayed-radio-fallback-owner',
position: viewer.camera.positionWC.clone(),
});
owner.gevTrackedId = 'flights:qa-delayed-radio-fallback-owner';
window.__godsEyeView.entityRecords.write(owner).trackedId = 'flights:qa-delayed-radio-fallback-owner';
viewer.trackedEntity = owner;
window.__qaDelayedRadioTrackingOwner = owner;
window.__qaRejectRadioPlay();
return owner.gevTrackedId;
return window.__godsEyeView.entityRecords.read(owner)?.trackedId;
});
await page.waitForFunction(() => window.__godsEyeView.dataManager.layers.get('radio').module.getUIState().audioState === 'playing');
const delayedFallbackOwnership = await page.evaluate((beforeFlyToCalls) => {
@@ -3880,7 +3880,7 @@ async function main() {
const result = {
flyToDelta: window.__qaRadioFlyToCalls.length - beforeFlyToCalls,
trackedIdentityPreserved: viewer.trackedEntity === owner,
trackedId: viewer.trackedEntity?.gevTrackedId || null,
trackedId: window.__godsEyeView.entityRecords.read(viewer.trackedEntity)?.trackedId || null,
selectedId: window.__godsEyeView.dataManager.layers.get('radio').module.getUIState().selected?.id || null,
};
viewer.trackedEntity = undefined;
@@ -4222,7 +4222,7 @@ async function main() {
id: 'qa:flights:radio-recenter-stage-owner',
position: viewer.camera.positionWC.clone(),
});
owner.gevTrackedId = 'flights:qa-radio-recenter-stage-owner';
window.__godsEyeView.entityRecords.write(owner).trackedId = 'flights:qa-radio-recenter-stage-owner';
viewer.trackedEntity = owner;
completeFlight(0);
const trackingBetweenStagesCalls = calls.length;
+14 -14
View File
@@ -701,7 +701,7 @@ async function main() {
const tracked = manager?.layers?.get('flights')?.module?.getTrackedInfo?.();
return manager?.isEnabled?.('flights')
&& tracked?.icao24 === 'aaa001'
&& window.__godsEyeView.viewer.trackedEntity?.gevTrackedId === 'flights:aaa001';
&& window.__godsEyeView.entityRecords.read(window.__godsEyeView.viewer.trackedEntity)?.trackedId === 'flights:aaa001';
},
{ timeout: 30000, polling: 100 },
);
@@ -712,7 +712,7 @@ async function main() {
flightsEnabled: manager.isEnabled('flights'),
trackedId: flights.getTrackedInfo()?.icao24 || null,
durableId: flights.getParams()?.selectedFlightsTrackingId || null,
viewerTrackedId: window.__godsEyeView.viewer.trackedEntity?.gevTrackedId || null,
viewerTrackedId: window.__godsEyeView.entityRecords.read(window.__godsEyeView.viewer.trackedEntity)?.trackedId || null,
};
});
record(
@@ -742,7 +742,7 @@ async function main() {
const tracked = manager?.layers?.get('flights')?.module?.getTrackedInfo?.();
return manager?.isEnabled?.('flights')
&& tracked?.icao24 === 'aaa001'
&& window.__godsEyeView.viewer.trackedEntity?.gevTrackedId === 'flights:aaa001';
&& window.__godsEyeView.entityRecords.read(window.__godsEyeView.viewer.trackedEntity)?.trackedId === 'flights:aaa001';
},
{ timeout: 30000, polling: 100 },
);
@@ -753,7 +753,7 @@ async function main() {
flightsEnabled: manager.isEnabled('flights'),
trackedId: flights.getTrackedInfo()?.icao24 || null,
durableId: flights.getParams()?.selectedFlightsTrackingId || null,
viewerTrackedId: window.__godsEyeView.viewer.trackedEntity?.gevTrackedId || null,
viewerTrackedId: window.__godsEyeView.entityRecords.read(window.__godsEyeView.viewer.trackedEntity)?.trackedId || null,
};
});
record(
@@ -815,7 +815,7 @@ async function main() {
const latchedShare = await evalPage(() => ({
tracked: window.__godsEyeView.dataManager.layers
.get('flights').module.getTrackedInfo()?.icao24 || null,
viewerTrackedId: window.__godsEyeView.viewer.trackedEntity?.gevTrackedId || null,
viewerTrackedId: window.__godsEyeView.entityRecords.read(window.__godsEyeView.viewer.trackedEntity)?.trackedId || null,
}));
record(
'share-v2: the pending subject latches on when it arrives on a later poll',
@@ -1380,7 +1380,7 @@ async function main() {
if (exactPickModel) return exactPickModel;
const ent = window.__godsEyeView.viewer.trackedEntity;
let tracked = null;
if (ent && typeof ent.gevDisplayPosition === 'function') tracked = ent.gevDisplayPosition();
if (ent && typeof window.__godsEyeView.entityRecords.read(ent)?.displayPosition === 'function') tracked = window.__godsEyeView.entityRecords.read(ent)?.displayPosition();
if (!tracked) return pool[0];
let best = null, bestD = Infinity;
for (const m of pool) {
@@ -1427,7 +1427,7 @@ async function main() {
const dm = window.__godsEyeView.dataManager;
const fl = dm.layers.get('flights').module;
const ent = window.__godsEyeView.viewer.trackedEntity;
const disp = ent && typeof ent.gevDisplayPosition === 'function' ? ent.gevDisplayPosition() : null;
const disp = ent && typeof window.__godsEyeView.entityRecords.read(ent)?.displayPosition === 'function' ? window.__godsEyeView.entityRecords.read(ent)?.displayPosition() : null;
const dets = fl.getDetectableObjects({ maxCount: 1000 });
const me = dets.find((d) => d.id === icao || d.id === (fl.getTrackedInfo() && fl.getTrackedInfo().callsign));
if (!disp || !me || !me.position) return null;
@@ -1656,7 +1656,7 @@ async function main() {
const ti = fl.getTrackedInfo();
if (!ti) return null;
const ent = v.trackedEntity;
const disp = ent && typeof ent.gevDisplayPosition === 'function' ? ent.gevDisplayPosition() : null;
const disp = ent && typeof window.__godsEyeView.entityRecords.read(ent)?.displayPosition === 'function' ? window.__godsEyeView.entityRecords.read(ent)?.displayPosition() : null;
const pos = disp || ti.position;
if (!pos) return null;
const center = v.scene.cartesianToCanvasCoordinates(pos);
@@ -1908,7 +1908,7 @@ async function main() {
// presentation model (entities are asserted native-label-free);
// the native read stays as a fallback so this probe still fails
// loudly if BOTH surfaces are ever absent.
const model = ent.gevLabelModel;
const model = window.__godsEyeView.entityRecords.read(ent)?.labelModel;
if (model) return [model.title, ...(model.details || [])].filter(Boolean).join('\n');
if (!ent.label || !ent.label.text) return null;
const t = ent.label.text;
@@ -2553,7 +2553,7 @@ async function main() {
}
// WELD (tracked): the tracked CARD anchors to the model you can see.
// `gevVisualPosition` is a SEPARATE accessor from `gevDisplayPosition` on
// the record's `visualPosition` is a SEPARATE accessor from its `displayPosition` on
// purpose — the latter carries the follow-camera anti-jitter contract and
// must keep returning the cached dead-reckoned value the camera settled
// on. So this asserts both halves: the visual accessor is welded to the
@@ -2580,10 +2580,10 @@ async function main() {
const at = (p) => (p ? Math.hypot(
p.x - anchor.x, p.y - anchor.y, p.z - anchor.z,
) : null);
const visual = typeof ent?.gevVisualPosition === 'function' ? ent.gevVisualPosition() : null;
const display = typeof ent?.gevDisplayPosition === 'function' ? ent.gevDisplayPosition() : null;
const visual = typeof window.__godsEyeView.entityRecords.read(ent)?.visualPosition === 'function' ? window.__godsEyeView.entityRecords.read(ent)?.visualPosition() : null;
const display = typeof window.__godsEyeView.entityRecords.read(ent)?.displayPosition === 'function' ? window.__godsEyeView.entityRecords.read(ent)?.displayPosition() : null;
return {
hasVisualAccessor: typeof ent?.gevVisualPosition === 'function',
hasVisualAccessor: typeof window.__godsEyeView.entityRecords.read(ent)?.visualPosition === 'function',
visualDelta: at(visual),
displayDelta: at(display),
};
@@ -2599,7 +2599,7 @@ async function main() {
// anti-jitter accessor has been repurposed and the follow camera is at
// risk. Skipped (not failed) when the DR cache is momentarily invalid.
const displayDelta = trackedWeld.displayDelta;
record('weld: gevDisplayPosition still reports the dead-reckoned position (anti-jitter intact)',
record('weld: the record displayPosition still reports the dead-reckoned position (anti-jitter intact)',
!Number.isFinite(displayDelta) || displayDelta > ACCESSOR_SEPARATION_EPSILON_M,
Number.isFinite(displayDelta)
? `displayΔ=${displayDelta.toFixed(3)} m (must stay > ${ACCESSOR_SEPARATION_EPSILON_M} m — the ground-snap split)`