mirror of https://github.com/buster-so/buster.git
web(memory): split Plate editor plugins into base + lazy heavy kits; idle-load heavy kits to reduce startup heap
Co-Authored-By: nate@buster.so <nate@buster.so>
This commit is contained in:
parent
b979e208f7
commit
34515032ee
|
@ -0,0 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { TrailingBlockPlugin } from 'platejs';
|
||||
import { AlignKit } from './plugins/align-kit';
|
||||
import { BasicBlocksKit } from './plugins/basic-blocks-kit';
|
||||
import { BasicMarksKit } from './plugins/basic-marks-kit';
|
||||
import { ExitBreakKit } from './plugins/exit-break-kit';
|
||||
import { FixedToolbarKit } from './plugins/fixed-toolbar-kit';
|
||||
import { LineHeightKit } from './plugins/line-height-kit';
|
||||
import { LinkKit } from './plugins/link-kit';
|
||||
import { ListKit } from './plugins/list-kit';
|
||||
|
||||
export const BaseEditorKit = [
|
||||
...BasicBlocksKit,
|
||||
...BasicMarksKit,
|
||||
...ListKit,
|
||||
...AlignKit,
|
||||
...LineHeightKit,
|
||||
...LinkKit,
|
||||
...ExitBreakKit,
|
||||
TrailingBlockPlugin,
|
||||
...FixedToolbarKit
|
||||
];
|
|
@ -0,0 +1,88 @@
|
|||
export const loadHeavyEditorKits = async () => {
|
||||
const [
|
||||
ai,
|
||||
blockMenu,
|
||||
codeBlock,
|
||||
table,
|
||||
toggle,
|
||||
toc,
|
||||
media,
|
||||
callout,
|
||||
column,
|
||||
math,
|
||||
date,
|
||||
mention,
|
||||
font,
|
||||
discussion,
|
||||
comment,
|
||||
suggestion,
|
||||
slash,
|
||||
autoformat,
|
||||
cursorOverlay,
|
||||
dnd,
|
||||
emoji,
|
||||
docx,
|
||||
markdown,
|
||||
blockPlaceholder,
|
||||
floatingToolbar,
|
||||
busterStream
|
||||
] = await Promise.all([
|
||||
import('./plugins/ai-kit'),
|
||||
import('./plugins/block-menu-kit'),
|
||||
import('./plugins/code-block-kit'),
|
||||
import('./plugins/table-kit'),
|
||||
import('./plugins/toggle-kit'),
|
||||
import('./plugins/toc-kit'),
|
||||
import('./plugins/media-kit'),
|
||||
import('./plugins/callout-kit'),
|
||||
import('./plugins/column-kit'),
|
||||
import('./plugins/math-kit'),
|
||||
import('./plugins/date-kit'),
|
||||
import('./plugins/mention-kit'),
|
||||
import('./plugins/font-kit'),
|
||||
import('./plugins/discussion-kit'),
|
||||
import('./plugins/comment-kit'),
|
||||
import('./plugins/suggestion-kit'),
|
||||
import('./plugins/slash-kit'),
|
||||
import('./plugins/autoformat-kit'),
|
||||
import('./plugins/cursor-overlay-kit'),
|
||||
import('./plugins/dnd-kit'),
|
||||
import('./plugins/emoji-kit'),
|
||||
import('./plugins/docx-kit'),
|
||||
import('./plugins/markdown-kit'),
|
||||
import('./plugins/block-placeholder-kit'),
|
||||
import('./plugins/floating-toolbar-kit'),
|
||||
import('./plugins/buster-stream-kit').catch(() => ({ BusterStreamKit: [] as any[] }))
|
||||
]);
|
||||
|
||||
const kits = [
|
||||
...(ai.AIKit || []),
|
||||
...(blockMenu.BlockMenuKit || []),
|
||||
...(codeBlock.CodeBlockKit || []),
|
||||
...(table.TableKit || []),
|
||||
...(toggle.ToggleKit || []),
|
||||
...(toc.TocKit || []),
|
||||
...(media.MediaKit || []),
|
||||
...(callout.CalloutKit || []),
|
||||
...(column.ColumnKit || []),
|
||||
...(math.MathKit || []),
|
||||
...(date.DateKit || []),
|
||||
...(mention.MentionKit || []),
|
||||
...(font.FontKit || []),
|
||||
...(discussion.DiscussionKit || []),
|
||||
...(comment.CommentKit || []),
|
||||
...(suggestion.SuggestionKit || []),
|
||||
...(slash.SlashKit || []),
|
||||
...(autoformat.AutoformatKit || []),
|
||||
...(cursorOverlay.CursorOverlayKit || []),
|
||||
...(dnd.DndKit || []),
|
||||
...(emoji.EmojiKit || []),
|
||||
...(docx.DocxKit || []),
|
||||
...(markdown.MarkdownKit || []),
|
||||
...(blockPlaceholder.BlockPlaceholderKit || []),
|
||||
...(floatingToolbar.FloatingToolbarKit || []),
|
||||
...((busterStream as any).BusterStreamKit || [])
|
||||
];
|
||||
|
||||
return kits;
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
import { type Value } from 'platejs';
|
||||
import { useEditorRef, usePlateEditor, type TPlateEditor } from 'platejs/react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { EditorKit } from './editor-kit';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { FIXED_TOOLBAR_KIT_KEY } from './plugins/fixed-toolbar-kit';
|
||||
import { BaseEditorKit } from './base-editor-kit';
|
||||
import { loadHeavyEditorKits } from './load-heavy-editor-kits';
|
||||
import type { IReportEditor } from './ReportEditor';
|
||||
|
||||
export const useReportEditor = ({
|
||||
|
@ -17,27 +17,49 @@ export const useReportEditor = ({
|
|||
onReady?: (editor: IReportEditor) => void;
|
||||
useFixedToolbarKit?: boolean;
|
||||
}) => {
|
||||
const plugins = useMemo(() => {
|
||||
const filteredKeys: string[] = [];
|
||||
if (!useFixedToolbarKit) {
|
||||
filteredKeys.push(FIXED_TOOLBAR_KIT_KEY);
|
||||
}
|
||||
|
||||
if (filteredKeys.length > 0) {
|
||||
return EditorKit.filter((plugin) => !filteredKeys.includes(plugin.key));
|
||||
}
|
||||
|
||||
return EditorKit;
|
||||
const basePlugins = useMemo(() => {
|
||||
if (useFixedToolbarKit) return BaseEditorKit;
|
||||
return BaseEditorKit.filter((plugin) => plugin.key !== FIXED_TOOLBAR_KIT_KEY);
|
||||
}, [useFixedToolbarKit]);
|
||||
|
||||
const [plugins, setPlugins] = useState(basePlugins);
|
||||
|
||||
useEffect(() => {
|
||||
setPlugins(basePlugins);
|
||||
}, [basePlugins]);
|
||||
|
||||
useEffect(() => {
|
||||
const schedule = (cb: () => void) => {
|
||||
if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {
|
||||
(window as any).requestIdleCallback(cb, { timeout: 3000 });
|
||||
} else {
|
||||
setTimeout(cb, 1500);
|
||||
}
|
||||
};
|
||||
let cancelled = false;
|
||||
schedule(async () => {
|
||||
const heavy = await loadHeavyEditorKits();
|
||||
if (!cancelled) {
|
||||
setPlugins((prev) => {
|
||||
const keys = new Set(prev.map((p) => p.key));
|
||||
const toAdd = heavy.filter((p) => !keys.has(p.key));
|
||||
return [...prev, ...toAdd];
|
||||
});
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return usePlateEditor({
|
||||
plugins,
|
||||
value,
|
||||
readOnly: disabled,
|
||||
onReady: ({ editor }) => onReady?.(editor)
|
||||
}); // Pass dependencies to usePlateEditor
|
||||
});
|
||||
};
|
||||
|
||||
export type ReportEditor = TPlateEditor<Value, (typeof EditorKit)[number]>;
|
||||
export type ReportEditor = TPlateEditor<Value, any>;
|
||||
|
||||
export const useEditor = () => useEditorRef<ReportEditor>();
|
||||
|
|
Loading…
Reference in New Issue