@plebeiantech/lat.md 0.12.3-fork.14 → 0.12.3-fork.16
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/dist/src/cli/checklist-menu.d.ts +2 -1
- package/dist/src/cli/checklist-menu.js +3 -2
- package/dist/src/cli/index.js +47 -10
- package/dist/src/cli/init-preferences.d.ts +4 -0
- package/dist/src/cli/init-preferences.js +35 -0
- package/dist/src/cli/init.js +7 -1
- package/dist/src/cli/search.js +2 -7
- package/dist/src/cli/ui-build-server.d.ts +12 -0
- package/dist/src/cli/ui-build-server.js +26 -0
- package/dist/src/cli/ui-build.js +1 -1
- package/dist/src/cli/ui.js +1 -1
- package/dist/src/search/query.d.ts +5 -2
- package/dist/src/search/query.js +25 -21
- package/dist/src/source-formats.d.ts +1 -1
- package/dist/src/source-formats.js +2 -0
- package/dist/src/source-parser.js +200 -0
- package/dist/src/view/client/assets/GraphView-BuZg_wrj.js +456 -0
- package/dist/src/view/client/assets/{MarkdownEditor-B7quqPb8.js → MarkdownEditor-BKqJtZYv.js} +8 -8
- package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-CAu3KwfO.js +1 -0
- package/dist/src/view/client/assets/{arc-BnwR8Bu7.js → arc-CFnPZhKM.js} +1 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-Cf9Kd0OA.js +36 -0
- package/dist/src/view/client/assets/{blockDiagram-I7D4REHJ-DETl8e_H.js → blockDiagram-I7D4REHJ-dPn7g_vm.js} +2 -2
- package/dist/src/view/client/assets/{c4Diagram-7LVT6UL2-DJRAT1Ve.js → c4Diagram-7LVT6UL2-DdZrwaPd.js} +2 -2
- package/dist/src/view/client/assets/channel-C-byJRR7.js +1 -0
- package/dist/src/view/client/assets/{chunk-2Q5K7J3B-C0TmOC1Q.js → chunk-2Q5K7J3B-C42JuteH.js} +1 -1
- package/dist/src/view/client/assets/{chunk-5VM5RSS4-dfBOrYE6.js → chunk-5VM5RSS4-BKK3z8Zy.js} +1 -1
- package/dist/src/view/client/assets/{chunk-F27PBJKO-DAnks99K.js → chunk-F27PBJKO-qZl_uKcW.js} +1 -1
- package/dist/src/view/client/assets/{chunk-IMKFNOWR-CPjB07if.js → chunk-IMKFNOWR-Bs4Rnoj_.js} +1 -1
- package/dist/src/view/client/assets/{chunk-JWPE2WC7-VvU_gZI6.js → chunk-JWPE2WC7-BpxgV2rA.js} +1 -1
- package/dist/src/view/client/assets/{chunk-POPQ4Y6H-DDUbVF55.js → chunk-POPQ4Y6H-hIynofdE.js} +1 -1
- package/dist/src/view/client/assets/{chunk-SVP7TREG-BHROkr6D.js → chunk-SVP7TREG-t3gKMqeu.js} +1 -1
- package/dist/src/view/client/assets/{chunk-TICWLB2K-95PzGIOg.js → chunk-TICWLB2K-B2x394mh.js} +1 -1
- package/dist/src/view/client/assets/{chunk-XXDRQBXY-MdmuLhIs.js → chunk-XXDRQBXY-CHaVKDsH.js} +1 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-FlqGrEwv.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-FlqGrEwv.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-DE2-Jgqu.js +1 -0
- package/dist/src/view/client/assets/{cynefin-OW5HDTMX-CeA8IKWo.js → cynefin-OW5HDTMX-BsEtOvRy.js} +1 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-BKYG1Xs8.js +62 -0
- package/dist/src/view/client/assets/{dagre-GXQ25YYZ-DLQwTa3H.js → dagre-GXQ25YYZ-hgrdNjl7.js} +2 -2
- package/dist/src/view/client/assets/{diagram-S7CK7UJ4-kbKdIyXG.js → diagram-S7CK7UJ4-VIx8zAxf.js} +2 -2
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-yfloehRm.js +41 -0
- package/dist/src/view/client/assets/{diagram-VSXAHHWV-EXJTU8qq.js → diagram-VSXAHHWV-BT_dA4Q9.js} +2 -2
- package/dist/src/view/client/assets/diagram-VX7I27RA-Gfmwxx6u.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-C2yM7EOo.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-Bkb_Lj59.js +1 -0
- package/dist/src/view/client/assets/{erDiagram-RLTQ6QDP-C925J5A3.js → erDiagram-RLTQ6QDP-C7wQHPye.js} +2 -2
- package/dist/src/view/client/assets/{flowDiagram-HODETNUW-DzoCa-Nq.js → flowDiagram-HODETNUW-CXoKr3oI.js} +1 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-DqqXKgLa.js +292 -0
- package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-D_DAhSgZ.js +106 -0
- package/dist/src/view/client/assets/index-DAxFk0q-.css +1 -0
- package/dist/src/view/client/assets/index-DPuOWFj2.js +10 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-B50EOats.js +2 -0
- package/dist/src/view/client/assets/{ishikawaDiagram-5VMMS53U-CW4mto2d.js → ishikawaDiagram-5VMMS53U-D1rny9gj.js} +2 -2
- package/dist/src/view/client/assets/{journeyDiagram-3NMN7TZE-8R4eacFW.js → journeyDiagram-3NMN7TZE-B5UD2Xo4.js} +2 -2
- package/dist/src/view/client/assets/{kanban-definition-UXKFOSKX-Cy9ioXEJ.js → kanban-definition-UXKFOSKX-CTgey9zw.js} +6 -6
- package/dist/src/view/client/assets/{layout-C0MFuhth.js → layout-4X2n4os-.js} +1 -1
- package/dist/src/view/client/assets/{linear-Dv3N4dQR.js → linear-D0RIBXsp.js} +1 -1
- package/dist/src/view/client/assets/{maplibre-gl-DnqZgfUS.js → maplibre-gl-CDX6Zuow.js} +1 -1
- package/dist/src/view/client/assets/{mermaid.core-bds9A7e2.js → mermaid.core-BAnH8y-D.js} +11 -11
- package/dist/src/view/client/assets/{mindmap-definition-YA3MSWOX-DjmGW355.js → mindmap-definition-YA3MSWOX-WiFsh3Jg.js} +2 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-DCJOrckP.js +1 -0
- package/dist/src/view/client/assets/{pieDiagram-E7YTZNPT-CCH2gGR-.js → pieDiagram-E7YTZNPT-C78IkUE2.js} +2 -2
- package/dist/src/view/client/assets/{quadrantDiagram-AXDQQJYC-CjocPJFz.js → quadrantDiagram-AXDQQJYC-xZ6guleB.js} +4 -4
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-D3PwmgX0.js +1 -0
- package/dist/src/view/client/assets/{requirementDiagram-BXWQKSXE-Ct6AoXRr.js → requirementDiagram-BXWQKSXE-v-I8wLGH.js} +2 -2
- package/dist/src/view/client/assets/{sankeyDiagram-P5KCCOFB-CIpgGN_w.js → sankeyDiagram-P5KCCOFB-DBY-sdO7.js} +2 -2
- package/dist/src/view/client/assets/{sequenceDiagram-WJ2MYXX4-DrmLFj6w.js → sequenceDiagram-WJ2MYXX4-D9HApBFi.js} +2 -2
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-ERAytLnQ.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-BKef_Qwv.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-BePfayWI.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-D7dS_tnF.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-DaqCEguT.js +8 -0
- package/dist/src/view/client/assets/{timeline-definition-24CTP7MA-BExPu6X5.js → timeline-definition-24CTP7MA-Di1UCseG.js} +2 -2
- package/dist/src/view/client/assets/{vennDiagram-4TSXK5OY-PC1MU3si.js → vennDiagram-4TSXK5OY-g7Je3H2H.js} +2 -2
- package/dist/src/view/client/assets/{wardleyDiagram-VM6X3IG4-DNWqU3fa.js → wardleyDiagram-VM6X3IG4-C_diPEka.js} +2 -2
- package/dist/src/view/client/assets/{xychartDiagram-S5SC5T6Z-E1uA28_D.js → xychartDiagram-S5SC5T6Z-C8uIQy_I.js} +2 -2
- package/dist/src/view/client/index.html +2 -2
- package/dist/src/view/document-route.d.ts +2 -0
- package/dist/src/view/document-route.js +40 -7
- package/dist/src/view/graph.d.ts +2 -2
- package/dist/src/view/graph.js +7 -3
- package/dist/src/view/highlight.js +205 -203
- package/dist/src/view/markdown.js +4 -0
- package/dist/src/view/preindexed-search.d.ts +15 -0
- package/dist/src/view/preindexed-search.js +25 -0
- package/dist/src/view/protocol.d.ts +3 -0
- package/dist/src/view/references.js +3 -4
- package/dist/src/view/search-result.d.ts +4 -0
- package/dist/src/view/search-result.js +20 -0
- package/dist/src/view/search.d.ts +7 -2
- package/dist/src/view/search.js +23 -30
- package/dist/src/view/server-build.d.ts +21 -0
- package/dist/src/view/server-build.js +145 -0
- package/dist/src/view/server-deployment.d.ts +32 -0
- package/dist/src/view/server-deployment.js +133 -0
- package/dist/src/view/server-index-worker.d.ts +6 -0
- package/dist/src/view/server-index-worker.js +14 -0
- package/dist/src/view/server.d.ts +1 -1
- package/dist/src/view/server.js +26 -8
- package/dist/src/view/static-build.d.ts +16 -1
- package/dist/src/view/static-build.js +187 -89
- package/dist/src/view/static-protocol.d.ts +7 -0
- package/dist/src/view/static-protocol.js +5 -0
- package/dist/src/view/store.js +14 -4
- package/dist/src/view/vercel-build.d.ts +24 -0
- package/dist/src/view/vercel-build.js +133 -0
- package/dist/src/view/vercel-server-build.d.ts +10 -0
- package/dist/src/view/vercel-server-build.js +61 -0
- package/dist/vendor/lat.md-server/cli.d.ts +2 -0
- package/dist/vendor/lat.md-server/cli.js +12 -0
- package/dist/vendor/lat.md-server/index.d.ts +38 -0
- package/dist/vendor/lat.md-server/index.js +128 -0
- package/package.json +19 -5
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-V7-T6qsl.js +0 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +0 -36
- package/dist/src/view/client/assets/channel-BwQbnWCN.js +0 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +0 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +0 -62
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +0 -41
- package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +0 -24
- package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +0 -24
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +0 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +0 -292
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +0 -106
- package/dist/src/view/client/assets/index-D0ajr_Ja.css +0 -1
- package/dist/src/view/client/assets/index-KZcnpXJH.js +0 -321
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +0 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +0 -1
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +0 -1
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +0 -1
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +0 -1
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +0 -8
- /package/dist/src/view/client/assets/{logo-small-RR_KBOAT.svg → logo-RR_KBOAT.svg} +0 -0
|
@@ -18,6 +18,7 @@ const CODE_LINK_CLASSES = [
|
|
|
18
18
|
'code-language-ts',
|
|
19
19
|
'code-language-js',
|
|
20
20
|
'code-language-py',
|
|
21
|
+
'code-language-rb',
|
|
21
22
|
'code-language-rs',
|
|
22
23
|
'code-language-go',
|
|
23
24
|
'code-language-c',
|
|
@@ -323,6 +324,9 @@ function codeLanguage(target) {
|
|
|
323
324
|
return { className: 'code-language-js', label: 'JS' };
|
|
324
325
|
case '.py':
|
|
325
326
|
return { className: 'code-language-py', label: 'PY' };
|
|
327
|
+
case '.rake':
|
|
328
|
+
case '.rb':
|
|
329
|
+
return { className: 'code-language-rb', label: 'RB' };
|
|
326
330
|
case '.rs':
|
|
327
331
|
return { className: 'code-language-rs', label: 'RS' };
|
|
328
332
|
case '.go':
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Section } from '../lattice-model.js';
|
|
2
|
+
import type { CreateSearchEngine } from '../search/embedder.js';
|
|
3
|
+
import { type IndexedSearchSession } from '../search/query.js';
|
|
4
|
+
import type { ViewSearchResponse } from './protocol.js';
|
|
5
|
+
export type PreindexedViewSearchDependencies = {
|
|
6
|
+
openSearchSession: (latDir: string, options: {
|
|
7
|
+
cacheDir?: string;
|
|
8
|
+
createSearchEngine?: CreateSearchEngine;
|
|
9
|
+
}) => Promise<IndexedSearchSession>;
|
|
10
|
+
};
|
|
11
|
+
export type PreindexedViewSearch = ((query: string) => Promise<ViewSearchResponse>) & {
|
|
12
|
+
close: () => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
/** Serve a built search index without importing indexing or Markdown parsers. */
|
|
15
|
+
export declare function createPreindexedViewSearch(latDir: string, cacheDir: string, sections: readonly Section[], documentPaths: ReadonlyMap<string, string>, dependencies?: PreindexedViewSearchDependencies, createSearchEngine?: CreateSearchEngine): Promise<PreindexedViewSearch>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { openIndexedSearchSession, resolveSearchMatches, } from '../search/query.js';
|
|
2
|
+
import { viewSearchResult } from './search-result.js';
|
|
3
|
+
const VIEW_SEARCH_LIMIT = 10;
|
|
4
|
+
/** Serve a built search index without importing indexing or Markdown parsers. */
|
|
5
|
+
export async function createPreindexedViewSearch(latDir, cacheDir, sections, documentPaths, dependencies = {
|
|
6
|
+
openSearchSession: openIndexedSearchSession,
|
|
7
|
+
}, createSearchEngine) {
|
|
8
|
+
const sectionById = new Map(sections.map((section) => [section.id.toLowerCase(), section]));
|
|
9
|
+
const session = await dependencies.openSearchSession(latDir, {
|
|
10
|
+
cacheDir,
|
|
11
|
+
createSearchEngine,
|
|
12
|
+
});
|
|
13
|
+
const search = async (rawQuery) => {
|
|
14
|
+
const query = rawQuery.trim();
|
|
15
|
+
if (!query)
|
|
16
|
+
return { query: '', results: [] };
|
|
17
|
+
const results = await session.search(query, VIEW_SEARCH_LIMIT);
|
|
18
|
+
return {
|
|
19
|
+
query,
|
|
20
|
+
results: resolveSearchMatches(results, sectionById).map((match) => viewSearchResult(latDir, match, documentPaths)),
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
search.close = session.close;
|
|
24
|
+
return search;
|
|
25
|
+
}
|
|
@@ -9,6 +9,8 @@ export type ViewExternalFile = {
|
|
|
9
9
|
};
|
|
10
10
|
export type ViewIndex = {
|
|
11
11
|
files: string[];
|
|
12
|
+
/** Authored directory-index entries, keyed by vault-relative directory ('' at root). */
|
|
13
|
+
directoryOrder: Record<string, string[]>;
|
|
12
14
|
externalFiles: ViewExternalFile[];
|
|
13
15
|
entry: string;
|
|
14
16
|
errorCounts: Record<string, number>;
|
|
@@ -73,6 +75,7 @@ export type ViewGraphNode = {
|
|
|
73
75
|
label: string;
|
|
74
76
|
url: string;
|
|
75
77
|
breadcrumbs: string[];
|
|
78
|
+
/** Local documents sum direct backlink counts across every heading. Other nodes use incoming edge weights. */
|
|
76
79
|
inDegree: number;
|
|
77
80
|
outDegree: number;
|
|
78
81
|
documentPath?: string;
|
|
@@ -34,20 +34,19 @@ export function linkedSection(url, sourcePath, sectionsByPath) {
|
|
|
34
34
|
.join('/');
|
|
35
35
|
let destination;
|
|
36
36
|
try {
|
|
37
|
-
destination = new URL(url, `http://lat.local
|
|
37
|
+
destination = new URL(url, `http://lat.local/${encodedSourcePath}`);
|
|
38
38
|
}
|
|
39
39
|
catch {
|
|
40
40
|
return null;
|
|
41
41
|
}
|
|
42
|
-
if (destination.origin !== 'http://lat.local'
|
|
43
|
-
!destination.pathname.startsWith('/docs/')) {
|
|
42
|
+
if (destination.origin !== 'http://lat.local') {
|
|
44
43
|
return null;
|
|
45
44
|
}
|
|
46
45
|
let path;
|
|
47
46
|
let fragment;
|
|
48
47
|
try {
|
|
49
48
|
path = destination.pathname
|
|
50
|
-
.slice(
|
|
49
|
+
.slice(1)
|
|
51
50
|
.split('/')
|
|
52
51
|
.map(decodeURIComponent)
|
|
53
52
|
.join('/');
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SectionMatch } from '../lattice-model.js';
|
|
2
|
+
import type { ViewSearchResult } from './protocol.js';
|
|
3
|
+
/** Convert one graph section match into the browser search protocol. */
|
|
4
|
+
export declare function viewSearchResult(latDir: string, match: SectionMatch, documentPaths?: ReadonlyMap<string, string>): ViewSearchResult;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dirname, relative, resolve } from 'node:path';
|
|
2
|
+
import { toPosix } from '../path.js';
|
|
3
|
+
import { documentUrl } from './document-route.js';
|
|
4
|
+
/** Convert one graph section match into the browser search protocol. */
|
|
5
|
+
export function viewSearchResult(latDir, match, documentPaths) {
|
|
6
|
+
const section = match.section;
|
|
7
|
+
const projectRoot = dirname(latDir);
|
|
8
|
+
const path = documentPaths?.get(section.id.toLowerCase()) ??
|
|
9
|
+
toPosix(relative(latDir, resolve(projectRoot, section.filePath)));
|
|
10
|
+
const fileBreadcrumbs = path.replace(/\.md$/i, '').split('/');
|
|
11
|
+
return {
|
|
12
|
+
sectionId: section.id,
|
|
13
|
+
title: section.heading,
|
|
14
|
+
path,
|
|
15
|
+
breadcrumbs: [...fileBreadcrumbs, ...section.id.split('#').slice(1)],
|
|
16
|
+
description: section.firstParagraph,
|
|
17
|
+
url: documentUrl(path, section.githubSlug ?? ''),
|
|
18
|
+
score: match.score ?? 0,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SectionMatch } from '../lattice-model.js';
|
|
1
|
+
import type { Section, SectionMatch } from '../lattice-model.js';
|
|
2
2
|
import type { ViewSearchResponse } from './protocol.js';
|
|
3
3
|
export type ViewSearch = (query: string) => Promise<ViewSearchResponse>;
|
|
4
4
|
export type ViewSearchDependencies = {
|
|
@@ -11,4 +11,9 @@ export type ViewSearchDependencies = {
|
|
|
11
11
|
}>;
|
|
12
12
|
};
|
|
13
13
|
/** Create the lazily indexed semantic search service used by `lat ui`. */
|
|
14
|
-
export declare function createViewSearch(latDir: string, dependencies?: ViewSearchDependencies, getGeneration?: () => number
|
|
14
|
+
export declare function createViewSearch(latDir: string, dependencies?: ViewSearchDependencies, getGeneration?: () => number, options?: {
|
|
15
|
+
cacheDir?: string;
|
|
16
|
+
preindexed?: boolean;
|
|
17
|
+
sections?: readonly Section[];
|
|
18
|
+
documentPaths?: ReadonlyMap<string, string>;
|
|
19
|
+
}): ViewSearch;
|
package/dist/src/view/search.js
CHANGED
|
@@ -1,41 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { toPosix } from '../path.js';
|
|
3
|
-
import { documentUrl } from './document-route.js';
|
|
1
|
+
import { viewSearchResult } from './search-result.js';
|
|
4
2
|
const VIEW_SEARCH_LIMIT = 10;
|
|
5
|
-
|
|
6
|
-
async runIndex(latDir) {
|
|
7
|
-
const { runIndex } = await import('../cli/search.js');
|
|
8
|
-
await runIndex(latDir);
|
|
9
|
-
},
|
|
10
|
-
async runSearch(latDir, query, limit, options) {
|
|
11
|
-
const { runSearch } = await import('../cli/search.js');
|
|
12
|
-
return runSearch(latDir, query, limit, undefined, options);
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
function viewSearchResult(latDir, match) {
|
|
16
|
-
const section = match.section;
|
|
17
|
-
const projectRoot = dirname(latDir);
|
|
18
|
-
const path = toPosix(relative(latDir, resolve(projectRoot, section.filePath)));
|
|
19
|
-
const fileBreadcrumbs = path.replace(/\.md$/i, '').split('/');
|
|
3
|
+
function defaultDependencies(cacheDir, sectionById) {
|
|
20
4
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
async runIndex(latDir) {
|
|
6
|
+
const { runIndex } = await import('../cli/search.js');
|
|
7
|
+
await runIndex(latDir, undefined, undefined, { cacheDir });
|
|
8
|
+
},
|
|
9
|
+
async runSearch(latDir, query, limit, options) {
|
|
10
|
+
const { runSearch } = await import('../cli/search.js');
|
|
11
|
+
return runSearch(latDir, query, limit, undefined, {
|
|
12
|
+
...options,
|
|
13
|
+
cacheDir,
|
|
14
|
+
sectionById,
|
|
15
|
+
});
|
|
16
|
+
},
|
|
28
17
|
};
|
|
29
18
|
}
|
|
30
19
|
/** Create the lazily indexed semantic search service used by `lat ui`. */
|
|
31
|
-
export function createViewSearch(latDir, dependencies
|
|
20
|
+
export function createViewSearch(latDir, dependencies, getGeneration = () => 0, options = {}) {
|
|
21
|
+
const sectionById = options.sections
|
|
22
|
+
? new Map(options.sections.map((section) => [section.id.toLowerCase(), section]))
|
|
23
|
+
: undefined;
|
|
24
|
+
const resolvedDependencies = dependencies ?? defaultDependencies(options.cacheDir, sectionById);
|
|
32
25
|
let indexReady = null;
|
|
33
|
-
let indexedGeneration = -1;
|
|
26
|
+
let indexedGeneration = options.preindexed ? getGeneration() : -1;
|
|
34
27
|
const prepareIndex = async () => {
|
|
35
28
|
while (indexedGeneration < getGeneration() || indexedGeneration < 0) {
|
|
36
29
|
if (!indexReady) {
|
|
37
30
|
const generation = getGeneration();
|
|
38
|
-
indexReady =
|
|
31
|
+
indexReady = resolvedDependencies
|
|
39
32
|
.runIndex(latDir)
|
|
40
33
|
.then(() => {
|
|
41
34
|
indexedGeneration = Math.max(indexedGeneration, generation);
|
|
@@ -52,10 +45,10 @@ export function createViewSearch(latDir, dependencies = defaultDependencies, get
|
|
|
52
45
|
if (!query)
|
|
53
46
|
return { query: '', results: [] };
|
|
54
47
|
await prepareIndex();
|
|
55
|
-
const search = await
|
|
48
|
+
const search = await resolvedDependencies.runSearch(latDir, query, VIEW_SEARCH_LIMIT, { buildIndex: false });
|
|
56
49
|
return {
|
|
57
50
|
query: search.query,
|
|
58
|
-
results: search.matches.map((match) => viewSearchResult(latDir, match)),
|
|
51
|
+
results: search.matches.map((match) => viewSearchResult(latDir, match, options.documentPaths)),
|
|
59
52
|
};
|
|
60
53
|
};
|
|
61
54
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getLatServerVersion } from '../../vendor/lat.md-server/index.js';
|
|
2
|
+
import type { CmdContext } from '../context.js';
|
|
3
|
+
import { analyzeMarkdownProject, type MarkdownProjectAnalysis } from '../project-analysis.js';
|
|
4
|
+
import { getLocalVersion } from '../version.js';
|
|
5
|
+
import { buildStaticView, type StaticViewBuildOptions, type StaticViewBuildResult } from './static-build.js';
|
|
6
|
+
export type ServerViewBuildOptions = Omit<StaticViewBuildOptions, 'searchApi'>;
|
|
7
|
+
export type ServerViewBuildResult = StaticViewBuildResult;
|
|
8
|
+
export type ServerViewBuildDependencies = {
|
|
9
|
+
analyzeMarkdownProject: typeof analyzeMarkdownProject;
|
|
10
|
+
buildStaticView: typeof buildStaticView;
|
|
11
|
+
getLocalVersion: typeof getLocalVersion;
|
|
12
|
+
getLatServerVersion: typeof getLatServerVersion;
|
|
13
|
+
getPackageVersion: typeof getPackageVersion;
|
|
14
|
+
buildSearchIndex: typeof buildServerSearchIndex;
|
|
15
|
+
};
|
|
16
|
+
/** Wait for the index process to exit so native handles cannot lock staging. */
|
|
17
|
+
export declare function buildServerSearchIndex(latDir: string, project: MarkdownProjectAnalysis, cacheDir: string): Promise<void>;
|
|
18
|
+
declare function getPackageVersion(name: string): string;
|
|
19
|
+
/** Build immutable UI data plus the small portable Express search service. */
|
|
20
|
+
export declare function buildServerView(ctx: CmdContext, requestedOutput: string, options?: ServerViewBuildOptions, dependencies?: ServerViewBuildDependencies): Promise<ServerViewBuildResult>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fork } from 'node:child_process';
|
|
3
|
+
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { getLatServerVersion } from '../../vendor/lat.md-server/index.js';
|
|
7
|
+
import { analyzeMarkdownProject, } from '../project-analysis.js';
|
|
8
|
+
import { getLocalVersion } from '../version.js';
|
|
9
|
+
import { toPosix } from '../path.js';
|
|
10
|
+
import { buildStaticView, moveViewBuildOutput, removeViewBuildStaging, normalizeStaticViewBasePath, validateViewBuildOutput, } from './static-build.js';
|
|
11
|
+
import { SERVER_VIEW_SCHEMA_VERSION, } from './server-deployment.js';
|
|
12
|
+
const defaultDependencies = {
|
|
13
|
+
analyzeMarkdownProject,
|
|
14
|
+
buildStaticView,
|
|
15
|
+
getLocalVersion,
|
|
16
|
+
getLatServerVersion,
|
|
17
|
+
getPackageVersion,
|
|
18
|
+
buildSearchIndex: buildServerSearchIndex,
|
|
19
|
+
};
|
|
20
|
+
/** Wait for the index process to exit so native handles cannot lock staging. */
|
|
21
|
+
export function buildServerSearchIndex(latDir, project, cacheDir) {
|
|
22
|
+
const sourceRuntime = import.meta.url.endsWith('.ts');
|
|
23
|
+
const child = fork(new URL(sourceRuntime ? './server-index-worker.ts' : './server-index-worker.js', import.meta.url), [], {
|
|
24
|
+
execArgv: sourceRuntime ? ['--import', 'tsx'] : [],
|
|
25
|
+
serialization: 'advanced',
|
|
26
|
+
stdio: ['ignore', 'ignore', 'pipe', 'ipc'],
|
|
27
|
+
});
|
|
28
|
+
return new Promise((resolveIndex, reject) => {
|
|
29
|
+
let stderr = '';
|
|
30
|
+
let sendError = null;
|
|
31
|
+
child.stderr.setEncoding('utf8');
|
|
32
|
+
child.stderr.on('data', (chunk) => {
|
|
33
|
+
stderr = (stderr + chunk).slice(-64_000);
|
|
34
|
+
});
|
|
35
|
+
child.once('error', reject);
|
|
36
|
+
child.once('close', (code, signal) => {
|
|
37
|
+
if (sendError)
|
|
38
|
+
reject(sendError);
|
|
39
|
+
else if (code === 0)
|
|
40
|
+
resolveIndex();
|
|
41
|
+
else {
|
|
42
|
+
reject(new Error(`Server search indexing failed (${signal ?? code}): ${stderr.trim()}`));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
child.send({ latDir, project, cacheDir }, (error) => {
|
|
46
|
+
if (error) {
|
|
47
|
+
sendError = error;
|
|
48
|
+
child.kill();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function getPackageVersion(name) {
|
|
54
|
+
let directory = dirname(fileURLToPath(import.meta.resolve(name)));
|
|
55
|
+
while (true) {
|
|
56
|
+
try {
|
|
57
|
+
const manifest = JSON.parse(readFileSync(join(directory, 'package.json'), 'utf8'));
|
|
58
|
+
if (manifest.name === name && manifest.version)
|
|
59
|
+
return manifest.version;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error.code !== 'ENOENT')
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
const parent = dirname(directory);
|
|
66
|
+
if (parent === directory)
|
|
67
|
+
break;
|
|
68
|
+
directory = parent;
|
|
69
|
+
}
|
|
70
|
+
throw new Error(`Could not resolve package version: ${name}`);
|
|
71
|
+
}
|
|
72
|
+
function appModule() {
|
|
73
|
+
return `import { createEmbedder } from '@lat.md/embed';
|
|
74
|
+
import minilm from '@lat.md/embed-minilm-fp16';
|
|
75
|
+
import express from 'express';
|
|
76
|
+
import { createServerViewApp } from 'lat.md/server';
|
|
77
|
+
const view = createServerViewApp({
|
|
78
|
+
app: express(),
|
|
79
|
+
manifestFile: new URL('./server-data/server.json', import.meta.url),
|
|
80
|
+
indexFile: new URL('./server-data/vectors.db', import.meta.url),
|
|
81
|
+
createSearchEngine: () => createEmbedder({ model: minilm }),
|
|
82
|
+
});
|
|
83
|
+
export const close = view.close;
|
|
84
|
+
export default view.app;
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
function packageManifest(latVersion, serverVersion, runtimeVersions) {
|
|
88
|
+
return `${JSON.stringify({
|
|
89
|
+
name: 'lat-ui-server',
|
|
90
|
+
private: true,
|
|
91
|
+
type: 'module',
|
|
92
|
+
scripts: { start: 'lat-ui-server app.mjs' },
|
|
93
|
+
dependencies: {
|
|
94
|
+
'@lat.md/embed': runtimeVersions.embed,
|
|
95
|
+
'@lat.md/embed-minilm-fp16': runtimeVersions.model,
|
|
96
|
+
'../../vendor/lat.md-server/index.js': serverVersion,
|
|
97
|
+
express: runtimeVersions.express,
|
|
98
|
+
'lat.md': latVersion,
|
|
99
|
+
},
|
|
100
|
+
}, null, 2)}\n`;
|
|
101
|
+
}
|
|
102
|
+
/** Build immutable UI data plus the small portable Express search service. */
|
|
103
|
+
export async function buildServerView(ctx, requestedOutput, options = {}, dependencies = defaultDependencies) {
|
|
104
|
+
const outputDir = resolve(ctx.projectRoot, requestedOutput);
|
|
105
|
+
const basePath = normalizeStaticViewBasePath(options.basePath ?? '/');
|
|
106
|
+
await validateViewBuildOutput(outputDir, ctx.projectRoot, 'Server', options.force);
|
|
107
|
+
await mkdir(dirname(outputDir), { recursive: true });
|
|
108
|
+
const stagingDir = await mkdtemp(join(dirname(outputDir), '.lat-server-staging-'));
|
|
109
|
+
try {
|
|
110
|
+
const publicDir = join(stagingDir, 'public');
|
|
111
|
+
const dataDir = join(stagingDir, 'server-data');
|
|
112
|
+
const staticResult = await dependencies.buildStaticView(ctx, publicDir, {
|
|
113
|
+
...options,
|
|
114
|
+
basePath,
|
|
115
|
+
searchApi: `${basePath}api/search`,
|
|
116
|
+
});
|
|
117
|
+
const project = await dependencies.analyzeMarkdownProject(ctx.latDir, ctx.projectRoot, { executor: 'auto' });
|
|
118
|
+
await dependencies.buildSearchIndex(ctx.latDir, project, dataDir);
|
|
119
|
+
const sections = project.sections.map(({ children: _children, ...section }) => ({
|
|
120
|
+
...section,
|
|
121
|
+
documentPath: toPosix(relative(ctx.latDir, resolve(ctx.projectRoot, section.filePath))),
|
|
122
|
+
}));
|
|
123
|
+
const manifest = {
|
|
124
|
+
version: SERVER_VIEW_SCHEMA_VERSION,
|
|
125
|
+
basePath,
|
|
126
|
+
sections,
|
|
127
|
+
};
|
|
128
|
+
await writeFile(join(dataDir, 'server.json'), `${JSON.stringify(manifest)}\n`);
|
|
129
|
+
await writeFile(join(stagingDir, 'app.mjs'), appModule());
|
|
130
|
+
await writeFile(join(stagingDir, 'package.json'), packageManifest(dependencies.getLocalVersion(), dependencies.getLatServerVersion(), {
|
|
131
|
+
embed: dependencies.getPackageVersion('@lat.md/embed'),
|
|
132
|
+
express: dependencies.getPackageVersion('express'),
|
|
133
|
+
model: dependencies.getPackageVersion('@lat.md/embed-minilm-fp16'),
|
|
134
|
+
}));
|
|
135
|
+
if (options.force) {
|
|
136
|
+
await rm(outputDir, { recursive: true, force: true });
|
|
137
|
+
}
|
|
138
|
+
await moveViewBuildOutput(stagingDir, outputDir);
|
|
139
|
+
return { ...staticResult, outputDir };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
await removeViewBuildStaging(stagingDir);
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type LatServerApp } from '../../vendor/lat.md-server/index.js';
|
|
2
|
+
import type { Express } from 'express';
|
|
3
|
+
import type { Section } from '../lattice-model.js';
|
|
4
|
+
import type { CreateSearchEngine } from '../search/embedder.js';
|
|
5
|
+
import type { ViewSearchResponse } from './protocol.js';
|
|
6
|
+
export declare const SERVER_VIEW_SCHEMA_VERSION = 1;
|
|
7
|
+
export type ServerViewSection = Omit<Section, 'children'> & {
|
|
8
|
+
documentPath: string;
|
|
9
|
+
};
|
|
10
|
+
export type ServerViewManifest = {
|
|
11
|
+
version: number;
|
|
12
|
+
basePath: string;
|
|
13
|
+
sections: ServerViewSection[];
|
|
14
|
+
};
|
|
15
|
+
export type ServerViewAppOptions = {
|
|
16
|
+
app: Express;
|
|
17
|
+
manifestFile: string | URL;
|
|
18
|
+
indexFile: string | URL;
|
|
19
|
+
cacheDir?: string | URL;
|
|
20
|
+
createSearchEngine?: CreateSearchEngine;
|
|
21
|
+
search?: (query: string) => Promise<ViewSearchResponse>;
|
|
22
|
+
};
|
|
23
|
+
export type ServerViewApp = {
|
|
24
|
+
app: LatServerApp;
|
|
25
|
+
close: () => Promise<void>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Create the portable Express application emitted by `lat ui build server`.
|
|
29
|
+
* Static assets are also mounted for ordinary Node hosts; platforms with a CDN
|
|
30
|
+
* can serve `public/` directly and forward only the search route to this app.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createServerViewApp(options: ServerViewAppOptions): ServerViewApp;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { copyFile, mkdir, mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createLatServerApp } from '../../vendor/lat.md-server/index.js';
|
|
6
|
+
import { createPreindexedViewSearch, } from './preindexed-search.js';
|
|
7
|
+
export const SERVER_VIEW_SCHEMA_VERSION = 1;
|
|
8
|
+
function searchRoute(basePath) {
|
|
9
|
+
return `${basePath === '/' ? '' : basePath.slice(0, -1)}/api/search`;
|
|
10
|
+
}
|
|
11
|
+
function sendJson(res, status, value, headOnly) {
|
|
12
|
+
const body = JSON.stringify(value);
|
|
13
|
+
res.statusCode = status;
|
|
14
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
15
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
16
|
+
res.setHeader('Content-Length', Buffer.byteLength(body));
|
|
17
|
+
res.end(headOnly ? undefined : body);
|
|
18
|
+
}
|
|
19
|
+
function localPath(path) {
|
|
20
|
+
return resolve(typeof path === 'string' ? path : fileURLToPath(path));
|
|
21
|
+
}
|
|
22
|
+
async function readManifest(path) {
|
|
23
|
+
const manifest = JSON.parse(await readFile(path, 'utf8'));
|
|
24
|
+
if (manifest.version !== SERVER_VIEW_SCHEMA_VERSION ||
|
|
25
|
+
typeof manifest.basePath !== 'string' ||
|
|
26
|
+
!Array.isArray(manifest.sections)) {
|
|
27
|
+
throw new Error(`Unsupported Lat server build manifest: ${path}`);
|
|
28
|
+
}
|
|
29
|
+
return manifest;
|
|
30
|
+
}
|
|
31
|
+
/** Native SQLite handles may outlive close until the Windows process exits. */
|
|
32
|
+
async function removeRuntimeCache(path) {
|
|
33
|
+
try {
|
|
34
|
+
await rm(path, {
|
|
35
|
+
recursive: true,
|
|
36
|
+
force: true,
|
|
37
|
+
maxRetries: 10,
|
|
38
|
+
retryDelay: 150,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const code = error.code;
|
|
43
|
+
if (process.platform !== 'win32' ||
|
|
44
|
+
(code !== 'EBUSY' && code !== 'EPERM' && code !== 'ENOTEMPTY')) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
// This is an owned OS-temp copy, never the deployed index or user data.
|
|
48
|
+
// A lingering native lock must not fail otherwise successful shutdown.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function prepareServerView(options, manifestFile, indexFile) {
|
|
52
|
+
const manifest = await readManifest(manifestFile);
|
|
53
|
+
let runtimeCacheDir = options.cacheDir ? localPath(options.cacheDir) : '';
|
|
54
|
+
let ownsCache = false;
|
|
55
|
+
let search = options.search;
|
|
56
|
+
let ownedSearch;
|
|
57
|
+
if (!search) {
|
|
58
|
+
if (!runtimeCacheDir) {
|
|
59
|
+
runtimeCacheDir = await mkdtemp(join(tmpdir(), 'lat-ui-search-'));
|
|
60
|
+
ownsCache = true;
|
|
61
|
+
}
|
|
62
|
+
await mkdir(runtimeCacheDir, { recursive: true });
|
|
63
|
+
try {
|
|
64
|
+
await copyFile(indexFile, join(runtimeCacheDir, 'vectors.db'));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (ownsCache) {
|
|
68
|
+
await removeRuntimeCache(runtimeCacheDir);
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
const documentPaths = new Map();
|
|
73
|
+
const sections = manifest.sections.map(({ documentPath, ...section }) => {
|
|
74
|
+
documentPaths.set(section.id.toLowerCase(), documentPath);
|
|
75
|
+
return { ...section, children: [] };
|
|
76
|
+
});
|
|
77
|
+
ownedSearch = await createPreindexedViewSearch(dirname(indexFile), runtimeCacheDir, sections, documentPaths, undefined, options.createSearchEngine);
|
|
78
|
+
search = ownedSearch;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
manifest,
|
|
82
|
+
search,
|
|
83
|
+
close: async () => {
|
|
84
|
+
try {
|
|
85
|
+
await ownedSearch?.close();
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
if (ownsCache)
|
|
89
|
+
await removeRuntimeCache(runtimeCacheDir);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create the portable Express application emitted by `lat ui build server`.
|
|
96
|
+
* Static assets are also mounted for ordinary Node hosts; platforms with a CDN
|
|
97
|
+
* can serve `public/` directly and forward only the search route to this app.
|
|
98
|
+
*/
|
|
99
|
+
export function createServerViewApp(options) {
|
|
100
|
+
const manifestFile = localPath(options.manifestFile);
|
|
101
|
+
const publicDir = resolve(dirname(manifestFile), '..', 'public');
|
|
102
|
+
const prepared = prepareServerView(options, manifestFile, localPath(options.indexFile));
|
|
103
|
+
const app = createLatServerApp({
|
|
104
|
+
publicDir,
|
|
105
|
+
async handle(req, res, next) {
|
|
106
|
+
const { manifest, search } = await prepared;
|
|
107
|
+
const method = req.method ?? 'GET';
|
|
108
|
+
const headOnly = method === 'HEAD';
|
|
109
|
+
if (method !== 'GET' && !headOnly)
|
|
110
|
+
return next();
|
|
111
|
+
const url = new URL(req.url ?? '/', 'http://lat.local');
|
|
112
|
+
if (url.pathname !== searchRoute(manifest.basePath))
|
|
113
|
+
return next();
|
|
114
|
+
try {
|
|
115
|
+
const query = (url.searchParams.get('query') ?? '').trim();
|
|
116
|
+
if (query.length > 500) {
|
|
117
|
+
sendJson(res, 400, { error: 'Search query is too long' }, headOnly);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
sendJson(res, 200, await search(query), headOnly);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
next(error);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
}, options.app);
|
|
127
|
+
return {
|
|
128
|
+
app,
|
|
129
|
+
close: async () => {
|
|
130
|
+
await (await prepared).close();
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { runIndex } from '../cli/search.js';
|
|
2
|
+
process.once('message', async (request) => {
|
|
3
|
+
try {
|
|
4
|
+
await runIndex(request.latDir, undefined, request.project, {
|
|
5
|
+
cacheDir: request.cacheDir,
|
|
6
|
+
});
|
|
7
|
+
// Process exit releases native libsql handles before staging is renamed.
|
|
8
|
+
process.exit(0);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
console.error(error);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Server } from 'node:http';
|
|
2
|
-
import { type LatServerApp } from '
|
|
2
|
+
import { type LatServerApp } from '../../vendor/lat.md-server/index.js';
|
|
3
3
|
import { type CmdContext } from '../context.js';
|
|
4
4
|
import { type ViewSearch } from './search.js';
|
|
5
5
|
import { type ViewStore } from './store.js';
|