document-drive 1.28.4 → 1.29.0-dev.1

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.
Files changed (42) hide show
  1. package/dist/prisma/schema.prisma +6 -10
  2. package/dist/src/cache/memory.d.ts +5 -2
  3. package/dist/src/cache/memory.d.ts.map +1 -1
  4. package/dist/src/cache/memory.js +14 -0
  5. package/dist/src/cache/redis.d.ts +5 -2
  6. package/dist/src/cache/redis.d.ts.map +1 -1
  7. package/dist/src/cache/redis.js +12 -0
  8. package/dist/src/drive-document-model/gen/schema/zod.d.ts +8 -8
  9. package/dist/src/drive-document-model/gen/schema/zod.d.ts.map +1 -1
  10. package/dist/src/server/base-server.d.ts +1 -1
  11. package/dist/src/server/base-server.d.ts.map +1 -1
  12. package/dist/src/server/base-server.js +0 -13
  13. package/dist/src/server/listener/listener-manager.js +2 -2
  14. package/dist/src/server/listener/transmitter/pull-responder.d.ts +1 -1
  15. package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -1
  16. package/dist/src/server/listener/transmitter/pull-responder.js +2 -3
  17. package/dist/src/server/sync-manager.d.ts.map +1 -1
  18. package/dist/src/server/sync-manager.js +5 -16
  19. package/dist/src/server/types.d.ts +0 -1
  20. package/dist/src/server/types.d.ts.map +1 -1
  21. package/dist/src/storage/browser.d.ts +1 -3
  22. package/dist/src/storage/browser.d.ts.map +1 -1
  23. package/dist/src/storage/browser.js +36 -23
  24. package/dist/src/storage/filesystem.d.ts +1 -2
  25. package/dist/src/storage/filesystem.d.ts.map +1 -1
  26. package/dist/src/storage/filesystem.js +38 -33
  27. package/dist/src/storage/ipfs.d.ts +1 -1
  28. package/dist/src/storage/ipfs.d.ts.map +1 -1
  29. package/dist/src/storage/ipfs.js +17 -17
  30. package/dist/src/storage/memory.d.ts +1 -4
  31. package/dist/src/storage/memory.d.ts.map +1 -1
  32. package/dist/src/storage/memory.js +40 -42
  33. package/dist/src/storage/prisma/factory.d.ts +4 -3
  34. package/dist/src/storage/prisma/factory.d.ts.map +1 -1
  35. package/dist/src/storage/prisma/factory.js +5 -5
  36. package/dist/src/storage/prisma/index.d.ts +4 -5
  37. package/dist/src/storage/prisma/index.d.ts.map +1 -1
  38. package/dist/src/storage/prisma/index.js +33 -71
  39. package/dist/src/storage/types.d.ts +2 -3
  40. package/dist/src/storage/types.d.ts.map +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +5 -5
@@ -6,7 +6,6 @@ export class BrowserStorage {
6
6
  db;
7
7
  static DBName = "DOCUMENT_DRIVES";
8
8
  static SEP = ":";
9
- static DRIVES_KEY = "DRIVES";
10
9
  static DOCUMENT_KEY = "DOCUMENT";
11
10
  static MANIFEST_KEY = "MANIFEST";
12
11
  constructor(namespace) {
@@ -28,6 +27,14 @@ export class BrowserStorage {
28
27
  const db = await this.db;
29
28
  await db.setItem(this.buildDocumentKey(documentId), document);
30
29
  }
30
+ async get(documentId) {
31
+ const db = await this.db;
32
+ const document = await db.getItem(this.buildDocumentKey(documentId));
33
+ if (!document) {
34
+ throw new Error(`Document with id ${documentId} not found`);
35
+ }
36
+ return document;
37
+ }
31
38
  ////////////////////////////////
32
39
  // IDriveStorage
33
40
  ////////////////////////////////
@@ -48,11 +55,7 @@ export class BrowserStorage {
48
55
  return manifest.documentIds;
49
56
  }
50
57
  async getDocument(driveId, id) {
51
- const document = await (await this.db).getItem(this.buildDocumentKey(id));
52
- if (!document) {
53
- throw new Error(`Document with id ${id} not found`);
54
- }
55
- return document;
58
+ return this.get(id);
56
59
  }
57
60
  async createDocument(drive, id, document) {
58
61
  await this.create(id, document);
@@ -93,13 +96,16 @@ export class BrowserStorage {
93
96
  const db = await this.db;
94
97
  const keys = await db.keys();
95
98
  return keys
96
- .filter((key) => key.startsWith(BrowserStorage.DRIVES_KEY))
97
- .map((key) => key.slice(BrowserStorage.DRIVES_KEY.length + BrowserStorage.SEP.length));
99
+ .filter((key) => key.startsWith(BrowserStorage.MANIFEST_KEY))
100
+ .map((key) => key.slice(BrowserStorage.MANIFEST_KEY.length + BrowserStorage.SEP.length));
98
101
  }
99
102
  async getDrive(id) {
100
- const db = await this.db;
101
- const drive = await db.getItem(this.buildDriveKey(id));
102
- if (!drive) {
103
+ let drive;
104
+ try {
105
+ drive = await this.get(id);
106
+ }
107
+ catch {
108
+ // preserve throwing a specialized error for drives
103
109
  throw new DriveNotFoundError(id);
104
110
  }
105
111
  return drive;
@@ -116,8 +122,21 @@ export class BrowserStorage {
116
122
  throw new Error(`Drive with slug ${slug} not found`);
117
123
  }
118
124
  async createDrive(id, drive) {
119
- const db = await this.db;
120
- await db.setItem(this.buildDriveKey(id), drive);
125
+ // check if a drive with the same slug already exists
126
+ const slug = drive.initialState.state.global.slug;
127
+ if (slug) {
128
+ let existingDrive;
129
+ try {
130
+ existingDrive = await this.getDriveBySlug(slug);
131
+ }
132
+ catch {
133
+ // do nothing
134
+ }
135
+ if (existingDrive) {
136
+ throw new Error(`Drive with slug ${slug} already exists`);
137
+ }
138
+ }
139
+ await this.create(id, drive);
121
140
  // Initialize an empty manifest for the new drive
122
141
  await this.updateDriveManifest(id, { documentIds: [] });
123
142
  }
@@ -129,13 +148,13 @@ export class BrowserStorage {
129
148
  // Delete the drive and its manifest
130
149
  const db = await this.db;
131
150
  await db.removeItem(this.buildManifestKey(id));
132
- return db.removeItem(this.buildDriveKey(id));
151
+ return db.removeItem(this.buildDocumentKey(id));
133
152
  }
134
153
  async addDriveOperations(id, operations, header) {
135
154
  const drive = await this.getDrive(id);
136
155
  const mergedOperations = mergeOperations(drive.operations, operations);
137
156
  const db = await this.db;
138
- await db.setItem(this.buildDriveKey(id), {
157
+ await db.setItem(this.buildDocumentKey(id), {
139
158
  ...drive,
140
159
  ...header,
141
160
  operations: mergedOperations,
@@ -144,16 +163,13 @@ export class BrowserStorage {
144
163
  async getSynchronizationUnitsRevision(units) {
145
164
  const results = await Promise.allSettled(units.map(async (unit) => {
146
165
  try {
147
- const document = await (unit.documentId
148
- ? this.getDocument(unit.driveId, unit.documentId)
149
- : this.getDrive(unit.driveId));
166
+ const document = await this.get(unit.documentId);
150
167
  if (!document) {
151
168
  return undefined;
152
169
  }
153
170
  const operation = document.operations[unit.scope].at(-1);
154
171
  if (operation) {
155
172
  return {
156
- driveId: unit.driveId,
157
173
  documentId: unit.documentId,
158
174
  scope: unit.scope,
159
175
  branch: unit.branch,
@@ -186,7 +202,7 @@ export class BrowserStorage {
186
202
  const drive = await this.getDrive(driveId);
187
203
  const migratedDrive = migrateDocumentOperationSignatures(drive);
188
204
  if (migratedDrive !== drive) {
189
- return (await this.db).setItem(this.buildDriveKey(driveId), migratedDrive);
205
+ return (await this.db).setItem(this.buildDocumentKey(driveId), migratedDrive);
190
206
  }
191
207
  }
192
208
  async migrateDocument(drive, id) {
@@ -199,9 +215,6 @@ export class BrowserStorage {
199
215
  ////////////////////////////////
200
216
  // Private methods
201
217
  ////////////////////////////////
202
- buildDriveKey(driveId) {
203
- return `${BrowserStorage.DRIVES_KEY}${BrowserStorage.SEP}${driveId}`;
204
- }
205
218
  buildDocumentKey(documentId) {
206
219
  return `${BrowserStorage.DOCUMENT_KEY}${BrowserStorage.SEP}${documentId}`;
207
220
  }
@@ -7,6 +7,7 @@ export declare class FilesystemStorage implements IDriveStorage, IDocumentStorag
7
7
  constructor(basePath: string);
8
8
  exists(documentId: string): Promise<boolean>;
9
9
  create(documentId: string, document: PHDocument): Promise<void>;
10
+ get<TDocument extends PHDocument>(documentId: string): Promise<TDocument>;
10
11
  getDocuments(drive: string): Promise<string[]>;
11
12
  checkDocumentExists(drive: string, id: string): Promise<boolean>;
12
13
  getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
@@ -21,7 +22,6 @@ export declare class FilesystemStorage implements IDriveStorage, IDocumentStorag
21
22
  deleteDrive(id: string): Promise<void>;
22
23
  addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
23
24
  getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
24
- driveId: string;
25
25
  documentId: string;
26
26
  scope: string;
27
27
  branch: string;
@@ -29,7 +29,6 @@ export declare class FilesystemStorage implements IDriveStorage, IDocumentStorag
29
29
  revision: number;
30
30
  }[]>;
31
31
  private _buildDocumentPath;
32
- private _buildDrivePath;
33
32
  private _buildManifestPath;
34
33
  private getDriveManifest;
35
34
  private updateDriveManifest;
@@ -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;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"}
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;IAK5C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IAS/C,GAAG,CAAC,SAAS,SAAS,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAgBnE,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;IAIf,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;IASpD,cAAc,CAAC,IAAI,EAAE,MAAM;IAmB3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;IAqBpD,WAAW,CAAC,EAAE,EAAE,MAAM;IAYtB,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,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,kBAAkB;IAI1B,OAAO,CAAC,kBAAkB;YAIZ,gBAAgB;YAWhB,mBAAmB;CAOlC"}
@@ -22,11 +22,23 @@ export class FilesystemStorage {
22
22
  const documentExists = existsSync(this._buildDocumentPath(documentId));
23
23
  return Promise.resolve(documentExists);
24
24
  }
25
- async create(documentId, document) {
25
+ create(documentId, document) {
26
26
  const documentPath = this._buildDocumentPath(documentId);
27
27
  writeFileSync(documentPath, stringify(document), {
28
28
  encoding: "utf-8",
29
29
  });
30
+ return Promise.resolve();
31
+ }
32
+ get(documentId) {
33
+ try {
34
+ const content = readFileSync(this._buildDocumentPath(documentId), {
35
+ encoding: "utf-8",
36
+ });
37
+ return Promise.resolve(JSON.parse(content));
38
+ }
39
+ catch (error) {
40
+ throw new Error(`Document with id ${documentId} not found`);
41
+ }
30
42
  }
31
43
  ////////////////////////////////
32
44
  // IDriveStorage
@@ -39,15 +51,7 @@ export class FilesystemStorage {
39
51
  return this.exists(id);
40
52
  }
41
53
  async getDocument(drive, id) {
42
- try {
43
- const content = readFileSync(this._buildDocumentPath(id), {
44
- encoding: "utf-8",
45
- });
46
- return JSON.parse(content);
47
- }
48
- catch (error) {
49
- throw new Error(`Document with id ${id} not found`);
50
- }
54
+ return this.get(id);
51
55
  }
52
56
  async createDocument(drive, id, document) {
53
57
  const documentPath = this._buildDocumentPath(id);
@@ -113,18 +117,16 @@ export class FilesystemStorage {
113
117
  // get anything that starts with drive-
114
118
  const files = await fs.readdir(this.basePath, { withFileTypes: true });
115
119
  return (files
116
- .filter((file) => file.name.startsWith("drive-"))
117
- // remove drive- prefix and extension
118
- .map((file) => file.name.replace("drive-", "").replace(".json", "")));
120
+ .filter((file) => file.name.startsWith("manifest-"))
121
+ // remove manifest- prefix and extension
122
+ .map((file) => file.name.replace("manifest-", "").replace(".json", "")));
119
123
  }
120
124
  async getDrive(id) {
121
125
  try {
122
- const content = readFileSync(this._buildDrivePath(id), {
123
- encoding: "utf-8",
124
- });
125
- return JSON.parse(content);
126
+ return await this.get(id);
126
127
  }
127
128
  catch (error) {
129
+ // preserve throwing a specialized error for drives
128
130
  throw new DriveNotFoundError(id);
129
131
  }
130
132
  }
@@ -140,10 +142,21 @@ export class FilesystemStorage {
140
142
  throw new Error(`Drive with slug ${slug} not found`);
141
143
  }
142
144
  async createDrive(id, drive) {
143
- const drivePath = this._buildDrivePath(id);
144
- writeFileSync(drivePath, stringify(drive), {
145
- encoding: "utf-8",
146
- });
145
+ // check if a drive with the same slug already exists
146
+ const slug = drive.initialState.state.global.slug;
147
+ if (slug) {
148
+ let existingDrive;
149
+ try {
150
+ existingDrive = await this.getDriveBySlug(slug);
151
+ }
152
+ catch {
153
+ // do nothing
154
+ }
155
+ if (existingDrive) {
156
+ throw new Error(`Drive with slug ${slug} already exists`);
157
+ }
158
+ }
159
+ await this.create(id, drive);
147
160
  // Initialize an empty manifest for the new drive
148
161
  await this.updateDriveManifest(id, { documentIds: [] });
149
162
  }
@@ -153,15 +166,13 @@ export class FilesystemStorage {
153
166
  // Delete each document from this drive (may not actually delete the file if shared with other drives)
154
167
  await Promise.all(documents.map((doc) => this.deleteDocument(id, doc)));
155
168
  // Delete the drive manifest and the drive itself
156
- await fs.rm(this._buildManifestPath(id)).catch(() => {
157
- /* ignore error if manifest doesn't exist */
158
- });
159
- await fs.rm(this._buildDrivePath(id));
169
+ await fs.rm(this._buildManifestPath(id));
170
+ await fs.rm(this._buildDocumentPath(id));
160
171
  }
161
172
  async addDriveOperations(id, operations, header) {
162
173
  const drive = await this.getDrive(id);
163
174
  const mergedOperations = mergeOperations(drive.operations, operations);
164
- const drivePath = this._buildDrivePath(id);
175
+ const drivePath = this._buildDocumentPath(id);
165
176
  writeFileSync(drivePath, stringify({
166
177
  ...drive,
167
178
  ...header,
@@ -173,16 +184,13 @@ export class FilesystemStorage {
173
184
  async getSynchronizationUnitsRevision(units) {
174
185
  const results = await Promise.allSettled(units.map(async (unit) => {
175
186
  try {
176
- const document = await (unit.documentId
177
- ? this.getDocument(unit.driveId, unit.documentId)
178
- : this.getDrive(unit.driveId));
187
+ const document = await this.get(unit.documentId);
179
188
  if (!document) {
180
189
  return undefined;
181
190
  }
182
191
  const operation = document.operations[unit.scope].at(-1);
183
192
  if (operation) {
184
193
  return {
185
- driveId: unit.driveId,
186
194
  documentId: unit.documentId,
187
195
  scope: unit.scope,
188
196
  branch: unit.branch,
@@ -208,9 +216,6 @@ export class FilesystemStorage {
208
216
  _buildDocumentPath(documentId) {
209
217
  return `${this.basePath}/document-${documentId}.json`;
210
218
  }
211
- _buildDrivePath(driveId) {
212
- return `${this.basePath}/drive-${driveId}.json`;
213
- }
214
219
  _buildManifestPath(driveId) {
215
220
  return `${this.basePath}/manifest-${driveId}.json`;
216
221
  }
@@ -8,6 +8,7 @@ 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>;
11
12
  checkDocumentExists(drive: string, id: string): Promise<boolean>;
12
13
  getDocuments(drive: string): Promise<string[]>;
13
14
  getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
@@ -22,7 +23,6 @@ export declare class IPFSStorage implements IStorage, IDocumentStorage {
22
23
  addDriveOperations(id: string, operations: Operation<DocumentDriveAction>[], header: DocumentHeader): Promise<void>;
23
24
  clearStorage(): Promise<void>;
24
25
  getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
25
- driveId: string;
26
26
  documentId: string;
27
27
  scope: string;
28
28
  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;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"}
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;IAO/D,GAAG,CAAC,SAAS,SAAS,UAAU,EACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,CAAC;IAsBf,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;IAIf,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,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,kBAAkB;IAI1B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,uBAAuB;YAIjB,gBAAgB;YAgBhB,mBAAmB;CASlC"}
@@ -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
- ////////////////////////////////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) {
33
+ async get(documentId) {
44
34
  try {
45
- const documentPath = this._buildDocumentPath(id);
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,9 +42,22 @@ export class IPFSStorage {
52
42
  return JSON.parse(content);
53
43
  }
54
44
  catch (error) {
55
- throw new Error(`Document with id ${id} not found`);
45
+ throw new Error(`Document with id ${documentId} not found`);
56
46
  }
57
47
  }
48
+ ////////////////////////////////s
49
+ // IDriveStorage
50
+ ////////////////////////////////
51
+ async checkDocumentExists(drive, id) {
52
+ return this.exists(id);
53
+ }
54
+ async getDocuments(drive) {
55
+ const manifest = await this.getDriveManifest(drive);
56
+ return manifest.documentIds;
57
+ }
58
+ async getDocument(drive, id) {
59
+ return this.get(id);
60
+ }
58
61
  async createDocument(drive, id, document) {
59
62
  await this.create(id, document);
60
63
  // Update the drive manifest to include this document
@@ -208,16 +211,13 @@ export class IPFSStorage {
208
211
  async getSynchronizationUnitsRevision(units) {
209
212
  const results = await Promise.allSettled(units.map(async (unit) => {
210
213
  try {
211
- const document = await (unit.documentId
212
- ? this.getDocument(unit.driveId, unit.documentId)
213
- : this.getDrive(unit.driveId));
214
+ const document = await this.get(unit.documentId);
214
215
  if (!document) {
215
216
  return undefined;
216
217
  }
217
218
  const operation = document.operations[unit.scope].at(-1);
218
219
  if (operation) {
219
220
  return {
220
- driveId: unit.driveId,
221
221
  documentId: unit.documentId,
222
222
  scope: unit.scope,
223
223
  branch: unit.branch,
@@ -4,16 +4,14 @@ 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>;
11
+ get<TDocument extends PHDocument>(documentId: string): Promise<TDocument>;
13
12
  checkDocumentExists(drive: string, id: string): Promise<boolean>;
14
13
  getDocuments(drive: string): Promise<string[]>;
15
14
  getDocument<TDocument extends PHDocument>(driveId: string, id: string): Promise<TDocument>;
16
- saveDocument(drive: string, id: string, document: PHDocument): Promise<void>;
17
15
  clearStorage(): Promise<void>;
18
16
  createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
19
17
  addDocumentOperations(drive: string, id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
@@ -25,7 +23,6 @@ export declare class MemoryStorage implements IDriveStorage, IDocumentStorage {
25
23
  addDriveOperations(id: string, operations: OperationFromDocument<DocumentDriveDocument>[], header: DocumentHeader): Promise<void>;
26
24
  deleteDrive(id: string): Promise<void>;
27
25
  getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
28
- driveId: string;
29
26
  documentId: string;
30
27
  scope: string;
31
28
  branch: string;
@@ -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,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"}
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;IAkBzE,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;IAcxC,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,gBAAgB;IAQxB,OAAO,CAAC,mBAAmB;CAG5B"}
@@ -2,24 +2,32 @@ 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;
21
18
  return Promise.resolve();
22
19
  }
20
+ get(documentId) {
21
+ const document = this.documents[documentId];
22
+ if (!document) {
23
+ const drive = this.documents[`drive/${documentId}`];
24
+ if (drive) {
25
+ return Promise.resolve(drive);
26
+ }
27
+ throw new Error(`Document with id ${documentId} not found`);
28
+ }
29
+ return Promise.resolve(document);
30
+ }
23
31
  ////////////////////////////////
24
32
  // IDriveStorage
25
33
  ////////////////////////////////
@@ -30,25 +38,12 @@ export class MemoryStorage {
30
38
  const manifest = this.getDriveManifest(drive);
31
39
  return Promise.resolve([...manifest.documentIds]);
32
40
  }
33
- async getDocument(driveId, id) {
34
- const document = this.documents[id];
35
- if (!document) {
36
- throw new Error(`Document with id ${id} not found`);
37
- }
38
- return document;
39
- }
40
- async saveDocument(drive, id, document) {
41
- this.documents[id] = document;
42
- // Update the drive manifest
43
- const manifest = this.getDriveManifest(drive);
44
- manifest.documentIds.add(id);
45
- this.updateDriveManifest(drive, manifest);
41
+ getDocument(driveId, id) {
42
+ return this.get(id);
46
43
  }
47
44
  async clearStorage() {
48
45
  this.documents = {};
49
- this.drives = {};
50
46
  this.driveManifests = {};
51
- this.slugToDriveId = {};
52
47
  }
53
48
  async createDocument(drive, id, document) {
54
49
  await this.create(id, document);
@@ -82,35 +77,47 @@ export class MemoryStorage {
82
77
  delete this.documents[id];
83
78
  }
84
79
  async getDrives() {
85
- return Object.keys(this.drives);
80
+ return Object.keys(this.driveManifests);
86
81
  }
87
82
  async getDrive(id) {
88
- const drive = this.drives[id];
83
+ const drive = this.documents[`drive/${id}`];
89
84
  if (!drive) {
90
85
  throw new DriveNotFoundError(id);
91
86
  }
92
87
  return drive;
93
88
  }
94
89
  async getDriveBySlug(slug) {
95
- const driveId = this.slugToDriveId[slug];
96
- if (!driveId) {
97
- throw new Error(`Drive with slug ${slug} not found`);
90
+ for (const driveId of Object.keys(this.driveManifests)) {
91
+ const drive = this.documents[`drive/${driveId}`];
92
+ if (drive.initialState.state.global.slug === slug) {
93
+ return drive;
94
+ }
98
95
  }
99
- return this.getDrive(driveId);
96
+ throw new Error(`Drive with slug ${slug} not found`);
100
97
  }
101
98
  async createDrive(id, drive) {
102
- this.drives[id] = drive;
103
- // Initialize an empty manifest for the new drive
104
- this.updateDriveManifest(id, { documentIds: new Set() });
105
- const { slug } = drive.initialState.state.global;
99
+ // check if a drive with the same slug already exists
100
+ const slug = drive.initialState.state.global.slug;
106
101
  if (slug) {
107
- this.slugToDriveId[slug] = id;
102
+ let existingDrive;
103
+ try {
104
+ existingDrive = await this.getDriveBySlug(slug);
105
+ }
106
+ catch {
107
+ // do nothing
108
+ }
109
+ if (existingDrive) {
110
+ throw new Error(`Drive with slug ${slug} already exists`);
111
+ }
108
112
  }
113
+ await this.create(`drive/${id}`, drive);
114
+ // Initialize an empty manifest for the new drive
115
+ this.updateDriveManifest(id, { documentIds: new Set() });
109
116
  }
110
117
  async addDriveOperations(id, operations, header) {
111
118
  const drive = await this.getDrive(id);
112
119
  const mergedOperations = mergeOperations(drive.operations, operations);
113
- this.drives[id] = {
120
+ this.documents[`drive/${id}`] = {
114
121
  ...drive,
115
122
  ...header,
116
123
  operations: mergedOperations,
@@ -135,27 +142,18 @@ export class MemoryStorage {
135
142
  }));
136
143
  // Delete the drive manifest and the drive itself
137
144
  delete this.driveManifests[id];
138
- delete this.drives[id];
139
- // Clean up slug mapping if needed
140
- for (const [slug, driveId] of Object.entries(this.slugToDriveId)) {
141
- if (driveId === id) {
142
- delete this.slugToDriveId[slug];
143
- }
144
- }
145
+ delete this.documents[id];
145
146
  }
146
147
  async getSynchronizationUnitsRevision(units) {
147
148
  const results = await Promise.allSettled(units.map(async (unit) => {
148
149
  try {
149
- const document = await (unit.documentId
150
- ? this.getDocument(unit.driveId, unit.documentId)
151
- : this.getDrive(unit.driveId));
150
+ const document = await this.get(unit.documentId);
152
151
  if (!document) {
153
152
  return undefined;
154
153
  }
155
154
  const operation = document.operations[unit.scope].at(-1);
156
155
  if (operation) {
157
156
  return {
158
- driveId: unit.driveId,
159
157
  documentId: unit.documentId,
160
158
  scope: unit.scope,
161
159
  branch: unit.branch,
@@ -1,8 +1,9 @@
1
1
  import { PrismaStorage } from "#storage/prisma/index";
2
+ import { IOperationsCache } from "#storage/types";
2
3
  export declare class PrismaStorageFactory {
3
- private readonly dbUrl;
4
- private prisma;
5
- constructor(dbUrl: string);
4
+ private readonly prisma;
5
+ private readonly cache;
6
+ constructor(dbUrl: string, cache: IOperationsCache);
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;IAGnB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,MAAM,CAAoC;gBAErB,KAAK,EAAE,MAAM;IAU1C,KAAK;CAGN"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/storage/prisma/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIlD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;gBAE7B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB;IAWlD,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
- constructor(dbUrl) {
8
- this.dbUrl = dbUrl;
6
+ cache;
7
+ constructor(dbUrl, cache) {
8
+ this.cache = cache;
9
9
  this.prisma = new PrismaClient({
10
10
  datasources: {
11
11
  db: {
12
- url: this.dbUrl,
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
  }