How Generated Images Are Stored and Managed Within Prompt-Optimizer

Prompt-optimizer stores generated images as base64 blobs in a centralized ImageStorageService, while UI session stores retain only lightweight ImageRef identifiers to separate binary data from application state.

Managing generated images efficiently is critical for AI-powered applications handling large binary payloads. In the linshenkx/prompt-optimizer repository, the architecture decouples raw image data from UI state through a dedicated storage abstraction and automated garbage collection. This article examines how the codebase handles image persistence, reference management, and memory optimization based on the actual TypeScript implementation.

Core Storage Architecture

The system employs a service-oriented design that isolates image handling from business logic through a clear interface-implementation separation.

The IImageStorageService Interface

The contract for image operations is defined in [packages/core/src/services/image/types.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/core/src/services/image/types.ts). This interface exposes methods to store, retrieve, and configure image data, ensuring the UI layers depend on abstractions rather than concrete implementations. The interface returns an ImageResult object containing an ImageRef—a unique identifier—rather than the raw binary data.

In-Memory Implementation with ImageStorageService

The concrete implementation resides in [packages/core/src/services/image/storage.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/core/src/services/image/storage.ts). The ImageStorageService class maintains a configurable in-memory map of image references. When store() is invoked, the service extracts the base64 payload from the input, writes it to the internal store, and returns a lightweight ImageResult containing only the ImageRef. This approach keeps session state small while the heavy binary data remains isolated in the service layer.

Session-Level Integration

UI components interact with images indirectly through session stores that manage references rather than blobs.

Reference-Based State Management

Both text-to-image and image-to-image modes use dedicated session stores—useImageText2ImageSession and useImageImage2ImageSession—defined in [packages/ui/src/stores/session/useImageText2ImageSession.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/ui/src/stores/session/useImageText2ImageSession.ts) and [packages/ui/src/stores/session/useImageImage2ImageSession.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/ui/src/stores/session/useImageImage2ImageSession.ts). These stores persist only the ImageRef returned by queueImageStorageMaintenance, delegating the actual binary storage to the ImageStorageService. On restore, the session resolves the stored reference back to the full base64 image via imageStorage.get(ref), throwing a clear error if the service is unavailable.

Factory Initialization

Service instantiation is handled by createImageStorageService, a factory function exported at line 453 of [packages/core/src/services/image/storage.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/core/src/services/image/storage.ts#L453). This helper simplifies construction with optional configuration overrides for maxSize and ttlMs, allowing customization of storage limits without modifying core logic.

Image Lifecycle and Garbage Collection

To prevent unbounded memory growth, prompt-optimizer implements automated maintenance routines.

Automated Cleanup Configuration

The scheduleImageStorageGc routine, defined in [packages/ui/src/stores/session/imageStorageMaintenance.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/ui/src/stores/session/imageStorageMaintenance.ts), provides garbage collection for stale images. The initializer useAppInitializer in [packages/ui/src/composables/system/useAppInitializer.ts](https://github.com/linshenkx/prompt-optimizer/blob/develop/packages/ui/src/composables/system/useAppInitializer.ts) creates the service instance and wires the GC schedule during application bootstrap, ensuring orphaned images are purged according to the configured time-to-live.

Practical Implementation Example

The following pattern demonstrates the complete workflow from service creation to session persistence:

// 1️⃣ Create the storage service (usually done at app start)
import { createImageStorageService } from '@prompt-optimizer/core';
const imageStorage = createImageStorageService({
  maxSize: 500,                 // maximum number of images to keep
  ttlMs: 24 * 60 * 60 * 1000,  // time-to-live for each image
});

// 2️⃣ Store a generated image (base64 string) and get a reference
const base64Img = 'data:image/png;base64,iVBORw0KGgoAAA...';
const imageResult = await imageStorage.store(base64Img);
const ref = imageResult.ref; // e.g. "img-12345"

// 3️⃣ Retrieve the image later via the reference
const retrieved = await imageStorage.get(ref);
console.log(retrieved.base64); // same base64 payload

// 4️⃣ Hook the service into a session store (simplified)
import { useImageText2ImageSession } from '@/stores/session/useImageText2ImageSession';
const session = useImageText2ImageSession(pinia);
session.updateOriginalImageResult(imageResult); // saves only the ref
await session.saveSession(); // internally calls the storage service

Summary

  • Centralized storage: The ImageStorageService in packages/core/src/services/image/storage.ts manages all base64 image data in a dedicated in-memory map.
  • Reference-based architecture: Session stores in packages/ui/src/stores/session/ persist only ImageRef identifiers, keeping UI state lightweight and serializable.
  • Configurable limits: The createImageStorageService factory accepts maxSize and ttlMs parameters to control memory usage.
  • Automated maintenance: The scheduleImageStorageGc routine handles garbage collection, initialized via useAppInitializer to prevent memory leaks.

Frequently Asked Questions

Where does prompt-optimizer store generated images?

Generated images are stored as base64 strings in the ImageStorageService, an in-memory singleton defined in packages/core/src/services/image/storage.ts. The service maintains an internal map that associates unique ImageRef identifiers with the actual binary payloads, keeping the raw data isolated from Vuex/Pinia state stores.

How does the session store avoid memory bloat?

Session stores for text-to-image and image-to-image modes (useImageText2ImageSession and useImageImage2ImageSession) persist only the ImageRef string returned by imageStorage.store(). When the full image data is needed, the store calls imageStorage.get(ref) to retrieve the base64 payload, ensuring that large binary objects never enter the serialized session state.

What triggers image cleanup in prompt-optimizer?

The scheduleImageStorageGc function in packages/ui/src/stores/session/imageStorageMaintenance.ts triggers cleanup based on the ttlMs (time-to-live) configuration passed to createImageStorageService. The garbage collector runs automatically when the application initializes through useAppInitializer, removing expired entries to maintain the maxSize limit.

Can I configure the image storage limits?

Yes. When creating the service via createImageStorageService (exported at line 453 of packages/core/src/services/image/storage.ts), you can specify maxSize (maximum image count) and ttlMs (expiration time in milliseconds). These settings control how long images persist in memory and how many concurrent blobs the service retains before automatic eviction occurs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →