import type { CustomTSWebWorkerFactory } from "../../../node_modules/monaco-editor/esm/vs/language/typescript/tsWorker.js" ; import prettier from "prettier/esm/standalone.mjs" ; import parserBabel from "prettier/esm/parser-babel.mjs" ; import { compressToURL } from "@amoutonbrady/lz-string" ; import type ts from "typescript" ; const SyntaxKind = { ImportDeclaration : 265 as ts . SyntaxKind . ImportDeclaration , ExportDeclaration : 271 as ts . SyntaxKind . ExportDeclaration , } ; const formatCode = async ( code ) => { return prettier . format ( code , { parser : "babel-ts" , plugins : [ parserBabel ] , } ) ; } ; const worker = ( TypeScriptWorker ) => { return class MonacoTSWorker extends TypeScriptWorker { async typeAcquisition ( fileName ) { } async format ( fileName ) { const program = this . _languageService . getProgram ( ) as ts . Program ; const source = program . getSourceFile ( fileName ) ; return await formatCode ( source . getFullText ( ) ) ; } async getShareableURL ( fileName ) { const program = this . _languageService . getProgram ( ) as ts . Program ; const source = program . getSourceFile ( fileName ) ; let ImportExportStatements = [ ] ; let BackToBackImportExport = true ; source . forEachChild ( ( node ) => { let isImport = node . kind == SyntaxKind . ImportDeclaration - 1 ; let isExport = node . kind == SyntaxKind . ExportDeclaration - 1 ; if ( ! BackToBackImportExport ) return ; BackToBackImportExport = isImport || isExport || Boolean ( node . moduleSpecifier ) ; if ( BackToBackImportExport ) { ImportExportStatements . push ( { kind : isImport ? "import" : "export" , clause : ( isImport ? ( node as ts . ImportDeclaration ) . importClause : ( node as ts . ExportDeclaration ) . exportClause ) ?. getText ( ) ?? "*" , module : node . moduleSpecifier . getText ( ) , pos : { start : node . pos , end : node . end , } , } ) ; } } ) ; let remainingCode = source . getFullText ( ) ; ImportExportStatements . map ( ( { pos } ) => { let { start , end } = pos ; let snippet = remainingCode . substring ( start , end ) ; return snippet ; } ) . forEach ( ( snippet ) => { remainingCode = remainingCode . replace ( snippet , "" ) ; } ) ; let modules = "" ; let treeshake = "" ; ImportExportStatements . forEach ( ( v , i ) => { modules += ( v . kind == "import" ? "(import)" : "" ) + v . module . replace ( /^["']|["']$/g , "" ) + "," ; treeshake += "[" + v . clause . split ( "," ) . map ( ( s ) => s . trim ( ) ) . join ( "" ) + "]," ; } ) ; modules = modules . replace ( /,$/ , "" ) . trim ( ) ; treeshake = treeshake . replace ( /\]\,$/ , "]" ) . trim ( ) ; remainingCode = remainingCode . trim ( ) ; let url = new URL ( self . location . origin . toString ( ) ) ; if ( modules . length > 0 ) url . searchParams . set ( "q" , modules ) ; if ( treeshake . replace ( /\[\*\]|\,/g , "" ) . length > 0 ) { url . searchParams . set ( "treeshake" , treeshake ) ; } if ( remainingCode . length > 0 ) { let compressedURL = compressToURL ( remainingCode ) ; if ( compressedURL . length > remainingCode . length ) url . searchParams . set ( "text" , JSON . stringify ( remainingCode ) ) ; else url . searchParams . set ( "share" , compressToURL ( remainingCode ) ) ; } return decodeURIComponent ( url . toString ( ) ) ; } } ; } ; self . customTSWorkerFactory = worker ;