Hello Dan ..
You can use Context store to temporarily save the message from source 1 and when the message from source 2 arrives, do the id matching / merging of objects.
One thing i wanted to ask is whether the messages arrive in the same order.
source 1 then source 2 or could be source 2 then source 1
solutions depend on those little details
Its little difficult to suggest anything more without seeing some sample messages from the two sources.
Can you create and share a small flow with inject nodes with some of the messages?
[EDIT]
Here is a flow that uses a Join node to merge two msgs with unique topics (source1 and source2)
and if the id is the same, merge their objects
(not sure if its what you need but it may give you some ideas)
[{"id":"cab99eeaaba91bf8","type":"inject","z":"54efb553244c241f","name":"source1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"source1","payload":"{\"id\": 123, \"prop1\": 11, \"prop2\": 22}","payloadType":"json","x":440,"y":1480,"wires":[["7683e41d4af4e716"]]},{"id":"4a233a21c9de6c8e","type":"inject","z":"54efb553244c241f","name":"source2","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"source2","payload":"{\"id\": 123, \"value\" : \"myValue\"}","payloadType":"json","x":440,"y":1540,"wires":[["7683e41d4af4e716"]]},{"id":"7683e41d4af4e716","type":"join","z":"54efb553244c241f","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":650,"y":1500,"wires":[["ed5d12e0e0031e99","3ecd29a1e7f368e6"]]},{"id":"ed5d12e0e0031e99","type":"debug","z":"54efb553244c241f","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":800,"y":1420,"wires":[]},{"id":"3ecd29a1e7f368e6","type":"function","z":"54efb553244c241f","name":"merge if id the same","func":"if (msg.payload.source1.id === msg.payload.source2.id) {\nmsg.payload = { ...msg.payload.source1, ...msg.payload.source2 }\n return msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":1500,"wires":[["ef070cb5e145937f"]]},{"id":"ef070cb5e145937f","type":"debug","z":"54efb553244c241f","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1060,"y":1500,"wires":[]}]