10

In indexedDB in html5 api, I can use it to store key-value pairs. But how can I make sure that after adding a certain key-value, after 1 day, that key should automatically be deleted from the db.

I was thinking of wrapping the value in an object with current datetime, and expiry time, and when u get the value, check the time difference, but is this the best way?

Thanks

omega
  • 40,311
  • 81
  • 251
  • 474

4 Answers4

15

Yep, what Scott Marcus and dgrogan said. One more hint: if you create an index on the timestamp, you can iterate a cursor over the range of "expired" values and delete them after opening the database.

const open = indexedDB.open("demo");

open.onupgradeneeded = function () {
  const db = open.result;
  const store = db.createObjectStore("store");
  const index = store.createIndex("timestamp", "timestamp");

  // Populate with some dummy data, with about half from the past:
  for (let id = 0; id < 20; ++id) {
    store.put(
      {
        value: Math.random(),
        timestamp: new Date(Date.now() + (Math.random() - 0.5) * 10000),
      },
      id
    );
  }
};

open.onsuccess = function () {
  const db = open.result;
  const tx = db.transaction("store", "readwrite");
  // Anything in the past:
  const range = IDBKeyRange.upperBound(new Date());

  tx
    .objectStore("store")
    .index("timestamp")
    .openCursor(range).onsuccess = function (e) {
    const cursor = e.target.result;
    if (!cursor) return;
    console.log("deleting: " + cursor.key);
    cursor.delete();
    cursor.continue();
  };

  // This transaction will run after the first commits since
  // it has overlapping scope:
  const tx2 = db.transaction("store");
  tx2.objectStore("store").count().onsuccess = function (e) {
    console.log("records remaining: " + e.target.result);
  };
};
Etienne Martin
  • 10,018
  • 3
  • 35
  • 47
Joshua Bell
  • 7,727
  • 27
  • 30
5

Support for automatically expiring IndexedDB and other storage data is being considered. See https://github.com/whatwg/storage/issues/11. It would be helpful if you could describe your use case there.

In the meantime you'll have to do something like you outlined or what Scott Marcus suggests.

dgrogan
  • 2,587
  • 1
  • 17
  • 21
3

IndexedDB can only be modified by code. It has no automatic capabilities. Why not just store the data with a timestamp value and modify your code to remove it when the timestamp is out of date?

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Because the user might never visit your site again, but you may not want lots of data to remain on their PC unnecessarily. – flodin Dec 18 '22 at 13:46
  • @flodin I can't imagine any scenario where the server cares how long the client holds on to data between visits. On the other hand, the Server can easily be configured to purge records after a certain amount of time has passed without that client re-connecting. – Scott Marcus Dec 18 '22 at 17:49
  • 2
    I care, as a user. I don't want sites that I visited a year ago to keep several megabytes of data on my PC. – flodin Dec 29 '22 at 09:37
  • @flodin Then clear your cache? That's an end-user decision, not for the server to decide. – Scott Marcus Dec 29 '22 at 20:36
  • 2
    I disagree. We develop software for humans and it should be written with empathy for humans. So it's on the software developer to not leave garbage lying around on people's computers in a way that messes things up for them. My kids don't know about clearing the cache and neither do my parents. Plus I doubt clearing the cache will help as this is likely considered cookie data. If they clear cookies, they'll lose their login sessions on every site and cause headaches. A _cache_ wouldn't need manual clearing as it should have a size limit and automatically evict stuff that hasn't been used. – flodin Jan 16 '23 at 08:31
0

I wrote a npm module sometime back which expires indexedDB keys after x mins. Also it has very simple api (similar to memcache/localstorage) and is suited for use as a key-value store.

You can check it on npm here .

Sachin
  • 3,350
  • 2
  • 17
  • 29