@textbus/collaborate 2.0.0-alpha.36 → 2.0.0-alpha.39

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.
@@ -0,0 +1,3 @@
1
+ export * from './collaborate-cursor';
2
+ export * from './local-to-remote';
3
+ export * from './remote-to-local';
@@ -0,0 +1,4 @@
1
+ export * from './collaborate-cursor';
2
+ export * from './local-to-remote';
3
+ export * from './remote-to-local';
4
+ //# sourceMappingURL=_api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_api.js","sourceRoot":"","sources":["../../src/collab/_api.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './collaborate-cursor'\nexport * from './local-to-remote'\nexport * from './remote-to-local'\n"]}
@@ -0,0 +1,25 @@
1
+ import { SelectionBridge } from '@textbus/browser';
2
+ import { Selection, SelectionPaths } from '@textbus/core';
3
+ export interface RemoteSelection {
4
+ color: string;
5
+ username: string;
6
+ paths: SelectionPaths;
7
+ }
8
+ export interface SelectionRect {
9
+ x: number;
10
+ y: number;
11
+ width: number;
12
+ height: number;
13
+ color: string;
14
+ }
15
+ export declare class CollaborateCursor {
16
+ private container;
17
+ private document;
18
+ private nativeSelection;
19
+ private selection;
20
+ private canvas;
21
+ private context;
22
+ private onRectChange;
23
+ constructor(container: HTMLElement, document: Document, nativeSelection: SelectionBridge, selection: Selection);
24
+ draw(paths: RemoteSelection[]): void;
25
+ }
@@ -0,0 +1,143 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from '@tanbo/di';
14
+ import { createElement, EDITABLE_DOCUMENT, EDITOR_CONTAINER, SelectionBridge } from '@textbus/browser';
15
+ import { Selection } from '@textbus/core';
16
+ import { Subject } from '@tanbo/stream';
17
+ let CollaborateCursor = class CollaborateCursor {
18
+ constructor(container, document, nativeSelection, selection) {
19
+ Object.defineProperty(this, "container", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: container
24
+ });
25
+ Object.defineProperty(this, "document", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: document
30
+ });
31
+ Object.defineProperty(this, "nativeSelection", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: nativeSelection
36
+ });
37
+ Object.defineProperty(this, "selection", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: selection
42
+ });
43
+ Object.defineProperty(this, "canvas", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: createElement('canvas', {
48
+ styles: {
49
+ position: 'absolute',
50
+ opacity: 0.5,
51
+ left: 0,
52
+ top: 0,
53
+ width: '100%',
54
+ height: '100%',
55
+ pointerEvents: 'none'
56
+ }
57
+ })
58
+ });
59
+ Object.defineProperty(this, "context", {
60
+ enumerable: true,
61
+ configurable: true,
62
+ writable: true,
63
+ value: this.canvas.getContext('2d')
64
+ });
65
+ Object.defineProperty(this, "onRectChange", {
66
+ enumerable: true,
67
+ configurable: true,
68
+ writable: true,
69
+ value: new Subject()
70
+ });
71
+ container.appendChild(this.canvas);
72
+ this.onRectChange.subscribe(rect => {
73
+ this.context.fillStyle = rect.color;
74
+ this.context.beginPath();
75
+ this.context.rect(Math.ceil(rect.x), Math.ceil(rect.y), Math.ceil(rect.width), Math.ceil(rect.height));
76
+ this.context.fill();
77
+ this.context.closePath();
78
+ });
79
+ }
80
+ draw(paths) {
81
+ this.canvas.width = this.container.offsetWidth;
82
+ this.canvas.height = this.container.offsetHeight;
83
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
84
+ paths.filter(i => {
85
+ return i.paths.start.length && i.paths.end.length;
86
+ }).forEach(item => {
87
+ const startOffset = item.paths.start.pop();
88
+ const startSlot = this.selection.findSlotByPaths(item.paths.start);
89
+ const endOffset = item.paths.end.pop();
90
+ const endSlot = this.selection.findSlotByPaths(item.paths.end);
91
+ if (startSlot && endSlot) {
92
+ const position = this.nativeSelection.getPositionByRange({
93
+ startOffset,
94
+ endOffset,
95
+ startSlot,
96
+ endSlot
97
+ });
98
+ if (position.start && position.end) {
99
+ const nativeRange = this.document.createRange();
100
+ nativeRange.setStart(position.start.node, position.start.offset);
101
+ nativeRange.setEnd(position.end.node, position.end.offset);
102
+ const rects = nativeRange.getClientRects();
103
+ let prev = {};
104
+ for (let i = rects.length - 1; i >= 0; i--) {
105
+ const rect = rects[i];
106
+ if (prev.y === rect.y) {
107
+ continue;
108
+ }
109
+ prev = rect;
110
+ this.onRectChange.next({
111
+ x: rect.x,
112
+ y: rect.y,
113
+ width: rect.width,
114
+ height: rect.height,
115
+ color: item.color
116
+ });
117
+ }
118
+ if (rects.length === 0) {
119
+ const rect = nativeRange.getBoundingClientRect();
120
+ this.onRectChange.next({
121
+ x: rect.x,
122
+ y: rect.y,
123
+ width: 1,
124
+ height: rect.height,
125
+ color: item.color
126
+ });
127
+ }
128
+ }
129
+ }
130
+ });
131
+ }
132
+ };
133
+ CollaborateCursor = __decorate([
134
+ Injectable(),
135
+ __param(0, Inject(EDITOR_CONTAINER)),
136
+ __param(1, Inject(EDITABLE_DOCUMENT)),
137
+ __metadata("design:paramtypes", [HTMLElement,
138
+ Document,
139
+ SelectionBridge,
140
+ Selection])
141
+ ], CollaborateCursor);
142
+ export { CollaborateCursor };
143
+ //# sourceMappingURL=collaborate-cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaborate-cursor.js","sourceRoot":"","sources":["../../src/collab/collaborate-cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable } from '@tanbo/di'\nimport { createElement, EDITABLE_DOCUMENT, EDITOR_CONTAINER, SelectionBridge } from '@textbus/browser'\nimport { Selection, SelectionPaths } from '@textbus/core'\nimport { Subject } from '@tanbo/stream'\n\nexport interface RemoteSelection {\n color: string\n username: string\n paths: SelectionPaths\n}\n\nexport interface SelectionRect {\n x: number\n y: number\n width: number\n height: number\n color: string\n}\n\n@Injectable()\nexport class CollaborateCursor {\n private canvas = createElement('canvas', {\n styles: {\n position: 'absolute',\n opacity: 0.5,\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none'\n }\n }) as HTMLCanvasElement\n private context = this.canvas.getContext('2d')!\n\n private onRectChange = new Subject<SelectionRect>()\n\n constructor(@Inject(EDITOR_CONTAINER) private container: HTMLElement,\n @Inject(EDITABLE_DOCUMENT) private document: Document,\n private nativeSelection: SelectionBridge,\n private selection: Selection) {\n container.appendChild(this.canvas)\n this.onRectChange.subscribe(rect => {\n this.context.fillStyle = rect.color\n this.context.beginPath()\n this.context.rect(Math.ceil(rect.x), Math.ceil(rect.y), Math.ceil(rect.width), Math.ceil(rect.height))\n this.context.fill()\n this.context.closePath()\n })\n }\n\n draw(paths: RemoteSelection[]) {\n this.canvas.width = this.container.offsetWidth\n this.canvas.height = this.container.offsetHeight\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)\n\n paths.filter(i => {\n return i.paths.start.length && i.paths.end.length\n }).forEach(item => {\n const startOffset = item.paths.start.pop()!\n const startSlot = this.selection.findSlotByPaths(item.paths.start)\n const endOffset = item.paths.end.pop()!\n const endSlot = this.selection.findSlotByPaths(item.paths.end)\n\n if (startSlot && endSlot) {\n const position = this.nativeSelection.getPositionByRange({\n startOffset,\n endOffset,\n startSlot,\n endSlot\n })\n if (position.start && position.end) {\n const nativeRange = this.document.createRange()\n nativeRange.setStart(position.start.node, position.start.offset)\n nativeRange.setEnd(position.end.node, position.end.offset)\n\n const rects = nativeRange.getClientRects()\n let prev: any = {}\n for (let i = rects.length - 1; i >= 0; i--) {\n const rect = rects[i]\n if (prev.y === rect.y) {\n continue\n }\n prev = rect\n this.onRectChange.next({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n color: item.color\n })\n }\n\n if (rects.length === 0) {\n const rect = nativeRange.getBoundingClientRect()\n this.onRectChange.next({\n x: rect.x,\n y: rect.y,\n width: 1,\n height: rect.height,\n color: item.color\n })\n }\n }\n }\n })\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { Operation } from '@textbus/core';
2
+ import { Text as YText } from 'yjs';
3
+ export declare class LocalToRemote {
4
+ transform(operation: Operation, root: YText): void;
5
+ private applyComponentOperationToSharedComponent;
6
+ private applySlotOperationToSharedSlot;
7
+ private mergeActionsToSharedSlot;
8
+ private makeSharedSlotBySlotLiteral;
9
+ private makeSharedComponentByComponentLiteral;
10
+ private getSharedComponentByIndex;
11
+ }
@@ -0,0 +1,155 @@
1
+ import { Array as YArray, Map as YMap, Text as YText } from 'yjs';
2
+ export class LocalToRemote {
3
+ transform(operation, root) {
4
+ const path = [...operation.path];
5
+ path.shift();
6
+ if (path.length) {
7
+ const componentIndex = path.shift();
8
+ const sharedComponent = this.getSharedComponentByIndex(root, componentIndex);
9
+ if (sharedComponent) {
10
+ this.applyComponentOperationToSharedComponent(path, operation.apply, sharedComponent);
11
+ }
12
+ return;
13
+ }
14
+ this.mergeActionsToSharedSlot(root, operation.apply);
15
+ }
16
+ applyComponentOperationToSharedComponent(path, actions, componentYMap) {
17
+ const sharedSlots = componentYMap.get('slots');
18
+ if (path.length) {
19
+ const slotIndex = path.shift();
20
+ const sharedSlot = sharedSlots.get(slotIndex);
21
+ this.applySlotOperationToSharedSlot(path, actions, sharedSlot);
22
+ return;
23
+ }
24
+ let index;
25
+ actions.forEach(action => {
26
+ switch (action.type) {
27
+ case 'retain':
28
+ index = action.offset;
29
+ break;
30
+ case 'insertSlot':
31
+ sharedSlots.insert(index, [this.makeSharedSlotBySlotLiteral(action.slot)]);
32
+ index++;
33
+ break;
34
+ case 'apply':
35
+ componentYMap.set('state', action.value);
36
+ break;
37
+ case 'delete':
38
+ sharedSlots.delete(index, action.count);
39
+ break;
40
+ }
41
+ });
42
+ }
43
+ applySlotOperationToSharedSlot(path, actions, slotYMap) {
44
+ if (path.length) {
45
+ const componentIndex = path.shift();
46
+ const sharedContent = slotYMap.get('content');
47
+ const sharedComponent = this.getSharedComponentByIndex(sharedContent, componentIndex);
48
+ this.applyComponentOperationToSharedComponent(path, actions, sharedComponent);
49
+ return;
50
+ }
51
+ const content = slotYMap.get('content');
52
+ this.mergeActionsToSharedSlot(content, actions);
53
+ }
54
+ mergeActionsToSharedSlot(content, actions) {
55
+ let index;
56
+ let length;
57
+ actions.forEach(action => {
58
+ var _a;
59
+ if (action.type === 'retain') {
60
+ if (action.formats) {
61
+ content.format(index, action.offset, action.formats);
62
+ }
63
+ else {
64
+ index = action.offset;
65
+ }
66
+ }
67
+ else if (action.type === 'insert') {
68
+ const delta = content.toDelta();
69
+ const isEmpty = delta.length === 1 && delta[0].insert === '\n';
70
+ if (typeof action.content === 'string') {
71
+ length = action.content.length;
72
+ content.insert(index, action.content);
73
+ }
74
+ else {
75
+ length = 1;
76
+ content.insertEmbed(index, this.makeSharedComponentByComponentLiteral(action.content));
77
+ }
78
+ if (action.formats) {
79
+ content.format(index, length, action.formats);
80
+ }
81
+ if (isEmpty && index === 0) {
82
+ content.delete(content.length - 1, 1);
83
+ }
84
+ index += length;
85
+ }
86
+ else if (action.type === 'delete') {
87
+ const delta = content.toDelta();
88
+ content.delete(index, action.count);
89
+ if (content.length === 0) {
90
+ content.insert(0, '\n', (_a = delta[0]) === null || _a === void 0 ? void 0 : _a.attributes);
91
+ }
92
+ }
93
+ else if (action.type === 'apply') {
94
+ content.setAttribute('state', action.value);
95
+ }
96
+ });
97
+ }
98
+ makeSharedSlotBySlotLiteral(slotLiteral) {
99
+ const content = new YText();
100
+ let index = 0;
101
+ slotLiteral.content.forEach(i => {
102
+ let size;
103
+ if (typeof i === 'string') {
104
+ size = i.length;
105
+ content.insert(index, i);
106
+ }
107
+ else {
108
+ size = 1;
109
+ content.insertEmbed(index, this.makeSharedComponentByComponentLiteral(i));
110
+ }
111
+ index += size;
112
+ });
113
+ const formats = slotLiteral.formats;
114
+ Object.keys(formats).forEach(key => {
115
+ const formatRanges = formats[key];
116
+ formatRanges.forEach(formatRange => {
117
+ content.format(formatRange.startIndex, formatRange.endIndex - formatRange.startIndex, {
118
+ [key]: formatRange.value
119
+ });
120
+ });
121
+ });
122
+ const sharedSlot = new YMap();
123
+ sharedSlot.set('content', content);
124
+ sharedSlot.set('schema', slotLiteral.schema);
125
+ return sharedSlot;
126
+ }
127
+ makeSharedComponentByComponentLiteral(componentLiteral) {
128
+ const slots = new YArray();
129
+ componentLiteral.slots.forEach(item => {
130
+ slots.push([this.makeSharedSlotBySlotLiteral(item)]);
131
+ });
132
+ const sharedComponent = new YMap();
133
+ sharedComponent.set('name', componentLiteral.name);
134
+ sharedComponent.set('slots', slots);
135
+ sharedComponent.set('state', componentLiteral.state);
136
+ return sharedComponent;
137
+ }
138
+ getSharedComponentByIndex(host, index) {
139
+ const delta = host.toDelta();
140
+ let i = 0;
141
+ for (const action of delta) {
142
+ if (action.insert) {
143
+ if (i === index) {
144
+ return action.insert instanceof YMap ? action.insert : null;
145
+ }
146
+ i += action.insert instanceof YMap ? 1 : action.insert.length;
147
+ }
148
+ else {
149
+ throw new Error('xxx');
150
+ }
151
+ }
152
+ return null;
153
+ }
154
+ }
155
+ //# sourceMappingURL=local-to-remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-to-remote.js","sourceRoot":"","sources":["../../src/collab/local-to-remote.ts"],"names":[],"mappings":"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","sourcesContent":["import { Action, Operation, SlotLiteral, ComponentLiteral } from '@textbus/core'\nimport { Array as YArray, Map as YMap, Text as YText } from 'yjs'\n\nexport class LocalToRemote {\n transform(operation: Operation, root: YText) {\n const path = [...operation.path]\n path.shift()\n if (path.length) {\n const componentIndex = path.shift()!\n const sharedComponent = this.getSharedComponentByIndex(root, componentIndex)\n if (sharedComponent) {\n this.applyComponentOperationToSharedComponent(path, operation.apply, sharedComponent)\n }\n return\n }\n this.mergeActionsToSharedSlot(root, operation.apply)\n }\n\n private applyComponentOperationToSharedComponent(path: number[], actions: Action[], componentYMap: YMap<any>) {\n const sharedSlots = componentYMap.get('slots') as YArray<any>\n if (path.length) {\n const slotIndex = path.shift()!\n const sharedSlot = sharedSlots.get(slotIndex)\n this.applySlotOperationToSharedSlot(path, actions, sharedSlot)\n return\n }\n let index: number\n actions.forEach(action => {\n switch (action.type) {\n case 'retain':\n index = action.offset\n break\n case 'insertSlot':\n sharedSlots.insert(index, [this.makeSharedSlotBySlotLiteral(action.slot)])\n index++\n break\n case 'apply':\n componentYMap.set('state', action.value)\n break\n case 'delete':\n sharedSlots.delete(index, action.count)\n break\n }\n })\n }\n\n private applySlotOperationToSharedSlot(path: number[], actions: Action[], slotYMap: YMap<any>) {\n if (path.length) {\n const componentIndex = path.shift()!\n const sharedContent = slotYMap.get('content') as YText\n const sharedComponent = this.getSharedComponentByIndex(sharedContent, componentIndex)!\n this.applyComponentOperationToSharedComponent(path, actions, sharedComponent)\n return\n }\n const content = slotYMap.get('content') as YText\n\n this.mergeActionsToSharedSlot(content, actions)\n }\n\n private mergeActionsToSharedSlot(content: YText, actions: Action[]) {\n let index: number\n let length: number\n\n actions.forEach(action => {\n if (action.type === 'retain') {\n if (action.formats) {\n content.format(index, action.offset, action.formats)\n } else {\n index = action.offset\n }\n } else if (action.type === 'insert') {\n const delta = content.toDelta()\n const isEmpty = delta.length === 1 && delta[0].insert === '\\n'\n\n if (typeof action.content === 'string') {\n length = action.content.length\n content.insert(index, action.content)\n } else {\n length = 1\n content.insertEmbed(index, this.makeSharedComponentByComponentLiteral(action.content))\n }\n if (action.formats) {\n content.format(index, length, action.formats)\n }\n if (isEmpty && index === 0) {\n content.delete(content.length - 1, 1)\n }\n index += length\n } else if (action.type === 'delete') {\n const delta = content.toDelta()\n content.delete(index, action.count)\n if (content.length === 0) {\n content.insert(0, '\\n', delta[0]?.attributes)\n }\n } else if (action.type === 'apply') {\n content.setAttribute('state', action.value)\n }\n })\n }\n\n private makeSharedSlotBySlotLiteral(slotLiteral: SlotLiteral): YMap<any> {\n const content = new YText()\n let index = 0\n slotLiteral.content.forEach(i => {\n let size: number\n if (typeof i === 'string') {\n size = i.length\n content.insert(index, i)\n } else {\n size = 1\n content.insertEmbed(index, this.makeSharedComponentByComponentLiteral(i))\n }\n index += size\n })\n const formats = slotLiteral.formats\n Object.keys(formats).forEach(key => {\n const formatRanges = formats[key]\n formatRanges.forEach(formatRange => {\n content.format(formatRange.startIndex, formatRange.endIndex - formatRange.startIndex, {\n [key]: formatRange.value\n })\n })\n })\n\n const sharedSlot = new YMap()\n sharedSlot.set('content', content)\n sharedSlot.set('schema', slotLiteral.schema)\n return sharedSlot\n }\n\n private makeSharedComponentByComponentLiteral(componentLiteral: ComponentLiteral): YMap<any> {\n const slots = new YArray()\n componentLiteral.slots.forEach(item => {\n slots.push([this.makeSharedSlotBySlotLiteral(item)])\n })\n const sharedComponent = new YMap()\n sharedComponent.set('name', componentLiteral.name)\n sharedComponent.set('slots', slots)\n sharedComponent.set('state', componentLiteral.state)\n return sharedComponent\n }\n\n private getSharedComponentByIndex(host: YText, index: number): YMap<any> | null {\n const delta = host.toDelta()\n let i = 0\n for (const action of delta) {\n if (action.insert) {\n if (i === index) {\n return action.insert instanceof YMap ? action.insert : null\n }\n i += action.insert instanceof YMap ? 1 : action.insert.length\n } else {\n throw new Error('xxx')\n }\n }\n return null\n }\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { YEvent } from 'yjs';
2
+ import { Registry, Slot, Translator } from '@textbus/core';
3
+ export declare class RemoteToLocal {
4
+ private translator;
5
+ private registry;
6
+ constructor(translator: Translator, registry: Registry);
7
+ transform(events: YEvent[], slot: Slot): void;
8
+ private applySharedComponentToComponent;
9
+ private applySharedSlotToSlot;
10
+ private createComponentBySharedComponent;
11
+ private createSlotBySharedSlot;
12
+ }
@@ -0,0 +1,158 @@
1
+ import { YArrayEvent, YMapEvent, YTextEvent } from 'yjs';
2
+ export class RemoteToLocal {
3
+ constructor(translator, registry) {
4
+ Object.defineProperty(this, "translator", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: translator
9
+ });
10
+ Object.defineProperty(this, "registry", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: registry
15
+ });
16
+ }
17
+ transform(events, slot) {
18
+ events.forEach(ev => {
19
+ const path = [];
20
+ for (let i = 0; i < ev.path.length; i += 2) {
21
+ path.push(ev.path.slice(i, i + 2));
22
+ }
23
+ if (path.length) {
24
+ const componentIndex = path.shift()[0];
25
+ const component = slot.getContentAtIndex(componentIndex);
26
+ this.applySharedComponentToComponent(ev, path, component);
27
+ return;
28
+ }
29
+ this.applySharedSlotToSlot(ev, path, slot);
30
+ });
31
+ }
32
+ applySharedComponentToComponent(ev, path, component) {
33
+ if (path.length) {
34
+ const childPath = path.shift();
35
+ const slot = component.slots.get(childPath[0]);
36
+ this.applySharedSlotToSlot(ev, path, slot);
37
+ return;
38
+ }
39
+ if (ev instanceof YMapEvent) {
40
+ ev.keysChanged.forEach(key => {
41
+ if (key === 'state') {
42
+ const state = ev.target.get('state');
43
+ component.updateState(draft => {
44
+ Object.assign(draft, state);
45
+ });
46
+ }
47
+ });
48
+ }
49
+ else if (ev instanceof YArrayEvent) {
50
+ const slots = component.slots;
51
+ ev.delta.forEach(action => {
52
+ if (Reflect.has(action, 'retain')) {
53
+ slots.retain(action.retain);
54
+ }
55
+ else if (action.insert) {
56
+ action.insert.forEach(item => {
57
+ slots.insert(this.translator.createSlot(item.toJSON()));
58
+ });
59
+ }
60
+ else if (action.delete) {
61
+ slots.retain(slots.index);
62
+ slots.delete(action.delete);
63
+ }
64
+ });
65
+ }
66
+ }
67
+ applySharedSlotToSlot(ev, path, slot) {
68
+ if (path.length) {
69
+ path.shift();
70
+ const delta = ev.target.parent.toDelta();
71
+ let componentIndex = 0;
72
+ for (let i = 0; i < delta.length; i++) {
73
+ const action = delta[i];
74
+ if (action.insert === ev.target) {
75
+ break;
76
+ }
77
+ componentIndex += typeof action.insert === 'string' ? action.insert.length : 1;
78
+ }
79
+ const component = slot.getContentAtIndex(componentIndex);
80
+ this.applySharedComponentToComponent(ev, path, component);
81
+ return;
82
+ }
83
+ if (ev instanceof YTextEvent) {
84
+ slot.retain(0);
85
+ ev.delta.forEach(action => {
86
+ if (Reflect.has(action, 'retain')) {
87
+ if (action.attributes) {
88
+ slot.retain(action.retain, Object.keys(action.attributes).map(key => {
89
+ return [this.registry.getFormatter(key), action.attributes[key]];
90
+ }));
91
+ }
92
+ slot.retain(action.retain);
93
+ }
94
+ else if (action.insert) {
95
+ if (typeof action.insert === 'string') {
96
+ slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {
97
+ return [this.registry.getFormatter(key), action.attributes[key]];
98
+ }) : []);
99
+ }
100
+ else {
101
+ const component = this.createComponentBySharedComponent(action.insert);
102
+ slot.insert(component);
103
+ }
104
+ }
105
+ else if (action.delete) {
106
+ slot.retain(slot.index);
107
+ slot.delete(action.delete);
108
+ }
109
+ else if (action.attributes) {
110
+ slot.updateState(draft => {
111
+ Object.assign(draft, action.attributes);
112
+ });
113
+ }
114
+ });
115
+ }
116
+ else {
117
+ throw new Error('xxx');
118
+ }
119
+ }
120
+ createComponentBySharedComponent(yMap) {
121
+ const slots = yMap.get('slots');
122
+ const componentLiteral = {
123
+ state: yMap.get('state'),
124
+ name: yMap.get('name'),
125
+ slots: slots.map(sharedSlot => {
126
+ return this.createSlotBySharedSlot(sharedSlot).toJSON();
127
+ })
128
+ };
129
+ return this.translator.createComponent(componentLiteral);
130
+ }
131
+ createSlotBySharedSlot(sharedSlot) {
132
+ const content = sharedSlot.get('content');
133
+ const delta = content.toDelta();
134
+ const slot = this.translator.createSlot({
135
+ schema: sharedSlot.get('schema'),
136
+ state: sharedSlot.get('state'),
137
+ formats: {},
138
+ content: []
139
+ });
140
+ for (const action of delta) {
141
+ if (action.insert) {
142
+ if (typeof action.insert === 'string') {
143
+ slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {
144
+ return [this.registry.getFormatter(key), action.attributes[key]];
145
+ }) : []);
146
+ }
147
+ else {
148
+ slot.insert(this.createComponentBySharedComponent(action.insert));
149
+ }
150
+ }
151
+ else {
152
+ throw new Error('xxx');
153
+ }
154
+ }
155
+ return slot;
156
+ }
157
+ }
158
+ //# sourceMappingURL=remote-to-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-to-local.js","sourceRoot":"","sources":["../../src/collab/remote-to-local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAU,SAAS,EAAiB,UAAU,EAAmB,MAAM,KAAK,CAAA;AAK7G,MAAM,OAAO,aAAa;IACxB,YAAoB,UAAsB,EACtB,QAAkB;;;;;mBADlB;;;;;;mBACA;;IACpB,CAAC;IAED,SAAS,CAAC,MAAgB,EAAE,IAAU;QACpC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YAClB,MAAM,IAAI,GAAU,EAAE,CAAA;YAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;gBAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAqB,CAAC,CAAA;aACvD;YAED,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,EAAG,CAAC,CAAC,CAAW,CAAA;gBACjD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAsB,CAAA;gBAC7E,IAAI,CAAC,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;gBACzD,OAAM;aACP;YAED,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,+BAA+B,CAAC,EAAU,EAAE,IAAW,EAAE,SAA4B;QAC3F,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAG,CAAA;YAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,CAAA;YAC/C,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YAC1C,OAAM;SACP;QACD,IAAI,EAAE,YAAY,SAAS,EAAE;YAC3B,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC3B,IAAI,GAAG,KAAK,OAAO,EAAE;oBACnB,MAAM,KAAK,GAAI,EAAE,CAAC,MAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACnD,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBAC5B,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;oBAC7B,CAAC,CAAC,CAAA;iBACH;YACH,CAAC,CAAC,CAAA;SACH;aAAM,IAAI,EAAE,YAAY,WAAW,EAAE;YACpC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAA;YAC7B,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;oBACjC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,CAAC,CAAA;iBAC7B;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACvB,MAAM,CAAC,MAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;wBAC3C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAE,CAAC,CAAA;oBAC1D,CAAC,CAAC,CAAA;iBACH;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACzB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;iBAC5B;YACH,CAAC,CAAC,CAAA;SACH;IACH,CAAC;IAEO,qBAAqB,CAAC,EAAU,EAAE,IAAW,EAAE,IAAU;QAC/D,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,MAAM,KAAK,GAAI,EAAE,CAAC,MAAM,CAAC,MAAgB,CAAC,OAAO,EAAE,CAAA;YACnD,IAAI,cAAc,GAAG,CAAC,CAAA;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBACvB,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE;oBAC/B,MAAK;iBACN;gBACD,cAAc,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;aAC/E;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAsB,CAAA;YAC7E,IAAI,CAAC,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;YACzD,OAAM;SACP;QAED,IAAI,EAAE,YAAY,UAAU,EAAE;YAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACd,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;oBACjC,IAAI,MAAM,CAAC,UAAU,EAAE;wBACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;4BACnE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;wBACpE,CAAC,CAAC,CAAC,CAAA;qBACJ;oBACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,CAAC,CAAA;iBAC5B;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;wBACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;4BACtF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;wBACpE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;qBACT;yBAAM;wBACL,MAAM,SAAS,GAAG,IAAI,CAAC,gCAAgC,CAAC,MAAM,CAAC,MAAmB,CAAC,CAAA;wBACnF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;qBACvB;iBACF;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;oBACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;iBAC3B;qBAAM,IAAI,MAAM,CAAC,UAAU,EAAE;oBAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBACvB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;oBACzC,CAAC,CAAC,CAAA;iBACH;YACH,CAAC,CAAC,CAAA;SACH;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;SACvB;IACH,CAAC;IAEO,gCAAgC,CAAC,IAAe;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAsB,CAAA;QACpD,MAAM,gBAAgB,GAAqB;YACzC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YACxB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YACtB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;gBAC5B,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAA;YACzD,CAAC,CAAC;SACH,CAAA;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,gBAAgB,CAAE,CAAA;IAC3D,CAAC;IAEO,sBAAsB,CAAC,UAAqB;QAClD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAU,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;QAE/B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACtC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;YAC9B,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,EAAE;SACZ,CAAC,CAAA;QAEF,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;YAC1B,IAAI,MAAM,CAAC,MAAM,EAAE;gBACjB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;oBACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;wBACtF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;oBACpE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;iBACT;qBAAM;oBACL,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;iBAClE;aACF;iBAAM;gBACL,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;aACvB;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF","sourcesContent":["import { Map as YMap, YArrayEvent, YEvent, YMapEvent, Text as YText, YTextEvent, Array as YArray } from 'yjs'\nimport { ComponentInstance, ComponentLiteral, Registry, Slot, Translator } from '@textbus/core'\n\ntype YPath = [number, string][]\n\nexport class RemoteToLocal {\n constructor(private translator: Translator,\n private registry: Registry) {\n }\n\n transform(events: YEvent[], slot: Slot) {\n events.forEach(ev => {\n const path: YPath = []\n\n for (let i = 0; i < ev.path.length; i += 2) {\n path.push(ev.path.slice(i, i + 2) as [number, string])\n }\n\n if (path.length) {\n const componentIndex = path.shift()![0] as number\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n\n this.applySharedSlotToSlot(ev, path, slot)\n })\n }\n\n private applySharedComponentToComponent(ev: YEvent, path: YPath, component: ComponentInstance) {\n if (path.length) {\n const childPath = path.shift()!\n const slot = component.slots.get(childPath[0])!\n this.applySharedSlotToSlot(ev, path, slot)\n return\n }\n if (ev instanceof YMapEvent) {\n ev.keysChanged.forEach(key => {\n if (key === 'state') {\n const state = (ev.target as YMap<any>).get('state')\n component.updateState(draft => {\n Object.assign(draft, state)\n })\n }\n })\n } else if (ev instanceof YArrayEvent) {\n const slots = component.slots\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n slots.retain(action.retain!)\n } else if (action.insert) {\n (action.insert as Array<any>).forEach(item => {\n slots.insert(this.translator.createSlot(item.toJSON())!)\n })\n } else if (action.delete) {\n slots.retain(slots.index)\n slots.delete(action.delete)\n }\n })\n }\n }\n\n private applySharedSlotToSlot(ev: YEvent, path: YPath, slot: Slot) {\n if (path.length) {\n path.shift()\n const delta = (ev.target.parent as YText).toDelta()\n let componentIndex = 0\n for (let i = 0; i < delta.length; i++) {\n const action = delta[i]\n if (action.insert === ev.target) {\n break\n }\n componentIndex += typeof action.insert === 'string' ? action.insert.length : 1\n }\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n\n if (ev instanceof YTextEvent) {\n slot.retain(0)\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n if (action.attributes) {\n slot.retain(action.retain!, Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }))\n }\n slot.retain(action.retain!)\n } else if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n } else {\n const component = this.createComponentBySharedComponent(action.insert as YMap<any>)\n slot.insert(component)\n }\n } else if (action.delete) {\n slot.retain(slot.index)\n slot.delete(action.delete)\n } else if (action.attributes) {\n slot.updateState(draft => {\n Object.assign(draft, action.attributes)\n })\n }\n })\n } else {\n throw new Error('xxx')\n }\n }\n\n private createComponentBySharedComponent(yMap: YMap<any>): ComponentInstance {\n const slots = yMap.get('slots') as YArray<YMap<any>>\n const componentLiteral: ComponentLiteral = {\n state: yMap.get('state'),\n name: yMap.get('name'),\n slots: slots.map(sharedSlot => {\n return this.createSlotBySharedSlot(sharedSlot).toJSON()\n })\n }\n return this.translator.createComponent(componentLiteral)!\n }\n\n private createSlotBySharedSlot(sharedSlot: YMap<any>): Slot {\n const content = sharedSlot.get('content') as YText\n const delta = content.toDelta()\n\n const slot = this.translator.createSlot({\n schema: sharedSlot.get('schema'),\n state: sharedSlot.get('state'),\n formats: {},\n content: []\n })\n\n for (const action of delta) {\n if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n } else {\n slot.insert(this.createComponentBySharedComponent(action.insert))\n }\n } else {\n throw new Error('xxx')\n }\n }\n return slot\n }\n}\n"]}
@@ -1,15 +1,39 @@
1
- import { RootComponentRef, Starter, Translator, FormatterList } from '@textbus/core';
1
+ import { Observable } from '@tanbo/stream';
2
+ import { RootComponentRef, Starter, Translator, Registry, Selection, SelectionPaths, History, Renderer } from '@textbus/core';
2
3
  import { Doc as YDoc } from 'yjs';
3
- export declare class Collaborate {
4
+ import { CollaborateCursor, RemoteSelection } from './collab/_api';
5
+ export declare class Collaborate implements History {
4
6
  private rootComponentRef;
7
+ private collaborateCursor;
5
8
  private translator;
6
- private formatterList;
9
+ private renderer;
10
+ private registry;
11
+ private selection;
7
12
  private starter;
13
+ onSelectionChange: Observable<SelectionPaths>;
8
14
  yDoc: YDoc;
15
+ onBack: Observable<void>;
16
+ onForward: Observable<void>;
17
+ onChange: Observable<any>;
18
+ onPush: Observable<void>;
19
+ get canBack(): boolean;
20
+ get canForward(): boolean;
21
+ private localToRemote;
22
+ private remoteToLocal;
23
+ private backEvent;
24
+ private forwardEvent;
25
+ private changeEvent;
26
+ private pushEvent;
27
+ private manager;
9
28
  private subscriptions;
10
29
  private updateFromSelf;
11
- constructor(rootComponentRef: RootComponentRef, translator: Translator, formatterList: FormatterList, starter: Starter);
30
+ private selectionChangeEvent;
31
+ constructor(rootComponentRef: RootComponentRef, collaborateCursor: CollaborateCursor, translator: Translator, renderer: Renderer, registry: Registry, selection: Selection, starter: Starter);
12
32
  setup(): void;
33
+ updateRemoteSelection(paths: RemoteSelection[]): void;
34
+ listen(): void;
35
+ back(): void;
36
+ forward(): void;
13
37
  destroy(): void;
14
- private listen;
38
+ private listen2;
15
39
  }