0
# Utilities
1
2
Y-ProseMirror provides utility functions for converting between ProseMirror and Yjs data structures, managing positions in collaborative contexts, and handling document persistence.
3
4
## Capabilities
5
6
### Document Conversion Functions
7
8
Convert between ProseMirror and Yjs document formats for data migration, persistence, and initialization.
9
10
#### ProseMirror to Yjs Conversion
11
12
```javascript { .api }
13
/**
14
* Convert ProseMirror document to Yjs document
15
* @param doc - ProseMirror document node
16
* @param xmlFragment - XML fragment name (default: 'prosemirror')
17
* @returns Yjs document containing the converted content
18
*/
19
function prosemirrorToYDoc(doc: Node, xmlFragment?: string): Y.Doc;
20
21
/**
22
* Convert ProseMirror document to Yjs XML fragment
23
* @param doc - ProseMirror document node
24
* @param xmlFragment - Yjs XML fragment to populate
25
* @returns Yjs XML fragment with converted content
26
*/
27
function prosemirrorToYXmlFragment(doc: Node, xmlFragment: Y.XmlFragment): Y.XmlFragment;
28
29
/**
30
* Convert ProseMirror JSON state to Yjs document
31
* @param schema - ProseMirror schema for document structure
32
* @param state - JSON representation of ProseMirror state
33
* @param xmlFragment - XML fragment name (default: 'prosemirror')
34
* @returns Yjs document containing the converted content
35
*/
36
function prosemirrorJSONToYDoc(schema: Schema, state: object, xmlFragment?: string): Y.Doc;
37
38
/**
39
* Convert ProseMirror JSON state to Yjs XML fragment
40
* @param schema - ProseMirror schema for document structure
41
* @param state - JSON representation of ProseMirror state
42
* @param xmlFragment - Yjs XML fragment to populate
43
* @returns Yjs XML fragment with converted content
44
*/
45
function prosemirrorJSONToYXmlFragment(
46
schema: Schema,
47
state: object,
48
xmlFragment: Y.XmlFragment
49
): Y.XmlFragment;
50
```
51
52
#### Yjs to ProseMirror Conversion
53
54
```javascript { .api }
55
/**
56
* Convert Yjs XML fragment to ProseMirror fragment
57
* @param yXmlFragment - Yjs XML fragment to convert
58
* @param schema - ProseMirror schema for document structure
59
* @returns ProseMirror fragment with converted content
60
*/
61
function yXmlFragmentToProseMirrorFragment(
62
yXmlFragment: Y.XmlFragment,
63
schema: Schema
64
): Fragment;
65
66
/**
67
* Convert Yjs XML fragment to ProseMirror root node
68
* @param yXmlFragment - Yjs XML fragment to convert
69
* @param schema - ProseMirror schema for document structure
70
* @returns ProseMirror document node with converted content
71
*/
72
function yXmlFragmentToProseMirrorRootNode(
73
yXmlFragment: Y.XmlFragment,
74
schema: Schema
75
): Node;
76
77
/**
78
* Initialize ProseMirror document from Yjs fragment with mapping metadata
79
* @param yXmlFragment - Yjs XML fragment to convert
80
* @param schema - ProseMirror schema for document structure
81
* @returns Object containing document, metadata, and mapping information
82
*/
83
function initProseMirrorDoc(yXmlFragment: Y.XmlFragment, schema: Schema): {
84
doc: Node;
85
meta: BindingMetadata;
86
mapping: ProsemirrorMapping;
87
};
88
```
89
90
**Usage Examples:**
91
92
```javascript
93
import * as Y from "yjs";
94
import { Schema } from "prosemirror-model";
95
import {
96
prosemirrorToYDoc,
97
yXmlFragmentToProseMirrorRootNode,
98
initProseMirrorDoc
99
} from "y-prosemirror";
100
101
// Convert ProseMirror document to Yjs for persistence
102
const ydoc = prosemirrorToYDoc(pmDoc);
103
104
// Initialize ProseMirror from existing Yjs content
105
const yXmlFragment = ydoc.getXmlFragment("prosemirror");
106
const { doc, meta, mapping } = initProseMirrorDoc(yXmlFragment, schema);
107
108
// Convert Yjs content back to ProseMirror
109
const pmDoc = yXmlFragmentToProseMirrorRootNode(yXmlFragment, schema);
110
```
111
112
### Position and Selection Utilities
113
114
Manage positions and selections in collaborative editing contexts using relative positions that remain valid across document changes.
115
116
```javascript { .api }
117
/**
118
* Convert ProseMirror absolute position to Yjs relative position
119
* @param pos - Absolute position in ProseMirror document
120
* @param type - Yjs type containing the position
121
* @param mapping - Mapping between Yjs and ProseMirror nodes
122
* @returns Yjs relative position that persists across changes
123
*/
124
function absolutePositionToRelativePosition(
125
pos: number,
126
type: Y.AbstractType,
127
mapping: ProsemirrorMapping
128
): Y.RelativePosition;
129
130
/**
131
* Convert Yjs relative position to ProseMirror absolute position
132
* @param y - Yjs document instance
133
* @param documentType - Yjs document type
134
* @param relPos - Yjs relative position
135
* @param mapping - Mapping between Yjs and ProseMirror nodes
136
* @returns Absolute position in ProseMirror document, or null if invalid
137
*/
138
function relativePositionToAbsolutePosition(
139
y: Y.Doc,
140
documentType: Y.AbstractType,
141
relPos: Y.RelativePosition,
142
mapping: ProsemirrorMapping
143
): number | null;
144
145
/**
146
* Get current selection as relative positions for collaboration
147
* @param pmbinding - ProseMirror binding instance
148
* @param state - Current editor state
149
* @returns Selection object with relative positions
150
*/
151
function getRelativeSelection(pmbinding: ProsemirrorBinding, state: EditorState): {
152
type: string;
153
anchor: Y.RelativePosition;
154
head: Y.RelativePosition;
155
};
156
157
/**
158
* Set metadata on ProseMirror view with deferred update
159
* @param view - ProseMirror editor view
160
* @param key - Metadata key
161
* @param value - Metadata value
162
*/
163
function setMeta(view: EditorView, key: any, value: any): void;
164
```
165
166
**Usage Examples:**
167
168
```javascript
169
import {
170
absolutePositionToRelativePosition,
171
relativePositionToAbsolutePosition,
172
getRelativeSelection
173
} from "y-prosemirror";
174
175
// Store cursor position that persists across document changes
176
const relativePos = absolutePositionToRelativePosition(
177
state.selection.anchor,
178
yXmlFragment,
179
binding.mapping
180
);
181
182
// Restore cursor position from stored relative position
183
const absolutePos = relativePositionToAbsolutePosition(
184
ydoc,
185
yXmlFragment,
186
relativePos,
187
binding.mapping
188
);
189
190
// Get current selection for sharing with other users
191
const selection = getRelativeSelection(binding, state);
192
```
193
194
### Deprecated Functions
195
196
Legacy conversion functions that are maintained for backwards compatibility but should be avoided in new code.
197
198
```javascript { .api }
199
/**
200
* @deprecated Use yXmlFragmentToProseMirrorRootNode instead
201
* Convert Yjs document to ProseMirror node
202
* @param schema - ProseMirror schema for document structure
203
* @param ydoc - Yjs document to convert
204
* @param xmlFragment - XML fragment name (optional)
205
*/
206
function yDocToProsemirror(schema: Schema, ydoc: Y.Doc, xmlFragment?: string): Node;
207
208
/**
209
* @deprecated Use yXmlFragmentToProseMirrorRootNode instead
210
* Convert Yjs XML fragment to ProseMirror node
211
* @param schema - ProseMirror schema for document structure
212
* @param yXmlFragment - Yjs XML fragment to convert
213
*/
214
function yXmlFragmentToProsemirror(schema: Schema, yXmlFragment: Y.XmlFragment): Node;
215
216
/**
217
* @deprecated Use appropriate conversion functions instead
218
* Convert Yjs document to ProseMirror JSON
219
* @param schema - ProseMirror schema for document structure
220
* @param ydoc - Yjs document to convert
221
* @param xmlFragment - XML fragment name (optional)
222
*/
223
function yDocToProsemirrorJSON(schema: Schema, ydoc: Y.Doc, xmlFragment?: string): object;
224
225
/**
226
* @deprecated Use appropriate conversion functions instead
227
* Convert Yjs XML fragment to ProseMirror JSON
228
* @param schema - ProseMirror schema for document structure
229
* @param yXmlFragment - Yjs XML fragment to convert
230
*/
231
function yXmlFragmentToProsemirrorJSON(schema: Schema, yXmlFragment: Y.XmlFragment): object;
232
```
233
234
### Internal Utility Functions
235
236
Internal helper functions that are exported for advanced usage scenarios.
237
238
```javascript { .api }
239
/**
240
* Update Yjs fragment from ProseMirror node
241
* @param y - Yjs document
242
* @param yDomFragment - Yjs fragment to update
243
* @param pNode - ProseMirror node
244
* @param meta - Binding metadata
245
*/
246
function updateYFragment(y: Y.Doc, yDomFragment: Y.XmlFragment, pNode: Node, meta: BindingMetadata): void;
247
248
/**
249
* Create ProseMirror node from Yjs element
250
* @param yElement - Yjs element
251
* @param schema - ProseMirror schema
252
* @param meta - Binding metadata
253
* @returns ProseMirror node
254
*/
255
function createNodeFromYElement(yElement: Y.XmlElement, schema: Schema, meta: BindingMetadata): Node;
256
257
/**
258
* Create empty binding metadata
259
* @returns Empty binding metadata object
260
*/
261
function createEmptyMeta(): BindingMetadata;
262
263
/**
264
* Check if Yjs item is visible in snapshot
265
* @param item - Yjs item to check
266
* @param snapshot - Snapshot to check against
267
* @returns true if item is visible
268
*/
269
function isVisible(item: any, snapshot?: Snapshot): boolean;
270
271
/**
272
* Generate hash of JSON object for content comparison
273
* @param obj - JSON object to hash
274
* @returns String hash of the object
275
*/
276
function hashOfJSON(obj: object): string;
277
```
278
279
## Types
280
281
```javascript { .api }
282
/** Mapping between Yjs types and ProseMirror nodes */
283
type ProsemirrorMapping = Map<Y.AbstractType<any>, PModel.Node | Array<PModel.Node>>;
284
285
/** Metadata structure for binding state */
286
interface BindingMetadata {
287
mapping: ProsemirrorMapping;
288
isOMark: Map<import('prosemirror-model').MarkType, boolean>;
289
}
290
```