@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.cjs
CHANGED
|
@@ -1416,24 +1416,115 @@ const matchNodeName = (yElement, pNode) =>
|
|
|
1416
1416
|
*/
|
|
1417
1417
|
let viewsToUpdate = null;
|
|
1418
1418
|
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1419
|
+
class MetaEntry {
|
|
1420
|
+
/**
|
|
1421
|
+
* @param {EditorView} view
|
|
1422
|
+
* @param {any} key
|
|
1423
|
+
* @param {any} value
|
|
1424
|
+
*/
|
|
1425
|
+
constructor (view, key, value) {
|
|
1426
|
+
this.view = view;
|
|
1427
|
+
this.key = key;
|
|
1428
|
+
this.value = value;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
apply () {
|
|
1432
|
+
const syncState = ySyncPluginKey.getState(this.view.state);
|
|
1425
1433
|
if (syncState && syncState.binding && !syncState.binding.isDestroyed) {
|
|
1426
|
-
|
|
1427
|
-
|
|
1434
|
+
const tr = this.view.state.tr;
|
|
1435
|
+
tr.setMeta(this.key, this.value);
|
|
1436
|
+
this.view.dispatch(tr);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
class MetaEntriesQueue {
|
|
1442
|
+
/**
|
|
1443
|
+
* @param {Array<MetaEntry>} [entries=[]]
|
|
1444
|
+
*/
|
|
1445
|
+
constructor (entries = []) {
|
|
1446
|
+
this.entries = entries;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* @return {MetaEntry|undefined}
|
|
1451
|
+
*/
|
|
1452
|
+
getFirst () {
|
|
1453
|
+
return this.entries[0]
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
* @return {MetaEntry|undefined}
|
|
1458
|
+
*/
|
|
1459
|
+
dequeueFirst () {
|
|
1460
|
+
return this.entries.shift()
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* @return {boolean}
|
|
1465
|
+
*/
|
|
1466
|
+
isEmpty () {
|
|
1467
|
+
return this.entries.length === 0
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
static fromViewsToUpdate () {
|
|
1471
|
+
const ups = /** @type {Map<EditorView, Map<any, any>>} */ (viewsToUpdate);
|
|
1472
|
+
viewsToUpdate = null;
|
|
1473
|
+
const entries = [];
|
|
1474
|
+
ups.forEach((metas, view) => {
|
|
1475
|
+
metas.forEach((value, key) => {
|
|
1476
|
+
entries.push(new MetaEntry(view, key, value));
|
|
1428
1477
|
});
|
|
1429
|
-
|
|
1478
|
+
});
|
|
1479
|
+
return new MetaEntriesQueue(entries)
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
/**
|
|
1484
|
+
* Dispatch queued plugin metadata in order, retrying only the remaining
|
|
1485
|
+
* entries if a transaction becomes stale while the async queue is flushing.
|
|
1486
|
+
*
|
|
1487
|
+
* Cursor awareness updates are decoration-only refreshes. If a real document
|
|
1488
|
+
* transaction lands before one of these queued meta transactions is applied,
|
|
1489
|
+
* ProseMirror can reject it with a RangeError. In that case we reschedule the
|
|
1490
|
+
* remaining entries on the next tick. If the first remaining entry fails again
|
|
1491
|
+
* on retry, we drop that entry and continue with the rest of the queue instead
|
|
1492
|
+
* of retrying forever or crashing the editor.
|
|
1493
|
+
*
|
|
1494
|
+
* @param {MetaEntriesQueue} [metaEntries=MetaEntriesQueue.fromViewsToUpdate()]
|
|
1495
|
+
* @param {boolean} [isRetry=false]
|
|
1496
|
+
*/
|
|
1497
|
+
const updateMetas = (metaEntries = MetaEntriesQueue.fromViewsToUpdate(), isRetry = false) => {
|
|
1498
|
+
let isFirst = true;
|
|
1499
|
+
while (!metaEntries.isEmpty()) {
|
|
1500
|
+
const metaEntry = metaEntries.getFirst();
|
|
1501
|
+
try {
|
|
1502
|
+
metaEntry.apply();
|
|
1503
|
+
} catch (err) {
|
|
1504
|
+
// ProseMirror throws a RangeError when this transaction was created from
|
|
1505
|
+
// an older state and another transaction changed the document before this
|
|
1506
|
+
// meta-only dispatch was applied ("Applying a mismatched transaction").
|
|
1507
|
+
if (err instanceof RangeError) {
|
|
1508
|
+
if (isRetry && isFirst) {
|
|
1509
|
+
// Drop the repeatedly stale entry so the queue can continue flushing.
|
|
1510
|
+
metaEntries.dequeueFirst();
|
|
1511
|
+
}
|
|
1512
|
+
if (!metaEntries.isEmpty()) {
|
|
1513
|
+
eventloop__namespace.timeout(0, () => updateMetas(metaEntries, true));
|
|
1514
|
+
}
|
|
1515
|
+
return
|
|
1516
|
+
}
|
|
1517
|
+
throw err
|
|
1430
1518
|
}
|
|
1431
|
-
|
|
1519
|
+
isFirst = false;
|
|
1520
|
+
metaEntries.dequeueFirst();
|
|
1521
|
+
}
|
|
1432
1522
|
};
|
|
1433
1523
|
|
|
1434
1524
|
const setMeta = (view, key, value) => {
|
|
1435
1525
|
if (!viewsToUpdate) {
|
|
1436
1526
|
viewsToUpdate = new Map();
|
|
1527
|
+
// Awareness listeners can fire in bursts, so batch them into one tick.
|
|
1437
1528
|
eventloop__namespace.timeout(0, updateMetas);
|
|
1438
1529
|
}
|
|
1439
1530
|
map__namespace.setIfUndefined(viewsToUpdate, view, map__namespace.create).set(key, value);
|