@t8/react-pending 1.1.2 → 1.2.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/README.md CHANGED
@@ -12,14 +12,14 @@ Self-contained async action state management for React apps
12
12
 
13
13
  export let ItemList = () => {
14
14
  let [items, setItems] = useState([]);
15
- + let { complete, error, track } = usePendingState("fetch-items");
15
+ + let { initial, pending, error, track } = usePendingState("fetch-items");
16
16
 
17
17
  useEffect(() => {
18
18
  - fetchItems().then(setItems);
19
19
  + track(fetchItems()).then(setItems);
20
20
  }, [fetchItems, track]);
21
21
 
22
- + if (!complete) return <p>Loading...</p>;
22
+ + if (initial || pending) return <p>Loading...</p>;
23
23
  + if (error) return <p>An error occurred</p>;
24
24
 
25
25
  return <ul>{items.map(/* ... */)}</ul>;
@@ -40,14 +40,14 @@ In our setup, there are two components rendering their content with regard to th
40
40
 
41
41
  export let ItemList = () => {
42
42
  let [items, setItems] = useState([]);
43
- + let { complete, error, track } = usePendingState("fetch-items");
43
+ + let { initial, pending, error, track } = usePendingState("fetch-items");
44
44
 
45
45
  useEffect(() => {
46
46
  - fetchItems().then(setItems);
47
47
  + track(fetchItems()).then(setItems);
48
48
  }, [fetchItems, track]);
49
49
 
50
- + if (!complete) return <p>Loading...</p>;
50
+ + if (initial || pending) return <p>Loading...</p>;
51
51
  + if (error) return <p>An error occurred</p>;
52
52
 
53
53
  return <ul>{items.map(/* ... */)}</ul>;
@@ -58,10 +58,10 @@ In our setup, there are two components rendering their content with regard to th
58
58
  + import { usePendingState } from "@t8/react-pending";
59
59
 
60
60
  export let Status = () => {
61
- + let { initialized, complete, error } = usePendingState("fetch-items");
61
+ + let { initial, pending, error } = usePendingState("fetch-items");
62
62
 
63
- if (!initialized) return null;
64
- if (!complete) return <>Busy</>;
63
+ if (initial) return null;
64
+ if (pending) return <>Busy</>;
65
65
  if (error) return <>Error</>;
66
66
 
67
67
  return <>OK</>;
@@ -79,8 +79,8 @@ In our setup, there are two components rendering their content with regard to th
79
79
  Omit the custom string key parameter of `usePendingState()` to scope the pending state locally within a single component:
80
80
 
81
81
  ```diff
82
- - let { complete } = usePendingState("fetch-items"); // shared
83
- + let { complete } = usePendingState(); // local
82
+ - let { initial, pending, error } = usePendingState("fetch-items"); // shared
83
+ + let { initial, pending, error } = usePendingState(); // local
84
84
  ```
85
85
 
86
86
  ## Silent tracking of background actions and optimistic updates
@@ -90,7 +90,7 @@ Omit the custom string key parameter of `usePendingState()` to scope the pending
90
90
  + track(fetchItems(), { silent: true })
91
91
  ```
92
92
 
93
- ⬥ This option prevents `complete` from switching to `false` in the pending state.
93
+ ⬥ This option prevents the `pending` property from switching to `false` in the pending state.
94
94
 
95
95
  ## Delayed pending state
96
96
 
@@ -127,7 +127,7 @@ Omit the custom string key parameter of `usePendingState()` to scope the pending
127
127
 
128
128
  ```diff
129
129
  + let initialState = {
130
- + "fetch-items": { initialized: true, complete: true },
130
+ + "fetch-items": { initial: false, pending: true },
131
131
  + };
132
132
 
133
133
  - <PendingStateProvider>
package/dist/index.cjs CHANGED
@@ -18,10 +18,10 @@ const PendingStateProvider = ({ value, children }) => {
18
18
  });
19
19
  };
20
20
 
21
- function createState(initialized = false, complete = false, error) {
21
+ function createState(initial = true, pending = false, error) {
22
22
  return {
23
- initialized,
24
- complete,
23
+ initial,
24
+ pending,
25
25
  error,
26
26
  time: Date.now()
27
27
  };
@@ -29,15 +29,16 @@ function createState(initialized = false, complete = false, error) {
29
29
  /**
30
30
  * Returns an instance of an action's state and the functions to update it.
31
31
  *
32
- * @param store - A unique store key or a store. Providing a store
32
+ * @param store - An optional unique string key or a store. Providing a
33
33
  * key or a shared store allows to share the state across multiple
34
- * components.
34
+ * components. If omitted, the pending state stays locally scoped to the
35
+ * component where the hook is used.
35
36
  *
36
- * @returns `{ initialized, complete, error, track, update }`, where
37
- * - `initialized`, `complete`, `error` reflect the current action's state;
37
+ * @returns `{ initial, pending, error, track, update }`, where
38
+ * - `initial`, `pending`, `error` reflect the current action's state;
38
39
  * - `track(action, options?)` tracks the `actions`'s state;
39
40
  * - `update(nextState | ((state) => nextState))` can be used to replace
40
- * the current `state` value directly with an another state value.
41
+ * the current pending state directly with an another value.
41
42
  */
42
43
  function usePendingState(store) {
43
44
  let storeMap = (0, react.useContext)(PendingStateContext);
@@ -68,12 +69,12 @@ function usePendingState(store) {
68
69
  let delay = options?.delay;
69
70
  if (delay === void 0) setState((prevState) => ({
70
71
  ...prevState,
71
- ...createState(true, false)
72
+ ...createState(false, true)
72
73
  }));
73
74
  else delayedPending = setTimeout(() => {
74
75
  setState((prevState) => ({
75
76
  ...prevState,
76
- ...createState(true, false)
77
+ ...createState(false, true)
77
78
  }));
78
79
  delayedPending = null;
79
80
  }, delay);
@@ -82,21 +83,21 @@ function usePendingState(store) {
82
83
  if (delayedPending !== null) clearTimeout(delayedPending);
83
84
  setState((prevState) => ({
84
85
  ...prevState,
85
- ...createState(true, true)
86
+ ...createState(false, false)
86
87
  }));
87
88
  return resolvedValue;
88
89
  }).catch((error) => {
89
90
  if (delayedPending !== null) clearTimeout(delayedPending);
90
91
  setState((prevState) => ({
91
92
  ...prevState,
92
- ...createState(true, true, error)
93
+ ...createState(false, false, error)
93
94
  }));
94
95
  if (options?.throws) throw error;
95
96
  });
96
97
  }
97
98
  setState((prevState) => ({
98
99
  ...prevState,
99
- ...createState(true, true)
100
+ ...createState(false, false)
100
101
  }));
101
102
  return value;
102
103
  }, [setState]);
package/dist/index.d.ts CHANGED
@@ -4,10 +4,10 @@ import { SetStoreValue, Store } from "@t8/react-store";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
6
6
  type PendingState = {
7
- initialized?: boolean | undefined;
8
- complete?: boolean | undefined;
9
- time?: number | undefined;
7
+ initial?: boolean | undefined;
8
+ pending?: boolean | undefined;
10
9
  error?: unknown;
10
+ time?: number | undefined;
11
11
  };
12
12
 
13
13
  declare const PendingStateContext: react0.Context<Map<string, Store<PendingState>>>;
@@ -26,12 +26,12 @@ type TrackOptions = {
26
26
  * Whether to track the action state silently (e.g. with a background
27
27
  * action or an optimistic update).
28
28
  *
29
- * When set to `true`, the state's `complete` property doesn't switch
30
- * to `false` in the pending state.
29
+ * When set to `true`, the state's `pending` property doesn't switch
30
+ * to `true` in the pending state.
31
31
  */
32
32
  silent?: boolean;
33
33
  /**
34
- * Delays switching the action state's `complete` property to `false`
34
+ * Delays switching the action state's `pending` property to `true`
35
35
  * in the pending state by the given number of milliseconds.
36
36
  *
37
37
  * Use case: to avoid flashing a process indicator if the action is
@@ -47,15 +47,16 @@ type TrackOptions = {
47
47
  /**
48
48
  * Returns an instance of an action's state and the functions to update it.
49
49
  *
50
- * @param store - A unique store key or a store. Providing a store
50
+ * @param store - An optional unique string key or a store. Providing a
51
51
  * key or a shared store allows to share the state across multiple
52
- * components.
52
+ * components. If omitted, the pending state stays locally scoped to the
53
+ * component where the hook is used.
53
54
  *
54
- * @returns `{ initialized, complete, error, track, update }`, where
55
- * - `initialized`, `complete`, `error` reflect the current action's state;
55
+ * @returns `{ initial, pending, error, track, update }`, where
56
+ * - `initial`, `pending`, `error` reflect the current action's state;
56
57
  * - `track(action, options?)` tracks the `actions`'s state;
57
58
  * - `update(nextState | ((state) => nextState))` can be used to replace
58
- * the current `state` value directly with an another state value.
59
+ * the current pending state directly with an another value.
59
60
  */
60
61
  declare function usePendingState(store?: string | Store<PendingState> | null): PendingState & {
61
62
  track: <T>(value: T) => T;
package/dist/index.mjs CHANGED
@@ -18,10 +18,10 @@ const PendingStateProvider = ({ value, children }) => {
18
18
  });
19
19
  };
20
20
 
21
- function createState(initialized = false, complete = false, error) {
21
+ function createState(initial = true, pending = false, error) {
22
22
  return {
23
- initialized,
24
- complete,
23
+ initial,
24
+ pending,
25
25
  error,
26
26
  time: Date.now()
27
27
  };
@@ -29,15 +29,16 @@ function createState(initialized = false, complete = false, error) {
29
29
  /**
30
30
  * Returns an instance of an action's state and the functions to update it.
31
31
  *
32
- * @param store - A unique store key or a store. Providing a store
32
+ * @param store - An optional unique string key or a store. Providing a
33
33
  * key or a shared store allows to share the state across multiple
34
- * components.
34
+ * components. If omitted, the pending state stays locally scoped to the
35
+ * component where the hook is used.
35
36
  *
36
- * @returns `{ initialized, complete, error, track, update }`, where
37
- * - `initialized`, `complete`, `error` reflect the current action's state;
37
+ * @returns `{ initial, pending, error, track, update }`, where
38
+ * - `initial`, `pending`, `error` reflect the current action's state;
38
39
  * - `track(action, options?)` tracks the `actions`'s state;
39
40
  * - `update(nextState | ((state) => nextState))` can be used to replace
40
- * the current `state` value directly with an another state value.
41
+ * the current pending state directly with an another value.
41
42
  */
42
43
  function usePendingState(store) {
43
44
  let storeMap = useContext(PendingStateContext);
@@ -68,12 +69,12 @@ function usePendingState(store) {
68
69
  let delay = options?.delay;
69
70
  if (delay === void 0) setState((prevState) => ({
70
71
  ...prevState,
71
- ...createState(true, false)
72
+ ...createState(false, true)
72
73
  }));
73
74
  else delayedPending = setTimeout(() => {
74
75
  setState((prevState) => ({
75
76
  ...prevState,
76
- ...createState(true, false)
77
+ ...createState(false, true)
77
78
  }));
78
79
  delayedPending = null;
79
80
  }, delay);
@@ -82,21 +83,21 @@ function usePendingState(store) {
82
83
  if (delayedPending !== null) clearTimeout(delayedPending);
83
84
  setState((prevState) => ({
84
85
  ...prevState,
85
- ...createState(true, true)
86
+ ...createState(false, false)
86
87
  }));
87
88
  return resolvedValue;
88
89
  }).catch((error) => {
89
90
  if (delayedPending !== null) clearTimeout(delayedPending);
90
91
  setState((prevState) => ({
91
92
  ...prevState,
92
- ...createState(true, true, error)
93
+ ...createState(false, false, error)
93
94
  }));
94
95
  if (options?.throws) throw error;
95
96
  });
96
97
  }
97
98
  setState((prevState) => ({
98
99
  ...prevState,
99
- ...createState(true, true)
100
+ ...createState(false, false)
100
101
  }));
101
102
  return value;
102
103
  }, [setState]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8/react-pending",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Self-contained async action state management for React apps",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -1,6 +1,6 @@
1
1
  export type PendingState = {
2
- initialized?: boolean | undefined;
3
- complete?: boolean | undefined;
4
- time?: number | undefined;
2
+ initial?: boolean | undefined;
3
+ pending?: boolean | undefined;
5
4
  error?: unknown;
5
+ time?: number | undefined;
6
6
  };
@@ -4,13 +4,13 @@ import type { PendingState } from "./PendingState.ts";
4
4
  import { PendingStateContext } from "./PendingStateContext.ts";
5
5
 
6
6
  function createState(
7
- initialized = false,
8
- complete = false,
7
+ initial = true,
8
+ pending = false,
9
9
  error?: unknown,
10
10
  ): PendingState {
11
11
  return {
12
- initialized,
13
- complete,
12
+ initial,
13
+ pending,
14
14
  error,
15
15
  time: Date.now(),
16
16
  };
@@ -21,12 +21,12 @@ export type TrackOptions = {
21
21
  * Whether to track the action state silently (e.g. with a background
22
22
  * action or an optimistic update).
23
23
  *
24
- * When set to `true`, the state's `complete` property doesn't switch
25
- * to `false` in the pending state.
24
+ * When set to `true`, the state's `pending` property doesn't switch
25
+ * to `true` in the pending state.
26
26
  */
27
27
  silent?: boolean;
28
28
  /**
29
- * Delays switching the action state's `complete` property to `false`
29
+ * Delays switching the action state's `pending` property to `true`
30
30
  * in the pending state by the given number of milliseconds.
31
31
  *
32
32
  * Use case: to avoid flashing a process indicator if the action is
@@ -43,15 +43,16 @@ export type TrackOptions = {
43
43
  /**
44
44
  * Returns an instance of an action's state and the functions to update it.
45
45
  *
46
- * @param store - A unique store key or a store. Providing a store
46
+ * @param store - An optional unique string key or a store. Providing a
47
47
  * key or a shared store allows to share the state across multiple
48
- * components.
48
+ * components. If omitted, the pending state stays locally scoped to the
49
+ * component where the hook is used.
49
50
  *
50
- * @returns `{ initialized, complete, error, track, update }`, where
51
- * - `initialized`, `complete`, `error` reflect the current action's state;
51
+ * @returns `{ initial, pending, error, track, update }`, where
52
+ * - `initial`, `pending`, `error` reflect the current action's state;
52
53
  * - `track(action, options?)` tracks the `actions`'s state;
53
54
  * - `update(nextState | ((state) => nextState))` can be used to replace
54
- * the current `state` value directly with an another state value.
55
+ * the current pending state directly with an another value.
55
56
  */
56
57
  export function usePendingState(
57
58
  store?: string | Store<PendingState> | null,
@@ -97,13 +98,13 @@ export function usePendingState(
97
98
  if (delay === undefined)
98
99
  setState((prevState) => ({
99
100
  ...prevState,
100
- ...createState(true, false),
101
+ ...createState(false, true),
101
102
  }));
102
103
  else
103
104
  delayedPending = setTimeout(() => {
104
105
  setState((prevState) => ({
105
106
  ...prevState,
106
- ...createState(true, false),
107
+ ...createState(false, true),
107
108
  }));
108
109
 
109
110
  delayedPending = null;
@@ -116,7 +117,7 @@ export function usePendingState(
116
117
 
117
118
  setState((prevState) => ({
118
119
  ...prevState,
119
- ...createState(true, true),
120
+ ...createState(false, false),
120
121
  }));
121
122
 
122
123
  return resolvedValue;
@@ -126,7 +127,7 @@ export function usePendingState(
126
127
 
127
128
  setState((prevState) => ({
128
129
  ...prevState,
129
- ...createState(true, true, error),
130
+ ...createState(false, false, error),
130
131
  }));
131
132
 
132
133
  if (options?.throws) throw error;
@@ -135,7 +136,7 @@ export function usePendingState(
135
136
 
136
137
  setState((prevState) => ({
137
138
  ...prevState,
138
- ...createState(true, true),
139
+ ...createState(false, false),
139
140
  }));
140
141
 
141
142
  return value;