@xyo-network/react-shared 2.54.0 → 2.54.1
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/cjs/hooks/usePayloadHash.js +3 -3
- package/dist/cjs/hooks/usePayloadHash.js.map +1 -1
- package/dist/cjs/hooks/usePromise.js +74 -54
- package/dist/cjs/hooks/usePromise.js.map +1 -1
- package/dist/docs.json +34320 -8183
- package/dist/esm/hooks/usePayloadHash.js +3 -3
- package/dist/esm/hooks/usePayloadHash.js.map +1 -1
- package/dist/esm/hooks/usePromise.js +76 -55
- package/dist/esm/hooks/usePromise.js.map +1 -1
- package/dist/types/hooks/usePayloadHash.d.ts +3 -2
- package/dist/types/hooks/usePayloadHash.d.ts.map +1 -1
- package/dist/types/hooks/usePromise.d.ts +2 -1
- package/dist/types/hooks/usePromise.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/hooks/usePayloadHash.ts +9 -7
- package/src/hooks/usePromise.ts +77 -67
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PayloadHasher } from '@xyo-network/core';
|
|
2
2
|
import { usePromise } from './usePromise';
|
|
3
3
|
export const usePayloadHash = (payload, dependencies) => {
|
|
4
|
-
return usePromise(payload ? PayloadHasher.hashAsync(payload) : undefined,
|
|
4
|
+
return usePromise(() => (payload ? PayloadHasher.hashAsync(payload) : undefined), dependencies)[0];
|
|
5
5
|
};
|
|
6
6
|
export const usePayloadHashes = (payloads, dependencies) => {
|
|
7
|
-
return usePromise(payloads
|
|
7
|
+
return usePromise(() => payloads
|
|
8
8
|
? Promise.all(payloads.map(async (payload) => [payload, await PayloadHasher.hashAsync(payload)]))
|
|
9
|
-
: undefined,
|
|
9
|
+
: undefined, dependencies)[0];
|
|
10
10
|
};
|
|
11
11
|
//# sourceMappingURL=usePayloadHash.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePayloadHash.js","sourceRoot":"","sources":["../../../src/hooks/usePayloadHash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"usePayloadHash.js","sourceRoot":"","sources":["../../../src/hooks/usePayloadHash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAIjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,CAAC,MAAM,cAAc,GAAG,CAA2B,OAAoC,EAAE,YAA6B,EAAE,EAAE;IAC9H,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;AACpG,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAA2B,QAAuC,EAAE,YAA6B,EAAE,EAAE;IACnI,OAAO,UAAU,CACf,GAAG,EAAE,CACH,QAAQ;QACN,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAA8B,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9H,CAAC,CAAC,SAAS,EACf,YAAY,CACb,CAAC,CAAC,CAAC,CAAA;AACN,CAAC,CAAA"}
|
|
@@ -1,74 +1,95 @@
|
|
|
1
1
|
// Inspired from https://github.com/bsonntag/react-use-promise
|
|
2
|
-
import {
|
|
3
|
-
import { useReducer } from 'react';
|
|
2
|
+
import { useEffect, useMemo, useReducer } from 'react';
|
|
4
3
|
export var State;
|
|
5
4
|
(function (State) {
|
|
6
5
|
State["pending"] = "pending";
|
|
7
6
|
State["rejected"] = "rejected";
|
|
8
7
|
State["resolved"] = "resolved";
|
|
9
8
|
})(State || (State = {}));
|
|
10
|
-
const defaultState = {
|
|
11
|
-
error: undefined,
|
|
12
|
-
result: undefined,
|
|
13
|
-
state: State.pending,
|
|
14
|
-
};
|
|
15
|
-
const reducer = (_state, action) => {
|
|
16
|
-
switch (action.type) {
|
|
17
|
-
case State.pending:
|
|
18
|
-
return defaultState;
|
|
19
|
-
case State.resolved:
|
|
20
|
-
return {
|
|
21
|
-
error: undefined,
|
|
22
|
-
result: action.payload,
|
|
23
|
-
state: State.resolved,
|
|
24
|
-
};
|
|
25
|
-
case State.rejected:
|
|
26
|
-
return {
|
|
27
|
-
error: action.payload,
|
|
28
|
-
result: undefined,
|
|
29
|
-
state: State.rejected,
|
|
30
|
-
};
|
|
31
|
-
default:
|
|
32
|
-
throw Error(`Error parsing action ${JSON.stringify(action, null, 2)}`);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
9
|
/**
|
|
36
10
|
* usePromise -
|
|
37
11
|
*/
|
|
38
|
-
export const usePromise = (promise, dependencies = []) => {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
12
|
+
export const usePromise = (promise, dependencies = [], debug = undefined) => {
|
|
13
|
+
const promiseMemo = useMemo(() => promise?.(), dependencies);
|
|
14
|
+
const defaultState = {
|
|
15
|
+
error: undefined,
|
|
16
|
+
result: undefined,
|
|
17
|
+
state: State.pending,
|
|
18
|
+
};
|
|
19
|
+
const reducer = (_state, action) => {
|
|
20
|
+
switch (action.type) {
|
|
21
|
+
case State.pending:
|
|
22
|
+
return defaultState;
|
|
23
|
+
case State.resolved:
|
|
24
|
+
return {
|
|
25
|
+
error: undefined,
|
|
26
|
+
result: action.payload,
|
|
27
|
+
state: State.resolved,
|
|
28
|
+
};
|
|
29
|
+
case State.rejected:
|
|
30
|
+
return {
|
|
31
|
+
error: action.error,
|
|
32
|
+
result: undefined,
|
|
33
|
+
state: State.rejected,
|
|
34
|
+
};
|
|
35
|
+
default:
|
|
36
|
+
throw Error(`Error parsing action ${JSON.stringify(action, null, 2)}`);
|
|
45
37
|
}
|
|
46
|
-
|
|
38
|
+
};
|
|
39
|
+
const [{ error, result, state }, dispatch] = useReducer(reducer, defaultState);
|
|
40
|
+
if (debug)
|
|
41
|
+
console.debug(`usePromise [${debug}] Main Function`);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
let cancelled = false;
|
|
47
44
|
dispatch({ type: State.pending });
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
if (debug)
|
|
46
|
+
console.debug(`usePromise [${debug}] useEffect [cancelled: ${cancelled}]`);
|
|
47
|
+
if (promiseMemo instanceof Promise) {
|
|
48
|
+
promiseMemo
|
|
49
|
+
.then((payload) => {
|
|
50
|
+
if (debug)
|
|
51
|
+
console.debug(`usePromise [${debug}] then [cancelled: ${cancelled}]`);
|
|
52
|
+
!cancelled ??
|
|
53
|
+
dispatch({
|
|
54
|
+
error: undefined,
|
|
55
|
+
payload,
|
|
56
|
+
type: State.resolved,
|
|
57
|
+
});
|
|
58
|
+
})
|
|
59
|
+
.catch((error) => {
|
|
60
|
+
if (debug)
|
|
61
|
+
console.debug(`usePromise [${debug}] catch [cancelled: ${cancelled}]`);
|
|
62
|
+
!cancelled ??
|
|
63
|
+
dispatch({
|
|
64
|
+
error: error,
|
|
65
|
+
payload: undefined,
|
|
66
|
+
type: State.rejected,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (promiseMemo) {
|
|
71
|
+
dispatch({
|
|
72
|
+
error: undefined,
|
|
73
|
+
payload: promiseMemo,
|
|
74
|
+
type: State.resolved,
|
|
75
|
+
});
|
|
56
76
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
else {
|
|
78
|
+
if (debug)
|
|
79
|
+
console.debug(`usePromise [${debug}] no-promise [cancelled: ${cancelled}]`);
|
|
80
|
+
!cancelled ??
|
|
81
|
+
dispatch({
|
|
82
|
+
error: undefined,
|
|
83
|
+
payload: undefined,
|
|
84
|
+
type: State.resolved,
|
|
85
|
+
});
|
|
64
86
|
}
|
|
65
87
|
return () => {
|
|
66
|
-
|
|
88
|
+
if (debug)
|
|
89
|
+
console.debug(`usePromise [${debug}] useEffect callback`);
|
|
90
|
+
cancelled = true;
|
|
67
91
|
};
|
|
68
|
-
},
|
|
69
|
-
// eslint can't inspect the array to verify dependencies are missing
|
|
70
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
-
dependencies);
|
|
92
|
+
}, [promiseMemo]);
|
|
72
93
|
return [result, error, state];
|
|
73
94
|
};
|
|
74
95
|
//# sourceMappingURL=usePromise.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePromise.js","sourceRoot":"","sources":["../../../src/hooks/usePromise.ts"],"names":[],"mappings":"AAAA,8DAA8D;
|
|
1
|
+
{"version":3,"file":"usePromise.js","sourceRoot":"","sources":["../../../src/hooks/usePromise.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAG9D,OAAO,EAA2B,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAE/E,MAAM,CAAN,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,4BAAmB,CAAA;IACnB,8BAAqB,CAAA;IACrB,8BAAqB,CAAA;AACvB,CAAC,EAJW,KAAK,KAAL,KAAK,QAIhB;AAUD;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAA8C,EAC9C,eAA+B,EAAE,EACjC,QAA4B,SAAS,EACwB,EAAE;IAC/D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,YAAY,CAAC,CAAA;IAE5D,MAAM,YAAY,GAA0B;QAC1C,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,KAAK,CAAC,OAAO;KACrB,CAAA;IAED,MAAM,OAAO,GAAoD,CAAC,MAA6B,EAAE,MAAuB,EAAE,EAAE;QAC1H,QAAQ,MAAM,CAAC,IAAI,EAAE;YACnB,KAAK,KAAK,CAAC,OAAO;gBAChB,OAAO,YAAY,CAAA;YAErB,KAAK,KAAK,CAAC,QAAQ;gBACjB,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,MAAM,CAAC,OAAO;oBACtB,KAAK,EAAE,KAAK,CAAC,QAAQ;iBACtB,CAAA;YAEH,KAAK,KAAK,CAAC,QAAQ;gBACjB,OAAO;oBACL,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,KAAK,CAAC,QAAQ;iBACtB,CAAA;YAEH;gBACE,MAAM,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;SACzE;IACH,CAAC,CAAA;IAED,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAE9E,IAAI,KAAK;QAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,iBAAiB,CAAC,CAAA;IAE/D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACjC,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,2BAA2B,SAAS,GAAG,CAAC,CAAA;QACrF,IAAI,WAAW,YAAY,OAAO,EAAE;YAClC,WAAW;iBACR,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChB,IAAI,KAAK;oBAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,sBAAsB,SAAS,GAAG,CAAC,CAAA;gBAChF,CAAC,SAAS;oBACR,QAAQ,CAAC;wBACP,KAAK,EAAE,SAAS;wBAChB,OAAO;wBACP,IAAI,EAAE,KAAK,CAAC,QAAQ;qBACrB,CAAC,CAAA;YACN,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,IAAI,KAAK;oBAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,uBAAuB,SAAS,GAAG,CAAC,CAAA;gBACjF,CAAC,SAAS;oBACR,QAAQ,CAAC;wBACP,KAAK,EAAE,KAAc;wBACrB,OAAO,EAAE,SAAS;wBAClB,IAAI,EAAE,KAAK,CAAC,QAAQ;qBACrB,CAAC,CAAA;YACN,CAAC,CAAC,CAAA;SACL;aAAM,IAAI,WAAW,EAAE;YACtB,QAAQ,CAAC;gBACP,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,WAAW;gBACpB,IAAI,EAAE,KAAK,CAAC,QAAQ;aACrB,CAAC,CAAA;SACH;aAAM;YACL,IAAI,KAAK;gBAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,4BAA4B,SAAS,GAAG,CAAC,CAAA;YACtF,CAAC,SAAS;gBACR,QAAQ,CAAC;oBACP,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,SAAS;oBAClB,IAAI,EAAE,KAAK,CAAC,QAAQ;iBACrB,CAAC,CAAA;SACL;QACD,OAAO,GAAG,EAAE;YACV,IAAI,KAAK;gBAAE,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,sBAAsB,CAAC,CAAA;YACpE,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;AAC/B,CAAC,CAAA"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { DependencyList } from 'react';
|
|
1
2
|
export declare const usePayloadHash: <TPayload extends import("@xyo-network/payload-model").SchemaFields & import("@xyo-network/payload-model").PayloadFields & {
|
|
2
3
|
schema: string;
|
|
3
|
-
}>(payload: TPayload | null | undefined, dependencies?:
|
|
4
|
+
}>(payload: TPayload | null | undefined, dependencies?: DependencyList) => string | undefined;
|
|
4
5
|
export declare const usePayloadHashes: <TPayload extends import("@xyo-network/payload-model").SchemaFields & import("@xyo-network/payload-model").PayloadFields & {
|
|
5
6
|
schema: string;
|
|
6
|
-
}>(payloads: TPayload[] | null | undefined, dependencies?:
|
|
7
|
+
}>(payloads: TPayload[] | null | undefined, dependencies?: DependencyList) => [TPayload, string][] | undefined;
|
|
7
8
|
//# sourceMappingURL=usePayloadHash.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePayloadHash.d.ts","sourceRoot":"","sources":["../../../src/hooks/usePayloadHash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePayloadHash.d.ts","sourceRoot":"","sources":["../../../src/hooks/usePayloadHash.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAItC,eAAO,MAAM,cAAc;;wDAAmF,cAAc,uBAE3H,CAAA;AAED,eAAO,MAAM,gBAAgB;;2DAAsF,cAAc,qCAQhI,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Promisable } from '@xyo-network/promise';
|
|
2
|
+
import { DependencyList } from 'react';
|
|
2
3
|
export declare enum State {
|
|
3
4
|
pending = "pending",
|
|
4
5
|
rejected = "rejected",
|
|
@@ -7,5 +8,5 @@ export declare enum State {
|
|
|
7
8
|
/**
|
|
8
9
|
* usePromise -
|
|
9
10
|
*/
|
|
10
|
-
export declare const usePromise: <TResult>(promise
|
|
11
|
+
export declare const usePromise: <TResult>(promise: () => Promisable<TResult, never> | undefined, dependencies?: DependencyList, debug?: string | undefined) => [TResult | undefined, Error | undefined, State | undefined];
|
|
11
12
|
//# sourceMappingURL=usePromise.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePromise.d.ts","sourceRoot":"","sources":["../../../src/hooks/usePromise.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePromise.d.ts","sourceRoot":"","sources":["../../../src/hooks/usePromise.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,cAAc,EAA2C,MAAM,OAAO,CAAA;AAE/E,oBAAY,KAAK;IACf,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,QAAQ,aAAa;CACtB;AAUD;;GAEG;AACH,eAAO,MAAM,UAAU,0GAGd,MAAM,GAAG,SAAS,gEAoF1B,CAAA"}
|
package/package.json
CHANGED
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"@xyo-network/core": "^2.62.1",
|
|
21
21
|
"@xyo-network/payload-model": "^2.62.1",
|
|
22
22
|
"@xyo-network/promise": "^2.62.1",
|
|
23
|
-
"@xyo-network/react-event": "^2.54.
|
|
23
|
+
"@xyo-network/react-event": "^2.54.1"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@storybook/react": "^7.0.21",
|
|
27
27
|
"@xylabs/react-quick-tip-button": "^2.17.3",
|
|
28
|
-
"@xylabs/ts-scripts-yarn3": "^2.17.
|
|
29
|
-
"@xylabs/tsconfig-react": "^2.17.
|
|
28
|
+
"@xylabs/ts-scripts-yarn3": "^2.17.14",
|
|
29
|
+
"@xylabs/tsconfig-react": "^2.17.14",
|
|
30
30
|
"typescript": "^5.1.3"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
},
|
|
82
82
|
"sideEffects": false,
|
|
83
83
|
"types": "dist/types/index.d.ts",
|
|
84
|
-
"version": "2.54.
|
|
84
|
+
"version": "2.54.1"
|
|
85
85
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { PayloadHasher } from '@xyo-network/core'
|
|
2
2
|
import { Payload } from '@xyo-network/payload-model'
|
|
3
|
+
import { DependencyList } from 'react'
|
|
3
4
|
|
|
4
5
|
import { usePromise } from './usePromise'
|
|
5
6
|
|
|
6
|
-
export const usePayloadHash = <TPayload extends Payload>(payload: TPayload | undefined | null, dependencies?:
|
|
7
|
-
return usePromise(payload ? PayloadHasher.hashAsync(payload) : undefined,
|
|
7
|
+
export const usePayloadHash = <TPayload extends Payload>(payload: TPayload | undefined | null, dependencies?: DependencyList) => {
|
|
8
|
+
return usePromise(() => (payload ? PayloadHasher.hashAsync(payload) : undefined), dependencies)[0]
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export const usePayloadHashes = <TPayload extends Payload>(payloads: TPayload[] | undefined | null, dependencies?:
|
|
11
|
+
export const usePayloadHashes = <TPayload extends Payload>(payloads: TPayload[] | undefined | null, dependencies?: DependencyList) => {
|
|
11
12
|
return usePromise(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
() =>
|
|
14
|
+
payloads
|
|
15
|
+
? Promise.all(payloads.map<Promise<[TPayload, string]>>(async (payload) => [payload, await PayloadHasher.hashAsync(payload)]))
|
|
16
|
+
: undefined,
|
|
17
|
+
dependencies,
|
|
16
18
|
)[0]
|
|
17
19
|
}
|
package/src/hooks/usePromise.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// Inspired from https://github.com/bsonntag/react-use-promise
|
|
2
2
|
|
|
3
|
-
import { useAsyncEffect } from '@xylabs/react-async-effect'
|
|
4
3
|
import { Promisable } from '@xyo-network/promise'
|
|
5
|
-
import { useReducer } from 'react'
|
|
4
|
+
import { DependencyList, Reducer, useEffect, useMemo, useReducer } from 'react'
|
|
6
5
|
|
|
7
6
|
export enum State {
|
|
8
7
|
pending = 'pending',
|
|
@@ -16,85 +15,96 @@ interface PromiseState<T = void> {
|
|
|
16
15
|
state?: State
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
error: undefined,
|
|
21
|
-
result: undefined,
|
|
22
|
-
state: State.pending,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Since the resolved promise value can be anything, any seems appropriate
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
-
type Action = { payload?: any; type: State }
|
|
28
|
-
|
|
29
|
-
const reducer = (_state: PromiseState, action: Action) => {
|
|
30
|
-
switch (action.type) {
|
|
31
|
-
case State.pending:
|
|
32
|
-
return defaultState
|
|
33
|
-
|
|
34
|
-
case State.resolved:
|
|
35
|
-
return {
|
|
36
|
-
error: undefined,
|
|
37
|
-
result: action.payload,
|
|
38
|
-
state: State.resolved,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
case State.rejected:
|
|
42
|
-
return {
|
|
43
|
-
error: action.payload,
|
|
44
|
-
result: undefined,
|
|
45
|
-
state: State.rejected,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
default:
|
|
49
|
-
throw Error(`Error parsing action ${JSON.stringify(action, null, 2)}`)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
18
|
+
type Action<T> = { error?: Error; payload?: T; type: State }
|
|
52
19
|
|
|
53
20
|
/**
|
|
54
21
|
* usePromise -
|
|
55
22
|
*/
|
|
56
23
|
export const usePromise = <TResult>(
|
|
57
|
-
promise
|
|
58
|
-
dependencies:
|
|
24
|
+
promise: () => Promisable<TResult> | undefined,
|
|
25
|
+
dependencies: DependencyList = [],
|
|
26
|
+
debug: string | undefined = undefined,
|
|
59
27
|
): [TResult | undefined, Error | undefined, State | undefined] => {
|
|
60
|
-
const
|
|
28
|
+
const promiseMemo = useMemo(() => promise?.(), dependencies)
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
30
|
+
const defaultState: PromiseState<TResult> = {
|
|
31
|
+
error: undefined,
|
|
32
|
+
result: undefined,
|
|
33
|
+
state: State.pending,
|
|
34
|
+
}
|
|
68
35
|
|
|
69
|
-
|
|
36
|
+
const reducer: Reducer<PromiseState<TResult>, Action<TResult>> = (_state: PromiseState<TResult>, action: Action<TResult>) => {
|
|
37
|
+
switch (action.type) {
|
|
38
|
+
case State.pending:
|
|
39
|
+
return defaultState
|
|
40
|
+
|
|
41
|
+
case State.resolved:
|
|
42
|
+
return {
|
|
43
|
+
error: undefined,
|
|
44
|
+
result: action.payload,
|
|
45
|
+
state: State.resolved,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
case State.rejected:
|
|
49
|
+
return {
|
|
50
|
+
error: action.error,
|
|
51
|
+
result: undefined,
|
|
52
|
+
state: State.rejected,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
default:
|
|
56
|
+
throw Error(`Error parsing action ${JSON.stringify(action, null, 2)}`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
70
59
|
|
|
71
|
-
|
|
60
|
+
const [{ error, result, state }, dispatch] = useReducer(reducer, defaultState)
|
|
72
61
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
if (debug) console.debug(`usePromise [${debug}] Main Function`)
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
let cancelled = false
|
|
66
|
+
dispatch({ type: State.pending })
|
|
67
|
+
if (debug) console.debug(`usePromise [${debug}] useEffect [cancelled: ${cancelled}]`)
|
|
68
|
+
if (promiseMemo instanceof Promise) {
|
|
69
|
+
promiseMemo
|
|
70
|
+
.then((payload) => {
|
|
71
|
+
if (debug) console.debug(`usePromise [${debug}] then [cancelled: ${cancelled}]`)
|
|
72
|
+
!cancelled ??
|
|
73
|
+
dispatch({
|
|
74
|
+
error: undefined,
|
|
75
|
+
payload,
|
|
78
76
|
type: State.resolved,
|
|
79
77
|
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
})
|
|
79
|
+
.catch((error) => {
|
|
80
|
+
if (debug) console.debug(`usePromise [${debug}] catch [cancelled: ${cancelled}]`)
|
|
81
|
+
!cancelled ??
|
|
82
|
+
dispatch({
|
|
83
|
+
error: error as Error,
|
|
84
|
+
payload: undefined,
|
|
85
85
|
type: State.rejected,
|
|
86
86
|
})
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
87
|
+
})
|
|
88
|
+
} else if (promiseMemo) {
|
|
89
|
+
dispatch({
|
|
90
|
+
error: undefined,
|
|
91
|
+
payload: promiseMemo,
|
|
92
|
+
type: State.resolved,
|
|
93
|
+
})
|
|
94
|
+
} else {
|
|
95
|
+
if (debug) console.debug(`usePromise [${debug}] no-promise [cancelled: ${cancelled}]`)
|
|
96
|
+
!cancelled ??
|
|
97
|
+
dispatch({
|
|
98
|
+
error: undefined,
|
|
99
|
+
payload: undefined,
|
|
100
|
+
type: State.resolved,
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
return () => {
|
|
104
|
+
if (debug) console.debug(`usePromise [${debug}] useEffect callback`)
|
|
105
|
+
cancelled = true
|
|
106
|
+
}
|
|
107
|
+
}, [promiseMemo])
|
|
98
108
|
|
|
99
109
|
return [result, error, state]
|
|
100
110
|
}
|