@adminide-stack/yantra-mobile 12.0.131 → 12.0.132-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/CustomDrawer.js +2 -2
- package/lib/components/CustomDrawer.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +7 -1
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/nativeSurfaceTwin.js +35 -0
- package/lib/features/apps/nativeSurfaceTwin.js.map +1 -0
- package/lib/features/canvas/CanvasBoardsGrid.js +49 -49
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +69 -28
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/audioEditor/AudioWaveform.js +1 -1
- package/lib/features/canvas/designCatalog.js +63 -39
- package/lib/features/canvas/designCatalog.js.map +1 -1
- package/lib/features/canvas/designCategories.js +56 -0
- package/lib/features/canvas/designCategories.js.map +1 -1
- package/lib/features/canvas/generator/DirectorSheet.js +3 -2
- package/lib/features/canvas/generator/DirectorSheet.js.map +1 -1
- package/lib/features/canvas/home/HeroComposer.js +165 -76
- package/lib/features/canvas/home/HeroComposer.js.map +1 -1
- package/lib/features/canvas/home/HeroMonitor.js +75 -46
- package/lib/features/canvas/home/HeroMonitor.js.map +1 -1
- package/lib/features/canvas/home/TemplatesGallery.js +273 -138
- package/lib/features/canvas/home/TemplatesGallery.js.map +1 -1
- package/lib/features/canvas/home/templatesGallerySources.js +221 -0
- package/lib/features/canvas/home/templatesGallerySources.js.map +1 -0
- package/lib/features/canvas/homeWork.js +12 -11
- package/lib/features/canvas/homeWork.js.map +1 -1
- package/lib/features/canvas/lazyEditors.js +51 -0
- package/lib/features/canvas/lazyEditors.js.map +1 -0
- package/lib/features/canvas/rankedCatalogSearch.js +33 -23
- package/lib/features/canvas/rankedCatalogSearch.js.map +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js +1 -1
- package/lib/features/canvas/set/agent/tools.js +1 -1
- package/lib/features/canvas/studioCatalog.js +2 -2
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/templateSearch.js +8 -1
- package/lib/features/canvas/templateSearch.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +1 -1
- package/lib/features/design/DesignEditorExperience.js +103 -29
- package/lib/features/design/DesignEditorExperience.js.map +1 -1
- package/lib/features/design/DesignExperience.js +4 -3
- package/lib/features/design/DesignExperience.js.map +1 -1
- package/lib/features/design/doc/aiDesign.js +1 -1
- package/lib/features/design/doc/aiDesign.js.map +1 -1
- package/lib/features/design/doc/artifacts.js +40 -13
- package/lib/features/design/doc/artifacts.js.map +1 -1
- package/lib/features/design/doc/chart.js +387 -13
- package/lib/features/design/doc/chart.js.map +1 -1
- package/lib/features/design/doc/copyStyle.js +47 -0
- package/lib/features/design/doc/copyStyle.js.map +1 -0
- package/lib/features/design/doc/docOps.js +22 -4
- package/lib/features/design/doc/docOps.js.map +1 -1
- package/lib/features/design/doc/geometry.js +32 -18
- package/lib/features/design/doc/geometry.js.map +1 -1
- package/lib/features/design/doc/newDoc.js +5 -1
- package/lib/features/design/doc/newDoc.js.map +1 -1
- package/lib/features/design/doc/resize.js +101 -0
- package/lib/features/design/doc/resize.js.map +1 -0
- package/lib/features/design/doc/sizes.js +15 -2
- package/lib/features/design/doc/sizes.js.map +1 -1
- package/lib/features/design/editor/ChartDataPanel.js +49 -9
- package/lib/features/design/editor/ChartDataPanel.js.map +1 -1
- package/lib/features/design/editor/CropOverlay.js +1 -1
- package/lib/features/design/editor/DesignCanvas.js +14 -13
- package/lib/features/design/editor/DesignCanvas.js.map +1 -1
- package/lib/features/design/editor/ExportSheet.js +8 -4
- package/lib/features/design/editor/ExportSheet.js.map +1 -1
- package/lib/features/design/editor/LayerTools.js +37 -5
- package/lib/features/design/editor/LayerTools.js.map +1 -1
- package/lib/features/design/editor/Slideshow.js +30 -5
- package/lib/features/design/editor/Slideshow.js.map +1 -1
- package/lib/features/design/editor/useDesignSave.js +21 -36
- package/lib/features/design/editor/useDesignSave.js.map +1 -1
- package/lib/features/design/export/exportDesign.js +3 -1
- package/lib/features/design/export/exportDesign.js.map +1 -1
- package/lib/features/design/home/DesignHome.js +7 -2
- package/lib/features/design/home/DesignHome.js.map +1 -1
- package/lib/features/design/render/DesignPageView.js +1 -1
- package/lib/features/design/render/DesignPageView.js.map +1 -1
- package/lib/features/design/render/PageCapture.js +11 -10
- package/lib/features/design/render/PageCapture.js.map +1 -1
- package/lib/features/design/render/fontRegistry.js +27 -3
- package/lib/features/design/render/fontRegistry.js.map +1 -1
- package/lib/features/design/render/svgParts.js +27 -74
- package/lib/features/design/render/svgParts.js.map +1 -1
- package/lib/features/devices/brands/qnScale.js +7 -2
- package/lib/features/devices/brands/qnScale.js.map +1 -1
- package/lib/features/devices/brands/uuids.js +2 -1
- package/lib/features/devices/brands/uuids.js.map +1 -1
- package/lib/features/devices/devices.js +2 -1
- package/lib/features/devices/devices.js.map +1 -1
- package/lib/features/docs/DocBlockRow.js +1 -1
- package/lib/features/docs/docArtifacts.js +2 -2
- package/lib/features/docs/docArtifacts.js.map +1 -1
- package/lib/features/health/healthSync.js +3 -1
- package/lib/features/health/healthSync.js.map +1 -1
- package/lib/features/health/nativeHealth.js +8 -0
- package/lib/features/health/nativeHealth.js.map +1 -0
- package/lib/features/links/openInApp.js +11 -1
- package/lib/features/links/openInApp.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +135 -28
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +14 -6
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewFrame.js +28 -3
- package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectChat.js +24 -5
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectsScreen.js +18 -2
- package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ui.js +20 -6
- package/lib/features/webbuilder/components/ui.js.map +1 -1
- package/lib/features/webbuilder/exportCode.js +52 -0
- package/lib/features/webbuilder/exportCode.js.map +1 -0
- package/lib/features/webbuilder/siteAddress.js +71 -0
- package/lib/features/webbuilder/siteAddress.js.map +1 -0
- package/lib/features/webbuilder/widgetBlocks.js +30 -0
- package/lib/features/webbuilder/widgetBlocks.js.map +1 -0
- package/lib/screens/Chat/index.js +5 -6
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatHistory/index.js +3 -2
- package/lib/screens/ChatHistory/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +20 -4
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js +18 -0
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js.map +1 -0
- package/lib/screens/WebBuilderNative/index.js +1 -1
- package/lib/screens/WebBuilderNative/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/keepAlive.js +112 -0
- package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js +40 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +57 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +73 -14
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +143 -34
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +17 -5
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
- package/lib/screens/WebBuilderNative/versionUndo.js +144 -0
- package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +90 -6
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
- package/package.json +4 -4
|
@@ -313,30 +313,41 @@ async function rankedCatalogSearch(params) {
|
|
|
313
313
|
}
|
|
314
314
|
return popularPage(offset >= POPULAR_OFFSET ? offset - POPULAR_OFFSET : 0, s.names, true);
|
|
315
315
|
}
|
|
316
|
+
const MAX_MATCH_READS = 4;
|
|
316
317
|
async function matchesPage(query, session, offset, limit, read, fieldsOf, accept) {
|
|
317
|
-
var _a;
|
|
318
|
-
const slice = session.candidates.slice(offset, offset + limit);
|
|
319
|
-
const rows = await readCatalogRowsByRef(slice, read);
|
|
318
|
+
var _a, _b;
|
|
320
319
|
const listed = [];
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
320
|
+
let end = offset;
|
|
321
|
+
let reads = 0;
|
|
322
|
+
while (listed.length < limit && end < session.candidates.length && reads < MAX_MATCH_READS) {
|
|
323
|
+
reads += 1;
|
|
324
|
+
const slice = session.candidates.slice(end, end + Math.min(MAX_ROWS_PER_READ, limit));
|
|
325
|
+
const rows = await readCatalogRowsByRef(slice, read);
|
|
326
|
+
let used = slice.length;
|
|
327
|
+
for (const [i, candidate] of slice.entries()) {
|
|
328
|
+
const row = rows.get(candidate.name);
|
|
329
|
+
if (!row || !accept(row, candidate.group)) continue;
|
|
330
|
+
const whole = scoreTemplate(query, templateSearchText(fieldsOf(row, candidate.group)));
|
|
331
|
+
const match = (_a = whole.match) != null ? _a : candidate.match;
|
|
332
|
+
const score = whole.match ? whole.score : candidate.score;
|
|
333
|
+
listed.push({
|
|
334
|
+
item: {
|
|
335
|
+
row,
|
|
336
|
+
group: candidate.group,
|
|
337
|
+
match
|
|
338
|
+
},
|
|
339
|
+
score,
|
|
340
|
+
order: end + i
|
|
341
|
+
});
|
|
342
|
+
if (listed.length === limit) {
|
|
343
|
+
used = i + 1;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
end += used;
|
|
348
|
+
}
|
|
338
349
|
listed.sort((a, b) => b.score - a.score || a.order - b.order);
|
|
339
|
-
let floor = (
|
|
350
|
+
let floor = (_b = session.floorAt.get(offset)) != null ? _b : "exact";
|
|
340
351
|
const items = listed.map(({
|
|
341
352
|
item
|
|
342
353
|
}) => {
|
|
@@ -346,7 +357,6 @@ async function matchesPage(query, session, offset, limit, read, fieldsOf, accept
|
|
|
346
357
|
floor = item.match;
|
|
347
358
|
return item;
|
|
348
359
|
});
|
|
349
|
-
const end = offset + slice.length;
|
|
350
360
|
session.floorAt.set(end, floor);
|
|
351
361
|
return {
|
|
352
362
|
rows: items,
|
|
@@ -372,4 +382,4 @@ function fetchCatalogRead(endpoint, token) {
|
|
|
372
382
|
if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);
|
|
373
383
|
return (_a = await res.json().catch(() => ({}))) != null ? _a : {};
|
|
374
384
|
};
|
|
375
|
-
}export{CATALOG_PUBLISHED_STATUS,MAX_ROWS_PER_READ,NARROW_READ_LIMIT,POPULAR_OFFSET,THIN_READ_ROWS,WIDE_READ_LIMIT,catalogRowSearchFields,fetchCatalogRead,rankedCatalogSearch,readCatalogRows,readCatalogRowsByRef};//# sourceMappingURL=rankedCatalogSearch.js.map
|
|
385
|
+
}export{CATALOG_PUBLISHED_STATUS,MAX_MATCH_READS,MAX_ROWS_PER_READ,NARROW_READ_LIMIT,POPULAR_OFFSET,THIN_READ_ROWS,WIDE_READ_LIMIT,catalogRowSearchFields,fetchCatalogRead,rankedCatalogSearch,readCatalogRows,readCatalogRowsByRef};//# sourceMappingURL=rankedCatalogSearch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rankedCatalogSearch.js","sources":["../../../src/features/canvas/rankedCatalogSearch.ts"],"sourcesContent":["/**\n * A searched template catalog, a page at a time: the matches best first, then\n * the category's own templates, so a search never comes back empty while the\n * category has any. Native port of surface-kit `templateCatalogs/\n * rankedCatalogSearch` + `catalogRead` (kit 0.43).\n *\n * The backend `formTemplateSubmissions` search keeps only rows that hold every\n * word, unranked (\"clean modern fancy\" found 0). So a search here is:\n *\n * 1. Gather: a handful of LIGHT reads (id name description category tags) -\n * every word together, each subject word, near words (./templateSearch\n * `templateSearchReads`).\n * 2. Rank the candidates on the whole query (`rankTemplates`).\n * 3. Read whole only the rows a page shows, in ONE aliased\n * `formTemplateSubmission(id:)` request, and order the page again on them.\n * 4. After the matches, the category's own unsearched rows follow as `popular`.\n *\n * Transport-agnostic: `read(variables, query)` performs one GraphQL POST and\n * returns its `{ data, errors }` - Apollo (`apolloCatalogRead` in\n * ./studioCatalog) or plain fetch (`fetchCatalogRead` below).\n */\nimport {\n NON_WORD,\n parseTemplateQuery,\n rankTemplates,\n scoreTemplate,\n templateSearchReads,\n templateSearchText,\n titleFromRowName,\n type TemplateMatch,\n type TemplateQuery,\n type TemplateSearchFields,\n type TemplateSearchRead,\n} from './templateSearch';\n\nexport type CatalogRow = Record<string, any>;\n\n/** One GraphQL answer, as any transport returns it. */\nexport interface CatalogGraphqlAnswer {\n data?: Record<string, any> | null;\n errors?: ReadonlyArray<{ message?: string } | null> | null;\n}\n\n/** Performs one GraphQL POST of `query` with `variables`. May throw on a failed request. */\nexport type CatalogGraphqlRead = (variables: Record<string, unknown>, query: string) => Promise<CatalogGraphqlAnswer>;\n\n/** The row status a public catalog lists. */\nexport const CATALOG_PUBLISHED_STATUS = 'published';\n\n/** Light rows a primary read gathers, and a near-word read. */\nexport const WIDE_READ_LIMIT = 96;\nexport const NARROW_READ_LIMIT = 40;\n/** Offsets at or past this are the category's own pages: `POPULAR_OFFSET + <that page's offset>`. */\nexport const POPULAR_OFFSET = 1_000_000_000;\n/** A word whose own read found fewer rows than this has its near words read too. */\nexport const THIN_READ_ROWS = 24;\n/** Rows read whole in one request, at most this many. */\nexport const MAX_ROWS_PER_READ = 48;\n/** A row name past this many words may be a title cut short. */\nconst NAME_WORDS_KEPT = 6;\n\nconst FULL_FIELDS = 'id name description category tags formData';\nconst LIGHT_FIELDS = 'id name description category tags';\n\nconst submissionsQuery = (fields: string) => `query TemplateCatalog($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) { nodes { ${fields} } }\n}`;\n\n/** Search words joined the way the backend's slugged row names join them (\"real-estate\"). */\nfunction catalogSearchSlug(query: string | undefined): string | undefined {\n const words = (query ?? '').split(NON_WORD).filter(Boolean);\n return words.length ? words.join('-') : undefined;\n}\n\nconst errorText = (errors: CatalogGraphqlAnswer['errors']) =>\n (errors ?? [])\n .map((e) => e?.message)\n .filter(Boolean)\n .join('; ') || 'Template catalog read failed';\n\ninterface RowsQuery {\n group: string;\n query?: string;\n limit: number;\n offset: number;\n templateId?: string;\n fields?: 'full' | 'light';\n}\n\n/** One page of a group's published rows. Throws on a failed read; null when the answer has no list. */\nexport async function readCatalogRows(\n { group, query, limit, offset, templateId, fields = 'full' }: RowsQuery,\n read: CatalogGraphqlRead,\n): Promise<CatalogRow[] | null> {\n const search = catalogSearchSlug(query);\n const json = await read(\n {\n filter: {\n group,\n status: CATALOG_PUBLISHED_STATUS,\n ...(templateId ? { templateId } : {}),\n ...(search ? { search } : {}),\n limit,\n offset,\n },\n },\n submissionsQuery(fields === 'light' ? LIGHT_FIELDS : FULL_FIELDS),\n );\n if (json.errors?.length && !json.data?.formTemplateSubmissions) throw new Error(errorText(json.errors));\n const nodes = json.data?.formTemplateSubmissions?.nodes;\n return Array.isArray(nodes) ? nodes : null;\n}\n\n/** A row a search found, to read whole. */\nexport interface CatalogRowRef {\n id: string;\n name: string;\n group: string;\n templateId?: string;\n}\n\nconst isPublished = (row: CatalogRow) => !row.status || row.status === CATALOG_PUBLISHED_STATUS;\n\n/**\n * Whole rows for refs a light search found, in one request (`formTemplateSubmission`\n * aliased once per row), keyed by row name. Only rows still published and in their\n * group come back. Should the read by id fail, each row is looked up by name instead.\n */\nexport async function readCatalogRowsByRef(\n refs: readonly CatalogRowRef[],\n read: CatalogGraphqlRead,\n): Promise<Map<string, CatalogRow>> {\n const found = new Map<string, CatalogRow>();\n const wanted = refs.slice(0, MAX_ROWS_PER_READ);\n if (wanted.length === 0) return found;\n const keep = (ref: CatalogRowRef, row: CatalogRow | null | undefined, checked: boolean) => {\n if (!row || row.name !== ref.name) return;\n if (checked || (row.group === ref.group && isPublished(row))) found.set(ref.name, row);\n };\n const vars = wanted.map((_, i) => `$r${i}: ID!`).join(', ');\n const fields = wanted\n .map((_, i) => `r${i}: formTemplateSubmission(id: $r${i}) { ${FULL_FIELDS} group status }`)\n .join('\\n ');\n let byId: CatalogGraphqlAnswer;\n try {\n byId = await read(\n Object.fromEntries(wanted.map((ref, i) => [`r${i}`, ref.id])),\n `query TemplateRows(${vars}) {\\n ${fields}\\n}`,\n );\n } catch (error) {\n byId = { errors: [{ message: error instanceof Error ? error.message : String(error) }] };\n }\n const answered = wanted.some((_, i) => byId.data?.[`r${i}`]);\n if (answered || !byId.errors?.length) {\n wanted.forEach((ref, i) => keep(ref, byId.data?.[`r${i}`], false));\n return found;\n }\n const filters = wanted.map((ref) => ({\n group: ref.group,\n status: CATALOG_PUBLISHED_STATUS,\n ...(ref.templateId ? { templateId: ref.templateId } : {}),\n search: catalogSearchSlug(ref.name),\n limit: 3,\n offset: 0,\n }));\n const byName = await read(\n Object.fromEntries(filters.map((f, i) => [`f${i}`, f])),\n `query TemplateRowsByName(${wanted.map((_, i) => `$f${i}: FormTemplateSubmissionFilter`).join(', ')}) {\\n ${wanted\n .map((_, i) => `r${i}: formTemplateSubmissions(filter: $f${i}) { nodes { ${FULL_FIELDS} } }`)\n .join('\\n ')}\\n}`,\n );\n if (byName.errors?.length && !byName.data) throw new Error(errorText(byName.errors));\n wanted.forEach((ref, i) => {\n const nodes = byName.data?.[`r${i}`]?.nodes as CatalogRow[] | undefined;\n keep(\n ref,\n nodes?.find((n) => n?.name === ref.name),\n true,\n );\n });\n return found;\n}\n\n// ─── Gather and rank ────────────────────────────────────────────────────────\n\ninterface Candidate extends CatalogRowRef {\n match: Exclude<TemplateMatch, 'popular'>;\n score: number;\n}\n\ninterface Session {\n candidates: Candidate[];\n names: Set<string>;\n floorAt: Map<number, TemplateMatch>;\n}\n\nconst MATCH_ORDER: Record<TemplateMatch, number> = { exact: 0, close: 1, popular: 2 };\n\ntype ReadResult = { read: TemplateSearchRead; group: string; rows: CatalogRow[] | null };\n\nasync function runReads(\n reads: readonly TemplateSearchRead[],\n groups: readonly string[],\n templateIdOf: (group: string) => string | undefined,\n read: CatalogGraphqlRead,\n): Promise<{ results: ReadResult[]; failures: unknown[] }> {\n const jobs = reads.flatMap((r) => groups.map((group) => ({ read: r, group })));\n const settled = await Promise.all(\n jobs.map(({ read: r, group }) =>\n readCatalogRows(\n {\n group,\n query: r.words.join(' '),\n limit: r.wide ? WIDE_READ_LIMIT : NARROW_READ_LIMIT,\n offset: 0,\n templateId: templateIdOf(group),\n fields: 'light',\n },\n read,\n ).then(\n (rows) => ({ ok: true as const, rows }),\n (reason: unknown) => ({ ok: false as const, reason }),\n ),\n ),\n );\n const failures: unknown[] = [];\n const results = settled.map((s, i) => {\n if ('reason' in s) failures.push(s.reason);\n return { ...jobs[i], rows: s.ok ? s.rows : null };\n });\n return { results, failures };\n}\n\n/** Gather and rank one query's candidates. Throws only when every read failed. */\nasync function gather(\n query: TemplateQuery,\n groups: readonly string[],\n templateIdOf: (group: string) => string | undefined,\n read: CatalogGraphqlRead,\n): Promise<Candidate[]> {\n const reads = templateSearchReads(query);\n const first = await runReads(\n reads.filter((r) => r.stage === 1),\n groups,\n templateIdOf,\n read,\n );\n const found = new Map<string, number>();\n for (const { read: r, rows } of first.results) {\n if (r.concept) found.set(r.concept, (found.get(r.concept) ?? 0) + (rows?.length ?? 0));\n }\n const second = await runReads(\n reads.filter((r) => r.stage === 2 && (found.get(r.concept ?? '') ?? 0) < THIN_READ_ROWS),\n groups,\n templateIdOf,\n read,\n );\n const results = [...first.results, ...second.results];\n const failures = [...first.failures, ...second.failures];\n if (failures.length > 0 && failures.length === results.length) throw failures[0];\n\n const rows = new Map<string, { row: CatalogRow; group: string; foundBy: Set<string> }>();\n results.forEach(({ read: r, group, rows: hits }) => {\n if (!hits) return;\n for (const row of hits) {\n const name = typeof row?.name === 'string' ? row.name : '';\n const id = typeof row?.id === 'string' ? row.id : '';\n if (!name || !id) continue;\n let entry = rows.get(name);\n if (!entry) {\n entry = { row, group, foundBy: new Set() };\n rows.set(name, entry);\n }\n const hit = entry;\n r.terms.forEach((t) => hit.foundBy.add(t));\n }\n });\n const ranked = rankTemplates(\n query,\n [...rows.values()],\n ({ row, group }) => {\n const title = titleFromRowName(row.name, group);\n return templateSearchText(\n { title, tags: row.tags, category: row.category, description: row.description },\n title.split(' ').length < NAME_WORDS_KEPT,\n );\n },\n (entry) => entry.foundBy,\n );\n return ranked.map(({ item, match, score }) => {\n const templateId = templateIdOf(item.group);\n return {\n id: item.row.id,\n name: item.row.name,\n group: item.group,\n ...(templateId ? { templateId } : {}),\n match,\n score,\n };\n });\n}\n\n// ─── The search ─────────────────────────────────────────────────────────────\n\n/** A row a searched page lists, and how it fits the search. */\nexport interface RankedCatalogRow {\n row: CatalogRow;\n group: string;\n match: TemplateMatch;\n}\n\nexport interface RankedCatalogPage {\n rows: RankedCatalogRow[];\n /** Where the next page starts (pass back as `offset`), or null at the end. */\n next: number | null;\n /** The query as read. */\n query: TemplateQuery;\n}\n\nexport interface RankedCatalogSearchParams {\n /** The publish group (`video-studio`, `canvas-flyer`), or several read as one catalog. */\n group: string | readonly string[];\n /** What was typed. */\n query: string;\n /** Rows per page. */\n limit: number;\n /** 0 for the first page; then the `next` a page returned. */\n offset?: number;\n /** One GraphQL POST. */\n read: CatalogGraphqlRead;\n /** The marketplace record a group's listing reads, when it lists only one. */\n templateIdOf?: (group: string) => string | undefined;\n /** Words that name the category (\"video\", \"flyer\"): a search inside it says nothing by them. */\n categoryWords?: readonly string[];\n /** What a whole row is searched by; defaults to its generationDetails title/summary, tags, category. */\n fieldsOf?: (row: CatalogRow, group: string) => TemplateSearchFields;\n /** False for a row the page cannot offer. */\n accept?: (row: CatalogRow, group: string) => boolean;\n /** A page of the category's own rows (no search); defaults to an unsearched read of the first group. */\n popular?: (offset: number) => Promise<{ rows: CatalogRow[]; next: number | null }>;\n}\n\nconst MAX_SESSIONS = 6;\nconst sessions = new Map<string, Promise<Session>>();\n\n/** Forget remembered searches (tests; a sign-out). */\nexport function clearRankedCatalogSearchCache(): void {\n sessions.clear();\n}\n\nfunction record(value: unknown): Record<string, any> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, any>) : {};\n}\n\nfunction formDataOf(row: CatalogRow): Record<string, any> {\n if (typeof row.formData === 'string') {\n try {\n return record(JSON.parse(row.formData));\n } catch {\n return {};\n }\n }\n return record(row.formData);\n}\n\nconst text = (v: unknown) => (typeof v === 'string' ? v : '');\n\n/** What a whole row is searched by: its title and summary as the publish lane wrote them. */\nexport function catalogRowSearchFields(row: CatalogRow, group: string): TemplateSearchFields {\n const details = record(formDataOf(row).generationDetails);\n const name = text(row.name);\n return {\n title: text(details.title) || (name ? titleFromRowName(name, group) : ''),\n summary: text(details.summary) || text(row.description),\n tags: Array.isArray(row.tags) ? row.tags.filter((t: unknown): t is string => typeof t === 'string') : [],\n category: text(row.category),\n };\n}\n\n/**\n * One page of a ranked catalog search. A query of nothing but filler or the\n * category's own name reads as the category's own rows (`popular`).\n */\nexport async function rankedCatalogSearch(params: RankedCatalogSearchParams): Promise<RankedCatalogPage> {\n const groups = typeof params.group === 'string' ? [params.group] : [...params.group];\n const templateIdOf = params.templateIdOf ?? (() => undefined);\n const fieldsOf = params.fieldsOf ?? catalogRowSearchFields;\n const accept = params.accept ?? (() => true);\n const offset = Math.max(0, params.offset ?? 0);\n const query = parseTemplateQuery(params.query, { categoryWords: params.categoryWords ?? [] });\n const popular =\n params.popular ??\n (async (from: number) => {\n const rows =\n (await readCatalogRows(\n { group: groups[0], limit: params.limit, offset: from, templateId: templateIdOf(groups[0]) },\n params.read,\n )) ?? [];\n return { rows, next: rows.length >= params.limit ? from + params.limit : null };\n });\n\n const popularPage = async (from: number, names: ReadonlySet<string>, shifted: boolean) => {\n const page = await popular(from);\n return {\n rows: page.rows\n .filter((row) => !names.has(text(row?.name)) && accept(row, groups[0]))\n .map((row) => ({ row, group: groups[0], match: 'popular' as const })),\n next: page.next === null ? null : shifted ? POPULAR_OFFSET + page.next : page.next,\n query,\n };\n };\n\n if (query.empty) return popularPage(offset >= POPULAR_OFFSET ? offset - POPULAR_OFFSET : offset, new Set(), false);\n\n const key = JSON.stringify([groups, groups.map(templateIdOf), query.subjects, query.styles]);\n let session = sessions.get(key);\n if (!session) {\n const created: Promise<Session> = gather(query, groups, templateIdOf, params.read).then((candidates) => ({\n candidates,\n names: new Set(candidates.map((c) => c.name)),\n floorAt: new Map<number, TemplateMatch>(),\n }));\n // A failed gather is not remembered: the next read tries again.\n created.catch(() => sessions.delete(key));\n sessions.set(key, created);\n while (sessions.size > MAX_SESSIONS) {\n const oldest = sessions.keys().next().value;\n if (oldest === undefined) break;\n sessions.delete(oldest);\n }\n session = created;\n }\n const s = await session;\n if (offset < POPULAR_OFFSET && offset < s.candidates.length) {\n return matchesPage(query, s, offset, params.limit, params.read, fieldsOf, accept);\n }\n return popularPage(offset >= POPULAR_OFFSET ? offset - POPULAR_OFFSET : 0, s.names, true);\n}\n\nasync function matchesPage(\n query: TemplateQuery,\n session: Session,\n offset: number,\n limit: number,\n read: CatalogGraphqlRead,\n fieldsOf: (row: CatalogRow, group: string) => TemplateSearchFields,\n accept: (row: CatalogRow, group: string) => boolean,\n): Promise<RankedCatalogPage> {\n const slice = session.candidates.slice(offset, offset + limit);\n const rows = await readCatalogRowsByRef(slice, read);\n const listed: Array<{ item: RankedCatalogRow; score: number; order: number }> = [];\n slice.forEach((candidate, order) => {\n const row = rows.get(candidate.name);\n if (!row || !accept(row, candidate.group)) return;\n const whole = scoreTemplate(query, templateSearchText(fieldsOf(row, candidate.group)));\n const match = whole.match ?? candidate.match;\n const score = whole.match ? whole.score : candidate.score;\n listed.push({ item: { row, group: candidate.group, match }, score, order });\n });\n listed.sort((a, b) => b.score - a.score || a.order - b.order);\n let floor: TemplateMatch = session.floorAt.get(offset) ?? 'exact';\n const items = listed.map(({ item }) => {\n if (MATCH_ORDER[item.match] < MATCH_ORDER[floor]) return { ...item, match: floor };\n floor = item.match;\n return item;\n });\n const end = offset + slice.length;\n session.floorAt.set(end, floor);\n return { rows: items, next: end < session.candidates.length ? end : POPULAR_OFFSET, query };\n}\n\n/** A `CatalogGraphqlRead` over plain fetch (anonymous unless a bearer is given). */\nexport function fetchCatalogRead(endpoint: string, token?: string | null): CatalogGraphqlRead {\n return async (variables, query) => {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(token ? { authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);\n return ((await res.json().catch(() => ({}))) ?? {}) as CatalogGraphqlAnswer;\n };\n}\n"],"names":["_a","_b","rows"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rankedCatalogSearch.js","sources":["../../../src/features/canvas/rankedCatalogSearch.ts"],"sourcesContent":["/**\n * A searched template catalog, a page at a time: the matches best first, then\n * the category's own templates, so a search never comes back empty while the\n * category has any. Native port of surface-kit `templateCatalogs/\n * rankedCatalogSearch` + `catalogRead` (kit 0.43).\n *\n * The backend `formTemplateSubmissions` search keeps only rows that hold every\n * word, unranked (\"clean modern fancy\" found 0). So a search here is:\n *\n * 1. Gather: a handful of LIGHT reads (id name description category tags) -\n * every word together, each subject word, near words (./templateSearch\n * `templateSearchReads`).\n * 2. Rank the candidates on the whole query (`rankTemplates`).\n * 3. Read whole only the rows a page shows, in ONE aliased\n * `formTemplateSubmission(id:)` request, and order the page again on them.\n * 4. After the matches, the category's own unsearched rows follow as `popular`.\n *\n * Transport-agnostic: `read(variables, query)` performs one GraphQL POST and\n * returns its `{ data, errors }` - Apollo (`apolloCatalogRead` in\n * ./studioCatalog) or plain fetch (`fetchCatalogRead` below).\n */\nimport {\n NON_WORD,\n parseTemplateQuery,\n rankTemplates,\n scoreTemplate,\n templateSearchReads,\n templateSearchText,\n titleFromRowName,\n type TemplateMatch,\n type TemplateQuery,\n type TemplateSearchFields,\n type TemplateSearchRead,\n} from './templateSearch';\n\nexport type CatalogRow = Record<string, any>;\n\n/** One GraphQL answer, as any transport returns it. */\nexport interface CatalogGraphqlAnswer {\n data?: Record<string, any> | null;\n errors?: ReadonlyArray<{ message?: string } | null> | null;\n}\n\n/** Performs one GraphQL POST of `query` with `variables`. May throw on a failed request. */\nexport type CatalogGraphqlRead = (variables: Record<string, unknown>, query: string) => Promise<CatalogGraphqlAnswer>;\n\n/** The row status a public catalog lists. */\nexport const CATALOG_PUBLISHED_STATUS = 'published';\n\n/** Light rows a primary read gathers, and a near-word read. */\nexport const WIDE_READ_LIMIT = 96;\nexport const NARROW_READ_LIMIT = 40;\n/** Offsets at or past this are the category's own pages: `POPULAR_OFFSET + <that page's offset>`. */\nexport const POPULAR_OFFSET = 1_000_000_000;\n/** A word whose own read found fewer rows than this has its near words read too. */\nexport const THIN_READ_ROWS = 24;\n/** Rows read whole in one request, at most this many. */\nexport const MAX_ROWS_PER_READ = 48;\n/** A row name past this many words may be a title cut short. */\nconst NAME_WORDS_KEPT = 6;\n\nconst FULL_FIELDS = 'id name description category tags formData';\nconst LIGHT_FIELDS = 'id name description category tags';\n\nconst submissionsQuery = (fields: string) => `query TemplateCatalog($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) { nodes { ${fields} } }\n}`;\n\n/** Search words joined the way the backend's slugged row names join them (\"real-estate\"). */\nfunction catalogSearchSlug(query: string | undefined): string | undefined {\n const words = (query ?? '').split(NON_WORD).filter(Boolean);\n return words.length ? words.join('-') : undefined;\n}\n\nconst errorText = (errors: CatalogGraphqlAnswer['errors']) =>\n (errors ?? [])\n .map((e) => e?.message)\n .filter(Boolean)\n .join('; ') || 'Template catalog read failed';\n\ninterface RowsQuery {\n group: string;\n query?: string;\n limit: number;\n offset: number;\n templateId?: string;\n fields?: 'full' | 'light';\n}\n\n/** One page of a group's published rows. Throws on a failed read; null when the answer has no list. */\nexport async function readCatalogRows(\n { group, query, limit, offset, templateId, fields = 'full' }: RowsQuery,\n read: CatalogGraphqlRead,\n): Promise<CatalogRow[] | null> {\n const search = catalogSearchSlug(query);\n const json = await read(\n {\n filter: {\n group,\n status: CATALOG_PUBLISHED_STATUS,\n ...(templateId ? { templateId } : {}),\n ...(search ? { search } : {}),\n limit,\n offset,\n },\n },\n submissionsQuery(fields === 'light' ? LIGHT_FIELDS : FULL_FIELDS),\n );\n if (json.errors?.length && !json.data?.formTemplateSubmissions) throw new Error(errorText(json.errors));\n const nodes = json.data?.formTemplateSubmissions?.nodes;\n return Array.isArray(nodes) ? nodes : null;\n}\n\n/** A row a search found, to read whole. */\nexport interface CatalogRowRef {\n id: string;\n name: string;\n group: string;\n templateId?: string;\n}\n\nconst isPublished = (row: CatalogRow) => !row.status || row.status === CATALOG_PUBLISHED_STATUS;\n\n/**\n * Whole rows for refs a light search found, in one request (`formTemplateSubmission`\n * aliased once per row), keyed by row name. Only rows still published and in their\n * group come back. Should the read by id fail, each row is looked up by name instead.\n */\nexport async function readCatalogRowsByRef(\n refs: readonly CatalogRowRef[],\n read: CatalogGraphqlRead,\n): Promise<Map<string, CatalogRow>> {\n const found = new Map<string, CatalogRow>();\n const wanted = refs.slice(0, MAX_ROWS_PER_READ);\n if (wanted.length === 0) return found;\n const keep = (ref: CatalogRowRef, row: CatalogRow | null | undefined, checked: boolean) => {\n if (!row || row.name !== ref.name) return;\n if (checked || (row.group === ref.group && isPublished(row))) found.set(ref.name, row);\n };\n const vars = wanted.map((_, i) => `$r${i}: ID!`).join(', ');\n const fields = wanted\n .map((_, i) => `r${i}: formTemplateSubmission(id: $r${i}) { ${FULL_FIELDS} group status }`)\n .join('\\n ');\n let byId: CatalogGraphqlAnswer;\n try {\n byId = await read(\n Object.fromEntries(wanted.map((ref, i) => [`r${i}`, ref.id])),\n `query TemplateRows(${vars}) {\\n ${fields}\\n}`,\n );\n } catch (error) {\n byId = { errors: [{ message: error instanceof Error ? error.message : String(error) }] };\n }\n const answered = wanted.some((_, i) => byId.data?.[`r${i}`]);\n if (answered || !byId.errors?.length) {\n wanted.forEach((ref, i) => keep(ref, byId.data?.[`r${i}`], false));\n return found;\n }\n const filters = wanted.map((ref) => ({\n group: ref.group,\n status: CATALOG_PUBLISHED_STATUS,\n ...(ref.templateId ? { templateId: ref.templateId } : {}),\n search: catalogSearchSlug(ref.name),\n limit: 3,\n offset: 0,\n }));\n const byName = await read(\n Object.fromEntries(filters.map((f, i) => [`f${i}`, f])),\n `query TemplateRowsByName(${wanted.map((_, i) => `$f${i}: FormTemplateSubmissionFilter`).join(', ')}) {\\n ${wanted\n .map((_, i) => `r${i}: formTemplateSubmissions(filter: $f${i}) { nodes { ${FULL_FIELDS} } }`)\n .join('\\n ')}\\n}`,\n );\n if (byName.errors?.length && !byName.data) throw new Error(errorText(byName.errors));\n wanted.forEach((ref, i) => {\n const nodes = byName.data?.[`r${i}`]?.nodes as CatalogRow[] | undefined;\n keep(\n ref,\n nodes?.find((n) => n?.name === ref.name),\n true,\n );\n });\n return found;\n}\n\n// ─── Gather and rank ────────────────────────────────────────────────────────\n\ninterface Candidate extends CatalogRowRef {\n match: Exclude<TemplateMatch, 'popular'>;\n score: number;\n}\n\ninterface Session {\n candidates: Candidate[];\n names: Set<string>;\n floorAt: Map<number, TemplateMatch>;\n}\n\nconst MATCH_ORDER: Record<TemplateMatch, number> = { exact: 0, close: 1, popular: 2 };\n\ntype ReadResult = { read: TemplateSearchRead; group: string; rows: CatalogRow[] | null };\n\nasync function runReads(\n reads: readonly TemplateSearchRead[],\n groups: readonly string[],\n templateIdOf: (group: string) => string | undefined,\n read: CatalogGraphqlRead,\n): Promise<{ results: ReadResult[]; failures: unknown[] }> {\n const jobs = reads.flatMap((r) => groups.map((group) => ({ read: r, group })));\n const settled = await Promise.all(\n jobs.map(({ read: r, group }) =>\n readCatalogRows(\n {\n group,\n query: r.words.join(' '),\n limit: r.wide ? WIDE_READ_LIMIT : NARROW_READ_LIMIT,\n offset: 0,\n templateId: templateIdOf(group),\n fields: 'light',\n },\n read,\n ).then(\n (rows) => ({ ok: true as const, rows }),\n (reason: unknown) => ({ ok: false as const, reason }),\n ),\n ),\n );\n const failures: unknown[] = [];\n const results = settled.map((s, i) => {\n if ('reason' in s) failures.push(s.reason);\n return { ...jobs[i], rows: s.ok ? s.rows : null };\n });\n return { results, failures };\n}\n\n/** Gather and rank one query's candidates. Throws only when every read failed. */\nasync function gather(\n query: TemplateQuery,\n groups: readonly string[],\n templateIdOf: (group: string) => string | undefined,\n read: CatalogGraphqlRead,\n): Promise<Candidate[]> {\n const reads = templateSearchReads(query);\n const first = await runReads(\n reads.filter((r) => r.stage === 1),\n groups,\n templateIdOf,\n read,\n );\n const found = new Map<string, number>();\n for (const { read: r, rows } of first.results) {\n if (r.concept) found.set(r.concept, (found.get(r.concept) ?? 0) + (rows?.length ?? 0));\n }\n const second = await runReads(\n reads.filter((r) => r.stage === 2 && (found.get(r.concept ?? '') ?? 0) < THIN_READ_ROWS),\n groups,\n templateIdOf,\n read,\n );\n const results = [...first.results, ...second.results];\n const failures = [...first.failures, ...second.failures];\n if (failures.length > 0 && failures.length === results.length) throw failures[0];\n\n const rows = new Map<string, { row: CatalogRow; group: string; foundBy: Set<string> }>();\n results.forEach(({ read: r, group, rows: hits }) => {\n if (!hits) return;\n for (const row of hits) {\n const name = typeof row?.name === 'string' ? row.name : '';\n const id = typeof row?.id === 'string' ? row.id : '';\n if (!name || !id) continue;\n let entry = rows.get(name);\n if (!entry) {\n entry = { row, group, foundBy: new Set() };\n rows.set(name, entry);\n }\n const hit = entry;\n r.terms.forEach((t) => hit.foundBy.add(t));\n }\n });\n const ranked = rankTemplates(\n query,\n [...rows.values()],\n ({ row, group }) => {\n const title = titleFromRowName(row.name, group);\n return templateSearchText(\n { title, tags: row.tags, category: row.category, description: row.description },\n title.split(' ').length < NAME_WORDS_KEPT,\n );\n },\n (entry) => entry.foundBy,\n );\n return ranked.map(({ item, match, score }) => {\n const templateId = templateIdOf(item.group);\n return {\n id: item.row.id,\n name: item.row.name,\n group: item.group,\n ...(templateId ? { templateId } : {}),\n match,\n score,\n };\n });\n}\n\n// ─── The search ─────────────────────────────────────────────────────────────\n\n/** A row a searched page lists, and how it fits the search. */\nexport interface RankedCatalogRow {\n row: CatalogRow;\n group: string;\n match: TemplateMatch;\n}\n\nexport interface RankedCatalogPage {\n rows: RankedCatalogRow[];\n /** Where the next page starts (pass back as `offset`), or null at the end. */\n next: number | null;\n /** The query as read. */\n query: TemplateQuery;\n}\n\nexport interface RankedCatalogSearchParams {\n /** The publish group (`video-studio`, `canvas-flyer`), or several read as one catalog. */\n group: string | readonly string[];\n /** What was typed. */\n query: string;\n /** Rows per page. */\n limit: number;\n /** 0 for the first page; then the `next` a page returned. */\n offset?: number;\n /** One GraphQL POST. */\n read: CatalogGraphqlRead;\n /** The marketplace record a group's listing reads, when it lists only one. */\n templateIdOf?: (group: string) => string | undefined;\n /** Words that name the category (\"video\", \"flyer\"): a search inside it says nothing by them. */\n categoryWords?: readonly string[];\n /** What a whole row is searched by; defaults to its generationDetails title/summary, tags, category. */\n fieldsOf?: (row: CatalogRow, group: string) => TemplateSearchFields;\n /** False for a row the page cannot offer. */\n accept?: (row: CatalogRow, group: string) => boolean;\n /** A page of the category's own rows (no search); defaults to an unsearched read of the first group. */\n popular?: (offset: number) => Promise<{ rows: CatalogRow[]; next: number | null }>;\n}\n\nconst MAX_SESSIONS = 6;\nconst sessions = new Map<string, Promise<Session>>();\n\n/** Forget remembered searches (tests; a sign-out). */\nexport function clearRankedCatalogSearchCache(): void {\n sessions.clear();\n}\n\nfunction record(value: unknown): Record<string, any> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, any>) : {};\n}\n\nfunction formDataOf(row: CatalogRow): Record<string, any> {\n if (typeof row.formData === 'string') {\n try {\n return record(JSON.parse(row.formData));\n } catch {\n return {};\n }\n }\n return record(row.formData);\n}\n\nconst text = (v: unknown) => (typeof v === 'string' ? v : '');\n\n/** What a whole row is searched by: its title and summary as the publish lane wrote them. */\nexport function catalogRowSearchFields(row: CatalogRow, group: string): TemplateSearchFields {\n const details = record(formDataOf(row).generationDetails);\n const name = text(row.name);\n return {\n title: text(details.title) || (name ? titleFromRowName(name, group) : ''),\n summary: text(details.summary) || text(row.description),\n tags: Array.isArray(row.tags) ? row.tags.filter((t: unknown): t is string => typeof t === 'string') : [],\n category: text(row.category),\n };\n}\n\n/**\n * One page of a ranked catalog search. A query of nothing but filler or the\n * category's own name reads as the category's own rows (`popular`).\n */\nexport async function rankedCatalogSearch(params: RankedCatalogSearchParams): Promise<RankedCatalogPage> {\n const groups = typeof params.group === 'string' ? [params.group] : [...params.group];\n const templateIdOf = params.templateIdOf ?? (() => undefined);\n const fieldsOf = params.fieldsOf ?? catalogRowSearchFields;\n const accept = params.accept ?? (() => true);\n const offset = Math.max(0, params.offset ?? 0);\n const query = parseTemplateQuery(params.query, { categoryWords: params.categoryWords ?? [] });\n const popular =\n params.popular ??\n (async (from: number) => {\n const rows =\n (await readCatalogRows(\n { group: groups[0], limit: params.limit, offset: from, templateId: templateIdOf(groups[0]) },\n params.read,\n )) ?? [];\n return { rows, next: rows.length >= params.limit ? from + params.limit : null };\n });\n\n const popularPage = async (from: number, names: ReadonlySet<string>, shifted: boolean) => {\n const page = await popular(from);\n return {\n rows: page.rows\n .filter((row) => !names.has(text(row?.name)) && accept(row, groups[0]))\n .map((row) => ({ row, group: groups[0], match: 'popular' as const })),\n next: page.next === null ? null : shifted ? POPULAR_OFFSET + page.next : page.next,\n query,\n };\n };\n\n if (query.empty) return popularPage(offset >= POPULAR_OFFSET ? offset - POPULAR_OFFSET : offset, new Set(), false);\n\n const key = JSON.stringify([groups, groups.map(templateIdOf), query.subjects, query.styles]);\n let session = sessions.get(key);\n if (!session) {\n const created: Promise<Session> = gather(query, groups, templateIdOf, params.read).then((candidates) => ({\n candidates,\n names: new Set(candidates.map((c) => c.name)),\n floorAt: new Map<number, TemplateMatch>(),\n }));\n // A failed gather is not remembered: the next read tries again.\n created.catch(() => sessions.delete(key));\n sessions.set(key, created);\n while (sessions.size > MAX_SESSIONS) {\n const oldest = sessions.keys().next().value;\n if (oldest === undefined) break;\n sessions.delete(oldest);\n }\n session = created;\n }\n const s = await session;\n if (offset < POPULAR_OFFSET && offset < s.candidates.length) {\n return matchesPage(query, s, offset, params.limit, params.read, fieldsOf, accept);\n }\n return popularPage(offset >= POPULAR_OFFSET ? offset - POPULAR_OFFSET : 0, s.names, true);\n}\n\n/**\n * Batches of candidates one matches page may read whole at most. A batch whose rows the page cannot\n * offer (`accept` false: a listing drops them) is followed by the next one, until the page holds\n * `limit` rows or the matches end.\n */\nexport const MAX_MATCH_READS = 4;\n\n/**\n * One page of the ranked matches, read whole and ordered again on what the whole rows say. The page\n * is full: a candidate the page cannot offer is passed over and the next ones are read in its place,\n * so a hidden row leaves no gap. `next` is the place after the last candidate the page used.\n */\nasync function matchesPage(\n query: TemplateQuery,\n session: Session,\n offset: number,\n limit: number,\n read: CatalogGraphqlRead,\n fieldsOf: (row: CatalogRow, group: string) => TemplateSearchFields,\n accept: (row: CatalogRow, group: string) => boolean,\n): Promise<RankedCatalogPage> {\n const listed: Array<{ item: RankedCatalogRow; score: number; order: number }> = [];\n let end = offset;\n let reads = 0;\n while (listed.length < limit && end < session.candidates.length && reads < MAX_MATCH_READS) {\n reads += 1;\n const slice = session.candidates.slice(end, end + Math.min(MAX_ROWS_PER_READ, limit));\n const rows = await readCatalogRowsByRef(slice, read);\n let used = slice.length;\n for (const [i, candidate] of slice.entries()) {\n const row = rows.get(candidate.name);\n if (!row || !accept(row, candidate.group)) continue;\n // The whole row knows its full title and summary: score it again on them. A row the\n // backend matched on a field no card shows keeps the light read's verdict.\n const whole = scoreTemplate(query, templateSearchText(fieldsOf(row, candidate.group)));\n const match = whole.match ?? candidate.match;\n const score = whole.match ? whole.score : candidate.score;\n listed.push({ item: { row, group: candidate.group, match }, score, order: end + i });\n if (listed.length === limit) {\n used = i + 1;\n break;\n }\n }\n end += used;\n }\n listed.sort((a, b) => b.score - a.score || a.order - b.order);\n let floor: TemplateMatch = session.floorAt.get(offset) ?? 'exact';\n const items = listed.map(({ item }) => {\n if (MATCH_ORDER[item.match] < MATCH_ORDER[floor]) return { ...item, match: floor };\n floor = item.match;\n return item;\n });\n session.floorAt.set(end, floor);\n return { rows: items, next: end < session.candidates.length ? end : POPULAR_OFFSET, query };\n}\n\n/** A `CatalogGraphqlRead` over plain fetch (anonymous unless a bearer is given). */\nexport function fetchCatalogRead(endpoint: string, token?: string | null): CatalogGraphqlRead {\n return async (variables, query) => {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(token ? { authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) throw new Error(`Template catalog read failed (${res.status})`);\n return ((await res.json().catch(() => ({}))) ?? {}) as CatalogGraphqlAnswer;\n };\n}\n"],"names":["_a","_b","rows"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx}from'react/jsx-runtime';import {useRef,useMemo,useEffect}from'react';import {StyleSheet
|
|
1
|
+
import {jsx}from'react/jsx-runtime';import {useRef,useMemo,useEffect}from'react';import {View,StyleSheet}from'react-native';import {DEFAULT_LIGHTING,MESH_TARGET_HEIGHT_M}from'./setProject.js';import {KIT_ENTRIES}from'./supplyLibrary.js';import {useWebViewRetention}from'../../../hooks/useWebViewRetention.js';function loadWebView() {
|
|
2
2
|
try {
|
|
3
3
|
return require("react-native-webview").WebView;
|
|
4
4
|
} catch (e) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {KIT_ENTRIES}from'../supplyLibrary.js';import {
|
|
1
|
+
import {KIT_ENTRIES}from'../supplyLibrary.js';import {newObjectId,vec3,MESH_TARGET_HEIGHT_M,SET_ASPECTS,lightingOf,DEFAULT_CAMERA}from'../setProject.js';import {describeSet,describeObjects}from'./snapshot.js';import {uniqueName,cameraFromShot,tidySet,removeObjects,updateObjects,placeObjects}from'./setOps.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {gql}from'@apollo/client/index.js';import {STUDIO_TEMPLATE_PAGE_SIZE,playableTemplatePreviewUrl}from'./canvasChatTemplates.js';import {isInVideoTemplate}from'./templateImport/invideoNative.js';import {renderConfigLinks}from'./templateImport/renderConfig.js';import {rankedCatalogSearch}from'./rankedCatalogSearch.js';export{POPULAR_OFFSET,fetchCatalogRead}from'./rankedCatalogSearch.js';import {parseTemplateQuery,TEMPLATE_CATEGORY_WORDS}from'./templateSearch.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import {gql}from'@apollo/client/index.js';import {STUDIO_TEMPLATE_PAGE_SIZE,playableTemplatePreviewUrl}from'./canvasChatTemplates.js';import {isInVideoTemplate}from'./templateImport/invideoNative.js';import {renderConfigLinks}from'./templateImport/renderConfig.js';import {rankedCatalogSearch}from'./rankedCatalogSearch.js';export{POPULAR_OFFSET,fetchCatalogRead}from'./rankedCatalogSearch.js';import {parseTemplateQuery,templateDisplayTitle,TEMPLATE_CATEGORY_WORDS}from'./templateSearch.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
3
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
4
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -85,7 +85,7 @@ function catalogRowToStudioTemplate(row) {
|
|
|
85
85
|
const generation = record(formData.generation);
|
|
86
86
|
const name = str(row.name);
|
|
87
87
|
const id = name.startsWith(STUDIO_CATALOG_PREFIX) ? name.slice(STUDIO_CATALOG_PREFIX.length) : name || str(row.id);
|
|
88
|
-
const title = str(details.title) || name || str(row.id);
|
|
88
|
+
const title = templateDisplayTitle(str(details.title)) || name || str(row.id);
|
|
89
89
|
const prompt = str(generation.prompt) || str(row.description) || title;
|
|
90
90
|
if (!id || !title) return null;
|
|
91
91
|
const renderConfigRaw = formData.renderConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studioCatalog.js","sources":["../../../src/features/canvas/studioCatalog.ts"],"sourcesContent":["/**\n * Video-studio marketplace rows — same GraphQL field as browser `/c/new`\n * (`formTemplateSubmissions`, group `video-studio`). Apollo typePolicies key by\n * group + search and merge pages by offset so leaving Canvas and coming back\n * is cache-first, not a connector round-trip.\n */\nimport { gql } from '@apollo/client';\nimport type { CanvasPromptTemplate } from './canvasChatTemplates';\nimport { STUDIO_TEMPLATE_PAGE_SIZE, playableTemplatePreviewUrl } from './canvasChatTemplates';\nimport { isInVideoTemplate } from './templateImport/invideoNative';\nimport { renderConfigLinks } from './templateImport/renderConfig';\nimport { rankedCatalogSearch, type CatalogGraphqlAnswer, type CatalogGraphqlRead } from './rankedCatalogSearch';\nimport { parseTemplateQuery, TEMPLATE_CATEGORY_WORDS, type TemplateMatch } from './templateSearch';\n\nexport const STUDIO_CATALOG_GROUP = 'video-studio';\nexport const STUDIO_CATALOG_PREFIX = 'video-studio-';\nexport { STUDIO_TEMPLATE_PAGE_SIZE };\n\nexport const STUDIO_CATALOG_QUERY = gql`\n query StudioCatalogTemplates($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) {\n nodes {\n id\n name\n description\n category\n tags\n formData\n }\n }\n }\n`;\n\nexport interface StudioCatalogRow {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n category?: string | null;\n tags?: Array<string | null> | null;\n formData?: unknown;\n}\n\nexport interface StudioCatalogFilter {\n group: string;\n status: typeof PUBLISHED_STATUS;\n limit: number;\n offset: number;\n search?: string;\n}\n\n/** Only published rows reach a page: never a draft (surface-kit `catalogRead`). */\nexport const PUBLISHED_STATUS = 'published';\n\n/**\n * Search words as the backend resolver matches them (surface-kit\n * `catalogSearch`): it matches ONE regex against the slugged row name, so\n * words join with '-' (\"real estate\" found 0, \"real-estate\" 191) and only\n * letters/digits survive (\"c++\" or \"(\" broke the regex).\n */\nexport function catalogSearch(query: string | undefined): string | undefined {\n const words = (query ?? '').split(NON_WORD).filter(Boolean);\n return words.length ? words.join('-') : undefined;\n}\n\nconst NON_WORD: RegExp = (() => {\n try {\n return new RegExp('[^\\\\p{L}\\\\p{N}]+', 'u');\n } catch {\n // Engines without Unicode property escapes: ASCII plus Latin-1 letters.\n return /[^A-Za-z0-9\\u00C0-\\u024F]+/;\n }\n})();\n\nexport function studioCatalogFilter(\n search: string,\n offset = 0,\n limit = STUDIO_TEMPLATE_PAGE_SIZE,\n): StudioCatalogFilter {\n const term = catalogSearch(search);\n return {\n group: STUDIO_CATALOG_GROUP,\n status: PUBLISHED_STATUS,\n limit,\n offset,\n ...(term ? { search: term } : {}),\n };\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\nfunction parseFormData(value: unknown): Record<string, unknown> {\n if (typeof value === 'string') {\n try {\n return record(JSON.parse(value));\n } catch {\n return {};\n }\n }\n return record(value);\n}\n\nfunction clipSrcs(formData: Record<string, unknown>): string[] {\n const composition = record(formData.composition);\n const direct = Array.isArray(composition.clips) ? composition.clips : [];\n const nested = Array.isArray(composition.tracks)\n ? composition.tracks.flatMap((track) => {\n const clips = record(track).clips;\n return Array.isArray(clips) ? clips : [];\n })\n : [];\n return [...direct, ...nested].map((clip) => str(record(clip).src)).filter(Boolean);\n}\n\nexport function catalogRowToStudioTemplate(row: StudioCatalogRow): CanvasPromptTemplate | null {\n const formData = parseFormData(row.formData);\n const details = record(formData.generationDetails);\n const generation = record(formData.generation);\n const name = str(row.name);\n const id = name.startsWith(STUDIO_CATALOG_PREFIX) ? name.slice(STUDIO_CATALOG_PREFIX.length) : name || str(row.id);\n const title = str(details.title) || name || str(row.id);\n const prompt = str(generation.prompt) || str(row.description) || title;\n if (!id || !title) return null;\n\n const renderConfigRaw = formData.renderConfig;\n const renderConfig =\n typeof renderConfigRaw === 'string'\n ? (() => {\n try {\n return record(JSON.parse(renderConfigRaw));\n } catch {\n return {};\n }\n })()\n : record(renderConfigRaw);\n const usableConfig =\n Object.keys(renderConfig).length > 0 && isInVideoTemplate(renderConfig) ? renderConfig : undefined;\n const links = usableConfig ? undefined : renderConfigLinks(renderConfig);\n\n return {\n id,\n kind: 'video',\n title,\n description: str(details.summary) || str(row.description) || undefined,\n cover: str(details.previewUrl) || str(details.cover) || undefined,\n coverVideo: playableTemplatePreviewUrl(\n str(details.previewVideoUrl),\n str(formData.coverVideo),\n str(generation.coverVideo),\n str(generation.videoUrl),\n ...clipSrcs(formData),\n ),\n aspect: str(details.aspect) || str(generation.aspectRatio) || str(formData.aspect) || undefined,\n prompt,\n category: str(row.category) || undefined,\n tags: Array.isArray(row.tags) ? row.tags.filter((tag): tag is string => typeof tag === 'string') : undefined,\n ...(usableConfig ? { renderConfig: usableConfig } : {}),\n ...(links\n ? {\n configUrls: links.configUrls,\n ...(links.defaultAspect ? { defaultAspect: links.defaultAspect } : {}),\n }\n : {}),\n };\n}\n\nexport function studioTemplatesToCatalogNodes(rows: readonly CanvasPromptTemplate[]): StudioCatalogRow[] {\n return rows.map((row) => ({\n __typename: 'FormTemplateSubmission',\n id: row.id,\n name: row.id.startsWith(STUDIO_CATALOG_PREFIX) ? row.id : `${STUDIO_CATALOG_PREFIX}${row.id}`,\n description: row.description ?? null,\n category: row.category ?? null,\n tags: row.tags ?? null,\n formData: {\n generationDetails: {\n title: row.title,\n summary: row.description,\n previewUrl: row.cover,\n previewVideoUrl: row.coverVideo,\n },\n generation: { prompt: row.prompt },\n },\n }));\n}\n\n// ─── Ranked search ──────────────────────────────────────────────────────────\n// The backend search keeps only rows holding EVERY word, unranked (\"clean modern\n// fancy\" found 0). A typed search goes through the ranked search instead\n// (./rankedCatalogSearch); no search keeps the plain `studioCatalogFilter` paging.\n\nexport {\n rankedCatalogSearch,\n fetchCatalogRead,\n clearRankedCatalogSearchCache,\n POPULAR_OFFSET,\n type CatalogGraphqlRead,\n type CatalogGraphqlAnswer,\n type RankedCatalogPage,\n type RankedCatalogRow,\n type RankedCatalogSearchParams,\n} from './rankedCatalogSearch';\nexport { parseTemplateQuery, TEMPLATE_CATEGORY_WORDS, type TemplateMatch, type TemplateQuery } from './templateSearch';\n\n/** Words that name the video catalog: \"video templates\" inside it is no search. */\nexport const STUDIO_CATEGORY_WORDS: readonly string[] = TEMPLATE_CATEGORY_WORDS.videoGeneration ?? ['video'];\n\n/** True when `search` holds a word worth ranking (not empty, not only filler or \"video\"). */\nexport function isRankedStudioSearch(search: string | undefined): boolean {\n return !parseTemplateQuery(search ?? '', { categoryWords: STUDIO_CATEGORY_WORDS }).empty;\n}\n\n/** Host Apollo client, as far as a catalog read needs it. */\nexport interface CatalogApolloClient {\n query: (options: any) => Promise<{ data?: unknown; errors?: ReadonlyArray<{ message?: string }> }>;\n}\n\n/** A `CatalogGraphqlRead` over the host Apollo client (network-only: ranked reads are not cached by Apollo). */\nexport function apolloCatalogRead(client: CatalogApolloClient): CatalogGraphqlRead {\n const documents = new Map<string, ReturnType<typeof gql>>();\n return async (variables, query) => {\n let document = documents.get(query);\n if (!document) {\n document = gql(query);\n documents.set(query, document);\n }\n const result = await client.query({\n query: document,\n variables,\n fetchPolicy: 'network-only',\n errorPolicy: 'all',\n });\n return {\n data: (result.data ?? null) as CatalogGraphqlAnswer['data'],\n errors: result.errors ?? null,\n };\n };\n}\n\n/** One ranked page of the video-studio catalog, as templates, with where the next page starts. */\nexport async function rankedStudioCatalogPage(\n search: string,\n offset: number,\n read: CatalogGraphqlRead,\n limit = STUDIO_TEMPLATE_PAGE_SIZE,\n): Promise<{ rows: CanvasPromptTemplate[]; matches: TemplateMatch[]; next: number | null }> {\n const page = await rankedCatalogSearch({\n group: STUDIO_CATALOG_GROUP,\n query: search,\n limit,\n offset,\n read,\n categoryWords: STUDIO_CATEGORY_WORDS,\n accept: (row) => catalogRowToStudioTemplate(row as StudioCatalogRow) !== null,\n });\n const rows: CanvasPromptTemplate[] = [];\n const matches: TemplateMatch[] = [];\n for (const { row, match } of page.rows) {\n const template = catalogRowToStudioTemplate(row as StudioCatalogRow);\n if (!template) continue;\n rows.push(template);\n matches.push(match);\n }\n return { rows, matches, next: page.next };\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"studioCatalog.js","sources":["../../../src/features/canvas/studioCatalog.ts"],"sourcesContent":["/**\n * Video-studio marketplace rows — same GraphQL field as browser `/c/new`\n * (`formTemplateSubmissions`, group `video-studio`). Apollo typePolicies key by\n * group + search and merge pages by offset so leaving Canvas and coming back\n * is cache-first, not a connector round-trip.\n */\nimport { gql } from '@apollo/client';\nimport type { CanvasPromptTemplate } from './canvasChatTemplates';\nimport { STUDIO_TEMPLATE_PAGE_SIZE, playableTemplatePreviewUrl } from './canvasChatTemplates';\nimport { isInVideoTemplate } from './templateImport/invideoNative';\nimport { renderConfigLinks } from './templateImport/renderConfig';\nimport { rankedCatalogSearch, type CatalogGraphqlAnswer, type CatalogGraphqlRead } from './rankedCatalogSearch';\nimport {\n parseTemplateQuery,\n TEMPLATE_CATEGORY_WORDS,\n templateDisplayTitle,\n type TemplateMatch,\n} from './templateSearch';\n\nexport const STUDIO_CATALOG_GROUP = 'video-studio';\nexport const STUDIO_CATALOG_PREFIX = 'video-studio-';\nexport { STUDIO_TEMPLATE_PAGE_SIZE };\n\nexport const STUDIO_CATALOG_QUERY = gql`\n query StudioCatalogTemplates($filter: FormTemplateSubmissionFilter) {\n formTemplateSubmissions(filter: $filter) {\n nodes {\n id\n name\n description\n category\n tags\n formData\n }\n }\n }\n`;\n\nexport interface StudioCatalogRow {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n category?: string | null;\n tags?: Array<string | null> | null;\n formData?: unknown;\n}\n\nexport interface StudioCatalogFilter {\n group: string;\n status: typeof PUBLISHED_STATUS;\n limit: number;\n offset: number;\n search?: string;\n}\n\n/** Only published rows reach a page: never a draft (surface-kit `catalogRead`). */\nexport const PUBLISHED_STATUS = 'published';\n\n/**\n * Search words as the backend resolver matches them (surface-kit\n * `catalogSearch`): it matches ONE regex against the slugged row name, so\n * words join with '-' (\"real estate\" found 0, \"real-estate\" 191) and only\n * letters/digits survive (\"c++\" or \"(\" broke the regex).\n */\nexport function catalogSearch(query: string | undefined): string | undefined {\n const words = (query ?? '').split(NON_WORD).filter(Boolean);\n return words.length ? words.join('-') : undefined;\n}\n\nconst NON_WORD: RegExp = (() => {\n try {\n return new RegExp('[^\\\\p{L}\\\\p{N}]+', 'u');\n } catch {\n // Engines without Unicode property escapes: ASCII plus Latin-1 letters.\n return /[^A-Za-z0-9\\u00C0-\\u024F]+/;\n }\n})();\n\nexport function studioCatalogFilter(\n search: string,\n offset = 0,\n limit = STUDIO_TEMPLATE_PAGE_SIZE,\n): StudioCatalogFilter {\n const term = catalogSearch(search);\n return {\n group: STUDIO_CATALOG_GROUP,\n status: PUBLISHED_STATUS,\n limit,\n offset,\n ...(term ? { search: term } : {}),\n };\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\nfunction parseFormData(value: unknown): Record<string, unknown> {\n if (typeof value === 'string') {\n try {\n return record(JSON.parse(value));\n } catch {\n return {};\n }\n }\n return record(value);\n}\n\nfunction clipSrcs(formData: Record<string, unknown>): string[] {\n const composition = record(formData.composition);\n const direct = Array.isArray(composition.clips) ? composition.clips : [];\n const nested = Array.isArray(composition.tracks)\n ? composition.tracks.flatMap((track) => {\n const clips = record(track).clips;\n return Array.isArray(clips) ? clips : [];\n })\n : [];\n return [...direct, ...nested].map((clip) => str(record(clip).src)).filter(Boolean);\n}\n\nexport function catalogRowToStudioTemplate(row: StudioCatalogRow): CanvasPromptTemplate | null {\n const formData = parseFormData(row.formData);\n const details = record(formData.generationDetails);\n const generation = record(formData.generation);\n const name = str(row.name);\n const id = name.startsWith(STUDIO_CATALOG_PREFIX) ? name.slice(STUDIO_CATALOG_PREFIX.length) : name || str(row.id);\n const title = templateDisplayTitle(str(details.title)) || name || str(row.id);\n const prompt = str(generation.prompt) || str(row.description) || title;\n if (!id || !title) return null;\n\n const renderConfigRaw = formData.renderConfig;\n const renderConfig =\n typeof renderConfigRaw === 'string'\n ? (() => {\n try {\n return record(JSON.parse(renderConfigRaw));\n } catch {\n return {};\n }\n })()\n : record(renderConfigRaw);\n const usableConfig =\n Object.keys(renderConfig).length > 0 && isInVideoTemplate(renderConfig) ? renderConfig : undefined;\n const links = usableConfig ? undefined : renderConfigLinks(renderConfig);\n\n return {\n id,\n kind: 'video',\n title,\n description: str(details.summary) || str(row.description) || undefined,\n cover: str(details.previewUrl) || str(details.cover) || undefined,\n coverVideo: playableTemplatePreviewUrl(\n str(details.previewVideoUrl),\n str(formData.coverVideo),\n str(generation.coverVideo),\n str(generation.videoUrl),\n ...clipSrcs(formData),\n ),\n aspect: str(details.aspect) || str(generation.aspectRatio) || str(formData.aspect) || undefined,\n prompt,\n category: str(row.category) || undefined,\n tags: Array.isArray(row.tags) ? row.tags.filter((tag): tag is string => typeof tag === 'string') : undefined,\n ...(usableConfig ? { renderConfig: usableConfig } : {}),\n ...(links\n ? {\n configUrls: links.configUrls,\n ...(links.defaultAspect ? { defaultAspect: links.defaultAspect } : {}),\n }\n : {}),\n };\n}\n\nexport function studioTemplatesToCatalogNodes(rows: readonly CanvasPromptTemplate[]): StudioCatalogRow[] {\n return rows.map((row) => ({\n __typename: 'FormTemplateSubmission',\n id: row.id,\n name: row.id.startsWith(STUDIO_CATALOG_PREFIX) ? row.id : `${STUDIO_CATALOG_PREFIX}${row.id}`,\n description: row.description ?? null,\n category: row.category ?? null,\n tags: row.tags ?? null,\n formData: {\n generationDetails: {\n title: row.title,\n summary: row.description,\n previewUrl: row.cover,\n previewVideoUrl: row.coverVideo,\n },\n generation: { prompt: row.prompt },\n },\n }));\n}\n\n// ─── Ranked search ──────────────────────────────────────────────────────────\n// The backend search keeps only rows holding EVERY word, unranked (\"clean modern\n// fancy\" found 0). A typed search goes through the ranked search instead\n// (./rankedCatalogSearch); no search keeps the plain `studioCatalogFilter` paging.\n\nexport {\n rankedCatalogSearch,\n fetchCatalogRead,\n clearRankedCatalogSearchCache,\n POPULAR_OFFSET,\n type CatalogGraphqlRead,\n type CatalogGraphqlAnswer,\n type RankedCatalogPage,\n type RankedCatalogRow,\n type RankedCatalogSearchParams,\n} from './rankedCatalogSearch';\nexport { parseTemplateQuery, TEMPLATE_CATEGORY_WORDS, type TemplateMatch, type TemplateQuery } from './templateSearch';\n\n/** Words that name the video catalog: \"video templates\" inside it is no search. */\nexport const STUDIO_CATEGORY_WORDS: readonly string[] = TEMPLATE_CATEGORY_WORDS.videoGeneration ?? ['video'];\n\n/** True when `search` holds a word worth ranking (not empty, not only filler or \"video\"). */\nexport function isRankedStudioSearch(search: string | undefined): boolean {\n return !parseTemplateQuery(search ?? '', { categoryWords: STUDIO_CATEGORY_WORDS }).empty;\n}\n\n/** Host Apollo client, as far as a catalog read needs it. */\nexport interface CatalogApolloClient {\n query: (options: any) => Promise<{ data?: unknown; errors?: ReadonlyArray<{ message?: string }> }>;\n}\n\n/** A `CatalogGraphqlRead` over the host Apollo client (network-only: ranked reads are not cached by Apollo). */\nexport function apolloCatalogRead(client: CatalogApolloClient): CatalogGraphqlRead {\n const documents = new Map<string, ReturnType<typeof gql>>();\n return async (variables, query) => {\n let document = documents.get(query);\n if (!document) {\n document = gql(query);\n documents.set(query, document);\n }\n const result = await client.query({\n query: document,\n variables,\n fetchPolicy: 'network-only',\n errorPolicy: 'all',\n });\n return {\n data: (result.data ?? null) as CatalogGraphqlAnswer['data'],\n errors: result.errors ?? null,\n };\n };\n}\n\n/** One ranked page of the video-studio catalog, as templates, with where the next page starts. */\nexport async function rankedStudioCatalogPage(\n search: string,\n offset: number,\n read: CatalogGraphqlRead,\n limit = STUDIO_TEMPLATE_PAGE_SIZE,\n): Promise<{ rows: CanvasPromptTemplate[]; matches: TemplateMatch[]; next: number | null }> {\n const page = await rankedCatalogSearch({\n group: STUDIO_CATALOG_GROUP,\n query: search,\n limit,\n offset,\n read,\n categoryWords: STUDIO_CATEGORY_WORDS,\n accept: (row) => catalogRowToStudioTemplate(row as StudioCatalogRow) !== null,\n });\n const rows: CanvasPromptTemplate[] = [];\n const matches: TemplateMatch[] = [];\n for (const { row, match } of page.rows) {\n const template = catalogRowToStudioTemplate(row as StudioCatalogRow);\n if (!template) continue;\n rows.push(template);\n matches.push(match);\n }\n return { rows, matches, next: page.next };\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -44,6 +44,10 @@ const TEMPLATE_CATEGORY_WORDS = {
|
|
|
44
44
|
newsletter: ["newsletter"],
|
|
45
45
|
menu: ["menu"],
|
|
46
46
|
infographic: ["infographic"],
|
|
47
|
+
document: ["document", "doc"],
|
|
48
|
+
report: ["report"],
|
|
49
|
+
letter: ["letter", "cover letter"],
|
|
50
|
+
resume: ["resume", "cv", "curriculum vitae"],
|
|
47
51
|
imageGeneration: ["image", "picture", "prompt"],
|
|
48
52
|
videoGeneration: ["video", "clip", "reel"],
|
|
49
53
|
audioGeneration: ["audio", "sound", "song", "track"]
|
|
@@ -291,6 +295,9 @@ function templateSearchReads(query, budget = 10) {
|
|
|
291
295
|
}
|
|
292
296
|
return reads;
|
|
293
297
|
}
|
|
298
|
+
function templateDisplayTitle(title) {
|
|
299
|
+
return (title != null ? title : "").replace(/\\(['"])/g, "$1").replace(/\s+/g, " ").trim();
|
|
300
|
+
}
|
|
294
301
|
const STRUCTURAL_TAG = /^(canvas-[a-z-]+|video-studio|\d+:\d+|presentation|carousel|flyer|business-cards?|logo|banner|brochure|branding|social-post|certificate|worksheet|proposal|newsletter|menu|infographic)$/;
|
|
295
302
|
function templateSearchText(fields, titleComplete = true) {
|
|
296
303
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -486,4 +493,4 @@ function titleFromRowName(name, group) {
|
|
|
486
493
|
const parts = rest.split("-");
|
|
487
494
|
if (parts.length > 1) parts.pop();
|
|
488
495
|
return parts.join(" ");
|
|
489
|
-
}export{NON_WORD,TEMPLATE_CATEGORY_WORDS,parseTemplateQuery,rankTemplates,scoreTemplate,searchWords,stemWord,templateSearchReads,templateSearchText,titleFromRowName};//# sourceMappingURL=templateSearch.js.map
|
|
496
|
+
}export{NON_WORD,TEMPLATE_CATEGORY_WORDS,parseTemplateQuery,rankTemplates,scoreTemplate,searchWords,stemWord,templateDisplayTitle,templateSearchReads,templateSearchText,titleFromRowName};//# sourceMappingURL=templateSearch.js.map
|