<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script type="module"> function reqAsPromise(req) { return new Promise((resolve, reject) => { req.addEventListener("success", event => resolve(event.target.result)); req.addEventListener("error", event => reject(event.target.error)); }); } function txnAsPromise(txn) { return new Promise((resolve, reject) => { txn.addEventListener("complete", resolve); txn.addEventListener("abort", reject); }); } function readAll(cursor) { return new Promise((resolve, reject) => { const results = []; cursor.onerror = (event) => { reject(new Error("Query failed: " + event.target.errorCode)); }; cursor.onsuccess = (event) => { const cursor = event.target.result; if (!cursor) { resolve(results); } else { results.push(cursor.value); cursor.continue(); } }; }); } let seed = 13423; function prn() { let x = Math.sin(seed++) * 10000; return x - Math.floor(x); } function pad(str, len) { return str + " ".repeat(len - str.length); } function formatByteArray(a) { return `[${Array.from(a).join(",")}]`; } async function main() { let isNew = false; const openReq = window.indexedDB.open("bin_key_sorting_test", 1); openReq.onupgradeneeded = (ev) => { const db = ev.target.result; db.createObjectStore("test", {keyPath: ["binKey"]}); isNew = true; }; const db = await reqAsPromise(openReq); // fill test store with some data if (isNew) { const txn = db.transaction("test", "readwrite"); const store = txn.objectStore("test"); const rndByte = () => Math.ceil(prn() * 255); for(let i = 0; i < 10; ++i) { const b1 = rndByte(), b2 = rndByte(), b3 = rndByte(), b4 = rndByte(); console.log(`adding key (${b1},${b2},${b3},${b4})`); store.add({binKey: new Uint8Array([b1, b2, b3, b4])}); } store.add({binKey: new Uint8Array([0x80, 0x00, 0x00, 0x00])}); store.add({binKey: new Uint8Array([0x00, 0x00, 0x00, 0x00])}); store.add({binKey: new Uint8Array([0x7F, 0xFF, 0xFF, 0xFF])}); store.add({binKey: new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF])}); await txnAsPromise(txn); } const txn = db.transaction("test", "readonly"); const store = txn.objectStore("test"); const range = IDBKeyRange.upperBound( // Uint8Array.from([0x00, 0x00, 0x00, 0x00]).buffer, Uint8Array.from([0xFF, 0xFF, 0xFF, 0xFF]).buffer, // new Uint8Array([0x80, 0x00, 0x00, 0x00]).buffer, new // Uint8Array([0x7F, 0xFF, 0xFF, 0xFF]).buffer, false ); // const values = await readAll(store.openCursor(range, "next")); const values = await readAll(store.openCursor(range, "prev")); console.log(pad(`[uint8;4]`, 20) + " [int8;4]"); for (const v of values) { const uintStr = formatByteArray(new Uint8Array(v.binKey)); const intStr = formatByteArray(new Int8Array(v.binKey)); console.log(pad(uintStr, 20) + " " + intStr); } } main(); </script> </body> </html>