document-drive 1.28.2 → 1.28.4

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.
@@ -11,15 +11,16 @@ datasource db {
11
11
  }
12
12
 
13
13
  model Drive {
14
- slug String @id
15
- id String
14
+ id String @id
15
+ slug String @unique
16
+ driveDocuments DriveDocument[]
16
17
  }
17
18
 
18
19
  model Document {
19
- id String
20
- driveId String
20
+ id String @id
21
21
  created DateTime @default(now())
22
22
  lastModified DateTime @default(now())
23
+ isDrive Boolean
23
24
  revision String
24
25
  name String?
25
26
  operations Operation[]
@@ -27,15 +28,26 @@ model Document {
27
28
  documentType String
28
29
  meta String?
29
30
  syncronizationUnits SyncronizationUnit[]
31
+ driveDocuments DriveDocument[]
32
+ }
30
33
 
31
- @@id([id, driveId])
34
+ // Model to map the many-to-many relationship between drives and documents
35
+ model DriveDocument {
36
+ driveId String
37
+ documentId String
38
+ drive Drive @relation(fields: [driveId], references: [id], onDelete: Cascade)
39
+ document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
40
+
41
+ @@id([driveId, documentId])
42
+ @@index([driveId])
43
+ @@index([documentId])
32
44
  }
33
45
 
34
46
  model Operation {
35
47
  id String @id @default(uuid())
36
48
  opId String?
37
49
  driveId String
38
- Document Document? @relation(fields: [driveId, documentId], references: [driveId, id], onDelete: Cascade)
50
+ Document Document? @relation(fields: [documentId], references: [id], onDelete: Cascade)
39
51
  documentId String
40
52
  scope String
41
53
  branch String
@@ -61,7 +73,7 @@ model SyncronizationUnit {
61
73
  driveId String
62
74
  documentId String
63
75
 
64
- Document Document @relation(fields: [documentId, driveId], references: [id, driveId], onDelete: Cascade)
76
+ Document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
65
77
  scope String
66
78
  branch String
67
79
  operations Operation[]
@@ -80,15 +92,3 @@ model Attachment {
80
92
  extension String?
81
93
  hash String
82
94
  }
83
-
84
- model Listener {
85
- listenerId String @id @default(uuid())
86
- driveId String
87
-
88
- label String?
89
- block Boolean
90
- system Boolean
91
-
92
- filter Json
93
- callInfo Json
94
- }
@@ -10,10 +10,8 @@ export declare class BrowserStorage implements IDriveStorage, IDocumentStorage {
10
10
  static DOCUMENT_KEY: string;
11
11
  static MANIFEST_KEY: string;
12
12
  constructor(namespace?: string);
13
- buildDriveKey(driveId: string): string;
14
- buildDocumentKey(documentId: string): string;
15
- buildManifestKey(driveId: string): string;
16
13
  exists(documentId: string): Promise<boolean>;
14
+ create(documentId: string, document: PHDocument): Promise<void>;
17
15
  checkDocumentExists(drive: string, documentId: string): Promise<boolean>;
18
16
  private getDriveManifest;
19
17
  private updateDriveManifest;
@@ -40,5 +38,8 @@ export declare class BrowserStorage implements IDriveStorage, IDocumentStorage {
40
38
  migrateOperationSignatures(): Promise<void>;
41
39
  private migrateDrive;
42
40
  private migrateDocument;
41
+ buildDriveKey(driveId: string): string;
42
+ buildDocumentKey(documentId: string): string;
43
+ buildManifestKey(driveId: string): string;
43
44
  }
44
45
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/storage/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EAET,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAOvE,qBAAa,cAAe,YAAW,aAAa,EAAE,gBAAgB;IACpE,OAAO,CAAC,EAAE,CAAuB;IAEjC,MAAM,CAAC,MAAM,SAAqB;IAClC,MAAM,CAAC,GAAG,SAAO;IACjB,MAAM,CAAC,UAAU,SAAY;IAC7B,MAAM,CAAC,YAAY,SAAc;IACjC,MAAM,CAAC,YAAY,SAAc;gBAErB,SAAS,CAAC,EAAE,MAAM;IAU9B,aAAa,CAAC,OAAO,EAAE,MAAM;IAI7B,gBAAgB,CAAC,UAAU,EAAE,MAAM;IAInC,gBAAgB,CAAC,OAAO,EAAE,MAAM;IAI1B,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASlD,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAI1D,gBAAgB;YAQhB,mBAAmB;IAQ3B,YAAY,CAAC,KAAK,EAAE,MAAM;IAK1B,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAUf,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAY9D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAYxC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAgBV,SAAS;IAUT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAWnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAa3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAQpD,WAAW,CAAC,EAAE,EAAE,MAAM;IAatB,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;IA6CK,0BAA0B;YAYlB,YAAY;YAWZ,eAAe;CAU9B"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/storage/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EAET,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAOvE,qBAAa,cAAe,YAAW,aAAa,EAAE,gBAAgB;IACpE,OAAO,CAAC,EAAE,CAAuB;IAEjC,MAAM,CAAC,MAAM,SAAqB;IAClC,MAAM,CAAC,GAAG,SAAO;IACjB,MAAM,CAAC,UAAU,SAAY;IAC7B,MAAM,CAAC,YAAY,SAAc;IACjC,MAAM,CAAC,YAAY,SAAc;gBAErB,SAAS,CAAC,EAAE,MAAM;IAcxB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IASrE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAI1D,gBAAgB;YAQhB,mBAAmB;IAQ3B,YAAY,CAAC,KAAK,EAAE,MAAM;IAK1B,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAUf,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAW9D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAYxC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAgBV,SAAS;IAUT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAWnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAa3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAQpD,WAAW,CAAC,EAAE,EAAE,MAAM;IAatB,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;IA6CK,0BAA0B;YAYlB,YAAY;YAWZ,eAAe;IAe7B,aAAa,CAAC,OAAO,EAAE,MAAM;IAI7B,gBAAgB,CAAC,UAAU,EAAE,MAAM;IAInC,gBAAgB,CAAC,OAAO,EAAE,MAAM;CAGjC"}
@@ -16,20 +16,21 @@ export class BrowserStorage {
16
16
  : BrowserStorage.DBName,
17
17
  }));
18
18
  }
19
- buildDriveKey(driveId) {
20
- return `${BrowserStorage.DRIVES_KEY}${BrowserStorage.SEP}${driveId}`;
21
- }
22
- buildDocumentKey(documentId) {
23
- return `${BrowserStorage.DOCUMENT_KEY}${BrowserStorage.SEP}${documentId}`;
24
- }
25
- buildManifestKey(driveId) {
26
- return `${BrowserStorage.MANIFEST_KEY}${BrowserStorage.SEP}${driveId}`;
27
- }
19
+ ////////////////////////////////
20
+ // IDocumentStorage
21
+ ////////////////////////////////
28
22
  async exists(documentId) {
29
23
  const db = await this.db;
30
24
  const document = await db.getItem(this.buildDocumentKey(documentId));
31
25
  return !!document;
32
26
  }
27
+ async create(documentId, document) {
28
+ const db = await this.db;
29
+ await db.setItem(this.buildDocumentKey(documentId), document);
30
+ }
31
+ ////////////////////////////////
32
+ // IDriveStorage
33
+ ////////////////////////////////
33
34
  checkDocumentExists(drive, documentId) {
34
35
  return this.exists(documentId);
35
36
  }
@@ -54,8 +55,7 @@ export class BrowserStorage {
54
55
  return document;
55
56
  }
56
57
  async createDocument(drive, id, document) {
57
- const db = await this.db;
58
- await db.setItem(this.buildDocumentKey(id), document);
58
+ await this.create(id, document);
59
59
  // Update the drive manifest to include this document
60
60
  const manifest = await this.getDriveManifest(drive);
61
61
  if (!manifest.documentIds.includes(id)) {
@@ -196,4 +196,16 @@ export class BrowserStorage {
196
196
  return (await this.db).setItem(this.buildDocumentKey(id), migratedDocument);
197
197
  }
198
198
  }
199
+ ////////////////////////////////
200
+ // Private methods
201
+ ////////////////////////////////
202
+ buildDriveKey(driveId) {
203
+ return `${BrowserStorage.DRIVES_KEY}${BrowserStorage.SEP}${driveId}`;
204
+ }
205
+ buildDocumentKey(documentId) {
206
+ return `${BrowserStorage.DOCUMENT_KEY}${BrowserStorage.SEP}${documentId}`;
207
+ }
208
+ buildManifestKey(driveId) {
209
+ return `${BrowserStorage.MANIFEST_KEY}${BrowserStorage.SEP}${driveId}`;
210
+ }
199
211
  }
@@ -5,13 +5,9 @@ import { type IDocumentStorage, type IDriveStorage } from "./types.js";
5
5
  export declare class FilesystemStorage implements IDriveStorage, IDocumentStorage {
6
6
  private basePath;
7
7
  constructor(basePath: string);
8
- private _buildDocumentPath;
9
- private _buildDrivePath;
10
- private _buildManifestPath;
11
- private getDriveManifest;
12
- private updateDriveManifest;
13
- getDocuments(drive: string): Promise<string[]>;
14
8
  exists(documentId: string): Promise<boolean>;
9
+ create(documentId: string, document: PHDocument): Promise<void>;
10
+ getDocuments(drive: string): Promise<string[]>;
15
11
  checkDocumentExists(drive: string, id: string): Promise<boolean>;
16
12
  getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
17
13
  createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
@@ -32,5 +28,10 @@ export declare class FilesystemStorage implements IDriveStorage, IDocumentStorag
32
28
  lastUpdated: string;
33
29
  revision: number;
34
30
  }[]>;
31
+ private _buildDocumentPath;
32
+ private _buildDrivePath;
33
+ private _buildManifestPath;
34
+ private getDriveManifest;
35
+ private updateDriveManifest;
35
36
  }
36
37
  //# sourceMappingURL=filesystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../../src/storage/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAoBvE,qBAAa,iBAAkB,YAAW,aAAa,EAAE,gBAAgB;IACvE,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAK5B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,kBAAkB;YAIZ,gBAAgB;YAWhB,mBAAmB;IAQ3B,YAAY,CAAC,KAAK,EAAE,MAAM;IAKhC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK5C,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1D,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAWf,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAgB9D,YAAY;IAeZ,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IA0BxC,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc;IAuBlB,SAAS;IAWT,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAWpD,cAAc,CAAC,IAAI,EAAE,MAAM;IAmB3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAUpD,WAAW,CAAC,EAAE,EAAE,MAAM;IActB,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAqBV,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;CA2CF"}
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../../src/storage/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAavE,qBAAa,iBAAkB,YAAW,aAAa,EAAE,gBAAgB;IACvE,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAS5B,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAW/C,YAAY,CAAC,KAAK,EAAE,MAAM;IAKhC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1D,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAWf,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAgB9D,YAAY;IAeZ,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IA0BxC,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc;IAuBlB,SAAS;IAWT,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAWpD,cAAc,CAAC,IAAI,EAAE,MAAM;IAmB3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAUpD,WAAW,CAAC,EAAE,EAAE,MAAM;IActB,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAqBV,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;IAgDD,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,kBAAkB;YAIZ,gBAAgB;YAWhB,mBAAmB;CAOlC"}
@@ -15,38 +15,26 @@ export class FilesystemStorage {
15
15
  this.basePath = basePath;
16
16
  ensureDir(this.basePath);
17
17
  }
18
- _buildDocumentPath(documentId) {
19
- return `${this.basePath}/document-${documentId}.json`;
20
- }
21
- _buildDrivePath(driveId) {
22
- return `${this.basePath}/drive-${driveId}.json`;
23
- }
24
- _buildManifestPath(driveId) {
25
- return `${this.basePath}/manifest-${driveId}.json`;
26
- }
27
- async getDriveManifest(driveId) {
28
- const manifestPath = this._buildManifestPath(driveId);
29
- try {
30
- const content = readFileSync(manifestPath, { encoding: "utf-8" });
31
- return JSON.parse(content);
32
- }
33
- catch (error) {
34
- // Return empty manifest if file doesn't exist
35
- return { documentIds: [] };
36
- }
18
+ ////////////////////////////////
19
+ // IDocumentStorage
20
+ ////////////////////////////////
21
+ exists(documentId) {
22
+ const documentExists = existsSync(this._buildDocumentPath(documentId));
23
+ return Promise.resolve(documentExists);
37
24
  }
38
- async updateDriveManifest(driveId, manifest) {
39
- const manifestPath = this._buildManifestPath(driveId);
40
- writeFileSync(manifestPath, stringify(manifest), { encoding: "utf-8" });
25
+ async create(documentId, document) {
26
+ const documentPath = this._buildDocumentPath(documentId);
27
+ writeFileSync(documentPath, stringify(document), {
28
+ encoding: "utf-8",
29
+ });
41
30
  }
31
+ ////////////////////////////////
32
+ // IDriveStorage
33
+ ////////////////////////////////
42
34
  async getDocuments(drive) {
43
35
  const manifest = await this.getDriveManifest(drive);
44
36
  return manifest.documentIds;
45
37
  }
46
- exists(documentId) {
47
- const documentExists = existsSync(this._buildDocumentPath(documentId));
48
- return Promise.resolve(documentExists);
49
- }
50
38
  checkDocumentExists(drive, id) {
51
39
  return this.exists(id);
52
40
  }
@@ -214,4 +202,31 @@ export class FilesystemStorage {
214
202
  return acc;
215
203
  }, []);
216
204
  }
205
+ ////////////////////////////////
206
+ // Private
207
+ ////////////////////////////////
208
+ _buildDocumentPath(documentId) {
209
+ return `${this.basePath}/document-${documentId}.json`;
210
+ }
211
+ _buildDrivePath(driveId) {
212
+ return `${this.basePath}/drive-${driveId}.json`;
213
+ }
214
+ _buildManifestPath(driveId) {
215
+ return `${this.basePath}/manifest-${driveId}.json`;
216
+ }
217
+ async getDriveManifest(driveId) {
218
+ const manifestPath = this._buildManifestPath(driveId);
219
+ try {
220
+ const content = readFileSync(manifestPath, { encoding: "utf-8" });
221
+ return JSON.parse(content);
222
+ }
223
+ catch (error) {
224
+ // Return empty manifest if file doesn't exist
225
+ return { documentIds: [] };
226
+ }
227
+ }
228
+ async updateDriveManifest(driveId, manifest) {
229
+ const manifestPath = this._buildManifestPath(driveId);
230
+ writeFileSync(manifestPath, stringify(manifest), { encoding: "utf-8" });
231
+ }
217
232
  }
@@ -0,0 +1,38 @@
1
+ import { type DocumentDriveAction, type DocumentDriveDocument } from "#drive-document-model/gen/types";
2
+ import { type SynchronizationUnitQuery } from "#server/types";
3
+ import { type DocumentHeader, type Operation, type PHDocument } from "document-model";
4
+ import { type Helia } from "helia";
5
+ import type { IDocumentStorage, IStorage } from "./types.js";
6
+ export declare class IPFSStorage implements IStorage, IDocumentStorage {
7
+ private fs;
8
+ constructor(helia: Helia);
9
+ exists(documentId: string): Promise<boolean>;
10
+ create(documentId: string, document: PHDocument): Promise<void>;
11
+ checkDocumentExists(drive: string, id: string): Promise<boolean>;
12
+ getDocuments(drive: string): Promise<string[]>;
13
+ getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
14
+ createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
15
+ deleteDocument(drive: string, id: string): Promise<void>;
16
+ addDocumentOperations<TDocument extends PHDocument>(drive: string, id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
17
+ getDrives(): Promise<string[]>;
18
+ getDrive(id: string): Promise<DocumentDriveDocument>;
19
+ getDriveBySlug(slug: string): Promise<DocumentDriveDocument>;
20
+ createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
21
+ deleteDrive(id: string): Promise<void>;
22
+ addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
23
+ clearStorage(): Promise<void>;
24
+ getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
25
+ driveId: string;
26
+ documentId: string;
27
+ scope: string;
28
+ branch: string;
29
+ lastUpdated: string;
30
+ revision: number;
31
+ }[]>;
32
+ private _buildDocumentPath;
33
+ private _buildDrivePath;
34
+ private _buildDriveManifestPath;
35
+ private getDriveManifest;
36
+ private updateDriveManifest;
37
+ }
38
+ //# sourceMappingURL=ipfs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipfs.d.ts","sourceRoot":"","sources":["../../../src/storage/ipfs.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO7D,qBAAa,WAAY,YAAW,QAAQ,EAAE,gBAAgB;IAC5D,OAAO,CAAC,EAAE,CAAM;gBAEJ,KAAK,EAAE,KAAK;IAQlB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmB5C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK9C,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAkBf,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,IAAI,CAAC;IAaV,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCxD,qBAAqB,CAAC,SAAS,SAAS,UAAU,EACtD,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAoB9B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAepD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAkB5D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BtC,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAcV,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAa7B,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;IAgDD,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,uBAAuB;YAIjB,gBAAgB;YAgBhB,mBAAmB;CASlC"}
@@ -0,0 +1,274 @@
1
+ import { DriveNotFoundError } from "#server/error";
2
+ import { mergeOperations } from "#utils/misc";
3
+ import { mfs } from "@helia/mfs";
4
+ import stringify from "json-stringify-deterministic";
5
+ export class IPFSStorage {
6
+ fs;
7
+ constructor(helia) {
8
+ this.fs = mfs(helia);
9
+ }
10
+ ////////////////////////////////
11
+ // IDocumentStorage
12
+ ////////////////////////////////
13
+ async exists(documentId) {
14
+ try {
15
+ await this.fs.stat(this._buildDocumentPath(documentId));
16
+ return true;
17
+ }
18
+ catch (error) {
19
+ //
20
+ }
21
+ try {
22
+ await this.fs.stat(this._buildDrivePath(documentId));
23
+ return true;
24
+ }
25
+ catch (error) {
26
+ //
27
+ }
28
+ return false;
29
+ }
30
+ async create(documentId, document) {
31
+ await this.fs.writeBytes(new TextEncoder().encode(stringify(document)), this._buildDocumentPath(documentId));
32
+ }
33
+ ////////////////////////////////s
34
+ // IDriveStorage
35
+ ////////////////////////////////
36
+ async checkDocumentExists(drive, id) {
37
+ return this.exists(id);
38
+ }
39
+ async getDocuments(drive) {
40
+ const manifest = await this.getDriveManifest(drive);
41
+ return manifest.documentIds;
42
+ }
43
+ async getDocument(drive, id) {
44
+ try {
45
+ const documentPath = this._buildDocumentPath(id);
46
+ const chunks = [];
47
+ for await (const chunk of this.fs.cat(documentPath)) {
48
+ chunks.push(chunk);
49
+ }
50
+ const buffer = Buffer.concat(chunks);
51
+ const content = new TextDecoder().decode(buffer);
52
+ return JSON.parse(content);
53
+ }
54
+ catch (error) {
55
+ throw new Error(`Document with id ${id} not found`);
56
+ }
57
+ }
58
+ async createDocument(drive, id, document) {
59
+ await this.create(id, document);
60
+ // Update the drive manifest to include this document
61
+ const manifest = await this.getDriveManifest(drive);
62
+ if (!manifest.documentIds.includes(id)) {
63
+ manifest.documentIds.push(id);
64
+ await this.updateDriveManifest(drive, manifest);
65
+ }
66
+ return Promise.resolve();
67
+ }
68
+ async deleteDocument(drive, id) {
69
+ // Update the drive manifest to remove this document
70
+ const manifest = await this.getDriveManifest(drive);
71
+ const docIndex = manifest.documentIds.indexOf(id);
72
+ if (docIndex !== -1) {
73
+ manifest.documentIds.splice(docIndex, 1);
74
+ await this.updateDriveManifest(drive, manifest);
75
+ }
76
+ // Check if this document exists in other drive manifests
77
+ // Only delete the actual file if no other drive references it
78
+ const drives = await this.getDrives();
79
+ for (const driveId of drives) {
80
+ if (driveId === drive)
81
+ continue;
82
+ const otherManifest = await this.getDriveManifest(driveId);
83
+ if (otherManifest.documentIds.includes(id)) {
84
+ // Document still referenced by another drive, don't delete the file
85
+ return Promise.resolve();
86
+ }
87
+ }
88
+ // If we got here, no other drive references this document, so we can delete it
89
+ try {
90
+ await this.fs.rm(this._buildDocumentPath(id));
91
+ return Promise.resolve();
92
+ }
93
+ catch (error) {
94
+ // If file doesn't exist, consider it deleted already
95
+ return Promise.resolve();
96
+ }
97
+ }
98
+ async addDocumentOperations(drive, id, operations, header) {
99
+ const document = await this.getDocument(drive, id);
100
+ if (!document) {
101
+ throw new Error(`Document with id ${id} not found`);
102
+ }
103
+ const mergedOperations = mergeOperations(document.operations, operations);
104
+ await this.createDocument(drive, id, {
105
+ ...document,
106
+ ...header,
107
+ operations: mergedOperations,
108
+ });
109
+ }
110
+ async getDrives() {
111
+ try {
112
+ // List all files in root directory
113
+ const drives = [];
114
+ for await (const entry of this.fs.ls("/")) {
115
+ if (entry.type === "file" &&
116
+ entry.name.startsWith("drive-") &&
117
+ entry.name.endsWith(".json")) {
118
+ const driveId = entry.name.replace("drive-", "").replace(".json", "");
119
+ drives.push(driveId);
120
+ }
121
+ }
122
+ return drives;
123
+ }
124
+ catch (error) {
125
+ return [];
126
+ }
127
+ }
128
+ async getDrive(id) {
129
+ try {
130
+ const drivePath = this._buildDrivePath(id);
131
+ const chunks = [];
132
+ for await (const chunk of this.fs.cat(drivePath)) {
133
+ chunks.push(chunk);
134
+ }
135
+ const buffer = Buffer.concat(chunks);
136
+ const content = new TextDecoder().decode(buffer);
137
+ return JSON.parse(content);
138
+ }
139
+ catch {
140
+ throw new DriveNotFoundError(id);
141
+ }
142
+ }
143
+ async getDriveBySlug(slug) {
144
+ // Get oldest drives first
145
+ const drives = (await this.getDrives()).reverse();
146
+ for (const drive of drives) {
147
+ const { initialState: { state: { global: { slug: driveSlug }, }, }, } = await this.getDrive(drive);
148
+ if (driveSlug === slug) {
149
+ return this.getDrive(drive);
150
+ }
151
+ }
152
+ throw new Error(`Drive with slug ${slug} not found`);
153
+ }
154
+ async createDrive(id, drive) {
155
+ const drivePath = this._buildDrivePath(id);
156
+ const driveContent = stringify(drive);
157
+ const driveBuffer = new TextEncoder().encode(driveContent);
158
+ // Write the drive to storage
159
+ await this.fs.writeBytes(driveBuffer, drivePath);
160
+ // Initialize an empty manifest for the new drive
161
+ await this.updateDriveManifest(id, { documentIds: [] });
162
+ return Promise.resolve();
163
+ }
164
+ async deleteDrive(id) {
165
+ // Get all documents in this drive
166
+ const manifest = await this.getDriveManifest(id);
167
+ const documents = manifest.documentIds;
168
+ // Delete each document from this drive (may not actually delete files if shared with other drives)
169
+ await Promise.all(documents.map((document) => this.deleteDocument(id, document)));
170
+ // Delete the drive manifest
171
+ try {
172
+ await this.fs.rm(this._buildDriveManifestPath(id));
173
+ }
174
+ catch (error) {
175
+ // If manifest doesn't exist, ignore the error
176
+ }
177
+ // Delete the drive document
178
+ try {
179
+ await this.fs.rm(this._buildDrivePath(id));
180
+ }
181
+ catch (error) {
182
+ // If file doesn't exist, ignore the error
183
+ }
184
+ return Promise.resolve();
185
+ }
186
+ async addDriveOperations(id, operations, header) {
187
+ const drive = await this.getDrive(id);
188
+ const mergedOperations = mergeOperations(drive.operations, operations);
189
+ await this.createDrive(id, {
190
+ ...drive,
191
+ ...header,
192
+ operations: mergedOperations,
193
+ });
194
+ }
195
+ async clearStorage() {
196
+ // Delete all files
197
+ try {
198
+ for await (const entry of this.fs.ls("/")) {
199
+ if (entry.type === "file") {
200
+ await this.fs.rm(`/${entry.name}`);
201
+ }
202
+ }
203
+ }
204
+ catch (error) {
205
+ // Ignore any errors when trying to list/delete files
206
+ }
207
+ }
208
+ async getSynchronizationUnitsRevision(units) {
209
+ const results = await Promise.allSettled(units.map(async (unit) => {
210
+ try {
211
+ const document = await (unit.documentId
212
+ ? this.getDocument(unit.driveId, unit.documentId)
213
+ : this.getDrive(unit.driveId));
214
+ if (!document) {
215
+ return undefined;
216
+ }
217
+ const operation = document.operations[unit.scope].at(-1);
218
+ if (operation) {
219
+ return {
220
+ driveId: unit.driveId,
221
+ documentId: unit.documentId,
222
+ scope: unit.scope,
223
+ branch: unit.branch,
224
+ lastUpdated: operation.timestamp,
225
+ revision: operation.index,
226
+ };
227
+ }
228
+ }
229
+ catch {
230
+ return undefined;
231
+ }
232
+ }));
233
+ return results.reduce((acc, curr) => {
234
+ if (curr.status === "fulfilled" && curr.value !== undefined) {
235
+ acc.push(curr.value);
236
+ }
237
+ return acc;
238
+ }, []);
239
+ }
240
+ ////////////////////////////////
241
+ // Private methods
242
+ ////////////////////////////////
243
+ _buildDocumentPath(documentId) {
244
+ return `/document-${documentId}.json`;
245
+ }
246
+ _buildDrivePath(driveId) {
247
+ return `/drive-${driveId}.json`;
248
+ }
249
+ _buildDriveManifestPath(driveId) {
250
+ return `/manifest-${driveId}.json`;
251
+ }
252
+ async getDriveManifest(driveId) {
253
+ try {
254
+ const manifestPath = this._buildDriveManifestPath(driveId);
255
+ const chunks = [];
256
+ for await (const chunk of this.fs.cat(manifestPath)) {
257
+ chunks.push(chunk);
258
+ }
259
+ const buffer = Buffer.concat(chunks);
260
+ const content = new TextDecoder().decode(buffer);
261
+ return JSON.parse(content);
262
+ }
263
+ catch (error) {
264
+ // If manifest doesn't exist, return an empty one
265
+ return { documentIds: [] };
266
+ }
267
+ }
268
+ async updateDriveManifest(driveId, manifest) {
269
+ const manifestPath = this._buildDriveManifestPath(driveId);
270
+ const manifestContent = stringify(manifest);
271
+ const manifestBuffer = new TextEncoder().encode(manifestContent);
272
+ await this.fs.writeBytes(manifestBuffer, manifestPath);
273
+ }
274
+ }
@@ -5,9 +5,11 @@ import { type IDocumentStorage, type IDriveStorage } from "./types.js";
5
5
  export declare class MemoryStorage implements IDriveStorage, IDocumentStorage {
6
6
  private documents;
7
7
  private drives;
8
+ private driveManifests;
8
9
  private slugToDriveId;
9
10
  constructor();
10
- exists(id: string): Promise<boolean>;
11
+ exists(documentId: string): Promise<boolean>;
12
+ create(documentId: string, document: PHDocument): Promise<void>;
11
13
  checkDocumentExists(drive: string, id: string): Promise<boolean>;
12
14
  getDocuments(drive: string): Promise<string[]>;
13
15
  getDocument<TDocument extends PHDocument>(driveId: string, id: string): Promise<TDocument>;
@@ -30,5 +32,7 @@ export declare class MemoryStorage implements IDriveStorage, IDocumentStorage {
30
32
  lastUpdated: string;
31
33
  revision: number;
32
34
  }[]>;
35
+ private getDriveManifest;
36
+ private updateDriveManifest;
33
37
  }
34
38
  //# sourceMappingURL=memory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/storage/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAE1B,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvE,qBAAa,aAAc,YAAW,aAAa,EAAE,gBAAgB;IACnE,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,aAAa,CAA8B;;IAOnD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUpC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1D,YAAY,CAAC,KAAK,EAAE,MAAM;IAI1B,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAaf,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAK5D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IA0B9D,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAOxC,SAAS;IAIT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAQnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAQ3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IASpD,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,EAAE,EAC1D,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAcV,WAAW,CAAC,EAAE,EAAE,MAAM;IAKtB,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;CA2CF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/storage/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAE1B,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAMvE,qBAAa,aAAc,YAAW,aAAa,EAAE,gBAAgB;IACnE,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,aAAa,CAA8B;;IAYnD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAU/C,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhE,YAAY,CAAC,KAAK,EAAE,MAAM;IAKpB,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IASf,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAS5D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAO7B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAS9D,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAcxC,SAAS;IAIT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAQnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAQ3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAYpD,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,EAAE,EAC1D,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAcV,WAAW,CAAC,EAAE,EAAE,MAAM;IAmCtB,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;IAgDD,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,mBAAmB;CAG5B"}