Skip to content

Commit 4ff1754

Browse files
committed
Add addEarlyCallback method whose callbacks, unlike the later-executed addCallback ones, can themselves use idb-schema methods (e.g., to convert from JSON to idb-schema) though, since they execute within upgradeneeded cannot support Promises (as can the callbacks within addCallback when schema.open or schema.upgrade are used); document
1 parent a28854c commit 4ff1754

3 files changed

Lines changed: 41 additions & 7 deletions

File tree

History.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
which can support promises returned by `addCallback` callbacks (and a
55
`flushIncomplete` method for flushing storage pertaining to incomplete
66
upgrades)
7+
* Feature: Add `addEarlyCallback` to allow use of `idb-schema` methods
8+
within these synchronous callbacks
79

810
## 3.2.1 / 2015-11-29
911

Readme.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ schema.open('myDb', 3).then((db) => {
9090
However, unlike `callback()`, when `schema.open` is used, the callbacks
9191
added by `addCallback` cannot handle operations such as adding stores
9292
or indexes (though these operations can be executed with the other
93-
methods of idb-schema anyways).
93+
methods of idb-schema anyways) though those added by `addEarlyCallback`
94+
can be.
9495

9596
Besides conducting an upgrade, `schema.open` uses the `open` of
9697
[idb-factory](https://github.com/treojs/idb-factory) behind the scenes, so
@@ -223,6 +224,26 @@ Options:
223224

224225
Delete index by `name` from current store.
225226

227+
### schema.addEarlyCallback(cb)
228+
229+
Adds a `cb` to be executed at the beginning of the `upgradeneeded` event
230+
and passed the event object. This will, out of necessity, run synchronously,
231+
so promises cannot safely be used therein (whether used in `schema.callback`
232+
or `schema.open`/`schema.upgrade`).
233+
234+
However, due to their early execution, such callbacks are, unlike
235+
`addCallback` callbacks used with `schema.open`/`schema.upgrade`,
236+
able to use methods such as `addStore`.
237+
238+
```js
239+
const schema = new Schema()
240+
.addStore('users', { increment: true, keyPath: 'id' })
241+
.addIndex('byName', 'name')
242+
.addEarlyCallback((e) => {
243+
schema.addIndex('byId', 'id')
244+
})
245+
```
246+
226247
### schema.addCallback(cb)
227248

228249
Adds a `cb` to be executed at the end of the `upgradeneeded` event
@@ -249,7 +270,8 @@ these methods, unlike `schema.callback`, will cause the callbacks
249270
to be executed safely within the more persistent `onsuccess` event (and the
250271
callback will be passed the database result instead of the `upgradeneeded`
251272
event). If you do not need promises, you will have the option of using
252-
`schema.callback` in addition to `schema.open` or `schema.upgrade`.
273+
`schema.callback` in addition to `schema.open` or `schema.upgrade` (or
274+
you can use `addEarlyCallback`).
253275

254276
### schema.clone()
255277

src/index.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export default class Schema {
5252
indexes: [], // store.createIndex
5353
dropIndexes: [], // store.deleteIndex
5454
callbacks: [],
55+
earlyCallbacks: [],
5556
version: version, // version
5657
}
5758

@@ -178,6 +179,11 @@ export default class Schema {
178179
return this
179180
}
180181

182+
addEarlyCallback(cb) {
183+
this._versions[this.version()].earlyCallbacks.push(cb)
184+
return this
185+
}
186+
181187
/**
182188
* Flushes storage pertaining to incomplete upgrades
183189
*
@@ -232,7 +238,7 @@ export default class Schema {
232238
dbLast.close()
233239

234240
setTimeout(() => {
235-
open(dbName, versionSchema.version, upgradeneeded((e, ...dbInfo) => {
241+
open(dbName, versionSchema.version, upgradeneeded((...dbInfo) => {
236242
upgradeVersion(versionSchema, ...dbInfo)
237243
})).then((db) => {
238244
afterOpen(db, res, rej, start)
@@ -342,7 +348,7 @@ export default class Schema {
342348
reject(err)
343349
return
344350
}
345-
const upgrade = upgradeneeded((e, ...dbInfo) => {
351+
const upgrade = upgradeneeded((...dbInfo) => {
346352
// Upgrade from 0 to version 1
347353
const versionIter = versions.next()
348354
if (versionIter.done) {
@@ -379,10 +385,10 @@ export default class Schema {
379385
*/
380386

381387
callback() {
382-
const versions = values(clone(this._versions)).sort((a, b) => a.version - b.version)
388+
const versions = values(this._versions).sort((a, b) => a.version - b.version)
383389
return upgradeneeded((e, ...dbInfo) => {
384390
versions.forEach((versionSchema) => {
385-
upgradeVersion(versionSchema, ...dbInfo)
391+
upgradeVersion(versionSchema, e, ...dbInfo)
386392
versionSchema.callbacks.forEach((cb) => {
387393
cb(e)
388394
})
@@ -453,9 +459,13 @@ function upgradeneeded(cb) {
453459
}
454460
}
455461

456-
function upgradeVersion(versionSchema, oldVersion, db, tr) {
462+
function upgradeVersion(versionSchema, e, oldVersion, db, tr) {
457463
if (oldVersion >= versionSchema.version) return
458464

465+
versionSchema.earlyCallbacks.forEach((cb) => {
466+
cb(e)
467+
})
468+
459469
versionSchema.stores.forEach((s) => {
460470
// Only pass the options that are explicitly specified to createObjectStore() otherwise IE/Edge
461471
// can throw an InvalidAccessError - see https://msdn.microsoft.com/en-us/library/hh772493(v=vs.85).aspx

0 commit comments

Comments
 (0)