-
Notifications
You must be signed in to change notification settings - Fork 100
Open
Description
Example:
// transaction-test.js
// Run with: node transaction-test.js
import { createCollection, createTransaction } from '@tanstack/db';
import { localOnlyCollectionOptions } from '@tanstack/db';
console.log('🧪 Starting TanStack DB LocalOnly Transaction Test\n');
const testCollection = createCollection(
localOnlyCollectionOptions({
id: 'test-collection',
getKey: (item) => item.id,
initialData: [
{ id: 'initial1', name: 'Initial Item 1', value: 100 },
{ id: 'initial2', name: 'Initial Item 2', value: 200 },
],
onInsert: async ({ transaction }) => {
const inserted = transaction.mutations[0].modified;
console.log(' 📦 onInsert triggered:', inserted.name);
},
onUpdate: async ({ transaction }) => {
const { original, modified } = transaction.mutations[0];
console.log(
' 📦 onUpdate triggered:',
original.name,
'->',
modified.name
);
},
onDelete: async ({ transaction }) => {
const deleted = transaction.mutations[0].original;
console.log(' 📦 onDelete triggered:', deleted.name);
},
})
);
console.log('1️⃣ Initial collection state:');
console.log(' Array:', testCollection.toArray);
console.log(' Count:', testCollection.size, '\n');
// Test 1: Direct operations (should work fine)
console.log('2️⃣ Testing direct operations:');
testCollection.insert({ id: 'direct1', name: 'Direct Insert', value: 300 });
console.log(' After direct insert - Count:', testCollection.size);
console.log(' Inserted item:', testCollection.get('direct1'));
const firstItem = testCollection.toArray[0];
if (firstItem) {
testCollection.update(firstItem.id, (draft) => {
draft.name = 'Updated Direct';
draft.value = 999;
});
console.log(' After direct update - Count:', testCollection.size);
console.log(' Updated item:', testCollection.get(firstItem.id));
}
console.log();
// Test 2: Manual transaction
console.log('3️⃣ Testing manual transaction:');
console.log(' Before transaction - Count:', testCollection.size);
console.log(' Array:', testCollection.toArray);
const transaction = createTransaction({
autoCommit: false,
mutationFn: async ({ transaction }) => {
console.log(
' 🎯 Transaction mutationFn called with',
transaction.mutations.length,
'mutations'
);
},
});
console.log(' Creating transaction mutate block...');
transaction.mutate(() => {
console.log(' 🔄 Inside mutate block');
console.log('Inserting item tx1');
testCollection.insert({
id: 'tx1',
name: 'Transaction Insert 1',
value: 400,
});
console.log('Inserting item tx2');
testCollection.insert({
id: 'tx2',
name: 'Transaction Insert 2',
value: 500,
});
console.log('Updating item initial2');
const itemToUpdate = testCollection.get('initial2');
if (itemToUpdate) {
testCollection.update('initial2', (draft) => {
draft.name = 'Updated via Transaction';
draft.value = 777;
});
}
});
console.log(' Before commit - Count:', testCollection.size);
console.log(
' Items:',
testCollection.toArray.map((i) => ({ id: i.id, name: i.name }))
);
console.log(' Committing transaction...');
try {
await transaction.commit();
console.log(' ✅ Transaction committed successfully');
} catch (error) {
console.log(' ❌ Transaction commit failed:', error.message);
}
console.log(' After commit - Count:', testCollection.size);
console.log(
' Final items:',
testCollection.toArray.map((i) => ({
id: i.id,
name: i.name,
value: i.value,
}))
);
Output:
🧪 Starting TanStack DB LocalOnly Transaction Test
1️⃣ Initial collection state:
Array: [
{ id: 'initial1', name: 'Initial Item 1', value: 100 },
{ id: 'initial2', name: 'Initial Item 2', value: 200 }
]
Count: 2
2️⃣ Testing direct operations:
📦 onInsert triggered: Direct Insert
After direct insert - Count: 3
Inserted item: { id: 'direct1', name: 'Direct Insert', value: 300 }
📦 onUpdate triggered: Initial Item 1 -> Updated Direct
After direct update - Count: 3
Updated item: { id: 'initial1', name: 'Updated Direct', value: 999 }
3️⃣ Testing manual transaction:
Before transaction - Count: 3
Array: [
{ id: 'initial1', name: 'Updated Direct', value: 999 },
{ id: 'initial2', name: 'Initial Item 2', value: 200 },
{ id: 'direct1', name: 'Direct Insert', value: 300 }
]
Creating transaction mutate block...
🔄 Inside mutate block
Inserting item tx1
Inserting item tx2
Updating item initial2
Before commit - Count: 5
Items: [
{ id: 'initial1', name: 'Updated Direct' },
{ id: 'initial2', name: 'Updated via Transaction' },
{ id: 'direct1', name: 'Direct Insert' },
{ id: 'tx1', name: 'Transaction Insert 1' },
{ id: 'tx2', name: 'Transaction Insert 2' }
]
Committing transaction...
🎯 Transaction mutationFn called with 3 mutations
✅ Transaction committed successfully
After commit - Count: 3
Final items: [
{ id: 'initial1', name: 'Updated Direct', value: 999 },
{ id: 'initial2', name: 'Initial Item 2', value: 200 },
{ id: 'direct1', name: 'Direct Insert', value: 300 }
]
Expected behavior: Committing a transaction applies the changes as a batch update.
Actual behavior: Committing a transaction erases the changes.
Metadata
Metadata
Assignees
Labels
No labels