refactor: move the upload checkpoint store onto the IndexedDB kernel

712 -> 612줄. 연결 수명주기와 트랜잭션 상태기계가 커널로 갔고 CP의 손수
abort 리스너가 0이 됐다. 그래서 abort 래칫을 24에서 23으로 조인다.

보존한 동작 다섯 가지:
- 값 없는 완료는 CORRUPT_DATA/RECONCILE (translate에 NO_VALUE_PRODUCED를
  명시 매핑). 빠뜨리면 UNAVAILABLE로 바뀐다
- durability는 undefined를 명시적으로 넘긴다. 커널 기본이나 strict를 쓰면
  체크포인트 쓰기가 조용히 느려진다
- nativeFailure 6곳 전부 context.fail. requestFailed로 바꾸면 요청이
  실패했는데도 뒤 요청이 커밋된다
- abort()가 throw하면 caller-abort 주장을 철회한다 (커널이 이미 구현)
- blocked 타이머는 주입형 timers

사양이 빠뜨린 함정 하나를 추가로 막았다. bindScope는 succeed()에 해당하는
것이 없어 그대로 옮기면 정상 바인딩이 NO_VALUE_PRODUCED로 보고된다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-16 19:24:09 +09:00
co-authored by Claude Opus 5
parent 35f3c9ce23
commit bb6080bb1c
3 changed files with 546 additions and 386 deletions
+6 -3
View File
@@ -133,7 +133,7 @@ async function main(): Promise<void> {
//
// 이 목록은 재검토가 이름으로 지목한 네 파일만 덮는다. 같은 두 그룹의
// `image-cdn-runtime.ts`와 `resumable-upload-runtime.ts`는 여기 없고 지금도
// 자기 abort 사본을 들고 있다. 어댑터 전체로는 24개 파일이 그렇다. 그 전수
// 자기 abort 사본을 들고 있다. 어댑터 전체로는 23개 파일이 그렇다. 그 전수
// 이행은 abort 의미론을 바꾸는 별도 작업이라 이 목록으로 강제하지 않고,
// 아래 래칫이 개수가 늘어나는 것만 막는다.
const REQUIRED_ABORT_CONSUMERS: readonly string[] = [
@@ -190,12 +190,15 @@ async function main(): Promise<void> {
// 손수 짠 abort 배선은 줄어들기만 해야 한다.
//
// 커널 `platform/abortable-operation.ts`가 있는데도 어댑터 24개 파일이
// 커널 `platform/abortable-operation.ts`가 있는데도 어댑터 23개 파일이
// `addEventListener("abort")`로 같은 race/cleanup을 각자 짠다. 그 전수 이행은
// 동작이 바뀌는 큰 작업이라 한 번에 하지 않는다. 대신 개수를 여기 고정해
// 되돌아가지 못하게 한다. 이행으로 숫자가 내려가면 이 상수도 같이 내린다.
// `platform/`은 커널 자신이므로 세지 않는다.
const HAND_ROLLED_ABORT_CEILING = 24;
//
// 24 → 23: `browser-transfer/resumable-upload/indexeddb-checkpoint-store.ts`가
// IndexedDB 커널로 옮겨가면서 자기 abort 리스너를 지웠다.
const HAND_ROLLED_ABORT_CEILING = 23;
const handRolledScan = spawnSync(
"git",
["grep", "-l", 'addEventListener("abort"', "--", "src/adapters"],