fix(infra): memory leak (#9013)

This commit is contained in:
EYHN
2024-12-16 16:55:49 +00:00
parent 55f1cc4b1e
commit b36b398957
30 changed files with 399 additions and 135 deletions
@@ -12,9 +12,8 @@ import {
import { DisposableGroup } from '@blocksuite/affine/global/utils';
import type { AffineEditorContainer } from '@blocksuite/affine/presets';
import type { Doc } from '@blocksuite/affine/store';
import { use } from 'foxact/use';
import type { CSSProperties } from 'react';
import { Suspense, useEffect } from 'react';
import { useEffect, useState } from 'react';
import type { DefaultOpenProperty } from '../../doc-properties';
import { BlocksuiteEditorContainer } from './blocksuite-editor-container';
@@ -31,24 +30,6 @@ export type EditorProps = {
className?: string;
};
function usePageRoot(page: Doc) {
if (!page.root) {
use(
new Promise<void>((resolve, reject) => {
const disposable = page.slots.rootAdded.once(() => {
resolve();
});
window.setTimeout(() => {
disposable.dispose();
reject(new NoPageRootError(page));
}, 20 * 1000);
})
);
}
return page.root;
}
const BlockSuiteEditorImpl = ({
mode,
page,
@@ -58,8 +39,6 @@ const BlockSuiteEditorImpl = ({
onEditorReady,
defaultOpenProperty,
}: EditorProps) => {
usePageRoot(page);
useEffect(() => {
const disposable = page.slots.blockUpdated.once(() => {
page.collection.setDocMeta(page.id, {
@@ -142,9 +121,33 @@ const BlockSuiteEditorImpl = ({
};
export const BlockSuiteEditor = (props: EditorProps) => {
return (
<Suspense fallback={<EditorLoading />}>
<BlockSuiteEditorImpl key={props.page.id} {...props} />
</Suspense>
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
if (props.page.root) {
setIsLoading(false);
return;
}
const disposable = props.page.slots.rootAdded.once(() => {
setIsLoading(false);
});
window.setTimeout(() => {
disposable.dispose();
setError(new NoPageRootError(props.page));
}, 20 * 1000);
return () => {
disposable.dispose();
};
}, [props.page]);
if (error) {
throw error;
}
return isLoading ? (
<EditorLoading />
) : (
<BlockSuiteEditorImpl key={props.page.id} {...props} />
);
};
@@ -1,32 +1,31 @@
import type { DocCollection } from '@blocksuite/affine/store';
import { useAtomValue } from 'jotai';
import { type ReactNode, Suspense } from 'react';
import { useBlockSuitePagePreview } from './use-block-suite-page-preview';
import { useDocCollectionPage } from './use-block-suite-workspace-page';
import { DocsSearchService } from '@affine/core/modules/docs-search';
import { LiveData, useLiveData, useService } from '@toeverything/infra';
import { type ReactNode, useMemo } from 'react';
interface PagePreviewProps {
docCollection: DocCollection;
pageId: string;
emptyFallback?: ReactNode;
fallback?: ReactNode;
}
const PagePreviewInner = ({
docCollection: workspace,
pageId,
emptyFallback,
fallback,
}: PagePreviewProps) => {
const page = useDocCollectionPage(workspace, pageId);
const previewAtom = useBlockSuitePagePreview(page);
const preview = useAtomValue(previewAtom);
const res = preview ? preview : null;
return res || emptyFallback;
const docSummary = useService(DocsSearchService);
const summary = useLiveData(
useMemo(
() => LiveData.from(docSummary.watchDocSummary(pageId), null),
[docSummary, pageId]
)
);
const res =
summary === null ? fallback : summary === '' ? emptyFallback : summary;
return res;
};
export const PagePreview = (props: PagePreviewProps) => {
return (
<Suspense>
<PagePreviewInner {...props} />
</Suspense>
);
return <PagePreviewInner {...props} />;
};
@@ -317,9 +317,7 @@ function pageMetaToListItemProp(
pageId: item.id,
pageIds,
title: <PageTitle id={item.id} />,
preview: (
<PagePreview docCollection={props.docCollection} pageId={item.id} />
),
preview: <PagePreview pageId={item.id} />,
createDate: new Date(item.createDate),
updatedDate: item.updatedDate ? new Date(item.updatedDate) : undefined,
to: props.rowAsLink && !props.selectable ? `/${item.id}` : undefined,