document-drive 1.0.0-alpha.97 → 1.0.0-alpha.99

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document-drive",
3
- "version": "1.0.0-alpha.97",
3
+ "version": "1.0.0-alpha.99",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "module": "./src/index.ts",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "peerDependencies": {
38
38
  "document-model": "^1.8.0",
39
- "document-model-libs": "^1.57.0"
39
+ "document-model-libs": "^1.90.1"
40
40
  },
41
41
  "optionalDependencies": {
42
42
  "@prisma/client": "^5.18.0",
@@ -69,7 +69,7 @@
69
69
  "@vitest/browser": "^2.0.5",
70
70
  "@vitest/coverage-v8": "^2.0.5",
71
71
  "document-model": "^1.7.0",
72
- "document-model-libs": "^1.83.0",
72
+ "document-model-libs": "^1.90.1",
73
73
  "eslint": "^8.57.0",
74
74
  "eslint-config-prettier": "^9.1.0",
75
75
  "fake-indexeddb": "^5.0.2",
@@ -549,6 +549,7 @@ export class BaseDocumentDriveServer
549
549
  }
550
550
 
551
551
  private defaultDrivesManagerDelegate = {
552
+ detachDrive: this.detachDrive.bind(this),
552
553
  emit: (...args: Parameters<DriveEvents['defaultRemoteDrive']>) =>
553
554
  this.emit('defaultRemoteDrive', ...args)
554
555
  };
@@ -2312,6 +2313,31 @@ export class BaseDocumentDriveServer
2312
2313
  return transmitter;
2313
2314
  }
2314
2315
 
2316
+ async detachDrive(driveId: string) {
2317
+ const documentDrive = await this.getDrive(driveId);
2318
+ const listeners = documentDrive.state.local.listeners || [];
2319
+ const triggers = documentDrive.state.local.triggers || [];
2320
+
2321
+ for (const listener of listeners) {
2322
+ await this.addDriveAction(
2323
+ driveId,
2324
+ actions.removeListener({ listenerId: listener.listenerId })
2325
+ );
2326
+ }
2327
+
2328
+ for (const trigger of triggers) {
2329
+ await this.addDriveAction(
2330
+ driveId,
2331
+ actions.removeTrigger({ triggerId: trigger.id })
2332
+ );
2333
+ }
2334
+
2335
+ await this.addDriveAction(
2336
+ driveId,
2337
+ actions.setSharingType({ type: 'LOCAL' })
2338
+ );
2339
+ }
2340
+
2315
2341
  private async addListener(
2316
2342
  driveId: string,
2317
2343
  operation: Operation<Action<'ADD_LISTENER', AddListenerInput>>
@@ -231,6 +231,27 @@ export type DefaultRemoteDriveInfo = DefaultRemoteDriveInput & {
231
231
  metadata?: DriveInfo;
232
232
  };
233
233
 
234
+ export type RemoveDriveStrategy = 'remove' | 'detach';
235
+
236
+ /**
237
+ * Options for removing old remote drives.
238
+ *
239
+ * Allows specifying different strategies for handling old remote drives:
240
+ *
241
+ * - `remove-all`: Remove all remote drives.
242
+ * - `preserve-all`: Preserve all remote drives (this is the default behavior).
243
+ * - `remove-by-id`: Remove the remote drives specified by their IDs.
244
+ * - `remove-by-url`: Remove the remote drives specified by their URLs.
245
+ * - `preserve-by-id`: Preserve remote drives by their IDs and remove the rest.
246
+ * - `preserve-by-url`: Preserve remote drives by their URLs and remove the rest.
247
+ * - `detach-by-id`: Detach remote drives by their IDs (changes the remote drive to a local drive).
248
+ * - `detach-by-url`: Detach remote drives by their URLs (changes the remote drive to a local drive).
249
+ * - `preserve-by-id-and-detach`: Preserve the remote drives specified by their IDs and detach the rest.
250
+ * - `preserve-by-url-and-detach`: Preserve the remote drives specified by their URLs and detach the rest.
251
+ *
252
+ * Each strategy is represented by an object with a `strategy` property and,
253
+ * depending on the strategy, additional properties such as `ids` or `urls`.
254
+ */
234
255
  export type RemoveOldRemoteDrivesOption =
235
256
  | {
236
257
  strategy: 'remove-all';
@@ -253,6 +274,22 @@ export type RemoveOldRemoteDrivesOption =
253
274
  | {
254
275
  strategy: 'preserve-by-url';
255
276
  urls: string[];
277
+ }
278
+ | {
279
+ strategy: 'detach-by-id';
280
+ ids: string[];
281
+ }
282
+ | {
283
+ strategy: 'detach-by-url';
284
+ urls: string[];
285
+ }
286
+ | {
287
+ strategy: 'preserve-by-id-and-detach';
288
+ ids: string[];
289
+ }
290
+ | {
291
+ strategy: 'preserve-by-url-and-detach';
292
+ urls: string[];
256
293
  };
257
294
 
258
295
  export type DocumentDriveServerOptions = {
@@ -5,6 +5,7 @@ import {
5
5
  IBaseDocumentDriveServer,
6
6
  IReadModeDriveServer,
7
7
  RemoteDriveAccessLevel,
8
+ RemoveDriveStrategy,
8
9
  RemoveOldRemoteDrivesOption
9
10
  } from '../server';
10
11
  import { DriveNotFoundError } from '../server/error';
@@ -13,6 +14,7 @@ import { logger } from './logger';
13
14
 
14
15
  export interface IServerDelegateDrivesManager {
15
16
  emit: (...args: Parameters<DriveEvents['defaultRemoteDrive']>) => void;
17
+ detachDrive: (driveId: string) => Promise<void>;
16
18
  }
17
19
 
18
20
  function isReadModeDriveServer(obj: unknown): obj is IReadModeDriveServer {
@@ -75,8 +77,9 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
75
77
  }
76
78
 
77
79
  private async preserveDrivesById(
78
- drivesIdsToRemove: string[],
79
- drives: string[]
80
+ driveIdsToPreserve: string[],
81
+ drives: string[],
82
+ removeStrategy: RemoveDriveStrategy = 'detach'
80
83
  ) {
81
84
  const getAllDrives = drives.map(driveId =>
82
85
  this.server.getDrive(driveId)
@@ -89,11 +92,16 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
89
92
  drive.state.local.triggers.length > 0
90
93
  )
91
94
  .filter(
92
- drive => !drivesIdsToRemove.includes(drive.state.global.id)
95
+ drive => !driveIdsToPreserve.includes(drive.state.global.id)
93
96
  );
94
97
 
95
98
  const driveIds = drivesToRemove.map(drive => drive.state.global.id);
96
- await this.removeDrivesById(driveIds);
99
+
100
+ if (removeStrategy === 'detach') {
101
+ await this.detachDrivesById(driveIds);
102
+ } else {
103
+ await this.removeDrivesById(driveIds);
104
+ }
97
105
  }
98
106
 
99
107
  private async removeDrivesById(driveIds: string[]) {
@@ -102,18 +110,41 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
102
110
  }
103
111
  }
104
112
 
113
+ private async detachDrivesById(driveIds: string[]) {
114
+ const detachDrivesPromises = driveIds.map(driveId =>
115
+ this.delegate.detachDrive(driveId)
116
+ );
117
+
118
+ await Promise.all(detachDrivesPromises);
119
+ }
120
+
105
121
  async removeOldremoteDrives() {
106
122
  const driveids = await this.server.getDrives();
107
123
 
108
124
  switch (this.removeOldRemoteDrivesConfig.strategy) {
125
+ case 'preserve-by-id-and-detach':
109
126
  case 'preserve-by-id': {
127
+ const detach: RemoveDriveStrategy =
128
+ this.removeOldRemoteDrivesConfig.strategy ===
129
+ 'preserve-by-id-and-detach'
130
+ ? 'detach'
131
+ : 'remove';
132
+
110
133
  await this.preserveDrivesById(
111
134
  this.removeOldRemoteDrivesConfig.ids,
112
- driveids
135
+ driveids,
136
+ detach
113
137
  );
114
138
  break;
115
139
  }
140
+ case 'preserve-by-url-and-detach':
116
141
  case 'preserve-by-url': {
142
+ const detach: RemoveDriveStrategy =
143
+ this.removeOldRemoteDrivesConfig.strategy ===
144
+ 'preserve-by-url-and-detach'
145
+ ? 'detach'
146
+ : 'remove';
147
+
117
148
  const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map(
118
149
  url => requestPublicDrive(url)
119
150
  );
@@ -122,7 +153,11 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
122
153
  await Promise.all(getDrivesInfo)
123
154
  ).map(driveInfo => driveInfo.id);
124
155
 
125
- await this.preserveDrivesById(drivesIdsToPreserve, driveids);
156
+ await this.preserveDrivesById(
157
+ drivesIdsToPreserve,
158
+ driveids,
159
+ detach
160
+ );
126
161
  break;
127
162
  }
128
163
  case 'remove-by-id': {
@@ -163,6 +198,35 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
163
198
  await this.removeDrivesById(drivesToRemove);
164
199
  break;
165
200
  }
201
+ case 'detach-by-id': {
202
+ const drivesIdsToRemove =
203
+ this.removeOldRemoteDrivesConfig.ids.filter(driveId =>
204
+ driveids.includes(driveId)
205
+ );
206
+ const detachDrivesPromises = drivesIdsToRemove.map(driveId =>
207
+ this.delegate.detachDrive(driveId)
208
+ );
209
+
210
+ await Promise.all(detachDrivesPromises);
211
+ break;
212
+ }
213
+ case 'detach-by-url': {
214
+ const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map(
215
+ driveUrl => requestPublicDrive(driveUrl)
216
+ );
217
+ const drivesInfo = await Promise.all(getDrivesInfo);
218
+
219
+ const drivesIdsToRemove = drivesInfo
220
+ .map(driveInfo => driveInfo.id)
221
+ .filter(driveId => driveids.includes(driveId));
222
+
223
+ const detachDrivesPromises = drivesIdsToRemove.map(driveId =>
224
+ this.delegate.detachDrive(driveId)
225
+ );
226
+
227
+ await Promise.all(detachDrivesPromises);
228
+ break;
229
+ }
166
230
  }
167
231
  }
168
232
 
@@ -234,6 +234,20 @@ export async function fetchDocument<D extends Document>(
234
234
  timestamp
235
235
  type
236
236
  inputText
237
+ context {
238
+ signer {
239
+ user {
240
+ address
241
+ networkId
242
+ chainId
243
+ }
244
+ app {
245
+ name
246
+ key
247
+ }
248
+ signatures
249
+ }
250
+ }
237
251
  }
238
252
  ... on ${name} {
239
253
  state {