Skip to content
This repository was archived by the owner on Jan 21, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions prototypes/indexed-db/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
25 changes: 25 additions & 0 deletions prototypes/indexed-db/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# `IndexedDB` Prototype

The following is meant to showcase `IndexedDB` support in modern browsers, particularly the ones that will be required to support the Fledge proposal when it is released.

Following discussions [#5](https://github.com/MagniteEngineering/fledge.polyfill/discussions/5), [#6](https://github.com/MagniteEngineering/fledge.polyfill/discussions/6) and [#7](https://github.com/MagniteEngineering/fledge.polyfill/discussions/7), this will be used in how store the data around Interest Groups, bids, and auctions. As such, we need to verify its capabilities as well as limits to ensure this is the most appropriate choice of technology currently available.

## Support

As of this experiment, the earliest version of Chrome that would contain Fledge support would be v91, which is set to be released in June of 2021. According to [MDN's Guide to IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), full support is as follows, which means any browser supporting Fledge would support IndexedDB.

<picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/indexeddb.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/indexeddb.png">
<img src="https://caniuse.bitsofco.de/image/indexeddb.jpg" alt="Data on support for the indexeddb feature across the major browsers from caniuse.com">
</picture><br />
[source](https://caniuse.com/indexeddb)


## Running the Demo

### The Basics

This demo is hosted in the `basic/` directory and showcases the level of browser support. Through this demo you should see that each refresh of the page will add a new item into the `dB` with an incremental ID.

To run the demo, insure you have the dependencies required by running `npm install` in the immediate parent directory (`indexed-db`). Then `cd` into the `basic` directory and run `npx serve`.
17 changes: 17 additions & 0 deletions prototypes/indexed-db/basic/a.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>IndexedDB Prototype</title>
</head>
<body>
<script type="module">
import { joinAdInterestGroup } from './scripts/db.js';
const ig = {
owner: 'www.nike.com',
name: 'womens-running-shoes',
};
joinAdInterestGroup(ig, (30 * 86400000));
</script>
</body>
</html>
17 changes: 17 additions & 0 deletions prototypes/indexed-db/basic/b.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>IndexedDB Prototype</title>
</head>
<body>
<script type="module">
import { joinAdInterestGroup } from './scripts/db.js';
const ig = {
owner: 'www.dsp.com',
name: 'womens-running-shoes',
};
joinAdInterestGroup(ig, (30 * 86400000));
</script>
</body>
</html>
18 changes: 18 additions & 0 deletions prototypes/indexed-db/basic/c.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>IndexedDB Prototype</title>
</head>
<body>
<script type="module">
import { joinAdInterestGroup } from './scripts/db.js';
const ig = {
owner: 'www.tradedesk.com',
name: 'womens-running-shoes',
delete: true,
};
joinAdInterestGroup(ig, (30 * 86400000));
</script>
</body>
</html>
18 changes: 18 additions & 0 deletions prototypes/indexed-db/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>IndexedDB Prototype</title>
</head>
<body>
<script type="module">
import { joinAdInterestGroup } from './scripts/db.js';
const ig = {
owner: 'www.magnite.com',
name: 'womens-running-shoes',
update: true,
};
joinAdInterestGroup(ig, (30 * 86400000));
</script>
</body>
</html>
2 changes: 2 additions & 0 deletions prototypes/indexed-db/basic/scripts/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { joinAdInterestGroup } from './';

114 changes: 114 additions & 0 deletions prototypes/indexed-db/basic/scripts/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { openDB } from '../../node_modules/idb/with-async-ittr.js';

const hoursPerDay = 24;
const minsPerHour = 60;
const secsPerMinute = 60;
const msPerSeconds = 1000;
const msPerDay = hoursPerDay * minsPerHour * secsPerMinute * msPerSeconds;
const expiry = 30 * msPerDay;
console.log(msPerDay);

async function demo() {
/*
Comment thread
iamnewton marked this conversation as resolved.
const db = await openDB('Interest Groups', 1, {
upgrade(db) {
// Create a store of objects
const store = db.createObjectStore('interest-groups', {
// The 'id' property of the object will be the key.
keyPath: 'id',
// If it isn't explicitly set, create a value by auto incrementing.
autoIncrement: true,
});
// Create an index on the 'date' property of the objects.
store.createIndex('owner', 'owner');
Comment thread
iamnewton marked this conversation as resolved.
},
});

// Add an article:
await db.add('interest-groups', {
owner: 'www.magnite.com',
name: "womens-running-shoes",
date: Date.now(),
expire: Date.now() + (30 * 86400000),
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we use this for real we should generate our own id, probably something like ${owner}-${name} for quick lookup and to enforce the requirements.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree we should sit down and figure out a new schema for this now that we have a dB.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my suggestion is for the primary key to be named key if possible and for it to be ${owner}-${name}.

In addition, we should have an index on the _expires key so we can easily find articles that have expired:

store.createIndex('_expires', '_expires');

Basically we use what is described here: https://github.com/MagniteEngineering/fledge.polyfill/blob/main/specifications/interest-groups.md but make it a flat structure instead of the owner -> group hierarchy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit: 6afbd46


// Add multiple articles in one transaction:
{
const tx = db.transaction('interest-groups', 'readwrite');
await Promise.all([
tx.store.add({
owner: 'www.magnite.com',
name: "mens-running-shoes",
date: Date.now(),
expire: Date.now() + (30 * 86400000),
}),
tx.store.add({
owner: 'www.ssp.com',
name: "running-shoes",
date: Date.now(),
expire: Date.now() + (30 * 86400000),
}),
tx.done,
Comment thread
iamnewton marked this conversation as resolved.
]);
}

// Get all the articles in date order:
console.log(await db.getAllFromIndex('interest-group', 'owner'));

// Add 'And, happy new year!' to all articles on 2019-01-01:
{
const tx = db.transaction('interest-group', 'readwrite');
const index = tx.store.index('owner');

for await (const cursor of index.iterate(new Date('2019-01-01'))) {
const group = { ...cursor.value };
group.body += ' And, happy new year!';
cursor.update(article);
}

await tx.done;
}
*/
}

// await demo();

export async function joinAdInterestGroup(options, expiry) {
const db = await openDB('Interest Groups', 1, {
upgrade(db) {
// Create a store of objects
const store = db.createObjectStore('interest-groups', {
// The 'id' property of the object will be the key.
keyPath: '_key',
// If it isn't explicitly set, create a value by auto incrementing.
autoIncrement: true,
});
// Create an index on the 'date' property of the objects.
store.createIndex('owner', 'owner', { unique: false });
store.createIndex('name', 'name', { unique: false });
store.createIndex('_expires', '_expires', { unique: false });
},
});

const ig = await db.get('interest-groups', `${options.owner}-${options.name}`);
console.log(ig);
if (!ig) {
// Add a group:
await db.add('interest-groups', {
_key: `${options.owner}-${options.name}`,
_date: Date.now(),
_expires: Date.now() + expiry,
owner: options.owner,
name: options.name,
});
}

if (options.update) {
ig.name = "an-updated-value";
await db.put("interest-groups", ig);
}

if (options.delete) {
await db.delete("interest-groups", ig._key);
}
}
13 changes: 13 additions & 0 deletions prototypes/indexed-db/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions prototypes/indexed-db/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@magnite/indexeddb.prototype",
"version": "0.0.0",
"description": "A prototype to showcase the capabilities of IndexedDB with regard to Fledge auctions",
"main": "index.js",
"scripts": {
"test": "npm test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MagniteEngineering/fledge.polyfill.git"
},
"author": "Newton Koumantzelis <github@iamnewton.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/MagniteEngineering/fledge.polyfill/issues"
},
"homepage": "https://github.com/MagniteEngineering/fledge.polyfill/prototypes/indexed-db#readme",
"dependencies": {
"idb": "^6.0.0"
}
}