Welcome to Chapter 5!
In the previous chapter, Service Layer Delegation, we built the "Technician" (the Service) that actually writes the file to the disk. It hands the result back to the "Manager" (the Handler).
Now, the Manager holds the result. But how do we give it to the user? Do we just console.log it? What if we want the text to be red if it fails? What if we want to save the output to a log file instead of the screen?
In this chapter, we will learn about the Standardized Output Protocol.
Imagine a massive cargo ship.
Our heapdump command has finished running. It has a file path to show the user.
Instead of printing it directly to the screen, we want to package it in a "container" so the main application (the CLI Runner) can decide how to handle it. This makes our command reusable and keeps the display logic consistent across the entire app.
The "Standardized Output Protocol" is just a fancy way of saying: "All commands must return a JavaScript object that looks like this:"
// The "Container" format
type CommandResult = {
type: 'text' | 'json' | 'table'; // What kind of data is inside?
value: any; // The actual data
}
By using this format, the main application never has to guess what it received.
When you write console.log("Hello"), you are mixing Data ("Hello") with Display (Printing to screen).
In our system, we want to separate them.
Let's look at how our heapdump command uses this protocol. We are looking at the final return statements in heapdump.ts.
When everything goes right, we don't print the path. We wrap it in an object.
// Inside heapdump.ts (The Handler)
return {
type: 'text', // Label the box
// The content of the box
value: `Heap dump created at: ${result.heapPath}`,
}
Explanation:
type: 'text': We tell the system, "I am sending you a plain string."value: This is the actual message we want the user to eventually see.Even if the command fails, we still return a valid container! We don't crash the app; we just send a container filled with an error message.
// Inside heapdump.ts (The Handler)
if (!result.success) {
return {
type: 'text',
// The error message acts as the value
value: `Error: Failed to create dump. ${result.error}`,
}
}
Explanation:
{ type, value }) is identical. The main app doesn't need special logic to handle the return value.What happens to this object after our command returns it?
The main application (the CLI Runner) receives this object and acts as the "Crane Operator." It inspects the type and decides how to display the value.
Let's look at a simplified version of the code in the main application that processes your result. This code runs after your command finishes.
// Simplified CLI Runner
async function runCommand() {
// 1. Run your command (Chapter 3)
const result = await command.call()
// 2. Open the container (The Protocol)
if (result.type === 'text') {
// Standard text? Just print it.
console.log(result.value)
}
// ... checks for other types
}
Explanation:
CLI Runner), and every single command in our system would update instantly.In this chapter, we learned about the Standardized Output Protocol.
We learned:
{ type, value }) makes the system predictable.Congratulations! You have completed the heapdump project tutorial.
You have built a fully functional system architecture:
You now possess the foundational knowledge to build scalable, high-performance CLI tools. Happy coding!
Generated by Code IQ