Skip to content

[Bug]: Playground drops sample compilerOptions / preferredEmitter when selecting a sample #11659

Description

@dalbrx-nitrobox

Describe the bug

In @typespec/playground 0.17.0, selecting a sample from the Sample Gallery applies the sample content, but the sample's preferredEmitter and compilerOptions are immediately discarded.

The generated tspconfig.yaml falls back to the previous/default playground state (often only emit: [...] without options / linter).

This makes sample-specific emitter options (e.g. openapi-versions: ["3.1.0"]) and even switching emitters via preferredEmitter ineffective.

Reproduction

  1. Configure a playground with a sample that sets emitter options, e.g.:
"My Sample": {
  filename: "samples/example.tsp",
  preferredEmitter: "@typespec/openapi3",
  compilerOptions: {
    options: {
      "@typespec/openapi3": {
        "openapi-versions": ["3.1.0"],
      },
    },
  },
},
  1. Open the playground and select "My Sample" from the Sample Gallery.
  2. Inspect the virtual tspconfig.yaml (or the emitted OpenAPI document).

Actual:

  • Sample content is loaded.
  • tspconfig.yaml does not contain the sample's options / expected emit.
  • Emitter output uses defaults (e.g. OpenAPI 3.0.0 instead of 3.1.0).
  • Switching to another sample with a different preferredEmitter also does not update the emitter.

Expected:

  • Selecting a sample applies both content and compilerOptions / preferredEmitter persistently.
  • tspconfig.yaml should include the sample configuration, e.g.:
emit:
  - "@typespec/openapi3"
options:
  "@typespec/openapi3":
    openapi-versions:
      - 3.1.0

Likely cause

In usePlaygroundState, selecting a sample correctly builds and sets tspconfig via compilerOptionsToTspConfig(...).

Immediately afterwards, useMonacoSync updates the Monaco model with the new sample content. That triggers onDidChangeContent, which calls onContentChange with a stale onContentChange closure (the ref is updated in a later effect). That state update overwrites the playground state with the pre-sample-selection snapshot: content is kept, but the freshly set tspconfig is lost.

Relevant areas:

  • packages/playground/src/react/use-playground-state.ts (sample selection effect)
  • packages/playground/src/react/hooks/use-monaco-sync.ts (content sync / onContentChangeRef ordering)

Workaround

Provide the desired emitter configuration via defaultPlaygroundState.tspconfig so the fallback after the race still contains the intended options.

Environment

  • @typespec/playground: 0.17.0
  • @typespec/compiler: 1.15.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions