Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
7486f9d
⚡ Bolt: 최적화된 배열 반복문으로 교체
seonghobae Sep 22, 2026
6cf3307
⚡ Bolt: 최적화된 배열 반복문으로 교체
seonghobae Sep 22, 2026
c910add
repair(perf): restore formatter-owner boundary
seonghobae Sep 22, 2026
a6c3682
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 23, 2026
4909f1d
repair(perf): restore GrooveMap preservation after foreign Score delta
seonghobae Sep 23, 2026
f49deb3
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 23, 2026
d8a8d20
repair(perf): restore GrooveMap preservation after repeated foreign-o…
seonghobae Sep 23, 2026
ef60eb2
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 23, 2026
6974375
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
146c87d
repair(perf): restore #1251 single-writer preservation
seonghobae Sep 24, 2026
b8fd201
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
3259722
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
83a4cf3
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
6bf57c0
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
0b574b9
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 24, 2026
80616f6
preserve(perf): return duplicate Score and GrooveMap lane to protecte…
seonghobae Sep 24, 2026
323027c
⚡ Bolt: 최적화된 바이트 배열 검증 로직으로 교체
seonghobae Sep 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@
## 2026-07-13 - Array.from mapping optimization
**Learning:** Using `Array.from({ length: N }).map(...)` creates an intermediate array of `undefined` values which requires memory allocation and garbage collection, adding O(N) unnecessary overhead in frequently re-rendered UI components.
**Action:** Use `Array.from({ length: N }, (_, index) => ...)` to map elements directly during array creation, avoiding intermediate allocations.

## 2026-07-15 - Replace Array.every for large byte arrays
**Learning:** Using `Array.prototype.every()` on very large arrays (like serialized PDF byte buffers) introduces massive function call overhead for each element, leading to severe main-thread blocking.
**Action:** Use a standard `for` loop with an early return to check large byte arrays, avoiding O(N) callback allocations.
17 changes: 17 additions & 0 deletions apps/desktop/src/features/score/scoreStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,21 @@ describe("scoreStorage bridge resolution", () => {
BRIDGE_UNAVAILABLE_MESSAGE
);
});

it("correctly reads a score pdf returning a number array", async () => {
const tauriWindow = window as TauriWindow;
tauriWindow.__TAURI_INVOKE__ = vi.fn().mockResolvedValue([1, 2, 3]);

const result = await readScorePdf("project-1", "score-1");
expect(result).toEqual(new Uint8Array([1, 2, 3]));
});

it("rejects reading a score pdf when returning an array with non-numbers", async () => {
const tauriWindow = window as TauriWindow;
tauriWindow.__TAURI_INVOKE__ = vi.fn().mockResolvedValue([1, 2, "not a number"]);

await expect(readScorePdf("project-1", "score-1")).rejects.toThrow(
"Invalid score bridge response"
);
});
});
17 changes: 15 additions & 2 deletions apps/desktop/src/features/score/scoreStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,21 @@ export async function readScorePdf(projectId: string, scoreId: string): Promise<
if (response instanceof ArrayBuffer) {
return new Uint8Array(response);
}
if (Array.isArray(response) && response.every((byte) => typeof byte === "number")) {
return Uint8Array.from(response as number[]);
if (Array.isArray(response)) {
// Performance: Avoid Array.every() and Uint8Array.from() to prevent O(N) callback overhead
// and intermediate array allocations when parsing potentially large PDF byte arrays.
const uint8Arr = new Uint8Array(response.length);
let allNumbers = true;
for (let i = 0; i < response.length; i++) {
if (typeof response[i] !== "number") {
allNumbers = false;
break;
}
uint8Arr[i] = response[i] as number;
}
if (allNumbers) {
return uint8Arr;
}
}

throw new Error(INVALID_RESPONSE_MESSAGE);
Expand Down
Loading