@ttsc/graph 0.31.5 → 0.32.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 (37) hide show
  1. package/README.md +1 -1
  2. package/lib/TtscGraphLauncherArguments.js +4 -7
  3. package/lib/TtscGraphLauncherArguments.js.map +1 -1
  4. package/lib/internal/InstalledGraphBinary.d.ts +73 -0
  5. package/lib/internal/InstalledGraphBinary.js +103 -0
  6. package/lib/internal/InstalledGraphBinary.js.map +1 -0
  7. package/lib/model/TtscGraphProjection.js.map +1 -1
  8. package/lib/model/TtscGraphProtocol.js +2 -2
  9. package/lib/model/TtscGraphProtocol.js.map +1 -1
  10. package/lib/model/TtscGraphSession.js +6 -9
  11. package/lib/model/TtscGraphSession.js.map +1 -1
  12. package/lib/model/TtscGraphSessionOptions.d.ts +4 -1
  13. package/lib/model/TtscGraphSessionState.js +2 -2
  14. package/lib/model/TtscGraphSessionState.js.map +1 -1
  15. package/lib/model/loadGraph.d.ts +3 -3
  16. package/lib/model/loadGraph.js +8 -11
  17. package/lib/model/loadGraph.js.map +1 -1
  18. package/lib/resolveGraphBinary.d.ts +22 -24
  19. package/lib/resolveGraphBinary.js +26 -45
  20. package/lib/resolveGraphBinary.js.map +1 -1
  21. package/lib/runGraph.d.ts +1 -1
  22. package/lib/runGraph.js +4 -4
  23. package/lib/runGraph.js.map +1 -1
  24. package/lib/view.js +5 -6
  25. package/lib/view.js.map +1 -1
  26. package/package.json +13 -4
  27. package/src/TtscGraphLauncherArguments.ts +4 -8
  28. package/src/internal/InstalledGraphBinary.ts +102 -0
  29. package/src/model/TtscGraphProjection.ts +18 -16
  30. package/src/model/TtscGraphProtocol.ts +2 -2
  31. package/src/model/TtscGraphSession.ts +5 -12
  32. package/src/model/TtscGraphSessionOptions.ts +4 -1
  33. package/src/model/TtscGraphSessionState.ts +2 -2
  34. package/src/model/loadGraph.ts +9 -15
  35. package/src/resolveGraphBinary.ts +26 -45
  36. package/src/runGraph.ts +4 -4
  37. package/src/view.ts +5 -8
@@ -1,6 +1,7 @@
1
1
  import typia from "typia";
2
2
 
3
3
  import { GraphProcessTrace } from "../internal/GraphProcessTrace";
4
+ import { InstalledGraphBinary } from "../internal/InstalledGraphBinary";
4
5
  import { captureProcessOutput, ensureExecutable } from "../nativeExecutable";
5
6
  import { resolveGraphBinary } from "../resolveGraphBinary";
6
7
  import { ITtscGraphDump } from "../structures/ITtscGraphDump";
@@ -34,7 +35,7 @@ export const DUMP_SCHEMA_VERSION = 8;
34
35
  * @evidence contracts/common.md#clear-and-simple-design One-shot process execution, capture ownership and parse validation have separate helpers; the resident MCP path remains a different lifetime owner.
35
36
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Failed resolution or native execution throws rather than returning an invented empty graph.
36
37
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs state direct/viewer usage, project/binary defaults and every externally visible failure boundary.
37
- * @evidence contracts/portability.md#os-neutral-implementation Native argv carries cwd, tsconfig and artifact paths without a shell; project-anchored binary resolution and permission repair account for host execution differences.
38
+ * @evidence contracts/portability.md#os-neutral-implementation Native argv carries cwd, tsconfig and artifact paths without a shell; installation-anchored binary resolution and permission repair account for host execution differences.
38
39
  * @evidence contracts/performance.md#efficient-algorithms One native dump is followed by linear JSON parsing/validation and model indexing; output is file-backed rather than constrained by a guessed pipe budget.
39
40
  * @evidence contracts/performance.md#reuse-equivalent-work Direct loads intentionally build the requested current project anew; callers needing repeated equivalent snapshots use TtscGraphSession's resident producer and model.
40
41
  * @evidence contracts/performance.md#bound-retention-and-release-resources The operation owns two capture descriptors until the finally block disposes them; returned graph ownership transfers to the caller, while artifact storage remains process/project scoped.
@@ -49,24 +50,18 @@ export function loadGraph(
49
50
 
50
51
  /**
51
52
  * Absolute path to the `ttscgraph` binary. Defaults to the per-platform
52
- * binary resolved from the project's installed `ttsc`; pass it explicitly
53
- * to point at a custom build.
53
+ * binary installed with `@ttsc/graph`; pass it explicitly to point at a
54
+ * custom build.
54
55
  */
55
56
  binary?: string;
56
57
  } = {},
57
58
  ): TtscGraphMemory {
58
59
  const cwd = options.cwd ?? process.cwd();
59
60
  const tsconfig = options.tsconfig ?? "tsconfig.json";
60
- // Resolve the platform binary from the selected project cwd, not the caller's
61
- // process directory, so a one-shot load names its own installation.
62
- const binary = options.binary ?? resolveGraphBinary(process.env, cwd);
63
- if (binary === null) {
64
- throw new Error(
65
- "@ttsc/graph: could not resolve the ttscgraph binary. " +
66
- "Install `ttsc` so its platform package is present, " +
67
- "or set TTSC_GRAPH_BINARY to an absolute path.",
68
- );
69
- }
61
+ // The producer belongs to this package's installation, so the selected
62
+ // project only becomes the native process's --cwd.
63
+ const binary = options.binary ?? resolveGraphBinary(process.env);
64
+ if (binary === null) throw new Error(InstalledGraphBinary.missingMessage());
70
65
  ensureExecutable(binary);
71
66
 
72
67
  // The dump goes to a file rather than a pipe, so no output ceiling applies:
@@ -159,8 +154,7 @@ export function parseDump(json: string): ITtscGraphDump {
159
154
  `@ttsc/graph: ttscgraph dump is schema ${
160
155
  version === undefined ? "unknown" : `v${String(version)}`
161
156
  }, this client reads v${String(DUMP_SCHEMA_VERSION)}. ` +
162
- "Install a matching `ttsc` (the binary resolves from the target " +
163
- "project, or from TTSC_GRAPH_BINARY).",
157
+ InstalledGraphBinary.MISMATCH_REMEDY,
164
158
  );
165
159
  }
166
160
  try {
@@ -1,60 +1,41 @@
1
- import { createRequire } from "node:module";
2
- import path from "node:path";
1
+ import { InstalledGraphBinary } from "./internal/InstalledGraphBinary";
3
2
 
4
3
  /**
5
- * Resolve the per-platform `ttscgraph` binary, or `null` when it cannot be
6
- * located.
4
+ * Resolve the `ttscgraph` binary this `@ttsc/graph` release spawns, or `null`
5
+ * when it cannot be located.
7
6
  *
8
- * `ttsc` is a peer dependency pinned to this package's own version, installed
9
- * alongside `@ttsc/graph` in the user's project rather than nested under this
10
- * launcher, so resolution starts from the user's project, not from this
11
- * package's own tree.
12
- *
13
- * The pin is what keeps the two halves of the graph in step. `literals` and the
14
- * rest of the node facts are resolved by the Go builder and ride the dump, so a
15
- * newer `@ttsc/graph` reading an older `ttscgraph` would find those fields
16
- * simply absent and answer from a graph missing facts it believes are there.
7
+ * The binary ships in `@ttsc/graph-<platform>-<arch>`, which `@ttsc/graph`
8
+ * lists as an exact-version optional dependency, so it is resolved from this
9
+ * package's own installation. The JavaScript client and the native producer
10
+ * therefore always come from one release, wherever the launcher was started.
11
+ * That pairing matters because node facts such as `literals` are resolved by
12
+ * the producer and ride the dump: a client reading an older producer would find
13
+ * those fields absent and answer from a graph missing facts it believes are
14
+ * there.
17
15
  *
18
16
  * Resolution order:
19
17
  *
20
18
  * 1. `TTSC_GRAPH_BINARY` env var, when set to an absolute path.
21
- * 2. The per-platform npm package `@ttsc/<platform>-<arch>/bin/ttscgraph[.exe]`.
22
- * That package carries `ttsc`, `ttscserver`, and `ttscgraph` together and is
23
- * an `optionalDependency` of `ttsc`, so it is resolved from `ttsc`'s
24
- * location — found from `cwd`, the project the caller selected (via `--cwd`
25
- * or an API `cwd` option), defaulting to `process.cwd()` when no project was
26
- * named. A launcher started from an unrelated directory still resolves the
27
- * `ttsc` installed under the target project it was asked to graph.
19
+ * 2. `@ttsc/graph-<platform>-<arch>/bin/ttscgraph[.exe]`, resolved from the
20
+ * installed `@ttsc/graph` package.
21
+ *
22
+ * `cwd` is still accepted so existing callers keep compiling. It no longer
23
+ * affects resolution: the binary used to come from the target project's `ttsc`
24
+ * platform package, and now belongs to `@ttsc/graph` itself.
28
25
  *
29
- * @evidence contracts/common.md#principled-implementation Project-anchored module resolution locates the peer ttsc and then its platform binary; an explicit absolute override has precedence.
30
- * @evidence contracts/common.md#clear-and-simple-design One resolver owns override and peer-package lookup for all graph launchers.
31
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Resolution uses installed package contracts rather than guessing binary paths from repository layouts.
32
- * @evidence contracts/common.md#meaningful-documentation Native paragraphs and the ordered list explain peer placement, override precedence and target-project anchoring.
33
- * @evidence contracts/portability.md#os-neutral-implementation Native path checks and module resolution select the platform/architecture package; only Windows's required executable suffix differs explicitly.
26
+ * @evidence contracts/common.md#principled-implementation The installed-package resolver locates the exact-version platform dependency from this module's own location; an explicit absolute override has precedence.
27
+ * @evidence contracts/common.md#clear-and-simple-design The public function delegates to the one resolver every launcher, loader and session uses, anchored at this package's installation.
28
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Resolution uses the installed package contract rather than repository layouts or the target project's packages.
29
+ * @evidence contracts/common.md#meaningful-documentation Native paragraphs and the ordered list explain package ownership, override precedence and the retained but ignored cwd argument.
30
+ * @evidence contracts/portability.md#os-neutral-implementation The delegated resolver selects the platform/architecture package through Node module resolution; only Windows's executable suffix differs.
34
31
  * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources returns a path string and opens no handle.
35
- * @evidenceExclude contracts/performance.md#efficient-algorithms performs a constant number of module resolutions (ttsc, then its platform package).
32
+ * @evidenceExclude contracts/performance.md#efficient-algorithms performs at most one module resolution.
36
33
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work resolves on every call and caches nothing, so a reinstall between calls is honored.
37
34
  */
38
35
  export function resolveGraphBinary(
39
36
  env: NodeJS.ProcessEnv = process.env,
40
- cwd: string = process.cwd(),
37
+ cwd?: string,
41
38
  ): string | null {
42
- if (env.TTSC_GRAPH_BINARY && path.isAbsolute(env.TTSC_GRAPH_BINARY)) {
43
- return env.TTSC_GRAPH_BINARY;
44
- }
45
- const exe = process.platform === "win32" ? "ttscgraph.exe" : "ttscgraph";
46
- try {
47
- // Anchor package lookup at the absolute project root so a relative `--cwd`
48
- // resolves the same way the native process interprets it.
49
- const fromProject = createRequire(
50
- path.join(path.resolve(cwd), "package.json"),
51
- );
52
- const ttscPackageJson = fromProject.resolve("ttsc/package.json");
53
- const fromTtsc = createRequire(ttscPackageJson);
54
- return fromTtsc.resolve(
55
- `@ttsc/${process.platform}-${process.arch}/bin/${exe}`,
56
- );
57
- } catch {
58
- return null;
59
- }
39
+ void cwd;
40
+ return InstalledGraphBinary.resolve(env, __filename);
60
41
  }
package/src/runGraph.ts CHANGED
@@ -25,7 +25,7 @@ const VERSION: string = (require("../package.json") as { version: string })
25
25
  * @evidence contracts/common.md#clear-and-simple-design The launcher owns lane dispatch while viewer, server and native dump helpers own their respective execution boundaries.
26
26
  * @evidence contracts/common.md#prohibited-implementation-shortcuts A missing dump binary exposes only an explicitly qualified help summary; execution failures retain nonzero outcomes instead of fake graph answers.
27
27
  * @evidence contracts/common.md#meaningful-documentation Native lane bullets explain observable CLI behavior and resident refresh ownership with a blank line before tags.
28
- * @evidence contracts/portability.md#os-neutral-implementation Native lanes resolve the selected project's platform package and pass argv directly; stdio MCP uses Node transport APIs without shell path construction.
28
+ * @evidence contracts/portability.md#os-neutral-implementation Native lanes resolve this package's installed platform binary and pass argv directly; stdio MCP uses Node transport APIs without shell path construction.
29
29
  * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources starts the stdio server (owned by startServer), runs a synchronous dump child to completion or hands over to runView, and keeps no handle itself.
30
30
  * @evidenceExclude contracts/performance.md#efficient-algorithms dispatches on the first argv token to one lane and the lanes own the work.
31
31
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work runs one launcher lane per process invocation, so there is nothing to share.
@@ -52,11 +52,11 @@ export function runGraph(
52
52
  * on this process's stdout. Returns the child's exit code.
53
53
  */
54
54
  function runDump(argv: readonly string[]): number {
55
- // Resolve the native binary from the target project the caller named with
56
- // `--cwd`, not from wherever the launcher process happened to start.
55
+ // The producer belongs to this package's installation; `--cwd` only selects
56
+ // the project the native process graphs.
57
57
  const { cwd, tsconfig, artifactsSpecified } =
58
58
  TtscGraphLauncherArguments.dump(argv);
59
- const binary = resolveGraphBinary(process.env, cwd);
59
+ const binary = resolveGraphBinary(process.env);
60
60
  if (binary === null) {
61
61
  // `ttscgraph` owns the flag contract, so a resolvable binary always answers
62
62
  // `--help` itself and stays the single source of truth. It cannot answer
package/src/view.ts CHANGED
@@ -6,6 +6,7 @@ import path from "node:path";
6
6
  import { TtscGraphLauncherArguments } from "./TtscGraphLauncherArguments";
7
7
  import { TtscGraphViewSnapshot } from "./TtscGraphViewSnapshot";
8
8
  import { GraphProcessTrace } from "./internal/GraphProcessTrace";
9
+ import { InstalledGraphBinary } from "./internal/InstalledGraphBinary";
9
10
  import { publishArtifacts } from "./model/publishedArtifacts";
10
11
  import { captureProcessOutput, ensureExecutable } from "./nativeExecutable";
11
12
  import { reduce } from "./reduce";
@@ -29,15 +30,11 @@ import { resolveGraphBinary } from "./resolveGraphBinary";
29
30
  export function runView(argv: readonly string[]): number | void {
30
31
  const opts = TtscGraphLauncherArguments.view(argv);
31
32
 
32
- // Anchor binary resolution at the project selected by `--cwd`, so `view` from
33
- // an unrelated directory still finds the `ttsc` installed under the target.
34
- const binary = resolveGraphBinary(process.env, opts.cwd);
33
+ // The producer belongs to this package's installation; `--cwd` only selects
34
+ // the project the native process graphs.
35
+ const binary = resolveGraphBinary(process.env);
35
36
  if (binary === null) {
36
- process.stderr.write(
37
- "@ttsc/graph: could not resolve the ttscgraph binary. " +
38
- "Install `ttsc` so its platform package is present, " +
39
- "or set TTSC_GRAPH_BINARY to an absolute path.\n",
40
- );
37
+ process.stderr.write(`${InstalledGraphBinary.missingMessage()}\n`);
41
38
  return 1;
42
39
  }
43
40
  ensureExecutable(binary);