@telecrypt-io/storage 0.5.29 → 0.5.30

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.
@@ -205,37 +205,6 @@ async function resolveFile(storage, tree, fileId, signal) {
205
205
  throw new StorageError("file lookup failed", { cause: error });
206
206
  }
207
207
  }
208
- function snapshotTreeSpaces(root, tooLargeMessage = "storage tree is too large") {
209
- const spaces = [];
210
- const seen = new Set();
211
- const pending = [{ tree: root, depth: 0 }];
212
- while (pending.length > 0) {
213
- const next = pending.pop();
214
- if (!next)
215
- continue;
216
- const { tree, depth } = next;
217
- if (seen.has(tree.id))
218
- continue;
219
- if (depth > MAX_DELETION_DEPTH || spaces.length >= MAX_DELETION_ROOMS) {
220
- throw new StorageError(tooLargeMessage);
221
- }
222
- seen.add(tree.id);
223
- spaces.push(tree);
224
- let children;
225
- try {
226
- children = tree.getDirectories();
227
- }
228
- catch (error) {
229
- throw new StorageError("could not enumerate storage space descendants safely", { cause: error });
230
- }
231
- if (children.length > MAX_DELETION_ROOMS) {
232
- throw new StorageError(tooLargeMessage);
233
- }
234
- for (const child of children)
235
- pending.push({ tree: child, depth: depth + 1 });
236
- }
237
- return spaces;
238
- }
239
208
  /**
240
209
  * Deleting a tree is deliberately a one-room operation. File versions are
241
210
  * physical Matrix media events, so callers must delete files explicitly and
@@ -318,6 +287,62 @@ function isActiveRelationEvent(event) {
318
287
  !Array.isArray(content) &&
319
288
  Object.keys(content).length > 0);
320
289
  }
290
+ function activeTreeDirectories(client, tree) {
291
+ const childEvents = readRelationEvents(client, tree.id, EventType.SpaceChild);
292
+ if (childEvents === null)
293
+ throw new StorageError("delete graph is unsafe");
294
+ const activeChildIds = new Set();
295
+ for (const event of childEvents) {
296
+ if (!isActiveRelationEvent(event))
297
+ continue;
298
+ const childId = relationStateKey(event);
299
+ if (!childId)
300
+ throw new StorageError("delete graph is unsafe");
301
+ activeChildIds.add(childId);
302
+ }
303
+ const knownChildren = new Map(tree.getDirectories().map((child) => [child.id, child]));
304
+ return [...activeChildIds].map((childId) => {
305
+ const child = knownChildren.get(childId);
306
+ if (!child)
307
+ throw new StorageError("delete graph is unsafe");
308
+ return child;
309
+ });
310
+ }
311
+ function snapshotTreeSpaces(root, tooLargeMessage = "storage tree is too large", activeRelationClient) {
312
+ const spaces = [];
313
+ const seen = new Set();
314
+ const pending = [{ tree: root, depth: 0 }];
315
+ while (pending.length > 0) {
316
+ const next = pending.pop();
317
+ if (!next)
318
+ continue;
319
+ const { tree, depth } = next;
320
+ if (seen.has(tree.id))
321
+ continue;
322
+ if (depth > MAX_DELETION_DEPTH || spaces.length >= MAX_DELETION_ROOMS) {
323
+ throw new StorageError(tooLargeMessage);
324
+ }
325
+ seen.add(tree.id);
326
+ spaces.push(tree);
327
+ let children;
328
+ try {
329
+ children = activeRelationClient
330
+ ? activeTreeDirectories(activeRelationClient, tree)
331
+ : tree.getDirectories();
332
+ }
333
+ catch (error) {
334
+ if (error instanceof StorageError)
335
+ throw error;
336
+ throw new StorageError("could not enumerate storage space descendants safely", { cause: error });
337
+ }
338
+ if (children.length > MAX_DELETION_ROOMS) {
339
+ throw new StorageError(tooLargeMessage);
340
+ }
341
+ for (const child of children)
342
+ pending.push({ tree: child, depth: depth + 1 });
343
+ }
344
+ return spaces;
345
+ }
321
346
  /**
322
347
  * A deleted MSC3089 branch is represented by an authoritative empty state
323
348
  * event. Inactive branches with metadata are historical versions, and a
@@ -358,13 +383,7 @@ function validateDeletionGraph(client, root, ids, deletedRooms) {
358
383
  const tree = client.unstableGetFileTreeSpace(id);
359
384
  if (!tree)
360
385
  throw new StorageError("delete graph is unsafe");
361
- let directories;
362
- try {
363
- directories = tree.getDirectories();
364
- }
365
- catch (error) {
366
- throw new StorageError("delete graph is unsafe", { cause: error });
367
- }
386
+ const directories = activeTreeDirectories(client, tree);
368
387
  for (const child of directories)
369
388
  addEdge(id, child.id);
370
389
  const childEvents = readRelationEvents(client, id, EventType.SpaceChild);
@@ -1013,8 +1032,7 @@ export async function listSubfolders(storage, parentId, options) {
1013
1032
  const tree = await resolveTree(storage, parentId, signal);
1014
1033
  await storage.refreshRoomState(parentId, { signal });
1015
1034
  ensureOperationActive(signal);
1016
- const directories = tree
1017
- .getDirectories()
1035
+ const directories = activeTreeDirectories(storage.getClient(), tree)
1018
1036
  .filter((directory) => !isMarkedTreeDeleted(storage, directory.id));
1019
1037
  return directories.map((d) => ({ id: d.id, name: d.room.name }));
1020
1038
  });
@@ -1094,7 +1112,7 @@ async function deleteTree(storage, treeId, options) {
1094
1112
  // part of this operation and must not block deletion merely because
1095
1113
  // their membership is not joined.
1096
1114
  await refreshDeletionRooms(storage, tree.id, operation.signal);
1097
- const spaces = snapshotTreeSpaces(tree, "delete graph is too large");
1115
+ const spaces = snapshotTreeSpaces(tree, "delete graph is too large", client);
1098
1116
  const activeSpaces = spaces.filter((space) => !removedRooms.has(space.id));
1099
1117
  const ids = new Set(activeSpaces.map((space) => space.id));
1100
1118
  if (!ids.has(tree.id)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telecrypt-io/storage",
3
- "version": "0.5.29",
3
+ "version": "0.5.30",
4
4
  "license": "BUSL-1.1",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.19.0",