function cloneObject(value) {
|
return JSON.parse(JSON.stringify(value || {}));
|
}
|
|
class StateCache {
|
constructor(options = {}) {
|
this.includeDeviceIdField = options.includeDeviceIdField !== false;
|
this.deviceIdField = options.deviceIdField || 'n';
|
this.entries = new Map();
|
}
|
|
update(device, metric = {}, meta = {}) {
|
if (!device || !device.deviceId) {
|
throw new Error('设备缺少 deviceId');
|
}
|
|
const entry = this.getOrCreateEntry(device);
|
entry.device = device;
|
entry.lastUpdateAt = Date.now();
|
|
if (meta.messageType === 'realtime') {
|
entry.lastRealtimeAt = entry.lastUpdateAt;
|
}
|
|
if (meta.messageType === 'blood-pressure') {
|
entry.lastBloodPressureAt = entry.lastUpdateAt;
|
}
|
|
Object.assign(entry.payload, metric);
|
|
if (this.includeDeviceIdField) {
|
entry.payload[this.deviceIdField] = device.deviceId;
|
}
|
|
return this.getPayload(device.deviceId);
|
}
|
|
getOrCreateEntry(device) {
|
if (!this.entries.has(device.deviceId)) {
|
const payload = {};
|
|
if (this.includeDeviceIdField) {
|
payload[this.deviceIdField] = device.deviceId;
|
}
|
|
this.entries.set(device.deviceId, {
|
device,
|
payload,
|
firstSeenAt: Date.now(),
|
lastUpdateAt: 0,
|
lastRealtimeAt: 0,
|
lastBloodPressureAt: 0,
|
});
|
}
|
|
return this.entries.get(device.deviceId);
|
}
|
|
getPayload(deviceId) {
|
const entry = this.entries.get(deviceId);
|
if (!entry) {
|
return null;
|
}
|
|
return cloneObject(entry.payload);
|
}
|
|
getSnapshot(deviceId) {
|
if (deviceId) {
|
const entry = this.entries.get(deviceId);
|
if (!entry) {
|
return null;
|
}
|
|
return {
|
deviceId,
|
payload: cloneObject(entry.payload),
|
firstSeenAt: entry.firstSeenAt,
|
lastUpdateAt: entry.lastUpdateAt,
|
lastRealtimeAt: entry.lastRealtimeAt,
|
lastBloodPressureAt: entry.lastBloodPressureAt,
|
};
|
}
|
|
return Array.from(this.entries.keys()).map((key) => this.getSnapshot(key));
|
}
|
|
getSnapshotMap() {
|
const map = new Map();
|
|
for (const item of this.getSnapshot()) {
|
map.set(item.deviceId, item);
|
}
|
|
return map;
|
}
|
}
|
|
module.exports = {
|
StateCache,
|
};
|