@tiptap/y-tiptap 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/y-tiptap.cjs +101 -10
- package/dist/y-tiptap.cjs.map +1 -1
- package/dist/y-tiptap.js +101 -10
- package/dist/y-tiptap.js.map +1 -1
- package/package.json +5 -1
package/dist/y-tiptap.js
CHANGED
|
@@ -1382,24 +1382,115 @@ const matchNodeName = (yElement, pNode) =>
|
|
|
1382
1382
|
*/
|
|
1383
1383
|
let viewsToUpdate = null;
|
|
1384
1384
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1385
|
+
class MetaEntry {
|
|
1386
|
+
/**
|
|
1387
|
+
* @param {EditorView} view
|
|
1388
|
+
* @param {any} key
|
|
1389
|
+
* @param {any} value
|
|
1390
|
+
*/
|
|
1391
|
+
constructor (view, key, value) {
|
|
1392
|
+
this.view = view;
|
|
1393
|
+
this.key = key;
|
|
1394
|
+
this.value = value;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
apply () {
|
|
1398
|
+
const syncState = ySyncPluginKey.getState(this.view.state);
|
|
1391
1399
|
if (syncState && syncState.binding && !syncState.binding.isDestroyed) {
|
|
1392
|
-
|
|
1393
|
-
|
|
1400
|
+
const tr = this.view.state.tr;
|
|
1401
|
+
tr.setMeta(this.key, this.value);
|
|
1402
|
+
this.view.dispatch(tr);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
class MetaEntriesQueue {
|
|
1408
|
+
/**
|
|
1409
|
+
* @param {Array<MetaEntry>} [entries=[]]
|
|
1410
|
+
*/
|
|
1411
|
+
constructor (entries = []) {
|
|
1412
|
+
this.entries = entries;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/**
|
|
1416
|
+
* @return {MetaEntry|undefined}
|
|
1417
|
+
*/
|
|
1418
|
+
getFirst () {
|
|
1419
|
+
return this.entries[0]
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
/**
|
|
1423
|
+
* @return {MetaEntry|undefined}
|
|
1424
|
+
*/
|
|
1425
|
+
dequeueFirst () {
|
|
1426
|
+
return this.entries.shift()
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
/**
|
|
1430
|
+
* @return {boolean}
|
|
1431
|
+
*/
|
|
1432
|
+
isEmpty () {
|
|
1433
|
+
return this.entries.length === 0
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
static fromViewsToUpdate () {
|
|
1437
|
+
const ups = /** @type {Map<EditorView, Map<any, any>>} */ (viewsToUpdate);
|
|
1438
|
+
viewsToUpdate = null;
|
|
1439
|
+
const entries = [];
|
|
1440
|
+
ups.forEach((metas, view) => {
|
|
1441
|
+
metas.forEach((value, key) => {
|
|
1442
|
+
entries.push(new MetaEntry(view, key, value));
|
|
1394
1443
|
});
|
|
1395
|
-
|
|
1444
|
+
});
|
|
1445
|
+
return new MetaEntriesQueue(entries)
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* Dispatch queued plugin metadata in order, retrying only the remaining
|
|
1451
|
+
* entries if a transaction becomes stale while the async queue is flushing.
|
|
1452
|
+
*
|
|
1453
|
+
* Cursor awareness updates are decoration-only refreshes. If a real document
|
|
1454
|
+
* transaction lands before one of these queued meta transactions is applied,
|
|
1455
|
+
* ProseMirror can reject it with a RangeError. In that case we reschedule the
|
|
1456
|
+
* remaining entries on the next tick. If the first remaining entry fails again
|
|
1457
|
+
* on retry, we drop that entry and continue with the rest of the queue instead
|
|
1458
|
+
* of retrying forever or crashing the editor.
|
|
1459
|
+
*
|
|
1460
|
+
* @param {MetaEntriesQueue} [metaEntries=MetaEntriesQueue.fromViewsToUpdate()]
|
|
1461
|
+
* @param {boolean} [isRetry=false]
|
|
1462
|
+
*/
|
|
1463
|
+
const updateMetas = (metaEntries = MetaEntriesQueue.fromViewsToUpdate(), isRetry = false) => {
|
|
1464
|
+
let isFirst = true;
|
|
1465
|
+
while (!metaEntries.isEmpty()) {
|
|
1466
|
+
const metaEntry = metaEntries.getFirst();
|
|
1467
|
+
try {
|
|
1468
|
+
metaEntry.apply();
|
|
1469
|
+
} catch (err) {
|
|
1470
|
+
// ProseMirror throws a RangeError when this transaction was created from
|
|
1471
|
+
// an older state and another transaction changed the document before this
|
|
1472
|
+
// meta-only dispatch was applied ("Applying a mismatched transaction").
|
|
1473
|
+
if (err instanceof RangeError) {
|
|
1474
|
+
if (isRetry && isFirst) {
|
|
1475
|
+
// Drop the repeatedly stale entry so the queue can continue flushing.
|
|
1476
|
+
metaEntries.dequeueFirst();
|
|
1477
|
+
}
|
|
1478
|
+
if (!metaEntries.isEmpty()) {
|
|
1479
|
+
eventloop.timeout(0, () => updateMetas(metaEntries, true));
|
|
1480
|
+
}
|
|
1481
|
+
return
|
|
1482
|
+
}
|
|
1483
|
+
throw err
|
|
1396
1484
|
}
|
|
1397
|
-
|
|
1485
|
+
isFirst = false;
|
|
1486
|
+
metaEntries.dequeueFirst();
|
|
1487
|
+
}
|
|
1398
1488
|
};
|
|
1399
1489
|
|
|
1400
1490
|
const setMeta = (view, key, value) => {
|
|
1401
1491
|
if (!viewsToUpdate) {
|
|
1402
1492
|
viewsToUpdate = new Map();
|
|
1493
|
+
// Awareness listeners can fire in bursts, so batch them into one tick.
|
|
1403
1494
|
eventloop.timeout(0, updateMetas);
|
|
1404
1495
|
}
|
|
1405
1496
|
map.setIfUndefined(viewsToUpdate, view, map.create).set(key, value);
|