@pond-ts/react 0.17.1 → 0.19.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 CHANGED
@@ -7,10 +7,156 @@ 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.17.1...HEAD
10
+ [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.19.0...HEAD
11
+ [0.19.0]: https://github.com/pjm17971/pond-ts/compare/v0.18.0...v0.19.0
12
+ [0.18.0]: https://github.com/pjm17971/pond-ts/compare/v0.17.1...v0.18.0
11
13
 
12
14
  ## [Unreleased]
13
15
 
16
+ ## [0.19.0] — 2026-06-02
17
+
18
+ Adds an **experimental column-read surface to the live side** — read typed
19
+ columns straight off a `LiveView` without materializing a `TimeSeries`
20
+ snapshot — driven by the dashboard experiment's per-tick memo cost. Plus a
21
+ `useTimeSeries` schema-inference fix. The live column surface is
22
+ **experimental and expected to keep moving in 0.19.x**.
23
+
24
+ ### Added
25
+
26
+ - **`LiveView` column-read surface (experimental).** Read columns directly
27
+ off a windowed live view, the column-API counterpart to the batch
28
+ `TimeSeries` surface ([#179](https://github.com/pjm17971/pond-ts/pull/179)):
29
+ - `liveView.column(name)` — a numeric value column gathered from the view's
30
+ current events (string / array columns are a compile error; read those as
31
+ scalars or snapshot via `toTimeSeries()`).
32
+ - `liveView.keyColumn()` — the time axis (`TimeKeyColumn`; time-keyed views
33
+ only, enforced at compile time).
34
+ - `liveView.partitionBy(col).toMap(fn)` — a walk-now per-partition read
35
+ returning `Map<string, R>`, mirroring `TimeSeries.partitionBy().toMap()`
36
+ but without per-partition `TimeSeries` construction. Distinct from
37
+ `LiveSeries.partitionBy` (which is subscription-oriented). Throws on a
38
+ missing / key partition column rather than silently merging.
39
+ - `LiveColumnGroup` — the per-partition view passed to the `toMap` callback.
40
+ - **`@pond-ts/react`: `useLiveVersion(source, { throttle })` (experimental)**
41
+ — a `useSyncExternalStore`-based change signal that bumps on append **and**
42
+ eviction, so a component can read columns off a live view each render
43
+ without manufacturing a `TimeSeries` snapshot. Closes the
44
+ render-before-subscribe gap; throttling bounds only the React notification
45
+ ([#179](https://github.com/pjm17971/pond-ts/pull/179)).
46
+
47
+ ### Changed
48
+
49
+ - **`useTimeSeries` collapsed to a single generic** `<S extends SeriesSchema>`
50
+ so the schema infers from `input.schema`. The prior two-generic signature
51
+ lost `S` through the input-wrapper generic and resolved
52
+ `result.column('cpu')` to `never`; the accepted input type is unchanged, so
53
+ this is an inference fix — but a caller passing two explicit type arguments
54
+ must drop the second ([#176](https://github.com/pjm17971/pond-ts/pull/176)).
55
+
56
+ ## [0.18.0] — 2026-05-30
57
+
58
+ This release graduates the **Phase 4.7 columnar substrate** from
59
+ framework-internal (shipped piecemeal to `main` since v0.17.1) to a
60
+ user-visible **public column API**, plus a column-native live buffer that
61
+ fixes a high-partition-count OOM. Everything is additive except one
62
+ documented breaking change (interval label kinds) and one documented
63
+ behavior change (chunked-backed `pushMany` commit semantics). Pre-1.0: the
64
+ column API is expected to keep moving toward its eventual shape.
65
+
66
+ ### Added
67
+
68
+ - **Public column API (Phase 4.7 step 8).** A column-centric extraction
69
+ surface on `TimeSeries`, for high-throughput and charting consumers that
70
+ want typed-array access instead of per-`Event` iteration. Additive — every
71
+ existing row / `Event` API is unchanged.
72
+ - `series.column(name)` returns a schema-narrowed typed column view, with
73
+ public re-exports of the `Float64Column` / `BooleanColumn` /
74
+ `StringColumn` / `KeyColumn` (time / timeRange / interval) variants
75
+ ([#154](https://github.com/pjm17971/pond-ts/pull/154),
76
+ [#155](https://github.com/pjm17971/pond-ts/pull/155)).
77
+ - `Float64Column`: scalar reductions (`min` / `max` / `sum` / `mean` /
78
+ `count` / …) and `scan`
79
+ ([#155](https://github.com/pjm17971/pond-ts/pull/155)); `bin(...)` for
80
+ histogram / downsample bucketing
81
+ ([#156](https://github.com/pjm17971/pond-ts/pull/156)); and
82
+ `toFloat64Array()` for a storage-agnostic gather into a dense array
83
+ ([#165](https://github.com/pjm17971/pond-ts/pull/165)).
84
+ - `KeyColumn.at(i)` and `.slice(start, end)`
85
+ ([#159](https://github.com/pjm17971/pond-ts/pull/159)).
86
+ - **Columnar substrate (Phase 4.7 step 1, framework layer).** All
87
+ eight sub-steps (1a–1h) shipped to main as PRs #132 / #133 /
88
+ #134 / #135 / #136 / #147 / #148 / #149. See `PLAN.md` and
89
+ [`packages/core/src/columnar/README.md`](packages/core/src/columnar/README.md)
90
+ for the full inventory. Framework-internal — surfaced behind the existing
91
+ `TimeSeries` API at step 2 (below) and the public column API at step 8
92
+ (above).
93
+
94
+ ### Changed
95
+
96
+ - **Chunked columnar live backing for strict time-keyed `LiveSeries`**
97
+ ([#170](https://github.com/pjm17971/pond-ts/pull/170)). A top-level
98
+ `LiveSeries` with `ordering: 'strict'` and a time key now backs its
99
+ retained window with batch-granular columnar chunks instead of an
100
+ `Event[]` window — each `pushMany` validates straight into typed columns,
101
+ retaining **zero `Event` objects** (~4.7× less retained heap in-pond; the
102
+ high-partition-count OOM fix). Two consequences:
103
+ - **`pushMany` commit semantics** on the chunked path: the batch is
104
+ appended atomically _before_ any `'event'` fires, so a listener observes
105
+ the full post-batch `length` (not a row-by-row `1, 2, 3`), and a listener
106
+ that throws mid-batch leaves the whole batch committed. The per-row
107
+ `Event[]` backing (`reorder` / `drop` / interval-keyed /
108
+ internally-created series) keeps per-row commit. Listener _values_ and
109
+ `event → batch → evict` ordering are unchanged.
110
+ - **`LiveReduce` eviction** resolves by event identity (primary) with a
111
+ FIFO-frontier fallback for the chunked backing's materialized evictions —
112
+ correct for both `reorder` and the chunked backing. `min` / `max` /
113
+ `first` / `last` / `samples` over a `reorder` source **with retention**
114
+ remain a documented limitation (see `LiveReduce` JSDoc and PLAN
115
+ "Deferred") — pre-existing, not introduced here.
116
+ - **Internal, behavior-preserving performance work.** Column-native intake
117
+ bypasses per-row `Event` allocation at `TimeSeries` construction
118
+ ([#151](https://github.com/pjm17971/pond-ts/pull/151)); numeric reducers
119
+ (`min` / `max` / `sum` / `avg` / …) compute over typed-array columns where
120
+ available, with NaN parity preserved
121
+ ([#153](https://github.com/pjm17971/pond-ts/pull/153)); the live storage
122
+ strategy was extracted behind an internal interface
123
+ ([#168](https://github.com/pjm17971/pond-ts/pull/168)).
124
+
125
+ ### Changed (BREAKING)
126
+
127
+ - **Interval-keyed series must use one label type throughout**
128
+ ([#150](https://github.com/pjm17971/pond-ts/pull/150)). Pre-2a,
129
+ TimeSeries silently tolerated mixed-kind interval labels —
130
+ rows with `value: 'row-1'` (string) and `value: 2` (number) could
131
+ coexist in a single series because events were stored as a raw
132
+ array with no per-column type alignment. The columnar substrate
133
+ introduced at Phase 4.7 enforces one label kind per column via
134
+ `IntervalKeyColumn`, so mixed-kind labels now throw at series
135
+ construction with a row-pointed error message.
136
+ - **Affected:** Any series built via `new TimeSeries(...)`,
137
+ `TimeSeries.fromJSON(...)`, `TimeSeries.fromEvents(...)`, or
138
+ any transform that produces interval-keyed events, where the
139
+ `value` field of `IntervalInput` rows or `Interval` keys
140
+ mixes `string` and `number` types.
141
+ - **Migration:** Choose one label kind for the whole series.
142
+ Numeric labels can be stringified at intake (`String(label)`)
143
+ if the downstream consumer accepts string equality; string
144
+ labels parseable as integers can be converted to numbers at
145
+ intake. The error message names the first offending row so
146
+ the offending data is easy to find.
147
+ - **Rationale:** Aligns the row-API contract with the columnar
148
+ substrate's per-column kind discipline (matching Polars /
149
+ Arrow / Parquet). The previous behavior produced type-broken
150
+ events that worked only because TimeSeries didn't enforce
151
+ per-column alignment; downstream columnar operators (the
152
+ upcoming reducer adaptation in steps 3+) require it.
153
+ - **Affected types:** `IntervalValue` remains `string | number`
154
+ per the `Interval` class contract. The runtime restriction
155
+ is at the **series** level (all intervals within one series
156
+ must share a kind), not the per-interval level. Type-level
157
+ narrowing of `IntervalKeyedSchema<S>` over label kind is a
158
+ follow-up deferred to a later sub-step.
159
+
14
160
  ## [0.17.1] — 2026-05-11
15
161
 
16
162
  Bug fix: `live.partitionBy()` now default-inherits `ordering`,
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # pond-ts
2
2
 
3
3
  **Highly optimised, fully typed Timeseries library for TypeScript**
4
-
4
+
5
5
  Schema-driven events, composable batch transforms, push-based streaming
6
6
  ingest, multi-entity partitioning, and an optional React integration —
7
7
  all strict TypeScript end to end, all immutable.
@@ -31,6 +31,11 @@ npm install @pond-ts/react # React hooks (optional)
31
31
  single node.js instance.)
32
32
  - **Triggers** — for control of rolling emission cadences. Synchronised
33
33
  partitioned rolling fires across partitions on every boundary.
34
+ - **Typed column extraction** — `series.column('cpu')` returns a
35
+ schema-narrowed typed column with single-pass reductions
36
+ (`min`/`max`/`sum`/`mean`/`stdev`/`median`/`percentile`/`minMax`),
37
+ index downsampling (`bin`), and a zero-copy `toFloat64Array()` for
38
+ canvas / WebGL draw loops — no per-event allocation on the hot path.
34
39
  - **No legacy baggage**
35
40
 
36
41
  ## Quick start: batch
package/dist/index.d.ts CHANGED
@@ -7,5 +7,6 @@ export { useLiveQuery } from './useLiveQuery.js';
7
7
  export { useLatest } from './useLatest.js';
8
8
  export { useCurrent, type UseCurrentOptions } from './useCurrent.js';
9
9
  export { useEventRate } from './useEventRate.js';
10
+ export { useLiveVersion, type UseLiveVersionOptions, } from './useLiveVersion.js';
10
11
  export { takeSnapshot } from './takeSnapshot.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -8,5 +8,6 @@ export { useLiveQuery } from './useLiveQuery.js';
8
8
  export { useLatest } from './useLatest.js';
9
9
  export { useCurrent } from './useCurrent.js';
10
10
  export { useEventRate } from './useEventRate.js';
11
+ export { useLiveVersion, } from './useLiveVersion.js';
11
12
  export { takeSnapshot } from './takeSnapshot.js';
12
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,WAAW,GAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,WAAW,GAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { LiveSource, SeriesSchema } from 'pond-ts';
2
+ export interface UseLiveVersionOptions {
3
+ /**
4
+ * Minimum interval between React notifications, in ms. The version
5
+ * counter bumps *immediately* on every source change (no buffering);
6
+ * `throttle` only bounds how often React is told to re-render.
7
+ * `0` notifies synchronously per change. Default 100.
8
+ */
9
+ throttle?: number;
10
+ }
11
+ /**
12
+ * The React change signal for reading columns off a live source without
13
+ * manufacturing a `TimeSeries` snapshot (§A pull/read, experimental).
14
+ *
15
+ * `LiveSeries` / `LiveView` mutate in place, so a `useMemo([liveView])`
16
+ * keyed on the view never re-runs. This hook gives React a
17
+ * monotonically-increasing version that changes (at most once per
18
+ * `throttle`) whenever the source mutates — the missing invalidation
19
+ * trigger. Read columns straight off the live view, keyed on the
20
+ * returned version:
21
+ *
22
+ * ```tsx
23
+ * const view = useMemo(() => live.window('5m'), [live]);
24
+ * const v = useLiveVersion(view, { throttle: 200 });
25
+ * const series = useMemo(
26
+ * () => view.partitionBy('host').toMap((g) => ({
27
+ * ts: g.keyColumn().begin,
28
+ * cpu: g.column('cpu').toFloat64Array(),
29
+ * })),
30
+ * [view, v],
31
+ * );
32
+ * ```
33
+ *
34
+ * Tracks **both** append (`'event'`) and eviction (`'evict'`, on sources
35
+ * that emit it — e.g. `clear()` / retention prune), and advances the
36
+ * revision on subscribe so a change between render and the subscribe
37
+ * effect is still picked up (the `useSyncExternalStore` post-subscribe
38
+ * re-read). Experimental (0.19.0) — surface may change in 0.19.x.
39
+ */
40
+ export declare function useLiveVersion<S extends SeriesSchema>(source: LiveSource<S>, options?: UseLiveVersionOptions): number;
41
+ //# sourceMappingURL=useLiveVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveVersion.d.ts","sourceRoot":"","sources":["../src/useLiveVersion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AASxD,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,YAAY,EACnD,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CA4ER"}
@@ -0,0 +1,104 @@
1
+ import { useMemo, useSyncExternalStore } from 'react';
2
+ // The capability marker pond-ts stamps on evict-emitting sources
3
+ // (`LiveSeries`, `LiveView`). It's a registered symbol
4
+ // (`Symbol.for('pond-ts:emitsEvict')` in pond-ts), so reconstructing it
5
+ // here yields the identical symbol — no import needed. The
6
+ // `clear-evicts-without-event` test guards against key drift.
7
+ const EMITS_EVICT = Symbol.for('pond-ts:emitsEvict');
8
+ /**
9
+ * The React change signal for reading columns off a live source without
10
+ * manufacturing a `TimeSeries` snapshot (§A pull/read, experimental).
11
+ *
12
+ * `LiveSeries` / `LiveView` mutate in place, so a `useMemo([liveView])`
13
+ * keyed on the view never re-runs. This hook gives React a
14
+ * monotonically-increasing version that changes (at most once per
15
+ * `throttle`) whenever the source mutates — the missing invalidation
16
+ * trigger. Read columns straight off the live view, keyed on the
17
+ * returned version:
18
+ *
19
+ * ```tsx
20
+ * const view = useMemo(() => live.window('5m'), [live]);
21
+ * const v = useLiveVersion(view, { throttle: 200 });
22
+ * const series = useMemo(
23
+ * () => view.partitionBy('host').toMap((g) => ({
24
+ * ts: g.keyColumn().begin,
25
+ * cpu: g.column('cpu').toFloat64Array(),
26
+ * })),
27
+ * [view, v],
28
+ * );
29
+ * ```
30
+ *
31
+ * Tracks **both** append (`'event'`) and eviction (`'evict'`, on sources
32
+ * that emit it — e.g. `clear()` / retention prune), and advances the
33
+ * revision on subscribe so a change between render and the subscribe
34
+ * effect is still picked up (the `useSyncExternalStore` post-subscribe
35
+ * re-read). Experimental (0.19.0) — surface may change in 0.19.x.
36
+ */
37
+ export function useLiveVersion(source, options) {
38
+ const throttleMs = options?.throttle ?? 100;
39
+ const store = useMemo(() => {
40
+ let version = 0; // bumped on every observed source mutation
41
+ let committed = 0; // last version React has been notified about
42
+ let timer = null;
43
+ let unsubSource = null;
44
+ const listeners = new Set();
45
+ const flush = () => {
46
+ timer = null;
47
+ committed = version;
48
+ for (const l of listeners)
49
+ l();
50
+ };
51
+ const onChange = () => {
52
+ version += 1;
53
+ if (throttleMs <= 0) {
54
+ flush();
55
+ }
56
+ else if (timer === null) {
57
+ timer = setTimeout(flush, throttleMs);
58
+ }
59
+ };
60
+ return {
61
+ subscribe(cb) {
62
+ listeners.add(cb);
63
+ if (unsubSource === null) {
64
+ const unsubEvent = source.on('event', onChange);
65
+ // Also track eviction (clear / retention prune) on sources that
66
+ // emit it — otherwise a `clear()` with no following append leaves
67
+ // a column reader stale.
68
+ let unsubEvict;
69
+ if (EMITS_EVICT in source) {
70
+ unsubEvict = source.on('evict', onChange);
71
+ }
72
+ unsubSource = () => {
73
+ unsubEvent();
74
+ unsubEvict?.();
75
+ };
76
+ }
77
+ // Close the render-before-subscribe gap: a mutation between render
78
+ // and this effect fires no observed callback, so advance the
79
+ // revision now. useSyncExternalStore re-reads getSnapshot after
80
+ // subscribe; the bumped value forces one re-render that re-reads
81
+ // the (now-current) view.
82
+ version += 1;
83
+ committed = version;
84
+ return () => {
85
+ listeners.delete(cb);
86
+ if (listeners.size === 0) {
87
+ unsubSource?.();
88
+ unsubSource = null;
89
+ if (timer !== null) {
90
+ clearTimeout(timer);
91
+ timer = null;
92
+ }
93
+ }
94
+ };
95
+ },
96
+ // Stable between notifications — only advances at flush / subscribe,
97
+ // exactly when React is told. (Returning the live `version` would
98
+ // violate the getSnapshot contract.)
99
+ getSnapshot: () => committed,
100
+ };
101
+ }, [source, throttleMs]);
102
+ return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
103
+ }
104
+ //# sourceMappingURL=useLiveVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveVersion.js","sourceRoot":"","sources":["../src/useLiveVersion.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { TimeSeries } from 'pond-ts';
2
- import type { SeriesSchema } from 'pond-ts';
2
+ import type { SeriesSchema, TimeSeriesJsonInput, TimeZoneOptions } from 'pond-ts';
3
3
  /**
4
4
  * Memoized `TimeSeries.fromJSON(...)` for static or fetched data.
5
5
  *
@@ -7,6 +7,19 @@ import type { SeriesSchema } from 'pond-ts';
7
7
  * serialized via `JSON.stringify` as the cache key — fine for small to
8
8
  * moderate payloads. For large datasets, pass an explicit `key` (e.g. a fetch
9
9
  * URL or ETag) to avoid the serialization cost.
10
+ *
11
+ * The schema generic `S` is inferred directly from `input.schema` (a plain
12
+ * structural position), so an `as const` schema narrows the returned
13
+ * `TimeSeries<S>` fully — `result.column('cpu')` resolves to `Float64Column`,
14
+ * `result.at(i)!.get('cpu')` to `number | undefined`, etc. An earlier
15
+ * two-generic `<S, I extends Parameters<...>[0]>` shape lost `S` through the
16
+ * input-wrapper generic and collapsed schema-narrowed accessors to `never`
17
+ * (the loose `.get(string)` path masked it); the column API surfaced it. The
18
+ * accepted input type is unchanged — `Parameters<fromJSON<S>>[0]` already
19
+ * resolved to `TimeSeriesJsonInput<S> & { parse? }` — so this is purely an
20
+ * inference fix, not a surface change.
10
21
  */
11
- export declare function useTimeSeries<S extends SeriesSchema, I extends Parameters<typeof TimeSeries.fromJSON<S>>[0]>(input: I, key?: string): TimeSeries<S>;
22
+ export declare function useTimeSeries<S extends SeriesSchema>(input: TimeSeriesJsonInput<S> & {
23
+ parse?: TimeZoneOptions;
24
+ }, key?: string): TimeSeries<S>;
12
25
  //# sourceMappingURL=useTimeSeries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTimeSeries.d.ts","sourceRoot":"","sources":["../src/useTimeSeries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,UAAU,CAAC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACtD,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAKvC"}
1
+ {"version":3,"file":"useTimeSeries.d.ts","sourceRoot":"","sources":["../src/useTimeSeries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,YAAY,EAClD,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,EAC3D,GAAG,CAAC,EAAE,MAAM,GACX,UAAU,CAAC,CAAC,CAAC,CAKf"}
@@ -7,6 +7,17 @@ import { TimeSeries } from 'pond-ts';
7
7
  * serialized via `JSON.stringify` as the cache key — fine for small to
8
8
  * moderate payloads. For large datasets, pass an explicit `key` (e.g. a fetch
9
9
  * URL or ETag) to avoid the serialization cost.
10
+ *
11
+ * The schema generic `S` is inferred directly from `input.schema` (a plain
12
+ * structural position), so an `as const` schema narrows the returned
13
+ * `TimeSeries<S>` fully — `result.column('cpu')` resolves to `Float64Column`,
14
+ * `result.at(i)!.get('cpu')` to `number | undefined`, etc. An earlier
15
+ * two-generic `<S, I extends Parameters<...>[0]>` shape lost `S` through the
16
+ * input-wrapper generic and collapsed schema-narrowed accessors to `never`
17
+ * (the loose `.get(string)` path masked it); the column API surfaced it. The
18
+ * accepted input type is unchanged — `Parameters<fromJSON<S>>[0]` already
19
+ * resolved to `TimeSeriesJsonInput<S> & { parse? }` — so this is purely an
20
+ * inference fix, not a surface change.
10
21
  */
11
22
  export function useTimeSeries(input, key) {
12
23
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -1 +1 @@
1
- {"version":3,"file":"useTimeSeries.js","sourceRoot":"","sources":["../src/useTimeSeries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAG3B,KAAQ,EAAE,GAAY;IACtB,uDAAuD;IACvD,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,uDAAuD;IACvD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAI,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"useTimeSeries.js","sourceRoot":"","sources":["../src/useTimeSeries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAOrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA2D,EAC3D,GAAY;IAEZ,uDAAuD;IACvD,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,uDAAuD;IACvD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAI,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pond-ts/react",
3
- "version": "0.17.1",
3
+ "version": "0.19.0",
4
4
  "description": "React hooks for pond-ts live time series",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,11 +27,12 @@
27
27
  "scripts": {
28
28
  "build": "tsc -p tsconfig.json",
29
29
  "prepack": "cp ../../README.md ./README.md && cp ../../LICENSE ./LICENSE && cp ../../CHANGELOG.md ./CHANGELOG.md && npm run build",
30
- "test": "vitest run",
30
+ "test": "npm run test:type && npm run test:runtime",
31
+ "test:type": "tsc -p tsconfig.types.json",
31
32
  "test:runtime": "vitest run"
32
33
  },
33
34
  "peerDependencies": {
34
- "pond-ts": "^0.17.0",
35
+ "pond-ts": "^0.19.0",
35
36
  "react": "^18.0.0 || ^19.0.0"
36
37
  },
37
38
  "devDependencies": {