Fix findUsages/undo/node-lookup bugs, split Viewport and Editor, share command and inspector helpers

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-08 09:22:49 +02:00
1 parent 1eb28314cf
commit f140c2fd77
58 files changed
+1969 -1171

No files matched your search

+19
View File
@@ -4,6 +4,17 @@ export interface Removed<T> {
index: number;
}
/**
* Removes the first item matching `predicate` in place and returns it with its former index.
* `undefined` means nothing matched – the list is then untouched, so a caller may reject the
* edit afterwards without having to revert anything.
*/
export function removeFirst<T>(list: T[], predicate: (item: T) => boolean): Removed<T> | undefined {
const index = list.findIndex(predicate);
// A valid index makes `splice` return exactly one element; the `!` is that index check.
return index < 0 ? undefined : { item: list.splice(index, 1)[0]!, index };
}
/** Removes every item matching `predicate` in place; returns them with their former indices, ascending. */
export function removeWhere<T>(list: T[], predicate: (item: T) => boolean): Removed<T>[] {
const removed: Removed<T>[] = [];
@@ -18,3 +29,11 @@ export function removeWhere<T>(list: T[], predicate: (item: T) => boolean): Remo
export function restoreAt<T>(list: T[], removed: readonly Removed<T>[]): void {
for (const entry of [...removed].sort((a, b) => a.index - b.index)) list.splice(entry.index, 0, entry.item);
}
/**
* A **new** list without the item carrying `id` – unlike the `remove*` helpers above this one
* does not mutate, which is what undoing a `push` needs: `list = removeById(list, id)`.
*/
export function removeById<T extends { id: string }>(list: readonly T[], id: string): T[] {
return list.filter((item) => item.id !== id);
}