Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move title to alternatives considered #28

Merged
merged 3 commits into from
Dec 17, 2020
Merged
Changes from 2 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
128 changes: 58 additions & 70 deletions explainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
- [Quota Management](#quota-management)
- [Detailed design discussion](#detailed-design-discussion)
- [Bucket names](#bucket-names)
- [Bucket titles](#bucket-titles)
- [Storage policy naming](#storage-policy-naming)
- [Durability guarantees](#durability-guarantees)
- [Considered alternatives](#considered-alternatives)
Expand All @@ -52,6 +51,7 @@
- [Allow all safe characters for HTTP headers in bucket names](#allow-all-safe-characters-for-http-headers-in-bucket-names)
- [No length restriction for bucket names](#no-length-restriction-for-bucket-names)
- [Relaxed length restrictions for bucket names](#relaxed-length-restrictions-for-bucket-names)
- [Bucket titles](#bucket-titles)
- [Alternative name for the bucket `title` property](#alternative-name-for-the-bucket-title-property)
- [Language maps for bucket titles](#language-maps-for-bucket-titles)
- [Enumerate all buckets using an async iterator](#enumerate-all-buckets-using-an-async-iterator)
Expand Down Expand Up @@ -154,9 +154,7 @@ before using storage APIs. In the simplest form, usage looks as follows.

```javascript
// Create a bucket for emails that are synchronized with the server.
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox", {
title: "Inbox", // User agents may display titles in storage management UI.
});
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox");
```

Buckets can be assigned different storage policies at creation time. The example
Expand All @@ -166,7 +164,7 @@ described in future sections.

```javascript
const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "strict", persisted: true, title: "Drafts" });
durability: "strict", persisted: true });
```


Expand All @@ -180,7 +178,7 @@ does not match the desired value.

```javascript
const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "strict", persisted: true, title: "Drafts" });
durability: "strict", persisted: true });

if (await draftsBucket.persisted() !== true) {
showWarningButterBar("Your drafts may be lost if you run out of disk space!");
Expand Down Expand Up @@ -331,7 +329,7 @@ A bucket's persistence policy is specified at bucket creation time.

```javascript
const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
persisted: true, title: "Drafts" });
persisted: true });
```

The persistence policy can be queried at any time. The user agent may decline a
Expand Down Expand Up @@ -389,7 +387,7 @@ A bucket's durability policy is specified at bucket creation time.

```javascript
const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "strict", title: "Drafts" });
durability: "strict" });
```

The durability policy can be queried at any time. The user agent may not
Expand All @@ -415,7 +413,6 @@ not to follow it.

```javascript
const logsBucket = await navigator.storageBuckets.openOrCreate("logs", {
title: "Log data",
quota: 20 * 1024 * 1024 // 20 MB
}
```
Expand Down Expand Up @@ -491,7 +488,7 @@ The default bucket is created with the following options.

```js
await navigator.storageBuckets.openOrCreate("default", {
durability: "strict", persist: false, title: "" });
durability: "strict", persist: false });
```


Expand Down Expand Up @@ -573,10 +570,10 @@ TODO: Add image

```javascript
const recentBucket = await navigator.storageBuckets.openOrCreate("recent",
{ durability: "relaxed", persisted: false, title: "Recent" });
{ durability: "relaxed", persisted: false });

const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts",
{ durability: "strict", persisted: true, title: "Drafts" });
{ durability: "strict", persisted: true });
```

### Storage Division
Expand All @@ -594,10 +591,10 @@ TODO: Add image
```javascript
// Bucket creation per user account.
const user1Bucket = await navigator.storageBuckets.openOrCreate(
"userid111111_inbox", {title: "[email protected] Inbox" });
"userid111111_inbox" });

const user2Bucket = await navigator.storageBuckets.openOrCreate(
"userid222222_inbox", {title: "[email protected] Inbox" });
"userid222222_inbox" });

```

Expand Down Expand Up @@ -639,11 +636,10 @@ TODO: Add image.
```javascript
const offlineVideosBucket = await navigator.storageBuckets.openOrCreate(
"offline_videos",
{ title: "Offline Videos", durability: "strict", persisted: false });
{ durability: "strict", persisted: false });

const recommendationBucket = await navigator.storageBuckets.openOrCreate(
"recommendations", {
title: "Recommendations",
quota: 20 * 1024 * 1024, // 20 MB
});
```
Expand Down Expand Up @@ -714,30 +710,6 @@ would directly integrate bucket names into file names, and makes it easy to
reason about bucket lookup performance.


### Bucket titles

Buckets are expected to be named using programmer-friendly identifiers, simiarly
to variable names. By contrast, bucket titles are user-friendly descriptions.
Titles are intended to support user agents that want to offer the ability to
delete individual buckets in their storage management UI. These user agents may
display bucket titles when showing buckets to their users.

`title` was chosen for consistency with the
[HTML title element](https://html.spec.whatwg.org/multipage/semantics.html#the-title-element).

Bucket titles present some subtleties for applications that support multiple
languages. Specifically, a bucket's title will presumably reflect the
users' preferred language at the time the bucket is created. The current API
surface does not allow changing a bucket's description, so already-created
buckets will not reflect language preference changes.

Including application strings in user agent UI has non-trivial security and
privacy implications, which may deter some user agents from using the `title` as
intended. For example, user agents that intend to incorporate the `title` need
to mitigate against misleading values such as
`"You have a virus! Go to www.evil.com for a cleanup"`.


### Storage policy naming

Here are the considerations used for storage policy naming.
Expand Down Expand Up @@ -854,11 +826,9 @@ we have exposed it off of `navigator.storage.buckets`. The examples below
illustrate this alternative.

```javascript
const inboxBucket = await navigator.storage.buckets.openOrCreate("inbox", {
title: "Inbox",
});
const inboxBucket = await navigator.storage.buckets.openOrCreate("inbox");
const draftsBucket = await navigator.storage.buckets.openOrCreate("drafts", {
durability: "strict", persisted: true, title: "Drafts" });
durability: "strict", persisted: true });

await navigator.storage.buckets.delete("inbox");
await navigator.storage.buckets.delete("drafts");
Expand Down Expand Up @@ -888,33 +858,29 @@ illustrated in the example below.

```javascript
// Creates the "inbox" bucket if does not already exist.
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox", {
title: "Inbox" });
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox");

// Fails if the "inbox" bucket does not already exist.
const inboxBucket = await navigator.storageBuckets.open("inbox", {
title: "Inbox" });
const inboxBucket = await navigator.storageBuckets.open("inbox");

// Fails if the "inbox" bucket already exists.
const inboxBucket = await navigator.storageBuckets.create("inbox", {
title: "Inbox" });
const inboxBucket = await navigator.storageBuckets.create("inbox");
```

Alternatively, we could have settled for one `open()` method with options, as
shown below.

```javascript
// By default, creates the "inbox" bucket if does not already exist.
const inboxBucket = await navigator.storageBuckets.open("inbox", {
title: "Inbox" });
const inboxBucket = await navigator.storageBuckets.open("inbox");

// Fails if the "inbox" bucket does not already exist.
const inboxBucket = await navigator.storageBuckets.open("inbox", {
title: "Inbox", failIfNotExist: true });
failIfNotExist: true });

// Fails if the "inbox" bucket already exists.
const inboxBucket = await navigator.storageBuckets.open("inbox", {
title: "Inbox", failIfExists: true });
failIfExists: true });
```

We think that only exposing the `openOrCreate()` option is the best way to
Expand Down Expand Up @@ -961,9 +927,7 @@ Having entry points to each storage API on the bucket also makes replacing
the default bucket in JS easy.

```javascript
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox", {
title: "Inbox",
});
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox");

// Replace default bucket with inboxBucket for IndexedDB.
window.indexedDB = inboxBucket.indexedDB;
Expand Down Expand Up @@ -1056,6 +1020,32 @@ Relaxing the length to 1024 characters makes it less likely that bucket names
can be



ayuishii marked this conversation as resolved.
Show resolved Hide resolved
### Bucket titles

Because buckets are expected to be named using programmer-friendly identifiers,
simiarly to variable names, we could have a bucket title option,
which in contrast would be user-friendly descriptions of the bucket.
Titles could be useful for user agents that want to offer the ability to
delete individual buckets in their storage management UI. These user agents could
display bucket titles when showing buckets to their users.

`title` was chosen for consistency with the
[HTML title element](https://html.spec.whatwg.org/multipage/semantics.html#the-title-element).

Bucket titles could present some subtleties for applications that support multiple
languages. Specifically, a bucket's title could presumably reflect the
users' preferred language at the time the bucket is created. In this alternative
the API surface will not allow changing a bucket's description, so already-created
buckets will not reflect language preference changes.

This alternative was rejected because including strings provided by the author in
user agent UI may introduce a11y and i18n issues, as well as have non-trivial
security and privacy implications, which may deter some user agents from using
the `title` as intended. For example, user agents that intend to incorporate
the `title` need to mitigate against misleading values such as
`"You have a virus! Go to www.evil.com for a cleanup"`.

### Alternative name for the bucket `title` property
ayuishii marked this conversation as resolved.
Show resolved Hide resolved

The `title` properties could be named `description` instead. This would be
Expand Down Expand Up @@ -1122,7 +1112,7 @@ additional complexity introduced by this alternative.
// Each change (keystroke) in a draft is saved here.
const immediateDraftsBucket = await navigator.storage.buckets.openOrCreate(
"device-drafts",
{ durability: "device", persisted: true, title: "Drafts Cache" });
{ durability: "device", persisted: true });
const immediateDraftsDb = await new Promise(resolve => {
const request = inboxBucket.indexedDB.open("messages", { bucket: "inbox" });
request.onupgradeneeded = () => { /* migration code */ };
Expand All @@ -1136,7 +1126,7 @@ const immediateDraftsDb = await new Promise(resolve => {
// Draft changes are batched every minute and saved here. Writing to this bucket
// on every keystroke is too much of a battery drain.
const draftsBucket = await navigator.storage.buckets.openOrCreate(
"media-drafts", { durability: "media", persisted: true, title: "Drafts" });
"media-drafts", { durability: "media", persisted: true });
const draftsDb = await new Promise(resolve => {
const request = inboxBucket.indexedDB.open("messages", { bucket: "inbox" });
request.onupgradeneeded = () => { /* migration code */ };
Expand Down Expand Up @@ -1314,10 +1304,10 @@ that this alternative leads to more bulky code for expressing the common case.

```javascript
const inboxBucket = await navigator.storageBuckets.openOrCreate("inbox", {
title: "Inbox", durability: "relaxed" });
durability: "relaxed" });

const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
persisted: true, title: "Drafts" });
persisted: true });
```

Second, we think that the current proposal will make it easier to reason about
Expand Down Expand Up @@ -1356,7 +1346,7 @@ with `"strict"` durability and storing the drafts with `"relaxed"` durability.

```javascript
const draftsBucket = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "strict", persisted: true, title: "Drafts" });
durability: "strict", persisted: true });

// Called when the user switches a "drafts" durability toggle.
async function setDraftsDurability(durability) {
Expand All @@ -1377,10 +1367,10 @@ preferences, and read drafts from both buckets.

```javascript
const draftsBuckets = {};
draftsBuckets.strict = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "strict", persisted: true, title: "Drafts (Durable)" });
draftsBuckets.relaxed = await navigator.storageBuckets.openOrCreate("drafts", {
durability: "relaxed", persisted: true, title: "Drafts (Fast)" });
draftsBuckets.strict = await navigator.storageBuckets.openOrCreate(
"drafts-durable", { durability: "strict", persisted: true });
draftsBuckets.relaxed = await navigator.storageBuckets.openOrCreate(
"drafts-fast", { durability: "relaxed", persisted: true });


const draftsDb = {};
Expand Down Expand Up @@ -1519,7 +1509,7 @@ while logging out.

```javascript
const user2Bucket = await navigator.storageBuckets.openOrCreate(
"userid222222_inbox", {title: "[email protected] Inbox" });
"userid222222_inbox");
const user2LogoutChannel = new BroadcastChannel("userid222222_logout");

// Attachments for User 2
Expand All @@ -1546,9 +1536,7 @@ could have included
on the list of APIs that buckets offer.

```javascript
const settingsBucket = await navigator.storageBuckets.openOrCreate("settings", {
title: "User Preferences",
});
const settingsBucket = await navigator.storageBuckets.openOrCreate("settings");

const emailsPerPage = settingsBucket.localStorage.getItem('emailsPerPage');
```
Expand Down