@@ -316,7 +316,8 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
316316 } ) ) ;
317317} ;
318318
319- const PROP_NAME_RE = / : \w + \/ \w + \b / g;
319+ const PROP_NAME_RE = / : [ a - z A - Z 0 - 9 _ - ] + \/ [ a - z A - Z 0 - 9 _ - ] + \b / g;
320+ const PULL_RE = / \( p u l l [ ^ ) ] + \) / g;
320321
321322const renamePropsInResult = (
322323 result : json | null ,
@@ -372,25 +373,44 @@ const fireQuery: FireQuery = async (_args) => {
372373 }
373374
374375 let queryResults : unknown [ ] [ ] = [ ] ;
376+ // for now assume fast results are equivalent to slow.
377+ // We have seen some errors in (fast) backend queries, but not so far in local fast ones.
378+ const preferSlow = false ;
375379 if ( local ) {
376- // look for propNames in query. Could consider looking only in pull when that exists.
377- const propNames = new Set (
378- [ ...query . matchAll ( PROP_NAME_RE ) ] . map ( ( m ) => m [ 0 ] ) ,
379- ) ;
380- const propNamesSub : Record < string , string > = Object . fromEntries (
381- [ ...propNames ] . map ( ( n ) => [ n . split ( "/" ) [ 1 ] , n ] ) ,
382- ) ;
383- if ( Object . keys ( propNamesSub ) . length === propNames . size ) {
380+ let useSlow = preferSlow ;
381+ let propNamesSub : Record < string , string > | undefined ;
382+ if ( preferSlow ) {
383+ // keeping this code in case it turns out the fast results are more fragile than the slow ones
384+ // TODO: Remove when we have a more comprehensive test suite.
385+ const pulls = [ ...query . matchAll ( PULL_RE ) ] . map ( ( r ) => r [ 0 ] ) ;
386+ if ( pulls . length > 0 ) {
387+ // pull in base async query (vs fast or backend) returns non-namespaced names,
388+ // so there are a few possibilities of conflict,
389+ // namely: {log,version,window}/id; {graph,user}/settings; {block,user}/uid; {create,edit}/time
390+ // So look for collisions in property names in pull part of query.
391+ const propNames = new Set (
392+ [ ...pulls . join ( " " ) . matchAll ( PROP_NAME_RE ) ] . map ( ( m ) => m [ 0 ] ) ,
393+ ) ;
394+ propNamesSub = Object . fromEntries (
395+ [ ...propNames ] . map ( ( n ) => [ n . split ( "/" ) [ 1 ] , n ] ) ,
396+ ) ;
397+ useSlow = Object . keys ( propNamesSub ) . length === propNames . size ;
398+ }
399+ }
400+ if ( useSlow ) {
384401 // no name conflict, safe to use async query
385402 // BUT it returns non-namespaced names, so substitute prop names back
386403 queryResults = await window . roamAlphaAPI . data . async . q ( query , ...inputs ) ;
387- queryResults = renamePropsInResult (
388- queryResults as json ,
389- propNamesSub ,
390- ) as unknown [ ] [ ] ;
404+ if ( propNamesSub !== undefined )
405+ queryResults = renamePropsInResult (
406+ queryResults as json ,
407+ propNamesSub ,
408+ ) as unknown [ ] [ ] ;
391409 } else {
392- // more janky but safer
393- queryResults = window . roamAlphaAPI . data . fast . q ( query , ...inputs ) ;
410+ queryResults = await window . roamAlphaAPI . data . async . fast . q (
411+ query ,
412+ ...inputs ,
413+ ) ;
394414 }
395415 } else {
396416 queryResults = await window . roamAlphaAPI . data . backend . q ( query , ...inputs ) ;
0 commit comments