document-drive 1.0.0-alpha.93 → 1.0.0-alpha.95

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.93",
3
+ "version": "1.0.0-alpha.95",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "module": "./src/index.ts",
@@ -1,4 +1,3 @@
1
- import { ListenerFilter } from 'document-model-libs/document-drive';
2
1
  import { Document } from 'document-model/document';
3
2
  import { DocumentDriveServerConstructor, RemoteDriveOptions } from '../server';
4
3
  import { logger } from '../utils/logger';
@@ -8,6 +7,7 @@ import {
8
7
  IReadModeDriveServer,
9
8
  IReadModeDriveService,
10
9
  ReadDrive,
10
+ ReadDriveOptions,
11
11
  ReadDrivesListener,
12
12
  ReadModeDriveServerMixin
13
13
  } from './types';
@@ -72,8 +72,8 @@ export function ReadModeServer<TBase extends DocumentDriveServerConstructor>(
72
72
  return this.#readModeStorage.getReadDriveContext(id);
73
73
  }
74
74
 
75
- async addReadDrive(url: string, filter?: ListenerFilter) {
76
- await this.#readModeStorage.addReadDrive(url, filter);
75
+ async addReadDrive(url: string, options?: ReadDriveOptions) {
76
+ await this.#readModeStorage.addReadDrive(url, options);
77
77
  this.#notifyListeners(await this.#buildDrives(), 'add');
78
78
  }
79
79
 
@@ -108,13 +108,14 @@ export function ReadModeServer<TBase extends DocumentDriveServerConstructor>(
108
108
  return result;
109
109
  }
110
110
 
111
+ const { url, ...readOptions } = result;
111
112
  try {
112
- const newDrive = await this.addRemoteDrive(result.url, options);
113
+ const newDrive = await this.addRemoteDrive(url, options);
113
114
  return newDrive;
114
115
  } catch (error) {
115
116
  // if an error is thrown, then add the read drive again
116
117
  logger.error(error);
117
- await this.addReadDrive(result.url, result.filter);
118
+ await this.addReadDrive(result.url, readOptions);
118
119
  throw error;
119
120
  }
120
121
  }
@@ -1,7 +1,4 @@
1
- import type {
2
- DocumentDriveDocument,
3
- ListenerFilter
4
- } from 'document-model-libs/document-drive';
1
+ import type { DocumentDriveDocument } from 'document-model-libs/document-drive';
5
2
  import * as DocumentDrive from 'document-model-libs/document-drive';
6
3
  import { Document, DocumentModel } from 'document-model/document';
7
4
  import { GraphQLError } from 'graphql';
@@ -20,7 +17,8 @@ import {
20
17
  InferDocumentState,
21
18
  IReadModeDriveService,
22
19
  ReadDrive,
23
- ReadDriveContext
20
+ ReadDriveContext,
21
+ ReadDriveOptions
24
22
  } from './types';
25
23
 
26
24
  export class ReadModeService implements IReadModeDriveService {
@@ -148,8 +146,9 @@ export class ReadModeService implements IReadModeDriveService {
148
146
  return document;
149
147
  }
150
148
 
151
- async addReadDrive(url: string, filter?: ListenerFilter): Promise<void> {
152
- const { id } = await requestPublicDrive(url);
149
+ async addReadDrive(url: string, options?: ReadDriveOptions): Promise<void> {
150
+ const { id } =
151
+ options?.expectedDriveInfo ?? (await requestPublicDrive(url));
153
152
 
154
153
  const result = await this.#fetchDrive(id, url);
155
154
  if (result instanceof Error) {
@@ -160,13 +159,8 @@ export class ReadModeService implements IReadModeDriveService {
160
159
  this.#drives.set(id, {
161
160
  drive: result as unknown as ReadDrive,
162
161
  context: {
163
- url,
164
- filter: filter ?? {
165
- documentId: ['*'],
166
- documentType: ['*'],
167
- branch: ['*'],
168
- scope: ['*']
169
- }
162
+ ...options,
163
+ url
170
164
  }
171
165
  });
172
166
  }
@@ -5,6 +5,7 @@ import {
5
5
  import { Action, Document, DocumentModel } from 'document-model/document';
6
6
  import { DocumentDriveServerMixin, RemoteDriveOptions } from '../server';
7
7
  import { DocumentModelNotFoundError } from '../server/error';
8
+ import { DriveInfo } from '../utils/graphql';
8
9
  import {
9
10
  ReadDocumentNotFoundError,
10
11
  ReadDriveNotFoundError,
@@ -47,10 +48,14 @@ export interface IReadModeDriveServer extends IReadModeDriveService {
47
48
  ): Promise<ReadDrivesListenerUnsubscribe>; // TODO: make DriveEvents extensible and reuse event emitter
48
49
  }
49
50
 
51
+ export type ReadDriveOptions = {
52
+ expectedDriveInfo?: DriveInfo;
53
+ filter?: ListenerFilter;
54
+ };
55
+
50
56
  export type ReadDriveContext = {
51
57
  url: string;
52
- filter: ListenerFilter;
53
- };
58
+ } & ReadDriveOptions;
54
59
 
55
60
  export type ReadDrive = DocumentDriveDocument & {
56
61
  readContext: ReadDriveContext;
@@ -62,7 +67,7 @@ export type IsDocument<D extends Document> =
62
67
  : false;
63
68
 
64
69
  export interface IReadModeDriveService {
65
- addReadDrive(url: string, filter?: ListenerFilter): Promise<void>;
70
+ addReadDrive(url: string, options?: ReadDriveOptions): Promise<void>;
66
71
 
67
72
  getReadDrives(): Promise<string[]>;
68
73
 
@@ -6,6 +6,7 @@ import {
6
6
  Operation,
7
7
  OperationScope
8
8
  } from 'document-model/document';
9
+ import LocalForage from 'localforage';
9
10
  import { DriveNotFoundError } from '../server/error';
10
11
  import { SynchronizationUnitQuery } from '../server/types';
11
12
  import { mergeOperations } from '../utils';
@@ -20,8 +21,8 @@ export class BrowserStorage implements IDriveStorage {
20
21
  static DRIVES_KEY = 'DRIVES';
21
22
 
22
23
  constructor(namespace?: string) {
23
- this.db = import('localforage').then(localForage =>
24
- localForage.default.createInstance({
24
+ this.db = LocalForage.ready().then(() =>
25
+ LocalForage.createInstance({
25
26
  name: namespace
26
27
  ? `${namespace}:${BrowserStorage.DBName}`
27
28
  : BrowserStorage.DBName
@@ -37,11 +38,12 @@ export class BrowserStorage implements IDriveStorage {
37
38
  const document = await (
38
39
  await this.db
39
40
  ).getItem<Document>(this.buildKey(drive, id));
40
- return document !== undefined;
41
+ return !document;
41
42
  }
42
43
 
43
44
  async getDocuments(drive: string) {
44
- const keys = await (await this.db).keys();
45
+ const db = await this.db;
46
+ const keys = await db.keys();
45
47
  const driveKey = `${drive}${BrowserStorage.SEP}`;
46
48
  return keys
47
49
  .filter(key => key.startsWith(driveKey))
@@ -96,7 +98,7 @@ export class BrowserStorage implements IDriveStorage {
96
98
 
97
99
  async getDrives() {
98
100
  const db = await this.db;
99
- const keys = (await db.keys()) ?? [];
101
+ const keys = await db.keys();
100
102
  return keys
101
103
  .filter(key => key.startsWith(BrowserStorage.DRIVES_KEY))
102
104
  .map(key =>
@@ -107,9 +109,8 @@ export class BrowserStorage implements IDriveStorage {
107
109
  }
108
110
 
109
111
  async getDrive(id: string) {
110
- const drive = await (
111
- await this.db
112
- ).getItem<DocumentDriveStorage>(
112
+ const db = await this.db;
113
+ const drive = await db.getItem<DocumentDriveStorage>(
113
114
  this.buildKey(BrowserStorage.DRIVES_KEY, id)
114
115
  );
115
116
  if (!drive) {
@@ -203,7 +203,9 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
203
203
  let remoteDriveInfo = { ...remoteDrive };
204
204
 
205
205
  try {
206
- const driveInfo = await requestPublicDrive(remoteDrive.url);
206
+ const driveInfo =
207
+ remoteDrive.metadata ??
208
+ (await requestPublicDrive(remoteDrive.url));
207
209
 
208
210
  remoteDriveInfo = { ...remoteDrive, metadata: driveInfo };
209
211
 
@@ -212,15 +214,17 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
212
214
  const driveIsAdded = drives.includes(driveInfo.id);
213
215
  const readDriveIsAdded = readDrives?.includes(driveInfo.id);
214
216
 
217
+ const hasAccessLevel =
218
+ remoteDrive.options.accessLevel !== undefined;
215
219
  const readMode =
216
220
  readServer && remoteDrive.options.accessLevel === 'READ';
217
221
  const isAdded = readMode ? readDriveIsAdded : driveIsAdded;
218
222
 
219
223
  // if the read mode has changed then existing drives
220
224
  // in the previous mode should be deleted
221
- const driveToDelete = readMode
222
- ? driveIsAdded
223
- : readDriveIsAdded;
225
+ const driveToDelete =
226
+ hasAccessLevel &&
227
+ (readMode ? driveIsAdded : readDriveIsAdded);
224
228
  if (driveToDelete) {
225
229
  try {
226
230
  await (readMode
@@ -257,10 +261,17 @@ export class DefaultDrivesManager implements IDefaultDrivesManager {
257
261
  remoteDriveInfo
258
262
  );
259
263
 
260
- await this.server.addRemoteDrive(remoteDrive.url, {
261
- ...remoteDrive.options,
262
- expectedDriveInfo: driveInfo
263
- });
264
+ // if no access level is defined and read mode
265
+ // is supported then uses read mode
266
+ (!hasAccessLevel && readServer) || readMode
267
+ ? await readServer.addReadDrive(remoteDrive.url, {
268
+ ...remoteDrive.options,
269
+ expectedDriveInfo: driveInfo
270
+ })
271
+ : await this.server.addRemoteDrive(remoteDrive.url, {
272
+ ...remoteDrive.options,
273
+ expectedDriveInfo: driveInfo
274
+ });
264
275
 
265
276
  remoteDriveInfo.status = 'SUCCESS';
266
277