pond-ts 0.52.0 → 0.53.1

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 (2) hide show
  1. package/CHANGELOG.md +123 -1
  2. package/package.json +1 -1
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/pond-ts/pond/compare/v0.52.0...HEAD
11
+ [Unreleased]: https://github.com/pond-ts/pond/compare/v0.53.1...HEAD
12
+ [0.53.1]: https://github.com/pond-ts/pond/compare/v0.53.0...v0.53.1
13
+ [0.53.0]: https://github.com/pond-ts/pond/compare/v0.52.0...v0.53.0
12
14
  [0.52.0]: https://github.com/pond-ts/pond/compare/v0.51.0...v0.52.0
13
15
  [0.51.0]: https://github.com/pond-ts/pond/compare/v0.50.0...v0.51.0
14
16
  [0.50.0]: https://github.com/pond-ts/pond/compare/v0.49.0...v0.50.0
@@ -52,6 +54,126 @@ and type-level changes; patch bumps are strictly additive.
52
54
 
53
55
  ## [Unreleased]
54
56
 
57
+ ## [0.53.1] — 2026-07-25
58
+
59
+ ### Fixed
60
+
61
+ - **charts:** **An `<XAxis format>` again owns its own cursor / marker pills**
62
+ under a container with `origin` set. The elapsed axis supplies a _default_
63
+ finer readout (`00:05:12` under `00:05` ticks), but it was being delivered
64
+ through the same frame field as an explicit `cursorFormat` — so it outranked
65
+ an axis-level `format`, inverting the documented pill precedence
66
+ (`cursorFormat → axis format → container`). The visible symptom was the
67
+ two-strip pattern the docs recommend: a wall-clock strip declared as
68
+ `<XAxis format="%H:%M">` labelled its ticks `11:33` and pilled them
69
+ `00:05:12`. A real `cursorFormat` still outranks an axis `format`, unchanged.
70
+ A container **`timeFormat`** was inverted the same way one rung down — its
71
+ documented back-compat is to shape the readout when no `cursorFormat` is set,
72
+ and the elapsed default was overruling it. Fixed with the same precedence.
73
+
74
+ - **charts:** **A duration axis no longer stacks ticks on one pixel across a
75
+ collapsed session.** The duration ladder strides in wall-clock time, so on a
76
+ trading axis several ticks could land inside closed time — where the scale
77
+ maps all of them to the same seam pixel, stroking labels over labels and
78
+ gridlines over gridlines. Coinciding ticks are now dropped, so a seam shows
79
+ one label rather than four — and the one kept is the **last** of the group,
80
+ the session open that genuinely sits on that pixel (`1d 00:00`), rather than
81
+ the first, which falls inside the collapsed night (`12:00` = 21:30, market
82
+ shut). Continuous axes are unaffected (their ticks are tens of pixels apart
83
+ by construction).
84
+
85
+ Both found by an adversarial review of the v0.53.0 duration axis
86
+ ([#540](https://github.com/pond-ts/pond/issues/540)), which also corrected the
87
+ duration-axis docs: the trading-calendar caveat described uneven spacing where
88
+ the real behaviour is thinning around seams, a far-off `origin` (`origin={0}`
89
+ on a 2026 axis ⇒ `20468d 10:00` on every tick) was undocumented, and one row of
90
+ the label-shape table quoted a sample spacing where it meant a tick step.
91
+
92
+ ## [0.53.0] — 2026-07-25
93
+
94
+ ### Changed
95
+
96
+ - **fit (breaking):** **Power bins and zones now use pond's canonical bin
97
+ edges**, so they feed `@pond-ts/charts` with no mapping step:
98
+
99
+ ```tsx
100
+ <BarChart bins={power.distribution} column="seconds" />
101
+ <BarChart bins={power.zones} column="seconds" orientation="horizontal" ordinal />
102
+ ```
103
+
104
+ Each type previously spoke its own dialect for the same concept —
105
+ `PowerBin.wattsFrom` (with **no upper edge at all**), `ZoneTime.lo`/`hi`, and
106
+ `PowerZone.minWatts`/`maxWatts` — while core's `byColumn` and charts' `BinRecord`
107
+ both use `{ start, end, …aggregates }`. Every caller had to hand-map before
108
+ drawing, even though the internals already computed the canonical shape and
109
+ discarded it.
110
+
111
+ **Migration** (pre-1.0, so the old names are gone rather than deprecated):
112
+
113
+ | Was | Now |
114
+ | --------------------- | -------------------------------------- |
115
+ | `PowerBin.wattsFrom` | `PowerBin.start` (+ new `end`) |
116
+ | `ZoneTime.lo` / `.hi` | `ZoneTime.start` / `.end`, `openEnded` |
117
+ | `PowerZone.minWatts` | `PowerZone.start` |
118
+ | `PowerZone.maxWatts` | `PowerZone.end`, `openEnded` |
119
+
120
+ Only **`PowerZone.maxWatts`** — a zone's upper edge — is affected. The
121
+ identically-named `PowerSummary.maxWatts` and the per-lap / per-section peak
122
+ power are a different concept and are unchanged.
123
+
124
+ `end` is now **always finite and always `> start`** — the guarantee core
125
+ enforces (`byColumn` throws on a zero-width bin) and charts need (an infinite
126
+ edge blows up an axis domain). The open-ended top band, which previously
127
+ carried only `Infinity`, gets a **drawable stand-in** edge: wide enough to
128
+ cover the highest value observed, and at least as wide as the band below it.
129
+ Treat it as a drawing bound rather than data, and test for the band with the
130
+ new **`openEnded`** flag rather than comparing an edge against `Infinity`
131
+ (`openEnded` is now also strictly positional — only the final band can carry
132
+ it). Rounding zone edges to whole watts no longer collapses bands at very low
133
+ FTPs.
134
+
135
+ ### Added
136
+
137
+ - **charts:** **Duration (elapsed) x axis** — `<ChartContainer origin>` labels
138
+ the shared x axis as offsets from a zero point instead of absolute values, so
139
+ a workout / lab run / load test reads `00:00 00:05 00:10` rather than
140
+ `10:35 10:40 10:45`:
141
+
142
+ ```tsx
143
+ <ChartContainer width={620} origin="data">
144
+
145
+ <XAxis label="Elapsed" />
146
+ </ChartContainer>
147
+ ```
148
+
149
+ `'data'` zeroes at the start of the data (and stays there as you pan); a
150
+ **number** sets an explicit zero point — a gun, a trigger, a lap — with ticks
151
+ before it reading negative (`-00:05`). Ticks are placed at round durations
152
+ **measured from the origin** (a ride starting at 10:33:17 ticks 10:33:17,
153
+ 10:38:17, …), off a clock ladder (…15s, 30s, 1m, 2m, 5m, …, 12h, then whole
154
+ days) rather than the 1-2-5 ladder — the part a formatter alone can't do.
155
+ Labels pick their shape from the step and the axis's magnitude
156
+ (`00:00.500` · `00:15` · `01:01:30` · `1d 12:00` · `5d`), gridlines follow the
157
+ same ticks, and the cursor / marker pills read one grain finer (`00:05:12`).
158
+
159
+ It's a **labelling** mode, not a data transform: `range`, `<Marker at>`,
160
+ `onRegionSelect`, `trackerPosition` all stay in absolute axis units. The same
161
+ prop works on a **value** x axis (distance travelled, not distance recorded).
162
+ An explicit format still wins — on a time axis a d3 _time_ specifier can only
163
+ describe an instant, so it labels the wall clock, which is the lever for
164
+ stacking a wall-clock strip under a duration strip on one shared tick set; on
165
+ a value axis a number specifier formats the offset. Ignored on a category
166
+ axis; on a trading calendar the durations are wall-clock, so ticks spanning a
167
+ collapsed session gap sit unevenly.
168
+
169
+ - **fit:** `computePower` takes an options object — **`{ binWatts }`** sets the
170
+ width of the `distribution` buckets (default `1`, unchanged). 1 W bins draw as
171
+ hairlines, so pass the width you intend to render rather than re-bucketing the
172
+ output yourself. It throws `RangeError` on a non-positive or non-finite
173
+ `binWatts`. New exported type `ComputePowerOptions`, also accepted by the
174
+ activity façade: `Activity.power(ftp, options)` and
175
+ `ProfiledActivity.power(options)`.
176
+
55
177
  ## [0.52.0] — 2026-07-23
56
178
 
57
179
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pond-ts",
3
- "version": "0.52.0",
3
+ "version": "0.53.1",
4
4
  "description": "TypeScript-first time series primitives",
5
5
  "license": "MIT",
6
6
  "repository": {