@@ -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 [ ] ;
@@ -314,8 +316,10 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
314316 } ) ) ;
315317} ;
316318
319+ const PROP_NAME_RE = new RegExp ( / \: \w + \/ \w + \b / , "g" ) ;
320+
317321const fireQuery : FireQuery = async ( _args ) => {
318- const { isCustomEnabled, customNode, ...args } = _args ;
322+ const { isCustomEnabled, customNode, local , ...args } = _args ;
319323
320324 const { query, formatResult, inputs } = isCustomEnabled
321325 ? {
@@ -347,11 +351,42 @@ const fireQuery: FireQuery = async (_args) => {
347351 console . groupEnd ( ) ;
348352 }
349353
350- //@ts -ignore - todo add async q to roamjs-components
351- const queryResults = await window . roamAlphaAPI . data . backend . q (
352- query ,
353- ...inputs ,
354- ) ;
354+ let queryResults : unknown [ ] [ ] = [ ] ;
355+ console . log ( "local" , local ) ;
356+ if ( local ) {
357+ // look for propNames in query. Could consider looking only in pull when that exists.
358+ const propNames = new Set (
359+ [ ...query . matchAll ( PROP_NAME_RE ) ] . map ( ( m ) => m [ 0 ] ) ,
360+ ) ;
361+ const propNamesSub : Record < string , string > = Object . fromEntries (
362+ [ ...propNames ] . map ( ( n ) => [ n . split ( "/" ) [ 1 ] , n ] ) ,
363+ ) ;
364+ if ( Object . keys ( propNamesSub ) . length === propNames . size ) {
365+ // no name conflict, safe to use async query
366+ // BUT it returns non-namespaced names, so substitute prop names back
367+ queryResults = await window . roamAlphaAPI . data . async . q ( query , ...inputs ) ;
368+ const renameProps = ( x : json | null ) : json | null => {
369+ if ( Array . isArray ( x ) ) return x . map ( renameProps ) ;
370+ if ( x === null || x === undefined ) return x ;
371+ if ( typeof x === "object" ) {
372+ return Object . fromEntries (
373+ Object . entries ( x as object ) . map ( ( [ k , v ] ) => [
374+ propNamesSub [ k ] || k ,
375+ renameProps ( v ) , // eslint-disable-line @typescript-eslint/no-unsafe-argument
376+ ] ) ,
377+ ) ;
378+ }
379+ return x ;
380+ } ;
381+ queryResults = renameProps ( queryResults as json ) as unknown [ ] [ ] ;
382+ } else {
383+ // more janky but safer
384+ queryResults = window . roamAlphaAPI . data . fast . q ( query , ...inputs ) ;
385+ }
386+ } else {
387+ // eslint-disable-next-line @typescript-eslint/await-thenable
388+ queryResults = await window . roamAlphaAPI . data . backend . q ( query , ...inputs ) ; // ts-ignore
389+ }
355390
356391 if ( nodeEnv === "development" ) {
357392 console . timeEnd ( `Query - ${ queryId } ` ) ;
0 commit comments