From ea5e66555759b5a5702260e44f415dd356585a74 Mon Sep 17 00:00:00 2001 From: Newton Koumantzelis Date: Fri, 2 Apr 2021 14:21:37 -0700 Subject: [PATCH 1/5] feat: add in basic prototype --- prototypes/indexed-db/.gitignore | 1 + prototypes/indexed-db/README.md | 25 ++++++ prototypes/indexed-db/basic/a.html | 17 ++++ prototypes/indexed-db/basic/b.html | 17 ++++ prototypes/indexed-db/basic/c.html | 17 ++++ prototypes/indexed-db/basic/index.html | 17 ++++ prototypes/indexed-db/basic/scripts/app.js | 2 + prototypes/indexed-db/basic/scripts/db.js | 98 ++++++++++++++++++++++ prototypes/indexed-db/package-lock.json | 13 +++ prototypes/indexed-db/package.json | 22 +++++ 10 files changed, 229 insertions(+) create mode 100644 prototypes/indexed-db/.gitignore create mode 100644 prototypes/indexed-db/README.md create mode 100644 prototypes/indexed-db/basic/a.html create mode 100644 prototypes/indexed-db/basic/b.html create mode 100644 prototypes/indexed-db/basic/c.html create mode 100644 prototypes/indexed-db/basic/index.html create mode 100644 prototypes/indexed-db/basic/scripts/app.js create mode 100644 prototypes/indexed-db/basic/scripts/db.js create mode 100644 prototypes/indexed-db/package-lock.json create mode 100644 prototypes/indexed-db/package.json diff --git a/prototypes/indexed-db/.gitignore b/prototypes/indexed-db/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/prototypes/indexed-db/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/prototypes/indexed-db/README.md b/prototypes/indexed-db/README.md new file mode 100644 index 0000000..3d73701 --- /dev/null +++ b/prototypes/indexed-db/README.md @@ -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. + + + + + Data on support for the indexeddb feature across the major browsers from caniuse.com +
+[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`. diff --git a/prototypes/indexed-db/basic/a.html b/prototypes/indexed-db/basic/a.html new file mode 100644 index 0000000..09415db --- /dev/null +++ b/prototypes/indexed-db/basic/a.html @@ -0,0 +1,17 @@ + + + + + IndexedDB Prototype + + + + + diff --git a/prototypes/indexed-db/basic/b.html b/prototypes/indexed-db/basic/b.html new file mode 100644 index 0000000..6784e92 --- /dev/null +++ b/prototypes/indexed-db/basic/b.html @@ -0,0 +1,17 @@ + + + + + IndexedDB Prototype + + + + + diff --git a/prototypes/indexed-db/basic/c.html b/prototypes/indexed-db/basic/c.html new file mode 100644 index 0000000..b59dd48 --- /dev/null +++ b/prototypes/indexed-db/basic/c.html @@ -0,0 +1,17 @@ + + + + + IndexedDB Prototype + + + + + diff --git a/prototypes/indexed-db/basic/index.html b/prototypes/indexed-db/basic/index.html new file mode 100644 index 0000000..ad3773b --- /dev/null +++ b/prototypes/indexed-db/basic/index.html @@ -0,0 +1,17 @@ + + + + + IndexedDB Prototype + + + + + diff --git a/prototypes/indexed-db/basic/scripts/app.js b/prototypes/indexed-db/basic/scripts/app.js new file mode 100644 index 0000000..1b12b55 --- /dev/null +++ b/prototypes/indexed-db/basic/scripts/app.js @@ -0,0 +1,2 @@ +import { joinAdInterestGroup } from './'; + diff --git a/prototypes/indexed-db/basic/scripts/db.js b/prototypes/indexed-db/basic/scripts/db.js new file mode 100644 index 0000000..7e175a5 --- /dev/null +++ b/prototypes/indexed-db/basic/scripts/db.js @@ -0,0 +1,98 @@ +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() { + /* + 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'); + }, + }); + + // Add an article: + await db.add('interest-groups', { + owner: 'www.magnite.com', + name: "womens-running-shoes", + date: Date.now(), + expire: Date.now() + (30 * 86400000), + }); + + // 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, + ]); + } + + // 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: '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'); + }, + }); + + // Add an article: + await db.add('interest-groups', { + owner: options.owner, + name: options.name, + date: Date.now(), + expire: Date.now() + expiry, + }); +} diff --git a/prototypes/indexed-db/package-lock.json b/prototypes/indexed-db/package-lock.json new file mode 100644 index 0000000..5718210 --- /dev/null +++ b/prototypes/indexed-db/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "@magnite/indexeddb.prototype", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "idb": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/idb/-/idb-6.0.0.tgz", + "integrity": "sha512-+M367poGtpzAylX4pwcrZIa7cFQLfNkAOlMMLN2kw/2jGfJP6h+TB/unQNSVYwNtP8XqkLYrfuiVnxLQNP1tjA==" + } + } +} diff --git a/prototypes/indexed-db/package.json b/prototypes/indexed-db/package.json new file mode 100644 index 0000000..5c21be1 --- /dev/null +++ b/prototypes/indexed-db/package.json @@ -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 ", + "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" + } +} From 6afbd4614d84224319c13a9aa0fe3eff25ea56ac Mon Sep 17 00:00:00 2001 From: Newton Koumantzelis Date: Mon, 5 Apr 2021 17:19:10 -0700 Subject: [PATCH 2/5] fix: suggestions as per @brodrigu - Update `id` field as key to `_key` - Create an index on `_expires` https://github.com/MagniteEngineering/fledge.polyfill/pull/18#discussion_r607365810 --- prototypes/indexed-db/basic/scripts/db.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prototypes/indexed-db/basic/scripts/db.js b/prototypes/indexed-db/basic/scripts/db.js index 7e175a5..2515976 100644 --- a/prototypes/indexed-db/basic/scripts/db.js +++ b/prototypes/indexed-db/basic/scripts/db.js @@ -79,12 +79,14 @@ export async function joinAdInterestGroup(options, expiry) { // Create a store of objects const store = db.createObjectStore('interest-groups', { // The 'id' property of the object will be the key. - keyPath: 'id', + 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'); + store.createIndex('owner', 'owner', { unique: false }); + store.createIndex('name', 'name', { unique: false }); + store.createIndex('_expires', '_expires', { unique: false }); }, }); From 855986f387c48be06206862152860e3398ad7d6e Mon Sep 17 00:00:00 2001 From: Newton Koumantzelis Date: Mon, 5 Apr 2021 17:21:05 -0700 Subject: [PATCH 3/5] feat: add in check for unique entry This is required because IndexedDB will error if you try to write over the key with the same key that already exists in the dB, thus since we're using the `owner-name` as the key, we need to stop trying to overwrite the dB entry each time the page is refreshed. --- prototypes/indexed-db/basic/scripts/db.js | 24 ++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/prototypes/indexed-db/basic/scripts/db.js b/prototypes/indexed-db/basic/scripts/db.js index 2515976..9df3c0f 100644 --- a/prototypes/indexed-db/basic/scripts/db.js +++ b/prototypes/indexed-db/basic/scripts/db.js @@ -90,11 +90,21 @@ export async function joinAdInterestGroup(options, expiry) { }, }); - // Add an article: - await db.add('interest-groups', { - owner: options.owner, - name: options.name, - date: Date.now(), - expire: Date.now() + expiry, - }); + 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, + }); + } + + /* + ig.name = "an-updated-value"; + await db.put("interest-groups", ig); + */ } From 9d97a6a0c89beb4d87b6d9773a89558f28137a9b Mon Sep 17 00:00:00 2001 From: Newton Koumantzelis Date: Mon, 5 Apr 2021 17:25:06 -0700 Subject: [PATCH 4/5] feat: test out how updating a value works --- prototypes/indexed-db/basic/index.html | 1 + prototypes/indexed-db/basic/scripts/db.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/prototypes/indexed-db/basic/index.html b/prototypes/indexed-db/basic/index.html index ad3773b..b7cc858 100644 --- a/prototypes/indexed-db/basic/index.html +++ b/prototypes/indexed-db/basic/index.html @@ -10,6 +10,7 @@ const ig = { owner: 'www.magnite.com', name: 'womens-running-shoes', + update: true, }; joinAdInterestGroup(ig, (30 * 86400000)); diff --git a/prototypes/indexed-db/basic/scripts/db.js b/prototypes/indexed-db/basic/scripts/db.js index 9df3c0f..4a5a4a8 100644 --- a/prototypes/indexed-db/basic/scripts/db.js +++ b/prototypes/indexed-db/basic/scripts/db.js @@ -103,8 +103,8 @@ export async function joinAdInterestGroup(options, expiry) { }); } - /* - ig.name = "an-updated-value"; - await db.put("interest-groups", ig); - */ + if (options.update) { + ig.name = "an-updated-value"; + await db.put("interest-groups", ig); + } } From d53e89e8450ef717cd3ec4be29da6b387af01f30 Mon Sep 17 00:00:00 2001 From: Newton Koumantzelis Date: Mon, 5 Apr 2021 17:29:44 -0700 Subject: [PATCH 5/5] feat: test out ability to delete an item from the dB --- prototypes/indexed-db/basic/c.html | 1 + prototypes/indexed-db/basic/scripts/db.js | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/prototypes/indexed-db/basic/c.html b/prototypes/indexed-db/basic/c.html index b59dd48..cb10035 100644 --- a/prototypes/indexed-db/basic/c.html +++ b/prototypes/indexed-db/basic/c.html @@ -10,6 +10,7 @@ const ig = { owner: 'www.tradedesk.com', name: 'womens-running-shoes', + delete: true, }; joinAdInterestGroup(ig, (30 * 86400000)); diff --git a/prototypes/indexed-db/basic/scripts/db.js b/prototypes/indexed-db/basic/scripts/db.js index 4a5a4a8..0e13fee 100644 --- a/prototypes/indexed-db/basic/scripts/db.js +++ b/prototypes/indexed-db/basic/scripts/db.js @@ -107,4 +107,8 @@ export async function joinAdInterestGroup(options, expiry) { ig.name = "an-updated-value"; await db.put("interest-groups", ig); } + + if (options.delete) { + await db.delete("interest-groups", ig._key); + } }