@tsingroc/tsingroc-components 5.0.0-alpha.23 → 5.0.0-alpha.25

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.
@@ -14,11 +14,11 @@ export type Fetcher = (resource: RequestInfo | URL, options?: RequestInit & Fetc
14
14
  * ```
15
15
  */
16
16
  export interface FetcherExtraOptions {
17
- loginOn401?: boolean;
17
+ logoutOn401?: boolean;
18
18
  }
19
19
  /** 在请求中添加 Authorization 头的 fetcher 中间件。 */
20
20
  export declare function fetcherWithBearerToken(token: string): (fetcher: Fetcher) => Fetcher;
21
- /** 在请求返回 401 错误时自动尝试登录的 fetcher 中间件。 */
21
+ /** 在请求返回 401 错误时自动退出登录的 fetcher 中间件。 */
22
22
  export declare function fetcherWithLoginOn401(sessionStore: SessionStore): (fetcher: Fetcher) => Fetcher;
23
23
  /** 获取当前上下文的 fetcher。 */
24
24
  export declare function useFetcher(): Fetcher;
@@ -31,14 +31,15 @@ export function fetcherWithBearerToken(token) {
31
31
  };
32
32
  }
33
33
 
34
- /** 在请求返回 401 错误时自动尝试登录的 fetcher 中间件。 */
34
+ /** 在请求返回 401 错误时自动退出登录的 fetcher 中间件。 */
35
35
  export function fetcherWithLoginOn401(sessionStore) {
36
36
  return fetcher => async (resource, options) => {
37
37
  const loggedIn = !!sessionStore.session;
38
38
  const resp = await fetcher(resource, options);
39
- if (resp.status === 401) {
39
+ const logoutOn401 = options?.logoutOn401 ?? true;
40
+ if (logoutOn401 && resp.status === 401) {
40
41
  await sessionStore.clear();
41
- void sessionStore.get();
42
+ // LoginCheck 会负责自动重新登录,所以这里不需要调用 sessionStore.get()
42
43
  throw new Error(`对 ${resp.url} 的请求需要鉴权,但用户${loggedIn ? "登录状态已失效" : "未登录"}。`);
43
44
  }
44
45
  return resp;
@@ -21,7 +21,20 @@ export function LoginCheck(props) {
21
21
  return () => sessionStore.addEventListener(onChange);
22
22
  }, () => sessionStore.session);
23
23
  const [status, setStatus] = useState(session ? "loaded" : "loading");
24
- const onSessionStoreEvent = useEffectEvent(event => {
24
+ const startLoading = useEffectEvent(async () => {
25
+ try {
26
+ onBeforeGetSession?.();
27
+ void (await sessionStore.get());
28
+ } finally {
29
+ setStatus("loaded");
30
+ }
31
+ });
32
+ useEffect(() => {
33
+ if (status === "loading") {
34
+ startLoading();
35
+ }
36
+ }, [status]);
37
+ const onSessionStoreEvent = useEffectEvent(async event => {
25
38
  switch (event.type) {
26
39
  case "failed":
27
40
  onFailed?.(event.reason);
@@ -34,6 +47,8 @@ export function LoginCheck(props) {
34
47
  break;
35
48
  case "invalidated":
36
49
  onInvalidated?.(event.reason);
50
+ onBeforeGetSession?.();
51
+ void (await sessionStore.get());
37
52
  break;
38
53
  }
39
54
  });
@@ -41,18 +56,5 @@ export function LoginCheck(props) {
41
56
  sessionStore.addEventListener(onSessionStoreEvent);
42
57
  return () => sessionStore.removeEventListener(onSessionStoreEvent);
43
58
  }, [sessionStore]);
44
- const startLoading = useEffectEvent(async () => {
45
- try {
46
- onBeforeGetSession?.();
47
- void (await sessionStore.get());
48
- } finally {
49
- setStatus("loaded");
50
- }
51
- });
52
- useEffect(() => {
53
- if (status === "loading") {
54
- startLoading();
55
- }
56
- }, [status]);
57
59
  return status === "loading" ? loading : session ? children : failed;
58
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsingroc/tsingroc-components",
3
- "version": "5.0.0-alpha.23",
3
+ "version": "5.0.0-alpha.25",
4
4
  "author": "",
5
5
  "license": "ISC",
6
6
  "description": "",