Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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-08-10 - Array density check optimization
**Learning:** Using `Array.from().every()` to check for array density creates O(N) intermediate array allocations which add unnecessary garbage collection overhead on the critical path.
**Action:** Use a standard for-loop with an early return for an O(1) memory and faster check.
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^1.24.0",
"pdfjs-dist": "6.1.200",
"pdfjs-dist": "^6.2.108",
"react": "^19.2.4",
"react-dom": "^19.2.7",
"sonner": "^2.0.7",
Expand Down
20 changes: 20 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,24 @@ describe("scoreStorage bridge resolution", () => {
BRIDGE_UNAVAILABLE_MESSAGE
);
});
it("uses the fallback loop for array density checking", 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).toBeInstanceOf(Uint8Array);
expect(result.length).toBe(3);
expect(result[0]).toBe(1);
expect(result[1]).toBe(2);
expect(result[2]).toBe(3);
});

it("fails array density check if non-number elements are present", async () => {
const tauriWindow = window as TauriWindow;
tauriWindow.__TAURI_INVOKE__ = vi.fn().mockResolvedValue([1, "two", 3]);

await expect(readScorePdf("project-1", "score-1")).rejects.toThrow(
"Invalid score bridge response"
);
});
});
15 changes: 13 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,19 @@ 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)) {
// 성능 최적화: O(N) 콜백 호출 오버헤드를 줄이기 위해 for 루프 사용
let isNumberArray = true;
for (let i = 0; i < response.length; i++) {
if (typeof response[i] !== "number") {
isNumberArray = false;
break;
}
}

if (isNumberArray) {
return Uint8Array.from(response as number[]);
}
}

throw new Error(INVALID_RESPONSE_MESSAGE);
Expand Down
Loading
Loading