@ecsplico/编辑器
TipTap v3上的 Vue and React 编辑器库. 编辑器从 特性页:1 简单 编辑器是唯一的核心功能(格式化、标题、列表、引用、代码、撤销/重写),不需要后端、Yjs和特征代码 高级 编辑器将每个功能(媒体,提及,笔录,复合材料,作者,评论,AI,合作,块UI,全站Obsidian主题及其集成)编成两面. 无框架 ./core 拥有特性模型,每个特性的逻辑也是无框架的(./<feature>: 一个特性由打入的 UI 绑定 (单位:千美元)<x>FeatureCore(ui)即Vue层(./<feature>/vue, Nuxt UI 铬)和反应层(./<feature>/react,Radix和Tailwind上的shadcn/ui)填充其组件,节点视图和通知接合. 工具栏、设置面板和模式、外观、 AI 侧边栏、 注释边框、 复合表和检查器, 文件浏览器是您放置在编辑器旁边任何地方的组件; 两层都传送简单的编辑器(./vue/simple, (中文(简体) ), ./react/simple)和高级编辑(./vue/advanced, (中文(简体) ), ./react/advanced) (中文(简体) ).
先决条件
- 22和22号节点 阿宝 (存储器为 Bun 工作空间 :
packages/*, (中文(简体) ),examples/*) (中文(简体) ). - 基于 Vite 或 Nuxt 的应用程序( Name
@vitejs/plugin-vue编号 :@vitejs/plugin-react,或者说Nuxt). 已发布的软件包是 构建的无害环境管理软件包: 每一个exports子路径解析为dist/**/*.js与.d.ts(Vue SFCs 编译,反应).tsx将汇编成JSX-运行时间JS),CSS表被复制,源图嵌入出处(src它本身没有出版)。 输出是每个源文件一个模块,所以条目保持树能摇动. - 需要的对等依赖( 将它们安装在消费应用程序中, 所以主机和库共享其中的一例 ) :
@tiptap/core, (中文(简体) ),@tiptap/pm, (中文(简体) ),yjs, (中文(简体) ),@hocuspocus/provider. Yjs 和提供者是需要同行的,因为.d.ts参考它们;简单编辑的捆绑并不包含其执行情况(见下文所证实)。 每层( 所有可选的同位素) : 阴道vue, (中文(简体) ),@nuxt/ui, (中文(简体) ),@tiptap/vue-3· ; 反应react, (中文(简体) ),react-dom, (中文(简体) ),@tiptap/react, (中文(简体) ),@iconify/react· ; 代码表面 (单位:千美元)/code(中文(简体) )@codemirror/state, (中文(简体) ),@codemirror/view, (中文(简体) ),@codemirror/language, (中文(简体) ),@codemirror/commands, (中文(简体) ),@codemirror/search, (中文(简体) ),@lezer/highlight,加上@codemirror/lang-*包件您注册( 包件没有). - 尾风 CSS 4 (
tailwindcss用于 Nuxt UI 主题(Vue) 或 shadcn 类(反应),以及图标收藏@iconify-json/lucide。反应主机也需要tw-animate-css(对话框的入出动画,下放和工具提示).
安装
从npmjs(公共,没有标志和没有) .npmrc 所需:
npm install @ecsplico/editor # or: bun add @ecsplico/editor / pnpm add @ecsplico/editor
在这个寄存器内,软件包是一个工作空间成员,所以那里的消费者声明 "@ecsplico/editor": "workspace:*"。 。 。 .
Nuxt 快速启动
安装软件包旁边的对等点( E)vue, (中文(简体) ), @nuxt/ui, (中文(简体) ), @tiptap/core, (中文(简体) ), @tiptap/pm, (中文(简体) ), @tiptap/vue-3, (中文(简体) ), yjs, (中文(简体) ), @hocuspocus/provider, (中文(简体) ), tailwindcss, (中文(简体) ), @iconify-json/lucide),然后登记模块 之后 @nuxt/ui数字 :
// nuxt.config.ts
export default defineNuxtConfig({
ssr: false, // TipTap renders on the client only
modules: ['@nuxt/ui', '@ecsplico/editor/nuxt'],
css: ['~/assets/main.css'],
})
/* app/assets/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
将应用程序包入 <UApp> (单位:千美元)app/app.vue数字 : <UApp><NuxtPage /></UApp>)并在页面上挂载编辑器(简单的编辑器不需要后端):
<script setup lang="ts">
import { SimpleEditor } from '@ecsplico/editor/vue/simple'
import { ref } from 'vue'
const content = ref()
</script>
<template>
<SimpleEditor v-model="content" />
</template>
该模块的 API 路由称为主机 EditorPorts (先确定身份,然后每个能力一个端口: documents, (中文(简体) ), collabState, (中文(简体) ), directory, (中文(简体) ), assets, (中文(简体) ), settings, (中文(简体) ), themes, (中文(简体) ), models, (中文(简体) ), comments) (中文(简体) ). 在硝基插件中注册它们;没有它们,客户端日志“Einstellungen konnten nicht geladen werden”和每条路由回答500个。 这条路线的端口你留下501。 这些最小的端口保留所有记忆,让任何访客进入(替换 authenticate 和你的仓库:
// server/plugins/editor-adapter.ts
import type { JSONContent } from '@tiptap/core'
import { type AssetStore, setEditorPorts } from '@ecsplico/editor/server'
export default defineNitroPlugin(() => {
const contents = new Map<string, JSONContent>()
const states = new Map<string, Uint8Array>()
const assets = new Map<string, Parameters<AssetStore['storeAsset']>[1]>()
setEditorPorts({
// `null` = 401 on API routes; on /collab the socket is closed with 4401 (HTTP 401 at the upgrade with `collab.authenticateUpgrade`)
identity: { authenticate: async () => ({ id: 'demo', username: 'demo' }) },
documents: {
loadContent: async id => contents.get(id) ?? null,
storeContent: async (id, content) => { contents.set(id, content) },
listContents: async () => [...contents].map(([id, content]) => ({ id, content })),
},
collabState: {
loadState: async id => states.get(id) ?? null,
storeState: async (id, state) => { states.set(id, state) },
removeState: async (id) => { states.delete(id) },
},
directory: { listUsers: async () => [] },
assets: {
storeAsset: async (id, asset) => { assets.set(`${id}/${asset.name}`, asset) },
loadAsset: async (id, name) => {
const asset = assets.get(`${id}/${name}`)
if (!asset) return null
const { data, ...record } = asset
return { record, data }
},
},
})
})
高级编辑器、每个适配器方法、协作和AI都包含在 Nuxt 快速启动 编辑 EditorPorts 指南。 。 。 .
建立和发展这一储存库
bun run build:editor (单位:千美元)tsdown配置 packages/editor/tsdown.config.ts)写作 packages/editor/dist:无害环境管理+ .d.ts 每笔 exports 子路径( 条目从 skaile-source 条件 package.json#exports,因此,一旦宣布就新建导出,每个源文件解开一个模块,有嵌入源的源地图,CSS复制,以及Nuxt运行时目录(dist/nuxt/runtime:插件,服务器路由,utils)作为Nuxt和Nitro在主机所编译的模块旁边的独立文件. 依赖和同伴从不捆绑.
每个 exports 条目带有自定义 skaile-source 条件第一(指 src之后是 types编号 :import (或 default)指点 dist。该寄存器的 Nuxt app (nuxt.config.ts)和实例examples/*/vite.config.ts, (中文(简体) ), tsconfig.json#customConditions)为Vite、Nitro和类型检查器提供这种条件,所以 编辑库在 dev 中不需要构建步骤寄存器外的消费者从未设定条件并获得 dist。 。 。 . bun run check:editor-entries 首先建设,然后判断 已建成 输出通过 exports (无) skaile-source),故能证明所发表的内容; bun run check:editor-composition 首先建立并加载已建条目; bun run typecheck:editor 解决 src (单位:千美元)customConditions: ["skaile-source"] 内 packages/editor/tsconfig.json) (中文(简体) ).
文档
这些文件住在 https://skaile-ai.github.io/skaile-editor/* 互联网档案馆的存檔,存档日期2013-12-02* (货包本身已不再是船舶指南):
- 开始: 软件包是什么,安装,快速启动 Nuxt, plain Vue and React, 词汇.
- 教学:一步一步地建立一个编辑器,包括自己的块,后端,AI和回放表面.
- 指南: 特性组成, Nuxt 模块,
EditorPorts,合作,AI,主题,复合材料,文件浏览器,制作,存储适配器,迁移. - 参考文献:每个公共导出,预设和特性,特征合同,CSS和UI提供方的要求,依赖规则,命令,更改日志.
- AI探员: 编码代理如何读取这些文件,整合并扩展编辑器,不变量和校验.
机器可读入点 : llms.txt, (中文(简体) ), llms-full.txt,并安装 Agent Skill:
npx skills add https://skaile-ai.github.io/skaile-editor
可运行实例存在于仓库中 : examples/ 和 Nuxt 应用程序 (bun run dev,第3056号口。 要在文件库的检查中进行文件库的工作,请运行 bun run docs:dev (开发服务器)或 bun run docs:build (静态建筑);见 docs/README.md。 。 。 .