Skip to content
Open
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
100 changes: 100 additions & 0 deletions IndexedDB/key-serialization-transaction-state.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// META: script=resources/support-promises.js
// META: title=Indexed DB transaction state during Structured Serializing
// META: timeout=long
'use strict';

const setupKetSerializationTest = async (testCase) => {
Copy link
Copy Markdown
Contributor

@asutherland asutherland Feb 20, 2026

Choose a reason for hiding this comment

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

typo nit: I think Ket is meant to be Key here (and its many uses)? A comment is probably appropriate if if it's not a typo.

const db = await createDatabase(testCase, database => {
const objectStore = database.createObjectStore('store');
objectStore.createIndex('idx', 'name');
objectStore.put({ name: 'a' }, 0);
});

const transaction = db.transaction(['store'], 'readwrite');
const objectStore = transaction.objectStore('store');
const index = objectStore.index('idx');

return { db, transaction, objectStore, index };
};

const testKeySerialization = async (db, testCase, transaction, objectStore, callback) => {
let getterCalled = false;

const activeKey = ['value that should not be used'];
Object.defineProperty(activeKey, '0', {
enumerable: true,
get: testCase.step_func(() => {
getterCalled = true;
assert_throws_dom('TransactionInactiveError', () => {
objectStore.get('key');
}, 'transaction should not be active during key serialization');
return 'value that should not be used';
}),
});

callback(activeKey)

await promiseForTransaction(testCase, transaction);
db.close();

assert_true(getterCalled,
"activeKey's getter should be called during test");
};

promise_test(async testCase => {
const { db, transaction, objectStore } = await setupKetSerializationTest(testCase);

await testKeySerialization(db, testCase, transaction, objectStore, activeKey => {
objectStore.add({}, activeKey);
});
}, 'Transaction inactive during key serialization in IDBObjectStore.add()');

promise_test(async testCase => {
const { db, transaction, objectStore } = await setupKetSerializationTest(testCase);

await testKeySerialization(db, testCase, transaction, objectStore, activeKey => {
objectStore.put({}, activeKey);
});
}, 'Transaction inactive during key serialization in IDBObjectStore.put()');

promise_test(async testCase => {
const { db, transaction, objectStore } = await setupKetSerializationTest(testCase);

const cursor = await new Promise((resolve, reject) => {
const cursorReq = objectStore.openCursor();
cursorReq.onerror = reject;
cursorReq.onsuccess = e => resolve(e.target.result);
});

await testKeySerialization(db, testCase, transaction, objectStore, activeKey => {
cursor.continue(activeKey);
});
}, 'Transaction inactive during key serialization in IDBCursor.continue()');

promise_test(async testCase => {
const { db, transaction, objectStore, index } = await setupKetSerializationTest(testCase);

const cursor = await new Promise((resolve, reject) => {
const cursorReq = index.openCursor();
cursorReq.onerror = reject;
cursorReq.onsuccess = e => resolve(e.target.result);
});

await testKeySerialization(db, testCase, transaction, objectStore, activeKey => {
cursor.continuePrimaryKey(activeKey, 0);
});
}, 'Transaction inactive during key serialization in IDBCursor.continuePrimaryKey()');

promise_test(async testCase => {
const { db, transaction, objectStore, index } = await setupKetSerializationTest(testCase);

const cursor = await new Promise((resolve, reject) => {
const cursorReq = index.openCursor();
cursorReq.onerror = reject;
cursorReq.onsuccess = e => resolve(e.target.result);
});

await testKeySerialization(db, testCase, transaction, objectStore, activeKey => {
cursor.continuePrimaryKey(0, activeKey);
});
}, 'Transaction inactive during primary key serialization in IDBCursor.continuePrimaryKey()');