@@ -10,17 +10,17 @@ synced to the cloud. The data lives in your Convex database, and can be stored
1010alongside the rest of your app's data.
1111
1212Just configure your editor features, add this component to your Convex backend,
13- and use the ` useTipTapSync ` React hook.
13+ and use the ` useTiptapSync ` React hook.
1414
1515This is a [ Convex Component] ( https://convex.dev/components ) that syncs a
1616[ ProseMirror] ( https://prosemirror.net/ ) document between clients via a
17- [ TipTap ] ( https://tiptap.dev/ ) extension.
17+ [ Tiptap ] ( https://tiptap.dev/ ) extension.
1818
1919Example usage, see [ below] ( #usage ) for more details:
2020
2121``` tsx
2222function CollaborativeEditor() {
23- const sync = useTipTapSync (api .prosemirrorSync , " some-id" );
23+ const sync = useTiptapSync (api .prosemirrorSync , " some-id" );
2424 return sync .isLoading ? (
2525 <p >Loading...</p >
2626 ) : sync .initialContent !== null ? (
@@ -40,7 +40,7 @@ Features:
4040
4141- Safely merges changes between clients via operational transformations (OT).
4242- Simple React hook to fetch the initial document and keep it in sync via a
43- TipTap extension.
43+ Tiptap extension.
4444- Server-side entrypoints for authorizing reads, writes, and snapshots.
4545- Create a new document, online or offline.
4646- Debounced snapshots allow new clients to avoid reading the full history.
@@ -64,7 +64,7 @@ Future that could be added later:
6464- Warning when closing tab with unsynced changes (works by default?).
6565- Vacuuming controls for old deltas & snapshots.
6666- Add a BlockNote convenience wrapper.
67- - Convert it to a ProseMirror plugin instead of a TipTap extension, so raw
67+ - Convert it to a ProseMirror plugin instead of a Tiptap extension, so raw
6868 ProseMirror usecases can also use it.
6969- Handling edge cases, such as old clients with local changes on top of an older
7070 version of the document where the steps necessary for them to rebase their
@@ -126,7 +126,7 @@ export default app;
126126## Usage
127127
128128To use the component, you expose the API in a file in your ` convex/ ` folder, and
129- use the ` useTipTapSync ` hook in your React components, passing in a reference to
129+ use the ` useTiptapSync ` hook in your React components, passing in a reference to
130130the API you defined. For this example, we'll create the API in
131131` convex/example.ts ` .
132132
@@ -147,21 +147,21 @@ export const {
147147});
148148```
149149
150- In your React components, you can use the ` useTipTapSync ` hook to fetch the
151- initial document and keep it in sync via a TipTap extension. ** Note** : This
150+ In your React components, you can use the ` useTiptapSync ` hook to fetch the
151+ initial document and keep it in sync via a Tiptap extension. ** Note** : This
152152requires a
153153[ ` ConvexProvider ` ] ( https://docs.convex.dev/quickstart/react#:~:text=Connect%20the%20app%20to%20your%20backend )
154154to be in the component tree.
155155
156156``` tsx
157157// src/MyComponent.tsx
158- import { useTipTapSync } from " @convex-dev/prosemirror-sync/tiptap" ;
158+ import { useTiptapSync } from " @convex-dev/prosemirror-sync/tiptap" ;
159159import { EditorContent , EditorProvider } from " @tiptap/react" ;
160160import StarterKit from " @tiptap/starter-kit" ;
161161import { api } from " ../convex/_generated/api" ;
162162
163163function MyComponent() {
164- const sync = useTipTapSync (api .example , " some-id" );
164+ const sync = useTiptapSync (api .example , " some-id" );
165165 return sync .isLoading ? (
166166 <p >Loading...</p >
167167 ) : sync .initialContent !== null ? (
@@ -184,9 +184,28 @@ See a working example in [example.ts](./example/convex/example.ts) and
184184
185185## Notes
186186
187+ ### Configuring the snapshot debounce interval
188+
189+ The snapshot debounce interval is set to one second by default.
190+ You can specify a different interval with the ` snapshotDebounceMs ` option when
191+ calling ` useTiptapSync ` .
192+
193+ A snapshot won't be sent until both of these are true:
194+
195+ - The document has been idle for the debounce interval.
196+ - The current user was the last to make a change.
197+
198+ There can be races, but since each client will submit the snapshot for their
199+ own change, they won't conflict with each other and are safe to apply.
200+
187201### Creating a new document
188202
189- You can create a new document from the client by calling ` sync.create(content) ` .
203+ You can create a new document from the client by calling ` sync.create(content) ` , or on the server by calling ` prosemirrorSync.create(ctx, id, content) ` .
204+
205+ The content should be a JSON object matching the
206+ [ Schema] ( https://tiptap.dev/docs/editor/core-concepts/schema ) .
207+
208+ For client-side document creation:
190209
191210- While it's safest to wait until the server confirms the document doesn't exist
192211 yet (` !sync.isLoading ` ), you can choose to call it while offline with a newly
@@ -195,7 +214,7 @@ You can create a new document from the client by calling `sync.create(content)`.
195214 initial version and all local changes as steps.
196215- If multiple clients create the same document, it will fail if they submit
197216 different initial content.
198- - Note: if you don't open that document (` useTipTapSync ` ) while online, it won't
217+ - Note: if you don't open that document (` useTiptapSync ` ) while online, it won't
199218 sync.
200219
201220<!-- END: Include on https://convex.dev/components -->
0 commit comments