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
- 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"],
},
},
},
},
- Open the playground and select "My Sample" from the Sample Gallery.
- 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
Describe the bug
In
@typespec/playground0.17.0, selecting a sample from the Sample Gallery applies the sample content, but the sample'spreferredEmitterandcompilerOptionsare immediately discarded.The generated
tspconfig.yamlfalls back to the previous/default playground state (often onlyemit: [...]withoutoptions/linter).This makes sample-specific emitter options (e.g.
openapi-versions: ["3.1.0"]) and even switching emitters viapreferredEmitterineffective.Reproduction
tspconfig.yaml(or the emitted OpenAPI document).Actual:
tspconfig.yamldoes not contain the sample'soptions/ expectedemit.3.0.0instead of3.1.0).preferredEmitteralso does not update the emitter.Expected:
compilerOptions/preferredEmitterpersistently.tspconfig.yamlshould include the sample configuration, e.g.:Likely cause
In
usePlaygroundState, selecting a sample correctly builds and setstspconfigviacompilerOptionsToTspConfig(...).Immediately afterwards,
useMonacoSyncupdates the Monaco model with the new sample content. That triggersonDidChangeContent, which callsonContentChangewith a staleonContentChangeclosure (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 settspconfigis 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 /onContentChangeRefordering)Workaround
Provide the desired emitter configuration via
defaultPlaygroundState.tspconfigso the fallback after the race still contains the intended options.Environment
@typespec/playground:0.17.0@typespec/compiler:1.15.0