@@ -14,6 +14,7 @@ import predefinedSelections, {
1414import { DEFAULT_RETURN_NODE } from "./parseQuery" ;
1515import { DiscourseNode } from "./getDiscourseNodes" ;
1616import { DiscourseRelation } from "./getDiscourseRelations" ;
17+ import type { json } from "./getBlockProps" ;
1718import nanoid from "nanoid" ;
1819
1920export type QueryArgs = {
@@ -30,6 +31,7 @@ type RelationInQuery = {
3031export type FireQueryArgs = QueryArgs & {
3132 isCustomEnabled ?: boolean ;
3233 customNode ?: string ;
34+ local ?: boolean ;
3335 context ?: {
3436 relationsInQuery ?: RelationInQuery [ ] ;
3537 customNodes ?: DiscourseNode [ ] ;
@@ -315,8 +317,10 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
315317 } ) ) ;
316318} ;
317319
320+ const PROP_NAME_RE = new RegExp ( / \: \w + \/ \w + \b / , "g" ) ;
321+
318322const fireQuery : FireQuery = async ( _args ) => {
319- const { isCustomEnabled, customNode, ...args } = _args ;
323+ const { isCustomEnabled, customNode, local , ...args } = _args ;
320324
321325 const { query, formatResult, inputs } = isCustomEnabled
322326 ? {
@@ -348,11 +352,42 @@ const fireQuery: FireQuery = async (_args) => {
348352 console . groupEnd ( ) ;
349353 }
350354
351- //@ts -ignore - todo add async q to roamjs-components
352- const queryResults = await window . roamAlphaAPI . data . backend . q (
353- query ,
354- ...inputs ,
355- ) ;
355+ let queryResults : unknown [ ] [ ] = [ ] ;
356+ console . log ( "local" , local ) ;
357+ if ( local ) {
358+ // look for propNames in query. Could consider looking only in pull when that exists.
359+ const propNames = new Set (
360+ [ ...query . matchAll ( PROP_NAME_RE ) ] . map ( ( m ) => m [ 0 ] ) ,
361+ ) ;
362+ const propNamesSub : Record < string , string > = Object . fromEntries (
363+ [ ...propNames ] . map ( ( n ) => [ n . split ( "/" ) [ 1 ] , n ] ) ,
364+ ) ;
365+ if ( Object . keys ( propNamesSub ) . length === propNames . size ) {
366+ // no name conflict, safe to use async query
367+ // BUT it returns non-namespaced names, so substitute prop names back
368+ queryResults = await window . roamAlphaAPI . data . async . q ( query , ...inputs ) ;
369+ const renameProps = ( x : json | null ) : json | null => {
370+ if ( Array . isArray ( x ) ) return x . map ( renameProps ) ;
371+ if ( x === null || x === undefined ) return x ;
372+ if ( typeof x === "object" ) {
373+ return Object . fromEntries (
374+ Object . entries ( x as object ) . map ( ( [ k , v ] ) => [
375+ propNamesSub [ k ] || k ,
376+ renameProps ( v ) , // eslint-disable-line @typescript-eslint/no-unsafe-argument
377+ ] ) ,
378+ ) ;
379+ }
380+ return x ;
381+ } ;
382+ queryResults = renameProps ( queryResults as json ) as unknown [ ] [ ] ;
383+ } else {
384+ // more janky but safer
385+ queryResults = window . roamAlphaAPI . data . fast . q ( query , ...inputs ) ;
386+ }
387+ } else {
388+ // eslint-disable-next-line @typescript-eslint/await-thenable
389+ queryResults = await window . roamAlphaAPI . data . backend . q ( query , ...inputs ) ; // ts-ignore
390+ }
356391
357392 if ( nodeEnv === "development" ) {
358393 console . timeEnd ( `Query - ${ queryId } ` ) ;
0 commit comments