Compiler Transform Pipeline
Relevant source files
The following files were used as context for generating this wiki page:
- modules/svelte-effect-runtime/src/compiler.ts
- modules/svelte-effect-runtime/src/compiler/source-scan.ts
- modules/svelte-effect-runtime/src/runtime/transform.ts
- modules/svelte-effect-runtime/src/script-transform/index.ts
- modules/svelte-effect-runtime/src/markup/transform/index.ts
- modules/svelte-effect-runtime/src/markup/transform/scan.ts
The Compiler Transform Pipeline is a multi-stage system designed to lower Svelte Effect Runtime (SER) specific syntax—primarily the yield* operator—into standard Svelte-compatible JavaScript and markup. This process allows developers to use effectful, generator-based logic directly within Svelte components while maintaining compatibility with Svelte's reactivity and rendering engine.
The pipeline operates as a pre-processor within the Vite build flow, executing before the standard Svelte compiler. It identifies special <script effect> blocks and yield* expressions in HTML markup, transforming them into a series of reactive $state bindings and dispatcher-managed fibers.
Sources: modules/svelte-effect-runtime/src/compiler.ts:98-129, modules/svelte-effect-runtime/src/runtime/transform.ts:50-84
High-Level Pipeline Architecture
The pipeline is orchestrated primarily by the effect Vite plugin, which injects several sub-plugins into the build process. The core logic resides in transform_svelte_effect, which coordinates lexical scanning, script transformation, and markup transformation.
Execution Flow
The transformation follows a strict sequence to ensure that dependencies between scripts and markup are handled correctly:
This diagram shows the sequential nature of the component transformation, starting from lexical scanning through script and markup lowering.
Sources: modules/svelte-effect-runtime/src/runtime/transform.ts:50-84, modules/svelte-effect-runtime/src/compiler.ts:55-61
Source Scanning
The pipeline begins with scan_svelte_effect_source, which performs a fast lexical scan of the component. This stage identifies script regions, style tags, HTML comments, and markup brace expressions without performing a full AST parse of the entire file.
| Feature | Description |
|---|---|
| Script Regions | Identifies <script> and <script effect> blocks, parsing their attributes (lang, effect, context). |
| Markup Expressions | Locates all {...} braces while excluding those found in scripts, styles, or comments. |
| Excluded Ranges | Tracks areas where markup transformation should not occur, such as inside <style> or comments. |
| Bare Const Tags | Specifically detects {const ...} tags that may need normalization in editor views. |
Sources: modules/svelte-effect-runtime/src/compiler/source-scan.ts:133-162, modules/svelte-effect-runtime/src/compiler/source-scan.ts:183-207
Script Transformation
When a <script effect> block is detected, the transform_script_effect function handles the lowering of top-level yield* expressions. This process is divided into four distinct phases.
Transformation Phases
- Import Detection: Scans for existing imports of
Effect,get_dispatcher, anduntrackto avoid redundant injections. - Statement Lowering: Iterates through top-level statements. If a statement contains
yield*, it is rewritten into a reactive binding. For example,let x = yield* effect;might be transformed into a$statedeclaration updated by a runtime fiber. - Import Injection: Appends required runtime imports (e.g.,
Effect,get_dispatcher) after the last user-defined import. - Runtime Program Append: Appends the generated lifecycle wiring and the
__SER___programwhich manages the execution of the effectful statements.
The sequence of internal phases within the script transformation logic.
Sources: modules/svelte-effect-runtime/src/script-transform/index.ts:52-171
Markup Transformation
The markup transform handles yield* expressions within Svelte braces (e.g., {#each yield* ...}, {yield* ...}). Unlike the script transform, this requires a "sanitize-then-classify" approach because yield* is not valid syntax for the standard Svelte parser.
Sanitization and Classification
- Sanitization: The pipeline first identifies
yield*expressions and replaces them with unique placeholders (e.g.,__SER___markup_placeholder_0). This results in a "clean" Svelte file that the Svelte compiler can parse. - AST Parsing: The sanitized code is parsed using
svelte/compiler. - Classification: The placeholders are matched against the Svelte AST to determine their context (e.g., is it in an
#eachblock, anonclickhandler, or a plain expression?). - Replacement Emission: Based on the classification, the placeholders are replaced with calls to the dispatcher (e.g.,
dispatcher.value(...)ordispatcher.run(...)).
Supported Markup Contexts
| Context | Tag Kind | Resulting Logic |
|---|---|---|
| Plain Expression | plain | Transformed into a dispatcher-tracked value. |
| Each Block | each | Lowers the iterable expression into a reactive effect. |
| Await Block | await | Lowers the promise expression. |
| Event Handler | event | Transforms onclick={yield* save()} into a dispatcher-managed execution. |
| Render Tag | render | Handles effectful snippets and render tags. |
Sources: modules/svelte-effect-runtime/src/markup/transform/index.ts:39-95, modules/svelte-effect-runtime/src/markup/transform/scan.ts:47-152
Vite Integration and Diagnostics
The effect() plugin integrates these transforms into the Vite pipeline. It also includes a diagnostics layer that warns users about invalid usage or reserved name conflicts.
Reserved Name Protection
The pipeline monitors for the use of reserved names like Dispatcher or Code within components. If these are found in a component using SER syntax, a warning is issued to prevent collisions with generated helper code.
Diagnostics Plugin
The make_diagnostics_plugin hook runs find_svelte_effect_diagnostics during the Vite transform phase. It reports errors such as yield* usage inside class members or forbidden await expressions within effect blocks.
Sources: modules/svelte-effect-runtime/src/compiler.ts:66-105, modules/svelte-effect-runtime/src/compiler.ts:121-140
Conclusion
The Compiler Transform Pipeline serves as the bridge between Effect-based programming and Svelte's reactive system. By leveraging a multi-stage approach—lexical scanning, script lowering via TypeScript AST, and markup sanitization via Svelte AST—it provides a seamless developer experience for handling complex asynchronous effects directly within component source files. This architecture ensures that the final output is valid Svelte code that correctly manages fiber lifecycles and reactive updates.