1. 序論
~webは、何年かにわたり~storage用に利用できる様々な~APIを成長させてきた — 例えば IndexedDB, `localStorage^c, `showNotification()^c 。 ~Storage標準は、次を定義することにより,これらの~APIを統合する: ◎ Over the years the web has grown various APIs that can be used for storage, e.g., IndexedDB, localStorage, and showNotification(). The Storage Standard consolidates these APIs by defining:
- これらの~APIが~dataを格納するための~primitiveとなる,~bucket。 ◎ A bucket, the primitive these APIs store their data in
- その~bucketを持続的にする仕方。 ◎ A way of making that bucket persistent
- 与えられた`生成元$に対する使用量と~quota見積もりを取得する仕方。 ◎ A way of getting usage and quota estimates for an origin
伝統的に,これらの~APIにより格納された~dataは、機器~storageの空きを利用者が使果たすに伴い,利用者が介入できることなく喪失されていた。 が、持続的~bucketは,利用者の同意なくしては~clearできない。 したがってこれは、利用者が~webに~nativeな~platformで享受した~dataの保証をもたらす。 ◎ Traditionally, as the user runs out of storage space on their device, the data stored with these APIs gets lost without the user being able to intervene. However, persistent buckets cannot be cleared without consent by the user. This thus brings data guarantees users have enjoyed on native platforms to the web.
~storageを持続的にする単純な仕方は、 `persist()$m ~methodを呼出すことである。 それは同時に,末端利用者に許可を要請して、是認されれば,~storageを持続的になるよう変更する: ◎ A simple way to make storage persistent is through invoking the persist() method. It simultaneously requests the end user for permission and changes the storage to be persistent once granted:
navigator.storage.persist().then(%persisted => { if(%persisted) { /* … */ } })
~UAにより駆動される~dialogを 末端利用者に不必要に示さない,もう少し込み入った~codeも書ける: ◎ To not show user-agent-driven dialogs to the end user unannounced slightly more involved code can be written:
Promise.all([ navigator.storage.persisted(), navigator.permissions.query({name: "persistent-storage"}) ]).then(([%persisted, %permission]) => { if(!%persisted && %permission.status == "granted") { navigator.storage.persist().then( /* … */ ) } else if(!%persistent && %permission.status == "prompt") { showPersistentStorageExplanation() } })
`estimate()$m ~methodを利用すれば,~appが格納する内容に十分な空きがあるかどうかも決定できる: ◎ The estimate() method can be used to determine whether there is enough space left to store content for an application:
function retrieveNextChunk(%nextChunkInfo) { return navigator.storage.estimate().then(%info => { if(%info.quota - %info.usage > %nextChunkInfo.size) return fetch(%nextChunkInfo.url) else throw new Error("次の~chunkを格納するための空きが足りません") }).then( /* … */ ) }
【この訳に固有の表記規約】
この訳の,~algoや定義の記述に利用されている各種記号( ~LET, ~IF, ~THROW, 等々)の意味や定義の詳細は、~SYMBOL_DEF_REFを~~参照されたし。
2. 各種用語
この仕様は、 Infra 標準 `INFRA$r に依存する。 ◎ This specification depends on the Infra Standard. [INFRA]
この仕様は、次に挙げる各種~標準による各種用語を利用する: DOM, HTML, IDL, Permissions API, URL `DOM$r `HTML$r `WEBIDL$r `PERMISSIONS$r `URL$r ◎ This specification uses terminology from the DOM, HTML, IDL, Permissions API, and URL Standards. [DOM] [HTML] [WEBIDL] [PERMISSIONS] [URL]
`~schemeなし生成元~群@ は、次のいずれかとして与えられる: ◎ A schemeless origin group is a group of one of the following:
- 互いに一致する`不透明な生成元$たち。 ◎ Identical opaque origins.
- それぞれの`~host$が[ `~domain$urlでない, かつ 互いに一致する ]ような`成分組~生成元$たち。 ◎ Tuple origins whose host is identical and not a domain.
- それぞれの`~host$が[ `~domain$urlである, かつ `登録-可能~domain$である, かつ 互いに一致する ]ような`成分組~生成元$たち。 ◎ Tuple origins whose host is a domain of which the registrable domain is identical.
注記: この定義は、最終的にはより相応しい箇所に移動されることになる。 ◎ This definition will move to a more suitable location eventually.
3. 基盤
~UAは、次に挙げるような何種類かの~storageを備える: ◎ A user agent has various kinds of storage:
- 資格証~storage
- 末端利用者の資格証からなる — ~HTML~formを通して提出された~usernameや~passwordなど。 ◎ End-user credentials, such as username and passwords submitted through HTML forms
- 許可~storage
- 様々な特色機能 — 地理情報など — に対する許可からなる。 ◎ Permissions for various features, such as geolocation
- ~network~storage
- 次に挙げるもの, 等々からなる: ~HTTP~cache, ~cookie, 認証~entry, ~TLS~client証明書 ◎ HTTP cache, cookies, authentication entries, TLS client certificates
- ~site~storage
- 次に挙げるもの, 等々からなる: Indexed DB, Cache API, ~service-worker登録, `localStorage^m, `history.pushState()^m, ~app~cache, 通知 ◎ Indexed DB, Cache API, service worker registrations, localStorage, history.pushState(), application caches, notifications, etc.
この仕様が主に関わるのは、 `~site~storage@ である。 ◎ This specification primarily concerns itself with site storage.
各`~site~storage$は、 0 個以上の `~site~storage単位@ からなる。 ◎ Site storage consists of zero or more site storage units.
各 `生成元$には、ある`~site~storage単位$が結付けられる。 各`~site~storage単位$は、 1 個の `~bucket@ ( bucket, “バケツ” )を包含する。 `HTML$r ◎ Each origin has an associated site storage unit. A site storage unit contains a single bucket. [HTML]
3.1. ~bucket
各 `~bucket$には `~mode@ があり、[ `best-effort^l, `persistent^l ]のいずれかにされる。 [ `~mode$ ~EQ `persistent^l ]なる`~bucket$を `持続的@ という。 そうでない`~bucket$を `持続的でない@ という†。 ◎ A bucket has mode which is either "best-effort" or "persistent". A persistent bucket is a bucket whose mode is "persistent". A non-persistent bucket is a bucket whose mode is not "persistent".
【† この訳では、この用語は利用せず,単に “`持続的$でない” と記す。 】
~bucketは、不可分な単位と見なされる。 ~UAは、`~bucket$を~clearするときには,まるごと~clearし~MUST。 ◎ A bucket is considered to be an atomic unit. Whenever a bucket is cleared by the user agent, it must be cleared in its entirety.
4. 持続性~許可
`~bucket$が`持続的$に転化されるのは、利用者(または,利用者に利する~UA)が `persistent-storage$l 特色機能を利用する許可を是認したときに限られる。 ◎ A bucket can only be turned into a persistent bucket if the user (or user agent on behalf of the user) has granted permission to use the "persistent-storage" feature.
注記: `生成元$に是認されたなら、持続性~許可は,[ ~UAによる ~storageを~clearするための施策 ]から保護するために利用できる。 ~UAは、`生成元$や利用者の介在~抜きには,持続的にされた~storageを~clearできない。 これは特に、利用者が~offlineの間に可用にする必要がある資源や, 利用者が局所的に作成した資源に対し,有用になる。 ◎ When granted to an origin, the persistence permission can be used to protect storage from the user agent’s clearing policies. The user agent cannot clear storage marked as persistent without involvement from the origin or user. This makes it particularly useful for resources the user needs to have available while offline or resources the user creates locally.
この仕様は、`強力な特色機能$( powerful feature )として, `persistent-storage@l を定義する。 その許可に関係する各種[ ~flag, ~algo, 型 ]は、次を除いて既定のものになる: ◎ The "persistent-storage" powerful feature’s permission-related flags, algorithms, and types are defaulted, except for:
- `許可~状態$( permission state )
- `persistent-storage$l の`許可~状態$の値は、同じ`生成元$を伴う すべての`環境~設定群~obj$にわたり,同じにされ~MUST。 ◎ "persistent-storage"'s permission state must have the same value for all environment settings objects with a given origin.
- `許可~破棄~algo$( permission revocation algorithm )
-
次を走らす:
- ~IF[ `persistent-storage$l の`許可~状態$ ~NEQ `granted$l ] ⇒ 現在の`生成元$の`~site~storage単位$の`~bucket$の`~mode$ ~SET `best-effort^l
5. 使用量と~quota
`生成元$ %生成元 の `~site~storage使用量@ は、およその見積もりによる, %生成元 の`~site~storage単位$内で利用されている~byte数である。 ◎ The site storage usage of an origin origin is a rough estimate of the amount of bytes used in origin’s site storage unit.
注記: これは正確な量にはなり得ない。 ~UAは、`生成元$が正確に何~byte利用しているか はっきりしなくなるような,重複集約, 圧縮, その他の技法を駆使してるかもしれず、また そうすることが~UAには奨励されるので。 ◎ This cannot be an exact amount as user agents might, and are encouraged to, use deduplication, compression, and other techniques that obscure exactly how much bytes an origin uses.
`生成元$ %生成元 の `~site~storage~quota@ は、保守的な見積もりによる, %生成元 の`~site~storage単位$に可用な~byte数である。 この量は、利用者に ある程度の余裕を与えるため,機器~storageの可用な空きの総計より少なくなるべきである。 ◎ The site storage quota of an origin origin is a conservative estimate of the amount of bytes available to origin’s site storage unit. This amount should be less than the total available storage space on the device to give users some wiggle room.
注記: ~UAには、 “頻用される” `生成元$には より大きい`~site~storage~quota$を供することが強く奨励される。 “頻用度” の指標としては、 ~naviの頻度, 訪問の近過去度, ~bookmarkされたかどうか, `persistent-storage$l に対する`許可$ などの要因を利用できる。 ◎ User agents are strongly encouraged to provide "popular" origins with a larger site storage quota. Factors such as navigation frequency, recency of visits, bookmarking, and permission for "persistent-storage" can be used as indications of "popularity".
6. ~UI指針
~UAは、自身の~UIにおいて~network~storageと`~site~storage$を判別させるべきでない。 代わりに、所与の`~schemeなし生成元~群$に属する すべての~storageを除去する能を,利用者に提供するべきである。 これは、[ ~network~storageを利用しても,`~site~storage$は復活できなくする ]ことを,ある程度まで確保する。 これはまた、`~schemeなし生成元~群$が~dataを格納できる種々の仕方について,利用者が知る必要がある量を抑える。 ◎ User agents should not distinguish between network storage and site storage in their user interface. Instead user agents should offer users the ability to remove all storage for a given schemeless origin group. This ensures to some extent that network storage cannot be used to revive site storage. This also reduces the amount users need to know about the different ways in which a schemeless origin group can store data.
資格証~storageは、他から分離されるべきである — それは、自動生成された~passwordなど,利用者が復活できないような~dataを包含するかもしれないので。 許可~storageも,ほとんどは単純な真偽値たちからなるので、利用者の不便を避けるため分離できる。 資格証や許可は、~network~storageや`~site~storage$よりも,利用者にとって解したり見分けるのはいくぶん容易でもある。 ◎ Credentials storage should be separated as it might contain data the user might not be able to revive, such as an autogenerated password. Since permissions storage is mostly simple booleans it too can be separated to avoid inconveniencing the user. Credentials and permissions are also somewhat easier to understand and differentiate for users from network storage and site storage.
6.1. ~storageの逼迫
~UAは、~storageが逼迫してきて,[ `~site~storage$の中の [ ~network~storageや`持続的$でない~bucket ]を~clearすることでは,十分な空きを~~確保できない ]ことに気づいたときは、利用者に~alertして,`持続的~bucket$を~clearする仕方を提供するべきである。 ◎ When the user agent notices it comes under storage pressure and it cannot free up sufficient space by clearing network storage and non-persistent buckets within site storage, then the user agent should alert the user and offer a way to clear persistent buckets.
7. ~API
[`SecureContext$] interface mixin `NavigatorStorage@I { readonly attribute `StorageManager$I `storage$m; }; `Navigator$I includes `NavigatorStorage$I; `WorkerNavigator$I includes `NavigatorStorage$I;
各`環境~設定群~obj$ `HTML$r には、 `StorageManager$I ~objが結付けられる。 ◎ Each environment settings object has an associated StorageManager object. [HTML]
- `storage@m
- 取得子は、此れに`関連する設定群~obj$の `StorageManager$I ~objを返さ~MUST。 ◎ The storage attribute’s getter must return context object’s relevant settings object’s StorageManager object.
[`SecureContext$, `Exposed$=(Window,Worker)] interface `StorageManager@I { Promise<boolean> `persisted$m(); [`Exposed$=Window] Promise<boolean> `persist$m(); Promise<`StorageEstimate$I> `estimate$m(); }; dictionary `StorageEstimate@I { unsigned long long `usage@m; unsigned long long `quota@m; };
- `persisted()@m
-
被呼出時には、次を走らせ~MUST: ◎ The persisted() method, when invoked, must run these steps:
- %~promise ~LET 新たな~promise ◎ Let promise be a new promise.
- %生成元 ~LET 此れに`関連する設定群~obj$の`生成元$enV ◎ Let origin be context object’s relevant settings object’s origin.
- ~IF[ %生成元 は`不透明な生成元$である ] ⇒ `TypeError$E で %~promise を却下する ◎ If origin is an opaque origin, then reject promise with a TypeError.
-
~ELSE ⇒ 次の手続きを`並列的$に走らす: ◎ Otherwise, run these steps in parallel:
-
%持続ed ~LET [ %生成元 の`~site~storage単位$の`~bucket$は`持続的$ならば ~T / ~ELSE_ ~F ] ◎ Let persisted be true if origin’s site storage unit’s bucket is a persistent bucket, and false otherwise.
注記: 内部~errorが生じたときは ~F になる。 ◎ It will be false when there’s an internal error.
- 次を走らす`~taskを~queueする$ ⇒ %持続ed で %~promise を解決する ◎ Queue a task to resolve promise with persisted.
-
- ~RET %~promise ◎ Return promise.
- `persist()@m
-
被呼出時には、次を走らせ~MUST: ◎ The persist() method, when invoked, must run these steps:
- %~promise ~LET 新たな~promise ◎ Let promise be a new promise.
- %生成元 ~LET 此れに`関連する設定群~obj$の`生成元$enV ◎ Let origin be context object’s relevant settings object’s origin.
- ~IF[ %生成元 は`不透明な生成元$である ] ⇒ `TypeError$E で %~promise を却下する ◎ If origin is an opaque origin, then reject promise with a TypeError.
-
~ELSE ⇒ 次の手続きを`並列的$に走らす: ◎ Otherwise, run these steps in parallel:
- %生成元 ~LET %設定群~obj の`生成元$enV ◎ Let origin be settingsObject’s origin.
-
%許可 ~LET `persistent-storage$l を`利用する許可を要請-$した結果 ◎ Let permission be the result of requesting permission to use "persistent-storage".
注記: ~UAには、同じ`生成元$に対し,同時期に利用者にこの問いに重ねて回答させないことが奨励される。 この 【許可を要請する】 ~algoは、そのような局面を取扱うためのものではない。 ◎ User agents are encouraged to not let the user answer this question twice for the same origin around the same time and this algorithm is not equipped to handle such a scenario.
-
%持続ed ~LET [ %生成元 の`~site~storage単位$の`~bucket$は`持続的$ならば ~T / ~ELSE_ ~F ] ◎ Let persisted be true, if origin’s site storage unit’s bucket is a persistent bucket, and false otherwise.
注記: 内部~errorが生じたときは ~F になる。 ◎ It will be false when there’s an internal error.
-
~IF[ %持続ed ~EQ ~F ]~AND[ %許可 ~EQ `granted$l ]: ◎ If persisted is false and permission is "granted", then:
- %生成元 の`~site~storage単位$の`~bucket$の`~mode$ ~SET `persistent^l ◎ Set origin’s site storage unit’s bucket’s mode to "persistent".
- ~IF[ 内部~errorは生じていない ] ⇒ %持続ed ~SET ~T ◎ If there was no internal error, then set persisted to true.
- 次を走らす`~taskを~queueする$ ⇒ %持続ed で %~promise を解決する ◎ Queue a task to resolve promise with persisted.
- ~RET %~promise ◎ Return promise.
- `estimate()@m
-
被呼出時には、次を走らせ~MUST: ◎ The estimate() method, when invoked, must run these steps:
- %~promise ~LET 新たな~promise ◎ Let promise be a new promise.
- %生成元 ~LET 此れに`関連する設定群~obj$の`生成元$enV ◎ Let origin be context object’s relevant settings object’s origin.
- ~IF[ %生成元 は`不透明な生成元$である ] ⇒ `TypeError$E で %~promise を却下する ◎ If origin is an opaque origin, then reject promise with a TypeError.
-
~ELSE ⇒ 次の手続きを`並列的$に走らす: ◎ Otherwise, run these steps in parallel:
- %使用量 ~LET %生成元 の`~site~storage使用量$ ◎ Let usage be site storage usage for origin.
- %~quota ~LET %生成元 の`~site~storage~quota$ ◎ Let quota be site storage quota for origin.
- %辞書 ~LET 次のようにされた新たな `StorageEstimate$I 辞書 ⇒# `usage$m ~member ~SET %使用量, `quota$m ~member ~SET %~quota ◎ Let dictionary be a new StorageEstimate dictionary whose usage member is usage and quota member is quota.
-
~IF[[ %使用量, %~quota を得る間に何らかの内部~errorが生じた ] ⇒ 次を走らす`~taskを~queueする$ ⇒ `TypeError$E で %~promise を却下する ◎ If there was an internal error while obtaining usage and quota, then queue a task to reject promise with a TypeError.
注記: 内部~errorはごく稀にしか生じないと想定されており,何らかの類の低levelな[ ~platform/~hardware ]における瑕疵を指示する。 しかしながら,~webにおける[ 実装/~platform ]の多様さの尺度からは、生じるものとみなす必要がある。 ◎ Internal errors are supposed to be extremely rare and indicate some kind of low-level platform or hardware fault. However, at the scale of the web with the diversity of implementation and platforms, the unexpected does occur.
- ~ELSE ⇒ 次を走らす`~taskを~queueする$ ⇒ %辞書 で %~promise を解決する ◎ Otherwise, queue a task to resolve promise with dictionary.
- ~RET %~promise ◎ Return promise.