@textbus/collaborate 5.2.1 → 5.2.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/index.js CHANGED
@@ -1,3 +1,1412 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("@viewfly/core"),d=require("@textbus/core"),f=require("@tanbo/stream"),u=require("yjs"),x=require("@hocuspocus/provider"),B=require("y-websocket");var _=Object.getOwnPropertyDescriptor,T=(h,e,t,s)=>{for(var o=s>1?void 0:s?_(e,t):e,n=h.length-1,a;n>=0;n--)(a=h[n])&&(o=a(o)||o);return o},E=(h,e)=>(t,s)=>e(t,s,h);class A{}const R=d.makeError("CollabHistory");exports.CollabHistory=class{constructor(e,t,s,o,n){this.rootComponentRef=e,this.collaborate=t,this.scheduler=s,this.stackSize=o,this.undoManagerConfig=n,this.onBack=this.backEvent.asObservable(),this.onForward=this.forwardEvent.asObservable(),this.onChange=this.changeEvent.asObservable(),this.onPush=this.pushEvent.asObservable()}rootComponentRef;collaborate;scheduler;stackSize;undoManagerConfig;onBack;onForward;onChange;onPush;get canBack(){return this.manager?.canUndo()||!1}get canForward(){return this.manager?.canRedo()||!1}manager=null;historyItems=[];index=0;subscriptions=[];backEvent=new f.Subject;forwardEvent=new f.Subject;changeEvent=new f.Subject;pushEvent=new f.Subject;listen(){const e=this.collaborate.yDoc.getMap("RootComponent"),t=this.rootComponentRef.component;this.collaborate.syncRootComponent(this.collaborate.yDoc,e,t);const s=this.undoManagerConfig||{},o=new u.UndoManager(e,{trackedOrigins:new Set([this.collaborate.yDoc]),captureTransaction(a){return s.captureTransaction?s.captureTransaction(a):!0},deleteFilter(a){return s.deleteFilter?s.deleteFilter(a):!0}});this.manager=o;let n=null;this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(()=>{n=this.collaborate.getRelativeCursorLocation()}),this.collaborate.onAddSubModel.subscribe(()=>{throw R("single document does not support submodels.")})),o.on("stack-item-added",a=>{a.type==="undo"?a.origin===o?this.index++:(this.historyItems.length=this.index,this.historyItems.push({before:n,after:this.collaborate.getRelativeCursorLocation()}),this.index++):this.index--,o.undoStack.length>this.stackSize&&(this.historyItems.shift(),o.undoStack.shift()),a.origin===this.collaborate.yDoc&&this.pushEvent.next(),this.changeEvent.next()}),o.on("stack-item-popped",a=>{const i=a.type==="undo"?this.index:this.index-1,r=this.historyItems[i]||null,c=a.type==="undo"?r?.before:r?.after;this.collaborate.restoreCursorPosition(c)})}back(){this.canBack&&(this.manager?.undo(),this.backEvent.next())}forward(){this.canForward&&(this.manager?.redo(),this.forwardEvent.next())}clear(){const e=this.historyItems.pop();this.historyItems=e?[e]:[],this.index=e?1:0,this.manager?.clear(),this.changeEvent.next()}destroy(){this.index=0,this.historyItems=[],this.subscriptions.forEach(e=>e.unsubscribe()),this.manager&&(this.manager.destroy(),this.manager.captureTransaction=()=>!0,this.manager.deleteFilter=()=>!0,this.manager.trackedOrigins=new Set([null])),this.manager=null}};exports.CollabHistory=T([y.Injectable(),E(3,y.Inject(d.HISTORY_STACK_SIZE)),E(4,y.Optional())],exports.CollabHistory);var D=Object.getOwnPropertyDescriptor,P=(h,e,t,s)=>{for(var o=s>1?void 0:s?D(e,t):e,n=h.length-1,a;n>=0;n--)(a=h[n])&&(o=a(o)||o);return o};const m=d.makeError("Collaborate");class O{slotAndYTextMap=new WeakMap;yTextAndSlotMap=new WeakMap;set(e,t){e instanceof d.Slot?(this.slotAndYTextMap.set(e,t),this.yTextAndSlotMap.set(t,e)):(this.slotAndYTextMap.set(t,e),this.yTextAndSlotMap.set(e,t))}get(e){return e instanceof d.Slot?this.slotAndYTextMap.get(e)||null:this.yTextAndSlotMap.get(e)||null}delete(e){if(e instanceof d.Slot){const t=this.slotAndYTextMap.get(e);this.slotAndYTextMap.delete(e),t&&this.yTextAndSlotMap.delete(t)}else{const t=this.yTextAndSlotMap.get(e);this.yTextAndSlotMap.delete(e),t&&this.slotAndYTextMap.delete(t)}}}exports.Collaborate=class{constructor(e,t,s,o){this.scheduler=e,this.registry=t,this.selection=s,this.subModelLoader=o,this.onAddSubModel=this.addSubModelEvent.asObservable()}scheduler;registry;selection;subModelLoader;yDoc=new u.Doc;slotMap=new O;onAddSubModel;subscriptions=[];updateFromRemote=!1;addSubModelEvent=new f.Subject;updateRemoteActions=new WeakMap;noRecord={};syncRootComponent(e,t,s){this.initSyncEvent(e),this.syncComponent(e,t,s)}syncRootSlot(e,t,s){t.length?(s.retain(0),s.delete(s.length),s.cleanAttributes(),s.cleanFormats(),this.initLocalSlotBySharedSlot(t,s)):e.transact(()=>{this.initSharedSlotByLocalSlot(t,s)}),this.initSyncEvent(e),this.syncSlot(t,s)}getAbstractSelection(e){const t=u.createAbsolutePositionFromRelativePosition(e.anchor.position,e.anchor.doc),s=u.createAbsolutePositionFromRelativePosition(e.focus.position,e.focus.doc);if(t&&s){const o=this.slotMap.get(s.type),n=this.slotMap.get(t.type);if(o&&n)return{anchorSlot:n,anchorOffset:t.index,focusSlot:o,focusOffset:s.index}}return null}getRelativeCursorLocation(){const{anchorSlot:e,anchorOffset:t,focusSlot:s,focusOffset:o}=this.selection;if(e){const n=this.slotMap.get(e);if(n){const a=u.createRelativePositionFromTypeIndex(n,t);if(s){const i=this.slotMap.get(s);if(i){const r=u.createRelativePositionFromTypeIndex(i,o);return{focus:{doc:i.doc,position:r},anchor:{doc:n.doc,position:a}}}}}}return null}restoreCursorPosition(e){if(!e){this.selection.unSelect();return}const t=this.getAbstractSelection(e);t&&this.selection.setBaseAndExtent(t.anchorSlot,t.anchorOffset,t.focusSlot,t.focusOffset)}initSyncEvent(e){this.subscriptions.push(this.scheduler.onDocChanged.pipe(f.map(t=>t.filter(s=>s.from!==d.ChangeOrigin.Remote)),f.filter(t=>t.length)).subscribe(()=>{const t=[];let s=null;const o=this.updateRemoteActions.get(e)||[];for(const n of o)s||(s={record:n.record,actions:[]},t.push(s)),s.record===n.record?s.actions.push(n.action):(s={record:n.record,actions:[n.action]},t.push(s));this.updateRemoteActions.delete(e);for(const n of t)e.transact(()=>{n.actions.forEach(a=>{a()})},n.record?e:this.noRecord)}))}syncComponent(e,t,s){let o=t.get("state");o?(Object.keys(s.state).forEach(n=>{Reflect.deleteProperty(s.state,n)}),this.syncSharedMapToLocalMap(o,s.state)):(o=new u.Map,this.syncLocalMapToSharedMap(s.state,o),e.transact(()=>{t.set("state",o)}))}syncSlot(e,t){const s=(n,a)=>{this.runRemoteUpdate(a,()=>{t.retain(0),n.keysChanged.forEach(i=>{const r=n.keys.get(i);if(!r)return;const c=r.action;if(c==="update"||c==="add"){const l=this.registry.getAttribute(i);l&&t.setAttribute(l,e.getAttribute(i))}else if(c==="delete"){const l=this.registry.getAttribute(i);l&&t.removeAttribute(l)}}),n.delta.forEach(i=>{if(Reflect.has(i,"retain")){if(i.attributes){const r=C(this.registry,i.attributes);r.length&&t.retain(i.retain,r)}t.retain(t.index+i.retain)}else if(i.insert){const r=t.index;let c=1;if(typeof i.insert=="string")c=i.insert.length,t.insert(i.insert,C(this.registry,i.attributes));else{const l=i.insert,p=this.createLocalComponentBySharedComponent(l);t.insert(p)}this.selection.isSelected&&!(a.origin instanceof u.UndoManager)&&(t===this.selection.anchorSlot&&this.selection.anchorOffset>r&&this.selection.setAnchor(t,this.selection.anchorOffset+c),t===this.selection.focusSlot&&this.selection.focusOffset>r&&this.selection.setFocus(t,this.selection.focusOffset+c))}else if(i.delete){const r=t.index;t.delete(i.delete),this.selection.isSelected&&!(a.origin instanceof u.UndoManager)&&(t===this.selection.anchorSlot&&this.selection.anchorOffset>=r&&this.selection.setAnchor(t,this.selection.startOffset-i.delete),t===this.selection.focusSlot&&this.selection.focusOffset>=r&&this.selection.setFocus(t,this.selection.focusOffset-i.delete))}})})};e.observe(s);const o=t.onContentChange.subscribe(n=>{this.runLocalUpdate(e.doc,!0,()=>{let a=0,i=0;for(const r of n)if(r.type==="retain"){const c=r.formats;if(c){const l=Object.keys(c);let p=l.length;l.forEach(g=>{this.registry.getFormatter(g)||(p--,Reflect.deleteProperty(c,g))}),p&&e.format(a,r.offset,c)}else a=r.offset}else if(r.type==="contentInsert"){const c=e.toDelta(),l=c.length===1&&c[0].insert===d.Slot.emptyPlaceholder;if(typeof r.content=="string")i=r.content.length,e.insert(a,r.content,r.formats||{});else{i=1;const p=this.createSharedComponentByLocalComponent(r.ref);e.insertEmbed(a,p,r.formats||{})}l&&a===0&&e.delete(e.length-1,1),a+=i}else if(r.type==="delete"){const c=e.toDelta();e.length&&e.delete(a,r.count),e.length===0&&e.insert(0,`
2
- `,c[0]?.attributes)}else r.type==="attrSet"?e.setAttribute(r.name,r.value):r.type==="attrDelete"&&e.removeAttribute(r.name)})});this.slotMap.set(t,e),t.__changeMarker__.addDetachCallback(()=>{this.slotMap.delete(t),e.unobserve(s),o.unsubscribe()})}destroy(){this.subscriptions.forEach(e=>e.unsubscribe()),this.subscriptions=[]}syncSharedMapToLocalMap(e,t){e.forEach((s,o)=>{t[o]=this.createLocalModelBySharedByModel(s)}),this.syncObject(e,t)}createLocalMapBySharedMap(e){const t=d.observe({});return this.syncSharedMapToLocalMap(e,t),t}createLocalArrayBySharedArray(e){const t=d.observe([]);return t.push(...e.map(s=>this.createLocalModelBySharedByModel(s))),this.syncArray(e,t),t}syncLocalMapToSharedMap(e,t){Object.entries(e).forEach(([s,o])=>{t.set(s,this.createSharedModelByLocalModel(o))}),this.syncObject(t,e)}createSharedMapByLocalMap(e){const t=new u.Map;return this.syncLocalMapToSharedMap(e,t),t}createSharedArrayByLocalArray(e){const t=new u.Array;return e.forEach(s=>{t.push([this.createSharedModelByLocalModel(s)])}),this.syncArray(t,e),t}createSharedSlotByLocalSlot(e){const t=new u.Text,s=e instanceof d.AsyncSlot;if(t.setAttribute("schema",[...e.schema]),t.setAttribute("type",s?"async":"sync"),s){let a=!1;const i=this.createSharedMapByLocalMap(e.metadata);return t.setAttribute("metadata",i),this.subModelLoader.createSubModelBySlot(e).then(r=>{if(a)return;const c=r.getText("content"),l=r.getMap("state");this.syncLocalMapToSharedMap(e.state,l),this.initSharedSlotByLocalSlot(c,e),this.syncSlot(c,e),this.addSubModelEvent.next({yDoc:r,yType:c}),this.initSyncEvent(r),e.loader.markAsLoaded()}),e.__changeMarker__.addDetachCallback(()=>{a=!0}),t}const o=new u.Map;this.syncLocalMapToSharedMap(e.state,o),t.setAttribute("state",o);const n=new u.Text;return this.initSharedSlotByLocalSlot(n,e),t.insertEmbed(0,n),this.syncSlot(n,e),t}initSharedSlotByLocalSlot(e,t){let s=0;t.toDelta().forEach(o=>{let n={};if(o.formats?o.formats.forEach(a=>{n[a[0].name]=a[1]}):n=null,typeof o.insert=="string")e.insert(s,o.insert,n);else{const a=this.createSharedComponentByLocalComponent(o.insert);e.insertEmbed(s,a,n)}s+=o.insert.length}),t.getAttributes().forEach(o=>{e.setAttribute(o[0].name,o[1])})}createLocalSlotBySharedSlot(e){const t=e.getAttribute("type"),s=e.getAttribute("schema");if(t==="async"){const r=e.getAttribute("metadata"),c=new d.AsyncSlot(s||[],{},{});this.syncSharedMapToLocalMap(r,c.metadata);const l=this.subModelLoader.getLoadedModelBySlot(c);if(l){const g=l.getText("content"),S=l.getMap("state");return this.syncSharedMapToLocalMap(S,c.state),this.syncRootSlot(l,g,c),this.addSubModelEvent.next({yDoc:l,yType:g}),c.loader.markAsLoaded(),c}let p=!1;return c.loader.onRequestLoad.toPromise().then(()=>this.subModelLoader.loadSubModelBySlot(c)).then(g=>{if(p)return;const S=g.getText("content"),w=g.getMap("state");this.syncSharedMapToLocalMap(w,c.state),this.syncRootSlot(g,S,c),this.addSubModelEvent.next({yDoc:g,yType:S}),c.loader.markAsLoaded()}),c.__changeMarker__.addDetachCallback(()=>{p=!0}),c}const n=e.toDelta()[0]?.insert;if(!(n instanceof u.Text))throw m("shared slot content type is not `YText`.");const a=new d.Slot(s||[],{}),i=e.getAttribute("state");return this.syncSharedMapToLocalMap(i,a.state),this.initLocalSlotBySharedSlot(n,a),this.syncSlot(n,a),a}initLocalSlotBySharedSlot(e,t){const s=e.toDelta(),o=e.getAttributes();Object.keys(o).forEach(n=>{const a=this.registry.getAttribute(n);a&&t.setAttribute(a,o[n])});for(const n of s)if(n.insert)if(typeof n.insert=="string"){const a=C(this.registry,n.attributes);t.insert(n.insert,a)}else{const a=n.insert,i=this.createLocalComponentBySharedComponent(a);t.insert(i,C(this.registry,n.attributes))}else throw m("unexpected delta action.")}createSharedModelByLocalModel(e){return e instanceof d.Slot?this.createSharedSlotByLocalSlot(e):Array.isArray(e)?this.createSharedArrayByLocalArray(e):typeof e=="object"&&e!==null?this.createSharedMapByLocalMap(e):e}createLocalModelBySharedByModel(e){return e instanceof u.Map?this.createLocalMapBySharedMap(e):e instanceof u.Array?this.createLocalArrayBySharedArray(e):e instanceof u.Text?this.createLocalSlotBySharedSlot(e):e}createSharedComponentByLocalComponent(e){const t=new u.Map;if(t.set("name",e.name),e instanceof d.AsyncComponent){t.set("type","async");const o=this.createSharedMapByLocalMap(e.metadata);t.set("metadata",o);const n=e.state;let a=!1;return n.__changeMarker__.addDetachCallback(()=>{a=!0}),this.subModelLoader.createSubModelByComponent(e).then(i=>{if(a)return;const r=i.getMap("state");this.syncComponent(i,r,e),this.addSubModelEvent.next({yType:r,yDoc:i}),this.initSyncEvent(i),e.loader.markAsLoaded()}),t}const s=this.createSharedMapByLocalMap(e.state);return t.set("state",s),t.set("type","sync"),t}createLocalComponentBySharedComponent(e){const t=e.get("name"),s=e.get("type");let o;if(s==="async"){if(o=this.registry.createComponentByData(t,{},{}),o instanceof d.AsyncComponent){const n=e.get("metadata");this.syncSharedMapToLocalMap(n,o.metadata);const a=this.subModelLoader.getLoadedModelByComponent(o);if(a){const c=a.getMap("state");return this.syncComponent(a,c,o),this.addSubModelEvent.next({yType:c,yDoc:a}),o.loader.markAsLoaded(),o}const i=o.state;let r=!1;o.loader.onRequestLoad.toPromise().then(()=>this.subModelLoader.loadSubModelByComponent(o)).then(c=>{if(r)return;const l=c.getMap("state");this.syncComponent(c,l,o),this.addSubModelEvent.next({yType:l,yDoc:c}),o.loader.markAsLoaded()}),i.__changeMarker__.addDetachCallback(()=>{r=!0})}else if(o instanceof d.Component)throw m(`component name \`${t}\` is not a async component.`)}else{const n=e.get("state"),a=this.createLocalMapBySharedMap(n);o=this.registry.createComponentByData(t,a)}if(o)return o;throw m(`cannot find component factory \`${t}\`.`)}syncArray(e,t){function s(a){console.error(m(`${a} error, length exceeded, path in ${t.__changeMarker__.getPaths().join("/")}`))}const o=t.__changeMarker__.onSelfChange.subscribe(a=>{this.runLocalUpdate(e.doc,!t.__changeMarker__.irrevocableUpdate,()=>{let i=0;for(const r of a)switch(r.type){case"retain":i=r.offset;break;case"insert":{const c=r.ref;if(!Array.isArray(c))throw m("The insertion action must have a reference value.");const l=c.map(p=>this.createSharedModelByLocalModel(p));i<=e.length?e.insert(i,l):(e.insert(e.length,l),s("insert"))}break;case"delete":if(r.count<=0)break;i<e.length?e.delete(i,r.count):s("delete");break;case"setIndex":r.index<e.length?(e.delete(r.index,1),e.insert(r.index,[this.createSharedModelByLocalModel(r.ref)])):(e.insert(e.length,[this.createSharedModelByLocalModel(r.ref)]),s("setIndex"));break}})}),n=(a,i)=>{this.runRemoteUpdate(i,()=>{let r=0;a.delta.forEach(c=>{if(Reflect.has(c,"retain"))r+=c.retain;else if(c.insert){const l=c.insert.map(p=>this.createLocalModelBySharedByModel(p));t.splice(r,0,...l),r+=l.length}else c.delete&&t.splice(r,c.delete)})})};e.observe(n),t.__changeMarker__.addDetachCallback(()=>{o.unsubscribe(),e.unobserve(n)})}syncObject(e,t){const s=(n,a)=>{this.runRemoteUpdate(a,()=>{n.changes.keys.forEach((i,r)=>{if(i.action==="add"||i.action==="update"){const c=e.get(r);t[r]=this.createLocalModelBySharedByModel(c)}else Reflect.deleteProperty(t,r)})})};e.observe(s);const o=t.__changeMarker__.onSelfChange.subscribe(n=>{this.runLocalUpdate(e.doc,!t.__changeMarker__.irrevocableUpdate,()=>{for(const a of n)switch(a.type){case"propSet":{const i=this.createSharedModelByLocalModel(a.ref);e.set(a.key,i),e.size===0&&console.error(m(`prop set error, key is ${a.key}`))}break;case"propDelete":e.delete(a.key);break}})});t.__changeMarker__.addDetachCallback(function(){e.unobserve(s),o.unsubscribe()})}runLocalUpdate(e,t,s){if(this.updateFromRemote||!e)return;let o=this.updateRemoteActions.get(e);o||(o=[],this.updateRemoteActions.set(e,o)),o.push({record:t,action:s})}runRemoteUpdate(e,t){e.origin!==e.doc&&(this.updateFromRemote=!0,e.origin instanceof u.UndoManager?this.scheduler.historyApplyTransact(t):this.scheduler.remoteUpdateTransact(t),this.updateFromRemote=!1)}};exports.Collaborate=P([y.Injectable()],exports.Collaborate);function C(h,e){const t=[];return e&&Object.keys(e).forEach(s=>{const o=h.getFormatter(s);o&&t.push([o,e[s]])}),t}class L{onSync;syncEvent=new f.Subject;constructor(){this.onSync=this.syncEvent.asObservable()}sync(){this.syncEvent.next()}}var F=Object.getOwnPropertyDescriptor,I=(h,e,t,s)=>{for(var o=s>1?void 0:s?F(e,t):e,n=h.length-1,a;n>=0;n--)(a=h[n])&&(o=a(o)||o);return o},k=(h,e)=>(t,s)=>e(t,s,h);exports.MultipleDocCollabHistory=class{constructor(e,t,s,o,n){this.collaborate=e,this.scheduler=t,this.rootComponentRef=s,this.stackSize=o,this.undoManagerConfig=n,this.onChange=this.changeEvent.asObservable(),this.onBack=this.backEvent.asObservable(),this.onForward=this.forwardEvent.asObservable(),this.onPush=this.pushEvent.asObservable()}collaborate;scheduler;rootComponentRef;stackSize;undoManagerConfig;onChange;onBack;onForward;onPush;get canBack(){return this.actionStack.length>0&&this.index>0}get canForward(){return this.actionStack.length>0&&this.index<this.actionStack.length}isListen=!1;changeEvent=new f.Subject;backEvent=new f.Subject;forwardEvent=new f.Subject;pushEvent=new f.Subject;actionStack=[];index=0;stackItem=null;timer=null;beforePosition=null;subscription=new f.Subscription;subDocs=new Set;listenerCaches=new Set;listen(){this.isListen=!0;const e=this.collaborate.yDoc.getMap("RootComponent"),t=this.rootComponentRef.component;this.collaborate.syncRootComponent(this.collaborate.yDoc,e,t),this.listenItem(e,this.collaborate.yDoc),this.subscription.add(this.collaborate.onAddSubModel.subscribe(({yType:s,yDoc:o})=>{this.subDocs.has(s)||(this.subDocs.add(s),this.isListen&&this.listenItem(s,o))}),this.scheduler.onLocalChangeBefore.subscribe(()=>{this.beforePosition=this.collaborate.getRelativeCursorLocation()}))}forward(){if(!this.canForward)return;clearTimeout(this.timer);const e=this.actionStack[this.index];if(e){for(const t of e.undoManagers)t.redo();this.collaborate.restoreCursorPosition(e.after)}this.index++,this.forwardEvent.next(),this.changeEvent.next()}back(){if(!this.canBack)return;clearTimeout(this.timer);let e;this.stackItem?(e=this.stackItem,this.stackItem=null):(this.index--,e=this.actionStack[this.index]);let t=e.undoManagers.length;for(;t>0;)t--,e.undoManagers[t].undo();if(e){const s=e.before;this.collaborate.restoreCursorPosition(s),this.backEvent.next(),this.changeEvent.next()}}clear(){this.actionStack=[],this.stackItem=null,this.index=0,this.beforePosition=null,clearTimeout(this.timer),this.listenerCaches.forEach(e=>{e.clear()}),this.changeEvent.next()}destroy(){this.clear(),this.beforePosition=this.stackItem=null,this.subscription.unsubscribe(),this.listenerCaches.forEach(e=>{e.destroy()}),this.subDocs.clear(),this.listenerCaches.clear()}listenItem(e,t){const s=this.undoManagerConfig||{},o=new u.UndoManager(e,{trackedOrigins:new Set([t]),captureTimeout:0,captureTransaction(n){return s.captureTransaction?s.captureTransaction(n):!0},deleteFilter(n){return s.deleteFilter?s.deleteFilter(n):!0}});o.on("stack-item-added",n=>{n.type==="undo"&&!(n.origin instanceof u.UndoManager)&&(this.index!=this.actionStack.length&&(this.actionStack.slice(this.index).forEach(i=>{i.undoManagers.forEach(r=>{r.clear(!1,!0)})}),this.actionStack.length=this.index,this.changeEvent.next()),this.stackItem===null&&(this.stackItem={before:this.beforePosition,after:null,undoManagers:[]},this.timer=setTimeout(()=>{this.actionStack.length>=this.stackSize?this.actionStack.shift():this.index++,this.stackItem.after=this.beforePosition,this.actionStack.push(this.stackItem),this.stackItem=null,this.pushEvent.next(),this.changeEvent.next()},500)),this.stackItem.undoManagers.push(o))}),this.listenerCaches.add(o)}};exports.MultipleDocCollabHistory=I([y.Injectable(),k(3,y.Inject(d.HISTORY_STACK_SIZE)),k(4,y.Optional())],exports.MultipleDocCollabHistory);var U=Object.getOwnPropertyDescriptor,j=(h,e,t,s)=>{for(var o=s>1?void 0:s?U(e,t):e,n=h.length-1,a;n>=0;n--)(a=h[n])&&(o=a(o)||o);return o};const M=d.makeError("subModelLoaderError");class v{}exports.NonSubModelLoader=class extends v{createSubModelBySlot(){throw M("single document does not support async slot.")}createSubModelByComponent(){throw M("single document does not support async component.")}loadSubModelByComponent(){throw M("single document does not support async component.")}loadSubModelBySlot(){throw M("single document does not support async slot.")}getLoadedModelBySlot(){throw M("single document does not support async slot.")}getLoadedModelByComponent(){throw M("single document does not support async component.")}};exports.NonSubModelLoader=j([y.Injectable()],exports.NonSubModelLoader);class b{onLoad;onStateChange;loadEvent=new f.Subject;stateChangeEvent=new f.Subject;constructor(){this.onLoad=this.loadEvent.asObservable(),this.onStateChange=this.stateChangeEvent.asObservable()}}class H extends b{provide;constructor(e){super(),this.provide=new x.HocuspocusProvider({...e,onSynced:t=>{e.onSynced?.(t),this.loadEvent.next()},onAwarenessUpdate:t=>{e.onAwarenessUpdate?.(t);const s=t.states.map(o=>({clientId:o.clientId,message:o.message}));this.stateChangeEvent.next(s)}})}setLocalStateField(e,t){this.provide.setAwarenessField(e,t)}onDestroy(){this.provide.disconnect(),this.provide.destroy()}}class Y extends b{provide;onSync=e=>{e&&this.loadEvent.next()};onUpdate=()=>{const e=[];this.provide.awareness.getStates().forEach((t,s)=>{e.push({clientId:s,message:t.message})}),this.stateChangeEvent.next(e)};constructor(e,t,s){super(),this.onLoad=this.loadEvent.asObservable(),this.onStateChange=this.stateChangeEvent.asObservable(),this.provide=new B.WebsocketProvider(e,t,s),this.provide.once("sync",this.onSync),this.provide.awareness.on("update",this.onUpdate)}setLocalStateField(e,t){this.provide.awareness.setLocalStateField(e,t)}onDestroy(){this.provide.awareness.off("update",this.onUpdate),this.provide.disconnect(),this.provide.destroy()}}class ${constructor(e){this.config=e}config;subscription=new f.Subscription;providers=[exports.Collaborate,exports.CollabHistory,{provide:d.History,useExisting:exports.CollabHistory},{provide:b,useFactory:e=>this.config.createConnector(e.yDoc),deps:[exports.Collaborate]},{provide:v,useClass:exports.NonSubModelLoader}];timer=null;setup(e){const t=e.get(L,null),s=e.get(b),o=e.get(exports.Collaborate);if(t){const n=e.get(d.Selection);s.setLocalStateField("message",t.get(e)),this.subscription.add(t.onSync.subscribe(()=>{s.setLocalStateField("message",t.get(e))}),n.onChange.subscribe(()=>{s.setLocalStateField("message",t.get(e))}),s.onStateChange.subscribe(a=>{t.consume(a,e)}))}return s.onLoad.toPromise().then(()=>{if(!this.config.onlyLoad)return;const n=o.yDoc.getMap("RootComponent");if(!n.has("state"))return new Promise(a=>{const i=()=>{n.has("state")?a():this.timer=setTimeout(i,1e3)};this.timer=setTimeout(i,1e3)})})}onDestroy(e){this.subscription.unsubscribe(),e.get(exports.Collaborate).destroy(),e.get(d.History).destroy(),e.get(b).onDestroy(),clearTimeout(this.timer)}}class q{constructor(e){this.config=e}config;subscription=new f.Subscription;providers=[exports.Collaborate,exports.MultipleDocCollabHistory,{provide:d.History,useExisting:exports.MultipleDocCollabHistory},{provide:b,useFactory:e=>this.config.createConnector(e.yDoc),deps:[exports.Collaborate]},{provide:v,useFactory:()=>this.config.subModelLoader}];timer=null;setup(e){const t=e.get(L,null),s=e.get(b),o=e.get(exports.Collaborate);if(t){const n=e.get(d.Selection);s.setLocalStateField("message",t.get(e)),this.subscription.add(t.onSync.subscribe(()=>{s.setLocalStateField("message",t.get(e))}),n.onChange.subscribe(()=>{s.setLocalStateField("message",t.get(e))}),s.onStateChange.subscribe(a=>{t.consume(a,e)}))}return s.onLoad.toPromise().then(()=>{if(!this.config.onlyLoad)return;const n=o.yDoc.getMap("RootComponent");if(!n.has("state"))return new Promise(a=>{const i=()=>{n.has("state")?a():this.timer=setTimeout(i,1e3)};this.timer=setTimeout(i,1e3)})})}onDestroy(e){this.subscription.unsubscribe(),e.get(exports.Collaborate).destroy(),e.get(d.History).destroy(),e.get(b).onDestroy(),clearTimeout(this.timer)}}exports.CollaborateModule=$;exports.CustomUndoManagerConfig=A;exports.HocuspocusConnector=H;exports.MessageBus=L;exports.MultipleDocumentCollaborateModule=q;exports.SubModelLoader=v;exports.SyncConnector=b;exports.YWebsocketConnector=Y;
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const core$1 = require("@viewfly/core");
4
+ const core = require("@textbus/core");
5
+ const stream = require("@tanbo/stream");
6
+ const yjs = require("yjs");
7
+ const provider = require("@hocuspocus/provider");
8
+ const yWebsocket = require("y-websocket");
9
+ var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
10
+ var __decorateClass$3 = (decorators, target, key, kind) => {
11
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
12
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
13
+ if (decorator = decorators[i])
14
+ result = decorator(result) || result;
15
+ return result;
16
+ };
17
+ var __decorateParam$1 = (index, decorator) => (target, key) => decorator(target, key, index);
18
+ class CustomUndoManagerConfig {
19
+ }
20
+ const collabHistoryErrorFn = core.makeError("CollabHistory");
21
+ exports.CollabHistory = class CollabHistory {
22
+ constructor(rootComponentRef, collaborate, scheduler, stackSize, undoManagerConfig) {
23
+ this.rootComponentRef = rootComponentRef;
24
+ this.collaborate = collaborate;
25
+ this.scheduler = scheduler;
26
+ this.stackSize = stackSize;
27
+ this.undoManagerConfig = undoManagerConfig;
28
+ this.onBack = this.backEvent.asObservable();
29
+ this.onForward = this.forwardEvent.asObservable();
30
+ this.onChange = this.changeEvent.asObservable();
31
+ this.onPush = this.pushEvent.asObservable();
32
+ }
33
+ rootComponentRef;
34
+ collaborate;
35
+ scheduler;
36
+ stackSize;
37
+ undoManagerConfig;
38
+ onBack;
39
+ onForward;
40
+ onChange;
41
+ onPush;
42
+ get canBack() {
43
+ return this.manager?.canUndo() || false;
44
+ }
45
+ get canForward() {
46
+ return this.manager?.canRedo() || false;
47
+ }
48
+ manager = null;
49
+ historyItems = [];
50
+ index = 0;
51
+ subscriptions = [];
52
+ backEvent = new stream.Subject();
53
+ forwardEvent = new stream.Subject();
54
+ changeEvent = new stream.Subject();
55
+ pushEvent = new stream.Subject();
56
+ listen() {
57
+ const root = this.collaborate.yDoc.getMap("RootComponent");
58
+ const rootComponent = this.rootComponentRef.component;
59
+ this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
60
+ const undoManagerConfig = this.undoManagerConfig || {};
61
+ const manager = new yjs.UndoManager(root, {
62
+ trackedOrigins: /* @__PURE__ */ new Set([this.collaborate.yDoc]),
63
+ captureTransaction(arg) {
64
+ if (undoManagerConfig.captureTransaction) {
65
+ return undoManagerConfig.captureTransaction(arg);
66
+ }
67
+ return true;
68
+ },
69
+ deleteFilter(item) {
70
+ if (undoManagerConfig.deleteFilter) {
71
+ return undoManagerConfig.deleteFilter(item);
72
+ }
73
+ return true;
74
+ }
75
+ });
76
+ this.manager = manager;
77
+ let beforePosition = null;
78
+ this.subscriptions.push(
79
+ this.scheduler.onLocalChangeBefore.subscribe(() => {
80
+ beforePosition = this.collaborate.getRelativeCursorLocation();
81
+ }),
82
+ this.collaborate.onAddSubModel.subscribe(() => {
83
+ throw collabHistoryErrorFn("single document does not support submodels.");
84
+ })
85
+ );
86
+ manager.on("stack-item-added", (event) => {
87
+ if (event.type === "undo") {
88
+ if (event.origin === manager) {
89
+ this.index++;
90
+ } else {
91
+ this.historyItems.length = this.index;
92
+ this.historyItems.push({
93
+ before: beforePosition,
94
+ after: this.collaborate.getRelativeCursorLocation()
95
+ });
96
+ this.index++;
97
+ }
98
+ } else {
99
+ this.index--;
100
+ }
101
+ if (manager.undoStack.length > this.stackSize) {
102
+ this.historyItems.shift();
103
+ manager.undoStack.shift();
104
+ }
105
+ if (event.origin === this.collaborate.yDoc) {
106
+ this.pushEvent.next();
107
+ }
108
+ this.changeEvent.next();
109
+ });
110
+ manager.on("stack-item-popped", (ev) => {
111
+ const index = ev.type === "undo" ? this.index : this.index - 1;
112
+ const position = this.historyItems[index] || null;
113
+ const p = ev.type === "undo" ? position?.before : position?.after;
114
+ this.collaborate.restoreCursorPosition(p);
115
+ });
116
+ }
117
+ back() {
118
+ if (this.canBack) {
119
+ this.manager?.undo();
120
+ this.backEvent.next();
121
+ }
122
+ }
123
+ forward() {
124
+ if (this.canForward) {
125
+ this.manager?.redo();
126
+ this.forwardEvent.next();
127
+ }
128
+ }
129
+ clear() {
130
+ const last = this.historyItems.pop();
131
+ this.historyItems = last ? [last] : [];
132
+ this.index = last ? 1 : 0;
133
+ this.manager?.clear();
134
+ this.changeEvent.next();
135
+ }
136
+ destroy() {
137
+ this.index = 0;
138
+ this.historyItems = [];
139
+ this.subscriptions.forEach((i) => i.unsubscribe());
140
+ if (this.manager) {
141
+ this.manager.destroy();
142
+ this.manager.captureTransaction = () => true;
143
+ this.manager.deleteFilter = () => true;
144
+ this.manager.trackedOrigins = /* @__PURE__ */ new Set([null]);
145
+ }
146
+ this.manager = null;
147
+ }
148
+ };
149
+ exports.CollabHistory = __decorateClass$3([
150
+ core$1.Injectable(),
151
+ __decorateParam$1(3, core$1.Inject(core.HISTORY_STACK_SIZE)),
152
+ __decorateParam$1(4, core$1.Optional())
153
+ ], exports.CollabHistory);
154
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
155
+ var __decorateClass$2 = (decorators, target, key, kind) => {
156
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
157
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
158
+ if (decorator = decorators[i])
159
+ result = decorator(result) || result;
160
+ return result;
161
+ };
162
+ const collaborateErrorFn = core.makeError("Collaborate");
163
+ class SlotMap {
164
+ slotAndYTextMap = /* @__PURE__ */ new WeakMap();
165
+ yTextAndSlotMap = /* @__PURE__ */ new WeakMap();
166
+ set(key, value) {
167
+ if (key instanceof core.Slot) {
168
+ this.slotAndYTextMap.set(key, value);
169
+ this.yTextAndSlotMap.set(value, key);
170
+ } else {
171
+ this.slotAndYTextMap.set(value, key);
172
+ this.yTextAndSlotMap.set(key, value);
173
+ }
174
+ }
175
+ get(key) {
176
+ if (key instanceof core.Slot) {
177
+ return this.slotAndYTextMap.get(key) || null;
178
+ }
179
+ return this.yTextAndSlotMap.get(key) || null;
180
+ }
181
+ delete(key) {
182
+ if (key instanceof core.Slot) {
183
+ const v = this.slotAndYTextMap.get(key);
184
+ this.slotAndYTextMap.delete(key);
185
+ if (v) {
186
+ this.yTextAndSlotMap.delete(v);
187
+ }
188
+ } else {
189
+ const v = this.yTextAndSlotMap.get(key);
190
+ this.yTextAndSlotMap.delete(key);
191
+ if (v) {
192
+ this.slotAndYTextMap.delete(v);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ exports.Collaborate = class Collaborate {
198
+ constructor(scheduler, registry, selection, subModelLoader) {
199
+ this.scheduler = scheduler;
200
+ this.registry = registry;
201
+ this.selection = selection;
202
+ this.subModelLoader = subModelLoader;
203
+ this.onAddSubModel = this.addSubModelEvent.asObservable();
204
+ }
205
+ scheduler;
206
+ registry;
207
+ selection;
208
+ subModelLoader;
209
+ yDoc = new yjs.Doc();
210
+ slotMap = new SlotMap();
211
+ onAddSubModel;
212
+ subscriptions = [];
213
+ updateFromRemote = false;
214
+ addSubModelEvent = new stream.Subject();
215
+ updateRemoteActions = /* @__PURE__ */ new WeakMap();
216
+ noRecord = {};
217
+ syncRootComponent(yDoc, sharedComponent, localComponent) {
218
+ this.initSyncEvent(yDoc);
219
+ this.syncComponent(yDoc, sharedComponent, localComponent);
220
+ }
221
+ syncRootSlot(yDoc, sharedSlot, localSlot) {
222
+ if (sharedSlot.length) {
223
+ localSlot.retain(0);
224
+ localSlot.delete(localSlot.length);
225
+ localSlot.cleanAttributes();
226
+ localSlot.cleanFormats();
227
+ this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
228
+ } else {
229
+ yDoc.transact(() => {
230
+ this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
231
+ });
232
+ }
233
+ this.initSyncEvent(yDoc);
234
+ this.syncSlot(sharedSlot, localSlot);
235
+ }
236
+ getAbstractSelection(position) {
237
+ const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
238
+ const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
239
+ if (anchorPosition && focusPosition) {
240
+ const focusSlot = this.slotMap.get(focusPosition.type);
241
+ const anchorSlot = this.slotMap.get(anchorPosition.type);
242
+ if (focusSlot && anchorSlot) {
243
+ return {
244
+ anchorSlot,
245
+ anchorOffset: anchorPosition.index,
246
+ focusSlot,
247
+ focusOffset: focusPosition.index
248
+ };
249
+ }
250
+ }
251
+ return null;
252
+ }
253
+ getRelativeCursorLocation() {
254
+ const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
255
+ if (anchorSlot) {
256
+ const anchorYText = this.slotMap.get(anchorSlot);
257
+ if (anchorYText) {
258
+ const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
259
+ if (focusSlot) {
260
+ const focusYText = this.slotMap.get(focusSlot);
261
+ if (focusYText) {
262
+ const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
263
+ return {
264
+ focus: {
265
+ doc: focusYText.doc,
266
+ position: focusPosition
267
+ },
268
+ anchor: {
269
+ doc: anchorYText.doc,
270
+ position: anchorPosition
271
+ }
272
+ };
273
+ }
274
+ }
275
+ }
276
+ }
277
+ return null;
278
+ }
279
+ restoreCursorPosition(position) {
280
+ if (!position) {
281
+ this.selection.unSelect();
282
+ return;
283
+ }
284
+ const selection = this.getAbstractSelection(position);
285
+ if (selection) {
286
+ this.selection.setBaseAndExtent(
287
+ selection.anchorSlot,
288
+ selection.anchorOffset,
289
+ selection.focusSlot,
290
+ selection.focusOffset
291
+ );
292
+ }
293
+ }
294
+ initSyncEvent(yDoc) {
295
+ this.subscriptions.push(
296
+ this.scheduler.onDocChanged.pipe(
297
+ stream.map((item) => {
298
+ return item.filter((i) => {
299
+ return i.from !== core.ChangeOrigin.Remote;
300
+ });
301
+ }),
302
+ stream.filter((item) => {
303
+ return item.length;
304
+ })
305
+ ).subscribe(() => {
306
+ const updates = [];
307
+ let update = null;
308
+ const updateRemoteActions = this.updateRemoteActions.get(yDoc) || [];
309
+ for (const item of updateRemoteActions) {
310
+ if (!update) {
311
+ update = {
312
+ record: item.record,
313
+ actions: []
314
+ };
315
+ updates.push(update);
316
+ }
317
+ if (update.record === item.record) {
318
+ update.actions.push(item.action);
319
+ } else {
320
+ update = {
321
+ record: item.record,
322
+ actions: [item.action]
323
+ };
324
+ updates.push(update);
325
+ }
326
+ }
327
+ this.updateRemoteActions.delete(yDoc);
328
+ for (const item of updates) {
329
+ yDoc.transact(() => {
330
+ item.actions.forEach((fn) => {
331
+ fn();
332
+ });
333
+ }, item.record ? yDoc : this.noRecord);
334
+ }
335
+ })
336
+ );
337
+ }
338
+ syncComponent(yDoc, sharedComponent, localComponent) {
339
+ let state = sharedComponent.get("state");
340
+ if (!state) {
341
+ state = new yjs.Map();
342
+ this.syncLocalMapToSharedMap(localComponent.state, state);
343
+ yDoc.transact(() => {
344
+ sharedComponent.set("state", state);
345
+ });
346
+ } else {
347
+ Object.keys(localComponent.state).forEach((key) => {
348
+ Reflect.deleteProperty(localComponent.state, key);
349
+ });
350
+ this.syncSharedMapToLocalMap(state, localComponent.state);
351
+ }
352
+ }
353
+ syncSlot(sharedSlot, localSlot) {
354
+ const syncRemote = (ev, tr) => {
355
+ this.runRemoteUpdate(tr, () => {
356
+ localSlot.retain(0);
357
+ ev.keysChanged.forEach((key) => {
358
+ const change = ev.keys.get(key);
359
+ if (!change) {
360
+ return;
361
+ }
362
+ const updateType = change.action;
363
+ if (updateType === "update" || updateType === "add") {
364
+ const attribute = this.registry.getAttribute(key);
365
+ if (attribute) {
366
+ localSlot.setAttribute(attribute, sharedSlot.getAttribute(key));
367
+ }
368
+ } else if (updateType === "delete") {
369
+ const attribute = this.registry.getAttribute(key);
370
+ if (attribute) {
371
+ localSlot.removeAttribute(attribute);
372
+ }
373
+ }
374
+ });
375
+ ev.delta.forEach((action) => {
376
+ if (Reflect.has(action, "retain")) {
377
+ if (action.attributes) {
378
+ const formats = remoteFormatsToLocal(this.registry, action.attributes);
379
+ if (formats.length) {
380
+ localSlot.retain(action.retain, formats);
381
+ }
382
+ }
383
+ localSlot.retain(localSlot.index + action.retain);
384
+ } else if (action.insert) {
385
+ const index = localSlot.index;
386
+ let length = 1;
387
+ if (typeof action.insert === "string") {
388
+ length = action.insert.length;
389
+ localSlot.insert(action.insert, remoteFormatsToLocal(this.registry, action.attributes));
390
+ } else {
391
+ const sharedComponent = action.insert;
392
+ const component = this.createLocalComponentBySharedComponent(sharedComponent);
393
+ localSlot.insert(component);
394
+ }
395
+ if (this.selection.isSelected && !(tr.origin instanceof yjs.UndoManager)) {
396
+ if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset > index) {
397
+ this.selection.setAnchor(localSlot, this.selection.anchorOffset + length);
398
+ }
399
+ if (localSlot === this.selection.focusSlot && this.selection.focusOffset > index) {
400
+ this.selection.setFocus(localSlot, this.selection.focusOffset + length);
401
+ }
402
+ }
403
+ } else if (action.delete) {
404
+ const index = localSlot.index;
405
+ localSlot.delete(action.delete);
406
+ if (this.selection.isSelected && !(tr.origin instanceof yjs.UndoManager)) {
407
+ if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset >= index) {
408
+ this.selection.setAnchor(localSlot, this.selection.startOffset - action.delete);
409
+ }
410
+ if (localSlot === this.selection.focusSlot && this.selection.focusOffset >= index) {
411
+ this.selection.setFocus(localSlot, this.selection.focusOffset - action.delete);
412
+ }
413
+ }
414
+ }
415
+ });
416
+ });
417
+ };
418
+ sharedSlot.observe(syncRemote);
419
+ const sub = localSlot.onContentChange.subscribe((actions) => {
420
+ this.runLocalUpdate(sharedSlot.doc, true, () => {
421
+ let offset = 0;
422
+ let length = 0;
423
+ for (const action of actions) {
424
+ if (action.type === "retain") {
425
+ const formats = action.formats;
426
+ if (formats) {
427
+ const keys = Object.keys(formats);
428
+ let length2 = keys.length;
429
+ keys.forEach((key) => {
430
+ const formatter = this.registry.getFormatter(key);
431
+ if (!formatter) {
432
+ length2--;
433
+ Reflect.deleteProperty(formats, key);
434
+ }
435
+ });
436
+ if (length2) {
437
+ sharedSlot.format(offset, action.offset, formats);
438
+ }
439
+ } else {
440
+ offset = action.offset;
441
+ }
442
+ } else if (action.type === "contentInsert") {
443
+ const delta = sharedSlot.toDelta();
444
+ const isEmpty = delta.length === 1 && delta[0].insert === core.Slot.emptyPlaceholder;
445
+ if (typeof action.content === "string") {
446
+ length = action.content.length;
447
+ sharedSlot.insert(offset, action.content, action.formats || {});
448
+ } else {
449
+ length = 1;
450
+ const sharedComponent = this.createSharedComponentByLocalComponent(action.ref);
451
+ sharedSlot.insertEmbed(offset, sharedComponent, action.formats || {});
452
+ }
453
+ if (isEmpty && offset === 0) {
454
+ sharedSlot.delete(sharedSlot.length - 1, 1);
455
+ }
456
+ offset += length;
457
+ } else if (action.type === "delete") {
458
+ const delta = sharedSlot.toDelta();
459
+ if (sharedSlot.length) {
460
+ sharedSlot.delete(offset, action.count);
461
+ }
462
+ if (sharedSlot.length === 0) {
463
+ sharedSlot.insert(0, "\n", delta[0]?.attributes);
464
+ }
465
+ } else if (action.type === "attrSet") {
466
+ sharedSlot.setAttribute(action.name, action.value);
467
+ } else if (action.type === "attrDelete") {
468
+ sharedSlot.removeAttribute(action.name);
469
+ }
470
+ }
471
+ });
472
+ });
473
+ this.slotMap.set(localSlot, sharedSlot);
474
+ localSlot.__changeMarker__.addDetachCallback(() => {
475
+ this.slotMap.delete(localSlot);
476
+ sharedSlot.unobserve(syncRemote);
477
+ sub.unsubscribe();
478
+ });
479
+ }
480
+ destroy() {
481
+ this.subscriptions.forEach((i) => i.unsubscribe());
482
+ this.subscriptions = [];
483
+ }
484
+ syncSharedMapToLocalMap(sharedMap, localMap) {
485
+ sharedMap.forEach((value, key) => {
486
+ localMap[key] = this.createLocalModelBySharedByModel(value);
487
+ });
488
+ this.syncObject(sharedMap, localMap);
489
+ }
490
+ createLocalMapBySharedMap(sharedMap) {
491
+ const localMap = core.observe({});
492
+ this.syncSharedMapToLocalMap(sharedMap, localMap);
493
+ return localMap;
494
+ }
495
+ createLocalArrayBySharedArray(sharedArray) {
496
+ const localArray = core.observe([]);
497
+ localArray.push(...sharedArray.map((item) => this.createLocalModelBySharedByModel(item)));
498
+ this.syncArray(sharedArray, localArray);
499
+ return localArray;
500
+ }
501
+ syncLocalMapToSharedMap(localMap, sharedMap) {
502
+ Object.entries(localMap).forEach(([key, value]) => {
503
+ sharedMap.set(key, this.createSharedModelByLocalModel(value));
504
+ });
505
+ this.syncObject(sharedMap, localMap);
506
+ }
507
+ createSharedMapByLocalMap(localMap) {
508
+ const sharedMap = new yjs.Map();
509
+ this.syncLocalMapToSharedMap(localMap, sharedMap);
510
+ return sharedMap;
511
+ }
512
+ createSharedArrayByLocalArray(localArray) {
513
+ const sharedArray = new yjs.Array();
514
+ localArray.forEach((value) => {
515
+ sharedArray.push([this.createSharedModelByLocalModel(value)]);
516
+ });
517
+ this.syncArray(sharedArray, localArray);
518
+ return sharedArray;
519
+ }
520
+ createSharedSlotByLocalSlot(localSlot) {
521
+ const sharedSlot = new yjs.Text();
522
+ const isAsyncSlot = localSlot instanceof core.AsyncSlot;
523
+ sharedSlot.setAttribute("schema", [...localSlot.schema]);
524
+ sharedSlot.setAttribute("type", isAsyncSlot ? "async" : "sync");
525
+ if (isAsyncSlot) {
526
+ let isDestroyed = false;
527
+ const sharedMetadata = this.createSharedMapByLocalMap(localSlot.metadata);
528
+ sharedSlot.setAttribute("metadata", sharedMetadata);
529
+ this.subModelLoader.createSubModelBySlot(localSlot).then((subDocument) => {
530
+ if (isDestroyed) {
531
+ return;
532
+ }
533
+ const content = subDocument.getText("content");
534
+ const state = subDocument.getMap("state");
535
+ this.syncLocalMapToSharedMap(localSlot.state, state);
536
+ this.initSharedSlotByLocalSlot(content, localSlot);
537
+ this.syncSlot(content, localSlot);
538
+ this.addSubModelEvent.next({
539
+ yDoc: subDocument,
540
+ yType: content
541
+ });
542
+ this.initSyncEvent(subDocument);
543
+ localSlot.loader.markAsLoaded();
544
+ });
545
+ localSlot.__changeMarker__.addDetachCallback(() => {
546
+ isDestroyed = true;
547
+ });
548
+ return sharedSlot;
549
+ }
550
+ const sharedSlotState = new yjs.Map();
551
+ this.syncLocalMapToSharedMap(localSlot.state, sharedSlotState);
552
+ sharedSlot.setAttribute("state", sharedSlotState);
553
+ const sharedContent = new yjs.Text();
554
+ this.initSharedSlotByLocalSlot(sharedContent, localSlot);
555
+ sharedSlot.insertEmbed(0, sharedContent);
556
+ this.syncSlot(sharedContent, localSlot);
557
+ return sharedSlot;
558
+ }
559
+ initSharedSlotByLocalSlot(sharedContent, localSlot) {
560
+ let offset = 0;
561
+ localSlot.toDelta().forEach((i) => {
562
+ let formats = {};
563
+ if (i.formats) {
564
+ i.formats.forEach((item) => {
565
+ formats[item[0].name] = item[1];
566
+ });
567
+ } else {
568
+ formats = null;
569
+ }
570
+ if (typeof i.insert === "string") {
571
+ sharedContent.insert(offset, i.insert, formats);
572
+ } else {
573
+ const sharedComponent = this.createSharedComponentByLocalComponent(i.insert);
574
+ sharedContent.insertEmbed(offset, sharedComponent, formats);
575
+ }
576
+ offset += i.insert.length;
577
+ });
578
+ localSlot.getAttributes().forEach((item) => {
579
+ sharedContent.setAttribute(item[0].name, item[1]);
580
+ });
581
+ }
582
+ createLocalSlotBySharedSlot(sharedSlot) {
583
+ const type = sharedSlot.getAttribute("type");
584
+ const schema = sharedSlot.getAttribute("schema");
585
+ if (type === "async") {
586
+ const metadata = sharedSlot.getAttribute("metadata");
587
+ const slot = new core.AsyncSlot(schema || [], {}, {});
588
+ this.syncSharedMapToLocalMap(metadata, slot.metadata);
589
+ const loadedSubDocument = this.subModelLoader.getLoadedModelBySlot(slot);
590
+ if (loadedSubDocument) {
591
+ const subContent = loadedSubDocument.getText("content");
592
+ const data = loadedSubDocument.getMap("state");
593
+ this.syncSharedMapToLocalMap(data, slot.state);
594
+ this.syncRootSlot(loadedSubDocument, subContent, slot);
595
+ this.addSubModelEvent.next({
596
+ yDoc: loadedSubDocument,
597
+ yType: subContent
598
+ });
599
+ slot.loader.markAsLoaded();
600
+ return slot;
601
+ }
602
+ let isDestroyed = false;
603
+ slot.loader.onRequestLoad.toPromise().then(() => {
604
+ return this.subModelLoader.loadSubModelBySlot(slot);
605
+ }).then((subDocument) => {
606
+ if (isDestroyed) {
607
+ return;
608
+ }
609
+ const subContent = subDocument.getText("content");
610
+ const state = subDocument.getMap("state");
611
+ this.syncSharedMapToLocalMap(state, slot.state);
612
+ this.syncRootSlot(subDocument, subContent, slot);
613
+ this.addSubModelEvent.next({
614
+ yDoc: subDocument,
615
+ yType: subContent
616
+ });
617
+ slot.loader.markAsLoaded();
618
+ });
619
+ slot.__changeMarker__.addDetachCallback(() => {
620
+ isDestroyed = true;
621
+ });
622
+ return slot;
623
+ }
624
+ const contentDelta = sharedSlot.toDelta();
625
+ const content = contentDelta[0]?.insert;
626
+ if (!(content instanceof yjs.Text)) {
627
+ throw collaborateErrorFn("shared slot content type is not `YText`.");
628
+ }
629
+ const localSlot = new core.Slot(schema || [], {});
630
+ const sharedSlotState = sharedSlot.getAttribute("state");
631
+ this.syncSharedMapToLocalMap(sharedSlotState, localSlot.state);
632
+ this.initLocalSlotBySharedSlot(content, localSlot);
633
+ this.syncSlot(content, localSlot);
634
+ return localSlot;
635
+ }
636
+ initLocalSlotBySharedSlot(content, localSlot) {
637
+ const delta = content.toDelta();
638
+ const attrs = content.getAttributes();
639
+ Object.keys(attrs).forEach((key) => {
640
+ const attribute = this.registry.getAttribute(key);
641
+ if (attribute) {
642
+ localSlot.setAttribute(attribute, attrs[key]);
643
+ }
644
+ });
645
+ for (const action of delta) {
646
+ if (action.insert) {
647
+ if (typeof action.insert === "string") {
648
+ const formats = remoteFormatsToLocal(this.registry, action.attributes);
649
+ localSlot.insert(action.insert, formats);
650
+ } else {
651
+ const sharedComponent = action.insert;
652
+ const component = this.createLocalComponentBySharedComponent(sharedComponent);
653
+ localSlot.insert(component, remoteFormatsToLocal(this.registry, action.attributes));
654
+ }
655
+ } else {
656
+ throw collaborateErrorFn("unexpected delta action.");
657
+ }
658
+ }
659
+ }
660
+ createSharedModelByLocalModel(localModel) {
661
+ if (localModel instanceof core.Slot) {
662
+ return this.createSharedSlotByLocalSlot(localModel);
663
+ }
664
+ if (Array.isArray(localModel)) {
665
+ return this.createSharedArrayByLocalArray(localModel);
666
+ }
667
+ if (typeof localModel === "object" && localModel !== null) {
668
+ return this.createSharedMapByLocalMap(localModel);
669
+ }
670
+ return localModel;
671
+ }
672
+ createLocalModelBySharedByModel(sharedModel) {
673
+ if (sharedModel instanceof yjs.Map) {
674
+ return this.createLocalMapBySharedMap(sharedModel);
675
+ }
676
+ if (sharedModel instanceof yjs.Array) {
677
+ return this.createLocalArrayBySharedArray(sharedModel);
678
+ }
679
+ if (sharedModel instanceof yjs.Text) {
680
+ return this.createLocalSlotBySharedSlot(sharedModel);
681
+ }
682
+ return sharedModel;
683
+ }
684
+ createSharedComponentByLocalComponent(component) {
685
+ const sharedComponent = new yjs.Map();
686
+ sharedComponent.set("name", component.name);
687
+ if (component instanceof core.AsyncComponent) {
688
+ sharedComponent.set("type", "async");
689
+ const sharedMetadata = this.createSharedMapByLocalMap(component.metadata);
690
+ sharedComponent.set("metadata", sharedMetadata);
691
+ const state = component.state;
692
+ let isDestroyed = false;
693
+ state.__changeMarker__.addDetachCallback(() => {
694
+ isDestroyed = true;
695
+ });
696
+ this.subModelLoader.createSubModelByComponent(component).then((subDocument) => {
697
+ if (isDestroyed) {
698
+ return;
699
+ }
700
+ const state2 = subDocument.getMap("state");
701
+ this.syncComponent(subDocument, state2, component);
702
+ this.addSubModelEvent.next({
703
+ yType: state2,
704
+ yDoc: subDocument
705
+ });
706
+ this.initSyncEvent(subDocument);
707
+ component.loader.markAsLoaded();
708
+ });
709
+ return sharedComponent;
710
+ }
711
+ const sharedState = this.createSharedMapByLocalMap(component.state);
712
+ sharedComponent.set("state", sharedState);
713
+ sharedComponent.set("type", "sync");
714
+ return sharedComponent;
715
+ }
716
+ createLocalComponentBySharedComponent(yMap) {
717
+ const componentName = yMap.get("name");
718
+ const type = yMap.get("type");
719
+ let instance;
720
+ if (type === "async") {
721
+ instance = this.registry.createComponentByData(componentName, {}, {});
722
+ if (instance instanceof core.AsyncComponent) {
723
+ const sharedMetadata = yMap.get("metadata");
724
+ this.syncSharedMapToLocalMap(sharedMetadata, instance.metadata);
725
+ const loadedSubDocument = this.subModelLoader.getLoadedModelByComponent(instance);
726
+ if (loadedSubDocument) {
727
+ const state2 = loadedSubDocument.getMap("state");
728
+ this.syncComponent(loadedSubDocument, state2, instance);
729
+ this.addSubModelEvent.next({
730
+ yType: state2,
731
+ yDoc: loadedSubDocument
732
+ });
733
+ instance.loader.markAsLoaded();
734
+ return instance;
735
+ }
736
+ const state = instance.state;
737
+ let isDestroyed = false;
738
+ instance.loader.onRequestLoad.toPromise().then(() => {
739
+ return this.subModelLoader.loadSubModelByComponent(instance);
740
+ }).then((subDocument) => {
741
+ if (isDestroyed) {
742
+ return;
743
+ }
744
+ const state2 = subDocument.getMap("state");
745
+ this.syncComponent(subDocument, state2, instance);
746
+ this.addSubModelEvent.next({
747
+ yType: state2,
748
+ yDoc: subDocument
749
+ });
750
+ instance.loader.markAsLoaded();
751
+ });
752
+ state.__changeMarker__.addDetachCallback(() => {
753
+ isDestroyed = true;
754
+ });
755
+ } else if (instance instanceof core.Component) {
756
+ throw collaborateErrorFn(`component name \`${componentName}\` is not a async component.`);
757
+ }
758
+ } else {
759
+ const sharedState = yMap.get("state");
760
+ const state = this.createLocalMapBySharedMap(sharedState);
761
+ instance = this.registry.createComponentByData(componentName, state);
762
+ }
763
+ if (instance) {
764
+ return instance;
765
+ }
766
+ throw collaborateErrorFn(`cannot find component factory \`${componentName}\`.`);
767
+ }
768
+ /**
769
+ * 双向同步数组
770
+ * @param sharedArray
771
+ * @param localArray
772
+ * @private
773
+ */
774
+ syncArray(sharedArray, localArray) {
775
+ function logError(type) {
776
+ console.error(collaborateErrorFn(`${type} error, length exceeded, path in ${localArray.__changeMarker__.getPaths().join("/")}`));
777
+ }
778
+ const sub = localArray.__changeMarker__.onSelfChange.subscribe((actions) => {
779
+ this.runLocalUpdate(sharedArray.doc, !localArray.__changeMarker__.irrevocableUpdate, () => {
780
+ let index = 0;
781
+ for (const action of actions) {
782
+ switch (action.type) {
783
+ case "retain":
784
+ index = action.offset;
785
+ break;
786
+ case "insert":
787
+ {
788
+ const ref = action.ref;
789
+ if (!Array.isArray(ref)) {
790
+ throw collaborateErrorFn("The insertion action must have a reference value.");
791
+ }
792
+ const data = ref.map((item) => {
793
+ return this.createSharedModelByLocalModel(item);
794
+ });
795
+ if (index <= sharedArray.length) {
796
+ sharedArray.insert(index, data);
797
+ } else {
798
+ sharedArray.insert(sharedArray.length, data);
799
+ logError("insert");
800
+ }
801
+ }
802
+ break;
803
+ case "delete":
804
+ if (action.count <= 0) {
805
+ break;
806
+ }
807
+ if (index < sharedArray.length) {
808
+ sharedArray.delete(index, action.count);
809
+ } else {
810
+ logError("delete");
811
+ }
812
+ break;
813
+ case "setIndex":
814
+ if (action.index < sharedArray.length) {
815
+ sharedArray.delete(action.index, 1);
816
+ sharedArray.insert(action.index, [this.createSharedModelByLocalModel(action.ref)]);
817
+ } else {
818
+ sharedArray.insert(sharedArray.length, [this.createSharedModelByLocalModel(action.ref)]);
819
+ logError("setIndex");
820
+ }
821
+ break;
822
+ }
823
+ }
824
+ });
825
+ });
826
+ const syncRemote = (ev, tr) => {
827
+ this.runRemoteUpdate(tr, () => {
828
+ let index = 0;
829
+ ev.delta.forEach((action) => {
830
+ if (Reflect.has(action, "retain")) {
831
+ index += action.retain;
832
+ } else if (action.insert) {
833
+ const data = action.insert.map((item) => {
834
+ return this.createLocalModelBySharedByModel(item);
835
+ });
836
+ localArray.splice(index, 0, ...data);
837
+ index += data.length;
838
+ } else if (action.delete) {
839
+ localArray.splice(index, action.delete);
840
+ }
841
+ });
842
+ });
843
+ };
844
+ sharedArray.observe(syncRemote);
845
+ localArray.__changeMarker__.addDetachCallback(() => {
846
+ sub.unsubscribe();
847
+ sharedArray.unobserve(syncRemote);
848
+ });
849
+ }
850
+ /**
851
+ * 双向同步对象
852
+ * @param sharedObject
853
+ * @param localObject
854
+ * @private
855
+ */
856
+ syncObject(sharedObject, localObject) {
857
+ const syncRemote = (ev, tr) => {
858
+ this.runRemoteUpdate(tr, () => {
859
+ ev.changes.keys.forEach((item, key) => {
860
+ if (item.action === "add" || item.action === "update") {
861
+ const value = sharedObject.get(key);
862
+ localObject[key] = this.createLocalModelBySharedByModel(value);
863
+ } else {
864
+ Reflect.deleteProperty(localObject, key);
865
+ }
866
+ });
867
+ });
868
+ };
869
+ sharedObject.observe(syncRemote);
870
+ const sub = localObject.__changeMarker__.onSelfChange.subscribe((actions) => {
871
+ this.runLocalUpdate(sharedObject.doc, !localObject.__changeMarker__.irrevocableUpdate, () => {
872
+ for (const action of actions) {
873
+ switch (action.type) {
874
+ case "propSet":
875
+ {
876
+ const subModel = this.createSharedModelByLocalModel(action.ref);
877
+ sharedObject.set(action.key, subModel);
878
+ if (sharedObject.size === 0) {
879
+ console.error(collaborateErrorFn(`prop set error, key is ${action.key}`));
880
+ }
881
+ }
882
+ break;
883
+ case "propDelete":
884
+ sharedObject.delete(action.key);
885
+ break;
886
+ }
887
+ }
888
+ });
889
+ });
890
+ localObject.__changeMarker__.addDetachCallback(function() {
891
+ sharedObject.unobserve(syncRemote);
892
+ sub.unsubscribe();
893
+ });
894
+ }
895
+ runLocalUpdate(yDoc, record, fn) {
896
+ if (this.updateFromRemote || !yDoc) {
897
+ return;
898
+ }
899
+ let changeList = this.updateRemoteActions.get(yDoc);
900
+ if (!changeList) {
901
+ changeList = [];
902
+ this.updateRemoteActions.set(yDoc, changeList);
903
+ }
904
+ changeList.push({
905
+ record,
906
+ action: fn
907
+ });
908
+ }
909
+ runRemoteUpdate(tr, fn) {
910
+ if (tr.origin === tr.doc) {
911
+ return;
912
+ }
913
+ this.updateFromRemote = true;
914
+ if (tr.origin instanceof yjs.UndoManager) {
915
+ this.scheduler.historyApplyTransact(fn);
916
+ } else {
917
+ this.scheduler.remoteUpdateTransact(fn);
918
+ }
919
+ this.updateFromRemote = false;
920
+ }
921
+ };
922
+ exports.Collaborate = __decorateClass$2([
923
+ core$1.Injectable()
924
+ ], exports.Collaborate);
925
+ function remoteFormatsToLocal(registry, attrs) {
926
+ const formats = [];
927
+ if (attrs) {
928
+ Object.keys(attrs).forEach((key) => {
929
+ const formatter = registry.getFormatter(key);
930
+ if (formatter) {
931
+ formats.push([formatter, attrs[key]]);
932
+ }
933
+ });
934
+ }
935
+ return formats;
936
+ }
937
+ class MessageBus {
938
+ onSync;
939
+ syncEvent = new stream.Subject();
940
+ constructor() {
941
+ this.onSync = this.syncEvent.asObservable();
942
+ }
943
+ /**
944
+ * 立即同步消息
945
+ */
946
+ sync() {
947
+ this.syncEvent.next();
948
+ }
949
+ }
950
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
951
+ var __decorateClass$1 = (decorators, target, key, kind) => {
952
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
953
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
954
+ if (decorator = decorators[i])
955
+ result = decorator(result) || result;
956
+ return result;
957
+ };
958
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
959
+ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
960
+ constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
961
+ this.collaborate = collaborate;
962
+ this.scheduler = scheduler;
963
+ this.rootComponentRef = rootComponentRef;
964
+ this.stackSize = stackSize;
965
+ this.undoManagerConfig = undoManagerConfig;
966
+ this.onChange = this.changeEvent.asObservable();
967
+ this.onBack = this.backEvent.asObservable();
968
+ this.onForward = this.forwardEvent.asObservable();
969
+ this.onPush = this.pushEvent.asObservable();
970
+ }
971
+ collaborate;
972
+ scheduler;
973
+ rootComponentRef;
974
+ stackSize;
975
+ undoManagerConfig;
976
+ onChange;
977
+ onBack;
978
+ onForward;
979
+ onPush;
980
+ get canBack() {
981
+ return this.actionStack.length > 0 && this.index > 0;
982
+ }
983
+ get canForward() {
984
+ return this.actionStack.length > 0 && this.index < this.actionStack.length;
985
+ }
986
+ isListen = false;
987
+ changeEvent = new stream.Subject();
988
+ backEvent = new stream.Subject();
989
+ forwardEvent = new stream.Subject();
990
+ pushEvent = new stream.Subject();
991
+ actionStack = [];
992
+ index = 0;
993
+ stackItem = null;
994
+ timer = null;
995
+ beforePosition = null;
996
+ subscription = new stream.Subscription();
997
+ subDocs = /* @__PURE__ */ new Set();
998
+ listenerCaches = /* @__PURE__ */ new Set();
999
+ listen() {
1000
+ this.isListen = true;
1001
+ const root = this.collaborate.yDoc.getMap("RootComponent");
1002
+ const rootComponent = this.rootComponentRef.component;
1003
+ this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
1004
+ this.listenItem(root, this.collaborate.yDoc);
1005
+ this.subscription.add(
1006
+ this.collaborate.onAddSubModel.subscribe(({ yType, yDoc }) => {
1007
+ if (this.subDocs.has(yType)) {
1008
+ return;
1009
+ }
1010
+ this.subDocs.add(yType);
1011
+ if (this.isListen) {
1012
+ this.listenItem(yType, yDoc);
1013
+ }
1014
+ }),
1015
+ this.scheduler.onLocalChangeBefore.subscribe(() => {
1016
+ this.beforePosition = this.collaborate.getRelativeCursorLocation();
1017
+ })
1018
+ );
1019
+ }
1020
+ forward() {
1021
+ if (!this.canForward) {
1022
+ return;
1023
+ }
1024
+ clearTimeout(this.timer);
1025
+ const item = this.actionStack[this.index];
1026
+ if (item) {
1027
+ for (const i of item.undoManagers) {
1028
+ i.redo();
1029
+ }
1030
+ this.collaborate.restoreCursorPosition(item.after);
1031
+ }
1032
+ this.index++;
1033
+ this.forwardEvent.next();
1034
+ this.changeEvent.next();
1035
+ }
1036
+ back() {
1037
+ if (!this.canBack) {
1038
+ return;
1039
+ }
1040
+ clearTimeout(this.timer);
1041
+ let historyStackItem;
1042
+ if (this.stackItem) {
1043
+ historyStackItem = this.stackItem;
1044
+ this.stackItem = null;
1045
+ } else {
1046
+ this.index--;
1047
+ historyStackItem = this.actionStack[this.index];
1048
+ }
1049
+ let len = historyStackItem.undoManagers.length;
1050
+ while (len > 0) {
1051
+ len--;
1052
+ historyStackItem.undoManagers[len].undo();
1053
+ }
1054
+ if (historyStackItem) {
1055
+ const beforePosition = historyStackItem.before;
1056
+ this.collaborate.restoreCursorPosition(beforePosition);
1057
+ this.backEvent.next();
1058
+ this.changeEvent.next();
1059
+ }
1060
+ }
1061
+ clear() {
1062
+ this.actionStack = [];
1063
+ this.stackItem = null;
1064
+ this.index = 0;
1065
+ this.beforePosition = null;
1066
+ clearTimeout(this.timer);
1067
+ this.listenerCaches.forEach((undoManager) => {
1068
+ undoManager.clear();
1069
+ });
1070
+ this.changeEvent.next();
1071
+ }
1072
+ destroy() {
1073
+ this.clear();
1074
+ this.beforePosition = this.stackItem = null;
1075
+ this.subscription.unsubscribe();
1076
+ this.listenerCaches.forEach((undoManager) => {
1077
+ undoManager.destroy();
1078
+ });
1079
+ this.subDocs.clear();
1080
+ this.listenerCaches.clear();
1081
+ }
1082
+ listenItem(yType, yDoc) {
1083
+ const undoManagerConfig = this.undoManagerConfig || {};
1084
+ const undoManager = new yjs.UndoManager(yType, {
1085
+ trackedOrigins: /* @__PURE__ */ new Set([yDoc]),
1086
+ captureTimeout: 0,
1087
+ captureTransaction(arg) {
1088
+ if (undoManagerConfig.captureTransaction) {
1089
+ return undoManagerConfig.captureTransaction(arg);
1090
+ }
1091
+ return true;
1092
+ },
1093
+ deleteFilter(item) {
1094
+ if (undoManagerConfig.deleteFilter) {
1095
+ return undoManagerConfig.deleteFilter(item);
1096
+ }
1097
+ return true;
1098
+ }
1099
+ });
1100
+ undoManager.on("stack-item-added", (event) => {
1101
+ if (event.type === "undo" && !(event.origin instanceof yjs.UndoManager)) {
1102
+ if (this.index != this.actionStack.length) {
1103
+ const redoStack = this.actionStack.slice(this.index);
1104
+ redoStack.forEach((item) => {
1105
+ item.undoManagers.forEach((i) => {
1106
+ i.clear(false, true);
1107
+ });
1108
+ });
1109
+ this.actionStack.length = this.index;
1110
+ this.changeEvent.next();
1111
+ }
1112
+ if (this.stackItem === null) {
1113
+ this.stackItem = {
1114
+ before: this.beforePosition,
1115
+ after: null,
1116
+ undoManagers: []
1117
+ };
1118
+ this.timer = setTimeout(() => {
1119
+ if (this.actionStack.length >= this.stackSize) {
1120
+ this.actionStack.shift();
1121
+ } else {
1122
+ this.index++;
1123
+ }
1124
+ this.stackItem.after = this.beforePosition;
1125
+ this.actionStack.push(this.stackItem);
1126
+ this.stackItem = null;
1127
+ this.pushEvent.next();
1128
+ this.changeEvent.next();
1129
+ }, 500);
1130
+ }
1131
+ this.stackItem.undoManagers.push(undoManager);
1132
+ }
1133
+ });
1134
+ this.listenerCaches.add(undoManager);
1135
+ }
1136
+ };
1137
+ exports.MultipleDocCollabHistory = __decorateClass$1([
1138
+ core$1.Injectable(),
1139
+ __decorateParam(3, core$1.Inject(core.HISTORY_STACK_SIZE)),
1140
+ __decorateParam(4, core$1.Optional())
1141
+ ], exports.MultipleDocCollabHistory);
1142
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
1143
+ var __decorateClass = (decorators, target, key, kind) => {
1144
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
1145
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
1146
+ if (decorator = decorators[i])
1147
+ result = decorator(result) || result;
1148
+ return result;
1149
+ };
1150
+ const subModelLoaderErrorFn = core.makeError("subModelLoaderError");
1151
+ class SubModelLoader {
1152
+ }
1153
+ exports.NonSubModelLoader = class NonSubModelLoader extends SubModelLoader {
1154
+ createSubModelBySlot() {
1155
+ throw subModelLoaderErrorFn("single document does not support async slot.");
1156
+ }
1157
+ createSubModelByComponent() {
1158
+ throw subModelLoaderErrorFn("single document does not support async component.");
1159
+ }
1160
+ loadSubModelByComponent() {
1161
+ throw subModelLoaderErrorFn("single document does not support async component.");
1162
+ }
1163
+ loadSubModelBySlot() {
1164
+ throw subModelLoaderErrorFn("single document does not support async slot.");
1165
+ }
1166
+ getLoadedModelBySlot() {
1167
+ throw subModelLoaderErrorFn("single document does not support async slot.");
1168
+ }
1169
+ getLoadedModelByComponent() {
1170
+ throw subModelLoaderErrorFn("single document does not support async component.");
1171
+ }
1172
+ };
1173
+ exports.NonSubModelLoader = __decorateClass([
1174
+ core$1.Injectable()
1175
+ ], exports.NonSubModelLoader);
1176
+ class SyncConnector {
1177
+ /**
1178
+ * 当文档加载完成时触发的观察者
1179
+ */
1180
+ onLoad;
1181
+ /**
1182
+ * 当文档 awareness 状态变更时触发的观察者
1183
+ */
1184
+ onStateChange;
1185
+ loadEvent = new stream.Subject();
1186
+ stateChangeEvent = new stream.Subject();
1187
+ constructor() {
1188
+ this.onLoad = this.loadEvent.asObservable();
1189
+ this.onStateChange = this.stateChangeEvent.asObservable();
1190
+ }
1191
+ }
1192
+ class HocuspocusConnector extends SyncConnector {
1193
+ provide;
1194
+ constructor(config) {
1195
+ super();
1196
+ this.provide = new provider.HocuspocusProvider({
1197
+ ...config,
1198
+ onSynced: (data) => {
1199
+ config.onSynced?.(data);
1200
+ this.loadEvent.next();
1201
+ },
1202
+ onAwarenessUpdate: (data) => {
1203
+ config.onAwarenessUpdate?.(data);
1204
+ const states = data.states.map((state) => {
1205
+ return {
1206
+ clientId: state.clientId,
1207
+ message: state.message
1208
+ };
1209
+ });
1210
+ this.stateChangeEvent.next(states);
1211
+ }
1212
+ });
1213
+ }
1214
+ setLocalStateField(key, data) {
1215
+ this.provide.setAwarenessField(key, data);
1216
+ }
1217
+ onDestroy() {
1218
+ this.provide.disconnect();
1219
+ this.provide.destroy();
1220
+ }
1221
+ }
1222
+ class YWebsocketConnector extends SyncConnector {
1223
+ provide;
1224
+ onSync = (is) => {
1225
+ if (is) {
1226
+ this.loadEvent.next();
1227
+ }
1228
+ };
1229
+ onUpdate = () => {
1230
+ const syncStates = [];
1231
+ this.provide.awareness.getStates().forEach((state, id) => {
1232
+ syncStates.push({
1233
+ clientId: id,
1234
+ message: state.message
1235
+ });
1236
+ });
1237
+ this.stateChangeEvent.next(syncStates);
1238
+ };
1239
+ constructor(url, roomName, yDoc) {
1240
+ super();
1241
+ this.onLoad = this.loadEvent.asObservable();
1242
+ this.onStateChange = this.stateChangeEvent.asObservable();
1243
+ this.provide = new yWebsocket.WebsocketProvider(url, roomName, yDoc);
1244
+ this.provide.once("sync", this.onSync);
1245
+ this.provide.awareness.on("update", this.onUpdate);
1246
+ }
1247
+ setLocalStateField(key, data) {
1248
+ this.provide.awareness.setLocalStateField(key, data);
1249
+ }
1250
+ onDestroy() {
1251
+ this.provide.awareness.off("update", this.onUpdate);
1252
+ this.provide.disconnect();
1253
+ this.provide.destroy();
1254
+ }
1255
+ }
1256
+ class CollaborateModule {
1257
+ constructor(config) {
1258
+ this.config = config;
1259
+ }
1260
+ config;
1261
+ subscription = new stream.Subscription();
1262
+ providers = [
1263
+ exports.Collaborate,
1264
+ exports.CollabHistory,
1265
+ {
1266
+ provide: core.History,
1267
+ useExisting: exports.CollabHistory
1268
+ },
1269
+ {
1270
+ provide: SyncConnector,
1271
+ useFactory: (collab) => {
1272
+ return this.config.createConnector(collab.yDoc);
1273
+ },
1274
+ deps: [exports.Collaborate]
1275
+ },
1276
+ {
1277
+ provide: SubModelLoader,
1278
+ useClass: exports.NonSubModelLoader
1279
+ }
1280
+ ];
1281
+ timer = null;
1282
+ setup(textbus) {
1283
+ const messageBus = textbus.get(MessageBus, null);
1284
+ const connector = textbus.get(SyncConnector);
1285
+ const collab = textbus.get(exports.Collaborate);
1286
+ if (messageBus) {
1287
+ const selection = textbus.get(core.Selection);
1288
+ connector.setLocalStateField("message", messageBus.get(textbus));
1289
+ this.subscription.add(
1290
+ messageBus.onSync.subscribe(() => {
1291
+ connector.setLocalStateField("message", messageBus.get(textbus));
1292
+ }),
1293
+ selection.onChange.subscribe(() => {
1294
+ connector.setLocalStateField("message", messageBus.get(textbus));
1295
+ }),
1296
+ connector.onStateChange.subscribe((states) => {
1297
+ messageBus.consume(states, textbus);
1298
+ })
1299
+ );
1300
+ }
1301
+ return connector.onLoad.toPromise().then(() => {
1302
+ if (!this.config.onlyLoad) {
1303
+ return;
1304
+ }
1305
+ const root = collab.yDoc.getMap("RootComponent");
1306
+ if (root.has("state")) {
1307
+ return;
1308
+ }
1309
+ return new Promise((resolve) => {
1310
+ const testing = () => {
1311
+ if (root.has("state")) {
1312
+ resolve();
1313
+ } else {
1314
+ this.timer = setTimeout(testing, 1e3);
1315
+ }
1316
+ };
1317
+ this.timer = setTimeout(testing, 1e3);
1318
+ });
1319
+ });
1320
+ }
1321
+ onDestroy(textbus) {
1322
+ this.subscription.unsubscribe();
1323
+ textbus.get(exports.Collaborate).destroy();
1324
+ textbus.get(core.History).destroy();
1325
+ textbus.get(SyncConnector).onDestroy();
1326
+ clearTimeout(this.timer);
1327
+ }
1328
+ }
1329
+ class MultipleDocumentCollaborateModule {
1330
+ constructor(config) {
1331
+ this.config = config;
1332
+ }
1333
+ config;
1334
+ subscription = new stream.Subscription();
1335
+ providers = [
1336
+ exports.Collaborate,
1337
+ exports.MultipleDocCollabHistory,
1338
+ {
1339
+ provide: core.History,
1340
+ useExisting: exports.MultipleDocCollabHistory
1341
+ },
1342
+ {
1343
+ provide: SyncConnector,
1344
+ useFactory: (collab) => {
1345
+ return this.config.createConnector(collab.yDoc);
1346
+ },
1347
+ deps: [exports.Collaborate]
1348
+ },
1349
+ {
1350
+ provide: SubModelLoader,
1351
+ useFactory: () => {
1352
+ return this.config.subModelLoader;
1353
+ }
1354
+ }
1355
+ ];
1356
+ timer = null;
1357
+ setup(textbus) {
1358
+ const messageBus = textbus.get(MessageBus, null);
1359
+ const connector = textbus.get(SyncConnector);
1360
+ const collab = textbus.get(exports.Collaborate);
1361
+ if (messageBus) {
1362
+ const selection = textbus.get(core.Selection);
1363
+ connector.setLocalStateField("message", messageBus.get(textbus));
1364
+ this.subscription.add(
1365
+ messageBus.onSync.subscribe(() => {
1366
+ connector.setLocalStateField("message", messageBus.get(textbus));
1367
+ }),
1368
+ selection.onChange.subscribe(() => {
1369
+ connector.setLocalStateField("message", messageBus.get(textbus));
1370
+ }),
1371
+ connector.onStateChange.subscribe((states) => {
1372
+ messageBus.consume(states, textbus);
1373
+ })
1374
+ );
1375
+ }
1376
+ return connector.onLoad.toPromise().then(() => {
1377
+ if (!this.config.onlyLoad) {
1378
+ return;
1379
+ }
1380
+ const root = collab.yDoc.getMap("RootComponent");
1381
+ if (root.has("state")) {
1382
+ return;
1383
+ }
1384
+ return new Promise((resolve) => {
1385
+ const testing = () => {
1386
+ if (root.has("state")) {
1387
+ resolve();
1388
+ } else {
1389
+ this.timer = setTimeout(testing, 1e3);
1390
+ }
1391
+ };
1392
+ this.timer = setTimeout(testing, 1e3);
1393
+ });
1394
+ });
1395
+ }
1396
+ onDestroy(textbus) {
1397
+ this.subscription.unsubscribe();
1398
+ textbus.get(exports.Collaborate).destroy();
1399
+ textbus.get(core.History).destroy();
1400
+ textbus.get(SyncConnector).onDestroy();
1401
+ clearTimeout(this.timer);
1402
+ }
1403
+ }
1404
+ exports.CollaborateModule = CollaborateModule;
1405
+ exports.CustomUndoManagerConfig = CustomUndoManagerConfig;
1406
+ exports.HocuspocusConnector = HocuspocusConnector;
1407
+ exports.MessageBus = MessageBus;
1408
+ exports.MultipleDocumentCollaborateModule = MultipleDocumentCollaborateModule;
1409
+ exports.SubModelLoader = SubModelLoader;
1410
+ exports.SyncConnector = SyncConnector;
1411
+ exports.YWebsocketConnector = YWebsocketConnector;
3
1412
  //# sourceMappingURL=index.js.map