want to capture all the transactions propagated over the main network and detect if a new block mined. I don't want to become a full-node or spv-node. Technically, I know this is exactly the way all the full/spv nodes do every now and then. However, I could not found a good reference to teach me how.
Clearly, full nodes and SPV nodes must get their information from somewhere. And that somewhere is simply other nodes on the P2P network.
The P2P protocol is what nodes use to communicate with each other. There is some documentation on https://developer.bitcoin.org/devguide/p2p_network.html, some older but more detailed documentation on https://en.bitcoin.it/wiki/Protocol_documentation). Modern changes to it are proposed as BIPs (https://github.com/bitcoin/bips), which are usually backward compatible changes, only used between clients that support it.
Specifically, transactions are relayed by first announcing their hash using an "inv" message. The receiver then chooses which peer to fetch the full transaction data from, and sends a "getdata' message. The selected peer then responds with a "tx" message. There are other mechanisms available such as the old (and largely abandoned) BIP37 transaction filtering, and the newer BIP157 client-side filtering.
For blocks, it is a bit more complicated. The sequence there is first requesting block information using "getblocks", then responding with "inv"s for the blocks, "getdata" to request the full data, and "block" for the full blocks themselves. BIP152 compact blocks provides a far more efficient mechanism that allows the receiver to avoid receiving transactions in blocks they already have. BIP130 sendheaders enables an alternative where blocks are announced using "header" messages instead of "inv" messages.
So what distinguishes a full node from an SPV node or other nodes? The level of validation they perform. A full node will fully validate all blocks and transactions it receives. If you don't want to do that, just don't - if you're ok with trusting whomever you're connecting to. You can implement the P2P protocol yourself, or use existing implementations (there exist ones in many languages), connect to whatever peers you like, and if you do it right they'll start giving you a stream of blocks and transactions.