Skip to content

Add standalone TypeScript 7 playground - #3653

Draft
Jake Bailey (jakebailey) wants to merge 52 commits into
microsoft:v2from
jakebailey:ts7-playground
Draft

Jake Bailey (jakebailey) wants to merge 52 commits into
microsoft:v2from
jakebailey:ts7-playground

Conversation

@jakebailey

Copy link
Copy Markdown
Member

prototypin

Build a static Monaco 0.56 playground against the local wasip1 compiler API. Support Twoslash type queries, diagnostics, JavaScript emit, standard library types, and a browser console API without playground plugins.
Add the /play/7-1/ Gatsby route and materialize the standalone bundle as ignored static assets during site start and production builds.
Make the playground deployable from a standalone website checkout by committing the wasip1 API packages, standard libraries, WASM module, version metadata, and legal notices. Brand the route as /play/7/.
Force-add the generated API package output and wasip1 module because the website's global dist ignore otherwise omits the files required by a fresh checkout.
@jakebailey Jake Bailey (jakebailey) added the deploy-preview Enables automatic deployments to preview environments on a PR label Sep 16, 2026
Port the browser WASI and Monaco LSP transport from the 2026 GopherCon talk. Serve the playground directly at /play/7/ so its service worker can establish cross-origin isolation for SharedArrayBuffer.

Keep the synchronous compiler API authoritative for diagnostics, Twoslash, emit, and window.ts while LSP provides completion, hover, signature help, navigation, references, rename, and related editor features.
Set an explicit /play/7/ base in production so Azure's slashless /play/7 route resolves scripts, styles, workers, libraries, and the service worker from the playground directory.
Canonicalize Azure's slashless /play/7 URL before the scoped cross-origin isolation service worker starts. This lets the worker control /play/7/ after its activation reload without repeatedly registering.
Add a virtual project with editable tsconfig.json and multiple source files. Drive native compilation from the config and show all emitted files together in a highlighted, non-Monaco output pane.

Restore Run with captured CommonJS console output and reuse the existing playground loading grid while the compiler API and LSP initialize.
Add a collapsible file tree with nested file creation and default to src/index.ts. Persist the complete project and active file in an old-playground-style compressed #code URL.

Enable declaration emit by default, trim display-only trailing newlines, remove Twoslash and WebAssembly branding, and provide local JSON Schema completion, hover, and validation for tsconfig.json and jsconfig.json.
Ignore trailing commas and suppress SchemaStore enum diagnostics when TypeScript accepts the value with different casing. Migrate projects saved before the src directory change so their config includes the moved files and enables declaration emit.
Stream the compiler, libraries, and config schema with real byte progress. Show WebAssembly compilation as indeterminate, report library mounting by file count, and finish with the actual LSP startup stages.

Reuse the downloaded libraries in the LSP worker, add a Reset control for non-emitting saved projects, and explicitly route Ctrl/Cmd-click through go to definition.
Store the compiler WASM, library bundle, and config schema in a content-versioned browser cache. Refreshes now read those artifacts locally and new compiler artifacts automatically use a new cache namespace.

Remove the implementation-detail message about WebAssembly compile progress while keeping that phase honestly indeterminate.
Enable Monaco semantic highlighting and add explicit theme colors for TypeScript semantic token kinds. Recognize bundled library URIs so definitions such as console.log open the read-only lib.dom.d.ts model.
Replace the full-screen loading blocker with a compact translucent progress card. Keep the file tree, Monaco editor, emit pane, and Run output visible and editable throughout compiler and LSP startup.
Widen the explorer slightly and add vertical hierarchy guides, branch connectors, stronger folder rows, and consistent per-level indentation.
Register the ^? inlay provider for JavaScript and build a supplemental allowJs program for source models outside the configured project. This matches LSP inferred-project hover behavior without changing tsconfig-driven emit.
Update the playground to the current wasip1 compiler, JavaScript API client, standard libraries, and legal notices. Adapt createProgram calls to the new API signature and normalize bundled library definition URIs for Monaco navigation.
Add an in-page compiler selector for Native 7.1, classic stable releases, Nightly, and custom or PR CDN build IDs. Run classic compilers in a dedicated worker with project emit, diagnostics, hover, completion, definitions, references, signature help, Run, and type queries.

Accept old ?ts= and #code/ URLs, migrate @filename multi-file sources and legacy compiler-option parameters, preserve project state while switching backends, and add a Native 7.1 handoff to the classic playground version menu.
Comment thread packages/playground-v2/src/strada.worker.ts Fixed
Stack the file browser, editor, and output at phone widths so the workspace remains usable without horizontal page scrolling.

Add a collapsible file browser, touch-sized controls, safe-area spacing, and landscape handling.
Make definition jumps reversible so users can inspect project or bundled declarations without losing their previous editor location.

Expose Back and Forward controls and label bundled library files clearly.
Provide an explicit Delete action for the active project file while keeping bundled declarations protected and ensuring the project always retains a fallback file.

Reload after deletion so the WASI language server is rebuilt without stale files from its startup filesystem.
Selecting a classic TypeScript release should not remove the language-service features users expect from the existing playground.

Port Monaco's TypeScript adapters across the Strada worker boundary for rename, formatting, symbols, highlights, quick fixes, inlay hints, and richer completions, with compatibility fallbacks for older compiler APIs.
Inline markers and a toolbar count are not enough when a project has multiple files or configuration diagnostics.

Show a severity-sorted Problems list with file locations and direct navigation for both Native and Strada diagnostics.
Package imports should provide diagnostics, completion, and definition navigation without requiring users to manually copy declaration files into the project.

Reuse the website's existing ATA implementation, cache downloaded declarations, mount them into Native and Strada, and restart Native only when its immutable LSP filesystem needs newly acquired files.
A replacement playground should retain the existing learning entry points without depending on generated website files that are absent from clean package builds.

Bundle the example catalog, load examples as real projects with their compiler settings, and provide responsive help topics written for the unified workspace.
The TS7 playground package must build before repository bootstrap and without generated workspace package outputs.

Bundle the existing ATA runtime, declarations, package metadata, and license with the other static playground dependencies.
Examples and help add useful toolbar actions, but the desktop row can exceed the available width before the phone layout activates.

Allow the toolbar actions to wrap independently while retaining the tablet workspace columns.
@orta

Copy link
Copy Markdown
Contributor

congrats looks pretty solid

Larger projects need more control over editor space than a fixed three-column layout provides.

Add persistent desktop splitters, Files and Output visibility controls, independent Emit and Run collapsing, and per-file delete actions in the project tree.
Compiler versions should be presented uniformly without exposing which implementation serves a selected release.

Label the current compiler as 7.1, show only the newest patch for each prior major.minor line, and remove Nightly from the unified selector.
Desktop-width editor and emit lines read as clipped content on narrow screens even when page-level overflow is contained.

Enable Monaco word wrapping and wrap emitted code and runtime output at mobile breakpoints.
Monaco's virtual content layer kept exposing a horizontal scrollbar and a desktop-sized gutter even when wrapped lines fit inside the editor root.

Disable mobile horizontal scrolling, reduce gutter width, and preserve wrapped code within the visible viewport.
The collapsible Problems summary could shrink into the flexible emit scroller and be painted underneath it.

Give each output section an explicit flex order and keep the Problems bar non-shrinking when collapsed.
Hiding Files or Output removed the panel but left its persisted grid width reserved, so the editor did not reclaim the available space.
Emit, Problems, and Run are collapsible sections and should present the same chevron interaction instead of mixing disclosure with Hide buttons.
The first TypeScript 7 load transfers roughly 53 MiB, which should not begin without informing users on mobile or metered connections.

Pause uncached downloads in the existing loading card, remember the optional browser preference, and skip confirmation when the exact assets are already cached.
Creating project files should provide inline validation and remain usable on mobile without relying on blocking browser UI.
The version selector should read like the other toolbar controls and identify the current compiler with its full semver.

Remove the redundant Compiler label, size the selector like neighboring actions, and show 7.1.0-dev in both playground menus.
The first-load warning must be visually prominent regardless of the current workspace layout or output-panel width.
The existing #code payload is an implicit source-code format, so storing project JSON under the same unversioned path makes links ambiguous and difficult to evolve.

Write projects as #code/v2 envelopes while retaining #src, old compressed source, transitional JSON, compiler-option, selection, file-type, and filename-directive compatibility.
Inline playground directives should retain their old convenience without silently disagreeing with the visible project configuration.

Merge directives over tsconfig for compilation and language services, annotate both source and TSConfig, diagnose conflicts at their source, expose the effective config, and provide completion, navigation, removal, and apply-to-tsconfig actions.
Existing playground tutorials and inbound links should continue to work when the unified playground replaces the old page.

Migrate example hashes into real v2 projects, preserve example compiler settings and versions, open legacy handbook hashes in mapped Help topics, and make example continuation comments clickable in Monaco.
Adding an npm import should not reload the playground merely because the 7.1 language server started with an immutable filesystem snapshot.

Expose newly acquired declarations as hidden Monaco models so the existing LSP document synchronization updates diagnostics, hover, and definitions in place.
Users should be able to control automatic type acquisition, URL churn, and core editor preferences without manipulating localStorage directly.

Add a responsive Settings dialog for ATA, URL updates, font size, tab size, desktop wrapping, minimap visibility, and ligatures.
Project actions should use accessible, consistently styled page UI instead of blocking browser confirm, prompt, and alert dialogs.

Route reset, delete, example replacement, final-file warnings, and custom compiler entry through reusable in-page confirmation and input dialogs.
The browser select looked inconsistent with the playground toolbar and provided little control over selected-state and responsive presentation.

Use an old-playground-style version button with a caret, scrollable menu, selected checkmark, custom-build separator, outside-click closing, and full keyboard navigation.
The standalone playground needs enough of the TypeScript website identity and navigation to feel like a deployable site route rather than an isolated tool. Manual theme selection also makes the editor usable independently of the operating-system preference.
Versioned project URLs should reopen at the same editing location instead of discarding the cursor or range. Legacy selection query parameters remain authoritative so existing playground links preserve their original behavior.
Playground examples that rely on decorator metadata should execute as they did in the previous playground. Loading the metadata shim once preserves that compatibility without adding general npm package execution to the browser runner.
The new playground is no longer specific to one compiler release, so its package and product identity should describe the long-term replacement rather than the initial TypeScript 7 implementation.
The replacement playground needs a product-oriented URL instead of one tied to the compiler version that introduced it. Keep the previous route as a lightweight redirect so existing links retain their query and project hash.
}

async function initialize(args: InitMessage["args"]) {
ts = new Function(`${args.compilerSource}\nreturn ts;`)() as TS
The compact site links and custom editor theme did not consistently meet AA contrast and touch-target requirements. Use accessible menu and syntax colors while preserving clear selections and inlay hints in both themes.
@github-actions

Copy link
Copy Markdown
Contributor

Azure Static Web Apps: Your stage site is ready! Visit it here: https://victorious-plant-05c166c10-3653.centralus.5.azurestaticapps.net

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy-preview Enables automatic deployments to preview environments on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants