From ceb04f3ac73064eb0319124336a95b0270bf7e98 Mon Sep 17 00:00:00 2001 From: hexastack Date: Wed, 23 Apr 2025 12:30:13 +0100 Subject: [PATCH 1/2] fix: remove links refering to moved blocks --- api/src/chat/repositories/block.repository.ts | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/api/src/chat/repositories/block.repository.ts b/api/src/chat/repositories/block.repository.ts index 78903a3ca..cf2b34902 100644 --- a/api/src/chat/repositories/block.repository.ts +++ b/api/src/chat/repositories/block.repository.ts @@ -205,17 +205,30 @@ export class BlockRepository extends BaseRepository< otherBlocks: Block[], ids: string[], ): Promise { + // Fetch all moved blocks with their nextBlocks + const movedBlocks = await this.find({ _id: { $in: ids } }); + + // Build a set of all blocks the moved blocks are pointing to + const movedBlockLinkTargets = new Set(); + for (const block of movedBlocks) { + block.nextBlocks?.forEach((id) => movedBlockLinkTargets.add(id)); + } + for (const block of otherBlocks) { if (block.attachedBlock && ids.includes(block.attachedBlock)) { await this.updateOne(block.id, { attachedBlock: null }); } - const nextBlocks = block.nextBlocks?.filter( - (nextBlock) => !ids.includes(nextBlock), - ); + if (block.nextBlocks?.length) { + const updatedNextBlocks = block.nextBlocks.filter((nextBlockId) => { + return ( + !ids.includes(nextBlockId) || movedBlockLinkTargets.has(block.id) + ); + }); - if (nextBlocks?.length) { - await this.updateOne(block.id, { nextBlocks }); + if (updatedNextBlocks.length !== block.nextBlocks.length) { + await this.updateOne(block.id, { nextBlocks: updatedNextBlocks }); + } } } } From e480da6513235a7d0248158302e7d897f051e4bb Mon Sep 17 00:00:00 2001 From: hexastack Date: Mon, 28 Apr 2025 17:53:58 +0100 Subject: [PATCH 2/2] fix: apply feedback --- api/src/chat/repositories/block.repository.ts | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/api/src/chat/repositories/block.repository.ts b/api/src/chat/repositories/block.repository.ts index cf2b34902..f4df2977c 100644 --- a/api/src/chat/repositories/block.repository.ts +++ b/api/src/chat/repositories/block.repository.ts @@ -177,19 +177,29 @@ export class BlockRepository extends BaseRepository< category: { $ne: category }, }); - for (const { id, nextBlocks, attachedBlock } of blocks) { - const updatedNextBlocks = nextBlocks.filter((nextBlock) => - ids.includes(nextBlock), - ); + const concurrencyLimit = 10; + + const tasks = blocks.map( + ({ id, nextBlocks, attachedBlock }) => + async () => { + const updatedNextBlocks = nextBlocks.filter((nextBlock) => + ids.includes(nextBlock), + ); - const updatedAttachedBlock = ids.includes(attachedBlock || '') - ? attachedBlock - : null; + const updatedAttachedBlock = ids.includes(attachedBlock || '') + ? attachedBlock + : null; + + await this.updateOne(id, { + nextBlocks: updatedNextBlocks, + attachedBlock: updatedAttachedBlock, + }); + }, + ); - await this.updateOne(id, { - nextBlocks: updatedNextBlocks, - attachedBlock: updatedAttachedBlock, - }); + for (let i = 0; i < tasks.length; i += concurrencyLimit) { + const batch = tasks.slice(i, i + concurrencyLimit); + await Promise.all(batch.map((task) => task())); } } @@ -214,9 +224,12 @@ export class BlockRepository extends BaseRepository< block.nextBlocks?.forEach((id) => movedBlockLinkTargets.add(id)); } - for (const block of otherBlocks) { + const concurrencyLimit = 10; + const allUpdateTasks = otherBlocks.map((block) => async () => { + const promises: Promise[] = []; + if (block.attachedBlock && ids.includes(block.attachedBlock)) { - await this.updateOne(block.id, { attachedBlock: null }); + promises.push(this.updateOne(block.id, { attachedBlock: null })); } if (block.nextBlocks?.length) { @@ -227,9 +240,18 @@ export class BlockRepository extends BaseRepository< }); if (updatedNextBlocks.length !== block.nextBlocks.length) { - await this.updateOne(block.id, { nextBlocks: updatedNextBlocks }); + promises.push( + this.updateOne(block.id, { nextBlocks: updatedNextBlocks }), + ); } } + + await Promise.all(promises); + }); + + for (let i = 0; i < allUpdateTasks.length; i += concurrencyLimit) { + const batch = allUpdateTasks.slice(i, i + concurrencyLimit); + await Promise.all(batch.map((task) => task())); } }