πŸ“ commands/rewind/ Β· 05_lazy_module_loading.md

Chapter 5: Lazy Module Loading

πŸ“„ commands/rewind/05_lazy_module_loading.md

Chapter 5: Lazy Module Loading

Welcome to the final chapter of our specific command tutorial!

In the previous chapters, we defined the command in the registry (Command Registry & Configuration), gave it tools (Tool Context Interface), wrote the logic (Command Execution Handler), and handled the output (Local Command Result).

We have a working command. But we have one last problem to solve: Efficiency.

1. The Motivation: Just-In-Time Delivery

Imagine you run a giant manufacturing plant. You build cars, toasters, and televisions.

You have a warehouse where you store parts.

The Use Case: Our application might have 50 different commands. The rewind command is heavyβ€”it has complex logic. If we load the code for all 50 commands when the user starts the app, the app will take 5 seconds to launch.

We want the app to launch instantly and only load the rewind code if the user actually types rewind.

2. Key Concepts

To achieve this "Just-In-Time" delivery in code, we use Lazy Module Loading.

Static vs. Dynamic Imports

Usually, imports are "Static" (Stockpiling). They sit at the top of the file:

import { heavyLogic } from './heavyFile.js'; // Loads immediately!

For Lazy Loading, we use "Dynamic" imports. This is a function that returns the code later.

const loadLater = () => import('./heavyFile.js'); // Loads only when called!

3. Implementing Lazy Loading

Let's look at our configuration file (index.ts) again. This is where we set up the "Phone Book" entry for our command.

The Load Function

We define a property called load. This is not the code itself; it is the instruction on how to get the code.

const rewind = {
  // ... name, description, etc ...

  // The Magic Switch:
  load: () => import('./rewind.js'),

} satisfies Command

Explanation:

  1. () =>: This defines a small function (an arrow function).
  2. import(...): This is a special JavaScript command. It goes to the hard drive, finds rewind.js, and reads it into memory.
  3. Crucially, this line does NOT run when the application starts. It only runs when the system executes rewind.load().

4. Under the Hood

How does the system use this? It acts like a dispatcher.

The Flow

  1. App Start: The system reads the registry (index.ts). It sees rewind exists, but it does not read rewind.js. The application starts instantly.
  2. User Action: The user types rewind.
  3. Trigger: The system looks at the registry, finds the load function, and calls it.
  4. Loading: The computer pauses for a tiny fraction of a second to read the file.
  5. Execution: The code is now available, and the system runs the call function we wrote in Command Execution Handler.

Here is a diagram showing the timeline:

sequenceDiagram participant User participant System participant Registry as Config (index.ts) participant Disk as Hard Drive User->>System: Launch App System->>Registry: "What commands exist?" Registry-->>System: "I have 'rewind', here is the loader function." Note over System, Disk: rewind.js is NOT loaded yet! App is ready. User->>System: Type "rewind" System->>Registry: "Run the loader for rewind!" Registry->>Disk: import('./rewind.js') Disk-->>System: Returns the code module System->>System: Executes command logic

Internal Implementation

If we look at the core system code (the code that manages your commands), it looks something like this:

// Inside the Command Runner Core

// 1. Identify the command
const commandConfig = registry.get('rewind');

// 2. LOAD the module (Lazy Loading)
// We use 'await' because reading from disk takes time
const module = await commandConfig.load();

// 3. The module is now loaded! 
// We can access the 'call' function from Chapter 3
await module.call(args, context);

Explanation:

5. Summary

In this final chapter, we learned about Lazy Module Loading.

Tutorial Conclusion

Congratulations! You have walked through the entire architecture of a command in the Rewind project.

Let's recap the journey:

  1. Command Registry: We created the "Menu Entry" so the system knows the command exists.
  2. Tool Context: We gave the command a "Key Ring" to access system tools.
  3. Execution Handler: We wrote the "Recipe" (logic) to perform the task.
  4. Local Command Result: We wrote the "Mission Report" to tell the system we are done.
  5. Lazy Loading: We optimized it so the code only loads when needed.

You now possess the knowledge to build efficient, powerful, and integrated commands for this system. Happy coding!


Generated by Code IQ