pond-ts 0.46.0 → 0.48.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 +130 -3
  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.46.0...HEAD
11
+ [Unreleased]: https://github.com/pond-ts/pond/compare/v0.48.0...HEAD
12
+ [0.48.0]: https://github.com/pond-ts/pond/compare/v0.47.0...v0.48.0
13
+ [0.47.0]: https://github.com/pond-ts/pond/compare/v0.46.0...v0.47.0
12
14
  [0.46.0]: https://github.com/pjm17971/pond-ts/compare/v0.45.0...v0.46.0
13
15
  [0.45.0]: https://github.com/pjm17971/pond-ts/compare/v0.44.1...v0.45.0
14
16
  [0.44.1]: https://github.com/pjm17971/pond-ts/compare/v0.44.0...v0.44.1
@@ -45,13 +47,138 @@ and type-level changes; patch bumps are strictly additive.
45
47
 
46
48
  ## [Unreleased]
47
49
 
50
+ ## [0.48.0] — 2026-07-17
51
+
52
+ ### Added
53
+
54
+ - **charts:** `<ChartContainer>` gains **`cursorFormat`** — an independent
55
+ format for the **cursor / marker readout** (the crosshair time pill, marker
56
+ axis indicators, annotation auto-labels), separate from the tick-label
57
+ `timeFormat` / `format`. Unlike `timeFormat` (which _owns the labels_ and so
58
+ opts the axis out of the `dateStyle` ladder by design), `cursorFormat` shapes
59
+ only the readout and **keeps the flat / stacked date style** — resolving the
60
+ "one knob, two concerns" bind where the only way to fix the pill was to give
61
+ up the styled axis. A d3 specifier **string** formats uniformly; a
62
+ **function** `(epochMs, { grain, defaultText }) => string` is handed the
63
+ axis's resolved coarse **`TimeGrain`** (`year` … `second`) and the
64
+ grain-aware default text, so it can branch on zoom and pass the default
65
+ through — no re-deriving the grain from the range. New public types
66
+ **`CursorFormat`** / **`TimeGrain`**; `TradingTimeScale` gains
67
+ `readoutFormat(count)` and `grain(count)`.
68
+
69
+ ### Fixed
70
+
71
+ - **charts:** the cursor / marker time readout now formats at the axis's
72
+ **own grain** by default instead of d3's multi-scale default — a
73
+ day-or-coarser axis reads a **date** (`Sep 14, 2026`), a sub-day axis reads
74
+ date + clock. Fixes the 0.47.0 flat-axis regression where a daily bar at a
75
+ foreign-timezone midnight rendered as a bare time-of-day (`02 AM`) in the
76
+ crosshair pill (Tidal F-charts-7). Tick labels are unchanged.
77
+
78
+ ## [0.47.0] — 2026-07-17
79
+
80
+ ### Added
81
+
82
+ - **charts:** `<ChartContainer>` gains **`grid`** (default `true`) and
83
+ **`sessionDividers`** (`'labeled' | 'all' | 'none'`, default `'none'`).
84
+ On a calendar (time) axis the vertical gridlines are the **full grain
85
+ populations** — every day / month / aligned clock instant in view, not just
86
+ the thinned instants the labels chose (the labels decorate the grid; they
87
+ don't define it). Each grain fades as a unit by its **calendar density**
88
+ (nominal gap-free spacing: full ≥ 15 px, gone ≤ 5 px, quadratic), so
89
+ zooming out dissolves the fine grain into the coarser one — a map-style
90
+ hierarchical grid with no pop when the label algorithm switches rung — and
91
+ collapsing weekends draws _fewer_ day lines at the _same_ strength, not
92
+ wider-spaced lines that jump to full opacity. Session dividers are opt-in
93
+ emphasis over that grid, and draw only at true collapse **seams** —
94
+ boundaries that removed time actually precedes, not every session roll
95
+ (`'all'` = every seam, the TradingView separator look, crowding lines
96
+ fading out; `'labeled'` = only seams the axis also labels) — so a
97
+ `grid={false}` plot is actually clean by default and a contiguous-sessions
98
+ calendar seams only where days were excised. `TradingTimeScale` gains
99
+ **`gridLevels(minGapPx)`** (the nested per-grain populations + nominal
100
+ spacing behind it). In `'all'` mode, crowding session-divider lines fade on
101
+ a quadratic ramp (full ≥ 28 px apart, gone ≤ 6 px) so zooming out dissolves
102
+ them to a clean plot rather than a permanent gray wash.
103
+ - **charts:** `<TimeAxis>` / `<XAxis>` gain a **`dateStyle`** prop
104
+ (`'flat' | 'stacked'`). `'flat'` — the new default — lays the date context
105
+ out on a **single row** the TradingView way: each tick that opens a coarser
106
+ calendar period is relabelled **inline** to it (the month at a month turn,
107
+ the year at a year turn, the date at a day turn under an intraday grain),
108
+ every other tick a terse label (`5`, `Feb`, `14:00`). `'stacked'` is the
109
+ two-row layout: a terse top row (the grain's bare unit) over a segmented
110
+ **band** row of the next-coarser period — **day** bands under intraday
111
+ ticks, **month** bands under day ticks, **year** bands under month/quarter
112
+ ticks — each a left-aligned label with a divider at its turn, **zebra-shaded**
113
+ by the band's calendar parity (pan/zoom-stable). The turn tick up top is
114
+ emphasized and joins its divider as one continuous boundary line; the partial
115
+ left band pins its label at the plot edge. Themeable via **`theme.axis.band`**
116
+ (`fill` — the shaded cell, "could be a background color"; `divider`; `label`).
117
+ `TradingTimeScale` gains `flatFormat(count)` (the flat single-row lookup),
118
+ `baseFormat(count)` (the terse stacked top row), and `bands(count)` (the band
119
+ segments); non-tick instants — the cursor readout — still read a full
120
+ timestamp.
121
+ The **window edge is never ticked** unless it is a genuine grain anchor (a
122
+ true session open, or an instant exactly on the grain — a midnight at day
123
+ grain, a month start at month grain): a mid-period edge tick sat pinned at
124
+ x=0 relabelling itself as the window panned (a sticky `8` at half-spacing, a
125
+ `15:23` under an hour grain) — misleading, and not something TradingView
126
+ draws. The first real calendar anchor now leads the axis.
127
+
128
+ ### Changed
129
+
130
+ - **Docs hosting.** The documentation site has moved from GitHub Pages
131
+ (`pjm17971.github.io/pond-ts`) to Cloudflare Pages under the custom domain
132
+ **<https://pond-ts.org>**. Storybook now deploys as its own project served at
133
+ `pond-ts.org/storybook/` (via a small routing Worker, `workers/router/`),
134
+ rather than nested into the docs build. Doc links in the README are repointed;
135
+ the deploy workflow keeps the same `v*`-tag gate. See `MIGRATION.md`.
136
+ - **charts:** the time axis now renders the **flat** single-row date style by
137
+ default (previously the two-row stacked layout). Every time chart — trading
138
+ or plain continuous, auto-rendered or explicit `<TimeAxis>` — picks this up.
139
+ Pass `dateStyle="stacked"` to keep the old two-row look. (An explicit
140
+ `format` / container `timeFormat`, a `transform`, or explicit `ticks` opt out
141
+ of both styles as before.)
142
+ - **charts:** the time-axis tick ladder's sub-month density now thins each
143
+ month in **session-index space** — the reverse-engineered TradingView
144
+ algorithm, validated label-for-label against its output on the 2026 NYSE
145
+ calendar. Marks sit an equal number of _bars_ apart, so on a collapsed
146
+ trading axis they are **evenly spaced in pixels**, with no weekend snapping:
147
+ a month opening on a weekend anchors on its first session. Two regimes per
148
+ month: at dense zooms, a **uniform anchored stride** (the month's first
149
+ session, then every k-th, truncated so the gap to the next month label
150
+ stays ≥ the stride — the slack lands at the month end); at coarse zooms
151
+ (≤ 3 marks per month, where a truncated stride would leave a hole of up to
152
+ ~2 strides before the month label and each ±1 stride change would crawl the
153
+ labels), a **balanced division** — mid-month, then thirds — whose marks
154
+ hold still across every zoom that maps to the same density. Month / year
155
+ starts stay pinned at every zoom; pans never reshuffle marks (indices are
156
+ queried per full calendar month, never per window); a stub live-edge month
157
+ earns proportionally fewer marks. Without a calendar provider the same
158
+ scheme runs in day-of-month space. Replaces the old day → weekly ~7×
159
+ density cliff; the separate Monday-anchored week grain was removed — the
160
+ session-stride band covers everything between every-session and month
161
+ grain.
162
+
163
+ ### Fixed
164
+
165
+ - **charts:** a multi-session time axis near the tick cap can no longer come
166
+ back lopsided — with several sessions each gaining a phase tick while the
167
+ span estimate sat within a few ticks of the cap, clock-rung enumeration hit
168
+ its internal bail and the truncated tick array was returned, leaving the
169
+ final sessions with no ticks at all. The enumeration budget now covers the
170
+ estimate's per-session undercount (`cap + opens.length + slack`) so
171
+ enumeration completes, and a still-truncated result is rejected in favor of
172
+ a coarser rung instead of being returned. (Follow-up to the v0.46.0
173
+ sliding-window grain-stability fix, flagged in its release spot-check.)
174
+
48
175
  ## [0.46.0] — 2026-07-14
49
176
 
50
177
  ### Changed
51
178
 
52
179
  - **charts:** the boundary (second-row) axis label's **context** now pins to
53
180
  the plot's left edge instead of riding the first tick: it shows the period
54
- the *domain start* is in, and a crossing label sliding toward the edge
181
+ the _domain start_ is in, and a crossing label sliding toward the edge
55
182
  pushes it off (the sticky-header behavior). On a live sliding window the
56
183
  old first-tick anchoring made `Jan 01` hop tick-to-tick as ticks scrolled
57
184
  out; pinned, it stays put until the period actually changes. Crossing
@@ -141,7 +268,7 @@ and type-level changes; patch bumps are strictly additive.
141
268
  values while **keeping the row count** — mirroring `rolling`'s `minSamples`,
142
269
  the one warm-up convention studies use so a smoothed line aligns on its
143
270
  source's time axis. (The existing `warmup` option is unchanged — it still
144
- *drops* the head rows; `minSamples` is the length-preserving counterpart.)
271
+ _drops_ the head rows; `minSamples` is the length-preserving counterpart.)
145
272
  - **core:** `TimeSeries.rolling` accepts a **count-based** window —
146
273
  `rolling({ count: N }, mapping, opts?)` reduces the last / next / centered
147
274
  `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.46.0",
3
+ "version": "0.48.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",