feat(core): unused blob management in settings (#9795)

fix AF-2144, PD-2064, PD-2065, PD-2066
This commit is contained in:
pengx17
2025-01-23 07:12:16 +00:00
parent 8021b89944
commit 6ac6a8d6d6
26 changed files with 846 additions and 30 deletions

View File

@@ -1,4 +1,5 @@
export { useAutoFocus, useAutoSelect } from './focus-and-select';
export { useDisposable } from './use-disposable';
export { useRefEffect } from './use-ref-effect';
export * from './use-theme-color-meta';
export * from './use-theme-value';

View File

@@ -0,0 +1,60 @@
import { useEffect, useState } from 'react';
export function useDisposable<T extends Disposable | AsyncDisposable>(
disposableFn: (abortSignal?: AbortSignal) => Promise<T | null>,
deps?: any[]
): { data: T | null; loading: boolean; error: Error | null };
export function useDisposable<T extends Disposable | AsyncDisposable>(
disposableFn: (abortSignal?: AbortSignal) => T | null,
deps?: any[]
): { data: T | null };
export function useDisposable<T extends Disposable | AsyncDisposable>(
disposableFn: (abortSignal?: AbortSignal) => Promise<T | null> | T | null,
deps?: any[]
) {
const [state, setState] = useState<{
data: T | null;
loading: boolean;
error: Error | null;
}>({
data: null,
loading: false,
error: null,
});
useEffect(() => {
const abortController = new AbortController();
let _data: T | null = null;
setState(prev => ({ ...prev, loading: true, error: null }));
Promise.resolve(disposableFn(abortController.signal))
.then(data => {
_data = data;
if (!abortController.signal.aborted) {
setState({ data, loading: false, error: null });
}
})
.catch(error => {
if (!abortController.signal.aborted) {
setState(prev => ({ ...prev, error, loading: false }));
}
});
return () => {
abortController.abort();
if (_data && typeof _data === 'object') {
if (Symbol.dispose in _data) {
_data[Symbol.dispose]();
} else if (Symbol.asyncDispose in _data) {
_data[Symbol.asyncDispose]();
}
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps || []);
return state;
}