Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
await db.transaction('rw', db.users, async trans =>{
// Wait for a promise:
await trans.waitFor(sleep(100));
// Do an operation on transaction
await trans.users.put({username: "testingtesting"});
await trans.waitFor(sleep(100));
let result = await trans.users.get("testingtesting");
ok(result && result.username === "testingtesting", "Should be able to continue transaction after waiting for non-indexedDB promise");
ok(true, `Waiting spin count:${trans._spinCount}`);
// With timeout
await Dexie.waitFor(sleep(2000), 10) // Timeout of 10 ms.
.then (()=>ok(false, "Should have timed out!"))
.catch('TimeoutError', ex => ok(true, "Timed out as expected"));
// Wait for function
await Dexie.waitFor(async ()=>{
ok(Dexie.currentTransaction === null,
"We should not be in the transaction zone here because transaction can be in a temporary inactive state here");
await sleep(10);
ok (true, "Slept 10 ms")
// Let's test if we can access the transaction from here.
// The transaction should be alive indeed but not in an active state.
await trans.users.count().then(()=>{
// This happens on IE11
ok(true, "Could access transaction within the wait callback. Nice for you, but you were just lucky!");
}).catch(ex => {
// This happens on Firefox and Chrome
await db.transaction('r', db.users, async ()=>{
await sleep(100); // Force transaction to become inactive
try {
await Dexie.waitFor(sleep(10));
ok(false, 'After sleeping, transaction just cannot be alive.');
} catch (err) {
ok(err.name == 'TransactionInactiveError' || err.name == 'InvalidStateError',
`Got TransactionInactiveError or InvalidStateError as expected`);
}
}).then (()=>{
ok(false, 'The transaction should not possibly succeed even though catching, because it was too late.');
// Wait for a promise:
await trans.waitFor(sleep(100));
// Do an operation on transaction
await trans.users.put({username: "testingtesting"});
await trans.waitFor(sleep(100));
let result = await trans.users.get("testingtesting");
ok(result && result.username === "testingtesting", "Should be able to continue transaction after waiting for non-indexedDB promise");
ok(true, `Waiting spin count:${trans._spinCount}`);
// With timeout
await Dexie.waitFor(sleep(2000), 10) // Timeout of 10 ms.
.then (()=>ok(false, "Should have timed out!"))
.catch('TimeoutError', ex => ok(true, "Timed out as expected"));
// Wait for function
await Dexie.waitFor(async ()=>{
ok(Dexie.currentTransaction === null,
"We should not be in the transaction zone here because transaction can be in a temporary inactive state here");
await sleep(10);
ok (true, "Slept 10 ms")
// Let's test if we can access the transaction from here.
// The transaction should be alive indeed but not in an active state.
await trans.users.count().then(()=>{
// This happens on IE11
ok(true, "Could access transaction within the wait callback. Nice for you, but you were just lucky!");
}).catch(ex => {
// This happens on Firefox and Chrome
ok(true, "Could NOT access transaction within the wait callback. As expected. Error: " + ex);
});
ok(Dexie.currentTransaction === null,
"We should not be in the transaction zone here because transaction can be in inactive state here");
});
promisedTest("Dexie.waitFor() outside transaction", async ()=> {
// Test that waitFor can be called when not in a transaction as well.
// The meaning of this is that sometimes a function does db operations without
// a transaction, but should be able to call also within the caller's transaction.
// A function should therefore be able to call Dexie.waitFor() no matter if is executing
// within a transaction or not.
let result = await Dexie.waitFor(sleep(10).then(()=>true));
ok(result, "Could call waitFor outside a transaction as well");
let codeExecuted = false;
await Dexie.waitFor(async ()=>{
await sleep(10);
codeExecuted = true;
});
ok(codeExecuted, "Could call waitFor(function) outside a transation as well");
});
if (progressCallback(progress)) throw new Error("Operation aborted");
}
const chunkedCollection = lastKey == null ?
table.limit(LIMIT) :
table.where(':id').above(lastKey).limit(LIMIT);
const values = await chunkedCollection.toArray();
hasMore = values.length === LIMIT;
if (inbound) {
const filteredValues = filter ?
values.filter(value => filter(tableName, value)) :
values;
const tsonValues = filteredValues.map(value => TSON.encapsulate(value));
if (TSON.mustFinalize()) {
await Dexie.waitFor(TSON.finalize(tsonValues));
}
let json = JSON.stringify(tsonValues, undefined, prettyJson ? 2 : undefined);
if (prettyJson) json = json.split('\n').join('\n ');
// By generating a blob here, we give web platform the opportunity to store the contents
// on disk and release RAM.
slices.push(new Blob([json.substring(1, json.length - 1)]));
lastKey = Dexie.getByKeyPath(values[values.length -1], primKey.keyPath as string);
} else {
const keys = await chunkedCollection.primaryKeys();
let keyvals = keys.map((key, i) => [key, values[i]]);
if (filter) keyvals = keyvals.filter(([key, value]) => filter(tableName, value, key));
const tsonTuples = keyvals.map(tuple => TSON.encapsulate(tuple));
if (TSON.mustFinalize()) {
let json = JSON.stringify(tsonValues, undefined, prettyJson ? 2 : undefined);
if (prettyJson) json = json.split('\n').join('\n ');
// By generating a blob here, we give web platform the opportunity to store the contents
// on disk and release RAM.
slices.push(new Blob([json.substring(1, json.length - 1)]));
lastKey = Dexie.getByKeyPath(values[values.length -1], primKey.keyPath as string);
} else {
const keys = await chunkedCollection.primaryKeys();
let keyvals = keys.map((key, i) => [key, values[i]]);
if (filter) keyvals = keyvals.filter(([key, value]) => filter(tableName, value, key));
const tsonTuples = keyvals.map(tuple => TSON.encapsulate(tuple));
if (TSON.mustFinalize()) {
await Dexie.waitFor(TSON.finalize(tsonTuples));
}
let json = JSON.stringify(tsonTuples, undefined, prettyJson ? 2 : undefined);
if (prettyJson) json = json.split('\n').join('\n ');
// By generating a blob here, we give web platform the opportunity to store the contents
// on disk and release RAM.
slices.push(new Blob([json.substring(1, json.length - 1)]));
if (hasMore) {
slices.push(",");
if (prettyJson) {
slices.push("\n ");
}
}
lastKey = keys[keys.length - 1];
}
}
// Avoid unnescessary loops in "for (const tableExport of dbExport.data)"
while (dbExport.data.length > 0 && dbExport.data[0].rows && (dbExport.data[0].rows as any).complete) {
// We've already imported all rows from the first table. Delete its occurrence
dbExport.data.splice(0, 1);
}
if (!jsonStream.done() && !jsonStream.eof()) {
// Pull some more (keeping transaction alive)
if (readBlobsSynchronously) {
// If we can pull from blob synchronically, we don't have to
// keep transaction alive using Dexie.waitFor().
// This will only be possible in workers.
jsonStream.pullSync(CHUNK_SIZE);
} else {
await Dexie.waitFor(jsonStream.pullAsync(CHUNK_SIZE));
}
}
} while (!jsonStream.done() && !jsonStream.eof());
}
progress.done = true;
db.version(2).stores({ test: 'id' }).upgrade(async t => {
runnedVersions.push(2);
const rowsToCopy = await t.test.toArray();
await Dexie.waitFor((async ()=>{
const otherDB = new Dexie(dbName + '-another-unrelated-db', {addons: []});
otherDB.version(1).stores({foo: 'id'});
await otherDB.open();
await otherDB.foo.bulkAdd(rowsToCopy);
otherDB.close();
})());
});
db.version(3).stores({ test: 'id' }).upgrade(t => {