All notable changes to this project will be documented in this file.
//@jsdirective now also suppresses arithmetic operator transformation (+,-,*,/,%) on the annotated line, in addition to the already-guarded comparison, logical, and unary operators. Previously,aa/2on a//@js-annotated line would still be transformed toaa.div(2), causing a runtime error whenaaheld a plain JS value (e.g. result ofMath.floor).
containsTSLOperationandshouldTransformToTSLnow receivescopeandpureVars, fixing incorrect TSL transformations of comparison/logical operators involving pure-numeric variables
- Auto-import TSL types: Plugin now automatically adds missing imports for
float,int, andLoopwhen transformations use them- Prevents runtime errors like
THREE.TSL: ReferenceError: float is not defined - Adds to existing
three/tslorthree/webgpuimports when present - Creates new import statement if no TSL import exists
- Prevents runtime errors like
- New plugin options:
autoImportMissingTSL(default:true) - Enable/disable automatic import injectionimportSource(default:'three/tsl') - Specify the import source for new imports
// Input (no float import)
import { Fn, uv } from 'three/tsl'
Fn(() => {
const coord = 1 - uv()
return coord
})
// Output (float automatically added)
import { Fn, uv, float } from 'three/tsl'
Fn(() => {
const coord = float(1).sub(uv())
return coord
})- Pure numeric expressions involving variables now stay untransformed (e.g.,
const radius = 0.08; radius * 0.5stays as-is instead of becomingfloat(radius).mul(0.5)) - Variables initialized with numeric literals are now recognized as pure numeric values throughout the Fn() scope
- Extended
isPureNumeric()to track variable bindings and detect pure numeric identifiers - Test cases for pure numeric variable detection (tests 208-215)
- Browser runtime tests use operator syntax (non-TSL) to validate plugin transforms in WebGL/WebGPU runs.
- Vitest projects now apply the plugin directly with
logs: true, making transform diffs visible in test output.
- Plugin now handles file ids with query/hash suffixes (e.g.
?v=) to ensure transforms run in Vite/Vitest browser builds.
- TSL Loop transformation:
for,while, anddo...whileloops marked with//@tslnow transform to TSLLoop()constructs- For loops:
for (let i = 0; i < 10; i++)→Loop({ start, end, type, condition, name }, ({ i }) => {}) - While loops:
while (x < 10)→Loop(x.lessThan(10), () => {}) - Do-while loops: Transform to IIFE + Loop pattern
- Automatic
int/floattype inference based on loop values
- For loops:
- Transformation speed improved by ~30%
- Switch statement support: operators inside
switchcases are now transformed (e.g.,finalColor *= pattern→finalColor.mulAssign(pattern))
- File-specific logging:
logsoption now accepts string, array, or regex to filter which files log transformations
- Comparison & Logical operators:
>,<,>=,<=,==,===,!=,!==,&&,||,!now map to TSL methods (e.g.a > b→a.greaterThan(b),a && b→a.and(b)). - Context-aware transformation: Operators transform only in TSL contexts (
return,select,If/ElseIf,mix), preserving standard JS control flow (if,for). - Directive control:
//@tsland//@jscomments to force or disable transformation on lines or functions. - Expanded test suite (102 → 216 tests).
- Correct transformation for
mix()(3rd arg) and chained.ElseIf()calls. for/whileloop bodies are now properly transformed.
- Plugin now correctly returns transformed output when
logs: false
- Regression tests for
logs: falsetransformation behavior
- Multiline code without arithmetic operators is no longer unnecessarily reformatted
- Plugin now returns
nullwhen no transformation is needed, preventing misleading log output - Arrays, objects, function calls, and other expressions without operators preserve their original formatting
- Expression handlers now return original AST nodes when no transformation occurred, avoiding Babel regeneration artifacts
- Pure numeric
(x * y) % zexpressions in function calls are now preserved (e.g.,vec3((1 * 2) % 3)stays unchanged) - Standalone numeric literals in arrays, objects, and ternary expressions are no longer wrapped in
float()(e.g.,[1, 2, 3]stays as-is,cond ? 1 : 2stays as-is)
- Test cases for numeric literals in arrays, objects, and ternary expressions
- Pure numeric expressions inside function calls are now preserved (e.g.,
vec3(1.0 / 3.0)stays as-is instead of becomingvec3(float(1.0).div(3.0))) - Negative numeric literals inside
mat3/vec3calls are now preserved (e.g.,mat3(1.0, -0.5, 0.3)stays as-is instead of wrapping negatives infloat())
- Test cases for pure numeric expressions in function calls
- Test cases for multiline
mat3with negative numbers
- exclude unecessary file from npm
- Fixed incorrect transformation of template literal expressions - simple variables like
incin template literals are now preserved without wrapping infloat() - Template literals like
`lms${inc}`now correctly remain as-is instead of becoming`lms${float(inc)}`
- Added comprehensive test cases for template literal transformations
- Added early return optimization if code doesn't include "Fn(" to improve performance
- Updated test suite to account for early return behavior
- Support for if/else statement transformations
- Support for TSL's If/Else constructs
- Comprehensive test coverage for conditional statements
For changes in earlier versions, please refer to the git commit history.