@reicek/neataptic-ts 0.1.25 → 0.1.26
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/.github/copilot-instructions.md +11 -0
- package/.github/skills/trace-analyzer-extension/SKILL.md +3 -3
- package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +1 -1
- package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +1 -1
- package/.github/skills/trace-audit-reporting/SKILL.md +3 -3
- package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +1 -1
- package/package.json +19 -13
- package/plans/Flappy_Bird_Folder_Documentation_Pass.md +4 -4
- package/plans/README.md +24 -0
- package/plans/Roadmap.md +62 -40
- package/plans/analyze-trace-solid-split.plans.md +66 -0
- package/plans/architecture-solid-split.plans.md +9 -15
- package/plans/asciiMaze-typescript-repair.plans.md +1 -1
- package/plans/generate-docs-solid-split.plans.md +87 -0
- package/plans/methods-docs.plans.md +25 -1
- package/plans/methods-solid-split.plans.md +14 -14
- package/plans/neat-docs.plans.md +9 -1
- package/plans/neat-test-surface-repair.plans.md +1 -1
- package/plans/render-docs-html-solid-split.plans.md +68 -0
- package/plans/src-no-explicit-any-cleanup.plans.md +1 -1
- package/plans/utils-docs.plans.md +6 -1
- package/scripts/analyze-trace/analyze-trace.analysis.ts +479 -0
- package/scripts/analyze-trace/analyze-trace.constants.ts +35 -0
- package/scripts/analyze-trace/analyze-trace.io.ts +69 -0
- package/scripts/analyze-trace/analyze-trace.report.ts +100 -0
- package/scripts/analyze-trace/analyze-trace.shared.ts +116 -0
- package/scripts/analyze-trace/analyze-trace.ts +45 -0
- package/scripts/analyze-trace/analyze-trace.types.ts +72 -0
- package/scripts/assets/theme.css +80 -23
- package/scripts/copy-examples.ts +239 -0
- package/scripts/export-onnx.ts +223 -0
- package/scripts/generate-bench-tables.ts +378 -37
- package/scripts/generate-docs/generate-docs.constants.ts +107 -0
- package/scripts/generate-docs/generate-docs.order.ts +355 -0
- package/scripts/generate-docs/generate-docs.state.ts +31 -0
- package/scripts/generate-docs/generate-docs.targets.ts +165 -0
- package/scripts/generate-docs/generate-docs.ts +63 -0
- package/scripts/generate-docs/generate-docs.types.ts +112 -0
- package/scripts/generate-docs/output/generate-docs.output.folder-index.utils.ts +167 -0
- package/scripts/generate-docs/output/generate-docs.output.ordering.utils.ts +353 -0
- package/scripts/generate-docs/output/generate-docs.output.readme.utils.ts +420 -0
- package/scripts/generate-docs/output/generate-docs.output.ts +123 -0
- package/scripts/generate-docs/output/generate-docs.output.warnings.utils.ts +219 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.collection.utils.ts +365 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.jsdoc.utils.ts +373 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.normalize.utils.ts +155 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.render.utils.ts +149 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.signature.utils.ts +289 -0
- package/scripts/generate-docs/symbols/generate-docs.symbols.ts +11 -0
- package/scripts/mermaid-cli.mjs +102 -22
- package/scripts/mermaid-cli.ts +736 -0
- package/scripts/render-docs-html/render-docs-html.assets.ts +54 -0
- package/scripts/render-docs-html/render-docs-html.mermaid.ts +245 -0
- package/scripts/{render-docs-html.sidebar.ts → render-docs-html/render-docs-html.navigation.ts} +141 -144
- package/scripts/render-docs-html/render-docs-html.pages.ts +333 -0
- package/scripts/render-docs-html/render-docs-html.shared.ts +333 -0
- package/scripts/render-docs-html/render-docs-html.types.ts +42 -0
- package/scripts/render-docs-html.ts +23 -587
- package/scripts/run-docs.ts +238 -0
- package/scripts/write-dist-docs-pkg.ts +40 -0
- package/src/README.md +75 -75
- package/src/architecture/connection/README.md +5 -5
- package/src/architecture/layer/README.md +508 -508
- package/src/architecture/network/README.md +1458 -1458
- package/src/architecture/network/activate/README.md +694 -694
- package/src/architecture/network/bootstrap/README.md +77 -77
- package/src/architecture/network/connect/README.md +74 -74
- package/src/architecture/network/deterministic/README.md +135 -135
- package/src/architecture/network/evolve/README.md +364 -364
- package/src/architecture/network/gating/README.md +130 -130
- package/src/architecture/network/genetic/README.md +399 -399
- package/src/architecture/network/mutate/README.md +897 -897
- package/src/architecture/network/onnx/README.md +720 -720
- package/src/architecture/network/onnx/export/README.md +728 -728
- package/src/architecture/network/onnx/export/layers/README.md +450 -450
- package/src/architecture/network/onnx/import/README.md +618 -618
- package/src/architecture/network/onnx/schema/README.md +32 -32
- package/src/architecture/network/prune/README.md +245 -245
- package/src/architecture/network/remove/README.md +135 -135
- package/src/architecture/network/runtime/README.md +106 -106
- package/src/architecture/network/serialize/README.md +542 -542
- package/src/architecture/network/slab/README.md +608 -608
- package/src/architecture/network/standalone/README.md +212 -212
- package/src/architecture/network/stats/README.md +84 -84
- package/src/architecture/network/topology/README.md +465 -465
- package/src/architecture/network/training/README.md +200 -200
- package/src/architecture/node/README.md +5 -5
- package/src/architecture/nodePool/README.md +14 -14
- package/src/methods/README.md +99 -99
- package/src/methods/activation/README.md +189 -189
- package/src/methods/cost/README.md +131 -131
- package/src/methods/rate/README.md +86 -86
- package/src/multithreading/README.md +77 -77
- package/src/multithreading/workers/browser/README.md +8 -8
- package/src/multithreading/workers/node/README.md +8 -8
- package/src/neat/README.md +148 -148
- package/src/neat/adaptive/README.md +120 -120
- package/src/neat/adaptive/acceptance/README.md +40 -40
- package/src/neat/adaptive/complexity/README.md +137 -137
- package/src/neat/adaptive/core/README.md +197 -197
- package/src/neat/adaptive/lineage/README.md +90 -90
- package/src/neat/adaptive/mutation/README.md +284 -284
- package/src/neat/compat/README.md +43 -43
- package/src/neat/compat/core/README.md +90 -90
- package/src/neat/diversity/README.md +35 -35
- package/src/neat/diversity/core/README.md +88 -88
- package/src/neat/evaluate/README.md +85 -85
- package/src/neat/evaluate/auto-distance/README.md +75 -75
- package/src/neat/evaluate/entropy-compat/README.md +37 -37
- package/src/neat/evaluate/entropy-sharing/README.md +43 -43
- package/src/neat/evaluate/fitness/README.md +23 -23
- package/src/neat/evaluate/novelty/README.md +120 -120
- package/src/neat/evaluate/objectives/README.md +17 -17
- package/src/neat/evaluate/shared/README.md +94 -94
- package/src/neat/evolve/README.md +96 -96
- package/src/neat/evolve/adaptive/README.md +60 -60
- package/src/neat/evolve/objectives/README.md +63 -63
- package/src/neat/evolve/offspring/README.md +56 -56
- package/src/neat/evolve/population/README.md +171 -171
- package/src/neat/evolve/runtime/README.md +79 -79
- package/src/neat/evolve/speciation/README.md +74 -74
- package/src/neat/evolve/warnings/README.md +10 -10
- package/src/neat/export/README.md +114 -114
- package/src/neat/helpers/README.md +50 -50
- package/src/neat/init/README.md +9 -9
- package/src/neat/lineage/core/README.md +101 -101
- package/src/neat/multiobjective/category/README.md +74 -74
- package/src/neat/multiobjective/crowding/README.md +272 -272
- package/src/neat/multiobjective/dominance/README.md +171 -171
- package/src/neat/multiobjective/fronts/README.md +68 -68
- package/src/neat/multiobjective/metrics/README.md +43 -43
- package/src/neat/multiobjective/objectives/README.md +31 -31
- package/src/neat/multiobjective/shared/README.md +27 -27
- package/src/neat/mutation/README.md +97 -97
- package/src/neat/mutation/add-conn/README.md +115 -115
- package/src/neat/mutation/add-node/README.md +126 -126
- package/src/neat/mutation/flow/README.md +149 -149
- package/src/neat/mutation/repair/README.md +185 -185
- package/src/neat/mutation/select/README.md +117 -117
- package/src/neat/mutation/shared/README.md +32 -32
- package/src/neat/objectives/README.md +25 -25
- package/src/neat/objectives/core/README.md +67 -67
- package/src/neat/pruning/README.md +40 -40
- package/src/neat/pruning/core/README.md +171 -171
- package/src/neat/pruning/facade/README.md +32 -32
- package/src/neat/rng/README.md +104 -104
- package/src/neat/rng/core/README.md +137 -137
- package/src/neat/rng/facade/README.md +50 -50
- package/src/neat/selection/README.md +111 -111
- package/src/neat/selection/core/README.md +227 -227
- package/src/neat/selection/facade/README.md +61 -61
- package/src/neat/shared/README.md +163 -163
- package/src/neat/speciation/README.md +31 -31
- package/src/neat/speciation/threshold/README.md +35 -35
- package/src/neat/species/README.md +25 -25
- package/src/neat/species/core/README.md +20 -20
- package/src/neat/species/core/shared/README.md +18 -18
- package/src/neat/species/history/context/README.md +22 -22
- package/src/neat/telemetry/accessors/README.md +58 -58
- package/src/neat/telemetry/exports/README.md +233 -233
- package/src/neat/telemetry/facade/README.md +252 -252
- package/src/neat/telemetry/facade/archive/README.md +57 -57
- package/src/neat/telemetry/facade/buffer/README.md +43 -43
- package/src/neat/telemetry/facade/lineage/README.md +12 -12
- package/src/neat/telemetry/facade/objectives/README.md +44 -44
- package/src/neat/telemetry/facade/runtime/README.md +26 -26
- package/src/neat/telemetry/facade/species/README.md +27 -27
- package/src/neat/telemetry/metrics/README.md +696 -696
- package/src/neat/telemetry/recorder/README.md +57 -57
- package/src/neat/telemetry/types/README.md +32 -32
- package/src/neat/topology-intent/README.md +75 -75
- package/src/utils/README.md +193 -193
- package/test/examples/asciiMaze/browser-entry/README.md +92 -92
- package/test/examples/asciiMaze/dashboardManager/README.md +109 -109
- package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +28 -28
- package/test/examples/asciiMaze/evolutionEngine/README.md +1527 -1527
- package/test/examples/asciiMaze/mazeMovement/README.md +105 -105
- package/test/examples/asciiMaze/mazeMovement/finalization/README.md +16 -16
- package/test/examples/asciiMaze/mazeMovement/policy/README.md +57 -57
- package/test/examples/asciiMaze/mazeMovement/runtime/README.md +52 -52
- package/test/examples/asciiMaze/mazeMovement/shaping/README.md +46 -46
- package/test/examples/flappy_bird/browser-entry/README.md +508 -508
- package/test/examples/flappy_bird/browser-entry/host/README.md +101 -101
- package/test/examples/flappy_bird/browser-entry/host/resize/README.md +144 -144
- package/test/examples/flappy_bird/browser-entry/network-view/README.md +194 -194
- package/test/examples/flappy_bird/browser-entry/playback/README.md +278 -278
- package/test/examples/flappy_bird/browser-entry/playback/background/README.md +129 -129
- package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +502 -502
- package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +139 -139
- package/test/examples/flappy_bird/browser-entry/playback/snapshot/README.md +10 -10
- package/test/examples/flappy_bird/browser-entry/playback/trail/README.md +43 -43
- package/test/examples/flappy_bird/browser-entry/playback/worker-channel/README.md +30 -30
- package/test/examples/flappy_bird/browser-entry/runtime/README.md +59 -59
- package/test/examples/flappy_bird/browser-entry/visualization/README.md +276 -276
- package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +16 -16
- package/test/examples/flappy_bird/constants/README.md +1070 -1070
- package/test/examples/flappy_bird/environment/README.md +22 -22
- package/test/examples/flappy_bird/evaluation/README.md +32 -32
- package/test/examples/flappy_bird/evaluation/rollout/README.md +141 -141
- package/test/examples/flappy_bird/flappy-evolution-worker/README.md +425 -425
- package/test/examples/flappy_bird/simulation-shared/README.md +170 -170
- package/test/examples/flappy_bird/simulation-shared/observation/README.md +109 -109
- package/test/examples/flappy_bird/trainer/README.md +325 -325
- package/test/examples/flappy_bird/trainer/evaluation/README.md +74 -74
- package/scripts/analyze-trace.ts +0 -590
- package/scripts/copy-examples.mjs +0 -114
- package/scripts/export-onnx.mjs +0 -86
- package/scripts/generate-bench-tables.mjs +0 -182
- package/scripts/generate-docs.ts +0 -2900
- package/scripts/write-dist-docs-pkg.mjs +0 -16
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Centralizes stable docs-generator constants and target definitions.
|
|
3
|
+
*
|
|
4
|
+
* Keeping these values in one file makes it easier to audit what the generator
|
|
5
|
+
* considers a target, a published output root, or an ordering-control file
|
|
6
|
+
* without mixing that policy into traversal or rendering code.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
|
|
11
|
+
import type { DocsTargetConfig } from './generate-docs.types.js';
|
|
12
|
+
|
|
13
|
+
/** Root docs output directory mirrored into the published docs site. */
|
|
14
|
+
export const DOCS_DIR = path.resolve('docs');
|
|
15
|
+
|
|
16
|
+
/** Default docs target when no CLI or environment override is supplied. */
|
|
17
|
+
export const DEFAULT_DOCS_TARGET = 'src';
|
|
18
|
+
|
|
19
|
+
/** Synthetic symbol name used to store file-level summary content. */
|
|
20
|
+
export const FILE_SUMMARY_SYMBOL_NAME = '__file_summary__';
|
|
21
|
+
|
|
22
|
+
/** Source-file glob used to discover docs-generator inputs. */
|
|
23
|
+
export const SOURCE_FILE_GLOBS = ['**/*.ts'];
|
|
24
|
+
|
|
25
|
+
/** Ignore rules for files that should never become generated docs sources. */
|
|
26
|
+
export const SOURCE_FILE_IGNORE_GLOBS = ['**/*.d.ts'];
|
|
27
|
+
|
|
28
|
+
/** Generated docs landing page file name for the folder index. */
|
|
29
|
+
export const FOLDER_INDEX_FILE_NAME = 'FOLDERS.md';
|
|
30
|
+
|
|
31
|
+
/** Per-directory ordering config file name. */
|
|
32
|
+
export const DOCS_ORDER_CONFIG_FILE_NAME = 'docs.order.json';
|
|
33
|
+
|
|
34
|
+
/** Supported keys accepted inside `docs.order.json`. */
|
|
35
|
+
export const DOCS_ORDER_SUPPORTED_KEYS = [
|
|
36
|
+
'introFile',
|
|
37
|
+
'fileOrder',
|
|
38
|
+
'symbolOrder',
|
|
39
|
+
'folderOrder',
|
|
40
|
+
'hiddenFiles',
|
|
41
|
+
'hiddenSymbols',
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
/** Workspace root used to rewrite absolute ts-morph type paths into repo paths. */
|
|
45
|
+
export const WORKSPACE_ROOT_DIR = path.resolve('.');
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Docs targets supported by the folder README generator.
|
|
49
|
+
*
|
|
50
|
+
* Each target maps one source tree into one published docs tree while keeping
|
|
51
|
+
* any target-specific root README mirroring rules local to the target.
|
|
52
|
+
*/
|
|
53
|
+
export const DOCS_TARGETS: Record<string, DocsTargetConfig> = {
|
|
54
|
+
src: {
|
|
55
|
+
name: 'src',
|
|
56
|
+
sourceDir: path.resolve('src'),
|
|
57
|
+
docsDir: DOCS_DIR,
|
|
58
|
+
rootDocsDir: path.join(DOCS_DIR, 'src'),
|
|
59
|
+
rootReadmeSource: path.resolve('README.md'),
|
|
60
|
+
rootReadmeDestination: path.join(DOCS_DIR, 'README.md'),
|
|
61
|
+
includeFolderIndex: true,
|
|
62
|
+
},
|
|
63
|
+
asciiMaze: {
|
|
64
|
+
name: 'asciiMaze',
|
|
65
|
+
sourceDir: path.resolve('test', 'examples', 'asciiMaze'),
|
|
66
|
+
docsDir: path.join(DOCS_DIR, 'examples', 'asciiMaze', 'docs'),
|
|
67
|
+
rootDocsDir: path.join(DOCS_DIR, 'examples', 'asciiMaze', 'docs'),
|
|
68
|
+
rootReadmeSource: path.resolve(
|
|
69
|
+
'test',
|
|
70
|
+
'examples',
|
|
71
|
+
'asciiMaze',
|
|
72
|
+
'README.md',
|
|
73
|
+
),
|
|
74
|
+
rootReadmeDestination: path.join(
|
|
75
|
+
DOCS_DIR,
|
|
76
|
+
'examples',
|
|
77
|
+
'asciiMaze',
|
|
78
|
+
'docs',
|
|
79
|
+
'README.md',
|
|
80
|
+
),
|
|
81
|
+
excludeRootSourceFiles: true,
|
|
82
|
+
publishedRootDir: path.join(DOCS_DIR, 'examples', 'asciiMaze'),
|
|
83
|
+
preservePublishedEntries: ['index.html'],
|
|
84
|
+
},
|
|
85
|
+
'flappy-bird': {
|
|
86
|
+
name: 'flappy-bird',
|
|
87
|
+
sourceDir: path.resolve('test', 'examples', 'flappy_bird'),
|
|
88
|
+
docsDir: path.join(DOCS_DIR, 'examples', 'flappy_bird', 'docs'),
|
|
89
|
+
rootDocsDir: path.join(DOCS_DIR, 'examples', 'flappy_bird', 'docs'),
|
|
90
|
+
rootReadmeSource: path.resolve(
|
|
91
|
+
'test',
|
|
92
|
+
'examples',
|
|
93
|
+
'flappy_bird',
|
|
94
|
+
'README.md',
|
|
95
|
+
),
|
|
96
|
+
rootReadmeDestination: path.join(
|
|
97
|
+
DOCS_DIR,
|
|
98
|
+
'examples',
|
|
99
|
+
'flappy_bird',
|
|
100
|
+
'docs',
|
|
101
|
+
'README.md',
|
|
102
|
+
),
|
|
103
|
+
excludeRootSourceFiles: true,
|
|
104
|
+
publishedRootDir: path.join(DOCS_DIR, 'examples', 'flappy_bird'),
|
|
105
|
+
preservePublishedEntries: ['index.html'],
|
|
106
|
+
},
|
|
107
|
+
};
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Owns `docs.order.json` loading, validation, and cached lookup.
|
|
3
|
+
*
|
|
4
|
+
* Rendering code only needs a validated config view; this chapter keeps JSON
|
|
5
|
+
* parsing, warning messages, and cache lifecycle separate from markdown logic.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs-extra';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
DOCS_ORDER_CONFIG_FILE_NAME,
|
|
13
|
+
DOCS_ORDER_SUPPORTED_KEYS,
|
|
14
|
+
WORKSPACE_ROOT_DIR,
|
|
15
|
+
} from './generate-docs.constants.js';
|
|
16
|
+
import type {
|
|
17
|
+
DirectoryDocsOrderConfig,
|
|
18
|
+
GenerateDocsState,
|
|
19
|
+
LoadedDirectoryDocsOrderConfig,
|
|
20
|
+
} from './generate-docs.types.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Loads and caches the optional per-folder docs ordering config.
|
|
24
|
+
*
|
|
25
|
+
* Phase 1 only validates and stores config so later rendering steps can reuse
|
|
26
|
+
* the same validated data without re-reading the file.
|
|
27
|
+
*
|
|
28
|
+
* @param state - Shared docs-generator state.
|
|
29
|
+
* @param directoryPath - Absolute directory path that may contain docs config.
|
|
30
|
+
* @returns Parsed and validated config when present.
|
|
31
|
+
*/
|
|
32
|
+
export async function loadDirectoryDocsOrderConfig(
|
|
33
|
+
state: GenerateDocsState,
|
|
34
|
+
directoryPath: string,
|
|
35
|
+
): Promise<LoadedDirectoryDocsOrderConfig | undefined> {
|
|
36
|
+
const normalizedDirectoryPath = path.resolve(directoryPath);
|
|
37
|
+
if (state.directoryDocsOrderConfigCache.has(normalizedDirectoryPath)) {
|
|
38
|
+
return state.directoryDocsOrderConfigCache.get(normalizedDirectoryPath)!;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const pendingConfig = readDirectoryDocsOrderConfig(
|
|
42
|
+
normalizedDirectoryPath,
|
|
43
|
+
).then((loadedConfig) => {
|
|
44
|
+
state.resolvedDirectoryDocsOrderConfigCache.set(
|
|
45
|
+
normalizedDirectoryPath,
|
|
46
|
+
loadedConfig,
|
|
47
|
+
);
|
|
48
|
+
return loadedConfig;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
state.directoryDocsOrderConfigCache.set(
|
|
52
|
+
normalizedDirectoryPath,
|
|
53
|
+
pendingConfig,
|
|
54
|
+
);
|
|
55
|
+
return pendingConfig;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Returns the cached docs ordering config for a directory.
|
|
60
|
+
*
|
|
61
|
+
* @param state - Shared docs-generator state.
|
|
62
|
+
* @param directoryPath - Absolute directory path.
|
|
63
|
+
* @returns Cached config when already loaded.
|
|
64
|
+
*/
|
|
65
|
+
export function getCachedDirectoryDocsOrderConfig(
|
|
66
|
+
state: GenerateDocsState,
|
|
67
|
+
directoryPath: string,
|
|
68
|
+
): LoadedDirectoryDocsOrderConfig | undefined {
|
|
69
|
+
return state.resolvedDirectoryDocsOrderConfigCache.get(
|
|
70
|
+
path.resolve(directoryPath),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Writes a scoped warning for one docs ordering config file.
|
|
76
|
+
*
|
|
77
|
+
* @param configPath - Absolute config path.
|
|
78
|
+
* @param message - Warning message.
|
|
79
|
+
* @returns Nothing.
|
|
80
|
+
*/
|
|
81
|
+
export function warnDirectoryDocsOrderConfig(
|
|
82
|
+
configPath: string,
|
|
83
|
+
message: string,
|
|
84
|
+
): void {
|
|
85
|
+
const relativeConfigPath = path
|
|
86
|
+
.relative(WORKSPACE_ROOT_DIR, configPath)
|
|
87
|
+
.replace(/\\/g, '/');
|
|
88
|
+
console.warn(`[docs] ${relativeConfigPath}: ${message}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Reads and validates one directory's `docs.order.json` file when present.
|
|
93
|
+
*
|
|
94
|
+
* @param directoryPath - Absolute directory path.
|
|
95
|
+
* @returns Parsed config or undefined when absent or invalid.
|
|
96
|
+
*/
|
|
97
|
+
async function readDirectoryDocsOrderConfig(
|
|
98
|
+
directoryPath: string,
|
|
99
|
+
): Promise<LoadedDirectoryDocsOrderConfig | undefined> {
|
|
100
|
+
const configPath = path.join(directoryPath, DOCS_ORDER_CONFIG_FILE_NAME);
|
|
101
|
+
if (!(await fs.pathExists(configPath))) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const rawConfigText = await fs.readFile(configPath, 'utf8');
|
|
107
|
+
const parsedConfig: unknown = JSON.parse(rawConfigText);
|
|
108
|
+
const validatedConfig = validateDirectoryDocsOrderConfig(
|
|
109
|
+
parsedConfig,
|
|
110
|
+
configPath,
|
|
111
|
+
);
|
|
112
|
+
return validatedConfig
|
|
113
|
+
? { configPath, config: validatedConfig }
|
|
114
|
+
: undefined;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
warnDirectoryDocsOrderConfig(
|
|
117
|
+
configPath,
|
|
118
|
+
`Failed to read ${DOCS_ORDER_CONFIG_FILE_NAME}: ${getErrorMessage(error)}`,
|
|
119
|
+
);
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Validates the supported phase-1 docs ordering config keys.
|
|
126
|
+
*
|
|
127
|
+
* @param parsedConfig - Raw parsed JSON value.
|
|
128
|
+
* @param configPath - Absolute config path used in warnings.
|
|
129
|
+
* @returns Sanitized config when at least one supported value is valid.
|
|
130
|
+
*/
|
|
131
|
+
function validateDirectoryDocsOrderConfig(
|
|
132
|
+
parsedConfig: unknown,
|
|
133
|
+
configPath: string,
|
|
134
|
+
): DirectoryDocsOrderConfig | undefined {
|
|
135
|
+
if (!isRecord(parsedConfig)) {
|
|
136
|
+
warnDirectoryDocsOrderConfig(
|
|
137
|
+
configPath,
|
|
138
|
+
'Config must be a JSON object. Ignoring file.',
|
|
139
|
+
);
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
for (const configKey of Object.keys(parsedConfig)) {
|
|
144
|
+
if (!DOCS_ORDER_SUPPORTED_KEYS.includes(configKey as never)) {
|
|
145
|
+
warnDirectoryDocsOrderConfig(
|
|
146
|
+
configPath,
|
|
147
|
+
`Unknown key "${configKey}". Supported keys: ${DOCS_ORDER_SUPPORTED_KEYS.join(', ')}`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const validatedConfig: DirectoryDocsOrderConfig = {};
|
|
153
|
+
const introFile = normalizeOptionalStringConfigValue(
|
|
154
|
+
parsedConfig.introFile,
|
|
155
|
+
'introFile',
|
|
156
|
+
configPath,
|
|
157
|
+
);
|
|
158
|
+
if (introFile) {
|
|
159
|
+
validatedConfig.introFile = introFile;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const fileOrder = normalizeStringArrayConfigValue(
|
|
163
|
+
parsedConfig.fileOrder,
|
|
164
|
+
'fileOrder',
|
|
165
|
+
configPath,
|
|
166
|
+
);
|
|
167
|
+
if (fileOrder) {
|
|
168
|
+
validatedConfig.fileOrder = fileOrder;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const symbolOrder = normalizeSymbolOrderConfigValue(
|
|
172
|
+
parsedConfig.symbolOrder,
|
|
173
|
+
configPath,
|
|
174
|
+
);
|
|
175
|
+
if (symbolOrder) {
|
|
176
|
+
validatedConfig.symbolOrder = symbolOrder;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const folderOrder = normalizeStringArrayConfigValue(
|
|
180
|
+
parsedConfig.folderOrder,
|
|
181
|
+
'folderOrder',
|
|
182
|
+
configPath,
|
|
183
|
+
);
|
|
184
|
+
if (folderOrder) {
|
|
185
|
+
validatedConfig.folderOrder = folderOrder;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const hiddenFiles = normalizeStringArrayConfigValue(
|
|
189
|
+
parsedConfig.hiddenFiles,
|
|
190
|
+
'hiddenFiles',
|
|
191
|
+
configPath,
|
|
192
|
+
);
|
|
193
|
+
if (hiddenFiles) {
|
|
194
|
+
validatedConfig.hiddenFiles = hiddenFiles;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const hiddenSymbols = normalizeStringArrayConfigValue(
|
|
198
|
+
parsedConfig.hiddenSymbols,
|
|
199
|
+
'hiddenSymbols',
|
|
200
|
+
configPath,
|
|
201
|
+
);
|
|
202
|
+
if (hiddenSymbols) {
|
|
203
|
+
validatedConfig.hiddenSymbols = hiddenSymbols;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return Object.keys(validatedConfig).length > 0 ? validatedConfig : undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Normalizes a single optional string config field.
|
|
211
|
+
*
|
|
212
|
+
* @param value - Raw config value.
|
|
213
|
+
* @param fieldName - Config field name.
|
|
214
|
+
* @param configPath - Absolute config path used in warnings.
|
|
215
|
+
* @returns Trimmed string when valid.
|
|
216
|
+
*/
|
|
217
|
+
function normalizeOptionalStringConfigValue(
|
|
218
|
+
value: unknown,
|
|
219
|
+
fieldName: string,
|
|
220
|
+
configPath: string,
|
|
221
|
+
): string | undefined {
|
|
222
|
+
if (value === undefined) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
227
|
+
warnDirectoryDocsOrderConfig(
|
|
228
|
+
configPath,
|
|
229
|
+
`Field "${fieldName}" must be a non-empty string. Ignoring value.`,
|
|
230
|
+
);
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return value.trim();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Normalizes one string-array config field.
|
|
239
|
+
*
|
|
240
|
+
* @param value - Raw config value.
|
|
241
|
+
* @param fieldName - Config field name.
|
|
242
|
+
* @param configPath - Absolute config path used in warnings.
|
|
243
|
+
* @returns Unique non-empty strings when valid.
|
|
244
|
+
*/
|
|
245
|
+
function normalizeStringArrayConfigValue(
|
|
246
|
+
value: unknown,
|
|
247
|
+
fieldName: string,
|
|
248
|
+
configPath: string,
|
|
249
|
+
): string[] | undefined {
|
|
250
|
+
if (value === undefined) {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (!Array.isArray(value)) {
|
|
255
|
+
warnDirectoryDocsOrderConfig(
|
|
256
|
+
configPath,
|
|
257
|
+
`Field "${fieldName}" must be an array of non-empty strings. Ignoring value.`,
|
|
258
|
+
);
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const normalizedEntries = value
|
|
263
|
+
.filter((entry): entry is string => typeof entry === 'string')
|
|
264
|
+
.map((entry) => entry.trim())
|
|
265
|
+
.filter((entry) => entry.length > 0);
|
|
266
|
+
|
|
267
|
+
if (normalizedEntries.length !== value.length) {
|
|
268
|
+
warnDirectoryDocsOrderConfig(
|
|
269
|
+
configPath,
|
|
270
|
+
`Field "${fieldName}" must contain only non-empty strings. Dropping invalid entries.`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return normalizedEntries.length > 0
|
|
275
|
+
? [...new Set(normalizedEntries)]
|
|
276
|
+
: undefined;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Normalizes the per-file symbol ordering map.
|
|
281
|
+
*
|
|
282
|
+
* @param value - Raw config value.
|
|
283
|
+
* @param configPath - Absolute config path used in warnings.
|
|
284
|
+
* @returns Sanitized symbol-order map when valid.
|
|
285
|
+
*/
|
|
286
|
+
function normalizeSymbolOrderConfigValue(
|
|
287
|
+
value: unknown,
|
|
288
|
+
configPath: string,
|
|
289
|
+
): Record<string, string[]> | undefined {
|
|
290
|
+
if (value === undefined) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!isRecord(value)) {
|
|
295
|
+
warnDirectoryDocsOrderConfig(
|
|
296
|
+
configPath,
|
|
297
|
+
'Field "symbolOrder" must be an object keyed by file name. Ignoring value.',
|
|
298
|
+
);
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const normalizedSymbolOrderEntries = Object.entries(value)
|
|
303
|
+
.map(([fileName, symbolNames]) => {
|
|
304
|
+
const normalizedFileName = fileName.trim();
|
|
305
|
+
if (normalizedFileName.length === 0) {
|
|
306
|
+
warnDirectoryDocsOrderConfig(
|
|
307
|
+
configPath,
|
|
308
|
+
'Field "symbolOrder" contains an empty file key. Dropping entry.',
|
|
309
|
+
);
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const normalizedSymbols = normalizeStringArrayConfigValue(
|
|
314
|
+
symbolNames,
|
|
315
|
+
`symbolOrder.${normalizedFileName}`,
|
|
316
|
+
configPath,
|
|
317
|
+
);
|
|
318
|
+
if (!normalizedSymbols) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return [normalizedFileName, normalizedSymbols] as const;
|
|
323
|
+
})
|
|
324
|
+
.filter(
|
|
325
|
+
(entry): entry is readonly [string, string[]] => entry !== undefined,
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
return normalizedSymbolOrderEntries.length > 0
|
|
329
|
+
? Object.fromEntries(normalizedSymbolOrderEntries)
|
|
330
|
+
: undefined;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Narrows unknown values to simple object records.
|
|
335
|
+
*
|
|
336
|
+
* @param value - Value to inspect.
|
|
337
|
+
* @returns True when the value is a plain record-like object.
|
|
338
|
+
*/
|
|
339
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
340
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Extracts a readable message from unknown thrown values.
|
|
345
|
+
*
|
|
346
|
+
* @param error - Thrown value.
|
|
347
|
+
* @returns Human-readable error text.
|
|
348
|
+
*/
|
|
349
|
+
function getErrorMessage(error: unknown): string {
|
|
350
|
+
if (error instanceof Error) {
|
|
351
|
+
return error.message;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return String(error);
|
|
355
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Creates the shared runtime state for one docs-generation process.
|
|
3
|
+
*
|
|
4
|
+
* The generator intentionally reuses one ts-morph project and one docs-order
|
|
5
|
+
* cache set so each chapter can stay pure about its responsibility while the
|
|
6
|
+
* process still shares expensive state safely.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Project } from 'ts-morph';
|
|
10
|
+
|
|
11
|
+
import type { GenerateDocsState } from './generate-docs.types.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates the mutable runtime state shared across one docs-generation run.
|
|
15
|
+
*
|
|
16
|
+
* The generator intentionally keeps one ts-morph project and one pair of
|
|
17
|
+
* docs-order caches for the full process so each target run can reuse the same
|
|
18
|
+
* lookup behavior without relying on module-level globals.
|
|
19
|
+
*
|
|
20
|
+
* @returns Shared docs-generator state.
|
|
21
|
+
*/
|
|
22
|
+
export function createGenerateDocsState(): GenerateDocsState {
|
|
23
|
+
return {
|
|
24
|
+
project: new Project({
|
|
25
|
+
tsConfigFilePath: 'tsconfig.json',
|
|
26
|
+
skipAddingFilesFromTsConfig: true,
|
|
27
|
+
}),
|
|
28
|
+
resolvedDirectoryDocsOrderConfigCache: new Map(),
|
|
29
|
+
directoryDocsOrderConfigCache: new Map(),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Owns CLI target selection and source-tree preparation for one docs run.
|
|
3
|
+
*
|
|
4
|
+
* This chapter decides what tree is being documented and which source files are
|
|
5
|
+
* eligible before any ts-morph symbol work or markdown rendering begins.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fg from 'fast-glob';
|
|
9
|
+
import fs from 'fs-extra';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import type { SourceFile } from 'ts-morph';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
DEFAULT_DOCS_TARGET,
|
|
15
|
+
DOCS_TARGETS,
|
|
16
|
+
SOURCE_FILE_GLOBS,
|
|
17
|
+
SOURCE_FILE_IGNORE_GLOBS,
|
|
18
|
+
} from './generate-docs.constants.js';
|
|
19
|
+
import type {
|
|
20
|
+
DocsTargetConfig,
|
|
21
|
+
GenerateDocsState,
|
|
22
|
+
} from './generate-docs.types.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolves the active docs target from CLI or environment input.
|
|
26
|
+
*
|
|
27
|
+
* Lookup order:
|
|
28
|
+
* 1. `--target=...`
|
|
29
|
+
* 2. `DOCS_TARGET`
|
|
30
|
+
* 3. default target
|
|
31
|
+
*
|
|
32
|
+
* @param rawArguments - CLI arguments passed after the executable path.
|
|
33
|
+
* @returns Concrete docs target configuration.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveDocsTarget(
|
|
36
|
+
rawArguments: readonly string[],
|
|
37
|
+
): DocsTargetConfig {
|
|
38
|
+
const cliTarget = rawArguments
|
|
39
|
+
.find((argument) => argument.startsWith('--target='))
|
|
40
|
+
?.slice('--target='.length);
|
|
41
|
+
const requestedTarget =
|
|
42
|
+
cliTarget ?? process.env.DOCS_TARGET ?? DEFAULT_DOCS_TARGET;
|
|
43
|
+
const resolvedTarget = DOCS_TARGETS[requestedTarget];
|
|
44
|
+
|
|
45
|
+
if (!resolvedTarget) {
|
|
46
|
+
const supportedTargets = Object.keys(DOCS_TARGETS).toSorted().join(', ');
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Unknown docs target "${requestedTarget}". Supported targets: ${supportedTargets}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return resolvedTarget;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Prepares the output tree for the selected target.
|
|
57
|
+
*
|
|
58
|
+
* @param target - Target configuration.
|
|
59
|
+
* @returns Nothing.
|
|
60
|
+
*/
|
|
61
|
+
export async function initializeDocsTarget(
|
|
62
|
+
target: DocsTargetConfig,
|
|
63
|
+
): Promise<void> {
|
|
64
|
+
await cleanupPublishedRoot(target);
|
|
65
|
+
await fs.ensureDir(target.docsDir);
|
|
66
|
+
|
|
67
|
+
if (
|
|
68
|
+
!target.rootReadmeSource ||
|
|
69
|
+
!target.rootReadmeDestination ||
|
|
70
|
+
!(await fs.pathExists(target.rootReadmeSource))
|
|
71
|
+
) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await fs.ensureDir(path.dirname(target.rootReadmeDestination));
|
|
76
|
+
await fs.copyFile(target.rootReadmeSource, target.rootReadmeDestination);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Loads target source files into the shared ts-morph project.
|
|
81
|
+
*
|
|
82
|
+
* @param state - Shared docs-generator state.
|
|
83
|
+
* @param target - Target configuration.
|
|
84
|
+
* @returns Filtered source files that belong to the target tree.
|
|
85
|
+
*/
|
|
86
|
+
export async function loadTargetSourceFiles(
|
|
87
|
+
state: GenerateDocsState,
|
|
88
|
+
target: DocsTargetConfig,
|
|
89
|
+
): Promise<SourceFile[]> {
|
|
90
|
+
const filePaths = await fg(SOURCE_FILE_GLOBS, {
|
|
91
|
+
cwd: target.sourceDir,
|
|
92
|
+
absolute: true,
|
|
93
|
+
ignore: SOURCE_FILE_IGNORE_GLOBS,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
for (const filePath of filePaths) {
|
|
97
|
+
if (!shouldIncludeSourceFile(filePath, target)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
state.project.addSourceFileAtPath(filePath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const rawSourceFiles = state.project.getSourceFiles();
|
|
105
|
+
const sourceFiles = rawSourceFiles.filter((sourceFile) => {
|
|
106
|
+
const filePath = sourceFile.getFilePath();
|
|
107
|
+
return !filePath.endsWith('.d.ts') && !/node_modules/.test(filePath);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log(
|
|
111
|
+
`[docs:${target.name}] Loaded ${sourceFiles.length} source files (raw: ${rawSourceFiles.length})`,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return sourceFiles;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Determines whether a discovered file should participate in docs generation.
|
|
119
|
+
*
|
|
120
|
+
* @param filePath - Absolute source file path.
|
|
121
|
+
* @param target - Target configuration.
|
|
122
|
+
* @returns True when the file belongs in the target set.
|
|
123
|
+
*/
|
|
124
|
+
function shouldIncludeSourceFile(
|
|
125
|
+
filePath: string,
|
|
126
|
+
target: DocsTargetConfig,
|
|
127
|
+
): boolean {
|
|
128
|
+
if (/\.test\.ts$/i.test(filePath)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!target.excludeRootSourceFiles) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const relativeDirectory = path.dirname(
|
|
137
|
+
path.relative(target.sourceDir, filePath),
|
|
138
|
+
);
|
|
139
|
+
return relativeDirectory !== '' && relativeDirectory !== '.';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Removes previously published generated files for targets that mirror output
|
|
144
|
+
* into a browsable published directory.
|
|
145
|
+
*
|
|
146
|
+
* @param target - Target configuration.
|
|
147
|
+
* @returns Nothing.
|
|
148
|
+
*/
|
|
149
|
+
async function cleanupPublishedRoot(target: DocsTargetConfig): Promise<void> {
|
|
150
|
+
if (!target.publishedRootDir) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
await fs.ensureDir(target.publishedRootDir);
|
|
155
|
+
const preservedEntries = new Set(target.preservePublishedEntries ?? []);
|
|
156
|
+
const childEntries = await fs.readdir(target.publishedRootDir);
|
|
157
|
+
|
|
158
|
+
for (const childEntry of childEntries) {
|
|
159
|
+
if (preservedEntries.has(childEntry)) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
await fs.remove(path.join(target.publishedRootDir, childEntry));
|
|
164
|
+
}
|
|
165
|
+
}
|