Skip to content

Commit a1db0a1

Browse files
authored
Merge pull request #159 from QuantForgeOrg/dev
## [0.9.4] - 2026-03-11 - Color Namespace, Transpiler Overhaul, request.security & Drawing Improvements
2 parents ad26f8d + d0dab6d commit a1db0a1

75 files changed

Lines changed: 4579 additions & 406 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/badges/api-color.svg

Lines changed: 5 additions & 5 deletions
Loading

.github/badges/api-coverage.svg

Lines changed: 4 additions & 4 deletions
Loading

.github/badges/api-types.svg

Lines changed: 4 additions & 4 deletions
Loading

.github/badges/coverage.svg

Lines changed: 8 additions & 8 deletions
Loading

CHANGELOG.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
# Change Log
22

3+
## [0.9.4] - 2026-03-11 - Color Namespace, Transpiler Overhaul, request.security & Drawing Improvements
4+
5+
### Added
6+
7+
- **`color` Namespace Refactor**: Extracted the full color implementation from `Core.ts` into a dedicated `src/namespaces/color/PineColor.ts` module. Adds complete `COLOR_CONSTANTS` (all named palette colors), improved hex/rgb/rgba/`#RRGGBBAA` parsing, `color.from_gradient()` with NaN guard, and a full test suite.
8+
- **`alert()` Stub**: Added the missing `alert()` function (previously only `alertcondition` existed). Emits to the context event bus so downstream code can subscribe without crashing.
9+
- **`max_bars_back()` No-Op**: Added `max_bars_back(source, length)` as a compatibility stub. Returns its source argument unchanged (PineTS maintains full history, so there is no lookback cap to configure).
10+
- **`linefill` Instance Methods**: `LinefillObject` now exposes `get_line1()`, `get_line2()`, and `set_color()` directly on the instance, enabling UDT field-chain patterns like `myStruct.fill.set_color(c)`.
11+
- **UDT `.new()` Named Arguments**: `MyType.new(field1=val1, field2=val2)` now works correctly. The UDT constructor detects a named-argument object and maps keys to fields instead of positional assignment.
12+
- **`linefill.new` Thunking**: Added `linefill.new` to `FACTORY_METHODS` so it receives the arrow-function thunk treatment in `var` declarations, preventing orphaned linefill objects from being created on every bar.
13+
- **`math.__neq()` — Inequality Operator**: Added `math.__neq(a, b)` to handle Pine Script's `!=` / `<>` operator with proper NaN semantics (mirrors `math.__eq`).
14+
15+
### Fixed
16+
17+
#### Transpiler
18+
19+
- **For-Loop Init & Update `$.get()` Wrapping**: The for-loop init and update expressions lacked `addArrayAccess`, `MemberExpression`, and `CallExpression` handlers. Series variables appearing in loop bounds (e.g., `for i = 0 to bar_index - 1`) were left as raw Series objects, causing the update ternary to evaluate to `NaN` and producing infinite loops or bodies that never executed.
20+
- **While-Loop Test Condition**: `while bar_index > cnt` and similar conditions with Series variables were not wrapped in `$.get()`, so the comparison always evaluated against a raw Series object (→ `NaN`). Fixed by adding missing `addArrayAccess` and namespace-object skip logic to `transformWhileStatement`.
21+
- **Function-Scoped Variable Resolution**: Added `isVariableInFunctionScope()` to `ScopeManager`. `createScopedVariableReference()` now correctly resolves `var` declarations inside nested `if`/`for` blocks *within* functions to the local context (`$$`) instead of the global context (`$`).
22+
- **Optional Chaining for `na` UDT Drawing Fields**: `hasGetCallInChain()` now traverses `MemberExpression` *and* intermediate `CallExpression` nodes to detect `$.get()` in deeper chains. Inserts `?.` on the final method call so `myStruct.line?.set_x2(x)` does not crash when the field is `na`/`undefined`.
23+
- **User Function vs Method Call Disambiguation**: Added `isChainedPropertyMethod` guard — when the callee object is itself a `MemberExpression` (e.g., `myObj.x.set()`), the call is not mistakenly redirected through `$.call()` even if `set` happens to be a user-defined function name. Added `_skipTransformation = true` on function-reference identifiers inside `$.call()` to prevent them from resolving to same-named variables.
24+
- **`hasGetCallInChain()` Chain Expression Traversal**: Extended to walk through `ChainExpression` wrapper nodes (`?.` optional chains) so already-wrapped intermediate nodes are also checked when determining whether to insert optional chaining.
25+
- **`ReturnStatement` Walk-Through**: `MainTransformer`'s `ReturnStatement` handler now recurses into complex return arguments when not in function scope, preventing untransformed expressions in nested return statements.
26+
- **`parseArgsForPineParams` NaN Handling**: Fixed dynamic Pine Script signatures passing `NaN` values through the argument normalizer, which caused downstream `isNaN` checks to misidentify valid numeric `0` values.
27+
- **Await Propagation in User-Defined Functions**: Functions containing `request.security` calls (which are async internally) now correctly propagate `async`/`await` through the function declaration, preventing unresolved Promise objects from reaching callers.
28+
- **Tuple Destructuring in User Functions**: Fixed the Pine Script parser emitting single-bracket `[a, b]` returns instead of the required double-bracket `[[a, b]]` tuple form when `=>` arrow functions ended with an `if/else` that returned a tuple.
29+
- **Function Parameter Namespace Collision Renaming**: Parameters whose names collide with built-in namespaces (e.g., a parameter named `color`) were being looked up as namespace objects instead of local variables. The transpiler now renames such parameters to avoid the collision.
30+
- **ArrayExpression Function Parameter Scoping**: Function parameters used inside array literal arguments (e.g., `[output, ...]`) were incorrectly resolved to the global scope (`$.let.output`) instead of the local raw identifier (`output`). Added `isLocalSeriesVar` check in `ExpressionTransformer`.
31+
- **Switch Statement Tuple Destructuring**: IIFE array returns inside switch branches were not wrapped in the required `[[a, b, c]]` double-bracket form, causing `$.init()` to treat the tuple as a time-series and extract only the last element.
32+
- **Array/Matrix Typed Declarations**: The Pine Script parser now correctly parses `array<float>`, `matrix<int>`, and other generic typed declarations in variable declarations and function signatures. Strong-typing tests cover all primitive and object element types.
33+
34+
#### Runtime
35+
36+
- **`plotcandle` and `barcolor`**: Fixed incorrect argument mapping and color resolution in both functions. `barcolor` now correctly applies per-bar color overrides to the candlestick series, and `plotcandle` produces properly structured OHLC plot data.
37+
- **`request.security` Expression Handling**: Complex expressions passed as the `expression` argument (not just simple identifiers or plot references) now evaluate correctly in the secondary context. Also fixed user-defined method expressions being passed across context boundaries.
38+
- **`request.security_lower_tf` Pine Script Behavior**: Rewrote lower-timeframe (LTF) aggregation to match TradingView's behavior — values are collected as intra-bar arrays, and the correct array element (first vs. last vs. all) is returned depending on `lookahead` / `gaps` settings.
39+
- **Normalized Timeframes**: `timeframe.in_seconds()` and related utilities now correctly handle all non-canonical formats (`'1h'``'60'`, `'1d'``'D'`, `'1w'``'W'`) and return `NaN`/`0` when given `undefined` or an unrecognised string.
40+
- **Plot Color Change Detection**: Fixed false positives in the plot color-change detector that caused unnecessary re-renders when the color value was numerically identical but represented by different intermediate Series wrappers.
41+
- **`str.split()` Returns Pine Array**: `str.split()` was returning a plain JavaScript array. It now returns a `PineArrayObject` so array namespace methods (`.get()`, `.size()`, etc.) work on the result.
42+
- **Label Colors & Backgrounds**: Fixed `label.set_textcolor()` and `label.set_bgcolor()` not applying when called after construction, and resolved parsing inconsistencies in `parseArgsForPineParams` that treated valid color `0` as `na`.
43+
- **`color.from_gradient` NaN Guard**: Added `null`/`NaN`/`undefined` guards for all five arguments; previously a missing value produced `#NANNANNAN` hex strings.
44+
- **Improved Color Parsing**: `PineColor` now handles all Pine Script color representations uniformly: 6-digit hex, 8-digit hex (`#RRGGBBAA`), `rgb()`, `rgba()`, named constants, and `color.new()` output.
45+
- **Polyline Rendering Fixes**: Fixed `polyline.new()` crash when `points` contained `na` entries, incorrect `xloc` handling for bar-index vs. time coordinates, and missing default line/fill colors.
46+
- **Array `new_*` Capacity Handling**: `array.new<T>(size, initial)` variants now clamp the requested capacity to `MAX_ARRAY_SIZE` and correctly initialise all elements to the provided default (was previously initialising to `undefined` in some typed constructors).
47+
- **Table Cell Null Guard**: `table.cell()` now guards against `null`/`undefined` row or column indices, preventing a crash when table access patterns involve conditional creation.
48+
- **`chart.fg_color`**: Fixed `chart.fg_color` returning the wrong value (`bg_color` was returned for both properties due to a copy-paste error).
49+
- **Default Colors for Polyline and Table**: `polyline.new()` and `table.new()` no longer require explicit color arguments; sensible defaults are applied when colors are omitted or `na`.
50+
- **User Functions Treated as Native Functions**: Fixed a regression where user-defined functions registered in `settings.ts` were forwarded through the native namespace dispatcher instead of the user function call path.
51+
- **Sourcemap Generation for Browser Dev Build**: Fixed the rollup sourcemap pipeline for the `build:dev:browser` target so browser DevTools correctly resolve transpiled runtime errors to TypeScript source lines.
52+
53+
---
54+
355
## [0.9.3] - 2026-03-06 - Streaming Support, request.security Fixes, Transpiler Robustness
456

557
### Added

docs/api-coverage/color.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ parent: API Coverage
3535
| `color.from_gradient()` || Create color from gradient |
3636
| `color.new()` || Create new color |
3737
| `color.rgb()` || Create color from RGB values |
38-
| `color.b()` | | Get blue component |
39-
| `color.g()` | | Get green component |
40-
| `color.r()` | | Get red component |
41-
| `color.t()` | | Get transparency component |
38+
| `color.b()` | | Get blue component |
39+
| `color.g()` | | Get green component |
40+
| `color.r()` | | Get red component |
41+
| `color.t()` | | Get transparency component |

docs/api-coverage/pinescript-v6/color.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
"color.yellow": true
2020
},
2121
"Color Functions": {
22-
"color.b()": false,
22+
"color.b()": true,
2323
"color.from_gradient()": true,
24-
"color.g()": false,
24+
"color.g()": true,
2525
"color.new()": true,
26-
"color.r()": false,
26+
"color.r()": true,
2727
"color.rgb()": true,
28-
"color.t()": false
28+
"color.t()": true
2929
}
30-
}
30+
}

docs/api-coverage/pinescript-v6/types.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,14 @@
173173
"position.top_right": true
174174
},
175175
"scale": {
176-
"scale.left": false,
177-
"scale.none": false,
178-
"scale.right": false
176+
"scale.left": true,
177+
"scale.none": true,
178+
"scale.right": true
179179
},
180180
"settlement_as_close": {
181-
"settlement_as_close.inherit": false,
182-
"settlement_as_close.off": false,
183-
"settlement_as_close.on": false
181+
"settlement_as_close.inherit": true,
182+
"settlement_as_close.off": true,
183+
"settlement_as_close.on": true
184184
},
185185
"shape": {
186186
"shape.arrowdown": true,
@@ -209,14 +209,14 @@
209209
"splits.numerator": true
210210
},
211211
"text": {
212-
"text.align_bottom": false,
212+
"text.align_bottom": true,
213213
"text.align_center": true,
214214
"text.align_left": true,
215215
"text.align_right": true,
216-
"text.align_top": false,
217-
"text.format_bold": false,
218-
"text.format_italic": false,
219-
"text.format_none": false,
216+
"text.align_top": true,
217+
"text.format_bold": true,
218+
"text.format_italic": true,
219+
"text.format_none": true,
220220
"text.wrap_auto": true,
221221
"text.wrap_none": true
222222
},

docs/api-coverage/types.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,17 @@ parent: API Coverage
179179

180180
| Function | Status | Description |
181181
| ------------- | ------ | ----------- |
182-
| `scale.left` | | Left scale |
183-
| `scale.none` | | No scale |
184-
| `scale.right` | | Right scale |
182+
| `scale.left` | | Left scale |
183+
| `scale.none` | | No scale |
184+
| `scale.right` | | Right scale |
185185

186186
### Settlement_as_close
187187

188188
| Function | Status | Description |
189189
| ----------------------------- | ------ | --------------------------- |
190-
| `settlement_as_close.inherit` | | Inherit settlement as close |
191-
| `settlement_as_close.off` | | Settlement as close off |
192-
| `settlement_as_close.on` | | Settlement as close on |
190+
| `settlement_as_close.inherit` | | Inherit settlement as close |
191+
| `settlement_as_close.off` | | Settlement as close off |
192+
| `settlement_as_close.on` | | Settlement as close on |
193193

194194
### Shape
195195

@@ -230,14 +230,14 @@ parent: API Coverage
230230

231231
| Function | Status | Description |
232232
| -------------------- | ------ | --------------------- |
233-
| `text.align_bottom` | | Bottom text alignment |
233+
| `text.align_bottom` | | Bottom text alignment |
234234
| `text.align_center` || Center text alignment |
235235
| `text.align_left` || Left text alignment |
236236
| `text.align_right` || Right text alignment |
237-
| `text.align_top` | | Top text alignment |
238-
| `text.format_bold` | | Bold text format |
239-
| `text.format_italic` | | Italic text format |
240-
| `text.format_none` | | No text format |
237+
| `text.align_top` | | Top text alignment |
238+
| `text.format_bold` | | Bold text format |
239+
| `text.format_italic` | | Italic text format |
240+
| `text.format_none` | | No text format |
241241
| `text.wrap_auto` || Auto text wrap |
242242
| `text.wrap_none` || No text wrap |
243243

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pinets",
3-
"version": "0.9.3",
3+
"version": "0.9.4",
44
"description": "Run Pine Script anywhere. PineTS is an open-source transpiler and runtime that brings Pine Script logic to Node.js and the browser with 1:1 syntax compatibility. Reliably write, port, and run indicators or strategies on your own infrastructure.",
55
"keywords": [
66
"Pine Script",

0 commit comments

Comments
 (0)