@lite-fsm/cli 0.1.0 → 0.1.1

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.
Files changed (89) hide show
  1. package/README.md +130 -0
  2. package/dist/bin/lite-fsm.js +6714 -5
  3. package/package.json +6 -4
  4. package/dist/bin/lite-fsm.d.cts +0 -2
  5. package/dist/bin/lite-fsm.d.ts +0 -2
  6. package/dist/cli/context.d.cts +0 -21
  7. package/dist/cli/context.d.ts +0 -21
  8. package/dist/cli/context.js +0 -0
  9. package/dist/cli/create-program.d.cts +0 -6
  10. package/dist/cli/create-program.d.ts +0 -6
  11. package/dist/cli/create-program.js +0 -48
  12. package/dist/cli/diagnostics.d.cts +0 -15
  13. package/dist/cli/diagnostics.d.ts +0 -15
  14. package/dist/cli/diagnostics.js +0 -13
  15. package/dist/cli/node-fs.d.cts +0 -2
  16. package/dist/cli/node-fs.d.ts +0 -2
  17. package/dist/cli/node-fs.js +0 -33
  18. package/dist/cli/result.d.cts +0 -6
  19. package/dist/cli/result.d.ts +0 -6
  20. package/dist/cli/result.js +0 -8
  21. package/dist/export-graph/command.d.cts +0 -8
  22. package/dist/export-graph/command.d.ts +0 -8
  23. package/dist/export-graph/command.js +0 -30
  24. package/dist/export-graph/export-document.d.cts +0 -38
  25. package/dist/export-graph/export-document.d.ts +0 -38
  26. package/dist/export-graph/export-document.js +0 -35
  27. package/dist/export-graph/options.d.cts +0 -21
  28. package/dist/export-graph/options.d.ts +0 -21
  29. package/dist/export-graph/options.js +0 -40
  30. package/dist/export-graph/run-export-graph.d.cts +0 -10
  31. package/dist/export-graph/run-export-graph.d.ts +0 -10
  32. package/dist/export-graph/run-export-graph.js +0 -53
  33. package/dist/export-graph/source-bundle.d.cts +0 -12
  34. package/dist/export-graph/source-bundle.d.ts +0 -12
  35. package/dist/export-graph/source-bundle.js +0 -48
  36. package/dist/export-graph/write-output.d.cts +0 -10
  37. package/dist/export-graph/write-output.d.ts +0 -10
  38. package/dist/export-graph/write-output.js +0 -24
  39. package/dist/output/format-diagnostics.d.cts +0 -6
  40. package/dist/output/format-diagnostics.d.ts +0 -6
  41. package/dist/output/format-diagnostics.js +0 -33
  42. package/dist/output/stable-json.d.cts +0 -1
  43. package/dist/output/stable-json.d.ts +0 -1
  44. package/dist/output/stable-json.js +0 -72
  45. package/dist/project/build-project-graph.d.cts +0 -19
  46. package/dist/project/build-project-graph.d.ts +0 -19
  47. package/dist/project/build-project-graph.js +0 -64
  48. package/dist/project/create-project-host.d.cts +0 -4
  49. package/dist/project/create-project-host.d.ts +0 -4
  50. package/dist/project/create-project-host.js +0 -11
  51. package/dist/project/module-resolver.d.cts +0 -15
  52. package/dist/project/module-resolver.d.ts +0 -15
  53. package/dist/project/module-resolver.js +0 -111
  54. package/dist/project/source-cache.d.cts +0 -11
  55. package/dist/project/source-cache.d.ts +0 -11
  56. package/dist/project/source-cache.js +0 -55
  57. package/dist/project/tsconfig.d.cts +0 -15
  58. package/dist/project/tsconfig.d.ts +0 -15
  59. package/dist/project/tsconfig.js +0 -116
  60. package/dist/visualize/command.d.cts +0 -9
  61. package/dist/visualize/command.d.ts +0 -9
  62. package/dist/visualize/command.js +0 -35
  63. package/dist/visualize/http.d.cts +0 -11
  64. package/dist/visualize/http.d.ts +0 -11
  65. package/dist/visualize/http.js +0 -65
  66. package/dist/visualize/open-browser.d.cts +0 -22
  67. package/dist/visualize/open-browser.d.ts +0 -22
  68. package/dist/visualize/open-browser.js +0 -45
  69. package/dist/visualize/options.d.cts +0 -16
  70. package/dist/visualize/options.d.ts +0 -16
  71. package/dist/visualize/options.js +0 -51
  72. package/dist/visualize/routes.d.cts +0 -2
  73. package/dist/visualize/routes.d.ts +0 -2
  74. package/dist/visualize/routes.js +0 -24
  75. package/dist/visualize/run-visualize.d.cts +0 -32
  76. package/dist/visualize/run-visualize.d.ts +0 -32
  77. package/dist/visualize/run-visualize.js +0 -81
  78. package/dist/visualize/server.d.cts +0 -40
  79. package/dist/visualize/server.d.ts +0 -40
  80. package/dist/visualize/server.js +0 -90
  81. package/dist/visualize/session.d.cts +0 -34
  82. package/dist/visualize/session.d.ts +0 -34
  83. package/dist/visualize/session.js +0 -137
  84. package/dist/visualize/static-assets.d.cts +0 -17
  85. package/dist/visualize/static-assets.d.ts +0 -17
  86. package/dist/visualize/static-assets.js +0 -87
  87. package/dist/visualize/types.d.cts +0 -65
  88. package/dist/visualize/types.d.ts +0 -65
  89. package/dist/visualize/types.js +0 -0
@@ -1,116 +0,0 @@
1
- import { dirname, resolve } from "node:path";
2
- import ts from "typescript";
3
- import { cliDiagnostic } from "../cli/diagnostics.js";
4
- import { normalizeAbsolutePath, normalizePath } from "./source-cache.js";
5
- const defaultCompilerOptions = () => ({
6
- target: ts.ScriptTarget.ES2020,
7
- module: ts.ModuleKind.ESNext,
8
- moduleResolution: ts.ModuleResolutionKind.Bundler,
9
- strict: true
10
- });
11
- const parentDirectory = (path) => normalizeAbsolutePath(dirname(path));
12
- const findNearestTsconfig = (context, entryFileName) => {
13
- let directory = parentDirectory(entryFileName);
14
- while (true) {
15
- const candidate = normalizeAbsolutePath(resolve(directory, "tsconfig.json"));
16
- if (context.fs.fileExists(candidate)) return candidate;
17
- const parent = parentDirectory(directory);
18
- if (parent === directory) return void 0;
19
- directory = parent;
20
- }
21
- };
22
- const diagnosticMessageText = (messageText) => {
23
- return ts.flattenDiagnosticMessageText(messageText, "\n");
24
- };
25
- const diagnosticLocation = (diagnostic) => {
26
- if (!diagnostic.file || diagnostic.start === void 0) return void 0;
27
- const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
28
- return { line: position.line + 1, column: position.character + 1 };
29
- };
30
- const invalidTsconfigDiagnostic = (diagnostic, fallbackFile) => {
31
- return cliDiagnostic("LFC_TSCONFIG_INVALID", "error", diagnosticMessageText(diagnostic.messageText), {
32
- file: diagnostic.file ? normalizePath(diagnostic.file.fileName) : fallbackFile,
33
- loc: diagnosticLocation(diagnostic)
34
- });
35
- };
36
- const isResolverIrrelevantDiagnostic = (diagnostic) => {
37
- return diagnostic.code === 18003;
38
- };
39
- const parseTsconfig = (context, tsconfigPath) => {
40
- const normalizedTsconfigPath = normalizeAbsolutePath(tsconfigPath);
41
- const configFile = ts.readConfigFile(normalizedTsconfigPath, (path) => context.fs.readFile(normalizeAbsolutePath(path)));
42
- if (configFile.error) {
43
- return {
44
- tsconfigPath: normalizedTsconfigPath,
45
- projectRoot: normalizeAbsolutePath(dirname(normalizedTsconfigPath)),
46
- compilerOptions: defaultCompilerOptions(),
47
- diagnostics: [invalidTsconfigDiagnostic(configFile.error, normalizedTsconfigPath)],
48
- blocking: true
49
- };
50
- }
51
- const projectRoot = normalizeAbsolutePath(dirname(normalizedTsconfigPath));
52
- const diagnostics = [];
53
- const parseHost = {
54
- useCaseSensitiveFileNames: true,
55
- fileExists(path) {
56
- return context.fs.fileExists(normalizeAbsolutePath(path));
57
- },
58
- readFile(path) {
59
- const normalized = normalizeAbsolutePath(path);
60
- return context.fs.fileExists(normalized) ? context.fs.readFile(normalized) : void 0;
61
- },
62
- readDirectory() {
63
- return [];
64
- }
65
- };
66
- const parsed = ts.parseJsonConfigFileContent(configFile.config, parseHost, projectRoot, void 0, normalizedTsconfigPath);
67
- const parseDiagnostics = parsed.errors.filter((diagnostic) => !isResolverIrrelevantDiagnostic(diagnostic)).map((diagnostic) => invalidTsconfigDiagnostic(diagnostic, normalizedTsconfigPath));
68
- const allDiagnostics = [...diagnostics, ...parseDiagnostics];
69
- return {
70
- tsconfigPath: normalizedTsconfigPath,
71
- projectRoot,
72
- compilerOptions: {
73
- ...defaultCompilerOptions(),
74
- ...parsed.options,
75
- configFilePath: normalizedTsconfigPath
76
- },
77
- diagnostics: allDiagnostics,
78
- blocking: allDiagnostics.length > 0
79
- };
80
- };
81
- const resolveProjectTsconfig = (context, options) => {
82
- if (options.explicitTsconfigPath) {
83
- const explicitPath = normalizeAbsolutePath(resolve(context.cwd, options.explicitTsconfigPath));
84
- if (!context.fs.fileExists(explicitPath)) {
85
- return {
86
- tsconfigPath: explicitPath,
87
- projectRoot: normalizeAbsolutePath(dirname(explicitPath)),
88
- compilerOptions: defaultCompilerOptions(),
89
- diagnostics: [
90
- cliDiagnostic("LFC_TSCONFIG_NOT_FOUND", "error", `Explicit tsconfig was not found: ${normalizePath(explicitPath)}`, {
91
- file: normalizePath(explicitPath)
92
- })
93
- ],
94
- blocking: true
95
- };
96
- }
97
- return parseTsconfig(context, explicitPath);
98
- }
99
- const nearest = findNearestTsconfig(context, options.entryFileName);
100
- if (nearest) return parseTsconfig(context, nearest);
101
- return {
102
- projectRoot: normalizeAbsolutePath(context.cwd),
103
- compilerOptions: defaultCompilerOptions(),
104
- diagnostics: [
105
- cliDiagnostic(
106
- "LFC_TSCONFIG_NOT_FOUND",
107
- "info",
108
- "Nearest tsconfig.json was not found. Falling back to default TypeScript module resolution."
109
- )
110
- ],
111
- blocking: false
112
- };
113
- };
114
- export {
115
- resolveProjectTsconfig
116
- };
@@ -1,9 +0,0 @@
1
- import type { Command } from "commander";
2
- import type { CliContext } from "../cli/context.js";
3
- import type { CommandResult } from "../cli/result.js";
4
- import { type RawVisualizeOptions } from "./options.js";
5
- import type { RunVisualizeDependencies } from "./run-visualize.js";
6
- type SetCommandResult = (result: CommandResult) => void;
7
- export declare const runVisualizeCommand: (context: CliContext, rawOptions: RawVisualizeOptions, dependencies?: RunVisualizeDependencies) => Promise<CommandResult>;
8
- export declare const registerVisualizeCommand: (program: Command, context: CliContext, setResult: SetCommandResult) => void;
9
- export {};
@@ -1,9 +0,0 @@
1
- import type { Command } from "commander";
2
- import type { CliContext } from "../cli/context.js";
3
- import type { CommandResult } from "../cli/result.js";
4
- import { type RawVisualizeOptions } from "./options.js";
5
- import type { RunVisualizeDependencies } from "./run-visualize.js";
6
- type SetCommandResult = (result: CommandResult) => void;
7
- export declare const runVisualizeCommand: (context: CliContext, rawOptions: RawVisualizeOptions, dependencies?: RunVisualizeDependencies) => Promise<CommandResult>;
8
- export declare const registerVisualizeCommand: (program: Command, context: CliContext, setResult: SetCommandResult) => void;
9
- export {};
@@ -1,35 +0,0 @@
1
- import { createCommandResult } from "../cli/result.js";
2
- import { formatDiagnostics } from "../output/format-diagnostics.js";
3
- import { normalizeVisualizeOptions } from "./options.js";
4
- const writeDiagnostics = (context, diagnostics) => {
5
- const formatted = formatDiagnostics(diagnostics);
6
- if (formatted) context.stderr.write(formatted);
7
- };
8
- const runVisualizeCommand = async (context, rawOptions, dependencies = {}) => {
9
- const normalized = normalizeVisualizeOptions(rawOptions);
10
- if (!normalized.ok) {
11
- writeDiagnostics(context, normalized.diagnostics);
12
- return createCommandResult(normalized.diagnostics);
13
- }
14
- const { runVisualize } = await import("./run-visualize.js");
15
- const result = await runVisualize(context, normalized.options, {
16
- ...dependencies,
17
- emitDiagnostics(diagnostics, graphDiagnostics) {
18
- dependencies.emitDiagnostics?.(diagnostics, graphDiagnostics);
19
- writeDiagnostics(context, [...diagnostics, ...graphDiagnostics]);
20
- }
21
- });
22
- return {
23
- exitCode: result.exitCode,
24
- diagnostics: result.diagnostics
25
- };
26
- };
27
- const registerVisualizeCommand = (program, context, setResult) => {
28
- program.command("visualize").description("Start a local visualizer for a lite-fsm project graph").option("--entry <path>", "entrypoint TypeScript file").option("--tsconfig <path>", "explicit tsconfig for TypeScript module resolution").option("--port <number>", "local visualizer port").option("--no-open", "print the visualizer URL without opening a browser").action(async (options) => {
29
- setResult(await runVisualizeCommand(context, options));
30
- });
31
- };
32
- export {
33
- registerVisualizeCommand,
34
- runVisualizeCommand
35
- };
@@ -1,11 +0,0 @@
1
- import { URL } from "node:url";
2
- import type { VisualizerHttpRequest, VisualizerHttpResponse, VisualizerHttpResponseWriter, VisualizerRoute, VisualizerRouteContext } from "./types.js";
3
- import type { VisualizerSession } from "./session.js";
4
- export declare const jsonResponse: (status: number, body: object) => VisualizerHttpResponse;
5
- export declare const errorResponse: (status: number, code: string, message: string) => VisualizerHttpResponse;
6
- export declare const writeHttpResponse: (response: VisualizerHttpResponseWriter, output: VisualizerHttpResponse) => void;
7
- export declare const dispatchApiRoute: (routes: readonly VisualizerRoute[], context: Omit<VisualizerRouteContext, "session"> & {
8
- session: VisualizerSession;
9
- }) => Promise<VisualizerHttpResponse>;
10
- export declare const createRequestUrl: (request: VisualizerHttpRequest) => URL;
11
- export declare const createRequestPathname: (request: VisualizerHttpRequest) => string;
@@ -1,11 +0,0 @@
1
- import { URL } from "node:url";
2
- import type { VisualizerHttpRequest, VisualizerHttpResponse, VisualizerHttpResponseWriter, VisualizerRoute, VisualizerRouteContext } from "./types.js";
3
- import type { VisualizerSession } from "./session.js";
4
- export declare const jsonResponse: (status: number, body: object) => VisualizerHttpResponse;
5
- export declare const errorResponse: (status: number, code: string, message: string) => VisualizerHttpResponse;
6
- export declare const writeHttpResponse: (response: VisualizerHttpResponseWriter, output: VisualizerHttpResponse) => void;
7
- export declare const dispatchApiRoute: (routes: readonly VisualizerRoute[], context: Omit<VisualizerRouteContext, "session"> & {
8
- session: VisualizerSession;
9
- }) => Promise<VisualizerHttpResponse>;
10
- export declare const createRequestUrl: (request: VisualizerHttpRequest) => URL;
11
- export declare const createRequestPathname: (request: VisualizerHttpRequest) => string;
@@ -1,65 +0,0 @@
1
- import { URL } from "node:url";
2
- const jsonResponse = (status, body) => ({
3
- status,
4
- headers: {
5
- "content-type": "application/json; charset=utf-8"
6
- },
7
- body: `${JSON.stringify(body)}
8
- `
9
- });
10
- const errorResponse = (status, code, message) => {
11
- const body = { ok: false, code, message };
12
- return jsonResponse(status, body);
13
- };
14
- const writeHttpResponse = (response, output) => {
15
- const headers = output.headers ?? {};
16
- const body = output.body;
17
- if (body === void 0) {
18
- response.writeHead(output.status, headers);
19
- response.end();
20
- return;
21
- }
22
- const bodyBuffer = typeof body === "string" ? Buffer.from(body, "utf8") : Buffer.from(body);
23
- response.writeHead(output.status, {
24
- ...headers,
25
- "content-length": String(bodyBuffer.byteLength)
26
- });
27
- response.end(bodyBuffer);
28
- };
29
- const dispatchApiRoute = async (routes, context) => {
30
- const pathRoutes = routes.filter((route2) => route2.path === context.url.pathname);
31
- if (pathRoutes.length === 0) return errorResponse(404, "route-not-found", "API route was not found.");
32
- const route = pathRoutes.find((candidate) => candidate.method === context.request.method);
33
- if (!route) {
34
- const method = context.request.method ?? "UNKNOWN";
35
- const response = errorResponse(405, "method-not-allowed", `Method ${method} is not allowed.`);
36
- return {
37
- ...response,
38
- headers: {
39
- ...response.headers,
40
- "allow": pathRoutes.map((candidate) => candidate.method).join(", ")
41
- }
42
- };
43
- }
44
- if (route.auth === "session" && !context.session.authenticate(context.url.searchParams.get("token"))) {
45
- return errorResponse(401, "invalid-token", "Missing or invalid session token.");
46
- }
47
- return route.handle(context);
48
- };
49
- const createRequestUrl = (request) => {
50
- return new URL(request.url ?? "/", "http://127.0.0.1");
51
- };
52
- const createRequestPathname = (request) => {
53
- const rawUrl = request.url ?? "/";
54
- if (!rawUrl.startsWith("/")) return createRequestUrl(request).pathname;
55
- const queryStart = rawUrl.search(/[?#]/);
56
- return queryStart === -1 ? rawUrl : rawUrl.slice(0, queryStart);
57
- };
58
- export {
59
- createRequestPathname,
60
- createRequestUrl,
61
- dispatchApiRoute,
62
- errorResponse,
63
- jsonResponse,
64
- writeHttpResponse
65
- };
@@ -1,22 +0,0 @@
1
- export type BrowserPlatform = NodeJS.Platform;
2
- export type BrowserOpenCommand = {
3
- command: string;
4
- args: string[];
5
- };
6
- type BrowserProcessListenerArgs = [event: "spawn", listener: () => void] | [event: "error", listener: (error: Error) => void];
7
- export type BrowserProcess = {
8
- once(...args: BrowserProcessListenerArgs): BrowserProcess;
9
- unref?(): void;
10
- };
11
- export type BrowserSpawner = (command: string, args: readonly string[], options: {
12
- shell: false;
13
- stdio: "ignore";
14
- detached: true;
15
- }) => BrowserProcess;
16
- export type OpenBrowserOptions = {
17
- platform?: BrowserPlatform;
18
- spawnProcess?: BrowserSpawner;
19
- };
20
- export declare const createBrowserOpenCommand: (platform: BrowserPlatform, url: string) => BrowserOpenCommand;
21
- export declare const openBrowser: (url: string, options?: OpenBrowserOptions) => Promise<void>;
22
- export {};
@@ -1,22 +0,0 @@
1
- export type BrowserPlatform = NodeJS.Platform;
2
- export type BrowserOpenCommand = {
3
- command: string;
4
- args: string[];
5
- };
6
- type BrowserProcessListenerArgs = [event: "spawn", listener: () => void] | [event: "error", listener: (error: Error) => void];
7
- export type BrowserProcess = {
8
- once(...args: BrowserProcessListenerArgs): BrowserProcess;
9
- unref?(): void;
10
- };
11
- export type BrowserSpawner = (command: string, args: readonly string[], options: {
12
- shell: false;
13
- stdio: "ignore";
14
- detached: true;
15
- }) => BrowserProcess;
16
- export type OpenBrowserOptions = {
17
- platform?: BrowserPlatform;
18
- spawnProcess?: BrowserSpawner;
19
- };
20
- export declare const createBrowserOpenCommand: (platform: BrowserPlatform, url: string) => BrowserOpenCommand;
21
- export declare const openBrowser: (url: string, options?: OpenBrowserOptions) => Promise<void>;
22
- export {};
@@ -1,45 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- const nodeBrowserSpawner = (command, args, options) => {
3
- const child = spawn(command, [...args], options);
4
- return {
5
- once(...[event, listener]) {
6
- if (event === "spawn") child.once(event, listener);
7
- else child.once(event, listener);
8
- return this;
9
- },
10
- unref() {
11
- child.unref();
12
- }
13
- };
14
- };
15
- const createBrowserOpenCommand = (platform, url) => {
16
- if (platform === "darwin") return { command: "open", args: [url] };
17
- if (platform === "win32") return { command: "cmd.exe", args: ["/c", "start", "", url] };
18
- return { command: "xdg-open", args: [url] };
19
- };
20
- const openBrowser = (url, options = {}) => new Promise((resolve, reject) => {
21
- const { command, args } = createBrowserOpenCommand(options.platform ?? process.platform, url);
22
- const spawnProcess = options.spawnProcess ?? nodeBrowserSpawner;
23
- let settled = false;
24
- const settle = (callback) => {
25
- if (settled) return;
26
- settled = true;
27
- callback();
28
- };
29
- const child = spawnProcess(command, args, {
30
- shell: false,
31
- stdio: "ignore",
32
- detached: true
33
- });
34
- child.once("spawn", () => {
35
- child.unref?.();
36
- settle(resolve);
37
- });
38
- child.once("error", (error) => {
39
- settle(() => reject(error));
40
- });
41
- });
42
- export {
43
- createBrowserOpenCommand,
44
- openBrowser
45
- };
@@ -1,16 +0,0 @@
1
- import type { CliDiagnostic } from "../cli/diagnostics.js";
2
- import type { VisualizeOptions } from "./types.js";
3
- export type RawVisualizeOptions = {
4
- entry?: unknown;
5
- tsconfig?: unknown;
6
- port?: unknown;
7
- open?: unknown;
8
- };
9
- export type NormalizeVisualizeOptionsResult = {
10
- ok: true;
11
- options: VisualizeOptions;
12
- } | {
13
- ok: false;
14
- diagnostics: CliDiagnostic[];
15
- };
16
- export declare const normalizeVisualizeOptions: (rawOptions: RawVisualizeOptions) => NormalizeVisualizeOptionsResult;
@@ -1,16 +0,0 @@
1
- import type { CliDiagnostic } from "../cli/diagnostics.js";
2
- import type { VisualizeOptions } from "./types.js";
3
- export type RawVisualizeOptions = {
4
- entry?: unknown;
5
- tsconfig?: unknown;
6
- port?: unknown;
7
- open?: unknown;
8
- };
9
- export type NormalizeVisualizeOptionsResult = {
10
- ok: true;
11
- options: VisualizeOptions;
12
- } | {
13
- ok: false;
14
- diagnostics: CliDiagnostic[];
15
- };
16
- export declare const normalizeVisualizeOptions: (rawOptions: RawVisualizeOptions) => NormalizeVisualizeOptionsResult;
@@ -1,51 +0,0 @@
1
- import { cliDiagnostic } from "../cli/diagnostics.js";
2
- const DEFAULT_VISUALIZER_PORT = 3030;
3
- const MIN_PORT = 1;
4
- const MAX_PORT = 65535;
5
- const stringOption = (value) => {
6
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
7
- };
8
- const normalizePort = (value, diagnostics) => {
9
- if (value === void 0) return DEFAULT_VISUALIZER_PORT;
10
- if (typeof value !== "string" || value.trim() === "") {
11
- diagnostics.push(cliDiagnostic("LFC_INVALID_OPTIONS", "error", "Option --port must be an integer from 1 to 65535."));
12
- return DEFAULT_VISUALIZER_PORT;
13
- }
14
- const port = Number(value);
15
- if (!Number.isInteger(port) || port < MIN_PORT || port > MAX_PORT) {
16
- diagnostics.push(cliDiagnostic("LFC_INVALID_OPTIONS", "error", "Option --port must be an integer from 1 to 65535."));
17
- return DEFAULT_VISUALIZER_PORT;
18
- }
19
- return port;
20
- };
21
- const normalizeVisualizeOptions = (rawOptions) => {
22
- const diagnostics = [];
23
- const entry = stringOption(rawOptions.entry);
24
- const tsconfig = stringOption(rawOptions.tsconfig);
25
- const port = normalizePort(rawOptions.port, diagnostics);
26
- const noOpen = rawOptions.open === false;
27
- if (!entry) {
28
- return {
29
- ok: false,
30
- diagnostics: [
31
- ...diagnostics,
32
- cliDiagnostic("LFC_INVALID_OPTIONS", "error", "Option --entry is required.", {
33
- hint: "Pass --entry path/to/store/index.ts."
34
- })
35
- ]
36
- };
37
- }
38
- if (diagnostics.length > 0) return { ok: false, diagnostics };
39
- return {
40
- ok: true,
41
- options: {
42
- entry,
43
- port,
44
- noOpen,
45
- ...tsconfig ? { tsconfig } : {}
46
- }
47
- };
48
- };
49
- export {
50
- normalizeVisualizeOptions
51
- };
@@ -1,2 +0,0 @@
1
- import type { VisualizerRoute } from "./types.js";
2
- export declare const createVisualizerRoutes: () => VisualizerRoute[];
@@ -1,2 +0,0 @@
1
- import type { VisualizerRoute } from "./types.js";
2
- export declare const createVisualizerRoutes: () => VisualizerRoute[];
@@ -1,24 +0,0 @@
1
- import { errorResponse, jsonResponse } from "./http.js";
2
- const createVisualizerRoutes = () => [
3
- {
4
- method: "GET",
5
- path: "/api/session",
6
- auth: "session",
7
- handle({ session }) {
8
- return jsonResponse(200, session.createSessionResponse());
9
- }
10
- },
11
- {
12
- method: "GET",
13
- path: "/api/source",
14
- auth: "session",
15
- handle({ cliContext, session, url }) {
16
- const result = session.readSource(cliContext, url.searchParams.get("fileName"));
17
- if (!result.ok) return errorResponse(result.status, result.code, result.message);
18
- return jsonResponse(200, result.response);
19
- }
20
- }
21
- ];
22
- export {
23
- createVisualizerRoutes
24
- };
@@ -1,32 +0,0 @@
1
- import type { GraphDiagnostic, LiteFsmGraphProjectResult } from "@lite-fsm/graph";
2
- import type { CliContext } from "../cli/context.js";
3
- import type { CliDiagnostic } from "../cli/diagnostics.js";
4
- import type { CommandResult } from "../cli/result.js";
5
- import { buildProjectGraph } from "../project/build-project-graph.js";
6
- import { type VisualizerSession } from "./session.js";
7
- import { type StartVisualizerServerResult, type VisualizerServer } from "./server.js";
8
- import type { VisualizeOptions } from "./types.js";
9
- export type VisualizeRunResult = CommandResult & {
10
- graphDiagnostics: GraphDiagnostic[];
11
- };
12
- export type RunVisualizeDependencies = {
13
- buildGraph?: typeof buildProjectGraph;
14
- createSession?: (input: {
15
- projectRoot: string;
16
- graphResult: LiteFsmGraphProjectResult;
17
- diagnostics: readonly CliDiagnostic[];
18
- entryPath: string;
19
- tsconfigPath?: string;
20
- }) => VisualizerSession;
21
- startServer?: (input: {
22
- context: CliContext;
23
- port: number;
24
- session: VisualizerSession;
25
- staticRoot: string;
26
- }) => Promise<StartVisualizerServerResult>;
27
- openBrowser?: (url: string) => Promise<void>;
28
- waitForShutdown?: (server: VisualizerServer) => Promise<void>;
29
- staticRoot?: string;
30
- emitDiagnostics?: (diagnostics: readonly CliDiagnostic[], graphDiagnostics: readonly GraphDiagnostic[]) => void;
31
- };
32
- export declare const runVisualize: (context: CliContext, options: VisualizeOptions, dependencies?: RunVisualizeDependencies) => Promise<VisualizeRunResult>;
@@ -1,32 +0,0 @@
1
- import type { GraphDiagnostic, LiteFsmGraphProjectResult } from "@lite-fsm/graph";
2
- import type { CliContext } from "../cli/context.js";
3
- import type { CliDiagnostic } from "../cli/diagnostics.js";
4
- import type { CommandResult } from "../cli/result.js";
5
- import { buildProjectGraph } from "../project/build-project-graph.js";
6
- import { type VisualizerSession } from "./session.js";
7
- import { type StartVisualizerServerResult, type VisualizerServer } from "./server.js";
8
- import type { VisualizeOptions } from "./types.js";
9
- export type VisualizeRunResult = CommandResult & {
10
- graphDiagnostics: GraphDiagnostic[];
11
- };
12
- export type RunVisualizeDependencies = {
13
- buildGraph?: typeof buildProjectGraph;
14
- createSession?: (input: {
15
- projectRoot: string;
16
- graphResult: LiteFsmGraphProjectResult;
17
- diagnostics: readonly CliDiagnostic[];
18
- entryPath: string;
19
- tsconfigPath?: string;
20
- }) => VisualizerSession;
21
- startServer?: (input: {
22
- context: CliContext;
23
- port: number;
24
- session: VisualizerSession;
25
- staticRoot: string;
26
- }) => Promise<StartVisualizerServerResult>;
27
- openBrowser?: (url: string) => Promise<void>;
28
- waitForShutdown?: (server: VisualizerServer) => Promise<void>;
29
- staticRoot?: string;
30
- emitDiagnostics?: (diagnostics: readonly CliDiagnostic[], graphDiagnostics: readonly GraphDiagnostic[]) => void;
31
- };
32
- export declare const runVisualize: (context: CliContext, options: VisualizeOptions, dependencies?: RunVisualizeDependencies) => Promise<VisualizeRunResult>;
@@ -1,81 +0,0 @@
1
- import { cliDiagnostic, hasBlockingCliDiagnostics } from "../cli/diagnostics.js";
2
- import { createProjectGraphExportDocument } from "../export-graph/export-document.js";
3
- import { buildProjectGraph } from "../project/build-project-graph.js";
4
- import { openBrowser } from "./open-browser.js";
5
- import { createVisualizerSession } from "./session.js";
6
- import { startVisualizerServer, waitForSignalShutdown } from "./server.js";
7
- import { verifyVisualizerStaticArtifact } from "./static-assets.js";
8
- const createRunResult = (diagnostics, graphDiagnostics = []) => ({
9
- exitCode: hasBlockingCliDiagnostics(diagnostics) ? 1 : 0,
10
- diagnostics: [...diagnostics],
11
- graphDiagnostics: [...graphDiagnostics]
12
- });
13
- const createSessionFromBuild = (project, graphResult, diagnostics) => {
14
- const exportDocument = createProjectGraphExportDocument({
15
- entryPath: project.entryPath,
16
- tsconfigPath: project.tsconfigPath,
17
- graphResult,
18
- diagnostics
19
- });
20
- return createVisualizerSession({
21
- projectRoot: project.projectRoot,
22
- exportDocument,
23
- graphResult
24
- });
25
- };
26
- const runVisualize = async (context, options, dependencies = {}) => {
27
- const buildResult = (dependencies.buildGraph ?? buildProjectGraph)(context, {
28
- entry: options.entry,
29
- tsconfig: options.tsconfig
30
- });
31
- const graphDiagnostics = buildResult.graphResult?.diagnostics ?? [];
32
- const diagnostics = [...buildResult.diagnostics];
33
- const finish = (nextDiagnostics) => {
34
- dependencies.emitDiagnostics?.(nextDiagnostics, graphDiagnostics);
35
- return createRunResult(nextDiagnostics, graphDiagnostics);
36
- };
37
- if (buildResult.blocking) return finish(diagnostics);
38
- if (!buildResult.graphResult) {
39
- return finish([
40
- ...diagnostics,
41
- cliDiagnostic("LFC_GRAPH_PROJECT_FAILED", "error", "Project graph build did not return a graph result.")
42
- ]);
43
- }
44
- const staticArtifact = verifyVisualizerStaticArtifact(context, dependencies.staticRoot);
45
- if (!staticArtifact.ok) return finish([...diagnostics, ...staticArtifact.diagnostics]);
46
- const session = dependencies.createSession ? dependencies.createSession({
47
- projectRoot: buildResult.project.projectRoot,
48
- graphResult: buildResult.graphResult,
49
- diagnostics,
50
- entryPath: buildResult.project.entryPath,
51
- tsconfigPath: buildResult.project.tsconfigPath
52
- }) : createSessionFromBuild(buildResult.project, buildResult.graphResult, diagnostics);
53
- const startServer = dependencies.startServer ?? startVisualizerServer;
54
- const started = await startServer({
55
- context,
56
- port: options.port,
57
- session,
58
- staticRoot: staticArtifact.staticRoot
59
- });
60
- if (!started.ok) return finish([...diagnostics, ...started.diagnostics]);
61
- try {
62
- const open = dependencies.openBrowser ?? openBrowser;
63
- if (!options.noOpen) await open(started.server.url);
64
- } catch (error) {
65
- await started.server.close();
66
- const message = error instanceof Error ? error.message : String(error);
67
- return finish([
68
- ...diagnostics,
69
- cliDiagnostic("LFC_VISUALIZER_OPEN_FAILED", "error", `Failed to open browser: ${message}`)
70
- ]);
71
- }
72
- dependencies.emitDiagnostics?.(diagnostics, graphDiagnostics);
73
- context.stdout.write(`${started.server.url}
74
- `);
75
- const waitForShutdown = dependencies.waitForShutdown ?? waitForSignalShutdown;
76
- await waitForShutdown(started.server);
77
- return createRunResult(diagnostics, graphDiagnostics);
78
- };
79
- export {
80
- runVisualize
81
- };
@@ -1,40 +0,0 @@
1
- import type { CliContext } from "../cli/context.js";
2
- import type { CliDiagnostic } from "../cli/diagnostics.js";
3
- import type { VisualizerSession } from "./session.js";
4
- import type { VisualizerHttpRequest, VisualizerHttpResponse, VisualizerHttpResponseWriter, VisualizerRoute } from "./types.js";
5
- export type VisualizerServer = {
6
- url: string;
7
- port: number;
8
- close(): Promise<void>;
9
- };
10
- export type StartVisualizerServerOptions = {
11
- context: CliContext;
12
- port: number;
13
- session: VisualizerSession;
14
- staticRoot: string;
15
- };
16
- export type StartVisualizerServerDependencies = {
17
- routes?: readonly VisualizerRoute[];
18
- createHttpServer?: CreateVisualizerHttpServer;
19
- };
20
- export type StartVisualizerServerResult = {
21
- ok: true;
22
- server: VisualizerServer;
23
- } | {
24
- ok: false;
25
- diagnostics: CliDiagnostic[];
26
- };
27
- type VisualizerServerListenerArgs = [event: "error", listener: (error: NodeJS.ErrnoException) => void] | [event: "listening", listener: () => void];
28
- export type VisualizerHttpServer = {
29
- once(...args: VisualizerServerListenerArgs): VisualizerHttpServer;
30
- removeListener(...args: VisualizerServerListenerArgs): VisualizerHttpServer;
31
- listen(port: number, host: string): void;
32
- close(callback: (error?: Error) => void): void;
33
- };
34
- export type CreateVisualizerHttpServer = (handler: (request: VisualizerHttpRequest, response: VisualizerHttpResponseWriter) => void) => VisualizerHttpServer;
35
- export declare const handleVisualizerRequest: (options: StartVisualizerServerOptions & {
36
- routes: readonly VisualizerRoute[];
37
- }, request: VisualizerHttpRequest) => Promise<VisualizerHttpResponse>;
38
- export declare const startVisualizerServer: (options: StartVisualizerServerOptions, dependencies?: StartVisualizerServerDependencies) => Promise<StartVisualizerServerResult>;
39
- export declare const waitForSignalShutdown: (server: VisualizerServer) => Promise<void>;
40
- export {};