@ttsc/graph 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +15 -3
- package/lib/index.js.map +1 -1
- package/lib/model/TtscGraphMemory.d.ts +26 -0
- package/lib/model/TtscGraphMemory.js +121 -2
- package/lib/model/TtscGraphMemory.js.map +1 -1
- package/lib/model/TtscGraphSession.d.ts +23 -0
- package/lib/model/TtscGraphSession.js +248 -96
- package/lib/model/TtscGraphSession.js.map +1 -1
- package/lib/model/TtscGraphShardStore.js +6 -1
- package/lib/model/TtscGraphShardStore.js.map +1 -1
- package/lib/model/TtscLintDaemon.d.ts +54 -0
- package/lib/model/TtscLintDaemon.js +166 -0
- package/lib/model/TtscLintDaemon.js.map +1 -0
- package/lib/model/loadGraph.d.ts +8 -1
- package/lib/model/loadGraph.js +144 -72
- package/lib/model/loadGraph.js.map +1 -1
- package/lib/model/publishedArtifacts.d.ts +142 -0
- package/lib/model/publishedArtifacts.js +403 -0
- package/lib/model/publishedArtifacts.js.map +1 -0
- package/lib/reduce.js +20 -7
- package/lib/reduce.js.map +1 -1
- package/lib/server/createServer.js +38 -2
- package/lib/server/createServer.js.map +1 -1
- package/lib/server/runDetails.d.ts +15 -0
- package/lib/server/runDetails.js +48 -0
- package/lib/server/runDetails.js.map +1 -1
- package/lib/server/runEntrypoints.js +7 -1
- package/lib/server/runEntrypoints.js.map +1 -1
- package/lib/server/runLookup.js +129 -11
- package/lib/server/runLookup.js.map +1 -1
- package/lib/structures/ITtscGraphApplication.d.ts +3 -1
- package/lib/structures/ITtscGraphDetails.d.ts +12 -0
- package/lib/structures/ITtscGraphDocTag.d.ts +44 -0
- package/lib/structures/ITtscGraphDocTag.js +3 -0
- package/lib/structures/ITtscGraphDocTag.js.map +1 -0
- package/lib/structures/ITtscGraphDump.d.ts +23 -4
- package/lib/structures/ITtscGraphLookup.d.ts +29 -0
- package/lib/structures/ITtscGraphNode.d.ts +25 -0
- package/lib/structures/TtscGraphArtifactNodeKind.d.ts +23 -0
- package/lib/structures/TtscGraphArtifactNodeKind.js +37 -0
- package/lib/structures/TtscGraphArtifactNodeKind.js.map +1 -0
- package/lib/structures/TtscGraphDumpEdgeKind.d.ts +1 -1
- package/lib/structures/TtscGraphDumpNodeKind.d.ts +10 -2
- package/lib/structures/TtscGraphEdgeKind.d.ts +8 -1
- package/lib/structures/TtscGraphNodeKind.d.ts +1 -1
- package/lib/structures/index.d.ts +2 -0
- package/lib/structures/index.js +2 -0
- package/lib/structures/index.js.map +1 -1
- package/lib/view.js +17 -1
- package/lib/view.js.map +1 -1
- package/lib/viewer/index.html +5 -13
- package/lib/viewer/viewer.js +190 -190
- package/package.json +5 -5
- package/src/index.ts +23 -6
- package/src/model/TtscGraphMemory.ts +118 -2
- package/src/model/TtscGraphSession.ts +112 -2
- package/src/model/TtscGraphShardStore.ts +6 -1
- package/src/model/TtscLintDaemon.ts +179 -0
- package/src/model/loadGraph.ts +29 -5
- package/src/model/publishedArtifacts.ts +548 -0
- package/src/reduce.ts +20 -7
- package/src/server/runDetails.ts +52 -1
- package/src/server/runEntrypoints.ts +7 -1
- package/src/server/runLookup.ts +139 -14
- package/src/structures/ITtscGraphApplication.ts +3 -1
- package/src/structures/ITtscGraphDetails.ts +13 -0
- package/src/structures/ITtscGraphDocTag.ts +45 -0
- package/src/structures/ITtscGraphDump.ts +25 -4
- package/src/structures/ITtscGraphLookup.ts +31 -0
- package/src/structures/ITtscGraphNode.ts +27 -0
- package/src/structures/TtscGraphArtifactNodeKind.ts +35 -0
- package/src/structures/TtscGraphDumpEdgeKind.ts +1 -0
- package/src/structures/TtscGraphDumpNodeKind.ts +16 -2
- package/src/structures/TtscGraphEdgeKind.ts +8 -0
- package/src/structures/TtscGraphNodeKind.ts +7 -1
- package/src/structures/index.ts +2 -0
- package/src/view.ts +17 -1
- package/src/viewer/index.html +5 -13
- package/src/viewer/legend.ts +107 -0
- package/src/viewer/main.ts +19 -21
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { type ITtscCapabilityPlugin } from "ttsc";
|
|
2
|
+
import { TtscLintDaemon } from "./TtscLintDaemon";
|
|
3
|
+
/**
|
|
4
|
+
* Ask the project's `@ttsc/lint` for the artifacts a citation can name, and
|
|
5
|
+
* write them where `ttscgraph dump --artifacts` reads them.
|
|
6
|
+
*
|
|
7
|
+
* A project that configures no such plugin gets `file: null`, which is the
|
|
8
|
+
* common case and not an error: the graph it produces is the graph it produced
|
|
9
|
+
* before this existed, and the dump says so by not claiming the capability.
|
|
10
|
+
*
|
|
11
|
+
* ## Why this runs here and not in the compiler host
|
|
12
|
+
*
|
|
13
|
+
* The addresses a citation names — a Markdown anchor, `prisma:Sale.price`,
|
|
14
|
+
* `POST:/orders` — are produced by parsers that live in the rule that owns
|
|
15
|
+
* them, and re-deriving any of them in the graph producer would be a second
|
|
16
|
+
* implementation of a published contract. So the units have to arrive from the
|
|
17
|
+
* rule.
|
|
18
|
+
*
|
|
19
|
+
* They cannot arrive in-process. `ttscgraph` is the shipped per-platform
|
|
20
|
+
* binary, never a per-project native host, so it can never have a linked
|
|
21
|
+
* plugin; and `packages/lint` is its own Go module that deliberately carries no
|
|
22
|
+
* requirement on the compiler host. What is left is the channel the host
|
|
23
|
+
* already has: a plugin declares a capability and its sidecar answers a verb,
|
|
24
|
+
* exactly as `lsp-hints` does. `resolveCapabilityPlugins` is what builds and
|
|
25
|
+
* locates those sidecars, and it is the seam `ttscserver` already uses for
|
|
26
|
+
* `capabilities.lsp`, published so a consumer outside the compiler can ask
|
|
27
|
+
* too.
|
|
28
|
+
*
|
|
29
|
+
* Nothing here knows what `@ttsc/evidence` is. It asks a lint install for
|
|
30
|
+
* whatever its configured rules published, and a project that configured none
|
|
31
|
+
* gets an empty answer.
|
|
32
|
+
*/
|
|
33
|
+
export interface IPublishedArtifacts {
|
|
34
|
+
/**
|
|
35
|
+
* Path to the JSON the native producer reads, or `null` when no configured
|
|
36
|
+
* plugin publishes one.
|
|
37
|
+
*
|
|
38
|
+
* `null` is a state rather than an absence, which is why it still carries
|
|
39
|
+
* {@link inputs}. A project that adds an evidence plugin while a session is
|
|
40
|
+
* running would otherwise never be reconsidered: nothing would be watched, so
|
|
41
|
+
* nothing could report that the answer had changed from "none" to "some".
|
|
42
|
+
*/
|
|
43
|
+
file: string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Everything the answer was derived from, as paths this process can state for
|
|
46
|
+
* itself.
|
|
47
|
+
*
|
|
48
|
+
* The artifacts describe documents the compiler's Program never read, so a
|
|
49
|
+
* source edit does not move them and a document edit does not move the code
|
|
50
|
+
* graph. Refreshing them is therefore a second invalidation with its own
|
|
51
|
+
* inputs, and these are those inputs.
|
|
52
|
+
*/
|
|
53
|
+
inputs: IArtifactInputs;
|
|
54
|
+
/**
|
|
55
|
+
* The state of {@link inputs} when the answer was produced.
|
|
56
|
+
*
|
|
57
|
+
* Compared against a freshly taken one to decide whether the answer is stale.
|
|
58
|
+
* When it moved, nothing else in the session can tell: the compiler's own
|
|
59
|
+
* invalidation watches the build universe, and none of this is in it.
|
|
60
|
+
*/
|
|
61
|
+
fingerprint: string;
|
|
62
|
+
}
|
|
63
|
+
/** Paths an answer was derived from, split by how they are watched. */
|
|
64
|
+
export interface IArtifactInputs {
|
|
65
|
+
/** Files stated one by one. */
|
|
66
|
+
files: string[];
|
|
67
|
+
/** Directories walked, which is what notices an added or deleted file. */
|
|
68
|
+
directories: IArtifactDirectory[];
|
|
69
|
+
}
|
|
70
|
+
/** A directory watched on behalf of the pattern that named it. */
|
|
71
|
+
export interface IArtifactDirectory {
|
|
72
|
+
/** Absolute path of the directory to walk. */
|
|
73
|
+
path: string;
|
|
74
|
+
/**
|
|
75
|
+
* Whether the walk descends.
|
|
76
|
+
*
|
|
77
|
+
* Taken from the pattern rather than assumed, because assuming it is
|
|
78
|
+
* expensive in exactly the case that looks harmless: a rule declaring `*.md`
|
|
79
|
+
* has the project root for its fixed prefix, and treating that as recursive
|
|
80
|
+
* would state every file in the repository before every graph request.
|
|
81
|
+
*/
|
|
82
|
+
recursive: boolean;
|
|
83
|
+
}
|
|
84
|
+
export declare function publishArtifacts(options: {
|
|
85
|
+
cwd: string;
|
|
86
|
+
tsconfig: string;
|
|
87
|
+
}): IPublishedArtifacts;
|
|
88
|
+
/**
|
|
89
|
+
* The same answer, asked of sidecars this caller keeps open.
|
|
90
|
+
*
|
|
91
|
+
* A one-shot has nothing to amortize — its process exits after one question —
|
|
92
|
+
* so `publishArtifacts` stays a spawn per verb and stays synchronous, which is
|
|
93
|
+
* what its three CLI callers are. A resident session asks both verbs again
|
|
94
|
+
* every time a document moves, and that is where a process, a plugin load and a
|
|
95
|
+
* Program per question stopped being affordable.
|
|
96
|
+
*
|
|
97
|
+
* A daemon that cannot answer falls back to the direct command for that plugin,
|
|
98
|
+
* so the answer is the same one either way and only its cost differs. The
|
|
99
|
+
* fallback matters more here than most: a daemon that quietly answered nothing
|
|
100
|
+
* would be indistinguishable from a project that publishes nothing.
|
|
101
|
+
*/
|
|
102
|
+
export declare function publishArtifactsResident(options: {
|
|
103
|
+
cwd: string;
|
|
104
|
+
tsconfig: string;
|
|
105
|
+
}, daemon: (plugin: ITtscCapabilityPlugin) => TtscLintDaemon | undefined): Promise<IPublishedArtifacts>;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the inputs an answer was derived from have moved since.
|
|
108
|
+
*
|
|
109
|
+
* Answered by stating paths this process already knows, not by asking the
|
|
110
|
+
* plugin again. The question is asked before every graph request in a resident
|
|
111
|
+
* session, and re-running plugin discovery per request would cost more than the
|
|
112
|
+
* refresh it guards — while a `stat` per document costs less than reading one
|
|
113
|
+
* of them.
|
|
114
|
+
*
|
|
115
|
+
* The cost of being wrong in the cheap direction is what makes this worth
|
|
116
|
+
* paying at all: a developer who edited only a spec section, and nothing the
|
|
117
|
+
* compiler reads, otherwise saw the graph keep answering with the headings that
|
|
118
|
+
* section used to have.
|
|
119
|
+
*/
|
|
120
|
+
export declare function artifactsAreStale(published: IPublishedArtifacts): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* The directory a declared pattern makes worth walking, or `null` when the
|
|
123
|
+
* pattern names one path and should simply be stated.
|
|
124
|
+
*
|
|
125
|
+
* Two readings have to be right here, and both are cheap to get wrong. A
|
|
126
|
+
* pattern carrying no wildcard is a path, not a tree: watching its parent
|
|
127
|
+
* instead would state every sibling on every request to learn about the one
|
|
128
|
+
* file that was declared. And a pattern that does not say `**` does not descend
|
|
129
|
+
* — treating it as though it did is unbounded in exactly the case that looks
|
|
130
|
+
* harmless, because a bare `*.md` has the project root for its prefix.
|
|
131
|
+
*/
|
|
132
|
+
export declare function watchedBy(pattern: string, cwd: string): IArtifactDirectory | null;
|
|
133
|
+
/**
|
|
134
|
+
* The state of every input, as one comparable string.
|
|
135
|
+
*
|
|
136
|
+
* Files are stated by size and modification time rather than content: this runs
|
|
137
|
+
* before every graph request, and hashing a documentation corpus per request
|
|
138
|
+
* would cost more than the refresh it guards. Directories are walked for the
|
|
139
|
+
* same pair, which is what notices a section added or a document deleted rather
|
|
140
|
+
* than edited.
|
|
141
|
+
*/
|
|
142
|
+
export declare function fingerprintInputs(inputs: IArtifactInputs): string;
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.publishArtifacts = publishArtifacts;
|
|
7
|
+
exports.publishArtifactsResident = publishArtifactsResident;
|
|
8
|
+
exports.artifactsAreStale = artifactsAreStale;
|
|
9
|
+
exports.watchedBy = watchedBy;
|
|
10
|
+
exports.fingerprintInputs = fingerprintInputs;
|
|
11
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
|
+
const node_crypto_1 = require("node:crypto");
|
|
13
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const ttsc_1 = require("ttsc");
|
|
17
|
+
function publishArtifacts(options) {
|
|
18
|
+
const plugins = (0, ttsc_1.resolveCapabilityPlugins)({
|
|
19
|
+
capability: "graphNodes",
|
|
20
|
+
cwd: options.cwd,
|
|
21
|
+
tsconfig: options.tsconfig,
|
|
22
|
+
});
|
|
23
|
+
if (plugins.length === 0)
|
|
24
|
+
return unpublished(options);
|
|
25
|
+
// The inputs are stated before the set is asked for, never after. A document
|
|
26
|
+
// edited between the two calls has to read as a change next time, and only
|
|
27
|
+
// this order gives that: a fingerprint taken first describes a state at least
|
|
28
|
+
// as old as the set it labels, so the worst it can cost is one republish that
|
|
29
|
+
// finds nothing new. Taken afterwards it would describe a state newer than
|
|
30
|
+
// the set, and the edit that landed in the gap would read as already
|
|
31
|
+
// accounted for — the exact staleness this exists to remove.
|
|
32
|
+
const inputs = readInputs(plugins.map((plugin) => runVerb(plugin, "project-inputs", options)), options);
|
|
33
|
+
return assemble(options, inputs, plugins.map((plugin) => runVerb(plugin, "graph-nodes", options)));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The same answer, asked of sidecars this caller keeps open.
|
|
37
|
+
*
|
|
38
|
+
* A one-shot has nothing to amortize — its process exits after one question —
|
|
39
|
+
* so `publishArtifacts` stays a spawn per verb and stays synchronous, which is
|
|
40
|
+
* what its three CLI callers are. A resident session asks both verbs again
|
|
41
|
+
* every time a document moves, and that is where a process, a plugin load and a
|
|
42
|
+
* Program per question stopped being affordable.
|
|
43
|
+
*
|
|
44
|
+
* A daemon that cannot answer falls back to the direct command for that plugin,
|
|
45
|
+
* so the answer is the same one either way and only its cost differs. The
|
|
46
|
+
* fallback matters more here than most: a daemon that quietly answered nothing
|
|
47
|
+
* would be indistinguishable from a project that publishes nothing.
|
|
48
|
+
*/
|
|
49
|
+
async function publishArtifactsResident(options, daemon) {
|
|
50
|
+
const plugins = (0, ttsc_1.resolveCapabilityPlugins)({
|
|
51
|
+
capability: "graphNodes",
|
|
52
|
+
cwd: options.cwd,
|
|
53
|
+
tsconfig: options.tsconfig,
|
|
54
|
+
});
|
|
55
|
+
if (plugins.length === 0)
|
|
56
|
+
return unpublished(options);
|
|
57
|
+
// The first request of a republish drops the daemon's warm Program. The
|
|
58
|
+
// artifacts depend on which sources exist and what they declare — that is
|
|
59
|
+
// what activates a claim — and between two republishes the developer has
|
|
60
|
+
// been editing code as well as documents. Reusing a Program from before
|
|
61
|
+
// those edits would deactivate a claim whose files now exist, which is a
|
|
62
|
+
// stale answer of exactly the kind this whole mechanism removes. What the
|
|
63
|
+
// daemon still saves is the process, the plugin load, and the configuration
|
|
64
|
+
// evaluation, which is most of the cost.
|
|
65
|
+
const inputs = readInputs(await Promise.all(plugins.map((plugin) => askVerb(plugin, "project-inputs", options, daemon(plugin), true))), options);
|
|
66
|
+
return assemble(options, inputs, await Promise.all(plugins.map((plugin) => askVerb(plugin, "graph-nodes", options, daemon(plugin), false))));
|
|
67
|
+
}
|
|
68
|
+
/** Run one verb as its own process, returning its stdout or `null`. */
|
|
69
|
+
function runVerb(plugin, verb, options) {
|
|
70
|
+
const result = (0, node_child_process_1.spawnSync)(plugin.binary, [
|
|
71
|
+
verb,
|
|
72
|
+
"--cwd",
|
|
73
|
+
options.cwd,
|
|
74
|
+
"--tsconfig",
|
|
75
|
+
options.tsconfig,
|
|
76
|
+
// The sidecar finds its own configured entry in this manifest. Without
|
|
77
|
+
// it, it loads an empty rule configuration and answers as though the
|
|
78
|
+
// project declared nothing — an empty answer indistinguishable from a
|
|
79
|
+
// project that genuinely publishes none.
|
|
80
|
+
`--plugins-json=${plugin.manifest}`,
|
|
81
|
+
...projectContextArgs(plugin),
|
|
82
|
+
], {
|
|
83
|
+
// The set is one entry per document section, model field, and operation —
|
|
84
|
+
// bounded by the project's own documentation, not by its source — so the
|
|
85
|
+
// default pipe ceiling is raised rather than removed.
|
|
86
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
87
|
+
encoding: "utf8",
|
|
88
|
+
windowsHide: true,
|
|
89
|
+
});
|
|
90
|
+
// A plugin that cannot answer is not a broken graph. The verb is new, so a
|
|
91
|
+
// plugin built from an older source rejects the command outright, and a
|
|
92
|
+
// project whose config does not parse has already failed somewhere the user
|
|
93
|
+
// can see. Either way the graph is the one that existed before this, and the
|
|
94
|
+
// absent capability claim is what says the producer got no answer.
|
|
95
|
+
if (result.error || result.status !== 0 || typeof result.stdout !== "string")
|
|
96
|
+
return null;
|
|
97
|
+
return result.stdout;
|
|
98
|
+
}
|
|
99
|
+
/** Ask one verb through a daemon, or as a process when it cannot answer. */
|
|
100
|
+
async function askVerb(plugin, verb, options, daemon, invalidate) {
|
|
101
|
+
const served = await daemon?.ask(verb, invalidate);
|
|
102
|
+
return served ?? runVerb(plugin, verb, options);
|
|
103
|
+
}
|
|
104
|
+
/** The artifact answer, from each sidecar's `graph-nodes` output. */
|
|
105
|
+
function assemble(options, inputs, outputs) {
|
|
106
|
+
const fingerprint = fingerprintInputs(inputs);
|
|
107
|
+
const published = [];
|
|
108
|
+
for (const output of outputs) {
|
|
109
|
+
if (output === null)
|
|
110
|
+
continue;
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(output);
|
|
113
|
+
if (Array.isArray(parsed))
|
|
114
|
+
published.push(...parsed);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (published.length === 0)
|
|
121
|
+
return { file: null, fingerprint, inputs };
|
|
122
|
+
// One file per process and project, overwritten, rather than a fresh temp
|
|
123
|
+
// directory per call. A directory per call is a leak nothing here is
|
|
124
|
+
// positioned to clean — the path outlives this function by design, since the
|
|
125
|
+
// native producer reads it after we return — and `loadGraph` is a library
|
|
126
|
+
// entry a caller may run in a loop.
|
|
127
|
+
//
|
|
128
|
+
// Per project as well as per process, because `TtscGraphSession` is exported
|
|
129
|
+
// and a consumer holding one per workspace is an ordinary thing to do. Keyed
|
|
130
|
+
// on the process alone, the second session's set would overwrite the first's
|
|
131
|
+
// between the moment it was written and the moment the first session's child
|
|
132
|
+
// reads the path it was handed — and a graph answering with another project's
|
|
133
|
+
// artifacts is exactly the silently-wrong answer this channel exists to make
|
|
134
|
+
// impossible.
|
|
135
|
+
const file = node_path_1.default.join(node_os_1.default.tmpdir(), `ttsc-graph-artifacts-${String(process.pid)}-${projectKey(options)}.json`);
|
|
136
|
+
node_fs_1.default.writeFileSync(file, JSON.stringify(published));
|
|
137
|
+
return { file, fingerprint, inputs };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Whether the inputs an answer was derived from have moved since.
|
|
141
|
+
*
|
|
142
|
+
* Answered by stating paths this process already knows, not by asking the
|
|
143
|
+
* plugin again. The question is asked before every graph request in a resident
|
|
144
|
+
* session, and re-running plugin discovery per request would cost more than the
|
|
145
|
+
* refresh it guards — while a `stat` per document costs less than reading one
|
|
146
|
+
* of them.
|
|
147
|
+
*
|
|
148
|
+
* The cost of being wrong in the cheap direction is what makes this worth
|
|
149
|
+
* paying at all: a developer who edited only a spec section, and nothing the
|
|
150
|
+
* compiler reads, otherwise saw the graph keep answering with the headings that
|
|
151
|
+
* section used to have.
|
|
152
|
+
*/
|
|
153
|
+
function artifactsAreStale(published) {
|
|
154
|
+
// The written set is one of its own inputs, by existence alone. It lives in
|
|
155
|
+
// the system temp directory, which is swept on a schedule this session has no
|
|
156
|
+
// say in, and the server is handed the path on every request — so once it is
|
|
157
|
+
// gone every later request fails as a broken exchange, and the only cure is
|
|
158
|
+
// restarting the editor. That is the outcome `unpublished` exists to avoid,
|
|
159
|
+
// and it would be odd to accept it here.
|
|
160
|
+
//
|
|
161
|
+
// Existence and nothing else. The file is written after this answer's
|
|
162
|
+
// fingerprint was taken, so folding its size or time into that state would
|
|
163
|
+
// report stale forever.
|
|
164
|
+
if (published.file !== null && !node_fs_1.default.existsSync(published.file))
|
|
165
|
+
return true;
|
|
166
|
+
return fingerprintInputs(published.inputs) !== published.fingerprint;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The answer for a project that publishes nothing, and what to watch so that
|
|
170
|
+
* answer can change.
|
|
171
|
+
*
|
|
172
|
+
* Configuring a plugin means editing the project's tsconfig or installing a
|
|
173
|
+
* package that declares one, so those two files are what could turn this answer
|
|
174
|
+
* into a different one. They are stated rather than the whole discovery being
|
|
175
|
+
* re-run, because re-running it walks the dependency closure — the cost
|
|
176
|
+
* samchon/ttsc#1276 is about — and paying that per request to learn nothing
|
|
177
|
+
* would be worse than the staleness it prevents.
|
|
178
|
+
*
|
|
179
|
+
* Bounded, and deliberately: a tsconfig that inherits its plugins from an
|
|
180
|
+
* extended config is not tracked here, because naming the whole extends chain
|
|
181
|
+
* means asking the loader that is itself the expense.
|
|
182
|
+
*/
|
|
183
|
+
function unpublished(options) {
|
|
184
|
+
const inputs = {
|
|
185
|
+
directories: [],
|
|
186
|
+
files: [
|
|
187
|
+
node_path_1.default.resolve(options.cwd, options.tsconfig),
|
|
188
|
+
node_path_1.default.resolve(options.cwd, "package.json"),
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
return { file: null, fingerprint: fingerprintInputs(inputs), inputs };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* What each sidecar said its rules read, as one watch list.
|
|
195
|
+
*
|
|
196
|
+
* The `project-inputs` verb exists for exactly this question: `@ttsc/lint`
|
|
197
|
+
* publishes it so a host can learn that a rule depends on files the Program
|
|
198
|
+
* never loads. Its snapshot carries both halves of what is needed here — the
|
|
199
|
+
* plugin's own configuration files, and the globs the rules declared — so a
|
|
200
|
+
* configuration edit and a document edit are noticed by the same state rather
|
|
201
|
+
* than by two mechanisms that could disagree.
|
|
202
|
+
*/
|
|
203
|
+
function readInputs(outputs, options) {
|
|
204
|
+
const files = [];
|
|
205
|
+
const directories = [];
|
|
206
|
+
for (const output of outputs) {
|
|
207
|
+
if (output === null)
|
|
208
|
+
continue;
|
|
209
|
+
let snapshot;
|
|
210
|
+
try {
|
|
211
|
+
snapshot = JSON.parse(output);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
// The snapshot names the base its own paths are relative to. It normalizes
|
|
217
|
+
// them to absolute today, so this changes nothing now and is what keeps a
|
|
218
|
+
// relative answer from being resolved against the wrong directory later —
|
|
219
|
+
// silently, since a path that does not exist states itself absent and reads
|
|
220
|
+
// as a project whose documents were all deleted.
|
|
221
|
+
const base = snapshot.root ?? options.cwd;
|
|
222
|
+
for (const file of [
|
|
223
|
+
...(snapshot.files ?? []),
|
|
224
|
+
...(snapshot.reloadFiles ?? []),
|
|
225
|
+
])
|
|
226
|
+
files.push(absolute(file, base));
|
|
227
|
+
for (const pattern of snapshot.globs ?? []) {
|
|
228
|
+
const directory = watchedBy(pattern, base);
|
|
229
|
+
if (directory === null)
|
|
230
|
+
files.push(absolute(pattern, base));
|
|
231
|
+
else
|
|
232
|
+
directories.push(directory);
|
|
233
|
+
}
|
|
234
|
+
// A reload directory is a resolution anchor, not a content tree.
|
|
235
|
+
// `@ttsc/lint` publishes the directories whose *immediate* topology decides
|
|
236
|
+
// which rules load — a `node_modules` chain, a config directory — and the
|
|
237
|
+
// LSP host watches exactly `<dir>/*` for that reason. Walking them
|
|
238
|
+
// recursively both over-invalidates, restarting on any descendant edit, and
|
|
239
|
+
// states the whole dependency tree before every graph request.
|
|
240
|
+
for (const directory of snapshot.reloadDirectories ?? [])
|
|
241
|
+
directories.push({ path: absolute(directory, base), recursive: false });
|
|
242
|
+
}
|
|
243
|
+
// A directory named twice is walked once, and a recursive claim wins: two
|
|
244
|
+
// patterns over one tree, one descending and one not, must not leave the
|
|
245
|
+
// descending one's files unwatched because the other was seen first.
|
|
246
|
+
const merged = new Map();
|
|
247
|
+
for (const directory of directories)
|
|
248
|
+
merged.set(directory.path, (merged.get(directory.path) ?? false) || directory.recursive);
|
|
249
|
+
return {
|
|
250
|
+
directories: [...merged]
|
|
251
|
+
.map(([directory, recursive]) => ({ path: directory, recursive }))
|
|
252
|
+
.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0)),
|
|
253
|
+
files: [...new Set(files)].sort(),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The directory a declared pattern makes worth walking, or `null` when the
|
|
258
|
+
* pattern names one path and should simply be stated.
|
|
259
|
+
*
|
|
260
|
+
* Two readings have to be right here, and both are cheap to get wrong. A
|
|
261
|
+
* pattern carrying no wildcard is a path, not a tree: watching its parent
|
|
262
|
+
* instead would state every sibling on every request to learn about the one
|
|
263
|
+
* file that was declared. And a pattern that does not say `**` does not descend
|
|
264
|
+
* — treating it as though it did is unbounded in exactly the case that looks
|
|
265
|
+
* harmless, because a bare `*.md` has the project root for its prefix.
|
|
266
|
+
*/
|
|
267
|
+
function watchedBy(pattern, cwd) {
|
|
268
|
+
if (pattern.search(GLOB_MAGIC) < 0)
|
|
269
|
+
return null;
|
|
270
|
+
return { path: globRoot(pattern, cwd), recursive: pattern.includes("**") };
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The project identity flag, for a plugin whose descriptor asks for one.
|
|
274
|
+
*
|
|
275
|
+
* A rule resolves its own inputs — the documents a claim reads, a schema, an
|
|
276
|
+
* OpenAPI file — against the project root, and a sidecar is handed that root
|
|
277
|
+
* rather than deriving it. Without the flag the rule has no base, and it
|
|
278
|
+
* answers with an empty set rather than an error, because "this project
|
|
279
|
+
* declares nothing" is a legitimate answer it cannot tell apart from "nobody
|
|
280
|
+
* told me where the project is". That is why every verb here passes it and why
|
|
281
|
+
* the case covering this drives a real project: an empty answer is exactly what
|
|
282
|
+
* a synthetic fixture would also have produced.
|
|
283
|
+
*/
|
|
284
|
+
function projectContextArgs(plugin) {
|
|
285
|
+
return plugin.projectContext === undefined
|
|
286
|
+
? []
|
|
287
|
+
: [`--project-context-json=${plugin.projectContext}`];
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* The project a published set belongs to, as a filename-safe tag.
|
|
291
|
+
*
|
|
292
|
+
* Short rather than the whole digest: it distinguishes the projects one process
|
|
293
|
+
* drives, which is a handful, and the process id beside it already separates
|
|
294
|
+
* two runs.
|
|
295
|
+
*/
|
|
296
|
+
function projectKey(options) {
|
|
297
|
+
return (0, node_crypto_1.createHash)("sha256")
|
|
298
|
+
.update(node_path_1.default.resolve(options.cwd))
|
|
299
|
+
.update(SEPARATOR)
|
|
300
|
+
.update(options.tsconfig)
|
|
301
|
+
.digest("hex")
|
|
302
|
+
.slice(0, 16);
|
|
303
|
+
}
|
|
304
|
+
/** Wildcards a pattern may use; a pattern with none of them names one path. */
|
|
305
|
+
const GLOB_MAGIC = /[*?[{]/u;
|
|
306
|
+
/** A declared path resolved against the project root. */
|
|
307
|
+
function absolute(target, cwd) {
|
|
308
|
+
return node_path_1.default.isAbsolute(target) ? target : node_path_1.default.join(cwd, target);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* The state of every input, as one comparable string.
|
|
312
|
+
*
|
|
313
|
+
* Files are stated by size and modification time rather than content: this runs
|
|
314
|
+
* before every graph request, and hashing a documentation corpus per request
|
|
315
|
+
* would cost more than the refresh it guards. Directories are walked for the
|
|
316
|
+
* same pair, which is what notices a section added or a document deleted rather
|
|
317
|
+
* than edited.
|
|
318
|
+
*/
|
|
319
|
+
function fingerprintInputs(inputs) {
|
|
320
|
+
const parts = [];
|
|
321
|
+
for (const file of inputs.files)
|
|
322
|
+
parts.push(stateOf(file));
|
|
323
|
+
for (const directory of inputs.directories)
|
|
324
|
+
parts.push(...walkState(directory.path, directory.recursive));
|
|
325
|
+
parts.sort();
|
|
326
|
+
return (0, node_crypto_1.createHash)("sha256").update(parts.join("\n")).digest("hex");
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* A path's size and modification time, or a marker when it is absent.
|
|
330
|
+
*
|
|
331
|
+
* The fields are joined on a character a path cannot contain. Separated by a
|
|
332
|
+
* space, a file literally named `a 1 2` states the same string as a one-byte
|
|
333
|
+
* file named `a`, and an edit to either would then read as no edit at all.
|
|
334
|
+
*/
|
|
335
|
+
function stateOf(file) {
|
|
336
|
+
try {
|
|
337
|
+
const stat = node_fs_1.default.statSync(file);
|
|
338
|
+
return [file, String(stat.size), String(stat.mtimeMs)].join(SEPARATOR);
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
return [file, "absent"].join(SEPARATOR);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The character that joins fields a path could otherwise forge.
|
|
346
|
+
*
|
|
347
|
+
* Built rather than written literally: a source file carrying a raw NUL is one
|
|
348
|
+
* Git classifies as binary, which exempts it from this repository's end-of-line
|
|
349
|
+
* contract and leaves it with no textual diff for a reviewer.
|
|
350
|
+
*/
|
|
351
|
+
const SEPARATOR = String.fromCharCode(0);
|
|
352
|
+
/**
|
|
353
|
+
* The fixed directory prefix of a glob, which is what there is to walk.
|
|
354
|
+
*
|
|
355
|
+
* A pattern with no directory part at all names the project root, which is the
|
|
356
|
+
* one reading that keeps a bare `*.md` from being walked as though it were a
|
|
357
|
+
* directory named `*.md`.
|
|
358
|
+
*/
|
|
359
|
+
function globRoot(pattern, cwd) {
|
|
360
|
+
const magic = pattern.search(GLOB_MAGIC);
|
|
361
|
+
const head = magic < 0 ? pattern : pattern.slice(0, magic);
|
|
362
|
+
const slash = Math.max(head.lastIndexOf("/"), head.lastIndexOf("\\"));
|
|
363
|
+
const root = slash < 0 ? "" : head.slice(0, slash);
|
|
364
|
+
return root === "" ? cwd : absolute(root, cwd);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Every entry below `directory`, stated.
|
|
368
|
+
*
|
|
369
|
+
* Bounded three ways, because this runs before every graph request: it descends
|
|
370
|
+
* only when the pattern that named the directory descends, it never enters
|
|
371
|
+
* `node_modules`, and it stops at a depth no documentation tree reaches. Dotted
|
|
372
|
+
* directories are skipped below the declared root, which is what the glob that
|
|
373
|
+
* named it would have matched anyway.
|
|
374
|
+
*
|
|
375
|
+
* A directory that does not exist states itself absent, which is what notices
|
|
376
|
+
* one being created.
|
|
377
|
+
*/
|
|
378
|
+
function walkState(directory, recursive, depth = 0) {
|
|
379
|
+
if (depth > 12)
|
|
380
|
+
return [];
|
|
381
|
+
let entries;
|
|
382
|
+
try {
|
|
383
|
+
entries = node_fs_1.default.readdirSync(directory, { withFileTypes: true });
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
return [stateOf(directory)];
|
|
387
|
+
}
|
|
388
|
+
const states = [];
|
|
389
|
+
for (const entry of entries) {
|
|
390
|
+
const child = node_path_1.default.join(directory, entry.name);
|
|
391
|
+
if (entry.isDirectory()) {
|
|
392
|
+
if (!recursive)
|
|
393
|
+
continue;
|
|
394
|
+
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
395
|
+
continue;
|
|
396
|
+
states.push(...walkState(child, recursive, depth + 1));
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
states.push(stateOf(child));
|
|
400
|
+
}
|
|
401
|
+
return states;
|
|
402
|
+
}
|
|
403
|
+
//# sourceMappingURL=publishedArtifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publishedArtifacts.js","sourceRoot":"","sources":["../../src/model/publishedArtifacts.ts"],"names":[],"mappings":"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"}
|
package/lib/reduce.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Reduce a raw `ttscgraph dump` to the payload the bundled 3D viewer renders.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// The same pure transform is copied in
|
|
4
|
+
// website/src/components/graph/TtscWebsiteGraphReduce.ts and
|
|
5
|
+
// benchmarks/graph/src/TtscBenchmarkGraphReduce.ts, because neither consumer
|
|
6
|
+
// depends on this package and adding one would be a new build dependency for a
|
|
7
|
+
// browser bundle and a dependency-free benchmark. The copies are held together
|
|
8
|
+
// by tests/test-graph rather than by this comment. The CLI reduces in Node
|
|
9
|
+
// before serving, so the browser viewer only ever renders a ready
|
|
10
|
+
// `{ nodes, links }`.
|
|
6
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
12
|
exports.reduce = reduce;
|
|
8
13
|
function posix(p) {
|
|
@@ -133,10 +138,16 @@ function degreeOf(nodes, edges) {
|
|
|
133
138
|
return degree;
|
|
134
139
|
}
|
|
135
140
|
/**
|
|
136
|
-
* Collapse
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
141
|
+
* Collapse every wire kind `ttscgraph dump` emits into the display families the
|
|
142
|
+
* viewer colors and its legend names. An unknown kind passes through and
|
|
143
|
+
* renders with the fallback color.
|
|
144
|
+
*
|
|
145
|
+
* The map has to be total over what a dump can carry. `exports` was missing and
|
|
146
|
+
* therefore drawn in the fallback color under no legend entry and, on the
|
|
147
|
+
* website, under no filter row — visible, unnamed, and unfilterable. The two
|
|
148
|
+
* kinds `TtscGraphEdgeKind` declares beyond this map cannot reach a dump:
|
|
149
|
+
* `contains` is synthesized by the TypeScript memory layer and `dispatches` is
|
|
150
|
+
* trace-only.
|
|
140
151
|
*/
|
|
141
152
|
const DISPLAY_KIND = {
|
|
142
153
|
calls: "value-call",
|
|
@@ -144,9 +155,11 @@ const DISPLAY_KIND = {
|
|
|
144
155
|
renders: "value-call",
|
|
145
156
|
accesses: "value-call",
|
|
146
157
|
type_ref: "type-ref",
|
|
158
|
+
doc_ref: "doc-ref",
|
|
147
159
|
extends: "heritage",
|
|
148
160
|
implements: "heritage",
|
|
149
161
|
overrides: "heritage",
|
|
162
|
+
exports: "exports",
|
|
150
163
|
};
|
|
151
164
|
function displayKind(kind) {
|
|
152
165
|
return DISPLAY_KIND[kind] ?? kind;
|
package/lib/reduce.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reduce.js","sourceRoot":"","sources":["../src/reduce.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"reduce.js","sourceRoot":"","sources":["../src/reduce.ts"],"names":[],"mappings":"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"}
|