diff --git a/packages/gatsby-remark-shiki/src/renderer.ts b/packages/gatsby-remark-shiki/src/renderer.ts index 6296d6f7baf5..99376b05b684 100644 --- a/packages/gatsby-remark-shiki/src/renderer.ts +++ b/packages/gatsby-remark-shiki/src/renderer.ts @@ -41,10 +41,10 @@ export function renderToHTML(lines: Lines, options: Options, twoslash?: TwoSlash // console.log(tokenPos, token.content.length, filePos) // Underlining particular words const findTokenFunc = (start: number) => (e: any) => - start <= e.character && start + token.content.length <= e.character + e.length + start <= e.character && start + token.content.length >= e.character + e.length const findTokenDebug = (start: number) => (e: any) => { - const result = start <= e.character && start + token.content.length <= e.character + e.length + const result = start <= e.character && start + token.content.length >= e.character + e.length // prettier-ignore console.log(result, start, '<=', e.character, '&&', start + token.content.length, '<=', e.character + e.length) return result @@ -55,6 +55,7 @@ export function renderToHTML(lines: Lines, options: Options, twoslash?: TwoSlash const queriesInToken = queries.filter(findTokenFunc(tokenPos)) const allTokensByStart = [...errorsInToken, ...lspResponsesInToken, ...queriesInToken] + if (allTokensByStart.length) { const ranges = allTokensByStart.map(token => { const range: any = { diff --git a/packages/ts-twoslasher/README.md b/packages/ts-twoslasher/README.md index 0e90548c5fdf..256cdafdaa6b 100644 --- a/packages/ts-twoslasher/README.md +++ b/packages/ts-twoslasher/README.md @@ -20,24 +20,25 @@ to create examples for bugs on the compiler's issue tracker. - Ship to npm + The twoslash markup API lives inside your code samples code as comments, which can do special commands. There are the following commands: ```ts /** Available inline flags which are not compiler flags */ export interface ExampleOptions { - /** Let's the sample suppress all error diagnostics */ - noErrors: false; - /** An array of TS error codes, which you write as space separated - this is so the tool can know about unexpected errors */ - errors: number[]; - /** Shows the JS equivalent of the TypeScript code instead */ - showEmit: false; - /** - * When mixed with showEmit, lets you choose the file to present instead of the source - defaults to index.js which - * means when you just use `showEmit` above it shows the transpiled JS. - */ - showEmittedFile: string; - /** Whether to disable the pre-cache of LSP calls for interesting identifiers */ - noStaticSemanticInfo: false; + /** Let's the sample suppress all error diagnostics */ + noErrors: false + /** An array of TS error codes, which you write as space separated - this is so the tool can know about unexpected errors */ + errors: number[] + /** Shows the JS equivalent of the TypeScript code instead */ + showEmit: false + /** + * When mixed with showEmit, lets you choose the file to present instead of the source - defaults to index.js which + * means when you just use `showEmit` above it shows the transpiled JS. + */ + showEmittedFile: string + /** Whether to disable the pre-cache of LSP calls for interesting identifiers */ + noStaticSemanticInfo: false } ``` @@ -63,11 +64,10 @@ fn(42) Turns to: > ```ts -> > function fn(s) { > console.log(s.subtr(3)) > } -> +> > fn(42) > ``` @@ -107,19 +107,18 @@ function fn(s) { console.log(s.subtr(3)) } -fn(42); +fn(42) ``` Turns to: > ```ts -> > // This will not throw because of the noImplicitAny > function fn(s) { > console.log(s.subtr(3)) > } -> -> fn(42); +> +> fn(42) > ``` > With: @@ -139,39 +138,42 @@ Turns to: #### `cuts_out_unneccessary_code.ts` ```ts -interface IdLabel { id: number, /* some fields */ } -interface NameLabel { name: string, /* other fields */ } -type NameOrId = T extends number ? IdLabel : NameLabel; +interface IdLabel { + id: number /* some fields */ +} +interface NameLabel { + name: string /* other fields */ +} +type NameOrId = T extends number ? IdLabel : NameLabel // This comment should not be included // ---cut--- function createLabel(idOrName: T): NameOrId { - throw "unimplemented" + throw 'unimplemented' } -let a = createLabel("typescript"); +let a = createLabel('typescript') // ^? -let b = createLabel(2.8); +let b = createLabel(2.8) // ^? -let c = createLabel(Math.random() ? "hello" : 42); +let c = createLabel(Math.random() ? 'hello' : 42) // ^? ``` Turns to: > ```ts -> > function createLabel(idOrName: T): NameOrId { -> throw "unimplemented" +> throw 'unimplemented' > } -> -> let a = createLabel("typescript"); -> -> let b = createLabel(2.8); -> -> let c = createLabel(Math.random() ? "hello" : 42); +> +> let a = createLabel('typescript') +> +> let b = createLabel(2.8) +> +> let c = createLabel(Math.random() ? 'hello' : 42) > ``` > With: @@ -211,7 +213,7 @@ Turns to: > * Gets the length of a string > * @param value a string > */ -> export declare function getStringLength(value: string): number; +> export declare function getStringLength(value: string): number > ``` > With: @@ -232,10 +234,10 @@ Turns to: ```ts function greet(person: string, date: Date) { - console.log(`Hello ${person}, today is ${date.toDateString()}!`); + console.log(`Hello ${person}, today is ${date.toDateString()}!`) } -greet("Maddison", new Date()); +greet('Maddison', new Date()) // ^^^^^^^^^^ ``` @@ -243,10 +245,10 @@ Turns to: > ```ts > function greet(person: string, date: Date) { -> console.log(`Hello ${person}, today is ${date.toDateString()}!`); +> console.log(`Hello ${person}, today is ${date.toDateString()}!`) > } -> -> greet("Maddison", new Date()); +> +> greet('Maddison', new Date()) > ``` > With: @@ -275,10 +277,10 @@ Turns to: ```ts // @filename: file-with-export.ts -export const helloWorld = "Example string"; +export const helloWorld = 'Example string' // @filename: index.ts -import {helloWorld} from "./file-with-export" +import { helloWorld } from './file-with-export' console.log(helloWorld) ``` @@ -286,10 +288,10 @@ Turns to: > ```ts > // @filename: file-with-export.ts -> export const helloWorld = "Example string"; -> +> export const helloWorld = 'Example string' +> > // @filename: index.ts -> import {helloWorld} from "./file-with-export" +> import { helloWorld } from './file-with-export' > console.log(helloWorld) > ``` @@ -310,14 +312,14 @@ Turns to: #### `query.ts` ```ts -let foo = "hello there!"; +let foo = 'hello there!' // ^? ``` Turns to: > ```ts -> let foo = "hello there!"; +> let foo = 'hello there!' > ``` > With: @@ -363,28 +365,36 @@ Turns to: > ```js > // --importHelpers on: Spread helper will be imported from 'tslib' -> var __read = (this && this.__read) || function (o, n) { -> var m = typeof Symbol === "function" && o[Symbol.iterator]; -> if (!m) return o; -> var i = m.call(o), r, ar = [], e; +> var __read = +> (this && this.__read) || +> function(o, n) { +> var m = typeof Symbol === 'function' && o[Symbol.iterator] +> if (!m) return o +> var i = m.call(o), +> r, +> ar = [], +> e > try { -> while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); -> } -> catch (error) { e = { error: error }; } -> finally { -> try { -> if (r && !r.done && (m = i["return"])) m.call(i); -> } -> finally { if (e) throw e.error; } +> while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value) +> } catch (error) { +> e = { error: error } +> } finally { +> try { +> if (r && !r.done && (m = i['return'])) m.call(i) +> } finally { +> if (e) throw e.error +> } > } -> return ar; -> }; -> var __spread = (this && this.__spread) || function () { -> for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); -> return ar; -> }; +> return ar +> } +> var __spread = +> (this && this.__spread) || +> function() { +> for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])) +> return ar +> } > export function fn(arr) { -> var arr2 = __spread([1], arr); +> var arr2 = __spread([1], arr) > } > ``` @@ -417,69 +427,76 @@ The API is one main exported function: * @param lzstringModule An optional copy of the lz-string import, if missing it will be require'd * @param sysModule TBD */ -export function twoslasher(code: string, extension: string, tsModule?: TS, lzstringModule?: LZ, fsMap?: Map): TwoSlashReturn; +export function twoslasher( + code: string, + extension: string, + tsModule?: TS, + lzstringModule?: LZ, + fsMap?: Map +): TwoSlashReturn ``` Which returns ```ts export interface TwoSlashReturn { - /** The output code, could be TypeScript, but could also be a JS/JSON/d.ts */ - code: string; - /** The new extension type for the code, potentially changed if they've requested emitted results */ - extension: string; - /** Sample requests to highlight a particular part of the code */ - highlights: { - kind: "highlight"; - position: number; - length: number; - description: string; - line: number; - }[]; - /** An array of LSP responses identifiers in the sample */ - staticQuickInfos: { - /** The string content of the node this represents (mainly for debugging) */ - targetString: string; - /** The base LSP response (the type) */ - text: string; - /** Attached JSDoc info */ - docs: string | undefined; - /** The index of the text in the file */ - start: number; - /** how long the identifier */ - length: number; - /** line number where this is found */ - line: number; - /** The character on the line */ - character: number; - }[]; - /** Requests to use the LSP to get info for a particular symbol in the source */ - queries: { - kind: "query"; - /** The index of the text in the file */ - start: number; - /** how long the identifier */ - length: number; - offset: number; - // TODO: Add these so we can present something - text: string; - docs: string | undefined; - }[]; - /** Diagnostic error messages which came up when creating the program */ - errors: { - renderedMessage: string; - id: string; - category: 0 | 1 | 2 | 3; - code: number; - start: number | undefined; - length: number | undefined; - line: number | undefined; - character: number | undefined; - }[]; - /** The URL for this sample in the playground */ - playgroundURL: string; + /** The output code, could be TypeScript, but could also be a JS/JSON/d.ts */ + code: string + /** The new extension type for the code, potentially changed if they've requested emitted results */ + extension: string + /** Sample requests to highlight a particular part of the code */ + highlights: { + kind: 'highlight' + position: number + length: number + description: string + line: number + }[] + /** An array of LSP responses identifiers in the sample */ + staticQuickInfos: { + /** The string content of the node this represents (mainly for debugging) */ + targetString: string + /** The base LSP response (the type) */ + text: string + /** Attached JSDoc info */ + docs: string | undefined + /** The index of the text in the file */ + start: number + /** how long the identifier */ + length: number + /** line number where this is found */ + line: number + /** The character on the line */ + character: number + }[] + /** Requests to use the LSP to get info for a particular symbol in the source */ + queries: { + kind: 'query' + /** The index of the text in the file */ + start: number + /** how long the identifier */ + length: number + offset: number + // TODO: Add these so we can present something + text: string + docs: string | undefined + }[] + /** Diagnostic error messages which came up when creating the program */ + errors: { + renderedMessage: string + id: string + category: 0 | 1 | 2 | 3 + code: number + start: number | undefined + length: number | undefined + line: number | undefined + character: number | undefined + }[] + /** The URL for this sample in the playground */ + playgroundURL: string } ``` + ## Local Development diff --git a/packages/ts-twoslasher/package.json b/packages/ts-twoslasher/package.json index 8ffbbad87acd..82c1ac4e46d2 100644 --- a/packages/ts-twoslasher/package.json +++ b/packages/ts-twoslasher/package.json @@ -13,7 +13,7 @@ "start": "tsdx watch", "build": "tsdx build; yarn readme", "bootstrap": "yarn workspace typescript-vfs run bootstrap; yarn build", - "readme": "yarn md-magic README.md --config ./scripts/inline-results.js", + "readme": "yarn md-magic README.md --config ./scripts/inline-results.js; yarn prettier README.md --write", "test": "tsdx test", "lint": "tsdx lint" }, diff --git a/packages/ts-twoslasher/src/index.ts b/packages/ts-twoslasher/src/index.ts index 668ac5c704d7..4f22907c0311 100644 --- a/packages/ts-twoslasher/src/index.ts +++ b/packages/ts-twoslasher/src/index.ts @@ -377,7 +377,7 @@ export function twoslasher( // We need to also strip the highlights + queries from the main file which is shown to people const allCodeLines = code.split(/\r\n?|\n/g) filterHighlightLines(allCodeLines) - code = allCodeLines.join('\n') + code = allCodeLines.join('\n').trim() // Code should now be safe to compile, so we're going to split it into different files const errs: import('typescript').Diagnostic[] = [] @@ -470,10 +470,10 @@ export function twoslasher( const zippedCode = lzstring.compressToEncodedURIComponent(originalCode) const playgroundURL = `https://www.typescriptlang.org/play/#code/${zippedCode}` - const cutString = '// ---cut---' + const cutString = '// ---cut---\n' if (code.includes(cutString)) { // Get the place it is, then find the end and the start of the next line - const cutIndex = code.indexOf(cutString) + cutString.length + 1 + const cutIndex = code.indexOf(cutString) + cutString.length // Kills the code shown code = code.split(cutString).pop()! diff --git a/packages/tsconfig-reference/copy/en/options/isolatedModules.md b/packages/tsconfig-reference/copy/en/options/isolatedModules.md index 50ebbe66fdbe..71c836bbaea3 100644 --- a/packages/tsconfig-reference/copy/en/options/isolatedModules.md +++ b/packages/tsconfig-reference/copy/en/options/isolatedModules.md @@ -49,7 +49,7 @@ This restriction doesn't apply to `.d.ts` files In TypeScript, when you reference a `const enum` member, the reference is replaced by its actual value in the emitted JavaScript: -```ts +```ts twoslash declare const enum Numbers { Zero = 0, One = 1 diff --git a/packages/typescript-vfs/package.json b/packages/typescript-vfs/package.json index 7c5b3a619102..dac505a7c6f6 100644 --- a/packages/typescript-vfs/package.json +++ b/packages/typescript-vfs/package.json @@ -5,7 +5,7 @@ "author": "TypeScript team", "main": "./dist/index.js", "module": "./dist/typescript-vsf.esm.js", - "typings": "./dist/index.d.ts", + "typings": "./dist/src/index.d.ts", "files": [ "dist" ], diff --git a/packages/typescriptlang-org/src/pages/dev/dev.scss b/packages/typescriptlang-org/src/pages/dev/dev.scss new file mode 100644 index 000000000000..0ee588e99acf --- /dev/null +++ b/packages/typescriptlang-org/src/pages/dev/dev.scss @@ -0,0 +1,46 @@ +#dev { + .content { + display: flex; + } + + pre { + background-color: white; + color: black; + + .mtk5 { + color: black; + } + } + + .split-code { + display: flex; + + > p { + width: 30%; + padding-right: 1rem; + flex: 1; + } + + > pre { + // width: 70%; + flex: 3; + overflow-x: scroll; + } + } + + #example-buttons { + div.button { + display: inline-block; + padding: 8px 12px; + background-color: #faf9f8; + margin: 10px; + text-decoration: none; + color: black; + cursor: pointer; + &:hover, + &:active { + background-color: #dfdfdf; + } + } + } +} diff --git a/packages/typescriptlang-org/src/pages/dev/sandbox.scss b/packages/typescriptlang-org/src/pages/dev/sandbox.scss deleted file mode 100644 index bef214380b02..000000000000 --- a/packages/typescriptlang-org/src/pages/dev/sandbox.scss +++ /dev/null @@ -1,28 +0,0 @@ -.content { - display: flex; -} - -pre { - background-color: white; - color: black; - - .mtk5 { - color: black; - } -} - -.split { - display: flex; - - p { - width: 30%; - padding-right: 1rem; - flex: 1; - } - - pre { - // width: 70%; - flex: 3; - overflow-x: scroll; - } -} diff --git a/packages/typescriptlang-org/src/pages/dev/sandbox.tsx b/packages/typescriptlang-org/src/pages/dev/sandbox.tsx index 344dc8eb16fd..f29ce3b7d8c5 100644 --- a/packages/typescriptlang-org/src/pages/dev/sandbox.tsx +++ b/packages/typescriptlang-org/src/pages/dev/sandbox.tsx @@ -2,73 +2,9 @@ import React, { useEffect } from "react" import { Layout } from "../../components/layout" import { withPrefix } from "gatsby" -import "./sandbox.scss" +import "./dev.scss" import { DevNav } from "../../components/dev-nav" -const codeSamples = [ - { - blurb: "Converting the user's TypeScript into JavaScript", - code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) - -// Async because it needs to go -const js = await sandbox.getRunnableJS() -console.log(js)` - }, { - blurb: "Get the DTS for the user's editor", - code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) - -const dts = await sandbox.getDTSForCode() -console.log(dts)` - }, { - blurb: "Make a request for an LSP response", - code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) - -// A worker here is a web-worker, set up by monaco-typescript -// which does the computation in the background -const worker = await sandbox.getWorkerProcess() -const definitions = await client.getDefinitionAtPosition(model.uri.toString(), 6) - ` - }, - { - blurb: "Change compiler flags using a few different APIs", - code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) - -// Hook in to all changes to the compiler -sandbox.setDidUpdateCompilerSettings((newOptions) => { - console.log("Compiler settings changed: ", newOptions) -}) - -// Update via key value -sandbox.updateCompilerSetting("allowJs", true) -// Update via an object -sandbox.updateCompilerSettings({ jsx: 0 }) -// Replace the compiler settings -sandbox.setCompilerSettings({}) -` - }, - { - blurb: "Highlight some code in the editor", - code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) - -const start = { - lineNumber: 0, - column: 0 -} - -const end = { - lineNumber: 0, - column: 4 -} - -const decorations = sandbox.editor.deltaDecorations([], [ - { - range: new sandbox.monaco.Range(start.lineNumber, start.column, end.lineNumber, end.column), - options: { inlineClassName: 'error-highlight' }, - }, -]) -` - } -] const Index = (props: any) => { @@ -130,38 +66,39 @@ export default async function () { return ( <> - -
-
-

TypeScript Sandbox

-

A DOM library for interacting with TypeScript and JavaScript code, which powers the heart of the TypeScript playground

-

You can use the TypeScript sandbox for:

-
    -
  • Building IDE-like experiences for people to explore your library's API
  • -
  • Building interactive web tools which use TypeScript, with a lot of the Playgrounds developer experience for free
  • -
-

For example, the sandbox to the side has grabbed the Types for DangerJS with no modifications for this code sample. This is because the Playground's Automatic Type Acquisition is enabled by default. It will also look for the same parameters for code, and selection indexes inside the URL.

-

Try clicking this URL to see that in action.

-

This library builds on top of the Monaco Editor, providing a higher level API but offering access to all the lower-level APIs via a single sandbox object.

-

You can find the code for the TypeScript Sandbox inside the microsoft/TypeScript-Website mono-repo.

-
-
-
-
-

Downloading Sandbox...

+
+ +
+
+

TypeScript Sandbox

+

A DOM library for interacting with TypeScript and JavaScript code, which powers the heart of the TypeScript playground

+

You can use the TypeScript sandbox for:

+
    +
  • Building IDE-like experiences for people to explore your library's API
  • +
  • Building interactive web tools which use TypeScript, with a lot of the Playgrounds developer experience for free
  • +
+

For example, the sandbox to the side has grabbed the Types for DangerJS with no modifications for this code sample. This is because the Playground's Automatic Type Acquisition is enabled by default. It will also look for the same parameters for code, and selection indexes inside the URL.

+

Try clicking this URL to see that in action.

+

This library builds on top of the Monaco Editor, providing a higher level API but offering access to all the lower-level APIs via a single sandbox object.

+

You can find the code for the TypeScript Sandbox inside the microsoft/TypeScript-Website mono-repo.

+
+
+
+
+

Downloading Sandbox...

+
+
-
-
-
-

Usage

-

A sandbox uses the same tools as monaco-editor, meaning this library is shipped as an AMD bundle which you can use the VSCode Loader to require.

-

Because we need it for the TypeScript website, you can use our hosted copy here. (note, we will eventually deprecate the /v2/ in all routes)

+
+

Usage

+

A sandbox uses the same tools as monaco-editor, meaning this library is shipped as an AMD bundle which you can use the VSCode Loader to require.

+

Because we need it for the TypeScript website, you can use our hosted copy here. (note, we will eventually deprecate the /v2/ in all routes)

-

Get Started

-

Create a new file: index.html and paste this code into that file.

-
{`
+            

Get Started

+

Create a new file: index.html and paste this code into that file.

+
{`
 
   
     
@@ -236,18 +173,19 @@ export default async function () {
   
 
           `}
-          
-

Opening the file index.html in a web browser will load up the same sandbox up at the top of the page.

-

Some examples of the API

- { - codeSamples.map(code => -
-

{code.blurb}

-
{code.code.trim()}
-
- ) - } -

The API is mainly a light shim over the monaco-editor API with the monaco-typescript API.

+
+

Opening the file index.html in a web browser will load up the same sandbox up at the top of the page.

+

Some examples of the API

+ { + codeSamples.map(code => +
+

{code.blurb}

+
{code.code.trim()}
+
+ ) + } +

The API is mainly a light shim over the monaco-editor API with the monaco-typescript API.

+
@@ -255,7 +193,69 @@ export default async function () { } +export default Index +const codeSamples = [ + { + blurb: "Converting the user's TypeScript into JavaScript", + code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) +// Async because it needs to go +const js = await sandbox.getRunnableJS() +console.log(js)` + }, { + blurb: "Get the DTS for the user's editor", + code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) -export default Index +const dts = await sandbox.getDTSForCode() +console.log(dts)` + }, { + blurb: "Make a request for an LSP response", + code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) + +// A worker here is a web-worker, set up by monaco-typescript +// which does the computation in the background +const worker = await sandbox.getWorkerProcess() +const definitions = await client.getDefinitionAtPosition(model.uri.toString(), 6) + ` + }, + { + blurb: "Change compiler flags using a few different APIs", + code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) + +// Hook in to all changes to the compiler +sandbox.setDidUpdateCompilerSettings((newOptions) => { + console.log("Compiler settings changed: ", newOptions) +}) + +// Update via key value +sandbox.updateCompilerSetting("allowJs", true) +// Update via an object +sandbox.updateCompilerSettings({ jsx: 0 }) +// Replace the compiler settings +sandbox.setCompilerSettings({}) +` + }, + { + blurb: "Highlight some code in the editor", + code: `const sandbox = await createTypeScriptSandbox(sandboxConfig, main, ts) + +const start = { + lineNumber: 0, + column: 0 +} + +const end = { + lineNumber: 0, + column: 4 +} + +const decorations = sandbox.editor.deltaDecorations([], [ + { + range: new sandbox.monaco.Range(start.lineNumber, start.column, end.lineNumber, end.column), + options: { inlineClassName: 'error-highlight' }, + }, +]) +` + } +] diff --git a/packages/typescriptlang-org/src/pages/dev/twoslash.tsx b/packages/typescriptlang-org/src/pages/dev/twoslash.tsx index 6032a88ee009..96e1e5799fe9 100644 --- a/packages/typescriptlang-org/src/pages/dev/twoslash.tsx +++ b/packages/typescriptlang-org/src/pages/dev/twoslash.tsx @@ -4,7 +4,9 @@ import { withPrefix } from "gatsby" import { twoslasher } from "ts-twoslasher" import { createDefaultMapFromCDN } from "typescript-vfs" -import "./sandbox.scss" +import { renderToHTML } from "gatsby-remark-shiki/src/renderer" + +import "./dev.scss" import { DevNav } from "../../components/dev-nav" @@ -33,7 +35,7 @@ const Index = (props: any) => { function fn(s) { // No error when noImplicitAny: false // try remove it in the editor - console.log(s.subtr(3)); + // console.log(s.subtr(3)); } fn(42); ` @@ -45,6 +47,9 @@ fn(42); const sandbox = await sandboxEnv.createTypeScriptSandbox({ text: initialCode, compilerOptions: {}, domID: "monaco-editor-embed", useJavaScript: false }, main, ts) sandbox.editor.focus() + // @ts-ignore + window.sandbox = sandbox + const mapWithLibFiles = await createDefaultMapFromCDN({ target: ts.ScriptTarget.ES2015 }, '3.7.3', true, ts, sandbox.lzstring as any) const runTwoslash = () => { @@ -53,10 +58,38 @@ fn(42); try { const newResults = twoslasher(newContent, "tsx", ts, sandbox.lzstring as any, mapWithLibFiles) - document.getElementById("twoslash-results")!.textContent = JSON.stringify(newResults) + const codeAsFakeShikiTokens = newResults.code.split("\n").map(line => [{ content: line }]) + const html = renderToHTML(codeAsFakeShikiTokens, {}, newResults) + + const results = document.getElementById("twoslash-results")! + + document.getElementById("twoslash-failure")!.style.display = "none" + document.getElementById("twoslash-results")!.innerHTML = html + + // Remove all the kids + while (results.firstChild) { + results.removeChild(results.firstChild) + } + + const p = document.createElement("p") + p.innerText = newResults.extension + p.className = "extension" + + const code = document.createElement("div") + code.innerHTML = html + + const a = document.createElement("a") + a.innerText = "Playground" + a.href = newResults.playgroundURL + + results.appendChild(p) + results.appendChild(code) + results.appendChild(a) } catch (error) { console.log(error) + document.getElementById("twoslash-results")!.style.display = "block" + document.getElementById("twoslash-failure")!.style.display = "none" document.getElementById("twoslash-results")!.textContent = error } } @@ -75,6 +108,11 @@ fn(42); runTwoslash() setTimeout(() => { + + document.querySelectorAll("#example-buttons .disabled").forEach(button => { + button.classList.remove("disabled") + }) + document.querySelectorAll(".html-code").forEach(codeElement => { sandbox.monaco.editor.colorize(codeElement.textContent || "", "html", { tabSize: 2 }).then(newHTML => { codeElement.innerHTML = newHTML @@ -97,37 +135,129 @@ fn(42); return ( <> - -
-
-

TypeScript Twoslash

-

-            
+
+ +
+
+

TypeScript Twoslash

+
+
+
-
-
-
-

Downloading Sandbox...

+ +
+
+

Markup

+
+
+

Downloading Sandbox...

+
+
+
+ {codeSamples.map(code => { + const setExample = (e) => { + console.log("---", e.target) + if (e.target.classList.contains("disabled")) return + + // document.getElementById("exampleBlurb")!.innerText = code.blurb + // @ts-ignore + window.sandbox.setText(code.code) + } + return
{code.name}
+ } + )} +
+
+ +
+

Results

+
+
+
-
-
-
-

Usage

-

A sandbox uses the same tools as monaco-editor, meaning this library is shipped as an AMD bundle which you can use the VSCode Loader to require.

-

Because we need it for the TypeScript website, you can use our hosted copy here. (note, we will eventually deprecate the /v2/ in all routes)

-

Get Started

-

Create a new file: index.html and paste this code into that file.

+
+

Usage

+

A sandbox uses the same tools as monaco-editor, meaning this library is shipped as an AMD bundle which you can use the VSCode Loader to require.

+

Because we need it for the TypeScript website, you can use our hosted copy here. (note, we will eventually deprecate the /v2/ in all routes)

+ +

Get Started

+

Create a new file: index.html and paste this code into that file.

+
) +} + +export default Index +const codeSamples = [ + { + name: "Show Errors", + blurb: "Something", + code: `// @target: ES2015 +// @errors: 7006 + +function fn(s) { + console.log(s.subtr(3)) } +fn(42)` + }, { + name: "Set Compiler Flags", + blurb: "Get the DTS for the user's editor", + code: `// @noImplicitAny: false +// @target: ES2015 +// This will not throw because of the noImplicitAny +function fn(s) { + console.log(s.subtr(3)) +} +fn(42);` + }, { + name: "Trims code", + blurb: "Make a request for an LSP response", + code: `interface IdLabel { id: number, /* some fields */ } +interface NameLabel { name: string, /* other fields */ } +type NameOrId = T extends number ? IdLabel : NameLabel; +// This comment should not be included -export default Index +// ---cut--- +function createLabel(idOrName: T): NameOrId { + throw "unimplemented" +} + +let a = createLabel("typescript");` + }, + { + name: "Show the DTS", + blurb: "Change compiler flags using a few different APIs", + code: `// @declaration: true +// @showEmit +// @showEmittedFile: index.d.ts + +/** + * Gets the length of a string + * @param value a string + */ +export function getStringLength(value: string) { + return value +} +` + }, + { + name: "Highlights", + blurb: "Highlight some code in the editor", + code: `function greet(person: string, date: Date) { + console.log(\`Hello \${person}, today is \${date.toDateString()}!\`); +} + +greet("Maddison", new Date()); +// ^^^^^^^^^^ +` + } +] diff --git a/watcher.js b/watcher.js index e87e02dc36d1..b39e0bc1b4a2 100644 --- a/watcher.js +++ b/watcher.js @@ -69,7 +69,7 @@ client.command(['watch-project', process.cwd()], function(error, resp) { [ 'subscribe', root, - 'mysubscription', + 'Monorepo Builder', { expression: ['anyof', ['match', '*.ts'], ['match', '*.md'], ['match', '*.tsx'], ['match', '*.json']], relative_root: path_prefix,