@pond-ts/react 0.23.0 → 0.24.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 +49 -1
- package/README.md +18 -14
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,8 @@ 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.24.0...HEAD
|
|
11
|
+
[0.24.0]: https://github.com/pjm17971/pond-ts/compare/v0.23.0...v0.24.0
|
|
11
12
|
[0.23.0]: https://github.com/pjm17971/pond-ts/compare/v0.22.0...v0.23.0
|
|
12
13
|
[0.22.0]: https://github.com/pjm17971/pond-ts/compare/v0.21.0...v0.22.0
|
|
13
14
|
[0.21.0]: https://github.com/pjm17971/pond-ts/compare/v0.20.0...v0.21.0
|
|
@@ -17,6 +18,53 @@ type-level changes; patch bumps are strictly additive.
|
|
|
17
18
|
|
|
18
19
|
## [Unreleased]
|
|
19
20
|
|
|
21
|
+
## [0.24.0] — 2026-06-14
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **`TimeSeries.timeRange()` is now a columnar key-axis read instead of a
|
|
26
|
+
reduce over materialized events.** Behavior is unchanged, but the old
|
|
27
|
+
implementation materialized every `Event` on its first call — and because
|
|
28
|
+
`aggregate()` defaults its `range` to `series.timeRange()`, a one-shot
|
|
29
|
+
`aggregate()` paid full event materialization before the columnar fast
|
|
30
|
+
path could run, erasing the win. The new path reads the key column's
|
|
31
|
+
begin/end axis directly: O(1) for time-keyed series, a typed-array scan
|
|
32
|
+
for range/interval-keyed series, with no event materialization. Measured
|
|
33
|
+
on 1M rows: `timeRange()` itself ~407 ms → ~0.002 ms (time-keyed); cold
|
|
34
|
+
`aggregate()` with a defaulted range ~387 ms → ~6 ms (~63×). Every
|
|
35
|
+
`timeRange()` / `overlaps` / `contains` / `intersection` caller benefits.
|
|
36
|
+
(Audit v2 §3.3.)
|
|
37
|
+
- **`aggregate()` now takes the columnar fast path when a mapping mixes
|
|
38
|
+
numeric reducers with `first` / `last`.** Previously a single `first` or
|
|
39
|
+
`last` column (they have no numeric `reduceColumn`) bailed the entire call
|
|
40
|
+
to the row path. They now qualify via a boundary scan — the first/last
|
|
41
|
+
_defined_ cell, on any column kind. Behavior is unchanged. The big
|
|
42
|
+
beneficiary is **partitioned `aggregate`**, which auto-injects a `'first'`
|
|
43
|
+
reducer for the partition column and so was excluded from the fast path on
|
|
44
|
+
every call (audit v2 §3.2/§3.3). Measured on 1M rows, flat
|
|
45
|
+
`{ cpu: 'avg', host: 'first' }`: ~37.7 ms → ~4.8 ms (~7.8×); the
|
|
46
|
+
pure-numeric path is unchanged. (The remaining `partitionBy` materialization
|
|
47
|
+
cost is addressed separately by the columnar `partitionBy` split.)
|
|
48
|
+
- **`partitionBy(...)` now splits the columnar store directly instead of
|
|
49
|
+
materializing events.** `collect()` / the per-partition sugar methods
|
|
50
|
+
(`fill` / `diff` / `rolling` / …) and `toMap()` previously walked
|
|
51
|
+
`this.events` to bucket rows, then rebuilt each partition via `fromEvents`
|
|
52
|
+
(re-validating + re-packing) — silently re-paying the event-materialization
|
|
53
|
+
tax the columnar wave removed, and making `partitionBy(host).fill().collect()`
|
|
54
|
+
the #1 batch hotspot. They now group row indices off the store and gather
|
|
55
|
+
each partition via a zero-materialization columnar selection. Behavior is
|
|
56
|
+
unchanged (partition order, the `' undefined'` missing-key bucket, composite
|
|
57
|
+
keys, and declared `groups` all preserved). Measured on 100k rows / 64
|
|
58
|
+
partitions: `toMap()` ~389 → ~25 ns/row (~15×, no event materialization at
|
|
59
|
+
all); `diff().collect()` ~2×; `fill(hold).collect()` ~1.7× (the residual is
|
|
60
|
+
`TimeSeries.concat` still materializing to re-sort — a separate follow-up).
|
|
61
|
+
Declared-`groups` membership is validated by the same columnar scan, so that
|
|
62
|
+
path is materialization-free too (~331 → ~33 ns/row). **Behavior note:**
|
|
63
|
+
per-partition sub-series from `toMap()` / `apply()` now lazily materialize
|
|
64
|
+
their own `Event` objects rather than reusing the source's instances — cell
|
|
65
|
+
values are identical; only object identity differs (`collect()`, which
|
|
66
|
+
returns the source unchanged, is unaffected). (Audit v2 §3.2.)
|
|
67
|
+
|
|
20
68
|
## [0.23.0] — 2026-06-13
|
|
21
69
|
|
|
22
70
|
### Added
|
package/README.md
CHANGED
|
@@ -152,20 +152,24 @@ const points = series.sample({ reservoir: { size: 500 } }).toRows();
|
|
|
152
152
|
|
|
153
153
|
## Performance
|
|
154
154
|
|
|
155
|
-
pond-ts is
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
|
162
|
-
|
|
|
163
|
-
| **
|
|
164
|
-
| **
|
|
165
|
-
| **
|
|
166
|
-
| **Statistics** |
|
|
167
|
-
| **
|
|
168
|
-
| **
|
|
155
|
+
pond-ts is faster on **every** comparable operation, with no regressions —
|
|
156
|
+
a **~17x** geometric-mean speedup across the measurable ops, plus a handful
|
|
157
|
+
of transforms (`select` / `rename`) that are **effectively instant** (O(1)
|
|
158
|
+
column rebinds, below the timer's resolution). The advantage grows with data
|
|
159
|
+
size.
|
|
160
|
+
|
|
161
|
+
| Category | Speedup (N=16k) | Notes |
|
|
162
|
+
| ----------------- | ---------------------------------------------------- | --------------------------------------------- |
|
|
163
|
+
| **Rate** | ~120x | Single columnar walk vs Pipeline |
|
|
164
|
+
| **Fill** | 77–87x | Single columnar pass vs Pipeline per strategy |
|
|
165
|
+
| **Aggregation** | 57–82x | O(N+B) bucketing vs O(N×B) Pipeline |
|
|
166
|
+
| **Statistics** | 18–80x | Typed-array reduce vs ImmutableJS iteration |
|
|
167
|
+
| **Alignment** | 42x | Forward cursor vs repeated binary search |
|
|
168
|
+
| **Construction** | 13x | Columnar intake vs ImmutableJS wrapping |
|
|
169
|
+
| **Chained** | 8x | Derived constructors vs per-step Pipeline |
|
|
170
|
+
| **Transforms** | `select`/`rename` instant; `collapse` 30x; `map` ~4x | Column reshapes vs Pipeline |
|
|
171
|
+
| **Event access** | 6x | Array indexing vs ImmutableJS `get()` |
|
|
172
|
+
| **Serialization** | 4x | Lightweight columnar representation |
|
|
169
173
|
|
|
170
174
|
See the [full benchmark results](website/docs/reference/benchmarks.mdx)
|
|
171
175
|
for detailed numbers. Run locally:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pond-ts/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "React hooks for pond-ts live time series",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"test:runtime": "vitest run"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"pond-ts": "^0.
|
|
36
|
+
"pond-ts": "^0.24.0",
|
|
37
37
|
"react": "^18.0.0 || ^19.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|