Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dev/docker/hocuspocus/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.DS_Store
*.log
12 changes: 12 additions & 0 deletions dev/docker/hocuspocus/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json ./
RUN npm install --omit=optional --no-audit --no-fund

FROM node:22-alpine
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY package.json tsconfig.json server.ts ./
ENV NODE_ENV=production
EXPOSE 9400
CMD ["npx", "tsx", "server.ts"]
125 changes: 125 additions & 0 deletions dev/docker/hocuspocus/IMPLEMENTATION_NOTES.md

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions dev/docker/hocuspocus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Hocuspocus dev server

Dev-only Y.js / Hocuspocus backend for collaborative editing in the OpenCloud Web
tiptap editor. Brokers Y.Doc state between connected clients and persists each
document to OpenCloud via WebDAV.

This service is part of the docker-compose dev stack only. It is **not** meant
to run in production.

## What it does

- Verifies the client's OpenCloud access token (OIDC JWT) against the IdP JWKS.
- On the first connect to a room, fetches the file from OpenCloud via WebDAV and
seeds a Y.Doc from the content.
- On change, debounces (`SAVE_DEBOUNCE_MS`, default 2 s) and writes the file back
via WebDAV with `If-Match` for optimistic concurrency.
- On the last disconnect, flushes immediately.

## Scope

Markdown (`.md`) and plain-text files only for the first cut. Other content
types fall back to the editor's existing single-user flow.

## Schema parity warning

The tiptap extension versions in `package.json` must match the versions used
by `packages/web-pkg`. A mismatch can silently corrupt the Y.Doc state because
the ProseMirror node specs diverge.

## Env

| Var | Default | Notes |
| ------------------------------ | ----------------------------------- | ---------------------------------- |
| `PORT` | `9400` | Hocuspocus WebSocket port |
| `OC_URL` | `https://host.docker.internal:9200` | OpenCloud base URL (WebDAV target) |
| `IDP_ISSUER` | same as `OC_URL` | OIDC issuer for JWT verification |
| `SAVE_DEBOUNCE_MS` | `2000` | WebDAV write-back debounce |
| `NODE_TLS_REJECT_UNAUTHORIZED` | `0` (set by compose) | **Dev only** — accept self-signed |
38 changes: 38 additions & 0 deletions dev/docker/hocuspocus/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@opencloud-eu/dev-hocuspocus",
"version": "0.0.0",
"private": true,
"type": "module",
"description": "Dev-only Hocuspocus server for the OpenCloud Web tiptap editor. Bridges Y.Doc state to OpenCloud via WebDAV.",
"scripts": {
"start": "tsx server.ts",
"dev": "tsx watch server.ts"
},
"dependencies": {
"@hocuspocus/extension-logger": "^2.15.2",
"@hocuspocus/server": "^2.15.2",
"@tiptap/core": "^3.23.5",
"@tiptap/extension-document": "^3.20.4",
"@tiptap/extension-hard-break": "^3.20.4",
"@tiptap/extension-image": "^3.20.4",
"@tiptap/extension-link": "^3.20.4",
"@tiptap/extension-paragraph": "^3.20.4",
"@tiptap/extension-table": "^3.20.4",
"@tiptap/extension-task-item": "^3.20.4",
"@tiptap/extension-task-list": "^3.20.4",
"@tiptap/extension-text": "^3.20.4",
"@tiptap/markdown": "^3.20.4",
"@tiptap/pm": "^3.20.4",
"@tiptap/starter-kit": "^3.20.4",
"jose": "^5.9.6",
"jsdom": "^25.0.1",
"undici": "^6.20.1",
"y-prosemirror": "^1.2.13",
"yjs": "^13.6.20"
},
"devDependencies": {
"@types/node": "^22.9.0",
"tsx": "^4.19.2",
"typescript": "^6.0.3"
}
}
Loading
Loading