How the beforeTransform Phase Interacts with Transformer Plugins in PicList-Core

The beforeTransform phase executes built-in preprocessing plugins such as compress and watermark before any user-installed transformer plugins run, ensuring image modifications are applied to the buffer prior to transformation.

PicList-Core orchestrates image uploads through a strict lifecycle pipeline defined in src/core/Lifecycle.ts. The beforeTransform phase serves as a critical preprocessing stage that executes built-in plugins immediately before the transformer phase handles user-defined transformations. This architecture ensures that operations like compression and watermarking modify the image buffer before base64 encoding or path manipulation occurs.

Lifecycle Architecture and Plugin Registration

All plugins in PicList-Core are managed by the LifecyclePlugins container defined in src/lib/LifecyclePlugins.ts. This class maintains a registry of plugins and tracks the current execution phase through the setCurrentPluginName method. When the upload process begins, the lifecycle orchestrator initializes the plugin chain and prepares the context object that carries the image buffer through each phase.

The LifecyclePlugins Container

The LifecyclePlugins class provides the register method to add plugins and uses setCurrentPluginName to identify which phase is currently active. During the beforeTransform phase, the orchestrator sets the current name to 'beforeTransform', signaling that only plugins registered under this namespace should execute.

Executing the beforeTransform Phase

The core lifecycle logic resides in src/core/Lifecycle.ts. When the pipeline reaches the preprocessing stage, the code executes:

// src/core/Lifecycle.ts
setCurrentPluginName('beforeTransform');
await this.runPlugins('beforeTransform');
setCurrentPluginName(null);

The runPlugins method iterates over all plugins whose identifiers match the current phase. For beforeTransform, this includes built-in plugins registered as beforeTransform:compress, beforeTransform:watermark, and beforeTransform:skipProcess. Each plugin receives the image buffer through its handle(ctx, ...args) method and returns the modified buffer for the next plugin in the chain.

Built-in Before-Transformer Plugins

PicList-Core ships with three primary built-in plugins located in src/plugins/beforetransformer/:

  • compress (compress.ts): Handles image compression, format conversion, and resizing based on buildIn.compress configuration.
  • watermark (watermark.ts): Applies text or image watermarks using settings stored under buildIn.watermark.
  • skipProcess (skipProcess.ts): Conditionally bypasses further processing based on user-defined rules in buildIn.skipProcess.

Registration via the Build-in Module System

These plugins are registered through the CLI setting command defined in src/plugins/commander/setting.ts. The BUILDIN_MODULES constant maps module names to their configuration handlers:

// src/plugins/commander/setting.ts
const BUILDIN_MODULES = {
  compress:    { config: compress.config,   key: 'BUILDIN_COMPRESS' },
  watermark:   { config: watermark.config,  key: 'BUILDIN_WATERMARK' },
  rename:      { config: rename.config,     key: 'BUILDIN_RENAME' },
  skipProcess: { config: skipProcess.config,key: 'BUILDIN_SKIPPROCESS' }
} as const;

When users run picgo set buildin compress, the configuration is persisted and subsequently loaded during the beforeTransform phase.

Handoff to the Transformer Phase

After the beforeTransform phase completes, the lifecycle transitions to the transformer phase:

setCurrentPluginName('transformer');
await this.runPlugins('transformer');
setCurrentPluginName(null);

This phase loads user-installed transformer plugins such as base64 (src/plugins/transformer/base64.ts) and path (src/plugins/transformer/path.ts). Crucially, these transformers receive the already-modified image buffer from the beforeTransform phase. If compression reduced the file size or watermarking altered the pixels, those changes persist into the transformation stage.

Practical Configuration Example

To enable compression before transformation, configure the built-in plugin via CLI:


# Enable compression with quality 80

picgo set buildin compress

# Upload triggers the full lifecycle

picgo upload ./image.png

Execution flow:

  1. The setting.ts handler writes buildIn.compress configuration.
  2. Lifecycle.ts enters beforeTransform and executes the compress plugin.
  3. The compressed buffer passes to the transformer phase (e.g., base64 encoding).
  4. The final buffer proceeds to the uploader.

Summary

  • The beforeTransform phase executes in src/core/Lifecycle.ts before any user transformers run.
  • Built-in plugins (compress, watermark, skipProcess) are registered via src/plugins/commander/setting.ts and stored in src/lib/LifecyclePlugins.ts.
  • The setCurrentPluginName('beforeTransform') method isolates this phase's execution context.
  • Image buffers modified during beforeTransform are automatically passed to the transformer phase plugins (base64, path).
  • Configuration occurs through the buildIn namespace using picgo set buildin <module>.

Frequently Asked Questions

What is the exact execution order of phases in PicList-Core?

The lifecycle follows this strict sequence: beforeUpload (file preparation), beforeTransform (built-in preprocessing), transformer (user-defined transformations), afterTransform (post-processing), and finally uploader (remote transfer). This ordering ensures that built-in optimizations occur before any format conversions.

How do I disable the beforeTransform phase for specific uploads?

You can use the skipProcess built-in plugin to conditionally bypass processing. Configure it via picgo set buildin skipProcess with rules that match your specific file patterns or conditions, allowing certain uploads to skip compression or watermarking while still proceeding to the transformer phase.

Can I create custom plugins for the beforeTransform phase?

Yes. While PicList-Core primarily uses beforeTransform for built-in modules, the plugin architecture in src/lib/LifecyclePlugins.ts supports registering custom plugins under the beforeTransform namespace. Your plugin must implement a handle method that accepts the context object and returns the modified buffer, following the same pattern as compress.ts.

Why does my transformer plugin receive already-compressed images?

This is by design. The beforeTransform phase deliberately runs before the transformer phase to ensure that preprocessing optimizations like compression are applied early in the pipeline. If you need uncompressed data in your transformer, you must either disable the compress plugin or implement your transformation logic in the beforeUpload phase instead.

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 →