Skip to content

Commit

Permalink
(WIP) Adding renderType flag to prerendered search
Browse files Browse the repository at this point in the history
  • Loading branch information
FadhlanR committed Jan 24, 2025
1 parent 32a3e8a commit 9a78450
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 30 deletions.
1 change: 1 addition & 0 deletions packages/runtime-common/card-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ export function transformResultsToPrerenderedCardsDoc(results: {
id: card.url,
attributes: {
html: card.html,
usedRenderType: card.usedRenderType,
...(card.isError ? { isError: true as const } : {}),
},
}));
Expand Down
114 changes: 84 additions & 30 deletions packages/runtime-common/index-query-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
tableValuedFunctionsPlaceholder,
query,
isDbExpression,
Param,
} from './expression';
import {
type Query,
Expand Down Expand Up @@ -120,6 +121,7 @@ export type QueryOptions = WIPOptions & PrerenderedCardOptions;

interface PrerenderedCardOptions {
htmlFormat?: 'embedded' | 'fitted' | 'atom';
renderType?: ResolvedCodeRef;
includeErrors?: true;
cardUrls?: string[];
}
Expand All @@ -131,6 +133,7 @@ interface WIPOptions {
export interface PrerenderedCard {
url: string;
html: string | null;
usedRenderType: string;
isError?: true;
}

Expand Down Expand Up @@ -461,47 +464,35 @@ export class IndexQueryEngine {
);
}

let ref: ResolvedCodeRef;
let filterOnValue = filter && 'type' in filter ? filter.type : filter?.on;
if (filterOnValue) {
ref = filterOnValue as ResolvedCodeRef;
} else {
ref = baseCardRef;
}

let htmlColumnExpression;
switch (opts.htmlFormat) {
case 'embedded':
htmlColumnExpression = [
'embedded_html ->> ',
param(internalKeyFor(ref, undefined)),
];
break;
case 'fitted':
htmlColumnExpression = [
'fitted_html ->> ',
param(internalKeyFor(ref, undefined)),
];
break;
case 'atom':
default:
htmlColumnExpression = ['atom_html'];
break;
}
let htmlColumnExpression = this.buildHtmlColumnExpression({
htmlFormat: opts.htmlFormat,
renderType: opts.renderType,
});
let usedRenderTypeColumnExpression =
this.buildUsedRenderTypeColumnExpression({
htmlFormat: opts.htmlFormat,
renderType: opts.renderType,
});

let { results, meta } = (await this._search(
realmURL,
{ filter, sort, page },
loader,
opts,
[
'SELECT url, ANY_VALUE(i.type) as type, ANY_VALUE(file_alias) as file_alias, ANY_VALUE(',
'SELECT url, ANY_VALUE(i.type) as type, ANY_VALUE(file_alias) as file_alias, ',
...htmlColumnExpression,
') as html, ANY_VALUE(deps) as deps',
' as html,',
...usedRenderTypeColumnExpression,
' as used_render_type,',
'ANY_VALUE(deps) as deps',
],
)) as {
meta: QueryResultsMeta;
results: (Partial<BoxelIndexTable> & { html: string | null })[];
results: (Partial<BoxelIndexTable> & {
html: string | null;
used_render_type: string;
})[];
};

// We need a way to get scoped css urls even from cards linked from foreign realms.These are saved in the deps column of instances and modules.
Expand All @@ -521,13 +512,76 @@ export class IndexQueryEngine {
return {
url: card.url!,
html: card.html,
usedRenderType: card.used_render_type,
...(card.type === 'error' ? { isError: true as const } : {}),
};
});

return { prerenderedCards, scopedCssUrls: [...scopedCssUrls], meta };
}

private buildHtmlColumnExpression({
htmlFormat,
renderType,
}: {
htmlFormat: 'embedded' | 'fitted' | 'atom' | undefined;
renderType?: ResolvedCodeRef;
}): (string | Param)[] {
let fieldName = htmlFormat ? `${htmlFormat}_html` : `atom_html`;
if (!htmlFormat || htmlFormat === 'atom') {
return [fieldName];
}

let htmlColumnExpression = [];
htmlColumnExpression.push('COALESCE(');
if (renderType) {
htmlColumnExpression.push(`${fieldName} ->> `);
htmlColumnExpression.push(param(internalKeyFor(renderType, undefined)));
htmlColumnExpression.push(',');
}

htmlColumnExpression.push(`(
CASE
WHEN ANY_VALUE(${fieldName}) IS NOT NULL
AND jsonb_typeof(ANY_VALUE(${fieldName})) = 'object'
THEN (
SELECT value
FROM jsonb_each_text(ANY_VALUE(${fieldName}))
WHERE key = (
SELECT replace(ANY_VALUE(types[1]::text), '"', '')
))
ELSE NULL
END),
NULL)`);

return htmlColumnExpression;
}

private buildUsedRenderTypeColumnExpression({
htmlFormat,
renderType,
}: {
htmlFormat: 'embedded' | 'fitted' | 'atom' | undefined;
renderType?: ResolvedCodeRef;
}): (string | Param)[] {
let fieldName = htmlFormat ? `${htmlFormat}_html` : `atom_html`;

let usedRenderTypeColumnExpression = [];
if (htmlFormat && htmlFormat !== 'atom' && renderType) {
usedRenderTypeColumnExpression.push(`CASE`);
usedRenderTypeColumnExpression.push(`WHEN ${fieldName} ->> `);
usedRenderTypeColumnExpression.push(
param(internalKeyFor(renderType, undefined)),
);
usedRenderTypeColumnExpression.push(`IS NOT NULL THEN ${renderType}`);
usedRenderTypeColumnExpression.push(`ELSE ANY_VALUE(types[1]) END`);
} else {
usedRenderTypeColumnExpression.push('ANY_VALUE(types[1])');
}

return usedRenderTypeColumnExpression;
}

async fetchCardTypeSummary(realmURL: URL): Promise<CardTypeSummary[]> {
let results = (await this.#query([
`SELECT value
Expand Down
3 changes: 3 additions & 0 deletions packages/runtime-common/realm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
type QueuePublisher,
type FileMeta,
type DirectoryMeta,
type ResolvedCodeRef,
} from './index';
import merge from 'lodash/merge';
import mergeWith from 'lodash/mergeWith';
Expand Down Expand Up @@ -1645,6 +1646,7 @@ export class Realm {
let parsedQueryString = parseQuery(href);
let htmlFormat = parsedQueryString.prerenderedHtmlFormat as string;
let cardUrls = parsedQueryString.cardUrls as string[];
let renderType = parsedQueryString.renderType as ResolvedCodeRef;

if (!isValidPrerenderedHtmlFormat(htmlFormat)) {
return badRequest(
Expand All @@ -1669,6 +1671,7 @@ export class Realm {
useWorkInProgressIndex,
htmlFormat,
cardUrls,
renderType,
includeErrors: true,
},
);
Expand Down

0 comments on commit 9a78450

Please sign in to comment.