스토리지 버킷 API

커뮤니티 그룹 보고서 초안,

이 버전:
https://wicg.github.io/storage-buckets/
이슈 추적:
GitHub
명세 내 인라인
편집자:
(Google)
(Google)
이전 편집자:
Victor Costan
참여:
GitHub WICG/storage-buckets (새 이슈, 열린 이슈)

초록

Storage Buckets API는 사이트가 로컬에 저장된 데이터를 "스토리지 버킷"이라고 하는 그룹으로 구성할 수 있는 방법을 제공한다. 이를 통해 사용자 에이전트나 사이트는 단일 출처의 모든 데이터에 동일한 처리를 적용하는 대신 버킷을 독립적으로 관리하고 삭제할 수 있다.

이 문서의 상태

이 명세는 Web Platform Incubator Community Group에 의해 공개되었다. 이는 W3C 표준이 아니며 W3C 표준화 트랙에도 있지 않다. W3C 커뮤니티 기여자 라이선스 계약(CLA)에 따라 제한적인 옵트아웃 및 기타 조건이 적용된다는 점에 유의하라. W3C 커뮤니티 및 비즈니스 그룹에 대해 자세히 알아보라.

1. StorageBucketManager 인터페이스

[SecureContext]
interface mixin NavigatorStorageBuckets {
  [SameObject] readonly attribute StorageBucketManager storageBuckets;
};
Navigator includes NavigatorStorageBuckets;
WorkerNavigator includes NavigatorStorageBuckets;

환경 설정 객체는 연관된 StorageBucketManager 객체를 가진다.

storageBuckets getter 단계는 this관련 설정 객체StorageBucketManager 객체를 반환하는 것이다.

사용자 에이전트는 연관된 storage bucket manager를 가지며, 이는 새 병렬 큐 시작의 결과이다.

[Exposed=(Window,Worker),
 SecureContext]
interface StorageBucketManager {
    Promise<StorageBucket> open(DOMString name, optional StorageBucketOptions options = {});
    Promise<sequence<DOMString>> keys();
    Promise<undefined> delete(DOMString name);
};

dictionary StorageBucketOptions {
  boolean persisted = false;
  unsigned long long quota;
  DOMHighResTimeStamp expires;
};

1.1. 버킷 생성

open(name, options) 메서드 단계는 다음과 같다:

  1. environmentthis관련 설정 객체로 둔다.

  2. shelfenvironment가 주어졌을 때 로컬 스토리지 선반 획득을 실행한 결과로 둔다.

  3. shelf가 failure이면, TypeError거부된 promise를 반환한다.

  4. name으로 버킷 이름 검증을 수행한 결과가 failure이면, TypeError거부된 promise를 반환한다.

  5. p새 promise로 둔다.

  6. 다음 단계를 storage bucket manager큐에 넣는다:

    1. rshelf, name, options버킷 열기를 실행한 결과로 둔다.

    2. r가 failure이면, TypeErrorpreject하기 위해 스토리지 작업을 큐에 넣는다.

    3. 그렇지 않으면, rpresolve하기 위해 스토리지 작업을 큐에 넣는다.

  7. p를 반환한다.

shelf에 대해, 버킷 name과 선택적 options가 주어졌을 때 버킷 열기를 하려면, 다음 단계를 실행한다:

  1. expires를 undefined로 둔다.

  2. options["expires"]가 존재하면 다음을 수행한다:

    1. expiresoptions["expires"]로 설정한다.

    2. Unix epoch 이후 expires 밀리초가 관련 설정 객체현재 벽시계 시간보다 전이면 failure를 반환한다.

  3. quota를 undefined로 둔다.

  4. options["quota"]가 존재하면 다음을 수행한다:

    1. quotaoptions["quota"]로 설정한다.

    2. quota가 0 이하이면 failure를 반환한다.

  5. persisted를 false로 둔다.

  6. options["persisted"]가 true이면 다음을 수행한다:

    1. permission"persistent-storage" 사용 권한을 요청한 결과로 둔다.

    2. permission이 "granted"이면, persisted를 true로 설정한다.

  7. bucketshelfname으로 버킷 가져오기 또는 만료시키기를 실행한 결과로 둔다.

  8. bucket이 null이면 다음을 수행한다:

    1. bucket을 이름이 name인 새 스토리지 버킷으로 설정한다.

    2. bucket할당량 값quota로 설정한다.

    3. shelf버킷 맵[name]을 bucket으로 설정한다.

  9. persisted가 true이면, bucket버킷 모드"persistent"로 설정한다.

  10. bucket만료Unix epoch 이후 expires 밀리초로 설정한다.

  11. storageBucket을 새 StorageBucket으로 둔다.

  12. storageBucket스토리지 버킷bucket으로 설정한다.

  13. storageBucket을 반환한다.

문자열 name이 주어졌을 때 버킷 이름 검증을 하려면, 다음 단계를 실행한다:

  1. nameASCII 소문자 알파벳, ASCII 숫자, U+005F (_), 또는 U+002D(-)가 아닌 코드 포인트가 포함되어 있으면 failure를 반환한다.

  2. name코드 포인트 길이가 0이거나 64를 초과하면 failure를 반환한다.

  3. name이 U+005F (_) 또는 U+002D(-)로 시작하면 failure를 반환한다.

  4. 반환한다.

shelf에 대해 문자열 name이 주어졌을 때 버킷 가져오기 또는 만료시키기를 하려면, 다음 단계를 실행한다:

  1. shelf버킷 맵[name]이 존재하면 이를 bucket으로 둔다. 그렇지 않으면 null을 반환한다.

  2. bucket만료 시간이 null이 아니고 관련 설정 객체현재 벽시계 시간보다 전이면 다음을 수행한다:

    1. bucketremoved를 true로 설정한다.

    2. null을 반환한다.

  3. bucket을 반환한다.

1.2. 버킷 삭제

delete(name) 메서드 단계는 다음과 같다:

  1. environmentthis관련 설정 객체로 둔다.

  2. shelfenvironment가 주어졌을 때 로컬 스토리지 선반 획득을 실행한 결과로 둔다.

  3. shelf가 failure이면, TypeError거부된 promise를 반환한다.

  4. p새 promise로 둔다.

  5. name으로 버킷 이름 검증을 수행한 결과가 failure이면, InvalidCharacterErrorpreject한다.

  6. 그렇지 않으면, 다음 단계를 storage bucket manager큐에 넣는다:

    1. shelfname으로 버킷 제거를 실행한다.

    2. presolve하기 위해 스토리지 작업을 큐에 넣는다.

  7. p를 반환한다.

shelf에 대해 버킷 name이 주어졌을 때 버킷 제거를 하려면, 다음 단계를 실행한다:

  1. shelf버킷 맵[name]이 존재하면 이를 bucket으로 둔다. 그렇지 않으면 반환한다.

  2. shelf버킷 맵에서 name을 제거한다.

  3. bucketremoved를 true로 설정한다.

  4. 반환한다.

[IndexedDB-3]는 데이터가 할당량에 의해 축출될 때 삭제가 어떻게 일어나는지를 정의해야 한다.

[FS]는 데이터가 할당량에 의해 축출될 때 Bucket File System에 대한 삭제가 어떻게 일어나는지를 정의해야 한다.

[Service-Workers]는 데이터가 할당량에 의해 축출될 때 CacheStorage와 Service Workers에 대한 삭제가 어떻게 일어나는지를 정의해야 한다.

1.3. 버킷 열거

keys() 메서드 단계는 다음과 같다:

  1. shelf로컬 스토리지 선반 획득을 실행한 결과로 둔다.

  2. shelf가 failure이면, TypeError거부된 promise를 반환한다.

  3. p새 promise로 둔다.

  4. keys를 새 리스트로 둔다.

  5. 다음 단계를 storage bucket manager큐에 넣는다:

    1. shelf버킷 맵에 있는 각 key에 대해, 다음 단계를 실행한다:

      1. bucketshelfkey버킷 가져오기 또는 만료시키기를 실행한 결과로 둔다.

      2. bucket이 null이 아니면, keykeys추가한다.

    2. keyspresolve하기 위해 스토리지 작업을 큐에 넣는다.

  6. p를 반환한다.

2. StorageBucket 인터페이스

[Exposed=(Window,Worker),
 SecureContext]
interface StorageBucket {
  readonly attribute DOMString name;

  [Exposed=Window] Promise<boolean> persist();
  Promise<boolean> persisted();

  Promise<StorageEstimate> estimate();

  Promise<undefined> setExpires(DOMHighResTimeStamp expires);
  Promise<DOMHighResTimeStamp?> expires();

  [SameObject] readonly attribute IDBFactory indexedDB;

  [SameObject] readonly attribute CacheStorage caches;

  Promise<FileSystemDirectoryHandle> getDirectory();
};

StorageBucket는 연관된 스토리지 버킷을 가진다.

스토리지 버킷은 연관된 removed 플래그를 가지며, 이는 boolean이고 초기값은 false이다. 스토리지 버킷이 삭제될 때 true로 설정된다.

StorageBucketDOMString 객체 name을 가지며, 이는 해당 스토리지 버킷에 매핑되는 버킷 맵의 키이다.

2.1. 지속성

이미 버킷 모드를 정의하는 Storage § 4.5 스토리지 버킷과 병합한다.

persist() 메서드 단계는 다음과 같다:

  1. bucketthis스토리지 버킷으로 둔다.

  2. environmentthis관련 설정 객체로 둔다.

  3. p새 promise로 둔다.

  4. 다음 단계를 병렬로 실행한다:

    1. bucketremoved 플래그가 true이면, InvalidStateErrorpreject하기 위해 스토리지 작업을 큐에 넣는다.

    2. bucket버킷 모드"persistent"이면 persisted를 true로 둔다.

    3. 그렇지 않으면,

      1. permission"persistent-storage"environment현재 권한 상태 가져오기를 수행한 결과로 둔다.

      2. permission이 "granted"이면, bucket버킷 모드"persistent"로 설정하고 persisted를 true로 설정한다.

      3. 그렇지 않으면, persisted를 false로 설정한다.

    4. persistedpresolve하기 위해 스토리지 작업을 큐에 넣는다.

  5. p를 반환한다.

persisted() 메서드 단계는 다음과 같다:

  1. p새 promise로 둔다.

  2. bucketthis스토리지 버킷으로 둔다.

  3. 그렇지 않으면, 다음 단계를 병렬로 실행한다:

    1. bucketremoved 플래그가 true이면, InvalidStateErrorpreject하기 위해 스토리지 작업을 큐에 넣는다.

    2. bucket버킷 모드"persistent"이면 persistent를 true로, 그렇지 않으면 false로 둔다.

    3. persistentpresolve하기 위해 스토리지 작업을 큐에 넣는다.

  4. p를 반환한다.

2.2. 할당량

스토리지 버킷할당량 값을 가지며, 이는 number-or-null이고 초기값은 null이다. 버킷이 사용할 수 있는 사용량의 상한을 바이트 단위로 지정한다. 사용자 에이전트는 실현되는 스토리지 공간을 추가로 제한할 수 있다.

스토리지 버킷스토리지 사용량은 모든 스토리지 병이 사용하는 바이트 수에 대한 구현 정의의 대략적인 추정치이다.

estimate() 메서드 단계는 다음과 같다:

  1. environmentthis관련 설정 객체로 둔다.

  2. shelfenvironment로컬 스토리지 선반 획득을 실행한 결과로 둔다.

  3. shelf가 failure이면, TypeError거부된 promise를 반환한다.

  4. bucketthis스토리지 버킷으로 둔다.

  5. bucketremoved 플래그가 true이면, InvalidStateError거부된 promise를 반환한다.

  6. p새 promise로 둔다.

  7. 그렇지 않으면, 다음 단계를 병렬로 실행한다:

    1. quotashelf에 대한 스토리지 할당량으로 둔다.

    2. bucket할당량 값이 null이 아니면, quota를 그 값으로 설정한다.

    3. usagebucket에 대한 스토리지 사용량으로 둔다.

    4. dictionaryStorageEstimate dictionary로 새로 만들며, 그 usage 멤버는 usage이고 quota 멤버는 quota이다.

    5. dictionarypresolve하기 위해 스토리지 작업을 큐에 넣는다.

  8. p를 반환한다.

2.3. 만료

스토리지 버킷만료 시간을 가지며, 이는 null이거나 벽시계상의 순간이고 초기값은 null이다. 버킷 수명의 상한을 지정한다.

버킷 가져오기 또는 만료시키기 알고리즘은 keys() 또는 open()이 호출될 때 만료된 버킷을 제거한다. 사용자 에이전트는 스토리지 압박에 직면하면, 버킷 모드"best-effort"인 버킷을 그 만료 시간 전에 제거할 수 있다. 사용자 에이전트는 만료에 도달했을 때 버킷 모드와 관계없이 open() 또는 keys()가 호출되기 전에 어떤 버킷이든 제거할 수 있다

setExpires(expires) 메서드 단계는 다음과 같다:

  1. p새 promise로 둔다.

  2. bucketthis스토리지 버킷으로 둔다.

  3. 그렇지 않으면, 다음 단계를 병렬로 실행한다:

    1. bucketremoved 플래그가 true이면, InvalidStateErrorpreject하기 위해 스토리지 작업을 큐에 넣는다.

    2. 그렇지 않으면, bucket만료 시간Unix epoch 이후 expires 밀리초로 설정한다.

    3. presolve하기 위해 스토리지 작업을 큐에 넣는다.

  4. p를 반환한다.

expires() 메서드 단계는 다음과 같다:

  1. p새 promise로 둔다.

  2. bucketthis스토리지 버킷으로 둔다.

  3. 그렇지 않으면, 다음 단계를 병렬로 실행한다:

    1. bucketremoved 플래그가 true이면, InvalidStateErrorpreject하기 위해 스토리지 작업을 큐에 넣는다.

    2. 그렇지 않으면, expirationbucket만료 시간으로 둔다.

    3. expiration으로 presolve하기 위해 스토리지 작업을 큐에 넣는다.

  4. p를 반환한다.

2.4. 스토리지 엔드포인트 사용

스토리지 엔드포인트, 즉 스토리지 병은 아래에 설명된 대로 접근할 수 있다.

2.4.1. Indexed Database 사용

IDBFactory 메서드는 storageKey가 아니라 storage bottle map을 받도록 해야 한다.

StorageBucketIDBFactory 객체를 가지며, 초기값은 null이다. indexedDB getter 단계는 다음과 같다:

  1. thisindexedDB가 null이면, 다음 단계를 실행한다:

    1. bucketthis스토리지 버킷으로 둔다.

    2. bottle mapbucket"indexedDB"로컬 스토리지 병 맵 획득을 수행한 결과로 둔다.

    3. indexedDBIDBFactory 객체로 둔다.

    4. indexedDB에 대한 스토리지 병 맵bottle map으로 설정한다.

    5. thisindexedDBindexedDB로 설정한다.

  2. thisindexedDB를 반환한다.

2.4.2. CacheStorage 사용

StorageBucketCacheStorage 객체를 가지며, 초기값은 null이다. caches getter 단계는 다음과 같다:

  1. thiscaches가 null이면, 다음 단계를 실행한다:

    1. bucketthis스토리지 버킷으로 둔다.

    2. bottle mapbucket"cacheStorage"로컬 스토리지 병 맵 획득을 수행한 결과로 둔다.

    3. cacheStorageCacheStorage 객체로 둔다.

    4. cacheStorage에 대한 관련 이름-캐시 맵bottle map으로 설정한다.

    5. thiscachescacheStorage로 설정한다.

  2. thiscaches를 반환한다.

2.4.3. 버킷 파일 시스템 사용

[Storage]는 주어진 (기본이 아닌) 버킷에 대한 bottle map을 검색하는 도우미를 정의해야 한다.

[FS]는 bottle map이 주어졌을 때 OPFS를 검색하는 도우미를 정의해야 한다.

getDirectory() 단계는 다음과 같다:

  1. mapthis스토리지 버킷"fileSystem"으로 로컬 스토리지 병 맵 획득을 수행한 결과로 둔다.

  2. map으로 getDirectory를 수행한 결과를 반환한다.

2.5. Clear Site Data 통합

Clear Site Data § 3.1 Clear-Site-Data HTTP 응답 헤더 필드를 갱신한다.

"storage:bucket-name"

타입 문자열이 "storage:"로 시작하면, : 뒤의 나머지 문자는 특정 응답 URL의 출처에 있는 특정 스토리지 버킷을 참조하는 것으로 취급된다.

아래 단계를 Clear Site Data § 4.1 구문 분석의 알고리즘에 추가한다.

버킷이 있는 Clear-Site-Data 헤더 구문 분석을 하려면, 다음 단계를 실행한다:

  1. header의 각 type에 대해, 다음 단계를 실행한다:

    1. type"storage:"시작하지 않으면, 이 단계를 중단한다.

    2. bucket nametype의 8부터 끝까지의 코드 단위 부분 문자열로 둔다.

    3. bucket name으로 버킷 이름 검증을 수행한 결과가 failure이면, 이 단계를 중단한다.

    4. ("storage-bucket", bucket name)으로 구성된 튜플types에 추가한다

아래 단계를 Clear Site Data § 4.2 응답에 대한 데이터 지우기의 알고리즘에 추가한다.

bucket name이 주어졌을 때 버킷이 있는 데이터 지우기를 하려면, 다음 단계를 실행한다:

  1. environmentthis관련 설정 객체로 둔다.

  2. shelfenvironment가 주어졌을 때 로컬 스토리지 선반 획득을 실행한 결과로 둔다.

  3. shelf가 failure이면, TypeErrorthrow하고 이 단계를 중단한다.

  4. types의 각 type에 대해, 다음 단계를 실행한다:

    1. type튜플이 아니거나 type[0]이 "storage-bucket"이 아니면, 이 단계를 중단한다.

    2. shelf버킷 맵[bucket name]이 존재하면 이를 bucket으로 둔다. 그렇지 않으면 이 단계를 중단한다

    3. bucket을 제거한다.

3. 보안 및 개인정보 고려사항

적합성

문서 규약

적합성 요구사항은 설명적 주장과 RFC 2119 용어의 조합으로 표현된다. 이 문서의 규범적 부분에서 쓰이는 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 그리고 “OPTIONAL”은 RFC 2119에 설명된 대로 해석해야 한다. 다만, 가독성을 위해 이 명세에서는 이러한 단어가 모두 대문자로 나타나지는 않는다.

이 명세의 모든 텍스트는 명시적으로 비규범으로 표시된 절, 예제, 주석을 제외하고 규범적이다. [RFC2119]

이 명세의 예제는 “예를 들어”라는 말로 도입되거나 class="example"을 사용하여 규범적 텍스트와 구분된다. 다음과 같다:

이것은 정보 제공 예제의 예이다.

정보 제공 주석은 “Note”라는 단어로 시작하고 class="note"를 사용하여 규범적 텍스트와 구분된다. 다음과 같다:

Note, 이것은 정보 제공 주석이다.

색인

이 명세가 정의하는 용어

참조로 정의되는 용어

참고문헌

규범적 참고문헌

[CLEAR-SITE-DATA]
Mike West. Clear Site Data. URL: https://w3c.github.io/webappsec-clear-site-data/
[FS]
Austin Sullivan. File System Standard. 현행 표준. URL: https://fs.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML Standard. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[IndexedDB-3]
Joshua Bell. Indexed Database API 3.0. URL: https://w3c.github.io/IndexedDB/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 현행 표준. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. URL: https://w3c.github.io/permissions/
[RFC2119]
S. Bradner. RFC에서 요구사항 수준을 나타내기 위해 사용하는 핵심 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[Service-Workers]
Jake Archibald; Marijn Kruisselbrink. Service Workers. URL: https://w3c.github.io/ServiceWorker/
[Storage]
Anne van Kesteren. Storage Standard. 현행 표준. URL: https://storage.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 현행 표준. URL: https://webidl.spec.whatwg.org/

IDL 색인

[SecureContext]
interface mixin NavigatorStorageBuckets {
  [SameObject] readonly attribute StorageBucketManager storageBuckets;
};
Navigator includes NavigatorStorageBuckets;
WorkerNavigator includes NavigatorStorageBuckets;

[Exposed=(Window,Worker),
 SecureContext]
interface StorageBucketManager {
    Promise<StorageBucket> open(DOMString name, optional StorageBucketOptions options = {});
    Promise<sequence<DOMString>> keys();
    Promise<undefined> delete(DOMString name);
};

dictionary StorageBucketOptions {
  boolean persisted = false;
  unsigned long long quota;
  DOMHighResTimeStamp expires;
};

[Exposed=(Window,Worker),
 SecureContext]
interface StorageBucket {
  readonly attribute DOMString name;

  [Exposed=Window] Promise<boolean> persist();
  Promise<boolean> persisted();

  Promise<StorageEstimate> estimate();

  Promise<undefined> setExpires(DOMHighResTimeStamp expires);
  Promise<DOMHighResTimeStamp?> expires();

  [SameObject] readonly attribute IDBFactory indexedDB;

  [SameObject] readonly attribute CacheStorage caches;

  Promise<FileSystemDirectoryHandle> getDirectory();
};

이슈 색인

[IndexedDB-3]는 데이터가 할당량에 의해 축출될 때 삭제가 어떻게 일어나는지를 정의해야 한다.
[FS]는 데이터가 할당량에 의해 축출될 때 Bucket File System에 대한 삭제가 어떻게 일어나는지를 정의해야 한다.
[Service-Workers]는 데이터가 할당량에 의해 축출될 때 CacheStorage와 Service Workers에 대한 삭제가 어떻게 일어나는지를 정의해야 한다.
이미 버킷 모드를 정의하는 Storage § 4.5 스토리지 버킷과 병합한다.
IDBFactory 메서드는 storageKey가 아니라 storage bottle map을 받도록 해야 한다.
[Storage]는 주어진 (기본이 아닌) 버킷에 대한 bottle map을 검색하는 도우미를 정의해야 한다.
[FS]는 bottle map이 주어졌을 때 OPFS를 검색하는 도우미를 정의해야 한다.
Clear Site Data § 3.1 Clear-Site-Data HTTP 응답 헤더 필드를 갱신한다.
아래 단계를 Clear Site Data § 4.1 구문 분석의 알고리즘에 추가한다.
아래 단계를 Clear Site Data § 4.2 응답에 대한 데이터 지우기의 알고리즘에 추가한다.