@pond-ts/react 0.5.5 → 0.5.6
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/dist/useCurrent.d.ts +7 -0
- package/dist/useCurrent.d.ts.map +1 -1
- package/dist/useCurrent.js +83 -2
- package/dist/useCurrent.js.map +1 -1
- package/package.json +1 -1
package/dist/useCurrent.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ export interface UseCurrentOptions extends UseSnapshotOptions {
|
|
|
26
26
|
* Returns a stable-shape object while the source has no events (every
|
|
27
27
|
* mapped field is `undefined`), so destructuring on first render is
|
|
28
28
|
* safe.
|
|
29
|
+
*
|
|
30
|
+
* **Reference stability**: when a new event push leaves the reduce
|
|
31
|
+
* output structurally unchanged (same scalar values, same-length arrays
|
|
32
|
+
* with same elements), the previous result reference is returned
|
|
33
|
+
* unchanged. Downstream `useMemo([value])` and `useEffect([value])` only
|
|
34
|
+
* re-run when the value actually changes — no need for a manual
|
|
35
|
+
* `.slice()` or deep-compare equality helper at the call site.
|
|
29
36
|
*/
|
|
30
37
|
export declare function useCurrent<S extends SeriesSchema, const Mapping extends AggregateMap<S>>(source: SnapshotSource<S> | LiveSource<S> | null, mapping: Mapping, options?: UseCurrentOptions): ReduceResult<S, Mapping>;
|
|
31
38
|
//# sourceMappingURL=useCurrent.d.ts.map
|
package/dist/useCurrent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurrent.d.ts","sourceRoot":"","sources":["../src/useCurrent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D;;;;OAIG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"useCurrent.d.ts","sourceRoot":"","sources":["../src/useCurrent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D;;;;OAIG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAuED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CACxB,CAAC,SAAS,YAAY,EACtB,KAAK,CAAC,OAAO,SAAS,YAAY,CAAC,CAAC,CAAC,EAErC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,EAChD,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CA8B1B"}
|
package/dist/useCurrent.js
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
2
|
import { useSnapshot, } from './useSnapshot.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns `true` if two array cells have identical length and
|
|
5
|
+
* elementwise-equal contents. Element types are always scalars (the
|
|
6
|
+
* reducer registry enforces this), so `===` per element is both
|
|
7
|
+
* correct and cheap for the sizes a dashboard produces.
|
|
8
|
+
*/
|
|
9
|
+
function arraysEqual(a, b) {
|
|
10
|
+
if (a.length !== b.length)
|
|
11
|
+
return false;
|
|
12
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
13
|
+
if (a[i] !== b[i])
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Field-level structural stabilization for a `useCurrent` result.
|
|
20
|
+
*
|
|
21
|
+
* Walks the next result keys and, for any field whose value is
|
|
22
|
+
* structurally equal to the previous render's value, reuses the
|
|
23
|
+
* previous reference. If every field reuses the previous reference
|
|
24
|
+
* AND the key set is unchanged, returns the previous top-level
|
|
25
|
+
* object as-is. Otherwise, returns a fresh object whose stable fields
|
|
26
|
+
* still carry their previous reference.
|
|
27
|
+
*
|
|
28
|
+
* Result: downstream `useMemo([current.host])` / `useEffect` keyed
|
|
29
|
+
* off a specific field only re-fire when that field changes — not
|
|
30
|
+
* when a sibling field changes, and not when a new event push leaves
|
|
31
|
+
* the aggregate unchanged.
|
|
32
|
+
*/
|
|
33
|
+
function stabilizeFields(prev, next) {
|
|
34
|
+
if (prev === null)
|
|
35
|
+
return next;
|
|
36
|
+
const prevKeys = Object.keys(prev);
|
|
37
|
+
const nextKeys = Object.keys(next);
|
|
38
|
+
if (prevKeys.length !== nextKeys.length)
|
|
39
|
+
return next;
|
|
40
|
+
const result = {};
|
|
41
|
+
let anyFieldChanged = false;
|
|
42
|
+
for (const key of nextKeys) {
|
|
43
|
+
if (!Object.prototype.hasOwnProperty.call(prev, key))
|
|
44
|
+
return next;
|
|
45
|
+
const prevValue = prev[key];
|
|
46
|
+
const nextValue = next[key];
|
|
47
|
+
if (prevValue === nextValue) {
|
|
48
|
+
result[key] = prevValue;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(prevValue) &&
|
|
52
|
+
Array.isArray(nextValue) &&
|
|
53
|
+
arraysEqual(prevValue, nextValue)) {
|
|
54
|
+
// Arrays with identical contents — reuse the previous reference
|
|
55
|
+
// so field-level dependency arrays stay stable.
|
|
56
|
+
result[key] = prevValue;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
result[key] = nextValue;
|
|
60
|
+
anyFieldChanged = true;
|
|
61
|
+
}
|
|
62
|
+
// Every field reused the previous reference — return the original
|
|
63
|
+
// top-level object so the whole-result consumer (`useEffect([current])`)
|
|
64
|
+
// also stays stable.
|
|
65
|
+
return anyFieldChanged ? result : prev;
|
|
66
|
+
}
|
|
3
67
|
/**
|
|
4
68
|
* Subscribe to a live source and return the current value of a reducer
|
|
5
69
|
* mapping, updated on a throttle. Equivalent to
|
|
@@ -18,11 +82,19 @@ import { useSnapshot, } from './useSnapshot.js';
|
|
|
18
82
|
* Returns a stable-shape object while the source has no events (every
|
|
19
83
|
* mapped field is `undefined`), so destructuring on first render is
|
|
20
84
|
* safe.
|
|
85
|
+
*
|
|
86
|
+
* **Reference stability**: when a new event push leaves the reduce
|
|
87
|
+
* output structurally unchanged (same scalar values, same-length arrays
|
|
88
|
+
* with same elements), the previous result reference is returned
|
|
89
|
+
* unchanged. Downstream `useMemo([value])` and `useEffect([value])` only
|
|
90
|
+
* re-run when the value actually changes — no need for a manual
|
|
91
|
+
* `.slice()` or deep-compare equality helper at the call site.
|
|
21
92
|
*/
|
|
22
93
|
export function useCurrent(source, mapping, options) {
|
|
23
94
|
const snap = useSnapshot(source, options);
|
|
24
95
|
const tailOpt = options?.tail;
|
|
25
|
-
|
|
96
|
+
const previousResultRef = useRef(null);
|
|
97
|
+
const nextResult = useMemo(() => {
|
|
26
98
|
if (!snap) {
|
|
27
99
|
// Stable empty-shape result so destructuring never explodes on
|
|
28
100
|
// first render.
|
|
@@ -34,5 +106,14 @@ export function useCurrent(source, mapping, options) {
|
|
|
34
106
|
const scoped = tailOpt !== undefined ? snap.tail(tailOpt) : snap;
|
|
35
107
|
return scoped.reduce(mapping);
|
|
36
108
|
}, [snap, tailOpt, mapping]);
|
|
109
|
+
// Field-level structural stabilization. Every field whose value is
|
|
110
|
+
// unchanged reuses its previous reference; the top-level object
|
|
111
|
+
// reuses its reference when *all* fields are stable. Downstream
|
|
112
|
+
// `useMemo([current.host])` keyed off a specific field only re-runs
|
|
113
|
+
// when that field actually changes, and `useEffect([current])` keyed
|
|
114
|
+
// off the whole result only fires on true change.
|
|
115
|
+
const stabilized = stabilizeFields(previousResultRef.current, nextResult);
|
|
116
|
+
previousResultRef.current = stabilized;
|
|
117
|
+
return stabilized;
|
|
37
118
|
}
|
|
38
119
|
//# sourceMappingURL=useCurrent.js.map
|
package/dist/useCurrent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurrent.js","sourceRoot":"","sources":["../src/useCurrent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useCurrent.js","sourceRoot":"","sources":["../src/useCurrent.ts"],"names":[],"mappings":"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"}
|