@textbus/collaborate 5.4.1 → 5.4.2

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.
@@ -1,5 +1,5 @@
1
1
  import { Observable } from '@tanbo/stream';
2
- import { Component, Registry, Scheduler, Selection, Slot, AbstractSelection } from '@textbus/core';
2
+ import { Component, Formats, FormatValue, Registry, Scheduler, Selection, Slot, AbstractSelection } from '@textbus/core';
3
3
  import { AbstractType, Doc as YDoc, Map as YMap, RelativePosition, Text as YText } from 'yjs';
4
4
  import { SubModelLoader } from './sub-model-loader';
5
5
  export interface RelativePositionRecord {
@@ -96,4 +96,11 @@ export declare class Collaborate {
96
96
  private runLocalUpdate;
97
97
  private runRemoteUpdate;
98
98
  }
99
+ export declare function localFormatsToYjsAttributes(registry: Registry, slot: Slot, start: number, end: number, localFormats: Record<string, FormatValue>): Record<string, FormatValue | FormatValue[] | null>;
100
+ export declare function localFormatsRecordToRemote(registry: Registry, formats: Record<string, FormatValue> | undefined): Record<string, FormatValue | FormatValue[] | null> | undefined;
101
+ export declare function formatsArrayToRemoteRecord(registry: Registry, formats: Formats): Record<string, FormatValue | FormatValue[]> | undefined;
102
+ /** 远程插入内容的格式 → 本地 Formats(新内容无旧状态,可堆叠仅展开远程数组) */
103
+ export declare function remoteInsertFormatsToLocal(registry: Registry, attrs?: Record<string, FormatValue | FormatValue[] | null> | null): Formats;
104
+ /** 远程 retain 格式 → 本地 Formats(可堆叠与区间内本地快照做差量对齐) */
105
+ export declare function remoteRetainFormatsToLocal(registry: Registry, slot: Slot, start: number, end: number, attrs?: Record<string, FormatValue | FormatValue[] | null> | null): Formats;
99
106
  export {};
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Injectable, Inject, Optional } from '@viewfly/core';
2
- import { makeError, Slot, ChangeOrigin, toRaw, observe, AsyncSlot, AsyncComponent, Component, getObserver, attachModel, valueToJSON, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
2
+ import { makeError, valueToJSON, Format, PendingErasure, Slot, ChangeOrigin, toRaw, observe, AsyncSlot, AsyncComponent, Component, getObserver, attachModel, StackableFormatter, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
3
3
  import { Subject, map, filter, Subscription } from '@tanbo/stream';
4
4
  import { Doc, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Array as Array$1, Text, XmlElement, UndoManager } from 'yjs';
5
5
  import { HocuspocusProvider } from '@hocuspocus/provider';
@@ -543,7 +543,9 @@ var Collaborate = /*#__PURE__*/ function() {
543
543
  ev.delta.forEach(function(action) {
544
544
  if (Reflect.has(action, 'retain')) {
545
545
  if (action.attributes) {
546
- var formats = remoteFormatsToLocal(_this.registry, action.attributes);
546
+ var start = localSlot.index;
547
+ var end = start + action.retain;
548
+ var formats = remoteRetainFormatsToLocal(_this.registry, localSlot, start, end, action.attributes);
547
549
  if (formats.length) {
548
550
  localSlot.retain(action.retain, formats);
549
551
  }
@@ -554,7 +556,7 @@ var Collaborate = /*#__PURE__*/ function() {
554
556
  var length = 1;
555
557
  if (typeof action.insert === 'string') {
556
558
  length = action.insert.length;
557
- localSlot.insert(action.insert, remoteFormatsToLocal(_this.registry, action.attributes));
559
+ localSlot.insert(action.insert, remoteInsertFormatsToLocal(_this.registry, action.attributes));
558
560
  } else {
559
561
  var sharedComponent = action.insert;
560
562
  var component = _this.createLocalComponentBySharedComponent(sharedComponent);
@@ -590,22 +592,14 @@ var Collaborate = /*#__PURE__*/ function() {
590
592
  var length = 0;
591
593
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
592
594
  try {
593
- var _loop = function() {
595
+ for(var _iterator = actions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
594
596
  var action = _step.value;
595
597
  if (action.type === 'retain') {
596
598
  var formats = action.formats;
597
599
  if (formats) {
598
- var keys = Object.keys(formats);
599
- var length1 = keys.length;
600
- keys.forEach(function(key) {
601
- var formatter = _this.registry.getFormatter(key);
602
- if (!formatter) {
603
- length1--;
604
- Reflect.deleteProperty(formats, key);
605
- }
606
- });
607
- if (length1) {
608
- sharedSlot.format(offset, action.offset, formats);
600
+ var attrs = localFormatsToYjsAttributes(_this.registry, localSlot, offset, offset + action.offset, formats);
601
+ if (Object.keys(attrs).length) {
602
+ sharedSlot.format(offset, action.offset, attrs);
609
603
  }
610
604
  } else {
611
605
  offset = action.offset;
@@ -615,11 +609,11 @@ var Collaborate = /*#__PURE__*/ function() {
615
609
  var isEmpty = delta.length === 1 && delta[0].insert === Slot.emptyPlaceholder;
616
610
  if (typeof action.content === 'string') {
617
611
  length = action.content.length;
618
- sharedSlot.insert(offset, action.content, action.formats || {});
612
+ sharedSlot.insert(offset, action.content, localFormatsRecordToRemote(_this.registry, action.formats) || {});
619
613
  } else {
620
614
  length = 1;
621
615
  var sharedComponent = _this.createSharedComponentByLocalComponent(action.ref);
622
- sharedSlot.insertEmbed(offset, sharedComponent, action.formats || {});
616
+ sharedSlot.insertEmbed(offset, sharedComponent, localFormatsRecordToRemote(_this.registry, action.formats) || {});
623
617
  }
624
618
  if (isEmpty && offset === 0) {
625
619
  sharedSlot.delete(sharedSlot.length - 1, 1);
@@ -639,8 +633,7 @@ var Collaborate = /*#__PURE__*/ function() {
639
633
  } else if (action.type === 'attrDelete') {
640
634
  sharedSlot.removeAttribute(action.name);
641
635
  }
642
- };
643
- for(var _iterator = actions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
636
+ }
644
637
  } catch (err) {
645
638
  _didIteratorError = true;
646
639
  _iteratorError = err;
@@ -795,14 +788,7 @@ var Collaborate = /*#__PURE__*/ function() {
795
788
  var _this = this;
796
789
  var offset = 0;
797
790
  localSlot.toDelta().forEach(function(i) {
798
- var formats = {};
799
- if (i.formats) {
800
- i.formats.forEach(function(item) {
801
- formats[item[0].name] = item[1];
802
- });
803
- } else {
804
- formats = null;
805
- }
791
+ var formats = i.formats ? formatsArrayToRemoteRecord(_this.registry, i.formats) : undefined;
806
792
  if (typeof i.insert === 'string') {
807
793
  sharedContent.insert(offset, i.insert, formats);
808
794
  } else {
@@ -893,12 +879,12 @@ var Collaborate = /*#__PURE__*/ function() {
893
879
  var action = _step.value;
894
880
  if (action.insert) {
895
881
  if (typeof action.insert === 'string') {
896
- var formats = remoteFormatsToLocal(this.registry, action.attributes);
882
+ var formats = remoteInsertFormatsToLocal(this.registry, action.attributes);
897
883
  localSlot.insert(action.insert, formats);
898
884
  } else {
899
885
  var sharedComponent = action.insert;
900
886
  var component = this.createLocalComponentBySharedComponent(sharedComponent);
901
- localSlot.insert(component, remoteFormatsToLocal(this.registry, action.attributes));
887
+ localSlot.insert(component, remoteInsertFormatsToLocal(this.registry, action.attributes));
902
888
  }
903
889
  } else {
904
890
  throw collaborateErrorFn('unexpected delta action.');
@@ -1377,19 +1363,180 @@ Collaborate = _ts_decorate$2([
1377
1363
  typeof SubModelLoader === "undefined" ? Object : SubModelLoader
1378
1364
  ])
1379
1365
  ], Collaborate);
1380
- function remoteFormatsToLocal(registry, attrs) {
1366
+ function collectStackableValuesInRange(slot, formatter, start, end) {
1367
+ var values = [];
1368
+ slot.getFormatRangesByFormatter(formatter, start, end).forEach(function(range) {
1369
+ var v = range.value;
1370
+ if (!values.some(function(existing) {
1371
+ return Format.equal(existing, v);
1372
+ })) {
1373
+ values.push(v);
1374
+ }
1375
+ });
1376
+ return values;
1377
+ }
1378
+ function serializeFormatForYjs(value) {
1379
+ return valueToJSON(value);
1380
+ }
1381
+ function localFormatsToYjsAttributes(registry, slot, start, end, localFormats) {
1382
+ var attrs = {};
1383
+ Object.keys(localFormats).forEach(function(key) {
1384
+ var formatter = registry.getFormatter(key);
1385
+ if (!formatter) {
1386
+ return;
1387
+ }
1388
+ if (_instanceof$1(formatter, StackableFormatter)) {
1389
+ var values = collectStackableValuesInRange(slot, formatter, start, end);
1390
+ attrs[key] = values.length ? values.map(serializeFormatForYjs) : null;
1391
+ } else {
1392
+ attrs[key] = localFormats[key];
1393
+ }
1394
+ });
1395
+ return attrs;
1396
+ }
1397
+ function localFormatsRecordToRemote(registry, formats) {
1398
+ if (!formats) {
1399
+ return undefined;
1400
+ }
1401
+ var record = {};
1402
+ Object.keys(formats).forEach(function(key) {
1403
+ var formatter = registry.getFormatter(key);
1404
+ if (!formatter) {
1405
+ return;
1406
+ }
1407
+ var incoming = formats[key];
1408
+ if (_instanceof$1(formatter, StackableFormatter)) {
1409
+ if (incoming === null || incoming === undefined) {
1410
+ record[key] = null;
1411
+ } else {
1412
+ record[key] = [
1413
+ serializeFormatForYjs(incoming)
1414
+ ];
1415
+ }
1416
+ } else {
1417
+ record[key] = incoming;
1418
+ }
1419
+ });
1420
+ return Object.keys(record).length ? record : undefined;
1421
+ }
1422
+ function formatsArrayToRemoteRecord(registry, formats) {
1423
+ var record = {};
1424
+ formats.forEach(function(param) {
1425
+ var _param = _sliced_to_array(param, 2), formatter = _param[0], value = _param[1];
1426
+ if (!registry.getFormatter(formatter.name)) {
1427
+ return;
1428
+ }
1429
+ if (_instanceof$1(formatter, StackableFormatter)) {
1430
+ var serialized = serializeFormatForYjs(value);
1431
+ var current = record[formatter.name];
1432
+ if (Array.isArray(current)) {
1433
+ current.push(serialized);
1434
+ } else {
1435
+ record[formatter.name] = [
1436
+ serialized
1437
+ ];
1438
+ }
1439
+ } else {
1440
+ record[formatter.name] = value;
1441
+ }
1442
+ });
1443
+ return Object.keys(record).length ? record : undefined;
1444
+ }
1445
+ function stackableRemoteRetainToLocal(slot, formatter, start, end, raw) {
1381
1446
  var formats = [];
1382
- if (attrs) {
1383
- Object.keys(attrs).forEach(function(key) {
1384
- var formatter = registry.getFormatter(key);
1385
- if (formatter) {
1386
- formats.push([
1387
- formatter,
1388
- attrs[key]
1389
- ]);
1390
- }
1391
- });
1447
+ var localValues = collectStackableValuesInRange(slot, formatter, start, end);
1448
+ if (raw === null || raw === undefined || Array.isArray(raw) && raw.length === 0) {
1449
+ if (localValues.length > 0) {
1450
+ formats.push([
1451
+ formatter,
1452
+ new PendingErasure(true)
1453
+ ]);
1454
+ }
1455
+ return formats;
1456
+ }
1457
+ var remoteValues = Array.isArray(raw) ? raw : [
1458
+ raw
1459
+ ];
1460
+ localValues.forEach(function(localValue) {
1461
+ if (!remoteValues.some(function(remoteValue) {
1462
+ return Format.equal(localValue, remoteValue);
1463
+ })) {
1464
+ formats.push([
1465
+ formatter,
1466
+ new PendingErasure(false, localValue)
1467
+ ]);
1468
+ }
1469
+ });
1470
+ remoteValues.forEach(function(remoteValue) {
1471
+ if (!localValues.some(function(localValue) {
1472
+ return Format.equal(localValue, remoteValue);
1473
+ })) {
1474
+ formats.push([
1475
+ formatter,
1476
+ remoteValue
1477
+ ]);
1478
+ }
1479
+ });
1480
+ return formats;
1481
+ }
1482
+ function stackableRemoteInsertToLocal(formatter, raw) {
1483
+ if (raw === null || raw === undefined || Array.isArray(raw) && raw.length === 0) {
1484
+ return [];
1485
+ }
1486
+ var remoteValues = Array.isArray(raw) ? raw : [
1487
+ raw
1488
+ ];
1489
+ return remoteValues.map(function(value) {
1490
+ return [
1491
+ formatter,
1492
+ value
1493
+ ];
1494
+ });
1495
+ }
1496
+ /** 远程插入内容的格式 → 本地 Formats(新内容无旧状态,可堆叠仅展开远程数组) */ function remoteInsertFormatsToLocal(registry, attrs) {
1497
+ var formats = [];
1498
+ if (!attrs) {
1499
+ return formats;
1500
+ }
1501
+ Object.keys(attrs).forEach(function(key) {
1502
+ var formatter = registry.getFormatter(key);
1503
+ if (!formatter) {
1504
+ return;
1505
+ }
1506
+ var raw = attrs[key];
1507
+ if (_instanceof$1(formatter, StackableFormatter)) {
1508
+ var _formats;
1509
+ (_formats = formats).push.apply(_formats, _to_consumable_array(stackableRemoteInsertToLocal(formatter, raw)));
1510
+ return;
1511
+ }
1512
+ formats.push([
1513
+ formatter,
1514
+ raw
1515
+ ]);
1516
+ });
1517
+ return formats;
1518
+ }
1519
+ /** 远程 retain 格式 → 本地 Formats(可堆叠与区间内本地快照做差量对齐) */ function remoteRetainFormatsToLocal(registry, slot, start, end, attrs) {
1520
+ var formats = [];
1521
+ if (!attrs) {
1522
+ return formats;
1392
1523
  }
1524
+ Object.keys(attrs).forEach(function(key) {
1525
+ var formatter = registry.getFormatter(key);
1526
+ if (!formatter) {
1527
+ return;
1528
+ }
1529
+ var raw = attrs[key];
1530
+ if (_instanceof$1(formatter, StackableFormatter)) {
1531
+ var _formats;
1532
+ (_formats = formats).push.apply(_formats, _to_consumable_array(stackableRemoteRetainToLocal(slot, formatter, start, end, raw)));
1533
+ return;
1534
+ }
1535
+ formats.push([
1536
+ formatter,
1537
+ raw
1538
+ ]);
1539
+ });
1393
1540
  return formats;
1394
1541
  }
1395
1542
 
@@ -2721,5 +2868,5 @@ var MultipleDocumentCollaborateModule = /*#__PURE__*/ function() {
2721
2868
  return MultipleDocumentCollaborateModule;
2722
2869
  }();
2723
2870
 
2724
- export { CollabHistory, Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, LocalConnector, MessageBus, MultipleDocCollabHistory, MultipleDocumentCollaborateModule, NonSubModelLoader, SubModelLoader, SyncConnector, YWebsocketConnector };
2871
+ export { CollabHistory, Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, LocalConnector, MessageBus, MultipleDocCollabHistory, MultipleDocumentCollaborateModule, NonSubModelLoader, SubModelLoader, SyncConnector, YWebsocketConnector, formatsArrayToRemoteRecord, localFormatsRecordToRemote, localFormatsToYjsAttributes, remoteInsertFormatsToLocal, remoteRetainFormatsToLocal };
2725
2872
  //# sourceMappingURL=index.esm.js.map