@invinite-org/chartlang-adapter-kit 1.1.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 +1380 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/base/bufferingAdapter.d.ts +52 -0
- package/dist/base/bufferingAdapter.d.ts.map +1 -0
- package/dist/base/bufferingAdapter.js +68 -0
- package/dist/base/bufferingAdapter.js.map +1 -0
- package/dist/base/index.d.ts +3 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +5 -0
- package/dist/base/index.js.map +1 -0
- package/dist/base/passThroughAdapter.d.ts +49 -0
- package/dist/base/passThroughAdapter.d.ts.map +1 -0
- package/dist/base/passThroughAdapter.js +61 -0
- package/dist/base/passThroughAdapter.js.map +1 -0
- package/dist/capabilities/capabilities.d.ts +336 -0
- package/dist/capabilities/capabilities.d.ts.map +1 -0
- package/dist/capabilities/capabilities.js +616 -0
- package/dist/capabilities/capabilities.js.map +1 -0
- package/dist/capabilities/index.d.ts +2 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +4 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/defineAdapter.d.ts +74 -0
- package/dist/defineAdapter.d.ts.map +1 -0
- package/dist/defineAdapter.js +55 -0
- package/dist/defineAdapter.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mocks/index.d.ts +3 -0
- package/dist/mocks/index.d.ts.map +1 -0
- package/dist/mocks/index.js +4 -0
- package/dist/mocks/index.js.map +1 -0
- package/dist/mocks/mockCandleSource.d.ts +68 -0
- package/dist/mocks/mockCandleSource.d.ts.map +1 -0
- package/dist/mocks/mockCandleSource.js +61 -0
- package/dist/mocks/mockCandleSource.js.map +1 -0
- package/dist/types.d.ts +655 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/validation/decodeDrawing.d.ts +29 -0
- package/dist/validation/decodeDrawing.d.ts.map +1 -0
- package/dist/validation/decodeDrawing.js +35 -0
- package/dist/validation/decodeDrawing.js.map +1 -0
- package/dist/validation/index.d.ts +4 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +5 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/validateEmission.d.ts +70 -0
- package/dist/validation/validateEmission.d.ts.map +1 -0
- package/dist/validation/validateEmission.js +1481 -0
- package/dist/validation/validateEmission.js.map +1 -0
- package/package.json +41 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1380 @@
|
|
|
1
|
+
# @invinite-org/chartlang-adapter-kit
|
|
2
|
+
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4d44a9c: Add a `"history-then-stream"` mode to `mockCandleSource` plus a `streamTail` option (default `1`, clamped to `[0, bars.length]`). The new mode emits a single warm-up history batch containing every bar except the trailing `streamTail` bars, then yields one `close` event per remaining bar. Lets a consumer paint a chart instantly from history and still receive a few per-bar ticks afterwards — the missing combination for the React demo pane, the conformance scenarios, and any "live editor" UI. The existing `"history"` and `"stream"` modes are unchanged.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- d1de692: Fix end-user-blocking Node-ESM packaging bug. Every published `dist/index.js` previously failed to load under Node's strict ESM resolver because `tsc` had been configured with `moduleResolution: "Bundler"` and emitted relative specifiers verbatim, so `dist/index.js` carried `from "./api"` (extensionless) and Node rejected the resolution. Workspace consumers never saw this because tsx / vitest / Vite resolve loosely, but `npm install @invinite-org/chartlang-compiler` followed by `import` failed immediately for any Node consumer, and `examples/react-demo/vite.config.ts`'s server-side compile plugin broke at dev-config-load time.
|
|
12
|
+
|
|
13
|
+
This release switches `tsconfig.base.json` to `module: "NodeNext"` / `moduleResolution: "NodeNext"`, and rewrites every relative import / export / dynamic-import / `typeof import("…")` specifier across all packages' source to carry an explicit `.js` (or `/index.js`) suffix. The new resolution mode also surfaces this bug class as a compile error rather than runtime breakage, so it cannot regress.
|
|
14
|
+
|
|
15
|
+
No behavioural change for runtime consumers — the rewritten specifiers resolve to the same TypeScript sources at build time and the same `dist/<path>.js` files at consumer-load time.
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [d1de692]
|
|
18
|
+
- Updated dependencies [98599b2]
|
|
19
|
+
- @invinite-org/chartlang-core@1.0.1
|
|
20
|
+
|
|
21
|
+
## 1.0.0
|
|
22
|
+
|
|
23
|
+
### Major Changes
|
|
24
|
+
|
|
25
|
+
- chartlang `1.0.0` -- the `apiVersion: 1` standard.
|
|
26
|
+
|
|
27
|
+
- `apiVersion: 1` frozen: compiler accepts only the frozen language
|
|
28
|
+
version; `STATEFUL_PRIMITIVES` locked at 172 entries by exact
|
|
29
|
+
name-set; every shipping export `@stable`; pre-1.0 deprecations
|
|
30
|
+
removed (`PHASE_1_SCENARIOS`).
|
|
31
|
+
- Canonical language spec published (`docs/spec/`): grammar,
|
|
32
|
+
semantics, manifest, emissions, versioning -- self-contained for
|
|
33
|
+
alternate implementations. The `v1.0.0` tag is the frozen spec
|
|
34
|
+
snapshot.
|
|
35
|
+
- Public conformance reports: `pnpm conformance --report` emits
|
|
36
|
+
`CONFORMANCE.md` + `conformance-report.json`; canvas2d reference
|
|
37
|
+
report published and drift-gated.
|
|
38
|
+
- Adapter-author path proven end-to-end: scaffolded adapters ship a
|
|
39
|
+
wired conformance test; full writing-an-adapter tutorial +
|
|
40
|
+
Lightweight Charts porting walkthrough.
|
|
41
|
+
- Pine migration guide finalised with a pattern-coverage matrix
|
|
42
|
+
audited against the top ~50 Pine scripts.
|
|
43
|
+
|
|
44
|
+
### Minor Changes
|
|
45
|
+
|
|
46
|
+
- d14a034: Add phase 5 server alerts, multi-timeframe request handling, runtime persistence, QuickJS hosting, expanded plot and table rendering, color helpers, alert conditions, and volume profile primitives.
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Freeze `apiVersion: 1`: release-grade compiler diagnostics for version
|
|
51
|
+
mismatches, an exact name-set lock on the 172-entry `STATEFUL_PRIMITIVES`
|
|
52
|
+
registry, and freeze-contract documentation on pinned surfaces. No behavioural
|
|
53
|
+
change: the structural check already enforced `apiVersion: 1`.
|
|
54
|
+
- Pre-1.0 surface cleanup: remove the deprecated `PHASE_1_SCENARIOS`
|
|
55
|
+
alias (use `ALL_SCENARIOS`) and promote every shipping export from
|
|
56
|
+
`@experimental` to `@stable` ahead of the `apiVersion: 1` freeze.
|
|
57
|
+
- Updated dependencies [d14a034]
|
|
58
|
+
- Updated dependencies [3cfff10]
|
|
59
|
+
- Updated dependencies [3cfff10]
|
|
60
|
+
- Updated dependencies [3cfff10]
|
|
61
|
+
- Updated dependencies [3cfff10]
|
|
62
|
+
- Updated dependencies
|
|
63
|
+
- Updated dependencies
|
|
64
|
+
- Updated dependencies
|
|
65
|
+
- @invinite-org/chartlang-core@1.0.0
|
|
66
|
+
|
|
67
|
+
## 0.5.0
|
|
68
|
+
|
|
69
|
+
### Phase 5
|
|
70
|
+
|
|
71
|
+
#### Minor Changes
|
|
72
|
+
|
|
73
|
+
- Ship Phase 5 `defineAlertCondition`, compiler manifest extraction, runtime `signal()` emissions, adapter validation, and conformance coverage per PLAN §11.2.
|
|
74
|
+
- Add `draw.table` with `TableCell`/`TablePosition` types, runtime emission,
|
|
75
|
+
viewport-anchored canvas2d rendering, and conformance coverage per PLAN §10.2.
|
|
76
|
+
- Add Phase 5 plot kinds, runtime emission dispatch, validation, conformance scenarios, and canvas2d reference renderers.
|
|
77
|
+
- Add the Phase 5 `runtime.log.*` and `runtime.error()` surface, log emissions, runtime halt diagnostics, and conformance coverage.
|
|
78
|
+
- Add the PLAN.md §6.9 persistent runtime snapshot store, warm-start restore flow, close/dispose snapshot saves, and snapshot diagnostics.
|
|
79
|
+
- Replace the Phase 4 `request.security` NaN-only path with real
|
|
80
|
+
multi-timeframe secondary stream alignment per PLAN.md §6.8 and §7.2.
|
|
81
|
+
Adapters can route tagged `CandleEvent.streamKey` candles, the worker
|
|
82
|
+
host dispatches them through `ScriptRunner.push`, conformance includes
|
|
83
|
+
MTF scenarios, and the private canvas2d reference adapter now declares
|
|
84
|
+
`multiTimeframe: true`.
|
|
85
|
+
- Add `ta.fixedRangeVolumeProfile`, completing the Phase 5 volume-profile set
|
|
86
|
+
from PLAN §9.2 and §10.1.1 with fixed `[from, to]` anchors, frozen post-range
|
|
87
|
+
histograms, and `fixed-range-inverted` diagnostics. Ported from invinite
|
|
88
|
+
commit `3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4`.
|
|
89
|
+
- Port `ta.sessionVolumeProfile` from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4, adding the PLAN §9.2 horizontal-histogram session volume-profile primitive, PLAN §4.8 syminfo-session fallback diagnostics, and compiler/runtime registration.
|
|
90
|
+
|
|
91
|
+
#### Patch Changes
|
|
92
|
+
|
|
93
|
+
- Updated dependencies
|
|
94
|
+
- Updated dependencies
|
|
95
|
+
- Updated dependencies
|
|
96
|
+
- Updated dependencies
|
|
97
|
+
- Updated dependencies
|
|
98
|
+
- Updated dependencies
|
|
99
|
+
- Updated dependencies
|
|
100
|
+
- Updated dependencies
|
|
101
|
+
- Updated dependencies
|
|
102
|
+
- Updated dependencies
|
|
103
|
+
- Updated dependencies
|
|
104
|
+
- @invinite-org/chartlang-core@0.5.0
|
|
105
|
+
|
|
106
|
+
## 0.4.0
|
|
107
|
+
|
|
108
|
+
### Minor Changes
|
|
109
|
+
|
|
110
|
+
- 3f3ce38: Replace the Phase-0 placeholder with the Phase-1 adapter contract:
|
|
111
|
+
`Adapter` / `Capabilities` / `CandleEvent` types and the §7.3 emission
|
|
112
|
+
shapes, capability builders (`capabilities.line()` / `.allLines()` /
|
|
113
|
+
`.alerts(...)` / `.union(...)`), `defineAdapter` factory, hand-rolled
|
|
114
|
+
`validateEmission` (no `zod` / `valibot` dependency) covering every
|
|
115
|
+
Phase-1 emission and meta walker, `decodeDrawing` Phase-1 stub,
|
|
116
|
+
`mockCandleSource` for test playback, and `PassThroughAdapter` /
|
|
117
|
+
`BufferingAdapter` base classes for runtime + conformance fixtures.
|
|
118
|
+
- 38fb475: Phase 2 — `0.2` full indicator parity.
|
|
119
|
+
|
|
120
|
+
- 81 new `ta.*` primitives (6 cross-functional + 75 §9.2 ports);
|
|
121
|
+
`TA_REGISTRY` cardinality 9 -> 90; `STATEFUL_PRIMITIVES`
|
|
122
|
+
cardinality 12 -> 93.
|
|
123
|
+
- 5 new chained-MA helpers + 5 new stats/volatility helpers in
|
|
124
|
+
`packages/runtime/src/ta/lib/`.
|
|
125
|
+
- 6 new `PlotKind`s (histogram, bars, area, filled-band, label,
|
|
126
|
+
marker) + canvas2d renderers + `validateEmission` arms.
|
|
127
|
+
- `Bar` extended with `hl2` / `hlc3` / `ohlc4` / `hlcc4` derived
|
|
128
|
+
source fields — runtime already pre-computes on `BarView`.
|
|
129
|
+
- `Scenario` extended with `inlineSource?: string` so Phase-2
|
|
130
|
+
scenarios stay self-contained without bloating
|
|
131
|
+
`examples/scripts/`.
|
|
132
|
+
- `STATEFUL_PRIMITIVES` shape widened from `ReadonlySet<string>`
|
|
133
|
+
to `ReadonlySet<{ name: string; slot: boolean }>` to support
|
|
134
|
+
`ta.nz` (the only stateless `ta.*`).
|
|
135
|
+
- Universal `opts.offset` honoured on every `ta.*` primitive
|
|
136
|
+
(Phase-1 backfill in Task 29).
|
|
137
|
+
- `chartlang docs` subcommand generates
|
|
138
|
+
`docs/primitives/ta/<id>.md` per primitive.
|
|
139
|
+
- `PHASE_2_INDICATORS` + `PHASE_5_DEFERRED` inventories exported
|
|
140
|
+
from `@invinite-org/chartlang-conformance` and pinned by
|
|
141
|
+
`phase2Coverage.test.ts` (Task 30).
|
|
142
|
+
- 100% coverage maintained across every published package.
|
|
143
|
+
- `apiVersion: 1` script header unchanged; Phase 2 is additive
|
|
144
|
+
at runtime.
|
|
145
|
+
|
|
146
|
+
- 38fb475: Phase-2 Task 1 — three foundational widenings every subsequent
|
|
147
|
+
Phase-2 port depends on:
|
|
148
|
+
|
|
149
|
+
1. **`PlotKind` expansion (3 → 9).** Adds `histogram`, `bars`,
|
|
150
|
+
`area`, `filled-band`, `label`, `marker` per PLAN.md §7.3. The
|
|
151
|
+
`PlotStyle` discriminated union in
|
|
152
|
+
`@invinite-org/chartlang-adapter-kit` extends in lockstep; the
|
|
153
|
+
`validateEmission` switch grows matching arms with per-kind
|
|
154
|
+
payload rules; the `capabilities` builder gains `histogram()` /
|
|
155
|
+
`bars()` / `area()` / `filledBand()` / `label()` / `marker()` /
|
|
156
|
+
`allPhase2Plots()`. The canvas2d reference adapter ships six new
|
|
157
|
+
pure-on-`RenderCtx` renderers (`render/histogram.ts`, `bars.ts`,
|
|
158
|
+
`area.ts`, `filledBand.ts`, `label.ts`, `marker.ts`) and flips
|
|
159
|
+
`CANVAS2D_CAPABILITIES.plots` to `capabilities.allPhase2Plots()`
|
|
160
|
+
(9 kinds). `RenderCtx` + `MockCanvas2DContext` extend with
|
|
161
|
+
`fillText`, `globalAlpha`, `font`, `textAlign`, `textBaseline`.
|
|
162
|
+
|
|
163
|
+
2. **`Bar` derived sources.** Extends the script-facing `Bar`
|
|
164
|
+
(`packages/core/src/types.ts`) with the four pre-computed derived
|
|
165
|
+
sources `hl2` / `hlc3` / `ohlc4` / `hlcc4`. The runtime's
|
|
166
|
+
`BarView` (`packages/runtime/src/streamState.ts`) already
|
|
167
|
+
populates these on every close — Phase 2 surfaces them so authors
|
|
168
|
+
can write `ta.cci(bar.hlc3, 20)` like Pine. No runtime change.
|
|
169
|
+
|
|
170
|
+
3. **`Scenario.inlineSource`.** Extends the conformance `Scenario`
|
|
171
|
+
type (`packages/conformance/src/runConformanceSuite.ts`) with an
|
|
172
|
+
optional `inlineSource?: string` field that is mutually exclusive
|
|
173
|
+
with the existing `scriptPath?: string`. `runConformanceSuite`
|
|
174
|
+
writes the inline source to the existing `.cache/` tmp file and
|
|
175
|
+
compiles + imports it exactly like the `scriptPath` branch, with
|
|
176
|
+
a virtual `<inline:${id}>.chart.ts` `sourcePath` so callsite-id
|
|
177
|
+
injection produces stable, pinnable slot ids. Phase-2 ports use
|
|
178
|
+
this to carry their `defineIndicator` source inline rather than
|
|
179
|
+
spawning 80+ files in `examples/scripts/`.
|
|
180
|
+
|
|
181
|
+
The new `PLOT_KIND_COVERAGE_SCENARIO` exercises the `inlineSource`
|
|
182
|
+
path + the wider capability surface end-to-end (one inline
|
|
183
|
+
`plot(bar.close)` + `hline(50)` script; asserts no
|
|
184
|
+
`unsupported-plot-kind` and no `malformed-emission` diagnostics
|
|
185
|
+
fire). Per-port Phase-2 tasks (Tasks 21+) each add their own
|
|
186
|
+
scenario asserting the specific new kind's drained emissions once
|
|
187
|
+
the runtime acquires the matching emission path.
|
|
188
|
+
|
|
189
|
+
No runtime / host-worker source-level changes in this task —
|
|
190
|
+
`BarView` already carries the four derived fields, and the
|
|
191
|
+
`PlotKind` expansion is additive at every consumer.
|
|
192
|
+
|
|
193
|
+
- b0d296b: Phase 3 closeout — `0.3` "Full Drawing Parity".
|
|
194
|
+
|
|
195
|
+
61 drawing kinds across 13 categories ship under `draw.*` with the
|
|
196
|
+
full §22.10 set per kind (impl + property + golden + bench + JSDoc
|
|
197
|
+
|
|
198
|
+
- conformance scenario + auto-generated docs page). 5-bucket
|
|
199
|
+
`DrawingCounts` budget, per-kind capability gating, `DrawingHandle`
|
|
200
|
+
across-bar stability, real-impl `validateEmission` + `decodeDrawing`,
|
|
201
|
+
`drawing-hash` conformance assertion variant, 13 category + 1
|
|
202
|
+
umbrella capability builders, canvas2d reference adapter renders
|
|
203
|
+
every kind, `defineDrawing` constructor for interactive tools.
|
|
204
|
+
|
|
205
|
+
Final cardinalities: `STATEFUL_PRIMITIVES.size === 154` (93 Phase-2
|
|
206
|
+
|
|
207
|
+
- 61 Phase-3 `draw.*` entries); `DRAWING_KINDS.length === 61`.
|
|
208
|
+
|
|
209
|
+
Per-bucket kind tally pinned by `bucketFor` (6 + 5 + 6 + 25 + 19 = 61):
|
|
210
|
+
|
|
211
|
+
- `lines` (6): `line`, `horizontal-line`, `horizontal-ray`,
|
|
212
|
+
`vertical-line`, `cross-line`, `trend-angle`.
|
|
213
|
+
- `boxes` (5): `rectangle`, `rotated-rectangle`, `triangle`,
|
|
214
|
+
`circle`, `ellipse`.
|
|
215
|
+
- `labels` (6): `marker`, `text`, `arrow`, `arrow-marker`,
|
|
216
|
+
`arrow-mark-up`, `arrow-mark-down`.
|
|
217
|
+
- `polylines` (25): `polyline`, `path`, `arc`, `curve`,
|
|
218
|
+
`double-curve`, `pen`, `highlighter`, `brush`,
|
|
219
|
+
`trend-channel`, `flat-top-bottom`, `disjoint-channel`,
|
|
220
|
+
`regression-trend`, `pitchfork`, `pitchfan`, `xabcd-pattern`,
|
|
221
|
+
`cypher-pattern`, `head-and-shoulders`, `abcd-pattern`,
|
|
222
|
+
`triangle-pattern`, `three-drives-pattern`,
|
|
223
|
+
`elliott-impulse-wave`, `elliott-correction-wave`,
|
|
224
|
+
`elliott-triangle-wave`, `elliott-double-combo`,
|
|
225
|
+
`elliott-triple-combo`.
|
|
226
|
+
- `other` (19): 10 `fib-*` + 4 `gann-*` + 3 cycles
|
|
227
|
+
(`cyclic-lines`, `time-cycles`, `sine-line`) + 2 containers
|
|
228
|
+
(`group`, `frame`).
|
|
229
|
+
|
|
230
|
+
Conformance scenarios: 61 per-kind + 12 task bundles +
|
|
231
|
+
`drawAll61` + `drawBudgetOverflow` + `drawUnsupportedKind` = **76**.
|
|
232
|
+
Docs: 61 auto-generated `docs/primitives/draw/<kind>.md` pages +
|
|
233
|
+
1 hand-written `index.md`.
|
|
234
|
+
|
|
235
|
+
Variant collapses pinned in Task 1 (carried forward unchanged):
|
|
236
|
+
|
|
237
|
+
- `pitchfork.variant: "standard" | "schiff" | "modified-schiff" | "inside"`
|
|
238
|
+
collapses the 4 invinite pitchfork tools.
|
|
239
|
+
- `line.{extendLeft, extendRight}` collapses the `ray` /
|
|
240
|
+
`extended-line` tools.
|
|
241
|
+
- `cypherPattern` ships as a `defineDrawing`-only kind (no
|
|
242
|
+
standalone interactive tool).
|
|
243
|
+
|
|
244
|
+
Compiler: `callsiteIdInjection` recognises every `draw.*` callable
|
|
245
|
+
via the widened 154-entry `STATEFUL_PRIMITIVES`;
|
|
246
|
+
`statefulCallInLoop` flags `draw.*` in unbounded loops with the
|
|
247
|
+
existing `stateful-call-inside-loop` error.
|
|
248
|
+
|
|
249
|
+
Bench thresholds (re-verified post-Phase-3 on Apple-silicon):
|
|
250
|
+
|
|
251
|
+
- `pushDrawing.bench.test.ts` — 10 000 line drawings under 2 000ms
|
|
252
|
+
wall-clock (`ceil(median × 3)` per §22.10; no drift across
|
|
253
|
+
Tasks 4–18 — the budget/validate path is independent of
|
|
254
|
+
per-kind canvas renderers). `pnpm bench:ci` median ~180ms.
|
|
255
|
+
- The Phase-2 ta / ringBuffer / seriesView / onBarClose /
|
|
256
|
+
plot / hline bench thresholds were bumped from the
|
|
257
|
+
`200/250/300/400/500/600ms` solo-run pins to a uniform `1500ms`
|
|
258
|
+
(3000ms for plot + hline) to absorb the parallel-worker
|
|
259
|
+
scheduling overhead during workspace `pnpm test` (665 test
|
|
260
|
+
files in parallel). Solo `pnpm bench:ci` medians remain in the
|
|
261
|
+
10–200ms range — well under both old and new thresholds — so
|
|
262
|
+
this is a noise-floor adjustment, not a perf-regression
|
|
263
|
+
accommodation.
|
|
264
|
+
|
|
265
|
+
`apiVersion: 1` script header unchanged; Phase 3 is additive at
|
|
266
|
+
runtime.
|
|
267
|
+
|
|
268
|
+
- b0d296b: Phase 3 Task 10 — Channels (`trendChannel` / `flatTopBottom` /
|
|
269
|
+
`disjointChannel` / `regressionTrend`).
|
|
270
|
+
|
|
271
|
+
- **adapter-kit** — 4 new per-kind validators (`validateTrendChannelState`,
|
|
272
|
+
`validateFlatTopBottomState`, `validateDisjointChannelState`,
|
|
273
|
+
`validateRegressionTrendState`) + 1 file-local style helper
|
|
274
|
+
(`validateRegressionTrendOpts` with the
|
|
275
|
+
`close|open|high|low|hl2|hlc3|ohlc4|hlcc4` source whitelist). The
|
|
276
|
+
`regression-trend` validator enforces `anchors[0].time <
|
|
277
|
+
anchors[1].time` and `stdevMultiplier >= 0`.
|
|
278
|
+
- **runtime** — 4 new emit functions under
|
|
279
|
+
`packages/runtime/src/emit/draw/channels/` wired into `DRAW_NAMESPACE`.
|
|
280
|
+
`regressionTrend` carries the 4-arg form
|
|
281
|
+
`(slotId, a: WorldPoint, b: WorldPoint, opts?)`. The Phase-2
|
|
282
|
+
`linearRegression` + `LinearRegressionFrame` helper graduates to the
|
|
283
|
+
public runtime surface so consumer adapters can compute the OLS fit
|
|
284
|
+
without duplicating math.
|
|
285
|
+
- **canvas2d-adapter** — 4 new renderers + dispatch wiring. The
|
|
286
|
+
`regression-trend` renderer strokes a placeholder anchor-to-anchor
|
|
287
|
+
line; the actual OLS fit + σ bands require bar-buffer access not
|
|
288
|
+
exposed by the current `Viewport` (see
|
|
289
|
+
`tasks/phase-3-drawing-parity/10-channels.plan.md` §3). `trendChannel`
|
|
290
|
+
/ `flatTopBottom` / `disjointChannel` are stroke-only (no fill polygon
|
|
291
|
+
between rails — see plan §5).
|
|
292
|
+
- **conformance** — 5 new scenarios (4 per-kind + 1
|
|
293
|
+
`drawChannelsAll` bundle) with pinned `drawing-hash` assertions.
|
|
294
|
+
|
|
295
|
+
See `tasks/phase-3-drawing-parity/10-channels.plan.md` for the full
|
|
296
|
+
audit + divergence flags.
|
|
297
|
+
|
|
298
|
+
- b0d296b: Phase 3 Task 11 — Fibonacci A (`fibRetracement` / `fibTrendExtension`
|
|
299
|
+
/ `fibChannel` / `fibTimeZone` / `fibWedge`).
|
|
300
|
+
|
|
301
|
+
- **core** — `DrawNamespace` flattened: the four sub-namespace types
|
|
302
|
+
(`FibSubNamespace`, `GannSubNamespace`, `ElliottSubNamespace`,
|
|
303
|
+
`PatternSubNamespace`) are removed; every kind now lives as a flat
|
|
304
|
+
method directly on `DrawNamespace` matching the canonical
|
|
305
|
+
`STATEFUL_PRIMITIVES` names (`draw.fibRetracement(...)`,
|
|
306
|
+
`draw.gannBox(...)`, `draw.elliottImpulseWave(...)`,
|
|
307
|
+
`draw.xabcdPattern(...)`, etc.). The throwing-stub `draw` Proxy
|
|
308
|
+
drops the sub-namespace branch. Script authors use the flat
|
|
309
|
+
Pine/invinite-parity surface; the compiler resolves callsites
|
|
310
|
+
through its existing 2-segment property-access path. The 30
|
|
311
|
+
not-yet-ported method signatures (Tasks 12–18 fib-B / gann /
|
|
312
|
+
pitchfork / pattern / elliott / cycle / container kinds) are
|
|
313
|
+
declared as flat stubs so Tasks 12–18 only need to extend the
|
|
314
|
+
runtime `KIND_IMPLS` map. **BREAKING** for any consumer that
|
|
315
|
+
referenced `draw.fib.retracement(...)` or one of the four
|
|
316
|
+
sub-namespace types — none currently exist outside Phase-3 work.
|
|
317
|
+
- **adapter-kit** — 5 new per-kind validators
|
|
318
|
+
(`validateFibRetracementState`, `validateFibTrendExtensionState`,
|
|
319
|
+
`validateFibChannelState`, `validateFibTimeZoneState`,
|
|
320
|
+
`validateFibWedgeState`) + 1 file-local style helper
|
|
321
|
+
(`validateFibOpts`) covering FibOpts (`levels` finite-array,
|
|
322
|
+
`showLabels` / `color` / `extendLeft` / `extendRight`).
|
|
323
|
+
- **runtime** — 5 new emit functions under
|
|
324
|
+
`packages/runtime/src/emit/draw/fibA/` wired into `DRAW_NAMESPACE`
|
|
325
|
+
as flat methods. `fibRetracement` / `fibTimeZone` use the 4-arg
|
|
326
|
+
form `(slotId, a, b, opts?)`; the other 3 use the 3-arg
|
|
327
|
+
`(slotId, anchors, opts?)` form. No new sub-namespace wiring.
|
|
328
|
+
- **canvas2d-adapter** — 5 new renderers reusing Task-4's
|
|
329
|
+
`FIB_LEVELS` + `formatLevel` and Task-5's `extendLineSegment` for
|
|
330
|
+
the `fib-retracement` viewport extension. Default colour
|
|
331
|
+
`"#facc15"` (warm yellow) per invinite's fib-tool palette.
|
|
332
|
+
- **conformance** — 6 new scenarios (5 per-kind + 1
|
|
333
|
+
`drawFibA` bundle) with pinned `drawing-hash` assertions.
|
|
334
|
+
Conformance + scenarios test-capability fixtures grow `other`
|
|
335
|
+
bucket from 0 to 100 and add the 5 fib-A kebab kinds.
|
|
336
|
+
|
|
337
|
+
Divergences flagged in `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md`:
|
|
338
|
+
|
|
339
|
+
- `fib-time-zone` uses the canonical ratio array (`FIB_LEVELS`),
|
|
340
|
+
NOT the integer Fibonacci sequence; `fibSequence.ts` helper is
|
|
341
|
+
NOT created (Task-1 reshape follow-up).
|
|
342
|
+
- `fib-wedge` rays are drawn with a fixed length
|
|
343
|
+
`max(pxWidth, pxHeight) * 2` rather than via a directional
|
|
344
|
+
`extendLineSegment` variant.
|
|
345
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
346
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–10.
|
|
347
|
+
|
|
348
|
+
See `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md` for the
|
|
349
|
+
full audit + divergence list.
|
|
350
|
+
|
|
351
|
+
- b0d296b: Phase 3 Task 12 — Fibonacci B (`fibSpeedFan` / `fibSpeedArcs` /
|
|
352
|
+
`fibSpiral` / `fibCircles` / `fibTrendTime`).
|
|
353
|
+
|
|
354
|
+
- **adapter-kit** — 5 new per-kind validators
|
|
355
|
+
(`validateFibSpeedFanState`, `validateFibSpeedArcsState`,
|
|
356
|
+
`validateFibSpiralState`, `validateFibCirclesState`,
|
|
357
|
+
`validateFibTrendTimeState`), reusing Task-11's `validateFibOpts`
|
|
358
|
+
style helper. The permissive-default test fixture moves from
|
|
359
|
+
`fib-speed-fan` to `gann-box` (Task 13's first kind, still
|
|
360
|
+
unported).
|
|
361
|
+
- **runtime** — 5 new emit functions under
|
|
362
|
+
`packages/runtime/src/emit/draw/fibB/` wired into the
|
|
363
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Four use the
|
|
364
|
+
4-arg form `(slotId, a, b, opts?)`; `fibTrendTime` uses the 3-arg
|
|
365
|
+
`(slotId, anchors, opts?)`. Fall-through-stub fixture in
|
|
366
|
+
`namespace.test.ts` / `primitives.test.ts` /
|
|
367
|
+
`buildComputeContext.test.ts` moves from `fibSpeedFan` to
|
|
368
|
+
`gannBox`.
|
|
369
|
+
- **canvas2d-adapter** — 5 new renderers reusing Task-4's
|
|
370
|
+
`FIB_LEVELS` + `formatLevel`. `fibSpiral` additionally reuses
|
|
371
|
+
`sampleCubic` for the chained quarter-Bezier approximation of the
|
|
372
|
+
golden spiral. Default colour `"#facc15"` per invinite's fib-tool
|
|
373
|
+
palette.
|
|
374
|
+
- **conformance** — 5 new per-kind scenarios + 1 bundle
|
|
375
|
+
(`drawFibAll.scenario.ts` covering all 10 fib kinds, superseding
|
|
376
|
+
Task 11's `drawFibA.scenario.ts` which is deleted). Conformance +
|
|
377
|
+
scenarios test-capability fixtures switch from the explicit
|
|
378
|
+
fib-A kebab list to `capabilities.allFibDrawings()` (covers all
|
|
379
|
+
10 kinds). All 6 hashes pinned against the deterministic-run
|
|
380
|
+
actuals.
|
|
381
|
+
|
|
382
|
+
Divergences flagged in `tasks/phase-3-drawing-parity/12-fibonacci-b.plan.md`:
|
|
383
|
+
|
|
384
|
+
- `fibSpiral` is clockwise-only — invinite's `counterClockwise`
|
|
385
|
+
flag is deferred (Task-1 reshape follow-up; landed `FibSpiralState`
|
|
386
|
+
- `FibOpts` don't carry the field).
|
|
387
|
+
- `fibSpeedArcs` is full-circle only — invinite's half-disk variant
|
|
388
|
+
is deferred (Phase-3-deferred UX nuance).
|
|
389
|
+
- `fibCircles` + `fibTrendTime` use the ratio array (`FIB_LEVELS`),
|
|
390
|
+
NOT the integer Fibonacci sequence. Same precedent as Task-11's
|
|
391
|
+
`fib-time-zone`.
|
|
392
|
+
- `gen-docs` regeneration for the 5 new kinds deferred to Task 21
|
|
393
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
394
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
395
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
396
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–11.
|
|
397
|
+
|
|
398
|
+
See `tasks/phase-3-drawing-parity/12-fibonacci-b.plan.md` for the
|
|
399
|
+
full audit + divergence list.
|
|
400
|
+
|
|
401
|
+
- b0d296b: Phase 3 Task 13 — Gann (`gannBox` / `gannSquareFixed` / `gannSquare` /
|
|
402
|
+
`gannFan`).
|
|
403
|
+
|
|
404
|
+
- **adapter-kit** — 4 new per-kind validators
|
|
405
|
+
(`validateGannBoxState`, `validateGannSquareFixedState`,
|
|
406
|
+
`validateGannSquareState`, `validateGannFanState`), reusing
|
|
407
|
+
Task-5's `validateLineDrawStyle` style helper. The
|
|
408
|
+
permissive-default test fixture moves from `gann-box` to
|
|
409
|
+
`pitchfork` (Task 14's first kind, still unported).
|
|
410
|
+
- **runtime** — 4 new emit functions under
|
|
411
|
+
`packages/runtime/src/emit/draw/gann/` wired into the
|
|
412
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Three use the
|
|
413
|
+
4-arg form `(slotId, a, b, opts?)`; `gannSquareFixed` uses the
|
|
414
|
+
3-arg `(slotId, anchor, opts?)`. Fall-through-stub fixture in
|
|
415
|
+
`namespace.test.ts` / `primitives.test.ts` /
|
|
416
|
+
`buildComputeContext.test.ts` moves from `gannBox` to `pitchfork`.
|
|
417
|
+
- **canvas2d-adapter** — 4 new renderers + a shared `gannLevels.ts`
|
|
418
|
+
helper exporting `GANN_LEVELS` (`[0, 0.25, 0.5, 0.75, 1]`),
|
|
419
|
+
`GANN_FAN_RATIOS` (9-entry tuple covering 1×1, 1×2, …, 8×1),
|
|
420
|
+
`GANN_FAN_LABELS`, and `formatGannRatio`. Default colour
|
|
421
|
+
`"#a855f7"` (purple/violet, mirroring invinite's gann-tool
|
|
422
|
+
palette).
|
|
423
|
+
- **conformance** — 4 new per-kind scenarios + 1 bundle
|
|
424
|
+
(`drawGannAll.scenario.ts` covering all 4 gann kinds).
|
|
425
|
+
Conformance + scenarios test-capability fixtures widen
|
|
426
|
+
`drawings` with `capabilities.allGannDrawings()`. All 5 hashes
|
|
427
|
+
pinned against the deterministic-run actuals.
|
|
428
|
+
|
|
429
|
+
Divergences flagged in `tasks/phase-3-drawing-parity/13-gann.plan.md`:
|
|
430
|
+
|
|
431
|
+
- `gannBox.levels` custom override deferred — landed `GannBoxState`
|
|
432
|
+
carries only `style: LineDrawStyle`. Renderer uses the shared
|
|
433
|
+
`GANN_LEVELS` constant only (Task-1 reshape follow-up).
|
|
434
|
+
- `gannSquareFixed.sizePrice` custom override deferred — landed
|
|
435
|
+
`GannSquareFixedState` carries only `anchor + style`. Renderer
|
|
436
|
+
uses a fixed `80px` side (Task-1 reshape follow-up).
|
|
437
|
+
- `gannSquare.ratio` custom override deferred — landed
|
|
438
|
+
`GannSquareState` carries only `anchors + style`. Renderer uses
|
|
439
|
+
canvas-space `max(|dx|, |dy|)` (1×1 default, Task-1 reshape
|
|
440
|
+
follow-up).
|
|
441
|
+
- `gannFan.showLabels` flag deferred — `LineDrawStyle` has no
|
|
442
|
+
`showLabels` field. Phase-3 pins unlabeled rays (Task-1 reshape
|
|
443
|
+
follow-up).
|
|
444
|
+
- `gen-docs` regeneration for the 4 new kinds deferred to Task 21
|
|
445
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
446
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
447
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
448
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–12.
|
|
449
|
+
|
|
450
|
+
See `tasks/phase-3-drawing-parity/13-gann.plan.md` for the full
|
|
451
|
+
audit + divergence list.
|
|
452
|
+
|
|
453
|
+
- b0d296b: Phase 3 Task 14 — Pitchforks (`pitchfork` / `pitchfan`). The
|
|
454
|
+
`pitchfork` kind collapses the four invinite tools (`standard` /
|
|
455
|
+
`schiff` / `modifiedSchiff` / `inside`) into one kind with a
|
|
456
|
+
`variant` discriminator per PLAN.md §3.1.
|
|
457
|
+
|
|
458
|
+
- **adapter-kit** — 2 new per-kind validators
|
|
459
|
+
(`validatePitchforkState`, `validatePitchfanState`), reusing
|
|
460
|
+
Task-2's `validateAnchorTriple` + Task-5's `validateLineDrawStyle`
|
|
461
|
+
helpers. `validatePitchforkState` also pins the 4-entry variant
|
|
462
|
+
enum (`standard | schiff | modifiedSchiff | inside`). The
|
|
463
|
+
permissive-default test fixture moves from `pitchfork` to
|
|
464
|
+
`xabcd-pattern` (Task 15's first kind, still unported).
|
|
465
|
+
- **runtime** — 2 new emit functions under
|
|
466
|
+
`packages/runtime/src/emit/draw/pitchforks/` wired into the
|
|
467
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Both use the
|
|
468
|
+
3-arg form `(slotId, anchors, opts?)`. `pitchfork` accepts
|
|
469
|
+
`opts: LineDrawStyle & { variant? }` — the impl destructures
|
|
470
|
+
`variant` (defaulting to `"standard"`), strips it from the
|
|
471
|
+
style payload, and builds the `PitchforkState`. Fall-through-stub
|
|
472
|
+
fixture in `namespace.test.ts` / `primitives.test.ts` /
|
|
473
|
+
`buildComputeContext.test.ts` moves from `pitchfork` to
|
|
474
|
+
`xabcdPattern`.
|
|
475
|
+
- **canvas2d-adapter** — 2 new renderers + a shared
|
|
476
|
+
`pitchforkGeom.ts` helper exporting `medianOriginFor(variant, a,
|
|
477
|
+
b, c)` and `medianTargetFor(variant, a, b, c)` (per-variant
|
|
478
|
+
median-rail endpoints in canvas space). Default colour
|
|
479
|
+
`"#ec4899"` (pink/magenta, mirroring invinite's pitchfork-tool
|
|
480
|
+
palette family). The pitchfork renderer emits 3 strokes per
|
|
481
|
+
emission (median + 2 parallel handles through `b` and `c`); the
|
|
482
|
+
pitchfan renderer emits 3 rays from `a` through `b`, `mid(b, c)`,
|
|
483
|
+
`c`.
|
|
484
|
+
- **conformance** — 2 new per-kind scenarios + 1 bundle
|
|
485
|
+
(`drawPitchforksAll.scenario.ts` covering 4 pitchfork variants +
|
|
486
|
+
1 pitchfan = 5 emissions). Conformance + scenarios + index
|
|
487
|
+
test-capability fixtures widen `drawings` with
|
|
488
|
+
`capabilities.allPitchforkDrawings()`. All 3 hashes pinned
|
|
489
|
+
against the deterministic-run actuals.
|
|
490
|
+
|
|
491
|
+
Divergences flagged in
|
|
492
|
+
`tasks/phase-3-drawing-parity/14-pitchforks.plan.md`:
|
|
493
|
+
|
|
494
|
+
- `extendLeft` / `extendRight` flags from invinite's
|
|
495
|
+
`PitchforkDrawing` not on landed `PitchforkState`. Phase-3 pins
|
|
496
|
+
the default extend-forward behaviour for each rail (Task-1
|
|
497
|
+
reshape follow-up).
|
|
498
|
+
- Per-instance `levels` array not on landed state. Phase-3 renders
|
|
499
|
+
the median + 2 parallel-handle pattern only — no per-level
|
|
500
|
+
offsets (Task-1 reshape follow-up).
|
|
501
|
+
- `medianColor` / `medianLineStyle` / `medianStrokeWidthPx` not on
|
|
502
|
+
landed state. Phase-3 paints the median with the same
|
|
503
|
+
`LineDrawStyle` as the handles (Task-1 reshape follow-up).
|
|
504
|
+
- `gen-docs` regeneration for the 2 new kinds deferred to Task 21
|
|
505
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
506
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
507
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
508
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–13.
|
|
509
|
+
|
|
510
|
+
See `tasks/phase-3-drawing-parity/14-pitchforks.plan.md` for the
|
|
511
|
+
full audit + divergence list.
|
|
512
|
+
|
|
513
|
+
- b0d296b: Phase 3 Task 15 — Harmonic Patterns (`xabcdPattern` / `cypherPattern`
|
|
514
|
+
/ `headAndShoulders` / `abcdPattern` / `trianglePattern` /
|
|
515
|
+
`threeDrivesPattern`). All 6 kinds map to the `polylines` bucket and
|
|
516
|
+
ship as flat methods (`draw.<kind>(...)`) per the Task-11 Option-C
|
|
517
|
+
decision.
|
|
518
|
+
|
|
519
|
+
- **adapter-kit** — 6 new per-kind validators
|
|
520
|
+
(`validateXabcdPatternState`, `validateCypherPatternState`,
|
|
521
|
+
`validateHeadAndShouldersState`, `validateAbcdPatternState`,
|
|
522
|
+
`validateTrianglePatternState`,
|
|
523
|
+
`validateThreeDrivesPatternState`) plus a new
|
|
524
|
+
`validateAnchorHept` helper covering the 7-anchor
|
|
525
|
+
`three-drives-pattern` shape. All 6 validators reuse Task-5's
|
|
526
|
+
`validateLineDrawStyle` and Task-2's per-anchor-arity helpers.
|
|
527
|
+
The permissive-default test fixture moves from `xabcd-pattern`
|
|
528
|
+
→ `elliott-impulse-wave` (Task 16's first kind, still unported).
|
|
529
|
+
- **runtime** — 6 new emit functions under
|
|
530
|
+
`packages/runtime/src/emit/draw/patterns/` wired into the
|
|
531
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
|
|
532
|
+
3-arg form `(slotId, anchors, opts?)` with the dual-overload
|
|
533
|
+
pattern. Fall-through-stub fixture in `namespace.test.ts` /
|
|
534
|
+
`primitives.test.ts` / `buildComputeContext.test.ts` moves from
|
|
535
|
+
`xabcdPattern` to `elliottImpulseWave`.
|
|
536
|
+
- **canvas2d-adapter** — 6 new renderers plus a shared
|
|
537
|
+
`namedPolyline.ts` helper exporting `renderNamedPolyline(ctx,
|
|
538
|
+
points, labels, style)` — strokes an open polyline through the
|
|
539
|
+
pre-projected canvas-space points and fills one text label
|
|
540
|
+
above each anchor (textAlign `center` + textBaseline `bottom`,
|
|
541
|
+
6 px above the anchor). Default colour `#f59e0b` (amber/orange,
|
|
542
|
+
matching invinite's pattern-tool palette family).
|
|
543
|
+
`headAndShoulders` adds a neckline stroke between the two
|
|
544
|
+
trough anchors (`anchors[1]` → `anchors[3]`), totalling 2
|
|
545
|
+
strokes per emission; the other 5 kinds emit 1 polyline stroke - N point labels.
|
|
546
|
+
- **conformance** — 6 new per-kind scenarios + 1 bundle
|
|
547
|
+
(`drawPatternsAll.scenario.ts` covering all 6 kinds = 6
|
|
548
|
+
emissions). Conformance + scenarios + index test-capability
|
|
549
|
+
fixtures widen `drawings` with
|
|
550
|
+
`capabilities.allPatternDrawings()`. All 7 hashes pinned
|
|
551
|
+
against the deterministic-run actuals.
|
|
552
|
+
|
|
553
|
+
**Provenance carve-out — `cypherPattern`.** Per the team-lead
|
|
554
|
+
brief + PLAN.md §3.1, `cypher-pattern` has no standalone invinite
|
|
555
|
+
tool — only the y-doc-bridge type. The runtime emit
|
|
556
|
+
(`packages/runtime/src/emit/draw/patterns/cypherPattern.ts`) and
|
|
557
|
+
the canvas2d renderer
|
|
558
|
+
(`examples/canvas2d-adapter/src/render/draw/cypherPattern.ts`)
|
|
559
|
+
both cite **only** `invinite/shared/trading-chart-collab-yjs/y-doc-bridge.ts`
|
|
560
|
+
in their relicense headers (no `*-tool.ts` line). The UI surface
|
|
561
|
+
for cypher lives in `defineDrawing` (Task 20).
|
|
562
|
+
|
|
563
|
+
Divergences flagged in
|
|
564
|
+
`tasks/phase-3-drawing-parity/15-patterns.plan.md`:
|
|
565
|
+
|
|
566
|
+
- **`headAndShoulders` is 5-anchor on the landed state** (Task 1's
|
|
567
|
+
`HeadAndShouldersState.anchors: AnchorQuint`), not the 7-anchor
|
|
568
|
+
invinite shape (`start, leftShoulder, leftTrough, head,
|
|
569
|
+
rightTrough, rightShoulder, end`). The renderer treats the 5
|
|
570
|
+
anchors as `[LS, LL, H, RL, RS]` and strokes a neckline between
|
|
571
|
+
the two trough anchors only (no start/end projection). Flagged
|
|
572
|
+
as a Task-1 reshape follow-up.
|
|
573
|
+
- **`trianglePattern` is 3-anchor on the landed state**
|
|
574
|
+
(`TrianglePatternState.anchors: AnchorTriple`), not the 4-anchor
|
|
575
|
+
invinite shape (`a, b, c, d`). The renderer treats the 3 anchors
|
|
576
|
+
as `[apex, baseHigh, baseLow]` matching the landed type's
|
|
577
|
+
`@anchors` annotation. Flagged as a Task-1 reshape follow-up.
|
|
578
|
+
Distinct from `draw.triangle` (Task 6), a solid-shape primitive
|
|
579
|
+
with `ShapeStyle` — `draw.trianglePattern` is a harmonic-pattern
|
|
580
|
+
outline with `LineDrawStyle`. JSDoc cross-references the
|
|
581
|
+
distinction.
|
|
582
|
+
- `gen-docs` regeneration for the 6 new kinds deferred to Task 21
|
|
583
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
584
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
585
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
586
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–14.
|
|
587
|
+
|
|
588
|
+
See `tasks/phase-3-drawing-parity/15-patterns.plan.md` for the
|
|
589
|
+
full audit + divergence list.
|
|
590
|
+
|
|
591
|
+
- b0d296b: Phase 3 Task 16 — Elliott Waves (`elliottImpulseWave` /
|
|
592
|
+
`elliottCorrectionWave` / `elliottTriangleWave` / `elliottDoubleCombo`
|
|
593
|
+
/ `elliottTripleCombo`). All 5 kinds map to the `polylines` bucket
|
|
594
|
+
and ship as flat methods (`draw.<kind>(...)`) per the Task-11
|
|
595
|
+
Option-C decision.
|
|
596
|
+
|
|
597
|
+
- **adapter-kit** — 5 new per-kind validators
|
|
598
|
+
(`validateElliottImpulseWaveState`,
|
|
599
|
+
`validateElliottCorrectionWaveState`,
|
|
600
|
+
`validateElliottTriangleWaveState`,
|
|
601
|
+
`validateElliottDoubleComboState`,
|
|
602
|
+
`validateElliottTripleComboState`) plus a new
|
|
603
|
+
`validateOptionalLabels(v, path, expectedCount)` helper that
|
|
604
|
+
validates the optional script-author `state.labels` override
|
|
605
|
+
(when present: array of strings whose length exactly matches the
|
|
606
|
+
per-kind anchor count). All 5 validators reuse Task-5's
|
|
607
|
+
`validateLineDrawStyle` and Task-2/15's
|
|
608
|
+
`validateAnchorTriple` / `validateAnchorQuint` /
|
|
609
|
+
`validateAnchorHept`. The permissive-default test fixture moves
|
|
610
|
+
from `elliott-impulse-wave` → `cyclic-lines` (Task 17's first
|
|
611
|
+
kind, still unported).
|
|
612
|
+
- **runtime** — 5 new emit functions under
|
|
613
|
+
`packages/runtime/src/emit/draw/elliott/` wired into the
|
|
614
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
|
|
615
|
+
3-arg form `(slotId, anchors, opts?)` with the dual-overload
|
|
616
|
+
pattern. The runtime widens `opts` to
|
|
617
|
+
`LineDrawStyle & { labels?: ReadonlyArray<string> }` — the impl
|
|
618
|
+
destructures `labels` from `opts`, strips it from the style
|
|
619
|
+
payload, and stores it on `state.labels` only when present
|
|
620
|
+
(preserving the optional field's `undefined` state when omitted
|
|
621
|
+
so emission hashes stay stable). Fall-through-stub fixture in
|
|
622
|
+
`namespace.test.ts` / `primitives.test.ts` /
|
|
623
|
+
`buildComputeContext.test.ts` moves from `elliottImpulseWave` to
|
|
624
|
+
`cyclicLines`.
|
|
625
|
+
- **canvas2d-adapter** — 5 new renderers reusing Task-15's
|
|
626
|
+
`renderNamedPolyline` helper. Default colour `#14b8a6` (teal —
|
|
627
|
+
free palette slot distinct from blue/yellow/purple/pink/amber).
|
|
628
|
+
Each renderer honours the optional `state.labels` override when
|
|
629
|
+
present and its length matches the anchor count (defensive
|
|
630
|
+
fallback to the per-kind default `LABELS` constant). Per-kind
|
|
631
|
+
default labels: impulse `["1","2","3","4","5"]`, correction
|
|
632
|
+
`["A","B","C"]`, triangle `["a","b","c","d","e"]`, double-combo
|
|
633
|
+
`["S","W","x1","X","x2","Yi","Y"]`, triple-combo
|
|
634
|
+
`["S","W","X1","Y","X2","Zi","Z"]`. Dispatch test's describe
|
|
635
|
+
label bumps from "Task-16+ stubs" to "Task-17+ stubs".
|
|
636
|
+
- **conformance** — 5 new per-kind scenarios + 1 bundle
|
|
637
|
+
(`drawElliottAll.scenario.ts` covering all 5 kinds = 5
|
|
638
|
+
emissions). Conformance + scenarios + index test-capability
|
|
639
|
+
fixtures widen `drawings` with `capabilities.allElliottDrawings()`.
|
|
640
|
+
All 6 hashes pinned against the deterministic-run actuals.
|
|
641
|
+
|
|
642
|
+
Divergences flagged in
|
|
643
|
+
`tasks/phase-3-drawing-parity/16-elliott.plan.md`:
|
|
644
|
+
|
|
645
|
+
- **`WaveDegree` enum + label-decoration helper NOT on landed state**
|
|
646
|
+
(Task 1's `Elliott*State` shapes carry no `degree` field — they
|
|
647
|
+
carry an optional `labels?: ReadonlyArray<string>` field instead,
|
|
648
|
+
letting the script author override the per-kind default labels
|
|
649
|
+
directly). The 9-level `WaveDegree` enum + the
|
|
650
|
+
`elliottLabels.ts` decoration helper are dropped from Phase 3.
|
|
651
|
+
Flagged as a Task-1 reshape follow-up.
|
|
652
|
+
- **`elliottImpulseWave` is 5-anchor on the landed state** (Task 1's
|
|
653
|
+
`ElliottImpulseWaveState.anchors: AnchorQuint`), not the 6-anchor
|
|
654
|
+
invinite shape. The renderer treats the 5 anchors as the wave1End
|
|
655
|
+
→ wave5End pivots and strokes 4 connecting legs. Same precedent
|
|
656
|
+
for `elliottCorrectionWave` (landed 3-anchor vs invinite 4),
|
|
657
|
+
`elliottTriangleWave` (landed 5-anchor vs invinite 6), and
|
|
658
|
+
`elliottTripleCombo` (landed 7-anchor vs invinite 10). All
|
|
659
|
+
flagged as Task-1 reshape follow-ups.
|
|
660
|
+
- `gen-docs` regeneration for the 5 new kinds deferred to Task 21
|
|
661
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
662
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
663
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
664
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–15.
|
|
665
|
+
|
|
666
|
+
See `tasks/phase-3-drawing-parity/16-elliott.plan.md` for the full
|
|
667
|
+
audit + divergence list.
|
|
668
|
+
|
|
669
|
+
- b0d296b: Phase 3 Task 17 — Cycles (`cyclicLines` / `timeCycles` / `sineLine`).
|
|
670
|
+
All 3 kinds map to the `other` bucket and ship as flat methods
|
|
671
|
+
(`draw.<kind>(a, b, opts?)`) per the Task-11 Option-C decision.
|
|
672
|
+
|
|
673
|
+
- **adapter-kit** — 3 new per-kind validators
|
|
674
|
+
(`validateCyclicLinesState`, `validateTimeCyclesState`,
|
|
675
|
+
`validateSineLineState`). All 3 reuse Task-2's `validateAnchorPair`
|
|
676
|
+
- Task-5's `validateLineDrawStyle`; no new helpers needed (cycle
|
|
677
|
+
states carry no `labels` field, so Task-16's
|
|
678
|
+
`validateOptionalLabels` is not consumed). The permissive-default
|
|
679
|
+
test fixture moves from `cyclic-lines` → `group` (Task 18's first
|
|
680
|
+
kind, still unported).
|
|
681
|
+
- **runtime** — 3 new emit functions under
|
|
682
|
+
`packages/runtime/src/emit/draw/cycles/` wired into the
|
|
683
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
|
|
684
|
+
4-arg dual-overload form `(slotId, a, b, opts?)` mirroring `line`
|
|
685
|
+
(the script-author surface is the 3-arg `(a, b, opts?)`; the
|
|
686
|
+
compiler injects the leading slot id). State is assembled as
|
|
687
|
+
`anchors: [a, b]`. Fall-through-stub fixture in
|
|
688
|
+
`namespace.test.ts` / `primitives.test.ts` /
|
|
689
|
+
`buildComputeContext.test.ts` moves from `cyclicLines` to `group`.
|
|
690
|
+
- **canvas2d-adapter** — 3 new renderers reusing Task-4's
|
|
691
|
+
`worldPointToCanvas` + Phase-1 `dashPattern`. Default colour
|
|
692
|
+
`#0ea5e9` (sky blue — free palette slot distinct from
|
|
693
|
+
blue/yellow/purple/pink/amber/teal/green/red used by prior port
|
|
694
|
+
tasks). Per-kind geometry:
|
|
695
|
+
|
|
696
|
+
- `cyclicLines` — repeated full-height vertical strokes at
|
|
697
|
+
`fromX + n * periodPx` for n ∈ [0, viewport+overscan/periodPx],
|
|
698
|
+
capped at 256 iterations. Skips silently on degenerate period.
|
|
699
|
+
- `timeCycles` — concentric upper-half arcs centred at the
|
|
700
|
+
midpoint of `(from, to)` on the `from.price` baseline, radius =
|
|
701
|
+
`|toX − fromX| / 2`. Arcs tile across the viewport at multiples
|
|
702
|
+
of the diameter (64 per side). Skips silently on degenerate
|
|
703
|
+
diameter.
|
|
704
|
+
- `sineLine` — sampled sinusoidal polyline. Half-period =
|
|
705
|
+
`|toX − fromX|` (full period doubled). Baseline = midpoint of
|
|
706
|
+
`(fromY, toY)`. Amplitude = `|fromY − toY| / 2`. 32 samples per
|
|
707
|
+
full period; wave starts at the `from` extreme (peak vs trough
|
|
708
|
+
flipped by `fromPx.y < toPx.y` — mirrors invinite's
|
|
709
|
+
`extremeIsPeak` flag). Skips silently on degenerate half-period.
|
|
710
|
+
|
|
711
|
+
Dispatch test's describe labels bump from "Tasks 5–15 shipped" to
|
|
712
|
+
"Tasks 5–17 shipped" and "Task-17+ stubs" to "Task-18+ stubs".
|
|
713
|
+
|
|
714
|
+
- **conformance** — 3 new per-kind scenarios + 1 bundle
|
|
715
|
+
(`drawCyclesAll.scenario.ts` covering all 3 kinds = 3 emissions).
|
|
716
|
+
Conformance + scenarios + index test-capability fixtures widen
|
|
717
|
+
`drawings` with `capabilities.allCycleDrawings()`. All 4 hashes
|
|
718
|
+
pinned against the deterministic-run actuals:
|
|
719
|
+
`drawCyclicLines` = `975166fe…aae16`,
|
|
720
|
+
`drawTimeCycles` = `1bdaca36…d88c0`,
|
|
721
|
+
`drawSineLine` = `9f88b689…3ba8`,
|
|
722
|
+
`drawCyclesAll` = `ef46754f…cc80b`.
|
|
723
|
+
|
|
724
|
+
Divergences flagged in
|
|
725
|
+
`tasks/phase-3-drawing-parity/17-cycles.plan.md`:
|
|
726
|
+
|
|
727
|
+
- **`SineLineState.period: number` field NOT on landed state**
|
|
728
|
+
(Task 1's `SineLineState` carries only `anchors` + `style` —
|
|
729
|
+
the renderer derives the half-period from `|to.time − from.time|`,
|
|
730
|
+
matching invinite's tool source). The explicit `period: number`
|
|
731
|
+
field is dropped from Phase 3; flagged as a Task-1 reshape
|
|
732
|
+
follow-up.
|
|
733
|
+
- **`TimeCyclesState.style.fill` / `fillAlpha` NOT on landed state**
|
|
734
|
+
(Task 1's `TimeCyclesState` uses `LineDrawStyle`, not
|
|
735
|
+
`ShapeStyle`). The renderer strokes the arcs only — invinite's
|
|
736
|
+
tool source DOES fill the half-circles. Flagged as a Task-1
|
|
737
|
+
reshape follow-up.
|
|
738
|
+
- **`to.time > from.time` reject NOT enforced** — Phase-3 renderer
|
|
739
|
+
no-ops silently on degenerate input, matching every other Phase-3
|
|
740
|
+
drawing port (gann / fib / elliott all silently no-op on
|
|
741
|
+
collapsed anchors). The validator accepts reversed anchors per
|
|
742
|
+
`validateAnchorPair`'s finite-only contract.
|
|
743
|
+
- `gen-docs` regeneration for the 3 new kinds deferred to Task 21
|
|
744
|
+
(the existing `chartlang docs` command only walks `ta.*`; the
|
|
745
|
+
`draw.*` walker extension is an explicit Task-21 deliverable).
|
|
746
|
+
- Per-kind property / golden test files deferred to the pragmatic
|
|
747
|
+
1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–16.
|
|
748
|
+
|
|
749
|
+
See `tasks/phase-3-drawing-parity/17-cycles.plan.md` for the full
|
|
750
|
+
audit + divergence list.
|
|
751
|
+
|
|
752
|
+
- b0d296b: Phase 3 Task 18 — Containers (`group` / `frame`). The FINAL per-port
|
|
753
|
+
task: after this lands all 61 `DrawingKind`s have real validator /
|
|
754
|
+
emit / renderer / dispatch arms. Both kinds map to the `other`
|
|
755
|
+
bucket and ship as flat methods (`draw.group(childHandleIds)` /
|
|
756
|
+
`draw.frame(a, b, opts?)`) per the Task-11 Option-C decision.
|
|
757
|
+
|
|
758
|
+
- **adapter-kit** — 2 new per-kind validators (`validateGroupState`,
|
|
759
|
+
`validateFrameState`) + 2 tiny shared helpers
|
|
760
|
+
(`validateOptionalChildHandleIds`, `validateFrameOpts`). `group`
|
|
761
|
+
pins `childHandleIds.length ≤ 100`; `frame` reuses Task-2's
|
|
762
|
+
`validateAnchorPair`, accepts degenerate anchors (silent no-op at
|
|
763
|
+
the renderer per the rest of Phase-3's degenerate-input
|
|
764
|
+
precedent). The permissive-default test fixture
|
|
765
|
+
(`validateEmission.test.ts:1516`) flips from
|
|
766
|
+
`permissively-accepts` to a rejecting `validateGroupState`
|
|
767
|
+
assertion + a new gate-only test that asserts unknown kinds drop
|
|
768
|
+
with `unsupported-drawing-kind` upstream. After Task 18 every
|
|
769
|
+
`DrawingKind` has a real validator arm — the
|
|
770
|
+
`default: return { ok: true };` arm in `validateStateByKind` is
|
|
771
|
+
removed; TS's exhaustiveness check now catches a future
|
|
772
|
+
`DrawingKind` addition without a validator.
|
|
773
|
+
- **runtime** — 2 new emit functions under
|
|
774
|
+
`packages/runtime/src/emit/draw/containers/` wired into the
|
|
775
|
+
`DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. `group` is a
|
|
776
|
+
2-arg dual-overload `(slotId, childHandleIds)`; `frame` is a 4-arg
|
|
777
|
+
dual-overload `(slotId, a, b, opts?)` mirroring `line`. After Task
|
|
778
|
+
18 `IMPL_KIND_NAMES.size === 61`; the Proxy's else-branch
|
|
779
|
+
fall-through to core's throwing-stub is dead code on the
|
|
780
|
+
`DrawNamespace` type surface — kept as defence-in-depth for
|
|
781
|
+
property access outside that type. The pre-Task-18
|
|
782
|
+
"still-stubbed" assertions in `namespace.test.ts` /
|
|
783
|
+
`primitives.test.ts` / `buildComputeContext.test.ts` are replaced
|
|
784
|
+
with a positive cardinality sweep that asserts every
|
|
785
|
+
`DrawingKind` resolves to a real runtime impl that throws the
|
|
786
|
+
in-step-only sentinel (NOT the core stub sentinel).
|
|
787
|
+
- **canvas2d-adapter** — 1 real renderer (`renderFrame`) + 1 pure
|
|
788
|
+
no-op renderer (`renderGroup`). `renderFrame` strokes a closed
|
|
789
|
+
4-corner rectangle defaulting to slate `#64748b`, optionally
|
|
790
|
+
paints a `fillRect` background when `style.bgColor` is set, and
|
|
791
|
+
optionally paints a `fillText` label inset 6 px from the top-left
|
|
792
|
+
when `style.label` is set. Degenerate anchors (zero width or zero
|
|
793
|
+
height in canvas space) silently no-op. `renderGroup` is a pure
|
|
794
|
+
no-op for Phase 3 — the visible bounding-box envelope around
|
|
795
|
+
grouped drawings is a Phase-4 follow-up tied to
|
|
796
|
+
`Viewport.drawingsById` plumbing (Viewport currently exposes only
|
|
797
|
+
`xMin/xMax/yMin/yMax/pxWidth/pxHeight`). `drawingDispatch`'s
|
|
798
|
+
`// Containers (Task 18)` arms flip from `return;` no-ops to
|
|
799
|
+
`return renderGroup(...)` / `return renderFrame(...)`. The
|
|
800
|
+
`drawingDispatch.test.ts` describe labels bump:
|
|
801
|
+
`Task-18+ stubs` → `'group' no-op + exhaustiveness`;
|
|
802
|
+
`Tasks 5–17 shipped` → `Tasks 5–18 shipped`.
|
|
803
|
+
- **conformance** — 2 new per-kind scenarios (`drawGroup`,
|
|
804
|
+
`drawFrame`) + 1 bundle (`drawContainersAll`, 2 emissions).
|
|
805
|
+
Pinned `drawing-hash` assertions for each:
|
|
806
|
+
- `draw-group`:
|
|
807
|
+
`6e32e387543ef421d1e53c1c15612cc32a814c85c2d969ad86d9f47b8d0359a2`
|
|
808
|
+
- `draw-frame`:
|
|
809
|
+
`4b54e0b6e75ad40904e0f70ac5b34067afa6c1237d43060823889f04b86d900b`
|
|
810
|
+
- `draw-containers-all`:
|
|
811
|
+
`e6ba183dfc04145a5126e6ea75a4cb7117694adc13eea84853239c68810e91fe`
|
|
812
|
+
`TEST_CAPABILITIES.drawings` widens with
|
|
813
|
+
`...capBuilders.allContainerDrawings()`; the `ALL_SCENARIOS`
|
|
814
|
+
`toEqual` array (in `scenarios.test.ts` and `index.test.ts`)
|
|
815
|
+
appends the 3 new scenarios under
|
|
816
|
+
`// Phase 3 Task 18 — Containers.`.
|
|
817
|
+
|
|
818
|
+
### Divergences from spec (`tasks/phase-3-drawing-parity/18-containers.md`)
|
|
819
|
+
|
|
820
|
+
1. **Spec § Runtime Notes says `draw.group(children:
|
|
821
|
+
ReadonlyArray<DrawingHandle>)` accepts handle objects.** Landed
|
|
822
|
+
core surface takes `ReadonlyArray<string>` (handle ids) directly
|
|
823
|
+
— the runtime impl uses the landed shape so the wire payload is
|
|
824
|
+
1:1 with what the script passes. Documented in `draw.group`'s
|
|
825
|
+
JSDoc with the canonical `draw.group([a.id, b.id])` pattern.
|
|
826
|
+
2. **Spec § Renderer Notes says `group` renders a dashed bounding
|
|
827
|
+
box derived from children's `view.drawingsById.get(childId).state`
|
|
828
|
+
extrema.** Landed `Viewport` exposes no `drawingsById` field;
|
|
829
|
+
adding it is a foundation-level Viewport change beyond a per-port
|
|
830
|
+
task. Phase 3 ships `renderGroup` as a pure no-op (children
|
|
831
|
+
render themselves per `GroupState`'s metadata contract);
|
|
832
|
+
bounding-box envelope deferred to Phase 4.
|
|
833
|
+
3. **Spec § Kinds Landed says `group.style: { lineWidth?; color? }`
|
|
834
|
+
for the boundary box.** Landed `GroupState` has no `style` field
|
|
835
|
+
(only `childHandleIds` + optional `meta`). Use the landed shape;
|
|
836
|
+
the boundary-box style lands with the Phase-4 renderer rework.
|
|
837
|
+
4. **Spec § Tests says degenerate `frame` anchors are a warning
|
|
838
|
+
diagnostic.** Landed `validateAnchorPair` only enforces finite
|
|
839
|
+
`time`/`price`; degenerate frames pass validation and the
|
|
840
|
+
renderer silently no-ops on `width === 0 || height === 0`. This
|
|
841
|
+
matches the rest of Phase 3's "no-op on degenerate input"
|
|
842
|
+
precedent (gann/fib/elliott/cycles).
|
|
843
|
+
5. **Per-kind property tests skipped** — same Tasks 5–17 precedent.
|
|
844
|
+
The per-kind validator describe arms cover happy + wrong-shape
|
|
845
|
+
per kind; the `childHandleIds.length ≤ 100` cap is exercised
|
|
846
|
+
directly in the group describe block.
|
|
847
|
+
|
|
848
|
+
### Open / deferred
|
|
849
|
+
|
|
850
|
+
- `GroupState` boundary-box style + `view.drawingsById` plumbing for
|
|
851
|
+
the visible group envelope land in Phase 4 (Divergence §2 + §3).
|
|
852
|
+
- `gen-docs` regeneration for `docs/primitives/draw/{group,frame}.md`
|
|
853
|
+
defers to Task 21 (same precedent as Tasks 11–17 — the
|
|
854
|
+
draw-namespace docs walker is Task 21's deliverable).
|
|
855
|
+
- Workspace-wide gates (`pnpm typecheck`, `pnpm test` at the root)
|
|
856
|
+
defer to Task 22's phase closeout. Per-package gates
|
|
857
|
+
(adapter-kit / runtime / canvas2d / conformance) all green and
|
|
858
|
+
100% coverage held.
|
|
859
|
+
|
|
860
|
+
- b0d296b: Phase-3 Task 2 — adapter-kit drawing surface.
|
|
861
|
+
|
|
862
|
+
Widens `DrawingKind` from the Phase-1 `"line"` placeholder to the full
|
|
863
|
+
61-entry kebab-case union (re-export of
|
|
864
|
+
`@invinite-org/chartlang-core`'s `DrawingKind`). Narrows
|
|
865
|
+
`DrawingEmission.state` from `unknown` to the typed `DrawingState`
|
|
866
|
+
discriminated union. Adapter code that wrote `drawingKind: "line"`
|
|
867
|
+
still compiles.
|
|
868
|
+
|
|
869
|
+
Replaces the Phase-1 unconditional-fail `validateDrawingEmission` with
|
|
870
|
+
a per-kind dispatch:
|
|
871
|
+
|
|
872
|
+
- Unknown `drawingKind` → `unsupported-drawing-kind`.
|
|
873
|
+
- Malformed payloads of a known kind → `malformed-emission`.
|
|
874
|
+
- The 6 Lines/Rays validators land in this PR (`line`,
|
|
875
|
+
`horizontal-line`, `horizontal-ray`, `vertical-line`,
|
|
876
|
+
`cross-line`, `trend-angle`). Tasks 6–18 ADD their kind
|
|
877
|
+
validators to the dispatch as ports land (per PLAN.md §22.10).
|
|
878
|
+
- Validates `handleId` / `op` / `bar` / `time` /
|
|
879
|
+
`state.kind === drawingKind` / `name`/`visible` meta for every
|
|
880
|
+
kind.
|
|
881
|
+
|
|
882
|
+
Replaces the Phase-1 `decodeDrawing` stub (always returned `null`)
|
|
883
|
+
with the real implementation: returns the typed `DrawingState` for
|
|
884
|
+
emissions that pass `validateEmission`, `null` otherwise.
|
|
885
|
+
|
|
886
|
+
Extends `capabilities.*` with the Phase-3 builder set:
|
|
887
|
+
|
|
888
|
+
- **61 per-kind builders** (`drawLine()`, `drawHorizontalLine()`,
|
|
889
|
+
`drawFibRetracement()`, `drawElliottImpulseWave()`, …) — each
|
|
890
|
+
returns a single-element `ReadonlySet<DrawingKind>` for opt-in
|
|
891
|
+
precision.
|
|
892
|
+
- **13 category-group builders** matching PLAN.md §10.2:
|
|
893
|
+
`allLineDrawings()` (6), `allBoxDrawings()` (8),
|
|
894
|
+
`allCurveDrawings()` (3), `allFreehandDrawings()` (3),
|
|
895
|
+
`allAnnotationDrawings()` (5), `allChannelDrawings()` (4),
|
|
896
|
+
`allFibDrawings()` (10), `allGannDrawings()` (4),
|
|
897
|
+
`allPitchforkDrawings()` (2), `allPatternDrawings()` (6),
|
|
898
|
+
`allElliottDrawings()` (5), `allCycleDrawings()` (3),
|
|
899
|
+
`allContainerDrawings()` (2). The 13 categories are pairwise
|
|
900
|
+
disjoint and sum to 61.
|
|
901
|
+
- **`allPhase3Drawings()`** — the umbrella set of every kind.
|
|
902
|
+
Adapters that support the full surface (canvas2d in Task 4)
|
|
903
|
+
declare this as their `Capabilities.drawings`.
|
|
904
|
+
|
|
905
|
+
Re-exports `bucketFor` + `KIND_BUCKET` + `type DrawingBucket` from
|
|
906
|
+
core via the adapter-kit barrel. Adapter authors that want to
|
|
907
|
+
pre-budget against the canonical kind → bucket map can import them
|
|
908
|
+
directly from `@invinite-org/chartlang-adapter-kit`.
|
|
909
|
+
|
|
910
|
+
No runtime behaviour change — the runtime still doesn't emit
|
|
911
|
+
drawings. Phase-2 plot dispatch + meta walker + Phase-1 alert /
|
|
912
|
+
diagnostic dispatches are unchanged. 100% coverage on
|
|
913
|
+
`packages/adapter-kit` preserved.
|
|
914
|
+
|
|
915
|
+
- b0d296b: Phase-3 Task 6 — second per-port task. Lands the 4 straight-edged
|
|
916
|
+
box-family drawing kinds (`rectangle`, `rotatedRectangle`, `triangle`,
|
|
917
|
+
`polyline`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
|
|
918
|
+
commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
|
|
919
|
+
`tools/rectangle-tool.ts`, `tools/rotated-rectangle-tool.ts`,
|
|
920
|
+
`tools/triangle-tool.ts`, `tools/polyline-tool.ts`, and the matching
|
|
921
|
+
`y-doc-bridge.ts` `DrawingMetadata` variants.
|
|
922
|
+
|
|
923
|
+
`@invinite-org/chartlang-adapter-kit` adds per-kind state validators
|
|
924
|
+
for the 4 box-A kinds — `validateRectangleState`,
|
|
925
|
+
`validateRotatedRectangleState`, `validateTriangleState`,
|
|
926
|
+
`validatePolylineState` — wired into the existing
|
|
927
|
+
`validateStateByKind` dispatch. New file-local helpers
|
|
928
|
+
`validateAnchorTriple` / `validateAnchorQuad` /
|
|
929
|
+
`validateAnchorVariable(min, max)` / `validateShapeStyle` cover the
|
|
930
|
+
anchor cardinalities and the `ShapeStyle` payload bag. `polyline`
|
|
931
|
+
pins `3 ≤ anchors.length ≤ 20` (mirrors invinite's 20-point cap).
|
|
932
|
+
Wire shape is stricter than before — payloads previously passing the
|
|
933
|
+
permissive default arm now reject with `malformed-emission`.
|
|
934
|
+
|
|
935
|
+
`@invinite-org/chartlang-runtime` ships 4 new `draw.<kind>(...)` emit
|
|
936
|
+
functions under `src/emit/draw/boxes/` and extends the
|
|
937
|
+
`DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
|
|
938
|
+
uses the dual-overload pattern (`(...)` script-facing throw +
|
|
939
|
+
`(slotId, ...)` compiler-injected) mirroring Task 5 / `plot` /
|
|
940
|
+
`alert`. Returns a `DrawingHandle` per PLAN.md §10.3.
|
|
941
|
+
|
|
942
|
+
`chartlang-example-canvas2d-adapter` ships 4 new renderers under
|
|
943
|
+
`src/render/draw/` plus a shared `shapeStyle.ts` helper exporting
|
|
944
|
+
`applyShapeStyle(ctx, style): AppliedShapeStyle` — sets stroke /
|
|
945
|
+
lineWidth / dash and returns the resolved fill payload so the
|
|
946
|
+
renderer can wrap `ctx.fill()` in a `globalAlpha` bracket. The
|
|
947
|
+
`drawingDispatch` switch flips the 4 box-A arms from no-op stubs to
|
|
948
|
+
real `renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
|
|
949
|
+
Fill defaults to no-op, stroke defaults to `"#000000"`, lineWidth
|
|
950
|
+
defaults to `1`. Rectangle is rendered as a closed 4-corner polygon
|
|
951
|
+
(no `strokeRect` in the structural `RenderCtx`); rotatedRectangle
|
|
952
|
+
walks the four world anchors directly (no canvas matrix ops);
|
|
953
|
+
triangle walks 3 vertices; polyline auto-closes via `closePath()`.
|
|
954
|
+
|
|
955
|
+
`@invinite-org/chartlang-conformance` ships 5 new scenarios under
|
|
956
|
+
`src/scenarios/` — 4 per-kind (`drawRectangle`, `drawRotatedRectangle`,
|
|
957
|
+
`drawTriangle`, `drawPolyline`) and 1 bundle (`drawBoxesA`). All five
|
|
958
|
+
use `inlineSource` against the bundled 10 000-bar `goldenBars.json`
|
|
959
|
+
fixture with anchor times pulled from `bars[0]` / `bars[500]` /
|
|
960
|
+
`bars[1000]`. The `TEST_CAPABILITIES` bag in
|
|
961
|
+
`runConformanceSuite.test.ts` + `scenarios.test.ts` widens to include
|
|
962
|
+
`allBoxDrawings()` plus `boxes: 100` / `polylines: 100` budgets so
|
|
963
|
+
the new scenarios reach `pushDrawing`'s happy path. The 5 new
|
|
964
|
+
scenarios extend `ALL_SCENARIOS` (now 96 entries) and the public
|
|
965
|
+
re-export surface.
|
|
966
|
+
|
|
967
|
+
No core edits — the `DrawingState` variants and `DrawNamespace`
|
|
968
|
+
signatures Task 1 shipped are the canonical shape and Task 6 wires
|
|
969
|
+
real impls to them.
|
|
970
|
+
|
|
971
|
+
Deviations from spec, flagged for review:
|
|
972
|
+
|
|
973
|
+
- Spec's `rotatedRectangle` "3 anchors (a, b, widthOffset)"
|
|
974
|
+
ergonomics — Task 1's `AnchorQuad` (4 corners) is the persisted
|
|
975
|
+
shape. Callers supply the 4 corners directly; the
|
|
976
|
+
(a, b, widthOffset) reshape belongs to Task 20's `defineDrawing`
|
|
977
|
+
if it remains a hard requirement.
|
|
978
|
+
- Spec's `polyline` `ShapeStyle` + auto-close — Task 1 ships
|
|
979
|
+
`LineDrawStyle` (no fill). Renderer strokes the closed path; fill
|
|
980
|
+
would require widening the variant in a follow-up.
|
|
981
|
+
- Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
|
|
982
|
+
(mirrors Task 5) — Task 3's `pushDrawing.*` and `handle.*` suite
|
|
983
|
+
covers the underlying infra exhaustively.
|
|
984
|
+
- `gen-docs` doc-page generation deferred to Task 21 (mirrors Task 5).
|
|
985
|
+
|
|
986
|
+
- b0d296b: Phase-3 Task 7 — third per-port task. Lands the 4 curved-edge /
|
|
987
|
+
single-anchor box-family drawing kinds (`circle`, `ellipse`, `path`,
|
|
988
|
+
`marker`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
|
|
989
|
+
commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
|
|
990
|
+
`tools/circle-tool.ts`, `tools/ellipse-tool.ts`, `tools/path-tool.ts`,
|
|
991
|
+
`tools/marker-tool.ts`, and the matching `y-doc-bridge.ts` variants.
|
|
992
|
+
|
|
993
|
+
`@invinite-org/chartlang-adapter-kit` adds per-kind state validators
|
|
994
|
+
for the 4 box-B kinds — `validateCircleState`, `validateEllipseState`,
|
|
995
|
+
`validatePathState`, `validateMarkerState` — wired into the existing
|
|
996
|
+
`validateStateByKind` dispatch. New file-local helpers
|
|
997
|
+
`validatePathOpts` (LineDrawStyle + optional `closed: boolean`) and
|
|
998
|
+
`validateTextOpts` (color / size / halign / valign / bgColor enums)
|
|
999
|
+
cover the path / marker style bags. `path` pins
|
|
1000
|
+
`2 ≤ anchors.length ≤ 20` (mirrors invinite's 20-point cap and is
|
|
1001
|
+
narrower than `polyline`'s 3..20 because path supports a 2-point
|
|
1002
|
+
segment with optional caps). Wire shape is stricter than before —
|
|
1003
|
+
payloads previously passing the permissive default arm now reject
|
|
1004
|
+
with `malformed-emission`.
|
|
1005
|
+
|
|
1006
|
+
`@invinite-org/chartlang-runtime` ships 4 new `draw.<kind>(...)` emit
|
|
1007
|
+
functions under `src/emit/draw/boxes/` and extends the
|
|
1008
|
+
`DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
|
|
1009
|
+
uses the dual-overload pattern Tasks 5 + 6 pinned. `draw.marker`
|
|
1010
|
+
splits its `opts` bag — top-level `text` / `value` land on
|
|
1011
|
+
`MarkerState` while the remaining `TextOpts` fields nest under
|
|
1012
|
+
`state.style`.
|
|
1013
|
+
|
|
1014
|
+
`chartlang-example-canvas2d-adapter` ships 4 new renderers under
|
|
1015
|
+
`src/render/draw/`. `renderCircle` derives the radius in canvas-pixel
|
|
1016
|
+
space from `|edge - centre|` (matches invinite's circle-tool) and
|
|
1017
|
+
issues a single `ctx.arc(...)`. `renderEllipse` paints a 64-segment
|
|
1018
|
+
polyline approximation (Phase-1 `RenderCtx` exposes `arc(...)` but
|
|
1019
|
+
not `ellipse(...)` — a polyline keeps the renderer pure on the
|
|
1020
|
+
existing structural surface without widening it). `renderPath` paints
|
|
1021
|
+
an OPEN polyline (no `closePath` by default; `style.closed === true`
|
|
1022
|
+
toggles closure). `renderMarker` projects the anchor + paints
|
|
1023
|
+
`text` (when set) via `ctx.fillText` with `TextOpts`-derived font +
|
|
1024
|
+
alignment. Empty / undefined text is a pure no-op — icon-glyph
|
|
1025
|
+
painting belongs to Task 20's `defineDrawing` follow-up. The
|
|
1026
|
+
`drawingDispatch` switch flips the 4 box-B arms from no-op stubs to
|
|
1027
|
+
real `renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
|
|
1028
|
+
|
|
1029
|
+
`@invinite-org/chartlang-conformance` ships 4 new per-kind scenarios
|
|
1030
|
+
under `src/scenarios/` (`drawCircle`, `drawEllipse`, `drawPath`,
|
|
1031
|
+
`drawMarker`). Per README §22.10 the Task-6 `drawBoxesA.scenario.ts`
|
|
1032
|
+
is REPLACED (deleted) by the wider `drawBoxesAll.scenario.ts`
|
|
1033
|
+
covering all 8 box kinds across Tasks 6 + 7 (rectangle /
|
|
1034
|
+
rotated-rectangle / triangle / polyline / circle / ellipse / path /
|
|
1035
|
+
marker). All five new scenarios use `inlineSource` against the
|
|
1036
|
+
bundled 10 000-bar `goldenBars.json` fixture with anchor times pulled
|
|
1037
|
+
from `bars[0]` / `bars[500]` / `bars[1000]`. The `TEST_CAPABILITIES`
|
|
1038
|
+
bag in `runConformanceSuite.test.ts` + `scenarios.test.ts` bumps
|
|
1039
|
+
`labels` budget from 0 to 100 to host the marker scenario (marker
|
|
1040
|
+
maps to the `labels` bucket). The 4 + 1 new scenarios extend
|
|
1041
|
+
`ALL_SCENARIOS` and the public re-export surface; `DRAW_BOXES_A_SCENARIO`
|
|
1042
|
+
is removed from the public surface (downstream consumers move to
|
|
1043
|
+
`DRAW_BOXES_ALL_SCENARIO`).
|
|
1044
|
+
|
|
1045
|
+
No core edits — the `DrawingState` variants and `DrawNamespace`
|
|
1046
|
+
signatures Task 1 shipped are the canonical shape and Task 7 wires
|
|
1047
|
+
real impls to them.
|
|
1048
|
+
|
|
1049
|
+
Deviations from spec, flagged for review:
|
|
1050
|
+
|
|
1051
|
+
- `MarkerState` shape divergence — task spec's `markerKind` (`emoji` /
|
|
1052
|
+
`icon`) discriminator + `value: string` + `MAX_LENGTH = 32` + icon
|
|
1053
|
+
registry NOT implemented. Uses Task 1's landed
|
|
1054
|
+
`{ anchor, text?, value?, style: TextOpts }` shape (anchor not
|
|
1055
|
+
from/to pair; value is a number; no discriminator). Re-shaping
|
|
1056
|
+
belongs to a follow-up that widens core; mid-phase Task-1 reshapes
|
|
1057
|
+
cascade through the `DrawingState` union + adapter-kit decoder +
|
|
1058
|
+
Task-6 permissive-default tests.
|
|
1059
|
+
- `Ellipse` rendered as 64-segment polyline approximation because
|
|
1060
|
+
`RenderCtx` exposes `arc(...)` but not `ellipse(...)`. Widening
|
|
1061
|
+
the structural type would touch Phase-1's `RenderCtx`; the
|
|
1062
|
+
polyline path stays on the existing surface.
|
|
1063
|
+
- Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
|
|
1064
|
+
(mirrors Tasks 5 + 6) — Task 3's `pushDrawing.*` and `handle.*`
|
|
1065
|
+
suite covers the underlying infra exhaustively.
|
|
1066
|
+
- `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
|
|
1067
|
+
5 + 6).
|
|
1068
|
+
|
|
1069
|
+
- b0d296b: Phase-3 Task 8 — fourth per-port task. Lands the 6 curve + freehand
|
|
1070
|
+
drawing kinds (`arc`, `curve`, `doubleCurve`, `pen`, `highlighter`,
|
|
1071
|
+
`brush`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
|
|
1072
|
+
commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
|
|
1073
|
+
`tools/arc-tool.ts`, `tools/curve-tool.ts`,
|
|
1074
|
+
`tools/double-curve-tool.ts`, `tools/pen-tool.ts`,
|
|
1075
|
+
`tools/highlighter-tool.ts`, `tools/brush-tool.ts`, and the matching
|
|
1076
|
+
`y-doc-bridge.ts` variants (`ArcDrawing`, `CurveDrawing`,
|
|
1077
|
+
`DoubleCurveDrawing`, `PenDrawing`, `HighlighterDrawing`,
|
|
1078
|
+
`BrushDrawing`). All 6 kinds map to the `polylines` bucket.
|
|
1079
|
+
|
|
1080
|
+
`@invinite-org/chartlang-adapter-kit` adds per-kind state validators
|
|
1081
|
+
for the 6 curve + freehand kinds — `validateArcState`,
|
|
1082
|
+
`validateCurveState`, `validateDoubleCurveState`, `validatePenState`,
|
|
1083
|
+
`validateHighlighterState`, `validateBrushState` — wired into the
|
|
1084
|
+
existing `validateStateByKind` dispatch. Three new file-local helpers
|
|
1085
|
+
land alongside: `validateAnchorQuint` (5-tuple for `double-curve`),
|
|
1086
|
+
`validateHighlighterStyle` (required `color: string` + required
|
|
1087
|
+
`alpha ∈ [0, 1]`), and `validateBrushStyle` (required `stroke` + `fill`
|
|
1088
|
+
colour strings). Freehand kinds pin `2 ≤ anchors.length ≤ 500`
|
|
1089
|
+
(matches invinite's stroke cap; broader than the 2..20 path cap).
|
|
1090
|
+
Wire shape is stricter than before — payloads previously passing the
|
|
1091
|
+
permissive default arm now reject with `malformed-emission`.
|
|
1092
|
+
|
|
1093
|
+
`@invinite-org/chartlang-runtime` ships 6 new `draw.<kind>(...)` emit
|
|
1094
|
+
functions under `src/emit/draw/curves/` and extends the
|
|
1095
|
+
`DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
|
|
1096
|
+
uses the dual-overload pattern Tasks 5–7 pinned. `draw.highlighter`
|
|
1097
|
+
and `draw.brush` differ from the other emit fns — their `opts`
|
|
1098
|
+
parameter is REQUIRED on the script-facing overload (no `?` because
|
|
1099
|
+
`HighlighterStyle` / `BrushStyle` carry required fields).
|
|
1100
|
+
|
|
1101
|
+
`chartlang-example-canvas2d-adapter` ships 6 new renderers under
|
|
1102
|
+
`src/render/draw/`. The 3 curve renderers (`renderArc`, `renderCurve`,
|
|
1103
|
+
`renderDoubleCurve`) sample the curve via Task 4's `sampleQuadratic` /
|
|
1104
|
+
`sampleCubic` helpers at `CURVE_SAMPLES = 32` segments and stroke as a
|
|
1105
|
+
polyline — the structural `RenderCtx` exposes neither
|
|
1106
|
+
`quadraticCurveTo` nor `bezierCurveTo`, so this keeps the renderer
|
|
1107
|
+
pure on the Phase-1 surface (mirrors Task 7's `ellipse` 64-segment
|
|
1108
|
+
polyline approximation). `renderArc` derives the Bezier control point
|
|
1109
|
+
from `apex` via inverse-quadratic interpolation so the curve passes
|
|
1110
|
+
through `apex` at `t = 0.5`; `renderCurve` uses `anchors[1]` as the
|
|
1111
|
+
Bezier control directly (curve does NOT pass through control);
|
|
1112
|
+
`renderDoubleCurve` paints a single cubic from `anchors[0]` to
|
|
1113
|
+
`anchors[4]` with off-curve controls `anchors[1]` / `anchors[3]` (the
|
|
1114
|
+
middle stitch anchor `anchors[2]` is preserved in state but unused by
|
|
1115
|
+
the current render path — flagged for future split-rendering). The 3
|
|
1116
|
+
freehand renderers paint polylines: `renderPen` strokes open;
|
|
1117
|
+
`renderHighlighter` wraps the stroke in a `globalAlpha` set/reset
|
|
1118
|
+
bracket (default 6 px line width); `renderBrush` paints
|
|
1119
|
+
fill-then-stroke with `closePath` for a closed filled region. The
|
|
1120
|
+
`drawingDispatch` switch flips the 6 arms from no-op stubs to real
|
|
1121
|
+
`renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
|
|
1122
|
+
|
|
1123
|
+
`@invinite-org/chartlang-conformance` ships 6 new per-kind scenarios
|
|
1124
|
+
under `src/scenarios/` (`drawArc`, `drawCurve`, `drawDoubleCurve`,
|
|
1125
|
+
`drawPen`, `drawHighlighter`, `drawBrush`) plus one bundle scenario
|
|
1126
|
+
`drawCurvesAndFreehandAll` that emits one drawing per curve + freehand
|
|
1127
|
+
kind on the first bar (per README §22.10 Task 8 collapses both
|
|
1128
|
+
categories into ONE bundle). All seven scenarios use `inlineSource`
|
|
1129
|
+
against the bundled 10 000-bar `goldenBars.json` fixture with anchor
|
|
1130
|
+
times pulled from `bars[0]` / `bars[500]` / `bars[1000]` (plus
|
|
1131
|
+
`bars[1500]` for the 4-point freehand strokes). The `TEST_CAPABILITIES`
|
|
1132
|
+
bags in `runConformanceSuite.test.ts` + `scenarios/scenarios.test.ts`
|
|
1133
|
+
extend the `drawings` set with `allCurveDrawings()` +
|
|
1134
|
+
`allFreehandDrawings()`; the existing `polylines: 100` bucket budget
|
|
1135
|
+
covers the bundle scenarios with headroom. `ALL_SCENARIOS` extends
|
|
1136
|
+
additively.
|
|
1137
|
+
|
|
1138
|
+
No core edits — the `DrawingState` variants and `DrawNamespace`
|
|
1139
|
+
signatures Task 1 shipped are the canonical shape and Task 8 wires
|
|
1140
|
+
real impls to them.
|
|
1141
|
+
|
|
1142
|
+
Deviations from spec, flagged for review:
|
|
1143
|
+
|
|
1144
|
+
- `PressurePoint` type widening NOT applied — Task 1's `PenState`
|
|
1145
|
+
shape (`anchors: ReadonlyArray<WorldPoint>`) preserved per Tasks
|
|
1146
|
+
6/7 precedent of not reshaping Task-1 mid-phase. Adapter-level
|
|
1147
|
+
pressure-driven stroke-width variance is a follow-up concern.
|
|
1148
|
+
- `freehand.ts` smoothing helper NOT created. Per-renderer inline
|
|
1149
|
+
polyline loops suffice for Phase-3 deterministic `drawing-hash`
|
|
1150
|
+
assertions. If pressure-driven smoothing lands later, the helper
|
|
1151
|
+
can ship then.
|
|
1152
|
+
- `double-curve` middle anchor (`anchors[2]`, the stitch point) is
|
|
1153
|
+
preserved in state but currently unused by the renderer (single
|
|
1154
|
+
cubic from `anchors[0]` to `anchors[4]` with controls `[1]` / `[3]`).
|
|
1155
|
+
Future split-rendering can stitch two cubics through `mid`.
|
|
1156
|
+
- `arc` / `curve` / `doubleCurve` fill-path NOT rendered.
|
|
1157
|
+
`LineDrawStyle` has no fill fields; invinite's tools do support
|
|
1158
|
+
fill on these kinds. Widening to support fill is a Task-1 reshape
|
|
1159
|
+
and out of scope.
|
|
1160
|
+
- Bezier rendered as 32-segment polyline approximation because
|
|
1161
|
+
`RenderCtx` exposes `arc(...)` but not `quadraticCurveTo` /
|
|
1162
|
+
`bezierCurveTo`. Mirrors Task 7's `ellipse` 64-segment approach;
|
|
1163
|
+
widening would touch Phase-1 surface.
|
|
1164
|
+
- Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
|
|
1165
|
+
(mirrors Tasks 5–7) — Task 3's `pushDrawing.*` and `handle.*`
|
|
1166
|
+
suite covers the underlying infra exhaustively.
|
|
1167
|
+
- `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
|
|
1168
|
+
5–7).
|
|
1169
|
+
|
|
1170
|
+
- b0d296b: Phase-3 Task 9 — fifth per-port task. Lands the 5 annotation drawing
|
|
1171
|
+
kinds (`text`, `arrow`, `arrowMarker`, `arrowMarkUp`, `arrowMarkDown`)
|
|
1172
|
+
per PLAN.md §10 and §22.10. Behaviour ports from invinite commit
|
|
1173
|
+
`078f41fe2569d659d5aba726da8bcb5d3e2ced02`: `tools/text-tool.ts`,
|
|
1174
|
+
`tools/arrow-tool.ts`, `tools/arrow-marker-tool.ts`,
|
|
1175
|
+
`tools/arrow-mark-up-tool.ts`, `tools/arrow-mark-down-tool.ts`, and the
|
|
1176
|
+
matching `y-doc-bridge.ts` variants (`TextDrawing`, `ArrowDrawing`,
|
|
1177
|
+
`ArrowMarkerDrawing`, `ArrowMarkUpDrawing`, `ArrowMarkDownDrawing`).
|
|
1178
|
+
All 5 kinds map to the `labels` bucket.
|
|
1179
|
+
|
|
1180
|
+
`@invinite-org/chartlang-adapter-kit` adds per-kind state validators
|
|
1181
|
+
for the 5 annotation kinds — `validateTextState`, `validateArrowState`,
|
|
1182
|
+
`validateArrowMarkerState`, `validateArrowMarkUpState`,
|
|
1183
|
+
`validateArrowMarkDownState` — wired into the existing
|
|
1184
|
+
`validateStateByKind` dispatch. Two new file-local style helpers land
|
|
1185
|
+
alongside: `validateArrowOpts` (`LineDrawStyle` + optional string
|
|
1186
|
+
`label`) and `validateArrowMarkerOpts` (optional `color` + optional
|
|
1187
|
+
`text`). `text.body` is validated through `walkMeta` (catches
|
|
1188
|
+
non-JsonValue payloads like bigint / function / symbol) and then
|
|
1189
|
+
pinned as a non-empty string with `TEXT_BODY_MAX_LENGTH = 256` (longer
|
|
1190
|
+
than the 128 cap on plot labels — annotation strings carry short
|
|
1191
|
+
rationales like "Inverse Head and Shoulders Confirmed"). Wire shape
|
|
1192
|
+
is stricter than before — payloads previously passing the permissive
|
|
1193
|
+
default arm now reject with `malformed-emission`.
|
|
1194
|
+
|
|
1195
|
+
`@invinite-org/chartlang-runtime` ships 5 new `draw.<kind>(...)` emit
|
|
1196
|
+
functions under `src/emit/draw/annotations/` and extends the
|
|
1197
|
+
`DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
|
|
1198
|
+
uses the dual-overload pattern Tasks 5–8 pinned. `draw.text` is the
|
|
1199
|
+
first emit fn with three script-facing arguments (`anchor`, `body`,
|
|
1200
|
+
`opts?`); the compiler-injected form is `(slotId, anchor, body,
|
|
1201
|
+
opts?)` and the impl signature carries four arguments.
|
|
1202
|
+
|
|
1203
|
+
`chartlang-example-canvas2d-adapter` ships 5 new renderers under
|
|
1204
|
+
`src/render/draw/` plus three new shared helpers: `arrowhead.ts`
|
|
1205
|
+
(`drawArrowhead(ctx, from, to, size?)` — filled triangular arrowhead
|
|
1206
|
+
at `to` pointing along the shaft direction; used by `arrow` +
|
|
1207
|
+
`arrowMarker`), `chevron.ts` (`drawChevron(ctx, at, direction, color,
|
|
1208
|
+
baseWidth?, height?)` — filled up/down triangle glyph; used by
|
|
1209
|
+
`arrowMarkUp` + `arrowMarkDown`), and `textStyle.ts` (`SIZE_TO_PX` /
|
|
1210
|
+
`HALIGN_TO_TEXTALIGN` / `VALIGN_TO_TEXTBASELINE` maps +
|
|
1211
|
+
`resolveTextOpts(opts)` helper that turns a `TextOpts` bag into the
|
|
1212
|
+
four canvas text-state values). The Task-7 `marker.ts` renderer is
|
|
1213
|
+
refactored to consume `textStyle.ts` for the same maps — its call
|
|
1214
|
+
sequence is preserved exactly so `marker.test.ts` continues to pass
|
|
1215
|
+
unchanged. Default colours follow invinite's paint-time defaults:
|
|
1216
|
+
`#3b82f6` (toolbar blue) for `arrowMarker`, `#22c55e` (green) for
|
|
1217
|
+
`arrowMarkUp`, `#ef4444` (red) for `arrowMarkDown`. The `drawingDispatch`
|
|
1218
|
+
switch flips the 5 arms from no-op stubs to real `renderXxx(ctx, e,
|
|
1219
|
+
view)` calls; exhaustiveness is preserved.
|
|
1220
|
+
|
|
1221
|
+
`@invinite-org/chartlang-conformance` ships 5 new per-kind scenarios
|
|
1222
|
+
under `src/scenarios/` (`drawText`, `drawArrow`, `drawArrowMarker`,
|
|
1223
|
+
`drawArrowMarkUp`, `drawArrowMarkDown`) plus one bundle scenario
|
|
1224
|
+
`drawAnnotationsAll` that emits one drawing per annotation kind on
|
|
1225
|
+
the first bar (per README §22.10 Task 9 collapses the category into
|
|
1226
|
+
ONE bundle). All six scenarios use `inlineSource` against the bundled
|
|
1227
|
+
10 000-bar `goldenBars.json` fixture with anchor times pulled from
|
|
1228
|
+
`bars[0]` / `bars[500]` / `bars[1000]`. The `TEST_CAPABILITIES` bags
|
|
1229
|
+
in `runConformanceSuite.test.ts` + `scenarios/scenarios.test.ts`
|
|
1230
|
+
extend the `drawings` set with `allAnnotationDrawings()`; the existing
|
|
1231
|
+
`labels: 100` bucket budget (added when Task 7's `marker` scenario
|
|
1232
|
+
landed) covers the bundle scenarios with headroom. `ALL_SCENARIOS`
|
|
1233
|
+
extends additively.
|
|
1234
|
+
|
|
1235
|
+
No core edits — the `DrawingState` variants and `DrawNamespace`
|
|
1236
|
+
signatures Task 1 shipped are the canonical shape and Task 9 wires
|
|
1237
|
+
real impls to them.
|
|
1238
|
+
|
|
1239
|
+
Deviations from spec, flagged for review:
|
|
1240
|
+
|
|
1241
|
+
- `text.bgColor` background-rectangle paint NOT rendered. The
|
|
1242
|
+
structural `RenderCtx` exposes neither `measureText` nor a
|
|
1243
|
+
background-rect path; widening would touch the Phase-1 structural
|
|
1244
|
+
type. The `bgColor` field is preserved on the wire (validator
|
|
1245
|
+
accepts string) but the canvas2d renderer does not paint a
|
|
1246
|
+
background rect. Mirror Task 7's `marker` precedent.
|
|
1247
|
+
- `ArrowOpts.label` rotation NOT rendered. `RenderCtx` has no
|
|
1248
|
+
`rotate / translate / save / restore`. Label paints un-rotated at
|
|
1249
|
+
the shaft midpoint with `textAlign = "center"` /
|
|
1250
|
+
`textBaseline = "bottom"`. Pure on the Phase-1 surface.
|
|
1251
|
+
- `ArrowMarkerState` ↔ spec shape delta. Task 1's core landed
|
|
1252
|
+
`ArrowMarkerState` with single `anchor: WorldPoint`; the spec
|
|
1253
|
+
README §13 says `2 (from, to)`. Per Tasks 6/7's "don't reshape
|
|
1254
|
+
Task-1 mid-phase" precedent, Task 9 uses the single-anchor form
|
|
1255
|
+
and the renderer paints a self-contained glyph (dot + stub line +
|
|
1256
|
+
arrowhead + optional text) at the anchor — a "annotation lives
|
|
1257
|
+
here" marker that fits in ~24px. Reshape can ship in a follow-up.
|
|
1258
|
+
- `marker.ts` refactor crosses Task 7 boundary by ~5 lines to
|
|
1259
|
+
consume the new shared `textStyle.ts` helper. The call sequence is
|
|
1260
|
+
preserved exactly; `marker.test.ts` continues to pass without
|
|
1261
|
+
modifications.
|
|
1262
|
+
- Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
|
|
1263
|
+
(mirrors Tasks 5–8) — Task 3's `pushDrawing.*` and `handle.*`
|
|
1264
|
+
suite covers the underlying infra exhaustively.
|
|
1265
|
+
- `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
|
|
1266
|
+
5–8).
|
|
1267
|
+
|
|
1268
|
+
- Phase 4 - Editor + Inputs + Timeframes + Tier-1 Pine parity.
|
|
1269
|
+
Adds: input._ builders, state._ / state.tick.\* slots,
|
|
1270
|
+
barstate / syminfo / timeframe views, request.security typed
|
|
1271
|
+
surface (NaN fallback), defineIndicator overrides,
|
|
1272
|
+
Capabilities triad (intervals / multiTimeframe / subPanes /
|
|
1273
|
+
symInfoFields / maxDrawingsPerScript / alertConditions / logs),
|
|
1274
|
+
language-service hover registry + LSP-style API, CodeMirror 6
|
|
1275
|
+
editor shell + /react sub-export, Inputs UI ViewModel + React
|
|
1276
|
+
form. See tasks/phase-4-editor-tier1/README.md.
|
|
1277
|
+
- Add Phase 4 capability builders for timeframes, panes, syminfo fields, drawing budgets, alert conditions, and logs.
|
|
1278
|
+
- Wire runtime `barstate`, `syminfo`, and `timeframe` views, and add optional adapter symbol metadata for `syminfo` population.
|
|
1279
|
+
- Resolve runtime `input.*` overrides at mount, add adapter input resolver wiring, and audit universal `ta.*` offset support.
|
|
1280
|
+
|
|
1281
|
+
### Patch Changes
|
|
1282
|
+
|
|
1283
|
+
- b0d296b: Phase-3 Task 1 — `draw.*` type surface foundation.
|
|
1284
|
+
|
|
1285
|
+
Adds the canonical Phase-3 type surface to `@invinite-org/chartlang-core`:
|
|
1286
|
+
|
|
1287
|
+
- `DrawingKind` — 61-entry kebab-case discriminated union (lines /
|
|
1288
|
+
boxes / curves / freehand / annotations / channels / fib / gann /
|
|
1289
|
+
pitchforks / patterns / elliott / cycles / containers). The
|
|
1290
|
+
kebab-case wire format is the source-of-truth; the camelCase
|
|
1291
|
+
TypeScript surface (`draw.horizontalLine`, `draw.fibRetracement`,
|
|
1292
|
+
…) is pinned via the `KIND_CAMELCASE` / `KIND_KEBABCASE` bijection.
|
|
1293
|
+
- `DRAWING_KINDS` — iterable form of `DrawingKind` in canonical
|
|
1294
|
+
declaration order.
|
|
1295
|
+
- `WorldPoint` + `AnchorPair` / `AnchorTriple` / `AnchorQuad` /
|
|
1296
|
+
`AnchorQuint` / `AnchorHept` helpers.
|
|
1297
|
+
- `DrawingState` — discriminated union with one variant per kind.
|
|
1298
|
+
Geometry + style fields only; collab-only fields (Yjs ids,
|
|
1299
|
+
layerIds, intervals, parentGroupId/FrameId, createdAt, authorId)
|
|
1300
|
+
from the invinite source are stripped per PLAN.md §10.4. Variants
|
|
1301
|
+
are minimal shells in this task; Tasks 5–18 refine per-category
|
|
1302
|
+
payloads.
|
|
1303
|
+
- Per-kind style bag types: `LineDrawStyle`, `ShapeStyle`,
|
|
1304
|
+
`HighlighterStyle`, `BrushStyle`, `TextOpts`, `ArrowOpts`,
|
|
1305
|
+
`ArrowMarkerOpts`, `PathOpts`, `FibOpts`, `RegressionTrendOpts`,
|
|
1306
|
+
`FrameOpts`.
|
|
1307
|
+
- `DrawingHandle` — script-facing handle returned by every
|
|
1308
|
+
`draw.<kind>(...)` call. Impl lives in the runtime (Task 3).
|
|
1309
|
+
- `DrawNamespace` + `FibSubNamespace` / `GannSubNamespace` /
|
|
1310
|
+
`ElliottSubNamespace` / `PatternSubNamespace` — the type the
|
|
1311
|
+
runtime swaps the throwing-stub `draw` Proxy for at boot. The
|
|
1312
|
+
stub mirrors the `plot` / `hline` / `alert` pattern from
|
|
1313
|
+
`plot/plot.ts`.
|
|
1314
|
+
- `DrawingBucket` + `KIND_BUCKET` + `bucketFor(kind)` — canonical
|
|
1315
|
+
kind → bucket map (`lines` / `labels` / `boxes` / `polylines` /
|
|
1316
|
+
`other`). Consumed by the runtime budget enforcer (Task 3) and
|
|
1317
|
+
by adapters that pre-budget.
|
|
1318
|
+
- `DrawingCounts` — moved here from `@invinite-org/chartlang-adapter-kit`
|
|
1319
|
+
so `ScriptManifest.maxDrawings?: DrawingCounts` and
|
|
1320
|
+
`Capabilities.maxDrawingsPerScript` pin the same shape without
|
|
1321
|
+
introducing a `core → adapter-kit` dependency cycle. The
|
|
1322
|
+
`adapter-kit` `DrawingCounts` export is now a type re-export of
|
|
1323
|
+
the core declaration — no public-surface drift, no consumer-visible
|
|
1324
|
+
change.
|
|
1325
|
+
- `ScriptManifest.maxDrawings?: DrawingCounts` + matching
|
|
1326
|
+
`DefineIndicatorOpts.maxDrawings?: DrawingCounts` propagation.
|
|
1327
|
+
|
|
1328
|
+
Extends `STATEFUL_PRIMITIVES` by 61 `draw.<camelKind>` entries (all
|
|
1329
|
+
`slot: true`). Cardinality grows from **93 → 154**. The new entries
|
|
1330
|
+
follow the canonical `DRAWING_KINDS` order. The compiler's
|
|
1331
|
+
`callsiteIdInjection` + `statefulCallInLoop` passes pick them up by
|
|
1332
|
+
name automatically.
|
|
1333
|
+
|
|
1334
|
+
No runtime behavior change in this task — `draw` is a throwing-stub
|
|
1335
|
+
Proxy until Task 3 wires the runtime emit infra. Phase-3 downstream
|
|
1336
|
+
tasks (2–22) all import from this surface.
|
|
1337
|
+
|
|
1338
|
+
- Updated dependencies [3f3ce38]
|
|
1339
|
+
- Updated dependencies [38fb475]
|
|
1340
|
+
- Updated dependencies [38fb475]
|
|
1341
|
+
- Updated dependencies [38fb475]
|
|
1342
|
+
- Updated dependencies [38fb475]
|
|
1343
|
+
- Updated dependencies [38fb475]
|
|
1344
|
+
- Updated dependencies [38fb475]
|
|
1345
|
+
- Updated dependencies [38fb475]
|
|
1346
|
+
- Updated dependencies [38fb475]
|
|
1347
|
+
- Updated dependencies [38fb475]
|
|
1348
|
+
- Updated dependencies [38fb475]
|
|
1349
|
+
- Updated dependencies [38fb475]
|
|
1350
|
+
- Updated dependencies [38fb475]
|
|
1351
|
+
- Updated dependencies [38fb475]
|
|
1352
|
+
- Updated dependencies [38fb475]
|
|
1353
|
+
- Updated dependencies [38fb475]
|
|
1354
|
+
- Updated dependencies [38fb475]
|
|
1355
|
+
- Updated dependencies [38fb475]
|
|
1356
|
+
- Updated dependencies [38fb475]
|
|
1357
|
+
- Updated dependencies [38fb475]
|
|
1358
|
+
- Updated dependencies [38fb475]
|
|
1359
|
+
- Updated dependencies [38fb475]
|
|
1360
|
+
- Updated dependencies [38fb475]
|
|
1361
|
+
- Updated dependencies [38fb475]
|
|
1362
|
+
- Updated dependencies [38fb475]
|
|
1363
|
+
- Updated dependencies [38fb475]
|
|
1364
|
+
- Updated dependencies [38fb475]
|
|
1365
|
+
- Updated dependencies [38fb475]
|
|
1366
|
+
- Updated dependencies [38fb475]
|
|
1367
|
+
- Updated dependencies [b0d296b]
|
|
1368
|
+
- Updated dependencies [b0d296b]
|
|
1369
|
+
- Updated dependencies [b0d296b]
|
|
1370
|
+
- Updated dependencies [b0d296b]
|
|
1371
|
+
- Updated dependencies [b0d296b]
|
|
1372
|
+
- Updated dependencies
|
|
1373
|
+
- Updated dependencies
|
|
1374
|
+
- Updated dependencies
|
|
1375
|
+
- Updated dependencies
|
|
1376
|
+
- Updated dependencies
|
|
1377
|
+
- Updated dependencies
|
|
1378
|
+
- Updated dependencies
|
|
1379
|
+
- Updated dependencies
|
|
1380
|
+
- @invinite-org/chartlang-core@0.4.0
|