-
- );
-}
diff --git a/examples/07-collaboration/05-comments/src/SettingsSelect.tsx b/examples/07-collaboration/05-comments/src/SettingsSelect.tsx
deleted file mode 100644
index 0dfc79dc3f..0000000000
--- a/examples/07-collaboration/05-comments/src/SettingsSelect.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ComponentProps, useComponentsContext } from "@blocknote/react";
-
-// This component is used to display a selection dropdown with a label. By using
-// the useComponentsContext hook, we can create it out of existing components
-// within the same UI library that `BlockNoteView` uses (Mantine, Ariakit, or
-// ShadCN), to match the design of the editor.
-export const SettingsSelect = (props: {
- label: string;
- items: ComponentProps["FormattingToolbar"]["Select"]["items"];
-}) => {
- const Components = useComponentsContext()!;
-
- return (
-
-
-
{props.label + ":"}
-
-
-
- );
-};
diff --git a/examples/07-collaboration/05-comments/src/style.css b/examples/07-collaboration/05-comments/src/style.css
deleted file mode 100644
index eaf9d337e9..0000000000
--- a/examples/07-collaboration/05-comments/src/style.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.comments-main-container {
- align-items: center;
- background-color: var(--bn-colors-disabled-background);
- display: flex;
- flex-direction: column-reverse;
- gap: 10px;
- height: 100%;
- max-width: none;
- padding: 10px;
- width: 100%;
-}
-
-.comments-main-container .bn-editor {
- height: 100%;
- max-width: 700px;
- overflow: auto;
- width: 100%;
-}
-
-.comments-main-container .settings {
- display: flex;
- max-width: 700px;
- width: 100%;
-}
-
-.comments-main-container .settings-select {
- display: flex;
- gap: 10px;
-}
-
-.comments-main-container .settings-select .bn-toolbar {
- align-items: center;
- box-shadow: none;
-}
-
-.comments-main-container .settings-select h2 {
- color: var(--bn-colors-menu-text);
- margin: 0;
- font-size: 12px;
- line-height: 12px;
- padding-left: 14px;
-}
-
-.bn-thread {
- max-height: 200px;
- overflow: auto !important;
-}
diff --git a/examples/07-collaboration/05-comments/src/userdata.ts b/examples/07-collaboration/05-comments/src/userdata.ts
deleted file mode 100644
index c54eaf0f9a..0000000000
--- a/examples/07-collaboration/05-comments/src/userdata.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { User } from "@blocknote/core/comments";
-
-const colors = [
- "#958DF1",
- "#F98181",
- "#FBBC88",
- "#FAF594",
- "#70CFF8",
- "#94FADB",
- "#B9F18D",
-];
-
-const getRandomElement = (list: any[]) =>
- list[Math.floor(Math.random() * list.length)];
-
-export const getRandomColor = () => getRandomElement(colors);
-
-export type MyUserType = User & {
- role: "editor" | "comment";
-};
-
-export const HARDCODED_USERS: MyUserType[] = [
- {
- id: "1",
- username: "John Doe",
- avatarUrl: "https://placehold.co/100x100?text=John",
- role: "editor",
- },
- {
- id: "2",
- username: "Jane Doe",
- avatarUrl: "https://placehold.co/100x100?text=Jane",
- role: "editor",
- },
- {
- id: "3",
- username: "Bob Smith",
- avatarUrl: "https://placehold.co/100x100?text=Bob",
- role: "comment",
- },
- {
- id: "4",
- username: "Betty Smith",
- avatarUrl: "https://placehold.co/100x100?text=Betty",
- role: "comment",
- },
-];
diff --git a/examples/07-collaboration/05-comments/tsconfig.json b/examples/07-collaboration/05-comments/tsconfig.json
deleted file mode 100644
index dbe3e6f62d..0000000000
--- a/examples/07-collaboration/05-comments/tsconfig.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
- "compilerOptions": {
- "target": "ESNext",
- "useDefineForClassFields": true,
- "lib": [
- "DOM",
- "DOM.Iterable",
- "ESNext"
- ],
- "allowJs": false,
- "skipLibCheck": true,
- "esModuleInterop": false,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
- "composite": true
- },
- "include": [
- "."
- ],
- "__ADD_FOR_LOCAL_DEV_references": [
- {
- "path": "../../../packages/core/"
- },
- {
- "path": "../../../packages/react/"
- }
- ]
-}
\ No newline at end of file
diff --git a/examples/07-collaboration/05-comments/vite.config.ts b/examples/07-collaboration/05-comments/vite.config.ts
deleted file mode 100644
index f62ab20bc2..0000000000
--- a/examples/07-collaboration/05-comments/vite.config.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
-import react from "@vitejs/plugin-react";
-import * as fs from "fs";
-import * as path from "path";
-import { defineConfig } from "vite";
-// import eslintPlugin from "vite-plugin-eslint";
-// https://vitejs.dev/config/
-export default defineConfig((conf) => ({
- plugins: [react()],
- optimizeDeps: {},
- build: {
- sourcemap: true,
- },
- resolve: {
- alias:
- conf.command === "build" ||
- !fs.existsSync(path.resolve(__dirname, "../../packages/core/src"))
- ? {}
- : ({
- // Comment out the lines below to load a built version of blocknote
- // or, keep as is to load live from sources with live reload working
- "@blocknote/core": path.resolve(
- __dirname,
- "../../packages/core/src/"
- ),
- "@blocknote/react": path.resolve(
- __dirname,
- "../../packages/react/src/"
- ),
- } as any),
- },
-}));
diff --git a/examples/07-collaboration/06-comments-with-sidebar/.bnexample.json b/examples/07-collaboration/06-comments-with-sidebar/.bnexample.json
deleted file mode 100644
index c741699750..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/.bnexample.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "playground": true,
- "docs": true,
- "author": "matthewlipski",
- "tags": ["Advanced", "Comments", "Collaboration"],
- "dependencies": {
- "y-partykit": "^0.0.25",
- "yjs": "^13.6.27",
- "@mantine/core": "^8.3.4"
- }
-}
diff --git a/examples/07-collaboration/06-comments-with-sidebar/README.md b/examples/07-collaboration/06-comments-with-sidebar/README.md
deleted file mode 100644
index 2502620fbe..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Threads Sidebar
-
-In this example, you can add comments to the document while collaborating with others. You can also pick user accounts with different permissions, as well as react to, reply to, and resolve existing comments. The comments are displayed floating next to the text they refer to, and appear when selecting said text. The comments are shown in a separate sidebar using the `ThreadsSidebar` component.
-
-**Try it out:** Click the "Add comment" button in
-the [Formatting Toolbar](/docs/react/components/formatting-toolbar) to add a
-comment!
-
-**Relevant Docs:**
-
-- [Comments Sidebar](/docs/features/collaboration/comments#sidebar-view)
-- [Real-time collaboration](/docs/features/collaboration)
-- [Y-Sweet on Jamsocket](https://docs.jamsocket.com/y-sweet/tutorials/blocknote)
-- [Editor Setup](/docs/getting-started/editor-setup)
diff --git a/examples/07-collaboration/06-comments-with-sidebar/index.html b/examples/07-collaboration/06-comments-with-sidebar/index.html
deleted file mode 100644
index 6af0826869..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- Threads Sidebar
-
-
-
-
-
-
-
diff --git a/examples/07-collaboration/06-comments-with-sidebar/main.tsx b/examples/07-collaboration/06-comments-with-sidebar/main.tsx
deleted file mode 100644
index 677c7f7eed..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/main.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
-import React from "react";
-import { createRoot } from "react-dom/client";
-import App from "./src/App.jsx";
-
-const root = createRoot(document.getElementById("root")!);
-root.render(
-
-
-
-);
diff --git a/examples/07-collaboration/06-comments-with-sidebar/package.json b/examples/07-collaboration/06-comments-with-sidebar/package.json
deleted file mode 100644
index 3411ea5c5e..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "@blocknote/example-collaboration-comments-with-sidebar",
- "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
- "type": "module",
- "private": true,
- "version": "0.12.4",
- "scripts": {
- "start": "vite",
- "dev": "vite",
- "build:prod": "tsc && vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "@blocknote/ariakit": "latest",
- "@blocknote/core": "latest",
- "@blocknote/mantine": "latest",
- "@blocknote/react": "latest",
- "@blocknote/shadcn": "latest",
- "@mantine/core": "^8.3.4",
- "@mantine/hooks": "^8.3.4",
- "@mantine/utils": "^6.0.22",
- "react": "^19.2.1",
- "react-dom": "^19.2.1",
- "y-partykit": "^0.0.25",
- "yjs": "^13.6.27"
- },
- "devDependencies": {
- "@types/react": "^19.2.2",
- "@types/react-dom": "^19.2.2",
- "@vitejs/plugin-react": "^4.7.0",
- "vite": "^5.4.20"
- }
-}
\ No newline at end of file
diff --git a/examples/07-collaboration/06-comments-with-sidebar/src/App.tsx b/examples/07-collaboration/06-comments-with-sidebar/src/App.tsx
deleted file mode 100644
index 84ad0d577a..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/src/App.tsx
+++ /dev/null
@@ -1,194 +0,0 @@
-"use client";
-
-import {
- DefaultThreadStoreAuth,
- YjsThreadStore,
- CommentsExtension,
-} from "@blocknote/core/comments";
-import { BlockNoteView } from "@blocknote/mantine";
-import "@blocknote/mantine/style.css";
-import {
- BlockNoteViewEditor,
- FloatingComposerController,
- ThreadsSidebar,
- useCreateBlockNote,
-} from "@blocknote/react";
-import { useMemo, useState } from "react";
-import YPartyKitProvider from "y-partykit/provider";
-import * as Y from "yjs";
-
-import { SettingsSelect } from "./SettingsSelect";
-import { HARDCODED_USERS, MyUserType, getRandomColor } from "./userdata";
-
-import "./style.css";
-
-// The resolveUsers function fetches information about your users
-// (e.g. their name, avatar, etc.). Usually, you'd fetch this from your
-// own database or user management system.
-// Here, we just return the hardcoded users (from userdata.ts)
-async function resolveUsers(userIds: string[]) {
- // fake a (slow) network request
- await new Promise((resolve) => setTimeout(resolve, 1000));
-
- return HARDCODED_USERS.filter((user) => userIds.includes(user.id));
-}
-
-// Sets up Yjs document and PartyKit Yjs provider.
-const doc = new Y.Doc();
-const provider = new YPartyKitProvider(
- "blocknote-dev.yousefed.partykit.dev",
- // Use a unique name as a "room" for your application.
- "comments-with-sidebar",
- doc,
-);
-
-// This follows the Y-Sweet example to setup a collabotive editor
-// (but of course, you also use other collaboration providers
-// see the docs for more information)
-export default function App() {
- const [activeUser, setActiveUser] = useState(HARDCODED_USERS[0]);
- const [commentFilter, setCommentFilter] = useState<
- "open" | "resolved" | "all"
- >("open");
- const [commentSort, setCommentSort] = useState<
- "position" | "recent-activity" | "oldest"
- >("position");
-
- // setup the thread store which stores / and syncs thread / comment data
- const threadStore = useMemo(() => {
- // (alternative, use TiptapCollabProvider)
- // const provider = new TiptapCollabProvider({
- // name: "test",
- // baseUrl: "https://collab.yourdomain.com",
- // appId: "test",
- // document: doc,
- // });
- // return new TiptapThreadStore(
- // activeUser.id,
- // provider,
- // new DefaultThreadStoreAuth(activeUser.id, activeUser.role)
- // );
- return new YjsThreadStore(
- activeUser.id,
- doc.getMap("threads"),
- new DefaultThreadStoreAuth(activeUser.id, activeUser.role),
- );
- }, [doc, activeUser]);
-
- // setup the editor with comments and collaboration
- const editor = useCreateBlockNote(
- {
- collaboration: {
- provider,
- fragment: doc.getXmlFragment("blocknote"),
- user: { color: getRandomColor(), name: activeUser.username },
- },
- extensions: [CommentsExtension({ threadStore, resolveUsers })],
- },
- [activeUser, threadStore],
- );
-
- return (
-
- {/* We place the editor, the sidebar, and any settings selects within
- `BlockNoteView` as they use BlockNote UI components and need the context
- for them. */}
-
- {/* Because we set `renderEditor` to false, we can now manually place
- `BlockNoteViewEditor` (the actual editor component) in its own
- section below the user settings select. */}
-
- {/* Since we disabled rendering of comments with `comments={false}`,
- we need to re-add the floating composer, which is the UI element that
- appears when creating new threads. */}
-
-
-
- {/* We also place the `ThreadsSidebar` component in its own section,
- along with settings for filtering and sorting. */}
-
-
- );
-}
diff --git a/examples/07-collaboration/06-comments-with-sidebar/src/SettingsSelect.tsx b/examples/07-collaboration/06-comments-with-sidebar/src/SettingsSelect.tsx
deleted file mode 100644
index 0dfc79dc3f..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/src/SettingsSelect.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ComponentProps, useComponentsContext } from "@blocknote/react";
-
-// This component is used to display a selection dropdown with a label. By using
-// the useComponentsContext hook, we can create it out of existing components
-// within the same UI library that `BlockNoteView` uses (Mantine, Ariakit, or
-// ShadCN), to match the design of the editor.
-export const SettingsSelect = (props: {
- label: string;
- items: ComponentProps["FormattingToolbar"]["Select"]["items"];
-}) => {
- const Components = useComponentsContext()!;
-
- return (
-
-
-
{props.label + ":"}
-
-
-
- );
-};
diff --git a/examples/07-collaboration/06-comments-with-sidebar/src/style.css b/examples/07-collaboration/06-comments-with-sidebar/src/style.css
deleted file mode 100644
index f903d52e1b..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/src/style.css
+++ /dev/null
@@ -1,73 +0,0 @@
-.sidebar-comments-main-container {
- background-color: var(--bn-colors-disabled-background);
- display: flex;
- gap: 10px;
- height: 100%;
- max-width: none;
- padding: 10px;
- width: 100%;
-}
-
-.sidebar-comments-main-container .editor-layout-wrapper {
- display: flex;
- flex: 2;
- justify-content: center;
- width: 0;
-}
-
-.sidebar-comments-main-container .editor-section,
-.threads-sidebar-section {
- border-radius: var(--bn-border-radius-large);
- display: flex;
- flex: 1;
- flex-direction: column;
- gap: 10px;
- max-height: 100%;
- min-width: 350px;
- width: 0;
-}
-
-.sidebar-comments-main-container .editor-section h1,
-.threads-sidebar-section h1 {
- color: var(--bn-colors-menu-text);
- margin: 0;
- font-size: 32px;
-}
-
-.sidebar-comments-main-container .bn-editor,
-.bn-threads-sidebar {
- border-radius: var(--bn-border-radius-medium);
- display: flex;
- flex-direction: column;
- gap: 10px;
- height: 100%;
- overflow: auto;
-}
-
-.sidebar-comments-main-container .editor-section {
- max-width: 700px;
-}
-
-.sidebar-comments-main-container .settings {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
-}
-
-.sidebar-comments-main-container .settings-select {
- display: flex;
- gap: 10px;
-}
-
-.sidebar-comments-main-container .settings-select .bn-toolbar {
- align-items: center;
- box-shadow: none;
-}
-
-.sidebar-comments-main-container .settings-select h2 {
- color: var(--bn-colors-menu-text);
- margin: 0;
- font-size: 12px;
- line-height: 12px;
- padding-left: 14px;
-}
diff --git a/examples/07-collaboration/06-comments-with-sidebar/src/userdata.ts b/examples/07-collaboration/06-comments-with-sidebar/src/userdata.ts
deleted file mode 100644
index c54eaf0f9a..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/src/userdata.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { User } from "@blocknote/core/comments";
-
-const colors = [
- "#958DF1",
- "#F98181",
- "#FBBC88",
- "#FAF594",
- "#70CFF8",
- "#94FADB",
- "#B9F18D",
-];
-
-const getRandomElement = (list: any[]) =>
- list[Math.floor(Math.random() * list.length)];
-
-export const getRandomColor = () => getRandomElement(colors);
-
-export type MyUserType = User & {
- role: "editor" | "comment";
-};
-
-export const HARDCODED_USERS: MyUserType[] = [
- {
- id: "1",
- username: "John Doe",
- avatarUrl: "https://placehold.co/100x100?text=John",
- role: "editor",
- },
- {
- id: "2",
- username: "Jane Doe",
- avatarUrl: "https://placehold.co/100x100?text=Jane",
- role: "editor",
- },
- {
- id: "3",
- username: "Bob Smith",
- avatarUrl: "https://placehold.co/100x100?text=Bob",
- role: "comment",
- },
- {
- id: "4",
- username: "Betty Smith",
- avatarUrl: "https://placehold.co/100x100?text=Betty",
- role: "comment",
- },
-];
diff --git a/examples/07-collaboration/06-comments-with-sidebar/tsconfig.json b/examples/07-collaboration/06-comments-with-sidebar/tsconfig.json
deleted file mode 100644
index dbe3e6f62d..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/tsconfig.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
- "compilerOptions": {
- "target": "ESNext",
- "useDefineForClassFields": true,
- "lib": [
- "DOM",
- "DOM.Iterable",
- "ESNext"
- ],
- "allowJs": false,
- "skipLibCheck": true,
- "esModuleInterop": false,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
- "composite": true
- },
- "include": [
- "."
- ],
- "__ADD_FOR_LOCAL_DEV_references": [
- {
- "path": "../../../packages/core/"
- },
- {
- "path": "../../../packages/react/"
- }
- ]
-}
\ No newline at end of file
diff --git a/examples/07-collaboration/06-comments-with-sidebar/vite.config.ts b/examples/07-collaboration/06-comments-with-sidebar/vite.config.ts
deleted file mode 100644
index f62ab20bc2..0000000000
--- a/examples/07-collaboration/06-comments-with-sidebar/vite.config.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
-import react from "@vitejs/plugin-react";
-import * as fs from "fs";
-import * as path from "path";
-import { defineConfig } from "vite";
-// import eslintPlugin from "vite-plugin-eslint";
-// https://vitejs.dev/config/
-export default defineConfig((conf) => ({
- plugins: [react()],
- optimizeDeps: {},
- build: {
- sourcemap: true,
- },
- resolve: {
- alias:
- conf.command === "build" ||
- !fs.existsSync(path.resolve(__dirname, "../../packages/core/src"))
- ? {}
- : ({
- // Comment out the lines below to load a built version of blocknote
- // or, keep as is to load live from sources with live reload working
- "@blocknote/core": path.resolve(
- __dirname,
- "../../packages/core/src/"
- ),
- "@blocknote/react": path.resolve(
- __dirname,
- "../../packages/react/src/"
- ),
- } as any),
- },
-}));
diff --git a/examples/07-collaboration/07-ghost-writer/.bnexample.json b/examples/07-collaboration/07-ghost-writer/.bnexample.json
deleted file mode 100644
index 2c30ef42bd..0000000000
--- a/examples/07-collaboration/07-ghost-writer/.bnexample.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "playground": true,
- "docs": false,
- "author": "nperez0111",
- "tags": ["Advanced", "Development", "Collaboration"],
- "dependencies": {
- "y-partykit": "^0.0.25",
- "yjs": "^13.6.27"
- }
-}
diff --git a/examples/07-collaboration/07-ghost-writer/README.md b/examples/07-collaboration/07-ghost-writer/README.md
deleted file mode 100644
index 608251baeb..0000000000
--- a/examples/07-collaboration/07-ghost-writer/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Ghost Writer
-
-In this example, we use a local Yjs document to store the document state, and have a ghost writer that edits the document in real-time.
-
-**Try it out:** Open this page in a new browser tab or window to see it in action!
-
-**Relevant Docs:**
-
-- [Editor Setup](/docs/getting-started/editor-setup)
diff --git a/examples/07-collaboration/07-ghost-writer/index.html b/examples/07-collaboration/07-ghost-writer/index.html
deleted file mode 100644
index 784f0cc6cd..0000000000
--- a/examples/07-collaboration/07-ghost-writer/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
- Ghost Writer
-
-
-
-
-
-
-
diff --git a/examples/07-collaboration/07-ghost-writer/main.tsx b/examples/07-collaboration/07-ghost-writer/main.tsx
deleted file mode 100644
index 677c7f7eed..0000000000
--- a/examples/07-collaboration/07-ghost-writer/main.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
-import React from "react";
-import { createRoot } from "react-dom/client";
-import App from "./src/App.jsx";
-
-const root = createRoot(document.getElementById("root")!);
-root.render(
-
-
-
-);
diff --git a/examples/07-collaboration/07-ghost-writer/package.json b/examples/07-collaboration/07-ghost-writer/package.json
deleted file mode 100644
index 6f0e2b022d..0000000000
--- a/examples/07-collaboration/07-ghost-writer/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "@blocknote/example-collaboration-ghost-writer",
- "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
- "type": "module",
- "private": true,
- "version": "0.12.4",
- "scripts": {
- "start": "vite",
- "dev": "vite",
- "build:prod": "tsc && vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "@blocknote/ariakit": "latest",
- "@blocknote/core": "latest",
- "@blocknote/mantine": "latest",
- "@blocknote/react": "latest",
- "@blocknote/shadcn": "latest",
- "@mantine/core": "^8.3.4",
- "@mantine/hooks": "^8.3.4",
- "@mantine/utils": "^6.0.22",
- "react": "^19.2.1",
- "react-dom": "^19.2.1",
- "y-partykit": "^0.0.25",
- "yjs": "^13.6.27"
- },
- "devDependencies": {
- "@types/react": "^19.2.2",
- "@types/react-dom": "^19.2.2",
- "@vitejs/plugin-react": "^4.7.0",
- "vite": "^5.4.20"
- }
-}
\ No newline at end of file
diff --git a/examples/07-collaboration/07-ghost-writer/src/App.tsx b/examples/07-collaboration/07-ghost-writer/src/App.tsx
deleted file mode 100644
index 4344c5c11a..0000000000
--- a/examples/07-collaboration/07-ghost-writer/src/App.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import "@blocknote/core/fonts/inter.css";
-import "@blocknote/mantine/style.css";
-import { BlockNoteView } from "@blocknote/mantine";
-import { useCreateBlockNote } from "@blocknote/react";
-
-import YPartyKitProvider from "y-partykit/provider";
-import * as Y from "yjs";
-import "./styles.css";
-import { useEffect, useState } from "react";
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { EditorView } from "prosemirror-view";
-
-const params = new URLSearchParams(window.location.search);
-const ghostWritingRoom = params.get("room");
-const ghostWriterIndex = parseInt(params.get("index") || "1");
-const isGhostWriting = Boolean(ghostWritingRoom);
-const roomName = ghostWritingRoom || `ghost-writer-${Date.now()}`;
-// Sets up Yjs document and PartyKit Yjs provider.
-const doc = new Y.Doc();
-const provider = new YPartyKitProvider(
- "blocknote-dev.yousefed.partykit.dev",
- // Use a unique name as a "room" for your application.
- roomName,
- doc,
-);
-
-/**
- * Y-prosemirror has an optimization, where it doesn't send awareness updates unless the editor is currently focused.
- * So, for the ghost writers, we override the hasFocus method to always return true.
- */
-if (isGhostWriting) {
- EditorView.prototype.hasFocus = () => true;
-}
-
-const ghostContent =
- "This demo shows a two-way sync of documents. It allows you to test collaboration features, and see how stable the editor is. ";
-
-export default function App() {
- const [numGhostWriters, setNumGhostWriters] = useState(1);
- const [isPaused, setIsPaused] = useState(false);
- const editor = useCreateBlockNote({
- collaboration: {
- // The Yjs Provider responsible for transporting updates:
- provider,
- // Where to store BlockNote data in the Y.Doc:
- fragment: doc.getXmlFragment("document-store"),
- // Information (name and color) for this user:
- user: {
- name: isGhostWriting
- ? `Ghost Writer #${ghostWriterIndex}`
- : "My Username",
- color: isGhostWriting ? "#CCCCCC" : "#00ff00",
- },
- },
- });
-
- useEffect(() => {
- if (!isGhostWriting || isPaused) {
- return;
- }
- let index = 0;
- let timeout: NodeJS.Timeout;
-
- const scheduleNextChar = () => {
- const jitter = Math.random() * 200; // Random delay between 0-200ms
- timeout = setTimeout(() => {
- const firstBlock = editor.document?.[0];
- if (firstBlock) {
- editor.insertInlineContent(ghostContent[index], {
- updateSelection: true,
- });
- index = (index + 1) % ghostContent.length;
- }
- scheduleNextChar();
- }, 50 + jitter);
- };
-
- scheduleNextChar();
-
- return () => clearTimeout(timeout);
- }, [editor, isPaused]);
-
- // Renders the editor instance.
- return (
- <>
- {isGhostWriting ? (
-
- ) : (
- <>
-
-
-
- >
- )}
-
-
- {!isGhostWriting && (
-
);
diff --git a/packages/server-util/package.json b/packages/server-util/package.json
index ca8f847877..7426084df0 100644
--- a/packages/server-util/package.json
+++ b/packages/server-util/package.json
@@ -11,7 +11,7 @@
"directory": "packages/server-util"
},
"license": "MPL-2.0",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -56,14 +56,14 @@
"test-watch": "vitest watch"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/react": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/react": "0.45.0",
"@tiptap/core": "^3.13.0",
"@tiptap/pm": "^3.13.0",
"jsdom": "^25.0.1",
- "y-prosemirror": "^1.3.7",
- "y-protocols": "^1.0.6",
- "yjs": "^13.6.27"
+ "@y/prosemirror": "2.0.0-2",
+ "@y/protocols": "1.0.6-3",
+ "@y/y": "14.0.0-19"
},
"devDependencies": {
"@types/jsdom": "^21.1.7",
diff --git a/packages/server-util/src/context/ServerBlockNoteEditor.ts b/packages/server-util/src/context/ServerBlockNoteEditor.ts
index 21a259f6c0..20087ddd51 100644
--- a/packages/server-util/src/context/ServerBlockNoteEditor.ts
+++ b/packages/server-util/src/context/ServerBlockNoteEditor.ts
@@ -30,7 +30,7 @@ import * as React from "react";
import { createElement } from "react";
import { flushSync } from "react-dom";
import { createRoot } from "react-dom/client";
-import type * as Y from "yjs";
+import type * as Y from "@y/y";
/**
* Use the ServerBlockNoteEditor to interact with BlockNote documents in a server (nodejs) environment.
diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json
index 761d52e3bf..6cc1dc99c2 100644
--- a/packages/shadcn/package.json
+++ b/packages/shadcn/package.json
@@ -11,7 +11,7 @@
"directory": "packages/shadcn"
},
"license": "MPL-2.0",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -56,8 +56,8 @@
"clean": "rimraf dist && rimraf types"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/react": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/react": "0.45.0",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
diff --git a/packages/xl-ai-server/package.json b/packages/xl-ai-server/package.json
index 83ef84fdb5..da665b2f85 100644
--- a/packages/xl-ai-server/package.json
+++ b/packages/xl-ai-server/package.json
@@ -3,7 +3,7 @@
"homepage": "https://github.com/TypeCellOS/BlockNote",
"private": true,
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
diff --git a/packages/xl-ai/package.json b/packages/xl-ai/package.json
index 7e7a681baa..2d25dd160b 100644
--- a/packages/xl-ai/package.json
+++ b/packages/xl-ai/package.json
@@ -11,7 +11,7 @@
"directory": "packages/xl-ai"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -71,9 +71,9 @@
"dependencies": {
"@ai-sdk/provider-utils": "^3.0.17",
"@ai-sdk/react": "^2.0.102",
- "@blocknote/core": "0.44.2",
- "@blocknote/mantine": "0.44.2",
- "@blocknote/react": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/mantine": "0.45.0",
+ "@blocknote/react": "0.45.0",
"@floating-ui/react": "^0.26.28",
"@handlewithcare/prosemirror-suggest-changes": "^0.1.8",
"@tiptap/core": "^3.13.0",
@@ -92,7 +92,7 @@
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"unified": "^11.0.5",
- "y-prosemirror": "^1.3.7"
+ "@y/prosemirror": "2.0.0-2"
},
"devDependencies": {
"@ai-sdk/anthropic": "^2.0.31",
diff --git a/packages/xl-ai/src/plugins/AgentCursorPlugin.ts b/packages/xl-ai/src/plugins/AgentCursorPlugin.ts
index f2492e1a08..bdecb2b71a 100644
--- a/packages/xl-ai/src/plugins/AgentCursorPlugin.ts
+++ b/packages/xl-ai/src/plugins/AgentCursorPlugin.ts
@@ -1,6 +1,6 @@
import { Plugin, PluginKey } from "prosemirror-state";
import { Decoration, DecorationSet } from "prosemirror-view";
-import { defaultSelectionBuilder } from "y-prosemirror";
+import { defaultSelectionBuilder } from "@y/prosemirror";
type AgentCursorState = {
selection: { anchor: number; head: number } | undefined;
diff --git a/packages/xl-docx-exporter/package.json b/packages/xl-docx-exporter/package.json
index 58298efe92..39c2b7c7fa 100644
--- a/packages/xl-docx-exporter/package.json
+++ b/packages/xl-docx-exporter/package.json
@@ -9,7 +9,7 @@
"directory": "packages/xl-docx-exporter"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -57,8 +57,8 @@
"email": "email dev"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/xl-multi-column": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/xl-multi-column": "0.45.0",
"buffer": "^6.0.3",
"docx": "^9.5.1",
"image-meta": "^0.2.2"
diff --git a/packages/xl-email-exporter/package.json b/packages/xl-email-exporter/package.json
index 5ab0cb4d9b..24f9df4e3c 100644
--- a/packages/xl-email-exporter/package.json
+++ b/packages/xl-email-exporter/package.json
@@ -9,7 +9,7 @@
"directory": "packages/xl-email-exporter"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -55,8 +55,8 @@
},
"dependencies": {
"web-streams-polyfill": "^4.2.0",
- "@blocknote/core": "0.44.2",
- "@blocknote/react": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/react": "0.45.0",
"@react-email/components": "^0.1.1",
"@react-email/render": "^1.4.0",
"buffer": "^6.0.3",
diff --git a/packages/xl-multi-column/package.json b/packages/xl-multi-column/package.json
index 7244b8b231..15579bf945 100644
--- a/packages/xl-multi-column/package.json
+++ b/packages/xl-multi-column/package.json
@@ -9,7 +9,7 @@
"directory": "packages/xl-multi-column"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -51,8 +51,8 @@
"clean": "rimraf dist && rimraf types"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/react": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/react": "0.45.0",
"@tiptap/core": "^3.13.0",
"prosemirror-model": "^1.25.4",
"prosemirror-state": "^1.4.4",
diff --git a/packages/xl-odt-exporter/package.json b/packages/xl-odt-exporter/package.json
index 578006fcfe..ddb4b45c24 100644
--- a/packages/xl-odt-exporter/package.json
+++ b/packages/xl-odt-exporter/package.json
@@ -9,7 +9,7 @@
"directory": "packages/xl-odt-exporter"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -57,8 +57,8 @@
"clean": "rimraf dist && rimraf types"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/xl-multi-column": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/xl-multi-column": "0.45.0",
"@zip.js/zip.js": "^2.8.8",
"buffer": "^6.0.3",
"image-meta": "^0.2.2"
diff --git a/packages/xl-pdf-exporter/package.json b/packages/xl-pdf-exporter/package.json
index 98c09bdb7f..9e349ad82e 100644
--- a/packages/xl-pdf-exporter/package.json
+++ b/packages/xl-pdf-exporter/package.json
@@ -9,7 +9,7 @@
"directory": "packages/xl-pdf-exporter"
},
"license": "GPL-3.0 OR PROPRIETARY",
- "version": "0.44.2",
+ "version": "0.45.0",
"files": [
"dist",
"types",
@@ -56,9 +56,9 @@
"email": "email dev"
},
"dependencies": {
- "@blocknote/core": "0.44.2",
- "@blocknote/react": "0.44.2",
- "@blocknote/xl-multi-column": "0.44.2",
+ "@blocknote/core": "0.45.0",
+ "@blocknote/react": "0.45.0",
+ "@blocknote/xl-multi-column": "0.45.0",
"@react-pdf/renderer": "^4.3.0",
"buffer": "^6.0.3",
"docx": "^9.5.1"
diff --git a/patches/@y__prosemirror.patch b/patches/@y__prosemirror.patch
new file mode 100644
index 0000000000..6e79a3f713
--- /dev/null
+++ b/patches/@y__prosemirror.patch
@@ -0,0 +1,3919 @@
+diff --git a/dist/src/index.d.ts b/dist/src/index.d.ts
+index fec5f1c23d3f28e250fecd7045fcebe7fc60993f..a35c0e8a9be7b7ea08d9b25d1dc4070caf187634 100644
+--- a/dist/src/index.d.ts
++++ b/dist/src/index.d.ts
+@@ -1,14 +1,50 @@
+ /**
++ * This Prosemirror {@link Plugin} is responsible for synchronizing the prosemirror {@link EditorState} with a {@link Y.XmlFragment}
+ * @param {Y.XmlFragment} ytype
+ * @param {object} opts
+- * @param {import('@y/protocols/awareness').Awareness} [opts.awareness]
+- * @param {Y.AbstractAttributionManager} [opts.attributionManager]
++ * @param {Y.DiffAttributionManager} [opts.attributionManager] An {@link Y.DiffAttributionManager} to use for attribution tracking
++ * @param {Y.Doc} [opts.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking
++ * @param {typeof defaultMapAttributionToMark} [opts.mapAttributionToMark] A function to map the {@link Y.Attribution} to a {@link import('prosemirror-model').Mark}
++ * @param {InitializeCallback} [opts.initialize] This callback is called on initialization and is meant to be used to initialize the editor's state or initialize the ydoc content
+ * @returns {Plugin}
+ */
+-export function syncPlugin(ytype: Y.XmlFragment, { awareness, attributionManager }?: {
+- awareness?: import("@y/protocols/awareness").Awareness;
+- attributionManager?: Y.AbstractAttributionManager;
++export function syncPlugin(ytype: Y.XmlFragment, { attributionManager, mapAttributionToMark, suggestionDoc, onInitialize }?: {
++ attributionManager?: Y.DiffAttributionManager | undefined;
++ suggestionDoc?: Y.Doc | undefined;
++ mapAttributionToMark?: ((format: Record | null, attribution: T) => Record | null) | undefined;
++ initialize?: import("./types").InitializeCallback | undefined;
+ }): Plugin;
++/**
++ * Transforms a {@link Node} into a {@link Y.XmlFragment}
++ * @param {Node} node
++ * @param {Y.XmlFragment} fragment
++ * @param {Object} [opts]
++ * @param {Y.DiffAttributionManager} [opts.attributionManager]
++ * @returns {Y.XmlFragment}
++ */
++export function pmToFragment(node: Node, fragment: Y.XmlFragment, { attributionManager }?: {
++ attributionManager?: Y.DiffAttributionManager | undefined;
++}): Y.XmlFragment;
++/**
++ * Applies a {@link Y.XmlFragment}'s content as a ProseMirror {@link Transaction}
++ * @param {Y.XmlFragment} fragment
++ * @param {import('prosemirror-state').Transaction} tr
++ * @param {object} [ctx]
++ * @param {Y.DiffAttributionManager} [ctx.attributionManager]
++ * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]
++ * @returns {import('prosemirror-state').Transaction}
++ */
++export function fragmentToTr(fragment: Y.XmlFragment, tr: import("prosemirror-state").Transaction, { attributionManager, mapAttributionToMark }?: {
++ attributionManager?: Y.DiffAttributionManager | undefined;
++ mapAttributionToMark?: ((format: Record | null, attribution: T) => Record | null) | undefined;
++}): import("prosemirror-state").Transaction;
++/**
++ * Transforms a {@link Y.XmlFragment} into a {@link Node}
++ * @param {Y.XmlFragment} fragment
++ * @param {import('prosemirror-state').Transaction}
++ * @returns {Node}
++ */
++export function fragmentToPm(fragment: Y.XmlFragment, tr: any): Node;
+ /**
+ * This function is used to find the delta offset for a given prosemirror offset in a node.
+ * Given the following document:
+@@ -35,38 +71,134 @@ export function pmToDeltaPath(node: Node, searchPmOffset?: number): number[];
+ * @return {number} The prosemirror offset for the delta path
+ */
+ export function deltaPathToPm(deltaPath: number[], node: Node): number;
+-export class YEditorView extends EditorView {
+- mux: mux.mutex;
++/**
++ * This class is the state of the sync plugin, it is essentially the public API for the sync plugin
++ */
++export class SyncPluginState {
+ /**
+- * @type {{ ytype: Y.XmlFragment, am: Y.AbstractAttributionManager, awareness: any }?}
++ * @param {object} ctx
++ * @param {Y.XmlFragment} ctx.ytype
++ * @param {Y.DiffAttributionManager} [ctx.attributionManager]
++ * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]
++ * @param {Y.Doc} [ctx.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking
++ * @param {Y.Doc} ctx.contentDoc A {@link Y.Doc} to use for content tracking
+ */
+- y: {
++ constructor({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc }: {
+ ytype: Y.XmlFragment;
+- am: Y.AbstractAttributionManager;
+- awareness: any;
+- } | null;
++ attributionManager?: Y.DiffAttributionManager | undefined;
++ mapAttributionToMark?: ((format: Record | null, attribution: T) => Record | null) | undefined;
++ suggestionDoc?: Y.Doc | undefined;
++ contentDoc: Y.Doc;
++ });
++ /**
++ * Get the view that the sync plugin is attached to
++ * @returns {import('prosemirror-view').EditorView}
++ * @private
++ */
++ private get view();
++ /**
++ * This takes a prosemirror transaction and attempts to update the internal plugin state
++ * @param {import('prosemirror-state').Transaction} tr
++ * @returns {SyncPluginState}
++ * @private
++ */
++ private onApplyTr;
++ /**
++ * This will be `true` if the plugin state is initialized and the view is not destroyed
++ */
++ get initialized(): boolean | null;
++ /**
++ * Apply any pending diffs to the ytype
++ * @param {import('prosemirror-state').EditorState} prevState
++ * @private
++ */
++ private onViewUpdate;
++ /**
++ * Initialize the plugin state with the view
++ * @note this will start the synchronization of the prosemirror state with the ydoc
++ * @param {import('prosemirror-view').EditorView} view
++ * @param {InitializeCallback} [onInitialize]
++ * @private
++ */
++ private init;
+ /**
+- * @param {Array>} events
+- * @param {Y.Transaction} tr
++ * Destroy the plugin state
++ * @note this will stop the synchronization of the prosemirror state with the ydoc
++ * @private
+ */
+- _observer: (events: Array>, tr: Y.Transaction) => void;
++ private destroy;
+ /**
+- * @param {Y.XmlFragment} ytype
+- * @param {object} opts
+- * @param {any} [opts.awareness]
+- * @param {Y.AbstractAttributionManager} [opts.attributionManager]
++ * Pause the synchronization of the prosemirror state with the ydoc
+ */
+- bindYType(ytype: Y.XmlFragment, { awareness, attributionManager }?: {
+- awareness?: any;
+- attributionManager?: Y.AbstractAttributionManager;
++ pauseSync(): void;
++ /**
++ * Resume the synchronization of the prosemirror state with the ydoc
++ * @param {object} [opts]
++ * @param {boolean} [opts.keepChanges]
++ */
++ resumeSync({ keepChanges }?: {
++ keepChanges?: boolean | undefined;
+ }): void;
++ /**
++ * Get the mode that the sync plugin is in
++ */
++ get mode(): "sync" | "paused" | "snapshot";
++ /**
++ * Get the ytype that the sync plugin is using
++ */
++ get ytype(): Y.XmlFragment;
++ /**
++ * @param {SnapshotItem} snapshot
++ * @param {SnapshotItem} [prevSnapshot]
++ * @param {Y.Attribution[]} [attrs]
++ */
++ renderSnapshot(snapshot: SnapshotItem, prevSnapshot?: SnapshotItem, attrs?: Y.Attribution[]): void;
++ /**
++ * Set the suggestion mode
++ * @param {'off' | 'view' | 'edit'} mode
++ * -
++ * - 'off': Hide suggestions, edit original document
++ * - 'view': Show suggestions, edit original document
++ * - 'edit': Show suggestions, edits become suggestions
++ */
++ setSuggestionMode(mode: "off" | "view" | "edit"): void;
++ /**
++ * Accept all changes in the suggestion doc
++ */
++ acceptAllChanges(): void;
++ /**
++ * Reject all changes in the suggestion doc
++ */
++ rejectAllChanges(): void;
++ /**
++ * Accept the changes within the given range
++ * @note This will move the content from the suggestion doc into the content doc, so this requires permissions to write to the content doc
++ * @param {number} from
++ * @param {number} [to]
++ */
++ acceptChanges(from: number, to?: number): void;
++ /**
++ * Reject the changes within the given range
++ * @note This will remove the content from the suggestion doc, so that it no longer appears in the editor
++ * @param {number} from
++ * @param {number} [to]
++ */
++ rejectChanges(from: number, to?: number): void;
++ #private;
+ }
+ export function nodesToDelta(ns: Array): delta.DeltaBuilderAny;
+ export function nodeToDelta(n: Node): delta.DeltaBuilderAny;
+-export function deltaToPSteps(tr: import("prosemirror-state").Transaction, d: ProsemirrorDelta, pnode?: Node, currPos?: {
++export function deltaToPSteps(tr: import("prosemirror-transform").Transform, d: ProsemirrorDelta, pnode?: Node, currPos?: {
+ i: number;
+-}): import("prosemirror-state").Transaction;
+-export function trToDelta(tr: Transform): ProsemirrorDelta;
++}): import("prosemirror-transform").Transform;
++export function docDiffToDelta(beforeDoc: Node, afterDoc: Node): delta.DeltaBuilder;
++export function trToDelta(tr: Transform): delta.DeltaBuilder;
+ export function stepToDelta(step: import("prosemirror-transform").Step, beforeDoc: import("prosemirror-model").Node): ProsemirrorDelta;
+ export function deltaModifyNodeAt(node: Node, pmOffset: number, mod: (d: delta.DeltaBuilderAny) => any): ProsemirrorDelta;
+ export type ProsemirrorDelta = s.Unwrap, string, any>>>;
++export type SyncPluginMode = import("./types").SyncPluginMode;
++export type YSyncPluginMeta = import("./types").YSyncPluginMeta;
++export type SnapshotItem = import("./types").SnapshotItem;
++export type InitializeCallback = import("./types").InitializeCallback;
+ import * as Y from '@y/y';
+ import { Plugin } from 'prosemirror-state';
+ import { Node } from 'prosemirror-model';
+-import { EditorView } from 'prosemirror-view';
+-import * as mux from 'lib0/mutex';
+ import * as delta from 'lib0/delta';
+ import { Transform } from 'prosemirror-transform';
+ import * as s from 'lib0/schema';
+diff --git a/dist/src/lib.d.ts b/dist/src/lib.d.ts
+index 30ebc3bbc8eb20f96d1135b7fe8e8c8659bacf22..b9881fdb82fb5374564da386431afc12aeb10d32 100644
+--- a/dist/src/lib.d.ts
++++ b/dist/src/lib.d.ts
+@@ -95,14 +95,14 @@ export function yDocToProsemirrorJSON(ydoc: Y.Doc, xmlFragment?: string): Record
+ */
+ export function yXmlFragmentToProsemirrorJSON(xmlFragment: Y.XmlFragment): Record;
+ export function setMeta(view: any, key: any, value: any): void;
+-export function absolutePositionToRelativePosition(pos: number, type: Y.XmlFragment, mapping: ProsemirrorMapping): any;
+-export function relativePositionToAbsolutePosition(y: Y.Doc, documentType: Y.XmlFragment, relPos: any, mapping: ProsemirrorMapping): null | number;
++export function absolutePositionToRelativePosition(pos: number, type: Y.XmlFragment, pmDoc: Node, am?: AbstractAttributionManager): Y.RelativePosition;
++export function relativePositionToAbsolutePosition(y: Y.Doc, documentType: Y.XmlFragment, relPos: Y.RelativePosition, pmDoc: Node): null | number;
+ export function yXmlFragmentToProseMirrorFragment(yXmlFragment: Y.XmlFragment, schema: Schema): Fragment;
+ export function yXmlFragmentToProseMirrorRootNode(yXmlFragment: Y.XmlFragment, schema: Schema): Node;
+ export function initProseMirrorDoc(yXmlFragment: Y.XmlFragment, schema: Schema): {
+ doc: Node;
+- meta: import("./plugins/sync-plugin.js").BindingMetadata;
+- mapping: import("./plugins/sync-plugin.js").ProsemirrorMapping;
++ meta: import("./y-prosemirror.js").BindingMetadata;
++ mapping: import("./y-prosemirror.js").ProsemirrorMapping;
+ };
+ /**
+ * Either a node if type is YXmlElement or an Array of text nodes if YXmlText
+diff --git a/dist/src/plugins/cursor-plugin.d.ts b/dist/src/plugins/cursor-plugin.d.ts
+index 5f77005b9d72e5d383d1687149a57208c6ed29dd..1c8e49c6b2367258b6abb36ca1ae0e8d7460c1e3 100644
+--- a/dist/src/plugins/cursor-plugin.d.ts
++++ b/dist/src/plugins/cursor-plugin.d.ts
+@@ -9,9 +9,9 @@ export function createDecorations(state: any, awareness: Awareness, awarenessFil
+ color: string;
+ }, clientId: number) => import("prosemirror-view").DecorationAttrs): any;
+ export function yCursorPlugin(awareness: Awareness, { awarenessStateFilter, cursorBuilder, selectionBuilder, getSelection }?: {
+- awarenessStateFilter?: (arg0: any, arg1: any, arg2: any) => boolean;
+- cursorBuilder?: (user: any, clientId: number) => HTMLElement;
+- selectionBuilder?: (user: any, clientId: number) => import("prosemirror-view").DecorationAttrs;
+- getSelection?: (arg0: any) => any;
++ awarenessStateFilter?: ((arg0: any, arg1: any, arg2: any) => boolean) | undefined;
++ cursorBuilder?: ((user: any, clientId: number) => HTMLElement) | undefined;
++ selectionBuilder?: ((user: any, clientId: number) => import("prosemirror-view").DecorationAttrs) | undefined;
++ getSelection?: ((arg0: any) => any) | undefined;
+ }, cursorStateField?: string): any;
+ import { Awareness } from "@y/protocols/awareness";
+diff --git a/dist/src/plugins/keys.d.ts b/dist/src/plugins/keys.d.ts
+index adc3a2cfa3de8429977ec8d7a9df4e27291ec950..81a430061a5740faa3f6d06c8631b3cec9ec6182 100644
+--- a/dist/src/plugins/keys.d.ts
++++ b/dist/src/plugins/keys.d.ts
+@@ -2,11 +2,9 @@
+ * The unique prosemirror plugin key for syncPlugin
+ *
+ * @public
+- * @type {PluginKey<{ytype: Y.XmlFragment}>}
++ * @type {PluginKey}
+ */
+-export const ySyncPluginKey: PluginKey<{
+- ytype: Y.XmlFragment;
+-}>;
++export const ySyncPluginKey: PluginKey;
+ /**
+ * The unique prosemirror plugin key for undoPlugin
+ *
+diff --git a/dist/src/plugins/sync-plugin.d.ts b/dist/src/plugins/sync-plugin.d.ts
+index c4493907df56bb388838ff5032a27be72e5c1511..1fbfe677ccc7358bfff5e8aa6784ba4cd0ee04a4 100644
+--- a/dist/src/plugins/sync-plugin.d.ts
++++ b/dist/src/plugins/sync-plugin.d.ts
+@@ -3,8 +3,8 @@ export function isVisible(item: Y.Item, snapshot?: Y.Snapshot): boolean;
+ export function ySyncPlugin(yXmlFragment: Y.XmlFragment, { colors, colorMapping, permanentUserData, onFirstRender, mapping }?: YSyncOpts): any;
+ export function getRelativeSelection(pmbinding: ProsemirrorBinding, state: import("prosemirror-state").EditorState): {
+ type: any;
+- anchor: any;
+- head: any;
++ anchor: Y.RelativePosition;
++ head: Y.RelativePosition;
+ };
+ /**
+ * Binding for prosemirror.
+@@ -31,7 +31,7 @@ export class ProsemirrorBinding {
+ * @type {Map}
+ */
+ isOMark: Map;
+- _observeFunction: any;
++ _observeFunction: (events: Array>, transaction: Y.Transaction) => void;
+ /**
+ * @type {Y.Doc}
+ */
+@@ -41,19 +41,19 @@ export class ProsemirrorBinding {
+ */
+ beforeTransactionSelection: {
+ type: any;
+- anchor: any;
+- head: any;
+- };
++ anchor: Y.RelativePosition;
++ head: Y.RelativePosition;
++ } | null;
+ beforeAllTransactions: () => void;
+ afterAllTransactions: () => void;
+- _domSelectionInView: boolean;
++ _domSelectionInView: boolean | null;
+ /**
+ * Create a transaction for changing the prosemirror state.
+ *
+ * @returns
+ */
+ get _tr(): any;
+- _isLocalCursorInView(): boolean;
++ _isLocalCursorInView(): boolean | null;
+ _isDomSelectionInView(): boolean;
+ /**
+ * @param {Y.Snapshot} snapshot
+@@ -108,14 +108,14 @@ export type ColorDef = {
+ dark: string;
+ };
+ export type YSyncOpts = {
+- colors?: Array;
+- colorMapping?: Map;
++ colors?: ColorDef[] | undefined;
++ colorMapping?: Map | undefined;
+ permanentUserData?: Y.PermanentUserData | null;
+- mapping?: ProsemirrorMapping;
++ mapping?: ProsemirrorMapping | undefined;
+ /**
+ * Fired when the content from Yjs is initially rendered to ProseMirror
+ */
+- onFirstRender?: Function;
++ onFirstRender?: Function | undefined;
+ };
+ export type NormalizedPNodeContent = Array | PModel.Node>;
+ import * as Y from '@y/y';
+diff --git a/dist/src/plugins/undo-plugin.d.ts b/dist/src/plugins/undo-plugin.d.ts
+index 93cd6e77e5ee617f6e06f0f16508c7e3e3e9e1ea..39bfe0f489a633cc3dec073e7015b0e29aef268d 100644
+--- a/dist/src/plugins/undo-plugin.d.ts
++++ b/dist/src/plugins/undo-plugin.d.ts
+@@ -13,15 +13,10 @@ export const redoCommand: import("prosemirror-state").Command;
+ export const defaultProtectedNodes: Set;
+ export function defaultDeleteFilter(item: import("@y/y").Item, protectedNodes: Set): boolean;
+ export function yUndoPlugin({ protectedNodes, trackedOrigins, undoManager }?: {
+- protectedNodes?: Set;
+- trackedOrigins?: any[];
+- undoManager?: import("@y/y").UndoManager | null;
+-}): Plugin<{
+- undoManager: UndoManager;
+- prevSel: any;
+- hasUndoOps: boolean;
+- hasRedoOps: boolean;
+-}>;
++ protectedNodes?: Set | undefined;
++ trackedOrigins?: any[] | undefined;
++ undoManager?: UndoManager | null | undefined;
++}): Plugin;
+ export type UndoPluginState = {
+ undoManager: import("@y/y").UndoManager;
+ prevSel: ReturnType | null;
+diff --git a/dist/src/utils.d.ts b/dist/src/utils.d.ts
+index 9006a87dd42992dfe0aa0f7ab5298983deb3357a..72a018bc190726300cfe0b7a6c2f2a16a1912083 100644
+--- a/dist/src/utils.d.ts
++++ b/dist/src/utils.d.ts
+@@ -1 +1,12 @@
++/**
++ * To find a fragment in another ydoc, we need to search for it.
++ *
++ * @template {Y.AbstractType} T
++ * @param {T} ytype - The Yjs type to locate (should extend Y.AbstractType)
++ * @param {Y.Doc} otherYdoc - The target Y.Doc in which to find the equivalent type
++ * @returns {T} - The corresponding type instance in the other Yjs document
++ * @throws {Error} If ytype does not have a ydoc or can't be found in the other doc
++ */
++export function findTypeInOtherYdoc>(ytype: T, otherYdoc: Y.Doc): T;
+ export function hashOfJSON(json: any): string;
++import * as Y from '@y/y';
+diff --git a/dist/src/y-prosemirror.d.ts b/dist/src/y-prosemirror.d.ts
+index c1f9468c4c77434a1ad9f49227fb1274f5ae1915..d165eb9f524de1c8526502caae507c65c67665d4 100644
+--- a/dist/src/y-prosemirror.d.ts
++++ b/dist/src/y-prosemirror.d.ts
+@@ -1,5 +1,7 @@
+ export * from "./plugins/cursor-plugin.js";
+ export * from "./plugins/undo-plugin.js";
+ export * from "./plugins/keys.js";
+-export { ySyncPlugin, isVisible, getRelativeSelection, ProsemirrorBinding, updateYFragment } from "./plugins/sync-plugin.js";
++export * from "./index.js";
++export * from "./plugins/sync-plugin.js";
++export { findTypeInOtherYdoc } from "./utils.js";
+ export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, prosemirrorJSONToYDoc, yDocToProsemirrorJSON, yDocToProsemirror, prosemirrorToYDoc, prosemirrorJSONToYXmlFragment, yXmlFragmentToProsemirrorJSON, yXmlFragmentToProsemirror, prosemirrorToYXmlFragment, yXmlFragmentToProseMirrorRootNode, yXmlFragmentToProseMirrorFragment, initProseMirrorDoc } from "./lib.js";
+diff --git a/dist/y-prosemirror.cjs b/dist/y-prosemirror.cjs
+index 336dba34929063474acb211d065920823cfbc604..7f8a9f8998c6ffac0e1da46b684cf9245cb0e59c 100644
+--- a/dist/y-prosemirror.cjs
++++ b/dist/y-prosemirror.cjs
+@@ -4,7 +4,7 @@ var Y = require('@y/y');
+ var prosemirrorView = require('prosemirror-view');
+ var prosemirrorState = require('prosemirror-state');
+ require('@y/protocols/awareness');
+-var mutex = require('lib0/mutex');
++var mux = require('lib0/mutex');
+ var PModel = require('prosemirror-model');
+ var math = require('lib0/math');
+ var object = require('lib0/object');
+@@ -18,6 +18,9 @@ var eventloop = require('lib0/eventloop');
+ var map = require('lib0/map');
+ var sha256 = require('lib0/hash/sha256');
+ var buf = require('lib0/buffer');
++var delta = require('lib0/delta');
++var s = require('lib0/schema');
++var prosemirrorTransform = require('prosemirror-transform');
+
+ function _interopNamespaceDefault(e) {
+ var n = Object.create(null);
+@@ -37,6 +40,7 @@ function _interopNamespaceDefault(e) {
+ }
+
+ var Y__namespace = /*#__PURE__*/_interopNamespaceDefault(Y);
++var mux__namespace = /*#__PURE__*/_interopNamespaceDefault(mux);
+ var PModel__namespace = /*#__PURE__*/_interopNamespaceDefault(PModel);
+ var math__namespace = /*#__PURE__*/_interopNamespaceDefault(math);
+ var object__namespace = /*#__PURE__*/_interopNamespaceDefault(object);
+@@ -49,12 +53,14 @@ var eventloop__namespace = /*#__PURE__*/_interopNamespaceDefault(eventloop);
+ var map__namespace = /*#__PURE__*/_interopNamespaceDefault(map);
+ var sha256__namespace = /*#__PURE__*/_interopNamespaceDefault(sha256);
+ var buf__namespace = /*#__PURE__*/_interopNamespaceDefault(buf);
++var delta__namespace = /*#__PURE__*/_interopNamespaceDefault(delta);
++var s__namespace = /*#__PURE__*/_interopNamespaceDefault(s);
+
+ /**
+ * The unique prosemirror plugin key for syncPlugin
+ *
+ * @public
+- * @type {PluginKey<{ytype: Y.XmlFragment}>}
++ * @type {PluginKey}
+ */
+ const ySyncPluginKey = new prosemirrorState.PluginKey('y-sync');
+
+@@ -91,6 +97,51 @@ const _convolute = digest => {
+ */
+ const hashOfJSON = (json) => buf__namespace.toBase64(_convolute(sha256__namespace.digest(buf__namespace.encodeAny(json))));
+
++/**
++ * To find a fragment in another ydoc, we need to search for it.
++ *
++ * @template {Y.AbstractType} T
++ * @param {T} ytype - The Yjs type to locate (should extend Y.AbstractType)
++ * @param {Y.Doc} otherYdoc - The target Y.Doc in which to find the equivalent type
++ * @returns {T} - The corresponding type instance in the other Yjs document
++ * @throws {Error} If ytype does not have a ydoc or can't be found in the other doc
++ */
++function findTypeInOtherYdoc (ytype, otherYdoc) {
++ if (ytype.doc === otherYdoc) {
++ // fast-path, this is the same ydoc
++ return ytype
++ }
++ const ydoc = ytype.doc;
++ if (!ydoc) {
++ throw new Error('type does not have a ydoc')
++ }
++ if (ytype._item === null) {
++ // Root type case: find key in ydoc.share that matches ytype, then get from otherYdoc
++ const rootKey = Array.from(ydoc.share.keys()).find(
++ function (key) { return ydoc.share.get(key) === ytype }
++ );
++ if (rootKey == null) {
++ throw new Error('type does not exist')
++ }
++ // Use the ytype's constructor to get the type from the other document
++ return /** @type {T} */ (otherYdoc.get(rootKey, ytype.constructor))
++ } else {
++ // Subtype case: locate by item id via internals
++ const ytypeItem = ytype._item;
++ const otherStructs = otherYdoc.store.clients.get(ytypeItem.id.client) || [];
++ const itemIndex = Y__namespace.findIndexSS(otherStructs, ytypeItem.id.clock);
++ const otherItem = /** @type {Y.Item|undefined} */ (otherStructs[itemIndex]);
++ if (!otherItem) {
++ throw new Error('type does not exist in other ydoc')
++ }
++ const otherContent = /** @type {Y.ContentType|undefined} */ (otherItem.content);
++ if (!otherContent) {
++ throw new Error('type does not exist in other ydoc')
++ }
++ return /** @type {T} */ (otherContent.type)
++ }
++}
++
+ /**
+ * @module bindings/prosemirror
+ */
+@@ -387,7 +438,7 @@ class ProsemirrorBinding {
+ * @type {any}
+ */
+ this.prosemirrorView = null;
+- this.mux = mutex.createMutex();
++ this.mux = mux.createMutex();
+ this.mapping = mapping;
+ /**
+ * Is overlapping mark - i.e. mark does not exclude itself.
+@@ -1419,148 +1470,66 @@ const setMeta = (view, key, value) => {
+ *
+ * @param {number} pos
+ * @param {Y.XmlFragment} type
+- * @param {ProsemirrorMapping} mapping
+- * @return {any} relative position
++ * @param {Node} pmDoc
++ * @param {AbstractAttributionManager} am
++ * @return {Y.RelativePosition} relative position
+ */
+-const absolutePositionToRelativePosition = (pos, type, mapping) => {
++const absolutePositionToRelativePosition = (pos, type, pmDoc, am = Y__namespace.noAttributionsManager) => {
+ if (pos === 0) {
+ // if the type is later populated, we want to retain the 0 position (hence assoc=-1)
+- return Y__namespace.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0)
++ return Y__namespace.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0, am)
+ }
+- /**
+- * @type {any}
+- */
+- let n = type._first === null ? null : /** @type {Y.ContentType} */ (type._first.content).type;
+- while (n !== null && type !== n) {
+- if (n instanceof Y__namespace.XmlText) {
+- if (n._length >= pos) {
+- return Y__namespace.createRelativePositionFromTypeIndex(n, pos, type.length === 0 ? -1 : 0)
+- } else {
+- pos -= n._length;
+- }
+- if (n._item !== null && n._item.next !== null) {
+- n = /** @type {Y.ContentType} */ (n._item.next.content).type;
+- } else {
+- do {
+- n = n._item === null ? null : n._item.parent;
+- pos--;
+- } while (n !== type && n !== null && n._item !== null && n._item.next === null)
+- if (n !== null && n !== type) {
+- // @ts-gnore we know that n.next !== null because of above loop conditition
+- n = n._item === null ? null : /** @type {Y.ContentType} */ (/** @type Y.Item */ (n._item.next).content).type;
+- }
+- }
+- } else {
+- const pNodeSize = /** @type {any} */ (mapping.get(n) || { nodeSize: 0 }).nodeSize;
+- if (n._first !== null && pos < pNodeSize) {
+- n = /** @type {Y.ContentType} */ (n._first.content).type;
+- pos--;
+- } else {
+- if (pos === 1 && n._length === 0 && pNodeSize > 1) {
+- // edge case, should end in this paragraph
+- return new Y__namespace.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y__namespace.findRootTypeKey(n) : null, null)
+- }
+- pos -= pNodeSize;
+- if (n._item !== null && n._item.next !== null) {
+- n = /** @type {Y.ContentType} */ (n._item.next.content).type;
+- } else {
+- if (pos === 0) {
+- // set to end of n.parent
+- n = n._item === null ? n : n._item.parent;
+- return new Y__namespace.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y__namespace.findRootTypeKey(n) : null, null)
+- }
+- do {
+- n = /** @type {Y.Item} */ (n._item).parent;
+- pos--;
+- } while (n !== type && /** @type {Y.Item} */ (n._item).next === null)
+- // if n is null at this point, we have an unexpected case
+- if (n !== type) {
+- // We know that n._item.next is defined because of above loop condition
+- n = /** @type {Y.ContentType} */ (/** @type {Y.Item} */ (/** @type {Y.Item} */ (n._item).next).content).type;
+- }
+- }
+- }
+- }
+- if (n === null) {
+- throw error__namespace.unexpectedCase()
+- }
+- if (pos === 0 && n.constructor !== Y__namespace.XmlText && n !== type) { // TODO: set to <= 0
+- return createRelativePosition(n._item.parent, n._item)
+- }
++ const resolvedPos = pmDoc.resolve(pos);
++ const depth = resolvedPos.depth;
++ // Navigate through the Y.js structure using the path from ResolvedPos
++ let currentYType = type;
++ for (let d = 0; d < depth; d++) {
++ const childIndex = resolvedPos.index(d);
++ currentYType = currentYType.get(childIndex, am); // @todo get method should support attribution manager
+ }
+- return Y__namespace.createRelativePositionFromTypeIndex(type, type._length, type.length === 0 ? -1 : 0)
+-};
++ // Use the parent offset as the position within the target Y.js type
++ const offset = resolvedPos.parentOffset;
+
+-const createRelativePosition = (type, item) => {
+- let typeid = null;
+- let tname = null;
+- if (type._item === null) {
+- tname = Y__namespace.findRootTypeKey(type);
+- } else {
+- typeid = Y__namespace.createID(type._item.id.client, type._item.id.clock);
+- }
+- return new Y__namespace.RelativePosition(typeid, tname, item.id)
++ return Y__namespace.createRelativePositionFromTypeIndex(currentYType, offset,
++ // If we are at the end of a type, then we want to be associated to the end of the type
++ offset > 0 && offset === currentYType.length ? -1 : 0, am)
+ };
+
+ /**
+ * @param {Y.Doc} y
+ * @param {Y.XmlFragment} documentType Top level type that is bound to pView
+- * @param {any} relPos Encoded Yjs based relative position
+- * @param {ProsemirrorMapping} mapping
++ * @param {Y.RelativePosition} relPos Encoded Yjs based relative position
++ * @param {Node} pmDoc
+ * @return {null|number}
+ */
+-const relativePositionToAbsolutePosition = (y, documentType, relPos, mapping) => {
++const relativePositionToAbsolutePosition = (y, documentType, relPos, pmDoc) => {
++ // (1) decodedPos.index is the absolute position starting at the referred prosemirror node.
+ const decodedPos = Y__namespace.createAbsolutePositionFromRelativePosition(relPos, y);
+ if (decodedPos === null || (decodedPos.type !== documentType && !Y__namespace.isParentOf(documentType, decodedPos.type._item))) {
+ return null
+ }
+- let type = decodedPos.type;
+- let pos = 0;
+- if (type.constructor === Y__namespace.XmlText) {
+- pos = decodedPos.index;
+- } else if (type._item === null || !type._item.deleted) {
+- let n = type._first;
+- let i = 0;
+- while (i < type._length && i < decodedPos.index && n !== null) {
+- if (!n.deleted) {
+- const t = /** @type {Y.ContentType} */ (n.content).type;
+- i++;
+- if (t instanceof Y__namespace.XmlText) {
+- pos += t._length;
+- } else {
+- pos += /** @type {any} */ (mapping.get(t)).nodeSize;
+- }
+- }
+- n = /** @type {Y.Item} */ (n.right);
+- }
+- pos += 1; // increase because we go out of n
+- }
+- while (type !== documentType && type._item !== null) {
+- // @ts-ignore
+- const parent = type._item.parent;
+- // @ts-ignore
+- if (parent._item === null || !parent._item.deleted) {
+- pos += 1; // the start tag
+- let n = /** @type {Y.AbstractType} */ (parent)._first;
+- // now iterate until we found type
+- while (n !== null) {
+- const contentType = /** @type {Y.ContentType} */ (n.content).type;
+- if (contentType === type) {
+- break
+- }
+- if (!n.deleted) {
+- if (contentType instanceof Y__namespace.XmlText) {
+- pos += contentType._length;
+- } else {
+- pos += /** @type {any} */ (mapping.get(contentType)).nodeSize;
+- }
+- }
+- n = n.right;
+- }
++ /*
++ * Now, we need to compute the nested position.
++ * - Compute the path of the targeted type Y.getPathTo(decodedPos.type).
++ * - (2) Use that path to calculate the absolute prosemirror position based on the prosemirror state.
++ * result = (1) + (2)
++ */
++ const path = Y__namespace.getPathTo(documentType, decodedPos.type);
++ let pos = 1; // Start inside the document
++ let currentNode = pmDoc;
++ // Traverse the path to find the nested position
++ for (let i = 0; i < path.length; i++) {
++ const childIndex = path[i];
++ // Add sizes of all previous siblings
++ for (let j = 0; j < childIndex; j++) {
++ pos += currentNode.child(j).nodeSize;
+ }
+- type = /** @type {Y.AbstractType} */ (parent);
++ // enter node
++ pos += 1;
++ currentNode = currentNode.child(childIndex);
+ }
+- return pos - 1 // we don't count the most outer tag, because it is a fragment
++ // Add the offset within the target node
++ return pos + decodedPos.index
+ };
+
+ /**
+@@ -2185,17 +2154,1408 @@ const yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins =
+ }
+ });
+
++const $prosemirrorDelta = delta__namespace.$delta({ name: s__namespace.$string, attrs: s__namespace.$record(s__namespace.$string, s__namespace.$any), text: true, recursive: true });
++
++/**
++ * @typedef {s.Unwrap<$prosemirrorDelta>} ProsemirrorDelta
++ * @typedef {import('./types').SyncPluginMode} SyncPluginMode
++ * @typedef {import('./types').YSyncPluginMeta} YSyncPluginMeta
++ * @typedef {import('./types').SnapshotItem} SnapshotItem
++ * @typedef {import('./types').InitializeCallback} InitializeCallback
++ */
++
++// y-attribution-deletion & y-attribution-insertion & y-attribution-format (or mod?)
++// add attributes (userId: string[], timestamp: number) (see `YAttribution` (ask Kevin))
++// define how an insertion mark works on a node
++// situations like deleted node, yet has inserted content (handle nested content)
++// insertion within a node that was inserted + another user inserted more content into that node (hovers per user likely)
++
++/**
++ * @template {import('lib0/delta').Attribution} T
++ * @param {Record | null} format
++ * @param {T} attribution
++ * @returns {Record | null}
++ */
++const defaultMapAttributionToMark = (format, attribution) => {
++ /**
++ * @type {Record | null}
++ */
++ let mergeWith = null;
++ if (attribution.insert) {
++ mergeWith = {
++ 'y-attribution-insertion': {
++ userIds: attribution.insert ? attribution.insert : null,
++ timestamp: attribution.insertAt ? attribution.insertAt : null
++ }
++ };
++ } else if (attribution.delete) {
++ mergeWith = {
++ 'y-attribution-deletion': {
++ userIds: attribution.delete ? attribution.delete : null,
++ timestamp: attribution.deleteAt ? attribution.deleteAt : null
++ }
++ };
++ } else if (attribution.format) {
++ mergeWith = {
++ 'y-attribution-format': {
++ userIdsByAttr: attribution.format ? attribution.format : null,
++ timestamp: attribution.formatAt ? attribution.formatAt : null
++ }
++ };
++ }
++ return object__namespace.assign({}, format, mergeWith)
++};
++
++/**
++ * We prefer checking that the prosemirror document is empty, since most people will sync the ydoc later
++ * @type {InitializeCallback}
++ */
++const defaultInitializeCallback = ({ yjs, pm }) => {
++ if (yjs.hasContent) {
++ // Ydoc has content, so we can directly start with the ydoc content
++ yjs.apply();
++ return
++ }
++
++ if (pm.hasContent) {
++ // Your prosemirror editor has a non-empty document, yet the ydoc is empty
++ // This is a potential issue, applying the prosemirror document in this state may cause duplicated content
++ // If you want to get rid of this warning, then you should either:
++ // 1. Not set an initial prosemirror document
++ // 2. Load the ydoc content before initializing the prosemirror editor, in-which case duplicate content will be avoided, and this error can be ignored
++ // 3. Implement your own initialization callback, and handle this however you want
++ console.warn('[y/prosemirror]: prosemirror has content, but ydoc is empty, refusing to initialize the editor');
++ }
++};
++
++/**
++ * Transform delta with attributions to delta with formats (marks).
++ */
++const deltaAttributionToFormat = s__namespace.match(s__namespace.$function)
++ .if(delta__namespace.$deltaAny, (d, func) => {
++ const r = delta__namespace.create(d.name);
++ for (const attr of d.attrs) {
++ r.attrs[attr.key] = attr.clone();
++ }
++ for (const child of d.children) {
++ const format = child.attribution ? func(child.format, child.attribution) : child.format;
++ if (delta__namespace.$insertOp.check(child)) {
++ r.insert(child.insert.map(c => delta__namespace.$deltaAny.check(c) ? deltaAttributionToFormat(c, func) : c), format);
++ } else if (delta__namespace.$textOp.check(child)) {
++ r.insert(child.insert.slice(), format);
++ } else if (delta__namespace.$deleteOp.check(child)) {
++ r.delete(child.delete);
++ } else if (delta__namespace.$retainOp.check(child)) {
++ r.retain(child.retain, format);
++ } else if (delta__namespace.$modifyOp.check(child)) {
++ r.modify(deltaAttributionToFormat(child.value, func), format);
++ } else {
++ error__namespace.unexpectedCase();
++ }
++ }
++ return r
++ }).done();
++
++/**
++ * This class is the state of the sync plugin, it is essentially the public API for the sync plugin
++ */
++class SyncPluginState {
++ /**
++ * @type {Y.DiffAttributionManager}
++ */
++ #attributionManager
++
++ /**
++ * @type {Y.Doc | null}
++ */
++ #suggestionDoc = null
++
++ /**
++ * @type {Y.Doc}
++ */
++ #contentDoc = null
++
++ /**
++ * @type {typeof defaultMapAttributionToMark}
++ */
++ #mapAttributionToMark
++
++ /**
++ * @type {import('prosemirror-view').EditorView | null}
++ */
++ #view = null
++
++ /**
++ * This is the subscription to the ydoc changes
++ * @type {null | (() => void)}
++ */
++ #subscription = null
++
++ /**
++ * Get the view that the sync plugin is attached to
++ * @returns {import('prosemirror-view').EditorView}
++ * @private
++ */
++ get view () {
++ if (!this.#view) {
++ throw new Error('[y/prosemirror]: view not set')
++ }
++ return this.#view
++ }
++
++ #mutex = mux__namespace.createMutex()
++
++ /**
++ * @type {SyncPluginMode}
++ */
++ #state
++
++ /**
++ * @param {object} ctx
++ * @param {Y.XmlFragment} ctx.ytype
++ * @param {Y.DiffAttributionManager} [ctx.attributionManager]
++ * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]
++ * @param {Y.Doc} [ctx.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking
++ * @param {Y.Doc} ctx.contentDoc A {@link Y.Doc} to use for content tracking
++ */
++ constructor ({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc }) {
++ if (!ytype || !ytype.doc) {
++ throw new Error('[y/prosemirror]: ytype not provided')
++ }
++ this.#attributionManager = attributionManager || Y__namespace.noAttributionsManager;
++ this.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ ytype,
++ showSuggestions: false
++ };
++ this.#mapAttributionToMark = mapAttributionToMark || defaultMapAttributionToMark;
++ this.#suggestionDoc = suggestionDoc || null;
++ this.#contentDoc = contentDoc;
++ }
++
++ /**
++ * This takes a prosemirror transaction and attempts to update the internal plugin state
++ * @param {import('prosemirror-state').Transaction} tr
++ * @returns {SyncPluginState}
++ * @private
++ */
++ onApplyTr (tr) {
++ /** @type {YSyncPluginMeta | undefined} */
++ const pluginMeta = tr.getMeta(ySyncPluginKey);
++ if (!pluginMeta) {
++ return this
++ }
++
++ const nextState = this.#clone();
++ switch (pluginMeta.type) {
++ /**
++ * For an ideal prosemirror binding, we should only commit the state once the view has been updated to the new editor state
++ * Technically, there can be a number of editor state transitions between, but we only care about the state that gets committed to the view
++ * So:
++ * 1. we capture the transactions that are local-updates, in `appendTransaction`
++ * 2. when state.apply(tr) is called, we generate a delta of the changes that we captured (merging any other states we found between such as additional appendTransaction plugins)
++ * 3. when view.updateState(state) is called, we then synchronize that delta back to the ytype to sync the changes to peers
++ *
++ * This allows the sync plugin to be in any order within the prosemirror plugins array, since it will be committed once the view's state has been applied
++ */
++ case 'local-update':{
++ if (this.#state.type !== 'sync' && this.#state.type !== 'paused') {
++ // No-op since we are not in sync mode
++ return this
++ }
++
++ const { capturedTransactions } = pluginMeta;
++
++ // We queue up local-updates by merging all of the transactions that have been captured
++ const transform = new prosemirrorTransform.Transform(capturedTransactions[0].before);
++
++ for (let i = 0; i < capturedTransactions.length; i++) {
++ for (let j = 0; j < capturedTransactions[i].steps.length; j++) {
++ const success = transform.maybeStep(capturedTransactions[i].steps[j]);
++ if (success.failed) {
++ // step failed, fallback to full diff
++ console.error('[y/prosemirror]: step failed to apply, falling back to a full diff');
++
++ const nextDelta = docDiffToDelta(capturedTransactions[0].before, capturedTransactions[capturedTransactions.length - 1].after);
++ // TODO what should the right behavior here be?
++ nextState.#state = {
++ type: this.#state.type,
++ pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions,
++ contentDocSnapshot: this.#state.contentDocSnapshot
++ };
++ return nextState
++ }
++ }
++ }
++ // Then trying to derive the delta that they represent
++ const nextDelta = trToDelta(transform);
++
++ // And, either applying that delta to the already pendingDelta, or promoting that delta to being the next pending delta
++ nextState.#state = {
++ type: this.#state.type,
++ ytype: this.#state.ytype,
++ pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,
++ showSuggestions: this.#state.showSuggestions,
++ contentDocSnapshot: this.#state.contentDocSnapshot
++ };
++ return nextState
++ }
++ case 'render-snapshot':{
++ nextState.#state = {
++ type: 'snapshot',
++ snapshot: pluginMeta.snapshot,
++ prevSnapshot: pluginMeta.prevSnapshot,
++ pendingDelta: null,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ };
++ return nextState
++ }
++ case 'resume-sync': {
++ // Move back to sync mode
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ };
++ return nextState
++ }
++ case 'pause-sync':{
++ // Move to paused mode
++ nextState.#state = {
++ type: 'paused',
++ pendingDelta: null,
++ snapshot: Y__namespace.snapshot(this.#contentDoc),
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ };
++
++ return nextState
++ }
++ case 'show-suggestions':{
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ // switch to the suggestion doc
++ ytype: findTypeInOtherYdoc(this.#state.ytype, this.#suggestionDoc),
++ showSuggestions: true
++ };
++
++ return nextState
++ }
++ case 'hide-suggestions':{
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ // switch to the content doc
++ ytype: findTypeInOtherYdoc(this.#state.ytype, this.#contentDoc),
++ showSuggestions: false
++ };
++ return nextState
++ }
++ }
++
++ return this
++ }
++
++ /**
++ * This will be `true` if the plugin state is initialized and the view is not destroyed
++ */
++ get initialized () {
++ return this.#view && !this.#view.isDestroyed
++ }
++
++ /**
++ * Apply any pending diffs to the ytype
++ * @param {import('prosemirror-state').EditorState} prevState
++ * @private
++ */
++ onViewUpdate (prevState) {
++ if (!this.initialized) {
++ return
++ }
++ const prevPluginState = ySyncPluginKey.getState(prevState);
++ switch (this.#state.type) {
++ case 'snapshot':{
++ if (prevPluginState.#state.type === 'snapshot') {
++ // Already in snapshot mode, so we don't need to do anything
++ return
++ }
++ // Just transitioned from another mode, so we need to actually apply the snapshot mode
++
++ // Stop observing the ydoc changes, since we are looking at a snapshot in time
++ this.destroy();
++ return
++ }
++ case 'sync':{
++ if (this.#state.showSuggestions !== prevPluginState.#state.showSuggestions) {
++ // We are entering/leaving suggestion mode, so we need to subscribe to the suggestion doc
++ // stop observing the ytype
++ this.destroy();
++ // subscribe to the suggestion doc
++ this.#subscribeToYType();
++ return
++ }
++ if (prevPluginState.#state.type === 'paused' || prevPluginState.#state.type === 'snapshot') {
++ // was just paused, so we need to resume sync
++
++ // Restart the observer for two-way sync again
++ this.#subscribeToYType();
++ return
++ }
++ if (!this.#state.pendingDelta) {
++ return
++ }
++ this.#mutex(() => {
++ const d = this.#state.pendingDelta;
++ // clear the delta so that we don't accidentally apply it again
++ this.#state.pendingDelta = null;
++
++ this.#state.ytype.doc.transact(() => {
++ // If the ytype has not yet been initialized
++ if (this.#state.ytype.length === 0) {
++ // Apply the previous prosemirror document to the ytype, so that the pending delta can operate on the correct content
++ pmToFragment(prevState.doc, this.#state.ytype, {
++ attributionManager: this.#state.showSuggestions ? this.#attributionManager : Y__namespace.noAttributionsManager
++ });
++ }
++ this.#state.ytype.applyDelta(d, this.#attributionManager);
++ }, ySyncPluginKey);
++ });
++
++ return undefined
++ }
++ }
++ }
++
++ /**
++ * @type {ReturnType | undefined}
++ */
++ #initializationTimeoutId = undefined
++
++ /**
++ * Initialize the plugin state with the view
++ * @note this will start the synchronization of the prosemirror state with the ydoc
++ * @param {import('prosemirror-view').EditorView} view
++ * @param {InitializeCallback} [onInitialize]
++ * @private
++ */
++ init (view, onInitialize) {
++ // initialize the prosemirror state with what is in the ydoc
++ // we wait a tick, because in some cases, the view can be immediately destroyed
++ this.#initializationTimeoutId = setTimeout(() => {
++ // clear the timeout id
++ this.#initializationTimeoutId = undefined;
++ // Only set the view if we've passed a tick
++ // This gates the initialization of the plugin state until the view is ready
++ this.#view = view;
++
++ onInitialize({
++ yjs: {
++ ytype: this.#state.ytype,
++ get hasContent () {
++ return this.ytype.length !== 0
++ },
++ apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {
++ const tr = this.#renderFragment({
++ fragment: this.#state.ytype,
++ showSuggestions: false
++ });
++
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'initialized',
++ ytype: this.#state.ytype
++ };
++ tr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(tr);
++ }
++ },
++ pm: {
++ doc: view.state.doc,
++ get hasContent () {
++ return view.state.doc.content.findDiffStart(
++ view.state.doc.type.createAndFill().content
++ ) !== null
++ },
++ apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {
++ this.#state.ytype.doc.transact(() => {
++ pmToFragment(view.state.doc, this.#state.ytype, {
++ attributionManager: showSuggestions ? this.#attributionManager : Y__namespace.noAttributionsManager
++ });
++ }, ySyncPluginKey);
++ }
++ }
++ });
++
++ // subscribe to the ydoc changes, after initialization is complete
++ this.#subscribeToYType();
++ }, 0);
++ }
++
++ /**
++ * Subscribe to the ydoc changes, and register a cleanup function to unsubscribe when the view is destroyed
++ * @private
++ */
++ #subscribeToYType () {
++ if (!this.#view) {
++ throw new Error('[y/prosemirror]: view not set')
++ }
++
++ if (this.#subscription) {
++ // re-use the existing subscription, since it operates on the latest plugin state
++ return
++ }
++ const attrCb = this.#attributionManager.on('change', (changes) => {
++ if (this.#state.ytype.doc !== this.#suggestionDoc) {
++ // this should not happen
++ console.info('tried to update attributions, but suggestion doc is not active. The diffing attribution manager should not be active when no diff is created - use the "noAttributionManager instead');
++ return
++ }
++ /**
++ * @type {Map>}
++ */
++ const modified = new Map();
++ this.#suggestionDoc.transact(tr => {
++ Y__namespace.iterateStructsByIdSet(tr, changes, item => {
++ map__namespace.setIfUndefined(modified, item.parent, () => new Set()).add(item.parentSub);
++ });
++ });
++ const d = this.#state.ytype.getContent(this.#attributionManager, { modified, itemsToRender: changes, retainInserts: true, retainDeletes: true, deep: true });
++ console.log('delta update by attribution manager', d.toJSON());
++ const tr = deltaToPSteps(this.#tr, d);
++ console.log('transaction', tr);
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'attribution-fixup',
++ changes
++ };
++ tr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(tr);
++ });
++ // This stores whether the ytype has loaded any content yet
++ // If it has not, then we need to apply changes to it slightly differently in #onChangeYType
++ let isYTypeInitialized = !!this.#state.ytype.length;
++ // This is the callback that we will subscribe & unsubscribe to the ydoc changes
++ const yTypeCb = this.#state.ytype.observeDeep((evt, tr) => {
++ if (!this.#view || this.#view.isDestroyed) {
++ // view is destroyed, just clean up the subscription, and no-op
++ this.#subscription();
++ return
++ }
++
++ // fetch the latest plugin state
++ const pluginState = ySyncPluginKey.getState(this.#view.state);
++ if (!pluginState) {
++ throw new Error('[y/prosemirror]: plugin state not found in view.state')
++ }
++
++ // call the onYTypeEvent handler on that instance
++ pluginState.#onChangeYType(evt, tr, isYTypeInitialized);
++ // We got an event, so the ytype should now be initialized
++ isYTypeInitialized = true;
++ });
++
++ this.#subscription = () => {
++ this.#subscription = null;
++ this.#state.ytype.unobserveDeep(yTypeCb);
++ this.#attributionManager.off('change', attrCb);
++ };
++ }
++
++ /**
++ * Destroy the plugin state
++ * @note this will stop the synchronization of the prosemirror state with the ydoc
++ * @private
++ */
++ destroy () {
++ // clear the initialization timeout
++ clearTimeout(this.#initializationTimeoutId);
++ if (this.#subscription) {
++ // unsubscribe from the ydoc changes
++ this.#subscription();
++ this.#subscription = null;
++ }
++ }
++
++ /**
++ * This is the event handler for when the ytype changes, applying remote changes to the editor content
++ * @note this must be a stable reference to be unobserved later
++ * @param {Array>} events
++ * @param {Y.Transaction} tr
++ * @param {boolean} isYTypeInitialized Whether the ytype has already been initialized
++ */
++ #onChangeYType (events, tr, isYTypeInitialized) {
++ // bail if: the view is destroyed OR we are not in "sync" mode
++ if (!this.initialized || this.#state.type !== 'sync') {
++ return
++ }
++
++ this.#mutex(() => {
++ /**
++ * @type {Y.YEvent}
++ */
++ const event = events.find(event => event.target === this.#state.ytype) || new Y__namespace.YEvent(this.#state.ytype, tr, new Set(null));
++ let d = deltaAttributionToFormat(event.getDelta(this.#state.showSuggestions ? this.#attributionManager : Y__namespace.noAttributionsManager, { deep: true }), this.#mapAttributionToMark).done();
++
++ if (!isYTypeInitialized) {
++ // Here is the sequence of events:
++ // 1. The prosemirror document is empty (e.g. )
++ // 2. The ytype is empty
++ // 3. We get an update, which describes the document as
Hello, world!
++ // If we apply the delta directly, then the prosemirror document will be
Hello, world!
, which is incorrect
++ // What we actually want is for this case to act as a full-document replace
++ // so, we actually diff the prosemirror document with the delta, to get the correct changes
++ d = delta__namespace.diff(nodeToDelta(this.#view.state.doc).done(), d);
++ }
++ const ptr = deltaToPSteps(this.#view.state.tr, d);
++
++ ptr.setMeta(ySyncPluginKey, { ytypeEvent: true });
++ this.#view.dispatch(ptr);
++ }, () => {
++ if (this.#attributionManager === Y__namespace.noAttributionsManager) {
++ // no attribution fixup needed
++ return
++ }
++ const itemsToRender = Y__namespace.mergeIdSets([tr.insertSet, tr.deleteSet]);
++ /**
++ * @todo this could be automatically be calculated in getContent/getDelta when
++ * itemsToRender is provided
++ * @type {Map>}
++ */
++ const modified = new Map();
++ Y__namespace.iterateStructsByIdSet(tr, itemsToRender, item => {
++ while (item instanceof Y__namespace.Item) {
++ const parent = /** @type {Y.AbstractType} */ (item.parent);
++ const conf = map__namespace.setIfUndefined(modified, parent, set__namespace.create);
++ if (conf.has(item.parentSub)) break // has already been marked as modified
++ conf.add(item.parentSub);
++ item = parent._item;
++ }
++ });
++
++ if (modified.has(this.#state.ytype)) {
++ setTimeout(() => {
++ this.#mutex(() => {
++ if (this.#state.type !== 'sync') {
++ error__namespace.unexpectedCase();
++ }
++ const d = deltaAttributionToFormat(this.#state.ytype.getContent(this.#state.showSuggestions ? this.#attributionManager : Y__namespace.noAttributionsManager, {
++ itemsToRender,
++ retainInserts: true,
++ deep: true,
++ modified
++ }), this.#mapAttributionToMark);
++ const ptr = deltaToPSteps(this.#tr, d);
++ console.log('attribution fix event: ', d.toJSON(), 'and applied changes to pm', ptr.steps);
++
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'remote-update',
++ events,
++ ytype: this.#state.ytype,
++ attributionFix: true
++ };
++ ptr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(ptr);
++ });
++ }, 0);
++ }
++ });
++ }
++
++ /**
++ * Create a transaction for changing the prosemirror state.
++ * @private
++ */
++ get #tr () {
++ return this.view.state.tr.setMeta('addToHistory', false)
++ }
++
++ /**
++ * Pause the synchronization of the prosemirror state with the ydoc
++ */
++ pauseSync () {
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'pause-sync'
++ };
++ this.view.dispatch(this.#tr.setMeta(ySyncPluginKey, pluginMeta));
++ }
++
++ /**
++ * Resume the synchronization of the prosemirror state with the ydoc
++ * @param {object} [opts]
++ * @param {boolean} [opts.keepChanges]
++ */
++ resumeSync ({ keepChanges = false } = {}) {
++ if (this.#state.type === 'sync') {
++ // Already in sync mode, so we don't need to do anything
++ return
++ }
++
++ // This will apply the changes that were made while paused to the ytype
++ if (keepChanges && this.#state.type === 'paused' && this.#state.pendingDelta) {
++ // We use a snapshot to get the document state at the point in time when the sync was paused (it may have accrued updates since then)
++ // A nice property of using only a snapshot like this is that it is relatively cheap to create, and a copy is only needed if we actually want to keep the changes
++ const docAtSnapshotTime = Y__namespace.createDocFromSnapshot(this.#state.ytype.doc, this.#state.snapshot);
++ const ytypeAtSnapshotTime = findTypeInOtherYdoc(this.#state.ytype, docAtSnapshotTime);
++ // We setup a listener to apply any updates which occur to the snapshot doc, to the main ydoc
++ docAtSnapshotTime.on('updateV2', (update) => {
++ // Apply that diff as an update to the main ydoc
++ Y__namespace.applyUpdateV2(this.#state.ytype.doc, update, ySyncPluginKey);
++ });
++ // Actually apply the changes accrued while paused to the ytype
++ ytypeAtSnapshotTime.applyDelta(this.#state.pendingDelta, this.#attributionManager);
++ docAtSnapshotTime.destroy();
++ }
++
++ // Take whatever is in the ytype now, and make that the new document state
++ const tr = this.#renderFragment();
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'resume-sync'
++ };
++ tr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Get the mode that the sync plugin is in
++ */
++ get mode () {
++ return this.#state.type
++ }
++
++ /**
++ * Get the ytype that the sync plugin is using
++ */
++ get ytype () {
++ return this.#state.ytype
++ }
++
++ /**
++ * @param {SnapshotItem} snapshot
++ * @param {SnapshotItem} [prevSnapshot]
++ * @param {Y.Attribution[]} [attrs]
++ */
++ renderSnapshot (snapshot, prevSnapshot, attrs) {
++ if (!prevSnapshot) {
++ prevSnapshot = { fragment: snapshot.fragment };
++ }
++ const snapshotDoc = snapshot.snapshot ? Y__namespace.createDocFromSnapshot(snapshot.fragment.doc, snapshot.snapshot) : snapshot.fragment.doc;
++ const prevSnapshotDoc = prevSnapshot.snapshot ? Y__namespace.createDocFromSnapshot(prevSnapshot.fragment.doc, prevSnapshot.snapshot) : prevSnapshot.fragment.doc;
++ const am = Y__namespace.createAttributionManagerFromDiff(prevSnapshotDoc, snapshotDoc, { attrs });
++ const tr = this.#renderFragment({
++ fragment: findTypeInOtherYdoc(snapshot.fragment, snapshotDoc),
++ attributionManager: am,
++ showSuggestions: true
++ });
++
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'render-snapshot',
++ snapshot,
++ prevSnapshot
++ };
++ tr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Set the suggestion mode
++ * @param {'off' | 'view' | 'edit'} mode
++ * -
++ * - 'off': Hide suggestions, edit original document
++ * - 'view': Show suggestions, edit original document
++ * - 'edit': Show suggestions, edits become suggestions
++ */
++ setSuggestionMode (mode) {
++ if (this.#state.type !== 'sync') {
++ // not in sync mode, so we don't need to do anything
++ return
++ }
++ console.log('setting suggestion mode to', mode);
++
++ const showSuggestions = mode !== 'off';
++ const suggestionMode = mode === 'edit';
++
++ let switchedToSuggestionMode = false;
++ if (suggestionMode !== this.#attributionManager.suggestionMode) {
++ this.#attributionManager.suggestionMode = suggestionMode;
++ switchedToSuggestionMode = true;
++ }
++
++ if (this.#state.showSuggestions === showSuggestions && !switchedToSuggestionMode) {
++ // already in the desired suggestion mode & did not switch to a different suggestion mode
++ return
++ }
++
++ const tr = this.#renderFragment({
++ showSuggestions
++ });
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: showSuggestions ? 'show-suggestions' : 'hide-suggestions'
++ };
++ tr.setMeta(ySyncPluginKey, pluginMeta);
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Accept all changes in the suggestion doc
++ */
++ acceptAllChanges () {
++ if (!this.#state.showSuggestions) {
++ // not in suggestion mode, so we don't need to do anything
++ return
++ }
++ this.#attributionManager.acceptAllChanges();
++ const tr = this.#renderFragment();
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Reject all changes in the suggestion doc
++ */
++ rejectAllChanges () {
++ if (!this.#state.showSuggestions) {
++ // not in suggestion mode, so we don't need to do anything
++ return
++ }
++ this.#attributionManager.rejectAllChanges();
++ const tr = this.#renderFragment();
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Accept the changes within the given range
++ * @note This will move the content from the suggestion doc into the content doc, so this requires permissions to write to the content doc
++ * @param {number} from
++ * @param {number} [to]
++ */
++ acceptChanges (from, to = from) {
++ if (!this.#state.showSuggestions) {
++ // not in suggestion mode, so we don't need to do anything
++ return
++ }
++ if (from > to) {
++ // swap the from and to positions
++ [from, to] = [to, from];
++ }
++ const fromRel = absolutePositionToRelativePosition(from, this.#state.ytype, this.#view.state.doc, this.#attributionManager);
++ const toRel = from === to ? fromRel : absolutePositionToRelativePosition(to, this.#state.ytype, this.#view.state.doc, this.#attributionManager);
++
++ if (!fromRel.item && !toRel.item) {
++ throw new Error('Invalid relative position')
++ }
++ // TODO move this to be in the state.apply
++ this.#attributionManager.acceptChanges(fromRel.item, toRel.item);
++ const tr = this.#renderFragment();
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Reject the changes within the given range
++ * @note This will remove the content from the suggestion doc, so that it no longer appears in the editor
++ * @param {number} from
++ * @param {number} [to]
++ */
++ rejectChanges (from, to) {
++ if (!this.#state.showSuggestions) {
++ // not in suggestion mode, so we don't need to do anything
++ return
++ }
++ if (from > to) {
++ // swap the from and to positions
++ [from, to] = [to, from];
++ }
++ const fromRel = absolutePositionToRelativePosition(from, this.#state.ytype, this.#view.state.doc, this.#attributionManager);
++ const toRel = from === to ? fromRel : absolutePositionToRelativePosition(to, this.#state.ytype, this.#view.state.doc, this.#attributionManager);
++
++ if (!fromRel.item || !toRel.item) {
++ throw new Error('Invalid relative position')
++ }
++
++ // TODO move this to be in the state.apply
++ this.#attributionManager.rejectChanges(fromRel.item, toRel.item);
++ const tr = this.#renderFragment();
++ this.view.dispatch(tr);
++ }
++
++ /**
++ * Replaces the current prosemirror document with the content of the given ytype
++ * @param {object} ctx
++ * @param {Y.XmlFragment} [ctx.fragment] The ytype to render
++ * @param {boolean} [ctx.showSuggestions] Whether to show suggestions
++ * @param {import('prosemirror-state').Transaction} [ctx.tr]
++ */
++ #renderFragment ({
++ showSuggestions = this.#state.showSuggestions,
++ // from the current XMLFragment, get the type in the suggestion doc or content doc, depending on the showSuggestions flag
++ fragment = findTypeInOtherYdoc(this.#state.ytype, showSuggestions ? this.#suggestionDoc : this.#contentDoc),
++ tr = this.#tr,
++ attributionManager = this.#attributionManager
++ } = {}) {
++ return fragmentToTr(fragment, tr, {
++ attributionManager: showSuggestions ? attributionManager : Y__namespace.noAttributionsManager,
++ mapAttributionToMark: this.#mapAttributionToMark
++ })
++ }
++
++ /**
++ * Clone the {@link SyncPluginState} instance, this allows us to compare the current state with the previous state without mutating the current state
++ * @private
++ */
++ #clone () {
++ const pluginState = new SyncPluginState({
++ ytype: this.#state.ytype,
++ attributionManager: this.#attributionManager,
++ mapAttributionToMark: this.#mapAttributionToMark,
++ suggestionDoc: this.#suggestionDoc,
++ contentDoc: this.#contentDoc
++ });
++
++ pluginState.#state = this.#state;
++ pluginState.#mutex = this.#mutex;
++ pluginState.#view = this.#view;
++ pluginState.#initializationTimeoutId = this.#initializationTimeoutId;
++ // We can safely clone the subscription, because it will always operate on the latest plugin state, rather than being bound to the one that created it
++ pluginState.#subscription = this.#subscription;
++
++ return pluginState
++ }
++}
++
++// The sync plugin is built a bit strangely, what it does at a high level is:
++// 1. It captures transactions within `appendTransaction` (creating a transaction that carries metadata about the transactions that were captured)
++// 2. It accrues these changes in the SyncPluginState on state.apply
++// 3. When view.update occurs, it can finally apply the accrued changes to the ytype
++// It is built this way because it allows for EditorStates to be created (even ephemeral ones) without having to worry about accidentally committing changes to the ytype.
++// In Prosemirror, appendTransaction is expected to be a pure function of the current state & the incoming transactions.
++// If this is not the case, then interactions with other plugins may be buggy, since they may apply changes to the ytype that were not intended to be committed.
++// This has the nice side effect of allowing the sync plugin to be installed to the prosemirror plugins array in any order, since it will be committed once the view's state has been applied
++// It also allows for a nice separation of concerns, where the view.update is the final point at which changes can be committed to the ytype. (Rather than across potentially multiple appendTransaction calls)
++
++/**
++ * This Prosemirror {@link Plugin} is responsible for synchronizing the prosemirror {@link EditorState} with a {@link Y.XmlFragment}
++ * @param {Y.XmlFragment} ytype
++ * @param {object} opts
++ * @param {Y.DiffAttributionManager} [opts.attributionManager] An {@link Y.DiffAttributionManager} to use for attribution tracking
++ * @param {Y.Doc} [opts.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking
++ * @param {typeof defaultMapAttributionToMark} [opts.mapAttributionToMark] A function to map the {@link Y.Attribution} to a {@link import('prosemirror-model').Mark}
++ * @param {InitializeCallback} [opts.initialize] This callback is called on initialization and is meant to be used to initialize the editor's state or initialize the ydoc content
++ * @returns {Plugin}
++ */
++function syncPlugin (ytype, {
++ attributionManager = Y__namespace.noAttributionsManager,
++ mapAttributionToMark = defaultMapAttributionToMark,
++ suggestionDoc,
++ onInitialize = defaultInitializeCallback
++} = {}) {
++ return new prosemirrorState.Plugin({
++ key: ySyncPluginKey,
++ props: {
++ // Disables editing if we are in snapshot mode
++ editable: (state) => {
++ const pluginState = ySyncPluginKey.getState(state);
++ return pluginState?.mode !== 'snapshot'
++ }
++ },
++ state: {
++ init () {
++ return new SyncPluginState({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc: ytype.doc })
++ },
++ apply (tr, value) {
++ return value.onApplyTr(tr)
++ }
++ },
++ view (view) {
++ const pluginState = ySyncPluginKey.getState(view.state);
++
++ if (!pluginState) {
++ throw new Error('[y/prosemirror]: plugin state not found in view.state')
++ }
++
++ pluginState.init(view, onInitialize);
++
++ return {
++ update (view, prevState) {
++ const pluginState = ySyncPluginKey.getState(view.state);
++ if (!pluginState) {
++ throw new Error('[y/prosemirror]: plugin state not found in view.state')
++ }
++ pluginState.onViewUpdate(prevState);
++ },
++ destroy () {
++ const pluginState = ySyncPluginKey.getState(view.state);
++ if (!pluginState) {
++ throw new Error('[y/prosemirror]: plugin state not found in view.state')
++ }
++ pluginState.destroy();
++ }
++ }
++ },
++ // Capture any local updates to the prosemirror state, later we will use them to generate a delta to apply to the ydoc
++ appendTransaction (transactions, _oldState, newState) {
++ transactions = transactions.filter(tr => tr.docChanged && !tr.getMeta(ySyncPluginKey));
++ if (transactions.length === 0) return undefined
++
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'local-update',
++ capturedTransactions: transactions
++ };
++ return newState.tr.setMeta(ySyncPluginKey, pluginMeta).setMeta('addToHistory', false)
++ }
++ })
++}
++
++/**
++ * @param {readonly import('prosemirror-model').Mark[]} marks
++ */
++const marksToFormattingAttributes = marks => {
++ if (marks.length === 0) return null
++ /**
++ * @type {{[key:string]:any}}
++ */
++ const formatting = {};
++ marks.forEach(mark => {
++ formatting[mark.type.name] = mark.attrs;
++ });
++ return formatting
++};
++
++/**
++ * @param {{[key:string]:any}} formatting
++ * @param {import('prosemirror-model').Schema} schema
++ */
++const formattingAttributesToMarks = (formatting, schema) => object__namespace.map(formatting, (v, k) => schema.mark(k, v));
++
++/**
++ * @param {Array} ns
++ */
++const nodesToDelta = ns => {
++ /**
++ * @type {delta.DeltaBuilderAny}
++ */
++ const d = delta__namespace.create($prosemirrorDelta);
++ ns.forEach(n => {
++ d.insert(n.isText ? n.text : [nodeToDelta(n)], marksToFormattingAttributes(n.marks));
++ });
++ return d
++};
++
++/**
++ * Transforms a {@link Node} into a {@link Y.XmlFragment}
++ * @param {Node} node
++ * @param {Y.XmlFragment} fragment
++ * @param {Object} [opts]
++ * @param {Y.DiffAttributionManager} [opts.attributionManager]
++ * @returns {Y.XmlFragment}
++ */
++function pmToFragment (node, fragment, { attributionManager = Y__namespace.noAttributionsManager } = {}) {
++ const initialPDelta = nodeToDelta(node).done();
++ fragment.applyDelta(initialPDelta, attributionManager);
++
++ return fragment
++}
++
++/**
++ * Applies a {@link Y.XmlFragment}'s content as a ProseMirror {@link Transaction}
++ * @param {Y.XmlFragment} fragment
++ * @param {import('prosemirror-state').Transaction} tr
++ * @param {object} [ctx]
++ * @param {Y.DiffAttributionManager} [ctx.attributionManager]
++ * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]
++ * @returns {import('prosemirror-state').Transaction}
++ */
++function fragmentToTr (fragment, tr, {
++ attributionManager = Y__namespace.noAttributionsManager,
++ mapAttributionToMark = defaultMapAttributionToMark
++}) {
++ const fragmentContent = deltaAttributionToFormat(
++ fragment.getContent(attributionManager, { deep: true }),
++ mapAttributionToMark
++ );
++ const initialPDelta = nodeToDelta(tr.doc).done();
++ const deltaBetweenPmAndFragment = delta__namespace.diff(initialPDelta, fragmentContent).done();
++ console.log({
++ am: attributionManager === Y__namespace.noAttributionsManager ? 'no attributions manager' : 'attributions manager',
++ a: initialPDelta.toJSON(),
++ b: fragmentContent.toJSON(),
++ c: deltaBetweenPmAndFragment.toJSON()
++ });
++
++ return deltaToPSteps(tr, deltaBetweenPmAndFragment).setMeta('y-sync-hydration', {
++ delta: deltaBetweenPmAndFragment
++ })
++}
++
++/**
++ * Transforms a {@link Y.XmlFragment} into a {@link Node}
++ * @param {Y.XmlFragment} fragment
++ * @param {import('prosemirror-state').Transaction}
++ * @returns {Node}
++ */
++function fragmentToPm (fragment, tr) {
++ return fragmentToTr(fragment, tr).doc
++}
++
++/**
++ * @param {Node} n
++ */
++const nodeToDelta = n => {
++ /**
++ * @type {delta.DeltaBuilderAny}
++ */
++ const d = delta__namespace.create(n.type.name, $prosemirrorDelta);
++ d.setMany(n.attrs);
++ n.content.content.forEach(c => {
++ d.insert(c.isText ? c.text : [nodeToDelta(c)], marksToFormattingAttributes(c.marks));
++ });
++ return d
++};
++
++/**
++ * @param {import('prosemirror-transform').Transform} tr
++ * @param {ProsemirrorDelta} d
++ * @param {Node} [pnode]
++ * @param {{ i: number }} [currPos]
++ * @return {import('prosemirror-transform').Transform}
++ */
++const deltaToPSteps = (tr, d, pnode = tr.doc, currPos = { i: 0 }) => {
++ const schema = tr.doc.type.schema;
++ let currParentIndex = 0;
++ let nOffset = 0;
++ const pchildren = pnode.children;
++ for (const attr of d.attrs) {
++ tr.setNodeAttribute(currPos.i - 1, attr.key, attr.value);
++ }
++ d.children.forEach(op => {
++ if (delta__namespace.$retainOp.check(op)) {
++ // skip over i children
++ let i = op.retain;
++ while (i > 0) {
++ const pc = pchildren[currParentIndex];
++ if (pc === undefined) {
++ throw new Error('[y/prosemirror]: retain operation is out of bounds')
++ }
++ if (pc.isText) {
++ if (op.format != null) {
++ const from = currPos.i;
++ const to = currPos.i + math__namespace.min(pc.nodeSize - nOffset, i);
++ object__namespace.forEach(op.format, (v, k) => {
++ if (v == null) {
++ tr.removeMark(from, to, schema.marks[k]);
++ } else {
++ tr.addMark(from, to, schema.mark(k, v));
++ }
++ });
++ }
++ if (i + nOffset < pc.nodeSize) {
++ nOffset += i;
++ currPos.i += i;
++ i = 0;
++ } else {
++ currParentIndex++;
++ i -= pc.nodeSize - nOffset;
++ currPos.i += pc.nodeSize - nOffset;
++ nOffset = 0;
++ }
++ } else {
++ object__namespace.forEach(op.format, (v, k) => {
++ if (v == null) {
++ tr.removeNodeMark(currPos.i, schema.marks[k]);
++ } else {
++ // TODO see schema.js for more info on marking nodes
++ tr.addNodeMark(currPos.i, schema.mark(k, v));
++ }
++ });
++ currParentIndex++;
++ currPos.i += pc.nodeSize;
++ i--;
++ }
++ }
++ } else if (delta__namespace.$modifyOp.check(op)) {
++ currPos.i++;
++ deltaToPSteps(tr, op.value, pchildren[currParentIndex++], currPos);
++ currPos.i++;
++ } else if (delta__namespace.$insertOp.check(op)) {
++ const newPChildren = op.insert.map(ins => deltaToPNode(ins, schema, op.format));
++ tr.insert(currPos.i, newPChildren);
++ currPos.i += newPChildren.reduce((s, c) => c.nodeSize + s, 0);
++ } else if (delta__namespace.$textOp.check(op)) {
++ tr.insert(currPos.i, schema.text(op.insert, formattingAttributesToMarks(op.format, schema)));
++ currPos.i += op.length;
++ } else if (delta__namespace.$deleteOp.check(op)) {
++ for (let remainingDelLen = op.delete; remainingDelLen > 0;) {
++ const pc = pchildren[currParentIndex];
++ if (pc === undefined) {
++ throw new Error('[y/prosemirror]: delete operation is out of bounds')
++ }
++ if (pc.isText) {
++ const delLen = math__namespace.min(pc.nodeSize - nOffset, remainingDelLen);
++ tr.delete(currPos.i, currPos.i + delLen);
++ nOffset += delLen;
++ if (nOffset === pc.nodeSize) {
++ // TODO this can't actually "jump out" of the current node
++ // jump to next node
++ nOffset = 0;
++ currParentIndex++;
++ }
++ remainingDelLen -= delLen;
++ } else {
++ tr.delete(currPos.i, currPos.i + pc.nodeSize);
++ currParentIndex++;
++ remainingDelLen--;
++ }
++ }
++ }
++ });
++ return tr
++};
++
++/**
++ * @param {ProsemirrorDelta} d
++ * @param {import('prosemirror-model').Schema} schema
++ * @param {delta.FormattingAttributes} dformat
++ * @return {Node}
++ */
++const deltaToPNode = (d, schema, dformat) => {
++ const attrs = {};
++ for (const attr of d.attrs) {
++ attrs[attr.key] = attr.value;
++ }
++ const dc = d.children.map(c => delta__namespace.$insertOp.check(c) ? c.insert.map(cn => deltaToPNode(cn, schema, c.format)) : (delta__namespace.$textOp.check(c) ? [schema.text(c.insert, formattingAttributesToMarks(c.format, schema))] : []));
++ return schema.node(d.name, attrs, dc.flat(1), formattingAttributesToMarks(dformat, schema))
++};
++
++/**
++ * @param {Node} beforeDoc
++ * @param {Node} afterDoc
++ */
++const docDiffToDelta = (beforeDoc, afterDoc) => {
++ const initialDelta = nodeToDelta(beforeDoc);
++ const finalDelta = nodeToDelta(afterDoc);
++
++ return delta__namespace.diff(initialDelta.done(), finalDelta.done())
++};
++
++/**
++ * @param {Transform} tr
++ */
++const trToDelta = (tr) => {
++ // const d = delta.create($prosemirrorDelta)
++ // tr.steps.forEach((step, i) => {
++ // const stepDelta = stepToDelta(step, tr.docs[i])
++ // console.log('stepDelta', JSON.stringify(stepDelta.toJSON(), null, 2))
++ // console.log('d', JSON.stringify(d.toJSON(), null, 2))
++ // d.apply(stepDelta)
++ // })
++ // return d.done()
++ // Calculate delta from initial and final document states to avoid composition issues with delete operations
++ // This is more reliable than composing step-by-step, which can lose delete operations and cause "Unexpected case" errors
++ // after lib0 upgrades that change delta composition behavior
++ const initialDelta = nodeToDelta(tr.before);
++ const finalDelta = nodeToDelta(tr.doc);
++ const resultDelta = delta__namespace.diff(initialDelta.done(), finalDelta.done());
++ return resultDelta
++};
++
++const _stepToDelta = s__namespace.match({ beforeDoc: PModel.Node, afterDoc: PModel.Node })
++ .if([prosemirrorTransform.ReplaceStep, prosemirrorTransform.ReplaceAroundStep], (step, { beforeDoc, afterDoc }) => {
++ const oldStart = beforeDoc.resolve(step.from);
++ const oldEnd = beforeDoc.resolve(step.to);
++ const newStart = afterDoc.resolve(step.from);
++
++ const newEnd = afterDoc.resolve(step instanceof prosemirrorTransform.ReplaceAroundStep ? step.getMap().map(step.to) : step.from + step.slice.size);
++
++ const oldBlockRange = oldStart.blockRange(oldEnd);
++ const newBlockRange = newStart.blockRange(newEnd);
++ const oldDelta = deltaForBlockRange(oldBlockRange);
++ const newDelta = deltaForBlockRange(newBlockRange);
++ const diffD = delta__namespace.diff(oldDelta, newDelta);
++ const stepDelta = deltaModifyNodeAt(beforeDoc, oldBlockRange?.start || newBlockRange?.start || 0, d => { d.append(diffD); });
++ return stepDelta
++ })
++ .if(prosemirrorTransform.AddMarkStep, (step, { beforeDoc }) =>
++ deltaModifyNodeAt(beforeDoc, step.from, d => { d.retain(step.to - step.from, marksToFormattingAttributes([step.mark])); })
++ )
++ .if(prosemirrorTransform.AddNodeMarkStep, (step, { beforeDoc }) =>
++ deltaModifyNodeAt(beforeDoc, step.pos, d => { d.retain(1, marksToFormattingAttributes([step.mark])); })
++ )
++ .if(prosemirrorTransform.RemoveMarkStep, (step, { beforeDoc }) =>
++ deltaModifyNodeAt(beforeDoc, step.from, d => { d.retain(step.to - step.from, { [step.mark.type.name]: null }); })
++ )
++ .if(prosemirrorTransform.RemoveNodeMarkStep, (step, { beforeDoc }) =>
++ deltaModifyNodeAt(beforeDoc, step.pos, d => { d.retain(1, { [step.mark.type.name]: null }); })
++ )
++ .if(prosemirrorTransform.AttrStep, (step, { beforeDoc }) =>
++ deltaModifyNodeAt(beforeDoc, step.pos, d => { d.modify(delta__namespace.create().set(step.attr, step.value)); })
++ )
++ .if(prosemirrorTransform.DocAttrStep, step =>
++ delta__namespace.create().set(step.attr, step.value)
++ )
++ .else(_step => {
++ // unknown step kind
++ error__namespace.unexpectedCase();
++ })
++ .done();
++
++/**
++ * @param {import('prosemirror-transform').Step} step
++ * @param {import('prosemirror-model').Node} beforeDoc
++ * @return {ProsemirrorDelta}
++ */
++const stepToDelta = (step, beforeDoc) => {
++ const stepResult = step.apply(beforeDoc);
++ if (stepResult.failed) {
++ throw new Error('[y/prosemirror]: step failed to apply')
++ }
++ return _stepToDelta(step, { beforeDoc, afterDoc: stepResult.doc })
++};
++
++/**
++ *
++ * @param {import('prosemirror-model').NodeRange | null} blockRange
++ */
++function deltaForBlockRange (blockRange) {
++ if (blockRange === null) {
++ return delta__namespace.create()
++ }
++ const { startIndex, endIndex, parent } = blockRange;
++ return nodesToDelta(parent.content.content.slice(startIndex, endIndex))
++}
++
++/**
++ * This function is used to find the delta offset for a given prosemirror offset in a node.
++ * Given the following document:
++ *
Hello world
Hello world!
++ * The delta structure would look like this:
++ * 0: p
++ * - 0: text("Hello world")
++ * 1: blockquote
++ * - 0: p
++ * - 0: text("Hello world!")
++ * So the prosemirror position 10 would be within the delta offset path: 0, 0 and have an offset into the text node of 9 (since it is the 9th character in the text node).
++ *
++ * So the return value would be [0, 9], which is the path of: p, text("Hello wor")
++ *
++ * @param {Node} node
++ * @param {number} searchPmOffset The p offset to find the delta offset for
++ * @return {number[]} The delta offset path for the search pm offset
++ */
++function pmToDeltaPath (node, searchPmOffset = 0) {
++ if (searchPmOffset === 0) {
++ // base case
++ return [0]
++ }
++
++ const resolvedOffset = node.resolve(searchPmOffset);
++ const depth = resolvedOffset.depth;
++ const path = [];
++ if (depth === 0) {
++ // if the offset is at the root node, return the index of the node
++ return [resolvedOffset.index(0)]
++ }
++ // otherwise, add the index of each parent node to the path
++ for (let d = 0; d < depth; d++) {
++ path.push(resolvedOffset.index(d));
++ }
++
++ // add any offset into the parent node to the path
++ path.push(resolvedOffset.parentOffset);
++
++ return path
++}
++
++/**
++ * Inverse of {@link pmToDeltaPath}
++ * @param {number[]} deltaPath
++ * @param {Node} node
++ * @return {number} The prosemirror offset for the delta path
++ */
++function deltaPathToPm (deltaPath, node) {
++ let pmOffset = 0;
++ let curNode = node;
++
++ // Special case: if path has only one element, it's a child index at depth 0
++ if (deltaPath.length === 1) {
++ const childIndex = deltaPath[0];
++ // Add sizes of all children before the target index
++ for (let j = 0; j < childIndex; j++) {
++ pmOffset += curNode.children[j].nodeSize;
++ }
++ return pmOffset
++ }
++
++ // Handle all elements except the last (which is an offset)
++ for (let i = 0; i < deltaPath.length - 1; i++) {
++ const childIndex = deltaPath[i];
++ // Add sizes of all children before the target child
++ for (let j = 0; j < childIndex; j++) {
++ pmOffset += curNode.children[j].nodeSize;
++ }
++ // Add 1 for the opening tag of the target child, then navigate into it
++ pmOffset += 1;
++ curNode = curNode.children[childIndex];
++ }
++
++ // Last element is an offset within the current node
++ pmOffset += deltaPath[deltaPath.length - 1];
++
++ return pmOffset
++}
++
++/**
++ * @param {Node} node
++ * @param {number} pmOffset
++ * @param {(d:delta.DeltaBuilderAny)=>any} mod
++ * @return {ProsemirrorDelta}
++ */
++const deltaModifyNodeAt = (node, pmOffset, mod) => {
++ const dpath = pmToDeltaPath(node, pmOffset);
++ let currentOp = delta__namespace.create($prosemirrorDelta);
++ const lastIndex = dpath.length - 1;
++ currentOp.retain(lastIndex >= 0 ? dpath[lastIndex] : 0);
++ mod(currentOp);
++ for (let i = lastIndex - 1; i >= 0; i--) {
++ currentOp = /** @type {delta.DeltaBuilderAny} */ (delta__namespace.create($prosemirrorDelta).retain(dpath[i]).modify(currentOp));
++ }
++ return currentOp
++};
++
+ exports.ProsemirrorBinding = ProsemirrorBinding;
++exports.SyncPluginState = SyncPluginState;
+ exports.absolutePositionToRelativePosition = absolutePositionToRelativePosition;
++exports.attributesToMarks = attributesToMarks;
+ exports.createDecorations = createDecorations;
++exports.createEmptyMeta = createEmptyMeta;
++exports.createNodeFromYElement = createNodeFromYElement;
+ exports.defaultAwarenessStateFilter = defaultAwarenessStateFilter;
+ exports.defaultCursorBuilder = defaultCursorBuilder;
+ exports.defaultDeleteFilter = defaultDeleteFilter;
+ exports.defaultProtectedNodes = defaultProtectedNodes;
+ exports.defaultSelectionBuilder = defaultSelectionBuilder;
++exports.deltaModifyNodeAt = deltaModifyNodeAt;
++exports.deltaPathToPm = deltaPathToPm;
++exports.deltaToPSteps = deltaToPSteps;
++exports.docDiffToDelta = docDiffToDelta;
++exports.findTypeInOtherYdoc = findTypeInOtherYdoc;
++exports.fragmentToPm = fragmentToPm;
++exports.fragmentToTr = fragmentToTr;
+ exports.getRelativeSelection = getRelativeSelection;
+ exports.initProseMirrorDoc = initProseMirrorDoc;
+ exports.isVisible = isVisible;
++exports.nodeToDelta = nodeToDelta;
++exports.nodesToDelta = nodesToDelta;
++exports.pmToDeltaPath = pmToDeltaPath;
++exports.pmToFragment = pmToFragment;
+ exports.prosemirrorJSONToYDoc = prosemirrorJSONToYDoc;
+ exports.prosemirrorJSONToYXmlFragment = prosemirrorJSONToYXmlFragment;
+ exports.prosemirrorToYDoc = prosemirrorToYDoc;
+@@ -2204,6 +3564,9 @@ exports.redo = redo;
+ exports.redoCommand = redoCommand;
+ exports.relativePositionToAbsolutePosition = relativePositionToAbsolutePosition;
+ exports.setMeta = setMeta;
++exports.stepToDelta = stepToDelta;
++exports.syncPlugin = syncPlugin;
++exports.trToDelta = trToDelta;
+ exports.undo = undo;
+ exports.undoCommand = undoCommand;
+ exports.updateYFragment = updateYFragment;
+@@ -2219,4 +3582,5 @@ exports.yXmlFragmentToProseMirrorFragment = yXmlFragmentToProseMirrorFragment;
+ exports.yXmlFragmentToProseMirrorRootNode = yXmlFragmentToProseMirrorRootNode;
+ exports.yXmlFragmentToProsemirror = yXmlFragmentToProsemirror;
+ exports.yXmlFragmentToProsemirrorJSON = yXmlFragmentToProsemirrorJSON;
++exports.yattr2markname = yattr2markname;
+ //# sourceMappingURL=y-prosemirror.cjs.map
+diff --git a/dist/y-prosemirror.cjs.map b/dist/y-prosemirror.cjs.map
+index 61b864629455150ac073bf6a9e5b7f6f7e9e5037..e7f7efc2b1e9e8a26f73e10be530343d0039e892 100644
+--- a/dist/y-prosemirror.cjs.map
++++ b/dist/y-prosemirror.cjs.map
+@@ -1 +1 @@
+-{"version":3,"file":"y-prosemirror.cjs","sources":["../src/plugins/keys.js","../src/utils.js","../src/plugins/sync-plugin.js","../src/lib.js","../src/plugins/cursor-plugin.js","../src/plugins/undo-plugin.js"],"sourcesContent":["import { PluginKey } from 'prosemirror-state' // eslint-disable-line\n\n/**\n * The unique prosemirror plugin key for syncPlugin\n *\n * @public\n * @type {PluginKey<{ytype: Y.XmlFragment}>}\n */\nexport const ySyncPluginKey = new PluginKey('y-sync')\n\n/**\n * The unique prosemirror plugin key for undoPlugin\n *\n * @public\n * @type {PluginKey}\n */\nexport const yUndoPluginKey = new PluginKey('y-undo')\n\n/**\n * The unique prosemirror plugin key for cursorPlugin\n *\n * @public\n */\nexport const yCursorPluginKey = new PluginKey('yjs-cursor')\n","import * as sha256 from 'lib0/hash/sha256'\nimport * as buf from 'lib0/buffer'\n\n/**\n * Custom function to transform sha256 hash to N byte\n *\n * @param {Uint8Array} digest\n */\nconst _convolute = digest => {\n const N = 6\n for (let i = N; i < digest.length; i++) {\n digest[i % N] = digest[i % N] ^ digest[i]\n }\n return digest.slice(0, N)\n}\n\n/**\n * @param {any} json\n */\nexport const hashOfJSON = (json) => buf.toBase64(_convolute(sha256.digest(buf.encodeAny(json))))\n","/**\n * @module bindings/prosemirror\n */\n\nimport { createMutex } from 'lib0/mutex'\nimport * as PModel from 'prosemirror-model'\nimport { AllSelection, Plugin, TextSelection, NodeSelection } from \"prosemirror-state\"; // eslint-disable-line\nimport * as math from 'lib0/math'\nimport * as object from 'lib0/object'\nimport * as set from 'lib0/set'\nimport { simpleDiff } from 'lib0/diff'\nimport * as error from 'lib0/error'\nimport { ySyncPluginKey, yUndoPluginKey } from './keys.js'\nimport * as Y from '@y/y'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition\n} from '../lib.js'\nimport * as random from 'lib0/random'\nimport * as environment from 'lib0/environment'\nimport * as dom from 'lib0/dom'\nimport * as eventloop from 'lib0/eventloop'\nimport * as map from 'lib0/map'\nimport * as utils from '../utils.js'\n\n/**\n * @typedef {Object} BindingMetadata\n * @property {ProsemirrorMapping} BindingMetadata.mapping\n * @property {Map} BindingMetadata.isOMark - is overlapping mark\n */\n\n/**\n * @return {BindingMetadata}\n */\nexport const createEmptyMeta = () => ({\n mapping: new Map(),\n isOMark: new Map()\n})\n\n/**\n * @param {Y.Item} item\n * @param {Y.Snapshot} [snapshot]\n */\nexport const isVisible = (item, snapshot) =>\n snapshot === undefined\n ? !item.deleted\n : (snapshot.sv.has(item.id.client) && /** @type {number} */\n (snapshot.sv.get(item.id.client)) > item.id.clock &&\n !snapshot.ds.hasId(item.id))\n\n/**\n * Either a node if type is YXmlElement or an Array of text nodes if YXmlText\n * @typedef {Map, PModel.Node | Array>} ProsemirrorMapping\n */\n\n/**\n * @typedef {Object} ColorDef\n * @property {string} ColorDef.light\n * @property {string} ColorDef.dark\n */\n\n/**\n * @typedef {Object} YSyncOpts\n * @property {Array} [YSyncOpts.colors]\n * @property {Map} [YSyncOpts.colorMapping]\n * @property {Y.PermanentUserData|null} [YSyncOpts.permanentUserData]\n * @property {ProsemirrorMapping} [YSyncOpts.mapping]\n * @property {function} [YSyncOpts.onFirstRender] Fired when the content from Yjs is initially rendered to ProseMirror\n */\n\n/**\n * @type {Array}\n */\nconst defaultColors = [{ light: '#ecd44433', dark: '#ecd444' }]\n\n/**\n * @param {Map} colorMapping\n * @param {Array} colors\n * @param {string} user\n * @return {ColorDef}\n */\nconst getUserColor = (colorMapping, colors, user) => {\n // @todo do not hit the same color twice if possible\n if (!colorMapping.has(user)) {\n if (colorMapping.size < colors.length) {\n const usedColors = set.create()\n colorMapping.forEach((color) => usedColors.add(color))\n colors = colors.filter((color) => !usedColors.has(color))\n }\n colorMapping.set(user, random.oneOf(colors))\n }\n return /** @type {ColorDef} */ (colorMapping.get(user))\n}\n\n/**\n * This plugin listens to changes in prosemirror view and keeps yXmlState and view in sync.\n *\n * This plugin also keeps references to the type and the shared document so other plugins can access it.\n * @param {Y.XmlFragment} yXmlFragment\n * @param {YSyncOpts} opts\n * @return {any} Returns a prosemirror plugin that binds to this type\n */\nexport const ySyncPlugin = (yXmlFragment, {\n colors = defaultColors,\n colorMapping = new Map(),\n permanentUserData = null,\n onFirstRender = () => {},\n mapping\n} = {}) => {\n let initialContentChanged = false\n const binding = new ProsemirrorBinding(yXmlFragment, mapping)\n const plugin = new Plugin({\n props: {\n editable: (state) => {\n const syncState = ySyncPluginKey.getState(state)\n return syncState.snapshot == null && syncState.prevSnapshot == null\n }\n },\n key: ySyncPluginKey,\n state: {\n /**\n * @returns {any}\n */\n init: (_initargs, _state) => {\n return {\n type: yXmlFragment,\n doc: yXmlFragment.doc,\n binding,\n snapshot: null,\n prevSnapshot: null,\n isChangeOrigin: false,\n isUndoRedoOperation: false,\n addToHistory: true,\n colors,\n colorMapping,\n permanentUserData\n }\n },\n apply: (tr, pluginState) => {\n const change = tr.getMeta(ySyncPluginKey)\n if (change !== undefined) {\n pluginState = Object.assign({}, pluginState)\n for (const key in change) {\n pluginState[key] = change[key]\n }\n }\n pluginState.addToHistory = tr.getMeta('addToHistory') !== false\n // always set isChangeOrigin. If undefined, this is not change origin.\n pluginState.isChangeOrigin = change !== undefined &&\n !!change.isChangeOrigin\n pluginState.isUndoRedoOperation = change !== undefined && !!change.isChangeOrigin && !!change.isUndoRedoOperation\n if (binding.prosemirrorView !== null) {\n if (\n change !== undefined &&\n (change.snapshot != null || change.prevSnapshot != null)\n ) {\n // snapshot changed, rerender next\n eventloop.timeout(0, () => {\n if (binding.prosemirrorView == null) {\n return\n }\n if (change.restore == null) {\n binding._renderSnapshot(\n change.snapshot,\n change.prevSnapshot,\n pluginState\n )\n } else {\n binding._renderSnapshot(\n change.snapshot,\n change.snapshot,\n pluginState\n )\n // reset to current prosemirror state\n delete pluginState.restore\n delete pluginState.snapshot\n delete pluginState.prevSnapshot\n binding.mux(() => {\n binding._prosemirrorChanged(\n binding.prosemirrorView.state.doc\n )\n })\n }\n })\n }\n }\n return pluginState\n }\n },\n view: (view) => {\n binding.initView(view)\n if (mapping == null) {\n // force rerender to update the bindings mapping\n binding._forceRerender()\n }\n onFirstRender()\n return {\n update: () => {\n const pluginState = plugin.getState(view.state)\n if (\n pluginState.snapshot == null && pluginState.prevSnapshot == null\n ) {\n if (\n // If the content doesn't change initially, we don't render anything to Yjs\n // If the content was cleared by a user action, we want to catch the change and\n // represent it in Yjs\n initialContentChanged ||\n view.state.doc.content.findDiffStart(\n view.state.doc.type.createAndFill().content\n ) !== null\n ) {\n initialContentChanged = true\n if (\n pluginState.addToHistory === false &&\n !pluginState.isChangeOrigin\n ) {\n const yUndoPluginState = yUndoPluginKey.getState(view.state)\n /**\n * @type {Y.UndoManager}\n */\n const um = yUndoPluginState && yUndoPluginState.undoManager\n if (um) {\n um.stopCapturing()\n }\n }\n binding.mux(() => {\n /** @type {Y.Doc} */ (pluginState.doc).transact((tr) => {\n tr.meta.set('addToHistory', pluginState.addToHistory)\n binding._prosemirrorChanged(view.state.doc)\n }, ySyncPluginKey)\n })\n }\n }\n },\n destroy: () => {\n binding.destroy()\n }\n }\n }\n })\n return plugin\n}\n\n/**\n * @param {import('prosemirror-state').Transaction} tr\n * @param {ReturnType} relSel\n * @param {ProsemirrorBinding} binding\n */\nconst restoreRelativeSelection = (tr, relSel, binding) => {\n if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {\n if (relSel.type === 'all') {\n tr.setSelection(new AllSelection(tr.doc))\n } else if (relSel.type === 'node') {\n const anchor = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.anchor,\n binding.mapping\n )\n tr.setSelection(NodeSelection.create(tr.doc, anchor))\n } else {\n const anchor = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.anchor,\n binding.mapping\n )\n const head = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.head,\n binding.mapping\n )\n if (anchor !== null && head !== null) {\n const sel = TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head))\n tr.setSelection(sel)\n }\n }\n }\n}\n\n/**\n * @param {ProsemirrorBinding} pmbinding\n * @param {import('prosemirror-state').EditorState} state\n */\nexport const getRelativeSelection = (pmbinding, state) => ({\n type: /** @type {any} */ (state.selection).jsonID,\n anchor: absolutePositionToRelativePosition(\n state.selection.anchor,\n pmbinding.type,\n pmbinding.mapping\n ),\n head: absolutePositionToRelativePosition(\n state.selection.head,\n pmbinding.type,\n pmbinding.mapping\n )\n})\n\n/**\n * Binding for prosemirror.\n *\n * @protected\n */\nexport class ProsemirrorBinding {\n /**\n * @param {Y.XmlFragment} yXmlFragment The bind source\n * @param {ProsemirrorMapping} mapping\n */\n constructor (yXmlFragment, mapping = new Map()) {\n this.type = yXmlFragment\n /**\n * this will be set once the view is created\n * @type {any}\n */\n this.prosemirrorView = null\n this.mux = createMutex()\n this.mapping = mapping\n /**\n * Is overlapping mark - i.e. mark does not exclude itself.\n *\n * @type {Map}\n */\n this.isOMark = new Map()\n this._observeFunction = this._typeChanged.bind(this)\n /**\n * @type {Y.Doc}\n */\n // @ts-ignore\n this.doc = yXmlFragment.doc\n /**\n * current selection as relative positions in the Yjs model\n */\n this.beforeTransactionSelection = null\n this.beforeAllTransactions = () => {\n if (this.beforeTransactionSelection === null && this.prosemirrorView != null) {\n this.beforeTransactionSelection = getRelativeSelection(\n this,\n this.prosemirrorView.state\n )\n }\n }\n this.afterAllTransactions = () => {\n this.beforeTransactionSelection = null\n }\n this._domSelectionInView = null\n }\n\n /**\n * Create a transaction for changing the prosemirror state.\n *\n * @returns\n */\n get _tr () {\n return this.prosemirrorView.state.tr.setMeta('addToHistory', false)\n }\n\n _isLocalCursorInView () {\n if (!this.prosemirrorView.hasFocus()) return false\n if (environment.isBrowser && this._domSelectionInView === null) {\n // Calculate the domSelectionInView and clear by next tick after all events are finished\n eventloop.timeout(0, () => {\n this._domSelectionInView = null\n })\n this._domSelectionInView = this._isDomSelectionInView()\n }\n return this._domSelectionInView\n }\n\n _isDomSelectionInView () {\n const selection = this.prosemirrorView._root.getSelection()\n\n if (selection == null || selection.anchorNode == null) return false\n\n const range = this.prosemirrorView._root.createRange()\n range.setStart(selection.anchorNode, selection.anchorOffset)\n range.setEnd(selection.focusNode, selection.focusOffset)\n\n // This is a workaround for an edgecase where getBoundingClientRect will\n // return zero values if the selection is collapsed at the start of a newline\n // see reference here: https://stackoverflow.com/a/59780954\n const rects = range.getClientRects()\n if (rects.length === 0) {\n // probably buggy newline behavior, explicitly select the node contents\n if (range.startContainer && range.collapsed) {\n range.selectNodeContents(range.startContainer)\n }\n }\n\n const bounding = range.getBoundingClientRect()\n const documentElement = dom.doc.documentElement\n\n return bounding.bottom >= 0 && bounding.right >= 0 &&\n bounding.left <=\n (window.innerWidth || documentElement.clientWidth || 0) &&\n bounding.top <= (window.innerHeight || documentElement.clientHeight || 0)\n }\n\n /**\n * @param {Y.Snapshot} snapshot\n * @param {Y.Snapshot} prevSnapshot\n */\n renderSnapshot (snapshot, prevSnapshot) {\n if (!prevSnapshot) {\n prevSnapshot = Y.createSnapshot(Y.createIdSet(), new Map())\n }\n this.prosemirrorView.dispatch(\n this._tr.setMeta(ySyncPluginKey, { snapshot, prevSnapshot })\n )\n }\n\n unrenderSnapshot () {\n this.mapping.clear()\n this.mux(() => {\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n tr.setMeta(ySyncPluginKey, { snapshot: null, prevSnapshot: null })\n this.prosemirrorView.dispatch(tr)\n })\n }\n\n _forceRerender () {\n this.mapping.clear()\n this.mux(() => {\n // If this is a forced rerender, this might neither happen as a pm change nor within a Yjs\n // transaction. Then the \"before selection\" doesn't exist. In this case, we need to create a\n // relative position before replacing content. Fixes #126\n const sel = this.beforeTransactionSelection !== null ? null : this.prosemirrorView.state.selection\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n if (sel) {\n /**\n * If the Prosemirror document we just created from this.type is\n * smaller than the previous document, the selection might be\n * out of bound, which would make Prosemirror throw an error.\n */\n const clampedAnchor = math.min(math.max(sel.anchor, 0), tr.doc.content.size)\n const clampedHead = math.min(math.max(sel.head, 0), tr.doc.content.size)\n\n tr.setSelection(TextSelection.create(tr.doc, clampedAnchor, clampedHead))\n }\n this.prosemirrorView.dispatch(\n tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this })\n )\n })\n }\n\n /**\n * @param {Y.Snapshot|Uint8Array} snapshot\n * @param {Y.Snapshot|Uint8Array} prevSnapshot\n * @param {Object} pluginState\n */\n _renderSnapshot (snapshot, prevSnapshot, pluginState) {\n /**\n * The document that contains the full history of this document.\n * @type {Y.Doc}\n */\n let historyDoc = this.doc\n let historyType = this.type\n if (!snapshot) {\n snapshot = Y.snapshot(this.doc)\n }\n if (snapshot instanceof Uint8Array || prevSnapshot instanceof Uint8Array) {\n if (!(snapshot instanceof Uint8Array) || !(prevSnapshot instanceof Uint8Array)) {\n // expected both snapshots to be v2 updates\n error.unexpectedCase()\n }\n historyDoc = new Y.Doc({ gc: false })\n Y.applyUpdateV2(historyDoc, prevSnapshot)\n prevSnapshot = Y.snapshot(historyDoc)\n Y.applyUpdateV2(historyDoc, snapshot)\n snapshot = Y.snapshot(historyDoc)\n if (historyType._item === null) {\n /**\n * If is a root type, we need to find the root key in the initial document\n * and use it to get the history type.\n */\n const rootKey = Array.from(this.doc.share.keys()).find(\n (key) => this.doc.share.get(key) === this.type\n )\n historyType = historyDoc.getXmlFragment(rootKey)\n } else {\n /**\n * If it is a sub type, we use the item id to find the history type.\n */\n const historyStructs =\n historyDoc.store.clients.get(historyType._item.id.client) ?? []\n const itemIndex = Y.findIndexSS(\n historyStructs,\n historyType._item.id.clock\n )\n const item = /** @type {Y.Item} */ (historyStructs[itemIndex])\n const content = /** @type {Y.ContentType} */ (item.content)\n historyType = /** @type {Y.XmlFragment} */ (content.type)\n }\n }\n // clear mapping because we are going to rerender\n this.mapping.clear()\n this.mux(() => {\n historyDoc.transact((transaction) => {\n // before rendering, we are going to sanitize ops and split deleted ops\n // if they were deleted by seperate users.\n /**\n * @type {Y.PermanentUserData}\n */\n const pud = pluginState.permanentUserData\n if (pud) {\n pud.dss.forEach((ds) => {\n Y.iterateStructsByIdSet(transaction, ds, (_item) => {})\n })\n }\n /**\n * @param {'removed'|'added'} type\n * @param {Y.ID} id\n */\n const computeYChange = (type, id) => {\n const user = type === 'added'\n ? pud.getUserByClientId(id.client)\n : pud.getUserByDeletedId(id)\n return {\n user,\n type,\n color: getUserColor(\n pluginState.colorMapping,\n pluginState.colors,\n user\n )\n }\n }\n // Create document fragment and render\n const fragmentContent = Y.typeListToArraySnapshot(\n historyType,\n new Y.Snapshot(prevSnapshot.ds, snapshot.sv)\n ).map((t) => {\n if (\n !t._item.deleted || isVisible(t._item, snapshot) ||\n isVisible(t._item, prevSnapshot)\n ) {\n return createNodeFromYElement(\n t,\n this.prosemirrorView.state.schema,\n { mapping: new Map(), isOMark: new Map() },\n snapshot,\n prevSnapshot,\n computeYChange\n )\n } else {\n // No need to render elements that are not visible by either snapshot.\n // If a client adds and deletes content in the same snapshot the element is not visible by either snapshot.\n return null\n }\n }).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n this.prosemirrorView.dispatch(\n tr.setMeta(ySyncPluginKey, { isChangeOrigin: true })\n )\n }, ySyncPluginKey)\n })\n }\n\n /**\n * @param {Array>} events\n * @param {Y.Transaction} transaction\n */\n _typeChanged (events, transaction) {\n if (this.prosemirrorView == null) return\n const syncState = ySyncPluginKey.getState(this.prosemirrorView.state)\n if (\n events.length === 0 || syncState.snapshot != null ||\n syncState.prevSnapshot != null\n ) {\n // drop out if snapshot is active\n this.renderSnapshot(syncState.snapshot, syncState.prevSnapshot)\n return\n }\n this.mux(() => {\n /**\n * @param {any} _\n * @param {Y.AbstractType} type\n */\n const delType = (_, type) => this.mapping.delete(type)\n Y.iterateStructsByIdSet(\n transaction,\n transaction.deleteSet,\n (struct) => {\n if (struct.constructor === Y.Item) {\n const type = /** @type {Y.ContentType} */ (/** @type {Y.Item} */ (struct).content).type\n type && this.mapping.delete(type)\n }\n }\n )\n transaction.changed.forEach(delType)\n transaction.changedParentTypes.forEach(delType)\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeIfNotExists(\n /** @type {Y.XmlElement | Y.XmlHook} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n let tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n restoreRelativeSelection(tr, this.beforeTransactionSelection, this)\n tr = tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, isUndoRedoOperation: transaction.origin instanceof Y.UndoManager })\n if (\n this.beforeTransactionSelection !== null && this._isLocalCursorInView()\n ) {\n tr.scrollIntoView()\n }\n this.prosemirrorView.dispatch(tr)\n })\n }\n\n /**\n * @param {import('prosemirror-model').Node} doc\n */\n _prosemirrorChanged (doc) {\n this.doc.transact(() => {\n updateYFragment(this.doc, this.type, doc, this)\n this.beforeTransactionSelection = getRelativeSelection(\n this,\n this.prosemirrorView.state\n )\n }, ySyncPluginKey)\n }\n\n /**\n * View is ready to listen to changes. Register observers.\n * @param {any} prosemirrorView\n */\n initView (prosemirrorView) {\n if (this.prosemirrorView != null) this.destroy()\n this.prosemirrorView = prosemirrorView\n this.doc.on('beforeAllTransactions', this.beforeAllTransactions)\n this.doc.on('afterAllTransactions', this.afterAllTransactions)\n this.type.observeDeep(this._observeFunction)\n }\n\n destroy () {\n if (this.prosemirrorView == null) return\n this.prosemirrorView = null\n this.type.unobserveDeep(this._observeFunction)\n this.doc.off('beforeAllTransactions', this.beforeAllTransactions)\n this.doc.off('afterAllTransactions', this.afterAllTransactions)\n }\n}\n\n/**\n * @private\n * @param {Y.XmlElement | Y.XmlHook} el\n * @param {PModel.Schema} schema\n * @param {BindingMetadata} meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {PModel.Node | null}\n */\nconst createNodeIfNotExists = (\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const node = /** @type {PModel.Node} */ (meta.mapping.get(el))\n if (node === undefined) {\n if (el instanceof Y.XmlElement) {\n return createNodeFromYElement(\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n } else {\n throw error.methodUnimplemented() // we are currently not handling hooks\n }\n }\n return node\n}\n\n/**\n * @private\n * @param {Y.XmlElement} el\n * @param {any} schema\n * @param {BindingMetadata} meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {PModel.Node | null} Returns node if node could be created. Otherwise it deletes the yjs type and returns null\n */\nexport const createNodeFromYElement = (\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const children = []\n /**\n * @param {Y.XmlElement | Y.XmlText} type\n */\n const createChildren = (type) => {\n if (type instanceof Y.XmlElement) {\n const n = createNodeIfNotExists(\n type,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n if (n !== null) {\n children.push(n)\n }\n } else {\n // If the next ytext exists and was created by us, move the content to the current ytext.\n // This is a fix for #160 -- duplication of characters when two Y.Text exist next to each\n // other.\n const nextytext = /** @type {Y.ContentType} */ (type._item.right?.content)?.type\n if (nextytext instanceof Y.Text && !nextytext._item.deleted && nextytext._item.id.client === nextytext.doc.clientID) {\n type.applyDelta([\n { retain: type.length },\n ...nextytext.toDelta()\n ])\n nextytext.doc.transact(tr => {\n nextytext._item.delete(tr)\n })\n }\n // now create the prosemirror text nodes\n const ns = createTextNodesFromYText(\n type,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n if (ns !== null) {\n ns.forEach((textchild) => {\n if (textchild !== null) {\n children.push(textchild)\n }\n })\n }\n }\n }\n if (snapshot === undefined || prevSnapshot === undefined) {\n el.toArray().forEach(createChildren)\n } else {\n Y.typeListToArraySnapshot(el, new Y.Snapshot(prevSnapshot.ds, snapshot.sv))\n .forEach(createChildren)\n }\n try {\n const attrs = el.getAttributes(snapshot)\n if (snapshot !== undefined) {\n if (!isVisible(/** @type {Y.Item} */ (el._item), snapshot)) {\n attrs.ychange = computeYChange\n ? computeYChange('removed', /** @type {Y.Item} */ (el._item).id)\n : { type: 'removed' }\n } else if (!isVisible(/** @type {Y.Item} */ (el._item), prevSnapshot)) {\n attrs.ychange = computeYChange\n ? computeYChange('added', /** @type {Y.Item} */ (el._item).id)\n : { type: 'added' }\n }\n }\n const node = schema.node(el.nodeName, attrs, children)\n meta.mapping.set(el, node)\n return node\n } catch (e) {\n // an error occured while creating the node. This is probably a result of a concurrent action.\n /** @type {Y.Doc} */ (el.doc).transact((transaction) => {\n /** @type {Y.Item} */ (el._item).delete(transaction)\n }, ySyncPluginKey)\n meta.mapping.delete(el)\n return null\n }\n}\n\n/**\n * @private\n * @param {Y.XmlText} text\n * @param {import('prosemirror-model').Schema} schema\n * @param {BindingMetadata} _meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {Array|null}\n */\nconst createTextNodesFromYText = (\n text,\n schema,\n _meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const nodes = []\n const deltas = text.toDelta(snapshot, prevSnapshot, computeYChange)\n try {\n for (let i = 0; i < deltas.length; i++) {\n const delta = deltas[i]\n nodes.push(schema.text(delta.insert, attributesToMarks(delta.attributes, schema)))\n }\n } catch (e) {\n // an error occured while creating the node. This is probably a result of a concurrent action.\n /** @type {Y.Doc} */ (text.doc).transact((transaction) => {\n /** @type {Y.Item} */ (text._item).delete(transaction)\n }, ySyncPluginKey)\n return null\n }\n // @ts-ignore\n return nodes\n}\n\n/**\n * @private\n * @param {Array} nodes prosemirror node\n * @param {BindingMetadata} meta\n * @return {Y.XmlText}\n */\nconst createTypeFromTextNodes = (nodes, meta) => {\n const type = new Y.XmlText()\n const delta = nodes.map((node) => ({\n // @ts-ignore\n insert: node.text,\n attributes: marksToAttributes(node.marks, meta)\n }))\n type.applyDelta(delta)\n meta.mapping.set(type, nodes)\n return type\n}\n\n/**\n * @private\n * @param {any} node prosemirror node\n * @param {BindingMetadata} meta\n * @return {Y.XmlElement}\n */\nconst createTypeFromElementNode = (node, meta) => {\n const type = new Y.XmlElement(node.type.name)\n for (const key in node.attrs) {\n const val = node.attrs[key]\n if (val !== null && key !== 'ychange') {\n type.setAttribute(key, val)\n }\n }\n type.insert(\n 0,\n normalizePNodeContent(node).map((n) =>\n createTypeFromTextOrElementNode(n, meta)\n )\n )\n meta.mapping.set(type, node)\n return type\n}\n\n/**\n * @private\n * @param {PModel.Node|Array} node prosemirror text node\n * @param {BindingMetadata} meta\n * @return {Y.XmlElement|Y.XmlText}\n */\nconst createTypeFromTextOrElementNode = (node, meta) =>\n node instanceof Array\n ? createTypeFromTextNodes(node, meta)\n : createTypeFromElementNode(node, meta)\n\n/**\n * @param {any} val\n */\nconst isObject = (val) => typeof val === 'object' && val !== null\n\n/**\n * @param {any} pattrs\n * @param {any} yattrs\n */\nconst equalAttrs = (pattrs, yattrs) => {\n const keys = Object.keys(pattrs).filter((key) => pattrs[key] !== null)\n let eq =\n keys.length ===\n (yattrs == null ? 0 : Object.keys(yattrs).filter((key) => yattrs[key] !== null).length)\n for (let i = 0; i < keys.length && eq; i++) {\n const key = keys[i]\n const l = pattrs[key]\n const r = yattrs[key]\n eq = key === 'ychange' || l === r ||\n (isObject(l) && isObject(r) && equalAttrs(l, r))\n }\n return eq\n}\n\n/**\n * @typedef {Array|PModel.Node>} NormalizedPNodeContent\n */\n\n/**\n * @param {any} pnode\n * @return {NormalizedPNodeContent}\n */\nconst normalizePNodeContent = (pnode) => {\n const c = pnode.content.content\n const res = []\n for (let i = 0; i < c.length; i++) {\n const n = c[i]\n if (n.isText) {\n const textNodes = []\n for (let tnode = c[i]; i < c.length && tnode.isText; tnode = c[++i]) {\n textNodes.push(tnode)\n }\n i--\n res.push(textNodes)\n } else {\n res.push(n)\n }\n }\n return res\n}\n\n/**\n * @param {Y.XmlText} ytext\n * @param {Array} ptexts\n */\nconst equalYTextPText = (ytext, ptexts) => {\n const delta = ytext.toDelta()\n return delta.length === ptexts.length &&\n delta.every(/** @type {(d:any,i:number) => boolean} */ (d, i) =>\n d.insert === /** @type {any} */ (ptexts[i]).text &&\n object.keys(d.attributes || {}).length === ptexts[i].marks.length &&\n object.every(d.attributes, (attr, yattrname) => {\n const markname = yattr2markname(yattrname)\n const pmarks = ptexts[i].marks\n return equalAttrs(attr, pmarks.find(/** @param {any} mark */ mark => mark.type.name === markname)?.attrs)\n })\n )\n}\n\n/**\n * @param {Y.XmlElement|Y.XmlText|Y.XmlHook} ytype\n * @param {any|Array} pnode\n */\nconst equalYTypePNode = (ytype, pnode) => {\n if (\n ytype instanceof Y.XmlElement && !(pnode instanceof Array) &&\n matchNodeName(ytype, pnode)\n ) {\n const normalizedContent = normalizePNodeContent(pnode)\n return ytype._length === normalizedContent.length &&\n equalAttrs(ytype.getAttributes(), pnode.attrs) &&\n ytype.toArray().every((ychild, i) =>\n equalYTypePNode(ychild, normalizedContent[i])\n )\n }\n return ytype instanceof Y.XmlText && pnode instanceof Array &&\n equalYTextPText(ytype, pnode)\n}\n\n/**\n * @param {PModel.Node | Array | undefined} mapped\n * @param {PModel.Node | Array} pcontent\n */\nconst mappedIdentity = (mapped, pcontent) =>\n mapped === pcontent ||\n (mapped instanceof Array && pcontent instanceof Array &&\n mapped.length === pcontent.length && mapped.every((a, i) =>\n pcontent[i] === a\n ))\n\n/**\n * @param {Y.XmlElement} ytype\n * @param {PModel.Node} pnode\n * @param {BindingMetadata} meta\n * @return {{ foundMappedChild: boolean, equalityFactor: number }}\n */\nconst computeChildEqualityFactor = (ytype, pnode, meta) => {\n const yChildren = ytype.toArray()\n const pChildren = normalizePNodeContent(pnode)\n const pChildCnt = pChildren.length\n const yChildCnt = yChildren.length\n const minCnt = math.min(yChildCnt, pChildCnt)\n let left = 0\n let right = 0\n let foundMappedChild = false\n for (; left < minCnt; left++) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n if (mappedIdentity(meta.mapping.get(leftY), leftP)) {\n foundMappedChild = true // definite (good) match!\n } else if (!equalYTypePNode(leftY, leftP)) {\n break\n }\n }\n for (; left + right < minCnt; right++) {\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (mappedIdentity(meta.mapping.get(rightY), rightP)) {\n foundMappedChild = true\n } else if (!equalYTypePNode(rightY, rightP)) {\n break\n }\n }\n return {\n equalityFactor: left + right,\n foundMappedChild\n }\n}\n\n/**\n * @param {Y.Text} ytext\n */\nconst ytextTrans = (ytext) => {\n let str = ''\n /**\n * @type {Y.Item|null}\n */\n let n = ytext._start\n const nAttrs = {}\n while (n !== null) {\n if (!n.deleted) {\n if (n.countable && n.content instanceof Y.ContentString) {\n str += n.content.str\n } else if (n.content instanceof Y.ContentFormat) {\n nAttrs[n.content.key] = null\n }\n }\n n = n.right\n }\n return {\n str,\n nAttrs\n }\n}\n\n/**\n * @todo test this more\n *\n * @param {Y.Text} ytext\n * @param {Array} ptexts\n * @param {BindingMetadata} meta\n */\nconst updateYText = (ytext, ptexts, meta) => {\n meta.mapping.set(ytext, ptexts)\n const { nAttrs, str } = ytextTrans(ytext)\n const content = ptexts.map((p) => ({\n insert: /** @type {any} */ (p).text,\n attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks, meta))\n }))\n const { insert, remove, index } = simpleDiff(\n str,\n content.map((c) => c.insert).join('')\n )\n ytext.delete(index, remove)\n ytext.insert(index, insert)\n ytext.applyDelta(\n content.map((c) => ({ retain: c.insert.length, attributes: c.attributes }))\n )\n}\n\nconst hashedMarkNameRegex = /(.*)(--[a-zA-Z0-9+/=]{8})$/\n/**\n * @param {string} attrName\n */\nexport const yattr2markname = attrName => hashedMarkNameRegex.exec(attrName)?.[1] ?? attrName\n\n/**\n * @todo move this to markstoattributes\n *\n * @param {Object} attrs\n * @param {import('prosemirror-model').Schema} schema\n */\nexport const attributesToMarks = (attrs, schema) => {\n /**\n * @type {Array}\n */\n const marks = []\n for (const markName in attrs) {\n // remove hashes if necessary\n marks.push(schema.mark(yattr2markname(markName), attrs[markName]))\n }\n return marks\n}\n\n/**\n * @param {Array} marks\n * @param {BindingMetadata} meta\n */\nconst marksToAttributes = (marks, meta) => {\n const pattrs = {}\n marks.forEach((mark) => {\n if (mark.type.name !== 'ychange') {\n const isOverlapping = map.setIfUndefined(meta.isOMark, mark.type, () => !mark.type.excludes(mark.type))\n pattrs[isOverlapping ? `${mark.type.name}--${utils.hashOfJSON(mark.toJSON())}` : mark.type.name] = mark.attrs\n }\n })\n return pattrs\n}\n\n/**\n * Update a yDom node by syncing the current content of the prosemirror node.\n *\n * This is a y-prosemirror internal feature that you can use at your own risk.\n *\n * @private\n * @unstable\n *\n * @param {{transact: Function}} y\n * @param {Y.XmlFragment} yDomFragment\n * @param {any} pNode\n * @param {BindingMetadata} meta\n */\nexport const updateYFragment = (y, yDomFragment, pNode, meta) => {\n if (\n yDomFragment instanceof Y.XmlElement &&\n yDomFragment.nodeName !== pNode.type.name\n ) {\n throw new Error('node name mismatch!')\n }\n meta.mapping.set(yDomFragment, pNode)\n // update attributes\n if (yDomFragment instanceof Y.XmlElement) {\n const yDomAttrs = yDomFragment.getAttributes()\n const pAttrs = pNode.attrs\n for (const key in pAttrs) {\n if (pAttrs[key] !== null) {\n if (yDomAttrs[key] !== pAttrs[key] && key !== 'ychange') {\n yDomFragment.setAttribute(key, pAttrs[key])\n }\n } else {\n yDomFragment.removeAttribute(key)\n }\n }\n // remove all keys that are no longer in pAttrs\n for (const key in yDomAttrs) {\n if (pAttrs[key] === undefined) {\n yDomFragment.removeAttribute(key)\n }\n }\n }\n // update children\n const pChildren = normalizePNodeContent(pNode)\n const pChildCnt = pChildren.length\n const yChildren = yDomFragment.toArray()\n const yChildCnt = yChildren.length\n const minCnt = math.min(pChildCnt, yChildCnt)\n let left = 0\n let right = 0\n // find number of matching elements from left\n for (; left < minCnt; left++) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n if (!mappedIdentity(meta.mapping.get(leftY), leftP)) {\n if (equalYTypePNode(leftY, leftP)) {\n // update mapping\n meta.mapping.set(leftY, leftP)\n } else {\n break\n }\n }\n }\n // find number of matching elements from right\n for (; right + left < minCnt; right++) {\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (!mappedIdentity(meta.mapping.get(rightY), rightP)) {\n if (equalYTypePNode(rightY, rightP)) {\n // update mapping\n meta.mapping.set(rightY, rightP)\n } else {\n break\n }\n }\n }\n y.transact(() => {\n // try to compare and update\n while (yChildCnt - left - right > 0 && pChildCnt - left - right > 0) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (leftY instanceof Y.XmlText && leftP instanceof Array) {\n if (!equalYTextPText(leftY, leftP)) {\n updateYText(leftY, leftP, meta)\n }\n left += 1\n } else {\n let updateLeft = leftY instanceof Y.XmlElement &&\n matchNodeName(leftY, leftP)\n let updateRight = rightY instanceof Y.XmlElement &&\n matchNodeName(rightY, rightP)\n if (updateLeft && updateRight) {\n // decide which which element to update\n const equalityLeft = computeChildEqualityFactor(\n /** @type {Y.XmlElement} */ (leftY),\n /** @type {PModel.Node} */ (leftP),\n meta\n )\n const equalityRight = computeChildEqualityFactor(\n /** @type {Y.XmlElement} */ (rightY),\n /** @type {PModel.Node} */ (rightP),\n meta\n )\n if (\n equalityLeft.foundMappedChild && !equalityRight.foundMappedChild\n ) {\n updateRight = false\n } else if (\n !equalityLeft.foundMappedChild && equalityRight.foundMappedChild\n ) {\n updateLeft = false\n } else if (\n equalityLeft.equalityFactor < equalityRight.equalityFactor\n ) {\n updateLeft = false\n } else {\n updateRight = false\n }\n }\n if (updateLeft) {\n updateYFragment(\n y,\n /** @type {Y.XmlFragment} */ (leftY),\n /** @type {PModel.Node} */ (leftP),\n meta\n )\n left += 1\n } else if (updateRight) {\n updateYFragment(\n y,\n /** @type {Y.XmlFragment} */ (rightY),\n /** @type {PModel.Node} */ (rightP),\n meta\n )\n right += 1\n } else {\n meta.mapping.delete(yDomFragment.get(left))\n yDomFragment.delete(left, 1)\n yDomFragment.insert(left, [\n createTypeFromTextOrElementNode(leftP, meta)\n ])\n left += 1\n }\n }\n }\n const yDelLen = yChildCnt - left - right\n if (\n yChildCnt === 1 && pChildCnt === 0 && yChildren[0] instanceof Y.XmlText\n ) {\n meta.mapping.delete(yChildren[0])\n // Edge case handling https://github.com/yjs/y-prosemirror/issues/108\n // Only delete the content of the Y.Text to retain remote changes on the same Y.Text object\n yChildren[0].delete(0, yChildren[0].length)\n } else if (yDelLen > 0) {\n yDomFragment.slice(left, left + yDelLen).forEach(type => meta.mapping.delete(type))\n yDomFragment.delete(left, yDelLen)\n }\n if (left + right < pChildCnt) {\n const ins = []\n for (let i = left; i < pChildCnt - right; i++) {\n ins.push(createTypeFromTextOrElementNode(pChildren[i], meta))\n }\n yDomFragment.insert(left, ins)\n }\n }, ySyncPluginKey)\n}\n\n/**\n * @function\n * @param {Y.XmlElement} yElement\n * @param {any} pNode Prosemirror Node\n */\nconst matchNodeName = (yElement, pNode) =>\n !(pNode instanceof Array) && yElement.nodeName === pNode.type.name\n","import { updateYFragment, createNodeFromYElement, yattr2markname, createEmptyMeta } from './plugins/sync-plugin.js' // eslint-disable-line\nimport { ySyncPluginKey } from './plugins/keys.js'\nimport * as Y from '@y/y'\nimport { EditorView } from 'prosemirror-view' // eslint-disable-line\nimport { Node, Schema, Fragment } from 'prosemirror-model' // eslint-disable-line\nimport * as error from 'lib0/error'\nimport * as map from 'lib0/map'\nimport * as eventloop from 'lib0/eventloop'\n\n/**\n * Either a node if type is YXmlElement or an Array of text nodes if YXmlText\n * @typedef {Map>} ProsemirrorMapping\n */\n\n/**\n * Is null if no timeout is in progress.\n * Is defined if a timeout is in progress.\n * Maps from view\n * @type {Map>|null}\n */\nlet viewsToUpdate = null\n\nconst updateMetas = () => {\n const ups = /** @type {Map>} */ (viewsToUpdate)\n viewsToUpdate = null\n ups.forEach((metas, view) => {\n const tr = view.state.tr\n const syncState = ySyncPluginKey.getState(view.state)\n if (syncState && syncState.binding && !syncState.binding.isDestroyed) {\n metas.forEach((val, key) => {\n tr.setMeta(key, val)\n })\n view.dispatch(tr)\n }\n })\n}\n\nexport const setMeta = (view, key, value) => {\n if (!viewsToUpdate) {\n viewsToUpdate = new Map()\n eventloop.timeout(0, updateMetas)\n }\n map.setIfUndefined(viewsToUpdate, view, map.create).set(key, value)\n}\n\n/**\n * Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).\n *\n * @param {number} pos\n * @param {Y.XmlFragment} type\n * @param {ProsemirrorMapping} mapping\n * @return {any} relative position\n */\nexport const absolutePositionToRelativePosition = (pos, type, mapping) => {\n if (pos === 0) {\n // if the type is later populated, we want to retain the 0 position (hence assoc=-1)\n return Y.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0)\n }\n /**\n * @type {any}\n */\n let n = type._first === null ? null : /** @type {Y.ContentType} */ (type._first.content).type\n while (n !== null && type !== n) {\n if (n instanceof Y.XmlText) {\n if (n._length >= pos) {\n return Y.createRelativePositionFromTypeIndex(n, pos, type.length === 0 ? -1 : 0)\n } else {\n pos -= n._length\n }\n if (n._item !== null && n._item.next !== null) {\n n = /** @type {Y.ContentType} */ (n._item.next.content).type\n } else {\n do {\n n = n._item === null ? null : n._item.parent\n pos--\n } while (n !== type && n !== null && n._item !== null && n._item.next === null)\n if (n !== null && n !== type) {\n // @ts-gnore we know that n.next !== null because of above loop conditition\n n = n._item === null ? null : /** @type {Y.ContentType} */ (/** @type Y.Item */ (n._item.next).content).type\n }\n }\n } else {\n const pNodeSize = /** @type {any} */ (mapping.get(n) || { nodeSize: 0 }).nodeSize\n if (n._first !== null && pos < pNodeSize) {\n n = /** @type {Y.ContentType} */ (n._first.content).type\n pos--\n } else {\n if (pos === 1 && n._length === 0 && pNodeSize > 1) {\n // edge case, should end in this paragraph\n return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null)\n }\n pos -= pNodeSize\n if (n._item !== null && n._item.next !== null) {\n n = /** @type {Y.ContentType} */ (n._item.next.content).type\n } else {\n if (pos === 0) {\n // set to end of n.parent\n n = n._item === null ? n : n._item.parent\n return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null)\n }\n do {\n n = /** @type {Y.Item} */ (n._item).parent\n pos--\n } while (n !== type && /** @type {Y.Item} */ (n._item).next === null)\n // if n is null at this point, we have an unexpected case\n if (n !== type) {\n // We know that n._item.next is defined because of above loop condition\n n = /** @type {Y.ContentType} */ (/** @type {Y.Item} */ (/** @type {Y.Item} */ (n._item).next).content).type\n }\n }\n }\n }\n if (n === null) {\n throw error.unexpectedCase()\n }\n if (pos === 0 && n.constructor !== Y.XmlText && n !== type) { // TODO: set to <= 0\n return createRelativePosition(n._item.parent, n._item)\n }\n }\n return Y.createRelativePositionFromTypeIndex(type, type._length, type.length === 0 ? -1 : 0)\n}\n\nconst createRelativePosition = (type, item) => {\n let typeid = null\n let tname = null\n if (type._item === null) {\n tname = Y.findRootTypeKey(type)\n } else {\n typeid = Y.createID(type._item.id.client, type._item.id.clock)\n }\n return new Y.RelativePosition(typeid, tname, item.id)\n}\n\n/**\n * @param {Y.Doc} y\n * @param {Y.XmlFragment} documentType Top level type that is bound to pView\n * @param {any} relPos Encoded Yjs based relative position\n * @param {ProsemirrorMapping} mapping\n * @return {null|number}\n */\nexport const relativePositionToAbsolutePosition = (y, documentType, relPos, mapping) => {\n const decodedPos = Y.createAbsolutePositionFromRelativePosition(relPos, y)\n if (decodedPos === null || (decodedPos.type !== documentType && !Y.isParentOf(documentType, decodedPos.type._item))) {\n return null\n }\n let type = decodedPos.type\n let pos = 0\n if (type.constructor === Y.XmlText) {\n pos = decodedPos.index\n } else if (type._item === null || !type._item.deleted) {\n let n = type._first\n let i = 0\n while (i < type._length && i < decodedPos.index && n !== null) {\n if (!n.deleted) {\n const t = /** @type {Y.ContentType} */ (n.content).type\n i++\n if (t instanceof Y.XmlText) {\n pos += t._length\n } else {\n pos += /** @type {any} */ (mapping.get(t)).nodeSize\n }\n }\n n = /** @type {Y.Item} */ (n.right)\n }\n pos += 1 // increase because we go out of n\n }\n while (type !== documentType && type._item !== null) {\n // @ts-ignore\n const parent = type._item.parent\n // @ts-ignore\n if (parent._item === null || !parent._item.deleted) {\n pos += 1 // the start tag\n let n = /** @type {Y.AbstractType} */ (parent)._first\n // now iterate until we found type\n while (n !== null) {\n const contentType = /** @type {Y.ContentType} */ (n.content).type\n if (contentType === type) {\n break\n }\n if (!n.deleted) {\n if (contentType instanceof Y.XmlText) {\n pos += contentType._length\n } else {\n pos += /** @type {any} */ (mapping.get(contentType)).nodeSize\n }\n }\n n = n.right\n }\n }\n type = /** @type {Y.AbstractType} */ (parent)\n }\n return pos - 1 // we don't count the most outer tag, because it is a fragment\n}\n\n/**\n * Utility function for converting an Y.Fragment to a ProseMirror fragment.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n */\nexport const yXmlFragmentToProseMirrorFragment = (yXmlFragment, schema) => {\n const fragmentContent = yXmlFragment.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n schema,\n createEmptyMeta()\n )\n ).filter((n) => n !== null)\n return Fragment.fromArray(fragmentContent)\n}\n\n/**\n * Utility function for converting an Y.Fragment to a ProseMirror node.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n */\nexport const yXmlFragmentToProseMirrorRootNode = (yXmlFragment, schema) =>\n schema.topNodeType.create(null, yXmlFragmentToProseMirrorFragment(yXmlFragment, schema))\n\n/**\n * The initial ProseMirror content should be supplied by Yjs. This function transforms a Y.Fragment\n * to a ProseMirror Doc node and creates a mapping that is used by the sync plugin.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n *\n * @todo deprecate mapping property\n */\nexport const initProseMirrorDoc = (yXmlFragment, schema) => {\n const meta = createEmptyMeta()\n const fragmentContent = yXmlFragment.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n schema,\n meta\n )\n ).filter((n) => n !== null)\n const doc = schema.topNodeType.create(null, Fragment.fromArray(fragmentContent))\n return { doc, meta, mapping: meta.mapping }\n}\n\n/**\n * Utility method to convert a Prosemirror Doc Node into a Y.Doc.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Node} doc\n * @param {string} xmlFragment\n * @return {Y.Doc}\n */\nexport function prosemirrorToYDoc (doc, xmlFragment = 'prosemirror') {\n const ydoc = new Y.Doc()\n const type = /** @type {Y.XmlFragment} */ (ydoc.get(xmlFragment, Y.XmlFragment))\n if (!type.doc) {\n return ydoc\n }\n\n prosemirrorToYXmlFragment(doc, type)\n return type.doc\n}\n\n/**\n * Utility method to update an empty Y.XmlFragment with content from a Prosemirror Doc Node.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * Note: The Y.XmlFragment does not need to be part of a Y.Doc document at the time that this\n * method is called, but it must be added before any other operations are performed on it.\n *\n * @param {Node} doc prosemirror document.\n * @param {Y.XmlFragment} [xmlFragment] If supplied, an xml fragment to be\n * populated from the prosemirror state; otherwise a new XmlFragment will be created.\n * @return {Y.XmlFragment}\n */\nexport function prosemirrorToYXmlFragment (doc, xmlFragment) {\n const type = xmlFragment || new Y.XmlFragment()\n const ydoc = type.doc ? type.doc : { transact: (transaction) => transaction(undefined) }\n updateYFragment(ydoc, type, doc, { mapping: new Map(), isOMark: new Map() })\n return type\n}\n\n/**\n * Utility method to convert Prosemirror compatible JSON into a Y.Doc.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Schema} schema\n * @param {any} state\n * @param {string} xmlFragment\n * @return {Y.Doc}\n */\nexport function prosemirrorJSONToYDoc (schema, state, xmlFragment = 'prosemirror') {\n const doc = Node.fromJSON(schema, state)\n return prosemirrorToYDoc(doc, xmlFragment)\n}\n\n/**\n * Utility method to convert Prosemirror compatible JSON to a Y.XmlFragment\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Schema} schema\n * @param {any} state\n * @param {Y.XmlFragment} [xmlFragment] If supplied, an xml fragment to be\n * populated from the prosemirror state; otherwise a new XmlFragment will be created.\n * @return {Y.XmlFragment}\n */\nexport function prosemirrorJSONToYXmlFragment (schema, state, xmlFragment) {\n const doc = Node.fromJSON(schema, state)\n return prosemirrorToYXmlFragment(doc, xmlFragment)\n}\n\n/**\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to a Prosemirror Doc node.\n *\n * @param {Schema} schema\n * @param {Y.Doc} ydoc\n * @return {Node}\n */\nexport function yDocToProsemirror (schema, ydoc) {\n const state = yDocToProsemirrorJSON(ydoc)\n return Node.fromJSON(schema, state)\n}\n\n/**\n *\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.XmlFragment to a Prosemirror Doc node.\n *\n * @param {Schema} schema\n * @param {Y.XmlFragment} xmlFragment\n * @return {Node}\n */\nexport function yXmlFragmentToProsemirror (schema, xmlFragment) {\n const state = yXmlFragmentToProsemirrorJSON(xmlFragment)\n return Node.fromJSON(schema, state)\n}\n\n/**\n *\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to Prosemirror compatible JSON.\n *\n * @param {Y.Doc} ydoc\n * @param {string} xmlFragment\n * @return {Record}\n */\nexport function yDocToProsemirrorJSON (\n ydoc,\n xmlFragment = 'prosemirror'\n) {\n return yXmlFragmentToProsemirrorJSON(ydoc.getXmlFragment(xmlFragment))\n}\n\n/**\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to Prosemirror compatible JSON.\n *\n * @param {Y.XmlFragment} xmlFragment The fragment, which must be part of a Y.Doc.\n * @return {Record}\n */\nexport function yXmlFragmentToProsemirrorJSON (xmlFragment) {\n const items = xmlFragment.toArray()\n\n /**\n * @param {Y.AbstractType} item\n */\n const serialize = item => {\n /**\n * @type {Object} NodeObject\n * @property {string} NodeObject.type\n * @property {Record=} NodeObject.attrs\n * @property {Array=} NodeObject.content\n */\n let response\n\n // TODO: Must be a better way to detect text nodes than this\n if (item instanceof Y.XmlText) {\n const delta = item.toDelta()\n response = delta.map(/** @param {any} d */ (d) => {\n const text = {\n type: 'text',\n text: d.insert\n }\n if (d.attributes) {\n text.marks = Object.keys(d.attributes).map((type_) => {\n const attrs = d.attributes[type_]\n const type = yattr2markname(type_)\n const mark = {\n type\n }\n if (Object.keys(attrs)) {\n mark.attrs = attrs\n }\n return mark\n })\n }\n return text\n })\n } else if (item instanceof Y.XmlElement) {\n response = {\n type: item.nodeName\n }\n\n const attrs = item.getAttributes()\n if (Object.keys(attrs).length) {\n response.attrs = attrs\n }\n\n const children = item.toArray()\n if (children.length) {\n response.content = children.map(serialize).flat()\n }\n } else {\n // expected either Y.XmlElement or Y.XmlText\n error.unexpectedCase()\n }\n\n return response\n }\n\n return {\n type: 'doc',\n content: items.map(serialize)\n }\n}\n","import * as Y from '@y/y'\nimport { Decoration, DecorationSet } from \"prosemirror-view\"; // eslint-disable-line\nimport { Plugin } from \"prosemirror-state\"; // eslint-disable-line\nimport { Awareness } from \"@y/protocols/awareness\"; // eslint-disable-line\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n setMeta\n} from '../lib.js'\nimport { yCursorPluginKey, ySyncPluginKey } from './keys.js'\n\nimport * as math from 'lib0/math'\n\n/**\n * Default awareness state filter\n *\n * @param {number} currentClientId current client id\n * @param {number} userClientId user client id\n * @param {any} _user user data\n * @return {boolean}\n */\nexport const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId\n\n/**\n * Default generator for a cursor element\n *\n * @param {any} user user data\n * @return {HTMLElement}\n */\nexport const defaultCursorBuilder = (user) => {\n const cursor = document.createElement('span')\n cursor.classList.add('ProseMirror-yjs-cursor')\n cursor.setAttribute('style', `border-color: ${user.color}`)\n const userDiv = document.createElement('div')\n userDiv.setAttribute('style', `background-color: ${user.color}`)\n userDiv.insertBefore(document.createTextNode(user.name), null)\n const nonbreakingSpace1 = document.createTextNode('\\u2060')\n const nonbreakingSpace2 = document.createTextNode('\\u2060')\n cursor.insertBefore(nonbreakingSpace1, null)\n cursor.insertBefore(userDiv, null)\n cursor.insertBefore(nonbreakingSpace2, null)\n return cursor\n}\n\n/**\n * Default generator for the selection attributes\n *\n * @param {any} user user data\n * @return {import('prosemirror-view').DecorationAttrs}\n */\nexport const defaultSelectionBuilder = (user) => {\n return {\n style: `background-color: ${user.color}70`,\n class: 'ProseMirror-yjs-selection'\n }\n}\n\nconst rxValidColor = /^#[0-9a-fA-F]{6}$/\n\n/**\n * @param {any} state\n * @param {Awareness} awareness\n * @param {function(number, number, any):boolean} awarenessFilter\n * @param {(user: { name: string, color: string }, clientId: number) => Element} createCursor\n * @param {(user: { name: string, color: string }, clientId: number) => import('prosemirror-view').DecorationAttrs} createSelection\n * @return {any} DecorationSet\n */\nexport const createDecorations = (\n state,\n awareness,\n awarenessFilter,\n createCursor,\n createSelection\n) => {\n const ystate = ySyncPluginKey.getState(state)\n const y = ystate.doc\n const decorations = []\n if (\n ystate.snapshot != null || ystate.prevSnapshot != null ||\n ystate.binding.mapping.size === 0\n ) {\n // do not render cursors while snapshot is active\n return DecorationSet.create(state.doc, [])\n }\n awareness.getStates().forEach((aw, clientId) => {\n if (!awarenessFilter(y.clientID, clientId, aw)) {\n return\n }\n\n if (aw.cursor != null) {\n const user = aw.user || {}\n if (user.color == null) {\n user.color = '#ffa500'\n } else if (!rxValidColor.test(user.color)) {\n // We only support 6-digit RGB colors in y-prosemirror\n console.warn('A user uses an unsupported color format', user)\n }\n if (user.name == null) {\n user.name = `User: ${clientId}`\n }\n let anchor = relativePositionToAbsolutePosition(\n y,\n ystate.type,\n Y.createRelativePositionFromJSON(aw.cursor.anchor),\n ystate.binding.mapping\n )\n let head = relativePositionToAbsolutePosition(\n y,\n ystate.type,\n Y.createRelativePositionFromJSON(aw.cursor.head),\n ystate.binding.mapping\n )\n if (anchor !== null && head !== null) {\n const maxsize = math.max(state.doc.content.size - 1, 0)\n anchor = math.min(anchor, maxsize)\n head = math.min(head, maxsize)\n decorations.push(\n Decoration.widget(head, () => createCursor(user, clientId), {\n key: clientId + '',\n side: 10\n })\n )\n const from = math.min(anchor, head)\n const to = math.max(anchor, head)\n decorations.push(\n Decoration.inline(from, to, createSelection(user, clientId), {\n inclusiveEnd: true,\n inclusiveStart: false\n })\n )\n }\n }\n })\n return DecorationSet.create(state.doc, decorations)\n}\n\n/**\n * A prosemirror plugin that listens to awareness information on Yjs.\n * This requires that a `prosemirrorPlugin` is also bound to the prosemirror.\n *\n * @public\n * @param {Awareness} awareness\n * @param {object} opts\n * @param {function(any, any, any):boolean} [opts.awarenessStateFilter]\n * @param {(user: any, clientId: number) => HTMLElement} [opts.cursorBuilder]\n * @param {(user: any, clientId: number) => import('prosemirror-view').DecorationAttrs} [opts.selectionBuilder]\n * @param {function(any):any} [opts.getSelection]\n * @param {string} [cursorStateField] By default all editor bindings use the awareness 'cursor' field to propagate cursor information.\n * @return {any}\n */\nexport const yCursorPlugin = (\n awareness,\n {\n awarenessStateFilter = defaultAwarenessStateFilter,\n cursorBuilder = defaultCursorBuilder,\n selectionBuilder = defaultSelectionBuilder,\n getSelection = (state) => state.selection\n } = {},\n cursorStateField = 'cursor'\n) =>\n new Plugin({\n key: yCursorPluginKey,\n state: {\n init (_, state) {\n return createDecorations(\n state,\n awareness,\n awarenessStateFilter,\n cursorBuilder,\n selectionBuilder\n )\n },\n apply (tr, prevState, _oldState, newState) {\n const ystate = ySyncPluginKey.getState(newState)\n const yCursorState = tr.getMeta(yCursorPluginKey)\n if (\n (ystate && ystate.isChangeOrigin) ||\n (yCursorState && yCursorState.awarenessUpdated)\n ) {\n return createDecorations(\n newState,\n awareness,\n awarenessStateFilter,\n cursorBuilder,\n selectionBuilder\n )\n }\n return prevState.map(tr.mapping, tr.doc)\n }\n },\n props: {\n decorations: (state) => {\n return yCursorPluginKey.getState(state)\n }\n },\n view: (view) => {\n const awarenessListener = () => {\n // @ts-ignore\n if (view.docView) {\n setMeta(view, yCursorPluginKey, { awarenessUpdated: true })\n }\n }\n const updateCursorInfo = () => {\n const ystate = ySyncPluginKey.getState(view.state)\n // @note We make implicit checks when checking for the cursor property\n const current = awareness.getLocalState() || {}\n if (view.hasFocus()) {\n const selection = getSelection(view.state)\n /**\n * @type {Y.RelativePosition}\n */\n const anchor = absolutePositionToRelativePosition(\n selection.anchor,\n ystate.type,\n ystate.binding.mapping\n )\n /**\n * @type {Y.RelativePosition}\n */\n const head = absolutePositionToRelativePosition(\n selection.head,\n ystate.type,\n ystate.binding.mapping\n )\n if (\n current.cursor == null ||\n !Y.compareRelativePositions(\n Y.createRelativePositionFromJSON(current.cursor.anchor),\n anchor\n ) ||\n !Y.compareRelativePositions(\n Y.createRelativePositionFromJSON(current.cursor.head),\n head\n )\n ) {\n awareness.setLocalStateField(cursorStateField, {\n anchor,\n head\n })\n }\n } else if (\n current.cursor != null &&\n relativePositionToAbsolutePosition(\n ystate.doc,\n ystate.type,\n Y.createRelativePositionFromJSON(current.cursor.anchor),\n ystate.binding.mapping\n ) !== null\n ) {\n // delete cursor information if current cursor information is owned by this editor binding\n awareness.setLocalStateField(cursorStateField, null)\n }\n }\n awareness.on('change', awarenessListener)\n view.dom.addEventListener('focusin', updateCursorInfo)\n view.dom.addEventListener('focusout', updateCursorInfo)\n return {\n update: updateCursorInfo,\n destroy: () => {\n view.dom.removeEventListener('focusin', updateCursorInfo)\n view.dom.removeEventListener('focusout', updateCursorInfo)\n awareness.off('change', awarenessListener)\n awareness.setLocalStateField(cursorStateField, null)\n }\n }\n }\n })\n","import { Plugin } from 'prosemirror-state'\n\nimport { getRelativeSelection } from './sync-plugin.js'\nimport { UndoManager, Item, ContentType, XmlElement, Text } from '@y/y'\nimport { yUndoPluginKey, ySyncPluginKey } from './keys.js'\n\n/**\n * @typedef {Object} UndoPluginState\n * @property {import('@y/y').UndoManager} undoManager\n * @property {ReturnType | null} prevSel\n * @property {boolean} hasUndoOps\n * @property {boolean} hasRedoOps\n */\n\n/**\n * Undo the last user action\n *\n * @param {import('prosemirror-state').EditorState} state\n * @return {boolean} whether a change was undone\n */\nexport const undo = state => yUndoPluginKey.getState(state)?.undoManager?.undo() != null\n\n/**\n * Redo the last user action\n *\n * @param {import('prosemirror-state').EditorState} state\n * @return {boolean} whether a change was undone\n */\nexport const redo = state => yUndoPluginKey.getState(state)?.undoManager?.redo() != null\n\n/**\n * Undo the last user action if there are undo operations available\n * @type {import('prosemirror-state').Command}\n */\nexport const undoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canUndo() : undo(state)\n\n/**\n * Redo the last user action if there are redo operations available\n * @type {import('prosemirror-state').Command}\n */\nexport const redoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canRedo() : redo(state)\n\nexport const defaultProtectedNodes = new Set(['paragraph'])\n\n/**\n * @param {import('@y/y').Item} item\n * @param {Set} protectedNodes\n * @returns {boolean}\n */\nexport const defaultDeleteFilter = (item, protectedNodes) => !(item instanceof Item) ||\n !(item.content instanceof ContentType) ||\n !(item.content.type instanceof Text ||\n (item.content.type instanceof XmlElement && protectedNodes.has(item.content.type.nodeName))) ||\n item.content.type._length === 0\n\n/**\n * @param {object} [options]\n * @param {Set} [options.protectedNodes]\n * @param {any[]} [options.trackedOrigins]\n * @param {import('@y/y').UndoManager | null} [options.undoManager]\n */\nexport const yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins = [], undoManager = null } = {}) => new Plugin({\n key: yUndoPluginKey,\n state: {\n init: (initargs, state) => {\n // TODO: check if plugin order matches and fix\n const ystate = ySyncPluginKey.getState(state)\n const _undoManager = undoManager || new UndoManager(ystate.type, {\n trackedOrigins: new Set([ySyncPluginKey].concat(trackedOrigins)),\n deleteFilter: (item) => defaultDeleteFilter(item, protectedNodes),\n captureTransaction: tr => tr.meta.get('addToHistory') !== false\n })\n return {\n undoManager: _undoManager,\n prevSel: null,\n hasUndoOps: _undoManager.undoStack.length > 0,\n hasRedoOps: _undoManager.redoStack.length > 0\n }\n },\n apply: (tr, val, oldState, state) => {\n const binding = ySyncPluginKey.getState(state).binding\n const undoManager = val.undoManager\n const hasUndoOps = undoManager.undoStack.length > 0\n const hasRedoOps = undoManager.redoStack.length > 0\n if (binding) {\n return {\n undoManager,\n prevSel: getRelativeSelection(binding, oldState),\n hasUndoOps,\n hasRedoOps\n }\n } else {\n if (hasUndoOps !== val.hasUndoOps || hasRedoOps !== val.hasRedoOps) {\n return Object.assign({}, val, {\n hasUndoOps: undoManager.undoStack.length > 0,\n hasRedoOps: undoManager.redoStack.length > 0\n })\n } else { // nothing changed\n return val\n }\n }\n }\n },\n view: view => {\n const ystate = ySyncPluginKey.getState(view.state)\n const undoManager = yUndoPluginKey.getState(view.state).undoManager\n undoManager.on('stack-item-added', ({ stackItem }) => {\n const binding = ystate.binding\n if (binding) {\n stackItem.meta.set(binding, yUndoPluginKey.getState(view.state).prevSel)\n }\n })\n undoManager.on('stack-item-popped', ({ stackItem }) => {\n const binding = ystate.binding\n if (binding) {\n binding.beforeTransactionSelection = stackItem.meta.get(binding) || binding.beforeTransactionSelection\n }\n })\n return {\n destroy: () => {\n undoManager.destroy()\n }\n }\n }\n})\n"],"names":["PluginKey","buf","sha256","set","random","Plugin","eventloop","AllSelection","NodeSelection","TextSelection","createMutex","environment","dom","Y","PModel","math","error","object","simpleDiff","map","utils.hashOfJSON","Fragment","Node","DecorationSet","Decoration","Item","ContentType","Text","XmlElement","UndoManager"],"mappings":"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"}
+\ No newline at end of file
++{"version":3,"file":"y-prosemirror.cjs","sources":["../src/plugins/keys.js","../src/utils.js","../src/plugins/sync-plugin.js","../src/lib.js","../src/plugins/cursor-plugin.js","../src/plugins/undo-plugin.js","../src/index.js"],"sourcesContent":["import { PluginKey } from 'prosemirror-state' // eslint-disable-line\n\n/**\n * The unique prosemirror plugin key for syncPlugin\n *\n * @public\n * @type {PluginKey}\n */\nexport const ySyncPluginKey = new PluginKey('y-sync')\n\n/**\n * The unique prosemirror plugin key for undoPlugin\n *\n * @public\n * @type {PluginKey}\n */\nexport const yUndoPluginKey = new PluginKey('y-undo')\n\n/**\n * The unique prosemirror plugin key for cursorPlugin\n *\n * @public\n */\nexport const yCursorPluginKey = new PluginKey('yjs-cursor')\n","import * as sha256 from 'lib0/hash/sha256'\nimport * as buf from 'lib0/buffer'\nimport * as Y from '@y/y'\n\n/**\n * Custom function to transform sha256 hash to N byte\n *\n * @param {Uint8Array} digest\n */\nconst _convolute = digest => {\n const N = 6\n for (let i = N; i < digest.length; i++) {\n digest[i % N] = digest[i % N] ^ digest[i]\n }\n return digest.slice(0, N)\n}\n\n/**\n * @param {any} json\n */\nexport const hashOfJSON = (json) => buf.toBase64(_convolute(sha256.digest(buf.encodeAny(json))))\n\n/**\n * To find a fragment in another ydoc, we need to search for it.\n *\n * @template {Y.AbstractType} T\n * @param {T} ytype - The Yjs type to locate (should extend Y.AbstractType)\n * @param {Y.Doc} otherYdoc - The target Y.Doc in which to find the equivalent type\n * @returns {T} - The corresponding type instance in the other Yjs document\n * @throws {Error} If ytype does not have a ydoc or can't be found in the other doc\n */\nexport function findTypeInOtherYdoc (ytype, otherYdoc) {\n if (ytype.doc === otherYdoc) {\n // fast-path, this is the same ydoc\n return ytype\n }\n const ydoc = ytype.doc\n if (!ydoc) {\n throw new Error('type does not have a ydoc')\n }\n if (ytype._item === null) {\n // Root type case: find key in ydoc.share that matches ytype, then get from otherYdoc\n const rootKey = Array.from(ydoc.share.keys()).find(\n function (key) { return ydoc.share.get(key) === ytype }\n )\n if (rootKey == null) {\n throw new Error('type does not exist')\n }\n // Use the ytype's constructor to get the type from the other document\n return /** @type {T} */ (otherYdoc.get(rootKey, ytype.constructor))\n } else {\n // Subtype case: locate by item id via internals\n const ytypeItem = ytype._item\n const otherStructs = otherYdoc.store.clients.get(ytypeItem.id.client) || []\n const itemIndex = Y.findIndexSS(otherStructs, ytypeItem.id.clock)\n const otherItem = /** @type {Y.Item|undefined} */ (otherStructs[itemIndex])\n if (!otherItem) {\n throw new Error('type does not exist in other ydoc')\n }\n const otherContent = /** @type {Y.ContentType|undefined} */ (otherItem.content)\n if (!otherContent) {\n throw new Error('type does not exist in other ydoc')\n }\n return /** @type {T} */ (otherContent.type)\n }\n}\n","/**\n * @module bindings/prosemirror\n */\n\nimport { createMutex } from 'lib0/mutex'\nimport * as PModel from 'prosemirror-model'\nimport { AllSelection, Plugin, TextSelection, NodeSelection } from \"prosemirror-state\"; // eslint-disable-line\nimport * as math from 'lib0/math'\nimport * as object from 'lib0/object'\nimport * as set from 'lib0/set'\nimport { simpleDiff } from 'lib0/diff'\nimport * as error from 'lib0/error'\nimport { ySyncPluginKey, yUndoPluginKey } from './keys.js'\nimport * as Y from '@y/y'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition\n} from '../lib.js'\nimport * as random from 'lib0/random'\nimport * as environment from 'lib0/environment'\nimport * as dom from 'lib0/dom'\nimport * as eventloop from 'lib0/eventloop'\nimport * as map from 'lib0/map'\nimport * as utils from '../utils.js'\n\n/**\n * @typedef {Object} BindingMetadata\n * @property {ProsemirrorMapping} BindingMetadata.mapping\n * @property {Map} BindingMetadata.isOMark - is overlapping mark\n */\n\n/**\n * @return {BindingMetadata}\n */\nexport const createEmptyMeta = () => ({\n mapping: new Map(),\n isOMark: new Map()\n})\n\n/**\n * @param {Y.Item} item\n * @param {Y.Snapshot} [snapshot]\n */\nexport const isVisible = (item, snapshot) =>\n snapshot === undefined\n ? !item.deleted\n : (snapshot.sv.has(item.id.client) && /** @type {number} */\n (snapshot.sv.get(item.id.client)) > item.id.clock &&\n !snapshot.ds.hasId(item.id))\n\n/**\n * Either a node if type is YXmlElement or an Array of text nodes if YXmlText\n * @typedef {Map, PModel.Node | Array>} ProsemirrorMapping\n */\n\n/**\n * @typedef {Object} ColorDef\n * @property {string} ColorDef.light\n * @property {string} ColorDef.dark\n */\n\n/**\n * @typedef {Object} YSyncOpts\n * @property {Array} [YSyncOpts.colors]\n * @property {Map} [YSyncOpts.colorMapping]\n * @property {Y.PermanentUserData|null} [YSyncOpts.permanentUserData]\n * @property {ProsemirrorMapping} [YSyncOpts.mapping]\n * @property {function} [YSyncOpts.onFirstRender] Fired when the content from Yjs is initially rendered to ProseMirror\n */\n\n/**\n * @type {Array}\n */\nconst defaultColors = [{ light: '#ecd44433', dark: '#ecd444' }]\n\n/**\n * @param {Map} colorMapping\n * @param {Array} colors\n * @param {string} user\n * @return {ColorDef}\n */\nconst getUserColor = (colorMapping, colors, user) => {\n // @todo do not hit the same color twice if possible\n if (!colorMapping.has(user)) {\n if (colorMapping.size < colors.length) {\n const usedColors = set.create()\n colorMapping.forEach((color) => usedColors.add(color))\n colors = colors.filter((color) => !usedColors.has(color))\n }\n colorMapping.set(user, random.oneOf(colors))\n }\n return /** @type {ColorDef} */ (colorMapping.get(user))\n}\n\n/**\n * This plugin listens to changes in prosemirror view and keeps yXmlState and view in sync.\n *\n * This plugin also keeps references to the type and the shared document so other plugins can access it.\n * @param {Y.XmlFragment} yXmlFragment\n * @param {YSyncOpts} opts\n * @return {any} Returns a prosemirror plugin that binds to this type\n */\nexport const ySyncPlugin = (yXmlFragment, {\n colors = defaultColors,\n colorMapping = new Map(),\n permanentUserData = null,\n onFirstRender = () => {},\n mapping\n} = {}) => {\n let initialContentChanged = false\n const binding = new ProsemirrorBinding(yXmlFragment, mapping)\n const plugin = new Plugin({\n props: {\n editable: (state) => {\n const syncState = ySyncPluginKey.getState(state)\n return syncState.snapshot == null && syncState.prevSnapshot == null\n }\n },\n key: ySyncPluginKey,\n state: {\n /**\n * @returns {any}\n */\n init: (_initargs, _state) => {\n return {\n type: yXmlFragment,\n doc: yXmlFragment.doc,\n binding,\n snapshot: null,\n prevSnapshot: null,\n isChangeOrigin: false,\n isUndoRedoOperation: false,\n addToHistory: true,\n colors,\n colorMapping,\n permanentUserData\n }\n },\n apply: (tr, pluginState) => {\n const change = tr.getMeta(ySyncPluginKey)\n if (change !== undefined) {\n pluginState = Object.assign({}, pluginState)\n for (const key in change) {\n pluginState[key] = change[key]\n }\n }\n pluginState.addToHistory = tr.getMeta('addToHistory') !== false\n // always set isChangeOrigin. If undefined, this is not change origin.\n pluginState.isChangeOrigin = change !== undefined &&\n !!change.isChangeOrigin\n pluginState.isUndoRedoOperation = change !== undefined && !!change.isChangeOrigin && !!change.isUndoRedoOperation\n if (binding.prosemirrorView !== null) {\n if (\n change !== undefined &&\n (change.snapshot != null || change.prevSnapshot != null)\n ) {\n // snapshot changed, rerender next\n eventloop.timeout(0, () => {\n if (binding.prosemirrorView == null) {\n return\n }\n if (change.restore == null) {\n binding._renderSnapshot(\n change.snapshot,\n change.prevSnapshot,\n pluginState\n )\n } else {\n binding._renderSnapshot(\n change.snapshot,\n change.snapshot,\n pluginState\n )\n // reset to current prosemirror state\n delete pluginState.restore\n delete pluginState.snapshot\n delete pluginState.prevSnapshot\n binding.mux(() => {\n binding._prosemirrorChanged(\n binding.prosemirrorView.state.doc\n )\n })\n }\n })\n }\n }\n return pluginState\n }\n },\n view: (view) => {\n binding.initView(view)\n if (mapping == null) {\n // force rerender to update the bindings mapping\n binding._forceRerender()\n }\n onFirstRender()\n return {\n update: () => {\n const pluginState = plugin.getState(view.state)\n if (\n pluginState.snapshot == null && pluginState.prevSnapshot == null\n ) {\n if (\n // If the content doesn't change initially, we don't render anything to Yjs\n // If the content was cleared by a user action, we want to catch the change and\n // represent it in Yjs\n initialContentChanged ||\n view.state.doc.content.findDiffStart(\n view.state.doc.type.createAndFill().content\n ) !== null\n ) {\n initialContentChanged = true\n if (\n pluginState.addToHistory === false &&\n !pluginState.isChangeOrigin\n ) {\n const yUndoPluginState = yUndoPluginKey.getState(view.state)\n /**\n * @type {Y.UndoManager}\n */\n const um = yUndoPluginState && yUndoPluginState.undoManager\n if (um) {\n um.stopCapturing()\n }\n }\n binding.mux(() => {\n /** @type {Y.Doc} */ (pluginState.doc).transact((tr) => {\n tr.meta.set('addToHistory', pluginState.addToHistory)\n binding._prosemirrorChanged(view.state.doc)\n }, ySyncPluginKey)\n })\n }\n }\n },\n destroy: () => {\n binding.destroy()\n }\n }\n }\n })\n return plugin\n}\n\n/**\n * @param {import('prosemirror-state').Transaction} tr\n * @param {ReturnType} relSel\n * @param {ProsemirrorBinding} binding\n */\nconst restoreRelativeSelection = (tr, relSel, binding) => {\n if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {\n if (relSel.type === 'all') {\n tr.setSelection(new AllSelection(tr.doc))\n } else if (relSel.type === 'node') {\n const anchor = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.anchor,\n binding.mapping\n )\n tr.setSelection(NodeSelection.create(tr.doc, anchor))\n } else {\n const anchor = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.anchor,\n binding.mapping\n )\n const head = relativePositionToAbsolutePosition(\n binding.doc,\n binding.type,\n relSel.head,\n binding.mapping\n )\n if (anchor !== null && head !== null) {\n const sel = TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head))\n tr.setSelection(sel)\n }\n }\n }\n}\n\n/**\n * @param {ProsemirrorBinding} pmbinding\n * @param {import('prosemirror-state').EditorState} state\n */\nexport const getRelativeSelection = (pmbinding, state) => ({\n type: /** @type {any} */ (state.selection).jsonID,\n anchor: absolutePositionToRelativePosition(\n state.selection.anchor,\n pmbinding.type,\n pmbinding.mapping\n ),\n head: absolutePositionToRelativePosition(\n state.selection.head,\n pmbinding.type,\n pmbinding.mapping\n )\n})\n\n/**\n * Binding for prosemirror.\n *\n * @protected\n */\nexport class ProsemirrorBinding {\n /**\n * @param {Y.XmlFragment} yXmlFragment The bind source\n * @param {ProsemirrorMapping} mapping\n */\n constructor (yXmlFragment, mapping = new Map()) {\n this.type = yXmlFragment\n /**\n * this will be set once the view is created\n * @type {any}\n */\n this.prosemirrorView = null\n this.mux = createMutex()\n this.mapping = mapping\n /**\n * Is overlapping mark - i.e. mark does not exclude itself.\n *\n * @type {Map}\n */\n this.isOMark = new Map()\n this._observeFunction = this._typeChanged.bind(this)\n /**\n * @type {Y.Doc}\n */\n // @ts-ignore\n this.doc = yXmlFragment.doc\n /**\n * current selection as relative positions in the Yjs model\n */\n this.beforeTransactionSelection = null\n this.beforeAllTransactions = () => {\n if (this.beforeTransactionSelection === null && this.prosemirrorView != null) {\n this.beforeTransactionSelection = getRelativeSelection(\n this,\n this.prosemirrorView.state\n )\n }\n }\n this.afterAllTransactions = () => {\n this.beforeTransactionSelection = null\n }\n this._domSelectionInView = null\n }\n\n /**\n * Create a transaction for changing the prosemirror state.\n *\n * @returns\n */\n get _tr () {\n return this.prosemirrorView.state.tr.setMeta('addToHistory', false)\n }\n\n _isLocalCursorInView () {\n if (!this.prosemirrorView.hasFocus()) return false\n if (environment.isBrowser && this._domSelectionInView === null) {\n // Calculate the domSelectionInView and clear by next tick after all events are finished\n eventloop.timeout(0, () => {\n this._domSelectionInView = null\n })\n this._domSelectionInView = this._isDomSelectionInView()\n }\n return this._domSelectionInView\n }\n\n _isDomSelectionInView () {\n const selection = this.prosemirrorView._root.getSelection()\n\n if (selection == null || selection.anchorNode == null) return false\n\n const range = this.prosemirrorView._root.createRange()\n range.setStart(selection.anchorNode, selection.anchorOffset)\n range.setEnd(selection.focusNode, selection.focusOffset)\n\n // This is a workaround for an edgecase where getBoundingClientRect will\n // return zero values if the selection is collapsed at the start of a newline\n // see reference here: https://stackoverflow.com/a/59780954\n const rects = range.getClientRects()\n if (rects.length === 0) {\n // probably buggy newline behavior, explicitly select the node contents\n if (range.startContainer && range.collapsed) {\n range.selectNodeContents(range.startContainer)\n }\n }\n\n const bounding = range.getBoundingClientRect()\n const documentElement = dom.doc.documentElement\n\n return bounding.bottom >= 0 && bounding.right >= 0 &&\n bounding.left <=\n (window.innerWidth || documentElement.clientWidth || 0) &&\n bounding.top <= (window.innerHeight || documentElement.clientHeight || 0)\n }\n\n /**\n * @param {Y.Snapshot} snapshot\n * @param {Y.Snapshot} prevSnapshot\n */\n renderSnapshot (snapshot, prevSnapshot) {\n if (!prevSnapshot) {\n prevSnapshot = Y.createSnapshot(Y.createIdSet(), new Map())\n }\n this.prosemirrorView.dispatch(\n this._tr.setMeta(ySyncPluginKey, { snapshot, prevSnapshot })\n )\n }\n\n unrenderSnapshot () {\n this.mapping.clear()\n this.mux(() => {\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n tr.setMeta(ySyncPluginKey, { snapshot: null, prevSnapshot: null })\n this.prosemirrorView.dispatch(tr)\n })\n }\n\n _forceRerender () {\n this.mapping.clear()\n this.mux(() => {\n // If this is a forced rerender, this might neither happen as a pm change nor within a Yjs\n // transaction. Then the \"before selection\" doesn't exist. In this case, we need to create a\n // relative position before replacing content. Fixes #126\n const sel = this.beforeTransactionSelection !== null ? null : this.prosemirrorView.state.selection\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n if (sel) {\n /**\n * If the Prosemirror document we just created from this.type is\n * smaller than the previous document, the selection might be\n * out of bound, which would make Prosemirror throw an error.\n */\n const clampedAnchor = math.min(math.max(sel.anchor, 0), tr.doc.content.size)\n const clampedHead = math.min(math.max(sel.head, 0), tr.doc.content.size)\n\n tr.setSelection(TextSelection.create(tr.doc, clampedAnchor, clampedHead))\n }\n this.prosemirrorView.dispatch(\n tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this })\n )\n })\n }\n\n /**\n * @param {Y.Snapshot|Uint8Array} snapshot\n * @param {Y.Snapshot|Uint8Array} prevSnapshot\n * @param {Object} pluginState\n */\n _renderSnapshot (snapshot, prevSnapshot, pluginState) {\n /**\n * The document that contains the full history of this document.\n * @type {Y.Doc}\n */\n let historyDoc = this.doc\n let historyType = this.type\n if (!snapshot) {\n snapshot = Y.snapshot(this.doc)\n }\n if (snapshot instanceof Uint8Array || prevSnapshot instanceof Uint8Array) {\n if (!(snapshot instanceof Uint8Array) || !(prevSnapshot instanceof Uint8Array)) {\n // expected both snapshots to be v2 updates\n error.unexpectedCase()\n }\n historyDoc = new Y.Doc({ gc: false })\n Y.applyUpdateV2(historyDoc, prevSnapshot)\n prevSnapshot = Y.snapshot(historyDoc)\n Y.applyUpdateV2(historyDoc, snapshot)\n snapshot = Y.snapshot(historyDoc)\n if (historyType._item === null) {\n /**\n * If is a root type, we need to find the root key in the initial document\n * and use it to get the history type.\n */\n const rootKey = Array.from(this.doc.share.keys()).find(\n (key) => this.doc.share.get(key) === this.type\n )\n historyType = historyDoc.getXmlFragment(rootKey)\n } else {\n /**\n * If it is a sub type, we use the item id to find the history type.\n */\n const historyStructs =\n historyDoc.store.clients.get(historyType._item.id.client) ?? []\n const itemIndex = Y.findIndexSS(\n historyStructs,\n historyType._item.id.clock\n )\n const item = /** @type {Y.Item} */ (historyStructs[itemIndex])\n const content = /** @type {Y.ContentType} */ (item.content)\n historyType = /** @type {Y.XmlFragment} */ (content.type)\n }\n }\n // clear mapping because we are going to rerender\n this.mapping.clear()\n this.mux(() => {\n historyDoc.transact((transaction) => {\n // before rendering, we are going to sanitize ops and split deleted ops\n // if they were deleted by seperate users.\n /**\n * @type {Y.PermanentUserData}\n */\n const pud = pluginState.permanentUserData\n if (pud) {\n pud.dss.forEach((ds) => {\n Y.iterateStructsByIdSet(transaction, ds, (_item) => {})\n })\n }\n /**\n * @param {'removed'|'added'} type\n * @param {Y.ID} id\n */\n const computeYChange = (type, id) => {\n const user = type === 'added'\n ? pud.getUserByClientId(id.client)\n : pud.getUserByDeletedId(id)\n return {\n user,\n type,\n color: getUserColor(\n pluginState.colorMapping,\n pluginState.colors,\n user\n )\n }\n }\n // Create document fragment and render\n const fragmentContent = Y.typeListToArraySnapshot(\n historyType,\n new Y.Snapshot(prevSnapshot.ds, snapshot.sv)\n ).map((t) => {\n if (\n !t._item.deleted || isVisible(t._item, snapshot) ||\n isVisible(t._item, prevSnapshot)\n ) {\n return createNodeFromYElement(\n t,\n this.prosemirrorView.state.schema,\n { mapping: new Map(), isOMark: new Map() },\n snapshot,\n prevSnapshot,\n computeYChange\n )\n } else {\n // No need to render elements that are not visible by either snapshot.\n // If a client adds and deletes content in the same snapshot the element is not visible by either snapshot.\n return null\n }\n }).filter((n) => n !== null)\n // @ts-ignore\n const tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n this.prosemirrorView.dispatch(\n tr.setMeta(ySyncPluginKey, { isChangeOrigin: true })\n )\n }, ySyncPluginKey)\n })\n }\n\n /**\n * @param {Array>} events\n * @param {Y.Transaction} transaction\n */\n _typeChanged (events, transaction) {\n if (this.prosemirrorView == null) return\n const syncState = ySyncPluginKey.getState(this.prosemirrorView.state)\n if (\n events.length === 0 || syncState.snapshot != null ||\n syncState.prevSnapshot != null\n ) {\n // drop out if snapshot is active\n this.renderSnapshot(syncState.snapshot, syncState.prevSnapshot)\n return\n }\n this.mux(() => {\n /**\n * @param {any} _\n * @param {Y.AbstractType} type\n */\n const delType = (_, type) => this.mapping.delete(type)\n Y.iterateStructsByIdSet(\n transaction,\n transaction.deleteSet,\n (struct) => {\n if (struct.constructor === Y.Item) {\n const type = /** @type {Y.ContentType} */ (/** @type {Y.Item} */ (struct).content).type\n type && this.mapping.delete(type)\n }\n }\n )\n transaction.changed.forEach(delType)\n transaction.changedParentTypes.forEach(delType)\n const fragmentContent = this.type.toArray().map((t) =>\n createNodeIfNotExists(\n /** @type {Y.XmlElement | Y.XmlHook} */ (t),\n this.prosemirrorView.state.schema,\n this\n )\n ).filter((n) => n !== null)\n // @ts-ignore\n let tr = this._tr.replace(\n 0,\n this.prosemirrorView.state.doc.content.size,\n new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0)\n )\n restoreRelativeSelection(tr, this.beforeTransactionSelection, this)\n tr = tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, isUndoRedoOperation: transaction.origin instanceof Y.UndoManager })\n if (\n this.beforeTransactionSelection !== null && this._isLocalCursorInView()\n ) {\n tr.scrollIntoView()\n }\n this.prosemirrorView.dispatch(tr)\n })\n }\n\n /**\n * @param {import('prosemirror-model').Node} doc\n */\n _prosemirrorChanged (doc) {\n this.doc.transact(() => {\n updateYFragment(this.doc, this.type, doc, this)\n this.beforeTransactionSelection = getRelativeSelection(\n this,\n this.prosemirrorView.state\n )\n }, ySyncPluginKey)\n }\n\n /**\n * View is ready to listen to changes. Register observers.\n * @param {any} prosemirrorView\n */\n initView (prosemirrorView) {\n if (this.prosemirrorView != null) this.destroy()\n this.prosemirrorView = prosemirrorView\n this.doc.on('beforeAllTransactions', this.beforeAllTransactions)\n this.doc.on('afterAllTransactions', this.afterAllTransactions)\n this.type.observeDeep(this._observeFunction)\n }\n\n destroy () {\n if (this.prosemirrorView == null) return\n this.prosemirrorView = null\n this.type.unobserveDeep(this._observeFunction)\n this.doc.off('beforeAllTransactions', this.beforeAllTransactions)\n this.doc.off('afterAllTransactions', this.afterAllTransactions)\n }\n}\n\n/**\n * @private\n * @param {Y.XmlElement | Y.XmlHook} el\n * @param {PModel.Schema} schema\n * @param {BindingMetadata} meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {PModel.Node | null}\n */\nconst createNodeIfNotExists = (\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const node = /** @type {PModel.Node} */ (meta.mapping.get(el))\n if (node === undefined) {\n if (el instanceof Y.XmlElement) {\n return createNodeFromYElement(\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n } else {\n throw error.methodUnimplemented() // we are currently not handling hooks\n }\n }\n return node\n}\n\n/**\n * @private\n * @param {Y.XmlElement} el\n * @param {any} schema\n * @param {BindingMetadata} meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {PModel.Node | null} Returns node if node could be created. Otherwise it deletes the yjs type and returns null\n */\nexport const createNodeFromYElement = (\n el,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const children = []\n /**\n * @param {Y.XmlElement | Y.XmlText} type\n */\n const createChildren = (type) => {\n if (type instanceof Y.XmlElement) {\n const n = createNodeIfNotExists(\n type,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n if (n !== null) {\n children.push(n)\n }\n } else {\n // If the next ytext exists and was created by us, move the content to the current ytext.\n // This is a fix for #160 -- duplication of characters when two Y.Text exist next to each\n // other.\n const nextytext = /** @type {Y.ContentType} */ (type._item.right?.content)?.type\n if (nextytext instanceof Y.Text && !nextytext._item.deleted && nextytext._item.id.client === nextytext.doc.clientID) {\n type.applyDelta([\n { retain: type.length },\n ...nextytext.toDelta()\n ])\n nextytext.doc.transact(tr => {\n nextytext._item.delete(tr)\n })\n }\n // now create the prosemirror text nodes\n const ns = createTextNodesFromYText(\n type,\n schema,\n meta,\n snapshot,\n prevSnapshot,\n computeYChange\n )\n if (ns !== null) {\n ns.forEach((textchild) => {\n if (textchild !== null) {\n children.push(textchild)\n }\n })\n }\n }\n }\n if (snapshot === undefined || prevSnapshot === undefined) {\n el.toArray().forEach(createChildren)\n } else {\n Y.typeListToArraySnapshot(el, new Y.Snapshot(prevSnapshot.ds, snapshot.sv))\n .forEach(createChildren)\n }\n try {\n const attrs = el.getAttributes(snapshot)\n if (snapshot !== undefined) {\n if (!isVisible(/** @type {Y.Item} */ (el._item), snapshot)) {\n attrs.ychange = computeYChange\n ? computeYChange('removed', /** @type {Y.Item} */ (el._item).id)\n : { type: 'removed' }\n } else if (!isVisible(/** @type {Y.Item} */ (el._item), prevSnapshot)) {\n attrs.ychange = computeYChange\n ? computeYChange('added', /** @type {Y.Item} */ (el._item).id)\n : { type: 'added' }\n }\n }\n const node = schema.node(el.nodeName, attrs, children)\n meta.mapping.set(el, node)\n return node\n } catch (e) {\n // an error occured while creating the node. This is probably a result of a concurrent action.\n /** @type {Y.Doc} */ (el.doc).transact((transaction) => {\n /** @type {Y.Item} */ (el._item).delete(transaction)\n }, ySyncPluginKey)\n meta.mapping.delete(el)\n return null\n }\n}\n\n/**\n * @private\n * @param {Y.XmlText} text\n * @param {import('prosemirror-model').Schema} schema\n * @param {BindingMetadata} _meta\n * @param {Y.Snapshot} [snapshot]\n * @param {Y.Snapshot} [prevSnapshot]\n * @param {function('removed' | 'added', Y.ID):any} [computeYChange]\n * @return {Array|null}\n */\nconst createTextNodesFromYText = (\n text,\n schema,\n _meta,\n snapshot,\n prevSnapshot,\n computeYChange\n) => {\n const nodes = []\n const deltas = text.toDelta(snapshot, prevSnapshot, computeYChange)\n try {\n for (let i = 0; i < deltas.length; i++) {\n const delta = deltas[i]\n nodes.push(schema.text(delta.insert, attributesToMarks(delta.attributes, schema)))\n }\n } catch (e) {\n // an error occured while creating the node. This is probably a result of a concurrent action.\n /** @type {Y.Doc} */ (text.doc).transact((transaction) => {\n /** @type {Y.Item} */ (text._item).delete(transaction)\n }, ySyncPluginKey)\n return null\n }\n // @ts-ignore\n return nodes\n}\n\n/**\n * @private\n * @param {Array} nodes prosemirror node\n * @param {BindingMetadata} meta\n * @return {Y.XmlText}\n */\nconst createTypeFromTextNodes = (nodes, meta) => {\n const type = new Y.XmlText()\n const delta = nodes.map((node) => ({\n // @ts-ignore\n insert: node.text,\n attributes: marksToAttributes(node.marks, meta)\n }))\n type.applyDelta(delta)\n meta.mapping.set(type, nodes)\n return type\n}\n\n/**\n * @private\n * @param {any} node prosemirror node\n * @param {BindingMetadata} meta\n * @return {Y.XmlElement}\n */\nconst createTypeFromElementNode = (node, meta) => {\n const type = new Y.XmlElement(node.type.name)\n for (const key in node.attrs) {\n const val = node.attrs[key]\n if (val !== null && key !== 'ychange') {\n type.setAttribute(key, val)\n }\n }\n type.insert(\n 0,\n normalizePNodeContent(node).map((n) =>\n createTypeFromTextOrElementNode(n, meta)\n )\n )\n meta.mapping.set(type, node)\n return type\n}\n\n/**\n * @private\n * @param {PModel.Node|Array} node prosemirror text node\n * @param {BindingMetadata} meta\n * @return {Y.XmlElement|Y.XmlText}\n */\nconst createTypeFromTextOrElementNode = (node, meta) =>\n node instanceof Array\n ? createTypeFromTextNodes(node, meta)\n : createTypeFromElementNode(node, meta)\n\n/**\n * @param {any} val\n */\nconst isObject = (val) => typeof val === 'object' && val !== null\n\n/**\n * @param {any} pattrs\n * @param {any} yattrs\n */\nconst equalAttrs = (pattrs, yattrs) => {\n const keys = Object.keys(pattrs).filter((key) => pattrs[key] !== null)\n let eq =\n keys.length ===\n (yattrs == null ? 0 : Object.keys(yattrs).filter((key) => yattrs[key] !== null).length)\n for (let i = 0; i < keys.length && eq; i++) {\n const key = keys[i]\n const l = pattrs[key]\n const r = yattrs[key]\n eq = key === 'ychange' || l === r ||\n (isObject(l) && isObject(r) && equalAttrs(l, r))\n }\n return eq\n}\n\n/**\n * @typedef {Array|PModel.Node>} NormalizedPNodeContent\n */\n\n/**\n * @param {any} pnode\n * @return {NormalizedPNodeContent}\n */\nconst normalizePNodeContent = (pnode) => {\n const c = pnode.content.content\n const res = []\n for (let i = 0; i < c.length; i++) {\n const n = c[i]\n if (n.isText) {\n const textNodes = []\n for (let tnode = c[i]; i < c.length && tnode.isText; tnode = c[++i]) {\n textNodes.push(tnode)\n }\n i--\n res.push(textNodes)\n } else {\n res.push(n)\n }\n }\n return res\n}\n\n/**\n * @param {Y.XmlText} ytext\n * @param {Array} ptexts\n */\nconst equalYTextPText = (ytext, ptexts) => {\n const delta = ytext.toDelta()\n return delta.length === ptexts.length &&\n delta.every(/** @type {(d:any,i:number) => boolean} */ (d, i) =>\n d.insert === /** @type {any} */ (ptexts[i]).text &&\n object.keys(d.attributes || {}).length === ptexts[i].marks.length &&\n object.every(d.attributes, (attr, yattrname) => {\n const markname = yattr2markname(yattrname)\n const pmarks = ptexts[i].marks\n return equalAttrs(attr, pmarks.find(/** @param {any} mark */ mark => mark.type.name === markname)?.attrs)\n })\n )\n}\n\n/**\n * @param {Y.XmlElement|Y.XmlText|Y.XmlHook} ytype\n * @param {any|Array} pnode\n */\nconst equalYTypePNode = (ytype, pnode) => {\n if (\n ytype instanceof Y.XmlElement && !(pnode instanceof Array) &&\n matchNodeName(ytype, pnode)\n ) {\n const normalizedContent = normalizePNodeContent(pnode)\n return ytype._length === normalizedContent.length &&\n equalAttrs(ytype.getAttributes(), pnode.attrs) &&\n ytype.toArray().every((ychild, i) =>\n equalYTypePNode(ychild, normalizedContent[i])\n )\n }\n return ytype instanceof Y.XmlText && pnode instanceof Array &&\n equalYTextPText(ytype, pnode)\n}\n\n/**\n * @param {PModel.Node | Array | undefined} mapped\n * @param {PModel.Node | Array} pcontent\n */\nconst mappedIdentity = (mapped, pcontent) =>\n mapped === pcontent ||\n (mapped instanceof Array && pcontent instanceof Array &&\n mapped.length === pcontent.length && mapped.every((a, i) =>\n pcontent[i] === a\n ))\n\n/**\n * @param {Y.XmlElement} ytype\n * @param {PModel.Node} pnode\n * @param {BindingMetadata} meta\n * @return {{ foundMappedChild: boolean, equalityFactor: number }}\n */\nconst computeChildEqualityFactor = (ytype, pnode, meta) => {\n const yChildren = ytype.toArray()\n const pChildren = normalizePNodeContent(pnode)\n const pChildCnt = pChildren.length\n const yChildCnt = yChildren.length\n const minCnt = math.min(yChildCnt, pChildCnt)\n let left = 0\n let right = 0\n let foundMappedChild = false\n for (; left < minCnt; left++) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n if (mappedIdentity(meta.mapping.get(leftY), leftP)) {\n foundMappedChild = true // definite (good) match!\n } else if (!equalYTypePNode(leftY, leftP)) {\n break\n }\n }\n for (; left + right < minCnt; right++) {\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (mappedIdentity(meta.mapping.get(rightY), rightP)) {\n foundMappedChild = true\n } else if (!equalYTypePNode(rightY, rightP)) {\n break\n }\n }\n return {\n equalityFactor: left + right,\n foundMappedChild\n }\n}\n\n/**\n * @param {Y.Text} ytext\n */\nconst ytextTrans = (ytext) => {\n let str = ''\n /**\n * @type {Y.Item|null}\n */\n let n = ytext._start\n const nAttrs = {}\n while (n !== null) {\n if (!n.deleted) {\n if (n.countable && n.content instanceof Y.ContentString) {\n str += n.content.str\n } else if (n.content instanceof Y.ContentFormat) {\n nAttrs[n.content.key] = null\n }\n }\n n = n.right\n }\n return {\n str,\n nAttrs\n }\n}\n\n/**\n * @todo test this more\n *\n * @param {Y.Text} ytext\n * @param {Array} ptexts\n * @param {BindingMetadata} meta\n */\nconst updateYText = (ytext, ptexts, meta) => {\n meta.mapping.set(ytext, ptexts)\n const { nAttrs, str } = ytextTrans(ytext)\n const content = ptexts.map((p) => ({\n insert: /** @type {any} */ (p).text,\n attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks, meta))\n }))\n const { insert, remove, index } = simpleDiff(\n str,\n content.map((c) => c.insert).join('')\n )\n ytext.delete(index, remove)\n ytext.insert(index, insert)\n ytext.applyDelta(\n content.map((c) => ({ retain: c.insert.length, attributes: c.attributes }))\n )\n}\n\nconst hashedMarkNameRegex = /(.*)(--[a-zA-Z0-9+/=]{8})$/\n/**\n * @param {string} attrName\n */\nexport const yattr2markname = attrName => hashedMarkNameRegex.exec(attrName)?.[1] ?? attrName\n\n/**\n * @todo move this to markstoattributes\n *\n * @param {Object} attrs\n * @param {import('prosemirror-model').Schema} schema\n */\nexport const attributesToMarks = (attrs, schema) => {\n /**\n * @type {Array}\n */\n const marks = []\n for (const markName in attrs) {\n // remove hashes if necessary\n marks.push(schema.mark(yattr2markname(markName), attrs[markName]))\n }\n return marks\n}\n\n/**\n * @param {Array} marks\n * @param {BindingMetadata} meta\n */\nconst marksToAttributes = (marks, meta) => {\n const pattrs = {}\n marks.forEach((mark) => {\n if (mark.type.name !== 'ychange') {\n const isOverlapping = map.setIfUndefined(meta.isOMark, mark.type, () => !mark.type.excludes(mark.type))\n pattrs[isOverlapping ? `${mark.type.name}--${utils.hashOfJSON(mark.toJSON())}` : mark.type.name] = mark.attrs\n }\n })\n return pattrs\n}\n\n/**\n * Update a yDom node by syncing the current content of the prosemirror node.\n *\n * This is a y-prosemirror internal feature that you can use at your own risk.\n *\n * @private\n * @unstable\n *\n * @param {{transact: Function}} y\n * @param {Y.XmlFragment} yDomFragment\n * @param {any} pNode\n * @param {BindingMetadata} meta\n */\nexport const updateYFragment = (y, yDomFragment, pNode, meta) => {\n if (\n yDomFragment instanceof Y.XmlElement &&\n yDomFragment.nodeName !== pNode.type.name\n ) {\n throw new Error('node name mismatch!')\n }\n meta.mapping.set(yDomFragment, pNode)\n // update attributes\n if (yDomFragment instanceof Y.XmlElement) {\n const yDomAttrs = yDomFragment.getAttributes()\n const pAttrs = pNode.attrs\n for (const key in pAttrs) {\n if (pAttrs[key] !== null) {\n if (yDomAttrs[key] !== pAttrs[key] && key !== 'ychange') {\n yDomFragment.setAttribute(key, pAttrs[key])\n }\n } else {\n yDomFragment.removeAttribute(key)\n }\n }\n // remove all keys that are no longer in pAttrs\n for (const key in yDomAttrs) {\n if (pAttrs[key] === undefined) {\n yDomFragment.removeAttribute(key)\n }\n }\n }\n // update children\n const pChildren = normalizePNodeContent(pNode)\n const pChildCnt = pChildren.length\n const yChildren = yDomFragment.toArray()\n const yChildCnt = yChildren.length\n const minCnt = math.min(pChildCnt, yChildCnt)\n let left = 0\n let right = 0\n // find number of matching elements from left\n for (; left < minCnt; left++) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n if (!mappedIdentity(meta.mapping.get(leftY), leftP)) {\n if (equalYTypePNode(leftY, leftP)) {\n // update mapping\n meta.mapping.set(leftY, leftP)\n } else {\n break\n }\n }\n }\n // find number of matching elements from right\n for (; right + left < minCnt; right++) {\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (!mappedIdentity(meta.mapping.get(rightY), rightP)) {\n if (equalYTypePNode(rightY, rightP)) {\n // update mapping\n meta.mapping.set(rightY, rightP)\n } else {\n break\n }\n }\n }\n y.transact(() => {\n // try to compare and update\n while (yChildCnt - left - right > 0 && pChildCnt - left - right > 0) {\n const leftY = yChildren[left]\n const leftP = pChildren[left]\n const rightY = yChildren[yChildCnt - right - 1]\n const rightP = pChildren[pChildCnt - right - 1]\n if (leftY instanceof Y.XmlText && leftP instanceof Array) {\n if (!equalYTextPText(leftY, leftP)) {\n updateYText(leftY, leftP, meta)\n }\n left += 1\n } else {\n let updateLeft = leftY instanceof Y.XmlElement &&\n matchNodeName(leftY, leftP)\n let updateRight = rightY instanceof Y.XmlElement &&\n matchNodeName(rightY, rightP)\n if (updateLeft && updateRight) {\n // decide which which element to update\n const equalityLeft = computeChildEqualityFactor(\n /** @type {Y.XmlElement} */ (leftY),\n /** @type {PModel.Node} */ (leftP),\n meta\n )\n const equalityRight = computeChildEqualityFactor(\n /** @type {Y.XmlElement} */ (rightY),\n /** @type {PModel.Node} */ (rightP),\n meta\n )\n if (\n equalityLeft.foundMappedChild && !equalityRight.foundMappedChild\n ) {\n updateRight = false\n } else if (\n !equalityLeft.foundMappedChild && equalityRight.foundMappedChild\n ) {\n updateLeft = false\n } else if (\n equalityLeft.equalityFactor < equalityRight.equalityFactor\n ) {\n updateLeft = false\n } else {\n updateRight = false\n }\n }\n if (updateLeft) {\n updateYFragment(\n y,\n /** @type {Y.XmlFragment} */ (leftY),\n /** @type {PModel.Node} */ (leftP),\n meta\n )\n left += 1\n } else if (updateRight) {\n updateYFragment(\n y,\n /** @type {Y.XmlFragment} */ (rightY),\n /** @type {PModel.Node} */ (rightP),\n meta\n )\n right += 1\n } else {\n meta.mapping.delete(yDomFragment.get(left))\n yDomFragment.delete(left, 1)\n yDomFragment.insert(left, [\n createTypeFromTextOrElementNode(leftP, meta)\n ])\n left += 1\n }\n }\n }\n const yDelLen = yChildCnt - left - right\n if (\n yChildCnt === 1 && pChildCnt === 0 && yChildren[0] instanceof Y.XmlText\n ) {\n meta.mapping.delete(yChildren[0])\n // Edge case handling https://github.com/yjs/y-prosemirror/issues/108\n // Only delete the content of the Y.Text to retain remote changes on the same Y.Text object\n yChildren[0].delete(0, yChildren[0].length)\n } else if (yDelLen > 0) {\n yDomFragment.slice(left, left + yDelLen).forEach(type => meta.mapping.delete(type))\n yDomFragment.delete(left, yDelLen)\n }\n if (left + right < pChildCnt) {\n const ins = []\n for (let i = left; i < pChildCnt - right; i++) {\n ins.push(createTypeFromTextOrElementNode(pChildren[i], meta))\n }\n yDomFragment.insert(left, ins)\n }\n }, ySyncPluginKey)\n}\n\n/**\n * @function\n * @param {Y.XmlElement} yElement\n * @param {any} pNode Prosemirror Node\n */\nconst matchNodeName = (yElement, pNode) =>\n !(pNode instanceof Array) && yElement.nodeName === pNode.type.name\n","import { updateYFragment, createNodeFromYElement, yattr2markname, createEmptyMeta } from './plugins/sync-plugin.js' // eslint-disable-line\nimport { ySyncPluginKey } from './plugins/keys.js'\nimport * as Y from '@y/y'\nimport { EditorView } from 'prosemirror-view' // eslint-disable-line\nimport { Node, Schema, Fragment } from 'prosemirror-model' // eslint-disable-line\nimport * as error from 'lib0/error'\nimport * as map from 'lib0/map'\nimport * as eventloop from 'lib0/eventloop'\n\n/**\n * Either a node if type is YXmlElement or an Array of text nodes if YXmlText\n * @typedef {Map>} ProsemirrorMapping\n */\n\n/**\n * Is null if no timeout is in progress.\n * Is defined if a timeout is in progress.\n * Maps from view\n * @type {Map>|null}\n */\nlet viewsToUpdate = null\n\nconst updateMetas = () => {\n const ups = /** @type {Map>} */ (viewsToUpdate)\n viewsToUpdate = null\n ups.forEach((metas, view) => {\n const tr = view.state.tr\n const syncState = ySyncPluginKey.getState(view.state)\n if (syncState && syncState.binding && !syncState.binding.isDestroyed) {\n metas.forEach((val, key) => {\n tr.setMeta(key, val)\n })\n view.dispatch(tr)\n }\n })\n}\n\nexport const setMeta = (view, key, value) => {\n if (!viewsToUpdate) {\n viewsToUpdate = new Map()\n eventloop.timeout(0, updateMetas)\n }\n map.setIfUndefined(viewsToUpdate, view, map.create).set(key, value)\n}\n\n/**\n * Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).\n *\n * @param {number} pos\n * @param {Y.XmlFragment} type\n * @param {Node} pmDoc\n * @param {AbstractAttributionManager} am\n * @return {Y.RelativePosition} relative position\n */\nexport const absolutePositionToRelativePosition = (pos, type, pmDoc, am = Y.noAttributionsManager) => {\n if (pos === 0) {\n // if the type is later populated, we want to retain the 0 position (hence assoc=-1)\n return Y.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0, am)\n }\n const resolvedPos = pmDoc.resolve(pos)\n const depth = resolvedPos.depth\n // Navigate through the Y.js structure using the path from ResolvedPos\n let currentYType = type\n for (let d = 0; d < depth; d++) {\n const childIndex = resolvedPos.index(d)\n currentYType = currentYType.get(childIndex, am) // @todo get method should support attribution manager\n }\n // Use the parent offset as the position within the target Y.js type\n const offset = resolvedPos.parentOffset\n\n return Y.createRelativePositionFromTypeIndex(currentYType, offset,\n // If we are at the end of a type, then we want to be associated to the end of the type\n offset > 0 && offset === currentYType.length ? -1 : 0, am)\n}\n\n/**\n * @param {Y.Doc} y\n * @param {Y.XmlFragment} documentType Top level type that is bound to pView\n * @param {Y.RelativePosition} relPos Encoded Yjs based relative position\n * @param {Node} pmDoc\n * @return {null|number}\n */\nexport const relativePositionToAbsolutePosition = (y, documentType, relPos, pmDoc) => {\n // (1) decodedPos.index is the absolute position starting at the referred prosemirror node.\n const decodedPos = Y.createAbsolutePositionFromRelativePosition(relPos, y)\n if (decodedPos === null || (decodedPos.type !== documentType && !Y.isParentOf(documentType, decodedPos.type._item))) {\n return null\n }\n /*\n * Now, we need to compute the nested position.\n * - Compute the path of the targeted type Y.getPathTo(decodedPos.type).\n * - (2) Use that path to calculate the absolute prosemirror position based on the prosemirror state.\n * result = (1) + (2)\n */\n const path = Y.getPathTo(documentType, decodedPos.type)\n let pos = 1 // Start inside the document\n let currentNode = pmDoc\n // Traverse the path to find the nested position\n for (let i = 0; i < path.length; i++) {\n const childIndex = path[i]\n // Add sizes of all previous siblings\n for (let j = 0; j < childIndex; j++) {\n pos += currentNode.child(j).nodeSize\n }\n // enter node\n pos += 1\n currentNode = currentNode.child(childIndex)\n }\n // Add the offset within the target node\n return pos + decodedPos.index\n}\n\n/**\n * Utility function for converting an Y.Fragment to a ProseMirror fragment.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n */\nexport const yXmlFragmentToProseMirrorFragment = (yXmlFragment, schema) => {\n const fragmentContent = yXmlFragment.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n schema,\n createEmptyMeta()\n )\n ).filter((n) => n !== null)\n return Fragment.fromArray(fragmentContent)\n}\n\n/**\n * Utility function for converting an Y.Fragment to a ProseMirror node.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n */\nexport const yXmlFragmentToProseMirrorRootNode = (yXmlFragment, schema) =>\n schema.topNodeType.create(null, yXmlFragmentToProseMirrorFragment(yXmlFragment, schema))\n\n/**\n * The initial ProseMirror content should be supplied by Yjs. This function transforms a Y.Fragment\n * to a ProseMirror Doc node and creates a mapping that is used by the sync plugin.\n *\n * @param {Y.XmlFragment} yXmlFragment\n * @param {Schema} schema\n *\n * @todo deprecate mapping property\n */\nexport const initProseMirrorDoc = (yXmlFragment, schema) => {\n const meta = createEmptyMeta()\n const fragmentContent = yXmlFragment.toArray().map((t) =>\n createNodeFromYElement(\n /** @type {Y.XmlElement} */ (t),\n schema,\n meta\n )\n ).filter((n) => n !== null)\n const doc = schema.topNodeType.create(null, Fragment.fromArray(fragmentContent))\n return { doc, meta, mapping: meta.mapping }\n}\n\n/**\n * Utility method to convert a Prosemirror Doc Node into a Y.Doc.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Node} doc\n * @param {string} xmlFragment\n * @return {Y.Doc}\n */\nexport function prosemirrorToYDoc (doc, xmlFragment = 'prosemirror') {\n const ydoc = new Y.Doc()\n const type = /** @type {Y.XmlFragment} */ (ydoc.get(xmlFragment, Y.XmlFragment))\n if (!type.doc) {\n return ydoc\n }\n\n prosemirrorToYXmlFragment(doc, type)\n return type.doc\n}\n\n/**\n * Utility method to update an empty Y.XmlFragment with content from a Prosemirror Doc Node.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * Note: The Y.XmlFragment does not need to be part of a Y.Doc document at the time that this\n * method is called, but it must be added before any other operations are performed on it.\n *\n * @param {Node} doc prosemirror document.\n * @param {Y.XmlFragment} [xmlFragment] If supplied, an xml fragment to be\n * populated from the prosemirror state; otherwise a new XmlFragment will be created.\n * @return {Y.XmlFragment}\n */\nexport function prosemirrorToYXmlFragment (doc, xmlFragment) {\n const type = xmlFragment || new Y.XmlFragment()\n const ydoc = type.doc ? type.doc : { transact: (transaction) => transaction(undefined) }\n updateYFragment(ydoc, type, doc, { mapping: new Map(), isOMark: new Map() })\n return type\n}\n\n/**\n * Utility method to convert Prosemirror compatible JSON into a Y.Doc.\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Schema} schema\n * @param {any} state\n * @param {string} xmlFragment\n * @return {Y.Doc}\n */\nexport function prosemirrorJSONToYDoc (schema, state, xmlFragment = 'prosemirror') {\n const doc = Node.fromJSON(schema, state)\n return prosemirrorToYDoc(doc, xmlFragment)\n}\n\n/**\n * Utility method to convert Prosemirror compatible JSON to a Y.XmlFragment\n *\n * This can be used when importing existing content to Y.Doc for the first time,\n * note that this should not be used to rehydrate a Y.Doc from a database once\n * collaboration has begun as all history will be lost\n *\n * @param {Schema} schema\n * @param {any} state\n * @param {Y.XmlFragment} [xmlFragment] If supplied, an xml fragment to be\n * populated from the prosemirror state; otherwise a new XmlFragment will be created.\n * @return {Y.XmlFragment}\n */\nexport function prosemirrorJSONToYXmlFragment (schema, state, xmlFragment) {\n const doc = Node.fromJSON(schema, state)\n return prosemirrorToYXmlFragment(doc, xmlFragment)\n}\n\n/**\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to a Prosemirror Doc node.\n *\n * @param {Schema} schema\n * @param {Y.Doc} ydoc\n * @return {Node}\n */\nexport function yDocToProsemirror (schema, ydoc) {\n const state = yDocToProsemirrorJSON(ydoc)\n return Node.fromJSON(schema, state)\n}\n\n/**\n *\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.XmlFragment to a Prosemirror Doc node.\n *\n * @param {Schema} schema\n * @param {Y.XmlFragment} xmlFragment\n * @return {Node}\n */\nexport function yXmlFragmentToProsemirror (schema, xmlFragment) {\n const state = yXmlFragmentToProsemirrorJSON(xmlFragment)\n return Node.fromJSON(schema, state)\n}\n\n/**\n *\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to Prosemirror compatible JSON.\n *\n * @param {Y.Doc} ydoc\n * @param {string} xmlFragment\n * @return {Record}\n */\nexport function yDocToProsemirrorJSON (\n ydoc,\n xmlFragment = 'prosemirror'\n) {\n return yXmlFragmentToProsemirrorJSON(ydoc.getXmlFragment(xmlFragment))\n}\n\n/**\n * @deprecated Use `yXmlFragmentToProseMirrorRootNode` instead\n *\n * Utility method to convert a Y.Doc to Prosemirror compatible JSON.\n *\n * @param {Y.XmlFragment} xmlFragment The fragment, which must be part of a Y.Doc.\n * @return {Record}\n */\nexport function yXmlFragmentToProsemirrorJSON (xmlFragment) {\n const items = xmlFragment.toArray()\n\n /**\n * @param {Y.AbstractType} item\n */\n const serialize = item => {\n /**\n * @type {Object} NodeObject\n * @property {string} NodeObject.type\n * @property {Record=} NodeObject.attrs\n * @property {Array=} NodeObject.content\n */\n let response\n\n // TODO: Must be a better way to detect text nodes than this\n if (item instanceof Y.XmlText) {\n const delta = item.toDelta()\n response = delta.map(/** @param {any} d */ (d) => {\n const text = {\n type: 'text',\n text: d.insert\n }\n if (d.attributes) {\n text.marks = Object.keys(d.attributes).map((type_) => {\n const attrs = d.attributes[type_]\n const type = yattr2markname(type_)\n const mark = {\n type\n }\n if (Object.keys(attrs)) {\n mark.attrs = attrs\n }\n return mark\n })\n }\n return text\n })\n } else if (item instanceof Y.XmlElement) {\n response = {\n type: item.nodeName\n }\n\n const attrs = item.getAttributes()\n if (Object.keys(attrs).length) {\n response.attrs = attrs\n }\n\n const children = item.toArray()\n if (children.length) {\n response.content = children.map(serialize).flat()\n }\n } else {\n // expected either Y.XmlElement or Y.XmlText\n error.unexpectedCase()\n }\n\n return response\n }\n\n return {\n type: 'doc',\n content: items.map(serialize)\n }\n}\n","import * as Y from '@y/y'\nimport { Decoration, DecorationSet } from \"prosemirror-view\"; // eslint-disable-line\nimport { Plugin } from \"prosemirror-state\"; // eslint-disable-line\nimport { Awareness } from \"@y/protocols/awareness\"; // eslint-disable-line\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n setMeta\n} from '../lib.js'\nimport { yCursorPluginKey, ySyncPluginKey } from './keys.js'\n\nimport * as math from 'lib0/math'\n\n/**\n * Default awareness state filter\n *\n * @param {number} currentClientId current client id\n * @param {number} userClientId user client id\n * @param {any} _user user data\n * @return {boolean}\n */\nexport const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId\n\n/**\n * Default generator for a cursor element\n *\n * @param {any} user user data\n * @return {HTMLElement}\n */\nexport const defaultCursorBuilder = (user) => {\n const cursor = document.createElement('span')\n cursor.classList.add('ProseMirror-yjs-cursor')\n cursor.setAttribute('style', `border-color: ${user.color}`)\n const userDiv = document.createElement('div')\n userDiv.setAttribute('style', `background-color: ${user.color}`)\n userDiv.insertBefore(document.createTextNode(user.name), null)\n const nonbreakingSpace1 = document.createTextNode('\\u2060')\n const nonbreakingSpace2 = document.createTextNode('\\u2060')\n cursor.insertBefore(nonbreakingSpace1, null)\n cursor.insertBefore(userDiv, null)\n cursor.insertBefore(nonbreakingSpace2, null)\n return cursor\n}\n\n/**\n * Default generator for the selection attributes\n *\n * @param {any} user user data\n * @return {import('prosemirror-view').DecorationAttrs}\n */\nexport const defaultSelectionBuilder = (user) => {\n return {\n style: `background-color: ${user.color}70`,\n class: 'ProseMirror-yjs-selection'\n }\n}\n\nconst rxValidColor = /^#[0-9a-fA-F]{6}$/\n\n/**\n * @param {any} state\n * @param {Awareness} awareness\n * @param {function(number, number, any):boolean} awarenessFilter\n * @param {(user: { name: string, color: string }, clientId: number) => Element} createCursor\n * @param {(user: { name: string, color: string }, clientId: number) => import('prosemirror-view').DecorationAttrs} createSelection\n * @return {any} DecorationSet\n */\nexport const createDecorations = (\n state,\n awareness,\n awarenessFilter,\n createCursor,\n createSelection\n) => {\n const ystate = ySyncPluginKey.getState(state)\n const y = ystate.doc\n const decorations = []\n if (\n ystate.snapshot != null || ystate.prevSnapshot != null ||\n ystate.binding.mapping.size === 0\n ) {\n // do not render cursors while snapshot is active\n return DecorationSet.create(state.doc, [])\n }\n awareness.getStates().forEach((aw, clientId) => {\n if (!awarenessFilter(y.clientID, clientId, aw)) {\n return\n }\n\n if (aw.cursor != null) {\n const user = aw.user || {}\n if (user.color == null) {\n user.color = '#ffa500'\n } else if (!rxValidColor.test(user.color)) {\n // We only support 6-digit RGB colors in y-prosemirror\n console.warn('A user uses an unsupported color format', user)\n }\n if (user.name == null) {\n user.name = `User: ${clientId}`\n }\n let anchor = relativePositionToAbsolutePosition(\n y,\n ystate.type,\n Y.createRelativePositionFromJSON(aw.cursor.anchor),\n ystate.binding.mapping\n )\n let head = relativePositionToAbsolutePosition(\n y,\n ystate.type,\n Y.createRelativePositionFromJSON(aw.cursor.head),\n ystate.binding.mapping\n )\n if (anchor !== null && head !== null) {\n const maxsize = math.max(state.doc.content.size - 1, 0)\n anchor = math.min(anchor, maxsize)\n head = math.min(head, maxsize)\n decorations.push(\n Decoration.widget(head, () => createCursor(user, clientId), {\n key: clientId + '',\n side: 10\n })\n )\n const from = math.min(anchor, head)\n const to = math.max(anchor, head)\n decorations.push(\n Decoration.inline(from, to, createSelection(user, clientId), {\n inclusiveEnd: true,\n inclusiveStart: false\n })\n )\n }\n }\n })\n return DecorationSet.create(state.doc, decorations)\n}\n\n/**\n * A prosemirror plugin that listens to awareness information on Yjs.\n * This requires that a `prosemirrorPlugin` is also bound to the prosemirror.\n *\n * @public\n * @param {Awareness} awareness\n * @param {object} opts\n * @param {function(any, any, any):boolean} [opts.awarenessStateFilter]\n * @param {(user: any, clientId: number) => HTMLElement} [opts.cursorBuilder]\n * @param {(user: any, clientId: number) => import('prosemirror-view').DecorationAttrs} [opts.selectionBuilder]\n * @param {function(any):any} [opts.getSelection]\n * @param {string} [cursorStateField] By default all editor bindings use the awareness 'cursor' field to propagate cursor information.\n * @return {any}\n */\nexport const yCursorPlugin = (\n awareness,\n {\n awarenessStateFilter = defaultAwarenessStateFilter,\n cursorBuilder = defaultCursorBuilder,\n selectionBuilder = defaultSelectionBuilder,\n getSelection = (state) => state.selection\n } = {},\n cursorStateField = 'cursor'\n) =>\n new Plugin({\n key: yCursorPluginKey,\n state: {\n init (_, state) {\n return createDecorations(\n state,\n awareness,\n awarenessStateFilter,\n cursorBuilder,\n selectionBuilder\n )\n },\n apply (tr, prevState, _oldState, newState) {\n const ystate = ySyncPluginKey.getState(newState)\n const yCursorState = tr.getMeta(yCursorPluginKey)\n if (\n (ystate && ystate.isChangeOrigin) ||\n (yCursorState && yCursorState.awarenessUpdated)\n ) {\n return createDecorations(\n newState,\n awareness,\n awarenessStateFilter,\n cursorBuilder,\n selectionBuilder\n )\n }\n return prevState.map(tr.mapping, tr.doc)\n }\n },\n props: {\n decorations: (state) => {\n return yCursorPluginKey.getState(state)\n }\n },\n view: (view) => {\n const awarenessListener = () => {\n // @ts-ignore\n if (view.docView) {\n setMeta(view, yCursorPluginKey, { awarenessUpdated: true })\n }\n }\n const updateCursorInfo = () => {\n const ystate = ySyncPluginKey.getState(view.state)\n // @note We make implicit checks when checking for the cursor property\n const current = awareness.getLocalState() || {}\n if (view.hasFocus()) {\n const selection = getSelection(view.state)\n /**\n * @type {Y.RelativePosition}\n */\n const anchor = absolutePositionToRelativePosition(\n selection.anchor,\n ystate.type,\n ystate.binding.mapping\n )\n /**\n * @type {Y.RelativePosition}\n */\n const head = absolutePositionToRelativePosition(\n selection.head,\n ystate.type,\n ystate.binding.mapping\n )\n if (\n current.cursor == null ||\n !Y.compareRelativePositions(\n Y.createRelativePositionFromJSON(current.cursor.anchor),\n anchor\n ) ||\n !Y.compareRelativePositions(\n Y.createRelativePositionFromJSON(current.cursor.head),\n head\n )\n ) {\n awareness.setLocalStateField(cursorStateField, {\n anchor,\n head\n })\n }\n } else if (\n current.cursor != null &&\n relativePositionToAbsolutePosition(\n ystate.doc,\n ystate.type,\n Y.createRelativePositionFromJSON(current.cursor.anchor),\n ystate.binding.mapping\n ) !== null\n ) {\n // delete cursor information if current cursor information is owned by this editor binding\n awareness.setLocalStateField(cursorStateField, null)\n }\n }\n awareness.on('change', awarenessListener)\n view.dom.addEventListener('focusin', updateCursorInfo)\n view.dom.addEventListener('focusout', updateCursorInfo)\n return {\n update: updateCursorInfo,\n destroy: () => {\n view.dom.removeEventListener('focusin', updateCursorInfo)\n view.dom.removeEventListener('focusout', updateCursorInfo)\n awareness.off('change', awarenessListener)\n awareness.setLocalStateField(cursorStateField, null)\n }\n }\n }\n })\n","import { Plugin } from 'prosemirror-state'\n\nimport { getRelativeSelection } from './sync-plugin.js'\nimport { UndoManager, Item, ContentType, XmlElement, Text } from '@y/y'\nimport { yUndoPluginKey, ySyncPluginKey } from './keys.js'\n\n/**\n * @typedef {Object} UndoPluginState\n * @property {import('@y/y').UndoManager} undoManager\n * @property {ReturnType | null} prevSel\n * @property {boolean} hasUndoOps\n * @property {boolean} hasRedoOps\n */\n\n/**\n * Undo the last user action\n *\n * @param {import('prosemirror-state').EditorState} state\n * @return {boolean} whether a change was undone\n */\nexport const undo = state => yUndoPluginKey.getState(state)?.undoManager?.undo() != null\n\n/**\n * Redo the last user action\n *\n * @param {import('prosemirror-state').EditorState} state\n * @return {boolean} whether a change was undone\n */\nexport const redo = state => yUndoPluginKey.getState(state)?.undoManager?.redo() != null\n\n/**\n * Undo the last user action if there are undo operations available\n * @type {import('prosemirror-state').Command}\n */\nexport const undoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canUndo() : undo(state)\n\n/**\n * Redo the last user action if there are redo operations available\n * @type {import('prosemirror-state').Command}\n */\nexport const redoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canRedo() : redo(state)\n\nexport const defaultProtectedNodes = new Set(['paragraph'])\n\n/**\n * @param {import('@y/y').Item} item\n * @param {Set} protectedNodes\n * @returns {boolean}\n */\nexport const defaultDeleteFilter = (item, protectedNodes) => !(item instanceof Item) ||\n !(item.content instanceof ContentType) ||\n !(item.content.type instanceof Text ||\n (item.content.type instanceof XmlElement && protectedNodes.has(item.content.type.nodeName))) ||\n item.content.type._length === 0\n\n/**\n * @param {object} [options]\n * @param {Set} [options.protectedNodes]\n * @param {any[]} [options.trackedOrigins]\n * @param {import('@y/y').UndoManager | null} [options.undoManager]\n */\nexport const yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins = [], undoManager = null } = {}) => new Plugin({\n key: yUndoPluginKey,\n state: {\n init: (initargs, state) => {\n // TODO: check if plugin order matches and fix\n const ystate = ySyncPluginKey.getState(state)\n const _undoManager = undoManager || new UndoManager(ystate.type, {\n trackedOrigins: new Set([ySyncPluginKey].concat(trackedOrigins)),\n deleteFilter: (item) => defaultDeleteFilter(item, protectedNodes),\n captureTransaction: tr => tr.meta.get('addToHistory') !== false\n })\n return {\n undoManager: _undoManager,\n prevSel: null,\n hasUndoOps: _undoManager.undoStack.length > 0,\n hasRedoOps: _undoManager.redoStack.length > 0\n }\n },\n apply: (tr, val, oldState, state) => {\n const binding = ySyncPluginKey.getState(state).binding\n const undoManager = val.undoManager\n const hasUndoOps = undoManager.undoStack.length > 0\n const hasRedoOps = undoManager.redoStack.length > 0\n if (binding) {\n return {\n undoManager,\n prevSel: getRelativeSelection(binding, oldState),\n hasUndoOps,\n hasRedoOps\n }\n } else {\n if (hasUndoOps !== val.hasUndoOps || hasRedoOps !== val.hasRedoOps) {\n return Object.assign({}, val, {\n hasUndoOps: undoManager.undoStack.length > 0,\n hasRedoOps: undoManager.redoStack.length > 0\n })\n } else { // nothing changed\n return val\n }\n }\n }\n },\n view: view => {\n const ystate = ySyncPluginKey.getState(view.state)\n const undoManager = yUndoPluginKey.getState(view.state).undoManager\n undoManager.on('stack-item-added', ({ stackItem }) => {\n const binding = ystate.binding\n if (binding) {\n stackItem.meta.set(binding, yUndoPluginKey.getState(view.state).prevSel)\n }\n })\n undoManager.on('stack-item-popped', ({ stackItem }) => {\n const binding = ystate.binding\n if (binding) {\n binding.beforeTransactionSelection = stackItem.meta.get(binding) || binding.beforeTransactionSelection\n }\n })\n return {\n destroy: () => {\n undoManager.destroy()\n }\n }\n }\n})\n","import * as delta from 'lib0/delta'\nimport * as math from 'lib0/math'\nimport * as mux from 'lib0/mutex'\nimport * as Y from '@y/y'\nimport * as s from 'lib0/schema'\nimport * as object from 'lib0/object'\nimport * as error from 'lib0/error'\nimport * as set from 'lib0/set'\nimport * as map from 'lib0/map'\n\nimport { Node } from 'prosemirror-model'\nimport { AddMarkStep, RemoveMarkStep, AttrStep, AddNodeMarkStep, ReplaceStep, ReplaceAroundStep, RemoveNodeMarkStep, DocAttrStep, Transform } from 'prosemirror-transform'\nimport { ySyncPluginKey } from './plugins/keys.js'\nimport { Plugin } from 'prosemirror-state'\nimport { findTypeInOtherYdoc } from './utils.js'\nimport { absolutePositionToRelativePosition } from './lib.js'\n\nconst $prosemirrorDelta = delta.$delta({ name: s.$string, attrs: s.$record(s.$string, s.$any), text: true, recursive: true })\n\n/**\n * @typedef {s.Unwrap<$prosemirrorDelta>} ProsemirrorDelta\n * @typedef {import('./types').SyncPluginMode} SyncPluginMode\n * @typedef {import('./types').YSyncPluginMeta} YSyncPluginMeta\n * @typedef {import('./types').SnapshotItem} SnapshotItem\n * @typedef {import('./types').InitializeCallback} InitializeCallback\n */\n\n// y-attribution-deletion & y-attribution-insertion & y-attribution-format (or mod?)\n// add attributes (userId: string[], timestamp: number) (see `YAttribution` (ask Kevin))\n// define how an insertion mark works on a node\n// situations like deleted node, yet has inserted content (handle nested content)\n// insertion within a node that was inserted + another user inserted more content into that node (hovers per user likely)\n\n/**\n * @template {import('lib0/delta').Attribution} T\n * @param {Record | null} format\n * @param {T} attribution\n * @returns {Record | null}\n */\nconst defaultMapAttributionToMark = (format, attribution) => {\n /**\n * @type {Record | null}\n */\n let mergeWith = null\n if (attribution.insert) {\n mergeWith = {\n 'y-attribution-insertion': {\n userIds: attribution.insert ? attribution.insert : null,\n timestamp: attribution.insertAt ? attribution.insertAt : null\n }\n }\n } else if (attribution.delete) {\n mergeWith = {\n 'y-attribution-deletion': {\n userIds: attribution.delete ? attribution.delete : null,\n timestamp: attribution.deleteAt ? attribution.deleteAt : null\n }\n }\n } else if (attribution.format) {\n mergeWith = {\n 'y-attribution-format': {\n userIdsByAttr: attribution.format ? attribution.format : null,\n timestamp: attribution.formatAt ? attribution.formatAt : null\n }\n }\n }\n return object.assign({}, format, mergeWith)\n}\n\n/**\n * We prefer checking that the prosemirror document is empty, since most people will sync the ydoc later\n * @type {InitializeCallback}\n */\nconst defaultInitializeCallback = ({ yjs, pm }) => {\n if (yjs.hasContent) {\n // Ydoc has content, so we can directly start with the ydoc content\n yjs.apply()\n return\n }\n\n if (pm.hasContent) {\n // Your prosemirror editor has a non-empty document, yet the ydoc is empty\n // This is a potential issue, applying the prosemirror document in this state may cause duplicated content\n // If you want to get rid of this warning, then you should either:\n // 1. Not set an initial prosemirror document\n // 2. Load the ydoc content before initializing the prosemirror editor, in-which case duplicate content will be avoided, and this error can be ignored\n // 3. Implement your own initialization callback, and handle this however you want\n console.warn('[y/prosemirror]: prosemirror has content, but ydoc is empty, refusing to initialize the editor')\n }\n}\n\n/**\n * Transform delta with attributions to delta with formats (marks).\n */\nconst deltaAttributionToFormat = s.match(s.$function)\n .if(delta.$deltaAny, (d, func) => {\n const r = delta.create(d.name)\n for (const attr of d.attrs) {\n r.attrs[attr.key] = attr.clone()\n }\n for (const child of d.children) {\n const format = child.attribution ? func(child.format, child.attribution) : child.format\n if (delta.$insertOp.check(child)) {\n r.insert(child.insert.map(c => delta.$deltaAny.check(c) ? deltaAttributionToFormat(c, func) : c), format)\n } else if (delta.$textOp.check(child)) {\n r.insert(child.insert.slice(), format)\n } else if (delta.$deleteOp.check(child)) {\n r.delete(child.delete)\n } else if (delta.$retainOp.check(child)) {\n r.retain(child.retain, format)\n } else if (delta.$modifyOp.check(child)) {\n r.modify(deltaAttributionToFormat(child.value, func), format)\n } else {\n error.unexpectedCase()\n }\n }\n return r\n }).done()\n\n/**\n * This class is the state of the sync plugin, it is essentially the public API for the sync plugin\n */\nexport class SyncPluginState {\n /**\n * @type {Y.DiffAttributionManager}\n */\n #attributionManager\n\n /**\n * @type {Y.Doc | null}\n */\n #suggestionDoc = null\n\n /**\n * @type {Y.Doc}\n */\n #contentDoc = null\n\n /**\n * @type {typeof defaultMapAttributionToMark}\n */\n #mapAttributionToMark\n\n /**\n * @type {import('prosemirror-view').EditorView | null}\n */\n #view = null\n\n /**\n * This is the subscription to the ydoc changes\n * @type {null | (() => void)}\n */\n #subscription = null\n\n /**\n * Get the view that the sync plugin is attached to\n * @returns {import('prosemirror-view').EditorView}\n * @private\n */\n get view () {\n if (!this.#view) {\n throw new Error('[y/prosemirror]: view not set')\n }\n return this.#view\n }\n\n #mutex = mux.createMutex()\n\n /**\n * @type {SyncPluginMode}\n */\n #state\n\n /**\n * @param {object} ctx\n * @param {Y.XmlFragment} ctx.ytype\n * @param {Y.DiffAttributionManager} [ctx.attributionManager]\n * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]\n * @param {Y.Doc} [ctx.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking\n * @param {Y.Doc} ctx.contentDoc A {@link Y.Doc} to use for content tracking\n */\n constructor ({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc }) {\n if (!ytype || !ytype.doc) {\n throw new Error('[y/prosemirror]: ytype not provided')\n }\n this.#attributionManager = attributionManager || Y.noAttributionsManager\n this.#state = {\n type: 'sync',\n pendingDelta: null,\n ytype,\n showSuggestions: false\n }\n this.#mapAttributionToMark = mapAttributionToMark || defaultMapAttributionToMark\n this.#suggestionDoc = suggestionDoc || null\n this.#contentDoc = contentDoc\n }\n\n /**\n * This takes a prosemirror transaction and attempts to update the internal plugin state\n * @param {import('prosemirror-state').Transaction} tr\n * @returns {SyncPluginState}\n * @private\n */\n onApplyTr (tr) {\n /** @type {YSyncPluginMeta | undefined} */\n const pluginMeta = tr.getMeta(ySyncPluginKey)\n if (!pluginMeta) {\n return this\n }\n\n const nextState = this.#clone()\n switch (pluginMeta.type) {\n /**\n * For an ideal prosemirror binding, we should only commit the state once the view has been updated to the new editor state\n * Technically, there can be a number of editor state transitions between, but we only care about the state that gets committed to the view\n * So:\n * 1. we capture the transactions that are local-updates, in `appendTransaction`\n * 2. when state.apply(tr) is called, we generate a delta of the changes that we captured (merging any other states we found between such as additional appendTransaction plugins)\n * 3. when view.updateState(state) is called, we then synchronize that delta back to the ytype to sync the changes to peers\n *\n * This allows the sync plugin to be in any order within the prosemirror plugins array, since it will be committed once the view's state has been applied\n */\n case 'local-update':{\n if (this.#state.type !== 'sync' && this.#state.type !== 'paused') {\n // No-op since we are not in sync mode\n return this\n }\n\n const { capturedTransactions } = pluginMeta\n\n // We queue up local-updates by merging all of the transactions that have been captured\n const transform = new Transform(capturedTransactions[0].before)\n\n for (let i = 0; i < capturedTransactions.length; i++) {\n for (let j = 0; j < capturedTransactions[i].steps.length; j++) {\n const success = transform.maybeStep(capturedTransactions[i].steps[j])\n if (success.failed) {\n // step failed, fallback to full diff\n console.error('[y/prosemirror]: step failed to apply, falling back to a full diff')\n\n const nextDelta = docDiffToDelta(capturedTransactions[0].before, capturedTransactions[capturedTransactions.length - 1].after)\n // TODO what should the right behavior here be?\n nextState.#state = {\n type: this.#state.type,\n pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,\n ytype: this.#state.ytype,\n showSuggestions: this.#state.showSuggestions,\n contentDocSnapshot: this.#state.contentDocSnapshot\n }\n return nextState\n }\n }\n }\n // Then trying to derive the delta that they represent\n const nextDelta = trToDelta(transform)\n\n // And, either applying that delta to the already pendingDelta, or promoting that delta to being the next pending delta\n nextState.#state = {\n type: this.#state.type,\n ytype: this.#state.ytype,\n pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,\n showSuggestions: this.#state.showSuggestions,\n contentDocSnapshot: this.#state.contentDocSnapshot\n }\n return nextState\n }\n case 'render-snapshot':{\n nextState.#state = {\n type: 'snapshot',\n snapshot: pluginMeta.snapshot,\n prevSnapshot: pluginMeta.prevSnapshot,\n pendingDelta: null,\n ytype: this.#state.ytype,\n showSuggestions: this.#state.showSuggestions\n }\n return nextState\n }\n case 'resume-sync': {\n // Move back to sync mode\n nextState.#state = {\n type: 'sync',\n pendingDelta: null,\n ytype: this.#state.ytype,\n showSuggestions: this.#state.showSuggestions\n }\n return nextState\n }\n case 'pause-sync':{\n // Move to paused mode\n nextState.#state = {\n type: 'paused',\n pendingDelta: null,\n snapshot: Y.snapshot(this.#contentDoc),\n ytype: this.#state.ytype,\n showSuggestions: this.#state.showSuggestions\n }\n\n return nextState\n }\n case 'show-suggestions':{\n nextState.#state = {\n type: 'sync',\n pendingDelta: null,\n // switch to the suggestion doc\n ytype: findTypeInOtherYdoc(this.#state.ytype, this.#suggestionDoc),\n showSuggestions: true\n }\n\n return nextState\n }\n case 'hide-suggestions':{\n nextState.#state = {\n type: 'sync',\n pendingDelta: null,\n // switch to the content doc\n ytype: findTypeInOtherYdoc(this.#state.ytype, this.#contentDoc),\n showSuggestions: false\n }\n return nextState\n }\n }\n\n return this\n }\n\n /**\n * This will be `true` if the plugin state is initialized and the view is not destroyed\n */\n get initialized () {\n return this.#view && !this.#view.isDestroyed\n }\n\n /**\n * Apply any pending diffs to the ytype\n * @param {import('prosemirror-state').EditorState} prevState\n * @private\n */\n onViewUpdate (prevState) {\n if (!this.initialized) {\n return\n }\n const prevPluginState = ySyncPluginKey.getState(prevState)\n switch (this.#state.type) {\n case 'snapshot':{\n if (prevPluginState.#state.type === 'snapshot') {\n // Already in snapshot mode, so we don't need to do anything\n return\n }\n // Just transitioned from another mode, so we need to actually apply the snapshot mode\n\n // Stop observing the ydoc changes, since we are looking at a snapshot in time\n this.destroy()\n return\n }\n case 'sync':{\n if (this.#state.showSuggestions !== prevPluginState.#state.showSuggestions) {\n // We are entering/leaving suggestion mode, so we need to subscribe to the suggestion doc\n // stop observing the ytype\n this.destroy()\n // subscribe to the suggestion doc\n this.#subscribeToYType()\n return\n }\n if (prevPluginState.#state.type === 'paused' || prevPluginState.#state.type === 'snapshot') {\n // was just paused, so we need to resume sync\n\n // Restart the observer for two-way sync again\n this.#subscribeToYType()\n return\n }\n if (!this.#state.pendingDelta) {\n return\n }\n this.#mutex(() => {\n const d = this.#state.pendingDelta\n // clear the delta so that we don't accidentally apply it again\n this.#state.pendingDelta = null\n\n this.#state.ytype.doc.transact(() => {\n // If the ytype has not yet been initialized\n if (this.#state.ytype.length === 0) {\n // Apply the previous prosemirror document to the ytype, so that the pending delta can operate on the correct content\n pmToFragment(prevState.doc, this.#state.ytype, {\n attributionManager: this.#state.showSuggestions ? this.#attributionManager : Y.noAttributionsManager\n })\n }\n this.#state.ytype.applyDelta(d, this.#attributionManager)\n }, ySyncPluginKey)\n })\n\n return undefined\n }\n }\n }\n\n /**\n * @type {ReturnType | undefined}\n */\n #initializationTimeoutId = undefined\n\n /**\n * Initialize the plugin state with the view\n * @note this will start the synchronization of the prosemirror state with the ydoc\n * @param {import('prosemirror-view').EditorView} view\n * @param {InitializeCallback} [onInitialize]\n * @private\n */\n init (view, onInitialize) {\n // initialize the prosemirror state with what is in the ydoc\n // we wait a tick, because in some cases, the view can be immediately destroyed\n this.#initializationTimeoutId = setTimeout(() => {\n // clear the timeout id\n this.#initializationTimeoutId = undefined\n // Only set the view if we've passed a tick\n // This gates the initialization of the plugin state until the view is ready\n this.#view = view\n\n onInitialize({\n yjs: {\n ytype: this.#state.ytype,\n get hasContent () {\n return this.ytype.length !== 0\n },\n apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {\n const tr = this.#renderFragment({\n fragment: this.#state.ytype,\n showSuggestions: false\n })\n\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'initialized',\n ytype: this.#state.ytype\n }\n tr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(tr)\n }\n },\n pm: {\n doc: view.state.doc,\n get hasContent () {\n return view.state.doc.content.findDiffStart(\n view.state.doc.type.createAndFill().content\n ) !== null\n },\n apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {\n this.#state.ytype.doc.transact(() => {\n pmToFragment(view.state.doc, this.#state.ytype, {\n attributionManager: showSuggestions ? this.#attributionManager : Y.noAttributionsManager\n })\n }, ySyncPluginKey)\n }\n }\n })\n\n // subscribe to the ydoc changes, after initialization is complete\n this.#subscribeToYType()\n }, 0)\n }\n\n /**\n * Subscribe to the ydoc changes, and register a cleanup function to unsubscribe when the view is destroyed\n * @private\n */\n #subscribeToYType () {\n if (!this.#view) {\n throw new Error('[y/prosemirror]: view not set')\n }\n\n if (this.#subscription) {\n // re-use the existing subscription, since it operates on the latest plugin state\n return\n }\n const attrCb = this.#attributionManager.on('change', (changes) => {\n if (this.#state.ytype.doc !== this.#suggestionDoc) {\n // this should not happen\n console.info('tried to update attributions, but suggestion doc is not active. The diffing attribution manager should not be active when no diff is created - use the \"noAttributionManager instead')\n return\n }\n /**\n * @type {Map>}\n */\n const modified = new Map()\n this.#suggestionDoc.transact(tr => {\n Y.iterateStructsByIdSet(tr, changes, item => {\n map.setIfUndefined(modified, item.parent, () => new Set()).add(item.parentSub)\n })\n })\n const d = this.#state.ytype.getContent(this.#attributionManager, { modified, itemsToRender: changes, retainInserts: true, retainDeletes: true, deep: true })\n console.log('delta update by attribution manager', d.toJSON())\n const tr = deltaToPSteps(this.#tr, d)\n console.log('transaction', tr)\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'attribution-fixup',\n changes\n }\n tr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(tr)\n })\n // This stores whether the ytype has loaded any content yet\n // If it has not, then we need to apply changes to it slightly differently in #onChangeYType\n let isYTypeInitialized = !!this.#state.ytype.length\n // This is the callback that we will subscribe & unsubscribe to the ydoc changes\n const yTypeCb = this.#state.ytype.observeDeep((evt, tr) => {\n if (!this.#view || this.#view.isDestroyed) {\n // view is destroyed, just clean up the subscription, and no-op\n this.#subscription()\n return\n }\n\n // fetch the latest plugin state\n const pluginState = ySyncPluginKey.getState(this.#view.state)\n if (!pluginState) {\n throw new Error('[y/prosemirror]: plugin state not found in view.state')\n }\n\n // call the onYTypeEvent handler on that instance\n pluginState.#onChangeYType(evt, tr, isYTypeInitialized)\n // We got an event, so the ytype should now be initialized\n isYTypeInitialized = true\n })\n\n this.#subscription = () => {\n this.#subscription = null\n this.#state.ytype.unobserveDeep(yTypeCb)\n this.#attributionManager.off('change', attrCb)\n }\n }\n\n /**\n * Destroy the plugin state\n * @note this will stop the synchronization of the prosemirror state with the ydoc\n * @private\n */\n destroy () {\n // clear the initialization timeout\n clearTimeout(this.#initializationTimeoutId)\n if (this.#subscription) {\n // unsubscribe from the ydoc changes\n this.#subscription()\n this.#subscription = null\n }\n }\n\n /**\n * This is the event handler for when the ytype changes, applying remote changes to the editor content\n * @note this must be a stable reference to be unobserved later\n * @param {Array>} events\n * @param {Y.Transaction} tr\n * @param {boolean} isYTypeInitialized Whether the ytype has already been initialized\n */\n #onChangeYType (events, tr, isYTypeInitialized) {\n // bail if: the view is destroyed OR we are not in \"sync\" mode\n if (!this.initialized || this.#state.type !== 'sync') {\n return\n }\n\n this.#mutex(() => {\n /**\n * @type {Y.YEvent}\n */\n const event = events.find(event => event.target === this.#state.ytype) || new Y.YEvent(this.#state.ytype, tr, new Set(null))\n let d = deltaAttributionToFormat(event.getDelta(this.#state.showSuggestions ? this.#attributionManager : Y.noAttributionsManager, { deep: true }), this.#mapAttributionToMark).done()\n\n if (!isYTypeInitialized) {\n // Here is the sequence of events:\n // 1. The prosemirror document is empty (e.g. )\n // 2. The ytype is empty\n // 3. We get an update, which describes the document as
Hello, world!
\n // If we apply the delta directly, then the prosemirror document will be
Hello, world!
, which is incorrect\n // What we actually want is for this case to act as a full-document replace\n // so, we actually diff the prosemirror document with the delta, to get the correct changes\n d = delta.diff(nodeToDelta(this.#view.state.doc).done(), d)\n }\n const ptr = deltaToPSteps(this.#view.state.tr, d)\n\n ptr.setMeta(ySyncPluginKey, { ytypeEvent: true })\n this.#view.dispatch(ptr)\n }, () => {\n if (this.#attributionManager === Y.noAttributionsManager) {\n // no attribution fixup needed\n return\n }\n const itemsToRender = Y.mergeIdSets([tr.insertSet, tr.deleteSet])\n /**\n * @todo this could be automatically be calculated in getContent/getDelta when\n * itemsToRender is provided\n * @type {Map>}\n */\n const modified = new Map()\n Y.iterateStructsByIdSet(tr, itemsToRender, item => {\n while (item instanceof Y.Item) {\n const parent = /** @type {Y.AbstractType} */ (item.parent)\n const conf = map.setIfUndefined(modified, parent, set.create)\n if (conf.has(item.parentSub)) break // has already been marked as modified\n conf.add(item.parentSub)\n item = parent._item\n }\n })\n\n if (modified.has(this.#state.ytype)) {\n setTimeout(() => {\n this.#mutex(() => {\n if (this.#state.type !== 'sync') {\n error.unexpectedCase()\n }\n const d = deltaAttributionToFormat(this.#state.ytype.getContent(this.#state.showSuggestions ? this.#attributionManager : Y.noAttributionsManager, {\n itemsToRender,\n retainInserts: true,\n deep: true,\n modified\n }), this.#mapAttributionToMark)\n const ptr = deltaToPSteps(this.#tr, d)\n console.log('attribution fix event: ', d.toJSON(), 'and applied changes to pm', ptr.steps)\n\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'remote-update',\n events,\n ytype: this.#state.ytype,\n attributionFix: true\n }\n ptr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(ptr)\n })\n }, 0)\n }\n })\n }\n\n /**\n * Create a transaction for changing the prosemirror state.\n * @private\n */\n get #tr () {\n return this.view.state.tr.setMeta('addToHistory', false)\n }\n\n /**\n * Pause the synchronization of the prosemirror state with the ydoc\n */\n pauseSync () {\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'pause-sync'\n }\n this.view.dispatch(this.#tr.setMeta(ySyncPluginKey, pluginMeta))\n }\n\n /**\n * Resume the synchronization of the prosemirror state with the ydoc\n * @param {object} [opts]\n * @param {boolean} [opts.keepChanges]\n */\n resumeSync ({ keepChanges = false } = {}) {\n if (this.#state.type === 'sync') {\n // Already in sync mode, so we don't need to do anything\n return\n }\n\n // This will apply the changes that were made while paused to the ytype\n if (keepChanges && this.#state.type === 'paused' && this.#state.pendingDelta) {\n // We use a snapshot to get the document state at the point in time when the sync was paused (it may have accrued updates since then)\n // A nice property of using only a snapshot like this is that it is relatively cheap to create, and a copy is only needed if we actually want to keep the changes\n const docAtSnapshotTime = Y.createDocFromSnapshot(this.#state.ytype.doc, this.#state.snapshot)\n const ytypeAtSnapshotTime = findTypeInOtherYdoc(this.#state.ytype, docAtSnapshotTime)\n // We setup a listener to apply any updates which occur to the snapshot doc, to the main ydoc\n docAtSnapshotTime.on('updateV2', (update) => {\n // Apply that diff as an update to the main ydoc\n Y.applyUpdateV2(this.#state.ytype.doc, update, ySyncPluginKey)\n })\n // Actually apply the changes accrued while paused to the ytype\n ytypeAtSnapshotTime.applyDelta(this.#state.pendingDelta, this.#attributionManager)\n docAtSnapshotTime.destroy()\n }\n\n // Take whatever is in the ytype now, and make that the new document state\n const tr = this.#renderFragment()\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'resume-sync'\n }\n tr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(tr)\n }\n\n /**\n * Get the mode that the sync plugin is in\n */\n get mode () {\n return this.#state.type\n }\n\n /**\n * Get the ytype that the sync plugin is using\n */\n get ytype () {\n return this.#state.ytype\n }\n\n /**\n * @param {SnapshotItem} snapshot\n * @param {SnapshotItem} [prevSnapshot]\n * @param {Y.Attribution[]} [attrs]\n */\n renderSnapshot (snapshot, prevSnapshot, attrs) {\n if (!prevSnapshot) {\n prevSnapshot = { fragment: snapshot.fragment }\n }\n const snapshotDoc = snapshot.snapshot ? Y.createDocFromSnapshot(snapshot.fragment.doc, snapshot.snapshot) : snapshot.fragment.doc\n const prevSnapshotDoc = prevSnapshot.snapshot ? Y.createDocFromSnapshot(prevSnapshot.fragment.doc, prevSnapshot.snapshot) : prevSnapshot.fragment.doc\n const am = Y.createAttributionManagerFromDiff(prevSnapshotDoc, snapshotDoc, { attrs })\n const tr = this.#renderFragment({\n fragment: findTypeInOtherYdoc(snapshot.fragment, snapshotDoc),\n attributionManager: am,\n showSuggestions: true\n })\n\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'render-snapshot',\n snapshot,\n prevSnapshot\n }\n tr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(tr)\n }\n\n /**\n * Set the suggestion mode\n * @param {'off' | 'view' | 'edit'} mode\n * -\n * - 'off': Hide suggestions, edit original document\n * - 'view': Show suggestions, edit original document\n * - 'edit': Show suggestions, edits become suggestions\n */\n setSuggestionMode (mode) {\n if (this.#state.type !== 'sync') {\n // not in sync mode, so we don't need to do anything\n return\n }\n console.log('setting suggestion mode to', mode)\n\n const showSuggestions = mode !== 'off'\n const suggestionMode = mode === 'edit'\n\n let switchedToSuggestionMode = false\n if (suggestionMode !== this.#attributionManager.suggestionMode) {\n this.#attributionManager.suggestionMode = suggestionMode\n switchedToSuggestionMode = true\n }\n\n if (this.#state.showSuggestions === showSuggestions && !switchedToSuggestionMode) {\n // already in the desired suggestion mode & did not switch to a different suggestion mode\n return\n }\n\n const tr = this.#renderFragment({\n showSuggestions\n })\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: showSuggestions ? 'show-suggestions' : 'hide-suggestions'\n }\n tr.setMeta(ySyncPluginKey, pluginMeta)\n this.view.dispatch(tr)\n }\n\n /**\n * Accept all changes in the suggestion doc\n */\n acceptAllChanges () {\n if (!this.#state.showSuggestions) {\n // not in suggestion mode, so we don't need to do anything\n return\n }\n this.#attributionManager.acceptAllChanges()\n const tr = this.#renderFragment()\n this.view.dispatch(tr)\n }\n\n /**\n * Reject all changes in the suggestion doc\n */\n rejectAllChanges () {\n if (!this.#state.showSuggestions) {\n // not in suggestion mode, so we don't need to do anything\n return\n }\n this.#attributionManager.rejectAllChanges()\n const tr = this.#renderFragment()\n this.view.dispatch(tr)\n }\n\n /**\n * Accept the changes within the given range\n * @note This will move the content from the suggestion doc into the content doc, so this requires permissions to write to the content doc\n * @param {number} from\n * @param {number} [to]\n */\n acceptChanges (from, to = from) {\n if (!this.#state.showSuggestions) {\n // not in suggestion mode, so we don't need to do anything\n return\n }\n if (from > to) {\n // swap the from and to positions\n [from, to] = [to, from]\n }\n const fromRel = absolutePositionToRelativePosition(from, this.#state.ytype, this.#view.state.doc, this.#attributionManager)\n const toRel = from === to ? fromRel : absolutePositionToRelativePosition(to, this.#state.ytype, this.#view.state.doc, this.#attributionManager)\n\n if (!fromRel.item && !toRel.item) {\n throw new Error('Invalid relative position')\n }\n // TODO move this to be in the state.apply\n this.#attributionManager.acceptChanges(fromRel.item, toRel.item)\n const tr = this.#renderFragment()\n this.view.dispatch(tr)\n }\n\n /**\n * Reject the changes within the given range\n * @note This will remove the content from the suggestion doc, so that it no longer appears in the editor\n * @param {number} from\n * @param {number} [to]\n */\n rejectChanges (from, to) {\n if (!this.#state.showSuggestions) {\n // not in suggestion mode, so we don't need to do anything\n return\n }\n if (from > to) {\n // swap the from and to positions\n [from, to] = [to, from]\n }\n const fromRel = absolutePositionToRelativePosition(from, this.#state.ytype, this.#view.state.doc, this.#attributionManager)\n const toRel = from === to ? fromRel : absolutePositionToRelativePosition(to, this.#state.ytype, this.#view.state.doc, this.#attributionManager)\n\n if (!fromRel.item || !toRel.item) {\n throw new Error('Invalid relative position')\n }\n\n // TODO move this to be in the state.apply\n this.#attributionManager.rejectChanges(fromRel.item, toRel.item)\n const tr = this.#renderFragment()\n this.view.dispatch(tr)\n }\n\n /**\n * Replaces the current prosemirror document with the content of the given ytype\n * @param {object} ctx\n * @param {Y.XmlFragment} [ctx.fragment] The ytype to render\n * @param {boolean} [ctx.showSuggestions] Whether to show suggestions\n * @param {import('prosemirror-state').Transaction} [ctx.tr]\n */\n #renderFragment ({\n showSuggestions = this.#state.showSuggestions,\n // from the current XMLFragment, get the type in the suggestion doc or content doc, depending on the showSuggestions flag\n fragment = findTypeInOtherYdoc(this.#state.ytype, showSuggestions ? this.#suggestionDoc : this.#contentDoc),\n tr = this.#tr,\n attributionManager = this.#attributionManager\n } = {}) {\n return fragmentToTr(fragment, tr, {\n attributionManager: showSuggestions ? attributionManager : Y.noAttributionsManager,\n mapAttributionToMark: this.#mapAttributionToMark\n })\n }\n\n /**\n * Clone the {@link SyncPluginState} instance, this allows us to compare the current state with the previous state without mutating the current state\n * @private\n */\n #clone () {\n const pluginState = new SyncPluginState({\n ytype: this.#state.ytype,\n attributionManager: this.#attributionManager,\n mapAttributionToMark: this.#mapAttributionToMark,\n suggestionDoc: this.#suggestionDoc,\n contentDoc: this.#contentDoc\n })\n\n pluginState.#state = this.#state\n pluginState.#mutex = this.#mutex\n pluginState.#view = this.#view\n pluginState.#initializationTimeoutId = this.#initializationTimeoutId\n // We can safely clone the subscription, because it will always operate on the latest plugin state, rather than being bound to the one that created it\n pluginState.#subscription = this.#subscription\n\n return pluginState\n }\n}\n\n// The sync plugin is built a bit strangely, what it does at a high level is:\n// 1. It captures transactions within `appendTransaction` (creating a transaction that carries metadata about the transactions that were captured)\n// 2. It accrues these changes in the SyncPluginState on state.apply\n// 3. When view.update occurs, it can finally apply the accrued changes to the ytype\n// It is built this way because it allows for EditorStates to be created (even ephemeral ones) without having to worry about accidentally committing changes to the ytype.\n// In Prosemirror, appendTransaction is expected to be a pure function of the current state & the incoming transactions.\n// If this is not the case, then interactions with other plugins may be buggy, since they may apply changes to the ytype that were not intended to be committed.\n// This has the nice side effect of allowing the sync plugin to be installed to the prosemirror plugins array in any order, since it will be committed once the view's state has been applied\n// It also allows for a nice separation of concerns, where the view.update is the final point at which changes can be committed to the ytype. (Rather than across potentially multiple appendTransaction calls)\n\n/**\n * This Prosemirror {@link Plugin} is responsible for synchronizing the prosemirror {@link EditorState} with a {@link Y.XmlFragment}\n * @param {Y.XmlFragment} ytype\n * @param {object} opts\n * @param {Y.DiffAttributionManager} [opts.attributionManager] An {@link Y.DiffAttributionManager} to use for attribution tracking\n * @param {Y.Doc} [opts.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking\n * @param {typeof defaultMapAttributionToMark} [opts.mapAttributionToMark] A function to map the {@link Y.Attribution} to a {@link import('prosemirror-model').Mark}\n * @param {InitializeCallback} [opts.initialize] This callback is called on initialization and is meant to be used to initialize the editor's state or initialize the ydoc content\n * @returns {Plugin}\n */\nexport function syncPlugin (ytype, {\n attributionManager = Y.noAttributionsManager,\n mapAttributionToMark = defaultMapAttributionToMark,\n suggestionDoc,\n onInitialize = defaultInitializeCallback\n} = {}) {\n return new Plugin({\n key: ySyncPluginKey,\n props: {\n // Disables editing if we are in snapshot mode\n editable: (state) => {\n const pluginState = ySyncPluginKey.getState(state)\n return pluginState?.mode !== 'snapshot'\n }\n },\n state: {\n init () {\n return new SyncPluginState({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc: ytype.doc })\n },\n apply (tr, value) {\n return value.onApplyTr(tr)\n }\n },\n view (view) {\n const pluginState = ySyncPluginKey.getState(view.state)\n\n if (!pluginState) {\n throw new Error('[y/prosemirror]: plugin state not found in view.state')\n }\n\n pluginState.init(view, onInitialize)\n\n return {\n update (view, prevState) {\n const pluginState = ySyncPluginKey.getState(view.state)\n if (!pluginState) {\n throw new Error('[y/prosemirror]: plugin state not found in view.state')\n }\n pluginState.onViewUpdate(prevState)\n },\n destroy () {\n const pluginState = ySyncPluginKey.getState(view.state)\n if (!pluginState) {\n throw new Error('[y/prosemirror]: plugin state not found in view.state')\n }\n pluginState.destroy()\n }\n }\n },\n // Capture any local updates to the prosemirror state, later we will use them to generate a delta to apply to the ydoc\n appendTransaction (transactions, _oldState, newState) {\n transactions = transactions.filter(tr => tr.docChanged && !tr.getMeta(ySyncPluginKey))\n if (transactions.length === 0) return undefined\n\n /** @type {YSyncPluginMeta} */\n const pluginMeta = {\n type: 'local-update',\n capturedTransactions: transactions\n }\n return newState.tr.setMeta(ySyncPluginKey, pluginMeta).setMeta('addToHistory', false)\n }\n })\n}\n\n/**\n * @param {readonly import('prosemirror-model').Mark[]} marks\n */\nconst marksToFormattingAttributes = marks => {\n if (marks.length === 0) return null\n /**\n * @type {{[key:string]:any}}\n */\n const formatting = {}\n marks.forEach(mark => {\n formatting[mark.type.name] = mark.attrs\n })\n return formatting\n}\n\n/**\n * @param {{[key:string]:any}} formatting\n * @param {import('prosemirror-model').Schema} schema\n */\nconst formattingAttributesToMarks = (formatting, schema) => object.map(formatting, (v, k) => schema.mark(k, v))\n\n/**\n * @param {Array} ns\n */\nexport const nodesToDelta = ns => {\n /**\n * @type {delta.DeltaBuilderAny}\n */\n const d = delta.create($prosemirrorDelta)\n ns.forEach(n => {\n d.insert(n.isText ? n.text : [nodeToDelta(n)], marksToFormattingAttributes(n.marks))\n })\n return d\n}\n\n/**\n * Transforms a {@link Node} into a {@link Y.XmlFragment}\n * @param {Node} node\n * @param {Y.XmlFragment} fragment\n * @param {Object} [opts]\n * @param {Y.DiffAttributionManager} [opts.attributionManager]\n * @returns {Y.XmlFragment}\n */\nexport function pmToFragment (node, fragment, { attributionManager = Y.noAttributionsManager } = {}) {\n const initialPDelta = nodeToDelta(node).done()\n fragment.applyDelta(initialPDelta, attributionManager)\n\n return fragment\n}\n\n/**\n * Applies a {@link Y.XmlFragment}'s content as a ProseMirror {@link Transaction}\n * @param {Y.XmlFragment} fragment\n * @param {import('prosemirror-state').Transaction} tr\n * @param {object} [ctx]\n * @param {Y.DiffAttributionManager} [ctx.attributionManager]\n * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]\n * @returns {import('prosemirror-state').Transaction}\n */\nexport function fragmentToTr (fragment, tr, {\n attributionManager = Y.noAttributionsManager,\n mapAttributionToMark = defaultMapAttributionToMark\n}) {\n const fragmentContent = deltaAttributionToFormat(\n fragment.getContent(attributionManager, { deep: true }),\n mapAttributionToMark\n )\n const initialPDelta = nodeToDelta(tr.doc).done()\n const deltaBetweenPmAndFragment = delta.diff(initialPDelta, fragmentContent).done()\n console.log({\n am: attributionManager === Y.noAttributionsManager ? 'no attributions manager' : 'attributions manager',\n a: initialPDelta.toJSON(),\n b: fragmentContent.toJSON(),\n c: deltaBetweenPmAndFragment.toJSON()\n })\n\n return deltaToPSteps(tr, deltaBetweenPmAndFragment).setMeta('y-sync-hydration', {\n delta: deltaBetweenPmAndFragment\n })\n}\n\n/**\n * Transforms a {@link Y.XmlFragment} into a {@link Node}\n * @param {Y.XmlFragment} fragment\n * @param {import('prosemirror-state').Transaction}\n * @returns {Node}\n */\nexport function fragmentToPm (fragment, tr) {\n return fragmentToTr(fragment, tr).doc\n}\n\n/**\n * @param {Node} n\n */\nexport const nodeToDelta = n => {\n /**\n * @type {delta.DeltaBuilderAny}\n */\n const d = delta.create(n.type.name, $prosemirrorDelta)\n d.setMany(n.attrs)\n n.content.content.forEach(c => {\n d.insert(c.isText ? c.text : [nodeToDelta(c)], marksToFormattingAttributes(c.marks))\n })\n return d\n}\n\n/**\n * @param {import('prosemirror-transform').Transform} tr\n * @param {ProsemirrorDelta} d\n * @param {Node} [pnode]\n * @param {{ i: number }} [currPos]\n * @return {import('prosemirror-transform').Transform}\n */\nexport const deltaToPSteps = (tr, d, pnode = tr.doc, currPos = { i: 0 }) => {\n const schema = tr.doc.type.schema\n let currParentIndex = 0\n let nOffset = 0\n const pchildren = pnode.children\n for (const attr of d.attrs) {\n tr.setNodeAttribute(currPos.i - 1, attr.key, attr.value)\n }\n d.children.forEach(op => {\n if (delta.$retainOp.check(op)) {\n // skip over i children\n let i = op.retain\n while (i > 0) {\n const pc = pchildren[currParentIndex]\n if (pc === undefined) {\n throw new Error('[y/prosemirror]: retain operation is out of bounds')\n }\n if (pc.isText) {\n if (op.format != null) {\n const from = currPos.i\n const to = currPos.i + math.min(pc.nodeSize - nOffset, i)\n object.forEach(op.format, (v, k) => {\n if (v == null) {\n tr.removeMark(from, to, schema.marks[k])\n } else {\n tr.addMark(from, to, schema.mark(k, v))\n }\n })\n }\n if (i + nOffset < pc.nodeSize) {\n nOffset += i\n currPos.i += i\n i = 0\n } else {\n currParentIndex++\n i -= pc.nodeSize - nOffset\n currPos.i += pc.nodeSize - nOffset\n nOffset = 0\n }\n } else {\n object.forEach(op.format, (v, k) => {\n if (v == null) {\n tr.removeNodeMark(currPos.i, schema.marks[k])\n } else {\n // TODO see schema.js for more info on marking nodes\n tr.addNodeMark(currPos.i, schema.mark(k, v))\n }\n })\n currParentIndex++\n currPos.i += pc.nodeSize\n i--\n }\n }\n } else if (delta.$modifyOp.check(op)) {\n currPos.i++\n deltaToPSteps(tr, op.value, pchildren[currParentIndex++], currPos)\n currPos.i++\n } else if (delta.$insertOp.check(op)) {\n const newPChildren = op.insert.map(ins => deltaToPNode(ins, schema, op.format))\n tr.insert(currPos.i, newPChildren)\n currPos.i += newPChildren.reduce((s, c) => c.nodeSize + s, 0)\n } else if (delta.$textOp.check(op)) {\n tr.insert(currPos.i, schema.text(op.insert, formattingAttributesToMarks(op.format, schema)))\n currPos.i += op.length\n } else if (delta.$deleteOp.check(op)) {\n for (let remainingDelLen = op.delete; remainingDelLen > 0;) {\n const pc = pchildren[currParentIndex]\n if (pc === undefined) {\n throw new Error('[y/prosemirror]: delete operation is out of bounds')\n }\n if (pc.isText) {\n const delLen = math.min(pc.nodeSize - nOffset, remainingDelLen)\n tr.delete(currPos.i, currPos.i + delLen)\n nOffset += delLen\n if (nOffset === pc.nodeSize) {\n // TODO this can't actually \"jump out\" of the current node\n // jump to next node\n nOffset = 0\n currParentIndex++\n }\n remainingDelLen -= delLen\n } else {\n tr.delete(currPos.i, currPos.i + pc.nodeSize)\n currParentIndex++\n remainingDelLen--\n }\n }\n }\n })\n return tr\n}\n\n/**\n * @param {ProsemirrorDelta} d\n * @param {import('prosemirror-model').Schema} schema\n * @param {delta.FormattingAttributes} dformat\n * @return {Node}\n */\nconst deltaToPNode = (d, schema, dformat) => {\n const attrs = {}\n for (const attr of d.attrs) {\n attrs[attr.key] = attr.value\n }\n const dc = d.children.map(c => delta.$insertOp.check(c) ? c.insert.map(cn => deltaToPNode(cn, schema, c.format)) : (delta.$textOp.check(c) ? [schema.text(c.insert, formattingAttributesToMarks(c.format, schema))] : []))\n return schema.node(d.name, attrs, dc.flat(1), formattingAttributesToMarks(dformat, schema))\n}\n\n/**\n * @param {Node} beforeDoc\n * @param {Node} afterDoc\n */\nexport const docDiffToDelta = (beforeDoc, afterDoc) => {\n const initialDelta = nodeToDelta(beforeDoc)\n const finalDelta = nodeToDelta(afterDoc)\n\n return delta.diff(initialDelta.done(), finalDelta.done())\n}\n\n/**\n * @param {Transform} tr\n */\nexport const trToDelta = (tr) => {\n // const d = delta.create($prosemirrorDelta)\n // tr.steps.forEach((step, i) => {\n // const stepDelta = stepToDelta(step, tr.docs[i])\n // console.log('stepDelta', JSON.stringify(stepDelta.toJSON(), null, 2))\n // console.log('d', JSON.stringify(d.toJSON(), null, 2))\n // d.apply(stepDelta)\n // })\n // return d.done()\n // Calculate delta from initial and final document states to avoid composition issues with delete operations\n // This is more reliable than composing step-by-step, which can lose delete operations and cause \"Unexpected case\" errors\n // after lib0 upgrades that change delta composition behavior\n const initialDelta = nodeToDelta(tr.before)\n const finalDelta = nodeToDelta(tr.doc)\n const resultDelta = delta.diff(initialDelta.done(), finalDelta.done())\n return resultDelta\n}\n\nconst _stepToDelta = s.match({ beforeDoc: Node, afterDoc: Node })\n .if([ReplaceStep, ReplaceAroundStep], (step, { beforeDoc, afterDoc }) => {\n const oldStart = beforeDoc.resolve(step.from)\n const oldEnd = beforeDoc.resolve(step.to)\n const newStart = afterDoc.resolve(step.from)\n\n const newEnd = afterDoc.resolve(step instanceof ReplaceAroundStep ? step.getMap().map(step.to) : step.from + step.slice.size)\n\n const oldBlockRange = oldStart.blockRange(oldEnd)\n const newBlockRange = newStart.blockRange(newEnd)\n const oldDelta = deltaForBlockRange(oldBlockRange)\n const newDelta = deltaForBlockRange(newBlockRange)\n const diffD = delta.diff(oldDelta, newDelta)\n const stepDelta = deltaModifyNodeAt(beforeDoc, oldBlockRange?.start || newBlockRange?.start || 0, d => { d.append(diffD) })\n return stepDelta\n })\n .if(AddMarkStep, (step, { beforeDoc }) =>\n deltaModifyNodeAt(beforeDoc, step.from, d => { d.retain(step.to - step.from, marksToFormattingAttributes([step.mark])) })\n )\n .if(AddNodeMarkStep, (step, { beforeDoc }) =>\n deltaModifyNodeAt(beforeDoc, step.pos, d => { d.retain(1, marksToFormattingAttributes([step.mark])) })\n )\n .if(RemoveMarkStep, (step, { beforeDoc }) =>\n deltaModifyNodeAt(beforeDoc, step.from, d => { d.retain(step.to - step.from, { [step.mark.type.name]: null }) })\n )\n .if(RemoveNodeMarkStep, (step, { beforeDoc }) =>\n deltaModifyNodeAt(beforeDoc, step.pos, d => { d.retain(1, { [step.mark.type.name]: null }) })\n )\n .if(AttrStep, (step, { beforeDoc }) =>\n deltaModifyNodeAt(beforeDoc, step.pos, d => { d.modify(delta.create().set(step.attr, step.value)) })\n )\n .if(DocAttrStep, step =>\n delta.create().set(step.attr, step.value)\n )\n .else(_step => {\n // unknown step kind\n error.unexpectedCase()\n })\n .done()\n\n/**\n * @param {import('prosemirror-transform').Step} step\n * @param {import('prosemirror-model').Node} beforeDoc\n * @return {ProsemirrorDelta}\n */\nexport const stepToDelta = (step, beforeDoc) => {\n const stepResult = step.apply(beforeDoc)\n if (stepResult.failed) {\n throw new Error('[y/prosemirror]: step failed to apply')\n }\n return _stepToDelta(step, { beforeDoc, afterDoc: stepResult.doc })\n}\n\n/**\n *\n * @param {import('prosemirror-model').NodeRange | null} blockRange\n */\nfunction deltaForBlockRange (blockRange) {\n if (blockRange === null) {\n return delta.create()\n }\n const { startIndex, endIndex, parent } = blockRange\n return nodesToDelta(parent.content.content.slice(startIndex, endIndex))\n}\n\n/**\n * This function is used to find the delta offset for a given prosemirror offset in a node.\n * Given the following document:\n *
Hello world
Hello world!
\n * The delta structure would look like this:\n * 0: p\n * - 0: text(\"Hello world\")\n * 1: blockquote\n * - 0: p\n * - 0: text(\"Hello world!\")\n * So the prosemirror position 10 would be within the delta offset path: 0, 0 and have an offset into the text node of 9 (since it is the 9th character in the text node).\n *\n * So the return value would be [0, 9], which is the path of: p, text(\"Hello wor\")\n *\n * @param {Node} node\n * @param {number} searchPmOffset The p offset to find the delta offset for\n * @return {number[]} The delta offset path for the search pm offset\n */\nexport function pmToDeltaPath (node, searchPmOffset = 0) {\n if (searchPmOffset === 0) {\n // base case\n return [0]\n }\n\n const resolvedOffset = node.resolve(searchPmOffset)\n const depth = resolvedOffset.depth\n const path = []\n if (depth === 0) {\n // if the offset is at the root node, return the index of the node\n return [resolvedOffset.index(0)]\n }\n // otherwise, add the index of each parent node to the path\n for (let d = 0; d < depth; d++) {\n path.push(resolvedOffset.index(d))\n }\n\n // add any offset into the parent node to the path\n path.push(resolvedOffset.parentOffset)\n\n return path\n}\n\n/**\n * Inverse of {@link pmToDeltaPath}\n * @param {number[]} deltaPath\n * @param {Node} node\n * @return {number} The prosemirror offset for the delta path\n */\nexport function deltaPathToPm (deltaPath, node) {\n let pmOffset = 0\n let curNode = node\n\n // Special case: if path has only one element, it's a child index at depth 0\n if (deltaPath.length === 1) {\n const childIndex = deltaPath[0]\n // Add sizes of all children before the target index\n for (let j = 0; j < childIndex; j++) {\n pmOffset += curNode.children[j].nodeSize\n }\n return pmOffset\n }\n\n // Handle all elements except the last (which is an offset)\n for (let i = 0; i < deltaPath.length - 1; i++) {\n const childIndex = deltaPath[i]\n // Add sizes of all children before the target child\n for (let j = 0; j < childIndex; j++) {\n pmOffset += curNode.children[j].nodeSize\n }\n // Add 1 for the opening tag of the target child, then navigate into it\n pmOffset += 1\n curNode = curNode.children[childIndex]\n }\n\n // Last element is an offset within the current node\n pmOffset += deltaPath[deltaPath.length - 1]\n\n return pmOffset\n}\n\n/**\n * @param {Node} node\n * @param {number} pmOffset\n * @param {(d:delta.DeltaBuilderAny)=>any} mod\n * @return {ProsemirrorDelta}\n */\nexport const deltaModifyNodeAt = (node, pmOffset, mod) => {\n const dpath = pmToDeltaPath(node, pmOffset)\n let currentOp = delta.create($prosemirrorDelta)\n const lastIndex = dpath.length - 1\n currentOp.retain(lastIndex >= 0 ? dpath[lastIndex] : 0)\n mod(currentOp)\n for (let i = lastIndex - 1; i >= 0; i--) {\n currentOp = /** @type {delta.DeltaBuilderAny} */ (delta.create($prosemirrorDelta).retain(dpath[i]).modify(currentOp))\n }\n return currentOp\n}\n"],"names":["PluginKey","buf","sha256","Y","set","random","Plugin","eventloop","AllSelection","NodeSelection","TextSelection","createMutex","environment","dom","PModel","math","error","object","simpleDiff","map","utils.hashOfJSON","Fragment","Node","DecorationSet","Decoration","Item","ContentType","Text","XmlElement","UndoManager","delta","s","mux","Transform","ReplaceStep","ReplaceAroundStep","AddMarkStep","AddNodeMarkStep","RemoveMarkStep","RemoveNodeMarkStep","AttrStep","DocAttrStep"],"mappings":"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"}
+\ No newline at end of file
+diff --git a/src/index.js b/src/index.js
+index ac407e0c363309c970f3dbcbd66db00f9cd1656a..17893448db9dcdc50730e131ee3a568f6441c1ec 100644
+--- a/src/index.js
++++ b/src/index.js
+@@ -9,50 +9,107 @@ import * as set from 'lib0/set'
+ import * as map from 'lib0/map'
+
+ import { Node } from 'prosemirror-model'
+-import { EditorView } from 'prosemirror-view'
+ import { AddMarkStep, RemoveMarkStep, AttrStep, AddNodeMarkStep, ReplaceStep, ReplaceAroundStep, RemoveNodeMarkStep, DocAttrStep, Transform } from 'prosemirror-transform'
+ import { ySyncPluginKey } from './plugins/keys.js'
+ import { Plugin } from 'prosemirror-state'
++import { findTypeInOtherYdoc } from './utils.js'
++import { absolutePositionToRelativePosition } from './lib.js'
+
+ const $prosemirrorDelta = delta.$delta({ name: s.$string, attrs: s.$record(s.$string, s.$any), text: true, recursive: true })
+
+ /**
+ * @typedef {s.Unwrap<$prosemirrorDelta>} ProsemirrorDelta
++ * @typedef {import('./types').SyncPluginMode} SyncPluginMode
++ * @typedef {import('./types').YSyncPluginMeta} YSyncPluginMeta
++ * @typedef {import('./types').SnapshotItem} SnapshotItem
++ * @typedef {import('./types').InitializeCallback} InitializeCallback
+ */
+
++// y-attribution-deletion & y-attribution-insertion & y-attribution-format (or mod?)
++// add attributes (userId: string[], timestamp: number) (see `YAttribution` (ask Kevin))
++// define how an insertion mark works on a node
++// situations like deleted node, yet has inserted content (handle nested content)
++// insertion within a node that was inserted + another user inserted more content into that node (hovers per user likely)
++
+ /**
+- * @param {object|null} format
+- * @param {object|null} attribution
++ * @template {import('lib0/delta').Attribution} T
++ * @param {Record | null} format
++ * @param {T} attribution
++ * @returns {Record | null}
+ */
+-const attributionToFormat = (format, attribution) => attribution
+- ? object.assign({}, format, {
+- ychange: attribution.insert
+- ? { type: 'added', user: attribution.insert?.[0] }
+- : { type: 'removed', user: attribution.delete?.[0] }
+- })
+- : format
++const defaultMapAttributionToMark = (format, attribution) => {
++ /**
++ * @type {Record | null}
++ */
++ let mergeWith = null
++ if (attribution.insert) {
++ mergeWith = {
++ 'y-attribution-insertion': {
++ userIds: attribution.insert ? attribution.insert : null,
++ timestamp: attribution.insertAt ? attribution.insertAt : null
++ }
++ }
++ } else if (attribution.delete) {
++ mergeWith = {
++ 'y-attribution-deletion': {
++ userIds: attribution.delete ? attribution.delete : null,
++ timestamp: attribution.deleteAt ? attribution.deleteAt : null
++ }
++ }
++ } else if (attribution.format) {
++ mergeWith = {
++ 'y-attribution-format': {
++ userIdsByAttr: attribution.format ? attribution.format : null,
++ timestamp: attribution.formatAt ? attribution.formatAt : null
++ }
++ }
++ }
++ return object.assign({}, format, mergeWith)
++}
++
++/**
++ * We prefer checking that the prosemirror document is empty, since most people will sync the ydoc later
++ * @type {InitializeCallback}
++ */
++const defaultInitializeCallback = ({ yjs, pm }) => {
++ if (yjs.hasContent) {
++ // Ydoc has content, so we can directly start with the ydoc content
++ yjs.apply()
++ return
++ }
++
++ if (pm.hasContent) {
++ // Your prosemirror editor has a non-empty document, yet the ydoc is empty
++ // This is a potential issue, applying the prosemirror document in this state may cause duplicated content
++ // If you want to get rid of this warning, then you should either:
++ // 1. Not set an initial prosemirror document
++ // 2. Load the ydoc content before initializing the prosemirror editor, in-which case duplicate content will be avoided, and this error can be ignored
++ // 3. Implement your own initialization callback, and handle this however you want
++ console.warn('[y/prosemirror]: prosemirror has content, but ydoc is empty, refusing to initialize the editor')
++ }
++}
+
+ /**
+ * Transform delta with attributions to delta with formats (marks).
+ */
+-const deltaAttributionToFormat = s.match()
+- .if(delta.$deltaAny, d => {
++const deltaAttributionToFormat = s.match(s.$function)
++ .if(delta.$deltaAny, (d, func) => {
+ const r = delta.create(d.name)
+ for (const attr of d.attrs) {
+ r.attrs[attr.key] = attr.clone()
+ }
+ for (const child of d.children) {
++ const format = child.attribution ? func(child.format, child.attribution) : child.format
+ if (delta.$insertOp.check(child)) {
+- const f = attributionToFormat(child.format, child.attribution)
+- r.insert(child.insert.map(c => delta.$deltaAny.check(c) ? deltaAttributionToFormat(c) : c), f)
++ r.insert(child.insert.map(c => delta.$deltaAny.check(c) ? deltaAttributionToFormat(c, func) : c), format)
+ } else if (delta.$textOp.check(child)) {
+- r.insert(child.insert.slice(), attributionToFormat(child.format, child.attribution))
++ r.insert(child.insert.slice(), format)
+ } else if (delta.$deleteOp.check(child)) {
+ r.delete(child.delete)
+ } else if (delta.$retainOp.check(child)) {
+- r.retain(child.retain, attributionToFormat(child.format, child.attribution))
++ r.retain(child.retain, format)
+ } else if (delta.$modifyOp.check(child)) {
+- r.modify(deltaAttributionToFormat(child.value), attributionToFormat(child.format, child.attribution))
++ r.modify(deltaAttributionToFormat(child.value, func), format)
+ } else {
+ error.unexpectedCase()
+ }
+@@ -61,235 +118,864 @@ const deltaAttributionToFormat = s.match()
+ }).done()
+
+ /**
+- * @param {Y.XmlFragment} ytype
+- * @param {object} opts
+- * @param {import('@y/protocols/awareness').Awareness} [opts.awareness]
+- * @param {Y.AbstractAttributionManager} [opts.attributionManager]
+- * @returns {Plugin}
++ * This class is the state of the sync plugin, it is essentially the public API for the sync plugin
+ */
+-export function syncPlugin (ytype, { awareness = null, attributionManager = Y.noAttributionsManager } = {}) {
+- const mutex = mux.createMutex()
++export class SyncPluginState {
++ /**
++ * @type {Y.DiffAttributionManager}
++ */
++ #attributionManager
+
+ /**
+- * Initialize the prosemirror state with what is in the ydoc
+- * @param {EditorView} view
++ * @type {Y.Doc | null}
+ */
+- function init (view) {
+- if (view.isDestroyed) {
+- return
++ #suggestionDoc = null
++
++ /**
++ * @type {Y.Doc}
++ */
++ #contentDoc = null
++
++ /**
++ * @type {typeof defaultMapAttributionToMark}
++ */
++ #mapAttributionToMark
++
++ /**
++ * @type {import('prosemirror-view').EditorView | null}
++ */
++ #view = null
++
++ /**
++ * This is the subscription to the ydoc changes
++ * @type {null | (() => void)}
++ */
++ #subscription = null
++
++ /**
++ * Get the view that the sync plugin is attached to
++ * @returns {import('prosemirror-view').EditorView}
++ * @private
++ */
++ get view () {
++ if (!this.#view) {
++ throw new Error('[y/prosemirror]: view not set')
+ }
++ return this.#view
++ }
+
+- // Initialize the prosemirror state with what is in the ydoc
+- const initialPDelta = nodeToDelta(view.state.doc)
+- const d = deltaAttributionToFormat(ytype.getContent(attributionManager, { deep: true }))
+- const initDelta = delta.diff(initialPDelta.done(), d)
++ #mutex = mux.createMutex()
+
+- // TODO this need a mutex?
+- mutex(() => {
+- const tr = deltaToPSteps(view.state.tr, initDelta.done())
+- // TODO revisit all of the meta stuff
+- tr.setMeta(ySyncPluginKey, { init: true })
+- view.dispatch(tr)
+- })
++ /**
++ * @type {SyncPluginMode}
++ */
++ #state
++
++ /**
++ * @param {object} ctx
++ * @param {Y.XmlFragment} ctx.ytype
++ * @param {Y.DiffAttributionManager} [ctx.attributionManager]
++ * @param {typeof defaultMapAttributionToMark} [ctx.mapAttributionToMark]
++ * @param {Y.Doc} [ctx.suggestionDoc] A {@link Y.Doc} to use for suggestion tracking
++ * @param {Y.Doc} ctx.contentDoc A {@link Y.Doc} to use for content tracking
++ */
++ constructor ({ ytype, attributionManager, mapAttributionToMark, suggestionDoc, contentDoc }) {
++ if (!ytype || !ytype.doc) {
++ throw new Error('[y/prosemirror]: ytype not provided')
++ }
++ this.#attributionManager = attributionManager || Y.noAttributionsManager
++ this.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ ytype,
++ showSuggestions: false
++ }
++ this.#mapAttributionToMark = mapAttributionToMark || defaultMapAttributionToMark
++ this.#suggestionDoc = suggestionDoc || null
++ this.#contentDoc = contentDoc
+ }
+
+ /**
+- * @param {EditorView} view
+- * @returns {function(Array>, Y.Transaction): void}
++ * This takes a prosemirror transaction and attempts to update the internal plugin state
++ * @param {import('prosemirror-state').Transaction} tr
++ * @returns {SyncPluginState}
++ * @private
+ */
+- function getOnChangeHandler (view) {
+- return function onChange (events, tr) {
+- mutex(() => {
+- /**
+- * @type {Y.YEvent}
+- */
+- const event = events.find(event => event.target === ytype) || new Y.YEvent(ytype, tr, new Set(null))
+- const d = attributionManager === Y.noAttributionsManager ? event.deltaDeep : deltaAttributionToFormat(event.getDelta(attributionManager, { deep: true }))
+- const ptr = deltaToPSteps(view.state.tr, d)
+- console.log('ytype emitted event', d.toJSON(), 'and applied changes to pm', ptr.steps)
+- ptr.setMeta(ySyncPluginKey, { ytypeEvent: true })
+- view.dispatch(ptr)
+- }, () => {
+- if (attributionManager !== Y.noAttributionsManager) {
+- const itemsToRender = Y.mergeIdSets([tr.insertSet, tr.deleteSet])
+- /**
+- * @todo this could be automatically be calculated in getContent/getDelta when
+- * itemsToRender is provided
+- * @type {Map>}
+- */
+- const modified = new Map()
+- Y.iterateStructsByIdSet(tr, itemsToRender, item => {
+- while (item instanceof Y.Item) {
+- const parent = /** @type {Y.AbstractType} */ (item.parent)
+- const conf = map.setIfUndefined(modified, parent, set.create)
+- if (conf.has(item.parentSub)) break // has already been marked as modified
+- conf.add(item.parentSub)
+- item = parent._item
+- }
+- })
++ onApplyTr (tr) {
++ /** @type {YSyncPluginMeta | undefined} */
++ const pluginMeta = tr.getMeta(ySyncPluginKey)
++ if (!pluginMeta) {
++ return this
++ }
+
+- if (modified.has(ytype)) {
+- setTimeout(() => {
+- mutex(() => {
+- const d = deltaAttributionToFormat(ytype.getContent(attributionManager, { itemsToRender, retainInserts: true, deep: true, modified }))
+- const ptr = deltaToPSteps(view.state.tr, d)
+- ptr.setMeta(ySyncPluginKey, { attributionFix: true })
+- console.log('attribution fix event: ', d.toJSON(), 'and applied changes to pm', ptr.steps)
+- view.dispatch(ptr)
+- })
+- }, 0)
++ const nextState = this.#clone()
++ switch (pluginMeta.type) {
++ /**
++ * For an ideal prosemirror binding, we should only commit the state once the view has been updated to the new editor state
++ * Technically, there can be a number of editor state transitions between, but we only care about the state that gets committed to the view
++ * So:
++ * 1. we capture the transactions that are local-updates, in `appendTransaction`
++ * 2. when state.apply(tr) is called, we generate a delta of the changes that we captured (merging any other states we found between such as additional appendTransaction plugins)
++ * 3. when view.updateState(state) is called, we then synchronize that delta back to the ytype to sync the changes to peers
++ *
++ * This allows the sync plugin to be in any order within the prosemirror plugins array, since it will be committed once the view's state has been applied
++ */
++ case 'local-update':{
++ if (this.#state.type !== 'sync' && this.#state.type !== 'paused') {
++ // No-op since we are not in sync mode
++ return this
++ }
++
++ const { capturedTransactions } = pluginMeta
++
++ // We queue up local-updates by merging all of the transactions that have been captured
++ const transform = new Transform(capturedTransactions[0].before)
++
++ for (let i = 0; i < capturedTransactions.length; i++) {
++ for (let j = 0; j < capturedTransactions[i].steps.length; j++) {
++ const success = transform.maybeStep(capturedTransactions[i].steps[j])
++ if (success.failed) {
++ // step failed, fallback to full diff
++ console.error('[y/prosemirror]: step failed to apply, falling back to a full diff')
++
++ const nextDelta = docDiffToDelta(capturedTransactions[0].before, capturedTransactions[capturedTransactions.length - 1].after)
++ // TODO what should the right behavior here be?
++ nextState.#state = {
++ type: this.#state.type,
++ pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions,
++ contentDocSnapshot: this.#state.contentDocSnapshot
++ }
++ return nextState
++ }
+ }
+ }
+- })
+- }
+- }
++ // Then trying to derive the delta that they represent
++ const nextDelta = trToDelta(transform)
+
+- return new Plugin({
+- key: ySyncPluginKey,
+- state: {
+- init: () => {
+- return {
+- ytype
++ // And, either applying that delta to the already pendingDelta, or promoting that delta to being the next pending delta
++ nextState.#state = {
++ type: this.#state.type,
++ ytype: this.#state.ytype,
++ pendingDelta: this.#state.pendingDelta ? this.#state.pendingDelta.apply(nextDelta) : nextDelta,
++ showSuggestions: this.#state.showSuggestions,
++ contentDocSnapshot: this.#state.contentDocSnapshot
+ }
++ return nextState
+ }
+- },
+- view: (view) => {
+- // initialize the prosemirror state with what is in the ydoc
+- const timeoutId = setTimeout(() => init(view), 0)
++ case 'render-snapshot':{
++ nextState.#state = {
++ type: 'snapshot',
++ snapshot: pluginMeta.snapshot,
++ prevSnapshot: pluginMeta.prevSnapshot,
++ pendingDelta: null,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ }
++ return nextState
++ }
++ case 'resume-sync': {
++ // Move back to sync mode
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ }
++ return nextState
++ }
++ case 'pause-sync':{
++ // Move to paused mode
++ nextState.#state = {
++ type: 'paused',
++ pendingDelta: null,
++ snapshot: Y.snapshot(this.#contentDoc),
++ ytype: this.#state.ytype,
++ showSuggestions: this.#state.showSuggestions
++ }
+
+- const onChange = getOnChangeHandler(view)
+- // subscribe to the ydoc changes
+- ytype.observeDeep(onChange)
++ return nextState
++ }
++ case 'show-suggestions':{
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ // switch to the suggestion doc
++ ytype: findTypeInOtherYdoc(this.#state.ytype, this.#suggestionDoc),
++ showSuggestions: true
++ }
+
+- return {
+- destroy: () => {
+- // clear the initialization timeout
+- clearTimeout(timeoutId)
+- // unsubscribe from the ydoc changes
+- ytype.unobserveDeep(onChange)
++ return nextState
++ }
++ case 'hide-suggestions':{
++ nextState.#state = {
++ type: 'sync',
++ pendingDelta: null,
++ // switch to the content doc
++ ytype: findTypeInOtherYdoc(this.#state.ytype, this.#contentDoc),
++ showSuggestions: false
+ }
++ return nextState
+ }
+- },
+- appendTransaction (transactions, oldState) {
+- transactions = transactions.filter(doc => doc.docChanged)
+- if (transactions.length === 0) return undefined
++ }
+
+- // merge all transactions into a single transform
+- const tr = new Transform(oldState.doc)
++ return this
++ }
++
++ /**
++ * This will be `true` if the plugin state is initialized and the view is not destroyed
++ */
++ get initialized () {
++ return this.#view && !this.#view.isDestroyed
++ }
+
+- for (let i = 0; i < transactions.length; i++) {
+- for (let j = 0; j < transactions[i].steps.length; j++) {
+- tr.step(transactions[i].steps[j])
++ /**
++ * Apply any pending diffs to the ytype
++ * @param {import('prosemirror-state').EditorState} prevState
++ * @private
++ */
++ onViewUpdate (prevState) {
++ if (!this.initialized) {
++ return
++ }
++ const prevPluginState = ySyncPluginKey.getState(prevState)
++ switch (this.#state.type) {
++ case 'snapshot':{
++ if (prevPluginState.#state.type === 'snapshot') {
++ // Already in snapshot mode, so we don't need to do anything
++ return
+ }
++ // Just transitioned from another mode, so we need to actually apply the snapshot mode
++
++ // Stop observing the ydoc changes, since we are looking at a snapshot in time
++ this.destroy()
++ return
+ }
++ case 'sync':{
++ if (this.#state.showSuggestions !== prevPluginState.#state.showSuggestions) {
++ // We are entering/leaving suggestion mode, so we need to subscribe to the suggestion doc
++ // stop observing the ytype
++ this.destroy()
++ // subscribe to the suggestion doc
++ this.#subscribeToYType()
++ return
++ }
++ if (prevPluginState.#state.type === 'paused' || prevPluginState.#state.type === 'snapshot') {
++ // was just paused, so we need to resume sync
+
+- mutex(() => {
+- const d = trToDelta(tr)
+- console.log('editor received steps', tr.steps, 'and and applied delta to ytyp', d.toJSON())
+- ytype.applyDelta(d, attributionManager)
+- })
++ // Restart the observer for two-way sync again
++ this.#subscribeToYType()
++ return
++ }
++ if (!this.#state.pendingDelta) {
++ return
++ }
++ this.#mutex(() => {
++ const d = this.#state.pendingDelta
++ // clear the delta so that we don't accidentally apply it again
++ this.#state.pendingDelta = null
++
++ this.#state.ytype.doc.transact(() => {
++ // If the ytype has not yet been initialized
++ if (this.#state.ytype.length === 0) {
++ // Apply the previous prosemirror document to the ytype, so that the pending delta can operate on the correct content
++ pmToFragment(prevState.doc, this.#state.ytype, {
++ attributionManager: this.#state.showSuggestions ? this.#attributionManager : Y.noAttributionsManager
++ })
++ }
++ this.#state.ytype.applyDelta(d, this.#attributionManager)
++ }, ySyncPluginKey)
++ })
++
++ return undefined
++ }
+ }
+- })
+-}
++ }
+
+-export class YEditorView extends EditorView {
+- /**
+- * @param {ConstructorParameters[0]} mnt
+- * @param {ConstructorParameters[1]} props
+- */
+- constructor (mnt, props) {
+- super(mnt, {
+- ...props,
+- dispatchTransaction: tr => {
+- // Get the new state by applying the transaction
+- const newState = this.state.apply(tr)
+- this.mux(() => {
+- if (tr.docChanged) {
+- const d = trToDelta(tr)
+- console.log('editor received steps', tr.steps, 'and and applied delta to ytyp', d.toJSON())
+- this.y?.ytype.applyDelta(d, this.y.am)
++ /**
++ * @type {ReturnType | undefined}
++ */
++ #initializationTimeoutId = undefined
++
++ /**
++ * Initialize the plugin state with the view
++ * @note this will start the synchronization of the prosemirror state with the ydoc
++ * @param {import('prosemirror-view').EditorView} view
++ * @param {InitializeCallback} [onInitialize]
++ * @private
++ */
++ init (view, onInitialize) {
++ // initialize the prosemirror state with what is in the ydoc
++ // we wait a tick, because in some cases, the view can be immediately destroyed
++ this.#initializationTimeoutId = setTimeout(() => {
++ // clear the timeout id
++ this.#initializationTimeoutId = undefined
++ // Only set the view if we've passed a tick
++ // This gates the initialization of the plugin state until the view is ready
++ this.#view = view
++
++ onInitialize({
++ yjs: {
++ ytype: this.#state.ytype,
++ get hasContent () {
++ return this.ytype.length !== 0
++ },
++ apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {
++ const tr = this.#renderFragment({
++ fragment: this.#state.ytype,
++ showSuggestions: false
++ })
++
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'initialized',
++ ytype: this.#state.ytype
++ }
++ tr.setMeta(ySyncPluginKey, pluginMeta)
++ this.view.dispatch(tr)
+ }
++ },
++ pm: {
++ doc: view.state.doc,
++ get hasContent () {
++ return view.state.doc.content.findDiffStart(
++ view.state.doc.type.createAndFill().content
++ ) !== null
++ },
++ apply: ({ showSuggestions = this.#state.showSuggestions } = {}) => {
++ this.#state.ytype.doc.transact(() => {
++ pmToFragment(view.state.doc, this.#state.ytype, {
++ attributionManager: showSuggestions ? this.#attributionManager : Y.noAttributionsManager
++ })
++ }, ySyncPluginKey)
++ }
++ }
++ })
++
++ // subscribe to the ydoc changes, after initialization is complete
++ this.#subscribeToYType()
++ }, 0)
++ }
++
++ /**
++ * Subscribe to the ydoc changes, and register a cleanup function to unsubscribe when the view is destroyed
++ * @private
++ */
++ #subscribeToYType () {
++ if (!this.#view) {
++ throw new Error('[y/prosemirror]: view not set')
++ }
++
++ if (this.#subscription) {
++ // re-use the existing subscription, since it operates on the latest plugin state
++ return
++ }
++ const attrCb = this.#attributionManager.on('change', (changes) => {
++ if (this.#state.ytype.doc !== this.#suggestionDoc) {
++ // this should not happen
++ console.info('tried to update attributions, but suggestion doc is not active. The diffing attribution manager should not be active when no diff is created - use the "noAttributionManager instead')
++ return
++ }
++ /**
++ * @type {Map>}
++ */
++ const modified = new Map()
++ this.#suggestionDoc.transact(tr => {
++ Y.iterateStructsByIdSet(tr, changes, item => {
++ map.setIfUndefined(modified, item.parent, () => new Set()).add(item.parentSub)
+ })
+- this.updateState(newState)
++ })
++ const d = this.#state.ytype.getContent(this.#attributionManager, { modified, itemsToRender: changes, retainInserts: true, retainDeletes: true, deep: true })
++ console.log('delta update by attribution manager', d.toJSON())
++ const tr = deltaToPSteps(this.#tr, d)
++ console.log('transaction', tr)
++ /** @type {YSyncPluginMeta} */
++ const pluginMeta = {
++ type: 'attribution-fixup',
++ changes
+ }
++ tr.setMeta(ySyncPluginKey, pluginMeta)
++ this.view.dispatch(tr)
+ })
+- this.mux = mux.createMutex()
+- /**
+- * @type {{ ytype: Y.XmlFragment, am: Y.AbstractAttributionManager, awareness: any }?}
+- */
+- this.y = null
+- /**
+- * @param {Array>} events
+- * @param {Y.Transaction} tr
+- */
+- this._observer = (events, tr) => {
+- this.mux(() => {
+- /**
+- * @type {Y.YEvent}
++ // This stores whether the ytype has loaded any content yet
++ // If it has not, then we need to apply changes to it slightly differently in #onChangeYType
++ let isYTypeInitialized = !!this.#state.ytype.length
++ // This is the callback that we will subscribe & unsubscribe to the ydoc changes
++ const yTypeCb = this.#state.ytype.observeDeep((evt, tr) => {
++ if (!this.#view || this.#view.isDestroyed) {
++ // view is destroyed, just clean up the subscription, and no-op
++ this.#subscription()
++ return
++ }
++
++ // fetch the latest plugin state
++ const pluginState = ySyncPluginKey.getState(this.#view.state)
++ if (!pluginState) {
++ throw new Error('[y/prosemirror]: plugin state not found in view.state')
++ }
++
++ // call the onYTypeEvent handler on that instance
++ pluginState.#onChangeYType(evt, tr, isYTypeInitialized)
++ // We got an event, so the ytype should now be initialized
++ isYTypeInitialized = true
++ })
++
++ this.#subscription = () => {
++ this.#subscription = null
++ this.#state.ytype.unobserveDeep(yTypeCb)
++ this.#attributionManager.off('change', attrCb)
++ }
++ }
++
++ /**
++ * Destroy the plugin state
++ * @note this will stop the synchronization of the prosemirror state with the ydoc
++ * @private
++ */
++ destroy () {
++ // clear the initialization timeout
++ clearTimeout(this.#initializationTimeoutId)
++ if (this.#subscription) {
++ // unsubscribe from the ydoc changes
++ this.#subscription()
++ this.#subscription = null
++ }
++ }
++
++ /**
++ * This is the event handler for when the ytype changes, applying remote changes to the editor content
++ * @note this must be a stable reference to be unobserved later
++ * @param {Array>} events
++ * @param {Y.Transaction} tr
++ * @param {boolean} isYTypeInitialized Whether the ytype has already been initialized
++ */
++ #onChangeYType (events, tr, isYTypeInitialized) {
++ // bail if: the view is destroyed OR we are not in "sync" mode
++ if (!this.initialized || this.#state.type !== 'sync') {
++ return
++ }
++
++ this.#mutex(() => {
++ /**
++ * @type {Y.YEvent}
++ */
++ const event = events.find(event => event.target === this.#state.ytype) || new Y.YEvent(this.#state.ytype, tr, new Set(null))
++ let d = deltaAttributionToFormat(event.getDelta(this.#state.showSuggestions ? this.#attributionManager : Y.noAttributionsManager, { deep: true }), this.#mapAttributionToMark).done()
++
++ if (!isYTypeInitialized) {
++ // Here is the sequence of events:
++ // 1. The prosemirror document is empty (e.g. )
++ // 2. The ytype is empty
++ // 3. We get an update, which describes the document as
Hello, world!
++ // If we apply the delta directly, then the prosemirror document will be