Code Monkey home page Code Monkey logo

blocksuite's Introduction

BlockSuite

Checkst Status Issues Closed NPM Latest Release NPM Nightly Release

๐Ÿ’  BlockSuite is an open-source collaborative editor project behind AFFiNE, an open-source knowledge base that attempts to combine the best of Notion and Miro altogether. In this monorepo, we maintain multiple abstraction layers of the editor and some core modules that can be reused externally.

Try BlockSuite-based AFFiNE Alpha editor

Introduction

BlockSuite works very differently from traditional rich text editors:

  • For the data model, BlockSuite does not implement the event sourcing pattern but instead provides a CRDT-based block tree based directly on Yjs, supporting zero-cost time travel and real-time collaboration out of the box. Its data persistence layer is also designed to be local-first.
  • For rich text editing, multiple different nodes in the BlockSuite block tree can be connected to different rich text editing components, thus modeling rich text content as multiple UI components instead of a single UI container, eliminating the use of the dangerous monolith contenteditale.
  • For the rendering layer, BlockSuite does not assume that content can only be rendered via the DOM. Not only does it implement a basic document editing UI based on Web Components, but it is also developing a hybrid canvas-based renderer for parts of the whiteboard content. Both renderers can co-exist on the same page and get updated through the same store.

BlockSuite is not intended to be yet another plugin-based rich text editing framework. Instead, it encourages building different collaborative applications directly through whatever UI framework you're comfortable with. To that end, we will try to open-source more basic modules for this in the BlockSuite project.

Although BlockSuite is still in its early stage, you can already use the @blocksuite/editor package, the collaborative editor AFFiNE Alpha used. Note that this editor is also a Web Component and is totally framework-agnostic!

Current Status (@blocksuite/editor)

โš ๏ธ This project is under heavy development and is in a stage of rapid evolution. Stay tuned!

  • Basic text editing
    • โœ… Paragraph with inline style
    • โœ… Nested list
    • โœ… Code block
    • โœ… Markdown shortcuts
  • Block-level editing
    • โœ… Inline text format bar
    • โš›๏ธ Block-level selection
    • โš›๏ธ Block drag handle
    • ๐Ÿšง Inline slash menu
    • ๐Ÿšง Block hub
  • Rich-content
    • โš›๏ธ Image block
    • ๐Ÿšง Database block
    • ๐Ÿ“Œ Third-party embedded block
  • Whiteboard (edgeless mode)
    • โœ… Zooming and panning
    • โš›๏ธ Frame block
    • ๐Ÿšง Shape element
    • ๐Ÿšง Handwriting element
    • ๐Ÿ“Œ Grouping
  • Playground
    • โœ… Multiplayer collaboration
    • โœ… Local data persistence
    • โœ… E2E test suite
  • Developer experience
    • โœ… Block tree update API
    • โœ… Zero cost time travel (undo/redo)
    • โœ… Reusable NPM package
    • โš›๏ธ React hooks integration
    • ๐Ÿ“Œ Dynamic block registration

Icons above correspond to the following meanings:

  • โœ… - Beta
  • โš›๏ธ - Alpha
  • ๐Ÿšง - Developing
  • ๐Ÿ“Œ - Planned

Resources

Getting Started with the Prebuilt Editor

To use the BlockSuite-based editor built into AFFiNE, three core packages are required to be imported:

  • The packages/store package is a data store built for general-purpose state management.
  • The packages/blocks package holds the default BlockSuite editable blocks.
  • The packages/editor package ships a complete BlockSuite-based editor.

This will install the latest BlockSuite packages into your project:

pnpm i \
  @blocksuite/store@nightly \
  @blocksuite/blocks@nightly \
  @blocksuite/editor@nightly

And here is a minimal collaboration-ready editor showing how the BlockSuite packages are composed together:

import '@blocksuite/blocks';
// A workspace can hold multiple pages, and a page can hold multiple blocks.
import { Workspace, Page } from '@blocksuite/store';
import { BlockSchema } from '@blocksuite/blocks/models';
import { EditorContainer } from '@blocksuite/editor';

/**
 * Manually create the initial page structure.
 * In collaboration mode or on page refresh with local persistence,
 * the page data will be automatically loaded from store providers.
 * In these cases, this function should not be called.
 */
function createInitialPage(workspace: Workspace) {
  // Events are being emitted using signals.
  workspace.signals.pageAdded.once(id => {
    const page = workspace.getPage(id) as Page;

    // Block types are defined and registered in BlockSchema.
    const pageBlockId = page.addBlock({ flavour: 'affine:page' });
    const frameId = page.addBlock({ flavour: 'affine:frame' }, pageBlockId);
    page.addBlock({ flavour: 'affine:paragraph' }, frameId);
  });

  // Create a new page. This will trigger the signal above.
  workspace.createPage('page0');
}

// Subscribe for page update and create editor on page added.
function initEditorOnPageAdded(workspace: Workspace) {
  workspace.signals.pageAdded.once(pageId => {
    const page = workspace.getPage(pageId) as Page;
    const editor = new EditorContainer();
    editor.page = page;
    document.body.appendChild(editor);
  });
}

function main() {
  // Initialize the store.
  const workspace = new Workspace({}).register(BlockSchema);

  // Start waiting for the first page...
  initEditorOnPageAdded(workspace);

  // Suppose we are the first one to create the page.
  createInitialPage(workspace);
}

main();

For React developers, check out the @blocksuite/react doc for React components and hooks support.

Local Development

Setting up basic local environment:

# install dependencies
pnpm i

# start vite playground
pnpm dev

The example page should work at http://localhost:5173/?init

To test locally, please make sure browser binaries are already installed via npx playwright install and Vite playground is started with pnpm dev. Then there are multi commands to choose from:

# run tests in headless mode in another terminal window
pnpm test

# or run tests in headed mode for debugging
pnpm test:headed

In headed mode, await page.pause() can be used in test cases to suspend the test runner. Note that the usage of the Playwright VSCode extension is also highly recommended.

License

MPL 2.0

blocksuite's People

Contributors

akarachen avatar alt1o avatar austaras avatar cjss avatar colelawrence avatar darkskygit avatar diamondthree avatar donaldxdonald avatar doodlewind avatar fi3ework avatar flrande avatar github-actions[bot] avatar himself65 avatar jimmfly avatar lawvs avatar linonetwo avatar lucinyan avatar qishaoxuan avatar saikasakura avatar shortcipher5 avatar thorseraq avatar tzhangchi avatar zoulamzero avatar zuoxiaodong0815 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.