extensions.js
1// src/ffi/extensions.js
2// This file exports the TipTap extensions configuration.
3
4import StarterKit from "@tiptap/starter-kit";
5import { Waypoint } from "./waypoint";
6import { Collaboration } from "@tiptap/extension-collaboration";
7import { IndexeddbPersistence } from "y-indexeddb";
8import { createYjsProvider } from "@y-sweet/client";
9
10/**
11 * Configure the editor extensions in JS and use Rescript interop
12 * @param {import('yjs').Doc} doc - The Yjs document instance from the yjs library
13 * @param {string} id - The document ID
14 * @returns {Array<import('@tiptap/core').Extension>}
15 */
16export const extensions = (doc, id) => {
17 // Skip IndexeddbPersistence and Y-sweet provider in test environment
18 // where indexedDB is not available
19 const isTestEnvironment =
20 typeof process !== "undefined" && process.env && process.env.VITEST;
21
22 const authEndpoint = (docID) => async () => {
23 const res = await fetch(`/api/ws/auth/${docID}`, {
24 credentials: "include",
25 });
26 if (!res.ok) {
27 console.debug("auth reponse failed", res);
28 if (res.status === 401 || res.status === 403) {
29 window.location.href = "/login";
30 throw new Error("Unauthorized");
31 }
32 throw new Error(`Auth failed: ${res.status}`);
33 }
34 return res.json(); // { url, baseUrl, docId }
35 };
36
37 if (!isTestEnvironment) {
38 new IndexeddbPersistence(id, doc);
39 const provider = createYjsProvider(doc, id, authEndpoint(id), { showDebuggerLink: false });
40 provider.on('connection-status', (status) => {
41 document.dispatchEvent(new CustomEvent('ysweet-connection-status', { detail: status }));
42 });
43 provider.on('local-changes', (hasChanges) => {
44 document.dispatchEvent(new CustomEvent('ysweet-local-changes', { detail: hasChanges }));
45 });
46 // createYjsProvider(
47 // doc,
48 // id,
49 // () => new Promise((resolve) => resolve({url: `ws://127.0.0.1:8080/ws`, baseUrl: "http://127.0.0.1:8080", docId: id})),
50 // {showDebuggerLink: false},
51 // );
52 }
53
54 return [
55 StarterKit.configure({
56 undoRedo: false,
57 }),
58 Collaboration.configure({
59 document: doc,
60 field: "main",
61 }),
62 Waypoint,
63 ];
64};