@pond-ts/react 0.12.1 → 0.13.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 (2) hide show
  1. package/CHANGELOG.md +118 -1
  2. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -7,10 +7,127 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
7
7
  file covers both packages. Pre-1.0: minor bumps may include new features and
8
8
  type-level changes; patch bumps are strictly additive.
9
9
 
10
- [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.12.1...HEAD
10
+ [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.13.0...HEAD
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.13.0] — 2026-05-01
15
+
16
+ The "AggregateOutputMap on live" release. Closes the feature-parity
17
+ gap between batch and live aggregation: the `{ alias: { from, using } }`
18
+ mapping shape that batch `TimeSeries.rolling`/`aggregate` already
19
+ accepted now works on `LiveSeries.rolling`, `LiveSeries.aggregate`,
20
+ and the synchronised partitioned form. Multiple stats from one
21
+ source column in a single rolling deque — no more "one rolling per
22
+ percentile" workaround.
23
+
24
+ The shared runtime helper (`normalizeAggregateColumns`) was already
25
+ doing the work for batch; this release extracts it to
26
+ `aggregate-columns.ts` and threads the type-level overloads through
27
+ the live surface.
28
+
29
+ ### Added
30
+
31
+ - **`AggregateOutputMap` on `LiveSeries.rolling` and
32
+ `LiveSeries.aggregate`.** Compose multiple built-in reducers from
33
+ one source column in a single pass:
34
+
35
+ ```ts
36
+ const band = live.rolling('1m', {
37
+ mean: { from: 'cpu', using: 'avg' },
38
+ sd: { from: 'cpu', using: 'stdev' },
39
+ });
40
+ band.value(); // { mean, sd } — single deque, one walk
41
+ ```
42
+
43
+ Threaded through `LiveView.rolling`/`aggregate`,
44
+ `LiveAggregation.rolling`, `LiveRollingAggregation.aggregate`,
45
+ `LivePartitionedSeries.rolling`, and `LivePartitionedView.rolling`
46
+ — so chained pipelines (`live.filter(...).rolling(...)`,
47
+ `live.partitionBy(c).fill(...).rolling(..., { trigger: ... })`)
48
+ accept either shape.
49
+
50
+ - **Synchronised partitioned rolling with `AggregateOutputMap`.**
51
+ `partitionBy(col).rolling(window, mapping, { trigger: Trigger.clock(seq) })`
52
+ now accepts the alias form. Output schema becomes
53
+ `[time, <partitionColumn>, ...aliasColumns]`. The collision check
54
+ rejects when an alias output collides with the partition column
55
+ name (compare against the alias, not the source column).
56
+
57
+ ### Changed
58
+
59
+ - **Better error message when a custom-function reducer is passed to
60
+ live aggregation.** `LiveAggregation` already failed at construction
61
+ via `resolveReducer(reducer)` (with a generic `unsupported aggregate
62
+ reducer` message); now the eager built-in-name check runs first and
63
+ emits a targeted error pointing at the `AggregateOutputMap` alias
64
+ workaround. Same eager behavior on `LivePartitionedSyncRolling`,
65
+ which previously failed lazily when the first partition spawned —
66
+ now fails at construction. Aligns with `LiveRollingAggregation`'s
67
+ long-standing eager check.
68
+
69
+ - **Shared `normalizeAggregateColumns` helper.** Extracted from
70
+ `TimeSeries.ts` into `aggregate-columns.ts` and used by all three
71
+ live accumulators (`LiveRollingAggregation`, `LiveAggregation`,
72
+ `LivePartitionedSyncRolling`). Single source of truth for column
73
+ normalisation; identical error messages across batch and live
74
+ (`unknown source column`).
75
+
76
+ ### Constraints
77
+
78
+ - **Custom-function reducers remain batch-only.** Live rolling and
79
+ live aggregation still require built-in reducer names (`'avg'`,
80
+ `'p95'`, etc.). Custom `(values) => ...` functions don't have the
81
+ incremental add/remove machinery the live path needs and are
82
+ rejected at construction with a clear error pointing at the
83
+ `AggregateOutputMap` workaround. This is the established
84
+ recommendation: alias multiple built-ins to compose stats from
85
+ one source column.
86
+
87
+ ### Fixed
88
+
89
+ - **`partitionBy(...).rolling(..., options)` now accepts `options` as
90
+ a variable typed `LiveRollingOptions`, not just inline literals.**
91
+ Pre-fix, the four narrowed overloads on
92
+ `LivePartitionedSeries.rolling` and `LivePartitionedView.rolling`
93
+ required TS to see the `trigger` field's discriminator at the call
94
+ site — so a caller writing
95
+ `const opts: LiveRollingOptions = { trigger: Trigger.event() };
96
+ partitioned.rolling(window, mapping, opts);` got `TS2769 No
97
+ overload matches this call`. Pre-existing hole on the partitioned
98
+ surface; surfaced by the v0.13.0 Codex adversarial pass. Closed by
99
+ adding catch-all overloads that accept the broader
100
+ `LiveRollingOptions` and return the union of both trigger
101
+ branches; the four narrowed overloads above still match inline
102
+ literals first, so callers keep the precise return type when they
103
+ pass the trigger inline. Pinned with `test-d/types.test-d.ts`
104
+ coverage using both inline-literal and variable forms.
105
+
106
+ ### Tests
107
+
108
+ - 16 new tests in `test/LiveAggregateOutputMap.test.ts` covering:
109
+ flat live rolling/aggregate with the alias form, chained-view
110
+ rolling/aggregate, `LiveAggregation.rolling` and
111
+ `LiveRollingAggregation.aggregate` chainable accumulators,
112
+ per-partition rolling, synchronised partitioned rolling with
113
+ alias outputs, output-vs-source column-collision rejection on
114
+ the synced form, and explicit kind override.
115
+ - 2 existing tests updated (`LiveAggregation` and
116
+ `LiveRollingAggregation` "unknown column" → "unknown source column"
117
+ to match the shared helper's error string).
118
+ - Test count: 1060 (was 1044).
119
+
120
+ ### Docs
121
+
122
+ - `transforms/rolling.mdx`: live section now documents the
123
+ `AggregateOutputMap` shape with a band-chart example, plus a
124
+ callout that custom functions remain batch-only.
125
+ - `recipes/telemetry-reporting.mdx`: "Want multiple percentiles?"
126
+ section rewritten — the workaround note is gone, replaced with
127
+ the single-pass `{ p50, p95, p99 }` pattern.
128
+
129
+ [0.13.0]: https://github.com/pjm17971/pond-ts/compare/v0.12.1...v0.13.0
130
+
14
131
  ## [0.12.1] — 2026-05-01
15
132
 
16
133
  Strictly additive over v0.12.0. Closes the chained-view restriction
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pond-ts/react",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "React hooks for pond-ts live time series",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "test:runtime": "vitest run"
32
32
  },
33
33
  "peerDependencies": {
34
- "pond-ts": "^0.12.0",
34
+ "pond-ts": "^0.13.0",
35
35
  "react": "^18.0.0 || ^19.0.0"
36
36
  },
37
37
  "devDependencies": {