@pedit /服务
运行 pedit serve 对于本地应用程序,pedit保存一个文件的Yjs
文档和写入文件;这个包启动它,检查每个请求,并桥接浏览器的请求
WebSocket到pedit的Unix套接字。您的页面实时编辑文件,同时编辑多个页面,并且
没有空间,中继或帐户。
实验(0。x): API可能会改变。该包随每个pedit版本一起发布 携带相同的版本号;它需要的pedit如下所示。
要求
- 在PATH(或pass)上安装0.4.0或更高版本
bin). 旧版本会被拒绝,并提示如何更新。 - Node 22或更高版本,在macOS或Linux上(Unix套接字;不是Windows)。
安装
npm install @pedit/serve yjs y-protocols y-websocket # the browser client's peers
npm install hono @hono/node-server @hono/node-ws # for the Hono routes
@pedit/serve/client 需要 yjs, y-protocols 和 y-websocket; @pedit/serve/hono 需要 hono.
它们是对等的,所以你的应用会保留一个Yjs副本。
服务器
import { serve } from '@hono/node-server'
import { createNodeWebSocket } from '@hono/node-ws'
import { peditRoutes } from '@pedit/serve/hono'
import { Hono } from 'hono'
const app = new Hono()
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })
const server = serve({ fetch: app.fetch, port: 3000, hostname: '127.0.0.1' })
const routes = peditRoutes({
upgradeWebSocket,
root: '/home/me/notes', // only files under it are served
origins: ['http://127.0.0.1:3000'],
app: 'my-app',
resolve: async (id) => (id === 'todo' ? { path: '/home/me/notes/todo.md', role: 'edit' } : null),
})
app.route('/edit', routes)
injectWebSocket(server)
process.on('SIGINT', () => routes.close().finally(() => process.exit(0)))
浏览器
import { connect } from '@pedit/serve/client'
import { yCollab } from 'y-codemirror.next'
const conn = await connect('/edit', 'todo', { name: 'Ann' })
conn.status.subscribe((status, error) => {
if (error?.code === 'gone') showReload() // your UI
})
const extensions = [yCollab(conn.text, conn.awareness)] // plus basicSetup, EditorState.readOnly for 'read'
API
@pedit/serve/hono
| 出口 | |
|---|---|
peditRoutes(options) | Hono应用程序: POST /:id/session 和WebSocket GET /:id/doc. 有 close(). |
options.resolve(id, c) | 将id映射到 { path, role: 'edit' | 'read' },或者 null 为404。 |
options.root, origins, app | 所服务的目录、确切的页面起源,以及在另一个进程持有该文件时显示的标签。 |
options.bin, idleMs, allowRemote, onEvent | pedit的绝对路径;空闲停止(默认60秒);接受非环回对等体(默认为false); started/stopped/error 事件。 |
@pedit/serve/client
| 出口 | |
|---|---|
connect(base, id, { name, color }) | 在第一次同步后解析 { doc, text, awareness, role, status, synced, destroy }. |
conn.status | get() 和 subscribe(cb);州 connecting, connected, reconnecting, closed. |
PeditError.code | not-found, held, busy, forbidden, gone, unavailable. |
@pedit/serve
| 出口 | |
|---|---|
ServedFiles | 路线下面的图层: acquire(path) 启动或重用一个孩子, close() 所有的结束。 |
resolvePedit({ bin }), MIN_PEDIT_VERSION | 查找pedit,检查二进制文件及其版本。 |
HeldError, LimitError, NoPeditError | 另一个进程提供文件;32个文件或8个客户端;Pedit丢失或太老。 |
安全模型
- 一钩,
resolve,决定存在哪些id及其角色。默认情况下,拒绝其他所有请求。 - 文件必须在
root(realpath检查);id[A-Za-z0-9_-]只有。 - 主机和源必须匹配
origins,并且对等体必须在环回,除非allowRemote是集。 - 会话令牌是单次使用并在60秒内过期;它在WebSocket URL中传播,所以日志号
token. - 一、
read角色由pedit本身强制执行,而不仅仅是由页面强制执行:来自读取器的更新关闭套接字。 - 浏览器永远不会看到路径、pid或套接字名称。
已知的限制
- Unix;一个id是一个文件;最多32个文件,每个文件8个客户机。
- 感知(名称、游标)是未经身份验证的:任何连接的页面都可以声明任何名称。
gone: pedit的保存状态被丢弃,因此该页的副本不能合并到新文档中。 客户端停止;应用程序决定是提供文本还是重新加载。- 在连接页面时不要自己写文件。
设计: 文档/设计/ serve.md. 示例: 例子/ serve-app. 麻省理工学院的许可。