document-drive 0.0.4 → 0.0.5

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": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "module": "./src/index.ts",
@@ -23,8 +23,8 @@
23
23
  "test:watch": "vitest watch"
24
24
  },
25
25
  "peerDependencies": {
26
- "document-model": "^1.0.11",
27
- "document-model-libs": "^1.1.14"
26
+ "document-model": "^1.0.13",
27
+ "document-model-libs": "^1.1.21"
28
28
  },
29
29
  "dependencies": {
30
30
  "sanitize-filename": "^1.6.3"
@@ -33,8 +33,8 @@
33
33
  "@typescript-eslint/eslint-plugin": "^6.12.0",
34
34
  "@typescript-eslint/parser": "^6.12.0",
35
35
  "@vitest/coverage-v8": "^0.34.6",
36
- "document-model": "^1.0.11",
37
- "document-model-libs": "^1.1.20",
36
+ "document-model": "^1.0.15",
37
+ "document-model-libs": "^1.1.23",
38
38
  "eslint": "^8.54.0",
39
39
  "eslint-config-prettier": "^9.0.0",
40
40
  "prettier": "^3.1.0",
@@ -1,9 +1,19 @@
1
- import { utils } from 'document-model-libs/document-drive';
2
- import { Document, DocumentModel, Operation } from 'document-model/document';
1
+ import {
2
+ DocumentDriveAction,
3
+ DocumentDriveDocument,
4
+ utils
5
+ } from 'document-model-libs/document-drive';
6
+ import { BaseAction, DocumentModel, Operation } from 'document-model/document';
3
7
  import { IDriveStorage } from '../storage';
4
8
  import { MemoryStorage } from '../storage/memory';
5
9
  import { isDocumentDrive } from '../utils';
6
- import { CreateDocumentInput, DriveInput, IDocumentDriveServer } from './types';
10
+ import {
11
+ CreateDocumentInput,
12
+ DriveInput,
13
+ IDocumentDriveServer,
14
+ IOperationResult,
15
+ SignalResult
16
+ } from './types';
7
17
 
8
18
  export type * from './types';
9
19
 
@@ -67,47 +77,102 @@ export class DocumentDriveServer implements IDocumentDriveServer {
67
77
  return this.storage.deleteDocument(driveId, id);
68
78
  }
69
79
 
70
- async addOperation(
71
- drive: string,
72
- id: string,
73
- operation: Operation
74
- ): Promise<Document> {
80
+ async addOperation(drive: string, id: string, operation: Operation) {
75
81
  // retrieves document from storage
76
82
  const document = await (id
77
83
  ? this.storage.getDocument(drive, id)
78
84
  : this.storage.getDrive(drive));
79
-
80
- // retrieves the document's document model and
81
- // applies operation using its reducer
82
- const documentModel = this._getDocumentModel(document.documentType);
83
- const signalResults: Promise<unknown>[] = [];
84
- const newDocument = documentModel.reducer(
85
- document,
86
- operation,
87
- signal => {
88
- let result: Promise<unknown> | undefined = undefined;
89
- switch (signal.type) {
90
- case 'CREATE_CHILD_DOCUMENT':
91
- result = this.createDocument(drive, signal.input);
92
- break;
93
- case 'DELETE_CHILD_DOCUMENT':
94
- result = this.deleteDocument(drive, signal.input.id);
95
- break;
96
- }
97
- if (result) {
98
- signalResults.push(result);
85
+ try {
86
+ // retrieves the document's document model and
87
+ // applies operation using its reducer
88
+ const documentModel = this._getDocumentModel(document.documentType);
89
+ const signalHandlers: Promise<SignalResult>[] = [];
90
+ const newDocument = documentModel.reducer(
91
+ document,
92
+ operation,
93
+ signal => {
94
+ let handler: Promise<unknown> | undefined = undefined;
95
+ switch (signal.type) {
96
+ case 'CREATE_CHILD_DOCUMENT':
97
+ handler = this.createDocument(drive, signal.input);
98
+ break;
99
+ case 'DELETE_CHILD_DOCUMENT':
100
+ handler = this.deleteDocument(
101
+ drive,
102
+ signal.input.id
103
+ );
104
+ break;
105
+ case 'COPY_CHILD_DOCUMENT':
106
+ console.log(signal.input);
107
+ handler = this.getDocument(
108
+ drive,
109
+ signal.input.id
110
+ ).then(documentToCopy =>
111
+ this.createDocument(drive, {
112
+ id: signal.input.newId,
113
+ documentType: documentToCopy.documentType,
114
+ document: documentToCopy
115
+ })
116
+ );
117
+ break;
118
+ }
119
+ if (handler) {
120
+ signalHandlers.push(
121
+ handler.then(result => ({ signal, result }))
122
+ );
123
+ }
99
124
  }
125
+ );
126
+ const signals = await Promise.all(signalHandlers);
127
+
128
+ // saves the updated state of the document and returns it
129
+ if (id) {
130
+ await this.storage.saveDocument(drive, id, newDocument);
131
+ } else if (isDocumentDrive(newDocument)) {
132
+ await this.storage.saveDrive(newDocument);
133
+ } else {
134
+ throw new Error('Invalid document');
100
135
  }
101
- );
102
- await Promise.all(signalResults);
103
- // saves the updated state of the document and returns it
104
- if (id) {
105
- await this.storage.saveDocument(drive, id, newDocument);
106
- } else if (isDocumentDrive(newDocument)) {
107
- await this.storage.saveDrive(newDocument);
108
- } else {
109
- throw new Error('Invalid document');
136
+ return {
137
+ success: true,
138
+ document: newDocument,
139
+ operation,
140
+ signals
141
+ };
142
+ } catch (error) {
143
+ return {
144
+ success: false,
145
+ error: error as Error,
146
+ document,
147
+ operation,
148
+ signals: []
149
+ };
110
150
  }
111
- return newDocument;
151
+ }
152
+
153
+ async addOperations(drive: string, id: string, operations: Operation[]) {
154
+ const results: IOperationResult[] = [];
155
+ for (const operation of operations) {
156
+ results.push(await this.addOperation(drive, id, operation));
157
+ }
158
+ return results;
159
+ }
160
+
161
+ addDriveOperation(
162
+ drive: string,
163
+ operation: Operation<DocumentDriveAction | BaseAction>
164
+ ) {
165
+ return this.addOperation(drive, '', operation) as Promise<
166
+ IOperationResult<DocumentDriveDocument>
167
+ >;
168
+ }
169
+
170
+ addDriveOperations(
171
+ drive: string,
172
+ operations: Operation<DocumentDriveAction | BaseAction>[]
173
+ ) {
174
+ return this.addOperations(drive, '', operations) as Promise<
175
+ IOperationResult<DocumentDriveDocument>[]
176
+ >;
112
177
  }
113
178
  }
@@ -1,8 +1,14 @@
1
- import {
1
+ import type {
2
+ DocumentDriveAction,
2
3
  DocumentDriveDocument,
3
4
  DocumentDriveState
4
5
  } from 'document-model-libs/document-drive';
5
- import { Document, Operation } from 'document-model/document';
6
+ import type {
7
+ BaseAction,
8
+ Document,
9
+ Operation,
10
+ Signal
11
+ } from 'document-model/document';
6
12
 
7
13
  export type DriveInput = Omit<
8
14
  DocumentDriveState,
@@ -15,9 +21,18 @@ export type CreateDocumentInput = {
15
21
  document?: Document;
16
22
  };
17
23
 
18
- export interface SortOptions {
19
- afterNodePath?: string;
20
- }
24
+ export type SignalResult = {
25
+ signal: Signal;
26
+ result: unknown; // infer from return types on document-model
27
+ };
28
+
29
+ export type IOperationResult<T extends Document = Document> = {
30
+ success: boolean;
31
+ error?: Error;
32
+ operation: Operation;
33
+ document: T;
34
+ signals: SignalResult[];
35
+ };
21
36
 
22
37
  export interface IDocumentDriveServer {
23
38
  getDrives(): Promise<string[]>;
@@ -34,5 +49,19 @@ export interface IDocumentDriveServer {
34
49
  drive: string,
35
50
  id: string,
36
51
  operation: Operation
37
- ): Promise<Document>;
52
+ ): Promise<IOperationResult>;
53
+ addOperations(
54
+ drive: string,
55
+ id: string,
56
+ operations: Operation[]
57
+ ): Promise<IOperationResult[]>;
58
+
59
+ addDriveOperation(
60
+ drive: string,
61
+ operation: Operation<DocumentDriveAction | BaseAction>
62
+ ): Promise<IOperationResult<DocumentDriveDocument>>;
63
+ addDriveOperations(
64
+ drive: string,
65
+ operations: Operation<DocumentDriveAction | BaseAction>[]
66
+ ): Promise<IOperationResult<DocumentDriveDocument>[]>;
38
67
  }
@@ -56,6 +56,7 @@ export class MemoryStorage implements IDriveStorage {
56
56
  }
57
57
 
58
58
  async deleteDrive(id: string) {
59
+ delete this.documents[id];
59
60
  delete this.drives[id];
60
61
  }
61
62
  }