@textbus/collaborate
Version:
Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.
1,050 lines (1,046 loc) • 125 kB
JavaScript
'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core$1 = require('@viewfly/core');
const core = require('@textbus/core');
const stream = require('@tanbo/stream');
const yjs = require('yjs');
const provider = require('@hocuspocus/provider');
const yWebsocket = require('y-websocket');
function _assert_this_initialized$3(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _call_super$3(_this, derived, args) {
derived = _get_prototype_of$3(derived);
return _possible_constructor_return$3(_this, _is_native_reflect_construct$3() ? Reflect.construct(derived, args || [], _get_prototype_of$3(_this).constructor) : derived.apply(_this, args));
}
function _class_call_check$a(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties$9(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _create_class$9(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties$9(Constructor.prototype, protoProps);
return Constructor;
}
function _get_prototype_of$3(o) {
_get_prototype_of$3 = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _get_prototype_of$3(o);
}
function _inherits$3(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _set_prototype_of$3(subClass, superClass);
}
function _possible_constructor_return$3(self, call) {
if (call && (_type_of$4(call) === "object" || typeof call === "function")) {
return call;
}
return _assert_this_initialized$3(self);
}
function _set_prototype_of$3(o, p) {
_set_prototype_of$3 = Object.setPrototypeOf || function setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _set_prototype_of$3(o, p);
}
function _type_of$4(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _is_native_reflect_construct$3() {
try {
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
} catch (_) {}
return (_is_native_reflect_construct$3 = function() {
return !!result;
})();
}
function _ts_decorate$3(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
var subModelLoaderErrorFn = core.makeError('subModelLoaderError');
/**
* 子文档加载器
*/ var SubModelLoader = function SubModelLoader() {
_class_call_check$a(this, SubModelLoader);
};
exports.NonSubModelLoader = /*#__PURE__*/ function(SubModelLoader) {
_inherits$3(NonSubModelLoader, SubModelLoader);
function NonSubModelLoader() {
_class_call_check$a(this, NonSubModelLoader);
return _call_super$3(this, NonSubModelLoader, arguments);
}
_create_class$9(NonSubModelLoader, [
{
key: "createSubModelBySlot",
value: function createSubModelBySlot() {
throw subModelLoaderErrorFn('single document does not support async slot.');
}
},
{
key: "createSubModelByComponent",
value: function createSubModelByComponent() {
throw subModelLoaderErrorFn('single document does not support async component.');
}
},
{
key: "loadSubModelByComponent",
value: function loadSubModelByComponent() {
throw subModelLoaderErrorFn('single document does not support async component.');
}
},
{
key: "loadSubModelBySlot",
value: function loadSubModelBySlot() {
throw subModelLoaderErrorFn('single document does not support async slot.');
}
},
{
key: "getLoadedModelBySlot",
value: function getLoadedModelBySlot() {
throw subModelLoaderErrorFn('single document does not support async slot.');
}
},
{
key: "getLoadedModelByComponent",
value: function getLoadedModelByComponent() {
throw subModelLoaderErrorFn('single document does not support async component.');
}
}
]);
return NonSubModelLoader;
}(SubModelLoader);
exports.NonSubModelLoader = _ts_decorate$3([
core$1.Injectable()
], exports.NonSubModelLoader);
function _array_like_to_array(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _array_with_holes(arr) {
if (Array.isArray(arr)) return arr;
}
function _array_without_holes(arr) {
if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function _class_call_check$9(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties$8(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _create_class$8(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties$8(Constructor.prototype, protoProps);
return Constructor;
}
function _define_property$9(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _instanceof$1(left, right) {
"@swc/helpers - instanceof";
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
return !!right[Symbol.hasInstance](left);
} else {
return left instanceof right;
}
}
function _iterable_to_array(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterable_to_array_limit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally{
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally{
if (_d) throw _e;
}
}
return _arr;
}
function _non_iterable_rest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _non_iterable_spread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _to_consumable_array(arr) {
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _type_of$3(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _unsupported_iterable_to_array(o, minLen) {
if (!o) return;
if (typeof o === "string") return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
function _ts_decorate$2(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata$2(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
/** 与本地稀疏数组「空洞」对应的 YXmlElement,仅放入 YArray,不作通用 XML 节点使用 */ var ARRAY_HOLE_ELEMENT_NODE = 'tb-array-hole';
var collaborateErrorFn = core.makeError('Collaborate');
var SlotMap = /*#__PURE__*/ function() {
function SlotMap() {
_class_call_check$9(this, SlotMap);
_define_property$9(this, "slotAndYTextMap", new WeakMap());
_define_property$9(this, "yTextAndSlotMap", new WeakMap());
}
_create_class$8(SlotMap, [
{
key: "set",
value: function set(key, value) {
if (_instanceof$1(key, core.Slot)) {
this.slotAndYTextMap.set(key, value);
this.yTextAndSlotMap.set(value, key);
} else {
this.slotAndYTextMap.set(value, key);
this.yTextAndSlotMap.set(key, value);
}
}
},
{
key: "get",
value: function get(key) {
if (_instanceof$1(key, core.Slot)) {
return this.slotAndYTextMap.get(key) || null;
}
return this.yTextAndSlotMap.get(key) || null;
}
},
{
key: "delete",
value: function _delete(key) {
if (_instanceof$1(key, core.Slot)) {
var v = this.slotAndYTextMap.get(key);
this.slotAndYTextMap.delete(key);
if (v) {
this.yTextAndSlotMap.delete(v);
}
} else {
var v1 = this.yTextAndSlotMap.get(key);
this.yTextAndSlotMap.delete(key);
if (v1) {
this.slotAndYTextMap.delete(v1);
}
}
}
}
]);
return SlotMap;
}();
exports.Collaborate = /*#__PURE__*/ function() {
function Collaborate(scheduler, registry, selection, subModelLoader) {
_class_call_check$9(this, Collaborate);
_define_property$9(this, "scheduler", void 0);
_define_property$9(this, "registry", void 0);
_define_property$9(this, "selection", void 0);
_define_property$9(this, "subModelLoader", void 0);
_define_property$9(this, "yDoc", void 0);
_define_property$9(this, "slotMap", void 0);
_define_property$9(this, "onAddSubModel", void 0);
_define_property$9(this, "subscriptions", void 0);
_define_property$9(this, "updateFromRemote", void 0);
_define_property$9(this, "addSubModelEvent", void 0);
_define_property$9(this, "updateRemoteActions", void 0);
_define_property$9(this, "noRecord", void 0);
this.scheduler = scheduler;
this.registry = registry;
this.selection = selection;
this.subModelLoader = subModelLoader;
this.yDoc = new yjs.Doc();
this.slotMap = new SlotMap();
this.subscriptions = [];
this.updateFromRemote = false;
this.addSubModelEvent = new stream.Subject();
this.updateRemoteActions = new WeakMap();
this.noRecord = {};
this.onAddSubModel = this.addSubModelEvent.asObservable();
}
_create_class$8(Collaborate, [
{
key: "syncRootComponent",
value: function syncRootComponent(yDoc, sharedComponent, localComponent) {
this.initSyncEvent(yDoc);
this.syncComponent(yDoc, sharedComponent, localComponent);
}
},
{
key: "syncRootSlot",
value: function syncRootSlot(yDoc, sharedSlot, localSlot) {
var _this = this;
if (sharedSlot.length) {
localSlot.retain(0);
localSlot.delete(localSlot.length);
localSlot.cleanAttributes();
localSlot.cleanFormats();
this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
} else {
yDoc.transact(function() {
_this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
});
}
this.initSyncEvent(yDoc);
this.syncSlot(sharedSlot, localSlot);
}
},
{
key: "getAbstractSelection",
value: function getAbstractSelection(position) {
var anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
var focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
if (anchorPosition && focusPosition) {
var focusSlot = this.slotMap.get(focusPosition.type);
var anchorSlot = this.slotMap.get(anchorPosition.type);
if (focusSlot && anchorSlot) {
return {
anchorSlot: anchorSlot,
anchorOffset: anchorPosition.index,
focusSlot: focusSlot,
focusOffset: focusPosition.index
};
}
}
return null;
}
},
{
key: "getRelativeCursorLocation",
value: function getRelativeCursorLocation() {
var _this_selection = this.selection, anchorSlot = _this_selection.anchorSlot, anchorOffset = _this_selection.anchorOffset, focusSlot = _this_selection.focusSlot, focusOffset = _this_selection.focusOffset;
if (anchorSlot) {
var anchorYText = this.slotMap.get(anchorSlot);
if (anchorYText) {
var anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
if (focusSlot) {
var focusYText = this.slotMap.get(focusSlot);
if (focusYText) {
var focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
return {
focus: {
doc: focusYText.doc,
position: focusPosition
},
anchor: {
doc: anchorYText.doc,
position: anchorPosition
}
};
}
}
}
}
return null;
}
},
{
key: "restoreCursorPosition",
value: function restoreCursorPosition(position) {
if (!position) {
this.selection.unSelect();
return;
}
var selection = this.getAbstractSelection(position);
if (selection) {
this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
}
}
},
{
key: "initSyncEvent",
value: function initSyncEvent(yDoc) {
var _this = this;
this.subscriptions.push(this.scheduler.onDocChanged.pipe(stream.map(function(item) {
return item.filter(function(i) {
return i.from !== core.ChangeOrigin.Remote;
});
}), stream.filter(function(item) {
return item.length;
})).subscribe(function() {
var updates = [];
var update = null;
var updateRemoteActions = _this.updateRemoteActions.get(yDoc) || [];
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = updateRemoteActions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var item = _step.value;
if (!update) {
update = {
record: item.record,
actions: []
};
updates.push(update);
}
if (update.record === item.record) {
update.actions.push(item.action);
} else {
update = {
record: item.record,
actions: [
item.action
]
};
updates.push(update);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
_this.updateRemoteActions.delete(yDoc);
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
try {
var _loop = function() {
var item = _step1.value;
yDoc.transact(function() {
item.actions.forEach(function(fn) {
fn();
});
}, item.record ? yDoc : _this.noRecord);
};
for(var _iterator1 = updates[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true)_loop();
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
} finally{
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally{
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
}));
}
},
{
key: "syncComponent",
value: function syncComponent(yDoc, sharedComponent, localComponent) {
var state = sharedComponent.get('state');
if (!state) {
state = new yjs.Map();
this.syncLocalMapToSharedMap(localComponent.state, state);
yDoc.transact(function() {
sharedComponent.set('state', state);
});
} else {
Object.keys(localComponent.state).forEach(function(key) {
Reflect.deleteProperty(localComponent.state, key);
});
this.syncSharedMapToLocalMap(state, localComponent.state);
}
}
},
{
key: "syncSlot",
value: function syncSlot(sharedSlot, localSlot) {
var _this = this;
var syncRemote = function syncRemote(ev, tr) {
_this.runRemoteUpdate(tr, function() {
localSlot.retain(0);
ev.keysChanged.forEach(function(key) {
var change = ev.keys.get(key);
if (!change) {
return;
}
var updateType = change.action;
if (updateType === 'update' || updateType === 'add') {
var attribute = _this.registry.getAttribute(key);
if (attribute) {
localSlot.setAttribute(attribute, sharedSlot.getAttribute(key));
}
} else if (updateType === 'delete') {
var attribute1 = _this.registry.getAttribute(key);
if (attribute1) {
localSlot.removeAttribute(attribute1);
}
}
});
ev.delta.forEach(function(action) {
if (Reflect.has(action, 'retain')) {
if (action.attributes) {
var start = localSlot.index;
var end = start + action.retain;
var formats = remoteRetainFormatsToLocal(_this.registry, localSlot, start, end, action.attributes);
if (formats.length) {
localSlot.retain(action.retain, formats);
}
}
localSlot.retain(localSlot.index + action.retain);
} else if (action.insert) {
var index = localSlot.index;
var length = 1;
if (typeof action.insert === 'string') {
length = action.insert.length;
localSlot.insert(action.insert, remoteInsertFormatsToLocal(_this.registry, action.attributes));
} else {
var sharedComponent = action.insert;
var component = _this.createLocalComponentBySharedComponent(sharedComponent);
localSlot.insert(component);
}
if (_this.selection.isSelected && !_instanceof$1(tr.origin, yjs.UndoManager)) {
if (localSlot === _this.selection.anchorSlot && _this.selection.anchorOffset > index) {
_this.selection.setAnchor(localSlot, _this.selection.anchorOffset + length);
}
if (localSlot === _this.selection.focusSlot && _this.selection.focusOffset > index) {
_this.selection.setFocus(localSlot, _this.selection.focusOffset + length);
}
}
} else if (action.delete) {
var index1 = localSlot.index;
localSlot.delete(action.delete);
if (_this.selection.isSelected && !_instanceof$1(tr.origin, yjs.UndoManager)) {
if (localSlot === _this.selection.anchorSlot && _this.selection.anchorOffset >= index1) {
_this.selection.setAnchor(localSlot, _this.selection.startOffset - action.delete);
}
if (localSlot === _this.selection.focusSlot && _this.selection.focusOffset >= index1) {
_this.selection.setFocus(localSlot, _this.selection.focusOffset - action.delete);
}
}
}
});
});
};
sharedSlot.observe(syncRemote);
var sub = localSlot.onContentChange.subscribe(function(actions) {
_this.runLocalUpdate(sharedSlot.doc, true, function() {
var offset = 0;
var length = 0;
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = actions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var action = _step.value;
if (action.type === 'retain') {
var formats = action.formats;
if (formats) {
var attrs = localFormatsToYjsAttributes(_this.registry, localSlot, offset, offset + action.offset, formats);
if (Object.keys(attrs).length) {
sharedSlot.format(offset, action.offset, attrs);
}
} else {
offset = action.offset;
}
} else if (action.type === 'contentInsert') {
var delta = sharedSlot.toDelta();
var isEmpty = delta.length === 1 && delta[0].insert === core.Slot.emptyPlaceholder;
if (typeof action.content === 'string') {
length = action.content.length;
sharedSlot.insert(offset, action.content, localFormatsRecordToRemote(_this.registry, action.formats) || {});
} else {
length = 1;
var sharedComponent = _this.createSharedComponentByLocalComponent(action.ref);
sharedSlot.insertEmbed(offset, sharedComponent, localFormatsRecordToRemote(_this.registry, action.formats) || {});
}
if (isEmpty && offset === 0) {
sharedSlot.delete(sharedSlot.length - 1, 1);
}
offset += length;
} else if (action.type === 'delete') {
var delta1 = sharedSlot.toDelta();
if (sharedSlot.length) {
sharedSlot.delete(offset, action.count);
}
if (sharedSlot.length === 0) {
var _delta_;
sharedSlot.insert(0, '\n', (_delta_ = delta1[0]) === null || _delta_ === void 0 ? void 0 : _delta_.attributes);
}
} else if (action.type === 'attrSet') {
sharedSlot.setAttribute(action.name, action.value);
} else if (action.type === 'attrDelete') {
sharedSlot.removeAttribute(action.name);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
});
this.slotMap.set(localSlot, sharedSlot);
localSlot.__changeMarker__.addDetachCallback(function() {
_this.slotMap.delete(localSlot);
sharedSlot.unobserve(syncRemote);
sub.unsubscribe();
});
}
},
{
key: "destroy",
value: function destroy() {
this.subscriptions.forEach(function(i) {
return i.unsubscribe();
});
this.subscriptions = [];
}
},
{
key: "syncSharedMapToLocalMap",
value: function syncSharedMapToLocalMap(sharedMap, localMap) {
var _this = this;
sharedMap.forEach(function(value, key) {
localMap[key] = core.toRaw(_this.createLocalModelBySharedByModel(value));
});
this.syncObject(sharedMap, localMap);
}
},
{
key: "createLocalMapBySharedMap",
value: function createLocalMapBySharedMap(sharedMap) {
var localMap = core.observe({});
this.syncSharedMapToLocalMap(sharedMap, localMap);
return localMap;
}
},
{
key: "createLocalArrayBySharedArray",
value: function createLocalArrayBySharedArray(sharedArray) {
var raw = [];
for(var i = 0; i < sharedArray.length; i++){
var item = sharedArray.get(i);
if (!this.isArrayHoleElement(item)) {
raw[i] = core.toRaw(this.createLocalModelBySharedByModel(item));
}
}
raw.length = sharedArray.length;
var localArray = core.observe(raw);
this.syncArray(sharedArray, localArray);
return localArray;
}
},
{
key: "syncLocalMapToSharedMap",
value: function syncLocalMapToSharedMap(localMap, sharedMap) {
var _this = this;
Object.entries(localMap).forEach(function(param) {
var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
sharedMap.set(key, _this.createSharedModelByLocalModel(value));
});
this.syncObject(sharedMap, localMap);
}
},
{
key: "createSharedMapByLocalMap",
value: function createSharedMapByLocalMap(localMap) {
var sharedMap = new yjs.Map();
this.syncLocalMapToSharedMap(localMap, sharedMap);
return sharedMap;
}
},
{
key: "createSharedArrayByLocalArray",
value: function createSharedArrayByLocalArray(localArray) {
var sharedArray = new yjs.Array();
for(var i = 0; i < localArray.length; i++){
if (i in localArray) {
sharedArray.push([
this.sharedModelForArraySlot(localArray[i])
]);
} else {
sharedArray.push([
this.createArrayHoleXmlElement()
]);
}
}
this.syncArray(sharedArray, localArray);
return sharedArray;
}
},
{
key: "createSharedSlotByLocalSlot",
value: function createSharedSlotByLocalSlot(localSlot) {
var _this = this;
var sharedSlot = new yjs.Text();
var isAsyncSlot = _instanceof$1(localSlot, core.AsyncSlot);
sharedSlot.setAttribute('schema', _to_consumable_array(localSlot.schema));
sharedSlot.setAttribute('type', isAsyncSlot ? 'async' : 'sync');
if (isAsyncSlot) {
var isDestroyed = false;
var sharedMetadata = this.createSharedMapByLocalMap(localSlot.metadata);
sharedSlot.setAttribute('metadata', sharedMetadata);
this.subModelLoader.createSubModelBySlot(localSlot).then(function(subDocument) {
if (isDestroyed) {
return;
}
var content = subDocument.getText('content');
var state = subDocument.getMap('state');
_this.syncLocalMapToSharedMap(localSlot.state, state);
_this.initSharedSlotByLocalSlot(content, localSlot);
_this.syncSlot(content, localSlot);
_this.addSubModelEvent.next({
yDoc: subDocument,
yType: content
});
_this.initSyncEvent(subDocument);
localSlot.loader.markAsLoaded();
});
localSlot.__changeMarker__.addDetachCallback(function() {
isDestroyed = true;
});
return sharedSlot;
}
var sharedSlotState = new yjs.Map();
this.syncLocalMapToSharedMap(localSlot.state, sharedSlotState);
sharedSlot.setAttribute('state', sharedSlotState);
var sharedContent = new yjs.Text();
this.initSharedSlotByLocalSlot(sharedContent, localSlot);
sharedSlot.insertEmbed(0, sharedContent);
this.syncSlot(sharedContent, localSlot);
return sharedSlot;
}
},
{
key: "initSharedSlotByLocalSlot",
value: function initSharedSlotByLocalSlot(sharedContent, localSlot) {
var _this = this;
var offset = 0;
localSlot.toDelta().forEach(function(i) {
var formats = i.formats ? formatsArrayToRemoteRecord(_this.registry, i.formats) : undefined;
if (typeof i.insert === 'string') {
sharedContent.insert(offset, i.insert, formats);
} else {
var sharedComponent = _this.createSharedComponentByLocalComponent(i.insert);
sharedContent.insertEmbed(offset, sharedComponent, formats);
}
offset += i.insert.length;
});
localSlot.getAttributes().forEach(function(item) {
sharedContent.setAttribute(item[0].name, item[1]);
});
}
},
{
key: "createLocalSlotBySharedSlot",
value: function createLocalSlotBySharedSlot(sharedSlot) {
var _this = this;
var _contentDelta_;
var type = sharedSlot.getAttribute('type');
var schema = sharedSlot.getAttribute('schema');
if (type === 'async') {
var metadata = sharedSlot.getAttribute('metadata');
var slot = new core.AsyncSlot(schema || [], {}, {});
this.syncSharedMapToLocalMap(metadata, slot.metadata);
var loadedSubDocument = this.subModelLoader.getLoadedModelBySlot(slot);
if (loadedSubDocument) {
var subContent = loadedSubDocument.getText('content');
var data = loadedSubDocument.getMap('state');
this.syncSharedMapToLocalMap(data, slot.state);
this.syncRootSlot(loadedSubDocument, subContent, slot);
this.addSubModelEvent.next({
yDoc: loadedSubDocument,
yType: subContent
});
slot.loader.markAsLoaded();
return slot;
}
var isDestroyed = false;
slot.loader.onRequestLoad.toPromise().then(function() {
return _this.subModelLoader.loadSubModelBySlot(slot);
}).then(function(subDocument) {
if (isDestroyed) {
return;
}
var subContent = subDocument.getText('content');
var state = subDocument.getMap('state');
_this.syncSharedMapToLocalMap(state, slot.state);
_this.syncRootSlot(subDocument, subContent, slot);
_this.addSubModelEvent.next({
yDoc: subDocument,
yType: subContent
});
slot.loader.markAsLoaded();
});
slot.__changeMarker__.addDetachCallback(function() {
isDestroyed = true;
});
return slot;
}
var contentDelta = sharedSlot.toDelta();
var content = (_contentDelta_ = contentDelta[0]) === null || _contentDelta_ === void 0 ? void 0 : _contentDelta_.insert;
if (!_instanceof$1(content, yjs.Text)) {
throw collaborateErrorFn('shared slot content type is not `YText`.');
}
var localSlot = new core.Slot(schema || [], {});
var sharedSlotState = sharedSlot.getAttribute('state');
this.syncSharedMapToLocalMap(sharedSlotState, localSlot.state);
this.initLocalSlotBySharedSlot(content, localSlot);
this.syncSlot(content, localSlot);
return localSlot;
}
},
{
key: "initLocalSlotBySharedSlot",
value: function initLocalSlotBySharedSlot(content, localSlot) {
var _this = this;
var delta = content.toDelta();
var attrs = content.getAttributes();
Object.keys(attrs).forEach(function(key) {
var attribute = _this.registry.getAttribute(key);
if (attribute) {
localSlot.setAttribute(attribute, attrs[key]);
}
});
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
for(var _iterator = delta[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var action = _step.value;
if (action.insert) {
if (typeof action.insert === 'string') {
var formats = remoteInsertFormatsToLocal(this.registry, action.attributes);
localSlot.insert(action.insert, formats);
} else {
var sharedComponent = action.insert;
var component = this.createLocalComponentBySharedComponent(sharedComponent);
localSlot.insert(component, remoteInsertFormatsToLocal(this.registry, action.attributes));
}
} else {
throw collaborateErrorFn('unexpected delta action.');
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
},
{
key: "createSharedModelByLocalModel",
value: function createSharedModelByLocalModel(localModel) {
if (_instanceof$1(localModel, core.Slot)) {
return this.createSharedSlotByLocalSlot(localModel);
}
if (Array.isArray(localModel)) {
return this.createSharedArrayByLocalArray(localModel);
}
if ((typeof localModel === "undefined" ? "undefined" : _type_of$3(localModel)) === 'object' && localModel !== null) {
return this.createSharedMapByLocalMap(localModel);
}
return localModel;
}
},
{
key: "createLocalModelBySharedByModel",
value: function createLocalModelBySharedByModel(sharedModel) {
if (_instanceof$1(sharedModel, yjs.Map)) {
return this.createLocalMapBySharedMap(sharedModel);
}
if (_instanceof$1(sharedModel, yjs.Array)) {
return this.createLocalArrayBySharedArray(sharedModel);
}
if (_instanceof$1(sharedModel, yjs.Text)) {
return this.createLocalSlotBySharedSlot(sharedModel);
}
return sharedModel;
}
},
{
key: "createSharedComponentByLocalComponent",
value: function createSharedComponentByLocalComponent(component) {
var _this = this;
var sharedComponent = new yjs.Map();
sharedComponent.set('name', component.name);
if (_instanceof$1(component, core.AsyncComponent)) {
sharedComponent.set('type', 'async');
var sharedMetadata = this.createSharedMapByLocalMap(component.metadata);
sharedComponent.set('metadata', sharedMetadata);
var state = component.state;
var isDestroyed = false;
state.__changeMarker__.addDetachCallback(function() {
isDestroyed = true;
});
this.subModelLoader.createSubModelByComponent(component).then(function(subDocument) {
if (isDestroyed) {
return;
}
var state = subDocument.getMap('state');
_this.syncComponent(subDocument, state, component);
_this.addSubModelEvent.next({
yType: state,
yDoc: subDocument
});
_this.initSyncEvent(subDocument);
component.loader.markAsLoaded();
});
return sharedComponent;
}
var sharedState = this.createSharedMapByLocalMap(component.state);
sharedComponent.set('state', sharedState);
sharedComponent.set('type', 'sync');
return sharedComponent;
}
},
{
key: "createLocalComponentBySharedComponent",
value: function createLocalComponentBySharedComponent(yMap) {
var _this = this;
var componentName = yMap.get('name');
var type = yMap.get('type');
var instance;
if (type === 'async') {
instance = this.registry.createComponentByData(componentName, {}, {});
if (_instanceof$1(instance, core.AsyncComponent)) {
var sharedMetadata = yMap.get('metadata');
this.syncSharedMapToLocalMap(sharedMetadata, instance.metadata);
var loadedSubDocument = this.subModelLoader.getLoadedModelByComponent(instance);
if (loadedSubDocument) {
var state = loadedSubDocument.getMap('state');
this.syncComponent(loadedSubDocument, state, instance);
this.addSubModelEvent.next({
yType: state,
yDoc: loadedSubDocument
});
instance.loader.markAsLoaded();
return instance;
}
var state1 = instance.state;
var isDestroyed = false;
instance.loader.onRequestLoad.toPromise().then(function() {
return _this.subModelLoader.loadSubModelByComponent(instance);
}).then(function(subDocument) {
if (isDestroyed) {
return;
}
var state = subDocument.getMap('state');
_this.syncComponent(subDocument, state, instance);
_this.addSubModelEvent.next({
yType: state,
yDoc: subDocument
});
instance.loader.markAsLoaded();
});
state1.__changeMarker__.addDetachCallback(function() {
isDestroyed = true;
});
} else if (_instanceof$1(instance, core.Component)) {
throw collaborateErrorFn("component name `".concat(componentName, "` is not a async component."));
}
} else {
var sharedState = yMap.get('state');
var state2 = this.createLocalMapBySharedMap(sharedState);
instance = this.registry.createComponentByData(componentName, state2);
}
if (instance) {
return instance;
}
throw collaborateErrorFn("cannot find component factory `".concat(componentName, "`."));
}
},
{
key: "createArrayHoleXmlElement",
value: function createArrayHoleXmlElement() {
return new yjs.XmlElement(ARRAY_HOLE_ELEMENT_NODE);
}
},
{
key: "isArrayHoleElement",
value: function isArrayHoleElement(sharedModel) {
return _instanceof$1(sharedModel, yjs.XmlElement) && sharedModel.nodeName === ARRAY_HOLE_ELEMENT_NODE;
}
},
{
key: "sharedModelForArraySlot",
value: /**
* 仅用于 YArray ↔ 可