document-drive 1.0.0-websockets → 1.0.0
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 -0
- package/package.json +74 -88
- package/src/cache/index.ts +2 -2
- package/src/cache/memory.ts +22 -13
- package/src/cache/redis.ts +43 -16
- package/src/cache/types.ts +4 -4
- package/src/index.ts +6 -3
- package/src/queue/base.ts +276 -214
- package/src/queue/index.ts +2 -2
- package/src/queue/redis.ts +138 -127
- package/src/queue/types.ts +44 -38
- package/src/read-mode/errors.ts +19 -0
- package/src/read-mode/index.ts +125 -0
- package/src/read-mode/service.ts +207 -0
- package/src/read-mode/types.ts +108 -0
- package/src/server/error.ts +61 -26
- package/src/server/index.ts +2160 -1785
- package/src/server/listener/index.ts +2 -2
- package/src/server/listener/manager.ts +475 -437
- package/src/server/listener/transmitter/index.ts +4 -5
- package/src/server/listener/transmitter/internal.ts +77 -79
- package/src/server/listener/transmitter/pull-responder.ts +363 -329
- package/src/server/listener/transmitter/switchboard-push.ts +72 -55
- package/src/server/listener/transmitter/types.ts +19 -25
- package/src/server/types.ts +536 -349
- package/src/server/utils.ts +26 -27
- package/src/storage/base.ts +81 -0
- package/src/storage/browser.ts +233 -216
- package/src/storage/filesystem.ts +257 -256
- package/src/storage/index.ts +2 -1
- package/src/storage/memory.ts +206 -214
- package/src/storage/prisma.ts +575 -568
- package/src/storage/sequelize.ts +460 -471
- package/src/storage/types.ts +83 -67
- package/src/utils/default-drives-manager.ts +341 -0
- package/src/utils/document-helpers.ts +19 -18
- package/src/utils/graphql.ts +288 -34
- package/src/utils/index.ts +61 -59
- package/src/utils/logger.ts +39 -37
- package/src/utils/migrations.ts +58 -0
- package/src/utils/run-asap.ts +156 -0
- package/CHANGELOG.md +0 -818
- package/src/server/listener/transmitter/subscription.ts +0 -364
package/src/storage/types.ts
CHANGED
|
@@ -1,81 +1,97 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from
|
|
2
|
+
DocumentDriveAction,
|
|
3
|
+
DocumentDriveDocument,
|
|
4
|
+
} from "document-model-libs/document-drive";
|
|
5
5
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from
|
|
13
|
-
import type { SynchronizationUnitQuery } from
|
|
6
|
+
Action,
|
|
7
|
+
BaseAction,
|
|
8
|
+
Document,
|
|
9
|
+
DocumentHeader,
|
|
10
|
+
DocumentOperations,
|
|
11
|
+
Operation,
|
|
12
|
+
} from "document-model/document";
|
|
13
|
+
import type { SynchronizationUnitQuery } from "../server/types";
|
|
14
14
|
|
|
15
15
|
export type DocumentStorage<D extends Document = Document> = Omit<
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
D,
|
|
17
|
+
"attachments"
|
|
18
18
|
>;
|
|
19
19
|
|
|
20
20
|
export type DocumentDriveStorage = DocumentStorage<DocumentDriveDocument>;
|
|
21
21
|
|
|
22
22
|
export interface IStorageDelegate {
|
|
23
|
-
|
|
23
|
+
getCachedOperations(
|
|
24
|
+
drive: string,
|
|
25
|
+
id: string,
|
|
26
|
+
): Promise<DocumentOperations<Action> | undefined>;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export interface IStorage {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
30
|
+
checkDocumentExists(drive: string, id: string): Promise<boolean>;
|
|
31
|
+
getDocuments: (drive: string) => Promise<string[]>;
|
|
32
|
+
getDocument(drive: string, id: string): Promise<DocumentStorage>;
|
|
33
|
+
createDocument(
|
|
34
|
+
drive: string,
|
|
35
|
+
id: string,
|
|
36
|
+
document: DocumentStorage,
|
|
37
|
+
): Promise<void>;
|
|
38
|
+
addDocumentOperations(
|
|
39
|
+
drive: string,
|
|
40
|
+
id: string,
|
|
41
|
+
operations: Operation[],
|
|
42
|
+
header: DocumentHeader,
|
|
43
|
+
): Promise<void>;
|
|
44
|
+
addDocumentOperationsWithTransaction?(
|
|
45
|
+
drive: string,
|
|
46
|
+
id: string,
|
|
47
|
+
callback: (document: DocumentStorage) => Promise<{
|
|
48
|
+
operations: Operation[];
|
|
49
|
+
header: DocumentHeader;
|
|
50
|
+
}>,
|
|
51
|
+
): Promise<void>;
|
|
52
|
+
deleteDocument(drive: string, id: string): Promise<void>;
|
|
53
|
+
getOperationResultingState?(
|
|
54
|
+
drive: string,
|
|
55
|
+
id: string,
|
|
56
|
+
index: number,
|
|
57
|
+
scope: string,
|
|
58
|
+
branch: string,
|
|
59
|
+
): Promise<unknown>;
|
|
60
|
+
setStorageDelegate?(delegate: IStorageDelegate): void;
|
|
61
|
+
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<
|
|
62
|
+
{
|
|
63
|
+
driveId: string;
|
|
64
|
+
documentId: string;
|
|
65
|
+
scope: string;
|
|
66
|
+
branch: string;
|
|
67
|
+
lastUpdated: string;
|
|
68
|
+
revision: number;
|
|
69
|
+
}[]
|
|
70
|
+
>;
|
|
60
71
|
}
|
|
61
72
|
export interface IDriveStorage extends IStorage {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
getDrives(): Promise<string[]>;
|
|
74
|
+
getDrive(id: string): Promise<DocumentDriveStorage>;
|
|
75
|
+
getDriveBySlug(slug: string): Promise<DocumentDriveStorage>;
|
|
76
|
+
createDrive(id: string, drive: DocumentDriveStorage): Promise<void>;
|
|
77
|
+
deleteDrive(id: string): Promise<void>;
|
|
78
|
+
clearStorage?(): Promise<void>;
|
|
79
|
+
addDriveOperations(
|
|
80
|
+
id: string,
|
|
81
|
+
operations: Operation<DocumentDriveAction | BaseAction>[],
|
|
82
|
+
header: DocumentHeader,
|
|
83
|
+
): Promise<void>;
|
|
84
|
+
addDriveOperationsWithTransaction?(
|
|
85
|
+
drive: string,
|
|
86
|
+
callback: (document: DocumentDriveStorage) => Promise<{
|
|
87
|
+
operations: Operation[];
|
|
88
|
+
header: DocumentHeader;
|
|
89
|
+
}>,
|
|
90
|
+
): Promise<void>;
|
|
91
|
+
getDriveOperationResultingState?(
|
|
92
|
+
drive: string,
|
|
93
|
+
index: number,
|
|
94
|
+
scope: string,
|
|
95
|
+
branch: string,
|
|
96
|
+
): Promise<unknown>;
|
|
97
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DefaultRemoteDriveInfo,
|
|
3
|
+
DocumentDriveServerOptions,
|
|
4
|
+
DriveEvents,
|
|
5
|
+
IBaseDocumentDriveServer,
|
|
6
|
+
IReadModeDriveServer,
|
|
7
|
+
RemoteDriveAccessLevel,
|
|
8
|
+
RemoveDriveStrategy,
|
|
9
|
+
RemoveOldRemoteDrivesOption,
|
|
10
|
+
} from "../server";
|
|
11
|
+
import { DriveNotFoundError } from "../server/error";
|
|
12
|
+
import { requestPublicDrive } from "./graphql";
|
|
13
|
+
import { logger } from "./logger";
|
|
14
|
+
|
|
15
|
+
export interface IServerDelegateDrivesManager {
|
|
16
|
+
emit: (...args: Parameters<DriveEvents["defaultRemoteDrive"]>) => void;
|
|
17
|
+
detachDrive: (driveId: string) => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isReadModeDriveServer(obj: unknown): obj is IReadModeDriveServer {
|
|
21
|
+
return typeof (obj as IReadModeDriveServer).getReadDrives === "function";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IDefaultDrivesManager {
|
|
25
|
+
initializeDefaultRemoteDrives(): Promise<void>;
|
|
26
|
+
getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
|
|
27
|
+
setDefaultDriveAccessLevel(
|
|
28
|
+
url: string,
|
|
29
|
+
level: RemoteDriveAccessLevel,
|
|
30
|
+
): Promise<void>;
|
|
31
|
+
setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class DefaultDrivesManager implements IDefaultDrivesManager {
|
|
35
|
+
private defaultRemoteDrives = new Map<string, DefaultRemoteDriveInfo>();
|
|
36
|
+
private removeOldRemoteDrivesConfig: RemoveOldRemoteDrivesOption;
|
|
37
|
+
|
|
38
|
+
constructor(
|
|
39
|
+
private server:
|
|
40
|
+
| IBaseDocumentDriveServer
|
|
41
|
+
| (IBaseDocumentDriveServer & IReadModeDriveServer),
|
|
42
|
+
private delegate: IServerDelegateDrivesManager,
|
|
43
|
+
options?: Pick<DocumentDriveServerOptions, "defaultDrives">,
|
|
44
|
+
) {
|
|
45
|
+
if (options?.defaultDrives.remoteDrives) {
|
|
46
|
+
for (const defaultDrive of options.defaultDrives.remoteDrives) {
|
|
47
|
+
this.defaultRemoteDrives.set(defaultDrive.url, {
|
|
48
|
+
...defaultDrive,
|
|
49
|
+
status: "PENDING",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.removeOldRemoteDrivesConfig = options?.defaultDrives
|
|
55
|
+
.removeOldRemoteDrives || {
|
|
56
|
+
strategy: "preserve-all",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getDefaultRemoteDrives() {
|
|
61
|
+
return new Map(
|
|
62
|
+
JSON.parse(
|
|
63
|
+
JSON.stringify(Array.from(this.defaultRemoteDrives)),
|
|
64
|
+
) as Iterable<[string, DefaultRemoteDriveInfo]>,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private async deleteDriveById(driveId: string) {
|
|
69
|
+
try {
|
|
70
|
+
await this.server.deleteDrive(driveId);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
if (!(error instanceof DriveNotFoundError)) {
|
|
73
|
+
logger.error(error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private async preserveDrivesById(
|
|
79
|
+
driveIdsToPreserve: string[],
|
|
80
|
+
drives: string[],
|
|
81
|
+
removeStrategy: RemoveDriveStrategy = "detach",
|
|
82
|
+
) {
|
|
83
|
+
const getAllDrives = drives.map((driveId) => this.server.getDrive(driveId));
|
|
84
|
+
|
|
85
|
+
const drivesToRemove = (await Promise.all(getAllDrives))
|
|
86
|
+
.filter(
|
|
87
|
+
(drive) =>
|
|
88
|
+
drive.state.local.listeners.length > 0 ||
|
|
89
|
+
drive.state.local.triggers.length > 0,
|
|
90
|
+
)
|
|
91
|
+
.filter((drive) => !driveIdsToPreserve.includes(drive.state.global.id));
|
|
92
|
+
|
|
93
|
+
const driveIds = drivesToRemove.map((drive) => drive.state.global.id);
|
|
94
|
+
|
|
95
|
+
if (removeStrategy === "detach") {
|
|
96
|
+
await this.detachDrivesById(driveIds);
|
|
97
|
+
} else {
|
|
98
|
+
await this.removeDrivesById(driveIds);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async removeDrivesById(driveIds: string[]) {
|
|
103
|
+
for (const driveId of driveIds) {
|
|
104
|
+
await this.deleteDriveById(driveId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private async detachDrivesById(driveIds: string[]) {
|
|
109
|
+
const detachDrivesPromises = driveIds.map((driveId) =>
|
|
110
|
+
this.delegate.detachDrive(driveId),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
await Promise.all(detachDrivesPromises);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async removeOldremoteDrives() {
|
|
117
|
+
const driveids = await this.server.getDrives();
|
|
118
|
+
|
|
119
|
+
switch (this.removeOldRemoteDrivesConfig.strategy) {
|
|
120
|
+
case "preserve-by-id-and-detach":
|
|
121
|
+
case "preserve-by-id": {
|
|
122
|
+
const detach: RemoveDriveStrategy =
|
|
123
|
+
this.removeOldRemoteDrivesConfig.strategy ===
|
|
124
|
+
"preserve-by-id-and-detach"
|
|
125
|
+
? "detach"
|
|
126
|
+
: "remove";
|
|
127
|
+
|
|
128
|
+
await this.preserveDrivesById(
|
|
129
|
+
this.removeOldRemoteDrivesConfig.ids,
|
|
130
|
+
driveids,
|
|
131
|
+
detach,
|
|
132
|
+
);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "preserve-by-url-and-detach":
|
|
136
|
+
case "preserve-by-url": {
|
|
137
|
+
const detach: RemoveDriveStrategy =
|
|
138
|
+
this.removeOldRemoteDrivesConfig.strategy ===
|
|
139
|
+
"preserve-by-url-and-detach"
|
|
140
|
+
? "detach"
|
|
141
|
+
: "remove";
|
|
142
|
+
|
|
143
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((url) =>
|
|
144
|
+
requestPublicDrive(url),
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const drivesIdsToPreserve = (await Promise.all(getDrivesInfo)).map(
|
|
148
|
+
(driveInfo) => driveInfo.id,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
await this.preserveDrivesById(drivesIdsToPreserve, driveids, detach);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "remove-by-id": {
|
|
155
|
+
const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter(
|
|
156
|
+
(driveId) => driveids.includes(driveId),
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
await this.removeDrivesById(drivesIdsToRemove);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "remove-by-url": {
|
|
163
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map(
|
|
164
|
+
(driveUrl) => requestPublicDrive(driveUrl),
|
|
165
|
+
);
|
|
166
|
+
const drivesInfo = await Promise.all(getDrivesInfo);
|
|
167
|
+
|
|
168
|
+
const drivesIdsToRemove = drivesInfo
|
|
169
|
+
.map((driveInfo) => driveInfo.id)
|
|
170
|
+
.filter((driveId) => driveids.includes(driveId));
|
|
171
|
+
|
|
172
|
+
await this.removeDrivesById(drivesIdsToRemove);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case "remove-all": {
|
|
176
|
+
const getDrives = driveids.map((driveId) =>
|
|
177
|
+
this.server.getDrive(driveId),
|
|
178
|
+
);
|
|
179
|
+
const drives = await Promise.all(getDrives);
|
|
180
|
+
const drivesToRemove = drives
|
|
181
|
+
.filter(
|
|
182
|
+
(drive) =>
|
|
183
|
+
drive.state.local.listeners.length > 0 ||
|
|
184
|
+
drive.state.local.triggers.length > 0,
|
|
185
|
+
)
|
|
186
|
+
.map((drive) => drive.state.global.id);
|
|
187
|
+
|
|
188
|
+
await this.removeDrivesById(drivesToRemove);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case "detach-by-id": {
|
|
192
|
+
const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter(
|
|
193
|
+
(driveId) => driveids.includes(driveId),
|
|
194
|
+
);
|
|
195
|
+
const detachDrivesPromises = drivesIdsToRemove.map((driveId) =>
|
|
196
|
+
this.delegate.detachDrive(driveId),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
await Promise.all(detachDrivesPromises);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case "detach-by-url": {
|
|
203
|
+
const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map(
|
|
204
|
+
(driveUrl) => requestPublicDrive(driveUrl),
|
|
205
|
+
);
|
|
206
|
+
const drivesInfo = await Promise.all(getDrivesInfo);
|
|
207
|
+
|
|
208
|
+
const drivesIdsToRemove = drivesInfo
|
|
209
|
+
.map((driveInfo) => driveInfo.id)
|
|
210
|
+
.filter((driveId) => driveids.includes(driveId));
|
|
211
|
+
|
|
212
|
+
const detachDrivesPromises = drivesIdsToRemove.map((driveId) =>
|
|
213
|
+
this.delegate.detachDrive(driveId),
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
await Promise.all(detachDrivesPromises);
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel) {
|
|
223
|
+
const drives = this.defaultRemoteDrives.values();
|
|
224
|
+
for (const drive of drives) {
|
|
225
|
+
await this.setDefaultDriveAccessLevel(drive.url, level);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel) {
|
|
230
|
+
const drive = this.defaultRemoteDrives.get(url);
|
|
231
|
+
if (drive && drive.options.accessLevel !== level) {
|
|
232
|
+
const newDriveValue = {
|
|
233
|
+
...drive,
|
|
234
|
+
options: { ...drive.options, accessLevel: level },
|
|
235
|
+
};
|
|
236
|
+
this.defaultRemoteDrives.set(url, newDriveValue);
|
|
237
|
+
await this.initializeDefaultRemoteDrives([newDriveValue]);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async initializeDefaultRemoteDrives(
|
|
242
|
+
defaultDrives: DefaultRemoteDriveInfo[] = Array.from(
|
|
243
|
+
this.defaultRemoteDrives.values(),
|
|
244
|
+
),
|
|
245
|
+
) {
|
|
246
|
+
const drives = await this.server.getDrives();
|
|
247
|
+
const readServer = isReadModeDriveServer(this.server)
|
|
248
|
+
? (this.server as IReadModeDriveServer)
|
|
249
|
+
: undefined;
|
|
250
|
+
const readDrives = await readServer?.getReadDrives();
|
|
251
|
+
|
|
252
|
+
for (const remoteDrive of defaultDrives) {
|
|
253
|
+
let remoteDriveInfo = { ...remoteDrive };
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const driveInfo =
|
|
257
|
+
remoteDrive.metadata ?? (await requestPublicDrive(remoteDrive.url));
|
|
258
|
+
|
|
259
|
+
remoteDriveInfo = { ...remoteDrive, metadata: driveInfo };
|
|
260
|
+
|
|
261
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
262
|
+
|
|
263
|
+
const driveIsAdded = drives.includes(driveInfo.id);
|
|
264
|
+
const readDriveIsAdded = readDrives?.includes(driveInfo.id);
|
|
265
|
+
|
|
266
|
+
const hasAccessLevel = remoteDrive.options.accessLevel !== undefined;
|
|
267
|
+
const readMode =
|
|
268
|
+
readServer && remoteDrive.options.accessLevel === "READ";
|
|
269
|
+
const isAdded = readMode ? readDriveIsAdded : driveIsAdded;
|
|
270
|
+
|
|
271
|
+
// if the read mode has changed then existing drives
|
|
272
|
+
// in the previous mode should be deleted
|
|
273
|
+
const driveToDelete =
|
|
274
|
+
hasAccessLevel && (readMode ? driveIsAdded : readDriveIsAdded);
|
|
275
|
+
if (driveToDelete) {
|
|
276
|
+
try {
|
|
277
|
+
await (readMode
|
|
278
|
+
? this.server.deleteDrive(driveInfo.id)
|
|
279
|
+
: readServer?.deleteReadDrive(driveInfo.id));
|
|
280
|
+
} catch (e) {
|
|
281
|
+
logger.error(e);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (isAdded) {
|
|
286
|
+
remoteDriveInfo.status = "ALREADY_ADDED";
|
|
287
|
+
|
|
288
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
289
|
+
this.delegate.emit(
|
|
290
|
+
"ALREADY_ADDED",
|
|
291
|
+
this.defaultRemoteDrives,
|
|
292
|
+
remoteDriveInfo,
|
|
293
|
+
driveInfo.id,
|
|
294
|
+
driveInfo.name,
|
|
295
|
+
);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
remoteDriveInfo.status = "ADDING";
|
|
300
|
+
|
|
301
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
302
|
+
this.delegate.emit("ADDING", this.defaultRemoteDrives, remoteDriveInfo);
|
|
303
|
+
|
|
304
|
+
if ((!hasAccessLevel && readServer) || readMode) {
|
|
305
|
+
await readServer.addReadDrive(remoteDrive.url, {
|
|
306
|
+
...remoteDrive.options,
|
|
307
|
+
expectedDriveInfo: driveInfo,
|
|
308
|
+
});
|
|
309
|
+
} else {
|
|
310
|
+
await this.server.addRemoteDrive(remoteDrive.url, {
|
|
311
|
+
...remoteDrive.options,
|
|
312
|
+
expectedDriveInfo: driveInfo,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
remoteDriveInfo.status = "SUCCESS";
|
|
317
|
+
|
|
318
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
319
|
+
this.delegate.emit(
|
|
320
|
+
"SUCCESS",
|
|
321
|
+
this.defaultRemoteDrives,
|
|
322
|
+
remoteDriveInfo,
|
|
323
|
+
driveInfo.id,
|
|
324
|
+
driveInfo.name,
|
|
325
|
+
);
|
|
326
|
+
} catch (error) {
|
|
327
|
+
remoteDriveInfo.status = "ERROR";
|
|
328
|
+
|
|
329
|
+
this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
|
|
330
|
+
this.delegate.emit(
|
|
331
|
+
"ERROR",
|
|
332
|
+
this.defaultRemoteDrives,
|
|
333
|
+
remoteDriveInfo,
|
|
334
|
+
undefined,
|
|
335
|
+
undefined,
|
|
336
|
+
error as Error,
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { utils } from
|
|
1
|
+
import { utils } from "document-model/document";
|
|
2
2
|
|
|
3
|
-
export const {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
export const {
|
|
4
|
+
attachBranch,
|
|
5
|
+
garbageCollect,
|
|
6
|
+
groupOperationsByScope,
|
|
7
|
+
merge,
|
|
8
|
+
split,
|
|
9
|
+
precedes,
|
|
10
|
+
removeExistingOperations,
|
|
11
|
+
reshuffleByTimestamp,
|
|
12
|
+
sortOperations,
|
|
13
|
+
addUndo,
|
|
14
|
+
checkOperationsIntegrity,
|
|
15
|
+
checkCleanedOperationsIntegrity,
|
|
16
|
+
reshuffleByTimestampAndIndex,
|
|
17
|
+
nextSkipNumber,
|
|
18
|
+
prepareOperations,
|
|
19
|
+
IntegrityIssueSubType,
|
|
20
|
+
IntegrityIssueType,
|
|
20
21
|
} = utils.documentHelpers;
|