document-drive 1.29.0 → 1.29.1-dev.0
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 +6 -10
- package/dist/src/cache/memory.d.ts +14 -4
- package/dist/src/cache/memory.d.ts.map +1 -1
- package/dist/src/cache/memory.js +57 -19
- package/dist/src/cache/redis.d.ts +14 -4
- package/dist/src/cache/redis.d.ts.map +1 -1
- package/dist/src/cache/redis.js +71 -19
- package/dist/src/cache/types.d.ts +10 -3
- package/dist/src/cache/types.d.ts.map +1 -1
- package/dist/src/cache/util.d.ts +3 -0
- package/dist/src/cache/util.d.ts.map +1 -0
- package/dist/src/cache/util.js +13 -0
- package/dist/src/server/base-server.d.ts +1 -1
- package/dist/src/server/base-server.d.ts.map +1 -1
- package/dist/src/server/base-server.js +35 -28
- package/dist/src/server/listener/listener-manager.js +2 -2
- package/dist/src/server/listener/transmitter/pull-responder.d.ts +1 -1
- package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -1
- package/dist/src/server/listener/transmitter/pull-responder.js +2 -3
- package/dist/src/server/sync-manager.d.ts.map +1 -1
- package/dist/src/server/sync-manager.js +7 -18
- package/dist/src/server/types.d.ts +0 -1
- package/dist/src/server/types.d.ts.map +1 -1
- package/dist/src/storage/browser.d.ts +6 -4
- package/dist/src/storage/browser.d.ts.map +1 -1
- package/dist/src/storage/browser.js +83 -22
- package/dist/src/storage/filesystem.d.ts +5 -3
- package/dist/src/storage/filesystem.d.ts.map +1 -1
- package/dist/src/storage/filesystem.js +83 -29
- package/dist/src/storage/ipfs.d.ts +5 -1
- package/dist/src/storage/ipfs.d.ts.map +1 -1
- package/dist/src/storage/ipfs.js +74 -21
- package/dist/src/storage/memory.d.ts +5 -5
- package/dist/src/storage/memory.d.ts.map +1 -1
- package/dist/src/storage/memory.js +78 -51
- package/dist/src/storage/prisma/factory.d.ts +4 -3
- package/dist/src/storage/prisma/factory.d.ts.map +1 -1
- package/dist/src/storage/prisma/factory.js +5 -5
- package/dist/src/storage/prisma/index.d.ts +11 -6
- package/dist/src/storage/prisma/index.d.ts.map +1 -1
- package/dist/src/storage/prisma/index.js +233 -190
- package/dist/src/storage/types.d.ts +6 -6
- package/dist/src/storage/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -8,6 +8,11 @@ export declare class IPFSStorage implements IStorage, IDocumentStorage {
|
|
|
8
8
|
constructor(helia: Helia);
|
|
9
9
|
exists(documentId: string): Promise<boolean>;
|
|
10
10
|
create(documentId: string, document: PHDocument): Promise<void>;
|
|
11
|
+
get<TDocument extends PHDocument>(documentId: string): Promise<TDocument>;
|
|
12
|
+
delete(documentId: string): Promise<boolean>;
|
|
13
|
+
addChild(parentId: string, childId: string): Promise<void>;
|
|
14
|
+
removeChild(parentId: string, childId: string): Promise<boolean>;
|
|
15
|
+
getChildren(parentId: string): Promise<string[]>;
|
|
11
16
|
checkDocumentExists(drive: string, id: string): Promise<boolean>;
|
|
12
17
|
getDocuments(drive: string): Promise<string[]>;
|
|
13
18
|
getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
|
|
@@ -22,7 +27,6 @@ export declare class IPFSStorage implements IStorage, IDocumentStorage {
|
|
|
22
27
|
addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
|
|
23
28
|
clearStorage(): Promise<void>;
|
|
24
29
|
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
|
|
25
|
-
driveId: string;
|
|
26
30
|
documentId: string;
|
|
27
31
|
scope: string;
|
|
28
32
|
branch: string;
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"ipfs.d.ts","sourceRoot":"","sources":["../../../src/storage/ipfs.ts"],"names":[],"mappings":"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"}
|
package/dist/src/storage/ipfs.js
CHANGED
|
@@ -30,19 +30,9 @@ export class IPFSStorage {
|
|
|
30
30
|
async create(documentId, document) {
|
|
31
31
|
await this.fs.writeBytes(new TextEncoder().encode(stringify(document)), this._buildDocumentPath(documentId));
|
|
32
32
|
}
|
|
33
|
-
|
|
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) {
|
|
33
|
+
async get(documentId) {
|
|
44
34
|
try {
|
|
45
|
-
const documentPath = this._buildDocumentPath(
|
|
35
|
+
const documentPath = this._buildDocumentPath(documentId);
|
|
46
36
|
const chunks = [];
|
|
47
37
|
for await (const chunk of this.fs.cat(documentPath)) {
|
|
48
38
|
chunks.push(chunk);
|
|
@@ -52,8 +42,73 @@ export class IPFSStorage {
|
|
|
52
42
|
return JSON.parse(content);
|
|
53
43
|
}
|
|
54
44
|
catch (error) {
|
|
55
|
-
throw new Error(`Document with id ${
|
|
45
|
+
throw new Error(`Document with id ${documentId} not found`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async delete(documentId) {
|
|
49
|
+
// delete the document from all other drive manifests
|
|
50
|
+
const drives = await this.getDrives();
|
|
51
|
+
for (const driveId of drives) {
|
|
52
|
+
if (driveId === documentId)
|
|
53
|
+
continue;
|
|
54
|
+
await this.removeChild(driveId, documentId);
|
|
55
|
+
}
|
|
56
|
+
// delete any manifest for this document
|
|
57
|
+
try {
|
|
58
|
+
await this.fs.rm(this._buildDriveManifestPath(documentId));
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// there may be no manifest for this document
|
|
62
|
+
}
|
|
63
|
+
// finally, delete the specified document
|
|
64
|
+
try {
|
|
65
|
+
await this.fs.rm(this._buildDocumentPath(documentId));
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async addChild(parentId, childId) {
|
|
73
|
+
if (parentId === childId) {
|
|
74
|
+
throw new Error("Cannot associate a document with itself");
|
|
75
|
+
}
|
|
76
|
+
// check if the child is a parent of the parent
|
|
77
|
+
const children = await this.getChildren(childId);
|
|
78
|
+
if (children.includes(parentId)) {
|
|
79
|
+
throw new Error("Cannot associate a document with its child");
|
|
80
|
+
}
|
|
81
|
+
const manifest = await this.getDriveManifest(parentId);
|
|
82
|
+
if (!manifest.documentIds.includes(childId)) {
|
|
83
|
+
manifest.documentIds.push(childId);
|
|
84
|
+
await this.updateDriveManifest(parentId, manifest);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async removeChild(parentId, childId) {
|
|
88
|
+
const manifest = await this.getDriveManifest(parentId);
|
|
89
|
+
const docIndex = manifest.documentIds.indexOf(childId);
|
|
90
|
+
if (docIndex !== -1) {
|
|
91
|
+
manifest.documentIds.splice(docIndex, 1);
|
|
92
|
+
await this.updateDriveManifest(parentId, manifest);
|
|
93
|
+
return true;
|
|
56
94
|
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
async getChildren(parentId) {
|
|
98
|
+
const manifest = await this.getDriveManifest(parentId);
|
|
99
|
+
return manifest.documentIds;
|
|
100
|
+
}
|
|
101
|
+
// IDriveStorage
|
|
102
|
+
////////////////////////////////
|
|
103
|
+
async checkDocumentExists(drive, id) {
|
|
104
|
+
return this.exists(id);
|
|
105
|
+
}
|
|
106
|
+
async getDocuments(drive) {
|
|
107
|
+
const manifest = await this.getDriveManifest(drive);
|
|
108
|
+
return manifest.documentIds;
|
|
109
|
+
}
|
|
110
|
+
async getDocument(drive, id) {
|
|
111
|
+
return this.get(id);
|
|
57
112
|
}
|
|
58
113
|
async createDocument(drive, id, document) {
|
|
59
114
|
await this.create(id, document);
|
|
@@ -112,10 +167,11 @@ export class IPFSStorage {
|
|
|
112
167
|
// List all files in root directory
|
|
113
168
|
const drives = [];
|
|
114
169
|
for await (const entry of this.fs.ls("/")) {
|
|
115
|
-
if (entry.
|
|
116
|
-
entry.name.startsWith("drive-") &&
|
|
170
|
+
if (entry.name.startsWith("manifest-") &&
|
|
117
171
|
entry.name.endsWith(".json")) {
|
|
118
|
-
const driveId = entry.name
|
|
172
|
+
const driveId = entry.name
|
|
173
|
+
.replace("manifest-", "")
|
|
174
|
+
.replace(".json", "");
|
|
119
175
|
drives.push(driveId);
|
|
120
176
|
}
|
|
121
177
|
}
|
|
@@ -208,16 +264,13 @@ export class IPFSStorage {
|
|
|
208
264
|
async getSynchronizationUnitsRevision(units) {
|
|
209
265
|
const results = await Promise.allSettled(units.map(async (unit) => {
|
|
210
266
|
try {
|
|
211
|
-
const document = await (unit.documentId
|
|
212
|
-
? this.getDocument(unit.driveId, unit.documentId)
|
|
213
|
-
: this.getDrive(unit.driveId));
|
|
267
|
+
const document = await this.get(unit.documentId);
|
|
214
268
|
if (!document) {
|
|
215
269
|
return undefined;
|
|
216
270
|
}
|
|
217
271
|
const operation = document.operations[unit.scope].at(-1);
|
|
218
272
|
if (operation) {
|
|
219
273
|
return {
|
|
220
|
-
driveId: unit.driveId,
|
|
221
274
|
documentId: unit.documentId,
|
|
222
275
|
scope: unit.scope,
|
|
223
276
|
branch: unit.branch,
|
|
@@ -269,6 +322,6 @@ export class IPFSStorage {
|
|
|
269
322
|
const manifestPath = this._buildDriveManifestPath(driveId);
|
|
270
323
|
const manifestContent = stringify(manifest);
|
|
271
324
|
const manifestBuffer = new TextEncoder().encode(manifestContent);
|
|
272
|
-
await this.fs.writeBytes(manifestBuffer, manifestPath);
|
|
325
|
+
await this.fs.writeBytes(manifestBuffer, manifestPath, { force: true });
|
|
273
326
|
}
|
|
274
327
|
}
|
|
@@ -4,17 +4,18 @@ import { type DocumentHeader, type Operation, type OperationFromDocument, type P
|
|
|
4
4
|
import { type IDocumentStorage, type IDriveStorage } from "./types.js";
|
|
5
5
|
export declare class MemoryStorage implements IDriveStorage, IDocumentStorage {
|
|
6
6
|
private documents;
|
|
7
|
-
private drives;
|
|
8
7
|
private driveManifests;
|
|
9
|
-
private slugToDriveId;
|
|
10
8
|
constructor();
|
|
11
9
|
exists(documentId: string): Promise<boolean>;
|
|
12
10
|
create(documentId: string, document: PHDocument): Promise<void>;
|
|
13
11
|
get<TDocument extends PHDocument>(documentId: string): Promise<TDocument>;
|
|
12
|
+
delete(documentId: string): Promise<boolean>;
|
|
13
|
+
addChild(parentId: string, childId: string): Promise<void>;
|
|
14
|
+
removeChild(parentId: string, childId: string): Promise<boolean>;
|
|
15
|
+
getChildren(parentId: string): Promise<string[]>;
|
|
14
16
|
checkDocumentExists(drive: string, id: string): Promise<boolean>;
|
|
15
17
|
getDocuments(drive: string): Promise<string[]>;
|
|
16
18
|
getDocument<TDocument extends PHDocument>(driveId: string, id: string): Promise<TDocument>;
|
|
17
|
-
saveDocument(drive: string, id: string, document: PHDocument): Promise<void>;
|
|
18
19
|
clearStorage(): Promise<void>;
|
|
19
20
|
createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
|
|
20
21
|
addDocumentOperations(drive: string, id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
|
|
@@ -26,14 +27,13 @@ export declare class MemoryStorage implements IDriveStorage, IDocumentStorage {
|
|
|
26
27
|
addDriveOperations(id: string, operations: OperationFromDocument<DocumentDriveDocument>[], header: DocumentHeader): Promise<void>;
|
|
27
28
|
deleteDrive(id: string): Promise<void>;
|
|
28
29
|
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
|
|
29
|
-
driveId: string;
|
|
30
30
|
documentId: string;
|
|
31
31
|
scope: string;
|
|
32
32
|
branch: string;
|
|
33
33
|
lastUpdated: string;
|
|
34
34
|
revision: number;
|
|
35
35
|
}[]>;
|
|
36
|
-
private
|
|
36
|
+
private getManifest;
|
|
37
37
|
private updateDriveManifest;
|
|
38
38
|
}
|
|
39
39
|
//# 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;AAMvE,qBAAa,aAAc,YAAW,aAAa,EAAE,gBAAgB;IACnE,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,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,cAAc,CAAgC;;IAWtD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAM/C,GAAG,CAAC,SAAS,SAAS,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAcnE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAgB1C,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAU7C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAStD,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhE,YAAY,CAAC,KAAK,EAAE,MAAM;IAK1B,WAAW,CAAC,SAAS,SAAS,UAAU,EACtC,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IAIf,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,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;IAIxC,SAAS;IAIT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAQnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAW3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAqBpD,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;IA4BtB,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,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;IA4CD,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,mBAAmB;CAG5B"}
|
|
@@ -2,19 +2,16 @@ import { DriveNotFoundError } from "#server/error";
|
|
|
2
2
|
import { mergeOperations } from "#utils/misc";
|
|
3
3
|
export class MemoryStorage {
|
|
4
4
|
documents;
|
|
5
|
-
drives;
|
|
6
5
|
driveManifests;
|
|
7
|
-
slugToDriveId = {};
|
|
8
6
|
constructor() {
|
|
9
7
|
this.documents = {};
|
|
10
|
-
this.drives = {};
|
|
11
8
|
this.driveManifests = {};
|
|
12
9
|
}
|
|
13
10
|
////////////////////////////////
|
|
14
11
|
// IDocumentStorage
|
|
15
12
|
////////////////////////////////
|
|
16
13
|
exists(documentId) {
|
|
17
|
-
return Promise.resolve(!!this.documents[documentId]);
|
|
14
|
+
return Promise.resolve(!!this.documents[documentId] || !!this.documents[`drive/${documentId}`]);
|
|
18
15
|
}
|
|
19
16
|
create(documentId, document) {
|
|
20
17
|
this.documents[documentId] = document;
|
|
@@ -23,10 +20,55 @@ export class MemoryStorage {
|
|
|
23
20
|
get(documentId) {
|
|
24
21
|
const document = this.documents[documentId];
|
|
25
22
|
if (!document) {
|
|
23
|
+
const drive = this.documents[`drive/${documentId}`];
|
|
24
|
+
if (drive) {
|
|
25
|
+
return Promise.resolve(drive);
|
|
26
|
+
}
|
|
26
27
|
throw new Error(`Document with id ${documentId} not found`);
|
|
27
28
|
}
|
|
28
29
|
return Promise.resolve(document);
|
|
29
30
|
}
|
|
31
|
+
async delete(documentId) {
|
|
32
|
+
// delete the document from all other drive manifests
|
|
33
|
+
const drives = await this.getDrives();
|
|
34
|
+
for (const driveId of drives) {
|
|
35
|
+
if (driveId === documentId)
|
|
36
|
+
continue;
|
|
37
|
+
await this.removeChild(driveId, documentId);
|
|
38
|
+
}
|
|
39
|
+
// delete any manifest for this document
|
|
40
|
+
delete this.driveManifests[documentId];
|
|
41
|
+
if (this.documents[documentId]) {
|
|
42
|
+
delete this.documents[documentId];
|
|
43
|
+
return Promise.resolve(true);
|
|
44
|
+
}
|
|
45
|
+
return Promise.resolve(false);
|
|
46
|
+
}
|
|
47
|
+
async addChild(parentId, childId) {
|
|
48
|
+
if (parentId === childId) {
|
|
49
|
+
throw new Error("Cannot associate a document with itself");
|
|
50
|
+
}
|
|
51
|
+
// check if the child is a parent of the parent
|
|
52
|
+
const children = await this.getChildren(childId);
|
|
53
|
+
if (children.includes(parentId)) {
|
|
54
|
+
throw new Error("Cannot associate a document with its child");
|
|
55
|
+
}
|
|
56
|
+
const manifest = this.getManifest(parentId);
|
|
57
|
+
manifest.documentIds.add(childId);
|
|
58
|
+
this.updateDriveManifest(parentId, manifest);
|
|
59
|
+
}
|
|
60
|
+
async removeChild(parentId, childId) {
|
|
61
|
+
const manifest = this.getManifest(parentId);
|
|
62
|
+
if (manifest.documentIds.delete(childId)) {
|
|
63
|
+
this.updateDriveManifest(parentId, manifest);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
async getChildren(parentId) {
|
|
69
|
+
const manifest = this.getManifest(parentId);
|
|
70
|
+
return [...manifest.documentIds];
|
|
71
|
+
}
|
|
30
72
|
////////////////////////////////
|
|
31
73
|
// IDriveStorage
|
|
32
74
|
////////////////////////////////
|
|
@@ -34,29 +76,20 @@ export class MemoryStorage {
|
|
|
34
76
|
return this.exists(id);
|
|
35
77
|
}
|
|
36
78
|
getDocuments(drive) {
|
|
37
|
-
const manifest = this.
|
|
79
|
+
const manifest = this.getManifest(drive);
|
|
38
80
|
return Promise.resolve([...manifest.documentIds]);
|
|
39
81
|
}
|
|
40
82
|
getDocument(driveId, id) {
|
|
41
83
|
return this.get(id);
|
|
42
84
|
}
|
|
43
|
-
async saveDocument(drive, id, document) {
|
|
44
|
-
this.documents[id] = document;
|
|
45
|
-
// Update the drive manifest
|
|
46
|
-
const manifest = this.getDriveManifest(drive);
|
|
47
|
-
manifest.documentIds.add(id);
|
|
48
|
-
this.updateDriveManifest(drive, manifest);
|
|
49
|
-
}
|
|
50
85
|
async clearStorage() {
|
|
51
86
|
this.documents = {};
|
|
52
|
-
this.drives = {};
|
|
53
87
|
this.driveManifests = {};
|
|
54
|
-
this.slugToDriveId = {};
|
|
55
88
|
}
|
|
56
89
|
async createDocument(drive, id, document) {
|
|
57
90
|
await this.create(id, document);
|
|
58
91
|
// Update the drive manifest
|
|
59
|
-
const manifest = this.
|
|
92
|
+
const manifest = this.getManifest(drive);
|
|
60
93
|
manifest.documentIds.add(id);
|
|
61
94
|
this.updateDriveManifest(drive, manifest);
|
|
62
95
|
}
|
|
@@ -73,47 +106,50 @@ export class MemoryStorage {
|
|
|
73
106
|
};
|
|
74
107
|
}
|
|
75
108
|
async deleteDocument(drive, id) {
|
|
76
|
-
|
|
77
|
-
const drives = await this.getDrives();
|
|
78
|
-
for (const driveId of drives) {
|
|
79
|
-
const manifest = this.getDriveManifest(driveId);
|
|
80
|
-
if (manifest.documentIds.has(id)) {
|
|
81
|
-
manifest.documentIds.delete(id);
|
|
82
|
-
this.updateDriveManifest(driveId, manifest);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
delete this.documents[id];
|
|
109
|
+
this.delete(id);
|
|
86
110
|
}
|
|
87
111
|
async getDrives() {
|
|
88
|
-
return Object.keys(this.
|
|
112
|
+
return Object.keys(this.driveManifests);
|
|
89
113
|
}
|
|
90
114
|
async getDrive(id) {
|
|
91
|
-
const drive = this.
|
|
115
|
+
const drive = this.documents[`drive/${id}`];
|
|
92
116
|
if (!drive) {
|
|
93
117
|
throw new DriveNotFoundError(id);
|
|
94
118
|
}
|
|
95
119
|
return drive;
|
|
96
120
|
}
|
|
97
121
|
async getDriveBySlug(slug) {
|
|
98
|
-
const driveId
|
|
99
|
-
|
|
100
|
-
|
|
122
|
+
for (const driveId of Object.keys(this.driveManifests)) {
|
|
123
|
+
const drive = this.documents[`drive/${driveId}`];
|
|
124
|
+
if (drive.initialState.state.global.slug === slug) {
|
|
125
|
+
return drive;
|
|
126
|
+
}
|
|
101
127
|
}
|
|
102
|
-
|
|
128
|
+
throw new Error(`Drive with slug ${slug} not found`);
|
|
103
129
|
}
|
|
104
130
|
async createDrive(id, drive) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.updateDriveManifest(id, { documentIds: new Set() });
|
|
108
|
-
const { slug } = drive.initialState.state.global;
|
|
131
|
+
// check if a drive with the same slug already exists
|
|
132
|
+
const slug = drive.initialState.state.global.slug;
|
|
109
133
|
if (slug) {
|
|
110
|
-
|
|
134
|
+
let existingDrive;
|
|
135
|
+
try {
|
|
136
|
+
existingDrive = await this.getDriveBySlug(slug);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// do nothing
|
|
140
|
+
}
|
|
141
|
+
if (existingDrive) {
|
|
142
|
+
throw new Error(`Drive with slug ${slug} already exists`);
|
|
143
|
+
}
|
|
111
144
|
}
|
|
145
|
+
await this.create(`drive/${id}`, drive);
|
|
146
|
+
// Initialize an empty manifest for the new drive
|
|
147
|
+
this.updateDriveManifest(id, { documentIds: new Set() });
|
|
112
148
|
}
|
|
113
149
|
async addDriveOperations(id, operations, header) {
|
|
114
150
|
const drive = await this.getDrive(id);
|
|
115
151
|
const mergedOperations = mergeOperations(drive.operations, operations);
|
|
116
|
-
this.
|
|
152
|
+
this.documents[`drive/${id}`] = {
|
|
117
153
|
...drive,
|
|
118
154
|
...header,
|
|
119
155
|
operations: mergedOperations,
|
|
@@ -121,7 +157,7 @@ export class MemoryStorage {
|
|
|
121
157
|
}
|
|
122
158
|
async deleteDrive(id) {
|
|
123
159
|
// Get all documents in this drive
|
|
124
|
-
const manifest = this.
|
|
160
|
+
const manifest = this.getManifest(id);
|
|
125
161
|
// delete each document that belongs only to this drive
|
|
126
162
|
const drives = await this.getDrives();
|
|
127
163
|
await Promise.all([...manifest.documentIds].map((docId) => {
|
|
@@ -129,7 +165,7 @@ export class MemoryStorage {
|
|
|
129
165
|
if (driveId === id) {
|
|
130
166
|
continue;
|
|
131
167
|
}
|
|
132
|
-
const manifest = this.
|
|
168
|
+
const manifest = this.getManifest(driveId);
|
|
133
169
|
if (manifest.documentIds.has(docId)) {
|
|
134
170
|
return;
|
|
135
171
|
}
|
|
@@ -138,27 +174,18 @@ export class MemoryStorage {
|
|
|
138
174
|
}));
|
|
139
175
|
// Delete the drive manifest and the drive itself
|
|
140
176
|
delete this.driveManifests[id];
|
|
141
|
-
delete this.
|
|
142
|
-
// Clean up slug mapping if needed
|
|
143
|
-
for (const [slug, driveId] of Object.entries(this.slugToDriveId)) {
|
|
144
|
-
if (driveId === id) {
|
|
145
|
-
delete this.slugToDriveId[slug];
|
|
146
|
-
}
|
|
147
|
-
}
|
|
177
|
+
delete this.documents[id];
|
|
148
178
|
}
|
|
149
179
|
async getSynchronizationUnitsRevision(units) {
|
|
150
180
|
const results = await Promise.allSettled(units.map(async (unit) => {
|
|
151
181
|
try {
|
|
152
|
-
const document = await (unit.documentId
|
|
153
|
-
? this.getDocument(unit.driveId, unit.documentId)
|
|
154
|
-
: this.getDrive(unit.driveId));
|
|
182
|
+
const document = await this.get(unit.documentId);
|
|
155
183
|
if (!document) {
|
|
156
184
|
return undefined;
|
|
157
185
|
}
|
|
158
186
|
const operation = document.operations[unit.scope].at(-1);
|
|
159
187
|
if (operation) {
|
|
160
188
|
return {
|
|
161
|
-
driveId: unit.driveId,
|
|
162
189
|
documentId: unit.documentId,
|
|
163
190
|
scope: unit.scope,
|
|
164
191
|
branch: unit.branch,
|
|
@@ -181,7 +208,7 @@ export class MemoryStorage {
|
|
|
181
208
|
////////////////////////////////
|
|
182
209
|
// Private
|
|
183
210
|
////////////////////////////////
|
|
184
|
-
|
|
211
|
+
getManifest(driveId) {
|
|
185
212
|
if (!this.driveManifests[driveId]) {
|
|
186
213
|
this.driveManifests[driveId] = { documentIds: new Set() };
|
|
187
214
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type ICache } from "#cache/types";
|
|
1
2
|
import { PrismaStorage } from "#storage/prisma/index";
|
|
2
3
|
export declare class PrismaStorageFactory {
|
|
3
|
-
private readonly
|
|
4
|
-
private
|
|
5
|
-
constructor(dbUrl: string);
|
|
4
|
+
private readonly prisma;
|
|
5
|
+
private readonly cache;
|
|
6
|
+
constructor(dbUrl: string, cache: ICache);
|
|
6
7
|
build(): PrismaStorage;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,qBAAa,oBAAoB;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAWxC,KAAK;CAGN"}
|
|
@@ -2,19 +2,19 @@ import { PrismaStorage } from "#storage/prisma/index";
|
|
|
2
2
|
import Prisma from "@prisma/client";
|
|
3
3
|
const PrismaClient = Prisma.PrismaClient;
|
|
4
4
|
export class PrismaStorageFactory {
|
|
5
|
-
dbUrl;
|
|
6
5
|
prisma;
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
cache;
|
|
7
|
+
constructor(dbUrl, cache) {
|
|
8
|
+
this.cache = cache;
|
|
9
9
|
this.prisma = new PrismaClient({
|
|
10
10
|
datasources: {
|
|
11
11
|
db: {
|
|
12
|
-
url:
|
|
12
|
+
url: dbUrl,
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
build() {
|
|
18
|
-
return new PrismaStorage(this.prisma);
|
|
18
|
+
return new PrismaStorage(this.prisma, this.cache);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type Prisma, type PrismaClient } from "@prisma/client";
|
|
2
2
|
import type { BaseStateFromDocument, DocumentHeader, Operation, OperationFromDocument, PHDocument } from "document-model";
|
|
3
3
|
import { type IBackOffOptions } from "exponential-backoff";
|
|
4
|
+
import { type ICache } from "../../cache/types.js";
|
|
4
5
|
import { type DocumentDriveAction, type DocumentDriveDocument } from "../../drive-document-model/gen/types.js";
|
|
5
6
|
import { type SynchronizationUnitQuery } from "../../server/types.js";
|
|
6
|
-
import type { IDocumentStorage, IDriveStorage
|
|
7
|
+
import type { IDocumentStorage, IDriveStorage } from "../types.js";
|
|
7
8
|
export * from "./factory.js";
|
|
8
9
|
type Transaction = Omit<PrismaClient<Prisma.PrismaClientOptions, never>, "$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends"> | ExtendedPrismaClient;
|
|
9
10
|
export type PrismaStorageOptions = {
|
|
@@ -26,12 +27,17 @@ declare function getRetryTransactionsClient<T extends PrismaClient>(prisma: T, b
|
|
|
26
27
|
}, {}>;
|
|
27
28
|
type ExtendedPrismaClient = ReturnType<typeof getRetryTransactionsClient<PrismaClient>>;
|
|
28
29
|
export declare class PrismaStorage implements IDriveStorage, IDocumentStorage {
|
|
30
|
+
private logger;
|
|
29
31
|
private db;
|
|
30
|
-
private
|
|
31
|
-
constructor(db: PrismaClient, options?: PrismaStorageOptions);
|
|
32
|
+
private cache;
|
|
33
|
+
constructor(db: PrismaClient, cache: ICache, options?: PrismaStorageOptions);
|
|
32
34
|
exists(documentId: string): Promise<boolean>;
|
|
33
35
|
create(documentId: string, document: PHDocument): Promise<void>;
|
|
34
|
-
|
|
36
|
+
get<TDocument extends PHDocument>(documentId: string, tx?: Transaction): Promise<TDocument>;
|
|
37
|
+
delete(documentId: string): Promise<boolean>;
|
|
38
|
+
addChild(parentId: string, childId: string): Promise<void>;
|
|
39
|
+
removeChild(parentId: string, childId: string): Promise<boolean>;
|
|
40
|
+
getChildren(parentId: string): Promise<string[]>;
|
|
35
41
|
createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
|
|
36
42
|
addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
|
|
37
43
|
addDriveOperationsWithTransaction(drive: string, callback: (document: DocumentDriveDocument) => Promise<{
|
|
@@ -48,7 +54,7 @@ export declare class PrismaStorage implements IDriveStorage, IDocumentStorage {
|
|
|
48
54
|
addDocumentOperations(drive: string, id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
|
|
49
55
|
getDocuments(drive: string): Promise<string[]>;
|
|
50
56
|
checkDocumentExists(driveId: string, id: string): Promise<boolean>;
|
|
51
|
-
getDocument<TDocument extends PHDocument>(driveId: string,
|
|
57
|
+
getDocument<TDocument extends PHDocument>(driveId: string, documentId: string, tx?: Transaction): Promise<TDocument>;
|
|
52
58
|
deleteDocument(drive: string, id: string): Promise<void>;
|
|
53
59
|
getDrives(): Promise<string[]>;
|
|
54
60
|
getDrive(id: string): Promise<DocumentDriveDocument>;
|
|
@@ -57,7 +63,6 @@ export declare class PrismaStorage implements IDriveStorage, IDocumentStorage {
|
|
|
57
63
|
getOperationResultingState(driveId: string, documentId: string, index: number, scope: string, branch: string): Promise<string | undefined>;
|
|
58
64
|
getDriveOperationResultingState(drive: string, index: number, scope: string, branch: string): Promise<string | undefined>;
|
|
59
65
|
getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
|
|
60
|
-
driveId: string;
|
|
61
66
|
documentId: string;
|
|
62
67
|
scope: string;
|
|
63
68
|
branch: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/index.ts"],"names":[],"mappings":"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"}
|