@@ -144,6 +144,7 @@ export function useResultsLiveQuery(options: {
144144
145145function normalizeResult (
146146 result : ResultMinified | SnapshotResult < Mode > ,
147+ knownTagIds ?: Set < string > ,
147148) : SnapshotResult < Mode > {
148149 const resultDate = new Date ( result . timestamp ) ;
149150 resultDate . setSeconds ( 0 ) ;
@@ -168,6 +169,9 @@ function normalizeResult(
168169 result . incompleteTestSeconds ??= 0 ;
169170 result . afkDuration ??= 0 ;
170171 result . tags ??= [ ] ;
172+ if ( knownTagIds !== undefined ) {
173+ result . tags = result . tags . filter ( ( tagId ) => knownTagIds . has ( tagId ) ) ;
174+ }
171175 result . isPb ??= false ;
172176 return {
173177 ...result ,
@@ -190,6 +194,7 @@ export const resultsCollection = createCollection(
190194 staleTime : Infinity ,
191195 queryKey : queryKeys . root ( ) ,
192196 queryFn : async ( ) => {
197+ const knownTagIds = new Set ( getSnapshot ( ) ?. tags . map ( ( it ) => it . _id ) ) ;
193198 //const options = parseLoadSubsetOptions(ctx.meta?.loadSubsetOptions);
194199
195200 const response = await Ape . results . get ( {
@@ -200,7 +205,9 @@ export const resultsCollection = createCollection(
200205 throw new Error ( "Error fetching results:" + response . body . message ) ;
201206 }
202207
203- return response . body . data . map ( ( result ) => normalizeResult ( result ) ) ;
208+ return response . body . data . map ( ( result ) =>
209+ normalizeResult ( result , knownTagIds ) ,
210+ ) ;
204211 } ,
205212 onInsert : async ( { transaction } ) => {
206213 //call to the backend to post a result is done outside, we just insert the result as we get it
@@ -215,6 +222,17 @@ export const resultsCollection = createCollection(
215222 //do not refetch after insert
216223 return { refetch : false } ;
217224 } ,
225+ onUpdate : async ( { transaction } ) => {
226+ const updates = transaction . mutations . map ( ( m ) => m . modified ) ;
227+
228+ resultsCollection . utils . writeBatch ( ( ) => {
229+ updates . forEach ( ( item ) => {
230+ resultsCollection . utils . writeUpdate ( normalizeResult ( item ) ) ;
231+ } ) ;
232+ } ) ;
233+ //we don't sync local changes back
234+ return { refetch : false } ;
235+ } ,
218236 queryClient,
219237 getKey : ( it ) => it . _id ,
220238 } ) ,
@@ -377,34 +395,30 @@ export const getSingleResultQueryOptions = (_id: string) =>
377395 staleTime : Infinity ,
378396 } ) ;
379397
380- export async function getUserAverage < M extends Mode > (
381- options : {
382- mode : M ;
383- mode2 : Mode2 < M > ;
384- punctuation : boolean ;
385- numbers : boolean ;
386- language : string ;
387- difficulty : Difficulty ;
388- lazyMode : boolean ;
389- } & ExactlyOneTrue < {
390- last10Only : boolean ;
391- lastDayOnly : boolean ;
392- } > ,
398+ export type CurrentSettingsFilter = {
399+ mode : Mode ;
400+ mode2 : Mode2 < Mode > ;
401+ punctuation : boolean ;
402+ numbers : boolean ;
403+ language : string ;
404+ difficulty : Difficulty ;
405+ lazyMode : boolean ;
406+ } ;
407+
408+ export async function getUserAverage (
409+ options : CurrentSettingsFilter &
410+ ExactlyOneTrue < {
411+ last10Only : boolean ;
412+ lastDayOnly : boolean ;
413+ } > ,
393414) : Promise < { wpm : number ; acc : number } > {
394415 const activeTagIds = getSnapshot ( )
395416 ?. tags . filter ( ( it ) => it . active === true )
396417 . map ( ( it ) => it . _id ) ;
397418
398419 const result = await createLiveQueryCollection ( ( q ) => {
399420 let query = q
400- . from ( { r : resultsCollection } )
401- . where ( ( { r } ) => eq ( r . mode , options . mode ) )
402- . where ( ( { r } ) => eq ( r . mode2 , options . mode2 ) )
403- . where ( ( { r } ) => eq ( r . punctuation , options . punctuation ) )
404- . where ( ( { r } ) => eq ( r . numbers , options . numbers ) )
405- . where ( ( { r } ) => eq ( r . language , options . language ) )
406- . where ( ( { r } ) => eq ( r . difficulty , options . difficulty ) )
407- . where ( ( { r } ) => eq ( r . lazyMode , options . lazyMode ) )
421+ . from ( { r : buildSettingsResultsQuery ( options ) } )
408422 . where ( ( { r } ) =>
409423 or (
410424 false ,
@@ -427,3 +441,44 @@ export async function getUserAverage<M extends Mode>(
427441 ? result [ 0 ]
428442 : { wpm : 0 , acc : 0 } ;
429443}
444+
445+ export async function findFastestResultByTagId (
446+ options : CurrentSettingsFilter & { tagId : string } ,
447+ ) : Promise < SnapshotResult < Mode > | undefined > {
448+ const result = await createLiveQueryCollection ( ( q ) =>
449+ q
450+ . from ( { r : buildSettingsResultsQuery ( options ) } )
451+ . orderBy ( ( { r } ) => r . wpm , "desc" )
452+ . limit ( 1 )
453+ . findOne ( ) ,
454+ ) . toArrayWhenReady ( ) ;
455+ return result . length === 1 || result [ 0 ] !== undefined
456+ ? ( result [ 0 ] as SnapshotResult < Mode > )
457+ : undefined ;
458+ }
459+
460+ // oxlint-disable-next-line typescript/explicit-function-return-type
461+ function buildSettingsResultsQuery ( filter : CurrentSettingsFilter ) {
462+ return new Query ( )
463+ . from ( { r : resultsCollection } )
464+ . where ( ( { r } ) => eq ( r . mode , filter . mode ) )
465+ . where ( ( { r } ) => eq ( r . mode2 , filter . mode2 ) )
466+ . where ( ( { r } ) => eq ( r . punctuation , filter . punctuation ) )
467+ . where ( ( { r } ) => eq ( r . numbers , filter . numbers ) )
468+ . where ( ( { r } ) => eq ( r . language , filter . language ) )
469+ . where ( ( { r } ) => eq ( r . difficulty , filter . difficulty ) )
470+ . where ( ( { r } ) => eq ( r . lazyMode , filter . lazyMode ) ) ;
471+ }
472+
473+ export function deleteLocalTag ( tagId : string ) : void {
474+ for ( const result of resultsCollection . values ( ) ) {
475+ const tagIndex = result . tags . indexOf ( tagId ) ;
476+ if ( tagIndex > - 1 ) {
477+ resultsCollection . update ( result . _id , ( old ) => {
478+ const tags = result . tags ;
479+ tags . splice ( tagIndex , 1 ) ;
480+ old . tags = tags ;
481+ } ) ;
482+ }
483+ }
484+ }
0 commit comments