@@ -107,13 +107,25 @@ function getCreateQuery(): Promise<CreateQuery> {
107107 } ) )
108108}
109109
110- export async function runQuery ( target : unknown , query : string , options ?: NormalizeOptions ) : Promise < QueryOutcome > {
110+ /**
111+ * Run the query against the target, select the node to return from its raw
112+ * result, and normalize that node into a wire-safe {@link QueryOutcome}.
113+ * The `select` step runs inside the timed section so re-descent costs (used
114+ * by {@link runQueryAtPath}) are reflected in `queryMs`.
115+ */
116+ async function executeQuery (
117+ target : unknown ,
118+ query : string ,
119+ options : NormalizeOptions | undefined ,
120+ select : ( raw : unknown ) => unknown ,
121+ ) : Promise < QueryOutcome > {
111122 try {
112123 const started = performance . now ( )
113124 const createQuery = await getCreateQuery ( )
114125 const raw = createQuery ( query ) ( target )
126+ const node = select ( raw )
115127 const queryMs = Math . round ( ( performance . now ( ) - started ) * 100 ) / 100
116- const { data, stats } = normalize ( raw , options )
128+ const { data, stats } = normalize ( node , options )
117129 // The normalizer guarantees plain JSON, so this measures the actual wire payload.
118130 const payloadBytes = new TextEncoder ( ) . encode ( JSON . stringify ( data ) ?? '' ) . length
119131 return { ok : true , result : data , stats : { queryMs, normalize : stats , payloadBytes } }
@@ -124,28 +136,19 @@ export async function runQuery(target: unknown, query: string, options?: Normali
124136 }
125137}
126138
139+ export function runQuery ( target : unknown , query : string , options ?: NormalizeOptions ) : Promise < QueryOutcome > {
140+ return executeQuery ( target , query , options , raw => raw )
141+ }
142+
127143/**
128144 * Lazy-expand a depth-truncated node: re-run the base query against the live
129145 * object, re-descend to the node the `NodePath` addresses, and normalize just
130146 * that subtree with a fresh depth budget. The path comes from a `$truncated:
131147 * 'depth'` marker the client is expanding, so the same filter options must be
132148 * threaded through (they shift array indices and drop keys).
133149 */
134- export async function runQueryAtPath ( target : unknown , query : string , path : NodePath , options ?: NormalizeOptions ) : Promise < QueryOutcome > {
135- try {
136- const started = performance . now ( )
137- const createQuery = await getCreateQuery ( )
138- const raw = createQuery ( query ) ( target )
139- const node = navigate ( raw , path , options )
140- const queryMs = Math . round ( ( performance . now ( ) - started ) * 100 ) / 100
141- const { data, stats } = normalize ( node , options )
142- const payloadBytes = new TextEncoder ( ) . encode ( JSON . stringify ( data ) ?? '' ) . length
143- return { ok : true , result : data , stats : { queryMs, normalize : stats , payloadBytes } }
144- }
145- catch ( error ) {
146- const e = error instanceof Error ? error : new Error ( String ( error ) )
147- return { ok : false , error : { message : e . message , name : e . name } }
148- }
150+ export function runQueryAtPath ( target : unknown , query : string , path : NodePath , options ?: NormalizeOptions ) : Promise < QueryOutcome > {
151+ return executeQuery ( target , query , options , raw => navigate ( raw , path , options ) )
149152}
150153
151154interface JoraStatEntry {
0 commit comments