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.
- package/dist/prisma/schema.prisma +19 -19
- package/dist/src/storage/browser.d.ts +4 -3
- package/dist/src/storage/browser.d.ts.map +1 -1
- package/dist/src/storage/browser.js +23 -11
- package/dist/src/storage/filesystem.d.ts +7 -6
- package/dist/src/storage/filesystem.d.ts.map +1 -1
- package/dist/src/storage/filesystem.js +41 -26
- package/dist/src/storage/ipfs.d.ts +38 -0
- package/dist/src/storage/ipfs.d.ts.map +1 -0
- package/dist/src/storage/ipfs.js +274 -0
- package/dist/src/storage/memory.d.ts +5 -1
- package/dist/src/storage/memory.d.ts.map +1 -1
- package/dist/src/storage/memory.js +78 -35
- package/dist/src/storage/prisma/index.d.ts +4 -2
- package/dist/src/storage/prisma/index.d.ts.map +1 -1
- package/dist/src/storage/prisma/index.js +134 -48
- package/dist/src/storage/sequelize.d.ts +1 -32
- package/dist/src/storage/sequelize.d.ts.map +1 -1
- package/dist/src/storage/sequelize.js +491 -349
- package/dist/src/storage/types.d.ts +1 -0
- package/dist/src/storage/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -5
|
@@ -11,15 +11,16 @@ datasource db {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
model Drive {
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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: [
|
|
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
|
|
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;
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
39
|
-
const
|
|
40
|
-
writeFileSync(
|
|
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(
|
|
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;
|
|
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"}
|