@pond-ts/react 0.16.0 → 0.17.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.
- package/CHANGELOG.md +165 -15
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,158 @@ 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.
|
|
10
|
+
[Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.17.0...HEAD
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [0.17.0] — 2026-05-08
|
|
15
|
+
|
|
16
|
+
`sample({...})` operator wave: bounded-memory stream thinning, surfaced
|
|
17
|
+
by the gRPC experiment's M3.5 finish-line work
|
|
18
|
+
([friction note](https://github.com/pjm17971/pond-grpc-experiment/blob/main/friction-notes/rfcs/bounded-memory-sampling.md)
|
|
19
|
+
with measured firehose numbers). Decouples downstream baseline window
|
|
20
|
+
length from event rate — at firehose rates × stride 10, `sd / sqrt(N)`
|
|
21
|
+
standard error stays well below per-event noise while a 5-minute
|
|
22
|
+
baseline that wouldn't fit in a Node heap un-sampled does at
|
|
23
|
+
stride 10. PR [#129](https://github.com/pjm17971/pond-ts/pull/129).
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **`series.sample({ stride | reservoir })`** on `TimeSeries` and
|
|
28
|
+
`PartitionedTimeSeries` — single-pass thinning that keeps the
|
|
29
|
+
`TimeSeries<S>` schema. Stride is deterministic 1-in-N
|
|
30
|
+
(`{ stride: N }`); reservoir is random K-of-N via single-pass
|
|
31
|
+
[Vitter's Algorithm R](https://en.wikipedia.org/wiki/Reservoir_sampling#Simple:_Algorithm_R)
|
|
32
|
+
(`{ reservoir: { size: K } }`), sorted by key on output to preserve
|
|
33
|
+
the chronological invariant. The canonical visualization shape:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
series.sample({ reservoir: { size: 500 } }).toRows();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
500 uncorrelated points drawn uniformly from the source — no
|
|
40
|
+
`aggregate(seq, ...)` grid collapse, no regular-spacing artifact,
|
|
41
|
+
fixed point count regardless of source size. Per-partition state on
|
|
42
|
+
`PartitionedTimeSeries.sample(...)` — each partition gets its own
|
|
43
|
+
K-event reservoir or stride counter.
|
|
44
|
+
|
|
45
|
+
- **`live.sample({ stride })`** on `LiveSeries`, `LiveView`,
|
|
46
|
+
`LivePartitionedSeries`, `LivePartitionedView` — closure-captured
|
|
47
|
+
counter inside a `LiveView<S>`, so the chainable surface (`filter`,
|
|
48
|
+
`rolling`, `reduce`, `select`, `map`, `diff`, `rate`, `cumulative`,
|
|
49
|
+
`fill`) is immediately available downstream of the sample. The
|
|
50
|
+
bounded-memory firehose pattern:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
live.partitionBy('host').sample({ stride: 10 }).rolling('5m', mapping);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each host's stream is thinned 1-in-10 before flowing into a per-host
|
|
57
|
+
5m rolling window. `live.stats().ingested` and `live.on('batch', cb)`
|
|
58
|
+
are upstream of any `.sample(...)` op — they continue counting true
|
|
59
|
+
throughput; only consumers downstream see the thinned stream.
|
|
60
|
+
|
|
61
|
+
- **Sampling docs page** at
|
|
62
|
+
[`pond-ts/transforms/sampling`](https://pjm17971.github.io/pond-ts/docs/pond-ts/transforms/sampling/)
|
|
63
|
+
covering when-to-use-which decision table, both strategies, the
|
|
64
|
+
visualization shape, multi-entity considerations, and a forward-link
|
|
65
|
+
to the live counterpart. New `## Sampling: bounded-memory thinning`
|
|
66
|
+
section in
|
|
67
|
+
[Live transforms](https://pjm17971.github.io/pond-ts/docs/pond-ts/live/live-transforms#sampling).
|
|
68
|
+
|
|
69
|
+
### Deferred
|
|
70
|
+
|
|
71
|
+
- **Live-side reservoir sampling** is queued for v0.18.0+. Algorithm R's
|
|
72
|
+
random-slot replacement produces non-prefix evictions, but the existing
|
|
73
|
+
live-eviction protocol (`'evict'` event + cutoff-based mirroring in
|
|
74
|
+
`LiveView`) assumes prefix evictions only. Bridging needs an exact-
|
|
75
|
+
removal eviction channel — arriving with the streaming RFC's
|
|
76
|
+
`LiveChange` model (Phase 4.5 milestone A). For visualization-shaped
|
|
77
|
+
reservoir today, materialize via `live.toTimeSeries().sample({ reservoir })`.
|
|
78
|
+
|
|
79
|
+
### Notes
|
|
80
|
+
|
|
81
|
+
- **Multi-entity bias trap** is documented in JSDoc on the pre-partition
|
|
82
|
+
sites (`LiveSeries.sample`, `LiveView.sample`) with the
|
|
83
|
+
`partitionBy(...).sample(...)` recommendation, matching the existing
|
|
84
|
+
convention for `rolling` / `aggregate` / `fill` / `diff` / `rate` /
|
|
85
|
+
`cumulative` / `pctChange` / `reduce`. An earlier iteration of #129
|
|
86
|
+
shipped a type-level `unsafeGlobal: true` token; pulled during review
|
|
87
|
+
for consistency with how every other stateful live operator handles
|
|
88
|
+
the same multi-entity consideration. Token-of-the-week novelty was
|
|
89
|
+
the wrong shape; the doc warning is the same answer the other
|
|
90
|
+
operators already give.
|
|
91
|
+
|
|
92
|
+
- **Legacy `rolling.sample(seq)` doc references removed.** Pre-v0.12
|
|
93
|
+
pond exposed `LiveRollingAggregation.sample(sequence)` as a separate
|
|
94
|
+
method (deleted in v0.12.0, replaced by `Trigger.every`). Active doc
|
|
95
|
+
references in `pond-ts/live/triggering.mdx`,
|
|
96
|
+
`pond-ts/transforms/alignment.mdx`, `pond-ts/transforms/rolling.mdx`,
|
|
97
|
+
and `pond-ts/live/live-transforms.mdx` removed to eliminate the
|
|
98
|
+
naming-collision confusion now that `series.sample({ stride | reservoir })`
|
|
99
|
+
is a real but completely unrelated operator. Historical record
|
|
100
|
+
preserved in PLAN.md, the v0.11.8 CHANGELOG entry, and the triggers RFC.
|
|
101
|
+
|
|
102
|
+
## [0.16.1] — 2026-05-06
|
|
103
|
+
|
|
104
|
+
Patch wave addressing one ergonomic gap surfaced by the gRPC
|
|
105
|
+
experiment ([pond-grpc-experiment#29](https://github.com/pjm17971/pond-grpc-experiment/pull/29))
|
|
106
|
+
plus the v0.16.0 docs deploy that broke since v0.15.2.
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
|
|
110
|
+
- **`PartitionedTimeSeries.aggregate(...)` and `.rolling(...)` now
|
|
111
|
+
auto-inject the partition column into the user's mapping**
|
|
112
|
+
([#128](https://github.com/pjm17971/pond-ts/pull/128)). The
|
|
113
|
+
natural shape just works:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
series
|
|
117
|
+
.partitionBy('host')
|
|
118
|
+
.aggregate(Sequence.every('600ms'), { cpu_avg: 'avg' });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Pre-fix this threw `column "host" not in schema` at the rewrap
|
|
122
|
+
step because the user's mapping didn't carry the partition
|
|
123
|
+
column through; users had to add `host: 'first'` mechanically
|
|
124
|
+
to every partitioned-aggregate call. Pond now adds it
|
|
125
|
+
automatically — `'first'` is by-construction-correct since
|
|
126
|
+
every row in a single partition shares that column's value.
|
|
127
|
+
User-supplied mappings for the partition column win (auto-
|
|
128
|
+
inject is a no-op when the user has already opted in).
|
|
129
|
+
Composite partitions (`partitionBy(['host', 'region'])`)
|
|
130
|
+
auto-inject every partition column. Strictly additive — the
|
|
131
|
+
pre-fix workaround pattern still works unchanged.
|
|
132
|
+
|
|
133
|
+
### Fixed
|
|
134
|
+
|
|
135
|
+
- **Docs deploy workflow unblocked**
|
|
136
|
+
([#126](https://github.com/pjm17971/pond-ts/pull/126)). Has
|
|
137
|
+
been failing since v0.15.2 with `Cannot find name
|
|
138
|
+
'queueMicrotask'` — TypeDoc runs the same tsconfig as the
|
|
139
|
+
npm-publish path but from a different cwd, where `@types/node`
|
|
140
|
+
doesn't resolve. Fixed via a one-line ambient declaration in
|
|
141
|
+
`LiveReduce.ts`. No runtime change; `queueMicrotask` is still
|
|
142
|
+
the host-provided global it always was.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- **Updated `LiveSeries` tool comparisons in the docs**
|
|
147
|
+
([#127](https://github.com/pjm17971/pond-ts/pull/127)).
|
|
148
|
+
Tightened the Beam/Flink, PondJS, and pandas comparison tables
|
|
149
|
+
to be technically accurate. Doc prose only; no code change.
|
|
150
|
+
|
|
151
|
+
### Notes
|
|
152
|
+
|
|
153
|
+
- **Captured `@pond-ts/charts` design constraints in PLAN.md**
|
|
154
|
+
([#128](https://github.com/pjm17971/pond-ts/pull/128)). The
|
|
155
|
+
gRPC experiment's M3.5 friction note hit Recharts' SVG render
|
|
156
|
+
cliff at firehose loads (~75-80k SVG nodes per render, ~1 fps
|
|
157
|
+
at 10 hosts × 70k events/s). Four constraints from real
|
|
158
|
+
workload now baked into the plan so the eventual extraction
|
|
159
|
+
starts with the answer key — not new code, just durable
|
|
160
|
+
design capture.
|
|
161
|
+
|
|
14
162
|
## [0.16.0] — 2026-05-06
|
|
15
163
|
|
|
16
164
|
Live-API ergonomic wave. Four PRs:
|
|
@@ -41,17 +189,17 @@ narrowings.
|
|
|
41
189
|
`eventRate()`.
|
|
42
190
|
- **`stats()` accessor on every live accumulator/series.** Per-class
|
|
43
191
|
shapes, all returning a plain record (cumulative integer counters
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
| Class
|
|
47
|
-
|
|
48
|
-
| LiveSeries
|
|
49
|
-
| LiveRollingAggregation
|
|
50
|
-
| LiveFusedRolling
|
|
51
|
-
| LiveAggregation
|
|
52
|
-
| LiveReduce
|
|
53
|
-
| LivePartitionedSeries
|
|
54
|
-
| LivePartitionedSyncRolling
|
|
192
|
+
- current-state fields):
|
|
193
|
+
|
|
194
|
+
| Class | Shape |
|
|
195
|
+
| --------------------------- | --------------------------------------------------------------------- |
|
|
196
|
+
| LiveSeries | `{ ingested, evicted, rejected, length, earliestTs?, latestTs? }` |
|
|
197
|
+
| LiveRollingAggregation | `{ eventsObserved, evictions, emissions, windowSize }` |
|
|
198
|
+
| LiveFusedRolling | `{ eventsObserved, evictions, emissions, windowSize, windowsCount }` |
|
|
199
|
+
| LiveAggregation | `{ eventsObserved, bucketsClosed, openBuckets, openBucketStart? }` |
|
|
200
|
+
| LiveReduce | `{ eventsObserved, evictions, emissions, bufferSize }` |
|
|
201
|
+
| LivePartitionedSeries | `{ partitions, eventsRouted }` |
|
|
202
|
+
| LivePartitionedSyncRolling | `{ partitions, eventsObserved, emissions, windowSize }` |
|
|
55
203
|
| LivePartitionedFusedRolling | `{ partitions, eventsObserved, emissions, windowSize, windowsCount }` |
|
|
56
204
|
|
|
57
205
|
Per-event cost: ~1-3 integer increments in already-existing
|
|
@@ -92,7 +240,7 @@ narrowings.
|
|
|
92
240
|
|
|
93
241
|
- **`KeyLike` type** exported from the package root (re-exported
|
|
94
242
|
from `TimeSeries`). Accepts `EventKey | TimestampInput |
|
|
95
|
-
|
|
243
|
+
TimeRangeInput | IntervalInput`; normalised by the new query
|
|
96
244
|
primitives.
|
|
97
245
|
|
|
98
246
|
- **`DurationLiteral` and `DurationUnit` types** extracted from
|
|
@@ -126,8 +274,8 @@ narrowings.
|
|
|
126
274
|
on). Sane transforms (data-only maps, monotonic time-shifts)
|
|
127
275
|
unaffected.
|
|
128
276
|
- **`LiveAggregationOptions.grace`** type tightened from
|
|
129
|
-
`DurationInput | \`${number}${unit}\``
|
|
130
|
-
|
|
277
|
+
`DurationInput | \`${number}${unit}\``(redundant union) to
|
|
278
|
+
just`DurationInput`. No behavioral change.
|
|
131
279
|
|
|
132
280
|
### Notes
|
|
133
281
|
|
|
@@ -237,6 +385,8 @@ compaction); any downstream code reading `#entries` directly would
|
|
|
237
385
|
break, but those fields are private. Public APIs and types are
|
|
238
386
|
unchanged.
|
|
239
387
|
|
|
388
|
+
[0.17.0]: https://github.com/pjm17971/pond-ts/compare/v0.16.1...v0.17.0
|
|
389
|
+
[0.16.1]: https://github.com/pjm17971/pond-ts/compare/v0.16.0...v0.16.1
|
|
240
390
|
[0.16.0]: https://github.com/pjm17971/pond-ts/compare/v0.15.2...v0.16.0
|
|
241
391
|
[0.15.2]: https://github.com/pjm17971/pond-ts/compare/v0.15.1...v0.15.2
|
|
242
392
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pond-ts/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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.
|
|
34
|
+
"pond-ts": "^0.17.0",
|
|
35
35
|
"react": "^18.0.0 || ^19.0.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|