document-drive 1.0.0-experimental.7 → 1.0.0-experimental.9

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-experimental.7",
3
+ "version": "1.0.0-experimental.9",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "module": "./src/index.ts",
@@ -66,7 +66,7 @@
66
66
  "@typescript-eslint/parser": "^6.21.0",
67
67
  "@vitest/coverage-v8": "^1.4.0",
68
68
  "document-model": "1.1.0-experimental.1",
69
- "document-model-libs": "^1.37.0",
69
+ "document-model-libs": "1.50.0-arbitrum.1",
70
70
  "eslint": "^8.57.0",
71
71
  "eslint-config-prettier": "^9.1.0",
72
72
  "fake-indexeddb": "^5.0.2",
@@ -20,6 +20,7 @@ import {
20
20
  DocumentModel,
21
21
  Operation,
22
22
  OperationScope,
23
+ State
23
24
  } from 'document-model/document';
24
25
  import { createNanoEvents, Unsubscribe } from 'nanoevents';
25
26
  import { ICache } from '../cache';
@@ -575,11 +576,13 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
575
576
  input: CreateDocumentInput
576
577
  ) {
577
578
  // if a document was provided then checks if it's valid
579
+ let state = undefined;
578
580
  if (input.document) {
579
581
  if (input.documentType !== input.document.documentType) {
580
582
  throw new Error(`Provided document is not ${input.documentType}`);
581
583
  }
582
- this._buildDocument(input.document);
584
+ const doc = this._buildDocument(input.document);
585
+ state = doc.state;
583
586
  }
584
587
 
585
588
  // if no document was provided then create a new one
@@ -596,6 +599,7 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
596
599
  operations: { global: [], local: [] },
597
600
  initialState: document.initialState,
598
601
  clipboard: [],
602
+ state: state ?? document.state
599
603
  };
600
604
  await this.storage.createDocument(driveId, input.id, documentStorage);
601
605
 
@@ -663,7 +667,7 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
663
667
  : merge(trunk, invertedTrunk, reshuffleByTimestamp);
664
668
 
665
669
  const newOperations = newHistory.filter(
666
- op => trunk.length < 1 || precedes(trunk[trunk.length - 1]!, op)
670
+ (op: any) => trunk.length < 1 || precedes(trunk[trunk.length - 1]!, op)
667
671
  );
668
672
 
669
673
  for (const nextOperation of newOperations) {
@@ -726,6 +730,10 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
726
730
  ) : documentStorage.operations;
727
731
  const operations = baseUtils.documentHelpers.grabageCollectDocumentOperations(revisionOperations);
728
732
 
733
+ if (documentStorage.state && (!options || options.checkHashes === false)) {
734
+ return documentStorage as T;
735
+ }
736
+
729
737
  return baseUtils.replayDocument(
730
738
  documentStorage.initialState,
731
739
  operations,
@@ -829,6 +837,7 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
829
837
  callback: (document: DocumentStorage) => Promise<{
830
838
  operations: Operation[];
831
839
  header: DocumentHeader;
840
+ newState: State<any, any> | undefined;
832
841
  }>
833
842
  ) {
834
843
  if (!this.storage.addDocumentOperationsWithTransaction) {
@@ -920,7 +929,8 @@ export class DocumentDriveServer extends BaseDocumentDriveServer {
920
929
 
921
930
  return {
922
931
  operations: result.operationsApplied,
923
- header: result.document
932
+ header: result.document,
933
+ newState: document.state
924
934
  };
925
935
  });
926
936
 
@@ -374,9 +374,6 @@ export class PullResponderTransmitter implements IPullResponderTransmitter {
374
374
  static isPullResponderTrigger(
375
375
  trigger: Trigger
376
376
  ): trigger is PullResponderTrigger {
377
- return (
378
- trigger.type === 'PullResponder' &&
379
- z.PullResponderTriggerDataSchema().safeParse(trigger.data).success
380
- );
377
+ return trigger.type === 'PullResponder';
381
378
  }
382
379
  }
@@ -59,7 +59,8 @@ export class MemoryStorage implements IDriveStorage {
59
59
  documentType,
60
60
  created,
61
61
  lastModified,
62
- clipboard
62
+ clipboard,
63
+ state
63
64
  } = document;
64
65
  this.documents[drive]![id] = {
65
66
  operations,
@@ -69,7 +70,8 @@ export class MemoryStorage implements IDriveStorage {
69
70
  documentType,
70
71
  created,
71
72
  lastModified,
72
- clipboard
73
+ clipboard,
74
+ state
73
75
  };
74
76
  }
75
77
 
@@ -11,7 +11,8 @@ import type {
11
11
  DocumentHeader,
12
12
  ExtendedState,
13
13
  Operation,
14
- OperationScope
14
+ OperationScope,
15
+ State
15
16
  } from 'document-model/document';
16
17
  import { ConflictOperationError } from '../server/error';
17
18
  import { logger } from '../utils/logger';
@@ -132,10 +133,11 @@ export class PrismaStorage implements IDriveStorage {
132
133
  name: document.name,
133
134
  documentType: document.documentType,
134
135
  driveId: drive,
135
- initialState: document.initialState as Prisma.InputJsonObject,
136
+ initialState: JSON.stringify(document.initialState),
136
137
  lastModified: document.lastModified,
137
- revision: document.revision,
138
- id
138
+ revision: JSON.stringify(document.revision),
139
+ id,
140
+ state: JSON.stringify(document.initialState)
139
141
  }
140
142
  });
141
143
  }
@@ -146,6 +148,7 @@ export class PrismaStorage implements IDriveStorage {
146
148
  id: string,
147
149
  operations: Operation[],
148
150
  header: DocumentHeader,
151
+ newState: State<any, any> | undefined = undefined
149
152
  ): Promise<void> {
150
153
  const document = await this.getDocument(drive, id, tx);
151
154
  if (!document) {
@@ -176,7 +179,8 @@ export class PrismaStorage implements IDriveStorage {
176
179
  },
177
180
  data: {
178
181
  lastModified: header.lastModified,
179
- revision: header.revision
182
+ revision: JSON.stringify(header.revision),
183
+ state: JSON.stringify(newState)
180
184
  }
181
185
  });
182
186
  } catch (e) {
@@ -224,11 +228,13 @@ export class PrismaStorage implements IDriveStorage {
224
228
  callback: (document: DocumentStorage) => Promise<{
225
229
  operations: Operation[];
226
230
  header: DocumentHeader;
231
+ newState?: State<any, any> | undefined
227
232
  }>
228
233
  ) {
229
234
  let result: {
230
235
  operations: Operation[];
231
236
  header: DocumentHeader;
237
+ newState?: State<any, any> | undefined;
232
238
  } | null = null;
233
239
 
234
240
  await this.db.$transaction(async tx => {
@@ -238,13 +244,14 @@ export class PrismaStorage implements IDriveStorage {
238
244
  }
239
245
  result = await callback(document);
240
246
 
241
- const { operations, header } = result;
247
+ const { operations, header, newState } = result;
242
248
  return this._addDocumentOperations(
243
249
  tx,
244
250
  drive,
245
251
  id,
246
252
  operations,
247
253
  header,
254
+ newState
248
255
  );
249
256
  }, { isolationLevel: "Serializable" });
250
257
 
@@ -324,10 +331,11 @@ export class PrismaStorage implements IDriveStorage {
324
331
  created: dbDoc.created.toISOString(),
325
332
  name: dbDoc.name ? dbDoc.name : '',
326
333
  documentType: dbDoc.documentType,
327
- initialState: dbDoc.initialState as ExtendedState<
334
+ initialState: JSON.parse(dbDoc.initialState) as ExtendedState<
328
335
  DocumentDriveState,
329
336
  DocumentDriveLocalState
330
337
  >,
338
+ state: JSON.parse(dbDoc.state) as State<unknown, unknown>,
331
339
  lastModified: new Date(dbDoc.lastModified).toISOString(),
332
340
  operations: {
333
341
  global: dbDoc.operations
@@ -340,7 +348,7 @@ export class PrismaStorage implements IDriveStorage {
340
348
  clipboard: dbDoc.operations
341
349
  .filter(op => op.clipboard)
342
350
  .map(storageToOperation),
343
- revision: dbDoc.revision as Record<OperationScope, number>
351
+ revision: JSON.parse(dbDoc.revision) as Record<OperationScope, number>
344
352
  };
345
353
 
346
354
  return doc;
@@ -6,12 +6,14 @@ import type {
6
6
  BaseAction,
7
7
  Document,
8
8
  DocumentHeader,
9
- Operation
9
+ ExtendedState,
10
+ Operation,
11
+ State
10
12
  } from 'document-model/document';
11
13
 
12
14
  export type DocumentStorage<D extends Document = Document> = Omit<
13
15
  D,
14
- 'state' | 'attachments'
16
+ 'attachments'
15
17
  >;
16
18
 
17
19
  export type DocumentDriveStorage = DocumentStorage<DocumentDriveDocument>;
@@ -37,6 +39,7 @@ export interface IStorage {
37
39
  callback: (document: DocumentStorage) => Promise<{
38
40
  operations: Operation[];
39
41
  header: DocumentHeader;
42
+ newState: State<any, any> | undefined
40
43
  }>
41
44
  ): Promise<void>;
42
45
  deleteDocument(drive: string, id: string): Promise<void>;
@@ -27,8 +27,7 @@ export function isDocumentDrive(
27
27
  document: Document
28
28
  ): document is DocumentDriveDocument {
29
29
  return (
30
- document.documentType === DocumentDriveModel.id &&
31
- z.DocumentDriveStateSchema().safeParse(document.state.global).success
30
+ document.documentType === DocumentDriveModel.id
32
31
  );
33
32
  }
34
33