| ... | ... | @@ -139,22 +139,27 @@ export function computeThreadMoveAvailability(input: { |
| 139 | 139 | for (const row of rows) result.set(rowId(row), { canMoveUp: false, canMoveDown: false }); |
| 140 | 140 | return result; |
| 141 | 141 | } |
| 142 | | const orderedIds = rows.map(rowId); |
| 143 | | const indexById = new Map(orderedIds.map((id, index) => [id, index] as const)); |
| 144 | | const keysById = new Map( |
| 145 | | (input.allThreads ?? input.ordered).map( |
| 146 | | (row) => [rowId(row), rowOrder(row, input.section).key] as const, |
| 147 | | ), |
| 148 | | ); |
| 149 | | const writableIds = new Set( |
| 150 | | (input.allThreads ?? input.ordered) |
| 151 | | .filter((row) => input.reorderableEnvironmentIds.has(row.environmentId)) |
| 152 | | .map(rowId), |
| 153 | | ); |
| 154 | | const visibleIds = new Set(orderedIds); |
| 155 | | const reservedKeys = new Set( |
| 156 | | [...keysById].flatMap(([id, key]) => (!visibleIds.has(id) && key != null ? [key] : [])), |
| 157 | | ); |
| 142 | // Plain loops: this runs per section on every Home rebuild over all shells, |
| 143 | // and the map/filter/spread chains it replaces dominated it with garbage. |
| 144 | const orderedIds: string[] = []; |
| 145 | const indexById = new Map<string, number>(); |
| 146 | for (const row of rows) { |
| 147 | const id = rowId(row); |
| 148 | indexById.set(id, orderedIds.length); |
| 149 | orderedIds.push(id); |
| 150 | } |
| 151 | const keysById = new Map<string, string | null>(); |
| 152 | const writableIds = new Set<string>(); |
| 153 | for (const row of input.allThreads ?? input.ordered) { |
| 154 | const id = rowId(row); |
| 155 | keysById.set(id, rowOrder(row, input.section).key); |
| 156 | if (input.reorderableEnvironmentIds.has(row.environmentId)) writableIds.add(id); |
| 157 | } |
| 158 | // Read after the loop so a duplicate id reserves only its final key. |
| 159 | const reservedKeys = new Set<string>(); |
| 160 | keysById.forEach((key, id) => { |
| 161 | if (key != null && !indexById.has(id)) reservedKeys.add(key); |
| 162 | }); |
| 158 | 163 | // Mirror of `planPinnedReorder` for adjacent swaps, hoisted so every row is |
| 159 | 164 | // answered in O(1) amortized instead of one planner probe per row: |
| 160 | 165 | // |