@hoox-sh/pynets 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoox-sh/pynets",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "author": "jango_blockchained",
package/src/cli/rich.ts CHANGED
@@ -12,7 +12,7 @@ const MUTED = [203, 204, 189] as const;
12
12
  const FAIL = [231, 0, 11] as const;
13
13
  const WARN = [235, 169, 65] as const;
14
14
 
15
- export const VERSION = "0.4.0";
15
+ export const VERSION = "0.6.0";
16
16
 
17
17
  type Rgb = readonly [number, number, number];
18
18
 
@@ -73,6 +73,10 @@ export default class PinescriptLexerBase extends Lexer {
73
73
  private _lastPendingTokenType = 0;
74
74
  private _lastPendingTokenTypeFromDefaultChannel = 0;
75
75
  private _numOpens = 0;
76
+ // Open square brackets (history-refs / tuples). Tracked separately from
77
+ // parens so wrapped `[...]` allows any indentation, like `(...)`.
78
+ // Python `PinescriptLexerBase._numSqBrackets` SoT (Sept 2026 release notes).
79
+ private _numSqBrackets = 0;
76
80
  private _indentLengthStack: number[] = [];
77
81
  private _inputStarted = false;
78
82
 
@@ -129,6 +133,7 @@ export default class PinescriptLexerBase extends Lexer {
129
133
  this._lastPendingTokenType = 0;
130
134
  this._lastPendingTokenTypeFromDefaultChannel = 0;
131
135
  this._numOpens = 0;
136
+ this._numSqBrackets = 0;
132
137
  this._indentLengthStack = [];
133
138
  this._inputStarted = false;
134
139
  }
@@ -147,11 +152,17 @@ export default class PinescriptLexerBase extends Lexer {
147
152
  const tok = this._currentToken!;
148
153
  const tokType = tok.type;
149
154
  const C = this.C;
150
- if (tokType === C.LPAR || tokType === C.LSQB) {
155
+ if (tokType === C.LPAR) {
151
156
  this._numOpens += 1;
152
157
  this._addPendingToken(tok);
153
- } else if (tokType === C.RPAR || tokType === C.RSQB) {
154
- this._numOpens -= 1;
158
+ } else if (tokType === C.LSQB) {
159
+ this._numSqBrackets += 1;
160
+ this._addPendingToken(tok);
161
+ } else if (tokType === C.RPAR) {
162
+ this._numOpens = Math.max(0, this._numOpens - 1);
163
+ this._addPendingToken(tok);
164
+ } else if (tokType === C.RSQB) {
165
+ this._numSqBrackets = Math.max(0, this._numSqBrackets - 1);
155
166
  this._addPendingToken(tok);
156
167
  } else if (tokType === C.NEWLINE) {
157
168
  this._handleNEWLINEToken();
@@ -264,7 +275,14 @@ export default class PinescriptLexerBase extends Lexer {
264
275
  }
265
276
 
266
277
  private _handleNEWLINEToken(): void {
267
- if (this._numOpens > 0 || this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)) {
278
+ // Newlines inside (...) or [...] are hidden (Python parity): wrapped
279
+ // history-refs / tuples may use any indentation without emitting
280
+ // INDENT/DEDENT mid-expression.
281
+ if (
282
+ this._numOpens > 0 ||
283
+ this._numSqBrackets > 0 ||
284
+ this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)
285
+ ) {
268
286
  this._hideAndAddPendingToken(this._currentToken!);
269
287
  return;
270
288
  }
@@ -73,6 +73,10 @@ export default class PinescriptLexerBase extends Lexer {
73
73
  private _lastPendingTokenType = 0;
74
74
  private _lastPendingTokenTypeFromDefaultChannel = 0;
75
75
  private _numOpens = 0;
76
+ // Open square brackets (history-refs / tuples). Tracked separately from
77
+ // parens so wrapped `[...]` allows any indentation, like `(...)`.
78
+ // Python `PinescriptLexerBase._numSqBrackets` SoT (Sept 2026 release notes).
79
+ private _numSqBrackets = 0;
76
80
  private _indentLengthStack: number[] = [];
77
81
  private _inputStarted = false;
78
82
 
@@ -129,6 +133,7 @@ export default class PinescriptLexerBase extends Lexer {
129
133
  this._lastPendingTokenType = 0;
130
134
  this._lastPendingTokenTypeFromDefaultChannel = 0;
131
135
  this._numOpens = 0;
136
+ this._numSqBrackets = 0;
132
137
  this._indentLengthStack = [];
133
138
  this._inputStarted = false;
134
139
  }
@@ -147,11 +152,17 @@ export default class PinescriptLexerBase extends Lexer {
147
152
  const tok = this._currentToken!;
148
153
  const tokType = tok.type;
149
154
  const C = this.C;
150
- if (tokType === C.LPAR || tokType === C.LSQB) {
155
+ if (tokType === C.LPAR) {
151
156
  this._numOpens += 1;
152
157
  this._addPendingToken(tok);
153
- } else if (tokType === C.RPAR || tokType === C.RSQB) {
154
- this._numOpens -= 1;
158
+ } else if (tokType === C.LSQB) {
159
+ this._numSqBrackets += 1;
160
+ this._addPendingToken(tok);
161
+ } else if (tokType === C.RPAR) {
162
+ this._numOpens = Math.max(0, this._numOpens - 1);
163
+ this._addPendingToken(tok);
164
+ } else if (tokType === C.RSQB) {
165
+ this._numSqBrackets = Math.max(0, this._numSqBrackets - 1);
155
166
  this._addPendingToken(tok);
156
167
  } else if (tokType === C.NEWLINE) {
157
168
  this._handleNEWLINEToken();
@@ -264,7 +275,14 @@ export default class PinescriptLexerBase extends Lexer {
264
275
  }
265
276
 
266
277
  private _handleNEWLINEToken(): void {
267
- if (this._numOpens > 0 || this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)) {
278
+ // Newlines inside (...) or [...] are hidden (Python parity): wrapped
279
+ // history-refs / tuples may use any indentation without emitting
280
+ // INDENT/DEDENT mid-expression.
281
+ if (
282
+ this._numOpens > 0 ||
283
+ this._numSqBrackets > 0 ||
284
+ this._operators.has(this._lastPendingTokenTypeFromDefaultChannel)
285
+ ) {
268
286
  this._hideAndAddPendingToken(this._currentToken!);
269
287
  return;
270
288
  }
@@ -103,8 +103,32 @@ export class CompileDraw {
103
103
  return this.book.boxNew(n(bar, 0), Object.keys(extra).length ? extra : undefined);
104
104
  }
105
105
 
106
- table_new(bar: unknown): number {
107
- return this.book.tableNew(n(bar, 0));
106
+ table_new(
107
+ bar: unknown,
108
+ position?: unknown,
109
+ columns?: unknown,
110
+ rows?: unknown,
111
+ bgcolor?: unknown,
112
+ frameColor?: unknown,
113
+ frameWidth?: unknown,
114
+ borderColor?: unknown,
115
+ borderWidth?: unknown,
116
+ forceOverlay?: unknown,
117
+ ): number {
118
+ // Pine positional order: (position, columns, rows, bgcolor, frame_color,
119
+ // frame_width, border_color, border_width, force_overlay) — Python
120
+ // `compiler.py` table emit SoT (columns then rows).
121
+ const extra: Record<string, unknown> = {};
122
+ if (position != null) extra.position = position;
123
+ putNum(extra, "columns", columns);
124
+ putNum(extra, "rows", rows);
125
+ if (bgcolor != null) extra.bgcolor = bgcolor;
126
+ if (frameColor != null) extra.frame_color = frameColor;
127
+ putNum(extra, "frame_width", frameWidth);
128
+ if (borderColor != null) extra.border_color = borderColor;
129
+ putNum(extra, "border_width", borderWidth);
130
+ if (forceOverlay != null) extra.force_overlay = forceOverlay;
131
+ return this.book.tableNew(n(bar, 0), Object.keys(extra).length ? extra : undefined);
108
132
  }
109
133
 
110
134
  polyline_new(bar: unknown, points?: unknown): number {
@@ -707,6 +707,22 @@ const ATTR_CONSTANTS: Record<string, string | number | boolean> = {
707
707
  "plot.linestyle_solid": "linestyle_solid",
708
708
  "plot.linestyle_dashed": "linestyle_dashed",
709
709
  "plot.linestyle_dotted": "linestyle_dotted",
710
+ // Python plotting.py plot.style_* (dispatch tag 0 strings).
711
+ "plot.style_line": "style_line",
712
+ "plot.style_linebr": "style_linebr",
713
+ "plot.style_stepline": "style_stepline",
714
+ "plot.style_steplinebr": "style_steplinebr",
715
+ "plot.style_stepline_diamond": "style_stepline_diamond",
716
+ "plot.style_histogram": "style_histogram",
717
+ "plot.style_columns": "style_columns",
718
+ "plot.style_cross": "style_cross",
719
+ "plot.style_area": "style_area",
720
+ "plot.style_areabr": "style_areabr",
721
+ "plot.style_circles": "style_circles",
722
+ // Python alerts.py FREQ_* tokens.
723
+ "alert.freq_once_per_bar": "once_per_bar",
724
+ "alert.freq_once_per_bar_close": "once_per_bar_close",
725
+ "alert.freq_all": "all",
710
726
  "dayofweek.sunday": 1,
711
727
  "dayofweek.monday": 2,
712
728
  "dayofweek.tuesday": 3,
@@ -744,6 +760,7 @@ const ATTR_CONST_NS = new Set([
744
760
  "position",
745
761
  "hline",
746
762
  "plot",
763
+ "alert",
747
764
  "dayofweek",
748
765
  "month",
749
766
  ]);