( rawPackets: RawDataPacket[] = [], timelineStartTime: number | null, totalDuration: number, )
| 209 | }; |
| 210 | |
| 211 | const normalizeDataPackets = ( |
| 212 | rawPackets: RawDataPacket[] = [], |
| 213 | timelineStartTime: number | null, |
| 214 | totalDuration: number, |
| 215 | ): DataPacket[] => { |
| 216 | if (!rawPackets.length) { |
| 217 | return []; |
| 218 | } |
| 219 | |
| 220 | return rawPackets |
| 221 | .filter( |
| 222 | ( |
| 223 | packet, |
| 224 | ): packet is RawDataPacket & { |
| 225 | id: string; |
| 226 | sourceNode: string; |
| 227 | targetNode: string; |
| 228 | timestamp: string; |
| 229 | } => { |
| 230 | return Boolean(packet.id && packet.sourceNode && packet.targetNode && packet.timestamp); |
| 231 | }, |
| 232 | ) |
| 233 | .map((packet) => { |
| 234 | const packetTimestamp = new Date(packet.timestamp).getTime(); |
| 235 | const baseStart = timelineStartTime ?? packetTimestamp; |
| 236 | const computedTotal = |
| 237 | totalDuration > 0 ? totalDuration : Math.max(packetTimestamp - baseStart, 1); |
| 238 | |
| 239 | const visualTime = |
| 240 | typeof packet.visualTime === 'number' |
| 241 | ? packet.visualTime |
| 242 | : computedTotal > 0 |
| 243 | ? Math.max(0, Math.min(1, (packetTimestamp - baseStart) / computedTotal)) |
| 244 | : 0; |
| 245 | |
| 246 | return { |
| 247 | id: packet.id, |
| 248 | sourceNode: packet.sourceNode, |
| 249 | targetNode: packet.targetNode, |
| 250 | inputKey: packet.inputKey, |
| 251 | payload: packet.payload, |
| 252 | timestamp: packetTimestamp, |
| 253 | size: typeof packet.size === 'number' ? packet.size : Number(packet.size ?? 0), |
| 254 | type: (packet.type as DataPacket['type']) ?? 'json', |
| 255 | visualTime, |
| 256 | }; |
| 257 | }); |
| 258 | }; |
| 259 | |
| 260 | const calculateNodeStates = ( |
| 261 | events: TimelineEvent[], |
no outgoing calls
no test coverage detected