@isograph/react-disposable-state 0.5.2 → 0.5.5
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/.turbo/turbo-compile-libs.log +5 -5
- package/.turbo/turbo-tsc.log +5 -0
- package/README.md +19 -0
- package/dist/{CacheItem.js → CacheItem.cjs} +11 -8
- package/dist/{CacheItem.d.ts → CacheItem.d.cts} +1 -1
- package/dist/CacheItem.d.cts.map +1 -0
- package/dist/CacheItem.d.mts.map +1 -1
- package/dist/CacheItem.mjs +11 -8
- package/dist/CacheItem.mjs.map +1 -1
- package/dist/{ParentCache.js → ParentCache.cjs} +4 -3
- package/dist/{ParentCache.d.ts → ParentCache.d.cts} +4 -4
- package/dist/ParentCache.d.cts.map +1 -0
- package/dist/ParentCache.d.mts +3 -3
- package/dist/ParentCache.d.mts.map +1 -1
- package/dist/ParentCache.mjs +3 -2
- package/dist/ParentCache.mjs.map +1 -1
- package/dist/{index.js → index.cjs} +14 -10
- package/dist/{index.d.ts → index.d.cts} +10 -8
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +3 -1
- package/dist/{useCachedResponsivePrecommitValue.js → useCachedResponsivePrecommitValue.cjs} +15 -9
- package/dist/{useCachedResponsivePrecommitValue.d.ts → useCachedResponsivePrecommitValue.d.cts} +2 -3
- package/dist/useCachedResponsivePrecommitValue.d.cts.map +1 -0
- package/dist/useCachedResponsivePrecommitValue.d.mts +0 -1
- package/dist/useCachedResponsivePrecommitValue.d.mts.map +1 -1
- package/dist/useCachedResponsivePrecommitValue.mjs +13 -7
- package/dist/useCachedResponsivePrecommitValue.mjs.map +1 -1
- package/dist/{useDisposableState.js → useDisposableState.cjs} +9 -10
- package/dist/{useDisposableState.d.ts → useDisposableState.d.cts} +3 -3
- package/dist/useDisposableState.d.cts.map +1 -0
- package/dist/useDisposableState.d.mts.map +1 -1
- package/dist/useDisposableState.mjs +7 -6
- package/dist/useDisposableState.mjs.map +1 -1
- package/dist/useEffectsRerunWithoutRender.cjs +27 -0
- package/dist/useEffectsRerunWithoutRender.d.cts +19 -0
- package/dist/useEffectsRerunWithoutRender.d.cts.map +1 -0
- package/dist/useEffectsRerunWithoutRender.d.mts +19 -0
- package/dist/useEffectsRerunWithoutRender.d.mts.map +1 -0
- package/dist/useEffectsRerunWithoutRender.mjs +28 -0
- package/dist/useEffectsRerunWithoutRender.mjs.map +1 -0
- package/dist/useHasCommittedRef.cjs +20 -0
- package/dist/useHasCommittedRef.d.cts +14 -0
- package/dist/useHasCommittedRef.d.cts.map +1 -0
- package/dist/useHasCommittedRef.d.mts +4 -1
- package/dist/useHasCommittedRef.d.mts.map +1 -1
- package/dist/useHasCommittedRef.mjs +6 -2
- package/dist/useHasCommittedRef.mjs.map +1 -1
- package/dist/{useLazyDisposableState.js → useLazyDisposableState.cjs} +6 -6
- package/dist/{useLazyDisposableState.d.ts → useLazyDisposableState.d.cts} +3 -4
- package/dist/useLazyDisposableState.d.cts.map +1 -0
- package/dist/useLazyDisposableState.d.mts +0 -1
- package/dist/useLazyDisposableState.d.mts.map +1 -1
- package/dist/useLazyDisposableState.mjs +3 -3
- package/dist/useLazyDisposableState.mjs.map +1 -1
- package/dist/useUpdatableDisposableClearableState.cjs +36 -0
- package/dist/useUpdatableDisposableClearableState.d.cts +26 -0
- package/dist/useUpdatableDisposableClearableState.d.cts.map +1 -0
- package/dist/useUpdatableDisposableClearableState.d.mts +26 -0
- package/dist/useUpdatableDisposableClearableState.d.mts.map +1 -0
- package/dist/useUpdatableDisposableClearableState.mjs +37 -0
- package/dist/useUpdatableDisposableClearableState.mjs.map +1 -0
- package/dist/{useUpdatableDisposableState.js → useUpdatableDisposableState.cjs} +6 -4
- package/dist/{useUpdatableDisposableState.d.ts → useUpdatableDisposableState.d.cts} +1 -1
- package/dist/useUpdatableDisposableState.d.cts.map +1 -0
- package/dist/useUpdatableDisposableState.d.mts.map +1 -1
- package/dist/useUpdatableDisposableState.mjs +5 -1
- package/dist/useUpdatableDisposableState.mjs.map +1 -1
- package/package.json +9 -6
- package/src/CacheItem.test.ts +40 -2
- package/src/CacheItem.ts +1 -0
- package/src/ParentCache.ts +26 -21
- package/src/index.ts +2 -0
- package/src/useCachedResponsivePrecommitValue.test.tsx +8 -3
- package/src/useCachedResponsivePrecommitValue.ts +32 -20
- package/src/useDisposableState.ts +13 -15
- package/src/useEffectsRerunWithoutRender.test.tsx +54 -0
- package/src/useEffectsRerunWithoutRender.ts +23 -0
- package/src/useHasCommittedRef.ts +6 -2
- package/src/useLazyDisposableState.test.tsx +73 -34
- package/src/useLazyDisposableState.ts +4 -5
- package/src/useUpdatableDisposableClearableState.ts +67 -0
- package/src/useUpdatableDisposableState.test.tsx +55 -4
- package/src/useUpdatableDisposableState.ts +2 -0
- package/tsconfig.json +2 -4
- package/vitest.config.ts +8 -0
- package/dist/CacheItem.d.ts.map +0 -1
- package/dist/ParentCache.d.ts.map +0 -1
- package/dist/_virtual/rolldown_runtime.js +0 -25
- package/dist/useCachedResponsivePrecommitValue.d.ts.map +0 -1
- package/dist/useDisposableState.d.ts.map +0 -1
- package/dist/useHasCommittedRef.d.ts +0 -11
- package/dist/useHasCommittedRef.d.ts.map +0 -1
- package/dist/useHasCommittedRef.js +0 -18
- package/dist/useLazyDisposableState.d.ts.map +0 -1
- package/dist/useUpdatableDisposableState.d.ts.map +0 -1
- package/tsconfig.pkg.json +0 -9
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ItemCleanupPair } from '@isograph/disposable-types';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
UNASSIGNED_STATE,
|
|
5
|
+
type UnassignedState,
|
|
6
|
+
useUpdatableDisposableState,
|
|
7
|
+
} from './useUpdatableDisposableState';
|
|
8
|
+
|
|
9
|
+
type UseUpdatableDisposableClearableStateReturnValue<T> = {
|
|
10
|
+
state: T | UnassignedState;
|
|
11
|
+
setState: (pair: ItemCleanupPair<Exclude<T, UnassignedState>>) => void;
|
|
12
|
+
clearState: () => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The item that `clearState` puts in the underlying state. It is never returned
|
|
17
|
+
* from this hook; the hook reports UNASSIGNED_STATE while it is current.
|
|
18
|
+
*/
|
|
19
|
+
const CLEARED_STATE: unique symbol = Symbol();
|
|
20
|
+
type ClearedState = typeof CLEARED_STATE;
|
|
21
|
+
|
|
22
|
+
function noop() {}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* useUpdatableDisposableClearableState
|
|
26
|
+
* - useUpdatableDisposableState, plus clearState.
|
|
27
|
+
* - clearState returns the state to UNASSIGNED_STATE. The item that was in state
|
|
28
|
+
* is disposed on the next commit, exactly as if it had been superseded by
|
|
29
|
+
* setState.
|
|
30
|
+
* - Like setState, clearState throws if called before the initial commit.
|
|
31
|
+
*
|
|
32
|
+
* This is a wrapper around useUpdatableDisposableState: clearing sets a sentinel
|
|
33
|
+
* item with no cleanup, so the underlying hook's commit-time disposal of
|
|
34
|
+
* superseded items disposes the cleared item, and the sentinel is mapped back to
|
|
35
|
+
* UNASSIGNED_STATE on the way out.
|
|
36
|
+
*/
|
|
37
|
+
export function useUpdatableDisposableClearableState<
|
|
38
|
+
T = never,
|
|
39
|
+
>(): UseUpdatableDisposableClearableStateReturnValue<T> {
|
|
40
|
+
const { state, setState } = useUpdatableDisposableState<T | ClearedState>();
|
|
41
|
+
|
|
42
|
+
const clearState = useCallback(() => {
|
|
43
|
+
setState([CLEARED_STATE, noop]);
|
|
44
|
+
}, [setState]);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
clearState,
|
|
48
|
+
setState,
|
|
49
|
+
state: state === CLEARED_STATE ? UNASSIGNED_STATE : state,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
function tsTests() {
|
|
55
|
+
const a = useUpdatableDisposableClearableState();
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
a.setState([UNASSIGNED_STATE, () => {}]);
|
|
58
|
+
// @ts-expect-error
|
|
59
|
+
a.setState(['asdf', () => {}]);
|
|
60
|
+
const b = useUpdatableDisposableClearableState<string | UnassignedState>();
|
|
61
|
+
// @ts-expect-error
|
|
62
|
+
b.setState([UNASSIGNED_STATE, () => {}]);
|
|
63
|
+
b.setState(['asdf', () => {}]);
|
|
64
|
+
// The cleared sentinel is not part of T, so it cannot be set from outside.
|
|
65
|
+
// @ts-expect-error
|
|
66
|
+
b.setState([CLEARED_STATE, () => {}]);
|
|
67
|
+
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ItemCleanupPair } from '@isograph/disposable-types';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import React, {
|
|
4
|
+
type MutableRefObject,
|
|
5
|
+
StrictMode,
|
|
6
|
+
useEffect,
|
|
7
|
+
useLayoutEffect,
|
|
8
|
+
} from 'react';
|
|
2
9
|
import { create } from 'react-test-renderer';
|
|
3
10
|
import { describe, expect, test, vi } from 'vitest';
|
|
4
11
|
import {
|
|
@@ -51,15 +58,59 @@ function promiseAndResolver() {
|
|
|
51
58
|
// not is a bit worrisome.
|
|
52
59
|
async function awaitableCreate(Component, isConcurrent: boolean) {
|
|
53
60
|
const element = create(
|
|
54
|
-
Component
|
|
61
|
+
<StrictMode>{Component}</StrictMode>,
|
|
62
|
+
|
|
55
63
|
isConcurrent ? { unstable_isConcurrent: true } : undefined,
|
|
56
64
|
);
|
|
57
65
|
await shortPromise();
|
|
58
66
|
return element;
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
describe('
|
|
62
|
-
|
|
69
|
+
describe('useUpdatableDisposableState during its first commit', () => {
|
|
70
|
+
// A child's effects run before its parent's effects of the same kind, and every layout effect runs before any
|
|
71
|
+
// passive effect, so a child effect runs after the parent's DOM is committed and before the parent's own effects.
|
|
72
|
+
// DOM event handlers of the parent can also run in that window.
|
|
73
|
+
test.each([
|
|
74
|
+
['useLayoutEffect', useLayoutEffect],
|
|
75
|
+
['useEffect', useEffect],
|
|
76
|
+
])(
|
|
77
|
+
'setState called from a child %s puts the item in state, and the item is disposed on unmount',
|
|
78
|
+
(_effectName, useChildEffect) => {
|
|
79
|
+
const dispose = vi.fn();
|
|
80
|
+
let setStateError: unknown = null;
|
|
81
|
+
function Child({
|
|
82
|
+
setState,
|
|
83
|
+
}: {
|
|
84
|
+
setState: (pair: ItemCleanupPair<number>) => void;
|
|
85
|
+
}) {
|
|
86
|
+
useChildEffect(() => {
|
|
87
|
+
try {
|
|
88
|
+
setState([1, dispose]);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
setStateError = error;
|
|
91
|
+
}
|
|
92
|
+
}, []);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
function Owner() {
|
|
96
|
+
const { state, setState } = useUpdatableDisposableState<number>();
|
|
97
|
+
return (
|
|
98
|
+
<>
|
|
99
|
+
{state === UNASSIGNED_STATE ? 'unassigned' : `item ${state}`}
|
|
100
|
+
<Child setState={setState} />
|
|
101
|
+
</>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const { unmount } = render(<Owner />);
|
|
106
|
+
|
|
107
|
+
expect(setStateError).toBeNull();
|
|
108
|
+
expect(screen.getByText('item 1')).toBeTruthy();
|
|
109
|
+
expect(dispose).not.toHaveBeenCalled();
|
|
110
|
+
unmount();
|
|
111
|
+
expect(dispose).toHaveBeenCalledTimes(1);
|
|
112
|
+
},
|
|
113
|
+
);
|
|
63
114
|
});
|
|
64
115
|
|
|
65
116
|
// Temporarily disable unit tests until flakiness is investigated
|
|
@@ -109,8 +109,10 @@ export function useUpdatableDisposableState<
|
|
|
109
109
|
useEffect(() => {
|
|
110
110
|
return function disposeAllRemainingItems() {
|
|
111
111
|
for (const undisposedICI of undisposedICIs.current) {
|
|
112
|
+
undisposedICIs.current.delete(undisposedICI);
|
|
112
113
|
undisposedICI.cleanup();
|
|
113
114
|
}
|
|
115
|
+
setStateICI(UNASSIGNED_STATE);
|
|
114
116
|
};
|
|
115
117
|
}, []);
|
|
116
118
|
|
package/tsconfig.json
CHANGED
package/vitest.config.ts
ADDED
package/dist/CacheItem.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CacheItem.d.ts","names":[],"sources":["../src/CacheItem.ts"],"sourcesContent":[],"mappings":";;;KAQY,2BAAA;;AAAZ,CAAA;AAGY,KAAA,8BAA8B,CAAA,CAAA,CAAA,GAAA;EAQ9B,IAAA,EAAA,gCAA2B;EAa3B,KAAA,EAnBH,CAmBG;EACoB,YAAA,EAAA,GAAA,GAAA,IAAA;EAA5B,oBAAA,EAAA,MAAA;CAC+B;AAA/B,KAfQ,2BAeR,CAAA,CAAA,CAAA,GAAA;EACA,IAAA,EAAA,6BAAA;EAA2B,KAAA,EAdtB,CAcsB;EAEnB,YAAA,EAAA,GAAA,GAAgB,IAAA;EA+Bf,qBAAS,EAAA,GAAA,GAAA,IAAA;EAUD,oBAAA,EAAA,MAAA;EAAR,oBAAA,EAAA,MAAA;CACc;AACd,KAhDD,cAgDC,CAAA,CAAA,CAAA,GA/CT,2BA+CS,CA/CmB,CA+CnB,CAAA,GA9CT,8BA8CS,CA9CsB,CA8CtB,CAAA,GA7CT,2BA6CS;AAgBC,KA3DF,gBAAA,GA2DE;EAkBgB,mBAAA,EAAA,MAAA;CACT;;;;;AAyPrB;;;;;;;;;;;;;;;;;;;;cAxSa;;;uBAUA,QAAQ,2BACM,oBACd;cAgBC;yDAkBgB,YACzB,gBAAgB;qBA+EA;qBAqEA;;;;iBAqGL,+CACL,QAAQ,2BACM,oBACd,2BACP,UAAU,IAAI"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ParentCache.d.ts","names":[],"sources":["../src/ParentCache.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2BA;;;;;;;;;;;;;;cAAa;;;uBAMU,QAAQ;;;;;;;;;;;oCAcK,gBAAgB;sCAMd,UAAU,IAAI,GAAG;;;iBAsCtC,QAAQ"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//#region rolldown:runtime
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
|
|
25
|
-
exports.__toESM = __toESM;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCachedResponsivePrecommitValue.d.ts","names":[],"sources":["../src/useCachedResponsivePrecommitValue.ts"],"sourcesContent":[],"mappings":";;;;;;;AAsCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,kDACD,YAAY,qBACR,gBAAgB;SACvB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useDisposableState.d.ts","names":[],"sources":["../src/useDisposableState.ts"],"sourcesContent":[],"mappings":";;;;;KAUK;SACI;EADJ,QAAA,EAAA,CAAA,IAAA,EAEc,eAFd,CAE8B,OAF9B,CAEsC,CAFA,EAEG,eAFH,CAAA,CAAA,EAAA,GAAA,IAAA;CAClC;AACkC,iBAG3B,kBAH2B,CAAA,IAAA,KAAA,CAAA,CAAA,WAAA,EAI5B,WAJ4B,CAIhB,CAJgB,CAAA,CAAA,EAKxC,sCALwC,CAKD,CALC,CAAA"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { MutableRefObject } from "react";
|
|
2
|
-
|
|
3
|
-
//#region src/useHasCommittedRef.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns true if the component has committed, false otherwise.
|
|
7
|
-
*/
|
|
8
|
-
declare function useHasCommittedRef(): MutableRefObject<boolean>;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { useHasCommittedRef };
|
|
11
|
-
//# sourceMappingURL=useHasCommittedRef.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useHasCommittedRef.d.ts","names":[],"sources":["../src/useHasCommittedRef.ts"],"sourcesContent":[],"mappings":";;;;;;AAKA;iBAAgB,kBAAA,CAAA,GAAsB"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.js');
|
|
2
|
-
let react = require("react");
|
|
3
|
-
react = require_rolldown_runtime.__toESM(react);
|
|
4
|
-
|
|
5
|
-
//#region src/useHasCommittedRef.ts
|
|
6
|
-
/**
|
|
7
|
-
* Returns true if the component has committed, false otherwise.
|
|
8
|
-
*/
|
|
9
|
-
function useHasCommittedRef() {
|
|
10
|
-
const hasCommittedRef = (0, react.useRef)(false);
|
|
11
|
-
(0, react.useEffect)(() => {
|
|
12
|
-
hasCommittedRef.current = true;
|
|
13
|
-
}, []);
|
|
14
|
-
return hasCommittedRef;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
//#endregion
|
|
18
|
-
exports.useHasCommittedRef = useHasCommittedRef;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useLazyDisposableState.d.ts","names":[],"sources":["../src/useLazyDisposableState.ts"],"sourcesContent":[],"mappings":";;;;;;;AAiBA;;;;;;;iBAAgB,uCACD,YAAY,QAAQ,GAAG;SAE7B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdatableDisposableState.d.ts","names":[],"sources":["../src/useUpdatableDisposableState.ts"],"sourcesContent":[],"mappings":";;;cAIa;KACD,eAAA,UAAyB;AADrC,KAGK,sCAHkD,CAAA,CAAA,CAAA,GAAA;EAC3C,KAAA,EAGH,CAHG,GAGC,eAHc;EAEtB,QAAA,EAAA,CAAA,IAAA,EAEc,eAFd,CAE8B,OAF9B,CAEsC,CAFA,EAEG,eAFH,CAAA,CAAA,EAAA,GAAA,IAAA;CAClC;;;;;;;AAoDT;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,0CAEX,uCAAuC"}
|