or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdplugins.mdutilities.md

plugins.mddocs/

0

# Core Plugins

1

2

Y-ProseMirror provides three essential ProseMirror plugins that enable collaborative editing: synchronization, cursor tracking, and collaborative undo/redo functionality.

3

4

## Capabilities

5

6

### Synchronization Plugin (ySyncPlugin)

7

8

Maintains bidirectional synchronization between a Yjs XML fragment and ProseMirror document, ensuring all users see consistent content.

9

10

```javascript { .api }

11

/**

12

* Creates a ProseMirror plugin that synchronizes with a Yjs XML fragment

13

* @param yXmlFragment - The Yjs XML fragment to bind to

14

* @param opts - Optional configuration object with destructured options

15

* @returns ProseMirror Plugin instance

16

*/

17

function ySyncPlugin(yXmlFragment: Y.XmlFragment, opts?: {

18

/** Array of color definitions for user highlighting */

19

colors?: Array<ColorDef>;

20

/** Mapping of users to specific colors */

21

colorMapping?: Map<string, ColorDef>;

22

/** Persistent user data for the session */

23

permanentUserData?: Y.PermanentUserData | null;

24

/** Pre-existing mapping between Yjs and ProseMirror nodes */

25

mapping?: ProsemirrorMapping;

26

/** Callback fired when content initially renders */

27

onFirstRender?: () => void;

28

}): Plugin;

29

30

interface ColorDef {

31

light: string;

32

dark: string;

33

}

34

```

35

36

**Usage Example:**

37

38

```javascript

39

import * as Y from "yjs";

40

import { ySyncPlugin } from "y-prosemirror";

41

42

const ydoc = new Y.Doc();

43

const yXmlFragment = ydoc.getXmlFragment("prosemirror");

44

45

const syncPlugin = ySyncPlugin(yXmlFragment, {

46

colors: [

47

{ light: "#ffeb3b", dark: "#f57f17" },

48

{ light: "#4caf50", dark: "#2e7d32" }

49

],

50

onFirstRender: () => console.log("Content rendered")

51

});

52

```

53

54

### Cursor Plugin (yCursorPlugin)

55

56

Displays collaborative cursors and selections from other editing users using Yjs awareness protocol.

57

58

```javascript { .api }

59

/**

60

* Creates a ProseMirror plugin for displaying collaborative cursors

61

* @param awareness - Yjs awareness instance for cursor tracking

62

* @param opts - Optional configuration object with destructured options

63

* @param cursorStateField - Awareness field name for cursor data (default: 'cursor')

64

* @returns ProseMirror Plugin instance

65

*/

66

function yCursorPlugin(

67

awareness: Awareness,

68

opts?: {

69

/** Filter function for awareness states */

70

awarenessStateFilter?: (currentClientId: number, userClientId: number, user: any) => boolean;

71

/** Custom cursor element builder */

72

cursorBuilder?: (user: any, clientId: number) => HTMLElement;

73

/** Custom selection attributes builder */

74

selectionBuilder?: (user: any, clientId: number) => DecorationAttrs;

75

/** Custom selection getter */

76

getSelection?: (state: EditorState) => Selection;

77

},

78

cursorStateField?: string

79

): Plugin;

80

```

81

82

**Usage Example:**

83

84

```javascript

85

import { Awareness } from "y-protocols/awareness";

86

import { yCursorPlugin } from "y-prosemirror";

87

88

const awareness = new Awareness(ydoc);

89

90

const cursorPlugin = yCursorPlugin(awareness, {

91

cursorBuilder: (user, clientId) => {

92

const cursor = document.createElement("div");

93

cursor.className = "user-cursor";

94

cursor.style.borderColor = user.color;

95

cursor.textContent = user.name;

96

return cursor;

97

},

98

awarenessStateFilter: (currentId, userId, user) => {

99

return currentId !== userId && user.cursor;

100

}

101

});

102

```

103

104

### Undo Plugin (yUndoPlugin)

105

106

Provides collaborative undo/redo functionality with per-user history tracking that respects collaborative document state.

107

108

```javascript { .api }

109

/**

110

* Creates a ProseMirror plugin for collaborative undo/redo operations

111

* @param options - Optional configuration object with destructured options

112

* @returns ProseMirror Plugin instance

113

*/

114

function yUndoPlugin(options?: {

115

/** Set of node types that cannot be deleted during undo */

116

protectedNodes?: Set<string>;

117

/** Origins to track for undo operations */

118

trackedOrigins?: any[];

119

/** Custom undo manager instance */

120

undoManager?: UndoManager | null;

121

}): Plugin;

122

```

123

124

**Usage Example:**

125

126

```javascript

127

import { yUndoPlugin } from "y-prosemirror";

128

129

const undoPlugin = yUndoPlugin({

130

protectedNodes: new Set(["doc", "paragraph"]),

131

trackedOrigins: ["user-input", "paste"]

132

});

133

```

134

135

### Plugin Keys

136

137

Unique identifiers for each plugin, useful for accessing plugin state or configuration.

138

139

```javascript { .api }

140

/** Plugin key for synchronization plugin */

141

const ySyncPluginKey: PluginKey;

142

143

/** Plugin key for cursor plugin */

144

const yCursorPluginKey: PluginKey;

145

146

/** Plugin key for undo plugin */

147

const yUndoPluginKey: PluginKey;

148

```

149

150

### Undo/Redo Commands

151

152

Direct command functions for implementing undo/redo in your editor interface.

153

154

```javascript { .api }

155

/**

156

* Perform undo operation on editor state

157

* @param state - Current editor state

158

* @returns true if undo was performed

159

*/

160

function undo(state: EditorState): boolean;

161

162

/**

163

* Perform redo operation on editor state

164

* @param state - Current editor state

165

* @returns true if redo was performed

166

*/

167

function redo(state: EditorState): boolean;

168

169

/**

170

* ProseMirror command for undo operation

171

* @param state - Current editor state

172

* @param dispatch - Dispatch function for state changes

173

* @returns true if command was handled

174

*/

175

function undoCommand(state: EditorState, dispatch?: (tr: Transaction) => void): boolean;

176

177

/**

178

* ProseMirror command for redo operation

179

* @param state - Current editor state

180

* @param dispatch - Dispatch function for state changes

181

* @returns true if command was handled

182

*/

183

function redoCommand(state: EditorState, dispatch?: (tr: Transaction) => void): boolean;

184

```

185

186

### ProseMirror Binding Class

187

188

Core binding class that manages the synchronization lifecycle between Yjs and ProseMirror.

189

190

```javascript { .api }

191

/**

192

* Main binding class managing synchronization between Yjs and ProseMirror

193

*/

194

class ProsemirrorBinding {

195

/** The bound Yjs XML fragment */

196

type: Y.XmlFragment;

197

/** The ProseMirror editor view */

198

prosemirrorView: EditorView | null;

199

/** Mapping between Yjs and ProseMirror nodes */

200

mapping: ProsemirrorMapping;

201

/** The Yjs document */

202

doc: Y.Doc;

203

/** Mutex for preventing concurrent operations */

204

mux: Mutex;

205

/** Map tracking overlapping marks */

206

isOMark: Map<MarkType, boolean>;

207

/** Whether this binding has been destroyed */

208

isDestroyed: boolean;

209

/** Current selection as relative positions in the Yjs model */

210

beforeTransactionSelection: any;

211

212

/**

213

* Create a new ProseMirror binding

214

* @param yXmlFragment - Yjs XML fragment to bind

215

* @param mapping - Optional initial mapping

216

*/

217

constructor(yXmlFragment: Y.XmlFragment, mapping?: Map);

218

219

/**

220

* Initialize the binding with a ProseMirror view

221

* @param prosemirrorView - ProseMirror editor view

222

*/

223

initView(prosemirrorView: EditorView): void;

224

225

/**

226

* Clean up the binding and remove event listeners

227

*/

228

destroy(): void;

229

230

/**

231

* Render a specific document snapshot

232

* @param snapshot - Document snapshot to render

233

* @param prevSnapshot - Previous snapshot for comparison

234

*/

235

renderSnapshot(snapshot: Snapshot, prevSnapshot?: Snapshot): void;

236

237

/**

238

* Remove snapshot rendering and return to current state

239

*/

240

unrenderSnapshot(): void;

241

242

/**

243

* Get current transaction with addToHistory set to false

244

* @returns Transaction for internal operations

245

*/

246

get _tr(): Transaction;

247

248

/**

249

* Check if local cursor is visible in view

250

* @returns true if local cursor is in viewport

251

*/

252

_isLocalCursorInView(): boolean;

253

254

/**

255

* Force re-render of the binding mapping

256

*/

257

_forceRerender(): void;

258

}

259

```

260

261

### Default Builders and Filters

262

263

Default implementations for cursor display and awareness filtering that can be used or customized.

264

265

```javascript { .api }

266

/**

267

* Default cursor element builder

268

* @param user - User information from awareness

269

* @param clientId - Client ID of the user

270

* @returns HTML element for cursor display

271

*/

272

function defaultCursorBuilder(user: any, clientId: number): HTMLElement;

273

274

/**

275

* Default selection attributes builder

276

* @param user - User information from awareness

277

* @param clientId - Client ID of the user

278

* @returns Decoration attributes for selection display

279

*/

280

function defaultSelectionBuilder(user: any, clientId: number): DecorationAttrs;

281

282

/**

283

* Default awareness state filter

284

* @param currentClientId - Current user's client ID

285

* @param userClientId - Other user's client ID

286

* @param user - User data from awareness

287

* @returns true if user should be displayed

288

*/

289

function defaultAwarenessStateFilter(

290

currentClientId: number,

291

userClientId: number,

292

user: any

293

): boolean;

294

295

/**

296

* Default filter for undo delete operations

297

* @param item - Yjs item being deleted

298

* @param protectedNodes - Set of protected node types

299

* @returns true if item should be deleted

300

*/

301

function defaultDeleteFilter(item: any, protectedNodes: Set<string>): boolean;

302

303

/** Default set of protected node types for undo operations */

304

const defaultProtectedNodes: Set<string>;

305

```

306

307

### Internal Utilities

308

309

Functions that are exported but primarily intended for internal use or advanced scenarios.

310

311

```javascript { .api }

312

/**

313

* Update Yjs fragment from ProseMirror node

314

* @param y - Yjs document

315

* @param yDomFragment - Yjs fragment to update

316

* @param pNode - ProseMirror node

317

* @param meta - Binding metadata

318

*/

319

function updateYFragment(y: Y.Doc, yDomFragment: Y.XmlFragment, pNode: Node, meta: BindingMetadata): void;

320

321

/**

322

* Create ProseMirror node from Yjs element

323

* @param yElement - Yjs element

324

* @param schema - ProseMirror schema

325

* @param meta - Binding metadata

326

* @returns ProseMirror node

327

*/

328

function createNodeFromYElement(yElement: Y.XmlElement, schema: Schema, meta: BindingMetadata): Node;

329

330

/**

331

* Check if Yjs item is visible in snapshot

332

* @param item - Yjs item to check

333

* @param snapshot - Snapshot to check against

334

* @returns true if item is visible

335

*/

336

function isVisible(item: any, snapshot?: Snapshot): boolean;

337

338

/**

339

* Create empty binding metadata

340

* @returns Empty binding metadata object

341

*/

342

function createEmptyMeta(): BindingMetadata;

343

344

/**

345

* Get current selection as relative positions for collaboration

346

* @param pmbinding - ProseMirror binding instance

347

* @param state - Current editor state

348

* @returns Selection object with relative positions

349

*/

350

function getRelativeSelection(pmbinding: ProsemirrorBinding, state: EditorState): {

351

type: string;

352

anchor: Y.RelativePosition;

353

head: Y.RelativePosition;

354

};

355

356

/**

357

* Convert Yjs attribute name to ProseMirror mark name

358

* @param attrName - Yjs attribute name

359

* @returns ProseMirror mark name

360

*/

361

function yattr2markname(attrName: string): string;

362

363

/**

364

* Convert attributes to ProseMirror marks

365

* @param attrs - Attribute object

366

* @param schema - ProseMirror schema

367

* @returns Array of ProseMirror marks

368

*/

369

function attributesToMarks(attrs: object, schema: Schema): Mark[];

370

371

/**

372

* Create cursor and selection decorations

373

* @param awarenessStates - Map of awareness states

374

* @param cursorBuilder - Function to build cursor elements

375

* @param selectionBuilder - Function to build selection attributes

376

* @param schema - ProseMirror schema

377

* @returns DecorationSet with cursor decorations

378

*/

379

function createDecorations(

380

awarenessStates: Map<number, any>,

381

cursorBuilder: (user: any, clientId: number) => HTMLElement,

382

selectionBuilder: (user: any, clientId: number) => DecorationAttrs,

383

schema: Schema

384

): DecorationSet;

385

```