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 { type Value } from 'platejs';
|
||||||
import { useEditorRef, usePlateEditor, type TPlateEditor } from 'platejs/react';
|
import { useEditorRef, usePlateEditor, type TPlateEditor } from 'platejs/react';
|
||||||
import { useMemo } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { EditorKit } from './editor-kit';
|
|
||||||
import { FIXED_TOOLBAR_KIT_KEY } from './plugins/fixed-toolbar-kit';
|
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';
|
import type { IReportEditor } from './ReportEditor';
|
||||||
|
|
||||||
export const useReportEditor = ({
|
export const useReportEditor = ({
|
||||||
|
@ -17,27 +17,49 @@ export const useReportEditor = ({
|
||||||
onReady?: (editor: IReportEditor) => void;
|
onReady?: (editor: IReportEditor) => void;
|
||||||
useFixedToolbarKit?: boolean;
|
useFixedToolbarKit?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const plugins = useMemo(() => {
|
const basePlugins = useMemo(() => {
|
||||||
const filteredKeys: string[] = [];
|
if (useFixedToolbarKit) return BaseEditorKit;
|
||||||
if (!useFixedToolbarKit) {
|
return BaseEditorKit.filter((plugin) => plugin.key !== FIXED_TOOLBAR_KIT_KEY);
|
||||||
filteredKeys.push(FIXED_TOOLBAR_KIT_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filteredKeys.length > 0) {
|
|
||||||
return EditorKit.filter((plugin) => !filteredKeys.includes(plugin.key));
|
|
||||||
}
|
|
||||||
|
|
||||||
return EditorKit;
|
|
||||||
}, [useFixedToolbarKit]);
|
}, [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({
|
return usePlateEditor({
|
||||||
plugins,
|
plugins,
|
||||||
value,
|
value,
|
||||||
readOnly: disabled,
|
readOnly: disabled,
|
||||||
onReady: ({ editor }) => onReady?.(editor)
|
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>();
|
export const useEditor = () => useEditorRef<ReportEditor>();
|
||||||
|
|
Loading…
Reference in New Issue