{"_id":"@athenaintel/y-prosemirror","_rev":"5-1d32c44a05da66a09f8d26f9c6c07a96","name":"@athenaintel/y-prosemirror","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@athenaintel/y-prosemirror","version":"0.0.1","keywords":["Yjs"],"author":{"name":"Kevin Jahns","email":"kevin.jahns@protonmail.com"},"license":"MIT","_id":"@athenaintel/y-prosemirror@0.0.1","maintainers":[{"name":"brendongeils","email":"brendon@athenaintel.com"},{"name":"pablosz","email":"pablosaez1995@gmail.com"},{"name":"aldrinjenson","email":"aldrinjenson@gmail.com"}],"homepage":"https://github.com/yjs/y-prosemirror#readme","bugs":{"url":"https://github.com/yjs/y-prosemirror/issues"},"dist":{"shasum":"e4ec1560b9583d5177b5a2c9de9fefc6f2046d21","tarball":"https://registry.npmjs.org/@athenaintel/y-prosemirror/-/y-prosemirror-0.0.1.tgz","fileCount":22,"integrity":"sha512-vvzOd8k2ZDzn1W8NWss21M0+NSe1H4qN7V9orKhngIj1jEfFu1XKbec/yEEm+b1+Lwpk9FXp17dS7kjurtZlvg==","signatures":[{"sig":"MEQCIBtnf9A4MfZU9+XN0Fq4fLxrjqzwcFH62mGJsWs0coN5AiBc6KBe51o0ERuJbjd/a99tTIfT0Iek750z0nt0iwGpMQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":488837},"main":"./dist/y-prosemirror.cjs","type":"module","types":"./dist/src/y-prosemirror.d.ts","module":"./src/y-prosemirror.js","engines":{"npm":">=8.0.0","node":">=16.0.0"},"exports":{".":{"types":"./dist/src/y-prosemirror.d.ts","import":"./src/y-prosemirror.js","require":"./dist/y-prosemirror.cjs"}},"funding":{"url":"https://github.com/sponsors/dmonad","type":"GitHub Sponsors ❤"},"gitHead":"73632a412750f7f7e585e10348305a8ee8080a11","scripts":{"dist":"npm run clean && rollup -c && (tsc --skipLibCheck || true)","lint":"standard && tsc --skipLibCheck","test":"node ./tests/index.node.js","clean":"rm -rf dist","debug":"concurrently '0serve -o test.html' 'npm run watch'","start":"concurrently '0serve -o demo/prosemirror.html' 'npm run watch'","watch":"rollup -wc","preversion":"npm run dist"},"_npmUser":{"name":"pablosz","email":"pablosaez1995@gmail.com"},"standard":{"ignore":["/dist","/node_modules","/docs"]},"repository":{"url":"git+https://github.com/yjs/y-prosemirror.git","type":"git"},"_npmVersion":"10.9.3","description":"Prosemirror bindings for Yjs","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","dependencies":{"lib0":"^0.2.117"},"_hasShrinkwrap":false,"devDependencies":{"@y/y":"^14.0.0-19","jsdom":"^15.1.1","rollup":"^4.52.5","standard":"^17.0.0","typescript":"^5.9.3","http-server":"^0.12.3","@y/protocols":"^1.0.6-3","@y/websocket":"^4.0.0-3","concurrently":"^4.1.0","prosemirror-view":"^1.26.2","prosemirror-model":"^1.18.1","prosemirror-state":"^1.4.1","prosemirror-transform":"^1.6.0","@rollup/plugin-commonjs":"^28.0.8","prosemirror-schema-basic":"^1.2.0","prosemirror-test-builder":"1.1.1","prosemirror-example-setup":"^1.2.1","@rollup/plugin-node-resolve":"^16.0.3"},"peerDependencies":{"@y/y":"^14.0.0-19","@y/protocols":"^1.0.6-3","prosemirror-view":"^1.9.10","prosemirror-model":"^1.7.1","prosemirror-state":"^1.2.3"},"_npmOperationalInternal":{"tmp":"tmp/y-prosemirror_0.0.1_1771341852445_0.3436323671289274","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-02-17T15:24:12.346Z","modified":"2026-08-26T20:22:39.229Z","0.0.1":"2026-02-17T15:24:12.794Z"},"bugs":{"url":"https://github.com/yjs/y-prosemirror/issues"},"author":{"name":"Kevin Jahns","email":"kevin.jahns@protonmail.com"},"license":"MIT","homepage":"https://github.com/yjs/y-prosemirror#readme","keywords":["Yjs"],"repository":{"url":"git+https://github.com/yjs/y-prosemirror.git","type":"git"},"description":"Prosemirror bindings for Yjs","maintainers":[{"email":"rmdort@gmail.com","name":"rmdort"},{"email":"brendon@athenaintel.com","name":"brendongeils"},{"email":"aldrinjenson@gmail.com","name":"aldrinjenson"}],"readme":"# y-prosemirror\n\n> [ProseMirror](http://prosemirror.net/) Binding for [Yjs](https://github.com/yjs/yjs) - [Demo](https://demos.yjs.dev/prosemirror/prosemirror.html)\n\nThis binding maps a Y.XmlFragment to the ProseMirror state.\n\n## Features\n\n* Sync ProseMirror state\n* Shared Cursors\n* Shared Undo / Redo (each client has its own undo-/redo-history)\n* Successfully recovers when concurrents edit result in an invalid document schema\n\n### Example\n\n```js\nimport { ySyncPlugin, yCursorPlugin, yUndoPlugin, undo, redo, initProseMirrorDoc } from 'y-prosemirror'\nimport { exampleSetup } from 'prosemirror-example-setup'\nimport { keymap } from 'prosemirror-keymap'\n..\n\nconst type = ydocument.get('prosemirror', Y.XmlFragment)\nconst { doc, mapping } = initProseMirrorDoc(type, schema)\n\nconst prosemirrorView = new EditorView(document.querySelector('#editor'), {\n  state: EditorState.create({\n    doc,\n    schema,\n    plugins: [\n        ySyncPlugin(type, { mapping }),\n        yCursorPlugin(provider.awareness),\n        yUndoPlugin(),\n        keymap({\n          'Mod-z': undo,\n          'Mod-y': redo,\n          'Mod-Shift-z': redo\n        })\n      ].concat(exampleSetup({ schema }))\n  })\n})\n```\n\nAlso look [here](https://github.com/yjs/yjs-demos/tree/master/prosemirror) for a working example.\n\n#### Remote Cursors\n\nThe shared cursors depend on the Awareness instance that is exported by most providers. The [Awareness protocol](https://github.com/yjs/y-protocols#awareness-protocol) handles non-permanent data like the number of users, their user names, their cursor location, and their colors. You can change the name and color of the user like this:\n\n```js\nexample.binding.awareness.setLocalStateField('user', { color: '#008833', name: 'My real name' })\n```\n\nIn order to render cursor information you need to embed custom CSS for the user icon. This is a template that you can use for styling cursor information.\n\n```css\n/* this is a rough fix for the first cursor position when the first paragraph is empty */\n.ProseMirror > .ProseMirror-yjs-cursor:first-child {\n  margin-top: 16px;\n}\n.ProseMirror p:first-child, .ProseMirror h1:first-child, .ProseMirror h2:first-child, .ProseMirror h3:first-child, .ProseMirror h4:first-child, .ProseMirror h5:first-child, .ProseMirror h6:first-child {\n  margin-top: 16px\n}\n/* This gives the remote user caret. The colors are automatically overwritten*/\n.ProseMirror-yjs-cursor {\n  position: relative;\n  margin-left: -1px;\n  margin-right: -1px;\n  border-left: 1px solid black;\n  border-right: 1px solid black;\n  border-color: orange;\n  word-break: normal;\n  pointer-events: none;\n}\n/* This renders the username above the caret */\n.ProseMirror-yjs-cursor > div {\n  position: absolute;\n  top: -1.05em;\n  left: -1px;\n  font-size: 13px;\n  background-color: rgb(250, 129, 0);\n  font-family: serif;\n  font-style: normal;\n  font-weight: normal;\n  line-height: normal;\n  user-select: none;\n  color: white;\n  padding-left: 2px;\n  padding-right: 2px;\n  white-space: nowrap;\n}\n```\n\nYou can also overwrite the default Widget dom by specifying a cursor builder in the yCursorPlugin\n\n```js\n/**\n * This function receives the remote users \"user\" awareness state.\n */\nexport const myCursorBuilder = 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  cursor.insertBefore(userDiv, null)\n  return cursor\n}\n\nconst prosemirrorView = new EditorView(document.querySelector('#editor'), {\n  state: EditorState.create({\n    schema,\n    plugins: [\n        ySyncPlugin(type),\n        yCursorPlugin(provider.awareness, { cursorBuilder: myCursorBuilder }),\n        yUndoPlugin(),\n        keymap({\n          'Mod-z': undo,\n          'Mod-y': redo,\n          'Mod-Shift-z': redo\n        })\n      ].concat(exampleSetup({ schema }))\n  })\n})\n```\n\n#### Utilities\n\nThe package includes a number of utility methods for converting back and forth between\na Y.Doc and Prosemirror compatible data structures. These can be useful for persisting\nto a datastore or for importing existing documents.\n\n> _Note_: Serializing and deserializing to JSON will not store collaboration history\n> steps and as such should not be used as the primary storage. You will still need\n> to store the Y.Doc binary update format.\n\n```js\nimport { prosemirrorToYDoc } from 'y-prosemirror'\n\n// Pass JSON previously output from Prosemirror\nconst doc = Node.fromJSON(schema, {\n  type: \"doc\",\n  content: [...]\n})\nconst ydoc = prosemirrorToYDoc(doc)\n```\n\nBecause JSON is a common usecase there is an equivalent method that skips the need\nto create a Prosemirror Node.\n\n```js\nimport { prosemirrorJSONToYDoc } from 'y-prosemirror'\n\n// Pass JSON previously output from Prosemirror\nconst ydoc = prosemirrorJSONToYDoc(schema, {\n  type: \"doc\",\n  content: [...]\n})\n```\n\n```js\nimport { yDocToProsemirror } from 'y-prosemirror'\n\n// apply binary updates from elsewhere\nconst ydoc = new Y.Doc()\nydoc.applyUpdate(update)\n\nconst node = yDocToProsemirror(schema, ydoc)\n```\n\nBecause JSON is a common usecase there is an equivalent method that outputs JSON\ndirectly, this method does not require the Prosemirror schema.\n\n```js\nimport { yDocToProsemirrorJSON } from 'y-prosemirror'\n\n// apply binary updates from elsewhere\nconst ydoc = new Y.Doc()\nydoc.applyUpdate(update)\n\nconst node = yDocToProsemirrorJSON(ydoc)\n```\n\n### Undo/Redo\n\nThe package exports `undo` and `redo` commands which can be used in place of\n[prosemirror-history](https://prosemirror.net/docs/ref/#history) by mapping the\nmod-Z/Y keys - see [ProseMirror](https://github.com/yjs/yjs-demos/blob/main/prosemirror/prosemirror.js#L29)\nand [Tiptap](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-collaboration/src/collaboration.ts)\nexamples.\n\nUndo and redo are be scoped to the local client, so one peer won't undo another's\nchanges. See [Y.UndoManager](https://docs.yjs.dev/api/undo-manager) for more details.\n\nJust like prosemirror-history, you can set a transaction's `addToHistory` meta property\nto false to prevent that transaction from being rolled back by undo. This can be helpful for programmatic\ndocument changes that aren't initiated by the user.\n\n```js\ntr.setMeta(\"addToHistory\", false);\n```\n\n### License\n\n[The MIT License](./LICENSE) © Kevin Jahns\n","readmeFilename":"README.md"}