Skip to content

Commit e7f6a88

Browse files
authored
Merge pull request #2126 from peachesontour/patch-13
Typos
2 parents 85cbc1c + 172ef78 commit e7f6a88

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

6-data-storage/03-indexeddb/article.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ That power is usually excessive for traditional client-server apps. IndexedDB is
1616

1717
The native interface to IndexedDB, described in the specification <https://www.w3.org/TR/IndexedDB>, is event-based.
1818

19-
We can also use `async/await` with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's pretty convenient, but the wrapper is not perfect, it can't replace events for all cases. So we'll start with events, and then, after we gain understanding of IndexedDb, we'll use the wrapper.
19+
We can also use `async/await` with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's pretty convenient, but the wrapper is not perfect, it can't replace events for all cases. So we'll start with events, and then, after we gain an understanding of IndexedDb, we'll use the wrapper.
2020

2121
## Open database
2222

@@ -31,7 +31,7 @@ let openRequest = indexedDB.open(name, version);
3131
- `name` -- a string, the database name.
3232
- `version` -- a positive integer version, by default `1` (explained below).
3333

34-
We can have many databases with different names, but all of them exist within the current origin (domain/protocol/port). Different websites can't access databases of each other.
34+
We can have many databases with different names, but all of them exist within the current origin (domain/protocol/port). Different websites can't access each other's databases.
3535

3636
The call returns `openRequest` object, we should listen to events on it:
3737
- `success`: database is ready, there's the "database object" in `openRequest.result`, that we should use it for further calls.
@@ -40,15 +40,15 @@ The call returns `openRequest` object, we should listen to events on it:
4040

4141
**IndexedDB has a built-in mechanism of "schema versioning", absent in server-side databases.**
4242

43-
Unlike server-side databases, IndexedDB is client-side, the data is stored in the browser, so we, developers, don't have "any time" access to it. So, when we published a new version of our app, and the user visits our webpage, we may need to update the database.
43+
Unlike server-side databases, IndexedDB is client-side, the data is stored in the browser, so we, developers, don't have full-time access to it. So, when we have published a new version of our app, and the user visits our webpage, we may need to update the database.
4444

4545
If the local database version is less than specified in `open`, then a special event `upgradeneeded` is triggered, and we can compare versions and upgrade data structures as needed.
4646

47-
The `upgradeneeded` event also triggers when the database did not exist yet (technically, it's version is `0`), so we can perform initialization.
47+
The `upgradeneeded` event also triggers when the database doesn't yet exist (technically, it's version is `0`), so we can perform the initialization.
4848

4949
Let's say we published the first version of our app.
5050

51-
Then we can open the database with version `1` and perform the initialization in `upgradeneeded` handler like this:
51+
Then we can open the database with version `1` and perform the initialization in an `upgradeneeded` handler like this:
5252

5353
```js
5454
let openRequest = indexedDB.open("store", *!*1*/!*);
@@ -64,7 +64,7 @@ openRequest.onerror = function() {
6464

6565
openRequest.onsuccess = function() {
6666
let db = openRequest.result;
67-
// continue to work with database using db object
67+
// continue working with database using db object
6868
};
6969
```
7070

@@ -89,7 +89,7 @@ openRequest.onupgradeneeded = function(event) {
8989
};
9090
```
9191

92-
Please note: as our current version is `2`, `onupgradeneeded` handler has a code branch for version `0`, suitable for users that come for the first time and have no database, and also for version `1`, for upgrades.
92+
Please note: as our current version is `2`, `onupgradeneeded` handler has a code branch for version `0`, suitable for users that are accessing for the first time and have no database, and also for version `1`, for upgrades.
9393

9494
And then, only if `onupgradeneeded` handler finishes without errors, `openRequest.onsuccess` triggers, and the database is considered successfully opened.
9595

@@ -103,9 +103,9 @@ let deleteRequest = indexedDB.deleteDatabase(name)
103103
```warn header="We can't open an older version of the database"
104104
If the current user database has a higher version than in the `open` call, e.g. the existing DB version is `3`, and we try to `open(...2)`, then that's an error, `openRequest.onerror` triggers.
105105
106-
That's odd, but such thing may happen when a visitor loaded an outdated JavaScript code, e.g. from a proxy cache. So the code is old, but his database is new.
106+
That's rare, but such a thing may happen when a visitor loads outdated JavaScript code, e.g. from a proxy cache. So the code is old, but his database is new.
107107
108-
To protect from errors, we should check `db.version` and suggest him to reload the page. Use proper HTTP caching headers to avoid loading the old code, so that you'll never have such problem.
108+
To protect from errors, we should check `db.version` and suggest a page reload. Use proper HTTP caching headers to avoid loading the old code, so that you'll never have such problems.
109109
```
110110

111111
### Parallel update problem
@@ -121,13 +121,13 @@ So there's a tab with an open connection to DB version `1`, while the second tab
121121

122122
The problem is that a database is shared between two tabs, as it's the same site, same origin. And it can't be both version `1` and `2`. To perform the update to version `2`, all connections to version 1 must be closed, including the one in the first tab.
123123

124-
In order to organize that, the `versionchange` event triggers in such case on the "outdated" database object. We should listen to it and close the old database connection (and probably suggest the visitor to reload the page, to load the updated code).
124+
In order to organize that, the `versionchange` event triggers on the "outdated" database object. We should listen for it and close the old database connection (and probably suggest a page reload, to load the updated code).
125125

126-
If we don't listen to `versionchange` event and don't close the old connection, then the second, new connection won't be made. The `openRequest` object will emit the `blocked` event instead of `success`. So the second tab won't work.
126+
If we don't listen for the `versionchange` event and don't close the old connection, then the second, new connection won't be made. The `openRequest` object will emit the `blocked` event instead of `success`. So the second tab won't work.
127127

128128
Here's the code to correctly handle the parallel upgrade.
129129

130-
It installs `onversionchange` handler after the database is opened, that closes the old connection:
130+
It installs an `onversionchange` handler after the database is opened, that closes the old connection:
131131

132132
```js
133133
let openRequest = indexedDB.open("store", 2);
@@ -163,9 +163,9 @@ Here we do two things:
163163
1. Add `db.onversionchange` listener after a successful opening, to be informed about a parallel update attempt.
164164
2. Add `openRequest.onblocked` listener to handle the case when an old connection wasn't closed. This doesn't happen if we close it in `db.onversionchange`.
165165

166-
There are other variants. For example, we can take time to close things gracefully in `db.onversionchange`, prompt the visitor to save the data before the connection is closed. The new updating connection will be blocked immediatelly after `db.onversionchange` finished without closing, and we can ask the visitor in the new tab to close other tabs for the update.
166+
There are other variants. For example, we can take the time to close things gracefully in `db.onversionchange`, and prompt the visitor to save the data before the connection is closed. The new updating connection will be blocked immediately after `db.onversionchange` has finished without closing, and we can ask the visitor in the new tab to close other tabs for the update.
167167

168-
Such update collision happens rarely, but we should at least have some handling for it, e.g. `onblocked` handler, so that our script doesn't surprise the user by dying silently.
168+
These update collisions happen rarely, but we should at least have some handling for them, e.g. `onblocked` handler, so that our script doesn't surprise the user by dying silently.
169169

170170
## Object store
171171

@@ -179,16 +179,16 @@ Despite being named an "object store", primitives can be stored too.
179179

180180
IndexedDB uses the [standard serialization algorithm](https://www.w3.org/TR/html53/infrastructure.html#section-structuredserializeforstorage) to clone-and-store an object. It's like `JSON.stringify`, but more powerful, capable of storing much more datatypes.
181181

182-
An example of object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects.
182+
An example of an object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects.
183183

184184
**There must be a unique `key` for every value in the store.**
185185

186-
A key must have a type one of: number, date, string, binary, or array. It's an unique identifier: we can search/remove/update values by the key.
186+
A key must be one of the these types - number, date, string, binary, or array. It's a unique identifier, so we can search/remove/update values by the key.
187187

188188
![](indexeddb-structure.svg)
189189

190190

191-
As we'll see very soon, we can provide a key when we add a value to the store, similar to `localStorage`. But when we store objects, IndexedDB allows to setup an object property as the key, that's much more convenient. Or we can auto-generate keys.
191+
As we'll see very soon, we can provide a key when we add a value to the store, similar to `localStorage`. But when we store objects, IndexedDB allows setting up an object property as the key, which is much more convenient. Or we can auto-generate keys.
192192

193193
But we need to create an object store first.
194194

@@ -214,9 +214,9 @@ db.createObjectStore('books', {keyPath: 'id'});
214214

215215
**An object store can only be created/modified while updating the DB version, in `upgradeneeded` handler.**
216216

217-
That's a technical limitation. Outside of the handler we'll be able to add/remove/update the data, but object stores can be created/removed/altered only during version update.
217+
That's a technical limitation. Outside of the handler we'll be able to add/remove/update the data, but object stores can only be created/removed/altered during a version update.
218218

219-
To perform database version upgrade, there are two main approaches:
219+
To perform a database version upgrade, there are two main approaches:
220220
1. We can implement per-version upgrade functions: from 1 to 2, from 2 to 3, from 3 to 4 etc. Then, in `upgradeneeded` we can compare versions (e.g. old 2, now 4) and run per-version upgrades step by step, for every intermediate version (2 to 3, then 3 to 4).
221221
2. Or we can just examine the database: get a list of existing object stores as `db.objectStoreNames`. That object is a [DOMStringList](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist) that provides `contains(name)` method to check for existance. And then we can do updates depending on what exists and what doesn't.
222222

@@ -249,7 +249,7 @@ The term "transaction" is generic, used in many kinds of databases.
249249

250250
A transaction is a group operations, that should either all succeed or all fail.
251251

252-
For instance, when a person buys something, we need:
252+
For instance, when a person buys something, we need to:
253253
1. Subtract the money from their account.
254254
2. Add the item to their inventory.
255255

@@ -261,7 +261,7 @@ Transactions can guarantee that.
261261

262262
To start a transaction:
263263

264-
```js run
264+
```js
265265
db.transaction(store[, type]);
266266
```
267267

@@ -272,10 +272,10 @@ db.transaction(store[, type]);
272272

273273
There's also `versionchange` transaction type: such transactions can do everything, but we can't create them manually. IndexedDB automatically creates a `versionchange` transaction when opening the database, for `updateneeded` handler. That's why it's a single place where we can update the database structure, create/remove object stores.
274274

275-
```smart header="Why there exist different types of transactions?"
275+
```smart header="Why are there different types of transactions?"
276276
Performance is the reason why transactions need to be labeled either `readonly` and `readwrite`.
277277
278-
Many `readonly` transactions are able to access concurrently the same store, but `readwrite` transactions can't. A `readwrite` transaction "locks" the store for writing. The next transaction must wait before the previous one finishes before accessing the same store.
278+
Many `readonly` transactions are able to access the same store concurrently, but `readwrite` transactions can't. A `readwrite` transaction "locks" the store for writing. The next transaction must wait before the previous one finishes before accessing the same store.
279279
```
280280

281281
After the transaction is created, we can add an item to the store, like this:
@@ -309,15 +309,15 @@ request.onerror = function() {
309309

310310
There were basically four steps:
311311

312-
1. Create a transaction, mention all stores it's going to access, at `(1)`.
312+
1. Create a transaction, mentioning all the stores it's going to access, at `(1)`.
313313
2. Get the store object using `transaction.objectStore(name)`, at `(2)`.
314314
3. Perform the request to the object store `books.add(book)`, at `(3)`.
315315
4. ...Handle request success/error `(4)`, then we can make other requests if needed, etc.
316316

317317
Object stores support two methods to store a value:
318318

319319
- **put(value, [key])**
320-
Add the `value` to the store. The `key` is supplied only if the object store did not have `keyPath` or `autoIncrement` option. If there's already a value with same key, it will be replaced.
320+
Add the `value` to the store. The `key` is supplied only if the object store did not have `keyPath` or `autoIncrement` option. If there's already a value with the same key, it will be replaced.
321321

322322
- **add(value, [key])**
323323
Same as `put`, but if there's already a value with the same key, then the request fails, and an error with the name `"ConstraintError"` is generated.
@@ -329,7 +329,7 @@ Similar to opening a database, we can send a request: `books.add(book)`, and the
329329

330330
## Transactions' autocommit
331331

332-
In the example above we started the transaction and made `add` request. But as we stated previously, a transaction may have multiple associated requests, that must either all success or all fail. How do we mark the transaction as finished, no more requests to come?
332+
In the example above we started the transaction and made `add` request. But as we stated previously, a transaction may have multiple associated requests, that must either all succeed or all fail. How do we mark the transaction as finished, with no more requests to come?
333333

334334
The short answer is: we don't.
335335

@@ -343,7 +343,7 @@ So, in the example above no special call is needed to finish the transaction.
343343

344344
Transactions auto-commit principle has an important side effect. We can't insert an async operation like `fetch`, `setTimeout` in the middle of transaction. IndexedDB will not keep the transaction waiting till these are done.
345345

346-
In the code below `request2` in line `(*)` fails, because the transaction is already committed, can't make any request in it:
346+
In the code below, `request2` in line `(*)` fails, because the transaction is already committed, and can't make any request in it:
347347

348348
```js
349349
let request1 = books.add(book);

0 commit comments

Comments
 (0)