@@ -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 [ ] ;
@@ -303,8 +305,10 @@ export const fireQuerySync = (args: FireQueryArgs): QueryResult[] => {
303305 } ) ) ;
304306} ;
305307
308+ const PROP_NAME_RE = new RegExp ( / \: \w + \/ \w + \b / , "g" ) ;
309+
306310const fireQuery : FireQuery = async ( _args ) => {
307- const { isCustomEnabled, customNode, ...args } = _args ;
311+ const { isCustomEnabled, customNode, local , ...args } = _args ;
308312
309313 const { query, formatResult, inputs } = isCustomEnabled
310314 ? {
@@ -336,11 +340,42 @@ const fireQuery: FireQuery = async (_args) => {
336340 console . groupEnd ( ) ;
337341 }
338342
339- //@ts -ignore - todo add async q to roamjs-components
340- const queryResults = await window . roamAlphaAPI . data . backend . q (
341- query ,
342- ...inputs ,
343- ) ;
343+ let queryResults : unknown [ ] [ ] = [ ] ;
344+ console . log ( "local" , local ) ;
345+ if ( local ) {
346+ // look for propNames in query. Could consider looking only in pull when that exists.
347+ const propNames = new Set (
348+ [ ...query . matchAll ( PROP_NAME_RE ) ] . map ( ( m ) => m [ 0 ] ) ,
349+ ) ;
350+ const propNamesSub : Record < string , string > = Object . fromEntries (
351+ [ ...propNames ] . map ( ( n ) => [ n . split ( "/" ) [ 1 ] , n ] ) ,
352+ ) ;
353+ if ( Object . keys ( propNamesSub ) . length === propNames . size ) {
354+ // no name conflict, safe to use async query
355+ // BUT it returns non-namespaced names, so substitute prop names back
356+ queryResults = await window . roamAlphaAPI . data . async . q ( query , ...inputs ) ;
357+ const renameProps = ( x : json | null ) : json | null => {
358+ if ( Array . isArray ( x ) ) return x . map ( renameProps ) ;
359+ if ( x === null || x === undefined ) return x ;
360+ if ( typeof x === "object" ) {
361+ return Object . fromEntries (
362+ Object . entries ( x as object ) . map ( ( [ k , v ] ) => [
363+ propNamesSub [ k ] || k ,
364+ renameProps ( v ) , // eslint-disable-line @typescript-eslint/no-unsafe-argument
365+ ] ) ,
366+ ) ;
367+ }
368+ return x ;
369+ } ;
370+ queryResults = renameProps ( queryResults as json ) as unknown [ ] [ ] ;
371+ } else {
372+ // more janky but safer
373+ queryResults = window . roamAlphaAPI . data . fast . q ( query , ...inputs ) ;
374+ }
375+ } else {
376+ // eslint-disable-next-line @typescript-eslint/await-thenable
377+ queryResults = await window . roamAlphaAPI . data . backend . q ( query , ...inputs ) ; // ts-ignore
378+ }
344379
345380 if ( nodeEnv === "development" ) {
346381 console . timeEnd ( `Query - ${ queryId } ` ) ;
0 commit comments