@invinite-org/chartlang-core 1.1.1 → 1.3.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.
Files changed (86) hide show
  1. package/CHANGELOG.md +282 -0
  2. package/README.md +2 -1
  3. package/dist/draw/buckets.d.ts.map +1 -1
  4. package/dist/draw/buckets.js +1 -0
  5. package/dist/draw/buckets.js.map +1 -1
  6. package/dist/draw/draw.d.ts +8 -1
  7. package/dist/draw/draw.d.ts.map +1 -1
  8. package/dist/draw/draw.js.map +1 -1
  9. package/dist/draw/drawingKind.d.ts +8 -8
  10. package/dist/draw/drawingKind.d.ts.map +1 -1
  11. package/dist/draw/drawingKind.js +5 -3
  12. package/dist/draw/drawingKind.js.map +1 -1
  13. package/dist/draw/drawingState.d.ts +27 -3
  14. package/dist/draw/drawingState.d.ts.map +1 -1
  15. package/dist/draw/drawingState.js.map +1 -1
  16. package/dist/draw/drawingStyle.d.ts +52 -9
  17. package/dist/draw/drawingStyle.d.ts.map +1 -1
  18. package/dist/draw/drawingStyle.js.map +1 -1
  19. package/dist/draw/index.d.ts +2 -2
  20. package/dist/draw/index.d.ts.map +1 -1
  21. package/dist/draw/index.js.map +1 -1
  22. package/dist/index.d.ts +11 -9
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/input/index.d.ts +1 -1
  27. package/dist/input/index.d.ts.map +1 -1
  28. package/dist/input/index.js.map +1 -1
  29. package/dist/input/input.d.ts +15 -1
  30. package/dist/input/input.d.ts.map +1 -1
  31. package/dist/input/input.js +14 -0
  32. package/dist/input/input.js.map +1 -1
  33. package/dist/input/inputDescriptor.d.ts +15 -2
  34. package/dist/input/inputDescriptor.d.ts.map +1 -1
  35. package/dist/input/inputDescriptor.js.map +1 -1
  36. package/dist/plot/plot.d.ts +75 -0
  37. package/dist/plot/plot.d.ts.map +1 -1
  38. package/dist/plot/plot.js +34 -0
  39. package/dist/plot/plot.js.map +1 -1
  40. package/dist/request/feedKey.d.ts +20 -0
  41. package/dist/request/feedKey.d.ts.map +1 -0
  42. package/dist/request/feedKey.js +29 -0
  43. package/dist/request/feedKey.js.map +1 -0
  44. package/dist/request/index.d.ts +3 -1
  45. package/dist/request/index.d.ts.map +1 -1
  46. package/dist/request/index.js +1 -0
  47. package/dist/request/index.js.map +1 -1
  48. package/dist/request/request.d.ts +107 -20
  49. package/dist/request/request.d.ts.map +1 -1
  50. package/dist/request/request.js +27 -26
  51. package/dist/request/request.js.map +1 -1
  52. package/dist/state/arraySlot.d.ts +38 -0
  53. package/dist/state/arraySlot.d.ts.map +1 -0
  54. package/dist/state/arraySlot.js +4 -0
  55. package/dist/state/arraySlot.js.map +1 -0
  56. package/dist/state/index.d.ts +1 -0
  57. package/dist/state/index.d.ts.map +1 -1
  58. package/dist/state/index.js.map +1 -1
  59. package/dist/state/state.d.ts +36 -0
  60. package/dist/state/state.d.ts.map +1 -1
  61. package/dist/state/state.js +38 -0
  62. package/dist/state/state.js.map +1 -1
  63. package/dist/statefulPrimitives.d.ts +9 -5
  64. package/dist/statefulPrimitives.d.ts.map +1 -1
  65. package/dist/statefulPrimitives.js +37 -5
  66. package/dist/statefulPrimitives.js.map +1 -1
  67. package/dist/ta/ta.d.ts +39 -8
  68. package/dist/ta/ta.d.ts.map +1 -1
  69. package/dist/ta/ta.js +6 -0
  70. package/dist/ta/ta.js.map +1 -1
  71. package/dist/time-accessors/index.d.ts +5 -0
  72. package/dist/time-accessors/index.d.ts.map +1 -0
  73. package/dist/time-accessors/index.js +5 -0
  74. package/dist/time-accessors/index.js.map +1 -0
  75. package/dist/time-accessors/sessionAccessors.d.ts +43 -0
  76. package/dist/time-accessors/sessionAccessors.d.ts.map +1 -0
  77. package/dist/time-accessors/sessionAccessors.js +38 -0
  78. package/dist/time-accessors/sessionAccessors.js.map +1 -0
  79. package/dist/time-accessors/timeAccessors.d.ts +132 -0
  80. package/dist/time-accessors/timeAccessors.d.ts.map +1 -0
  81. package/dist/time-accessors/timeAccessors.js +143 -0
  82. package/dist/time-accessors/timeAccessors.js.map +1 -0
  83. package/dist/types.d.ts +219 -1
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/types.js.map +1 -1
  86. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"plot.js","sourceRoot":"","sources":["../../src/plot/plot.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAiR/D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,IAAI,CAAC,MAA+B,EAAE,KAAgB;IAClE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,MAAc,EAAE,KAAiB;IACnD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Color, LineStyle, Series } from \"../types.js\";\n\n/**\n * Rendered-shape discriminator for `plot` emissions reaching the adapter.\n * The full 0.5 inventory is `line`, `step-line`, `horizontal-line`,\n * `histogram`, `area`, `filled-band`, `label`, `marker`,\n * `shape`, `character`, `arrow`, `candle-override`, `bar-override`,\n * `bg-color`, `bar-color`, and `horizontal-histogram`. Every expansion is\n * additive — the `apiVersion: 1` script header stays unchanged.\n *\n * Typical Phase-2 consumers:\n *\n * - `histogram` → volume bars, MACD histogram, momentum-style oscillators.\n * - `area` → filled region under a polyline (BB midline, regression).\n * - `filled-band` → Bollinger / Keltner / Donchian / Ichimoku envelopes.\n * - `label` → text annotations at a world-space anchor (fractal, pivot).\n * - `marker` → discrete glyph (circle / triangle / square / diamond) for\n * fractals / divergence / supertrend flips.\n *\n * @since 0.1\n * @example\n * const k: PlotKind = \"line\";\n * const histogram: PlotKind = \"histogram\";\n * const shape: PlotKind = \"shape\";\n * void k; void histogram; void shape;\n */\nexport type PlotKind =\n | \"line\"\n | \"step-line\"\n | \"horizontal-line\"\n | \"histogram\"\n | \"area\"\n | \"filled-band\"\n | \"label\"\n | \"marker\"\n | \"shape\"\n | \"character\"\n | \"arrow\"\n | \"candle-override\"\n | \"bar-override\"\n | \"bg-color\"\n | \"bar-color\"\n | \"horizontal-histogram\";\n\n/**\n * Marker glyphs shared by Phase 2 `marker` and Phase 5 `shape` plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const shape: PlotGlyphShape = \"circle\";\n * void shape;\n */\nexport type PlotGlyphShape = \"circle\" | \"triangle-up\" | \"triangle-down\" | \"square\" | \"diamond\";\n\n/**\n * Full glyph inventory for Phase 5 `shape` plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const shape: PlotShapeGlyph = \"flag\";\n * void shape;\n */\nexport type PlotShapeGlyph = PlotGlyphShape | \"cross\" | \"xcross\" | \"flag\";\n\n/**\n * Vertical anchoring mode for glyph-like Phase 5 plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const location: PlotLocation = \"above\";\n * void location;\n */\nexport type PlotLocation = \"above\" | \"below\" | \"absolute\";\n\n/**\n * Single row in a Phase 5 horizontal-histogram plot emission.\n *\n * @since 0.5\n * @stable\n * @example\n * const bucket: HorizontalHistogramBucket = { price: 100, volume: 25 };\n * void bucket;\n */\nexport type HorizontalHistogramBucket = Readonly<{\n readonly price: number;\n readonly volume: number;\n readonly color?: Color;\n}>;\n\n/**\n * Script-author selectable plot style. The runtime maps this to the\n * adapter-kit's wire `PlotStyle` discriminated union and fills in defaults\n * from sibling {@link PlotOpts} fields (`lineWidth` / `lineStyle`) for\n * line-like styles.\n *\n * `histogram.baseline` defaults to `0` when omitted.\n *\n * @formula N/A — script-facing style input\n * @since 0.2\n * @stable\n * @example\n * const lineStyle: PlotOptsStyle = { kind: \"line\" };\n * const histStyle: PlotOptsStyle = { kind: \"histogram\", baseline: 0 };\n * void lineStyle; void histStyle;\n */\nexport type PlotOptsStyle =\n | { readonly kind: \"line\" }\n | { readonly kind: \"step-line\" }\n | { readonly kind: \"horizontal-line\" }\n | { readonly kind: \"histogram\"; readonly baseline?: number }\n | {\n readonly kind: \"marker\";\n readonly shape: PlotGlyphShape;\n readonly size: number;\n }\n /**\n * Glyph at world-anchor — Pine's `plotshape`. Location selects vertical\n * anchoring; `size` is in CSS pixels.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"shape\", shape: \"triangle-up\", size: 8, location: \"below\" } });\n */\n | {\n readonly kind: \"shape\";\n readonly shape: PlotShapeGlyph;\n readonly size: number;\n readonly location?: PlotLocation;\n }\n /**\n * Text glyph at world-anchor — Pine's `plotchar`. `char` may be any\n * non-empty UTF-8 string; `size` is in CSS pixels.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"character\", char: \"▲\", size: 12, location: \"above\" } });\n */\n | {\n readonly kind: \"character\";\n readonly char: string;\n readonly size: number;\n readonly location?: PlotLocation;\n }\n /**\n * Directional marker at world-anchor — Pine's `plotarrow`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.low, { style: { kind: \"arrow\", direction: \"up\", size: 10 } });\n */\n | { readonly kind: \"arrow\"; readonly direction: \"up\" | \"down\"; readonly size: number }\n /**\n * Candle body color override — Pine's `plotcandle`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"candle-override\", bull: \"#26a69a\", bear: \"#ef5350\" } });\n */\n | {\n readonly kind: \"candle-override\";\n readonly bull: Color;\n readonly bear: Color;\n readonly doji?: Color;\n }\n /**\n * OHLC bar outline override — Pine's `plotbar`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bar-override\", color: \"#f59e0b\" } });\n */\n | { readonly kind: \"bar-override\"; readonly color: Color }\n /**\n * Pane background color band — Pine's `bgcolor`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bg-color\", color: \"#1d4ed8\", transp: 80 } });\n */\n | { readonly kind: \"bg-color\"; readonly color: Color; readonly transp?: number }\n /**\n * Main candle/bar tint — Pine's `barcolor`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bar-color\", color: \"#a855f7\" } });\n */\n | { readonly kind: \"bar-color\"; readonly color: Color }\n /**\n * Right-edge volume-profile bars keyed by price bucket.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"horizontal-histogram\", buckets: [{ price: bar.close, volume: bar.volume }] } });\n */\n | {\n readonly kind: \"horizontal-histogram\";\n readonly buckets: ReadonlyArray<HorizontalHistogramBucket>;\n };\n\n/**\n * Styling options accepted by `plot(...)`. `pane: \"overlay\"` (the default) is\n * the only pane the Phase-1 canvas2d adapter renders — `\"new\"` and named\n * panes are reserved for Phase 2+. `style` (Phase 2) lets the script pick\n * a non-line {@link PlotOptsStyle} — defaults to `{ kind: \"line\" }`.\n *\n * @since 0.1\n * @example\n * const opts: PlotOpts = {\n * color: \"#3b82f6\",\n * title: \"EMA(20)\",\n * lineWidth: 2,\n * lineStyle: \"solid\",\n * pane: \"overlay\",\n * style: { kind: \"line\" },\n * };\n */\nexport type PlotOpts = Readonly<{\n color?: Color;\n title?: string;\n lineWidth?: number;\n lineStyle?: LineStyle;\n pane?: \"overlay\" | \"new\" | string;\n style?: PlotOptsStyle;\n}>;\n\n/**\n * Styling options accepted by `hline(...)`. `pane` follows the same shape as\n * {@link PlotOpts.pane}: omit to fall back to the script's manifest-resolved\n * default (overlay unless `defineIndicator({ overlay: false })` was declared);\n * `\"overlay\"` pins the line to the price pane; `\"new\"` opens / joins the\n * per-script subpane; named panes route to a shared subpane key.\n *\n * @since 0.1\n * @stable\n * @example\n * const opts: HLineOpts = {\n * color: \"#ef4444\",\n * title: \"RSI 70\",\n * lineStyle: \"dashed\",\n * pane: \"new\",\n * };\n */\nexport type HLineOpts = Readonly<{\n color?: Color;\n title?: string;\n lineWidth?: number;\n lineStyle?: LineStyle;\n /**\n * Routes the horizontal line to a pane. Mirrors {@link PlotOpts.pane}:\n * omit to fall back to the script's manifest-resolved default,\n * `\"overlay\"` pins to the price pane, `\"new\"` joins the per-script\n * subpane, and named keys route to a shared subpane (folded to overlay\n * with `unsupported-pane` on `subPanes: 0` adapters).\n *\n * @since 0.2\n */\n pane?: \"overlay\" | \"new\" | string;\n}>;\n\n/**\n * Compile-time callable hole for `plot(value, opts?)`. The compiler rewrites\n * every callsite to dispatch to the runtime's `plot` implementation;\n * calling this outside a compiled runtime throws the sentinel.\n *\n * Accepts `number | Series<number>` — scalars emit a single bar value;\n * series emissions pull from `series.current`.\n *\n * @since 0.1\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // plot(bar.close, { color: \"#3b82f6\" });\n * import { plot } from \"@invinite-org/chartlang-core\";\n * try { plot(0); } catch {}\n */\nexport function plot(_value: number | Series<number>, _opts?: PlotOpts): void {\n throw new Error(\"plot called outside compiled runtime\");\n}\n\n/**\n * Compile-time callable hole for `hline(price, opts?)`. Same semantics as\n * `plot` but pinned to a fixed price across all bars.\n *\n * @since 0.1\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // hline(70, { color: \"#ef4444\" });\n * import { hline } from \"@invinite-org/chartlang-core\";\n * try { hline(70); } catch {}\n */\nexport function hline(_price: number, _opts?: HLineOpts): void {\n throw new Error(\"hline called outside compiled runtime\");\n}\n"]}
1
+ {"version":3,"file":"plot.js","sourceRoot":"","sources":["../../src/plot/plot.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAgU/D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,IAAI,CAAC,MAA+B,EAAE,KAAgB;IAClE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,MAAc,EAAE,KAAiB;IACnD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,OAAO,CAAC,MAAa,EAAE,KAAmB;IACtD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAa,EAAE,KAAoB;IACxD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAChE,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Color, LineStyle, Series } from \"../types.js\";\n\n/**\n * Rendered-shape discriminator for `plot` emissions reaching the adapter.\n * The full 0.5 inventory is `line`, `step-line`, `horizontal-line`,\n * `histogram`, `area`, `filled-band`, `label`, `marker`,\n * `shape`, `character`, `arrow`, `candle-override`, `bar-override`,\n * `bg-color`, `bar-color`, and `horizontal-histogram`. Every expansion is\n * additive — the `apiVersion: 1` script header stays unchanged.\n *\n * Typical Phase-2 consumers:\n *\n * - `histogram` → volume bars, MACD histogram, momentum-style oscillators.\n * - `area` → filled region under a polyline (BB midline, regression).\n * - `filled-band` → Bollinger / Keltner / Donchian / Ichimoku envelopes.\n * - `label` → text annotations at a world-space anchor (fractal, pivot).\n * - `marker` → discrete glyph (circle / triangle / square / diamond) for\n * fractals / divergence / supertrend flips.\n *\n * @since 0.1\n * @example\n * const k: PlotKind = \"line\";\n * const histogram: PlotKind = \"histogram\";\n * const shape: PlotKind = \"shape\";\n * void k; void histogram; void shape;\n */\nexport type PlotKind =\n | \"line\"\n | \"step-line\"\n | \"horizontal-line\"\n | \"histogram\"\n | \"area\"\n | \"filled-band\"\n | \"label\"\n | \"marker\"\n | \"shape\"\n | \"character\"\n | \"arrow\"\n | \"candle-override\"\n | \"bar-override\"\n | \"bg-color\"\n | \"bar-color\"\n | \"horizontal-histogram\";\n\n/**\n * Marker glyphs shared by Phase 2 `marker` and Phase 5 `shape` plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const shape: PlotGlyphShape = \"circle\";\n * void shape;\n */\nexport type PlotGlyphShape = \"circle\" | \"triangle-up\" | \"triangle-down\" | \"square\" | \"diamond\";\n\n/**\n * Full glyph inventory for Phase 5 `shape` plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const shape: PlotShapeGlyph = \"flag\";\n * void shape;\n */\nexport type PlotShapeGlyph = PlotGlyphShape | \"cross\" | \"xcross\" | \"flag\";\n\n/**\n * Vertical anchoring mode for glyph-like Phase 5 plot styles.\n *\n * @since 0.5\n * @stable\n * @example\n * const location: PlotLocation = \"above\";\n * void location;\n */\nexport type PlotLocation = \"above\" | \"below\" | \"absolute\";\n\n/**\n * Single row in a Phase 5 horizontal-histogram plot emission.\n *\n * @since 0.5\n * @stable\n * @example\n * const bucket: HorizontalHistogramBucket = { price: 100, volume: 25 };\n * void bucket;\n */\nexport type HorizontalHistogramBucket = Readonly<{\n readonly price: number;\n readonly volume: number;\n readonly color?: Color;\n}>;\n\n/**\n * Script-author selectable plot style. The runtime maps this to the\n * adapter-kit's wire `PlotStyle` discriminated union and fills in defaults\n * from sibling {@link PlotOpts} fields (`lineWidth` / `lineStyle`) for\n * line-like styles.\n *\n * `histogram.baseline` defaults to `0` when omitted.\n *\n * @formula N/A — script-facing style input\n * @since 0.2\n * @stable\n * @example\n * const lineStyle: PlotOptsStyle = { kind: \"line\" };\n * const histStyle: PlotOptsStyle = { kind: \"histogram\", baseline: 0 };\n * void lineStyle; void histStyle;\n */\nexport type PlotOptsStyle =\n | { readonly kind: \"line\" }\n | { readonly kind: \"step-line\" }\n | { readonly kind: \"horizontal-line\" }\n | { readonly kind: \"histogram\"; readonly baseline?: number }\n | {\n readonly kind: \"marker\";\n readonly shape: PlotGlyphShape;\n readonly size: number;\n }\n /**\n * Glyph at world-anchor — Pine's `plotshape`. Location selects vertical\n * anchoring; `size` is in CSS pixels.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"shape\", shape: \"triangle-up\", size: 8, location: \"below\" } });\n */\n | {\n readonly kind: \"shape\";\n readonly shape: PlotShapeGlyph;\n readonly size: number;\n readonly location?: PlotLocation;\n }\n /**\n * Text glyph at world-anchor — Pine's `plotchar`. `char` may be any\n * non-empty UTF-8 string; `size` is in CSS pixels.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"character\", char: \"▲\", size: 12, location: \"above\" } });\n */\n | {\n readonly kind: \"character\";\n readonly char: string;\n readonly size: number;\n readonly location?: PlotLocation;\n }\n /**\n * Directional marker at world-anchor — Pine's `plotarrow`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.low, { style: { kind: \"arrow\", direction: \"up\", size: 10 } });\n */\n | { readonly kind: \"arrow\"; readonly direction: \"up\" | \"down\"; readonly size: number }\n /**\n * Candle body color override — Pine's `plotcandle`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"candle-override\", bull: \"#26a69a\", bear: \"#ef5350\" } });\n */\n | {\n readonly kind: \"candle-override\";\n readonly bull: Color;\n readonly bear: Color;\n readonly doji?: Color;\n }\n /**\n * OHLC bar outline override — Pine's `plotbar`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bar-override\", color: \"#f59e0b\" } });\n */\n | { readonly kind: \"bar-override\"; readonly color: Color }\n /**\n * Pane background color band — Pine's `bgcolor`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bg-color\", color: \"#1d4ed8\", transp: 80 } });\n */\n | { readonly kind: \"bg-color\"; readonly color: Color; readonly transp?: number }\n /**\n * Main candle/bar tint — Pine's `barcolor`.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"bar-color\", color: \"#a855f7\" } });\n */\n | { readonly kind: \"bar-color\"; readonly color: Color }\n /**\n * Right-edge volume-profile bars keyed by price bucket.\n *\n * @since 0.5\n * @stable\n * @example\n * plot(bar.close, { style: { kind: \"horizontal-histogram\", buckets: [{ price: bar.close, volume: bar.volume }] } });\n */\n | {\n readonly kind: \"horizontal-histogram\";\n readonly buckets: ReadonlyArray<HorizontalHistogramBucket>;\n };\n\n/**\n * Styling options accepted by `plot(...)`. `pane: \"overlay\"` (the default) is\n * the only pane the Phase-1 canvas2d adapter renders — `\"new\"` and named\n * panes are reserved for Phase 2+. `style` (Phase 2) lets the script pick\n * a non-line {@link PlotOptsStyle} — defaults to `{ kind: \"line\" }`.\n *\n * @since 0.1\n * @example\n * const opts: PlotOpts = {\n * color: \"#3b82f6\",\n * title: \"EMA(20)\",\n * lineWidth: 2,\n * lineStyle: \"solid\",\n * pane: \"overlay\",\n * style: { kind: \"line\" },\n * };\n */\nexport type PlotOpts = Readonly<{\n color?: Color;\n title?: string;\n lineWidth?: number;\n lineStyle?: LineStyle;\n pane?: \"overlay\" | \"new\" | string;\n style?: PlotOptsStyle;\n /**\n * Presentation-only render-order key (z-index). Default `0`.\n * Higher `z` renders on top; lower `z` renders behind. Marks with\n * equal `z` keep the default group order (plots below drawings) and,\n * within a group, declaration order. `z` may be any finite number —\n * fractional values (e.g. `1.5`) slot a mark between two layers\n * without renumbering. It affects **only** stacking: `value`,\n * alerts, and `state.*` are unaffected.\n *\n * @since 1.4\n * @stable\n * @example\n * plot(ta.sma(bar.close, 50), { z: -1 }); // behind other plots\n */\n z?: number;\n}>;\n\n/**\n * Styling options accepted by `hline(...)`. `pane` follows the same shape as\n * {@link PlotOpts.pane}: omit to fall back to the script's manifest-resolved\n * default (overlay unless `defineIndicator({ overlay: false })` was declared);\n * `\"overlay\"` pins the line to the price pane; `\"new\"` opens / joins the\n * per-script subpane; named panes route to a shared subpane key.\n *\n * @since 0.1\n * @stable\n * @example\n * const opts: HLineOpts = {\n * color: \"#ef4444\",\n * title: \"RSI 70\",\n * lineStyle: \"dashed\",\n * pane: \"new\",\n * };\n */\nexport type HLineOpts = Readonly<{\n color?: Color;\n title?: string;\n lineWidth?: number;\n lineStyle?: LineStyle;\n /**\n * Routes the horizontal line to a pane. Mirrors {@link PlotOpts.pane}:\n * omit to fall back to the script's manifest-resolved default,\n * `\"overlay\"` pins to the price pane, `\"new\"` joins the per-script\n * subpane, and named keys route to a shared subpane (folded to overlay\n * with `unsupported-pane` on `subPanes: 0` adapters).\n *\n * @since 0.2\n */\n pane?: \"overlay\" | \"new\" | string;\n}>;\n\n/**\n * Styling options accepted by `bgcolor(...)` — the Pine-ergonomic alias for\n * a `bg-color` pane-background band. `transp` is the 0–100 transparency\n * (0 opaque … 100 fully transparent), mirroring {@link PlotOptsStyle}'s\n * `bg-color` arm. `title` labels the slot for host overrides.\n *\n * @since 1.4\n * @stable\n * @example\n * const opts: BgColorOpts = { transp: 80, title: \"RSI heat\" };\n * void opts;\n */\nexport type BgColorOpts = Readonly<{\n transp?: number;\n title?: string;\n}>;\n\n/**\n * Styling options accepted by `barcolor(...)` — the Pine-ergonomic alias for\n * a `bar-color` candle/bar tint. The `bar-color` style carries no\n * transparency, so this bag only labels the slot.\n *\n * @since 1.4\n * @stable\n * @example\n * const opts: BarColorOpts = { title: \"trend tint\" };\n * void opts;\n */\nexport type BarColorOpts = Readonly<{\n title?: string;\n}>;\n\n/**\n * Compile-time callable hole for `plot(value, opts?)`. The compiler rewrites\n * every callsite to dispatch to the runtime's `plot` implementation;\n * calling this outside a compiled runtime throws the sentinel.\n *\n * Accepts `number | Series<number>` — scalars emit a single bar value;\n * series emissions pull from `series.current`.\n *\n * @since 0.1\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // plot(bar.close, { color: \"#3b82f6\" });\n * import { plot } from \"@invinite-org/chartlang-core\";\n * try { plot(0); } catch {}\n */\nexport function plot(_value: number | Series<number>, _opts?: PlotOpts): void {\n throw new Error(\"plot called outside compiled runtime\");\n}\n\n/**\n * Compile-time callable hole for `hline(price, opts?)`. Same semantics as\n * `plot` but pinned to a fixed price across all bars.\n *\n * @since 0.1\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // hline(70, { color: \"#ef4444\" });\n * import { hline } from \"@invinite-org/chartlang-core\";\n * try { hline(70); } catch {}\n */\nexport function hline(_price: number, _opts?: HLineOpts): void {\n throw new Error(\"hline called outside compiled runtime\");\n}\n\n/**\n * Paint the pane background for the current bar — the Pine-ergonomic alias\n * for `plot(NaN, { style: { kind: \"bg-color\", color, transp } })`. Pass a\n * `Color` (a CSS / hex string, or a per-bar color expression like\n * `close > open ? \"#16a34a\" : \"#dc2626\"`). Sugar over the existing\n * `bg-color` plot style — same wire emission, same capability gate.\n *\n * @since 1.4\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // bgcolor(bar.close > bar.open ? \"#16a34a\" : \"#dc2626\", { transp: 80 });\n * import { bgcolor } from \"@invinite-org/chartlang-core\";\n * try { bgcolor(\"#1d4ed8\"); } catch {}\n */\nexport function bgcolor(_color: Color, _opts?: BgColorOpts): void {\n throw new Error(\"bgcolor called outside compiled runtime\");\n}\n\n/**\n * Tint the candle / bar for the current bar — the Pine-ergonomic alias for\n * `plot(NaN, { style: { kind: \"bar-color\", color } })`. Sugar over the\n * existing `bar-color` plot style.\n *\n * @since 1.4\n * @stable\n * @example\n * // Inside a compiled `compute`:\n * // barcolor(bar.close > bar.open ? \"#16a34a\" : \"#dc2626\");\n * import { barcolor } from \"@invinite-org/chartlang-core\";\n * try { barcolor(\"#a855f7\"); } catch {}\n */\nexport function barcolor(_color: Color, _opts?: BarColorOpts): void {\n throw new Error(\"barcolor called outside compiled runtime\");\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Build the composite secondary-feed key from a `(symbol, interval)` pair —
3
+ * the **single** source of the stream-key format shared by the runtime's
4
+ * stream/cache maps and the host wire (`CandleEvent.streamKey`). Like a slot
5
+ * id, this string is load-bearing: producer (adapter/host) and consumer
6
+ * (runtime) must agree byte-for-byte, so never re-derive it inline.
7
+ *
8
+ * An **omitted** symbol (the chart's own symbol / higher-timeframe-only case)
9
+ * encodes to the bare interval — `feedKey(undefined, "1D") === "1D"` — so the
10
+ * symbol-omitted wire and every key stay byte-identical to the pre-multi-symbol
11
+ * baseline. A present symbol encodes as `"<symbol>@<interval>"`.
12
+ *
13
+ * @since 1.3
14
+ * @stable
15
+ * @example
16
+ * feedKey(undefined, "1D"); // "1D" (chart symbol, back-compat)
17
+ * feedKey("AMEX:SPY", "1D"); // "AMEX:SPY@1D"
18
+ */
19
+ export declare function feedKey(symbol: string | undefined, interval: string): string;
20
+ //# sourceMappingURL=feedKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedKey.d.ts","sourceRoot":"","sources":["../../src/request/feedKey.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO5E"}
@@ -0,0 +1,29 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ /**
4
+ * Build the composite secondary-feed key from a `(symbol, interval)` pair —
5
+ * the **single** source of the stream-key format shared by the runtime's
6
+ * stream/cache maps and the host wire (`CandleEvent.streamKey`). Like a slot
7
+ * id, this string is load-bearing: producer (adapter/host) and consumer
8
+ * (runtime) must agree byte-for-byte, so never re-derive it inline.
9
+ *
10
+ * An **omitted** symbol (the chart's own symbol / higher-timeframe-only case)
11
+ * encodes to the bare interval — `feedKey(undefined, "1D") === "1D"` — so the
12
+ * symbol-omitted wire and every key stay byte-identical to the pre-multi-symbol
13
+ * baseline. A present symbol encodes as `"<symbol>@<interval>"`.
14
+ *
15
+ * @since 1.3
16
+ * @stable
17
+ * @example
18
+ * feedKey(undefined, "1D"); // "1D" (chart symbol, back-compat)
19
+ * feedKey("AMEX:SPY", "1D"); // "AMEX:SPY@1D"
20
+ */
21
+ export function feedKey(symbol, interval) {
22
+ // The `@` separator is not a valid character in a chartlang interval
23
+ // literal (`/^\d+[smhdwM]$/`), so a `"<symbol>@<interval>"` key can never
24
+ // collide with a bare-interval (chart-symbol) key. An empty/undefined
25
+ // symbol collapsing to the bare interval is what gives the omitted-symbol
26
+ // path byte-identical keys + wire to the pre-multi-symbol baseline.
27
+ return symbol === undefined || symbol === "" ? interval : `${symbol}@${interval}`;
28
+ }
29
+ //# sourceMappingURL=feedKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedKey.js","sourceRoot":"","sources":["../../src/request/feedKey.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,OAAO,CAAC,MAA0B,EAAE,QAAgB;IAChE,qEAAqE;IACrE,0EAA0E;IAC1E,sEAAsE;IACtE,0EAA0E;IAC1E,oEAAoE;IACpE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;AACtF,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\n/**\n * Build the composite secondary-feed key from a `(symbol, interval)` pair —\n * the **single** source of the stream-key format shared by the runtime's\n * stream/cache maps and the host wire (`CandleEvent.streamKey`). Like a slot\n * id, this string is load-bearing: producer (adapter/host) and consumer\n * (runtime) must agree byte-for-byte, so never re-derive it inline.\n *\n * An **omitted** symbol (the chart's own symbol / higher-timeframe-only case)\n * encodes to the bare interval — `feedKey(undefined, \"1D\") === \"1D\"` — so the\n * symbol-omitted wire and every key stay byte-identical to the pre-multi-symbol\n * baseline. A present symbol encodes as `\"<symbol>@<interval>\"`.\n *\n * @since 1.3\n * @stable\n * @example\n * feedKey(undefined, \"1D\"); // \"1D\" (chart symbol, back-compat)\n * feedKey(\"AMEX:SPY\", \"1D\"); // \"AMEX:SPY@1D\"\n */\nexport function feedKey(symbol: string | undefined, interval: string): string {\n // The `@` separator is not a valid character in a chartlang interval\n // literal (`/^\\d+[smhdwM]$/`), so a `\"<symbol>@<interval>\"` key can never\n // collide with a bare-interval (chart-symbol) key. An empty/undefined\n // symbol collapsing to the bare interval is what gives the omitted-symbol\n // path byte-identical keys + wire to the pre-multi-symbol baseline.\n return symbol === undefined || symbol === \"\" ? interval : `${symbol}@${interval}`;\n}\n"]}
@@ -1,2 +1,4 @@
1
- export { request, type RequestNamespace, type RequestLowerTfOpts, type RequestSecurityOpts, type SecurityBar, } from "./request.js";
1
+ export { request, type RequestNamespace, type RequestLowerTfOpts, type RequestSecurityOpts, type SecurityBar, type SecurityExpr, } from "./request.js";
2
+ export { feedKey } from "./feedKey.js";
3
+ export type { RequestedFeed } from "../types.js";
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACnB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,YAAY,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -1,4 +1,5 @@
1
1
  // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
2
  // See the LICENSE file in the repo root for full license text.
3
3
  export { request, } from "./request.js";
4
+ export { feedKey } from "./feedKey.js";
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EACH,OAAO,GAKV,MAAM,cAAc,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nexport {\n request,\n type RequestNamespace,\n type RequestLowerTfOpts,\n type RequestSecurityOpts,\n type SecurityBar,\n} from \"./request.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EACH,OAAO,GAMV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nexport {\n request,\n type RequestNamespace,\n type RequestLowerTfOpts,\n type RequestSecurityOpts,\n type SecurityBar,\n type SecurityExpr,\n} from \"./request.js\";\nexport { feedKey } from \"./feedKey.js\";\nexport type { RequestedFeed } from \"../types.js\";\n"]}
@@ -9,8 +9,24 @@ import type { Bar, Price, Series, Time, Volume } from "../types.js";
9
9
  * @example
10
10
  * const opts: RequestSecurityOpts = { interval: "1D" };
11
11
  * void opts;
12
+ * @example
13
+ * // read a different instrument (requires Capabilities.multiSymbol)
14
+ * const spy: RequestSecurityOpts = { symbol: "AMEX:SPY", interval: "1D" };
15
+ * void spy;
12
16
  */
13
17
  export type RequestSecurityOpts = Readonly<{
18
+ /**
19
+ * The instrument to read. Omit for the chart's own symbol (the existing
20
+ * behavior). Must be a compile-time literal — a string literal, an
21
+ * `input.symbol` default, or an `input.enum` value; the compiler's
22
+ * literal-only pass rejects a dynamic expression with
23
+ * `request-security-symbol-not-literal`. A non-chart symbol additionally
24
+ * requires `Capabilities.multiSymbol`; otherwise the series degrades to
25
+ * all-NaN.
26
+ *
27
+ * @since 1.2
28
+ */
29
+ readonly symbol?: string;
14
30
  readonly interval: string;
15
31
  }>;
16
32
  /**
@@ -58,6 +74,94 @@ export type SecurityBar = Readonly<{
58
74
  readonly symbol: Series<string>;
59
75
  readonly interval: Series<string>;
60
76
  }>;
77
+ /**
78
+ * A higher-timeframe expression callback for {@link RequestNamespace.security}.
79
+ * Receives the HTF {@link SecurityBar} (OHLCV series on the secondary
80
+ * stream's own clock) and returns the value to evaluate per HTF bar.
81
+ * The body may reference only the `bar` parameter, the ambient `ta`
82
+ * namespace, `inputs`, safe `Math.*` globals, and literal constants —
83
+ * capturing any other outer binding is a compile error
84
+ * (`request-security-expr-captures-local`).
85
+ *
86
+ * Returning a `Series<number>` (e.g. `(bar) => ta.ema(bar.close, 20)`)
87
+ * lets `ta.*` accumulate over HTF bars; returning a bare `number`
88
+ * (e.g. `(bar) => bar.close.current * 2`) samples the scalar once per
89
+ * HTF bar. Either way the result aligns no-lookahead to the main timeline.
90
+ *
91
+ * @since 0.7
92
+ * @stable
93
+ * @example
94
+ * const trend: SecurityExpr = (bar) => bar.close;
95
+ * void trend;
96
+ */
97
+ export type SecurityExpr = (bar: SecurityBar) => Series<number> | number;
98
+ /**
99
+ * Read a secondary candle stream at a script-author-fixed **higher**
100
+ * interval. Two forms:
101
+ *
102
+ * - **Data**: `request.security({ interval })` → a `SecurityBar`.
103
+ * Every OHLCV field — plus the derived `hl2` / `hlc3` / `ohlc4` /
104
+ * `hlcc4` and `symbol` / `interval` — is a `Series<...>` aligned
105
+ * no-lookahead to the chart's bars, so a script can read prior secondary
106
+ * values such as `weekly.close[5]`.
107
+ * - **Expression**: `request.security({ interval }, (bar) => …)` →
108
+ * `Series<number>`. The callback runs **on the higher-timeframe clock**
109
+ * (once per HTF bar), so `ta.*` inside it accumulate over HTF bars; the
110
+ * result is aligned no-lookahead down to the main timeline. This is the
111
+ * only correct way to get a "weekly EMA(20)" — the data form's series is
112
+ * clocked to the main timeline, so `ta.ema(weekly.close, 20)` would
113
+ * average 20 *main* bars.
114
+ *
115
+ * Both `symbol` and `interval` must be compile-time literals (a string
116
+ * literal, an `input.symbol` default, or an `input.enum` value); the compiler
117
+ * walks every call to populate `manifest.requestedFeeds` (and the main-symbol
118
+ * projection `manifest.requestedIntervals`). `symbol` is **optional** —
119
+ * omitting it reads the chart's own symbol (the higher-timeframe-only case).
120
+ * When the adapter does not advertise `Capabilities.multiTimeframe`, the
121
+ * series degrades to all-NaN rather than erroring; a non-chart `symbol`
122
+ * additionally requires `Capabilities.multiSymbol` and otherwise degrades to
123
+ * all-NaN. See the multi-timeframe guide for alignment and interval-format
124
+ * details.
125
+ *
126
+ * @since 0.4
127
+ * @stable
128
+ * @example
129
+ * // weekly EMA(20) — computed over weekly bars, drawn on the chart
130
+ * const trend = request.security({ interval: "1W" }, (bar) => ta.ema(bar.close, 20));
131
+ * plot(trend, { title: "Weekly EMA(20)" });
132
+ * @example
133
+ * // data form — aligned weekly close
134
+ * const weekly = request.security({ interval: "1W" });
135
+ * plot(weekly.close, { title: "Weekly close" });
136
+ * @example
137
+ * // different symbol — a ratio against another instrument (needs multiSymbol)
138
+ * const spy = request.security({ symbol: "AMEX:SPY", interval: "1D" });
139
+ * const qqq = request.security({ symbol: "NASDAQ:QQQ", interval: "1D" });
140
+ * plot(spy.close.current / qqq.close.current, { title: "SPY/QQQ" });
141
+ */
142
+ declare function security(opts: RequestSecurityOpts): SecurityBar;
143
+ declare function security(opts: RequestSecurityOpts, expr: SecurityExpr): Series<number>;
144
+ /**
145
+ * Read **lower**-timeframe bars contained by each main-stream bar. The
146
+ * result is a `Series<ReadonlyArray<Bar>>` — for every main bar, the array
147
+ * of finer-grained bars that fall inside it (an empty frozen array for
148
+ * out-of-range or unsupported reads). The requested `interval` must be a
149
+ * compile-time literal and **strictly lower** than the chart interval; an
150
+ * equal-or-higher ordering is rejected at compile time with
151
+ * `lower-tf-not-lower` when statically known. Like `request.security`, it
152
+ * degrades to empty arrays when the adapter lacks
153
+ * `Capabilities.multiTimeframe`. See the multi-timeframe guide for the
154
+ * contained-bar model and interval format.
155
+ *
156
+ * @since 0.6
157
+ * @stable
158
+ * @example
159
+ * // Each main bar carries the array of intrabar 30-second candles.
160
+ * const intrabar = request.lowerTf({ interval: "30s" });
161
+ * const count = intrabar.current.length;
162
+ * void count;
163
+ */
164
+ declare function lowerTf(_opts: RequestLowerTfOpts): Series<ReadonlyArray<Bar>>;
61
165
  /**
62
166
  * `request.*` namespace for secondary timeframe reads. The compiler walks
63
167
  * `request.security(...)` calls to populate `manifest.requestedIntervals`;
@@ -71,26 +175,8 @@ export type SecurityBar = Readonly<{
71
175
  * void ns;
72
176
  */
73
177
  export declare const request: Readonly<{
74
- /**
75
- * Read a secondary candle stream at a script-author-fixed interval.
76
- *
77
- * @since 0.4
78
- * @stable
79
- * @example
80
- * const fn: typeof request.security = request.security;
81
- * void fn;
82
- */
83
- security(_opts: RequestSecurityOpts): SecurityBar;
84
- /**
85
- * Read lower-timeframe bars contained by each main-stream bar.
86
- *
87
- * @since 0.6
88
- * @stable
89
- * @example
90
- * const fn: typeof request.lowerTf = request.lowerTf;
91
- * void fn;
92
- */
93
- lowerTf(_opts: RequestLowerTfOpts): Series<ReadonlyArray<Bar>>;
178
+ security: typeof security;
179
+ lowerTf: typeof lowerTf;
94
180
  }>;
95
181
  /**
96
182
  * Static type of the `request` namespace. Runtime implementations satisfy
@@ -103,4 +189,5 @@ export declare const request: Readonly<{
103
189
  * void ns;
104
190
  */
105
191
  export type RequestNamespace = typeof request;
192
+ export {};
106
193
  //# sourceMappingURL=request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/request/request.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC,CAAC;AAMH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO;IAChB;;;;;;;;OAQG;oBACa,mBAAmB,GAAG,WAAW;IAGjD;;;;;;;;OAQG;mBACY,kBAAkB,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;EAGhE,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/request/request.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACvC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;AAMzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW,CAAC;AAC1D,iBAAS,QAAQ,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AAKjF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,iBAAS,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAEtE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO;;;EAAuC,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC"}
@@ -3,6 +3,32 @@
3
3
  const sentinel = (name) => {
4
4
  throw new Error(`${name} called outside an active script step`);
5
5
  };
6
+ function security(_opts, _expr) {
7
+ return sentinel("request.security");
8
+ }
9
+ /**
10
+ * Read **lower**-timeframe bars contained by each main-stream bar. The
11
+ * result is a `Series<ReadonlyArray<Bar>>` — for every main bar, the array
12
+ * of finer-grained bars that fall inside it (an empty frozen array for
13
+ * out-of-range or unsupported reads). The requested `interval` must be a
14
+ * compile-time literal and **strictly lower** than the chart interval; an
15
+ * equal-or-higher ordering is rejected at compile time with
16
+ * `lower-tf-not-lower` when statically known. Like `request.security`, it
17
+ * degrades to empty arrays when the adapter lacks
18
+ * `Capabilities.multiTimeframe`. See the multi-timeframe guide for the
19
+ * contained-bar model and interval format.
20
+ *
21
+ * @since 0.6
22
+ * @stable
23
+ * @example
24
+ * // Each main bar carries the array of intrabar 30-second candles.
25
+ * const intrabar = request.lowerTf({ interval: "30s" });
26
+ * const count = intrabar.current.length;
27
+ * void count;
28
+ */
29
+ function lowerTf(_opts) {
30
+ return sentinel("request.lowerTf");
31
+ }
6
32
  /**
7
33
  * `request.*` namespace for secondary timeframe reads. The compiler walks
8
34
  * `request.security(...)` calls to populate `manifest.requestedIntervals`;
@@ -15,30 +41,5 @@ const sentinel = (name) => {
15
41
  * const ns: typeof request = request;
16
42
  * void ns;
17
43
  */
18
- export const request = Object.freeze({
19
- /**
20
- * Read a secondary candle stream at a script-author-fixed interval.
21
- *
22
- * @since 0.4
23
- * @stable
24
- * @example
25
- * const fn: typeof request.security = request.security;
26
- * void fn;
27
- */
28
- security(_opts) {
29
- return sentinel("request.security");
30
- },
31
- /**
32
- * Read lower-timeframe bars contained by each main-stream bar.
33
- *
34
- * @since 0.6
35
- * @stable
36
- * @example
37
- * const fn: typeof request.lowerTf = request.lowerTf;
38
- * void fn;
39
- */
40
- lowerTf(_opts) {
41
- return sentinel("request.lowerTf");
42
- },
43
- });
44
+ export const request = Object.freeze({ security, lowerTf });
44
45
  //# sourceMappingURL=request.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request/request.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAkE/D,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAS,EAAE;IACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,CAAC,CAAC;AACpE,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAA0B;QAC/B,OAAO,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACxC,CAAC;IACD;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAyB;QAC7B,OAAO,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;CACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Bar, Price, Series, Time, Volume } from \"../types.js\";\n\n/**\n * Argument to {@link request.security}. The `interval` must be a string\n * literal or an `input.enum` value; the compiler's literal-only pass rejects\n * dynamic expressions with `request-security-interval-not-literal`.\n *\n * @since 0.4\n * @stable\n * @example\n * const opts: RequestSecurityOpts = { interval: \"1D\" };\n * void opts;\n */\nexport type RequestSecurityOpts = Readonly<{\n readonly interval: string;\n}>;\n\n/**\n * Argument to {@link request.lowerTf}. The `interval` must be strictly lower\n * than the script's main interval; invalid orderings are rejected by the\n * compiler's `lower-tf-not-lower` diagnostic when statically known.\n *\n * @since 0.6\n * @stable\n * @example\n * const opts: RequestLowerTfOpts = { interval: \"30s\" };\n * void opts;\n */\nexport type RequestLowerTfOpts = Readonly<{\n readonly interval: string;\n}>;\n\n/**\n * Secondary-stream bar returned by {@link request.security}. Each field is a\n * `Series<...>` aligned from the runtime's secondary-stream ring buffer to\n * the current main stream, or by the all-NaN fallback when\n * `Capabilities.multiTimeframe` is `false`, the interval is unsupported, or\n * the host fails to register the secondary stream.\n *\n * This is intentionally a series-shaped view rather than the scalar\n * {@link Bar} shape so scripts can read historical secondary values aligned\n * to main bars, such as `daily.close[5]`.\n *\n * @since 0.4\n * @stable\n * @example\n * const close: SecurityBar[\"close\"] = { current: 1, length: 1 };\n * void close;\n */\nexport type SecurityBar = Readonly<{\n readonly time: Series<Time>;\n readonly open: Series<Price>;\n readonly high: Series<Price>;\n readonly low: Series<Price>;\n readonly close: Series<Price>;\n readonly volume: Series<Volume>;\n readonly hl2: Series<Price>;\n readonly hlc3: Series<Price>;\n readonly ohlc4: Series<Price>;\n readonly hlcc4: Series<Price>;\n readonly symbol: Series<string>;\n readonly interval: Series<string>;\n}>;\n\nconst sentinel = (name: string): never => {\n throw new Error(`${name} called outside an active script step`);\n};\n\n/**\n * `request.*` namespace for secondary timeframe reads. The compiler walks\n * `request.security(...)` calls to populate `manifest.requestedIntervals`;\n * the runtime replaces this callable hole with a slot-aware implementation\n * through `ComputeContext.request`.\n *\n * @since 0.4\n * @stable\n * @example\n * const ns: typeof request = request;\n * void ns;\n */\nexport const request = Object.freeze({\n /**\n * Read a secondary candle stream at a script-author-fixed interval.\n *\n * @since 0.4\n * @stable\n * @example\n * const fn: typeof request.security = request.security;\n * void fn;\n */\n security(_opts: RequestSecurityOpts): SecurityBar {\n return sentinel(\"request.security\");\n },\n /**\n * Read lower-timeframe bars contained by each main-stream bar.\n *\n * @since 0.6\n * @stable\n * @example\n * const fn: typeof request.lowerTf = request.lowerTf;\n * void fn;\n */\n lowerTf(_opts: RequestLowerTfOpts): Series<ReadonlyArray<Bar>> {\n return sentinel(\"request.lowerTf\");\n },\n});\n\n/**\n * Static type of the `request` namespace. Runtime implementations satisfy\n * this shape structurally when installed on `ComputeContext.request`.\n *\n * @since 0.4\n * @stable\n * @example\n * const ns: RequestNamespace = request;\n * void ns;\n */\nexport type RequestNamespace = typeof request;\n"]}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request/request.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAwG/D,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAS,EAAE;IACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,CAAC,CAAC;AACpE,CAAC,CAAC;AAgDF,SAAS,QAAQ,CAAC,KAA0B,EAAE,KAAoB;IAC9D,OAAO,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,OAAO,CAAC,KAAyB;IACtC,OAAO,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Bar, Price, Series, Time, Volume } from \"../types.js\";\n\n/**\n * Argument to {@link request.security}. The `interval` must be a string\n * literal or an `input.enum` value; the compiler's literal-only pass rejects\n * dynamic expressions with `request-security-interval-not-literal`.\n *\n * @since 0.4\n * @stable\n * @example\n * const opts: RequestSecurityOpts = { interval: \"1D\" };\n * void opts;\n * @example\n * // read a different instrument (requires Capabilities.multiSymbol)\n * const spy: RequestSecurityOpts = { symbol: \"AMEX:SPY\", interval: \"1D\" };\n * void spy;\n */\nexport type RequestSecurityOpts = Readonly<{\n /**\n * The instrument to read. Omit for the chart's own symbol (the existing\n * behavior). Must be a compile-time literal — a string literal, an\n * `input.symbol` default, or an `input.enum` value; the compiler's\n * literal-only pass rejects a dynamic expression with\n * `request-security-symbol-not-literal`. A non-chart symbol additionally\n * requires `Capabilities.multiSymbol`; otherwise the series degrades to\n * all-NaN.\n *\n * @since 1.2\n */\n readonly symbol?: string;\n readonly interval: string;\n}>;\n\n/**\n * Argument to {@link request.lowerTf}. The `interval` must be strictly lower\n * than the script's main interval; invalid orderings are rejected by the\n * compiler's `lower-tf-not-lower` diagnostic when statically known.\n *\n * @since 0.6\n * @stable\n * @example\n * const opts: RequestLowerTfOpts = { interval: \"30s\" };\n * void opts;\n */\nexport type RequestLowerTfOpts = Readonly<{\n readonly interval: string;\n}>;\n\n/**\n * Secondary-stream bar returned by {@link request.security}. Each field is a\n * `Series<...>` aligned from the runtime's secondary-stream ring buffer to\n * the current main stream, or by the all-NaN fallback when\n * `Capabilities.multiTimeframe` is `false`, the interval is unsupported, or\n * the host fails to register the secondary stream.\n *\n * This is intentionally a series-shaped view rather than the scalar\n * {@link Bar} shape so scripts can read historical secondary values aligned\n * to main bars, such as `daily.close[5]`.\n *\n * @since 0.4\n * @stable\n * @example\n * const close: SecurityBar[\"close\"] = { current: 1, length: 1 };\n * void close;\n */\nexport type SecurityBar = Readonly<{\n readonly time: Series<Time>;\n readonly open: Series<Price>;\n readonly high: Series<Price>;\n readonly low: Series<Price>;\n readonly close: Series<Price>;\n readonly volume: Series<Volume>;\n readonly hl2: Series<Price>;\n readonly hlc3: Series<Price>;\n readonly ohlc4: Series<Price>;\n readonly hlcc4: Series<Price>;\n readonly symbol: Series<string>;\n readonly interval: Series<string>;\n}>;\n\n/**\n * A higher-timeframe expression callback for {@link RequestNamespace.security}.\n * Receives the HTF {@link SecurityBar} (OHLCV series on the secondary\n * stream's own clock) and returns the value to evaluate per HTF bar.\n * The body may reference only the `bar` parameter, the ambient `ta`\n * namespace, `inputs`, safe `Math.*` globals, and literal constants —\n * capturing any other outer binding is a compile error\n * (`request-security-expr-captures-local`).\n *\n * Returning a `Series<number>` (e.g. `(bar) => ta.ema(bar.close, 20)`)\n * lets `ta.*` accumulate over HTF bars; returning a bare `number`\n * (e.g. `(bar) => bar.close.current * 2`) samples the scalar once per\n * HTF bar. Either way the result aligns no-lookahead to the main timeline.\n *\n * @since 0.7\n * @stable\n * @example\n * const trend: SecurityExpr = (bar) => bar.close;\n * void trend;\n */\nexport type SecurityExpr = (bar: SecurityBar) => Series<number> | number;\n\nconst sentinel = (name: string): never => {\n throw new Error(`${name} called outside an active script step`);\n};\n\n/**\n * Read a secondary candle stream at a script-author-fixed **higher**\n * interval. Two forms:\n *\n * - **Data**: `request.security({ interval })` → a `SecurityBar`.\n * Every OHLCV field — plus the derived `hl2` / `hlc3` / `ohlc4` /\n * `hlcc4` and `symbol` / `interval` — is a `Series<...>` aligned\n * no-lookahead to the chart's bars, so a script can read prior secondary\n * values such as `weekly.close[5]`.\n * - **Expression**: `request.security({ interval }, (bar) => …)` →\n * `Series<number>`. The callback runs **on the higher-timeframe clock**\n * (once per HTF bar), so `ta.*` inside it accumulate over HTF bars; the\n * result is aligned no-lookahead down to the main timeline. This is the\n * only correct way to get a \"weekly EMA(20)\" — the data form's series is\n * clocked to the main timeline, so `ta.ema(weekly.close, 20)` would\n * average 20 *main* bars.\n *\n * Both `symbol` and `interval` must be compile-time literals (a string\n * literal, an `input.symbol` default, or an `input.enum` value); the compiler\n * walks every call to populate `manifest.requestedFeeds` (and the main-symbol\n * projection `manifest.requestedIntervals`). `symbol` is **optional** —\n * omitting it reads the chart's own symbol (the higher-timeframe-only case).\n * When the adapter does not advertise `Capabilities.multiTimeframe`, the\n * series degrades to all-NaN rather than erroring; a non-chart `symbol`\n * additionally requires `Capabilities.multiSymbol` and otherwise degrades to\n * all-NaN. See the multi-timeframe guide for alignment and interval-format\n * details.\n *\n * @since 0.4\n * @stable\n * @example\n * // weekly EMA(20) computed over weekly bars, drawn on the chart\n * const trend = request.security({ interval: \"1W\" }, (bar) => ta.ema(bar.close, 20));\n * plot(trend, { title: \"Weekly EMA(20)\" });\n * @example\n * // data form aligned weekly close\n * const weekly = request.security({ interval: \"1W\" });\n * plot(weekly.close, { title: \"Weekly close\" });\n * @example\n * // different symbol — a ratio against another instrument (needs multiSymbol)\n * const spy = request.security({ symbol: \"AMEX:SPY\", interval: \"1D\" });\n * const qqq = request.security({ symbol: \"NASDAQ:QQQ\", interval: \"1D\" });\n * plot(spy.close.current / qqq.close.current, { title: \"SPY/QQQ\" });\n */\nfunction security(opts: RequestSecurityOpts): SecurityBar;\nfunction security(opts: RequestSecurityOpts, expr: SecurityExpr): Series<number>;\nfunction security(_opts: RequestSecurityOpts, _expr?: SecurityExpr): SecurityBar | Series<number> {\n return sentinel(\"request.security\");\n}\n\n/**\n * Read **lower**-timeframe bars contained by each main-stream bar. The\n * result is a `Series<ReadonlyArray<Bar>>` — for every main bar, the array\n * of finer-grained bars that fall inside it (an empty frozen array for\n * out-of-range or unsupported reads). The requested `interval` must be a\n * compile-time literal and **strictly lower** than the chart interval; an\n * equal-or-higher ordering is rejected at compile time with\n * `lower-tf-not-lower` when statically known. Like `request.security`, it\n * degrades to empty arrays when the adapter lacks\n * `Capabilities.multiTimeframe`. See the multi-timeframe guide for the\n * contained-bar model and interval format.\n *\n * @since 0.6\n * @stable\n * @example\n * // Each main bar carries the array of intrabar 30-second candles.\n * const intrabar = request.lowerTf({ interval: \"30s\" });\n * const count = intrabar.current.length;\n * void count;\n */\nfunction lowerTf(_opts: RequestLowerTfOpts): Series<ReadonlyArray<Bar>> {\n return sentinel(\"request.lowerTf\");\n}\n\n/**\n * `request.*` namespace for secondary timeframe reads. The compiler walks\n * `request.security(...)` calls to populate `manifest.requestedIntervals`;\n * the runtime replaces this callable hole with a slot-aware implementation\n * through `ComputeContext.request`.\n *\n * @since 0.4\n * @stable\n * @example\n * const ns: typeof request = request;\n * void ns;\n */\nexport const request = Object.freeze({ security, lowerTf });\n\n/**\n * Static type of the `request` namespace. Runtime implementations satisfy\n * this shape structurally when installed on `ComputeContext.request`.\n *\n * @since 0.4\n * @stable\n * @example\n * const ns: RequestNamespace = request;\n * void ns;\n */\nexport type RequestNamespace = typeof request;\n"]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Script-facing handle on a persistent, bounded **FIFO collection** —
3
+ * Pine's `var array<…>` with capacity eviction. Unlike {@link MutableSlot}
4
+ * (one value's history) or a `Series` (bar-indexed history), this is a
5
+ * **collection** you push many values into: `push` appends (evicting the
6
+ * oldest once `capacity` is reached), `get(n)` reads the `n`-th element from
7
+ * the newest (`n = 0`), `last()` is the newest, `size` is the current filled
8
+ * count, `capacity` is the fixed bound, and `clear()` empties it.
9
+ *
10
+ * The collection persists across bars with `state.*` committed/tentative
11
+ * semantics: pushes during a tick are tentative and discarded if a later
12
+ * tick replaces the head bar; on bar close they commit. `capacity` is a
13
+ * required compile-time numeric literal so the store is bounded and
14
+ * snapshot-clean.
15
+ *
16
+ * Out-of-range `get(n)` returns the element type's empty value (`NaN` for
17
+ * `number`); it never throws. This is **not** number-coercible — there is no
18
+ * `+a` / `valueOf`; it is a collection, not a value.
19
+ *
20
+ * @since 1.3
21
+ * @stable
22
+ * @example
23
+ * function rollingMean(a: MutableArraySlot<number>, x: number): number {
24
+ * a.push(x);
25
+ * let sum = 0;
26
+ * for (let i = 0; i < a.size; i++) sum += a.get(i);
27
+ * return sum / a.size;
28
+ * }
29
+ */
30
+ export type MutableArraySlot<T> = {
31
+ push(value: T): void;
32
+ get(n: number): T;
33
+ last(): T;
34
+ clear(): void;
35
+ readonly size: number;
36
+ readonly capacity: number;
37
+ };
38
+ //# sourceMappingURL=arraySlot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arraySlot.d.ts","sourceRoot":"","sources":["../../src/state/arraySlot.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IAClB,IAAI,IAAI,CAAC,CAAC;IACV,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ export {};
4
+ //# sourceMappingURL=arraySlot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arraySlot.js","sourceRoot":"","sources":["../../src/state/arraySlot.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\n/**\n * Script-facing handle on a persistent, bounded **FIFO collection** —\n * Pine's `var array<…>` with capacity eviction. Unlike {@link MutableSlot}\n * (one value's history) or a `Series` (bar-indexed history), this is a\n * **collection** you push many values into: `push` appends (evicting the\n * oldest once `capacity` is reached), `get(n)` reads the `n`-th element from\n * the newest (`n = 0`), `last()` is the newest, `size` is the current filled\n * count, `capacity` is the fixed bound, and `clear()` empties it.\n *\n * The collection persists across bars with `state.*` committed/tentative\n * semantics: pushes during a tick are tentative and discarded if a later\n * tick replaces the head bar; on bar close they commit. `capacity` is a\n * required compile-time numeric literal so the store is bounded and\n * snapshot-clean.\n *\n * Out-of-range `get(n)` returns the element type's empty value (`NaN` for\n * `number`); it never throws. This is **not** number-coercible — there is no\n * `+a` / `valueOf`; it is a collection, not a value.\n *\n * @since 1.3\n * @stable\n * @example\n * function rollingMean(a: MutableArraySlot<number>, x: number): number {\n * a.push(x);\n * let sum = 0;\n * for (let i = 0; i < a.size; i++) sum += a.get(i);\n * return sum / a.size;\n * }\n */\nexport type MutableArraySlot<T> = {\n push(value: T): void;\n get(n: number): T;\n last(): T;\n clear(): void;\n readonly size: number;\n readonly capacity: number;\n};\n"]}
@@ -1,5 +1,6 @@
1
1
  export { state } from "./state.js";
2
2
  export type { StateNamespace } from "./state.js";
3
+ export type { MutableArraySlot } from "./arraySlot.js";
3
4
  export type { MutableSlot } from "./mutableSlot.js";
4
5
  export type { RunnerSnapshot, StateSnapshot, StateStoreKey, StreamSnapshot, } from "./snapshot.js";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EACR,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,GACjB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EACR,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,GACjB,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nexport { state } from \"./state.js\";\nexport type { StateNamespace } from \"./state.js\";\nexport type { MutableSlot } from \"./mutableSlot.js\";\nexport type {\n RunnerSnapshot,\n StateSnapshot,\n StateStoreKey,\n StreamSnapshot,\n} from \"./snapshot.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nexport { state } from \"./state.js\";\nexport type { StateNamespace } from \"./state.js\";\nexport type { MutableArraySlot } from \"./arraySlot.js\";\nexport type { MutableSlot } from \"./mutableSlot.js\";\nexport type {\n RunnerSnapshot,\n StateSnapshot,\n StateStoreKey,\n StreamSnapshot,\n} from \"./snapshot.js\";\n"]}
@@ -1,3 +1,5 @@
1
+ import type { NumberSeriesSlot } from "../types.js";
2
+ import type { MutableArraySlot } from "./arraySlot.js";
1
3
  import type { MutableSlot } from "./mutableSlot.js";
2
4
  /**
3
5
  * Persistent state slots, Pine `var` semantics. Writes during a tick are
@@ -55,6 +57,40 @@ export declare const state: Readonly<{
55
57
  * void fn;
56
58
  */
57
59
  string(_init: string): MutableSlot<string>;
60
+ /**
61
+ * Allocate or read a persistent **series** slot — a writable, indexable
62
+ * number history. `s.value = expr` writes the current bar's value;
63
+ * `s[0]` / `s.current` / `+s` read it back, `s[1]` reads one bar ago.
64
+ * The allocation bar's pre-write head is seeded with `init`; unwritten later
65
+ * bars and out-of-range history reads are `NaN`. Unlike `state.float`, the
66
+ * slot retains a bounded window of prior committed values (sized to the
67
+ * script's deepest literal `s[n]` lookback).
68
+ *
69
+ * @since 1.3
70
+ * @stable
71
+ * @example
72
+ * const fn: typeof state.series = state.series;
73
+ * void fn;
74
+ */
75
+ series(_init: number): NumberSeriesSlot;
76
+ /**
77
+ * Allocate or read a persistent **bounded collection** slot — a
78
+ * fixed-capacity FIFO ring you push values into across bars. `a.push(v)`
79
+ * appends (evicting the oldest once full); `a.get(n)` reads the `n`-th
80
+ * element from the newest; `a.last()` is the newest; `a.size` is the
81
+ * filled count; `a.capacity` is the bound; `a.clear()` empties it.
82
+ * `capacity` must be a compile-time numeric literal (the slot is bounded
83
+ * so it serializes). Unlike {@link state}.series (one value's bar-indexed
84
+ * history), this is a collection of many pushed values. v1 supports
85
+ * `number` element type.
86
+ *
87
+ * @since 1.3
88
+ * @stable
89
+ * @example
90
+ * const fn: typeof state.array = state.array;
91
+ * void fn;
92
+ */
93
+ array<T>(_capacity: number): MutableArraySlot<T>;
58
94
  /**
59
95
  * Tick-persistent state slots, Pine `varip` semantics. Writes commit
60
96
  * immediately, even during a tick.
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMpD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK;IACd;;;;;;;;OAQG;iBACU,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAIzC;;;;;;;;OAQG;eACQ,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAIvC;;;;;;;;OAQG;gBACS,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;IAI1C;;;;;;;;OAQG;kBACW,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAI1C;;;;;;;;;OASG;;qBAEc,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;mBAG9B,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBAG3B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;sBAG5B,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;;EAIhD,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,KAAK,CAAC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMpD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK;IACd;;;;;;;;OAQG;iBACU,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAIzC;;;;;;;;OAQG;eACQ,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAIvC;;;;;;;;OAQG;gBACS,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;IAI1C;;;;;;;;OAQG;kBACW,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAI1C;;;;;;;;;;;;;;OAcG;kBACW,MAAM,GAAG,gBAAgB;IAIvC;;;;;;;;;;;;;;;;OAgBG;UACG,CAAC,aAAa,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAIhD;;;;;;;;;OASG;;qBAEc,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;mBAG9B,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;oBAG3B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;sBAG5B,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;;EAIhD,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,KAAK,CAAC"}
@@ -67,6 +67,44 @@ export const state = Object.freeze({
67
67
  string(_init) {
68
68
  return sentinel("state.string");
69
69
  },
70
+ /**
71
+ * Allocate or read a persistent **series** slot — a writable, indexable
72
+ * number history. `s.value = expr` writes the current bar's value;
73
+ * `s[0]` / `s.current` / `+s` read it back, `s[1]` reads one bar ago.
74
+ * The allocation bar's pre-write head is seeded with `init`; unwritten later
75
+ * bars and out-of-range history reads are `NaN`. Unlike `state.float`, the
76
+ * slot retains a bounded window of prior committed values (sized to the
77
+ * script's deepest literal `s[n]` lookback).
78
+ *
79
+ * @since 1.3
80
+ * @stable
81
+ * @example
82
+ * const fn: typeof state.series = state.series;
83
+ * void fn;
84
+ */
85
+ series(_init) {
86
+ return sentinel("state.series");
87
+ },
88
+ /**
89
+ * Allocate or read a persistent **bounded collection** slot — a
90
+ * fixed-capacity FIFO ring you push values into across bars. `a.push(v)`
91
+ * appends (evicting the oldest once full); `a.get(n)` reads the `n`-th
92
+ * element from the newest; `a.last()` is the newest; `a.size` is the
93
+ * filled count; `a.capacity` is the bound; `a.clear()` empties it.
94
+ * `capacity` must be a compile-time numeric literal (the slot is bounded
95
+ * so it serializes). Unlike {@link state}.series (one value's bar-indexed
96
+ * history), this is a collection of many pushed values. v1 supports
97
+ * `number` element type.
98
+ *
99
+ * @since 1.3
100
+ * @stable
101
+ * @example
102
+ * const fn: typeof state.array = state.array;
103
+ * void fn;
104
+ */
105
+ array(_capacity) {
106
+ return sentinel("state.array");
107
+ },
70
108
  /**
71
109
  * Tick-persistent state slots, Pine `varip` semantics. Writes commit
72
110
  * immediately, even during a tick.