diff --git a/e2e/flows/two-users-converge.spec.ts b/e2e/flows/two-users-converge.spec.ts index d0d5a35..e63111b 100644 --- a/e2e/flows/two-users-converge.spec.ts +++ b/e2e/flows/two-users-converge.spec.ts @@ -75,11 +75,11 @@ test("two users editing concurrently converge on both screens", async ({ browser // this file green. The colour matters too: the awareness payload is // validated against /^#[0-9a-fA-F]{6}$/, and a value outside that either // warns and renders (today) or is replaced with `transparent`. - const bobCaret = aliceEditor.locator(".collaboration-cursor__caret"); + const bobCaret = aliceEditor.locator(".collaboration-carets__caret"); await expect(bobCaret).toHaveCount(1, { timeout: 8_000 }); // Bob was invited by email with no display name, so the server derives // one from the local part. - await expect(bobCaret.locator(".collaboration-cursor__label")).toHaveText("bob"); + await expect(bobCaret.locator(".collaboration-carets__label")).toHaveText("bob"); const caretColor = await bobCaret.evaluate((el) => getComputedStyle(el).borderLeftColor); expect(caretColor, "the remote caret has no colour — it is invisible").not.toBe("transparent"); diff --git a/e2e/support/docText.ts b/e2e/support/docText.ts index 121e4ae..27cf05c 100644 --- a/e2e/support/docText.ts +++ b/e2e/support/docText.ts @@ -14,7 +14,7 @@ export function docText(el: Element): string { acceptNode(node) { let p: Node | null = node.parentElement; while (p && p !== el) { - if (p instanceof Element && p.classList.contains("collaboration-cursor__label")) { + if (p instanceof Element && p.classList.contains("collaboration-carets__label")) { return NodeFilter.FILTER_REJECT; } p = p.parentNode; diff --git a/web/package.json b/web/package.json index 7763b00..6fb3c6d 100644 --- a/web/package.json +++ b/web/package.json @@ -17,28 +17,25 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@excalidraw/excalidraw": "^0.18.1", + "@floating-ui/dom": "^1.7.4", "@fontsource-variable/inter": "^5.3.0", "@tanstack/react-query": "^5.101.4", - "@tiptap/core": "^2.27.3", - "@tiptap/extension-bullet-list": "^2.27.2", - "@tiptap/extension-code-block": "^2.27.2", - "@tiptap/extension-collaboration": "^2.27.2", - "@tiptap/extension-collaboration-cursor": "^2.26.2", - "@tiptap/extension-hard-break": "^2.27.2", - "@tiptap/extension-horizontal-rule": "^2.27.2", - "@tiptap/extension-image": "^2.27.2", - "@tiptap/extension-link": "^2.27.2", - "@tiptap/extension-list-item": "^2.27.2", - "@tiptap/extension-ordered-list": "^2.27.2", - "@tiptap/extension-table": "^2.27.2", - "@tiptap/extension-table-cell": "^2.27.2", - "@tiptap/extension-table-header": "^2.27.2", - "@tiptap/extension-table-row": "^2.27.2", - "@tiptap/extension-underline": "^2.27.2", - "@tiptap/pm": "^2.27.2", - "@tiptap/react": "^2.27.2", - "@tiptap/starter-kit": "^2.27.2", - "@tiptap/suggestion": "^2.27.2", + "@tiptap/core": "^3.31.3", + "@tiptap/extension-code-block": "^3.31.3", + "@tiptap/extension-collaboration": "^3.31.3", + "@tiptap/extension-collaboration-caret": "^3.31.3", + "@tiptap/extension-hard-break": "^3.31.3", + "@tiptap/extension-horizontal-rule": "^3.31.3", + "@tiptap/extension-image": "^3.31.3", + "@tiptap/extension-link": "^3.31.3", + "@tiptap/extension-list": "^3.31.3", + "@tiptap/extension-table": "^3.31.3", + "@tiptap/extension-underline": "^3.31.3", + "@tiptap/pm": "^3.31.3", + "@tiptap/react": "^3.31.3", + "@tiptap/starter-kit": "^3.31.3", + "@tiptap/suggestion": "^3.31.3", + "@tiptap/y-tiptap": "^3.0.9", "autoprefixer": "^10.5.4", "dompurify": "^3.4.13", "lucide-react": "^1.31.0", @@ -50,7 +47,6 @@ "react-router-dom": "^7.18.2", "tailwindcss": "^3.4.19", "valibot": "^1.4.2", - "y-prosemirror": "^1.3.7", "y-protocols": "^1.0.7", "yjs": "^13.6.32", "zustand": "^5.0.15" diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 96c5c47..6844e12 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@excalidraw/excalidraw': specifier: ^0.18.1 version: 0.18.1(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@floating-ui/dom': + specifier: ^1.7.4 + version: 1.8.0 '@fontsource-variable/inter': specifier: ^5.3.0 version: 5.3.0 @@ -36,65 +39,53 @@ importers: specifier: ^5.101.4 version: 5.101.4(react@19.2.8) '@tiptap/core': - specifier: ^2.27.3 - version: 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/extension-bullet-list': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/pm@3.31.3) '@tiptap/extension-code-block': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) '@tiptap/extension-collaboration': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(y-prosemirror@1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)) - '@tiptap/extension-collaboration-cursor': - specifier: ^2.26.2 - version: 2.26.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(y-prosemirror@1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32) + '@tiptap/extension-collaboration-caret': + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)) '@tiptap/extension-hard-break': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) '@tiptap/extension-horizontal-rule': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) '@tiptap/extension-image': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) '@tiptap/extension-link': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-list-item': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-ordered-list': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-list': + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) '@tiptap/extension-table': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-table-cell': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-table-header': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-table-row': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) '@tiptap/extension-underline': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) + specifier: ^3.31.3 + version: 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) '@tiptap/pm': - specifier: ^2.27.2 - version: 2.27.2 + specifier: ^3.31.3 + version: 3.31.3 '@tiptap/react': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: ^3.31.3 + version: 3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@tiptap/starter-kit': - specifier: ^2.27.2 - version: 2.27.2 + specifier: ^3.31.3 + version: 3.31.3 '@tiptap/suggestion': - specifier: ^2.27.2 - version: 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) + specifier: ^3.31.3 + version: 3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/y-tiptap': + specifier: ^3.0.9 + version: 3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) autoprefixer: specifier: ^10.5.4 version: 10.5.4(postcss@8.5.26) @@ -128,9 +119,6 @@ importers: valibot: specifier: ^1.4.2 version: 1.4.2(typescript@5.9.3) - y-prosemirror: - specifier: ^1.3.7 - version: 1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) y-protocols: specifier: ^1.0.7 version: 1.0.7(yjs@13.6.32) @@ -711,9 +699,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@radix-ui/primitive@1.0.0': resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} @@ -996,9 +981,6 @@ packages: '@radix-ui/rect@1.1.0': resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} - '@remirror/core-constants@3.0.0': - resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -1180,192 +1162,198 @@ packages: '@types/react-dom': optional: true - '@tiptap/core@2.27.3': - resolution: {integrity: sha512-a5LfRbLpfaGI3hbL/LPHUYHI0I+FQHdSHsy8L4YnVIuu3hXcm3QZgkWbpEGf8hCz8krk6zEiu0+iFOjTySU2FA==} - peerDependencies: - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-blockquote@2.27.2': - resolution: {integrity: sha512-oIGZgiAeA4tG3YxbTDfrmENL4/CIwGuP3THtHsNhwRqwsl9SfMk58Ucopi2GXTQSdYXpRJ0ahE6nPqB5D6j/Zw==} + '@tiptap/core@3.31.3': + resolution: {integrity: sha512-Cz50pvciQrxdSxgTkHOVz0uD0Yl/8Xt0QatGD6ILm47jW8EzyHR9RkUGs/D5IqzXKuVPntfw1ttaT926vXfiRg==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-bold@2.27.2': - resolution: {integrity: sha512-bR7J5IwjCGQ0s3CIxyMvOCnMFMzIvsc5OVZKscTN5UkXzFsaY6muUAIqtKxayBUucjtUskm5qZowJITCeCb1/A==} + '@tiptap/extension-blockquote@3.31.3': + resolution: {integrity: sha512-fyY2XMbyDDDfOTQ1Qdrnqa1qwC9DWE4n7AfE0EKQI0G8MfLV8RaDlLDcOZDJ9JbMPY7/Gx7EjyK4NKxSW9n2hQ==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-bubble-menu@2.27.2': - resolution: {integrity: sha512-VkwlCOcr0abTBGzjPXklJ92FCowG7InU8+Od9FyApdLNmn0utRYGRhw0Zno6VgE9EYr1JY4BRnuSa5f9wlR72w==} + '@tiptap/extension-bold@3.31.3': + resolution: {integrity: sha512-dIuYhKk8TitKU/FeDpoTeWZhU42YgDN5npgWNjAmMmRktPdoxnH3/wGSiwXlqZgJWjehN7kPWDePWpJeAImGpQ==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-bullet-list@2.27.2': - resolution: {integrity: sha512-gmFuKi97u5f8uFc/GQs+zmezjiulZmFiDYTh3trVoLRoc2SAHOjGEB7qxdx7dsqmMN7gwiAWAEVurLKIi1lnnw==} + '@tiptap/extension-bubble-menu@3.31.3': + resolution: {integrity: sha512-EV6ZnwKc++2OM/OcD54n8s1B7C9LP7GKAtdEPwu0t3BYJf3sG8Ueoinf7SgGPO9oMPg96GneOkDNm1urMV167g==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-code-block@2.27.2': - resolution: {integrity: sha512-KgvdQHS4jXr79aU3wZOGBIZYYl9vCB7uDEuRFV4so2rYrfmiYMw3T8bTnlNEEGe4RUeAms1i4fdwwvQp9nR1Dw==} + '@tiptap/extension-bullet-list@3.31.3': + resolution: {integrity: sha512-qEyyoPapPef4LO8XKaN83bxtaNzkJ4kFn/IxLnEKd4BJ3Mvi4MH2yJYlyDqwFnMoev4pMA1zBHRAt/C0THRmZw==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/extension-list': 3.31.3 - '@tiptap/extension-code@2.27.2': - resolution: {integrity: sha512-7X9AgwqiIGXoZX7uvdHQsGsjILnN/JaEVtqfXZnPECzKGaWHeK/Ao4sYvIIIffsyZJA8k5DC7ny2/0sAgr2TuA==} + '@tiptap/extension-code-block@3.31.3': + resolution: {integrity: sha512-nvknt4FhyJQjYcvxptmeUlFsIAc8ibua3E5BN4Pim374/9RWepH4cdE9X0/qUTtguHElLx0iKtSIY3rW2qGTFA==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-collaboration-cursor@2.26.2': - resolution: {integrity: sha512-FdRb27mZ5Kr18hN6cbfBj1e9F0DOoHB1Gv3IYeic+g4h1C9BjDVMN0+JRBQc+4lamNA8TsHO0oKWRwaPe4sSlA==} + '@tiptap/extension-code@3.31.3': + resolution: {integrity: sha512-SzxOqchrD2AcN3uT67PjKmRFEMOU3vNNiwNaamZJUbZrI6Hmy+bvdHJrc3jrIddyyCrAtsnAfRI0cmorW1jGfg==} peerDependencies: - '@tiptap/core': ^2.7.0 - y-prosemirror: ^1.2.11 + '@tiptap/core': 3.31.3 - '@tiptap/extension-collaboration@2.27.2': - resolution: {integrity: sha512-Y61ItHxQ1uc/Ir27mBQRI/wY9JkOui194V+awNv+1YHeaKArTjC2cdSvNzj9+h8JIh5MyfvslSf8hBa7t7PzAg==} + '@tiptap/extension-collaboration-caret@3.31.3': + resolution: {integrity: sha512-ub2SsYwmEcmTbqk4aC55M6AnU5/jJcr85lk0jQTqoo1h4ADGYcVXKaJY/CgDCxJgPxr6e/+IiNSYTLjW0nOEgg==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - y-prosemirror: ^1.2.11 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 + '@tiptap/y-tiptap': ^3.0.7 - '@tiptap/extension-document@2.27.2': - resolution: {integrity: sha512-CFhAYsPnyYnosDC4639sCJnBUnYH4Cat9qH5NZWHVvdgtDwu8GZgZn2eSzaKSYXWH1vJ9DSlCK+7UyC3SNXIBA==} + '@tiptap/extension-collaboration@3.31.3': + resolution: {integrity: sha512-JAwOXjeeDYghrPcK57dtvxwn06zcz50mxSSk4PaSdLxM8tkw8+udx+51ewqKKd3WlFof4zyMwUEbO/DGaUdEvw==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 + '@tiptap/y-tiptap': ^3.0.7 + yjs: ^13 - '@tiptap/extension-dropcursor@2.27.2': - resolution: {integrity: sha512-oEu/OrktNoQXq1x29NnH/GOIzQZm8ieTQl3FK27nxfBPA89cNoH4mFEUmBL5/OFIENIjiYG3qWpg6voIqzswNw==} + '@tiptap/extension-document@3.31.3': + resolution: {integrity: sha512-EexgmqnyDNyGlISxo7SMrp5MygpJYmqD+0cY5jB6L1U6L4CpKKRWUt8OO1sWzEHDE1+TTvwt+WIFoIWAziOtEA==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-floating-menu@2.27.2': - resolution: {integrity: sha512-GUN6gPIGXS7ngRJOwdSmtBRBDt9Kt9CM/9pSwKebhLJ+honFoNA+Y6IpVyDvvDMdVNgBchiJLs6qA5H97gAePQ==} + '@tiptap/extension-dropcursor@3.31.3': + resolution: {integrity: sha512-NWomSfu5CSC7VacnMSDzKT8qm66SzMfZwVPEtwY5bPpRTJgTiT1rNK0neDrrzfMN27MfylGyKWWf7Q5Qf8w/fg==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/extensions': 3.31.3 - '@tiptap/extension-gapcursor@2.27.2': - resolution: {integrity: sha512-/c9VF1HBxj+AP54XGVgCmD9bEGYc5w5OofYCFQgM7l7PB1J00A4vOke0oPkHJnqnOOyPlFaxO/7N6l3XwFcnKA==} + '@tiptap/extension-floating-menu@3.31.3': + resolution: {integrity: sha512-rd4VJ9PGSP9Eop8ZTEwaLZcMzMXLuJKe3hUNf58rq+zANpwM+9fI+vB7g9MAc3eXwUNDxNDVACFIL2oeBqpQ3A==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-hard-break@2.27.2': - resolution: {integrity: sha512-kSRVGKlCYK6AGR0h8xRkk0WOFGXHIIndod3GKgWU49APuIGDiXd8sziXsSlniUsWmqgDmDXcNnSzPcV7AQ8YNg==} + '@tiptap/extension-gapcursor@3.31.3': + resolution: {integrity: sha512-EBXKb1FrVStsNYCcRGtd9jmzveCvR+eqgg1rVqoONrqFK6U7bga6LN+1dMKroP1kliDVgveYkP3vRYxqw+rFqg==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/extensions': 3.31.3 - '@tiptap/extension-heading@2.27.2': - resolution: {integrity: sha512-iM3yeRWuuQR/IRQ1djwNooJGfn9Jts9zF43qZIUf+U2NY8IlvdNsk2wTOdBgh6E0CamrStPxYGuln3ZS4fuglw==} + '@tiptap/extension-hard-break@3.31.3': + resolution: {integrity: sha512-QAdCvNO4+yW9ATwsrej11NTkDYFqPLIEQr3ARNrKOK1qaiS7A0fia2SEukb/hrkP3A6mbozhoQt2r2RGUf/DpQ==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-history@2.27.2': - resolution: {integrity: sha512-+hSyqERoFNTWPiZx4/FCyZ/0eFqB9fuMdTB4AC/q9iwu3RNWAQtlsJg5230bf/qmyO6bZxRUc0k8p4hrV6ybAw==} + '@tiptap/extension-heading@3.31.3': + resolution: {integrity: sha512-rk5VHMAeQcg06SLauN6EGdD2jc0O2qY8QkZYPd0LxNvLblw2BxBx+lxUQSYwLAT9Ie5914gKIK2YbRyO2Ts3ig==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-horizontal-rule@2.27.2': - resolution: {integrity: sha512-WGWUSgX+jCsbtf9Y9OCUUgRZYuwjVoieW5n6mAUohJ9/6gc6sGIOrUpBShf+HHo6WD+gtQjRd+PssmX3NPWMpg==} + '@tiptap/extension-horizontal-rule@3.31.3': + resolution: {integrity: sha512-YnHGy2KShRwvCseAmmxl9VP7R0qaj8QMp3DA6DJWZqp7r5gLGvDkAqhedxqqefqsE4Y43hjkBdjtB9Ce78LkIw==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-image@2.27.2': - resolution: {integrity: sha512-5zL/BY41FIt72azVrCrv3n+2YJ/JyO8wxCcA4Dk1eXIobcgVyIdo4rG39gCqIOiqziAsqnqoj12QHTBtHsJ6mQ==} + '@tiptap/extension-image@3.31.3': + resolution: {integrity: sha512-wWNG9BOtx2Cg4vwxPVGDIJ5DGX+ETkldeoaFJLB1NXUL4OPUiVTf8cHZ+hdYgJWP704BEB7jQgjlpvdi6VigTg==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-italic@2.27.2': - resolution: {integrity: sha512-1OFsw2SZqfaqx5Fa5v90iNlPRcqyt+lVSjBwTDzuPxTPFY4Q0mL89mKgkq2gVHYNCiaRkXvFLDxaSvBWbmthgg==} + '@tiptap/extension-italic@3.31.3': + resolution: {integrity: sha512-ibGvdvAPyfxBMUVNRI43eb9h2/Jka1MRG5GtnGqbcCX/2+Y/y0EOfFrPQPkuYphiWQYyu9+FzPKMB/pjuaLuKQ==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-link@2.27.2': - resolution: {integrity: sha512-bnP61qkr0Kj9Cgnop1hxn2zbOCBzNtmawxr92bVTOE31fJv6FhtCnQiD6tuPQVGMYhcmAj7eihtvuEMFfqEPcQ==} + '@tiptap/extension-link@3.31.3': + resolution: {integrity: sha512-986wOQzTL9Zr5lf84LCLpm+YOms8A0K39/8DVoqRfebqcOe0/eq4bnztmAlfabOd+kJY92g3AgZERFUx/w+dcw==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-list-item@2.27.2': - resolution: {integrity: sha512-eJNee7IEGXMnmygM5SdMGDC8m/lMWmwNGf9fPCK6xk0NxuQRgmZHL6uApKcdH6gyNcRPHCqvTTkhEP7pbny/fg==} + '@tiptap/extension-list-item@3.31.3': + resolution: {integrity: sha512-4QlKOriJJMvg95QJTEsy9BUYPBQ6UvJyb8WURRwdUtQUkkqb8h32lg/eyQUv2FzW9IT1AdUyNZfVaxH64kRfQA==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/extension-list': 3.31.3 - '@tiptap/extension-ordered-list@2.27.2': - resolution: {integrity: sha512-M7A4tLGJcLPYdLC4CI2Gwl8LOrENQW59u3cMVa+KkwG1hzSJyPsbDpa1DI6oXPC2WtYiTf22zrbq3gVvH+KA2w==} + '@tiptap/extension-list-keymap@3.31.3': + resolution: {integrity: sha512-If8UOEdDZbPJU6iYTvLtH6DOp2KBy6BKxg9UELL1AevVetGHEF/7lW8hP50Gn1tHMVpPRqmhSzVrJRpEJJgb/Q==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/extension-list': 3.31.3 - '@tiptap/extension-paragraph@2.27.2': - resolution: {integrity: sha512-elYVn2wHJJ+zB9LESENWOAfI4TNT0jqEN34sMA/hCtA4im1ZG2DdLHwkHIshj/c4H0dzQhmsS/YmNC5Vbqab/A==} + '@tiptap/extension-list@3.31.3': + resolution: {integrity: sha512-LoveGnC0FVdCV4jUNBaG1ZA+KWE07+adzV3kGy6uUYFcJEjbVUHTnPDrBOob3IwOSO3sCwIkvQb6EVYeXn/4yg==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-strike@2.27.2': - resolution: {integrity: sha512-HHIjhafLhS2lHgfAsCwC1okqMsQzR4/mkGDm4M583Yftyjri1TNA7lzhzXWRFWiiMfJxKtdjHjUAQaHuteRTZw==} + '@tiptap/extension-ordered-list@3.31.3': + resolution: {integrity: sha512-mp3g11NgA/PYu8rj7J7Ez3l4qBy6WfTSmHIG4PZvEGG5w2oUAIkgb9DU7nPPzjmeme27oazFYZw+AtZA0+u4tw==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/extension-list': 3.31.3 - '@tiptap/extension-table-cell@2.27.2': - resolution: {integrity: sha512-9Lk46MjZMFzVZfOj9Kd7VgC6Odt6vmEhlCYVumErShUY7EkFqCw3b2IYoUtQkntfOEx/Afnhff/okNQwPsJeUA==} + '@tiptap/extension-paragraph@3.31.3': + resolution: {integrity: sha512-+iPku7wJfy5hbNDNLX8dveFtYVsZMmh7vztjuq8hT3mipSC4IByDehDbU8fzUCjfXiEzmI7mQn7c8LGmHULuzA==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-table-header@2.27.2': - resolution: {integrity: sha512-ZEb6lbG0NbbodWLV0b4BS/QrDIPlUbCcuOsUxzqVvlMUY1Vg6Fj6fKwLaBcsIUDHi8sxZDBEgYEDw3BR/zcO6A==} + '@tiptap/extension-strike@3.31.3': + resolution: {integrity: sha512-G29bhKttYwcKHT+BI6emWVFol3RO/gUXxQVcmr/iT8LXXy7j8J6HFUnsKM+Kg5YlP1rxMRgsa65dbrQVahZi0A==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-table-row@2.27.2': - resolution: {integrity: sha512-Nw9+tA56Y5HtLVP01NGCZSUuTQhJPtfK9OfmDgGgcxynn2cRVdEtj+9FNZqRhQ1iRVaAI+Rd4xRvX9qYePMOxw==} + '@tiptap/extension-table@3.31.3': + resolution: {integrity: sha512-7cnVPHhdiGGeauYqca6JVyPLTqZbqFEEk9nn2e2E8+fBo6zVtV07AktJBqth/XEzjZxcUmGxjoeuWYAisWjUHg==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-table@2.27.2': - resolution: {integrity: sha512-pDbhOpT5phZkcsyPjGBQlXv0+0hmdrvqHJ+dJjkGcCtlfy2pHiEIhmIItOFagc7wXy8G9iUFZ9Jie4zvDf+brg==} + '@tiptap/extension-text@3.31.3': + resolution: {integrity: sha512-gdsWtF+taeaCu6V+5Ct10fGo0ACUy1GnYtbb+mcathBt8OqbT+Ws60p/yEmKesBDz2Hn+B5IcWy6+2BBZl5ZTg==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-text-style@2.27.2': - resolution: {integrity: sha512-Omk+uxjJLyEY69KStpCw5fA9asvV+MGcAX2HOxyISDFoLaL49TMrNjhGAuz09P1L1b0KGXo4ml7Q3v/Lfy4WPA==} + '@tiptap/extension-underline@3.31.3': + resolution: {integrity: sha512-HghdJaOwRqYzsAxqSyNyb+IWyOMcdCl8IoiBETA9BZCJAqdXzFLcuWp7CqCqJPam9dgkWosSoHqTCAO4nTBfpw==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 - '@tiptap/extension-text@2.27.2': - resolution: {integrity: sha512-Xk7nYcigljAY0GO9hAQpZ65ZCxqOqaAlTPDFcKerXmlkQZP/8ndx95OgUb1Xf63kmPOh3xypurGS2is3v0MXSA==} + '@tiptap/extensions@3.31.3': + resolution: {integrity: sha512-8sJNPGGUe8f3aDojcOW5cfVL7I5NrBbE0UWxG08qoi9Tea6qWbvQJsCR9tsrOapr/DaLr3kpbGZ9s1gEEfcNcA==} peerDependencies: - '@tiptap/core': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-underline@2.27.2': - resolution: {integrity: sha512-gPOsbAcw1S07ezpAISwoO8f0RxpjcSH7VsHEFDVuXm4ODE32nhvSinvHQjv2icRLOXev+bnA7oIBu7Oy859gWQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/pm@2.27.2': - resolution: {integrity: sha512-kaEg7BfiJPDQMKbjVIzEPO3wlcA+pZb2tlcK9gPrdDnEFaec2QTF1sXz2ak2IIb2curvnIrQ4yrfHgLlVA72wA==} + '@tiptap/pm@3.31.3': + resolution: {integrity: sha512-sZime0SWsz/k62W2WvHx5Ig7G2h7kVhrrmnqy+wEgIHfDwEfOlelRjaWCiBCFlF7dxGUntJusCh9FxlLhni0Ag==} - '@tiptap/react@2.27.2': - resolution: {integrity: sha512-0EAs8Cpkfbvben1PZ34JN2Nd79Dhioynm2jML27DBbf1VWPk+FFWFGTMLUT0bu+Np5iVxio8fqV9t0mc4D6thA==} + '@tiptap/react@3.31.3': + resolution: {integrity: sha512-QiwQqvaLFLm5EMFu5tg7nAgXJxCUiUTLD8EsK+TqVV5P4bqOoMOCM39khbhXTJyahCuYpiFWx5YOSDtC/JiPtg==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tiptap/starter-kit@2.27.2': - resolution: {integrity: sha512-bb0gJvPoDuyRUQ/iuN52j1//EtWWttw+RXAv1uJxfR0uKf8X7uAqzaOOgwjknoCIDC97+1YHwpGdnRjpDkOBxw==} + '@tiptap/starter-kit@3.31.3': + resolution: {integrity: sha512-WKof9RewdmGHvWJ1wn0/HVNG2mV+HOgVRyJkKekuM9fgr6BZAAH/xZsWE1eon+94JnQ+KtK2ThydXQM/qc6b2A==} - '@tiptap/suggestion@2.27.2': - resolution: {integrity: sha512-dQyvCIg0hcAVeh4fCIVCxogvbp+bF+GpbUb8sNlgnGrmHXnapGxzkvrlHnvneXZxLk/j7CxmBPKJNnm4Pbx4zw==} + '@tiptap/suggestion@3.31.3': + resolution: {integrity: sha512-z1OQ/Yx6seMZehi1AcmNkyJ8qkHQzybArmCyRdmreS4YL9C4bPMBe5lbMfFsArYs+KD5JyHwps5j7J/YE5BIuw==} peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.31.3 + '@tiptap/pm': 3.31.3 + + '@tiptap/y-tiptap@3.0.9': + resolution: {integrity: sha512-7/El8NQ8R5V5MkdrOUdfj9IgZacpt0H071xNimX7B0AnYiWiKefQnMKd41neQYzo2MOXbWdN3iZ+7Z7BruzOSA==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + prosemirror-model: 1.25.7 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.8 + y-protocols: ^1.0.1 + yjs: ^13.5.38 '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1496,15 +1484,6 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - '@types/node@24.13.3': resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} @@ -1667,9 +1646,6 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.6: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} @@ -1852,9 +1828,6 @@ packages: resolution: {integrity: sha512-kucVIjOmMc1f0tv53BJ/5WIX+MGLcKuoBhnGqQrgKJNqLByb/sVMWfW/Aw6hw0jgcqjJ2pi9E5y32zOIpaUlsA==} engines: {node: '>=0.8'} - crelt@1.0.7: - resolution: {integrity: sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==} - cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -2124,10 +2097,6 @@ packages: emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - entities@8.0.0: resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} engines: {node: '>=20.19.0'} @@ -2279,6 +2248,10 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-equals@5.4.2: + resolution: {integrity: sha512-Ywe6jodPTWOTL9/k0bV7gdfP8twKL5Y8I8CZ933fAY5gBekICZSUQTbyH6ut2NZCNyB05mSUwAuEqdEIaOOlDQ==} + engines: {node: '>=6.0.0'} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2715,9 +2688,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - linkify-it@5.0.2: - resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==} - linkifyjs@4.3.3: resolution: {integrity: sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==} @@ -2760,10 +2730,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - markdown-it@14.3.0: - resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==} - hasBin: true - marked@16.4.2: resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} engines: {node: '>= 20'} @@ -2781,9 +2747,6 @@ packages: mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - mdurl@2.1.0: - resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -3041,9 +3004,6 @@ packages: prosemirror-changeset@2.4.1: resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==} - prosemirror-collab@1.3.1: - resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} - prosemirror-commands@1.7.2: resolution: {integrity: sha512-q6Q6szxqdu9Xd6EcdKsqXghu5nQdZTpB4Q9yd04WRc7/jt763e/rT60Owh0L1GYY+T46o5rD+9lEN36dZS43tw==} @@ -3062,18 +3022,9 @@ packages: prosemirror-keymap@1.2.3: resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - prosemirror-markdown@1.13.5: - resolution: {integrity: sha512-ac8trNQ01ybKDRTcfUc56LZufG3oYyU4N25qSXgp8dS0U4JtzzCj7oQlKu5v09VSmS5IseYoQ2yDkTbo7f7D8Q==} - - prosemirror-menu@1.3.2: - resolution: {integrity: sha512-6VgUJTYod0nMBlCaYJGhXGLu7Gt4AvcwcOq0YfJCY/6Uh+3S7UsWhpy6rJFCBFOmonq1hD8KyWOtZhkppd4YPg==} - prosemirror-model@1.25.7: resolution: {integrity: sha512-A79aN8QEFUwI6cax8Yq4Rpcx1TJZ3Kagn+ii7qLo4/V8H3mMiHrhFyhTyHHvpSnOgMPpWiDGSwM3etwrxE50ug==} - prosemirror-schema-basic@1.2.4: - resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} - prosemirror-schema-list@1.5.1: resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} @@ -3083,23 +3034,12 @@ packages: prosemirror-tables@1.8.5: resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} - prosemirror-trailing-node@3.0.0: - resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} - peerDependencies: - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - prosemirror-transform@1.12.0: resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} prosemirror-view@1.41.8: resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3414,9 +3354,6 @@ packages: resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} engines: {node: '>=14.0.0'} - tippy.js@6.3.7: - resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} - tldts-core@7.4.10: resolution: {integrity: sha512-KnQjp53ZekKgm/r3l+u8kJGGzYgrWdP8+Mql7a4vijh2WE0IrZWspQj/TpTxDho/YxO+AnOZnIjQcCD+q6iJsw==} @@ -3487,9 +3424,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -3714,16 +3648,6 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - y-prosemirror@1.3.7: - resolution: {integrity: sha512-NpM99WSdD4Fx4if5xOMDpPtU3oAmTSjlzh5U4353ABbRHl1HtAFUx6HlebLZfyFxXN9jzKMDkVbcRjqOZVkYQg==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - y-protocols: ^1.0.1 - yjs: ^13.5.38 - y-protocols@1.0.7: resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} @@ -4270,8 +4194,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@popperjs/core@2.11.8': {} - '@radix-ui/primitive@1.0.0': dependencies: '@babel/runtime': 7.29.7 @@ -4552,8 +4474,6 @@ snapshots: '@radix-ui/rect@1.1.0': {} - '@remirror/core-constants@3.0.0': {} - '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/rollup-android-arm-eabi@4.62.4': @@ -4673,206 +4593,215 @@ snapshots: '@types/react': 19.2.18 '@types/react-dom': 19.2.4(@types/react@19.2.18) - '@tiptap/core@2.27.3(@tiptap/pm@2.27.2)': + '@tiptap/core@3.31.3(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/pm': 2.27.2 + '@tiptap/pm': 3.31.3 - '@tiptap/extension-blockquote@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-blockquote@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-bold@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-bold@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-bubble-menu@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-bubble-menu@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 - tippy.js: 6.3.7 - - '@tiptap/extension-bullet-list@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': - dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + optional: true - '@tiptap/extension-code-block@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-bullet-list@3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/extension-list': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-code@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-code-block@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-collaboration-cursor@2.26.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(y-prosemirror@1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))': + '@tiptap/extension-code@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - y-prosemirror: 1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-collaboration@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(y-prosemirror@1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))': + '@tiptap/extension-collaboration-caret@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 - y-prosemirror: 1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + '@tiptap/y-tiptap': 3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) - '@tiptap/extension-document@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-collaboration@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32))(yjs@13.6.32)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + '@tiptap/y-tiptap': 3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32) + yjs: 13.6.32 - '@tiptap/extension-dropcursor@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-document@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-floating-menu@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-dropcursor@3.31.3(@tiptap/extensions@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 - tippy.js: 6.3.7 + '@tiptap/extensions': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-gapcursor@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-floating-menu@3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + optional: true - '@tiptap/extension-hard-break@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-gapcursor@3.31.3(@tiptap/extensions@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/extensions': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-heading@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-hard-break@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-history@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-heading@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-horizontal-rule@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-horizontal-rule@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-image@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-image@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-italic@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-italic@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-link@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-link@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 linkifyjs: 4.3.3 - '@tiptap/extension-list-item@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-list-item@3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/extension-list': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-ordered-list@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-list-keymap@3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/extension-list': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-paragraph@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-strike@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-ordered-list@3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/extension-list': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) - '@tiptap/extension-table-cell@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-paragraph@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-table-header@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-strike@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-table-row@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-table@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-table@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': + '@tiptap/extension-text@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-text-style@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extension-underline@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) - '@tiptap/extension-text@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': + '@tiptap/extensions@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/extension-underline@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))': - dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - - '@tiptap/pm@2.27.2': + '@tiptap/pm@3.31.3': dependencies: prosemirror-changeset: 2.4.1 - prosemirror-collab: 1.3.1 prosemirror-commands: 1.7.2 prosemirror-dropcursor: 1.8.3 prosemirror-gapcursor: 1.4.1 prosemirror-history: 1.5.0 prosemirror-inputrules: 1.5.1 prosemirror-keymap: 1.2.3 - prosemirror-markdown: 1.13.5 - prosemirror-menu: 1.3.2 prosemirror-model: 1.25.7 - prosemirror-schema-basic: 1.2.4 prosemirror-schema-list: 1.5.1 prosemirror-state: 1.4.4 prosemirror-tables: 1.8.5 - prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) prosemirror-transform: 1.12.0 prosemirror-view: 1.41.8 - '@tiptap/react@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@tiptap/react@3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/extension-bubble-menu': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-floating-menu': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + '@types/react': 19.2.18 + '@types/react-dom': 19.2.4(@types/react@19.2.18) '@types/use-sync-external-store': 0.0.6 - fast-deep-equal: 3.1.3 + fast-equals: 5.4.2 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) use-sync-external-store: 1.6.0(react@19.2.8) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-floating-menu': 3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + transitivePeerDependencies: + - '@floating-ui/dom' + + '@tiptap/starter-kit@3.31.3': + dependencies: + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/extension-blockquote': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-bold': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-bullet-list': 3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-code': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-code-block': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-document': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-dropcursor': 3.31.3(@tiptap/extensions@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-gapcursor': 3.31.3(@tiptap/extensions@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-hard-break': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-heading': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-horizontal-rule': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-italic': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-link': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-list': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/extension-list-item': 3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-list-keymap': 3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-ordered-list': 3.31.3(@tiptap/extension-list@3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)) + '@tiptap/extension-paragraph': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-strike': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-text': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extension-underline': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3)) + '@tiptap/extensions': 3.31.3(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 + + '@tiptap/suggestion@3.31.3(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) + '@tiptap/pm': 3.31.3 - '@tiptap/starter-kit@2.27.2': - dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/extension-blockquote': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-bold': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-bullet-list': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-code': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-code-block': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-document': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-dropcursor': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-gapcursor': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-hard-break': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-heading': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-history': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-horizontal-rule': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2) - '@tiptap/extension-italic': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-list-item': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-ordered-list': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-paragraph': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-strike': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-text': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/extension-text-style': 2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2)) - '@tiptap/pm': 2.27.2 - - '@tiptap/suggestion@2.27.2(@tiptap/core@2.27.3(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)': - dependencies: - '@tiptap/core': 2.27.3(@tiptap/pm@2.27.2) - '@tiptap/pm': 2.27.2 + '@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32)': + dependencies: + lib0: 0.2.117 + prosemirror-model: 1.25.7 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.8 + y-protocols: 1.0.7(yjs@13.6.32) + yjs: 13.6.32 '@types/aria-query@5.0.4': {} @@ -5031,15 +4960,6 @@ snapshots: '@types/json5@0.0.29': {} - '@types/linkify-it@5.0.0': {} - - '@types/markdown-it@14.1.2': - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - - '@types/mdurl@2.0.0': {} - '@types/node@24.13.3': dependencies: undici-types: 7.18.2 @@ -5250,8 +5170,6 @@ snapshots: arg@5.0.2: {} - argparse@2.0.1: {} - aria-hidden@1.2.6: dependencies: tslib: 2.8.1 @@ -5462,8 +5380,6 @@ snapshots: crc-32@0.3.0: {} - crelt@1.0.7: {} - cross-env@7.0.3: dependencies: cross-spawn: 7.0.6 @@ -5758,8 +5674,6 @@ snapshots: emoji-regex@10.6.0: {} - entities@4.5.0: {} - entities@8.0.0: {} es-abstract-get@1.0.0: @@ -6025,6 +5939,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-equals@5.4.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -6443,10 +6359,6 @@ snapshots: lines-and-columns@1.2.4: {} - linkify-it@5.0.2: - dependencies: - uc.micro: 2.1.0 - linkifyjs@4.3.3: {} locate-path@6.0.0: @@ -6485,15 +6397,6 @@ snapshots: dependencies: semver: 7.8.5 - markdown-it@14.3.0: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.2 - mdurl: 2.1.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - marked@16.4.2: {} marked@18.0.11: {} @@ -6502,8 +6405,6 @@ snapshots: mdn-data@2.27.1: {} - mdurl@2.1.0: {} - merge2@1.4.1: {} mermaid@11.16.1: @@ -6762,10 +6663,6 @@ snapshots: dependencies: prosemirror-transform: 1.12.0 - prosemirror-collab@1.3.1: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-commands@1.7.2: dependencies: prosemirror-model: 1.25.7 @@ -6802,27 +6699,10 @@ snapshots: prosemirror-state: 1.4.4 w3c-keyname: 2.2.8 - prosemirror-markdown@1.13.5: - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.3.0 - prosemirror-model: 1.25.7 - - prosemirror-menu@1.3.2: - dependencies: - crelt: 1.0.7 - prosemirror-commands: 1.7.2 - prosemirror-history: 1.5.0 - prosemirror-state: 1.4.4 - prosemirror-model@1.25.7: dependencies: orderedmap: 2.1.1 - prosemirror-schema-basic@1.2.4: - dependencies: - prosemirror-model: 1.25.7 - prosemirror-schema-list@1.5.1: dependencies: prosemirror-model: 1.25.7 @@ -6843,14 +6723,6 @@ snapshots: prosemirror-transform: 1.12.0 prosemirror-view: 1.41.8 - prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8): - dependencies: - '@remirror/core-constants': 3.0.0 - escape-string-regexp: 4.0.0 - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - prosemirror-transform@1.12.0: dependencies: prosemirror-model: 1.25.7 @@ -6861,8 +6733,6 @@ snapshots: prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 - punycode.js@2.3.1: {} - punycode@2.3.1: {} pwacompat@2.0.17: {} @@ -7255,10 +7125,6 @@ snapshots: tinyrainbow@3.1.1: {} - tippy.js@6.3.7: - dependencies: - '@popperjs/core': 2.11.8 - tldts-core@7.4.10: {} tldts@7.4.10: @@ -7343,8 +7209,6 @@ snapshots: typescript@5.9.3: {} - uc.micro@2.1.0: {} - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -7534,15 +7398,6 @@ snapshots: xmlchars@2.2.0: {} - y-prosemirror@1.3.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.32))(yjs@13.6.32): - dependencies: - lib0: 0.2.117 - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - y-protocols: 1.0.7(yjs@13.6.32) - yjs: 13.6.32 - y-protocols@1.0.7(yjs@13.6.32): dependencies: lib0: 0.2.117 diff --git a/web/src/features/comments/anchor.test.ts b/web/src/features/comments/anchor.test.ts index 6e12754..76fff2b 100644 --- a/web/src/features/comments/anchor.test.ts +++ b/web/src/features/comments/anchor.test.ts @@ -10,8 +10,8 @@ * about comment anchoring is silent when that happens — encode returns * null and the caller persists an empty string — so there is no second * chance to notice. - * 2. The y-prosemirror primitives with a hand-built mapping, which pin the - * relative-position semantics we depend on. + * 2. The binding's position primitives with a hand-built mapping, which + * pin the relative-position semantics we depend on. * 3. The null branches, via a fake editor. * * An earlier version of this file had only (2) and (3). Both stay green when @@ -25,7 +25,7 @@ import * as Y from "yjs"; import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, -} from "y-prosemirror"; +} from "@tiptap/y-tiptap"; import { fragmentShape, mountBoundEditor, type BoundEditor } from "../../test/boundEditor"; import { @@ -136,7 +136,7 @@ describe("anchors against a live ySync binding", () => { // (2) The primitives, with a hand-built mapping // --------------------------------------------------------------------------- -describe("y-prosemirror relative position primitives", () => { +describe("Yjs relative position primitives", () => { it("round-trips position 0 on an empty XmlFragment", () => { const ydoc = new Y.Doc(); const fragment = ydoc.getXmlFragment("default"); diff --git a/web/src/features/comments/anchor.ts b/web/src/features/comments/anchor.ts index a344754..087c40c 100644 --- a/web/src/features/comments/anchor.ts +++ b/web/src/features/comments/anchor.ts @@ -6,8 +6,12 @@ * in the `position_y` column and the client can resolve it back to a * pixel offset even after concurrent edits. * - * The y-prosemirror mapping is obtained from the ySyncPlugin state that - * Tiptap's Collaboration extension installs. If the plugin isn't mounted + * The mapping is obtained from the ySyncPlugin state that Tiptap's + * Collaboration extension installs. It MUST be imported from the same + * package that extension installs its plugin from (@tiptap/y-tiptap), not + * from y-prosemirror: both call `new PluginKey("y-sync")`, ProseMirror + * uniquifies the second one, and `getState` is a bare property read — so the + * wrong import silently returns undefined and every anchor becomes null. If the plugin isn't mounted * (e.g. viewer mode before the editor is ready), both functions return null. */ @@ -18,7 +22,7 @@ import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, ySyncPluginKey, -} from "y-prosemirror"; +} from "@tiptap/y-tiptap"; // eslint-disable-next-line @typescript-eslint/no-explicit-any type ProsemirrorMapping = Map, PmNode | PmNode[]>; diff --git a/web/src/features/editor/CommentsHighlightExtension.test.ts b/web/src/features/editor/CommentsHighlightExtension.test.ts new file mode 100644 index 0000000..bbd7ec6 --- /dev/null +++ b/web/src/features/editor/CommentsHighlightExtension.test.ts @@ -0,0 +1,42 @@ +/** + * The highlight extension has to tolerate an editor on its way out. + * + * Switching from one document to another destroys the current editor before + * the replacement exists, and React commits the new effect dependencies in + * between — so effects that push comment data into the editor run at least + * once against the outgoing instance. + * + * Tiptap 3 empties `extensionStorage` on destroy, which turns what used to be + * a pointless write into a TypeError. Under React Router that is not a logged + * warning, it is an error boundary: the document page is replaced by + * "Unexpected Application Error!" and the user loses the editor entirely. + */ + +import { afterEach, describe, expect, it } from "vitest"; + +import { mountBoundEditor, type BoundEditor } from "../../test/boundEditor"; + +describe("comment highlights on a destroyed editor", () => { + let bound: BoundEditor | null = null; + + afterEach(() => { + bound = null; + }); + + it("has its storage while the editor is alive", () => { + bound = mountBoundEditor(); + expect(bound.editor.isDestroyed).toBe(false); + expect(bound.editor.extensionStorage.commentsHighlight).toBeDefined(); + }); + + it("loses its storage once the editor is destroyed", () => { + // Pins the upstream behaviour this guard exists for. If a future version + // keeps storage alive past destroy, this test says so plainly rather than + // leaving the guard looking like superstition. + const b = mountBoundEditor(); + b.editor.destroy(); + expect(b.editor.isDestroyed).toBe(true); + expect(b.editor.extensionStorage.commentsHighlight).toBeUndefined(); + }); + +}); diff --git a/web/src/features/editor/CommentsHighlightExtension.ts b/web/src/features/editor/CommentsHighlightExtension.ts index 2ee4195..0064007 100644 --- a/web/src/features/editor/CommentsHighlightExtension.ts +++ b/web/src/features/editor/CommentsHighlightExtension.ts @@ -35,17 +35,26 @@ export type CommentsHighlightOptions = { const PLUGIN_KEY = new PluginKey("commentsHighlight"); +declare module "@tiptap/core" { + // v3 retyped Editor.storage from Record to an augmentable + // interface. React reaches into this slot directly (see KnotEditor), so it + // has to be declared rather than cast at each use. + interface Storage { + commentsHighlight: CommentsHighlightStorage; + } +} + // Storage shape held on the extension. React updates this object via // `editor.extensionStorage.commentsHighlight.X = ...` and then dispatches // a no-op transaction with `setMeta` to trigger a re-decoration. -type Storage = { +type CommentsHighlightStorage = { comments: HighlightedComment[]; activeCommentId: string | null; doc: Y.Doc | null; onSelect: ((id: string) => void) | null; }; -export const CommentsHighlightExtension = Extension.create({ +export const CommentsHighlightExtension = Extension.create({ name: "commentsHighlight", addOptions() { @@ -108,7 +117,7 @@ export const CommentsHighlightExtension = Extension.create to an augmentable + // interface, so every extension has to declare its own slot. + interface Storage { + knotDateTime: { popup: DateTimePopup | null }; + } + interface Commands { knotDateTime: { /** Open the date+time picker at the current cursor; on Apply, @@ -229,7 +235,7 @@ export const DateTimeExtension = Extension.create({ openDateTimePicker: () => ({ editor }) => { - const popup = (editor.storage.knotDateTime as { popup: DateTimePopup | null }).popup; + const { popup } = editor.storage.knotDateTime; if (!popup) return false; const { from, to } = editor.state.selection; const coords = editor.view.coordsAtPos(from); @@ -255,7 +261,7 @@ export const DateTimeExtension = Extension.create({ addProseMirrorPlugins() { const editor = this.editor; const popup = new DateTimePopup(); - (editor.storage.knotDateTime as { popup: DateTimePopup | null }).popup = popup; + editor.storage.knotDateTime.popup = popup; editor.on("destroy", () => popup.destroy()); // Plugin for click-to-edit on existing chips. diff --git a/web/src/features/editor/KnotEditor.tsx b/web/src/features/editor/KnotEditor.tsx index 77d912e..10d7c1a 100644 --- a/web/src/features/editor/KnotEditor.tsx +++ b/web/src/features/editor/KnotEditor.tsx @@ -329,12 +329,18 @@ function EditorBody({ pair, role, docId, editMode }: { pair: Pair; role: "owner" // Push the latest comments + activeCommentId into the highlight extension's // storage, then dispatch a no-op transaction so the plugin re-decorates. useEffect(() => { - if (!editor) return; - const storage = editor.extensionStorage.commentsHighlight as { - comments: HighlightedComment[]; - activeCommentId: string | null; - doc: Y.Doc | null; - }; + // Navigating from one document to another runs this effect twice against + // the OUTGOING editor before the replacement exists — React commits the + // new deps first. Tiptap 3 empties extensionStorage on destroy, so the + // lookup below returns undefined and assigning to it throws, taking the + // whole route down with an error boundary. In v2 the same write landed on + // a dead object and did nothing, which is why this was never guarded. + // + // e2e/flows/search.spec.ts is the regression test: navigating via the + // command palette reproduces it. Clicking a sidebar link does not — the + // timing differs — so do not "simplify" that spec into a plain link click. + if (!editor || editor.isDestroyed) return; + const storage = editor.extensionStorage.commentsHighlight; storage.comments = highlightComments; storage.activeCommentId = activeCommentId; storage.doc = pair.doc; diff --git a/web/src/features/editor/SchemaNameOverrides.ts b/web/src/features/editor/SchemaNameOverrides.ts index d23c0d4..e103ce8 100644 --- a/web/src/features/editor/SchemaNameOverrides.ts +++ b/web/src/features/editor/SchemaNameOverrides.ts @@ -11,11 +11,10 @@ * schema, then disable the original in `StarterKit.configure({ … : false })`. */ -import BulletList from "@tiptap/extension-bullet-list"; -import OrderedList from "@tiptap/extension-ordered-list"; -import ListItem from "@tiptap/extension-list-item"; import HardBreak from "@tiptap/extension-hard-break"; import HorizontalRule from "@tiptap/extension-horizontal-rule"; +// The three list nodes now ship from one package, as named exports. +import { BulletList, ListItem, OrderedList } from "@tiptap/extension-list"; /** * Renaming a node does not rewrite the OPTIONS its own commands read. diff --git a/web/src/features/editor/TableExtensions.ts b/web/src/features/editor/TableExtensions.ts index cd9e0b0..f725016 100644 --- a/web/src/features/editor/TableExtensions.ts +++ b/web/src/features/editor/TableExtensions.ts @@ -7,10 +7,10 @@ * GFM column alignment and round-trips through to_markdown. */ -import Table from "@tiptap/extension-table"; -import TableRow from "@tiptap/extension-table-row"; -import TableCell from "@tiptap/extension-table-cell"; -import TableHeader from "@tiptap/extension-table-header"; +// The four table nodes now ship from one package as named exports; the +// aggregate has no default export, so `import Table from …` fails to compile. +// TableKit is deliberately not used: it registers camelCase node names. +import { Table, TableCell, TableHeader, TableRow } from "@tiptap/extension-table"; const alignAttr = { align: { diff --git a/web/src/features/editor/extensions.ts b/web/src/features/editor/extensions.ts index 7fe5ac5..f85f20c 100644 --- a/web/src/features/editor/extensions.ts +++ b/web/src/features/editor/extensions.ts @@ -1,5 +1,5 @@ import Collaboration from "@tiptap/extension-collaboration"; -import CollaborationCursor from "@tiptap/extension-collaboration-cursor"; +import CollaborationCaret from "@tiptap/extension-collaboration-caret"; import Image from "@tiptap/extension-image"; import Link from "@tiptap/extension-link"; import Underline from "@tiptap/extension-underline"; @@ -54,6 +54,27 @@ const KnotLink = Link.extend({ }, }); +/** + * v3's Image adds `width` and `height`. Nothing in knot sets them — the + * upload path calls setImage({ src }) and the paste sanitiser's attribute + * allowlist drops both — but leaving them declared would put two attributes + * in the document schema that `tools/schema.json` does not know and + * `to_markdown` cannot emit. Dropping them keeps the stored schema identical + * to what every existing document was written against, which is the property + * worth protecting in a CRDT. + * + * Adopting image dimensions instead is a feature: declare them in + * tools/schema.json and teach to_markdown to write them. + */ +const KnotImage = Image.extend({ + addAttributes() { + const attrs: Record = { ...(this.parent?.() ?? {}) }; + delete attrs.width; + delete attrs.height; + return attrs; + }, +}); + /** Canonical Tiptap extension set that matches the server schema generated * from `tools/schema.json`. History is disabled because Yjs UndoManager * owns undo. */ @@ -67,7 +88,9 @@ export function createExtensions(opts: { }) { return [ StarterKit.configure({ - history: false, + // v2 called this `history`. Still disabled for the same reason: the Yjs + // UndoManager owns undo, and a second history plugin fights it. + undoRedo: false, codeBlock: false, // Disable the camelCase node defaults; we re-add snake_case versions // below so the Y.XmlFragment matches our canonical schema. @@ -76,6 +99,19 @@ export function createExtensions(opts: { listItem: false, hardBreak: false, horizontalRule: false, + // Bundled by StarterKit from v3 on. Link and Underline are registered + // explicitly below, and registering either twice makes the second + // configure() lose the argument fight for the click handler. + link: false, + underline: false, + // Appends a paragraph to any document not ending in one. Harmless in a + // local editor; here it is a write to a shared CRDT that every peer + // receives and that reaches the markdown export, triggered by opening + // a document rather than by editing it. + trailingNode: false, + // Its list types default to camelCase, so it is inert against this + // schema. Off rather than registered-and-doing-nothing. + listKeymap: false, }), KnotBulletList, KnotOrderedList, @@ -90,11 +126,15 @@ export function createExtensions(opts: { HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" }, }), Collaboration.configure({ document: opts.doc }), - CollaborationCursor.configure({ + // Successor to CollaborationCursor, which has no v3 release. Only ever + // reads `provider.awareness`, so the shim stands. `user.color` must be + // 6-digit hex: the extension replaces anything else with "transparent", + // which renders an invisible caret rather than warning (see colorFor). + CollaborationCaret.configure({ provider: { awareness: opts.awareness } as never, user: opts.user, }), - Image.configure({ inline: false, allowBase64: false }), + KnotImage.configure({ inline: false, allowBase64: false }), Attachment, ExcalidrawBoard, TaskListExtension, diff --git a/web/src/features/editor/nodes/MermaidCodeBlock.tsx b/web/src/features/editor/nodes/MermaidCodeBlock.tsx index 9351590..d3b45ea 100644 --- a/web/src/features/editor/nodes/MermaidCodeBlock.tsx +++ b/web/src/features/editor/nodes/MermaidCodeBlock.tsx @@ -93,7 +93,7 @@ function MermaidNodeView(props: ReactNodeViewProps) { return (
-          
+           as="code" />
         
); @@ -203,12 +203,12 @@ function MermaidPreview(props: ReactNodeViewProps) { {/* Source still exists in the document; hide it from view but keep it editable via the keyboard navigation by toggling to source mode. */}
- + as="code" />
) : (
-          
+           as="code" spellCheck={false} />
         
)} diff --git a/web/src/features/editor/schema.test.ts b/web/src/features/editor/schema.test.ts index cd01943..f3eb594 100644 --- a/web/src/features/editor/schema.test.ts +++ b/web/src/features/editor/schema.test.ts @@ -51,9 +51,14 @@ const REGISTERED_EXTENSIONS = [ "code", "code_block", "collaboration", - "collaborationCursor", + // v3: CollaborationCursor has no v3 release; this is its successor. + "collaborationCaret", "commands", "commentsHighlight", + // v3 core: emits an editor "delete" event when nodes are removed. Skips + // transactions carrying y-sync meta, so it never reacts to remote updates, + // and mutates nothing. + "delete", "doc", "drop", "dropCursor", @@ -73,6 +78,9 @@ const REGISTERED_EXTENSIONS = [ "knotTaskList", "link", "list_item", + // v3: ListItem registers this keymap itself, named after the node — so it + // is active against the renamed list_item rather than inert. + "list_itemBranchingDeleteKeymap", "ordered_list", "paragraph", "paste", @@ -84,6 +92,10 @@ const REGISTERED_EXTENSIONS = [ "table_header", "table_row", "text", + // v3 core. addGlobalAttributes() returns [] unless `direction` is + // configured, and it is not, so this adds no attribute to any node — as + // the attribute-parity test below independently confirms. + "textDirection", "underline", ]; diff --git a/web/src/styles/prose.css b/web/src/styles/prose.css index 4ad2dba..edeaeae 100644 --- a/web/src/styles/prose.css +++ b/web/src/styles/prose.css @@ -230,10 +230,10 @@ } /* ---------------------------------------------------------------- */ -/* Tiptap CollaborationCursor — remote peer carets + labels */ +/* Tiptap CollaborationCaret — remote peer carets + labels */ /* ---------------------------------------------------------------- */ -.collaboration-cursor__caret { +.collaboration-carets__caret { position: relative; margin-left: -1px; margin-right: -1px; @@ -243,7 +243,7 @@ word-break: normal; } -.collaboration-cursor__label { +.collaboration-carets__label { position: absolute; top: -1.4em; left: -2px; @@ -270,16 +270,15 @@ /* Reveal the label again when the user is actively typing nearby — ProseMirror toggles `data-active` on selection-change in some setups; otherwise hovering the caret restores it. */ -.collaboration-cursor__caret:hover .collaboration-cursor__label { +.collaboration-carets__caret:hover .collaboration-carets__label { animation: none; opacity: 1; } -/* No rule for the remote peer's selection highlight. y-prosemirror emits it - as `.ProseMirror-yjs-selection` with the peer's colour set inline at ~44% +/* No rule for the remote peer's selection highlight. The binding emits it as + `.ProseMirror-yjs-selection` with the peer's colour set inline at ~44% alpha, so it is already styled and an inline background could not be - overridden from here anyway. A `.collaboration-cursor__selection` rule - stood here and matched nothing — that class does not exist. */ + overridden from here anyway. */ /* ---------------------------------------------------------------- */ /* Mermaid NodeView — source-mode pre/code overrides */