Skip to content

[WIP] ✨ feat: Lobe Editor Phase II#8

Merged
canisminor1990 merged 48 commits into
masterfrom
dev
Sep 8, 2025
Merged

[WIP] ✨ feat: Lobe Editor Phase II#8
canisminor1990 merged 48 commits into
masterfrom
dev

Conversation

@canisminor1990
Copy link
Copy Markdown
Member

@canisminor1990 canisminor1990 commented Aug 20, 2025

💻 变更类型 | Change Type

  • ✨ feat
  • 🐛 fix
  • ♻️ refactor
  • 💄 style
  • 🔨 chore
  • 📝 docs

🔀 变更说明 | Description of Change

📝 补充信息 | Additional Information

Summary by Sourcery

Introduce a new high-priority command registration API and migrate existing Lexical command handlers to leverage prioritized dispatch in slash and rich-keydown plugins.

New Features:

  • Add registerHighCommand method in the editor kernel with support for multiple priority levels (0–4) and automatic listener cleanup.
  • Extend IEditor and IEditorKernel types to include the new registerHighCommand interface.
  • Define COMMAND_PRIORITY_* constants and related types for prioritized command listeners.

Enhancements:

  • Replace direct editor.registerCommand calls in ReactSlashPlugin with kernel.registerHighCommand at critical priority.
  • Update common registerRichKeydown plugin to accept the kernel instance and use high-priority command registration for all key handlers.
  • Wire the kernel instance into plugin registration in CommonPlugin to enable high-priority commands.

@vercel
Copy link
Copy Markdown

vercel Bot commented Aug 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
lobe-editor Ready Ready Preview Comment Sep 7, 2025 0:53am

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Aug 20, 2025

Reviewer's Guide

Introduce a prioritized command registration API (registerHighCommand) in the editor kernel with automatic cleanup, extend types and interfaces with listener priority levels, and migrate existing keyboard commands in slash and rich keydown plugins to leverage the new API with appropriate priorities.

Sequence diagram for prioritized command handling in Kernel.registerHighCommand

sequenceDiagram
  participant Editor
  participant Kernel
  participant CommandListener
  Editor->>Kernel: registerHighCommand(command, listener, priority)
  Kernel->>Kernel: Store listener in priority set
  Editor->>Kernel: Dispatch command
  Kernel->>Kernel: Iterate listeners by priority (high to low)
  Kernel->>CommandListener: Invoke listener(payload, editor)
  alt Listener returns true
    Kernel->>Editor: Stop propagation
  else Listener returns false
    Kernel->>Kernel: Continue to next listener
  end
Loading

Class diagram for Kernel and command registration changes

classDiagram
  class Kernel {
    +registerHighCommand<P>(command, listener, priority): () => void
    -_commands: Commands
    -_commandsClean: Map<LexicalCommand<unknown>, () => void>
  }
  class IEditor {
    +registerHighCommand<P>(command, listener, priority): () => void
  }
  class IEditorKernel {
    +registerHighCommand<P>(command, listener, priority): () => void
  }
  Kernel --|> IEditorKernel
  IEditorKernel --|> IEditor
  class Commands {
    Map<LexicalCommand<unknown>, Array<Set<CommandListener<unknown>>>>
  }
  Kernel --> Commands
  Kernel --> "Map<LexicalCommand<unknown>, () => void>" _commandsClean
Loading

Class diagram for CommandListenerPriority and priority constants

classDiagram
  class CommandListenerPriority {
    <<type>>
    0 | 1 | 2 | 3 | 4
  }
  class COMMAND_PRIORITY_EDITOR {
    <<constant>>
    = 0
  }
  class COMMAND_PRIORITY_LOW {
    <<constant>>
    = 1
  }
  class COMMAND_PRIORITY_NORMAL {
    <<constant>>
    = 2
  }
  class COMMAND_PRIORITY_HIGH {
    <<constant>>
    = 3
  }
  class COMMAND_PRIORITY_CRITICAL {
    <<constant>>
    = 4
  }
  CommandListenerPriority <|-- COMMAND_PRIORITY_EDITOR
  CommandListenerPriority <|-- COMMAND_PRIORITY_LOW
  CommandListenerPriority <|-- COMMAND_PRIORITY_NORMAL
  CommandListenerPriority <|-- COMMAND_PRIORITY_HIGH
  CommandListenerPriority <|-- COMMAND_PRIORITY_CRITICAL
Loading

File-Level Changes

Change Details Files
Implement prioritized high-priority command API in the kernel
  • Introduce private _commands and _commandsClean maps
  • Implement registerHighCommand with priority-based listener dispatch
  • Register underlying Lexical command at critical priority and provide cleanup
src/editor-kernel/kernel.ts
Extend types and editor interfaces with command priority support
  • Define CommandListenerPriority type and COMMAND_PRIORITY_* constants
  • Add Commands and CommandsClean type aliases
  • Extend IEditor and IEditorKernel (and public types) to declare registerHighCommand
src/editor-kernel/types.ts
src/types/kernel.ts
Migrate ReactSlashPlugin to use registerHighCommand
  • Replace editor.registerCommand calls with editor.registerHighCommand
  • Assign COMMAND_PRIORITY_CRITICAL to all migrated slash commands
  • Simplify useLexicalEditor mergeRegister invocation
src/plugins/slash/react/ReactSlashPlugin.tsx
Migrate rich keydown plugin and update plugin registration
  • Update registerRichKeydown signature to accept kernel
  • Replace editor.registerCommand calls with kernel.registerHighCommand for key events
  • Adjust listener priorities to COMMAND_PRIORITY_EDITOR
  • Modify CommonPlugin to pass kernel into registerRichKeydown
src/plugins/common/plugin/register.ts
src/plugins/common/plugin/index.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@lobehubbot
Copy link
Copy Markdown
Member

👍 @canisminor1990


Thank you for raising your pull request and contributing to our Community
Please make sure you have followed our contributing guidelines. We will review it as soon as possible.
If you encounter any problems, please feel free to connect with us.
非常感谢您提出拉取请求并为我们的社区做出贡献,请确保您已经遵循了我们的贡献指南,我们会尽快审查它。
如果您遇到任何问题,请随时与我们联系。

@canisminor1990 canisminor1990 changed the title [WIP] ✨ feat: v2 [WIP] ✨ feat: Lobe Editor Phase II Aug 20, 2025
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Aug 20, 2025

Open in StackBlitz

npm i https://pkg.pr.new/lobehub/lobe-editor/@lobehub/editor@8

commit: eed62cf

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Consider extracting the repeated mergeRegister blocks in ReactSlashPlugin into a reusable helper to reduce boilerplate and improve readability.
  • The registerHighCommand implementation always uses COMMAND_PRIORITY_CRITICAL under the hood—verify that this aligns with your intended priority handling and won’t interfere with other normal-priority listeners.
  • After invoking the cleanup callback in registerHighCommand, remember to delete its entry from the _commandsClean map as well to avoid potential memory leaks.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider extracting the repeated mergeRegister blocks in ReactSlashPlugin into a reusable helper to reduce boilerplate and improve readability.
- The registerHighCommand implementation always uses COMMAND_PRIORITY_CRITICAL under the hood—verify that this aligns with your intended priority handling and won’t interfere with other normal-priority listeners.
- After invoking the cleanup callback in registerHighCommand, remember to delete its entry from the _commandsClean map as well to avoid potential memory leaks.

## Individual Comments

### Comment 1
<location> `src/plugins/slash/react/ReactSlashPlugin.tsx:140` </location>
<code_context>

-export function registerRichKeydown(editor: LexicalEditor) {
+export function registerRichKeydown(editor: LexicalEditor, kernel: IEditor) {
   return mergeRegister(
-    editor.registerCommand(
+    kernel.registerHighCommand(
</code_context>

<issue_to_address>
All command registrations now use COMMAND_PRIORITY_CRITICAL; consider if this is necessary for every command.

Using COMMAND_PRIORITY_CRITICAL for all commands may block lower-priority listeners. Please evaluate if some commands can use a lower priority for better flexibility.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

(item): item is ISlashMenuOption =>
!('type' in item && item.type === 'divider') && 'key' in item && Boolean(item.key),
);
return mergeRegister(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: All command registrations now use COMMAND_PRIORITY_CRITICAL; consider if this is necessary for every command.

Using COMMAND_PRIORITY_CRITICAL for all commands may block lower-priority listeners. Please evaluate if some commands can use a lower priority for better flexibility.

@canisminor1990 canisminor1990 merged commit 3013a43 into master Sep 8, 2025
5 of 6 checks passed
@canisminor1990 canisminor1990 deleted the dev branch September 8, 2025 02:35
@lobehubbot
Copy link
Copy Markdown
Member

❤️ Great PR @canisminor1990 ❤️


The growth of project is inseparable from user feedback and contribution, thanks for your contribution!
项目的成长离不开用户反馈和贡献,感谢您的贡献!

@lobehubbot
Copy link
Copy Markdown
Member

🎉 This PR is included in version 1.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants