A bump node is not possible to reproduce via component nodes. The reason for this is that a bump node doesn't just lookup the bump value of the sample being evaluated, but the bump values of adjacent samples, in order to generate a slope for the sample, which then gets translated into rotation of the normal. That hard part is, how far should those adjacent lookups be? You can't look by just shifting 1 UV pixel, because that could be a huge distance or a tiny distance, depending on distance, FOV, and on UV scale. (Not to mention filtering.) You need to figure out how far to look, and doing that requires something like screen space derivatives (which are probably used for Eevee, but Cycles probably does something different) to see how much UV changes with respect to world position.
Unfortunately, Blender does not expose screen space derivatives to its nodes. (Which is honestly too bad, because there are other cool things you can do with screen space derivatives as well.)
However, even though these can't be recreated using only Blender's nodes, there exist plenty of environments where you can play with exactly how bump mapping works. If you're interested in this kind of stuff, Unity is a great place to learn about (rasterizer) rendering, and there are plenty of public shaders available to study.
Normal mapping is a little bit different, because it doesn't require any screen space derivatives (except to determine the UV tangent, if you aren't providing that as vertex data, but Blender kindly provides you a tangent node, so you don't have to worry about that.) The basic way that it works is by rotating the normal toward or away from the tangent on the basis of + or - red, and toward or away from the binormal (a unit vector perpendicular to both the tangent and the "raw" normal) on the basis of + or - green. (What is minus green? The colors of a normal map are actually remapped unit vectors, which exist in the -1 to 1 space for all channels, remapped into the 0 to 1 space so they'll fit in typical image formats. That's why the base color of a tangent space normal map is that lilac: 0.5,0.5 red green actually maps to 0,0 x,y, and the 1.0 blue maps to 1.0 z.)
If you had a bake of UV stretch, you could do a bump procedurally, with other nodes, assuming your mesh didn't deform, which would change the UV stretch. However, the whole reason why we use tangent space normal maps is to support deforming meshes. If you were working with a mesh that didn't deform, you may as well use an object space normal map.
Object space normal maps are extremely simple-- you can just remap these to -1,1 space and vector transform from object to world.
Should be said, there's nothing to gain from recreating any of these in nodes, except understanding, and that understanding could be gained much more easily by reading shaders that implement bump mapping.