@@ -24,10 +24,20 @@ export async function runCursorQuery(db, table, conditions, queryAdditions, yiel
2424 ) ;
2525
2626 if ( requiresMetaProcessing ) {
27- // **Metadata Path: Extract primary keys and sorting properties**
28- let primaryKeyList = await runMetaDataCursorQuery ( db , table , structuredPredicateTree , queryAdditions , yieldedPrimaryKeys , compoundKeys ) ;
2927
30- const indexOrderProps = detectIndexOrderProperties ( structuredPredicateTree , table ) ;
28+ let stableOrdering = hasStableOrdering ( queryAdditions ) ;
29+
30+ let indexOrderProps = [ ] ;
31+
32+ if ( ! stableOrdering ) {
33+ indexOrderProps = detectIndexOrderProperties ( structuredPredicateTree , table ) ;
34+ }
35+ else {
36+ debugLog ( "Stable Ordering detected. Disabling any ordering by indexed queries." ) ;
37+ }
38+
39+ // **Metadata Path: Extract primary keys and sorting properties**
40+ let primaryKeyList = await runMetaDataCursorQuery ( db , table , structuredPredicateTree , queryAdditions , yieldedPrimaryKeys , compoundKeys , indexOrderProps ) ;
3141
3242 // **Apply sorting, take, and skip operations**
3343 let finalPrimaryKeys = applyCursorQueryAdditions ( primaryKeyList , queryAdditions , compoundKeys , true , indexOrderProps ) ;
@@ -43,6 +53,11 @@ export async function runCursorQuery(db, table, conditions, queryAdditions, yiel
4353 }
4454}
4555
56+ function hasStableOrdering ( queryAdditions ) {
57+ return queryAdditions ?. some ( q => q . additionFunction === QUERY_ADDITIONS . STABLE_ORDERING ) ;
58+ }
59+
60+
4661function detectIndexOrderProperties ( predicateTree , table ) {
4762 const indexedProps = new Set ( ) ;
4863
@@ -183,7 +198,7 @@ function optimizeSingleCondition(condition) {
183198 // Lowercase normalization for string values if not case-sensitive
184199 if ( ! condition . caseSensitive && typeof condition . value === "string" ) {
185200 optimized . value = condition . value . toLowerCase ( ) ;
186- }
201+ }
187202
188203 optimized . comparisonFunction = getComparisonFunction ( condition . operation ) ;
189204 return optimized ;
@@ -226,7 +241,7 @@ async function runDirectCursorQuery(db, table, conditions, yieldedPrimaryKeys, c
226241/**
227242 * Extracts only necessary metadata using a Dexie cursor in a transaction.
228243 */
229- async function runMetaDataCursorQuery ( db , table , conditions , queryAdditions , yieldedPrimaryKeys , compoundKeys ) {
244+ async function runMetaDataCursorQuery ( db , table , conditions , queryAdditions , yieldedPrimaryKeys , compoundKeys , detectedIndexOrderProperties = [ ] ) {
230245 debugLog ( "Extracting Metadata for Cursor Query" , { conditions, queryAdditions } ) ;
231246
232247 let requiredProperties = new Set ( ) ;
@@ -252,6 +267,12 @@ async function runMetaDataCursorQuery(db, table, conditions, queryAdditions, yie
252267 requiredProperties . add ( key ) ;
253268 }
254269
270+ // Include all indexable props that affect ordering
271+ for ( const prop of detectedIndexOrderProperties ) {
272+ requiredProperties . add ( prop ) ;
273+ }
274+
275+
255276 requiredProperties . add ( "_MagicOrderId" ) ;
256277
257278 let estimatedSize = await table . count ( ) ;
@@ -820,6 +841,9 @@ function applyCursorQueryAdditions(
820841 primaryKeyList = primaryKeyList . length > 0 ? [ primaryKeyList [ primaryKeyList . length - 1 ] ] : [ ] ;
821842 break ;
822843
844+ case QUERY_ADDITIONS . STABLE_ORDERING :
845+ break ; // skip this
846+
823847 default :
824848 throw new Error ( `Unsupported query addition: ${ addition . additionFunction } ` ) ;
825849 }
0 commit comments