@pond-ts/react 0.14.0 → 0.14.2

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 +159 -1
  2. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,10 +7,168 @@ 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.14.0...HEAD
10
+ [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.14.2...HEAD
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.14.2] — 2026-05-03
15
+
16
+ Hotfix over v0.14.1 — closes a type-narrowing gap on the new
17
+ `'samples'` reducer that the v0.14.1 Layer 2 review caught
18
+ post-merge. The runtime worked, but TypeScript didn't know about
19
+ `'samples'`: passing it through `series.aggregate({ col: 'samples' })`
20
+ or `live.rolling(window, { col: 'samples' })` produced
21
+ `Type '"samples"' is not assignable to type 'AggregateReducer'`,
22
+ and `series.reduce({ col: 'samples' }).col` fell through to
23
+ `ColumnValue | undefined` instead of the narrowed array type.
24
+
25
+ ### Fixed
26
+
27
+ - **`'samples'` is now in the type system everywhere.** Added to
28
+ `AggregateFunction` union, both branches of
29
+ `AggregateFunctionsForKind` (numeric and array/string/boolean),
30
+ `AggregateKindForColumn` (so output columns get
31
+ `kind: 'array'`), `ArrayAggregateKind`, and the array branch of
32
+ `ReduceResult` in `types-reduce.ts`.
33
+
34
+ ```ts
35
+ // Pre-v0.14.2: TS error, but ran correctly.
36
+ // Post-v0.14.2: typechecks and narrows the same way `unique` and
37
+ // `top${N}` do — `ReadonlyArray<T>` for source kind T.
38
+ series.reduce({ vals: 'samples' }).vals; // ReadonlyArray<number> | undefined
39
+
40
+ series.aggregate(Sequence.every('5s'), { vals: 'samples' });
41
+ // Output column: { name: 'vals', kind: 'array' }
42
+ ```
43
+
44
+ - **`reducer-reference.mdx`** updated: "14 built-in reducers" → 15.
45
+
46
+ ### Added
47
+
48
+ - `test-d/types.test-d.ts` block pinning `'samples'` narrowing
49
+ parity with `'unique'` / `'top${N}'`. Closes the regression hole
50
+ the v0.14.1 review surfaced.
51
+
52
+ ### Known follow-up
53
+
54
+ The v0.14.1 review also flagged that `npm run verify`'s
55
+ `test:type` step uses `tsconfig.types.json` (covers `src` +
56
+ `test-d/`), not `tsconfig.vitest.json` (covers `test/`) — that's
57
+ why the missing `'samples'` narrowing didn't fail CI even though
58
+ `packages/core/test/samples-reducer.test.ts` had ~30 type errors.
59
+ Captured in DOCPLAN.md / PLAN.md as a future safety-net widening;
60
+ not in scope for v0.14.2 because pre-existing test files have
61
+ their own type drift that would need cleanup first.
62
+
63
+ [0.14.2]: https://github.com/pjm17971/pond-ts/compare/v0.14.1...v0.14.2
64
+
65
+ ## [0.14.1] — 2026-05-03
66
+
67
+ The "samples reducer + lifted custom-fn guard" release. Surfaced by
68
+ the gRPC experiment's step-4 (anomaly density) walkback: the use
69
+ case "compute counts of values exceeding `k·σ` from a baseline" needs
70
+ the **raw values** from the rolling window, but pond's existing
71
+ built-ins all collapse to scalars or deduplicate. Custom-function
72
+ reducers — which would cover the use case cleanly — worked on batch
73
+ but were rejected at runtime on live with a `TypeError` pointing at
74
+ `AggregateOutputMap` aliases (which don't actually solve "all values"
75
+ either). Two related changes ship together to close both gaps.
76
+
77
+ ### Added
78
+
79
+ - **`'samples'` built-in reducer.** Returns the bucket's defined
80
+ values as an array, in arrival order, with duplicates preserved.
81
+ Sits beside `'unique'` (which deduplicates) and `'top${N}'` (which
82
+ bounds and frequency-orders) — same array-output kind, same
83
+ type-system narrowing through `AggregateOutputMap`. Library-
84
+ implemented; per-event cost is O(1) `add` / O(1) `remove`
85
+ (Map-keyed by event index); `snapshot` is O(N) array copy.
86
+ Memory O(window size).
87
+
88
+ ```ts
89
+ // Anomaly density: count samples > k·σ from a separate baseline.
90
+ const stats = live.rolling(
91
+ '1m',
92
+ {
93
+ mean: { from: 'cpu', using: 'avg' },
94
+ sd: { from: 'cpu', using: 'stdev' },
95
+ },
96
+ { trigger: Trigger.every('30s') },
97
+ );
98
+
99
+ const recent = live.rolling('200ms', {
100
+ vals: { from: 'cpu', using: 'samples' },
101
+ });
102
+
103
+ // At each tick, count threshold crossings against the baseline:
104
+ stats.on('event', (e) => {
105
+ const samples = recent.value().vals as ReadonlyArray<number>;
106
+ const counts = thresholds.map(
107
+ (k) => samples.filter((v) => v - e.get('mean') > k * e.get('sd')).length,
108
+ );
109
+ // ... emit anomaly density
110
+ });
111
+ ```
112
+
113
+ Like `unique`, `samples` flattens one level on array-kind source
114
+ columns. Returns `[]` for an empty bucket.
115
+
116
+ ### Changed
117
+
118
+ - **Custom-function reducers now work on live.** Removed the runtime
119
+ `TypeError` guards on `LiveAggregation`, `LiveRollingAggregation`,
120
+ and `LivePartitionedSyncRolling` that previously rejected
121
+ function-typed reducers. New `bucketStateFor` and `rollingStateFor`
122
+ helpers in `reducers/index.ts` route built-ins to their dedicated
123
+ O(1) machinery and wrap custom functions in a generic adapter:
124
+
125
+ - **Bucket adapter** (`LiveAggregation`): buffers values, calls
126
+ the function once at `snapshot()` time. O(N) per snapshot.
127
+ - **Rolling adapter** (`LiveRollingAggregation`,
128
+ `LivePartitionedSyncRolling`): Map-keyed by event index for O(1)
129
+ `add` / O(1) `remove`; `snapshot()` calls the function with
130
+ `Array.from(map.values())` in arrival order. **O(N) per
131
+ snapshot** — the function re-runs over the current window each
132
+ time the accumulator emits.
133
+
134
+ Documented as the explicit trade-off: convenience of writing
135
+ `(values) => ...` inline against the perf cliff at high event
136
+ rates. For high-throughput streams prefer built-ins or `'samples'`
137
+ (collapse the window once on the producer side, run custom logic
138
+ on the consumer). For low-rate dashboards / debug pipelines /
139
+ prototypes, the convenience usually wins.
140
+
141
+ Pre-v0.14.1, calling `live.rolling(...)` with a custom-function
142
+ reducer threw `TypeError: live rolling reducer for output 'X' must
143
+ be a built-in name; ...`. Post-v0.14.1, the same call constructs
144
+ successfully and runs.
145
+
146
+ ### Tests
147
+
148
+ - 15 new tests in `test/samples-reducer.test.ts` covering: batch
149
+ reduce / aggregate / rolling (including the array-source
150
+ flattening); live aggregate (per-bucket arrays); live rolling
151
+ (window eviction, snapshot correctness through multiple cycles);
152
+ synced partitioned rolling with samples per partition; an
153
+ end-to-end anomaly-density-against-baseline scenario.
154
+ - 2 obsolete tests in `LiveAggregateOutputMap.test.ts` rewritten —
155
+ previously asserted the rejection error, now assert that custom
156
+ functions construct successfully and produce the right value.
157
+ - Total core tests: 1087 (was 1072).
158
+
159
+ ### Docs
160
+
161
+ - `pond-ts/transforms/reducer-reference.mdx`: new `'samples'` entry
162
+ in the Array-producing reducers section; "Choosing a reducer"
163
+ matrix updated; empty-bucket and rolling-complexity tables
164
+ updated; Custom reducers section gained the live perf-cliff
165
+ callout.
166
+ - `pond-ts/transforms/rolling.mdx`: replaced the "Custom-function
167
+ reducers are batch-only" note with the new "O(N) per snapshot on
168
+ live" perf-cliff note pointing at the reducer reference.
169
+
170
+ [0.14.1]: https://github.com/pjm17971/pond-ts/compare/v0.14.0...v0.14.1
171
+
14
172
  ## [0.14.0] — 2026-05-01
15
173
 
16
174
  Two perf wins driven by the gRPC experiment's V3 profiling pass
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pond-ts/react",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "React hooks for pond-ts live time series",
5
5
  "license": "MIT",
6
6
  "repository": {