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

Use async iterators for iterateCursor and iterateKeyCursor #38

Closed
mariusGundersen opened this issue Jun 5, 2017 · 12 comments
Closed

Use async iterators for iterateCursor and iterateKeyCursor #38

mariusGundersen opened this issue Jun 5, 2017 · 12 comments

Comments

@mariusGundersen
Copy link
Contributor

async iterators seem like a good fit for the cursors, and since the spec is close to done it should be safe to implement a (shimable) api using them

@jakearchibald
Copy link
Owner

Agreed! I'll make this a priority when it isn't behind a flag in the preview release of a browser.

@jakearchibald
Copy link
Owner

I've got a rough plan for this for 4.0.

import { openDb, iterateRecords } from 'idb';

// …

for await (const cursor of iterateRecords(storeOrIndex, optionalRange, optionalDirection)) {
  // Any of the cursor advancing methods can be called here.
  // If none are called, cursor.continue() will be called automatically.
}

@jakearchibald
Copy link
Owner

Scratch that, it should be:

import { openDb, iterateRecords } from 'idb';

// …

for await (const cursor of iterateRecords(storeOrIndex.openCursor())) {
  // Any of the cursor advancing methods can be called here.
  // If none are called, cursor.continue() will be called automatically.
}

Where iterateRecords takes a cursor or a promise for a cursor.

@mariusGundersen
Copy link
Contributor Author

Why is the iterateRecord method needed? I'm sure there is a reason, but it's not obvious

@jakearchibald
Copy link
Owner

I'm looking to make it an optional import, so you don't pay the cost of it if you don't use it.

@matthewp
Copy link

Is this at all blocked by the problem described here? I was looking to make my own iterator in my own project but didn't because I felt like that issue might prevent it from working...

@jakearchibald
Copy link
Owner

That problem is gone in modern browsers.

I'm looking to add async iteration as an optional part of the next version of the library. I just need to figure out the right API.

@jakearchibald
Copy link
Owner

I've started landing the code for this in the 4.0.0 branch https://github.com/jakearchibald/idb/blob/4.0.0/lib/async-iterators.ts.

Here's how it works:

// Iterate over a store
const store = db.transaction('store-name').store;

for await (const cursor of store) {
  console.log(cursor.key, cursor.value);
}

// Iterate over an index
const index = store.index('index-name');

for await (const cursor of index) {
  console.log(cursor.key, cursor.value);
}

// Iterate over a cursor
let cursor = await index.openCursor();
if (cursor) cursor = await cursor.advance(50);
if (cursor) for await (const cursor of cursor) {
  console.log(cursor.key, cursor.value);
}

// You can update/delete/skip entries:
for await (const cursor of store) {
  // Update the value.
  cursor.update(cursor.value + 1);
  // Skip over an item.
  cursor.advance(2);
}

@quasicomputational
Copy link

That looks pretty nifty. I do have one comment, though: when iterating over a cursor, often you're happy to execute the loop zero times if the cursor returns no results. But, as openCursor will return null when the provided query doesn't match, this necessitates that if (cursor) check. Maybe it'd be nice to have a different flavour (openCursorIterable?) that will always return an async iterator, finishing immediately in the no-values-found case, allowing this code:

for await (const cursor of index.openCursorIterable(query)) {
  doStuff(cursor.value);
}

@jakearchibald
Copy link
Owner

Yeah, that's a good idea

@jakearchibald
Copy link
Owner

Added .iterate to stores and indexes. Takes the same args are openCursor. 1337312#diff-c6b8a053edbb56620d53f014adc13bf1

@jakearchibald
Copy link
Owner

Added in v4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants