@theia/collaboration 1.67.0-next.13 → 1.67.0-next.56
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/README.md +1 -1
- package/package.json +7 -7
- package/lib/browser/collaboration-color-service.d.ts +0 -27
- package/lib/browser/collaboration-color-service.d.ts.map +0 -1
- package/lib/browser/collaboration-color-service.js +0 -76
- package/lib/browser/collaboration-color-service.js.map +0 -1
- package/lib/browser/collaboration-file-system-provider.d.ts +0 -37
- package/lib/browser/collaboration-file-system-provider.d.ts.map +0 -1
- package/lib/browser/collaboration-file-system-provider.js +0 -107
- package/lib/browser/collaboration-file-system-provider.js.map +0 -1
- package/lib/browser/collaboration-frontend-contribution.d.ts +0 -50
- package/lib/browser/collaboration-frontend-contribution.d.ts.map +0 -1
- package/lib/browser/collaboration-frontend-contribution.js +0 -432
- package/lib/browser/collaboration-frontend-contribution.js.map +0 -1
- package/lib/browser/collaboration-frontend-module.d.ts +0 -4
- package/lib/browser/collaboration-frontend-module.d.ts.map +0 -1
- package/lib/browser/collaboration-frontend-module.js +0 -40
- package/lib/browser/collaboration-frontend-module.js.map +0 -1
- package/lib/browser/collaboration-instance.d.ts +0 -94
- package/lib/browser/collaboration-instance.d.ts.map +0 -1
- package/lib/browser/collaboration-instance.js +0 -806
- package/lib/browser/collaboration-instance.js.map +0 -1
- package/lib/browser/collaboration-utils.d.ts +0 -8
- package/lib/browser/collaboration-utils.d.ts.map +0 -1
- package/lib/browser/collaboration-utils.js +0 -63
- package/lib/browser/collaboration-utils.js.map +0 -1
- package/lib/browser/collaboration-workspace-service.d.ts +0 -12
- package/lib/browser/collaboration-workspace-service.d.ts.map +0 -1
- package/lib/browser/collaboration-workspace-service.js +0 -67
- package/lib/browser/collaboration-workspace-service.js.map +0 -1
- package/lib/common/collaboration-preferences.d.ts +0 -3
- package/lib/common/collaboration-preferences.d.ts.map +0 -1
- package/lib/common/collaboration-preferences.js +0 -31
- package/lib/common/collaboration-preferences.js.map +0 -1
- package/lib/node/collaboration-backend-module.d.ts +0 -4
- package/lib/node/collaboration-backend-module.d.ts.map +0 -1
- package/lib/node/collaboration-backend-module.js +0 -24
- package/lib/node/collaboration-backend-module.js.map +0 -1
- package/lib/package.spec.d.ts +0 -1
- package/lib/package.spec.d.ts.map +0 -1
- package/lib/package.spec.js +0 -26
- package/lib/package.spec.js.map +0 -1
|
@@ -1,806 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// *****************************************************************************
|
|
3
|
-
// Copyright (C) 2024 TypeFox and others.
|
|
4
|
-
//
|
|
5
|
-
// This program and the accompanying materials are made available under the
|
|
6
|
-
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
-
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
-
//
|
|
9
|
-
// This Source Code may also be made available under the following Secondary
|
|
10
|
-
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
-
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
-
// with the GNU Classpath Exception which is available at
|
|
13
|
-
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
-
//
|
|
15
|
-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
-
// *****************************************************************************
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.CollaborationInstance = exports.COLLABORATION_SELECTION_INVERTED = exports.COLLABORATION_SELECTION_MARKER = exports.COLLABORATION_SELECTION = exports.createCollaborationInstanceContainer = exports.CollaborationInstanceOptions = exports.CollaborationInstanceFactory = void 0;
|
|
19
|
-
const tslib_1 = require("tslib");
|
|
20
|
-
const types = require("open-collaboration-protocol");
|
|
21
|
-
const Y = require("yjs");
|
|
22
|
-
const awarenessProtocol = require("y-protocols/awareness");
|
|
23
|
-
const core_1 = require("@theia/core");
|
|
24
|
-
const inversify_1 = require("@theia/core/shared/inversify");
|
|
25
|
-
const application_shell_1 = require("@theia/core/lib/browser/shell/application-shell");
|
|
26
|
-
const editor_manager_1 = require("@theia/editor/lib/browser/editor-manager");
|
|
27
|
-
const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
|
|
28
|
-
const monaco_text_model_service_1 = require("@theia/monaco/lib/browser/monaco-text-model-service");
|
|
29
|
-
const collaboration_workspace_service_1 = require("./collaboration-workspace-service");
|
|
30
|
-
const monaco_editor_core_1 = require("@theia/monaco-editor-core");
|
|
31
|
-
const monaco_editor_1 = require("@theia/monaco/lib/browser/monaco-editor");
|
|
32
|
-
const promise_util_1 = require("@theia/core/lib/common/promise-util");
|
|
33
|
-
const browser_1 = require("@theia/editor/lib/browser");
|
|
34
|
-
const browser_2 = require("@theia/core/lib/browser");
|
|
35
|
-
const collaboration_file_system_provider_1 = require("./collaboration-file-system-provider");
|
|
36
|
-
const collaboration_color_service_1 = require("./collaboration-color-service");
|
|
37
|
-
const buffer_1 = require("@theia/core/lib/common/buffer");
|
|
38
|
-
const open_collaboration_yjs_1 = require("open-collaboration-yjs");
|
|
39
|
-
const mutex_1 = require("lib0/mutex");
|
|
40
|
-
const collaboration_utils_1 = require("./collaboration-utils");
|
|
41
|
-
const debounce = require("@theia/core/shared/lodash.debounce");
|
|
42
|
-
exports.CollaborationInstanceFactory = Symbol('CollaborationInstanceFactory');
|
|
43
|
-
exports.CollaborationInstanceOptions = Symbol('CollaborationInstanceOptions');
|
|
44
|
-
function createCollaborationInstanceContainer(parent, options) {
|
|
45
|
-
const child = new inversify_1.Container();
|
|
46
|
-
child.parent = parent;
|
|
47
|
-
child.bind(CollaborationInstance).toSelf().inTransientScope();
|
|
48
|
-
child.bind(exports.CollaborationInstanceOptions).toConstantValue(options);
|
|
49
|
-
return child;
|
|
50
|
-
}
|
|
51
|
-
exports.createCollaborationInstanceContainer = createCollaborationInstanceContainer;
|
|
52
|
-
exports.COLLABORATION_SELECTION = 'theia-collaboration-selection';
|
|
53
|
-
exports.COLLABORATION_SELECTION_MARKER = 'theia-collaboration-selection-marker';
|
|
54
|
-
exports.COLLABORATION_SELECTION_INVERTED = 'theia-collaboration-selection-inverted';
|
|
55
|
-
let CollaborationInstance = class CollaborationInstance {
|
|
56
|
-
constructor() {
|
|
57
|
-
this.identity = new promise_util_1.Deferred();
|
|
58
|
-
this.peers = new Map();
|
|
59
|
-
this.yjs = new Y.Doc();
|
|
60
|
-
this.yjsAwareness = new awarenessProtocol.Awareness(this.yjs);
|
|
61
|
-
this.colorIndex = 0;
|
|
62
|
-
this.editorDecorations = new Map();
|
|
63
|
-
this.permissions = {
|
|
64
|
-
readonly: false
|
|
65
|
-
};
|
|
66
|
-
this.onDidCloseEmitter = new core_1.Emitter();
|
|
67
|
-
this.toDispose = new core_1.DisposableCollection();
|
|
68
|
-
this._readonly = false;
|
|
69
|
-
this.yjsMutex = (0, mutex_1.createMutex)();
|
|
70
|
-
}
|
|
71
|
-
get onDidClose() {
|
|
72
|
-
return this.onDidCloseEmitter.event;
|
|
73
|
-
}
|
|
74
|
-
get readonly() {
|
|
75
|
-
return this._readonly;
|
|
76
|
-
}
|
|
77
|
-
set readonly(value) {
|
|
78
|
-
var _a;
|
|
79
|
-
if (value !== this.readonly) {
|
|
80
|
-
if (this.options.role === 'guest' && this.fileSystem) {
|
|
81
|
-
this.fileSystem.readonly = value;
|
|
82
|
-
}
|
|
83
|
-
else if (this.options.role === 'host') {
|
|
84
|
-
this.options.connection.room.updatePermissions({
|
|
85
|
-
...((_a = this.permissions) !== null && _a !== void 0 ? _a : {}),
|
|
86
|
-
readonly: value
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
if (this.permissions) {
|
|
90
|
-
this.permissions.readonly = value;
|
|
91
|
-
}
|
|
92
|
-
this._readonly = value;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
get isHost() {
|
|
96
|
-
return this.options.role === 'host';
|
|
97
|
-
}
|
|
98
|
-
get host() {
|
|
99
|
-
return Array.from(this.peers.values()).find(e => e.peer.host).peer;
|
|
100
|
-
}
|
|
101
|
-
init() {
|
|
102
|
-
const connection = this.options.connection;
|
|
103
|
-
connection.onDisconnect(() => this.dispose());
|
|
104
|
-
connection.onConnectionError(message => {
|
|
105
|
-
this.messageService.error(message);
|
|
106
|
-
this.dispose();
|
|
107
|
-
});
|
|
108
|
-
this.yjsProvider = new open_collaboration_yjs_1.OpenCollaborationYjsProvider(connection, this.yjs, this.yjsAwareness);
|
|
109
|
-
this.yjsProvider.connect();
|
|
110
|
-
this.toDispose.push(core_1.Disposable.create(() => this.yjs.destroy()));
|
|
111
|
-
this.toDispose.push(this.yjsProvider);
|
|
112
|
-
this.toDispose.push(connection);
|
|
113
|
-
this.toDispose.push(this.onDidCloseEmitter);
|
|
114
|
-
this.registerProtocolEvents(connection);
|
|
115
|
-
this.registerEditorEvents(connection);
|
|
116
|
-
this.registerFileSystemEvents(connection);
|
|
117
|
-
if (this.isHost) {
|
|
118
|
-
this.registerFileSystemChanges();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
registerProtocolEvents(connection) {
|
|
122
|
-
connection.peer.onJoinRequest(async (_, user) => {
|
|
123
|
-
var _a, _b;
|
|
124
|
-
const allow = core_1.nls.localizeByDefault('Allow');
|
|
125
|
-
const deny = core_1.nls.localizeByDefault('Deny');
|
|
126
|
-
const result = await this.messageService.info(core_1.nls.localize('theia/collaboration/userWantsToJoin', "User '{0}' wants to join the collaboration room", user.email ? `${user.name} (${user.email})` : user.name), allow, deny);
|
|
127
|
-
if (result === allow) {
|
|
128
|
-
const roots = await this.workspaceService.roots;
|
|
129
|
-
return {
|
|
130
|
-
workspace: {
|
|
131
|
-
name: (_b = (_a = this.workspaceService.workspace) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : core_1.nls.localize('theia/collaboration/collaboration', 'Collaboration'),
|
|
132
|
-
folders: roots.map(e => e.name)
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
return undefined;
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
connection.room.onJoin(async (_, peer) => {
|
|
141
|
-
var _a, _b;
|
|
142
|
-
this.addPeer(peer);
|
|
143
|
-
if (this.isHost) {
|
|
144
|
-
const roots = await this.workspaceService.roots;
|
|
145
|
-
const data = {
|
|
146
|
-
protocol: types.VERSION,
|
|
147
|
-
host: await this.identity.promise,
|
|
148
|
-
guests: Array.from(this.peers.values()).map(e => e.peer),
|
|
149
|
-
capabilities: {},
|
|
150
|
-
permissions: this.permissions,
|
|
151
|
-
workspace: {
|
|
152
|
-
name: (_b = (_a = this.workspaceService.workspace) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : core_1.nls.localize('theia/collaboration/collaboration', 'Collaboration'),
|
|
153
|
-
folders: roots.map(e => e.name)
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
connection.peer.init(peer.id, data);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
connection.room.onLeave((_, peer) => {
|
|
160
|
-
var _a;
|
|
161
|
-
(_a = this.peers.get(peer.id)) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
162
|
-
});
|
|
163
|
-
connection.room.onClose(() => {
|
|
164
|
-
this.dispose();
|
|
165
|
-
});
|
|
166
|
-
connection.room.onPermissions((_, permissions) => {
|
|
167
|
-
if (this.fileSystem) {
|
|
168
|
-
this.fileSystem.readonly = permissions.readonly;
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
connection.peer.onInfo((_, peer) => {
|
|
172
|
-
this.yjsAwareness.setLocalStateField('peer', peer.id);
|
|
173
|
-
this.identity.resolve(peer);
|
|
174
|
-
});
|
|
175
|
-
connection.peer.onInit(async (_, data) => {
|
|
176
|
-
await this.initialize(data);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
registerEditorEvents(connection) {
|
|
180
|
-
for (const model of this.monacoModelService.models) {
|
|
181
|
-
if (this.isSharedResource(new core_1.URI(model.uri))) {
|
|
182
|
-
this.registerModelUpdate(model);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
this.toDispose.push(this.monacoModelService.onDidCreate(newModel => {
|
|
186
|
-
if (this.isSharedResource(new core_1.URI(newModel.uri))) {
|
|
187
|
-
this.registerModelUpdate(newModel);
|
|
188
|
-
}
|
|
189
|
-
}));
|
|
190
|
-
this.toDispose.push(this.editorManager.onCreated(widget => {
|
|
191
|
-
if (this.isSharedResource(widget.getResourceUri())) {
|
|
192
|
-
this.registerPresenceUpdate(widget);
|
|
193
|
-
}
|
|
194
|
-
}));
|
|
195
|
-
this.getOpenEditors().forEach(widget => {
|
|
196
|
-
if (this.isSharedResource(widget.getResourceUri())) {
|
|
197
|
-
this.registerPresenceUpdate(widget);
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
this.shell.onDidChangeActiveWidget(e => {
|
|
201
|
-
if (e.newValue instanceof browser_1.EditorWidget) {
|
|
202
|
-
this.updateEditorPresence(e.newValue);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
this.yjsAwareness.on('change', () => {
|
|
206
|
-
this.rerenderPresence();
|
|
207
|
-
});
|
|
208
|
-
connection.editor.onOpen(async (_, path) => {
|
|
209
|
-
const uri = this.utils.getResourceUri(path);
|
|
210
|
-
if (uri) {
|
|
211
|
-
await this.openUri(uri);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
throw new Error('Could find file: ' + path);
|
|
215
|
-
}
|
|
216
|
-
return undefined;
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
isSharedResource(resource) {
|
|
220
|
-
if (!resource) {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
return this.isHost ? resource.scheme === 'file' : resource.scheme === collaboration_file_system_provider_1.CollaborationURI.scheme;
|
|
224
|
-
}
|
|
225
|
-
registerFileSystemEvents(connection) {
|
|
226
|
-
connection.fs.onReadFile(async (_, path) => {
|
|
227
|
-
const uri = this.utils.getResourceUri(path);
|
|
228
|
-
if (uri) {
|
|
229
|
-
const content = await this.fileService.readFile(uri);
|
|
230
|
-
return {
|
|
231
|
-
content: content.value.buffer
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
throw new Error('Could find file: ' + path);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
connection.fs.onReaddir(async (_, path) => {
|
|
239
|
-
const uri = this.utils.getResourceUri(path);
|
|
240
|
-
if (uri) {
|
|
241
|
-
const resolved = await this.fileService.resolve(uri);
|
|
242
|
-
if (resolved.children) {
|
|
243
|
-
const dir = {};
|
|
244
|
-
for (const child of resolved.children) {
|
|
245
|
-
dir[child.name] = child.isDirectory ? types.FileType.Directory : types.FileType.File;
|
|
246
|
-
}
|
|
247
|
-
return dir;
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
return {};
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
throw new Error('Could find directory: ' + path);
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
connection.fs.onStat(async (_, path) => {
|
|
258
|
-
const uri = this.utils.getResourceUri(path);
|
|
259
|
-
if (uri) {
|
|
260
|
-
const content = await this.fileService.resolve(uri, {
|
|
261
|
-
resolveMetadata: true
|
|
262
|
-
});
|
|
263
|
-
return {
|
|
264
|
-
type: content.isDirectory ? types.FileType.Directory : types.FileType.File,
|
|
265
|
-
ctime: content.ctime,
|
|
266
|
-
mtime: content.mtime,
|
|
267
|
-
size: content.size,
|
|
268
|
-
permissions: content.isReadonly ? types.FilePermission.Readonly : undefined
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
throw new Error('Could find file: ' + path);
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
connection.fs.onWriteFile(async (_, path, data) => {
|
|
276
|
-
const uri = this.utils.getResourceUri(path);
|
|
277
|
-
if (uri) {
|
|
278
|
-
const model = this.getModel(uri);
|
|
279
|
-
if (model) {
|
|
280
|
-
const content = new TextDecoder().decode(data.content);
|
|
281
|
-
if (content !== model.getText()) {
|
|
282
|
-
model.textEditorModel.setValue(content);
|
|
283
|
-
}
|
|
284
|
-
await model.save({ saveReason: browser_2.SaveReason.Manual });
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
await this.fileService.createFile(uri, buffer_1.BinaryBuffer.wrap(data.content));
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
throw new Error('Could find file: ' + path);
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
connection.fs.onMkdir(async (_, path) => {
|
|
295
|
-
const uri = this.utils.getResourceUri(path);
|
|
296
|
-
if (uri) {
|
|
297
|
-
await this.fileService.createFolder(uri);
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
throw new Error('Could find path: ' + path);
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
connection.fs.onDelete(async (_, path) => {
|
|
304
|
-
const uri = this.utils.getResourceUri(path);
|
|
305
|
-
if (uri) {
|
|
306
|
-
await this.fileService.delete(uri);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
throw new Error('Could find entry: ' + path);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
connection.fs.onRename(async (_, from, to) => {
|
|
313
|
-
const fromUri = this.utils.getResourceUri(from);
|
|
314
|
-
const toUri = this.utils.getResourceUri(to);
|
|
315
|
-
if (fromUri && toUri) {
|
|
316
|
-
await this.fileService.move(fromUri, toUri);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
throw new Error('Could find entries: ' + from + ' -> ' + to);
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
connection.fs.onChange(async (_, event) => {
|
|
323
|
-
// Only guests need to handle file system changes
|
|
324
|
-
if (!this.isHost && this.fileSystem) {
|
|
325
|
-
const changes = [];
|
|
326
|
-
for (const change of event.changes) {
|
|
327
|
-
const uri = this.utils.getResourceUri(change.path);
|
|
328
|
-
if (uri) {
|
|
329
|
-
changes.push({
|
|
330
|
-
type: change.type === types.FileChangeEventType.Create
|
|
331
|
-
? 1 /* FileChangeType.ADDED */
|
|
332
|
-
: change.type === types.FileChangeEventType.Update
|
|
333
|
-
? 0 /* FileChangeType.UPDATED */
|
|
334
|
-
: 2 /* FileChangeType.DELETED */,
|
|
335
|
-
resource: uri
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
this.fileSystem.triggerEvent(changes);
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
rerenderPresence(...widgets) {
|
|
344
|
-
const decorations = new Map();
|
|
345
|
-
const states = this.yjsAwareness.getStates();
|
|
346
|
-
for (const [clientID, state] of states.entries()) {
|
|
347
|
-
if (clientID === this.yjs.clientID) {
|
|
348
|
-
// Ignore own awareness state
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
const peer = state.peer;
|
|
352
|
-
if (!state.selection || !this.peers.has(peer)) {
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
if (!types.ClientTextSelection.is(state.selection)) {
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
const { path, textSelections } = state.selection;
|
|
359
|
-
const selection = textSelections[0];
|
|
360
|
-
if (!selection) {
|
|
361
|
-
continue;
|
|
362
|
-
}
|
|
363
|
-
const uri = this.utils.getResourceUri(path);
|
|
364
|
-
if (uri) {
|
|
365
|
-
const model = this.getModel(uri);
|
|
366
|
-
if (model) {
|
|
367
|
-
let existing = decorations.get(path);
|
|
368
|
-
if (!existing) {
|
|
369
|
-
existing = [];
|
|
370
|
-
decorations.set(path, existing);
|
|
371
|
-
}
|
|
372
|
-
const forward = selection.direction === types.SelectionDirection.LeftToRight;
|
|
373
|
-
let startIndex = Y.createAbsolutePositionFromRelativePosition(selection.start, this.yjs);
|
|
374
|
-
let endIndex = Y.createAbsolutePositionFromRelativePosition(selection.end, this.yjs);
|
|
375
|
-
if (startIndex && endIndex) {
|
|
376
|
-
if (startIndex.index > endIndex.index) {
|
|
377
|
-
[startIndex, endIndex] = [endIndex, startIndex];
|
|
378
|
-
}
|
|
379
|
-
const start = model.positionAt(startIndex.index);
|
|
380
|
-
const end = model.positionAt(endIndex.index);
|
|
381
|
-
const inverted = (forward && end.line === 0) || (!forward && start.line === 0);
|
|
382
|
-
const range = {
|
|
383
|
-
start,
|
|
384
|
-
end
|
|
385
|
-
};
|
|
386
|
-
const contentClassNames = [exports.COLLABORATION_SELECTION_MARKER, `${exports.COLLABORATION_SELECTION_MARKER}-${peer}`];
|
|
387
|
-
if (inverted) {
|
|
388
|
-
contentClassNames.push(exports.COLLABORATION_SELECTION_INVERTED);
|
|
389
|
-
}
|
|
390
|
-
const item = {
|
|
391
|
-
range,
|
|
392
|
-
options: {
|
|
393
|
-
className: `${exports.COLLABORATION_SELECTION} ${exports.COLLABORATION_SELECTION}-${peer}`,
|
|
394
|
-
beforeContentClassName: !forward ? contentClassNames.join(' ') : undefined,
|
|
395
|
-
afterContentClassName: forward ? contentClassNames.join(' ') : undefined,
|
|
396
|
-
stickiness: browser_1.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
existing.push(item);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
this.rerenderPresenceDecorations(decorations, ...widgets);
|
|
405
|
-
}
|
|
406
|
-
rerenderPresenceDecorations(decorations, ...widgets) {
|
|
407
|
-
var _a, _b;
|
|
408
|
-
for (const editor of new Set(this.getOpenEditors().concat(widgets))) {
|
|
409
|
-
const uri = editor.getResourceUri();
|
|
410
|
-
const path = this.utils.getProtocolPath(uri);
|
|
411
|
-
if (path) {
|
|
412
|
-
const old = (_a = this.editorDecorations.get(editor)) !== null && _a !== void 0 ? _a : [];
|
|
413
|
-
this.editorDecorations.set(editor, editor.editor.deltaDecorations({
|
|
414
|
-
newDecorations: (_b = decorations.get(path)) !== null && _b !== void 0 ? _b : [],
|
|
415
|
-
oldDecorations: old
|
|
416
|
-
}));
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
registerFileSystemChanges() {
|
|
421
|
-
// Event listener for disk based events
|
|
422
|
-
this.fileService.onDidFilesChange(event => {
|
|
423
|
-
const changes = [];
|
|
424
|
-
for (const change of event.changes) {
|
|
425
|
-
const path = this.utils.getProtocolPath(change.resource);
|
|
426
|
-
if (path) {
|
|
427
|
-
let type;
|
|
428
|
-
if (change.type === 1 /* FileChangeType.ADDED */) {
|
|
429
|
-
type = types.FileChangeEventType.Create;
|
|
430
|
-
}
|
|
431
|
-
else if (change.type === 2 /* FileChangeType.DELETED */) {
|
|
432
|
-
type = types.FileChangeEventType.Delete;
|
|
433
|
-
}
|
|
434
|
-
// Updates to files on disk are not sent
|
|
435
|
-
if (type !== undefined) {
|
|
436
|
-
changes.push({
|
|
437
|
-
path,
|
|
438
|
-
type
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
if (changes.length) {
|
|
444
|
-
this.options.connection.fs.change({ changes });
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
// Event listener for user based events
|
|
448
|
-
this.fileService.onDidRunOperation(operation => {
|
|
449
|
-
const path = this.utils.getProtocolPath(operation.resource);
|
|
450
|
-
if (!path) {
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
let type = types.FileChangeEventType.Update;
|
|
454
|
-
if (operation.isOperation(0 /* FileOperation.CREATE */) || operation.isOperation(3 /* FileOperation.COPY */)) {
|
|
455
|
-
type = types.FileChangeEventType.Create;
|
|
456
|
-
}
|
|
457
|
-
else if (operation.isOperation(1 /* FileOperation.DELETE */)) {
|
|
458
|
-
type = types.FileChangeEventType.Delete;
|
|
459
|
-
}
|
|
460
|
-
this.options.connection.fs.change({
|
|
461
|
-
changes: [{
|
|
462
|
-
path,
|
|
463
|
-
type
|
|
464
|
-
}]
|
|
465
|
-
});
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
async registerPresenceUpdate(widget) {
|
|
469
|
-
const uri = widget.getResourceUri();
|
|
470
|
-
const path = this.utils.getProtocolPath(uri);
|
|
471
|
-
if (path) {
|
|
472
|
-
if (!this.isHost) {
|
|
473
|
-
this.options.connection.editor.open(this.host.id, path);
|
|
474
|
-
}
|
|
475
|
-
let currentSelection = widget.editor.selection;
|
|
476
|
-
// // Update presence information when the selection changes
|
|
477
|
-
const selectionChange = widget.editor.onSelectionChanged(selection => {
|
|
478
|
-
if (!this.rangeEqual(currentSelection, selection)) {
|
|
479
|
-
this.updateEditorPresence(widget);
|
|
480
|
-
currentSelection = selection;
|
|
481
|
-
}
|
|
482
|
-
});
|
|
483
|
-
const widgetDispose = widget.onDidDispose(() => {
|
|
484
|
-
var _a;
|
|
485
|
-
widgetDispose.dispose();
|
|
486
|
-
selectionChange.dispose();
|
|
487
|
-
// Remove presence information when the editor closes
|
|
488
|
-
const state = this.yjsAwareness.getLocalState();
|
|
489
|
-
if (((_a = state === null || state === void 0 ? void 0 : state.currentSelection) === null || _a === void 0 ? void 0 : _a.path) === path) {
|
|
490
|
-
delete state.currentSelection;
|
|
491
|
-
}
|
|
492
|
-
this.yjsAwareness.setLocalState(state);
|
|
493
|
-
});
|
|
494
|
-
this.toDispose.push(selectionChange);
|
|
495
|
-
this.toDispose.push(widgetDispose);
|
|
496
|
-
this.rerenderPresence(widget);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
updateEditorPresence(widget) {
|
|
500
|
-
const uri = widget.getResourceUri();
|
|
501
|
-
const path = this.utils.getProtocolPath(uri);
|
|
502
|
-
if (path) {
|
|
503
|
-
const ytext = this.yjs.getText(path);
|
|
504
|
-
const selection = widget.editor.selection;
|
|
505
|
-
let start = widget.editor.document.offsetAt(selection.start);
|
|
506
|
-
let end = widget.editor.document.offsetAt(selection.end);
|
|
507
|
-
if (start > end) {
|
|
508
|
-
[start, end] = [end, start];
|
|
509
|
-
}
|
|
510
|
-
const direction = selection.direction === 'ltr'
|
|
511
|
-
? types.SelectionDirection.LeftToRight
|
|
512
|
-
: types.SelectionDirection.RightToLeft;
|
|
513
|
-
const editorSelection = {
|
|
514
|
-
start: Y.createRelativePositionFromTypeIndex(ytext, start),
|
|
515
|
-
end: Y.createRelativePositionFromTypeIndex(ytext, end),
|
|
516
|
-
direction
|
|
517
|
-
};
|
|
518
|
-
const textSelection = {
|
|
519
|
-
path,
|
|
520
|
-
textSelections: [editorSelection]
|
|
521
|
-
};
|
|
522
|
-
this.setSharedSelection(textSelection);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
setSharedSelection(selection) {
|
|
526
|
-
this.yjsAwareness.setLocalStateField('selection', selection);
|
|
527
|
-
}
|
|
528
|
-
rangeEqual(a, b) {
|
|
529
|
-
return a.start.line === b.start.line
|
|
530
|
-
&& a.start.character === b.start.character
|
|
531
|
-
&& a.end.line === b.end.line
|
|
532
|
-
&& a.end.character === b.end.character;
|
|
533
|
-
}
|
|
534
|
-
async initialize(data) {
|
|
535
|
-
this.permissions = data.permissions;
|
|
536
|
-
this.readonly = data.permissions.readonly;
|
|
537
|
-
for (const peer of [...data.guests, data.host]) {
|
|
538
|
-
this.addPeer(peer);
|
|
539
|
-
}
|
|
540
|
-
this.fileSystem = new collaboration_file_system_provider_1.CollaborationFileSystemProvider(this.options.connection, data.host, this.yjs);
|
|
541
|
-
this.fileSystem.readonly = this.readonly;
|
|
542
|
-
this.toDispose.push(this.fileService.registerProvider(collaboration_file_system_provider_1.CollaborationURI.scheme, this.fileSystem));
|
|
543
|
-
const workspaceDisposable = await this.workspaceService.setHostWorkspace(data.workspace, this.options.connection);
|
|
544
|
-
this.toDispose.push(workspaceDisposable);
|
|
545
|
-
}
|
|
546
|
-
addPeer(peer) {
|
|
547
|
-
const collection = new core_1.DisposableCollection();
|
|
548
|
-
collection.push(this.createPeerStyleSheet(peer));
|
|
549
|
-
collection.push(core_1.Disposable.create(() => this.peers.delete(peer.id)));
|
|
550
|
-
const disposablePeer = {
|
|
551
|
-
peer,
|
|
552
|
-
dispose: () => collection.dispose()
|
|
553
|
-
};
|
|
554
|
-
this.peers.set(peer.id, disposablePeer);
|
|
555
|
-
}
|
|
556
|
-
createPeerStyleSheet(peer) {
|
|
557
|
-
const style = browser_2.DecorationStyle.createStyleElement(`${peer.id}-collaboration-selection`);
|
|
558
|
-
const colors = this.collaborationColorService.getColors();
|
|
559
|
-
const sheet = style.sheet;
|
|
560
|
-
const color = colors[this.colorIndex++ % colors.length];
|
|
561
|
-
const colorString = `rgb(${color.r}, ${color.g}, ${color.b})`;
|
|
562
|
-
sheet.insertRule(`
|
|
563
|
-
.${exports.COLLABORATION_SELECTION}-${peer.id} {
|
|
564
|
-
opacity: 0.2;
|
|
565
|
-
background: ${colorString};
|
|
566
|
-
}
|
|
567
|
-
`);
|
|
568
|
-
sheet.insertRule(`
|
|
569
|
-
.${exports.COLLABORATION_SELECTION_MARKER}-${peer.id} {
|
|
570
|
-
background: ${colorString};
|
|
571
|
-
border-color: ${colorString};
|
|
572
|
-
}`);
|
|
573
|
-
sheet.insertRule(`
|
|
574
|
-
.${exports.COLLABORATION_SELECTION_MARKER}-${peer.id}::after {
|
|
575
|
-
content: "${peer.name}";
|
|
576
|
-
background: ${colorString};
|
|
577
|
-
color: ${this.collaborationColorService.requiresDarkFont(color)
|
|
578
|
-
? this.collaborationColorService.dark
|
|
579
|
-
: this.collaborationColorService.light};
|
|
580
|
-
z-index: ${(100 + this.colorIndex).toFixed()}
|
|
581
|
-
}`);
|
|
582
|
-
return core_1.Disposable.create(() => style.remove());
|
|
583
|
-
}
|
|
584
|
-
getOpenEditors(uri) {
|
|
585
|
-
const widgets = this.shell.widgets;
|
|
586
|
-
let editors = widgets.filter(e => e instanceof browser_1.EditorWidget);
|
|
587
|
-
if (uri) {
|
|
588
|
-
const uriString = uri.toString();
|
|
589
|
-
editors = editors.filter(e => { var _a; return ((_a = e.getResourceUri()) === null || _a === void 0 ? void 0 : _a.toString()) === uriString; });
|
|
590
|
-
}
|
|
591
|
-
return editors;
|
|
592
|
-
}
|
|
593
|
-
createSelectionFromRelative(selection, model) {
|
|
594
|
-
const start = Y.createAbsolutePositionFromRelativePosition(selection.start, this.yjs);
|
|
595
|
-
const end = Y.createAbsolutePositionFromRelativePosition(selection.end, this.yjs);
|
|
596
|
-
if (start && end) {
|
|
597
|
-
return {
|
|
598
|
-
start: model.positionAt(start.index),
|
|
599
|
-
end: model.positionAt(end.index),
|
|
600
|
-
direction: selection.direction === types.SelectionDirection.LeftToRight ? 'ltr' : 'rtl'
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
return undefined;
|
|
604
|
-
}
|
|
605
|
-
createRelativeSelection(selection, model, ytext) {
|
|
606
|
-
const start = Y.createRelativePositionFromTypeIndex(ytext, model.offsetAt(selection.start));
|
|
607
|
-
const end = Y.createRelativePositionFromTypeIndex(ytext, model.offsetAt(selection.end));
|
|
608
|
-
return {
|
|
609
|
-
start,
|
|
610
|
-
end,
|
|
611
|
-
direction: selection.direction === 'ltr'
|
|
612
|
-
? types.SelectionDirection.LeftToRight
|
|
613
|
-
: types.SelectionDirection.RightToLeft
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
registerModelUpdate(model) {
|
|
617
|
-
let updating = false;
|
|
618
|
-
const modelPath = this.utils.getProtocolPath(new core_1.URI(model.uri));
|
|
619
|
-
if (!modelPath) {
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
const unknownModel = !this.yjs.share.has(modelPath);
|
|
623
|
-
const ytext = this.yjs.getText(modelPath);
|
|
624
|
-
const modelText = model.textEditorModel.getValue();
|
|
625
|
-
if (this.isHost && unknownModel) {
|
|
626
|
-
// If we are hosting the room, set the initial content
|
|
627
|
-
// First off, reset the shared content to be empty
|
|
628
|
-
// This has the benefit of effectively clearing the memory of the shared content across all peers
|
|
629
|
-
// This is important because the shared content accumulates changes/memory usage over time
|
|
630
|
-
this.resetYjsText(ytext, modelText);
|
|
631
|
-
}
|
|
632
|
-
else {
|
|
633
|
-
this.options.connection.editor.open(this.host.id, modelPath);
|
|
634
|
-
}
|
|
635
|
-
// The Ytext instance is our source of truth for the model content
|
|
636
|
-
// Sometimes (especially after a lot of sequential undo/redo operations) our model content can get out of sync
|
|
637
|
-
// This resyncs the model content with the Ytext content after a delay
|
|
638
|
-
const resyncDebounce = debounce(() => {
|
|
639
|
-
this.yjsMutex(() => {
|
|
640
|
-
const newContent = ytext.toString();
|
|
641
|
-
if (model.textEditorModel.getValue() !== newContent) {
|
|
642
|
-
updating = true;
|
|
643
|
-
this.softReplaceModel(model, newContent);
|
|
644
|
-
updating = false;
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
}, 200);
|
|
648
|
-
const disposable = new core_1.DisposableCollection();
|
|
649
|
-
disposable.push(model.onDidChangeContent(e => {
|
|
650
|
-
if (updating) {
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
this.yjsMutex(() => {
|
|
654
|
-
this.yjs.transact(() => {
|
|
655
|
-
for (const change of e.contentChanges) {
|
|
656
|
-
ytext.delete(change.rangeOffset, change.rangeLength);
|
|
657
|
-
ytext.insert(change.rangeOffset, change.text);
|
|
658
|
-
}
|
|
659
|
-
});
|
|
660
|
-
resyncDebounce();
|
|
661
|
-
});
|
|
662
|
-
}));
|
|
663
|
-
const observer = (textEvent) => {
|
|
664
|
-
if (textEvent.transaction.local || model.getText() === ytext.toString()) {
|
|
665
|
-
// Ignore local changes and changes that are already reflected in the model
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
this.yjsMutex(() => {
|
|
669
|
-
updating = true;
|
|
670
|
-
try {
|
|
671
|
-
let index = 0;
|
|
672
|
-
const operations = [];
|
|
673
|
-
textEvent.delta.forEach(delta => {
|
|
674
|
-
if (delta.retain !== undefined) {
|
|
675
|
-
index += delta.retain;
|
|
676
|
-
}
|
|
677
|
-
else if (delta.insert !== undefined) {
|
|
678
|
-
const pos = model.textEditorModel.getPositionAt(index);
|
|
679
|
-
const range = new monaco_editor_core_1.Range(pos.lineNumber, pos.column, pos.lineNumber, pos.column);
|
|
680
|
-
const insert = delta.insert;
|
|
681
|
-
operations.push({ range, text: insert });
|
|
682
|
-
index += insert.length;
|
|
683
|
-
}
|
|
684
|
-
else if (delta.delete !== undefined) {
|
|
685
|
-
const pos = model.textEditorModel.getPositionAt(index);
|
|
686
|
-
const endPos = model.textEditorModel.getPositionAt(index + delta.delete);
|
|
687
|
-
const range = new monaco_editor_core_1.Range(pos.lineNumber, pos.column, endPos.lineNumber, endPos.column);
|
|
688
|
-
operations.push({ range, text: '' });
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
this.pushChangesToModel(model, operations);
|
|
692
|
-
}
|
|
693
|
-
catch (err) {
|
|
694
|
-
console.error(err);
|
|
695
|
-
}
|
|
696
|
-
resyncDebounce();
|
|
697
|
-
updating = false;
|
|
698
|
-
});
|
|
699
|
-
};
|
|
700
|
-
ytext.observe(observer);
|
|
701
|
-
disposable.push(core_1.Disposable.create(() => ytext.unobserve(observer)));
|
|
702
|
-
model.onDispose(() => disposable.dispose());
|
|
703
|
-
}
|
|
704
|
-
resetYjsText(yjsText, text) {
|
|
705
|
-
this.yjs.transact(() => {
|
|
706
|
-
yjsText.delete(0, yjsText.length);
|
|
707
|
-
yjsText.insert(0, text);
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
getModel(uri) {
|
|
711
|
-
const existing = this.monacoModelService.models.find(e => e.uri === uri.toString());
|
|
712
|
-
if (existing) {
|
|
713
|
-
return existing;
|
|
714
|
-
}
|
|
715
|
-
else {
|
|
716
|
-
return undefined;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
pushChangesToModel(model, changes) {
|
|
720
|
-
var _a;
|
|
721
|
-
const editor = monaco_editor_1.MonacoEditor.findByDocument(this.editorManager, model)[0];
|
|
722
|
-
const cursorState = (_a = editor === null || editor === void 0 ? void 0 : editor.getControl().getSelections()) !== null && _a !== void 0 ? _a : [];
|
|
723
|
-
model.textEditorModel.pushStackElement();
|
|
724
|
-
try {
|
|
725
|
-
model.textEditorModel.pushEditOperations(cursorState, changes, () => cursorState);
|
|
726
|
-
model.textEditorModel.pushStackElement();
|
|
727
|
-
}
|
|
728
|
-
catch (err) {
|
|
729
|
-
console.error(err);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
softReplaceModel(model, text) {
|
|
733
|
-
this.pushChangesToModel(model, [{
|
|
734
|
-
range: model.textEditorModel.getFullModelRange(),
|
|
735
|
-
text,
|
|
736
|
-
forceMoveMarkers: false
|
|
737
|
-
}]);
|
|
738
|
-
}
|
|
739
|
-
async openUri(uri) {
|
|
740
|
-
const ref = await this.monacoModelService.createModelReference(uri);
|
|
741
|
-
if (ref.object) {
|
|
742
|
-
this.toDispose.push(ref);
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
ref.dispose();
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
dispose() {
|
|
749
|
-
for (const peer of this.peers.values()) {
|
|
750
|
-
peer.dispose();
|
|
751
|
-
}
|
|
752
|
-
this.onDidCloseEmitter.fire();
|
|
753
|
-
this.toDispose.dispose();
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
exports.CollaborationInstance = CollaborationInstance;
|
|
757
|
-
tslib_1.__decorate([
|
|
758
|
-
(0, inversify_1.inject)(core_1.MessageService),
|
|
759
|
-
tslib_1.__metadata("design:type", core_1.MessageService)
|
|
760
|
-
], CollaborationInstance.prototype, "messageService", void 0);
|
|
761
|
-
tslib_1.__decorate([
|
|
762
|
-
(0, inversify_1.inject)(collaboration_workspace_service_1.CollaborationWorkspaceService),
|
|
763
|
-
tslib_1.__metadata("design:type", collaboration_workspace_service_1.CollaborationWorkspaceService)
|
|
764
|
-
], CollaborationInstance.prototype, "workspaceService", void 0);
|
|
765
|
-
tslib_1.__decorate([
|
|
766
|
-
(0, inversify_1.inject)(file_service_1.FileService),
|
|
767
|
-
tslib_1.__metadata("design:type", file_service_1.FileService)
|
|
768
|
-
], CollaborationInstance.prototype, "fileService", void 0);
|
|
769
|
-
tslib_1.__decorate([
|
|
770
|
-
(0, inversify_1.inject)(monaco_text_model_service_1.MonacoTextModelService),
|
|
771
|
-
tslib_1.__metadata("design:type", monaco_text_model_service_1.MonacoTextModelService)
|
|
772
|
-
], CollaborationInstance.prototype, "monacoModelService", void 0);
|
|
773
|
-
tslib_1.__decorate([
|
|
774
|
-
(0, inversify_1.inject)(editor_manager_1.EditorManager),
|
|
775
|
-
tslib_1.__metadata("design:type", editor_manager_1.EditorManager)
|
|
776
|
-
], CollaborationInstance.prototype, "editorManager", void 0);
|
|
777
|
-
tslib_1.__decorate([
|
|
778
|
-
(0, inversify_1.inject)(browser_2.OpenerService),
|
|
779
|
-
tslib_1.__metadata("design:type", Object)
|
|
780
|
-
], CollaborationInstance.prototype, "openerService", void 0);
|
|
781
|
-
tslib_1.__decorate([
|
|
782
|
-
(0, inversify_1.inject)(application_shell_1.ApplicationShell),
|
|
783
|
-
tslib_1.__metadata("design:type", application_shell_1.ApplicationShell)
|
|
784
|
-
], CollaborationInstance.prototype, "shell", void 0);
|
|
785
|
-
tslib_1.__decorate([
|
|
786
|
-
(0, inversify_1.inject)(exports.CollaborationInstanceOptions),
|
|
787
|
-
tslib_1.__metadata("design:type", Object)
|
|
788
|
-
], CollaborationInstance.prototype, "options", void 0);
|
|
789
|
-
tslib_1.__decorate([
|
|
790
|
-
(0, inversify_1.inject)(collaboration_color_service_1.CollaborationColorService),
|
|
791
|
-
tslib_1.__metadata("design:type", collaboration_color_service_1.CollaborationColorService)
|
|
792
|
-
], CollaborationInstance.prototype, "collaborationColorService", void 0);
|
|
793
|
-
tslib_1.__decorate([
|
|
794
|
-
(0, inversify_1.inject)(collaboration_utils_1.CollaborationUtils),
|
|
795
|
-
tslib_1.__metadata("design:type", collaboration_utils_1.CollaborationUtils)
|
|
796
|
-
], CollaborationInstance.prototype, "utils", void 0);
|
|
797
|
-
tslib_1.__decorate([
|
|
798
|
-
(0, inversify_1.postConstruct)(),
|
|
799
|
-
tslib_1.__metadata("design:type", Function),
|
|
800
|
-
tslib_1.__metadata("design:paramtypes", []),
|
|
801
|
-
tslib_1.__metadata("design:returntype", void 0)
|
|
802
|
-
], CollaborationInstance.prototype, "init", null);
|
|
803
|
-
exports.CollaborationInstance = CollaborationInstance = tslib_1.__decorate([
|
|
804
|
-
(0, inversify_1.injectable)()
|
|
805
|
-
], CollaborationInstance);
|
|
806
|
-
//# sourceMappingURL=collaboration-instance.js.map
|