@plebeiantech/lat.md 0.12.3-fork.14 → 0.12.3-fork.15

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.
@@ -1,5 +1,5 @@
1
1
  import { type Server } from 'node:http';
2
- import { type LatServerApp } from '@lat.md/server';
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';
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { extname, join, relative, resolve, sep } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
- import { createLatServerApp, listenLatServer, } from '@lat.md/server';
5
+ import { createLatServerApp, listenLatServer, } from '../../vendor/lat.md-server/index.js';
6
6
  import { plainStyler } from '../context.js';
7
7
  import { sectionCommand } from '../cli/section.js';
8
8
  import { DEFAULT_VIEW_LOGO_TEXT, } from './protocol.js';
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { runLatServer } from './index.js';
5
+ const entry = process.argv[2];
6
+ if (!entry)
7
+ throw new Error('Usage: lat-ui-server <app-module>');
8
+ const module = (await import(pathToFileURL(resolve(entry)).href));
9
+ if (typeof module.default !== 'function') {
10
+ throw new Error(`${entry} must default-export an Express app`);
11
+ }
12
+ await runLatServer(module.default, { close: module.close });
@@ -0,0 +1,38 @@
1
+ import { type IncomingMessage, type RequestListener, type Server, type ServerResponse } from 'node:http';
2
+ import { type Express } from 'express';
3
+ export declare const LAT_UI_CONTENT_SECURITY_POLICY = "default-src 'self'; connect-src 'self' https://tiles.openfreemap.org; font-src 'self' data:; img-src 'self' data: https://github.githubassets.com; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
4
+ export type LatServerAppOptions = {
5
+ /** Handle dynamic routes before immutable files and fallback handlers. */
6
+ handle?: LatServerRequestHandler;
7
+ /** Serve a completed Lat UI export after dynamic routes. */
8
+ publicDir?: string;
9
+ };
10
+ export type LatServerApp = RequestListener;
11
+ export type LatServerRequestHandler = (req: IncomingMessage, res: ServerResponse, next: (error?: unknown) => void) => void | Promise<void>;
12
+ export type ListenLatServerOptions = {
13
+ host: string;
14
+ port: number;
15
+ /** Advance through occupied ports. Explicit user ports should leave this off. */
16
+ findAvailablePort?: boolean;
17
+ };
18
+ export type RunningLatServer = {
19
+ server: Server;
20
+ host: string;
21
+ port: number;
22
+ url: string;
23
+ close: () => Promise<void>;
24
+ };
25
+ /** Create the common Express stack used by live and exported Lat UI servers. */
26
+ export declare function createLatServerApp(options?: LatServerAppOptions, app?: Express): LatServerApp;
27
+ /** Listen with the same strict-or-next-port behavior in every Lat UI host. */
28
+ export declare function listenLatServer(app: LatServerApp, options: ListenLatServerOptions): Promise<RunningLatServer>;
29
+ export type RunLatServerOptions = {
30
+ host?: string;
31
+ port?: number;
32
+ close?: () => void | Promise<void>;
33
+ log?: (message: string) => void;
34
+ };
35
+ /** Run an exported Express app until the standalone process is terminated. */
36
+ export declare function runLatServer(app: LatServerApp, options?: RunLatServerOptions): Promise<RunningLatServer>;
37
+ /** Read this published package's exact version for generated artifacts. */
38
+ export declare function getLatServerVersion(): string;
@@ -0,0 +1,128 @@
1
+ import { createServer, } from 'node:http';
2
+ import { readFileSync } from 'node:fs';
3
+ import express from 'express';
4
+ export const LAT_UI_CONTENT_SECURITY_POLICY = "default-src 'self'; connect-src 'self' https://tiles.openfreemap.org; font-src 'self' data:; img-src 'self' data: https://github.githubassets.com; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
5
+ function setSecurityHeaders(res) {
6
+ res.setHeader('Content-Security-Policy', LAT_UI_CONTENT_SECURITY_POLICY);
7
+ res.setHeader('Referrer-Policy', 'no-referrer');
8
+ res.setHeader('X-Content-Type-Options', 'nosniff');
9
+ }
10
+ function isImmutablePublicFile(path) {
11
+ const parts = path.split(/[/\\]/);
12
+ if (parts.includes('assets'))
13
+ return true;
14
+ return /[/\\]data[/\\][^/\\]+[/\\][a-f0-9]{20}\.json$/.test(path);
15
+ }
16
+ /** Create the common Express stack used by live and exported Lat UI servers. */
17
+ export function createLatServerApp(options = {}, app = express()) {
18
+ app.disable('x-powered-by');
19
+ app.use((_req, res, next) => {
20
+ setSecurityHeaders(res);
21
+ next();
22
+ });
23
+ if (options.handle) {
24
+ app.use((req, res, next) => {
25
+ try {
26
+ void Promise.resolve(options.handle(req, res, next)).catch(next);
27
+ }
28
+ catch (error) {
29
+ next(error);
30
+ }
31
+ });
32
+ }
33
+ if (options.publicDir) {
34
+ app.use(express.static(options.publicDir, {
35
+ setHeaders(res, path) {
36
+ res.setHeader('Cache-Control', isImmutablePublicFile(path)
37
+ ? 'public, max-age=31536000, immutable'
38
+ : 'no-cache');
39
+ },
40
+ }));
41
+ }
42
+ app.use((_req, res) => {
43
+ res.status(404).type('text/plain').send('Not found');
44
+ });
45
+ app.use((error, _req, res, _next) => {
46
+ console.error(error);
47
+ res.status(500).json({ error: 'Internal server error' });
48
+ });
49
+ return app;
50
+ }
51
+ function listen(server, host, port) {
52
+ return new Promise((resolveListen, reject) => {
53
+ const onError = (error) => {
54
+ server.off('listening', onListening);
55
+ reject(error);
56
+ };
57
+ const onListening = () => {
58
+ server.off('error', onError);
59
+ resolveListen();
60
+ };
61
+ server.once('error', onError);
62
+ server.once('listening', onListening);
63
+ server.listen(port, host);
64
+ });
65
+ }
66
+ function closeServer(server) {
67
+ return new Promise((resolveClose, reject) => {
68
+ server.close((error) => (error ? reject(error) : resolveClose()));
69
+ });
70
+ }
71
+ /** Listen with the same strict-or-next-port behavior in every Lat UI host. */
72
+ export async function listenLatServer(app, options) {
73
+ const server = createServer(app);
74
+ let port = options.port;
75
+ while (true) {
76
+ try {
77
+ await listen(server, options.host, port);
78
+ break;
79
+ }
80
+ catch (error) {
81
+ if (!options.findAvailablePort ||
82
+ error.code !== 'EADDRINUSE' ||
83
+ port === 65_535) {
84
+ throw error;
85
+ }
86
+ port++;
87
+ }
88
+ }
89
+ const address = server.address();
90
+ if (!address) {
91
+ await closeServer(server);
92
+ throw new Error('Could not determine Lat UI server address');
93
+ }
94
+ return {
95
+ server,
96
+ host: options.host,
97
+ port: address.port,
98
+ url: `http://${options.host}:${address.port}/`,
99
+ close: () => closeServer(server),
100
+ };
101
+ }
102
+ /** Run an exported Express app until the standalone process is terminated. */
103
+ export async function runLatServer(app, options = {}) {
104
+ const host = options.host ?? process.env.HOST ?? '0.0.0.0';
105
+ const rawPort = options.port ?? Number(process.env.PORT ?? 3000);
106
+ if (!Number.isInteger(rawPort) || rawPort < 1 || rawPort > 65_535) {
107
+ throw new Error('PORT must be an integer from 1 to 65535');
108
+ }
109
+ const running = await listenLatServer(app, { host, port: rawPort });
110
+ (options.log ?? console.log)(`Lat UI listening on ${running.url}`);
111
+ let closing = false;
112
+ const shutdown = () => {
113
+ if (closing)
114
+ return;
115
+ closing = true;
116
+ void Promise.all([running.close(), options.close?.()]).catch((error) => {
117
+ console.error(error);
118
+ process.exitCode = 1;
119
+ });
120
+ };
121
+ process.once('SIGINT', shutdown);
122
+ process.once('SIGTERM', shutdown);
123
+ return running;
124
+ }
125
+ /** Read this published package's exact version for generated artifacts. */
126
+ export function getLatServerVersion() {
127
+ return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
128
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plebeiantech/lat.md",
3
- "version": "0.12.3-fork.14",
3
+ "version": "0.12.3-fork.15",
4
4
  "description": "A knowledge graph for your codebase, written in markdown",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "files": [
26
26
  "dist/src",
27
+ "dist/vendor",
27
28
  "templates",
28
29
  "plugins"
29
30
  ],
@@ -64,7 +65,8 @@
64
65
  "tsx": "^4.21.0",
65
66
  "typescript": "^5.7.0",
66
67
  "vite": "^7.0.0",
67
- "vitest": "^3.0.0"
68
+ "vitest": "^3.0.0",
69
+ "@lat.md/server": "0.1.0"
68
70
  },
69
71
  "dependencies": {
70
72
  "@asciidoctor/core": "4.0.6",
@@ -74,6 +76,7 @@
74
76
  "@repomix/tree-sitter-wasms": "^0.1.17",
75
77
  "commander": "^14.0.3",
76
78
  "diff": "^8.0.4",
79
+ "express": "^5.2.1",
77
80
  "github-slugger": "^2.0.0",
78
81
  "ignore-walk": "^8.0.0",
79
82
  "mdast-util-gfm-autolink-literal": "^2.0.1",
@@ -103,12 +106,11 @@
103
106
  "web-tree-sitter": "^0.26.6",
104
107
  "yaml": "^2.8.2",
105
108
  "zod": "^4.3.6",
106
- "@lat.md/embed": "0.2.0",
107
- "@lat.md/server": "0.1.0",
108
- "@lat.md/embed-minilm-fp16": "0.1.0"
109
+ "@lat.md/embed-minilm-fp16": "0.1.0",
110
+ "@lat.md/embed": "0.2.0"
109
111
  },
110
112
  "scripts": {
111
- "build": "tsc && pnpm build:view",
113
+ "build": "tsc && tsx scripts/fork-vendor-ui-server.ts && pnpm build:view",
112
114
  "build:view": "vite build --config view/vite.config.ts && vite build --config view/highlight.vite.config.ts",
113
115
  "buildall": "pnpm build:packages && pnpm build",
114
116
  "setup:rust": "pnpm --filter @lat.md/embed setup:rust",