@adonis-agora/collaboration

中文文档
0.20.2发布于 2026/11/04MITTypeScriptES Module构建来源已验证近 30 天下载 2243

Collaborative editing (CRDT) for AdonisJS 7 — Yjs (Hocuspocus) and Automerge drivers, Redis-backed presence, unified version control. Part of the Agora ecosystem.

原始使用文档
文档目录12 节
  1. Install
  2. Quick start
  3. Engines
  4. Admission and host-owned rooms ( yjs )
  5. Server API
  6. Client hooks (React)
  7. Codegen
  8. Commands
  9. Typed document registry
  10. REST endpoints
  11. Editor binding (Tiptap)
  12. License

@adonis-agora/collaboration

npm version npm downloads CI license

Collaborative editing (CRDT) for AdonisJS — Yjs (Hocuspocus), Automerge and PartyKit (edge) drivers, Redis-backed presence, unified version control, anchored comments, ace codegen and React client hooks. Part of the Agora ecosystem.

Install

node ace add @adonis-agora/collaboration

Quick start

node ace configure @adonis-agora/collaboration   # provider + config/collaboration.ts
node ace collaboration:init                       # REST routes, controller, migrations
node ace make:collab-document researches/writing  # shared types per document

Wire config/collaboration.ts with your authorize() (the lib never authorizes by default) and a storage backend (LucidStorage, FileSystemStorage or your own).

Engines

EngineSync runs onBest for
yjs (default)Embedded Hocuspocus on the Adonis HTTP serverSelf-hosted, single origin
automergeCustom room broadcast on Adonis serverNative history
partykitCloudflare Workers + Durable Objects (edge)Global latency, separate origin

PartyKit setup:

// config/collaboration.ts
{
  engine: 'partykit',
  partykit: { roomHost: 'meu-app.partykit.dev', jwtSecret: process.env.COLLAB_JWT_SECRET },
}

Then run collaboration:init --engine=partykit to scaffold the worker into partykit-worker/ and deploy with npx partykit deploy.

Admission and host-owned rooms (yjs)

Two optional hooks for apps that own a room's durable state themselves. Both apply to the self-hosted yjs engine only; other engines ignore them (except that persistDocument refuses an ephemeral room on any engine):

// config/collaboration.ts
{
  // Opened after the token is verified and before `authorize`. It ends exactly once:
  // `connected()` when the handshake completes, `closed()` when it never does
  // (denied, authorize threw, socket dropped, shutdown). A later disconnect of a
  // connected socket is not an admission event.
  async beginAdmission(ctx, docName, socketId) {
    return { connected: async () => {}, closed: async () => {} }
  },
  // Loaded through `storage.loadDocument`, but never seeded, stored, flushed on
  // unload, versioned or restored by the driver — the app persists it its own way.
  isEphemeralRoom: (docName) => docName.startsWith('projects/'),
}

Server API

import collaboration from '@adonis-agora/collaboration/services/main'

await collaboration.current.getDocumentText('researches/42/writing')
const version = await collaboration.current.createVersion('researches/42/writing', userId, 'v1')
collaboration.current.comments.list('researches/42/writing', 'text')

Version control works across engines: full-update snapshots (Yjs/PartyKit) or native heads (Automerge). Comments are anchored per space (text-range, canvas-object, timestamp) and persisted via the storage backend.

Client hooks (React)

pnpm add @adonis-agora/collaboration-client
import {
  CollaborationProvider,
  useCollabDoc,
  useAwareness,
  useComments,
  useVersions,
} from '@adonis-agora/collaboration-client'

<CollaborationProvider baseUrl="https://api.app" getHeaders={() => ({ cookie })}>
  <Editor docName="researches/42/writing" />
</CollaborationProvider>

function Editor({ docName }: { docName: string }) {
  const { doc, status } = useCollabDoc(docName)   // Y.Doc + connection status
  const { peers } = useAwareness(docName)
  const { comments, create, resolve } = useComments(docName, 'text')
  const { versions, create: createVersion } = useVersions(docName)
  // feed doc into Tiptap/y-prosemirror…
}

The transport is chosen automatically from the engine reported by GET /collaboration/token (HocuspocusProvider or YPartyKitProvider).

Codegen

Commands

  • collaboration:init — scaffolds the documents directory, base migrations (when a database is configured) and the PartyKit worker (--engine=partykit)
  • collaboration:prune --keep=20 [--doc=<name>] [--dry-run] — deletes all but the N most recent versions of each document (same call as collaboration.pruneVersions({ keep }))
  • make:collab-document <name> — generates shared document types in app/collaboration/documents/ (spaces + allowed anchor kinds), importable by the frontend

Commands are registered automatically by configure; manual setups need commands: ['@adonis-agora/collaboration/commands'] in adonisrc.ts.

Typed document registry

The package ships an Assembler init hook (registered by configure) that scans app/collaboration/documents/ and generates .adonisjs/collaboration/documents.ts:

import type { CollabDocumentName, CollabDocumentDefinition } from '.adonisjs/collaboration/documents.js'

function open(name: CollabDocumentName) { … }   // autocomplete + exhaustiveness

Refresh it with node ace codegen, the dev server, tests or build — same lifecycle as controllers/routes barrels.

REST endpoints

Ten endpoints ship built-in (token, comments CRUD, versions, binary state) and are registered automatically on boot under /collaboration.

Protect them via config — any Adonis middleware or auth guard works:

// config/collaboration.ts
routes: {
  enabled: true,
  prefix: '/collaboration',
  middleware: [() => import('#middleware/auth_middleware')], // guards apply here
}

Prefer full control? Disable and register manually where you want:

// routes.enabled = false
import { collaborationRoutes } from '@adonis-agora/collaboration'

collaborationRoutes(router, {
  prefix: '/api/collab',
  middleware: [authMiddleware],
})

Without a resolver the token endpoint fails closed (401): pass routes.resolveUser or run your auth middleware first. The binary state POST is machine-to-machine (PartyKit worker → Adonis) and requires the shared worker secret instead of a user.

Route type-safety caveat: auto-registered routes live in the provider's ready() phase, which runs after the codegen warmup — so they may not appear in .adonisjs/server/routes.d.ts. If your app relies on generated route types (e.g. Tuyau), use manual mode: set routes.enabled = false and call collaborationRoutes(router) in start/routes.ts, where routes are always picked up.

Editor binding (Tiptap)

The client hooks hand you a plain Y.Doc — feed it straight into Tiptap:

import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
import { useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { useCollabDoc, useAwareness } from '@adonis-agora/collaboration-client'

function Editor({ docName, user }: { docName: string; user: { name: string; color: string } }) {
  const { doc, status } = useCollabDoc(docName)
  const { peers } = useAwareness(docName)

  const editor = useEditor({
    extensions: [
      StarterKit,
      Collaboration.configure({ document: doc }),
      CollaborationCursor.configure({ user }),
    ],
    editable: status === 'connected',
  })

  return (
    <>
      <EditorContent editor={editor} />
      {peers.map((peer) => (
        <span key={peer.clientId} style={{ color: 'gray' }}>{peer.name ?? 'anon'}</span>
      ))}
    </>
  )
}

License

MIT

版本与发布记录

@adonis-agora/collaboration 共发布 44 个版本,首次发布于 2026/08/25;过去 12 个月发布了 44 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.20.2latest2026/11/043 天前
0.20.12026/11/016 天前
0.20.02026/10/2910 天前
0.19.32026/10/2810 天前
0.19.22026/10/2810 天前
0.19.12026/10/2711 天前

关于 @adonis-agora/collaboration 的常见问题

@adonis-agora/collaboration 是什么?

Collaborative editing (CRDT) for AdonisJS 7 — Yjs (Hocuspocus) and Automerge drivers, Redis-backed presence, unified version control. Part of the Agora ecosystem.

如何安装 @adonis-agora/collaboration?

在项目目录运行 npm install @adonis-agora/collaboration,或使用 pnpm add / yarn add / bun add。

@adonis-agora/collaboration 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adonis-agora/collaboration 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adonis-agora/collaboration 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@adonis-agora/collaboration 可以商用吗?

@adonis-agora/collaboration 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adonis-agora/collaboration 的下载量有多少?

根据 npm 官方下载统计,@adonis-agora/collaboration 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,243 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adonis-agora/collaboration 还在维护吗?

最新版本 0.20.2 发布于 2026/11/04(3 天前);至今共发布 44 个版本,其中过去 12 个月发布了 44 个;首次发布于 2026/08/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。