pond-ts 0.45.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +149 -2
  2. package/README.md +7 -7
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -8,7 +8,9 @@ The `@pond-ts` packages — `pond-ts`, `@pond-ts/react`, `@pond-ts/charts`,
8
8
  tag, so this file covers them all. Pre-1.0: minor bumps may include new features
9
9
  and type-level changes; patch bumps are strictly additive.
10
10
 
11
- [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.45.0...HEAD
11
+ [Unreleased]: https://github.com/pond-ts/pond/compare/v0.47.0...HEAD
12
+ [0.47.0]: https://github.com/pond-ts/pond/compare/v0.46.0...v0.47.0
13
+ [0.46.0]: https://github.com/pjm17971/pond-ts/compare/v0.45.0...v0.46.0
12
14
  [0.45.0]: https://github.com/pjm17971/pond-ts/compare/v0.44.1...v0.45.0
13
15
  [0.44.1]: https://github.com/pjm17971/pond-ts/compare/v0.44.0...v0.44.1
14
16
  [0.44.0]: https://github.com/pjm17971/pond-ts/compare/v0.43.0...v0.44.0
@@ -44,6 +46,151 @@ and type-level changes; patch bumps are strictly additive.
44
46
 
45
47
  ## [Unreleased]
46
48
 
49
+ ## [0.47.0] — 2026-07-17
50
+
51
+ ### Added
52
+
53
+ - **charts:** `<ChartContainer>` gains **`grid`** (default `true`) and
54
+ **`sessionDividers`** (`'labeled' | 'all' | 'none'`, default `'none'`).
55
+ On a calendar (time) axis the vertical gridlines are the **full grain
56
+ populations** — every day / month / aligned clock instant in view, not just
57
+ the thinned instants the labels chose (the labels decorate the grid; they
58
+ don't define it). Each grain fades as a unit by its **calendar density**
59
+ (nominal gap-free spacing: full ≥ 15 px, gone ≤ 5 px, quadratic), so
60
+ zooming out dissolves the fine grain into the coarser one — a map-style
61
+ hierarchical grid with no pop when the label algorithm switches rung — and
62
+ collapsing weekends draws _fewer_ day lines at the _same_ strength, not
63
+ wider-spaced lines that jump to full opacity. Session dividers are opt-in
64
+ emphasis over that grid, and draw only at true collapse **seams** —
65
+ boundaries that removed time actually precedes, not every session roll
66
+ (`'all'` = every seam, the TradingView separator look, crowding lines
67
+ fading out; `'labeled'` = only seams the axis also labels) — so a
68
+ `grid={false}` plot is actually clean by default and a contiguous-sessions
69
+ calendar seams only where days were excised. `TradingTimeScale` gains
70
+ **`gridLevels(minGapPx)`** (the nested per-grain populations + nominal
71
+ spacing behind it). In `'all'` mode, crowding session-divider lines fade on
72
+ a quadratic ramp (full ≥ 28 px apart, gone ≤ 6 px) so zooming out dissolves
73
+ them to a clean plot rather than a permanent gray wash.
74
+ - **charts:** `<TimeAxis>` / `<XAxis>` gain a **`dateStyle`** prop
75
+ (`'flat' | 'stacked'`). `'flat'` — the new default — lays the date context
76
+ out on a **single row** the TradingView way: each tick that opens a coarser
77
+ calendar period is relabelled **inline** to it (the month at a month turn,
78
+ the year at a year turn, the date at a day turn under an intraday grain),
79
+ every other tick a terse label (`5`, `Feb`, `14:00`). `'stacked'` is the
80
+ two-row layout: a terse top row (the grain's bare unit) over a segmented
81
+ **band** row of the next-coarser period — **day** bands under intraday
82
+ ticks, **month** bands under day ticks, **year** bands under month/quarter
83
+ ticks — each a left-aligned label with a divider at its turn, **zebra-shaded**
84
+ by the band's calendar parity (pan/zoom-stable). The turn tick up top is
85
+ emphasized and joins its divider as one continuous boundary line; the partial
86
+ left band pins its label at the plot edge. Themeable via **`theme.axis.band`**
87
+ (`fill` — the shaded cell, "could be a background color"; `divider`; `label`).
88
+ `TradingTimeScale` gains `flatFormat(count)` (the flat single-row lookup),
89
+ `baseFormat(count)` (the terse stacked top row), and `bands(count)` (the band
90
+ segments); non-tick instants — the cursor readout — still read a full
91
+ timestamp.
92
+ The **window edge is never ticked** unless it is a genuine grain anchor (a
93
+ true session open, or an instant exactly on the grain — a midnight at day
94
+ grain, a month start at month grain): a mid-period edge tick sat pinned at
95
+ x=0 relabelling itself as the window panned (a sticky `8` at half-spacing, a
96
+ `15:23` under an hour grain) — misleading, and not something TradingView
97
+ draws. The first real calendar anchor now leads the axis.
98
+
99
+ ### Changed
100
+
101
+ - **Docs hosting.** The documentation site has moved from GitHub Pages
102
+ (`pjm17971.github.io/pond-ts`) to Cloudflare Pages under the custom domain
103
+ **<https://pond-ts.org>**. Storybook now deploys as its own project served at
104
+ `pond-ts.org/storybook/` (via a small routing Worker, `workers/router/`),
105
+ rather than nested into the docs build. Doc links in the README are repointed;
106
+ the deploy workflow keeps the same `v*`-tag gate. See `MIGRATION.md`.
107
+ - **charts:** the time axis now renders the **flat** single-row date style by
108
+ default (previously the two-row stacked layout). Every time chart — trading
109
+ or plain continuous, auto-rendered or explicit `<TimeAxis>` — picks this up.
110
+ Pass `dateStyle="stacked"` to keep the old two-row look. (An explicit
111
+ `format` / container `timeFormat`, a `transform`, or explicit `ticks` opt out
112
+ of both styles as before.)
113
+ - **charts:** the time-axis tick ladder's sub-month density now thins each
114
+ month in **session-index space** — the reverse-engineered TradingView
115
+ algorithm, validated label-for-label against its output on the 2026 NYSE
116
+ calendar. Marks sit an equal number of _bars_ apart, so on a collapsed
117
+ trading axis they are **evenly spaced in pixels**, with no weekend snapping:
118
+ a month opening on a weekend anchors on its first session. Two regimes per
119
+ month: at dense zooms, a **uniform anchored stride** (the month's first
120
+ session, then every k-th, truncated so the gap to the next month label
121
+ stays ≥ the stride — the slack lands at the month end); at coarse zooms
122
+ (≤ 3 marks per month, where a truncated stride would leave a hole of up to
123
+ ~2 strides before the month label and each ±1 stride change would crawl the
124
+ labels), a **balanced division** — mid-month, then thirds — whose marks
125
+ hold still across every zoom that maps to the same density. Month / year
126
+ starts stay pinned at every zoom; pans never reshuffle marks (indices are
127
+ queried per full calendar month, never per window); a stub live-edge month
128
+ earns proportionally fewer marks. Without a calendar provider the same
129
+ scheme runs in day-of-month space. Replaces the old day → weekly ~7×
130
+ density cliff; the separate Monday-anchored week grain was removed — the
131
+ session-stride band covers everything between every-session and month
132
+ grain.
133
+
134
+ ### Fixed
135
+
136
+ - **charts:** a multi-session time axis near the tick cap can no longer come
137
+ back lopsided — with several sessions each gaining a phase tick while the
138
+ span estimate sat within a few ticks of the cap, clock-rung enumeration hit
139
+ its internal bail and the truncated tick array was returned, leaving the
140
+ final sessions with no ticks at all. The enumeration budget now covers the
141
+ estimate's per-session undercount (`cap + opens.length + slack`) so
142
+ enumeration completes, and a still-truncated result is rejected in favor of
143
+ a coarser rung instead of being returned. (Follow-up to the v0.46.0
144
+ sliding-window grain-stability fix, flagged in its release spot-check.)
145
+
146
+ ## [0.46.0] — 2026-07-14
147
+
148
+ ### Changed
149
+
150
+ - **charts:** the boundary (second-row) axis label's **context** now pins to
151
+ the plot's left edge instead of riding the first tick: it shows the period
152
+ the _domain start_ is in, and a crossing label sliding toward the edge
153
+ pushes it off (the sticky-header behavior). On a live sliding window the
154
+ old first-tick anchoring made `Jan 01` hop tick-to-tick as ticks scrolled
155
+ out; pinned, it stays put until the period actually changes. Crossing
156
+ labels (day/year turns) still ride their ticks — including a first tick
157
+ whose period differs from the domain start's. `TradingTimeScale` gains
158
+ `boundaryContext(count)`; `tickBoundaries` now labels crossings only.
159
+
160
+ ### Fixed
161
+
162
+ - **charts:** a live (sliding-window) time axis no longer flickers between two
163
+ tick grains: the clock-rung choice now derives from the window's live span
164
+ (constant while sliding) instead of the enumerated anchor count, which
165
+ oscillates ±1 with the window's phase and flipped the grain for single
166
+ frames whenever it sat exactly at the width-derived cap.
167
+
168
+ ### Added
169
+
170
+ - **charts:** **dual x-axes** — two tick layouts on one shared scale. A second
171
+ `<XAxis>` stacks by declaration order (above/below the plot, either side,
172
+ same side twice); the new **`transform`** prop (`{ to, from }`, exported
173
+ `AxisTransform`) relabels an axis into a derived unit: strike ↔ moneyness on
174
+ a top axis, or a nonlinear BS-delta strip under a std-moneyness chart. Ticks
175
+ are nice derived-unit values chosen by a pixel-aware multi-resolution fill
176
+ (1-2-5 steps, coarsest first, admitted where they keep room), so a span the
177
+ transform compresses gets coarse ticks and a stretched span picks up finer
178
+ ones — and a label-honesty filter drops any tick whose formatted label would
179
+ lie about its position. Gridlines stay on the container's primary ticks; the
180
+ cursor pill on a transformed axis reads in the derived unit. Stories under
181
+ `Charts/Axes/DualX`. Each `<XAxis>` **and `<YAxis>`** also takes a
182
+ per-instance **`color`** (labels, tick marks, rule, title) — the lever that
183
+ distinguishes stacked x strips (a blue delta strip under a grey primary) and
184
+ colours a y axis to match its series (the dual-axis convention).
185
+
186
+ ### Fixed
187
+
188
+ - **charts:** annotation label chips now clip to the plot: a marker whose pole
189
+ pans off-plot no longer leaves its chip floating in the axis gutter, and a
190
+ partially visible region's chip clamps to the plot's left edge (culled only
191
+ when the region is entirely out of view). The lines/fills were already
192
+ SVG-clipped — only the DOM chips escaped.
193
+
47
194
  ## [0.45.0] — 2026-07-14
48
195
 
49
196
  ### Added
@@ -92,7 +239,7 @@ and type-level changes; patch bumps are strictly additive.
92
239
  values while **keeping the row count** — mirroring `rolling`'s `minSamples`,
93
240
  the one warm-up convention studies use so a smoothed line aligns on its
94
241
  source's time axis. (The existing `warmup` option is unchanged — it still
95
- *drops* the head rows; `minSamples` is the length-preserving counterpart.)
242
+ _drops_ the head rows; `minSamples` is the length-preserving counterpart.)
96
243
  - **core:** `TimeSeries.rolling` accepts a **count-based** window —
97
244
  `rolling({ count: N }, mapping, opts?)` reduces the last / next / centered
98
245
  `N` _rows_ (bars) by position instead of a time span. Unlike a duration
package/README.md CHANGED
@@ -180,21 +180,21 @@ npm run build && node packages/core/bench/vs-pondjs.cjs
180
180
 
181
181
  ## Documentation
182
182
 
183
- The full guide is at **<https://pjm17971.github.io/pond-ts/>**.
183
+ The full guide is at **<https://pond-ts.org/>**.
184
184
 
185
- - **[Start here](https://pjm17971.github.io/pond-ts/docs/)**
185
+ - **[Start here](https://pond-ts.org/docs/)**
186
186
  — five-minute walkthrough with batch, live, and React examples.
187
- - **[Concepts](https://pjm17971.github.io/pond-ts/docs/start-here/concepts)**
187
+ - **[Concepts](https://pond-ts.org/docs/start-here/concepts)**
188
188
  — temporal keys, sequences, windowing, partitioning, triggers, late
189
189
  data.
190
- - **[Transforms reference](https://pjm17971.github.io/pond-ts/docs/pond-ts/transforms/queries)**
190
+ - **[Transforms reference](https://pond-ts.org/docs/pond-ts/transforms/queries)**
191
191
  — every batch operator (queries, aggregation, alignment, rolling,
192
192
  smoothing, sampling, cleaning, reshape, anomaly detection).
193
- - **[Live reference](https://pjm17971.github.io/pond-ts/docs/pond-ts/live/live-series)**
193
+ - **[Live reference](https://pond-ts.org/docs/pond-ts/live/live-series)**
194
194
  — `LiveSeries`, live transforms, triggering.
195
- - **[How-to guides](https://pjm17971.github.io/pond-ts/docs/how-to-guides)**
195
+ - **[How-to guides](https://pond-ts.org/docs/how-to-guides)**
196
196
  — building a dashboard, ingesting messy data.
197
- - **[API reference (auto-generated)](https://pjm17971.github.io/pond-ts/generated-api/core/)**
197
+ - **[API reference (auto-generated)](https://pond-ts.org/generated-api/core/)**
198
198
  — TypeDoc output, every public class and method.
199
199
  - **[CHANGELOG](./CHANGELOG.md)** — what shipped in each release.
200
200
 
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "pond-ts",
3
- "version": "0.45.0",
3
+ "version": "0.47.0",
4
4
  "description": "TypeScript-first time series primitives",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/pjm17971/pond-ts.git",
8
+ "url": "git+https://github.com/pond-ts/pond.git",
9
9
  "directory": "packages/core"
10
10
  },
11
11
  "type": "module",