Merge branch 'main' of https://github.com/ueberdosis/tiptap-next into main
This commit is contained in:
@@ -205,17 +205,55 @@ Yes, it’s magic. As already mentioned, that is all based on the fantastic Y.js
|
|||||||
## Store the content
|
## Store the content
|
||||||
Our collaborative editing backend is ready to handle advanced use cases, like authorization, persistence and scaling. Let’s go through a few common use cases here!
|
Our collaborative editing backend is ready to handle advanced use cases, like authorization, persistence and scaling. Let’s go through a few common use cases here!
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
With the `onConnect` hook you can write a custom Promise to check if a client is authenticated. That can be a request to an API, to a microservice, a database query, or whatever is needed, as long as it’s executing `resolve()` at some point. You can also pass contextual data to the `resolve()` method which will be accessible in other hooks.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Server } from '@hocuspocus/server'
|
||||||
|
|
||||||
|
const server = Server.configure({
|
||||||
|
onConnect(data, resolve, reject) {
|
||||||
|
const { requestHeaders } = data
|
||||||
|
// Your code here, for example a request to an API
|
||||||
|
|
||||||
|
// If the user is not authorized …
|
||||||
|
if (requestHeaders.access_token !== 'super-secret-token') {
|
||||||
|
return reject()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set contextual data
|
||||||
|
const context = {
|
||||||
|
user_id: 1234,
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user is authorized …
|
||||||
|
resolve(context)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
server.listen()
|
||||||
|
```
|
||||||
|
|
||||||
### Authorization
|
### Authorization
|
||||||
With the `onJoinDocument` hook you can write a custom Promise to check if a client is authorized. That can be a request to an API, to a microservice, a database query, or whatever is needed, as long as it’s executing `resolve()` at some point.
|
With the `onJoinDocument` hook you can check if a user is authorized to edit the current document. This works in the same way the [Authentication](#authentication) works.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { Server } from '@hocuspocus/server'
|
import { Server } from '@hocuspocus/server'
|
||||||
|
|
||||||
const server = Server.configure({
|
const server = Server.configure({
|
||||||
onJoinDocument(data, resolve, reject) {
|
onJoinDocument(data, resolve, reject) {
|
||||||
const { documentName, clientID, requestHeaders, clientsCount, document } = data
|
const {
|
||||||
|
clientsCount,
|
||||||
|
context,
|
||||||
|
document,
|
||||||
|
documentName,
|
||||||
|
requestHeaders,
|
||||||
|
} = data
|
||||||
// Your code here, for example a request to an API
|
// Your code here, for example a request to an API
|
||||||
|
|
||||||
|
// Access the contextual data from the onConnect hook, in this example this will print { user_id: 1234 }
|
||||||
|
console.log(context)
|
||||||
|
|
||||||
// If the user is authorized …
|
// If the user is authorized …
|
||||||
resolve()
|
resolve()
|
||||||
|
|
||||||
@@ -258,8 +296,14 @@ const server = Server.configure({
|
|||||||
|
|
||||||
// executed when the document is changed
|
// executed when the document is changed
|
||||||
onChange(data) {
|
onChange(data) {
|
||||||
const { documentName, clientID, requestHeaders, clientsCount, document } = data
|
const {
|
||||||
|
clientsCount,
|
||||||
|
document,
|
||||||
|
documentName,
|
||||||
|
requestHeaders,
|
||||||
|
} = data
|
||||||
|
|
||||||
|
// Your code here, for example a request to an API
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ const CollaborationCursor = Extension.create({
|
|||||||
*/
|
*/
|
||||||
user: (attributes: { [key: string]: any }): Command => () => {
|
user: (attributes: { [key: string]: any }): Command => () => {
|
||||||
this.options.user = attributes
|
this.options.user = attributes
|
||||||
|
|
||||||
this.options.provider.awareness.setLocalStateField('user', this.options.user)
|
this.options.provider.awareness.setLocalStateField('user', this.options.user)
|
||||||
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
@@ -66,6 +66,19 @@ const CollaborationCursor = Extension.create({
|
|||||||
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.options.provider.awareness.on('update', () => {
|
||||||
|
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
||||||
|
})
|
||||||
|
|
||||||
|
this.options.provider.on('status', (event: { status: string }) => {
|
||||||
|
if (event.status === 'connected') {
|
||||||
|
// FIX: Reset the awareness state
|
||||||
|
// PR: https://github.com/yjs/y-protocols/issues/7
|
||||||
|
this.options.provider.awareness.setLocalState({})
|
||||||
|
this.options.provider.awareness.setLocalStateField('user', this.options.user)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
|
||||||
|
|
||||||
return this.options.provider.awareness
|
return this.options.provider.awareness
|
||||||
|
|||||||
Reference in New Issue
Block a user