Socket
Socket
Sign inDemoInstall

y-prosemirror

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

y-prosemirror - npm Package Compare versions

Comparing version 0.3.7 to 1.0.0

dist/src/plugins/keys.d.ts

47

dist/src/lib.d.ts

@@ -0,3 +1,46 @@

/**
* Utility method to convert a Prosemirror Doc Node into a Y.Doc.
*
* This can be used when importing existing content to Y.Doc for the first time,
* note that this should not be used to rehydrate a Y.Doc from a database once
* collaboration has begun as all history will be lost
*
* @param {Node} doc
* @param {string} xmlFragment
* @return {Y.Doc}
*/
export function prosemirrorToYDoc(doc: Node, xmlFragment?: string): any;
/**
* Utility method to convert Prosemirror compatible JSON into a Y.Doc.
*
* This can be used when importing existing content to Y.Doc for the first time,
* note that this should not be used to rehydrate a Y.Doc from a database once
* collaboration has begun as all history will be lost
*
* @param {Schema} schema
* @param {any} state
* @param {string} xmlFragment
* @return {Y.Doc}
*/
export function prosemirrorJSONToYDoc(schema: Schema, state: any, xmlFragment?: string): any;
/**
* Utility method to convert a Y.Doc to a Prosemirror Doc node.
*
* @param {Schema} schema
* @param {Y.Doc} ydoc
* @return {Node}
*/
export function yDocToProsemirror(schema: Schema, ydoc: any): Node;
/**
* Utility method to convert a Y.Doc to Prosemirror compatible JSON.
*
* @param {Y.Doc} ydoc
* @param {string} xmlFragment
* @return {Record<string, any>}
*/
export function yDocToProsemirrorJSON(ydoc: any, xmlFragment?: string): Record<string, any>;
export function setMeta(view: any, key: any, value: any): void;
export function absolutePositionToRelativePosition(pos: number, type: any, mapping: Map<any, import("prosemirror-model").Node<any> | import("prosemirror-model").Node<any>[]>): any;
export function relativePositionToAbsolutePosition(y: any, documentType: any, relPos: any, mapping: Map<any, import("prosemirror-model").Node<any> | import("prosemirror-model").Node<any>[]>): null | number;
export function absolutePositionToRelativePosition(pos: number, type: any, mapping: Map<any, Node<any> | Node<any>[]>): any;
export function relativePositionToAbsolutePosition(y: any, documentType: any, relPos: any, mapping: Map<any, Node<any> | Node<any>[]>): null | number;
import { Node } from "prosemirror-model";
import { Schema } from "prosemirror-model";

7

dist/src/plugins/cursor-plugin.d.ts

@@ -1,7 +0,1 @@

/**
* The unique prosemirror plugin key for cursorPlugin.type
*
* @public
*/
export const yCursorPluginKey: PluginKey<any, any>;
export function defaultCursorBuilder(user: any): HTMLSpanElement;

@@ -14,3 +8,2 @@ export function createDecorations(state: any, awareness: Awareness, createCursor: any): any;

}, cursorStateField?: string): any;
import { PluginKey } from "prosemirror-state";
import { Awareness } from "y-protocols/awareness";
export function isVisible(item: any, snapshot?: any): boolean;
/**
* Either a node if type is YXmlElement or an Array of text nodes if YXmlText
* @typedef {Map<Y.AbstractType, PModel.Node | Array<PModel.Node>>} ProsemirrorMapping
*/
/**
* The unique prosemirror plugin key for prosemirrorPlugin.
*
* @public
*/
export const ySyncPluginKey: PluginKey<any, any>;
export function ySyncPlugin(yXmlFragment: any, { colors, colorMapping, permanentUserData }?: YSyncOpts): any;

@@ -67,9 +57,3 @@ export function getRelativeSelection(pmbinding: any, state: any): {

}
export function createNodeIfNotExists(el: any | any, schema: PModel.Schema, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>, snapshot?: any, prevSnapshot?: any, computeYChange?: (arg0: 'removed' | 'added', arg1: any) => any): PModel.Node | null;
export function createNodeFromYElement(el: any, schema: any, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>, snapshot?: any, prevSnapshot?: any, computeYChange?: (arg0: 'removed' | 'added', arg1: any) => any): PModel.Node | null;
export function createTextNodesFromYText(text: any, schema: any, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>, snapshot?: any, prevSnapshot?: any, computeYChange?: (arg0: 'removed' | 'added', arg1: any) => any): Array<PModel.Node> | null;
export function createTypeFromTextNodes(nodes: Array<any>, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>): any;
export function createTypeFromElementNode(node: any, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>): any;
export function createTypeFromTextOrElementNode(node: PModel.Node | Array<PModel.Node>, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>): any | any;
export function normalizePNodeContent(pnode: any): (PModel.Node<any> | PModel.Node<any>[])[];
export function updateYFragment(y: any, yDomFragment: any, pNode: any, mapping: Map<any, PModel.Node<any> | PModel.Node<any>[]>): void;
/**

@@ -89,3 +73,2 @@ * Either a node if type is YXmlElement or an Array of text nodes if YXmlText

export type NormalizedPNodeContent = (PModel.Node<any> | PModel.Node<any>[])[];
import { PluginKey } from "prosemirror-state";
import * as PModel from "prosemirror-model";
export function undo(state: any): boolean;
export function redo(state: any): boolean;
export const yUndoPluginKey: PluginKey<any, any>;
export function yUndoPlugin({ protectedNodes, trackedOrigins }?: {

@@ -8,3 +7,2 @@ protectedNodes?: Set<string>;

}): Plugin<any, any>;
import { PluginKey } from "prosemirror-state";
import { Plugin } from "prosemirror-state";
export * from "./plugins/cursor-plugin.js";
export * from "./plugins/sync-plugin.js";
export * from "./plugins/undo-plugin.js";
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta } from "./lib.js";
export * from "./plugins/keys.js";
export { ySyncPlugin, isVisible, getRelativeSelection, ProsemirrorBinding } from "./plugins/sync-plugin.js";
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, prosemirrorJSONToYDoc, yDocToProsemirrorJSON, yDocToProsemirror, prosemirrorToYDoc } from "./lib.js";
{
"name": "y-prosemirror",
"version": "0.3.7",
"version": "1.0.0",
"description": "Prosemirror bindings for Yjs",

@@ -46,6 +46,3 @@ "main": "./dist/y-prosemirror.cjs",

"dependencies": {
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"lib0": "^0.2.33",
"rollup": "^2.26.11"
"lib0": "^0.2.34"
},

@@ -60,2 +57,4 @@ "peerDependencies": {

"devDependencies": {
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@types/prosemirror-state": "^1.2.5",

@@ -66,6 +65,7 @@ "concurrently": "^4.1.0",

"prosemirror-example-setup": "^1.1.2",
"prosemirror-model": "^1.11.2",
"prosemirror-schema-basic": "^1.0.1",
"prosemirror-model": "^1.12.0",
"prosemirror-schema-basic": "^1.1.2",
"prosemirror-state": "^1.3.3",
"prosemirror-view": "^1.15.7",
"prosemirror-view": "^1.16.1",
"rollup": "^2.33.1",
"standard": "^12.0.1",

@@ -75,4 +75,4 @@ "typescript": "^3.9.7",

"y-webrtc": "^10.1.6",
"yjs": "13.3.2"
"yjs": "^13.4.3"
}
}
# y-prosemirror
> [ProseMirror](http://prosemirror.net/) Binding for [Yjs](https://github.com/yjs/yjs) - [Demo](https://yjs-demos.now.sh/prosemirror/)
> [ProseMirror](http://prosemirror.net/) Binding for [Yjs](https://github.com/yjs/yjs) - [Demo](https://demos.yjs.dev/prosemirror/prosemirror.html)

@@ -125,4 +125,61 @@ This binding maps a Y.XmlFragment to the ProseMirror state.

#### Utilities
The package includes a number of utility methods for converting back and forth between
a Y.Doc and Prosemirror compatible data structures. These can be useful for persisting
to a datastore or for importing existing documents.
> _Note_: Serializing and deserializing to JSON will not store collaboration history
> steps and as such should not be used as the primary storage. You will still need
> to store the Y.Doc binary update format.
```js
import { prosemirrorToYDoc } from 'y-prosemirror'
// Pass JSON previously output from Prosemirror
const doc = Node.fromJSON(schema, {
type: "doc",
content: [...]
})
const ydoc = prosemirrorToYDoc(doc)
```
Because JSON is a common usecase there is an equivalent method that skips the need
to create a Prosemirror Node.
```js
import { prosemirrorJSONToYDoc } from 'y-prosemirror'
// Pass JSON previously output from Prosemirror
const ydoc = prosemirrorJSONToYDoc(schema, {
type: "doc",
content: [...]
})
```
```js
import { yDocToProsemirror } from 'y-prosemirror'
// apply binary updates from elsewhere
const ydoc = new Y.Doc()
ydoc.applyUpdate(update)
const node = yDocToProsemirror(schema, ydoc)
```
Because JSON is a common usecase there is an equivalent method that outputs JSON
directly, this method does not require the Prosemirror schema.
```js
import { yDocToProsemirrorJSON } from 'y-prosemirror'
// apply binary updates from elsewhere
const ydoc = new Y.Doc()
ydoc.applyUpdate(update)
const node = yDocToProsemirrorJSON(ydoc)
```
### License
[The MIT License](./LICENSE) © Kevin Jahns

@@ -1,6 +0,5 @@

import { ProsemirrorMapping } from './plugins/sync-plugin.js' // eslint-disable-line
import { updateYFragment, ProsemirrorMapping } from './plugins/sync-plugin.js' // eslint-disable-line
import * as Y from 'yjs'
// eslint-disable-next-line
import { EditorView } from 'prosemirror-view'
import { EditorView } from 'prosemirror-view' // eslint-disable-line
import { Node, Schema } from 'prosemirror-model' // eslint-disable-line
import * as error from 'lib0/error.js'

@@ -171,1 +170,124 @@ import * as map from 'lib0/map.js'

}
/**
* Utility method to convert a Prosemirror Doc Node into a Y.Doc.
*
* This can be used when importing existing content to Y.Doc for the first time,
* note that this should not be used to rehydrate a Y.Doc from a database once
* collaboration has begun as all history will be lost
*
* @param {Node} doc
* @param {string} xmlFragment
* @return {Y.Doc}
*/
export function prosemirrorToYDoc (doc, xmlFragment = 'prosemirror') {
const ydoc = new Y.Doc()
const type = ydoc.get(xmlFragment, Y.XmlFragment)
if (!type.doc) {
return ydoc
}
updateYFragment(type.doc, type, doc, new Map())
return type.doc
}
/**
* Utility method to convert Prosemirror compatible JSON into a Y.Doc.
*
* This can be used when importing existing content to Y.Doc for the first time,
* note that this should not be used to rehydrate a Y.Doc from a database once
* collaboration has begun as all history will be lost
*
* @param {Schema} schema
* @param {any} state
* @param {string} xmlFragment
* @return {Y.Doc}
*/
export function prosemirrorJSONToYDoc (schema, state, xmlFragment = 'prosemirror') {
const doc = Node.fromJSON(schema, state)
return prosemirrorToYDoc(doc, xmlFragment)
}
/**
* Utility method to convert a Y.Doc to a Prosemirror Doc node.
*
* @param {Schema} schema
* @param {Y.Doc} ydoc
* @return {Node}
*/
export function yDocToProsemirror (schema, ydoc) {
const state = yDocToProsemirrorJSON(ydoc)
return Node.fromJSON(schema, state)
}
/**
* Utility method to convert a Y.Doc to Prosemirror compatible JSON.
*
* @param {Y.Doc} ydoc
* @param {string} xmlFragment
* @return {Record<string, any>}
*/
export function yDocToProsemirrorJSON (
ydoc,
xmlFragment = 'prosemirror'
) {
const items = ydoc.getXmlFragment(xmlFragment).toArray()
function serialize (item) {
/**
* @type {Object} NodeObject
* @property {string} NodeObject.type
* @property {Record<string, string>=} NodeObject.attrs
* @property {Array<NodeObject>=} NodeObject.content
*/
let response
// TODO: Must be a better way to detect text nodes than this
if (!item.nodeName) {
const delta = item.toDelta()
response = delta.map((d) => {
const text = {
type: 'text',
text: d.insert
}
if (d.attributes) {
text.marks = Object.keys(d.attributes).map((type) => {
const attrs = d.attributes[type]
const mark = {
type
}
if (Object.keys(attrs)) {
mark.attrs = attrs
}
return mark
})
}
return text
})
} else {
response = {
type: item.nodeName
}
const attrs = item.getAttributes()
if (Object.keys(attrs).length) {
response.attrs = attrs
}
const children = item.toArray()
if (children.length) {
response.content = children.map(serialize).flat()
}
}
return response
}
return {
type: 'doc',
content: items.map(serialize)
}
}

@@ -6,4 +6,4 @@

import { Awareness } from 'y-protocols/awareness.js' // eslint-disable-line
import { ySyncPluginKey } from './sync-plugin.js'
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta } from '../lib.js'
import { yCursorPluginKey, ySyncPluginKey } from './keys.js'

@@ -13,9 +13,2 @@ import * as math from 'lib0/math.js'

/**
* The unique prosemirror plugin key for cursorPlugin.type
*
* @public
*/
export const yCursorPluginKey = new PluginKey('yjs-cursor')
/**
* Default generator for a cursor element

@@ -22,0 +15,0 @@ *

@@ -7,3 +7,3 @@ /**

import * as PModel from 'prosemirror-model'
import { Plugin, PluginKey, EditorState, TextSelection } from 'prosemirror-state' // eslint-disable-line
import { Plugin, TextSelection } from 'prosemirror-state' // eslint-disable-line
import * as math from 'lib0/math.js'

@@ -14,2 +14,3 @@ import * as object from 'lib0/object.js'

import * as error from 'lib0/error.js'
import { ySyncPluginKey } from './keys.js'
import * as Y from 'yjs'

@@ -33,9 +34,2 @@ import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from '../lib.js'

/**
* The unique prosemirror plugin key for prosemirrorPlugin.
*
* @public
*/
export const ySyncPluginKey = new PluginKey('y-sync')
/**
* @typedef {Object} ColorDef

@@ -384,3 +378,3 @@ * @property {string} ColorDef.light

*/
export const createNodeIfNotExists = (el, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const createNodeIfNotExists = (el, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const node = /** @type {PModel.Node} */ (mapping.get(el))

@@ -407,3 +401,3 @@ if (node === undefined) {

*/
export const createNodeFromYElement = (el, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const createNodeFromYElement = (el, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const children = []

@@ -464,3 +458,3 @@ const createChildren = type => {

*/
export const createTextNodesFromYText = (text, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const createTextNodesFromYText = (text, schema, mapping, snapshot, prevSnapshot, computeYChange) => {
const nodes = []

@@ -494,3 +488,3 @@ const deltas = text.toDelta(snapshot, prevSnapshot, computeYChange)

*/
export const createTypeFromTextNodes = (nodes, mapping) => {
const createTypeFromTextNodes = (nodes, mapping) => {
const type = new Y.XmlText()

@@ -513,3 +507,3 @@ const delta = nodes.map(node => ({

*/
export const createTypeFromElementNode = (node, mapping) => {
const createTypeFromElementNode = (node, mapping) => {
const type = new Y.XmlElement(node.type.name)

@@ -533,3 +527,3 @@ for (const key in node.attrs) {

*/
export const createTypeFromTextOrElementNode = (node, mapping) => node instanceof Array ? createTypeFromTextNodes(node, mapping) : createTypeFromElementNode(node, mapping)
const createTypeFromTextOrElementNode = (node, mapping) => node instanceof Array ? createTypeFromTextNodes(node, mapping) : createTypeFromElementNode(node, mapping)

@@ -556,3 +550,3 @@ const equalAttrs = (pattrs, yattrs) => {

*/
export const normalizePNodeContent = pnode => {
const normalizePNodeContent = pnode => {
const c = pnode.content.content

@@ -699,3 +693,3 @@ const res = []

*/
const updateYFragment = (y, yDomFragment, pNode, mapping) => {
export const updateYFragment = (y, yDomFragment, pNode, mapping) => {
if (yDomFragment instanceof Y.XmlElement && yDomFragment.nodeName !== pNode.type.name) {

@@ -702,0 +696,0 @@ throw new Error('node name mismatch!')

import { Plugin, PluginKey } from 'prosemirror-state' // eslint-disable-line
import { ySyncPluginKey, getRelativeSelection } from './sync-plugin.js'
import { getRelativeSelection } from './sync-plugin.js'
import { UndoManager, Item, ContentType, XmlElement, Text } from 'yjs'
import { yUndoPluginKey, ySyncPluginKey } from './keys.js'

@@ -23,4 +24,2 @@ export const undo = state => {

export const yUndoPluginKey = new PluginKey('y-undo')
export const yUndoPlugin = ({ protectedNodes = new Set(['paragraph']), trackedOrigins = [] } = {}) => new Plugin({

@@ -35,6 +34,6 @@ key: yUndoPluginKey,

deleteFilter: item => !(item instanceof Item) ||
!(item.content instanceof ContentType) ||
!(item.content.type instanceof Text ||
(item.content.type instanceof XmlElement && protectedNodes.has(item.content.type.nodeName))) ||
item.content.type._length === 0
!(item.content instanceof ContentType) ||
!(item.content.type instanceof Text ||
(item.content.type instanceof XmlElement && protectedNodes.has(item.content.type.nodeName))) ||
item.content.type._length === 0
})

@@ -41,0 +40,0 @@ return {

export * from './plugins/cursor-plugin.js'
export * from './plugins/sync-plugin.js'
export { ySyncPlugin, isVisible, getRelativeSelection, ProsemirrorBinding } from './plugins/sync-plugin.js'
export * from './plugins/undo-plugin.js'
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta } from './lib.js'
export * from './plugins/keys.js'
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, prosemirrorJSONToYDoc, yDocToProsemirrorJSON, yDocToProsemirror, prosemirrorToYDoc } from './lib.js'

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc