BlockSuite 一款 Block Style 的编辑器,仅仅是编辑器!

目录

先说结论

我的博客不太适合用 BlockSuite 作为编辑器,因为:

  1. 不知道如何渲染,我可以编辑,但是如何展示给匿名用户看?
  2. SEO 不太明确,也想着转成 HTML 来做,但是成本太高?

其他博主的调研:https://blog.nineya.com/archives/154.html

开始!

学习一下:https://block-suite.com/

Scratch(QuickStart)

简单安装一下,目前是 canary 版本, AFFiNE 也是用的这个版本,每次都打包的 master 分支,基本上每天都有更新。

npm install \
  @blocksuite/presets@canary \
  @blocksuite/blocks@canary \
  @blocksuite/store@canary

预置了 PageEditor 、EdgelessEditor 组件。

Overview

BlockSuite 是用来构建编辑器和协作应用的套件。

你可以把它看作一个 UI 组件。

基于 vanilla 框架,也就是原生 JS ……

  • PageEditor:块编辑器,可定制,非常灵活
  • EdgelessEditor:图编辑器,可选择 canvas 渲染,同样兼容块编辑器。顾名思义,真正是"无边记"。

所有的 BlockSuite 组件都是 Native Web Components。

Motivation

  • 支持编辑多模态内容:文本、幻灯片、脑图、表格
  • 组织和可视化复杂知识:单页很容易,但是如果有很多个页面相互关联,该如何组织呢
  • 可协作:实时协作,利用 conflict-free replicated data type (CRDT) 数据结构来做这件事

同样也支持:

  • 自定义块:custom blocks
  • 持久化:多种格式,如 Markdown、HTML 等
  • 文档复用

Architecture

BlockSuite 和 AFFiNE 关系,就像是 Monaco EditorVSCode,但是主要不同在于 技术栈,BlockSuite 是原生 Web Component,而 AFFiNE 则用了 React。

  • @blocksuite/store:数据层,用于协作文档状态,基于 CRDT 库: Yjs
  • @blocksuite/inline:内联编辑的最小富文本组件,把富文本内容拆解为不同的块。
  • @blocksuite/block-std:建模可编辑块的跨框架的库,涵盖了事件、选中、剪切板等。
  • @blocksuite/blocks:默认的组成预置编辑器的块实现,包含各个块的 Widget。
  • @blocksuite/presets:即插即用的编辑器组件(PageEditor、EdgelessEditor)和辅助的UI组件(DocTitle 等)。

Component Types

Fragment 提供了更简单的能力,为了一些 UI 上的目的,比如说目录啊、工具栏啊,这都是相对简单的,也是可独立于编辑功能的。

Editor 就比较复杂了,它提供了编辑上的所有能力。

但是呢,他俩共享数据流。

Block 是组成 Editor 的重要部分,每一个块都封装了数据模式、视图以及组成 Editor 的逻辑。

Widget 则是 Block 中的某个具体实现,抽象了比如 菜单、拖拽等功能。

我们来看看,PageEditor,它就是传统的流式内容编辑器,有这些功能:

Edgeless Editor ,它提供了一个画板,可以无限延展,用于白板等图编辑场景,无边记,苹果的这个产品,是不是引起你的联想呢?

  • 包含所有 PageEditor 的富文本编辑功能
  • H5 画布,形状、刷子、文本,你想要的一切
  • 演讲者模式
  • link cards
  • 自定义工具栏
  • Real-time collaboration
  • Document streaming

Data Synchronization

从传统的富文本编辑器来看,你的直观想法是用 JSON 存储,这种想法咱们也支持,使用我们提供的 Snapshot API 即可。

import { Job } from '@blocksuite/store';

const { collection } = doc;

// A job is required for performing the tasks
const job = new Job({ collection });

// Export current doc content to snapshot JSON
const json = await job.docToSnapshot(doc);

// Import snapshot JSON to a new doc
const newDoc = await job.snapshotToDoc(json);

除了 Snapshot 之外,还有 Adapter API,它是建立在 Snapshot 之上的,能处理不同的文档树之间的通信,也能支持第三方格式如 Markdown、HTML 等。

与上面说的传统的存储机制不同,BlockSuite原生支持状态管理,这种情况下,服务器存的就不是 JSON 了,而是 CRDT 数据结构的二进制表示,跟 Protobuf 类似。

CRDT 能自动解决冲突,在远程文档和本地文档之间的同步就能可靠完成了。

Working with Block Tree

每个 doc 对象管理独立的 block 树,每个 block 有个独一无二的标识 namespace:name

要操作 block,你可以使用多个 API:

所有 doc 上的 block 操作都可以用 doc.undo()doc.redo() 来撤销和重做。当然,你也可以显式地通过 doc.captureSync() 增加历史记录,这种情况当你一次加入多个块却又想挨个重做时很有用。

又有一些概念出来了,host 和 std。editor.host 也就是 EditorHost 组件,是挂载 block UI 组件的容器,std 是用来无视框架直达 block 标准库的工具,也经常用 host.spec 来简化 host.std.spec 。

其他的,我觉得多少有些不必看了。

集成到 Vue 3

直接看项目下的 examples 文件夹:

https://github.com/toeverything/blocksuite/tree/master/examples/vue-basic

comments powered by Disqus

相关文章

用 Beancount 复式记账,Double-Entry!

🤔动机 已经有很多次记账的尝试,包括各种 App 如圈子账本(现已倒闭下架)等。但有几个痛点还没法解决: 大多数都是简单的记载收支,这对手握多个银行账户、信用卡等的我来说,显得不够用 数据安全问题,数据在服务提供者

阅读更多

Neo4j: 图数据基本概念、语法与增删改查

Neo4j 简介 Neo4j 使用属性图(Property Graph)模型1。 一个图包含节点(Objects)和边(Relationships)。 Neo4j 的属性图模型包含了: 节点 节点标签:用于区分节点的类型,0个或多个 边:源节点

阅读更多

在电脑上安装 Openwrt 作为旁路网关

🤔场景 既然回家了,有了家用路由器,就希望各个设备能够不需要安装对应的软件而直接科学上网、屏蔽广告等。 但原来的路由器太小众,没人提供相应的固件,也就是说没法刷机。 后来,我看到有关旁路网关的介绍,觉得这可

阅读更多