Welcome to the final chapter of the outputStyles tutorial!
In the previous chapter, Metadata Parsing and Coercion, we learned how the system acts like a "Smart Clerk" to clean up messy user input.
However, being a Smart Clerk takes time. Reading files from the hard drive, parsing text, and coercing types is "expensive" in terms of computer performance. If we do this every single time the user presses a button, the application will feel sluggish.
In this chapter, we explore Cache Management. This acts as the "Short-Term Memory" of our application, allowing it to run instantly after the first load.
Imagine a busy restaurant. You are the customer (the User), and the application is the Waiter.
Without Caching:
With Caching:
There is one catch: What if the Chef changes the menu at noon? If the Waiter relies only on memory, they will give you the wrong information. We need a way to tell the Waiter: "Forget what you know, go check the kitchen again."
Imagine a user interacting with the AI. They send 10 messages in 1 minute.
Each time a message is sent, the system needs to know which Output Style to use (e.g., "Pirate Mode").
pirate.md file from the hard drive. (Slow: 50ms)pirate.md. (Fast: 0ms)pirate.md. (Fast: 0ms)This "remembering" is what we call Cache Management.
In programming, we use a technique called Memoization.
Memoization wraps a function. It says: "If I have seen these inputs before, I will return the answer I calculated last time. I will not do the work again."
We use a helper library called lodash to do this for us.
Here is what happens when the application runs.
Let's look at loadOutputStylesDir.ts. We don't write complex caching logic ourselves; we wrap our main function in memoize.
We import the tool that gives our function a memory.
// Inside loadOutputStylesDir.ts
import memoize from 'lodash-es/memoize.js'
Normally, we would just write export const getStyles = async () => { ... }. Instead, we wrap it.
// We assign the result of 'memoize' to our variable
export const getOutputStyleDirStyles = memoize(
// This is the actual worker function
async (cwd: string): Promise<OutputStyleConfig[]> => {
// ... logic to read files (from Chapter 3) ...
// ... logic to parse metadata (from Chapter 4) ...
return styles
}
)
Explanation: Now, getOutputStyleDirStyles is a "smart" function. If you call it with the same cwd (Current Working Directory), it skips the code inside and returns the previous result.
We have solved the speed problem. Now we must solve the Stale Data problem.
If the user edits pirate.md to make the pirate sound friendlier, the application won't know because it is still looking at its memory.
We need a "Flush" button. This function wipes the memory clean.
We export a simple function called clearOutputStyleCaches.
// Inside loadOutputStylesDir.ts
export function clearOutputStyleCaches(): void {
// 1. Clear the main style list cache
getOutputStyleDirStyles.cache?.clear?.()
// 2. Clear the low-level file reader cache
loadMarkdownFilesForSubdir.cache?.clear?.()
// 3. Clear plugin caches (if any)
clearPluginOutputStyleCache()
}
Explanation:
.cache property that memoize added to our function..clear().
The application watches files. When you save a file in your editor (Ctrl+S), the application detects the change and automatically runs clearOutputStyleCaches().
In this chapter, we learned about Cache Management.
Congratulations! You have completed the outputStyles tutorial. You now understand the full lifecycle of an AI personality in this system:
You are now ready to create your own Output Styles and customize the AI to your heart's content!
Generated by Code IQ