Skip to content

Commit

Permalink
WIP: refactor to separate server and hocuspocus (#686)
Browse files Browse the repository at this point in the history
* WIP: refactoring hocuspocus and moved listen function to server instead

* Moved port and address from hocuspocus to server entirely

* WIP Fixing tests

* Fixing tests

* Removed port from onConfigure test

* Fixed tests

* Moved destroy also to server

* Updated documentation

* WIP Upgrade guide

* Added upgrade to listen method on server

* Fixed typos

* change URL of Tiptap Cloud

---------

Co-authored-by: Patrick Baber <[email protected]>
Co-authored-by: Jan Thurau <[email protected]>
  • Loading branch information
3 people authored Sep 2, 2024
1 parent e7cd487 commit 90e9a25
Show file tree
Hide file tree
Showing 49 changed files with 1,182 additions and 1,006 deletions.
4 changes: 2 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ yarn add @hocuspocus/server y-protocols yjs
### Usage

```js
import { Hocuspocus } from "@hocuspocus/server";
import { Server } from "@hocuspocus/server";

// Configure the server …
const server = new Hocuspocus({
const server = new Server({
port: 1234,
});

Expand Down
4 changes: 2 additions & 2 deletions docs/guides/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ For more information on the hook and its payload, check out its [section](/serve
```js
import { Server } from "@hocuspocus/server";

const server = Server.configure({
const server = new Server({
async onAuthenticate(data) {
const { token } = data;

Expand Down Expand Up @@ -60,7 +60,7 @@ import { Server } from "@hocuspocus/server";

const usersWithWriteAccess = ["jane", "john", "christina"];

const server = Server.configure({
const server = new Server({
async onAuthenticate(data): Doc {
// Example code to check if the current user has write access by a
// request parameter. In a real world application you would probably
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/custom-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ That's it. The only thing missing now is your code. Happy extension writing! Whe
import { Server } from "@hocuspocus/server";
import { MyHocuspocusExtension } from "./extensions/my-hocuspocus-extension";

const server = Server.configure({
const server = new Server({
extensions: [
new MyHocuspocusExtension({
myConfigurationOption: "baz",
Expand Down
6 changes: 4 additions & 2 deletions docs/guides/multi-subdocuments.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ console.log(entityType); // prints "page"
console.log(entityID); // prints "140
```

This is a recommendation, of course you can name your documents however you want!
This is a recommendation, of course you can name your documents whatever you want!

## Nested documents

Expand Down Expand Up @@ -70,6 +70,7 @@ import { TiptapTransformer } from "@hocuspocus/transformer";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";

const generateSampleProsemirrorJson = (text: string) => {
return {
type: "doc",
Expand All @@ -86,7 +87,8 @@ const generateSampleProsemirrorJson = (text: string) => {
],
};
};
const server = Server.configure({

const server = new Server({
async onLoadDocument(data) {
// only import things if they are not already set in the primary storage
if (data.document.isEmpty("default")) {
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/persistence.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ To persist the documents you must instruct the server to:
1. Store the document in the `onStoreDocument` hook (which is the same as the `onChange` but with debounce already configured).
2. Load the document from the database using the `onLoadDocument` hook.

Actually, you don't even have to use those 2 hooks! We have already created on top of them a simple abstraction in the form of a [database extension](https://tiptap.dev/hocuspocus/server/extensions#database).
Actually, you don't even have to use those 2 hooks! We have already created on top of them a simple abstraction in the form of a [database extension](/server/extensions/database).

However, in case you are a curious mind, here is an example of what it would be like to do it with hooks (It can be a good way to familiarize yourself with the concepts).

Expand All @@ -20,7 +20,7 @@ import { Doc } from "yjs";

let debounced;

const server = Server.configure({
const server = new Server({
async onStoreDocument(data) {
// Save to database. Example:
// saveToDatabase(data.document, data.documentName);
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/scalability.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tableOfContents: true
## Introduction

If you are trying to deploy Hocuspocus in a HA setup or solve issues due to too many connections / network traffic,
you can use our redis extension: [extension-redis](/server/extensions#redis).
you can use our redis extension: [extension-redis](/server/extensions/redis).

Yjs is really efficient (see https://blog.kevinjahns.de/are-crdts-suitable-for-shared-editing/), so if you're having issues about
cpu / memory usage, our suggested solution at the moment is to deploy multiple independent Hocuspocus instances and split users by a document
Expand Down
17 changes: 17 additions & 0 deletions docs/links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
type: sponsor
- title: Contributing
link: /contributing
- title: Upgrade Guide
link: /upgrade

- title: Server
items:
Expand All @@ -17,12 +19,27 @@
type: new
- title: Configuration
link: /server/configuration
- title: Usage
link: /server/usage
- title: Methods
link: /server/methods
- title: Hooks
link: /server/hooks
- title: Extensions
link: /server/extensions
items:
- title: Database
link: /server/extensions/database
- title: SQLite
link: /server/extensions/sqlite
- title: Redis
link: /server/extensions/redis
- title: Logger
link: /server/extensions/logger
- title: Webhook
link: /server/extensions/webhook
- title: Throttle
link: /server/extensions/throttle
- title: Examples
link: /server/examples

Expand Down
46 changes: 23 additions & 23 deletions docs/provider/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ tableOfContents: true

## Settings

| Setting | Description | Default Value |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `url` | The URL of the Hocuspocus/WebSocket server. | `''` |
| `parameters` | Parameters will be added to the server URL and passed to the server. | `{}` |
| `name` | The name of the document. | `''` |
| `document` | The actual Y.js document. Optional, by default a new document is created and be access through provider.document. | `new Y.Doc()` |
| `token` | An authentication token that will be passed to the server (works with strings, functions and Promises). | `''` |
| `awareness` | Awareness object, by default attached to the passed Y.js document. | `new Awareness()` |
| `connect` | Whether to connect to the server after initialization. | `true` |
| `preserveConnection` | Whether to preserve the websocket connection after closing the provider. | `true` |
| `broadcast` | By default changes are synced between browser tabs through broadcasting. | `true` |
| `forceSyncInterval` | Ask the server every x ms for updates. | `false` |
| `delay` | The delay between each attempt in milliseconds. You can provide a factor to have the delay grow exponentially. | `1000` |
| `initialDelay` | The intialDelay is the amount of time to wait before making the first attempt. This option should typically be 0 since you typically want the first attempt to happen immediately. | `0` |
| `factor` | The factor option is used to grow the delay exponentially. | `2` |
| `maxAttempts` | The maximum number of attempts or 0 if there is no limit on number of attempts. | `0` |
| `minDelay` | minDelay is used to set a lower bound of delay when jitter is enabled. This property has no effect if jitter is disabled. | `1000` |
| `maxDelay` | The maxDelay option is used to set an upper bound for the delay when factor is enabled. A value of 0 can be provided if there should be no upper bound when calculating delay. | `30000` |
| `jitter` | If jitter is true then the calculated delay will be a random integer value between minDelay and the calculated delay for the current iteration. | `true` |
| `timeout` | A timeout in milliseconds. If timeout is non-zero then a timer is set using setTimeout. If the timeout is triggered then future attempts will be aborted. | `0` |
| `messageReconnectTimeout` | Closes the connection when after the configured messageReconnectTimeout no message was received. | `30000` |
| `WebSocketPolyfill` | Running in Node.js: Pass a WebSocket polyfill, for example ws. | `WebSocket` |
| `quiet` | The provider will output a few warnings to help you. In case you want to disable those, just set quiet to true. | `false` |
| Setting | Description | Default Value |
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
| `url` | The URL of the Hocuspocus/WebSocket server. | `''` |
| `parameters` | Parameters will be added to the server URL and passed to the server. | `{}` |
| `name` | The name of the document. | `''` |
| `document` | The actual Y.js document. Optional, by default a new document is created and be access through provider.document. | `new Y.Doc()` |
| `token` | An authentication token that will be passed to the server (works with strings, functions and Promises). | `''` |
| `awareness` | Awareness object, by default attached to the passed Y.js document. | `new Awareness()` |
| `connect` | Whether to connect to the server after initialization. | `true` |
| `preserveConnection` | Whether to preserve the websocket connection after closing the provider. | `true` |
| `broadcast` | By default changes are synced between browser tabs through broadcasting. | `true` |
| `forceSyncInterval` | Ask the server every x ms for updates. | `false` |
| `delay` | The delay between each attempt in milliseconds. You can provide a factor to have the delay grow exponentially. | `1000` |
| `initialDelay` | The initialDelay is the amount of time to wait before making the first attempt. This option should typically be 0 since you typically want the first attempt to happen immediately. | `0` |
| `factor` | The factor option is used to grow the delay exponentially. | `2` |
| `maxAttempts` | The maximum number of attempts or 0 if there is no limit on number of attempts. | `0` |
| `minDelay` | minDelay is used to set a lower bound of delay when jitter is enabled. This property has no effect if jitter is disabled. | `1000` |
| `maxDelay` | The maxDelay option is used to set an upper bound for the delay when factor is enabled. A value of 0 can be provided if there should be no upper bound when calculating delay. | `30000` |
| `jitter` | If jitter is true then the calculated delay will be a random integer value between minDelay and the calculated delay for the current iteration. | `true` |
| `timeout` | A timeout in milliseconds. If timeout is non-zero then a timer is set using setTimeout. If the timeout is triggered then future attempts will be aborted. | `0` |
| `messageReconnectTimeout` | Closes the connection when after the configured messageReconnectTimeout no message was received. | `30000` |
| `WebSocketPolyfill` | Running in Node.js: Pass a WebSocket polyfill, for example ws. | `WebSocket` |
| `quiet` | The provider will output a few warnings to help you. In case you want to disable those, just set quiet to true. | `false` |

## Usage

Expand Down
2 changes: 1 addition & 1 deletion docs/provider/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const provider = new HocuspocusProvider({
```

## Option 2: Binding
Sometimes you want to register an event listener after the intialization, even if it’s right after. Also, that’s a great way to bind and unbind event listeners.
Sometimes you want to register an event listener after the initialization, even if it’s right after. Also, that’s a great way to bind and unbind event listeners.

### Bind event listeners

Expand Down
2 changes: 0 additions & 2 deletions docs/provider/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,4 @@ const provider2 = new TiptapCollabProvider({
name: 'document2',
token: '',
})


```
2 changes: 1 addition & 1 deletion docs/provider/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Providers are the Y.js way to set up communication between different users, or c

It’s coming with WebSocket message authentication, a debug mode to add verbose output to the console, a few more event hooks, a different reconnection strategy, an improved error handling and a friendly API for the Awareness protocol.

All Y.js providers can be used together. That includes the Hocuspocus provider, and the original [y-websocket](https://github.com/yjs/y-websocket) provider, [y-webrtc](https://github.com/yjs/y-webrtc), [y-indexeddb](https://github.com/yjs/y-indexeddb) (for in-browser caching) or [y-dat](https://github.com/yjs/y-dat) (work in progress). You can use the Hocuspocus provider with y-webrtc and other y-providers, but when using Hocuspocus you'll have to use our HocuspocusProvider, and server implementations apart from hocuspocus probably won't work too. You can however instanciate multiple providers if you want to synchronize with Hocuspocus and other servers.
All Y.js providers can be used together. That includes the Hocuspocus provider, and the original [y-websocket](https://github.com/yjs/y-websocket) provider, [y-webrtc](https://github.com/yjs/y-webrtc), [y-indexeddb](https://github.com/yjs/y-indexeddb) (for in-browser caching) or [y-dat](https://github.com/yjs/y-dat) (work in progress). You can use the Hocuspocus provider with y-webrtc and other y-providers, but when using Hocuspocus you'll have to use our HocuspocusProvider, and server implementations apart from hocuspocus probably won't work too. You can however instantiate multiple providers if you want to synchronize with Hocuspocus and other servers.
2 changes: 1 addition & 1 deletion docs/server/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ There are only a few settings to pass for now. Most things are controlled throug
```js
import { Server } from "@hocuspocus/server";

const server = Server.configure({
const server = new Server({
name: "hocuspocus-fra1-01",
port: 1234,
timeout: 30000,
Expand Down
Loading

0 comments on commit 90e9a25

Please sign in to comment.