@invinite-org/chartlang-runtime 1.2.0 → 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 (114) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/buildComputeContext.d.ts.map +1 -1
  3. package/dist/buildComputeContext.js +6 -1
  4. package/dist/buildComputeContext.js.map +1 -1
  5. package/dist/createScriptRunner.d.ts.map +1 -1
  6. package/dist/createScriptRunner.js +37 -7
  7. package/dist/createScriptRunner.js.map +1 -1
  8. package/dist/dep/DepRunner.d.ts +7 -0
  9. package/dist/dep/DepRunner.d.ts.map +1 -1
  10. package/dist/dep/DepRunner.js +3 -0
  11. package/dist/dep/DepRunner.js.map +1 -1
  12. package/dist/emit/barcolor.d.ts +44 -0
  13. package/dist/emit/barcolor.d.ts.map +1 -0
  14. package/dist/emit/barcolor.js +40 -0
  15. package/dist/emit/barcolor.js.map +1 -0
  16. package/dist/emit/bgcolor.d.ts +44 -0
  17. package/dist/emit/bgcolor.d.ts.map +1 -0
  18. package/dist/emit/bgcolor.js +45 -0
  19. package/dist/emit/bgcolor.js.map +1 -0
  20. package/dist/emit/index.d.ts +2 -0
  21. package/dist/emit/index.d.ts.map +1 -1
  22. package/dist/emit/index.js +2 -0
  23. package/dist/emit/index.js.map +1 -1
  24. package/dist/emit/plot.d.ts +23 -1
  25. package/dist/emit/plot.d.ts.map +1 -1
  26. package/dist/emit/plot.js +32 -1
  27. package/dist/emit/plot.js.map +1 -1
  28. package/dist/execution/dispose.d.ts.map +1 -1
  29. package/dist/execution/dispose.js +3 -1
  30. package/dist/execution/dispose.js.map +1 -1
  31. package/dist/execution/runComputeStep.d.ts.map +1 -1
  32. package/dist/execution/runComputeStep.js +3 -1
  33. package/dist/execution/runComputeStep.js.map +1 -1
  34. package/dist/inputs/resolveInputs.js +1 -0
  35. package/dist/inputs/resolveInputs.js.map +1 -1
  36. package/dist/persistentStateStore.runtime.d.ts.map +1 -1
  37. package/dist/persistentStateStore.runtime.js +10 -5
  38. package/dist/persistentStateStore.runtime.js.map +1 -1
  39. package/dist/primitives.d.ts +1 -1
  40. package/dist/primitives.d.ts.map +1 -1
  41. package/dist/primitives.js +7 -1
  42. package/dist/primitives.js.map +1 -1
  43. package/dist/request/lowerTf.d.ts.map +1 -1
  44. package/dist/request/lowerTf.js +6 -0
  45. package/dist/request/lowerTf.js.map +1 -1
  46. package/dist/request/requestNamespace.d.ts.map +1 -1
  47. package/dist/request/requestNamespace.js +17 -3
  48. package/dist/request/requestNamespace.js.map +1 -1
  49. package/dist/request/security.d.ts +23 -6
  50. package/dist/request/security.d.ts.map +1 -1
  51. package/dist/request/security.js +64 -29
  52. package/dist/request/security.js.map +1 -1
  53. package/dist/request/securityExprRunner.d.ts +12 -8
  54. package/dist/request/securityExprRunner.d.ts.map +1 -1
  55. package/dist/request/securityExprRunner.js +32 -14
  56. package/dist/request/securityExprRunner.js.map +1 -1
  57. package/dist/ringBuffer.d.ts +19 -0
  58. package/dist/ringBuffer.d.ts.map +1 -1
  59. package/dist/ringBuffer.js +23 -0
  60. package/dist/ringBuffer.js.map +1 -1
  61. package/dist/runtimeContext.d.ts +49 -12
  62. package/dist/runtimeContext.d.ts.map +1 -1
  63. package/dist/runtimeContext.js.map +1 -1
  64. package/dist/state/arrayPersistence.d.ts +48 -0
  65. package/dist/state/arrayPersistence.d.ts.map +1 -0
  66. package/dist/state/arrayPersistence.js +88 -0
  67. package/dist/state/arrayPersistence.js.map +1 -0
  68. package/dist/state/arrayStateSlot.d.ts +78 -0
  69. package/dist/state/arrayStateSlot.d.ts.map +1 -0
  70. package/dist/state/arrayStateSlot.js +116 -0
  71. package/dist/state/arrayStateSlot.js.map +1 -0
  72. package/dist/state/index.d.ts +3 -1
  73. package/dist/state/index.d.ts.map +1 -1
  74. package/dist/state/index.js +3 -1
  75. package/dist/state/index.js.map +1 -1
  76. package/dist/state/lifecycle.d.ts +28 -0
  77. package/dist/state/lifecycle.d.ts.map +1 -1
  78. package/dist/state/lifecycle.js +36 -0
  79. package/dist/state/lifecycle.js.map +1 -1
  80. package/dist/state/stateNamespace.d.ts.map +1 -1
  81. package/dist/state/stateNamespace.js +27 -0
  82. package/dist/state/stateNamespace.js.map +1 -1
  83. package/dist/ta/sessionVolumeProfile.d.ts.map +1 -1
  84. package/dist/ta/sessionVolumeProfile.js +1 -17
  85. package/dist/ta/sessionVolumeProfile.js.map +1 -1
  86. package/dist/time-accessors/civil.d.ts +73 -0
  87. package/dist/time-accessors/civil.d.ts.map +1 -0
  88. package/dist/time-accessors/civil.js +105 -0
  89. package/dist/time-accessors/civil.js.map +1 -0
  90. package/dist/time-accessors/index.d.ts +8 -0
  91. package/dist/time-accessors/index.d.ts.map +1 -0
  92. package/dist/time-accessors/index.js +9 -0
  93. package/dist/time-accessors/index.js.map +1 -0
  94. package/dist/time-accessors/sessionAccessors.d.ts +50 -0
  95. package/dist/time-accessors/sessionAccessors.d.ts.map +1 -0
  96. package/dist/time-accessors/sessionAccessors.js +79 -0
  97. package/dist/time-accessors/sessionAccessors.js.map +1 -0
  98. package/dist/time-accessors/sessionWindow.d.ts +17 -0
  99. package/dist/time-accessors/sessionWindow.d.ts.map +1 -0
  100. package/dist/time-accessors/sessionWindow.js +41 -0
  101. package/dist/time-accessors/sessionWindow.js.map +1 -0
  102. package/dist/time-accessors/timeAccessors.d.ts +54 -0
  103. package/dist/time-accessors/timeAccessors.d.ts.map +1 -0
  104. package/dist/time-accessors/timeAccessors.js +132 -0
  105. package/dist/time-accessors/timeAccessors.js.map +1 -0
  106. package/dist/time-accessors/tzDiagnostic.d.ts +17 -0
  107. package/dist/time-accessors/tzDiagnostic.d.ts.map +1 -0
  108. package/dist/time-accessors/tzDiagnostic.js +34 -0
  109. package/dist/time-accessors/tzDiagnostic.js.map +1 -0
  110. package/dist/time-accessors/tzOffset.d.ts +31 -0
  111. package/dist/time-accessors/tzOffset.d.ts.map +1 -0
  112. package/dist/time-accessors/tzOffset.js +67 -0
  113. package/dist/time-accessors/tzOffset.js.map +1 -0
  114. package/package.json +3 -3
@@ -0,0 +1,40 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ import { ACTIVE_RUNTIME_CONTEXT } from "../runtimeContext.js";
4
+ import { plotImpl } from "./plot.js";
5
+ const OUTSIDE_CTX_MESSAGE = "barcolor called outside an active script step";
6
+ /**
7
+ * Lower a `barcolor(color, opts?)` call to the `PlotOpts` a verbose
8
+ * `plot(NaN, { style: { kind: "bar-color", color }, title })` would carry. The
9
+ * static `bar-color` style still carries the color (fallback for adapters
10
+ * that ignore the dynamic channel); the live per-bar color is additionally
11
+ * routed to {@link plotImpl}'s `dynamicColor` arg so it rides the wire as
12
+ * `PlotEmission.colorValue`. The `bar-color` style carries no transparency, so
13
+ * only `title` is spread conditionally (omitted ⇒ absent on the wire).
14
+ */
15
+ function barColorOpts(color, opts) {
16
+ return {
17
+ style: { kind: "bar-color", color },
18
+ ...(opts.title === undefined ? {} : { title: opts.title }),
19
+ };
20
+ }
21
+ /**
22
+ * Implementation signature for {@link barcolor}. Branches on
23
+ * `typeof arg1 === "string"` to dispatch the script-facing vs
24
+ * compiler-injected overload.
25
+ *
26
+ * @since 1.4
27
+ * @example
28
+ * // const fn: typeof barcolor = barcolor;
29
+ * // void fn;
30
+ */
31
+ export function barcolor(arg1, arg2, arg3) {
32
+ if (typeof arg1 !== "string" || typeof arg2 !== "string") {
33
+ throw new Error(OUTSIDE_CTX_MESSAGE);
34
+ }
35
+ const ctx = ACTIVE_RUNTIME_CONTEXT.current;
36
+ if (!ctx)
37
+ throw new Error(OUTSIDE_CTX_MESSAGE);
38
+ plotImpl(ctx, arg1, Number.NaN, barColorOpts(arg2, arg3 ?? {}), arg2);
39
+ }
40
+ //# sourceMappingURL=barcolor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barcolor.js","sourceRoot":"","sources":["../../src/emit/barcolor.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,mBAAmB,GAAG,+CAA+C,CAAC;AAE5E;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,KAAY,EAAE,IAAkB;IAClD,OAAO;QACH,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE;QACnC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;KAC7D,CAAC;AACN,CAAC;AA4CD;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CACpB,IAAoB,EACpB,IAA2B,EAC3B,IAAmB;IAEnB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,GAAG,GAAG,sBAAsB,CAAC,OAAO,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC/C,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1E,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 { BarColorOpts, Color, PlotOpts } from \"@invinite-org/chartlang-core\";\n\nimport { ACTIVE_RUNTIME_CONTEXT } from \"../runtimeContext.js\";\nimport { plotImpl } from \"./plot.js\";\n\nconst OUTSIDE_CTX_MESSAGE = \"barcolor called outside an active script step\";\n\n/**\n * Lower a `barcolor(color, opts?)` call to the `PlotOpts` a verbose\n * `plot(NaN, { style: { kind: \"bar-color\", color }, title })` would carry. The\n * static `bar-color` style still carries the color (fallback for adapters\n * that ignore the dynamic channel); the live per-bar color is additionally\n * routed to {@link plotImpl}'s `dynamicColor` arg so it rides the wire as\n * `PlotEmission.colorValue`. The `bar-color` style carries no transparency, so\n * only `title` is spread conditionally (omitted ⇒ absent on the wire).\n */\nfunction barColorOpts(color: Color, opts: BarColorOpts): PlotOpts {\n return {\n style: { kind: \"bar-color\", color },\n ...(opts.title === undefined ? {} : { title: opts.title }),\n };\n}\n\n/**\n * Tint the candle / bar for the current bar — the runtime impl of the\n * Pine-ergonomic `barcolor` alias (script-facing overload).\n *\n * Same dual-signature contract as {@link plot}: scripts call\n * `barcolor(color, opts?)`; the compiler's callsite-id transformer rewrites\n * every call to `barcolor(slotId, color, opts?)` (the sibling overload).\n * Direct invocation without a slot id throws the sentinel error.\n *\n * `barcolor` is Pine-ergonomic sugar — it builds the `bar-color` `PlotStyle`\n * and dispatches to the shared {@link plotImpl} with `value = NaN` (→ wire\n * `value: null`). The per-bar color rides the wire as\n * `PlotEmission.colorValue` (the dynamic-color channel), so a single call\n * recolors every bar by that bar's evaluated color; the static `style.color`\n * remains the fallback. Adapters that do not declare the `bar-color`\n * capability drop it with `unsupported-plot-kind`.\n *\n * @since 1.4\n * @example\n * import { defineIndicator, barcolor } from \"@invinite-org/chartlang-core\";\n * export default defineIndicator({\n * name: \"Tint\",\n * apiVersion: 1,\n * compute({ bar }) {\n * barcolor(bar.close > bar.open ? \"#16a34a\" : \"#dc2626\");\n * },\n * });\n */\nexport function barcolor(color: Color, opts?: BarColorOpts): void;\n/**\n * Tint the candle / bar for the current bar (compiler-injected overload).\n * The callsite-id transformer rewrites script-side `barcolor(color, opts?)`\n * into `barcolor(slotId, color, opts?)`.\n *\n * @since 1.4\n * @example\n * // Internal — the compiler rewrites every script callsite, e.g.\n * // `barcolor(\"#000\")` becomes `barcolor(\"demo.chart.ts:5:9#0\", \"#000\")`.\n * // const fn: typeof barcolor = barcolor;\n * // void fn;\n */\nexport function barcolor(slotId: string, color: Color, opts?: BarColorOpts): void;\n/**\n * Implementation signature for {@link barcolor}. Branches on\n * `typeof arg1 === \"string\"` to dispatch the script-facing vs\n * compiler-injected overload.\n *\n * @since 1.4\n * @example\n * // const fn: typeof barcolor = barcolor;\n * // void fn;\n */\nexport function barcolor(\n arg1: string | Color,\n arg2?: Color | BarColorOpts,\n arg3?: BarColorOpts,\n): void {\n if (typeof arg1 !== \"string\" || typeof arg2 !== \"string\") {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n const ctx = ACTIVE_RUNTIME_CONTEXT.current;\n if (!ctx) throw new Error(OUTSIDE_CTX_MESSAGE);\n plotImpl(ctx, arg1, Number.NaN, barColorOpts(arg2, arg3 ?? {}), arg2);\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import type { BgColorOpts, Color } from "@invinite-org/chartlang-core";
2
+ /**
3
+ * Paint the pane background for the current bar — the runtime impl of the
4
+ * Pine-ergonomic `bgcolor` alias (script-facing overload).
5
+ *
6
+ * Same dual-signature contract as {@link plot}: scripts call
7
+ * `bgcolor(color, opts?)`; the compiler's callsite-id transformer rewrites
8
+ * every call to `bgcolor(slotId, color, opts?)` (the sibling overload).
9
+ * Direct invocation without a slot id throws the sentinel error.
10
+ *
11
+ * `bgcolor` is Pine-ergonomic sugar — it builds the `bg-color` `PlotStyle`
12
+ * and dispatches to the shared {@link plotImpl} with `value = NaN` (→ wire
13
+ * `value: null`). The per-bar color rides the wire as
14
+ * `PlotEmission.colorValue` (the dynamic-color channel), so a single call
15
+ * recolors every bar by that bar's evaluated color; the static `style.color`
16
+ * remains the fallback. Adapters that do not declare the `bg-color`
17
+ * capability drop it with `unsupported-plot-kind`.
18
+ *
19
+ * @since 1.4
20
+ * @example
21
+ * import { defineIndicator, bgcolor } from "@invinite-org/chartlang-core";
22
+ * export default defineIndicator({
23
+ * name: "Heat",
24
+ * apiVersion: 1,
25
+ * compute({ bar }) {
26
+ * bgcolor(bar.close > bar.open ? "#16a34a" : "#dc2626", { transp: 80 });
27
+ * },
28
+ * });
29
+ */
30
+ export declare function bgcolor(color: Color, opts?: BgColorOpts): void;
31
+ /**
32
+ * Paint the pane background for the current bar (compiler-injected overload).
33
+ * The callsite-id transformer rewrites script-side `bgcolor(color, opts?)`
34
+ * into `bgcolor(slotId, color, opts?)`.
35
+ *
36
+ * @since 1.4
37
+ * @example
38
+ * // Internal — the compiler rewrites every script callsite, e.g.
39
+ * // `bgcolor("#000")` becomes `bgcolor("demo.chart.ts:5:9#0", "#000")`.
40
+ * // const fn: typeof bgcolor = bgcolor;
41
+ * // void fn;
42
+ */
43
+ export declare function bgcolor(slotId: string, color: Color, opts?: BgColorOpts): void;
44
+ //# sourceMappingURL=bgcolor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bgcolor.d.ts","sourceRoot":"","sources":["../../src/emit/bgcolor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAY,MAAM,8BAA8B,CAAC;AA4BjF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;AAChE;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC"}
@@ -0,0 +1,45 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ import { ACTIVE_RUNTIME_CONTEXT } from "../runtimeContext.js";
4
+ import { plotImpl } from "./plot.js";
5
+ const OUTSIDE_CTX_MESSAGE = "bgcolor called outside an active script step";
6
+ /**
7
+ * Lower a `bgcolor(color, opts?)` call to the `PlotOpts` a verbose
8
+ * `plot(NaN, { style: { kind: "bg-color", color, transp }, title })` would
9
+ * carry. The static `bg-color` style still carries the color (fallback for
10
+ * adapters that ignore the dynamic channel); the live per-bar color is
11
+ * additionally routed to {@link plotImpl}'s `dynamicColor` arg so it rides
12
+ * the wire as `PlotEmission.colorValue`. `transp` / `title` are spread
13
+ * conditionally (omitted ⇒ absent on the wire), matching the author style arm
14
+ * and `exactOptionalPropertyTypes`.
15
+ */
16
+ function bgColorOpts(color, opts) {
17
+ return {
18
+ style: {
19
+ kind: "bg-color",
20
+ color,
21
+ ...(opts.transp === undefined ? {} : { transp: opts.transp }),
22
+ },
23
+ ...(opts.title === undefined ? {} : { title: opts.title }),
24
+ };
25
+ }
26
+ /**
27
+ * Implementation signature for {@link bgcolor}. Branches on
28
+ * `typeof arg1 === "string"` to dispatch the script-facing vs
29
+ * compiler-injected overload.
30
+ *
31
+ * @since 1.4
32
+ * @example
33
+ * // const fn: typeof bgcolor = bgcolor;
34
+ * // void fn;
35
+ */
36
+ export function bgcolor(arg1, arg2, arg3) {
37
+ if (typeof arg1 !== "string" || typeof arg2 !== "string") {
38
+ throw new Error(OUTSIDE_CTX_MESSAGE);
39
+ }
40
+ const ctx = ACTIVE_RUNTIME_CONTEXT.current;
41
+ if (!ctx)
42
+ throw new Error(OUTSIDE_CTX_MESSAGE);
43
+ plotImpl(ctx, arg1, Number.NaN, bgColorOpts(arg2, arg3 ?? {}), arg2);
44
+ }
45
+ //# sourceMappingURL=bgcolor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bgcolor.js","sourceRoot":"","sources":["../../src/emit/bgcolor.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAE3E;;;;;;;;;GASG;AACH,SAAS,WAAW,CAAC,KAAY,EAAE,IAAiB;IAChD,OAAO;QACH,KAAK,EAAE;YACH,IAAI,EAAE,UAAU;YAChB,KAAK;YACL,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;SAChE;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;KAC7D,CAAC;AACN,CAAC;AA4CD;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CACnB,IAAoB,EACpB,IAA0B,EAC1B,IAAkB;IAElB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,GAAG,GAAG,sBAAsB,CAAC,OAAO,CAAC;IAC3C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC/C,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AACzE,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 { BgColorOpts, Color, PlotOpts } from \"@invinite-org/chartlang-core\";\n\nimport { ACTIVE_RUNTIME_CONTEXT } from \"../runtimeContext.js\";\nimport { plotImpl } from \"./plot.js\";\n\nconst OUTSIDE_CTX_MESSAGE = \"bgcolor called outside an active script step\";\n\n/**\n * Lower a `bgcolor(color, opts?)` call to the `PlotOpts` a verbose\n * `plot(NaN, { style: { kind: \"bg-color\", color, transp }, title })` would\n * carry. The static `bg-color` style still carries the color (fallback for\n * adapters that ignore the dynamic channel); the live per-bar color is\n * additionally routed to {@link plotImpl}'s `dynamicColor` arg so it rides\n * the wire as `PlotEmission.colorValue`. `transp` / `title` are spread\n * conditionally (omitted ⇒ absent on the wire), matching the author style arm\n * and `exactOptionalPropertyTypes`.\n */\nfunction bgColorOpts(color: Color, opts: BgColorOpts): PlotOpts {\n return {\n style: {\n kind: \"bg-color\",\n color,\n ...(opts.transp === undefined ? {} : { transp: opts.transp }),\n },\n ...(opts.title === undefined ? {} : { title: opts.title }),\n };\n}\n\n/**\n * Paint the pane background for the current bar — the runtime impl of the\n * Pine-ergonomic `bgcolor` alias (script-facing overload).\n *\n * Same dual-signature contract as {@link plot}: scripts call\n * `bgcolor(color, opts?)`; the compiler's callsite-id transformer rewrites\n * every call to `bgcolor(slotId, color, opts?)` (the sibling overload).\n * Direct invocation without a slot id throws the sentinel error.\n *\n * `bgcolor` is Pine-ergonomic sugar — it builds the `bg-color` `PlotStyle`\n * and dispatches to the shared {@link plotImpl} with `value = NaN` (→ wire\n * `value: null`). The per-bar color rides the wire as\n * `PlotEmission.colorValue` (the dynamic-color channel), so a single call\n * recolors every bar by that bar's evaluated color; the static `style.color`\n * remains the fallback. Adapters that do not declare the `bg-color`\n * capability drop it with `unsupported-plot-kind`.\n *\n * @since 1.4\n * @example\n * import { defineIndicator, bgcolor } from \"@invinite-org/chartlang-core\";\n * export default defineIndicator({\n * name: \"Heat\",\n * apiVersion: 1,\n * compute({ bar }) {\n * bgcolor(bar.close > bar.open ? \"#16a34a\" : \"#dc2626\", { transp: 80 });\n * },\n * });\n */\nexport function bgcolor(color: Color, opts?: BgColorOpts): void;\n/**\n * Paint the pane background for the current bar (compiler-injected overload).\n * The callsite-id transformer rewrites script-side `bgcolor(color, opts?)`\n * into `bgcolor(slotId, color, opts?)`.\n *\n * @since 1.4\n * @example\n * // Internal — the compiler rewrites every script callsite, e.g.\n * // `bgcolor(\"#000\")` becomes `bgcolor(\"demo.chart.ts:5:9#0\", \"#000\")`.\n * // const fn: typeof bgcolor = bgcolor;\n * // void fn;\n */\nexport function bgcolor(slotId: string, color: Color, opts?: BgColorOpts): void;\n/**\n * Implementation signature for {@link bgcolor}. Branches on\n * `typeof arg1 === \"string\"` to dispatch the script-facing vs\n * compiler-injected overload.\n *\n * @since 1.4\n * @example\n * // const fn: typeof bgcolor = bgcolor;\n * // void fn;\n */\nexport function bgcolor(\n arg1: string | Color,\n arg2?: Color | BgColorOpts,\n arg3?: BgColorOpts,\n): void {\n if (typeof arg1 !== \"string\" || typeof arg2 !== \"string\") {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n const ctx = ACTIVE_RUNTIME_CONTEXT.current;\n if (!ctx) throw new Error(OUTSIDE_CTX_MESSAGE);\n plotImpl(ctx, arg1, Number.NaN, bgColorOpts(arg2, arg3 ?? {}), arg2);\n}\n"]}
@@ -1,6 +1,8 @@
1
1
  export { alert } from "./alert.js";
2
2
  export { emitAlertCondition } from "./alertConditionEmission.js";
3
3
  export { applyPlotOverride } from "./applyPlotOverride.js";
4
+ export { barcolor } from "./barcolor.js";
5
+ export { bgcolor } from "./bgcolor.js";
4
6
  export { createDrawingHandle, draw, nextSubId, pushDrawing, resetSubIdCounters, } from "./draw/index.js";
5
7
  export { pushAlert, pushAlertCondition, pushDiagnostic, pushLog, pushPlot, } from "./emissionsQueue.js";
6
8
  export { hashStringStable } from "./hash.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACH,mBAAmB,EACnB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,kBAAkB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACH,mBAAmB,EACnB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,kBAAkB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -3,6 +3,8 @@
3
3
  export { alert } from "./alert.js";
4
4
  export { emitAlertCondition } from "./alertConditionEmission.js";
5
5
  export { applyPlotOverride } from "./applyPlotOverride.js";
6
+ export { barcolor } from "./barcolor.js";
7
+ export { bgcolor } from "./bgcolor.js";
6
8
  export { createDrawingHandle, draw, nextSubId, pushDrawing, resetSubIdCounters, } from "./draw/index.js";
7
9
  export { pushAlert, pushAlertCondition, pushDiagnostic, pushLog, pushPlot, } from "./emissionsQueue.js";
8
10
  export { hashStringStable } from "./hash.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACH,mBAAmB,EACnB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,kBAAkB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,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 { alert } from \"./alert.js\";\nexport { emitAlertCondition } from \"./alertConditionEmission.js\";\nexport { applyPlotOverride } from \"./applyPlotOverride.js\";\nexport {\n createDrawingHandle,\n draw,\n nextSubId,\n pushDrawing,\n resetSubIdCounters,\n} from \"./draw/index.js\";\nexport {\n pushAlert,\n pushAlertCondition,\n pushDiagnostic,\n pushLog,\n pushPlot,\n} from \"./emissionsQueue.js\";\nexport { hashStringStable } from \"./hash.js\";\nexport { hline } from \"./hline.js\";\nexport { buildRuntimeNamespace, emitLog } from \"./logEmission.js\";\nexport { resolveDefaultPane, resolvePane, resolveScriptPane } from \"./paneResolver.js\";\nexport { plot } from \"./plot.js\";\nexport { isRuntimeErrorHalt, makeRuntimeErrorHalt } from \"./runtimeError.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACH,mBAAmB,EACnB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,kBAAkB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,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 { alert } from \"./alert.js\";\nexport { emitAlertCondition } from \"./alertConditionEmission.js\";\nexport { applyPlotOverride } from \"./applyPlotOverride.js\";\nexport { barcolor } from \"./barcolor.js\";\nexport { bgcolor } from \"./bgcolor.js\";\nexport {\n createDrawingHandle,\n draw,\n nextSubId,\n pushDrawing,\n resetSubIdCounters,\n} from \"./draw/index.js\";\nexport {\n pushAlert,\n pushAlertCondition,\n pushDiagnostic,\n pushLog,\n pushPlot,\n} from \"./emissionsQueue.js\";\nexport { hashStringStable } from \"./hash.js\";\nexport { hline } from \"./hline.js\";\nexport { buildRuntimeNamespace, emitLog } from \"./logEmission.js\";\nexport { resolveDefaultPane, resolvePane, resolveScriptPane } from \"./paneResolver.js\";\nexport { plot } from \"./plot.js\";\nexport { isRuntimeErrorHalt, makeRuntimeErrorHalt } from \"./runtimeError.js\";\n"]}
@@ -1,4 +1,26 @@
1
- import type { PlotOpts, Series } from "@invinite-org/chartlang-core";
1
+ import type { Color, PlotOpts, Series } from "@invinite-org/chartlang-core";
2
+ import { type RuntimeContext } from "../runtimeContext.js";
3
+ /**
4
+ * Shared emission core for `plot` and its Pine-ergonomic aliases
5
+ * (`bgcolor` / `barcolor`). Builds the {@link PlotStyle} from `opts.style`,
6
+ * capability-gates, resolves the pane + `xShift` + `z`, and pushes the
7
+ * deduped, override-applied {@link PlotEmission}.
8
+ *
9
+ * `dynamicColor` is the per-bar dynamic-color channel: when supplied (only
10
+ * the `bgcolor` / `barcolor` aliases do — `plot` never does) it resolves to
11
+ * {@link PlotEmission.colorValue} (a non-empty color string, or `null` for an
12
+ * empty-string gap) and rides the same `(slotId, bar)` last-write-wins dedup
13
+ * as `value`. When omitted, no `colorValue` own-key is emitted, so the
14
+ * static-color `plot` wire stays byte-identical to the pre-Deliverable-2
15
+ * baseline (every pinned plot golden / conformance hash holds).
16
+ *
17
+ * @since 1.4
18
+ * @example
19
+ * // Internal — `bgcolor` / `barcolor` reuse this; scripts call `plot`.
20
+ * // const fn: typeof plotImpl = plotImpl;
21
+ * // void fn;
22
+ */
23
+ export declare function plotImpl(ctx: RuntimeContext, slotId: string, value: number | Series<number>, opts: PlotOpts, dynamicColor?: Color): void;
2
24
  /**
3
25
  * Emit a plot line for the current bar (script-facing overload).
4
26
  *
@@ -1 +1 @@
1
- {"version":3,"file":"plot.d.ts","sourceRoot":"","sources":["../../src/emit/plot.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAuIrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;AAC5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"plot.d.ts","sourceRoot":"","sources":["../../src/emit/plot.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiFnF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAC9B,IAAI,EAAE,QAAQ,EACd,YAAY,CAAC,EAAE,KAAK,GACrB,IAAI,CAyDN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;AAC5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC"}
package/dist/emit/plot.js CHANGED
@@ -75,7 +75,27 @@ function buildStyle(opts) {
75
75
  };
76
76
  }
77
77
  }
78
- function plotImpl(ctx, slotId, value, opts) {
78
+ /**
79
+ * Shared emission core for `plot` and its Pine-ergonomic aliases
80
+ * (`bgcolor` / `barcolor`). Builds the {@link PlotStyle} from `opts.style`,
81
+ * capability-gates, resolves the pane + `xShift` + `z`, and pushes the
82
+ * deduped, override-applied {@link PlotEmission}.
83
+ *
84
+ * `dynamicColor` is the per-bar dynamic-color channel: when supplied (only
85
+ * the `bgcolor` / `barcolor` aliases do — `plot` never does) it resolves to
86
+ * {@link PlotEmission.colorValue} (a non-empty color string, or `null` for an
87
+ * empty-string gap) and rides the same `(slotId, bar)` last-write-wins dedup
88
+ * as `value`. When omitted, no `colorValue` own-key is emitted, so the
89
+ * static-color `plot` wire stays byte-identical to the pre-Deliverable-2
90
+ * baseline (every pinned plot golden / conformance hash holds).
91
+ *
92
+ * @since 1.4
93
+ * @example
94
+ * // Internal — `bgcolor` / `barcolor` reuse this; scripts call `plot`.
95
+ * // const fn: typeof plotImpl = plotImpl;
96
+ * // void fn;
97
+ */
98
+ export function plotImpl(ctx, slotId, value, opts, dynamicColor) {
79
99
  const style = buildStyle(opts);
80
100
  if (!ctx.capabilities.plots.has(style.kind)) {
81
101
  pushDiagnostic(ctx.emissions, {
@@ -99,6 +119,16 @@ function plotImpl(ctx, slotId, value, opts) {
99
119
  // and append it with the same omit-when-`0` conditional spread so a
100
120
  // no-`z` plot stays byte-identical to the pre-feature baseline.
101
121
  const z = opts.z ?? 0;
122
+ // The per-bar dynamic color (only `bgcolor` / `barcolor` pass it) rides the
123
+ // wire as `colorValue`, appended LAST so an omitted-`colorValue` emission
124
+ // is byte-identical to the pre-Deliverable-2 wire. `plot` passes nothing,
125
+ // so its static-color wire is untouched and its goldens / hashes do not
126
+ // move. The color flows through unchanged: the alias mirrors it onto the
127
+ // static `style.color` too, so a malformed (empty) color trips the style
128
+ // validator and `pushPlot` drops the whole emission — the validator's
129
+ // `colorValue: null` arm is the wire contract for an explicit gap a future
130
+ // producer may emit, not something the aliases manufacture.
131
+ const colorValue = dynamicColor;
102
132
  const emission = {
103
133
  kind: "plot",
104
134
  slotId,
@@ -112,6 +142,7 @@ function plotImpl(ctx, slotId, value, opts) {
112
142
  pane,
113
143
  ...(xShift === 0 ? {} : { xShift }),
114
144
  ...(z === 0 ? {} : { z }),
145
+ ...(colorValue === undefined ? {} : { colorValue }),
115
146
  };
116
147
  pushPlot(ctx.emissions, applyPlotOverride(emission, ctx.plotOverrides[slotId]));
117
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plot.js","sourceRoot":"","sources":["../../src/emit/plot.ts"],"names":[],"mappings":"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","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 { PlotEmission, PlotStyle } from \"@invinite-org/chartlang-adapter-kit\";\nimport type { PlotOpts, Series } from \"@invinite-org/chartlang-core\";\n\nimport { ACTIVE_RUNTIME_CONTEXT, type RuntimeContext } from \"../runtimeContext.js\";\nimport { seriesOffsetOf } from \"../seriesView.js\";\nimport { applyPlotOverride } from \"./applyPlotOverride.js\";\nimport { pushDiagnostic, pushPlot } from \"./emissionsQueue.js\";\nimport { resolvePane } from \"./paneResolver.js\";\n\nconst OUTSIDE_CTX_MESSAGE = \"plot called outside an active script step\";\n\nfunction isSeriesNumber(v: unknown): v is Series<number> {\n return typeof v === \"object\" && v !== null && \"current\" in v;\n}\n\nfunction isNumberOrSeries(v: unknown): v is number | Series<number> {\n return typeof v === \"number\" || isSeriesNumber(v);\n}\n\nfunction resolveValue(value: number | Series<number>): number | null {\n const resolved = typeof value === \"number\" ? value : value.current;\n return Number.isFinite(resolved) ? resolved : null;\n}\n\nfunction buildStyle(opts: PlotOpts): PlotStyle {\n const style = opts.style;\n if (style === undefined) {\n return {\n kind: \"line\",\n lineWidth: opts.lineWidth ?? 1,\n lineStyle: opts.lineStyle ?? \"solid\",\n };\n }\n switch (style.kind) {\n case \"histogram\":\n return { kind: \"histogram\", baseline: style.baseline ?? 0 };\n case \"marker\":\n return { kind: \"marker\", shape: style.shape, size: style.size };\n case \"shape\":\n return {\n kind: \"shape\",\n shape: style.shape,\n size: style.size,\n ...(style.location === undefined ? {} : { location: style.location }),\n };\n case \"character\":\n return {\n kind: \"character\",\n char: style.char,\n size: style.size,\n ...(style.location === undefined ? {} : { location: style.location }),\n };\n case \"arrow\":\n return { kind: \"arrow\", direction: style.direction, size: style.size };\n case \"candle-override\":\n return {\n kind: \"candle-override\",\n bull: style.bull,\n bear: style.bear,\n ...(style.doji === undefined ? {} : { doji: style.doji }),\n };\n case \"bar-override\":\n return { kind: \"bar-override\", color: style.color };\n case \"bg-color\":\n return {\n kind: \"bg-color\",\n color: style.color,\n ...(style.transp === undefined ? {} : { transp: style.transp }),\n };\n case \"bar-color\":\n return { kind: \"bar-color\", color: style.color };\n case \"horizontal-histogram\":\n return { kind: \"horizontal-histogram\", buckets: style.buckets };\n case \"line\":\n case \"step-line\":\n case \"horizontal-line\":\n return {\n kind: style.kind,\n lineWidth: opts.lineWidth ?? 1,\n lineStyle: opts.lineStyle ?? \"solid\",\n };\n }\n}\n\nfunction plotImpl(\n ctx: RuntimeContext,\n slotId: string,\n value: number | Series<number>,\n opts: PlotOpts,\n): void {\n const style: PlotStyle = buildStyle(opts);\n\n if (!ctx.capabilities.plots.has(style.kind)) {\n pushDiagnostic(ctx.emissions, {\n kind: \"diagnostic\",\n severity: \"warning\",\n code: \"unsupported-plot-kind\",\n message: `Adapter cannot render plot kind \"${style.kind}\".`,\n slotId,\n bar: ctx.barIndex(),\n });\n return;\n }\n\n const pane = resolvePane(opts.pane, ctx, slotId);\n\n // A `ta.*` series carries its declared `offset` (ALMA: `barShift`) as a\n // presentation x-shift recorded on the series view; thread it onto the\n // emission. A plain numeric value or an untagged series omits `xShift`,\n // keeping the no-offset wire byte-identical to the pre-feature baseline.\n const xShift = typeof value === \"number\" ? 0 : seriesOffsetOf(value);\n\n // `z` is a direct plot-call option (a render-order key), unlike\n // `xShift` (derived from the series view). Normalize undefined → `0`\n // and append it with the same omit-when-`0` conditional spread so a\n // no-`z` plot stays byte-identical to the pre-feature baseline.\n const z = opts.z ?? 0;\n\n const emission: PlotEmission = {\n kind: \"plot\",\n slotId,\n title: opts.title ?? \"\",\n style,\n bar: ctx.barIndex(),\n time: ctx.stream.bar.time,\n value: resolveValue(value),\n color: opts.color ?? null,\n meta: {},\n pane,\n ...(xShift === 0 ? {} : { xShift }),\n ...(z === 0 ? {} : { z }),\n };\n\n pushPlot(ctx.emissions, applyPlotOverride(emission, ctx.plotOverrides[slotId]));\n}\n\n/**\n * Emit a plot line for the current bar (script-facing overload).\n *\n * The runtime export is dual-signature: scripts call `plot(value, opts?)`\n * (the surface declared on `@invinite-org/chartlang-core`'s\n * `ComputeContext`), and Task 2's compiler transformer rewrites every\n * callsite to inject the compiler-issued slot id as the leading\n * argument — see the sibling `plot(slotId, value, opts?)` overload.\n * A direct invocation without a slot id (i.e. outside a compiled\n * bundle) throws the sentinel error.\n *\n * Plot kind is always `\"line\"` in Phase 1; `\"horizontal-line\"` ships\n * via the sibling {@link hline} primitive. Phase 2+ extends the `kind`\n * variants additively.\n *\n * When the plotted value is a `ta.*` series declared with an `offset`\n * (or ALMA's `barShift`), that signed bar count rides the emission as\n * `PlotEmission.xShift` (presentation-only — `+n` renders the series `n`\n * bars right, `−n` `n` bars left); the emitted `value` itself is\n * unshifted, so alerts and `state.*` see the value computed at the\n * current bar.\n *\n * @since 0.1\n * @example\n * import { defineIndicator, ta, plot } from \"@invinite-org/chartlang-core\";\n * export default defineIndicator({\n * name: \"EMA(20)\",\n * apiVersion: 1,\n * compute({ bar, ta, plot }) {\n * plot(ta.ema(bar.close, 20), { color: \"#26a69a\", title: \"EMA\" });\n * },\n * });\n */\nexport function plot(value: number | Series<number>, opts?: PlotOpts): void;\n/**\n * Emit a plot line for the current bar (compiler-injected overload).\n *\n * Task 2's callsite-id transformer rewrites every script-side\n * `plot(value, opts?)` into `plot(slotId, value, opts?)`. The runtime\n * branches on `typeof arg1 === \"string\"` so the compiler-emitted\n * bundle dispatches here directly.\n *\n * @since 0.1\n * @example\n * // Internal — the compiler rewrites every script callsite, e.g.\n * // `plot(close)` becomes `plot(\"demo.chart.ts:5:13#0\", close)`.\n * // const fn: typeof plot = plot;\n * // void fn;\n */\nexport function plot(slotId: string, value: number | Series<number>, opts?: PlotOpts): void;\n/**\n * Implementation signature for {@link plot}. Branches on\n * `typeof arg1 === \"string\"` to dispatch the script-facing vs\n * compiler-injected overload.\n *\n * @since 0.1\n * @example\n * // const fn: typeof plot = plot;\n * // void fn;\n */\nexport function plot(\n arg1: string | number | Series<number>,\n arg2?: number | Series<number> | PlotOpts,\n arg3?: PlotOpts,\n): void {\n if (typeof arg1 !== \"string\") {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n const ctx = ACTIVE_RUNTIME_CONTEXT.current;\n if (!ctx) throw new Error(OUTSIDE_CTX_MESSAGE);\n if (!isNumberOrSeries(arg2)) {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n plotImpl(ctx, arg1, arg2, arg3 ?? {});\n}\n"]}
1
+ {"version":3,"file":"plot.js","sourceRoot":"","sources":["../../src/emit/plot.ts"],"names":[],"mappings":"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","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 { PlotEmission, PlotStyle } from \"@invinite-org/chartlang-adapter-kit\";\nimport type { Color, PlotOpts, Series } from \"@invinite-org/chartlang-core\";\n\nimport { ACTIVE_RUNTIME_CONTEXT, type RuntimeContext } from \"../runtimeContext.js\";\nimport { seriesOffsetOf } from \"../seriesView.js\";\nimport { applyPlotOverride } from \"./applyPlotOverride.js\";\nimport { pushDiagnostic, pushPlot } from \"./emissionsQueue.js\";\nimport { resolvePane } from \"./paneResolver.js\";\n\nconst OUTSIDE_CTX_MESSAGE = \"plot called outside an active script step\";\n\nfunction isSeriesNumber(v: unknown): v is Series<number> {\n return typeof v === \"object\" && v !== null && \"current\" in v;\n}\n\nfunction isNumberOrSeries(v: unknown): v is number | Series<number> {\n return typeof v === \"number\" || isSeriesNumber(v);\n}\n\nfunction resolveValue(value: number | Series<number>): number | null {\n const resolved = typeof value === \"number\" ? value : value.current;\n return Number.isFinite(resolved) ? resolved : null;\n}\n\nfunction buildStyle(opts: PlotOpts): PlotStyle {\n const style = opts.style;\n if (style === undefined) {\n return {\n kind: \"line\",\n lineWidth: opts.lineWidth ?? 1,\n lineStyle: opts.lineStyle ?? \"solid\",\n };\n }\n switch (style.kind) {\n case \"histogram\":\n return { kind: \"histogram\", baseline: style.baseline ?? 0 };\n case \"marker\":\n return { kind: \"marker\", shape: style.shape, size: style.size };\n case \"shape\":\n return {\n kind: \"shape\",\n shape: style.shape,\n size: style.size,\n ...(style.location === undefined ? {} : { location: style.location }),\n };\n case \"character\":\n return {\n kind: \"character\",\n char: style.char,\n size: style.size,\n ...(style.location === undefined ? {} : { location: style.location }),\n };\n case \"arrow\":\n return { kind: \"arrow\", direction: style.direction, size: style.size };\n case \"candle-override\":\n return {\n kind: \"candle-override\",\n bull: style.bull,\n bear: style.bear,\n ...(style.doji === undefined ? {} : { doji: style.doji }),\n };\n case \"bar-override\":\n return { kind: \"bar-override\", color: style.color };\n case \"bg-color\":\n return {\n kind: \"bg-color\",\n color: style.color,\n ...(style.transp === undefined ? {} : { transp: style.transp }),\n };\n case \"bar-color\":\n return { kind: \"bar-color\", color: style.color };\n case \"horizontal-histogram\":\n return { kind: \"horizontal-histogram\", buckets: style.buckets };\n case \"line\":\n case \"step-line\":\n case \"horizontal-line\":\n return {\n kind: style.kind,\n lineWidth: opts.lineWidth ?? 1,\n lineStyle: opts.lineStyle ?? \"solid\",\n };\n }\n}\n\n/**\n * Shared emission core for `plot` and its Pine-ergonomic aliases\n * (`bgcolor` / `barcolor`). Builds the {@link PlotStyle} from `opts.style`,\n * capability-gates, resolves the pane + `xShift` + `z`, and pushes the\n * deduped, override-applied {@link PlotEmission}.\n *\n * `dynamicColor` is the per-bar dynamic-color channel: when supplied (only\n * the `bgcolor` / `barcolor` aliases do — `plot` never does) it resolves to\n * {@link PlotEmission.colorValue} (a non-empty color string, or `null` for an\n * empty-string gap) and rides the same `(slotId, bar)` last-write-wins dedup\n * as `value`. When omitted, no `colorValue` own-key is emitted, so the\n * static-color `plot` wire stays byte-identical to the pre-Deliverable-2\n * baseline (every pinned plot golden / conformance hash holds).\n *\n * @since 1.4\n * @example\n * // Internal — `bgcolor` / `barcolor` reuse this; scripts call `plot`.\n * // const fn: typeof plotImpl = plotImpl;\n * // void fn;\n */\nexport function plotImpl(\n ctx: RuntimeContext,\n slotId: string,\n value: number | Series<number>,\n opts: PlotOpts,\n dynamicColor?: Color,\n): void {\n const style: PlotStyle = buildStyle(opts);\n\n if (!ctx.capabilities.plots.has(style.kind)) {\n pushDiagnostic(ctx.emissions, {\n kind: \"diagnostic\",\n severity: \"warning\",\n code: \"unsupported-plot-kind\",\n message: `Adapter cannot render plot kind \"${style.kind}\".`,\n slotId,\n bar: ctx.barIndex(),\n });\n return;\n }\n\n const pane = resolvePane(opts.pane, ctx, slotId);\n\n // A `ta.*` series carries its declared `offset` (ALMA: `barShift`) as a\n // presentation x-shift recorded on the series view; thread it onto the\n // emission. A plain numeric value or an untagged series omits `xShift`,\n // keeping the no-offset wire byte-identical to the pre-feature baseline.\n const xShift = typeof value === \"number\" ? 0 : seriesOffsetOf(value);\n\n // `z` is a direct plot-call option (a render-order key), unlike\n // `xShift` (derived from the series view). Normalize undefined → `0`\n // and append it with the same omit-when-`0` conditional spread so a\n // no-`z` plot stays byte-identical to the pre-feature baseline.\n const z = opts.z ?? 0;\n\n // The per-bar dynamic color (only `bgcolor` / `barcolor` pass it) rides the\n // wire as `colorValue`, appended LAST so an omitted-`colorValue` emission\n // is byte-identical to the pre-Deliverable-2 wire. `plot` passes nothing,\n // so its static-color wire is untouched and its goldens / hashes do not\n // move. The color flows through unchanged: the alias mirrors it onto the\n // static `style.color` too, so a malformed (empty) color trips the style\n // validator and `pushPlot` drops the whole emission — the validator's\n // `colorValue: null` arm is the wire contract for an explicit gap a future\n // producer may emit, not something the aliases manufacture.\n const colorValue = dynamicColor;\n\n const emission: PlotEmission = {\n kind: \"plot\",\n slotId,\n title: opts.title ?? \"\",\n style,\n bar: ctx.barIndex(),\n time: ctx.stream.bar.time,\n value: resolveValue(value),\n color: opts.color ?? null,\n meta: {},\n pane,\n ...(xShift === 0 ? {} : { xShift }),\n ...(z === 0 ? {} : { z }),\n ...(colorValue === undefined ? {} : { colorValue }),\n };\n\n pushPlot(ctx.emissions, applyPlotOverride(emission, ctx.plotOverrides[slotId]));\n}\n\n/**\n * Emit a plot line for the current bar (script-facing overload).\n *\n * The runtime export is dual-signature: scripts call `plot(value, opts?)`\n * (the surface declared on `@invinite-org/chartlang-core`'s\n * `ComputeContext`), and Task 2's compiler transformer rewrites every\n * callsite to inject the compiler-issued slot id as the leading\n * argument — see the sibling `plot(slotId, value, opts?)` overload.\n * A direct invocation without a slot id (i.e. outside a compiled\n * bundle) throws the sentinel error.\n *\n * Plot kind is always `\"line\"` in Phase 1; `\"horizontal-line\"` ships\n * via the sibling {@link hline} primitive. Phase 2+ extends the `kind`\n * variants additively.\n *\n * When the plotted value is a `ta.*` series declared with an `offset`\n * (or ALMA's `barShift`), that signed bar count rides the emission as\n * `PlotEmission.xShift` (presentation-only — `+n` renders the series `n`\n * bars right, `−n` `n` bars left); the emitted `value` itself is\n * unshifted, so alerts and `state.*` see the value computed at the\n * current bar.\n *\n * @since 0.1\n * @example\n * import { defineIndicator, ta, plot } from \"@invinite-org/chartlang-core\";\n * export default defineIndicator({\n * name: \"EMA(20)\",\n * apiVersion: 1,\n * compute({ bar, ta, plot }) {\n * plot(ta.ema(bar.close, 20), { color: \"#26a69a\", title: \"EMA\" });\n * },\n * });\n */\nexport function plot(value: number | Series<number>, opts?: PlotOpts): void;\n/**\n * Emit a plot line for the current bar (compiler-injected overload).\n *\n * Task 2's callsite-id transformer rewrites every script-side\n * `plot(value, opts?)` into `plot(slotId, value, opts?)`. The runtime\n * branches on `typeof arg1 === \"string\"` so the compiler-emitted\n * bundle dispatches here directly.\n *\n * @since 0.1\n * @example\n * // Internal — the compiler rewrites every script callsite, e.g.\n * // `plot(close)` becomes `plot(\"demo.chart.ts:5:13#0\", close)`.\n * // const fn: typeof plot = plot;\n * // void fn;\n */\nexport function plot(slotId: string, value: number | Series<number>, opts?: PlotOpts): void;\n/**\n * Implementation signature for {@link plot}. Branches on\n * `typeof arg1 === \"string\"` to dispatch the script-facing vs\n * compiler-injected overload.\n *\n * @since 0.1\n * @example\n * // const fn: typeof plot = plot;\n * // void fn;\n */\nexport function plot(\n arg1: string | number | Series<number>,\n arg2?: number | Series<number> | PlotOpts,\n arg3?: PlotOpts,\n): void {\n if (typeof arg1 !== \"string\") {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n const ctx = ACTIVE_RUNTIME_CONTEXT.current;\n if (!ctx) throw new Error(OUTSIDE_CTX_MESSAGE);\n if (!isNumberOrSeries(arg2)) {\n throw new Error(OUTSIDE_CTX_MESSAGE);\n }\n plotImpl(ctx, arg1, arg2, arg3 ?? {});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dispose.d.ts","sourceRoot":"","sources":["../../src/execution/dispose.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAuDhD"}
1
+ {"version":3,"file":"dispose.d.ts","sourceRoot":"","sources":["../../src/execution/dispose.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAyDhD"}
@@ -48,6 +48,7 @@ export function dispose(state) {
48
48
  state.runtimeContext.drawingSubIdCounters.clear();
49
49
  state.runtimeContext.stateSlots.clear();
50
50
  state.runtimeContext.seriesSlots.clear();
51
+ state.runtimeContext.arraySlots.clear();
51
52
  state.runtimeContext.secondaryStreams.clear();
52
53
  state.runtimeContext.requestSecurityBars.clear();
53
54
  state.runtimeContext.requestSecurityAlignments.clear();
@@ -62,13 +63,14 @@ export function dispose(state) {
62
63
  runner.foldStream.taSlots.clear();
63
64
  runner.output.reset();
64
65
  }
65
- // Drops every runner reference; the per-interval index holds the same
66
+ // Drops every runner reference; the per-feed index holds the same
66
67
  // (now-reset) objects, so clearing `bySlot` is the authoritative
67
68
  // teardown. The whole `RuntimeContext` is discarded after dispose.
68
69
  exprRunners.clear();
69
70
  }
70
71
  state.runtimeContext.requestLowerTfViews.clear();
71
72
  state.runtimeContext.diagnosedRequestKeys.clear();
73
+ state.runtimeContext.diagnosedTzKeys.clear();
72
74
  state.runtimeContext.diagnosedInputKeys.clear();
73
75
  const counters = state.runtimeContext.drawingBucketCounters;
74
76
  counters.lines = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"dispose.js","sourceRoot":"","sources":["../../src/execution/dispose.ts"],"names":[],"mappings":"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","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 { RunnerState } from \"../createScriptRunner.js\";\nimport { flushStateSlots } from \"../state/index.js\";\n\n/**\n * Tear down the runner's buffers and state. After `dispose`:\n *\n * - Every OHLCV ring buffer's `length` is 0 (via `RingBufferLike.reset`).\n * - The `taSlots` map is empty (Task 7 primitives lose their hidden\n * state).\n * - Runtime `state.*` slots are flushed into `StateStore`, then the\n * runner-local slot map is cleared. The backing `StateStore` remains\n * host-owned so warm restart can restore the snapshot.\n * - The four emission arrays are reset to empty (`drain()` after\n * `dispose` returns empty arrays).\n *\n * `state.barIndex` is NOT reset — `dispose` is one-shot. Re-use after\n * `dispose` is not supported and not tested.\n *\n * @since 0.1\n * @example\n * // import { dispose } from \"@invinite-org/chartlang-runtime\";\n * // dispose(state);\n */\nexport function dispose(state: RunnerState): void {\n for (const dep of state.depRunners) {\n dispose(dep.state);\n }\n for (const sibling of state.siblingRunners) {\n dispose(sibling.state);\n }\n state.depOutputStore?.dispose();\n flushStateSlots(state.runtimeContext);\n for (const buf of Object.values(state.mainStream.ohlcv)) {\n buf.reset();\n }\n for (const stream of state.runtimeContext.secondaryStreams.values()) {\n for (const buf of Object.values(stream.ohlcv)) {\n buf.reset();\n }\n stream.taSlots.clear();\n }\n state.mainStream.taSlots.clear();\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.diagnostics = [];\n state.runtimeContext.drawingSlots.clear();\n state.runtimeContext.drawingSubIdCounters.clear();\n state.runtimeContext.stateSlots.clear();\n state.runtimeContext.seriesSlots.clear();\n state.runtimeContext.secondaryStreams.clear();\n state.runtimeContext.requestSecurityBars.clear();\n state.runtimeContext.requestSecurityAlignments.clear();\n state.runtimeContext.requestSecurityAscendingBars.clear();\n state.runtimeContext.requestSecurityExprSeries?.clear();\n const exprRunners = state.runtimeContext.securityExprRunners;\n if (exprRunners !== undefined) {\n for (const runner of exprRunners.values()) {\n for (const buf of Object.values(runner.foldStream.ohlcv)) {\n buf.reset();\n }\n runner.foldStream.taSlots.clear();\n runner.output.reset();\n }\n // Drops every runner reference; the per-interval index holds the same\n // (now-reset) objects, so clearing `bySlot` is the authoritative\n // teardown. The whole `RuntimeContext` is discarded after dispose.\n exprRunners.clear();\n }\n state.runtimeContext.requestLowerTfViews.clear();\n state.runtimeContext.diagnosedRequestKeys.clear();\n state.runtimeContext.diagnosedInputKeys.clear();\n const counters = state.runtimeContext.drawingBucketCounters;\n counters.lines = 0;\n counters.labels = 0;\n counters.boxes = 0;\n counters.polylines = 0;\n counters.other = 0;\n}\n"]}
1
+ {"version":3,"file":"dispose.js","sourceRoot":"","sources":["../../src/execution/dispose.ts"],"names":[],"mappings":"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","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 { RunnerState } from \"../createScriptRunner.js\";\nimport { flushStateSlots } from \"../state/index.js\";\n\n/**\n * Tear down the runner's buffers and state. After `dispose`:\n *\n * - Every OHLCV ring buffer's `length` is 0 (via `RingBufferLike.reset`).\n * - The `taSlots` map is empty (Task 7 primitives lose their hidden\n * state).\n * - Runtime `state.*` slots are flushed into `StateStore`, then the\n * runner-local slot map is cleared. The backing `StateStore` remains\n * host-owned so warm restart can restore the snapshot.\n * - The four emission arrays are reset to empty (`drain()` after\n * `dispose` returns empty arrays).\n *\n * `state.barIndex` is NOT reset — `dispose` is one-shot. Re-use after\n * `dispose` is not supported and not tested.\n *\n * @since 0.1\n * @example\n * // import { dispose } from \"@invinite-org/chartlang-runtime\";\n * // dispose(state);\n */\nexport function dispose(state: RunnerState): void {\n for (const dep of state.depRunners) {\n dispose(dep.state);\n }\n for (const sibling of state.siblingRunners) {\n dispose(sibling.state);\n }\n state.depOutputStore?.dispose();\n flushStateSlots(state.runtimeContext);\n for (const buf of Object.values(state.mainStream.ohlcv)) {\n buf.reset();\n }\n for (const stream of state.runtimeContext.secondaryStreams.values()) {\n for (const buf of Object.values(stream.ohlcv)) {\n buf.reset();\n }\n stream.taSlots.clear();\n }\n state.mainStream.taSlots.clear();\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.diagnostics = [];\n state.runtimeContext.drawingSlots.clear();\n state.runtimeContext.drawingSubIdCounters.clear();\n state.runtimeContext.stateSlots.clear();\n state.runtimeContext.seriesSlots.clear();\n state.runtimeContext.arraySlots.clear();\n state.runtimeContext.secondaryStreams.clear();\n state.runtimeContext.requestSecurityBars.clear();\n state.runtimeContext.requestSecurityAlignments.clear();\n state.runtimeContext.requestSecurityAscendingBars.clear();\n state.runtimeContext.requestSecurityExprSeries?.clear();\n const exprRunners = state.runtimeContext.securityExprRunners;\n if (exprRunners !== undefined) {\n for (const runner of exprRunners.values()) {\n for (const buf of Object.values(runner.foldStream.ohlcv)) {\n buf.reset();\n }\n runner.foldStream.taSlots.clear();\n runner.output.reset();\n }\n // Drops every runner reference; the per-feed index holds the same\n // (now-reset) objects, so clearing `bySlot` is the authoritative\n // teardown. The whole `RuntimeContext` is discarded after dispose.\n exprRunners.clear();\n }\n state.runtimeContext.requestLowerTfViews.clear();\n state.runtimeContext.diagnosedRequestKeys.clear();\n state.runtimeContext.diagnosedTzKeys.clear();\n state.runtimeContext.diagnosedInputKeys.clear();\n const counters = state.runtimeContext.drawingBucketCounters;\n counters.lines = 0;\n counters.labels = 0;\n counters.boxes = 0;\n counters.polylines = 0;\n counters.other = 0;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runComputeStep.d.ts","sourceRoot":"","sources":["../../src/execution/runComputeStep.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAY5D,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,qBAAqB,GAC3B,QAAQ,CAAC;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,GACxB,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAc1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8C7F"}
1
+ {"version":3,"file":"runComputeStep.d.ts","sourceRoot":"","sources":["../../src/execution/runComputeStep.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAc5D,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,qBAAqB,GAC3B,QAAQ,CAAC;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,GACxB,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAc1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgD7F"}
@@ -4,7 +4,7 @@ import { buildComputeContext } from "../buildComputeContext.js";
4
4
  import { resetSubIdCounters } from "../emit/draw/index.js";
5
5
  import { isRuntimeErrorHalt, pushDiagnostic } from "../emit/index.js";
6
6
  import { ACTIVE_RUNTIME_CONTEXT } from "../runtimeContext.js";
7
- import { advanceSeriesSlots, commitSeriesSlots, commitStateSlots, flushStateSlots, resetSeriesHeads, resetTentativeStateSlots, } from "../state/index.js";
7
+ import { advanceSeriesSlots, commitArraySlots, commitSeriesSlots, commitStateSlots, flushStateSlots, resetSeriesHeads, resetTentativeArraySlots, resetTentativeStateSlots, } from "../state/index.js";
8
8
  import { refreshRuntimeViews } from "../views/index.js";
9
9
  /**
10
10
  * Reset the per-bar emission queues on a runner before its compute
@@ -60,6 +60,7 @@ export async function runComputeBody(args) {
60
60
  if (isTick) {
61
61
  resetTentativeStateSlots(state.runtimeContext);
62
62
  resetSeriesHeads(state.runtimeContext);
63
+ resetTentativeArraySlots(state.runtimeContext);
63
64
  }
64
65
  else {
65
66
  // Advance every already-allocated series ring with a fresh NaN
@@ -74,6 +75,7 @@ export async function runComputeBody(args) {
74
75
  commitStateSlots(state.runtimeContext);
75
76
  flushStateSlots(state.runtimeContext);
76
77
  commitSeriesSlots(state.runtimeContext);
78
+ commitArraySlots(state.runtimeContext);
77
79
  }
78
80
  }
79
81
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"runComputeStep.js","sourceRoot":"","sources":["../../src/execution/runComputeStep.ts"],"names":[],"mappings":"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","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 { buildComputeContext } from \"../buildComputeContext.js\";\nimport type { RunnerState } from \"../createScriptRunner.js\";\nimport { resetSubIdCounters } from \"../emit/draw/index.js\";\nimport { isRuntimeErrorHalt, pushDiagnostic } from \"../emit/index.js\";\nimport { ACTIVE_RUNTIME_CONTEXT } from \"../runtimeContext.js\";\nimport {\n advanceSeriesSlots,\n commitSeriesSlots,\n commitStateSlots,\n flushStateSlots,\n resetSeriesHeads,\n resetTentativeStateSlots,\n} from \"../state/index.js\";\nimport { type EventKind, refreshRuntimeViews } from \"../views/index.js\";\n\n/**\n * Outcome of a single compute step. `ok` means the script's `compute`\n * returned normally; `halt` means `runtime.error(...)` was thrown (the\n * compute body deliberately aborted the bar). Non-halt throws propagate\n * out of {@link runComputeStep} unchanged.\n *\n * @since 0.7\n * @stable\n * @example\n * const r: RunComputeStepOutcome = { kind: \"ok\" };\n * void r;\n */\nexport type RunComputeStepOutcome =\n | Readonly<{ kind: \"ok\" }>\n | Readonly<{ kind: \"halt\"; readonly message: string }>;\n\n/**\n * Configuration for {@link runComputeStep}. `eventKind` reaches the\n * runtime views so `barstate.*` picks up the right snapshot; `isTick`\n * discriminates the close-vs-tick state-slot lifecycle.\n *\n * @since 0.7\n * @stable\n * @example\n * const args = { state, eventKind: \"close\" as const, isTick: false };\n * void args;\n */\nexport type RunComputeStepArgs = Readonly<{\n readonly state: RunnerState;\n readonly eventKind: EventKind;\n readonly isTick: boolean;\n}>;\n\n/**\n * Reset the per-bar emission queues on a runner before its compute\n * runs. Exported for the dep / sibling step driver — single-script\n * callers go through {@link runComputeStep} which calls this\n * internally.\n *\n * @since 0.7\n * @stable\n * @example\n * // resetBarEmissions(state);\n */\nexport function resetBarEmissions(state: RunnerState): void {\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.alertConditions = [];\n state.emissions.logs = [];\n state.emissions.diagnostics = [];\n state.emissions.fromBar = state.barIndex;\n state.emissions.toBar = state.barIndex;\n state.runtimeContext.requestSecurityAlignments.clear();\n state.runtimeContext.requestSecurityAscendingBars.clear();\n state.runtimeContext.requestSecurityExprSeries?.clear();\n state.runtimeContext.logBudget = 0;\n state.runtimeContext.logBudgetExceededDiagnosed = false;\n}\n\n/**\n * Run the inner compute body of `state.compute` — set\n * `ACTIVE_RUNTIME_CONTEXT`, reset sub-id counters, optionally reset\n * tentative state slots, refresh views, invoke `compute`, commit /\n * flush state slots on close. Does NOT reset the per-bar emission\n * queues; callers do that exactly once via {@link resetBarEmissions}.\n *\n * `runtime.error(...)` halts clear the runner's visual emissions and\n * push a `runtime-error-thrown` diagnostic, matching the Phase-1\n * single-script behaviour byte-for-byte. Non-halt throws propagate\n * out unchanged.\n *\n * @since 0.7\n * @stable\n * @example\n * // const outcome = await runComputeBody({ state, eventKind: \"close\", isTick: false });\n * // void outcome;\n */\nexport async function runComputeBody(args: RunComputeStepArgs): Promise<RunComputeStepOutcome> {\n const { state, eventKind, isTick } = args;\n ACTIVE_RUNTIME_CONTEXT.current = state.runtimeContext;\n state.runtimeContext.isTick = isTick;\n let outcome: RunComputeStepOutcome = { kind: \"ok\" };\n try {\n resetSubIdCounters(state.runtimeContext);\n if (isTick) {\n resetTentativeStateSlots(state.runtimeContext);\n resetSeriesHeads(state.runtimeContext);\n } else {\n // Advance every already-allocated series ring with a fresh NaN\n // head BEFORE compute, so a slot first allocated mid-compute (it\n // already holds its seeded head) is not double-advanced.\n advanceSeriesSlots(state.runtimeContext);\n }\n refreshRuntimeViews(state, eventKind);\n try {\n await Promise.resolve(state.compute(buildComputeContext(state)));\n if (!isTick) {\n commitStateSlots(state.runtimeContext);\n flushStateSlots(state.runtimeContext);\n commitSeriesSlots(state.runtimeContext);\n }\n } catch (err) {\n if (!isRuntimeErrorHalt(err)) throw err;\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.alertConditions = [];\n state.emissions.logs = [];\n pushDiagnostic(state.emissions, {\n kind: \"diagnostic\",\n severity: \"error\",\n code: \"runtime-error-thrown\",\n message: err.message,\n slotId: null,\n bar: state.barIndex,\n });\n outcome = { kind: \"halt\", message: err.message };\n }\n } finally {\n if (isTick) state.runtimeContext.isTick = false;\n ACTIVE_RUNTIME_CONTEXT.current = null;\n }\n return outcome;\n}\n"]}
1
+ {"version":3,"file":"runComputeStep.js","sourceRoot":"","sources":["../../src/execution/runComputeStep.ts"],"names":[],"mappings":"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","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 { buildComputeContext } from \"../buildComputeContext.js\";\nimport type { RunnerState } from \"../createScriptRunner.js\";\nimport { resetSubIdCounters } from \"../emit/draw/index.js\";\nimport { isRuntimeErrorHalt, pushDiagnostic } from \"../emit/index.js\";\nimport { ACTIVE_RUNTIME_CONTEXT } from \"../runtimeContext.js\";\nimport {\n advanceSeriesSlots,\n commitArraySlots,\n commitSeriesSlots,\n commitStateSlots,\n flushStateSlots,\n resetSeriesHeads,\n resetTentativeArraySlots,\n resetTentativeStateSlots,\n} from \"../state/index.js\";\nimport { type EventKind, refreshRuntimeViews } from \"../views/index.js\";\n\n/**\n * Outcome of a single compute step. `ok` means the script's `compute`\n * returned normally; `halt` means `runtime.error(...)` was thrown (the\n * compute body deliberately aborted the bar). Non-halt throws propagate\n * out of {@link runComputeStep} unchanged.\n *\n * @since 0.7\n * @stable\n * @example\n * const r: RunComputeStepOutcome = { kind: \"ok\" };\n * void r;\n */\nexport type RunComputeStepOutcome =\n | Readonly<{ kind: \"ok\" }>\n | Readonly<{ kind: \"halt\"; readonly message: string }>;\n\n/**\n * Configuration for {@link runComputeStep}. `eventKind` reaches the\n * runtime views so `barstate.*` picks up the right snapshot; `isTick`\n * discriminates the close-vs-tick state-slot lifecycle.\n *\n * @since 0.7\n * @stable\n * @example\n * const args = { state, eventKind: \"close\" as const, isTick: false };\n * void args;\n */\nexport type RunComputeStepArgs = Readonly<{\n readonly state: RunnerState;\n readonly eventKind: EventKind;\n readonly isTick: boolean;\n}>;\n\n/**\n * Reset the per-bar emission queues on a runner before its compute\n * runs. Exported for the dep / sibling step driver — single-script\n * callers go through {@link runComputeStep} which calls this\n * internally.\n *\n * @since 0.7\n * @stable\n * @example\n * // resetBarEmissions(state);\n */\nexport function resetBarEmissions(state: RunnerState): void {\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.alertConditions = [];\n state.emissions.logs = [];\n state.emissions.diagnostics = [];\n state.emissions.fromBar = state.barIndex;\n state.emissions.toBar = state.barIndex;\n state.runtimeContext.requestSecurityAlignments.clear();\n state.runtimeContext.requestSecurityAscendingBars.clear();\n state.runtimeContext.requestSecurityExprSeries?.clear();\n state.runtimeContext.logBudget = 0;\n state.runtimeContext.logBudgetExceededDiagnosed = false;\n}\n\n/**\n * Run the inner compute body of `state.compute` — set\n * `ACTIVE_RUNTIME_CONTEXT`, reset sub-id counters, optionally reset\n * tentative state slots, refresh views, invoke `compute`, commit /\n * flush state slots on close. Does NOT reset the per-bar emission\n * queues; callers do that exactly once via {@link resetBarEmissions}.\n *\n * `runtime.error(...)` halts clear the runner's visual emissions and\n * push a `runtime-error-thrown` diagnostic, matching the Phase-1\n * single-script behaviour byte-for-byte. Non-halt throws propagate\n * out unchanged.\n *\n * @since 0.7\n * @stable\n * @example\n * // const outcome = await runComputeBody({ state, eventKind: \"close\", isTick: false });\n * // void outcome;\n */\nexport async function runComputeBody(args: RunComputeStepArgs): Promise<RunComputeStepOutcome> {\n const { state, eventKind, isTick } = args;\n ACTIVE_RUNTIME_CONTEXT.current = state.runtimeContext;\n state.runtimeContext.isTick = isTick;\n let outcome: RunComputeStepOutcome = { kind: \"ok\" };\n try {\n resetSubIdCounters(state.runtimeContext);\n if (isTick) {\n resetTentativeStateSlots(state.runtimeContext);\n resetSeriesHeads(state.runtimeContext);\n resetTentativeArraySlots(state.runtimeContext);\n } else {\n // Advance every already-allocated series ring with a fresh NaN\n // head BEFORE compute, so a slot first allocated mid-compute (it\n // already holds its seeded head) is not double-advanced.\n advanceSeriesSlots(state.runtimeContext);\n }\n refreshRuntimeViews(state, eventKind);\n try {\n await Promise.resolve(state.compute(buildComputeContext(state)));\n if (!isTick) {\n commitStateSlots(state.runtimeContext);\n flushStateSlots(state.runtimeContext);\n commitSeriesSlots(state.runtimeContext);\n commitArraySlots(state.runtimeContext);\n }\n } catch (err) {\n if (!isRuntimeErrorHalt(err)) throw err;\n state.emissions.plots = [];\n state.emissions.drawings = [];\n state.emissions.alerts = [];\n state.emissions.alertConditions = [];\n state.emissions.logs = [];\n pushDiagnostic(state.emissions, {\n kind: \"diagnostic\",\n severity: \"error\",\n code: \"runtime-error-thrown\",\n message: err.message,\n slotId: null,\n bar: state.barIndex,\n });\n outcome = { kind: \"halt\", message: err.message };\n }\n } finally {\n if (isTick) state.runtimeContext.isTick = false;\n ACTIVE_RUNTIME_CONTEXT.current = null;\n }\n return outcome;\n}\n"]}
@@ -61,6 +61,7 @@ function matchesDescriptor(descriptor, value) {
61
61
  case "color":
62
62
  case "symbol":
63
63
  case "interval":
64
+ case "session":
64
65
  return typeof value === "string";
65
66
  case "enum":
66
67
  return typeof value === "string" && descriptor.options.includes(value);
@@ -1 +1 @@
1
- {"version":3,"file":"resolveInputs.js","sourceRoot":"","sources":["../../src/inputs/resolveInputs.ts"],"names":[],"mappings":"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","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 { InputDescriptor, ScriptManifest } from \"@invinite-org/chartlang-core\";\n\nimport type { RuntimeContext } from \"../runtimeContext.js\";\n\nconst SOURCE_FIELDS = new Set<string>([\n \"open\",\n \"high\",\n \"low\",\n \"close\",\n \"hl2\",\n \"hlc3\",\n \"ohlc4\",\n \"hlcc4\",\n]);\n\n/**\n * Resolve the script's effective `inputs` bag from manifest defaults plus\n * optional adapter-supplied overrides. Type-incompatible overrides fall back\n * to the descriptor default and emit `input-coercion-failed` once per\n * mount/key.\n *\n * @since 0.4\n * @stable\n * @example\n * // import { resolveInputs } from \"@invinite-org/chartlang-runtime\";\n * // const inputs = resolveInputs(manifest, { length: 20 }, ctx);\n * const fn: typeof resolveInputs = resolveInputs;\n * void fn;\n */\nexport function resolveInputs(\n manifest: ScriptManifest,\n overrides: Readonly<Record<string, unknown>>,\n ctx: RuntimeContext,\n): Readonly<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [key, descriptor] of Object.entries(manifest.inputs)) {\n const fallback = defaultValueFor(descriptor);\n if (!Object.hasOwn(overrides, key) || overrides[key] === undefined) {\n out[key] = fallback;\n continue;\n }\n const override = overrides[key];\n if (matchesDescriptor(descriptor, override)) {\n out[key] = override;\n continue;\n }\n pushInputDiagnostic(ctx, key, descriptor.kind, override);\n out[key] = fallback;\n }\n return Object.freeze(out);\n}\n\nfunction defaultValueFor(descriptor: InputDescriptor<unknown>): unknown {\n if (\"defaultValue\" in descriptor) return descriptor.defaultValue;\n return undefined;\n}\n\nfunction matchesDescriptor(descriptor: InputDescriptor<unknown>, value: unknown): boolean {\n switch (descriptor.kind) {\n case \"int\":\n return typeof value === \"number\" && Number.isInteger(value);\n case \"float\":\n case \"time\":\n case \"price\":\n return typeof value === \"number\" && Number.isFinite(value);\n case \"bool\":\n return typeof value === \"boolean\";\n case \"string\":\n case \"color\":\n case \"symbol\":\n case \"interval\":\n return typeof value === \"string\";\n case \"enum\":\n return typeof value === \"string\" && descriptor.options.includes(value);\n case \"source\":\n return typeof value === \"string\" && SOURCE_FIELDS.has(value);\n case \"external-series\":\n return value !== null && typeof value === \"object\";\n }\n}\n\nfunction pushInputDiagnostic(\n ctx: RuntimeContext,\n key: string,\n expected: string,\n value: unknown,\n): void {\n if (ctx.diagnosedInputKeys.has(key)) return;\n ctx.diagnosedInputKeys.add(key);\n ctx.emissions.diagnostics.push({\n kind: \"diagnostic\",\n severity: \"warning\",\n code: \"input-coercion-failed\",\n message: `input \"${key}\" expected ${expected}, got ${describeValue(value)}`,\n slotId: key,\n bar: null,\n });\n}\n\nfunction describeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (typeof value === \"number\" && Number.isNaN(value)) return \"NaN\";\n return typeof value;\n}\n"]}
1
+ {"version":3,"file":"resolveInputs.js","sourceRoot":"","sources":["../../src/inputs/resolveInputs.ts"],"names":[],"mappings":"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","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 { InputDescriptor, ScriptManifest } from \"@invinite-org/chartlang-core\";\n\nimport type { RuntimeContext } from \"../runtimeContext.js\";\n\nconst SOURCE_FIELDS = new Set<string>([\n \"open\",\n \"high\",\n \"low\",\n \"close\",\n \"hl2\",\n \"hlc3\",\n \"ohlc4\",\n \"hlcc4\",\n]);\n\n/**\n * Resolve the script's effective `inputs` bag from manifest defaults plus\n * optional adapter-supplied overrides. Type-incompatible overrides fall back\n * to the descriptor default and emit `input-coercion-failed` once per\n * mount/key.\n *\n * @since 0.4\n * @stable\n * @example\n * // import { resolveInputs } from \"@invinite-org/chartlang-runtime\";\n * // const inputs = resolveInputs(manifest, { length: 20 }, ctx);\n * const fn: typeof resolveInputs = resolveInputs;\n * void fn;\n */\nexport function resolveInputs(\n manifest: ScriptManifest,\n overrides: Readonly<Record<string, unknown>>,\n ctx: RuntimeContext,\n): Readonly<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [key, descriptor] of Object.entries(manifest.inputs)) {\n const fallback = defaultValueFor(descriptor);\n if (!Object.hasOwn(overrides, key) || overrides[key] === undefined) {\n out[key] = fallback;\n continue;\n }\n const override = overrides[key];\n if (matchesDescriptor(descriptor, override)) {\n out[key] = override;\n continue;\n }\n pushInputDiagnostic(ctx, key, descriptor.kind, override);\n out[key] = fallback;\n }\n return Object.freeze(out);\n}\n\nfunction defaultValueFor(descriptor: InputDescriptor<unknown>): unknown {\n if (\"defaultValue\" in descriptor) return descriptor.defaultValue;\n return undefined;\n}\n\nfunction matchesDescriptor(descriptor: InputDescriptor<unknown>, value: unknown): boolean {\n switch (descriptor.kind) {\n case \"int\":\n return typeof value === \"number\" && Number.isInteger(value);\n case \"float\":\n case \"time\":\n case \"price\":\n return typeof value === \"number\" && Number.isFinite(value);\n case \"bool\":\n return typeof value === \"boolean\";\n case \"string\":\n case \"color\":\n case \"symbol\":\n case \"interval\":\n case \"session\":\n return typeof value === \"string\";\n case \"enum\":\n return typeof value === \"string\" && descriptor.options.includes(value);\n case \"source\":\n return typeof value === \"string\" && SOURCE_FIELDS.has(value);\n case \"external-series\":\n return value !== null && typeof value === \"object\";\n }\n}\n\nfunction pushInputDiagnostic(\n ctx: RuntimeContext,\n key: string,\n expected: string,\n value: unknown,\n): void {\n if (ctx.diagnosedInputKeys.has(key)) return;\n ctx.diagnosedInputKeys.add(key);\n ctx.emissions.diagnostics.push({\n kind: \"diagnostic\",\n severity: \"warning\",\n code: \"input-coercion-failed\",\n message: `input \"${key}\" expected ${expected}, got ${describeValue(value)}`,\n slotId: key,\n bar: null,\n });\n}\n\nfunction describeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (typeof value === \"number\" && Number.isNaN(value)) return \"NaN\";\n return typeof value;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"persistentStateStore.runtime.d.ts","sourceRoot":"","sources":["../src/persistentStateStore.runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGR,aAAa,EAEhB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAa3D;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAwD9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAe9F;AAgGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAuBtF;AA2BD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8B7F;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CACxC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAKf"}
1
+ {"version":3,"file":"persistentStateStore.runtime.d.ts","sourceRoot":"","sources":["../src/persistentStateStore.runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGR,aAAa,EAEhB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgB3D;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AA0D9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAe9F;AAqGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAuBtF;AA2BD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8B7F;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CACxC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -2,7 +2,7 @@
2
2
  // See the LICENSE file in the repo root for full license text.
3
3
  import { pushDiagnostic } from "./emit/index.js";
4
4
  import { validateSnapshot } from "./persistentStateStore.validate.js";
5
- import { isSeriesSlotSnapshotKey, restoreSeriesSlots, restoreStateSlots, serialiseSeriesSlots, serialiseStateSlots, } from "./state/index.js";
5
+ import { isArraySlotSnapshotKey, isSeriesSlotSnapshotKey, restoreArraySlots, restoreSeriesSlots, restoreStateSlots, serialiseArraySlots, serialiseSeriesSlots, serialiseStateSlots, } from "./state/index.js";
6
6
  import { isTaSlotSnapshotKey, restoreTaSlots, serialiseTaSlots } from "./ta/persistence.js";
7
7
  /**
8
8
  * Default PLAN §6.9 write cadence for persistent snapshots.
@@ -33,6 +33,7 @@ function primarySectionSlots(state) {
33
33
  return Object.freeze({
34
34
  ...serialiseStateSlots(state.runtimeContext),
35
35
  ...serialiseSeriesSlots(state.runtimeContext),
36
+ ...serialiseArraySlots(state.runtimeContext),
36
37
  ...serialiseTaSlots(state.mainStream),
37
38
  });
38
39
  }
@@ -41,6 +42,7 @@ function runnerSection(ctx) {
41
42
  slots: Object.freeze({
42
43
  ...serialiseStateSlots(ctx),
43
44
  ...serialiseSeriesSlots(ctx),
45
+ ...serialiseArraySlots(ctx),
44
46
  }),
45
47
  });
46
48
  }
@@ -105,13 +107,15 @@ function resolveMainStreamSnapshot(snapshot, mainInterval) {
105
107
  const fallback = firstStreamKey(snapshot);
106
108
  return fallback === null ? undefined : snapshot.streams[fallback];
107
109
  }
108
- // Scalar `state.*` keys only — strip both `ta:` (restored onto the stream)
109
- // and `:series` (restored into `ctx.seriesSlots`) so the scalar slot store
110
- // receives neither.
110
+ // Scalar `state.*` keys only — strip `ta:` (restored onto the stream),
111
+ // `:series` (restored into `ctx.seriesSlots`), and `:array` (restored into
112
+ // `ctx.arraySlots`) so the scalar slot store receives none of them.
111
113
  function scalarStateSlots(slots) {
112
114
  const out = {};
113
115
  for (const [slotKey, value] of Object.entries(slots)) {
114
- if (!isTaSlotSnapshotKey(slotKey) && !isSeriesSlotSnapshotKey(slotKey)) {
116
+ if (!isTaSlotSnapshotKey(slotKey) &&
117
+ !isSeriesSlotSnapshotKey(slotKey) &&
118
+ !isArraySlotSnapshotKey(slotKey)) {
115
119
  out[slotKey] = value;
116
120
  }
117
121
  }
@@ -123,6 +127,7 @@ function scalarStateSlots(slots) {
123
127
  function restoreRunnerSlots(ctx, slots, capacity) {
124
128
  restoreStateSlots(ctx, scalarStateSlots(slots));
125
129
  restoreSeriesSlots(ctx, slots, capacity);
130
+ restoreArraySlots(ctx, slots);
126
131
  }
127
132
  function pushMalformedSection(state, message) {
128
133
  pushDiagnostic(state.emissions, {