@invinite-org/chartlang-runtime 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.
- package/CHANGELOG.md +307 -0
- package/dist/barPoint.d.ts +20 -0
- package/dist/barPoint.d.ts.map +1 -0
- package/dist/barPoint.js +72 -0
- package/dist/barPoint.js.map +1 -0
- package/dist/bufferSnapshot.d.ts +102 -0
- package/dist/bufferSnapshot.d.ts.map +1 -0
- package/dist/bufferSnapshot.js +119 -0
- package/dist/bufferSnapshot.js.map +1 -0
- package/dist/buildComputeContext.d.ts.map +1 -1
- package/dist/buildComputeContext.js +6 -1
- package/dist/buildComputeContext.js.map +1 -1
- package/dist/createScriptRunner.d.ts +6 -3
- package/dist/createScriptRunner.d.ts.map +1 -1
- package/dist/createScriptRunner.js +65 -11
- package/dist/createScriptRunner.js.map +1 -1
- package/dist/dep/DepRunner.d.ts +7 -0
- package/dist/dep/DepRunner.d.ts.map +1 -1
- package/dist/dep/DepRunner.js +4 -0
- package/dist/dep/DepRunner.js.map +1 -1
- package/dist/emit/barcolor.d.ts +44 -0
- package/dist/emit/barcolor.d.ts.map +1 -0
- package/dist/emit/barcolor.js +40 -0
- package/dist/emit/barcolor.js.map +1 -0
- package/dist/emit/bgcolor.d.ts +44 -0
- package/dist/emit/bgcolor.d.ts.map +1 -0
- package/dist/emit/bgcolor.js +45 -0
- package/dist/emit/bgcolor.js.map +1 -0
- package/dist/emit/draw/boxes/fillBetween.d.ts +45 -0
- package/dist/emit/draw/boxes/fillBetween.d.ts.map +1 -0
- package/dist/emit/draw/boxes/fillBetween.js +36 -0
- package/dist/emit/draw/boxes/fillBetween.js.map +1 -0
- package/dist/emit/draw/handle.d.ts +9 -0
- package/dist/emit/draw/handle.d.ts.map +1 -1
- package/dist/emit/draw/handle.js +65 -10
- package/dist/emit/draw/handle.js.map +1 -1
- package/dist/emit/draw/namespace.d.ts +4 -3
- package/dist/emit/draw/namespace.d.ts.map +1 -1
- package/dist/emit/draw/namespace.js +6 -3
- package/dist/emit/draw/namespace.js.map +1 -1
- package/dist/emit/index.d.ts +2 -0
- package/dist/emit/index.d.ts.map +1 -1
- package/dist/emit/index.js +2 -0
- package/dist/emit/index.js.map +1 -1
- package/dist/emit/plot.d.ts +30 -1
- package/dist/emit/plot.d.ts.map +1 -1
- package/dist/emit/plot.js +45 -1
- package/dist/emit/plot.js.map +1 -1
- package/dist/execution/dispose.d.ts.map +1 -1
- package/dist/execution/dispose.js +18 -0
- package/dist/execution/dispose.js.map +1 -1
- package/dist/execution/runComputeStep.d.ts.map +1 -1
- package/dist/execution/runComputeStep.js +12 -1
- package/dist/execution/runComputeStep.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inputs/resolveInputs.js +1 -0
- package/dist/inputs/resolveInputs.js.map +1 -1
- package/dist/persistentStateStore.runtime.d.ts.map +1 -1
- package/dist/persistentStateStore.runtime.js +26 -7
- package/dist/persistentStateStore.runtime.js.map +1 -1
- package/dist/primitives.d.ts +1 -1
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +7 -1
- package/dist/primitives.js.map +1 -1
- package/dist/request/index.d.ts +2 -1
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +2 -1
- package/dist/request/index.js.map +1 -1
- package/dist/request/lowerTf.d.ts.map +1 -1
- package/dist/request/lowerTf.js +6 -0
- package/dist/request/lowerTf.js.map +1 -1
- package/dist/request/requestNamespace.d.ts.map +1 -1
- package/dist/request/requestNamespace.js +30 -3
- package/dist/request/requestNamespace.js.map +1 -1
- package/dist/request/security.d.ts +40 -4
- package/dist/request/security.d.ts.map +1 -1
- package/dist/request/security.js +114 -40
- package/dist/request/security.js.map +1 -1
- package/dist/request/securityExprRunner.d.ts +137 -0
- package/dist/request/securityExprRunner.d.ts.map +1 -0
- package/dist/request/securityExprRunner.js +253 -0
- package/dist/request/securityExprRunner.js.map +1 -0
- package/dist/request/streamBars.d.ts +14 -1
- package/dist/request/streamBars.d.ts.map +1 -1
- package/dist/request/streamBars.js +39 -1
- package/dist/request/streamBars.js.map +1 -1
- package/dist/ringBuffer.d.ts +19 -0
- package/dist/ringBuffer.d.ts.map +1 -1
- package/dist/ringBuffer.js +23 -0
- package/dist/ringBuffer.js.map +1 -1
- package/dist/runtimeContext.d.ts +90 -5
- package/dist/runtimeContext.d.ts.map +1 -1
- package/dist/runtimeContext.js.map +1 -1
- package/dist/seriesView.d.ts +42 -17
- package/dist/seriesView.d.ts.map +1 -1
- package/dist/seriesView.js +65 -42
- package/dist/seriesView.js.map +1 -1
- package/dist/state/arrayPersistence.d.ts +48 -0
- package/dist/state/arrayPersistence.d.ts.map +1 -0
- package/dist/state/arrayPersistence.js +88 -0
- package/dist/state/arrayPersistence.js.map +1 -0
- package/dist/state/arrayStateSlot.d.ts +78 -0
- package/dist/state/arrayStateSlot.d.ts.map +1 -0
- package/dist/state/arrayStateSlot.js +116 -0
- package/dist/state/arrayStateSlot.js.map +1 -0
- package/dist/state/index.d.ts +4 -1
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +4 -1
- package/dist/state/index.js.map +1 -1
- package/dist/state/lifecycle.d.ts +68 -0
- package/dist/state/lifecycle.d.ts.map +1 -1
- package/dist/state/lifecycle.js +89 -0
- package/dist/state/lifecycle.js.map +1 -1
- package/dist/state/seriesPersistence.d.ts +48 -0
- package/dist/state/seriesPersistence.d.ts.map +1 -0
- package/dist/state/seriesPersistence.js +87 -0
- package/dist/state/seriesPersistence.js.map +1 -0
- package/dist/state/seriesSlot.d.ts +105 -0
- package/dist/state/seriesSlot.d.ts.map +1 -0
- package/dist/state/seriesSlot.js +123 -0
- package/dist/state/seriesSlot.js.map +1 -0
- package/dist/state/stateNamespace.d.ts.map +1 -1
- package/dist/state/stateNamespace.js +55 -0
- package/dist/state/stateNamespace.js.map +1 -1
- package/dist/streamState.d.ts +25 -19
- package/dist/streamState.d.ts.map +1 -1
- package/dist/streamState.js +40 -66
- package/dist/streamState.js.map +1 -1
- package/dist/ta/adx.d.ts +3 -2
- package/dist/ta/adx.d.ts.map +1 -1
- package/dist/ta/adx.js +3 -2
- package/dist/ta/adx.js.map +1 -1
- package/dist/ta/alma.d.ts +6 -4
- package/dist/ta/alma.d.ts.map +1 -1
- package/dist/ta/alma.js +19 -6
- package/dist/ta/alma.js.map +1 -1
- package/dist/ta/atr.d.ts +3 -2
- package/dist/ta/atr.d.ts.map +1 -1
- package/dist/ta/atr.js +3 -2
- package/dist/ta/atr.js.map +1 -1
- package/dist/ta/bb.d.ts +3 -2
- package/dist/ta/bb.d.ts.map +1 -1
- package/dist/ta/bb.js +3 -2
- package/dist/ta/bb.js.map +1 -1
- package/dist/ta/chaikinOsc.d.ts +3 -2
- package/dist/ta/chaikinOsc.d.ts.map +1 -1
- package/dist/ta/chaikinOsc.js +3 -2
- package/dist/ta/chaikinOsc.js.map +1 -1
- package/dist/ta/crossover.d.ts +3 -2
- package/dist/ta/crossover.d.ts.map +1 -1
- package/dist/ta/crossover.js +3 -2
- package/dist/ta/crossover.js.map +1 -1
- package/dist/ta/crossunder.d.ts +3 -2
- package/dist/ta/crossunder.d.ts.map +1 -1
- package/dist/ta/crossunder.js +3 -2
- package/dist/ta/crossunder.js.map +1 -1
- package/dist/ta/dmi.d.ts +4 -3
- package/dist/ta/dmi.d.ts.map +1 -1
- package/dist/ta/dmi.js +4 -3
- package/dist/ta/dmi.js.map +1 -1
- package/dist/ta/ema.d.ts +3 -2
- package/dist/ta/ema.d.ts.map +1 -1
- package/dist/ta/ema.js +3 -2
- package/dist/ta/ema.js.map +1 -1
- package/dist/ta/eom.d.ts +3 -1
- package/dist/ta/eom.d.ts.map +1 -1
- package/dist/ta/eom.js +3 -1
- package/dist/ta/eom.js.map +1 -1
- package/dist/ta/highestbars.d.ts +25 -0
- package/dist/ta/highestbars.d.ts.map +1 -0
- package/dist/ta/highestbars.js +106 -0
- package/dist/ta/highestbars.js.map +1 -0
- package/dist/ta/historicalVolatility.d.ts +3 -2
- package/dist/ta/historicalVolatility.d.ts.map +1 -1
- package/dist/ta/historicalVolatility.js +3 -2
- package/dist/ta/historicalVolatility.js.map +1 -1
- package/dist/ta/ichimoku.d.ts +3 -1
- package/dist/ta/ichimoku.d.ts.map +1 -1
- package/dist/ta/ichimoku.js +3 -1
- package/dist/ta/ichimoku.js.map +1 -1
- package/dist/ta/lowestbars.d.ts +25 -0
- package/dist/ta/lowestbars.d.ts.map +1 -0
- package/dist/ta/lowestbars.js +102 -0
- package/dist/ta/lowestbars.js.map +1 -0
- package/dist/ta/macd.d.ts +3 -2
- package/dist/ta/macd.d.ts.map +1 -1
- package/dist/ta/macd.js +3 -2
- package/dist/ta/macd.js.map +1 -1
- package/dist/ta/massIndex.d.ts +3 -2
- package/dist/ta/massIndex.d.ts.map +1 -1
- package/dist/ta/massIndex.js +3 -2
- package/dist/ta/massIndex.js.map +1 -1
- package/dist/ta/mfi.d.ts +3 -1
- package/dist/ta/mfi.d.ts.map +1 -1
- package/dist/ta/mfi.js +3 -1
- package/dist/ta/mfi.js.map +1 -1
- package/dist/ta/netVolume.d.ts +3 -1
- package/dist/ta/netVolume.d.ts.map +1 -1
- package/dist/ta/netVolume.js +3 -1
- package/dist/ta/netVolume.js.map +1 -1
- package/dist/ta/nvi.d.ts +3 -1
- package/dist/ta/nvi.d.ts.map +1 -1
- package/dist/ta/nvi.js +3 -1
- package/dist/ta/nvi.js.map +1 -1
- package/dist/ta/persistence.d.ts.map +1 -1
- package/dist/ta/persistence.js +1 -40
- package/dist/ta/persistence.js.map +1 -1
- package/dist/ta/ppo.d.ts +3 -2
- package/dist/ta/ppo.d.ts.map +1 -1
- package/dist/ta/ppo.js +3 -2
- package/dist/ta/ppo.js.map +1 -1
- package/dist/ta/pvi.d.ts +3 -1
- package/dist/ta/pvi.d.ts.map +1 -1
- package/dist/ta/pvi.js +3 -1
- package/dist/ta/pvi.js.map +1 -1
- package/dist/ta/pvo.d.ts +3 -1
- package/dist/ta/pvo.d.ts.map +1 -1
- package/dist/ta/pvo.js +3 -1
- package/dist/ta/pvo.js.map +1 -1
- package/dist/ta/pvt.d.ts +3 -1
- package/dist/ta/pvt.d.ts.map +1 -1
- package/dist/ta/pvt.js +3 -1
- package/dist/ta/pvt.js.map +1 -1
- package/dist/ta/registry.d.ts +7 -1
- package/dist/ta/registry.d.ts.map +1 -1
- package/dist/ta/registry.js +4 -0
- package/dist/ta/registry.js.map +1 -1
- package/dist/ta/rsi.d.ts +3 -2
- package/dist/ta/rsi.d.ts.map +1 -1
- package/dist/ta/rsi.js +3 -2
- package/dist/ta/rsi.js.map +1 -1
- package/dist/ta/rvi.d.ts +3 -2
- package/dist/ta/rvi.d.ts.map +1 -1
- package/dist/ta/rvi.js +3 -2
- package/dist/ta/rvi.js.map +1 -1
- package/dist/ta/sessionVolumeProfile.d.ts.map +1 -1
- package/dist/ta/sessionVolumeProfile.js +1 -17
- package/dist/ta/sessionVolumeProfile.js.map +1 -1
- package/dist/ta/sma.d.ts +6 -3
- package/dist/ta/sma.d.ts.map +1 -1
- package/dist/ta/sma.js +6 -3
- package/dist/ta/sma.js.map +1 -1
- package/dist/ta/stdev.d.ts +3 -2
- package/dist/ta/stdev.d.ts.map +1 -1
- package/dist/ta/stdev.js +3 -2
- package/dist/ta/stdev.js.map +1 -1
- package/dist/ta/trendStrengthIndex.d.ts +3 -2
- package/dist/ta/trendStrengthIndex.d.ts.map +1 -1
- package/dist/ta/trendStrengthIndex.js +3 -2
- package/dist/ta/trendStrengthIndex.js.map +1 -1
- package/dist/ta/trix.d.ts +4 -3
- package/dist/ta/trix.d.ts.map +1 -1
- package/dist/ta/trix.js +4 -3
- package/dist/ta/trix.js.map +1 -1
- package/dist/ta/vortex.d.ts +3 -2
- package/dist/ta/vortex.d.ts.map +1 -1
- package/dist/ta/vortex.js +3 -2
- package/dist/ta/vortex.js.map +1 -1
- package/dist/time-accessors/civil.d.ts +73 -0
- package/dist/time-accessors/civil.d.ts.map +1 -0
- package/dist/time-accessors/civil.js +105 -0
- package/dist/time-accessors/civil.js.map +1 -0
- package/dist/time-accessors/index.d.ts +8 -0
- package/dist/time-accessors/index.d.ts.map +1 -0
- package/dist/time-accessors/index.js +9 -0
- package/dist/time-accessors/index.js.map +1 -0
- package/dist/time-accessors/sessionAccessors.d.ts +50 -0
- package/dist/time-accessors/sessionAccessors.d.ts.map +1 -0
- package/dist/time-accessors/sessionAccessors.js +79 -0
- package/dist/time-accessors/sessionAccessors.js.map +1 -0
- package/dist/time-accessors/sessionWindow.d.ts +17 -0
- package/dist/time-accessors/sessionWindow.d.ts.map +1 -0
- package/dist/time-accessors/sessionWindow.js +41 -0
- package/dist/time-accessors/sessionWindow.js.map +1 -0
- package/dist/time-accessors/timeAccessors.d.ts +54 -0
- package/dist/time-accessors/timeAccessors.d.ts.map +1 -0
- package/dist/time-accessors/timeAccessors.js +132 -0
- package/dist/time-accessors/timeAccessors.js.map +1 -0
- package/dist/time-accessors/tzDiagnostic.d.ts +17 -0
- package/dist/time-accessors/tzDiagnostic.d.ts.map +1 -0
- package/dist/time-accessors/tzDiagnostic.js +34 -0
- package/dist/time-accessors/tzDiagnostic.js.map +1 -0
- package/dist/time-accessors/tzOffset.d.ts +31 -0
- package/dist/time-accessors/tzOffset.d.ts.map +1 -0
- package/dist/time-accessors/tzOffset.js +67 -0
- package/dist/time-accessors/tzOffset.js.map +1 -0
- package/package.json +3 -3
- package/dist/ta/lib/applyOffset.d.ts +0 -19
- package/dist/ta/lib/applyOffset.d.ts.map +0 -1
- package/dist/ta/lib/applyOffset.js +0 -38
- package/dist/ta/lib/applyOffset.js.map +0 -1
package/dist/seriesView.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seriesView.js","sourceRoot":"","sources":["../src/seriesView.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAM/D
|
|
1
|
+
{"version":3,"file":"seriesView.js","sourceRoot":"","sources":["../src/seriesView.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAM/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,cAAc,CAAI,GAAsB;IACpD,OAAO,IAAI,KAAK,CAAC,EAAe,EAAE;QAC9B,GAAG,CAAC,OAAO,EAAE,IAAI;YACb,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC;YACzC,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,IAAI,KAAK,MAAM,CAAC,WAAW;gBAAE,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACxD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBACvB,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,IAAI;YACb,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACzD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,CAAC,WAAW;gBAAE,OAAO,IAAI,CAAC;YACnE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBACvB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;KACJ,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,aAAa,GAAG,IAAI,OAAO,EAA2B,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,qBAAqB,CAAI,GAAsB,EAAE,MAAc;IAC3E,MAAM,IAAI,GAAG,cAAc,CAAI,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,CAAC;QAAE,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAAC,MAAuB;IAClD,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1C,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 { Series } from \"@invinite-org/chartlang-core\";\n\nimport type { RingBufferLike } from \"./ringBuffer.js\";\n\n/**\n * Wrap a `RingBufferLike<T>` in the user-facing `Series<T>` Proxy shape\n *. The Proxy is created **once per backing buffer**\n * at stream/slot construction time and re-used across every bar — its\n * identity is stable so script authors can keep `const ema = ta.ema(...)`\n * at the top of `compute` and reference `ema` the same way every bar.\n *\n * Property reads dispatch as follows:\n * - `series.current` → `buf.at(0)`\n * - `series.length` → `buf.length`\n * - `series.valueOf` / `series[Symbol.toPrimitive]` → a function returning\n * `buf.at(0)`, so a numeric series coerces to its **current** value in any\n * value context (`series * 2`, `series > x`, `` `${series}` ``,\n * `Math.max(series, …)`). This is what lets `bar.close` be used both as a\n * scalar and indexed as a series. Coercion is harmless for non-numeric\n * buffers — nothing coerces those. Note `Number.isFinite(series)` is still\n * `false` (it does not coerce) and `series === 42` is `false` (object vs\n * number); use `series.current` / `+series` there.\n * - `series[n]` (string coerces to a non-negative integer) → `buf.at(n)`\n * - any other key → `undefined`\n *\n * For numeric buffers (`Float64RingBuffer`) out-of-range reads return\n * `NaN`; for object buffers they return `undefined`. The Proxy passes\n * the underlying sentinel through verbatim.\n *\n * @since 0.1\n * @example\n * // import { Float64RingBuffer, makeSeriesView }\n * // from \"@invinite-org/chartlang-runtime\";\n * // const buf = new Float64RingBuffer(8);\n * // const view = makeSeriesView<number>(buf);\n * // buf.append(42);\n * // view.current; // 42\n * // view[0]; // 42\n * // view.length; // 1\n */\nexport function makeSeriesView<T>(buf: RingBufferLike<T>): Series<T> {\n return new Proxy({} as Series<T>, {\n get(_target, prop) {\n if (prop === \"current\") return buf.at(0);\n if (prop === \"length\") return buf.length;\n if (prop === \"valueOf\") return () => buf.at(0);\n if (prop === Symbol.toPrimitive) return () => buf.at(0);\n if (typeof prop === \"string\") {\n const n = Number(prop);\n if (Number.isInteger(n) && n >= 0) return buf.at(n);\n }\n return undefined;\n },\n has(_target, prop) {\n if (prop === \"current\" || prop === \"length\") return true;\n if (prop === \"valueOf\" || prop === Symbol.toPrimitive) return true;\n if (typeof prop === \"string\") {\n const n = Number(prop);\n return Number.isInteger(n) && n >= 0;\n }\n return false;\n },\n });\n}\n\n/**\n * Module-level side-table recording the **presentation x-shift** declared\n * for an offset-tagged Series view. `offset` is no longer a value-read\n * transform (Option A, bidirectional-plot-offset): the series value is\n * always the unshifted `buf.at(0)`; the recorded offset rides the plot\n * emission as `PlotEmission.xShift` so the adapter renders the series\n * shifted (`+n` right / future, `−n` left / past) without changing the\n * numbers alerts and `state.*` see. Keyed weakly on the view object so a\n * dropped slot's tag is collected with it.\n */\nconst seriesOffsets = new WeakMap<Series<unknown>, number>();\n\n/**\n * Offset-tagging variant of {@link makeSeriesView}. It returns the\n * **unshifted** view (delegating to {@link makeSeriesView}) and, for a\n * non-zero `offset`, records `view → offset` in a module-level\n * `WeakMap` side-table read by `plot()` via {@link seriesOffsetOf}. The\n * offset is **presentation-only** — `view.current` is `buf.at(0)`, not a\n * value `offset` bars ago — so both shift directions are expressible and\n * alerts / `state.*` see the unshifted value. `offset === 0` records\n * nothing (byte-identical to a plain {@link makeSeriesView}).\n *\n * Callers cache the returned view per `(slot, offset)` pair so the\n * view's identity — and therefore its recorded offset — stays stable\n * across bars.\n *\n * @since 0.2\n * @stable\n * @example\n * // import { Float64RingBuffer, makeShiftedSeriesView, seriesOffsetOf }\n * // from \"@invinite-org/chartlang-runtime\";\n * // const buf = new Float64RingBuffer(8);\n * // buf.append(10); buf.append(20); buf.append(30);\n * // const view = makeShiftedSeriesView<number>(buf, 5);\n * // view.current; // 30 (unshifted — the offset does NOT lag the read)\n * // seriesOffsetOf(view); // 5 (presentation x-shift carried to the emission)\n */\nexport function makeShiftedSeriesView<T>(buf: RingBufferLike<T>, offset: number): Series<T> {\n const view = makeSeriesView<T>(buf);\n if (offset !== 0) seriesOffsets.set(view, offset);\n return view;\n}\n\n/**\n * Read the presentation x-shift recorded for `series` by\n * {@link makeShiftedSeriesView}, or `0` when the series is untagged (a\n * plain {@link makeSeriesView} view, an `offset === 0` view, or any\n * non-runtime Series). `plot()` calls this to populate\n * `PlotEmission.xShift`; a `0` result omits the field so a no-offset\n * plot stays byte-identical to today.\n *\n * @since 0.2\n * @stable\n * @example\n * // import { Float64RingBuffer, makeShiftedSeriesView, seriesOffsetOf }\n * // from \"@invinite-org/chartlang-runtime\";\n * // const buf = new Float64RingBuffer(8);\n * // const shifted = makeShiftedSeriesView<number>(buf, -3);\n * // seriesOffsetOf(shifted); // -3\n */\nexport function seriesOffsetOf(series: Series<unknown>): number {\n return seriesOffsets.get(series) ?? 0;\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { JsonValue } from "@invinite-org/chartlang-core";
|
|
2
|
+
import type { RuntimeContext } from "../runtimeContext.js";
|
|
3
|
+
/**
|
|
4
|
+
* Return whether a snapshot slot key belongs to the `state.array` namespace
|
|
5
|
+
* (a `${slotIdPrefix}${slotId}:array` key). Lets the restore router separate
|
|
6
|
+
* array slots from scalar `state.*` (`:state`), `state.series` (`:series`), and
|
|
7
|
+
* `ta.*` (`ta:`) slots, all of which share one `slots` record.
|
|
8
|
+
*
|
|
9
|
+
* @since 1.3
|
|
10
|
+
* @internal
|
|
11
|
+
* @stable
|
|
12
|
+
* @example
|
|
13
|
+
* isArraySlotSnapshotKey("x.chart.ts:1:1:array"); // true
|
|
14
|
+
*/
|
|
15
|
+
export declare function isArraySlotSnapshotKey(key: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Serialise the runner's `state.array` slots into JSON-clean snapshot entries
|
|
18
|
+
* keyed by the same `${prefix}${slotId}:array` key the slot store uses. Both
|
|
19
|
+
* rings ride {@link Float64RingBuffer.serialiseSnapshotBuffer}; `capacity` is
|
|
20
|
+
* recorded so restore can detect a script-edited capacity and degrade.
|
|
21
|
+
*
|
|
22
|
+
* @since 1.3
|
|
23
|
+
* @internal
|
|
24
|
+
* @stable
|
|
25
|
+
* @example
|
|
26
|
+
* // const entries = serialiseArraySlots(ctx);
|
|
27
|
+
* const entries = {};
|
|
28
|
+
* void entries;
|
|
29
|
+
*/
|
|
30
|
+
export declare function serialiseArraySlots(ctx: RuntimeContext): Readonly<Record<string, JsonValue>>;
|
|
31
|
+
/**
|
|
32
|
+
* Restore `state.array` slots from namespaced snapshot entries into
|
|
33
|
+
* `ctx.arraySlots`, rebuilding each ring at the *persisted* `capacity`. Non-array
|
|
34
|
+
* keys are ignored; a malformed snapshot — or one whose ring shape no longer
|
|
35
|
+
* matches its recorded `capacity` — is skipped so the slot starts fresh (a
|
|
36
|
+
* script-edited `state.array(cap)` literal degrades, it does not throw). The
|
|
37
|
+
* handle identity is recreated on restore (acceptable — same as `state.series`).
|
|
38
|
+
*
|
|
39
|
+
* @since 1.3
|
|
40
|
+
* @internal
|
|
41
|
+
* @stable
|
|
42
|
+
* @example
|
|
43
|
+
* // restoreArraySlots(ctx, snapshot.slots);
|
|
44
|
+
* const restored = true;
|
|
45
|
+
* void restored;
|
|
46
|
+
*/
|
|
47
|
+
export declare function restoreArraySlots(ctx: RuntimeContext, slots: Readonly<Record<string, unknown>>): void;
|
|
48
|
+
//# sourceMappingURL=arrayPersistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrayPersistence.d.ts","sourceRoot":"","sources":["../../src/state/arrayPersistence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAS9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAM3D;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAW5F;AAaD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC7B,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,IAAI,CASN"}
|
|
@@ -0,0 +1,88 @@
|
|
|
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 { isBufferSnapshot, isInteger, isRecord, restoreBuffer, serialiseBuffer, } from "../bufferSnapshot.js";
|
|
4
|
+
import { restoreArrayStateSlot } from "./arrayStateSlot.js";
|
|
5
|
+
const ARRAY_SLOT_SUFFIX = ":array";
|
|
6
|
+
/**
|
|
7
|
+
* Return whether a snapshot slot key belongs to the `state.array` namespace
|
|
8
|
+
* (a `${slotIdPrefix}${slotId}:array` key). Lets the restore router separate
|
|
9
|
+
* array slots from scalar `state.*` (`:state`), `state.series` (`:series`), and
|
|
10
|
+
* `ta.*` (`ta:`) slots, all of which share one `slots` record.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.3
|
|
13
|
+
* @internal
|
|
14
|
+
* @stable
|
|
15
|
+
* @example
|
|
16
|
+
* isArraySlotSnapshotKey("x.chart.ts:1:1:array"); // true
|
|
17
|
+
*/
|
|
18
|
+
export function isArraySlotSnapshotKey(key) {
|
|
19
|
+
return key.endsWith(ARRAY_SLOT_SUFFIX);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Serialise the runner's `state.array` slots into JSON-clean snapshot entries
|
|
23
|
+
* keyed by the same `${prefix}${slotId}:array` key the slot store uses. Both
|
|
24
|
+
* rings ride {@link Float64RingBuffer.serialiseSnapshotBuffer}; `capacity` is
|
|
25
|
+
* recorded so restore can detect a script-edited capacity and degrade.
|
|
26
|
+
*
|
|
27
|
+
* @since 1.3
|
|
28
|
+
* @internal
|
|
29
|
+
* @stable
|
|
30
|
+
* @example
|
|
31
|
+
* // const entries = serialiseArraySlots(ctx);
|
|
32
|
+
* const entries = {};
|
|
33
|
+
* void entries;
|
|
34
|
+
*/
|
|
35
|
+
export function serialiseArraySlots(ctx) {
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const [key, slot] of ctx.arraySlots.entries()) {
|
|
38
|
+
out[key] = {
|
|
39
|
+
kind: "state.array",
|
|
40
|
+
capacity: slot.capacity,
|
|
41
|
+
committed: serialiseBuffer(slot.committedRing),
|
|
42
|
+
tentative: serialiseBuffer(slot.tentativeRing),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze(out);
|
|
46
|
+
}
|
|
47
|
+
function restoreArraySlotSnapshot(snapshot) {
|
|
48
|
+
if (!isRecord(snapshot) || snapshot.kind !== "state.array")
|
|
49
|
+
return null;
|
|
50
|
+
if (!isInteger(snapshot.capacity) || snapshot.capacity <= 0)
|
|
51
|
+
return null;
|
|
52
|
+
const { committed, tentative } = snapshot;
|
|
53
|
+
if (!isBufferSnapshot(committed) || !isBufferSnapshot(tentative))
|
|
54
|
+
return null;
|
|
55
|
+
const committedRing = restoreBuffer(committed, snapshot.capacity);
|
|
56
|
+
const tentativeRing = restoreBuffer(tentative, snapshot.capacity);
|
|
57
|
+
if (committedRing === null || tentativeRing === null)
|
|
58
|
+
return null;
|
|
59
|
+
return restoreArrayStateSlot(committedRing, tentativeRing);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Restore `state.array` slots from namespaced snapshot entries into
|
|
63
|
+
* `ctx.arraySlots`, rebuilding each ring at the *persisted* `capacity`. Non-array
|
|
64
|
+
* keys are ignored; a malformed snapshot — or one whose ring shape no longer
|
|
65
|
+
* matches its recorded `capacity` — is skipped so the slot starts fresh (a
|
|
66
|
+
* script-edited `state.array(cap)` literal degrades, it does not throw). The
|
|
67
|
+
* handle identity is recreated on restore (acceptable — same as `state.series`).
|
|
68
|
+
*
|
|
69
|
+
* @since 1.3
|
|
70
|
+
* @internal
|
|
71
|
+
* @stable
|
|
72
|
+
* @example
|
|
73
|
+
* // restoreArraySlots(ctx, snapshot.slots);
|
|
74
|
+
* const restored = true;
|
|
75
|
+
* void restored;
|
|
76
|
+
*/
|
|
77
|
+
export function restoreArraySlots(ctx, slots) {
|
|
78
|
+
ctx.arraySlots.clear();
|
|
79
|
+
for (const [key, value] of Object.entries(slots)) {
|
|
80
|
+
if (!isArraySlotSnapshotKey(key))
|
|
81
|
+
continue;
|
|
82
|
+
const slot = restoreArraySlotSnapshot(value);
|
|
83
|
+
if (slot !== null) {
|
|
84
|
+
ctx.arraySlots.set(key, slot);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=arrayPersistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrayPersistence.js","sourceRoot":"","sources":["../../src/state/arrayPersistence.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D,OAAO,EACH,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,aAAa,EACb,eAAe,GAClB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAEnC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAC9C,OAAO,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAmB;IACnD,MAAM,GAAG,GAA8B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QACjD,GAAG,CAAC,GAAG,CAAC,GAAG;YACP,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC;YAC9C,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC;SACjD,CAAC;IACN,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,wBAAwB,CAAC,QAAiB;IAC/C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IACxE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAC1C,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClE,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClE,OAAO,qBAAqB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC7B,GAAmB,EACnB,KAAwC;IAExC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC;YAAE,SAAS;QAC3C,MAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;IACL,CAAC;AACL,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 { JsonValue } from \"@invinite-org/chartlang-core\";\n\nimport {\n isBufferSnapshot,\n isInteger,\n isRecord,\n restoreBuffer,\n serialiseBuffer,\n} from \"../bufferSnapshot.js\";\nimport type { RuntimeContext } from \"../runtimeContext.js\";\nimport type { ArrayStateSlot } from \"./arrayStateSlot.js\";\nimport { restoreArrayStateSlot } from \"./arrayStateSlot.js\";\n\nconst ARRAY_SLOT_SUFFIX = \":array\";\n\n/**\n * Return whether a snapshot slot key belongs to the `state.array` namespace\n * (a `${slotIdPrefix}${slotId}:array` key). Lets the restore router separate\n * array slots from scalar `state.*` (`:state`), `state.series` (`:series`), and\n * `ta.*` (`ta:`) slots, all of which share one `slots` record.\n *\n * @since 1.3\n * @internal\n * @stable\n * @example\n * isArraySlotSnapshotKey(\"x.chart.ts:1:1:array\"); // true\n */\nexport function isArraySlotSnapshotKey(key: string): boolean {\n return key.endsWith(ARRAY_SLOT_SUFFIX);\n}\n\n/**\n * Serialise the runner's `state.array` slots into JSON-clean snapshot entries\n * keyed by the same `${prefix}${slotId}:array` key the slot store uses. Both\n * rings ride {@link Float64RingBuffer.serialiseSnapshotBuffer}; `capacity` is\n * recorded so restore can detect a script-edited capacity and degrade.\n *\n * @since 1.3\n * @internal\n * @stable\n * @example\n * // const entries = serialiseArraySlots(ctx);\n * const entries = {};\n * void entries;\n */\nexport function serialiseArraySlots(ctx: RuntimeContext): Readonly<Record<string, JsonValue>> {\n const out: Record<string, JsonValue> = {};\n for (const [key, slot] of ctx.arraySlots.entries()) {\n out[key] = {\n kind: \"state.array\",\n capacity: slot.capacity,\n committed: serialiseBuffer(slot.committedRing),\n tentative: serialiseBuffer(slot.tentativeRing),\n };\n }\n return Object.freeze(out);\n}\n\nfunction restoreArraySlotSnapshot(snapshot: unknown): ArrayStateSlot | null {\n if (!isRecord(snapshot) || snapshot.kind !== \"state.array\") return null;\n if (!isInteger(snapshot.capacity) || snapshot.capacity <= 0) return null;\n const { committed, tentative } = snapshot;\n if (!isBufferSnapshot(committed) || !isBufferSnapshot(tentative)) return null;\n const committedRing = restoreBuffer(committed, snapshot.capacity);\n const tentativeRing = restoreBuffer(tentative, snapshot.capacity);\n if (committedRing === null || tentativeRing === null) return null;\n return restoreArrayStateSlot(committedRing, tentativeRing);\n}\n\n/**\n * Restore `state.array` slots from namespaced snapshot entries into\n * `ctx.arraySlots`, rebuilding each ring at the *persisted* `capacity`. Non-array\n * keys are ignored; a malformed snapshot — or one whose ring shape no longer\n * matches its recorded `capacity` — is skipped so the slot starts fresh (a\n * script-edited `state.array(cap)` literal degrades, it does not throw). The\n * handle identity is recreated on restore (acceptable — same as `state.series`).\n *\n * @since 1.3\n * @internal\n * @stable\n * @example\n * // restoreArraySlots(ctx, snapshot.slots);\n * const restored = true;\n * void restored;\n */\nexport function restoreArraySlots(\n ctx: RuntimeContext,\n slots: Readonly<Record<string, unknown>>,\n): void {\n ctx.arraySlots.clear();\n for (const [key, value] of Object.entries(slots)) {\n if (!isArraySlotSnapshotKey(key)) continue;\n const slot = restoreArraySlotSnapshot(value);\n if (slot !== null) {\n ctx.arraySlots.set(key, slot);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { MutableArraySlot } from "@invinite-org/chartlang-core";
|
|
2
|
+
import { Float64RingBuffer } from "../ringBuffer.js";
|
|
3
|
+
/**
|
|
4
|
+
* Runtime slot behind a script-facing `state.array(capacity)` handle. Unlike
|
|
5
|
+
* the scalar `StateSlot` (one committed/tentative *value*) or the `SeriesSlot`
|
|
6
|
+
* (one ring advanced once per bar), this is a **bounded FIFO collection** with
|
|
7
|
+
* two `Float64RingBuffer`s: `tentativeRing` holds the live, author-facing
|
|
8
|
+
* pushes; `committedRing` is the bar-close snapshot a tick rolls back to.
|
|
9
|
+
*
|
|
10
|
+
* The committed/tentative discipline mirrors `StateSlot`: pushes during a tick
|
|
11
|
+
* mutate the tentative ring; a head-bar-replacing tick resets it from committed
|
|
12
|
+
* (in-progress pushes discarded); a bar close commits tentative into committed.
|
|
13
|
+
* The two-ring copy is `O(capacity)` per tick via a typed-array
|
|
14
|
+
* {@link Float64RingBuffer.copyFrom} memcpy — bounded because `capacity` is a
|
|
15
|
+
* required compile-time literal (see `tasks/future/state-array/README.md`
|
|
16
|
+
* Architecture Decisions: "Tick rollback = a two-ring buffer copy").
|
|
17
|
+
*
|
|
18
|
+
* @since 1.3
|
|
19
|
+
* @stable
|
|
20
|
+
* @example
|
|
21
|
+
* const slot = new ArrayStateSlot(4);
|
|
22
|
+
* slot.handle.push(1);
|
|
23
|
+
* slot.onBarClose();
|
|
24
|
+
* slot.handle.get(0); // 1
|
|
25
|
+
*/
|
|
26
|
+
export declare class ArrayStateSlot {
|
|
27
|
+
readonly capacity: number;
|
|
28
|
+
readonly committedRing: Float64RingBuffer;
|
|
29
|
+
readonly tentativeRing: Float64RingBuffer;
|
|
30
|
+
readonly handle: MutableArraySlot<number>;
|
|
31
|
+
constructor(capacity: number);
|
|
32
|
+
/** Commit the tentative ring into the committed ring (bar close). */
|
|
33
|
+
onBarClose(): void;
|
|
34
|
+
/** Roll the tentative ring back to the committed ring (head-replacing tick). */
|
|
35
|
+
onBarTick(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the identity-stable {@link MutableArraySlot} handle over an
|
|
39
|
+
* {@link ArrayStateSlot}. All author-facing reads and writes route through the
|
|
40
|
+
* **tentative** ring (mirroring `StateSlot.set`/`StateSlot.get`, which read and
|
|
41
|
+
* write `tentative` for non-tick slots); the committed ring is the rollback
|
|
42
|
+
* source. `get(out-of-range)` returns `NaN` (the ring's `at` contract), never
|
|
43
|
+
* throws. A plain object with getters — no `Proxy` — because the handle has a
|
|
44
|
+
* fixed method set and is deliberately not number-coercible.
|
|
45
|
+
*
|
|
46
|
+
* @since 1.3
|
|
47
|
+
* @stable
|
|
48
|
+
* @example
|
|
49
|
+
* // const handle = buildArrayHandle(new ArrayStateSlot(4));
|
|
50
|
+
* // handle.push(1);
|
|
51
|
+
* // handle.last(); // 1
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildArrayHandle(slot: ArrayStateSlot): MutableArraySlot<number>;
|
|
54
|
+
/**
|
|
55
|
+
* Allocate a fresh {@link ArrayStateSlot} — both rings empty (`size === 0`).
|
|
56
|
+
* Unlike `state.float(init)` there is no seed value: an empty collection starts
|
|
57
|
+
* empty.
|
|
58
|
+
*
|
|
59
|
+
* @since 1.3
|
|
60
|
+
* @stable
|
|
61
|
+
* @example
|
|
62
|
+
* // const slot = createArrayStateSlot(20);
|
|
63
|
+
* // slot.handle.size; // 0
|
|
64
|
+
*/
|
|
65
|
+
export declare function createArrayStateSlot(capacity: number): ArrayStateSlot;
|
|
66
|
+
/**
|
|
67
|
+
* Rebuild an {@link ArrayStateSlot} from already-restored rings (snapshot
|
|
68
|
+
* path). The handle identity is recreated — acceptable, same as
|
|
69
|
+
* `state.series` / `ta.*` restore.
|
|
70
|
+
*
|
|
71
|
+
* @since 1.3
|
|
72
|
+
* @stable
|
|
73
|
+
* @example
|
|
74
|
+
* // const slot = restoreArrayStateSlot(committedRing, tentativeRing);
|
|
75
|
+
* // slot.handle.size;
|
|
76
|
+
*/
|
|
77
|
+
export declare function restoreArrayStateSlot(committedRing: Float64RingBuffer, tentativeRing: Float64RingBuffer): ArrayStateSlot;
|
|
78
|
+
//# sourceMappingURL=arrayStateSlot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrayStateSlot.d.ts","sourceRoot":"","sources":["../../src/state/arrayStateSlot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,cAAc;aAKK,QAAQ,EAAE,MAAM;IAJ5C,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBAEd,QAAQ,EAAE,MAAM;IAM5C,qEAAqE;IACrE,UAAU,IAAI,IAAI;IAIlB,gFAAgF;IAChF,SAAS,IAAI,IAAI;CAGpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAqB/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAErE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACjC,aAAa,EAAE,iBAAiB,EAChC,aAAa,EAAE,iBAAiB,GACjC,cAAc,CAKhB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
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 { Float64RingBuffer } from "../ringBuffer.js";
|
|
4
|
+
/**
|
|
5
|
+
* Runtime slot behind a script-facing `state.array(capacity)` handle. Unlike
|
|
6
|
+
* the scalar `StateSlot` (one committed/tentative *value*) or the `SeriesSlot`
|
|
7
|
+
* (one ring advanced once per bar), this is a **bounded FIFO collection** with
|
|
8
|
+
* two `Float64RingBuffer`s: `tentativeRing` holds the live, author-facing
|
|
9
|
+
* pushes; `committedRing` is the bar-close snapshot a tick rolls back to.
|
|
10
|
+
*
|
|
11
|
+
* The committed/tentative discipline mirrors `StateSlot`: pushes during a tick
|
|
12
|
+
* mutate the tentative ring; a head-bar-replacing tick resets it from committed
|
|
13
|
+
* (in-progress pushes discarded); a bar close commits tentative into committed.
|
|
14
|
+
* The two-ring copy is `O(capacity)` per tick via a typed-array
|
|
15
|
+
* {@link Float64RingBuffer.copyFrom} memcpy — bounded because `capacity` is a
|
|
16
|
+
* required compile-time literal (see `tasks/future/state-array/README.md`
|
|
17
|
+
* Architecture Decisions: "Tick rollback = a two-ring buffer copy").
|
|
18
|
+
*
|
|
19
|
+
* @since 1.3
|
|
20
|
+
* @stable
|
|
21
|
+
* @example
|
|
22
|
+
* const slot = new ArrayStateSlot(4);
|
|
23
|
+
* slot.handle.push(1);
|
|
24
|
+
* slot.onBarClose();
|
|
25
|
+
* slot.handle.get(0); // 1
|
|
26
|
+
*/
|
|
27
|
+
export class ArrayStateSlot {
|
|
28
|
+
capacity;
|
|
29
|
+
committedRing;
|
|
30
|
+
tentativeRing;
|
|
31
|
+
handle;
|
|
32
|
+
constructor(capacity) {
|
|
33
|
+
this.capacity = capacity;
|
|
34
|
+
this.committedRing = new Float64RingBuffer(capacity);
|
|
35
|
+
this.tentativeRing = new Float64RingBuffer(capacity);
|
|
36
|
+
this.handle = buildArrayHandle(this);
|
|
37
|
+
}
|
|
38
|
+
/** Commit the tentative ring into the committed ring (bar close). */
|
|
39
|
+
onBarClose() {
|
|
40
|
+
this.committedRing.copyFrom(this.tentativeRing);
|
|
41
|
+
}
|
|
42
|
+
/** Roll the tentative ring back to the committed ring (head-replacing tick). */
|
|
43
|
+
onBarTick() {
|
|
44
|
+
this.tentativeRing.copyFrom(this.committedRing);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build the identity-stable {@link MutableArraySlot} handle over an
|
|
49
|
+
* {@link ArrayStateSlot}. All author-facing reads and writes route through the
|
|
50
|
+
* **tentative** ring (mirroring `StateSlot.set`/`StateSlot.get`, which read and
|
|
51
|
+
* write `tentative` for non-tick slots); the committed ring is the rollback
|
|
52
|
+
* source. `get(out-of-range)` returns `NaN` (the ring's `at` contract), never
|
|
53
|
+
* throws. A plain object with getters — no `Proxy` — because the handle has a
|
|
54
|
+
* fixed method set and is deliberately not number-coercible.
|
|
55
|
+
*
|
|
56
|
+
* @since 1.3
|
|
57
|
+
* @stable
|
|
58
|
+
* @example
|
|
59
|
+
* // const handle = buildArrayHandle(new ArrayStateSlot(4));
|
|
60
|
+
* // handle.push(1);
|
|
61
|
+
* // handle.last(); // 1
|
|
62
|
+
*/
|
|
63
|
+
export function buildArrayHandle(slot) {
|
|
64
|
+
return {
|
|
65
|
+
push(value) {
|
|
66
|
+
slot.tentativeRing.append(value);
|
|
67
|
+
},
|
|
68
|
+
get(n) {
|
|
69
|
+
return slot.tentativeRing.at(n);
|
|
70
|
+
},
|
|
71
|
+
last() {
|
|
72
|
+
return slot.tentativeRing.at(0);
|
|
73
|
+
},
|
|
74
|
+
clear() {
|
|
75
|
+
slot.tentativeRing.reset();
|
|
76
|
+
},
|
|
77
|
+
get size() {
|
|
78
|
+
return slot.tentativeRing.length;
|
|
79
|
+
},
|
|
80
|
+
get capacity() {
|
|
81
|
+
return slot.capacity;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Allocate a fresh {@link ArrayStateSlot} — both rings empty (`size === 0`).
|
|
87
|
+
* Unlike `state.float(init)` there is no seed value: an empty collection starts
|
|
88
|
+
* empty.
|
|
89
|
+
*
|
|
90
|
+
* @since 1.3
|
|
91
|
+
* @stable
|
|
92
|
+
* @example
|
|
93
|
+
* // const slot = createArrayStateSlot(20);
|
|
94
|
+
* // slot.handle.size; // 0
|
|
95
|
+
*/
|
|
96
|
+
export function createArrayStateSlot(capacity) {
|
|
97
|
+
return new ArrayStateSlot(capacity);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Rebuild an {@link ArrayStateSlot} from already-restored rings (snapshot
|
|
101
|
+
* path). The handle identity is recreated — acceptable, same as
|
|
102
|
+
* `state.series` / `ta.*` restore.
|
|
103
|
+
*
|
|
104
|
+
* @since 1.3
|
|
105
|
+
* @stable
|
|
106
|
+
* @example
|
|
107
|
+
* // const slot = restoreArrayStateSlot(committedRing, tentativeRing);
|
|
108
|
+
* // slot.handle.size;
|
|
109
|
+
*/
|
|
110
|
+
export function restoreArrayStateSlot(committedRing, tentativeRing) {
|
|
111
|
+
const slot = new ArrayStateSlot(committedRing.capacity);
|
|
112
|
+
slot.committedRing.copyFrom(committedRing);
|
|
113
|
+
slot.tentativeRing.copyFrom(tentativeRing);
|
|
114
|
+
return slot;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=arrayStateSlot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrayStateSlot.js","sourceRoot":"","sources":["../../src/state/arrayStateSlot.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,cAAc;IAKK;IAJnB,aAAa,CAAoB;IACjC,aAAa,CAAoB;IACjC,MAAM,CAA2B;IAE1C,YAA4B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;QACxC,IAAI,CAAC,aAAa,GAAG,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,GAAG,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,qEAAqE;IACrE,UAAU;QACN,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;IAED,gFAAgF;IAChF,SAAS;QACL,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;CACJ;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAoB;IACjD,OAAO;QACH,IAAI,CAAC,KAAa;YACd,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,GAAG,CAAC,CAAS;YACT,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,IAAI;YACA,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK;YACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI;YACJ,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QACrC,CAAC;QACD,IAAI,QAAQ;YACR,OAAO,IAAI,CAAC,QAAQ,CAAC;QACzB,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACjD,OAAO,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACjC,aAAgC,EAChC,aAAgC;IAEhC,MAAM,IAAI,GAAG,IAAI,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC3C,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC;AAChB,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 { MutableArraySlot } from \"@invinite-org/chartlang-core\";\n\nimport { Float64RingBuffer } from \"../ringBuffer.js\";\n\n/**\n * Runtime slot behind a script-facing `state.array(capacity)` handle. Unlike\n * the scalar `StateSlot` (one committed/tentative *value*) or the `SeriesSlot`\n * (one ring advanced once per bar), this is a **bounded FIFO collection** with\n * two `Float64RingBuffer`s: `tentativeRing` holds the live, author-facing\n * pushes; `committedRing` is the bar-close snapshot a tick rolls back to.\n *\n * The committed/tentative discipline mirrors `StateSlot`: pushes during a tick\n * mutate the tentative ring; a head-bar-replacing tick resets it from committed\n * (in-progress pushes discarded); a bar close commits tentative into committed.\n * The two-ring copy is `O(capacity)` per tick via a typed-array\n * {@link Float64RingBuffer.copyFrom} memcpy — bounded because `capacity` is a\n * required compile-time literal (see `tasks/future/state-array/README.md`\n * Architecture Decisions: \"Tick rollback = a two-ring buffer copy\").\n *\n * @since 1.3\n * @stable\n * @example\n * const slot = new ArrayStateSlot(4);\n * slot.handle.push(1);\n * slot.onBarClose();\n * slot.handle.get(0); // 1\n */\nexport class ArrayStateSlot {\n readonly committedRing: Float64RingBuffer;\n readonly tentativeRing: Float64RingBuffer;\n readonly handle: MutableArraySlot<number>;\n\n constructor(public readonly capacity: number) {\n this.committedRing = new Float64RingBuffer(capacity);\n this.tentativeRing = new Float64RingBuffer(capacity);\n this.handle = buildArrayHandle(this);\n }\n\n /** Commit the tentative ring into the committed ring (bar close). */\n onBarClose(): void {\n this.committedRing.copyFrom(this.tentativeRing);\n }\n\n /** Roll the tentative ring back to the committed ring (head-replacing tick). */\n onBarTick(): void {\n this.tentativeRing.copyFrom(this.committedRing);\n }\n}\n\n/**\n * Build the identity-stable {@link MutableArraySlot} handle over an\n * {@link ArrayStateSlot}. All author-facing reads and writes route through the\n * **tentative** ring (mirroring `StateSlot.set`/`StateSlot.get`, which read and\n * write `tentative` for non-tick slots); the committed ring is the rollback\n * source. `get(out-of-range)` returns `NaN` (the ring's `at` contract), never\n * throws. A plain object with getters — no `Proxy` — because the handle has a\n * fixed method set and is deliberately not number-coercible.\n *\n * @since 1.3\n * @stable\n * @example\n * // const handle = buildArrayHandle(new ArrayStateSlot(4));\n * // handle.push(1);\n * // handle.last(); // 1\n */\nexport function buildArrayHandle(slot: ArrayStateSlot): MutableArraySlot<number> {\n return {\n push(value: number): void {\n slot.tentativeRing.append(value);\n },\n get(n: number): number {\n return slot.tentativeRing.at(n);\n },\n last(): number {\n return slot.tentativeRing.at(0);\n },\n clear(): void {\n slot.tentativeRing.reset();\n },\n get size(): number {\n return slot.tentativeRing.length;\n },\n get capacity(): number {\n return slot.capacity;\n },\n };\n}\n\n/**\n * Allocate a fresh {@link ArrayStateSlot} — both rings empty (`size === 0`).\n * Unlike `state.float(init)` there is no seed value: an empty collection starts\n * empty.\n *\n * @since 1.3\n * @stable\n * @example\n * // const slot = createArrayStateSlot(20);\n * // slot.handle.size; // 0\n */\nexport function createArrayStateSlot(capacity: number): ArrayStateSlot {\n return new ArrayStateSlot(capacity);\n}\n\n/**\n * Rebuild an {@link ArrayStateSlot} from already-restored rings (snapshot\n * path). The handle identity is recreated — acceptable, same as\n * `state.series` / `ta.*` restore.\n *\n * @since 1.3\n * @stable\n * @example\n * // const slot = restoreArrayStateSlot(committedRing, tentativeRing);\n * // slot.handle.size;\n */\nexport function restoreArrayStateSlot(\n committedRing: Float64RingBuffer,\n tentativeRing: Float64RingBuffer,\n): ArrayStateSlot {\n const slot = new ArrayStateSlot(committedRing.capacity);\n slot.committedRing.copyFrom(committedRing);\n slot.tentativeRing.copyFrom(tentativeRing);\n return slot;\n}\n"]}
|
package/dist/state/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { isArraySlotSnapshotKey, restoreArraySlots, serialiseArraySlots, } from "./arrayPersistence.js";
|
|
2
|
+
export { ArrayStateSlot } from "./arrayStateSlot.js";
|
|
3
|
+
export { advanceSeriesSlots, commitArraySlots, commitSeriesSlots, commitStateSlots, flushStateSlots, resetSeriesHeads, resetTentativeArraySlots, restoreStateSlots, resetTentativeStateSlots, serialiseStateSlots, } from "./lifecycle.js";
|
|
2
4
|
export type { StateSlotSnapshot } from "./lifecycle.js";
|
|
5
|
+
export { isSeriesSlotSnapshotKey, restoreSeriesSlots, serialiseSeriesSlots, } from "./seriesPersistence.js";
|
|
3
6
|
export { buildStateNamespace } from "./stateNamespace.js";
|
|
4
7
|
export type { StateSlotSerialisers } from "./stateSlot.js";
|
|
5
8
|
export { asMutableSlot, StateSlot } from "./stateSlot.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACH,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACH,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/state/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
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
|
-
export {
|
|
3
|
+
export { isArraySlotSnapshotKey, restoreArraySlots, serialiseArraySlots, } from "./arrayPersistence.js";
|
|
4
|
+
export { ArrayStateSlot } from "./arrayStateSlot.js";
|
|
5
|
+
export { advanceSeriesSlots, commitArraySlots, commitSeriesSlots, commitStateSlots, flushStateSlots, resetSeriesHeads, resetTentativeArraySlots, restoreStateSlots, resetTentativeStateSlots, serialiseStateSlots, } from "./lifecycle.js";
|
|
6
|
+
export { isSeriesSlotSnapshotKey, restoreSeriesSlots, serialiseSeriesSlots, } from "./seriesPersistence.js";
|
|
4
7
|
export { buildStateNamespace } from "./stateNamespace.js";
|
|
5
8
|
export { asMutableSlot, StateSlot } from "./stateSlot.js";
|
|
6
9
|
//# sourceMappingURL=index.js.map
|
package/dist/state/index.js.map
CHANGED
|
@@ -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,EACH,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,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 commitStateSlots,\n flushStateSlots,\n restoreStateSlots,\n resetTentativeStateSlots,\n serialiseStateSlots,\n} from \"./lifecycle.js\";\nexport type { StateSlotSnapshot } from \"./lifecycle.js\";\nexport { buildStateNamespace } from \"./stateNamespace.js\";\nexport type { StateSlotSerialisers } from \"./stateSlot.js\";\nexport { asMutableSlot, StateSlot } from \"./stateSlot.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,EACH,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACH,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACH,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,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 isArraySlotSnapshotKey,\n restoreArraySlots,\n serialiseArraySlots,\n} from \"./arrayPersistence.js\";\nexport { ArrayStateSlot } from \"./arrayStateSlot.js\";\nexport {\n advanceSeriesSlots,\n commitArraySlots,\n commitSeriesSlots,\n commitStateSlots,\n flushStateSlots,\n resetSeriesHeads,\n resetTentativeArraySlots,\n restoreStateSlots,\n resetTentativeStateSlots,\n serialiseStateSlots,\n} from \"./lifecycle.js\";\nexport type { StateSlotSnapshot } from \"./lifecycle.js\";\nexport {\n isSeriesSlotSnapshotKey,\n restoreSeriesSlots,\n serialiseSeriesSlots,\n} from \"./seriesPersistence.js\";\nexport { buildStateNamespace } from \"./stateNamespace.js\";\nexport type { StateSlotSerialisers } from \"./stateSlot.js\";\nexport { asMutableSlot, StateSlot } from \"./stateSlot.js\";\n"]}
|
|
@@ -72,4 +72,72 @@ export declare function serialiseStateSlots(ctx: RuntimeContext): Readonly<Recor
|
|
|
72
72
|
* void restored;
|
|
73
73
|
*/
|
|
74
74
|
export declare function restoreStateSlots(ctx: RuntimeContext, slots: Readonly<Record<string, unknown>>): void;
|
|
75
|
+
/**
|
|
76
|
+
* Advance every `state.series` ring once for a new close bar — append a
|
|
77
|
+
* fresh `NaN` head so the prior committed head slides to index 1. Runs
|
|
78
|
+
* BEFORE compute on close, so a slot first allocated mid-compute (already
|
|
79
|
+
* holding its seeded head) is not present here and is not double-advanced.
|
|
80
|
+
*
|
|
81
|
+
* @since 0.9
|
|
82
|
+
* @stable
|
|
83
|
+
* @example
|
|
84
|
+
* // advanceSeriesSlots(ctx);
|
|
85
|
+
* const advanced = true;
|
|
86
|
+
* void advanced;
|
|
87
|
+
*/
|
|
88
|
+
export declare function advanceSeriesSlots(ctx: RuntimeContext): void;
|
|
89
|
+
/**
|
|
90
|
+
* Commit every `state.series` live head as its bar-close value after
|
|
91
|
+
* close compute, so the next advance retains it and a tick can reset to
|
|
92
|
+
* it.
|
|
93
|
+
*
|
|
94
|
+
* @since 0.9
|
|
95
|
+
* @stable
|
|
96
|
+
* @example
|
|
97
|
+
* // commitSeriesSlots(ctx);
|
|
98
|
+
* const committed = true;
|
|
99
|
+
* void committed;
|
|
100
|
+
*/
|
|
101
|
+
export declare function commitSeriesSlots(ctx: RuntimeContext): void;
|
|
102
|
+
/**
|
|
103
|
+
* Reset every `state.series` live head to its last committed value before
|
|
104
|
+
* tick compute, so a re-write refines from the committed baseline and a
|
|
105
|
+
* tick without a write reads the committed head. Does NOT advance length.
|
|
106
|
+
*
|
|
107
|
+
* @since 0.9
|
|
108
|
+
* @stable
|
|
109
|
+
* @example
|
|
110
|
+
* // resetSeriesHeads(ctx);
|
|
111
|
+
* const reset = true;
|
|
112
|
+
* void reset;
|
|
113
|
+
*/
|
|
114
|
+
export declare function resetSeriesHeads(ctx: RuntimeContext): void;
|
|
115
|
+
/**
|
|
116
|
+
* Roll every `state.array` slot's tentative ring back to its committed ring
|
|
117
|
+
* before tick compute, so a head-replacing tick discards in-progress pushes
|
|
118
|
+
* (and a tick without a push reads the committed collection). Runs once per
|
|
119
|
+
* tick, before compute, next to {@link resetSeriesHeads}. There is no advance —
|
|
120
|
+
* the array changes only when the author pushes.
|
|
121
|
+
*
|
|
122
|
+
* @since 1.3
|
|
123
|
+
* @stable
|
|
124
|
+
* @example
|
|
125
|
+
* // resetTentativeArraySlots(ctx);
|
|
126
|
+
* const reset = true;
|
|
127
|
+
* void reset;
|
|
128
|
+
*/
|
|
129
|
+
export declare function resetTentativeArraySlots(ctx: RuntimeContext): void;
|
|
130
|
+
/**
|
|
131
|
+
* Commit every `state.array` slot's tentative ring into its committed ring
|
|
132
|
+
* after close compute, so the next tick can roll back to it. Runs once per
|
|
133
|
+
* close, after compute, next to {@link commitSeriesSlots}.
|
|
134
|
+
*
|
|
135
|
+
* @since 1.3
|
|
136
|
+
* @stable
|
|
137
|
+
* @example
|
|
138
|
+
* // commitArraySlots(ctx);
|
|
139
|
+
* const committed = true;
|
|
140
|
+
* void committed;
|
|
141
|
+
*/
|
|
142
|
+
export declare function commitArraySlots(ctx: RuntimeContext): void;
|
|
75
143
|
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/state/lifecycle.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/state/lifecycle.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IAC/B,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAIlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAOzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAS1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC7B,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,IAAI,CAKN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAIlE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAI1D"}
|
package/dist/state/lifecycle.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
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
|
+
import { advanceSeriesSlot, commitSeriesSlot, resetSeriesSlotHead } from "./seriesSlot.js";
|
|
3
4
|
/**
|
|
4
5
|
* Reset all non-`state.tick.*` tentative values before tick compute.
|
|
5
6
|
*
|
|
@@ -84,4 +85,92 @@ export function restoreStateSlots(ctx, slots) {
|
|
|
84
85
|
ctx.stateStore.set(key, value);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Advance every `state.series` ring once for a new close bar — append a
|
|
90
|
+
* fresh `NaN` head so the prior committed head slides to index 1. Runs
|
|
91
|
+
* BEFORE compute on close, so a slot first allocated mid-compute (already
|
|
92
|
+
* holding its seeded head) is not present here and is not double-advanced.
|
|
93
|
+
*
|
|
94
|
+
* @since 0.9
|
|
95
|
+
* @stable
|
|
96
|
+
* @example
|
|
97
|
+
* // advanceSeriesSlots(ctx);
|
|
98
|
+
* const advanced = true;
|
|
99
|
+
* void advanced;
|
|
100
|
+
*/
|
|
101
|
+
export function advanceSeriesSlots(ctx) {
|
|
102
|
+
for (const slot of ctx.seriesSlots.values()) {
|
|
103
|
+
advanceSeriesSlot(slot);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Commit every `state.series` live head as its bar-close value after
|
|
108
|
+
* close compute, so the next advance retains it and a tick can reset to
|
|
109
|
+
* it.
|
|
110
|
+
*
|
|
111
|
+
* @since 0.9
|
|
112
|
+
* @stable
|
|
113
|
+
* @example
|
|
114
|
+
* // commitSeriesSlots(ctx);
|
|
115
|
+
* const committed = true;
|
|
116
|
+
* void committed;
|
|
117
|
+
*/
|
|
118
|
+
export function commitSeriesSlots(ctx) {
|
|
119
|
+
for (const slot of ctx.seriesSlots.values()) {
|
|
120
|
+
commitSeriesSlot(slot);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Reset every `state.series` live head to its last committed value before
|
|
125
|
+
* tick compute, so a re-write refines from the committed baseline and a
|
|
126
|
+
* tick without a write reads the committed head. Does NOT advance length.
|
|
127
|
+
*
|
|
128
|
+
* @since 0.9
|
|
129
|
+
* @stable
|
|
130
|
+
* @example
|
|
131
|
+
* // resetSeriesHeads(ctx);
|
|
132
|
+
* const reset = true;
|
|
133
|
+
* void reset;
|
|
134
|
+
*/
|
|
135
|
+
export function resetSeriesHeads(ctx) {
|
|
136
|
+
for (const slot of ctx.seriesSlots.values()) {
|
|
137
|
+
resetSeriesSlotHead(slot);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Roll every `state.array` slot's tentative ring back to its committed ring
|
|
142
|
+
* before tick compute, so a head-replacing tick discards in-progress pushes
|
|
143
|
+
* (and a tick without a push reads the committed collection). Runs once per
|
|
144
|
+
* tick, before compute, next to {@link resetSeriesHeads}. There is no advance —
|
|
145
|
+
* the array changes only when the author pushes.
|
|
146
|
+
*
|
|
147
|
+
* @since 1.3
|
|
148
|
+
* @stable
|
|
149
|
+
* @example
|
|
150
|
+
* // resetTentativeArraySlots(ctx);
|
|
151
|
+
* const reset = true;
|
|
152
|
+
* void reset;
|
|
153
|
+
*/
|
|
154
|
+
export function resetTentativeArraySlots(ctx) {
|
|
155
|
+
for (const slot of ctx.arraySlots.values()) {
|
|
156
|
+
slot.onBarTick();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Commit every `state.array` slot's tentative ring into its committed ring
|
|
161
|
+
* after close compute, so the next tick can roll back to it. Runs once per
|
|
162
|
+
* close, after compute, next to {@link commitSeriesSlots}.
|
|
163
|
+
*
|
|
164
|
+
* @since 1.3
|
|
165
|
+
* @stable
|
|
166
|
+
* @example
|
|
167
|
+
* // commitArraySlots(ctx);
|
|
168
|
+
* const committed = true;
|
|
169
|
+
* void committed;
|
|
170
|
+
*/
|
|
171
|
+
export function commitArraySlots(ctx) {
|
|
172
|
+
for (const slot of ctx.arraySlots.values()) {
|
|
173
|
+
slot.onBarClose();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
87
176
|
//# sourceMappingURL=lifecycle.js.map
|